aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Smith-Rowland <3dw4rd@verizon.net>2016-05-23 11:54:48 +0000
committerEdward Smith-Rowland <3dw4rd@verizon.net>2016-05-23 11:54:48 +0000
commitdc9d5bbde1481f66c13a7d3980c1718e8e86a6ef (patch)
treec4121a7a6e2bf3fc759cfce7a72673d8afa54d87
parent6f7dfd2ebfeb769922455377769ae58460d00e5b (diff)
Merged revisions r232323 through r236585 to the branch
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/tr29124@236586 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog37
-rw-r--r--MAINTAINERS1
-rw-r--r--Makefile.def5
-rw-r--r--Makefile.in58
-rwxr-xr-xconfig.guess93
-rwxr-xr-xconfig.sub8
-rwxr-xr-xconfigure16
-rw-r--r--configure.ac16
-rw-r--r--contrib/ChangeLog4
-rwxr-xr-xcontrib/download_prerequisites8
-rw-r--r--gcc/ChangeLog3057
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in8
-rw-r--r--gcc/ada/ChangeLog112
-rw-r--r--gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst2
-rw-r--r--gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst66
-rw-r--r--gcc/ada/einfo.ads83
-rw-r--r--gcc/ada/exp_ch4.adb6
-rw-r--r--gcc/ada/exp_ch6.adb4
-rw-r--r--gcc/ada/exp_pakd.adb11
-rw-r--r--gcc/ada/exp_util.adb25
-rw-r--r--gcc/ada/freeze.adb340
-rw-r--r--gcc/ada/freeze.ads12
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in8
-rw-r--r--gcc/ada/gcc-interface/decl.c82
-rw-r--r--gcc/ada/gcc-interface/gigi.h8
-rw-r--r--gcc/ada/gcc-interface/trans.c4
-rw-r--r--gcc/ada/gcc-interface/utils.c89
-rw-r--r--gcc/ada/s-osinte-gnu.ads7
-rw-r--r--gcc/ada/system-darwin-ppc64.ads5
-rw-r--r--gcc/ada/system-linux-armeb.ads3
-rw-r--r--gcc/ada/system-linux-mips.ads5
-rw-r--r--gcc/ada/system-linux-mips64el.ads5
-rw-r--r--gcc/ada/system-linux-mipsel.ads5
-rw-r--r--gcc/ada/system-linux-ppc64.ads5
-rw-r--r--gcc/ada/system-linux-sparcv9.ads5
-rw-r--r--gcc/ada/system-rtems.ads5
-rw-r--r--gcc/alias.c4
-rw-r--r--gcc/bitmap.c2
-rw-r--r--gcc/builtins.c185
-rw-r--r--gcc/builtins.h1
-rw-r--r--gcc/c-family/ChangeLog43
-rw-r--r--gcc/c-family/c-common.c129
-rw-r--r--gcc/c-family/c-common.h13
-rw-r--r--gcc/c-family/c.opt8
-rw-r--r--gcc/c-family/cilk.c10
-rw-r--r--gcc/c/ChangeLog119
-rw-r--r--gcc/c/Make-lang.in11
-rw-r--r--gcc/c/c-decl.c96
-rw-r--r--gcc/c/c-errors.c6
-rw-r--r--gcc/c/c-parser.c104
-rw-r--r--gcc/c/c-tree.h18
-rw-r--r--gcc/c/c-typeck.c107
-rw-r--r--gcc/calls.c221
-rw-r--r--gcc/cfganal.c17
-rw-r--r--gcc/cfgcleanup.c123
-rw-r--r--gcc/cfgexpand.c4
-rw-r--r--gcc/cfgloop.h4
-rw-r--r--gcc/cfgloopanal.c35
-rw-r--r--gcc/cfgrtl.c8
-rw-r--r--gcc/cfgrtl.h2
-rw-r--r--gcc/cgraph.c80
-rw-r--r--gcc/cgraph.h41
-rw-r--r--gcc/cgraphclones.c56
-rw-r--r--gcc/cgraphunit.c5
-rw-r--r--gcc/cif-code.def8
-rw-r--r--gcc/combine.c11
-rw-r--r--gcc/config.gcc54
-rw-r--r--gcc/config.in6
-rw-r--r--gcc/config/aarch64/aarch64-elf.h9
-rw-r--r--gcc/config/aarch64/aarch64-protos.h1
-rw-r--r--gcc/config/aarch64/aarch64-simd.md85
-rw-r--r--gcc/config/aarch64/aarch64.c130
-rw-r--r--gcc/config/aarch64/aarch64.h17
-rw-r--r--gcc/config/aarch64/aarch64.md89
-rw-r--r--gcc/config/aarch64/arm_neon.h459
-rw-r--r--gcc/config/alpha/alpha.c2
-rw-r--r--gcc/config/alpha/alpha.md5
-rw-r--r--gcc/config/arm/arm-builtins.c6
-rw-r--r--gcc/config/arm/arm-c.c10
-rw-r--r--gcc/config/arm/arm.c186
-rw-r--r--gcc/config/arm/arm.h3
-rw-r--r--gcc/config/arm/arm.md12
-rw-r--r--gcc/config/arm/arm_neon.h12
-rw-r--r--gcc/config/arm/vfp.md55
-rw-r--r--gcc/config/avr/avr.c2
-rw-r--r--gcc/config/avr/avr.md7
-rw-r--r--gcc/config/i386/constraints.md9
-rw-r--r--gcc/config/i386/cygming.h11
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c338
-rw-r--r--gcc/config/i386/i386.h3
-rw-r--r--gcc/config/i386/i386.md694
-rw-r--r--gcc/config/i386/mingw32.h6
-rw-r--r--gcc/config/i386/predicates.md56
-rw-r--r--gcc/config/i386/sse.md1081
-rw-r--r--gcc/config/i386/sync.md111
-rw-r--r--gcc/config/i386/xopintrin.h8
-rw-r--r--gcc/config/ia64/ia64.c2
-rw-r--r--gcc/config/mips/constraints.md55
-rw-r--r--gcc/config/mips/i6400.md177
-rw-r--r--gcc/config/mips/m5100.md2
-rw-r--r--gcc/config/mips/mips-cpus.def8
-rw-r--r--gcc/config/mips/mips-ftypes.def157
-rw-r--r--gcc/config/mips/mips-modes.def14
-rw-r--r--gcc/config/mips/mips-msa.md2736
-rw-r--r--gcc/config/mips/mips-protos.h20
-rw-r--r--gcc/config/mips/mips.c2227
-rw-r--r--gcc/config/mips/mips.h92
-rw-r--r--gcc/config/mips/mips.md45
-rw-r--r--gcc/config/mips/mips.opt4
-rw-r--r--gcc/config/mips/msa.h582
-rw-r--r--gcc/config/mips/mti-elf.h4
-rw-r--r--gcc/config/mips/mti-linux.h6
-rw-r--r--gcc/config/mips/p5600.md119
-rw-r--r--gcc/config/mips/predicates.md129
-rw-r--r--gcc/config/nvptx/nvptx.c62
-rw-r--r--gcc/config/nvptx/nvptx.md11
-rw-r--r--gcc/config/rl78/rl78.c88
-rw-r--r--gcc/config/rl78/rl78.md10
-rw-r--r--gcc/config/rl78/rl78.opt4
-rw-r--r--gcc/config/rs6000/altivec.md24
-rw-r--r--gcc/config/rs6000/constraints.md19
-rw-r--r--gcc/config/rs6000/freebsd64.h5
-rw-r--r--gcc/config/rs6000/linux64.h5
-rw-r--r--gcc/config/rs6000/predicates.md108
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def47
-rw-r--r--gcc/config/rs6000/rs6000-c.c126
-rw-r--r--gcc/config/rs6000/rs6000-cpus.def9
-rw-r--r--gcc/config/rs6000/rs6000-protos.h2
-rw-r--r--gcc/config/rs6000/rs6000.c1279
-rw-r--r--gcc/config/rs6000/rs6000.h38
-rw-r--r--gcc/config/rs6000/rs6000.md10
-rw-r--r--gcc/config/rs6000/rs6000.opt16
-rw-r--r--gcc/config/rs6000/sysv4.h53
-rw-r--r--gcc/config/rs6000/vsx.md347
-rw-r--r--gcc/config/rx/rx-protos.h22
-rw-r--r--gcc/config/rx/rx.c45
-rw-r--r--gcc/config/rx/rx.md142
-rw-r--r--gcc/config/s390/s390.md46
-rw-r--r--gcc/config/sh/predicates.md18
-rw-r--r--gcc/config/sh/sh-protos.h21
-rw-r--r--gcc/config/sh/sh.c625
-rw-r--r--gcc/config/sh/sh.h76
-rw-r--r--gcc/config/sh/sh.md705
-rw-r--r--gcc/config/sh/sh.opt16
-rw-r--r--gcc/config/sol2.h13
-rwxr-xr-xgcc/configure27
-rw-r--r--gcc/configure.ac11
-rw-r--r--gcc/coretypes.h49
-rw-r--r--gcc/cp/ChangeLog185
-rw-r--r--gcc/cp/Make-lang.in11
-rw-r--r--gcc/cp/call.c11
-rw-r--r--gcc/cp/constexpr.c26
-rw-r--r--gcc/cp/cp-tree.h32
-rw-r--r--gcc/cp/cp-ubsan.c4
-rw-r--r--gcc/cp/decl.c79
-rw-r--r--gcc/cp/decl2.c5
-rw-r--r--gcc/cp/init.c29
-rw-r--r--gcc/cp/method.c4
-rw-r--r--gcc/cp/name-lookup.c13
-rw-r--r--gcc/cp/parser.c102
-rw-r--r--gcc/cp/pt.c194
-rw-r--r--gcc/cp/search.c26
-rw-r--r--gcc/cp/semantics.c83
-rw-r--r--gcc/cp/tree.c27
-rw-r--r--gcc/cp/typeck.c110
-rw-r--r--gcc/cp/typeck2.c22
-rw-r--r--gcc/cppbuiltin.c3
-rw-r--r--gcc/cse.c54
-rw-r--r--gcc/df-scan.c15
-rw-r--r--gcc/diagnostic-show-locus.c39
-rw-r--r--gcc/diagnostic.h4
-rw-r--r--gcc/doc/cpp.texi5
-rw-r--r--gcc/doc/extend.texi886
-rw-r--r--gcc/doc/install.texi6
-rw-r--r--gcc/doc/invoke.texi227
-rw-r--r--gcc/doc/md.texi43
-rw-r--r--gcc/doc/sourcebuild.texi3
-rw-r--r--gcc/doc/tm.texi14
-rw-r--r--gcc/doc/tm.texi.in4
-rw-r--r--gcc/dse.c29
-rw-r--r--gcc/dwarf2out.c29
-rw-r--r--gcc/except.c19
-rw-r--r--gcc/expr.c244
-rw-r--r--gcc/expr.h30
-rw-r--r--gcc/flag-types.h24
-rw-r--r--gcc/fold-const.c314
-rw-r--r--gcc/fold-const.h1
-rw-r--r--gcc/fortran/ChangeLog128
-rw-r--r--gcc/fortran/check.c2
-rw-r--r--gcc/fortran/class.c32
-rw-r--r--gcc/fortran/decl.c568
-rw-r--r--gcc/fortran/dump-parse-tree.c1
-rw-r--r--gcc/fortran/expr.c16
-rw-r--r--gcc/fortran/frontend-passes.c10
-rw-r--r--gcc/fortran/gfortran.h23
-rw-r--r--gcc/fortran/gfortran.texi254
-rw-r--r--gcc/fortran/interface.c217
-rw-r--r--gcc/fortran/invoke.texi21
-rw-r--r--gcc/fortran/lang.opt8
-rw-r--r--gcc/fortran/libgfortran.h2
-rw-r--r--gcc/fortran/match.c122
-rw-r--r--gcc/fortran/match.h4
-rw-r--r--gcc/fortran/misc.c6
-rw-r--r--gcc/fortran/module.c47
-rw-r--r--gcc/fortran/openmp.c1239
-rw-r--r--gcc/fortran/options.c20
-rw-r--r--gcc/fortran/parse.c545
-rw-r--r--gcc/fortran/parse.h3
-rw-r--r--gcc/fortran/primary.c116
-rw-r--r--gcc/fortran/resolve.c873
-rw-r--r--gcc/fortran/symbol.c159
-rw-r--r--gcc/fortran/trans-decl.c33
-rw-r--r--gcc/fortran/trans-expr.c43
-rw-r--r--gcc/fortran/trans-io.c6
-rw-r--r--gcc/fortran/trans-stmt.c2
-rw-r--r--gcc/fortran/trans-types.c73
-rw-r--r--gcc/function.c488
-rw-r--r--gcc/fwprop.c11
-rw-r--r--gcc/gcc.c9
-rw-r--r--gcc/genattr-common.c2
-rw-r--r--gcc/genattr.c10
-rw-r--r--gcc/genattrtab.c2
-rw-r--r--gcc/genautomata.c107
-rw-r--r--gcc/gencodes.c2
-rw-r--r--gcc/genconditions.c2
-rw-r--r--gcc/genconfig.c2
-rw-r--r--gcc/genconstants.c2
-rw-r--r--gcc/genemit.c2
-rw-r--r--gcc/genenums.c2
-rw-r--r--gcc/genextract.c2
-rw-r--r--gcc/genflags.c2
-rw-r--r--gcc/gengtype.c2
-rw-r--r--gcc/genmddeps.c2
-rw-r--r--gcc/genmddump.c5
-rw-r--r--gcc/genmodes.c21
-rw-r--r--gcc/genopinit.c2
-rw-r--r--gcc/genoutput.c4
-rw-r--r--gcc/genpeep.c4
-rw-r--r--gcc/genpreds.c2
-rw-r--r--gcc/genrecog.c2
-rw-r--r--gcc/gensupport.c4
-rw-r--r--gcc/gensupport.h5
-rw-r--r--gcc/gentarget-def.c2
-rw-r--r--gcc/gimple-fold.c24
-rw-r--r--gcc/gimple-low.c11
-rw-r--r--gcc/gimple-pretty-print.c62
-rw-r--r--gcc/gimple.c18
-rw-r--r--gcc/gimple.h20
-rw-r--r--gcc/gimplify.c151
-rw-r--r--gcc/gimplify.h6
-rw-r--r--gcc/go/ChangeLog5
-rw-r--r--gcc/go/Make-lang.in1
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/escape.cc526
-rw-r--r--gcc/go/gofrontend/escape.h442
-rw-r--r--gcc/go/gofrontend/gogo.h37
-rw-r--r--gcc/go/gofrontend/types.h45
-rw-r--r--gcc/graphite-scop-detection.c3
-rw-r--r--gcc/hard-reg-set.h8
-rw-r--r--gcc/hsa-gen.c25
-rw-r--r--gcc/input.c10
-rw-r--r--gcc/input.h1
-rw-r--r--gcc/internal-fn.c25
-rw-r--r--gcc/internal-fn.def5
-rw-r--r--gcc/ipa-cp.c29
-rw-r--r--gcc/ipa-icf.c2
-rw-r--r--gcc/ipa-inline-analysis.c305
-rw-r--r--gcc/ipa-inline-transform.c97
-rw-r--r--gcc/ipa-inline.c51
-rw-r--r--gcc/ipa-inline.h4
-rw-r--r--gcc/ipa-prop.c192
-rw-r--r--gcc/ipa-prop.h13
-rw-r--r--gcc/ipa-pure-const.c122
-rw-r--r--gcc/ira.c18
-rw-r--r--gcc/jit/ChangeLog300
-rw-r--r--gcc/jit/docs/_build/texinfo/libgccjit.texi763
-rw-r--r--gcc/jit/docs/topics/compatibility.rst7
-rw-r--r--gcc/jit/docs/topics/expressions.rst40
-rw-r--r--gcc/jit/dummy-frontend.c34
-rw-r--r--gcc/jit/jit-common.h1
-rw-r--r--gcc/jit/jit-playback.c61
-rw-r--r--gcc/jit/jit-playback.h28
-rw-r--r--gcc/jit/jit-recording.c62
-rw-r--r--gcc/jit/jit-recording.h525
-rw-r--r--gcc/jit/libgccjit.c20
-rw-r--r--gcc/jit/libgccjit.h13
-rw-r--r--gcc/jit/libgccjit.map5
-rw-r--r--gcc/langhooks-def.h2
-rw-r--r--gcc/langhooks.c5
-rw-r--r--gcc/langhooks.h5
-rw-r--r--gcc/libfuncs.h31
-rw-r--r--gcc/loop-doloop.c20
-rw-r--r--gcc/lra-constraints.c17
-rw-r--r--gcc/lto-cgraph.c11
-rw-r--r--gcc/lto-section-in.c3
-rw-r--r--gcc/lto-streamer-in.c3
-rw-r--r--gcc/lto-streamer.c7
-rw-r--r--gcc/lto-streamer.h4
-rw-r--r--gcc/lto/ChangeLog8
-rw-r--r--gcc/lto/lto-partition.c2
-rw-r--r--gcc/lto/lto-symtab.c5
-rw-r--r--gcc/machmode.h4
-rw-r--r--gcc/match.pd238
-rw-r--r--gcc/omp-low.c13
-rw-r--r--gcc/omp-simd-clone.c1
-rw-r--r--gcc/optabs-libfuncs.c29
-rw-r--r--gcc/optabs.c20
-rw-r--r--gcc/optabs.def3
-rw-r--r--gcc/opts-common.c11
-rw-r--r--gcc/opts.c30
-rw-r--r--gcc/params.def6
-rw-r--r--gcc/pass_manager.h6
-rw-r--r--gcc/passes.c34
-rw-r--r--gcc/passes.def8
-rw-r--r--gcc/po/ChangeLog12
-rw-r--r--gcc/po/da.po556
-rw-r--r--gcc/po/sv.po1782
-rw-r--r--gcc/po/zh_CN.po23
-rw-r--r--gcc/print-tree.c2
-rw-r--r--gcc/read-md.c35
-rw-r--r--gcc/read-md.h3
-rw-r--r--gcc/read-rtl.c33
-rw-r--r--gcc/reginfo.c1
-rw-r--r--gcc/regrename.c55
-rw-r--r--gcc/sched-deps.c7
-rw-r--r--gcc/shrink-wrap.c235
-rw-r--r--gcc/shrink-wrap.h9
-rw-r--r--gcc/stor-layout.c12
-rw-r--r--gcc/system.h4
-rw-r--r--gcc/target.def22
-rw-r--r--gcc/testsuite/ChangeLog1030
-rw-r--r--gcc/testsuite/c-c++-common/Wdangling-else-1.c13
-rw-r--r--gcc/testsuite/c-c++-common/Wdangling-else-2.c13
-rw-r--r--gcc/testsuite/c-c++-common/Wdangling-else-3.c13
-rw-r--r--gcc/testsuite/c-c++-common/Wdangling-else-4.c31
-rw-r--r--gcc/testsuite/c-c++-common/asan/clone-test-1.c2
-rw-r--r--gcc/testsuite/c-c++-common/attr-opt-1.c37
-rw-r--r--gcc/testsuite/c-c++-common/attributes-3.c27
-rw-r--r--gcc/testsuite/c-c++-common/builtin_location.c57
-rw-r--r--gcc/testsuite/c-c++-common/pr69669.c3
-rw-r--r--gcc/testsuite/c-c++-common/pr70756-2.c12
-rw-r--r--gcc/testsuite/c-c++-common/pr70756.c23
-rw-r--r--gcc/testsuite/c-c++-common/tm/safe-1.c12
-rw-r--r--gcc/testsuite/c-c++-common/tsan/sanitize-thread-macro.c12
-rw-r--r--gcc/testsuite/g++.dg/Wattributes.C20
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-60049.C24
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/decltype64.C32
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/auto-fn31.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/builtin_location.C175
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C287
-rw-r--r--gcc/testsuite/g++.dg/debug/pr71057.C12
-rw-r--r--gcc/testsuite/g++.dg/diagnostic/pr71075.C8
-rw-r--r--gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C12
-rw-r--r--gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C7
-rw-r--r--gcc/testsuite/g++.dg/gomp/udr-4.C2
-rw-r--r--gcc/testsuite/g++.dg/inherit/thunk1.C3
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-7.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/ivinline-9.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/pr71146.C29
-rw-r--r--gcc/testsuite/g++.dg/lookup/member4.C17
-rw-r--r--gcc/testsuite/g++.dg/lookup/member5.C32
-rw-r--r--gcc/testsuite/g++.dg/lto/pr69589_0.C4
-rw-r--r--gcc/testsuite/g++.dg/opt/pr70906.C69
-rw-r--r--gcc/testsuite/g++.dg/opt/pr70933.C29
-rw-r--r--gcc/testsuite/g++.dg/opt/pr71100.C18
-rw-r--r--gcc/testsuite/g++.dg/opt/pr71210-1.C14
-rw-r--r--gcc/testsuite/g++.dg/opt/pr71210-2.C23
-rw-r--r--gcc/testsuite/g++.dg/parse/dot1.C2
-rw-r--r--gcc/testsuite/g++.dg/plugin/self-assign-test-1.C2
-rw-r--r--gcc/testsuite/g++.dg/plugin/self-assign-test-2.C2
-rw-r--r--gcc/testsuite/g++.dg/pr62314.C17
-rw-r--r--gcc/testsuite/g++.dg/pr71184.C1
-rw-r--r--gcc/testsuite/g++.dg/spellcheck-fields-2.C19
-rw-r--r--gcc/testsuite/g++.dg/template/crash122.C4
-rw-r--r--gcc/testsuite/g++.dg/template/pr70466-1.C27
-rw-r--r--gcc/testsuite/g++.dg/template/pr70466-2.C25
-rw-r--r--gcc/testsuite/g++.dg/template/pseudodtor3.C2
-rw-r--r--gcc/testsuite/g++.dg/template/using14.C2
-rw-r--r--gcc/testsuite/g++.dg/torture/pr71002.C160
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/ivopts-3.C2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr70199.c3
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr70916.c28
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20030222-1.c1
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr68185.c2
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr70460.c3
-rw-r--r--gcc/testsuite/gcc.dg/Waddress-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/Wduplicate-decl-specifier-c11.c27
-rw-r--r--gcc/testsuite/gcc.dg/Wduplicate-decl-specifier.c63
-rw-r--r--gcc/testsuite/gcc.dg/Woverride-init-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/Woverride-init-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/atomic-noinline-aux.c3
-rw-r--r--gcc/testsuite/gcc.dg/autopar/outer-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/call-diag-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/nested_fun.c65
-rw-r--r--gcc/testsuite/gcc.dg/fold-notrotate-1.c54
-rw-r--r--gcc/testsuite/gcc.dg/fold-notshift-1.c77
-rw-r--r--gcc/testsuite/gcc.dg/fold-notshift-2.c33
-rw-r--r--gcc/testsuite/gcc.dg/fold-perm.c8
-rw-r--r--gcc/testsuite/gcc.dg/foo.specs2
-rw-r--r--gcc/testsuite/gcc.dg/graphite/pr70956.c4
-rw-r--r--gcc/testsuite/gcc.dg/graphite/scop-18.c4
-rw-r--r--gcc/testsuite/gcc.dg/init-excess-2.c47
-rw-r--r--gcc/testsuite/gcc.dg/ipa/iinline-cstagg-1.c37
-rw-r--r--gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c30
-rw-r--r--gcc/testsuite/gcc.dg/ipa/inline-8.c39
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-1.c42
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-2.c46
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-3.c58
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-4.c64
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c37
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c43
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c65
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr70306.c1
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr70646.c40
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pure-const-3.c24
-rw-r--r--gcc/testsuite/gcc.dg/nested-func-10.c1
-rw-r--r--gcc/testsuite/gcc.dg/nested-func-9.c1
-rw-r--r--gcc/testsuite/gcc.dg/optimize-bswapsi-4.c28
-rw-r--r--gcc/testsuite/gcc.dg/opts-7.c6
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-color.c3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c58
-rw-r--r--gcc/testsuite/gcc.dg/plugin/must_tail_call_plugin.c76
-rw-r--r--gcc/testsuite/gcc.dg/plugin/plugin.exp3
-rw-r--r--gcc/testsuite/gcc.dg/plugin/self-assign-test-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr18079-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr30172-1.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr41783.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr63743.c3
-rw-r--r--gcc/testsuite/gcc.dg/pr68671.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr69634.c1
-rw-r--r--gcc/testsuite/gcc.dg/pr70807.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr70859-2.c18
-rw-r--r--gcc/testsuite/gcc.dg/pr70859.c69
-rw-r--r--gcc/testsuite/gcc.dg/pr71006.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr71071.c12
-rw-r--r--gcc/testsuite/gcc.dg/pr71084.c38
-rw-r--r--gcc/testsuite/gcc.dg/pr71148.c46
-rw-r--r--gcc/testsuite/gcc.dg/qual-return-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/qual-return-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/qual-return-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/qual-return-5.c32
-rw-r--r--gcc/testsuite/gcc.dg/qual-return-6.c12
-rw-r--r--gcc/testsuite/gcc.dg/setjmp-6.c1
-rw-r--r--gcc/testsuite/gcc.dg/spec-options.c3
-rw-r--r--gcc/testsuite/gcc.dg/spellcheck-options-11.c7
-rw-r--r--gcc/testsuite/gcc.dg/tm/pr51696.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/20160404-1.c21
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr54261-1.c5
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr66178.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70935.c39
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70941.c12
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70985.c28
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70986-1.c22
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70986-2.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr70986-3.c18
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71020.c76
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71039.c14
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71055.c18
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71059.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71062.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71132.c24
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr71168.c20
-rw-r--r--gcc/testsuite/gcc.dg/torture/type-generic-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/71206.c8
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/and-1.c11
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/andnot-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/bit-assoc.c29
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ifc-10.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ifc-11.c20
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ifc-9.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ifc-cd.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ifc-pr56541.c25
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loadpre10.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loadpre23.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loadpre25.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loadpre4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr40921.c26
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr63586-2.c32
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr63586.c70
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr69270.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr70919.c46
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr71179.c10
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr71185.c13
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-14.c5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c5
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-54.c56
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-55.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-18.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-store-ccp-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/unord.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vector-6.c35
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp100.c32
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp59.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp99.c9
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/bounds-3.c22
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-19.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr56541.c27
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr57206.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr58135.c10
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr61194.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr66636.c3
-rw-r--r--gcc/testsuite/gcc.dg/vect/section-anchors-vect-70.c33
-rw-r--r--gcc/testsuite/gcc.dg/vect/section-anchors-vect-71.c25
-rw-r--r--gcc/testsuite/gcc.dg/vect/section-anchors-vect-72.c29
-rw-r--r--gcc/testsuite/gcc.dg/vect/tree-vect.h17
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-23.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-mask-store-move-1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h17
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/compute-ref-data.h16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/p64_p128.c665
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c490
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vget_lane.c19
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmul.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c255
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c160
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c202
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrnd.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndX.inc43
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrnda.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndm.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndn.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndp.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndx.c16
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vshl.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vsli_n.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c105
-rw-r--r--gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vtst.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-1.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-4.c1
-rw-r--r--gcc/testsuite/gcc.target/aarch64/fmla_intrinsic_1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/fmls_intrinsic_1.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/noplt_3.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/pr70809_1.c18
-rw-r--r--gcc/testsuite/gcc.target/aarch64/simd/vmul_elem_1.c519
-rw-r--r--gcc/testsuite/gcc.target/aarch64/struct_return.c31
-rw-r--r--gcc/testsuite/gcc.target/aarch64/tail_indirect_call_1.c4
-rw-r--r--gcc/testsuite/gcc.target/arm/aapcs/neon-vect10.c31
-rw-r--r--gcc/testsuite/gcc.target/arm/aapcs/neon-vect9.c23
-rw-r--r--gcc/testsuite/gcc.target/arm/aapcs/vfp18.c27
-rw-r--r--gcc/testsuite/gcc.target/arm/aapcs/vfp19.c29
-rw-r--r--gcc/testsuite/gcc.target/arm/aapcs/vfp20.c21
-rw-r--r--gcc/testsuite/gcc.target/arm/aapcs/vfp21.c25
-rw-r--r--gcc/testsuite/gcc.target/arm/fp16-aapcs-1.c17
-rw-r--r--gcc/testsuite/gcc.target/arm/fp16-param-1.c12
-rw-r--r--gcc/testsuite/gcc.target/arm/fp16-return-1.c7
-rw-r--r--gcc/testsuite/gcc.target/arm/interrupt-1.c6
-rw-r--r--gcc/testsuite/gcc.target/arm/interrupt-2.c6
-rw-r--r--gcc/testsuite/gcc.target/arm/pr70830.c14
-rw-r--r--gcc/testsuite/gcc.target/arm/pr71056.c32
-rw-r--r--gcc/testsuite/gcc.target/avr/pr71103.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-kunpckdq-1.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-pack-2.c100
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpalignr-3.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-1.c104
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-2.c68
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-3.c58
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpextr-1.c109
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpinsr-1.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpmaddubsw-3.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpmaddwd-3.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpmulhrsw-3.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpshufb-3.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpsraw-3.c44
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512dq-abs-copysign-1.c71
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512dq-logic-2.c196
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512dq-vbroadcast-2.c49
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512dq-vinsert-1.c100
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512dq-vpextr-1.c53
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512dq-vpinsr-1.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-additional-reg-names.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-cvt-1.c38
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfmadd-1.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-1.c71
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-2.c49
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-logic-1.c132
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-logic-2.c196
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-pack-1.c68
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-pack-2.c108
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vbroadcast-1.c41
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vbroadcast-2.c47
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vinsert-1.c98
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vinserti32x4-3.c49
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vinsertps-1.c39
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vmovq-1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vpalignr-3.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-1.c104
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-2.c68
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-3.c58
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vpinsr-1.c63
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vpmulhrsw-3.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vpshufb-3.c30
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vpsrad-3.c44
-rw-r--r--gcc/testsuite/gcc.target/i386/fabsneg-1.c36
-rw-r--r--gcc/testsuite/gcc.target/i386/mmx-2.c2
-rw-r--r--gcc/testsuite/gcc.target/i386/pr44281.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/pr49244-1.c188
-rw-r--r--gcc/testsuite/gcc.target/i386/pr49244-2.c108
-rw-r--r--gcc/testsuite/gcc.target/i386/pr61599-1.c4
-rw-r--r--gcc/testsuite/gcc.target/i386/pr61599-2.c5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr66746.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70467-1.c55
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70467-3.c19
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70467-4.c18
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70799-1.c41
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70876.c13
-rw-r--r--gcc/testsuite/gcc.target/i386/pr70877.c14
-rw-r--r--gcc/testsuite/gcc.target/i386/sse-13.c1
-rw-r--r--gcc/testsuite/gcc.target/i386/strinline.c4
-rw-r--r--gcc/testsuite/gcc.target/mips/mips16-attributes.c1
-rw-r--r--gcc/testsuite/gcc.target/nvptx/abi-vararg-3.c13
-rw-r--r--gcc/testsuite/gcc.target/nvptx/ary-init.c2
-rw-r--r--gcc/testsuite/gcc.target/nvptx/decl.c1
-rw-r--r--gcc/testsuite/gcc.target/nvptx/sincos.c17
-rw-r--r--gcc/testsuite/gcc.target/nvptx/trailing-init.c1
-rw-r--r--gcc/testsuite/gcc.target/nvptx/uninit-decl.c18
-rw-r--r--gcc/testsuite/gcc.target/powerpc/darn-0.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/darn-1.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/darn-2.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dform-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dform-2.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dform-3.c39
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-complex-1.c157
-rw-r--r--gcc/testsuite/gcc.target/powerpc/float128-complex-2.c160
-rw-r--r--gcc/testsuite/gcc.target/powerpc/p8vector-int128-1.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/p9-splat-1.c27
-rw-r--r--gcc/testsuite/gcc.target/powerpc/p9-splat-2.c38
-rw-r--r--gcc/testsuite/gcc.target/powerpc/p9-splat-3.c61
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr47755.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr68805.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr70866.c11
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr70963.c44
-rw-r--r--gcc/testsuite/gcc.target/powerpc/savres.c34
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-adde-int128.c59
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-adde.c61
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-addec-int128.c123
-rw-r--r--gcc/testsuite/gcc.target/powerpc/vec-addec.c119
-rw-r--r--gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c151
-rw-r--r--gcc/testsuite/gcc.target/s390/s390.exp11
-rw-r--r--gcc/testsuite/gcc.target/sh/pr52933-1.c78
-rw-r--r--gcc/testsuite/gcc.target/sh/pr52933-2.c6
-rw-r--r--gcc/testsuite/gcc.target/sh/pr54089-1.c9
-rw-r--r--gcc/testsuite/gcc.target/sh/pr58219.c60
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_1.f9056
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_10.f90119
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_11.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_2.f9041
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_3.f9052
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_4.f9043
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_5.f9049
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_6.f9046
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_7.f9075
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_8.f9060
-rw-r--r--gcc/testsuite/gfortran.dg/dec_structure_9.f9042
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_1.f9066
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_2.f9060
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_3.f9035
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_4.f9063
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_5.f9041
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_6.f9059
-rw-r--r--gcc/testsuite/gfortran.dg/dec_union_7.f9038
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/pr70855.f9018
-rw-r--r--gcc/testsuite/gfortran.dg/pr42108.f902
-rw-r--r--gcc/testsuite/gfortran.dg/pr46519-1.f2
-rw-r--r--gcc/testsuite/gfortran.dg/pr69603.f9016
-rw-r--r--gcc/testsuite/gfortran.dg/pr70931.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/pr70937.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/pr71047.f0848
-rw-r--r--gcc/testsuite/gfortran.dg/pr71204.f9017
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/pr70960.f9010
-rw-r--r--gcc/testsuite/gnat.dg/debug5.adb22
-rw-r--r--gcc/testsuite/gnat.dg/debug6.adb10
-rw-r--r--gcc/testsuite/gnat.dg/debug6_pkg.ads16
-rw-r--r--gcc/testsuite/gnat.dg/opt53.adb12
-rw-r--r--gcc/testsuite/gnat.dg/opt54.adb12
-rw-r--r--gcc/testsuite/jit.dg/all-non-failing-tests.h10
-rw-r--r--gcc/testsuite/jit.dg/test-error-array-bounds.c72
-rw-r--r--gcc/testsuite/jit.dg/test-error-impossible-must-tail-call.c93
-rw-r--r--gcc/testsuite/jit.dg/test-factorial-must-tail-call.c109
-rw-r--r--gcc/trans-mem.c6
-rw-r--r--gcc/tree-affine.c2
-rw-r--r--gcc/tree-call-cdce.c104
-rw-r--r--gcc/tree-cfg.c56
-rw-r--r--gcc/tree-chkp.c16
-rw-r--r--gcc/tree-complex.c15
-rw-r--r--gcc/tree-core.h14
-rw-r--r--gcc/tree-data-ref.c9
-rw-r--r--gcc/tree-dfa.c23
-rw-r--r--gcc/tree-dfa.h1
-rw-r--r--gcc/tree-if-conv.c324
-rw-r--r--gcc/tree-inline.c78
-rw-r--r--gcc/tree-into-ssa.c8
-rw-r--r--gcc/tree-loop-distribution.c35
-rw-r--r--gcc/tree-parloops.c1
-rw-r--r--gcc/tree-pass.h1
-rw-r--r--gcc/tree-pretty-print.c17
-rw-r--r--gcc/tree-sra.c54
-rw-r--r--gcc/tree-ssa-alias.c43
-rw-r--r--gcc/tree-ssa-alias.h4
-rw-r--r--gcc/tree-ssa-ccp.c293
-rw-r--r--gcc/tree-ssa-coalesce.c30
-rw-r--r--gcc/tree-ssa-loop-im.c2
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c4
-rw-r--r--gcc/tree-ssa-loop-ivopts.c465
-rw-r--r--gcc/tree-ssa-loop-niter.c9
-rw-r--r--gcc/tree-ssa-loop-prefetch.c5
-rw-r--r--gcc/tree-ssa-loop-unswitch.c6
-rw-r--r--gcc/tree-ssa-math-opts.c44
-rw-r--r--gcc/tree-ssa-operands.c1
-rw-r--r--gcc/tree-ssa-phiprop.c21
-rw-r--r--gcc/tree-ssa-pre.c30
-rw-r--r--gcc/tree-ssa-reassoc.c181
-rw-r--r--gcc/tree-ssa-sccvn.c300
-rw-r--r--gcc/tree-ssa-structalias.c7
-rw-r--r--gcc/tree-ssa-tail-merge.c3
-rw-r--r--gcc/tree-ssa-uninit.c401
-rw-r--r--gcc/tree-ssa.c151
-rw-r--r--gcc/tree-ssanames.c4
-rw-r--r--gcc/tree-vect-loop.c23
-rw-r--r--gcc/tree-vect-patterns.c7
-rw-r--r--gcc/tree-vect-slp.c64
-rw-r--r--gcc/tree-vect-stmts.c21
-rw-r--r--gcc/tree-vectorizer.c132
-rw-r--r--gcc/tree-vrp.c202
-rw-r--r--gcc/tree.c81
-rw-r--r--gcc/tree.def15
-rw-r--r--gcc/tree.h13
-rw-r--r--gcc/ubsan.c1
-rw-r--r--gcc/wide-int.h2
-rw-r--r--gnattools/ChangeLog7
-rw-r--r--gnattools/Makefile.in54
-rwxr-xr-xgnattools/configure3
-rw-r--r--gnattools/configure.ac1
-rw-r--r--include/ChangeLog7
-rw-r--r--libatomic/config/rtems/host-config.h41
-rw-r--r--libatomic/config/rtems/lock.c37
-rw-r--r--libbacktrace/ChangeLog11
-rw-r--r--libbacktrace/elf.c3
-rw-r--r--libcilkrts/ChangeLog133
-rw-r--r--libcilkrts/Makefile.am35
-rw-r--r--libcilkrts/Makefile.in131
-rw-r--r--libcilkrts/README6
-rw-r--r--libcilkrts/configure1972
-rw-r--r--libcilkrts/configure.ac30
-rw-r--r--libcilkrts/configure.tgt23
-rw-r--r--libcilkrts/include/cilk/cilk.h37
-rw-r--r--libcilkrts/include/cilk/cilk_api.h184
-rw-r--r--libcilkrts/include/cilk/cilk_api_linux.h19
-rw-r--r--libcilkrts/include/cilk/cilk_stub.h28
-rw-r--r--libcilkrts/include/cilk/cilk_undocumented.h21
-rw-r--r--libcilkrts/include/cilk/common.h52
-rw-r--r--libcilkrts/include/cilk/holder.h25
-rw-r--r--libcilkrts/include/cilk/hyperobject_base.h23
-rw-r--r--libcilkrts/include/cilk/metaprogramming.h107
-rw-r--r--libcilkrts/include/cilk/reducer.h1154
-rw-r--r--libcilkrts/include/cilk/reducer_file.h19
-rw-r--r--libcilkrts/include/cilk/reducer_list.h461
-rw-r--r--libcilkrts/include/cilk/reducer_max.h19
-rw-r--r--libcilkrts/include/cilk/reducer_min.h19
-rw-r--r--libcilkrts/include/cilk/reducer_min_max.h1559
-rw-r--r--libcilkrts/include/cilk/reducer_opadd.h227
-rw-r--r--libcilkrts/include/cilk/reducer_opand.h216
-rw-r--r--libcilkrts/include/cilk/reducer_opmul.h131
-rw-r--r--libcilkrts/include/cilk/reducer_opor.h213
-rw-r--r--libcilkrts/include/cilk/reducer_opxor.h212
-rw-r--r--libcilkrts/include/cilk/reducer_ostream.h650
-rw-r--r--libcilkrts/include/cilk/reducer_string.h198
-rw-r--r--libcilkrts/include/cilk/reducer_vector.h533
-rw-r--r--libcilkrts/include/cilktools/cilkscreen.h19
-rw-r--r--libcilkrts/include/cilktools/cilkview.h19
-rw-r--r--libcilkrts/include/cilktools/fake_mutex.h19
-rw-r--r--libcilkrts/include/cilktools/lock_guard.h19
-rw-r--r--libcilkrts/include/internal/abi.h33
-rw-r--r--libcilkrts/include/internal/cilk_fake.h19
-rw-r--r--libcilkrts/include/internal/cilk_version.h31
-rw-r--r--libcilkrts/include/internal/metacall.h19
-rw-r--r--libcilkrts/include/internal/rev.mk21
-rw-r--r--libcilkrts/mk/cilk-version.mk19
-rw-r--r--libcilkrts/runtime/acknowledgements.dox19
-rw-r--r--libcilkrts/runtime/bug.cpp21
-rw-r--r--libcilkrts/runtime/bug.h19
-rw-r--r--libcilkrts/runtime/c_reducers.c26
-rw-r--r--libcilkrts/runtime/cilk-abi-cilk-for.cpp22
-rw-r--r--libcilkrts/runtime/cilk-abi-vla-internal.c19
-rw-r--r--libcilkrts/runtime/cilk-abi-vla-internal.h19
-rw-r--r--libcilkrts/runtime/cilk-abi.c73
-rw-r--r--libcilkrts/runtime/cilk-ittnotify.h19
-rw-r--r--libcilkrts/runtime/cilk-tbb-interop.h19
-rw-r--r--libcilkrts/runtime/cilk_api.c19
-rw-r--r--libcilkrts/runtime/cilk_fiber-unix.cpp58
-rw-r--r--libcilkrts/runtime/cilk_fiber-unix.h30
-rw-r--r--libcilkrts/runtime/cilk_fiber.cpp19
-rw-r--r--libcilkrts/runtime/cilk_fiber.h19
-rw-r--r--libcilkrts/runtime/cilk_malloc.c21
-rw-r--r--libcilkrts/runtime/cilk_malloc.h19
-rw-r--r--libcilkrts/runtime/cilk_str_mem.h94
-rw-r--r--libcilkrts/runtime/component.h19
-rw-r--r--libcilkrts/runtime/config/arm/cilk-abi-vla.c115
-rw-r--r--libcilkrts/runtime/config/arm/os-fence.h64
-rw-r--r--libcilkrts/runtime/config/arm/os-unix-sysdep.c105
-rw-r--r--libcilkrts/runtime/config/generic/cilk-abi-vla.c21
-rw-r--r--libcilkrts/runtime/config/generic/os-fence.h19
-rw-r--r--libcilkrts/runtime/config/generic/os-unix-sysdep.c19
-rw-r--r--libcilkrts/runtime/config/x86/cilk-abi-vla.c78
-rw-r--r--libcilkrts/runtime/config/x86/os-fence.h19
-rw-r--r--libcilkrts/runtime/config/x86/os-unix-sysdep.c21
-rw-r--r--libcilkrts/runtime/declare-alloca.h (renamed from libcilkrts/runtime/symbol_test.c)64
-rw-r--r--libcilkrts/runtime/doxygen-layout.xml19
-rw-r--r--libcilkrts/runtime/doxygen.cfg19
-rw-r--r--libcilkrts/runtime/except-gcc.cpp27
-rw-r--r--libcilkrts/runtime/except-gcc.h19
-rw-r--r--libcilkrts/runtime/except.h19
-rw-r--r--libcilkrts/runtime/frame_malloc.c19
-rw-r--r--libcilkrts/runtime/frame_malloc.h19
-rw-r--r--libcilkrts/runtime/full_frame.c19
-rw-r--r--libcilkrts/runtime/full_frame.h19
-rw-r--r--libcilkrts/runtime/global_state.cpp43
-rw-r--r--libcilkrts/runtime/global_state.h33
-rw-r--r--libcilkrts/runtime/jmpbuf.c19
-rw-r--r--libcilkrts/runtime/jmpbuf.h19
-rw-r--r--libcilkrts/runtime/linux-symbols.ver23
-rw-r--r--libcilkrts/runtime/local_state.c19
-rw-r--r--libcilkrts/runtime/local_state.h19
-rw-r--r--libcilkrts/runtime/mac-symbols.txt6
-rw-r--r--libcilkrts/runtime/metacall_impl.c19
-rw-r--r--libcilkrts/runtime/metacall_impl.h19
-rw-r--r--libcilkrts/runtime/os-unix.c210
-rw-r--r--libcilkrts/runtime/os.h21
-rw-r--r--libcilkrts/runtime/os_mutex-unix.c19
-rw-r--r--libcilkrts/runtime/os_mutex.h19
-rw-r--r--libcilkrts/runtime/pedigrees.c19
-rw-r--r--libcilkrts/runtime/pedigrees.h19
-rw-r--r--libcilkrts/runtime/record-replay.cpp42
-rw-r--r--libcilkrts/runtime/record-replay.h19
-rw-r--r--libcilkrts/runtime/reducer_impl.cpp19
-rw-r--r--libcilkrts/runtime/reducer_impl.h19
-rw-r--r--libcilkrts/runtime/rts-common.h33
-rw-r--r--libcilkrts/runtime/scheduler.c114
-rw-r--r--libcilkrts/runtime/scheduler.h19
-rw-r--r--libcilkrts/runtime/signal_node.c19
-rw-r--r--libcilkrts/runtime/signal_node.h19
-rw-r--r--libcilkrts/runtime/spin_mutex.c19
-rw-r--r--libcilkrts/runtime/spin_mutex.h19
-rw-r--r--libcilkrts/runtime/sslib/ignore_handler_s.c72
-rw-r--r--libcilkrts/runtime/sslib/safe_lib.h61
-rw-r--r--libcilkrts/runtime/sslib/safe_lib_errno.h100
-rw-r--r--libcilkrts/runtime/sslib/safe_str_constraint.c146
-rw-r--r--libcilkrts/runtime/sslib/safe_str_constraint.h78
-rw-r--r--libcilkrts/runtime/sslib/safe_str_lib.h70
-rw-r--r--libcilkrts/runtime/sslib/safe_types.h61
-rw-r--r--libcilkrts/runtime/sslib/safeclib_private.h93
-rw-r--r--libcilkrts/runtime/sslib/snprintf_s.h49
-rw-r--r--libcilkrts/runtime/sslib/snprintf_support.c353
-rw-r--r--libcilkrts/runtime/sslib/strcpy_s.c198
-rw-r--r--libcilkrts/runtime/sslib/strncpy_s.c238
-rw-r--r--libcilkrts/runtime/sslib/strnlen_s.c112
-rw-r--r--libcilkrts/runtime/stats.c69
-rw-r--r--libcilkrts/runtime/stats.h56
-rw-r--r--libcilkrts/runtime/sysdep-unix.c147
-rw-r--r--libcilkrts/runtime/sysdep.h19
-rw-r--r--libcilkrts/runtime/worker_mutex.c19
-rw-r--r--libcilkrts/runtime/worker_mutex.h19
-rw-r--r--libcpp/ChangeLog9
-rw-r--r--libcpp/config.in3
-rwxr-xr-xlibcpp/configure22
-rw-r--r--libcpp/configure.ac15
-rw-r--r--libcpp/lex.c4
-rw-r--r--libcpp/po/ChangeLog12
-rw-r--r--libcpp/po/da.po10
-rw-r--r--libcpp/po/fi.po12
-rw-r--r--libcpp/po/nl.po21
-rw-r--r--libgcc/ChangeLog13
-rw-r--r--libgcc/config.host16
-rw-r--r--libgomp/ChangeLog19
-rw-r--r--libgomp/oacc-init.c14
-rw-r--r--libgomp/testsuite/libgomp.hsa.c/complex-align-2.c27
-rw-r--r--libgomp/testsuite/libgomp.hsa.c/switch-sbr-2.c59
-rw-r--r--libiberty/ChangeLog71
-rw-r--r--libiberty/cp-demangle.c52
-rw-r--r--libiberty/cplus-dem.c13
-rw-r--r--libiberty/testsuite/demangle-expected129
-rw-r--r--libsanitizer/ChangeLog6
-rw-r--r--libsanitizer/asan/asan_malloc_linux.cc43
-rw-r--r--libstdc++-v3/ChangeLog120
-rw-r--r--libstdc++-v3/include/debug/bitset2
-rw-r--r--libstdc++-v3/include/debug/deque2
-rw-r--r--libstdc++-v3/include/debug/functions.h7
-rw-r--r--libstdc++-v3/include/debug/list2
-rw-r--r--libstdc++-v3/include/debug/map2
-rw-r--r--libstdc++-v3/include/debug/set2
-rw-r--r--libstdc++-v3/include/debug/string2
-rw-r--r--libstdc++-v3/include/debug/unordered_map2
-rw-r--r--libstdc++-v3/include/debug/unordered_set2
-rw-r--r--libstdc++-v3/include/debug/vector2
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_dir.h59
-rw-r--r--libstdc++-v3/include/experimental/memory_resource18
-rw-r--r--libstdc++-v3/include/std/tuple23
-rw-r--r--libstdc++-v3/src/c++11/cow-stdexcept.cc37
-rw-r--r--libstdc++-v3/src/filesystem/ops.cc19
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc30
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc71
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc75
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/canonical.cc20
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/copy_file.cc82
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc63
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc1
-rw-r--r--libstdc++-v3/testsuite/experimental/memory_resource/1.cc (renamed from libstdc++-v3/testsuite/experimental/type_erased_allocator/1.cc)42
-rw-r--r--libstdc++-v3/testsuite/experimental/memory_resource/null_memory_resource.cc (renamed from libstdc++-v3/testsuite/experimental/type_erased_allocator/1_neg.cc)34
-rw-r--r--libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc87
-rw-r--r--libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc3
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp5
-rw-r--r--libvtv/ChangeLog7
-rw-r--r--libvtv/Makefile.am7
-rw-r--r--libvtv/Makefile.in17
932 files changed, 51825 insertions, 14964 deletions
diff --git a/ChangeLog b/ChangeLog
index 5dc8de35e35..7d4241766c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2016-05-20 Bill Seurer <seurer@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Fix
+ code formatting in ALTIVEC_BUILTIN_VEC_ADDE section.
+
+2016-05-20 Bill Seurer <seurer@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000-builtin.def (vec_addec): Change vec_addec to a
+ special case builtin.
+ * config/rs6000/rs6000-c.c (altivec_resolve_overloaded_builtin): Add
+ support for ALTIVEC_BUILTIN_VEC_ADDEC.
+ * config/rs6000/rs6000.c (altivec_init_builtins): Add definition
+ for __builtin_vec_addec.
+
+2016-05-16 Jakub Sejdak <jakub.sejdak@phoesys.com>
+
+ * config.guess: Import version 2016-04-02 (newest).
+ * config.sub: Import version 2016-05-10 (newest).
+
+2016-05-16 Anton Kolesov <anton.kolesov@synopsys.com>
+
+ * configure.ac: Add ARC support to libgloss.
+ * configure: Regenerate
+
+2016-05-09 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
+2016-05-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * configure.ac (mpfr): Remove pre-3.1.0 mpfr compatibility code.
+ * configure: Regenerated.
+ * Makefile.def (gmp): Explicitly disable assembler.
+ (mpfr): Adjust lib_path.
+ (mpc): Likewise.
+ * Makefile.in: Regenerated.
+
2016-05-01 Jakub Jelinek <jakub@redhat.com>
PR bootstrap/70704
diff --git a/MAINTAINERS b/MAINTAINERS
index acffe921fc3..c615168c1b3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -560,6 +560,7 @@ Iain Sandoe <iain@codesourcery.com>
Duncan Sands <baldrick@gcc.gnu.org>
Sujoy Saraswati <sujoy.saraswati@hpe.com>
Trevor Saunders <tsaunders@mozilla.com>
+Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
William Schmidt <wschmidt@linux.vnet.ibm.com>
Tilo Schwarz <tilo@tilo-schwarz.de>
Martin Sebor <msebor@gcc.gnu.org>
diff --git a/Makefile.def b/Makefile.def
index ea8453e851f..ec5f31e9cee 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -50,6 +50,7 @@ host_modules= { module= gcc; bootstrap=true;
host_modules= { module= gmp; lib_path=.libs; bootstrap=true;
// Work around in-tree gmp configure bug with missing flex.
extra_configure_flags='--disable-shared LEX="touch lex.yy.c"';
+ extra_make_flags='AM_CFLAGS="-DNO_ASM"';
no_install= true;
// none-*-* disables asm optimizations, bootstrap-testing
// the compiler more thoroughly.
@@ -57,11 +58,11 @@ host_modules= { module= gmp; lib_path=.libs; bootstrap=true;
// gmp's configure will complain if given anything
// different from host for target.
target="none-${host_vendor}-${host_os}"; };
-host_modules= { module= mpfr; lib_path=.libs; bootstrap=true;
+host_modules= { module= mpfr; lib_path=src/.libs; bootstrap=true;
extra_configure_flags='--disable-shared @extra_mpfr_configure_flags@';
extra_make_flags='AM_CFLAGS="-DNO_ASM"';
no_install= true; };
-host_modules= { module= mpc; lib_path=.libs; bootstrap=true;
+host_modules= { module= mpc; lib_path=src/.libs; bootstrap=true;
extra_configure_flags='--disable-shared @extra_mpc_gmp_configure_flags@ @extra_mpc_mpfr_configure_flags@';
no_install= true; };
host_modules= { module= isl; lib_path=.libs; bootstrap=true;
diff --git a/Makefile.in b/Makefile.in
index 1522e39ec5b..f778d03583e 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -639,12 +639,12 @@ HOST_LIB_PATH_gmp = \
@if mpfr
HOST_LIB_PATH_mpfr = \
- $$r/$(HOST_SUBDIR)/mpfr/.libs:$$r/$(HOST_SUBDIR)/prev-mpfr/.libs:
+ $$r/$(HOST_SUBDIR)/mpfr/src/.libs:$$r/$(HOST_SUBDIR)/prev-mpfr/src/.libs:
@endif mpfr
@if mpc
HOST_LIB_PATH_mpc = \
- $$r/$(HOST_SUBDIR)/mpc/.libs:$$r/$(HOST_SUBDIR)/prev-mpc/.libs:
+ $$r/$(HOST_SUBDIR)/mpc/src/.libs:$$r/$(HOST_SUBDIR)/prev-mpc/src/.libs:
@endif mpc
@if isl
@@ -11300,7 +11300,7 @@ all-gmp: configure-gmp
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
(cd $(HOST_SUBDIR)/gmp && \
- $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) $(STAGE1_FLAGS_TO_PASS) \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_HOST_FLAGS) $(STAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" \
$(TARGET-gmp))
@endif gmp
@@ -11329,7 +11329,7 @@ all-stage1-gmp: configure-stage1-gmp
CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
$(EXTRA_HOST_FLAGS) \
- $(STAGE1_FLAGS_TO_PASS) \
+ $(STAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" \
TFLAGS="$(STAGE1_TFLAGS)" \
$(TARGET-stage1-gmp)
@@ -11344,7 +11344,7 @@ clean-stage1-gmp:
fi; \
cd $(HOST_SUBDIR)/gmp && \
$(MAKE) $(EXTRA_HOST_FLAGS) \
- $(STAGE1_FLAGS_TO_PASS) clean
+ $(STAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" clean
@endif gmp-bootstrap
@@ -11371,7 +11371,7 @@ all-stage2-gmp: configure-stage2-gmp
CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
- $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" \
TFLAGS="$(STAGE2_TFLAGS)" \
$(TARGET-stage2-gmp)
@@ -11385,7 +11385,7 @@ clean-stage2-gmp:
$(MAKE) stage2-start; \
fi; \
cd $(HOST_SUBDIR)/gmp && \
- $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) clean
+ $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" clean
@endif gmp-bootstrap
@@ -11412,7 +11412,7 @@ all-stage3-gmp: configure-stage3-gmp
CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
- $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" \
TFLAGS="$(STAGE3_TFLAGS)" \
$(TARGET-stage3-gmp)
@@ -11426,7 +11426,7 @@ clean-stage3-gmp:
$(MAKE) stage3-start; \
fi; \
cd $(HOST_SUBDIR)/gmp && \
- $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) clean
+ $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" clean
@endif gmp-bootstrap
@@ -11453,7 +11453,7 @@ all-stage4-gmp: configure-stage4-gmp
CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
- $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" \
TFLAGS="$(STAGE4_TFLAGS)" \
$(TARGET-stage4-gmp)
@@ -11467,7 +11467,7 @@ clean-stage4-gmp:
$(MAKE) stage4-start; \
fi; \
cd $(HOST_SUBDIR)/gmp && \
- $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) clean
+ $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" clean
@endif gmp-bootstrap
@@ -11494,7 +11494,7 @@ all-stageprofile-gmp: configure-stageprofile-gmp
CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
- $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" \
TFLAGS="$(STAGEprofile_TFLAGS)" \
$(TARGET-stageprofile-gmp)
@@ -11508,7 +11508,7 @@ clean-stageprofile-gmp:
$(MAKE) stageprofile-start; \
fi; \
cd $(HOST_SUBDIR)/gmp && \
- $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) clean
+ $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" clean
@endif gmp-bootstrap
@@ -11535,7 +11535,7 @@ all-stagefeedback-gmp: configure-stagefeedback-gmp
CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
- $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) \
+ $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" \
TFLAGS="$(STAGEfeedback_TFLAGS)" \
$(TARGET-stagefeedback-gmp)
@@ -11549,7 +11549,7 @@ clean-stagefeedback-gmp:
$(MAKE) stagefeedback-start; \
fi; \
cd $(HOST_SUBDIR)/gmp && \
- $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) clean
+ $(MAKE) $(EXTRA_HOST_FLAGS) $(POSTSTAGE1_FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" clean
@endif gmp-bootstrap
@@ -11567,7 +11567,7 @@ check-gmp:
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) $(EXTRA_HOST_EXPORTS) \
(cd $(HOST_SUBDIR)/gmp && \
- $(MAKE) $(FLAGS_TO_PASS) $(EXTRA_BOOTSTRAP_FLAGS) check)
+ $(MAKE) $(FLAGS_TO_PASS) AM_CFLAGS="-DNO_ASM" $(EXTRA_BOOTSTRAP_FLAGS) check)
@endif gmp
@@ -11602,7 +11602,7 @@ info-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing info in gmp"; \
@@ -11627,7 +11627,7 @@ dvi-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing dvi in gmp"; \
@@ -11652,7 +11652,7 @@ pdf-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing pdf in gmp"; \
@@ -11677,7 +11677,7 @@ html-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing html in gmp"; \
@@ -11702,7 +11702,7 @@ TAGS-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing TAGS in gmp"; \
@@ -11728,7 +11728,7 @@ install-info-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing install-info in gmp"; \
@@ -11754,7 +11754,7 @@ install-pdf-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing install-pdf in gmp"; \
@@ -11780,7 +11780,7 @@ install-html-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing install-html in gmp"; \
@@ -11805,7 +11805,7 @@ installcheck-gmp: \
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing installcheck in gmp"; \
@@ -11829,7 +11829,7 @@ mostlyclean-gmp:
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing mostlyclean in gmp"; \
@@ -11853,7 +11853,7 @@ clean-gmp:
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing clean in gmp"; \
@@ -11877,7 +11877,7 @@ distclean-gmp:
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing distclean in gmp"; \
@@ -11901,7 +11901,7 @@ maintainer-clean-gmp:
r=`${PWD_COMMAND}`; export r; \
s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
$(HOST_EXPORTS) \
- for flag in $(EXTRA_HOST_FLAGS) ; do \
+ for flag in $(EXTRA_HOST_FLAGS) AM_CFLAGS="-DNO_ASM"; do \
eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
done; \
echo "Doing maintainer-clean in gmp"; \
diff --git a/config.guess b/config.guess
index dcd5149681d..0967f2afa92 100755
--- a/config.guess
+++ b/config.guess
@@ -2,7 +2,7 @@
# Attempt to guess a canonical system name.
# Copyright 1992-2016 Free Software Foundation, Inc.
-timestamp='2016-01-01'
+timestamp='2016-04-02'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -237,6 +237,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
exit ;;
+ *:LibertyBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/^.*BSD\.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-libertybsd${UNAME_RELEASE}
+ exit ;;
*:ekkoBSD:*:*)
echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
exit ;;
@@ -268,42 +272,42 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
case "$ALPHA_CPU_TYPE" in
"EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
+ UNAME_MACHINE=alpha ;;
"EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
+ UNAME_MACHINE=alphaev5 ;;
"EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
+ UNAME_MACHINE=alphaev56 ;;
"EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
+ UNAME_MACHINE=alphapca56 ;;
"EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
+ UNAME_MACHINE=alphapca57 ;;
"EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
+ UNAME_MACHINE=alphaev6 ;;
"EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
+ UNAME_MACHINE=alphaev67 ;;
"EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
+ UNAME_MACHINE=alphaev68 ;;
"EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
+ UNAME_MACHINE=alphaev69 ;;
"EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
+ UNAME_MACHINE=alphaev7 ;;
"EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
+ UNAME_MACHINE=alphaev79 ;;
esac
# A Pn.n version is a patched version.
# A Vn.n version is a released version.
# A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
@@ -376,16 +380,16 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;;
i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
eval $set_cc_for_build
- SUN_ARCH="i386"
+ SUN_ARCH=i386
# If there is a compiler, see if it is configured for 64-bit objects.
# Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
# This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
- SUN_ARCH="x86_64"
+ SUN_ARCH=x86_64
fi
fi
echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
@@ -410,7 +414,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
exit ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ test "x${UNAME_RELEASE}" = x && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
@@ -635,13 +639,13 @@ EOF
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 523) HP_ARCH=hppa1.0 ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH=hppa1.1 ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ 32) HP_ARCH=hppa2.0n ;;
+ 64) HP_ARCH=hppa2.0w ;;
+ '') HP_ARCH=hppa2.0 ;; # HP-UX 10.20
esac ;;
esac
fi
@@ -680,11 +684,11 @@ EOF
exit (0);
}
EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ (CCOPTS="" $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
fi ;;
esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
+ if [ ${HP_ARCH} = hppa2.0w ]
then
eval $set_cc_for_build
@@ -697,12 +701,12 @@ EOF
# $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
# => hppa64-hp-hpux11.23
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ if echo __LP64__ | (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) |
grep -q __LP64__
then
- HP_ARCH="hppa2.0w"
+ HP_ARCH=hppa2.0w
else
- HP_ARCH="hppa64"
+ HP_ARCH=hppa64
fi
fi
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@@ -807,14 +811,14 @@ EOF
echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_PROC=`uname -m | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ FUJITSU_SYS=`uname -p | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
@@ -896,7 +900,7 @@ EOF
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr "[:upper:]" "[:lower:]"``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
@@ -919,7 +923,7 @@ EOF
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ if test "$?" = 0 ; then LIBC=gnulibc1 ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
@@ -1272,6 +1276,9 @@ EOF
SX-8R:SUPER-UX:*:*)
echo sx8r-nec-superux${UNAME_RELEASE}
exit ;;
+ SX-ACE:SUPER-UX:*:*)
+ echo sxace-nec-superux${UNAME_RELEASE}
+ exit ;;
Power*:Rhapsody:*:*)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
exit ;;
@@ -1285,9 +1292,9 @@ EOF
UNAME_PROCESSOR=powerpc
fi
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if [ "$CC_FOR_BUILD" != no_compiler_found ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ (CCOPTS="" $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
@@ -1309,7 +1316,7 @@ EOF
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
+ if test "$UNAME_PROCESSOR" = x86; then
UNAME_PROCESSOR=i386
UNAME_MACHINE=pc
fi
@@ -1340,7 +1347,7 @@ EOF
# "uname -m" is not consistent, so use $cputype instead. 386
# is converted to i386 for consistency with other x86
# operating systems.
- if test "$cputype" = "386"; then
+ if test "$cputype" = 386; then
UNAME_MACHINE=i386
else
UNAME_MACHINE="$cputype"
@@ -1382,7 +1389,7 @@ EOF
echo i386-pc-xenix
exit ;;
i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE} | sed -e 's/ .*$//'`
exit ;;
i*86:rdos:*:*)
echo ${UNAME_MACHINE}-pc-rdos
diff --git a/config.sub b/config.sub
index da6d1b6826a..6d86a1e2f77 100755
--- a/config.sub
+++ b/config.sub
@@ -2,7 +2,7 @@
# Configuration validation subroutine script.
# Copyright 1992-2016 Free Software Foundation, Inc.
-timestamp='2016-01-01'
+timestamp='2016-05-10'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -1382,7 +1382,7 @@ case $os in
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -bitrig* | -openbsd* | -solidbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* | -libertybsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
@@ -1399,7 +1399,7 @@ case $os in
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* \
- | -onefs* | -tirtos*)
+ | -onefs* | -tirtos* | -phoenix*)
# Remember, each alternative MUST END IN *, to match a version number.
;;
-qnx*)
@@ -1531,6 +1531,8 @@ case $os in
;;
-nacl*)
;;
+ -ios)
+ ;;
-none)
;;
*)
diff --git a/configure b/configure
index d17b477f127..ea63784be9c 100755
--- a/configure
+++ b/configure
@@ -3756,9 +3756,6 @@ case "${target}" in
sh*-*-pe|mips*-*-pe|*arm-wince-pe)
noconfigdirs="$noconfigdirs tcl tk itcl libgui sim"
;;
- arc-*-*|arceb-*-*)
- noconfigdirs="$noconfigdirs target-libgloss"
- ;;
arm-*-pe*)
noconfigdirs="$noconfigdirs target-libgloss"
;;
@@ -5568,16 +5565,9 @@ if test "x$with_mpfr_lib" != x; then
gmplibs="-L$with_mpfr_lib $gmplibs"
fi
if test "x$with_mpfr$with_mpfr_include$with_mpfr_lib" = x && test -d ${srcdir}/mpfr; then
- # MPFR v3.1.0 moved the sources into a src sub-directory.
- if test -d ${srcdir}/mpfr/src; then
- gmplibs='-L$$r/$(HOST_SUBDIR)/mpfr/src/'"$lt_cv_objdir $gmplibs"
- gmpinc='-I$$r/$(HOST_SUBDIR)/mpfr/src -I$$s/mpfr/src '"$gmpinc"
- extra_mpc_mpfr_configure_flags='--with-mpfr-include=$$s/mpfr/src --with-mpfr-lib=$$r/$(HOST_SUBDIR)/mpfr/src/'"$lt_cv_objdir"
- else
- gmplibs='-L$$r/$(HOST_SUBDIR)/mpfr/'"$lt_cv_objdir $gmplibs"
- gmpinc='-I$$r/$(HOST_SUBDIR)/mpfr -I$$s/mpfr '"$gmpinc"
- extra_mpc_mpfr_configure_flags='--with-mpfr-include=$$s/mpfr --with-mpfr-lib=$$r/$(HOST_SUBDIR)/mpfr/'"$lt_cv_objdir"
- fi
+ gmplibs='-L$$r/$(HOST_SUBDIR)/mpfr/src/'"$lt_cv_objdir $gmplibs"
+ gmpinc='-I$$r/$(HOST_SUBDIR)/mpfr/src -I$$s/mpfr/src '"$gmpinc"
+ extra_mpc_mpfr_configure_flags='--with-mpfr-include=$$s/mpfr/src --with-mpfr-lib=$$r/$(HOST_SUBDIR)/mpfr/src/'"$lt_cv_objdir"
# Do not test the mpfr version. Assume that it is sufficient, since
# it is in the source tree, and the library has not been built yet
# but it would be included on the link line in the version check below
diff --git a/configure.ac b/configure.ac
index 3aec655d219..54558df98ab 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1092,9 +1092,6 @@ case "${target}" in
sh*-*-pe|mips*-*-pe|*arm-wince-pe)
noconfigdirs="$noconfigdirs tcl tk itcl libgui sim"
;;
- arc-*-*|arceb-*-*)
- noconfigdirs="$noconfigdirs target-libgloss"
- ;;
arm-*-pe*)
noconfigdirs="$noconfigdirs target-libgloss"
;;
@@ -1548,16 +1545,9 @@ if test "x$with_mpfr_lib" != x; then
gmplibs="-L$with_mpfr_lib $gmplibs"
fi
if test "x$with_mpfr$with_mpfr_include$with_mpfr_lib" = x && test -d ${srcdir}/mpfr; then
- # MPFR v3.1.0 moved the sources into a src sub-directory.
- if test -d ${srcdir}/mpfr/src; then
- gmplibs='-L$$r/$(HOST_SUBDIR)/mpfr/src/'"$lt_cv_objdir $gmplibs"
- gmpinc='-I$$r/$(HOST_SUBDIR)/mpfr/src -I$$s/mpfr/src '"$gmpinc"
- extra_mpc_mpfr_configure_flags='--with-mpfr-include=$$s/mpfr/src --with-mpfr-lib=$$r/$(HOST_SUBDIR)/mpfr/src/'"$lt_cv_objdir"
- else
- gmplibs='-L$$r/$(HOST_SUBDIR)/mpfr/'"$lt_cv_objdir $gmplibs"
- gmpinc='-I$$r/$(HOST_SUBDIR)/mpfr -I$$s/mpfr '"$gmpinc"
- extra_mpc_mpfr_configure_flags='--with-mpfr-include=$$s/mpfr --with-mpfr-lib=$$r/$(HOST_SUBDIR)/mpfr/'"$lt_cv_objdir"
- fi
+ gmplibs='-L$$r/$(HOST_SUBDIR)/mpfr/src/'"$lt_cv_objdir $gmplibs"
+ gmpinc='-I$$r/$(HOST_SUBDIR)/mpfr/src -I$$s/mpfr/src '"$gmpinc"
+ extra_mpc_mpfr_configure_flags='--with-mpfr-include=$$s/mpfr/src --with-mpfr-lib=$$r/$(HOST_SUBDIR)/mpfr/src/'"$lt_cv_objdir"
# Do not test the mpfr version. Assume that it is sufficient, since
# it is in the source tree, and the library has not been built yet
# but it would be included on the link line in the version check below
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index a045faeefdb..2559db408a8 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,7 @@
+2016-05-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * download_prerequisites: Adjust gmp/mpfr/mpc versions.
+
2016-04-30 Oleg Endo <olegendo@gcc.gnu.org>
* compare-all-tests: Remove SH5 support.
diff --git a/contrib/download_prerequisites b/contrib/download_prerequisites
index cf97ec9daa8..b135f5fe5f1 100755
--- a/contrib/download_prerequisites
+++ b/contrib/download_prerequisites
@@ -4,7 +4,7 @@
# Run this from the top level of the gcc source tree and the gcc
# build will do the right thing.
#
-# (C) 2010 Free Software Foundation
+# (C) 2010-2016 Free Software Foundation
#
# 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
@@ -30,9 +30,9 @@ if [ ! -e gcc/BASE-VER ] ; then
fi
# Necessary to build GCC.
-MPFR=mpfr-2.4.2
-GMP=gmp-4.3.2
-MPC=mpc-0.8.1
+MPFR=mpfr-3.1.4
+GMP=gmp-6.1.0
+MPC=mpc-1.0.3
wget ftp://gcc.gnu.org/pub/gcc/infrastructure/$MPFR.tar.bz2 || exit 1
tar xjf $MPFR.tar.bz2 || exit 1
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ff0b573b0c9..4218dab37bb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,3057 @@
+2016-05-23 Martin Jambor <mjambor@suse.cz>
+
+ * hsa-gen.c (gen_hsa_insns_for_switch_stmt): Create an empty
+ default block if a PHI node in the original one would be resized.
+
+2016-05-23 Venkataramanan Kumar <venkataramanan.kumar@amd.com>
+
+ PR tree-optimization/58135
+ * tree-vect-slp.c: When group size is not multiple
+ of vector size, allow splitting of store group at
+ vector boundary.
+
+2016-05-23 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * config/arm/arm_neon.h (vtst_p16, vtstq_p16): New.
+
+2016-05-22 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/sse.md (vec_set_lo_<mode><mask_name>,
+ vec_set_hi_<mode><mask_name>): Add && <mask_avx512dq_condition>
+ condition. For !TARGET_AVX512DQ, emit 32x4 instruction instead
+ of 64x2.
+
+ * config/i386/sse.md (vec_set_lo_v16hi, vec_set_hi_v16hi,
+ vec_set_lo_v32qi, vec_set_hi_v32qi): Add alternative with
+ v constraint instead of x and vinserti32x4 insn.
+
+ * config/i386/sse.md (i128vldq): New mode iterator.
+ (avx2_vbroadcasti128_<mode>, avx_vbroadcastf128_<mode>): Add
+ avx512dq and avx512vl alternatives.
+
+ * config/i386/sse.md (avx2_vec_dupv4df): Use v instead of x
+ constraint, use maybe_evex prefix instead of vex.
+ (vec_dupv4sf): Use v constraint instead of x for output
+ operand except for noavx alternative, use Yv constraint
+ instead of x for input. Use maybe_evex prefix instead of vex.
+ (*vec_dupv4si): Likewise.
+ (*vec_dupv2di): Likewise.
+
+2016-05-22 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR middle-end/40921
+ * tree-ssa-reassoc.c (try_special_add_to_ops): New.
+ (linearize_expr_tree): Call try_special_add_to_ops.
+ (reassociate_bb): Convert MULT_EXPR by (-1) to NEGATE_EXPR.
+
+2016-05-21 Senthil Kumar Selvaraj <senthil_kumar.selvaraj@atmel.com>
+
+ * config/avr/avr.c (avr_expand_prologue): Add INCOMING_FRAME_SP_OFFSET
+ to computed stack_usage.
+
+2016-05-21 Pitchumani Sivanupandi <pitchumani.s@atmel.com>
+
+ PR target/71103
+ * config/avr/avr.md (define_expand "mov<mode>"): If the source
+ operand is subreg (symbol_ref) then move the symbol ref to register.
+
+2016-05-21 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree.c (array_at_struct_end_p): Look through MEM_REF.
+
+2016-05-21 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR middle-end/71179
+ * tree-ssa-reassoc.c (transform_add_to_multiply): Disallow float
+ VECTOR type.
+
+2016-05-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-vrp.c (compare_values_warnv): Simplify handling of symbolic
+ ranges by calling get_single_symbol and tidy up. Look more closely
+ into NAME + CST1 vs CST2 comparisons if type overflow is undefined.
+
+2016-05-20 Jeff Law <law@redhat.com>
+
+ * bitmap.c (bitmap_find_bit): Remove useless test.
+
+2016-05-20 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * function.c (thread_prologue_and_epilogue_insns): Commit the
+ insertion of the epilogue.
+
+2016-05-20 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/70884
+ * tree-sra.c (initialize_constant_pool_replacements): Do not check
+ should_scalarize_away_bitmap and cannot_scalarize_away_bitmap bits.
+ (sort_and_splice_var_accesses): Do not consider multiple scalar reads
+ of constant pool data as a reason for scalarization.
+
+2016-05-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/arm/arm.c (arm_expand_prologue): Set the stack usage to 0
+ for naked functions.
+ (thumb1_expand_prologue): Likewise.
+
+2016-05-20 Nathan Sidwell <nathan@acm.org>
+
+ * config/nvptx/nptx.c (nvptx_option_override): Only set
+ flag_toplevel_reorder, if not explicitly specified. Set
+ flag_no_common, unless explicitly specified.
+
+2016-05-20 David Malcolm <dmalcolm@redhat.com>
+
+ * calls.c (can_implement_as_sibling_call_p): Mark param
+ reg_parm_stack_space with ATTRIBUTE_UNUSED.
+
+2016-05-20 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc/config/i386/i386.c (ix86_rtx_costs) <case CONST_DOUBLE>:
+ Use IS_STACK_MODE when calculating cost of standard 80387 constants.
+ Fallthru to CONST_VECTOR case to calculate cost of standard SSE
+ constants.
+ <case CONST_WIDE_INT>: Calculate cost of (MEM (SYMBOL_REF)).
+ (ix86_legitimate_constant_p): Use CASE_CONST_SCALAR_INT
+ and CASE_CONST_ANY.
+
+2016-05-20 Cesar Philippidis <cesar@codesourcery.com>
+
+ * config/nvptx/nvptx.md (sincossf3): New pattern.
+
+2016-05-20 David Malcolm <dmalcolm@redhat.com>
+
+ * calls.c (maybe_complain_about_tail_call): New function.
+ (initialize_argument_information): Call
+ maybe_complain_about_tail_call when clearing *may_tailcall.
+ (can_implement_as_sibling_call_p): Call
+ maybe_complain_about_tail_call when returning false.
+ (expand_call): Read CALL_EXPR_MUST_TAIL_CALL and, if set,
+ ensure try_tail_call is set. Call maybe_complain_about_tail_call
+ if tail-call optimization fails.
+ * cfgexpand.c (expand_call_stmt): Initialize
+ CALL_EXPR_MUST_TAIL_CALL from gimple_call_must_tail_p.
+ * gimple-pretty-print.c (dump_gimple_call): Dump
+ gimple_call_must_tail_p.
+ * gimple.c (gimple_build_call_from_tree): Call
+ gimple_call_set_must_tail with the value of
+ CALL_EXPR_MUST_TAIL_CALL.
+ * gimple.h (enum gf_mask): Add GF_CALL_MUST_TAIL_CALL.
+ (gimple_call_set_must_tail): New function.
+ (gimple_call_must_tail_p): New function.
+ * print-tree.c (print_node): Update printing of TREE_STATIC
+ to reflect its use for CALL_EXPR_MUST_TAIL_CALL.
+ * tree-core.h (struct tree_base): Add MUST_TAIL_CALL to the
+ trailing comment listing applicable flags.
+ * tree.h (CALL_EXPR_MUST_TAIL_CALL): New macro.
+
+2016-05-20 David Malcolm <dmalcolm@redhat.com>
+
+ * calls.c (expand_call): Move "Rest of purposes for tail call
+ optimizations to fail" to...
+ (can_implement_as_sibling_call_p): ...this new function, and
+ split into multiple "if" statements.
+
+2016-05-20 Jan Hubicka <hubicka@ucw.cz>
+
+ * cfgloop.h (expected_loop_iterations_unbounded,
+ expected_loop_iterations): Unconstify.
+ * cfgloopanal.c (expected_loop_iterations_unbounded): Sanity check the
+ profile with known upper bound; return 3 when profile is absent.
+ (expected_loop_iterations): Update.
+
+2016-05-20 Jan Hubicka <hubicka@ucw.cz>
+
+ * loop-doloop.c (doloop_optimize): Use get_estimated_loop_iterations_int
+ and get_max_loop_iterations_int.
+
+2016-05-20 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-ssa-loop-niter.c (idx_infer_loop_bounds): We can not produce
+ realistic upper bounds here.
+
+2016-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/71210
+ * gimple-fold.c (gimple_fold_call): Do not remove lhs of noreturn
+ calls if the LHS is variable length or has addressable type.
+ If targets[0]->decl is a noreturn call with void return type and
+ zero arguments, adjust fntype and remove lhs in that case.
+
+2016-05-20 Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/71079
+ PR tree-optimization/71206
+ * match.pd ((X ^ Y) ^ (X ^ Z)): Convert the arguments.
+
+2016-05-20 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * tree-vectorizer.c (get_vec_alignment_for_decl): New static function.
+ (get_vec_alignment_for_array_decl): Likewise.
+ (get_vec_alignment_for_record_decl): Likewise.
+ (increase_alignment::execute): Move code to find alignment to
+ get_vec_alignment_for_array_decl and call get_vec_alignment_for_decl.
+ (type_align_map): New hash_map.
+
+2016-05-20 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/29756
+ * tree.def (BIT_INSERT_EXPR): New tcc_expression tree code.
+ * expr.c (expand_expr_real_2): Handle BIT_INSERT_EXPR.
+ * fold-const.c (operand_equal_p): Likewise.
+ (fold_ternary_loc): Add constant folding of BIT_INSERT_EXPR.
+ * gimplify.c (gimplify_expr): Handle BIT_INSERT_EXPR.
+ * tree-inline.c (estimate_operator_cost): Likewise.
+ * tree-pretty-print.c (dump_generic_node): Likewise.
+ * tree-ssa-operands.c (get_expr_operands): Likewise.
+ * cfgexpand.c (expand_debug_expr): Likewise.
+ * gimple-pretty-print.c (dump_ternary_rhs): Likewise.
+ * gimple.c (get_gimple_rhs_num_ops): Handle BIT_INSERT_EXPR.
+ * tree-cfg.c (verify_gimple_assign_ternary): Verify BIT_INSERT_EXPR.
+ * tree-ssa.c (non_rewritable_lvalue_p): We can rewrite
+ vector inserts using BIT_FIELD_REF or MEM_REF on the lhs.
+ (execute_update_addresses_taken): Do it.
+
+2016-05-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71185
+ * tree-ssa-loop-prefetch.c (gather_memory_references): Drop
+ register operations.
+
+2016-05-20 Richard Biener <rguenther@suse.de>
+
+ * tree-if-conv.c (add_bb_predicate_gimplified_stmts): Use
+ gimple_seq_add_seq_without_update.
+ (release_bb_predicate): Assert we have no operands to free.
+ (if_convertible_loop_p_1): Calculate post dominators later.
+ Do not free BB predicates here.
+ (combine_blocks): Do not recompute BB predicates.
+ (version_loop_for_if_conversion): Save BB predicates around
+ loop versioning.
+
+2016-05-19 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * function.c (make_epilogue_seq): Remove epilogue_end parameter.
+ (thread_prologue_and_epilogue_insns): Remove bb_flags. Restructure
+ code. Ignore sibcalls on EDGE_IGNORE edges.
+ * shrink-wrap.c (handle_simple_exit): New function. Set EDGE_IGNORE
+ on edges for sibcalls that run without prologue. The rest of the
+ function is combined from...
+ (fix_fake_fallthrough_edge): ... this, and ...
+ (try_shrink_wrapping): ... a part of this. Remove the bb_with
+ function argument, make it a local variable.
+
+2016-05-19 Sandra Loosemore <sandra@codesourcery.com>
+
+ * config/i386/cygming.h (DWARF2_UNWIND_INFO): Allow
+ --disable-sjlj-exceptions for TARGET_BI_ARCH to select DWARF-2 EH
+ for 32-bit mode and SEH for 64-bit.
+ * config/i386/mingw32.h (SHARED_LIBGCC_UNDEFS_SPEC): Handle
+ TARGET_64BIT_DEFAULT.
+
+2016-05-19 Ryan Burn <contact@rnburn.com>
+
+ * Makefile.in (GTFILES): Add cilk.h and cilk-common.c.
+ * gengtype.c (open_base_files): Add cilk.h to ifiles.
+
+2016-05-19 Uros Bizjak <ubizjak@gmail.com>
+
+ * sched-deps.c (sched_analyze_2) <case TRAP_IF>: Also
+ force pending loads from memory.
+
+2016-05-19 Kelvin Nilsen <kelvin@gcc.gnu.org>
+
+ * config/rs6000/altivec.md (UNSPEC_DARN): New unspec constant.
+ (UNSPEC_DARN_32): New unspec constant.
+ (UNSPEC_DARN_RAW): New unspec constant.
+ (darn_32): New instruction.
+ (darn_raw): New instruction.
+ (darn): New instruction.
+ * config/rs6000/rs6000-builtin.def (RS6000_BUILTIN_0): Add
+ support and documentation for this macro.
+ (BU_P9_MISC_1): New macro definition.
+ (BU_P9_64BIT_MISC_0): New macro definition.
+ (BU_P9_MISC_0): New macro definition.
+ (darn_32): New builtin definition.
+ (darn_raw): New builtin definition.
+ (darn): New builtin definition.
+ * config/rs6000/rs6000.c: Add #define RS6000_BUILTIN_0 and #undef
+ RS6000_BUILTIN_0 directives to surround each occurrence of
+ #include "rs6000-builtin.def".
+ (rs6000_builtin_mask_calculate): Add in the RS6000_BTM_MODULO and
+ RS6000_BTM_64BIT flags to the returned mask, depending on
+ configuration.
+ (def_builtin): Correct an error in the assignments made to the
+ debugging variable attr_string.
+ (rs6000_expand_builtin): Add support for no-operand built-in
+ functions.
+ (builtin_function_type): Remove fatal_error assertion that is no
+ longer valid.
+ (rs6000_common_init_builtins): Add support for no-operand built-in
+ functions.
+ * config/rs6000/rs6000.h (RS6000_BTM_MODULO): New macro
+ definition.
+ (RS6000_BTM_PURE): Enhance comment to clarify intent of this flag
+ definition.
+ (RS6000_BTM_64BIT): New macro definition.
+ * doc/extend.texi: Document __builtin_darn (void),
+ __builtin_darn_raw (void), and __builtin_darn_32 (void) built-in
+ functions.
+
+2016-05-19 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-vect-loop.c (vect_analyze_loop_2): Use also
+ max_loop_iterations_int.
+
+2016-05-19 Marek Polacek <polacek@redhat.com>
+
+ PR tree-optimization/71031
+ * tree-vrp.c (extract_range_from_binary_expr_1): Turn assert into a
+ condition and adjust the code a bit.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * tree-vect-stmts.c (vectorizable_simd_clone_call): Utilize
+ auto_vec instead of vec.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * tree-parloops.c (oacc_entry_exit_ok): Release a vector.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * tree-if-conv.c (ifcvt_repair_bool_pattern): Utilize auto_vecs.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * ipa-pure-const.c (set_function_state): Remove an existing
+ funct_state.
+ (remove_node_data): Do not free it as it's released
+ in set_function_state.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * tree-vect-slp.c (vect_attempt_slp_rearrange_stmts): Release
+ bitmap.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * omp-simd-clone.c (simd_clone_adjust): Release vector.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-reassoc.c (eliminate_duplicate_pair): Truncate
+ an auto_vec instead of re-creating it.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-loop-prefetch.c (determine_loop_nest_reuse): Use
+ auto_vec instead of vec.
+
+2016-05-19 Martin Liska <mliska@suse.cz>
+
+ * lto-section-in.c (lto_get_section_data): Call
+ lto_check_version with additional argument.
+ * lto-streamer.c (lto_check_version): Add new argument.
+ * lto-streamer.h (lto_check_version): Likewise.
+
+2016-05-19 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (arm_new_rtx_costs, SIGN_EXTEND case):
+ Don't add cost of inner memory when handling sign-extended loads.
+
+2016-05-19 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR rtl-optimization/71148
+ * cse.c (cse_main): Free dominance info.
+ (rest_of_handle_cse): Don't free dominance info.
+ (rest_of_handle_cse2): Likewise.
+ (rest_of_handle_cse_after_global_opts): Likewise.
+
+2016-05-19 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/71056
+ * config/arm/arm-builtins.c (arm_builtin_vectorized_function): Return
+ NULL_TREE early if NEON is not available. Remove now redundant check
+ in ARM_CHECK_BUILTIN_MODE.
+
+2016-05-19 Maxim Ostapenko <m.ostapenko@samsung.com>
+
+ PR sanitizer/64354
+ * cppbuiltin.c (define_builtin_macros_for_compilation_flags): Add new
+ builtin __SANITIZE_THREAD__ macros for fsanitize=thread switch.
+ * doc/cpp.texi: Document new macros.
+
+2016-05-19 Bin Cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/69848
+ * tree-vect-loop.c (vectorizable_reduction): Don't factor
+ comparison expr out of VEC_COND_EXPR for COND_REDUCTION.
+
+2016-05-19 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * function.c (thread_prologue_and_epilogue_insn): Move the
+ "goto epilogue_done" one block later.
+
+2016-05-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70729
+ * passes.def: Move LIM pass before PRE. Remove no longer
+ required copyprop and move first DCE out of the loop pipeline.
+
+2016-05-18 David Malcolm <dmalcolm@redhat.com>
+
+ PR driver/69265
+ * Makefile.in (GCC_OBJS): Move spellcheck.o to...
+ (OBJS-libcommon-target): ...here.
+ * opts-common.c: Include spellcheck.h.
+ (cmdline_handle_error): Build a vec of valid options and use it
+ to suggest provide hints for misspelled arguments.
+
+2016-05-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/71100
+ * cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Don't drop
+ lhs if it has TREE_ADDRESSABLE type.
+
+2016-05-18 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/71145
+ * config/alpha/alpha.md (trap): Add (use (reg:DI 29)).
+ (*exception_receiver_1): Return "#" for TARGET_EXPLICIT_RELOCS.
+
+2016-05-18 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/69708
+ * ipa-cp.c (ipa_get_jf_pass_through_result): Allow non-ip constant
+ input for NOP_EXPR pass-through functions.
+ * ipa-prop.c (ipa_compute_jump_functions_for_edge): Allow
+ aggregate global constant VAR_DECLs in constant jump functions.
+
+2016-05-18 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/69708
+ * ipa-prop.c (parm_preserved_before_stmt_p): Return true for loads
+ from TREE_READONLY parameters.
+
+2016-05-18 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/69708
+ * cgraph.h (cgraph_indirect_call_info): New field
+ guaranteed_unmodified.
+ * ipa-cp.c (ipa_get_indirect_edge_target_1): Also pass parameter value
+ to ipa_find_agg_cst_for_param, check guaranteed_unmodified when
+ appropriate.
+ * ipa-inline-analysis.c (evaluate_conditions_for_known_args): Also
+ pass the parameter value to ipa_find_agg_cst_for_param.
+ * ipa-prop.c (ipa_load_from_parm_agg): New parameter
+ guaranteed_unmodified, store AA results there instead of bailing out
+ if present.
+ (ipa_note_param_call): Also initialize guaranteed_unmodified flag.
+ (ipa_analyze_indirect_call_uses): Also set guaranteed_unmodified flag.
+ (find_constructor_constant_at_offset): New function.
+ (ipa_find_agg_cst_from_init): Likewise.
+ (ipa_find_agg_cst_for_param): Also seearch for aggregate values in
+ static initializers of contants, report back through a new paameter
+ from_global_constant if that was the case.
+ (try_make_edge_direct_simple_call): Also pass parameter value to
+ ipa_find_agg_cst_for_param, check guaranteed_unmodified when
+ appropriate.
+ (ipa_write_indirect_edge_info): Stream new flag guaranteed_unmodified.
+ (ipa_read_indirect_edge_info): Likewise.
+ * ipa-prop.h (ipa_find_agg_cst_for_param): Update declaration.
+ (ipa_load_from_parm_agg): Likewise.
+
+2016-05-18 Jiong Wang <jiong.wang@arm.com>
+
+ PR rtl-optimization/71150
+ * lra-constraint (process_addr_reg): Guard "in_class_p" with REG_P
+ check.
+
+2016-05-18 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/70915
+ * config/rs6000/constraints.md (wE constraint): New constraint
+ for a vector constant that can be loaded with XXSPLTIB.
+ (wM constraint): New constraint for a vector constant of a 1's.
+ (wS constraint): New constraint for a vector constant that can be
+ loaded with XXSPLTIB and a vector sign extend instruction.
+ * config/rs6000/predicates.md (xxspltib_constant_split): New
+ predicates for wE/wS constraints.
+ (xxspltib_constant_nosplit): Likewise.
+ (easy_vector_constant): Add support for constants that can be
+ loaded via XXSPLTIB.
+ (all_ones_constant): New predicate for vector constant with all
+ 1's set.
+ (splat_input_operand): Add support for ISA 3.0 word splat operations.
+ * config/rs6000/rs6000.c (xxspltib_constant_p): New function to
+ return if a constant can be loaded with the ISA 3.0 XXSPLTIB
+ instruction and possibly with a sign extension.
+ (output_vec_const_move): Add support for XXSPLTIB. If we are
+ loading up 0/-1 into Altivec registers, prefer using VSPLTISW
+ instead of XXLXOR/XXLORC.
+ (rs6000_expand_vector_init): Add support for ISA 3.0 word splat
+ operations.
+ (rs6000_legitimize_reload_address): Likewise.
+ (rs6000_output_move_128bit): Use output_vec_const_move to emit
+ constants.
+ * config/rs6000/vsx.md (VSX_M): Add TImode (if -mvsx-timode) and
+ combine VSX_M and VSX_M2 into one iterator.
+ (VSX_M2): Likewise.
+ (VSINT_84): New iterators for loading constants with XXSPLTIB.
+ (VSINT_842): Likewise.
+ (UNSPEC_VSX_SIGN_EXTEND): New UNSPEC.
+ (xxspltib_v16qi): New insns to load up constants with the ISA 3.0
+ XXSPLTIB instruction.
+ (xxspltib_<mode>_nosplit): Likewise.
+ (xxspltib_<mode>_split): New insn to load up constants with
+ XXSPLTIB and a sign extend instruction.
+ (vsx_mov<mode>): Replace single move that handled all vector types
+ with separate 32-bit and 64-bit moves. Combine the movti_<bit>
+ moves (when -mvsx-timode is in effect) into the main vector
+ moves. Eliminate separate moves for <VSr> <VSa>, where the
+ preferred register class (<VSr>) is listed first, and the
+ secondary register class (<VSa>) is listed second with a '?' to
+ discourage use. Prefer loading 0/-1 in any VSX register for ISA
+ 3.0, and Altivec registers for ISA 2.06/2.07 (PR target/70915) so
+ that if the register was involved in a slow operation, the
+ clear/set operation does not wait for the slow operation to
+ finish. Adjust the length attributes for 32-bit mode. Use
+ rs6000_output_move_128bit and drop the use of the string
+ instructions for 32-bit movti when -mvsx-timode is in effect. Use
+ spacing so that the alternatives and attributes don't generate
+ long lines, and put things in columns, so that it is easier to
+ match up the operands and attributes with the insn alternatives.
+ (vsx_mov<mode>_64bit): Likewise.
+ (vsx_mov<mode>_32bit): Likewise.
+ (vsx_movti_64bit): Fold movti into normal vector moves.
+ (vsx_movti_32bit): Likewise.
+ (vsx_splat_<mode>, V4SI/V4SF modes): Add support for ISA 3.0 word
+ splat instructions.
+ (vsx_splat_v4si_internal): Likewise.
+ (vsx_splat_v4sf_internal): Likewise.
+ (vector fusion peepholes): Use VSX_M instead of VSX_M2.
+ (vsx_sign_extend_qi_<mode>): New ISA 3.0 instructions to sign
+ extend vector elements.
+ (vsx_sign_extend_hi_<mode>): Likewise.
+ (vsx_sign_extend_si_v2di): Likewise.
+ * config/rs6000/rs6000-protos.h (xxspltib_constant_p): Add
+ declaration.
+ * doc/md.texi (PowerPC constraints): Document the wE, wM, and wS
+ constraints. Add trailing period to wL documentation.
+
+2016-05-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR middle-end/71020
+ * tree-dfa.h (replace_abnormal_ssa_names): Declare.
+ * tree-dfa.c (replace_abnormal_ssa_names): New function.
+ * tree-call-cdce.c: Include tree-dfa.h.
+ (can_guard_call_p): New function, extracted from...
+ (can_use_internal_fn): ...here.
+ (shrink_wrap_one_built_in_call_with_conds): Remove failure path
+ and return void.
+ (shrink_wrap_one_built_in_call): Likewise.
+ (use_internal_fn): Likewise.
+ (shrink_wrap_conditional_dead_built_in_calls): Update accordingly
+ and return void. Call replace_abnormal_ssa_names.
+ (pass_call_cdce::execute): Check can_guard_call_p during the
+ initial walk. Assume shrink_wrap_conditional_dead_built_in_calls
+ will always change something.
+
+2016-05-18 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/70646
+ * ipa-prop.c (determine_locally_known_aggregate_parts): Bail out early
+ if parameter PARAM_IPA_MAX_AGG_ITEMS is zero.
+
+2016-05-18 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/70646
+ * ipa-inline.h (condition): New field size.
+ * ipa-inline-analysis.c (add_condition): New parameter SIZE, use it
+ for comaprison and store it into the new condition.
+ (evaluate_conditions_for_known_args): Use condition size to check
+ access sizes for all but CHANGED conditions.
+ (unmodified_parm_1): New parameter size_p, store access size into it.
+ (unmodified_parm): Likewise.
+ (unmodified_parm_or_parm_agg_item): Likewise.
+ (eliminated_by_inlining_prob): Pass NULL to unmodified_parm as size_p.
+ (set_cond_stmt_execution_predicate): Extract access sizes and store
+ them to conditions.
+ (set_switch_stmt_execution_predicate): Likewise.
+ (will_be_nonconstant_expr_predicate): Likewise.
+ (will_be_nonconstant_predicate): Likewise.
+ (inline_read_section): Stream condition size.
+ (inline_write_summary): Likewise.
+
+2016-05-18 Richard Biener <rguenther@suse.de>
+
+ * tree-ssa-loop-im.c (determine_max_movement): Properly add
+ condition cost to PHI cost instead of total_cost.
+
+2016-05-18 Martin Liska <mliska@suse.cz>
+
+ PR fortran/70856
+ * ipa-icf.c (sem_variable::merge): Set DECL_PT_UID for
+ merged variables.
+
+2016-05-18 Richard Biener <rguenther@suse.de>
+
+ * lto-streamer.h (LTO_major_version): Bump to 6.
+
+2016-05-18 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * function.c (make_split_prologue_seq, make_prologue_seq,
+ make_epilogue_seq): New functions, factored out from...
+ (thread_prologue_and_epilogue_insns): Here.
+
+2016-05-18 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * function.c (rest_of_handle_thread_prologue_and_epilogue): Call
+ cleanup_cfg with CLEANUP_EXPENSIVE after shrink-wrapping instead
+ of before. Add a comment.
+
+2016-05-18 Bin Cheng <bin.cheng@arm.com>
+
+ * tree-ssa-loop-ivopts.c (get_computation_cost_at): Check invariant
+ expression pointer, not pointer to the pointer.
+
+2016-05-18 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/sse.md (pbroadcast_evex_isa): New mode attr.
+ (avx2_pbroadcast<mode>): Add another alternative with v instead
+ of x constraints in it, using <pbroadcast_evex_isa> isa.
+ (avx2_pbroadcast<mode>_1): Similarly, add two such alternatives.
+
+ * config/i386/sse.md (<ssse3_avx2>_palignr<mode>): Use
+ constraint x instead of v in second alternative, add avx512bw
+ alternative.
+
+ * config/i386/sse.md (<ssse3_avx2>_pshufb<mode>3<mask_name>): Use
+ constraint x instead of v in second alternative, add avx512bw
+ alternative.
+
+ * config/i386/sse.md (*<ssse3_avx2>_pmulhrsw<mode>3<mask_name>): Use
+ constraint x instead of v in second alternative, add avx512bw
+ alternative.
+
+ * config/i386/sse.md (avx2_pmaddubsw256, ssse3_pmaddubsw128): Add
+ avx512bw alternative.
+
+2016-05-18 Kirill Yukhin <kirill.yukhin@intel.com>
+
+ * gcc/config/i386/sse.md (define_insn "*andnot<mode>3"): Extend static
+ array to 128 chars.
+ (define_insn "*andnottf3"): Ditto.
+ (define_insn "*<code><mode>3"/any_logic): Ditto.
+ (define_insn "*<code>tf3"/any_logic): Ditto.
+ (define_insn "sse2_storehpd"): Use Yv constraint for scalar
+ operand to block AVX-512VL insn variant emit when it is not enabled.
+
+2016-05-18 Kirill Yukhin <kirill.yukhin@intel.com>
+
+ * config/i386/sse.md (define_insn "*vec_concatv2sf_sse4_1"): Use 'Yv'
+ constraint fot SF mode.
+
+2016-05-18 Petr Murzin <petr.murzin@intel.com>
+ Kirill Yukhin <kirill.yukhin@intel.com>
+
+ * config/i386/sse.md (define_insn "srcp14<mode>"): Use proper operand
+ modifiers.
+ (define_insn "rsqrt14<mode>"): Ditto.
+ (define_insn "<mask_codefor>avx512dq_cvtps2qqv2di<mask_name>"): Ditto.
+ (define_insn "<fixsuffix>fix_truncv2sfv2di2<mask_name>"): Ditto.
+ (define_insn "avx512f_<code>v8div16qi2_mask_store"): Ditto.
+ (define_insn "vec_set_hi_<mode><mask_name>"): Ditto.
+ (define_insn "<mask_codefor>avx512dq_broadcast<mode><mask_name>"):
+ Ditto.
+ (define_insn "*avx512f_gatherdi<mode>"): Ditto.
+ (define_insn "*avx512f_scatterdi<mode>"): Ditto.
+ * config/i386/i386.c (ix86_print_operand): Expand check for size
+ override codes for Intel syntax.
+
+2016-05-18 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71168
+ * tree-loop-distribution.c (distribute_loop): Move *destroy_p
+ initialization earlier.
+
+2016-05-18 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-simd.md
+ (aarch64_reduc_plus_internal<mode>): Rename to...
+ (reduc_plus_scal): ...This, and remove previous implementation.
+
+2016-05-18 Richard Biener <rguenther@suse.de>
+
+ * passes.def: Put late dse and cd_dce in canonical order.
+
+2016-05-17 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-inline-transform.c (preserve_function_body_p): Look for
+ first non-thunk clone.
+ (save_function_body): Save into first non-thunk.
+ * lto-cgraph.c (lto_output_edge): When streaming thunk do not look
+ up call stmt id.
+ (lto_output_node): Inline thunks don't need body in every
+ partition.
+ * lto-streamer-in.c: Do not fixup thunk clones.
+ * cgraphclones.c (cgraph_node::create_edge_including_clone): Skip
+ thunks.
+ * tree-inline.c (copy_bb): Be prepared for target node to be new after
+ folding suceeds.
+
+2016-05-17 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR middle-end/63586
+ * tree-ssa-reassoc.c (transform_add_to_multiply): New.
+ (reassociate_bb): Call transform_add_to_multiply.
+
+2016-05-17 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ * config/aarch64/aarch64.c (all_extensions): Removed unused
+ static variable.
+
+2016-05-17 Nathan Sidwell <nathan@acm.org>
+
+ * config/nvptx/nvptx.c (nvptx_function_arg_boundary): New.
+ (TARGET_FUNCTION_ARG_BOUNDARY): Override.
+
+2016-05-17 Mikhail Maltsev <maltsevm@gmail.com>
+
+ PR tree-optimization/54579
+ PR middle-end/55299
+ * match.pd (~(~X >> Y), ~(~X >>r Y), ~(~X <<r Y)): New patterns.
+
+2016-05-17 Marek Polacek <polacek@redhat.com>
+
+ PR ipa/71146
+ * tree-inline.c (expand_call_inline): Call
+ maybe_remove_unused_call_args.
+
+2016-05-17 Jim Wilson <jim.wilson@linaro.org>
+
+ * doc/cpp.texi (__GNUC__): Major version changes are no longer rare.
+ * doc/invoke.texi (-mnan=2008): Change signalling to signaling.
+ * doc/md.texi (fmin@var{m}3): Likewise.
+
+2016-05-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * match.pd (X & C): New transformation.
+
+2016-05-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * match.pd (~X & Y): New transformation.
+
+2016-05-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * tree-vrp.c (simplify_truth_ops_using_ranges): Set range
+ information for new SSA_NAME.
+ (simplify_conversion_using_ranges): Get range through get_range_info
+ instead of get_value_range.
+
+2016-05-17 Jiong Wang <jiong.wang@arm.com>
+
+ * config/aarch64/arm_neon.h (vmvn_s8): Reimplement using C operator.
+ Remove inline assembly.
+ (vmvn_s16): Likewise.
+ (vmvn_s32): Likewise.
+ (vmvn_u8): Likewise.
+ (vmvn_u16): Likewise.
+ (vmvn_u32): Likewise.
+ (vmvnq_s8): Likewise.
+ (vmvnq_s16): Likewise.
+ (vmvnq_s32): Likewise.
+ (vmvnq_u8): Likewise.
+ (vmvnq_u16): Likewise.
+ (vmvnq_u32): Likewise.
+ (vmvn_p8): Likewise.
+ (vmvnq_p16): Likewise.
+
+2016-05-17 Jiong Wang <jiong.wang@arm.com>
+
+ * config/aarch64/aarch64-simd.md (vmul_n_f32): Remove inline assembly.
+ Use builtin.
+ (vmul_n_s16): Likewise.
+ (vmul_n_s32): Likewise.
+ (vmul_n_u16): Likewise.
+ (vmul_n_u32): Likewise.
+ (vmulq_n_f32): Likewise.
+ (vmulq_n_f64): Likewise.
+ (vmulq_n_s16): Likewise.
+ (vmulq_n_s32): Likewise.
+ (vmulq_n_u16): Likewise.
+ (vmulq_n_u32): Likewise.
+
+2016-05-17 Jiong Wang <jiong.wang@arm.com>
+
+ * config/aarch64/aarch64-simd.md (*aarch64_mul3_elt_to_128df): Extend
+ to all supported modes. Rename to "*aarch64_mul3_elt_from_dup".
+
+2016-05-17 Jiong Wang <jiong.wang@arm.com>
+
+ * config/aarch64/aarch64-simd.md (*aarch64_fma4_elt_to_128df): Rename
+ to *aarch64_fma4_elt_from_dup<mode>.
+ (*aarch64_fnma4_elt_to_128df): Rename to
+ *aarch64_fnma4_elt_from_dup<mode>.
+ * config/aarch64/arm_neon.h (vfma_n_f64): New.
+ (vfms_n_f32): Likewise.
+ (vfms_n_f64): Likewise.
+ (vfmsq_n_f32): Likewise.
+ (vfmsq_n_f64): Likewise.
+
+2016-05-17 Gerald Pfeifer <gerald@pfeifer.com>
+
+ * wide-int.h: Change fixed_wide_int_storage from class to struct.
+
+2016-05-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71132
+ * tree-loop-distribution.c (create_rdg_cd_edges): Pass in loop.
+ Only add control dependences for blocks in the loop.
+ (build_rdg): Adjust.
+ (generate_code_for_partition): Return whether loop should
+ be destroyed and delay that.
+ (distribute_loop): Likewise.
+ (pass_loop_distribution::execute): Record loops to be destroyed
+ and perform delayed destroying of loops.
+
+2016-05-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/70809
+ * config/aarch64/aarch64-simd.md (aarch64_vmls<mode>): Delete.
+
+2016-05-17 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-elf.h (ASM_OUTPUT_DEF): Delete.
+
+2016-05-17 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR target/71114
+ * config/i386/i386.c (dimode_scalar_chain::convert_op): Fix
+ insertion point for instructions generated by validize_mem.
+
+2016-05-17 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64.c (SHIFT_COUNT_TRUNCATED): Wrap definition
+ in brackets.
+
+2016-05-17 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64.c
+ (aarch64_output_simd_mov_immediate): Make "buf_size" a variable
+ rather than a macro.
+
+2016-05-16 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * doc/invoke.texi (AArch64 Options): Various updates.
+
+2016-05-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-inline-analysis.c (compute_inline_parameters): Disable inlinig
+ into instrumentation thunks.
+ * cif-code.def (CIF_CHKP): New.
+
+2016-05-16 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/xopintrin.h: Correct "unsinged" typo in the comments.
+
+2016-05-16 Martin Jambor <mjambor@suse.cz>
+
+ * hsa-gen.c (fillup_for_decl): Increase alignment to natural one.
+ (get_symbol_for_decl): Sorry if a global symbol in under-aligned.
+
+2016-05-16 Marek Polacek <polacek@redhat.com>
+
+ * gimple.c (maybe_remove_unused_call_args): Fix typos in the
+ commentary.
+
+2016-05-16 Martin Jambor <mjambor@suse.cz>
+
+ PR hsa/70857
+ * omp-low.c (grid_expand_target_grid_body): Copy RESULT_DECL of
+ the outlined kernel function.
+
+2016-05-16 Robert Suchanek <robert.suchanek@imgtec.com>
+
+ * config/mips/mips.h (ISA_HAS_LSA): Enable for -mmsa.
+ (ISA_HAS_DLSA): Ditto.
+
+2016-05-16 Matthew Fortune <matthew.fortune@imgtec.com>
+
+ * config/mips/m5100.md (m51_int_load): Update the latency to 2.
+
+2016-05-16 Nathan Sidwell <nathan@acm.org>
+
+ * config/nvptx/nvptx.c (nvptx_mangle_decl_assembler_name): Revert.
+ (nvptx_name_replacement): Restore. Add comment.
+ (write_fn_proto, write_fn_proto_from_insn,
+ nvptx_output_call_insn): Restore
+ (TARGET_MANGLE_DECL_ASSEMBLER_NAME): Delete.
+
+2016-05-16 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * config/aarch64/aarch64.md
+ (add<mode>3_compareC_cconly_imm): Remove use of %w.
+ (add<mode>3_compareC_imm): Likewise.
+ (<optab>si3_uxtw): Split into register and immediate variants.
+ (andsi3_compare0_uxtw): Likewise.
+ (and<mode>3_compare0): Likewise.
+ (and<mode>3nr_compare0): Likewise.
+ (stack_protect_test_<mode>): Don't use %x for memory operands.
+
+2016-05-16 Matthew Fortune <matthew.fortune@imgtec.com>
+
+ * config/mips/mips-cpus.def (p5600): Add multi-line brackets.
+
+2016-05-16 Wilco Dijkstra <wdijkstr@arm.com>
+
+ * gcc/config/aarch64/aarch64.md (aarch64_ashl_sisd_or_int_<mode>3):
+ Split integer shifts into shift_reg and bfm.
+ (aarch64_lshr_sisd_or_int_<mode>3): Likewise.
+ (aarch64_ashr_sisd_or_int_<mode>3): Likewise.
+ (ror<mode>3_insn): Likewise.
+ (<optab>si3_insn_uxtw): Likewise.
+ (<optab><mode>3_insn): Change to rotate_imm.
+ (extr<mode>5_insn_alt): Likewise.
+ (extrsi5_insn_uxtw): Likewise.
+ (extrsi5_insn_uxtw_alt): Likewise.
+
+2016-05-16 Matthew Wahab <matthew.wahab@arm.com>
+
+ * doc/tm.texi: Regenerate.
+ * doc/tm.texi.in (TARGET_INVALID_PARAMETER_TYPE): Remove.
+ (TARGET_INVALID_RETURN_TYPE): Remove.
+ * system.h: Poison TARGET_INVALID_PARAMETER_TYPE and
+ TARGET_INVALID_RETURN_TYPE.
+ * target.def (invalid_parameter_type): Remove.
+ (invalid_return_type): Remove.
+
+2016-05-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-inline-analysis.c (compute_inline_parameters): Be more reailistic
+ on estimating thunk bodies; do not set inline_failed to CIF_THUNK for
+ calls from thunk.
+ * ipa-inline-transform.c (inline_call): When inlining into thunk produce
+ gimple body.
+ (preserve_function_body_p): No need to preserve function body
+ * cif-codes.def (CIF_THUNK): Remove.
+ * cgraphclones.c (duplicate_thunk_for_node): Thunks calls are inlinable.
+
+2016-05-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-inline.c (expand_call_inline): recurse after inlining thunk.
+
+2016-05-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree.c (free_lang_data_in_decl): Also set target/optimization flags
+ for thunks.
+
+2016-05-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-inline.c (report_inline_failed_reason): Look into thunks, too
+ (inline_small_functions): Do not look for function symbol when
+ resetting caches.
+
+2016-05-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * lto-cgraph.c (compute_ltrans_boundary, output_symtab): Fix handling
+ of inline thunks
+
+2016-05-16 Matthew Wahab <matthew.wahab@arm.com>
+ Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+ Jiong Wang <jiong.wang@arm.com>
+
+ * config/arm/arm-c.c (arm_cpu_builtins): Use def_or_undef_macro
+ for __ARM_FP16_FORMAT_IEEE and __ARM_FP16_FORMAT_ALTERNATIVE.
+ Define __ARM_FP16_ARGS when appropriate.
+ * config/arm/arm.c (arm_invalid_parameter_type): Remove
+ declaration.
+ (arm_invalid_return_type): Likewise.
+ (TARGET_INVALID_PARAMETER_TYPE): Remove.
+ (TARGET_INVALID_RETURN_TYPE): Remove.
+ (aapcs_vfp_sub_candidate): Allow HFmode.
+ (aapcs_vfp_allocate): Add comment. Support HFmode.
+ (aapcs_vfp_allocate_return_reg): Likewise.
+ (struct aapcs_cp_arg_layout): Slightly reword comments for
+ is_return_candidate and allocate_return_reg.
+ (output_mov_vfp): Update assert.
+ (arm_hard_regno_mode_ok): Remove comment, update HF-mode
+ condition.
+ (arm_invalid_parameter_type): Remove.
+ (amr_invalid_return_type): Remove.
+ * config/arm/arm.h (TARGET_NEON_FP16): Fix definition.
+ * config/arm/arm.md (*arm32_movhf): Disable for TARGET_VFP.
+ * config/arm/vfp.md (*movhf_vfp): Enable for TARGET_VFP.
+
+2016-05-16 Matthew Wahab <matthew.wahab@arm.com>
+
+ * config/aarch64/aarch64.h (LEGITIMIZE_RELOAD_ADDRESS): Remove.
+ * config/aarch64/arch64-protos.h
+ (aarch64_legitimize_reload_address): Remove.
+ * config/aarch64/aarch64.c (aarch64_legitimize_reload_address):
+ Remove.
+
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * configure.ac: Add ACX_NONCANONICAL_HOST.
+ * configure: Regenerate.
+ * Makefile.in: Set host_noncanonical.
+
+2016-05-14 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/71097
+ * config/i386/i386.md (*movtf_internal): Before register allocation,
+ do not allow FP constants for CM_MEDIUM memory model, allow only
+ standard FP constants for CM_LARGE and CM_LARGE_PIC models.
+ (*movxf_internal): Ditto.
+ (*movdf_internal): Ditto.
+ (*movsf_internal): Ditto.
+
+2016-05-13 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/67483
+ * combine.c (make_compound_operation): Don't call extract_left_shift
+ with negative shift amounts.
+
+2016-05-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/71071
+ * fold-const.c (fold_checksum_tree): Allow modification
+ of TYPE_ALIAS_SET during folding.
+
+ * config/i386/i386.c (ix86_compute_frame_layout, ix86_expand_prologue,
+ ix86_expand_split_stack_prologue): Use HOST_WIDE_INT_C macro.
+ (ix86_split_to_parts): Likewise. Fix up formatting.
+
+2016-05-13 H.J. Lu <hongjiu.lu@intel.com>
+
+ * tree-ssa-loop-ivopts.c (create_new_ivs): Cast to
+ unsigned HOST_WIDE_INT with HOST_WIDE_INT_PRINT_UNSIGNED in
+ printf format.
+
+2016-05-13 Nathan Sidwell <nathan@acm.org>
+
+ * config/nvptx/nvptx.c (nvptx_mangle_decl_assembler_name): New.
+ (nvptx_name_replacement): Delete.
+ (write_fn_proto, write_fn_proto_from_insn,
+ nvptx_output_call_insn): Remove nvptx_name_replacement call.
+ (TARGET_MANGLE_DECL_ASSEMBLER_NAME): Override.
+ * langhooks.c (add_builtin_funcction_common): Call
+ targetm.mangle_decl_assembler_name.
+
+ * config/nvptx/nvptx.c (write_fn_proto): Handle
+ BUILT_IN_ATOMIC_COMPARE_EXCHANGE_n oddity.
+
+2016-05-13 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-loop-ivopts.c (create_new_ivs): Use HOST_WIDE_INT_PRINT_DEC
+ and PRIu64 in printf format.
+
+2016-05-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * tree-ssa-loop-ivanon.c (try_unroll_loop_completely): Typo fix in
+ comment.
+
+2016-05-13 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * tree-ssa-loop-ivcanon.c (try_unroll_loop_completely):
+ Change --param max-completely-peeled-times to
+ --param max-completely-peel-times in dump file printing.
+
+2016-05-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/42587
+ * tree-ssa-math-opts.c (perform_symbolic_merge): Handle BIT_FIELD_REF.
+ (find_bswap_or_nop_1): Likewise.
+ (bswap_replace): Likewise.
+
+2016-05-13 Martin Liska <mliska@suse.cz>
+
+ * tree-vect-patterns.c (vect_recog_mask_conversion_pattern):
+ Initialize a variable with default value.
+
+2016-05-13 Martin Liska <mliska@suse.cz>
+
+ * doc/invoke.texi: Enhance explanation of error recovery
+ of sanitizers.
+
+2016-05-13 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-loop-ivopts.c (avg_loop_niter): Fix coding style.
+ (struct cost_pair): Change inv_expr_id (int) to inv_expr
+ (iv_inv_expr_ent *).
+ (struct iv_inv_expr_ent): Comment struct fields.
+ (sort_iv_inv_expr_ent): New function.
+ (struct ivopts_data): Rename inv_expr_id to max_inv_expr_id.
+ (struct iv_ca): Replace used_inv_expr and num_used_inv_expr with
+ a hash_map between iv_inv_expr_ent and number of usages.
+ (niter_for_exit): Fix coding style.
+ (tree_ssa_iv_optimize_init): Use renamed variable.
+ (determine_base_object): Fix coding style.
+ (alloc_iv): Likewise.
+ (find_interesting_uses_outside): Likewise.
+ (add_candidate_1): Likewise.
+ (add_standard_iv_candidates): Likewise.
+ (set_group_iv_cost): Replace inv_expr_id with inv_expr.
+ (prepare_decl_rtl): Fix coding style.
+ (get_address_cost): Likewise.
+ (get_shiftadd_cost): Likewise.
+ (force_expr_to_var_cost): Likewise.
+ (compare_aff_trees): Likewise.
+ (get_expr_id): Restructure the function.
+ (get_loop_invariant_expr_id): Renamed to
+ get_loop_invariant_expr.
+ (get_computation_cost_at): Replace usage of inv_expr_id with
+ inv_expr.
+ (get_computation_cost): Likewise.
+ (determine_group_iv_cost_generic): Likewise.
+ (determine_group_iv_cost_address): Likewise.
+ (iv_period): Fix coding style.
+ (iv_elimination_compare_lt): Likewise.
+ (may_eliminate_iv): Likewise.
+ (determine_group_iv_cost_cond): Replace usage of inv_expr_id with
+ inv_expr.
+ (determine_group_iv_costs): Dump invariant expressions.
+ (iv_ca_recount_cost): Use the newly added hash_map.
+ (iv_ca_set_remove_invariants): Fix coding style.
+ (iv_ca_set_add_invariants): Fix coding style.
+ (iv_ca_set_no_cp): Utilize the newly added hash_map for used
+ invariants.
+ (iv_ca_set_cp): Likewise.
+ (iv_ca_new): Initialize the newly added hash_map and remove
+ initialization of fields.
+ (iv_ca_free): Delete the hash_map.
+ (iv_ca_dump): Dump invariant expressions.
+ (iv_ca_extend): Fix coding style.
+ (try_add_cand_for): Likewise.
+ (create_new_ivs): Dump information about # of avg iterations and
+ # of used invariant expressions.
+ (rewrite_use_compare): Fix coding style.
+ (free_loop_data): Set default value for max_inv_expr_id.
+
+2016-05-13 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ * cse.c (rest_of_handle_cse): Use cleanup_cfg
+ returned value cse_cfg_altered computation.
+ (rest_of_handle_cse2): Likewise.
+ (rest_of_handle_cse_after_global_opts): Likewise.
+
+2016-05-13 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ PR target/53440
+ * config/arm/arm.c (arm32_output_mi_thunk): New.
+ (arm_output_mi_thunk): Rename to arm_thumb1_mi_thunk. Rework
+ to split Thumb1 vs TARGET_32BIT functionality.
+ (arm_thumb1_mi_thunk): New.
+
+2016-05-13 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ * config/aarch64/aarch64.c (TARGET_OMIT_STRUCT_RETURN_REG): Set
+ to true.
+
+2016-05-13 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ PR target/71080
+ * config/i386/i386.c (ix86_in_large_data_p): Guard against NULL exp.
+
+2016-05-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * builtins.c (expand_builtin_memcmp): Do not emit the call here.
+ (expand_builtin_trap): Emit a regular call.
+ (set_builtin_user_assembler_name): Remove obsolete cases.
+ * dse.c (scan_insn): Adjust.
+ * except.c: Include calls.h.
+ (sjlj_emit_function_enter): If DONT_USE_BUILTIN_SETJMP is defined,
+ emit a regular call to setjmp.
+ * expr.c (emit_block_move_hints): Call emit_block_copy_via_libcall.
+ (block_move_libcall_safe_for_call_parm): Use memcpy builtin.
+ (emit_block_move_via_libcall): Delete.
+ (block_move_fn): Delete.
+ (init_block_move_fn): Likewise.
+ (emit_block_move_libcall_fn): Likewise.
+ (emit_block_op_via_libcall): New function.
+ (set_storage_via_libcall): Tidy up and use memset builtin.
+ (block_clear_fn): Delete.
+ (init_block_clear_fn): Likewise.
+ (clear_storage_libcall_fn): Likewise.
+ (expand_assignment): Call emit_block_move_via_libcall.
+ Do not include gt-expr.h.
+ * expr.h (emit_block_op_via_libcall): Declare.
+ (emit_block_copy_via_libcall): New inline function.
+ (emit_block_move_via_libcall): Likewise.
+ (emit_block_comp_via_libcall): Likewise.
+ (block_clear_fn): Delete.
+ (init_block_move_fn): Likewise.
+ (init_block_clear_fn): Likewise.
+ (emit_block_move_via_libcall): Likewise.
+ (set_storage_via_libcall): Add default parameter value.
+ * libfuncs.h (enum libfunc_index): Remove obsolete values.
+ (abort_libfunc): Delete.
+ (memcpy_libfunc): Likewise.
+ (memmove_libfunc): Likewise.
+ (memcmp_libfunc): Likewise.
+ (memset_libfunc): Likewise.
+ (setbits_libfunc): Likewise.
+ (setjmp_libfunc): Likewise.
+ (longjmp_libfunc): Likewise.
+ (profile_function_entry_libfunc): Likewise.
+ (profile_function_exit_libfunc): Likewise.
+ (gcov_flush_libfunc): Likewise.
+ * optabs-libfuncs.c (build_libfunc_function): Set DECL_ARTIFICIAL
+ and DECL_VISIBILITY on the declaration.
+ (init_optabs): Do not initialize obsolete libfuncs.
+ * optabs.c (prepare_cmp_insn): Call emit_block_comp_via_libcall.
+ * tree-core.h (ECF_RET1): Define.
+ (ECF_TM_PURE): Adjust.
+ (ECF_TM_BUILTIN): Likewise.
+ * tree.c (set_call_expr_flags): Deal with ECF_RET1.
+ (build_common_builtin_nodes): Initialize abort builtin.
+ Add ECF_RET1 on memcpy, memmove and memset builtins.
+ Pass final flags for alloca and alloca_with_align builtins.
+ * config/alpha/alpha.c (alpha_init_libfuncs): Do not initialize
+ obsolete builtins.
+ * config/ia64/ia64.c (ia64_vms_init_libfuncs): Likewise.
+ * config/i386/i386.c (ix86_expand_set_or_movmem): Adjust call to
+ set_storage_via_libcall and call emit_block_copy_via_libcall.
+
+2016-05-12 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*call_got_x32): Change operand 0 to
+ DImode before it is passed to ix86_output_call_operand.
+ (*call_value_got_x32): Ditto for operand 1.
+
+2016-05-12 Jiong Wang <jiong.wang@arm.com>
+
+ PR rtl-optimization/70904
+ * lra-constraint.c (process_addr_reg): Relax the restriction on subreg
+ reload for wide mode.
+
+2016-05-12 Marek Polacek <polacek@redhat.com>
+
+ PR c/70756
+ * langhooks-def.h (lhd_incomplete_type_error): Adjust declaration.
+ * langhooks.c (lhd_incomplete_type_error): Add location parameter.
+ * langhooks.h (incomplete_type_error): Likewise.
+ * tree.c (size_in_bytes_loc): Renamed from size_in_bytes. Add location
+ parameter, pass it down to incomplete_type_error.
+ * tree.h (size_in_bytes): New inline overload.
+ (size_in_bytes_loc): Renamed from size_in_bytes.
+
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71059
+ * tree-ssa-pre.c (phi_translate_1): Fully fold translated
+ nary before looking up or entering the expression into the VN
+ hashes.
+ * tree-ssa-sccvn.c (vn_nary_build_or_lookup): Fix comment typo.
+ Make sure to re-use NARYs without result as inserted by
+ phi-translation.
+
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71062
+ * tree-ssa-alias.h (struct pt_solution): Add vars_contains_restrict
+ field.
+ * tree-ssa-structalias.c (set_uids_in_ptset): Set
+ vars_contains_restrict if the var is a restrict tag.
+ * tree-ssa-alias.c (ptrs_compare_unequal): If vars_contains_restrict
+ do not disambiguate pointers against it.
+ (dump_points_to_solution): Re-structure and adjust for new
+ vars_contains_restrict flag.
+ * gimple-pretty-print.c (pp_points_to_solution): Likewise.
+
+2016-05-12 Martin Liska <mliska@suse.cz>
+
+ * doc/invoke.texi: Explain connection between
+ -fsanitize-recover=address and ASAN_OPTIONS="halt_on_error=1".
+
+2016-05-12 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR tree-optimization/71006
+ * tree-vect-loop.c (vect_determine_vectorization_factor): Don't
+ consider COND_EXPR as a mask producer.
+
+2016-05-12 Marek Polacek <polacek@redhat.com>
+
+ PR driver/71063
+ * opts.c (common_handle_option): Detect missing argument for --help^.
+
+2016-05-12 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/70830
+ * config/arm/arm.c (arm_output_multireg_pop): Avoid POP instruction
+ when popping the PC and within an interrupt handler routine.
+ Add missing tab to output of "ldmfd".
+ (output_return_instruction): Output LDMFD with SP update rather
+ than POP when returning from interrupt handler.
+
+2016-05-12 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.md (isa): Add x64_avx512dq, enable if
+ TARGET_64BIT && TARGET_AVX512DQ.
+ * config/i386/sse.md (*vec_extract<mode>): Add avx512bw alternatives.
+ (*vec_extract<PEXTR_MODE12:mode>_zext): Add avx512bw alternative.
+ (*vec_extract<ssevecmodelower>_0, *vec_extractv4si_0_zext,
+ *vec_extractv2di_0_sse): Use v constraint instead of x constraint.
+ (*vec_extractv4si): Add avx512dq and avx512bw alternatives.
+ (*vec_extractv4si_zext): Add avx512dq alternative.
+ (*vec_extractv2di_1): Add x64_avx512dq and avx512bw alternatives,
+ use v instead of x constraint in other alternatives where possible.
+
+ * config/i386/sse.md (sse2_loadld): Use v instead of x
+ constraint in alternatives 0,1,4.
+
+ * config/i386/sse.md (pinsr_evex_isa): New mode attr.
+ (<sse2p4_1>_pinsr<ssemodesuffix>): Add 2 alternatives with
+ v constraints instead of x and <pinsr_evex_isa> isa attribute.
+
+ PR target/71019
+ * config/i386/sse.md (<sse2_avx2>_packssdw<mask_name>,
+ <sse4_1_avx2>_packusdw<mask_name>): Make sure EVEX encoded insn
+ is not emitted unless TARGET_AVX512BW.
+ (<sse2_avx2>_packuswb<mask_name>, <sse2_avx2>_packsswb<mask_name>):
+ Likewise. For TARGET_AVX512BW, use "=v" constraint instead of "=x"
+ for the result operand.
+
+ * config/i386/sse.md (*vec_setv4sf_sse4_1, sse4_1_insertps): Use v
+ constraint instead of x in avx alternatives. Use maybe_evex instead
+ of vex prefix.
+
+ * config/i386/constraints.md (Yv): New constraint.
+ * config/i386/i386.h (VALID_AVX512VL_128_REG_MODE): Allow
+ TFmode and V1TImode in xmm16+ registers for TARGET_AVX512VL.
+ * config/i386/i386.md (avx512fvecmode): New mode attr.
+ (*pushtf): Use v constraint instead of x.
+ (*movtf_internal): Likewise. For TARGET_AVX512VL and
+ xmm16+ registers, use vmovdqu64 or vmovdqa64 instructions.
+ (*absneg<mode>2): Use Yv constraint instead of x constraint.
+ (*absnegtf2_sse): Likewise.
+ (copysign<mode>3_const, copysign<mode>3_var): Likewise.
+ * config/i386/sse.md (*andnot<mode>3): Add avx512vl and
+ avx512f alternatives.
+ (*andnottf3, *<code><mode>3, *<code>tf3): Likewise.
+
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71060
+ * tree-data-ref.c (initialize_data_dependence_relation): Do not
+ require exact match of DR_BASE_OBJECT but only matching address and
+ type.
+
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70986
+ * cfganal.c: Include cfgloop.h.
+ (dfs_find_deadend): Prefer to take edges exiting loops.
+
+2016-05-11 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/pr70963.c: Require at least power8 at both
+ compile and run time.
+
+2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
+
+ PR c/43651
+ * doc/invoke.texi (Wduplicate-decl-specifier): Document new option.
+
+2016-05-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.c (legitimize_pic_address): Use
+ copy_to_suggested_reg instead of gen_movsi.
+
+2016-05-11 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/predicates.md (quad_memory_operand): Move most of
+ the code into quad_address_p and call it to share code with
+ vsx_quad_dform_memory_operand.
+ (vsx_quad_dform_memory_operand): New predicate for ISA 3.0 vector
+ d-form support.
+ * config/rs6000/rs6000.opt (-mlra): Switch to being an option mask
+ bit instead of being a separate word. Split -mpower9-dform into
+ two switches, -mpower9-dform-scalar and -mpower9-dform-vector.
+ * config/rs6000/rs6000.c (RELOAD_REG_QUAD_OFFSET): New addr_mask
+ for the register class supporting 128-bit quad word memory offsets.
+ (mode_supports_vsx_dform_quad): Helper function to return if the
+ register class uses quad word memory offsets.
+ (rs6000_debug_addr_mask): Add support for quad word memory offsets.
+ (rs6000_debug_reg_global): Always print if we are using LRA or not.
+ (rs6000_setup_reg_addr_masks): If ISA 3.0 vector d-form
+ instructions are enabled, set up the appropriate addr_masks for
+ 128-bit types.
+ (rs6000_init_hard_regno_mode_ok): wb constraint is now based on
+ -mpower9-dform-scalar, instead of -mpower9-dform.
+ (rs6000_option_override_internal): Split -mpower9-dform into two
+ switches, -mpower9-dform-scalar and -mpower9-dform-vector. The
+ -mpower9-dform switch sets or clears both. If we are not using
+ the LRA register allocator, do not enable -mpower9-dform-vector by
+ default. If we are using LRA, enable -mpower9-dform-vector and
+ -mvsx-timode if it is appropriate. Issue a warning if either
+ -mpower9-dform-vector or -mvsx-timode are explicitly used without
+ enabling LRA.
+ (quad_address_offset_p): New helper function to return if the
+ offset is legal for quad word memory instructions.
+ (quad_address_p): New function to determin if GPR or vector
+ register quad word memory addresses are legal.
+ (mem_operand_gpr): Validate quad word address offsets.
+ (reg_offset_addressing_ok_p): Add support for ISA 3.0 vector
+ d-form (register + offset) instructions.
+ (offsettable_ok_by_alignment): Likewise.
+ (rs6000_legitimate_offset_address_p): Likewise.
+ (legitimate_lo_sum_address_p): Likewise.
+ (rs6000_legitimize_address): Likewise.
+ (rs6000_legitimize_reload_address): Add more debug statements for
+ -mdebug=addr.
+ (rs6000_legitimate_address_p): Add support for ISA 3.0 vector
+ d-form instructions.
+ (rs6000_secondary_reload_memory): Add support for ISA 3.0 vector
+ d-form instructions. Distinguish different cases in debug
+ output. (rs6000_secondary_reload_inner): Add support for ISA 3.0 vector
+ d-form instructions.
+ (rs6000_preferred_reload_class): Likewise.
+ (rs6000_output_move_128bit): Add support for ISA 3.0 d-form
+ instructions. If ISA 3.0 is available, generate lxvx/stxvx instead
+ of the ISA 2.06 indexed memory instructions.
+ (rs6000_emit_prologue): If we have ISA 3.0 d-form instructions,
+ use them to save/restore the saved vector registers instead of
+ using Altivec instructions.
+ (rs6000_emit_epilogue): Likewise.
+ (rs6000_lra_p): Use TARGET_LRA instead of the old option word.
+ (rs6000_opt_masks): Split -mpower9-dform into
+ -mpower9-dform-scalar and -mpower9-dform-vector.
+ (rs6000_print_options_internal): Print -mno-<switch> if <switch>
+ was not selected.
+ * config/rs6000/vsx.md (p9_vecload_<mode>): Delete hack to emit
+ ISA 3.0 vector indexed memory instructions, and fold the code into
+ the normal mov<mode> patterns.
+ (p9_vecstore_<mode>): Likewise.
+ (vsx_mov<mode>): Add support for ISA 3.0 vector d-form
+ instructions.
+ (vsx_movti_64bit): Likewise.
+ (vsx_movti_32bit): Likewise.
+ * config/rs6000/constraints.md (wO constraint): New constraint for
+ ISA 3.0 vector d-form support.
+ * config/rs6000/rs6000-cpus.def (ISA_3_0_MASKS_SERVER): Use
+ -mpower9-dform-scalar instead of -mpower9-dform. Add note not to
+ include -mpower9-dform-vector until we switch over to LRA.
+ (POWERPC_MASKS): Add -mlra. Split -mpower9-dform into two.
+ switches, -mpower9-dform-scalar and -mpower9-dform-vector.
+ * config/rs6000/rs6000-protos.h (quad_address_p): Add declaration.
+ * doc/invoke.texi (RS/6000 and PowerPC Options): Add documentation
+ for -mpower9-dform and -mlra.
+ * doc/md.texi (wO constraint): Document wO constraint.
+
+2016-05-11 Alexander Monakov <amonakov@ispras.ru>
+
+ * genattr.c (main): Change 'rtx' to 'rtx_insn *' in prototypes of
+ 'insn_latency', 'maximal_insn_latency', 'min_insn_conflict_delay'.
+ * genautomata.c (output_internal_insn_code_evaluation): Simplify.
+ Move handling of non-insn arguments inline into the sole user:
+ (output_trans_func): ...here.
+ (output_min_insn_conflict_delay_func): Change 'rtx' to 'rtx_insn *'
+ in emitted function prototype.
+ (output_internal_insn_latency_func): Ditto. Simplify.
+ (output_internal_maximal_insn_latency_func): Ditto. Delete
+ always-unused argument.
+ (output_insn_latency_func): Ditto.
+ (output_maximal_insn_latency_func): Ditto.
+
+2016-05-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71055
+ * tree-ssa-sccvn.c (vn_reference_lookup_3): When native-interpreting
+ sth with precision not equal to access size verify we don't chop
+ off bits.
+
+2016-05-11 Richard Biener <rguenther@suse.de>
+
+ PR debug/71057
+ * dwarf2out.c (retry_incomplete_types): Set early_dwarf.
+ (dwarf2out_finish): Move retry_incomplete_types call ...
+ (dwarf2out_early_finish): ... here.
+
+2016-05-11 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/71002
+ * alias.c (reference_alias_ptr_type): Preserve alias-set zero
+ if the langhook insists on it.
+ * fold-const.c (make_bit_field_ref): Add arg for the original
+ reference and preserve its alias-set.
+ (decode_field_reference): Take exp by reference and adjust it
+ to the original memory reference.
+ (optimize_bit_field_compare): Adjust callers.
+ (fold_truth_andor_1): Likewise.
+ * gimplify.c (gimplify_expr): Adjust in-SSA form test.
+
+2016-05-11 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR middle-end/70807
+ * cfgrtl.h (delete_insn_and_edges): Now return bool.
+ * cfgrtl.c (delete_insn_and_edges): Likewise.
+ * config/i386/i386.c (convert_scalars_to_vector): Remove
+ redundant code.
+ * cse.c (cse_insn): Compute cse_cfg_altered.
+ (delete_trivially_dead_insns): Likewise.
+ (cse_cc_succs): Likewise.
+ (rest_of_handle_cse): Free dominance info if required.
+ (rest_of_handle_cse2): Likewise.
+ (rest_of_handle_cse_after_global_opts): Likewise.
+
+2016-05-11 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.c (is_complex_IBM_long_double,
+ abi_v4_pass_in_fpr): New functions.
+ (rs6000_function_arg_boundary): Exclude complex IBM long double
+ from 64-bit alignment when ABI_V4.
+ (rs6000_function_arg, rs6000_function_arg_advance_1,
+ rs6000_gimplify_va_arg): Use abi_v4_pass_in_fpr.
+
+2016-05-10 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR rtl-optimization/71028
+ * cfgcleanup.c (try_optimize_cfg): Do not flip a conditional
+ jump with just a return in the fallthrough block if the branch
+ block contains just a return as well.
+
+2016-05-10 Marc Glisse <marc.glisse@inria.fr>
+
+ * fold-const.c (fold_binary_loc) [(X ^ Y) & Y]: Remove and merge with...
+ * match.pd ((X & Y) ^ Y): ... this.
+ ((X & Y) & Y, (X | Y) | Y, (X ^ Y) ^ Y, (X & Y) & (X & Z), (X | Y)
+ | (X | Z), (X ^ Y) ^ (X ^ Z)): New transformations.
+
+2016-05-10 David Malcolm <dmalcolm@redhat.com>
+
+ * read-md.c (require_char_ws): New function.
+ (read_string): Simplify using require_char_ws.
+ (handle_constants): Likewise.
+ (handle_enum): Likewise.
+ (handle_file): Likewise.
+ * read-md.h (require_char_ws): New declaration.
+ * read-rtl.c (read_conditions): Simplify using require_char_ws.
+ (read_mapping): Likewise.
+ (read_rtx_code): Likewise.
+ (read_nested_rtx): Likewise.
+
+2016-05-10 James Norris <jnorris@codesourcery.com>
+
+ * config/rs6000/sysv4.h (CRTOFFLOADBEGIN): Define. Add crtoffloadbegin.o
+ if offloading is enabled and -fopenacc or -fopenmp is specified.
+ (CRTOFFLOADEND): Likewise.
+ (STARTFILE_LINUX_SPEC): Add CRTOFFLOADBEGIN.
+ (ENDFILE_LINUX_SPEC): Add CRTOFFLOADEND.
+
+2016-05-10 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.c (legitimize_pic_address): Merge 64-bit and 32-bit
+ gotoff_operand code paths. Use copy_to_suggested_regs and
+ expand_simple_binop where appropriate. Cleanup.
+
+2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR target/70799
+ * config/i386/i386.c (dimode_scalar_to_vector_candidate_p): Allow
+ integer constants.
+ (dimode_scalar_chain::vector_const_cost): New.
+ (dimode_scalar_chain::compute_convert_gain): Handle constants.
+ (dimode_scalar_chain::convert_op): Likewise.
+ (dimode_scalar_chain::convert_insn): Likewise.
+
+2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * dwarf2out.c (resolve_args_picking_1): Consider DW_OP_neg as an
+ unary operation, not a binary one.
+
+2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR middle-end/70877
+ * tree-chkp.c (chkp_add_bounds_to_call_stmt): Handle
+ calls with type casted fndecl.
+
+2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR tree-optimization/70786
+ * tree-chkp.c (chkp_find_bounds_1): Support WITH_SIZE_EXPR.
+ * gcc/calls.c (initialize_argument_information): Bind bounds
+ with corresponding args passed by reference.
+
+2016-05-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/70927
+ * config/i386/sse.md (<sse>_andnot<mode>3<mask_name>),
+ *<code><mode>3<mask_name>): For !TARGET_AVX512DQ and EVEX encoding,
+ use vp*[dq] instead of v*p[sd] instructions and adjust mode attribute
+ accordingly.
+
+2016-05-10 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR target/70963
+ * config/rs6000/vsx.md (vsx_xvcvdpsxds_scale): Generate correct
+ code for a zero scale factor.
+ (vsx_xvcvdpuxds_scale): Likewise.
+
+2016-05-10 David Malcolm <dmalcolm@redhat.com>
+
+ * diagnostic-show-locus.c (layout::layout): Call show_ruler
+ if show_ruler_p was set on the context.
+ (layout::show_ruler): New method.
+ * diagnostic.h (struct diagnostic_context): Add field
+ "show_ruler_p".
+
+2016-05-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71039
+ * tree-ssa-phiprop.c: Include tree-ssa-loop.h.
+ (chk_uses): New function.
+ (propagate_with_phi): Verify we can safely replicate the lhs of an
+ aggregate assignment on all incoming edges.
+
+2016-05-10 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/rx/rx-protos.h (is_interrupt_func, is_fast_interrupt_func):
+ Forward declare.
+ (rx_atomic_sequence): New class.
+ * config/rx/rx.c (rx_print_operand): Use symbolic names for PSW bits.
+ (is_interrupt_func, is_fast_interrupt_func): Make non-static and
+ non-inline.
+ (rx_atomic_sequence::rx_atomic_sequence,
+ rx_atomic_sequence::~rx_atomic_sequence): New functions.
+ * config/rx/rx.md (CTRLREG_PSW, CTRLREG_USP, CTRLREG_FPSW, CTRLREG_CPEN,
+ CTRLREG_BPSW, CTRLREG_BPC, CTRLREG_ISP, CTRLREG_FINTV,
+ CTRLREG_INTB): New constants.
+ (FETCHOP): New code iterator.
+ (fethcop_name, fetchop_name2): New iterator code attributes.
+ (QIHI): New mode iterator.
+ (atomic_exchange<mode>, atomic_exchangesi, xchg_mem<mode>,
+ atomic_fetch_<fetchop_name>si, atomic_fetch_nandsi,
+ atomic_<fetchop_name>_fetchsi, atomic_nand_fetchsi): New patterns.
+
+2016-05-10 Martin Liska <mliska@suse.cz>
+
+ * tree-inline.c (remap_dependence_clique): Do not remap
+ debugging statements.
+
+2016-05-10 Andreas Krebbel <krebbel@linux.vnet.ibm.com>
+
+ * config/s390/s390.md ("*vec_cmp<insn_cmp>df_cconly")
+ ("*fixuns_truncdfdi2_z13")
+ ("*fixuns_trunc<FP:mode><GPR:mode>2_z196")
+ ("*fix_truncdfdi2_bfp_z13", "*floatunsdidf2_z13")
+ ("*extendsfdf2_z13"): Replace TARGET_Z13 with TARGET_VX.
+
+2016-05-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70497
+ PR tree-optimization/28367
+ * tree-ssa-sccvn.c (vn_nary_build_or_lookup): New function
+ split out from ...
+ (visit_reference_op_load): ... here.
+ (vn_reference_lookup_3): Use it to handle subreg-like accesses
+ with simplified BIT_FIELD_REFs.
+ * tree-ssa-pre.c (eliminate_insert): Handle inserting BIT_FIELD_REFs.
+ * tree-complex.c (extract_component): Handle BIT_FIELD_REFs
+ correctly.
+
+2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * dwarf2out.c (add_abstract_origin_attribute): Adjust
+ documentation comment. For BLOCK nodes, add a
+ DW_AT_abstract_origin attribute that points to the DIE generated
+ for the origin BLOCK.
+ (gen_lexical_block_die): Call add_abstract_origin_attribute for
+ blocks from inlined functions.
+
+2016-05-10 Alan Modra <amodra@gmail.com>
+
+ PR target/70947
+ * config/rs6000/rs6000.c (rs6000_expand_split_stack_prologue): Stop
+ regrename modifying insns saving lr before __morestack call.
+ * config/rs6000/rs6000.md (split_stack_return): Similarly for
+ insns restoring lr after __morestack call.
+
+2016-05-09 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.md (set_got, set_got_labelled, lwp_llwpcb,
+ lwp_lwpval<mode>3, lwp_lwpins<mode>3): Remove constraints from
+ expanders.
+ * config/i386/sse.md (vec_interleave_high<mode>,
+ vec_interleave_low<mode>, <avx512>_vpermi2var<mode>3_maskz,
+ <avx512>_vpermt2var<mode>3_maskz): Likewise.
+
+2016-05-04 Aaron Sawdey <acsawdey@linux.vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (rs6000_reassociation_width): Add
+ function for TARGET_SCHED_REASSOCIATION_WIDTH to enable
+ parallel reassociation for power8 and forward.
+
+2016-05-09 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (absneg splitters with general regs): Use
+ general_reg_operand predicate.
+ (btsq peephole2): Use x86_64_immediate_operand to check if new
+ value is suitable for immediate operand. Generate emitted insn
+ using RTL expressions.
+ (btcq peephole2): Ditto.
+ (btrq peephole2): Ditto. Generate correct immediate operand
+ for AND masking.
+
+2016-05-09 Richard Sandiford <richard.sandiford@arm.com>
+
+ * cfgexpand.c (expand_debug_expr): Fix address offset for negative
+ bitpos.
+
+2016-05-09 Richard Sandiford <richard.sandiford@arm.com>
+
+ * tree-affine.c (wide_int_constant_multiple_p): Add missing
+ pointer dereference.
+
+2016-05-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70985
+ * match.pd (BIT_FIELD_REF -> (type)): Disable on GIMPLE when
+ op0 isn't a gimple register.
+
+2016-05-09 Prachi Godbole <prachi.godbole@imgtec.com>
+
+ * config/mips/i6400.md (i6400_fpu_intadd, i6400_fpu_logic)
+ (i6400_fpu_div, i6400_fpu_cmp, i6400_fpu_float, i6400_fpu_store)
+ (i6400_fpu_long_pipe, i6400_fpu_logic_l, i6400_fpu_float_l)
+ (i6400_fpu_mult): New cpu units.
+ (i6400_msa_add_d, i6400_msa_int_add, i6400_msa_short_logic3)
+ (i6400_msa_short_logic2, i6400_msa_short_logic, i6400_msa_move)
+ (i6400_msa_cmp, i6400_msa_short_float2, i6400_msa_div_d)
+ (i6400_msa_div_w, i6400_msa_div_h, i6400_msa_div_b)
+ (i6400_msa_copy, i6400_msa_branch, i6400_fpu_msa_store)
+ (i6400_fpu_msa_load, i6400_fpu_msa_move, i6400_msa_long_logic1)
+ (i6400_msa_long_logic2, i6400_msa_mult, i6400_msa_long_float2)
+ (i6400_msa_long_float4, i6400_msa_long_float5)
+ (i6400_msa_long_float8, i6400_msa_fdiv_df)
+ (i6400_msa_fdiv_sf): New reservations.
+ * config/mips/p5600.md (p5600_fpu_intadd, p5600_fpu_cmp)
+ (p5600_fpu_float, p5600_fpu_logic_a, p5600_fpu_logic_b)
+ (p5600_fpu_div, p5600_fpu_logic, p5600_fpu_float_a)
+ (p5600_fpu_float_b, p5600_fpu_float_c, p5600_fpu_float_d)
+ (p5600_fpu_mult, p5600_fpu_fdiv, p5600_fpu_load): New cpu units.
+ (msa_short_int_add, msa_short_logic, msa_short_logic_move_v)
+ (msa_short_cmp, msa_short_float2, msa_short_logic3)
+ (msa_short_store4, msa_long_load, msa_short_store)
+ (msa_long_logic, msa_long_float2, msa_long_float4)
+ (msa_long_float5, msa_long_float8, msa_long_mult)
+ (msa_long_fdiv, msa_long_div): New reservations.
+
+2016-05-09 Robert Suchanek <robert.suchanek@imgtec.com>
+ Sameera Deshpande <sameera.deshpande@imgtec.com>
+ Matthew Fortune <matthew.fortune@imgtec.com>
+ Graham Stott <graham.stott@imgtec.com>
+ Chao-ying Fu <chao-ying.fu@imgtec.com>
+
+ * config.gcc: Add MSA header file for mips*-*-* target.
+ * config/mips/constraints.md (YI, YC, YZ, Unv5, Uuv5, Usv5, Uuv6)
+ (Ubv8i, Urv8): New constraints.
+ * config/mips/mips-ftypes.def: Add function types for MSA
+ builtins.
+ * config/mips/mips-modes.def (V16QI, V8HI, V4SI, V2DI, V4SF)
+ (V2DF, V32QI, V16HI, V8SI, V4DI, V8SF, V4DF): New modes.
+ * config/mips/mips-msa.md: New file.
+ * config/mips/mips-protos.h
+ (mips_split_128bit_const_insns): New prototype.
+ (mips_msa_idiv_insns): Likewise.
+ (mips_split_128bit_move): Likewise.
+ (mips_split_128bit_move_p): Likewise.
+ (mips_split_msa_copy_d): Likewise.
+ (mips_split_msa_insert_d): Likewise.
+ (mips_split_msa_fill_d): Likewise.
+ (mips_expand_msa_branch): Likewise.
+ (mips_const_vector_same_val_p): Likewise.
+ (mips_const_vector_same_bytes_p): Likewise.
+ (mips_const_vector_same_int_p): Likewise.
+ (mips_const_vector_shuffle_set_p): Likewise.
+ (mips_const_vector_bitimm_set_p): Likewise.
+ (mips_const_vector_bitimm_clr_p): Likewise.
+ (mips_msa_vec_parallel_const_half): Likewise.
+ (mips_msa_output_division): Likewise.
+ (mips_ldst_scaled_shift): Likewise.
+ (mips_expand_vec_cond_expr): Likewise.
+ * config/mips/mips.c (enum mips_builtin_type): Add
+ MIPS_BUILTIN_MSA_TEST_BRANCH.
+ (mips_gen_const_int_vector_shuffle): New prototype.
+ (mips_const_vector_bitimm_set_p): New function.
+ (mips_const_vector_bitimm_clr_p): Likewise.
+ (mips_const_vector_same_val_p): Likewise.
+ (mips_const_vector_same_bytes_p): Likewise.
+ (mips_const_vector_same_int_p): Likewise.
+ (mips_const_vector_shuffle_set_p): Likewise.
+ (mips_symbol_insns): Forbid loading symbols via immediate for
+ MSA.
+ (mips_valid_offset_p): Limit offset to 10-bit for MSA loads and
+ stores.
+ (mips_valid_lo_sum_p): Forbid loadings symbols via %lo(base) for
+ MSA.
+ (mips_lx_address_p): Add support load indexed address for MSA.
+ (mips_address_insns): Add calculation of instructions needed for
+ stores and loads for MSA.
+ (mips_const_insns): Move CONST_DOUBLE below CONST_VECTOR. Handle
+ CONST_VECTOR for MSA and let it fall through.
+ (mips_ldst_scaled_shift): New function.
+ (mips_subword_at_byte): Likewise.
+ (mips_msa_idiv_insns): Likewise.
+ (mips_legitimize_move): Validate MSA moves.
+ (mips_rtx_costs): Add UNGE, UNGT, UNLE, UNLT cases. Add
+ calculation of costs for MSA division.
+ (mips_split_move_p): Check if MSA moves need splitting.
+ (mips_split_move): Split MSA moves if necessary.
+ (mips_split_128bit_move_p): New function.
+ (mips_split_128bit_move): Likewise.
+ (mips_split_msa_copy_d): Likewise.
+ (mips_split_msa_insert_d): Likewise.
+ (mips_split_msa_fill_d): Likewise.
+ (mips_output_move): Handle MSA moves.
+ (mips_expand_msa_branch): New function.
+ (mips_print_operand): Add 'E', 'B', 'w', 'v' and 'V' modifiers.
+ Reinstate 'y' modifier.
+ (mips_file_start): Add MSA .gnu_attribute.
+ (mips_hard_regno_mode_ok_p): Allow TImode and 128-bit vectors in
+ FPRs.
+ (mips_hard_regno_nregs): Always return 1 for MSA supported mode.
+ (mips_class_max_nregs): Add register size for MSA supported mode.
+ (mips_cannot_change_mode_class): Allow conversion between MSA
+ vector modes and TImode.
+ (mips_mode_ok_for_mov_fmt_p): Allow MSA to use move.v
+ instruction.
+ (mips_secondary_reload_class): Force MSA loads/stores via memory.
+ (mips_preferred_simd_mode): Add preffered modes for MSA.
+ (mips_vector_mode_supported_p): Add MSA supported modes.
+ (mips_autovectorize_vector_sizes): New function.
+ (mips_msa_output_division): Likewise.
+ (MSA_BUILTIN, MIPS_BUILTIN_DIRECT_NO_TARGET)
+ (MSA_NO_TARGET_BUILTIN, MSA_BUILTIN_TEST_BRANCH): New macros.
+ (CODE_FOR_msa_adds_s_b, CODE_FOR_msa_adds_s_h)
+ (CODE_FOR_msa_adds_s_w, CODE_FOR_msa_adds_s_d)
+ (CODE_FOR_msa_adds_u_b, CODE_FOR_msa_adds_u_h)
+ (CODE_FOR_msa_adds_u_w, CODE_FOR_msa_adds_u_du
+ (CODE_FOR_msa_addv_b, CODE_FOR_msa_addv_h, CODE_FOR_msa_addv_w)
+ (CODE_FOR_msa_addv_d, CODE_FOR_msa_and_v, CODE_FOR_msa_bmnz_v)
+ (CODE_FOR_msa_bmnzi_b, CODE_FOR_msa_bmz_v, CODE_FOR_msa_bmzi_b)
+ (CODE_FOR_msa_bnz_v, CODE_FOR_msa_bz_v, CODE_FOR_msa_bsel_v)
+ (CODE_FOR_msa_bseli_b, CODE_FOR_msa_ceqi_h, CODE_FOR_msa_ceqi_w)
+ (CODE_FOR_msa_ceqi_d, CODE_FOR_msa_clti_s_b)
+ (CODE_FOR_msa_clti_s_h, CODE_FOR_msa_clti_s_w)
+ (CODE_FOR_msa_clti_s_d, CODE_FOR_msa_clti_u_b)
+ (CODE_FOR_msa_clti_u_h, CODE_FOR_msa_clti_u_w)
+ (CODE_FOR_msa_clti_u_d, CODE_FOR_msa_clei_s_b)
+ (CODE_FOR_msa_clei_s_h, CODE_FOR_msa_clei_s_w)
+ (CODE_FOR_msa_clei_s_d, CODE_FOR_msa_clei_u_b)
+ (CODE_FOR_msa_clei_u_h, CODE_FOR_msa_clei_u_w)
+ (CODE_FOR_msa_clei_u_d, CODE_FOR_msa_div_s_b)
+ (CODE_FOR_msa_div_s_h, CODE_FOR_msa_div_s_w)
+ (CODE_FOR_msa_div_s_d, CODE_FOR_msa_div_u_b)
+ (CODE_FOR_msa_div_u_h, CODE_FOR_msa_div_u_w)
+ (CODE_FOR_msa_div_u_d, CODE_FOR_msa_fadd_w, CODE_FOR_msa_fadd_d)
+ (CODE_FOR_msa_fexdo_w, CODE_FOR_msa_ftrunc_s_w)
+ (CODE_FOR_msa_ftrunc_s_d, CODE_FOR_msa_ftrunc_u_w)
+ (CODE_FOR_msa_ftrunc_u_d, CODE_FOR_msa_ffint_s_w)
+ (CODE_FOR_msa_ffint_s_d, CODE_FOR_msa_ffint_u_w)
+ (CODE_FOR_msa_ffint_u_d, CODE_FOR_msa_fsub_w)
+ (CODE_FOR_msa_fsub_d, CODE_FOR_msa_fmsub_d, CODE_FOR_msa_fmadd_w)
+ (CODE_FOR_msa_fmadd_d, CODE_FOR_msa_fmsub_w, CODE_FOR_msa_fmul_w)
+ (CODE_FOR_msa_fmul_d, CODE_FOR_msa_fdiv_w, CODE_FOR_msa_fdiv_d)
+ (CODE_FOR_msa_fmax_w, CODE_FOR_msa_fmax_d, CODE_FOR_msa_fmax_a_w)
+ (CODE_FOR_msa_fmax_a_d, CODE_FOR_msa_fmin_w, CODE_FOR_msa_fmin_d)
+ (CODE_FOR_msa_fmin_a_w, CODE_FOR_msa_fmin_a_d)
+ (CODE_FOR_msa_fsqrt_w, CODE_FOR_msa_fsqrt_d)
+ (CODE_FOR_msa_max_s_b, CODE_FOR_msa_max_s_h)
+ (CODE_FOR_msa_max_s_w, CODE_FOR_msa_max_s_d)
+ (CODE_FOR_msa_max_u_b, CODE_FOR_msa_max_u_h)
+ (CODE_FOR_msa_max_u_w, CODE_FOR_msa_max_u_d)
+ (CODE_FOR_msa_min_s_b, CODE_FOR_msa_min_s_h)
+ (CODE_FOR_msa_min_s_w, CODE_FOR_msa_min_s_d)
+ (CODE_FOR_msa_min_u_b, CODE_FOR_msa_min_u_h)
+ (CODE_FOR_msa_min_u_w, CODE_FOR_msa_min_u_d)
+ (CODE_FOR_msa_mod_s_b, CODE_FOR_msa_mod_s_h)
+ (CODE_FOR_msa_mod_s_w, CODE_FOR_msa_mod_s_d)
+ (CODE_FOR_msa_mod_u_b, CODE_FOR_msa_mod_u_h)
+ (CODE_FOR_msa_mod_u_w, CODE_FOR_msa_mod_u_d)
+ (CODE_FOR_msa_mod_s_b, CODE_FOR_msa_mod_s_h)
+ (CODE_FOR_msa_mod_s_w, CODE_FOR_msa_mod_s_d)
+ (CODE_FOR_msa_mod_u_b, CODE_FOR_msa_mod_u_h)
+ (CODE_FOR_msa_mod_u_w, CODE_FOR_msa_mod_u_d)
+ (CODE_FOR_msa_mulv_b, CODE_FOR_msa_mulv_h, CODE_FOR_msa_mulv_w)
+ (CODE_FOR_msa_mulv_d, CODE_FOR_msa_nlzc_b, CODE_FOR_msa_nlzc_h)
+ (CODE_FOR_msa_nlzc_w, CODE_FOR_msa_nlzc_d, CODE_FOR_msa_nor_v)
+ (CODE_FOR_msa_or_v, CODE_FOR_msa_ori_b, CODE_FOR_msa_nori_b)
+ (CODE_FOR_msa_pcnt_b, CODE_FOR_msa_pcnt_h, CODE_FOR_msa_pcnt_w)
+ (CODE_FOR_msa_pcnt_d, CODE_FOR_msa_xor_v, CODE_FOR_msa_xori_b)
+ (CODE_FOR_msa_sll_b, CODE_FOR_msa_sll_h, CODE_FOR_msa_sll_w)
+ (CODE_FOR_msa_sll_d, CODE_FOR_msa_slli_b, CODE_FOR_msa_slli_h)
+ (CODE_FOR_msa_slli_w, CODE_FOR_msa_slli_d, CODE_FOR_msa_sra_b)
+ (CODE_FOR_msa_sra_h, CODE_FOR_msa_sra_w, CODE_FOR_msa_sra_d)
+ (CODE_FOR_msa_srai_b, CODE_FOR_msa_srai_h, CODE_FOR_msa_srai_w)
+ (CODE_FOR_msa_srai_d, CODE_FOR_msa_srl_b, CODE_FOR_msa_srl_h)
+ (CODE_FOR_msa_srl_w, CODE_FOR_msa_srl_d, CODE_FOR_msa_srli_b)
+ (CODE_FOR_msa_srli_h, CODE_FOR_msa_srli_w, CODE_FOR_msa_srli_d)
+ (CODE_FOR_msa_subv_b, CODE_FOR_msa_subv_h, CODE_FOR_msa_subv_w)
+ (CODE_FOR_msa_subv_d, CODE_FOR_msa_subvi_b, CODE_FOR_msa_subvi_h)
+ (CODE_FOR_msa_subvi_w, CODE_FOR_msa_subvi_d, CODE_FOR_msa_move_v)
+ (CODE_FOR_msa_vshf_b, CODE_FOR_msa_vshf_h, CODE_FOR_msa_vshf_w)
+ (CODE_FOR_msa_vshf_d, CODE_FOR_msa_ilvod_d, CODE_FOR_msa_ilvev_d)
+ (CODE_FOR_msa_pckod_d, CODE_FOR_msa_pckdev_d, CODE_FOR_msa_ldi_b)
+ (CODE_FOR_msa_ldi_hi, CODE_FOR_msa_ldi_w)
+ (CODE_FOR_msa_ldi_d): New code_aliasing macros.
+ (mips_builtins): Add MSA sll_b, sll_h, sll_w, sll_d, slli_b,
+ slli_h, slli_w, slli_d, sra_b, sra_h, sra_w, sra_d, srai_b,
+ srai_h, srai_w, srai_d, srar_b, srar_h, srar_w, srar_d, srari_b,
+ srari_h, srari_w, srari_d, srl_b, srl_h, srl_w, srl_d, srli_b,
+ srli_h, srli_w, srli_d, srlr_b, srlr_h, srlr_w, srlr_d, srlri_b,
+ srlri_h, srlri_w, srlri_d, bclr_b, bclr_h, bclr_w, bclr_d,
+ bclri_b, bclri_h, bclri_w, bclri_d, bset_b, bset_h, bset_w,
+ bset_d, bseti_b, bseti_h, bseti_w, bseti_d, bneg_b, bneg_h,
+ bneg_w, bneg_d, bnegi_b, bnegi_h, bnegi_w, bnegi_d, binsl_b,
+ binsl_h, binsl_w, binsl_d, binsli_b, binsli_h, binsli_w,
+ binsli_d, binsr_b, binsr_h, binsr_w, binsr_d, binsri_b, binsri_h,
+ binsri_w, binsri_d, addv_b, addv_h, addv_w, addv_d, addvi_b,
+ addvi_h, addvi_w, addvi_d, subv_b, subv_h, subv_w, subv_d,
+ subvi_b, subvi_h, subvi_w, subvi_d, max_s_b, max_s_h, max_s_w,
+ max_s_d, maxi_s_b, maxi_s_h, maxi_s_w, maxi_s_d, max_u_b,
+ max_u_h, max_u_w, max_u_d, maxi_u_b, maxi_u_h, maxi_u_w,
+ maxi_u_d, min_s_b, min_s_h, min_s_w, min_s_d, mini_s_b, mini_s_h,
+ mini_s_w, mini_s_d, min_u_b, min_u_h, min_u_w, min_u_d, mini_u_b,
+ mini_u_h, mini_u_w, mini_u_d, max_a_b, max_a_h, max_a_w, max_a_d,
+ min_a_b, min_a_h, min_a_w, min_a_d, ceq_b, ceq_h, ceq_w, ceq_d,
+ ceqi_b, ceqi_h, ceqi_w, ceqi_d, clt_s_b, clt_s_h, clt_s_w,
+ clt_s_d, clti_s_b, clti_s_h, clti_s_w, clti_s_d, clt_u_b,
+ clt_u_h, clt_u_w, clt_u_d, clti_u_b, clti_u_h, clti_u_w,
+ clti_u_d, cle_s_b, cle_s_h, cle_s_w, cle_s_d, clei_s_b, clei_s_h,
+ clei_s_w, clei_s_d, cle_u_b, cle_u_h, cle_u_w, cle_u_d, clei_u_b,
+ clei_u_h, clei_u_w, clei_u_d, ld_b, ld_h, ld_w, ld_d, st_b, st_h,
+ st_w, st_d, sat_s_b, sat_s_h, sat_s_w, sat_s_d, sat_u_b, sat_u_h,
+ sat_u_w, sat_u_d, add_a_b, add_a_h, add_a_w, add_a_d, adds_a_b,
+ adds_a_h, adds_a_w, adds_a_d, adds_s_b, adds_s_h, adds_s_w,
+ adds_s_d, adds_u_b, adds_u_h, adds_u_w, adds_u_d, ave_s_b,
+ ave_s_h, ave_s_w, ave_s_d, ave_u_b, ave_u_h, ave_u_w, ave_u_d,
+ aver_s_b, aver_s_h, aver_s_w, aver_s_d, aver_u_b, aver_u_h,
+ aver_u_w, aver_u_d, subs_s_b, subs_s_h, subs_s_w, subs_s_d,
+ subs_u_b, subs_u_h, subs_u_w, subs_u_d, subsuu_s_b, subsuu_s_h,
+ subsuu_s_w, subsuu_s_d, subsus_u_b, subsus_u_h, subsus_u_w,
+ subsus_u_d, asub_s_b, asub_s_h, asub_s_w, asub_s_d, asub_u_b,
+ asub_u_h, asub_u_w, asub_u_d, mulv_b, mulv_h, mulv_w, mulv_d,
+ maddv_b, maddv_h, maddv_w, maddv_d, msubv_b, msubv_h, msubv_w,
+ msubv_d, div_s_b, div_s_h, div_s_w, div_s_d, div_u_b, div_u_h,
+ div_u_w, div_u_d, hadd_s_h, hadd_s_w, hadd_s_d, hadd_u_h,
+ hadd_u_w, hadd_u_d, hsub_s_h, hsub_s_w, hsub_s_d, hsub_u_h,
+ hsub_u_w, hsub_u_d, mod_s_b, mod_s_h, mod_s_w, mod_s_d, mod_u_b,
+ mod_u_h, mod_u_w, mod_u_d, dotp_s_h, dotp_s_w, dotp_s_d,
+ dotp_u_h, dotp_u_w, dotp_u_d, dpadd_s_h, dpadd_s_w, dpadd_s_d,
+ dpadd_u_h, dpadd_u_w, dpadd_u_d, dpsub_s_h, dpsub_s_w, dpsub_s_d,
+ dpsub_u_h, dpsub_u_w, dpsub_u_d, sld_b, sld_h, sld_w, sld_d,
+ sldi_b, sldi_h, sldi_w, sldi_d, splat_b, splat_h, splat_w,
+ splat_d, splati_b, splati_h, splati_w, splati_d, pckev_b,
+ pckev_h, pckev_w, pckev_d, pckod_b, pckod_h, pckod_w, pckod_d,
+ ilvl_b, ilvl_h, ilvl_w, ilvl_d, ilvr_b, ilvr_h, ilvr_w, ilvr_d,
+ ilvev_b, ilvev_h, ilvev_w, ilvev_d, ilvod_b, ilvod_h, ilvod_w,
+ ilvod_d, vshf_b, vshf_h, vshf_w, vshf_d, and_v, andi_b, or_v,
+ ori_b, nor_v, nori_b, xor_v, xori_b, bmnz_v, bmnzi_b, bmz_v,
+ bmzi_b, bsel_v, bseli_b, shf_b, shf_h, shf_w, bnz_v, bz_v,
+ fill_b, fill_h, fill_w, fill_d, pcnt_b, pcnt_h, pcnt_w,
+ pcnt_d, nloc_b, nloc_h, nloc_w, nloc_d, nlzc_b, nlzc_h, nlzc_w,
+ nlzc_d, copy_s_b, copy_s_h, copy_s_w, copy_s_d, copy_u_b,
+ copy_u_h, copy_u_w, copy_u_d, insert_b, insert_h, insert_w,
+ insert_d, insve_b, insve_h, insve_w, insve_d, bnz_b, bnz_h,
+ bnz_w, bnz_d, bz_b, bz_h, bz_w, bz_d, ldi_b, ldi_h, ldi_w, ldi_d,
+ fcaf_w, fcaf_d, fcor_w, fcor_d, fcun_w, fcun_d, fcune_w, fcune_d,
+ fcueq_w, fcueq_d, fceq_w, fceq_d, fcne_w, fcne_d, fclt_w, fclt_d,
+ fcult_w, fcult_d, fcle_w, fcle_d, fcule_w, fcule_d, fsaf_w,
+ fsaf_d, fsor_w, fsor_d, fsun_w, fsun_d, fsune_w, fsune_d,
+ fsueq_w, fsueq_d, fseq_w, fseq_d, fsne_w, fsne_d, fslt_w,
+ fslt_d, fsult_w, fsult_d, fsle_w, fsle_d, fsule_w, fsule_d,
+ fadd_w, fadd_d, fsub_w, fsub_d, fmul_w, fmul_d, fdiv_w, fdiv_d,
+ fmadd_w, fmadd_d, fmsub_w, fmsub_d, fexp2_w, fexp2_d, fexdo_h,
+ fexdo_w, ftq_h, ftq_w, fmin_w, fmin_d, fmin_a_w, fmin_a_d,
+ fmax_w, fmax_d, fmax_a_w, fmax_a_d, mul_q_h, mul_q_w, mulr_q_h,
+ mulr_q_w, madd_q_h, madd_q_w, maddr_q_h, maddr_q_w, msub_q_h,
+ msub_q_w, msubr_q_h, msubr_q_w, fclass_w, fclass_d, fsqrt_w,
+ fsqrt_d, frcp_w, frcp_d, frint_w, frint_d, frsqrt_w, frsqrt_d,
+ flog2_w, flog2_d, fexupl_w, fexupl_d, fexupr_w, fexupr_d, ffql_w,
+ ffql_d, ffqr_w, ffqr_d, ftint_s_w, ftint_s_d, ftint_u_w,
+ ftint_u_d, ftrunc_s_w, ftrunc_s_d, ftrunc_u_w, ftrunc_u_d,
+ ffint_s_w, ffint_s_d, ffint_u_w, ffint_u_d, ctcmsa, cfcmsa,
+ move_v builtins.
+ (mips_get_builtin_decl_index): New array.
+ (MIPS_ATYPE_QI, MIPS_ATYPE_HI, MIPS_ATYPE_V2DI, MIPS_ATYPE_V4SI)
+ (MIPS_ATYPE_V8HI, MIPS_ATYPE_V16QI, MIPS_ATYPE_V2DF)
+ (MIPS_ATYPE_V4SF, MIPS_ATYPE_UV2DI, MIPS_ATYPE_UV4SI)
+ (MIPS_ATYPE_UV8HI, MIPS_ATYPE_UV16QI): New.
+ (mips_init_builtins): Initialize mips_get_builtin_decl_index
+ array.
+ (TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION): Define target
+ hook.
+ (mips_expand_builtin_insn): Prepare operands for
+ CODE_FOR_msa_addvi_b, CODE_FOR_msa_addvi_h, CODE_FOR_msa_addvi_w,
+ CODE_FOR_msa_addvi_d, CODE_FOR_msa_clti_u_b,
+ CODE_FOR_msa_clti_u_h, CODE_FOR_msa_clti_u_w,
+ CODE_FOR_msa_clti_u_d, CODE_FOR_msa_clei_u_b,
+ CODE_FOR_msa_clei_u_h, CODE_FOR_msa_clei_u_w,
+ CODE_FOR_msa_clei_u_d, CODE_FOR_msa_maxi_u_b,
+ CODE_FOR_msa_maxi_u_h, CODE_FOR_msa_maxi_u_w,
+ CODE_FOR_msa_maxi_u_d, CODE_FOR_msa_mini_u_b,
+ CODE_FOR_msa_mini_u_h, CODE_FOR_msa_mini_u_w,
+ CODE_FOR_msa_mini_u_d, CODE_FOR_msa_subvi_b,
+ CODE_FOR_msa_subvi_h, CODE_FOR_msa_subvi_w, CODE_FOR_msa_subvi_d,
+ CODE_FOR_msa_ceqi_b, CODE_FOR_msa_ceqi_h, CODE_FOR_msa_ceqi_w,
+ CODE_FOR_msa_ceqi_d, CODE_FOR_msa_clti_s_b,
+ CODE_FOR_msa_clti_s_h, CODE_FOR_msa_clti_s_w,
+ CODE_FOR_msa_clti_s_d, CODE_FOR_msa_clei_s_b,
+ CODE_FOR_msa_clei_s_h, CODE_FOR_msa_clei_s_w,
+ CODE_FOR_msa_clei_s_d, CODE_FOR_msa_maxi_s_b,
+ CODE_FOR_msa_maxi_s_h, CODE_FOR_msa_maxi_s_w,
+ CODE_FOR_msa_maxi_s_d, CODE_FOR_msa_mini_s_b,
+ CODE_FOR_msa_mini_s_h, CODE_FOR_msa_mini_s_w,
+ CODE_FOR_msa_mini_s_d, CODE_FOR_msa_andi_b, CODE_FOR_msa_ori_b,
+ CODE_FOR_msa_nori_b, CODE_FOR_msa_xori_b, CODE_FOR_msa_bmzi_b,
+ CODE_FOR_msa_bmnzi_b, CODE_FOR_msa_bseli_b, CODE_FOR_msa_fill_b,
+ CODE_FOR_msa_fill_h, CODE_FOR_msa_fill_w, CODE_FOR_msa_fill_d,
+ CODE_FOR_msa_ilvl_b, CODE_FOR_msa_ilvl_h, CODE_FOR_msa_ilvl_w,
+ CODE_FOR_msa_ilvl_d, CODE_FOR_msa_ilvr_b, CODE_FOR_msa_ilvr_h,
+ CODE_FOR_msa_ilvr_w, CODE_FOR_msa_ilvr_d, CODE_FOR_msa_ilvev_b,
+ CODE_FOR_msa_ilvev_h, CODE_FOR_msa_ilvev_w, CODE_FOR_msa_ilvod_b,
+ CODE_FOR_msa_ilvod_h, CODE_FOR_msa_ilvod_w, CODE_FOR_msa_pckev_b,
+ CODE_FOR_msa_pckev_h, CODE_FOR_msa_pckev_w, CODE_FOR_msa_pckod_b,
+ CODE_FOR_msa_pckod_h, CODE_FOR_msa_pckod_w, CODE_FOR_msa_slli_b,
+ CODE_FOR_msa_slli_h, CODE_FOR_msa_slli_w, CODE_FOR_msa_slli_d,
+ CODE_FOR_msa_srai_b, CODE_FOR_msa_srai_h, CODE_FOR_msa_srai_w,
+ CODE_FOR_msa_srai_d, CODE_FOR_msa_srli_b, CODE_FOR_msa_srli_h,
+ CODE_FOR_msa_srli_w, CODE_FOR_msa_srli_d, CODE_FOR_msa_insert_b,
+ CODE_FOR_msa_insert_h, CODE_FOR_msa_insert_w,
+ CODE_FOR_msa_insert_d, CODE_FOR_msa_insve_b,
+ CODE_FOR_msa_insve_h, CODE_FOR_msa_insve_w, CODE_FOR_msa_insve_d,
+ CODE_FOR_msa_shf_b, CODE_FOR_msa_shf_h, CODE_FOR_msa_shf_w,
+ CODE_FOR_msa_shf_w_f, CODE_FOR_msa_vshf_b, CODE_FOR_msa_vshf_h,
+ CODE_FOR_msa_vshf_w, CODE_FOR_msa_vshf_d.
+ (mips_expand_builtin): Add case for MIPS_BULTIN_MSA_TEST_BRANCH.
+ (mips_set_compression_mode): Disallow MSA with MIPS16 code.
+ (mips_option_override): -mmsa requires -mfp64 and -mhard-float.
+ These are set implicitly and an error is reported if overridden.
+ (mips_expand_builtin_msa_test_branch): New function.
+ (mips_expand_msa_shuffle): Likewise.
+ (MAX_VECT_LEN): Increase maximum length of a vector to 16 bytes.
+ (TARGET_SCHED_REASSOCIATION_WIDTH): Define target hook.
+ (TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES): Likewise.
+ (mips_expand_vec_unpack): Add support for MSA.
+ (mips_expand_vector_init): Likewise.
+ (mips_expand_vi_constant): Use CONST0_RTX (element_mode)
+ instead of const0_rtx.
+ (mips_msa_vec_parallel_const_half): New function.
+ (mips_gen_const_int_vector): Likewise.
+ (mips_gen_const_int_vector_shuffle): Likewise.
+ (mips_expand_msa_cmp): Likewise.
+ (mips_expand_vec_cond_expr): Likewise.
+ * config/mips/mips.h
+ (TARGET_CPU_CPP_BUILTINS): Add __mips_msa and __mips_msa_width.
+ (OPTION_DEFAULT_SPECS): Ignore --with-fp-32 if -mmsa is
+ specified.
+ (ASM_SPEC): Pass mmsa and mno-msa to the assembler.
+ (ISA_HAS_MSA): New macro.
+ (UNITS_PER_MSA_REG): Likewise.
+ (BITS_PER_MSA_REG): Likewise.
+ (BIGGEST_ALIGNMENT): Redefine using ISA_HAS_MSA.
+ (MSA_REG_FIRST): New macro.
+ (MSA_REG_LAST): Likewise.
+ (MSA_REG_NUM): Likewise.
+ (MSA_REG_P): Likewise.
+ (MSA_REG_RTX_P): Likewise.
+ (MSA_SUPPORTED_MODE_P): Likewise.
+ (HARD_REGNO_CALL_PART_CLOBBERED): Redefine using TARGET_MSA.
+ (ADDITIONAL_REGISTER_NAMES): Add named registers $w0-$w31.
+ * config/mips/mips.md: Include mips-msa.md.
+ (alu_type): Add simd_add.
+ (mode): Add V2DI, V4SI, V8HI, V16QI, V2DF, V4SF.
+ (type): Add simd_div, simd_fclass, simd_flog2, simd_fadd,
+ simd_fcvt, simd_fmul, simd_fmadd, simd_fdiv, simd_bitins,
+ simd_bitmov, simd_insert, simd_sld, simd_mul, simd_fcmp,
+ simd_fexp2, simd_int_arith, simd_bit, simd_shift, simd_splat,
+ simd_fill, simd_permute, simd_shf, simd_sat, simd_pcnt,
+ simd_copy, simd_branch, simd_cmsa, simd_fminmax, simd_logic,
+ simd_move, simd_load, simd_store. Choose "multi" for moves
+ for "qword_mode".
+ (qword_mode): New attribute.
+ (insn_count): Add instruction count for quad moves.
+ Increase the count for MIPS SIMD division.
+ (UNITMODE): Add UNITMODEs for vector types.
+ (addsub): New code iterator.
+ * config/mips/mips.opt (mmsa): New option.
+ * config/mips/msa.h: New file.
+ * config/mips/mti-elf.h: Don't infer -mfpxx if -mmsa is
+ specified.
+ * config/mips/mti-linux.h: Likewise.
+ * config/mips/predicates.md
+ (const_msa_branch_operand): New constraint.
+ (const_uimm3_operand): Likewise.
+ (const_uimm4_operand): Likewise.
+ (const_uimm5_operand): Likewise.
+ (const_uimm8_operand): Likewise.
+ (const_imm5_operand): Likewise.
+ (aq10b_operand): Likewise.
+ (aq10h_operand): Likewise.
+ (aq10w_operand): Likewise.
+ (aq10d_operand): Likewise.
+ (const_m1_operand): Likewise.
+ (reg_or_m1_operand): Likewise.
+ (const_exp_2_operand): Likewise.
+ (const_exp_4_operand): Likewise.
+ (const_exp_8_operand): Likewise.
+ (const_exp_16_operand): Likewise.
+ (const_vector_same_val_operand): Likewise.
+ (const_vector_same_simm5_operand): Likewise.
+ (const_vector_same_uimm5_operand): Likewise.
+ (const_vector_same_uimm6_operand): Likewise.
+ (const_vector_same_uimm8_operand): Likewise.
+ (par_const_vector_shf_set_operand): Likewise.
+ (reg_or_vector_same_val_operand): Likewise.
+ (reg_or_vector_same_simm5_operand): Likewise.
+ (reg_or_vector_same_uimm6_operand): Likewise.
+ * doc/extend.texi (MIPS SIMD Architecture Functions): New
+ section.
+ * doc/invoke.texi (-mmsa): Document new option.
+
+2016-05-09 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * configure.ac (enable_vtable_verify): Handle --enable-vtable-verify.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * gcc.c (VTABLE_VERIFICATION_SPEC) [!ENABLE_VTABLE_VERIFY]: Error
+ on -fvtable-verify.
+ * config/sol2.h [!ENABLE_VTABLE_VERIFY] (STARTFILE_VTV_SPEC): Define.
+ (ENDFILE_VTV_SPEC): Define.
+
+2016-05-09 Kaushik Phatak <kaushik.phatak@kpit.com>
+
+ * config/rl78/rl78.c (rl78_expand_prologue): Save the MDUC related
+ registers in all interrupt handlers if necessary.
+ (rl78_option_override): Add warning.
+ (MUST_SAVE_MDUC_REGISTERS): New macro.
+ (rl78_expand_epilogue): Restore the MDUC registers if necessary.
+ * config/rl78/rl78.c (check_mduc_usage): New function.
+ (mduc_regs): New structure to hold MDUC register data.
+ * config/rl78/rl78.md (is_g13_muldiv_insn): New attribute.
+ (mulsi3_g13): Add is_g13_muldiv_insn attribute.
+ (udivmodsi4_g13): Add is_g13_muldiv_insn attribute.
+ (mulhi3_g13): Add is_g13_muldiv_insn attribute.
+ * config/rl78/rl78.opt (msave-mduc-in-interrupts): New option.
+ * doc/invoke.texi (RL78 Options): Add -msave-mduc-in-interrupts.
+
+2016-05-09 Bin Cheng <bin.cheng@arm.com>
+
+ * tree-if-conv.c (tree-ssa-loop.h): Include header file.
+ (tree-ssa-loop-niter.h): Ditto.
+ (idx_within_array_bound, ref_within_array_bound): New functions.
+ (ifcvt_memrefs_wont_trap): Check if array ref is within bound.
+ Factor out check on writable base object to ...
+ (base_object_writable): ... here.
+
+2016-05-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.md (probe_stack): Add modes to set source
+ and destination.
+
+2016-05-09 Bernd Schmidt <bschmidt@redhat.com>
+
+ * regrename.c (base_reg_class_for_rename): New static function.
+ (scan_rtx_address, scan_rtx): Use it instead of base_reg_class.
+
+2016-05-08 Jan Hubicka <hubicka@ucw.cz>
+
+ * cgraph.c (thunk_adjust): Export.
+ * cgraphclones.c (cgraph_node::create_clone): Clone thunk info.
+ * cgraphunit.c (thunk_adjust): Export.
+ (cgraph_node::assemble_thunks_and_aliases): Do not assemble inlined
+ thunks.
+ * ipa-inline-analyssi.c (compute_inline_parameters): Thunks are
+ inlinable.
+ * tree-inline.c (expand_call_inline): Expand thunks inline.
+
+2016-05-08 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/70998
+ * config/i386/sse.md (*sse2_vd_cvtsd2ss): New insn pattern.
+ (*sse2_vd_cvtss2sd): Ditto.
+ * config/i386/i386.md
+ (TARGET_SSE_PARTIAL_REG_DEPENDENCY float_truncate df->sf splitter):
+ Generate *sse2_vd_cvtsd2ss pattern.
+ (TARGET_SSE_PARTIAL_REG_DEPENDENCY float_extend sf->df splitter):
+ Generate *sse2_vd_cvtss2sd pattern.
+
+2016-05-08 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.h (GET_SH_ARG_CLASS): Convert macro into ...
+ * config/sh/sh.c (get_sh_arg_class): ... this new function. Update its
+ users.
+
+2016-05-08 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh-protos.h (sh_media_register_for_return): Remove.
+ * config/sh/sh.c: Define and declare variables on first use throughout
+ the file.
+ (current_function_interrupt): Change to bool type.
+ (frame_insn): Rename to emit_frame_insn and update users.
+ (push_regs): Use bool for 'interrupt_handler' argument.
+ (save_schedule_s): Remove.
+ (TARGET_ASM_UNALIGNED_DI_OP, TARGET_ASM_ALIGNED_DI_OP): Remove.
+ (sh_option_override): Don't nullify targetm.asm_out.aligned_op.di and
+ targetm.asm_out.unaligned_op.di.
+ (gen_far_branch): Remove redundant forward declaration.
+ (sh_media_register_for_return, MAX_SAVED_REGS, save_entry_s, save_entry,
+ MAX_TEMPS, save_schedule_ssave_schedule): Remove.
+ (sh_set_return_address, sh_function_ok_for_sibcall,
+ scavenge_reg): Update comments.
+ (sh_builtin_saveregs): Use TRAGET_FPU_ANY condition.
+ (sh2a_get_function_vector_number, sh2a_function_vector_p): Use for loop.
+ (sh_attr_renesas_p): Remove unnecessary parentheses.
+ (branch_dest): Simplify.
+ * config/sh/sh.h (sh_args): Remove byref, byref_regs, stack_regs fields.
+ Change force_mem, prototype_p, outgoing, renesas_abi fields to bool.
+ (CUMULATIVE_ARGS): Change macro to typedef.
+ (current_function_interrupt): Change to bool type.
+ (sh_arg_class, sh_args, CUMULATIVE_ARGS, current_function_interrupt):
+ Surround with __cplusplus ifdef.
+ (sh_compare_op0, sh_compare_op1): Remove.
+ (EPILOGUE_USES): Use TARGET_FPU_ANY condition.
+
+2016-05-07 Jim Wilson <jim.wilson@linaro.org>
+
+ * config/arm/arm.md: (arch): Add neon.
+ (arch_enabled): Return yes for arch neon when TARGET_NEON.
+ * config/arm/vfp.md (movdf_vfp): Add w/G as alternative 3. Add
+ neon_move as type for alt 3. Add arch attr enabling alt 3 for neon.
+ Emit vmov.i64 for alt 3. Renumber alternatives 3 to 8. Adjust
+ attributes for alt renumbering. Mark alt 3 as non-predicable.
+ (thumb2_movdf_vfp): Likewise.
+
+2016-05-07 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (*addqi_1): Add preferred_for_speed attribute
+ to disparage alternatives 3 and 4 for TARGET_PARTIAL_REG_STALL targets.
+ (*andqi_1): Add preferred_for_speed attribute to disparage
+ alternative 2 for TARGET_PARTIAL_REG_STALL targets.
+ (*<code>qi_1): Ditto.
+ (*one_cmplqi2_1): Add preferred_for_speed attribute to disparage
+ alternative 1 for TARGET_PARTIAL_REG_STALL targets.
+ (*ashlqi3_1): Ditto.
+ (*swap<mode>): Merge from *swap<mode>_1 and *swap<mode>_2 patterns.
+ Add preferred_for_size attribute to disparage alternative 0 and
+ preferred_for_speed attribute to disparage alternative 1 for
+ TARGET_PARTIAL_REG_STALL targets.
+
+2016-05-07 Tom de Vries <tom@codesourcery.com>
+
+ PR tree-optimization/70956
+ * graphite-scop-detection.c (build_cross_bb_scalars_def): Handle NULL
+ def.
+
+2016-05-07 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh-protos.h (sh_cbranch_distance): Declare new function.
+ * config/sh/sh.c (sh_cbranch_distance): Implement it.
+ * config/sh/sh.md (branch_zero): Remove define_attr.
+ (define_delay): Disable delay slot if branch distance is one insn.
+
+2016-05-06 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (LEAMODE): New mode attribute.
+ (plus to LEA splitter): Rewrite splitter using LEAMODE mode attribute.
+ (ashift to LEA splitter): Rewrte splitter using SWI mode iterator
+ and LEAMODE mode attribute. Use VOIDmode const_0_to_3_operand as
+ operand 2 predicate.
+ (*lea<mode>_general_2): Use VOIDmode for const248_operand.
+ (*lea<mode>_general_3): Ditto.
+ (*lea<mode>_general_4): Use VOIDmode for const_0_to_3_operand.
+
+2016-05-06 Jakub Jelinek <jakub@redhat.com>
+
+ * genmddump.c (main): Convert argv from char ** to const char **.
+
+2016-05-06 David Malcolm <dmalcolm@redhat.com>
+
+ * coretypes.h (OVERRIDE): New macro.
+ (FINAL): New macro.
+
+2016-05-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-ssa-coalesce.c (gimple_can_coalesce_p): In the optimized case,
+ allow coalescing if the types are compatible.
+
+2016-05-06 David Malcolm <dmalcolm@redhat.com>
+
+ * pass_manager.h (pass_manager::register_pass_name): New method.
+ (pass_manager::get_pass_by_name): New method.
+ (pass_manager::create_pass_tab): New method.
+ (pass_manager::m_name_to_pass_map): New field.
+ * passes.c (name_to_pass_map): Delete global in favor of field
+ "m_name_to_pass_map" of pass_manager.
+ (register_pass_name): Rename from a function to...
+ (pass_manager::register_pass_name): ...this method, updating
+ for renaming of global "name_to_pass_map" to field
+ "m_name_to_pass_map".
+ (create_pass_tab): Rename from a function to...
+ (pass_manager::create_pass_tab): ...this method, updating
+ for renaming of global "name_to_pass_map" to field.
+ (get_pass_by_name): Rename from a function to...
+ (pass_manager::get_pass_by_name): ...this method.
+ (enable_disable_pass): Convert use of get_pass_by_name to
+ a method call, locating the pass_manager singleton.
+
+2016-05-06 David Malcolm <dmalcolm@redhat.com>
+
+ * genattr-common.c (main): Convert argv from char ** to const char **.
+ * genattr.c (main): Likewise.
+ * genattrtab.c (main): Likewise.
+ * genautomata.c (initiate_automaton_gen): Likewise.
+ (main): Likewise.
+ * gencodes.c (main): Likewise.
+ * genconditions.c (main): Likewise.
+ * genconfig.c (main): Likewise.
+ * genconstants.c (main): Likewise.
+ * genemit.c (main): Likewise.
+ * genenums.c (main): Likewise.
+ * genextract.c (main): Likewise.
+ * genflags.c (main): Likewise.
+ * genmddeps.c (main): Likewise.
+ * genopinit.c (main): Likewise.
+ * genoutput.c (main): Likewise.
+ * genpeep.c (main): Likewise.
+ * genpreds.c (main): Likewise.
+ * genrecog.c (main): Likewise.
+ * gensupport.c (init_rtx_reader_args_cb): Likewise.
+ (init_rtx_reader_args): Likewise.
+ * gensupport.h (init_rtx_reader_args_cb): Likewise.
+ (init_rtx_reader_args): Likewise.
+ * gentarget-def.c (main): Likewise.
+ * read-md.c (read_md_files): Likewise.
+ * read-md.h (read_md_files): Likewise.
+
+2016-05-06 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (int cmove peephole2s): Use general_reg_operand
+ instead of register_and_not_any_fp_reg_operand as operand 0 predicate.
+ * config/i386/predicates.md (register_and_not_any_fp_reg_operand):
+ Remove unused predicate.
+ (register_and_not_fp_reg_operand): Ditto.
+
+2016-05-06 Martin Liska <mliska@suse.cz>
+
+ * tree-if-conv.c (ifcvt_split_critical_edges): Use auto_vec
+ instead of vec as the vector is local to the function.
+
+2016-05-06 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/sse.md (*<code>v8hi3, *<code>v16qi3): Add
+ avx512bw alternative.
+
+ * config/i386/sse.md (<mask_codefor>ashr<mode>3<mask_name>): Move
+ before the ashr<mode>3 pattern.
+
+ * config/i386/sse.md (*avx2_pmaddwd, *sse2_pmaddwd): Use
+ v instead of x in vex or maybe_vex alternatives, use
+ maybe_evex instead of vex in prefix.
+
+ * config/i386/sse.md (*vec_extractv4sf_0, *sse4_1_extractps,
+ *vec_extractv4sf_mem, vec_extract_lo_v16hi, vec_extract_hi_v16hi,
+ vec_extract_lo_v32qi, vec_extract_hi_v32qi): Use v instead of x
+ in vex or maybe_vex alternatives, use maybe_evex instead of vex
+ in prefix.
+
+ * config/i386/sse.md (*vec_concatv2sf_sse4_1, *vec_concatv4sf): Use
+ v instead of x in vex or maybe_vex alternatives, use
+ maybe_evex instead of vex in prefix.
+
+ * config/i386/sse.md (sse_shufps_<mode>, sse_storehps, sse_loadhps,
+ sse_storelps, sse_movss, avx2_vec_dup<mode>, avx2_vec_dupv8sf_1,
+ sse2_shufpd_<mode>, sse2_storehpd, sse2_storelpd, sse2_loadhpd,
+ sse2_loadlpd, sse2_movsd): Use v instead of x in vex or maybe_vex
+ alternatives, use maybe_evex instead of vex in prefix.
+
+ * config/i386/sse.md (vec_interleave_lowv4sf,
+ *vec_interleave_highv2df, *vec_interleave_lowv2df): Use
+ v instead of x in vex or maybe_vex alternatives, use
+ maybe_evex instead of vex in prefix.
+
+ * config/i386/sse.md (sse_movhlps, sse_movlhps): Use
+ v instead of x in vex or maybe_vex alternatives, use
+ maybe_evex instead of vex in prefix.
+
+ * config/i386/sse.md (*avx_cvtpd2dq256_2, *avx_cvtps2pd256_2): Use
+ v constraint instead of x.
+
+2016-05-06 Nathan Sidwell <nathan@codesourcery.com>
+
+ * gimple.c (gimple_call_same_target_p): Unique functions are eq.
+ * tree-ssa-tail-merge.c (same_succ::equal): Check pointer eq
+ equality first.
+
+2016-05-06 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70948
+ * tree-ssa-structalias.c (find_func_aliases_for_builtin_call):
+ Properly clobber all fields of va_list for __builtin_va_start.
+
+2016-05-06 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ PR debug/70935
+ * tree-ssa-loop-unswitch.c (find_loop_guard): Reject guard edge with
+ loop latch destination.
+
+2016-05-06 Martin Liska <mliska@suse.cz>
+
+ * tree-ssa-uninit.c: Apply manual changes
+ to the GNU coding style.
+ (prune_uninit_phi_opnds): Rename from
+ prune_uninit_phi_opnds_in_unrealizable_paths.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.opt (madjust-unroll, minvalid-symbols, msoft-atomic,
+ mspace): Remove deprecated options.
+ * doc/invoke.texi (SH options): Remove -mspace.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.md (ic_invalidate_line_sh4a): Fix insn length.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.md (*cmpeqsi_t): Remove combine insn pattern and similar
+ corresponding combine split pattern.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/58219
+ * config/sh/predicates.md (long_displacement_mem_operand): New.
+ * config/sh/sh.md (movsi_i): Allow for SH2A, disallow for any FPU.
+ Add movi20, movi20s alternatives. Adjust length attribute for
+ alternatives.
+ (movsi_ie): Allow for any FPU. Adjust length attribute for
+ alternatives.
+ (movsi_i_lowpart): Add movi20, movi20s alternatives. Adjust length
+ attribute for alternatives.
+ (*mov<mode>): Use long_displacement_mem_operand for length attribute.
+ (*movdi_i, movdf_k, movdf_i4, movsf_i, movsf_ie, movsf_ie_ra): Adjust
+ length attribute for alternatives.
+
+2016-05-06 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70960
+ * tree-if-conv.c (ifcvt_walk_pattern_tree): Handle non-SSA ops.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/52933
+ * config/sh/sh.md (*cmp_div0s_7, *cmp_div0s_8): Add div0s variants.
+ * config/sh/sh.c (sh_rtx_costs): Add another div0s case.
+
+2016-05-06 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/70875
+ * ubsan.c (get_ubsan_type_info_for_type): Remove assert.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54089
+ * config/sh/sh.md (*rotcr): Add another variant.
+
+2016-05-06 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/70931
+ * dwarf2out.c (native_encode_initializer): Skip zero-sized fields.
+
+2016-05-06 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/70941
+ * fold-const.c (split_tree): Always convert to the original type
+ before negating.
+
+2016-05-06 Richard Biener <rguenther@suse.de>
+
+ * fwprop.c (fwprop): Remove duplicate cleanup_cfg call.
+ (fwprop_addr): Likewise.
+
+2016-05-06 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/70873
+ * config/i386/i386-protos.h (ix86_standard_x87sse_constant_load_p):
+ New prototype.
+ * config/i386/i386.c (ix86_standard_x87sse_constant_load_p): New.
+ * config/i386/i386.md (push mem splitter): Use find_constant_src in
+ the splitter condition.
+ (FP load splitter): Use ix86_standard_x87sse_constant_load_p in
+ the splitter condition.
+ (FP float_extend load splitter): Ditto.
+
+2016-05-05 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (peehole2 patterns): Change true_regnum
+ to REGNO in all peephole2 patterns.
+ (post-reload splitters): Change true_regnum to REGNO in
+ post-reload splitters.
+ (zero_extend splitters): Use general_reg_operand and
+ nonimmediate_gr_operand predicates.
+
+2016-05-05 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/sse.md (<avx512>_fmadd_<mode>_mask3<round_name>): Use
+ v constraint instead of x.
+
+2016-05-05 Alan Modra <amodra@gmail.com>
+
+ PR target/68662
+ * config/rs6000/sysv4.h (SUBTARGET_OVERRIDE_OPTIONS): Don't
+ set OPTION_MASK_RELOCATABLE when flag_pic == 2. Set
+ TARGET_NO_FP_IN_TOC for -mrelocatable.
+ (MINIMAL_TOC_SECTION_ASM_OP): Remove redundant
+ TARGET_RELOCATABLE test.
+ (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P): Likewise.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Likewise.
+ * config/rs6000/linux64.h (MINIMAL_TOC_SECTION_ASM_OP): Likewise.
+ (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P): Likewise.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Likewise.
+ * config/rs6000/freebsd64.h (MINIMAL_TOC_SECTION_ASM_OP): Likewise.
+ (ASM_OUTPUT_SPECIAL_POOL_ENTRY_P): Likewise.
+ (ASM_PREFERRED_EH_DATA_FORMAT): Likewise.
+ * config/rs6000/predicates.md (easy_fp_constant): Likewise.
+ * config/rs6000/rs6000.c (rs6000_elf_output_toc_section_asm_op):
+ Likewise.
+ (rs6000_assemble_integer): Update TARGET_RELOCATABLE test.
+ (rs6000_stack_info): Likewise.
+ (rs6000_elf_asm_out_constructor): Likewise.
+ (rs6000_elf_asm_out_destructor): Likewise.
+ (rs6000_elf_declare_function_name): Likewise.
+ * config/rs6000/rs6000.md (load_toc_aix_di): Likewise.
+ * config/rs6000/rs6000.h (MASK_RELOCATABLE, MASK_MINIMAL_TOC):
+ Don't define.
+
+2016-05-05 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.c (rs6000_frame_related): Rewrite.
+
+2016-05-05 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.c (rs6000_savres_strategy): Don't use
+ out-of-line gpr restore for one or two regs if that would add
+ a save of lr.
+
+2016-05-04 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/70873
+ * config/i386/i386.md
+ (TARGET_SSE_PARTIAL_REG_DEPENDENCY float_extend sf->df peephole2):
+ Change to post-epilogue_completed late splitter. Use sse_reg_operand
+ as operand 0 predicate.
+ (TARGET_SSE_PARTIAL_REG_DEPENDENCY float_truncate df->sf peephole2):
+ Ditto.
+ (TARGET_SSE_PARTIAL_REG_DEPENDENCY float {si,di}->{sf,df} peephole2):
+ Ditto. Emit the pattern using RTX.
+
+ (TARGET_USE_VECTOR_FP_CONVERTS float_extend sf->df splitter):
+ Use sse_reg_opreand as operand 0 predicate. Do not use true_regnum in
+ the post-reload splitter. Use lowpart_subreg instead of gen_rtx_REG.
+ (TARGET_USE_VECTOR_FP_CONVERTS float_truncate df->sf splitter):
+ Ditto.
+ (TARGET_USE_VECTOR_CONVERTS float si->{sf,df} splitter): Use
+ sse_reg_operand as operand 0 predicate.
+
+ (TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS float_extend sf->df peephole2):
+ Use sse_reg_opreand as operand 0 predicate. Use lowpart_subreg
+ instead of gen_rtx_REG.
+ (TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS float_truncate sf->df peephole2):
+ Ditto.
+
+2016-05-04 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * function.c (emit_use_return_register_into_block): Delete.
+ (gen_return_pattern): Delete.
+ (emit_return_into_block): Delete.
+ (active_insn_between): Delete.
+ (convert_jumps_to_returns): Delete.
+ (emit_return_for_exit): Delete.
+ (thread_prologue_and_epilogue_insns): Delete all code dealing with
+ simple_return for shrink-wrapped blocks.
+ * shrink-wrap.c (try_shrink_wrapping): Insert simple_return at the
+ end of blocks that need one.
+ (get_unconverted_simple_return): Delete.
+ (convert_to_simple_return): Delete.
+ * shrink-wrap.c (get_unconverted_simple_return): Delete declaration.
+ (convert_to_simple_return): Ditto.
+
+2016-05-04 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * cfgcleanup.c (bb_is_just_return): New function.
+ (try_optimize_cfg): Simplify jumps to return, branches to return,
+ and branches around return.
+
+2016-05-04 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * cfgcleanup.c (try_simplify_condjump): Don't try to simplify a
+ branch to a return.
+
+2016-05-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/70906
+ PR c++/70933
+ * tree-core.h (enum operand_equal_flag): Add OEP_HASH_CHECK.
+ * tree.c (inchash::add_expr): If !IS_EXPR_CODE_CLASS (tclass),
+ assert flags & OEP_HASH_CHECK, instead of asserting it
+ never happens. Handle TARGET_EXPR.
+ * fold-const.c (operand_equal_p): For hash verification,
+ or in OEP_HASH_CHECK into flags.
+
+2016-05-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-ssa-coalesce.c (gimple_can_coalesce_p): Fix reference in head
+ comment.
+ (compute_samebase_partition_bases): Fix typo.
+
+2016-05-04 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/sse.md (vec_interleave_highv8sf,
+ vec_interleave_lowv8sf, vec_interleave_highv4df,
+ vec_interleave_lowv4df): Remove constraints from expanders.
+
+ * config/i386/sse.md (sse2_movq128): Use v constraint instead of x.
+
+2016-05-04 Jan Hubicka <hubicka@ucw.cz>
+
+ * tree-inline.c (expand_call_inline): Fix path dealing with
+ making lhs of call statement undefined.
+
+2016-05-04 Jan Hubicka <hubicka@ucw.cz>
+
+ * cgraph.c (cgraph_node::call_for_symbol_thunks_and_aliases):
+ Check availability on NODE, too.
+ * cgraph.h (symtab_node::call_for_symbol_and_aliases): Likewise.
+ (cgraph_node::call_for_symbol_and_aliases): Likewise.
+ (varpool_node::call_for_symbol_and_aliase): Likewise.
+ * ipa-pure-const.c (add_new_function): Analyze all bodies.
+ (propagate_pure_const): Propagate across interposable functions, too.
+ (skip_function_for_local_pure_const): Do not skip interposable bodies
+ with aliases.
+ (pass_local_pure_const::execute): Update.
+
+2016-05-04 Marek Polacek <polacek@redhat.com>
+
+ * doc/invoke.texi: Document -Wdangling-else.
+
+2016-05-04 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
+ * config.gcc: Error out when conflicting multilib is detected. Do not
+ loop over multilibs since no combination is legal.
+
+2016-05-04 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.h (PIC_OFFSET_TABLE_REGNUM): Correct.
+ * config/rs6000/sysv4.h (TARGET_TOC): Simplify.
+ * config/rs6000/rs6000.c (rs6000_elf_output_toc_section_asm_op):
+ Align .toc.
+
+2016-05-04 Matthew Fortune <matthew.fortune@imgtec.com>
+
+ * config/mips/mips-cpus.def (p5600): Avoid IMADD by default.
+ Clean up p5600 comments.
+
+2016-05-04 Richard Biener <rguenther@suse.de>
+
+ * match.pd: Add BIT_FIELD_REF canonicalizations and vector
+ constructor simplifications.
+ * fold-const.c (fold_ternary_loc): Remove duplicate functionality here.
+
+2016-05-04 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/predicates (post_inc_mem, pre_dec_mem): New predicates.
+ * config/sh/sh-protos.h (sh_find_set_of_reg): Return null result if
+ result.set_rtx is null instead of aborting.
+ * config/sh/sh.h (USE_LOAD_POST_INCREMENT, USE_STORE_PRE_DECREMENT):
+ Always enable.
+ (USE_LOAD_PRE_DECREMENT, USE_STORE_POST_INCREMENT): Enable for SH2A.
+ * config/sh/sh.md (*extend<mode>si2_predec, *mov<mode>_load_predec,
+ *mov<mode>_store_postinc): New patterns.
+
+2016-05-04 Marc Glisse <marc.glisse@inria.fr>
+
+ * match.pd ((A | B) & (A | C)): Generalize to BIT_XOR_EXPR. Mark
+ as commutative. Check both conversions are NOP.
+ ((A & B) OP (C & B)): Remove.
+
+2016-05-04 Alan Modra <amodra@gmail.com>
+
+ * combine.c (simplify_set): Correct WORD_REGISTER_OPERATIONS test.
+
+2016-05-04 Alan Modra <amodra@gmail.com>
+
+ PR target/70866
+ * config/rs6000/rs6000.c (rs6000_stack_info): Don't set cr_save_p
+ when cr2,3,4 are all fixed regs.
+
+2016-05-04 Bernd Schmidt <bschmidt@redhat.com>
+
+ PR rtl-optimization/57193
+ * opts.c (default_options_table): Revert OPT_frename_registers change.
+ * doc/invoke.texi (-frename-registers, -O2): Likewise.
+
+2016-05-03 Martin Sebor <msebor@redhat.com>
+
+ PR c++/66561
+ * builtins.c (fold_builtin_FILE): New function.
+ (fold_builtin_FUNCTION, fold_builtin_LINE): New functions.
+ (fold_builtin_0): Call them.
+ * gimplify.c (gimplify_call_expr): Remove the handling of
+ BUILT_IN_FILE, BUILT_IN_FUNCTION, and BUILT_IN_LINE.
+
+ PR c++/66561
+ * doc/extend.texi (Other Builtins): Update __builtin_FILE,
+ __builtin_FUNCTION, and __builtin_LINE to reflect they yield
+ constants.
+
+ PR c++/66639
+ * doc/extend.texi (Function Names as Strings): Update __func__,
+ __FUNCTION__, __PRETTY_FUNCTION__ to reflect they evaluate to
+ constants.
+
+2016-05-03 Jakub Jelinek <jakub@redhat.com>
+ Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70916
+ * tree-if-conv.c: Include cfganal.h.
+ (pass_if_conversion::execute): Call connect_infinite_loops_to_exit
+ and remove_fake_exit_edges around the optimization pass.
+
+2016-05-03 Jan Hubicka <hubicka@ucw.cz>
+
+ * cgraph.c (symbol_table::create_edge): Set inline_failed.
+ (cgraph_edge::make_direct): Likewise.
+ (cgraph_edge::dump_edge_flags): Dump call_stmt_cannot_inline_p.
+ * cgraphclones.c (duplicate_thunk_for_node): Set inline_failed.
+ * cif-code.def (CIF_LTO_MISMATCHED_DECLARATIONS): New code
+ (CIF_THUNK): New code.
+ * ipa-inline-analysis.c (initialize_inline_failed): Preserve
+ CIF_FINAL_ERROR codes; do not deal with call_stmt_cannot_inline_p.
+ (compute_inline_parameters): Set inline_failed for thunks.
+ (inline_analyze_function): Cleanup.
+ * ipa-inline.c (can_inline_edge_p): Do not deal with
+ call_stmt_cannot_inline_p.
+ (can_early_inline_edge_p): Likewise.
+ (early_inliner): Initialize inline_failed.
+ * lto-cgraph.c (lto_output_edge): Sanity check inline_failed.
+
+2016-05-03 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/predicates.md (x87nonimm_ssenomem_operand): Rename
+ from nonimm_ssenomem_operand.
+ (nonimm_ssenomem_operand): New predicate.
+ * config/i386/i386.md (extendsfdf2): Use nonimm_ssenomem_operand
+ as operand 0 predicate.
+ (*extendsfdf2): Merge from *extendsfdf2_mixed and *extendsfdf2_i387.
+ Disable unsupported alternatives using "enabled" attribute.
+ Use register_ssemem_operand as operand 0 predicate.
+ (*fop_<mode>_1): Use x87nonimm_ssenomem_operand as operand 1 predicate.
+
+2016-05-03 Marek Polacek <polacek@redhat.com>
+
+ PR c/70859
+ * input.c (expansion_point_location): New function.
+ * input.h (expansion_point_location): Declare.
+
+2016-05-03 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * dwarf2out.c (resolve_args_picking_1): Replace the frame_offset
+ occurence with frame_offset_ ones.
+
+2016-05-03 Alan Modra <amodra@gmail.com>
+
+ PR rtl-optimization/70890
+ * ira.c (combine_and_move_insns): When moving def_insn, remove
+ equivs on use_insn.
+
+2016-05-03 Dominik Vogt <vogt@linux.vnet.ibm.com>
+
+ * config/s390/s390.md ("*r<noxa>sbg_<mode>_sll")
+ ("*r<noxa>sbg_<mode>_srl"): New define_insns.
+ ("*r<noxa>sbg_<mode>_srl_bitmask"): Rename by adding "_bitmask".
+ ("*r<noxa>sbg_<mode>_sll_bitmask"): Likewise.
+
+2016-05-03 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.c (rs6000_savres_strategy): Correct condition
+ for SAVE_MULTIPLE/STORE_MULTIPLE.
+
+2016-05-03 Jakub Jelinek <jakub@redhat.com>
+
+ * config/i386/i386.md (*truncdfsf_mixed, *truncdfsf_i387,
+ *truncxfsf2_mixed, *truncxfdf2_mixed): Use v constraint instead of x.
+
+2016-05-03 Richard Biener <rguenther@suse.de>
+
+ * gimplify.h (get_initialized_tmp_var): Add allow_ssa parameter
+ default true.
+ (gimplify_arg): Likewise.
+ * gimplify.c (gimplify_expr): Add overload with allow_ssa parameter,
+ re-writing the result to a decl if required.
+ (internal_get_tmp_var): Add allow_ssa parameter
+ and override into_ssa with it.
+ (get_formal_tmp_var): Adjust.
+ (get_initialized_tmp_var): Add allow_ssa parameter.
+ (gimplify_arg): Add allow_ssa parameter and avoid generating
+ SSA names for the result false.
+ (gimplify_call_expr): If the call may return twice do not
+ gimplify parameters into SSA.
+ (prepare_gimple_addressable): Do not allow an SSA name as temporary.
+ (gimplify_modify_expr): Adjust assert. For noreturn calls
+ with a SSA name LHS adjust its def.
+ (gimplify_save_expr): Do not allow an SSA name as save-expr result.
+ (gimplify_one_sizepos): Do not allow an SSA name as a sizepos.
+ (gimplify_body): Init GIMPLE SSA data structures and gimplify into-SSA.
+ (gimplify_scan_omp_clauses): Make sure OMP_CLAUSE_SIZE is not
+ an SSA name. Likewise for OMP_CLAUSE_REDUCTION operands.
+ (gimplify_omp_for): Likewise for OMP_CLAUSE_DECL. Likewise
+ for OMP_FOR_COND, OMP_FOR_INCR and OMP_CLAUSE_LINEAR_STEP.
+ (optimize_target_teams): Do not allow SSA names for clause operands.
+ (gimplify_expr): Likewise for where we mark the result addressable.
+ * passes.def (pass_init_datastructures): Remove.
+ * tree-into-ssa.c (mark_def_sites): Ignore existing SSA names.
+ (rewrite_stmt): Likewise.
+ * tree-inline.c (initialize_cfun): Properly transfer SSA state.
+ (replace_locals_op): Replace SSA names.
+ (copy_gimple_seq_and_replace_locals): Init src_cfun.
+ * gimple-low.c (lower_builtin_setjmp): Deal with SSA.
+ * cgraph.c (release_function_body): Free CFG annotations only
+ when we have a CFG. Simplify.
+ * gimple-fold.c (gimplify_and_update_call_from_tree): Use
+ force_gimple_operand instead of get_initialized_tmp_var.
+ * tree-pass.h (make_pass_init_datastructures): Remove.
+ * tree-ssa.c (execute_init_datastructures): Remove.
+ (pass_data_init_datastructures): Likewise.
+ (class pass_init_datastructures): Likewise.
+ (make_pass_init_datastructures): Likewise.
+ * omp-low.c (create_omp_child_function): Init SSA data structures.
+ (grid_expand_target_grid_body): Likewise.
+ * tree-cfg.c (move_block_to_fn): Double-check the DEF is an SSA
+ name before adding it to names_to_release.
+ (remove_bb): Always release SSA defs.
+ * tree-ssa-ccp.c (get_default_value): Check SSA_NAME_VAR
+ before dereferencing it.
+ * cgraphunit.c (init_lowered_empty_function): Always
+ int SSA data structures.
+ * tree-ssanames.c (release_defs): Remove assert that we are in
+ SSA form.
+ * trans-mem.c (diagnose_tm_1): Handle SSA name function.
+
+2016-05-03 Jakub Jelinek <jakub@redhat.com>
+ Uros Bizjak <ubizjak@gmail.com>
+
+ PR rtl-optimization/70467
+ * config/i386/predicates.md (x86_64_hilo_int_operand,
+ x86_64_hilo_general_operand): New predicates.
+ * config/i386/constraints.md (Wd): New constraint.
+ * config/i386/i386.md (mode attr di): Use Wd instead of e.
+ (general_hilo_operand): New mode attr.
+ (add<mode>3, sub<mode>3): Use <general_hilo_operand>
+ instead of <general_operand>.
+ (*add<dwi>3_doubleword, *sub<dwi>3_doubleword): Use
+ x86_64_hilo_general_operand instead of <general_operand>.
+
+2016-05-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/70916
+ * tree-if-conv.c (constant_or_ssa_name): Removed.
+ (fold_build_cond_expr): Use is_gimple_val instead of
+ constant_or_ssa_name.
+
+ PR tree-optimization/70916
+ * tree-vect-patterns.c (vect_recog_mask_conversion_pattern): Give up
+ if COND_EXPR rhs1 is neither SSA_NAME nor COMPARISON_CLASS_P.
+
+ PR target/49244
+ * tree-ssa-ccp.c: Include stor-layout.h and optabs-query.h.
+ (optimize_atomic_bit_test_and): New function.
+ (pass_fold_builtins::execute): Use it.
+ * optabs.def (atomic_bit_test_and_set_optab,
+ atomic_bit_test_and_complement_optab,
+ atomic_bit_test_and_reset_optab): New optabs.
+ * internal-fn.def (ATOMIC_BIT_TEST_AND_SET,
+ ATOMIC_BIT_TEST_AND_COMPLEMENT, ATOMIC_BIT_TEST_AND_RESET): New ifns.
+ * builtins.h (expand_ifn_atomic_bit_test_and): New prototype.
+ * builtins.c (expand_ifn_atomic_bit_test_and): New function.
+ * internal-fn.c (expand_ATOMIC_BIT_TEST_AND_SET,
+ expand_ATOMIC_BIT_TEST_AND_COMPLEMENT,
+ expand_ATOMIC_BIT_TEST_AND_RESET): New functions.
+ * doc/md.texi (atomic_bit_test_and_set@var{mode},
+ atomic_bit_test_and_complement@var{mode},
+ atomic_bit_test_and_reset@var{mode}): Document.
+ * config/i386/sync.md (atomic_bit_test_and_set<mode>,
+ atomic_bit_test_and_complement<mode>,
+ atomic_bit_test_and_reset<mode>): New expanders.
+ (atomic_bit_test_and_set<mode>_1,
+ atomic_bit_test_and_complement<mode>_1,
+ atomic_bit_test_and_reset<mode>_1): New insns.
+
+2016-05-03 Richard Sandiford <richard.sandiford@arm.com>
+
+ PR rtl-optimization/70687
+ * combine.c (change_zero_ext): Check for scalar modes. Use wide_int
+ instead of unsigned HOST_WIDE_INT.
+
+2016-05-03 Bernd Schmidt <bschmidt@redhat.com>
+
+ PR rtl-optimization/44281
+ * hard-reg-set.h (struct target_hard_regs): New field
+ x_fixed_nonglobal_reg_set.
+ (fixed_nonglobal_reg_set): New macro.
+ * reginfo.c (init_reg_sets_1): Initialize it.
+ * ira.c (setup_alloc_regs): Use fixed_nonglobal_reg_set instead
+ of fixed_reg_set.
+ * df-scan.c (df_insn_refs_collect): Asms may reference global regs.
+
+2016-05-03 Bin Cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/56541
+ * doc/invoke.texi (@item max-tree-if-conversion-phi-args): New item.
+ * params.def (PARAM_MAX_TREE_IF_CONVERSION_PHI_ARGS): new param.
+ * tree-if-conv.c (MAX_PHI_ARG_NUM): new macro.
+ (any_complicated_phi): new static variable.
+ (aggressive_if_conv): delete.
+ (if_convertible_phi_p): support phis with more than two arguments.
+ (if_convertible_bb_p): remvoe check on aggressive_if_conv and
+ critical pred edges.
+ (ifcvt_split_critical_edges): support phis with more than two
+ arguments by checking new parameter. only split critical edges
+ if needed.
+ (tree_if_conversion): handle simd pragma marked loop using new
+ local variable aggressive_if_conv. check any_complicated_phi.
+
+2016-05-03 Bin Cheng <bin.cheng@arm.com>
+
+ * tree-ssa-loop-ivopts.c (get_computation_cost_at): Check depends_on
+ before using it.
+
+2016-05-03 Bin Cheng <bin.cheng@arm.com>
+
+ * tree-ssa-loop-ivopts.c (get_computation_cost_at): Don't clobber
+ cbase.
+
+2016-05-03 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * config/sh/sh.md (udivsi3, divsi3, mulsi3): Simplify.
+ (mulhisi3, umulhisi3, (smulsi3_highpart, umulsi3_highpart): Convert to
+ define_insn_and_split.
+ (mulsi3_i): New define_insn_and_split.
+ (mulsi3_call): Convert to define_insn.
+ (mulsidi3, mulsidi3_compact, umulsidi3, umulsidi3_compact):
+ Remove constraints.
+
+2016-05-02 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * machmode.h (mode_complex): Add support to give the complex mode
+ for a given mode.
+ (GET_MODE_COMPLEX_MODE): Likewise.
+ * stor-layout.c (layout_type): For COMPLEX_TYPE, use the mode
+ stored by build_complex_type and gfc_build_complex_type instead of
+ trying to figure out the appropriate mode based on the size. Raise
+ an assertion error, if the type was not set.
+ * genmodes.c (struct mode_data): Add field for the complex type of
+ the given type.
+ (blank_mode): Likewise.
+ (make_complex_modes): Remember the complex mode created in the
+ base type.
+ (emit_mode_complex): Write out the mode_complex array to map a
+ type mode to the complex version.
+ (emit_insn_modes_c): Likewise.
+ * tree.c (build_complex_type): Set the complex type to use before
+ calling layout_type.
+ * config/rs6000/rs6000.c (rs6000_hard_regno_nregs_internal): Add
+ support for __float128 complex datatypes.
+ (rs6000_hard_regno_mode_ok): Likewise.
+ (rs6000_setup_reg_addr_masks): Likewise.
+ (rs6000_complex_function_value): Likewise.
+ * config/rs6000/rs6000.h (FLOAT128_IEEE_P): Likewise.
+ __float128 and __ibm128 complex.
+ (FLOAT128_IBM_P): Likewise.
+ (ALTIVEC_ARG_MAX_RETURN): Likewise.
+ * doc/extend.texi (Additional Floating Types): Document that
+ -mfloat128 must be used to enable __float128. Document complex
+ __float128 and __ibm128 support.
+
+2016-05-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/49244
+ * gimple.c (gimple_builtin_call_types_compatible_p): Allow
+ char/short arguments promoted to int because of promote_prototypes.
+
+2016-05-02 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/predicates.md (register_ssemem_operand): New predicate.
+ * config/i386/i386.md (*cmpi<FPCMP:unord><MODEF:mode>): Merge from
+ *cmpi<FPCMP:unord><MODEF:mode>_mixed and
+ *cmpi<FPCMP:unord><X87MODEF:mode>_i387. Disable unsupported
+ alternatives using "enabled" attribute. Use register_ssemem_operand
+ as operand 1 predicate.
+ (*cmpi<unord>xf_i387): Split XFmode pattern from
+ *cmpi<FPCMP:unord><X87MODEF:mode>_i387.
+ (*absneg<mode>2): Merge from *absneg<mode>2_mixed and
+ *absneg<mode>2_i387. Disable unsupported alternatives using
+ "enabled" attribute.
+ (*absnegxf2_i387): Split XFmode pattern from *absneg<mode>2_i387.
+
+2016-05-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * omp-low.c (lower_oacc_head_tail): Assert there is at least one
+ marker.
+ (oacc_loop_process): Check mask for loop termination.
+
+2016-05-02 Jan Hubicka <hubicka@ucw.cz>
+
+ * cif-code.def (CIF_THUNK): Add.
+ * ipa-inline-analsysis.c (evaluate_conditions_for_known_args): Revert
+ accidental change.
+
+2016-05-02 Jan Hubicka <hubicka@ucw.cz>
+
+ * ipa-inline-analysis.c (reset_inline_summary): Clear fp_expressions
+ (dump_inline_summary): Dump it.
+ (fp_expression_p): New predicate.
+ (estimate_function_body_sizes): Use it.
+ (inline_merge_summary): Merge fp_expressions.
+ (inline_read_section): Read fp_expressions.
+ (inline_write_summary): Write fp_expressions.
+ * ipa-inline.c (can_inline_edge_p): Permit inlining across fp math
+ codegen boundary if either caller or callee is !fp_expressions.
+ * ipa-inline.h (inline_summary): Add fp_expressions.
+ * ipa-inline-transform.c (inline_call): When inlining !fp_expressions
+ to fp_expressions be sure the fp generation flags are updated.
+
+2016-05-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/70467
+ * cse.c (cse_insn): Handle no-op MEM moves after folding.
+
+ PR rtl-optimization/70467
+ * ipa-pure-const.c (check_call): Handle internal calls even in
+ ipa mode like in local mode.
+
+2016-05-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * doc/install.texi: Document supported in-tree gmp/mpfr/mpc versions.
+
+2016-05-02 Marc Glisse <marc.glisse@inria.fr>
+
+ * match.pd (X u< X, X u> X): New transformations.
+
+2016-05-02 Marc Glisse <marc.glisse@inria.fr>
+
+ * flag-types.h (enum warn_strict_overflow_code): Move ...
+ * coretypes.h: ... here.
+ * fold-const.h (fold_overflow_warning): Declare.
+ * fold-const.c (fold_overflow_warning): Make non-static.
+ (fold_comparison): Move the transformation of X +- C1 CMP C2
+ into X CMP C2 -+ C1 ...
+ * match.pd: ... here.
+ * gimple-fold.c (fold_stmt_1): Protect with
+ fold_defer_overflow_warnings.
+
2016-05-02 Nathan Sidwell <nathan@codesourcery.com>
* omp-low.c (struct oacc_loop): Add 'inner' field.
@@ -41,8 +3095,6 @@
Disable unsupported alternatives using "enabled" attribute. Use
nonimm_ssenomem_operand as operand 1 predicate. Also check
X87_ENABLE_ARITH for TARGET_MIX_SSE_I387 alternatives.
- * config/i386/predicates.md (nonimm_ssenomem_operand): New predicate.
- (register_mixssei387nonimm_operand): Remove predicate.
2016-05-02 Richard Sandiford <richard.sandiford@arm.com>
@@ -2041,6 +5093,7 @@
(avx512f_<castmode><avxsizesuffix>_<castmode>): Ditto.
(avx512f_<castmode><avxsizesuffix>_256<castmode>): Ditto.
(*sse4_1_extractps): Use lowpart_subreg.
+ * config/i386/i386.md (x87 floatsplitter): Use gen_lowpart.
2016-04-18 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index 66287530c41..fd54cb34cf5 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20160502
+20160523
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 6c5adc0bb58..2d6f1e8d02f 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -56,6 +56,7 @@ MAKEOVERRIDES =
build=@build@
host=@host@
+host_noncanonical=@host_noncanonical@
target=@target@
target_noncanonical:=@target_noncanonical@
@@ -1159,7 +1160,7 @@ CXX_TARGET_OBJS=@cxx_target_objs@
FORTRAN_TARGET_OBJS=@fortran_target_objs@
# Object files for gcc many-languages driver.
-GCC_OBJS = gcc.o gcc-main.o ggc-none.o spellcheck.o
+GCC_OBJS = gcc.o gcc-main.o ggc-none.o
c-family-warn = $(STRICT_WARN)
@@ -1548,7 +1549,7 @@ OBJS-libcommon = diagnostic.o diagnostic-color.o diagnostic-show-locus.o \
# compiler and containing target-dependent code.
OBJS-libcommon-target = $(common_out_object_file) prefix.o params.o \
opts.o opts-common.o options.o vec.o hooks.o common/common-targhooks.o \
- hash-table.o file-find.o
+ hash-table.o file-find.o spellcheck.o
# This lists all host objects for the front ends.
ALL_HOST_FRONTEND_OBJS = $(foreach v,$(CONFIG_LANGUAGES),$($(v)_OBJS))
@@ -2354,7 +2355,8 @@ s-match: build/genmatch$(build_exeext) $(srcdir)/match.pd cfn-operators.pd
GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(host_xm_file_list) \
$(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
- $(srcdir)/wide-int.h $(srcdir)/alias.h $(srcdir)/coverage.c $(srcdir)/rtl.h \
+ $(srcdir)/wide-int.h $(srcdir)/alias.h $(srcdir)/cilk.h \
+ $(srcdir)/cilk-common.c $(srcdir)/coverage.c $(srcdir)/rtl.h \
$(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/tree-core.h \
$(srcdir)/libfuncs.h $(SYMTAB_H) \
$(srcdir)/real.h $(srcdir)/function.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index a48c2f5f6f1..525b89f9c6e 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,115 @@
+2016-05-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Signed_Integer_Subtype>:
+ Make same-sized subtypes of signed base types signed.
+ * gcc-interface/utils.c (make_type_from_size): Adjust to above change.
+ (unchecked_convert): Likewise.
+
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Variable>: Do not build
+ a specific type for the object if it is deemed a constant.
+
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * freeze.adb (Freeze_Record_Type): Extend pragma Implicit_Packing to
+ components of any elementary types and of composite types.
+
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * freeze.adb (Freeze_Array_Type): Call Addressable predicate instead
+ of testing for individual sizes.
+ (Freeze_Entity): Rework implementation of pragma Implicit_Packing for
+ array types, in particular test for suitable sizes upfront and do not
+ mimic the processing that will be redone later in Freeze_Array_Type.
+
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (elaborate_all_entities_for_package): Also skip
+ formal objects.
+
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * doc/gnat_rm/implementation_defined_attributes.rst
+ (Scalar_Storage_Order): Adjust restriction for packed array types.
+ * einfo.ads (Is_Bit_Packed_Array): Adjust description.
+ (Is_Packed): Likewise.
+ (Is_Packed_Array_Impl_Type): Likewise.
+ (Packed_Array_Impl_Type): Likewise.
+ * exp_ch4.adb (Expand_N_Indexed_Component): Do not do anything special
+ if the prefix is not a packed array implemented specially.
+ * exp_ch6.adb (Expand_Actuals): Expand indexed components only for
+ bit-packed array types.
+ * exp_pakd.adb (Install_PAT): Set Is_Packed_Array_Impl_Type flag on
+ the PAT before analyzing its declaration.
+ (Create_Packed_Array_Impl_Type): Remove redundant statements.
+ * freeze.adb (Check_Component_Storage_Order): Reject packed array
+ components only if they are bit packed.
+ (Freeze_Array_Type): Fix logic detecting bit packing and do not bit
+ pack for composite types whose size is multiple of a byte.
+ Create the implementation type for packed array types only when it is
+ needed, i.e. bit packing or packing because of holes in index types.
+ Make sure the Has_Non_Standard_Rep and Is_Packed flags agree.
+ * gcc-interface/gigi.h (make_packable_type): Add MAX_ALIGN parameter.
+ * gcc-interface/decl.c (gnat_to_gnu_entity) <E_Signed_Integer_Subtype>:
+ Call maybe_pad_type instead of building the padding type manually.
+ (gnat_to_gnu_entity) <E_Array_Subtype>: Do not assert that
+ Packed_Array_Impl_Type is present for packed arrays.
+ (gnat_to_gnu_component_type): Also handle known alignment for packed
+ types by passing it to make_packable_type.
+ * gcc-interface/utils.c (make_packable_type): Add MAX_ALIGN parameter
+ and deal with it in the array case. Adjust recursive call. Simplify
+ computation of new size and cap the alignment to BIGGEST_ALIGNMENT.
+
+2016-05-16 Thomas Quinot <quinot@adacore.com>
+
+ * freeze.adb (Check_Component_Storage_Order): Also get full view of
+ enclosing type.
+
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * exp_util.adb (Remove_Side_Effects): Also make a constant if we need
+ to capture the value for a small not by-reference record type.
+ * freeze.ads (Check_Compile_Time_Size): Adjust comment.
+ * freeze.adb (Set_Small_Size): Likewise. Accept a size in the range
+ of 33 .. 64 bits.
+ (Check_Compile_Time_Size): Merge scalar and access type cases. Change
+ variable name in array type case. For the computation of the packed
+ size, deal with record components and remove redundant test.
+ (Freeze_Array_Type): Also adjust packing status when the size of the
+ component type is in the range 33 .. 64 bits.
+ * doc/gnat_rm/representation_clauses_and_pragmas.rst: Turn primitive
+ into elementary type throughout. Minor tweaks.
+ (Alignment Clauses): Document actual alignment of packed array types.
+ (Pragma Pack for Arrays): List only the 3 main cases and adjust. Add
+ "simple" to the record case. Document effect on non packable types.
+ (Pragma Pack for Records): Likewise. Add record case and adjust.
+
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/Make-lang.in (GNATMAKE_FOR_HOST): In the canadian
+ cross case, use host_noncanonical instead of host as prefix.
+ (GNATBIND_FOR_HOST): Likewise.
+ (GNATLINK_FOR_HOST): Likewise.
+ (GNATLS_FOR_HOST): Likewise.
+
+2016-05-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/70969
+ * system-darwin-ppc64.ads: Add pragma No_Elaboration_Code_All.
+ * system-linux-armeb.ads: Likewise.
+ * system-linux-mips64el.ads: Likewise.
+ * system-linux-mips.ads: Likewise.
+ * system-linux-mipsel.ads: Likewise.
+ * system-linux-ppc64.ads: Likewise.
+ * system-linux-sparcv9.ads: Likewise.
+ * system-rtems.ads: Likewise.
+
+2016-05-04 Samuel Thibault <samuel.thibault@ens-lyon.org>
+
+ * s-osinte-gnu.ads (Get_Page_Size): Return int and use getpagesize
+ instead of __getpagesize.
+
2016-05-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* gcc-interface/Makefile.in (install-gcc-specs): Use foreach.
diff --git a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
index 432db36441a..958ab2413f7 100644
--- a/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
+++ b/gcc/ada/doc/gnat_rm/implementation_defined_attributes.rst
@@ -969,7 +969,7 @@ must have the same scalar storage order as the parent type.
If a component of `T` is of a record or array type, then that type must
also have a `Scalar_Storage_Order` attribute definition clause.
-A component of a record or array type that is a packed array, or that
+A component of a record or array type that is a bit-packed array, or that
does not start on a byte boundary, must have the same scalar storage order
as the enclosing record or array type.
diff --git a/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst b/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
index b9eee2f6c13..0a3dd4a9112 100644
--- a/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
+++ b/gcc/ada/doc/gnat_rm/representation_clauses_and_pragmas.rst
@@ -32,9 +32,9 @@ GNAT requires that all alignment clauses specify a power of 2, and all
default alignments are always a power of 2. The default alignment
values are as follows:
-* *Primitive Types*.
+* *Elementary Types*.
- For primitive types, the alignment is the minimum of the actual size of
+ For elementary types, the alignment is the minimum of the actual size of
objects of the type divided by `Storage_Unit`,
and the maximum alignment supported by the target.
(This maximum alignment is given by the GNAT-specific attribute
@@ -53,10 +53,11 @@ values are as follows:
For arrays, the alignment is equal to the alignment of the component type
for the normal case where no packing or component size is given. If the
array is packed, and the packing is effective (see separate section on
- packed arrays), then the alignment will be one for long packed arrays,
- or arrays whose length is not known at compile time. For short packed
+ packed arrays), then the alignment will be either 4, 2 or 1 for long packed
+ arrays or arrays whose length is not known at compile time, depending on
+ whether the component size is divisible by 4, 2 or is odd. For short packed
arrays, which are handled internally as modular types, the alignment
- will be as described for primitive types, e.g., a packed array of length
+ will be as described for elementary types, e.g. a packed array of length
31 bits will have an object size of four bytes, and an alignment of 4.
* *Records*.
@@ -789,7 +790,7 @@ restrictions placed on component clauses as follows:
little-endian machines, this must be explicitly programmed. This capability
is not provided by `Bit_Order`.
-* Components that are positioned across byte boundaries
+* Components that are positioned across byte boundaries.
but do not occupy an integral number of bytes. Given that bytes are not
reordered, such fields would occupy a non-contiguous sequence of bits
@@ -1069,22 +1070,23 @@ Pragma Pack for Arrays
.. index:: Pragma Pack (for arrays)
-Pragma `Pack` applied to an array has no effect unless the component type
-is packable. For a component type to be packable, it must be one of the
-following cases:
+Pragma `Pack` applied to an array has an effect that depends upon whether the
+component type is *packable*. For a component type to be *packable*, it must
+be one of the following cases:
-*
- Any scalar type
-*
- Any type whose size is specified with a size clause
-*
- Any packed array type with a static size
-*
- Any record type padded because of its default alignment
+* Any elementary type.
+
+* Any small packed array type with a static size.
+
+* Any small simple record type with a static size.
For all these cases, if the component subtype size is in the range
-1 through 63, then the effect of the pragma `Pack` is exactly as though a
+1 through 64, then the effect of the pragma `Pack` is exactly as though a
component size were specified giving the component subtype size.
+
+All other types are non-packable, they occupy an integral number of storage
+units and the only effect of pragma Pack is to remove alignment gaps.
+
For example if we have:
.. code-block:: ada
@@ -1095,7 +1097,7 @@ For example if we have:
pragma Pack (ar);
Then the component size of `ar` will be set to 5 (i.e., to `r'size`,
-and the size of the array `ar` will be exactly 40 bits.
+and the size of the array `ar` will be exactly 40 bits).
Note that in some cases this rather fierce approach to packing can produce
unexpected effects. For example, in Ada 95 and Ada 2005,
@@ -1184,23 +1186,21 @@ taken by components. We distinguish between *packable* components and
*non-packable* components.
Components of the following types are considered packable:
-*
- Components of a primitive type are packable unless they are aliased
- or of an atomic type.
+* Components of an elementary type are packable unless they are aliased,
+ independent or of an atomic type.
-*
- Small packed arrays, whose size does not exceed 64 bits, and where the
- size is statically known at compile time, are represented internally
- as modular integers, and so they are also packable.
+* Small packed arrays, where the size is statically known, are represented
+ internally as modular integers, and so they are also packable.
+* Small simple records, where the size is statically known, are also packable.
-All packable components occupy the exact number of bits corresponding to
-their `Size` value, and are packed with no padding bits, i.e., they
-can start on an arbitrary bit boundary.
+For all these cases, if the 'Size value is in the range 1 through 64, the
+components occupy the exact number of bits corresponding to this value
+and are packed with no padding bits, i.e. they can start on an arbitrary
+bit boundary.
-All other types are non-packable, they occupy an integral number of
-storage units, and
-are placed at a boundary corresponding to their alignment requirements.
+All other types are non-packable, they occupy an integral number of storage
+units and the only effect of pragma Pack is to remove alignment gaps.
For example, consider the record
@@ -1331,7 +1331,7 @@ so for example, the following is permitted:
Note: the above rules apply to recent releases of GNAT 5.
In GNAT 3, there are more severe restrictions on larger components.
-For non-primitive types, including packed arrays with a size greater than
+For composite types, including packed arrays with a size greater than
64 bits, component clauses must respect the alignment requirement of the
type, in particular, always starting on a byte boundary, and the length
must be a multiple of the storage unit.
diff --git a/gcc/ada/einfo.ads b/gcc/ada/einfo.ads
index 901e2ef937e..69492fc1748 100644
--- a/gcc/ada/einfo.ads
+++ b/gcc/ada/einfo.ads
@@ -2268,9 +2268,9 @@ package Einfo is
-- is bit packed (i.e. the component size is known by the front end and
-- is in the range 1-7, 9-15, 17-31, or 33-63). Is_Packed is always set
-- if Is_Bit_Packed_Array is set, but it is possible for Is_Packed to be
--- set without Is_Bit_Packed_Array for the case of an array having one or
--- more index types that are enumeration types with non-standard
--- enumeration representations.
+-- set without Is_Bit_Packed_Array if the component size is not known by
+-- the front-end or for the case of an array having one or more index
+-- types that are enumeration types with non-standard representation.
-- Is_Boolean_Type (synthesized)
-- Applies to all entities, true for boolean types and subtypes,
@@ -2852,49 +2852,49 @@ package Einfo is
-- Is_Packed (Flag51) [implementation base type only]
-- Defined in all type entities. This flag is set only for record and
--- array types which have a packed representation. There are three
--- cases which cause packing:
+-- array types which have a packed representation. There are four cases
+-- which cause packing:
--
--- 1. Explicit use of pragma Pack for an array of package components
--- 2. Explicit use of pragma Pack to pack a record
--- 4. Setting Component_Size of an array to a bit-packable value
--- 3. Indexing an array with a non-standard enumeration type.
+-- 1. Explicit use of pragma Pack to pack a record.
+-- 2. Explicit use of pragma Pack to pack an array.
+-- 3. Setting Component_Size of an array to a packable value.
+-- 4. Indexing an array with a non-standard enumeration type.
--
--- For records, Is_Packed is always set if Has_Pragma_Pack is set,
--- and can also be set on its own in a derived type which inherited
--- its packed status.
---
--- For arrays, Is_Packed is set if an array is bit packed (i.e. the
--- component size is known at compile time and is 1-7, 9-15 or 17-31),
--- or if the array has one or more index types that are enumeration
--- types with non-standard representations (in GNAT, we store such
--- arrays compactly, using the Pos of the enumeration type value).
---
--- As for the case of records, Is_Packed can be set on its own for a
--- derived type, with the same dual before/after freeze meaning.
--- Is_Packed can also be set as the result of an explicit component
--- size clause that specifies an appropriate component size.
---
--- In the bit packed array case, Is_Bit_Packed_Array will be set in
--- the bit packed case once the array type is frozen.
+-- For records, Is_Packed is always set if Has_Pragma_Pack is set, and
+-- can also be set on its own in a derived type which inherited its
+-- packed status.
--
+-- For arrays, Is_Packed is set if either Has_Pragma_Pack is set and the
+-- component size is either not known at compile time or known but not
+-- 8/16/32/64 bits, or a Component_Size clause exists and the specified
+-- value is smaller than 64 bits but not 8/16/32, or if the array has one
+-- or more index types that are enumeration types with a non-standard
+-- representation (in GNAT, we store such arrays compactly, using the Pos
+-- of the enumeration type value). As for the case of records, Is_Packed
+-- can be set on its own for a derived type.
+
-- Before an array type is frozen, Is_Packed will always be set if
-- Has_Pragma_Pack is set. Before the freeze point, it is not possible
-- to know the component size, since the component type is not frozen
-- until the array type is frozen. Thus Is_Packed for an array type
-- before it is frozen means that packed is required. Then if it turns
--- out that the component size is not suitable for bit packing, the
--- Is_Packed flag gets turned off.
+-- out that the component size doesn't require packing, the Is_Packed
+-- flag gets turned off.
+-- In the bit packed array case (i.e. component size is known at compile
+-- time and is 1-7, 9-15, 17-31 or 33-63), Is_Bit_Packed_Array will be
+-- set once the array type is frozen.
+--
-- Is_Packed_Array (synth)
-- Applies to all entities, true if entity is for a packed array.
-- Is_Packed_Array_Impl_Type (Flag138)
-- Defined in all entities. This flag is set on the entity for the type
--- used to implement a packed array (either a modular type, or a subtype
--- of Packed_Bytes{1,2,4} as appropriate). The flag is set if and only
+-- used to implement a packed array (either a modular type or a subtype
+-- of Packed_Bytes{1,2,4} in the bit packed array case, a regular array
+-- in the non-standard enumeration index case). It is set if and only
-- if the type appears in the Packed_Array_Impl_Type field of some other
--- entity. It is used by the backend to activate the special processing
+-- entity. It is used by the back end to activate the special processing
-- for such types (unchecked conversions that would not otherwise be
-- allowed are allowed for such types). If Is_Packed_Array_Impl_Type is
-- set in an entity, then the Original_Array_Type field of this entity
@@ -3698,16 +3698,17 @@ package Einfo is
-- with formal packages. ???
-- Packed_Array_Impl_Type (Node23)
--- Defined in array types and subtypes, including the string literal
--- subtype case, if the corresponding type is packed (either bit packed
--- or packed to eliminate holes in non-contiguous enumeration type index
--- types). References the type used to represent the packed array, which
--- is either a modular type for short static arrays, or an array of
--- System.Unsigned. Note that in some situations (internal types, and
--- references to fields of variant records), it is not always possible
--- to construct this type in advance of its use. If this field is empty,
--- then the necessary type is declared on the fly for each reference to
--- the array.
+-- Defined in array types and subtypes, except for the string literal
+-- subtype case, if the corresponding type is packed and implemented
+-- specially (either bit packed or packed to eliminate holes in the
+-- non-contiguous enumeration index types). References the type used to
+-- represent the packed array, which is either a modular type for short
+-- static arrays or an array of System.Unsigned in the bit packed case,
+-- or a regular array in the non-standard enumeration index case). Note
+-- that in some situations (internal types and references to fields of
+-- variant records), it is not always possible to construct this type in
+-- advance of its use. If this field is empty, then the necessary type
+-- is declared on the fly for each reference to the array.
-- Parameter_Mode (synthesized)
-- Applies to formal parameter entities. This is a synonym for Ekind,
diff --git a/gcc/ada/exp_ch4.adb b/gcc/ada/exp_ch4.adb
index cb1c117b30b..e6ea474eec1 100644
--- a/gcc/ada/exp_ch4.adb
+++ b/gcc/ada/exp_ch4.adb
@@ -6216,9 +6216,11 @@ package body Exp_Ch4 is
Activate_Atomic_Synchronization (N);
end if;
- -- All done for the non-packed case
+ -- All done if the prefix is not a packed array implemented specially
- if not Is_Packed (Etype (Prefix (N))) then
+ if not (Is_Packed (Etype (Prefix (N)))
+ and then Present (Packed_Array_Impl_Type (Etype (Prefix (N)))))
+ then
return;
end if;
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index dbdd33dc8fc..9f7c1dc01c6 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -2038,7 +2038,7 @@ package body Exp_Ch6 is
-- Processing for IN parameters
else
- -- For IN parameters is in the packed array case, we expand an
+ -- For IN parameters in the bit packed array case, we expand an
-- indexed component (the circuit in Exp_Ch4 deliberately left
-- indexed components appearing as actuals untouched, so that
-- the special processing above for the OUT and IN OUT cases
@@ -2047,7 +2047,7 @@ package body Exp_Ch6 is
-- easier simply to handle all cases here.)
if Nkind (Actual) = N_Indexed_Component
- and then Is_Packed (Etype (Prefix (Actual)))
+ and then Is_Bit_Packed_Array (Etype (Prefix (Actual)))
then
Reset_Packed_Prefix;
Expand_Packed_Element_Reference (Actual);
diff --git a/gcc/ada/exp_pakd.adb b/gcc/ada/exp_pakd.adb
index ea82596b820..0ec3ef44814 100644
--- a/gcc/ada/exp_pakd.adb
+++ b/gcc/ada/exp_pakd.adb
@@ -543,6 +543,7 @@ package body Exp_Pakd is
end if;
Set_Is_Itype (PAT, True);
+ Set_Is_Packed_Array_Impl_Type (PAT, True);
Set_Packed_Array_Impl_Type (Typ, PAT);
Analyze (Decl, Suppress => All_Checks);
@@ -569,7 +570,6 @@ package body Exp_Pakd is
Init_Alignment (PAT);
Set_Parent (PAT, Empty);
Set_Associated_Node_For_Itype (PAT, Typ);
- Set_Is_Packed_Array_Impl_Type (PAT, True);
Set_Original_Array_Type (PAT, Typ);
-- Propagate representation aspects
@@ -701,8 +701,6 @@ package body Exp_Pakd is
Make_Defining_Identifier (Loc,
Chars => New_External_Name (Chars (Typ), 'P'));
- Set_Packed_Array_Impl_Type (Typ, PAT);
-
declare
Indexes : constant List_Id := New_List;
Indx : Node_Id;
@@ -798,9 +796,6 @@ package body Exp_Pakd is
Type_Definition => Typedef);
end;
- -- Set type as packed array type and install it
-
- Set_Is_Packed_Array_Impl_Type (PAT);
Install_PAT;
return;
@@ -819,13 +814,13 @@ package body Exp_Pakd is
Make_Defining_Identifier (Loc,
Chars => Make_Packed_Array_Impl_Type_Name (Typ, Csize));
- Set_Packed_Array_Impl_Type (Typ, PAT);
Set_PB_Type;
Decl :=
Make_Subtype_Declaration (Loc,
Defining_Identifier => PAT,
Subtype_Indication => New_Occurrence_Of (PB_Type, Loc));
+
Install_PAT;
return;
@@ -843,8 +838,6 @@ package body Exp_Pakd is
Make_Defining_Identifier (Loc,
Chars => Make_Packed_Array_Impl_Type_Name (Typ, Csize));
- Set_Packed_Array_Impl_Type (Typ, PAT);
-
-- Build an expression for the length of the array in bits.
-- This is the product of the length of each of the dimensions
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 4ea4cb2bf3b..7dbf44acfe8 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -7711,15 +7711,22 @@ package body Exp_Util is
Scope_Suppress.Suppress := (others => True);
- -- If it is an elementary type and we need to capture the value, just
- -- make a constant. Likewise if this is not a name reference, except
- -- for a type conversion because we would enter an infinite recursion
- -- with Checks.Apply_Predicate_Check if the target type has predicates.
- -- And type conversions need a specific treatment anyway, see below.
- -- Also do it if we have a volatile reference and Name_Req is not set
- -- (see comments for Side_Effect_Free).
-
- if Is_Elementary_Type (Exp_Type)
+ -- If this is an elementary or a small not by-reference record type, and
+ -- we need to capture the value, just make a constant; this is cheap and
+ -- objects of both kinds of types can be bit aligned, so it might not be
+ -- possible to generate a reference to them. Likewise if this is not a
+ -- name reference, except for a type conversion because we would enter
+ -- an infinite recursion with Checks.Apply_Predicate_Check if the target
+ -- type has predicates (and type conversions need a specific treatment
+ -- anyway, see below). Also do it if we have a volatile reference and
+ -- Name_Req is not set (see comments for Side_Effect_Free).
+
+ if (Is_Elementary_Type (Exp_Type)
+ or else (Is_Record_Type (Exp_Type)
+ and then Known_Static_RM_Size (Exp_Type)
+ and then RM_Size (Exp_Type) <= 64
+ and then not Has_Discriminants (Exp_Type)
+ and then not Is_By_Reference_Type (Exp_Type)))
and then (Variable_Ref
or else (not Is_Name_Reference (Exp)
and then Nkind (Exp) /= N_Type_Conversion)
diff --git a/gcc/ada/freeze.adb b/gcc/ada/freeze.adb
index 1fce9477818..ec8ea2c3a4e 100644
--- a/gcc/ada/freeze.adb
+++ b/gcc/ada/freeze.adb
@@ -745,9 +745,9 @@ package body Freeze is
procedure Check_Compile_Time_Size (T : Entity_Id) is
procedure Set_Small_Size (T : Entity_Id; S : Uint);
- -- Sets the compile time known size (32 bits or less) in the Esize
- -- field, of T checking for a size clause that was given which attempts
- -- to give a smaller size, and also checking for an alignment clause.
+ -- Sets the compile time known size (64 bits or less) in the RM_Size
+ -- field of T, checking for a size clause that was given which attempts
+ -- to give a smaller size.
function Size_Known (T : Entity_Id) return Boolean;
-- Recursive function that does all the work
@@ -765,7 +765,7 @@ package body Freeze is
procedure Set_Small_Size (T : Entity_Id; S : Uint) is
begin
- if S > 32 then
+ if S > 64 then
return;
-- Check for bad size clause given
@@ -800,14 +800,12 @@ package body Freeze is
if Size_Known_At_Compile_Time (T) then
return True;
- -- Always True for scalar types. This is true even for generic formal
- -- scalar types. We used to return False in the latter case, but the
- -- size is known at compile time, even in the template, we just do
- -- not know the exact size but that's not the point of this routine.
+ -- Always True for elementary types, even generic formal elementary
+ -- types. We used to return False in the latter case, but the size
+ -- is known at compile time, even in the template, we just do not
+ -- know the exact size but that's not the point of this routine.
- elsif Is_Scalar_Type (T)
- or else Is_Task_Type (T)
- then
+ elsif Is_Elementary_Type (T) or else Is_Task_Type (T) then
return True;
-- Array types
@@ -817,8 +815,8 @@ package body Freeze is
-- String literals always have known size, and we can set it
if Ekind (T) = E_String_Literal_Subtype then
- Set_Small_Size (T, Component_Size (T)
- * String_Literal_Length (T));
+ Set_Small_Size
+ (T, Component_Size (T) * String_Literal_Length (T));
return True;
-- Unconstrained types never have known at compile time size
@@ -839,10 +837,10 @@ package body Freeze is
end if;
-- Check for all indexes static, and also compute possible size
- -- (in case it is less than 32 and may be packable).
+ -- (in case it is not greater than 64 and may be packable).
declare
- Esiz : Uint := Component_Size (T);
+ Size : Uint := Component_Size (T);
Dim : Uint;
begin
@@ -869,24 +867,19 @@ package body Freeze is
Dim := Expr_Value (High) - Expr_Value (Low) + 1;
if Dim >= 0 then
- Esiz := Esiz * Dim;
+ Size := Size * Dim;
else
- Esiz := Uint_0;
+ Size := Uint_0;
end if;
end if;
Next_Index (Index);
end loop;
- Set_Small_Size (T, Esiz);
+ Set_Small_Size (T, Size);
return True;
end;
- -- Access types always have known at compile time sizes
-
- elsif Is_Access_Type (T) then
- return True;
-
-- For non-generic private types, go to underlying type if present
elsif Is_Private_Type (T)
@@ -1074,11 +1067,10 @@ package body Freeze is
if Packed_Size_Known then
- -- We can only deal with elementary types, since for
- -- non-elementary components, alignment enters into the
- -- picture, and we don't know enough to handle proper
- -- alignment in this context. Packed arrays count as
- -- elementary if the representation is a modular type.
+ -- We can deal with elementary types, small packed arrays
+ -- if the representation is a modular type and also small
+ -- record types (if the size is not greater than 64, but
+ -- the condition is checked by Set_Small_Size).
if Is_Elementary_Type (Ctyp)
or else (Is_Array_Type (Ctyp)
@@ -1086,33 +1078,14 @@ package body Freeze is
(Packed_Array_Impl_Type (Ctyp))
and then Is_Modular_Integer_Type
(Packed_Array_Impl_Type (Ctyp)))
+ or else Is_Record_Type (Ctyp)
then
- -- Packed size unknown if we have an atomic/VFA type
- -- or a by-reference type, since the back end knows
- -- how these are layed out.
-
- if Is_Atomic_Or_VFA (Ctyp)
- or else Is_By_Reference_Type (Ctyp)
- then
- Packed_Size_Known := False;
-
-- If RM_Size is known and static, then we can keep
- -- accumulating the packed size
-
- elsif Known_Static_RM_Size (Ctyp) then
-
- -- A little glitch, to be removed sometime ???
- -- gigi does not understand zero sizes yet.
+ -- accumulating the packed size.
- if RM_Size (Ctyp) = Uint_0 then
- Packed_Size_Known := False;
+ if Known_Static_RM_Size (Ctyp) then
- -- Normal case where we can keep accumulating the
- -- packed array size.
-
- else
- Packed_Size := Packed_Size + RM_Size (Ctyp);
- end if;
+ Packed_Size := Packed_Size + RM_Size (Ctyp);
-- If we have a field whose RM_Size is not known then
-- we can't figure out the packed size here.
@@ -1121,8 +1094,7 @@ package body Freeze is
Packed_Size_Known := False;
end if;
- -- If we have a non-elementary type we can't figure out
- -- the packed array size (alignment issues).
+ -- For other types we can't figure out the packed size
else
Packed_Size_Known := False;
@@ -1189,7 +1161,8 @@ package body Freeze is
ADC : Node_Id;
Comp_ADC_Present : out Boolean)
is
- Comp_Type : Entity_Id;
+ Encl_Base : Entity_Id;
+ Comp_Base : Entity_Id;
Comp_ADC : Node_Id;
Err_Node : Node_Id;
@@ -1208,7 +1181,7 @@ package body Freeze is
if Present (Comp) then
Err_Node := Comp;
- Comp_Type := Etype (Comp);
+ Comp_Base := Etype (Comp);
if Is_Tag (Comp) then
Comp_Byte_Aligned := True;
@@ -1233,24 +1206,28 @@ package body Freeze is
else
Err_Node := Encl_Type;
- Comp_Type := Component_Type (Encl_Type);
+ Comp_Base := Component_Type (Encl_Type);
Component_Aliased := Has_Aliased_Components (Encl_Type);
end if;
-- Note: the Reverse_Storage_Order flag is set on the base type, but
-- the attribute definition clause is attached to the first subtype.
+ -- Also, if the base type is incomplete or private, go to full view
+ -- if known
- Comp_Type := Base_Type (Comp_Type);
-
- -- If the base type is incomplete or private, go to full view if known
+ Encl_Base := Base_Type (Encl_Type);
+ if Present (Underlying_Type (Encl_Base)) then
+ Encl_Base := Underlying_Type (Encl_Base);
+ end if;
- if Present (Underlying_Type (Comp_Type)) then
- Comp_Type := Underlying_Type (Comp_Type);
+ Comp_Base := Base_Type (Comp_Base);
+ if Present (Underlying_Type (Comp_Base)) then
+ Comp_Base := Underlying_Type (Comp_Base);
end if;
Comp_ADC := Get_Attribute_Definition_Clause
- (First_Subtype (Comp_Type),
+ (First_Subtype (Comp_Base),
Attribute_Scalar_Storage_Order);
Comp_ADC_Present := Present (Comp_ADC);
@@ -1258,14 +1235,14 @@ package body Freeze is
-- But, if the record has Complex_Representation, then it is treated as
-- a scalar in the back end so the storage order is irrelevant.
- if (Is_Record_Type (Comp_Type)
- and then not Has_Complex_Representation (Comp_Type))
- or else Is_Array_Type (Comp_Type)
+ if (Is_Record_Type (Comp_Base)
+ and then not Has_Complex_Representation (Comp_Base))
+ or else Is_Array_Type (Comp_Base)
then
Comp_SSO_Differs :=
- Reverse_Storage_Order (Encl_Type)
+ Reverse_Storage_Order (Encl_Base)
/=
- Reverse_Storage_Order (Comp_Type);
+ Reverse_Storage_Order (Comp_Base);
-- Parent and extension must have same storage order
@@ -1277,31 +1254,31 @@ package body Freeze is
end if;
-- If component and composite SSO differs, check that component
- -- falls on byte boundaries and isn't packed.
+ -- falls on byte boundaries and isn't bit packed.
elsif Comp_SSO_Differs then
-- Component SSO differs from enclosing composite:
- -- Reject if component is a packed array, as it may be represented
+ -- Reject if component is a bit-packed array, as it is represented
-- as a scalar internally.
- if Is_Packed_Array (Comp_Type) then
+ if Is_Bit_Packed_Array (Comp_Base) then
Error_Msg_N
("type of packed component must have same scalar storage "
& "order as enclosing composite", Err_Node);
- -- Reject if composite is a packed array, as it may be rewritten
+ -- Reject if composite is a bit-packed array, as it is rewritten
-- into an array of scalars.
- elsif Is_Packed_Array (Encl_Type) then
+ elsif Is_Bit_Packed_Array (Encl_Base) then
Error_Msg_N
("type of packed array must have same scalar storage order "
& "as component", Err_Node);
-- Reject if not byte aligned
- elsif Is_Record_Type (Encl_Type)
+ elsif Is_Record_Type (Encl_Base)
and then not Comp_Byte_Aligned
then
Error_Msg_N
@@ -1313,7 +1290,7 @@ package body Freeze is
elsif Present (ADC) and then No (Comp_ADC) then
Error_Msg_NE
("scalar storage order specified for & does not apply to "
- & "component?", Err_Node, Encl_Type);
+ & "component?", Err_Node, Encl_Base);
end if;
end if;
@@ -2409,7 +2386,7 @@ package body Freeze is
end if;
end if;
- -- Case of component size that may result in packing
+ -- Case of component size that may result in bit packing
if 1 <= Csiz and then Csiz <= 64 then
declare
@@ -2474,42 +2451,54 @@ package body Freeze is
end if;
end if;
- -- Actual packing is not needed for 8, 16, 32, 64. Also
- -- not needed for 24 if alignment is 1.
-
- if Csiz = 8
- or else Csiz = 16
- or else Csiz = 32
- or else Csiz = 64
- or else (Csiz = 24 and then Alignment (Ctyp) = 1)
- then
- -- Here the array was requested to be packed, but
- -- the packing request had no effect, so Is_Packed
- -- is reset.
+ -- Bit packing is never needed for 8, 16, 32, 64
- -- Note: semantically this means that we lose track
- -- of the fact that a derived type inherited a pragma
- -- Pack that was non- effective, but that seems fine.
-
- -- We regard a Pack pragma as a request to set a
- -- representation characteristic, and this request
- -- may be ignored.
-
- Set_Is_Packed (Base_Type (Arr), False);
- Set_Is_Bit_Packed_Array (Base_Type (Arr), False);
+ if Addressable (Csiz) then
+ -- If the Esize of the component is known and equal to
+ -- the component size then even packing is not needed.
if Known_Static_Esize (Component_Type (Arr))
and then Esize (Component_Type (Arr)) = Csiz
then
+ -- Here the array was requested to be packed, but
+ -- the packing request had no effect whatsoever,
+ -- so flag Is_Packed is reset.
+
+ -- Note: semantically this means that we lose track
+ -- of the fact that a derived type inherited pragma
+ -- Pack that was non-effective, but that is fine.
+
+ -- We regard a Pack pragma as a request to set a
+ -- representation characteristic, and this request
+ -- may be ignored.
+
+ Set_Is_Packed (Base_Type (Arr), False);
Set_Has_Non_Standard_Rep (Base_Type (Arr), False);
+ else
+ Set_Is_Packed (Base_Type (Arr), True);
+ Set_Has_Non_Standard_Rep (Base_Type (Arr), True);
end if;
- -- In all other cases, packing is indeed needed
+ Set_Is_Bit_Packed_Array (Base_Type (Arr), False);
+
+ -- Bit packing is not needed for multiples of the storage
+ -- unit if the type is composite because the back end can
+ -- byte pack composite types.
+
+ elsif Csiz mod System_Storage_Unit = 0
+ and then Is_Composite_Type (Ctyp)
+ then
+
+ Set_Is_Packed (Base_Type (Arr), True);
+ Set_Has_Non_Standard_Rep (Base_Type (Arr), True);
+ Set_Is_Bit_Packed_Array (Base_Type (Arr), False);
+
+ -- In all other cases, bit packing is needed
else
+ Set_Is_Packed (Base_Type (Arr), True);
Set_Has_Non_Standard_Rep (Base_Type (Arr), True);
Set_Is_Bit_Packed_Array (Base_Type (Arr), True);
- Set_Is_Packed (Base_Type (Arr), True);
end if;
end;
end if;
@@ -2801,12 +2790,14 @@ package body Freeze is
Set_Component_Alignment_If_Not_Set (Arr);
- -- If the array is packed, we must create the packed array type to be
- -- used to actually implement the type. This is only needed for real
- -- array types (not for string literal types, since they are present
- -- only for the front end).
+ -- If the array is packed and bit packed or packed to eliminate holes
+ -- in the non-contiguous enumeration index types, we must create the
+ -- packed array type to be used to actually implement the type. This
+ -- is only needed for real array types (not for string literal types,
+ -- since they are present only for the front end).
if Is_Packed (Arr)
+ and then (Is_Bit_Packed_Array (Arr) or else Non_Standard_Enum)
and then Ekind (Arr) /= E_String_Literal_Subtype
then
Create_Packed_Array_Impl_Type (Arr);
@@ -3543,13 +3534,23 @@ package body Freeze is
-- Set True if we find at least one component whose type has a
-- Scalar_Storage_Order attribute definition clause.
- All_Scalar_Components : Boolean := True;
- -- Set False if we encounter a component of a non-scalar type
+ All_Elem_Components : Boolean := True;
+ -- Set False if we encounter a component of a composite type
+
+ All_Sized_Components : Boolean := True;
+ -- Set False if we encounter a component with unknown RM_Size
+
+ All_Storage_Unit_Components : Boolean := True;
+ -- Set False if we encounter a component of a composite type whose
+ -- RM_Size is not a multiple of the storage unit.
- Scalar_Component_Total_RM_Size : Uint := Uint_0;
- Scalar_Component_Total_Esize : Uint := Uint_0;
- -- Accumulates total RM_Size values and total Esize values of all
- -- scalar components. Used for processing of Implicit_Packing.
+ Elem_Component_Total_Esize : Uint := Uint_0;
+ -- Accumulates total Esize values of all elementary components. Used
+ -- for processing of Implicit_Packing.
+
+ Sized_Component_Total_RM_Size : Uint := Uint_0;
+ -- Accumulates total RM_Size values of all sized components. Used
+ -- for processing of Implicit_Packing.
function Check_Allocator (N : Node_Id) return Node_Id;
-- If N is an allocator, possibly wrapped in one or more level of
@@ -3844,13 +3845,22 @@ package body Freeze is
-- this stage we might be dealing with a real component, or with
-- an implicit subtype declaration.
- if not Is_Scalar_Type (Etype (Comp)) then
- All_Scalar_Components := False;
+ if Known_Static_RM_Size (Etype (Comp)) then
+ Sized_Component_Total_RM_Size :=
+ Sized_Component_Total_RM_Size + RM_Size (Etype (Comp));
+
+ if Is_Elementary_Type (Etype (Comp)) then
+ Elem_Component_Total_Esize :=
+ Elem_Component_Total_Esize + Esize (Etype (Comp));
+ else
+ All_Elem_Components := False;
+
+ if RM_Size (Etype (Comp)) mod System_Storage_Unit /= 0 then
+ All_Storage_Unit_Components := False;
+ end if;
+ end if;
else
- Scalar_Component_Total_RM_Size :=
- Scalar_Component_Total_RM_Size + RM_Size (Etype (Comp));
- Scalar_Component_Total_Esize :=
- Scalar_Component_Total_Esize + Esize (Etype (Comp));
+ All_Sized_Components := False;
end if;
-- If the component is an Itype with Delayed_Freeze and is either
@@ -4321,26 +4331,33 @@ package body Freeze is
and then not Aliased_Component
- -- Must have size clause and all scalar components
+ -- Must have size clause and all sized components
and then Has_Size_Clause (Rec)
- and then All_Scalar_Components
+ and then All_Sized_Components
-- Do not try implicit packing on records with discriminants, too
-- complicated, especially in the variant record case.
and then not Has_Discriminants (Rec)
- -- We can implicitly pack if the specified size of the record is
- -- less than the sum of the object sizes (no point in packing if
- -- this is not the case).
+ -- We want to implicitly pack if the specified size of the record
+ -- is less than the sum of the object sizes (no point in packing
+ -- if this is not the case) if we can compute it, i.e. if we have
+ -- only elementary components. Otherwise, we have at least one
+ -- composite component and we want to implicit pack only if bit
+ -- packing is required for it, as we are sure in this case that
+ -- the back end cannot do the expected layout without packing.
- and then RM_Size (Rec) < Scalar_Component_Total_Esize
+ and then ((All_Elem_Components
+ and then RM_Size (Rec) < Elem_Component_Total_Esize)
+ or else (not All_Elem_Components
+ and then not All_Storage_Unit_Components))
-- And the total RM size cannot be greater than the specified size
-- since otherwise packing will not get us where we have to be.
- and then RM_Size (Rec) >= Scalar_Component_Total_RM_Size
+ and then RM_Size (Rec) >= Sized_Component_Total_RM_Size
-- Never do implicit packing in CodePeer or SPARK modes since
-- we don't do any packing in these modes, since this generates
@@ -5300,20 +5317,20 @@ package body Freeze is
if E /= Base_Type (E) then
- -- Before we do anything else, a specialized test for the case of
- -- a size given for an array where the array needs to be packed,
- -- but was not so the size cannot be honored. This is the case
- -- where implicit packing may apply. The reason we do this so
- -- early is that if we have implicit packing, the layout of the
- -- base type is affected, so we must do this before we freeze
- -- the base type.
+ -- Before we do anything else, a specific test for the case of a
+ -- size given for an array where the array would need to be packed
+ -- in order for the size to be honored, but is not. This is the
+ -- case where implicit packing may apply. The reason we do this so
+ -- early is that, if we have implicit packing, the layout of the
+ -- base type is affected, so we must do this before we freeze the
+ -- base type.
-- We could do this processing only if implicit packing is enabled
-- since in all other cases, the error would be caught by the back
-- end. However, we choose to do the check even if we do not have
-- implicit packing enabled, since this allows us to give a more
- -- useful error message (advising use of pragmas Implicit_Packing
- -- or Pack).
+ -- useful error message (advising use of pragma Implicit_Packing
+ -- or pragma Pack).
if Is_Array_Type (E) then
declare
@@ -5326,7 +5343,8 @@ package body Freeze is
Hi : Node_Id;
Indx : Node_Id;
- Num_Elmts : Uint;
+ Dim : Uint;
+ Num_Elmts : Uint := Uint_1;
-- Number of elements in array
begin
@@ -5342,13 +5360,21 @@ package body Freeze is
-- a chance to freeze the base type (and it is that freeze
-- action that causes stuff to be inherited).
+ -- The conditions on the size are identical to those used in
+ -- Freeze_Array_Type to set the Is_Packed flag.
+
if Has_Size_Clause (E)
and then Known_Static_RM_Size (E)
and then not Is_Packed (E)
and then not Has_Pragma_Pack (E)
and then not Has_Component_Size_Clause (E)
and then Known_Static_RM_Size (Ctyp)
- and then RM_Size (Ctyp) < 64
+ and then Rsiz <= 64
+ and then not (Addressable (Rsiz)
+ and then Known_Static_Esize (Ctyp)
+ and then Esize (Ctyp) = Rsiz)
+ and then not (Rsiz mod System_Storage_Unit = 0
+ and then Is_Composite_Type (Ctyp))
and then not Is_Limited_Composite (E)
and then not Is_Packed (Root_Type (E))
and then not Has_Component_Size_Clause (Root_Type (E))
@@ -5356,7 +5382,6 @@ package body Freeze is
then
-- Compute number of elements in array
- Num_Elmts := Uint_1;
Indx := First_Index (E);
while Present (Indx) loop
Get_Index_Bounds (Indx, Lo, Hi);
@@ -5368,33 +5393,28 @@ package body Freeze is
goto No_Implicit_Packing;
end if;
- Num_Elmts :=
- Num_Elmts *
- UI_Max (Uint_0,
- Expr_Value (Hi) - Expr_Value (Lo) + 1);
+ Dim := Expr_Value (Hi) - Expr_Value (Lo) + 1;
+
+ if Dim >= 0 then
+ Num_Elmts := Num_Elmts * Dim;
+ else
+ Num_Elmts := Uint_0;
+ end if;
+
Next_Index (Indx);
end loop;
-- What we are looking for here is the situation where
-- the RM_Size given would be exactly right if there was
- -- a pragma Pack (resulting in the component size being
- -- the same as the RM_Size). Furthermore, the component
- -- type size must be an odd size (not a multiple of
- -- storage unit). If the component RM size is an exact
- -- number of storage units that is a power of two, the
- -- array is not packed and has a standard representation.
-
- if RM_Size (E) = Num_Elmts * Rsiz
- and then Rsiz mod System_Storage_Unit /= 0
- then
+ -- a pragma Pack, resulting in the component size being
+ -- the RM_Size of the component type.
+
+ if RM_Size (E) = Num_Elmts * Rsiz then
-- For implicit packing mode, just set the component
- -- size silently.
+ -- size and Freeze_Array_Type will do the rest.
if Implicit_Packing then
- Set_Component_Size (Btyp, Rsiz);
- Set_Is_Bit_Packed_Array (Btyp);
- Set_Is_Packed (Btyp);
- Set_Has_Non_Standard_Rep (Btyp);
+ Set_Component_Size (Btyp, Rsiz);
-- Otherwise give an error message
@@ -5405,20 +5425,6 @@ package body Freeze is
("\use explicit pragma Pack "
& "or use pragma Implicit_Packing", SZ);
end if;
-
- elsif RM_Size (E) = Num_Elmts * Rsiz
- and then Implicit_Packing
- and then
- (Rsiz / System_Storage_Unit = 1
- or else
- Rsiz / System_Storage_Unit = 2
- or else
- Rsiz / System_Storage_Unit = 4)
- then
- -- Not a packed array, but indicate the desired
- -- component size, for the back-end.
-
- Set_Component_Size (Btyp, Rsiz);
end if;
end if;
end;
diff --git a/gcc/ada/freeze.ads b/gcc/ada/freeze.ads
index 81f2e0001ba..079d7132abe 100644
--- a/gcc/ada/freeze.ads
+++ b/gcc/ada/freeze.ads
@@ -151,15 +151,15 @@ package Freeze is
-- fact Gigi decides it is known, but the opposite situation can never
-- occur.
--
- -- Size is known at compile time, but the actual value of the size is
- -- not known to the front end or is definitely 32 or more. In this case
- -- Size_Known_At_Compile_Time is set, but the Esize field is left set
+ -- Size is known at compile time, but the actual value of the size is not
+ -- known to the front end or is definitely greater than 64. In this case,
+ -- Size_Known_At_Compile_Time is set, but the RM_Size field is left set
-- to zero (to be set by Gigi).
--
-- Size is known at compile time, and the actual value of the size is
- -- known to the front end and is less than 32. In this case, the flag
- -- Size_Known_At_Compile_Time is set, and in addition Esize is set to
- -- the required size, allowing for possible front end packing of an
+ -- known to the front end and is not greater than 64. In this case, the
+ -- flag Size_Known_At_Compile_Time is set, and in addition RM_Size is set
+ -- to the required size, allowing for possible front end packing of an
-- array using this type as a component type.
--
-- Note: the flag Size_Known_At_Compile_Time is used to determine if the
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index fbfa6c62ea5..47a92687f76 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -175,10 +175,10 @@ else
# or a cross-native compiler. We provide defaults for tools targeting the
# host platform, but they can be overriden by just setting <tool>_FOR_HOST
# variables.
- GNATMAKE_FOR_HOST=$(host)-gnatmake
- GNATBIND_FOR_HOST=$(host)-gnatbind
- GNATLINK_FOR_HOST=$(host)-gnatlink
- GNATLS_FOR_HOST=$(host)-gnatls
+ GNATMAKE_FOR_HOST=$(host_noncanonical)-gnatmake
+ GNATBIND_FOR_HOST=$(host_noncanonical)-gnatbind
+ GNATLINK_FOR_HOST=$(host_noncanonical)-gnatlink
+ GNATLS_FOR_HOST=$(host_noncanonical)-gnatls
ifeq ($(host), $(target))
# This is a cross native. All the sources are taken from the currently
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index f3d2b52671d..6b6bc07684d 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -1437,9 +1437,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
= build_reference_type (TYPE_OBJECT_RECORD_TYPE (gnu_array));
}
- if (const_flag)
- gnu_type = change_qualified_type (gnu_type, TYPE_QUAL_CONST);
-
/* Convert the expression to the type of the object if need be. */
if (gnu_expr && initial_value_needs_conversion (gnu_type, gnu_expr))
gnu_expr = convert (gnu_type, gnu_expr);
@@ -1817,7 +1814,12 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* First subtypes of Character are treated as Character; otherwise
this should be an unsigned type if the base type is unsigned or
if the lower bound is constant and non-negative or if the type
- is biased. */
+ is biased. However, even if the lower bound is constant and
+ non-negative, we use a signed type for a subtype with the same
+ size as its signed base type, because this eliminates useless
+ conversions to it and gives more leeway to the optimizer; but
+ this means that we will need to explicitly test for this case
+ when we change the representation based on the RM size. */
if (kind == E_Enumeration_Subtype
&& No (First_Literal (Etype (gnat_entity)))
&& Esize (gnat_entity) == RM_Size (gnat_entity)
@@ -1825,7 +1827,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
&& flag_signed_char)
gnu_type = make_signed_type (CHAR_TYPE_SIZE);
else if (Is_Unsigned_Type (Etype (gnat_entity))
- || Is_Unsigned_Type (gnat_entity)
+ || (Esize (Etype (gnat_entity)) != Esize (gnat_entity)
+ && Is_Unsigned_Type (gnat_entity))
|| Has_Biased_Representation (gnat_entity))
gnu_type = make_unsigned_type (esize);
else
@@ -1961,47 +1964,20 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
/* If the type we are dealing with has got a smaller alignment than the
natural one, we need to wrap it up in a record type and misalign the
- latter; we reuse the padding machinery for this purpose. Note that,
- even if the record type is marked as packed because of misalignment,
- we don't pack the field so as to give it the size of the type. */
+ latter; we reuse the padding machinery for this purpose. */
else if (align > 0)
{
- tree gnu_field_type, gnu_field;
-
- /* Set the RM size before wrapping up the type. */
- SET_TYPE_RM_SIZE (gnu_type,
- UI_To_gnu (RM_Size (gnat_entity), bitsizetype));
+ tree gnu_size = UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
- /* Create a stripped-down declaration, mainly for debugging. */
- create_type_decl (gnu_entity_name, gnu_type, true, debug_info_p,
- gnat_entity);
+ /* Set the RM size before wrapping the type. */
+ SET_TYPE_RM_SIZE (gnu_type, gnu_size);
- /* Now save it and build the enclosing record type. */
- gnu_field_type = gnu_type;
+ gnu_type
+ = maybe_pad_type (gnu_type, TYPE_SIZE (gnu_type), align,
+ gnat_entity, false, true, definition, false);
- gnu_type = make_node (RECORD_TYPE);
- TYPE_PADDING_P (gnu_type) = 1;
- TYPE_NAME (gnu_type) = create_concat_name (gnat_entity, "PAD");
TYPE_PACKED (gnu_type) = 1;
- TYPE_SIZE (gnu_type) = TYPE_SIZE (gnu_field_type);
- TYPE_SIZE_UNIT (gnu_type) = TYPE_SIZE_UNIT (gnu_field_type);
- SET_TYPE_ADA_SIZE (gnu_type, TYPE_RM_SIZE (gnu_field_type));
- SET_TYPE_ALIGN (gnu_type, align);
- relate_alias_sets (gnu_type, gnu_field_type, ALIAS_SET_COPY);
-
- /* Don't declare the field as addressable since we won't be taking
- its address and this would prevent create_field_decl from making
- a bitfield. */
- gnu_field
- = create_field_decl (get_identifier ("F"), gnu_field_type,
- gnu_type, TYPE_SIZE (gnu_field_type),
- bitsize_zero_node, 0, 0);
-
- finish_record_type (gnu_type, gnu_field, 2, false);
- compute_record_mode (gnu_type);
-
- if (gnat_encodings == DWARF_GNAT_ENCODINGS_MINIMAL)
- SET_TYPE_DEBUG_TYPE (gnu_type, gnu_field_type);
+ SET_TYPE_ADA_SIZE (gnu_type, gnu_size);
}
break;
@@ -2909,10 +2885,6 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, bool definition)
TREE_TYPE (TYPE_FIELDS (gnu_type)) = gnu_inner;
}
}
-
- else
- /* Abort if packed array with no Packed_Array_Impl_Type. */
- gcc_assert (!Is_Packed (gnat_entity));
}
break;
@@ -5234,6 +5206,16 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
const Entity_Id gnat_type = Component_Type (gnat_array);
tree gnu_type = gnat_to_gnu_type (gnat_type);
tree gnu_comp_size;
+ unsigned int max_align;
+
+ /* If an alignment is specified, use it as a cap on the component type
+ so that it can be honored for the whole type. But ignore it for the
+ original type of packed array types. */
+ if (No (Packed_Array_Impl_Type (gnat_array))
+ && Known_Alignment (gnat_array))
+ max_align = validate_alignment (Alignment (gnat_array), gnat_array, 0);
+ else
+ max_align = 0;
/* Try to get a smaller form of the component if needed. */
if ((Is_Packed (gnat_array) || Has_Component_Size_Clause (gnat_array))
@@ -5243,7 +5225,7 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
&& RECORD_OR_UNION_TYPE_P (gnu_type)
&& !TYPE_FAT_POINTER_P (gnu_type)
&& tree_fits_uhwi_p (TYPE_SIZE (gnu_type)))
- gnu_type = make_packable_type (gnu_type, false);
+ gnu_type = make_packable_type (gnu_type, false, max_align);
if (Has_Atomic_Components (gnat_array))
check_ok_for_atomic_type (gnu_type, gnat_array, true);
@@ -5276,16 +5258,6 @@ gnat_to_gnu_component_type (Entity_Id gnat_array, bool definition,
if (gnu_comp_size && !Is_Bit_Packed_Array (gnat_array))
{
tree orig_type = gnu_type;
- unsigned int max_align;
-
- /* If an alignment is specified, use it as a cap on the component type
- so that it can be honored for the whole type. But ignore it for the
- original type of packed array types. */
- if (No (Packed_Array_Impl_Type (gnat_array))
- && Known_Alignment (gnat_array))
- max_align = validate_alignment (Alignment (gnat_array), gnat_array, 0);
- else
- max_align = 0;
gnu_type = make_type_from_size (gnu_type, gnu_comp_size, false);
if (max_align > 0 && TYPE_ALIGN (gnu_type) > max_align)
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index 9cc744b24f2..099923d97fb 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -129,9 +129,11 @@ extern tree make_aligning_type (tree type, unsigned int align, tree size,
as the field type of a packed record if IN_RECORD is true, or as the
component type of a packed array if IN_RECORD is false. See if we can
rewrite it either as a type that has a non-BLKmode, which we can pack
- tighter in the packed record case, or as a smaller type. If so, return
- the new type. If not, return the original type. */
-extern tree make_packable_type (tree type, bool in_record);
+ tighter in the packed record case, or as a smaller type with at most
+ MAX_ALIGN alignment if the value is non-zero. If so, return the new
+ type; if not, return the original type. */
+extern tree make_packable_type (tree type, bool in_record,
+ unsigned int max_align = 0);
/* Given a type TYPE, return a new type whose size is appropriate for SIZE.
If TYPE is the best type, return it. Otherwise, make a new type. We
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index 4febc04264b..8cf4cea564c 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -8446,6 +8446,10 @@ elaborate_all_entities_for_package (Entity_Id gnat_package)
if (IN (kind, Generic_Unit_Kind))
continue;
+ /* Skip formal objects. */
+ if (IN (kind, Formal_Object_Kind))
+ continue;
+
/* Skip package bodies. */
if (kind == E_Package_Body)
continue;
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 8c36149a18c..798048a903d 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -937,23 +937,24 @@ make_aligning_type (tree type, unsigned int align, tree size,
/* TYPE is a RECORD_TYPE, UNION_TYPE or QUAL_UNION_TYPE that is being used
as the field type of a packed record if IN_RECORD is true, or as the
component type of a packed array if IN_RECORD is false. See if we can
- rewrite it either as a type that has a non-BLKmode, which we can pack
- tighter in the packed record case, or as a smaller type. If so, return
- the new type. If not, return the original type. */
+ rewrite it either as a type that has non-BLKmode, which we can pack
+ tighter in the packed record case, or as a smaller type with at most
+ MAX_ALIGN alignment if the value is non-zero. If so, return the new
+ type; if not, return the original type. */
tree
-make_packable_type (tree type, bool in_record)
+make_packable_type (tree type, bool in_record, unsigned int max_align)
{
unsigned HOST_WIDE_INT size = tree_to_uhwi (TYPE_SIZE (type));
unsigned HOST_WIDE_INT new_size;
- tree new_type, old_field, field_list = NULL_TREE;
- unsigned int align;
+ unsigned int align = TYPE_ALIGN (type);
+ unsigned int new_align;
/* No point in doing anything if the size is zero. */
if (size == 0)
return type;
- new_type = make_node (TREE_CODE (type));
+ tree new_type = make_node (TREE_CODE (type));
/* Copy the name and flags from the old type to that of the new.
Note that we rely on the pointer equality created here for
@@ -970,49 +971,50 @@ make_packable_type (tree type, bool in_record)
type with BLKmode. */
if (in_record && size <= MAX_FIXED_MODE_SIZE)
{
- align = ceil_pow2 (size);
- SET_TYPE_ALIGN (new_type, align);
- new_size = (size + align - 1) & -align;
+ new_size = ceil_pow2 (size);
+ new_align = MIN (new_size, BIGGEST_ALIGNMENT);
+ SET_TYPE_ALIGN (new_type, new_align);
}
else
{
- unsigned HOST_WIDE_INT align;
-
/* Do not try to shrink the size if the RM size is not constant. */
if (TYPE_CONTAINS_TEMPLATE_P (type)
|| !tree_fits_uhwi_p (TYPE_ADA_SIZE (type)))
return type;
/* Round the RM size up to a unit boundary to get the minimal size
- for a BLKmode record. Give up if it's already the size. */
+ for a BLKmode record. Give up if it's already the size and we
+ don't need to lower the alignment. */
new_size = tree_to_uhwi (TYPE_ADA_SIZE (type));
new_size = (new_size + BITS_PER_UNIT - 1) & -BITS_PER_UNIT;
- if (new_size == size)
+ if (new_size == size && (max_align == 0 || align <= max_align))
return type;
- align = new_size & -new_size;
- SET_TYPE_ALIGN (new_type, MIN (TYPE_ALIGN (type), align));
+ new_align = MIN (new_size & -new_size, BIGGEST_ALIGNMENT);
+ if (max_align > 0 && new_align > max_align)
+ new_align = max_align;
+ SET_TYPE_ALIGN (new_type, MIN (align, new_align));
}
TYPE_USER_ALIGN (new_type) = 1;
/* Now copy the fields, keeping the position and size as we don't want
to change the layout by propagating the packedness downwards. */
- for (old_field = TYPE_FIELDS (type); old_field;
- old_field = DECL_CHAIN (old_field))
+ tree new_field_list = NULL_TREE;
+ for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field))
{
- tree new_field_type = TREE_TYPE (old_field);
+ tree new_field_type = TREE_TYPE (field);
tree new_field, new_size;
if (RECORD_OR_UNION_TYPE_P (new_field_type)
&& !TYPE_FAT_POINTER_P (new_field_type)
&& tree_fits_uhwi_p (TYPE_SIZE (new_field_type)))
- new_field_type = make_packable_type (new_field_type, true);
+ new_field_type = make_packable_type (new_field_type, true, max_align);
/* However, for the last field in a not already packed record type
that is of an aggregate type, we need to use the RM size in the
packable version of the record type, see finish_record_type. */
- if (!DECL_CHAIN (old_field)
+ if (!DECL_CHAIN (field)
&& !TYPE_PACKED (type)
&& RECORD_OR_UNION_TYPE_P (new_field_type)
&& !TYPE_FAT_POINTER_P (new_field_type)
@@ -1020,24 +1022,24 @@ make_packable_type (tree type, bool in_record)
&& TYPE_ADA_SIZE (new_field_type))
new_size = TYPE_ADA_SIZE (new_field_type);
else
- new_size = DECL_SIZE (old_field);
+ new_size = DECL_SIZE (field);
new_field
- = create_field_decl (DECL_NAME (old_field), new_field_type, new_type,
- new_size, bit_position (old_field),
+ = create_field_decl (DECL_NAME (field), new_field_type, new_type,
+ new_size, bit_position (field),
TYPE_PACKED (type),
- !DECL_NONADDRESSABLE_P (old_field));
+ !DECL_NONADDRESSABLE_P (field));
- DECL_INTERNAL_P (new_field) = DECL_INTERNAL_P (old_field);
- SET_DECL_ORIGINAL_FIELD_TO_FIELD (new_field, old_field);
+ DECL_INTERNAL_P (new_field) = DECL_INTERNAL_P (field);
+ SET_DECL_ORIGINAL_FIELD_TO_FIELD (new_field, field);
if (TREE_CODE (new_type) == QUAL_UNION_TYPE)
- DECL_QUALIFIER (new_field) = DECL_QUALIFIER (old_field);
+ DECL_QUALIFIER (new_field) = DECL_QUALIFIER (field);
- DECL_CHAIN (new_field) = field_list;
- field_list = new_field;
+ DECL_CHAIN (new_field) = new_field_list;
+ new_field_list = new_field;
}
- finish_record_type (new_type, nreverse (field_list), 2, false);
+ finish_record_type (new_type, nreverse (new_field_list), 2, false);
relate_alias_sets (new_type, type, ALIAS_SET_COPY);
if (TYPE_STUB_DECL (type))
SET_DECL_PARALLEL_TYPE (TYPE_STUB_DECL (new_type),
@@ -1054,8 +1056,7 @@ make_packable_type (tree type, bool in_record)
else
{
TYPE_SIZE (new_type) = bitsize_int (new_size);
- TYPE_SIZE_UNIT (new_type)
- = size_int ((new_size + BITS_PER_UNIT - 1) / BITS_PER_UNIT);
+ TYPE_SIZE_UNIT (new_type) = size_int (new_size / BITS_PER_UNIT);
}
if (!TYPE_CONTAINS_TEMPLATE_P (type))
@@ -1069,8 +1070,8 @@ make_packable_type (tree type, bool in_record)
SET_TYPE_MODE (new_type,
mode_for_size_tree (TYPE_SIZE (new_type), MODE_INT, 1));
- /* If neither the mode nor the size has shrunk, return the old type. */
- if (TYPE_MODE (new_type) == BLKmode && new_size >= size)
+ /* If neither mode nor size nor alignment shrunk, return the old type. */
+ if (TYPE_MODE (new_type) == BLKmode && new_size >= size && max_align == 0)
return type;
return new_type;
@@ -1115,7 +1116,14 @@ make_type_from_size (tree type, tree size_tree, bool for_biased)
break;
biased_p |= for_biased;
- if (TYPE_UNSIGNED (type) || biased_p)
+
+ /* The type should be an unsigned type if the original type is unsigned
+ or if the lower bound is constant and non-negative or if the type is
+ biased, see E_Signed_Integer_Subtype case of gnat_to_gnu_entity. */
+ if (TYPE_UNSIGNED (type)
+ || (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
+ && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0)
+ || biased_p)
new_type = make_unsigned_type (size);
else
new_type = make_signed_type (size);
@@ -5110,7 +5118,9 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
/* If the result is an integral type whose precision is not equal to its
size, sign- or zero-extend the result. We need not do this if the input
is an integral type of the same precision and signedness or if the output
- is a biased type or if both the input and output are unsigned. */
+ is a biased type or if both the input and output are unsigned, or if the
+ lower bound is constant and non-negative, see E_Signed_Integer_Subtype
+ case of gnat_to_gnu_entity. */
if (!notrunc_p
&& INTEGRAL_TYPE_P (type)
&& TYPE_RM_SIZE (type)
@@ -5122,7 +5132,10 @@ unchecked_convert (tree type, tree expr, bool notrunc_p)
? TYPE_RM_SIZE (etype)
: TYPE_SIZE (etype)) == 0)
&& !(code == INTEGER_TYPE && TYPE_BIASED_REPRESENTATION_P (type))
- && !(TYPE_UNSIGNED (type) && TYPE_UNSIGNED (etype)))
+ && !((TYPE_UNSIGNED (type)
+ || (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST
+ && tree_int_cst_sgn (TYPE_MIN_VALUE (type)) >= 0))
+ && TYPE_UNSIGNED (etype)))
{
tree base_type
= gnat_type_for_size (TREE_INT_CST_LOW (TYPE_SIZE (type)),
diff --git a/gcc/ada/s-osinte-gnu.ads b/gcc/ada/s-osinte-gnu.ads
index 6cac9b9b880..183c5b83f60 100644
--- a/gcc/ada/s-osinte-gnu.ads
+++ b/gcc/ada/s-osinte-gnu.ads
@@ -344,10 +344,9 @@ package System.OS_Interface is
-- returns the stack base of the specified thread. Only call this function
-- when Stack_Base_Available is True.
- -- From: /usr/include/i386-gnu/bits/shm.h __getpagesize or getpagesize??
- function Get_Page_Size return size_t;
- function Get_Page_Size return Address;
- pragma Import (C, Get_Page_Size, "__getpagesize");
+ -- From: /usr/include/i386-gnu/bits/shm.h
+ function Get_Page_Size return int;
+ pragma Import (C, Get_Page_Size, "getpagesize");
-- Returns the size of a page
-- From /usr/include/i386-gnu/bits/mman.h
diff --git a/gcc/ada/system-darwin-ppc64.ads b/gcc/ada/system-darwin-ppc64.ads
index ae36136adfa..29cc18726ea 100644
--- a/gcc/ada/system-darwin-ppc64.ads
+++ b/gcc/ada/system-darwin-ppc64.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- (Darwin/PPC64 Version) --
-- --
--- Copyright (C) 2011-2015, Free Software Foundation, Inc. --
+-- Copyright (C) 2011-2016, Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -40,6 +40,9 @@ package System is
-- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-- 2005, this is Pure in any case (AI-362).
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
type Name is (SYSTEM_NAME_GNAT);
System_Name : constant Name := SYSTEM_NAME_GNAT;
diff --git a/gcc/ada/system-linux-armeb.ads b/gcc/ada/system-linux-armeb.ads
index 355108f2e7f..e855eb20cf3 100644
--- a/gcc/ada/system-linux-armeb.ads
+++ b/gcc/ada/system-linux-armeb.ads
@@ -40,6 +40,9 @@ package System is
-- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-- 2005, this is Pure in any case (AI-362).
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
type Name is (SYSTEM_NAME_GNAT);
System_Name : constant Name := SYSTEM_NAME_GNAT;
diff --git a/gcc/ada/system-linux-mips.ads b/gcc/ada/system-linux-mips.ads
index 3893cd9acf9..d5dc2cd2897 100644
--- a/gcc/ada/system-linux-mips.ads
+++ b/gcc/ada/system-linux-mips.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- (GNU-Linux/MIPS Version) --
-- --
--- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -40,6 +40,9 @@ package System is
-- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-- 2005, this is Pure in any case (AI-362).
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
type Name is (SYSTEM_NAME_GNAT);
System_Name : constant Name := SYSTEM_NAME_GNAT;
diff --git a/gcc/ada/system-linux-mips64el.ads b/gcc/ada/system-linux-mips64el.ads
index 76db8484b46..995fb8161e8 100644
--- a/gcc/ada/system-linux-mips64el.ads
+++ b/gcc/ada/system-linux-mips64el.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- (GNU-Linux/MIPS64EL Version) --
-- --
--- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -40,6 +40,9 @@ package System is
-- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-- 2005, this is Pure in any case (AI-362).
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
type Name is (SYSTEM_NAME_GNAT);
System_Name : constant Name := SYSTEM_NAME_GNAT;
diff --git a/gcc/ada/system-linux-mipsel.ads b/gcc/ada/system-linux-mipsel.ads
index f4dc9bc204d..405ab7a0f95 100644
--- a/gcc/ada/system-linux-mipsel.ads
+++ b/gcc/ada/system-linux-mipsel.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- (GNU-Linux/MIPSEL Version) --
-- --
--- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -40,6 +40,9 @@ package System is
-- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-- 2005, this is Pure in any case (AI-362).
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
type Name is (SYSTEM_NAME_GNAT);
System_Name : constant Name := SYSTEM_NAME_GNAT;
diff --git a/gcc/ada/system-linux-ppc64.ads b/gcc/ada/system-linux-ppc64.ads
index c6905316419..5bb306f8618 100644
--- a/gcc/ada/system-linux-ppc64.ads
+++ b/gcc/ada/system-linux-ppc64.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- (GNU-Linux/PPC64 Version) --
-- --
--- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -40,6 +40,9 @@ package System is
-- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-- 2005, this is Pure in any case (AI-362).
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
type Name is (SYSTEM_NAME_GNAT);
System_Name : constant Name := SYSTEM_NAME_GNAT;
diff --git a/gcc/ada/system-linux-sparcv9.ads b/gcc/ada/system-linux-sparcv9.ads
index 406fa046f2a..e4d11560d20 100644
--- a/gcc/ada/system-linux-sparcv9.ads
+++ b/gcc/ada/system-linux-sparcv9.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- (GNU/Linux-SPARCV9 Version) --
-- --
--- Copyright (C) 1992-2015, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2016, Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -40,6 +40,9 @@ package System is
-- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-- 2005, this is Pure in any case (AI-362).
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
type Name is (SYSTEM_NAME_GNAT);
System_Name : constant Name := SYSTEM_NAME_GNAT;
diff --git a/gcc/ada/system-rtems.ads b/gcc/ada/system-rtems.ads
index e4daf6bf0ad..664c228038e 100644
--- a/gcc/ada/system-rtems.ads
+++ b/gcc/ada/system-rtems.ads
@@ -7,7 +7,7 @@
-- S p e c --
-- (Compiler Version) --
-- --
--- Copyright (C) 1992-2015 Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2016 Free Software Foundation, Inc. --
-- --
-- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow --
@@ -44,6 +44,9 @@ package System is
-- this unit Pure instead of Preelaborable; see RM 13.7.1(15). In Ada
-- 2005, this is Pure in any case (AI-362).
+ pragma No_Elaboration_Code_All;
+ -- Allow the use of that restriction in units that WITH this unit
+
type Name is (SYSTEM_NAME_GNAT);
System_Name : constant Name := SYSTEM_NAME_GNAT;
diff --git a/gcc/alias.c b/gcc/alias.c
index 451f8f3dee5..1e4c4d19e69 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -769,6 +769,10 @@ reference_alias_ptr_type_1 (tree *t)
tree
reference_alias_ptr_type (tree t)
{
+ /* If the frontend assigns this alias-set zero, preserve that. */
+ if (lang_hooks.get_alias_set (t) == 0)
+ return ptr_type_node;
+
tree ptype = reference_alias_ptr_type_1 (&t);
/* If there is a given pointer type for aliasing purposes, return it. */
if (ptype != NULL_TREE)
diff --git a/gcc/bitmap.c b/gcc/bitmap.c
index 0c05512b666..010cf752d76 100644
--- a/gcc/bitmap.c
+++ b/gcc/bitmap.c
@@ -556,7 +556,7 @@ bitmap_find_bit (bitmap head, unsigned int bit)
want, the one we want doesn't exist. */
head->current = element;
head->indx = element->indx;
- if (element != 0 && element->indx != indx)
+ if (element->indx != indx)
element = 0;
return element;
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 3d89bafe34a..931d4a6b7bc 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -3757,20 +3757,7 @@ expand_builtin_memcmp (tree exp, rtx target)
return convert_to_mode (mode, result, 0);
}
- result = target;
- if (! (result != 0
- && REG_P (result) && GET_MODE (result) == mode
- && REGNO (result) >= FIRST_PSEUDO_REGISTER))
- result = gen_reg_rtx (mode);
-
- emit_library_call_value (memcmp_libfunc, result, LCT_PURE,
- TYPE_MODE (integer_type_node), 3,
- XEXP (arg1_rtx, 0), Pmode,
- XEXP (arg2_rtx, 0), Pmode,
- convert_to_mode (TYPE_MODE (sizetype), arg3_rtx,
- TYPE_UNSIGNED (sizetype)),
- TYPE_MODE (sizetype));
- return result;
+ return NULL_RTX;
}
/* Expand expression EXP, which is a call to the strcmp builtin. Return NULL_RTX
@@ -4455,7 +4442,12 @@ expand_builtin_trap (void)
add_reg_note (insn, REG_ARGS_SIZE, GEN_INT (stack_pointer_delta));
}
else
- emit_library_call (abort_libfunc, LCT_NORETURN, VOIDmode, 0);
+ {
+ tree fn = builtin_decl_implicit (BUILT_IN_ABORT);
+ tree call_expr = build_call_expr (fn, 0);
+ expand_call (call_expr, NULL_RTX, false);
+ }
+
emit_barrier ();
}
@@ -5310,6 +5302,90 @@ expand_builtin_atomic_fetch_op (machine_mode mode, tree exp, rtx target,
return ret;
}
+/* Expand IFN_ATOMIC_BIT_TEST_AND_* internal function. */
+
+void
+expand_ifn_atomic_bit_test_and (gcall *call)
+{
+ tree ptr = gimple_call_arg (call, 0);
+ tree bit = gimple_call_arg (call, 1);
+ tree flag = gimple_call_arg (call, 2);
+ tree lhs = gimple_call_lhs (call);
+ enum memmodel model = MEMMODEL_SYNC_SEQ_CST;
+ machine_mode mode = TYPE_MODE (TREE_TYPE (flag));
+ enum rtx_code code;
+ optab optab;
+ struct expand_operand ops[5];
+
+ gcc_assert (flag_inline_atomics);
+
+ if (gimple_call_num_args (call) == 4)
+ model = get_memmodel (gimple_call_arg (call, 3));
+
+ rtx mem = get_builtin_sync_mem (ptr, mode);
+ rtx val = expand_expr_force_mode (bit, mode);
+
+ switch (gimple_call_internal_fn (call))
+ {
+ case IFN_ATOMIC_BIT_TEST_AND_SET:
+ code = IOR;
+ optab = atomic_bit_test_and_set_optab;
+ break;
+ case IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT:
+ code = XOR;
+ optab = atomic_bit_test_and_complement_optab;
+ break;
+ case IFN_ATOMIC_BIT_TEST_AND_RESET:
+ code = AND;
+ optab = atomic_bit_test_and_reset_optab;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ if (lhs == NULL_TREE)
+ {
+ val = expand_simple_binop (mode, ASHIFT, const1_rtx,
+ val, NULL_RTX, true, OPTAB_DIRECT);
+ if (code == AND)
+ val = expand_simple_unop (mode, NOT, val, NULL_RTX, true);
+ expand_atomic_fetch_op (const0_rtx, mem, val, code, model, false);
+ return;
+ }
+
+ rtx target = expand_expr (lhs, NULL_RTX, VOIDmode, EXPAND_WRITE);
+ enum insn_code icode = direct_optab_handler (optab, mode);
+ gcc_assert (icode != CODE_FOR_nothing);
+ create_output_operand (&ops[0], target, mode);
+ create_fixed_operand (&ops[1], mem);
+ create_convert_operand_to (&ops[2], val, mode, true);
+ create_integer_operand (&ops[3], model);
+ create_integer_operand (&ops[4], integer_onep (flag));
+ if (maybe_expand_insn (icode, 5, ops))
+ return;
+
+ rtx bitval = val;
+ val = expand_simple_binop (mode, ASHIFT, const1_rtx,
+ val, NULL_RTX, true, OPTAB_DIRECT);
+ rtx maskval = val;
+ if (code == AND)
+ val = expand_simple_unop (mode, NOT, val, NULL_RTX, true);
+ rtx result = expand_atomic_fetch_op (gen_reg_rtx (mode), mem, val,
+ code, model, false);
+ if (integer_onep (flag))
+ {
+ result = expand_simple_binop (mode, ASHIFTRT, result, bitval,
+ NULL_RTX, true, OPTAB_DIRECT);
+ result = expand_simple_binop (mode, AND, result, const1_rtx, target,
+ true, OPTAB_DIRECT);
+ }
+ else
+ result = expand_simple_binop (mode, AND, result, maskval, target, true,
+ OPTAB_DIRECT);
+ if (result != target)
+ emit_move_insn (target, result);
+}
+
/* Expand an atomic clear operation.
void _atomic_clear (BOOL *obj, enum memmodel)
EXP is the call expression. */
@@ -7927,6 +8003,39 @@ fold_builtin_arith_overflow (location_t loc, enum built_in_function fcode,
return build2_loc (loc, COMPOUND_EXPR, boolean_type_node, store, ovfres);
}
+/* Fold a call to __builtin_FILE to a constant string. */
+
+static inline tree
+fold_builtin_FILE (location_t loc)
+{
+ if (const char *fname = LOCATION_FILE (loc))
+ return build_string_literal (strlen (fname) + 1, fname);
+
+ return build_string_literal (1, "");
+}
+
+/* Fold a call to __builtin_FUNCTION to a constant string. */
+
+static inline tree
+fold_builtin_FUNCTION ()
+{
+ if (current_function_decl)
+ {
+ const char *name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
+ return build_string_literal (strlen (name) + 1, name);
+ }
+
+ return build_string_literal (1, "");
+}
+
+/* Fold a call to __builtin_LINE to an integer constant. */
+
+static inline tree
+fold_builtin_LINE (location_t loc, tree type)
+{
+ return build_int_cst (type, LOCATION_LINE (loc));
+}
+
/* Fold a call to built-in function FNDECL with 0 arguments.
This function returns NULL_TREE if no simplification was possible. */
@@ -7937,6 +8046,15 @@ fold_builtin_0 (location_t loc, tree fndecl)
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
switch (fcode)
{
+ case BUILT_IN_FILE:
+ return fold_builtin_FILE (loc);
+
+ case BUILT_IN_FUNCTION:
+ return fold_builtin_FUNCTION ();
+
+ case BUILT_IN_LINE:
+ return fold_builtin_LINE (loc, type);
+
CASE_FLT_FN (BUILT_IN_INF):
case BUILT_IN_INFD32:
case BUILT_IN_INFD64:
@@ -9762,42 +9880,19 @@ fold_call_stmt (gcall *stmt, bool ignore)
void
set_builtin_user_assembler_name (tree decl, const char *asmspec)
{
- tree builtin;
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
&& DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
&& asmspec != 0);
- builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
+ tree builtin = builtin_decl_explicit (DECL_FUNCTION_CODE (decl));
set_user_assembler_name (builtin, asmspec);
- switch (DECL_FUNCTION_CODE (decl))
+
+ if (DECL_FUNCTION_CODE (decl) == BUILT_IN_FFS
+ && INT_TYPE_SIZE < BITS_PER_WORD)
{
- case BUILT_IN_MEMCPY:
- init_block_move_fn (asmspec);
- memcpy_libfunc = set_user_assembler_libfunc ("memcpy", asmspec);
- break;
- case BUILT_IN_MEMSET:
- init_block_clear_fn (asmspec);
- memset_libfunc = set_user_assembler_libfunc ("memset", asmspec);
- break;
- case BUILT_IN_MEMMOVE:
- memmove_libfunc = set_user_assembler_libfunc ("memmove", asmspec);
- break;
- case BUILT_IN_MEMCMP:
- memcmp_libfunc = set_user_assembler_libfunc ("memcmp", asmspec);
- break;
- case BUILT_IN_ABORT:
- abort_libfunc = set_user_assembler_libfunc ("abort", asmspec);
- break;
- case BUILT_IN_FFS:
- if (INT_TYPE_SIZE < BITS_PER_WORD)
- {
- set_user_assembler_libfunc ("ffs", asmspec);
- set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE,
- MODE_INT, 0), "ffs");
- }
- break;
- default:
- break;
+ set_user_assembler_libfunc ("ffs", asmspec);
+ set_optab_libfunc (ffs_optab, mode_for_size (INT_TYPE_SIZE, MODE_INT, 0),
+ "ffs");
}
}
diff --git a/gcc/builtins.h b/gcc/builtins.h
index b49def349d0..51e298cb76b 100644
--- a/gcc/builtins.h
+++ b/gcc/builtins.h
@@ -71,6 +71,7 @@ extern tree std_fn_abi_va_list (tree);
extern tree std_canonical_va_list_type (tree);
extern void std_expand_builtin_va_start (tree, rtx);
extern void expand_builtin_trap (void);
+extern void expand_ifn_atomic_bit_test_and (gcall *);
extern rtx expand_builtin (tree, rtx, rtx, machine_mode, int);
extern rtx expand_builtin_with_bounds (tree, rtx, rtx, machine_mode, int);
extern enum built_in_function builtin_mathfn_code (const_tree);
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 49012e14307..f6ba9410200 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,46 @@
+2016-05-12 Marek Polacek <polacek@redhat.com>
+
+ PR c/70756
+ * c-common.c (pointer_int_sum): Call size_in_bytes_loc instead of
+ size_in_bytes and pass LOC to it.
+
+2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
+
+ PR c/43651
+ * c.opt (Wduplicate-decl-specifier): New option.
+
+2016-05-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/71024
+ * c-common.c (diagnose_mismatched_attributes): New function.
+ * c-common.h (diagnose_mismatched_attributes): Declare.
+
+2016-05-04 Marek Polacek <polacek@redhat.com>
+
+ * c.opt (Wdangling-else): New option.
+
+2016-05-03 Marek Polacek <polacek@redhat.com>
+
+ PR c/70859
+ * c-common.c (builtin_function_validate_nargs): Add location
+ parameter. Use it.
+ (check_builtin_function_arguments): Add location and arguments
+ parameters. Use them.
+ * c-common.h (check_builtin_function_arguments): Update declaration.
+
+2016-05-03 Richard Biener <rguenther@suse.de>
+
+ * cilk.c (cilk_gimplify_call_params_in_spawned_fn): Do not
+ allow call args to gimplify to SSA names.
+
+2016-05-03 Marek Polacek <polacek@redhat.com>
+
+ * c-common.h (enum c_omp_region_type): Remove stray comma.
+
+2016-05-02 Cesar Philippidis <cesar@codesourcery.com>
+
+ * c-common.h (enum c_omp_region_type): Define.
+
2016-05-02 Richard Sandiford <richard.sandiford@arm.com>
* c-common.c (shorten_compare): Use wi::to_wide.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d45bf1b67f6..146e8059c1a 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -4269,7 +4269,7 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
size_exp = integer_one_node;
}
else
- size_exp = size_in_bytes (TREE_TYPE (result_type));
+ size_exp = size_in_bytes_loc (loc, TREE_TYPE (result_type));
/* We are manipulating pointer values, so we don't need to warn
about relying on undefined signed overflow. We disable the
@@ -9797,31 +9797,39 @@ check_function_arguments_recurse (void (*callback)
/* Checks for a builtin function FNDECL that the number of arguments
NARGS against the required number REQUIRED and issues an error if
there is a mismatch. Returns true if the number of arguments is
- correct, otherwise false. */
+ correct, otherwise false. LOC is the location of FNDECL. */
static bool
-builtin_function_validate_nargs (tree fndecl, int nargs, int required)
+builtin_function_validate_nargs (location_t loc, tree fndecl, int nargs,
+ int required)
{
if (nargs < required)
{
- error_at (input_location,
- "not enough arguments to function %qE", fndecl);
+ error_at (loc, "not enough arguments to function %qE", fndecl);
return false;
}
else if (nargs > required)
{
- error_at (input_location,
- "too many arguments to function %qE", fndecl);
+ error_at (loc, "too many arguments to function %qE", fndecl);
return false;
}
return true;
}
+/* Helper macro for check_builtin_function_arguments. */
+#define ARG_LOCATION(N) \
+ (arg_loc.is_empty () \
+ ? EXPR_LOC_OR_LOC (args[(N)], input_location) \
+ : expansion_point_location (arg_loc[(N)]))
+
/* Verifies the NARGS arguments ARGS to the builtin function FNDECL.
- Returns false if there was an error, otherwise true. */
+ Returns false if there was an error, otherwise true. LOC is the
+ location of the function; ARG_LOC is a vector of locations of the
+ arguments. */
bool
-check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
+check_builtin_function_arguments (location_t loc, vec<location_t> arg_loc,
+ tree fndecl, int nargs, tree *args)
{
if (!DECL_BUILT_IN (fndecl)
|| DECL_BUILT_IN_CLASS (fndecl) != BUILT_IN_NORMAL)
@@ -9843,21 +9851,21 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
/* The maximum alignment in bits corresponding to the same
maximum in bytes enforced in check_user_alignment(). */
unsigned maxalign = (UINT_MAX >> 1) + 1;
-
+
/* Reject invalid alignments. */
if (align < BITS_PER_UNIT || maxalign < align)
{
- error_at (EXPR_LOC_OR_LOC (args[1], input_location),
+ error_at (ARG_LOCATION (1),
"second argument to function %qE must be a constant "
"integer power of 2 between %qi and %qu bits",
fndecl, BITS_PER_UNIT, maxalign);
return false;
}
- return true;
+ return true;
}
case BUILT_IN_CONSTANT_P:
- return builtin_function_validate_nargs (fndecl, nargs, 1);
+ return builtin_function_validate_nargs (loc, fndecl, nargs, 1);
case BUILT_IN_ISFINITE:
case BUILT_IN_ISINF:
@@ -9865,12 +9873,12 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
case BUILT_IN_ISNAN:
case BUILT_IN_ISNORMAL:
case BUILT_IN_SIGNBIT:
- if (builtin_function_validate_nargs (fndecl, nargs, 1))
+ if (builtin_function_validate_nargs (loc, fndecl, nargs, 1))
{
if (TREE_CODE (TREE_TYPE (args[0])) != REAL_TYPE)
{
- error ("non-floating-point argument in call to "
- "function %qE", fndecl);
+ error_at (ARG_LOCATION (0), "non-floating-point argument in "
+ "call to function %qE", fndecl);
return false;
}
return true;
@@ -9883,7 +9891,7 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
case BUILT_IN_ISLESSEQUAL:
case BUILT_IN_ISLESSGREATER:
case BUILT_IN_ISUNORDERED:
- if (builtin_function_validate_nargs (fndecl, nargs, 2))
+ if (builtin_function_validate_nargs (loc, fndecl, nargs, 2))
{
enum tree_code code0, code1;
code0 = TREE_CODE (TREE_TYPE (args[0]));
@@ -9892,8 +9900,8 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
|| (code0 == REAL_TYPE && code1 == INTEGER_TYPE)
|| (code0 == INTEGER_TYPE && code1 == REAL_TYPE)))
{
- error ("non-floating-point arguments in call to "
- "function %qE", fndecl);
+ error_at (loc, "non-floating-point arguments in call to "
+ "function %qE", fndecl);
return false;
}
return true;
@@ -9901,22 +9909,20 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
return false;
case BUILT_IN_FPCLASSIFY:
- if (builtin_function_validate_nargs (fndecl, nargs, 6))
+ if (builtin_function_validate_nargs (loc, fndecl, nargs, 6))
{
- unsigned i;
-
- for (i=0; i<5; i++)
+ for (unsigned int i = 0; i < 5; i++)
if (TREE_CODE (args[i]) != INTEGER_CST)
{
- error ("non-const integer argument %u in call to function %qE",
- i+1, fndecl);
+ error_at (ARG_LOCATION (i), "non-const integer argument %u in "
+ "call to function %qE", i + 1, fndecl);
return false;
}
if (TREE_CODE (TREE_TYPE (args[5])) != REAL_TYPE)
{
- error ("non-floating-point argument in call to function %qE",
- fndecl);
+ error_at (ARG_LOCATION (5), "non-floating-point argument in "
+ "call to function %qE", fndecl);
return false;
}
return true;
@@ -9924,11 +9930,12 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
return false;
case BUILT_IN_ASSUME_ALIGNED:
- if (builtin_function_validate_nargs (fndecl, nargs, 2 + (nargs > 2)))
+ if (builtin_function_validate_nargs (loc, fndecl, nargs, 2 + (nargs > 2)))
{
if (nargs >= 3 && TREE_CODE (TREE_TYPE (args[2])) != INTEGER_TYPE)
{
- error ("non-integer argument 3 in call to function %qE", fndecl);
+ error_at (ARG_LOCATION (2), "non-integer argument 3 in call to "
+ "function %qE", fndecl);
return false;
}
return true;
@@ -9938,21 +9945,21 @@ check_builtin_function_arguments (tree fndecl, int nargs, tree *args)
case BUILT_IN_ADD_OVERFLOW:
case BUILT_IN_SUB_OVERFLOW:
case BUILT_IN_MUL_OVERFLOW:
- if (builtin_function_validate_nargs (fndecl, nargs, 3))
+ if (builtin_function_validate_nargs (loc, fndecl, nargs, 3))
{
unsigned i;
for (i = 0; i < 2; i++)
if (!INTEGRAL_TYPE_P (TREE_TYPE (args[i])))
{
- error ("argument %u in call to function %qE does not have "
- "integral type", i + 1, fndecl);
+ error_at (ARG_LOCATION (i), "argument %u in call to function "
+ "%qE does not have integral type", i + 1, fndecl);
return false;
}
if (TREE_CODE (TREE_TYPE (args[2])) != POINTER_TYPE
|| TREE_CODE (TREE_TYPE (TREE_TYPE (args[2]))) != INTEGER_TYPE)
{
- error ("argument 3 in call to function %qE does not have "
- "pointer to integer type", fndecl);
+ error_at (ARG_LOCATION (2), "argument 3 in call to function %qE "
+ "does not have pointer to integer type", fndecl);
return false;
}
return true;
@@ -12817,4 +12824,58 @@ get_source_date_epoch ()
return (time_t) epoch;
}
+/* Check and possibly warn if two declarations have contradictory
+ attributes, such as always_inline vs. noinline. */
+
+bool
+diagnose_mismatched_attributes (tree olddecl, tree newdecl)
+{
+ bool warned = false;
+
+ tree a1 = lookup_attribute ("optimize", DECL_ATTRIBUTES (olddecl));
+ tree a2 = lookup_attribute ("optimize", DECL_ATTRIBUTES (newdecl));
+ /* An optimization attribute applied on a declaration after the
+ definition is likely not what the user wanted. */
+ if (a2 != NULL_TREE
+ && DECL_SAVED_TREE (olddecl) != NULL_TREE
+ && (a1 == NULL_TREE || !attribute_list_equal (a1, a2)))
+ warned |= warning (OPT_Wattributes,
+ "optimization attribute on %qD follows "
+ "definition but the attribute doesn%'t match",
+ newdecl);
+
+ /* Diagnose inline __attribute__ ((noinline)) which is silly. */
+ if (DECL_DECLARED_INLINE_P (newdecl)
+ && DECL_UNINLINABLE (olddecl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes, "inline declaration of %qD follows "
+ "declaration with attribute noinline", newdecl);
+ else if (DECL_DECLARED_INLINE_P (olddecl)
+ && DECL_UNINLINABLE (newdecl)
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
+ warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute "
+ "noinline follows inline declaration ", newdecl);
+ else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("always_inline", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute "
+ "%qs follows declaration with attribute %qs",
+ newdecl, "noinline", "always_inline");
+ else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute "
+ "%qs follows declaration with attribute %qs",
+ newdecl, "always_inline", "noinline");
+ else if (lookup_attribute ("cold", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("hot", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute "
+ "%qs follows declaration with attribute %qs",
+ newdecl, "cold", "hot");
+ else if (lookup_attribute ("hot", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("cold", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes, "declaration of %q+D with attribute "
+ "%qs follows declaration with attribute %qs",
+ newdecl, "hot", "cold");
+ return warned;
+}
+
#include "gt-c-family-c-common.h"
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index 99fa3ab2937..0ee9f567123 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -788,7 +788,8 @@ extern void check_function_arguments_recurse (void (*)
unsigned HOST_WIDE_INT),
void *, tree,
unsigned HOST_WIDE_INT);
-extern bool check_builtin_function_arguments (tree, int, tree *);
+extern bool check_builtin_function_arguments (location_t, vec<location_t>,
+ tree, int, tree *);
extern void check_function_format (tree, int, tree *);
extern tree handle_unused_attribute (tree *, tree, tree, int, bool *);
extern tree handle_format_attribute (tree *, tree, tree, int, bool *);
@@ -849,6 +850,7 @@ extern bool keyword_is_type_qualifier (enum rid);
extern bool keyword_is_decl_specifier (enum rid);
extern bool cxx_fundamental_alignment_p (unsigned);
extern bool pointer_to_zero_sized_aggr_p (tree);
+extern bool diagnose_mismatched_attributes (tree, tree);
#define c_sizeof(LOC, T) c_sizeof_or_alignof_type (LOC, T, true, false, 1)
#define c_alignof(LOC, T) c_sizeof_or_alignof_type (LOC, T, false, false, 1)
@@ -1261,6 +1263,15 @@ enum c_omp_clause_split
C_OMP_CLAUSE_SPLIT_TASKLOOP = C_OMP_CLAUSE_SPLIT_FOR
};
+enum c_omp_region_type
+{
+ C_ORT_OMP = 1 << 0,
+ C_ORT_CILK = 1 << 1,
+ C_ORT_ACC = 1 << 2,
+ C_ORT_DECLARE_SIMD = 1 << 3,
+ C_ORT_OMP_DECLARE_SIMD = C_ORT_OMP | C_ORT_DECLARE_SIMD
+};
+
extern tree c_finish_omp_master (location_t, tree);
extern tree c_finish_omp_taskgroup (location_t, tree);
extern tree c_finish_omp_critical (location_t, tree, tree, tree);
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 05bfa7cbc6f..918df16ea99 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -370,6 +370,10 @@ Wctor-dtor-privacy
C++ ObjC++ Var(warn_ctor_dtor_privacy) Warning
Warn when all constructors and destructors are private.
+Wdangling-else
+C ObjC C++ ObjC++ Var(warn_dangling_else) Warning LangEnabledBy(C ObjC C++ ObjC++,Wparentheses)
+Warn about dangling else.
+
Wdate-time
C ObjC C++ ObjC++ CPP(warn_date_time) CppReason(CPP_W_DATE_TIME) Var(cpp_warn_date_time) Init(0) Warning
Warn about __TIME__, __DATE__ and __TIMESTAMP__ usage.
@@ -1004,6 +1008,10 @@ Wsubobject-linkage
C++ ObjC++ Var(warn_subobject_linkage) Warning Init(1)
Warn if a class type has a base or a field whose type uses the anonymous namespace or depends on a type with no linkage.
+Wduplicate-decl-specifier
+C ObjC Var(warn_duplicate_decl_specifier) Warning LangEnabledBy(C ObjC,Wall)
+Warn when a declaration has duplicate const, volatile, restrict or _Atomic specifier.
+
ansi
C ObjC C++ ObjC++
A synonym for -std=c89 (for C) or -std=c++98 (for C++).
diff --git a/gcc/c-family/cilk.c b/gcc/c-family/cilk.c
index 69a79baffea..8f34cd6c5e4 100644
--- a/gcc/c-family/cilk.c
+++ b/gcc/c-family/cilk.c
@@ -795,9 +795,13 @@ cilk_gimplify_call_params_in_spawned_fn (tree *expr_p, gimple_seq *pre_p)
fix_parm_expr = &TREE_OPERAND (*expr_p, 1);
if (TREE_CODE (*fix_parm_expr) == CALL_EXPR)
- for (ii = 0; ii < call_expr_nargs (*fix_parm_expr); ii++)
- gimplify_arg (&CALL_EXPR_ARG (*fix_parm_expr, ii), pre_p,
- EXPR_LOCATION (*fix_parm_expr));
+ {
+ /* Cilk outlining assumes GENERIC bodies, avoid leaking SSA names
+ via parameters. */
+ for (ii = 0; ii < call_expr_nargs (*fix_parm_expr); ii++)
+ gimplify_arg (&CALL_EXPR_ARG (*fix_parm_expr, ii), pre_p,
+ EXPR_LOCATION (*fix_parm_expr), false);
+ }
}
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 793186bfb63..c65f2e9e5e0 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,122 @@
+2016-05-20 Martin Sebor <msebor@redhat.com>
+
+ PR c/71115
+ * c-typeck.c (error_init): Use
+ expansion_point_location_if_in_system_header.
+ (warning_init): Same.
+
+2016-05-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR c/71171
+ * c-parser.c (c_parser_generic_selection): Use c_expr::set_error
+ in error-handling.
+ (c_parser_postfix_expression): Likewise.
+ * c-tree.h (c_expr::set_error): New method.
+ * c-typeck.c (parser_build_binary_op): In error-handling, ensure
+ that result's range is initialized.
+
+2016-05-17 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * c-typeck.c (parser_build_unary_op): Fix formatting.
+
+2016-05-16 Matthew Wahab <matthew.wahab@arm.com>
+
+ * c-decl.c (grokdeclarator): Remove errmsg and use of
+ targetm.invalid_return_type.
+ (grokparms): Remove errmsg and use of
+ targetm.invalid_parameter_type.
+
+2016-05-13 Joseph Myers <joseph@codesourcery.com>
+
+ * c-decl.c (grokdeclarator): For C11, discard qualifiers on
+ function return type.
+
+2016-05-12 Marek Polacek <polacek@redhat.com>
+
+ PR c/70756
+ * c-decl.c (build_compound_literal): Pass LOC down to
+ c_incomplete_type_error.
+ * c-tree.h (require_complete_type): Adjust declaration.
+ (c_incomplete_type_error): Likewise.
+ * c-typeck.c (require_complete_type): Add location parameter, pass it
+ down to c_incomplete_type_error.
+ (c_incomplete_type_error): Add location parameter, pass it down to
+ error_at.
+ (build_component_ref): Pass location down to c_incomplete_type_error.
+ (default_conversion): Pass location down to require_complete_type.
+ (build_array_ref): Likewise.
+ (build_function_call_vec): Likewise.
+ (convert_arguments): Likewise.
+ (build_unary_op): Likewise.
+ (build_c_cast): Likewise.
+ (build_modify_expr): Likewise.
+ (convert_for_assignment): Likewise.
+ (c_finish_omp_clauses): Likewise.
+
+2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
+
+ PR c/43651
+ * c-decl.c (declspecs_add_qual): Warn when -Wduplicate-decl-specifier
+ is enabled.
+ * c-errors.c (pedwarn_c90): Return true if warned.
+ * c-tree.h (pedwarn_c90): Change return type to bool.
+ (enum c_declspec_word): Add new enumerator cdw_atomic.
+
+2016-05-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/71024
+ * c-decl.c (diagnose_mismatched_decls): Factor out code to
+ diagnose_mismatched_attributes and call it.
+
+2016-05-10 Marek Polacek <polacek@redhat.com>
+
+ PR c/70255
+ * c-decl.c (diagnose_mismatched_decls): Warn for optimize attribute
+ on a declaration following the definition.
+
+2016-05-05 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_switch_statement): Add IF_P argument,
+ parse it through to c_parser_c99_block_statement.
+ (c_parser_statement_after_labels): Adjust c_parser_switch_statement
+ caller.
+
+2016-05-04 Marek Polacek <polacek@redhat.com>
+
+ * c-parser.c (c_parser_if_statement): Replace OPT_Wparentheses with
+ OPT_Wdangling_else.
+
+2016-05-04 Marek Polacek <polacek@redhat.com>
+
+ PR c/48778
+ * c-typeck.c (build_binary_op): Don't issue -Waddress warnings
+ for macro expansions.
+
+2016-05-03 Marek Polacek <polacek@redhat.com>
+
+ PR c/70859
+ * c-typeck.c (build_function_call_vec): Pass LOC and ARG_LOC down to
+ check_builtin_function_arguments.
+
+2016-05-03 Richard Biener <rguenther@suse.de>
+
+ * Make-lang.in (cc1-checksum.c): For stage-final re-use
+ the checksum from the previous stage.
+
+2016-05-02 Cesar Philippidis <cesar@codesourcery.com>
+
+ * c-parser.c (c_parser_oacc_all_clauses): Update call to
+ c_finish_omp_clauses.
+ (c_parser_omp_all_clauses): Likewise.
+ (c_parser_oacc_cache): Likewise.
+ (c_parser_oacc_loop): Likewise.
+ (omp_split_clauses): Likewise.
+ (c_parser_omp_declare_target): Likewise.
+ (c_parser_cilk_all_clauses): Likewise.
+ (c_parser_cilk_for): Likewise.
+ * c-typeck.c (c_finish_omp_clauses): Replace bool arguments
+ is_omp, declare_simd, and is_cilk with enum c_omp_region_type ort.
+
2016-05-02 Marek Polacek <polacek@redhat.com>
PR c/70851
diff --git a/gcc/c/Make-lang.in b/gcc/c/Make-lang.in
index 8525707f996..34c8b0ed856 100644
--- a/gcc/c/Make-lang.in
+++ b/gcc/c/Make-lang.in
@@ -61,11 +61,18 @@ c_OBJS = $(C_OBJS) cc1-checksum.o c/gccspec.o
c-warn = $(STRICT_WARN)
# compute checksum over all object files and the options
+# re-use the checksum from the prev-final stage so it passes
+# the bootstrap comparison and allows comparing of the cc1 binary
cc1-checksum.c : build/genchecksum$(build_exeext) checksum-options \
$(C_OBJS) $(BACKEND) $(LIBDEPS)
- build/genchecksum$(build_exeext) $(C_OBJS) $(BACKEND) $(LIBDEPS) \
+ if [ -f ../stage_final ] \
+ && cmp -s ../stage_current ../stage_final; then \
+ cp ../prev-gcc/cc1-checksum.c cc1-checksum.c; \
+ else \
+ build/genchecksum$(build_exeext) $(C_OBJS) $(BACKEND) $(LIBDEPS) \
checksum-options > cc1-checksum.c.tmp && \
- $(srcdir)/../move-if-change cc1-checksum.c.tmp cc1-checksum.c
+ $(srcdir)/../move-if-change cc1-checksum.c.tmp cc1-checksum.c; \
+ fi
cc1$(exeext): $(C_OBJS) cc1-checksum.o $(BACKEND) $(LIBDEPS)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(C_OBJS) \
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 7094efc5dfe..9441fbb3b40 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -2227,43 +2227,7 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
}
if (TREE_CODE (newdecl) == FUNCTION_DECL)
- {
- /* Diagnose inline __attribute__ ((noinline)) which is silly. */
- if (DECL_DECLARED_INLINE_P (newdecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
- warned |= warning (OPT_Wattributes,
- "inline declaration of %qD follows "
- "declaration with attribute noinline", newdecl);
- else if (DECL_DECLARED_INLINE_P (olddecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
- warned |= warning (OPT_Wattributes,
- "declaration of %q+D with attribute "
- "noinline follows inline declaration ", newdecl);
- else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))
- && lookup_attribute ("always_inline", DECL_ATTRIBUTES (olddecl)))
- warned |= warning (OPT_Wattributes,
- "declaration of %q+D with attribute "
- "%qs follows declaration with attribute %qs",
- newdecl, "noinline", "always_inline");
- else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (newdecl))
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
- warned |= warning (OPT_Wattributes,
- "declaration of %q+D with attribute "
- "%qs follows declaration with attribute %qs",
- newdecl, "always_inline", "noinline");
- else if (lookup_attribute ("cold", DECL_ATTRIBUTES (newdecl))
- && lookup_attribute ("hot", DECL_ATTRIBUTES (olddecl)))
- warned |= warning (OPT_Wattributes,
- "declaration of %q+D with attribute %qs follows "
- "declaration with attribute %qs", newdecl, "cold",
- "hot");
- else if (lookup_attribute ("hot", DECL_ATTRIBUTES (newdecl))
- && lookup_attribute ("cold", DECL_ATTRIBUTES (olddecl)))
- warned |= warning (OPT_Wattributes,
- "declaration of %q+D with attribute %qs follows "
- "declaration with attribute %qs", newdecl, "hot",
- "cold");
- }
+ warned |= diagnose_mismatched_attributes (olddecl, newdecl);
else /* PARM_DECL, VAR_DECL */
{
/* Redeclaration of a parameter is a constraint violation (this is
@@ -5112,7 +5076,7 @@ build_compound_literal (location_t loc, tree type, tree init, bool non_const)
if (type == error_mark_node || !COMPLETE_TYPE_P (type))
{
- c_incomplete_type_error (NULL_TREE, type);
+ c_incomplete_type_error (loc, NULL_TREE, type);
return error_mark_node;
}
@@ -5392,7 +5356,6 @@ grokdeclarator (const struct c_declarator *declarator,
struct c_arg_info *arg_info = 0;
addr_space_t as1, as2, address_space;
location_t loc = UNKNOWN_LOCATION;
- const char *errmsg;
tree expr_dummy;
bool expr_const_operands_dummy;
enum c_declarator_kind first_non_attr_kind;
@@ -6126,12 +6089,6 @@ grokdeclarator (const struct c_declarator *declarator,
"an array");
type = integer_type_node;
}
- errmsg = targetm.invalid_return_type (type);
- if (errmsg)
- {
- error (errmsg);
- type = integer_type_node;
- }
/* Construct the function type and go to the next
inner layer of declarator. */
@@ -6142,20 +6099,35 @@ grokdeclarator (const struct c_declarator *declarator,
qualify the return type, not the function type. */
if (type_quals)
{
+ int quals_used = type_quals;
/* Type qualifiers on a function return type are
normally permitted by the standard but have no
effect, so give a warning at -Wreturn-type.
Qualifiers on a void return type are banned on
function definitions in ISO C; GCC used to used
- them for noreturn functions. */
- if (VOID_TYPE_P (type) && really_funcdef)
+ them for noreturn functions. The resolution of C11
+ DR#423 means qualifiers (other than _Atomic) are
+ actually removed from the return type when
+ determining the function type. */
+ if (flag_isoc11)
+ quals_used &= TYPE_QUAL_ATOMIC;
+ if (quals_used && VOID_TYPE_P (type) && really_funcdef)
pedwarn (loc, 0,
"function definition has qualified void return type");
else
warning_at (loc, OPT_Wignored_qualifiers,
"type qualifiers ignored on function return type");
- type = c_build_qualified_type (type, type_quals);
+ /* Ensure an error for restrict on invalid types; the
+ DR#423 resolution is not entirely clear about
+ this. */
+ if (flag_isoc11
+ && (type_quals & TYPE_QUAL_RESTRICT)
+ && (!POINTER_TYPE_P (type)
+ || !C_TYPE_OBJECT_OR_INCOMPLETE_P (TREE_TYPE (type))))
+ error_at (loc, "invalid use of %<restrict%>");
+ if (quals_used)
+ type = c_build_qualified_type (type, quals_used);
}
type_quals = TYPE_UNQUALIFIED;
@@ -6868,7 +6840,6 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
{
tree parm, type, typelt;
unsigned int parmno;
- const char *errmsg;
/* If there is a parameter of incomplete type in a definition,
this is an error. In a declaration this is valid, and a
@@ -6917,15 +6888,6 @@ grokparms (struct c_arg_info *arg_info, bool funcdef_flag)
}
}
- errmsg = targetm.invalid_parameter_type (type);
- if (errmsg)
- {
- error (errmsg);
- TREE_VALUE (typelt) = error_mark_node;
- TREE_TYPE (parm) = error_mark_node;
- arg_types = NULL_TREE;
- }
-
if (DECL_NAME (parm) && TREE_USED (parm))
warn_if_shadowing (parm);
}
@@ -9551,32 +9513,48 @@ declspecs_add_qual (source_location loc,
gcc_assert (TREE_CODE (qual) == IDENTIFIER_NODE
&& C_IS_RESERVED_WORD (qual));
i = C_RID_CODE (qual);
+ location_t prev_loc = 0;
switch (i)
{
case RID_CONST:
dupe = specs->const_p;
specs->const_p = true;
+ prev_loc = specs->locations[cdw_const];
specs->locations[cdw_const] = loc;
break;
case RID_VOLATILE:
dupe = specs->volatile_p;
specs->volatile_p = true;
+ prev_loc = specs->locations[cdw_volatile];
specs->locations[cdw_volatile] = loc;
break;
case RID_RESTRICT:
dupe = specs->restrict_p;
specs->restrict_p = true;
+ prev_loc = specs->locations[cdw_restrict];
specs->locations[cdw_restrict] = loc;
break;
case RID_ATOMIC:
dupe = specs->atomic_p;
specs->atomic_p = true;
+ prev_loc = specs->locations[cdw_atomic];
+ specs->locations[cdw_atomic] = loc;
break;
default:
gcc_unreachable ();
}
if (dupe)
- pedwarn_c90 (loc, OPT_Wpedantic, "duplicate %qE", qual);
+ {
+ bool warned = pedwarn_c90 (loc, OPT_Wpedantic,
+ "duplicate %qE declaration specifier", qual);
+ if (!warned
+ && warn_duplicate_decl_specifier
+ && prev_loc >= RESERVED_LOCATION_COUNT
+ && !from_macro_expansion_at (prev_loc)
+ && !from_macro_expansion_at (loc))
+ warning_at (loc, OPT_Wduplicate_decl_specifier,
+ "duplicate %qE declaration specifier", qual);
+ }
return specs;
}
diff --git a/gcc/c/c-errors.c b/gcc/c/c-errors.c
index d5e78b875ee..af157c00fc8 100644
--- a/gcc/c/c-errors.c
+++ b/gcc/c/c-errors.c
@@ -71,11 +71,12 @@ pedwarn_c99 (location_t location, int opt, const char *gmsgid, ...)
ISO C99 but not supported in ISO C90, thus we explicitly don't pedwarn
when C99 is specified. (There is no flag_c90.) */
-void
+bool
pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
{
diagnostic_info diagnostic;
va_list ap;
+ bool warned = false;
rich_location richloc (line_table, location);
va_start (ap, gmsgid);
@@ -92,6 +93,7 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
? DK_PEDWARN : DK_WARNING);
diagnostic.option_index = opt;
report_diagnostic (&diagnostic);
+ warned = true;
goto out;
}
}
@@ -114,7 +116,9 @@ pedwarn_c90 (location_t location, int opt, const char *gmsgid, ...)
diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN);
diagnostic.option_index = opt;
report_diagnostic (&diagnostic);
+ warned = true;
}
out:
va_end (ap);
+ return warned;
}
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 832b8dda486..c2c83143c05 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -1305,7 +1305,7 @@ static void c_parser_statement (c_parser *, bool *);
static void c_parser_statement_after_labels (c_parser *, bool *,
vec<tree> * = NULL);
static void c_parser_if_statement (c_parser *, bool *, vec<tree> *);
-static void c_parser_switch_statement (c_parser *);
+static void c_parser_switch_statement (c_parser *, bool *);
static void c_parser_while_statement (c_parser *, bool, bool *);
static void c_parser_do_statement (c_parser *, bool);
static void c_parser_for_statement (c_parser *, bool, bool *);
@@ -5138,7 +5138,7 @@ c_parser_statement_after_labels (c_parser *parser, bool *if_p,
c_parser_if_statement (parser, if_p, chain);
break;
case RID_SWITCH:
- c_parser_switch_statement (parser);
+ c_parser_switch_statement (parser, if_p);
break;
case RID_WHILE:
c_parser_while_statement (parser, false, if_p);
@@ -5542,7 +5542,7 @@ c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
/* Diagnose an ambiguous else if if-then-else is nested inside
if-then. */
if (nested_if)
- warning_at (loc, OPT_Wparentheses,
+ warning_at (loc, OPT_Wdangling_else,
"suggest explicit braces to avoid ambiguous %<else%>");
if (warn_duplicated_cond)
@@ -5570,7 +5570,7 @@ c_parser_if_statement (c_parser *parser, bool *if_p, vec<tree> *chain)
*/
static void
-c_parser_switch_statement (c_parser *parser)
+c_parser_switch_statement (c_parser *parser, bool *if_p)
{
struct c_expr ce;
tree block, expr, body, save_break;
@@ -5605,7 +5605,7 @@ c_parser_switch_statement (c_parser *parser)
c_start_case (switch_loc, switch_cond_loc, expr, explicit_cast_p);
save_break = c_break_label;
c_break_label = NULL_TREE;
- body = c_parser_c99_block_statement (parser, NULL/*if??*/);
+ body = c_parser_c99_block_statement (parser, if_p);
c_finish_case (body, ce.original_type);
if (c_break_label)
{
@@ -7194,7 +7194,7 @@ c_parser_generic_selection (c_parser *parser)
error_expr.original_code = ERROR_MARK;
error_expr.original_type = NULL;
- error_expr.value = error_mark_node;
+ error_expr.set_error ();
matched_assoc.type_location = UNKNOWN_LOCATION;
matched_assoc.type = NULL_TREE;
matched_assoc.expression = error_expr;
@@ -7505,13 +7505,13 @@ c_parser_postfix_expression (c_parser *parser)
gcc_assert (c_dialect_objc ());
if (!c_parser_require (parser, CPP_DOT, "expected %<.%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (c_parser_next_token_is_not (parser, CPP_NAME))
{
c_parser_error (parser, "expected identifier");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
c_token *component_tok = c_parser_peek_token (parser);
@@ -7525,7 +7525,7 @@ c_parser_postfix_expression (c_parser *parser)
}
default:
c_parser_error (parser, "expected expression");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
break;
@@ -7547,7 +7547,7 @@ c_parser_postfix_expression (c_parser *parser)
parser->error = true;
c_parser_skip_until_found (parser, CPP_CLOSE_BRACE, NULL);
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
stmt = c_begin_stmt_expr ();
@@ -7576,7 +7576,7 @@ c_parser_postfix_expression (c_parser *parser)
"expected %<)%>");
if (type_name == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
}
else
expr = c_parser_postfix_expression_after_paren_type (parser,
@@ -7636,7 +7636,7 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
e1 = c_parser_expr_no_commas (parser, NULL);
@@ -7645,7 +7645,7 @@ c_parser_postfix_expression (c_parser *parser)
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
loc = c_parser_peek_token (parser)->location;
@@ -7655,7 +7655,7 @@ c_parser_postfix_expression (c_parser *parser)
"expected %<)%>");
if (t1 == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
}
else
{
@@ -7677,7 +7677,7 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
t1 = c_parser_type_name (parser);
@@ -7688,7 +7688,7 @@ c_parser_postfix_expression (c_parser *parser)
if (parser->error)
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7777,7 +7777,7 @@ c_parser_postfix_expression (c_parser *parser)
&cexpr_list, true,
&close_paren_loc))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7785,7 +7785,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "wrong number of arguments to "
"%<__builtin_choose_expr%>");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7810,25 +7810,25 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (!c_parser_require (parser, CPP_COMMA, "expected %<,%>"))
{
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
t2 = c_parser_type_name (parser);
if (t2 == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
{
@@ -7840,7 +7840,7 @@ c_parser_postfix_expression (c_parser *parser)
e2 = groktypename (t2, NULL, NULL);
if (e1 == error_mark_node || e2 == error_mark_node)
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7865,14 +7865,14 @@ c_parser_postfix_expression (c_parser *parser)
&cexpr_list, false,
&close_paren_loc))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (vec_safe_length (cexpr_list) != 2)
{
error_at (loc, "wrong number of arguments to "
"%<__builtin_call_with_static_chain%>");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7907,7 +7907,7 @@ c_parser_postfix_expression (c_parser *parser)
&cexpr_list, false,
&close_paren_loc))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7915,7 +7915,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "wrong number of arguments to "
"%<__builtin_complex%>");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7937,7 +7937,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "%<__builtin_complex%> operand "
"not of real binary floating-point type");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (TYPE_MAIN_VARIANT (TREE_TYPE (e1_p->value))
@@ -7945,7 +7945,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc,
"%<__builtin_complex%> operands of different types");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
pedwarn_c90 (loc, OPT_Wpedantic,
@@ -7971,7 +7971,7 @@ c_parser_postfix_expression (c_parser *parser)
&cexpr_list, false,
&close_paren_loc))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
@@ -7994,7 +7994,7 @@ c_parser_postfix_expression (c_parser *parser)
{
error_at (loc, "wrong number of arguments to "
"%<__builtin_shuffle%>");
- expr.value = error_mark_node;
+ expr.set_error ();
}
set_c_expr_source_range (&expr, loc, close_paren_loc);
break;
@@ -8004,7 +8004,7 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
{
@@ -8021,14 +8021,14 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
if (c_parser_next_token_is_not (parser, CPP_NAME))
{
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
{
@@ -8047,13 +8047,13 @@ c_parser_postfix_expression (c_parser *parser)
c_parser_consume_token (parser);
if (!c_parser_require (parser, CPP_OPEN_PAREN, "expected %<(%>"))
{
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
t1 = c_parser_type_name (parser);
if (t1 == NULL)
{
- expr.value = error_mark_node;
+ expr.set_error ();
c_parser_skip_until_found (parser, CPP_CLOSE_PAREN, NULL);
break;
}
@@ -8076,7 +8076,7 @@ c_parser_postfix_expression (c_parser *parser)
error_at (loc, "-fcilkplus must be enabled to use "
"%<_Cilk_spawn%>");
expr = c_parser_cast_expression (parser, NULL);
- expr.value = error_mark_node;
+ expr.set_error ();
}
else if (c_parser_peek_token (parser)->keyword == RID_CILK_SPAWN)
{
@@ -8095,7 +8095,7 @@ c_parser_postfix_expression (c_parser *parser)
break;
default:
c_parser_error (parser, "expected expression");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
break;
@@ -8116,7 +8116,7 @@ c_parser_postfix_expression (c_parser *parser)
/* Else fall through to report error. */
default:
c_parser_error (parser, "expected expression");
- expr.value = error_mark_node;
+ expr.set_error ();
break;
}
return c_parser_postfix_expression_after_primary
@@ -8331,7 +8331,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
else
{
c_parser_error (parser, "expected identifier");
- expr.value = error_mark_node;
+ expr.set_error ();
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
return expr;
@@ -8363,7 +8363,7 @@ c_parser_postfix_expression_after_primary (c_parser *parser,
else
{
c_parser_error (parser, "expected identifier");
- expr.value = error_mark_node;
+ expr.set_error ();
expr.original_code = ERROR_MARK;
expr.original_type = NULL;
return expr;
@@ -13183,7 +13183,7 @@ c_parser_oacc_all_clauses (c_parser *parser, omp_clause_mask mask,
c_parser_skip_to_pragma_eol (parser);
if (finish_p)
- return c_finish_omp_clauses (clauses, false);
+ return c_finish_omp_clauses (clauses, C_ORT_ACC);
return clauses;
}
@@ -13468,8 +13468,8 @@ c_parser_omp_all_clauses (c_parser *parser, omp_clause_mask mask,
if (finish_p)
{
if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
- return c_finish_omp_clauses (clauses, true, true);
- return c_finish_omp_clauses (clauses, true);
+ return c_finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
+ return c_finish_omp_clauses (clauses, C_ORT_OMP);
}
return clauses;
@@ -13503,7 +13503,7 @@ c_parser_oacc_cache (location_t loc, c_parser *parser)
tree stmt, clauses;
clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE__CACHE_, NULL);
- clauses = c_finish_omp_clauses (clauses, false);
+ clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
c_parser_skip_to_pragma_eol (parser);
@@ -13839,9 +13839,9 @@ c_parser_oacc_loop (location_t loc, c_parser *parser, char *p_name,
{
clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
if (*cclauses)
- *cclauses = c_finish_omp_clauses (*cclauses, false);
+ *cclauses = c_finish_omp_clauses (*cclauses, C_ORT_ACC);
if (clauses)
- clauses = c_finish_omp_clauses (clauses, false);
+ clauses = c_finish_omp_clauses (clauses, C_ORT_ACC);
}
tree block = c_begin_compound_stmt (true);
@@ -15015,7 +15015,7 @@ omp_split_clauses (location_t loc, enum tree_code code,
c_omp_split_clauses (loc, code, mask, clauses, cclauses);
for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
if (cclauses[i])
- cclauses[i] = c_finish_omp_clauses (cclauses[i], true);
+ cclauses[i] = c_finish_omp_clauses (cclauses[i], C_ORT_OMP);
}
/* OpenMP 4.0:
@@ -16546,7 +16546,7 @@ c_parser_omp_declare_target (c_parser *parser)
{
clauses = c_parser_omp_var_list_parens (parser, OMP_CLAUSE_TO_DECLARE,
clauses);
- clauses = c_finish_omp_clauses (clauses, true);
+ clauses = c_finish_omp_clauses (clauses, C_ORT_OMP);
c_parser_skip_to_pragma_eol (parser);
}
else
@@ -17515,7 +17515,7 @@ c_parser_cilk_all_clauses (c_parser *parser)
saw_error:
c_parser_skip_to_pragma_eol (parser);
- return c_finish_omp_clauses (clauses, false, false, true);
+ return c_finish_omp_clauses (clauses, C_ORT_CILK);
}
/* This function helps parse the grainsize pragma for a _Cilk_for statement.
@@ -17597,7 +17597,7 @@ c_parser_cilk_for (c_parser *parser, tree grain, bool *if_p)
tree clauses = build_omp_clause (EXPR_LOCATION (grain), OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (clauses) = OMP_CLAUSE_SCHEDULE_CILKFOR;
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses) = grain;
- clauses = c_finish_omp_clauses (clauses, false);
+ clauses = c_finish_omp_clauses (clauses, C_ORT_CILK);
tree block = c_begin_compound_stmt (true);
tree sb = push_stmt_list ();
@@ -17663,7 +17663,7 @@ c_parser_cilk_for (c_parser *parser, tree grain, bool *if_p)
OMP_CLAUSE_OPERAND (c, 0)
= cilk_for_number_of_iterations (omp_for);
OMP_CLAUSE_CHAIN (c) = clauses;
- OMP_PARALLEL_CLAUSES (omp_par) = c_finish_omp_clauses (c, true);
+ OMP_PARALLEL_CLAUSES (omp_par) = c_finish_omp_clauses (c, C_ORT_CILK);
add_stmt (omp_par);
}
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 4633182eef9..444e9a4777e 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -143,6 +143,15 @@ struct c_expr
of this expression. */
location_t get_start () const { return src_range.m_start; }
location_t get_finish () const { return src_range.m_finish; }
+
+ /* Set the value to error_mark_node whilst ensuring that src_range
+ is initialized. */
+ void set_error ()
+ {
+ value = error_mark_node;
+ src_range.m_start = UNKNOWN_LOCATION;
+ src_range.m_finish = UNKNOWN_LOCATION;
+ }
};
/* Type alias for struct c_expr. This allows to use the structure
@@ -253,6 +262,7 @@ enum c_declspec_word {
cdw_const,
cdw_volatile,
cdw_restrict,
+ cdw_atomic,
cdw_saturating,
cdw_alignas,
cdw_address_space,
@@ -588,13 +598,13 @@ extern tree c_last_sizeof_arg;
extern struct c_switch *c_switch_stack;
extern tree c_objc_common_truthvalue_conversion (location_t, tree);
-extern tree require_complete_type (tree);
+extern tree require_complete_type (location_t, tree);
extern int same_translation_unit_p (const_tree, const_tree);
extern int comptypes (tree, tree);
extern int comptypes_check_different_types (tree, tree, bool *);
extern bool c_vla_type_p (const_tree);
extern bool c_mark_addressable (tree);
-extern void c_incomplete_type_error (const_tree, const_tree);
+extern void c_incomplete_type_error (location_t, const_tree, const_tree);
extern tree c_type_promotes_to (tree);
extern struct c_expr default_function_array_conversion (location_t,
struct c_expr);
@@ -661,7 +671,7 @@ extern tree c_begin_omp_task (void);
extern tree c_finish_omp_task (location_t, tree, tree);
extern void c_finish_omp_cancel (location_t, tree);
extern void c_finish_omp_cancellation_point (location_t, tree);
-extern tree c_finish_omp_clauses (tree, bool, bool = false, bool = false);
+extern tree c_finish_omp_clauses (tree, enum c_omp_region_type);
extern tree c_build_va_arg (location_t, tree, location_t, tree);
extern tree c_finish_transaction (location_t, tree, int);
extern bool c_tree_equal (tree, tree);
@@ -716,7 +726,7 @@ extern void c_bind (location_t, tree, bool);
extern bool tag_exists_p (enum tree_code, tree);
/* In c-errors.c */
-extern void pedwarn_c90 (location_t, int opt, const char *, ...)
+extern bool pedwarn_c90 (location_t, int opt, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4);
extern bool pedwarn_c99 (location_t, int opt, const char *, ...)
ATTRIBUTE_GCC_DIAG(3,4);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 58c21393e47..7c9b078ed1b 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -183,11 +183,12 @@ struct tagged_tu_seen_cache {
static const struct tagged_tu_seen_cache * tagged_tu_seen_base;
static void free_all_tagged_tu_seen_up_to (const struct tagged_tu_seen_cache *);
-/* Do `exp = require_complete_type (exp);' to make sure exp
- does not have an incomplete type. (That includes void types.) */
+/* Do `exp = require_complete_type (loc, exp);' to make sure exp
+ does not have an incomplete type. (That includes void types.)
+ LOC is the location of the use. */
tree
-require_complete_type (tree value)
+require_complete_type (location_t loc, tree value)
{
tree type = TREE_TYPE (value);
@@ -198,23 +199,24 @@ require_complete_type (tree value)
if (COMPLETE_TYPE_P (type))
return value;
- c_incomplete_type_error (value, type);
+ c_incomplete_type_error (loc, value, type);
return error_mark_node;
}
/* Print an error message for invalid use of an incomplete type.
VALUE is the expression that was used (or 0 if that isn't known)
- and TYPE is the type that was invalid. */
+ and TYPE is the type that was invalid. LOC is the location for
+ the error. */
void
-c_incomplete_type_error (const_tree value, const_tree type)
+c_incomplete_type_error (location_t loc, const_tree value, const_tree type)
{
/* Avoid duplicate error message. */
if (TREE_CODE (type) == ERROR_MARK)
return;
if (value != 0 && (VAR_P (value) || TREE_CODE (value) == PARM_DECL))
- error ("%qD has an incomplete type %qT", value, type);
+ error_at (loc, "%qD has an incomplete type %qT", value, type);
else
{
retry:
@@ -228,7 +230,7 @@ c_incomplete_type_error (const_tree value, const_tree type)
break;
case VOID_TYPE:
- error ("invalid use of void expression");
+ error_at (loc, "invalid use of void expression");
return;
case ARRAY_TYPE:
@@ -236,13 +238,13 @@ c_incomplete_type_error (const_tree value, const_tree type)
{
if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) == NULL)
{
- error ("invalid use of flexible array member");
+ error_at (loc, "invalid use of flexible array member");
return;
}
type = TREE_TYPE (type);
goto retry;
}
- error ("invalid use of array with unspecified bounds");
+ error_at (loc, "invalid use of array with unspecified bounds");
return;
default:
@@ -250,10 +252,10 @@ c_incomplete_type_error (const_tree value, const_tree type)
}
if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
- error ("invalid use of undefined type %qT", type);
+ error_at (loc, "invalid use of undefined type %qT", type);
else
/* If this type has a typedef-name, the TYPE_NAME is a TYPE_DECL. */
- error ("invalid use of incomplete typedef %qT", type);
+ error_at (loc, "invalid use of incomplete typedef %qT", type);
}
}
@@ -2117,7 +2119,7 @@ default_conversion (tree exp)
return error_mark_node;
}
- exp = require_complete_type (exp);
+ exp = require_complete_type (EXPR_LOC_OR_LOC (exp, input_location), exp);
if (exp == error_mark_node)
return error_mark_node;
@@ -2334,7 +2336,7 @@ build_component_ref (location_t loc, tree datum, tree component)
{
if (!COMPLETE_TYPE_P (type))
{
- c_incomplete_type_error (NULL_TREE, type);
+ c_incomplete_type_error (loc, NULL_TREE, type);
return error_mark_node;
}
@@ -2642,7 +2644,7 @@ build_array_ref (location_t loc, tree array, tree index)
in an inline function.
Hope it doesn't break something else. */
| TREE_THIS_VOLATILE (array));
- ret = require_complete_type (rval);
+ ret = require_complete_type (loc, rval);
protected_set_expr_location (ret, loc);
if (non_lvalue)
ret = non_lvalue_loc (loc, ret);
@@ -3046,7 +3048,8 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
if (fundecl
&& DECL_BUILT_IN (fundecl)
&& DECL_BUILT_IN_CLASS (fundecl) == BUILT_IN_NORMAL
- && !check_builtin_function_arguments (fundecl, nargs, argarray))
+ && !check_builtin_function_arguments (loc, arg_loc, fundecl, nargs,
+ argarray))
return error_mark_node;
/* Check that the arguments to the function are valid. */
@@ -3087,7 +3090,7 @@ build_function_call_vec (location_t loc, vec<location_t> arg_loc,
"function with qualified void return type called");
return result;
}
- return require_complete_type (result);
+ return require_complete_type (loc, result);
}
/* Like build_function_call_vec, but call also resolve_overloaded_builtin. */
@@ -3238,7 +3241,7 @@ convert_arguments (location_t loc, vec<location_t> arg_loc, tree typelist,
val = c_fully_fold (val, false, NULL);
STRIP_TYPE_NOPS (val);
- val = require_complete_type (val);
+ val = require_complete_type (ploc, val);
if (type != 0)
{
@@ -3488,8 +3491,8 @@ parser_build_unary_op (location_t loc, enum tree_code code, struct c_expr arg)
{
result.value = build_unary_op (loc, code, arg.value, 0);
- if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
- overflow_warning (loc, result.value);
+ if (TREE_OVERFLOW_P (result.value) && !TREE_OVERFLOW_P (arg.value))
+ overflow_warning (loc, result.value);
}
/* We are typically called when parsing a prefix token at LOC acting on
@@ -3530,7 +3533,12 @@ parser_build_binary_op (location_t location, enum tree_code code,
result.original_type = NULL;
if (TREE_CODE (result.value) == ERROR_MARK)
- return result;
+ {
+ set_c_expr_source_range (&result,
+ arg1.get_start (),
+ arg2.get_finish ());
+ return result;
+ }
if (location != UNKNOWN_LOCATION)
protected_set_expr_location (result.value, location);
@@ -4046,7 +4054,7 @@ build_unary_op (location_t location,
arg = remove_c_maybe_const_expr (arg);
if (code != ADDR_EXPR)
- arg = require_complete_type (arg);
+ arg = require_complete_type (location, arg);
typecode = TREE_CODE (TREE_TYPE (arg));
if (typecode == ERROR_MARK)
@@ -5267,7 +5275,7 @@ build_c_cast (location_t loc, tree type, tree expr)
if (!VOID_TYPE_P (type))
{
- value = require_complete_type (value);
+ value = require_complete_type (loc, value);
if (value == error_mark_node)
return error_mark_node;
}
@@ -5537,7 +5545,7 @@ build_modify_expr (location_t location, tree lhs, tree lhs_origtype,
bool is_atomic_op;
/* Types that aren't fully specified cannot be used in assignments. */
- lhs = require_complete_type (lhs);
+ lhs = require_complete_type (location, lhs);
/* Avoid duplicate error messages from operands that had errors. */
if (TREE_CODE (lhs) == ERROR_MARK || TREE_CODE (rhs) == ERROR_MARK)
@@ -5871,16 +5879,21 @@ error_init (location_t loc, const char *gmsgid)
component name is taken from the spelling stack. */
static void
-pedwarn_init (location_t location, int opt, const char *gmsgid)
+pedwarn_init (location_t loc, int opt, const char *gmsgid)
{
char *ofwhat;
bool warned;
+ /* Use the location where a macro was expanded rather than where
+ it was defined to make sure macros defined in system headers
+ but used incorrectly elsewhere are diagnosed. */
+ source_location exploc = expansion_point_location_if_in_system_header (loc);
+
/* The gmsgid may be a format string with %< and %>. */
- warned = pedwarn (location, opt, gmsgid);
+ warned = pedwarn (exploc, opt, gmsgid);
ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat && warned)
- inform (location, "(near initialization for %qs)", ofwhat);
+ inform (exploc, "(near initialization for %qs)", ofwhat);
}
/* Issue a warning for a bad initializer component.
@@ -5895,11 +5908,16 @@ warning_init (location_t loc, int opt, const char *gmsgid)
char *ofwhat;
bool warned;
+ /* Use the location where a macro was expanded rather than where
+ it was defined to make sure macros defined in system headers
+ but used incorrectly elsewhere are diagnosed. */
+ source_location exploc = expansion_point_location_if_in_system_header (loc);
+
/* The gmsgid may be a format string with %< and %>. */
- warned = warning_at (loc, opt, gmsgid);
+ warned = warning_at (exploc, opt, gmsgid);
ofwhat = print_spelling ((char *) alloca (spelling_length () + 1));
if (*ofwhat && warned)
- inform (loc, "(near initialization for %qs)", ofwhat);
+ inform (exploc, "(near initialization for %qs)", ofwhat);
}
/* If TYPE is an array type and EXPR is a parenthesized string
@@ -6132,7 +6150,7 @@ convert_for_assignment (location_t location, location_t expr_loc, tree type,
error_at (location, "void value not ignored as it ought to be");
return error_mark_node;
}
- rhs = require_complete_type (rhs);
+ rhs = require_complete_type (location, rhs);
if (rhs == error_mark_node)
return error_mark_node;
@@ -11066,7 +11084,8 @@ build_binary_op (location_t location, enum tree_code code,
else if (code0 == POINTER_TYPE && null_pointer_constant_p (orig_op1))
{
if (TREE_CODE (op0) == ADDR_EXPR
- && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0)))
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))
+ && !from_macro_expansion_at (location))
{
if (code == EQ_EXPR)
warning_at (location,
@@ -11086,7 +11105,8 @@ build_binary_op (location_t location, enum tree_code code,
else if (code1 == POINTER_TYPE && null_pointer_constant_p (orig_op0))
{
if (TREE_CODE (op1) == ADDR_EXPR
- && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0)))
+ && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))
+ && !from_macro_expansion_at (location))
{
if (code == EQ_EXPR)
warning_at (location,
@@ -12496,8 +12516,7 @@ c_find_omp_placeholder_r (tree *tp, int *, void *data)
Remove any elements from the list that are invalid. */
tree
-c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
- bool is_cilk)
+c_finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
{
bitmap_head generic_head, firstprivate_head, lastprivate_head;
bitmap_head aligned_head, map_head, map_field_head;
@@ -12540,7 +12559,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST)
{
- if (handle_omp_array_sections (c, is_omp))
+ if (handle_omp_array_sections (c, ort & C_ORT_OMP))
{
remove = true;
break;
@@ -12548,7 +12567,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
t = OMP_CLAUSE_DECL (c);
}
- t = require_complete_type (t);
+ t = require_complete_type (OMP_CLAUSE_LOCATION (c), t);
if (t == error_mark_node)
{
remove = true;
@@ -12768,10 +12787,10 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
goto check_dup_generic;
case OMP_CLAUSE_LINEAR:
- if (!declare_simd)
+ if (ort != C_ORT_OMP_DECLARE_SIMD)
need_implicitly_determined = true;
t = OMP_CLAUSE_DECL (c);
- if (!declare_simd
+ if (ort != C_ORT_OMP_DECLARE_SIMD
&& OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
{
error_at (OMP_CLAUSE_LOCATION (c),
@@ -12779,7 +12798,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
"clause on %<simd%> or %<for%> constructs");
OMP_CLAUSE_LINEAR_KIND (c) = OMP_CLAUSE_LINEAR_DEFAULT;
}
- if (is_cilk)
+ if (ort & C_ORT_CILK)
{
if (!INTEGRAL_TYPE_P (TREE_TYPE (t))
&& !SCALAR_FLOAT_TYPE_P (TREE_TYPE (t))
@@ -12805,7 +12824,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
break;
}
}
- if (declare_simd)
+ if (ort == C_ORT_OMP_DECLARE_SIMD)
{
tree s = OMP_CLAUSE_LINEAR_STEP (c);
if (TREE_CODE (s) == PARM_DECL)
@@ -12984,7 +13003,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
}
if (TREE_CODE (t) == TREE_LIST)
{
- if (handle_omp_array_sections (c, is_omp))
+ if (handle_omp_array_sections (c, ort & C_ORT_OMP))
remove = true;
break;
}
@@ -13007,7 +13026,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST)
{
- if (handle_omp_array_sections (c, is_omp))
+ if (handle_omp_array_sections (c, ort & C_ORT_OMP))
remove = true;
else
{
@@ -13054,7 +13073,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
break;
}
if (TREE_CODE (t) == COMPONENT_REF
- && is_omp
+ && (ort & C_ORT_OMP)
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_)
{
if (DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
@@ -13359,7 +13378,7 @@ c_finish_omp_clauses (tree clauses, bool is_omp, bool declare_simd,
if (need_complete)
{
- t = require_complete_type (t);
+ t = require_complete_type (OMP_CLAUSE_LOCATION (c), t);
if (t == error_mark_node)
remove = true;
}
diff --git a/gcc/calls.c b/gcc/calls.c
index 6415e08b28d..587969fcf01 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -1102,6 +1102,19 @@ store_unaligned_arguments_into_pseudos (struct arg_data *args, int num_actuals)
}
}
+/* Issue an error if CALL_EXPR was flagged as requiring
+ tall-call optimization. */
+
+static void
+maybe_complain_about_tail_call (tree call_expr, const char *reason)
+{
+ gcc_assert (TREE_CODE (call_expr) == CALL_EXPR);
+ if (!CALL_EXPR_MUST_TAIL_CALL (call_expr))
+ return;
+
+ error_at (EXPR_LOCATION (call_expr), "cannot tail-call: %s", reason);
+}
+
/* Fill in ARGS_SIZE and ARGS array based on the parameters found in
CALL_EXPR EXP.
@@ -1188,6 +1201,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
j--;
}
}
+ argpos = 0;
FOR_EACH_CALL_EXPR_ARG (arg, iter, exp)
{
tree argtype = TREE_TYPE (arg);
@@ -1206,6 +1220,14 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
chkp_find_bound_slots (argtype, slots);
}
}
+ else if (CALL_WITH_BOUNDS_P (exp)
+ && pass_by_reference (NULL, TYPE_MODE (argtype), argtype,
+ argpos < n_named_args))
+ {
+ if (slots)
+ BITMAP_FREE (slots);
+ ptr_arg = j;
+ }
else if (POINTER_BOUNDS_TYPE_P (argtype))
{
/* We expect bounds in instrumented calls only.
@@ -1249,6 +1271,7 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
else
args[j].tree_value = arg;
j--;
+ argpos++;
}
if (slots)
@@ -1333,7 +1356,13 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
/* We can't use sibcalls if a callee-copied argument is
stored in the current function's frame. */
if (!call_from_thunk_p && DECL_P (base) && !TREE_STATIC (base))
- *may_tailcall = false;
+ {
+ *may_tailcall = false;
+ maybe_complain_about_tail_call (exp,
+ "a callee-copied argument is"
+ " stored in the current "
+ " function's frame");
+ }
args[i].tree_value = build_fold_addr_expr_loc (loc,
args[i].tree_value);
@@ -1396,6 +1425,9 @@ initialize_argument_information (int num_actuals ATTRIBUTE_UNUSED,
= build_fold_addr_expr_loc (loc, make_tree (type, copy));
type = TREE_TYPE (args[i].tree_value);
*may_tailcall = false;
+ maybe_complain_about_tail_call (exp,
+ "argument must be passed"
+ " by copying");
}
}
@@ -2334,6 +2366,126 @@ avoid_likely_spilled_reg (rtx x)
return x;
}
+/* Helper function for expand_call.
+ Return false is EXP is not implementable as a sibling call. */
+
+static bool
+can_implement_as_sibling_call_p (tree exp,
+ rtx structure_value_addr,
+ tree funtype,
+ int reg_parm_stack_space ATTRIBUTE_UNUSED,
+ tree fndecl,
+ int flags,
+ tree addr,
+ const args_size &args_size)
+{
+ if (!targetm.have_sibcall_epilogue ())
+ {
+ maybe_complain_about_tail_call
+ (exp,
+ "machine description does not have"
+ " a sibcall_epilogue instruction pattern");
+ return false;
+ }
+
+ /* Doing sibling call optimization needs some work, since
+ structure_value_addr can be allocated on the stack.
+ It does not seem worth the effort since few optimizable
+ sibling calls will return a structure. */
+ if (structure_value_addr != NULL_RTX)
+ {
+ maybe_complain_about_tail_call (exp, "callee returns a structure");
+ return false;
+ }
+
+#ifdef REG_PARM_STACK_SPACE
+ /* If outgoing reg parm stack space changes, we can not do sibcall. */
+ if (OUTGOING_REG_PARM_STACK_SPACE (funtype)
+ != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl))
+ || (reg_parm_stack_space != REG_PARM_STACK_SPACE (current_function_decl)))
+ {
+ maybe_complain_about_tail_call (exp,
+ "inconsistent size of stack space"
+ " allocated for arguments which are"
+ " passed in registers");
+ return false;
+ }
+#endif
+
+ /* Check whether the target is able to optimize the call
+ into a sibcall. */
+ if (!targetm.function_ok_for_sibcall (fndecl, exp))
+ {
+ maybe_complain_about_tail_call (exp,
+ "target is not able to optimize the"
+ " call into a sibling call");
+ return false;
+ }
+
+ /* Functions that do not return exactly once may not be sibcall
+ optimized. */
+ if (flags & ECF_RETURNS_TWICE)
+ {
+ maybe_complain_about_tail_call (exp, "callee returns twice");
+ return false;
+ }
+ if (flags & ECF_NORETURN)
+ {
+ maybe_complain_about_tail_call (exp, "callee does not return");
+ return false;
+ }
+
+ if (TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr))))
+ {
+ maybe_complain_about_tail_call (exp, "volatile function type");
+ return false;
+ }
+
+ /* If the called function is nested in the current one, it might access
+ some of the caller's arguments, but could clobber them beforehand if
+ the argument areas are shared. */
+ if (fndecl && decl_function_context (fndecl) == current_function_decl)
+ {
+ maybe_complain_about_tail_call (exp, "nested function");
+ return false;
+ }
+
+ /* If this function requires more stack slots than the current
+ function, we cannot change it into a sibling call.
+ crtl->args.pretend_args_size is not part of the
+ stack allocated by our caller. */
+ if (args_size.constant > (crtl->args.size - crtl->args.pretend_args_size))
+ {
+ maybe_complain_about_tail_call (exp,
+ "callee required more stack slots"
+ " than the caller");
+ return false;
+ }
+
+ /* If the callee pops its own arguments, then it must pop exactly
+ the same number of arguments as the current function. */
+ if (targetm.calls.return_pops_args (fndecl, funtype, args_size.constant)
+ != targetm.calls.return_pops_args (current_function_decl,
+ TREE_TYPE (current_function_decl),
+ crtl->args.size))
+ {
+ maybe_complain_about_tail_call (exp,
+ "inconsistent number of"
+ " popped arguments");
+ return false;
+ }
+
+ if (!lang_hooks.decls.ok_for_sibcall (fndecl))
+ {
+ maybe_complain_about_tail_call (exp, "frontend does not support"
+ " sibling call");
+ return false;
+ }
+
+ /* All checks passed. */
+ return true;
+}
+
/* Generate all the code for a CALL_EXPR exp
and return an rtx for its value.
Store the value in TARGET (specified as an rtx) if convenient.
@@ -2362,6 +2514,7 @@ expand_call (tree exp, rtx target, int ignore)
/* The type of the function being called. */
tree fntype;
bool try_tail_call = CALL_EXPR_TAILCALL (exp);
+ bool must_tail_call = CALL_EXPR_MUST_TAIL_CALL (exp);
int pass;
/* Register in which non-BLKmode value will be returned,
@@ -2729,45 +2882,19 @@ expand_call (tree exp, rtx target, int ignore)
|| dbg_cnt (tail_call) == false)
try_tail_call = 0;
+ /* If the user has marked the function as requiring tail-call
+ optimization, attempt it. */
+ if (must_tail_call)
+ try_tail_call = 1;
+
/* Rest of purposes for tail call optimizations to fail. */
- if (!try_tail_call
- || !targetm.have_sibcall_epilogue ()
- /* Doing sibling call optimization needs some work, since
- structure_value_addr can be allocated on the stack.
- It does not seem worth the effort since few optimizable
- sibling calls will return a structure. */
- || structure_value_addr != NULL_RTX
-#ifdef REG_PARM_STACK_SPACE
- /* If outgoing reg parm stack space changes, we can not do sibcall. */
- || (OUTGOING_REG_PARM_STACK_SPACE (funtype)
- != OUTGOING_REG_PARM_STACK_SPACE (TREE_TYPE (current_function_decl)))
- || (reg_parm_stack_space != REG_PARM_STACK_SPACE (current_function_decl))
-#endif
- /* Check whether the target is able to optimize the call
- into a sibcall. */
- || !targetm.function_ok_for_sibcall (fndecl, exp)
- /* Functions that do not return exactly once may not be sibcall
- optimized. */
- || (flags & (ECF_RETURNS_TWICE | ECF_NORETURN))
- || TYPE_VOLATILE (TREE_TYPE (TREE_TYPE (addr)))
- /* If the called function is nested in the current one, it might access
- some of the caller's arguments, but could clobber them beforehand if
- the argument areas are shared. */
- || (fndecl && decl_function_context (fndecl) == current_function_decl)
- /* If this function requires more stack slots than the current
- function, we cannot change it into a sibling call.
- crtl->args.pretend_args_size is not part of the
- stack allocated by our caller. */
- || args_size.constant > (crtl->args.size
- - crtl->args.pretend_args_size)
- /* If the callee pops its own arguments, then it must pop exactly
- the same number of arguments as the current function. */
- || (targetm.calls.return_pops_args (fndecl, funtype, args_size.constant)
- != targetm.calls.return_pops_args (current_function_decl,
- TREE_TYPE (current_function_decl),
- crtl->args.size))
- || !lang_hooks.decls.ok_for_sibcall (fndecl))
- try_tail_call = 0;
+ if (try_tail_call)
+ try_tail_call = can_implement_as_sibling_call_p (exp,
+ structure_value_addr,
+ funtype,
+ reg_parm_stack_space,
+ fndecl,
+ flags, addr, args_size);
/* Check if caller and callee disagree in promotion of function
return value. */
@@ -2797,7 +2924,13 @@ expand_call (tree exp, rtx target, int ignore)
&& (caller_unsignedp != callee_unsignedp
|| GET_MODE_BITSIZE (caller_mode)
< GET_MODE_BITSIZE (callee_mode)))))
- try_tail_call = 0;
+ {
+ try_tail_call = 0;
+ maybe_complain_about_tail_call (exp,
+ "caller and callee disagree in"
+ " promotion of function"
+ " return value");
+ }
}
/* Ensure current function's preferred stack boundary is at least
@@ -3695,7 +3828,13 @@ expand_call (tree exp, rtx target, int ignore)
crtl->tail_call_emit = true;
}
else
- emit_insn (normal_call_insns);
+ {
+ emit_insn (normal_call_insns);
+ if (try_tail_call)
+ /* Ideally we'd emit a message for all of the ways that it could
+ have failed. */
+ maybe_complain_about_tail_call (exp, "tail call production failed");
+ }
currently_expanding_call--;
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index 189762cba8e..a4bdef60305 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3. If not see
#include "cfghooks.h"
#include "timevar.h"
#include "cfganal.h"
+#include "cfgloop.h"
/* Store the data structures necessary for depth-first search. */
struct depth_first_search_ds {
@@ -747,7 +748,21 @@ dfs_find_deadend (basic_block bb)
return bb;
}
- bb = EDGE_SUCC (bb, 0)->dest;
+ /* If we are in an analyzed cycle make sure to try exiting it.
+ Note this is a heuristic only and expected to work when loop
+ fixup is needed as well. */
+ if (! bb->loop_father
+ || ! loop_outer (bb->loop_father))
+ bb = EDGE_SUCC (bb, 0)->dest;
+ else
+ {
+ edge_iterator ei;
+ edge e;
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ if (loop_exit_edge_p (bb->loop_father, e))
+ break;
+ bb = e ? e->dest : EDGE_SUCC (bb, 0)->dest;
+ }
}
gcc_unreachable ();
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 6e92d4cdde2..023b9d239a8 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -156,6 +156,7 @@ try_simplify_condjump (basic_block cbranch_block)
cbranch_dest_block = cbranch_jump_edge->dest;
if (cbranch_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun)
+ || jump_dest_block == EXIT_BLOCK_PTR_FOR_FN (cfun)
|| !can_fallthru (jump_block, cbranch_dest_block))
return false;
@@ -2605,6 +2606,35 @@ trivially_empty_bb_p (basic_block bb)
}
}
+/* Return true if BB contains just a return and possibly a USE of the
+ return value. Fill in *RET and *USE with the return and use insns
+ if any found, otherwise NULL. */
+
+static bool
+bb_is_just_return (basic_block bb, rtx_insn **ret, rtx_insn **use)
+{
+ *ret = *use = NULL;
+ rtx_insn *insn;
+
+ if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun))
+ return false;
+
+ FOR_BB_INSNS (bb, insn)
+ if (NONDEBUG_INSN_P (insn))
+ {
+ if (!*ret && ANY_RETURN_P (PATTERN (insn)))
+ *ret = insn;
+ else if (!*ret && !*use && GET_CODE (PATTERN (insn)) == USE
+ && REG_P (XEXP (PATTERN (insn), 0))
+ && REG_FUNCTION_VALUE_P (XEXP (PATTERN (insn), 0)))
+ *use = insn;
+ else
+ return false;
+ }
+
+ return !!*ret;
+}
+
/* Do simple CFG optimizations - basic block merging, simplifying of jump
instructions etc. Return nonzero if changes were made. */
@@ -2791,6 +2821,99 @@ try_optimize_cfg (int mode)
}
}
+ /* Try to change a branch to a return to just that return. */
+ rtx_insn *ret, *use;
+ if (single_succ_p (b)
+ && onlyjump_p (BB_END (b))
+ && bb_is_just_return (single_succ (b), &ret, &use))
+ {
+ if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
+ PATTERN (ret), 0))
+ {
+ if (use)
+ emit_insn_before (copy_insn (PATTERN (use)),
+ BB_END (b));
+ if (dump_file)
+ fprintf (dump_file, "Changed jump %d->%d to return.\n",
+ b->index, single_succ (b)->index);
+ redirect_edge_succ (single_succ_edge (b),
+ EXIT_BLOCK_PTR_FOR_FN (cfun));
+ single_succ_edge (b)->flags &= ~EDGE_CROSSING;
+ changed_here = true;
+ }
+ }
+
+ /* Try to change a conditional branch to a return to the
+ respective conditional return. */
+ if (EDGE_COUNT (b->succs) == 2
+ && any_condjump_p (BB_END (b))
+ && bb_is_just_return (BRANCH_EDGE (b)->dest, &ret, &use))
+ {
+ if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
+ PATTERN (ret), 0))
+ {
+ if (use)
+ emit_insn_before (copy_insn (PATTERN (use)),
+ BB_END (b));
+ if (dump_file)
+ fprintf (dump_file, "Changed conditional jump %d->%d "
+ "to conditional return.\n",
+ b->index, BRANCH_EDGE (b)->dest->index);
+ redirect_edge_succ (BRANCH_EDGE (b),
+ EXIT_BLOCK_PTR_FOR_FN (cfun));
+ BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING;
+ changed_here = true;
+ }
+ }
+
+ /* Try to flip a conditional branch that falls through to
+ a return so that it becomes a conditional return and a
+ new jump to the original branch target. */
+ if (EDGE_COUNT (b->succs) == 2
+ && BRANCH_EDGE (b)->dest != EXIT_BLOCK_PTR_FOR_FN (cfun)
+ && any_condjump_p (BB_END (b))
+ && bb_is_just_return (FALLTHRU_EDGE (b)->dest, &ret, &use))
+ {
+ if (invert_jump (as_a <rtx_jump_insn *> (BB_END (b)),
+ JUMP_LABEL (BB_END (b)), 0))
+ {
+ basic_block new_ft = BRANCH_EDGE (b)->dest;
+ if (redirect_jump (as_a <rtx_jump_insn *> (BB_END (b)),
+ PATTERN (ret), 0))
+ {
+ if (use)
+ emit_insn_before (copy_insn (PATTERN (use)),
+ BB_END (b));
+ if (dump_file)
+ fprintf (dump_file, "Changed conditional jump "
+ "%d->%d to conditional return, adding "
+ "fall-through jump.\n",
+ b->index, BRANCH_EDGE (b)->dest->index);
+ redirect_edge_succ (BRANCH_EDGE (b),
+ EXIT_BLOCK_PTR_FOR_FN (cfun));
+ BRANCH_EDGE (b)->flags &= ~EDGE_CROSSING;
+ std::swap (BRANCH_EDGE (b)->probability,
+ FALLTHRU_EDGE (b)->probability);
+ update_br_prob_note (b);
+ basic_block jb = force_nonfallthru (FALLTHRU_EDGE (b));
+ notice_new_block (jb);
+ if (!redirect_jump (as_a <rtx_jump_insn *> (BB_END (jb)),
+ block_label (new_ft), 0))
+ gcc_unreachable ();
+ redirect_edge_succ (single_succ_edge (jb), new_ft);
+ changed_here = true;
+ }
+ else
+ {
+ /* Invert the jump back to what it was. This should
+ never fail. */
+ if (!invert_jump (as_a <rtx_jump_insn *> (BB_END (b)),
+ JUMP_LABEL (BB_END (b)), 0))
+ gcc_unreachable ();
+ }
+ }
+ }
+
/* Simplify branch over branch. */
if ((mode & CLEANUP_EXPENSIVE)
&& !(mode & CLEANUP_CFGLAYOUT)
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index 21f21c97502..56ef71dfbab 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -2626,6 +2626,7 @@ expand_call_stmt (gcall *stmt)
TREE_NOTHROW (exp) = 1;
CALL_EXPR_TAILCALL (exp) = gimple_call_tail_p (stmt);
+ CALL_EXPR_MUST_TAIL_CALL (exp) = gimple_call_must_tail_p (stmt);
CALL_EXPR_RETURN_SLOT_OPT (exp) = gimple_call_return_slot_opt_p (stmt);
if (decl
&& DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL
@@ -4473,7 +4474,7 @@ expand_debug_expr (tree exp)
{
HOST_WIDE_INT units
= (-bitpos + BITS_PER_UNIT - 1) / BITS_PER_UNIT;
- op0 = adjust_address_nv (op0, mode1, units);
+ op0 = adjust_address_nv (op0, mode1, -units);
bitpos += units * BITS_PER_UNIT;
}
else if (bitpos == 0 && bitsize == GET_MODE_BITSIZE (mode))
@@ -5025,6 +5026,7 @@ expand_debug_expr (tree exp)
case FIXED_CONVERT_EXPR:
case OBJ_TYPE_REF:
case WITH_SIZE_EXPR:
+ case BIT_INSERT_EXPR:
return NULL;
case DOT_PROD_EXPR:
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 54e738f20f4..173fda84ba4 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -316,8 +316,8 @@ extern void verify_loop_structure (void);
/* Loop analysis. */
extern bool just_once_each_iteration_p (const struct loop *, const_basic_block);
-gcov_type expected_loop_iterations_unbounded (const struct loop *);
-extern unsigned expected_loop_iterations (const struct loop *);
+gcov_type expected_loop_iterations_unbounded (struct loop *);
+extern unsigned expected_loop_iterations (struct loop *);
extern rtx doloop_condition_get (rtx);
void mark_loop_for_removal (loop_p);
diff --git a/gcc/cfgloopanal.c b/gcc/cfgloopanal.c
index 4d35820b729..938ac43879a 100644
--- a/gcc/cfgloopanal.c
+++ b/gcc/cfgloopanal.c
@@ -231,14 +231,20 @@ average_num_loop_insns (const struct loop *loop)
value. */
gcov_type
-expected_loop_iterations_unbounded (const struct loop *loop)
+expected_loop_iterations_unbounded (struct loop *loop)
{
edge e;
edge_iterator ei;
-
- if (loop->latch->count || loop->header->count)
+ gcov_type expected;
+
+
+ /* Average loop rolls about 3 times. If we have no profile at all, it is
+ best we can do. */
+ if (profile_status_for_fn (cfun) == PROFILE_ABSENT)
+ expected = 3;
+ else if (loop->latch->count || loop->header->count)
{
- gcov_type count_in, count_latch, expected;
+ gcov_type count_in, count_latch;
count_in = 0;
count_latch = 0;
@@ -253,8 +259,6 @@ expected_loop_iterations_unbounded (const struct loop *loop)
expected = count_latch * 2;
else
expected = (count_latch + count_in - 1) / count_in;
-
- return expected;
}
else
{
@@ -270,17 +274,28 @@ expected_loop_iterations_unbounded (const struct loop *loop)
freq_in += EDGE_FREQUENCY (e);
if (freq_in == 0)
- return freq_latch * 2;
-
- return (freq_latch + freq_in - 1) / freq_in;
+ {
+ /* If we have no profile at all, expect 3 iterations. */
+ if (!freq_latch)
+ expected = 3;
+ else
+ expected = freq_latch * 2;
+ }
+ else
+ expected = (freq_latch + freq_in - 1) / freq_in;
}
+
+ HOST_WIDE_INT max = get_max_loop_iterations_int (loop);
+ if (max != -1 && max < expected)
+ return max;
+ return expected;
}
/* Returns expected number of LOOP iterations. The returned value is bounded
by REG_BR_PROB_BASE. */
unsigned
-expected_loop_iterations (const struct loop *loop)
+expected_loop_iterations (struct loop *loop)
{
gcov_type expected = expected_loop_iterations_unbounded (loop);
return (expected > REG_BR_PROB_BASE ? REG_BR_PROB_BASE : expected);
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 62b0596203f..3d8ed60c2a0 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -215,9 +215,10 @@ delete_insn (rtx uncast_insn)
}
}
-/* Like delete_insn but also purge dead edges from BB. */
+/* Like delete_insn but also purge dead edges from BB.
+ Return true if any edges are eliminated. */
-void
+bool
delete_insn_and_edges (rtx_insn *insn)
{
bool purge = false;
@@ -228,7 +229,8 @@ delete_insn_and_edges (rtx_insn *insn)
purge = true;
delete_insn (insn);
if (purge)
- purge_dead_edges (BLOCK_FOR_INSN (insn));
+ return purge_dead_edges (BLOCK_FOR_INSN (insn));
+ return false;
}
/* Unlink a chain of insns between START and FINISH, leaving notes
diff --git a/gcc/cfgrtl.h b/gcc/cfgrtl.h
index 0d880242354..d81928a6ebf 100644
--- a/gcc/cfgrtl.h
+++ b/gcc/cfgrtl.h
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3. If not see
#define GCC_CFGRTL_H
extern void delete_insn (rtx);
-extern void delete_insn_and_edges (rtx_insn *);
+extern bool delete_insn_and_edges (rtx_insn *);
extern void delete_insn_chain (rtx, rtx, bool);
extern basic_block create_basic_block_structure (rtx_insn *, rtx_insn *,
rtx_note *, basic_block);
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index d93a93988f1..cf9192f2a1b 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -859,9 +859,15 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
&& callee && callee->decl
&& !gimple_check_call_matching_types (call_stmt, callee->decl,
false))
- edge->call_stmt_cannot_inline_p = true;
+ {
+ edge->inline_failed = CIF_MISMATCHED_ARGUMENTS;
+ edge->call_stmt_cannot_inline_p = true;
+ }
else
- edge->call_stmt_cannot_inline_p = false;
+ {
+ edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
+ edge->call_stmt_cannot_inline_p = false;
+ }
edge->indirect_info = NULL;
edge->indirect_inlining_edge = 0;
@@ -1240,10 +1246,12 @@ cgraph_edge::make_direct (cgraph_node *callee)
/* Insert to callers list of the new callee. */
edge->set_callee (callee);
- if (call_stmt)
- call_stmt_cannot_inline_p
- = !gimple_check_call_matching_types (call_stmt, callee->decl,
- false);
+ if (call_stmt
+ && !gimple_check_call_matching_types (call_stmt, callee->decl, false))
+ {
+ call_stmt_cannot_inline_p = true;
+ inline_failed = CIF_MISMATCHED_ARGUMENTS;
+ }
/* We need to re-determine the inlining status of the edge. */
initialize_inline_failed (edge);
@@ -1507,7 +1515,8 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
/* If the call becomes noreturn, remove the LHS if possible. */
if (lhs
&& (gimple_call_flags (new_stmt) & ECF_NORETURN)
- && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST)
+ && TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs))) == INTEGER_CST
+ && !TREE_ADDRESSABLE (TREE_TYPE (lhs)))
{
if (TREE_CODE (lhs) == SSA_NAME)
{
@@ -1729,30 +1738,26 @@ release_function_body (tree decl)
if (fn)
{
if (fn->cfg
- || fn->gimple_df)
+ && loops_for_fn (fn))
{
- if (fn->cfg
- && loops_for_fn (fn))
- {
- fn->curr_properties &= ~PROP_loops;
- loop_optimizer_finalize (fn);
- }
- if (fn->gimple_df)
- {
- delete_tree_ssa (fn);
- delete_tree_cfg_annotations (fn);
- fn->eh = NULL;
- }
- if (fn->cfg)
- {
- gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
- gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
- clear_edges (fn);
- fn->cfg = NULL;
- }
- if (fn->value_histograms)
- free_histograms (fn);
+ fn->curr_properties &= ~PROP_loops;
+ loop_optimizer_finalize (fn);
+ }
+ if (fn->gimple_df)
+ {
+ delete_tree_ssa (fn);
+ fn->eh = NULL;
}
+ if (fn->cfg)
+ {
+ gcc_assert (!dom_info_available_p (fn, CDI_DOMINATORS));
+ gcc_assert (!dom_info_available_p (fn, CDI_POST_DOMINATORS));
+ delete_tree_cfg_annotations (fn);
+ clear_edges (fn);
+ fn->cfg = NULL;
+ }
+ if (fn->value_histograms)
+ free_histograms (fn);
gimple_set_body (decl, NULL);
/* Struct function hangs a lot of data that would leak if we didn't
removed all pointers to it. */
@@ -2000,6 +2005,8 @@ cgraph_edge::dump_edge_flags (FILE *f)
fprintf (f, "(speculative) ");
if (!inline_failed)
fprintf (f, "(inlined) ");
+ if (call_stmt_cannot_inline_p)
+ fprintf (f, "(call_stmt_cannot_inline_p) ");
if (indirect_inlining_edge)
fprintf (f, "(indirect_inlining) ");
if (count)
@@ -2283,7 +2290,7 @@ cgraph_node::can_be_local_p (void)
}
/* Call callback on cgraph_node, thunks and aliases associated to cgraph_node.
- When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+ When INCLUDE_OVERWRITABLE is false, overwritable symbols are
skipped. When EXCLUDE_VIRTUAL_THUNKS is true, virtual thunks are
skipped. */
bool
@@ -2295,9 +2302,14 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
{
cgraph_edge *e;
ipa_ref *ref;
+ enum availability avail = AVAIL_AVAILABLE;
- if (callback (this, data))
- return true;
+ if (include_overwritable
+ || (avail = get_availability ()) > AVAIL_INTERPOSABLE)
+ {
+ if (callback (this, data))
+ return true;
+ }
FOR_EACH_ALIAS (this, ref)
{
cgraph_node *alias = dyn_cast <cgraph_node *> (ref->referring);
@@ -2308,7 +2320,7 @@ cgraph_node::call_for_symbol_thunks_and_aliases (bool (*callback)
exclude_virtual_thunks))
return true;
}
- if (get_availability () <= AVAIL_INTERPOSABLE)
+ if (avail <= AVAIL_INTERPOSABLE)
return false;
for (e = callers; e; e = e->next_caller)
if (e->caller->thunk.thunk_p
@@ -3313,7 +3325,7 @@ cgraph_node::verify_node (void)
error ("More than one edge out of thunk node");
error_found = true;
}
- if (gimple_has_body_p (decl))
+ if (gimple_has_body_p (decl) && !global.inlined_to)
{
error ("Thunk is not supposed to have body");
error_found = true;
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 5ce032e1e57..ecafe63a536 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1579,9 +1579,14 @@ struct GTY(()) cgraph_indirect_call_info
unsigned agg_contents : 1;
/* Set when this is a call through a member pointer. */
unsigned member_ptr : 1;
- /* When the previous bit is set, this one determines whether the destination
- is loaded from a parameter passed by reference. */
+ /* When the agg_contents bit is set, this one determines whether the
+ destination is loaded from a parameter passed by reference. */
unsigned by_ref : 1;
+ /* When the agg_contents bit is set, this one determines whether we can
+ deduce from the function body that the loaded value from the reference is
+ never modified between the invocation of the function and the load
+ point. */
+ unsigned guaranteed_unmodified : 1;
/* For polymorphic calls this specify whether the virtual table pointer
may have changed in between function entry and the call. */
unsigned vptr_changed : 1;
@@ -2299,6 +2304,7 @@ void cgraphunit_c_finalize (void);
IN_SSA is true if the gimple is in SSA. */
basic_block init_lowered_empty_function (tree, bool, gcov_type);
+tree thunk_adjust (gimple_stmt_iterator *, tree, bool, HOST_WIDE_INT, tree);
/* In cgraphclones.c */
tree clone_function_name_1 (const char *, const char *);
@@ -3096,8 +3102,7 @@ symtab_node::get_availability (symtab_node *ref)
}
/* Call calback on symtab node and aliases associated to this node.
- When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
- skipped. */
+ When INCLUDE_OVERWRITABLE is false, overwritable symbols are skipped. */
inline bool
symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
@@ -3105,15 +3110,19 @@ symtab_node::call_for_symbol_and_aliases (bool (*callback) (symtab_node *,
void *data,
bool include_overwritable)
{
- if (callback (this, data))
- return true;
+ if (include_overwritable
+ || get_availability () > AVAIL_INTERPOSABLE)
+ {
+ if (callback (this, data))
+ return true;
+ }
if (has_aliases_p ())
return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
return false;
}
/* Call callback on function and aliases associated to the function.
- When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+ When INCLUDE_OVERWRITABLE is false, overwritable symbols are
skipped. */
inline bool
@@ -3122,15 +3131,19 @@ cgraph_node::call_for_symbol_and_aliases (bool (*callback) (cgraph_node *,
void *data,
bool include_overwritable)
{
- if (callback (this, data))
- return true;
+ if (include_overwritable
+ || get_availability () > AVAIL_INTERPOSABLE)
+ {
+ if (callback (this, data))
+ return true;
+ }
if (has_aliases_p ())
return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
return false;
}
/* Call calback on varpool symbol and aliases associated to varpool symbol.
- When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+ When INCLUDE_OVERWRITABLE is false, overwritable symbols are
skipped. */
inline bool
@@ -3139,8 +3152,12 @@ varpool_node::call_for_symbol_and_aliases (bool (*callback) (varpool_node *,
void *data,
bool include_overwritable)
{
- if (callback (this, data))
- return true;
+ if (include_overwritable
+ || get_availability () > AVAIL_INTERPOSABLE)
+ {
+ if (callback (this, data))
+ return true;
+ }
if (has_aliases_p ())
return call_for_symbol_and_aliases_1 (callback, data, include_overwritable);
return false;
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 07ceb1a80d4..686c2890021 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -337,7 +337,6 @@ duplicate_thunk_for_node (cgraph_node *thunk, cgraph_node *node)
cgraph_edge *e = new_thunk->create_edge (node, NULL, 0,
CGRAPH_FREQ_BASE);
- e->call_stmt_cannot_inline_p = true;
symtab->call_edge_duplication_hooks (thunk->callees, e);
symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
return new_thunk;
@@ -435,6 +434,7 @@ cgraph_node::create_clone (tree new_decl, gcov_type gcov_count, int freq,
new_node->tm_clone = tm_clone;
new_node->icf_merged = icf_merged;
new_node->merged_comdat = merged_comdat;
+ new_node->thunk = thunk;
new_node->clone.tree_map = NULL;
new_node->clone.args_to_skip = args_to_skip;
@@ -771,33 +771,35 @@ cgraph_node::create_edge_including_clones (cgraph_node *callee,
node = clones;
if (node)
while (node != this)
- {
- cgraph_edge *edge = node->get_edge (old_stmt);
-
- /* It is possible that clones already contain the edge while
- master didn't. Either we promoted indirect call into direct
- call in the clone or we are processing clones of unreachable
- master where edges has been removed. */
- if (edge)
- edge->set_call_stmt (stmt);
- else if (! node->get_edge (stmt))
- {
- edge = node->create_edge (callee, stmt, count, freq);
- edge->inline_failed = reason;
- }
+ /* Thunk clones do not get updated while copying inline function body. */
+ if (!node->thunk.thunk_p)
+ {
+ cgraph_edge *edge = node->get_edge (old_stmt);
+
+ /* It is possible that clones already contain the edge while
+ master didn't. Either we promoted indirect call into direct
+ call in the clone or we are processing clones of unreachable
+ master where edges has been removed. */
+ if (edge)
+ edge->set_call_stmt (stmt);
+ else if (! node->get_edge (stmt))
+ {
+ edge = node->create_edge (callee, stmt, count, freq);
+ edge->inline_failed = reason;
+ }
- if (node->clones)
- node = node->clones;
- else if (node->next_sibling_clone)
- node = node->next_sibling_clone;
- else
- {
- while (node != this && !node->next_sibling_clone)
- node = node->clone_of;
- if (node != this)
- node = node->next_sibling_clone;
- }
- }
+ if (node->clones)
+ node = node->clones;
+ else if (node->next_sibling_clone)
+ node = node->next_sibling_clone;
+ else
+ {
+ while (node != this && !node->next_sibling_clone)
+ node = node->clone_of;
+ if (node != this)
+ node = node->next_sibling_clone;
+ }
+ }
}
/* Remove the node from cgraph and all inline clones inlined into it.
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 4351ae49952..4bfcad78f59 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -1428,10 +1428,10 @@ init_lowered_empty_function (tree decl, bool in_ssa, gcov_type count)
allocate_struct_function (decl, false);
gimple_register_cfg_hooks ();
init_empty_tree_cfg ();
+ init_tree_ssa (cfun);
if (in_ssa)
{
- init_tree_ssa (cfun);
init_ssa_operands (cfun);
cfun->gimple_df->in_ssa_p = true;
cfun->curr_properties |= PROP_ssa;
@@ -1471,7 +1471,7 @@ init_lowered_empty_function (tree decl, bool in_ssa, gcov_type count)
non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and
zero for a result adjusting thunk. */
-static tree
+tree
thunk_adjust (gimple_stmt_iterator * bsi,
tree ptr, bool this_adjusting,
HOST_WIDE_INT fixed_offset, tree virtual_offset)
@@ -1907,6 +1907,7 @@ cgraph_node::assemble_thunks_and_aliases (void)
for (e = callers; e;)
if (e->caller->thunk.thunk_p
+ && !e->caller->global.inlined_to
&& !e->caller->thunk.add_pointer_bounds_args)
{
cgraph_node *thunk = e->caller;
diff --git a/gcc/cif-code.def b/gcc/cif-code.def
index 050388b5a63..b5e019ffb7b 100644
--- a/gcc/cif-code.def
+++ b/gcc/cif-code.def
@@ -91,6 +91,10 @@ DEFCIFCODE(NOT_DECLARED_INLINED, CIF_FINAL_NORMAL,
DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FINAL_ERROR,
N_("mismatched arguments"))
+/* Caller and callee disagree on the arguments. */
+DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR,
+ N_("mismatched declarations during linktime optimization"))
+
/* Call was originally indirect. */
DEFCIFCODE(ORIGINALLY_INDIRECT_CALL, CIF_FINAL_NORMAL,
N_("originally indirect function call not considered for inlining"))
@@ -131,3 +135,7 @@ DEFCIFCODE(CILK_SPAWN, CIF_FINAL_ERROR,
/* We proved that the call is unreachable. */
DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR,
N_("unreachable"))
+
+/* We can't inline because of instrumentation thunk. */
+DEFCIFCODE(CHKP, CIF_FINAL_ERROR,
+ N_("caller is instrumetnation thunk"))
diff --git a/gcc/combine.c b/gcc/combine.c
index 1d0e8beeb2c..cd864ccb0d4 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -6736,7 +6736,7 @@ simplify_set (rtx x)
+ (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))
&& (WORD_REGISTER_OPERATIONS
|| (GET_MODE_SIZE (GET_MODE (src))
- < GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
+ <= GET_MODE_SIZE (GET_MODE (SUBREG_REG (src)))))
#ifdef CANNOT_CHANGE_MODE_CLASS
&& ! (REG_P (dest) && REGNO (dest) < FIRST_PSEUDO_REGISTER
&& REG_CANNOT_CHANGE_MODE_P (REGNO (dest),
@@ -8037,6 +8037,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& ! (GET_CODE (lhs) == SUBREG
&& (OBJECT_P (SUBREG_REG (lhs))))
&& CONST_INT_P (rhs)
+ && INTVAL (rhs) >= 0
&& INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
&& INTVAL (rhs) < mode_width
&& (new_rtx = extract_left_shift (lhs, INTVAL (rhs))) != 0)
@@ -11096,6 +11097,7 @@ change_zero_ext (rtx *src)
XEXP (x, 0), GEN_INT (start));
}
else if (GET_CODE (x) == ZERO_EXTEND
+ && SCALAR_INT_MODE_P (mode)
&& GET_CODE (XEXP (x, 0)) == SUBREG
&& GET_MODE (SUBREG_REG (XEXP (x, 0))) == mode
&& subreg_lowpart_p (XEXP (x, 0)))
@@ -11106,11 +11108,8 @@ change_zero_ext (rtx *src)
else
continue;
- unsigned HOST_WIDE_INT mask = 1;
- mask <<= size;
- mask--;
-
- x = gen_rtx_AND (mode, x, GEN_INT (mask));
+ wide_int mask = wi::mask (size, false, GET_MODE_PRECISION (mode));
+ x = gen_rtx_AND (mode, x, immed_wide_int_const (mask, mode));
SUBST (**iter, x);
changed = true;
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 4e98df76cfe..51af122aafb 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -427,7 +427,7 @@ microblaze*-*-*)
;;
mips*-*-*)
cpu_type=mips
- extra_headers="loongson.h"
+ extra_headers="loongson.h msa.h"
extra_objs="frame-header-opt.o"
extra_options="${extra_options} g.opt fused-madd.opt mips/mips-tables.opt"
;;
@@ -3765,38 +3765,40 @@ case "${target}" in
# Add extra multilibs
if test "x$with_multilib_list" != x; then
arm_multilibs=`echo $with_multilib_list | sed -e 's/,/ /g'`
- for arm_multilib in ${arm_multilibs}; do
- case ${arm_multilib} in
- aprofile)
+ case ${arm_multilibs} in
+ aprofile)
# Note that arm/t-aprofile is a
# stand-alone make file fragment to be
# used only with itself. We do not
# specifically use the
# TM_MULTILIB_OPTION framework because
# this shorthand is more
- # pragmatic. Additionally it is only
- # designed to work without any
- # with-cpu, with-arch with-mode
+ # pragmatic.
+ tmake_profile_file="arm/t-aprofile"
+ ;;
+ default)
+ ;;
+ *)
+ echo "Error: --with-multilib-list=${with_multilib_list} not supported." 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test "x${tmake_profile_file}" != x ; then
+ # arm/t-aprofile is only designed to work
+ # without any with-cpu, with-arch, with-mode,
# with-fpu or with-float options.
- if test "x$with_arch" != x \
- || test "x$with_cpu" != x \
- || test "x$with_float" != x \
- || test "x$with_fpu" != x \
- || test "x$with_mode" != x ; then
- echo "Error: You cannot use any of --with-arch/cpu/fpu/float/mode with --with-multilib-list=aprofile" 1>&2
- exit 1
- fi
- tmake_file="${tmake_file} arm/t-aprofile"
- break
- ;;
- default)
- ;;
- *)
- echo "Error: --with-multilib-list=${with_multilib_list} not supported." 1>&2
- exit 1
- ;;
- esac
- done
+ if test "x$with_arch" != x \
+ || test "x$with_cpu" != x \
+ || test "x$with_float" != x \
+ || test "x$with_fpu" != x \
+ || test "x$with_mode" != x ; then
+ echo "Error: You cannot use any of --with-arch/cpu/fpu/float/mode with --with-multilib-list=${with_multilib_list}" 1>&2
+ exit 1
+ fi
+
+ tmake_file="${tmake_file} ${tmake_profile_file}"
+ fi
fi
;;
diff --git a/gcc/config.in b/gcc/config.in
index bdde25fe12f..39d1e7524f8 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -234,6 +234,12 @@
#endif
+/* Define 0/1 if vtable verification feature is enabled. */
+#ifndef USED_FOR_TARGET
+#undef ENABLE_VTABLE_VERIFY
+#endif
+
+
/* Define to 1 if installation paths should be looked up in the Windows
Registry. Ignored on non-Windows hosts. */
#ifndef USED_FOR_TARGET
diff --git a/gcc/config/aarch64/aarch64-elf.h b/gcc/config/aarch64/aarch64-elf.h
index 66c0bb27c5b..1fbee6fdaab 100644
--- a/gcc/config/aarch64/aarch64-elf.h
+++ b/gcc/config/aarch64/aarch64-elf.h
@@ -25,15 +25,6 @@
#define ASM_OUTPUT_LABELREF(FILE, NAME) \
aarch64_asm_output_labelref (FILE, NAME)
-#define ASM_OUTPUT_DEF(FILE, NAME1, NAME2) \
- do \
- { \
- assemble_name (FILE, NAME1); \
- fputs (" = ", FILE); \
- assemble_name (FILE, NAME2); \
- fputc ('\n', FILE); \
- } while (0)
-
#define TEXT_SECTION_ASM_OP "\t.text"
#define DATA_SECTION_ASM_OP "\t.data"
#define BSS_SECTION_ASM_OP "\t.bss"
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index f22a31c2830..6a8a8506738 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -339,7 +339,6 @@ int aarch64_simd_attr_length_move (rtx_insn *);
int aarch64_uxt_size (int, HOST_WIDE_INT);
int aarch64_vec_fpconst_pow_of_2 (rtx);
rtx aarch64_final_eh_return_addr (void);
-rtx aarch64_legitimize_reload_address (rtx *, machine_mode, int, int, int);
rtx aarch64_mask_from_zextract_ops (rtx, rtx);
const char *aarch64_output_move_struct (rtx *operands);
rtx aarch64_return_addr (int, rtx);
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index bd73bce6441..59a578f5937 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -371,15 +371,15 @@
[(set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")]
)
-(define_insn "*aarch64_mul3_elt_to_128df"
- [(set (match_operand:V2DF 0 "register_operand" "=w")
- (mult:V2DF
- (vec_duplicate:V2DF
- (match_operand:DF 2 "register_operand" "w"))
- (match_operand:V2DF 1 "register_operand" "w")))]
+(define_insn "*aarch64_mul3_elt_from_dup<mode>"
+ [(set (match_operand:VMUL 0 "register_operand" "=w")
+ (mult:VMUL
+ (vec_duplicate:VMUL
+ (match_operand:<VEL> 1 "register_operand" "<h_con>"))
+ (match_operand:VMUL 2 "register_operand" "w")))]
"TARGET_SIMD"
- "fmul\\t%0.2d, %1.2d, %2.d[0]"
- [(set_attr "type" "neon_fp_mul_d_scalar_q")]
+ "<f>mul\t%0.<Vtype>, %2.<Vtype>, %1.<Vetype>[0]";
+ [(set_attr "type" "neon<fp>_mul_<Vetype>_scalar<q>")]
)
(define_insn "aarch64_rsqrte_<mode>2"
@@ -1579,16 +1579,16 @@
[(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
)
-(define_insn "*aarch64_fma4_elt_to_128df"
- [(set (match_operand:V2DF 0 "register_operand" "=w")
- (fma:V2DF
- (vec_duplicate:V2DF
- (match_operand:DF 1 "register_operand" "w"))
- (match_operand:V2DF 2 "register_operand" "w")
- (match_operand:V2DF 3 "register_operand" "0")))]
+(define_insn "*aarch64_fma4_elt_from_dup<mode>"
+ [(set (match_operand:VMUL 0 "register_operand" "=w")
+ (fma:VMUL
+ (vec_duplicate:VMUL
+ (match_operand:<VEL> 1 "register_operand" "w"))
+ (match_operand:VMUL 2 "register_operand" "w")
+ (match_operand:VMUL 3 "register_operand" "0")))]
"TARGET_SIMD"
- "fmla\\t%0.2d, %2.2d, %1.2d[0]"
- [(set_attr "type" "neon_fp_mla_d_scalar_q")]
+ "fmla\t%0.<Vtype>, %2.<Vtype>, %1.<Vetype>[0]"
+ [(set_attr "type" "neon<fp>_mla_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_fma4_elt_to_64v2df"
@@ -1656,17 +1656,17 @@
[(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
)
-(define_insn "*aarch64_fnma4_elt_to_128df"
- [(set (match_operand:V2DF 0 "register_operand" "=w")
- (fma:V2DF
- (neg:V2DF
- (match_operand:V2DF 2 "register_operand" "w"))
- (vec_duplicate:V2DF
- (match_operand:DF 1 "register_operand" "w"))
- (match_operand:V2DF 3 "register_operand" "0")))]
- "TARGET_SIMD"
- "fmls\\t%0.2d, %2.2d, %1.2d[0]"
- [(set_attr "type" "neon_fp_mla_d_scalar_q")]
+(define_insn "*aarch64_fnma4_elt_from_dup<mode>"
+ [(set (match_operand:VMUL 0 "register_operand" "=w")
+ (fma:VMUL
+ (neg:VMUL
+ (match_operand:VMUL 2 "register_operand" "w"))
+ (vec_duplicate:VMUL
+ (match_operand:<VEL> 1 "register_operand" "w"))
+ (match_operand:VMUL 3 "register_operand" "0")))]
+ "TARGET_SIMD"
+ "fmls\t%0.<Vtype>, %2.<Vtype>, %1.<Vetype>[0]"
+ [(set_attr "type" "neon<fp>_mla_<Vetype>_scalar<q>")]
)
(define_insn "*aarch64_fnma4_elt_to_64v2df"
@@ -1919,16 +1919,6 @@
}
)
-(define_insn "aarch64_vmls<mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (minus:VDQF (match_operand:VDQF 1 "register_operand" "0")
- (mult:VDQF (match_operand:VDQF 2 "register_operand" "w")
- (match_operand:VDQF 3 "register_operand" "w"))))]
- "TARGET_SIMD"
- "fmls\\t%0.<Vtype>, %2.<Vtype>, %3.<Vtype>"
- [(set_attr "type" "neon_fp_mla_<Vetype>_scalar<q>")]
-)
-
;; FP Max/Min
;; Max/Min are introduced by idiom recognition by GCC's mid-end. An
;; expression like:
@@ -1989,19 +1979,6 @@
}
)
-(define_expand "reduc_plus_scal_<mode>"
- [(match_operand:<VEL> 0 "register_operand" "=w")
- (match_operand:V2F 1 "register_operand" "w")]
- "TARGET_SIMD"
- {
- rtx elt = GEN_INT (ENDIAN_LANE_N (<MODE>mode, 0));
- rtx scratch = gen_reg_rtx (<MODE>mode);
- emit_insn (gen_aarch64_reduc_plus_internal<mode> (scratch, operands[1]));
- emit_insn (gen_aarch64_get_lane<mode> (operands[0], scratch, elt));
- DONE;
- }
-)
-
(define_insn "aarch64_reduc_plus_internal<mode>"
[(set (match_operand:VDQV 0 "register_operand" "=w")
(unspec:VDQV [(match_operand:VDQV 1 "register_operand" "w")]
@@ -2020,9 +1997,9 @@
[(set_attr "type" "neon_reduc_add")]
)
-(define_insn "aarch64_reduc_plus_internal<mode>"
- [(set (match_operand:V2F 0 "register_operand" "=w")
- (unspec:V2F [(match_operand:V2F 1 "register_operand" "w")]
+(define_insn "reduc_plus_scal_<mode>"
+ [(set (match_operand:<VEL> 0 "register_operand" "=w")
+ (unspec:<VEL> [(match_operand:V2F 1 "register_operand" "w")]
UNSPEC_FADDV))]
"TARGET_SIMD"
"faddp\\t%<Vetype>0, %1.<Vtype>"
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 999549426e6..bd45a7d0620 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -663,16 +663,6 @@ struct aarch64_option_extension
const unsigned long flags_off;
};
-/* ISA extensions in AArch64. */
-static const struct aarch64_option_extension all_extensions[] =
-{
-#define AARCH64_OPT_EXTENSION(NAME, X, FLAGS_ON, FLAGS_OFF, FEATURE_STRING) \
- {NAME, FLAGS_ON, FLAGS_OFF},
-#include "aarch64-option-extensions.def"
-#undef AARCH64_OPT_EXTENSION
- {NULL, 0, 0}
-};
-
typedef enum aarch64_cond_code
{
AARCH64_EQ = 0, AARCH64_NE, AARCH64_CS, AARCH64_CC, AARCH64_MI, AARCH64_PL,
@@ -5022,120 +5012,6 @@ aarch64_legitimize_address (rtx x, rtx /* orig_x */, machine_mode mode)
return x;
}
-/* Try a machine-dependent way of reloading an illegitimate address
- operand. If we find one, push the reload and return the new rtx. */
-
-rtx
-aarch64_legitimize_reload_address (rtx *x_p,
- machine_mode mode,
- int opnum, int type,
- int ind_levels ATTRIBUTE_UNUSED)
-{
- rtx x = *x_p;
-
- /* Do not allow mem (plus (reg, const)) if vector struct mode. */
- if (aarch64_vect_struct_mode_p (mode)
- && GET_CODE (x) == PLUS
- && REG_P (XEXP (x, 0))
- && CONST_INT_P (XEXP (x, 1)))
- {
- rtx orig_rtx = x;
- x = copy_rtx (x);
- push_reload (orig_rtx, NULL_RTX, x_p, NULL,
- BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
- opnum, (enum reload_type) type);
- return x;
- }
-
- /* We must recognize output that we have already generated ourselves. */
- if (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 0)) == PLUS
- && REG_P (XEXP (XEXP (x, 0), 0))
- && CONST_INT_P (XEXP (XEXP (x, 0), 1))
- && CONST_INT_P (XEXP (x, 1)))
- {
- push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
- BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
- opnum, (enum reload_type) type);
- return x;
- }
-
- /* We wish to handle large displacements off a base register by splitting
- the addend across an add and the mem insn. This can cut the number of
- extra insns needed from 3 to 1. It is only useful for load/store of a
- single register with 12 bit offset field. */
- if (GET_CODE (x) == PLUS
- && REG_P (XEXP (x, 0))
- && CONST_INT_P (XEXP (x, 1))
- && HARD_REGISTER_P (XEXP (x, 0))
- && mode != TImode
- && mode != TFmode
- && aarch64_regno_ok_for_base_p (REGNO (XEXP (x, 0)), true))
- {
- HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
- HOST_WIDE_INT low = val & 0xfff;
- HOST_WIDE_INT high = val - low;
- HOST_WIDE_INT offs;
- rtx cst;
- machine_mode xmode = GET_MODE (x);
-
- /* In ILP32, xmode can be either DImode or SImode. */
- gcc_assert (xmode == DImode || xmode == SImode);
-
- /* Reload non-zero BLKmode offsets. This is because we cannot ascertain
- BLKmode alignment. */
- if (GET_MODE_SIZE (mode) == 0)
- return NULL_RTX;
-
- offs = low % GET_MODE_SIZE (mode);
-
- /* Align misaligned offset by adjusting high part to compensate. */
- if (offs != 0)
- {
- if (aarch64_uimm12_shift (high + offs))
- {
- /* Align down. */
- low = low - offs;
- high = high + offs;
- }
- else
- {
- /* Align up. */
- offs = GET_MODE_SIZE (mode) - offs;
- low = low + offs;
- high = high + (low & 0x1000) - offs;
- low &= 0xfff;
- }
- }
-
- /* Check for overflow. */
- if (high + low != val)
- return NULL_RTX;
-
- cst = GEN_INT (high);
- if (!aarch64_uimm12_shift (high))
- cst = force_const_mem (xmode, cst);
-
- /* Reload high part into base reg, leaving the low part
- in the mem instruction.
- Note that replacing this gen_rtx_PLUS with plus_constant is
- wrong in this case because we rely on the
- (plus (plus reg c1) c2) structure being preserved so that
- XEXP (*p, 0) in push_reload below uses the correct term. */
- x = gen_rtx_PLUS (xmode,
- gen_rtx_PLUS (xmode, XEXP (x, 0), cst),
- GEN_INT (low));
-
- push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
- BASE_REG_CLASS, xmode, VOIDmode, 0, 0,
- opnum, (enum reload_type) type);
- return x;
- }
-
- return NULL_RTX;
-}
-
-
/* Return the reload icode required for a constant pool in mode. */
static enum insn_code
aarch64_constant_pool_reload_icode (machine_mode mode)
@@ -11959,12 +11835,11 @@ aarch64_output_simd_mov_immediate (rtx const_vector,
info.value = GEN_INT (0);
else
{
-#define buf_size 20
+ const unsigned int buf_size = 20;
char float_buf[buf_size] = {'\0'};
real_to_decimal_for_mode (float_buf,
CONST_DOUBLE_REAL_VALUE (info.value),
buf_size, buf_size, 1, mode);
-#undef buf_size
if (lane_count == 1)
snprintf (templ, sizeof (templ), "fmov\t%%d0, %s", float_buf);
@@ -14232,6 +14107,9 @@ aarch64_optab_supported_p (int op, machine_mode, machine_mode,
#undef TARGET_OPTAB_SUPPORTED_P
#define TARGET_OPTAB_SUPPORTED_P aarch64_optab_supported_p
+#undef TARGET_OMIT_STRUCT_RETURN_REG
+#define TARGET_OMIT_STRUCT_RETURN_REG true
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-aarch64.h"
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 4135da1becd..fa941b6c9f1 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -652,21 +652,6 @@ typedef struct
#define CONSTANT_ADDRESS_P(X) aarch64_constant_address_p(X)
-/* Try a machine-dependent way of reloading an illegitimate address
- operand. If we find one, push the reload and jump to WIN. This
- macro is used in only one place: `find_reloads_address' in reload.c. */
-
-#define LEGITIMIZE_RELOAD_ADDRESS(X, MODE, OPNUM, TYPE, IND_L, WIN) \
-do { \
- rtx new_x = aarch64_legitimize_reload_address (&(X), MODE, OPNUM, TYPE, \
- IND_L); \
- if (new_x) \
- { \
- X = new_x; \
- goto WIN; \
- } \
-} while (0)
-
#define REGNO_OK_FOR_BASE_P(REGNO) \
aarch64_regno_ok_for_base_p (REGNO, true)
@@ -850,7 +835,7 @@ do { \
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
aarch64_cannot_change_mode_class (FROM, TO, CLASS)
-#define SHIFT_COUNT_TRUNCATED !TARGET_SIMD
+#define SHIFT_COUNT_TRUNCATED (!TARGET_SIMD)
/* Choose appropriate mode for caller saves, so we do the minimum
required size of load/store. */
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 9b282f13388..223a4cc6d31 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -1786,7 +1786,7 @@
"aarch64_zero_extend_const_eq (<DWI>mode, operands[2],
<MODE>mode, operands[1])"
"@
- cmn\\t%<w>0, %<w>1
+ cmn\\t%<w>0, %1
cmp\\t%<w>0, #%n1"
[(set_attr "type" "alus_imm")]
)
@@ -1818,11 +1818,11 @@
"aarch64_zero_extend_const_eq (<DWI>mode, operands[3],
<MODE>mode, operands[2])"
"@
- adds\\t%<w>0, %<w>1, %<w>2
+ adds\\t%<w>0, %<w>1, %2
subs\\t%<w>0, %<w>1, #%n2"
[(set_attr "type" "alus_imm")]
)
-
+
(define_insn "add<mode>3_compareC"
[(set (reg:CC_C CC_REGNUM)
(ne:CC_C
@@ -3425,7 +3425,9 @@
(LOGICAL:SI (match_operand:SI 1 "register_operand" "%r,r")
(match_operand:SI 2 "aarch64_logical_operand" "r,K"))))]
""
- "<logical>\\t%w0, %w1, %w2"
+ "@
+ <logical>\\t%w0, %w1, %w2
+ <logical>\\t%w0, %w1, %2"
[(set_attr "type" "logic_reg,logic_imm")]
)
@@ -3438,7 +3440,9 @@
(set (match_operand:GPI 0 "register_operand" "=r,r")
(and:GPI (match_dup 1) (match_dup 2)))]
""
- "ands\\t%<w>0, %<w>1, %<w>2"
+ "@
+ ands\\t%<w>0, %<w>1, %<w>2
+ ands\\t%<w>0, %<w>1, %2"
[(set_attr "type" "logics_reg,logics_imm")]
)
@@ -3452,7 +3456,9 @@
(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
""
- "ands\\t%w0, %w1, %w2"
+ "@
+ ands\\t%w0, %w1, %w2
+ ands\\t%w0, %w1, %2"
[(set_attr "type" "logics_reg,logics_imm")]
)
@@ -3806,7 +3812,9 @@
(match_operand:GPI 1 "aarch64_logical_operand" "r,<lconst>"))
(const_int 0)))]
""
- "tst\\t%<w>0, %<w>1"
+ "@
+ tst\\t%<w>0, %<w>1
+ tst\\t%<w>0, %1"
[(set_attr "type" "logics_reg,logics_imm")]
)
@@ -3936,33 +3944,35 @@
;; Logical left shift using SISD or Integer instruction
(define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
- [(set (match_operand:GPI 0 "register_operand" "=r,w,w")
- (ashift:GPI
- (match_operand:GPI 1 "register_operand" "r,w,w")
- (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>,Us<cmode>,w")))]
+ [(set (match_operand:GPI 0 "register_operand" "=r,r,w,w")
+ (ashift:GPI
+ (match_operand:GPI 1 "register_operand" "r,r,w,w")
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,r,Us<cmode>,w")))]
""
"@
+ lsl\t%<w>0, %<w>1, %2
lsl\t%<w>0, %<w>1, %<w>2
shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>"
- [(set_attr "simd" "no,yes,yes")
- (set_attr "type" "shift_reg,neon_shift_imm<q>, neon_shift_reg<q>")]
+ [(set_attr "simd" "no,no,yes,yes")
+ (set_attr "type" "bfm,shift_reg,neon_shift_imm<q>, neon_shift_reg<q>")]
)
;; Logical right shift using SISD or Integer instruction
(define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
- [(set (match_operand:GPI 0 "register_operand" "=r,w,&w,&w")
- (lshiftrt:GPI
- (match_operand:GPI 1 "register_operand" "r,w,w,w")
- (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>,Us<cmode>,w,0")))]
+ [(set (match_operand:GPI 0 "register_operand" "=r,r,w,&w,&w")
+ (lshiftrt:GPI
+ (match_operand:GPI 1 "register_operand" "r,r,w,w,w")
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,r,Us<cmode>,w,0")))]
""
"@
+ lsr\t%<w>0, %<w>1, %2
lsr\t%<w>0, %<w>1, %<w>2
ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
#
#"
- [(set_attr "simd" "no,yes,yes,yes")
- (set_attr "type" "shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
+ [(set_attr "simd" "no,no,yes,yes,yes")
+ (set_attr "type" "bfm,shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
)
(define_split
@@ -3997,18 +4007,19 @@
;; Arithmetic right shift using SISD or Integer instruction
(define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
- [(set (match_operand:GPI 0 "register_operand" "=r,w,&w,&w")
+ [(set (match_operand:GPI 0 "register_operand" "=r,r,w,&w,&w")
(ashiftrt:GPI
- (match_operand:GPI 1 "register_operand" "r,w,w,w")
- (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "rUs<cmode>,Us<cmode>,w,0")))]
+ (match_operand:GPI 1 "register_operand" "r,r,w,w,w")
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,r,Us<cmode>,w,0")))]
""
"@
+ asr\t%<w>0, %<w>1, %2
asr\t%<w>0, %<w>1, %<w>2
sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
#
#"
- [(set_attr "simd" "no,yes,yes,yes")
- (set_attr "type" "shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
+ [(set_attr "simd" "no,no,yes,yes,yes")
+ (set_attr "type" "bfm,shift_reg,neon_shift_imm<q>,neon_shift_reg<q>,neon_shift_reg<q>")]
)
(define_split
@@ -4100,21 +4111,25 @@
[(set (match_operand:GPI 0 "register_operand" "=r,r")
(rotatert:GPI
(match_operand:GPI 1 "register_operand" "r,r")
- (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "r,Us<cmode>")))]
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,r")))]
""
- "ror\\t%<w>0, %<w>1, %<w>2"
- [(set_attr "type" "shift_reg, rotate_imm")]
+ "@
+ ror\\t%<w>0, %<w>1, %2
+ ror\\t%<w>0, %<w>1, %<w>2"
+ [(set_attr "type" "rotate_imm,shift_reg")]
)
;; zero_extend version of above
(define_insn "*<optab>si3_insn_uxtw"
- [(set (match_operand:DI 0 "register_operand" "=r")
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI (SHIFT:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "rUss"))))]
+ (match_operand:SI 1 "register_operand" "r,r")
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_si" "Uss,r"))))]
""
- "<shift>\\t%w0, %w1, %w2"
- [(set_attr "type" "shift_reg")]
+ "@
+ <shift>\\t%w0, %w1, %2
+ <shift>\\t%w0, %w1, %w2"
+ [(set_attr "type" "bfm,shift_reg")]
)
(define_insn "*<optab><mode>3_insn"
@@ -4138,7 +4153,7 @@
"UINTVAL (operands[3]) < GET_MODE_BITSIZE (<MODE>mode) &&
(UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
"extr\\t%<w>0, %<w>1, %<w>2, %4"
- [(set_attr "type" "shift_imm")]
+ [(set_attr "type" "rotate_imm")]
)
;; There are no canonicalisation rules for ashift and lshiftrt inside an ior
@@ -4153,7 +4168,7 @@
&& (UINTVAL (operands[3]) + UINTVAL (operands[4])
== GET_MODE_BITSIZE (<MODE>mode))"
"extr\\t%<w>0, %<w>1, %<w>2, %4"
- [(set_attr "type" "shift_imm")]
+ [(set_attr "type" "rotate_imm")]
)
;; zero_extend version of the above
@@ -4167,7 +4182,7 @@
"UINTVAL (operands[3]) < 32 &&
(UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
"extr\\t%w0, %w1, %w2, %4"
- [(set_attr "type" "shift_imm")]
+ [(set_attr "type" "rotate_imm")]
)
(define_insn "*extrsi5_insn_uxtw_alt"
@@ -4180,7 +4195,7 @@
"UINTVAL (operands[3]) < 32 &&
(UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
"extr\\t%w0, %w1, %w2, %4"
- [(set_attr "type" "shift_imm")]
+ [(set_attr "type" "rotate_imm")]
)
(define_insn "*ror<mode>3_insn"
@@ -5194,7 +5209,7 @@
UNSPEC_SP_TEST))
(clobber (match_scratch:PTR 3 "=&r"))]
""
- "ldr\t%<w>3, %x1\;ldr\t%<w>0, %x2\;eor\t%<w>0, %<w>3, %<w>0"
+ "ldr\t%<w>3, %1\;ldr\t%<w>0, %2\;eor\t%<w>0, %<w>3, %<w>0"
[(set_attr "length" "12")
(set_attr "type" "multiple")])
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 2612a325718..e563e3d2f77 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -7938,61 +7938,6 @@ vmovn_u64 (uint64x2_t a)
return result;
}
-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
-vmul_n_f32 (float32x2_t a, float32_t b)
-{
- float32x2_t result;
- __asm__ ("fmul %0.2s,%1.2s,%2.s[0]"
- : "=w"(result)
- : "w"(a), "w"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
-vmul_n_s16 (int16x4_t a, int16_t b)
-{
- int16x4_t result;
- __asm__ ("mul %0.4h,%1.4h,%2.h[0]"
- : "=w"(result)
- : "w"(a), "x"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
-vmul_n_s32 (int32x2_t a, int32_t b)
-{
- int32x2_t result;
- __asm__ ("mul %0.2s,%1.2s,%2.s[0]"
- : "=w"(result)
- : "w"(a), "w"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-vmul_n_u16 (uint16x4_t a, uint16_t b)
-{
- uint16x4_t result;
- __asm__ ("mul %0.4h,%1.4h,%2.h[0]"
- : "=w"(result)
- : "w"(a), "x"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
-vmul_n_u32 (uint32x2_t a, uint32_t b)
-{
- uint32x2_t result;
- __asm__ ("mul %0.2s,%1.2s,%2.s[0]"
- : "=w"(result)
- : "w"(a), "w"(b)
- : /* No clobbers */);
- return result;
-}
-
#define vmull_high_lane_s16(a, b, c) \
__extension__ \
({ \
@@ -8443,227 +8388,6 @@ vmull_u32 (uint32x2_t a, uint32x2_t b)
return result;
}
-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
-vmulq_n_f32 (float32x4_t a, float32_t b)
-{
- float32x4_t result;
- __asm__ ("fmul %0.4s,%1.4s,%2.s[0]"
- : "=w"(result)
- : "w"(a), "w"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
-vmulq_n_f64 (float64x2_t a, float64_t b)
-{
- float64x2_t result;
- __asm__ ("fmul %0.2d,%1.2d,%2.d[0]"
- : "=w"(result)
- : "w"(a), "w"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
-vmulq_n_s16 (int16x8_t a, int16_t b)
-{
- int16x8_t result;
- __asm__ ("mul %0.8h,%1.8h,%2.h[0]"
- : "=w"(result)
- : "w"(a), "x"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
-vmulq_n_s32 (int32x4_t a, int32_t b)
-{
- int32x4_t result;
- __asm__ ("mul %0.4s,%1.4s,%2.s[0]"
- : "=w"(result)
- : "w"(a), "w"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
-vmulq_n_u16 (uint16x8_t a, uint16_t b)
-{
- uint16x8_t result;
- __asm__ ("mul %0.8h,%1.8h,%2.h[0]"
- : "=w"(result)
- : "w"(a), "x"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
-vmulq_n_u32 (uint32x4_t a, uint32_t b)
-{
- uint32x4_t result;
- __asm__ ("mul %0.4s,%1.4s,%2.s[0]"
- : "=w"(result)
- : "w"(a), "w"(b)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vmvn_p8 (poly8x8_t a)
-{
- poly8x8_t result;
- __asm__ ("mvn %0.8b,%1.8b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vmvn_s8 (int8x8_t a)
-{
- int8x8_t result;
- __asm__ ("mvn %0.8b,%1.8b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
-vmvn_s16 (int16x4_t a)
-{
- int16x4_t result;
- __asm__ ("mvn %0.8b,%1.8b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
-vmvn_s32 (int32x2_t a)
-{
- int32x2_t result;
- __asm__ ("mvn %0.8b,%1.8b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vmvn_u8 (uint8x8_t a)
-{
- uint8x8_t result;
- __asm__ ("mvn %0.8b,%1.8b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-vmvn_u16 (uint16x4_t a)
-{
- uint16x4_t result;
- __asm__ ("mvn %0.8b,%1.8b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
-vmvn_u32 (uint32x2_t a)
-{
- uint32x2_t result;
- __asm__ ("mvn %0.8b,%1.8b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
-vmvnq_p8 (poly8x16_t a)
-{
- poly8x16_t result;
- __asm__ ("mvn %0.16b,%1.16b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vmvnq_s8 (int8x16_t a)
-{
- int8x16_t result;
- __asm__ ("mvn %0.16b,%1.16b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
-vmvnq_s16 (int16x8_t a)
-{
- int16x8_t result;
- __asm__ ("mvn %0.16b,%1.16b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
-vmvnq_s32 (int32x4_t a)
-{
- int32x4_t result;
- __asm__ ("mvn %0.16b,%1.16b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-vmvnq_u8 (uint8x16_t a)
-{
- uint8x16_t result;
- __asm__ ("mvn %0.16b,%1.16b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
-vmvnq_u16 (uint16x8_t a)
-{
- uint16x8_t result;
- __asm__ ("mvn %0.16b,%1.16b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
-vmvnq_u32 (uint32x4_t a)
-{
- uint32x4_t result;
- __asm__ ("mvn %0.16b,%1.16b"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-
__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
vpadal_s8 (int16x4_t a, int8x8_t b)
{
@@ -14456,6 +14180,12 @@ vfma_n_f32 (float32x2_t __a, float32x2_t __b, float32_t __c)
return __builtin_aarch64_fmav2sf (__b, vdup_n_f32 (__c), __a);
}
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vfma_n_f64 (float64x1_t __a, float64x1_t __b, float64_t __c)
+{
+ return (float64x1_t) {__b[0] * __c + __a[0]};
+}
+
__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
vfmaq_n_f32 (float32x4_t __a, float32x4_t __b, float32_t __c)
{
@@ -14597,6 +14327,29 @@ vfmsq_f64 (float64x2_t __a, float64x2_t __b, float64x2_t __c)
return __builtin_aarch64_fmav2df (-__b, __c, __a);
}
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vfms_n_f32 (float32x2_t __a, float32x2_t __b, float32_t __c)
+{
+ return __builtin_aarch64_fmav2sf (-__b, vdup_n_f32 (__c), __a);
+}
+
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vfms_n_f64 (float64x1_t __a, float64x1_t __b, float64_t __c)
+{
+ return (float64x1_t) {-__b[0] * __c + __a[0]};
+}
+
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vfmsq_n_f32 (float32x4_t __a, float32x4_t __b, float32_t __c)
+{
+ return __builtin_aarch64_fmav4sf (-__b, vdupq_n_f32 (__c), __a);
+}
+
+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+vfmsq_n_f64 (float64x2_t __a, float64x2_t __b, float64_t __c)
+{
+ return __builtin_aarch64_fmav2df (-__b, vdupq_n_f64 (__c), __a);
+}
/* vfms_lane */
@@ -18895,6 +18648,160 @@ vmulq_laneq_u32 (uint32x4_t __a, uint32x4_t __b, const int __lane)
return __a * __aarch64_vget_lane_any (__b, __lane);
}
+/* vmul_n. */
+
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vmul_n_f32 (float32x2_t __a, float32_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vmulq_n_f32 (float32x4_t __a, float32_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+vmulq_n_f64 (float64x2_t __a, float64_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vmul_n_s16 (int16x4_t __a, int16_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
+vmulq_n_s16 (int16x8_t __a, int16_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vmul_n_s32 (int32x2_t __a, int32_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vmulq_n_s32 (int32x4_t __a, int32_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vmul_n_u16 (uint16x4_t __a, uint16_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
+vmulq_n_u16 (uint16x8_t __a, uint16_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vmul_n_u32 (uint32x2_t __a, uint32_t __b)
+{
+ return __a * __b;
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vmulq_n_u32 (uint32x4_t __a, uint32_t __b)
+{
+ return __a * __b;
+}
+
+/* vmvn */
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vmvn_p8 (poly8x8_t __a)
+{
+ return (poly8x8_t) ~((int8x8_t) __a);
+}
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vmvn_s8 (int8x8_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vmvn_s16 (int16x4_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vmvn_s32 (int32x2_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vmvn_u8 (uint8x8_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vmvn_u16 (uint16x4_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vmvn_u32 (uint32x2_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
+vmvnq_p8 (poly8x16_t __a)
+{
+ return (poly8x16_t) ~((int8x16_t) __a);
+}
+
+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
+vmvnq_s8 (int8x16_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
+vmvnq_s16 (int16x8_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vmvnq_s32 (int32x4_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
+vmvnq_u8 (uint8x16_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
+vmvnq_u16 (uint16x8_t __a)
+{
+ return ~__a;
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vmvnq_u32 (uint32x4_t __a)
+{
+ return ~__a;
+}
+
/* vneg */
__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index e023d3bc278..94fed1029ba 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -9752,8 +9752,6 @@ alpha_init_libfuncs (void)
set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
- abort_libfunc = init_one_libfunc ("decc$abort");
- memcmp_libfunc = init_one_libfunc ("decc$memcmp");
#ifdef MEM_LIBFUNCS_INIT
MEM_LIBFUNCS_INIT;
#endif
diff --git a/gcc/config/alpha/alpha.md b/gcc/config/alpha/alpha.md
index 932608b0fe2..3e4594bf4c6 100644
--- a/gcc/config/alpha/alpha.md
+++ b/gcc/config/alpha/alpha.md
@@ -3738,7 +3738,8 @@
;; BUGCHK is documented common to OSF/1 and VMS PALcode.
(define_insn "trap"
- [(trap_if (const_int 1) (const_int 0))]
+ [(trap_if (const_int 1) (const_int 0))
+ (use (reg:DI 29))]
""
"call_pal 0x81"
[(set_attr "type" "callpal")])
@@ -5157,7 +5158,7 @@
"TARGET_ABI_OSF"
{
if (TARGET_EXPLICIT_RELOCS)
- return "ldah $29,0($26)\t\t!gpdisp!%*\;lda $29,0($29)\t\t!gpdisp!%*";
+ return "#";
else
return "ldgp $29,0($26)";
}
diff --git a/gcc/config/arm/arm-builtins.c b/gcc/config/arm/arm-builtins.c
index 90fb40fed24..68b2839879f 100644
--- a/gcc/config/arm/arm-builtins.c
+++ b/gcc/config/arm/arm-builtins.c
@@ -2861,6 +2861,10 @@ arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
int in_n, out_n;
bool out_unsigned_p = TYPE_UNSIGNED (type_out);
+ /* Can't provide any vectorized builtins when we can't use NEON. */
+ if (!TARGET_NEON)
+ return NULL_TREE;
+
if (TREE_CODE (type_out) != VECTOR_TYPE
|| TREE_CODE (type_in) != VECTOR_TYPE)
return NULL_TREE;
@@ -2875,7 +2879,7 @@ arm_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
NULL_TREE is returned if no such builtin is available. */
#undef ARM_CHECK_BUILTIN_MODE
#define ARM_CHECK_BUILTIN_MODE(C) \
- (TARGET_NEON && TARGET_FPU_ARMV8 \
+ (TARGET_FPU_ARMV8 \
&& flag_unsafe_math_optimizations \
&& ARM_CHECK_BUILTIN_MODE_1 (C))
diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c
index 4fbdfc50d03..b98470fff45 100644
--- a/gcc/config/arm/arm-c.c
+++ b/gcc/config/arm/arm-c.c
@@ -135,10 +135,12 @@ arm_cpu_builtins (struct cpp_reader* pfile)
else
cpp_undef (pfile, "__ARM_FP");
- if (arm_fp16_format == ARM_FP16_FORMAT_IEEE)
- builtin_define ("__ARM_FP16_FORMAT_IEEE");
- if (arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE)
- builtin_define ("__ARM_FP16_FORMAT_ALTERNATIVE");
+ def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_IEEE",
+ arm_fp16_format == ARM_FP16_FORMAT_IEEE);
+ def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_ALTERNATIVE",
+ arm_fp16_format == ARM_FP16_FORMAT_ALTERNATIVE);
+ def_or_undef_macro (pfile, "__ARM_FP16_ARGS",
+ arm_fp16_format != ARM_FP16_FORMAT_NONE);
def_or_undef_macro (pfile, "__ARM_FEATURE_FMA", TARGET_FMA);
def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 71b51439dc7..af9725b93d4 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -249,8 +249,6 @@ static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
static bool arm_output_addr_const_extra (FILE *, rtx);
static bool arm_allocate_stack_slots_for_args (void);
static bool arm_warn_func_return (tree);
-static const char *arm_invalid_parameter_type (const_tree t);
-static const char *arm_invalid_return_type (const_tree t);
static tree arm_promoted_type (const_tree t);
static tree arm_convert_to_type (tree type, tree expr);
static bool arm_scalar_mode_supported_p (machine_mode);
@@ -300,6 +298,9 @@ static void arm_canonicalize_comparison (int *code, rtx *op0, rtx *op1,
static unsigned HOST_WIDE_INT arm_asan_shadow_offset (void);
static void arm_sched_fusion_priority (rtx_insn *, int, int *, int*);
+static bool arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT,
+ const_tree);
+
/* Table of machine attributes. */
static const struct attribute_spec arm_attribute_table[] =
@@ -463,7 +464,7 @@ static const struct attribute_spec arm_attribute_table[] =
#undef TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK arm_output_mi_thunk
#undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
-#define TARGET_ASM_CAN_OUTPUT_MI_THUNK default_can_output_mi_thunk_no_vcall
+#define TARGET_ASM_CAN_OUTPUT_MI_THUNK arm_can_output_mi_thunk
#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS arm_rtx_costs
@@ -654,12 +655,6 @@ static const struct attribute_spec arm_attribute_table[] =
#undef TARGET_PREFERRED_RELOAD_CLASS
#define TARGET_PREFERRED_RELOAD_CLASS arm_preferred_reload_class
-#undef TARGET_INVALID_PARAMETER_TYPE
-#define TARGET_INVALID_PARAMETER_TYPE arm_invalid_parameter_type
-
-#undef TARGET_INVALID_RETURN_TYPE
-#define TARGET_INVALID_RETURN_TYPE arm_invalid_return_type
-
#undef TARGET_PROMOTED_TYPE
#define TARGET_PROMOTED_TYPE arm_promoted_type
@@ -5549,7 +5544,7 @@ aapcs_vfp_sub_candidate (const_tree type, machine_mode *modep)
{
case REAL_TYPE:
mode = TYPE_MODE (type);
- if (mode != DFmode && mode != SFmode)
+ if (mode != DFmode && mode != SFmode && mode != HFmode)
return -1;
if (*modep == VOIDmode)
@@ -5797,11 +5792,16 @@ aapcs_vfp_is_call_candidate (CUMULATIVE_ARGS *pcum, machine_mode mode,
&pcum->aapcs_vfp_rcount);
}
+/* Implement the allocate field in aapcs_cp_arg_layout. See the comment there
+ for the behaviour of this function. */
+
static bool
aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, machine_mode mode,
const_tree type ATTRIBUTE_UNUSED)
{
- int shift = GET_MODE_SIZE (pcum->aapcs_vfp_rmode) / GET_MODE_SIZE (SFmode);
+ int rmode_size
+ = MAX (GET_MODE_SIZE (pcum->aapcs_vfp_rmode), GET_MODE_SIZE (SFmode));
+ int shift = rmode_size / GET_MODE_SIZE (SFmode);
unsigned mask = (1 << (shift * pcum->aapcs_vfp_rcount)) - 1;
int regno;
@@ -5850,6 +5850,9 @@ aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, machine_mode mode,
return false;
}
+/* Implement the allocate_return_reg field in aapcs_cp_arg_layout. See the
+ comment there for the behaviour of this function. */
+
static rtx
aapcs_vfp_allocate_return_reg (enum arm_pcs pcs_variant ATTRIBUTE_UNUSED,
machine_mode mode,
@@ -5940,13 +5943,13 @@ static struct
required for a return from FUNCTION_ARG. */
bool (*allocate) (CUMULATIVE_ARGS *, machine_mode, const_tree);
- /* Return true if a result of mode MODE (or type TYPE if MODE is
- BLKmode) is can be returned in this co-processor's registers. */
+ /* Return true if a result of mode MODE (or type TYPE if MODE is BLKmode) can
+ be returned in this co-processor's registers. */
bool (*is_return_candidate) (enum arm_pcs, machine_mode, const_tree);
- /* Allocate and return an RTX element to hold the return type of a
- call, this routine must not fail and will only be called if
- is_return_candidate returned true with the same parameters. */
+ /* Allocate and return an RTX element to hold the return type of a call. This
+ routine must not fail and will only be called if is_return_candidate
+ returned true with the same parameters. */
rtx (*allocate_return_reg) (enum arm_pcs, machine_mode, const_tree);
/* Finish processing this argument and prepare to start processing
@@ -10759,8 +10762,6 @@ arm_new_rtx_costs (rtx x, enum rtx_code code, enum rtx_code outer_code,
if ((arm_arch4 || GET_MODE (XEXP (x, 0)) == SImode)
&& MEM_P (XEXP (x, 0)))
{
- *cost = rtx_cost (XEXP (x, 0), VOIDmode, code, 0, speed_p);
-
if (mode == DImode)
*cost += COSTS_N_INSNS (1);
@@ -17755,6 +17756,7 @@ arm_output_multireg_pop (rtx *operands, bool return_pc, rtx cond, bool reverse,
int num_saves = XVECLEN (operands[0], 0);
unsigned int regno;
unsigned int regno_base = REGNO (operands[1]);
+ bool interrupt_p = IS_INTERRUPT (arm_current_func_type ());
offset = 0;
offset += update ? 1 : 0;
@@ -17772,7 +17774,8 @@ arm_output_multireg_pop (rtx *operands, bool return_pc, rtx cond, bool reverse,
}
conditional = reverse ? "%?%D0" : "%?%d0";
- if ((regno_base == SP_REGNUM) && update)
+ /* Can't use POP if returning from an interrupt. */
+ if ((regno_base == SP_REGNUM) && !(interrupt_p && return_pc))
{
sprintf (pattern, "pop%s\t{", conditional);
}
@@ -17781,11 +17784,8 @@ arm_output_multireg_pop (rtx *operands, bool return_pc, rtx cond, bool reverse,
/* Output ldmfd when the base register is SP, otherwise output ldmia.
It's just a convention, their semantics are identical. */
if (regno_base == SP_REGNUM)
- /* update is never true here, hence there is no need to handle
- pop here. */
- sprintf (pattern, "ldmfd%s", conditional);
-
- if (update)
+ sprintf (pattern, "ldmfd%s\t", conditional);
+ else if (update)
sprintf (pattern, "ldmia%s\t", conditional);
else
sprintf (pattern, "ldm%s\t", conditional);
@@ -17811,7 +17811,7 @@ arm_output_multireg_pop (rtx *operands, bool return_pc, rtx cond, bool reverse,
strcat (pattern, "}");
- if (IS_INTERRUPT (arm_current_func_type ()) && return_pc)
+ if (interrupt_p && return_pc)
strcat (pattern, "^");
output_asm_insn (pattern, &cond);
@@ -18608,7 +18608,8 @@ output_move_vfp (rtx *operands)
gcc_assert (REG_P (reg));
gcc_assert (IS_VFP_REGNUM (REGNO (reg)));
- gcc_assert (mode == SFmode
+ gcc_assert ((mode == HFmode && TARGET_HARD_FLOAT && TARGET_VFP)
+ || mode == SFmode
|| mode == DFmode
|| mode == SImode
|| mode == DImode
@@ -19622,8 +19623,12 @@ output_return_instruction (rtx operand, bool really_return, bool reverse,
sprintf (instr, "ldmfd%s\t%%|sp, {", conditional);
}
}
+ /* For interrupt returns we have to use an LDM rather than
+ a POP so that we can use the exception return variant. */
+ else if (IS_INTERRUPT (func_type))
+ sprintf (instr, "ldmfd%s\t%%|sp!, {", conditional);
else
- sprintf (instr, "pop%s\t{", conditional);
+ sprintf (instr, "pop%s\t{", conditional);
p = instr + strlen (instr);
@@ -21461,7 +21466,11 @@ arm_expand_prologue (void)
/* Naked functions don't have prologues. */
if (IS_NAKED (func_type))
- return;
+ {
+ if (flag_stack_usage_info)
+ current_function_static_stack_size = 0;
+ return;
+ }
/* Make a copy of c_f_p_a_s as we may need to modify it locally. */
args_to_push = crtl->args.pretend_args_size;
@@ -23397,10 +23406,8 @@ arm_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
if (mode == DFmode)
return VFP_REGNO_OK_FOR_DOUBLE (regno);
- /* VFP registers can hold HFmode values, but there is no point in
- putting them there unless we have hardware conversion insns. */
if (mode == HFmode)
- return TARGET_FP16 && VFP_REGNO_OK_FOR_SINGLE (regno);
+ return VFP_REGNO_OK_FOR_SINGLE (regno);
if (TARGET_NEON)
return (VALID_NEON_DREG_MODE (mode) && VFP_REGNO_OK_FOR_DOUBLE (regno))
@@ -23604,26 +23611,6 @@ arm_debugger_arg_offset (int value, rtx addr)
return value;
}
-/* Implement TARGET_INVALID_PARAMETER_TYPE. */
-
-static const char *
-arm_invalid_parameter_type (const_tree t)
-{
- if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
- return N_("function parameters cannot have __fp16 type");
- return NULL;
-}
-
-/* Implement TARGET_INVALID_PARAMETER_TYPE. */
-
-static const char *
-arm_invalid_return_type (const_tree t)
-{
- if (SCALAR_FLOAT_TYPE_P (t) && TYPE_PRECISION (t) == 16)
- return N_("functions cannot return __fp16 type");
- return NULL;
-}
-
/* Implement TARGET_PROMOTED_TYPE. */
static tree
@@ -24715,7 +24702,11 @@ thumb1_expand_prologue (void)
/* Naked functions don't have prologues. */
if (IS_NAKED (func_type))
- return;
+ {
+ if (flag_stack_usage_info)
+ current_function_static_stack_size = 0;
+ return;
+ }
if (IS_INTERRUPT (func_type))
{
@@ -26129,11 +26120,10 @@ arm_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
/* Output code to add DELTA to the first argument, and then jump
to FUNCTION. Used for C++ multiple inheritance. */
+
static void
-arm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
- HOST_WIDE_INT delta,
- HOST_WIDE_INT vcall_offset ATTRIBUTE_UNUSED,
- tree function)
+arm_thumb1_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
+ HOST_WIDE_INT, tree function)
{
static int thunk_label = 0;
char label[256];
@@ -26274,6 +26264,76 @@ arm_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
final_end_function ();
}
+/* MI thunk handling for TARGET_32BIT. */
+
+static void
+arm32_output_mi_thunk (FILE *file, tree, HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset, tree function)
+{
+ /* On ARM, this_regno is R0 or R1 depending on
+ whether the function returns an aggregate or not.
+ */
+ int this_regno = (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)),
+ function)
+ ? R1_REGNUM : R0_REGNUM);
+
+ rtx temp = gen_rtx_REG (Pmode, IP_REGNUM);
+ rtx this_rtx = gen_rtx_REG (Pmode, this_regno);
+ reload_completed = 1;
+ emit_note (NOTE_INSN_PROLOGUE_END);
+
+ /* Add DELTA to THIS_RTX. */
+ if (delta != 0)
+ arm_split_constant (PLUS, Pmode, NULL_RTX,
+ delta, this_rtx, this_rtx, false);
+
+ /* Add *(*THIS_RTX + VCALL_OFFSET) to THIS_RTX. */
+ if (vcall_offset != 0)
+ {
+ /* Load *THIS_RTX. */
+ emit_move_insn (temp, gen_rtx_MEM (Pmode, this_rtx));
+ /* Compute *THIS_RTX + VCALL_OFFSET. */
+ arm_split_constant (PLUS, Pmode, NULL_RTX, vcall_offset, temp, temp,
+ false);
+ /* Compute *(*THIS_RTX + VCALL_OFFSET). */
+ emit_move_insn (temp, gen_rtx_MEM (Pmode, temp));
+ emit_insn (gen_add3_insn (this_rtx, this_rtx, temp));
+ }
+
+ /* Generate a tail call to the target function. */
+ if (!TREE_USED (function))
+ {
+ assemble_external (function);
+ TREE_USED (function) = 1;
+ }
+ rtx funexp = XEXP (DECL_RTL (function), 0);
+ funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
+ rtx_insn * insn = emit_call_insn (gen_sibcall (funexp, const0_rtx, NULL_RTX));
+ SIBLING_CALL_P (insn) = 1;
+
+ insn = get_insns ();
+ shorten_branches (insn);
+ final_start_function (insn, file, 1);
+ final (insn, file, 1);
+ final_end_function ();
+
+ /* Stop pretending this is a post-reload pass. */
+ reload_completed = 0;
+}
+
+/* Output code to add DELTA to the first argument, and then jump
+ to FUNCTION. Used for C++ multiple inheritance. */
+
+static void
+arm_output_mi_thunk (FILE *file, tree thunk, HOST_WIDE_INT delta,
+ HOST_WIDE_INT vcall_offset, tree function)
+{
+ if (TARGET_32BIT)
+ arm32_output_mi_thunk (file, thunk, delta, vcall_offset, function);
+ else
+ arm_thumb1_mi_thunk (file, thunk, delta, vcall_offset, function);
+}
+
int
arm_emit_vector_const (FILE *file, rtx x)
{
@@ -30378,4 +30438,18 @@ arm_simd_check_vect_par_cnst_half_p (rtx op, machine_mode mode,
return true;
}
+/* Can output mi_thunk for all cases except for non-zero vcall_offset
+ in Thumb1. */
+static bool
+arm_can_output_mi_thunk (const_tree, HOST_WIDE_INT, HOST_WIDE_INT vcall_offset,
+ const_tree)
+{
+ /* For now, we punt and not handle this for TARGET_THUMB1. */
+ if (vcall_offset && TARGET_THUMB1)
+ return false;
+
+ /* Otherwise ok. */
+ return true;
+}
+
#include "gt-arm.h"
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index ad123dde991..5b1a03080d0 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -194,7 +194,8 @@ extern void (*arm_lang_output_object_attributes_hook)(void);
/* FPU supports half-precision floating-point with NEON element load/store. */
#define TARGET_NEON_FP16 \
(TARGET_VFP \
- && ARM_FPU_FSET_HAS (TARGET_FPU_FEATURES, FPU_FL_NEON | FPU_FL_FP16))
+ && ARM_FPU_FSET_HAS (TARGET_FPU_FEATURES, FPU_FL_NEON) \
+ && ARM_FPU_FSET_HAS (TARGET_FPU_FEATURES, FPU_FL_FP16))
/* FPU supports VFP half-precision floating-point. */
#define TARGET_FP16 \
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 47171b99682..4049f104c6d 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -121,7 +121,7 @@
; arm_arch6. "v6t2" for Thumb-2 with arm_arch6. This attribute is
; used to compute attribute "enabled", use type "any" to enable an
; alternative in all cases.
-(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3"
+(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon"
(const_string "any"))
(define_attr "arch_enabled" "no,yes"
@@ -177,6 +177,10 @@
(and (eq_attr "arch" "armv6_or_vfpv3")
(match_test "arm_arch6 || TARGET_VFP3"))
(const_string "yes")
+
+ (and (eq_attr "arch" "neon")
+ (match_test "TARGET_NEON"))
+ (const_string "yes")
]
(const_string "no")))
@@ -6547,7 +6551,7 @@
(define_insn "*arm32_movhf"
[(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r")
(match_operand:HF 1 "general_operand" " m,r,r,F"))]
- "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_FP16)
+ "TARGET_32BIT && !(TARGET_HARD_FLOAT && TARGET_VFP)
&& ( s_register_operand (operands[0], HFmode)
|| s_register_operand (operands[1], HFmode))"
"*
@@ -8152,8 +8156,8 @@
)
(define_insn "probe_stack"
- [(set (match_operand 0 "memory_operand" "=m")
- (unspec [(const_int 0)] UNSPEC_PROBE_STACK))]
+ [(set (match_operand:SI 0 "memory_operand" "=m")
+ (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))]
"TARGET_32BIT"
"str%?\\tr0, %0"
[(set_attr "type" "store1")
diff --git a/gcc/config/arm/arm_neon.h b/gcc/config/arm/arm_neon.h
index 07503d7aa35..7997cb4ad3a 100644
--- a/gcc/config/arm/arm_neon.h
+++ b/gcc/config/arm/arm_neon.h
@@ -2607,6 +2607,12 @@ vtst_p8 (poly8x8_t __a, poly8x8_t __b)
return (uint8x8_t)__builtin_neon_vtstv8qi ((int8x8_t) __a, (int8x8_t) __b);
}
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vtst_p16 (poly16x4_t __a, poly16x4_t __b)
+{
+ return (uint16x4_t)__builtin_neon_vtstv4hi ((int16x4_t) __a, (int16x4_t) __b);
+}
+
__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
vtstq_s8 (int8x16_t __a, int8x16_t __b)
{
@@ -2649,6 +2655,12 @@ vtstq_p8 (poly8x16_t __a, poly8x16_t __b)
return (uint8x16_t)__builtin_neon_vtstv16qi ((int8x16_t) __a, (int8x16_t) __b);
}
+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
+vtstq_p16 (poly16x8_t __a, poly16x8_t __b)
+{
+ return (uint16x8_t)__builtin_neon_vtstv8hi ((int16x8_t) __a, (int16x8_t) __b);
+}
+
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
vabd_s8 (int8x8_t __a, int8x8_t __b)
{
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index ac5f3b862b5..9750ba16260 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -268,7 +268,8 @@
(define_insn "*movhf_vfp"
[(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,t,r,t,r,r")
(match_operand:HF 1 "general_operand" " m,r,t,r,r,t,F"))]
- "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_FP16 && !TARGET_NEON_FP16
+ "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP
+ && !TARGET_NEON_FP16
&& ( s_register_operand (operands[0], HFmode)
|| s_register_operand (operands[1], HFmode))"
"*
@@ -394,8 +395,8 @@
;; DFmode moves
(define_insn "*movdf_vfp"
- [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w ,Uv,r, m,w,r")
- (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,UvF,w ,mF,r,w,r"))]
+ [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w ,Uv,r, m,w,r")
+ (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,G,UvF,w ,mF,r,w,r"))]
"TARGET_ARM && TARGET_HARD_FLOAT && TARGET_VFP
&& ( register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))"
@@ -410,39 +411,43 @@
case 2:
gcc_assert (TARGET_VFP_DOUBLE);
return \"vmov%?.f64\\t%P0, %1\";
- case 3: case 4:
+ case 3:
+ gcc_assert (TARGET_VFP_DOUBLE);
+ return \"vmov.i64\\t%P0, #0\\t%@ float\";
+ case 4: case 5:
return output_move_vfp (operands);
- case 5: case 6:
+ case 6: case 7:
return output_move_double (operands, true, NULL);
- case 7:
+ case 8:
if (TARGET_VFP_SINGLE)
return \"vmov%?.f32\\t%0, %1\;vmov%?.f32\\t%p0, %p1\";
else
return \"vmov%?.f64\\t%P0, %P1\";
- case 8:
+ case 9:
return \"#\";
default:
gcc_unreachable ();
}
}
"
- [(set_attr "type" "f_mcrr,f_mrrc,fconstd,f_loadd,f_stored,\
+ [(set_attr "type" "f_mcrr,f_mrrc,fconstd,neon_move,f_loadd,f_stored,\
load2,store2,ffarithd,multiple")
- (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8)
- (eq_attr "alternative" "7")
+ (set (attr "length") (cond [(eq_attr "alternative" "6,7,9") (const_int 8)
+ (eq_attr "alternative" "8")
(if_then_else
(match_test "TARGET_VFP_SINGLE")
(const_int 8)
(const_int 4))]
(const_int 4)))
- (set_attr "predicable" "yes")
- (set_attr "pool_range" "*,*,*,1020,*,1020,*,*,*")
- (set_attr "neg_pool_range" "*,*,*,1004,*,1004,*,*,*")]
+ (set_attr "predicable" "yes,yes,yes,no,yes,yes,yes,yes,yes,yes")
+ (set_attr "pool_range" "*,*,*,*,1020,*,1020,*,*,*")
+ (set_attr "neg_pool_range" "*,*,*,*,1004,*,1004,*,*,*")
+ (set_attr "arch" "any,any,any,neon,any,any,any,any,any,any")]
)
(define_insn "*thumb2_movdf_vfp"
- [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w ,Uv,r ,m,w,r")
- (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,UvF,w, mF,r, w,r"))]
+ [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=w,?r,w ,w,w ,Uv,r ,m,w,r")
+ (match_operand:DF 1 "soft_df_operand" " ?r,w,Dy,G,UvF,w, mF,r, w,r"))]
"TARGET_THUMB2 && TARGET_HARD_FLOAT && TARGET_VFP
&& ( register_operand (operands[0], DFmode)
|| register_operand (operands[1], DFmode))"
@@ -457,11 +462,14 @@
case 2:
gcc_assert (TARGET_VFP_DOUBLE);
return \"vmov%?.f64\\t%P0, %1\";
- case 3: case 4:
+ case 3:
+ gcc_assert (TARGET_VFP_DOUBLE);
+ return \"vmov.i64\\t%P0, #0\\t%@ float\";
+ case 4: case 5:
return output_move_vfp (operands);
- case 5: case 6: case 8:
+ case 6: case 7: case 9:
return output_move_double (operands, true, NULL);
- case 7:
+ case 8:
if (TARGET_VFP_SINGLE)
return \"vmov%?.f32\\t%0, %1\;vmov%?.f32\\t%p0, %p1\";
else
@@ -471,17 +479,18 @@
}
}
"
- [(set_attr "type" "f_mcrr,f_mrrc,fconstd,f_loadd,\
+ [(set_attr "type" "f_mcrr,f_mrrc,fconstd,neon_move,f_loadd,\
f_stored,load2,store2,ffarithd,multiple")
- (set (attr "length") (cond [(eq_attr "alternative" "5,6,8") (const_int 8)
- (eq_attr "alternative" "7")
+ (set (attr "length") (cond [(eq_attr "alternative" "6,7,9") (const_int 8)
+ (eq_attr "alternative" "8")
(if_then_else
(match_test "TARGET_VFP_SINGLE")
(const_int 8)
(const_int 4))]
(const_int 4)))
- (set_attr "pool_range" "*,*,*,1018,*,4094,*,*,*")
- (set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
+ (set_attr "pool_range" "*,*,*,*,1018,*,4094,*,*,*")
+ (set_attr "neg_pool_range" "*,*,*,*,1008,*,0,*,*,*")
+ (set_attr "arch" "any,any,any,neon,any,any,any,any,any,any")]
)
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 8de39e0a660..ba5cd914e55 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -1484,7 +1484,7 @@ avr_expand_prologue (void)
avr_prologue_setup_frame (size, set);
if (flag_stack_usage_info)
- current_function_static_stack_size = cfun->machine->stack_usage;
+ current_function_static_stack_size = cfun->machine->stack_usage + INCOMING_FRAME_SP_OFFSET;
}
diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index c9884461841..927bc6967a1 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -638,6 +638,13 @@
rtx dest = operands[0];
rtx src = avr_eval_addr_attrib (operands[1]);
+ if (SUBREG_P(src) && (GET_CODE(XEXP(src,0)) == SYMBOL_REF) &&
+ can_create_pseudo_p())
+ {
+ rtx symbol_ref = XEXP(src, 0);
+ XEXP (src, 0) = copy_to_mode_reg (GET_MODE(symbol_ref), symbol_ref);
+ }
+
if (avr_mem_flash_p (dest))
DONE;
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 93d136bc666..44f2d33fc42 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -145,6 +145,10 @@
"TARGET_SSE ? (X86_TUNE_AVOID_4BYTE_PREFIXES ? NO_REX_SSE_REGS : ALL_SSE_REGS) : NO_REGS"
"@internal Lower SSE register when avoiding REX prefix and all SSE registers otherwise.")
+(define_register_constraint "Yv"
+ "TARGET_AVX512VL ? ALL_SSE_REGS : TARGET_SSE ? SSE_REGS : NO_REGS"
+ "@internal For AVX512VL, any EVEX encodable SSE register (@code{%xmm0-%xmm31}), otherwise any SSE register.")
+
;; We use the B prefix to denote any number of internal operands:
;; f FLAGS_REG
;; g GOT memory operand.
@@ -270,6 +274,11 @@
(and (match_operand 0 "x86_64_zext_immediate_operand")
(match_test "GET_MODE (op) != VOIDmode")))
+(define_constraint "Wd"
+ "128-bit integer constant where both the high and low 64-bit word
+ of it satisfies the e constraint."
+ (match_operand 0 "x86_64_hilo_int_operand"))
+
(define_constraint "Z"
"32-bit unsigned integer constant, or a symbolic reference known
to fit that range (for immediate operands in zero-extending x86-64
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index 9da473359a5..d6c2254b800 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -339,16 +339,13 @@ do { \
#define ASM_COMMENT_START " #"
#ifndef DWARF2_UNWIND_INFO
-/* If configured with --disable-sjlj-exceptions, use DWARF2, else
- default to SJLJ. */
+/* If configured with --disable-sjlj-exceptions, use DWARF2 for 32-bit
+ mode else default to SJLJ. 64-bit code uses SEH unless you request
+ SJLJ. */
#if (defined (CONFIG_SJLJ_EXCEPTIONS) && !CONFIG_SJLJ_EXCEPTIONS)
/* The logic of this #if must be kept synchronised with the logic
- for selecting the tmake_eh_file fragment in config.gcc. */
+ for selecting the tmake_eh_file fragment in libgcc/config.host. */
#define DWARF2_UNWIND_INFO 1
-/* If multilib is selected break build as sjlj is required. */
-#if defined (TARGET_BI_ARCH)
-#error For 64-bit windows and 32-bit based multilib version of gcc just SJLJ exceptions are supported.
-#endif
#else
#define DWARF2_UNWIND_INFO 0
#endif
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 4145ed56658..447f67e2dff 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -52,6 +52,7 @@ extern const char *standard_80387_constant_opcode (rtx);
extern rtx standard_80387_constant_rtx (int);
extern int standard_sse_constant_p (rtx, machine_mode);
extern const char *standard_sse_constant_opcode (rtx_insn *, rtx);
+extern bool ix86_standard_x87sse_constant_load_p (const rtx_insn *, rtx);
extern bool symbolic_reference_mentioned_p (rtx);
extern bool extended_reg_mentioned_p (rtx);
extern bool x86_extended_QIreg_mentioned_p (rtx_insn *);
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 9680aaf3f50..1cb88d6dc0a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -2789,7 +2789,8 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
return convertible_comparison_p (insn);
/* We are interested in DImode promotion only. */
- if (GET_MODE (src) != DImode
+ if ((GET_MODE (src) != DImode
+ && !CONST_INT_P (src))
|| GET_MODE (dst) != DImode)
return false;
@@ -2809,24 +2810,31 @@ dimode_scalar_to_vector_candidate_p (rtx_insn *insn)
return true;
case MEM:
+ case CONST_INT:
return REG_P (dst);
default:
return false;
}
- if (!REG_P (XEXP (src, 0)) && !MEM_P (XEXP (src, 0))
+ if (!REG_P (XEXP (src, 0))
+ && !MEM_P (XEXP (src, 0))
+ && !CONST_INT_P (XEXP (src, 0))
/* Check for andnot case. */
&& (GET_CODE (src) != AND
|| GET_CODE (XEXP (src, 0)) != NOT
|| !REG_P (XEXP (XEXP (src, 0), 0))))
return false;
- if (!REG_P (XEXP (src, 1)) && !MEM_P (XEXP (src, 1)))
+ if (!REG_P (XEXP (src, 1))
+ && !MEM_P (XEXP (src, 1))
+ && !CONST_INT_P (XEXP (src, 1)))
return false;
- if (GET_MODE (XEXP (src, 0)) != DImode
- || GET_MODE (XEXP (src, 1)) != DImode)
+ if ((GET_MODE (XEXP (src, 0)) != DImode
+ && !CONST_INT_P (XEXP (src, 0)))
+ || (GET_MODE (XEXP (src, 1)) != DImode
+ && !CONST_INT_P (XEXP (src, 1))))
return false;
return true;
@@ -3120,6 +3128,7 @@ class dimode_scalar_chain : public scalar_chain
void convert_reg (unsigned regno);
void make_vector_copies (unsigned regno);
void convert_registers ();
+ int vector_const_cost (rtx exp);
};
class timode_scalar_chain : public scalar_chain
@@ -3328,6 +3337,19 @@ scalar_chain::build (bitmap candidates, unsigned insn_uid)
BITMAP_FREE (queue);
}
+/* Return a cost of building a vector costant
+ instead of using a scalar one. */
+
+int
+dimode_scalar_chain::vector_const_cost (rtx exp)
+{
+ gcc_assert (CONST_INT_P (exp));
+
+ if (standard_sse_constant_p (exp, V2DImode))
+ return COSTS_N_INSNS (1);
+ return ix86_cost->sse_load[1];
+}
+
/* Compute a gain for chain conversion. */
int
@@ -3359,11 +3381,25 @@ dimode_scalar_chain::compute_convert_gain ()
|| GET_CODE (src) == IOR
|| GET_CODE (src) == XOR
|| GET_CODE (src) == AND)
- gain += ix86_cost->add;
+ {
+ gain += ix86_cost->add;
+ if (CONST_INT_P (XEXP (src, 0)))
+ gain -= vector_const_cost (XEXP (src, 0));
+ if (CONST_INT_P (XEXP (src, 1)))
+ gain -= vector_const_cost (XEXP (src, 1));
+ }
else if (GET_CODE (src) == COMPARE)
{
/* Assume comparison cost is the same. */
}
+ else if (GET_CODE (src) == CONST_INT)
+ {
+ if (REG_P (dst))
+ gain += COSTS_N_INSNS (2);
+ else if (MEM_P (dst))
+ gain += 2 * ix86_cost->int_store[2] - ix86_cost->sse_store[1];
+ gain -= vector_const_cost (src);
+ }
else
gcc_unreachable ();
}
@@ -3639,6 +3675,30 @@ dimode_scalar_chain::convert_op (rtx *op, rtx_insn *insn)
}
*op = gen_rtx_SUBREG (V2DImode, *op, 0);
}
+ else if (CONST_INT_P (*op))
+ {
+ rtx vec_cst;
+ rtx tmp = gen_rtx_SUBREG (V2DImode, gen_reg_rtx (DImode), 0);
+
+ /* Prefer all ones vector in case of -1. */
+ if (constm1_operand (*op, GET_MODE (*op)))
+ vec_cst = CONSTM1_RTX (V2DImode);
+ else
+ vec_cst = gen_rtx_CONST_VECTOR (V2DImode,
+ gen_rtvec (2, *op, const0_rtx));
+
+ if (!standard_sse_constant_p (vec_cst, V2DImode))
+ {
+ start_sequence ();
+ vec_cst = validize_mem (force_const_mem (V2DImode, vec_cst));
+ rtx_insn *seq = get_insns ();
+ end_sequence ();
+ emit_insn_before (seq, insn);
+ }
+
+ emit_insn_before (gen_move_insn (tmp, vec_cst), insn);
+ *op = tmp;
+ }
else
{
gcc_assert (SUBREG_P (*op));
@@ -3711,6 +3771,10 @@ dimode_scalar_chain::convert_insn (rtx_insn *insn)
UNSPEC_PTEST);
break;
+ case CONST_INT:
+ convert_op (&src, insn);
+ break;
+
default:
gcc_unreachable ();
}
@@ -3911,13 +3975,6 @@ convert_scalars_to_vector ()
bitmap_obstack_release (NULL);
df_process_deferred_rescans ();
- /* FIXME: Since the CSE pass may change dominance info, which isn't
- expected by the fwprop pass, call free_dominance_info to
- invalidate dominance info. Otherwise, the fwprop pass may crash
- when dominance info is changed. */
- if (TARGET_64BIT)
- free_dominance_info (CDI_DOMINATORS);
-
/* Conversion means we may have 128bit register spills/fills
which require aligned stack. */
if (converted_insns)
@@ -6772,6 +6829,9 @@ ix86_in_large_data_p (tree exp)
if (ix86_cmodel != CM_MEDIUM && ix86_cmodel != CM_MEDIUM_PIC)
return false;
+ if (exp == NULL_TREE)
+ return false;
+
/* Functions are never large data. */
if (TREE_CODE (exp) == FUNCTION_DECL)
return false;
@@ -11219,6 +11279,26 @@ standard_sse_constant_opcode (rtx_insn *insn, rtx x)
gcc_unreachable ();
}
+/* Returns true if INSN can be transformed from a memory load
+ to a supported FP constant load. */
+
+bool
+ix86_standard_x87sse_constant_load_p (const rtx_insn *insn, rtx dst)
+{
+ rtx src = find_constant_src (insn);
+
+ gcc_assert (REG_P (dst));
+
+ if (src == NULL
+ || (SSE_REGNO_P (REGNO (dst))
+ && standard_sse_constant_p (src, GET_MODE (dst)) != 1)
+ || (STACK_REGNO_P (REGNO (dst))
+ && standard_80387_constant_p (src) < 1))
+ return false;
+
+ return true;
+}
+
/* Returns true if OP contains a symbol reference */
bool
@@ -11886,7 +11966,7 @@ ix86_compute_frame_layout (struct ix86_frame *frame)
to_allocate = offset - frame->sse_reg_save_offset;
if ((!to_allocate && frame->nregs <= 1)
- || (TARGET_64BIT && to_allocate >= (HOST_WIDE_INT) 0x80000000))
+ || (TARGET_64BIT && to_allocate >= HOST_WIDE_INT_C (0x80000000)))
frame->save_regs_using_mov = false;
if (ix86_using_red_zone ()
@@ -13308,7 +13388,7 @@ ix86_expand_prologue (void)
{
HOST_WIDE_INT size = allocate;
- if (TARGET_64BIT && size >= (HOST_WIDE_INT) 0x80000000)
+ if (TARGET_64BIT && size >= HOST_WIDE_INT_C (0x80000000))
size = 0x80000000 - STACK_CHECK_PROTECT - 1;
if (TARGET_STACK_PROBE)
@@ -14249,7 +14329,7 @@ ix86_expand_split_stack_prologue (void)
different function: __morestack_large. We pass the
argument size in the upper 32 bits of r10 and pass the
frame size in the lower 32 bits. */
- gcc_assert ((allocate & (HOST_WIDE_INT) 0xffffffff) == allocate);
+ gcc_assert ((allocate & HOST_WIDE_INT_C (0xffffffff)) == allocate);
gcc_assert ((args_size & 0xffffffff) == args_size);
if (split_stack_fn_large == NULL_RTX)
@@ -14784,8 +14864,7 @@ ix86_legitimate_constant_p (machine_mode mode, rtx x)
#endif
break;
- case CONST_INT:
- case CONST_WIDE_INT:
+ CASE_CONST_SCALAR_INT:
switch (mode)
{
case TImode:
@@ -14820,18 +14899,16 @@ ix86_legitimate_constant_p (machine_mode mode, rtx x)
static bool
ix86_cannot_force_const_mem (machine_mode mode, rtx x)
{
- /* We can always put integral constants and vectors in memory. */
+ /* We can put any immediate constant in memory. */
switch (GET_CODE (x))
{
- case CONST_INT:
- case CONST_WIDE_INT:
- case CONST_DOUBLE:
- case CONST_VECTOR:
+ CASE_CONST_ANY:
return false;
default:
break;
}
+
return !ix86_legitimate_constant_p (mode, x);
}
@@ -15355,46 +15432,16 @@ legitimize_pic_address (rtx orig, rtx reg)
if (TARGET_64BIT && legitimate_pic_address_disp_p (addr))
new_rtx = addr;
- else if (TARGET_64BIT && !TARGET_PECOFF
- && ix86_cmodel != CM_SMALL_PIC && gotoff_operand (addr, Pmode))
+ else if ((!TARGET_64BIT
+ || /* TARGET_64BIT && */ ix86_cmodel != CM_SMALL_PIC)
+ && !TARGET_PECOFF
+ && gotoff_operand (addr, Pmode))
{
- rtx tmpreg;
- /* This symbol may be referenced via a displacement from the PIC
- base address (@GOTOFF). */
-
+ /* This symbol may be referenced via a displacement
+ from the PIC base address (@GOTOFF). */
if (GET_CODE (addr) == CONST)
addr = XEXP (addr, 0);
- if (GET_CODE (addr) == PLUS)
- {
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
- UNSPEC_GOTOFF);
- new_rtx = gen_rtx_PLUS (Pmode, new_rtx, XEXP (addr, 1));
- }
- else
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
- new_rtx = gen_rtx_CONST (Pmode, new_rtx);
- if (!reg)
- tmpreg = gen_reg_rtx (Pmode);
- else
- tmpreg = reg;
- emit_move_insn (tmpreg, new_rtx);
- if (reg != 0)
- {
- new_rtx = expand_simple_binop (Pmode, PLUS, reg, pic_offset_table_rtx,
- tmpreg, 1, OPTAB_DIRECT);
- new_rtx = reg;
- }
- else
- new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, tmpreg);
- }
- else if (!TARGET_64BIT && !TARGET_PECOFF && gotoff_operand (addr, Pmode))
- {
- /* This symbol may be referenced via a displacement from the PIC
- base address (@GOTOFF). */
-
- if (GET_CODE (addr) == CONST)
- addr = XEXP (addr, 0);
if (GET_CODE (addr) == PLUS)
{
new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, XEXP (addr, 0)),
@@ -15403,56 +15450,49 @@ legitimize_pic_address (rtx orig, rtx reg)
}
else
new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTOFF);
+
new_rtx = gen_rtx_CONST (Pmode, new_rtx);
- new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
+
+ if (TARGET_64BIT)
+ new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
if (reg != 0)
{
- emit_move_insn (reg, new_rtx);
- new_rtx = reg;
- }
+ gcc_assert (REG_P (reg));
+ new_rtx = expand_simple_binop (Pmode, PLUS, pic_offset_table_rtx,
+ new_rtx, reg, 1, OPTAB_DIRECT);
+ }
+ else
+ new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
}
else if ((GET_CODE (addr) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (addr) == 0)
- /* We can't use @GOTOFF for text labels on VxWorks;
- see gotoff_operand. */
+ /* We can't use @GOTOFF for text labels
+ on VxWorks, see gotoff_operand. */
|| (TARGET_VXWORKS_RTP && GET_CODE (addr) == LABEL_REF))
{
rtx tmp = legitimize_pe_coff_symbol (addr, true);
if (tmp)
return tmp;
- /* For x64 PE-COFF there is no GOT table. So we use address
- directly. */
+ /* For x64 PE-COFF there is no GOT table,
+ so we use address directly. */
if (TARGET_64BIT && TARGET_PECOFF)
{
new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_PCREL);
new_rtx = gen_rtx_CONST (Pmode, new_rtx);
-
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
- emit_move_insn (reg, new_rtx);
- new_rtx = reg;
}
else if (TARGET_64BIT && ix86_cmodel != CM_LARGE_PIC)
{
- new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOTPCREL);
+ new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr),
+ UNSPEC_GOTPCREL);
new_rtx = gen_rtx_CONST (Pmode, new_rtx);
new_rtx = gen_const_mem (Pmode, new_rtx);
set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
-
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
- /* Use directly gen_movsi, otherwise the address is loaded
- into register for CSE. We don't want to CSE this addresses,
- instead we CSE addresses from the GOT table, so skip this. */
- emit_insn (gen_movsi (reg, new_rtx));
- new_rtx = reg;
}
else
{
- /* This symbol must be referenced via a load from the
- Global Offset Table (@GOT). */
-
+ /* This symbol must be referenced via a load
+ from the Global Offset Table (@GOT). */
new_rtx = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, addr), UNSPEC_GOT);
new_rtx = gen_rtx_CONST (Pmode, new_rtx);
if (TARGET_64BIT)
@@ -15460,26 +15500,15 @@ legitimize_pic_address (rtx orig, rtx reg)
new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
new_rtx = gen_const_mem (Pmode, new_rtx);
set_mem_alias_set (new_rtx, ix86_GOT_alias_set ());
-
- if (reg == 0)
- reg = gen_reg_rtx (Pmode);
- emit_move_insn (reg, new_rtx);
- new_rtx = reg;
}
+
+ new_rtx = copy_to_suggested_reg (new_rtx, reg, Pmode);
}
else
{
if (CONST_INT_P (addr)
&& !x86_64_immediate_operand (addr, VOIDmode))
- {
- if (reg)
- {
- emit_move_insn (reg, addr);
- new_rtx = reg;
- }
- else
- new_rtx = force_reg (Pmode, addr);
- }
+ new_rtx = copy_to_suggested_reg (addr, reg, Pmode);
else if (GET_CODE (addr) == CONST)
{
addr = XEXP (addr, 0);
@@ -15493,13 +15522,15 @@ legitimize_pic_address (rtx orig, rtx reg)
return orig;
gcc_assert (GET_CODE (addr) == PLUS);
}
+
if (GET_CODE (addr) == PLUS)
{
rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
- /* Check first to see if this is a constant offset from a @GOTOFF
- symbol reference. */
- if (!TARGET_PECOFF && gotoff_operand (op0, Pmode)
+ /* Check first to see if this is a constant
+ offset from a @GOTOFF symbol reference. */
+ if (!TARGET_PECOFF
+ && gotoff_operand (op0, Pmode)
&& CONST_INT_P (op1))
{
if (!TARGET_64BIT)
@@ -15508,13 +15539,18 @@ legitimize_pic_address (rtx orig, rtx reg)
UNSPEC_GOTOFF);
new_rtx = gen_rtx_PLUS (Pmode, new_rtx, op1);
new_rtx = gen_rtx_CONST (Pmode, new_rtx);
- new_rtx = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
if (reg != 0)
{
- emit_move_insn (reg, new_rtx);
- new_rtx = reg;
+ gcc_assert (REG_P (reg));
+ new_rtx = expand_simple_binop (Pmode, PLUS,
+ pic_offset_table_rtx,
+ new_rtx, reg, 1,
+ OPTAB_DIRECT);
}
+ else
+ new_rtx
+ = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, new_rtx);
}
else
{
@@ -15523,7 +15559,9 @@ legitimize_pic_address (rtx orig, rtx reg)
{
if (!x86_64_immediate_operand (op1, Pmode))
op1 = force_reg (Pmode, op1);
- new_rtx = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
+
+ new_rtx
+ = gen_rtx_PLUS (Pmode, force_reg (Pmode, op0), op1);
}
}
}
@@ -15541,6 +15579,7 @@ legitimize_pic_address (rtx orig, rtx reg)
{
if (!x86_64_immediate_operand (new_rtx, mode))
new_rtx = force_reg (mode, new_rtx);
+
new_rtx
= gen_rtx_PLUS (mode, force_reg (mode, base), new_rtx);
}
@@ -15549,8 +15588,8 @@ legitimize_pic_address (rtx orig, rtx reg)
}
else
{
- /* For %rip addressing, we have to use just disp32, not
- base nor index. */
+ /* For %rip addressing, we have to use
+ just disp32, not base nor index. */
if (TARGET_64BIT
&& (GET_CODE (base) == SYMBOL_REF
|| GET_CODE (base) == LABEL_REF))
@@ -17580,6 +17619,10 @@ ix86_print_operand (FILE *file, rtx x, int code)
size = "QWORD";
else if (code == 'x')
size = "XMMWORD";
+ else if (code == 't')
+ size = "YMMWORD";
+ else if (code == 'g')
+ size = "ZMMWORD";
else if (mode == BLKmode)
/* ... or BLKmode operands, when not overridden. */
size = NULL;
@@ -24521,20 +24564,17 @@ ix86_split_to_parts (rtx operand, rtx *parts, machine_mode mode)
real_to_target (l, CONST_DOUBLE_REAL_VALUE (operand), mode);
/* real_to_target puts 32-bit pieces in each long. */
- parts[0] =
- gen_int_mode
- ((l[0] & (HOST_WIDE_INT) 0xffffffff)
- | ((l[1] & (HOST_WIDE_INT) 0xffffffff) << 32),
- DImode);
+ parts[0] = gen_int_mode ((l[0] & HOST_WIDE_INT_C (0xffffffff))
+ | ((l[1] & HOST_WIDE_INT_C (0xffffffff))
+ << 32), DImode);
if (upper_mode == SImode)
parts[1] = gen_int_mode (l[2], SImode);
else
- parts[1] =
- gen_int_mode
- ((l[2] & (HOST_WIDE_INT) 0xffffffff)
- | ((l[3] & (HOST_WIDE_INT) 0xffffffff) << 32),
- DImode);
+ parts[1]
+ = gen_int_mode ((l[2] & HOST_WIDE_INT_C (0xffffffff))
+ | ((l[3] & HOST_WIDE_INT_C (0xffffffff))
+ << 32), DImode);
}
else
gcc_unreachable ();
@@ -26875,7 +26915,7 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
{
if (UINTVAL (count_exp) >= (unsigned HOST_WIDE_INT)dynamic_check)
{
- emit_block_move_via_libcall (dst, src, count_exp, false);
+ emit_block_copy_via_libcall (dst, src, count_exp);
count_exp = const0_rtx;
goto epilogue;
}
@@ -26890,9 +26930,9 @@ ix86_expand_set_or_movmem (rtx dst, rtx src, rtx count_exp, rtx val_exp,
1, hot_label);
predict_jump (REG_BR_PROB_BASE * 90 / 100);
if (issetmem)
- set_storage_via_libcall (dst, count_exp, val_exp, false);
+ set_storage_via_libcall (dst, count_exp, val_exp);
else
- emit_block_move_via_libcall (dst, src, count_exp, false);
+ emit_block_copy_via_libcall (dst, src, count_exp);
emit_jump (jump_around_label);
emit_label (hot_label);
}
@@ -44030,43 +44070,43 @@ ix86_rtx_costs (rtx x, machine_mode mode, int outer_code_i, int opno,
*total = 0;
return true;
- case CONST_WIDE_INT:
- *total = 0;
- return true;
-
case CONST_DOUBLE:
- switch (standard_80387_constant_p (x))
+ if (TARGET_80387 && IS_STACK_MODE (mode))
+ switch (standard_80387_constant_p (x))
+ {
+ case -1:
+ case 0:
+ break;
+ case 1: /* 0.0 */
+ *total = 1;
+ return true;
+ default: /* Other constants */
+ *total = 2;
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST_VECTOR:
+ switch (standard_sse_constant_p (x, mode))
{
- case 1: /* 0.0 */
- *total = 1;
- return true;
- default: /* Other constants */
- *total = 2;
- return true;
case 0:
- case -1:
break;
+ case 1: /* 0: xor eliminates false dependency */
+ *total = 0;
+ return true;
+ default: /* -1: cmp contains false dependency */
+ *total = 1;
+ return true;
}
- if (SSE_FLOAT_MODE_P (mode))
- {
- case CONST_VECTOR:
- switch (standard_sse_constant_p (x, mode))
- {
- case 0:
- break;
- case 1: /* 0: xor eliminates false dependency */
- *total = 0;
- return true;
- default: /* -1: cmp contains false dependency */
- *total = 1;
- return true;
- }
- }
+ /* FALLTHRU */
+
+ case CONST_WIDE_INT:
/* Fall back to (MEM (SYMBOL_REF)), since that's where
it'll probably end up. Add a penalty for size. */
*total = (COSTS_N_INSNS (1)
- + (flag_pic != 0 && !TARGET_64BIT)
- + (mode == SFmode ? 0 : mode == DFmode ? 1 : 2));
+ + (!TARGET_64BIT && flag_pic)
+ + (GET_MODE_SIZE (mode) <= 4
+ ? 0 : GET_MODE_SIZE (mode) <= 8 ? 1 : 2));
return true;
case ZERO_EXTEND:
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index d0b418b0fd9..b70a8c653e0 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -1126,7 +1126,8 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
#define VALID_AVX512VL_128_REG_MODE(MODE) \
((MODE) == V2DImode || (MODE) == V2DFmode || (MODE) == V16QImode \
- || (MODE) == V4SImode || (MODE) == V4SFmode || (MODE) == V8HImode)
+ || (MODE) == V4SImode || (MODE) == V4SFmode || (MODE) == V8HImode \
+ || (MODE) == TFmode || (MODE) == V1TImode)
#define VALID_SSE2_REG_MODE(MODE) \
((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index f4d33c59551..933faf847e8 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -796,7 +796,7 @@
sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq,
- avx512vl,noavx512vl"
+ avx512vl,noavx512vl,x64_avx512dq"
(const_string "base"))
(define_attr "enabled" ""
@@ -807,6 +807,8 @@
(symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
(eq_attr "isa" "x64_avx")
(symbol_ref "TARGET_64BIT && TARGET_AVX")
+ (eq_attr "isa" "x64_avx512dq")
+ (symbol_ref "TARGET_64BIT && TARGET_AVX512DQ")
(eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
(eq_attr "isa" "sse2_noavx")
@@ -1024,6 +1026,9 @@
(define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
(define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
+;; LEA mode corresponding to an integer mode
+(define_mode_attr LEAMODE [(QI "SI") (HI "SI") (SI "SI") (DI "DI")])
+
;; Half mode for double word integer modes.
(define_mode_iterator DWIH [(SI "!TARGET_64BIT")
(DI "TARGET_64BIT")])
@@ -1065,7 +1070,7 @@
(define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
;; Immediate operand constraint for double integer modes.
-(define_mode_attr di [(SI "nF") (DI "e")])
+(define_mode_attr di [(SI "nF") (DI "Wd")])
;; Immediate operand constraint for shifts.
(define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
@@ -1078,6 +1083,15 @@
(DI "x86_64_general_operand")
(TI "x86_64_general_operand")])
+;; General operand predicate for integer modes, where for TImode
+;; we need both words of the operand to be general operands.
+(define_mode_attr general_hilo_operand
+ [(QI "general_operand")
+ (HI "general_operand")
+ (SI "x86_64_general_operand")
+ (DI "x86_64_general_operand")
+ (TI "x86_64_hilo_general_operand")])
+
;; General sign extend operand predicate for integer modes,
;; which disallows VOIDmode operands and thus it is suitable
;; for use inside sign_extend.
@@ -1156,6 +1170,10 @@
(define_mode_attr ssevecmodelower
[(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
+;; AVX512F vector mode corresponding to a scalar mode
+(define_mode_attr avx512fvecmode
+ [(QI "V64QI") (HI "V32HI") (SI "V16SI") (DI "V8DI") (SF "V16SF") (DF "V8DF")])
+
;; Instruction suffix for REX 64bit operators.
(define_mode_attr rex64suffix [(SI "") (DI "{q}")])
@@ -1665,12 +1683,13 @@
(define_mode_iterator FPCMP [CCFP CCFPU])
(define_mode_attr unord [(CCFP "") (CCFPU "u")])
-(define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
+(define_insn "*cmpi<FPCMP:unord><MODEF:mode>"
[(set (reg:FPCMP FLAGS_REG)
(compare:FPCMP
(match_operand:MODEF 0 "register_operand" "f,v")
- (match_operand:MODEF 1 "nonimmediate_operand" "f,vm")))]
- "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
+ (match_operand:MODEF 1 "register_ssemem_operand" "f,vm")))]
+ "(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
+ || (TARGET_80387 && TARGET_CMOVE)"
"* return output_fp_compare (insn, operands, true,
<FPCMP:MODE>mode == CCFPUmode);"
[(set_attr "type" "fcmp,ssecomi")
@@ -1689,22 +1708,27 @@
(set_attr "bdver1_decode" "double")
(set_attr "znver1_decode" "double")
(set (attr "enabled")
- (cond [(eq_attr "alternative" "0")
- (symbol_ref "TARGET_MIX_SSE_I387")
- ]
- (symbol_ref "true")))])
+ (if_then_else
+ (match_test ("SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"))
+ (if_then_else
+ (eq_attr "alternative" "0")
+ (symbol_ref "TARGET_MIX_SSE_I387")
+ (symbol_ref "true"))
+ (if_then_else
+ (eq_attr "alternative" "0")
+ (symbol_ref "true")
+ (symbol_ref "false"))))])
-(define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
+(define_insn "*cmpi<unord>xf_i387"
[(set (reg:FPCMP FLAGS_REG)
(compare:FPCMP
- (match_operand:X87MODEF 0 "register_operand" "f")
- (match_operand:X87MODEF 1 "register_operand" "f")))]
- "TARGET_80387 && TARGET_CMOVE
- && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
+ (match_operand:XF 0 "register_operand" "f")
+ (match_operand:XF 1 "register_operand" "f")))]
+ "TARGET_80387 && TARGET_CMOVE"
"* return output_fp_compare (insn, operands, true,
- <FPCMP:MODE>mode == CCFPUmode);"
+ <MODE>mode == CCFPUmode);"
[(set_attr "type" "fcmp")
- (set_attr "mode" "<X87MODEF:MODE>")
+ (set_attr "mode" "XF")
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "direct")
(set_attr "bdver1_decode" "double")
@@ -2681,34 +2705,31 @@
(set_attr "amdfam10_decode" "double")
(set_attr "bdver1_decode" "double")])
-(define_insn "*swap<mode>_1"
- [(set (match_operand:SWI12 0 "register_operand" "+r")
- (match_operand:SWI12 1 "register_operand" "+r"))
+(define_insn "*swap<mode>"
+ [(set (match_operand:SWI12 0 "register_operand" "+<r>,r")
+ (match_operand:SWI12 1 "register_operand" "+<r>,r"))
(set (match_dup 1)
(match_dup 0))]
- "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
- "xchg{l}\t%k1, %k0"
+ ""
+ "@
+ xchg{<imodesuffix>}\t%1, %0
+ xchg{l}\t%k1, %k0"
[(set_attr "type" "imov")
- (set_attr "mode" "SI")
+ (set_attr "mode" "<MODE>,SI")
+ (set (attr "preferred_for_size")
+ (cond [(eq_attr "alternative" "0")
+ (symbol_ref "false")]
+ (symbol_ref "true")))
+ ;; Potential partial reg stall on alternative 1.
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "1")
+ (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+ (symbol_ref "true")))
(set_attr "pent_pair" "np")
(set_attr "athlon_decode" "vector")
(set_attr "amdfam10_decode" "double")
(set_attr "bdver1_decode" "double")])
-;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
-;; is disabled for AMDFAM10
-(define_insn "*swap<mode>_2"
- [(set (match_operand:SWI12 0 "register_operand" "+<r>")
- (match_operand:SWI12 1 "register_operand" "+<r>"))
- (set (match_dup 1)
- (match_dup 0))]
- "TARGET_PARTIAL_REG_STALL"
- "xchg{<imodesuffix>}\t%1, %0"
- [(set_attr "type" "imov")
- (set_attr "mode" "<MODE>")
- (set_attr "pent_pair" "np")
- (set_attr "athlon_decode" "vector")])
-
(define_expand "movstrict<mode>"
[(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
(match_operand:SWI12 1 "general_operand"))]
@@ -2913,7 +2934,7 @@
(define_insn "*pushtf"
[(set (match_operand:TF 0 "push_operand" "=<,<")
- (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
+ (match_operand:TF 1 "general_no_elim_operand" "v,*roF"))]
"TARGET_64BIT || TARGET_SSE"
{
/* This insn should be already split before reg-stack. */
@@ -3057,14 +3078,10 @@
(define_split
[(set (match_operand:SF 0 "push_operand")
(match_operand:SF 1 "memory_operand"))]
- "reload_completed"
+ "reload_completed
+ && find_constant_src (insn)"
[(set (match_dup 0) (match_dup 2))]
-{
- operands[2] = find_constant_src (curr_insn);
-
- if (operands[2] == NULL_RTX)
- FAIL;
-})
+ "operands[2] = find_constant_src (curr_insn);")
(define_split
[(set (match_operand 0 "push_operand")
@@ -3092,14 +3109,14 @@
"ix86_expand_move (<MODE>mode, operands); DONE;")
(define_insn "*movtf_internal"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
- (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=v,v ,m,?*r ,!o")
+ (match_operand:TF 1 "general_operand" "C ,vm,v,*roF,*rC"))]
"(TARGET_64BIT || TARGET_SSE)
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| !CONST_DOUBLE_P (operands[1])
- || (optimize_function_for_size_p (cfun)
+ || ((optimize_function_for_size_p (cfun)
+ || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
&& standard_sse_constant_p (operands[1], TFmode) == 1
&& !memory_operand (operands[0], TFmode))
|| (!TARGET_MEMORY_MISMATCH_STALL
@@ -3118,6 +3135,10 @@
{
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovups\t{%1, %0|%0, %1}";
+ else if (TARGET_AVX512VL
+ && (EXT_REX_SSE_REG_P (operands[0])
+ || EXT_REX_SSE_REG_P (operands[1])))
+ return "vmovdqu64\t{%1, %0|%0, %1}";
else
return "%vmovdqu\t{%1, %0|%0, %1}";
}
@@ -3125,6 +3146,10 @@
{
if (get_attr_mode (insn) == MODE_V4SF)
return "%vmovaps\t{%1, %0|%0, %1}";
+ else if (TARGET_AVX512VL
+ && (EXT_REX_SSE_REG_P (operands[0])
+ || EXT_REX_SSE_REG_P (operands[1])))
+ return "vmovdqa64\t{%1, %0|%0, %1}";
else
return "%vmovdqa\t{%1, %0|%0, %1}";
}
@@ -3175,9 +3200,9 @@
"fm,f,G,roF,r , *roF,*r,F ,C,roF,rF"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| !CONST_DOUBLE_P (operands[1])
- || (optimize_function_for_size_p (cfun)
+ || ((optimize_function_for_size_p (cfun)
+ || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
&& standard_80387_constant_p (operands[1]) > 0
&& !memory_operand (operands[0], XFmode))
|| (!TARGET_MEMORY_MISMATCH_STALL
@@ -3248,9 +3273,9 @@
"Yf*fm,Yf*f,G ,roF,r ,*roF,*r,F ,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r ,roF,rF,rmF,rC"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| !CONST_DOUBLE_P (operands[1])
- || (optimize_function_for_size_p (cfun)
+ || ((optimize_function_for_size_p (cfun)
+ || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
&& ((!(TARGET_SSE2 && TARGET_SSE_MATH)
&& standard_80387_constant_p (operands[1]) > 0)
|| (TARGET_SSE2 && TARGET_SSE_MATH
@@ -3450,9 +3475,9 @@
"Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r ,rmF,rF"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (!can_create_pseudo_p ()
- || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
|| !CONST_DOUBLE_P (operands[1])
- || (optimize_function_for_size_p (cfun)
+ || ((optimize_function_for_size_p (cfun)
+ || (ix86_cmodel == CM_LARGE || ix86_cmodel == CM_LARGE_PIC))
&& ((!TARGET_SSE_MATH
&& standard_80387_constant_p (operands[1]) > 0)
|| (TARGET_SSE_MATH
@@ -3586,19 +3611,10 @@
&& (GET_MODE (operands[0]) == TFmode
|| GET_MODE (operands[0]) == XFmode
|| GET_MODE (operands[0]) == DFmode
- || GET_MODE (operands[0]) == SFmode)"
+ || GET_MODE (operands[0]) == SFmode)
+ && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
[(set (match_dup 0) (match_dup 2))]
-{
- operands[2] = find_constant_src (curr_insn);
-
- if (operands[2] == NULL_RTX
- || (SSE_REGNO_P (REGNO (operands[0]))
- && standard_sse_constant_p (operands[2],
- GET_MODE (operands[0])) != 1)
- || (STACK_REGNO_P (REGNO (operands[0]))
- && standard_80387_constant_p (operands[2]) < 1))
- FAIL;
-})
+ "operands[2] = find_constant_src (curr_insn);")
(define_split
[(set (match_operand 0 "any_fp_register_operand")
@@ -3606,19 +3622,10 @@
"reload_completed
&& (GET_MODE (operands[0]) == TFmode
|| GET_MODE (operands[0]) == XFmode
- || GET_MODE (operands[0]) == DFmode)"
+ || GET_MODE (operands[0]) == DFmode)
+ && ix86_standard_x87sse_constant_load_p (insn, operands[0])"
[(set (match_dup 0) (match_dup 2))]
-{
- operands[2] = find_constant_src (curr_insn);
-
- if (operands[2] == NULL_RTX
- || (SSE_REGNO_P (REGNO (operands[0]))
- && standard_sse_constant_p (operands[2],
- GET_MODE (operands[0])) != 1)
- || (STACK_REGNO_P (REGNO (operands[0]))
- && standard_80387_constant_p (operands[2]) < 1))
- FAIL;
-})
+ "operands[2] = find_constant_src (curr_insn);")
;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
(define_split
@@ -3762,20 +3769,18 @@
"split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
(define_split
- [(set (match_operand:DI 0 "register_operand")
- (zero_extend:DI (match_operand:SI 1 "register_operand")))]
+ [(set (match_operand:DI 0 "general_reg_operand")
+ (zero_extend:DI (match_operand:SI 1 "general_reg_operand")))]
"!TARGET_64BIT && reload_completed
- && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
- && true_regnum (operands[0]) == true_regnum (operands[1])"
+ && REGNO (operands[0]) == REGNO (operands[1])"
[(set (match_dup 4) (const_int 0))]
"split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
(define_split
- [(set (match_operand:DI 0 "nonimmediate_operand")
- (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
+ [(set (match_operand:DI 0 "nonimmediate_gr_operand")
+ (zero_extend:DI (match_operand:SI 1 "nonimmediate_gr_operand")))]
"!TARGET_64BIT && reload_completed
- && !(MEM_P (operands[0]) && MEM_P (operands[1]))
- && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
+ && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
[(set (match_dup 3) (match_dup 1))
(set (match_dup 4) (const_int 0))]
"split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
@@ -3813,7 +3818,8 @@
[(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])]
{
- if (true_regnum (operands[0]) != true_regnum (operands[1]))
+ if (!REG_P (operands[1])
+ || REGNO (operands[0]) != REGNO (operands[1]))
{
ix86_expand_clear (operands[0]);
@@ -3860,7 +3866,8 @@
[(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
(clobber (reg:CC FLAGS_REG))])]
{
- if (true_regnum (operands[0]) != true_regnum (operands[1]))
+ if (!REG_P (operands[1])
+ || REGNO (operands[0]) != REGNO (operands[1]))
{
ix86_expand_clear (operands[0]);
@@ -3973,8 +3980,8 @@
/* Generate a cltd if possible and doing so it profitable. */
if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
- && true_regnum (operands[1]) == AX_REG
- && true_regnum (operands[2]) == DX_REG)
+ && REGNO (operands[1]) == AX_REG
+ && REGNO (operands[2]) == DX_REG)
{
emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
}
@@ -4015,8 +4022,8 @@
(set (match_operand:SI 3 "memory_operand") (match_dup 2))]
"/* cltd is shorter than sarl $31, %eax */
!optimize_function_for_size_p (cfun)
- && true_regnum (operands[1]) == AX_REG
- && true_regnum (operands[2]) == DX_REG
+ && REGNO (operands[1]) == AX_REG
+ && REGNO (operands[2]) == DX_REG
&& peep2_reg_dead_p (2, operands[1])
&& peep2_reg_dead_p (3, operands[2])
&& !reg_mentioned_p (operands[2], operands[3])"
@@ -4037,19 +4044,19 @@
{
split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
- if (true_regnum (operands[3]) != true_regnum (operands[1]))
+ if (REGNO (operands[3]) != REGNO (operands[1]))
emit_move_insn (operands[3], operands[1]);
/* Generate a cltd if possible and doing so it profitable. */
if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
- && true_regnum (operands[3]) == AX_REG
- && true_regnum (operands[4]) == DX_REG)
+ && REGNO (operands[3]) == AX_REG
+ && REGNO (operands[4]) == DX_REG)
{
emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
DONE;
}
- if (true_regnum (operands[4]) != true_regnum (operands[1]))
+ if (REGNO (operands[4]) != REGNO (operands[1]))
emit_move_insn (operands[4], operands[1]);
emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
@@ -4188,15 +4195,15 @@
"operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
(define_expand "extendsfdf2"
- [(set (match_operand:DF 0 "nonimmediate_operand")
+ [(set (match_operand:DF 0 "nonimm_ssenomem_operand")
(float_extend:DF (match_operand:SF 1 "general_operand")))]
- "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
{
/* ??? Needed for compress_float_constant since all fp constants
are TARGET_LEGITIMATE_CONSTANT_P. */
if (CONST_DOUBLE_P (operands[1]))
{
- if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
+ if ((!SSE_FLOAT_MODE_P (DFmode) || TARGET_MIX_SSE_I387)
&& standard_80387_constant_p (operands[1]) > 0)
{
operands[1] = simplify_const_unary_operation
@@ -4216,12 +4223,12 @@
that might lead to ICE on 32bit target. The sequence unlikely combine
anyway. */
(define_split
- [(set (match_operand:DF 0 "register_operand")
+ [(set (match_operand:DF 0 "sse_reg_operand")
(float_extend:DF
(match_operand:SF 1 "nonimmediate_operand")))]
"TARGET_USE_VECTOR_FP_CONVERTS
&& optimize_insn_for_speed_p ()
- && reload_completed && SSE_REG_P (operands[0])
+ && reload_completed
&& (!EXT_REX_SSE_REG_P (operands[0])
|| TARGET_AVX512VL)"
[(set (match_dup 2)
@@ -4238,13 +4245,11 @@
{
/* If it is unsafe to overwrite upper half of source, we need
to move to destination and unpack there. */
- if (((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
- || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
- && true_regnum (operands[0]) != true_regnum (operands[1]))
+ if (REGNO (operands[0]) != REGNO (operands[1])
|| (EXT_REX_SSE_REG_P (operands[1])
&& !TARGET_AVX512VL))
{
- rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
+ rtx tmp = lowpart_subreg (SFmode, operands[0], DFmode);
emit_move_insn (tmp, operands[1]);
}
else
@@ -4252,7 +4257,7 @@
/* FIXME: vec_interleave_lowv4sf for AVX512VL should allow
=v, v, then vbroadcastss will be only needed for AVX512F without
AVX512VL. */
- if (!EXT_REX_SSE_REGNO_P (true_regnum (operands[3])))
+ if (!EXT_REX_SSE_REGNO_P (REGNO (operands[3])))
emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
operands[3]));
else
@@ -4268,21 +4273,20 @@
;; It's more profitable to split and then extend in the same register.
(define_peephole2
- [(set (match_operand:DF 0 "register_operand")
+ [(set (match_operand:DF 0 "sse_reg_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])"
+ && optimize_insn_for_speed_p ()"
[(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]));")
+ "operands[2] = lowpart_subreg (SFmode, operands[0], DFmode);")
-(define_insn "*extendsfdf2_mixed"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,v")
+(define_insn "*extendsfdf2"
+ [(set (match_operand:DF 0 "nonimm_ssenomem_operand" "=f,m,v")
(float_extend:DF
(match_operand:SF 1 "nonimmediate_operand" "fm,f,vm")))]
- "TARGET_SSE2 && TARGET_SSE_MATH"
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
{
switch (which_alternative)
{
@@ -4301,18 +4305,16 @@
(set_attr "prefix" "orig,orig,maybe_vex")
(set_attr "mode" "SF,XF,DF")
(set (attr "enabled")
- (cond [(eq_attr "alternative" "0,1")
- (symbol_ref "TARGET_MIX_SSE_I387")
- ]
- (symbol_ref "true")))])
-
-(define_insn "*extendsfdf2_i387"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
- (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
- "TARGET_80387"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "SF,XF")])
+ (if_then_else
+ (match_test ("SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"))
+ (if_then_else
+ (eq_attr "alternative" "0,1")
+ (symbol_ref "TARGET_MIX_SSE_I387")
+ (symbol_ref "true"))
+ (if_then_else
+ (eq_attr "alternative" "0,1")
+ (symbol_ref "true")
+ (symbol_ref "false"))))])
(define_expand "extend<mode>xf2"
[(set (match_operand:XF 0 "nonimmediate_operand")
@@ -4355,9 +4357,9 @@
[(set (match_operand:SF 0 "nonimmediate_operand")
(float_truncate:SF
(match_operand:DF 1 "nonimmediate_operand")))]
- "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
{
- if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
+ if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
;
else if (flag_unsafe_math_optimizations)
;
@@ -4377,12 +4379,12 @@
that might lead to ICE on 32bit target. The sequence unlikely combine
anyway. */
(define_split
- [(set (match_operand:SF 0 "register_operand")
+ [(set (match_operand:SF 0 "sse_reg_operand")
(float_truncate:SF
(match_operand:DF 1 "nonimmediate_operand")))]
"TARGET_USE_VECTOR_FP_CONVERTS
&& optimize_insn_for_speed_p ()
- && reload_completed && SSE_REG_P (operands[0])
+ && reload_completed
&& (!EXT_REX_SSE_REG_P (operands[0])
|| TARGET_AVX512VL)"
[(set (match_dup 2)
@@ -4400,9 +4402,7 @@
if (REG_P (operands[1]))
{
if (!TARGET_SSE3
- && true_regnum (operands[0]) != true_regnum (operands[1])
- && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
- || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
+ && REGNO (operands[0]) != REGNO (operands[1]))
{
rtx tmp = lowpart_subreg (DFmode, operands[0], SFmode);
emit_move_insn (tmp, operands[1]);
@@ -4419,15 +4419,14 @@
;; It's more profitable to split and then extend in the same register.
(define_peephole2
- [(set (match_operand:SF 0 "register_operand")
+ [(set (match_operand:SF 0 "sse_reg_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])"
+ && optimize_insn_for_speed_p ()"
[(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]));")
+ "operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
(define_expand "truncdfsf2_with_temp"
[(parallel [(set (match_operand:SF 0)
@@ -4440,7 +4439,7 @@
[(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
(float_truncate:SF
(match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
- "TARGET_SSE2 && TARGET_SSE_MATH"
+ "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
{
switch (which_alternative)
{
@@ -4472,9 +4471,9 @@
(set_attr "mode" "SF")])
(define_insn "*truncdfsf_mixed"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
(float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
+ (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
(clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
"TARGET_MIX_SSE_I387"
{
@@ -4496,7 +4495,7 @@
(set_attr "mode" "SF")])
(define_insn "*truncdfsf_i387"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
(float_truncate:SF
(match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
(clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
@@ -4534,7 +4533,7 @@
"reload_completed"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (match_dup 2))]
- "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
+ "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
;; Conversion from XFmode to {SF,DF}mode
@@ -4558,7 +4557,7 @@
})
(define_insn "*truncxfsf2_mixed"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
(float_truncate:SF
(match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
(clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
@@ -4572,7 +4571,7 @@
(set_attr "mode" "SF")])
(define_insn "*truncxfdf2_mixed"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
(float_truncate:DF
(match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
(clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
@@ -5140,11 +5139,11 @@
;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
;; alternative in sse2_loadld.
(define_split
- [(set (match_operand:MODEF 0 "register_operand")
+ [(set (match_operand:MODEF 0 "sse_reg_operand")
(float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed && SSE_REG_P (operands[0])
+ "TARGET_USE_VECTOR_CONVERTS
+ && optimize_function_for_speed_p (cfun)
+ && reload_completed
&& (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)
&& (!EXT_REX_SSE_REG_P (operands[0])
|| TARGET_AVX512VL)"
@@ -5163,83 +5162,83 @@
DONE;
})
-;; Avoid partial SSE register dependency stalls
+;; Avoid partial SSE register dependency stalls. This splitter should split
+;; late in the pass sequence (after register rename pass), so allocated
+;; registers won't change anymore
+
(define_split
- [(set (match_operand:MODEF 0 "register_operand")
+ [(set (match_operand:MODEF 0 "sse_reg_operand")
(float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_SSE_PARTIAL_REG_DEPENDENCY
+ "TARGET_SSE_PARTIAL_REG_DEPENDENCY
&& optimize_function_for_speed_p (cfun)
- && reload_completed && SSE_REG_P (operands[0])
+ && epilogue_completed
&& (!EXT_REX_SSE_REG_P (operands[0])
|| TARGET_AVX512VL)"
- [(const_int 0)]
+ [(set (match_dup 0)
+ (vec_merge:<MODEF:ssevecmode>
+ (vec_duplicate:<MODEF:ssevecmode>
+ (float:MODEF
+ (match_dup 1)))
+ (match_dup 0)
+ (const_int 1)))]
{
const machine_mode vmode = <MODEF:ssevecmode>mode;
- const machine_mode mode = <MODEF:MODE>mode;
- rtx t, op0 = lowpart_subreg (vmode, operands[0], mode);
- emit_move_insn (op0, CONST0_RTX (vmode));
-
- t = gen_rtx_FLOAT (mode, operands[1]);
- t = gen_rtx_VEC_DUPLICATE (vmode, t);
- t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
- emit_insn (gen_rtx_SET (op0, t));
- DONE;
+ operands[0] = lowpart_subreg (vmode, operands[0], <MODEF:MODE>mode);
+ emit_move_insn (operands[0], CONST0_RTX (vmode));
})
-;; Break partial reg stall for cvtsd2ss.
+;; Break partial reg stall for cvtsd2ss. This splitter should split
+;; late in the pass sequence (after register rename pass),
+;; so allocated registers won't change anymore.
-(define_peephole2
- [(set (match_operand:SF 0 "register_operand")
+(define_split
+ [(set (match_operand:SF 0 "sse_reg_operand")
(float_truncate:SF
(match_operand:DF 1 "nonimmediate_operand")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_SSE_PARTIAL_REG_DEPENDENCY
+ "TARGET_SSE_PARTIAL_REG_DEPENDENCY
&& optimize_function_for_speed_p (cfun)
- && SSE_REG_P (operands[0])
- && (!SSE_REG_P (operands[1])
+ && epilogue_completed
+ && (!REG_P (operands[1])
|| REGNO (operands[0]) != REGNO (operands[1]))
&& (!EXT_REX_SSE_REG_P (operands[0])
|| TARGET_AVX512VL)"
[(set (match_dup 0)
(vec_merge:V4SF
(vec_duplicate:V4SF
- (float_truncate:V2SF
+ (float_truncate:SF
(match_dup 1)))
(match_dup 0)
(const_int 1)))]
{
operands[0] = lowpart_subreg (V4SFmode, operands[0], SFmode);
- operands[1] = lowpart_subreg (V2DFmode, operands[1], DFmode);
emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
})
-;; Break partial reg stall for cvtss2sd.
+;; Break partial reg stall for cvtss2sd. This splitter should split
+;; late in the pass sequence (after register rename pass),
+;; so allocated registers won't change anymore.
-(define_peephole2
- [(set (match_operand:DF 0 "register_operand")
+(define_split
+ [(set (match_operand:DF 0 "sse_reg_operand")
(float_extend:DF
(match_operand:SF 1 "nonimmediate_operand")))]
- "TARGET_SSE2 && TARGET_SSE_MATH
- && TARGET_SSE_PARTIAL_REG_DEPENDENCY
+ "TARGET_SSE_PARTIAL_REG_DEPENDENCY
&& optimize_function_for_speed_p (cfun)
- && SSE_REG_P (operands[0])
- && (!SSE_REG_P (operands[1])
+ && epilogue_completed
+ && (!REG_P (operands[1])
|| REGNO (operands[0]) != REGNO (operands[1]))
&& (!EXT_REX_SSE_REG_P (operands[0])
|| TARGET_AVX512VL)"
[(set (match_dup 0)
(vec_merge:V2DF
- (float_extend:V2DF
- (vec_select:V2SF
- (match_dup 1)
- (parallel [(const_int 0) (const_int 1)])))
- (match_dup 0)
+ (vec_duplicate:V2DF
+ (float_extend:DF
+ (match_dup 1)))
+ (match_dup 0)
(const_int 1)))]
{
operands[0] = lowpart_subreg (V2DFmode, operands[0], DFmode);
- operands[1] = lowpart_subreg (V4SFmode, operands[1], SFmode);
emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
})
@@ -5284,7 +5283,7 @@
emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
operands[4]));
- operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
+ operands[3] = gen_lowpart (DImode, operands[3]);
})
(define_split
@@ -5427,7 +5426,7 @@
(define_expand "add<mode>3"
[(set (match_operand:SDWIM 0 "nonimmediate_operand")
(plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
- (match_operand:SDWIM 2 "<general_operand>")))]
+ (match_operand:SDWIM 2 "<general_hilo_operand>")))]
""
"ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
@@ -5435,7 +5434,8 @@
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
(plus:<DWI>
(match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
- (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
+ (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
+ "ro<di>,r<di>")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
"#"
@@ -5615,7 +5615,6 @@
(const_string "*")))
(set_attr "mode" "HI,HI,HI,SI")])
-;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
(define_insn "*addqi_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
(plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
@@ -5623,7 +5622,7 @@
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (PLUS, QImode, operands)"
{
- bool widen = (which_alternative == 3 || which_alternative == 4);
+ bool widen = (get_attr_mode (insn) != MODE_QI);
switch (get_attr_type (insn))
{
@@ -5672,7 +5671,12 @@
(and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
(const_string "1")
(const_string "*")))
- (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
+ (set_attr "mode" "QI,QI,QI,SI,SI,SI")
+ ;; Potential partial reg stall on alternatives 3 and 4.
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "3,4")
+ (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+ (symbol_ref "true")))])
(define_insn "*addqi_1_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
@@ -5721,32 +5725,6 @@
(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
(clobber (reg:CC FLAGS_REG))])])
-;; Convert add to the lea pattern to avoid flags dependency.
-(define_split
- [(set (match_operand:SWI 0 "register_operand")
- (plus:SWI (match_operand:SWI 1 "register_operand")
- (match_operand:SWI 2 "<nonmemory_operand>")))
- (clobber (reg:CC FLAGS_REG))]
- "reload_completed && ix86_lea_for_add_ok (insn, operands)"
- [(const_int 0)]
-{
- machine_mode mode = <MODE>mode;
- rtx pat;
-
- if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
- {
- mode = SImode;
- operands[0] = gen_lowpart (mode, operands[0]);
- operands[1] = gen_lowpart (mode, operands[1]);
- operands[2] = gen_lowpart (mode, operands[2]);
- }
-
- pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
-
- emit_insn (gen_rtx_SET (operands[0], pat));
- DONE;
-})
-
;; Split non destructive adds if we cannot use lea.
(define_split
[(set (match_operand:DI 0 "register_operand")
@@ -5764,6 +5742,24 @@
;; Convert add to the lea pattern to avoid flags dependency.
(define_split
+ [(set (match_operand:SWI 0 "register_operand")
+ (plus:SWI (match_operand:SWI 1 "register_operand")
+ (match_operand:SWI 2 "<nonmemory_operand>")))
+ (clobber (reg:CC FLAGS_REG))]
+ "reload_completed && ix86_lea_for_add_ok (insn, operands)"
+ [(set (match_dup 0)
+ (plus:<LEAMODE> (match_dup 1) (match_dup 2)))]
+{
+ if (<MODE>mode != <LEAMODE>mode)
+ {
+ operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
+ operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
+ operands[2] = gen_lowpart (<LEAMODE>mode, operands[2]);
+ }
+})
+
+;; Convert add to the lea pattern to avoid flags dependency.
+(define_split
[(set (match_operand:DI 0 "register_operand")
(zero_extend:DI
(plus:SI (match_operand:SI 1 "register_operand")
@@ -6248,7 +6244,7 @@
[(set (match_operand:SWI12 0 "register_operand" "=r")
(plus:SWI12
(mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
- (match_operand:SWI12 2 "const248_operand" "n"))
+ (match_operand 2 "const248_operand" "n"))
(match_operand:SWI12 3 "nonmemory_operand" "ri")))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
"#"
@@ -6270,7 +6266,7 @@
(plus:SWI12
(plus:SWI12
(mult:SWI12 (match_operand:SWI12 1 "index_register_operand" "l")
- (match_operand:SWI12 2 "const248_operand" "n"))
+ (match_operand 2 "const248_operand" "n"))
(match_operand:SWI12 3 "register_operand" "r"))
(match_operand:SWI12 4 "immediate_operand" "i")))]
"!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
@@ -6296,8 +6292,8 @@
(any_or:SWI12
(ashift:SWI12
(match_operand:SWI12 1 "index_register_operand" "l")
- (match_operand:SWI12 2 "const_0_to_3_operand" "n"))
- (match_operand:SWI12 3 "const_int_operand" "n")))]
+ (match_operand 2 "const_0_to_3_operand" "n"))
+ (match_operand 3 "const_int_operand" "n")))]
"(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
&& ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
< (HOST_WIDE_INT_1U << INTVAL (operands[2])))"
@@ -6320,8 +6316,8 @@
(any_or:SWI48
(ashift:SWI48
(match_operand:SWI48 1 "index_register_operand" "l")
- (match_operand:SWI48 2 "const_0_to_3_operand" "n"))
- (match_operand:SWI48 3 "const_int_operand" "n")))]
+ (match_operand 2 "const_0_to_3_operand" "n"))
+ (match_operand 3 "const_int_operand" "n")))]
"(unsigned HOST_WIDE_INT) INTVAL (operands[3])
< (HOST_WIDE_INT_1U << INTVAL (operands[2]))"
"#"
@@ -6339,7 +6335,7 @@
(define_expand "sub<mode>3"
[(set (match_operand:SDWIM 0 "nonimmediate_operand")
(minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
- (match_operand:SDWIM 2 "<general_operand>")))]
+ (match_operand:SDWIM 2 "<general_hilo_operand>")))]
""
"ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
@@ -6347,7 +6343,8 @@
[(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
(minus:<DWI>
(match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
- (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
+ (match_operand:<DWI> 2 "x86_64_hilo_general_operand"
+ "ro<di>,r<di>")))
(clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
"#"
@@ -7184,7 +7181,7 @@
(match_operand:DWIH 2 "nonimmediate_operand"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_BMI2 && reload_completed
- && true_regnum (operands[1]) == DX_REG"
+ && REGNO (operands[1]) == DX_REG"
[(parallel [(set (match_dup 3)
(mult:DWIH (match_dup 1) (match_dup 2)))
(set (match_dup 4)
@@ -8230,7 +8227,6 @@
(const_string "*")))
(set_attr "mode" "HI,HI,SI,HI")])
-;; %%% Potential partial reg stall on alternative 2. What to do?
(define_insn "*andqi_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
(and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
@@ -8253,7 +8249,12 @@
}
}
[(set_attr "type" "alu,alu,alu,msklog")
- (set_attr "mode" "QI,QI,SI,HI")])
+ (set_attr "mode" "QI,QI,SI,HI")
+ ;; Potential partial reg stall on alternative 2.
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "2")
+ (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+ (symbol_ref "true")))])
(define_insn "*andqi_1_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
@@ -8329,7 +8330,8 @@
(match_operand:SWI248 2 "const_int_operand")))
(clobber (reg:CC FLAGS_REG))]
"reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
+ && (!REG_P (operands[1])
+ || REGNO (operands[0]) != REGNO (operands[1]))"
[(const_int 0)]
{
HOST_WIDE_INT ival = INTVAL (operands[2]);
@@ -8737,7 +8739,6 @@
[(set_attr "type" "alu,alu,msklog")
(set_attr "mode" "HI")])
-;; %%% Potential partial reg stall on alternative 2. What to do?
(define_insn "*<code>qi_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
(any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
@@ -8750,7 +8751,12 @@
<logic>{l}\t{%k2, %k0|%k0, %k2}
k<logic>w\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "alu,alu,alu,msklog")
- (set_attr "mode" "QI,QI,SI,HI")])
+ (set_attr "mode" "QI,QI,SI,HI")
+ ;; Potential partial reg stall on alternative 2.
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "2")
+ (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+ (symbol_ref "true")))])
;; See comment for addsi_1_zext why we do use nonimmediate_operand
(define_insn "*<code>si_1_zext"
@@ -9235,27 +9241,33 @@
"TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
"ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
-(define_insn "*absneg<mode>2_mixed"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
+(define_insn "*absneg<mode>2"
+ [(set (match_operand:MODEF 0 "register_operand" "=Yv,Yv,f,!r")
(match_operator:MODEF 3 "absneg_operator"
- [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
- (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
+ [(match_operand:MODEF 1 "register_operand" "0,Yv,0,0")]))
+ (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "Yvm,0,X,X"))
(clobber (reg:CC FLAGS_REG))]
- "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
"#"
[(set (attr "enabled")
- (cond [(eq_attr "alternative" "2")
- (symbol_ref "TARGET_MIX_SSE_I387")
- ]
- (symbol_ref "true")))])
+ (if_then_else
+ (match_test ("SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"))
+ (if_then_else
+ (eq_attr "alternative" "2")
+ (symbol_ref "TARGET_MIX_SSE_I387")
+ (symbol_ref "true"))
+ (if_then_else
+ (eq_attr "alternative" "2,3")
+ (symbol_ref "true")
+ (symbol_ref "false"))))])
-(define_insn "*absneg<mode>2_i387"
- [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
- (match_operator:X87MODEF 3 "absneg_operator"
- [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
+(define_insn "*absnegxf2_i387"
+ [(set (match_operand:XF 0 "register_operand" "=f,!r")
+ (match_operator:XF 3 "absneg_operator"
+ [(match_operand:XF 1 "register_operand" "0,0")]))
(use (match_operand 2))
(clobber (reg:CC FLAGS_REG))]
- "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
+ "TARGET_80387"
"#")
(define_expand "<code>tf2"
@@ -9265,10 +9277,10 @@
"ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
(define_insn "*absnegtf2_sse"
- [(set (match_operand:TF 0 "register_operand" "=x,x")
+ [(set (match_operand:TF 0 "register_operand" "=Yv,Yv")
(match_operator:TF 3 "absneg_operator"
- [(match_operand:TF 1 "register_operand" "0,x")]))
- (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
+ [(match_operand:TF 1 "register_operand" "0,Yv")]))
+ (use (match_operand:TF 2 "nonimmediate_operand" "Yvm,0"))
(clobber (reg:CC FLAGS_REG))]
"TARGET_SSE"
"#")
@@ -9284,12 +9296,12 @@
[(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
(define_split
- [(set (match_operand 0 "register_operand")
+ [(set (match_operand 0 "sse_reg_operand")
(match_operator 3 "absneg_operator"
[(match_operand 1 "register_operand")]))
(use (match_operand 2 "nonimmediate_operand"))
(clobber (reg:CC FLAGS_REG))]
- "reload_completed && SSE_REG_P (operands[0])"
+ "reload_completed"
[(set (match_dup 0) (match_dup 3))]
{
machine_mode mode = GET_MODE (operands[0]);
@@ -9308,7 +9320,7 @@
})
(define_split
- [(set (match_operand:SF 0 "register_operand")
+ [(set (match_operand:SF 0 "general_reg_operand")
(match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
(use (match_operand:V4SF 2))
(clobber (reg:CC FLAGS_REG))]
@@ -9332,7 +9344,7 @@
})
(define_split
- [(set (match_operand:DF 0 "register_operand")
+ [(set (match_operand:DF 0 "general_reg_operand")
(match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
(use (match_operand 2))
(clobber (reg:CC FLAGS_REG))]
@@ -9370,7 +9382,7 @@
})
(define_split
- [(set (match_operand:XF 0 "register_operand")
+ [(set (match_operand:XF 0 "general_reg_operand")
(match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
(use (match_operand 2))
(clobber (reg:CC FLAGS_REG))]
@@ -9380,8 +9392,7 @@
{
rtx tmp;
operands[0] = gen_rtx_REG (SImode,
- true_regnum (operands[0])
- + (TARGET_64BIT ? 1 : 2));
+ REGNO (operands[0]) + (TARGET_64BIT ? 1 : 2));
if (GET_CODE (operands[1]) == ABS)
{
tmp = GEN_INT (0x7fff);
@@ -9449,11 +9460,11 @@
"ix86_expand_copysign (operands); DONE;")
(define_insn_and_split "copysign<mode>3_const"
- [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
+ [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv")
(unspec:CSGNMODE
- [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
+ [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "YvmC")
(match_operand:CSGNMODE 2 "register_operand" "0")
- (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
+ (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "Yvm")]
UNSPEC_COPYSIGN))]
"(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|| (TARGET_SSE && (<MODE>mode == TFmode))"
@@ -9463,14 +9474,16 @@
"ix86_split_copysign_const (operands); DONE;")
(define_insn "copysign<mode>3_var"
- [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
+ [(set (match_operand:CSGNMODE 0 "register_operand" "=Yv,Yv,Yv,Yv,Yv")
(unspec:CSGNMODE
- [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
- (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
- (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
- (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
+ [(match_operand:CSGNMODE 2 "register_operand" "Yv,0,0,Yv,Yv")
+ (match_operand:CSGNMODE 3 "register_operand" "1,1,Yv,1,Yv")
+ (match_operand:<CSGNVMODE> 4
+ "nonimmediate_operand" "X,Yvm,Yvm,0,0")
+ (match_operand:<CSGNVMODE> 5
+ "nonimmediate_operand" "0,Yvm,1,Yvm,1")]
UNSPEC_COPYSIGN))
- (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
+ (clobber (match_scratch:<CSGNVMODE> 1 "=Yv,Yv,Yv,Yv,Yv"))]
"(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|| (TARGET_SSE && (<MODE>mode == TFmode))"
"#")
@@ -9522,7 +9535,6 @@
(set_attr "prefix" "*,vex")
(set_attr "mode" "HI")])
-;; %%% Potential partial reg stall on alternative 1. What to do?
(define_insn "*one_cmplqi2_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
(not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
@@ -9545,7 +9557,12 @@
[(set_attr "isa" "*,*,avx512f")
(set_attr "type" "negnot,negnot,msklog")
(set_attr "prefix" "*,*,vex")
- (set_attr "mode" "QI,SI,QI")])
+ (set_attr "mode" "QI,SI,QI")
+ ;; Potential partial reg stall on alternative 1.
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "1")
+ (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+ (symbol_ref "true")))])
;; ??? Currently never generated - xor is used instead.
(define_insn "*one_cmplsi2_1_zext"
@@ -9964,7 +9981,6 @@
(const_string "*")))
(set_attr "mode" "HI,SI")])
-;; %%% Potential partial reg stall on alternative 1. What to do?
(define_insn "*ashlqi3_1"
[(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
(ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
@@ -10020,7 +10036,12 @@
(match_test "optimize_function_for_size_p (cfun)")))))
(const_string "0")
(const_string "*")))
- (set_attr "mode" "QI,SI,SI")])
+ (set_attr "mode" "QI,SI,SI")
+ ;; Potential partial reg stall on alternative 1.
+ (set (attr "preferred_for_speed")
+ (cond [(eq_attr "alternative" "1")
+ (symbol_ref "!TARGET_PARTIAL_REG_STALL")]
+ (symbol_ref "true")))])
(define_insn "*ashlqi3_1_slp"
[(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
@@ -10067,31 +10088,21 @@
;; Convert ashift to the lea pattern to avoid flags dependency.
(define_split
- [(set (match_operand 0 "register_operand")
- (ashift (match_operand 1 "index_register_operand")
- (match_operand:QI 2 "const_int_operand")))
+ [(set (match_operand:SWI 0 "register_operand")
+ (ashift:SWI (match_operand:SWI 1 "index_register_operand")
+ (match_operand 2 "const_0_to_3_operand")))
(clobber (reg:CC FLAGS_REG))]
- "GET_MODE (operands[0]) == GET_MODE (operands[1])
- && reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
- [(const_int 0)]
+ "reload_completed
+ && REGNO (operands[0]) != REGNO (operands[1])"
+ [(set (match_dup 0)
+ (mult:<LEAMODE> (match_dup 1) (match_dup 2)))]
{
- machine_mode mode = GET_MODE (operands[0]);
- rtx pat;
-
- if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
- {
- mode = SImode;
- operands[0] = gen_lowpart (mode, operands[0]);
- operands[1] = gen_lowpart (mode, operands[1]);
+ if (<MODE>mode != <LEAMODE>mode)
+ {
+ operands[0] = gen_lowpart (<LEAMODE>mode, operands[0]);
+ operands[1] = gen_lowpart (<LEAMODE>mode, operands[1]);
}
-
- operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
-
- pat = gen_rtx_MULT (mode, operands[1], operands[2]);
-
- emit_insn (gen_rtx_SET (operands[0], pat));
- DONE;
+ operands[2] = GEN_INT (1 << INTVAL (operands[2]));
})
;; Convert ashift to the lea pattern to avoid flags dependency.
@@ -10099,15 +10110,15 @@
[(set (match_operand:DI 0 "register_operand")
(zero_extend:DI
(ashift:SI (match_operand:SI 1 "index_register_operand")
- (match_operand:QI 2 "const_int_operand"))))
+ (match_operand 2 "const_0_to_3_operand"))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && reload_completed
- && true_regnum (operands[0]) != true_regnum (operands[1])"
+ && REGNO (operands[0]) != REGNO (operands[1])"
[(set (match_dup 0)
(zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
{
operands[1] = gen_lowpart (SImode, operands[1]);
- operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
+ operands[2] = GEN_INT (1 << INTVAL (operands[2]));
})
;; This pattern can't accept a variable shift count, since shifts by
@@ -11054,20 +11065,19 @@
(const_int 1))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_64BIT && !TARGET_USE_BT"
- [(const_int 0)]
+ [(parallel [(set (match_dup 0)
+ (ior:DI (match_dup 0) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))])]
{
int i = INTVAL (operands[1]);
- rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
+ operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
- if (i >= 31)
+ if (!x86_64_immediate_operand (operands[3], DImode))
{
- emit_move_insn (operands[2], op1);
- op1 = operands[2];
+ emit_move_insn (operands[2], operands[3]);
+ operands[3] = operands[2];
}
-
- emit_insn (gen_iordi3 (operands[0], operands[0], op1));
- DONE;
})
(define_peephole2
@@ -11079,20 +11089,19 @@
(const_int 0))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_64BIT && !TARGET_USE_BT"
- [(const_int 0)]
+ [(parallel [(set (match_dup 0)
+ (and:DI (match_dup 0) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))])]
{
int i = INTVAL (operands[1]);
- rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
+ operands[3] = gen_int_mode (~(HOST_WIDE_INT_1U << i), DImode);
- if (i >= 32)
+ if (!x86_64_immediate_operand (operands[3], DImode))
{
- emit_move_insn (operands[2], op1);
- op1 = operands[2];
+ emit_move_insn (operands[2], operands[3]);
+ operands[3] = operands[2];
}
-
- emit_insn (gen_anddi3 (operands[0], operands[0], op1));
- DONE;
})
(define_peephole2
@@ -11105,20 +11114,19 @@
(match_dup 0) (const_int 1) (match_dup 1))))
(clobber (reg:CC FLAGS_REG))])]
"TARGET_64BIT && !TARGET_USE_BT"
- [(const_int 0)]
+ [(parallel [(set (match_dup 0)
+ (xor:DI (match_dup 0) (match_dup 3)))
+ (clobber (reg:CC FLAGS_REG))])]
{
int i = INTVAL (operands[1]);
- rtx op1 = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
+ operands[3] = gen_int_mode (HOST_WIDE_INT_1U << i, DImode);
- if (i >= 31)
+ if (!x86_64_immediate_operand (operands[3], DImode))
{
- emit_move_insn (operands[2], op1);
- op1 = operands[2];
+ emit_move_insn (operands[2], operands[3]);
+ operands[3] = operands[2];
}
-
- emit_insn (gen_xordi3 (operands[0], operands[0], op1));
- DONE;
})
(define_insn "*bt<mode>"
@@ -11942,7 +11950,10 @@
(match_operand:SI 0 "GOT_memory_operand" "Bg")))
(match_operand 1))]
"TARGET_X32"
- "* return ix86_output_call_insn (insn, operands[0]);"
+{
+ rtx fnaddr = gen_const_mem (DImode, XEXP (operands[0], 0));
+ return ix86_output_call_insn (insn, fnaddr);
+}
[(set_attr "type" "call")])
;; Since sibcall never returns, we can only use call-clobbered register
@@ -11955,8 +11966,8 @@
(match_operand 2))]
"!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
{
- rtx fnaddr = gen_rtx_PLUS (Pmode, operands[0], operands[1]);
- fnaddr = gen_const_mem (Pmode, fnaddr);
+ rtx fnaddr = gen_rtx_PLUS (SImode, operands[0], operands[1]);
+ fnaddr = gen_const_mem (SImode, fnaddr);
return ix86_output_call_insn (insn, fnaddr);
}
[(set_attr "type" "call")])
@@ -12135,7 +12146,10 @@
(match_operand:SI 1 "GOT_memory_operand" "Bg")))
(match_operand 2)))]
"TARGET_X32"
- "* return ix86_output_call_insn (insn, operands[1]);"
+{
+ rtx fnaddr = gen_const_mem (DImode, XEXP (operands[1], 0));
+ return ix86_output_call_insn (insn, fnaddr);
+}
[(set_attr "type" "callv")])
;; Since sibcall never returns, we can only use call-clobbered register
@@ -12149,8 +12163,8 @@
(match_operand 3)))]
"!TARGET_MACHO && !TARGET_64BIT && SIBLING_CALL_P (insn)"
{
- rtx fnaddr = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
- fnaddr = gen_const_mem (Pmode, fnaddr);
+ rtx fnaddr = gen_rtx_PLUS (SImode, operands[1], operands[2]);
+ fnaddr = gen_const_mem (SImode, fnaddr);
return ix86_output_call_insn (insn, fnaddr);
}
[(set_attr "type" "callv")])
@@ -12513,7 +12527,7 @@
(define_expand "set_got"
[(parallel
- [(set (match_operand:SI 0 "register_operand" "=r")
+ [(set (match_operand:SI 0 "register_operand")
(unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
(clobber (reg:CC FLAGS_REG))])]
"!TARGET_64BIT"
@@ -12533,7 +12547,7 @@
(define_expand "set_got_labelled"
[(parallel
- [(set (match_operand:SI 0 "register_operand" "=r")
+ [(set (match_operand:SI 0 "register_operand")
(unspec:SI [(label_ref (match_operand 1))]
UNSPEC_SET_GOT))
(clobber (reg:CC FLAGS_REG))])]
@@ -14039,9 +14053,9 @@
[(set (match_operand:MODEF 0 "register_operand" "=f,f,x,v")
(match_operator:MODEF 3 "binary_fp_operator"
[(match_operand:MODEF 1
- "nonimm_ssenomem_operand" "0,fm,0,v")
+ "x87nonimm_ssenomem_operand" "0,fm,0,v")
(match_operand:MODEF 2
- "nonimmediate_operand" "fm,0,xm,vm")]))]
+ "nonimmediate_operand" "fm,0,xm,vm")]))]
"((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
|| (TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)))
&& !COMMUTATIVE_ARITH_P (operands[3])
@@ -17215,7 +17229,7 @@
(set_attr "mode" "DF,DF,DI,DI,DI,DI")])
(define_split
- [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
+ [(set (match_operand:DF 0 "general_reg_operand")
(if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
(match_operand:DF 2 "nonimmediate_operand")
@@ -17271,7 +17285,7 @@
;; Don't do conditional moves with memory inputs
(define_peephole2
[(match_scratch:MODEF 4 "r")
- (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
+ (set (match_operand:MODEF 0 "general_reg_operand")
(if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
[(reg FLAGS_REG) (const_int 0)])
(match_operand:MODEF 2 "nonimmediate_operand")
@@ -17821,7 +17835,7 @@
(match_operand:SI 3 "immediate_operand"))
(const_int 0)]))]
"ix86_match_ccmode (insn, CCNOmode)
- && (true_regnum (operands[2]) != AX_REG
+ && (REGNO (operands[2]) != AX_REG
|| satisfies_constraint_K (operands[3]))
&& peep2_reg_dead_p (1, operands[2])"
[(parallel
@@ -17842,7 +17856,7 @@
(const_int 0)]))]
"! TARGET_PARTIAL_REG_STALL
&& ix86_match_ccmode (insn, CCNOmode)
- && true_regnum (operands[2]) != AX_REG
+ && REGNO (operands[2]) != AX_REG
&& peep2_reg_dead_p (1, operands[2])"
[(parallel
[(set (match_dup 0)
@@ -17863,7 +17877,7 @@
(const_int 0)]))]
"! TARGET_PARTIAL_REG_STALL
&& ix86_match_ccmode (insn, CCNOmode)
- && true_regnum (operands[2]) != AX_REG
+ && REGNO (operands[2]) != AX_REG
&& peep2_reg_dead_p (1, operands[2])"
[(parallel [(set (match_dup 0)
(match_op_dup 1
@@ -19032,7 +19046,7 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define_expand "lwp_llwpcb"
- [(unspec_volatile [(match_operand 0 "register_operand" "r")]
+ [(unspec_volatile [(match_operand 0 "register_operand")]
UNSPECV_LLWP_INTRINSIC)]
"TARGET_LWP")
@@ -19046,7 +19060,7 @@
(set_attr "length" "5")])
(define_expand "lwp_slwpcb"
- [(set (match_operand 0 "register_operand" "=r")
+ [(set (match_operand 0 "register_operand")
(unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
"TARGET_LWP"
{
@@ -19070,9 +19084,9 @@
(set_attr "length" "5")])
(define_expand "lwp_lwpval<mode>3"
- [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
- (match_operand:SI 2 "nonimmediate_operand" "rm")
- (match_operand:SI 3 "const_int_operand" "i")]
+ [(unspec_volatile [(match_operand:SWI48 1 "register_operand")
+ (match_operand:SI 2 "nonimmediate_operand")
+ (match_operand:SI 3 "const_int_operand")]
UNSPECV_LWPVAL_INTRINSIC)]
"TARGET_LWP"
;; Avoid unused variable warning.
@@ -19092,11 +19106,11 @@
(define_expand "lwp_lwpins<mode>3"
[(set (reg:CCC FLAGS_REG)
- (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
- (match_operand:SI 2 "nonimmediate_operand" "rm")
- (match_operand:SI 3 "const_int_operand" "i")]
+ (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand")
+ (match_operand:SI 2 "nonimmediate_operand")
+ (match_operand:SI 3 "const_int_operand")]
UNSPECV_LWPINS_INTRINSIC))
- (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
+ (set (match_operand:QI 0 "nonimmediate_operand")
(eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
"TARGET_LWP")
diff --git a/gcc/config/i386/mingw32.h b/gcc/config/i386/mingw32.h
index e04818966fa..0407efe7df3 100644
--- a/gcc/config/i386/mingw32.h
+++ b/gcc/config/i386/mingw32.h
@@ -100,10 +100,12 @@ along with GCC; see the file COPYING3. If not see
#if DWARF2_UNWIND_INFO
/* DW2-unwind is just available for 32-bit mode. */
#if TARGET_64BIT_DEFAULT
-#error DW2 unwind is not available for 64-bit.
-#endif
+#define SHARED_LIBGCC_UNDEFS_SPEC \
+ "%{m32: %{shared-libgcc: -u ___register_frame_info -u ___deregister_frame_info}}"
+#else
#define SHARED_LIBGCC_UNDEFS_SPEC \
"%{shared-libgcc: -u ___register_frame_info -u ___deregister_frame_info}"
+#endif
#else
#define SHARED_LIBGCC_UNDEFS_SPEC ""
#endif
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index fe9bb2bc695..b3cf2a3cb04 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -27,11 +27,6 @@
(and (match_code "reg")
(match_test "STACK_REGNO_P (REGNO (op))")))
-;; Return true if OP is a non-fp register_operand.
-(define_predicate "register_and_not_any_fp_reg_operand"
- (and (match_code "reg")
- (not (match_test "ANY_FP_REGNO_P (REGNO (op))"))))
-
;; True if the operand is a GENERAL class register.
(define_predicate "general_reg_operand"
(and (match_code "reg")
@@ -43,11 +38,6 @@
(match_test "GENERAL_REGNO_P (REGNO (op))")
(match_operand 0 "nonimmediate_operand")))
-;; Return true if OP is a register operand other than an i387 fp register.
-(define_predicate "register_and_not_fp_reg_operand"
- (and (match_code "reg")
- (not (match_test "STACK_REGNO_P (REGNO (op))"))))
-
;; True if the operand is an MMX register.
(define_predicate "mmx_reg_operand"
(and (match_code "reg")
@@ -121,11 +111,26 @@
(match_operand 0 "nonmemory_operand")
(match_operand 0 "general_operand")))
+;; Match register operands, but include memory operands for TARGET_SSE_MATH.
+(define_predicate "register_ssemem_operand"
+ (if_then_else
+ (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH")
+ (match_operand 0 "nonimmediate_operand")
+ (match_operand 0 "register_operand")))
+
;; Match nonimmediate operands, but exclude memory operands
;; for TARGET_SSE_MATH if TARGET_MIX_SSE_I387 is not enabled.
(define_predicate "nonimm_ssenomem_operand"
(if_then_else
(and (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH")
+ (not (match_test "TARGET_MIX_SSE_I387")))
+ (match_operand 0 "register_operand")
+ (match_operand 0 "nonimmediate_operand")))
+
+;; The above predicate, suitable for x87 arithmetic operators.
+(define_predicate "x87nonimm_ssenomem_operand"
+ (if_then_else
+ (and (match_test "SSE_FLOAT_MODE_P (mode) && TARGET_SSE_MATH")
(not (match_test "TARGET_MIX_SSE_I387 && X87_ENABLE_ARITH (mode)")))
(match_operand 0 "register_operand")
(match_operand 0 "nonimmediate_operand")))
@@ -335,6 +340,29 @@
return false;
})
+;; Return true if VALUE is a constant integer whose low and high words satisfy
+;; x86_64_immediate_operand.
+(define_predicate "x86_64_hilo_int_operand"
+ (match_code "const_int,const_wide_int")
+{
+ switch (GET_CODE (op))
+ {
+ case CONST_INT:
+ return x86_64_immediate_operand (op, mode);
+
+ case CONST_WIDE_INT:
+ gcc_assert (CONST_WIDE_INT_NUNITS (op) == 2);
+ return (x86_64_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (op, 0)),
+ DImode)
+ && x86_64_immediate_operand (GEN_INT (CONST_WIDE_INT_ELT (op,
+ 1)),
+ DImode));
+
+ default:
+ gcc_unreachable ();
+ }
+})
+
;; Return true if size of VALUE can be stored in a sign
;; extended immediate field.
(define_predicate "x86_64_immediate_size_operand"
@@ -350,6 +378,14 @@
(match_operand 0 "x86_64_immediate_operand"))
(match_operand 0 "general_operand")))
+;; Return true if OP's both words are general operands representable
+;; on x86_64.
+(define_predicate "x86_64_hilo_general_operand"
+ (if_then_else (match_test "TARGET_64BIT")
+ (ior (match_operand 0 "nonimmediate_operand")
+ (match_operand 0 "x86_64_hilo_int_operand"))
+ (match_operand 0 "general_operand")))
+
;; Return true if OP is non-VOIDmode general operand representable
;; on x86_64. This predicate is used in sign-extending conversion
;; operations that require non-VOIDmode immediate operands.
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 42d553cfdaa..745b6b665f5 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -778,6 +778,12 @@
(V64QI "i64x4") (V32QI "%~128") (V32HI "i64x4") (V16HI "%~128")
(V16SI "i64x4") (V8SI "%~128") (V8DI "i64x4") (V4DI "%~128")])
+;; For 256-bit modes for TARGET_AVX512VL && TARGET_AVX512DQ
+;; i32x4, f32x4, i64x2 or f64x2 suffixes.
+(define_mode_attr i128vldq
+ [(V8SF "f32x4") (V4DF "f64x2")
+ (V32QI "i32x4") (V16HI "i32x4") (V8SI "i32x4") (V4DI "i64x2")])
+
;; Mix-n-match
(define_mode_iterator AVX256MODE2P [V8SI V8SF V4DF])
(define_mode_iterator AVX512MODE2P [V16SI V16SF V8DF])
@@ -1076,10 +1082,10 @@
(set_attr "mode" "<sseinsnmode>")])
(define_insn "sse2_movq128"
- [(set (match_operand:V2DI 0 "register_operand" "=x")
+ [(set (match_operand:V2DI 0 "register_operand" "=v")
(vec_concat:V2DI
(vec_select:DI
- (match_operand:V2DI 1 "nonimmediate_operand" "xm")
+ (match_operand:V2DI 1 "nonimmediate_operand" "vm")
(parallel [(const_int 0)]))
(const_int 0)))]
"TARGET_SSE2"
@@ -1485,7 +1491,7 @@
(match_operand:VF_128 2 "register_operand" "v")
(const_int 1)))]
"TARGET_AVX512F"
- "vrcp14<ssescalarmodesuffix>\t{%1, %2, %0|%0, %2, %1}"
+ "vrcp14<ssescalarmodesuffix>\t{%1, %2, %0|%0, %2, %<iptr>1}"
[(set_attr "type" "sse")
(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
@@ -1583,7 +1589,7 @@
(match_operand:VF_128 2 "register_operand" "v")
(const_int 1)))]
"TARGET_AVX512F"
- "vrsqrt14<ssescalarmodesuffix>\t{%1, %2, %0|%0, %2, %1}"
+ "vrsqrt14<ssescalarmodesuffix>\t{%1, %2, %0|%0, %2, %<iptr>1}"
[(set_attr "type" "sse")
(set_attr "prefix" "evex")
(set_attr "mode" "<MODE>")])
@@ -2783,54 +2789,61 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define_insn "<sse>_andnot<mode>3<mask_name>"
- [(set (match_operand:VF_128_256 0 "register_operand" "=x,v")
+ [(set (match_operand:VF_128_256 0 "register_operand" "=x,x,v,v")
(and:VF_128_256
(not:VF_128_256
- (match_operand:VF_128_256 1 "register_operand" "0,v"))
- (match_operand:VF_128_256 2 "vector_operand" "xBm,vm")))]
+ (match_operand:VF_128_256 1 "register_operand" "0,x,v,v"))
+ (match_operand:VF_128_256 2 "vector_operand" "xBm,xm,vm,vm")))]
"TARGET_SSE && <mask_avx512vl_condition>"
{
static char buf[128];
const char *ops;
const char *suffix;
- switch (get_attr_mode (insn))
- {
- case MODE_V8SF:
- case MODE_V4SF:
- suffix = "ps";
- break;
- default:
- suffix = "<ssemodesuffix>";
- }
-
switch (which_alternative)
{
case 0:
ops = "andn%s\t{%%2, %%0|%%0, %%2}";
break;
case 1:
+ case 2:
+ case 3:
ops = "vandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
break;
default:
gcc_unreachable ();
}
- /* There is no vandnp[sd] in avx512f. Use vpandn[qd]. */
- if (<mask_applied> && !TARGET_AVX512DQ)
+ switch (get_attr_mode (insn))
{
+ case MODE_V8SF:
+ case MODE_V4SF:
+ suffix = "ps";
+ break;
+ case MODE_OI:
+ case MODE_TI:
+ /* There is no vandnp[sd] in avx512f. Use vpandn[qd]. */
suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
ops = "vpandn%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
+ break;
+ default:
+ suffix = "<ssemodesuffix>";
}
snprintf (buf, sizeof (buf), ops, suffix);
return buf;
}
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512dq,avx512f")
(set_attr "type" "sselog")
- (set_attr "prefix" "orig,maybe_evex")
+ (set_attr "prefix" "orig,maybe_vex,evex,evex")
(set (attr "mode")
- (cond [(and (match_test "<MODE_SIZE> == 16")
+ (cond [(and (match_test "<mask_applied>")
+ (and (eq_attr "alternative" "1")
+ (match_test "!TARGET_AVX512DQ")))
+ (const_string "<sseintvecmode2>")
+ (eq_attr "alternative" "3")
+ (const_string "<sseintvecmode2>")
+ (and (match_test "<MODE_SIZE> == 16")
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "<ssePSmode>")
(match_test "TARGET_AVX")
@@ -2870,7 +2883,10 @@
}
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
- (set_attr "mode" "<sseinsnmode>")])
+ (set (attr "mode")
+ (if_then_else (match_test "TARGET_AVX512DQ")
+ (const_string "<sseinsnmode>")
+ (const_string "XI")))])
(define_expand "<code><mode>3<mask_name>"
[(set (match_operand:VF_128_256 0 "register_operand")
@@ -2889,10 +2905,10 @@
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
(define_insn "*<code><mode>3<mask_name>"
- [(set (match_operand:VF_128_256 0 "register_operand" "=x,v")
+ [(set (match_operand:VF_128_256 0 "register_operand" "=x,x,v,v")
(any_logic:VF_128_256
- (match_operand:VF_128_256 1 "vector_operand" "%0,v")
- (match_operand:VF_128_256 2 "vector_operand" "xBm,vm")))]
+ (match_operand:VF_128_256 1 "vector_operand" "%0,x,v,v")
+ (match_operand:VF_128_256 2 "vector_operand" "xBm,xm,vm,vm")))]
"TARGET_SSE && <mask_avx512vl_condition>
&& ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
{
@@ -2900,43 +2916,50 @@
const char *ops;
const char *suffix;
- switch (get_attr_mode (insn))
- {
- case MODE_V8SF:
- case MODE_V4SF:
- suffix = "ps";
- break;
- default:
- suffix = "<ssemodesuffix>";
- }
-
switch (which_alternative)
{
case 0:
ops = "<logic>%s\t{%%2, %%0|%%0, %%2}";
break;
case 1:
+ case 2:
+ case 3:
ops = "v<logic>%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
break;
default:
gcc_unreachable ();
}
- /* There is no v<logic>p[sd] in avx512f. Use vp<logic>[dq]. */
- if (<mask_applied> && !TARGET_AVX512DQ)
+ switch (get_attr_mode (insn))
{
+ case MODE_V8SF:
+ case MODE_V4SF:
+ suffix = "ps";
+ break;
+ case MODE_OI:
+ case MODE_TI:
+ /* There is no v<logic>p[sd] in avx512f. Use vp<logic>[qd]. */
suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
ops = "vp<logic>%s\t{%%2, %%1, %%0<mask_operand3_1>|%%0<mask_operand3_1>, %%1, %%2}";
+ break;
+ default:
+ suffix = "<ssemodesuffix>";
}
snprintf (buf, sizeof (buf), ops, suffix);
return buf;
}
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512dq,avx512f")
(set_attr "type" "sselog")
- (set_attr "prefix" "orig,maybe_evex")
+ (set_attr "prefix" "orig,maybe_evex,evex,evex")
(set (attr "mode")
- (cond [(and (match_test "<MODE_SIZE> == 16")
+ (cond [(and (match_test "<mask_applied>")
+ (and (eq_attr "alternative" "1")
+ (match_test "!TARGET_AVX512DQ")))
+ (const_string "<sseintvecmode2>")
+ (eq_attr "alternative" "3")
+ (const_string "<sseintvecmode2>")
+ (and (match_test "<MODE_SIZE> == 16")
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "<ssePSmode>")
(match_test "TARGET_AVX")
@@ -2961,7 +2984,7 @@
ops = "";
/* There is no v<logic>p[sd] in avx512f. Use vp<logic>[dq]. */
- if ((<MODE_SIZE> == 64 || <mask_applied>) && !TARGET_AVX512DQ)
+ if (!TARGET_AVX512DQ)
{
suffix = GET_MODE_INNER (<MODE>mode) == DFmode ? "q" : "d";
ops = "p";
@@ -2974,7 +2997,10 @@
}
[(set_attr "type" "sselog")
(set_attr "prefix" "evex")
- (set_attr "mode" "<sseinsnmode>")])
+ (set (attr "mode")
+ (if_then_else (match_test "TARGET_AVX512DQ")
+ (const_string "<sseinsnmode>")
+ (const_string "XI")))])
(define_expand "copysign<mode>3"
[(set (match_dup 4)
@@ -3000,14 +3026,14 @@
;; because the native instructions read the full 128-bits.
(define_insn "*andnot<mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,x,v,v")
(and:MODEF
(not:MODEF
- (match_operand:MODEF 1 "register_operand" "0,x"))
- (match_operand:MODEF 2 "register_operand" "x,x")))]
+ (match_operand:MODEF 1 "register_operand" "0,x,v,v"))
+ (match_operand:MODEF 2 "register_operand" "x,x,v,v")))]
"SSE_FLOAT_MODE_P (<MODE>mode)"
{
- static char buf[32];
+ static char buf[128];
const char *ops;
const char *suffix
= (get_attr_mode (insn) == MODE_V4SF) ? "ps" : "<ssevecmodesuffix>";
@@ -3020,6 +3046,24 @@
case 1:
ops = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
break;
+ case 2:
+ if (TARGET_AVX512DQ)
+ ops = "vandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+ else
+ {
+ suffix = <MODE>mode == DFmode ? "q" : "d";
+ ops = "vpandn%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+ }
+ break;
+ case 3:
+ if (TARGET_AVX512DQ)
+ ops = "vandn%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}";
+ else
+ {
+ suffix = <MODE>mode == DFmode ? "q" : "d";
+ ops = "vpandn%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}";
+ }
+ break;
default:
gcc_unreachable ();
}
@@ -3027,11 +3071,19 @@
snprintf (buf, sizeof (buf), ops, suffix);
return buf;
}
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512vl,avx512f")
(set_attr "type" "sselog")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,vex,evex,evex")
(set (attr "mode")
- (cond [(and (match_test "<MODE_SIZE> == 16")
+ (cond [(eq_attr "alternative" "2")
+ (if_then_else (match_test "TARGET_AVX512DQ")
+ (const_string "<ssevecmode>")
+ (const_string "TI"))
+ (eq_attr "alternative" "3")
+ (if_then_else (match_test "TARGET_AVX512DQ")
+ (const_string "<avx512fvecmode>")
+ (const_string "XI"))
+ (and (match_test "<MODE_SIZE> == 16")
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "V4SF")
(match_test "TARGET_AVX")
@@ -3042,16 +3094,17 @@
(const_string "<ssevecmode>")))])
(define_insn "*andnottf3"
- [(set (match_operand:TF 0 "register_operand" "=x,x")
+ [(set (match_operand:TF 0 "register_operand" "=x,x,v,v")
(and:TF
- (not:TF (match_operand:TF 1 "register_operand" "0,x"))
- (match_operand:TF 2 "vector_operand" "xBm,xm")))]
+ (not:TF (match_operand:TF 1 "register_operand" "0,x,v,v"))
+ (match_operand:TF 2 "vector_operand" "xBm,xm,vm,v")))]
"TARGET_SSE"
{
- static char buf[32];
+ static char buf[128];
const char *ops;
const char *tmp
- = (get_attr_mode (insn) == MODE_V4SF) ? "andnps" : "pandn";
+ = (which_alternative >= 2 ? "pandnq"
+ : get_attr_mode (insn) == MODE_V4SF ? "andnps" : "pandn");
switch (which_alternative)
{
@@ -3059,8 +3112,12 @@
ops = "%s\t{%%2, %%0|%%0, %%2}";
break;
case 1:
+ case 2:
ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
break;
+ case 3:
+ ops = "v%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}";
+ break;
default:
gcc_unreachable ();
}
@@ -3068,7 +3125,7 @@
snprintf (buf, sizeof (buf), ops, tmp);
return buf;
}
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512vl,avx512f")
(set_attr "type" "sselog")
(set (attr "prefix_data16")
(if_then_else
@@ -3076,9 +3133,13 @@
(eq_attr "mode" "TI"))
(const_string "1")
(const_string "*")))
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,vex,evex,evex")
(set (attr "mode")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
+ (cond [(eq_attr "alternative" "2")
+ (const_string "TI")
+ (eq_attr "alternative" "3")
+ (const_string "XI")
+ (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
(const_string "V4SF")
(match_test "TARGET_AVX")
(const_string "TI")
@@ -3089,13 +3150,13 @@
(const_string "TI")))])
(define_insn "*<code><mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,x,v,v")
(any_logic:MODEF
- (match_operand:MODEF 1 "register_operand" "%0,x")
- (match_operand:MODEF 2 "register_operand" "x,x")))]
+ (match_operand:MODEF 1 "register_operand" "%0,x,v,v")
+ (match_operand:MODEF 2 "register_operand" "x,x,v,v")))]
"SSE_FLOAT_MODE_P (<MODE>mode)"
{
- static char buf[32];
+ static char buf[128];
const char *ops;
const char *suffix
= (get_attr_mode (insn) == MODE_V4SF) ? "ps" : "<ssevecmodesuffix>";
@@ -3105,9 +3166,26 @@
case 0:
ops = "<logic>%s\t{%%2, %%0|%%0, %%2}";
break;
+ case 2:
+ if (!TARGET_AVX512DQ)
+ {
+ suffix = <MODE>mode == DFmode ? "q" : "d";
+ ops = "vp<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
+ break;
+ }
+ /* FALLTHRU */
case 1:
ops = "v<logic>%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
break;
+ case 3:
+ if (TARGET_AVX512DQ)
+ ops = "v<logic>%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}";
+ else
+ {
+ suffix = <MODE>mode == DFmode ? "q" : "d";
+ ops = "vp<logic>%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}";
+ }
+ break;
default:
gcc_unreachable ();
}
@@ -3115,11 +3193,19 @@
snprintf (buf, sizeof (buf), ops, suffix);
return buf;
}
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512vl,avx512f")
(set_attr "type" "sselog")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,vex,evex,evex")
(set (attr "mode")
- (cond [(and (match_test "<MODE_SIZE> == 16")
+ (cond [(eq_attr "alternative" "2")
+ (if_then_else (match_test "TARGET_AVX512DQ")
+ (const_string "<ssevecmode>")
+ (const_string "TI"))
+ (eq_attr "alternative" "3")
+ (if_then_else (match_test "TARGET_AVX512DQ")
+ (const_string "<avx512fvecmode>")
+ (const_string "XI"))
+ (and (match_test "<MODE_SIZE> == 16")
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "V4SF")
(match_test "TARGET_AVX")
@@ -3138,17 +3224,18 @@
"ix86_fixup_binary_operands_no_copy (<CODE>, TFmode, operands);")
(define_insn "*<code>tf3"
- [(set (match_operand:TF 0 "register_operand" "=x,x")
+ [(set (match_operand:TF 0 "register_operand" "=x,x,v,v")
(any_logic:TF
- (match_operand:TF 1 "vector_operand" "%0,x")
- (match_operand:TF 2 "vector_operand" "xBm,xm")))]
+ (match_operand:TF 1 "vector_operand" "%0,x,v,v")
+ (match_operand:TF 2 "vector_operand" "xBm,xm,vm,v")))]
"TARGET_SSE
&& ix86_binary_operator_ok (<CODE>, TFmode, operands)"
{
- static char buf[32];
+ static char buf[128];
const char *ops;
const char *tmp
- = (get_attr_mode (insn) == MODE_V4SF) ? "<logic>ps" : "p<logic>";
+ = (which_alternative >= 2 ? "p<logic>q"
+ : get_attr_mode (insn) == MODE_V4SF ? "<logic>ps" : "p<logic>");
switch (which_alternative)
{
@@ -3156,8 +3243,12 @@
ops = "%s\t{%%2, %%0|%%0, %%2}";
break;
case 1:
+ case 2:
ops = "v%s\t{%%2, %%1, %%0|%%0, %%1, %%2}";
break;
+ case 3:
+ ops = "v%s\t{%%g2, %%g1, %%g0|%%g0, %%g1, %%g2}";
+ break;
default:
gcc_unreachable ();
}
@@ -3165,7 +3256,7 @@
snprintf (buf, sizeof (buf), ops, tmp);
return buf;
}
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512vl,avx512f")
(set_attr "type" "sselog")
(set (attr "prefix_data16")
(if_then_else
@@ -3173,9 +3264,13 @@
(eq_attr "mode" "TI"))
(const_string "1")
(const_string "*")))
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,vex,evex,evex")
(set (attr "mode")
- (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
+ (cond [(eq_attr "alternative" "2")
+ (const_string "TI")
+ (eq_attr "alternative" "3")
+ (const_string "QI")
+ (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
(const_string "V4SF")
(match_test "TARGET_AVX")
(const_string "TI")
@@ -3327,10 +3422,10 @@
(set_attr "mode" "<MODE>")])
(define_insn "<avx512>_fmadd_<mode>_mask3<round_name>"
- [(set (match_operand:VF_AVX512VL 0 "register_operand" "=x")
+ [(set (match_operand:VF_AVX512VL 0 "register_operand" "=v")
(vec_merge:VF_AVX512VL
(fma:VF_AVX512VL
- (match_operand:VF_AVX512VL 1 "register_operand" "x")
+ (match_operand:VF_AVX512VL 1 "register_operand" "v")
(match_operand:VF_AVX512VL 2 "nonimmediate_operand" "<round_constraint>")
(match_operand:VF_AVX512VL 3 "register_operand" "0"))
(match_dup 3)
@@ -4187,7 +4282,7 @@
(parallel [(const_int 0) (const_int 1)]))]
UNSPEC_FIX_NOTRUNC))]
"TARGET_AVX512DQ && TARGET_AVX512VL"
- "vcvtps2qq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
+ "vcvtps2qq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %q1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "TI")])
@@ -4210,7 +4305,7 @@
(parallel [(const_int 0) (const_int 1)]))]
UNSPEC_UNSIGNED_FIX_NOTRUNC))]
"TARGET_AVX512DQ && TARGET_AVX512VL"
- "vcvtps2uqq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
+ "vcvtps2uqq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %q1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "TI")])
@@ -4735,9 +4830,9 @@
"operands[2] = CONST0_RTX (V4SImode);")
(define_insn "*avx_cvtpd2dq256_2"
- [(set (match_operand:V8SI 0 "register_operand" "=x")
+ [(set (match_operand:V8SI 0 "register_operand" "=v")
(vec_concat:V8SI
- (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "xm")]
+ (unspec:V4SI [(match_operand:V4DF 1 "nonimmediate_operand" "vm")]
UNSPEC_FIX_NOTRUNC)
(match_operand:V4SI 2 "const0_operand")))]
"TARGET_AVX"
@@ -4885,7 +4980,7 @@
(match_operand:V4SF 1 "nonimmediate_operand" "vm")
(parallel [(const_int 0) (const_int 1)]))))]
"TARGET_AVX512DQ && TARGET_AVX512VL"
- "vcvttps2<fixsuffix>qq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
+ "vcvttps2<fixsuffix>qq\t{%1, %0<mask_operand2>|%0<mask_operand2>, %q1}"
[(set_attr "type" "ssecvt")
(set_attr "prefix" "evex")
(set_attr "mode" "TI")])
@@ -4949,6 +5044,27 @@
(set_attr "prefix" "orig,orig,<round_prefix>")
(set_attr "mode" "SF")])
+(define_insn "*sse2_vd_cvtsd2ss"
+ [(set (match_operand:V4SF 0 "register_operand" "=x,x,v")
+ (vec_merge:V4SF
+ (vec_duplicate:V4SF
+ (float_truncate:SF (match_operand:DF 2 "nonimmediate_operand" "x,m,vm")))
+ (match_operand:V4SF 1 "register_operand" "0,0,v")
+ (const_int 1)))]
+ "TARGET_SSE2"
+ "@
+ cvtsd2ss\t{%2, %0|%0, %2}
+ cvtsd2ss\t{%2, %0|%0, %2}
+ vcvtsd2ss\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,noavx,avx")
+ (set_attr "type" "ssecvt")
+ (set_attr "athlon_decode" "vector,double,*")
+ (set_attr "amdfam10_decode" "vector,double,*")
+ (set_attr "bdver1_decode" "direct,direct,*")
+ (set_attr "btver2_decode" "double,double,double")
+ (set_attr "prefix" "orig,orig,vex")
+ (set_attr "mode" "SF")])
+
(define_insn "sse2_cvtss2sd<round_saeonly_name>"
[(set (match_operand:V2DF 0 "register_operand" "=x,x,v")
(vec_merge:V2DF
@@ -4972,6 +5088,27 @@
(set_attr "prefix" "orig,orig,<round_saeonly_prefix>")
(set_attr "mode" "DF")])
+(define_insn "*sse2_vd_cvtss2sd"
+ [(set (match_operand:V2DF 0 "register_operand" "=x,x,v")
+ (vec_merge:V2DF
+ (vec_duplicate:V2DF
+ (float_extend:DF (match_operand:SF 2 "nonimmediate_operand" "x,m,vm")))
+ (match_operand:V2DF 1 "register_operand" "0,0,v")
+ (const_int 1)))]
+ "TARGET_SSE2"
+ "@
+ cvtss2sd\t{%2, %0|%0, %2}
+ cvtss2sd\t{%2, %0|%0, %2}
+ vcvtss2sd\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "noavx,noavx,avx")
+ (set_attr "type" "ssecvt")
+ (set_attr "amdfam10_decode" "vector,double,*")
+ (set_attr "athlon_decode" "direct,direct,*")
+ (set_attr "bdver1_decode" "direct,direct,*")
+ (set_attr "btver2_decode" "double,double,double")
+ (set_attr "prefix" "orig,orig,vex")
+ (set_attr "mode" "DF")])
+
(define_insn "<mask_codefor>avx512f_cvtpd2ps512<mask_name><round_name>"
[(set (match_operand:V8SF 0 "register_operand" "=v")
(float_truncate:V8SF
@@ -5050,10 +5187,10 @@
(set_attr "mode" "<MODE>")])
(define_insn "*avx_cvtps2pd256_2"
- [(set (match_operand:V4DF 0 "register_operand" "=x")
+ [(set (match_operand:V4DF 0 "register_operand" "=v")
(float_extend:V4DF
(vec_select:V4SF
- (match_operand:V8SF 1 "nonimmediate_operand" "xm")
+ (match_operand:V8SF 1 "nonimmediate_operand" "vm")
(parallel [(const_int 0) (const_int 1)
(const_int 2) (const_int 3)]))))]
"TARGET_AVX"
@@ -5744,11 +5881,11 @@
})
(define_insn "sse_movhlps"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,x,x,m")
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,v,x,v,m")
(vec_select:V4SF
(vec_concat:V8SF
- (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
- (match_operand:V4SF 2 "nonimmediate_operand" " x,x,o,o,x"))
+ (match_operand:V4SF 1 "nonimmediate_operand" " 0,v,0,v,0")
+ (match_operand:V4SF 2 "nonimmediate_operand" " x,v,o,o,v"))
(parallel [(const_int 6)
(const_int 7)
(const_int 2)
@@ -5762,7 +5899,7 @@
%vmovhps\t{%2, %0|%q0, %2}"
[(set_attr "isa" "noavx,avx,noavx,avx,*")
(set_attr "type" "ssemov")
- (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
+ (set_attr "prefix" "orig,maybe_evex,orig,maybe_evex,maybe_vex")
(set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
(define_expand "sse_movlhps_exp"
@@ -5789,11 +5926,11 @@
})
(define_insn "sse_movlhps"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,x,x,o")
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,v,x,v,o")
(vec_select:V4SF
(vec_concat:V8SF
- (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
- (match_operand:V4SF 2 "nonimmediate_operand" " x,x,m,m,x"))
+ (match_operand:V4SF 1 "nonimmediate_operand" " 0,v,0,v,0")
+ (match_operand:V4SF 2 "nonimmediate_operand" " x,v,m,v,v"))
(parallel [(const_int 0)
(const_int 1)
(const_int 4)
@@ -5807,7 +5944,7 @@
%vmovlps\t{%2, %H0|%H0, %2}"
[(set_attr "isa" "noavx,avx,noavx,avx,*")
(set_attr "type" "ssemov")
- (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
+ (set_attr "prefix" "orig,maybe_evex,orig,maybe_evex,maybe_vex")
(set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
(define_insn "<mask_codefor>avx512f_unpckhps512<mask_name>"
@@ -5851,8 +5988,8 @@
[(set (match_dup 3)
(vec_select:V8SF
(vec_concat:V16SF
- (match_operand:V8SF 1 "register_operand" "x")
- (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
+ (match_operand:V8SF 1 "register_operand")
+ (match_operand:V8SF 2 "nonimmediate_operand"))
(parallel [(const_int 0) (const_int 8)
(const_int 1) (const_int 9)
(const_int 4) (const_int 12)
@@ -5956,8 +6093,8 @@
[(set (match_dup 3)
(vec_select:V8SF
(vec_concat:V16SF
- (match_operand:V8SF 1 "register_operand" "x")
- (match_operand:V8SF 2 "nonimmediate_operand" "xm"))
+ (match_operand:V8SF 1 "register_operand")
+ (match_operand:V8SF 2 "nonimmediate_operand"))
(parallel [(const_int 0) (const_int 8)
(const_int 1) (const_int 9)
(const_int 4) (const_int 12)
@@ -5987,11 +6124,11 @@
})
(define_insn "vec_interleave_lowv4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=x,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,v")
(vec_select:V4SF
(vec_concat:V8SF
- (match_operand:V4SF 1 "register_operand" "0,x")
- (match_operand:V4SF 2 "vector_operand" "xBm,xm"))
+ (match_operand:V4SF 1 "register_operand" "0,v")
+ (match_operand:V4SF 2 "vector_operand" "xBm,vm"))
(parallel [(const_int 0) (const_int 4)
(const_int 1) (const_int 5)])))]
"TARGET_SSE"
@@ -6000,7 +6137,7 @@
vunpcklps\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sselog")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,maybe_evex")
(set_attr "mode" "V4SF")])
;; These are modeled with the same vec_concat as the others so that we
@@ -6219,11 +6356,11 @@
(set_attr "mode" "V4SF")])
(define_insn "sse_shufps_<mode>"
- [(set (match_operand:VI4F_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VI4F_128 0 "register_operand" "=x,v")
(vec_select:VI4F_128
(vec_concat:<ssedoublevecmode>
- (match_operand:VI4F_128 1 "register_operand" "0,x")
- (match_operand:VI4F_128 2 "vector_operand" "xBm,xm"))
+ (match_operand:VI4F_128 1 "register_operand" "0,v")
+ (match_operand:VI4F_128 2 "vector_operand" "xBm,vm"))
(parallel [(match_operand 3 "const_0_to_3_operand")
(match_operand 4 "const_0_to_3_operand")
(match_operand 5 "const_4_to_7_operand")
@@ -6250,13 +6387,13 @@
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sseshuf")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,maybe_evex")
(set_attr "mode" "V4SF")])
(define_insn "sse_storehps"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
+ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,v,v")
(vec_select:V2SF
- (match_operand:V4SF 1 "nonimmediate_operand" "x,x,o")
+ (match_operand:V4SF 1 "nonimmediate_operand" "v,v,o")
(parallel [(const_int 2) (const_int 3)])))]
"TARGET_SSE"
"@
@@ -6288,12 +6425,12 @@
})
(define_insn "sse_loadhps"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,x,x,o")
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,v,x,v,o")
(vec_concat:V4SF
(vec_select:V2SF
- (match_operand:V4SF 1 "nonimmediate_operand" " 0,x,0,x,0")
+ (match_operand:V4SF 1 "nonimmediate_operand" " 0,v,0,v,0")
(parallel [(const_int 0) (const_int 1)]))
- (match_operand:V2SF 2 "nonimmediate_operand" " m,m,x,x,x")))]
+ (match_operand:V2SF 2 "nonimmediate_operand" " m,m,x,v,v")))]
"TARGET_SSE"
"@
movhps\t{%2, %0|%0, %q2}
@@ -6303,13 +6440,13 @@
%vmovlps\t{%2, %H0|%H0, %2}"
[(set_attr "isa" "noavx,avx,noavx,avx,*")
(set_attr "type" "ssemov")
- (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
+ (set_attr "prefix" "orig,maybe_evex,orig,maybe_evex,maybe_vex")
(set_attr "mode" "V2SF,V2SF,V4SF,V4SF,V2SF")])
(define_insn "sse_storelps"
- [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,x,x")
+ [(set (match_operand:V2SF 0 "nonimmediate_operand" "=m,v,v")
(vec_select:V2SF
- (match_operand:V4SF 1 "nonimmediate_operand" " x,x,m")
+ (match_operand:V4SF 1 "nonimmediate_operand" " v,v,m")
(parallel [(const_int 0) (const_int 1)])))]
"TARGET_SSE"
"@
@@ -6341,11 +6478,11 @@
})
(define_insn "sse_loadlps"
- [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,x,x,x,m")
+ [(set (match_operand:V4SF 0 "nonimmediate_operand" "=x,v,x,v,m")
(vec_concat:V4SF
- (match_operand:V2SF 2 "nonimmediate_operand" " 0,x,m,m,x")
+ (match_operand:V2SF 2 "nonimmediate_operand" " 0,v,m,m,v")
(vec_select:V2SF
- (match_operand:V4SF 1 "nonimmediate_operand" " x,x,0,x,0")
+ (match_operand:V4SF 1 "nonimmediate_operand" " x,v,0,v,0")
(parallel [(const_int 2) (const_int 3)]))))]
"TARGET_SSE"
"@
@@ -6357,14 +6494,14 @@
[(set_attr "isa" "noavx,avx,noavx,avx,*")
(set_attr "type" "sseshuf,sseshuf,ssemov,ssemov,ssemov")
(set_attr "length_immediate" "1,1,*,*,*")
- (set_attr "prefix" "orig,vex,orig,vex,maybe_vex")
+ (set_attr "prefix" "orig,maybe_evex,orig,maybe_evex,maybe_vex")
(set_attr "mode" "V4SF,V4SF,V2SF,V2SF,V2SF")])
(define_insn "sse_movss"
- [(set (match_operand:V4SF 0 "register_operand" "=x,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,v")
(vec_merge:V4SF
- (match_operand:V4SF 2 "register_operand" " x,x")
- (match_operand:V4SF 1 "register_operand" " 0,x")
+ (match_operand:V4SF 2 "register_operand" " x,v")
+ (match_operand:V4SF 1 "register_operand" " 0,v")
(const_int 1)))]
"TARGET_SSE"
"@
@@ -6372,31 +6509,31 @@
vmovss\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "isa" "noavx,avx")
(set_attr "type" "ssemov")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,maybe_evex")
(set_attr "mode" "SF")])
(define_insn "avx2_vec_dup<mode>"
- [(set (match_operand:VF1_128_256 0 "register_operand" "=x")
+ [(set (match_operand:VF1_128_256 0 "register_operand" "=v")
(vec_duplicate:VF1_128_256
(vec_select:SF
- (match_operand:V4SF 1 "register_operand" "x")
+ (match_operand:V4SF 1 "register_operand" "v")
(parallel [(const_int 0)]))))]
"TARGET_AVX2"
"vbroadcastss\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "maybe_evex")
(set_attr "mode" "<MODE>")])
(define_insn "avx2_vec_dupv8sf_1"
- [(set (match_operand:V8SF 0 "register_operand" "=x")
+ [(set (match_operand:V8SF 0 "register_operand" "=v")
(vec_duplicate:V8SF
(vec_select:SF
- (match_operand:V8SF 1 "register_operand" "x")
+ (match_operand:V8SF 1 "register_operand" "v")
(parallel [(const_int 0)]))))]
"TARGET_AVX2"
"vbroadcastss\t{%x1, %0|%0, %x1}"
[(set_attr "type" "sselog1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "maybe_evex")
(set_attr "mode" "V8SF")])
(define_insn "avx512f_vec_dup<mode>_1"
@@ -6415,12 +6552,12 @@
;; unpcklps with register source since it is shorter.
(define_insn "*vec_concatv2sf_sse4_1"
[(set (match_operand:V2SF 0 "register_operand"
- "=Yr,*x,x,Yr,*x,x,x,*y ,*y")
+ "=Yr,*x, v,Yr,*x,v,v,*y ,*y")
(vec_concat:V2SF
(match_operand:SF 1 "nonimmediate_operand"
- " 0, 0,x, 0,0, x,m, 0 , m")
+ " 0, 0,Yv, 0,0, v,m, 0 , m")
(match_operand:SF 2 "vector_move_operand"
- " Yr,*x,x, m,m, m,C,*ym, C")))]
+ " Yr,*x,Yv, m,m, m,C,*ym, C")))]
"TARGET_SSE4_1 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
"@
unpcklps\t{%2, %0|%0, %2}
@@ -6437,7 +6574,7 @@
(set_attr "prefix_data16" "*,*,*,1,1,*,*,*,*")
(set_attr "prefix_extra" "*,*,*,1,1,1,*,*,*")
(set_attr "length_immediate" "*,*,*,1,1,1,*,*,*")
- (set_attr "prefix" "orig,orig,vex,orig,orig,vex,maybe_vex,orig,orig")
+ (set_attr "prefix" "orig,orig,maybe_evex,orig,orig,maybe_evex,maybe_vex,orig,orig")
(set_attr "mode" "V4SF,V4SF,V4SF,V4SF,V4SF,V4SF,SF,DI,DI")])
;; ??? In theory we can match memory for the MMX alternative, but allowing
@@ -6458,10 +6595,10 @@
(set_attr "mode" "V4SF,SF,DI,DI")])
(define_insn "*vec_concatv4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=x,x,x,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,v,x,v")
(vec_concat:V4SF
- (match_operand:V2SF 1 "register_operand" " 0,x,0,x")
- (match_operand:V2SF 2 "nonimmediate_operand" " x,x,m,m")))]
+ (match_operand:V2SF 1 "register_operand" " 0,v,0,v")
+ (match_operand:V2SF 2 "nonimmediate_operand" " x,v,m,m")))]
"TARGET_SSE"
"@
movlhps\t{%2, %0|%0, %2}
@@ -6470,7 +6607,7 @@
vmovhps\t{%2, %1, %0|%0, %1, %q2}"
[(set_attr "isa" "noavx,avx,noavx,avx")
(set_attr "type" "ssemov")
- (set_attr "prefix" "orig,vex,orig,vex")
+ (set_attr "prefix" "orig,maybe_evex,orig,maybe_evex")
(set_attr "mode" "V4SF,V4SF,V2SF,V2SF")])
(define_expand "vec_init<mode>"
@@ -6526,11 +6663,11 @@
;; A subset is vec_setv4sf.
(define_insn "*vec_setv4sf_sse4_1"
- [(set (match_operand:V4SF 0 "register_operand" "=Yr,*x,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=Yr,*x,v")
(vec_merge:V4SF
(vec_duplicate:V4SF
- (match_operand:SF 2 "nonimmediate_operand" "Yrm,*xm,xm"))
- (match_operand:V4SF 1 "register_operand" "0,0,x")
+ (match_operand:SF 2 "nonimmediate_operand" "Yrm,*xm,vm"))
+ (match_operand:V4SF 1 "register_operand" "0,0,v")
(match_operand:SI 3 "const_int_operand")))]
"TARGET_SSE4_1
&& ((unsigned) exact_log2 (INTVAL (operands[3]))
@@ -6553,13 +6690,13 @@
(set_attr "prefix_data16" "1,1,*")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "orig,orig,vex")
+ (set_attr "prefix" "orig,orig,maybe_evex")
(set_attr "mode" "V4SF")])
(define_insn "sse4_1_insertps"
- [(set (match_operand:V4SF 0 "register_operand" "=Yr,*x,x")
- (unspec:V4SF [(match_operand:V4SF 2 "nonimmediate_operand" "Yrm,*xm,xm")
- (match_operand:V4SF 1 "register_operand" "0,0,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=Yr,*x,v")
+ (unspec:V4SF [(match_operand:V4SF 2 "nonimmediate_operand" "Yrm,*xm,vm")
+ (match_operand:V4SF 1 "register_operand" "0,0,v")
(match_operand:SI 3 "const_0_to_255_operand" "n,n,n")]
UNSPEC_INSERTPS))]
"TARGET_SSE4_1"
@@ -6587,7 +6724,7 @@
(set_attr "prefix_data16" "1,1,*")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "orig,orig,vex")
+ (set_attr "prefix" "orig,orig,maybe_evex")
(set_attr "mode" "V4SF")])
(define_split
@@ -6613,9 +6750,9 @@
})
(define_insn_and_split "*vec_extractv4sf_0"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=x,m,f,r")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=v,m,f,r")
(vec_select:SF
- (match_operand:V4SF 1 "nonimmediate_operand" "xm,x,m,m")
+ (match_operand:V4SF 1 "nonimmediate_operand" "vm,v,m,m")
(parallel [(const_int 0)])))]
"TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"#"
@@ -6624,9 +6761,9 @@
"operands[1] = gen_lowpart (SFmode, operands[1]);")
(define_insn_and_split "*sse4_1_extractps"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,rm,x,x")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=rm,rm,v,v")
(vec_select:SF
- (match_operand:V4SF 1 "register_operand" "Yr,*x,0,x")
+ (match_operand:V4SF 1 "register_operand" "Yr,*v,0,v")
(parallel [(match_operand:SI 2 "const_0_to_3_operand" "n,n,n,n")])))]
"TARGET_SSE4_1"
"@
@@ -6665,7 +6802,7 @@
(set_attr "mode" "V4SF,V4SF,*,*")])
(define_insn_and_split "*vec_extractv4sf_mem"
- [(set (match_operand:SF 0 "register_operand" "=x,*r,f")
+ [(set (match_operand:SF 0 "register_operand" "=v,*r,f")
(vec_select:SF
(match_operand:V4SF 1 "memory_operand" "o,o,o")
(parallel [(match_operand 2 "const_0_to_3_operand" "n,n,n")])))]
@@ -7239,9 +7376,9 @@
(set_attr "mode" "XI")])
(define_insn_and_split "vec_extract_lo_v16hi"
- [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
+ [(set (match_operand:V8HI 0 "nonimmediate_operand" "=v,m")
(vec_select:V8HI
- (match_operand:V16HI 1 "nonimmediate_operand" "xm,x")
+ (match_operand:V16HI 1 "nonimmediate_operand" "vm,v")
(parallel [(const_int 0) (const_int 1)
(const_int 2) (const_int 3)
(const_int 4) (const_int 5)
@@ -7253,20 +7390,27 @@
"operands[1] = gen_lowpart (V8HImode, operands[1]);")
(define_insn "vec_extract_hi_v16hi"
- [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m")
+ [(set (match_operand:V8HI 0 "nonimmediate_operand" "=x,m,v,m,v,m")
(vec_select:V8HI
- (match_operand:V16HI 1 "register_operand" "x,x")
+ (match_operand:V16HI 1 "register_operand" "x,x,v,v,v,v")
(parallel [(const_int 8) (const_int 9)
(const_int 10) (const_int 11)
(const_int 12) (const_int 13)
(const_int 14) (const_int 15)])))]
"TARGET_AVX"
- "vextract%~128\t{$0x1, %1, %0|%0, %1, 0x1}"
+ "@
+ vextract%~128\t{$0x1, %1, %0|%0, %1, 0x1}
+ vextract%~128\t{$0x1, %1, %0|%0, %1, 0x1}
+ vextracti32x4\t{$0x1, %1, %0|%0, %1, 0x1}
+ vextracti32x4\t{$0x1, %1, %0|%0, %1, 0x1}
+ vextracti32x4\t{$0x1, %g1, %0|%0, %g1, 0x1}
+ vextracti32x4\t{$0x1, %g1, %0|%0, %g1, 0x1}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "memory" "none,store")
- (set_attr "prefix" "vex")
+ (set_attr "isa" "*,*,avx512dq,avx512dq,avx512f,avx512f")
+ (set_attr "memory" "none,store,none,store,none,store")
+ (set_attr "prefix" "vex,vex,evex,evex,evex,evex")
(set_attr "mode" "OI")])
(define_insn_and_split "vec_extract_lo_v64qi"
@@ -7325,9 +7469,9 @@
(set_attr "mode" "XI")])
(define_insn_and_split "vec_extract_lo_v32qi"
- [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
+ [(set (match_operand:V16QI 0 "nonimmediate_operand" "=v,m")
(vec_select:V16QI
- (match_operand:V32QI 1 "nonimmediate_operand" "xm,x")
+ (match_operand:V32QI 1 "nonimmediate_operand" "vm,v")
(parallel [(const_int 0) (const_int 1)
(const_int 2) (const_int 3)
(const_int 4) (const_int 5)
@@ -7343,9 +7487,9 @@
"operands[1] = gen_lowpart (V16QImode, operands[1]);")
(define_insn "vec_extract_hi_v32qi"
- [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m")
+ [(set (match_operand:V16QI 0 "nonimmediate_operand" "=x,m,v,m,v,m")
(vec_select:V16QI
- (match_operand:V32QI 1 "register_operand" "x,x")
+ (match_operand:V32QI 1 "register_operand" "x,x,v,v,v,v")
(parallel [(const_int 16) (const_int 17)
(const_int 18) (const_int 19)
(const_int 20) (const_int 21)
@@ -7355,12 +7499,19 @@
(const_int 28) (const_int 29)
(const_int 30) (const_int 31)])))]
"TARGET_AVX"
- "vextract%~128\t{$0x1, %1, %0|%0, %1, 0x1}"
+ "@
+ vextract%~128\t{$0x1, %1, %0|%0, %1, 0x1}
+ vextract%~128\t{$0x1, %1, %0|%0, %1, 0x1}
+ vextracti32x4\t{$0x1, %1, %0|%0, %1, 0x1}
+ vextracti32x4\t{$0x1, %1, %0|%0, %1, 0x1}
+ vextracti32x4\t{$0x1, %g1, %0|%0, %g1, 0x1}
+ vextracti32x4\t{$0x1, %g1, %0|%0, %g1, 0x1}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "memory" "none,store")
- (set_attr "prefix" "vex")
+ (set_attr "isa" "*,*,avx512dq,avx512dq,avx512f,avx512f")
+ (set_attr "memory" "none,store,none,store,none,store")
+ (set_attr "prefix" "vex,vex,evex,evex,evex,evex")
(set_attr "mode" "OI")])
;; Modes handled by vec_extract patterns.
@@ -7424,8 +7575,8 @@
[(set (match_dup 3)
(vec_select:V4DF
(vec_concat:V8DF
- (match_operand:V4DF 1 "register_operand" "x")
- (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
+ (match_operand:V4DF 1 "register_operand")
+ (match_operand:V4DF 2 "nonimmediate_operand"))
(parallel [(const_int 0) (const_int 4)
(const_int 2) (const_int 6)])))
(set (match_dup 4)
@@ -7480,11 +7631,11 @@
})
(define_insn "*vec_interleave_highv2df"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,x,m")
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,v,v,x,v,m")
(vec_select:V2DF
(vec_concat:V4DF
- (match_operand:V2DF 1 "nonimmediate_operand" " 0,x,o,o,o,x")
- (match_operand:V2DF 2 "nonimmediate_operand" " x,x,1,0,x,0"))
+ (match_operand:V2DF 1 "nonimmediate_operand" " 0,v,o,o,o,v")
+ (match_operand:V2DF 2 "nonimmediate_operand" " x,v,1,0,v,0"))
(parallel [(const_int 1)
(const_int 3)])))]
"TARGET_SSE2 && ix86_vec_interleave_v2df_operator_ok (operands, 1)"
@@ -7498,7 +7649,7 @@
[(set_attr "isa" "noavx,avx,sse3,noavx,avx,*")
(set_attr "type" "sselog,sselog,sselog,ssemov,ssemov,ssemov")
(set_attr "prefix_data16" "*,*,*,1,*,1")
- (set_attr "prefix" "orig,vex,maybe_vex,orig,vex,maybe_vex")
+ (set_attr "prefix" "orig,maybe_evex,maybe_vex,orig,maybe_evex,maybe_vex")
(set_attr "mode" "V2DF,V2DF,DF,V1DF,V1DF,V1DF")])
(define_expand "avx512f_movddup512<mask_name>"
@@ -7584,8 +7735,8 @@
[(set (match_dup 3)
(vec_select:V4DF
(vec_concat:V8DF
- (match_operand:V4DF 1 "register_operand" "x")
- (match_operand:V4DF 2 "nonimmediate_operand" "xm"))
+ (match_operand:V4DF 1 "register_operand")
+ (match_operand:V4DF 2 "nonimmediate_operand"))
(parallel [(const_int 0) (const_int 4)
(const_int 2) (const_int 6)])))
(set (match_dup 4)
@@ -7639,11 +7790,11 @@
})
(define_insn "*vec_interleave_lowv2df"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,x,o")
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,v,v,x,v,o")
(vec_select:V2DF
(vec_concat:V4DF
- (match_operand:V2DF 1 "nonimmediate_operand" " 0,x,m,0,x,0")
- (match_operand:V2DF 2 "nonimmediate_operand" " x,x,1,m,m,x"))
+ (match_operand:V2DF 1 "nonimmediate_operand" " 0,v,m,0,v,0")
+ (match_operand:V2DF 2 "nonimmediate_operand" " x,v,1,m,m,v"))
(parallel [(const_int 0)
(const_int 2)])))]
"TARGET_SSE2 && ix86_vec_interleave_v2df_operator_ok (operands, 0)"
@@ -7657,7 +7808,7 @@
[(set_attr "isa" "noavx,avx,sse3,noavx,avx,*")
(set_attr "type" "sselog,sselog,sselog,ssemov,ssemov,ssemov")
(set_attr "prefix_data16" "*,*,*,1,*,1")
- (set_attr "prefix" "orig,vex,maybe_vex,orig,vex,maybe_vex")
+ (set_attr "prefix" "orig,maybe_evex,maybe_vex,orig,maybe_evex,maybe_vex")
(set_attr "mode" "V2DF,V2DF,DF,V1DF,V1DF,V1DF")])
(define_split
@@ -8248,11 +8399,11 @@
(set_attr "mode" "TI")])
(define_insn "sse2_shufpd_<mode>"
- [(set (match_operand:VI8F_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VI8F_128 0 "register_operand" "=x,v")
(vec_select:VI8F_128
(vec_concat:<ssedoublevecmode>
- (match_operand:VI8F_128 1 "register_operand" "0,x")
- (match_operand:VI8F_128 2 "vector_operand" "xBm,xm"))
+ (match_operand:VI8F_128 1 "register_operand" "0,v")
+ (match_operand:VI8F_128 2 "vector_operand" "xBm,vm"))
(parallel [(match_operand 3 "const_0_to_1_operand")
(match_operand 4 "const_2_to_3_operand")])))]
"TARGET_SSE2"
@@ -8275,15 +8426,15 @@
[(set_attr "isa" "noavx,avx")
(set_attr "type" "sseshuf")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,maybe_evex")
(set_attr "mode" "V2DF")])
;; Avoid combining registers from different units in a single alternative,
;; see comment above inline_secondary_memory_needed function in i386.c
(define_insn "sse2_storehpd"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x,x,*f,r")
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,Yv,x,*f,r")
(vec_select:DF
- (match_operand:V2DF 1 "nonimmediate_operand" " x,0,x,o,o,o")
+ (match_operand:V2DF 1 "nonimmediate_operand" " v,0, v,o,o,o")
(parallel [(const_int 1)])))]
"TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"@
@@ -8301,7 +8452,7 @@
(not (match_test "TARGET_AVX")))
(const_string "1")
(const_string "*")))
- (set_attr "prefix" "maybe_vex,orig,vex,*,*,*")
+ (set_attr "prefix" "maybe_vex,orig,maybe_evex,*,*,*")
(set_attr "mode" "V1DF,V1DF,V2DF,DF,DF,DF")])
(define_split
@@ -8332,7 +8483,7 @@
(define_insn "sse2_storelpd"
[(set (match_operand:DF 0 "nonimmediate_operand" "=m,x,x,*f,r")
(vec_select:DF
- (match_operand:V2DF 1 "nonimmediate_operand" " x,x,m,m,m")
+ (match_operand:V2DF 1 "nonimmediate_operand" " v,x,m,m,m")
(parallel [(const_int 0)])))]
"TARGET_SSE2 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"@
@@ -8393,14 +8544,14 @@
;; see comment above inline_secondary_memory_needed function in i386.c
(define_insn "sse2_loadhpd"
[(set (match_operand:V2DF 0 "nonimmediate_operand"
- "=x,x,x,x,o,o ,o")
+ "=x,v,x,v,o,o ,o")
(vec_concat:V2DF
(vec_select:DF
(match_operand:V2DF 1 "nonimmediate_operand"
- " 0,x,0,x,0,0 ,0")
+ " 0,v,0,v,0,0 ,0")
(parallel [(const_int 0)]))
(match_operand:DF 2 "nonimmediate_operand"
- " m,m,x,x,x,*f,r")))]
+ " m,m,x,v,x,*f,r")))]
"TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
"@
movhpd\t{%2, %0|%0, %2}
@@ -8413,7 +8564,7 @@
[(set_attr "isa" "noavx,avx,noavx,avx,*,*,*")
(set_attr "type" "ssemov,ssemov,sselog,sselog,ssemov,fmov,imov")
(set_attr "prefix_data16" "1,*,*,*,*,*,*")
- (set_attr "prefix" "orig,vex,orig,vex,*,*,*")
+ (set_attr "prefix" "orig,maybe_evex,orig,maybe_evex,*,*,*")
(set_attr "mode" "V1DF,V1DF,V2DF,V2DF,DF,DF,DF")])
(define_split
@@ -8449,13 +8600,13 @@
;; see comment above inline_secondary_memory_needed function in i386.c
(define_insn "sse2_loadlpd"
[(set (match_operand:V2DF 0 "nonimmediate_operand"
- "=x,x,x,x,x,x,x,x,m,m ,m")
+ "=v,x,v,x,v,x,x,v,m,m ,m")
(vec_concat:V2DF
(match_operand:DF 2 "nonimmediate_operand"
- "xm,m,m,x,x,0,0,x,x,*f,r")
+ "vm,m,m,x,v,0,0,v,x,*f,r")
(vec_select:DF
(match_operand:V2DF 1 "vector_move_operand"
- " C,0,x,0,x,x,o,o,0,0 ,0")
+ " C,0,v,0,v,x,o,o,0,0 ,0")
(parallel [(const_int 1)]))))]
"TARGET_SSE2 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
"@
@@ -8482,7 +8633,7 @@
(const_string "ssemov")))
(set_attr "prefix_data16" "*,1,*,*,*,*,1,*,*,*,*")
(set_attr "length_immediate" "*,*,*,*,*,1,*,*,*,*,*")
- (set_attr "prefix" "maybe_vex,orig,vex,orig,vex,orig,orig,vex,*,*,*")
+ (set_attr "prefix" "maybe_vex,orig,maybe_evex,orig,maybe_evex,orig,orig,maybe_evex,*,*,*")
(set_attr "mode" "DF,V1DF,V1DF,V1DF,V1DF,V2DF,V1DF,V1DF,DF,DF,DF")])
(define_split
@@ -8495,10 +8646,10 @@
"operands[0] = adjust_address (operands[0], DFmode, 0);")
(define_insn "sse2_movsd"
- [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,x,x,x,m,x,x,x,o")
+ [(set (match_operand:V2DF 0 "nonimmediate_operand" "=x,v,x,v,m,x,x,v,o")
(vec_merge:V2DF
- (match_operand:V2DF 2 "nonimmediate_operand" " x,x,m,m,x,0,0,x,0")
- (match_operand:V2DF 1 "nonimmediate_operand" " 0,x,0,x,0,x,o,o,x")
+ (match_operand:V2DF 2 "nonimmediate_operand" " x,v,m,m,v,0,0,v,0")
+ (match_operand:V2DF 1 "nonimmediate_operand" " 0,v,0,v,0,x,o,o,v")
(const_int 1)))]
"TARGET_SSE2"
"@
@@ -8524,7 +8675,7 @@
(const_string "1")
(const_string "*")))
(set_attr "length_immediate" "*,*,*,*,*,1,*,*,*")
- (set_attr "prefix" "orig,vex,orig,vex,maybe_vex,orig,orig,vex,maybe_vex")
+ (set_attr "prefix" "orig,maybe_evex,orig,maybe_evex,maybe_vex,orig,orig,maybe_evex,maybe_vex")
(set_attr "mode" "DF,DF,V1DF,V1DF,V1DF,V2DF,V1DF,V1DF,V1DF")])
(define_insn "vec_dupv2df<mask_name>"
@@ -8799,7 +8950,7 @@
(const_int 12) (const_int 13)
(const_int 14) (const_int 15)]))))]
"TARGET_AVX512VL"
- "vpmov<trunsuffix>qb\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+ "vpmov<trunsuffix>qb\t{%1, %0%{%2%}|%w0%{%2%}, %1}"
[(set_attr "type" "ssemov")
(set_attr "memory" "store")
(set_attr "prefix" "evex")
@@ -8889,7 +9040,11 @@
(const_int 12) (const_int 13)
(const_int 14) (const_int 15)]))))]
"TARGET_AVX512VL"
- "vpmov<trunsuffix><pmov_suff_3>\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+{
+ if (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) == 8)
+ return "vpmov<trunsuffix><pmov_suff_3>\t{%1, %0%{%2%}|%k0%{%2%}, %1}";
+ return "vpmov<trunsuffix><pmov_suff_3>\t{%1, %0%{%2%}|%0%{%2%}, %g1}";
+}
[(set_attr "type" "ssemov")
(set_attr "memory" "store")
(set_attr "prefix" "evex")
@@ -8980,7 +9135,11 @@
(const_int 12) (const_int 13)
(const_int 14) (const_int 15)]))))]
"TARGET_AVX512VL"
- "vpmov<trunsuffix><pmov_suff_3>\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+{
+ if (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) == 4)
+ return "vpmov<trunsuffix><pmov_suff_3>\t{%1, %0%{%2%}|%0%{%2%}, %g1}";
+ return "vpmov<trunsuffix><pmov_suff_3>\t{%1, %0%{%2%}|%0%{%2%}, %1}";
+}
[(set_attr "type" "ssemov")
(set_attr "memory" "store")
(set_attr "prefix" "evex")
@@ -9074,7 +9233,11 @@
(parallel [(const_int 4) (const_int 5)
(const_int 6) (const_int 7)]))))]
"TARGET_AVX512VL"
- "vpmov<trunsuffix><pmov_suff_4>\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+{
+ if (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) == 4)
+ return "vpmov<trunsuffix><pmov_suff_4>\t{%1, %0%{%2%}|%0%{%2%}, %t1}";
+ return "vpmov<trunsuffix><pmov_suff_4>\t{%1, %0%{%2%}|%0%{%2%}, %g1}";
+}
[(set_attr "type" "ssemov")
(set_attr "memory" "store")
(set_attr "prefix" "evex")
@@ -9149,7 +9312,7 @@
(const_int 4) (const_int 5)
(const_int 6) (const_int 7)]))))]
"TARGET_AVX512VL"
- "vpmov<trunsuffix>qw\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+ "vpmov<trunsuffix>qw\t{%1, %0%{%2%}|%0%{%2%}, %g1}"
[(set_attr "type" "ssemov")
(set_attr "memory" "store")
(set_attr "prefix" "evex")
@@ -9228,7 +9391,7 @@
(match_dup 0)
(parallel [(const_int 2) (const_int 3)]))))]
"TARGET_AVX512VL"
- "vpmov<trunsuffix>qd\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+ "vpmov<trunsuffix>qd\t{%1, %0%{%2%}|%0%{%2%}, %t1}"
[(set_attr "type" "ssemov")
(set_attr "memory" "store")
(set_attr "prefix" "evex")
@@ -9331,7 +9494,7 @@
(const_int 12) (const_int 13)
(const_int 14) (const_int 15)]))))]
"TARGET_AVX512F"
- "vpmov<trunsuffix>qb\t{%1, %0%{%2%}|%0%{%2%}, %1}"
+ "vpmov<trunsuffix>qb\t{%1, %0%{%2%}|%q0%{%2%}, %1}"
[(set_attr "type" "ssemov")
(set_attr "memory" "store")
(set_attr "prefix" "evex")
@@ -9803,19 +9966,19 @@
"ix86_fixup_binary_operands_no_copy (MULT, V16HImode, operands);")
(define_insn "*avx2_pmaddwd"
- [(set (match_operand:V8SI 0 "register_operand" "=x")
+ [(set (match_operand:V8SI 0 "register_operand" "=x,v")
(plus:V8SI
(mult:V8SI
(sign_extend:V8SI
(vec_select:V8HI
- (match_operand:V16HI 1 "nonimmediate_operand" "%x")
+ (match_operand:V16HI 1 "nonimmediate_operand" "%x,v")
(parallel [(const_int 0) (const_int 2)
(const_int 4) (const_int 6)
(const_int 8) (const_int 10)
(const_int 12) (const_int 14)])))
(sign_extend:V8SI
(vec_select:V8HI
- (match_operand:V16HI 2 "nonimmediate_operand" "xm")
+ (match_operand:V16HI 2 "nonimmediate_operand" "xm,vm")
(parallel [(const_int 0) (const_int 2)
(const_int 4) (const_int 6)
(const_int 8) (const_int 10)
@@ -9836,7 +9999,8 @@
"TARGET_AVX2 && ix86_binary_operator_ok (MULT, V16HImode, operands)"
"vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
- (set_attr "prefix" "vex")
+ (set_attr "isa" "*,avx512bw")
+ (set_attr "prefix" "vex,evex")
(set_attr "mode" "OI")])
(define_expand "sse2_pmaddwd"
@@ -9866,17 +10030,17 @@
"ix86_fixup_binary_operands_no_copy (MULT, V8HImode, operands);")
(define_insn "*sse2_pmaddwd"
- [(set (match_operand:V4SI 0 "register_operand" "=x,x")
+ [(set (match_operand:V4SI 0 "register_operand" "=x,x,v")
(plus:V4SI
(mult:V4SI
(sign_extend:V4SI
(vec_select:V4HI
- (match_operand:V8HI 1 "vector_operand" "%0,x")
+ (match_operand:V8HI 1 "vector_operand" "%0,x,v")
(parallel [(const_int 0) (const_int 2)
(const_int 4) (const_int 6)])))
(sign_extend:V4SI
(vec_select:V4HI
- (match_operand:V8HI 2 "vector_operand" "xBm,xm")
+ (match_operand:V8HI 2 "vector_operand" "xBm,xm,vm")
(parallel [(const_int 0) (const_int 2)
(const_int 4) (const_int 6)]))))
(mult:V4SI
@@ -9891,12 +10055,13 @@
"TARGET_SSE2 && ix86_binary_operator_ok (MULT, V8HImode, operands)"
"@
pmaddwd\t{%2, %0|%0, %2}
+ vpmaddwd\t{%2, %1, %0|%0, %1, %2}
vpmaddwd\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sseiadd")
(set_attr "atom_unit" "simul")
- (set_attr "prefix_data16" "1,*")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix_data16" "1,*,*")
+ (set_attr "prefix" "orig,vex,evex")
(set_attr "mode" "TI")])
(define_insn "avx512dq_mul<mode>3<mask_name>"
@@ -10072,6 +10237,20 @@
DONE;
})
+(define_insn "<mask_codefor>ashr<mode>3<mask_name>"
+ [(set (match_operand:VI24_AVX512BW_1 0 "register_operand" "=v,v")
+ (ashiftrt:VI24_AVX512BW_1
+ (match_operand:VI24_AVX512BW_1 1 "nonimmediate_operand" "v,vm")
+ (match_operand:SI 2 "nonmemory_operand" "v,N")))]
+ "TARGET_AVX512VL"
+ "vpsra<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
+ [(set_attr "type" "sseishft")
+ (set (attr "length_immediate")
+ (if_then_else (match_operand 2 "const_int_operand")
+ (const_string "1")
+ (const_string "0")))
+ (set_attr "mode" "<sseinsnmode>")])
+
(define_insn "ashr<mode>3"
[(set (match_operand:VI24_AVX2 0 "register_operand" "=x,x")
(ashiftrt:VI24_AVX2
@@ -10091,20 +10270,6 @@
(set_attr "prefix" "orig,vex")
(set_attr "mode" "<sseinsnmode>")])
-(define_insn "<mask_codefor>ashr<mode>3<mask_name>"
- [(set (match_operand:VI24_AVX512BW_1 0 "register_operand" "=v,v")
- (ashiftrt:VI24_AVX512BW_1
- (match_operand:VI24_AVX512BW_1 1 "nonimmediate_operand" "v,vm")
- (match_operand:SI 2 "nonmemory_operand" "v,N")))]
- "TARGET_AVX512VL"
- "vpsra<ssemodesuffix>\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
- [(set_attr "type" "sseishft")
- (set (attr "length_immediate")
- (if_then_else (match_operand 2 "const_int_operand")
- (const_string "1")
- (const_string "0")))
- (set_attr "mode" "<sseinsnmode>")])
-
(define_insn "<mask_codefor>ashrv2di3<mask_name>"
[(set (match_operand:V2DI 0 "register_operand" "=v,v")
(ashiftrt:V2DI
@@ -10442,19 +10607,20 @@
(set_attr "mode" "TI")])
(define_insn "*<code>v8hi3"
- [(set (match_operand:V8HI 0 "register_operand" "=x,x")
+ [(set (match_operand:V8HI 0 "register_operand" "=x,x,v")
(smaxmin:V8HI
- (match_operand:V8HI 1 "vector_operand" "%0,x")
- (match_operand:V8HI 2 "vector_operand" "xBm,xm")))]
+ (match_operand:V8HI 1 "vector_operand" "%0,x,v")
+ (match_operand:V8HI 2 "vector_operand" "xBm,xm,vm")))]
"TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V8HImode, operands)"
"@
p<maxmin_int>w\t{%2, %0|%0, %2}
+ vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}
vp<maxmin_int>w\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sseiadd")
- (set_attr "prefix_data16" "1,*")
- (set_attr "prefix_extra" "*,1")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix_data16" "1,*,*")
+ (set_attr "prefix_extra" "*,1,1")
+ (set_attr "prefix" "orig,vex,evex")
(set_attr "mode" "TI")])
(define_expand "<code><mode>3"
@@ -10526,19 +10692,20 @@
(set_attr "mode" "TI")])
(define_insn "*<code>v16qi3"
- [(set (match_operand:V16QI 0 "register_operand" "=x,x")
+ [(set (match_operand:V16QI 0 "register_operand" "=x,x,v")
(umaxmin:V16QI
- (match_operand:V16QI 1 "vector_operand" "%0,x")
- (match_operand:V16QI 2 "vector_operand" "xBm,xm")))]
+ (match_operand:V16QI 1 "vector_operand" "%0,x,v")
+ (match_operand:V16QI 2 "vector_operand" "xBm,xm,vm")))]
"TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, V16QImode, operands)"
"@
p<maxmin_int>b\t{%2, %0|%0, %2}
+ vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}
vp<maxmin_int>b\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sseiadd")
- (set_attr "prefix_data16" "1,*")
- (set_attr "prefix_extra" "*,1")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix_data16" "1,*,*")
+ (set_attr "prefix_extra" "*,1,1")
+ (set_attr "prefix" "orig,vex,evex")
(set_attr "mode" "TI")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -11351,54 +11518,57 @@
})
(define_insn "<sse2_avx2>_packsswb<mask_name>"
- [(set (match_operand:VI1_AVX512 0 "register_operand" "=x,x")
+ [(set (match_operand:VI1_AVX512 0 "register_operand" "=x,x,v")
(vec_concat:VI1_AVX512
(ss_truncate:<ssehalfvecmode>
- (match_operand:<sseunpackmode> 1 "register_operand" "0,v"))
+ (match_operand:<sseunpackmode> 1 "register_operand" "0,x,v"))
(ss_truncate:<ssehalfvecmode>
- (match_operand:<sseunpackmode> 2 "vector_operand" "xBm,vm"))))]
+ (match_operand:<sseunpackmode> 2 "vector_operand" "xBm,xm,vm"))))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
"@
packsswb\t{%2, %0|%0, %2}
+ vpacksswb\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}
vpacksswb\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sselog")
- (set_attr "prefix_data16" "1,*")
- (set_attr "prefix" "orig,maybe_evex")
+ (set_attr "prefix_data16" "1,*,*")
+ (set_attr "prefix" "orig,<mask_prefix>,evex")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "<sse2_avx2>_packssdw<mask_name>"
- [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,v")
+ [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,x,v")
(vec_concat:VI2_AVX2
(ss_truncate:<ssehalfvecmode>
- (match_operand:<sseunpackmode> 1 "register_operand" "0,v"))
+ (match_operand:<sseunpackmode> 1 "register_operand" "0,x,v"))
(ss_truncate:<ssehalfvecmode>
- (match_operand:<sseunpackmode> 2 "vector_operand" "xBm,vm"))))]
+ (match_operand:<sseunpackmode> 2 "vector_operand" "xBm,xm,vm"))))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
"@
packssdw\t{%2, %0|%0, %2}
+ vpackssdw\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}
vpackssdw\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sselog")
- (set_attr "prefix_data16" "1,*")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix_data16" "1,*,*")
+ (set_attr "prefix" "orig,<mask_prefix>,evex")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "<sse2_avx2>_packuswb<mask_name>"
- [(set (match_operand:VI1_AVX512 0 "register_operand" "=x,x")
+ [(set (match_operand:VI1_AVX512 0 "register_operand" "=x,x,v")
(vec_concat:VI1_AVX512
(us_truncate:<ssehalfvecmode>
- (match_operand:<sseunpackmode> 1 "register_operand" "0,v"))
+ (match_operand:<sseunpackmode> 1 "register_operand" "0,x,v"))
(us_truncate:<ssehalfvecmode>
- (match_operand:<sseunpackmode> 2 "vector_operand" "xBm,vm"))))]
+ (match_operand:<sseunpackmode> 2 "vector_operand" "xBm,xm,vm"))))]
"TARGET_SSE2 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
"@
packuswb\t{%2, %0|%0, %2}
+ vpackuswb\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}
vpackuswb\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sselog")
- (set_attr "prefix_data16" "1,*")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix_data16" "1,*,*")
+ (set_attr "prefix" "orig,<mask_prefix>,evex")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "avx512bw_interleave_highv64qi<mask_name>"
@@ -11839,9 +12009,9 @@
(set_attr "mode" "TI")])
(define_expand "vec_interleave_high<mode>"
- [(match_operand:VI_256 0 "register_operand" "=x")
- (match_operand:VI_256 1 "register_operand" "x")
- (match_operand:VI_256 2 "nonimmediate_operand" "xm")]
+ [(match_operand:VI_256 0 "register_operand")
+ (match_operand:VI_256 1 "register_operand")
+ (match_operand:VI_256 2 "nonimmediate_operand")]
"TARGET_AVX2"
{
rtx t1 = gen_reg_rtx (<MODE>mode);
@@ -11857,9 +12027,9 @@
})
(define_expand "vec_interleave_low<mode>"
- [(match_operand:VI_256 0 "register_operand" "=x")
- (match_operand:VI_256 1 "register_operand" "x")
- (match_operand:VI_256 2 "nonimmediate_operand" "xm")]
+ [(match_operand:VI_256 0 "register_operand")
+ (match_operand:VI_256 1 "register_operand")
+ (match_operand:VI_256 2 "nonimmediate_operand")]
"TARGET_AVX2"
{
rtx t1 = gen_reg_rtx (<MODE>mode);
@@ -11884,13 +12054,17 @@
[(V16QI "sse4_1") (V8HI "sse2")
(V4SI "sse4_1") (V2DI "sse4_1")])
+(define_mode_attr pinsr_evex_isa
+ [(V16QI "avx512bw") (V8HI "avx512bw")
+ (V4SI "avx512dq") (V2DI "avx512dq")])
+
;; sse4_1_pinsrd must come before sse2_loadld since it is preferred.
(define_insn "<sse2p4_1>_pinsr<ssemodesuffix>"
- [(set (match_operand:PINSR_MODE 0 "register_operand" "=x,x,x,x")
+ [(set (match_operand:PINSR_MODE 0 "register_operand" "=x,x,x,x,v,v")
(vec_merge:PINSR_MODE
(vec_duplicate:PINSR_MODE
- (match_operand:<ssescalarmode> 2 "nonimmediate_operand" "r,m,r,m"))
- (match_operand:PINSR_MODE 1 "register_operand" "0,0,x,x")
+ (match_operand:<ssescalarmode> 2 "nonimmediate_operand" "r,m,r,m,r,m"))
+ (match_operand:PINSR_MODE 1 "register_operand" "0,0,x,x,v,v")
(match_operand:SI 3 "const_int_operand")))]
"TARGET_SSE2
&& ((unsigned) exact_log2 (INTVAL (operands[3]))
@@ -11907,16 +12081,18 @@
case 1:
return "pinsr<ssemodesuffix>\t{%3, %2, %0|%0, %2, %3}";
case 2:
+ case 4:
if (GET_MODE_SIZE (<ssescalarmode>mode) < GET_MODE_SIZE (SImode))
return "vpinsr<ssemodesuffix>\t{%3, %k2, %1, %0|%0, %1, %k2, %3}";
/* FALLTHRU */
case 3:
+ case 5:
return "vpinsr<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}";
default:
gcc_unreachable ();
}
}
- [(set_attr "isa" "noavx,noavx,avx,avx")
+ [(set_attr "isa" "noavx,noavx,avx,avx,<pinsr_evex_isa>,<pinsr_evex_isa>")
(set_attr "type" "sselog")
(set (attr "prefix_rex")
(if_then_else
@@ -11937,7 +12113,7 @@
(const_string "*")
(const_string "1")))
(set_attr "length_immediate" "1")
- (set_attr "prefix" "orig,orig,vex,vex")
+ (set_attr "prefix" "orig,orig,vex,vex,evex,evex")
(set_attr "mode" "TI")])
(define_expand "<extract_type>_vinsert<shuffletype><extract_suf>_mask"
@@ -12071,7 +12247,7 @@
(const_int 2) (const_int 3)]))
(match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "vm")))]
"TARGET_AVX512F"
- "vinsert<shuffletype>64x4\t{$0x1, %2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2, $0x1}"
+ "vinsert<shuffletype>64x4\t{$0x1, %2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2, 0x1}"
[(set_attr "type" "sselog")
(set_attr "length_immediate" "1")
(set_attr "prefix" "evex")
@@ -12855,11 +13031,11 @@
"operands[2] = CONST0_RTX (V4SImode);")
(define_insn "sse2_loadld"
- [(set (match_operand:V4SI 0 "register_operand" "=x,Yi,x,x,x")
+ [(set (match_operand:V4SI 0 "register_operand" "=v,Yi,x,x,v")
(vec_merge:V4SI
(vec_duplicate:V4SI
- (match_operand:SI 2 "nonimmediate_operand" "m ,r ,m,x,x"))
- (match_operand:V4SI 1 "reg_or_0_operand" "C ,C ,C,0,x")
+ (match_operand:SI 2 "nonimmediate_operand" "m ,r ,m,x,v"))
+ (match_operand:V4SI 1 "reg_or_0_operand" "C ,C ,C,0,v")
(const_int 1)))]
"TARGET_SSE"
"@
@@ -12870,7 +13046,7 @@
vmovss\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "isa" "sse2,sse2,noavx,noavx,avx")
(set_attr "type" "ssemov")
- (set_attr "prefix" "maybe_vex,maybe_vex,orig,orig,vex")
+ (set_attr "prefix" "maybe_vex,maybe_vex,orig,orig,maybe_evex")
(set_attr "mode" "TI,TI,V4SF,SF,SF")])
;; QI and HI modes handled by pextr patterns.
@@ -12878,39 +13054,44 @@
[(V16QI "TARGET_SSE4_1") V8HI])
(define_insn "*vec_extract<mode>"
- [(set (match_operand:<ssescalarmode> 0 "register_sse4nonimm_operand" "=r,m")
+ [(set (match_operand:<ssescalarmode> 0 "register_sse4nonimm_operand" "=r,m,r,m")
(vec_select:<ssescalarmode>
- (match_operand:PEXTR_MODE12 1 "register_operand" "x,x")
+ (match_operand:PEXTR_MODE12 1 "register_operand" "x,x,v,v")
(parallel
[(match_operand:SI 2 "const_0_to_<ssescalarnummask>_operand")])))]
"TARGET_SSE2"
"@
%vpextr<ssemodesuffix>\t{%2, %1, %k0|%k0, %1, %2}
- %vpextr<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "*,sse4")
+ %vpextr<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
+ vpextr<ssemodesuffix>\t{%2, %1, %k0|%k0, %1, %2}
+ vpextr<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
+ [(set_attr "isa" "*,sse4,avx512bw,avx512bw")
(set_attr "type" "sselog1")
(set_attr "prefix_data16" "1")
(set (attr "prefix_extra")
(if_then_else
- (and (eq_attr "alternative" "0")
+ (and (eq_attr "alternative" "0,2")
(eq (const_string "<MODE>mode") (const_string "V8HImode")))
(const_string "*")
(const_string "1")))
(set_attr "length_immediate" "1")
- (set_attr "prefix" "maybe_vex")
+ (set_attr "prefix" "maybe_vex,maybe_vex,evex,evex")
(set_attr "mode" "TI")])
(define_insn "*vec_extract<PEXTR_MODE12:mode>_zext"
- [(set (match_operand:SWI48 0 "register_operand" "=r")
+ [(set (match_operand:SWI48 0 "register_operand" "=r,r")
(zero_extend:SWI48
(vec_select:<PEXTR_MODE12:ssescalarmode>
- (match_operand:PEXTR_MODE12 1 "register_operand" "x")
+ (match_operand:PEXTR_MODE12 1 "register_operand" "x,v")
(parallel
[(match_operand:SI 2
"const_0_to_<PEXTR_MODE12:ssescalarnummask>_operand")]))))]
"TARGET_SSE2"
- "%vpextr<PEXTR_MODE12:ssemodesuffix>\t{%2, %1, %k0|%k0, %1, %2}"
- [(set_attr "type" "sselog1")
+ "@
+ %vpextr<PEXTR_MODE12:ssemodesuffix>\t{%2, %1, %k0|%k0, %1, %2}
+ vpextr<PEXTR_MODE12:ssemodesuffix>\t{%2, %1, %k0|%k0, %1, %2}"
+ [(set_attr "isa" "*,avx512bw")
+ (set_attr "type" "sselog1")
(set_attr "prefix_data16" "1")
(set (attr "prefix_extra")
(if_then_else
@@ -12931,9 +13112,9 @@
"#")
(define_insn "*vec_extract<ssevecmodelower>_0"
- [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r ,r,x ,m")
+ [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r ,r,v ,m")
(vec_select:SWI48
- (match_operand:<ssevecmode> 1 "nonimmediate_operand" "mYj,x,xm,x")
+ (match_operand:<ssevecmode> 1 "nonimmediate_operand" "mYj,v,vm,v")
(parallel [(const_int 0)])))]
"TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"#"
@@ -12943,7 +13124,7 @@
[(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI
(vec_select:SI
- (match_operand:V4SI 1 "register_operand" "x")
+ (match_operand:V4SI 1 "register_operand" "v")
(parallel [(const_int 0)]))))]
"TARGET_64BIT && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC"
"#"
@@ -12952,9 +13133,9 @@
"operands[1] = gen_lowpart (SImode, operands[1]);")
(define_insn "*vec_extractv2di_0_sse"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=x,m")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=v,m")
(vec_select:DI
- (match_operand:V2DI 1 "nonimmediate_operand" "xm,x")
+ (match_operand:V2DI 1 "nonimmediate_operand" "vm,v")
(parallel [(const_int 0)])))]
"TARGET_SSE && !TARGET_64BIT
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))"
@@ -12970,46 +13151,49 @@
"operands[1] = gen_lowpart (<MODE>mode, operands[1]);")
(define_insn "*vec_extractv4si"
- [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,Yr,*x,x")
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm,Yr,*x,x,Yv")
(vec_select:SI
- (match_operand:V4SI 1 "register_operand" "x,0,0,x")
+ (match_operand:V4SI 1 "register_operand" "x,v,0,0,x,v")
(parallel [(match_operand:SI 2 "const_0_to_3_operand")])))]
"TARGET_SSE4_1"
{
switch (which_alternative)
{
case 0:
+ case 1:
return "%vpextrd\t{%2, %1, %0|%0, %1, %2}";
- case 1:
case 2:
- operands [2] = GEN_INT (INTVAL (operands[2]) * 4);
+ case 3:
+ operands[2] = GEN_INT (INTVAL (operands[2]) * 4);
return "psrldq\t{%2, %0|%0, %2}";
- case 3:
- operands [2] = GEN_INT (INTVAL (operands[2]) * 4);
+ case 4:
+ case 5:
+ operands[2] = GEN_INT (INTVAL (operands[2]) * 4);
return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
default:
gcc_unreachable ();
}
}
- [(set_attr "isa" "*,noavx,noavx,avx")
- (set_attr "type" "sselog1,sseishft1,sseishft1,sseishft1")
- (set_attr "prefix_extra" "1,*,*,*")
+ [(set_attr "isa" "*,avx512dq,noavx,noavx,avx,avx512bw")
+ (set_attr "type" "sselog1,sselog1,sseishft1,sseishft1,sseishft1,sseishft1")
+ (set_attr "prefix_extra" "1,1,*,*,*,*")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "maybe_vex,orig,orig,vex")
+ (set_attr "prefix" "maybe_vex,evex,orig,orig,vex,evex")
(set_attr "mode" "TI")])
(define_insn "*vec_extractv4si_zext"
- [(set (match_operand:DI 0 "register_operand" "=r")
+ [(set (match_operand:DI 0 "register_operand" "=r,r")
(zero_extend:DI
(vec_select:SI
- (match_operand:V4SI 1 "register_operand" "x")
+ (match_operand:V4SI 1 "register_operand" "x,v")
(parallel [(match_operand:SI 2 "const_0_to_3_operand")]))))]
"TARGET_64BIT && TARGET_SSE4_1"
"%vpextrd\t{%2, %1, %k0|%k0, %1, %2}"
- [(set_attr "type" "sselog1")
+ [(set_attr "isa" "*,avx512dq")
+ (set_attr "type" "sselog1")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
(set_attr "prefix" "maybe_vex")
@@ -13038,26 +13222,28 @@
})
(define_insn "*vec_extractv2di_1"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,m,x,x,x,x,r")
+ [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm,m,x,x,Yv,x,v,r")
(vec_select:DI
- (match_operand:V2DI 1 "nonimmediate_operand" "x ,x,0,x,x,o,o")
+ (match_operand:V2DI 1 "nonimmediate_operand" "x ,v ,v,0,x, v,x,o,o")
(parallel [(const_int 1)])))]
"TARGET_SSE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
"@
%vpextrq\t{$1, %1, %0|%0, %1, 1}
+ vpextrq\t{$1, %1, %0|%0, %1, 1}
%vmovhps\t{%1, %0|%0, %1}
psrldq\t{$8, %0|%0, 8}
vpsrldq\t{$8, %1, %0|%0, %1, 8}
+ vpsrldq\t{$8, %1, %0|%0, %1, 8}
movhlps\t{%1, %0|%0, %1}
#
#"
- [(set_attr "isa" "x64_sse4,*,sse2_noavx,avx,noavx,*,x64")
- (set_attr "type" "sselog1,ssemov,sseishft1,sseishft1,ssemov,ssemov,imov")
- (set_attr "length_immediate" "1,*,1,1,*,*,*")
- (set_attr "prefix_rex" "1,*,*,*,*,*,*")
- (set_attr "prefix_extra" "1,*,*,*,*,*,*")
- (set_attr "prefix" "maybe_vex,maybe_vex,orig,vex,orig,*,*")
- (set_attr "mode" "TI,V2SF,TI,TI,V4SF,DI,DI")])
+ [(set_attr "isa" "x64_sse4,x64_avx512dq,*,sse2_noavx,avx,avx512bw,noavx,*,x64")
+ (set_attr "type" "sselog1,sselog1,ssemov,sseishft1,sseishft1,sseishft1,ssemov,ssemov,imov")
+ (set_attr "length_immediate" "1,1,*,1,1,1,*,*,*")
+ (set_attr "prefix_rex" "1,1,*,*,*,*,*,*,*")
+ (set_attr "prefix_extra" "1,1,*,*,*,*,*,*,*")
+ (set_attr "prefix" "maybe_vex,evex,maybe_vex,orig,vex,evex,orig,*,*")
+ (set_attr "mode" "TI,TI,V2SF,TI,TI,TI,V4SF,DI,DI")])
(define_split
[(set (match_operand:<ssescalarmode> 0 "register_operand")
@@ -13765,12 +13951,12 @@
(set_attr "mode" "DI")])
(define_insn "avx2_pmaddubsw256"
- [(set (match_operand:V16HI 0 "register_operand" "=x")
+ [(set (match_operand:V16HI 0 "register_operand" "=x,v")
(ss_plus:V16HI
(mult:V16HI
(zero_extend:V16HI
(vec_select:V16QI
- (match_operand:V32QI 1 "register_operand" "x")
+ (match_operand:V32QI 1 "register_operand" "x,v")
(parallel [(const_int 0) (const_int 2)
(const_int 4) (const_int 6)
(const_int 8) (const_int 10)
@@ -13781,7 +13967,7 @@
(const_int 28) (const_int 30)])))
(sign_extend:V16HI
(vec_select:V16QI
- (match_operand:V32QI 2 "nonimmediate_operand" "xm")
+ (match_operand:V32QI 2 "nonimmediate_operand" "xm,vm")
(parallel [(const_int 0) (const_int 2)
(const_int 4) (const_int 6)
(const_int 8) (const_int 10)
@@ -13813,9 +13999,10 @@
(const_int 29) (const_int 31)]))))))]
"TARGET_AVX2"
"vpmaddubsw\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "type" "sseiadd")
+ [(set_attr "isa" "*,avx512bw")
+ (set_attr "type" "sseiadd")
(set_attr "prefix_extra" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "vex,evex")
(set_attr "mode" "OI")])
;; The correct representation for this is absolutely enormous, and
@@ -13868,19 +14055,19 @@
(set_attr "mode" "XI")])
(define_insn "ssse3_pmaddubsw128"
- [(set (match_operand:V8HI 0 "register_operand" "=x,x")
+ [(set (match_operand:V8HI 0 "register_operand" "=x,x,v")
(ss_plus:V8HI
(mult:V8HI
(zero_extend:V8HI
(vec_select:V8QI
- (match_operand:V16QI 1 "register_operand" "0,x")
+ (match_operand:V16QI 1 "register_operand" "0,x,v")
(parallel [(const_int 0) (const_int 2)
(const_int 4) (const_int 6)
(const_int 8) (const_int 10)
(const_int 12) (const_int 14)])))
(sign_extend:V8HI
(vec_select:V8QI
- (match_operand:V16QI 2 "vector_operand" "xBm,xm")
+ (match_operand:V16QI 2 "vector_operand" "xBm,xm,vm")
(parallel [(const_int 0) (const_int 2)
(const_int 4) (const_int 6)
(const_int 8) (const_int 10)
@@ -13901,13 +14088,14 @@
"TARGET_SSSE3"
"@
pmaddubsw\t{%2, %0|%0, %2}
+ vpmaddubsw\t{%2, %1, %0|%0, %1, %2}
vpmaddubsw\t{%2, %1, %0|%0, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sseiadd")
(set_attr "atom_unit" "simul")
- (set_attr "prefix_data16" "1,*")
+ (set_attr "prefix_data16" "1,*,*")
(set_attr "prefix_extra" "1")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,vex,evex")
(set_attr "mode" "TI")])
(define_insn "ssse3_pmaddubsw"
@@ -13988,16 +14176,16 @@
})
(define_insn "*<ssse3_avx2>_pmulhrsw<mode>3<mask_name>"
- [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,v")
+ [(set (match_operand:VI2_AVX2 0 "register_operand" "=x,x,v")
(truncate:VI2_AVX2
(lshiftrt:<ssedoublemode>
(plus:<ssedoublemode>
(lshiftrt:<ssedoublemode>
(mult:<ssedoublemode>
(sign_extend:<ssedoublemode>
- (match_operand:VI2_AVX2 1 "vector_operand" "%0,v"))
+ (match_operand:VI2_AVX2 1 "vector_operand" "%0,x,v"))
(sign_extend:<ssedoublemode>
- (match_operand:VI2_AVX2 2 "vector_operand" "xBm,vm")))
+ (match_operand:VI2_AVX2 2 "vector_operand" "xBm,xm,vm")))
(const_int 14))
(match_operand:VI2_AVX2 3 "const1_operand"))
(const_int 1))))]
@@ -14005,12 +14193,13 @@
&& ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
"@
pmulhrsw\t{%2, %0|%0, %2}
+ vpmulhrsw\t{%2, %1, %0<mask_operand4>|%0<mask_operand4>, %1, %2}
vpmulhrsw\t{%2, %1, %0<mask_operand4>|%0<mask_operand4>, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sseimul")
- (set_attr "prefix_data16" "1,*")
+ (set_attr "prefix_data16" "1,*,*")
(set_attr "prefix_extra" "1")
- (set_attr "prefix" "orig,maybe_evex")
+ (set_attr "prefix" "orig,maybe_evex,evex")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "*ssse3_pmulhrswv4hi3"
@@ -14035,21 +14224,22 @@
(set_attr "mode" "DI")])
(define_insn "<ssse3_avx2>_pshufb<mode>3<mask_name>"
- [(set (match_operand:VI1_AVX512 0 "register_operand" "=x,v")
+ [(set (match_operand:VI1_AVX512 0 "register_operand" "=x,x,v")
(unspec:VI1_AVX512
- [(match_operand:VI1_AVX512 1 "register_operand" "0,v")
- (match_operand:VI1_AVX512 2 "vector_operand" "xBm,vm")]
+ [(match_operand:VI1_AVX512 1 "register_operand" "0,x,v")
+ (match_operand:VI1_AVX512 2 "vector_operand" "xBm,xm,vm")]
UNSPEC_PSHUFB))]
"TARGET_SSSE3 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
"@
pshufb\t{%2, %0|%0, %2}
+ vpshufb\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}
vpshufb\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sselog1")
- (set_attr "prefix_data16" "1,*")
+ (set_attr "prefix_data16" "1,*,*")
(set_attr "prefix_extra" "1")
- (set_attr "prefix" "orig,maybe_evex")
- (set_attr "btver2_decode" "vector,vector")
+ (set_attr "prefix" "orig,maybe_evex,evex")
+ (set_attr "btver2_decode" "vector")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "ssse3_pshufbv8qi3"
@@ -14117,11 +14307,11 @@
(set_attr "mode" "<sseinsnmode>")])
(define_insn "<ssse3_avx2>_palignr<mode>"
- [(set (match_operand:SSESCALARMODE 0 "register_operand" "=x,v")
+ [(set (match_operand:SSESCALARMODE 0 "register_operand" "=x,x,v")
(unspec:SSESCALARMODE
- [(match_operand:SSESCALARMODE 1 "register_operand" "0,v")
- (match_operand:SSESCALARMODE 2 "vector_operand" "xBm,vm")
- (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n,n")]
+ [(match_operand:SSESCALARMODE 1 "register_operand" "0,x,v")
+ (match_operand:SSESCALARMODE 2 "vector_operand" "xBm,xm,vm")
+ (match_operand:SI 3 "const_0_to_255_mul_8_operand" "n,n,n")]
UNSPEC_PALIGNR))]
"TARGET_SSSE3"
{
@@ -14132,18 +14322,19 @@
case 0:
return "palignr\t{%3, %2, %0|%0, %2, %3}";
case 1:
+ case 2:
return "vpalignr\t{%3, %2, %1, %0|%0, %1, %2, %3}";
default:
gcc_unreachable ();
}
}
- [(set_attr "isa" "noavx,avx")
+ [(set_attr "isa" "noavx,avx,avx512bw")
(set_attr "type" "sseishft")
(set_attr "atom_unit" "sishuf")
- (set_attr "prefix_data16" "1,*")
+ (set_attr "prefix_data16" "1,*,*")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "orig,vex")
+ (set_attr "prefix" "orig,vex,evex")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "ssse3_palignrdi"
@@ -14423,21 +14614,22 @@
(set_attr "mode" "<sseinsnmode>")])
(define_insn "<sse4_1_avx2>_packusdw<mask_name>"
- [(set (match_operand:VI2_AVX2 0 "register_operand" "=Yr,*x,v")
+ [(set (match_operand:VI2_AVX2 0 "register_operand" "=Yr,*x,x,v")
(vec_concat:VI2_AVX2
(us_truncate:<ssehalfvecmode>
- (match_operand:<sseunpackmode> 1 "register_operand" "0,0,v"))
+ (match_operand:<sseunpackmode> 1 "register_operand" "0,0,x,v"))
(us_truncate:<ssehalfvecmode>
- (match_operand:<sseunpackmode> 2 "vector_operand" "YrBm,*xBm,vm"))))]
+ (match_operand:<sseunpackmode> 2 "vector_operand" "YrBm,*xBm,xm,vm"))))]
"TARGET_SSE4_1 && <mask_mode512bit_condition> && <mask_avx512bw_condition>"
"@
packusdw\t{%2, %0|%0, %2}
packusdw\t{%2, %0|%0, %2}
+ vpackusdw\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}
vpackusdw\t{%2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2}"
- [(set_attr "isa" "noavx,noavx,avx")
+ [(set_attr "isa" "noavx,noavx,avx,avx512bw")
(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
- (set_attr "prefix" "orig,orig,maybe_evex")
+ (set_attr "prefix" "orig,orig,<mask_prefix>,evex")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "<sse4_1_avx2>_pblendvb"
@@ -16551,30 +16743,40 @@
(set_attr "btver2_decode" "vector")
(set_attr "mode" "OI")])
+(define_mode_attr pbroadcast_evex_isa
+ [(V64QI "avx512bw") (V32QI "avx512bw") (V16QI "avx512bw")
+ (V32HI "avx512bw") (V16HI "avx512bw") (V8HI "avx512bw")
+ (V16SI "avx512f") (V8SI "avx512f") (V4SI "avx512f")
+ (V8DI "avx512f") (V4DI "avx512f") (V2DI "avx512f")])
+
(define_insn "avx2_pbroadcast<mode>"
- [(set (match_operand:VI 0 "register_operand" "=x")
+ [(set (match_operand:VI 0 "register_operand" "=x,v")
(vec_duplicate:VI
(vec_select:<ssescalarmode>
- (match_operand:<ssexmmmode> 1 "nonimmediate_operand" "xm")
+ (match_operand:<ssexmmmode> 1 "nonimmediate_operand" "xm,vm")
(parallel [(const_int 0)]))))]
"TARGET_AVX2"
"vpbroadcast<ssemodesuffix>\t{%1, %0|%0, %<iptr>1}"
- [(set_attr "type" "ssemov")
+ [(set_attr "isa" "*,<pbroadcast_evex_isa>")
+ (set_attr "type" "ssemov")
(set_attr "prefix_extra" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "vex,evex")
(set_attr "mode" "<sseinsnmode>")])
(define_insn "avx2_pbroadcast<mode>_1"
- [(set (match_operand:VI_256 0 "register_operand" "=x,x")
+ [(set (match_operand:VI_256 0 "register_operand" "=x,x,v,v")
(vec_duplicate:VI_256
(vec_select:<ssescalarmode>
- (match_operand:VI_256 1 "nonimmediate_operand" "m,x")
+ (match_operand:VI_256 1 "nonimmediate_operand" "m,x,m,v")
(parallel [(const_int 0)]))))]
"TARGET_AVX2"
"@
vpbroadcast<ssemodesuffix>\t{%1, %0|%0, %<iptr>1}
+ vpbroadcast<ssemodesuffix>\t{%x1, %0|%0, %x1}
+ vpbroadcast<ssemodesuffix>\t{%1, %0|%0, %<iptr>1}
vpbroadcast<ssemodesuffix>\t{%x1, %0|%0, %x1}"
- [(set_attr "type" "ssemov")
+ [(set_attr "isa" "*,*,<pbroadcast_evex_isa>,<pbroadcast_evex_isa>")
+ (set_attr "type" "ssemov")
(set_attr "prefix_extra" "1")
(set_attr "prefix" "vex")
(set_attr "mode" "<sseinsnmode>")])
@@ -16684,15 +16886,15 @@
(set_attr "mode" "OI")])
(define_insn "avx2_vec_dupv4df"
- [(set (match_operand:V4DF 0 "register_operand" "=x")
+ [(set (match_operand:V4DF 0 "register_operand" "=v")
(vec_duplicate:V4DF
(vec_select:DF
- (match_operand:V2DF 1 "register_operand" "x")
+ (match_operand:V2DF 1 "register_operand" "v")
(parallel [(const_int 0)]))))]
"TARGET_AVX2"
"vbroadcastsd\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "maybe_evex")
(set_attr "mode" "V4DF")])
(define_insn "<avx512>_vec_dup<mode>_1"
@@ -16795,9 +16997,9 @@
(const_int 1)))])
(define_insn "vec_dupv4sf"
- [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=v,v,x")
(vec_duplicate:V4SF
- (match_operand:SF 1 "nonimmediate_operand" "x,m,0")))]
+ (match_operand:SF 1 "nonimmediate_operand" "Yv,m,0")))]
"TARGET_SSE"
"@
vshufps\t{$0, %1, %1, %0|%0, %1, %1, 0}
@@ -16807,13 +17009,13 @@
(set_attr "type" "sseshuf1,ssemov,sseshuf1")
(set_attr "length_immediate" "1,0,1")
(set_attr "prefix_extra" "0,1,*")
- (set_attr "prefix" "vex,vex,orig")
+ (set_attr "prefix" "maybe_evex,maybe_evex,orig")
(set_attr "mode" "V4SF")])
(define_insn "*vec_dupv4si"
- [(set (match_operand:V4SI 0 "register_operand" "=x,x,x")
+ [(set (match_operand:V4SI 0 "register_operand" "=v,v,x")
(vec_duplicate:V4SI
- (match_operand:SI 1 "nonimmediate_operand" " x,m,0")))]
+ (match_operand:SI 1 "nonimmediate_operand" "Yv,m,0")))]
"TARGET_SSE"
"@
%vpshufd\t{$0, %1, %0|%0, %1, 0}
@@ -16823,13 +17025,13 @@
(set_attr "type" "sselog1,ssemov,sselog1")
(set_attr "length_immediate" "1,0,1")
(set_attr "prefix_extra" "0,1,*")
- (set_attr "prefix" "maybe_vex,vex,orig")
+ (set_attr "prefix" "maybe_vex,maybe_evex,orig")
(set_attr "mode" "TI,V4SF,V4SF")])
(define_insn "*vec_dupv2di"
- [(set (match_operand:V2DI 0 "register_operand" "=x,x,x,x")
+ [(set (match_operand:V2DI 0 "register_operand" "=x,v,v,x")
(vec_duplicate:V2DI
- (match_operand:DI 1 "nonimmediate_operand" " 0,x,m,0")))]
+ (match_operand:DI 1 "nonimmediate_operand" " 0,Yv,m,0")))]
"TARGET_SSE"
"@
punpcklqdq\t%0, %0
@@ -16838,19 +17040,23 @@
movlhps\t%0, %0"
[(set_attr "isa" "sse2_noavx,avx,sse3,noavx")
(set_attr "type" "sselog1,sselog1,sselog1,ssemov")
- (set_attr "prefix" "orig,vex,maybe_vex,orig")
+ (set_attr "prefix" "orig,maybe_evex,maybe_vex,orig")
(set_attr "mode" "TI,TI,DF,V4SF")])
(define_insn "avx2_vbroadcasti128_<mode>"
- [(set (match_operand:VI_256 0 "register_operand" "=x")
+ [(set (match_operand:VI_256 0 "register_operand" "=x,v,v")
(vec_concat:VI_256
- (match_operand:<ssehalfvecmode> 1 "memory_operand" "m")
+ (match_operand:<ssehalfvecmode> 1 "memory_operand" "m,m,m")
(match_dup 1)))]
"TARGET_AVX2"
- "vbroadcasti128\t{%1, %0|%0, %1}"
- [(set_attr "type" "ssemov")
+ "@
+ vbroadcasti128\t{%1, %0|%0, %1}
+ vbroadcast<i128vldq>\t{%1, %0|%0, %1}
+ vbroadcast<shuffletype>32x4\t{%1, %0|%0, %1}"
+ [(set_attr "isa" "*,avx512dq,avx512vl")
+ (set_attr "type" "ssemov")
(set_attr "prefix_extra" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "vex,evex,evex")
(set_attr "mode" "OI")])
;; Modes handled by AVX vec_dup patterns.
@@ -16927,19 +17133,24 @@
"operands[2] = gen_lowpart (<ssehalfvecmode>mode, operands[0]);")
(define_insn "avx_vbroadcastf128_<mode>"
- [(set (match_operand:V_256 0 "register_operand" "=x,x,x")
+ [(set (match_operand:V_256 0 "register_operand" "=x,x,x,v,v,v,v")
(vec_concat:V_256
- (match_operand:<ssehalfvecmode> 1 "nonimmediate_operand" "m,0,?x")
+ (match_operand:<ssehalfvecmode> 1 "nonimmediate_operand" "m,0,?x,m,0,m,0")
(match_dup 1)))]
"TARGET_AVX"
"@
vbroadcast<i128>\t{%1, %0|%0, %1}
vinsert<i128>\t{$1, %1, %0, %0|%0, %0, %1, 1}
- vperm2<i128>\t{$0, %t1, %t1, %0|%0, %t1, %t1, 0}"
- [(set_attr "type" "ssemov,sselog1,sselog1")
+ vperm2<i128>\t{$0, %t1, %t1, %0|%0, %t1, %t1, 0}
+ vbroadcast<i128vldq>\t{%1, %0|%0, %1}
+ vinsert<i128vldq>\t{$1, %1, %0, %0|%0, %0, %1, 1}
+ vbroadcast<shuffletype>32x4\t{%1, %0|%0, %1}
+ vinsert<shuffletype>32x4\t{$1, %1, %0, %0|%0, %0, %1, 1}"
+ [(set_attr "isa" "*,*,*,avx512dq,avx512dq,avx512vl,avx512vl")
+ (set_attr "type" "ssemov,sselog1,sselog1,ssemov,sselog1,ssemov,sselog1")
(set_attr "prefix_extra" "1")
- (set_attr "length_immediate" "0,1,1")
- (set_attr "prefix" "vex")
+ (set_attr "length_immediate" "0,1,1,0,1,0,1")
+ (set_attr "prefix" "vex,vex,vex,evex,evex,evex,evex")
(set_attr "mode" "<sseinsnmode>")])
;; For broadcast[i|f]32x2. Yes there is no v4sf version, only v4si.
@@ -16961,7 +17172,7 @@
(match_operand:<ssexmmmode> 1 "nonimmediate_operand" "vm")
(parallel [(const_int 0) (const_int 1)]))))]
"TARGET_AVX512DQ"
- "vbroadcast<shuffletype>32x2\t{%1, %0<mask_operand2>|%0<mask_operand2>, %1}"
+ "vbroadcast<shuffletype>32x2\t{%1, %0<mask_operand2>|%0<mask_operand2>, %q1}"
[(set_attr "type" "ssemov")
(set_attr "prefix_extra" "1")
(set_attr "prefix" "evex")
@@ -17184,11 +17395,11 @@
(set_attr "mode" "<sseinsnmode>")])
(define_expand "<avx512>_vpermi2var<mode>3_maskz"
- [(match_operand:VI48F 0 "register_operand" "=v")
- (match_operand:VI48F 1 "register_operand" "v")
- (match_operand:<sseintvecmode> 2 "register_operand" "0")
- (match_operand:VI48F 3 "nonimmediate_operand" "vm")
- (match_operand:<avx512fmaskmode> 4 "register_operand" "Yk")]
+ [(match_operand:VI48F 0 "register_operand")
+ (match_operand:VI48F 1 "register_operand")
+ (match_operand:<sseintvecmode> 2 "register_operand")
+ (match_operand:VI48F 3 "nonimmediate_operand")
+ (match_operand:<avx512fmaskmode> 4 "register_operand")]
"TARGET_AVX512F"
{
emit_insn (gen_<avx512>_vpermi2var<mode>3_maskz_1 (
@@ -17212,11 +17423,11 @@
})
(define_expand "<avx512>_vpermi2var<mode>3_maskz"
- [(match_operand:VI2_AVX512VL 0 "register_operand" "=v")
- (match_operand:VI2_AVX512VL 1 "register_operand" "v")
- (match_operand:<sseintvecmode> 2 "register_operand" "0")
- (match_operand:VI2_AVX512VL 3 "nonimmediate_operand" "vm")
- (match_operand:<avx512fmaskmode> 4 "register_operand" "Yk")]
+ [(match_operand:VI2_AVX512VL 0 "register_operand")
+ (match_operand:VI2_AVX512VL 1 "register_operand")
+ (match_operand:<sseintvecmode> 2 "register_operand")
+ (match_operand:VI2_AVX512VL 3 "nonimmediate_operand")
+ (match_operand:<avx512fmaskmode> 4 "register_operand")]
"TARGET_AVX512BW"
{
emit_insn (gen_<avx512>_vpermi2var<mode>3_maskz_1 (
@@ -17313,11 +17524,11 @@
(set_attr "mode" "<sseinsnmode>")])
(define_expand "<avx512>_vpermt2var<mode>3_maskz"
- [(match_operand:VI48F 0 "register_operand" "=v")
- (match_operand:<sseintvecmode> 1 "register_operand" "v")
- (match_operand:VI48F 2 "register_operand" "0")
- (match_operand:VI48F 3 "nonimmediate_operand" "vm")
- (match_operand:<avx512fmaskmode> 4 "register_operand" "Yk")]
+ [(match_operand:VI48F 0 "register_operand")
+ (match_operand:<sseintvecmode> 1 "register_operand")
+ (match_operand:VI48F 2 "register_operand")
+ (match_operand:VI48F 3 "nonimmediate_operand")
+ (match_operand:<avx512fmaskmode> 4 "register_operand")]
"TARGET_AVX512F"
{
emit_insn (gen_<avx512>_vpermt2var<mode>3_maskz_1 (
@@ -17327,11 +17538,11 @@
})
(define_expand "<avx512>_vpermt2var<mode>3_maskz"
- [(match_operand:VI1_AVX512VL 0 "register_operand" "=v")
- (match_operand:<sseintvecmode> 1 "register_operand" "v")
- (match_operand:VI1_AVX512VL 2 "register_operand" "0")
- (match_operand:VI1_AVX512VL 3 "nonimmediate_operand" "vm")
- (match_operand:<avx512fmaskmode> 4 "register_operand" "Yk")]
+ [(match_operand:VI1_AVX512VL 0 "register_operand")
+ (match_operand:<sseintvecmode> 1 "register_operand")
+ (match_operand:VI1_AVX512VL 2 "register_operand")
+ (match_operand:VI1_AVX512VL 3 "nonimmediate_operand")
+ (match_operand:<avx512fmaskmode> 4 "register_operand")]
"TARGET_AVX512VBMI"
{
emit_insn (gen_<avx512>_vpermt2var<mode>3_maskz_1 (
@@ -17341,11 +17552,11 @@
})
(define_expand "<avx512>_vpermt2var<mode>3_maskz"
- [(match_operand:VI2_AVX512VL 0 "register_operand" "=v")
- (match_operand:<sseintvecmode> 1 "register_operand" "v")
- (match_operand:VI2_AVX512VL 2 "register_operand" "0")
- (match_operand:VI2_AVX512VL 3 "nonimmediate_operand" "vm")
- (match_operand:<avx512fmaskmode> 4 "register_operand" "Yk")]
+ [(match_operand:VI2_AVX512VL 0 "register_operand")
+ (match_operand:<sseintvecmode> 1 "register_operand")
+ (match_operand:VI2_AVX512VL 2 "register_operand")
+ (match_operand:VI2_AVX512VL 3 "nonimmediate_operand")
+ (match_operand:<avx512fmaskmode> 4 "register_operand")]
"TARGET_AVX512BW"
{
emit_insn (gen_<avx512>_vpermt2var<mode>3_maskz_1 (
@@ -17607,10 +17818,12 @@
(vec_select:<ssehalfvecmode>
(match_operand:VI8F_256 1 "register_operand" "v")
(parallel [(const_int 2) (const_int 3)]))))]
- "TARGET_AVX"
+ "TARGET_AVX && <mask_avx512dq_condition>"
{
- if (TARGET_AVX512VL)
+ if (TARGET_AVX512DQ)
return "vinsert<shuffletype>64x2\t{$0x0, %2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2, 0x0}";
+ else if (TARGET_AVX512VL)
+ return "vinsert<shuffletype>32x4\t{$0x0, %2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2, 0x0}";
else
return "vinsert<i128>\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}";
}
@@ -17627,10 +17840,12 @@
(match_operand:VI8F_256 1 "register_operand" "v")
(parallel [(const_int 0) (const_int 1)]))
(match_operand:<ssehalfvecmode> 2 "nonimmediate_operand" "vm")))]
- "TARGET_AVX"
+ "TARGET_AVX && <mask_avx512dq_condition>"
{
- if (TARGET_AVX512VL)
+ if (TARGET_AVX512DQ)
return "vinsert<shuffletype>64x2\t{$0x1, %2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2, 0x1}";
+ else if (TARGET_AVX512VL)
+ return "vinsert<shuffletype>32x4\t{$0x1, %2, %1, %0<mask_operand3>|%0<mask_operand3>, %1, %2, 0x1}";
else
return "vinsert<i128>\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}";
}
@@ -17683,47 +17898,51 @@
(set_attr "mode" "<sseinsnmode>")])
(define_insn "vec_set_lo_v16hi"
- [(set (match_operand:V16HI 0 "register_operand" "=x")
+ [(set (match_operand:V16HI 0 "register_operand" "=x,v")
(vec_concat:V16HI
- (match_operand:V8HI 2 "nonimmediate_operand" "xm")
+ (match_operand:V8HI 2 "nonimmediate_operand" "xm,vm")
(vec_select:V8HI
- (match_operand:V16HI 1 "register_operand" "x")
+ (match_operand:V16HI 1 "register_operand" "x,v")
(parallel [(const_int 8) (const_int 9)
(const_int 10) (const_int 11)
(const_int 12) (const_int 13)
(const_int 14) (const_int 15)]))))]
"TARGET_AVX"
- "vinsert%~128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
+ "@
+ vinsert%~128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}
+ vinserti32x4\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "vex,evex")
(set_attr "mode" "OI")])
(define_insn "vec_set_hi_v16hi"
- [(set (match_operand:V16HI 0 "register_operand" "=x")
+ [(set (match_operand:V16HI 0 "register_operand" "=x,v")
(vec_concat:V16HI
(vec_select:V8HI
- (match_operand:V16HI 1 "register_operand" "x")
+ (match_operand:V16HI 1 "register_operand" "x,v")
(parallel [(const_int 0) (const_int 1)
(const_int 2) (const_int 3)
(const_int 4) (const_int 5)
(const_int 6) (const_int 7)]))
- (match_operand:V8HI 2 "nonimmediate_operand" "xm")))]
+ (match_operand:V8HI 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_AVX"
- "vinsert%~128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
+ "@
+ vinsert%~128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}
+ vinserti32x4\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "vex,evex")
(set_attr "mode" "OI")])
(define_insn "vec_set_lo_v32qi"
- [(set (match_operand:V32QI 0 "register_operand" "=x")
+ [(set (match_operand:V32QI 0 "register_operand" "=x,v")
(vec_concat:V32QI
- (match_operand:V16QI 2 "nonimmediate_operand" "xm")
+ (match_operand:V16QI 2 "nonimmediate_operand" "xm,v")
(vec_select:V16QI
- (match_operand:V32QI 1 "register_operand" "x")
+ (match_operand:V32QI 1 "register_operand" "x,v")
(parallel [(const_int 16) (const_int 17)
(const_int 18) (const_int 19)
(const_int 20) (const_int 21)
@@ -17733,18 +17952,20 @@
(const_int 28) (const_int 29)
(const_int 30) (const_int 31)]))))]
"TARGET_AVX"
- "vinsert%~128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
+ "@
+ vinsert%~128\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}
+ vinserti32x4\t{$0x0, %2, %1, %0|%0, %1, %2, 0x0}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "vex,evex")
(set_attr "mode" "OI")])
(define_insn "vec_set_hi_v32qi"
- [(set (match_operand:V32QI 0 "register_operand" "=x")
+ [(set (match_operand:V32QI 0 "register_operand" "=x,v")
(vec_concat:V32QI
(vec_select:V16QI
- (match_operand:V32QI 1 "register_operand" "x")
+ (match_operand:V32QI 1 "register_operand" "x,v")
(parallel [(const_int 0) (const_int 1)
(const_int 2) (const_int 3)
(const_int 4) (const_int 5)
@@ -17753,13 +17974,15 @@
(const_int 10) (const_int 11)
(const_int 12) (const_int 13)
(const_int 14) (const_int 15)]))
- (match_operand:V16QI 2 "nonimmediate_operand" "xm")))]
+ (match_operand:V16QI 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_AVX"
- "vinsert%~128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
+ "@
+ vinsert%~128\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}
+ vinserti32x4\t{$0x1, %2, %1, %0|%0, %1, %2, 0x1}"
[(set_attr "type" "sselog")
(set_attr "prefix_extra" "1")
(set_attr "length_immediate" "1")
- (set_attr "prefix" "vex")
+ (set_attr "prefix" "vex,evex")
(set_attr "mode" "OI")])
(define_insn "<avx_avx2>_maskload<ssemodesuffix><avxsizesuffix>"
@@ -18375,7 +18598,11 @@
UNSPEC_GATHER))
(clobber (match_scratch:QI 2 "=&Yk"))]
"TARGET_AVX512F"
- "v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, %g6}"
+{
+ if (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) == 4)
+ return "v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, %t6}";
+ return "v<sseintprefix>gatherq<ssemodesuffix>\t{%6, %1%{%2%}|%1%{%2%}, %g6}";
+}
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
@@ -18475,7 +18702,11 @@
UNSPEC_SCATTER))
(clobber (match_scratch:QI 1 "=&Yk"))]
"TARGET_AVX512F"
- "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%5%{%1%}, %3}"
+{
+ if (GET_MODE_SIZE (GET_MODE_INNER (<MODE>mode)) == 8)
+ return "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%5%{%1%}, %3}";
+ return "v<sseintprefix>scatterq<ssemodesuffix>\t{%3, %5%{%1%}|%t5%{%1%}, %3}";
+}
[(set_attr "type" "ssemov")
(set_attr "prefix" "evex")
(set_attr "mode" "<sseinsnmode>")])
diff --git a/gcc/config/i386/sync.md b/gcc/config/i386/sync.md
index bc4fd34e6d5..8322676a7b0 100644
--- a/gcc/config/i386/sync.md
+++ b/gcc/config/i386/sync.md
@@ -605,3 +605,114 @@
(clobber (reg:CC FLAGS_REG))]
""
"lock{%;} %K2<logic>{<imodesuffix>}\t{%1, %0|%0, %1}")
+
+(define_expand "atomic_bit_test_and_set<mode>"
+ [(match_operand:SWI248 0 "register_operand")
+ (match_operand:SWI248 1 "memory_operand")
+ (match_operand:SWI248 2 "nonmemory_operand")
+ (match_operand:SI 3 "const_int_operand") ;; model
+ (match_operand:SI 4 "const_int_operand")]
+ ""
+{
+ emit_insn (gen_atomic_bit_test_and_set<mode>_1 (operands[1], operands[2],
+ operands[3]));
+ rtx tem = gen_reg_rtx (QImode);
+ ix86_expand_setcc (tem, EQ, gen_rtx_REG (CCCmode, FLAGS_REG), const0_rtx);
+ rtx result = convert_modes (<MODE>mode, QImode, tem, 1);
+ if (operands[4] == const0_rtx)
+ result = expand_simple_binop (<MODE>mode, ASHIFT, result,
+ operands[2], operands[0], 0, OPTAB_DIRECT);
+ if (result != operands[0])
+ emit_move_insn (operands[0], result);
+ DONE;
+})
+
+(define_insn "atomic_bit_test_and_set<mode>_1"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (unspec_volatile:SWI248
+ [(match_operand:SWI248 0 "memory_operand" "+m")
+ (match_operand:SI 2 "const_int_operand")] ;; model
+ UNSPECV_XCHG)
+ (const_int 0)))
+ (set (zero_extract:SWI248 (match_dup 0)
+ (const_int 1)
+ (match_operand:SWI248 1 "nonmemory_operand" "rN"))
+ (const_int 1))]
+ ""
+ "lock{%;} %K2bts{<imodesuffix>}\t{%1, %0|%0, %1}")
+
+(define_expand "atomic_bit_test_and_complement<mode>"
+ [(match_operand:SWI248 0 "register_operand")
+ (match_operand:SWI248 1 "memory_operand")
+ (match_operand:SWI248 2 "nonmemory_operand")
+ (match_operand:SI 3 "const_int_operand") ;; model
+ (match_operand:SI 4 "const_int_operand")]
+ ""
+{
+ emit_insn (gen_atomic_bit_test_and_complement<mode>_1 (operands[1],
+ operands[2],
+ operands[3]));
+ rtx tem = gen_reg_rtx (QImode);
+ ix86_expand_setcc (tem, EQ, gen_rtx_REG (CCCmode, FLAGS_REG), const0_rtx);
+ rtx result = convert_modes (<MODE>mode, QImode, tem, 1);
+ if (operands[4] == const0_rtx)
+ result = expand_simple_binop (<MODE>mode, ASHIFT, result,
+ operands[2], operands[0], 0, OPTAB_DIRECT);
+ if (result != operands[0])
+ emit_move_insn (operands[0], result);
+ DONE;
+})
+
+(define_insn "atomic_bit_test_and_complement<mode>_1"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (unspec_volatile:SWI248
+ [(match_operand:SWI248 0 "memory_operand" "+m")
+ (match_operand:SI 2 "const_int_operand")] ;; model
+ UNSPECV_XCHG)
+ (const_int 0)))
+ (set (zero_extract:SWI248 (match_dup 0)
+ (const_int 1)
+ (match_operand:SWI248 1 "nonmemory_operand" "rN"))
+ (not:SWI248 (zero_extract:SWI248 (match_dup 0)
+ (const_int 1)
+ (match_dup 1))))]
+ ""
+ "lock{%;} %K2btc{<imodesuffix>}\t{%1, %0|%0, %1}")
+
+(define_expand "atomic_bit_test_and_reset<mode>"
+ [(match_operand:SWI248 0 "register_operand")
+ (match_operand:SWI248 1 "memory_operand")
+ (match_operand:SWI248 2 "nonmemory_operand")
+ (match_operand:SI 3 "const_int_operand") ;; model
+ (match_operand:SI 4 "const_int_operand")]
+ ""
+{
+ emit_insn (gen_atomic_bit_test_and_reset<mode>_1 (operands[1], operands[2],
+ operands[3]));
+ rtx tem = gen_reg_rtx (QImode);
+ ix86_expand_setcc (tem, EQ, gen_rtx_REG (CCCmode, FLAGS_REG), const0_rtx);
+ rtx result = convert_modes (<MODE>mode, QImode, tem, 1);
+ if (operands[4] == const0_rtx)
+ result = expand_simple_binop (<MODE>mode, ASHIFT, result,
+ operands[2], operands[0], 0, OPTAB_DIRECT);
+ if (result != operands[0])
+ emit_move_insn (operands[0], result);
+ DONE;
+})
+
+(define_insn "atomic_bit_test_and_reset<mode>_1"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (unspec_volatile:SWI248
+ [(match_operand:SWI248 0 "memory_operand" "+m")
+ (match_operand:SI 2 "const_int_operand")] ;; model
+ UNSPECV_XCHG)
+ (const_int 0)))
+ (set (zero_extract:SWI248 (match_dup 0)
+ (const_int 1)
+ (match_operand:SWI248 1 "nonmemory_operand" "rN"))
+ (const_int 0))]
+ ""
+ "lock{%;} %K2btr{<imodesuffix>}\t{%1, %0|%0, %1}")
diff --git a/gcc/config/i386/xopintrin.h b/gcc/config/i386/xopintrin.h
index 609cba04a6f..9c25cc54be0 100644
--- a/gcc/config/i386/xopintrin.h
+++ b/gcc/config/i386/xopintrin.h
@@ -330,7 +330,7 @@ _mm_sha_epi64(__m128i __A, __m128i __B)
}
/* Compare and Predicate Generation
- pcom (integer, unsinged bytes) */
+ pcom (integer, unsigned bytes) */
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_comlt_epu8(__m128i __A, __m128i __B)
@@ -380,7 +380,7 @@ _mm_comtrue_epu8(__m128i __A, __m128i __B)
return (__m128i) __builtin_ia32_vpcomtrueub ((__v16qi)__A, (__v16qi)__B);
}
-/*pcom (integer, unsinged words) */
+/*pcom (integer, unsigned words) */
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_comlt_epu16(__m128i __A, __m128i __B)
@@ -430,7 +430,7 @@ _mm_comtrue_epu16(__m128i __A, __m128i __B)
return (__m128i) __builtin_ia32_vpcomtrueuw ((__v8hi)__A, (__v8hi)__B);
}
-/*pcom (integer, unsinged double words) */
+/*pcom (integer, unsigned double words) */
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_comlt_epu32(__m128i __A, __m128i __B)
@@ -480,7 +480,7 @@ _mm_comtrue_epu32(__m128i __A, __m128i __B)
return (__m128i) __builtin_ia32_vpcomtrueud ((__v4si)__A, (__v4si)__B);
}
-/*pcom (integer, unsinged quad words) */
+/*pcom (integer, unsigned quad words) */
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_comlt_epu64(__m128i __A, __m128i __B)
diff --git a/gcc/config/ia64/ia64.c b/gcc/config/ia64/ia64.c
index 3fcc3b5385d..742123f401e 100644
--- a/gcc/config/ia64/ia64.c
+++ b/gcc/config/ia64/ia64.c
@@ -10624,8 +10624,6 @@ ia64_vms_init_libfuncs (void)
set_optab_libfunc (smod_optab, DImode, "OTS$REM_L");
set_optab_libfunc (umod_optab, SImode, "OTS$REM_UI");
set_optab_libfunc (umod_optab, DImode, "OTS$REM_UL");
- abort_libfunc = init_one_libfunc ("decc$abort");
- memcmp_libfunc = init_one_libfunc ("decc$memcmp");
#ifdef MEM_LIBFUNCS_INIT
MEM_LIBFUNCS_INIT;
#endif
diff --git a/gcc/config/mips/constraints.md b/gcc/config/mips/constraints.md
index 133e346a8fc..56b363e699b 100644
--- a/gcc/config/mips/constraints.md
+++ b/gcc/config/mips/constraints.md
@@ -308,6 +308,61 @@
"@internal"
(match_operand 0 "low_bitmask_operand"))
+(define_constraint "YI"
+ "@internal
+ A replicated vector const in which the replicated value is in the range
+ [-512,511]."
+ (and (match_code "const_vector")
+ (match_test "mips_const_vector_same_int_p (op, mode, -512, 511)")))
+
+(define_constraint "YC"
+ "@internal
+ A replicated vector const in which the replicated value has a single
+ bit set."
+ (and (match_code "const_vector")
+ (match_test "mips_const_vector_bitimm_set_p (op, mode)")))
+
+(define_constraint "YZ"
+ "@internal
+ A replicated vector const in which the replicated value has a single
+ bit clear."
+ (and (match_code "const_vector")
+ (match_test "mips_const_vector_bitimm_clr_p (op, mode)")))
+
+(define_constraint "Unv5"
+ "@internal
+ A replicated vector const in which the replicated value is in the range
+ [-31,0]."
+ (and (match_code "const_vector")
+ (match_test "mips_const_vector_same_int_p (op, mode, -31, 0)")))
+
+(define_constraint "Uuv5"
+ "@internal
+ A replicated vector const in which the replicated value is in the range
+ [0,31]."
+ (and (match_code "const_vector")
+ (match_test "mips_const_vector_same_int_p (op, mode, 0, 31)")))
+
+(define_constraint "Usv5"
+ "@internal
+ A replicated vector const in which the replicated value is in the range
+ [-16,15]."
+ (and (match_code "const_vector")
+ (match_test "mips_const_vector_same_int_p (op, mode, -16, 15)")))
+
+(define_constraint "Uuv6"
+ "@internal
+ A replicated vector const in which the replicated value is in the range
+ [0,63]."
+ (and (match_code "const_vector")
+ (match_test "mips_const_vector_same_int_p (op, mode, 0, 63)")))
+
+(define_constraint "Urv8"
+ "@internal
+ A replicated vector const with replicated byte values as well as elements"
+ (and (match_code "const_vector")
+ (match_test "mips_const_vector_same_bytes_p (op, mode)")))
+
(define_memory_constraint "ZC"
"A memory operand whose address is formed by a base register and offset
that is suitable for use in instructions with the same addressing mode
diff --git a/gcc/config/mips/i6400.md b/gcc/config/mips/i6400.md
index 0f8230d6426..99881a79353 100644
--- a/gcc/config/mips/i6400.md
+++ b/gcc/config/mips/i6400.md
@@ -26,10 +26,13 @@
(define_cpu_unit "i6400_control, i6400_ctu, i6400_alu0" "i6400_int_pipe")
;; Short FPU pipeline.
-(define_cpu_unit "i6400_fpu_short" "i6400_fpu_short_pipe")
+(define_cpu_unit "i6400_fpu_short, i6400_fpu_intadd, i6400_fpu_logic,
+ i6400_fpu_div, i6400_fpu_cmp, i6400_fpu_float,
+ i6400_fpu_store" "i6400_fpu_short_pipe")
;; Long FPU pipeline.
-(define_cpu_unit "i6400_fpu_long, i6400_fpu_apu" "i6400_fpu_long_pipe")
+(define_cpu_unit "i6400_fpu_long, i6400_fpu_logic_l, i6400_fpu_float_l,
+ i6400_fpu_mult, i6400_fpu_apu" "i6400_fpu_long_pipe")
(define_reservation "i6400_control_ctu" "i6400_control, i6400_ctu")
(define_reservation "i6400_control_alu0" "i6400_control, i6400_alu0")
@@ -37,6 +40,176 @@
(define_reservation "i6400_agen_alu1" "i6400_agen, i6400_alu1")
;;
+;; FPU-MSA pipe
+;;
+
+;; Short pipe
+
+;; addv, subv
+(define_insn_reservation "i6400_msa_add_d" 1
+ (and (eq_attr "cpu" "i6400")
+ (and (eq_attr "mode" "!V2DI")
+ (eq_attr "alu_type" "simd_add")))
+ "i6400_fpu_short, i6400_fpu_intadd")
+
+;; add, hadd, sub, hsub, average, min, max, compare
+(define_insn_reservation "i6400_msa_int_add" 2
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_int_arith"))
+ "i6400_fpu_short, i6400_fpu_intadd")
+
+;; sat, pcnt
+(define_insn_reservation "i6400_msa_short_logic3" 3
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_sat,simd_pcnt"))
+ "i6400_fpu_short, i6400_fpu_logic")
+
+;; shifts, nloc, nlzc, bneg, bclr, shf
+(define_insn_reservation "i6400_msa_short_logic2" 2
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_shift,simd_shf,simd_bit"))
+ "i6400_fpu_short, i6400_fpu_logic")
+
+;; and, or, xor, ilv, pck, fill, splat
+(define_insn_reservation "i6400_msa_short_logic" 1
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_permute,simd_logic,simd_splat,simd_fill"))
+ "i6400_fpu_short, i6400_fpu_logic")
+
+;; move.v, ldi
+(define_insn_reservation "i6400_msa_move" 1
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_move"))
+ "i6400_fpu_short, i6400_fpu_logic")
+
+;; Float compare New: CMP.cond.fmt
+(define_insn_reservation "i6400_msa_cmp" 2
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_fcmp"))
+ "i6400_fpu_short, i6400_fpu_cmp")
+
+;; Float min, max, class
+(define_insn_reservation "i6400_msa_short_float2" 2
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_fminmax,simd_fclass"))
+ "i6400_fpu_short, i6400_fpu_float")
+
+;; div.d, mod.d (non-pipelined)
+(define_insn_reservation "i6400_msa_div_d" 36
+ (and (eq_attr "cpu" "i6400")
+ (and (eq_attr "mode" "V2DI")
+ (eq_attr "type" "simd_div")))
+ "i6400_fpu_short+i6400_fpu_div*36")
+
+;; div.w, mod.w (non-pipelined)
+(define_insn_reservation "i6400_msa_div_w" 20
+ (and (eq_attr "cpu" "i6400")
+ (and (eq_attr "mode" "V4SI")
+ (eq_attr "type" "simd_div")))
+ "i6400_fpu_short+i6400_fpu_div*20")
+
+;; div.h, mod.h (non-pipelined)
+(define_insn_reservation "i6400_msa_div_h" 12
+ (and (eq_attr "cpu" "i6400")
+ (and (eq_attr "mode" "V8HI")
+ (eq_attr "type" "simd_div")))
+ "i6400_fpu_short+i6400_fpu_div*12")
+
+;; div.b, mod.b (non-pipelined)
+(define_insn_reservation "i6400_msa_div_b" 8
+ (and (eq_attr "cpu" "i6400")
+ (and (eq_attr "mode" "V16QI")
+ (eq_attr "type" "simd_div")))
+ "i6400_fpu_short+i6400_fpu_div*8")
+
+;; Vector copy
+(define_insn_reservation "i6400_msa_copy" 1
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_copy"))
+ "i6400_fpu_short, i6400_fpu_store")
+
+;; Vector bz, bnz
+(define_insn_reservation "i6400_msa_branch" 1
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_branch"))
+ "i6400_control_ctu")
+
+;; Vector store
+(define_insn_reservation "i6400_fpu_msa_store" 1
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_store"))
+ "i6400_agen_lsu")
+
+;; Vector load
+(define_insn_reservation "i6400_fpu_msa_load" 3
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_load"))
+ "i6400_agen_lsu")
+
+;; cfcmsa, ctcmsa
+(define_insn_reservation "i6400_fpu_msa_move" 1
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_cmsa"))
+ "i6400_control_alu0 | i6400_agen_alu1")
+
+;; Long pipe
+
+;; bmz, bmnz, bsel, insert, insve
+(define_insn_reservation "i6400_msa_long_logic1" 1
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_bitmov,simd_insert"))
+ "i6400_fpu_long, i6400_fpu_logic_l")
+
+;; binsl, binsr, vshf, sld
+(define_insn_reservation "i6400_msa_long_logic2" 2
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_bitins,simd_sld"))
+ "i6400_fpu_long, i6400_fpu_logic_l")
+
+;; Vector mul, dotp, madd, msub
+(define_insn_reservation "i6400_msa_mult" 5
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_mul"))
+ "i6400_fpu_long, i6400_fpu_mult")
+
+;; Float flog2
+(define_insn_reservation "i6400_msa_long_float2" 2
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_flog2"))
+ "i6400_fpu_long, i6400_fpu_float_l")
+
+;; fadd, fsub
+(define_insn_reservation "i6400_msa_long_float4" 4
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_fadd,simd_fcvt"))
+ "i6400_fpu_long, i6400_fpu_float_l")
+
+;; fmul, fexp2
+(define_insn_reservation "i6400_msa_long_float5" 5
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_fmul,simd_fexp2"))
+ "i6400_fpu_long, i6400_fpu_float_l")
+
+;; fmadd, fmsub
+(define_insn_reservation "i6400_msa_long_float8" 8
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_fmadd"))
+ "i6400_fpu_long, i6400_fpu_float_l")
+
+;; fdiv.d
+(define_insn_reservation "i6400_msa_fdiv_df" 30
+ (and (eq_attr "cpu" "i6400")
+ (and (eq_attr "mode" "V2DF")
+ (eq_attr "type" "simd_fdiv")))
+ "i6400_fpu_long+i6400_fpu_float_l*30")
+
+;; fdiv.w
+(define_insn_reservation "i6400_msa_fdiv_sf" 22
+ (and (eq_attr "cpu" "i6400")
+ (eq_attr "type" "simd_fdiv"))
+ "i6400_fpu_long+i6400_fpu_float_l*22")
+
+;;
;; FPU pipe
;;
diff --git a/gcc/config/mips/m5100.md b/gcc/config/mips/m5100.md
index f69fc7fc609..8d87b7087fc 100644
--- a/gcc/config/mips/m5100.md
+++ b/gcc/config/mips/m5100.md
@@ -65,7 +65,7 @@
;; loads: lb, lbu, lh, lhu, ll, lw, lwl, lwr, lwpc, lwxs
;; prefetch: prefetch, prefetchx
-(define_insn_reservation "m51_int_load" 3
+(define_insn_reservation "m51_int_load" 2
(and (eq_attr "cpu" "m5100")
(eq_attr "type" "load,prefetch,prefetchx"))
"m51_alu")
diff --git a/gcc/config/mips/mips-cpus.def b/gcc/config/mips/mips-cpus.def
index 17034f2ea95..b46c86f49c6 100644
--- a/gcc/config/mips/mips-cpus.def
+++ b/gcc/config/mips/mips-cpus.def
@@ -44,10 +44,7 @@ MIPS_CPU ("mips4", PROCESSOR_R10000, 4, 0)
isn't tuned to a specific processor. */
MIPS_CPU ("mips32", PROCESSOR_4KC, 32, PTF_AVOID_BRANCHLIKELY)
MIPS_CPU ("mips32r2", PROCESSOR_74KF2_1, 33, PTF_AVOID_BRANCHLIKELY)
-/* mips32r3 is micromips hense why it uses the M4K processor.
- mips32r5 should use the p5600 processor, but there is no definition
- for this yet, so in the short term we will use the same processor entry
- as mips32r2. */
+/* mips32r3 is micromips hense why it uses the M4K processor. */
MIPS_CPU ("mips32r3", PROCESSOR_M4K, 34, PTF_AVOID_BRANCHLIKELY)
MIPS_CPU ("mips32r5", PROCESSOR_P5600, 36, PTF_AVOID_BRANCHLIKELY)
MIPS_CPU ("mips32r6", PROCESSOR_I6400, 37, 0)
@@ -150,7 +147,8 @@ MIPS_CPU ("1004kf1_1", PROCESSOR_24KF1_1, 33, 0)
MIPS_CPU ("interaptiv", PROCESSOR_24KF2_1, 33, 0)
/* MIPS32 Release 5 processors. */
-MIPS_CPU ("p5600", PROCESSOR_P5600, 36, PTF_AVOID_BRANCHLIKELY)
+MIPS_CPU ("p5600", PROCESSOR_P5600, 36, (PTF_AVOID_BRANCHLIKELY
+ | PTF_AVOID_IMADD))
MIPS_CPU ("m5100", PROCESSOR_M5100, 36, PTF_AVOID_BRANCHLIKELY)
MIPS_CPU ("m5101", PROCESSOR_M5100, 36, PTF_AVOID_BRANCHLIKELY)
diff --git a/gcc/config/mips/mips-ftypes.def b/gcc/config/mips/mips-ftypes.def
index 7fe1c06eb00..69cf4379ed1 100644
--- a/gcc/config/mips/mips-ftypes.def
+++ b/gcc/config/mips/mips-ftypes.def
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
Please keep this list lexicographically sorted by the LIST argument. */
DEF_MIPS_FTYPE (1, (DF, DF))
DEF_MIPS_FTYPE (2, (DF, DF, DF))
+DEF_MIPS_FTYPE (1, (DF, V2DF))
DEF_MIPS_FTYPE (2, (DI, DI, DI))
DEF_MIPS_FTYPE (2, (DI, DI, SI))
@@ -45,6 +46,7 @@ DEF_MIPS_FTYPE (3, (DI, DI, V4QI, V4QI))
DEF_MIPS_FTYPE (2, (DI, POINTER, SI))
DEF_MIPS_FTYPE (2, (DI, SI, SI))
DEF_MIPS_FTYPE (2, (DI, USI, USI))
+DEF_MIPS_FTYPE (2, (DI, V2DI, UQI))
DEF_MIPS_FTYPE (2, (INT, DF, DF))
DEF_MIPS_FTYPE (2, (INT, SF, SF))
@@ -54,23 +56,51 @@ DEF_MIPS_FTYPE (4, (INT, V2SF, V2SF, V2SF, V2SF))
DEF_MIPS_FTYPE (1, (SF, SF))
DEF_MIPS_FTYPE (2, (SF, SF, SF))
DEF_MIPS_FTYPE (1, (SF, V2SF))
+DEF_MIPS_FTYPE (1, (SF, V4SF))
DEF_MIPS_FTYPE (2, (SI, DI, SI))
DEF_MIPS_FTYPE (2, (SI, POINTER, SI))
DEF_MIPS_FTYPE (1, (SI, SI))
DEF_MIPS_FTYPE (2, (SI, SI, SI))
DEF_MIPS_FTYPE (3, (SI, SI, SI, SI))
+DEF_MIPS_FTYPE (1, (SI, UQI))
+DEF_MIPS_FTYPE (1, (SI, UV16QI))
+DEF_MIPS_FTYPE (1, (SI, UV2DI))
+DEF_MIPS_FTYPE (1, (SI, UV4SI))
+DEF_MIPS_FTYPE (1, (SI, UV8HI))
+DEF_MIPS_FTYPE (2, (SI, V16QI, UQI))
DEF_MIPS_FTYPE (1, (SI, V2HI))
DEF_MIPS_FTYPE (2, (SI, V2HI, V2HI))
DEF_MIPS_FTYPE (1, (SI, V4QI))
DEF_MIPS_FTYPE (2, (SI, V4QI, V4QI))
+DEF_MIPS_FTYPE (2, (SI, V4SI, UQI))
+DEF_MIPS_FTYPE (2, (SI, V8HI, UQI))
DEF_MIPS_FTYPE (1, (SI, VOID))
DEF_MIPS_FTYPE (2, (UDI, UDI, UDI))
DEF_MIPS_FTYPE (2, (UDI, UV2SI, UV2SI))
+DEF_MIPS_FTYPE (2, (UDI, V2DI, UQI))
+DEF_MIPS_FTYPE (2, (USI, V16QI, UQI))
+DEF_MIPS_FTYPE (2, (USI, V4SI, UQI))
+DEF_MIPS_FTYPE (2, (USI, V8HI, UQI))
DEF_MIPS_FTYPE (1, (USI, VOID))
+DEF_MIPS_FTYPE (2, (UV16QI, UV16QI, UQI))
+DEF_MIPS_FTYPE (2, (UV16QI, UV16QI, UV16QI))
+DEF_MIPS_FTYPE (3, (UV16QI, UV16QI, UV16QI, UQI))
+DEF_MIPS_FTYPE (3, (UV16QI, UV16QI, UV16QI, UV16QI))
+DEF_MIPS_FTYPE (2, (UV16QI, UV16QI, V16QI))
+
+DEF_MIPS_FTYPE (2, (UV2DI, UV2DI, UQI))
+DEF_MIPS_FTYPE (2, (UV2DI, UV2DI, UV2DI))
+DEF_MIPS_FTYPE (3, (UV2DI, UV2DI, UV2DI, UQI))
+DEF_MIPS_FTYPE (3, (UV2DI, UV2DI, UV2DI, UV2DI))
+DEF_MIPS_FTYPE (3, (UV2DI, UV2DI, UV4SI, UV4SI))
+DEF_MIPS_FTYPE (2, (UV2DI, UV2DI, V2DI))
+DEF_MIPS_FTYPE (2, (UV2DI, UV4SI, UV4SI))
+DEF_MIPS_FTYPE (1, (UV2DI, V2DF))
+
DEF_MIPS_FTYPE (2, (UV2SI, UV2SI, UQI))
DEF_MIPS_FTYPE (2, (UV2SI, UV2SI, UV2SI))
@@ -82,10 +112,75 @@ DEF_MIPS_FTYPE (3, (UV4HI, UV4HI, UV4HI, USI))
DEF_MIPS_FTYPE (1, (UV4HI, UV8QI))
DEF_MIPS_FTYPE (2, (UV4HI, UV8QI, UV8QI))
+DEF_MIPS_FTYPE (2, (UV4SI, UV4SI, UQI))
+DEF_MIPS_FTYPE (2, (UV4SI, UV4SI, UV4SI))
+DEF_MIPS_FTYPE (3, (UV4SI, UV4SI, UV4SI, UQI))
+DEF_MIPS_FTYPE (3, (UV4SI, UV4SI, UV4SI, UV4SI))
+DEF_MIPS_FTYPE (3, (UV4SI, UV4SI, UV8HI, UV8HI))
+DEF_MIPS_FTYPE (2, (UV4SI, UV4SI, V4SI))
+DEF_MIPS_FTYPE (2, (UV4SI, UV8HI, UV8HI))
+DEF_MIPS_FTYPE (1, (UV4SI, V4SF))
+
+DEF_MIPS_FTYPE (2, (UV8HI, UV16QI, UV16QI))
+DEF_MIPS_FTYPE (2, (UV8HI, UV8HI, UQI))
+DEF_MIPS_FTYPE (3, (UV8HI, UV8HI, UV16QI, UV16QI))
+DEF_MIPS_FTYPE (2, (UV8HI, UV8HI, UV8HI))
+DEF_MIPS_FTYPE (3, (UV8HI, UV8HI, UV8HI, UQI))
+DEF_MIPS_FTYPE (3, (UV8HI, UV8HI, UV8HI, UV8HI))
+DEF_MIPS_FTYPE (2, (UV8HI, UV8HI, V8HI))
+
DEF_MIPS_FTYPE (2, (UV8QI, UV4HI, UV4HI))
DEF_MIPS_FTYPE (1, (UV8QI, UV8QI))
DEF_MIPS_FTYPE (2, (UV8QI, UV8QI, UV8QI))
+DEF_MIPS_FTYPE (2, (V16QI, CVPOINTER, SI))
+DEF_MIPS_FTYPE (1, (V16QI, HI))
+DEF_MIPS_FTYPE (1, (V16QI, SI))
+DEF_MIPS_FTYPE (2, (V16QI, UV16QI, UQI))
+DEF_MIPS_FTYPE (2, (V16QI, UV16QI, UV16QI))
+DEF_MIPS_FTYPE (1, (V16QI, V16QI))
+DEF_MIPS_FTYPE (2, (V16QI, V16QI, QI))
+DEF_MIPS_FTYPE (2, (V16QI, V16QI, SI))
+DEF_MIPS_FTYPE (2, (V16QI, V16QI, UQI))
+DEF_MIPS_FTYPE (3, (V16QI, V16QI, UQI, SI))
+DEF_MIPS_FTYPE (3, (V16QI, V16QI, UQI, V16QI))
+DEF_MIPS_FTYPE (2, (V16QI, V16QI, V16QI))
+DEF_MIPS_FTYPE (3, (V16QI, V16QI, V16QI, SI))
+DEF_MIPS_FTYPE (3, (V16QI, V16QI, V16QI, UQI))
+DEF_MIPS_FTYPE (3, (V16QI, V16QI, V16QI, V16QI))
+
+DEF_MIPS_FTYPE (1, (V2DF, DF))
+DEF_MIPS_FTYPE (1, (V2DF, UV2DI))
+DEF_MIPS_FTYPE (1, (V2DF, V2DF))
+DEF_MIPS_FTYPE (2, (V2DF, V2DF, V2DF))
+DEF_MIPS_FTYPE (3, (V2DF, V2DF, V2DF, V2DF))
+DEF_MIPS_FTYPE (2, (V2DF, V2DF, V2DI))
+DEF_MIPS_FTYPE (1, (V2DF, V2DI))
+DEF_MIPS_FTYPE (1, (V2DF, V4SF))
+DEF_MIPS_FTYPE (1, (V2DF, V4SI))
+
+DEF_MIPS_FTYPE (2, (V2DI, CVPOINTER, SI))
+DEF_MIPS_FTYPE (1, (V2DI, DI))
+DEF_MIPS_FTYPE (1, (V2DI, HI))
+DEF_MIPS_FTYPE (2, (V2DI, UV2DI, UQI))
+DEF_MIPS_FTYPE (2, (V2DI, UV2DI, UV2DI))
+DEF_MIPS_FTYPE (2, (V2DI, UV4SI, UV4SI))
+DEF_MIPS_FTYPE (1, (V2DI, V2DF))
+DEF_MIPS_FTYPE (2, (V2DI, V2DF, V2DF))
+DEF_MIPS_FTYPE (1, (V2DI, V2DI))
+DEF_MIPS_FTYPE (2, (V2DI, V2DI, QI))
+DEF_MIPS_FTYPE (2, (V2DI, V2DI, SI))
+DEF_MIPS_FTYPE (2, (V2DI, V2DI, UQI))
+DEF_MIPS_FTYPE (3, (V2DI, V2DI, UQI, DI))
+DEF_MIPS_FTYPE (3, (V2DI, V2DI, UQI, V2DI))
+DEF_MIPS_FTYPE (3, (V2DI, V2DI, UV4SI, UV4SI))
+DEF_MIPS_FTYPE (2, (V2DI, V2DI, V2DI))
+DEF_MIPS_FTYPE (3, (V2DI, V2DI, V2DI, SI))
+DEF_MIPS_FTYPE (3, (V2DI, V2DI, V2DI, UQI))
+DEF_MIPS_FTYPE (3, (V2DI, V2DI, V2DI, V2DI))
+DEF_MIPS_FTYPE (3, (V2DI, V2DI, V4SI, V4SI))
+DEF_MIPS_FTYPE (2, (V2DI, V4SI, V4SI))
+
DEF_MIPS_FTYPE (1, (V2HI, SI))
DEF_MIPS_FTYPE (2, (V2HI, SI, SI))
DEF_MIPS_FTYPE (3, (V2HI, SI, SI, SI))
@@ -118,12 +213,74 @@ DEF_MIPS_FTYPE (1, (V4QI, V4QI))
DEF_MIPS_FTYPE (2, (V4QI, V4QI, SI))
DEF_MIPS_FTYPE (2, (V4QI, V4QI, V4QI))
+DEF_MIPS_FTYPE (1, (V4SF, SF))
+DEF_MIPS_FTYPE (1, (V4SF, UV4SI))
+DEF_MIPS_FTYPE (2, (V4SF, V2DF, V2DF))
+DEF_MIPS_FTYPE (1, (V4SF, V4SF))
+DEF_MIPS_FTYPE (2, (V4SF, V4SF, V4SF))
+DEF_MIPS_FTYPE (3, (V4SF, V4SF, V4SF, V4SF))
+DEF_MIPS_FTYPE (2, (V4SF, V4SF, V4SI))
+DEF_MIPS_FTYPE (1, (V4SF, V4SI))
+DEF_MIPS_FTYPE (1, (V4SF, V8HI))
+
+DEF_MIPS_FTYPE (2, (V4SI, CVPOINTER, SI))
+DEF_MIPS_FTYPE (1, (V4SI, HI))
+DEF_MIPS_FTYPE (1, (V4SI, SI))
+DEF_MIPS_FTYPE (2, (V4SI, UV4SI, UQI))
+DEF_MIPS_FTYPE (2, (V4SI, UV4SI, UV4SI))
+DEF_MIPS_FTYPE (2, (V4SI, UV8HI, UV8HI))
+DEF_MIPS_FTYPE (2, (V4SI, V2DF, V2DF))
+DEF_MIPS_FTYPE (1, (V4SI, V4SF))
+DEF_MIPS_FTYPE (2, (V4SI, V4SF, V4SF))
+DEF_MIPS_FTYPE (1, (V4SI, V4SI))
+DEF_MIPS_FTYPE (2, (V4SI, V4SI, QI))
+DEF_MIPS_FTYPE (2, (V4SI, V4SI, SI))
+DEF_MIPS_FTYPE (2, (V4SI, V4SI, UQI))
+DEF_MIPS_FTYPE (3, (V4SI, V4SI, UQI, SI))
+DEF_MIPS_FTYPE (3, (V4SI, V4SI, UQI, V4SI))
+DEF_MIPS_FTYPE (3, (V4SI, V4SI, UV8HI, UV8HI))
+DEF_MIPS_FTYPE (2, (V4SI, V4SI, V4SI))
+DEF_MIPS_FTYPE (3, (V4SI, V4SI, V4SI, SI))
+DEF_MIPS_FTYPE (3, (V4SI, V4SI, V4SI, UQI))
+DEF_MIPS_FTYPE (3, (V4SI, V4SI, V4SI, V4SI))
+DEF_MIPS_FTYPE (3, (V4SI, V4SI, V8HI, V8HI))
+DEF_MIPS_FTYPE (2, (V4SI, V8HI, V8HI))
+
+DEF_MIPS_FTYPE (2, (V8HI, CVPOINTER, SI))
+DEF_MIPS_FTYPE (1, (V8HI, HI))
+DEF_MIPS_FTYPE (1, (V8HI, SI))
+DEF_MIPS_FTYPE (2, (V8HI, UV16QI, UV16QI))
+DEF_MIPS_FTYPE (2, (V8HI, UV8HI, UQI))
+DEF_MIPS_FTYPE (2, (V8HI, UV8HI, UV8HI))
+DEF_MIPS_FTYPE (2, (V8HI, V16QI, V16QI))
+DEF_MIPS_FTYPE (2, (V8HI, V4SF, V4SF))
+DEF_MIPS_FTYPE (1, (V8HI, V8HI))
+DEF_MIPS_FTYPE (2, (V8HI, V8HI, QI))
+DEF_MIPS_FTYPE (2, (V8HI, V8HI, SI))
+DEF_MIPS_FTYPE (3, (V8HI, V8HI, SI, UQI))
+DEF_MIPS_FTYPE (2, (V8HI, V8HI, UQI))
+DEF_MIPS_FTYPE (3, (V8HI, V8HI, UQI, SI))
+DEF_MIPS_FTYPE (3, (V8HI, V8HI, UQI, V8HI))
+DEF_MIPS_FTYPE (3, (V8HI, V8HI, UV16QI, UV16QI))
+DEF_MIPS_FTYPE (3, (V8HI, V8HI, V16QI, V16QI))
+DEF_MIPS_FTYPE (2, (V8HI, V8HI, V8HI))
+DEF_MIPS_FTYPE (3, (V8HI, V8HI, V8HI, SI))
+DEF_MIPS_FTYPE (3, (V8HI, V8HI, V8HI, UQI))
+DEF_MIPS_FTYPE (3, (V8HI, V8HI, V8HI, V8HI))
+
DEF_MIPS_FTYPE (2, (V8QI, V4HI, V4HI))
DEF_MIPS_FTYPE (1, (V8QI, V8QI))
DEF_MIPS_FTYPE (2, (V8QI, V8QI, V8QI))
DEF_MIPS_FTYPE (2, (VOID, SI, CVPOINTER))
DEF_MIPS_FTYPE (2, (VOID, SI, SI))
+DEF_MIPS_FTYPE (2, (VOID, UQI, SI))
DEF_MIPS_FTYPE (1, (VOID, USI))
+DEF_MIPS_FTYPE (3, (VOID, V16QI, CVPOINTER, SI))
+DEF_MIPS_FTYPE (3, (VOID, V2DF, POINTER, SI))
+DEF_MIPS_FTYPE (3, (VOID, V2DI, CVPOINTER, SI))
DEF_MIPS_FTYPE (2, (VOID, V2HI, V2HI))
DEF_MIPS_FTYPE (2, (VOID, V4QI, V4QI))
+DEF_MIPS_FTYPE (3, (VOID, V4SF, POINTER, SI))
+DEF_MIPS_FTYPE (3, (VOID, V4SI, CVPOINTER, SI))
+DEF_MIPS_FTYPE (3, (VOID, V8HI, CVPOINTER, SI))
diff --git a/gcc/config/mips/mips-modes.def b/gcc/config/mips/mips-modes.def
index 08d713243d9..b21f5d16c95 100644
--- a/gcc/config/mips/mips-modes.def
+++ b/gcc/config/mips/mips-modes.def
@@ -24,11 +24,17 @@ VECTOR_MODES (INT, 4); /* V4QI V2HI */
VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
+/* For MIPS MSA 128 bits. */
+VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
+VECTOR_MODES (FLOAT, 16); /* V4SF V2DF */
+
/* Double-sized vector modes for vec_concat. */
-VECTOR_MODE (INT, QI, 16); /* V16QI */
-VECTOR_MODE (INT, HI, 8); /* V8HI */
-VECTOR_MODE (INT, SI, 4); /* V4SI */
-VECTOR_MODE (FLOAT, SF, 4); /* V4SF */
+VECTOR_MODE (INT, QI, 32); /* V32QI */
+VECTOR_MODE (INT, HI, 16); /* V16HI */
+VECTOR_MODE (INT, SI, 8); /* V8SI */
+VECTOR_MODE (INT, DI, 4); /* V4DI */
+VECTOR_MODE (FLOAT, SF, 8); /* V8SF */
+VECTOR_MODE (FLOAT, DF, 4); /* V4DF */
VECTOR_MODES (FRACT, 4); /* V4QQ V2HQ */
VECTOR_MODES (UFRACT, 4); /* V4UQQ V2UHQ */
diff --git a/gcc/config/mips/mips-msa.md b/gcc/config/mips/mips-msa.md
new file mode 100644
index 00000000000..1082856dd98
--- /dev/null
+++ b/gcc/config/mips/mips-msa.md
@@ -0,0 +1,2736 @@
+;; Machine Description for MIPS MSA ASE
+;; Based on the MIPS MSA spec Revision 1.11 8/4/2014
+;;
+;; Copyright (C) 2015 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3. If not see
+;; <http://www.gnu.org/licenses/>.
+;;
+
+(define_c_enum "unspec" [
+ UNSPEC_MSA_ASUB_S
+ UNSPEC_MSA_ASUB_U
+ UNSPEC_MSA_AVE_S
+ UNSPEC_MSA_AVE_U
+ UNSPEC_MSA_AVER_S
+ UNSPEC_MSA_AVER_U
+ UNSPEC_MSA_BCLR
+ UNSPEC_MSA_BCLRI
+ UNSPEC_MSA_BINSL
+ UNSPEC_MSA_BINSLI
+ UNSPEC_MSA_BINSR
+ UNSPEC_MSA_BINSRI
+ UNSPEC_MSA_BNEG
+ UNSPEC_MSA_BNEGI
+ UNSPEC_MSA_BSET
+ UNSPEC_MSA_BSETI
+ UNSPEC_MSA_BRANCH_V
+ UNSPEC_MSA_BRANCH
+ UNSPEC_MSA_CFCMSA
+ UNSPEC_MSA_CTCMSA
+ UNSPEC_MSA_FCAF
+ UNSPEC_MSA_FCLASS
+ UNSPEC_MSA_FCUNE
+ UNSPEC_MSA_FEXDO
+ UNSPEC_MSA_FEXP2
+ UNSPEC_MSA_FEXUPL
+ UNSPEC_MSA_FEXUPR
+ UNSPEC_MSA_FFQL
+ UNSPEC_MSA_FFQR
+ UNSPEC_MSA_FLOG2
+ UNSPEC_MSA_FRCP
+ UNSPEC_MSA_FRINT
+ UNSPEC_MSA_FRSQRT
+ UNSPEC_MSA_FSAF
+ UNSPEC_MSA_FSEQ
+ UNSPEC_MSA_FSLE
+ UNSPEC_MSA_FSLT
+ UNSPEC_MSA_FSNE
+ UNSPEC_MSA_FSOR
+ UNSPEC_MSA_FSUEQ
+ UNSPEC_MSA_FSULE
+ UNSPEC_MSA_FSULT
+ UNSPEC_MSA_FSUN
+ UNSPEC_MSA_FSUNE
+ UNSPEC_MSA_FTINT_S
+ UNSPEC_MSA_FTINT_U
+ UNSPEC_MSA_FTQ
+ UNSPEC_MSA_MADD_Q
+ UNSPEC_MSA_MADDR_Q
+ UNSPEC_MSA_MSUB_Q
+ UNSPEC_MSA_MSUBR_Q
+ UNSPEC_MSA_MUL_Q
+ UNSPEC_MSA_MULR_Q
+ UNSPEC_MSA_NLOC
+ UNSPEC_MSA_SAT_S
+ UNSPEC_MSA_SAT_U
+ UNSPEC_MSA_SLD
+ UNSPEC_MSA_SLDI
+ UNSPEC_MSA_SPLAT
+ UNSPEC_MSA_SPLATI
+ UNSPEC_MSA_SRAR
+ UNSPEC_MSA_SRARI
+ UNSPEC_MSA_SRLR
+ UNSPEC_MSA_SRLRI
+ UNSPEC_MSA_SUBS_S
+ UNSPEC_MSA_SUBS_U
+ UNSPEC_MSA_SUBSUU_S
+ UNSPEC_MSA_SUBSUS_U
+ UNSPEC_MSA_VSHF
+])
+
+;; All vector modes with 128 bits.
+(define_mode_iterator MSA [V2DF V4SF V2DI V4SI V8HI V16QI])
+
+;; Same as MSA. Used by vcond to iterate two modes.
+(define_mode_iterator MSA_2 [V2DF V4SF V2DI V4SI V8HI V16QI])
+
+;; Only used for splitting insert_d and copy_{u,s}.d.
+(define_mode_iterator MSA_D [V2DI V2DF])
+
+;; Only used for copy_{u,s}.w.
+(define_mode_iterator MSA_W [V4SI V4SF])
+
+;; Only integer modes.
+(define_mode_iterator IMSA [V2DI V4SI V8HI V16QI])
+
+;; As IMSA but excludes V16QI.
+(define_mode_iterator IMSA_DWH [V2DI V4SI V8HI])
+
+;; As IMSA but excludes V2DI.
+(define_mode_iterator IMSA_WHB [V4SI V8HI V16QI])
+
+;; Only integer modes equal or larger than a word.
+(define_mode_iterator IMSA_DW [V2DI V4SI])
+
+;; Only integer modes smaller than a word.
+(define_mode_iterator IMSA_HB [V8HI V16QI])
+
+;; Only integer modes for fixed-point madd_q/maddr_q.
+(define_mode_iterator IMSA_WH [V4SI V8HI])
+
+;; Only floating-point modes.
+(define_mode_iterator FMSA [V2DF V4SF])
+
+;; Only used for immediate set shuffle elements instruction.
+(define_mode_iterator MSA_WHB_W [V4SI V8HI V16QI V4SF])
+
+;; The attribute gives the integer vector mode with same size.
+(define_mode_attr VIMODE
+ [(V2DF "V2DI")
+ (V4SF "V4SI")
+ (V2DI "V2DI")
+ (V4SI "V4SI")
+ (V8HI "V8HI")
+ (V16QI "V16QI")])
+
+;; The attribute gives half modes for vector modes.
+(define_mode_attr VHMODE
+ [(V8HI "V16QI")
+ (V4SI "V8HI")
+ (V2DI "V4SI")])
+
+;; The attribute gives double modes for vector modes.
+(define_mode_attr VDMODE
+ [(V4SI "V2DI")
+ (V8HI "V4SI")
+ (V16QI "V8HI")])
+
+;; The attribute gives half modes with same number of elements for vector modes.
+(define_mode_attr VTRUNCMODE
+ [(V8HI "V8QI")
+ (V4SI "V4HI")
+ (V2DI "V2SI")])
+
+;; This attribute gives the mode of the result for "copy_s_b, copy_u_b" etc.
+(define_mode_attr VRES
+ [(V2DF "DF")
+ (V4SF "SF")
+ (V2DI "DI")
+ (V4SI "SI")
+ (V8HI "SI")
+ (V16QI "SI")])
+
+;; Only used with MSA_D iterator.
+(define_mode_attr msa_d
+ [(V2DI "reg_or_0")
+ (V2DF "register")])
+
+;; This attribute gives the integer vector mode with same size.
+(define_mode_attr mode_i
+ [(V2DF "v2di")
+ (V4SF "v4si")
+ (V2DI "v2di")
+ (V4SI "v4si")
+ (V8HI "v8hi")
+ (V16QI "v16qi")])
+
+;; This attribute gives suffix for MSA instructions.
+(define_mode_attr msafmt
+ [(V2DF "d")
+ (V4SF "w")
+ (V2DI "d")
+ (V4SI "w")
+ (V8HI "h")
+ (V16QI "b")])
+
+;; This attribute gives suffix for integers in VHMODE.
+(define_mode_attr hmsafmt
+ [(V2DI "w")
+ (V4SI "h")
+ (V8HI "b")])
+
+;; This attribute gives define_insn suffix for MSA instructions that need
+;; distinction between integer and floating point.
+(define_mode_attr msafmt_f
+ [(V2DF "d_f")
+ (V4SF "w_f")
+ (V2DI "d")
+ (V4SI "w")
+ (V8HI "h")
+ (V16QI "b")])
+
+;; This is used to form an immediate operand constraint using
+;; "const_<indeximm>_operand".
+(define_mode_attr indeximm
+ [(V2DF "0_or_1")
+ (V4SF "0_to_3")
+ (V2DI "0_or_1")
+ (V4SI "0_to_3")
+ (V8HI "uimm3")
+ (V16QI "uimm4")])
+
+;; This attribute represents bitmask needed for vec_merge using
+;; "const_<bitmask>_operand".
+(define_mode_attr bitmask
+ [(V2DF "exp_2")
+ (V4SF "exp_4")
+ (V2DI "exp_2")
+ (V4SI "exp_4")
+ (V8HI "exp_8")
+ (V16QI "exp_16")])
+
+;; This attribute is used to form an immediate operand constraint using
+;; "const_<bitimm>_operand".
+(define_mode_attr bitimm
+ [(V16QI "uimm3")
+ (V8HI "uimm4")
+ (V4SI "uimm5")
+ (V2DI "uimm6")])
+
+(define_expand "vec_init<mode>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand:MSA 1 "")]
+ "ISA_HAS_MSA"
+{
+ mips_expand_vector_init (operands[0], operands[1]);
+ DONE;
+})
+
+;; pckev pattern with implicit type conversion.
+(define_insn "vec_pack_trunc_<mode>"
+ [(set (match_operand:<VHMODE> 0 "register_operand" "=f")
+ (vec_concat:<VHMODE>
+ (truncate:<VTRUNCMODE>
+ (match_operand:IMSA_DWH 1 "register_operand" "f"))
+ (truncate:<VTRUNCMODE>
+ (match_operand:IMSA_DWH 2 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "pckev.<hmsafmt>\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "vec_unpacks_hi_v4sf"
+ [(set (match_operand:V2DF 0 "register_operand" "=f")
+ (float_extend:V2DF
+ (vec_select:V2SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (match_dup 2))))]
+ "ISA_HAS_MSA"
+{
+ operands[2] = mips_msa_vec_parallel_const_half (V4SFmode, true/*high_p*/);
+})
+
+(define_expand "vec_unpacks_lo_v4sf"
+ [(set (match_operand:V2DF 0 "register_operand" "=f")
+ (float_extend:V2DF
+ (vec_select:V2SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (match_dup 2))))]
+ "ISA_HAS_MSA"
+{
+ operands[2] = mips_msa_vec_parallel_const_half (V4SFmode, false/*high_p*/);
+})
+
+(define_expand "vec_unpacks_hi_<mode>"
+ [(match_operand:<VDMODE> 0 "register_operand")
+ (match_operand:IMSA_WHB 1 "register_operand")]
+ "ISA_HAS_MSA"
+{
+ mips_expand_vec_unpack (operands, false/*unsigned_p*/, true/*high_p*/);
+ DONE;
+})
+
+(define_expand "vec_unpacks_lo_<mode>"
+ [(match_operand:<VDMODE> 0 "register_operand")
+ (match_operand:IMSA_WHB 1 "register_operand")]
+ "ISA_HAS_MSA"
+{
+ mips_expand_vec_unpack (operands, false/*unsigned_p*/, false/*high_p*/);
+ DONE;
+})
+
+(define_expand "vec_unpacku_hi_<mode>"
+ [(match_operand:<VDMODE> 0 "register_operand")
+ (match_operand:IMSA_WHB 1 "register_operand")]
+ "ISA_HAS_MSA"
+{
+ mips_expand_vec_unpack (operands, true/*unsigned_p*/, true/*high_p*/);
+ DONE;
+})
+
+(define_expand "vec_unpacku_lo_<mode>"
+ [(match_operand:<VDMODE> 0 "register_operand")
+ (match_operand:IMSA_WHB 1 "register_operand")]
+ "ISA_HAS_MSA"
+{
+ mips_expand_vec_unpack (operands, true/*unsigned_p*/, false/*high_p*/);
+ DONE;
+})
+
+(define_expand "vec_extract<mode>"
+ [(match_operand:<UNITMODE> 0 "register_operand")
+ (match_operand:IMSA 1 "register_operand")
+ (match_operand 2 "const_<indeximm>_operand")]
+ "ISA_HAS_MSA"
+{
+ if (<UNITMODE>mode == QImode || <UNITMODE>mode == HImode)
+ {
+ rtx dest1 = gen_reg_rtx (SImode);
+ emit_insn (gen_msa_copy_s_<msafmt> (dest1, operands[1], operands[2]));
+ emit_move_insn (operands[0],
+ gen_lowpart (<UNITMODE>mode, dest1));
+ }
+ else
+ emit_insn (gen_msa_copy_s_<msafmt> (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_expand "vec_extract<mode>"
+ [(match_operand:<UNITMODE> 0 "register_operand")
+ (match_operand:FMSA 1 "register_operand")
+ (match_operand 2 "const_<indeximm>_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx temp;
+ HOST_WIDE_INT val = INTVAL (operands[2]);
+
+ if (val == 0)
+ temp = operands[1];
+ else
+ {
+ /* We need to do the SLDI operation in V16QImode and adjust
+ operands[2] accordingly. */
+ rtx wd = gen_reg_rtx (V16QImode);
+ rtx ws = gen_reg_rtx (V16QImode);
+ emit_move_insn (ws, gen_rtx_SUBREG (V16QImode, operands[1], 0));
+ rtx n = GEN_INT (val * GET_MODE_SIZE (<UNITMODE>mode));
+ gcc_assert (INTVAL (n) < GET_MODE_NUNITS (V16QImode));
+ emit_insn (gen_msa_sldi_b (wd, ws, ws, n));
+ temp = gen_reg_rtx (<MODE>mode);
+ emit_move_insn (temp, gen_rtx_SUBREG (<MODE>mode, wd, 0));
+ }
+ emit_insn (gen_msa_vec_extract_<msafmt_f> (operands[0], temp));
+ DONE;
+})
+
+(define_insn_and_split "msa_vec_extract_<msafmt_f>"
+ [(set (match_operand:<UNITMODE> 0 "register_operand" "=f")
+ (vec_select:<UNITMODE>
+ (match_operand:FMSA 1 "register_operand" "f")
+ (parallel [(const_int 0)])))]
+ "ISA_HAS_MSA"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 1))]
+ "operands[1] = gen_rtx_REG (<UNITMODE>mode, REGNO (operands[1]));"
+ [(set_attr "move_type" "fmove")
+ (set_attr "mode" "<UNITMODE>")])
+
+(define_expand "vec_set<mode>"
+ [(match_operand:IMSA 0 "register_operand")
+ (match_operand:<UNITMODE> 1 "reg_or_0_operand")
+ (match_operand 2 "const_<indeximm>_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx index = GEN_INT (1 << INTVAL (operands[2]));
+ emit_insn (gen_msa_insert_<msafmt> (operands[0], operands[1],
+ operands[0], index));
+ DONE;
+})
+
+(define_expand "vec_set<mode>"
+ [(match_operand:FMSA 0 "register_operand")
+ (match_operand:<UNITMODE> 1 "register_operand")
+ (match_operand 2 "const_<indeximm>_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx index = GEN_INT (1 << INTVAL (operands[2]));
+ emit_insn (gen_msa_insve_<msafmt_f>_scalar (operands[0], operands[1],
+ operands[0], index));
+ DONE;
+})
+
+(define_expand "vcondu<MSA:mode><IMSA:mode>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand:MSA 1 "reg_or_m1_operand")
+ (match_operand:MSA 2 "reg_or_0_operand")
+ (match_operator 3 ""
+ [(match_operand:IMSA 4 "register_operand")
+ (match_operand:IMSA 5 "register_operand")])]
+ "ISA_HAS_MSA
+ && (GET_MODE_NUNITS (<MSA:MODE>mode) == GET_MODE_NUNITS (<IMSA:MODE>mode))"
+{
+ mips_expand_vec_cond_expr (<MSA:MODE>mode, <MSA:VIMODE>mode, operands);
+ DONE;
+})
+
+(define_expand "vcond<MSA:mode><MSA_2:mode>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand:MSA 1 "reg_or_m1_operand")
+ (match_operand:MSA 2 "reg_or_0_operand")
+ (match_operator 3 ""
+ [(match_operand:MSA_2 4 "register_operand")
+ (match_operand:MSA_2 5 "register_operand")])]
+ "ISA_HAS_MSA
+ && (GET_MODE_NUNITS (<MSA:MODE>mode) == GET_MODE_NUNITS (<MSA_2:MODE>mode))"
+{
+ mips_expand_vec_cond_expr (<MSA:MODE>mode, <MSA:VIMODE>mode, operands);
+ DONE;
+})
+
+(define_insn "msa_insert_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (vec_merge:MSA
+ (vec_duplicate:MSA
+ (match_operand:<UNITMODE> 1 "reg_or_0_operand" "dJ"))
+ (match_operand:MSA 2 "register_operand" "0")
+ (match_operand 3 "const_<bitmask>_operand" "")))]
+ "ISA_HAS_MSA"
+{
+ if (!TARGET_64BIT && (<MODE>mode == V2DImode || <MODE>mode == V2DFmode))
+ return "#";
+ else
+ return "insert.<msafmt>\t%w0[%y3],%z1";
+}
+ [(set_attr "type" "simd_insert")
+ (set_attr "mode" "<MODE>")])
+
+(define_split
+ [(set (match_operand:MSA_D 0 "register_operand")
+ (vec_merge:MSA_D
+ (vec_duplicate:MSA_D
+ (match_operand:<UNITMODE> 1 "<MSA_D:msa_d>_operand"))
+ (match_operand:MSA_D 2 "register_operand")
+ (match_operand 3 "const_<bitmask>_operand")))]
+ "reload_completed && ISA_HAS_MSA && !TARGET_64BIT"
+ [(const_int 0)]
+{
+ mips_split_msa_insert_d (operands[0], operands[2], operands[3], operands[1]);
+ DONE;
+})
+
+(define_insn "msa_insve_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (vec_merge:MSA
+ (vec_duplicate:MSA
+ (vec_select:<UNITMODE>
+ (match_operand:MSA 1 "register_operand" "f")
+ (parallel [(const_int 0)])))
+ (match_operand:MSA 2 "register_operand" "0")
+ (match_operand 3 "const_<bitmask>_operand" "")))]
+ "ISA_HAS_MSA"
+ "insve.<msafmt>\t%w0[%y3],%w1[0]"
+ [(set_attr "type" "simd_insert")
+ (set_attr "mode" "<MODE>")])
+
+;; Operand 3 is a scalar.
+(define_insn "msa_insve_<msafmt_f>_scalar"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (vec_merge:FMSA
+ (vec_duplicate:FMSA
+ (match_operand:<UNITMODE> 1 "register_operand" "f"))
+ (match_operand:FMSA 2 "register_operand" "0")
+ (match_operand 3 "const_<bitmask>_operand" "")))]
+ "ISA_HAS_MSA"
+ "insve.<msafmt>\t%w0[%y3],%w1[0]"
+ [(set_attr "type" "simd_insert")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_copy_<su>_<msafmt>"
+ [(set (match_operand:<VRES> 0 "register_operand" "=d")
+ (any_extend:<VRES>
+ (vec_select:<UNITMODE>
+ (match_operand:IMSA_HB 1 "register_operand" "f")
+ (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
+ "ISA_HAS_MSA"
+ "copy_<su>.<msafmt>\t%0,%w1[%2]"
+ [(set_attr "type" "simd_copy")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_copy_u_w"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (zero_extend:DI
+ (vec_select:SI
+ (match_operand:V4SI 1 "register_operand" "f")
+ (parallel [(match_operand 2 "const_0_to_3_operand" "")]))))]
+ "ISA_HAS_MSA && TARGET_64BIT"
+ "copy_u.w\t%0,%w1[%2]"
+ [(set_attr "type" "simd_copy")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_copy_s_<msafmt_f>_64bit"
+ [(set (match_operand:DI 0 "register_operand" "=d")
+ (sign_extend:DI
+ (vec_select:<UNITMODE>
+ (match_operand:MSA_W 1 "register_operand" "f")
+ (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
+ "ISA_HAS_MSA && TARGET_64BIT"
+ "copy_s.<msafmt>\t%0,%w1[%2]"
+ [(set_attr "type" "simd_copy")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_copy_s_<msafmt_f>"
+ [(set (match_operand:<UNITMODE> 0 "register_operand" "=d")
+ (vec_select:<UNITMODE>
+ (match_operand:MSA_W 1 "register_operand" "f")
+ (parallel [(match_operand 2 "const_<indeximm>_operand" "")])))]
+ "ISA_HAS_MSA"
+ "copy_s.<msafmt>\t%0,%w1[%2]"
+ [(set_attr "type" "simd_copy")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn_and_split "msa_copy_s_<msafmt_f>"
+ [(set (match_operand:<UNITMODE> 0 "register_operand" "=d")
+ (vec_select:<UNITMODE>
+ (match_operand:MSA_D 1 "register_operand" "f")
+ (parallel [(match_operand 2 "const_<indeximm>_operand" "")])))]
+ "ISA_HAS_MSA"
+{
+ if (TARGET_64BIT)
+ return "copy_s.<msafmt>\t%0,%w1[%2]";
+ else
+ return "#";
+}
+ "reload_completed && ISA_HAS_MSA && !TARGET_64BIT"
+ [(const_int 0)]
+{
+ mips_split_msa_copy_d (operands[0], operands[1], operands[2],
+ gen_msa_copy_s_w);
+ DONE;
+}
+ [(set_attr "type" "simd_copy")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "vec_perm_const<mode>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand:MSA 1 "register_operand")
+ (match_operand:MSA 2 "register_operand")
+ (match_operand:<VIMODE> 3 "")]
+ "ISA_HAS_MSA"
+{
+ if (mips_expand_vec_perm_const (operands))
+ DONE;
+ else
+ FAIL;
+})
+
+(define_expand "abs<mode>2"
+ [(match_operand:IMSA 0 "register_operand" "=f")
+ (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))]
+ "ISA_HAS_MSA"
+{
+ rtx reg = gen_reg_rtx (<MODE>mode);
+ emit_move_insn (reg, CONST0_RTX (<MODE>mode));
+ emit_insn (gen_msa_add_a_<msafmt> (operands[0], operands[1], reg));
+ DONE;
+})
+
+(define_expand "neg<mode>2"
+ [(set (match_operand:MSA 0 "register_operand")
+ (minus:MSA (match_dup 2)
+ (match_operand:MSA 1 "register_operand")))]
+ "ISA_HAS_MSA"
+{
+ rtx reg = gen_reg_rtx (<MODE>mode);
+ emit_move_insn (reg, CONST0_RTX (<MODE>mode));
+ operands[2] = reg;
+})
+
+(define_expand "msa_ldi<mode>"
+ [(match_operand:IMSA 0 "register_operand")
+ (match_operand 1 "const_imm10_operand")]
+ "ISA_HAS_MSA"
+{
+ if (<MODE>mode == V16QImode)
+ operands[1] = GEN_INT (trunc_int_for_mode (INTVAL (operands[1]),
+ <UNITMODE>mode));
+ emit_move_insn (operands[0],
+ mips_gen_const_int_vector (<MODE>mode, INTVAL (operands[1])));
+ DONE;
+})
+
+(define_insn "vec_perm<mode>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (unspec:MSA [(match_operand:MSA 1 "register_operand" "f")
+ (match_operand:MSA 2 "register_operand" "f")
+ (match_operand:<VIMODE> 3 "register_operand" "0")]
+ UNSPEC_MSA_VSHF))]
+ "ISA_HAS_MSA"
+ "vshf.<msafmt>\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_sld")
+ (set_attr "mode" "<MODE>")])
+
+(define_expand "mov<mode>"
+ [(set (match_operand:MSA 0)
+ (match_operand:MSA 1))]
+ "ISA_HAS_MSA"
+{
+ if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
+ DONE;
+})
+
+(define_expand "movmisalign<mode>"
+ [(set (match_operand:MSA 0)
+ (match_operand:MSA 1))]
+ "ISA_HAS_MSA"
+{
+ if (mips_legitimize_move (<MODE>mode, operands[0], operands[1]))
+ DONE;
+})
+
+;; 128-bit MSA modes can only exist in MSA registers or memory. An exception
+;; is allowing MSA modes for GP registers for arguments and return values.
+(define_insn "mov<mode>_msa"
+ [(set (match_operand:MSA 0 "nonimmediate_operand" "=f,f,R,*d,*f")
+ (match_operand:MSA 1 "move_operand" "fYGYI,R,f,*f,*d"))]
+ "ISA_HAS_MSA"
+ { return mips_output_move (operands[0], operands[1]); }
+ [(set_attr "type" "simd_move,simd_load,simd_store,simd_copy,simd_insert")
+ (set_attr "mode" "<MODE>")])
+
+(define_split
+ [(set (match_operand:MSA 0 "nonimmediate_operand")
+ (match_operand:MSA 1 "move_operand"))]
+ "reload_completed && ISA_HAS_MSA
+ && mips_split_move_insn_p (operands[0], operands[1], insn)"
+ [(const_int 0)]
+{
+ mips_split_move_insn (operands[0], operands[1], curr_insn);
+ DONE;
+})
+
+;; Offset load
+(define_expand "msa_ld_<msafmt_f>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand 1 "pmode_register_operand")
+ (match_operand 2 "aq10<msafmt>_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
+ INTVAL (operands[2]));
+ mips_emit_move (operands[0], gen_rtx_MEM (<MODE>mode, addr));
+ DONE;
+})
+
+;; Offset store
+(define_expand "msa_st_<msafmt_f>"
+ [(match_operand:MSA 0 "register_operand")
+ (match_operand 1 "pmode_register_operand")
+ (match_operand 2 "aq10<msafmt>_operand")]
+ "ISA_HAS_MSA"
+{
+ rtx addr = plus_constant (GET_MODE (operands[1]), operands[1],
+ INTVAL (operands[2]));
+ mips_emit_move (gen_rtx_MEM (<MODE>mode, addr), operands[0]);
+ DONE;
+})
+
+;; Integer operations
+(define_insn "add<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+ (plus:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_ximm5_operand" "f,Unv5,Uuv5")))]
+ "ISA_HAS_MSA"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "addv.<msafmt>\t%w0,%w1,%w2";
+ case 1:
+ {
+ HOST_WIDE_INT val = INTVAL (CONST_VECTOR_ELT (operands[2], 0));
+
+ operands[2] = GEN_INT (-val);
+ return "subvi.<msafmt>\t%w0,%w1,%d2";
+ }
+ case 2:
+ return "addvi.<msafmt>\t%w0,%w1,%E2";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "alu_type" "simd_add")
+ (set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "sub<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (minus:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))]
+ "ISA_HAS_MSA"
+ "@
+ subv.<msafmt>\t%w0,%w1,%w2
+ subvi.<msafmt>\t%w0,%w1,%E2"
+ [(set_attr "alu_type" "simd_add")
+ (set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "mul<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (mult:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "mulv.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_maddv_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (plus:IMSA (mult:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f"))
+ (match_operand:IMSA 3 "register_operand" "0")))]
+ "ISA_HAS_MSA"
+ "maddv.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_msubv_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (minus:IMSA (match_operand:IMSA 1 "register_operand" "0")
+ (mult:IMSA (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "msubv.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "div<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (div:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ { return mips_msa_output_division ("div_s.<msafmt>\t%w0,%w1,%w2", operands); }
+ [(set_attr "type" "simd_div")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "udiv<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (udiv:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ { return mips_msa_output_division ("div_u.<msafmt>\t%w0,%w1,%w2", operands); }
+ [(set_attr "type" "simd_div")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "mod<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (mod:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ { return mips_msa_output_division ("mod_s.<msafmt>\t%w0,%w1,%w2", operands); }
+ [(set_attr "type" "simd_div")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "umod<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (umod:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ { return mips_msa_output_division ("mod_u.<msafmt>\t%w0,%w1,%w2", operands); }
+ [(set_attr "type" "simd_div")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "xor<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+ (xor:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
+ "ISA_HAS_MSA"
+ "@
+ xor.v\t%w0,%w1,%w2
+ bnegi.%v0\t%w0,%w1,%V2
+ xori.b\t%w0,%w1,%B2"
+ [(set_attr "type" "simd_logic,simd_bit,simd_logic")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "ior<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+ (ior:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YC,Urv8")))]
+ "ISA_HAS_MSA"
+ "@
+ or.v\t%w0,%w1,%w2
+ bseti.%v0\t%w0,%w1,%V2
+ ori.b\t%w0,%w1,%B2"
+ [(set_attr "type" "simd_logic,simd_bit,simd_logic")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "and<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f,f")
+ (and:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,YZ,Urv8")))]
+ "ISA_HAS_MSA"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return "and.v\t%w0,%w1,%w2";
+ case 1:
+ {
+ rtx elt0 = CONST_VECTOR_ELT (operands[2], 0);
+ unsigned HOST_WIDE_INT val = ~UINTVAL (elt0);
+ operands[2] = mips_gen_const_int_vector (<MODE>mode, val & (-val));
+ return "bclri.%v0\t%w0,%w1,%V2";
+ }
+ case 2:
+ return "andi.b\t%w0,%w1,%B2";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "simd_logic,simd_bit,simd_logic")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "one_cmpl<mode>2"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (not:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "nor.v\t%w0,%w1,%w1"
+ [(set_attr "type" "simd_logic")
+ (set_attr "mode" "TI")])
+
+(define_insn "vlshr<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (lshiftrt:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
+ "ISA_HAS_MSA"
+ "@
+ srl.<msafmt>\t%w0,%w1,%w2
+ srli.<msafmt>\t%w0,%w1,%E2"
+ [(set_attr "type" "simd_shift")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "vashr<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (ashiftrt:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
+ "ISA_HAS_MSA"
+ "@
+ sra.<msafmt>\t%w0,%w1,%w2
+ srai.<msafmt>\t%w0,%w1,%E2"
+ [(set_attr "type" "simd_shift")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "vashl<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (ashift:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_uimm6_operand" "f,Uuv6")))]
+ "ISA_HAS_MSA"
+ "@
+ sll.<msafmt>\t%w0,%w1,%w2
+ slli.<msafmt>\t%w0,%w1,%E2"
+ [(set_attr "type" "simd_shift")
+ (set_attr "mode" "<MODE>")])
+
+;; Floating-point operations
+(define_insn "add<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (plus:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fadd.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fadd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "sub<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (minus:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fsub.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fadd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "mul<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (mult:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fmul.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fmul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "div<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (div:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fdiv.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fdiv")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "fma<mode>4"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (fma:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")
+ (match_operand:FMSA 3 "register_operand" "0")))]
+ "ISA_HAS_MSA"
+ "fmadd.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fmadd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "fnma<mode>4"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (fma:FMSA (neg:FMSA (match_operand:FMSA 1 "register_operand" "f"))
+ (match_operand:FMSA 2 "register_operand" "f")
+ (match_operand:FMSA 3 "register_operand" "0")))]
+ "ISA_HAS_MSA"
+ "fmsub.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fmadd")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "sqrt<mode>2"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (sqrt:FMSA (match_operand:FMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fsqrt.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fdiv")
+ (set_attr "mode" "<MODE>")])
+
+;; Built-in functions
+(define_insn "msa_add_a_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (plus:IMSA (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
+ (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "add_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_adds_a_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (ss_plus:IMSA
+ (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
+ (abs:IMSA (match_operand:IMSA 2 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "adds_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "ssadd<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (ss_plus:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "adds_s.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "usadd<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (us_plus:IMSA (match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "adds_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_asub_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_ASUB_S))]
+ "ISA_HAS_MSA"
+ "asub_s.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_asub_u_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_ASUB_U))]
+ "ISA_HAS_MSA"
+ "asub_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_ave_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_AVE_S))]
+ "ISA_HAS_MSA"
+ "ave_s.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_ave_u_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_AVE_U))]
+ "ISA_HAS_MSA"
+ "ave_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_aver_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_AVER_S))]
+ "ISA_HAS_MSA"
+ "aver_s.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_aver_u_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_AVER_U))]
+ "ISA_HAS_MSA"
+ "aver_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bclr_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_BCLR))]
+ "ISA_HAS_MSA"
+ "bclr.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_bit")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bclri_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_BCLRI))]
+ "ISA_HAS_MSA"
+ "bclri.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "simd_bit")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_binsl_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_BINSL))]
+ "ISA_HAS_MSA"
+ "binsl.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_bitins")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_binsli_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand 3 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_BINSLI))]
+ "ISA_HAS_MSA"
+ "binsli.<msafmt>\t%w0,%w2,%3"
+ [(set_attr "type" "simd_bitins")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_binsr_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand:IMSA 3 "register_operand" "f")]
+ UNSPEC_MSA_BINSR))]
+ "ISA_HAS_MSA"
+ "binsr.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_bitins")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_binsri_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "0")
+ (match_operand:IMSA 2 "register_operand" "f")
+ (match_operand 3 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_BINSRI))]
+ "ISA_HAS_MSA"
+ "binsri.<msafmt>\t%w0,%w2,%3"
+ [(set_attr "type" "simd_bitins")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bmnz_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (ior:IMSA (and:IMSA (match_operand:IMSA 2 "register_operand" "f,f")
+ (match_operand:IMSA 3 "reg_or_vector_same_val_operand" "f,Urv8"))
+ (and:IMSA (not:IMSA (match_dup 3))
+ (match_operand:IMSA 1 "register_operand" "0,0"))))]
+ "ISA_HAS_MSA"
+ "@
+ bmnz.v\t%w0,%w2,%w3
+ bmnzi.b\t%w0,%w2,%B3"
+ [(set_attr "type" "simd_bitmov")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bmz_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (ior:IMSA (and:IMSA (not:IMSA
+ (match_operand:IMSA 3 "reg_or_vector_same_val_operand" "f,Urv8"))
+ (match_operand:IMSA 2 "register_operand" "f,f"))
+ (and:IMSA (match_operand:IMSA 1 "register_operand" "0,0")
+ (match_dup 3))))]
+ "ISA_HAS_MSA"
+ "@
+ bmz.v\t%w0,%w2,%w3
+ bmzi.b\t%w0,%w2,%B3"
+ [(set_attr "type" "simd_bitmov")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bneg_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_BNEG))]
+ "ISA_HAS_MSA"
+ "bneg.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_bit")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bnegi_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_msa_branch_operand" "")]
+ UNSPEC_MSA_BNEGI))]
+ "ISA_HAS_MSA"
+ "bnegi.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "simd_bit")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bsel_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (ior:IMSA (and:IMSA (not:IMSA
+ (match_operand:IMSA 1 "register_operand" "0,0"))
+ (match_operand:IMSA 2 "register_operand" "f,f"))
+ (and:IMSA (match_dup 1)
+ (match_operand:IMSA 3 "reg_or_vector_same_val_operand" "f,Urv8"))))]
+ "ISA_HAS_MSA"
+ "@
+ bsel.v\t%w0,%w2,%w3
+ bseli.b\t%w0,%w2,%B3"
+ [(set_attr "type" "simd_bitmov")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bset_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_BSET))]
+ "ISA_HAS_MSA"
+ "bset.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_bit")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_bseti_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_BSETI))]
+ "ISA_HAS_MSA"
+ "bseti.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "simd_bit")
+ (set_attr "mode" "<MODE>")])
+
+(define_code_iterator ICC [eq le leu lt ltu])
+
+(define_code_attr icc
+ [(eq "eq")
+ (le "le_s")
+ (leu "le_u")
+ (lt "lt_s")
+ (ltu "lt_u")])
+
+(define_code_attr icci
+ [(eq "eqi")
+ (le "lei_s")
+ (leu "lei_u")
+ (lt "lti_s")
+ (ltu "lti_u")])
+
+(define_code_attr cmpi
+ [(eq "s")
+ (le "s")
+ (leu "u")
+ (lt "s")
+ (ltu "u")])
+
+(define_insn "msa_c<ICC:icc>_<IMSA:msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (ICC:IMSA
+ (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_<ICC:cmpi>imm5_operand" "f,U<ICC:cmpi>v5")))]
+ "ISA_HAS_MSA"
+ "@
+ c<ICC:icc>.<IMSA:msafmt>\t%w0,%w1,%w2
+ c<ICC:icci>.<IMSA:msafmt>\t%w0,%w1,%E2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_dotp_<su>_d"
+ [(set (match_operand:V2DI 0 "register_operand" "=f")
+ (plus:V2DI
+ (mult:V2DI
+ (any_extend:V2DI
+ (vec_select:V2SI
+ (match_operand:V4SI 1 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)])))
+ (any_extend:V2DI
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)]))))
+ (mult:V2DI
+ (any_extend:V2DI
+ (vec_select:V4SI (match_dup 1)
+ (parallel [(const_int 1) (const_int 3)])))
+ (any_extend:V2DI
+ (vec_select:V4SI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)]))))))]
+ "ISA_HAS_MSA"
+ "dotp_<su>.d\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V2DI")])
+
+(define_insn "msa_dotp_<su>_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (plus:V4SI
+ (mult:V4SI
+ (any_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 1 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)])))
+ (any_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 2 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)]))))
+ (mult:V4SI
+ (any_extend:V4SI
+ (vec_select:V4HI (match_dup 1)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)])))
+ (any_extend:V4SI
+ (vec_select:V4HI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)]))))))]
+ "ISA_HAS_MSA"
+ "dotp_<su>.w\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_dotp_<su>_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (plus:V8HI
+ (mult:V8HI
+ (any_extend:V8HI
+ (vec_select:V8QI
+ (match_operand:V16QI 1 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)])))
+ (any_extend:V8HI
+ (vec_select:V8QI
+ (match_operand:V16QI 2 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)]))))
+ (mult:V8HI
+ (any_extend:V8HI
+ (vec_select:V8QI (match_dup 1)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)])))
+ (any_extend:V8HI
+ (vec_select:V8QI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)]))))))]
+ "ISA_HAS_MSA"
+ "dotp_<su>.h\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_dpadd_<su>_d"
+ [(set (match_operand:V2DI 0 "register_operand" "=f")
+ (plus:V2DI
+ (plus:V2DI
+ (mult:V2DI
+ (any_extend:V2DI
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)])))
+ (any_extend:V2DI
+ (vec_select:V2SI
+ (match_operand:V4SI 3 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)]))))
+ (mult:V2DI
+ (any_extend:V2DI
+ (vec_select:V4SI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)])))
+ (any_extend:V2DI
+ (vec_select:V4SI (match_dup 3)
+ (parallel [(const_int 1) (const_int 3)])))))
+ (match_operand:V2DI 1 "register_operand" "0")))]
+ "ISA_HAS_MSA"
+ "dpadd_<su>.d\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V2DI")])
+
+(define_insn "msa_dpadd_<su>_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (plus:V4SI
+ (plus:V4SI
+ (mult:V4SI
+ (any_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 2 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)])))
+ (any_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 3 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)]))))
+ (mult:V4SI
+ (any_extend:V4SI
+ (vec_select:V4HI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)])))
+ (any_extend:V4SI
+ (vec_select:V4HI (match_dup 3)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)])))))
+ (match_operand:V4SI 1 "register_operand" "0")))]
+ "ISA_HAS_MSA"
+ "dpadd_<su>.w\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_dpadd_<su>_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (plus:V8HI
+ (plus:V8HI
+ (mult:V8HI
+ (any_extend:V8HI
+ (vec_select:V8QI
+ (match_operand:V16QI 2 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)])))
+ (any_extend:V8HI
+ (vec_select:V8QI
+ (match_operand:V16QI 3 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)]))))
+ (mult:V8HI
+ (any_extend:V8HI
+ (vec_select:V8QI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)])))
+ (any_extend:V8HI
+ (vec_select:V8QI (match_dup 3)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)])))))
+ (match_operand:V8HI 1 "register_operand" "0")))]
+ "ISA_HAS_MSA"
+ "dpadd_<su>.h\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_dpsub_<su>_d"
+ [(set (match_operand:V2DI 0 "register_operand" "=f")
+ (minus:V2DI
+ (match_operand:V2DI 1 "register_operand" "0")
+ (plus:V2DI
+ (mult:V2DI
+ (any_extend:V2DI
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)])))
+ (any_extend:V2DI
+ (vec_select:V2SI
+ (match_operand:V4SI 3 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)]))))
+ (mult:V2DI
+ (any_extend:V2DI
+ (vec_select:V4SI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)])))
+ (any_extend:V2DI
+ (vec_select:V4SI (match_dup 3)
+ (parallel [(const_int 1) (const_int 3)])))))))]
+ "ISA_HAS_MSA"
+ "dpsub_<su>.d\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V2DI")])
+
+(define_insn "msa_dpsub_<su>_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (minus:V4SI
+ (match_operand:V4SI 1 "register_operand" "0")
+ (plus:V4SI
+ (mult:V4SI
+ (any_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 2 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)])))
+ (any_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 3 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)]))))
+ (mult:V4SI
+ (any_extend:V4SI
+ (vec_select:V4HI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)])))
+ (any_extend:V4SI
+ (vec_select:V4HI (match_dup 3)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)])))))))]
+ "ISA_HAS_MSA"
+ "dpsub_<su>.w\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_dpsub_<su>_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (minus:V8HI
+ (match_operand:V8HI 1 "register_operand" "0")
+ (plus:V8HI
+ (mult:V8HI
+ (any_extend:V8HI
+ (vec_select:V8QI
+ (match_operand:V16QI 2 "register_operand" "%f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)])))
+ (any_extend:V8HI
+ (vec_select:V8QI
+ (match_operand:V16QI 3 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)]))))
+ (mult:V8HI
+ (any_extend:V8HI
+ (vec_select:V8QI (match_dup 2)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)])))
+ (any_extend:V8HI
+ (vec_select:V8QI (match_dup 3)
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)])))))))]
+ "ISA_HAS_MSA"
+ "dpsub_<su>.h\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_fclass_<msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FCLASS))]
+ "ISA_HAS_MSA"
+ "fclass.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fclass")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_fcaf_<msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_FCAF))]
+ "ISA_HAS_MSA"
+ "fcaf.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fcmp")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_fcune_<FMSA:msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_FCUNE))]
+ "ISA_HAS_MSA"
+ "fcune.<FMSA:msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fcmp")
+ (set_attr "mode" "<MODE>")])
+
+(define_code_iterator FCC [unordered ordered eq ne le lt uneq unle unlt])
+
+(define_code_attr fcc
+ [(unordered "fcun")
+ (ordered "fcor")
+ (eq "fceq")
+ (ne "fcne")
+ (uneq "fcueq")
+ (unle "fcule")
+ (unlt "fcult")
+ (le "fcle")
+ (lt "fclt")])
+
+(define_int_iterator FSC_UNS [UNSPEC_MSA_FSAF UNSPEC_MSA_FSUN UNSPEC_MSA_FSOR
+ UNSPEC_MSA_FSEQ UNSPEC_MSA_FSNE UNSPEC_MSA_FSUEQ
+ UNSPEC_MSA_FSUNE UNSPEC_MSA_FSULE UNSPEC_MSA_FSULT
+ UNSPEC_MSA_FSLE UNSPEC_MSA_FSLT])
+
+(define_int_attr fsc
+ [(UNSPEC_MSA_FSAF "fsaf")
+ (UNSPEC_MSA_FSUN "fsun")
+ (UNSPEC_MSA_FSOR "fsor")
+ (UNSPEC_MSA_FSEQ "fseq")
+ (UNSPEC_MSA_FSNE "fsne")
+ (UNSPEC_MSA_FSUEQ "fsueq")
+ (UNSPEC_MSA_FSUNE "fsune")
+ (UNSPEC_MSA_FSULE "fsule")
+ (UNSPEC_MSA_FSULT "fsult")
+ (UNSPEC_MSA_FSLE "fsle")
+ (UNSPEC_MSA_FSLT "fslt")])
+
+(define_insn "msa_<FCC:fcc>_<FMSA:msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (FCC:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "<FCC:fcc>.<FMSA:msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fcmp")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_<fsc>_<FMSA:msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")]
+ FSC_UNS))]
+ "ISA_HAS_MSA"
+ "<fsc>.<FMSA:msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fcmp")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_fexp2_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:<VIMODE> 2 "register_operand" "f")]
+ UNSPEC_MSA_FEXP2))]
+ "ISA_HAS_MSA"
+ "fexp2.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fexp2")
+ (set_attr "mode" "<MODE>")])
+
+(define_mode_attr fint
+ [(V4SF "v4si")
+ (V2DF "v2di")])
+
+(define_mode_attr FQ
+ [(V4SF "V8HI")
+ (V2DF "V4SI")])
+
+(define_mode_attr FINTCNV
+ [(V4SF "I2S")
+ (V2DF "I2D")])
+
+(define_mode_attr FINTCNV_2
+ [(V4SF "S2I")
+ (V2DF "D2I")])
+
+(define_insn "float<fint><FMSA:mode>2"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (float:FMSA (match_operand:<VIMODE> 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "ffint_s.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "<FINTCNV>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "floatuns<fint><FMSA:mode>2"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unsigned_float:FMSA
+ (match_operand:<VIMODE> 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "ffint_u.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "<FINTCNV>")
+ (set_attr "mode" "<MODE>")])
+
+(define_mode_attr FFQ
+ [(V4SF "V8HI")
+ (V2DF "V4SI")])
+
+(define_insn "msa_ffql_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:<FQ> 1 "register_operand" "f")]
+ UNSPEC_MSA_FFQL))]
+ "ISA_HAS_MSA"
+ "ffql.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "<FINTCNV>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_ffqr_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:<FQ> 1 "register_operand" "f")]
+ UNSPEC_MSA_FFQR))]
+ "ISA_HAS_MSA"
+ "ffqr.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "<FINTCNV>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_fill_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f,f")
+ (vec_duplicate:MSA
+ (match_operand:<UNITMODE> 1 "reg_or_0_operand" "d,J")))]
+ "ISA_HAS_MSA"
+{
+ if (which_alternative == 1)
+ return "ldi.<msafmt>\t%w0,0";
+
+ if (!TARGET_64BIT && (<MODE>mode == V2DImode || <MODE>mode == V2DFmode))
+ return "#";
+ else
+ return "fill.<msafmt>\t%w0,%z1";
+}
+ [(set_attr "type" "simd_fill")
+ (set_attr "mode" "<MODE>")])
+
+(define_split
+ [(set (match_operand:MSA_D 0 "register_operand")
+ (vec_duplicate:MSA_D
+ (match_operand:<UNITMODE> 1 "register_operand")))]
+ "reload_completed && ISA_HAS_MSA && !TARGET_64BIT"
+ [(const_int 0)]
+{
+ mips_split_msa_fill_d (operands[0], operands[1]);
+ DONE;
+})
+
+(define_insn "msa_flog2_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FLOG2))]
+ "ISA_HAS_MSA"
+ "flog2.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_flog2")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "smax<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (smax:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fmax.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fminmax")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_fmax_a_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (if_then_else
+ (gt (abs:FMSA (match_operand:FMSA 1 "register_operand" "f"))
+ (abs:FMSA (match_operand:FMSA 2 "register_operand" "f")))
+ (match_dup 1)
+ (match_dup 2)))]
+ "ISA_HAS_MSA"
+ "fmax_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fminmax")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "smin<mode>3"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (smin:FMSA (match_operand:FMSA 1 "register_operand" "f")
+ (match_operand:FMSA 2 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "fmin.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fminmax")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_fmin_a_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (if_then_else
+ (lt (abs:FMSA (match_operand:FMSA 1 "register_operand" "f"))
+ (abs:FMSA (match_operand:FMSA 2 "register_operand" "f")))
+ (match_dup 1)
+ (match_dup 2)))]
+ "ISA_HAS_MSA"
+ "fmin_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fminmax")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_frcp_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FRCP))]
+ "ISA_HAS_MSA"
+ "frcp.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fdiv")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_frint_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FRINT))]
+ "ISA_HAS_MSA"
+ "frint.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_frsqrt_<msafmt>"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FRSQRT))]
+ "ISA_HAS_MSA"
+ "frsqrt.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fdiv")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_ftint_s_<msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FTINT_S))]
+ "ISA_HAS_MSA"
+ "ftint_s.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "<FINTCNV_2>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_ftint_u_<msafmt>"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (unspec:<VIMODE> [(match_operand:FMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_FTINT_U))]
+ "ISA_HAS_MSA"
+ "ftint_u.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "<FINTCNV_2>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "fix_trunc<FMSA:mode><mode_i>2"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (fix:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "ftrunc_s.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "<FINTCNV_2>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "fixuns_trunc<FMSA:mode><mode_i>2"
+ [(set (match_operand:<VIMODE> 0 "register_operand" "=f")
+ (unsigned_fix:<VIMODE> (match_operand:FMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "ftrunc_u.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "<FINTCNV_2>")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_ftq_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f")]
+ UNSPEC_MSA_FTQ))]
+ "ISA_HAS_MSA"
+ "ftq.h\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "S2I")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_ftq_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (unspec:V4SI [(match_operand:V2DF 1 "register_operand" "f")
+ (match_operand:V2DF 2 "register_operand" "f")]
+ UNSPEC_MSA_FTQ))]
+ "ISA_HAS_MSA"
+ "ftq.w\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "cnv_mode" "D2I")
+ (set_attr "mode" "V2DF")])
+
+(define_insn "msa_h<optab>_<su>_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (addsub:V8HI
+ (any_extend:V8HI
+ (vec_select:V8QI
+ (match_operand:V16QI 1 "register_operand" "f")
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)])))
+ (any_extend:V8HI
+ (vec_select:V8QI
+ (match_operand:V16QI 2 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)])))))]
+ "ISA_HAS_MSA"
+ "h<optab>_<su>.h\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_h<optab>_<su>_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (addsub:V4SI
+ (any_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 1 "register_operand" "f")
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)])))
+ (any_extend:V4SI
+ (vec_select:V4HI
+ (match_operand:V8HI 2 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)])))))]
+ "ISA_HAS_MSA"
+ "h<optab>_<su>.w\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_h<optab>_<su>_d"
+ [(set (match_operand:V2DI 0 "register_operand" "=f")
+ (addsub:V2DI
+ (any_extend:V2DI
+ (vec_select:V2SI
+ (match_operand:V4SI 1 "register_operand" "f")
+ (parallel [(const_int 1) (const_int 3)])))
+ (any_extend:V2DI
+ (vec_select:V2SI
+ (match_operand:V4SI 2 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 2)])))))]
+ "ISA_HAS_MSA"
+ "h<optab>_<su>.d\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "V2DI")])
+
+(define_insn "msa_ilvev_b"
+ [(set (match_operand:V16QI 0 "register_operand" "=f")
+ (vec_select:V16QI
+ (vec_concat:V32QI
+ (match_operand:V16QI 1 "register_operand" "f")
+ (match_operand:V16QI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 16)
+ (const_int 2) (const_int 18)
+ (const_int 4) (const_int 20)
+ (const_int 6) (const_int 22)
+ (const_int 8) (const_int 24)
+ (const_int 10) (const_int 26)
+ (const_int 12) (const_int 28)
+ (const_int 14) (const_int 30)])))]
+ "ISA_HAS_MSA"
+ "ilvev.b\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V16QI")])
+
+(define_insn "msa_ilvev_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (vec_select:V8HI
+ (vec_concat:V16HI
+ (match_operand:V8HI 1 "register_operand" "f")
+ (match_operand:V8HI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 8)
+ (const_int 2) (const_int 10)
+ (const_int 4) (const_int 12)
+ (const_int 6) (const_int 14)])))]
+ "ISA_HAS_MSA"
+ "ilvev.h\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_ilvev_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (vec_select:V4SI
+ (vec_concat:V8SI
+ (match_operand:V4SI 1 "register_operand" "f")
+ (match_operand:V4SI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 4)
+ (const_int 2) (const_int 6)])))]
+ "ISA_HAS_MSA"
+ "ilvev.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_ilvev_w_f"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (vec_select:V4SF
+ (vec_concat:V8SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 4)
+ (const_int 2) (const_int 6)])))]
+ "ISA_HAS_MSA"
+ "ilvev.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_ilvl_b"
+ [(set (match_operand:V16QI 0 "register_operand" "=f")
+ (vec_select:V16QI
+ (vec_concat:V32QI
+ (match_operand:V16QI 1 "register_operand" "f")
+ (match_operand:V16QI 2 "register_operand" "f"))
+ (parallel [(const_int 8) (const_int 24)
+ (const_int 9) (const_int 25)
+ (const_int 10) (const_int 26)
+ (const_int 11) (const_int 27)
+ (const_int 12) (const_int 28)
+ (const_int 13) (const_int 29)
+ (const_int 14) (const_int 30)
+ (const_int 15) (const_int 31)])))]
+ "ISA_HAS_MSA"
+ "ilvl.b\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V16QI")])
+
+(define_insn "msa_ilvl_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (vec_select:V8HI
+ (vec_concat:V16HI
+ (match_operand:V8HI 1 "register_operand" "f")
+ (match_operand:V8HI 2 "register_operand" "f"))
+ (parallel [(const_int 4) (const_int 12)
+ (const_int 5) (const_int 13)
+ (const_int 6) (const_int 14)
+ (const_int 7) (const_int 15)])))]
+ "ISA_HAS_MSA"
+ "ilvl.h\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_ilvl_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (vec_select:V4SI
+ (vec_concat:V8SI
+ (match_operand:V4SI 1 "register_operand" "f")
+ (match_operand:V4SI 2 "register_operand" "f"))
+ (parallel [(const_int 2) (const_int 6)
+ (const_int 3) (const_int 7)])))]
+ "ISA_HAS_MSA"
+ "ilvl.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_ilvl_w_f"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (vec_select:V4SF
+ (vec_concat:V8SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f"))
+ (parallel [(const_int 2) (const_int 6)
+ (const_int 3) (const_int 7)])))]
+ "ISA_HAS_MSA"
+ "ilvl.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_ilvl_d"
+ [(set (match_operand:V2DI 0 "register_operand" "=f")
+ (vec_select:V2DI
+ (vec_concat:V4DI
+ (match_operand:V2DI 1 "register_operand" "f")
+ (match_operand:V2DI 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 3)])))]
+ "ISA_HAS_MSA"
+ "ilvl.d\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V2DI")])
+
+(define_insn "msa_ilvl_d_f"
+ [(set (match_operand:V2DF 0 "register_operand" "=f")
+ (vec_select:V2DF
+ (vec_concat:V4DF
+ (match_operand:V2DF 1 "register_operand" "f")
+ (match_operand:V2DF 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 3)])))]
+ "ISA_HAS_MSA"
+ "ilvl.d\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V2DF")])
+
+(define_insn "msa_ilvod_b"
+ [(set (match_operand:V16QI 0 "register_operand" "=f")
+ (vec_select:V16QI
+ (vec_concat:V32QI
+ (match_operand:V16QI 1 "register_operand" "f")
+ (match_operand:V16QI 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 17)
+ (const_int 3) (const_int 19)
+ (const_int 5) (const_int 21)
+ (const_int 7) (const_int 23)
+ (const_int 9) (const_int 25)
+ (const_int 11) (const_int 27)
+ (const_int 13) (const_int 29)
+ (const_int 15) (const_int 31)])))]
+ "ISA_HAS_MSA"
+ "ilvod.b\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V16QI")])
+
+(define_insn "msa_ilvod_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (vec_select:V8HI
+ (vec_concat:V16HI
+ (match_operand:V8HI 1 "register_operand" "f")
+ (match_operand:V8HI 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 9)
+ (const_int 3) (const_int 11)
+ (const_int 5) (const_int 13)
+ (const_int 7) (const_int 15)])))]
+ "ISA_HAS_MSA"
+ "ilvod.h\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_ilvod_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (vec_select:V4SI
+ (vec_concat:V8SI
+ (match_operand:V4SI 1 "register_operand" "f")
+ (match_operand:V4SI 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 5)
+ (const_int 3) (const_int 7)])))]
+ "ISA_HAS_MSA"
+ "ilvod.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_ilvod_w_f"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (vec_select:V4SF
+ (vec_concat:V8SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 5)
+ (const_int 3) (const_int 7)])))]
+ "ISA_HAS_MSA"
+ "ilvod.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_ilvr_b"
+ [(set (match_operand:V16QI 0 "register_operand" "=f")
+ (vec_select:V16QI
+ (vec_concat:V32QI
+ (match_operand:V16QI 1 "register_operand" "f")
+ (match_operand:V16QI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 16)
+ (const_int 1) (const_int 17)
+ (const_int 2) (const_int 18)
+ (const_int 3) (const_int 19)
+ (const_int 4) (const_int 20)
+ (const_int 5) (const_int 21)
+ (const_int 6) (const_int 22)
+ (const_int 7) (const_int 23)])))]
+ "ISA_HAS_MSA"
+ "ilvr.b\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V16QI")])
+
+(define_insn "msa_ilvr_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (vec_select:V8HI
+ (vec_concat:V16HI
+ (match_operand:V8HI 1 "register_operand" "f")
+ (match_operand:V8HI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 8)
+ (const_int 1) (const_int 9)
+ (const_int 2) (const_int 10)
+ (const_int 3) (const_int 11)])))]
+ "ISA_HAS_MSA"
+ "ilvr.h\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_ilvr_w"
+ [(set (match_operand:V4SI 0 "register_operand" "=f")
+ (vec_select:V4SI
+ (vec_concat:V8SI
+ (match_operand:V4SI 1 "register_operand" "f")
+ (match_operand:V4SI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 4)
+ (const_int 1) (const_int 5)])))]
+ "ISA_HAS_MSA"
+ "ilvr.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_ilvr_w_f"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (vec_select:V4SF
+ (vec_concat:V8SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 4)
+ (const_int 1) (const_int 5)])))]
+ "ISA_HAS_MSA"
+ "ilvr.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_ilvr_d"
+ [(set (match_operand:V2DI 0 "register_operand" "=f")
+ (vec_select:V2DI
+ (vec_concat:V4DI
+ (match_operand:V2DI 1 "register_operand" "f")
+ (match_operand:V2DI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 2)])))]
+ "ISA_HAS_MSA"
+ "ilvr.d\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V2DI")])
+
+(define_insn "msa_ilvr_d_f"
+ [(set (match_operand:V2DF 0 "register_operand" "=f")
+ (vec_select:V2DF
+ (vec_concat:V4DF
+ (match_operand:V2DF 1 "register_operand" "f")
+ (match_operand:V2DF 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 2)])))]
+ "ISA_HAS_MSA"
+ "ilvr.d\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V2DF")])
+
+(define_insn "msa_madd_q_<msafmt>"
+ [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
+ (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0")
+ (match_operand:IMSA_WH 2 "register_operand" "f")
+ (match_operand:IMSA_WH 3 "register_operand" "f")]
+ UNSPEC_MSA_MADD_Q))]
+ "ISA_HAS_MSA"
+ "madd_q.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_maddr_q_<msafmt>"
+ [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
+ (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0")
+ (match_operand:IMSA_WH 2 "register_operand" "f")
+ (match_operand:IMSA_WH 3 "register_operand" "f")]
+ UNSPEC_MSA_MADDR_Q))]
+ "ISA_HAS_MSA"
+ "maddr_q.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_max_a_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (if_then_else
+ (gt (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
+ (abs:IMSA (match_operand:IMSA 2 "register_operand" "f")))
+ (match_dup 1)
+ (match_dup 2)))]
+ "ISA_HAS_MSA"
+ "max_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "smax<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (smax:IMSA (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_simm5_operand" "f,Usv5")))]
+ "ISA_HAS_MSA"
+ "@
+ max_s.<msafmt>\t%w0,%w1,%w2
+ maxi_s.<msafmt>\t%w0,%w1,%B2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "umax<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (umax:IMSA (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))]
+ "ISA_HAS_MSA"
+ "@
+ max_u.<msafmt>\t%w0,%w1,%w2
+ maxi_u.<msafmt>\t%w0,%w1,%B2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_min_a_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (if_then_else
+ (lt (abs:IMSA (match_operand:IMSA 1 "register_operand" "f"))
+ (abs:IMSA (match_operand:IMSA 2 "register_operand" "f")))
+ (match_dup 1)
+ (match_dup 2)))]
+ "ISA_HAS_MSA"
+ "min_a.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "smin<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (smin:IMSA (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_simm5_operand" "f,Usv5")))]
+ "ISA_HAS_MSA"
+ "@
+ min_s.<msafmt>\t%w0,%w1,%w2
+ mini_s.<msafmt>\t%w0,%w1,%B2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "umin<mode>3"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (umin:IMSA (match_operand:IMSA 1 "register_operand" "f,f")
+ (match_operand:IMSA 2 "reg_or_vector_same_uimm5_operand" "f,Uuv5")))]
+ "ISA_HAS_MSA"
+ "@
+ min_u.<msafmt>\t%w0,%w1,%w2
+ mini_u.<msafmt>\t%w0,%w1,%B2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_msub_q_<msafmt>"
+ [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
+ (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0")
+ (match_operand:IMSA_WH 2 "register_operand" "f")
+ (match_operand:IMSA_WH 3 "register_operand" "f")]
+ UNSPEC_MSA_MSUB_Q))]
+ "ISA_HAS_MSA"
+ "msub_q.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_msubr_q_<msafmt>"
+ [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
+ (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "0")
+ (match_operand:IMSA_WH 2 "register_operand" "f")
+ (match_operand:IMSA_WH 3 "register_operand" "f")]
+ UNSPEC_MSA_MSUBR_Q))]
+ "ISA_HAS_MSA"
+ "msubr_q.<msafmt>\t%w0,%w2,%w3"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_mul_q_<msafmt>"
+ [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
+ (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "f")
+ (match_operand:IMSA_WH 2 "register_operand" "f")]
+ UNSPEC_MSA_MUL_Q))]
+ "ISA_HAS_MSA"
+ "mul_q.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_mulr_q_<msafmt>"
+ [(set (match_operand:IMSA_WH 0 "register_operand" "=f")
+ (unspec:IMSA_WH [(match_operand:IMSA_WH 1 "register_operand" "f")
+ (match_operand:IMSA_WH 2 "register_operand" "f")]
+ UNSPEC_MSA_MULR_Q))]
+ "ISA_HAS_MSA"
+ "mulr_q.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_mul")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_nloc_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")]
+ UNSPEC_MSA_NLOC))]
+ "ISA_HAS_MSA"
+ "nloc.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_bit")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "clz<mode>2"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (clz:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "nlzc.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_bit")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_nor_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f,f")
+ (and:IMSA (not:IMSA (match_operand:IMSA 1 "register_operand" "f,f"))
+ (not:IMSA (match_operand:IMSA 2 "reg_or_vector_same_val_operand" "f,Urv8"))))]
+ "ISA_HAS_MSA"
+ "@
+ nor.v\t%w0,%w1,%w2
+ nori.b\t%w0,%w1,%B2"
+ [(set_attr "type" "simd_logic")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_pckev_b"
+[(set (match_operand:V16QI 0 "register_operand" "=f")
+ (vec_select:V16QI
+ (vec_concat:V32QI
+ (match_operand:V16QI 1 "register_operand" "f")
+ (match_operand:V16QI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)
+ (const_int 16) (const_int 18)
+ (const_int 20) (const_int 22)
+ (const_int 24) (const_int 26)
+ (const_int 28) (const_int 30)])))]
+ "ISA_HAS_MSA"
+ "pckev.b\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V16QI")])
+
+(define_insn "msa_pckev_h"
+[(set (match_operand:V8HI 0 "register_operand" "=f")
+ (vec_select:V8HI
+ (vec_concat:V16HI
+ (match_operand:V8HI 1 "register_operand" "f")
+ (match_operand:V8HI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)
+ (const_int 8) (const_int 10)
+ (const_int 12) (const_int 14)])))]
+ "ISA_HAS_MSA"
+ "pckev.h\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_pckev_w"
+[(set (match_operand:V4SI 0 "register_operand" "=f")
+ (vec_select:V4SI
+ (vec_concat:V8SI
+ (match_operand:V4SI 1 "register_operand" "f")
+ (match_operand:V4SI 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)])))]
+ "ISA_HAS_MSA"
+ "pckev.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_pckev_w_f"
+[(set (match_operand:V4SF 0 "register_operand" "=f")
+ (vec_select:V4SF
+ (vec_concat:V8SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f"))
+ (parallel [(const_int 0) (const_int 2)
+ (const_int 4) (const_int 6)])))]
+ "ISA_HAS_MSA"
+ "pckev.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_pckod_b"
+[(set (match_operand:V16QI 0 "register_operand" "=f")
+ (vec_select:V16QI
+ (vec_concat:V32QI
+ (match_operand:V16QI 1 "register_operand" "f")
+ (match_operand:V16QI 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)
+ (const_int 17) (const_int 19)
+ (const_int 21) (const_int 23)
+ (const_int 25) (const_int 27)
+ (const_int 29) (const_int 31)])))]
+ "ISA_HAS_MSA"
+ "pckod.b\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V16QI")])
+
+(define_insn "msa_pckod_h"
+[(set (match_operand:V8HI 0 "register_operand" "=f")
+ (vec_select:V8HI
+ (vec_concat:V16HI
+ (match_operand:V8HI 1 "register_operand" "f")
+ (match_operand:V8HI 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)
+ (const_int 9) (const_int 11)
+ (const_int 13) (const_int 15)])))]
+ "ISA_HAS_MSA"
+ "pckod.h\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "msa_pckod_w"
+[(set (match_operand:V4SI 0 "register_operand" "=f")
+ (vec_select:V4SI
+ (vec_concat:V8SI
+ (match_operand:V4SI 1 "register_operand" "f")
+ (match_operand:V4SI 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)])))]
+ "ISA_HAS_MSA"
+ "pckod.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SI")])
+
+(define_insn "msa_pckod_w_f"
+[(set (match_operand:V4SF 0 "register_operand" "=f")
+ (vec_select:V4SF
+ (vec_concat:V8SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f"))
+ (parallel [(const_int 1) (const_int 3)
+ (const_int 5) (const_int 7)])))]
+ "ISA_HAS_MSA"
+ "pckod.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_permute")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "popcount<mode>2"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (popcount:IMSA (match_operand:IMSA 1 "register_operand" "f")))]
+ "ISA_HAS_MSA"
+ "pcnt.<msafmt>\t%w0,%w1"
+ [(set_attr "type" "simd_pcnt")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_sat_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SAT_S))]
+ "ISA_HAS_MSA"
+ "sat_s.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "simd_sat")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_sat_u_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SAT_U))]
+ "ISA_HAS_MSA"
+ "sat_u.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "simd_sat")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_shf_<msafmt_f>"
+ [(set (match_operand:MSA_WHB_W 0 "register_operand" "=f")
+ (vec_select:MSA_WHB_W
+ (match_operand:MSA_WHB_W 1 "register_operand" "f")
+ (match_operand 2 "par_const_vector_shf_set_operand" "")))]
+ "ISA_HAS_MSA"
+{
+ HOST_WIDE_INT val = 0;
+ unsigned int i;
+
+ /* We convert the selection to an immediate. */
+ for (i = 0; i < 4; i++)
+ val |= INTVAL (XVECEXP (operands[2], 0, i)) << (2 * i);
+
+ operands[2] = GEN_INT (val);
+ return "shf.<msafmt>\t%w0,%w1,%X2";
+}
+ [(set_attr "type" "simd_shf")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_srar_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_SRAR))]
+ "ISA_HAS_MSA"
+ "srar.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_shift")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_srari_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SRARI))]
+ "ISA_HAS_MSA"
+ "srari.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "simd_shift")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_srlr_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_SRLR))]
+ "ISA_HAS_MSA"
+ "srlr.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_shift")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_srlri_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand 2 "const_<bitimm>_operand" "")]
+ UNSPEC_MSA_SRLRI))]
+ "ISA_HAS_MSA"
+ "srlri.<msafmt>\t%w0,%w1,%2"
+ [(set_attr "type" "simd_shift")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_subs_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_SUBS_S))]
+ "ISA_HAS_MSA"
+ "subs_s.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_subs_u_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_SUBS_U))]
+ "ISA_HAS_MSA"
+ "subs_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_subsuu_s_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_SUBSUU_S))]
+ "ISA_HAS_MSA"
+ "subsuu_s.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_subsus_u_<msafmt>"
+ [(set (match_operand:IMSA 0 "register_operand" "=f")
+ (unspec:IMSA [(match_operand:IMSA 1 "register_operand" "f")
+ (match_operand:IMSA 2 "register_operand" "f")]
+ UNSPEC_MSA_SUBSUS_U))]
+ "ISA_HAS_MSA"
+ "subsus_u.<msafmt>\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_int_arith")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_sld_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (unspec:MSA [(match_operand:MSA 1 "register_operand" "0")
+ (match_operand:MSA 2 "register_operand" "f")
+ (match_operand:SI 3 "reg_or_0_operand" "dJ")]
+ UNSPEC_MSA_SLD))]
+ "ISA_HAS_MSA"
+ "sld.<msafmt>\t%w0,%w2[%z3]"
+ [(set_attr "type" "simd_sld")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_sldi_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (unspec:MSA [(match_operand:MSA 1 "register_operand" "0")
+ (match_operand:MSA 2 "register_operand" "f")
+ (match_operand 3 "const_<indeximm>_operand" "")]
+ UNSPEC_MSA_SLDI))]
+ "ISA_HAS_MSA"
+ "sldi.<msafmt>\t%w0,%w2[%3]"
+ [(set_attr "type" "simd_sld")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_splat_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (unspec:MSA [(match_operand:MSA 1 "register_operand" "f")
+ (match_operand:SI 2 "register_operand" "d")]
+ UNSPEC_MSA_SPLAT))]
+ "ISA_HAS_MSA"
+ "splat.<msafmt>\t%w0,%w1[%z2]"
+ [(set_attr "type" "simd_splat")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_splati_<msafmt_f>"
+ [(set (match_operand:MSA 0 "register_operand" "=f")
+ (vec_duplicate:MSA
+ (vec_select:<UNITMODE>
+ (match_operand:MSA 1 "register_operand" "f")
+ (parallel [(match_operand 2 "const_<indeximm>_operand" "")]))))]
+ "ISA_HAS_MSA"
+ "splati.<msafmt>\t%w0,%w1[%2]"
+ [(set_attr "type" "simd_splat")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_splati_<msafmt_f>_scalar"
+ [(set (match_operand:FMSA 0 "register_operand" "=f")
+ (unspec:FMSA [(match_operand:<UNITMODE> 1 "register_operand" "f")]
+ UNSPEC_MSA_SPLATI))]
+ "ISA_HAS_MSA"
+ "splati.<msafmt>\t%w0,%w1[0]"
+ [(set_attr "type" "simd_splat")
+ (set_attr "mode" "<MODE>")])
+
+(define_insn "msa_cfcmsa"
+ [(set (match_operand:SI 0 "register_operand" "=d")
+ (unspec_volatile:SI [(match_operand 1 "const_uimm5_operand" "")]
+ UNSPEC_MSA_CFCMSA))]
+ "ISA_HAS_MSA"
+ "cfcmsa\t%0,$%1"
+ [(set_attr "type" "simd_cmsa")
+ (set_attr "mode" "SI")])
+
+(define_insn "msa_ctcmsa"
+ [(unspec_volatile [(match_operand 0 "const_uimm5_operand" "")
+ (match_operand:SI 1 "register_operand" "d")]
+ UNSPEC_MSA_CTCMSA)]
+ "ISA_HAS_MSA"
+ "ctcmsa\t$%0,%1"
+ [(set_attr "type" "simd_cmsa")
+ (set_attr "mode" "SI")])
+
+(define_insn "msa_fexdo_h"
+ [(set (match_operand:V8HI 0 "register_operand" "=f")
+ (unspec:V8HI [(match_operand:V4SF 1 "register_operand" "f")
+ (match_operand:V4SF 2 "register_operand" "f")]
+ UNSPEC_MSA_FEXDO))]
+ "ISA_HAS_MSA"
+ "fexdo.h\t%w0,%w1,%w2"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "mode" "V8HI")])
+
+(define_insn "vec_pack_trunc_v2df"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (vec_concat:V4SF
+ (float_truncate:V2SF (match_operand:V2DF 1 "register_operand" "f"))
+ (float_truncate:V2SF (match_operand:V2DF 2 "register_operand" "f"))))]
+ "ISA_HAS_MSA"
+ "fexdo.w\t%w0,%w2,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_fexupl_w"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")]
+ UNSPEC_MSA_FEXUPL))]
+ "ISA_HAS_MSA"
+ "fexupl.w\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_fexupl_d"
+ [(set (match_operand:V2DF 0 "register_operand" "=f")
+ (float_extend:V2DF
+ (vec_select:V2SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (parallel [(const_int 2) (const_int 3)]))))]
+ "ISA_HAS_MSA"
+ "fexupl.d\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "mode" "V2DF")])
+
+(define_insn "msa_fexupr_w"
+ [(set (match_operand:V4SF 0 "register_operand" "=f")
+ (unspec:V4SF [(match_operand:V8HI 1 "register_operand" "f")]
+ UNSPEC_MSA_FEXUPR))]
+ "ISA_HAS_MSA"
+ "fexupr.w\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "mode" "V4SF")])
+
+(define_insn "msa_fexupr_d"
+ [(set (match_operand:V2DF 0 "register_operand" "=f")
+ (float_extend:V2DF
+ (vec_select:V2SF
+ (match_operand:V4SF 1 "register_operand" "f")
+ (parallel [(const_int 0) (const_int 1)]))))]
+ "ISA_HAS_MSA"
+ "fexupr.d\t%w0,%w1"
+ [(set_attr "type" "simd_fcvt")
+ (set_attr "mode" "V2DF")])
+
+(define_code_attr msabr
+ [(eq "bz")
+ (ne "bnz")])
+
+(define_code_attr msabr_neg
+ [(eq "bnz")
+ (ne "bz")])
+
+(define_insn "msa_<msabr>_<msafmt_f>"
+ [(set (pc) (if_then_else
+ (equality_op
+ (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+ UNSPEC_MSA_BRANCH)
+ (match_operand:SI 2 "const_0_operand"))
+ (label_ref (match_operand 0))
+ (pc)))]
+ "ISA_HAS_MSA"
+{
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH ("<msabr>.<msafmt>",
+ "%w1,%0"),
+ MIPS_BRANCH ("<msabr_neg>.<msafmt>",
+ "%w1,%0"));
+}
+ [(set_attr "type" "simd_branch")
+ (set_attr "mode" "<MODE>")
+ (set_attr "compact_form" "never")])
+
+(define_insn "msa_<msabr>_v_<msafmt_f>"
+ [(set (pc) (if_then_else
+ (equality_op
+ (unspec:SI [(match_operand:MSA 1 "register_operand" "f")]
+ UNSPEC_MSA_BRANCH_V)
+ (match_operand:SI 2 "const_0_operand"))
+ (label_ref (match_operand 0))
+ (pc)))]
+ "ISA_HAS_MSA"
+{
+ return mips_output_conditional_branch (insn, operands,
+ MIPS_BRANCH ("<msabr>.v", "%w1,%0"),
+ MIPS_BRANCH ("<msabr_neg>.v",
+ "%w1,%0"));
+}
+ [(set_attr "type" "simd_branch")
+ (set_attr "mode" "TI")
+ (set_attr "compact_form" "never")])
diff --git a/gcc/config/mips/mips-protos.h b/gcc/config/mips/mips-protos.h
index 01aad8295b3..09cf6626e27 100644
--- a/gcc/config/mips/mips-protos.h
+++ b/gcc/config/mips/mips-protos.h
@@ -197,8 +197,9 @@ extern bool mips_stack_address_p (rtx, machine_mode);
extern int mips_address_insns (rtx, machine_mode, bool);
extern int mips_const_insns (rtx);
extern int mips_split_const_insns (rtx);
+extern int mips_split_128bit_const_insns (rtx);
extern int mips_load_store_insns (rtx, rtx_insn *);
-extern int mips_idiv_insns (void);
+extern int mips_idiv_insns (machine_mode);
extern rtx_insn *mips_emit_move (rtx, rtx);
#ifdef RTX_CODE
extern void mips_emit_binary (enum rtx_code, rtx, rtx, rtx);
@@ -216,6 +217,11 @@ extern bool mips_split_move_p (rtx, rtx, enum mips_split_type);
extern void mips_split_move (rtx, rtx, enum mips_split_type);
extern bool mips_split_move_insn_p (rtx, rtx, rtx);
extern void mips_split_move_insn (rtx, rtx, rtx);
+extern void mips_split_128bit_move (rtx, rtx);
+extern bool mips_split_128bit_move_p (rtx, rtx);
+extern void mips_split_msa_copy_d (rtx, rtx, rtx, rtx (*)(rtx, rtx, rtx));
+extern void mips_split_msa_insert_d (rtx, rtx, rtx, rtx);
+extern void mips_split_msa_fill_d (rtx, rtx);
extern const char *mips_output_move (rtx, rtx);
extern bool mips_cfun_has_cprestore_slot_p (void);
extern bool mips_cprestore_address_p (rtx, bool);
@@ -278,6 +284,15 @@ extern void mips_expand_before_return (void);
extern void mips_expand_epilogue (bool);
extern bool mips_can_use_return_insn (void);
+extern bool mips_const_vector_same_val_p (rtx, machine_mode);
+extern bool mips_const_vector_same_bytes_p (rtx, machine_mode);
+extern bool mips_const_vector_same_int_p (rtx, machine_mode, HOST_WIDE_INT,
+ HOST_WIDE_INT);
+extern bool mips_const_vector_shuffle_set_p (rtx, machine_mode);
+extern bool mips_const_vector_bitimm_set_p (rtx, machine_mode);
+extern bool mips_const_vector_bitimm_clr_p (rtx, machine_mode);
+extern rtx mips_msa_vec_parallel_const_half (machine_mode, bool);
+extern rtx mips_gen_const_int_vector (machine_mode, int);
extern bool mips_secondary_memory_needed (enum reg_class, enum reg_class,
machine_mode);
extern bool mips_cannot_change_mode_class (machine_mode,
@@ -305,6 +320,7 @@ extern const char *mips_output_sync (void);
extern const char *mips_output_sync_loop (rtx_insn *, rtx *);
extern unsigned int mips_sync_loop_insns (rtx_insn *, rtx *);
extern const char *mips_output_division (const char *, rtx *);
+extern const char *mips_msa_output_division (const char *, rtx *);
extern const char *mips_output_probe_stack_range (rtx, rtx);
extern bool mips_hard_regno_rename_ok (unsigned int, unsigned int);
extern unsigned int mips_hard_regno_nregs (int, machine_mode);
@@ -343,6 +359,7 @@ extern void mips_expand_vec_reduc (rtx, rtx, rtx (*)(rtx, rtx, rtx));
extern void mips_expand_vec_minmax (rtx, rtx, rtx,
rtx (*) (rtx, rtx, rtx), bool);
+extern int mips_ldst_scaled_shift (machine_mode);
extern bool mips_signed_immediate_p (unsigned HOST_WIDE_INT, int, int);
extern bool mips_unsigned_immediate_p (unsigned HOST_WIDE_INT, int, int);
extern const char *umips_output_save_restore (bool, rtx);
@@ -372,5 +389,6 @@ extern mulsidi3_gen_fn mips_mulsidi3_gen_fn (enum rtx_code);
#endif
extern void mips_register_frame_header_opt (void);
+extern void mips_expand_vec_cond_expr (machine_mode, machine_mode, rtx *);
#endif /* ! GCC_MIPS_PROTOS_H */
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 399f231791d..06acd30ec25 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -244,6 +244,10 @@ enum mips_builtin_type {
/* As above, but the instruction only sets a single $fcc register. */
MIPS_BUILTIN_CMP_SINGLE,
+ /* The function corresponds to an MSA conditional branch instruction
+ combined with a compare instruction. */
+ MIPS_BUILTIN_MSA_TEST_BRANCH,
+
/* For generating bposge32 branch instructions in MIPS32 DSP ASE. */
MIPS_BUILTIN_BPOSGE32
};
@@ -1126,6 +1130,7 @@ static int mips_register_move_cost (machine_mode, reg_class_t,
reg_class_t);
static unsigned int mips_function_arg_boundary (machine_mode, const_tree);
static machine_mode mips_get_reg_raw_mode (int regno);
+static rtx mips_gen_const_int_vector_shuffle (machine_mode, int);
/* This hash table keeps track of implicit "mips16" and "nomips16" attributes
for -mflip_mips16. It maps decl names onto a boolean mode setting. */
@@ -1835,6 +1840,140 @@ mips_symbol_binds_local_p (const_rtx x)
: SYMBOL_REF_LOCAL_P (x));
}
+/* Return true if OP is a constant vector with the number of units in MODE,
+ and each unit has the same bit set. */
+
+bool
+mips_const_vector_bitimm_set_p (rtx op, machine_mode mode)
+{
+ if (GET_CODE (op) == CONST_VECTOR && op != CONST0_RTX (mode))
+ {
+ unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (op, 0));
+ int vlog2 = exact_log2 (val & GET_MODE_MASK (GET_MODE_INNER (mode)));
+
+ if (vlog2 != -1)
+ {
+ gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
+ gcc_assert (vlog2 >= 0 && vlog2 <= GET_MODE_UNIT_BITSIZE (mode) - 1);
+ return mips_const_vector_same_val_p (op, mode);
+ }
+ }
+
+ return false;
+}
+
+/* Return true if OP is a constant vector with the number of units in MODE,
+ and each unit has the same bit clear. */
+
+bool
+mips_const_vector_bitimm_clr_p (rtx op, machine_mode mode)
+{
+ if (GET_CODE (op) == CONST_VECTOR && op != CONSTM1_RTX (mode))
+ {
+ unsigned HOST_WIDE_INT val = ~UINTVAL (CONST_VECTOR_ELT (op, 0));
+ int vlog2 = exact_log2 (val & GET_MODE_MASK (GET_MODE_INNER (mode)));
+
+ if (vlog2 != -1)
+ {
+ gcc_assert (GET_MODE_CLASS (mode) == MODE_VECTOR_INT);
+ gcc_assert (vlog2 >= 0 && vlog2 <= GET_MODE_UNIT_BITSIZE (mode) - 1);
+ return mips_const_vector_same_val_p (op, mode);
+ }
+ }
+
+ return false;
+}
+
+/* Return true if OP is a constant vector with the number of units in MODE,
+ and each unit has the same value. */
+
+bool
+mips_const_vector_same_val_p (rtx op, machine_mode mode)
+{
+ int i, nunits = GET_MODE_NUNITS (mode);
+ rtx first;
+
+ if (GET_CODE (op) != CONST_VECTOR || GET_MODE (op) != mode)
+ return false;
+
+ first = CONST_VECTOR_ELT (op, 0);
+ for (i = 1; i < nunits; i++)
+ if (!rtx_equal_p (first, CONST_VECTOR_ELT (op, i)))
+ return false;
+
+ return true;
+}
+
+/* Return true if OP is a constant vector with the number of units in MODE,
+ and each unit has the same value as well as replicated bytes in the value.
+*/
+
+bool
+mips_const_vector_same_bytes_p (rtx op, machine_mode mode)
+{
+ int i, bytes;
+ HOST_WIDE_INT val, first_byte;
+ rtx first;
+
+ if (!mips_const_vector_same_val_p (op, mode))
+ return false;
+
+ first = CONST_VECTOR_ELT (op, 0);
+ bytes = GET_MODE_UNIT_SIZE (mode);
+ val = INTVAL (first);
+ first_byte = val & 0xff;
+ for (i = 1; i < bytes; i++)
+ {
+ val >>= 8;
+ if ((val & 0xff) != first_byte)
+ return false;
+ }
+
+ return true;
+}
+
+/* Return true if OP is a constant vector with the number of units in MODE,
+ and each unit has the same integer value in the range [LOW, HIGH]. */
+
+bool
+mips_const_vector_same_int_p (rtx op, machine_mode mode, HOST_WIDE_INT low,
+ HOST_WIDE_INT high)
+{
+ HOST_WIDE_INT value;
+ rtx elem0;
+
+ if (!mips_const_vector_same_val_p (op, mode))
+ return false;
+
+ elem0 = CONST_VECTOR_ELT (op, 0);
+ if (!CONST_INT_P (elem0))
+ return false;
+
+ value = INTVAL (elem0);
+ return (value >= low && value <= high);
+}
+
+/* Return true if OP is a constant vector with repeated 4-element sets
+ in mode MODE. */
+
+bool
+mips_const_vector_shuffle_set_p (rtx op, machine_mode mode)
+{
+ int nunits = GET_MODE_NUNITS (mode);
+ int nsets = nunits / 4;
+ int set = 0;
+ int i, j;
+
+ /* Check if we have the same 4-element sets. */
+ for (j = 0; j < nsets; j++, set = 4 * j)
+ for (i = 0; i < 4; i++)
+ if ((INTVAL (XVECEXP (op, 0, i))
+ != (INTVAL (XVECEXP (op, 0, set + i)) - set))
+ || !IN_RANGE (INTVAL (XVECEXP (op, 0, set + i)), 0, set + 3))
+ return false;
+ return true;
+}
+
/* Return true if rtx constants of mode MODE should be put into a small
data section. */
@@ -2206,6 +2345,11 @@ mips_symbol_insns_1 (enum mips_symbol_type type, machine_mode mode)
static int
mips_symbol_insns (enum mips_symbol_type type, machine_mode mode)
{
+ /* MSA LD.* and ST.* cannot support loading symbols via an immediate
+ operand. */
+ if (MSA_SUPPORTED_MODE_P (mode))
+ return 0;
+
return mips_symbol_insns_1 (type, mode) * (TARGET_MIPS16 ? 2 : 1);
}
@@ -2325,6 +2469,12 @@ mips_valid_offset_p (rtx x, machine_mode mode)
&& !SMALL_OPERAND (INTVAL (x) + GET_MODE_SIZE (mode) - UNITS_PER_WORD))
return false;
+ /* MSA LD.* and ST.* supports 10-bit signed offsets. */
+ if (MSA_SUPPORTED_MODE_P (mode)
+ && !mips_signed_immediate_p (INTVAL (x), 10,
+ mips_ldst_scaled_shift (mode)))
+ return false;
+
return true;
}
@@ -2351,6 +2501,10 @@ mips_valid_lo_sum_p (enum mips_symbol_type symbol_type, machine_mode mode)
&& GET_MODE_BITSIZE (mode) > GET_MODE_ALIGNMENT (mode))
return false;
+ /* MSA LD.* and ST.* cannot support loading symbols via %lo($base). */
+ if (MSA_SUPPORTED_MODE_P (mode))
+ return false;
+
return true;
}
@@ -2480,6 +2634,8 @@ mips_lx_address_p (rtx addr, machine_mode mode)
return true;
if (ISA_HAS_LDX && mode == DImode)
return true;
+ if (MSA_SUPPORTED_MODE_P (mode))
+ return true;
return false;
}
@@ -2517,6 +2673,7 @@ mips_address_insns (rtx x, machine_mode mode, bool might_split_p)
{
struct mips_address_info addr;
int factor;
+ bool msa_p = (!might_split_p && MSA_SUPPORTED_MODE_P (mode));
/* BLKmode is used for single unaligned loads and stores and should
not count as a multiword mode. (GET_MODE_SIZE (BLKmode) is pretty
@@ -2531,6 +2688,15 @@ mips_address_insns (rtx x, machine_mode mode, bool might_split_p)
switch (addr.type)
{
case ADDRESS_REG:
+ if (msa_p)
+ {
+ /* MSA LD.* and ST.* supports 10-bit signed offsets. */
+ if (mips_signed_immediate_p (INTVAL (addr.offset), 10,
+ mips_ldst_scaled_shift (mode)))
+ return 1;
+ else
+ return 0;
+ }
if (TARGET_MIPS16
&& !mips16_unextended_reference_p (mode, addr.reg,
UINTVAL (addr.offset)))
@@ -2538,13 +2704,13 @@ mips_address_insns (rtx x, machine_mode mode, bool might_split_p)
return factor;
case ADDRESS_LO_SUM:
- return TARGET_MIPS16 ? factor * 2 : factor;
+ return msa_p ? 0 : TARGET_MIPS16 ? factor * 2 : factor;
case ADDRESS_CONST_INT:
- return factor;
+ return msa_p ? 0 : factor;
case ADDRESS_SYMBOLIC:
- return factor * mips_symbol_insns (addr.symbol_type, mode);
+ return msa_p ? 0 : factor * mips_symbol_insns (addr.symbol_type, mode);
}
return 0;
}
@@ -2568,6 +2734,19 @@ mips_signed_immediate_p (unsigned HOST_WIDE_INT x, int bits, int shift = 0)
return mips_unsigned_immediate_p (x, bits, shift);
}
+/* Return the scale shift that applied to MSA LD/ST address offset. */
+
+int
+mips_ldst_scaled_shift (machine_mode mode)
+{
+ int shift = exact_log2 (GET_MODE_UNIT_SIZE (mode));
+
+ if (shift < 0 || shift > 8)
+ gcc_unreachable ();
+
+ return shift;
+}
+
/* Return true if X is legitimate for accessing values of mode MODE,
if it is based on a MIPS16 register, and if the offset satisfies
OFFSET_PREDICATE. */
@@ -2663,8 +2842,12 @@ mips_const_insns (rtx x)
return mips_build_integer (codes, INTVAL (x));
- case CONST_DOUBLE:
case CONST_VECTOR:
+ if (ISA_HAS_MSA
+ && mips_const_vector_same_int_p (x, GET_MODE (x), -512, 511))
+ return 1;
+ /* Fall through. */
+ case CONST_DOUBLE:
/* Allow zeros for normal mode, where we can use $0. */
return !TARGET_MIPS16 && x == CONST0_RTX (GET_MODE (x)) ? 1 : 0;
@@ -2724,6 +2907,26 @@ mips_split_const_insns (rtx x)
return low + high;
}
+/* Return one word of 128-bit value OP, taking into account the fixed
+ endianness of certain registers. BYTE selects from the byte address. */
+
+rtx
+mips_subword_at_byte (rtx op, unsigned int byte)
+{
+ machine_mode mode;
+
+ mode = GET_MODE (op);
+ if (mode == VOIDmode)
+ mode = TImode;
+
+ gcc_assert (!FP_REG_RTX_P (op));
+
+ if (MEM_P (op))
+ return mips_rewrite_small_data (adjust_address (op, word_mode, byte));
+
+ return simplify_gen_subreg (word_mode, op, mode, byte);
+}
+
/* Return the number of instructions needed to implement INSN,
given that it loads from or stores to MEM. Assume that
BASE_INSN_LENGTH is the length of one instruction. */
@@ -2754,14 +2957,14 @@ mips_load_store_insns (rtx mem, rtx_insn *insn)
assuming that BASE_INSN_LENGTH is the length of one instruction. */
int
-mips_idiv_insns (void)
+mips_idiv_insns (machine_mode mode)
{
int count;
count = 1;
if (TARGET_CHECK_ZERO_DIV)
{
- if (GENERATE_DIVIDE_TRAPS)
+ if (GENERATE_DIVIDE_TRAPS && !MSA_SUPPORTED_MODE_P (mode))
count++;
else
count += 2;
@@ -2771,6 +2974,7 @@ mips_idiv_insns (void)
count++;
return count;
}
+
/* Emit a move from SRC to DEST. Assume that the move expanders can
handle all moves if !can_create_pseudo_p (). The distinction is
@@ -3478,7 +3682,14 @@ mips_legitimize_const_move (machine_mode mode, rtx dest, rtx src)
bool
mips_legitimize_move (machine_mode mode, rtx dest, rtx src)
{
- if (!register_operand (dest, mode) && !reg_or_0_operand (src, mode))
+ /* Both src and dest are non-registers; one special case is supported where
+ the source is (const_int 0) and the store can source the zero register.
+ MIPS16 and MSA are never able to source the zero register directly in
+ memory operations. */
+ if (!register_operand (dest, mode)
+ && !register_operand (src, mode)
+ && (TARGET_MIPS16 || !const_0_operand (src, mode)
+ || MSA_SUPPORTED_MODE_P (mode)))
{
mips_emit_move (dest, force_reg (mode, src));
return true;
@@ -4044,6 +4255,10 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
case NE:
case UNORDERED:
case LTGT:
+ case UNGE:
+ case UNGT:
+ case UNLE:
+ case UNLT:
/* Branch comparisons have VOIDmode, so use the first operand's
mode instead. */
mode = GET_MODE (XEXP (x, 0));
@@ -4208,7 +4423,7 @@ mips_rtx_costs (rtx x, machine_mode mode, int outer_code,
*total += set_src_cost (XEXP (x, 0), mode, speed);
return true;
}
- *total = COSTS_N_INSNS (mips_idiv_insns ());
+ *total = COSTS_N_INSNS (mips_idiv_insns (mode));
}
else if (mode == DImode)
*total = mips_cost->int_div_di;
@@ -4514,6 +4729,10 @@ mips_split_move_p (rtx dest, rtx src, enum mips_split_type split_type)
return false;
}
+ /* Check if MSA moves need splitting. */
+ if (MSA_SUPPORTED_MODE_P (GET_MODE (dest)))
+ return mips_split_128bit_move_p (dest, src);
+
/* Otherwise split all multiword moves. */
return size > UNITS_PER_WORD;
}
@@ -4527,7 +4746,9 @@ mips_split_move (rtx dest, rtx src, enum mips_split_type split_type)
rtx low_dest;
gcc_checking_assert (mips_split_move_p (dest, src, split_type));
- if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src))
+ if (MSA_SUPPORTED_MODE_P (GET_MODE (dest)))
+ mips_split_128bit_move (dest, src);
+ else if (FP_REG_RTX_P (dest) || FP_REG_RTX_P (src))
{
if (!TARGET_64BIT && GET_MODE (dest) == DImode)
emit_insn (gen_move_doubleword_fprdi (dest, src));
@@ -4600,6 +4821,199 @@ mips_insn_split_type (rtx insn)
return SPLIT_IF_NECESSARY;
}
+/* Return true if a 128-bit move from SRC to DEST should be split. */
+
+bool
+mips_split_128bit_move_p (rtx dest, rtx src)
+{
+ /* MSA-to-MSA moves can be done in a single instruction. */
+ if (FP_REG_RTX_P (src) && FP_REG_RTX_P (dest))
+ return false;
+
+ /* Check for MSA loads and stores. */
+ if (FP_REG_RTX_P (dest) && MEM_P (src))
+ return false;
+ if (FP_REG_RTX_P (src) && MEM_P (dest))
+ return false;
+
+ /* Check for MSA set to an immediate const vector with valid replicated
+ element. */
+ if (FP_REG_RTX_P (dest)
+ && mips_const_vector_same_int_p (src, GET_MODE (src), -512, 511))
+ return false;
+
+ /* Check for MSA load zero immediate. */
+ if (FP_REG_RTX_P (dest) && src == CONST0_RTX (GET_MODE (src)))
+ return false;
+
+ return true;
+}
+
+/* Split a 128-bit move from SRC to DEST. */
+
+void
+mips_split_128bit_move (rtx dest, rtx src)
+{
+ int byte, index;
+ rtx low_dest, low_src, d, s;
+
+ if (FP_REG_RTX_P (dest))
+ {
+ gcc_assert (!MEM_P (src));
+
+ rtx new_dest = dest;
+ if (!TARGET_64BIT)
+ {
+ if (GET_MODE (dest) != V4SImode)
+ new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
+ }
+ else
+ {
+ if (GET_MODE (dest) != V2DImode)
+ new_dest = simplify_gen_subreg (V2DImode, dest, GET_MODE (dest), 0);
+ }
+
+ for (byte = 0, index = 0; byte < GET_MODE_SIZE (TImode);
+ byte += UNITS_PER_WORD, index++)
+ {
+ s = mips_subword_at_byte (src, byte);
+ if (!TARGET_64BIT)
+ emit_insn (gen_msa_insert_w (new_dest, s, new_dest,
+ GEN_INT (1 << index)));
+ else
+ emit_insn (gen_msa_insert_d (new_dest, s, new_dest,
+ GEN_INT (1 << index)));
+ }
+ }
+ else if (FP_REG_RTX_P (src))
+ {
+ gcc_assert (!MEM_P (dest));
+
+ rtx new_src = src;
+ if (!TARGET_64BIT)
+ {
+ if (GET_MODE (src) != V4SImode)
+ new_src = simplify_gen_subreg (V4SImode, src, GET_MODE (src), 0);
+ }
+ else
+ {
+ if (GET_MODE (src) != V2DImode)
+ new_src = simplify_gen_subreg (V2DImode, src, GET_MODE (src), 0);
+ }
+
+ for (byte = 0, index = 0; byte < GET_MODE_SIZE (TImode);
+ byte += UNITS_PER_WORD, index++)
+ {
+ d = mips_subword_at_byte (dest, byte);
+ if (!TARGET_64BIT)
+ emit_insn (gen_msa_copy_s_w (d, new_src, GEN_INT (index)));
+ else
+ emit_insn (gen_msa_copy_s_d (d, new_src, GEN_INT (index)));
+ }
+ }
+ else
+ {
+ low_dest = mips_subword_at_byte (dest, 0);
+ low_src = mips_subword_at_byte (src, 0);
+ gcc_assert (REG_P (low_dest) && REG_P (low_src));
+ /* Make sure the source register is not written before reading. */
+ if (REGNO (low_dest) <= REGNO (low_src))
+ {
+ for (byte = 0; byte < GET_MODE_SIZE (TImode);
+ byte += UNITS_PER_WORD)
+ {
+ d = mips_subword_at_byte (dest, byte);
+ s = mips_subword_at_byte (src, byte);
+ mips_emit_move (d, s);
+ }
+ }
+ else
+ {
+ for (byte = GET_MODE_SIZE (TImode) - UNITS_PER_WORD; byte >= 0;
+ byte -= UNITS_PER_WORD)
+ {
+ d = mips_subword_at_byte (dest, byte);
+ s = mips_subword_at_byte (src, byte);
+ mips_emit_move (d, s);
+ }
+ }
+ }
+}
+
+/* Split a COPY_S.D with operands DEST, SRC and INDEX. GEN is a function
+ used to generate subregs. */
+
+void
+mips_split_msa_copy_d (rtx dest, rtx src, rtx index,
+ rtx (*gen_fn)(rtx, rtx, rtx))
+{
+ gcc_assert ((GET_MODE (src) == V2DImode && GET_MODE (dest) == DImode)
+ || (GET_MODE (src) == V2DFmode && GET_MODE (dest) == DFmode));
+
+ /* Note that low is always from the lower index, and high is always
+ from the higher index. */
+ rtx low = mips_subword (dest, false);
+ rtx high = mips_subword (dest, true);
+ rtx new_src = simplify_gen_subreg (V4SImode, src, GET_MODE (src), 0);
+
+ emit_insn (gen_fn (low, new_src, GEN_INT (INTVAL (index) * 2)));
+ emit_insn (gen_fn (high, new_src, GEN_INT (INTVAL (index) * 2 + 1)));
+}
+
+/* Split a INSERT.D with operand DEST, SRC1.INDEX and SRC2. */
+
+void
+mips_split_msa_insert_d (rtx dest, rtx src1, rtx index, rtx src2)
+{
+ int i;
+ gcc_assert (GET_MODE (dest) == GET_MODE (src1));
+ gcc_assert ((GET_MODE (dest) == V2DImode
+ && (GET_MODE (src2) == DImode || src2 == const0_rtx))
+ || (GET_MODE (dest) == V2DFmode && GET_MODE (src2) == DFmode));
+
+ /* Note that low is always from the lower index, and high is always
+ from the higher index. */
+ rtx low = mips_subword (src2, false);
+ rtx high = mips_subword (src2, true);
+ rtx new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
+ rtx new_src1 = simplify_gen_subreg (V4SImode, src1, GET_MODE (src1), 0);
+ i = exact_log2 (INTVAL (index));
+ gcc_assert (i != -1);
+
+ emit_insn (gen_msa_insert_w (new_dest, low, new_src1,
+ GEN_INT (1 << (i * 2))));
+ emit_insn (gen_msa_insert_w (new_dest, high, new_dest,
+ GEN_INT (1 << (i * 2 + 1))));
+}
+
+/* Split FILL.D. */
+
+void
+mips_split_msa_fill_d (rtx dest, rtx src)
+{
+ gcc_assert ((GET_MODE (dest) == V2DImode
+ && (GET_MODE (src) == DImode || src == const0_rtx))
+ || (GET_MODE (dest) == V2DFmode && GET_MODE (src) == DFmode));
+
+ /* Note that low is always from the lower index, and high is always
+ from the higher index. */
+ rtx low, high;
+ if (src == const0_rtx)
+ {
+ low = src;
+ high = src;
+ }
+ else
+ {
+ low = mips_subword (src, false);
+ high = mips_subword (src, true);
+ }
+ rtx new_dest = simplify_gen_subreg (V4SImode, dest, GET_MODE (dest), 0);
+ emit_insn (gen_msa_fill_w (new_dest, low));
+ emit_insn (gen_msa_insert_w (new_dest, high, new_dest, GEN_INT (1 << 1)));
+ emit_insn (gen_msa_insert_w (new_dest, high, new_dest, GEN_INT (1 << 3)));
+}
+
/* Return true if a move from SRC to DEST in INSN should be split. */
bool
@@ -4623,19 +5037,25 @@ mips_split_move_insn (rtx dest, rtx src, rtx insn)
const char *
mips_output_move (rtx dest, rtx src)
{
- enum rtx_code dest_code, src_code;
- machine_mode mode;
+ enum rtx_code dest_code = GET_CODE (dest);
+ enum rtx_code src_code = GET_CODE (src);
+ machine_mode mode = GET_MODE (dest);
+ bool dbl_p = (GET_MODE_SIZE (mode) == 8);
+ bool msa_p = MSA_SUPPORTED_MODE_P (mode);
enum mips_symbol_type symbol_type;
- bool dbl_p;
-
- dest_code = GET_CODE (dest);
- src_code = GET_CODE (src);
- mode = GET_MODE (dest);
- dbl_p = (GET_MODE_SIZE (mode) == 8);
if (mips_split_move_p (dest, src, SPLIT_IF_NECESSARY))
return "#";
+ if (msa_p
+ && dest_code == REG && FP_REG_P (REGNO (dest))
+ && src_code == CONST_VECTOR
+ && CONST_INT_P (CONST_VECTOR_ELT (src, 0)))
+ {
+ gcc_assert (mips_const_vector_same_int_p (src, mode, -512, 511));
+ return "ldi.%v0\t%w0,%E1";
+ }
+
if ((src_code == REG && GP_REG_P (REGNO (src)))
|| (!TARGET_MIPS16 && src == CONST0_RTX (mode)))
{
@@ -4666,7 +5086,15 @@ mips_output_move (rtx dest, rtx src)
}
if (FP_REG_P (REGNO (dest)))
- return dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0";
+ {
+ if (msa_p)
+ {
+ gcc_assert (src == CONST0_RTX (GET_MODE (src)));
+ return "ldi.%v0\t%w0,0";
+ }
+
+ return dbl_p ? "dmtc1\t%z1,%0" : "mtc1\t%z1,%0";
+ }
if (ALL_COP_REG_P (REGNO (dest)))
{
@@ -4683,6 +5111,7 @@ mips_output_move (rtx dest, rtx src)
case 2: return "sh\t%z1,%0";
case 4: return "sw\t%z1,%0";
case 8: return "sd\t%z1,%0";
+ default: gcc_unreachable ();
}
}
if (dest_code == REG && GP_REG_P (REGNO (dest)))
@@ -4711,7 +5140,10 @@ mips_output_move (rtx dest, rtx src)
}
if (FP_REG_P (REGNO (src)))
- return dbl_p ? "dmfc1\t%0,%1" : "mfc1\t%0,%1";
+ {
+ gcc_assert (!msa_p);
+ return dbl_p ? "dmfc1\t%0,%1" : "mfc1\t%0,%1";
+ }
if (ALL_COP_REG_P (REGNO (src)))
{
@@ -4729,6 +5161,7 @@ mips_output_move (rtx dest, rtx src)
case 2: return "lhu\t%0,%1";
case 4: return "lw\t%0,%1";
case 8: return "ld\t%0,%1";
+ default: gcc_unreachable ();
}
if (src_code == CONST_INT)
@@ -4775,17 +5208,29 @@ mips_output_move (rtx dest, rtx src)
{
if (GET_MODE (dest) == V2SFmode)
return "mov.ps\t%0,%1";
+ else if (msa_p)
+ return "move.v\t%w0,%w1";
else
return dbl_p ? "mov.d\t%0,%1" : "mov.s\t%0,%1";
}
if (dest_code == MEM)
- return dbl_p ? "sdc1\t%1,%0" : "swc1\t%1,%0";
+ {
+ if (msa_p)
+ return "st.%v1\t%w1,%0";
+
+ return dbl_p ? "sdc1\t%1,%0" : "swc1\t%1,%0";
+ }
}
if (dest_code == REG && FP_REG_P (REGNO (dest)))
{
if (src_code == MEM)
- return dbl_p ? "ldc1\t%0,%1" : "lwc1\t%0,%1";
+ {
+ if (msa_p)
+ return "ld.%v0\t%w0,%1";
+
+ return dbl_p ? "ldc1\t%0,%1" : "lwc1\t%0,%1";
+ }
}
if (dest_code == REG && ALL_COP_REG_P (REGNO (dest)) && src_code == MEM)
{
@@ -8455,10 +8900,14 @@ mips_print_operand_punct_valid_p (unsigned char code)
/* Implement TARGET_PRINT_OPERAND. The MIPS-specific operand codes are:
+ 'E' Print CONST_INT OP element 0 of a replicated CONST_VECTOR in decimal.
'X' Print CONST_INT OP in hexadecimal format.
'x' Print the low 16 bits of CONST_INT OP in hexadecimal format.
'd' Print CONST_INT OP in decimal.
+ 'B' Print CONST_INT OP element 0 of a replicated CONST_VECTOR
+ as an unsigned byte [0..255].
'm' Print one less than CONST_INT OP in decimal.
+ 'y' Print exact log2 of CONST_INT OP in decimal.
'h' Print the high-part relocation associated with OP, after stripping
any outermost HIGH.
'R' Print the low-part relocation associated with OP.
@@ -8466,6 +8915,7 @@ mips_print_operand_punct_valid_p (unsigned char code)
'N' Print the inverse of the integer branch condition for comparison OP.
'F' Print the FPU branch condition for comparison OP.
'W' Print the inverse of the FPU branch condition for comparison OP.
+ 'w' Print a MSA register.
'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...),
'z' for (eq:?I ...), 'n' for (ne:?I ...).
't' Like 'T', but with the EQ/NE cases reversed
@@ -8476,7 +8926,11 @@ mips_print_operand_punct_valid_p (unsigned char code)
'L' Print the low-order register in a double-word register operand.
'M' Print high-order register in a double-word register operand.
'z' Print $0 if OP is zero, otherwise print OP normally.
- 'b' Print the address of a memory operand, without offset. */
+ 'b' Print the address of a memory operand, without offset.
+ 'v' Print the insn size suffix b, h, w or d for vector modes V16QI, V8HI,
+ V4SI, V2SI, and w, d for vector modes V4SF, V2DF respectively.
+ 'V' Print exact log2 of CONST_INT OP element 0 of a replicated
+ CONST_VECTOR in decimal. */
static void
mips_print_operand (FILE *file, rtx op, int letter)
@@ -8494,6 +8948,18 @@ mips_print_operand (FILE *file, rtx op, int letter)
switch (letter)
{
+ case 'E':
+ if (GET_CODE (op) == CONST_VECTOR)
+ {
+ gcc_assert (mips_const_vector_same_val_p (op, GET_MODE (op)));
+ op = CONST_VECTOR_ELT (op, 0);
+ gcc_assert (CONST_INT_P (op));
+ fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op));
+ }
+ else
+ output_operand_lossage ("invalid use of '%%%c'", letter);
+ break;
+
case 'X':
if (CONST_INT_P (op))
fprintf (file, HOST_WIDE_INT_PRINT_HEX, INTVAL (op));
@@ -8515,6 +8981,19 @@ mips_print_operand (FILE *file, rtx op, int letter)
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
+ case 'B':
+ if (GET_CODE (op) == CONST_VECTOR)
+ {
+ gcc_assert (mips_const_vector_same_val_p (op, GET_MODE (op)));
+ op = CONST_VECTOR_ELT (op, 0);
+ gcc_assert (CONST_INT_P (op));
+ unsigned HOST_WIDE_INT val8 = UINTVAL (op) & GET_MODE_MASK (QImode);
+ fprintf (file, HOST_WIDE_INT_PRINT_UNSIGNED, val8);
+ }
+ else
+ output_operand_lossage ("invalid use of '%%%c'", letter);
+ break;
+
case 'm':
if (CONST_INT_P (op))
fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (op) - 1);
@@ -8522,6 +9001,34 @@ mips_print_operand (FILE *file, rtx op, int letter)
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
+ case 'y':
+ if (CONST_INT_P (op))
+ {
+ int val = exact_log2 (INTVAL (op));
+ if (val != -1)
+ fprintf (file, "%d", val);
+ else
+ output_operand_lossage ("invalid use of '%%%c'", letter);
+ }
+ else
+ output_operand_lossage ("invalid use of '%%%c'", letter);
+ break;
+
+ case 'V':
+ if (GET_CODE (op) == CONST_VECTOR)
+ {
+ machine_mode mode = GET_MODE_INNER (GET_MODE (op));
+ unsigned HOST_WIDE_INT val = UINTVAL (CONST_VECTOR_ELT (op, 0));
+ int vlog2 = exact_log2 (val & GET_MODE_MASK (mode));
+ if (vlog2 != -1)
+ fprintf (file, "%d", vlog2);
+ else
+ output_operand_lossage ("invalid use of '%%%c'", letter);
+ }
+ else
+ output_operand_lossage ("invalid use of '%%%c'", letter);
+ break;
+
case 'h':
if (code == HIGH)
op = XEXP (op, 0);
@@ -8582,6 +9089,35 @@ mips_print_operand (FILE *file, rtx op, int letter)
output_operand_lossage ("invalid use of '%%%c'", letter);
break;
+ case 'w':
+ if (code == REG && MSA_REG_P (REGNO (op)))
+ fprintf (file, "$w%s", &reg_names[REGNO (op)][2]);
+ else
+ output_operand_lossage ("invalid use of '%%%c'", letter);
+ break;
+
+ case 'v':
+ switch (GET_MODE (op))
+ {
+ case V16QImode:
+ fprintf (file, "b");
+ break;
+ case V8HImode:
+ fprintf (file, "h");
+ break;
+ case V4SImode:
+ case V4SFmode:
+ fprintf (file, "w");
+ break;
+ case V2DImode:
+ case V2DFmode:
+ fprintf (file, "d");
+ break;
+ default:
+ output_operand_lossage ("invalid use of '%%%c'", letter);
+ }
+ break;
+
default:
switch (code)
{
@@ -9316,6 +9852,10 @@ mips_file_start (void)
attr = 1;
fprintf (asm_out_file, "\t.gnu_attribute 4, %d\n", attr);
+
+ /* 128-bit MSA. */
+ if (ISA_HAS_MSA)
+ fprintf (asm_out_file, "\t.gnu_attribute 8, 1\n");
}
#endif
#endif
@@ -12159,9 +12699,13 @@ mips_hard_regno_mode_ok_p (unsigned int regno, machine_mode mode)
size = GET_MODE_SIZE (mode);
mclass = GET_MODE_CLASS (mode);
- if (GP_REG_P (regno) && mode != CCFmode)
+ if (GP_REG_P (regno) && mode != CCFmode && !MSA_SUPPORTED_MODE_P (mode))
return ((regno - GP_REG_FIRST) & 1) == 0 || size <= UNITS_PER_WORD;
+ /* For MSA, allow TImode and 128-bit vector modes in all FPR. */
+ if (FP_REG_P (regno) && MSA_SUPPORTED_MODE_P (mode))
+ return true;
+
if (FP_REG_P (regno)
&& (((regno - FP_REG_FIRST) % MAX_FPRS_PER_FMT) == 0
|| (MIN_FPRS_PER_FMT == 1 && size <= UNITS_PER_FPREG)))
@@ -12277,7 +12821,12 @@ mips_hard_regno_nregs (int regno, machine_mode mode)
return (GET_MODE_SIZE (mode) + 3) / 4;
if (FP_REG_P (regno))
- return (GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG;
+ {
+ if (MSA_SUPPORTED_MODE_P (mode))
+ return 1;
+
+ return (GET_MODE_SIZE (mode) + UNITS_PER_FPREG - 1) / UNITS_PER_FPREG;
+ }
/* All other registers are word-sized. */
return (GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
@@ -12298,12 +12847,19 @@ mips_class_max_nregs (enum reg_class rclass, machine_mode mode)
{
if (HARD_REGNO_MODE_OK (ST_REG_FIRST, mode))
size = MIN (size, 4);
+
AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) ST_REGS]);
}
if (hard_reg_set_intersect_p (left, reg_class_contents[(int) FP_REGS]))
{
if (HARD_REGNO_MODE_OK (FP_REG_FIRST, mode))
- size = MIN (size, UNITS_PER_FPREG);
+ {
+ if (MSA_SUPPORTED_MODE_P (mode))
+ size = MIN (size, UNITS_PER_MSA_REG);
+ else
+ size = MIN (size, UNITS_PER_FPREG);
+ }
+
AND_COMPL_HARD_REG_SET (left, reg_class_contents[(int) FP_REGS]);
}
if (!hard_reg_set_empty_p (left))
@@ -12324,6 +12880,10 @@ mips_cannot_change_mode_class (machine_mode from,
&& INTEGRAL_MODE_P (from) && INTEGRAL_MODE_P (to))
return false;
+ /* Allow conversions between different MSA vector modes. */
+ if (MSA_SUPPORTED_MODE_P (from) && MSA_SUPPORTED_MODE_P (to))
+ return false;
+
/* Otherwise, there are several problems with changing the modes of
values in floating-point registers:
@@ -12359,7 +12919,8 @@ mips_small_register_classes_for_mode_p (machine_mode mode
return TARGET_MIPS16;
}
-/* Return true if moves in mode MODE can use the FPU's mov.fmt instruction. */
+/* Return true if moves in mode MODE can use the FPU's mov.fmt instruction,
+ or use the MSA's move.v instruction. */
static bool
mips_mode_ok_for_mov_fmt_p (machine_mode mode)
@@ -12377,7 +12938,7 @@ mips_mode_ok_for_mov_fmt_p (machine_mode mode)
return TARGET_HARD_FLOAT && TARGET_PAIRED_SINGLE_FLOAT;
default:
- return false;
+ return MSA_SUPPORTED_MODE_P (mode);
}
}
@@ -12624,6 +13185,10 @@ mips_secondary_reload_class (enum reg_class rclass,
pairs of lwc1s and swc1s if ldc1 and sdc1 are not supported. */
return NO_REGS;
+ if (MEM_P (x) && MSA_SUPPORTED_MODE_P (mode))
+ /* In this case we can use MSA LD.* and ST.*. */
+ return NO_REGS;
+
if (GP_REG_P (regno) || x == CONST0_RTX (mode))
/* In this case we can use mtc1, mfc1, dmtc1 or dmfc1. */
return NO_REGS;
@@ -12693,7 +13258,7 @@ mips_vector_mode_supported_p (machine_mode mode)
return TARGET_LOONGSON_VECTORS;
default:
- return false;
+ return MSA_SUPPORTED_MODE_P (mode);
}
}
@@ -12712,14 +13277,46 @@ mips_scalar_mode_supported_p (machine_mode mode)
/* Implement TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
static machine_mode
-mips_preferred_simd_mode (machine_mode mode ATTRIBUTE_UNUSED)
+mips_preferred_simd_mode (machine_mode mode)
{
if (TARGET_PAIRED_SINGLE_FLOAT
&& mode == SFmode)
return V2SFmode;
+
+ if (!ISA_HAS_MSA)
+ return word_mode;
+
+ switch (mode)
+ {
+ case QImode:
+ return V16QImode;
+ case HImode:
+ return V8HImode;
+ case SImode:
+ return V4SImode;
+ case DImode:
+ return V2DImode;
+
+ case SFmode:
+ return V4SFmode;
+
+ case DFmode:
+ return V2DFmode;
+
+ default:
+ break;
+ }
return word_mode;
}
+/* Implement TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
+
+static unsigned int
+mips_autovectorize_vector_sizes (void)
+{
+ return ISA_HAS_MSA ? 16 : 0;
+}
+
/* Implement TARGET_INIT_LIBFUNCS. */
static void
@@ -13727,6 +14324,25 @@ mips_output_division (const char *division, rtx *operands)
}
return s;
}
+
+/* Return the assembly code for MSA DIV_{S,U}.DF or MOD_{S,U}.DF instructions,
+ which has the operands given by OPERANDS. Add in a divide-by-zero check
+ if needed. */
+
+const char *
+mips_msa_output_division (const char *division, rtx *operands)
+{
+ const char *s;
+
+ s = division;
+ if (TARGET_CHECK_ZERO_DIV)
+ {
+ output_asm_insn ("%(bnz.%v0\t%w2,1f", operands);
+ output_asm_insn (s, operands);
+ s = "break\t7%)\n1:";
+ }
+ return s;
+}
/* Return true if destination of IN_INSN is used as add source in
OUT_INSN. Both IN_INSN and OUT_INSN are of type fmadd. Example:
@@ -14480,6 +15096,7 @@ AVAIL_NON_MIPS16 (dsp_64, TARGET_64BIT && TARGET_DSP)
AVAIL_NON_MIPS16 (dspr2_32, !TARGET_64BIT && TARGET_DSPR2)
AVAIL_NON_MIPS16 (loongson, TARGET_LOONGSON_VECTORS)
AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
+AVAIL_NON_MIPS16 (msa, TARGET_MSA)
/* Construct a mips_builtin_description from the given arguments.
@@ -14596,6 +15213,38 @@ AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
#define LOONGSON_BUILTIN_SUFFIX(INSN, SUFFIX, FUNCTION_TYPE) \
LOONGSON_BUILTIN_ALIAS (INSN, INSN ## _ ## SUFFIX, FUNCTION_TYPE)
+/* Define an MSA MIPS_BUILTIN_DIRECT function __builtin_msa_<INSN>
+ for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
+ field. */
+#define MSA_BUILTIN(INSN, FUNCTION_TYPE) \
+ { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
+ "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
+ FUNCTION_TYPE, mips_builtin_avail_msa }
+
+/* Define a remapped MSA MIPS_BUILTIN_DIRECT function __builtin_msa_<INSN>
+ for instruction CODE_FOR_msa_<INSN2>. FUNCTION_TYPE is
+ a builtin_description field. */
+#define MSA_BUILTIN_REMAP(INSN, INSN2, FUNCTION_TYPE) \
+ { CODE_FOR_msa_ ## INSN2, MIPS_FP_COND_f, \
+ "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT, \
+ FUNCTION_TYPE, mips_builtin_avail_msa }
+
+/* Define an MSA MIPS_BUILTIN_MSA_TEST_BRANCH function __builtin_msa_<INSN>
+ for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
+ field. */
+#define MSA_BUILTIN_TEST_BRANCH(INSN, FUNCTION_TYPE) \
+ { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
+ "__builtin_msa_" #INSN, MIPS_BUILTIN_MSA_TEST_BRANCH, \
+ FUNCTION_TYPE, mips_builtin_avail_msa }
+
+/* Define an MSA MIPS_BUILTIN_DIRECT_NO_TARGET function __builtin_msa_<INSN>
+ for instruction CODE_FOR_msa_<INSN>. FUNCTION_TYPE is a builtin_description
+ field. */
+#define MSA_NO_TARGET_BUILTIN(INSN, FUNCTION_TYPE) \
+ { CODE_FOR_msa_ ## INSN, MIPS_FP_COND_f, \
+ "__builtin_msa_" #INSN, MIPS_BUILTIN_DIRECT_NO_TARGET, \
+ FUNCTION_TYPE, mips_builtin_avail_msa }
+
#define CODE_FOR_mips_sqrt_ps CODE_FOR_sqrtv2sf2
#define CODE_FOR_mips_addq_ph CODE_FOR_addv2hi3
#define CODE_FOR_mips_addu_qb CODE_FOR_addv4qi3
@@ -14636,6 +15285,203 @@ AVAIL_NON_MIPS16 (cache, TARGET_CACHE_BUILTIN)
#define CODE_FOR_loongson_psubush CODE_FOR_ussubv4hi3
#define CODE_FOR_loongson_psubusb CODE_FOR_ussubv8qi3
+#define CODE_FOR_msa_adds_s_b CODE_FOR_ssaddv16qi3
+#define CODE_FOR_msa_adds_s_h CODE_FOR_ssaddv8hi3
+#define CODE_FOR_msa_adds_s_w CODE_FOR_ssaddv4si3
+#define CODE_FOR_msa_adds_s_d CODE_FOR_ssaddv2di3
+#define CODE_FOR_msa_adds_u_b CODE_FOR_usaddv16qi3
+#define CODE_FOR_msa_adds_u_h CODE_FOR_usaddv8hi3
+#define CODE_FOR_msa_adds_u_w CODE_FOR_usaddv4si3
+#define CODE_FOR_msa_adds_u_d CODE_FOR_usaddv2di3
+#define CODE_FOR_msa_addv_b CODE_FOR_addv16qi3
+#define CODE_FOR_msa_addv_h CODE_FOR_addv8hi3
+#define CODE_FOR_msa_addv_w CODE_FOR_addv4si3
+#define CODE_FOR_msa_addv_d CODE_FOR_addv2di3
+#define CODE_FOR_msa_addvi_b CODE_FOR_addv16qi3
+#define CODE_FOR_msa_addvi_h CODE_FOR_addv8hi3
+#define CODE_FOR_msa_addvi_w CODE_FOR_addv4si3
+#define CODE_FOR_msa_addvi_d CODE_FOR_addv2di3
+#define CODE_FOR_msa_and_v CODE_FOR_andv16qi3
+#define CODE_FOR_msa_andi_b CODE_FOR_andv16qi3
+#define CODE_FOR_msa_bmnz_v CODE_FOR_msa_bmnz_b
+#define CODE_FOR_msa_bmnzi_b CODE_FOR_msa_bmnz_b
+#define CODE_FOR_msa_bmz_v CODE_FOR_msa_bmz_b
+#define CODE_FOR_msa_bmzi_b CODE_FOR_msa_bmz_b
+#define CODE_FOR_msa_bnz_v CODE_FOR_msa_bnz_v_b
+#define CODE_FOR_msa_bz_v CODE_FOR_msa_bz_v_b
+#define CODE_FOR_msa_bsel_v CODE_FOR_msa_bsel_b
+#define CODE_FOR_msa_bseli_b CODE_FOR_msa_bsel_b
+#define CODE_FOR_msa_ceqi_b CODE_FOR_msa_ceq_b
+#define CODE_FOR_msa_ceqi_h CODE_FOR_msa_ceq_h
+#define CODE_FOR_msa_ceqi_w CODE_FOR_msa_ceq_w
+#define CODE_FOR_msa_ceqi_d CODE_FOR_msa_ceq_d
+#define CODE_FOR_msa_clti_s_b CODE_FOR_msa_clt_s_b
+#define CODE_FOR_msa_clti_s_h CODE_FOR_msa_clt_s_h
+#define CODE_FOR_msa_clti_s_w CODE_FOR_msa_clt_s_w
+#define CODE_FOR_msa_clti_s_d CODE_FOR_msa_clt_s_d
+#define CODE_FOR_msa_clti_u_b CODE_FOR_msa_clt_u_b
+#define CODE_FOR_msa_clti_u_h CODE_FOR_msa_clt_u_h
+#define CODE_FOR_msa_clti_u_w CODE_FOR_msa_clt_u_w
+#define CODE_FOR_msa_clti_u_d CODE_FOR_msa_clt_u_d
+#define CODE_FOR_msa_clei_s_b CODE_FOR_msa_cle_s_b
+#define CODE_FOR_msa_clei_s_h CODE_FOR_msa_cle_s_h
+#define CODE_FOR_msa_clei_s_w CODE_FOR_msa_cle_s_w
+#define CODE_FOR_msa_clei_s_d CODE_FOR_msa_cle_s_d
+#define CODE_FOR_msa_clei_u_b CODE_FOR_msa_cle_u_b
+#define CODE_FOR_msa_clei_u_h CODE_FOR_msa_cle_u_h
+#define CODE_FOR_msa_clei_u_w CODE_FOR_msa_cle_u_w
+#define CODE_FOR_msa_clei_u_d CODE_FOR_msa_cle_u_d
+#define CODE_FOR_msa_div_s_b CODE_FOR_divv16qi3
+#define CODE_FOR_msa_div_s_h CODE_FOR_divv8hi3
+#define CODE_FOR_msa_div_s_w CODE_FOR_divv4si3
+#define CODE_FOR_msa_div_s_d CODE_FOR_divv2di3
+#define CODE_FOR_msa_div_u_b CODE_FOR_udivv16qi3
+#define CODE_FOR_msa_div_u_h CODE_FOR_udivv8hi3
+#define CODE_FOR_msa_div_u_w CODE_FOR_udivv4si3
+#define CODE_FOR_msa_div_u_d CODE_FOR_udivv2di3
+#define CODE_FOR_msa_fadd_w CODE_FOR_addv4sf3
+#define CODE_FOR_msa_fadd_d CODE_FOR_addv2df3
+#define CODE_FOR_msa_fexdo_w CODE_FOR_vec_pack_trunc_v2df
+#define CODE_FOR_msa_ftrunc_s_w CODE_FOR_fix_truncv4sfv4si2
+#define CODE_FOR_msa_ftrunc_s_d CODE_FOR_fix_truncv2dfv2di2
+#define CODE_FOR_msa_ftrunc_u_w CODE_FOR_fixuns_truncv4sfv4si2
+#define CODE_FOR_msa_ftrunc_u_d CODE_FOR_fixuns_truncv2dfv2di2
+#define CODE_FOR_msa_ffint_s_w CODE_FOR_floatv4siv4sf2
+#define CODE_FOR_msa_ffint_s_d CODE_FOR_floatv2div2df2
+#define CODE_FOR_msa_ffint_u_w CODE_FOR_floatunsv4siv4sf2
+#define CODE_FOR_msa_ffint_u_d CODE_FOR_floatunsv2div2df2
+#define CODE_FOR_msa_fsub_w CODE_FOR_subv4sf3
+#define CODE_FOR_msa_fsub_d CODE_FOR_subv2df3
+#define CODE_FOR_msa_fmadd_w CODE_FOR_fmav4sf4
+#define CODE_FOR_msa_fmadd_d CODE_FOR_fmav2df4
+#define CODE_FOR_msa_fmsub_w CODE_FOR_fnmav4sf4
+#define CODE_FOR_msa_fmsub_d CODE_FOR_fnmav2df4
+#define CODE_FOR_msa_fmul_w CODE_FOR_mulv4sf3
+#define CODE_FOR_msa_fmul_d CODE_FOR_mulv2df3
+#define CODE_FOR_msa_fdiv_w CODE_FOR_divv4sf3
+#define CODE_FOR_msa_fdiv_d CODE_FOR_divv2df3
+#define CODE_FOR_msa_fmax_w CODE_FOR_smaxv4sf3
+#define CODE_FOR_msa_fmax_d CODE_FOR_smaxv2df3
+#define CODE_FOR_msa_fmin_w CODE_FOR_sminv4sf3
+#define CODE_FOR_msa_fmin_d CODE_FOR_sminv2df3
+#define CODE_FOR_msa_fsqrt_w CODE_FOR_sqrtv4sf2
+#define CODE_FOR_msa_fsqrt_d CODE_FOR_sqrtv2df2
+#define CODE_FOR_msa_max_s_b CODE_FOR_smaxv16qi3
+#define CODE_FOR_msa_max_s_h CODE_FOR_smaxv8hi3
+#define CODE_FOR_msa_max_s_w CODE_FOR_smaxv4si3
+#define CODE_FOR_msa_max_s_d CODE_FOR_smaxv2di3
+#define CODE_FOR_msa_maxi_s_b CODE_FOR_smaxv16qi3
+#define CODE_FOR_msa_maxi_s_h CODE_FOR_smaxv8hi3
+#define CODE_FOR_msa_maxi_s_w CODE_FOR_smaxv4si3
+#define CODE_FOR_msa_maxi_s_d CODE_FOR_smaxv2di3
+#define CODE_FOR_msa_max_u_b CODE_FOR_umaxv16qi3
+#define CODE_FOR_msa_max_u_h CODE_FOR_umaxv8hi3
+#define CODE_FOR_msa_max_u_w CODE_FOR_umaxv4si3
+#define CODE_FOR_msa_max_u_d CODE_FOR_umaxv2di3
+#define CODE_FOR_msa_maxi_u_b CODE_FOR_umaxv16qi3
+#define CODE_FOR_msa_maxi_u_h CODE_FOR_umaxv8hi3
+#define CODE_FOR_msa_maxi_u_w CODE_FOR_umaxv4si3
+#define CODE_FOR_msa_maxi_u_d CODE_FOR_umaxv2di3
+#define CODE_FOR_msa_min_s_b CODE_FOR_sminv16qi3
+#define CODE_FOR_msa_min_s_h CODE_FOR_sminv8hi3
+#define CODE_FOR_msa_min_s_w CODE_FOR_sminv4si3
+#define CODE_FOR_msa_min_s_d CODE_FOR_sminv2di3
+#define CODE_FOR_msa_mini_s_b CODE_FOR_sminv16qi3
+#define CODE_FOR_msa_mini_s_h CODE_FOR_sminv8hi3
+#define CODE_FOR_msa_mini_s_w CODE_FOR_sminv4si3
+#define CODE_FOR_msa_mini_s_d CODE_FOR_sminv2di3
+#define CODE_FOR_msa_min_u_b CODE_FOR_uminv16qi3
+#define CODE_FOR_msa_min_u_h CODE_FOR_uminv8hi3
+#define CODE_FOR_msa_min_u_w CODE_FOR_uminv4si3
+#define CODE_FOR_msa_min_u_d CODE_FOR_uminv2di3
+#define CODE_FOR_msa_mini_u_b CODE_FOR_uminv16qi3
+#define CODE_FOR_msa_mini_u_h CODE_FOR_uminv8hi3
+#define CODE_FOR_msa_mini_u_w CODE_FOR_uminv4si3
+#define CODE_FOR_msa_mini_u_d CODE_FOR_uminv2di3
+#define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3
+#define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3
+#define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3
+#define CODE_FOR_msa_mod_s_d CODE_FOR_modv2di3
+#define CODE_FOR_msa_mod_u_b CODE_FOR_umodv16qi3
+#define CODE_FOR_msa_mod_u_h CODE_FOR_umodv8hi3
+#define CODE_FOR_msa_mod_u_w CODE_FOR_umodv4si3
+#define CODE_FOR_msa_mod_u_d CODE_FOR_umodv2di3
+#define CODE_FOR_msa_mod_s_b CODE_FOR_modv16qi3
+#define CODE_FOR_msa_mod_s_h CODE_FOR_modv8hi3
+#define CODE_FOR_msa_mod_s_w CODE_FOR_modv4si3
+#define CODE_FOR_msa_mod_s_d CODE_FOR_modv2di3
+#define CODE_FOR_msa_mod_u_b CODE_FOR_umodv16qi3
+#define CODE_FOR_msa_mod_u_h CODE_FOR_umodv8hi3
+#define CODE_FOR_msa_mod_u_w CODE_FOR_umodv4si3
+#define CODE_FOR_msa_mod_u_d CODE_FOR_umodv2di3
+#define CODE_FOR_msa_mulv_b CODE_FOR_mulv16qi3
+#define CODE_FOR_msa_mulv_h CODE_FOR_mulv8hi3
+#define CODE_FOR_msa_mulv_w CODE_FOR_mulv4si3
+#define CODE_FOR_msa_mulv_d CODE_FOR_mulv2di3
+#define CODE_FOR_msa_nlzc_b CODE_FOR_clzv16qi2
+#define CODE_FOR_msa_nlzc_h CODE_FOR_clzv8hi2
+#define CODE_FOR_msa_nlzc_w CODE_FOR_clzv4si2
+#define CODE_FOR_msa_nlzc_d CODE_FOR_clzv2di2
+#define CODE_FOR_msa_nor_v CODE_FOR_msa_nor_b
+#define CODE_FOR_msa_or_v CODE_FOR_iorv16qi3
+#define CODE_FOR_msa_ori_b CODE_FOR_iorv16qi3
+#define CODE_FOR_msa_nori_b CODE_FOR_msa_nor_b
+#define CODE_FOR_msa_pcnt_b CODE_FOR_popcountv16qi2
+#define CODE_FOR_msa_pcnt_h CODE_FOR_popcountv8hi2
+#define CODE_FOR_msa_pcnt_w CODE_FOR_popcountv4si2
+#define CODE_FOR_msa_pcnt_d CODE_FOR_popcountv2di2
+#define CODE_FOR_msa_xor_v CODE_FOR_xorv16qi3
+#define CODE_FOR_msa_xori_b CODE_FOR_xorv16qi3
+#define CODE_FOR_msa_sll_b CODE_FOR_vashlv16qi3
+#define CODE_FOR_msa_sll_h CODE_FOR_vashlv8hi3
+#define CODE_FOR_msa_sll_w CODE_FOR_vashlv4si3
+#define CODE_FOR_msa_sll_d CODE_FOR_vashlv2di3
+#define CODE_FOR_msa_slli_b CODE_FOR_vashlv16qi3
+#define CODE_FOR_msa_slli_h CODE_FOR_vashlv8hi3
+#define CODE_FOR_msa_slli_w CODE_FOR_vashlv4si3
+#define CODE_FOR_msa_slli_d CODE_FOR_vashlv2di3
+#define CODE_FOR_msa_sra_b CODE_FOR_vashrv16qi3
+#define CODE_FOR_msa_sra_h CODE_FOR_vashrv8hi3
+#define CODE_FOR_msa_sra_w CODE_FOR_vashrv4si3
+#define CODE_FOR_msa_sra_d CODE_FOR_vashrv2di3
+#define CODE_FOR_msa_srai_b CODE_FOR_vashrv16qi3
+#define CODE_FOR_msa_srai_h CODE_FOR_vashrv8hi3
+#define CODE_FOR_msa_srai_w CODE_FOR_vashrv4si3
+#define CODE_FOR_msa_srai_d CODE_FOR_vashrv2di3
+#define CODE_FOR_msa_srl_b CODE_FOR_vlshrv16qi3
+#define CODE_FOR_msa_srl_h CODE_FOR_vlshrv8hi3
+#define CODE_FOR_msa_srl_w CODE_FOR_vlshrv4si3
+#define CODE_FOR_msa_srl_d CODE_FOR_vlshrv2di3
+#define CODE_FOR_msa_srli_b CODE_FOR_vlshrv16qi3
+#define CODE_FOR_msa_srli_h CODE_FOR_vlshrv8hi3
+#define CODE_FOR_msa_srli_w CODE_FOR_vlshrv4si3
+#define CODE_FOR_msa_srli_d CODE_FOR_vlshrv2di3
+#define CODE_FOR_msa_subv_b CODE_FOR_subv16qi3
+#define CODE_FOR_msa_subv_h CODE_FOR_subv8hi3
+#define CODE_FOR_msa_subv_w CODE_FOR_subv4si3
+#define CODE_FOR_msa_subv_d CODE_FOR_subv2di3
+#define CODE_FOR_msa_subvi_b CODE_FOR_subv16qi3
+#define CODE_FOR_msa_subvi_h CODE_FOR_subv8hi3
+#define CODE_FOR_msa_subvi_w CODE_FOR_subv4si3
+#define CODE_FOR_msa_subvi_d CODE_FOR_subv2di3
+
+#define CODE_FOR_msa_move_v CODE_FOR_movv16qi
+
+#define CODE_FOR_msa_vshf_b CODE_FOR_vec_permv16qi
+#define CODE_FOR_msa_vshf_h CODE_FOR_vec_permv8hi
+#define CODE_FOR_msa_vshf_w CODE_FOR_vec_permv4si
+#define CODE_FOR_msa_vshf_d CODE_FOR_vec_permv2di
+
+#define CODE_FOR_msa_ilvod_d CODE_FOR_msa_ilvl_d
+#define CODE_FOR_msa_ilvev_d CODE_FOR_msa_ilvr_d
+#define CODE_FOR_msa_pckod_d CODE_FOR_msa_ilvl_d
+#define CODE_FOR_msa_pckev_d CODE_FOR_msa_ilvr_d
+
+#define CODE_FOR_msa_ldi_b CODE_FOR_msa_ldiv16qi
+#define CODE_FOR_msa_ldi_h CODE_FOR_msa_ldiv8hi
+#define CODE_FOR_msa_ldi_w CODE_FOR_msa_ldiv4si
+#define CODE_FOR_msa_ldi_d CODE_FOR_msa_ldiv2di
+
static const struct mips_builtin_description mips_builtins[] = {
#define MIPS_GET_FCSR 0
DIRECT_BUILTIN (get_fcsr, MIPS_USI_FTYPE_VOID, hard_float),
@@ -14924,12 +15770,547 @@ static const struct mips_builtin_description mips_builtins[] = {
LOONGSON_BUILTIN_SUFFIX (punpcklwd, s, MIPS_V2SI_FTYPE_V2SI_V2SI),
/* Sundry other built-in functions. */
- DIRECT_NO_TARGET_BUILTIN (cache, MIPS_VOID_FTYPE_SI_CVPOINTER, cache)
+ DIRECT_NO_TARGET_BUILTIN (cache, MIPS_VOID_FTYPE_SI_CVPOINTER, cache),
+
+ /* Built-in functions for MSA. */
+ MSA_BUILTIN (sll_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (sll_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (sll_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (sll_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (slli_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (slli_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (slli_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (slli_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (sra_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (sra_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (sra_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (sra_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (srai_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (srai_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (srai_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (srai_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (srar_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (srar_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (srar_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (srar_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (srari_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (srari_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (srari_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (srari_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (srl_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (srl_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (srl_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (srl_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (srli_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (srli_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (srli_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (srli_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (srlr_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (srlr_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (srlr_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (srlr_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (srlri_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (srlri_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (srlri_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (srlri_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (bclr_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (bclr_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (bclr_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (bclr_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (bclri_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (bclri_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
+ MSA_BUILTIN (bclri_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
+ MSA_BUILTIN (bclri_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
+ MSA_BUILTIN (bset_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (bset_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (bset_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (bset_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (bseti_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (bseti_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
+ MSA_BUILTIN (bseti_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
+ MSA_BUILTIN (bseti_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
+ MSA_BUILTIN (bneg_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (bneg_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (bneg_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (bneg_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (bnegi_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (bnegi_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
+ MSA_BUILTIN (bnegi_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
+ MSA_BUILTIN (bnegi_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
+ MSA_BUILTIN (binsl_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
+ MSA_BUILTIN (binsl_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UV8HI),
+ MSA_BUILTIN (binsl_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UV4SI),
+ MSA_BUILTIN (binsl_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UV2DI),
+ MSA_BUILTIN (binsli_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
+ MSA_BUILTIN (binsli_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UQI),
+ MSA_BUILTIN (binsli_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UQI),
+ MSA_BUILTIN (binsli_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UQI),
+ MSA_BUILTIN (binsr_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
+ MSA_BUILTIN (binsr_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UV8HI),
+ MSA_BUILTIN (binsr_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UV4SI),
+ MSA_BUILTIN (binsr_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UV2DI),
+ MSA_BUILTIN (binsri_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
+ MSA_BUILTIN (binsri_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI_UQI),
+ MSA_BUILTIN (binsri_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI_UQI),
+ MSA_BUILTIN (binsri_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI_UQI),
+ MSA_BUILTIN (addv_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (addv_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (addv_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (addv_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (addvi_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (addvi_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (addvi_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (addvi_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (subv_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (subv_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (subv_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (subv_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (subvi_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (subvi_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (subvi_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (subvi_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (max_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (max_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (max_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (max_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (maxi_s_b, MIPS_V16QI_FTYPE_V16QI_QI),
+ MSA_BUILTIN (maxi_s_h, MIPS_V8HI_FTYPE_V8HI_QI),
+ MSA_BUILTIN (maxi_s_w, MIPS_V4SI_FTYPE_V4SI_QI),
+ MSA_BUILTIN (maxi_s_d, MIPS_V2DI_FTYPE_V2DI_QI),
+ MSA_BUILTIN (max_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (max_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (max_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (max_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (maxi_u_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (maxi_u_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
+ MSA_BUILTIN (maxi_u_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
+ MSA_BUILTIN (maxi_u_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
+ MSA_BUILTIN (min_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (min_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (min_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (min_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (mini_s_b, MIPS_V16QI_FTYPE_V16QI_QI),
+ MSA_BUILTIN (mini_s_h, MIPS_V8HI_FTYPE_V8HI_QI),
+ MSA_BUILTIN (mini_s_w, MIPS_V4SI_FTYPE_V4SI_QI),
+ MSA_BUILTIN (mini_s_d, MIPS_V2DI_FTYPE_V2DI_QI),
+ MSA_BUILTIN (min_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (min_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (min_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (min_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (mini_u_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (mini_u_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
+ MSA_BUILTIN (mini_u_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
+ MSA_BUILTIN (mini_u_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
+ MSA_BUILTIN (max_a_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (max_a_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (max_a_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (max_a_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (min_a_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (min_a_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (min_a_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (min_a_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (ceq_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (ceq_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (ceq_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (ceq_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (ceqi_b, MIPS_V16QI_FTYPE_V16QI_QI),
+ MSA_BUILTIN (ceqi_h, MIPS_V8HI_FTYPE_V8HI_QI),
+ MSA_BUILTIN (ceqi_w, MIPS_V4SI_FTYPE_V4SI_QI),
+ MSA_BUILTIN (ceqi_d, MIPS_V2DI_FTYPE_V2DI_QI),
+ MSA_BUILTIN (clt_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (clt_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (clt_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (clt_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (clti_s_b, MIPS_V16QI_FTYPE_V16QI_QI),
+ MSA_BUILTIN (clti_s_h, MIPS_V8HI_FTYPE_V8HI_QI),
+ MSA_BUILTIN (clti_s_w, MIPS_V4SI_FTYPE_V4SI_QI),
+ MSA_BUILTIN (clti_s_d, MIPS_V2DI_FTYPE_V2DI_QI),
+ MSA_BUILTIN (clt_u_b, MIPS_V16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (clt_u_h, MIPS_V8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (clt_u_w, MIPS_V4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (clt_u_d, MIPS_V2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (clti_u_b, MIPS_V16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (clti_u_h, MIPS_V8HI_FTYPE_UV8HI_UQI),
+ MSA_BUILTIN (clti_u_w, MIPS_V4SI_FTYPE_UV4SI_UQI),
+ MSA_BUILTIN (clti_u_d, MIPS_V2DI_FTYPE_UV2DI_UQI),
+ MSA_BUILTIN (cle_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (cle_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (cle_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (cle_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (clei_s_b, MIPS_V16QI_FTYPE_V16QI_QI),
+ MSA_BUILTIN (clei_s_h, MIPS_V8HI_FTYPE_V8HI_QI),
+ MSA_BUILTIN (clei_s_w, MIPS_V4SI_FTYPE_V4SI_QI),
+ MSA_BUILTIN (clei_s_d, MIPS_V2DI_FTYPE_V2DI_QI),
+ MSA_BUILTIN (cle_u_b, MIPS_V16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (cle_u_h, MIPS_V8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (cle_u_w, MIPS_V4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (cle_u_d, MIPS_V2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (clei_u_b, MIPS_V16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (clei_u_h, MIPS_V8HI_FTYPE_UV8HI_UQI),
+ MSA_BUILTIN (clei_u_w, MIPS_V4SI_FTYPE_UV4SI_UQI),
+ MSA_BUILTIN (clei_u_d, MIPS_V2DI_FTYPE_UV2DI_UQI),
+ MSA_BUILTIN (ld_b, MIPS_V16QI_FTYPE_CVPOINTER_SI),
+ MSA_BUILTIN (ld_h, MIPS_V8HI_FTYPE_CVPOINTER_SI),
+ MSA_BUILTIN (ld_w, MIPS_V4SI_FTYPE_CVPOINTER_SI),
+ MSA_BUILTIN (ld_d, MIPS_V2DI_FTYPE_CVPOINTER_SI),
+ MSA_NO_TARGET_BUILTIN (st_b, MIPS_VOID_FTYPE_V16QI_CVPOINTER_SI),
+ MSA_NO_TARGET_BUILTIN (st_h, MIPS_VOID_FTYPE_V8HI_CVPOINTER_SI),
+ MSA_NO_TARGET_BUILTIN (st_w, MIPS_VOID_FTYPE_V4SI_CVPOINTER_SI),
+ MSA_NO_TARGET_BUILTIN (st_d, MIPS_VOID_FTYPE_V2DI_CVPOINTER_SI),
+ MSA_BUILTIN (sat_s_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (sat_s_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (sat_s_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (sat_s_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (sat_u_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (sat_u_h, MIPS_UV8HI_FTYPE_UV8HI_UQI),
+ MSA_BUILTIN (sat_u_w, MIPS_UV4SI_FTYPE_UV4SI_UQI),
+ MSA_BUILTIN (sat_u_d, MIPS_UV2DI_FTYPE_UV2DI_UQI),
+ MSA_BUILTIN (add_a_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (add_a_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (add_a_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (add_a_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (adds_a_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (adds_a_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (adds_a_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (adds_a_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (adds_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (adds_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (adds_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (adds_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (adds_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (adds_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (adds_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (adds_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (ave_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (ave_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (ave_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (ave_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (ave_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (ave_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (ave_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (ave_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (aver_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (aver_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (aver_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (aver_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (aver_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (aver_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (aver_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (aver_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (subs_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (subs_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (subs_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (subs_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (subs_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (subs_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (subs_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (subs_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (subsuu_s_b, MIPS_V16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (subsuu_s_h, MIPS_V8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (subsuu_s_w, MIPS_V4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (subsuu_s_d, MIPS_V2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (subsus_u_b, MIPS_UV16QI_FTYPE_UV16QI_V16QI),
+ MSA_BUILTIN (subsus_u_h, MIPS_UV8HI_FTYPE_UV8HI_V8HI),
+ MSA_BUILTIN (subsus_u_w, MIPS_UV4SI_FTYPE_UV4SI_V4SI),
+ MSA_BUILTIN (subsus_u_d, MIPS_UV2DI_FTYPE_UV2DI_V2DI),
+ MSA_BUILTIN (asub_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (asub_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (asub_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (asub_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (asub_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (asub_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (asub_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (asub_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (mulv_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (mulv_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (mulv_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (mulv_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (maddv_b, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI),
+ MSA_BUILTIN (maddv_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
+ MSA_BUILTIN (maddv_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
+ MSA_BUILTIN (maddv_d, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI),
+ MSA_BUILTIN (msubv_b, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI),
+ MSA_BUILTIN (msubv_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
+ MSA_BUILTIN (msubv_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
+ MSA_BUILTIN (msubv_d, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI),
+ MSA_BUILTIN (div_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (div_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (div_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (div_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (div_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (div_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (div_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (div_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (hadd_s_h, MIPS_V8HI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (hadd_s_w, MIPS_V4SI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (hadd_s_d, MIPS_V2DI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (hadd_u_h, MIPS_UV8HI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (hadd_u_w, MIPS_UV4SI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (hadd_u_d, MIPS_UV2DI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (hsub_s_h, MIPS_V8HI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (hsub_s_w, MIPS_V4SI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (hsub_s_d, MIPS_V2DI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (hsub_u_h, MIPS_V8HI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (hsub_u_w, MIPS_V4SI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (hsub_u_d, MIPS_V2DI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (mod_s_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (mod_s_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (mod_s_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (mod_s_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (mod_u_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (mod_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (mod_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (mod_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV2DI),
+ MSA_BUILTIN (dotp_s_h, MIPS_V8HI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (dotp_s_w, MIPS_V4SI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (dotp_s_d, MIPS_V2DI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (dotp_u_h, MIPS_UV8HI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (dotp_u_w, MIPS_UV4SI_FTYPE_UV8HI_UV8HI),
+ MSA_BUILTIN (dotp_u_d, MIPS_UV2DI_FTYPE_UV4SI_UV4SI),
+ MSA_BUILTIN (dpadd_s_h, MIPS_V8HI_FTYPE_V8HI_V16QI_V16QI),
+ MSA_BUILTIN (dpadd_s_w, MIPS_V4SI_FTYPE_V4SI_V8HI_V8HI),
+ MSA_BUILTIN (dpadd_s_d, MIPS_V2DI_FTYPE_V2DI_V4SI_V4SI),
+ MSA_BUILTIN (dpadd_u_h, MIPS_UV8HI_FTYPE_UV8HI_UV16QI_UV16QI),
+ MSA_BUILTIN (dpadd_u_w, MIPS_UV4SI_FTYPE_UV4SI_UV8HI_UV8HI),
+ MSA_BUILTIN (dpadd_u_d, MIPS_UV2DI_FTYPE_UV2DI_UV4SI_UV4SI),
+ MSA_BUILTIN (dpsub_s_h, MIPS_V8HI_FTYPE_V8HI_V16QI_V16QI),
+ MSA_BUILTIN (dpsub_s_w, MIPS_V4SI_FTYPE_V4SI_V8HI_V8HI),
+ MSA_BUILTIN (dpsub_s_d, MIPS_V2DI_FTYPE_V2DI_V4SI_V4SI),
+ MSA_BUILTIN (dpsub_u_h, MIPS_V8HI_FTYPE_V8HI_UV16QI_UV16QI),
+ MSA_BUILTIN (dpsub_u_w, MIPS_V4SI_FTYPE_V4SI_UV8HI_UV8HI),
+ MSA_BUILTIN (dpsub_u_d, MIPS_V2DI_FTYPE_V2DI_UV4SI_UV4SI),
+ MSA_BUILTIN (sld_b, MIPS_V16QI_FTYPE_V16QI_V16QI_SI),
+ MSA_BUILTIN (sld_h, MIPS_V8HI_FTYPE_V8HI_V8HI_SI),
+ MSA_BUILTIN (sld_w, MIPS_V4SI_FTYPE_V4SI_V4SI_SI),
+ MSA_BUILTIN (sld_d, MIPS_V2DI_FTYPE_V2DI_V2DI_SI),
+ MSA_BUILTIN (sldi_b, MIPS_V16QI_FTYPE_V16QI_V16QI_UQI),
+ MSA_BUILTIN (sldi_h, MIPS_V8HI_FTYPE_V8HI_V8HI_UQI),
+ MSA_BUILTIN (sldi_w, MIPS_V4SI_FTYPE_V4SI_V4SI_UQI),
+ MSA_BUILTIN (sldi_d, MIPS_V2DI_FTYPE_V2DI_V2DI_UQI),
+ MSA_BUILTIN (splat_b, MIPS_V16QI_FTYPE_V16QI_SI),
+ MSA_BUILTIN (splat_h, MIPS_V8HI_FTYPE_V8HI_SI),
+ MSA_BUILTIN (splat_w, MIPS_V4SI_FTYPE_V4SI_SI),
+ MSA_BUILTIN (splat_d, MIPS_V2DI_FTYPE_V2DI_SI),
+ MSA_BUILTIN (splati_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (splati_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (splati_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (splati_d, MIPS_V2DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (pckev_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (pckev_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (pckev_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (pckev_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (pckod_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (pckod_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (pckod_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (pckod_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (ilvl_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (ilvl_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (ilvl_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (ilvl_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (ilvr_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (ilvr_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (ilvr_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (ilvr_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (ilvev_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (ilvev_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (ilvev_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (ilvev_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (ilvod_b, MIPS_V16QI_FTYPE_V16QI_V16QI),
+ MSA_BUILTIN (ilvod_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (ilvod_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (ilvod_d, MIPS_V2DI_FTYPE_V2DI_V2DI),
+ MSA_BUILTIN (vshf_b, MIPS_V16QI_FTYPE_V16QI_V16QI_V16QI),
+ MSA_BUILTIN (vshf_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
+ MSA_BUILTIN (vshf_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
+ MSA_BUILTIN (vshf_d, MIPS_V2DI_FTYPE_V2DI_V2DI_V2DI),
+ MSA_BUILTIN (and_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (andi_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (or_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (ori_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (nor_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (nori_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (xor_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI),
+ MSA_BUILTIN (xori_b, MIPS_UV16QI_FTYPE_UV16QI_UQI),
+ MSA_BUILTIN (bmnz_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
+ MSA_BUILTIN (bmnzi_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
+ MSA_BUILTIN (bmz_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
+ MSA_BUILTIN (bmzi_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
+ MSA_BUILTIN (bsel_v, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UV16QI),
+ MSA_BUILTIN (bseli_b, MIPS_UV16QI_FTYPE_UV16QI_UV16QI_UQI),
+ MSA_BUILTIN (shf_b, MIPS_V16QI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (shf_h, MIPS_V8HI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (shf_w, MIPS_V4SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN_TEST_BRANCH (bnz_v, MIPS_SI_FTYPE_UV16QI),
+ MSA_BUILTIN_TEST_BRANCH (bz_v, MIPS_SI_FTYPE_UV16QI),
+ MSA_BUILTIN (fill_b, MIPS_V16QI_FTYPE_SI),
+ MSA_BUILTIN (fill_h, MIPS_V8HI_FTYPE_SI),
+ MSA_BUILTIN (fill_w, MIPS_V4SI_FTYPE_SI),
+ MSA_BUILTIN (fill_d, MIPS_V2DI_FTYPE_DI),
+ MSA_BUILTIN (pcnt_b, MIPS_V16QI_FTYPE_V16QI),
+ MSA_BUILTIN (pcnt_h, MIPS_V8HI_FTYPE_V8HI),
+ MSA_BUILTIN (pcnt_w, MIPS_V4SI_FTYPE_V4SI),
+ MSA_BUILTIN (pcnt_d, MIPS_V2DI_FTYPE_V2DI),
+ MSA_BUILTIN (nloc_b, MIPS_V16QI_FTYPE_V16QI),
+ MSA_BUILTIN (nloc_h, MIPS_V8HI_FTYPE_V8HI),
+ MSA_BUILTIN (nloc_w, MIPS_V4SI_FTYPE_V4SI),
+ MSA_BUILTIN (nloc_d, MIPS_V2DI_FTYPE_V2DI),
+ MSA_BUILTIN (nlzc_b, MIPS_V16QI_FTYPE_V16QI),
+ MSA_BUILTIN (nlzc_h, MIPS_V8HI_FTYPE_V8HI),
+ MSA_BUILTIN (nlzc_w, MIPS_V4SI_FTYPE_V4SI),
+ MSA_BUILTIN (nlzc_d, MIPS_V2DI_FTYPE_V2DI),
+ MSA_BUILTIN (copy_s_b, MIPS_SI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (copy_s_h, MIPS_SI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN (copy_s_w, MIPS_SI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN (copy_s_d, MIPS_DI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (copy_u_b, MIPS_USI_FTYPE_V16QI_UQI),
+ MSA_BUILTIN (copy_u_h, MIPS_USI_FTYPE_V8HI_UQI),
+ MSA_BUILTIN_REMAP (copy_u_w, copy_s_w, MIPS_USI_FTYPE_V4SI_UQI),
+ MSA_BUILTIN_REMAP (copy_u_d, copy_s_d, MIPS_UDI_FTYPE_V2DI_UQI),
+ MSA_BUILTIN (insert_b, MIPS_V16QI_FTYPE_V16QI_UQI_SI),
+ MSA_BUILTIN (insert_h, MIPS_V8HI_FTYPE_V8HI_UQI_SI),
+ MSA_BUILTIN (insert_w, MIPS_V4SI_FTYPE_V4SI_UQI_SI),
+ MSA_BUILTIN (insert_d, MIPS_V2DI_FTYPE_V2DI_UQI_DI),
+ MSA_BUILTIN (insve_b, MIPS_V16QI_FTYPE_V16QI_UQI_V16QI),
+ MSA_BUILTIN (insve_h, MIPS_V8HI_FTYPE_V8HI_UQI_V8HI),
+ MSA_BUILTIN (insve_w, MIPS_V4SI_FTYPE_V4SI_UQI_V4SI),
+ MSA_BUILTIN (insve_d, MIPS_V2DI_FTYPE_V2DI_UQI_V2DI),
+ MSA_BUILTIN_TEST_BRANCH (bnz_b, MIPS_SI_FTYPE_UV16QI),
+ MSA_BUILTIN_TEST_BRANCH (bnz_h, MIPS_SI_FTYPE_UV8HI),
+ MSA_BUILTIN_TEST_BRANCH (bnz_w, MIPS_SI_FTYPE_UV4SI),
+ MSA_BUILTIN_TEST_BRANCH (bnz_d, MIPS_SI_FTYPE_UV2DI),
+ MSA_BUILTIN_TEST_BRANCH (bz_b, MIPS_SI_FTYPE_UV16QI),
+ MSA_BUILTIN_TEST_BRANCH (bz_h, MIPS_SI_FTYPE_UV8HI),
+ MSA_BUILTIN_TEST_BRANCH (bz_w, MIPS_SI_FTYPE_UV4SI),
+ MSA_BUILTIN_TEST_BRANCH (bz_d, MIPS_SI_FTYPE_UV2DI),
+ MSA_BUILTIN (ldi_b, MIPS_V16QI_FTYPE_HI),
+ MSA_BUILTIN (ldi_h, MIPS_V8HI_FTYPE_HI),
+ MSA_BUILTIN (ldi_w, MIPS_V4SI_FTYPE_HI),
+ MSA_BUILTIN (ldi_d, MIPS_V2DI_FTYPE_HI),
+ MSA_BUILTIN (fcaf_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcaf_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fcor_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcor_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fcun_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcun_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fcune_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcune_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fcueq_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcueq_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fceq_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fceq_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fcne_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcne_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fclt_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fclt_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fcult_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcult_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fcle_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcle_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fcule_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fcule_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsaf_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsaf_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsor_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsor_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsun_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsun_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsune_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsune_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsueq_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsueq_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fseq_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fseq_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsne_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsne_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fslt_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fslt_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsult_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsult_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsle_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsle_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsule_w, MIPS_V4SI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsule_d, MIPS_V2DI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fadd_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fadd_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fsub_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fsub_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fmul_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fmul_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fdiv_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fdiv_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fmadd_w, MIPS_V4SF_FTYPE_V4SF_V4SF_V4SF),
+ MSA_BUILTIN (fmadd_d, MIPS_V2DF_FTYPE_V2DF_V2DF_V2DF),
+ MSA_BUILTIN (fmsub_w, MIPS_V4SF_FTYPE_V4SF_V4SF_V4SF),
+ MSA_BUILTIN (fmsub_d, MIPS_V2DF_FTYPE_V2DF_V2DF_V2DF),
+ MSA_BUILTIN (fexp2_w, MIPS_V4SF_FTYPE_V4SF_V4SI),
+ MSA_BUILTIN (fexp2_d, MIPS_V2DF_FTYPE_V2DF_V2DI),
+ MSA_BUILTIN (fexdo_h, MIPS_V8HI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fexdo_w, MIPS_V4SF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (ftq_h, MIPS_V8HI_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (ftq_w, MIPS_V4SI_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fmin_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fmin_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fmin_a_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fmin_a_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fmax_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fmax_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (fmax_a_w, MIPS_V4SF_FTYPE_V4SF_V4SF),
+ MSA_BUILTIN (fmax_a_d, MIPS_V2DF_FTYPE_V2DF_V2DF),
+ MSA_BUILTIN (mul_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (mul_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (mulr_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI),
+ MSA_BUILTIN (mulr_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI),
+ MSA_BUILTIN (madd_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
+ MSA_BUILTIN (madd_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
+ MSA_BUILTIN (maddr_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
+ MSA_BUILTIN (maddr_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
+ MSA_BUILTIN (msub_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
+ MSA_BUILTIN (msub_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
+ MSA_BUILTIN (msubr_q_h, MIPS_V8HI_FTYPE_V8HI_V8HI_V8HI),
+ MSA_BUILTIN (msubr_q_w, MIPS_V4SI_FTYPE_V4SI_V4SI_V4SI),
+ MSA_BUILTIN (fclass_w, MIPS_V4SI_FTYPE_V4SF),
+ MSA_BUILTIN (fclass_d, MIPS_V2DI_FTYPE_V2DF),
+ MSA_BUILTIN (fsqrt_w, MIPS_V4SF_FTYPE_V4SF),
+ MSA_BUILTIN (fsqrt_d, MIPS_V2DF_FTYPE_V2DF),
+ MSA_BUILTIN (frcp_w, MIPS_V4SF_FTYPE_V4SF),
+ MSA_BUILTIN (frcp_d, MIPS_V2DF_FTYPE_V2DF),
+ MSA_BUILTIN (frint_w, MIPS_V4SF_FTYPE_V4SF),
+ MSA_BUILTIN (frint_d, MIPS_V2DF_FTYPE_V2DF),
+ MSA_BUILTIN (frsqrt_w, MIPS_V4SF_FTYPE_V4SF),
+ MSA_BUILTIN (frsqrt_d, MIPS_V2DF_FTYPE_V2DF),
+ MSA_BUILTIN (flog2_w, MIPS_V4SF_FTYPE_V4SF),
+ MSA_BUILTIN (flog2_d, MIPS_V2DF_FTYPE_V2DF),
+ MSA_BUILTIN (fexupl_w, MIPS_V4SF_FTYPE_V8HI),
+ MSA_BUILTIN (fexupl_d, MIPS_V2DF_FTYPE_V4SF),
+ MSA_BUILTIN (fexupr_w, MIPS_V4SF_FTYPE_V8HI),
+ MSA_BUILTIN (fexupr_d, MIPS_V2DF_FTYPE_V4SF),
+ MSA_BUILTIN (ffql_w, MIPS_V4SF_FTYPE_V8HI),
+ MSA_BUILTIN (ffql_d, MIPS_V2DF_FTYPE_V4SI),
+ MSA_BUILTIN (ffqr_w, MIPS_V4SF_FTYPE_V8HI),
+ MSA_BUILTIN (ffqr_d, MIPS_V2DF_FTYPE_V4SI),
+ MSA_BUILTIN (ftint_s_w, MIPS_V4SI_FTYPE_V4SF),
+ MSA_BUILTIN (ftint_s_d, MIPS_V2DI_FTYPE_V2DF),
+ MSA_BUILTIN (ftint_u_w, MIPS_UV4SI_FTYPE_V4SF),
+ MSA_BUILTIN (ftint_u_d, MIPS_UV2DI_FTYPE_V2DF),
+ MSA_BUILTIN (ftrunc_s_w, MIPS_V4SI_FTYPE_V4SF),
+ MSA_BUILTIN (ftrunc_s_d, MIPS_V2DI_FTYPE_V2DF),
+ MSA_BUILTIN (ftrunc_u_w, MIPS_UV4SI_FTYPE_V4SF),
+ MSA_BUILTIN (ftrunc_u_d, MIPS_UV2DI_FTYPE_V2DF),
+ MSA_BUILTIN (ffint_s_w, MIPS_V4SF_FTYPE_V4SI),
+ MSA_BUILTIN (ffint_s_d, MIPS_V2DF_FTYPE_V2DI),
+ MSA_BUILTIN (ffint_u_w, MIPS_V4SF_FTYPE_UV4SI),
+ MSA_BUILTIN (ffint_u_d, MIPS_V2DF_FTYPE_UV2DI),
+ MSA_NO_TARGET_BUILTIN (ctcmsa, MIPS_VOID_FTYPE_UQI_SI),
+ MSA_BUILTIN (cfcmsa, MIPS_SI_FTYPE_UQI),
+ MSA_BUILTIN (move_v, MIPS_V16QI_FTYPE_V16QI),
};
/* Index I is the function declaration for mips_builtins[I], or null if the
function isn't defined on this target. */
static GTY(()) tree mips_builtin_decls[ARRAY_SIZE (mips_builtins)];
+/* Get the index I of the function declaration for mips_builtin_decls[I]
+ using the instruction code or return null if not defined for the target. */
+static GTY(()) int mips_get_builtin_decl_index[NUM_INSN_CODES];
/* MODE is a vector mode whose elements have type TYPE. Return the type
of the vector itself. */
@@ -14971,7 +16352,9 @@ mips_build_cvpointer_type (void)
#define MIPS_ATYPE_CVPOINTER mips_build_cvpointer_type ()
/* Standard mode-based argument types. */
+#define MIPS_ATYPE_QI intQI_type_node
#define MIPS_ATYPE_UQI unsigned_intQI_type_node
+#define MIPS_ATYPE_HI intHI_type_node
#define MIPS_ATYPE_SI intSI_type_node
#define MIPS_ATYPE_USI unsigned_intSI_type_node
#define MIPS_ATYPE_DI intDI_type_node
@@ -14986,6 +16369,24 @@ mips_build_cvpointer_type (void)
#define MIPS_ATYPE_V4QI mips_builtin_vector_type (intQI_type_node, V4QImode)
#define MIPS_ATYPE_V4HI mips_builtin_vector_type (intHI_type_node, V4HImode)
#define MIPS_ATYPE_V8QI mips_builtin_vector_type (intQI_type_node, V8QImode)
+
+#define MIPS_ATYPE_V2DI \
+ mips_builtin_vector_type (long_long_integer_type_node, V2DImode)
+#define MIPS_ATYPE_V4SI mips_builtin_vector_type (intSI_type_node, V4SImode)
+#define MIPS_ATYPE_V8HI mips_builtin_vector_type (intHI_type_node, V8HImode)
+#define MIPS_ATYPE_V16QI mips_builtin_vector_type (intQI_type_node, V16QImode)
+#define MIPS_ATYPE_V2DF mips_builtin_vector_type (double_type_node, V2DFmode)
+#define MIPS_ATYPE_V4SF mips_builtin_vector_type (float_type_node, V4SFmode)
+
+#define MIPS_ATYPE_UV2DI \
+ mips_builtin_vector_type (long_long_unsigned_type_node, V2DImode)
+#define MIPS_ATYPE_UV4SI \
+ mips_builtin_vector_type (unsigned_intSI_type_node, V4SImode)
+#define MIPS_ATYPE_UV8HI \
+ mips_builtin_vector_type (unsigned_intHI_type_node, V8HImode)
+#define MIPS_ATYPE_UV16QI \
+ mips_builtin_vector_type (unsigned_intQI_type_node, V16QImode)
+
#define MIPS_ATYPE_UV2SI \
mips_builtin_vector_type (unsigned_intSI_type_node, V2SImode)
#define MIPS_ATYPE_UV4HI \
@@ -15047,10 +16448,13 @@ mips_init_builtins (void)
{
d = &mips_builtins[i];
if (d->avail ())
- mips_builtin_decls[i]
- = add_builtin_function (d->name,
- mips_build_function_type (d->function_type),
- i, BUILT_IN_MD, NULL, NULL);
+ {
+ mips_builtin_decls[i]
+ = add_builtin_function (d->name,
+ mips_build_function_type (d->function_type),
+ i, BUILT_IN_MD, NULL, NULL);
+ mips_get_builtin_decl_index[d->icode] = i;
+ }
}
}
@@ -15064,6 +16468,48 @@ mips_builtin_decl (unsigned int code, bool initialize_p ATTRIBUTE_UNUSED)
return mips_builtin_decls[code];
}
+/* Implement TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION. */
+
+static tree
+mips_builtin_vectorized_function (unsigned int fn, tree type_out, tree type_in)
+{
+ machine_mode in_mode, out_mode;
+ int in_n, out_n;
+
+ if (TREE_CODE (type_out) != VECTOR_TYPE
+ || TREE_CODE (type_in) != VECTOR_TYPE
+ || !ISA_HAS_MSA)
+ return NULL_TREE;
+
+ out_mode = TYPE_MODE (TREE_TYPE (type_out));
+ out_n = TYPE_VECTOR_SUBPARTS (type_out);
+ in_mode = TYPE_MODE (TREE_TYPE (type_in));
+ in_n = TYPE_VECTOR_SUBPARTS (type_in);
+
+ /* INSN is the name of the associated instruction pattern, without
+ the leading CODE_FOR_. */
+#define MIPS_GET_BUILTIN(INSN) \
+ mips_builtin_decls[mips_get_builtin_decl_index[CODE_FOR_##INSN]]
+
+ switch (fn)
+ {
+ case BUILT_IN_SQRT:
+ if (out_mode == DFmode && out_n == 2
+ && in_mode == DFmode && in_n == 2)
+ return MIPS_GET_BUILTIN (msa_fsqrt_d);
+ break;
+ case BUILT_IN_SQRTF:
+ if (out_mode == SFmode && out_n == 4
+ && in_mode == SFmode && in_n == 4)
+ return MIPS_GET_BUILTIN (msa_fsqrt_w);
+ break;
+ default:
+ break;
+ }
+
+ return NULL_TREE;
+}
+
/* Take argument ARGNO from EXP's argument list and convert it into
an expand operand. Store the operand in *OP. */
@@ -15090,6 +16536,211 @@ static rtx
mips_expand_builtin_insn (enum insn_code icode, unsigned int nops,
struct expand_operand *ops, bool has_target_p)
{
+ machine_mode imode;
+
+ switch (icode)
+ {
+ case CODE_FOR_msa_addvi_b:
+ case CODE_FOR_msa_addvi_h:
+ case CODE_FOR_msa_addvi_w:
+ case CODE_FOR_msa_addvi_d:
+ case CODE_FOR_msa_clti_u_b:
+ case CODE_FOR_msa_clti_u_h:
+ case CODE_FOR_msa_clti_u_w:
+ case CODE_FOR_msa_clti_u_d:
+ case CODE_FOR_msa_clei_u_b:
+ case CODE_FOR_msa_clei_u_h:
+ case CODE_FOR_msa_clei_u_w:
+ case CODE_FOR_msa_clei_u_d:
+ case CODE_FOR_msa_maxi_u_b:
+ case CODE_FOR_msa_maxi_u_h:
+ case CODE_FOR_msa_maxi_u_w:
+ case CODE_FOR_msa_maxi_u_d:
+ case CODE_FOR_msa_mini_u_b:
+ case CODE_FOR_msa_mini_u_h:
+ case CODE_FOR_msa_mini_u_w:
+ case CODE_FOR_msa_mini_u_d:
+ case CODE_FOR_msa_subvi_b:
+ case CODE_FOR_msa_subvi_h:
+ case CODE_FOR_msa_subvi_w:
+ case CODE_FOR_msa_subvi_d:
+ gcc_assert (has_target_p && nops == 3);
+ /* We only generate a vector of constants iff the second argument
+ is an immediate. We also validate the range of the immediate. */
+ if (!CONST_INT_P (ops[2].value)
+ || !IN_RANGE (INTVAL (ops[2].value), 0, 31))
+ break;
+ ops[2].mode = ops[0].mode;
+ ops[2].value = mips_gen_const_int_vector (ops[2].mode,
+ INTVAL (ops[2].value));
+ break;
+
+ case CODE_FOR_msa_ceqi_b:
+ case CODE_FOR_msa_ceqi_h:
+ case CODE_FOR_msa_ceqi_w:
+ case CODE_FOR_msa_ceqi_d:
+ case CODE_FOR_msa_clti_s_b:
+ case CODE_FOR_msa_clti_s_h:
+ case CODE_FOR_msa_clti_s_w:
+ case CODE_FOR_msa_clti_s_d:
+ case CODE_FOR_msa_clei_s_b:
+ case CODE_FOR_msa_clei_s_h:
+ case CODE_FOR_msa_clei_s_w:
+ case CODE_FOR_msa_clei_s_d:
+ case CODE_FOR_msa_maxi_s_b:
+ case CODE_FOR_msa_maxi_s_h:
+ case CODE_FOR_msa_maxi_s_w:
+ case CODE_FOR_msa_maxi_s_d:
+ case CODE_FOR_msa_mini_s_b:
+ case CODE_FOR_msa_mini_s_h:
+ case CODE_FOR_msa_mini_s_w:
+ case CODE_FOR_msa_mini_s_d:
+ gcc_assert (has_target_p && nops == 3);
+ /* We only generate a vector of constants iff the second argument
+ is an immediate. We also validate the range of the immediate. */
+ if (!CONST_INT_P (ops[2].value)
+ || !IN_RANGE (INTVAL (ops[2].value), -16, 15))
+ break;
+ ops[2].mode = ops[0].mode;
+ ops[2].value = mips_gen_const_int_vector (ops[2].mode,
+ INTVAL (ops[2].value));
+ break;
+
+ case CODE_FOR_msa_andi_b:
+ case CODE_FOR_msa_ori_b:
+ case CODE_FOR_msa_nori_b:
+ case CODE_FOR_msa_xori_b:
+ gcc_assert (has_target_p && nops == 3);
+ if (!CONST_INT_P (ops[2].value))
+ break;
+ ops[2].mode = ops[0].mode;
+ ops[2].value = mips_gen_const_int_vector (ops[2].mode,
+ INTVAL (ops[2].value));
+ break;
+
+ case CODE_FOR_msa_bmzi_b:
+ case CODE_FOR_msa_bmnzi_b:
+ case CODE_FOR_msa_bseli_b:
+ gcc_assert (has_target_p && nops == 4);
+ if (!CONST_INT_P (ops[3].value))
+ break;
+ ops[3].mode = ops[0].mode;
+ ops[3].value = mips_gen_const_int_vector (ops[3].mode,
+ INTVAL (ops[3].value));
+ break;
+
+ case CODE_FOR_msa_fill_b:
+ case CODE_FOR_msa_fill_h:
+ case CODE_FOR_msa_fill_w:
+ case CODE_FOR_msa_fill_d:
+ /* Map the built-ins to vector fill operations. We need fix up the mode
+ for the element being inserted. */
+ gcc_assert (has_target_p && nops == 2);
+ imode = GET_MODE_INNER (ops[0].mode);
+ ops[1].value = lowpart_subreg (imode, ops[1].value, ops[1].mode);
+ ops[1].mode = imode;
+ break;
+
+ case CODE_FOR_msa_ilvl_b:
+ case CODE_FOR_msa_ilvl_h:
+ case CODE_FOR_msa_ilvl_w:
+ case CODE_FOR_msa_ilvl_d:
+ case CODE_FOR_msa_ilvr_b:
+ case CODE_FOR_msa_ilvr_h:
+ case CODE_FOR_msa_ilvr_w:
+ case CODE_FOR_msa_ilvr_d:
+ case CODE_FOR_msa_ilvev_b:
+ case CODE_FOR_msa_ilvev_h:
+ case CODE_FOR_msa_ilvev_w:
+ case CODE_FOR_msa_ilvod_b:
+ case CODE_FOR_msa_ilvod_h:
+ case CODE_FOR_msa_ilvod_w:
+ case CODE_FOR_msa_pckev_b:
+ case CODE_FOR_msa_pckev_h:
+ case CODE_FOR_msa_pckev_w:
+ case CODE_FOR_msa_pckod_b:
+ case CODE_FOR_msa_pckod_h:
+ case CODE_FOR_msa_pckod_w:
+ /* Swap the operands 1 and 2 for interleave operations. Built-ins follow
+ convention of ISA, which have op1 as higher component and op2 as lower
+ component. However, the VEC_PERM op in tree and vec_concat in RTL
+ expects first operand to be lower component, because of which this
+ swap is needed for builtins. */
+ gcc_assert (has_target_p && nops == 3);
+ std::swap (ops[1], ops[2]);
+ break;
+
+ case CODE_FOR_msa_slli_b:
+ case CODE_FOR_msa_slli_h:
+ case CODE_FOR_msa_slli_w:
+ case CODE_FOR_msa_slli_d:
+ case CODE_FOR_msa_srai_b:
+ case CODE_FOR_msa_srai_h:
+ case CODE_FOR_msa_srai_w:
+ case CODE_FOR_msa_srai_d:
+ case CODE_FOR_msa_srli_b:
+ case CODE_FOR_msa_srli_h:
+ case CODE_FOR_msa_srli_w:
+ case CODE_FOR_msa_srli_d:
+ gcc_assert (has_target_p && nops == 3);
+ if (!CONST_INT_P (ops[2].value)
+ || !IN_RANGE (INTVAL (ops[2].value), 0,
+ GET_MODE_UNIT_PRECISION (ops[0].mode) - 1))
+ break;
+ ops[2].mode = ops[0].mode;
+ ops[2].value = mips_gen_const_int_vector (ops[2].mode,
+ INTVAL (ops[2].value));
+ break;
+
+ case CODE_FOR_msa_insert_b:
+ case CODE_FOR_msa_insert_h:
+ case CODE_FOR_msa_insert_w:
+ case CODE_FOR_msa_insert_d:
+ /* Map the built-ins to insert operations. We need to swap operands,
+ fix up the mode for the element being inserted, and generate
+ a bit mask for vec_merge. */
+ gcc_assert (has_target_p && nops == 4);
+ std::swap (ops[1], ops[2]);
+ std::swap (ops[1], ops[3]);
+ imode = GET_MODE_INNER (ops[0].mode);
+ ops[1].value = lowpart_subreg (imode, ops[1].value, ops[1].mode);
+ ops[1].mode = imode;
+ ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
+ break;
+
+ case CODE_FOR_msa_insve_b:
+ case CODE_FOR_msa_insve_h:
+ case CODE_FOR_msa_insve_w:
+ case CODE_FOR_msa_insve_d:
+ /* Map the built-ins to element insert operations. We need to swap
+ operands and generate a bit mask. */
+ gcc_assert (has_target_p && nops == 4);
+ std::swap (ops[1], ops[2]);
+ std::swap (ops[1], ops[3]);
+ ops[3].value = GEN_INT (1 << INTVAL (ops[3].value));
+ break;
+
+ case CODE_FOR_msa_shf_b:
+ case CODE_FOR_msa_shf_h:
+ case CODE_FOR_msa_shf_w:
+ case CODE_FOR_msa_shf_w_f:
+ gcc_assert (has_target_p && nops == 3);
+ ops[2].value = mips_gen_const_int_vector_shuffle (ops[0].mode,
+ INTVAL (ops[2].value));
+ break;
+
+ case CODE_FOR_msa_vshf_b:
+ case CODE_FOR_msa_vshf_h:
+ case CODE_FOR_msa_vshf_w:
+ case CODE_FOR_msa_vshf_d:
+ gcc_assert (has_target_p && nops == 4);
+ std::swap (ops[1], ops[3]);
+ break;
+
+ default:
+ break;
+ }
+
if (!maybe_expand_insn (icode, nops, ops))
{
error ("invalid argument to built-in function");
@@ -15182,6 +16833,50 @@ mips_expand_builtin_movtf (enum mips_builtin_type type,
4, ops, true);
}
+/* Expand an MSA built-in for a compare and branch instruction specified by
+ ICODE, set a general-purpose register to 1 if the branch was taken,
+ 0 otherwise. */
+
+static rtx
+mips_expand_builtin_msa_test_branch (enum insn_code icode, tree exp)
+{
+ struct expand_operand ops[3];
+ rtx_insn *cbranch;
+ rtx_code_label *true_label, *done_label;
+ rtx cmp_result;
+
+ true_label = gen_label_rtx ();
+ done_label = gen_label_rtx ();
+
+ create_input_operand (&ops[0], true_label, TYPE_MODE (TREE_TYPE (exp)));
+ mips_prepare_builtin_arg (&ops[1], exp, 0);
+ create_fixed_operand (&ops[2], const0_rtx);
+
+ /* Make sure that the operand 1 is a REG. */
+ if (GET_CODE (ops[1].value) != REG)
+ ops[1].value = force_reg (ops[1].mode, ops[1].value);
+
+ if ((cbranch = maybe_gen_insn (icode, 3, ops)) == NULL_RTX)
+ error ("failed to expand built-in function");
+
+ cmp_result = gen_reg_rtx (SImode);
+
+ /* First assume that CMP_RESULT is false. */
+ mips_emit_move (cmp_result, const0_rtx);
+
+ /* Branch to TRUE_LABEL if CBRANCH is taken and DONE_LABEL otherwise. */
+ emit_jump_insn (cbranch);
+ emit_jump_insn (gen_jump (done_label));
+ emit_barrier ();
+
+ /* Set CMP_RESULT to true if the branch was taken. */
+ emit_label (true_label);
+ mips_emit_move (cmp_result, const1_rtx);
+
+ emit_label (done_label);
+ return cmp_result;
+}
+
/* Move VALUE_IF_TRUE into TARGET if CONDITION is true; move VALUE_IF_FALSE
into TARGET otherwise. Return TARGET. */
@@ -15318,6 +17013,9 @@ mips_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
return mips_expand_builtin_compare (d->builtin_type, d->icode,
d->cond, target, exp);
+ case MIPS_BUILTIN_MSA_TEST_BRANCH:
+ return mips_expand_builtin_msa_test_branch (d->icode, exp);
+
case MIPS_BUILTIN_BPOSGE32:
return mips_expand_builtin_bposge (d->builtin_type, target);
}
@@ -17592,6 +19290,9 @@ mips_set_compression_mode (unsigned int compression_mode)
if (TARGET_HARD_FLOAT_ABI && !TARGET_OLDABI)
sorry ("hard-float MIPS16 code for ABIs other than o32 and o64");
+
+ if (TARGET_MSA)
+ sorry ("MSA MIPS16 code");
}
else
{
@@ -17768,6 +19469,11 @@ mips_option_override (void)
if (TARGET_MICROMIPS && TARGET_MIPS16)
error ("unsupported combination: %s", "-mips16 -mmicromips");
+ /* Prohibit Paired-Single and MSA combination. This is software restriction
+ rather than architectural. */
+ if (ISA_HAS_MSA && TARGET_PAIRED_SINGLE_FLOAT)
+ error ("unsupported combination: %s", "-mmsa -mpaired-single");
+
/* Save the base compression state and process flags as though we
were generating uncompressed code. */
mips_base_compression_flags = TARGET_COMPRESSION;
@@ -17871,6 +19577,8 @@ mips_option_override (void)
target_flags |= MASK_FLOAT64;
else if (TARGET_64BIT && TARGET_DOUBLE_FLOAT)
target_flags |= MASK_FLOAT64;
+ else if (mips_abi == ABI_32 && ISA_HAS_MSA && !TARGET_FLOATXX)
+ target_flags |= MASK_FLOAT64;
else
target_flags &= ~MASK_FLOAT64;
}
@@ -18129,6 +19837,11 @@ mips_option_override (void)
TARGET_MIPS3D = 0;
}
+ /* Make sure that when ISA_HAS_MSA is true, TARGET_FLOAT64 and
+ TARGET_HARD_FLOAT_ABI and both true. */
+ if (ISA_HAS_MSA && !(TARGET_FLOAT64 && TARGET_HARD_FLOAT_ABI))
+ error ("%<-mmsa%> must be used with %<-mfp64%> and %<-mhard-float%>");
+
/* Make sure that -mpaired-single is only used on ISAs that support it.
We must disable it otherwise since it relies on other ISA properties
like ISA_HAS_8CC having their normal values. */
@@ -19164,7 +20877,7 @@ mips_prepare_pch_save (void)
/* Generate or test for an insn that supports a constant permutation. */
-#define MAX_VECT_LEN 8
+#define MAX_VECT_LEN 16
struct expand_vec_perm_d
{
@@ -19368,6 +21081,41 @@ mips_expand_vpc_loongson_bcast (struct expand_vec_perm_d *d)
return true;
}
+/* Construct (set target (vec_select op0 (parallel selector))) and
+ return true if that's a valid instruction in the active ISA. */
+
+static bool
+mips_expand_msa_shuffle (struct expand_vec_perm_d *d)
+{
+ rtx x, elts[MAX_VECT_LEN];
+ rtvec v;
+ rtx_insn *insn;
+ unsigned i;
+
+ if (!ISA_HAS_MSA)
+ return false;
+
+ for (i = 0; i < d->nelt; i++)
+ elts[i] = GEN_INT (d->perm[i]);
+
+ v = gen_rtvec_v (d->nelt, elts);
+ x = gen_rtx_PARALLEL (VOIDmode, v);
+
+ if (!mips_const_vector_shuffle_set_p (x, d->vmode))
+ return false;
+
+ x = gen_rtx_VEC_SELECT (d->vmode, d->op0, x);
+ x = gen_rtx_SET (d->target, x);
+
+ insn = emit_insn (x);
+ if (recog_memoized (insn) < 0)
+ {
+ remove_insn (insn);
+ return false;
+ }
+ return true;
+}
+
static bool
mips_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
{
@@ -19402,6 +21150,8 @@ mips_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
return true;
if (mips_expand_vpc_loongson_bcast (d))
return true;
+ if (mips_expand_msa_shuffle (d))
+ return true;
return false;
}
@@ -19480,6 +21230,17 @@ mips_expand_vec_perm_const (rtx operands[4])
return ok;
}
+/* Implement TARGET_SCHED_REASSOCIATION_WIDTH. */
+
+static int
+mips_sched_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED,
+ machine_mode mode)
+{
+ if (MSA_SUPPORTED_MODE_P (mode))
+ return 2;
+ return 1;
+}
+
/* Implement TARGET_VECTORIZE_VEC_PERM_CONST_OK. */
static bool
@@ -19530,9 +21291,62 @@ mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p)
{
machine_mode imode = GET_MODE (operands[1]);
rtx (*unpack) (rtx, rtx, rtx);
- rtx (*cmpgt) (rtx, rtx, rtx);
+ rtx (*cmpFunc) (rtx, rtx, rtx);
rtx tmp, dest, zero;
+ if (ISA_HAS_MSA)
+ {
+ switch (imode)
+ {
+ case V4SImode:
+ if (BYTES_BIG_ENDIAN != high_p)
+ unpack = gen_msa_ilvl_w;
+ else
+ unpack = gen_msa_ilvr_w;
+
+ cmpFunc = gen_msa_clt_s_w;
+ break;
+
+ case V8HImode:
+ if (BYTES_BIG_ENDIAN != high_p)
+ unpack = gen_msa_ilvl_h;
+ else
+ unpack = gen_msa_ilvr_h;
+
+ cmpFunc = gen_msa_clt_s_h;
+ break;
+
+ case V16QImode:
+ if (BYTES_BIG_ENDIAN != high_p)
+ unpack = gen_msa_ilvl_b;
+ else
+ unpack = gen_msa_ilvr_b;
+
+ cmpFunc = gen_msa_clt_s_b;
+ break;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+
+ if (!unsigned_p)
+ {
+ /* Extract sign extention for each element comparing each element
+ with immediate zero. */
+ tmp = gen_reg_rtx (imode);
+ emit_insn (cmpFunc (tmp, operands[1], CONST0_RTX (imode)));
+ }
+ else
+ tmp = force_reg (imode, CONST0_RTX (imode));
+
+ dest = gen_reg_rtx (imode);
+
+ emit_insn (unpack (dest, operands[1], tmp));
+ emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), dest));
+ return;
+ }
+
switch (imode)
{
case V8QImode:
@@ -19540,14 +21354,14 @@ mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p)
unpack = gen_loongson_punpckhbh;
else
unpack = gen_loongson_punpcklbh;
- cmpgt = gen_loongson_pcmpgtb;
+ cmpFunc = gen_loongson_pcmpgtb;
break;
case V4HImode:
if (high_p)
unpack = gen_loongson_punpckhhw;
else
unpack = gen_loongson_punpcklhw;
- cmpgt = gen_loongson_pcmpgth;
+ cmpFunc = gen_loongson_pcmpgth;
break;
default:
gcc_unreachable ();
@@ -19559,7 +21373,7 @@ mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p)
else
{
tmp = gen_reg_rtx (imode);
- emit_insn (cmpgt (tmp, zero, operands[1]));
+ emit_insn (cmpFunc (tmp, zero, operands[1]));
}
dest = gen_reg_rtx (imode);
@@ -19568,6 +21382,28 @@ mips_expand_vec_unpack (rtx operands[2], bool unsigned_p, bool high_p)
emit_move_insn (operands[0], gen_lowpart (GET_MODE (operands[0]), dest));
}
+/* Construct and return PARALLEL RTX with CONST_INTs for HIGH (high_p == TRUE)
+ or LOW (high_p == FALSE) half of a vector for mode MODE. */
+
+rtx
+mips_msa_vec_parallel_const_half (machine_mode mode, bool high_p)
+{
+ int nunits = GET_MODE_NUNITS (mode);
+ rtvec v = rtvec_alloc (nunits / 2);
+ int base;
+ int i;
+
+ if (BYTES_BIG_ENDIAN)
+ base = high_p ? 0 : nunits / 2;
+ else
+ base = high_p ? nunits / 2 : 0;
+
+ for (i = 0; i < nunits / 2; i++)
+ RTVEC_ELT (v, i) = GEN_INT (base + i);
+
+ return gen_rtx_PARALLEL (VOIDmode, v);
+}
+
/* A subroutine of mips_expand_vec_init, match constant vector elements. */
static inline bool
@@ -19615,6 +21451,42 @@ mips_expand_vi_broadcast (machine_mode vmode, rtx target, rtx elt)
gcc_assert (ok);
}
+/* Return a const_int vector of VAL with mode MODE. */
+
+rtx
+mips_gen_const_int_vector (machine_mode mode, int val)
+{
+ int nunits = GET_MODE_NUNITS (mode);
+ rtvec v = rtvec_alloc (nunits);
+ int i;
+
+ for (i = 0; i < nunits; i++)
+ RTVEC_ELT (v, i) = gen_int_mode (val, GET_MODE_INNER (mode));
+
+ return gen_rtx_CONST_VECTOR (mode, v);
+}
+
+/* Return a vector of repeated 4-element sets generated from
+ immediate VAL in mode MODE. */
+
+static rtx
+mips_gen_const_int_vector_shuffle (machine_mode mode, int val)
+{
+ int nunits = GET_MODE_NUNITS (mode);
+ int nsets = nunits / 4;
+ rtx elts[MAX_VECT_LEN];
+ int set = 0;
+ int i, j;
+
+ /* Generate a const_int vector replicating the same 4-element set
+ from an immediate. */
+ for (j = 0; j < nsets; j++, set = 4 * j)
+ for (i = 0; i < 4; i++)
+ elts[set + i] = GEN_INT (set + ((val >> (2 * i)) & 0x3));
+
+ return gen_rtx_PARALLEL (VOIDmode, gen_rtvec_v (nunits, elts));
+}
+
/* A subroutine of mips_expand_vec_init, replacing all of the non-constant
elements of VALS with zeros, copy the constant vector to TARGET. */
@@ -19627,8 +21499,9 @@ mips_expand_vi_constant (machine_mode vmode, unsigned nelt,
for (i = 0; i < nelt; ++i)
{
- if (!mips_constant_elt_p (RTVEC_ELT (vec, i)))
- RTVEC_ELT (vec, i) = const0_rtx;
+ rtx elem = RTVEC_ELT (vec, i);
+ if (!mips_constant_elt_p (elem))
+ RTVEC_ELT (vec, i) = CONST0_RTX (GET_MODE (elem));
}
emit_move_insn (target, gen_rtx_CONST_VECTOR (vmode, vec));
@@ -19689,6 +21562,106 @@ mips_expand_vector_init (rtx target, rtx vals)
all_same = false;
}
+ if (ISA_HAS_MSA)
+ {
+ if (all_same)
+ {
+ rtx same = XVECEXP (vals, 0, 0);
+ rtx temp, temp2;
+
+ if (CONST_INT_P (same) && nvar == 0
+ && mips_signed_immediate_p (INTVAL (same), 10, 0))
+ {
+ switch (vmode)
+ {
+ case V16QImode:
+ case V8HImode:
+ case V4SImode:
+ case V2DImode:
+ emit_move_insn (target, same);
+ return;
+
+ default:
+ break;
+ }
+ }
+ temp = gen_reg_rtx (imode);
+ if (imode == GET_MODE (same))
+ temp2 = same;
+ else if (GET_MODE_SIZE (imode) >= UNITS_PER_WORD)
+ temp2 = simplify_gen_subreg (imode, same, GET_MODE (same), 0);
+ else
+ temp2 = lowpart_subreg (imode, same, GET_MODE (same));
+ emit_move_insn (temp, temp2);
+
+ switch (vmode)
+ {
+ case V16QImode:
+ case V8HImode:
+ case V4SImode:
+ case V2DImode:
+ mips_emit_move (target, gen_rtx_VEC_DUPLICATE (vmode, temp));
+ break;
+
+ case V4SFmode:
+ emit_insn (gen_msa_splati_w_f_scalar (target, temp));
+ break;
+
+ case V2DFmode:
+ emit_insn (gen_msa_splati_d_f_scalar (target, temp));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ {
+ rtvec vec = shallow_copy_rtvec (XVEC (vals, 0));
+
+ for (i = 0; i < nelt; ++i)
+ RTVEC_ELT (vec, i) = CONST0_RTX (imode);
+
+ emit_move_insn (target, gen_rtx_CONST_VECTOR (vmode, vec));
+
+ for (i = 0; i < nelt; ++i)
+ {
+ rtx temp = gen_reg_rtx (imode);
+ emit_move_insn (temp, XVECEXP (vals, 0, i));
+ switch (vmode)
+ {
+ case V16QImode:
+ emit_insn (gen_vec_setv16qi (target, temp, GEN_INT (i)));
+ break;
+
+ case V8HImode:
+ emit_insn (gen_vec_setv8hi (target, temp, GEN_INT (i)));
+ break;
+
+ case V4SImode:
+ emit_insn (gen_vec_setv4si (target, temp, GEN_INT (i)));
+ break;
+
+ case V2DImode:
+ emit_insn (gen_vec_setv2di (target, temp, GEN_INT (i)));
+ break;
+
+ case V4SFmode:
+ emit_insn (gen_vec_setv4sf (target, temp, GEN_INT (i)));
+ break;
+
+ case V2DFmode:
+ emit_insn (gen_vec_setv2df (target, temp, GEN_INT (i)));
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
+ }
+ return;
+ }
+
/* Load constants from the pool, or whatever's handy. */
if (nvar == 0)
{
@@ -19839,6 +21812,169 @@ mips_hard_regno_caller_save_mode (unsigned int regno,
return mode;
}
+/* Generate RTL for comparing CMP_OP0 and CMP_OP1 using condition COND and
+ store the result -1 or 0 in DEST. */
+
+static void
+mips_expand_msa_cmp (rtx dest, enum rtx_code cond, rtx op0, rtx op1)
+{
+ machine_mode cmp_mode = GET_MODE (op0);
+ int unspec = -1;
+ bool negate = false;
+
+ switch (cmp_mode)
+ {
+ case V16QImode:
+ case V8HImode:
+ case V4SImode:
+ case V2DImode:
+ switch (cond)
+ {
+ case NE:
+ cond = reverse_condition (cond);
+ negate = true;
+ break;
+ case EQ:
+ case LT:
+ case LE:
+ case LTU:
+ case LEU:
+ break;
+ case GE:
+ case GT:
+ case GEU:
+ case GTU:
+ std::swap (op0, op1);
+ cond = swap_condition (cond);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ mips_emit_binary (cond, dest, op0, op1);
+ if (negate)
+ emit_move_insn (dest, gen_rtx_NOT (GET_MODE (dest), dest));
+ break;
+
+ case V4SFmode:
+ case V2DFmode:
+ switch (cond)
+ {
+ case UNORDERED:
+ case ORDERED:
+ case EQ:
+ case NE:
+ case UNEQ:
+ case UNLE:
+ case UNLT:
+ break;
+ case LTGT: cond = NE; break;
+ case UNGE: cond = UNLE; std::swap (op0, op1); break;
+ case UNGT: cond = UNLT; std::swap (op0, op1); break;
+ case LE: unspec = UNSPEC_MSA_FSLE; break;
+ case LT: unspec = UNSPEC_MSA_FSLT; break;
+ case GE: unspec = UNSPEC_MSA_FSLE; std::swap (op0, op1); break;
+ case GT: unspec = UNSPEC_MSA_FSLT; std::swap (op0, op1); break;
+ default:
+ gcc_unreachable ();
+ }
+ if (unspec < 0)
+ mips_emit_binary (cond, dest, op0, op1);
+ else
+ {
+ rtx x = gen_rtx_UNSPEC (GET_MODE (dest),
+ gen_rtvec (2, op0, op1), unspec);
+ emit_insn (gen_rtx_SET (dest, x));
+ }
+ break;
+
+ default:
+ gcc_unreachable ();
+ break;
+ }
+}
+
+/* Expand VEC_COND_EXPR, where:
+ MODE is mode of the result
+ VIMODE equivalent integer mode
+ OPERANDS operands of VEC_COND_EXPR. */
+
+void
+mips_expand_vec_cond_expr (machine_mode mode, machine_mode vimode,
+ rtx *operands)
+{
+ rtx cond = operands[3];
+ rtx cmp_op0 = operands[4];
+ rtx cmp_op1 = operands[5];
+ rtx cmp_res = gen_reg_rtx (vimode);
+
+ mips_expand_msa_cmp (cmp_res, GET_CODE (cond), cmp_op0, cmp_op1);
+
+ /* We handle the following cases:
+ 1) r = a CMP b ? -1 : 0
+ 2) r = a CMP b ? -1 : v
+ 3) r = a CMP b ? v : 0
+ 4) r = a CMP b ? v1 : v2 */
+
+ /* Case (1) above. We only move the results. */
+ if (operands[1] == CONSTM1_RTX (vimode)
+ && operands[2] == CONST0_RTX (vimode))
+ emit_move_insn (operands[0], cmp_res);
+ else
+ {
+ rtx src1 = gen_reg_rtx (vimode);
+ rtx src2 = gen_reg_rtx (vimode);
+ rtx mask = gen_reg_rtx (vimode);
+ rtx bsel;
+
+ /* Move the vector result to use it as a mask. */
+ emit_move_insn (mask, cmp_res);
+
+ if (register_operand (operands[1], mode))
+ {
+ rtx xop1 = operands[1];
+ if (mode != vimode)
+ {
+ xop1 = gen_reg_rtx (vimode);
+ emit_move_insn (xop1, gen_rtx_SUBREG (vimode, operands[1], 0));
+ }
+ emit_move_insn (src1, xop1);
+ }
+ else
+ {
+ gcc_assert (operands[1] == CONSTM1_RTX (vimode));
+ /* Case (2) if the below doesn't move the mask to src2. */
+ emit_move_insn (src1, mask);
+ }
+
+ if (register_operand (operands[2], mode))
+ {
+ rtx xop2 = operands[2];
+ if (mode != vimode)
+ {
+ xop2 = gen_reg_rtx (vimode);
+ emit_move_insn (xop2, gen_rtx_SUBREG (vimode, operands[2], 0));
+ }
+ emit_move_insn (src2, xop2);
+ }
+ else
+ {
+ gcc_assert (operands[2] == CONST0_RTX (mode));
+ /* Case (3) if the above didn't move the mask to src1. */
+ emit_move_insn (src2, mask);
+ }
+
+ /* We deal with case (4) if the mask wasn't moved to either src1 or src2.
+ In any case, we eventually do vector mask-based copy. */
+ bsel = gen_rtx_IOR (vimode,
+ gen_rtx_AND (vimode,
+ gen_rtx_NOT (vimode, mask), src2),
+ gen_rtx_AND (vimode, mask, src1));
+ /* The result is placed back to a register with the mask. */
+ emit_insn (gen_rtx_SET (mask, bsel));
+ emit_move_insn (operands[0], gen_rtx_SUBREG (mode, mask, 0));
+ }
+}
+
/* Implement TARGET_CASE_VALUES_THRESHOLD. */
unsigned int
@@ -20120,6 +22256,9 @@ mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
#undef TARGET_MODE_REP_EXTENDED
#define TARGET_MODE_REP_EXTENDED mips_mode_rep_extended
+#undef TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION
+#define TARGET_VECTORIZE_BUILTIN_VECTORIZED_FUNCTION \
+ mips_builtin_vectorized_function
#undef TARGET_VECTOR_MODE_SUPPORTED_P
#define TARGET_VECTOR_MODE_SUPPORTED_P mips_vector_mode_supported_p
@@ -20128,6 +22267,9 @@ mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
#undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
#define TARGET_VECTORIZE_PREFERRED_SIMD_MODE mips_preferred_simd_mode
+#undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
+#define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES \
+ mips_autovectorize_vector_sizes
#undef TARGET_INIT_BUILTINS
#define TARGET_INIT_BUILTINS mips_init_builtins
@@ -20205,6 +22347,9 @@ mips_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
#undef TARGET_VECTORIZE_VEC_PERM_CONST_OK
#define TARGET_VECTORIZE_VEC_PERM_CONST_OK mips_vectorize_vec_perm_const_ok
+#undef TARGET_SCHED_REASSOCIATION_WIDTH
+#define TARGET_SCHED_REASSOCIATION_WIDTH mips_sched_reassociation_width
+
#undef TARGET_CASE_VALUES_THRESHOLD
#define TARGET_CASE_VALUES_THRESHOLD mips_case_values_threshold
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 803ab98e760..e8897d19edd 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -209,10 +209,12 @@ struct mips_cpu_info {
#endif
/* ISA has LSA available. */
-#define ISA_HAS_LSA (mips_isa_rev >= 6)
+#define ISA_HAS_LSA (mips_isa_rev >= 6 || ISA_HAS_MSA)
/* ISA has DLSA available. */
-#define ISA_HAS_DLSA (TARGET_64BIT && mips_isa_rev >= 6)
+#define ISA_HAS_DLSA (TARGET_64BIT \
+ && (mips_isa_rev >= 6 \
+ || ISA_HAS_MSA))
/* The ISA compression flags that are currently in effect. */
#define TARGET_COMPRESSION (target_flags & (MASK_MIPS16 | MASK_MICROMIPS))
@@ -472,6 +474,12 @@ struct mips_cpu_info {
builtin_define ("__mips_dsp_rev=1"); \
} \
\
+ if (ISA_HAS_MSA) \
+ { \
+ builtin_define ("__mips_msa"); \
+ builtin_define ("__mips_msa_width=128"); \
+ } \
+ \
MIPS_CPP_SET_PROCESSOR ("_MIPS_ARCH", mips_arch_info); \
MIPS_CPP_SET_PROCESSOR ("_MIPS_TUNE", mips_tune_info); \
\
@@ -824,7 +832,8 @@ struct mips_cpu_info {
--with-fpu is ignored if -msoft-float, -msingle-float or -mdouble-float are
specified.
--with-nan is ignored if -mnan is specified.
- --with-fp-32 is ignored if -msoft-float, -msingle-float or -mfp are specified.
+ --with-fp-32 is ignored if -msoft-float, -msingle-float, -mmsa or -mfp are
+ specified.
--with-odd-spreg-32 is ignored if -msoft-float, -msingle-float, -modd-spreg
or -mno-odd-spreg are specified.
--with-divide is ignored if -mdivide-traps or -mdivide-breaks are
@@ -841,7 +850,7 @@ struct mips_cpu_info {
{"fpu", "%{!msoft-float:%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}}" }, \
{"nan", "%{!mnan=*:-mnan=%(VALUE)}" }, \
{"fp_32", "%{" OPT_ARCH32 \
- ":%{!msoft-float:%{!msingle-float:%{!mfp*:-mfp%(VALUE)}}}}" }, \
+ ":%{!msoft-float:%{!msingle-float:%{!mfp*:%{!mmsa:-mfp%(VALUE)}}}}}" }, \
{"odd_spreg_32", "%{" OPT_ARCH32 ":%{!msoft-float:%{!msingle-float:" \
"%{!modd-spreg:%{!mno-odd-spreg:-m%(VALUE)}}}}}" }, \
{"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
@@ -1175,6 +1184,9 @@ struct mips_cpu_info {
/* Revision 2 of the DSP ASE is available. */
#define ISA_HAS_DSPR2 (TARGET_DSPR2 && !TARGET_MIPS16)
+/* The MSA ASE is available. */
+#define ISA_HAS_MSA (TARGET_MSA && !TARGET_MIPS16)
+
/* True if the result of a load is not available to the next instruction.
A nop will then be needed between instructions like "lw $4,..."
and "addiu $4,$4,1". */
@@ -1316,6 +1328,7 @@ struct mips_cpu_info {
%{meva} %{mno-eva} \
%{mvirt} %{mno-virt} \
%{mxpa} %{mno-xpa} \
+%{mmsa} %{mno-msa} \
%{msmartmips} %{mno-smartmips} \
%{mmt} %{mno-mt} \
%{mfix-rm7000} %{mno-fix-rm7000} \
@@ -1487,6 +1500,11 @@ FP_ASM_SPEC "\
#define MIN_UNITS_PER_WORD 4
#endif
+/* Width of a MSA vector register in bytes. */
+#define UNITS_PER_MSA_REG 16
+/* Width of a MSA vector register in bits. */
+#define BITS_PER_MSA_REG (UNITS_PER_MSA_REG * BITS_PER_UNIT)
+
/* For MIPS, width of a floating point register. */
#define UNITS_PER_FPREG (TARGET_FLOAT64 ? 8 : 4)
@@ -1559,8 +1577,11 @@ FP_ASM_SPEC "\
/* 8 is observed right on a DECstation and on riscos 4.02. */
#define STRUCTURE_SIZE_BOUNDARY 8
-/* There is no point aligning anything to a rounder boundary than this. */
-#define BIGGEST_ALIGNMENT LONG_DOUBLE_TYPE_SIZE
+/* There is no point aligning anything to a rounder boundary than
+ LONG_DOUBLE_TYPE_SIZE, unless under MSA the bigggest alignment is
+ BITS_PER_MSA_REG. */
+#define BIGGEST_ALIGNMENT \
+ (ISA_HAS_MSA ? BITS_PER_MSA_REG : LONG_DOUBLE_TYPE_SIZE)
/* All accesses must be aligned. */
#define STRICT_ALIGNMENT 1
@@ -1667,7 +1688,7 @@ FP_ASM_SPEC "\
/* The [d]clz instructions have the natural values at 0. */
#define CLZ_DEFINED_VALUE_AT_ZERO(MODE, VALUE) \
- ((VALUE) = GET_MODE_BITSIZE (MODE), 2)
+ ((VALUE) = GET_MODE_UNIT_BITSIZE (MODE), 2)
/* Standard register usage. */
@@ -1798,6 +1819,10 @@ FP_ASM_SPEC "\
#define MD_REG_NUM (MD_REG_LAST - MD_REG_FIRST + 1)
#define MD_DBX_FIRST (FP_DBX_FIRST + FP_REG_NUM)
+#define MSA_REG_FIRST FP_REG_FIRST
+#define MSA_REG_LAST FP_REG_LAST
+#define MSA_REG_NUM FP_REG_NUM
+
/* The DWARF 2 CFA column which tracks the return address from a
signal handler context. This means that to maintain backwards
compatibility, no hard register can be assigned this column if it
@@ -1886,8 +1911,11 @@ FP_ASM_SPEC "\
/* Test if REGNO is hi, lo, or one of the 6 new DSP accumulators. */
#define ACC_REG_P(REGNO) \
(MD_REG_P (REGNO) || DSP_ACC_REG_P (REGNO))
+#define MSA_REG_P(REGNO) \
+ ((unsigned int) ((int) (REGNO) - MSA_REG_FIRST) < MSA_REG_NUM)
#define FP_REG_RTX_P(X) (REG_P (X) && FP_REG_P (REGNO (X)))
+#define MSA_REG_RTX_P(X) (REG_P (X) && MSA_REG_P (REGNO (X)))
/* True if X is (const (unspec [(const_int 0)] UNSPEC_GP)). This is used
to initialize the mips16 gp pseudo register. */
@@ -1916,10 +1944,12 @@ FP_ASM_SPEC "\
mips_hard_regno_caller_save_mode (REGNO, NREGS, MODE)
/* Odd-numbered single-precision registers are not considered callee-saved
- for o32 FPXX as they will be clobbered when run on an FR=1 FPU. */
+ for o32 FPXX as they will be clobbered when run on an FR=1 FPU.
+ MSA vector registers with MODE > 64 bits are part clobbered too. */
#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) \
- (TARGET_FLOATXX && hard_regno_nregs[REGNO][MODE] == 1 \
- && FP_REG_P (REGNO) && ((REGNO) & 1))
+ ((TARGET_FLOATXX && hard_regno_nregs[REGNO][MODE] == 1 \
+ && FP_REG_P (REGNO) && ((REGNO) & 1)) \
+ || (ISA_HAS_MSA && FP_REG_P (REGNO) && GET_MODE_SIZE (MODE) > 8))
#define MODES_TIEABLE_P mips_modes_tieable_p
@@ -2381,6 +2411,13 @@ enum reg_class
#define FP_ARG_FIRST (FP_REG_FIRST + 12)
#define FP_ARG_LAST (FP_ARG_FIRST + MAX_ARGS_IN_REGISTERS - 1)
+/* True if MODE is vector and supported in a MSA vector register. */
+#define MSA_SUPPORTED_MODE_P(MODE) \
+ (ISA_HAS_MSA \
+ && GET_MODE_SIZE (MODE) == UNITS_PER_MSA_REG \
+ && (GET_MODE_CLASS (MODE) == MODE_VECTOR_INT \
+ || GET_MODE_CLASS (MODE) == MODE_VECTOR_FLOAT))
+
/* Temporary register that is used when restoring $gp after a call. $4 and $5
are used for returning complex double values in soft-float code, so $6 is the
first suitable candidate for TARGET_MIPS16. For !TARGET_MIPS16 we can use
@@ -2606,6 +2643,7 @@ typedef struct mips_args {
we generally don't want to use them for copying arbitrary data.
A single N-word move is usually the same cost as N single-word moves. */
#define MOVE_MAX UNITS_PER_WORD
+/* We don't modify it for MSA as it is only used by the classic reload. */
#define MAX_MOVE_MAX 8
/* Define this macro as a C expression which is nonzero if
@@ -2767,7 +2805,39 @@ typedef struct mips_args {
{ "gp", 28 + GP_REG_FIRST }, \
{ "sp", 29 + GP_REG_FIRST }, \
{ "fp", 30 + GP_REG_FIRST }, \
- { "ra", 31 + GP_REG_FIRST } \
+ { "ra", 31 + GP_REG_FIRST }, \
+ { "$w0", 0 + FP_REG_FIRST }, \
+ { "$w1", 1 + FP_REG_FIRST }, \
+ { "$w2", 2 + FP_REG_FIRST }, \
+ { "$w3", 3 + FP_REG_FIRST }, \
+ { "$w4", 4 + FP_REG_FIRST }, \
+ { "$w5", 5 + FP_REG_FIRST }, \
+ { "$w6", 6 + FP_REG_FIRST }, \
+ { "$w7", 7 + FP_REG_FIRST }, \
+ { "$w8", 8 + FP_REG_FIRST }, \
+ { "$w9", 9 + FP_REG_FIRST }, \
+ { "$w10", 10 + FP_REG_FIRST }, \
+ { "$w11", 11 + FP_REG_FIRST }, \
+ { "$w12", 12 + FP_REG_FIRST }, \
+ { "$w13", 13 + FP_REG_FIRST }, \
+ { "$w14", 14 + FP_REG_FIRST }, \
+ { "$w15", 15 + FP_REG_FIRST }, \
+ { "$w16", 16 + FP_REG_FIRST }, \
+ { "$w17", 17 + FP_REG_FIRST }, \
+ { "$w18", 18 + FP_REG_FIRST }, \
+ { "$w19", 19 + FP_REG_FIRST }, \
+ { "$w20", 20 + FP_REG_FIRST }, \
+ { "$w21", 21 + FP_REG_FIRST }, \
+ { "$w22", 22 + FP_REG_FIRST }, \
+ { "$w23", 23 + FP_REG_FIRST }, \
+ { "$w24", 24 + FP_REG_FIRST }, \
+ { "$w25", 25 + FP_REG_FIRST }, \
+ { "$w26", 26 + FP_REG_FIRST }, \
+ { "$w27", 27 + FP_REG_FIRST }, \
+ { "$w28", 28 + FP_REG_FIRST }, \
+ { "$w29", 29 + FP_REG_FIRST }, \
+ { "$w30", 30 + FP_REG_FIRST }, \
+ { "$w31", 31 + FP_REG_FIRST } \
}
#define DBR_OUTPUT_SEQEND(STREAM) \
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index 188308aae83..d8d564fabd9 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -225,11 +225,12 @@
shift_shift"
(const_string "unknown"))
-(define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor"
+(define_attr "alu_type" "unknown,add,sub,not,nor,and,or,xor,simd_add"
(const_string "unknown"))
;; Main data type used by the insn
-(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW"
+(define_attr "mode" "unknown,none,QI,HI,SI,DI,TI,SF,DF,TF,FPSW,
+ V2DI,V4SI,V8HI,V16QI,V2DF,V4SF"
(const_string "unknown"))
;; True if the main data type is twice the size of a word.
@@ -243,6 +244,13 @@
(const_string "yes")]
(const_string "no")))
+;; True if the main data type is four times of the size of a word.
+(define_attr "qword_mode" "no,yes"
+ (cond [(and (eq_attr "mode" "TI,TF")
+ (not (match_test "TARGET_64BIT")))
+ (const_string "yes")]
+ (const_string "no")))
+
;; Attributes describing a sync loop. These loops have the form:
;;
;; if (RELEASE_BARRIER == YES) sync
@@ -365,7 +373,12 @@
shift,slt,signext,clz,pop,trap,imul,imul3,imul3nc,imadd,idiv,idiv3,move,
fmove,fadd,fmul,fmadd,fdiv,frdiv,frdiv1,frdiv2,fabs,fneg,fcmp,fcvt,fsqrt,
frsqrt,frsqrt1,frsqrt2,dspmac,dspmacsat,accext,accmod,dspalu,dspalusat,
- multi,atomic,syncloop,nop,ghost,multimem"
+ multi,atomic,syncloop,nop,ghost,multimem,
+ simd_div,simd_fclass,simd_flog2,simd_fadd,simd_fcvt,simd_fmul,simd_fmadd,
+ simd_fdiv,simd_bitins,simd_bitmov,simd_insert,simd_sld,simd_mul,simd_fcmp,
+ simd_fexp2,simd_int_arith,simd_bit,simd_shift,simd_splat,simd_fill,
+ simd_permute,simd_shf,simd_sat,simd_pcnt,simd_copy,simd_branch,simd_cmsa,
+ simd_fminmax,simd_logic,simd_move,simd_load,simd_store"
(cond [(eq_attr "jal" "!unset") (const_string "call")
(eq_attr "got" "load") (const_string "load")
@@ -400,6 +413,11 @@
(eq_attr "move_type" "constN,shift_shift")
(const_string "multi")
+ ;; These types of move are split for quadword modes only.
+ (and (eq_attr "move_type" "move,const")
+ (eq_attr "qword_mode" "yes"))
+ (const_string "multi")
+
;; These types of move are split for doubleword modes only.
(and (eq_attr "move_type" "move,const")
(eq_attr "dword_mode" "yes"))
@@ -486,6 +504,12 @@
(eq_attr "dword_mode" "yes"))
(const_int 2)
+ ;; Check for quadword moves that are decomposed into four
+ ;; instructions.
+ (and (eq_attr "move_type" "mtc,mfc,move")
+ (eq_attr "qword_mode" "yes"))
+ (const_int 4)
+
;; Constants, loads and stores are handled by external routines.
(and (eq_attr "move_type" "const,constN")
(eq_attr "dword_mode" "yes"))
@@ -527,7 +551,7 @@
(const_int 2)
(eq_attr "type" "idiv,idiv3")
- (symbol_ref "mips_idiv_insns ()")
+ (symbol_ref "mips_idiv_insns (GET_MODE (PATTERN (insn)))")
(not (eq_attr "sync_mem" "none"))
(symbol_ref "mips_sync_loop_insns (insn, operands)")]
@@ -884,8 +908,10 @@
(define_mode_attr fmt [(SF "s") (DF "d") (V2SF "ps")])
;; This attribute gives the upper-case mode name for one unit of a
-;; floating-point mode.
-(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF")])
+;; floating-point mode or vector mode.
+(define_mode_attr UNITMODE [(SF "SF") (DF "DF") (V2SF "SF") (V4SF "SF")
+ (V16QI "QI") (V8HI "HI") (V4SI "SI") (V2DI "DI")
+ (V2DF "DF")])
;; This attribute gives the integer mode that has the same size as a
;; fixed-point mode.
@@ -941,6 +967,10 @@
;; from the same template.
(define_code_iterator any_mod [mod umod])
+;; This code iterator allows addition and subtraction to be generated
+;; from the same template.
+(define_code_iterator addsub [plus minus])
+
;; This code iterator allows all native floating-point comparisons to be
;; generated from the same template.
(define_code_iterator fcond [unordered uneq unlt unle eq lt le
@@ -7634,6 +7664,9 @@
; ST-Microelectronics Loongson-2E/2F-specific patterns.
(include "loongson.md")
+; The MIPS MSA Instructions.
+(include "mips-msa.md")
+
(define_c_enum "unspec" [
UNSPEC_ADDRESS_FIRST
])
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index ebd67e4bdb9..08dd83e14ce 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -299,6 +299,10 @@ mmicromips
Target Report Mask(MICROMIPS)
Use microMIPS instructions.
+mmsa
+Target Report Var(TARGET_MSA)
+Use MIPS MSA Extension instructions.
+
mmt
Target Report Var(TARGET_MT)
Allow the use of MT instructions.
diff --git a/gcc/config/mips/msa.h b/gcc/config/mips/msa.h
new file mode 100644
index 00000000000..341eb7f81d1
--- /dev/null
+++ b/gcc/config/mips/msa.h
@@ -0,0 +1,582 @@
+/* MIPS MSA intrinsics include file.
+
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ Contributed by Imagination Technologies Ltd.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published
+ by the Free Software Foundation; either version 3, or (at your
+ option) any later version.
+
+ GCC is distributed in the hope that it will be useful, but WITHOUT
+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
+ License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _MSA_H
+#define _MSA_H 1
+
+#if defined(__mips_msa)
+typedef signed char v16i8 __attribute__ ((vector_size(16), aligned(16)));
+typedef signed char v16i8_b __attribute__ ((vector_size(16), aligned(1)));
+typedef unsigned char v16u8 __attribute__ ((vector_size(16), aligned(16)));
+typedef unsigned char v16u8_b __attribute__ ((vector_size(16), aligned(1)));
+typedef short v8i16 __attribute__ ((vector_size(16), aligned(16)));
+typedef short v8i16_h __attribute__ ((vector_size(16), aligned(2)));
+typedef unsigned short v8u16 __attribute__ ((vector_size(16), aligned(16)));
+typedef unsigned short v8u16_h __attribute__ ((vector_size(16), aligned(2)));
+typedef int v4i32 __attribute__ ((vector_size(16), aligned(16)));
+typedef int v4i32_w __attribute__ ((vector_size(16), aligned(4)));
+typedef unsigned int v4u32 __attribute__ ((vector_size(16), aligned(16)));
+typedef unsigned int v4u32_w __attribute__ ((vector_size(16), aligned(4)));
+typedef long long v2i64 __attribute__ ((vector_size(16), aligned(16)));
+typedef long long v2i64_d __attribute__ ((vector_size(16), aligned(8)));
+typedef unsigned long long v2u64 __attribute__ ((vector_size(16), aligned(16)));
+typedef unsigned long long v2u64_d __attribute__ ((vector_size(16), aligned(8)));
+typedef float v4f32 __attribute__ ((vector_size(16), aligned(16)));
+typedef float v4f32_w __attribute__ ((vector_size(16), aligned(4)));
+typedef double v2f64 __attribute__ ((vector_size(16), aligned(16)));
+typedef double v2f64_d __attribute__ ((vector_size(16), aligned(8)));
+
+#define __msa_sll_b __builtin_msa_sll_b
+#define __msa_sll_h __builtin_msa_sll_h
+#define __msa_sll_w __builtin_msa_sll_w
+#define __msa_sll_d __builtin_msa_sll_d
+#define __msa_slli_b __builtin_msa_slli_b
+#define __msa_slli_h __builtin_msa_slli_h
+#define __msa_slli_w __builtin_msa_slli_w
+#define __msa_slli_d __builtin_msa_slli_d
+#define __msa_sra_b __builtin_msa_sra_b
+#define __msa_sra_h __builtin_msa_sra_h
+#define __msa_sra_w __builtin_msa_sra_w
+#define __msa_sra_d __builtin_msa_sra_d
+#define __msa_srai_b __builtin_msa_srai_b
+#define __msa_srai_h __builtin_msa_srai_h
+#define __msa_srai_w __builtin_msa_srai_w
+#define __msa_srai_d __builtin_msa_srai_d
+#define __msa_srar_b __builtin_msa_srar_b
+#define __msa_srar_h __builtin_msa_srar_h
+#define __msa_srar_w __builtin_msa_srar_w
+#define __msa_srar_d __builtin_msa_srar_d
+#define __msa_srari_b __builtin_msa_srari_b
+#define __msa_srari_h __builtin_msa_srari_h
+#define __msa_srari_w __builtin_msa_srari_w
+#define __msa_srari_d __builtin_msa_srari_d
+#define __msa_srl_b __builtin_msa_srl_b
+#define __msa_srl_h __builtin_msa_srl_h
+#define __msa_srl_w __builtin_msa_srl_w
+#define __msa_srl_d __builtin_msa_srl_d
+#define __msa_srli_b __builtin_msa_srli_b
+#define __msa_srli_h __builtin_msa_srli_h
+#define __msa_srli_w __builtin_msa_srli_w
+#define __msa_srli_d __builtin_msa_srli_d
+#define __msa_srlr_b __builtin_msa_srlr_b
+#define __msa_srlr_h __builtin_msa_srlr_h
+#define __msa_srlr_w __builtin_msa_srlr_w
+#define __msa_srlr_d __builtin_msa_srlr_d
+#define __msa_srlri_b __builtin_msa_srlri_b
+#define __msa_srlri_h __builtin_msa_srlri_h
+#define __msa_srlri_w __builtin_msa_srlri_w
+#define __msa_srlri_d __builtin_msa_srlri_d
+#define __msa_bclr_b __builtin_msa_bclr_b
+#define __msa_bclr_h __builtin_msa_bclr_h
+#define __msa_bclr_w __builtin_msa_bclr_w
+#define __msa_bclr_d __builtin_msa_bclr_d
+#define __msa_bclri_b __builtin_msa_bclri_b
+#define __msa_bclri_h __builtin_msa_bclri_h
+#define __msa_bclri_w __builtin_msa_bclri_w
+#define __msa_bclri_d __builtin_msa_bclri_d
+#define __msa_bset_b __builtin_msa_bset_b
+#define __msa_bset_h __builtin_msa_bset_h
+#define __msa_bset_w __builtin_msa_bset_w
+#define __msa_bset_d __builtin_msa_bset_d
+#define __msa_bseti_b __builtin_msa_bseti_b
+#define __msa_bseti_h __builtin_msa_bseti_h
+#define __msa_bseti_w __builtin_msa_bseti_w
+#define __msa_bseti_d __builtin_msa_bseti_d
+#define __msa_bneg_b __builtin_msa_bneg_b
+#define __msa_bneg_h __builtin_msa_bneg_h
+#define __msa_bneg_w __builtin_msa_bneg_w
+#define __msa_bneg_d __builtin_msa_bneg_d
+#define __msa_bnegi_b __builtin_msa_bnegi_b
+#define __msa_bnegi_h __builtin_msa_bnegi_h
+#define __msa_bnegi_w __builtin_msa_bnegi_w
+#define __msa_bnegi_d __builtin_msa_bnegi_d
+#define __msa_binsl_b __builtin_msa_binsl_b
+#define __msa_binsl_h __builtin_msa_binsl_h
+#define __msa_binsl_w __builtin_msa_binsl_w
+#define __msa_binsl_d __builtin_msa_binsl_d
+#define __msa_binsli_b __builtin_msa_binsli_b
+#define __msa_binsli_h __builtin_msa_binsli_h
+#define __msa_binsli_w __builtin_msa_binsli_w
+#define __msa_binsli_d __builtin_msa_binsli_d
+#define __msa_binsr_b __builtin_msa_binsr_b
+#define __msa_binsr_h __builtin_msa_binsr_h
+#define __msa_binsr_w __builtin_msa_binsr_w
+#define __msa_binsr_d __builtin_msa_binsr_d
+#define __msa_binsri_b __builtin_msa_binsri_b
+#define __msa_binsri_h __builtin_msa_binsri_h
+#define __msa_binsri_w __builtin_msa_binsri_w
+#define __msa_binsri_d __builtin_msa_binsri_d
+#define __msa_addv_b __builtin_msa_addv_b
+#define __msa_addv_h __builtin_msa_addv_h
+#define __msa_addv_w __builtin_msa_addv_w
+#define __msa_addv_d __builtin_msa_addv_d
+#define __msa_addvi_b __builtin_msa_addvi_b
+#define __msa_addvi_h __builtin_msa_addvi_h
+#define __msa_addvi_w __builtin_msa_addvi_w
+#define __msa_addvi_d __builtin_msa_addvi_d
+#define __msa_subv_b __builtin_msa_subv_b
+#define __msa_subv_h __builtin_msa_subv_h
+#define __msa_subv_w __builtin_msa_subv_w
+#define __msa_subv_d __builtin_msa_subv_d
+#define __msa_subvi_b __builtin_msa_subvi_b
+#define __msa_subvi_h __builtin_msa_subvi_h
+#define __msa_subvi_w __builtin_msa_subvi_w
+#define __msa_subvi_d __builtin_msa_subvi_d
+#define __msa_max_s_b __builtin_msa_max_s_b
+#define __msa_max_s_h __builtin_msa_max_s_h
+#define __msa_max_s_w __builtin_msa_max_s_w
+#define __msa_max_s_d __builtin_msa_max_s_d
+#define __msa_maxi_s_b __builtin_msa_maxi_s_b
+#define __msa_maxi_s_h __builtin_msa_maxi_s_h
+#define __msa_maxi_s_w __builtin_msa_maxi_s_w
+#define __msa_maxi_s_d __builtin_msa_maxi_s_d
+#define __msa_max_u_b __builtin_msa_max_u_b
+#define __msa_max_u_h __builtin_msa_max_u_h
+#define __msa_max_u_w __builtin_msa_max_u_w
+#define __msa_max_u_d __builtin_msa_max_u_d
+#define __msa_maxi_u_b __builtin_msa_maxi_u_b
+#define __msa_maxi_u_h __builtin_msa_maxi_u_h
+#define __msa_maxi_u_w __builtin_msa_maxi_u_w
+#define __msa_maxi_u_d __builtin_msa_maxi_u_d
+#define __msa_min_s_b __builtin_msa_min_s_b
+#define __msa_min_s_h __builtin_msa_min_s_h
+#define __msa_min_s_w __builtin_msa_min_s_w
+#define __msa_min_s_d __builtin_msa_min_s_d
+#define __msa_mini_s_b __builtin_msa_mini_s_b
+#define __msa_mini_s_h __builtin_msa_mini_s_h
+#define __msa_mini_s_w __builtin_msa_mini_s_w
+#define __msa_mini_s_d __builtin_msa_mini_s_d
+#define __msa_min_u_b __builtin_msa_min_u_b
+#define __msa_min_u_h __builtin_msa_min_u_h
+#define __msa_min_u_w __builtin_msa_min_u_w
+#define __msa_min_u_d __builtin_msa_min_u_d
+#define __msa_mini_u_b __builtin_msa_mini_u_b
+#define __msa_mini_u_h __builtin_msa_mini_u_h
+#define __msa_mini_u_w __builtin_msa_mini_u_w
+#define __msa_mini_u_d __builtin_msa_mini_u_d
+#define __msa_max_a_b __builtin_msa_max_a_b
+#define __msa_max_a_h __builtin_msa_max_a_h
+#define __msa_max_a_w __builtin_msa_max_a_w
+#define __msa_max_a_d __builtin_msa_max_a_d
+#define __msa_min_a_b __builtin_msa_min_a_b
+#define __msa_min_a_h __builtin_msa_min_a_h
+#define __msa_min_a_w __builtin_msa_min_a_w
+#define __msa_min_a_d __builtin_msa_min_a_d
+#define __msa_ceq_b __builtin_msa_ceq_b
+#define __msa_ceq_h __builtin_msa_ceq_h
+#define __msa_ceq_w __builtin_msa_ceq_w
+#define __msa_ceq_d __builtin_msa_ceq_d
+#define __msa_ceqi_b __builtin_msa_ceqi_b
+#define __msa_ceqi_h __builtin_msa_ceqi_h
+#define __msa_ceqi_w __builtin_msa_ceqi_w
+#define __msa_ceqi_d __builtin_msa_ceqi_d
+#define __msa_clt_s_b __builtin_msa_clt_s_b
+#define __msa_clt_s_h __builtin_msa_clt_s_h
+#define __msa_clt_s_w __builtin_msa_clt_s_w
+#define __msa_clt_s_d __builtin_msa_clt_s_d
+#define __msa_clti_s_b __builtin_msa_clti_s_b
+#define __msa_clti_s_h __builtin_msa_clti_s_h
+#define __msa_clti_s_w __builtin_msa_clti_s_w
+#define __msa_clti_s_d __builtin_msa_clti_s_d
+#define __msa_clt_u_b __builtin_msa_clt_u_b
+#define __msa_clt_u_h __builtin_msa_clt_u_h
+#define __msa_clt_u_w __builtin_msa_clt_u_w
+#define __msa_clt_u_d __builtin_msa_clt_u_d
+#define __msa_clti_u_b __builtin_msa_clti_u_b
+#define __msa_clti_u_h __builtin_msa_clti_u_h
+#define __msa_clti_u_w __builtin_msa_clti_u_w
+#define __msa_clti_u_d __builtin_msa_clti_u_d
+#define __msa_cle_s_b __builtin_msa_cle_s_b
+#define __msa_cle_s_h __builtin_msa_cle_s_h
+#define __msa_cle_s_w __builtin_msa_cle_s_w
+#define __msa_cle_s_d __builtin_msa_cle_s_d
+#define __msa_clei_s_b __builtin_msa_clei_s_b
+#define __msa_clei_s_h __builtin_msa_clei_s_h
+#define __msa_clei_s_w __builtin_msa_clei_s_w
+#define __msa_clei_s_d __builtin_msa_clei_s_d
+#define __msa_cle_u_b __builtin_msa_cle_u_b
+#define __msa_cle_u_h __builtin_msa_cle_u_h
+#define __msa_cle_u_w __builtin_msa_cle_u_w
+#define __msa_cle_u_d __builtin_msa_cle_u_d
+#define __msa_clei_u_b __builtin_msa_clei_u_b
+#define __msa_clei_u_h __builtin_msa_clei_u_h
+#define __msa_clei_u_w __builtin_msa_clei_u_w
+#define __msa_clei_u_d __builtin_msa_clei_u_d
+#define __msa_ld_b __builtin_msa_ld_b
+#define __msa_ld_h __builtin_msa_ld_h
+#define __msa_ld_w __builtin_msa_ld_w
+#define __msa_ld_d __builtin_msa_ld_d
+#define __msa_st_b __builtin_msa_st_b
+#define __msa_st_h __builtin_msa_st_h
+#define __msa_st_w __builtin_msa_st_w
+#define __msa_st_d __builtin_msa_st_d
+#define __msa_sat_s_b __builtin_msa_sat_s_b
+#define __msa_sat_s_h __builtin_msa_sat_s_h
+#define __msa_sat_s_w __builtin_msa_sat_s_w
+#define __msa_sat_s_d __builtin_msa_sat_s_d
+#define __msa_sat_u_b __builtin_msa_sat_u_b
+#define __msa_sat_u_h __builtin_msa_sat_u_h
+#define __msa_sat_u_w __builtin_msa_sat_u_w
+#define __msa_sat_u_d __builtin_msa_sat_u_d
+#define __msa_add_a_b __builtin_msa_add_a_b
+#define __msa_add_a_h __builtin_msa_add_a_h
+#define __msa_add_a_w __builtin_msa_add_a_w
+#define __msa_add_a_d __builtin_msa_add_a_d
+#define __msa_adds_a_b __builtin_msa_adds_a_b
+#define __msa_adds_a_h __builtin_msa_adds_a_h
+#define __msa_adds_a_w __builtin_msa_adds_a_w
+#define __msa_adds_a_d __builtin_msa_adds_a_d
+#define __msa_adds_s_b __builtin_msa_adds_s_b
+#define __msa_adds_s_h __builtin_msa_adds_s_h
+#define __msa_adds_s_w __builtin_msa_adds_s_w
+#define __msa_adds_s_d __builtin_msa_adds_s_d
+#define __msa_adds_u_b __builtin_msa_adds_u_b
+#define __msa_adds_u_h __builtin_msa_adds_u_h
+#define __msa_adds_u_w __builtin_msa_adds_u_w
+#define __msa_adds_u_d __builtin_msa_adds_u_d
+#define __msa_ave_s_b __builtin_msa_ave_s_b
+#define __msa_ave_s_h __builtin_msa_ave_s_h
+#define __msa_ave_s_w __builtin_msa_ave_s_w
+#define __msa_ave_s_d __builtin_msa_ave_s_d
+#define __msa_ave_u_b __builtin_msa_ave_u_b
+#define __msa_ave_u_h __builtin_msa_ave_u_h
+#define __msa_ave_u_w __builtin_msa_ave_u_w
+#define __msa_ave_u_d __builtin_msa_ave_u_d
+#define __msa_aver_s_b __builtin_msa_aver_s_b
+#define __msa_aver_s_h __builtin_msa_aver_s_h
+#define __msa_aver_s_w __builtin_msa_aver_s_w
+#define __msa_aver_s_d __builtin_msa_aver_s_d
+#define __msa_aver_u_b __builtin_msa_aver_u_b
+#define __msa_aver_u_h __builtin_msa_aver_u_h
+#define __msa_aver_u_w __builtin_msa_aver_u_w
+#define __msa_aver_u_d __builtin_msa_aver_u_d
+#define __msa_subs_s_b __builtin_msa_subs_s_b
+#define __msa_subs_s_h __builtin_msa_subs_s_h
+#define __msa_subs_s_w __builtin_msa_subs_s_w
+#define __msa_subs_s_d __builtin_msa_subs_s_d
+#define __msa_subs_u_b __builtin_msa_subs_u_b
+#define __msa_subs_u_h __builtin_msa_subs_u_h
+#define __msa_subs_u_w __builtin_msa_subs_u_w
+#define __msa_subs_u_d __builtin_msa_subs_u_d
+#define __msa_subsuu_s_b __builtin_msa_subsuu_s_b
+#define __msa_subsuu_s_h __builtin_msa_subsuu_s_h
+#define __msa_subsuu_s_w __builtin_msa_subsuu_s_w
+#define __msa_subsuu_s_d __builtin_msa_subsuu_s_d
+#define __msa_subsus_u_b __builtin_msa_subsus_u_b
+#define __msa_subsus_u_h __builtin_msa_subsus_u_h
+#define __msa_subsus_u_w __builtin_msa_subsus_u_w
+#define __msa_subsus_u_d __builtin_msa_subsus_u_d
+#define __msa_asub_s_b __builtin_msa_asub_s_b
+#define __msa_asub_s_h __builtin_msa_asub_s_h
+#define __msa_asub_s_w __builtin_msa_asub_s_w
+#define __msa_asub_s_d __builtin_msa_asub_s_d
+#define __msa_asub_u_b __builtin_msa_asub_u_b
+#define __msa_asub_u_h __builtin_msa_asub_u_h
+#define __msa_asub_u_w __builtin_msa_asub_u_w
+#define __msa_asub_u_d __builtin_msa_asub_u_d
+#define __msa_mulv_b __builtin_msa_mulv_b
+#define __msa_mulv_h __builtin_msa_mulv_h
+#define __msa_mulv_w __builtin_msa_mulv_w
+#define __msa_mulv_d __builtin_msa_mulv_d
+#define __msa_maddv_b __builtin_msa_maddv_b
+#define __msa_maddv_h __builtin_msa_maddv_h
+#define __msa_maddv_w __builtin_msa_maddv_w
+#define __msa_maddv_d __builtin_msa_maddv_d
+#define __msa_msubv_b __builtin_msa_msubv_b
+#define __msa_msubv_h __builtin_msa_msubv_h
+#define __msa_msubv_w __builtin_msa_msubv_w
+#define __msa_msubv_d __builtin_msa_msubv_d
+#define __msa_div_s_b __builtin_msa_div_s_b
+#define __msa_div_s_h __builtin_msa_div_s_h
+#define __msa_div_s_w __builtin_msa_div_s_w
+#define __msa_div_s_d __builtin_msa_div_s_d
+#define __msa_div_u_b __builtin_msa_div_u_b
+#define __msa_div_u_h __builtin_msa_div_u_h
+#define __msa_div_u_w __builtin_msa_div_u_w
+#define __msa_div_u_d __builtin_msa_div_u_d
+#define __msa_hadd_s_h __builtin_msa_hadd_s_h
+#define __msa_hadd_s_w __builtin_msa_hadd_s_w
+#define __msa_hadd_s_d __builtin_msa_hadd_s_d
+#define __msa_hadd_u_h __builtin_msa_hadd_u_h
+#define __msa_hadd_u_w __builtin_msa_hadd_u_w
+#define __msa_hadd_u_d __builtin_msa_hadd_u_d
+#define __msa_hsub_s_h __builtin_msa_hsub_s_h
+#define __msa_hsub_s_w __builtin_msa_hsub_s_w
+#define __msa_hsub_s_d __builtin_msa_hsub_s_d
+#define __msa_hsub_u_h __builtin_msa_hsub_u_h
+#define __msa_hsub_u_w __builtin_msa_hsub_u_w
+#define __msa_hsub_u_d __builtin_msa_hsub_u_d
+#define __msa_mod_s_b __builtin_msa_mod_s_b
+#define __msa_mod_s_h __builtin_msa_mod_s_h
+#define __msa_mod_s_w __builtin_msa_mod_s_w
+#define __msa_mod_s_d __builtin_msa_mod_s_d
+#define __msa_mod_u_b __builtin_msa_mod_u_b
+#define __msa_mod_u_h __builtin_msa_mod_u_h
+#define __msa_mod_u_w __builtin_msa_mod_u_w
+#define __msa_mod_u_d __builtin_msa_mod_u_d
+#define __msa_dotp_s_h __builtin_msa_dotp_s_h
+#define __msa_dotp_s_w __builtin_msa_dotp_s_w
+#define __msa_dotp_s_d __builtin_msa_dotp_s_d
+#define __msa_dotp_u_h __builtin_msa_dotp_u_h
+#define __msa_dotp_u_w __builtin_msa_dotp_u_w
+#define __msa_dotp_u_d __builtin_msa_dotp_u_d
+#define __msa_dpadd_s_h __builtin_msa_dpadd_s_h
+#define __msa_dpadd_s_w __builtin_msa_dpadd_s_w
+#define __msa_dpadd_s_d __builtin_msa_dpadd_s_d
+#define __msa_dpadd_u_h __builtin_msa_dpadd_u_h
+#define __msa_dpadd_u_w __builtin_msa_dpadd_u_w
+#define __msa_dpadd_u_d __builtin_msa_dpadd_u_d
+#define __msa_dpsub_s_h __builtin_msa_dpsub_s_h
+#define __msa_dpsub_s_w __builtin_msa_dpsub_s_w
+#define __msa_dpsub_s_d __builtin_msa_dpsub_s_d
+#define __msa_dpsub_u_h __builtin_msa_dpsub_u_h
+#define __msa_dpsub_u_w __builtin_msa_dpsub_u_w
+#define __msa_dpsub_u_d __builtin_msa_dpsub_u_d
+#define __msa_sld_b __builtin_msa_sld_b
+#define __msa_sld_h __builtin_msa_sld_h
+#define __msa_sld_w __builtin_msa_sld_w
+#define __msa_sld_d __builtin_msa_sld_d
+#define __msa_sldi_b __builtin_msa_sldi_b
+#define __msa_sldi_h __builtin_msa_sldi_h
+#define __msa_sldi_w __builtin_msa_sldi_w
+#define __msa_sldi_d __builtin_msa_sldi_d
+#define __msa_splat_b __builtin_msa_splat_b
+#define __msa_splat_h __builtin_msa_splat_h
+#define __msa_splat_w __builtin_msa_splat_w
+#define __msa_splat_d __builtin_msa_splat_d
+#define __msa_splati_b __builtin_msa_splati_b
+#define __msa_splati_h __builtin_msa_splati_h
+#define __msa_splati_w __builtin_msa_splati_w
+#define __msa_splati_d __builtin_msa_splati_d
+#define __msa_pckev_b __builtin_msa_pckev_b
+#define __msa_pckev_h __builtin_msa_pckev_h
+#define __msa_pckev_w __builtin_msa_pckev_w
+#define __msa_pckev_d __builtin_msa_pckev_d
+#define __msa_pckod_b __builtin_msa_pckod_b
+#define __msa_pckod_h __builtin_msa_pckod_h
+#define __msa_pckod_w __builtin_msa_pckod_w
+#define __msa_pckod_d __builtin_msa_pckod_d
+#define __msa_ilvl_b __builtin_msa_ilvl_b
+#define __msa_ilvl_h __builtin_msa_ilvl_h
+#define __msa_ilvl_w __builtin_msa_ilvl_w
+#define __msa_ilvl_d __builtin_msa_ilvl_d
+#define __msa_ilvr_b __builtin_msa_ilvr_b
+#define __msa_ilvr_h __builtin_msa_ilvr_h
+#define __msa_ilvr_w __builtin_msa_ilvr_w
+#define __msa_ilvr_d __builtin_msa_ilvr_d
+#define __msa_ilvev_b __builtin_msa_ilvev_b
+#define __msa_ilvev_h __builtin_msa_ilvev_h
+#define __msa_ilvev_w __builtin_msa_ilvev_w
+#define __msa_ilvev_d __builtin_msa_ilvev_d
+#define __msa_ilvod_b __builtin_msa_ilvod_b
+#define __msa_ilvod_h __builtin_msa_ilvod_h
+#define __msa_ilvod_w __builtin_msa_ilvod_w
+#define __msa_ilvod_d __builtin_msa_ilvod_d
+#define __msa_vshf_b __builtin_msa_vshf_b
+#define __msa_vshf_h __builtin_msa_vshf_h
+#define __msa_vshf_w __builtin_msa_vshf_w
+#define __msa_vshf_d __builtin_msa_vshf_d
+#define __msa_and_v __builtin_msa_and_v
+#define __msa_andi_b __builtin_msa_andi_b
+#define __msa_or_v __builtin_msa_or_v
+#define __msa_ori_b __builtin_msa_ori_b
+#define __msa_nor_v __builtin_msa_nor_v
+#define __msa_nori_b __builtin_msa_nori_b
+#define __msa_xor_v __builtin_msa_xor_v
+#define __msa_xori_b __builtin_msa_xori_b
+#define __msa_bmnz_v __builtin_msa_bmnz_v
+#define __msa_bmnzi_b __builtin_msa_bmnzi_b
+#define __msa_bmz_v __builtin_msa_bmz_v
+#define __msa_bmzi_b __builtin_msa_bmzi_b
+#define __msa_bsel_v __builtin_msa_bsel_v
+#define __msa_bseli_b __builtin_msa_bseli_b
+#define __msa_shf_b __builtin_msa_shf_b
+#define __msa_shf_h __builtin_msa_shf_h
+#define __msa_shf_w __builtin_msa_shf_w
+#define __msa_test_bnz_v __builtin_msa_bnz_v
+#define __msa_test_bz_v __builtin_msa_bz_v
+#define __msa_fill_b __builtin_msa_fill_b
+#define __msa_fill_h __builtin_msa_fill_h
+#define __msa_fill_w __builtin_msa_fill_w
+#define __msa_fill_d __builtin_msa_fill_d
+#define __msa_pcnt_b __builtin_msa_pcnt_b
+#define __msa_pcnt_h __builtin_msa_pcnt_h
+#define __msa_pcnt_w __builtin_msa_pcnt_w
+#define __msa_pcnt_d __builtin_msa_pcnt_d
+#define __msa_nloc_b __builtin_msa_nloc_b
+#define __msa_nloc_h __builtin_msa_nloc_h
+#define __msa_nloc_w __builtin_msa_nloc_w
+#define __msa_nloc_d __builtin_msa_nloc_d
+#define __msa_nlzc_b __builtin_msa_nlzc_b
+#define __msa_nlzc_h __builtin_msa_nlzc_h
+#define __msa_nlzc_w __builtin_msa_nlzc_w
+#define __msa_nlzc_d __builtin_msa_nlzc_d
+#define __msa_copy_s_b __builtin_msa_copy_s_b
+#define __msa_copy_s_h __builtin_msa_copy_s_h
+#define __msa_copy_s_w __builtin_msa_copy_s_w
+#define __msa_copy_s_d __builtin_msa_copy_s_d
+#define __msa_copy_u_b __builtin_msa_copy_u_b
+#define __msa_copy_u_h __builtin_msa_copy_u_h
+#define __msa_copy_u_w __builtin_msa_copy_u_w
+#define __msa_copy_u_d __builtin_msa_copy_u_d
+#define __msa_insert_b __builtin_msa_insert_b
+#define __msa_insert_h __builtin_msa_insert_h
+#define __msa_insert_w __builtin_msa_insert_w
+#define __msa_insert_d __builtin_msa_insert_d
+#define __msa_insve_b __builtin_msa_insve_b
+#define __msa_insve_h __builtin_msa_insve_h
+#define __msa_insve_w __builtin_msa_insve_w
+#define __msa_insve_d __builtin_msa_insve_d
+#define __msa_test_bnz_b __builtin_msa_bnz_b
+#define __msa_test_bnz_h __builtin_msa_bnz_h
+#define __msa_test_bnz_w __builtin_msa_bnz_w
+#define __msa_test_bnz_d __builtin_msa_bnz_d
+#define __msa_test_bz_b __builtin_msa_bz_b
+#define __msa_test_bz_h __builtin_msa_bz_h
+#define __msa_test_bz_w __builtin_msa_bz_w
+#define __msa_test_bz_d __builtin_msa_bz_d
+#define __msa_ldi_b __builtin_msa_ldi_b
+#define __msa_ldi_h __builtin_msa_ldi_h
+#define __msa_ldi_w __builtin_msa_ldi_w
+#define __msa_ldi_d __builtin_msa_ldi_d
+#define __msa_fcaf_w __builtin_msa_fcaf_w
+#define __msa_fcaf_d __builtin_msa_fcaf_d
+#define __msa_fcor_w __builtin_msa_fcor_w
+#define __msa_fcor_d __builtin_msa_fcor_d
+#define __msa_fcun_w __builtin_msa_fcun_w
+#define __msa_fcun_d __builtin_msa_fcun_d
+#define __msa_fcune_w __builtin_msa_fcune_w
+#define __msa_fcune_d __builtin_msa_fcune_d
+#define __msa_fcueq_w __builtin_msa_fcueq_w
+#define __msa_fcueq_d __builtin_msa_fcueq_d
+#define __msa_fceq_w __builtin_msa_fceq_w
+#define __msa_fceq_d __builtin_msa_fceq_d
+#define __msa_fcne_w __builtin_msa_fcne_w
+#define __msa_fcne_d __builtin_msa_fcne_d
+#define __msa_fclt_w __builtin_msa_fclt_w
+#define __msa_fclt_d __builtin_msa_fclt_d
+#define __msa_fcult_w __builtin_msa_fcult_w
+#define __msa_fcult_d __builtin_msa_fcult_d
+#define __msa_fcle_w __builtin_msa_fcle_w
+#define __msa_fcle_d __builtin_msa_fcle_d
+#define __msa_fcule_w __builtin_msa_fcule_w
+#define __msa_fcule_d __builtin_msa_fcule_d
+#define __msa_fsaf_w __builtin_msa_fsaf_w
+#define __msa_fsaf_d __builtin_msa_fsaf_d
+#define __msa_fsor_w __builtin_msa_fsor_w
+#define __msa_fsor_d __builtin_msa_fsor_d
+#define __msa_fsun_w __builtin_msa_fsun_w
+#define __msa_fsun_d __builtin_msa_fsun_d
+#define __msa_fsune_w __builtin_msa_fsune_w
+#define __msa_fsune_d __builtin_msa_fsune_d
+#define __msa_fsueq_w __builtin_msa_fsueq_w
+#define __msa_fsueq_d __builtin_msa_fsueq_d
+#define __msa_fseq_w __builtin_msa_fseq_w
+#define __msa_fseq_d __builtin_msa_fseq_d
+#define __msa_fsne_w __builtin_msa_fsne_w
+#define __msa_fsne_d __builtin_msa_fsne_d
+#define __msa_fslt_w __builtin_msa_fslt_w
+#define __msa_fslt_d __builtin_msa_fslt_d
+#define __msa_fsult_w __builtin_msa_fsult_w
+#define __msa_fsult_d __builtin_msa_fsult_d
+#define __msa_fsle_w __builtin_msa_fsle_w
+#define __msa_fsle_d __builtin_msa_fsle_d
+#define __msa_fsule_w __builtin_msa_fsule_w
+#define __msa_fsule_d __builtin_msa_fsule_d
+#define __msa_fadd_w __builtin_msa_fadd_w
+#define __msa_fadd_d __builtin_msa_fadd_d
+#define __msa_fsub_w __builtin_msa_fsub_w
+#define __msa_fsub_d __builtin_msa_fsub_d
+#define __msa_fmul_w __builtin_msa_fmul_w
+#define __msa_fmul_d __builtin_msa_fmul_d
+#define __msa_fdiv_w __builtin_msa_fdiv_w
+#define __msa_fdiv_d __builtin_msa_fdiv_d
+#define __msa_fmadd_w __builtin_msa_fmadd_w
+#define __msa_fmadd_d __builtin_msa_fmadd_d
+#define __msa_fmsub_w __builtin_msa_fmsub_w
+#define __msa_fmsub_d __builtin_msa_fmsub_d
+#define __msa_fexp2_w __builtin_msa_fexp2_w
+#define __msa_fexp2_d __builtin_msa_fexp2_d
+#define __msa_fexdo_h __builtin_msa_fexdo_h
+#define __msa_fexdo_w __builtin_msa_fexdo_w
+#define __msa_ftq_h __builtin_msa_ftq_h
+#define __msa_ftq_w __builtin_msa_ftq_w
+#define __msa_fmin_w __builtin_msa_fmin_w
+#define __msa_fmin_d __builtin_msa_fmin_d
+#define __msa_fmin_a_w __builtin_msa_fmin_a_w
+#define __msa_fmin_a_d __builtin_msa_fmin_a_d
+#define __msa_fmax_w __builtin_msa_fmax_w
+#define __msa_fmax_d __builtin_msa_fmax_d
+#define __msa_fmax_a_w __builtin_msa_fmax_a_w
+#define __msa_fmax_a_d __builtin_msa_fmax_a_d
+#define __msa_mul_q_h __builtin_msa_mul_q_h
+#define __msa_mul_q_w __builtin_msa_mul_q_w
+#define __msa_mulr_q_h __builtin_msa_mulr_q_h
+#define __msa_mulr_q_w __builtin_msa_mulr_q_w
+#define __msa_madd_q_h __builtin_msa_madd_q_h
+#define __msa_madd_q_w __builtin_msa_madd_q_w
+#define __msa_maddr_q_h __builtin_msa_maddr_q_h
+#define __msa_maddr_q_w __builtin_msa_maddr_q_w
+#define __msa_msub_q_h __builtin_msa_msub_q_h
+#define __msa_msub_q_w __builtin_msa_msub_q_w
+#define __msa_msubr_q_h __builtin_msa_msubr_q_h
+#define __msa_msubr_q_w __builtin_msa_msubr_q_w
+#define __msa_fclass_w __builtin_msa_fclass_w
+#define __msa_fclass_d __builtin_msa_fclass_d
+#define __msa_fsqrt_w __builtin_msa_fsqrt_w
+#define __msa_fsqrt_d __builtin_msa_fsqrt_d
+#define __msa_frcp_w __builtin_msa_frcp_w
+#define __msa_frcp_d __builtin_msa_frcp_d
+#define __msa_frint_w __builtin_msa_frint_w
+#define __msa_frint_d __builtin_msa_frint_d
+#define __msa_frsqrt_w __builtin_msa_frsqrt_w
+#define __msa_frsqrt_d __builtin_msa_frsqrt_d
+#define __msa_flog2_w __builtin_msa_flog2_w
+#define __msa_flog2_d __builtin_msa_flog2_d
+#define __msa_fexupl_w __builtin_msa_fexupl_w
+#define __msa_fexupl_d __builtin_msa_fexupl_d
+#define __msa_fexupr_w __builtin_msa_fexupr_w
+#define __msa_fexupr_d __builtin_msa_fexupr_d
+#define __msa_ffql_w __builtin_msa_ffql_w
+#define __msa_ffql_d __builtin_msa_ffql_d
+#define __msa_ffqr_w __builtin_msa_ffqr_w
+#define __msa_ffqr_d __builtin_msa_ffqr_d
+#define __msa_ftint_s_w __builtin_msa_ftint_s_w
+#define __msa_ftint_s_d __builtin_msa_ftint_s_d
+#define __msa_ftint_u_w __builtin_msa_ftint_u_w
+#define __msa_ftint_u_d __builtin_msa_ftint_u_d
+#define __msa_ftrunc_s_w __builtin_msa_ftrunc_s_w
+#define __msa_ftrunc_s_d __builtin_msa_ftrunc_s_d
+#define __msa_ftrunc_u_w __builtin_msa_ftrunc_u_w
+#define __msa_ftrunc_u_d __builtin_msa_ftrunc_u_d
+#define __msa_ffint_s_w __builtin_msa_ffint_s_w
+#define __msa_ffint_s_d __builtin_msa_ffint_s_d
+#define __msa_ffint_u_w __builtin_msa_ffint_u_w
+#define __msa_ffint_u_d __builtin_msa_ffint_u_d
+#define __msa_cfcmsa __builtin_msa_cfcmsa
+#define __msa_move_v __builtin_msa_move_v
+#endif /* defined(__mips_msa) */
+#endif /* _MSA_H */
diff --git a/gcc/config/mips/mti-elf.h b/gcc/config/mips/mti-elf.h
index e804f6ab645..c4ae24bac36 100644
--- a/gcc/config/mips/mti-elf.h
+++ b/gcc/config/mips/mti-elf.h
@@ -39,8 +39,8 @@ along with GCC; see the file COPYING3. If not see
\
/* If no FP ABI option is specified, infer one from the \
ABI/ISA level. */ \
- "%{!msoft-float: %{!msingle-float: %{!mfp*: %{mabi=32: %{" \
- MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}", \
+ "%{!msoft-float: %{!msingle-float: %{!mfp*: %{!mmsa: %{mabi=32: %{" \
+ MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}}", \
\
/* Make sure that an endian option is always present. This makes \
things like LINK_SPEC easier to write. */ \
diff --git a/gcc/config/mips/mti-linux.h b/gcc/config/mips/mti-linux.h
index d84ad1842b2..76b0f34059c 100644
--- a/gcc/config/mips/mti-linux.h
+++ b/gcc/config/mips/mti-linux.h
@@ -61,9 +61,9 @@ along with GCC; see the file COPYING3. If not see
"%{!mabi=*: %{" MIPS_32BIT_OPTION_SPEC ": -mabi=32;: -mabi=n32}}", \
\
/* If no FP ABI option is specified, infer one from the \
- ABI/ISA level. */ \
- "%{!msoft-float: %{!msingle-float: %{!mfp*: %{mabi=32: %{" \
- MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}", \
+ ABI/ISA level unless there is a conflicting option. */ \
+ "%{!msoft-float: %{!msingle-float: %{!mfp*: %{!mmsa: %{mabi=32: %{" \
+ MIPS_FPXX_OPTION_SPEC ": -mfpxx}}}}}}", \
\
/* Base SPECs. */ \
BASE_DRIVER_SELF_SPECS \
diff --git a/gcc/config/mips/p5600.md b/gcc/config/mips/p5600.md
index 35e8749e8da..694a745a926 100644
--- a/gcc/config/mips/p5600.md
+++ b/gcc/config/mips/p5600.md
@@ -31,10 +31,15 @@
(define_cpu_unit "p5600_fpu_short, p5600_fpu_long" "p5600_fpu_pipe")
;; Short FPU pipeline
-(define_cpu_unit "p5600_fpu_store" "p5600_fpu_pipe")
+(define_cpu_unit "p5600_fpu_intadd, p5600_fpu_cmp, p5600_fpu_float,
+ p5600_fpu_logic_a, p5600_fpu_logic_b, p5600_fpu_div,
+ p5600_fpu_store" "p5600_fpu_pipe")
;; Long FPU pipeline
-(define_cpu_unit "p5600_fpu_apu" "p5600_fpu_pipe")
+(define_cpu_unit "p5600_fpu_logic, p5600_fpu_float_a, p5600_fpu_float_b,
+ p5600_fpu_float_c, p5600_fpu_float_d" "p5600_fpu_pipe")
+(define_cpu_unit "p5600_fpu_mult, p5600_fpu_fdiv, p5600_fpu_load,
+ p5600_fpu_apu" "p5600_fpu_pipe")
(define_reservation "p5600_agq_al2" "p5600_agq, p5600_al2")
(define_reservation "p5600_agq_ctistd" "p5600_agq, p5600_ctistd")
@@ -42,6 +47,116 @@
(define_reservation "p5600_alq_alu" "p5600_alq, p5600_alu")
;;
+;; FPU-MSA pipe
+;;
+
+;; Arithmetic
+;; add, hadd, sub, hsub, average, min, max, compare
+(define_insn_reservation "msa_short_int_add" 2
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_int_arith"))
+ "p5600_fpu_short, p5600_fpu_intadd")
+
+;; Bitwise Instructions
+;; and, or, xor, bit-clear, leading-bits-count, shift, shuffle
+(define_insn_reservation "msa_short_logic" 2
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_shift,simd_bit,simd_splat,simd_fill,simd_shf,
+ simd_permute,simd_logic"))
+ "p5600_fpu_short, p5600_fpu_logic_a")
+
+;; move.v
+(define_insn_reservation "msa_short_logic_move_v" 2
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_move"))
+ "p5600_fpu_short, p5600_fpu_logic_a")
+
+;; Float compare
+(define_insn_reservation "msa_short_cmp" 2
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_fcmp"))
+ "p5600_fpu_short, p5600_fpu_cmp")
+
+;; Float exp2, min, max
+(define_insn_reservation "msa_short_float2" 2
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_fexp2,simd_fminmax"))
+ "p5600_fpu_short, p5600_fpu_float")
+
+;; Vector sat
+(define_insn_reservation "msa_short_logic3" 3
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_sat,simd_pcnt"))
+ "p5600_fpu_short, p5600_fpu_logic_a, p5600_fpu_logic_b")
+
+;; Vector copy, bz, bnz
+(define_insn_reservation "msa_short_store4" 4
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_copy,simd_branch,simd_cmsa"))
+ "p5600_fpu_short, p5600_fpu_store")
+
+;; Vector load
+(define_insn_reservation "msa_long_load" 10
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_load"))
+ "p5600_fpu_long, p5600_fpu_load")
+
+;; Vector store
+(define_insn_reservation "msa_short_store" 2
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_store"))
+ "p5600_fpu_short, p5600_fpu_store")
+
+;; binsl, binsr, insert, vshf, sld
+(define_insn_reservation "msa_long_logic" 2
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_bitins,simd_bitmov,simd_insert,simd_sld"))
+ "p5600_fpu_long, p5600_fpu_logic")
+
+;; Float fclass, flog2
+(define_insn_reservation "msa_long_float2" 2
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_fclass,simd_flog2"))
+ "p5600_fpu_long, p5600_fpu_float_a")
+
+;; fadd, fsub
+(define_insn_reservation "msa_long_float4" 4
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_fadd,simd_fcvt"))
+ "p5600_fpu_long, p5600_fpu_float_a, p5600_fpu_float_b")
+
+;; fmul
+(define_insn_reservation "msa_long_float5" 5
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_fmul"))
+ "p5600_fpu_long, p5600_fpu_float_a, p5600_fpu_float_b, p5600_fpu_float_c")
+
+;; fmadd, fmsub
+(define_insn_reservation "msa_long_float8" 8
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_fmadd"))
+ "p5600_fpu_long, p5600_fpu_float_a,
+ p5600_fpu_float_b, p5600_fpu_float_c, p5600_fpu_float_d")
+
+;; Vector mul, dotp, madd, msub
+(define_insn_reservation "msa_long_mult" 5
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_mul"))
+ "p5600_fpu_long, p5600_fpu_mult")
+
+;; fdiv, fmod (semi-pipelined)
+(define_insn_reservation "msa_long_fdiv" 10
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_fdiv"))
+ "p5600_fpu_long, nothing, nothing, p5600_fpu_fdiv*8")
+
+;; div, mod (non-pipelined)
+(define_insn_reservation "msa_long_div" 10
+ (and (eq_attr "cpu" "p5600")
+ (eq_attr "type" "simd_div"))
+ "p5600_fpu_long, p5600_fpu_div*9, p5600_fpu_div + p5600_fpu_logic_a")
+
+;;
;; FPU pipe
;;
diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md
index cbeace9d640..e6b6d2f60da 100644
--- a/gcc/config/mips/predicates.md
+++ b/gcc/config/mips/predicates.md
@@ -35,12 +35,36 @@
(define_predicate "const_immlsa_operand"
(and (match_code "const_int")
- (match_test "IN_RANGE (INTVAL (op), 1, 4)")))
+ (match_test "IN_RANGE (INTVAL (op), 1, 4)")))
+
+(define_predicate "const_msa_branch_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), -1024, 1023)")))
+
+(define_predicate "const_uimm3_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 7)")))
+
+(define_predicate "const_uimm4_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 15)")))
+
+(define_predicate "const_uimm5_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 31)")))
(define_predicate "const_uimm6_operand"
(and (match_code "const_int")
(match_test "UIMM6_OPERAND (INTVAL (op))")))
+(define_predicate "const_uimm8_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 255)")))
+
+(define_predicate "const_imm5_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), -16, 15)")))
+
(define_predicate "const_imm10_operand"
(and (match_code "const_int")
(match_test "IMM10_OPERAND (INTVAL (op))")))
@@ -49,6 +73,22 @@
(ior (match_operand 0 "const_imm10_operand")
(match_operand 0 "register_operand")))
+(define_predicate "aq10b_operand"
+ (and (match_code "const_int")
+ (match_test "mips_signed_immediate_p (INTVAL (op), 10, 0)")))
+
+(define_predicate "aq10h_operand"
+ (and (match_code "const_int")
+ (match_test "mips_signed_immediate_p (INTVAL (op), 10, 1)")))
+
+(define_predicate "aq10w_operand"
+ (and (match_code "const_int")
+ (match_test "mips_signed_immediate_p (INTVAL (op), 10, 2)")))
+
+(define_predicate "aq10d_operand"
+ (and (match_code "const_int")
+ (match_test "mips_signed_immediate_p (INTVAL (op), 10, 3)")))
+
(define_predicate "sle_operand"
(and (match_code "const_int")
(match_test "SMALL_OPERAND (INTVAL (op) + 1)")))
@@ -61,6 +101,14 @@
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (GET_MODE (op))")))
+(define_predicate "const_m1_operand"
+ (and (match_code "const_int,const_double,const_vector")
+ (match_test "op == CONSTM1_RTX (GET_MODE (op))")))
+
+(define_predicate "reg_or_m1_operand"
+ (ior (match_operand 0 "const_m1_operand")
+ (match_operand 0 "register_operand")))
+
(define_predicate "reg_or_0_operand"
(ior (and (match_operand 0 "const_0_operand")
(not (match_test "TARGET_MIPS16")))
@@ -74,6 +122,23 @@
(ior (match_operand 0 "const_1_operand")
(match_operand 0 "register_operand")))
+;; These are used in vec_merge, hence accept bitmask as const_int.
+(define_predicate "const_exp_2_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 1)")))
+
+(define_predicate "const_exp_4_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 3)")))
+
+(define_predicate "const_exp_8_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 7)")))
+
+(define_predicate "const_exp_16_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (exact_log2 (INTVAL (op)), 0, 15)")))
+
;; This is used for indexing into vectors, and hence only accepts const_int.
(define_predicate "const_0_or_1_operand"
(and (match_code "const_int")
@@ -507,3 +572,65 @@
(define_predicate "non_volatile_mem_operand"
(and (match_operand 0 "memory_operand")
(not (match_test "MEM_VOLATILE_P (op)"))))
+
+(define_predicate "const_vector_same_val_operand"
+ (match_code "const_vector")
+{
+ return mips_const_vector_same_val_p (op, mode);
+})
+
+(define_predicate "const_vector_same_simm5_operand"
+ (match_code "const_vector")
+{
+ return mips_const_vector_same_int_p (op, mode, -16, 15);
+})
+
+(define_predicate "const_vector_same_uimm5_operand"
+ (match_code "const_vector")
+{
+ return mips_const_vector_same_int_p (op, mode, 0, 31);
+})
+
+(define_predicate "const_vector_same_ximm5_operand"
+ (match_code "const_vector")
+{
+ return mips_const_vector_same_int_p (op, mode, -31, 31);
+})
+
+(define_predicate "const_vector_same_uimm6_operand"
+ (match_code "const_vector")
+{
+ return mips_const_vector_same_int_p (op, mode, 0, 63);
+})
+
+(define_predicate "const_vector_same_uimm8_operand"
+ (match_code "const_vector")
+{
+ return mips_const_vector_same_int_p (op, mode, 0, 255);
+})
+
+(define_predicate "par_const_vector_shf_set_operand"
+ (match_code "parallel")
+{
+ return mips_const_vector_shuffle_set_p (op, mode);
+})
+
+(define_predicate "reg_or_vector_same_val_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "const_vector_same_val_operand")))
+
+(define_predicate "reg_or_vector_same_simm5_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "const_vector_same_simm5_operand")))
+
+(define_predicate "reg_or_vector_same_uimm5_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "const_vector_same_uimm5_operand")))
+
+(define_predicate "reg_or_vector_same_ximm5_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "const_vector_same_ximm5_operand")))
+
+(define_predicate "reg_or_vector_same_uimm6_operand"
+ (ior (match_operand 0 "register_operand")
+ (match_operand 0 "const_vector_same_uimm6_operand")))
diff --git a/gcc/config/nvptx/nvptx.c b/gcc/config/nvptx/nvptx.c
index a6c90b633f9..1bd18710245 100644
--- a/gcc/config/nvptx/nvptx.c
+++ b/gcc/config/nvptx/nvptx.c
@@ -155,8 +155,19 @@ static void
nvptx_option_override (void)
{
init_machine_status = nvptx_init_machine_status;
- /* Gives us a predictable order, which we need especially for variables. */
- flag_toplevel_reorder = 1;
+
+ /* Set toplevel_reorder, unless explicitly disabled. We need
+ reordering so that we emit necessary assembler decls of
+ undeclared variables. */
+ if (!global_options_set.x_flag_toplevel_reorder)
+ flag_toplevel_reorder = 1;
+
+ /* Set flag_no_common, unless explicitly disabled. We fake common
+ using .weak, and that's not entirely accurate, so avoid it
+ unless forced. */
+ if (!global_options_set.x_flag_no_common)
+ flag_no_common = 1;
+
/* Assumes that it will see only hard registers. */
flag_var_tracking = 0;
@@ -258,7 +269,10 @@ section_for_decl (const_tree decl)
/* Check NAME for special function names and redirect them by returning a
replacement. This applies to malloc, free and realloc, for which we
- want to use libgcc wrappers, and call, which triggers a bug in ptxas. */
+ want to use libgcc wrappers, and call, which triggers a bug in
+ ptxas. We can't use TARGET_MANGLE_DECL_ASSEMBLER_NAME, as that's
+ not active in an offload compiler -- the names are all set by the
+ host-side compiler. */
static const char *
nvptx_name_replacement (const char *name)
@@ -461,6 +475,17 @@ nvptx_function_arg_advance (cumulative_args_t cum_v,
cum->count++;
}
+/* Implement TARGET_FUNCTION_ARG_BOUNDARY.
+
+ For nvptx This is only used for varadic args. The type has already
+ been promoted and/or converted to invisible reference. */
+
+static unsigned
+nvptx_function_arg_boundary (machine_mode mode, const_tree ARG_UNUSED (type))
+{
+ return GET_MODE_ALIGNMENT (mode);
+}
+
/* Handle the TARGET_STRICT_ARGUMENT_NAMING target hook.
For nvptx, we know how to handle functions declared as stdarg: by
@@ -751,6 +776,26 @@ write_fn_proto (std::stringstream &s, bool is_defn,
tree fntype = TREE_TYPE (decl);
tree result_type = TREE_TYPE (fntype);
+ /* atomic_compare_exchange_$n builtins have an exceptional calling
+ convention. */
+ int not_atomic_weak_arg = -1;
+ if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (decl))
+ {
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_1:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_2:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_4:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_8:
+ case BUILT_IN_ATOMIC_COMPARE_EXCHANGE_16:
+ /* These atomics skip the 'weak' parm in an actual library
+ call. We must skip it in the prototype too. */
+ not_atomic_weak_arg = 3;
+ break;
+
+ default:
+ break;
+ }
+
/* Declare the result. */
bool return_in_mem = write_return_type (s, true, result_type);
@@ -775,11 +820,14 @@ write_fn_proto (std::stringstream &s, bool is_defn,
prototyped = false;
}
- for (; args; args = TREE_CHAIN (args))
+ for (; args; args = TREE_CHAIN (args), not_atomic_weak_arg--)
{
tree type = prototyped ? TREE_VALUE (args) : TREE_TYPE (args);
-
- argno = write_arg_type (s, -1, argno, type, prototyped);
+
+ if (not_atomic_weak_arg)
+ argno = write_arg_type (s, -1, argno, type, prototyped);
+ else
+ gcc_assert (type == boolean_type_node);
}
if (stdarg_p (fntype))
@@ -4809,6 +4857,8 @@ nvptx_goacc_reduction (gcall *call)
#define TARGET_FUNCTION_INCOMING_ARG nvptx_function_incoming_arg
#undef TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE nvptx_function_arg_advance
+#undef TARGET_FUNCTION_ARG_BOUNDARY
+#define TARGET_FUNCTION_ARG_BOUNDARY nvptx_function_arg_boundary
#undef TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE nvptx_pass_by_reference
#undef TARGET_FUNCTION_VALUE_REGNO_P
diff --git a/gcc/config/nvptx/nvptx.md b/gcc/config/nvptx/nvptx.md
index 33a4862b98e..e48412de6a6 100644
--- a/gcc/config/nvptx/nvptx.md
+++ b/gcc/config/nvptx/nvptx.md
@@ -794,6 +794,17 @@
""
"%.\\tsqrt%#%t0\\t%0, %1;")
+(define_expand "sincossf3"
+ [(set (match_operand:SF 0 "nvptx_register_operand" "=R")
+ (unspec:SF [(match_operand:SF 2 "nvptx_register_operand" "R")]
+ UNSPEC_COS))
+ (set (match_operand:SF 1 "nvptx_register_operand" "=R")
+ (unspec:SF [(match_dup 2)] UNSPEC_SIN))]
+ "flag_unsafe_math_optimizations"
+{
+ operands[2] = make_safe_from (operands[2], operands[0]);
+})
+
(define_insn "sinsf2"
[(set (match_operand:SF 0 "nvptx_register_operand" "=R")
(unspec:SF [(match_operand:SF 1 "nvptx_register_operand" "R")]
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index 13c22539268..2d850610ea6 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -76,6 +76,23 @@ static const char * const word_regnames[] =
"sp", "ap", "psw", "es", "cs"
};
+/* Structure for G13 MDUC registers. */
+struct mduc_reg_type
+{
+ unsigned int address;
+ enum machine_mode mode;
+};
+
+struct mduc_reg_type mduc_regs[] =
+{
+ {0xf00e8, QImode},
+ {0xffff0, HImode},
+ {0xffff2, HImode},
+ {0xf2224, HImode},
+ {0xf00e0, HImode},
+ {0xf00e2, HImode}
+};
+
struct GTY(()) machine_function
{
/* If set, the rest of the fields have been computed. */
@@ -317,6 +334,10 @@ rl78_output_symbol_ref (FILE * file, rtx sym)
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE rl78_option_override
+#define MUST_SAVE_MDUC_REGISTERS \
+ (TARGET_SAVE_MDUC_REGISTERS \
+ && (is_interrupt_func (NULL_TREE)) && RL78_MUL_G13)
+
static void
rl78_option_override (void)
{
@@ -344,6 +365,9 @@ rl78_option_override (void)
/* Address spaces are currently only supported by C. */
error ("-mes0 can only be used with C");
+ if (TARGET_SAVE_MDUC_REGISTERS && !(TARGET_G13 || RL78_MUL_G13))
+ warning (0, "mduc registers only saved for G13 target");
+
switch (rl78_cpu_type)
{
case CPU_UNINIT:
@@ -1257,13 +1281,34 @@ rl78_initial_elimination_offset (int from, int to)
return rv;
}
-static int
+static bool
rl78_is_naked_func (void)
{
return (lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)) != NULL_TREE);
}
+/* Check if the block uses mul/div insns for G13 target. */
+
+static bool
+check_mduc_usage (void)
+{
+ rtx_insn * insn;
+ basic_block bb;
+
+ FOR_EACH_BB_FN (bb, cfun)
+ {
+ FOR_BB_INSNS (bb, insn)
+ {
+ if (INSN_P (insn)
+ && (get_attr_is_g13_muldiv_insn (insn) == IS_G13_MULDIV_INSN_YES))
+ return true;
+ }
+ }
+ return false;
+}
+
/* Expand the function prologue (from the prologue pattern). */
+
void
rl78_expand_prologue (void)
{
@@ -1278,6 +1323,9 @@ rl78_expand_prologue (void)
/* Always re-compute the frame info - the register usage may have changed. */
rl78_compute_frame_info ();
+ if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+ cfun->machine->framesize += ARRAY_SIZE (mduc_regs) * 2;
+
if (flag_stack_usage_info)
current_function_static_stack_size = cfun->machine->framesize;
@@ -1327,6 +1375,24 @@ rl78_expand_prologue (void)
F (emit_insn (gen_push (ax)));
}
+ /* Save MDUC registers inside interrupt routine. */
+ if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+ {
+ for (int i = 0; i < ARRAY_SIZE (mduc_regs); i++)
+ {
+ mduc_reg_type *reg = mduc_regs + i;
+ rtx mem_mduc = gen_rtx_MEM (reg->mode, GEN_INT (reg->address));
+
+ MEM_VOLATILE_P (mem_mduc) = 1;
+ if (reg->mode == QImode)
+ emit_insn (gen_movqi (gen_rtx_REG (QImode, A_REG), mem_mduc));
+ else
+ emit_insn (gen_movhi (gen_rtx_REG (HImode, AX_REG), mem_mduc));
+
+ emit_insn (gen_push (gen_rtx_REG (HImode, AX_REG)));
+ }
+ }
+
if (frame_pointer_needed)
{
F (emit_move_insn (ax, sp));
@@ -1400,6 +1466,23 @@ rl78_expand_epilogue (void)
}
}
+ /* Restore MDUC registers from interrupt routine. */
+ if (MUST_SAVE_MDUC_REGISTERS && (!crtl->is_leaf || check_mduc_usage ()))
+ {
+ for (int i = ARRAY_SIZE (mduc_regs) - 1; i >= 0; i--)
+ {
+ mduc_reg_type *reg = mduc_regs + i;
+ rtx mem_mduc = gen_rtx_MEM (reg->mode, GEN_INT (reg->address));
+
+ emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
+ MEM_VOLATILE_P (mem_mduc) = 1;
+ if (reg->mode == QImode)
+ emit_insn (gen_movqi (mem_mduc, gen_rtx_REG (QImode, A_REG)));
+ else
+ emit_insn (gen_movhi (mem_mduc, gen_rtx_REG (HImode, AX_REG)));
+ }
+ }
+
if (is_interrupt_func (cfun->decl) && cfun->machine->uses_es)
{
emit_insn (gen_pop (gen_rtx_REG (HImode, AX_REG)));
@@ -1495,6 +1578,9 @@ rl78_start_function (FILE *file, HOST_WIDE_INT hwi_local ATTRIBUTE_UNUSED)
if (cfun->machine->uses_es)
fprintf (file, "\t; uses ES register\n");
+
+ if (MUST_SAVE_MDUC_REGISTERS)
+ fprintf (file, "\t; preserves MDUC registers\n");
}
/* Return an RTL describing where a function return value of type RET_TYPE
diff --git a/gcc/config/rl78/rl78.md b/gcc/config/rl78/rl78.md
index 739f6057b92..33bd1988537 100644
--- a/gcc/config/rl78/rl78.md
+++ b/gcc/config/rl78/rl78.md
@@ -67,6 +67,7 @@
(include "rl78-virt.md")
(include "rl78-real.md")
+(define_attr "is_g13_muldiv_insn" "yes,no" (const_string "no"))
;; Function Prologue/Epilogue Instructions
@@ -379,7 +380,8 @@
movw ax, 0xffff6 ; MDBL
movw %h0, ax
; end of mulhi macro"
- [(set_attr "valloc" "macax")]
+ [(set_attr "valloc" "macax")
+ (set_attr "is_g13_muldiv_insn" "yes")]
)
;; 0xFFFF0 is MACR(L). 0xFFFF2 is MACR(H) but we don't care about it
@@ -459,7 +461,8 @@
movw ax, !0xf00e0 ; MDCL
movw %H0, ax
; end of mulsi macro"
- [(set_attr "valloc" "macax")]
+ [(set_attr "valloc" "macax")
+ (set_attr "is_g13_muldiv_insn" "yes")]
)
(define_expand "udivmodhi4"
@@ -692,5 +695,6 @@
movw %H3, ax \n\
; end of udivmodsi macro";
}
- [(set_attr "valloc" "macax")]
+ [(set_attr "valloc" "macax")
+ (set_attr "is_g13_muldiv_insn" "yes")]
)
diff --git a/gcc/config/rl78/rl78.opt b/gcc/config/rl78/rl78.opt
index a8e53ee0735..26db67cb658 100644
--- a/gcc/config/rl78/rl78.opt
+++ b/gcc/config/rl78/rl78.opt
@@ -91,3 +91,7 @@ Alias for -mcpu=g14.
mes0
Target Mask(ES0)
Assume ES is zero throughout program execution, use ES: for read-only data.
+
+msave-mduc-in-interrupts
+Target Mask(SAVE_MDUC_REGISTERS)
+Stores the MDUC registers in interrupt handlers for G13 target.
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 7a8c8ebf3f3..e94aec39d73 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -73,6 +73,9 @@
UNSPEC_VUNPACK_LO_SIGN_DIRECT
UNSPEC_VUPKHPX
UNSPEC_VUPKLPX
+ UNSPEC_DARN
+ UNSPEC_DARN_32
+ UNSPEC_DARN_RAW
UNSPEC_DST
UNSPEC_DSTT
UNSPEC_DSTST
@@ -3590,6 +3593,27 @@
[(set_attr "length" "4")
(set_attr "type" "vecsimple")])
+(define_insn "darn_32"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(const_int 0)] UNSPEC_DARN_32))]
+ "TARGET_MODULO"
+ "darn %0,0"
+ [(set_attr "type" "integer")])
+
+(define_insn "darn_raw"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(const_int 0)] UNSPEC_DARN_RAW))]
+ "TARGET_MODULO && TARGET_64BIT"
+ "darn %0,2"
+ [(set_attr "type" "integer")])
+
+(define_insn "darn"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (unspec:DI [(const_int 0)] UNSPEC_DARN))]
+ "TARGET_MODULO && TARGET_64BIT"
+ "darn %0,1"
+ [(set_attr "type" "integer")])
+
(define_expand "bcd<bcd_add_sub>_<code>"
[(parallel [(set (reg:CCFP 74)
(compare:CCFP
diff --git a/gcc/config/rs6000/constraints.md b/gcc/config/rs6000/constraints.md
index ea15764e513..ef8f617d9a8 100644
--- a/gcc/config/rs6000/constraints.md
+++ b/gcc/config/rs6000/constraints.md
@@ -140,6 +140,10 @@
(and (match_code "const_int")
(match_test "TARGET_VSX && (ival == VECTOR_ELEMENT_SCALAR_64BIT)")))
+(define_constraint "wE"
+ "Vector constant that can be loaded with the XXSPLTIB instruction."
+ (match_test "xxspltib_constant_nosplit (op, mode)"))
+
;; Extended fusion store
(define_memory_constraint "wF"
"Memory operand suitable for power9 fusion load/stores"
@@ -156,11 +160,26 @@
(and (match_test "TARGET_DIRECT_MOVE_128")
(match_test "(ival == VECTOR_ELEMENT_MFVSRLD_64BIT)"))))
+;; Generate the XXORC instruction to set a register to all 1's
+(define_constraint "wM"
+ "Match vector constant with all 1's if the XXLORC instruction is available"
+ (and (match_test "TARGET_P8_VECTOR")
+ (match_operand 0 "all_ones_constant")))
+
+;; ISA 3.0 vector d-form addresses
+(define_memory_constraint "wO"
+ "Memory operand suitable for the ISA 3.0 vector d-form instructions."
+ (match_operand 0 "vsx_quad_dform_memory_operand"))
+
;; Lq/stq validates the address for load/store quad
(define_memory_constraint "wQ"
"Memory operand suitable for the load/store quad instructions"
(match_operand 0 "quad_memory_operand"))
+(define_constraint "wS"
+ "Vector constant that can be loaded with XXSPLTIB & sign extension."
+ (match_test "xxspltib_constant_split (op, mode)"))
+
;; Altivec style load/store that ignores the bottom bits of the address
(define_memory_constraint "wZ"
"Indexed or indirect memory operand, ignoring the bottom 4 bits"
diff --git a/gcc/config/rs6000/freebsd64.h b/gcc/config/rs6000/freebsd64.h
index 899b858d821..3038c43b25f 100644
--- a/gcc/config/rs6000/freebsd64.h
+++ b/gcc/config/rs6000/freebsd64.h
@@ -349,7 +349,7 @@ extern int dot_symbols;
true if the symbol may be affected by dynamic relocations. */
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
- ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE) \
+ (TARGET_64BIT || flag_pic \
? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \
| (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \
: DW_EH_PE_absptr)
@@ -384,7 +384,7 @@ extern int dot_symbols;
#define MINIMAL_TOC_SECTION_ASM_OP \
(TARGET_64BIT \
? "\t.section\t\".toc1\",\"aw\"" \
- : ((TARGET_RELOCATABLE || flag_pic) \
+ : (flag_pic \
? "\t.section\t\".got2\",\"aw\"" \
: "\t.section\t\".got1\",\"aw\""))
@@ -422,7 +422,6 @@ extern int dot_symbols;
&& ! TARGET_NO_FP_IN_TOC))) \
|| (!TARGET_64BIT \
&& !TARGET_NO_FP_IN_TOC \
- && !TARGET_RELOCATABLE \
&& SCALAR_FLOAT_MODE_P (GET_MODE (X)) \
&& BITS_PER_WORD == HOST_BITS_PER_INT)))))
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index fefa0c4eef3..e86b5d52ad6 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -489,7 +489,7 @@ extern int dot_symbols;
#define MINIMAL_TOC_SECTION_ASM_OP \
(TARGET_64BIT \
? "\t.section\t\".toc1\",\"aw\"" \
- : ((TARGET_RELOCATABLE || flag_pic) \
+ : (flag_pic \
? "\t.section\t\".got2\",\"aw\"" \
: "\t.section\t\".got1\",\"aw\""))
@@ -585,7 +585,6 @@ extern int dot_symbols;
&& ! TARGET_NO_FP_IN_TOC))) \
|| (!TARGET_64BIT \
&& !TARGET_NO_FP_IN_TOC \
- && !TARGET_RELOCATABLE \
&& SCALAR_FLOAT_MODE_P (GET_MODE (X)) \
&& BITS_PER_WORD == HOST_BITS_PER_INT)))))
@@ -594,7 +593,7 @@ extern int dot_symbols;
true if the symbol may be affected by dynamic relocations. */
#undef ASM_PREFERRED_EH_DATA_FORMAT
#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
- ((TARGET_64BIT || flag_pic || TARGET_RELOCATABLE) \
+ (TARGET_64BIT || flag_pic \
? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \
| (TARGET_64BIT ? DW_EH_PE_udata8 : DW_EH_PE_sdata4)) \
: DW_EH_PE_absptr)
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 71fac765e24..5b852a12c21 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -539,13 +539,6 @@
if (flag_pic && DEFAULT_ABI == ABI_V4)
return 0;
-#ifdef TARGET_RELOCATABLE
- /* Similarly if we are using -mrelocatable, consider all constants
- to be hard. */
- if (TARGET_RELOCATABLE)
- return 0;
-#endif
-
/* If we have real FPRs, consider floating point constants hard (other than
0.0 under VSX), so that the constant gets pushed to memory during the
early RTL phases. This has the advantage that double precision constants
@@ -572,6 +565,38 @@
}
})
+;; Return 1 if the operand is a CONST_VECTOR or VEC_DUPLICATE of a constant
+;; that can loaded with a XXSPLTIB instruction and then a VUPKHSB, VECSB2W or
+;; VECSB2D instruction.
+
+(define_predicate "xxspltib_constant_split"
+ (match_code "const_vector,vec_duplicate,const_int")
+{
+ int value = 256;
+ int num_insns = -1;
+
+ if (!xxspltib_constant_p (op, mode, &num_insns, &value))
+ return false;
+
+ return num_insns > 1;
+})
+
+
+;; Return 1 if the operand is a CONST_VECTOR that can loaded directly with a
+;; XXSPLTIB instruction.
+
+(define_predicate "xxspltib_constant_nosplit"
+ (match_code "const_vector,vec_duplicate,const_int")
+{
+ int value = 256;
+ int num_insns = -1;
+
+ if (!xxspltib_constant_p (op, mode, &num_insns, &value))
+ return false;
+
+ return num_insns == 1;
+})
+
;; Return 1 if the operand is a CONST_VECTOR and can be loaded into a
;; vector register without using memory.
(define_predicate "easy_vector_constant"
@@ -590,7 +615,14 @@
if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
{
- if (zero_constant (op, mode))
+ int value = 256;
+ int num_insns = -1;
+
+ if (zero_constant (op, mode) || all_ones_constant (op, mode))
+ return true;
+
+ if (TARGET_P9_VECTOR
+ && xxspltib_constant_p (op, mode, &num_insns, &value))
return true;
return easy_altivec_constant (op, mode);
@@ -669,6 +701,11 @@
(and (match_code "const_int,const_double,const_wide_int,const_vector")
(match_test "op == CONST0_RTX (mode)")))
+;; Return 1 if operand is constant -1 (scalars and vectors).
+(define_predicate "all_ones_constant"
+ (and (match_code "const_int,const_double,const_wide_int,const_vector")
+ (match_test "op == CONSTM1_RTX (mode) && !FLOAT_MODE_P (mode)")))
+
;; Return 1 if operand is 0.0.
(define_predicate "zero_fp_constant"
(and (match_code "const_double")
@@ -698,48 +735,25 @@
(define_predicate "quad_memory_operand"
(match_code "mem")
{
- rtx addr, op0, op1;
- int ret;
-
if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI)
- ret = 0;
-
- else if (!memory_operand (op, mode))
- ret = 0;
-
- else if (GET_MODE_SIZE (GET_MODE (op)) != 16)
- ret = 0;
-
- else if (MEM_ALIGN (op) < 128)
- ret = 0;
-
- else
- {
- addr = XEXP (op, 0);
- if (int_reg_operand (addr, Pmode))
- ret = 1;
+ return false;
- else if (GET_CODE (addr) != PLUS)
- ret = 0;
+ if (GET_MODE_SIZE (mode) != 16 || !MEM_P (op) || MEM_ALIGN (op) < 128)
+ return false;
- else
- {
- op0 = XEXP (addr, 0);
- op1 = XEXP (addr, 1);
- ret = (int_reg_operand (op0, Pmode)
- && GET_CODE (op1) == CONST_INT
- && IN_RANGE (INTVAL (op1), -32768, 32767)
- && (INTVAL (op1) & 15) == 0);
- }
- }
+ return quad_address_p (XEXP (op, 0), mode, true);
+})
- if (TARGET_DEBUG_ADDR)
- {
- fprintf (stderr, "\nquad_memory_operand, ret = %s\n", ret ? "true" : "false");
- debug_rtx (op);
- }
+;; Return 1 if the operand is suitable for load/store to vector registers with
+;; d-form addressing (register+offset), which was added in ISA 3.0.
+;; Unlike quad_memory_operand, we do not have to check for alignment.
+(define_predicate "vsx_quad_dform_memory_operand"
+ (match_code "mem")
+{
+ if (!TARGET_P9_DFORM_VECTOR || !MEM_P (op) || GET_MODE_SIZE (mode) != 16)
+ return false;
- return ret;
+ return quad_address_p (XEXP (op, 0), mode, false);
})
;; Return 1 if the operand is an indexed or indirect memory operand.
@@ -1054,6 +1068,10 @@
mode = V2DFmode;
else if (mode == DImode)
mode = V2DImode;
+ else if (mode == SImode && TARGET_P9_VECTOR)
+ mode = V4SImode;
+ else if (mode == SFmode && TARGET_P9_VECTOR)
+ mode = V4SFmode;
else
gcc_unreachable ();
return memory_address_addr_space_p (mode, XEXP (op, 0),
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index ef9fbadd200..399d9f69514 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -24,6 +24,7 @@
<http://www.gnu.org/licenses/>. */
/* Before including this file, some macros must be defined:
+ RS6000_BUILTIN_0 -- 0 arg builtins
RS6000_BUILTIN_1 -- 1 arg builtins
RS6000_BUILTIN_2 -- 2 arg builtins
RS6000_BUILTIN_3 -- 3 arg builtins
@@ -43,6 +44,10 @@
ATTR builtin attribute information.
ICODE Insn code of the function that implents the builtin. */
+#ifndef RS6000_BUILTIN_0
+ #error "RS6000_BUILTIN_0 is not defined."
+#endif
+
#ifndef RS6000_BUILTIN_1
#error "RS6000_BUILTIN_1 is not defined."
#endif
@@ -637,6 +642,41 @@
| RS6000_BTC_TERNARY), \
CODE_FOR_ ## ICODE) /* ICODE */
+/* Miscellaneous builtins for instructions added in ISA 3.0. These
+ instructions don't require either the DFP or VSX options, just the basic
+ ISA 3.0 enablement since they operate on general purpose registers. */
+#define BU_P9_MISC_1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_MODULO, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+/* Miscellaneous builtins for instructions added in ISA 3.0. These
+ instructions don't require either the DFP or VSX options, just the basic
+ ISA 3.0 enablement since they operate on general purpose registers,
+ and they require 64-bit addressing. */
+#define BU_P9_64BIT_MISC_0(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_MODULO \
+ | RS6000_BTM_64BIT, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_SPECIAL), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+/* Miscellaneous builtins for instructions added in ISA 3.0. These
+ instructions don't require either the DFP or VSX options, just the basic
+ ISA 3.0 enablement since they operate on general purpose registers. */
+#define BU_P9_MISC_0(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_0 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_MODULO, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_SPECIAL), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
/* 128-bit long double floating point builtins. */
#define BU_LDBL128_2(ENUM, NAME, ATTR, ICODE) \
RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
@@ -951,7 +991,6 @@ BU_ALTIVEC_X (VEC_EXT_V4SF, "vec_ext_v4sf", CONST)
before we get to the point about classifying the builtin type. */
/* 3 argument Altivec overloaded builtins. */
-BU_ALTIVEC_OVERLOAD_3 (ADDEC, "addec")
BU_ALTIVEC_OVERLOAD_3 (MADD, "madd")
BU_ALTIVEC_OVERLOAD_3 (MADDS, "madds")
BU_ALTIVEC_OVERLOAD_3 (MLADD, "mladd")
@@ -1137,6 +1176,7 @@ BU_ALTIVEC_OVERLOAD_P (VCMPGE_P, "vcmpge_p")
/* Overloaded Altivec builtins that are handled as special cases. */
BU_ALTIVEC_OVERLOAD_X (ADDE, "adde")
+BU_ALTIVEC_OVERLOAD_X (ADDEC, "addec")
BU_ALTIVEC_OVERLOAD_X (CTF, "ctf")
BU_ALTIVEC_OVERLOAD_X (CTS, "cts")
BU_ALTIVEC_OVERLOAD_X (CTU, "ctu")
@@ -1653,6 +1693,11 @@ BU_P8V_MISC_3 (BCDSUB_OV, "bcdsub_ov", CONST, bcdsub_unordered)
BU_DFP_MISC_2 (PACK_TD, "pack_dec128", CONST, packtd)
BU_DFP_MISC_2 (UNPACK_TD, "unpack_dec128", CONST, unpacktd)
+/* 0 argument general-purpose register functions added in ISA 3.0 (power9). */
+BU_P9_MISC_0 (DARN_32, "darn_32", MISC, darn_32)
+BU_P9_64BIT_MISC_0 (DARN_RAW, "darn_raw", MISC, darn_raw)
+BU_P9_64BIT_MISC_0 (DARN, "darn", MISC, darn)
+
BU_LDBL128_2 (PACK_TF, "pack_longdouble", CONST, packtf)
BU_LDBL128_2 (UNPACK_TF, "unpack_longdouble", CONST, unpacktf)
diff --git a/gcc/config/rs6000/rs6000-c.c b/gcc/config/rs6000/rs6000-c.c
index c69c93c5bd2..e09a86e8ada 100644
--- a/gcc/config/rs6000/rs6000-c.c
+++ b/gcc/config/rs6000/rs6000-c.c
@@ -4622,37 +4622,41 @@ assignment for unaligned loads and stores");
/* All 3 arguments must be vectors of (signed or unsigned) (int or
__int128) and the types must match. */
if ((arg0_type != arg1_type) || (arg1_type != arg2_type))
- goto bad;
+ goto bad;
if (TREE_CODE (arg0_type) != VECTOR_TYPE)
- goto bad;
+ goto bad;
switch (TYPE_MODE (TREE_TYPE (arg0_type)))
{
- /* For {un}signed ints,
- vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb),
- vec_and (carryv, 0x1)). */
+ /* For {un}signed ints,
+ vec_adde (va, vb, carryv) == vec_add (vec_add (va, vb),
+ vec_and (carryv, 0x1)). */
case SImode:
{
- vec<tree, va_gc> *params = make_tree_vector();
+ vec<tree, va_gc> *params = make_tree_vector ();
vec_safe_push (params, arg0);
vec_safe_push (params, arg1);
- tree call = altivec_resolve_overloaded_builtin
- (loc, rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD], params);
- tree const1 = build_vector_from_val (arg0_type,
- build_int_cstu(TREE_TYPE (arg0_type), 1));
- tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR,
- arg0_type, arg2, const1);
- params = make_tree_vector();
+ tree add_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD];
+ tree call = altivec_resolve_overloaded_builtin (loc, add_builtin,
+ params);
+ tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
+ tree ones_vector = build_vector_from_val (arg0_type, const1);
+ tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
+ arg2, ones_vector);
+ params = make_tree_vector ();
vec_safe_push (params, call);
vec_safe_push (params, and_expr);
- return altivec_resolve_overloaded_builtin
- (loc, rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD], params);
+ return altivec_resolve_overloaded_builtin (loc, add_builtin,
+ params);
}
/* For {un}signed __int128s use the vaddeuqm instruction
directly. */
case TImode:
- return altivec_resolve_overloaded_builtin
- (loc, rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDEUQM], arglist);
+ {
+ tree adde_bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDEUQM];
+ return altivec_resolve_overloaded_builtin (loc, adde_bii,
+ arglist);
+ }
/* Types other than {un}signed int and {un}signed __int128
are errors. */
@@ -4661,6 +4665,86 @@ assignment for unaligned loads and stores");
}
}
+ if (fcode == ALTIVEC_BUILTIN_VEC_ADDEC)
+ {
+ /* vec_addec needs to be special cased because there is no instruction
+ for the {un}signed int version. */
+ if (nargs != 3)
+ {
+ error ("vec_addec only accepts 3 arguments");
+ return error_mark_node;
+ }
+
+ tree arg0 = (*arglist)[0];
+ tree arg0_type = TREE_TYPE (arg0);
+ tree arg1 = (*arglist)[1];
+ tree arg1_type = TREE_TYPE (arg1);
+ tree arg2 = (*arglist)[2];
+ tree arg2_type = TREE_TYPE (arg2);
+
+ /* All 3 arguments must be vectors of (signed or unsigned) (int or
+ __int128) and the types must match. */
+ if (arg0_type != arg1_type || arg1_type != arg2_type)
+ goto bad;
+ if (TREE_CODE (arg0_type) != VECTOR_TYPE)
+ goto bad;
+
+ switch (TYPE_MODE (TREE_TYPE (arg0_type)))
+ {
+ /* For {un}signed ints,
+ vec_addec (va, vb, carryv) ==
+ vec_or (vec_addc (va, vb),
+ vec_addc (vec_add (va, vb),
+ vec_and (carryv, 0x1))). */
+ case SImode:
+ {
+ /* Use save_expr to ensure that operands used more than once
+ that may have side effects (like calls) are only evaluated
+ once. */
+ arg0 = save_expr (arg0);
+ arg1 = save_expr (arg1);
+ vec<tree, va_gc> *params = make_tree_vector ();
+ vec_safe_push (params, arg0);
+ vec_safe_push (params, arg1);
+ tree addc_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADDC];
+ tree call1 = altivec_resolve_overloaded_builtin (loc, addc_builtin,
+ params);
+ params = make_tree_vector ();
+ vec_safe_push (params, arg0);
+ vec_safe_push (params, arg1);
+ tree add_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_ADD];
+ tree call2 = altivec_resolve_overloaded_builtin (loc, add_builtin,
+ params);
+ tree const1 = build_int_cstu (TREE_TYPE (arg0_type), 1);
+ tree ones_vector = build_vector_from_val (arg0_type, const1);
+ tree and_expr = fold_build2_loc (loc, BIT_AND_EXPR, arg0_type,
+ arg2, ones_vector);
+ params = make_tree_vector ();
+ vec_safe_push (params, call2);
+ vec_safe_push (params, and_expr);
+ call2 = altivec_resolve_overloaded_builtin (loc, addc_builtin,
+ params);
+ params = make_tree_vector ();
+ vec_safe_push (params, call1);
+ vec_safe_push (params, call2);
+ tree or_builtin = rs6000_builtin_decls[ALTIVEC_BUILTIN_VEC_OR];
+ return altivec_resolve_overloaded_builtin (loc, or_builtin,
+ params);
+ }
+ /* For {un}signed __int128s use the vaddecuq instruction. */
+ case TImode:
+ {
+ tree VADDECUQ_bii = rs6000_builtin_decls[P8V_BUILTIN_VEC_VADDECUQ];
+ return altivec_resolve_overloaded_builtin (loc, VADDECUQ_bii,
+ arglist);
+ }
+ /* Types other than {un}signed int and {un}signed __int128
+ are errors. */
+ default:
+ goto bad;
+ }
+ }
+
/* For now treat vec_splats and vec_promote as the same. */
if (fcode == ALTIVEC_BUILTIN_VEC_SPLATS
|| fcode == ALTIVEC_BUILTIN_VEC_PROMOTE)
@@ -4759,9 +4843,9 @@ assignment for unaligned loads and stores");
arg1_type = TREE_TYPE (arg1);
if (TREE_CODE (arg1_type) != VECTOR_TYPE)
- goto bad;
+ goto bad;
if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
- goto bad;
+ goto bad;
/* If we are targeting little-endian, but -maltivec=be has been
specified to override the element order, adjust the element
@@ -4862,9 +4946,9 @@ assignment for unaligned loads and stores");
arg2 = (*arglist)[2];
if (TREE_CODE (arg1_type) != VECTOR_TYPE)
- goto bad;
+ goto bad;
if (!INTEGRAL_TYPE_P (TREE_TYPE (arg2)))
- goto bad;
+ goto bad;
/* If we are targeting little-endian, but -maltivec=be has been
specified to override the element order, adjust the element
diff --git a/gcc/config/rs6000/rs6000-cpus.def b/gcc/config/rs6000/rs6000-cpus.def
index 275404a63ac..27239f1d371 100644
--- a/gcc/config/rs6000/rs6000-cpus.def
+++ b/gcc/config/rs6000/rs6000-cpus.def
@@ -60,13 +60,14 @@
| OPTION_MASK_UPPER_REGS_SF)
/* Add ISEL back into ISA 3.0, since it is supposed to be a win. Do not add
- P9_DFORM or P9_MINMAX until they are fully debugged. */
+ P9_MINMAX until the hardware that supports it is available. Do not add
+ P9_DFORM_VECTOR until LRA is the default register allocator. */
#define ISA_3_0_MASKS_SERVER (ISA_2_7_MASKS_SERVER \
| OPTION_MASK_FLOAT128_HW \
| OPTION_MASK_ISEL \
| OPTION_MASK_MODULO \
| OPTION_MASK_P9_FUSION \
- | OPTION_MASK_P9_DFORM \
+ | OPTION_MASK_P9_DFORM_SCALAR \
| OPTION_MASK_P9_VECTOR)
#define POWERPC_7400_MASK (OPTION_MASK_PPC_GFXOPT | OPTION_MASK_ALTIVEC)
@@ -94,6 +95,7 @@
| OPTION_MASK_FPRND \
| OPTION_MASK_HTM \
| OPTION_MASK_ISEL \
+ | OPTION_MASK_LRA \
| OPTION_MASK_MFCRF \
| OPTION_MASK_MFPGPR \
| OPTION_MASK_MODULO \
@@ -101,7 +103,8 @@
| OPTION_MASK_NO_UPDATE \
| OPTION_MASK_P8_FUSION \
| OPTION_MASK_P8_VECTOR \
- | OPTION_MASK_P9_DFORM \
+ | OPTION_MASK_P9_DFORM_SCALAR \
+ | OPTION_MASK_P9_DFORM_VECTOR \
| OPTION_MASK_P9_FUSION \
| OPTION_MASK_P9_MINMAX \
| OPTION_MASK_P9_VECTOR \
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index d9a6b1f784b..6b4d17801d0 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -31,6 +31,7 @@ extern void init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, int, int, int,
#endif /* TREE_CODE */
extern bool easy_altivec_constant (rtx, machine_mode);
+extern bool xxspltib_constant_p (rtx, machine_mode, int *, int *);
extern int vspltis_shifted (rtx);
extern HOST_WIDE_INT const_vector_elt_as_int (rtx, unsigned int);
extern bool macho_lo_sum_memory_operand (rtx, machine_mode);
@@ -86,6 +87,7 @@ extern int registers_ok_for_quad_peep (rtx, rtx);
extern int mems_ok_for_quad_peep (rtx, rtx);
extern bool gpr_or_gpr_p (rtx, rtx);
extern bool direct_move_p (rtx, rtx);
+extern bool quad_address_p (rtx, machine_mode, bool);
extern bool quad_load_store_p (rtx, rtx);
extern bool fusion_gpr_load_p (rtx, rtx, rtx, rtx);
extern void expand_fusion_gpr_load (rtx *);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index d12633d85c9..0488db563e6 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -452,6 +452,7 @@ typedef unsigned char addr_mask_type;
#define RELOAD_REG_PRE_INCDEC 0x10 /* PRE_INC/PRE_DEC valid. */
#define RELOAD_REG_PRE_MODIFY 0x20 /* PRE_MODIFY valid. */
#define RELOAD_REG_AND_M16 0x40 /* AND -16 addressing. */
+#define RELOAD_REG_QUAD_OFFSET 0x80 /* quad offset is limited. */
/* Register type masks based on the type, of valid addressing modes. */
struct rs6000_reg_addr {
@@ -499,6 +500,16 @@ mode_supports_vmx_dform (machine_mode mode)
return ((reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_OFFSET) != 0);
}
+/* Return true if we have D-form addressing in VSX registers. This addressing
+ is more limited than normal d-form addressing in that the offset must be
+ aligned on a 16-byte boundary. */
+static inline bool
+mode_supports_vsx_dform_quad (machine_mode mode)
+{
+ return ((reg_addr[mode].addr_mask[RELOAD_REG_ANY] & RELOAD_REG_QUAD_OFFSET)
+ != 0);
+}
+
/* Target cpu costs. */
@@ -1128,6 +1139,7 @@ struct processor_costs ppca2_cost = {
/* Table that classifies rs6000 builtin functions (pure, const, etc.). */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -1140,6 +1152,9 @@ struct processor_costs ppca2_cost = {
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
+ { NAME, ICODE, MASK, ATTR },
+
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
{ NAME, ICODE, MASK, ATTR },
@@ -1185,6 +1200,7 @@ static const struct rs6000_builtin_info_type rs6000_builtin_info[] =
#include "rs6000-builtin.def"
};
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -1755,6 +1771,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
#undef TARGET_CONDITIONAL_REGISTER_USAGE
#define TARGET_CONDITIONAL_REGISTER_USAGE rs6000_conditional_register_usage
+#undef TARGET_SCHED_REASSOCIATION_WIDTH
+#define TARGET_SCHED_REASSOCIATION_WIDTH rs6000_reassociation_width
+
#undef TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT rs6000_trampoline_init
@@ -1866,7 +1885,7 @@ rs6000_hard_regno_nregs_internal (int regno, machine_mode mode)
128-bit floating point that can go in vector registers, which has VSX
memory addressing. */
if (FP_REGNO_P (regno))
- reg_size = (VECTOR_MEM_VSX_P (mode)
+ reg_size = (VECTOR_MEM_VSX_P (mode) || FLOAT128_VECTOR_P (mode)
? UNITS_PER_VSX_WORD
: UNITS_PER_FP_WORD);
@@ -1898,6 +1917,9 @@ rs6000_hard_regno_mode_ok (int regno, machine_mode mode)
{
int last_regno = regno + rs6000_hard_regno_nregs[mode][regno] - 1;
+ if (COMPLEX_MODE_P (mode))
+ mode = GET_MODE_INNER (mode);
+
/* PTImode can only go in GPRs. Quad word memory operations require even/odd
register combinations, and use PTImode where we need to deal with quad
word memory operations. Don't allow quad words in the argument or frame
@@ -2105,7 +2127,9 @@ rs6000_debug_addr_mask (addr_mask_type mask, bool keep_spaces)
else if (keep_spaces)
*p++ = ' ';
- if ((mask & RELOAD_REG_OFFSET) != 0)
+ if ((mask & RELOAD_REG_QUAD_OFFSET) != 0)
+ *p++ = 'O';
+ else if ((mask & RELOAD_REG_OFFSET) != 0)
*p++ = 'o';
else if (keep_spaces)
*p++ = ' ';
@@ -2642,8 +2666,7 @@ rs6000_debug_reg_global (void)
if (TARGET_LINK_STACK)
fprintf (stderr, DEBUG_FMT_S, "link_stack", "true");
- if (targetm.lra_p ())
- fprintf (stderr, DEBUG_FMT_S, "lra", "true");
+ fprintf (stderr, DEBUG_FMT_S, "lra", TARGET_LRA ? "true" : "false");
if (TARGET_P8_FUSION)
{
@@ -2699,8 +2722,17 @@ rs6000_setup_reg_addr_masks (void)
for (m = 0; m < NUM_MACHINE_MODES; ++m)
{
- machine_mode m2 = (machine_mode)m;
- unsigned short msize = GET_MODE_SIZE (m2);
+ machine_mode m2 = (machine_mode) m;
+ bool complex_p = false;
+ size_t msize;
+
+ if (COMPLEX_MODE_P (m2))
+ {
+ complex_p = true;
+ m2 = GET_MODE_INNER (m2);
+ }
+
+ msize = GET_MODE_SIZE (m2);
/* SDmode is special in that we want to access it only via REG+REG
addressing on power7 and above, since we want to use the LFIWZX and
@@ -2722,7 +2754,7 @@ rs6000_setup_reg_addr_masks (void)
/* Indicate if the mode takes more than 1 physical register. If
it takes a single register, indicate it can do REG+REG
addressing. */
- if (nregs > 1 || m == BLKmode)
+ if (nregs > 1 || m == BLKmode || complex_p)
addr_mask |= RELOAD_REG_MULTIPLE;
else
addr_mask |= RELOAD_REG_INDEXED;
@@ -2738,7 +2770,7 @@ rs6000_setup_reg_addr_masks (void)
&& msize <= 8
&& !VECTOR_MODE_P (m2)
&& !FLOAT128_VECTOR_P (m2)
- && !COMPLEX_MODE_P (m2)
+ && !complex_p
&& (m2 != DFmode || !TARGET_UPPER_REGS_DF)
&& (m2 != SFmode || !TARGET_UPPER_REGS_SF)
&& !(TARGET_E500_DOUBLE && msize == 8))
@@ -2769,17 +2801,31 @@ rs6000_setup_reg_addr_masks (void)
}
/* GPR and FPR registers can do REG+OFFSET addressing, except
- possibly for SDmode. ISA 3.0 (i.e. power9) adds D-form
- addressing for scalars to altivec registers. */
+ possibly for SDmode. ISA 3.0 (i.e. power9) adds D-form addressing
+ for 64-bit scalars and 32-bit SFmode to altivec registers. */
if ((addr_mask != 0) && !indexed_only_p
&& msize <= 8
&& (rc == RELOAD_REG_GPR
- || rc == RELOAD_REG_FPR
- || (rc == RELOAD_REG_VMX
- && TARGET_P9_DFORM
- && (m2 == DFmode || m2 == SFmode))))
+ || ((msize == 8 || m2 == SFmode)
+ && (rc == RELOAD_REG_FPR
+ || (rc == RELOAD_REG_VMX
+ && TARGET_P9_DFORM_SCALAR)))))
addr_mask |= RELOAD_REG_OFFSET;
+ /* VSX registers can do REG+OFFSET addresssing if ISA 3.0
+ instructions are enabled. The offset for 128-bit VSX registers is
+ only 12-bits. While GPRs can handle the full offset range, VSX
+ registers can only handle the restricted range. */
+ else if ((addr_mask != 0) && !indexed_only_p
+ && msize == 16 && TARGET_P9_DFORM_VECTOR
+ && (ALTIVEC_OR_VSX_VECTOR_MODE (m2)
+ || (m2 == TImode && TARGET_VSX_TIMODE)))
+ {
+ addr_mask |= RELOAD_REG_OFFSET;
+ if (rc == RELOAD_REG_FPR || rc == RELOAD_REG_VMX)
+ addr_mask |= RELOAD_REG_QUAD_OFFSET;
+ }
+
/* VMX registers can do (REG & -16) and ((REG+REG) & -16)
addressing on 128-bit types. */
if (rc == RELOAD_REG_VMX && msize == 16
@@ -3102,7 +3148,7 @@ rs6000_init_hard_regno_mode_ok (bool global_init_p)
}
/* Support for new D-form instructions. */
- if (TARGET_P9_DFORM)
+ if (TARGET_P9_DFORM_SCALAR)
rs6000_constraints[RS6000_CONSTRAINT_wb] = ALTIVEC_REGS;
/* Support for ISA 3.0 (power9) vectors. */
@@ -3622,6 +3668,8 @@ rs6000_builtin_mask_calculate (void)
| ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL : 0)
| ((TARGET_P8_VECTOR) ? RS6000_BTM_P8_VECTOR : 0)
| ((TARGET_P9_VECTOR) ? RS6000_BTM_P9_VECTOR : 0)
+ | ((TARGET_MODULO) ? RS6000_BTM_MODULO : 0)
+ | ((TARGET_64BIT) ? RS6000_BTM_64BIT : 0)
| ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0)
| ((TARGET_HTM) ? RS6000_BTM_HTM : 0)
| ((TARGET_DFP) ? RS6000_BTM_DFP : 0)
@@ -3975,7 +4023,8 @@ rs6000_option_override_internal (bool global_init_p)
/* For the newer switches (vsx, dfp, etc.) set some of the older options,
unless the user explicitly used the -mno-<option> to disable the code. */
- if (TARGET_P9_VECTOR || TARGET_MODULO || TARGET_P9_DFORM || TARGET_P9_MINMAX)
+ if (TARGET_P9_VECTOR || TARGET_MODULO || TARGET_P9_DFORM_SCALAR
+ || TARGET_P9_DFORM_VECTOR || TARGET_P9_DFORM_BOTH > 0 || TARGET_P9_MINMAX)
rs6000_isa_flags |= (ISA_3_0_MASKS_SERVER & ~rs6000_isa_flags_explicit);
else if (TARGET_P8_VECTOR || TARGET_DIRECT_MOVE || TARGET_CRYPTO)
rs6000_isa_flags |= (ISA_2_7_MASKS_SERVER & ~rs6000_isa_flags_explicit);
@@ -4189,26 +4238,49 @@ rs6000_option_override_internal (bool global_init_p)
&& !(rs6000_isa_flags_explicit & OPTION_MASK_TOC_FUSION))
rs6000_isa_flags |= OPTION_MASK_TOC_FUSION;
+ /* -mpower9-dform turns on both -mpower9-dform-scalar and
+ -mpower9-dform-vector. There are currently problems if
+ -mpower9-dform-vector instructions are enabled when we use the RELOAD
+ register allocator. */
+ if (TARGET_P9_DFORM_BOTH > 0)
+ {
+ if (!(rs6000_isa_flags_explicit & OPTION_MASK_P9_DFORM_VECTOR)
+ && TARGET_LRA)
+ rs6000_isa_flags |= OPTION_MASK_P9_DFORM_VECTOR;
+
+ if (!(rs6000_isa_flags_explicit & OPTION_MASK_P9_DFORM_SCALAR))
+ rs6000_isa_flags |= OPTION_MASK_P9_DFORM_SCALAR;
+ }
+ else if (TARGET_P9_DFORM_BOTH == 0)
+ {
+ if (!(rs6000_isa_flags_explicit & OPTION_MASK_P9_DFORM_VECTOR))
+ rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM_VECTOR;
+
+ if (!(rs6000_isa_flags_explicit & OPTION_MASK_P9_DFORM_SCALAR))
+ rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM_SCALAR;
+ }
+
/* ISA 3.0 D-form instructions require p9-vector and upper-regs. */
- if (TARGET_P9_DFORM && !TARGET_P9_VECTOR)
+ if ((TARGET_P9_DFORM_SCALAR || TARGET_P9_DFORM_VECTOR) && !TARGET_P9_VECTOR)
{
if (rs6000_isa_flags_explicit & OPTION_MASK_P9_VECTOR)
error ("-mpower9-dform requires -mpower9-vector");
- rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM;
+ rs6000_isa_flags &= ~(OPTION_MASK_P9_DFORM_SCALAR
+ | OPTION_MASK_P9_DFORM_VECTOR);
}
- if (TARGET_P9_DFORM && !TARGET_UPPER_REGS_DF)
+ if (TARGET_P9_DFORM_SCALAR && !TARGET_UPPER_REGS_DF)
{
if (rs6000_isa_flags_explicit & OPTION_MASK_UPPER_REGS_DF)
error ("-mpower9-dform requires -mupper-regs-df");
- rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM;
+ rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM_SCALAR;
}
- if (TARGET_P9_DFORM && !TARGET_UPPER_REGS_SF)
+ if (TARGET_P9_DFORM_SCALAR && !TARGET_UPPER_REGS_SF)
{
if (rs6000_isa_flags_explicit & OPTION_MASK_UPPER_REGS_SF)
error ("-mpower9-dform requires -mupper-regs-sf");
- rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM;
+ rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM_SCALAR;
}
/* ISA 3.0 vector instructions include ISA 2.07. */
@@ -4219,6 +4291,47 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_isa_flags &= ~OPTION_MASK_P9_VECTOR;
}
+ /* There have been bugs with both -mvsx-timode and -mpower9-dform-vector that
+ don't show up with -mlra, but do show up with -mno-lra. Given -mlra will
+ become the default once PR 69847 is fixed, turn off the options with
+ problems by default if -mno-lra was used, and warn if the user explicitly
+ asked for the option.
+
+ Enable -mpower9-dform-vector by default if LRA and other power9 options.
+ Enable -mvsx-timode by default if LRA and VSX. */
+ if (!TARGET_LRA)
+ {
+ if (TARGET_VSX_TIMODE)
+ {
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_VSX_TIMODE) != 0)
+ warning (0, "-mvsx-timode might need -mlra");
+
+ else
+ rs6000_isa_flags &= ~OPTION_MASK_VSX_TIMODE;
+ }
+
+ if (TARGET_P9_DFORM_VECTOR)
+ {
+ if ((rs6000_isa_flags_explicit & OPTION_MASK_P9_DFORM_VECTOR) != 0)
+ warning (0, "-mpower9-dform-vector might need -mlra");
+
+ else
+ rs6000_isa_flags &= ~OPTION_MASK_P9_DFORM_VECTOR;
+ }
+ }
+
+ else
+ {
+ if (TARGET_VSX && !TARGET_VSX_TIMODE
+ && (rs6000_isa_flags_explicit & OPTION_MASK_VSX_TIMODE) == 0)
+ rs6000_isa_flags |= OPTION_MASK_VSX_TIMODE;
+
+ if (TARGET_VSX && TARGET_P9_VECTOR && !TARGET_P9_DFORM_VECTOR
+ && TARGET_P9_DFORM_SCALAR && TARGET_P9_DFORM_BOTH < 0
+ && (rs6000_isa_flags_explicit & OPTION_MASK_P9_DFORM_VECTOR) == 0)
+ rs6000_isa_flags |= OPTION_MASK_P9_DFORM_VECTOR;
+ }
+
/* Set -mallow-movmisalign to explicitly on if we have full ISA 2.07
support. If we only have ISA 2.06 support, and the user did not specify
the switch, leave it set to -1 so the movmisalign patterns are enabled,
@@ -6135,6 +6248,128 @@ gen_easy_altivec_constant (rtx op)
gcc_unreachable ();
}
+/* Return true if OP is of the given MODE and can be synthesized with ISA 3.0
+ instructions (xxspltib, vupkhsb/vextsb2w/vextb2d).
+
+ Return the number of instructions needed (1 or 2) into the address pointed
+ via NUM_INSNS_PTR.
+
+ If NOSPLIT_P, only return true for constants that only generate the XXSPLTIB
+ instruction and can go in any VSX register. If !NOSPLIT_P, only return true
+ for constants that generate XXSPLTIB and need a sign extend operation, which
+ restricts us to the Altivec registers.
+
+ Allow either (vec_const [...]) or (vec_duplicate <const>). If OP is a valid
+ XXSPLTIB constant, return the constant being set via the CONST_PTR
+ pointer. */
+
+bool
+xxspltib_constant_p (rtx op,
+ machine_mode mode,
+ int *num_insns_ptr,
+ int *constant_ptr)
+{
+ size_t nunits = GET_MODE_NUNITS (mode);
+ size_t i;
+ HOST_WIDE_INT value;
+ rtx element;
+
+ /* Set the returned values to out of bound values. */
+ *num_insns_ptr = -1;
+ *constant_ptr = 256;
+
+ if (!TARGET_P9_VECTOR)
+ return false;
+
+ if (mode == VOIDmode)
+ mode = GET_MODE (op);
+
+ else if (mode != GET_MODE (op))
+ return false;
+
+ /* Handle (vec_duplicate <constant>). */
+ if (GET_CODE (op) == VEC_DUPLICATE)
+ {
+ if (mode != V16QImode && mode != V8HImode && mode != V4SImode
+ && mode != V2DImode)
+ return false;
+
+ element = XEXP (op, 0);
+ if (!CONST_INT_P (element))
+ return false;
+
+ value = INTVAL (element);
+ if (!IN_RANGE (value, -128, 127))
+ return false;
+ }
+
+ /* Handle (const_vector [...]). */
+ else if (GET_CODE (op) == CONST_VECTOR)
+ {
+ if (mode != V16QImode && mode != V8HImode && mode != V4SImode
+ && mode != V2DImode)
+ return false;
+
+ element = CONST_VECTOR_ELT (op, 0);
+ if (!CONST_INT_P (element))
+ return false;
+
+ value = INTVAL (element);
+ if (!IN_RANGE (value, -128, 127))
+ return false;
+
+ for (i = 1; i < nunits; i++)
+ {
+ element = CONST_VECTOR_ELT (op, i);
+ if (!CONST_INT_P (element))
+ return false;
+
+ if (value != INTVAL (element))
+ return false;
+ }
+
+ /* See if we could generate vspltisw/vspltish directly instead of
+ xxspltib + sign extend. Special case 0/-1 to allow getting
+ any VSX register instead of an Altivec register. */
+ if (!IN_RANGE (value, -1, 0) && EASY_VECTOR_15 (value)
+ && (mode == V4SImode || mode == V8HImode))
+ return false;
+ }
+
+ /* Handle integer constants being loaded into the upper part of the VSX
+ register as a scalar. If the value isn't 0/-1, only allow it if
+ the mode can go in Altivec registers. */
+ else if (CONST_INT_P (op))
+ {
+ if (!SCALAR_INT_MODE_P (mode))
+ return false;
+
+ value = INTVAL (op);
+ if (!IN_RANGE (value, -128, 127))
+ return false;
+
+ if (!IN_RANGE (value, -1, 0)
+ && (reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_VALID) == 0)
+ return false;
+ }
+
+ else
+ return false;
+
+ /* Return # of instructions and the constant byte for XXSPLTIB. */
+ if (mode == V16QImode)
+ *num_insns_ptr = 1;
+
+ else if (IN_RANGE (value, -1, 0))
+ *num_insns_ptr = 1;
+
+ else
+ *num_insns_ptr = 2;
+
+ *constant_ptr = (int) value;
+ return true;
+}
+
const char *
output_vec_const_move (rtx *operands)
{
@@ -6148,23 +6383,60 @@ output_vec_const_move (rtx *operands)
if (TARGET_VSX)
{
+ bool dest_vmx_p = ALTIVEC_REGNO_P (REGNO (dest));
+ int xxspltib_value = 256;
+ int num_insns = -1;
+
if (zero_constant (vec, mode))
- return "xxlxor %x0,%x0,%x0";
+ {
+ if (TARGET_P9_VECTOR)
+ return "xxspltib %x0,0";
+
+ else if (dest_vmx_p)
+ return "vspltisw %0,0";
- if (TARGET_P8_VECTOR && vec == CONSTM1_RTX (mode))
- return "xxlorc %x0,%x0,%x0";
+ else
+ return "xxlxor %x0,%x0,%x0";
+ }
+
+ if (all_ones_constant (vec, mode))
+ {
+ if (TARGET_P9_VECTOR)
+ return "xxspltib %x0,255";
+
+ else if (dest_vmx_p)
+ return "vspltisw %0,-1";
+
+ else if (TARGET_P8_VECTOR)
+ return "xxlorc %x0,%x0,%x0";
+
+ else
+ gcc_unreachable ();
+ }
+
+ if (TARGET_P9_VECTOR
+ && xxspltib_constant_p (vec, mode, &num_insns, &xxspltib_value))
+ {
+ if (num_insns == 1)
+ {
+ operands[2] = GEN_INT (xxspltib_value & 0xff);
+ return "xxspltib %x0,%2";
+ }
- if ((mode == V2DImode || mode == V1TImode)
- && INTVAL (CONST_VECTOR_ELT (vec, 0)) == -1
- && INTVAL (CONST_VECTOR_ELT (vec, 1)) == -1)
- return (TARGET_P8_VECTOR) ? "xxlorc %x0,%x0,%x0" : "vspltisw %0,-1";
+ return "#";
+ }
}
if (TARGET_ALTIVEC)
{
rtx splat_vec;
+
+ gcc_assert (ALTIVEC_REGNO_P (REGNO (dest)));
if (zero_constant (vec, mode))
- return "vxor %0,%0,%0";
+ return "vspltisw %0,0";
+
+ if (all_ones_constant (vec, mode))
+ return "vspltisw %0,-1";
/* Do we need to construct a value using VSLDOI? */
shift = vspltis_shifted (vec);
@@ -6437,6 +6709,15 @@ rs6000_expand_vector_init (rtx target, rtx vals)
return;
}
+ /* Word values on ISA 3.0 can use mtvsrws, lxvwsx, or vspltisw. V4SF is
+ complicated since scalars are stored as doubles in the registers. */
+ if (TARGET_P9_VECTOR && mode == V4SImode && all_same
+ && VECTOR_MEM_VSX_P (mode))
+ {
+ emit_insn (gen_vsx_splat_v4si (target, XVECEXP (vals, 0, 0)));
+ return;
+ }
+
/* With single precision floating point on VSX, know that internally single
precision is actually represented as a double, and either make 2 V2DF
vectors, and convert these vectors to single precision, or do one
@@ -6445,14 +6726,23 @@ rs6000_expand_vector_init (rtx target, rtx vals)
{
if (all_same)
{
- rtx freg = gen_reg_rtx (V4SFmode);
- rtx sreg = force_reg (SFmode, XVECEXP (vals, 0, 0));
- rtx cvt = ((TARGET_XSCVDPSPN)
- ? gen_vsx_xscvdpspn_scalar (freg, sreg)
- : gen_vsx_xscvdpsp_scalar (freg, sreg));
+ rtx op0 = XVECEXP (vals, 0, 0);
+
+ if (TARGET_P9_VECTOR)
+ emit_insn (gen_vsx_splat_v4sf (target, op0));
- emit_insn (cvt);
- emit_insn (gen_vsx_xxspltw_v4sf_direct (target, freg, const0_rtx));
+ else
+ {
+ rtx freg = gen_reg_rtx (V4SFmode);
+ rtx sreg = force_reg (SFmode, op0);
+ rtx cvt = (TARGET_XSCVDPSPN
+ ? gen_vsx_xscvdpspn_scalar (freg, sreg)
+ : gen_vsx_xscvdpsp_scalar (freg, sreg));
+
+ emit_insn (cvt);
+ emit_insn (gen_vsx_xxspltw_v4sf_direct (target, freg,
+ const0_rtx));
+ }
}
else
{
@@ -6903,6 +7193,59 @@ direct_move_p (rtx op0, rtx op1)
return false;
}
+/* Return true if the OFFSET is valid for the quad address instructions that
+ use d-form (register + offset) addressing. */
+
+static inline bool
+quad_address_offset_p (HOST_WIDE_INT offset)
+{
+ return (IN_RANGE (offset, -32768, 32767) && ((offset) & 0xf) == 0);
+}
+
+/* Return true if the ADDR is an acceptable address for a quad memory
+ operation of mode MODE (either LQ/STQ for general purpose registers, or
+ LXV/STXV for vector registers under ISA 3.0. GPR_P is true if this address
+ is intended for LQ/STQ. If it is false, the address is intended for the ISA
+ 3.0 LXV/STXV instruction. */
+
+bool
+quad_address_p (rtx addr, machine_mode mode, bool gpr_p)
+{
+ rtx op0, op1;
+
+ if (GET_MODE_SIZE (mode) != 16)
+ return false;
+
+ if (gpr_p)
+ {
+ if (!TARGET_QUAD_MEMORY && !TARGET_SYNC_TI)
+ return false;
+
+ /* LQ/STQ can handle indirect addresses. */
+ if (base_reg_operand (addr, Pmode))
+ return true;
+ }
+
+ else
+ {
+ if (!mode_supports_vsx_dform_quad (mode))
+ return false;
+ }
+
+ if (GET_CODE (addr) != PLUS)
+ return false;
+
+ op0 = XEXP (addr, 0);
+ if (!base_reg_operand (op0, Pmode))
+ return false;
+
+ op1 = XEXP (addr, 1);
+ if (!CONST_INT_P (op1))
+ return false;
+
+ return quad_address_offset_p (INTVAL (op1));
+}
+
/* Return true if this is a load or store quad operation. This function does
not handle the atomic quad memory instructions. */
@@ -6995,6 +7338,10 @@ mem_operand_gpr (rtx op, machine_mode mode)
if (TARGET_POWERPC64 && (offset & 3) != 0)
return false;
+ if (mode_supports_vsx_dform_quad (mode)
+ && !quad_address_offset_p (offset))
+ return false;
+
extra = GET_MODE_SIZE (mode) - UNITS_PER_WORD;
if (extra < 0)
extra = 0;
@@ -7024,13 +7371,14 @@ reg_offset_addressing_ok_p (machine_mode mode)
case TImode:
case TFmode:
case KFmode:
- /* AltiVec/VSX vector modes. Only reg+reg addressing is valid. While
- TImode is not a vector mode, if we want to use the VSX registers to
- move it around, we need to restrict ourselves to reg+reg addressing.
- Similarly for IEEE 128-bit floating point that is passed in a single
- vector register. */
+ /* AltiVec/VSX vector modes. Only reg+reg addressing was valid until the
+ ISA 3.0 vector d-form addressing mode was added. While TImode is not
+ a vector mode, if we want to use the VSX registers to move it around,
+ we need to restrict ourselves to reg+reg addressing. Similarly for
+ IEEE 128-bit floating point that is passed in a single vector
+ register. */
if (VECTOR_MEM_ALTIVEC_OR_VSX_P (mode))
- return false;
+ return mode_supports_vsx_dform_quad (mode);
break;
case V4HImode:
@@ -7097,6 +7445,11 @@ offsettable_ok_by_alignment (rtx op, HOST_WIDE_INT offset,
if (GET_CODE (op) != SYMBOL_REF)
return false;
+ /* ISA 3.0 vector d-form addressing is restricted, don't allow
+ SYMBOL_REF. */
+ if (mode_supports_vsx_dform_quad (mode))
+ return false;
+
dsize = GET_MODE_SIZE (mode);
decl = SYMBOL_REF_DECL (op);
if (!decl)
@@ -7251,6 +7604,9 @@ rs6000_legitimate_offset_address_p (machine_mode mode, rtx x,
return false;
if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
return false;
+ if (mode_supports_vsx_dform_quad (mode))
+ return (virtual_stack_registers_memory_p (x)
+ || quad_address_p (x, mode, false));
if (!reg_offset_addressing_ok_p (mode))
return virtual_stack_registers_memory_p (x);
if (legitimate_constant_pool_address_p (x, mode, strict || lra_in_progress))
@@ -7389,6 +7745,9 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
return false;
if (!INT_REG_OK_FOR_BASE_P (XEXP (x, 0), strict))
return false;
+ /* quad word addresses are restricted, and we can't use LO_SUM. */
+ if (mode_supports_vsx_dform_quad (mode))
+ return false;
/* Restrict addressing for DI because of our SUBREG hackery. */
if (TARGET_E500_DOUBLE && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
return false;
@@ -7400,7 +7759,7 @@ legitimate_lo_sum_address_p (machine_mode mode, rtx x, int strict)
if (DEFAULT_ABI == ABI_V4 && flag_pic)
return false;
- /* LRA don't use LEGITIMIZE_RELOAD_ADDRESS as it usually calls
+ /* LRA doesn't use LEGITIMIZE_RELOAD_ADDRESS as it usually calls
push_reload from reload pass code. LEGITIMIZE_RELOAD_ADDRESS
recognizes some LO_SUM addresses as valid although this
function says opposite. In most cases, LRA through different
@@ -7454,7 +7813,8 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
{
unsigned int extra;
- if (!reg_offset_addressing_ok_p (mode))
+ if (!reg_offset_addressing_ok_p (mode)
+ || mode_supports_vsx_dform_quad (mode))
{
if (virtual_stack_registers_memory_p (x))
return x;
@@ -8150,12 +8510,16 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
{
bool reg_offset_p = reg_offset_addressing_ok_p (mode);
- /* Nasty hack for vsx_splat_V2DF/V2DI load from mem, which takes a
- DFmode/DImode MEM. */
+ /* Nasty hack for vsx_splat_v2df/v2di load from mem, which takes a
+ DFmode/DImode MEM. Ditto for ISA 3.0 vsx_splat_v4sf/v4si. */
if (reg_offset_p
&& opnum == 1
&& ((mode == DFmode && recog_data.operand_mode[0] == V2DFmode)
- || (mode == DImode && recog_data.operand_mode[0] == V2DImode)))
+ || (mode == DImode && recog_data.operand_mode[0] == V2DImode)
+ || (mode == SFmode && recog_data.operand_mode[0] == V4SFmode
+ && TARGET_P9_VECTOR)
+ || (mode == SImode && recog_data.operand_mode[0] == V4SImode
+ && TARGET_P9_VECTOR)))
reg_offset_p = false;
/* We must recognize output that we have already generated ourselves. */
@@ -8165,6 +8529,11 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
&& GET_CODE (XEXP (x, 1)) == CONST_INT)
{
+ if (TARGET_DEBUG_ADDR)
+ {
+ fprintf (stderr, "\nlegitimize_reload_address push_reload #1:\n");
+ debug_rtx (x);
+ }
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
opnum, (enum reload_type) type);
@@ -8176,6 +8545,11 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
if (GET_CODE (x) == LO_SUM
&& GET_CODE (XEXP (x, 0)) == HIGH)
{
+ if (TARGET_DEBUG_ADDR)
+ {
+ fprintf (stderr, "\nlegitimize_reload_address push_reload #2:\n");
+ debug_rtx (x);
+ }
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
opnum, (enum reload_type) type);
@@ -8208,6 +8582,11 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
{
rtx hi = gen_rtx_HIGH (Pmode, copy_rtx (x));
x = gen_rtx_LO_SUM (Pmode, hi, x);
+ if (TARGET_DEBUG_ADDR)
+ {
+ fprintf (stderr, "\nlegitimize_reload_address push_reload #3:\n");
+ debug_rtx (x);
+ }
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
opnum, (enum reload_type) type);
@@ -8245,6 +8624,11 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
GEN_INT (high)),
GEN_INT (low));
+ if (TARGET_DEBUG_ADDR)
+ {
+ fprintf (stderr, "\nlegitimize_reload_address push_reload #4:\n");
+ debug_rtx (x);
+ }
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, GET_MODE (x), VOIDmode, 0, 0,
opnum, (enum reload_type) type);
@@ -8305,6 +8689,11 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
x = gen_rtx_LO_SUM (GET_MODE (x),
gen_rtx_HIGH (Pmode, x), x);
+ if (TARGET_DEBUG_ADDR)
+ {
+ fprintf (stderr, "\nlegitimize_reload_address push_reload #5:\n");
+ debug_rtx (x);
+ }
push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
opnum, (enum reload_type) type);
@@ -8338,9 +8727,16 @@ rs6000_legitimize_reload_address (rtx x, machine_mode mode,
{
x = create_TOC_reference (x, NULL_RTX);
if (TARGET_CMODEL != CMODEL_SMALL)
- push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
- BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
- opnum, (enum reload_type) type);
+ {
+ if (TARGET_DEBUG_ADDR)
+ {
+ fprintf (stderr, "\nlegitimize_reload_address push_reload #6:\n");
+ debug_rtx (x);
+ }
+ push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
+ BASE_REG_CLASS, Pmode, VOIDmode, 0, 0,
+ opnum, (enum reload_type) type);
+ }
*win = 1;
return x;
}
@@ -8396,6 +8792,7 @@ static bool
rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
{
bool reg_offset_p = reg_offset_addressing_ok_p (mode);
+ bool quad_offset_p = mode_supports_vsx_dform_quad (mode);
/* If this is an unaligned stvx/ldvx type address, discard the outer AND. */
if (VECTOR_MEM_ALTIVEC_P (mode)
@@ -8415,15 +8812,26 @@ rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
return 1;
if (virtual_stack_registers_memory_p (x))
return 1;
- if (reg_offset_p && legitimate_small_data_p (mode, x))
- return 1;
- if (reg_offset_p
- && legitimate_constant_pool_address_p (x, mode,
+
+ /* Handle restricted vector d-form offsets in ISA 3.0. */
+ if (quad_offset_p)
+ {
+ if (quad_address_p (x, mode, false))
+ return 1;
+ }
+
+ else if (reg_offset_p)
+ {
+ if (legitimate_small_data_p (mode, x))
+ return 1;
+ if (legitimate_constant_pool_address_p (x, mode,
reg_ok_strict || lra_in_progress))
- return 1;
- if (reg_offset_p && reg_addr[mode].fused_toc && GET_CODE (x) == UNSPEC
- && XINT (x, 1) == UNSPEC_FUSION_ADDIS)
- return 1;
+ return 1;
+ if (reg_addr[mode].fused_toc && GET_CODE (x) == UNSPEC
+ && XINT (x, 1) == UNSPEC_FUSION_ADDIS)
+ return 1;
+ }
+
/* For TImode, if we have load/store quad and TImode in VSX registers, only
allow register indirect addresses. This will allow the values to go in
either GPRs or VSX registers without reloading. The vector types would
@@ -8462,7 +8870,8 @@ rs6000_legitimate_address_p (machine_mode mode, rtx x, bool reg_ok_strict)
&& legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
&& rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
return 1;
- if (reg_offset_p && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
+ if (reg_offset_p && !quad_offset_p
+ && legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
return 1;
return 0;
}
@@ -8621,6 +9030,40 @@ rs6000_offsettable_memref_p (rtx op, machine_mode reg_mode)
true, worst_case);
}
+/* Determine the reassociation width to be used in reassociate_bb.
+ This takes into account how many parallel operations we
+ can actually do of a given type, and also the latency.
+ P8:
+ int add/sub 6/cycle
+ mul 2/cycle
+ vect add/sub/mul 2/cycle
+ fp add/sub/mul 2/cycle
+ dfp 1/cycle
+*/
+
+static int
+rs6000_reassociation_width (unsigned int opc ATTRIBUTE_UNUSED,
+ enum machine_mode mode)
+{
+ switch (rs6000_cpu)
+ {
+ case PROCESSOR_POWER8:
+ case PROCESSOR_POWER9:
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ return 1;
+ if (VECTOR_MODE_P (mode))
+ return 4;
+ if (INTEGRAL_MODE_P (mode))
+ return opc == MULT_EXPR ? 4 : 6;
+ if (FLOAT_MODE_P (mode))
+ return 4;
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
/* Change register usage conditional on target flags. */
static void
rs6000_conditional_register_usage (void)
@@ -10040,6 +10483,35 @@ rs6000_must_pass_in_stack (machine_mode mode, const_tree type)
return must_pass_in_stack_var_size_or_pad (mode, type);
}
+static inline bool
+is_complex_IBM_long_double (machine_mode mode)
+{
+ return mode == ICmode || (!TARGET_IEEEQUAD && mode == TCmode);
+}
+
+/* Whether ABI_V4 passes MODE args to a function in floating point
+ registers. */
+
+static bool
+abi_v4_pass_in_fpr (machine_mode mode)
+{
+ if (!TARGET_FPRS || !TARGET_HARD_FLOAT)
+ return false;
+ if (TARGET_SINGLE_FLOAT && mode == SFmode)
+ return true;
+ if (TARGET_DOUBLE_FLOAT && mode == DFmode)
+ return true;
+ /* ABI_V4 passes complex IBM long double in 8 gprs.
+ Stupid, but we can't change the ABI now. */
+ if (is_complex_IBM_long_double (mode))
+ return false;
+ if (FLOAT128_2REG_P (mode))
+ return true;
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ return true;
+ return false;
+}
+
/* If defined, a C expression which determines whether, and in which
direction, to pad out an argument with extra space. The value
should be of type `enum direction': either `upward' to pad above
@@ -10124,6 +10596,7 @@ rs6000_function_arg_boundary (machine_mode mode, const_tree type)
&& (GET_MODE_SIZE (mode) == 8
|| (TARGET_HARD_FLOAT
&& TARGET_FPRS
+ && !is_complex_IBM_long_double (mode)
&& FLOAT128_2REG_P (mode))))
return 64;
else if (FLOAT128_VECTOR_P (mode))
@@ -10503,11 +10976,7 @@ rs6000_function_arg_advance_1 (CUMULATIVE_ARGS *cum, machine_mode mode,
}
else if (DEFAULT_ABI == ABI_V4)
{
- if (TARGET_HARD_FLOAT && TARGET_FPRS
- && ((TARGET_SINGLE_FLOAT && mode == SFmode)
- || (TARGET_DOUBLE_FLOAT && mode == DFmode)
- || FLOAT128_2REG_P (mode)
- || DECIMAL_FLOAT_MODE_P (mode)))
+ if (abi_v4_pass_in_fpr (mode))
{
/* _Decimal128 must use an even/odd register pair. This assumes
that the register number is odd when fregno is odd. */
@@ -11164,11 +11633,7 @@ rs6000_function_arg (cumulative_args_t cum_v, machine_mode mode,
else if (abi == ABI_V4)
{
- if (TARGET_HARD_FLOAT && TARGET_FPRS
- && ((TARGET_SINGLE_FLOAT && mode == SFmode)
- || (TARGET_DOUBLE_FLOAT && mode == DFmode)
- || FLOAT128_2REG_P (mode)
- || DECIMAL_FLOAT_MODE_P (mode)))
+ if (abi_v4_pass_in_fpr (mode))
{
/* _Decimal128 must use an even/odd register pair. This assumes
that the register number is odd when fregno is odd. */
@@ -12089,19 +12554,15 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
rsize = (size + 3) / 4;
align = 1;
- if (TARGET_HARD_FLOAT && TARGET_FPRS
- && ((TARGET_SINGLE_FLOAT && TYPE_MODE (type) == SFmode)
- || (TARGET_DOUBLE_FLOAT
- && (TYPE_MODE (type) == DFmode
- || FLOAT128_2REG_P (TYPE_MODE (type))
- || DECIMAL_FLOAT_MODE_P (TYPE_MODE (type))))))
+ machine_mode mode = TYPE_MODE (type);
+ if (abi_v4_pass_in_fpr (mode))
{
/* FP args go in FP registers, if present. */
reg = fpr;
n_reg = (size + 7) / 8;
sav_ofs = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4) * 4;
sav_scale = ((TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) ? 8 : 4);
- if (TYPE_MODE (type) != SFmode && TYPE_MODE (type) != SDmode)
+ if (mode != SFmode && mode != SDmode)
align = 8;
}
else
@@ -12121,7 +12582,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
addr = create_tmp_var (ptr_type_node, "addr");
/* AltiVec vectors never go in registers when -mabi=altivec. */
- if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (TYPE_MODE (type)))
+ if (TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode))
align = 16;
else
{
@@ -12142,7 +12603,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
}
/* _Decimal128 is passed in even/odd fpr pairs; the stored
reg number is 0 for f1, so we want to make it odd. */
- else if (reg == fpr && TYPE_MODE (type) == TDmode)
+ else if (reg == fpr && mode == TDmode)
{
t = build2 (BIT_IOR_EXPR, TREE_TYPE (reg), unshare_expr (reg),
build_int_cst (TREE_TYPE (reg), 1));
@@ -12169,7 +12630,7 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
FP register for 32-bit binaries. */
if (TARGET_32BIT
&& TARGET_HARD_FLOAT && TARGET_FPRS
- && TYPE_MODE (type) == SDmode)
+ && mode == SDmode)
t = fold_build_pointer_plus_hwi (t, size);
gimplify_assign (addr, t, pre_p);
@@ -12256,7 +12717,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
/* const function, function only depends on the inputs. */
TREE_READONLY (t) = 1;
TREE_NOTHROW (t) = 1;
- attr_string = ", pure";
+ attr_string = ", const";
}
else if ((classify & RS6000_BTC_PURE) != 0)
{
@@ -12264,7 +12725,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
external state. */
DECL_PURE_P (t) = 1;
TREE_NOTHROW (t) = 1;
- attr_string = ", const";
+ attr_string = ", pure";
}
else if ((classify & RS6000_BTC_FP) != 0)
{
@@ -12296,6 +12757,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
/* Simple ternary operations: VECd = foo (VECa, VECb, VECc). */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12308,6 +12770,7 @@ def_builtin (const char *name, tree type, enum rs6000_builtins code)
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) \
@@ -12329,6 +12792,7 @@ static const struct builtin_description bdesc_3arg[] =
/* DST operations: void foo (void *, const int, const char). */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12341,6 +12805,7 @@ static const struct builtin_description bdesc_3arg[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12362,6 +12827,7 @@ static const struct builtin_description bdesc_dst[] =
/* Simple binary operations: VECc = foo (VECa, VECb). */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12374,6 +12840,7 @@ static const struct builtin_description bdesc_dst[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
@@ -12393,6 +12860,7 @@ static const struct builtin_description bdesc_2arg[] =
#include "rs6000-builtin.def"
};
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12405,6 +12873,7 @@ static const struct builtin_description bdesc_2arg[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12427,6 +12896,7 @@ static const struct builtin_description bdesc_altivec_preds[] =
};
/* SPE predicates. */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12439,6 +12909,7 @@ static const struct builtin_description bdesc_altivec_preds[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12459,6 +12930,7 @@ static const struct builtin_description bdesc_spe_predicates[] =
};
/* SPE evsel predicates. */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12471,6 +12943,7 @@ static const struct builtin_description bdesc_spe_predicates[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12491,6 +12964,7 @@ static const struct builtin_description bdesc_spe_evsel[] =
};
/* PAIRED predicates. */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12503,6 +12977,7 @@ static const struct builtin_description bdesc_spe_evsel[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12524,6 +12999,7 @@ static const struct builtin_description bdesc_paired_preds[] =
/* ABS* operations. */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12536,6 +13012,7 @@ static const struct builtin_description bdesc_paired_preds[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12558,6 +13035,7 @@ static const struct builtin_description bdesc_abs[] =
/* Simple unary operations: VECb = foo (unsigned literal) or VECb =
foo (VECa). */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12570,6 +13048,7 @@ static const struct builtin_description bdesc_abs[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) \
{ MASK, ICODE, NAME, ENUM },
@@ -12589,7 +13068,43 @@ static const struct builtin_description bdesc_1arg[] =
#include "rs6000-builtin.def"
};
+/* Simple no-argument operations: result = __builtin_darn_32 () */
+
+#undef RS6000_BUILTIN_0
+#undef RS6000_BUILTIN_1
+#undef RS6000_BUILTIN_2
+#undef RS6000_BUILTIN_3
+#undef RS6000_BUILTIN_A
+#undef RS6000_BUILTIN_D
+#undef RS6000_BUILTIN_E
+#undef RS6000_BUILTIN_H
+#undef RS6000_BUILTIN_P
+#undef RS6000_BUILTIN_Q
+#undef RS6000_BUILTIN_S
+#undef RS6000_BUILTIN_X
+
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) \
+ { MASK, ICODE, NAME, ENUM },
+
+#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_A(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_D(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_E(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_H(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_P(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_Q(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_S(ENUM, NAME, MASK, ATTR, ICODE)
+#define RS6000_BUILTIN_X(ENUM, NAME, MASK, ATTR, ICODE)
+
+static const struct builtin_description bdesc_0arg[] =
+{
+#include "rs6000-builtin.def"
+};
+
/* HTM builtins. */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12602,6 +13117,7 @@ static const struct builtin_description bdesc_1arg[] =
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE)
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE)
@@ -12621,6 +13137,7 @@ static const struct builtin_description bdesc_htm[] =
#include "rs6000-builtin.def"
};
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -12705,7 +13222,6 @@ rs6000_expand_mtfsf_builtin (enum insn_code icode, tree exp)
return NULL_RTX;
}
-
static rtx
rs6000_expand_unop_builtin (enum insn_code icode, tree exp, rtx target)
{
@@ -15145,10 +15661,12 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
}
unsigned attr = rs6000_builtin_info[uns_fcode].attr & RS6000_BTC_TYPE_MASK;
+ /* RS6000_BTC_SPECIAL represents no-operand operators. */
gcc_assert (attr == RS6000_BTC_UNARY
|| attr == RS6000_BTC_BINARY
- || attr == RS6000_BTC_TERNARY);
-
+ || attr == RS6000_BTC_TERNARY
+ || attr == RS6000_BTC_SPECIAL);
+
/* Handle simple unary operations. */
d = bdesc_1arg;
for (i = 0; i < ARRAY_SIZE (bdesc_1arg); i++, d++)
@@ -15167,6 +15685,12 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
if (d->code == fcode)
return rs6000_expand_ternop_builtin (d->icode, exp, target);
+ /* Handle simple no-argument operations. */
+ d = bdesc_0arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
+ if (d->code == fcode)
+ return rs6000_expand_zeroop_builtin (d->icode, target);
+
gcc_unreachable ();
}
@@ -16033,6 +16557,8 @@ altivec_init_builtins (void)
def_builtin ("__builtin_vec_adde", opaque_ftype_opaque_opaque_opaque,
ALTIVEC_BUILTIN_VEC_ADDE);
+ def_builtin ("__builtin_vec_addec", opaque_ftype_opaque_opaque_opaque,
+ ALTIVEC_BUILTIN_VEC_ADDEC);
/* Cell builtins. */
def_builtin ("__builtin_altivec_lvlx", v16qi_ftype_long_pcvoid, ALTIVEC_BUILTIN_LVLX);
@@ -16547,10 +17073,6 @@ builtin_function_type (machine_mode mode_ret, machine_mode mode_arg0,
while (num_args > 0 && h.mode[num_args] == VOIDmode)
num_args--;
- if (num_args == 0)
- fatal_error (input_location,
- "internal error: builtin function %s had no type", name);
-
ret_type = builtin_mode_to_type[h.mode[0]][h.uns_p[0]];
if (!ret_type && h.uns_p[0])
ret_type = builtin_mode_to_type[h.mode[0]][0];
@@ -16602,6 +17124,7 @@ rs6000_common_init_builtins (void)
tree opaque_ftype_opaque = NULL_TREE;
tree opaque_ftype_opaque_opaque = NULL_TREE;
tree opaque_ftype_opaque_opaque_opaque = NULL_TREE;
+ tree v2si_ftype = NULL_TREE;
tree v2si_ftype_qi = NULL_TREE;
tree v2si_ftype_v2si_qi = NULL_TREE;
tree v2si_ftype_int_qi = NULL_TREE;
@@ -16818,6 +17341,64 @@ rs6000_common_init_builtins (void)
def_builtin (d->name, type, d->code);
}
+
+ /* Add the simple no-argument operators. */
+ d = bdesc_0arg;
+ for (i = 0; i < ARRAY_SIZE (bdesc_0arg); i++, d++)
+ {
+ machine_mode mode0;
+ tree type;
+ HOST_WIDE_INT mask = d->mask;
+
+ if ((mask & builtin_mask) != mask)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, skip no-argument %s\n", d->name);
+ continue;
+ }
+ if (rs6000_overloaded_builtin_p (d->code))
+ {
+ if (!opaque_ftype_opaque)
+ opaque_ftype_opaque
+ = build_function_type_list (opaque_V4SI_type_node, NULL_TREE);
+ type = opaque_ftype_opaque;
+ }
+ else
+ {
+ enum insn_code icode = d->icode;
+ if (d->name == 0)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr, "rs6000_builtin, bdesc_0arg[%lu] no name\n",
+ (long unsigned) i);
+ continue;
+ }
+ if (icode == CODE_FOR_nothing)
+ {
+ if (TARGET_DEBUG_BUILTIN)
+ fprintf (stderr,
+ "rs6000_builtin, skip no-argument %s (no code)\n",
+ d->name);
+ continue;
+ }
+ mode0 = insn_data[icode].operand[0].mode;
+ if (mode0 == V2SImode)
+ {
+ /* code for SPE */
+ if (! (type = v2si_ftype))
+ {
+ v2si_ftype
+ = build_function_type_list (opaque_V2SI_type_node,
+ NULL_TREE);
+ type = v2si_ftype;
+ }
+ }
+ else
+ type = builtin_function_type (mode0, VOIDmode, VOIDmode, VOIDmode,
+ d->code, d->name);
+ }
+ def_builtin (d->name, type, d->code);
+ }
}
/* Set up AIX/Darwin/64-bit Linux quad floating point routines. */
@@ -18202,25 +18783,33 @@ rs6000_secondary_reload_memory (rtx addr,
addr_mask = (reg_addr[mode].addr_mask[RELOAD_REG_VMX]
& ~RELOAD_REG_AND_M16);
- else
+ /* If the register allocator hasn't made up its mind yet on the register
+ class to use, settle on defaults to use. */
+ else if (rclass == NO_REGS)
{
- if (TARGET_DEBUG_ADDR)
- fprintf (stderr,
- "rs6000_secondary_reload_memory: mode = %s, class = %s, "
- "class is not GPR, FPR, VMX\n",
- GET_MODE_NAME (mode), reg_class_names[rclass]);
+ addr_mask = (reg_addr[mode].addr_mask[RELOAD_REG_ANY]
+ & ~RELOAD_REG_AND_M16);
- return -1;
+ if ((addr_mask & RELOAD_REG_MULTIPLE) != 0)
+ addr_mask &= ~(RELOAD_REG_INDEXED
+ | RELOAD_REG_PRE_INCDEC
+ | RELOAD_REG_PRE_MODIFY);
}
+ else
+ addr_mask = 0;
+
/* If the register isn't valid in this register class, just return now. */
if ((addr_mask & RELOAD_REG_VALID) == 0)
{
if (TARGET_DEBUG_ADDR)
- fprintf (stderr,
- "rs6000_secondary_reload_memory: mode = %s, class = %s, "
- "not valid in class\n",
- GET_MODE_NAME (mode), reg_class_names[rclass]);
+ {
+ fprintf (stderr,
+ "rs6000_secondary_reload_memory: mode = %s, class = %s, "
+ "not valid in class\n",
+ GET_MODE_NAME (mode), reg_class_names[rclass]);
+ debug_rtx (addr);
+ }
return -1;
}
@@ -18348,13 +18937,23 @@ rs6000_secondary_reload_memory (rtx addr,
}
}
+ else if ((addr_mask & RELOAD_REG_QUAD_OFFSET) != 0
+ && CONST_INT_P (plus_arg1))
+ {
+ if (!quad_address_offset_p (INTVAL (plus_arg1)))
+ {
+ extra_cost = 1;
+ type = "vector d-form offset";
+ }
+ }
+
/* Make sure the register class can handle offset addresses. */
else if (rs6000_legitimate_offset_address_p (mode, addr, false, true))
{
if ((addr_mask & RELOAD_REG_OFFSET) == 0)
{
extra_cost = 1;
- type = "offset";
+ type = "offset #2";
}
}
@@ -18367,7 +18966,14 @@ rs6000_secondary_reload_memory (rtx addr,
break;
case LO_SUM:
- if (!legitimate_lo_sum_address_p (mode, addr, false))
+ /* Quad offsets are restricted and can't handle normal addresses. */
+ if ((addr_mask & RELOAD_REG_QUAD_OFFSET) != 0)
+ {
+ extra_cost = -1;
+ type = "vector d-form lo_sum";
+ }
+
+ else if (!legitimate_lo_sum_address_p (mode, addr, false))
{
fail_msg = "bad LO_SUM";
extra_cost = -1;
@@ -18384,8 +18990,17 @@ rs6000_secondary_reload_memory (rtx addr,
case CONST:
case SYMBOL_REF:
case LABEL_REF:
- type = "address";
- extra_cost = rs6000_secondary_reload_toc_costs (addr_mask);
+ if ((addr_mask & RELOAD_REG_QUAD_OFFSET) != 0)
+ {
+ extra_cost = -1;
+ type = "vector d-form lo_sum #2";
+ }
+
+ else
+ {
+ type = "address";
+ extra_cost = rs6000_secondary_reload_toc_costs (addr_mask);
+ }
break;
/* TOC references look like offsetable memory. */
@@ -18396,6 +19011,12 @@ rs6000_secondary_reload_memory (rtx addr,
extra_cost = -1;
}
+ else if ((addr_mask & RELOAD_REG_QUAD_OFFSET) != 0)
+ {
+ extra_cost = -1;
+ type = "vector d-form lo_sum #3";
+ }
+
else if ((addr_mask & RELOAD_REG_OFFSET) == 0)
{
extra_cost = 1;
@@ -18849,6 +19470,9 @@ rs6000_secondary_reload (bool in_p,
fprintf (stderr, ", reload func = %s, extra cost = %d",
insn_data[sri->icode].name, sri->extra_cost);
+ else if (sri->extra_cost > 0)
+ fprintf (stderr, ", extra cost = %d", sri->extra_cost);
+
fputs ("\n", stderr);
debug_rtx (x);
}
@@ -19023,6 +19647,16 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
}
}
+ else if (mode_supports_vsx_dform_quad (mode) && CONST_INT_P (op1))
+ {
+ if (((addr_mask & RELOAD_REG_QUAD_OFFSET) == 0)
+ || !quad_address_p (addr, mode, false))
+ {
+ emit_insn (gen_rtx_SET (scratch, addr));
+ new_addr = scratch;
+ }
+ }
+
/* Make sure the register class can handle offset addresses. */
else if (rs6000_legitimate_offset_address_p (mode, addr, false, true))
{
@@ -19053,6 +19687,13 @@ rs6000_secondary_reload_inner (rtx reg, rtx mem, rtx scratch, bool store_p)
}
}
+ /* Quad offsets are restricted and can't handle normal addresses. */
+ else if (mode_supports_vsx_dform_quad (mode))
+ {
+ emit_insn (gen_rtx_SET (scratch, addr));
+ new_addr = scratch;
+ }
+
/* Make sure the register class can handle offset addresses. */
else if (legitimate_lo_sum_address_p (mode, addr, false))
{
@@ -19242,6 +19883,16 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
machine_mode mode = GET_MODE (x);
bool is_constant = CONSTANT_P (x);
+ /* If a mode can't go in FPR/ALTIVEC/VSX registers, don't return a preferred
+ reload class for it. */
+ if ((rclass == ALTIVEC_REGS || rclass == VSX_REGS)
+ && (reg_addr[mode].addr_mask[RELOAD_REG_VMX] & RELOAD_REG_VALID) == 0)
+ return NO_REGS;
+
+ if ((rclass == FLOAT_REGS || rclass == VSX_REGS)
+ && (reg_addr[mode].addr_mask[RELOAD_REG_FPR] & RELOAD_REG_VALID) == 0)
+ return NO_REGS;
+
/* For VSX, see if we should prefer FLOAT_REGS or ALTIVEC_REGS. Do not allow
the reloading of address expressions using PLUS into floating point
registers. */
@@ -19263,7 +19914,8 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
}
/* D-form addressing can easily reload the value. */
- if (mode_supports_vmx_dform (mode))
+ if (mode_supports_vmx_dform (mode)
+ || mode_supports_vsx_dform_quad (mode))
return rclass;
/* If this is a scalar floating point value and we don't have D-form
@@ -19291,6 +19943,25 @@ rs6000_preferred_reload_class (rtx x, enum reg_class rclass)
return NO_REGS;
}
+ /* If we haven't picked a register class, and the type is a vector or
+ floating point type, prefer to use the VSX, FPR, or Altivec register
+ classes. */
+ if (rclass == NO_REGS)
+ {
+ if (TARGET_VSX && VECTOR_MEM_VSX_OR_P8_VECTOR_P (mode))
+ return VSX_REGS;
+
+ if (TARGET_ALTIVEC && VECTOR_MEM_ALTIVEC_P (mode))
+ return ALTIVEC_REGS;
+
+ if (DECIMAL_FLOAT_MODE_P (mode))
+ return TARGET_DFP ? FLOAT_REGS : NO_REGS;
+
+ if (TARGET_FPRS && TARGET_HARD_FLOAT && FLOAT_MODE_P (mode)
+ && (reg_addr[mode].addr_mask[RELOAD_REG_FPR] & RELOAD_REG_VALID) == 0)
+ return FLOAT_REGS;
+ }
+
if (GET_MODE_CLASS (mode) == MODE_INT && rclass == NON_SPECIAL_REGS)
return GENERAL_REGS;
@@ -19679,8 +20350,16 @@ rs6000_output_move_128bit (rtx operands[])
else if (TARGET_VSX && dest_vsx_p)
{
- if (mode == V16QImode || mode == V8HImode || mode == V4SImode)
+ if (mode_supports_vsx_dform_quad (mode)
+ && quad_address_p (XEXP (src, 0), mode, false))
+ return "lxv %x0,%1";
+
+ else if (TARGET_P9_VECTOR)
+ return "lxvx %x0,%y1";
+
+ else if (mode == V16QImode || mode == V8HImode || mode == V4SImode)
return "lxvw4x %x0,%y1";
+
else
return "lxvd2x %x0,%y1";
}
@@ -19709,8 +20388,16 @@ rs6000_output_move_128bit (rtx operands[])
else if (TARGET_VSX && src_vsx_p)
{
- if (mode == V16QImode || mode == V8HImode || mode == V4SImode)
+ if (mode_supports_vsx_dform_quad (mode)
+ && quad_address_p (XEXP (dest, 0), mode, false))
+ return "stxv %x1,%0";
+
+ else if (TARGET_P9_VECTOR)
+ return "stxvx %x1,%y0";
+
+ else if (mode == V16QImode || mode == V8HImode || mode == V4SImode)
return "stxvw4x %x1,%y0";
+
else
return "stxvd2x %x1,%y0";
}
@@ -19732,10 +20419,8 @@ rs6000_output_move_128bit (rtx operands[])
if (dest_gpr_p)
return "#";
- else if (TARGET_VSX && dest_vsx_p && zero_constant (src, mode))
- return "xxlxor %x0,%x0,%x0";
-
- else if (TARGET_ALTIVEC && dest_vmx_p)
+ else if ((dest_vmx_p && TARGET_ALTIVEC)
+ || (dest_vsx_p && TARGET_VSX))
return output_vec_const_move (operands);
}
@@ -20613,7 +21298,8 @@ rs6000_assemble_integer (rtx x, unsigned int size, int aligned_p)
don't need to mark it here. We used to skip the text section, but it
should never be valid for relocated addresses to be placed in the text
section. */
- if (TARGET_RELOCATABLE
+ if (DEFAULT_ABI == ABI_V4
+ && (TARGET_RELOCATABLE || flag_pic > 1)
&& in_section != toc_section
&& !recurse
&& !CONST_SCALAR_INT_P (x)
@@ -23370,24 +24056,24 @@ rs6000_savres_strategy (rs6000_stack_t *info,
}
}
+ /* info->lr_save_p isn't yet set if the only reason lr needs to be
+ saved is an out-of-line save or restore. Set up the value for
+ the next test (excluding out-of-line gprs). */
+ bool lr_save_p = (info->lr_save_p
+ || !(strategy & SAVE_INLINE_FPRS)
+ || !(strategy & SAVE_INLINE_VRS)
+ || !(strategy & REST_INLINE_FPRS)
+ || !(strategy & REST_INLINE_VRS));
+
if (TARGET_MULTIPLE
&& !TARGET_POWERPC64
&& !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
- && info->first_gp_reg_save != 32)
+ && info->first_gp_reg_save < 31)
{
/* Prefer store multiple for saves over out-of-line routines,
since the store-multiple instruction will always be smaller. */
strategy |= SAVE_INLINE_GPRS | SAVE_MULTIPLE;
- /* info->lr_save_p isn't yet set if the only reason lr needs to be
- saved is an out-of-line save or restore. Set up the value for
- the next test (excluding out-of-line gprs). */
- bool lr_save_p = (info->lr_save_p
- || !(strategy & SAVE_INLINE_FPRS)
- || !(strategy & SAVE_INLINE_VRS)
- || !(strategy & REST_INLINE_FPRS)
- || !(strategy & REST_INLINE_VRS));
-
/* The situation is more complicated with load multiple. We'd
prefer to use the out-of-line routines for restores, since the
"exit" out-of-line routines can handle the restore of LR and the
@@ -23400,6 +24086,12 @@ rs6000_savres_strategy (rs6000_stack_t *info,
strategy |= REST_INLINE_GPRS | REST_MULTIPLE;
}
+ /* Using the "exit" out-of-line routine does not improve code size
+ if using it would require lr to be saved and if only saving one
+ or two gprs. */
+ else if (!lr_save_p && info->first_gp_reg_save > 29)
+ strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
+
/* We can only use load multiple or the out-of-line routines to
restore gprs if we've saved all the registers from
first_gp_reg_save. Otherwise, we risk loading garbage.
@@ -23637,9 +24329,9 @@ rs6000_stack_info (void)
info->calls_p = (!crtl->is_leaf || cfun->machine->ra_needs_full_frame);
/* Determine if we need to save the condition code registers. */
- if (df_regs_ever_live_p (CR2_REGNO)
- || df_regs_ever_live_p (CR3_REGNO)
- || df_regs_ever_live_p (CR4_REGNO))
+ if (save_reg_p (CR2_REGNO)
+ || save_reg_p (CR3_REGNO)
+ || save_reg_p (CR4_REGNO))
{
info->cr_save_p = 1;
if (DEFAULT_ABI == ABI_V4)
@@ -23804,7 +24496,9 @@ rs6000_stack_info (void)
&& !TARGET_PROFILE_KERNEL)
|| (DEFAULT_ABI == ABI_V4 && cfun->calls_alloca)
#ifdef TARGET_RELOCATABLE
- || (TARGET_RELOCATABLE && (get_pool_size () != 0))
+ || (DEFAULT_ABI == ABI_V4
+ && (TARGET_RELOCATABLE || flag_pic > 1)
+ && get_pool_size () != 0)
#endif
|| rs6000_ra_ever_killed ())
info->lr_save_p = 1;
@@ -24660,7 +25354,7 @@ output_probe_stack_range (rtx reg1, rtx reg2)
}
/* Add to 'insn' a note which is PATTERN (INSN) but with REG replaced
- with (plus:P (reg 1) VAL), and with REG2 replaced with RREG if REG2
+ with (plus:P (reg 1) VAL), and with REG2 replaced with REPL2 if REG2
is not NULL. It would be nice if dwarf2out_frame_debug_expr could
deduce these equivalences by itself so it wasn't necessary to hold
its hand so much. Don't be tempted to always supply d2_f_d_e with
@@ -24670,22 +25364,28 @@ output_probe_stack_range (rtx reg1, rtx reg2)
static rtx
rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
- rtx reg2, rtx rreg)
+ rtx reg2, rtx repl2)
{
- rtx real, temp;
+ rtx repl;
- if (REGNO (reg) == STACK_POINTER_REGNUM && reg2 == NULL_RTX)
+ if (REGNO (reg) == STACK_POINTER_REGNUM)
{
- /* No need for any replacement. Just set RTX_FRAME_RELATED_P. */
- int i;
-
gcc_checking_assert (val == 0);
- real = PATTERN (insn);
- if (GET_CODE (real) == PARALLEL)
- for (i = 0; i < XVECLEN (real, 0); i++)
- if (GET_CODE (XVECEXP (real, 0, i)) == SET)
+ repl = NULL_RTX;
+ }
+ else
+ repl = gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, STACK_POINTER_REGNUM),
+ GEN_INT (val));
+
+ rtx pat = PATTERN (insn);
+ if (!repl && !reg2)
+ {
+ /* No need for any replacement. Just set RTX_FRAME_RELATED_P. */
+ if (GET_CODE (pat) == PARALLEL)
+ for (int i = 0; i < XVECLEN (pat, 0); i++)
+ if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
{
- rtx set = XVECEXP (real, 0, i);
+ rtx set = XVECEXP (pat, 0, i);
/* If this PARALLEL has been emitted for out-of-line
register save functions, or store multiple, then omit
@@ -24700,79 +25400,47 @@ rs6000_frame_related (rtx insn, rtx reg, HOST_WIDE_INT val,
return insn;
}
- /* copy_rtx will not make unique copies of registers, so we need to
- ensure we don't have unwanted sharing here. */
- if (reg == reg2)
- reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
-
- if (reg == rreg)
- reg = gen_raw_REG (GET_MODE (reg), REGNO (reg));
-
- real = copy_rtx (PATTERN (insn));
-
- if (reg2 != NULL_RTX)
- real = replace_rtx (real, reg2, rreg);
-
- if (REGNO (reg) == STACK_POINTER_REGNUM)
- gcc_checking_assert (val == 0);
- else
- real = replace_rtx (real, reg,
- gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode,
- STACK_POINTER_REGNUM),
- GEN_INT (val)));
-
- /* We expect that 'real' is either a SET or a PARALLEL containing
+ /* We expect that 'pat' is either a SET or a PARALLEL containing
SETs (and possibly other stuff). In a PARALLEL, all the SETs
- are important so they all have to be marked RTX_FRAME_RELATED_P. */
+ are important so they all have to be marked RTX_FRAME_RELATED_P.
+ Call simplify_replace_rtx on the SETs rather than the whole insn
+ so as to leave the other stuff alone (for example USE of r12). */
- if (GET_CODE (real) == SET)
+ if (GET_CODE (pat) == SET)
{
- rtx set = real;
-
- temp = simplify_rtx (SET_SRC (set));
- if (temp)
- SET_SRC (set) = temp;
- temp = simplify_rtx (SET_DEST (set));
- if (temp)
- SET_DEST (set) = temp;
- if (GET_CODE (SET_DEST (set)) == MEM)
- {
- temp = simplify_rtx (XEXP (SET_DEST (set), 0));
- if (temp)
- XEXP (SET_DEST (set), 0) = temp;
- }
+ if (repl)
+ pat = simplify_replace_rtx (pat, reg, repl);
+ if (reg2)
+ pat = simplify_replace_rtx (pat, reg2, repl2);
}
- else
+ else if (GET_CODE (pat) == PARALLEL)
{
- int i;
+ pat = shallow_copy_rtx (pat);
+ XVEC (pat, 0) = shallow_copy_rtvec (XVEC (pat, 0));
- gcc_assert (GET_CODE (real) == PARALLEL);
- for (i = 0; i < XVECLEN (real, 0); i++)
- if (GET_CODE (XVECEXP (real, 0, i)) == SET)
+ for (int i = 0; i < XVECLEN (pat, 0); i++)
+ if (GET_CODE (XVECEXP (pat, 0, i)) == SET)
{
- rtx set = XVECEXP (real, 0, i);
-
- temp = simplify_rtx (SET_SRC (set));
- if (temp)
- SET_SRC (set) = temp;
- temp = simplify_rtx (SET_DEST (set));
- if (temp)
- SET_DEST (set) = temp;
- if (GET_CODE (SET_DEST (set)) == MEM)
- {
- temp = simplify_rtx (XEXP (SET_DEST (set), 0));
- if (temp)
- XEXP (SET_DEST (set), 0) = temp;
- }
+ rtx set = XVECEXP (pat, 0, i);
+
+ if (repl)
+ set = simplify_replace_rtx (set, reg, repl);
+ if (reg2)
+ set = simplify_replace_rtx (set, reg2, repl2);
+ XVECEXP (pat, 0, i) = set;
+
/* Omit eh_frame info for any user-defined global regs. */
if (!REG_P (SET_SRC (set))
|| !fixed_reg_p (REGNO (SET_SRC (set))))
RTX_FRAME_RELATED_P (set) = 1;
}
}
+ else
+ gcc_unreachable ();
RTX_FRAME_RELATED_P (insn) = 1;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, real);
+ if (repl || reg2)
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, pat);
return insn;
}
@@ -26146,25 +26814,37 @@ rs6000_emit_prologue (void)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
rtx areg, savereg, mem;
- int offset;
+ HOST_WIDE_INT offset;
offset = (info->altivec_save_offset + frame_off
+ 16 * (i - info->first_altivec_reg_save));
savereg = gen_rtx_REG (V4SImode, i);
- NOT_INUSE (0);
- areg = gen_rtx_REG (Pmode, 0);
- emit_move_insn (areg, GEN_INT (offset));
-
- /* AltiVec addressing mode is [reg+reg]. */
- mem = gen_frame_mem (V4SImode,
- gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
+ if (TARGET_P9_DFORM_VECTOR && quad_address_offset_p (offset))
+ {
+ mem = gen_frame_mem (V4SImode,
+ gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (offset)));
+ insn = emit_insn (gen_rtx_SET (mem, savereg));
+ areg = NULL_RTX;
+ }
+ else
+ {
+ NOT_INUSE (0);
+ areg = gen_rtx_REG (Pmode, 0);
+ emit_move_insn (areg, GEN_INT (offset));
- /* Rather than emitting a generic move, force use of the stvx
- instruction, which we always want. In particular we don't
- want xxpermdi/stxvd2x for little endian. */
- insn = emit_insn (gen_altivec_stvx_v4si_internal (mem, savereg));
+ /* AltiVec addressing mode is [reg+reg]. */
+ mem = gen_frame_mem (V4SImode,
+ gen_rtx_PLUS (Pmode, frame_reg_rtx, areg));
+
+ /* Rather than emitting a generic move, force use of the stvx
+ instruction, which we always want on ISA 2.07 (power8) systems.
+ In particular we don't want xxpermdi/stxvd2x for little
+ endian. */
+ insn = emit_insn (gen_altivec_stvx_v4si_internal (mem, savereg));
+ }
rs6000_frame_related (insn, frame_reg_rtx, sp_off - frame_off,
areg, GEN_INT (offset));
@@ -26884,23 +27564,35 @@ rs6000_emit_epilogue (int sibcall)
for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
- rtx addr, areg, mem, reg;
+ rtx addr, areg, mem, insn;
+ rtx reg = gen_rtx_REG (V4SImode, i);
+ HOST_WIDE_INT offset
+ = (info->altivec_save_offset + frame_off
+ + 16 * (i - info->first_altivec_reg_save));
- areg = gen_rtx_REG (Pmode, 0);
- emit_move_insn
- (areg, GEN_INT (info->altivec_save_offset
- + frame_off
- + 16 * (i - info->first_altivec_reg_save)));
+ if (TARGET_P9_DFORM_VECTOR && quad_address_offset_p (offset))
+ {
+ mem = gen_frame_mem (V4SImode,
+ gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (offset)));
+ insn = gen_rtx_SET (reg, mem);
+ }
+ else
+ {
+ areg = gen_rtx_REG (Pmode, 0);
+ emit_move_insn (areg, GEN_INT (offset));
- /* AltiVec addressing mode is [reg+reg]. */
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
- mem = gen_frame_mem (V4SImode, addr);
-
- reg = gen_rtx_REG (V4SImode, i);
- /* Rather than emitting a generic move, force use of the
- lvx instruction, which we always want. In particular
- we don't want lxvd2x/xxpermdi for little endian. */
- (void) emit_insn (gen_altivec_lvx_v4si_internal (reg, mem));
+ /* AltiVec addressing mode is [reg+reg]. */
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
+ mem = gen_frame_mem (V4SImode, addr);
+
+ /* Rather than emitting a generic move, force use of the
+ lvx instruction, which we always want. In particular we
+ don't want lxvd2x/xxpermdi for little endian. */
+ insn = gen_altivec_lvx_v4si_internal (reg, mem);
+ }
+
+ (void) emit_insn (insn);
}
}
@@ -27087,23 +27779,35 @@ rs6000_emit_epilogue (int sibcall)
for (i = info->first_altivec_reg_save; i <= LAST_ALTIVEC_REGNO; ++i)
if (info->vrsave_mask & ALTIVEC_REG_BIT (i))
{
- rtx addr, areg, mem, reg;
+ rtx addr, areg, mem, insn;
+ rtx reg = gen_rtx_REG (V4SImode, i);
+ HOST_WIDE_INT offset
+ = (info->altivec_save_offset + frame_off
+ + 16 * (i - info->first_altivec_reg_save));
- areg = gen_rtx_REG (Pmode, 0);
- emit_move_insn
- (areg, GEN_INT (info->altivec_save_offset
- + frame_off
- + 16 * (i - info->first_altivec_reg_save)));
+ if (TARGET_P9_DFORM_VECTOR && quad_address_offset_p (offset))
+ {
+ mem = gen_frame_mem (V4SImode,
+ gen_rtx_PLUS (Pmode, frame_reg_rtx,
+ GEN_INT (offset)));
+ insn = gen_rtx_SET (reg, mem);
+ }
+ else
+ {
+ areg = gen_rtx_REG (Pmode, 0);
+ emit_move_insn (areg, GEN_INT (offset));
- /* AltiVec addressing mode is [reg+reg]. */
- addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
- mem = gen_frame_mem (V4SImode, addr);
-
- reg = gen_rtx_REG (V4SImode, i);
- /* Rather than emitting a generic move, force use of the
- lvx instruction, which we always want. In particular
- we don't want lxvd2x/xxpermdi for little endian. */
- (void) emit_insn (gen_altivec_lvx_v4si_internal (reg, mem));
+ /* AltiVec addressing mode is [reg+reg]. */
+ addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, areg);
+ mem = gen_frame_mem (V4SImode, addr);
+
+ /* Rather than emitting a generic move, force use of the
+ lvx instruction, which we always want. In particular we
+ don't want lxvd2x/xxpermdi for little endian. */
+ insn = gen_altivec_lvx_v4si_internal (reg, mem);
+ }
+
+ (void) emit_insn (insn);
}
}
@@ -27921,6 +28625,11 @@ rs6000_expand_split_stack_prologue (void)
const0_rtx, const0_rtx));
call_fusage = NULL_RTX;
use_reg (&call_fusage, r12);
+ /* Say the call uses r0, even though it doesn't, to stop regrename
+ from twiddling with the insns saving lr, trashing args for cfun.
+ The insns restoring lr are similarly protected by making
+ split_stack_return use r0. */
+ use_reg (&call_fusage, r0);
add_function_usage_to (insn, call_fusage);
emit_insn (gen_frame_load (r0, r1, info->lr_save_offset));
insn = emit_move_insn (lr, r0);
@@ -31282,13 +31991,12 @@ static void
rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
{
if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
- && TARGET_MINIMAL_TOC
- && !TARGET_RELOCATABLE)
+ && TARGET_MINIMAL_TOC)
{
if (!toc_initialized)
{
- toc_initialized = 1;
fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
+ ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
(*targetm.asm_out.internal_label) (asm_out_file, "LCTOC", 0);
fprintf (asm_out_file, "\t.tc ");
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1[TC],");
@@ -31296,20 +32004,29 @@ rs6000_elf_output_toc_section_asm_op (const void *data ATTRIBUTE_UNUSED)
fprintf (asm_out_file, "\n");
fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
+ ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
fprintf (asm_out_file, " = .+32768\n");
+ toc_initialized = 1;
}
else
fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
}
- else if ((DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
- && !TARGET_RELOCATABLE)
- fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
+ else if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
+ {
+ fprintf (asm_out_file, "%s\n", TOC_SECTION_ASM_OP);
+ if (!toc_initialized)
+ {
+ ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
+ toc_initialized = 1;
+ }
+ }
else
{
fprintf (asm_out_file, "%s\n", MINIMAL_TOC_SECTION_ASM_OP);
if (!toc_initialized)
{
+ ASM_OUTPUT_ALIGN (asm_out_file, TARGET_64BIT ? 3 : 2);
ASM_OUTPUT_INTERNAL_LABEL_PREFIX (asm_out_file, "LCTOC1");
fprintf (asm_out_file, " = .+32768\n");
toc_initialized = 1;
@@ -31886,7 +32603,8 @@ rs6000_elf_asm_out_constructor (rtx symbol, int priority)
switch_to_section (get_section (section, SECTION_WRITE, NULL));
assemble_align (POINTER_SIZE);
- if (TARGET_RELOCATABLE)
+ if (DEFAULT_ABI == ABI_V4
+ && (TARGET_RELOCATABLE || flag_pic > 1))
{
fputs ("\t.long (", asm_out_file);
output_addr_const (asm_out_file, symbol);
@@ -31916,7 +32634,8 @@ rs6000_elf_asm_out_destructor (rtx symbol, int priority)
switch_to_section (get_section (section, SECTION_WRITE, NULL));
assemble_align (POINTER_SIZE);
- if (TARGET_RELOCATABLE)
+ if (DEFAULT_ABI == ABI_V4
+ && (TARGET_RELOCATABLE || flag_pic > 1))
{
fputs ("\t.long (", asm_out_file);
output_addr_const (asm_out_file, symbol);
@@ -31958,7 +32677,8 @@ rs6000_elf_declare_function_name (FILE *file, const char *name, tree decl)
return;
}
- if (TARGET_RELOCATABLE
+ if (DEFAULT_ABI == ABI_V4
+ && (TARGET_RELOCATABLE || flag_pic > 1)
&& !TARGET_SECURE_PLT
&& (get_pool_size () != 0 || crtl->profile)
&& uses_TOC ())
@@ -34066,8 +34786,14 @@ rs6000_complex_function_value (machine_mode mode)
machine_mode inner = GET_MODE_INNER (mode);
unsigned int inner_bytes = GET_MODE_UNIT_SIZE (mode);
- if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
+ if (TARGET_FLOAT128
+ && (mode == KCmode
+ || (mode == TCmode && TARGET_IEEEQUAD)))
+ regno = ALTIVEC_ARG_RETURN;
+
+ else if (FLOAT_MODE_P (mode) && TARGET_HARD_FLOAT && TARGET_FPRS)
regno = FP_ARG_RETURN;
+
else
{
regno = GP_ARG_RETURN;
@@ -34253,7 +34979,7 @@ rs6000_libcall_value (machine_mode mode)
static bool
rs6000_lra_p (void)
{
- return rs6000_lra_flag;
+ return TARGET_LRA;
}
/* Given FROM and TO register numbers, say whether this elimination is allowed.
@@ -34614,7 +35340,8 @@ static struct rs6000_opt_mask const rs6000_opt_masks[] =
{ "power8-fusion", OPTION_MASK_P8_FUSION, false, true },
{ "power8-fusion-sign", OPTION_MASK_P8_FUSION_SIGN, false, true },
{ "power8-vector", OPTION_MASK_P8_VECTOR, false, true },
- { "power9-dform", OPTION_MASK_P9_DFORM, false, true },
+ { "power9-dform-scalar", OPTION_MASK_P9_DFORM_SCALAR, false, true },
+ { "power9-dform-vector", OPTION_MASK_P9_DFORM_VECTOR, false, true },
{ "power9-fusion", OPTION_MASK_P9_FUSION, false, true },
{ "power9-minmax", OPTION_MASK_P9_MINMAX, false, true },
{ "power9-vector", OPTION_MASK_P9_VECTOR, false, true },
@@ -35247,7 +35974,9 @@ rs6000_print_options_internal (FILE *file,
size_t i;
size_t start_column = 0;
size_t cur_column;
- size_t max_column = 76;
+ size_t max_column = 120;
+ size_t prefix_len = strlen (prefix);
+ size_t comma_len = 0;
const char *comma = "";
if (indent)
@@ -35265,27 +35994,45 @@ rs6000_print_options_internal (FILE *file,
cur_column = start_column;
for (i = 0; i < num_elements; i++)
{
- if ((flags & opts[i].mask) != 0)
+ bool invert = opts[i].invert;
+ const char *name = opts[i].name;
+ const char *no_str = "";
+ HOST_WIDE_INT mask = opts[i].mask;
+ size_t len = comma_len + prefix_len + strlen (name);
+
+ if (!invert)
{
- const char *no_str = rs6000_opt_masks[i].invert ? "no-" : "";
- size_t len = (strlen (comma)
- + strlen (prefix)
- + strlen (no_str)
- + strlen (rs6000_opt_masks[i].name));
+ if ((flags & mask) == 0)
+ {
+ no_str = "no-";
+ len += sizeof ("no-") - 1;
+ }
+
+ flags &= ~mask;
+ }
- cur_column += len;
- if (cur_column > max_column)
+ else
+ {
+ if ((flags & mask) != 0)
{
- fprintf (stderr, ", \\\n%*s", (int)start_column, "");
- cur_column = start_column + len;
- comma = "";
+ no_str = "no-";
+ len += sizeof ("no-") - 1;
}
- fprintf (file, "%s%s%s%s", comma, prefix, no_str,
- rs6000_opt_masks[i].name);
- flags &= ~ opts[i].mask;
- comma = ", ";
+ flags |= mask;
}
+
+ cur_column += len;
+ if (cur_column > max_column)
+ {
+ fprintf (stderr, ", \\\n%*s", (int)start_column, "");
+ cur_column = start_column + len;
+ comma = "";
+ }
+
+ fprintf (file, "%s%s%s%s", comma, prefix, no_str, name);
+ comma = ", ";
+ comma_len = sizeof (", ") - 1;
}
fputs ("\n", file);
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 6e02d1d2867..a438bfb1b23 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -418,12 +418,12 @@ extern const char *host_detect_local_cpu (int argc, const char **argv);
Similarly IFmode is the IBM long double format even if the default is IEEE
128-bit. */
#define FLOAT128_IEEE_P(MODE) \
- (((MODE) == TFmode && TARGET_IEEEQUAD) \
- || ((MODE) == KFmode))
+ ((TARGET_IEEEQUAD && ((MODE) == TFmode || (MODE) == TCmode)) \
+ || ((MODE) == KFmode) || ((MODE) == KCmode))
#define FLOAT128_IBM_P(MODE) \
- (((MODE) == TFmode && !TARGET_IEEEQUAD) \
- || ((MODE) == IFmode))
+ ((!TARGET_IEEEQUAD && ((MODE) == TFmode || (MODE) == TCmode)) \
+ || ((MODE) == IFmode) || ((MODE) == ICmode))
/* Helper macros to say whether a 128-bit floating point type can go in a
single vector register, or whether it needs paired scalar values. */
@@ -636,18 +636,10 @@ extern int rs6000_vector_align[];
#define MASK_64BIT OPTION_MASK_64BIT
#endif
-#ifdef TARGET_RELOCATABLE
-#define MASK_RELOCATABLE OPTION_MASK_RELOCATABLE
-#endif
-
#ifdef TARGET_LITTLE_ENDIAN
#define MASK_LITTLE_ENDIAN OPTION_MASK_LITTLE_ENDIAN
#endif
-#ifdef TARGET_MINIMAL_TOC
-#define MASK_MINIMAL_TOC OPTION_MASK_MINIMAL_TOC
-#endif
-
#ifdef TARGET_REGNAMES
#define MASK_REGNAMES OPTION_MASK_REGNAMES
#endif
@@ -656,6 +648,11 @@ extern int rs6000_vector_align[];
#define MASK_PROTOTYPE OPTION_MASK_PROTOTYPE
#endif
+#ifdef TARGET_MODULO
+#define RS6000_BTM_MODULO OPTION_MASK_MODULO
+#endif
+
+
/* For power systems, we want to enable Altivec and VSX builtins even if the
user did not use -maltivec or -mvsx to allow the builtins to be used inside
of #pragma GCC target or the target attribute to change the code level for a
@@ -1775,7 +1772,9 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
#define ALTIVEC_ARG_RETURN (FIRST_ALTIVEC_REGNO + 2)
#define FP_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? FP_ARG_RETURN \
: (FP_ARG_RETURN + AGGR_ARG_NUM_REG - 1))
-#define ALTIVEC_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 ? ALTIVEC_ARG_RETURN \
+#define ALTIVEC_ARG_MAX_RETURN (DEFAULT_ABI != ABI_ELFv2 \
+ ? (ALTIVEC_ARG_RETURN \
+ + (TARGET_FLOAT128 ? 1 : 0)) \
: (ALTIVEC_ARG_RETURN + AGGR_ARG_NUM_REG - 1))
/* Flags for the call/call_value rtl operations set up by function_arg */
@@ -2056,7 +2055,10 @@ do { \
to allocate such a register (if necessary). */
#define RS6000_PIC_OFFSET_TABLE_REGNUM 30
-#define PIC_OFFSET_TABLE_REGNUM (flag_pic ? RS6000_PIC_OFFSET_TABLE_REGNUM : INVALID_REGNUM)
+#define PIC_OFFSET_TABLE_REGNUM \
+ (TARGET_TOC ? TOC_REGISTER \
+ : flag_pic ? RS6000_PIC_OFFSET_TABLE_REGNUM \
+ : INVALID_REGNUM)
#define TOC_REGISTER (TARGET_MINIMAL_TOC ? RS6000_PIC_OFFSET_TABLE_REGNUM : 2)
@@ -2639,7 +2641,9 @@ extern int frame_pointer_needed;
#define RS6000_BTC_MISC 0x00000000 /* No special attributes. */
#define RS6000_BTC_CONST 0x00000100 /* uses no global state. */
-#define RS6000_BTC_PURE 0x00000200 /* reads global state/mem. */
+#define RS6000_BTC_PURE 0x00000200 /* reads global
+ state/mem and does
+ not modify global state. */
#define RS6000_BTC_FP 0x00000400 /* depends on rounding mode. */
#define RS6000_BTC_ATTR_MASK 0x00000700 /* Mask of the attributes. */
@@ -2675,6 +2679,7 @@ extern int frame_pointer_needed;
#define RS6000_BTM_DFP MASK_DFP /* Decimal floating point. */
#define RS6000_BTM_HARD_FLOAT MASK_SOFT_FLOAT /* Hardware floating point. */
#define RS6000_BTM_LDBL128 MASK_MULTIPLE /* 128-bit long double. */
+#define RS6000_BTM_64BIT MASK_64BIT /* 64-bit addressing. */
#define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \
| RS6000_BTM_VSX \
@@ -2694,6 +2699,7 @@ extern int frame_pointer_needed;
/* Define builtin enum index. */
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
@@ -2706,6 +2712,7 @@ extern int frame_pointer_needed;
#undef RS6000_BUILTIN_S
#undef RS6000_BUILTIN_X
+#define RS6000_BUILTIN_0(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_1(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_2(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
#define RS6000_BUILTIN_3(ENUM, NAME, MASK, ATTR, ICODE) ENUM,
@@ -2725,6 +2732,7 @@ enum rs6000_builtins
RS6000_BUILTIN_COUNT
};
+#undef RS6000_BUILTIN_0
#undef RS6000_BUILTIN_1
#undef RS6000_BUILTIN_2
#undef RS6000_BUILTIN_3
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 5566185076a..349bcca62e4 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -9499,12 +9499,8 @@
char buf[30];
extern int need_toc_init;
need_toc_init = 1;
-#ifdef TARGET_RELOCATABLE
ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
- !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE);
-#else
- ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
-#endif
+ !TARGET_ELF || !TARGET_MINIMAL_TOC);
if (TARGET_ELF)
strcat (buf, \"@toc\");
operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
@@ -12591,8 +12587,10 @@
(set_attr "indexed" "no")])
;; A return instruction which the middle-end doesn't see.
+;; Use r0 to stop regrename twiddling with lr restore insns emitted
+;; after the call to __morestack.
(define_insn "split_stack_return"
- [(unspec_volatile [(const_int 0)] UNSPECV_SPLIT_STACK_RETURN)]
+ [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
""
"blr"
[(set_attr "type" "jmpreg")])
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index 9a155ce0e05..92c5396c47e 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -470,8 +470,8 @@ Target RejectNegative Joined UInteger Var(rs6000_long_double_type_size) Save
-mlong-double-<n> Specify size of long double (64 or 128 bits).
mlra
-Target Report Var(rs6000_lra_flag) Init(0) Save
-Use LRA instead of reload.
+Target Report Mask(LRA) Var(rs6000_isa_flags)
+Enable Local Register Allocation.
msched-costly-dep=
Target RejectNegative Joined Var(rs6000_sched_costly_dep_str)
@@ -609,9 +609,17 @@ mpower9-vector
Target Report Mask(P9_VECTOR) Var(rs6000_isa_flags)
Use/do not use vector and scalar instructions added in ISA 3.0.
+mpower9-dform-scalar
+Target Undocumented Mask(P9_DFORM_SCALAR) Var(rs6000_isa_flags)
+Use/do not use scalar register+offset memory instructions added in ISA 3.0.
+
+mpower9-dform-vector
+Target Undocumented Mask(P9_DFORM_VECTOR) Var(rs6000_isa_flags)
+Use/do not use vector register+offset memory instructions added in ISA 3.0.
+
mpower9-dform
-Target Undocumented Mask(P9_DFORM) Var(rs6000_isa_flags)
-Use/do not use vector and scalar instructions added in ISA 3.0.
+Target Report Var(TARGET_P9_DFORM_BOTH) Init(-1) Save
+Use/do not use register+offset memory instructions added in ISA 3.0.
mpower9-minmax
Target Undocumented Mask(P9_MINMAX) Var(rs6000_isa_flags)
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index cbf909722da..dbef3780a9d 100644
--- a/gcc/config/rs6000/sysv4.h
+++ b/gcc/config/rs6000/sysv4.h
@@ -40,10 +40,8 @@
#undef ASM_DEFAULT_SPEC
#define ASM_DEFAULT_SPEC "-mppc"
-#define TARGET_TOC ((rs6000_isa_flags & OPTION_MASK_64BIT) \
- || ((rs6000_isa_flags \
- & (OPTION_MASK_RELOCATABLE \
- | OPTION_MASK_MINIMAL_TOC)) \
+#define TARGET_TOC (TARGET_64BIT \
+ || (TARGET_MINIMAL_TOC \
&& flag_pic > 1) \
|| DEFAULT_ABI != ABI_V4)
@@ -192,16 +190,25 @@ do { \
error ("-msecure-plt not supported by your assembler"); \
} \
\
- /* Treat -fPIC the same as -mrelocatable. */ \
if (flag_pic > 1 && DEFAULT_ABI == ABI_V4) \
{ \
- rs6000_isa_flags |= OPTION_MASK_RELOCATABLE | OPTION_MASK_MINIMAL_TOC; \
+ /* Note: flag_pic should not change any option flags that would \
+ be invalid with or pessimise -fno-PIC code. LTO turns off \
+ flag_pic when linking/recompiling a fixed position executable. \
+ However, if the objects were originally compiled with -fPIC, \
+ then other target options forced on here by -fPIC are restored \
+ when recompiling those objects without -fPIC. In particular \
+ TARGET_RELOCATABLE must not be enabled here by flag_pic. */ \
+ rs6000_isa_flags |= OPTION_MASK_MINIMAL_TOC; \
TARGET_NO_FP_IN_TOC = 1; \
} \
\
- else if (TARGET_RELOCATABLE) \
- if (!flag_pic) \
- flag_pic = 2; \
+ if (TARGET_RELOCATABLE) \
+ { \
+ if (!flag_pic) \
+ flag_pic = 2; \
+ TARGET_NO_FP_IN_TOC = 1; \
+ } \
} while (0)
#ifndef RS6000_BI_ARCH
@@ -317,8 +324,7 @@ do { \
/* Put PC relative got entries in .got2. */
#define MINIMAL_TOC_SECTION_ASM_OP \
- (TARGET_RELOCATABLE || (flag_pic && DEFAULT_ABI == ABI_V4) \
- ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
+ (flag_pic ? "\t.section\t\".got2\",\"aw\"" : "\t.section\t\".got1\",\"aw\"")
#define SDATA_SECTION_ASM_OP "\t.section\t\".sdata\",\"aw\""
#define SDATA2_SECTION_ASM_OP "\t.section\t\".sdata2\",\"a\""
@@ -352,7 +358,6 @@ do { \
|| (GET_CODE (X) == CONST_INT \
&& GET_MODE_BITSIZE (MODE) <= GET_MODE_BITSIZE (Pmode)) \
|| (!TARGET_NO_FP_IN_TOC \
- && !TARGET_RELOCATABLE \
&& GET_CODE (X) == CONST_DOUBLE \
&& SCALAR_FLOAT_MODE_P (GET_MODE (X)) \
&& BITS_PER_WORD == HOST_BITS_PER_INT)))
@@ -744,21 +749,32 @@ ENDIAN_SELECT(" -mbig", " -mlittle", DEFAULT_ASM_ENDIAN)
%{!mnewlib: %{pthread:-lpthread} %{shared:-lc} \
%{!shared: %{profile:-lc_p} %{!profile:-lc}}}"
+#if ENABLE_OFFLOADING == 1
+#define CRTOFFLOADBEGIN "%{fopenacc|fopenmp:crtoffloadbegin%O%s}"
+#define CRTOFFLOADEND "%{fopenacc|fopenmp:crtoffloadend%O%s}"
+#else
+#define CRTOFFLOADBEGIN ""
+#define CRTOFFLOADEND ""
+#endif
+
#ifdef HAVE_LD_PIE
#define STARTFILE_LINUX_SPEC "\
%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
%{mnewlib:ecrti.o%s;:crti.o%s} \
-%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s} \
+" CRTOFFLOADBEGIN
#else
#define STARTFILE_LINUX_SPEC "\
%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}} \
%{mnewlib:ecrti.o%s;:crti.o%s} \
-%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+%{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s} \
+" CRTOFFLOADBEGIN
#endif
#define ENDFILE_LINUX_SPEC "\
%{shared|pie:crtendS.o%s;:crtend.o%s} \
-%{mnewlib:ecrtn.o%s;:crtn.o%s}"
+%{mnewlib:ecrtn.o%s;:crtn.o%s} \
+" CRTOFFLOADEND
#define LINK_START_LINUX_SPEC ""
@@ -941,9 +957,10 @@ ncrtn.o%s"
/* Select a format to encode pointers in exception handling data. CODE
is 0 for data, 1 for code labels, 2 for function pointers. GLOBAL is
true if the symbol may be affected by dynamic relocations. */
-#define ASM_PREFERRED_EH_DATA_FORMAT(CODE,GLOBAL) \
- ((flag_pic || TARGET_RELOCATABLE) \
- ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel | DW_EH_PE_sdata4) \
+#define ASM_PREFERRED_EH_DATA_FORMAT(CODE, GLOBAL) \
+ (flag_pic \
+ ? (((GLOBAL) ? DW_EH_PE_indirect : 0) | DW_EH_PE_pcrel \
+ | DW_EH_PE_sdata4) \
: DW_EH_PE_absptr)
#define DOUBLE_INT_ASM_OP "\t.quad\t"
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 508eeacd3a4..2b6963b0ac5 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -55,8 +55,7 @@
(KF "FLOAT128_VECTOR_P (KFmode)")
(TF "FLOAT128_VECTOR_P (TFmode)")])
-;; Iterator for memory move. Handle TImode specially to allow
-;; it to use gprs as well as vsx registers.
+;; Iterator for memory moves.
(define_mode_iterator VSX_M [V16QI
V8HI
V4SI
@@ -65,18 +64,8 @@
V2DF
V1TI
(KF "FLOAT128_VECTOR_P (KFmode)")
- (TF "FLOAT128_VECTOR_P (TFmode)")])
-
-(define_mode_iterator VSX_M2 [V16QI
- V8HI
- V4SI
- V2DI
- V4SF
- V2DF
- V1TI
- (KF "FLOAT128_VECTOR_P (KFmode)")
- (TF "FLOAT128_VECTOR_P (TFmode)")
- (TI "TARGET_VSX_TIMODE")])
+ (TF "FLOAT128_VECTOR_P (TFmode)")
+ (TI "TARGET_VSX_TIMODE")])
;; Map into the appropriate load/store name based on the type
(define_mode_attr VSm [(V16QI "vw4")
@@ -270,6 +259,10 @@
(define_mode_attr VS_64reg [(V2DF "ws")
(V2DI "wi")])
+;; Iterators for loading constants with xxspltib
+(define_mode_iterator VSINT_84 [V4SI V2DI])
+(define_mode_iterator VSINT_842 [V8HI V4SI V2DI])
+
;; Constants for creating unspecs
(define_c_enum "unspec"
[UNSPEC_VSX_CONCAT
@@ -299,26 +292,9 @@
UNSPEC_VSX_XVCVUXDDP
UNSPEC_VSX_XVCVDPSXDS
UNSPEC_VSX_XVCVDPUXDS
+ UNSPEC_VSX_SIGN_EXTEND
])
-;; VSX (P9) moves
-
-(define_insn "*p9_vecload_<mode>"
- [(set (match_operand:VSX_M2 0 "vsx_register_operand" "=<VSa>")
- (match_operand:VSX_M2 1 "memory_operand" "Z"))]
- "TARGET_P9_VECTOR"
- "lxvx %x0,%y1"
- [(set_attr "type" "vecload")
- (set_attr "length" "4")])
-
-(define_insn "*p9_vecstore_<mode>"
- [(set (match_operand:VSX_M2 0 "memory_operand" "=Z")
- (match_operand:VSX_M2 1 "vsx_register_operand" "<VSa>"))]
- "TARGET_P9_VECTOR"
- "stxvx %x1,%y0"
- [(set_attr "type" "vecstore")
- (set_attr "length" "4")])
-
;; VSX moves
;; The patterns for LE permuted loads and stores come before the general
@@ -787,92 +763,141 @@
(const_int 64)))]
"")
-(define_insn "*vsx_mov<mode>"
- [(set (match_operand:VSX_M 0 "nonimmediate_operand" "=Z,<VSr>,<VSr>,?Z,?<VSa>,?<VSa>,r,we,wQ,?&r,??Y,??r,??r,<VSr>,?<VSa>,*r,v,wZ,v")
- (match_operand:VSX_M 1 "input_operand" "<VSr>,Z,<VSr>,<VSa>,Z,<VSa>,we,b,r,wQ,r,Y,r,j,j,j,W,v,wZ"))]
- "VECTOR_MEM_VSX_P (<MODE>mode)
- && (register_operand (operands[0], <MODE>mode)
- || register_operand (operands[1], <MODE>mode))"
+;; Vector constants that can be generated with XXSPLTIB that was added in ISA
+;; 3.0. Both (const_vector [..]) and (vec_duplicate ...) forms are recognized.
+(define_insn "xxspltib_v16qi"
+ [(set (match_operand:V16QI 0 "vsx_register_operand" "=wa")
+ (vec_duplicate:V16QI (match_operand:SI 1 "s8bit_cint_operand" "n")))]
+ "TARGET_P9_VECTOR"
{
- return rs6000_output_move_128bit (operands);
+ operands[2] = GEN_INT (INTVAL (operands[1]) & 0xff);
+ return "xxspltib %x0,%2";
}
- [(set_attr "type" "vecstore,vecload,vecsimple,vecstore,vecload,vecsimple,mffgpr,mftgpr,load,store,store,load, *,vecsimple,vecsimple,*, *,vecstore,vecload")
- (set_attr "length" "4,4,4,4,4,4,8,4,12,12,12,12,16,4,4,*,16,4,4")])
-
-;; Unlike other VSX moves, allow the GPRs even for reloading, since a normal
-;; use of TImode is for unions. However for plain data movement, slightly
-;; favor the vector loads
-(define_insn "*vsx_movti_64bit"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,wa,wa,wa,r,we,v,v,wZ,wQ,&r,Y,r,r,?r")
- (match_operand:TI 1 "input_operand" "wa,Z,wa,O,we,b,W,wZ,v,r,wQ,r,Y,r,n"))]
- "TARGET_POWERPC64 && VECTOR_MEM_VSX_P (TImode)
- && (register_operand (operands[0], TImode)
- || register_operand (operands[1], TImode))"
+ [(set_attr "type" "vecperm")])
+
+(define_insn "xxspltib_<mode>_nosplit"
+ [(set (match_operand:VSINT_842 0 "vsx_register_operand" "=wa")
+ (match_operand:VSINT_842 1 "xxspltib_constant_nosplit" "wE"))]
+ "TARGET_P9_VECTOR"
{
- return rs6000_output_move_128bit (operands);
+ rtx op1 = operands[1];
+ int value = 256;
+ int num_insns = -1;
+
+ if (!xxspltib_constant_p (op1, <MODE>mode, &num_insns, &value)
+ || num_insns != 1)
+ gcc_unreachable ();
+
+ operands[2] = GEN_INT (value & 0xff);
+ return "xxspltib %x0,%2";
}
- [(set_attr "type" "vecstore,vecload,vecsimple,vecsimple,mffgpr,mftgpr,vecsimple,vecstore,vecload,store,load,store,load,*,*")
- (set_attr "length" "4,4,4,4,8,4,16,4,4,8,8,8,8,8,8")])
-
-(define_insn "*vsx_movti_32bit"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=Z,wa,wa,wa,v, v,wZ,Q,Y,????r,????r,????r,r")
- (match_operand:TI 1 "input_operand" "wa, Z,wa, O,W,wZ, v,r,r, Q, Y, r,n"))]
- "! TARGET_POWERPC64 && VECTOR_MEM_VSX_P (TImode)
- && (register_operand (operands[0], TImode)
- || register_operand (operands[1], TImode))"
+ [(set_attr "type" "vecperm")])
+
+(define_insn_and_split "*xxspltib_<mode>_split"
+ [(set (match_operand:VSINT_842 0 "altivec_register_operand" "=v")
+ (match_operand:VSINT_842 1 "xxspltib_constant_split" "wS"))]
+ "TARGET_P9_VECTOR"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- switch (which_alternative)
- {
- case 0:
- return "stxvd2x %x1,%y0";
+ int value = 256;
+ int num_insns = -1;
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx tmp = ((can_create_pseudo_p ())
+ ? gen_reg_rtx (V16QImode)
+ : gen_lowpart (V16QImode, op0));
- case 1:
- return "lxvd2x %x0,%y1";
+ if (!xxspltib_constant_p (op1, <MODE>mode, &num_insns, &value)
+ || num_insns != 2)
+ gcc_unreachable ();
- case 2:
- return "xxlor %x0,%x1,%x1";
+ emit_insn (gen_xxspltib_v16qi (tmp, GEN_INT (value)));
- case 3:
- return "xxlxor %x0,%x0,%x0";
+ if (<MODE>mode == V2DImode)
+ emit_insn (gen_vsx_sign_extend_qi_v2di (op0, tmp));
- case 4:
- return output_vec_const_move (operands);
+ else if (<MODE>mode == V4SImode)
+ emit_insn (gen_vsx_sign_extend_qi_v4si (op0, tmp));
- case 5:
- return "stvx %1,%y0";
+ else if (<MODE>mode == V8HImode)
+ emit_insn (gen_altivec_vupkhsb (op0, tmp));
- case 6:
- return "lvx %0,%y1";
+ else
+ gcc_unreachable ();
- case 7:
- if (TARGET_STRING)
- return \"stswi %1,%P0,16\";
+ DONE;
+}
+ [(set_attr "type" "vecperm")
+ (set_attr "length" "8")])
- case 8:
- return \"#\";
- case 9:
- /* If the address is not used in the output, we can use lsi. Otherwise,
- fall through to generating four loads. */
- if (TARGET_STRING
- && ! reg_overlap_mentioned_p (operands[0], operands[1]))
- return \"lswi %0,%P1,16\";
- /* ... fall through ... */
+;; Prefer using vector registers over GPRs. Prefer using ISA 3.0's XXSPLTISB
+;; or Altivec VSPLITW 0/-1 over XXLXOR/XXLORC to set a register to all 0's or
+;; all 1's, since the machine does not have to wait for the previous
+;; instruction using the register being set (such as a store waiting on a slow
+;; instruction). But generate XXLXOR/XXLORC if it will avoid a register move.
- case 10:
- case 11:
- case 12:
- return \"#\";
- default:
- gcc_unreachable ();
- }
+;; VSX store VSX load VSX move VSX->GPR GPR->VSX LQ (GPR)
+;; STQ (GPR) GPR load GPR store GPR move XXSPLTIB VSPLTISW
+;; VSX 0/-1 GPR 0/-1 VMX const GPR const LVX (VMX) STVX (VMX)
+(define_insn "*vsx_mov<mode>_64bit"
+ [(set (match_operand:VSX_M 0 "nonimmediate_operand"
+ "=ZwO, <VSa>, <VSa>, r, we, ?wQ,
+ ?&r, ??r, ??Y, ??r, wo, v,
+ ?<VSa>, *r, v, ??r, wZ, v")
+
+ (match_operand:VSX_M 1 "input_operand"
+ "<VSa>, ZwO, <VSa>, we, r, r,
+ wQ, Y, r, r, wE, jwM,
+ ?jwM, jwM, W, W, v, wZ"))]
+
+ "TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
+ && (register_operand (operands[0], <MODE>mode)
+ || register_operand (operands[1], <MODE>mode))"
+{
+ return rs6000_output_move_128bit (operands);
}
- [(set_attr "type" "vecstore,vecload,vecsimple,vecsimple,vecsimple,vecstore,vecload,store,store,load,load, *, *")
- (set_attr "update" " *, *, *, *, *, *, *, yes, yes, yes, yes, *, *")
- (set_attr "length" " 4, 4, 4, 4, 8, 4, 4, 16, 16, 16, 16,16,16")
- (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
- (const_string "always")
- (const_string "conditional")))])
+ [(set_attr "type"
+ "vecstore, vecload, vecsimple, mffgpr, mftgpr, load,
+ store, load, store, *, vecsimple, vecsimple,
+ vecsimple, *, *, *, vecstore, vecload")
+
+ (set_attr "length"
+ "4, 4, 4, 8, 4, 8,
+ 8, 8, 8, 8, 4, 4,
+ 4, 8, 20, 20, 4, 4")])
+
+;; VSX store VSX load VSX move GPR load GPR store GPR move
+;; XXSPLTIB VSPLTISW VSX 0/-1 GPR 0/-1 VMX const GPR const
+;; LVX (VMX) STVX (VMX)
+(define_insn "*vsx_mov<mode>_32bit"
+ [(set (match_operand:VSX_M 0 "nonimmediate_operand"
+ "=ZwO, <VSa>, <VSa>, ??r, ??Y, ??r,
+ wo, v, ?<VSa>, *r, v, ??r,
+ wZ, v")
+
+ (match_operand:VSX_M 1 "input_operand"
+ "<VSa>, ZwO, <VSa>, Y, r, r,
+ wE, jwM, ?jwM, jwM, W, W,
+ v, wZ"))]
+
+ "!TARGET_POWERPC64 && VECTOR_MEM_VSX_P (<MODE>mode)
+ && (register_operand (operands[0], <MODE>mode)
+ || register_operand (operands[1], <MODE>mode))"
+{
+ return rs6000_output_move_128bit (operands);
+}
+ [(set_attr "type"
+ "vecstore, vecload, vecsimple, load, store, *,
+ vecsimple, vecsimple, vecsimple, *, *, *,
+ vecstore, vecload")
+
+ (set_attr "length"
+ "4, 4, 4, 16, 16, 16,
+ 4, 4, 4, 16, 20, 32,
+ 4, 4")])
;; Explicit load/store expanders for the builtin functions
(define_expand "vsx_load_<mode>"
@@ -1717,10 +1742,15 @@
{
rtx op0 = operands[0];
rtx op1 = operands[1];
- rtx tmp = gen_reg_rtx (V2DFmode);
- int scale = INTVAL(operands[2]);
- if (scale != 0)
- rs6000_scale_v2df (tmp, op1, scale);
+ rtx tmp;
+ int scale = INTVAL (operands[2]);
+ if (scale == 0)
+ tmp = op1;
+ else
+ {
+ tmp = gen_reg_rtx (V2DFmode);
+ rs6000_scale_v2df (tmp, op1, scale);
+ }
emit_insn (gen_vsx_xvcvdpsxds (op0, tmp));
DONE;
})
@@ -1741,10 +1771,15 @@
{
rtx op0 = operands[0];
rtx op1 = operands[1];
- rtx tmp = gen_reg_rtx (V2DFmode);
- int scale = INTVAL(operands[2]);
- if (scale != 0)
- rs6000_scale_v2df (tmp, op1, scale);
+ rtx tmp;
+ int scale = INTVAL (operands[2]);
+ if (scale == 0)
+ tmp = op1;
+ else
+ {
+ tmp = gen_reg_rtx (V2DFmode);
+ rs6000_scale_v2df (tmp, op1, scale);
+ }
emit_insn (gen_vsx_xvcvdpuxds (op0, tmp));
DONE;
})
@@ -2362,7 +2397,52 @@
lxvdsx %x0,%y1"
[(set_attr "type" "vecperm,vecperm,vecload,vecperm,vecperm,vecload")])
-;; V4SF/V4SI splat
+;; V4SI splat (ISA 3.0)
+;; When SI's are allowed in VSX registers, add XXSPLTW support
+(define_expand "vsx_splat_<mode>"
+ [(set (match_operand:VSX_W 0 "vsx_register_operand" "")
+ (vec_duplicate:VSX_W
+ (match_operand:<VS_scalar> 1 "splat_input_operand" "")))]
+ "TARGET_P9_VECTOR"
+{
+ if (MEM_P (operands[1]))
+ operands[1] = rs6000_address_for_fpconvert (operands[1]);
+ else if (!REG_P (operands[1]))
+ operands[1] = force_reg (<VS_scalar>mode, operands[1]);
+})
+
+(define_insn "*vsx_splat_v4si_internal"
+ [(set (match_operand:V4SI 0 "vsx_register_operand" "=wa,wa")
+ (vec_duplicate:V4SI
+ (match_operand:SI 1 "reg_or_indexed_operand" "r,Z")))]
+ "TARGET_P9_VECTOR"
+ "@
+ mtvsrws %x0,%1
+ lxvwsx %x0,%y1"
+ [(set_attr "type" "mftgpr,vecload")])
+
+;; V4SF splat (ISA 3.0)
+(define_insn_and_split "*vsx_splat_v4sf_internal"
+ [(set (match_operand:V4SF 0 "vsx_register_operand" "=wa,wa,wa")
+ (vec_duplicate:V4SF
+ (match_operand:SF 1 "reg_or_indexed_operand" "Z,wy,r")))]
+ "TARGET_P9_VECTOR"
+ "@
+ lxvwsx %x0,%y1
+ #
+ mtvsrws %x0,%1"
+ "&& reload_completed && vsx_register_operand (operands[1], SFmode)"
+ [(set (match_dup 0)
+ (unspec:V4SF [(match_dup 1)] UNSPEC_VSX_CVDPSPN))
+ (set (match_dup 0)
+ (vec_duplicate:V4SF
+ (vec_select:SF (match_dup 0)
+ (parallel [(const_int 0)]))))]
+ ""
+ [(set_attr "type" "vecload,vecperm,mftgpr")
+ (set_attr "length" "4,8,4")])
+
+;; V4SF/V4SI splat from a vector element
(define_insn "vsx_xxspltw_<mode>"
[(set (match_operand:VSX_W 0 "vsx_register_operand" "=wf,?<VSa>")
(vec_duplicate:VSX_W
@@ -2605,21 +2685,50 @@
(define_peephole
[(set (match_operand:P 0 "base_reg_operand" "")
(match_operand:P 1 "short_cint_operand" ""))
- (set (match_operand:VSX_M2 2 "vsx_register_operand" "")
- (mem:VSX_M2 (plus:P (match_dup 0)
- (match_operand:P 3 "int_reg_operand" ""))))]
+ (set (match_operand:VSX_M 2 "vsx_register_operand" "")
+ (mem:VSX_M (plus:P (match_dup 0)
+ (match_operand:P 3 "int_reg_operand" ""))))]
"TARGET_VSX && TARGET_P8_FUSION && !TARGET_P9_VECTOR"
- "li %0,%1\t\t\t# vector load fusion\;lx<VSX_M2:VSm>x %x2,%0,%3"
+ "li %0,%1\t\t\t# vector load fusion\;lx<VSX_M:VSm>x %x2,%0,%3"
[(set_attr "length" "8")
(set_attr "type" "vecload")])
(define_peephole
[(set (match_operand:P 0 "base_reg_operand" "")
(match_operand:P 1 "short_cint_operand" ""))
- (set (match_operand:VSX_M2 2 "vsx_register_operand" "")
- (mem:VSX_M2 (plus:P (match_operand:P 3 "int_reg_operand" "")
- (match_dup 0))))]
+ (set (match_operand:VSX_M 2 "vsx_register_operand" "")
+ (mem:VSX_M (plus:P (match_operand:P 3 "int_reg_operand" "")
+ (match_dup 0))))]
"TARGET_VSX && TARGET_P8_FUSION && !TARGET_P9_VECTOR"
- "li %0,%1\t\t\t# vector load fusion\;lx<VSX_M2:VSm>x %x2,%0,%3"
+ "li %0,%1\t\t\t# vector load fusion\;lx<VSX_M:VSm>x %x2,%0,%3"
[(set_attr "length" "8")
(set_attr "type" "vecload")])
+
+
+;; ISA 3.0 vector extend sign support
+
+(define_insn "vsx_sign_extend_qi_<mode>"
+ [(set (match_operand:VSINT_84 0 "vsx_register_operand" "=v")
+ (unspec:VSINT_84
+ [(match_operand:V16QI 1 "vsx_register_operand" "v")]
+ UNSPEC_VSX_SIGN_EXTEND))]
+ "TARGET_P9_VECTOR"
+ "vextsb2<wd> %0,%1"
+ [(set_attr "type" "vecsimple")])
+
+(define_insn "*vsx_sign_extend_hi_<mode>"
+ [(set (match_operand:VSINT_84 0 "vsx_register_operand" "=v")
+ (unspec:VSINT_84
+ [(match_operand:V8HI 1 "vsx_register_operand" "v")]
+ UNSPEC_VSX_SIGN_EXTEND))]
+ "TARGET_P9_VECTOR"
+ "vextsh2<wd> %0,%1"
+ [(set_attr "type" "vecsimple")])
+
+(define_insn "*vsx_sign_extend_si_v2di"
+ [(set (match_operand:V2DI 0 "vsx_register_operand" "=v")
+ (unspec:V2DI [(match_operand:V4SI 1 "vsx_register_operand" "v")]
+ UNSPEC_VSX_SIGN_EXTEND))]
+ "TARGET_P9_VECTOR"
+ "vextsw2d %0,%1"
+ [(set_attr "type" "vecsimple")])
diff --git a/gcc/config/rx/rx-protos.h b/gcc/config/rx/rx-protos.h
index 160b9cce4aa..771528b3dd5 100644
--- a/gcc/config/rx/rx-protos.h
+++ b/gcc/config/rx/rx-protos.h
@@ -26,6 +26,28 @@ extern void rx_expand_epilogue (bool);
extern void rx_expand_prologue (void);
extern int rx_initial_elimination_offset (int, int);
+bool is_interrupt_func (const_tree decl);
+bool is_fast_interrupt_func (const_tree decl);
+
+/* rx_atomic_sequence is used to emit the header and footer
+ of an atomic sequence. It's supposed to be used in a scope.
+ When constructed, it will emit the atomic sequence header insns.
+ When destructred (goes out of scope), it will emit the
+ corresponding atomic sequence footer insns. */
+class rx_atomic_sequence
+{
+public:
+ rx_atomic_sequence (const_tree fun_decl);
+ ~rx_atomic_sequence (void);
+
+private:
+ rx_atomic_sequence (void);
+ rx_atomic_sequence (const rx_atomic_sequence&);
+ rx_atomic_sequence& operator = (const rx_atomic_sequence&);
+
+ rtx m_prev_psw_reg;
+};
+
#ifdef RTX_CODE
extern int rx_adjust_insn_length (rtx_insn *, int);
extern int rx_align_for_label (rtx, int);
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index 3a374a01c70..8dfc8856abe 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -630,15 +630,15 @@ rx_print_operand (FILE * file, rtx op, int letter)
gcc_assert (CONST_INT_P (op));
switch (INTVAL (op))
{
- case 0: fprintf (file, "psw"); break;
- case 2: fprintf (file, "usp"); break;
- case 3: fprintf (file, "fpsw"); break;
- case 4: fprintf (file, "cpen"); break;
- case 8: fprintf (file, "bpsw"); break;
- case 9: fprintf (file, "bpc"); break;
- case 0xa: fprintf (file, "isp"); break;
- case 0xb: fprintf (file, "fintv"); break;
- case 0xc: fprintf (file, "intb"); break;
+ case CTRLREG_PSW: fprintf (file, "psw"); break;
+ case CTRLREG_USP: fprintf (file, "usp"); break;
+ case CTRLREG_FPSW: fprintf (file, "fpsw"); break;
+ case CTRLREG_CPEN: fprintf (file, "cpen"); break;
+ case CTRLREG_BPSW: fprintf (file, "bpsw"); break;
+ case CTRLREG_BPC: fprintf (file, "bpc"); break;
+ case CTRLREG_ISP: fprintf (file, "isp"); break;
+ case CTRLREG_FINTV: fprintf (file, "fintv"); break;
+ case CTRLREG_INTB: fprintf (file, "intb"); break;
default:
warning (0, "unrecognized control register number: %d - using 'psw'",
(int) INTVAL (op));
@@ -1216,7 +1216,7 @@ has_func_attr (const_tree decl, const char * func_attr)
/* Returns true if the provided function has the "fast_interrupt" attribute. */
-static inline bool
+bool
is_fast_interrupt_func (const_tree decl)
{
return has_func_attr (decl, "fast_interrupt");
@@ -1224,7 +1224,7 @@ is_fast_interrupt_func (const_tree decl)
/* Returns true if the provided function has the "interrupt" attribute. */
-static inline bool
+bool
is_interrupt_func (const_tree decl)
{
return has_func_attr (decl, "interrupt");
@@ -3409,6 +3409,29 @@ rx_enable_lra (void)
return TARGET_ENABLE_LRA;
}
+rx_atomic_sequence::rx_atomic_sequence (const_tree fun_decl)
+{
+ if (is_fast_interrupt_func (fun_decl) || is_interrupt_func (fun_decl))
+ {
+ /* If we are inside an interrupt handler, assume that interrupts are
+ off -- which is the default hardware behavior. In this case, there
+ is no need to disable the interrupts. */
+ m_prev_psw_reg = NULL;
+ }
+ else
+ {
+ m_prev_psw_reg = gen_reg_rtx (SImode);
+ emit_insn (gen_mvfc (m_prev_psw_reg, GEN_INT (CTRLREG_PSW)));
+ emit_insn (gen_clrpsw (GEN_INT ('I')));
+ }
+}
+
+rx_atomic_sequence::~rx_atomic_sequence (void)
+{
+ if (m_prev_psw_reg != NULL)
+ emit_insn (gen_mvtc (GEN_INT (CTRLREG_PSW), m_prev_psw_reg));
+}
+
#undef TARGET_NARROW_VOLATILE_BITFIELD
#define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield
diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md
index 787c37bc967..9af16828b8c 100644
--- a/gcc/config/rx/rx.md
+++ b/gcc/config/rx/rx.md
@@ -75,6 +75,16 @@
(UNSPEC_BUILTIN_WAIT 51)
(UNSPEC_PID_ADDR 52)
+
+ (CTRLREG_PSW 0)
+ (CTRLREG_USP 2)
+ (CTRLREG_FPSW 3)
+ (CTRLREG_CPEN 4)
+ (CTRLREG_BPSW 8)
+ (CTRLREG_BPC 9)
+ (CTRLREG_ISP 10)
+ (CTRLREG_FINTV 11)
+ (CTRLREG_INTB 12)
]
)
@@ -2145,7 +2155,17 @@
FAIL;
})
-;; Atomic exchange operation.
+;; Atomic operations.
+
+(define_code_iterator FETCHOP [plus minus ior xor and])
+
+(define_code_attr fetchop_name
+ [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")])
+
+(define_code_attr fetchop_name2
+ [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")])
+
+(define_mode_iterator QIHI [QI HI])
(define_insn "sync_lock_test_and_setsi"
[(set (match_operand:SI 0 "register_operand" "=r,r")
@@ -2157,6 +2177,126 @@
[(set_attr "length" "3,6")
(set_attr "timings" "22")]
)
+
+(define_expand "atomic_exchange<mode>"
+ [(match_operand:QIHI 0 "register_operand") ;; oldval output
+ (match_operand:QIHI 1 "rx_restricted_mem_operand") ;; memory
+ (match_operand:QIHI 2 "register_operand") ;; newval input
+ (match_operand:QIHI 3 "const_int_operand")] ;; memory model
+ ""
+{
+ emit_insn (gen_xchg_mem<mode> (operands[0], operands[1], operands[2]));
+ DONE;
+})
+
+(define_expand "atomic_exchangesi"
+ [(match_operand:SI 0 "register_operand") ;; oldval output
+ (match_operand:SI 1 "rx_restricted_mem_operand") ;; memory
+ (match_operand:SI 2 "register_operand") ;; newval input
+ (match_operand:SI 3 "const_int_operand")] ;; memory model
+ ""
+{
+ emit_insn (gen_sync_lock_test_and_setsi (operands[0], operands[1],
+ operands[2]));
+ DONE;
+})
+
+(define_insn "xchg_mem<mode>"
+ [(set (match_operand:QIHI 0 "register_operand" "=r")
+ (match_operand:QIHI 1 "rx_compare_operand" "=Q"))
+ (set (match_dup 1)
+ (match_operand:QIHI 2 "register_operand" "0"))]
+ ""
+ "xchg\t%1, %0"
+ [(set_attr "length" "6")
+ (set_attr "timings" "22")]
+)
+
+;; read - modify - write - return old value
+(define_expand "atomic_fetch_<fetchop_name>si"
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "memory_operand"))
+ (set (match_dup 1)
+ (FETCHOP:SI (match_dup 1) (match_operand:SI 2 "rx_source_operand")))
+ (match_operand:SI 3 "const_int_operand")] ;; memory model
+ ""
+{
+ {
+ rx_atomic_sequence seq (current_function_decl);
+
+ emit_move_insn (operands[0], operands[1]);
+
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_<fetchop_name2>si3 (tmp, operands[0], operands[2]));
+
+ emit_move_insn (operands[1], tmp);
+ }
+ DONE;
+})
+
+(define_expand "atomic_fetch_nandsi"
+ [(set (match_operand:SI 0 "register_operand")
+ (match_operand:SI 1 "memory_operand"))
+ (set (match_dup 1)
+ (not:SI (and:SI (match_dup 1)
+ (match_operand:SI 2 "rx_source_operand"))))
+ (match_operand:SI 3 "const_int_operand")] ;; memory model
+ ""
+{
+ {
+ rx_atomic_sequence seq (current_function_decl);
+
+ emit_move_insn (operands[0], operands[1]);
+
+ rtx tmp = gen_reg_rtx (SImode);
+ emit_insn (gen_andsi3 (tmp, operands[0], operands[2]));
+ emit_insn (gen_one_cmplsi2 (tmp, tmp));
+
+ emit_move_insn (operands[1], tmp);
+ }
+ DONE;
+})
+
+;; read - modify - write - return new value
+(define_expand "atomic_<fetchop_name>_fetchsi"
+ [(set (match_operand:SI 0 "register_operand")
+ (FETCHOP:SI (match_operand:SI 1 "rx_restricted_mem_operand")
+ (match_operand:SI 2 "register_operand")))
+ (set (match_dup 1)
+ (FETCHOP:SI (match_dup 1) (match_dup 2)))
+ (match_operand:SI 3 "const_int_operand")] ;; memory model
+ ""
+{
+ {
+ rx_atomic_sequence seq (current_function_decl);
+
+ emit_move_insn (operands[0], operands[2]);
+ emit_insn (gen_<fetchop_name2>si3 (operands[0], operands[0], operands[1]));
+ emit_move_insn (operands[1], operands[0]);
+ }
+ DONE;
+})
+
+(define_expand "atomic_nand_fetchsi"
+ [(set (match_operand:SI 0 "register_operand")
+ (not:SI (and:SI (match_operand:SI 1 "rx_restricted_mem_operand")
+ (match_operand:SI 2 "register_operand"))))
+ (set (match_dup 1)
+ (not:SI (and:SI (match_dup 1) (match_dup 2))))
+ (match_operand:SI 3 "const_int_operand")] ;; memory model
+ ""
+{
+ {
+ rx_atomic_sequence seq (current_function_decl);
+
+ emit_move_insn (operands[0], operands[2]);
+ emit_insn (gen_andsi3 (operands[0], operands[0], operands[1]));
+ emit_insn (gen_one_cmplsi2 (operands[0], operands[0]));
+ emit_move_insn (operands[1], operands[0]);
+ }
+ DONE;
+});
+
;; Block move functions.
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 12a7f2a63c3..caf8ed558c3 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -1305,7 +1305,7 @@
(compare:VFCMP (match_operand:DF 0 "register_operand" "v")
(match_operand:DF 1 "register_operand" "v")))
(clobber (match_scratch:V2DI 2 "=v"))]
- "TARGET_Z13 && TARGET_HARD_FLOAT"
+ "TARGET_VX && TARGET_HARD_FLOAT"
"wfc<asm_fcmp>dbs\t%v2,%v0,%v1"
[(set_attr "op_type" "VRR")])
@@ -3989,7 +3989,7 @@
"r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%b3"
[(set_attr "op_type" "RIE")])
-(define_insn "*r<noxa>sbg_<mode>_srl"
+(define_insn "*r<noxa>sbg_<mode>_srl_bitmask"
[(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
(IXOR:GPR
(and:GPR
@@ -4005,7 +4005,7 @@
"r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,64-%3"
[(set_attr "op_type" "RIE")])
-(define_insn "*r<noxa>sbg_<mode>_sll"
+(define_insn "*r<noxa>sbg_<mode>_sll_bitmask"
[(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
(IXOR:GPR
(and:GPR
@@ -4021,6 +4021,36 @@
"r<noxa>sbg\t%0,%1,%<bfstart>2,%<bfend>2,%3"
[(set_attr "op_type" "RIE")])
+;; unsigned {int,long} a, b
+;; a = a | (b << const_int)
+;; a = a ^ (b << const_int)
+(define_insn "*r<noxa>sbg_<mode>_sll"
+ [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
+ (IXOR:GPR
+ (ashift:GPR
+ (match_operand:GPR 1 "nonimmediate_operand" "d")
+ (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
+ (match_operand:GPR 3 "nonimmediate_operand" "0")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_Z10"
+ "r<noxa>sbg\t%0,%1,64-<bitsize>,63-%2,%2"
+ [(set_attr "op_type" "RIE")])
+
+;; unsigned {int,long} a, b
+;; a = a | (b >> const_int)
+;; a = a ^ (b >> const_int)
+(define_insn "*r<noxa>sbg_<mode>_srl"
+ [(set (match_operand:GPR 0 "nonimmediate_operand" "=d")
+ (IXOR:GPR
+ (lshiftrt:GPR
+ (match_operand:GPR 1 "nonimmediate_operand" "d")
+ (match_operand:GPR 2 "nonzero_shift_count_operand" ""))
+ (match_operand:GPR 3 "nonimmediate_operand" "0")))
+ (clobber (reg:CC CC_REGNUM))]
+ "TARGET_Z10"
+ "r<noxa>sbg\t%0,%1,64-<bitsize>+%2,63,64-%2"
+ [(set_attr "op_type" "RIE")])
+
;; These two are generated by combine for s.bf &= val.
;; ??? For bitfields smaller than 32-bits, we wind up with SImode
;; shifts and ands, which results in some truly awful patterns
@@ -4673,7 +4703,7 @@
(unsigned_fix:DI (match_operand:DF 1 "register_operand" "f,v")))
(unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
(clobber (reg:CC CC_REGNUM))]
- "TARGET_Z13 && TARGET_HARD_FLOAT"
+ "TARGET_VX && TARGET_HARD_FLOAT"
"@
clgdbr\t%0,%h2,%1,0
wclgdb\t%v0,%v1,0,%h2"
@@ -4688,7 +4718,7 @@
(unspec:GPR [(match_operand:GPR 2 "immediate_operand" "K")] UNSPEC_ROUND)
(clobber (reg:CC CC_REGNUM))]
"TARGET_Z196 && TARGET_HARD_FLOAT
- && (!TARGET_Z13 || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
+ && (!TARGET_VX || <GPR:MODE>mode != DImode || <FP:MODE>mode != DFmode)"
"cl<GPR:gf><FP:xde><FP:bt>r\t%0,%h2,%1,0"
[(set_attr "op_type" "RRF")
(set_attr "type" "ftoi")])
@@ -4708,7 +4738,7 @@
(fix:DI (match_operand:DF 1 "register_operand" "f,v")))
(unspec:DI [(match_operand:DI 2 "immediate_operand" "K,K")] UNSPEC_ROUND)
(clobber (reg:CC CC_REGNUM))]
- "TARGET_Z13 && TARGET_HARD_FLOAT"
+ "TARGET_VX && TARGET_HARD_FLOAT"
"@
cgdbr\t%0,%h2,%1
wcgdb\t%v0,%v1,0,%h2"
@@ -4816,7 +4846,7 @@
(define_insn "*floatunsdidf2_z13"
[(set (match_operand:DF 0 "register_operand" "=f,v")
(unsigned_float:DF (match_operand:DI 1 "register_operand" "d,v")))]
- "TARGET_Z13 && TARGET_HARD_FLOAT"
+ "TARGET_VX && TARGET_HARD_FLOAT"
"@
cdlgbr\t%0,0,%1,0
wcdlgb\t%v0,%v1,0,0"
@@ -4920,7 +4950,7 @@
(define_insn "*extendsfdf2_z13"
[(set (match_operand:DF 0 "register_operand" "=f,f,v")
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f,R,v")))]
- "TARGET_Z13 && TARGET_HARD_FLOAT"
+ "TARGET_VX && TARGET_HARD_FLOAT"
"@
ldebr\t%0,%1
ldeb\t%0,%1
diff --git a/gcc/config/sh/predicates.md b/gcc/config/sh/predicates.md
index 3e69d88f64b..4de90af9abb 100644
--- a/gcc/config/sh/predicates.md
+++ b/gcc/config/sh/predicates.md
@@ -230,6 +230,24 @@
(match_test "sh_disp_addr_displacement (op)
<= sh_max_mov_insn_displacement (GET_MODE (op), false)")))
+;; Returns true if OP is a displacement address that does not fit into
+;; a 16 bit (non-SH2A) memory load / store insn.
+(define_predicate "long_displacement_mem_operand"
+ (and (match_operand 0 "displacement_mem_operand")
+ (not (match_operand 0 "short_displacement_mem_operand"))))
+
+;; Returns true if OP is a post-increment addressing mode memory reference.
+(define_predicate "post_inc_mem"
+ (and (match_code "mem")
+ (match_code "post_inc" "0")
+ (match_code "reg" "00")))
+
+;; Returns true if OP is a pre-decrement addressing mode memory reference.
+(define_predicate "pre_dec_mem"
+ (and (match_code "mem")
+ (match_code "pre_dec" "0")
+ (match_code "reg" "00")))
+
;; Returns 1 if the operand can be used in an SH2A movu.{b|w} insn.
(define_predicate "zero_extend_movu_operand"
(and (ior (match_operand 0 "displacement_mem_operand")
diff --git a/gcc/config/sh/sh-protos.h b/gcc/config/sh/sh-protos.h
index ea7e847300d..fecbb886d0f 100644
--- a/gcc/config/sh/sh-protos.h
+++ b/gcc/config/sh/sh-protos.h
@@ -224,8 +224,12 @@ sh_find_set_of_reg (rtx reg, rtx_insn* insn, F stepfunc,
}
}
- if (result.set_src != NULL)
- gcc_assert (result.insn != NULL && result.set_rtx != NULL);
+ /* If the searched reg is found inside a (mem (post_inc:SI (reg))), set_of
+ will return NULL and set_rtx will be NULL.
+ In this case report a 'not found'. result.insn will always be non-null
+ at this point, so no need to check it. */
+ if (result.set_src != NULL && result.set_rtx == NULL)
+ result.set_src = NULL;
return result;
}
@@ -344,13 +348,24 @@ private:
extern sh_treg_insns sh_split_treg_set_expr (rtx x, rtx_insn* curr_insn);
+enum
+{
+ /* An effective conditional branch distance of zero bytes is impossible.
+ Hence we can use it to designate an unknown value. */
+ unknown_cbranch_distance = 0u,
+ infinite_cbranch_distance = ~0u
+};
+
+unsigned int
+sh_cbranch_distance (rtx_insn* cbranch_insn,
+ unsigned int max_dist = infinite_cbranch_distance);
+
#endif /* RTX_CODE */
extern void sh_cpu_cpp_builtins (cpp_reader* pfile);
extern const char *output_jump_label_table (void);
extern rtx get_t_reg_rtx (void);
-extern int sh_media_register_for_return (void);
extern void sh_expand_prologue (void);
extern void sh_expand_epilogue (bool);
extern void sh_set_return_address (rtx, rtx);
diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c
index ebdb523cd17..a36b098cf40 100644
--- a/gcc/config/sh/sh.c
+++ b/gcc/config/sh/sh.c
@@ -80,8 +80,9 @@ int code_for_indirect_jump_scratch = CODE_FOR_indirect_jump_scratch;
? (DECL_ATTRIBUTES (decl)) \
: TYPE_ATTRIBUTES (TREE_TYPE (decl))
-/* Set to 1 by expand_prologue() when the function is an interrupt handler. */
-int current_function_interrupt;
+/* Set to true by expand_prologue() when the function is an
+ interrupt handler. */
+bool current_function_interrupt;
tree sh_deferred_function_attributes;
tree *sh_deferred_function_attributes_tail = &sh_deferred_function_attributes;
@@ -180,10 +181,10 @@ static void sh_reorg (void);
static void sh_option_override (void);
static void sh_override_options_after_change (void);
static void output_stack_adjust (int, rtx, int, HARD_REG_SET *, bool);
-static rtx_insn *frame_insn (rtx);
+static rtx_insn* emit_frame_insn (rtx);
static rtx push (int);
static void pop (int);
-static void push_regs (HARD_REG_SET *, int);
+static void push_regs (HARD_REG_SET* mask, bool interrupt_handler);
static int calc_live_regs (HARD_REG_SET *);
static HOST_WIDE_INT rounded_frame_size (int);
static bool sh_frame_pointer_required (void);
@@ -267,7 +268,6 @@ static rtx sh_delegitimize_address (rtx);
static bool sh_cannot_substitute_mem_equiv_p (rtx);
static bool sh_legitimize_address_displacement (rtx *, rtx *, machine_mode);
static int scavenge_reg (HARD_REG_SET *s);
-struct save_schedule_s;
static rtx sh_struct_value_rtx (tree, int);
static rtx sh_function_value (const_tree, const_tree, bool);
@@ -355,12 +355,6 @@ static const struct attribute_spec sh_attribute_table[] =
#undef TARGET_ASM_UNALIGNED_SI_OP
#define TARGET_ASM_UNALIGNED_SI_OP "\t.ualong\t"
-/* These are NULLed out on non-SH5 in TARGET_OPTION_OVERRIDE. */
-#undef TARGET_ASM_UNALIGNED_DI_OP
-#define TARGET_ASM_UNALIGNED_DI_OP "\t.uaquad\t"
-#undef TARGET_ASM_ALIGNED_DI_OP
-#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
-
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE sh_option_override
@@ -832,10 +826,6 @@ sh_option_override (void)
sh_cpu = PROCESSOR_SH4A;
}
- /* Only the sh64-elf assembler fully supports .quad properly. */
- targetm.asm_out.aligned_op.di = NULL;
- targetm.asm_out.unaligned_op.di = NULL;
-
/* User/priviledged mode is supported only on SH3* and SH4*.
Disable it for everything else. */
if (!TARGET_SH3 && TARGET_USERMODE)
@@ -1662,11 +1652,9 @@ prepare_move_operands (rtx operands[], machine_mode mode)
if (mode == Pmode || mode == ptr_mode)
{
- rtx op0, op1, opc;
- enum tls_model tls_kind;
-
- op0 = operands[0];
- op1 = operands[1];
+ rtx op0 = operands[0];
+ rtx op1 = operands[1];
+ rtx opc;
if (GET_CODE (op1) == CONST
&& GET_CODE (XEXP (op1, 0)) == PLUS
&& (tls_symbolic_operand (XEXP (XEXP (op1, 0), 0), Pmode)
@@ -1678,6 +1666,8 @@ prepare_move_operands (rtx operands[], machine_mode mode)
else
opc = NULL_RTX;
+ enum tls_model tls_kind;
+
if (! reload_in_progress && ! reload_completed
&& (tls_kind = tls_symbolic_operand (op1, Pmode)) != TLS_MODEL_NONE)
{
@@ -1698,7 +1688,7 @@ prepare_move_operands (rtx operands[], machine_mode mode)
emit_use (gen_rtx_REG (SImode, PIC_REG));
if (flag_schedule_insns)
emit_insn (gen_blockage ());
- }
+ }
switch (tls_kind)
{
@@ -1928,6 +1918,52 @@ sh_fixed_condition_code_regs (unsigned int* p1, unsigned int* p2)
return true;
}
+/* Try to calculate the branch distance of a conditional branch in bytes.
+
+ FIXME: Because of PR 59189 we can't use the CFG here. Instead just
+ walk from this insn into the next (fall-through) basic block and see if
+ we hit the label. */
+unsigned int
+sh_cbranch_distance (rtx_insn* _cbranch_insn, unsigned int max_dist)
+{
+ rtx_jump_insn* cbranch_insn = safe_as_a<rtx_jump_insn*> (_cbranch_insn);
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "sh_cbranch_distance insn = \n");
+ print_rtl_single (dump_file, cbranch_insn);
+ }
+
+ unsigned int dist = 0;
+
+ for (rtx_insn* i = next_nonnote_insn (cbranch_insn);
+ i != NULL && dist < max_dist; i = next_nonnote_insn (i))
+ {
+ const unsigned int i_len = get_attr_length (i);
+ dist += i_len;
+
+ if (dump_file)
+ fprintf (dump_file, " insn %d length = %u dist = %u\n",
+ INSN_UID (i), i_len, dist);
+
+ if (rtx_code_label* l = dyn_cast<rtx_code_label*> (i))
+ {
+ if (l == cbranch_insn->jump_target ())
+ {
+ if (dump_file)
+ fprintf (dump_file, " cbranch dist = %u\n", dist);
+ return dist;
+ }
+ break;
+ }
+ }
+
+ if (dump_file)
+ fprintf (dump_file, " cbranch dist = unknown\n");
+
+ return unknown_cbranch_distance;
+}
+
enum rtx_code
prepare_cbranch_operands (rtx *operands, machine_mode mode,
enum rtx_code comparison)
@@ -2210,7 +2246,6 @@ sh_emit_scc_to_t (enum rtx_code code, rtx op0, rtx op1)
{
rtx t_reg = get_t_reg_rtx ();
enum rtx_code oldcode = code;
- machine_mode mode;
/* First need a compare insn. */
switch (code)
@@ -2236,7 +2271,7 @@ sh_emit_scc_to_t (enum rtx_code code, rtx op0, rtx op1)
if (code != oldcode)
std::swap (op0, op1);
- mode = GET_MODE (op0);
+ machine_mode mode = GET_MODE (op0);
if (mode == VOIDmode)
mode = GET_MODE (op1);
@@ -2779,14 +2814,13 @@ static bool
unspec_caller_rtx_p (rtx pat)
{
rtx base, offset;
- int i;
-
split_const (pat, &base, &offset);
+
if (GET_CODE (base) == UNSPEC)
{
if (XINT (base, 1) == UNSPEC_CALLER)
return true;
- for (i = 0; i < XVECLEN (base, 0); i++)
+ for (int i = 0; i < XVECLEN (base, 0); i++)
if (unspec_caller_rtx_p (XVECEXP (base, 0, i)))
return true;
}
@@ -2798,8 +2832,6 @@ unspec_caller_rtx_p (rtx pat)
static bool
sh_cannot_copy_insn_p (rtx_insn *insn)
{
- rtx pat;
-
if (!reload_completed || !flag_pic)
return false;
@@ -2808,7 +2840,7 @@ sh_cannot_copy_insn_p (rtx_insn *insn)
if (asm_noperands (insn) >= 0)
return false;
- pat = PATTERN (insn);
+ rtx pat = PATTERN (insn);
if (GET_CODE (pat) == CLOBBER || GET_CODE (pat) == USE)
return false;
@@ -3209,6 +3241,15 @@ sh_rtx_costs (rtx x, machine_mode mode ATTRIBUTE_UNUSED, int outer_code,
*total = 1; //COSTS_N_INSNS (1);
return true;
}
+
+ /* div0s variant. */
+ if (GET_CODE (XEXP (x, 0)) == XOR
+ && GET_CODE (XEXP (XEXP (x, 0), 0)) == XOR
+ && CONST_INT_P (XEXP (XEXP (x, 0), 1)))
+ {
+ *total = 1;
+ return true;
+ }
return false;
/* The cost of a sign or zero extend depends on whether the source is a
@@ -4424,12 +4465,11 @@ static int max_labelno_before_reorg;
static rtx_code_label *
add_constant (rtx x, machine_mode mode, rtx last_value)
{
- int i;
rtx_code_label *lab, *new_rtx;
label_ref_list_t ref, newref;
/* First see if we've already got it. */
- for (i = 0; i < pool_size; i++)
+ for (int i = 0; i < pool_size; i++)
{
if (x->code == pool_vector[i].value->code
&& mode == pool_vector[i].mode)
@@ -4503,7 +4543,6 @@ static void
dump_table (rtx_insn *start, rtx_insn *barrier)
{
rtx_insn *scan = barrier;
- int i;
bool need_align = true;
rtx lab;
label_ref_list_t ref;
@@ -4511,7 +4550,7 @@ dump_table (rtx_insn *start, rtx_insn *barrier)
/* Do two passes, first time dump out the HI sized constants. */
- for (i = 0; i < pool_size; i++)
+ for (int i = 0; i < pool_size; i++)
{
pool_node *p = &pool_vector[i];
@@ -4560,7 +4599,7 @@ dump_table (rtx_insn *start, rtx_insn *barrier)
scan = emit_insn_after (gen_align_log (GEN_INT (3)), scan);
need_align = false;
- for (i = 0; i < pool_size; i++)
+ for (int i = 0; i < pool_size; i++)
{
pool_node *p = &pool_vector[i];
@@ -4626,7 +4665,7 @@ dump_table (rtx_insn *start, rtx_insn *barrier)
pool_size = 0;
}
- for (i = 0; i < pool_size; i++)
+ for (int i = 0; i < pool_size; i++)
{
pool_node *p = &pool_vector[i];
@@ -5195,7 +5234,7 @@ sfunc_uses_reg (rtx_insn *insn)
if (! reg_part)
return NULL_RTX;
reg = XEXP (reg_part, 0);
- for (i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
+ for (int i = XVECLEN (pattern, 0) - 1; i >= 0; i--)
{
part = XVECEXP (pattern, 0, i);
if (part == reg_part || GET_CODE (part) == CLOBBER)
@@ -5214,14 +5253,12 @@ sfunc_uses_reg (rtx_insn *insn)
static bool
noncall_uses_reg (rtx reg, rtx_insn *insn, rtx *set)
{
- rtx pattern, reg2;
-
*set = NULL_RTX;
- reg2 = sfunc_uses_reg (insn);
+ rtx reg2 = sfunc_uses_reg (insn);
if (reg2 && REGNO (reg2) == REGNO (reg))
{
- pattern = single_set (insn);
+ rtx pattern = single_set (insn);
if (pattern
&& REG_P (SET_DEST (pattern))
&& REGNO (reg) == REGNO (SET_DEST (pattern)))
@@ -5232,7 +5269,7 @@ noncall_uses_reg (rtx reg, rtx_insn *insn, rtx *set)
{
/* We don't use rtx_equal_p because we don't care if the mode is
different. */
- pattern = single_set (insn);
+ rtx pattern = single_set (insn);
if (pattern
&& REG_P (SET_DEST (pattern))
&& REGNO (reg) == REGNO (SET_DEST (pattern)))
@@ -5255,13 +5292,11 @@ noncall_uses_reg (rtx reg, rtx_insn *insn, rtx *set)
return true;
}
- pattern = PATTERN (insn);
+ rtx pattern = PATTERN (insn);
if (GET_CODE (pattern) == PARALLEL)
{
- int i;
-
- for (i = XVECLEN (pattern, 0) - 1; i >= 1; i--)
+ for (int i = XVECLEN (pattern, 0) - 1; i >= 1; i--)
if (reg_mentioned_p (reg, XVECEXP (pattern, 0, i)))
return true;
pattern = XVECEXP (pattern, 0, 0);
@@ -5301,7 +5336,7 @@ regs_used (rtx x, int is_dest)
{
enum rtx_code code;
const char *fmt;
- int i, used = 0;
+ int used = 0;
if (! x)
return used;
@@ -5348,12 +5383,11 @@ regs_used (rtx x, int is_dest)
fmt = GET_RTX_FORMAT (code);
- for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
+ for (int i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'E')
{
- int j;
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
used |= regs_used (XVECEXP (x, i, j), is_dest);
}
else if (fmt[i] == 'e')
@@ -5376,7 +5410,6 @@ gen_block_redirect (rtx_insn *jump, int addr, int need_block)
{
int dead = 0;
rtx_insn *prev = prev_nonnote_insn (jump);
- rtx dest;
/* First, check if we already have an instruction that satisfies our need. */
if (prev && NONJUMP_INSN_P (prev) && ! prev->deleted ())
@@ -5402,7 +5435,7 @@ gen_block_redirect (rtx_insn *jump, int addr, int need_block)
}
/* We can't use JUMP_LABEL here because it might be undefined
when not optimizing. */
- dest = XEXP (SET_SRC (PATTERN (jump)), 0);
+ rtx dest = XEXP (SET_SRC (PATTERN (jump)), 0);
/* If the branch is out of range, try to find a scratch register for it. */
if (optimize
&& (INSN_ADDRESSES (INSN_UID (dest)) - addr + (unsigned) 4092
@@ -5420,11 +5453,9 @@ gen_block_redirect (rtx_insn *jump, int addr, int need_block)
for (scan = jump; (scan = PREV_INSN (scan)); )
{
- enum rtx_code code;
-
if (scan->deleted ())
continue;
- code = GET_CODE (scan);
+ rtx_code code = GET_CODE (scan);
if (code == CODE_LABEL || code == JUMP_INSN)
break;
if (code == INSN
@@ -5439,11 +5470,9 @@ gen_block_redirect (rtx_insn *jump, int addr, int need_block)
for (used = dead = 0, scan = JUMP_LABEL_AS_INSN (jump);
(scan = NEXT_INSN (scan)); )
{
- enum rtx_code code;
-
if (scan->deleted ())
continue;
- code = GET_CODE (scan);
+ rtx_code code = GET_CODE (scan);
if (INSN_P (scan))
{
used |= regs_used (PATTERN (scan), 0);
@@ -5539,15 +5568,14 @@ struct far_branch
int address;
};
-static void gen_far_branch (struct far_branch *);
enum mdep_reorg_phase_e mdep_reorg_phase;
+
static void
gen_far_branch (struct far_branch *bp)
{
rtx_insn *insn = bp->insert_place;
rtx_jump_insn *jump;
rtx_code_label *label = gen_label_rtx ();
- int ok;
emit_label_after (label, insn);
if (bp->far_label)
@@ -5576,7 +5604,7 @@ gen_far_branch (struct far_branch *bp)
JUMP_LABEL (jump) = pat;
}
- ok = invert_jump (as_a <rtx_jump_insn *> (insn), label, 1);
+ bool ok = invert_jump (as_a <rtx_jump_insn *> (insn), label, 1);
gcc_assert (ok);
/* If we are branching around a jump (rather than a return), prevent
@@ -5646,8 +5674,6 @@ fixup_addr_diff_vecs (rtx_insn *first)
int
barrier_align (rtx_insn *barrier_or_label)
{
- rtx next, pat;
-
if (! barrier_or_label)
return 0;
@@ -5660,7 +5686,7 @@ barrier_align (rtx_insn *barrier_or_label)
&& PREV_INSN (barrier_or_label)
&& JUMP_TABLE_DATA_P (PREV_INSN (barrier_or_label)))
{
- pat = PATTERN (PREV_INSN (barrier_or_label));
+ rtx pat = PATTERN (PREV_INSN (barrier_or_label));
/* If this is a very small table, we want to keep the alignment after
the table to the minimum for proper code alignment. */
return ((optimize_size
@@ -5669,12 +5695,12 @@ barrier_align (rtx_insn *barrier_or_label)
? 1 : align_jumps_log);
}
- next = next_active_insn (barrier_or_label);
+ rtx next = next_active_insn (barrier_or_label);
if (! next)
return 0;
- pat = PATTERN (next);
+ rtx pat = PATTERN (next);
if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_ALIGN)
/* This is a barrier in front of a constant table. */
@@ -6242,11 +6268,11 @@ int
get_dest_uid (rtx label, int max_uid)
{
rtx_insn *dest = next_real_insn (label);
- int dest_uid;
+
if (! dest)
/* This can happen for an undefined label. */
return 0;
- dest_uid = INSN_UID (dest);
+ int dest_uid = INSN_UID (dest);
/* If this is a newly created branch redirection blocking instruction,
we cannot index the branch_uid or insn_addresses arrays with its
uid. But then, we won't need to, because the actual destination is
@@ -6505,14 +6531,9 @@ final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
if (TARGET_RELAX)
{
- rtx note;
-
- note = find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX);
- if (note)
+ if (rtx note = find_reg_note (insn, REG_LABEL_OPERAND, NULL_RTX))
{
- rtx pattern;
-
- pattern = PATTERN (insn);
+ rtx pattern = PATTERN (insn);
if (GET_CODE (pattern) == PARALLEL)
pattern = XVECEXP (pattern, 0, 0);
switch (GET_CODE (pattern))
@@ -6543,12 +6564,10 @@ final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
const char *
output_jump_label_table (void)
{
- int i;
-
if (pool_size)
{
fprintf (asm_out_file, "\t.align 2\n");
- for (i = 0; i < pool_size; i++)
+ for (int i = 0; i < pool_size; i++)
{
pool_node *p = &pool_vector[i];
@@ -6593,7 +6612,7 @@ static void
output_stack_adjust (int size, rtx reg, int epilogue_p,
HARD_REG_SET *live_regs_mask, bool frame_p)
{
- rtx_insn *(*emit_fn) (rtx) = frame_p ? &frame_insn : &emit_insn;
+ rtx_insn *(*emit_fn) (rtx) = frame_p ? &emit_frame_insn : &emit_insn;
if (size)
{
HOST_WIDE_INT align = STACK_BOUNDARY / BITS_PER_UNIT;
@@ -6743,10 +6762,9 @@ output_stack_adjust (int size, rtx reg, int epilogue_p,
}
}
-/* Emit the specified insn and mark it as frame related.
- FIXME: Rename this to emit_frame_insn. */
+/* Emit the specified insn and mark it as frame related. */
static rtx_insn *
-frame_insn (rtx x)
+emit_frame_insn (rtx x)
{
rtx_insn *insn = emit_insn (x);
RTX_FRAME_RELATED_P (insn) = 1;
@@ -6774,7 +6792,7 @@ push (int rn)
else
x = gen_push (gen_rtx_REG (SImode, rn));
- x = frame_insn (x);
+ x = emit_frame_insn (x);
add_reg_note (x, REG_INC, gen_rtx_REG (SImode, STACK_POINTER_REGNUM));
return x;
}
@@ -6817,15 +6835,15 @@ pop (int rn)
/* Generate code to push the regs specified in the mask. */
static void
-push_regs (HARD_REG_SET *mask, int interrupt_handler)
+push_regs (HARD_REG_SET *mask, bool interrupt_handler)
{
- int i = interrupt_handler ? LAST_BANKED_REG + 1 : 0;
- int skip_fpscr = 0;
+ bool skip_fpscr = false;
/* Push PR last; this gives better latencies after the prologue, and
candidates for the return delay slot when there are no general
registers pushed. */
- for (; i < FIRST_PSEUDO_REGISTER; i++)
+ for (int i = interrupt_handler ? LAST_BANKED_REG + 1 : 0;
+ i < FIRST_PSEUDO_REGISTER; i++)
{
/* If this is an interrupt handler, and the SZ bit varies,
and we have to push any floating point register, we need
@@ -6838,7 +6856,7 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler)
push (FPSCR_REG);
COMPL_HARD_REG_SET (unsaved, *mask);
fpscr_set_from_mem (NORMAL_MODE (FP_MODE), unsaved);
- skip_fpscr = 1;
+ skip_fpscr = true;
}
if (i != PR_REG
&& (i != FPSCR_REG || ! skip_fpscr)
@@ -6864,7 +6882,7 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler)
{
unsigned int count = 0;
- for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
+ for (int i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
if (TEST_HARD_REG_BIT (*mask, i))
count++;
else
@@ -6886,8 +6904,8 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler)
insns. */
emit_insn (gen_blockage ());
x = gen_movml_push_banked (sp_reg);
- x = frame_insn (x);
- for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
+ x = emit_frame_insn (x);
+ for (int i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
{
mem = gen_rtx_MEM (SImode, plus_constant (Pmode, sp_reg, i * 4));
reg = gen_rtx_REG (SImode, i);
@@ -6899,7 +6917,7 @@ push_regs (HARD_REG_SET *mask, int interrupt_handler)
emit_insn (gen_blockage ());
}
else
- for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
+ for (int i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
if (TEST_HARD_REG_BIT (*mask, i))
push (i);
}
@@ -6919,11 +6937,9 @@ static int
calc_live_regs (HARD_REG_SET *live_regs_mask)
{
unsigned int reg;
- int count;
tree attrs;
bool interrupt_or_trapa_handler, trapa_handler, interrupt_handler;
bool nosave_low_regs;
- int pr_live, has_call;
attrs = DECL_ATTRIBUTES (current_function_decl);
interrupt_or_trapa_handler = sh_cfun_interrupt_handler_p ();
@@ -6937,7 +6953,7 @@ calc_live_regs (HARD_REG_SET *live_regs_mask)
target_flags &= ~MASK_FPU_SINGLE;
/* If we can save a lot of saves by switching to double mode, do that. */
else if (TARGET_FPU_DOUBLE && TARGET_FMOVD && TARGET_FPU_SINGLE)
- for (count = 0, reg = FIRST_FP_REG; reg <= LAST_FP_REG; reg += 2)
+ for (int count = 0, reg = FIRST_FP_REG; reg <= LAST_FP_REG; reg += 2)
if (df_regs_ever_live_p (reg) && df_regs_ever_live_p (reg+1)
&& (! call_really_used_regs[reg]
|| interrupt_handler)
@@ -6947,20 +6963,22 @@ calc_live_regs (HARD_REG_SET *live_regs_mask)
break;
}
- {
- rtx pr_initial = has_hard_reg_initial_val (Pmode, PR_REG);
- pr_live = (pr_initial
+
+ rtx pr_initial = has_hard_reg_initial_val (Pmode, PR_REG);
+ bool pr_live = (pr_initial
? (!REG_P (pr_initial)
|| REGNO (pr_initial) != (PR_REG))
: df_regs_ever_live_p (PR_REG));
- /* For Shcompact, if not optimizing, we end up with a memory reference
- using the return address pointer for __builtin_return_address even
- though there is no actual need to put the PR register on the stack. */
- pr_live |= df_regs_ever_live_p (RETURN_ADDRESS_POINTER_REGNUM);
- }
+ /* For Shcompact, if not optimizing, we end up with a memory reference
+ using the return address pointer for __builtin_return_address even
+ though there is no actual need to put the PR register on the stack. */
+ pr_live |= df_regs_ever_live_p (RETURN_ADDRESS_POINTER_REGNUM);
+
/* Force PR to be live if the prologue has to call the SHmedia
argument decoder or register saver. */
- has_call = pr_live;
+ bool has_call = pr_live;
+
+ int count;
for (count = 0, reg = FIRST_PSEUDO_REGISTER; reg-- != 0; )
{
if (reg == PR_REG
@@ -7064,68 +7082,11 @@ rounded_frame_size (int pushed)
return ((size + pushed + align - 1) & -align) - pushed;
}
-/* Choose a call-clobbered target-branch register that remains
- unchanged along the whole function. We set it up as the return
- value in the prologue. */
-int
-sh_media_register_for_return (void)
-{
- int regno;
- int tr0_used;
-
- if (! crtl->is_leaf)
- return -1;
- if (lookup_attribute ("interrupt_handler",
- DECL_ATTRIBUTES (current_function_decl)))
- return -1;
- if (sh_cfun_interrupt_handler_p ())
- return -1;
-
- tr0_used = flag_pic && df_regs_ever_live_p (PIC_OFFSET_TABLE_REGNUM);
-
- for (regno = FIRST_TARGET_REG + tr0_used; regno <= LAST_TARGET_REG; regno++)
- if (call_really_used_regs[regno] && ! df_regs_ever_live_p (regno))
- return regno;
-
- return -1;
-}
-
-/* The maximum registers we need to save are:
- - 62 general purpose registers (r15 is stack pointer, r63 is zero)
- - 32 floating point registers (for each pair, we save none,
- one single precision value, or a double precision value).
- - 8 target registers
- - add 1 entry for a delimiter. */
-#define MAX_SAVED_REGS (62+32+8)
-
-typedef struct save_entry_s
-{
- unsigned char reg;
- unsigned char mode;
- short offset;
-} save_entry;
-
-#define MAX_TEMPS 4
-
-/* There will be a delimiter entry with VOIDmode both at the start and the
- end of a filled in schedule. The end delimiter has the offset of the
- save with the smallest (i.e. most negative) offset. */
-typedef struct save_schedule_s
-{
- save_entry entries[MAX_SAVED_REGS + 2];
- int temps[MAX_TEMPS+1];
-} save_schedule;
-
/* Expand code for the function prologue. */
void
sh_expand_prologue (void)
{
- HARD_REG_SET live_regs_mask;
- int d, i;
- int d_rounding = 0;
int save_flags = target_flags;
- int pretend_args;
- int stack_usage;
tree sp_switch_attr
= lookup_attribute ("sp_switch", DECL_ATTRIBUTES (current_function_decl));
@@ -7133,16 +7094,14 @@ sh_expand_prologue (void)
/* We have pretend args if we had an object sent partially in registers
and partially on the stack, e.g. a large structure. */
- pretend_args = crtl->args.pretend_args_size;
+ int pretend_args = crtl->args.pretend_args_size;
if (TARGET_VARARGS_PRETEND_ARGS (current_function_decl)
&& (NPARM_REGS(SImode)
> crtl->args.info.arg_count[(int) SH_ARG_INT]))
pretend_args = 0;
- output_stack_adjust (-pretend_args
- - crtl->args.info.stack_regs * 8,
- stack_pointer_rtx, 0, NULL, true);
- stack_usage = pretend_args + crtl->args.info.stack_regs * 8;
+ output_stack_adjust (-pretend_args, stack_pointer_rtx, 0, NULL, true);
+ int stack_usage = pretend_args;
/* Emit the code for SETUP_VARARGS. */
if (cfun->stdarg)
@@ -7150,7 +7109,7 @@ sh_expand_prologue (void)
if (TARGET_VARARGS_PRETEND_ARGS (current_function_decl))
{
/* Push arg regs as if they'd been provided by caller in stack. */
- for (i = 0; i < NPARM_REGS(SImode); i++)
+ for (int i = 0; i < NPARM_REGS(SImode); i++)
{
int rn = NPARM_REGS(SImode) + FIRST_PARM_REG - i - 1;
@@ -7171,8 +7130,7 @@ sh_expand_prologue (void)
/* The argument specifies a variable holding the address of the
stack the interrupt function should switch to/from at entry/exit. */
tree arg = TREE_VALUE ( TREE_VALUE (sp_switch_attr));
- const char *s
- = ggc_strdup (TREE_STRING_POINTER (arg));
+ const char* s = ggc_strdup (TREE_STRING_POINTER (arg));
rtx sp_switch = gen_rtx_SYMBOL_REF (Pmode, s);
lab = add_constant (sp_switch, SImode, 0);
@@ -7181,7 +7139,8 @@ sh_expand_prologue (void)
emit_insn (gen_sp_switch_1 (newsrc));
}
- d = calc_live_regs (&live_regs_mask);
+ HARD_REG_SET live_regs_mask;
+ int d = calc_live_regs (&live_regs_mask);
/* ??? Maybe we could save some switching if we can move a mode switch
that already happens to be at the function start into the prologue. */
if (target_flags != save_flags && ! current_function_interrupt)
@@ -7199,12 +7158,12 @@ sh_expand_prologue (void)
target_flags = save_flags;
- output_stack_adjust (-rounded_frame_size (d) + d_rounding,
+ output_stack_adjust (-rounded_frame_size (d),
stack_pointer_rtx, 0, NULL, true);
- stack_usage += rounded_frame_size (d) - d_rounding;
+ stack_usage += rounded_frame_size (d);
if (frame_pointer_needed)
- frame_insn (GEN_MOV (hard_frame_pointer_rtx, stack_pointer_rtx));
+ emit_frame_insn (GEN_MOV (hard_frame_pointer_rtx, stack_pointer_rtx));
/* If we are profiling, make sure no instructions are scheduled before
the call to mcount. Similarly if some call instructions are swapped
@@ -7221,19 +7180,15 @@ sh_expand_prologue (void)
void
sh_expand_epilogue (bool sibcall_p)
{
- HARD_REG_SET live_regs_mask;
- int d, i;
- int d_rounding = 0;
-
int save_flags = target_flags;
- int frame_size, save_size;
- int fpscr_deferred = 0;
+ bool fpscr_deferred = false;
int e = sibcall_p ? -1 : 1;
- d = calc_live_regs (&live_regs_mask);
+ HARD_REG_SET live_regs_mask;
+ int d = calc_live_regs (&live_regs_mask);
- save_size = d;
- frame_size = rounded_frame_size (d);
+ int save_size = d;
+ int frame_size = rounded_frame_size (d);
if (frame_pointer_needed)
{
@@ -7248,7 +7203,7 @@ sh_expand_epilogue (bool sibcall_p)
occur after the SP adjustment and clobber data in the local
frame. */
emit_insn (gen_blockage ());
- frame_insn (GEN_MOV (stack_pointer_rtx, hard_frame_pointer_rtx));
+ emit_frame_insn (GEN_MOV (stack_pointer_rtx, hard_frame_pointer_rtx));
}
else if (frame_size)
{
@@ -7290,7 +7245,7 @@ sh_expand_epilogue (bool sibcall_p)
{
unsigned int count = 0;
- for (i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
+ for (int i = FIRST_BANKED_REG; i <= LAST_BANKED_REG; i++)
if (TEST_HARD_REG_BIT (live_regs_mask, i))
count++;
else
@@ -7314,7 +7269,7 @@ sh_expand_epilogue (bool sibcall_p)
emit_insn (gen_blockage ());
}
else
- for (i = LAST_BANKED_REG; i >= FIRST_BANKED_REG; i--)
+ for (int i = LAST_BANKED_REG; i >= FIRST_BANKED_REG; i--)
if (TEST_HARD_REG_BIT (live_regs_mask, i))
pop (i);
@@ -7323,14 +7278,14 @@ sh_expand_epilogue (bool sibcall_p)
else
last_reg = FIRST_PSEUDO_REGISTER;
- for (i = 0; i < last_reg; i++)
+ for (int i = 0; i < last_reg; i++)
{
int j = (FIRST_PSEUDO_REGISTER - 1) - i;
if (j == FPSCR_REG && current_function_interrupt && TARGET_FMOVD
&& hard_reg_set_intersect_p (live_regs_mask,
reg_class_contents[DF_REGS]))
- fpscr_deferred = 1;
+ fpscr_deferred = true;
/* For an ISR with RESBANK attribute assigned, don't pop
following registers, R0-R14, MACH, MACL and GBR. */
else if (j != PR_REG && TEST_HARD_REG_BIT (live_regs_mask, j)
@@ -7350,9 +7305,7 @@ sh_expand_epilogue (bool sibcall_p)
emit_insn (gen_toggle_sz ());
target_flags = save_flags;
- output_stack_adjust (crtl->args.pretend_args_size
- + save_size + d_rounding
- + crtl->args.info.stack_regs * 8,
+ output_stack_adjust (crtl->args.pretend_args_size + save_size,
stack_pointer_rtx, e, NULL, true);
if (crtl->calls_eh_return)
@@ -7379,8 +7332,7 @@ sh_set_return_address (rtx ra, rtx tmp)
HARD_REG_SET live_regs_mask;
int d = calc_live_regs (&live_regs_mask);
- /* If pr_reg isn't life, we can set it (or the register given in
- sh_media_register_for_return) directly. */
+ /* If pr_reg isn't life, we can set it directly. */
if (! TEST_HARD_REG_BIT (live_regs_mask, PR_REG))
{
rtx rr = gen_rtx_REG (SImode, PR_REG);
@@ -7427,7 +7379,7 @@ sh_builtin_saveregs (void)
int bufsize, regno;
alias_set_type alias_set;
- if (! TARGET_SH2E && ! TARGET_SH4)
+ if (!TARGET_FPU_ANY)
{
error ("__builtin_saveregs not supported by this subtarget");
return const0_rtx;
@@ -7668,30 +7620,26 @@ static tree
sh_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
gimple_seq *post_p ATTRIBUTE_UNUSED)
{
- HOST_WIDE_INT size, rsize;
- tree tmp, pptr_type_node;
+ tree tmp;
tree addr, lab_over = NULL, result = NULL;
- bool pass_by_ref;
tree eff_type;
- if (!VOID_TYPE_P (type))
- pass_by_ref = targetm.calls.must_pass_in_stack (TYPE_MODE (type), type);
- else
- pass_by_ref = false;
+ const bool pass_by_ref =
+ !VOID_TYPE_P (type)
+ && targetm.calls.must_pass_in_stack (TYPE_MODE (type), type);
if (pass_by_ref)
type = build_pointer_type (type);
- size = int_size_in_bytes (type);
- rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
- pptr_type_node = build_pointer_type (ptr_type_node);
+ HOST_WIDE_INT size = int_size_in_bytes (type);
+ HOST_WIDE_INT rsize = (size + UNITS_PER_WORD - 1) & -UNITS_PER_WORD;
+ tree pptr_type_node = build_pointer_type (ptr_type_node);
if ((TARGET_SH2E || TARGET_SH4)
&& ! (TARGET_HITACHI || sh_cfun_attr_renesas_p ()))
{
tree f_next_o, f_next_o_limit, f_next_fp, f_next_fp_limit, f_next_stack;
tree next_o, next_o_limit, next_fp, next_fp_limit, next_stack;
- int pass_as_float;
tree lab_false;
tree member;
@@ -7736,6 +7684,7 @@ sh_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
}
}
+ bool pass_as_float;
if (TARGET_FPU_DOUBLE)
{
pass_as_float = ((TREE_CODE (eff_type) == REAL_TYPE && size <= 8)
@@ -7949,6 +7898,20 @@ sh_callee_copies (cumulative_args_t cum, machine_mode mode,
% SH_MIN_ALIGN_FOR_CALLEE_COPY == 0));
}
+static sh_arg_class
+get_sh_arg_class (machine_mode mode)
+{
+ if (TARGET_FPU_ANY && mode == SFmode)
+ return SH_ARG_FLOAT;
+
+ if (TARGET_FPU_DOUBLE
+ && (GET_MODE_CLASS (mode) == MODE_FLOAT
+ || GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT))
+ return SH_ARG_FLOAT;
+
+ return SH_ARG_INT;
+}
+
/* Round a register number up to a proper boundary for an arg of mode
MODE.
The SH doesn't care about double alignment, so we only
@@ -7964,9 +7927,9 @@ sh_round_reg (const CUMULATIVE_ARGS& cum, machine_mode mode)
&& (mode == DFmode || mode == DCmode)
&& cum.arg_count[(int) SH_ARG_FLOAT] < NPARM_REGS (mode)))
&& GET_MODE_UNIT_SIZE (mode) > UNITS_PER_WORD)
- ? (cum.arg_count[(int) GET_SH_ARG_CLASS (mode)]
- + (cum.arg_count[(int) GET_SH_ARG_CLASS (mode)] & 1))
- : cum.arg_count[(int) GET_SH_ARG_CLASS (mode)]);
+ ? (cum.arg_count[(int) get_sh_arg_class (mode)]
+ + (cum.arg_count[(int) get_sh_arg_class (mode)] & 1))
+ : cum.arg_count[(int) get_sh_arg_class (mode)]);
}
/* Return true if arg of the specified mode should be passed in a register
@@ -8094,7 +8057,7 @@ sh_function_arg_advance (cumulative_args_t ca_v, machine_mode mode,
CUMULATIVE_ARGS *ca = get_cumulative_args (ca_v);
if (ca->force_mem)
- ca->force_mem = 0;
+ ca->force_mem = false;
if ((TARGET_HITACHI || ca->renesas_abi) && TARGET_FPU_DOUBLE)
{
@@ -8118,7 +8081,7 @@ sh_function_arg_advance (cumulative_args_t ca_v, machine_mode mode,
if (! ((TARGET_SH4 || TARGET_SH2A) || ca->renesas_abi)
|| sh_pass_in_reg_p (*ca, mode, type))
- (ca->arg_count[(int) GET_SH_ARG_CLASS (mode)]
+ (ca->arg_count[(int) get_sh_arg_class (mode)]
= (sh_round_reg (*ca, mode)
+ (mode == BLKmode
? CEIL (int_size_in_bytes (type), UNITS_PER_WORD)
@@ -8235,27 +8198,22 @@ sh_pretend_outgoing_varargs_named (cumulative_args_t ca_v)
int
initial_elimination_offset (int from, int to)
{
- int regs_saved;
- int regs_saved_rounding = 0;
- int total_saved_regs_space;
- int total_auto_space;
+ const int regs_saved_rounding = 0;
int save_flags = target_flags;
HARD_REG_SET live_regs_mask;
- regs_saved = calc_live_regs (&live_regs_mask);
+ int regs_saved = calc_live_regs (&live_regs_mask);
- total_auto_space = rounded_frame_size (regs_saved) - regs_saved_rounding;
+ int total_auto_space = rounded_frame_size (regs_saved) - regs_saved_rounding;
target_flags = save_flags;
- total_saved_regs_space = regs_saved + regs_saved_rounding;
+ int total_saved_regs_space = regs_saved + regs_saved_rounding;
if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
- return total_saved_regs_space + total_auto_space
- + crtl->args.info.byref_regs * 8;
+ return total_saved_regs_space + total_auto_space;
if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
- return total_saved_regs_space + total_auto_space
- + crtl->args.info.byref_regs * 8;
+ return total_saved_regs_space + total_auto_space;
/* Initial gap between fp and sp is 0. */
if (from == HARD_FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
@@ -8277,39 +8235,34 @@ initial_elimination_offset (int from, int to)
void
sh_fix_range (const char *const_str)
{
- int i, first, last;
- char *str, *dash, *comma;
-
/* str must be of the form REG1'-'REG2{,REG1'-'REG} where REG1 and
REG2 are either register names or register numbers. The effect
of this option is to mark the registers in the range from REG1 to
REG2 as ``fixed'' so they won't be used by the compiler. */
- i = strlen (const_str);
- str = (char *) alloca (i + 1);
- memcpy (str, const_str, i + 1);
+ char* str = strcpy ((char*)alloca (strlen (const_str) + 1), const_str);
while (1)
{
- dash = strchr (str, '-');
+ char* dash = strchr (str, '-');
if (!dash)
{
warning (0, "value of -mfixed-range must have form REG1-REG2");
return;
}
*dash = '\0';
- comma = strchr (dash + 1, ',');
+ char* comma = strchr (dash + 1, ',');
if (comma)
*comma = '\0';
- first = decode_reg_name (str);
+ int first = decode_reg_name (str);
if (first < 0)
{
warning (0, "unknown register name: %s", str);
return;
}
- last = decode_reg_name (dash + 1);
+ int last = decode_reg_name (dash + 1);
if (last < 0)
{
warning (0, "unknown register name: %s", dash + 1);
@@ -8324,7 +8277,7 @@ sh_fix_range (const char *const_str)
return;
}
- for (i = first; i <= last; ++i)
+ for (int i = first; i <= last; ++i)
fixed_regs[i] = call_used_regs[i] = 1;
if (!comma)
@@ -8339,8 +8292,6 @@ sh_fix_range (const char *const_str)
static void
sh_insert_attributes (tree node, tree *attributes)
{
- tree attrs;
-
if (TREE_CODE (node) != FUNCTION_DECL)
return;
@@ -8350,7 +8301,7 @@ sh_insert_attributes (tree node, tree *attributes)
/* Append the attributes to the deferred attributes. */
*sh_deferred_function_attributes_tail = *attributes;
- attrs = sh_deferred_function_attributes;
+ tree attrs = sh_deferred_function_attributes;
if (!attrs)
return;
@@ -8545,28 +8496,17 @@ sh2a_is_function_vector_call (rtx x)
int
sh2a_get_function_vector_number (rtx x)
{
- int num;
- tree list, t;
-
if ((GET_CODE (x) == SYMBOL_REF)
&& (SYMBOL_REF_FLAGS (x) & SYMBOL_FLAG_FUNCVEC_FUNCTION))
{
- t = SYMBOL_REF_DECL (x);
+ tree t = SYMBOL_REF_DECL (x);
if (TREE_CODE (t) != FUNCTION_DECL)
return 0;
- list = SH_ATTRIBUTES (t);
- while (list)
- {
- if (is_attribute_p ("function_vector", TREE_PURPOSE (list)))
- {
- num = TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (list)));
- return num;
- }
-
- list = TREE_CHAIN (list);
- }
+ for (tree list = SH_ATTRIBUTES (t); list; list = TREE_CHAIN (list))
+ if (is_attribute_p ("function_vector", TREE_PURPOSE (list)))
+ return TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (list)));
return 0;
}
@@ -8644,8 +8584,7 @@ sh_attr_renesas_p (const_tree td)
td = TREE_TYPE (td);
if (td == error_mark_node)
return false;
- return (lookup_attribute ("renesas", TYPE_ATTRIBUTES (td))
- != NULL_TREE);
+ return lookup_attribute ("renesas", TYPE_ATTRIBUTES (td)) != NULL_TREE;
}
/* True if __attribute__((renesas)) or -mrenesas, for the current
@@ -8671,18 +8610,13 @@ sh_cfun_interrupt_handler_p (void)
bool
sh2a_function_vector_p (tree func)
{
- tree list;
if (TREE_CODE (func) != FUNCTION_DECL)
return false;
- list = SH_ATTRIBUTES (func);
- while (list)
- {
- if (is_attribute_p ("function_vector", TREE_PURPOSE (list)))
- return true;
+ for (tree list = SH_ATTRIBUTES (func); list; list = TREE_CHAIN (list))
+ if (is_attribute_p ("function_vector", TREE_PURPOSE (list)))
+ return true;
- list = TREE_CHAIN (list);
- }
return false;
}
@@ -8742,12 +8676,10 @@ system_reg_operand (rtx op, machine_mode mode ATTRIBUTE_UNUSED)
bool
fp_zero_operand (rtx op)
{
- const REAL_VALUE_TYPE *r;
-
if (GET_MODE (op) != SFmode)
return false;
- r = CONST_DOUBLE_REAL_VALUE (op);
+ const REAL_VALUE_TYPE* r = CONST_DOUBLE_REAL_VALUE (op);
return real_equal (r, &dconst0) && ! REAL_VALUE_MINUS_ZERO (*r);
}
@@ -8775,13 +8707,11 @@ static int
branch_dest (rtx branch)
{
rtx dest = SET_SRC (PATTERN (branch));
- int dest_uid;
if (GET_CODE (dest) == IF_THEN_ELSE)
dest = XEXP (dest, 1);
- dest = XEXP (dest, 0);
- dest_uid = INSN_UID (dest);
- return INSN_ADDRESSES (dest_uid);
+
+ return INSN_ADDRESSES (INSN_UID (XEXP (dest, 0)));
}
/* Return nonzero if REG is not used after INSN.
@@ -8790,24 +8720,20 @@ branch_dest (rtx branch)
bool
reg_unused_after (rtx reg, rtx_insn *insn)
{
- enum rtx_code code;
- rtx set;
-
/* If the reg is set by this instruction, then it is safe for our
case. Disregard the case where this is a store to memory, since
we are checking a register used in the store address. */
- set = single_set (insn);
+ rtx set = single_set (insn);
if (set && !MEM_P (SET_DEST (set))
&& reg_overlap_mentioned_p (reg, SET_DEST (set)))
return true;
while ((insn = NEXT_INSN (insn)))
{
- rtx set;
if (!INSN_P (insn))
continue;
- code = GET_CODE (insn);
+ rtx_code code = GET_CODE (insn);
#if 0
/* If this is a label that existed before reload, then the register
@@ -8829,10 +8755,9 @@ reg_unused_after (rtx reg, rtx_insn *insn)
else if (code == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
{
rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (insn));
- int i;
- int retval = 0;
+ bool retval = false;
- for (i = 0; i < seq->len (); i++)
+ for (int i = 0; i < seq->len (); i++)
{
rtx_insn *this_insn = seq->insn (i);
rtx set = single_set (this_insn);
@@ -8859,18 +8784,18 @@ reg_unused_after (rtx reg, rtx_insn *insn)
&& reg_overlap_mentioned_p (reg, PATTERN (this_insn)))
return false;
}
- if (retval == 1)
+ if (retval)
return true;
else if (code == JUMP_INSN)
return false;
}
- set = single_set (insn);
+ rtx set = single_set (insn);
if (set && reg_overlap_mentioned_p (reg, SET_SRC (set)))
return false;
if (set && reg_overlap_mentioned_p (reg, SET_DEST (set)))
return !MEM_P (SET_DEST (set));
- if (set == 0 && reg_overlap_mentioned_p (reg, PATTERN (insn)))
+ if (set == NULL && reg_overlap_mentioned_p (reg, PATTERN (insn)))
return false;
if (code == CALL_INSN && call_really_used_regs[REGNO (reg)])
@@ -8894,13 +8819,9 @@ static GTY(()) tree fpscr_values;
static void
emit_fpu_switch (rtx scratch, int index)
{
- rtx src;
-
if (fpscr_values == NULL)
{
- tree t;
-
- t = build_index_type (integer_one_node);
+ tree t = build_index_type (integer_one_node);
t = build_array_type (integer_type_node, t);
t = build_decl (BUILTINS_LOCATION,
VAR_DECL, get_identifier ("__fpscr_values"), t);
@@ -8914,7 +8835,7 @@ emit_fpu_switch (rtx scratch, int index)
fpscr_values = t;
}
- src = DECL_RTL (fpscr_values);
+ rtx src = DECL_RTL (fpscr_values);
if (!can_create_pseudo_p ())
{
emit_move_insn (scratch, XEXP (src, 0));
@@ -8962,9 +8883,8 @@ fpscr_set_from_mem (int mode, HARD_REG_SET regs_live)
{
enum attr_fp_mode fp_mode = (enum attr_fp_mode) mode;
enum attr_fp_mode norm_mode = ACTUAL_NORMAL_MODE (FP_MODE);
- rtx addr_reg;
- addr_reg = !can_create_pseudo_p () ? get_free_reg (regs_live) : NULL_RTX;
+ rtx addr_reg = !can_create_pseudo_p () ? get_free_reg (regs_live) : NULL_RTX;
emit_fpu_switch (addr_reg, fp_mode == norm_mode);
}
@@ -8976,13 +8896,11 @@ fpscr_set_from_mem (int mode, HARD_REG_SET regs_live)
static bool
sequence_insn_p (rtx_insn *insn)
{
- rtx_insn *prev, *next;
-
- prev = PREV_INSN (insn);
+ rtx_insn* prev = PREV_INSN (insn);
if (prev == NULL)
return false;
- next = NEXT_INSN (prev);
+ rtx_insn* next = NEXT_INSN (prev);
if (next == NULL)
return false;
@@ -9146,9 +9064,6 @@ sh_legitimate_address_p (machine_mode mode, rtx x, bool strict)
bool
nonpic_symbol_mentioned_p (rtx x)
{
- const char *fmt;
- int i;
-
if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF
|| GET_CODE (x) == PC)
return true;
@@ -9174,13 +9089,12 @@ nonpic_symbol_mentioned_p (rtx x)
|| XINT (x, 1) == UNSPEC_GOTOFFFUNCDESC))
return false;
- fmt = GET_RTX_FORMAT (GET_CODE (x));
- for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
+ const char* fmt = GET_RTX_FORMAT (GET_CODE (x));
+ for (int i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
{
if (fmt[i] == 'E')
{
- int j;
- for (j = XVECLEN (x, i) - 1; j >= 0; j--)
+ for (int j = XVECLEN (x, i) - 1; j >= 0; j--)
if (nonpic_symbol_mentioned_p (XVECEXP (x, i, j)))
return true;
}
@@ -9194,8 +9108,7 @@ nonpic_symbol_mentioned_p (rtx x)
/* Convert a non-PIC address in `orig' to a PIC address using @GOT or
@GOTOFF in `reg'. */
rtx
-legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED,
- rtx reg)
+legitimize_pic_address (rtx orig, machine_mode mode ATTRIBUTE_UNUSED, rtx reg)
{
if (tls_symbolic_operand (orig, Pmode) != TLS_MODEL_NONE)
return orig;
@@ -9411,16 +9324,14 @@ sh_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
static rtx
sh_delegitimize_address (rtx orig_x)
{
- rtx x, y;
-
orig_x = delegitimize_mem_from_attrs (orig_x);
- x = orig_x;
+ rtx x = orig_x;
if (MEM_P (x))
x = XEXP (x, 0);
if (GET_CODE (x) == CONST)
{
- y = XEXP (x, 0);
+ rtx y = XEXP (x, 0);
if (GET_CODE (y) == UNSPEC)
{
if (XINT (y, 1) == UNSPEC_GOT
@@ -9450,9 +9361,6 @@ sh_delegitimize_address (rtx orig_x)
static rtx
mark_constant_pool_use (rtx x)
{
- rtx_insn *insn, *lab;
- rtx pattern;
-
if (x == NULL_RTX)
return x;
@@ -9468,8 +9376,8 @@ mark_constant_pool_use (rtx x)
/* Get the first label in the list of labels for the same constant
and delete another labels in the list. */
- lab = as_a <rtx_insn *> (x);
- for (insn = PREV_INSN (lab); insn; insn = PREV_INSN (insn))
+ rtx_insn* lab = as_a <rtx_insn*> (x);
+ for (rtx_insn* insn = PREV_INSN (lab); insn; insn = PREV_INSN (insn))
{
if (!LABEL_P (insn)
|| LABEL_REFS (insn) != NEXT_INSN (insn))
@@ -9481,12 +9389,13 @@ mark_constant_pool_use (rtx x)
as_a<rtx_insn *> (insn)->set_deleted ();
/* Mark constants in a window. */
- for (insn = NEXT_INSN (as_a <rtx_insn *> (x)); insn; insn = NEXT_INSN (insn))
+ for (rtx_insn* insn = NEXT_INSN (as_a <rtx_insn *> (x)); insn;
+ insn = NEXT_INSN (insn))
{
if (!NONJUMP_INSN_P (insn))
continue;
- pattern = PATTERN (insn);
+ rtx pattern = PATTERN (insn);
if (GET_CODE (pattern) != UNSPEC_VOLATILE)
continue;
@@ -9581,14 +9490,11 @@ sh_adjust_cost (rtx_insn *insn, rtx link ATTRIBUTE_UNUSED,
if (REG_NOTE_KIND (link) == 0)
{
- enum attr_type type;
- rtx dep_set;
-
if (recog_memoized (insn) < 0
|| recog_memoized (dep_insn) < 0)
return cost;
- dep_set = single_set (dep_insn);
+ rtx dep_set = single_set (dep_insn);
/* The latency that we specify in the scheduling description refers
to the actual output, not to an auto-increment register; for that,
@@ -9634,8 +9540,8 @@ sh_adjust_cost (rtx_insn *insn, rtx link ATTRIBUTE_UNUSED,
}
if (TARGET_HARD_SH4 && !TARGET_SH4_300)
{
- enum attr_type dep_type = get_attr_type (dep_insn);
-
+ attr_type dep_type = get_attr_type (dep_insn);
+ attr_type type;
if (dep_type == TYPE_FLOAD || dep_type == TYPE_PCFLOAD)
cost--;
else if ((dep_type == TYPE_LOAD_SI || dep_type == TYPE_PCLOAD_SI)
@@ -9675,6 +9581,7 @@ sh_adjust_cost (rtx_insn *insn, rtx link ATTRIBUTE_UNUSED,
else if (TARGET_SH4_300)
{
/* Stores need their input register two cycles later. */
+ attr_type type;
if (dep_set && cost >= 1
&& ((type = get_attr_type (insn)) == TYPE_STORE
|| type == TYPE_PSTORE
@@ -9794,12 +9701,9 @@ find_set_regmode_weight (rtx x, machine_mode mode)
static short
find_insn_regmode_weight (rtx insn, machine_mode mode)
{
- short reg_weight = 0;
- rtx x;
-
/* Increment weight for each register born here. */
- x = PATTERN (insn);
- reg_weight += find_set_regmode_weight (x, mode);
+ rtx x = PATTERN (insn);
+ short reg_weight = find_set_regmode_weight (x, mode);
if (GET_CODE (x) == PARALLEL)
{
int j;
@@ -9894,27 +9798,24 @@ ready_reorder (rtx_insn **ready, int nready)
static int
find_r0_life_regions (basic_block b)
{
- rtx_insn *end, *insn;
- rtx pset;
- rtx r0_reg;
- int live;
+ bool live;
int set;
int death = 0;
if (REGNO_REG_SET_P (df_get_live_in (b), R0_REG))
{
set = 1;
- live = 1;
+ live = true;
}
else
{
set = 0;
- live = 0;
+ live = false;
}
- insn = BB_HEAD (b);
- end = BB_END (b);
- r0_reg = gen_rtx_REG (SImode, R0_REG);
+ rtx_insn* insn = BB_HEAD (b);
+ rtx_insn* end = BB_END (b);
+ rtx r0_reg = gen_rtx_REG (SImode, R0_REG);
while (1)
{
if (INSN_P (insn))
@@ -9922,15 +9823,17 @@ find_r0_life_regions (basic_block b)
if (find_regno_note (insn, REG_DEAD, R0_REG))
{
death++;
- live = 0;
+ live = false;
}
+
+ rtx pset;
if (!live
&& (pset = single_set (insn))
&& reg_overlap_mentioned_p (r0_reg, SET_DEST (pset))
&& !find_regno_note (insn, REG_UNUSED, R0_REG))
{
set++;
- live = 1;
+ live = true;
}
}
if (insn == end)
@@ -10223,10 +10126,6 @@ sh_trampoline_adjust_address (rtx tramp)
return tramp;
}
-/* FIXME: This is overly conservative. A SHcompact function that
- receives arguments ``by reference'' will have them stored in its
- own stack frame, so it must not pass pointers or references to
- these arguments to other functions by means of sibling calls. */
/* If PIC, we cannot make sibling calls to global functions
because the PLT requires r12 to be live. */
static bool
@@ -10566,15 +10465,14 @@ sh_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
for (int i = 1; i <= 3; i++, nop++)
{
- tree arg;
- machine_mode opmode, argmode;
- tree optype;
-
if (! signature_args[signature][i])
break;
- arg = CALL_EXPR_ARG (exp, i - 1);
+ tree arg = CALL_EXPR_ARG (exp, i - 1);
if (arg == error_mark_node)
return const0_rtx;
+
+ machine_mode opmode;
+ tree optype;
if (signature_args[signature][i] & 8)
{
opmode = ptr_mode;
@@ -10585,7 +10483,8 @@ sh_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
opmode = insn_data[icode].operand[nop].mode;
optype = (*lang_hooks.types.type_for_mode) (opmode, 0);
}
- argmode = TYPE_MODE (TREE_TYPE (arg));
+
+ machine_mode argmode = TYPE_MODE (TREE_TYPE (arg));
if (argmode != opmode)
arg = build1 (NOP_EXPR, optype, arg);
op[nop] = expand_expr (arg, NULL_RTX, opmode, EXPAND_NORMAL);
@@ -11095,12 +10994,12 @@ function_symbol (rtx target, const char *name, sh_function_kind kind)
return function_symbol_result (sym, lab);
}
-/* Find the number of a general purpose register in S. */
+/* Find the number of the first general purpose register in S that
+ is not set. */
static int
scavenge_reg (HARD_REG_SET *s)
{
- int r;
- for (r = FIRST_GENERAL_REG; r <= LAST_GENERAL_REG; r++)
+ for (int r = FIRST_GENERAL_REG; r <= LAST_GENERAL_REG; r++)
if (TEST_HARD_REG_BIT (*s, r))
return r;
return -1;
@@ -11133,14 +11032,13 @@ sh_expand_t_scc (rtx operands[])
rtx op0 = operands[2];
rtx op1 = operands[3];
rtx result = target;
- HOST_WIDE_INT val;
if (!REG_P (op0) || REGNO (op0) != T_REG
|| !CONST_INT_P (op1))
return false;
if (!REG_P (result))
result = gen_reg_rtx (SImode);
- val = INTVAL (op1);
+ HOST_WIDE_INT val = INTVAL (op1);
if ((code == EQ && val == 1) || (code == NE && val == 0))
emit_insn (gen_movt (result, get_t_reg_rtx ()));
else if ((code == EQ && val == 0) || (code == NE && val == 1))
@@ -11158,14 +11056,11 @@ sh_expand_t_scc (rtx operands[])
static rtx
extract_sfunc_addr (rtx insn)
{
- rtx pattern, part = NULL_RTX;
- int len, i;
-
- pattern = PATTERN (insn);
- len = XVECLEN (pattern, 0);
- for (i = 0; i < len; i++)
+ rtx pattern = PATTERN (insn);
+ const int len = XVECLEN (pattern, 0);
+ for (int i = 0; i < len; i++)
{
- part = XVECEXP (pattern, 0, i);
+ rtx part = XVECEXP (pattern, 0, i);
if (GET_CODE (part) == USE && GET_MODE (XEXP (part, 0)) == Pmode
&& GENERAL_REGISTER_P (true_regnum (XEXP (part, 0))))
return XEXP (part, 0);
@@ -11250,13 +11145,10 @@ sh_init_cumulative_args (CUMULATIVE_ARGS * pcum,
{
pcum->arg_count [(int) SH_ARG_FLOAT] = 0;
pcum->free_single_fp_reg = 0;
- pcum->stack_regs = 0;
- pcum->byref_regs = 0;
- pcum->byref = 0;
- pcum->outgoing = (n_named_args == -1) ? 0 : 1;
+ pcum->outgoing = n_named_args != -1;
- /* XXX - Should we check TARGET_HITACHI here ??? */
- pcum->renesas_abi = sh_attr_renesas_p (fntype) ? 1 : 0;
+ /* FIXME: Should we check TARGET_HITACHI here ??? */
+ pcum->renesas_abi = sh_attr_renesas_p (fntype);
if (fntype)
{
@@ -11268,7 +11160,7 @@ sh_init_cumulative_args (CUMULATIVE_ARGS * pcum,
else
{
pcum->arg_count [(int) SH_ARG_INT] = 0;
- pcum->prototype_p = FALSE;
+ pcum->prototype_p = false;
if (mode != VOIDmode)
{
/* If the default ABI is the Renesas ABI then all library
@@ -11287,7 +11179,7 @@ sh_init_cumulative_args (CUMULATIVE_ARGS * pcum,
&& TARGET_FPU_DOUBLE)));
}
else
- pcum->force_mem = FALSE;
+ pcum->force_mem = false;
}
}
@@ -11543,8 +11435,7 @@ sh_movsf_ie_ra_split_p (rtx op0, rtx op1, rtx op2)
static void
sh_conditional_register_usage (void)
{
- int regno;
- for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
+ for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
if (! VALID_REGISTER_P (regno))
fixed_regs[regno] = call_used_regs[regno] = 1;
/* R8 and R9 are call-clobbered on SH5, but not on earlier SH ABIs. */
@@ -11566,7 +11457,7 @@ sh_conditional_register_usage (void)
call_really_used_regs[MACL_REG] = 0;
}
- for (regno = FIRST_GENERAL_REG; regno <= LAST_GENERAL_REG; regno++)
+ for (int regno = FIRST_GENERAL_REG; regno <= LAST_GENERAL_REG; regno++)
if (! fixed_regs[regno] && call_really_used_regs[regno])
SET_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
@@ -11614,9 +11505,6 @@ sh_init_sync_libfuncs (void)
bool
sh_can_use_simple_return_p (void)
{
- HARD_REG_SET live_regs_mask;
- int d;
-
if (! reload_completed || frame_pointer_needed)
return false;
@@ -11625,7 +11513,8 @@ sh_can_use_simple_return_p (void)
return false;
/* Finally, allow for pr save. */
- d = calc_live_regs (&live_regs_mask);
+ HARD_REG_SET live_regs_mask;
+ int d = calc_live_regs (&live_regs_mask);
if (rounded_frame_size (d) > 4)
return false;
diff --git a/gcc/config/sh/sh.h b/gcc/config/sh/sh.h
index 60c625028c1..a1a789fba66 100644
--- a/gcc/config/sh/sh.h
+++ b/gcc/config/sh/sh.h
@@ -201,7 +201,7 @@ extern int code_for_indirect_jump_scratch;
SUBTARGET_EXTRA_SPECS
#if TARGET_CPU_DEFAULT & MASK_HARD_SH4
-#define SUBTARGET_ASM_RELAX_SPEC "%{!m1:%{!m2:%{!m3*::-isa=sh4-up}}}"
+#define SUBTARGET_ASM_RELAX_SPEC "%{!m1:%{!m2:%{!m3*:-isa=sh4-up}}}"
#else
#define SUBTARGET_ASM_RELAX_SPEC "%{m4*:-isa=sh4-up}"
#endif
@@ -245,7 +245,7 @@ extern int code_for_indirect_jump_scratch;
/* Strict nofpu means that the compiler should tell the assembler
to reject FPU instructions. E.g. from ASM inserts. */
#if TARGET_CPU_DEFAULT & MASK_HARD_SH4 && !(TARGET_CPU_DEFAULT & MASK_SH_E)
-#define SUBTARGET_ASM_ISA_SPEC "%{!m1:%{!m2:%{!m3*:%{m4-nofpu|!m4*::-isa=sh4-nofpu}}}}"
+#define SUBTARGET_ASM_ISA_SPEC "%{!m1:%{!m2:%{!m3*:%{m4-nofpu|!m4*:-isa=sh4-nofpu}}}}"
#else
#define SUBTARGET_ASM_ISA_SPEC \
@@ -1154,6 +1154,8 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
&& (unsigned) (REGNO) < (unsigned) (FIRST_FP_PARM_REG \
+ NPARM_REGS (SFmode))))
+#ifdef __cplusplus
+
/* Define a data type for recording info about an argument list
during the scan of that argument list. This data type should
hold all necessary information about the function itself
@@ -1164,48 +1166,37 @@ extern enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
of arguments scanned so far (including the invisible argument,
if any, which holds the structure-value-address).
Thus NARGREGS or more means all following args should go on the stack. */
+
enum sh_arg_class { SH_ARG_INT = 0, SH_ARG_FLOAT = 1 };
-struct sh_args {
- int arg_count[2];
- int force_mem;
+
+struct sh_args
+{
+ /* How many SH_ARG_INT and how many SH_ARG_FLOAT args there are. */
+ int arg_count[2];
+
+ bool force_mem;
+
/* Nonzero if a prototype is available for the function. */
- int prototype_p;
+ bool prototype_p;
+
/* The number of an odd floating-point register, that should be used
for the next argument of type float. */
- int free_single_fp_reg;
+ int free_single_fp_reg;
+
/* Whether we're processing an outgoing function call. */
- int outgoing;
- /* The number of general-purpose registers that should have been
- used to pass partial arguments, that are passed totally on the
- stack. On SHcompact, a call trampoline will pop them off the
- stack before calling the actual function, and, if the called
- function is implemented in SHcompact mode, the incoming arguments
- decoder will push such arguments back onto the stack. For
- incoming arguments, STACK_REGS also takes into account other
- arguments passed by reference, that the decoder will also push
- onto the stack. */
- int stack_regs;
- /* The number of general-purpose registers that should have been
- used to pass arguments, if the arguments didn't have to be passed
- by reference. */
- int byref_regs;
- /* Set as by shcompact_byref if the current argument is to be passed
- by reference. */
- int byref;
+ bool outgoing;
/* This is set to nonzero when the call in question must use the Renesas ABI,
even without the -mrenesas option. */
- int renesas_abi;
+ bool renesas_abi;
};
-#define CUMULATIVE_ARGS struct sh_args
+typedef sh_args CUMULATIVE_ARGS;
+
+/* Set when processing a function with interrupt attribute. */
+extern bool current_function_interrupt;
-#define GET_SH_ARG_CLASS(MODE) \
- ((TARGET_FPU_ANY && (MODE) == SFmode) \
- ? SH_ARG_FLOAT \
- : TARGET_FPU_DOUBLE && (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- || GET_MODE_CLASS (MODE) == MODE_COMPLEX_FLOAT) \
- ? SH_ARG_FLOAT : SH_ARG_INT)
+#endif // __cplusplus
/* Initialize a variable CUM of type CUMULATIVE_ARGS
for a call to a function whose data type is FNTYPE.
@@ -1307,12 +1298,10 @@ struct sh_args {
#define HAVE_POST_INCREMENT TARGET_SH1
#define HAVE_PRE_DECREMENT TARGET_SH1
-#define USE_LOAD_POST_INCREMENT(mode) ((mode == SImode || mode == DImode) \
- ? 0 : TARGET_SH1)
-#define USE_LOAD_PRE_DECREMENT(mode) 0
-#define USE_STORE_POST_INCREMENT(mode) 0
-#define USE_STORE_PRE_DECREMENT(mode) ((mode == SImode || mode == DImode) \
- ? 0 : TARGET_SH1)
+#define USE_LOAD_POST_INCREMENT(mode) TARGET_SH1
+#define USE_LOAD_PRE_DECREMENT(mode) TARGET_SH2A
+#define USE_STORE_POST_INCREMENT(mode) TARGET_SH2A
+#define USE_STORE_PRE_DECREMENT(mode) TARGET_SH1
/* If a memory clear move would take CLEAR_RATIO or more simple
move-instruction pairs, we will do a setmem instead. */
@@ -1807,10 +1796,6 @@ struct sh_args {
#define FINAL_PRESCAN_INSN(INSN, OPVEC, NOPERANDS) \
final_prescan_insn ((INSN), (OPVEC), (NOPERANDS))
-
-extern rtx sh_compare_op0;
-extern rtx sh_compare_op1;
-
/* Which processor to schedule for. The elements of the enumeration must
match exactly the cpu attribute in the sh.md file. */
enum processor_type {
@@ -1849,8 +1834,6 @@ extern enum mdep_reorg_phase_e mdep_reorg_phase;
extern tree sh_deferred_function_attributes;
extern tree *sh_deferred_function_attributes_tail;
-/* Set when processing a function with interrupt attribute. */
-extern int current_function_interrupt;
/* Instructions with unfilled delay slots take up an
@@ -1891,8 +1874,7 @@ extern int current_function_interrupt;
? (TARGET_FMOVD ? FP_MODE_DOUBLE : FP_MODE_NONE) \
: ACTUAL_NORMAL_MODE (ENTITY))
-#define EPILOGUE_USES(REGNO) ((TARGET_SH2E || TARGET_SH4) \
- && (REGNO) == FPSCR_REG)
+#define EPILOGUE_USES(REGNO) (TARGET_FPU_ANY && REGNO == FPSCR_REG)
#define DWARF_FRAME_RETURN_COLUMN (DWARF_FRAME_REGNUM (PR_REG))
diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
index da1dfe98c20..406721dc736 100644
--- a/gcc/config/sh/sh.md
+++ b/gcc/config/sh/sh.md
@@ -477,16 +477,6 @@
(define_attr "is_sfunc" ""
(if_then_else (eq_attr "type" "sfunc") (const_int 1) (const_int 0)))
-(define_attr "branch_zero" "yes,no"
- (cond [(eq_attr "type" "!cbranch") (const_string "no")
- (ne (symbol_ref "(next_active_insn (insn)\
- == (prev_active_insn\
- (XEXP (SET_SRC (PATTERN (insn)), 1))))\
- && get_attr_length (next_active_insn (insn)) == 2")
- (const_int 0))
- (const_string "yes")]
- (const_string "no")))
-
;; SH4 Double-precision computation with double-precision result -
;; the two halves are ready at different times.
(define_attr "dfp_comp" "yes,no"
@@ -539,8 +529,13 @@
(eq_attr "type" "!pstore,prget")) (nil) (nil)])
;; Conditional branches with delay slots are available starting with SH2.
+;; If zero displacement conditional branches are fast, disable the delay
+;; slot if the branch jumps over only one 2-byte insn.
(define_delay
- (and (eq_attr "type" "cbranch") (match_test "TARGET_SH2"))
+ (and (eq_attr "type" "cbranch")
+ (match_test "TARGET_SH2")
+ (not (and (match_test "TARGET_ZDCBRANCH")
+ (match_test "sh_cbranch_distance (insn, 4) == 2"))))
[(eq_attr "cond_delay_slot" "yes") (nil) (nil)])
;; -------------------------------------------------------------------------
@@ -909,22 +904,6 @@
FAIL;
})
-;; FIXME: For some reason, on SH4A and SH2A combine fails to simplify this
-;; pattern by itself. What this actually does is:
-;; x == 0: (1 >> 0-0) & 1 = 1
-;; x != 0: (1 >> 0-x) & 1 = 0
-;; Without this the test pr51244-8.c fails on SH2A and SH4A.
-(define_insn_and_split "*cmpeqsi_t"
- [(set (reg:SI T_REG)
- (and:SI (lshiftrt:SI
- (const_int 1)
- (neg:SI (match_operand:SI 0 "arith_reg_operand" "r")))
- (const_int 1)))]
- "TARGET_SH1"
- "#"
- "&& 1"
- [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))])
-
(define_insn "cmpgtsi_t"
[(set (reg:SI T_REG)
(gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
@@ -1103,6 +1082,97 @@
(lshiftrt:SI (xor:SI (match_dup 0) (match_dup 1)) (const_int 31)))
(set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
+;; In some cases, it might be shorter to get a tested bit into bit 31 and
+;; use div0s. Otherwise it's usually better to just leave the xor and tst
+;; sequence. The only thing we can try to do here is avoiding the large
+;; tst constant.
+(define_insn_and_split "*cmp_div0s_7"
+ [(set (reg:SI T_REG)
+ (zero_extract:SI (xor:SI (match_operand:SI 0 "arith_reg_operand")
+ (match_operand:SI 1 "arith_reg_operand"))
+ (const_int 1)
+ (match_operand 2 "const_int_operand")))]
+ "TARGET_SH1 && can_create_pseudo_p ()
+ && (INTVAL (operands[2]) == 7 || INTVAL (operands[2]) == 15
+ || INTVAL (operands[2]) == 23 || INTVAL (operands[2]) == 29
+ || INTVAL (operands[2]) == 30 || INTVAL (operands[2]) == 31)"
+ "#"
+ "&& 1"
+ [(const_int 0)]
+{
+ const int bitpos = INTVAL (operands[2]);
+
+ rtx op0 = gen_reg_rtx (SImode);
+ rtx op1 = gen_reg_rtx (SImode);
+
+ if (bitpos == 23 || bitpos == 30 || bitpos == 29)
+ {
+ emit_insn (gen_ashlsi3 (op0, operands[0], GEN_INT (31 - bitpos)));
+ emit_insn (gen_ashlsi3 (op1, operands[1], GEN_INT (31 - bitpos)));
+ }
+ else if (bitpos == 15)
+ {
+ emit_insn (gen_extendhisi2 (op0, gen_lowpart (HImode, operands[0])));
+ emit_insn (gen_extendhisi2 (op1, gen_lowpart (HImode, operands[1])));
+ }
+ else if (bitpos == 7)
+ {
+ emit_insn (gen_extendqisi2 (op0, gen_lowpart (QImode, operands[0])));
+ emit_insn (gen_extendqisi2 (op1, gen_lowpart (QImode, operands[1])));
+ }
+ else if (bitpos == 31)
+ {
+ op0 = operands[0];
+ op1 = operands[1];
+ }
+ else
+ gcc_unreachable ();
+
+ emit_insn (gen_cmp_div0s (op0, op1));
+ DONE;
+})
+
+;; For bits 0..7 using a xor and tst #imm,r0 sequence seems to be better.
+;; Thus allow the following patterns only for higher bit positions where
+;; we it's more likely to save the large tst constant.
+(define_insn_and_split "*cmp_div0s_8"
+ [(set (reg:SI T_REG)
+ (eq:SI (zero_extract:SI (match_operand:SI 0 "arith_reg_operand")
+ (const_int 1)
+ (match_operand 2 "const_int_operand"))
+ (zero_extract:SI (match_operand:SI 1 "arith_reg_operand")
+ (const_int 1)
+ (match_dup 2))))]
+ "TARGET_SH1 && can_create_pseudo_p ()
+ && (INTVAL (operands[2]) == 15
+ || INTVAL (operands[2]) == 23 || INTVAL (operands[2]) == 29
+ || INTVAL (operands[2]) == 30 || INTVAL (operands[2]) == 31)"
+ "#"
+ "&& 1"
+ [(set (reg:SI T_REG)
+ (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
+ (const_int 1) (match_dup 2)))
+ (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
+
+(define_insn_and_split "*cmp_div0s_9"
+ [(set (reg:SI T_REG)
+ (zero_extract:SI (xor:SI (xor:SI (match_operand:SI 0 "arith_reg_operand")
+ (match_operand:SI 1 "arith_reg_operand"))
+ (match_operand 2 "const_int_operand"))
+ (const_int 1)
+ (match_operand 3 "const_int_operand")))]
+ "TARGET_SH1 && can_create_pseudo_p ()
+ && (INTVAL (operands[2]) & 0xFFFFFFFF) == (1U << INTVAL (operands[3]))
+ && (INTVAL (operands[3]) == 15
+ || INTVAL (operands[3]) == 23 || INTVAL (operands[3]) == 29
+ || INTVAL (operands[3]) == 30 || INTVAL (operands[3]) == 31)"
+ "#"
+ "&& 1"
+ [(set (reg:SI T_REG)
+ (zero_extract:SI (xor:SI (match_dup 0) (match_dup 1))
+ (const_int 1) (match_dup 3)))
+ (set (reg:SI T_REG) (xor:SI (reg:SI T_REG) (const_int 1)))])
+
;; -------------------------------------------------------------------------
;; SImode compare and branch
;; -------------------------------------------------------------------------
@@ -1138,29 +1208,6 @@
(label_ref (match_dup 2))
(pc)))])
-;; FIXME: Similar to the *cmpeqsi_t pattern above, for some reason, on SH4A
-;; and SH2A combine fails to simplify this pattern by itself.
-;; What this actually does is:
-;; x == 0: (1 >> 0-0) & 1 = 1
-;; x != 0: (1 >> 0-x) & 1 = 0
-;; Without this the test pr51244-8.c fails on SH2A and SH4A.
-(define_split
- [(set (pc)
- (if_then_else
- (eq (and:SI (lshiftrt:SI
- (const_int 1)
- (neg:SI (match_operand:SI 0 "arith_reg_operand" "")))
- (const_int 1))
- (const_int 0))
- (label_ref (match_operand 2))
- (pc)))
- (clobber (reg:SI T_REG))]
- "TARGET_SH1"
- [(set (reg:SI T_REG) (eq:SI (match_dup 0) (const_int 0)))
- (set (pc) (if_then_else (eq (reg:SI T_REG) (const_int 0))
- (label_ref (match_dup 2))
- (pc)))])
-
;; FIXME: These don't seem to have any effect on the generated cbranch code
;; anymore, but only on some register allocation choices.
(define_split
@@ -2244,16 +2291,9 @@
(define_expand "udivsi3"
- [(set (match_dup 3) (symbol_ref:SI "__udivsi3"))
- (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
- (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
- (parallel [(set (match_operand:SI 0 "register_operand" "")
- (udiv:SI (reg:SI R4_REG)
- (reg:SI R5_REG)))
- (clobber (reg:SI T_REG))
- (clobber (reg:SI PR_REG))
- (clobber (reg:SI R4_REG))
- (use (match_dup 3))])]
+ [(set (match_operand:SI 0 "register_operand")
+ (udiv:SI (match_operand:SI 1 "general_operand")
+ (match_operand:SI 2 "general_operand")))]
""
{
rtx last;
@@ -2379,18 +2419,9 @@
(set_attr "needs_delay_slot" "yes")])
(define_expand "divsi3"
- [(set (match_dup 3) (symbol_ref:SI "__sdivsi3"))
- (set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
- (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
- (parallel [(set (match_operand:SI 0 "register_operand" "")
- (div:SI (reg:SI R4_REG)
- (reg:SI R5_REG)))
- (clobber (reg:SI T_REG))
- (clobber (reg:SI PR_REG))
- (clobber (reg:SI R1_REG))
- (clobber (reg:SI R2_REG))
- (clobber (reg:SI R3_REG))
- (use (match_dup 3))])]
+ [(set (match_operand:SI 0 "register_operand")
+ (div:SI (match_operand:SI 1 "general_operand")
+ (match_operand:SI 2 "general_operand")))]
""
{
rtx last;
@@ -2434,6 +2465,30 @@
;; Multiplication instructions
;; -------------------------------------------------------------------------
+(define_insn_and_split "mulhisi3"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (mult:SI (sign_extend:SI (match_operand:HI 1 "arith_reg_operand"))
+ (sign_extend:SI (match_operand:HI 2 "arith_reg_operand"))))
+ (clobber (reg:SI MACL_REG))]
+ "TARGET_SH1 && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (reg:SI MACL_REG) (mult:SI (sign_extend:SI (match_dup 1))
+ (sign_extend:SI (match_dup 2))))
+ (set (match_dup 0) (reg:SI MACL_REG))])
+
+(define_insn_and_split "umulhisi3"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (mult:SI (zero_extend:SI (match_operand:HI 1 "arith_reg_operand"))
+ (zero_extend:SI (match_operand:HI 2 "arith_reg_operand"))))
+ (clobber (reg:SI MACL_REG))]
+ "TARGET_SH1 && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (reg:SI MACL_REG) (mult:SI (zero_extend:SI (match_dup 1))
+ (zero_extend:SI (match_dup 2))))
+ (set (match_dup 0) (reg:SI MACL_REG))])
+
(define_insn "umulhisi3_i"
[(set (reg:SI MACL_REG)
(mult:SI (zero_extend:SI
@@ -2454,69 +2509,10 @@
"muls.w %1,%0"
[(set_attr "type" "smpy")])
-(define_expand "mulhisi3"
- [(set (reg:SI MACL_REG)
- (mult:SI (sign_extend:SI
- (match_operand:HI 1 "arith_reg_operand" ""))
- (sign_extend:SI
- (match_operand:HI 2 "arith_reg_operand" ""))))
- (set (match_operand:SI 0 "arith_reg_operand" "")
- (reg:SI MACL_REG))]
- "TARGET_SH1"
-{
- rtx_insn *insn;
- rtx macl;
-
- macl = gen_rtx_REG (SImode, MACL_REG);
- start_sequence ();
- emit_insn (gen_mulhisi3_i (operands[1], operands[2]));
- insn = get_insns ();
- end_sequence ();
- /* expand_binop can't find a suitable code in umul_widen_optab to
- make a REG_EQUAL note from, so make one here.
- See also smulsi3_highpart.
- ??? Alternatively, we could put this at the calling site of expand_binop,
- i.e. expand_expr. */
- /* Use emit_libcall_block for loop invariant code motion and to make
- a REG_EQUAL note. */
- emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
-
- DONE;
-})
-
-(define_expand "umulhisi3"
- [(set (reg:SI MACL_REG)
- (mult:SI (zero_extend:SI
- (match_operand:HI 1 "arith_reg_operand" ""))
- (zero_extend:SI
- (match_operand:HI 2 "arith_reg_operand" ""))))
- (set (match_operand:SI 0 "arith_reg_operand" "")
- (reg:SI MACL_REG))]
- "TARGET_SH1"
-{
- rtx_insn *insn;
- rtx macl;
-
- macl = gen_rtx_REG (SImode, MACL_REG);
- start_sequence ();
- emit_insn (gen_umulhisi3_i (operands[1], operands[2]));
- insn = get_insns ();
- end_sequence ();
- /* expand_binop can't find a suitable code in umul_widen_optab to
- make a REG_EQUAL note from, so make one here.
- See also smulsi3_highpart.
- ??? Alternatively, we could put this at the calling site of expand_binop,
- i.e. expand_expr. */
- /* Use emit_libcall_block for loop invariant code motion and to make
- a REG_EQUAL note. */
- emit_libcall_block (insn, operands[0], macl, SET_SRC (single_set (insn)));
-
- DONE;
-})
;; mulsi3 on the SH2 can be done in one instruction, on the SH1 we generate
;; a call to a routine which clobbers known registers.
-(define_insn ""
+(define_insn "mulsi3_call"
[(set (match_operand:SI 1 "register_operand" "=z")
(mult:SI (reg:SI R4_REG) (reg:SI R5_REG)))
(clobber (reg:SI MACL_REG))
@@ -2531,22 +2527,6 @@
[(set_attr "type" "sfunc")
(set_attr "needs_delay_slot" "yes")])
-(define_expand "mulsi3_call"
- [(set (reg:SI R4_REG) (match_operand:SI 1 "general_operand" ""))
- (set (reg:SI R5_REG) (match_operand:SI 2 "general_operand" ""))
- (parallel[(set (match_operand:SI 0 "register_operand" "")
- (mult:SI (reg:SI R4_REG)
- (reg:SI R5_REG)))
- (clobber (reg:SI MACL_REG))
- (clobber (reg:SI T_REG))
- (clobber (reg:SI PR_REG))
- (clobber (reg:SI R3_REG))
- (clobber (reg:SI R2_REG))
- (clobber (reg:SI R1_REG))
- (use (match_operand:SI 3 "register_operand" ""))])]
- "TARGET_SH1"
- "")
-
(define_insn "mul_r"
[(set (match_operand:SI 0 "arith_reg_dest" "=r")
(mult:SI (match_operand:SI 1 "arith_reg_operand" "0")
@@ -2563,33 +2543,44 @@
"mul.l %1,%0"
[(set_attr "type" "dmpy")])
+(define_insn_and_split "mulsi3_i"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (mult:SI (match_operand:SI 1 "arith_reg_operand")
+ (match_operand:SI 2 "arith_reg_operand")))
+ (clobber (reg:SI MACL_REG))]
+ "TARGET_SH2 && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(set (reg:SI MACL_REG) (mult:SI (match_dup 1) (match_dup 2)))
+ (set (match_dup 0) (reg:SI MACL_REG))])
+
(define_expand "mulsi3"
- [(set (reg:SI MACL_REG)
- (mult:SI (match_operand:SI 1 "arith_reg_operand" "")
- (match_operand:SI 2 "arith_reg_operand" "")))
- (set (match_operand:SI 0 "arith_reg_operand" "")
- (reg:SI MACL_REG))]
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (mult:SI (match_operand:SI 1 "arith_reg_operand")
+ (match_operand:SI 2 "arith_reg_operand")))]
"TARGET_SH1"
{
if (!TARGET_SH2)
{
- /* The address must be set outside the libcall,
- since it goes into a pseudo. */
+ emit_move_insn (gen_rtx_REG (SImode, R4_REG), operands[1]);
+ emit_move_insn (gen_rtx_REG (SImode, R5_REG), operands[2]);
+
rtx sym = function_symbol (NULL, "__mulsi3", SFUNC_STATIC).sym;
- rtx addr = force_reg (SImode, sym);
- rtx insns = gen_mulsi3_call (operands[0], operands[1],
- operands[2], addr);
- emit_insn (insns);
+
+ emit_insn (gen_mulsi3_call (force_reg (SImode, sym), operands[0]));
}
else
{
- rtx macl = gen_rtx_REG (SImode, MACL_REG);
+ /* FIXME: For some reason, expanding the mul_l insn and the macl store
+ insn early gives slightly better code. In particular it prevents
+ the decrement-test loop type to be used in some cases which saves
+ one multiplication in the loop setup code.
+
+ emit_insn (gen_mulsi3_i (operands[0], operands[1], operands[2]));
+ */
emit_insn (gen_mul_l (operands[1], operands[2]));
- /* consec_sets_giv can only recognize the first insn that sets a
- giv as the giv insn. So we must tag this also with a REG_EQUAL
- note. */
- emit_insn (gen_movsi_i ((operands[0]), macl));
+ emit_move_insn (operands[0], gen_rtx_REG (SImode, MACL_REG));
}
DONE;
})
@@ -2610,9 +2601,9 @@
[(set_attr "type" "dmpy")])
(define_expand "mulsidi3"
- [(set (match_operand:DI 0 "arith_reg_dest" "")
- (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
- (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
+ [(set (match_operand:DI 0 "arith_reg_dest")
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+ (sign_extend:DI (match_operand:SI 2 "arith_reg_operand"))))]
"TARGET_SH2"
{
emit_insn (gen_mulsidi3_compact (operands[0], operands[1], operands[2]));
@@ -2620,13 +2611,12 @@
})
(define_insn_and_split "mulsidi3_compact"
- [(set (match_operand:DI 0 "arith_reg_dest" "=r")
- (mult:DI
- (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
- (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
+ [(set (match_operand:DI 0 "arith_reg_dest")
+ (mult:DI (sign_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+ (sign_extend:DI (match_operand:SI 2 "arith_reg_operand"))))
(clobber (reg:SI MACH_REG))
(clobber (reg:SI MACL_REG))]
- "TARGET_SH2"
+ "TARGET_SH2 && can_create_pseudo_p ()"
"#"
"&& 1"
[(const_int 0)]
@@ -2659,9 +2649,9 @@
[(set_attr "type" "dmpy")])
(define_expand "umulsidi3"
- [(set (match_operand:DI 0 "arith_reg_dest" "")
- (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
- (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" ""))))]
+ [(set (match_operand:DI 0 "arith_reg_dest")
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+ (zero_extend:DI (match_operand:SI 2 "arith_reg_operand"))))]
"TARGET_SH2"
{
emit_insn (gen_umulsidi3_compact (operands[0], operands[1], operands[2]));
@@ -2669,13 +2659,12 @@
})
(define_insn_and_split "umulsidi3_compact"
- [(set (match_operand:DI 0 "arith_reg_dest" "=r")
- (mult:DI
- (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" "r"))
- (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "r"))))
+ [(set (match_operand:DI 0 "arith_reg_dest")
+ (mult:DI (zero_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+ (zero_extend:DI (match_operand:SI 2 "arith_reg_operand"))))
(clobber (reg:SI MACH_REG))
(clobber (reg:SI MACL_REG))]
- "TARGET_SH2"
+ "TARGET_SH2 && can_create_pseudo_p ()"
"#"
"&& 1"
[(const_int 0)]
@@ -2705,38 +2694,23 @@
"dmuls.l %1,%0"
[(set_attr "type" "dmpy")])
-(define_expand "smulsi3_highpart"
- [(parallel
- [(set (reg:SI MACH_REG)
- (truncate:SI
- (lshiftrt:DI
+(define_insn_and_split "smulsi3_highpart"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (truncate:SI
+ (lshiftrt:DI
(mult:DI
- (sign_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
- (sign_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
- (const_int 32))))
- (clobber (reg:SI MACL_REG))])
- (set (match_operand:SI 0 "arith_reg_operand" "")
- (reg:SI MACH_REG))]
- "TARGET_SH2"
+ (sign_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+ (sign_extend:DI (match_operand:SI 2 "arith_reg_operand")))
+ (const_int 32))))
+ (clobber (reg:SI MACL_REG))
+ (clobber (reg:SI MACH_REG))]
+ "TARGET_SH2 && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- rtx_insn *insn;
- rtx mach;
-
- mach = gen_rtx_REG (SImode, MACH_REG);
- start_sequence ();
emit_insn (gen_smulsi3_highpart_i (operands[1], operands[2]));
- insn = get_insns ();
- end_sequence ();
- /* expand_binop can't find a suitable code in mul_highpart_optab to
- make a REG_EQUAL note from, so make one here.
- See also {,u}mulhisi.
- ??? Alternatively, we could put this at the calling site of expand_binop,
- i.e. expand_mult_highpart. */
- /* Use emit_libcall_block for loop invariant code motion and to make
- a REG_EQUAL note. */
- emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
-
- DONE;
+ emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
})
(define_insn "umulsi3_highpart_i"
@@ -2752,33 +2726,22 @@
"dmulu.l %1,%0"
[(set_attr "type" "dmpy")])
-(define_expand "umulsi3_highpart"
- [(parallel
- [(set (reg:SI MACH_REG)
- (truncate:SI
- (lshiftrt:DI
+(define_insn_and_split "umulsi3_highpart"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (truncate:SI
+ (lshiftrt:DI
(mult:DI
- (zero_extend:DI (match_operand:SI 1 "arith_reg_operand" ""))
- (zero_extend:DI (match_operand:SI 2 "arith_reg_operand" "")))
- (const_int 32))))
- (clobber (reg:SI MACL_REG))])
- (set (match_operand:SI 0 "arith_reg_operand" "")
- (reg:SI MACH_REG))]
- "TARGET_SH2"
+ (zero_extend:DI (match_operand:SI 1 "arith_reg_operand"))
+ (zero_extend:DI (match_operand:SI 2 "arith_reg_operand")))
+ (const_int 32))))
+ (clobber (reg:SI MACL_REG))]
+ "TARGET_SH2 && can_create_pseudo_p ()"
+ "#"
+ "&& 1"
+ [(const_int 0)]
{
- rtx_insn *insn;
- rtx mach;
-
- mach = gen_rtx_REG (SImode, MACH_REG);
- start_sequence ();
emit_insn (gen_umulsi3_highpart_i (operands[1], operands[2]));
- insn = get_insns ();
- end_sequence ();
- /* Use emit_libcall_block for loop invariant code motion and to make
- a REG_EQUAL note. */
- emit_libcall_block (insn, operands[0], mach, SET_SRC (single_set (insn)));
-
- DONE;
+ emit_move_insn (operands[0], gen_rtx_REG (SImode, MACH_REG));
})
;; -------------------------------------------------------------------------
@@ -3443,6 +3406,22 @@
DONE;
})
+(define_insn_and_split "*rotcr"
+ [(set (match_operand:SI 0 "arith_reg_dest")
+ (ior:SI (lshiftrt:SI (match_operand:SI 1 "arith_reg_operand")
+ (const_int 1))
+ (const_int -2147483648))) ;; 0xffffffff80000000
+ (clobber (reg:SI T_REG))]
+ "TARGET_SH1"
+ "#"
+ "&& can_create_pseudo_p ()"
+ [(const_int 0)]
+{
+ emit_insn (gen_sett ());
+ emit_insn (gen_rotcr (operands[0], operands[1], get_t_reg_rtx ()));
+ DONE;
+})
+
;; rotcr combine patterns for rotating in the negated T_REG value.
(define_insn_and_split "*rotcr_neg_t"
[(set (match_operand:SI 0 "arith_reg_dest")
@@ -4904,6 +4883,15 @@
[(set_attr "type" "load")
(set_attr "length" "2,2,4")])
+;; The pre-dec and post-inc mems must be captured by the '<' and '>'
+;; constraints, otherwise wrong code might get generated.
+(define_insn "*extend<mode>si2_predec"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=z")
+ (sign_extend:SI (match_operand:QIHI 1 "pre_dec_mem" "<")))]
+ "TARGET_SH2A"
+ "mov.<bw> %1,%0"
+ [(set_attr "type" "load")])
+
;; The *_snd patterns will take care of other QImode/HImode addressing
;; modes than displacement addressing. They must be defined _after_ the
;; displacement addressing patterns. Otherwise the displacement addressing
@@ -5149,20 +5137,23 @@
;; t/r must come after r/r, lest reload will try to reload stuff like
;; (set (subreg:SI (mem:QI (plus:SI (reg:SI SP_REG) (const_int 12)) 0) 0)
;; (made from (set (subreg:SI (reg:QI ###) 0) ) into T.
+;; Notice that although this pattern allows movi20 and movi20s on non-SH2A,
+;; those alternatives will not be taken, as they will be converted into
+;; PC-relative loads.
(define_insn "movsi_i"
[(set (match_operand:SI 0 "general_movdst_operand"
- "=r,r,r,r,r,r,m,<,<,x,l,x,l,r")
+ "=r,r, r, r, r, r,r,r,m,<,<,x,l,x,l,r")
(match_operand:SI 1 "general_movsrc_operand"
- "Q,r,I08,mr,x,l,r,x,l,r,r,>,>,i"))]
- "TARGET_SH1
- && ! TARGET_SH2E
- && ! TARGET_SH2A
+ " Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,i"))]
+ "TARGET_SH1 && !TARGET_FPU_ANY
&& (register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode))"
"@
mov.l %1,%0
mov %1,%0
mov %1,%0
+ movi20 %1,%0
+ movi20s %1,%0
mov.l %1,%0
sts %1,%0
sts %1,%0
@@ -5174,9 +5165,27 @@
lds.l %1,%0
lds.l %1,%0
fake %1,%0"
- [(set_attr "type" "pcload_si,move,movi8,load_si,mac_gp,prget,store,mac_mem,
- pstore,gp_mac,prset,mem_mac,pload,pcload_si")
- (set_attr "length" "*,*,*,*,*,*,*,*,*,*,*,*,*,*")])
+ [(set_attr "type" "pcload_si,move,movi8,move,move,load_si,mac_gp,prget,store,
+ mac_mem,pstore,gp_mac,prset,mem_mac,pload,pcload_si")
+ (set_attr_alternative "length"
+ [(const_int 2)
+ (const_int 2)
+ (const_int 2)
+ (const_int 4)
+ (const_int 4)
+ (if_then_else (match_operand 1 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (const_int 2)
+ (const_int 2)
+ (if_then_else (match_operand 0 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (const_int 2)
+ (const_int 2)
+ (const_int 2)
+ (const_int 2)
+ (const_int 2)
+ (const_int 2)
+ (const_int 2)])])
;; t/r must come after r/r, lest reload will try to reload stuff like
;; (subreg:SI (reg:SF FR14_REG) 0) into T (compiling stdlib/strtod.c -m3e -O2)
@@ -5184,12 +5193,15 @@
;; will require a reload.
;; ??? We can't include f/f because we need the proper FPSCR setting when
;; TARGET_FMOVD is in effect, and mode switching is done before reload.
+;; Notice that although this pattern allows movi20 and movi20s on non-SH2A,
+;; those alternatives will not be taken, as they will be converted into
+;; PC-relative loads.
(define_insn "movsi_ie"
[(set (match_operand:SI 0 "general_movdst_operand"
- "=r,r,r,r,r,r,r,r,mr,<,<,x,l,x,l,y,<,r,y,r,*f,y,*f,y")
+ "=r,r, r, r, r, r,r,r,mr,<,<,x,l,x,l,y,<,r,y,r,*f, y,*f,y")
(match_operand:SI 1 "general_movsrc_operand"
- "Q,r,I08,I20,I28,mr,x,l,r,x,l,r,r,>,>,>,y,i,r,y,y,*f,*f,y"))]
- "(TARGET_SH2E || TARGET_SH2A)
+ " Q,r,I08,I20,I28,mr,x,l, r,x,l,r,r,>,>,>,y,i,r,y, y,*f,*f,y"))]
+ "TARGET_SH1 && TARGET_FPU_ANY
&& ((register_operand (operands[0], SImode)
&& !fpscr_operand (operands[0], SImode))
|| (register_operand (operands[1], SImode)
@@ -5229,14 +5241,12 @@
(const_int 2)
(const_int 4)
(const_int 4)
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
+ (if_then_else (match_operand 1 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
(const_int 2)
(const_int 2)
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
+ (if_then_else (match_operand 0 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
(const_int 2)
(const_int 2)
(const_int 2)
@@ -5253,23 +5263,44 @@
(const_int 2)
(const_int 0)])])
+;; Notice that although this pattern allows movi20 and movi20s on non-SH2A,
+;; those alternatives will not be taken, as they will be converted into
+;; PC-relative loads.
(define_insn "movsi_i_lowpart"
[(set (strict_low_part
- (match_operand:SI 0 "general_movdst_operand" "+r,r,r,r,r,r,m,r"))
- (match_operand:SI 1 "general_movsrc_operand" "Q,r,I08,mr,x,l,r,i"))]
- "TARGET_SH1
- && (register_operand (operands[0], SImode)
- || register_operand (operands[1], SImode))"
+ (match_operand:SI 0 "general_movdst_operand"
+ "+r,r, r, r, r, r,r,r,m,r"))
+ (match_operand:SI 1 "general_movsrc_operand"
+ " Q,r,I08,I20,I28,mr,x,l,r,i"))]
+ "TARGET_SH1
+ && (register_operand (operands[0], SImode)
+ || register_operand (operands[1], SImode))"
"@
mov.l %1,%0
mov %1,%0
mov %1,%0
+ movi20 %1,%0
+ movi20s %1,%0
mov.l %1,%0
sts %1,%0
sts %1,%0
mov.l %1,%0
fake %1,%0"
- [(set_attr "type" "pcload,move,arith,load,mac_gp,prget,store,pcload")])
+ [(set_attr "type" "pcload,move,movi8,move,move,load,mac_gp,prget,store,
+ pcload")
+ (set_attr_alternative "length"
+ [(const_int 2)
+ (const_int 2)
+ (const_int 2)
+ (const_int 4)
+ (const_int 4)
+ (if_then_else (match_operand 1 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (const_int 2)
+ (const_int 2)
+ (if_then_else (match_operand 0 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (const_int 2)])])
(define_insn_and_split "load_ra"
[(set (match_operand:SI 0 "general_movdst_operand" "")
@@ -5326,7 +5357,7 @@
" synco" "\n"
" icbi @%0";
}
- [(set_attr "length" "16") ;; FIXME: Why 16 and not 6? Looks like typo.
+ [(set_attr "length" "6")
(set_attr "type" "cwb")])
(define_expand "mov<mode>"
@@ -5345,6 +5376,22 @@
prepare_move_operands (operands, <MODE>mode);
})
+;; The pre-dec and post-inc mems must be captured by the '<' and '>'
+;; constraints, otherwise wrong code might get generated.
+(define_insn "*mov<mode>_load_predec"
+ [(set (match_operand:QIHISI 0 "arith_reg_dest" "=z")
+ (match_operand:QIHISI 1 "pre_dec_mem" "<"))]
+ "TARGET_SH2A"
+ "mov.<bwl> %1,%0"
+ [(set_attr "type" "load")])
+
+(define_insn "*mov<mode>_store_postinc"
+ [(set (match_operand:QIHISI 0 "post_inc_mem" "=>")
+ (match_operand:QIHISI 1 "arith_reg_operand" "z"))]
+ "TARGET_SH2A"
+ "mov.<bwl> %1,%0"
+ [(set_attr "type" "store")])
+
;; Specifying the displacement addressing load / store patterns separately
;; before the generic movqi / movhi pattern allows controlling the order
;; in which load / store insns are selected in a more fine grained way.
@@ -5430,27 +5477,26 @@
lds %1,%0"
[(set_attr "type" "pcload,move,movi8,store,load,store,load,store,load,prget,prset")
(set (attr "length")
- (cond [(and (match_operand 0 "displacement_mem_operand")
- (not (match_operand 0 "short_displacement_mem_operand")))
- (const_int 4)
- (and (match_operand 1 "displacement_mem_operand")
- (not (match_operand 1 "short_displacement_mem_operand")))
- (const_int 4)]
+ (cond [(match_operand 0 "long_displacement_mem_operand") (const_int 4)
+ (match_operand 1 "long_displacement_mem_operand") (const_int 4)]
(const_int 2)))])
;; x/r can be created by inlining/cse, e.g. for execute/961213-1.c
;; compiled with -m2 -ml -O3 -funroll-loops
(define_insn "*movdi_i"
- [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m,r,r,r,*!x")
- (match_operand:DI 1 "general_movsrc_operand" "Q,r,m,r,I08,i,x,r"))]
+ [(set (match_operand:DI 0 "general_movdst_operand" "=r,r,r,m, r,r,r,*!x")
+ (match_operand:DI 1 "general_movsrc_operand" " Q,r,m,r,I08,i,x, r"))]
"TARGET_SH1
&& (arith_reg_operand (operands[0], DImode)
|| arith_reg_operand (operands[1], DImode))"
{
return output_movedouble (insn, operands, DImode);
}
- [(set_attr "length" "4")
- (set_attr "type" "pcload,move,load,store,move,pcload,move,move")])
+ [(set_attr "type" "pcload,move,load,store,move,pcload,move,move")
+ (set (attr "length")
+ (cond [(match_operand 0 "long_displacement_mem_operand") (const_int 8)
+ (match_operand 1 "long_displacement_mem_operand") (const_int 8)]
+ (const_int 4)))])
;; If the output is a register and the input is memory or a register, we have
;; to be careful and see which word needs to be loaded first.
@@ -5528,8 +5574,8 @@
;; FIXME: This should be a define_insn_and_split.
(define_insn "movdf_k"
- [(set (match_operand:DF 0 "general_movdst_operand" "=r,r,r,m")
- (match_operand:DF 1 "general_movsrc_operand" "r,FQ,m,r"))]
+ [(set (match_operand:DF 0 "general_movdst_operand" "=r, r,r,m")
+ (match_operand:DF 1 "general_movsrc_operand" " r,FQ,m,r"))]
"TARGET_SH1
&& (!TARGET_FPU_DOUBLE || reload_completed
/* ??? We provide some insn so that direct_{load,store}[DFmode] get set */
@@ -5540,8 +5586,11 @@
{
return output_movedouble (insn, operands, DFmode);
}
- [(set_attr "length" "4")
- (set_attr "type" "move,pcload,load,store")])
+ [(set_attr "type" "move,pcload,load,store")
+ (set (attr "length")
+ (cond [(match_operand 0 "long_displacement_mem_operand") (const_int 8)
+ (match_operand 1 "long_displacement_mem_operand") (const_int 8)]
+ (const_int 4)))])
;; All alternatives of movdf_i4 are split for ! TARGET_FMOVD.
;; However, the d/F/c/z alternative cannot be split directly; it is converted
@@ -5549,11 +5598,19 @@
;; the d/m/c/X alternative, which is split later into single-precision
;; instructions. And when not optimizing, no splits are done before fixing
;; up pcloads, so we need usable length information for that.
+;; A DF constant load results in the following worst-case 8 byte sequence:
+;; mova ...,r0
+;; fmov.s @r0+,..
+;; fmov.s @r0,...
+;; add #-4,r0
(define_insn "movdf_i4"
- [(set (match_operand:DF 0 "general_movdst_operand" "=d,r,d,d,m,r,r,m,!??r,!???d")
- (match_operand:DF 1 "general_movsrc_operand" "d,r,F,m,d,FQ,m,r,d,r"))
+ [(set (match_operand:DF 0 "general_movdst_operand"
+ "=d,r, d,d,m, r,r,m,!??r,!???d")
+ (match_operand:DF 1 "general_movsrc_operand"
+ " d,r, F,m,d,FQ,m,r, d, r"))
(use (reg:SI FPSCR_MODES_REG))
- (clobber (match_scratch:SI 2 "=X,X,&z,X,X,X,X,X,X,X"))]
+ (clobber (match_scratch:SI 2
+ "=X,X,&z,X,X, X,X,X, X, X"))]
"TARGET_FPU_DOUBLE
&& (arith_reg_operand (operands[0], DFmode)
|| arith_reg_operand (operands[1], DFmode))"
@@ -5577,16 +5634,28 @@
}
}
[(set_attr_alternative "length"
- [(if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
+ [(if_then_else (eq_attr "fmovd" "yes") (const_int 2) (const_int 4))
(const_int 4)
- (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
- (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
- (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 6))
+ (if_then_else (eq_attr "fmovd" "yes") (const_int 4) (const_int 8))
+ (if_then_else (match_operand 1 "displacement_mem_operand")
+ (if_then_else (eq_attr "fmovd" "yes")
+ (const_int 4) (const_int 8))
+ (if_then_else (eq_attr "fmovd" "yes")
+ (const_int 2) (const_int 4)))
+ (if_then_else (match_operand 0 "displacement_mem_operand")
+ (if_then_else (eq_attr "fmovd" "yes")
+ (const_int 4) (const_int 8))
+ (if_then_else (eq_attr "fmovd" "yes")
+ (const_int 2) (const_int 4)))
(const_int 4)
- (const_int 8) (const_int 8) ;; these need only 8 bytes for @(r0,rn)
+ (if_then_else (match_operand 1 "long_displacement_mem_operand")
+ (const_int 8) (const_int 4))
+ (if_then_else (match_operand 0 "long_displacement_mem_operand")
+ (const_int 8) (const_int 4))
(const_int 8)
(const_int 8)])
- (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,fload")
+ (set_attr "type" "fmove,move,pcfload,fload,fstore,pcload,load,store,load,
+ fload")
(set_attr "late_fp_use" "*,*,*,*,yes,*,*,*,*,*")
(set (attr "fp_mode") (if_then_else (eq_attr "fmovd" "yes")
(const_string "double")
@@ -5980,8 +6049,11 @@
}
})
+;; FIXME Although the movsf_i pattern is not used when there's an FPU,
+;; it somehow influences some RA choices also on FPU targets.
+;; For non-FPU targets it's actually not needed.
(define_insn "movsf_i"
- [(set (match_operand:SF 0 "general_movdst_operand" "=r,r,r,r,m,l,r")
+ [(set (match_operand:SF 0 "general_movdst_operand" "=r,r, r, r,m,l,r")
(match_operand:SF 1 "general_movsrc_operand" "r,G,FQ,mr,r,r,l"))]
"TARGET_SH1
&& (! TARGET_SH2E
@@ -5998,21 +6070,34 @@
mov.l %1,%0
lds %1,%0
sts %1,%0"
- [(set_attr "type" "move,move,pcload,load,store,move,move")])
+ [(set_attr "type" "move,move,pcload,load,store,move,move")
+ (set_attr_alternative "length"
+ [(const_int 2)
+ (const_int 2)
+ (if_then_else (match_operand 1 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (if_then_else (match_operand 1 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (if_then_else (match_operand 0 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (const_int 2)
+ (const_int 2)])])
;; We may not split the ry/yr/XX alternatives to movsi_ie, since
;; update_flow_info would not know where to put REG_EQUAL notes
;; when the destination changes mode.
(define_insn "movsf_ie"
[(set (match_operand:SF 0 "general_movdst_operand"
- "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
+ "=f,r,f,f,fy, f,m, r, r,m,f,y,y,rf,r,y,<,y,y")
(match_operand:SF 1 "general_movsrc_operand"
- "f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
+ " f,r,G,H,FQ,mf,f,FQ,mr,r,y,f,>,fr,y,r,y,>,y"))
(use (reg:SI FPSCR_MODES_REG))
- (clobber (match_scratch:SI 2 "=X,X,X,X,&z,X,X,X,X,X,X,X,X,y,X,X,X,X,X"))]
+ (clobber (match_scratch:SI 2 "=X,X,X,X,&z, X,X, X, X,X,X,X,X, y,X,X,X,X,X"))]
"TARGET_SH2E
- && (arith_reg_operand (operands[0], SFmode) || fpul_operand (operands[0], SFmode)
- || arith_reg_operand (operands[1], SFmode) || fpul_operand (operands[1], SFmode)
+ && (arith_reg_operand (operands[0], SFmode)
+ || fpul_operand (operands[0], SFmode)
+ || arith_reg_operand (operands[1], SFmode)
+ || fpul_operand (operands[1], SFmode)
|| arith_reg_operand (operands[2], SImode))"
"@
fmov %1,%0
@@ -6043,19 +6128,15 @@
(const_int 2)
(const_int 2)
(const_int 4)
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
+ (if_then_else (match_operand 1 "displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (if_then_else (match_operand 0 "displacement_mem_operand")
+ (const_int 4) (const_int 2))
(const_int 2)
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
+ (if_then_else (match_operand 1 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (if_then_else (match_operand 0 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
(const_int 2)
(const_int 2)
(const_int 2)
@@ -6091,11 +6172,11 @@
(define_insn_and_split "movsf_ie_ra"
[(set (match_operand:SF 0 "general_movdst_operand"
- "=f,r,f,f,fy,f,m,r,r,m,f,y,y,rf,r,y,<,y,y")
+ "=f,r,f,f,fy,f,m, r,r,m,f,y,y,rf,r,y,<,y,y")
(match_operand:SF 1 "general_movsrc_operand"
- "f,r,G,H,FQ,m,f,FQ,m,r,y,f,>,fr,y,r,y,>,y"))
+ " f,r,G,H,FQ,m,f,FQ,m,r,y,f,>,fr,y,r,y,>,y"))
(use (reg:SI FPSCR_MODES_REG))
- (clobber (match_scratch:SF 2 "=r,r,X,X,&z,r,r,X,r,r,r,r,r,y,r,r,r,r,r"))
+ (clobber (match_scratch:SF 2 "=r,r,X,X,&z,r,r, X,r,r,r,r,r, y,r,r,r,r,r"))
(const_int 0)]
"TARGET_SH2E
&& (arith_reg_operand (operands[0], SFmode)
@@ -6141,19 +6222,15 @@
(const_int 2)
(const_int 2)
(const_int 4)
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
+ (if_then_else (match_operand 1 "displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (if_then_else (match_operand 0 "displacement_mem_operand")
+ (const_int 4) (const_int 2))
(const_int 2)
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
- (if_then_else
- (match_test "TARGET_SH2A")
- (const_int 4) (const_int 2))
+ (if_then_else (match_operand 1 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
+ (if_then_else (match_operand 0 "long_displacement_mem_operand")
+ (const_int 4) (const_int 2))
(const_int 2)
(const_int 2)
(const_int 2)
diff --git a/gcc/config/sh/sh.opt b/gcc/config/sh/sh.opt
index f9b02c520cb..2a94c9becb2 100644
--- a/gcc/config/sh/sh.opt
+++ b/gcc/config/sh/sh.opt
@@ -181,10 +181,6 @@ maccumulate-outgoing-args
Target Report Var(TARGET_ACCUMULATE_OUTGOING_ARGS) Init(1)
Reserve space for outgoing arguments in the function prologue.
-madjust-unroll
-Target Ignore
-Does nothing. Preserved for backward compatibility.
-
mb
Target Report RejectNegative InverseMask(LITTLE_ENDIAN)
Generate code in big endian mode.
@@ -245,10 +241,6 @@ minline-ic_invalidate
Target Report Var(TARGET_INLINE_IC_INVALIDATE)
inline code to invalidate instruction cache entries after setting up nested function trampolines.
-minvalid-symbols
-Target Report Mask(INVALID_SYMBOLS) Condition(SUPPORT_ANY_SH5)
-Assume symbols might be invalid.
-
misize
Target Report RejectNegative Mask(DUMPISIZE)
Annotate assembler instructions with estimated addresses.
@@ -279,10 +271,6 @@ mrenesas
Target Mask(HITACHI)
Follow Renesas (formerly Hitachi) / SuperH calling conventions.
-msoft-atomic
-Target Undocumented Alias(matomic-model=, soft-gusa, none)
-Deprecated. Use -matomic= instead to select the atomic model.
-
matomic-model=
Target Report RejectNegative Joined Var(sh_atomic_model_str)
Specify the model for atomic operations.
@@ -291,10 +279,6 @@ mtas
Target Report RejectNegative Var(TARGET_ENABLE_TAS)
Use tas.b instruction for __atomic_test_and_set.
-mspace
-Target RejectNegative Alias(Os)
-Deprecated. Use -Os instead.
-
multcost=
Target RejectNegative Joined UInteger Var(sh_multcost) Init(-1)
Cost to assume for a multiply insn.
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index 5160e1fda18..50f2b383a1b 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -166,21 +166,26 @@ along with GCC; see the file COPYING3. If not see
#define STARTFILE_CRTBEGIN_SPEC "crtbegin.o%s"
#endif
+#if ENABLE_VTABLE_VERIFY
#if SUPPORTS_INIT_PRIORITY
#define STARTFILE_VTV_SPEC \
"%{fvtable-verify=none:%s; \
fvtable-verify=preinit:vtv_start_preinit.o%s; \
fvtable-verify=std:vtv_start.o%s}"
-
#define ENDFILE_VTV_SPEC \
"%{fvtable-verify=none:%s; \
fvtable-verify=preinit:vtv_end_preinit.o%s; \
fvtable-verify=std:vtv_end.o%s}"
-#else
+#else /* !SUPPORTS_INIT_PRIORITY */
#define STARTFILE_VTV_SPEC \
- "%{fvtable-verify:%e-fvtable-verify is not supported in this configuration}"
+ "%{fvtable-verify=*: \
+ %e-fvtable-verify=%* is not supported in this configuration}"
#define ENDFILE_VTV_SPEC ""
-#endif
+#endif /* !SUPPORTS_INIT_PRIORITY */
+#else /* !ENABLE_VTABLE_VERIFY */
+#define STARTFILE_VTV_SPEC ""
+#define ENDFILE_VTV_SPEC ""
+#endif /* !ENABLE_VTABLE_VERIFY */
/* We don't use the standard svr4 STARTFILE_SPEC because it's wrong for us. */
#undef STARTFILE_SPEC
diff --git a/gcc/configure b/gcc/configure
index 274c397be7d..c8d8abcb3a5 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -822,6 +822,7 @@ host_subdir
build_subdir
build_libsubdir
target_noncanonical
+host_noncanonical
target_os
target_vendor
target_cpu
@@ -904,6 +905,7 @@ enable_decimal_float
enable_fixed_point
enable_threads
enable_tls
+enable_vtable_verify
enable_objc_gc
with_dwarf2
enable_shared
@@ -1619,6 +1621,7 @@ Optional Features:
package
--enable-tls enable or disable generation of tls code overriding
the assembler check for tls support
+ --enable-vtable-verify enable vtable verification feature
--enable-objc-gc enable the use of Boehm's garbage collector with the
GNU Objective-C runtime
--disable-shared don't provide a shared libgcc
@@ -3321,7 +3324,7 @@ test -n "$target_alias" &&
NONENONEs,x,x, &&
program_prefix=${target_alias}-
-# Determine the noncanonical target name, for directory use.
+# Determine the noncanonical host name, for Ada.
case ${build_alias} in
"") build_noncanonical=${build} ;;
*) build_noncanonical=${build_alias} ;;
@@ -3332,6 +3335,10 @@ esac
*) host_noncanonical=${host_alias} ;;
esac
+
+
+
+# Determine the noncanonical target name, for directory use.
case ${target_alias} in
"") target_noncanonical=${host_noncanonical} ;;
*) target_noncanonical=${target_alias} ;;
@@ -7591,6 +7598,20 @@ else
fi
+# Check whether --enable-vtable-verify was given.
+if test "${enable_vtable_verify+set}" = set; then :
+ enableval=$enable_vtable_verify;
+else
+ enable_vtable_verify=no
+fi
+
+vtable_verify=`if test x$enable_vtable_verify = xyes; then echo 1; else echo 0; fi`
+
+cat >>confdefs.h <<_ACEOF
+#define ENABLE_VTABLE_VERIFY $vtable_verify
+_ACEOF
+
+
# Check whether --enable-objc-gc was given.
if test "${enable_objc_gc+set}" = set; then :
enableval=$enable_objc_gc; if test x$enable_objc_gc = xno; then
@@ -18458,7 +18479,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 18462 "configure"
+#line 18482 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -18564,7 +18585,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 18568 "configure"
+#line 18588 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/gcc/configure.ac b/gcc/configure.ac
index e40d82a8306..ab91de6e4b1 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -35,6 +35,9 @@ AC_CANONICAL_BUILD
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
+# Determine the noncanonical host name, for Ada.
+ACX_NONCANONICAL_HOST
+
# Determine the noncanonical target name, for directory use.
ACX_NONCANONICAL_TARGET
@@ -865,6 +868,14 @@ Valid choices are 'yes' and 'no'.]) ;;
esac
], [enable_tls=''])
+AC_ARG_ENABLE(vtable-verify,
+[AS_HELP_STRING([--enable-vtable-verify],
+ [enable vtable verification feature])],,
+[enable_vtable_verify=no])
+vtable_verify=`if test x$enable_vtable_verify = xyes; then echo 1; else echo 0; fi`
+AC_DEFINE_UNQUOTED(ENABLE_VTABLE_VERIFY, $vtable_verify,
+[Define 0/1 if vtable verification feature is enabled.])
+
AC_ARG_ENABLE(objc-gc,
[AS_HELP_STRING([--enable-objc-gc],
[enable the use of Boehm's garbage collector with
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index 12067fdf534..b3a91a6d5c5 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -222,6 +222,30 @@ enum var_init_status
VAR_INIT_STATUS_INITIALIZED
};
+/* Names for the different levels of -Wstrict-overflow=N. The numeric
+ values here correspond to N. */
+enum warn_strict_overflow_code
+{
+ /* Overflow warning that should be issued with -Wall: a questionable
+ construct that is easy to avoid even when using macros. Example:
+ folding (x + CONSTANT > x) to 1. */
+ WARN_STRICT_OVERFLOW_ALL = 1,
+ /* Overflow warning about folding a comparison to a constant because
+ of undefined signed overflow, other than cases covered by
+ WARN_STRICT_OVERFLOW_ALL. Example: folding (abs (x) >= 0) to 1
+ (this is false when x == INT_MIN). */
+ WARN_STRICT_OVERFLOW_CONDITIONAL = 2,
+ /* Overflow warning about changes to comparisons other than folding
+ them to a constant. Example: folding (x + 1 > 1) to (x > 0). */
+ WARN_STRICT_OVERFLOW_COMPARISON = 3,
+ /* Overflow warnings not covered by the above cases. Example:
+ folding ((x * 10) / 5) to (x * 2). */
+ WARN_STRICT_OVERFLOW_MISC = 4,
+ /* Overflow warnings about reducing magnitude of constants in
+ comparison. Example: folding (x + 2 > y) to (x + 1 >= y). */
+ WARN_STRICT_OVERFLOW_MAGNITUDE = 5
+};
+
/* The type of an alias set. Code currently assumes that variables of
this type can take the values 0 (the alias set which aliases
everything) and -1 (sometimes indicating that the alias set is
@@ -337,6 +361,31 @@ typedef void (*gt_pointer_operator) (void *, void *);
typedef unsigned char uchar;
#endif
+/* C++11 adds the ability to add "override" after an implementation of a
+ virtual function in a subclass, to:
+ (A) document that this is an override of a virtual function
+ (B) allow the compiler to issue a warning if it isn't (e.g. a mismatch
+ of the type signature).
+
+ Similarly, it allows us to add a "final" to indicate that no subclass
+ may subsequently override the vfunc.
+
+ Provide OVERRIDE and FINAL as macros, allowing us to get these benefits
+ when compiling with C++11 support, but without requiring C++11.
+
+ For gcc, use "-std=c++11" to enable C++11 support; gcc 6 onwards enables
+ this by default (actually GNU++14). */
+
+#if __cplusplus >= 201103
+/* C++11 claims to be available: use it: */
+#define OVERRIDE override
+#define FINAL final
+#else
+/* No C++11 support; leave the macros empty: */
+#define OVERRIDE
+#define FINAL
+#endif
+
/* Most host source files will require the following headers. */
#if !defined (GENERATOR_FILE) && !defined (USED_FOR_TARGET)
#include "machmode.h"
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index c40efcfc2cf..9618a28dadd 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,188 @@
+2016-05-20 Nathan Sidwell <nathan@acm.org>
+
+ * constexpr.c (cxx_bind_parameters_in_call): Avoid gratuitous if
+ ... goto.
+ (cxx_eval_call_expression): Fix comment grammar.
+
+2016-05-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/70572
+ * decl.c (cp_finish_decl): Check do_auto_deduction return value
+ and return immediately in case of erroneous code.
+
+2016-05-19 Marek Polacek <polacek@redhat.com>
+
+ PR c++/71075
+ * pt.c (unify_template_argument_mismatch): Use %qE instead of %qD.
+
+2016-05-19 Jason Merrill <jason@redhat.com>
+
+ PR c++/10200
+ * pt.c (fn_type_unification): Add outer template args if needed.
+ (type_unification_real): Handle getting full args.
+
+2016-05-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/71184
+ * parser.c (cp_parser_operator): For array new/delete, check that
+ cp_parser_require returned a non-NULL token before dereferencing
+ it.
+
+2016-05-19 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * decl.c (finish_enum_value_list): Use the specified mode.
+
+2016-05-18 Jason Merrill <jason@redhat.com>
+
+ * pt.c (value_dependent_expression_p): Tweak new cases to better
+ match the wording in the standard.
+
+2016-05-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/69793
+ * parser.c (cp_parser_template_id): Don't call cp_lexer_peek_nth_token
+ when the previous cp_lexer_peek_token returns CPP_EOF.
+
+2016-05-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/70466
+ * call.c (convert_like_real): Check that we are actually converting
+ from an init list.
+
+2016-05-16 Matthew Wahab <matthew.wahab@arm.com>
+
+ * decl.c (grokdeclarator): Remove errmsg and use of
+ targetm.invalid_return_type.
+ (grokparms): Remove errmsg and use of
+ targetm.invalid_parameter_type.
+
+2016-05-13 Jason Merrill <jason@redhat.com>
+
+ PR c++/10200
+ PR c++/69753
+ * pt.c (tsubst_decl): Use uses_template_parms.
+ (instantiate_template_1): Handle non-dependent calls in templates.
+ (value_dependent_expression_p): Handle BASELINK, FUNCTION_DECL.
+ (type_dependent_expression_p): Only consider innermost template args.
+ (dependent_template_arg_p): Check enclosing class of a template here.
+ (dependent_template_p): Not here.
+ (type_dependent_object_expression_p): New.
+ * typeck.c (finish_class_member_access_expr): Use it.
+ * parser.c (cp_parser_postfix_expression): Use it.
+ (cp_parser_postfix_dot_deref_expression): Use it. Use comptypes
+ to detect the current instantiation.
+ (cp_parser_lookup_name): Really implement DR 141.
+ * search.c (lookup_field_r): Prefer a dependent using-declaration.
+ (any_dependent_bases_p): Split out from...
+ * name-lookup.c (do_class_using_decl): ...here.
+ * call.c (build_new_method_call_1): Use it.
+ * semantics.c (finish_call_expr): 'this' doesn't make a call dependent.
+ * tree.c (non_static_member_function_p): Remove.
+ * typeck2.c (build_x_arrow): Use dependent_scope_p.
+
+ * parser.c (cp_parser_postfix_dot_deref_expression): Use
+ complete_type_or_else for unknown_type_node, too.
+
+2016-05-12 Marek Polacek <polacek@redhat.com>
+
+ PR c/70756
+ * call.c (build_new_op_1): Pass LOC to cp_build_modify_expr.
+ * cp-tree.h (cp_build_modify_expr): Update declaration.
+ (cxx_incomplete_type_error, cxx_incomplete_type_diagnostic): New inline
+ overloads.
+ * cp-ubsan.c (cp_ubsan_dfs_initialize_vtbl_ptrs): Pass INPUT_LOCATION to
+ cp_build_modify_expr.
+ * decl2.c (set_guard): Likewise.
+ (handle_tls_init): Likewise.
+ * init.c (perform_member_init): Likewise.
+ (expand_virtual_init): Likewise.
+ (build_new_1): Likewise.
+ (build_vec_delete_1): Likewise.
+ (get_temp_regvar): Likewise.
+ (build_vec_init): Likewise.
+ * method.c (do_build_copy_assign): Likewise.
+ (assignable_expr): Likewise.
+ * semantics.c (finish_omp_for): Likewise.
+ * typeck.c (cp_build_binary_op): Pass LOCATION to pointer_diff and
+ cp_pointer_int_sum.
+ (cp_pointer_int_sum): Add location parameter. Pass it down to
+ pointer_int_sum.
+ (pointer_diff): Add location parameter. Use it.
+ (build_modify_expr): Pass location down to cp_build_modify_expr.
+ (cp_build_modify_expr): Add location parameter. Use it.
+ (build_x_modify_expr): Pass location down to cp_build_modify_expr.
+ * typeck2.c (cxx_incomplete_type_diagnostic,
+ cxx_incomplete_type_error): Add location parameter.
+
+2016-05-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/71024
+ * decl.c (duplicate_decls): Call diagnose_mismatched_decls.
+
+2016-05-05 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_selection_statement): For RID_SWITCH,
+ pass if_p instead of NULL to cp_parser_implicitly_scoped_statement.
+
+2016-05-04 Marek Polacek <polacek@redhat.com>
+
+ * parser.c (cp_parser_selection_statement): Replace OPT_Wparentheses
+ with OPT_Wdangling_else.
+
+2016-05-03 Martin Sebor <msebor@redhat.com>
+
+ PR c++/66561
+ * tree.c (builtin_valid_in_constant_expr_p): Treat BUILT_IN_FILE,
+ BUILT_IN_FUNCTION, and BUILT_IN_LINE as constant expressions.
+
+2016-05-03 Marek Polacek <polacek@redhat.com>
+
+ PR c/70859
+ * call.c (build_cxx_call): Pass location and vNULL down to
+ check_builtin_function_arguments.
+
+2016-05-03 Richard Biener <rguenther@suse.de>
+
+ * Make-lang.in (cc1plus-checksum.c): For stage-final re-use
+ the checksum from the previous stage.
+
+2016-05-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/62314
+ * typeck.c (finish_class_member_access_expr): When
+ giving a hint about a possibly-misspelled member name,
+ add a fix-it replacement hint.
+
+2016-05-02 Cesar Philippidis <cesar@codesourcery.com>
+
+ * cp-tree.h (finish_omp_clauses): Update prototype.
+ * parser.c (cp_parser_oacc_all_clauses): Update call to
+ finish_omp_clauses.
+ (cp_parser_omp_all_clauses): Likewise.
+ (cp_parser_omp_for_loop): Likewise.
+ (cp_omp_split_clauses): Likewise.
+ (cp_parser_oacc_cache): Likewise.
+ (cp_parser_oacc_loop): Likewise.
+ (cp_parser_omp_declare_target):
+ (cp_parser_cilk_simd_all_clauses): Likewise.
+ (cp_parser_cilk_for): Likewise.
+ * pt.c (tsubst_omp_clauses): Replace allow_fields and declare_simd
+ arguments with enum c_omp_region_type ort.
+ (tsubst_omp_clauses): Update calls to finish_omp_clauses.
+ (tsubst_omp_attribute): Update calls to tsubst_omp_clauses.
+ (tsubst_omp_for_iterator): Update calls to finish_omp_clauses.
+ (tsubst_expr): Update calls to tsubst_omp_clauses.
+ * semantics.c (finish_omp_clauses): Replace bool arguments
+ allow_fields, declare_simd, and is_cilk with bitmask ort.
+ (finish_omp_for): Update call to finish_omp_clauses.
+
+2016-05-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/62314
+ * parser.c (cp_parser_class_head): Capture the start location;
+ use it to emit a fix-it insertion hint when complaining
+ about missing "template <> " in explicit specializations.
+
2016-05-02 Richard Sandiford <richard.sandiford@arm.com>
* init.c (build_new_1): Use shift operators instead of wi:: shifts.
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 8770f6ff1be..625a77c5386 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -90,11 +90,18 @@ c++_OBJS = $(CXX_OBJS) cc1plus-checksum.o cp/g++spec.o
cp-warn = $(STRICT_WARN)
# compute checksum over all object files and the options
+# re-use the checksum from the prev-final stage so it passes
+# the bootstrap comparison and allows comparing of the cc1 binary
cc1plus-checksum.c : build/genchecksum$(build_exeext) checksum-options \
$(CXX_OBJS) $(BACKEND) $(LIBDEPS)
- build/genchecksum$(build_exeext) $(CXX_OBJS) $(BACKEND) $(LIBDEPS) \
+ if [ -f ../stage_final ] \
+ && cmp -s ../stage_current ../stage_final; then \
+ cp ../prev-gcc/cc1plus-checksum.c cc1plus-checksum.c; \
+ else \
+ build/genchecksum$(build_exeext) $(CXX_OBJS) $(BACKEND) $(LIBDEPS) \
checksum-options > cc1plus-checksum.c.tmp && \
- $(srcdir)/../move-if-change cc1plus-checksum.c.tmp cc1plus-checksum.c
+ $(srcdir)/../move-if-change cc1plus-checksum.c.tmp cc1plus-checksum.c; \
+ fi
cc1plus$(exeext): $(CXX_OBJS) cc1plus-checksum.o $(BACKEND) $(LIBDEPS)
+$(LLINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ \
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 476e806d419..729b7eb4ba3 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -5757,7 +5757,7 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1,
switch (code)
{
case MODIFY_EXPR:
- return cp_build_modify_expr (arg1, code2, arg2, complain);
+ return cp_build_modify_expr (loc, arg1, code2, arg2, complain);
case INDIRECT_REF:
return cp_build_indirect_ref (arg1, RO_UNARY_STAR, complain);
@@ -6377,8 +6377,9 @@ convert_like_real (conversion *convs, tree expr, tree fn, int argnum,
/* When converting from an init list we consider explicit
constructors, but actually trying to call one is an error. */
if (DECL_NONCONVERTING_P (convfn) && DECL_CONSTRUCTOR_P (convfn)
+ && BRACE_ENCLOSED_INITIALIZER_P (expr)
/* Unless this is for direct-list-initialization. */
- && !DIRECT_LIST_INIT_P (expr)
+ && !CONSTRUCTOR_IS_DIRECT_INIT (expr)
/* And in C++98 a default constructor can't be explicit. */
&& cxx_dialect >= cxx11)
{
@@ -7790,7 +7791,8 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
for (i = 0; i < nargs; i++)
argarray[i] = fold_non_dependent_expr (argarray[i]);
- if (!check_builtin_function_arguments (fndecl, nargs, argarray))
+ if (!check_builtin_function_arguments (EXPR_LOCATION (fn), vNULL, fndecl,
+ nargs, argarray))
return error_mark_node;
}
@@ -8406,6 +8408,9 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
we know we really need it. */
cand->first_arg = instance;
}
+ else if (any_dependent_bases_p ())
+ /* We can't tell until instantiation time whether we can use
+ *this as the implicit object argument. */;
else
{
if (complain & tf_error)
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c
index 6054d1a9e3f..7b562605b7b 100644
--- a/gcc/cp/constexpr.c
+++ b/gcc/cp/constexpr.c
@@ -1201,18 +1201,18 @@ cxx_bind_parameters_in_call (const constexpr_ctx *ctx, tree t,
/* Just discard ellipsis args after checking their constantitude. */
if (!parms)
continue;
- if (*non_constant_p)
- /* Don't try to adjust the type of non-constant args. */
- goto next;
-
- /* Make sure the binding has the same type as the parm. */
- if (TREE_CODE (type) != REFERENCE_TYPE)
- arg = adjust_temp_type (type, arg);
- if (!TREE_CONSTANT (arg))
- *non_constant_args = true;
- *p = build_tree_list (parms, arg);
- p = &TREE_CHAIN (*p);
- next:
+
+ if (!*non_constant_p)
+ {
+ /* Make sure the binding has the same type as the parm. But
+ only for constant args. */
+ if (TREE_CODE (type) != REFERENCE_TYPE)
+ arg = adjust_temp_type (type, arg);
+ if (!TREE_CONSTANT (arg))
+ *non_constant_args = true;
+ *p = build_tree_list (parms, arg);
+ p = &TREE_CHAIN (*p);
+ }
parms = TREE_CHAIN (parms);
}
}
@@ -1420,7 +1420,7 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t,
*slot = entry = ggc_alloc<constexpr_call> ();
*entry = new_call;
}
- /* Calls which are in progress have their result set to NULL
+ /* Calls that are in progress have their result set to NULL,
so that we can detect circular dependencies. */
else if (entry->result == NULL)
{
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 8a06609dc04..ad21cdf8334 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -6125,6 +6125,7 @@ extern bool any_dependent_template_arguments_p (const_tree);
extern bool dependent_template_p (tree);
extern bool dependent_template_id_p (tree, tree);
extern bool type_dependent_expression_p (tree);
+extern bool type_dependent_object_expression_p (tree);
extern bool any_type_dependent_arguments_p (const vec<tree, va_gc> *);
extern bool any_type_dependent_elements_p (const_tree);
extern bool type_dependent_expression_p_push (tree);
@@ -6233,6 +6234,7 @@ extern tree adjust_result_of_qualified_name_lookup
extern tree copied_binfo (tree, tree);
extern tree original_binfo (tree, tree);
extern int shared_member_p (tree);
+extern bool any_dependent_bases_p (tree = current_nonlambda_class_type ());
/* The representation of a deferred access check. */
@@ -6399,8 +6401,7 @@ extern tree omp_reduction_id (enum tree_code, tree, tree);
extern tree cp_remove_omp_priv_cleanup_stmt (tree *, int *, void *);
extern void cp_check_omp_declare_reduction (tree);
extern void finish_omp_declare_simd_methods (tree);
-extern tree finish_omp_clauses (tree, bool, bool = false,
- bool = false);
+extern tree finish_omp_clauses (tree, enum c_omp_region_type);
extern tree push_omp_privatization_clauses (bool);
extern void pop_omp_privatization_clauses (tree);
extern void save_omp_privatization_clauses (vec<tree> &);
@@ -6526,7 +6527,6 @@ extern tree get_first_fn (tree);
extern tree ovl_cons (tree, tree);
extern tree build_overload (tree, tree);
extern tree ovl_scope (tree);
-extern bool non_static_member_function_p (tree);
extern const char *cxx_printable_name (tree, int);
extern const char *cxx_printable_name_translate (tree, int);
extern tree build_exception_variant (tree, tree);
@@ -6667,7 +6667,8 @@ extern tree cp_build_c_cast (tree, tree, tsubst_flags_t);
extern cp_expr build_x_modify_expr (location_t, tree,
enum tree_code, tree,
tsubst_flags_t);
-extern tree cp_build_modify_expr (tree, enum tree_code, tree,
+extern tree cp_build_modify_expr (location_t, tree,
+ enum tree_code, tree,
tsubst_flags_t);
extern tree convert_for_initialization (tree, tree, tree, int,
impl_conv_rhs, tree, int,
@@ -6727,11 +6728,24 @@ extern tree finish_binary_fold_expr (tree, tree, int);
/* in typeck2.c */
extern void require_complete_eh_spec_types (tree, tree);
-extern void cxx_incomplete_type_diagnostic (const_tree, const_tree, diagnostic_t);
-#undef cxx_incomplete_type_error
-extern void cxx_incomplete_type_error (const_tree, const_tree);
-#define cxx_incomplete_type_error(V,T) \
- (cxx_incomplete_type_diagnostic ((V), (T), DK_ERROR))
+extern void cxx_incomplete_type_diagnostic (location_t, const_tree,
+ const_tree, diagnostic_t);
+inline void
+cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
+ diagnostic_t diag_kind)
+{
+ cxx_incomplete_type_diagnostic (EXPR_LOC_OR_LOC (value, input_location),
+ value, type, diag_kind);
+}
+
+extern void cxx_incomplete_type_error (location_t, const_tree,
+ const_tree);
+inline void
+cxx_incomplete_type_error (const_tree value, const_tree type)
+{
+ cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
+}
+
extern void cxx_incomplete_type_inform (const_tree);
extern tree error_not_base_type (tree, tree);
extern tree binfo_or_else (tree, tree);
diff --git a/gcc/cp/cp-ubsan.c b/gcc/cp/cp-ubsan.c
index be24a5ca5c8..9c8f6e67d54 100644
--- a/gcc/cp/cp-ubsan.c
+++ b/gcc/cp/cp-ubsan.c
@@ -299,8 +299,8 @@ cp_ubsan_dfs_initialize_vtbl_ptrs (tree binfo, void *data)
/* Assign NULL to the vptr. */
tree vtbl = build_zero_cst (TREE_TYPE (vtbl_ptr));
- tree stmt = cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
- tf_warning_or_error);
+ tree stmt = cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
+ vtbl, tf_warning_or_error);
if (vptr_via_virtual_p (binfo))
/* If this vptr comes from a virtual base of the complete object, only
clear it if we're in charge of virtual bases. */
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5f9031f0664..7a69711bdb1 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -1389,38 +1389,14 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
if (DECL_P (olddecl)
&& TREE_CODE (newdecl) == FUNCTION_DECL
&& TREE_CODE (olddecl) == FUNCTION_DECL
- && (DECL_UNINLINABLE (newdecl) || DECL_UNINLINABLE (olddecl)))
- {
- if (DECL_DECLARED_INLINE_P (newdecl)
- && DECL_UNINLINABLE (newdecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
- /* Already warned elsewhere. */;
- else if (DECL_DECLARED_INLINE_P (olddecl)
- && DECL_UNINLINABLE (olddecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
- /* Already warned. */;
- else if (DECL_DECLARED_INLINE_P (newdecl)
- && DECL_UNINLINABLE (olddecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
- {
- if (warning_at (DECL_SOURCE_LOCATION (newdecl),
- OPT_Wattributes, "function %qD redeclared as inline",
- newdecl))
- inform (DECL_SOURCE_LOCATION (olddecl),
- "previous declaration of %qD with attribute noinline",
- olddecl);
- }
- else if (DECL_DECLARED_INLINE_P (olddecl)
- && DECL_UNINLINABLE (newdecl)
- && lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
- {
- if (warning_at (DECL_SOURCE_LOCATION (newdecl),
- OPT_Wattributes, "function %qD redeclared with "
- "attribute noinline", newdecl))
- inform (DECL_SOURCE_LOCATION (olddecl),
- "previous declaration of %qD was inline",
- olddecl);
- }
+ && diagnose_mismatched_attributes (olddecl, newdecl))
+ {
+ if (DECL_INITIAL (olddecl))
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous definition of %q+D was here", olddecl);
+ else
+ inform (DECL_SOURCE_LOCATION (olddecl),
+ "previous declaration of %qD was here", olddecl);
}
/* Check for redeclaration and other discrepancies. */
@@ -6633,6 +6609,13 @@ cp_finish_decl (tree decl, tree init, bool init_const_expr_p,
adc_variable_type);
if (type == error_mark_node)
return;
+ if (TREE_CODE (type) == FUNCTION_TYPE)
+ {
+ error ("initializer for %<decltype(auto) %D%> has function type "
+ "(did you forget the %<()%> ?)", decl);
+ TREE_TYPE (decl) = error_mark_node;
+ return;
+ }
cp_apply_type_quals_to_decl (cp_type_quals (type), decl);
}
@@ -9271,7 +9254,6 @@ grokdeclarator (const cp_declarator *declarator,
bool late_return_type_p = false;
bool array_parameter_p = false;
source_location saved_loc = input_location;
- const char *errmsg;
tree reqs = NULL_TREE;
signed_p = decl_spec_seq_has_spec_p (declspecs, ds_signed);
@@ -10071,12 +10053,6 @@ grokdeclarator (const cp_declarator *declarator,
decl, but to its return type. */
type_quals = TYPE_UNQUALIFIED;
}
- errmsg = targetm.invalid_return_type (type);
- if (errmsg)
- {
- error (errmsg);
- type = integer_type_node;
- }
/* Error about some types functions can't return. */
@@ -11422,7 +11398,8 @@ grokdeclarator (const cp_declarator *declarator,
}
else if (current_function_decl)
{
- /* FIXME need arm citation */
+ /* 7.1.1: There can be no static function declarations within a
+ block. */
error ("cannot declare static function inside another function");
invalid_static = 1;
}
@@ -11709,7 +11686,6 @@ grokparms (tree parmlist, tree *parms)
tree type = NULL_TREE;
tree init = TREE_PURPOSE (parm);
tree decl = TREE_VALUE (parm);
- const char *errmsg;
if (parm == void_list_node)
break;
@@ -11752,14 +11728,6 @@ grokparms (tree parmlist, tree *parms)
init = NULL_TREE;
}
- if (type != error_mark_node
- && (errmsg = targetm.invalid_parameter_type (type)))
- {
- error (errmsg);
- type = error_mark_node;
- TREE_TYPE (decl) = error_mark_node;
- }
-
if (type != error_mark_node)
{
if (deprecated_state != DEPRECATED_SUPPRESS)
@@ -13385,6 +13353,19 @@ finish_enum_value_list (tree enumtype)
use_short_enum = flag_short_enums
|| lookup_attribute ("packed", TYPE_ATTRIBUTES (enumtype));
+ /* If the precision of the type was specified with an attribute and it
+ was too small, give an error. Otherwise, use it. */
+ if (TYPE_PRECISION (enumtype))
+ {
+ if (precision > TYPE_PRECISION (enumtype))
+ error ("specified mode too small for enumeral values");
+ else
+ {
+ use_short_enum = true;
+ precision = TYPE_PRECISION (enumtype);
+ }
+ }
+
for (itk = (use_short_enum ? itk_char : itk_int);
itk != itk_none;
itk++)
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 0ea326d7699..22f9eded291 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3161,7 +3161,7 @@ set_guard (tree guard)
guard_init = integer_one_node;
if (!same_type_p (TREE_TYPE (guard_init), TREE_TYPE (guard)))
guard_init = fold_convert (TREE_TYPE (guard), guard_init);
- return cp_build_modify_expr (guard, NOP_EXPR, guard_init,
+ return cp_build_modify_expr (input_location, guard, NOP_EXPR, guard_init,
tf_warning_or_error);
}
@@ -4346,7 +4346,8 @@ handle_tls_init (void)
tree cond = cp_build_unary_op (TRUTH_NOT_EXPR, guard, false,
tf_warning_or_error);
finish_if_stmt_cond (cond, if_stmt);
- finish_expr_stmt (cp_build_modify_expr (guard, NOP_EXPR, boolean_true_node,
+ finish_expr_stmt (cp_build_modify_expr (loc, guard, NOP_EXPR,
+ boolean_true_node,
tf_warning_or_error));
for (; vars; vars = TREE_CHAIN (vars))
{
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 681ca12c62a..8e7541fcf98 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -798,7 +798,8 @@ perform_member_init (tree member, tree init)
tf_warning_or_error);
if (init)
- finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
+ finish_expr_stmt (cp_build_modify_expr (input_location, decl,
+ INIT_EXPR, init,
tf_warning_or_error));
}
@@ -1254,8 +1255,8 @@ expand_virtual_init (tree binfo, tree decl)
/* Assign the vtable to the vptr. */
vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0, tf_warning_or_error);
- finish_expr_stmt (cp_build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl,
- tf_warning_or_error));
+ finish_expr_stmt (cp_build_modify_expr (input_location, vtbl_ptr, NOP_EXPR,
+ vtbl, tf_warning_or_error));
}
/* If an exception is thrown in a constructor, those base classes already
@@ -3208,8 +3209,8 @@ build_new_1 (vec<tree, va_gc> **placement, tree type, tree nelts,
ie = build_x_compound_expr_from_vec (*init, "new initializer",
complain);
- init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
- complain);
+ init_expr = cp_build_modify_expr (input_location, init_expr,
+ INIT_EXPR, ie, complain);
}
stable = stabilize_init (init_expr, &init_preeval_expr);
}
@@ -3596,7 +3597,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
tbase = create_temporary_var (ptype);
tbase_init
- = cp_build_modify_expr (tbase, NOP_EXPR,
+ = cp_build_modify_expr (input_location, tbase, NOP_EXPR,
fold_build_pointer_plus_loc (input_location,
fold_convert (ptype,
base),
@@ -3613,7 +3614,7 @@ build_vec_delete_1 (tree base, tree maxindex, tree type,
fold_convert (ptype, base)));
tmp = fold_build1_loc (input_location, NEGATE_EXPR, sizetype, size_exp);
tmp = fold_build_pointer_plus (tbase, tmp);
- tmp = cp_build_modify_expr (tbase, NOP_EXPR, tmp, complain);
+ tmp = cp_build_modify_expr (input_location, tbase, NOP_EXPR, tmp, complain);
if (tmp == error_mark_node)
return error_mark_node;
body = build_compound_expr (input_location, body, tmp);
@@ -3735,8 +3736,8 @@ get_temp_regvar (tree type, tree init)
decl = create_temporary_var (type);
add_decl_expr (decl);
- finish_expr_stmt (cp_build_modify_expr (decl, INIT_EXPR, init,
- tf_warning_or_error));
+ finish_expr_stmt (cp_build_modify_expr (input_location, decl, INIT_EXPR,
+ init, tf_warning_or_error));
return decl;
}
@@ -4000,8 +4001,8 @@ build_vec_init (tree base, tree maxindex, tree init,
else if (MAYBE_CLASS_TYPE_P (type) || TREE_CODE (type) == ARRAY_TYPE)
one_init = build_aggr_init (baseref, elt, 0, complain);
else
- one_init = cp_build_modify_expr (baseref, NOP_EXPR,
- elt, complain);
+ one_init = cp_build_modify_expr (input_location, baseref,
+ NOP_EXPR, elt, complain);
if (one_init == error_mark_node)
errors = true;
if (try_const)
@@ -4128,12 +4129,12 @@ build_vec_init (tree base, tree maxindex, tree init,
from = NULL_TREE;
if (from_array == 2)
- elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
- complain);
+ elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR,
+ from, complain);
else if (type_build_ctor_call (type))
elt_init = build_aggr_init (to, from, 0, complain);
else if (from)
- elt_init = cp_build_modify_expr (to, NOP_EXPR, from,
+ elt_init = cp_build_modify_expr (input_location, to, NOP_EXPR, from,
complain);
else
gcc_unreachable ();
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 0e501d9045a..310e7ebe728 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -741,7 +741,7 @@ do_build_copy_assign (tree fndecl)
init = move (init);
if (DECL_NAME (field))
- init = cp_build_modify_expr (comp, NOP_EXPR, init,
+ init = cp_build_modify_expr (input_location, comp, NOP_EXPR, init,
tf_warning_or_error);
else
init = build2 (MODIFY_EXPR, TREE_TYPE (comp), comp, init);
@@ -1023,7 +1023,7 @@ assignable_expr (tree to, tree from)
++cp_unevaluated_operand;
to = build_stub_object (to);
from = build_stub_object (from);
- tree r = cp_build_modify_expr (to, NOP_EXPR, from, tf_none);
+ tree r = cp_build_modify_expr (input_location, to, NOP_EXPR, from, tf_none);
--cp_unevaluated_operand;
return r;
}
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 86d260c83c1..d32a1532e1a 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -3333,8 +3333,6 @@ do_class_using_decl (tree scope, tree name)
/* True if any of the bases of CURRENT_CLASS_TYPE are dependent. */
bool bases_dependent_p;
tree binfo;
- tree base_binfo;
- int i;
if (name == error_mark_node)
return NULL_TREE;
@@ -3371,16 +3369,7 @@ do_class_using_decl (tree scope, tree name)
|| (IDENTIFIER_TYPENAME_P (name)
&& dependent_type_p (TREE_TYPE (name))));
- bases_dependent_p = false;
- if (processing_template_decl)
- for (binfo = TYPE_BINFO (current_class_type), i = 0;
- BINFO_BASE_ITERATE (binfo, i, base_binfo);
- i++)
- if (dependent_type_p (TREE_TYPE (base_binfo)))
- {
- bases_dependent_p = true;
- break;
- }
+ bases_dependent_p = any_dependent_bases_p ();
decl = NULL_TREE;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index ded0dee6b5f..076e7f36847 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -6851,7 +6851,7 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
tree fn = TREE_OPERAND (postfix_expression, 1);
if (processing_template_decl
- && (type_dependent_expression_p (instance)
+ && (type_dependent_object_expression_p (instance)
|| (!BASELINK_P (fn)
&& TREE_CODE (fn) != FIELD_DECL)
|| type_dependent_expression_p (fn)
@@ -7186,8 +7186,9 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
if (token_type == CPP_DEREF)
postfix_expression = build_x_arrow (location, postfix_expression,
tf_warning_or_error);
- /* Check to see whether or not the expression is type-dependent. */
- dependent_p = type_dependent_expression_p (postfix_expression);
+ /* Check to see whether or not the expression is type-dependent and
+ not the current instantiation. */
+ dependent_p = type_dependent_object_expression_p (postfix_expression);
/* The identifier following the `->' or `.' is not qualified. */
parser->scope = NULL_TREE;
parser->qualifying_scope = NULL_TREE;
@@ -7207,18 +7208,15 @@ cp_parser_postfix_dot_deref_expression (cp_parser *parser,
underlying type here. */
scope = non_reference (scope);
/* The type of the POSTFIX_EXPRESSION must be complete. */
- if (scope == unknown_type_node)
- {
- error_at (location, "%qE does not have class type",
- postfix_expression.get_value ());
- scope = NULL_TREE;
- }
/* Unlike the object expression in other contexts, *this is not
required to be of complete type for purposes of class member
access (5.2.5) outside the member function body. */
- else if (postfix_expression != current_class_ref
- && !(processing_template_decl && scope == current_class_type))
- scope = complete_type_or_else (scope, NULL_TREE);
+ if (postfix_expression != current_class_ref
+ && !(processing_template_decl
+ && current_class_type
+ && (same_type_ignoring_top_level_qualifiers_p
+ (scope, current_class_type))))
+ scope = complete_type_or_else (scope, postfix_expression);
/* Let the name lookup machinery know that we are processing a
class member access expression. */
parser->context->object_type = scope;
@@ -10951,7 +10949,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
statement which does have an else clause. We warn
about the potential ambiguity. */
if (nested_if)
- warning_at (EXPR_LOCATION (statement), OPT_Wparentheses,
+ warning_at (EXPR_LOCATION (statement), OPT_Wdangling_else,
"suggest explicit braces to avoid ambiguous"
" %<else%>");
if (warn_duplicated_cond)
@@ -10978,7 +10976,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
in_statement = parser->in_statement;
parser->in_switch_statement_p = true;
parser->in_statement |= IN_SWITCH_STMT;
- cp_parser_implicitly_scoped_statement (parser, NULL,
+ cp_parser_implicitly_scoped_statement (parser, if_p,
guard_tinfo);
parser->in_switch_statement_p = in_switch_statement_p;
parser->in_statement = in_statement;
@@ -13793,8 +13791,9 @@ cp_parser_operator (cp_parser* parser)
/* Consume the `[' token. */
cp_lexer_consume_token (parser->lexer);
/* Look for the `]' token. */
- end_loc = cp_parser_require (parser, CPP_CLOSE_SQUARE,
- RT_CLOSE_SQUARE)->location;
+ if (cp_token *close_token
+ = cp_parser_require (parser, CPP_CLOSE_SQUARE, RT_CLOSE_SQUARE))
+ end_loc = close_token->location;
id = ansi_opname (op == NEW_EXPR
? VEC_NEW_EXPR : VEC_DELETE_EXPR);
}
@@ -14837,11 +14836,11 @@ cp_parser_template_id (cp_parser *parser,
/* If we find the sequence `[:' after a template-name, it's probably
a digraph-typo for `< ::'. Substitute the tokens and check if we can
parse correctly the argument list. */
- next_token = cp_lexer_peek_token (parser->lexer);
- next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2);
- if (next_token->type == CPP_OPEN_SQUARE
+ if (((next_token = cp_lexer_peek_token (parser->lexer))->type
+ == CPP_OPEN_SQUARE)
&& next_token->flags & DIGRAPH
- && next_token_2->type == CPP_COLON
+ && ((next_token_2 = cp_lexer_peek_nth_token (parser->lexer, 2))->type
+ == CPP_COLON)
&& !(next_token_2->flags & PREV_WHITE))
{
cp_parser_parse_tentatively (parser);
@@ -21656,6 +21655,8 @@ cp_parser_class_head (cp_parser* parser,
if (class_key == none_type)
return error_mark_node;
+ location_t class_head_start_location = input_location;
+
/* Parse the attributes. */
attributes = cp_parser_attributes_opt (parser);
@@ -21872,8 +21873,20 @@ cp_parser_class_head (cp_parser* parser,
&& parser->num_template_parameter_lists == 0
&& template_id_p)
{
- error_at (type_start_token->location,
- "an explicit specialization must be preceded by %<template <>%>");
+ /* Build a location of this form:
+ struct typename <ARGS>
+ ^~~~~~~~~~~~~~~~~~~~~~
+ with caret==start at the start token, and
+ finishing at the end of the type. */
+ location_t reported_loc
+ = make_location (class_head_start_location,
+ class_head_start_location,
+ get_finish (type_start_token->location));
+ rich_location richloc (line_table, reported_loc);
+ richloc.add_fixit_insert (class_head_start_location, "template <> ");
+ error_at_rich_loc
+ (&richloc,
+ "an explicit specialization must be preceded by %<template <>%>");
invalid_explicit_specialization_p = true;
/* Take the same action that would have been taken by
cp_parser_explicit_specialization. */
@@ -24798,24 +24811,11 @@ cp_parser_lookup_name (cp_parser *parser, tree name,
decl = NULL_TREE;
if (!decl)
- {
- /* Look it up in the enclosing context. */
- decl = lookup_name_real (name, tag_type != none_type,
- /*nonclass=*/0,
- /*block_p=*/true, is_namespace, 0);
- /* DR 141 says when looking for a template-name after -> or ., only
- consider class templates. We need to fix our handling of
- dependent expressions to implement that properly, but for now
- let's ignore namespace-scope function templates. */
- if (decl && is_template && !DECL_TYPE_TEMPLATE_P (decl))
- {
- tree d = decl;
- if (is_overloaded_fn (d))
- d = get_first_fn (d);
- if (DECL_P (d) && !DECL_CLASS_SCOPE_P (d))
- decl = NULL_TREE;
- }
- }
+ /* Look it up in the enclosing context. DR 141: When looking for a
+ template-name after -> or ., only consider class templates. */
+ decl = lookup_name_real (name, tag_type != none_type || is_template,
+ /*nonclass=*/0,
+ /*block_p=*/true, is_namespace, 0);
if (object_type == unknown_type_node)
/* The object is type-dependent, so we can't look anything up; we used
this to get the DR 141 behavior. */
@@ -32261,7 +32261,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
cp_parser_skip_to_pragma_eol (parser, pragma_tok);
if (finish_p)
- return finish_omp_clauses (clauses, false);
+ return finish_omp_clauses (clauses, C_ORT_ACC);
return clauses;
}
@@ -32580,9 +32580,9 @@ cp_parser_omp_all_clauses (cp_parser *parser, omp_clause_mask mask,
if (finish_p)
{
if ((mask & (OMP_CLAUSE_MASK_1 << PRAGMA_OMP_CLAUSE_UNIFORM)) != 0)
- return finish_omp_clauses (clauses, false, true);
+ return finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
else
- return finish_omp_clauses (clauses, true);
+ return finish_omp_clauses (clauses, C_ORT_OMP);
}
return clauses;
}
@@ -33657,7 +33657,7 @@ cp_parser_omp_for_loop (cp_parser *parser, enum tree_code code, tree clauses,
else
c = build_omp_clause (loc, OMP_CLAUSE_LASTPRIVATE);
OMP_CLAUSE_DECL (c) = add_private_clause;
- c = finish_omp_clauses (c, true);
+ c = finish_omp_clauses (c, C_ORT_OMP);
if (c)
{
OMP_CLAUSE_CHAIN (c) = clauses;
@@ -33809,7 +33809,7 @@ cp_omp_split_clauses (location_t loc, enum tree_code code,
c_omp_split_clauses (loc, code, mask, clauses, cclauses);
for (i = 0; i < C_OMP_CLAUSE_SPLIT_COUNT; i++)
if (cclauses[i])
- cclauses[i] = finish_omp_clauses (cclauses[i], true);
+ cclauses[i] = finish_omp_clauses (cclauses[i], C_ORT_OMP);
}
/* OpenMP 4.0:
@@ -35092,7 +35092,7 @@ cp_parser_oacc_cache (cp_parser *parser, cp_token *pragma_tok)
tree stmt, clauses;
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE__CACHE_, NULL_TREE);
- clauses = finish_omp_clauses (clauses, false);
+ clauses = finish_omp_clauses (clauses, C_ORT_ACC);
cp_parser_require_pragma_eol (parser, cp_lexer_peek_token (parser->lexer));
@@ -35419,9 +35419,9 @@ cp_parser_oacc_loop (cp_parser *parser, cp_token *pragma_tok, char *p_name,
{
clauses = c_oacc_split_loop_clauses (clauses, cclauses, is_parallel);
if (*cclauses)
- *cclauses = finish_omp_clauses (*cclauses, false);
+ *cclauses = finish_omp_clauses (*cclauses, C_ORT_ACC);
if (clauses)
- clauses = finish_omp_clauses (clauses, false);
+ clauses = finish_omp_clauses (clauses, C_ORT_ACC);
}
tree block = begin_omp_structured_block ();
@@ -35786,7 +35786,7 @@ cp_parser_omp_declare_target (cp_parser *parser, cp_token *pragma_tok)
{
clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE_TO_DECLARE,
clauses);
- clauses = finish_omp_clauses (clauses, true);
+ clauses = finish_omp_clauses (clauses, C_ORT_OMP);
cp_parser_require_pragma_eol (parser, pragma_tok);
}
else
@@ -37726,7 +37726,7 @@ cp_parser_cilk_simd_all_clauses (cp_parser *parser, cp_token *pragma_token)
if (clauses == error_mark_node)
return error_mark_node;
else
- return finish_omp_clauses (clauses, false, false, true);
+ return finish_omp_clauses (clauses, C_ORT_CILK);
}
/* Main entry-point for parsing Cilk Plus <#pragma simd> for loops. */
@@ -37771,7 +37771,7 @@ cp_parser_cilk_for (cp_parser *parser, tree grain, bool *if_p)
tree clauses = build_omp_clause (EXPR_LOCATION (grain), OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (clauses) = OMP_CLAUSE_SCHEDULE_CILKFOR;
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clauses) = grain;
- clauses = finish_omp_clauses (clauses, false);
+ clauses = finish_omp_clauses (clauses, C_ORT_CILK);
tree ret = cp_parser_omp_for_loop (parser, CILK_FOR, clauses, NULL, if_p);
if (ret)
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 2d033e3771a..2bba571b97e 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -6165,7 +6165,7 @@ unify_template_argument_mismatch (bool explain_p, tree parm, tree arg)
{
if (explain_p)
inform (input_location,
- " template argument %qE does not match %qD", arg, parm);
+ " template argument %qE does not match %qE", arg, parm);
return 1;
}
@@ -9563,7 +9563,8 @@ can_complete_type_without_circularity (tree type)
return 1;
}
-static tree tsubst_omp_clauses (tree, bool, bool, tree, tsubst_flags_t, tree);
+static tree tsubst_omp_clauses (tree, enum c_omp_region_type, tree,
+ tsubst_flags_t, tree);
/* Instantiate a single dependent attribute T (a TREE_LIST), and return either
T or a new TREE_LIST, possibly a chain in the case of a pack expansion. */
@@ -9582,10 +9583,10 @@ tsubst_attribute (tree t, tree *decl_p, tree args,
get_attribute_name (t)))
{
tree clauses = TREE_VALUE (val);
- clauses = tsubst_omp_clauses (clauses, true, false, args,
+ clauses = tsubst_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD, args,
complain, in_decl);
c_omp_declare_simd_clauses_to_decls (*decl_p, clauses);
- clauses = finish_omp_clauses (clauses, false, true);
+ clauses = finish_omp_clauses (clauses, C_ORT_OMP_DECLARE_SIMD);
tree parms = DECL_ARGUMENTS (*decl_p);
clauses
= c_omp_declare_simd_clauses_to_numbers (parms, clauses);
@@ -11699,16 +11700,9 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain)
if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL)
{
tree spec;
- bool dependent_p;
- /* If T is not dependent, just return it. We have to
- increment PROCESSING_TEMPLATE_DECL because
- value_dependent_expression_p assumes that nothing is
- dependent when PROCESSING_TEMPLATE_DECL is zero. */
- ++processing_template_decl;
- dependent_p = value_dependent_expression_p (t);
- --processing_template_decl;
- if (!dependent_p)
+ /* If T is not dependent, just return it. */
+ if (!uses_template_parms (DECL_TI_ARGS (t)))
RETURN (t);
/* Calculate the most general template of which R is a
@@ -14535,7 +14529,7 @@ tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain,
/* Like tsubst_copy, but specifically for OpenMP clauses. */
static tree
-tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
+tsubst_omp_clauses (tree clauses, enum c_omp_region_type ort,
tree args, tsubst_flags_t complain, tree in_decl)
{
tree new_clauses = NULL_TREE, nc, oc;
@@ -14685,7 +14679,7 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
default:
gcc_unreachable ();
}
- if (allow_fields)
+ if ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP)
switch (OMP_CLAUSE_CODE (nc))
{
case OMP_CLAUSE_SHARED:
@@ -14747,9 +14741,9 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, bool allow_fields,
}
new_clauses = nreverse (new_clauses);
- if (!declare_simd)
+ if (ort != C_ORT_OMP_DECLARE_SIMD)
{
- new_clauses = finish_omp_clauses (new_clauses, allow_fields);
+ new_clauses = finish_omp_clauses (new_clauses, ort);
if (linear_no_step)
for (nc = new_clauses; nc; nc = OMP_CLAUSE_CHAIN (nc))
if (nc == linear_no_step)
@@ -14970,7 +14964,7 @@ tsubst_omp_for_iterator (tree t, int i, tree declv, tree orig_declv,
{
tree c = build_omp_clause (input_location, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_DECL (c) = decl;
- c = finish_omp_clauses (c, true);
+ c = finish_omp_clauses (c, C_ORT_OMP);
if (c)
{
OMP_CLAUSE_CHAIN (c) = *clauses;
@@ -15452,7 +15446,7 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OACC_KERNELS:
case OACC_PARALLEL:
- tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false, false, args, complain,
+ tmp = tsubst_omp_clauses (OMP_CLAUSES (t), C_ORT_ACC, args, complain,
in_decl);
stmt = begin_omp_parallel ();
RECUR (OMP_BODY (t));
@@ -15461,8 +15455,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_PARALLEL:
r = push_omp_privatization_clauses (OMP_PARALLEL_COMBINED (t));
- tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t), false, true,
- args, complain, in_decl);
+ tmp = tsubst_omp_clauses (OMP_PARALLEL_CLAUSES (t), C_ORT_OMP, args,
+ complain, in_decl);
if (OMP_PARALLEL_COMBINED (t))
omp_parallel_combined_clauses = &tmp;
stmt = begin_omp_parallel ();
@@ -15475,8 +15469,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_TASK:
r = push_omp_privatization_clauses (false);
- tmp = tsubst_omp_clauses (OMP_TASK_CLAUSES (t), false, true,
- args, complain, in_decl);
+ tmp = tsubst_omp_clauses (OMP_TASK_CLAUSES (t), C_ORT_OMP, args,
+ complain, in_decl);
stmt = begin_omp_task ();
RECUR (OMP_TASK_BODY (t));
finish_omp_task (tmp, stmt);
@@ -15495,12 +15489,17 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
tree declv = NULL_TREE, initv = NULL_TREE, condv = NULL_TREE;
tree orig_declv = NULL_TREE;
tree incrv = NULL_TREE;
+ enum c_omp_region_type ort = C_ORT_OMP;
int i;
+ if (TREE_CODE (t) == CILK_SIMD || TREE_CODE (t) == CILK_FOR)
+ ort = C_ORT_CILK;
+ else if (TREE_CODE (t) == OACC_LOOP)
+ ort = C_ORT_ACC;
+
r = push_omp_privatization_clauses (OMP_FOR_INIT (t) == NULL_TREE);
- clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t), false,
- TREE_CODE (t) != OACC_LOOP,
- args, complain, in_decl);
+ clauses = tsubst_omp_clauses (OMP_FOR_CLAUSES (t), ort, args, complain,
+ in_decl);
if (OMP_FOR_INIT (t) != NULL_TREE)
{
declv = make_tree_vec (TREE_VEC_LENGTH (OMP_FOR_INIT (t)));
@@ -15556,8 +15555,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_CRITICAL:
r = push_omp_privatization_clauses (TREE_CODE (t) == OMP_TEAMS
&& OMP_TEAMS_COMBINED (t));
- tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false, true,
- args, complain, in_decl);
+ tmp = tsubst_omp_clauses (OMP_CLAUSES (t), C_ORT_OMP, args, complain,
+ in_decl);
stmt = push_stmt_list ();
RECUR (OMP_BODY (t));
stmt = pop_stmt_list (stmt);
@@ -15572,9 +15571,9 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OACC_DATA:
case OMP_TARGET_DATA:
case OMP_TARGET:
- tmp = tsubst_omp_clauses (OMP_CLAUSES (t), false,
- TREE_CODE (t) != OACC_DATA,
- args, complain, in_decl);
+ tmp = tsubst_omp_clauses (OMP_CLAUSES (t), (TREE_CODE (t) == OACC_DATA)
+ ? C_ORT_ACC : C_ORT_OMP, args, complain,
+ in_decl);
keep_next_level (true);
stmt = begin_omp_structured_block ();
@@ -15619,8 +15618,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OACC_DECLARE:
t = copy_node (t);
- tmp = tsubst_omp_clauses (OACC_DECLARE_CLAUSES (t), false, false,
- args, complain, in_decl);
+ tmp = tsubst_omp_clauses (OACC_DECLARE_CLAUSES (t), C_ORT_ACC, args,
+ complain, in_decl);
OACC_DECLARE_CLAUSES (t) = tmp;
add_stmt (t);
break;
@@ -15628,8 +15627,8 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OMP_TARGET_UPDATE:
case OMP_TARGET_ENTER_DATA:
case OMP_TARGET_EXIT_DATA:
- tmp = tsubst_omp_clauses (OMP_STANDALONE_CLAUSES (t), false, true,
- args, complain, in_decl);
+ tmp = tsubst_omp_clauses (OMP_STANDALONE_CLAUSES (t), C_ORT_OMP, args,
+ complain, in_decl);
t = copy_node (t);
OMP_STANDALONE_CLAUSES (t) = tmp;
add_stmt (t);
@@ -15638,16 +15637,16 @@ tsubst_expr (tree t, tree args, tsubst_flags_t complain, tree in_decl,
case OACC_ENTER_DATA:
case OACC_EXIT_DATA:
case OACC_UPDATE:
- tmp = tsubst_omp_clauses (OMP_STANDALONE_CLAUSES (t), false, false,
- args, complain, in_decl);
+ tmp = tsubst_omp_clauses (OMP_STANDALONE_CLAUSES (t), C_ORT_ACC, args,
+ complain, in_decl);
t = copy_node (t);
OMP_STANDALONE_CLAUSES (t) = tmp;
add_stmt (t);
break;
case OMP_ORDERED:
- tmp = tsubst_omp_clauses (OMP_ORDERED_CLAUSES (t), false, true,
- args, complain, in_decl);
+ tmp = tsubst_omp_clauses (OMP_ORDERED_CLAUSES (t), C_ORT_OMP, args,
+ complain, in_decl);
stmt = push_stmt_list ();
RECUR (OMP_BODY (t));
stmt = pop_stmt_list (stmt);
@@ -17322,12 +17321,14 @@ instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain)
/* Check to see if we already have this specialization. */
gen_tmpl = most_general_template (tmpl);
- if (tmpl != gen_tmpl)
- /* The TMPL is a partial instantiation. To get a full set of
- arguments we must add the arguments used to perform the
- partial instantiation. */
- targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl),
- targ_ptr);
+ if (TMPL_ARGS_DEPTH (targ_ptr)
+ < TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (gen_tmpl)))
+ /* targ_ptr only has the innermost template args, so add the outer ones
+ from tmpl, which could be either a partial instantiation or gen_tmpl (in
+ the case of a non-dependent call within a template definition). */
+ targ_ptr = (add_outermost_template_args
+ (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (tmpl)),
+ targ_ptr));
/* It would be nice to avoid hashing here and then again in tsubst_decl,
but it doesn't seem to be on the hot path. */
@@ -17577,6 +17578,13 @@ fn_type_unification (tree fn,
tree tinst;
tree r = error_mark_node;
+ tree full_targs = targs;
+ if (TMPL_ARGS_DEPTH (targs)
+ < TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (fn)))
+ full_targs = (add_outermost_template_args
+ (DECL_TI_ARGS (DECL_TEMPLATE_RESULT (fn)),
+ targs));
+
if (decltype_p)
complain |= tf_decltype;
@@ -17622,6 +17630,14 @@ fn_type_unification (tree fn,
location_t loc = input_location;
bool incomplete = false;
+ if (explicit_targs == error_mark_node)
+ goto fail;
+
+ if (TMPL_ARGS_DEPTH (explicit_targs)
+ < TMPL_ARGS_DEPTH (full_targs))
+ explicit_targs = add_outermost_template_args (full_targs,
+ explicit_targs);
+
/* Adjust any explicit template arguments before entering the
substitution context. */
explicit_targs
@@ -17701,6 +17717,7 @@ fn_type_unification (tree fn,
goto fail;
/* Place the explicitly specified arguments in TARGS. */
+ explicit_targs = INNERMOST_TEMPLATE_ARGS (explicit_targs);
for (i = NUM_TMPL_ARGS (explicit_targs); i--;)
TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (explicit_targs, i);
}
@@ -17750,7 +17767,7 @@ fn_type_unification (tree fn,
checks = NULL;
ok = !type_unification_real (DECL_INNERMOST_TEMPLATE_PARMS (fn),
- targs, parms, args, nargs, /*subr=*/0,
+ full_targs, parms, args, nargs, /*subr=*/0,
strict, flags, &checks, explain_p);
if (!explain_p)
pop_tinst_level ();
@@ -18246,7 +18263,7 @@ unify_one_argument (tree tparms, tree targs, tree parm, tree arg,
static int
type_unification_real (tree tparms,
- tree targs,
+ tree full_targs,
tree xparms,
const tree *xargs,
unsigned int xnargs,
@@ -18269,6 +18286,8 @@ type_unification_real (tree tparms,
gcc_assert (xparms == NULL_TREE || TREE_CODE (xparms) == TREE_LIST);
gcc_assert (ntparms > 0);
+ tree targs = INNERMOST_TEMPLATE_ARGS (full_targs);
+
/* Reset the number of non-defaulted template arguments contained
in TARGS. */
NON_DEFAULT_TEMPLATE_ARGS_COUNT (targs) = NULL_TREE;
@@ -18303,7 +18322,7 @@ type_unification_real (tree tparms,
arg = args[ia];
++ia;
- if (unify_one_argument (tparms, targs, parm, arg, subr, strict,
+ if (unify_one_argument (tparms, full_targs, parm, arg, subr, strict,
explain_p))
return 1;
}
@@ -18323,7 +18342,7 @@ type_unification_real (tree tparms,
/* Copy the parameter into parmvec. */
TREE_VEC_ELT (parmvec, 0) = TREE_VALUE (parms);
- if (unify_pack_expansion (tparms, targs, parmvec, argvec, strict,
+ if (unify_pack_expansion (tparms, full_targs, parmvec, argvec, strict,
/*subr=*/subr, explain_p))
return 1;
@@ -18484,8 +18503,8 @@ type_unification_real (tree tparms,
location_t save_loc = input_location;
if (DECL_P (parm))
input_location = DECL_SOURCE_LOCATION (parm);
- arg = tsubst_template_arg (arg, targs, complain, NULL_TREE);
- arg = convert_template_argument (parm, arg, targs, complain,
+ arg = tsubst_template_arg (arg, full_targs, complain, NULL_TREE);
+ arg = convert_template_argument (parm, arg, full_targs, complain,
i, NULL_TREE);
input_location = save_loc;
*checks = get_deferred_access_checks ();
@@ -22647,6 +22666,17 @@ value_dependent_expression_p (tree expression)
switch (TREE_CODE (expression))
{
+ case BASELINK:
+ /* A dependent member function of the current instantiation. */
+ return dependent_type_p (BINFO_TYPE (BASELINK_BINFO (expression)));
+
+ case FUNCTION_DECL:
+ /* A dependent member function of the current instantiation. */
+ if (DECL_CLASS_SCOPE_P (expression)
+ && dependent_type_p (DECL_CONTEXT (expression)))
+ return true;
+ break;
+
case IDENTIFIER_NODE:
/* A name that has not been looked up -- must be dependent. */
return true;
@@ -22791,10 +22821,10 @@ value_dependent_expression_p (tree expression)
case CALL_EXPR:
{
+ if (value_dependent_expression_p (CALL_EXPR_FN (expression)))
+ return true;
tree fn = get_callee_fndecl (expression);
int i, nargs;
- if (!fn && value_dependent_expression_p (CALL_EXPR_FN (expression)))
- return true;
nargs = call_expr_nargs (expression);
for (i = 0; i < nargs; ++i)
{
@@ -22958,13 +22988,6 @@ type_dependent_expression_p (tree expression)
|| dependent_scope_p (scope));
}
- /* A function template specialization is type-dependent if it has any
- dependent template arguments. */
- if (TREE_CODE (expression) == FUNCTION_DECL
- && DECL_LANG_SPECIFIC (expression)
- && DECL_TEMPLATE_INFO (expression))
- return any_dependent_template_arguments_p (DECL_TI_ARGS (expression));
-
if (TREE_CODE (expression) == TEMPLATE_DECL
&& !DECL_TEMPLATE_TEMPLATE_PARM_P (expression))
return false;
@@ -23017,13 +23040,18 @@ type_dependent_expression_p (tree expression)
&& DECL_INITIAL (expression))
return true;
- /* A variable template specialization is type-dependent if it has any
- dependent template arguments. */
- if (VAR_P (expression)
+ /* A function or variable template-id is type-dependent if it has any
+ dependent template arguments. Note that we only consider the innermost
+ template arguments here, since those are the ones that come from the
+ template-id; the template arguments for the enclosing class do not make it
+ type-dependent, they only make a member function value-dependent. */
+ if (VAR_OR_FUNCTION_DECL_P (expression)
&& DECL_LANG_SPECIFIC (expression)
&& DECL_TEMPLATE_INFO (expression)
- && variable_template_p (DECL_TI_TEMPLATE (expression)))
- return any_dependent_template_arguments_p (DECL_TI_ARGS (expression));
+ && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (expression))
+ && (any_dependent_template_arguments_p
+ (INNERMOST_TEMPLATE_ARGS (DECL_TI_ARGS (expression)))))
+ return true;
/* Always dependent, on the number of arguments if nothing else. */
if (TREE_CODE (expression) == EXPR_PACK_EXPANSION)
@@ -23081,6 +23109,22 @@ type_dependent_expression_p (tree expression)
return (dependent_type_p (TREE_TYPE (expression)));
}
+/* [temp.dep.expr]/5: A class member access expression (5.2.5) is
+ type-dependent if the expression refers to a member of the current
+ instantiation and the type of the referenced member is dependent, or the
+ class member access expression refers to a member of an unknown
+ specialization.
+
+ This function returns true if the OBJECT in such a class member access
+ expression is of an unknown specialization. */
+
+bool
+type_dependent_object_expression_p (tree object)
+{
+ tree scope = TREE_TYPE (object);
+ return (!scope || dependent_scope_p (scope));
+}
+
/* walk_tree callback function for instantiation_dependent_expression_p,
below. Returns non-zero if a dependent subexpression is found. */
@@ -23285,9 +23329,18 @@ dependent_template_arg_p (tree arg)
if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT)
arg = ARGUMENT_PACK_SELECT_ARG (arg);
- if (TREE_CODE (arg) == TEMPLATE_DECL
- || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
- return dependent_template_p (arg);
+ if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM)
+ return true;
+ if (TREE_CODE (arg) == TEMPLATE_DECL)
+ {
+ if (DECL_TEMPLATE_PARM_P (arg))
+ return true;
+ /* A member template of a dependent class is not necessarily
+ type-dependent, but it is a dependent template argument because it
+ will be a member of an unknown specialization to that template. */
+ tree scope = CP_DECL_CONTEXT (arg);
+ return TYPE_P (scope) && dependent_type_p (scope);
+ }
else if (ARGUMENT_PACK_P (arg))
{
tree args = ARGUMENT_PACK_ARGS (arg);
@@ -23383,7 +23436,7 @@ any_dependent_template_arguments_p (const_tree args)
return false;
}
-/* Returns TRUE if the template TMPL is dependent. */
+/* Returns TRUE if the template TMPL is type-dependent. */
bool
dependent_template_p (tree tmpl)
@@ -23406,9 +23459,6 @@ dependent_template_p (tree tmpl)
/* So are names that have not been looked up. */
if (TREE_CODE (tmpl) == SCOPE_REF || identifier_p (tmpl))
return true;
- /* So are member templates of dependent classes. */
- if (TYPE_P (CP_DECL_CONTEXT (tmpl)))
- return dependent_type_p (DECL_CONTEXT (tmpl));
return false;
}
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 503e34b7f2e..f47833f0686 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1106,6 +1106,14 @@ lookup_field_r (tree binfo, void *data)
if (!nval)
/* Look for a data member or type. */
nval = lookup_field_1 (type, lfi->name, lfi->want_type);
+ else if (TREE_CODE (nval) == OVERLOAD && OVL_USED (nval))
+ {
+ /* If we have both dependent and non-dependent using-declarations, return
+ the dependent one rather than an incomplete list of functions. */
+ tree dep_using = lookup_field_1 (type, lfi->name, lfi->want_type);
+ if (dep_using && TREE_CODE (dep_using) == USING_DECL)
+ nval = dep_using;
+ }
/* If there is no declaration with the indicated name in this type,
then there's nothing to do. */
@@ -2844,3 +2852,21 @@ original_binfo (tree binfo, tree here)
return result;
}
+/* True iff TYPE has any dependent bases (and therefore we can't say
+ definitively that another class is not a base of an instantiation of
+ TYPE). */
+
+bool
+any_dependent_bases_p (tree type)
+{
+ if (!type || !CLASS_TYPE_P (type) || !processing_template_decl)
+ return false;
+
+ unsigned i;
+ tree base_binfo;
+ FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_BINFOS (TYPE_BINFO (type)), i, base_binfo)
+ if (BINFO_DEPENDENT_BASE_P (base_binfo))
+ return true;
+
+ return false;
+}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index 2365a732cbe..06dee5a6669 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -2300,18 +2300,7 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
with no type; type_dependent_expression_p recognizes
expressions with no type as being dependent. */
if (type_dependent_expression_p (fn)
- || any_type_dependent_arguments_p (*args)
- /* For a non-static member function that doesn't have an
- explicit object argument, we need to specifically
- test the type dependency of the "this" pointer because it
- is not included in *ARGS even though it is considered to
- be part of the list of arguments. Note that this is
- related to CWG issues 515 and 1005. */
- || (TREE_CODE (fn) != COMPONENT_REF
- && non_static_member_function_p (fn)
- && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (get_first_fn (fn))
- && current_class_ref
- && type_dependent_expression_p (current_class_ref)))
+ || any_type_dependent_arguments_p (*args))
{
result = build_nt_call_vec (fn, *args);
SET_EXPR_LOCATION (result, EXPR_LOC_OR_LOC (fn, input_location));
@@ -2399,17 +2388,6 @@ finish_call_expr (tree fn, vec<tree, va_gc> **args, bool disallow_virtual,
object = maybe_dummy_object (BINFO_TYPE (BASELINK_ACCESS_BINFO (fn)),
NULL);
- if (processing_template_decl)
- {
- if (type_dependent_expression_p (object))
- {
- tree ret = build_nt_call_vec (orig_fn, orig_args);
- release_tree_vector (orig_args);
- return ret;
- }
- object = build_non_dependent_expr (object);
- }
-
result = build_new_method_call (object, fn, args, NULL_TREE,
(disallow_virtual
? LOOKUP_NORMAL|LOOKUP_NONVIRTUAL
@@ -5793,8 +5771,7 @@ cp_finish_omp_clause_depend_sink (tree sink_clause)
Remove any elements from the list that are invalid. */
tree
-finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
- bool is_cilk)
+finish_omp_clauses (tree clauses, enum c_omp_region_type ort)
{
bitmap_head generic_head, firstprivate_head, lastprivate_head;
bitmap_head aligned_head, map_head, map_field_head;
@@ -5820,17 +5797,18 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
switch (OMP_CLAUSE_CODE (c))
{
case OMP_CLAUSE_SHARED:
- field_ok = allow_fields;
+ field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
goto check_dup_generic;
case OMP_CLAUSE_PRIVATE:
- field_ok = allow_fields;
+ field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
goto check_dup_generic;
case OMP_CLAUSE_REDUCTION:
- field_ok = allow_fields;
+ field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST)
{
- if (handle_omp_array_sections (c, allow_fields))
+ if (handle_omp_array_sections (c, ((ort & C_ORT_OMP_DECLARE_SIMD)
+ == C_ORT_OMP)))
{
remove = true;
break;
@@ -5858,14 +5836,14 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
goto check_dup_generic;
case OMP_CLAUSE_COPYPRIVATE:
copyprivate_seen = true;
- field_ok = allow_fields;
+ field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
goto check_dup_generic;
case OMP_CLAUSE_COPYIN:
goto check_dup_generic;
case OMP_CLAUSE_LINEAR:
- field_ok = allow_fields;
+ field_ok = ((ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP);
t = OMP_CLAUSE_DECL (c);
- if (!declare_simd
+ if (ort != C_ORT_OMP_DECLARE_SIMD
&& OMP_CLAUSE_LINEAR_KIND (c) != OMP_CLAUSE_LINEAR_DEFAULT)
{
error_at (OMP_CLAUSE_LOCATION (c),
@@ -5890,7 +5868,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
}
if (TREE_CODE (type) == REFERENCE_TYPE)
type = TREE_TYPE (type);
- if (is_cilk)
+ if (ort == C_ORT_CILK)
{
if (!INTEGRAL_TYPE_P (type)
&& !SCALAR_FLOAT_TYPE_P (type)
@@ -5925,7 +5903,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
}
else if (!type_dependent_expression_p (t)
&& !INTEGRAL_TYPE_P (TREE_TYPE (t))
- && (!declare_simd
+ && (ort != C_ORT_OMP_DECLARE_SIMD
|| TREE_CODE (t) != PARM_DECL
|| TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE
|| !INTEGRAL_TYPE_P (TREE_TYPE (TREE_TYPE (t)))))
@@ -5937,7 +5915,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
else
{
t = mark_rvalue_use (t);
- if (declare_simd && TREE_CODE (t) == PARM_DECL)
+ if (ort == C_ORT_OMP_DECLARE_SIMD && TREE_CODE (t) == PARM_DECL)
{
OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c) = 1;
goto check_dup_generic;
@@ -5946,7 +5924,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
&& (VAR_P (OMP_CLAUSE_DECL (c))
|| TREE_CODE (OMP_CLAUSE_DECL (c)) == PARM_DECL))
{
- if (declare_simd)
+ if (ort == C_ORT_OMP_DECLARE_SIMD)
{
t = maybe_constant_value (t);
if (TREE_CODE (t) != INTEGER_CST)
@@ -5981,7 +5959,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
else if (TREE_CODE (type) == POINTER_TYPE
/* Can't multiply the step yet if *this
is still incomplete type. */
- && (!declare_simd
+ && (ort != C_ORT_OMP_DECLARE_SIMD
|| TREE_CODE (OMP_CLAUSE_DECL (c)) != PARM_DECL
|| !DECL_ARTIFICIAL (OMP_CLAUSE_DECL (c))
|| DECL_NAME (OMP_CLAUSE_DECL (c))
@@ -6018,7 +5996,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
t = OMP_CLAUSE_DECL (c);
check_dup_generic_t:
if (t == current_class_ptr
- && (!declare_simd
+ && (ort != C_ORT_OMP_DECLARE_SIMD
|| (OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE_UNIFORM)))
{
@@ -6084,7 +6062,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
break;
}
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
- && (!allow_fields || TREE_CODE (t) != FIELD_DECL))
+ && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
+ || TREE_CODE (t) != FIELD_DECL))
{
if (processing_template_decl)
break;
@@ -6123,7 +6102,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
break;
}
if (!VAR_P (t) && TREE_CODE (t) != PARM_DECL
- && (!allow_fields || TREE_CODE (t) != FIELD_DECL))
+ && ((ort & C_ORT_OMP_DECLARE_SIMD) != C_ORT_OMP
+ || TREE_CODE (t) != FIELD_DECL))
{
if (processing_template_decl)
break;
@@ -6466,7 +6446,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
case OMP_CLAUSE_ALIGNED:
t = OMP_CLAUSE_DECL (c);
- if (t == current_class_ptr && !declare_simd)
+ if (t == current_class_ptr && ort != C_ORT_OMP_DECLARE_SIMD)
{
error ("%<this%> allowed in OpenMP only in %<declare simd%>"
" clauses");
@@ -6549,7 +6529,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
}
if (TREE_CODE (t) == TREE_LIST)
{
- if (handle_omp_array_sections (c, allow_fields))
+ if (handle_omp_array_sections (c, ((ort & C_ORT_OMP_DECLARE_SIMD)
+ == C_ORT_OMP)))
remove = true;
break;
}
@@ -6583,7 +6564,8 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
t = OMP_CLAUSE_DECL (c);
if (TREE_CODE (t) == TREE_LIST)
{
- if (handle_omp_array_sections (c, allow_fields))
+ if (handle_omp_array_sections (c, ((ort & C_ORT_OMP_DECLARE_SIMD)
+ == C_ORT_OMP)))
remove = true;
else
{
@@ -6638,7 +6620,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
OMP_CLAUSE_DECL (c) = t;
}
if (TREE_CODE (t) == COMPONENT_REF
- && allow_fields
+ && (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
&& OMP_CLAUSE_CODE (c) != OMP_CLAUSE__CACHE_)
{
if (type_dependent_expression_p (t))
@@ -6778,7 +6760,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
handle_map_references:
if (!remove
&& !processing_template_decl
- && allow_fields
+ && (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP
&& TREE_CODE (TREE_TYPE (OMP_CLAUSE_DECL (c))) == REFERENCE_TYPE)
{
t = OMP_CLAUSE_DECL (c);
@@ -6972,7 +6954,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
case OMP_CLAUSE_IS_DEVICE_PTR:
case OMP_CLAUSE_USE_DEVICE_PTR:
- field_ok = allow_fields;
+ field_ok = (ort & C_ORT_OMP_DECLARE_SIMD) == C_ORT_OMP;
t = OMP_CLAUSE_DECL (c);
if (!type_dependent_expression_p (t))
{
@@ -7112,7 +7094,7 @@ finish_omp_clauses (tree clauses, bool allow_fields, bool declare_simd,
need_implicitly_determined = true;
break;
case OMP_CLAUSE_LINEAR:
- if (!declare_simd)
+ if (ort != C_ORT_OMP_DECLARE_SIMD)
need_implicitly_determined = true;
else if (OMP_CLAUSE_LINEAR_VARIABLE_STRIDE (c)
&& !bitmap_bit_p (&map_head,
@@ -8069,7 +8051,7 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
{
if (orig_incr)
TREE_VEC_ELT (orig_incr, i) = incr;
- incr = cp_build_modify_expr (TREE_OPERAND (incr, 0),
+ incr = cp_build_modify_expr (elocus, TREE_OPERAND (incr, 0),
TREE_CODE (TREE_OPERAND (incr, 1)),
TREE_OPERAND (incr, 2),
tf_warning_or_error);
@@ -8103,7 +8085,8 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
if (!processing_template_decl)
{
init = fold_build_cleanup_point_expr (TREE_TYPE (init), init);
- init = cp_build_modify_expr (decl, NOP_EXPR, init, tf_warning_or_error);
+ init = cp_build_modify_expr (elocus, decl, NOP_EXPR, init,
+ tf_warning_or_error);
}
else
init = build2 (MODIFY_EXPR, void_type_node, decl, init);
@@ -8342,7 +8325,7 @@ finish_omp_for (location_t locus, enum tree_code code, tree declv,
OMP_CLAUSE_OPERAND (c, 0)
= cilk_for_number_of_iterations (omp_for);
OMP_CLAUSE_CHAIN (c) = clauses;
- OMP_PARALLEL_CLAUSES (omp_par) = finish_omp_clauses (c, false);
+ OMP_PARALLEL_CLAUSES (omp_par) = finish_omp_clauses (c, C_ORT_CILK);
add_stmt (omp_par);
return omp_par;
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d7e9c7b8048..04702ee1c00 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -346,10 +346,16 @@ builtin_valid_in_constant_expr_p (const_tree decl)
return false;
switch (DECL_FUNCTION_CODE (decl))
{
- case BUILT_IN_CONSTANT_P:
- case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
+ /* These always have constant results like the corresponding
+ macros/symbol. */
+ case BUILT_IN_FILE:
+ case BUILT_IN_FUNCTION:
+ case BUILT_IN_LINE:
+
/* These have constant results even if their operands are
non-constant. */
+ case BUILT_IN_CONSTANT_P:
+ case BUILT_IN_ATOMIC_ALWAYS_LOCK_FREE:
return true;
default:
return false;
@@ -2121,23 +2127,6 @@ ovl_scope (tree ovl)
ovl = OVL_CHAIN (ovl);
return CP_DECL_CONTEXT (OVL_CURRENT (ovl));
}
-
-/* Return TRUE if FN is a non-static member function, FALSE otherwise.
- This function looks into BASELINK and OVERLOAD nodes. */
-
-bool
-non_static_member_function_p (tree fn)
-{
- if (fn == NULL_TREE)
- return false;
-
- if (is_overloaded_fn (fn))
- fn = get_first_fn (fn);
-
- return (DECL_P (fn)
- && DECL_NONSTATIC_MEMBER_FUNCTION_P (fn));
-}
-
#define PRINT_RING_SIZE 4
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7e12009a5e5..cd058fa258e 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -43,13 +43,14 @@ static tree pfn_from_ptrmemfunc (tree);
static tree delta_from_ptrmemfunc (tree);
static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
tsubst_flags_t, int);
-static tree cp_pointer_int_sum (enum tree_code, tree, tree, tsubst_flags_t);
+static tree cp_pointer_int_sum (location_t, enum tree_code, tree, tree,
+ tsubst_flags_t);
static tree rationalize_conditional_expr (enum tree_code, tree,
tsubst_flags_t);
static int comp_ptr_ttypes_real (tree, tree, int);
static bool comp_except_types (tree, tree, bool);
static bool comp_array_types (const_tree, const_tree, bool);
-static tree pointer_diff (tree, tree, tree, tsubst_flags_t);
+static tree pointer_diff (location_t, tree, tree, tree, tsubst_flags_t);
static tree get_delta_difference (tree, tree, bool, bool, tsubst_flags_t);
static void casts_away_constness_r (tree *, tree *, tsubst_flags_t);
static bool casts_away_constness (tree, tree, tsubst_flags_t);
@@ -2667,7 +2668,7 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
if (processing_template_decl)
{
if (/* If OBJECT is dependent, so is OBJECT.NAME. */
- type_dependent_expression_p (object)
+ type_dependent_object_expression_p (object)
/* If NAME is "f<args>", where either 'f' or 'args' is
dependent, then the expression is dependent. */
|| (TREE_CODE (name) == TEMPLATE_ID_EXPR
@@ -2677,9 +2678,12 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
expression is dependent. */
|| (TREE_CODE (name) == SCOPE_REF
&& TYPE_P (TREE_OPERAND (name, 0))
- && dependent_type_p (TREE_OPERAND (name, 0))))
- return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
- object.get_value (), name, NULL_TREE);
+ && dependent_scope_p (TREE_OPERAND (name, 0))))
+ {
+ dependent:
+ return build_min_nt_loc (UNKNOWN_LOCATION, COMPONENT_REF,
+ orig_object, name, NULL_TREE);
+ }
object = build_non_dependent_expr (object);
}
else if (c_dialect_objc ()
@@ -2804,7 +2808,12 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
}
if (TREE_CODE (name) == BIT_NOT_EXPR)
- member = lookup_destructor (object, scope, name, complain);
+ {
+ if (dependent_type_p (object_type))
+ /* The destructor isn't declared yet. */
+ goto dependent;
+ member = lookup_destructor (object, scope, name, complain);
+ }
else
{
/* Look up the member. */
@@ -2812,14 +2821,29 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
/*want_type=*/false, complain);
if (member == NULL_TREE)
{
+ if (dependent_type_p (object_type))
+ /* Try again at instantiation time. */
+ goto dependent;
if (complain & tf_error)
{
tree guessed_id = lookup_member_fuzzy (access_path, name,
/*want_type=*/false);
if (guessed_id)
- error ("%q#T has no member named %qE; did you mean %qE?",
- TREE_CODE (access_path) == TREE_BINFO
- ? TREE_TYPE (access_path) : object_type, name, guessed_id);
+ {
+ location_t bogus_component_loc = input_location;
+ rich_location rich_loc (line_table, bogus_component_loc);
+ source_range bogus_component_range =
+ get_range_from_loc (line_table, bogus_component_loc);
+ rich_loc.add_fixit_replace
+ (bogus_component_range,
+ IDENTIFIER_POINTER (guessed_id));
+ error_at_rich_loc
+ (&rich_loc,
+ "%q#T has no member named %qE; did you mean %qE?",
+ TREE_CODE (access_path) == TREE_BINFO
+ ? TREE_TYPE (access_path) : object_type, name,
+ guessed_id);
+ }
else
error ("%q#T has no member named %qE",
TREE_CODE (access_path) == TREE_BINFO
@@ -2829,6 +2853,8 @@ finish_class_member_access_expr (cp_expr object, tree name, bool template_p,
}
if (member == error_mark_node)
return error_mark_node;
+ if (TREE_CODE (member) == USING_DECL && DECL_DEPENDENT_P (member))
+ goto dependent;
}
if (is_template_id)
@@ -4224,8 +4250,8 @@ cp_build_binary_op (location_t location,
if (code0 == POINTER_TYPE && code1 == POINTER_TYPE
&& same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
TREE_TYPE (type1)))
- return pointer_diff (op0, op1, common_pointer_type (type0, type1),
- complain);
+ return pointer_diff (location, op0, op1,
+ common_pointer_type (type0, type1), complain);
/* In all other cases except pointer - int, the usual arithmetic
rules apply. */
else if (!(code0 == POINTER_TYPE && code1 == INTEGER_TYPE))
@@ -4248,8 +4274,8 @@ cp_build_binary_op (location_t location,
result_type = TREE_TYPE (ptr_operand);
break;
}
- return cp_pointer_int_sum (code,
- ptr_operand,
+ return cp_pointer_int_sum (location, code,
+ ptr_operand,
int_operand,
complain);
}
@@ -5214,8 +5240,8 @@ build_x_vec_perm_expr (location_t loc,
of pointer PTROP and integer INTOP. */
static tree
-cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
- tsubst_flags_t complain)
+cp_pointer_int_sum (location_t loc, enum tree_code resultcode, tree ptrop,
+ tree intop, tsubst_flags_t complain)
{
tree res_type = TREE_TYPE (ptrop);
@@ -5226,7 +5252,7 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
pointer_int_sum() anyway. */
complete_type (TREE_TYPE (res_type));
- return pointer_int_sum (input_location, resultcode, ptrop,
+ return pointer_int_sum (loc, resultcode, ptrop,
intop, complain & tf_warning_or_error);
}
@@ -5234,7 +5260,8 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
The resulting tree has type int. */
static tree
-pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
+pointer_diff (location_t loc, tree op0, tree op1, tree ptrtype,
+ tsubst_flags_t complain)
{
tree result;
tree restype = ptrdiff_type_node;
@@ -5246,7 +5273,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (VOID_TYPE_P (target_type))
{
if (complain & tf_error)
- permerror (input_location, "ISO C++ forbids using pointer of "
+ permerror (loc, "ISO C++ forbids using pointer of "
"type %<void *%> in subtraction");
else
return error_mark_node;
@@ -5254,7 +5281,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (TREE_CODE (target_type) == FUNCTION_TYPE)
{
if (complain & tf_error)
- permerror (input_location, "ISO C++ forbids using pointer to "
+ permerror (loc, "ISO C++ forbids using pointer to "
"a function in subtraction");
else
return error_mark_node;
@@ -5262,7 +5289,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (TREE_CODE (target_type) == METHOD_TYPE)
{
if (complain & tf_error)
- permerror (input_location, "ISO C++ forbids using pointer to "
+ permerror (loc, "ISO C++ forbids using pointer to "
"a method in subtraction");
else
return error_mark_node;
@@ -5271,7 +5298,7 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
/* First do the subtraction as integers;
then drop through to build the divide operator. */
- op0 = cp_build_binary_op (input_location,
+ op0 = cp_build_binary_op (loc,
MINUS_EXPR,
cp_convert (restype, op0, complain),
cp_convert (restype, op1, complain),
@@ -5281,8 +5308,8 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (!COMPLETE_TYPE_P (TREE_TYPE (TREE_TYPE (op1))))
{
if (complain & tf_error)
- error ("invalid use of a pointer to an incomplete type in "
- "pointer arithmetic");
+ error_at (loc, "invalid use of a pointer to an incomplete type in "
+ "pointer arithmetic");
else
return error_mark_node;
}
@@ -5290,19 +5317,19 @@ pointer_diff (tree op0, tree op1, tree ptrtype, tsubst_flags_t complain)
if (pointer_to_zero_sized_aggr_p (TREE_TYPE (op1)))
{
if (complain & tf_error)
- error ("arithmetic on pointer to an empty aggregate");
+ error_at (loc, "arithmetic on pointer to an empty aggregate");
else
return error_mark_node;
}
op1 = (TYPE_PTROB_P (ptrtype)
- ? size_in_bytes (target_type)
+ ? size_in_bytes_loc (loc, target_type)
: integer_one_node);
/* Do the division. */
- result = build2 (EXACT_DIV_EXPR, restype, op0,
- cp_convert (restype, op1, complain));
+ result = build2_loc (loc, EXACT_DIV_EXPR, restype, op0,
+ cp_convert (restype, op1, complain));
return result;
}
@@ -7458,13 +7485,14 @@ cp_build_c_cast (tree type, tree expr, tsubst_flags_t complain)
/* For use from the C common bits. */
tree
-build_modify_expr (location_t /*location*/,
+build_modify_expr (location_t location,
tree lhs, tree /*lhs_origtype*/,
enum tree_code modifycode,
location_t /*rhs_location*/, tree rhs,
tree /*rhs_origtype*/)
{
- return cp_build_modify_expr (lhs, modifycode, rhs, tf_warning_or_error);
+ return cp_build_modify_expr (location, lhs, modifycode, rhs,
+ tf_warning_or_error);
}
/* Build an assignment expression of lvalue LHS from value RHS.
@@ -7475,8 +7503,8 @@ build_modify_expr (location_t /*location*/,
C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed. */
tree
-cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
- tsubst_flags_t complain)
+cp_build_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
+ tree rhs, tsubst_flags_t complain)
{
tree result;
tree newrhs = rhs;
@@ -7498,7 +7526,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
TREE_OPERAND (lhs, 1));
- newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0),
+ newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 0),
modifycode, rhs, complain);
if (newrhs == error_mark_node)
return error_mark_node;
@@ -7506,7 +7534,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
/* Handle (a, b) used as an "lvalue". */
case COMPOUND_EXPR:
- newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 1),
+ newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
modifycode, rhs, complain);
if (newrhs == error_mark_node)
return error_mark_node;
@@ -7518,8 +7546,8 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
lhs = build2 (TREE_CODE (lhs), TREE_TYPE (lhs),
cp_stabilize_reference (TREE_OPERAND (lhs, 0)),
TREE_OPERAND (lhs, 1));
- newrhs = cp_build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs,
- complain);
+ newrhs = cp_build_modify_expr (loc, TREE_OPERAND (lhs, 0), modifycode,
+ rhs, complain);
if (newrhs == error_mark_node)
return error_mark_node;
return build2 (COMPOUND_EXPR, lhstype, lhs, newrhs);
@@ -7568,9 +7596,9 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
cond = build_conditional_expr
(input_location, TREE_OPERAND (lhs, 0),
- cp_build_modify_expr (TREE_OPERAND (lhs, 1),
+ cp_build_modify_expr (loc, TREE_OPERAND (lhs, 1),
modifycode, rhs, complain),
- cp_build_modify_expr (TREE_OPERAND (lhs, 2),
+ cp_build_modify_expr (loc, TREE_OPERAND (lhs, 2),
modifycode, rhs, complain),
complain);
@@ -7668,9 +7696,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs,
lhs = cp_stabilize_reference (lhs);
rhs = rvalue (rhs);
rhs = stabilize_expr (rhs, &init);
- newrhs = cp_build_binary_op (input_location,
- modifycode, lhs, rhs,
- complain);
+ newrhs = cp_build_binary_op (loc, modifycode, lhs, rhs, complain);
if (newrhs == error_mark_node)
{
if (complain & tf_error)
@@ -7881,7 +7907,7 @@ build_x_modify_expr (location_t loc, tree lhs, enum tree_code modifycode,
return rval;
}
}
- return cp_build_modify_expr (lhs, modifycode, rhs, complain);
+ return cp_build_modify_expr (loc, lhs, modifycode, rhs, complain);
}
/* Helper function for get_delta_difference which assumes FROM is a base
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index e59ad51c3bd..833be20f7fe 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -451,8 +451,8 @@ cxx_incomplete_type_inform (const_tree type)
type of diagnostic (see diagnostic.def). */
void
-cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
- diagnostic_t diag_kind)
+cxx_incomplete_type_diagnostic (location_t loc, const_tree value,
+ const_tree type, diagnostic_t diag_kind)
{
bool is_decl = false, complained = false;
@@ -475,8 +475,6 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
retry:
/* We must print an error message. Be clever about what it says. */
- location_t loc = EXPR_LOC_OR_LOC (value, input_location);
-
switch (TREE_CODE (type))
{
case RECORD_TYPE:
@@ -570,13 +568,14 @@ cxx_incomplete_type_diagnostic (const_tree value, const_tree type,
}
}
-/* Backward-compatibility interface to incomplete_type_diagnostic;
- required by ../tree.c. */
-#undef cxx_incomplete_type_error
+/* Print an error message for invalid use of an incomplete type.
+ VALUE is the expression that was used (or 0 if that isn't known)
+ and TYPE is the type that was invalid. */
+
void
-cxx_incomplete_type_error (const_tree value, const_tree type)
+cxx_incomplete_type_error (location_t loc, const_tree value, const_tree type)
{
- cxx_incomplete_type_diagnostic (value, type, DK_ERROR);
+ cxx_incomplete_type_diagnostic (loc, value, type, DK_ERROR);
}
@@ -1704,7 +1703,10 @@ build_x_arrow (location_t loc, tree expr, tsubst_flags_t complain)
if (processing_template_decl)
{
- if (type_dependent_expression_p (expr))
+ if (type && TREE_CODE (type) == POINTER_TYPE
+ && !dependent_scope_p (TREE_TYPE (type)))
+ /* Pointer to current instantiation, don't treat as dependent. */;
+ else if (type_dependent_expression_p (expr))
return build_min_nt_loc (loc, ARROW_EXPR, expr);
expr = build_non_dependent_expr (expr);
}
diff --git a/gcc/cppbuiltin.c b/gcc/cppbuiltin.c
index 6d494add73b..69ccdb91846 100644
--- a/gcc/cppbuiltin.c
+++ b/gcc/cppbuiltin.c
@@ -92,6 +92,9 @@ define_builtin_macros_for_compilation_flags (cpp_reader *pfile)
if (flag_sanitize & SANITIZE_ADDRESS)
cpp_define (pfile, "__SANITIZE_ADDRESS__");
+ if (flag_sanitize & SANITIZE_THREAD)
+ cpp_define (pfile, "__SANITIZE_THREAD__");
+
if (optimize_size)
cpp_define (pfile, "__OPTIMIZE_SIZE__");
if (optimize)
diff --git a/gcc/cse.c b/gcc/cse.c
index 2665d9a2733..bce4fb0262e 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4575,6 +4575,7 @@ cse_insn (rtx_insn *insn)
for (i = 0; i < n_sets; i++)
{
bool repeat = false;
+ bool mem_noop_insn = false;
rtx src, dest;
rtx src_folded;
struct table_elt *elt = 0, *p;
@@ -5166,7 +5167,7 @@ cse_insn (rtx_insn *insn)
}
/* Avoid creation of overlapping memory moves. */
- if (MEM_P (trial) && MEM_P (SET_DEST (sets[i].rtl)))
+ if (MEM_P (trial) && MEM_P (dest) && !rtx_equal_p (trial, dest))
{
rtx src, dest;
@@ -5277,6 +5278,21 @@ cse_insn (rtx_insn *insn)
break;
}
+ /* Similarly, lots of targets don't allow no-op
+ (set (mem x) (mem x)) moves. */
+ else if (n_sets == 1
+ && MEM_P (trial)
+ && MEM_P (dest)
+ && rtx_equal_p (trial, dest)
+ && !side_effects_p (dest)
+ && (cfun->can_delete_dead_exceptions
+ || insn_nothrow_p (insn)))
+ {
+ SET_SRC (sets[i].rtl) = trial;
+ mem_noop_insn = true;
+ break;
+ }
+
/* Reject certain invalid forms of CONST that we create. */
else if (CONSTANT_P (trial)
&& GET_CODE (trial) == CONST
@@ -5489,12 +5505,22 @@ cse_insn (rtx_insn *insn)
else if (n_sets == 1 && dest == pc_rtx && src == pc_rtx)
{
/* One less use of the label this insn used to jump to. */
- delete_insn_and_edges (insn);
+ cse_cfg_altered |= delete_insn_and_edges (insn);
cse_jumps_altered = true;
/* No more processing for this set. */
sets[i].rtl = 0;
}
+ /* Similarly for no-op MEM moves. */
+ else if (mem_noop_insn)
+ {
+ if (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))
+ cse_cfg_altered = true;
+ cse_cfg_altered |= delete_insn_and_edges (insn);
+ /* No more processing for this set. */
+ sets[i].rtl = 0;
+ }
+
/* If this SET is now setting PC to a label, we know it used to
be a conditional or computed branch. */
else if (dest == pc_rtx && GET_CODE (src) == LABEL_REF
@@ -5525,7 +5551,7 @@ cse_insn (rtx_insn *insn)
REG_NOTES (new_rtx) = note;
}
- delete_insn_and_edges (insn);
+ cse_cfg_altered |= delete_insn_and_edges (insn);
insn = new_rtx;
}
else
@@ -6643,6 +6669,10 @@ cse_main (rtx_insn *f ATTRIBUTE_UNUSED, int nregs)
int *rc_order = XNEWVEC (int, last_basic_block_for_fn (cfun));
int i, n_blocks;
+ /* CSE doesn't use dominane info but can invalidate it in different ways.
+ For simplicity free dominance info here. */
+ free_dominance_info (CDI_DOMINATORS);
+
df_set_flags (DF_LR_RUN_DCE);
df_note_add_problem ();
df_analyze ();
@@ -7105,7 +7135,7 @@ delete_trivially_dead_insns (rtx_insn *insns, int nreg)
count_reg_usage (insn, counts, NULL_RTX, -1);
ndead++;
}
- delete_insn_and_edges (insn);
+ cse_cfg_altered |= delete_insn_and_edges (insn);
}
}
@@ -7401,7 +7431,7 @@ cse_cc_succs (basic_block bb, basic_block orig_bb, rtx cc_reg, rtx cc_src,
newreg);
}
- delete_insn_and_edges (insns[i]);
+ cse_cfg_altered |= delete_insn_and_edges (insns[i]);
}
return mode;
@@ -7536,11 +7566,11 @@ rest_of_handle_cse (void)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
- cleanup_cfg (CLEANUP_CFG_CHANGED);
+ cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED);
timevar_pop (TV_JUMP);
}
else if (tem == 1 || optimize > 1)
- cleanup_cfg (0);
+ cse_cfg_altered |= cleanup_cfg (0);
return 0;
}
@@ -7605,11 +7635,11 @@ rest_of_handle_cse2 (void)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
- cleanup_cfg (CLEANUP_CFG_CHANGED);
+ cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED);
timevar_pop (TV_JUMP);
}
else if (tem == 1)
- cleanup_cfg (0);
+ cse_cfg_altered |= cleanup_cfg (0);
cse_not_expected = 1;
return 0;
@@ -7669,7 +7699,7 @@ rest_of_handle_cse_after_global_opts (void)
rebuild_jump_labels (get_insns ());
tem = cse_main (get_insns (), max_reg_num ());
- purge_all_dead_edges ();
+ cse_cfg_altered |= purge_all_dead_edges ();
delete_trivially_dead_insns (get_insns (), max_reg_num ());
cse_not_expected = !flag_rerun_cse_after_loop;
@@ -7679,11 +7709,11 @@ rest_of_handle_cse_after_global_opts (void)
{
timevar_push (TV_JUMP);
rebuild_jump_labels (get_insns ());
- cleanup_cfg (CLEANUP_CFG_CHANGED);
+ cse_cfg_altered |= cleanup_cfg (CLEANUP_CFG_CHANGED);
timevar_pop (TV_JUMP);
}
else if (tem == 1)
- cleanup_cfg (0);
+ cse_cfg_altered |= cleanup_cfg (0);
flag_cse_follow_jumps = save_cfj;
return 0;
diff --git a/gcc/df-scan.c b/gcc/df-scan.c
index e6d01d60082..19d8e0f0eeb 100644
--- a/gcc/df-scan.c
+++ b/gcc/df-scan.c
@@ -3223,11 +3223,22 @@ df_insn_refs_collect (struct df_collection_rec *collection_rec,
}
}
+ int flags = (is_cond_exec) ? DF_REF_CONDITIONAL : 0;
/* For CALL_INSNs, first record DF_REF_BASE register defs, as well as
uses from CALL_INSN_FUNCTION_USAGE. */
if (CALL_P (insn_info->insn))
- df_get_call_refs (collection_rec, bb, insn_info,
- (is_cond_exec) ? DF_REF_CONDITIONAL : 0);
+ df_get_call_refs (collection_rec, bb, insn_info, flags);
+
+ if (asm_noperands (PATTERN (insn_info->insn)) >= 0)
+ for (unsigned i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+ if (global_regs[i])
+ {
+ /* As with calls, asm statements reference all global regs. */
+ df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
+ NULL, bb, insn_info, DF_REF_REG_USE, flags);
+ df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
+ NULL, bb, insn_info, DF_REF_REG_DEF, flags);
+ }
/* Record other defs. These should be mostly for DF_REF_REGULAR, so
that a qsort on the defs is unnecessary in most cases. */
diff --git a/gcc/diagnostic-show-locus.c b/gcc/diagnostic-show-locus.c
index bf956661252..eeccee51716 100644
--- a/gcc/diagnostic-show-locus.c
+++ b/gcc/diagnostic-show-locus.c
@@ -199,6 +199,8 @@ class layout
void print_annotation_line (int row, const line_bounds lbounds);
void print_any_fixits (int row, const rich_location *richloc);
+ void show_ruler (int max_column) const;
+
private:
void calculate_line_spans ();
@@ -653,6 +655,9 @@ layout::layout (diagnostic_context * context,
m_x_offset = column - right_margin;
gcc_assert (m_x_offset >= 0);
}
+
+ if (context->show_ruler_p)
+ show_ruler (m_x_offset + max_width);
}
/* Return true iff we should print a heading when starting the
@@ -1084,6 +1089,40 @@ layout::move_to_column (int *column, int dest_column)
}
}
+/* For debugging layout issues, render a ruler giving column numbers
+ (after the 1-column indent). */
+
+void
+layout::show_ruler (int max_column) const
+{
+ /* Hundreds. */
+ if (max_column > 99)
+ {
+ pp_space (m_pp);
+ for (int column = 1 + m_x_offset; column <= max_column; column++)
+ if (0 == column % 10)
+ pp_character (m_pp, '0' + (column / 100) % 10);
+ else
+ pp_space (m_pp);
+ pp_newline (m_pp);
+ }
+
+ /* Tens. */
+ pp_space (m_pp);
+ for (int column = 1 + m_x_offset; column <= max_column; column++)
+ if (0 == column % 10)
+ pp_character (m_pp, '0' + (column / 10) % 10);
+ else
+ pp_space (m_pp);
+ pp_newline (m_pp);
+
+ /* Units. */
+ pp_space (m_pp);
+ for (int column = 1 + m_x_offset; column <= max_column; column++)
+ pp_character (m_pp, '0' + (column % 10));
+ pp_newline (m_pp);
+}
+
} /* End of anonymous namespace. */
/* Print the physical source code corresponding to the location of
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index ff573577084..48ae50d6879 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -201,6 +201,10 @@ struct diagnostic_context
source code (to avoid e.g. colorizing just the first character in
a token, which would look strange). */
bool colorize_source_p;
+
+ /* Usable by plugins; if true, print a debugging ruler above the
+ source output. */
+ bool show_ruler_p;
};
static inline void
diff --git a/gcc/doc/cpp.texi b/gcc/doc/cpp.texi
index 72f4e7c6b26..44f59bdfb47 100644
--- a/gcc/doc/cpp.texi
+++ b/gcc/doc/cpp.texi
@@ -1984,7 +1984,7 @@ by GCC, or a non-GCC compiler that claims to accept the GNU C dialects,
you can simply test @code{__GNUC__}. If you need to write code
which depends on a specific version, you must be more careful. Each
time the minor version is increased, the patch level is reset to zero;
-each time the major version is increased (which happens rarely), the
+each time the major version is increased, the
minor version and patch level are reset. If you wish to use the
predefined macros directly in the conditional, you will need to write it
like this:
@@ -2362,6 +2362,9 @@ in use.
This macro is defined, with value 1, when @option{-fsanitize=address}
or @option{-fsanitize=kernel-address} are in use.
+@item __SANITIZE_THREAD__
+This macro is defined, with value 1, when @option{-fsanitize=thread} is in use.
+
@item __TIMESTAMP__
This macro expands to a string constant that describes the date and time
of the last modification of the current source file. The string constant
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 8ec7dcb5e5c..5199134ca3c 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -962,8 +962,13 @@ complex @code{__float128} type. When these problems are fixed, you
would use the following syntax to declare @code{_Complex128} to be a
complex @code{__float128} type:
+On the PowerPC Linux VSX targets, you can declare complex types using
+the corresponding internal complex type, @code{KCmode} for
+@code{__float128} type and @code{ICmode} for @code{__ibm128} type:
+
@smallexample
-typedef _Complex float __attribute__((mode(KC))) _Complex128;
+typedef _Complex float __attribute__((mode(KC))) _Complex_float128;
+typedef _Complex float __attribute__((mode(IC))) _Complex_ibm128;
@end smallexample
Not all targets support additional floating-point types.
@@ -8924,9 +8929,11 @@ This extension is not supported by GNU C++.
@cindex @code{__FUNCTION__} identifier
@cindex @code{__PRETTY_FUNCTION__} identifier
-GCC provides three magic variables that hold the name of the current
-function, as a string. The first of these is @code{__func__}, which
-is part of the C99 standard:
+GCC provides three magic constants that hold the name of the current
+function as a string. In C++11 and later modes, all three are treated
+as constant expressions and can be used in @code{constexpr} constexts.
+The first of these constants is @code{__func__}, which is part of
+the C99 standard:
The identifier @code{__func__} is implicitly declared by the translator
as if, immediately following the opening brace of each function
@@ -8938,20 +8945,21 @@ static const char __func__[] = "function-name";
@noindent
appeared, where function-name is the name of the lexically-enclosing
-function. This name is the unadorned name of the function.
+function. This name is the unadorned name of the function. As an
+extension, at file (or, in C++, namespace scope), @code{__func__}
+evaluates to the empty string.
@code{__FUNCTION__} is another name for @code{__func__}, provided for
backward compatibility with old versions of GCC.
In C, @code{__PRETTY_FUNCTION__} is yet another name for
-@code{__func__}. However, in C++, @code{__PRETTY_FUNCTION__} contains
-the type signature of the function as well as its bare name. For
-example, this program:
+@code{__func__}, except that at file (or, in C++, namespace scope),
+it evaluates to the string @code{"top level"}. In addition, in C++,
+@code{__PRETTY_FUNCTION__} contains the signature of the function as
+well as its bare name. For example, this program:
@smallexample
-extern "C" @{
-extern int printf (char *, ...);
-@}
+extern "C" int printf (const char *, ...);
class a @{
public:
@@ -8980,7 +8988,7 @@ __PRETTY_FUNCTION__ = void a::sub(int)
@end smallexample
These identifiers are variables, not preprocessor macros, and may not
-be used to initialize @code{char} arrays or be concatenated with other string
+be used to initialize @code{char} arrays or be concatenated with string
literals.
@node Return Address
@@ -11086,22 +11094,50 @@ means that the compiler can assume for @code{x}, set to @code{arg}, that
@end deftypefn
@deftypefn {Built-in Function} int __builtin_LINE ()
-This function is the equivalent to the preprocessor @code{__LINE__}
-macro and returns the line number of the invocation of the built-in.
-In a C++ default argument for a function @var{F}, it gets the line number of
-the call to @var{F}.
+This function is the equivalent of the preprocessor @code{__LINE__}
+macro and returns a constant integer expression that evaluates to
+the line number of the invocation of the built-in. When used as a C++
+default argument for a function @var{F}, it returns the line number
+of the call to @var{F}.
@end deftypefn
@deftypefn {Built-in Function} {const char *} __builtin_FUNCTION ()
-This function is the equivalent to the preprocessor @code{__FUNCTION__}
-macro and returns the function name the invocation of the built-in is in.
+This function is the equivalent of the @code{__FUNCTION__} symbol
+and returns an address constant pointing to the name of the function
+from which the built-in was invoked, or the empty string if
+the invocation is not at function scope. When used as a C++ default
+argument for a function @var{F}, it returns the name of @var{F}'s
+caller or the empty string if the call was not made at function
+scope.
@end deftypefn
@deftypefn {Built-in Function} {const char *} __builtin_FILE ()
-This function is the equivalent to the preprocessor @code{__FILE__}
-macro and returns the file name the invocation of the built-in is in.
-In a C++ default argument for a function @var{F}, it gets the file name of
-the call to @var{F}.
+This function is the equivalent of the preprocessor @code{__FILE__}
+macro and returns an address constant pointing to the file name
+containing the invocation of the built-in, or the empty string if
+the invocation is not at function scope. When used as a C++ default
+argument for a function @var{F}, it returns the file name of the call
+to @var{F} or the empty string if the call was not made at function
+scope.
+
+For example, in the following, each call to function @code{foo} will
+print a line similar to @code{"file.c:123: foo: message"} with the name
+of the file and the line number of the @code{printf} call, the name of
+the function @code{foo}, followed by the word @code{message}.
+
+@smallexample
+const char*
+function (const char *func = __builtin_FUNCTION ())
+@{
+ return func;
+@}
+
+void foo (void)
+@{
+ printf ("%s:%i: %s: message\n", file (), line (), function ());
+@}
+@end smallexample
+
@end deftypefn
@deftypefn {Built-in Function} void __builtin___clear_cache (char *@var{begin}, char *@var{end})
@@ -11415,6 +11451,7 @@ instructions, but allow the compiler to schedule those calls.
* MIPS DSP Built-in Functions::
* MIPS Paired-Single Support::
* MIPS Loongson Built-in Functions::
+* MIPS SIMD Architecture (MSA) Support::
* Other MIPS Built-in Functions::
* MSP430 Built-in Functions::
* NDS32 Built-in Functions::
@@ -13525,6 +13562,794 @@ else
@end smallexample
@end table
+@node MIPS SIMD Architecture (MSA) Support
+@subsection MIPS SIMD Architecture (MSA) Support
+
+@menu
+* MIPS SIMD Architecture Built-in Functions::
+@end menu
+
+GCC provides intrinsics to access the SIMD instructions provided by the
+MSA MIPS SIMD Architecture. The interface is made available by including
+@code{<msa.h>} and using @option{-mmsa -mhard-float -mfp64 -mnan=2008}.
+For each @code{__builtin_msa_*}, there is a shortened name of the intrinsic,
+@code{__msa_*}.
+
+MSA implements 128-bit wide vector registers, operating on 8-, 16-, 32- and
+64-bit integer, 16- and 32-bit fixed-point, or 32- and 64-bit floating point
+data elements. The following vectors typedefs are included in @code{msa.h}:
+@itemize
+@item @code{v16i8}, a vector of sixteen signed 8-bit integers;
+@item @code{v16u8}, a vector of sixteen unsigned 8-bit integers;
+@item @code{v8i16}, a vector of eight signed 16-bit integers;
+@item @code{v8u16}, a vector of eight unsigned 16-bit integers;
+@item @code{v4i32}, a vector of four signed 32-bit integers;
+@item @code{v4u32}, a vector of four unsigned 32-bit integers;
+@item @code{v2i64}, a vector of two signed 64-bit integers;
+@item @code{v2u64}, a vector of two unsigned 64-bit integers;
+@item @code{v4f32}, a vector of four 32-bit floats;
+@item @code{v2f64}, a vector of two 64-bit doubles.
+@end itemize
+
+Intructions and corresponding built-ins may have additional restrictions and/or
+input/output values manipulated:
+@itemize
+@item @code{imm0_1}, an integer literal in range 0 to 1;
+@item @code{imm0_3}, an integer literal in range 0 to 3;
+@item @code{imm0_7}, an integer literal in range 0 to 7;
+@item @code{imm0_15}, an integer literal in range 0 to 15;
+@item @code{imm0_31}, an integer literal in range 0 to 31;
+@item @code{imm0_63}, an integer literal in range 0 to 63;
+@item @code{imm0_255}, an integer literal in range 0 to 255;
+@item @code{imm_n16_15}, an integer literal in range -16 to 15;
+@item @code{imm_n512_511}, an integer literal in range -512 to 511;
+@item @code{imm_n1024_1022}, an integer literal in range -512 to 511 left
+shifted by 1 bit, i.e., -1024, -1022, @dots{}, 1020, 1022;
+@item @code{imm_n2048_2044}, an integer literal in range -512 to 511 left
+shifted by 2 bits, i.e., -2048, -2044, @dots{}, 2040, 2044;
+@item @code{imm_n4096_4088}, an integer literal in range -512 to 511 left
+shifted by 3 bits, i.e., -4096, -4088, @dots{}, 4080, 4088;
+@item @code{imm1_4}, an integer literal in range 1 to 4;
+@item @code{i32, i64, u32, u64, f32, f64}, defined as follows:
+@end itemize
+
+@smallexample
+@{
+typedef int i32;
+#if __LONG_MAX__ == __LONG_LONG_MAX__
+typedef long i64;
+#else
+typedef long long i64;
+#endif
+
+typedef unsigned int u32;
+#if __LONG_MAX__ == __LONG_LONG_MAX__
+typedef unsigned long u64;
+#else
+typedef unsigned long long u64;
+#endif
+
+typedef double f64;
+typedef float f32;
+@}
+@end smallexample
+
+@node MIPS SIMD Architecture Built-in Functions
+@subsubsection MIPS SIMD Architecture Built-in Functions
+
+The intrinsics provided are listed below; each is named after the
+machine instruction.
+
+@smallexample
+v16i8 __builtin_msa_add_a_b (v16i8, v16i8);
+v8i16 __builtin_msa_add_a_h (v8i16, v8i16);
+v4i32 __builtin_msa_add_a_w (v4i32, v4i32);
+v2i64 __builtin_msa_add_a_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_adds_a_b (v16i8, v16i8);
+v8i16 __builtin_msa_adds_a_h (v8i16, v8i16);
+v4i32 __builtin_msa_adds_a_w (v4i32, v4i32);
+v2i64 __builtin_msa_adds_a_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_adds_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_adds_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_adds_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_adds_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_adds_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_adds_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_adds_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_adds_u_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_addv_b (v16i8, v16i8);
+v8i16 __builtin_msa_addv_h (v8i16, v8i16);
+v4i32 __builtin_msa_addv_w (v4i32, v4i32);
+v2i64 __builtin_msa_addv_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_addvi_b (v16i8, imm0_31);
+v8i16 __builtin_msa_addvi_h (v8i16, imm0_31);
+v4i32 __builtin_msa_addvi_w (v4i32, imm0_31);
+v2i64 __builtin_msa_addvi_d (v2i64, imm0_31);
+
+v16u8 __builtin_msa_and_v (v16u8, v16u8);
+
+v16u8 __builtin_msa_andi_b (v16u8, imm0_255);
+
+v16i8 __builtin_msa_asub_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_asub_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_asub_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_asub_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_asub_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_asub_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_asub_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_asub_u_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_ave_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_ave_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_ave_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_ave_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_ave_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_ave_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_ave_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_ave_u_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_aver_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_aver_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_aver_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_aver_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_aver_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_aver_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_aver_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_aver_u_d (v2u64, v2u64);
+
+v16u8 __builtin_msa_bclr_b (v16u8, v16u8);
+v8u16 __builtin_msa_bclr_h (v8u16, v8u16);
+v4u32 __builtin_msa_bclr_w (v4u32, v4u32);
+v2u64 __builtin_msa_bclr_d (v2u64, v2u64);
+
+v16u8 __builtin_msa_bclri_b (v16u8, imm0_7);
+v8u16 __builtin_msa_bclri_h (v8u16, imm0_15);
+v4u32 __builtin_msa_bclri_w (v4u32, imm0_31);
+v2u64 __builtin_msa_bclri_d (v2u64, imm0_63);
+
+v16u8 __builtin_msa_binsl_b (v16u8, v16u8, v16u8);
+v8u16 __builtin_msa_binsl_h (v8u16, v8u16, v8u16);
+v4u32 __builtin_msa_binsl_w (v4u32, v4u32, v4u32);
+v2u64 __builtin_msa_binsl_d (v2u64, v2u64, v2u64);
+
+v16u8 __builtin_msa_binsli_b (v16u8, v16u8, imm0_7);
+v8u16 __builtin_msa_binsli_h (v8u16, v8u16, imm0_15);
+v4u32 __builtin_msa_binsli_w (v4u32, v4u32, imm0_31);
+v2u64 __builtin_msa_binsli_d (v2u64, v2u64, imm0_63);
+
+v16u8 __builtin_msa_binsr_b (v16u8, v16u8, v16u8);
+v8u16 __builtin_msa_binsr_h (v8u16, v8u16, v8u16);
+v4u32 __builtin_msa_binsr_w (v4u32, v4u32, v4u32);
+v2u64 __builtin_msa_binsr_d (v2u64, v2u64, v2u64);
+
+v16u8 __builtin_msa_binsri_b (v16u8, v16u8, imm0_7);
+v8u16 __builtin_msa_binsri_h (v8u16, v8u16, imm0_15);
+v4u32 __builtin_msa_binsri_w (v4u32, v4u32, imm0_31);
+v2u64 __builtin_msa_binsri_d (v2u64, v2u64, imm0_63);
+
+v16u8 __builtin_msa_bmnz_v (v16u8, v16u8, v16u8);
+
+v16u8 __builtin_msa_bmnzi_b (v16u8, v16u8, imm0_255);
+
+v16u8 __builtin_msa_bmz_v (v16u8, v16u8, v16u8);
+
+v16u8 __builtin_msa_bmzi_b (v16u8, v16u8, imm0_255);
+
+v16u8 __builtin_msa_bneg_b (v16u8, v16u8);
+v8u16 __builtin_msa_bneg_h (v8u16, v8u16);
+v4u32 __builtin_msa_bneg_w (v4u32, v4u32);
+v2u64 __builtin_msa_bneg_d (v2u64, v2u64);
+
+v16u8 __builtin_msa_bnegi_b (v16u8, imm0_7);
+v8u16 __builtin_msa_bnegi_h (v8u16, imm0_15);
+v4u32 __builtin_msa_bnegi_w (v4u32, imm0_31);
+v2u64 __builtin_msa_bnegi_d (v2u64, imm0_63);
+
+i32 __builtin_msa_bnz_b (v16u8);
+i32 __builtin_msa_bnz_h (v8u16);
+i32 __builtin_msa_bnz_w (v4u32);
+i32 __builtin_msa_bnz_d (v2u64);
+
+i32 __builtin_msa_bnz_v (v16u8);
+
+v16u8 __builtin_msa_bsel_v (v16u8, v16u8, v16u8);
+
+v16u8 __builtin_msa_bseli_b (v16u8, v16u8, imm0_255);
+
+v16u8 __builtin_msa_bset_b (v16u8, v16u8);
+v8u16 __builtin_msa_bset_h (v8u16, v8u16);
+v4u32 __builtin_msa_bset_w (v4u32, v4u32);
+v2u64 __builtin_msa_bset_d (v2u64, v2u64);
+
+v16u8 __builtin_msa_bseti_b (v16u8, imm0_7);
+v8u16 __builtin_msa_bseti_h (v8u16, imm0_15);
+v4u32 __builtin_msa_bseti_w (v4u32, imm0_31);
+v2u64 __builtin_msa_bseti_d (v2u64, imm0_63);
+
+i32 __builtin_msa_bz_b (v16u8);
+i32 __builtin_msa_bz_h (v8u16);
+i32 __builtin_msa_bz_w (v4u32);
+i32 __builtin_msa_bz_d (v2u64);
+
+i32 __builtin_msa_bz_v (v16u8);
+
+v16i8 __builtin_msa_ceq_b (v16i8, v16i8);
+v8i16 __builtin_msa_ceq_h (v8i16, v8i16);
+v4i32 __builtin_msa_ceq_w (v4i32, v4i32);
+v2i64 __builtin_msa_ceq_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_ceqi_b (v16i8, imm_n16_15);
+v8i16 __builtin_msa_ceqi_h (v8i16, imm_n16_15);
+v4i32 __builtin_msa_ceqi_w (v4i32, imm_n16_15);
+v2i64 __builtin_msa_ceqi_d (v2i64, imm_n16_15);
+
+i32 __builtin_msa_cfcmsa (imm0_31);
+
+v16i8 __builtin_msa_cle_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_cle_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_cle_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_cle_s_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_cle_u_b (v16u8, v16u8);
+v8i16 __builtin_msa_cle_u_h (v8u16, v8u16);
+v4i32 __builtin_msa_cle_u_w (v4u32, v4u32);
+v2i64 __builtin_msa_cle_u_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_clei_s_b (v16i8, imm_n16_15);
+v8i16 __builtin_msa_clei_s_h (v8i16, imm_n16_15);
+v4i32 __builtin_msa_clei_s_w (v4i32, imm_n16_15);
+v2i64 __builtin_msa_clei_s_d (v2i64, imm_n16_15);
+
+v16i8 __builtin_msa_clei_u_b (v16u8, imm0_31);
+v8i16 __builtin_msa_clei_u_h (v8u16, imm0_31);
+v4i32 __builtin_msa_clei_u_w (v4u32, imm0_31);
+v2i64 __builtin_msa_clei_u_d (v2u64, imm0_31);
+
+v16i8 __builtin_msa_clt_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_clt_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_clt_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_clt_s_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_clt_u_b (v16u8, v16u8);
+v8i16 __builtin_msa_clt_u_h (v8u16, v8u16);
+v4i32 __builtin_msa_clt_u_w (v4u32, v4u32);
+v2i64 __builtin_msa_clt_u_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_clti_s_b (v16i8, imm_n16_15);
+v8i16 __builtin_msa_clti_s_h (v8i16, imm_n16_15);
+v4i32 __builtin_msa_clti_s_w (v4i32, imm_n16_15);
+v2i64 __builtin_msa_clti_s_d (v2i64, imm_n16_15);
+
+v16i8 __builtin_msa_clti_u_b (v16u8, imm0_31);
+v8i16 __builtin_msa_clti_u_h (v8u16, imm0_31);
+v4i32 __builtin_msa_clti_u_w (v4u32, imm0_31);
+v2i64 __builtin_msa_clti_u_d (v2u64, imm0_31);
+
+i32 __builtin_msa_copy_s_b (v16i8, imm0_15);
+i32 __builtin_msa_copy_s_h (v8i16, imm0_7);
+i32 __builtin_msa_copy_s_w (v4i32, imm0_3);
+i64 __builtin_msa_copy_s_d (v2i64, imm0_1);
+
+u32 __builtin_msa_copy_u_b (v16i8, imm0_15);
+u32 __builtin_msa_copy_u_h (v8i16, imm0_7);
+u32 __builtin_msa_copy_u_w (v4i32, imm0_3);
+u64 __builtin_msa_copy_u_d (v2i64, imm0_1);
+
+void __builtin_msa_ctcmsa (imm0_31, i32);
+
+v16i8 __builtin_msa_div_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_div_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_div_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_div_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_div_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_div_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_div_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_div_u_d (v2u64, v2u64);
+
+v8i16 __builtin_msa_dotp_s_h (v16i8, v16i8);
+v4i32 __builtin_msa_dotp_s_w (v8i16, v8i16);
+v2i64 __builtin_msa_dotp_s_d (v4i32, v4i32);
+
+v8u16 __builtin_msa_dotp_u_h (v16u8, v16u8);
+v4u32 __builtin_msa_dotp_u_w (v8u16, v8u16);
+v2u64 __builtin_msa_dotp_u_d (v4u32, v4u32);
+
+v8i16 __builtin_msa_dpadd_s_h (v8i16, v16i8, v16i8);
+v4i32 __builtin_msa_dpadd_s_w (v4i32, v8i16, v8i16);
+v2i64 __builtin_msa_dpadd_s_d (v2i64, v4i32, v4i32);
+
+v8u16 __builtin_msa_dpadd_u_h (v8u16, v16u8, v16u8);
+v4u32 __builtin_msa_dpadd_u_w (v4u32, v8u16, v8u16);
+v2u64 __builtin_msa_dpadd_u_d (v2u64, v4u32, v4u32);
+
+v8i16 __builtin_msa_dpsub_s_h (v8i16, v16i8, v16i8);
+v4i32 __builtin_msa_dpsub_s_w (v4i32, v8i16, v8i16);
+v2i64 __builtin_msa_dpsub_s_d (v2i64, v4i32, v4i32);
+
+v8i16 __builtin_msa_dpsub_u_h (v8i16, v16u8, v16u8);
+v4i32 __builtin_msa_dpsub_u_w (v4i32, v8u16, v8u16);
+v2i64 __builtin_msa_dpsub_u_d (v2i64, v4u32, v4u32);
+
+v4f32 __builtin_msa_fadd_w (v4f32, v4f32);
+v2f64 __builtin_msa_fadd_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fcaf_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcaf_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fceq_w (v4f32, v4f32);
+v2i64 __builtin_msa_fceq_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fclass_w (v4f32);
+v2i64 __builtin_msa_fclass_d (v2f64);
+
+v4i32 __builtin_msa_fcle_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcle_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fclt_w (v4f32, v4f32);
+v2i64 __builtin_msa_fclt_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fcne_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcne_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fcor_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcor_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fcueq_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcueq_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fcule_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcule_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fcult_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcult_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fcun_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcun_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fcune_w (v4f32, v4f32);
+v2i64 __builtin_msa_fcune_d (v2f64, v2f64);
+
+v4f32 __builtin_msa_fdiv_w (v4f32, v4f32);
+v2f64 __builtin_msa_fdiv_d (v2f64, v2f64);
+
+v8i16 __builtin_msa_fexdo_h (v4f32, v4f32);
+v4f32 __builtin_msa_fexdo_w (v2f64, v2f64);
+
+v4f32 __builtin_msa_fexp2_w (v4f32, v4i32);
+v2f64 __builtin_msa_fexp2_d (v2f64, v2i64);
+
+v4f32 __builtin_msa_fexupl_w (v8i16);
+v2f64 __builtin_msa_fexupl_d (v4f32);
+
+v4f32 __builtin_msa_fexupr_w (v8i16);
+v2f64 __builtin_msa_fexupr_d (v4f32);
+
+v4f32 __builtin_msa_ffint_s_w (v4i32);
+v2f64 __builtin_msa_ffint_s_d (v2i64);
+
+v4f32 __builtin_msa_ffint_u_w (v4u32);
+v2f64 __builtin_msa_ffint_u_d (v2u64);
+
+v4f32 __builtin_msa_ffql_w (v8i16);
+v2f64 __builtin_msa_ffql_d (v4i32);
+
+v4f32 __builtin_msa_ffqr_w (v8i16);
+v2f64 __builtin_msa_ffqr_d (v4i32);
+
+v16i8 __builtin_msa_fill_b (i32);
+v8i16 __builtin_msa_fill_h (i32);
+v4i32 __builtin_msa_fill_w (i32);
+v2i64 __builtin_msa_fill_d (i64);
+
+v4f32 __builtin_msa_flog2_w (v4f32);
+v2f64 __builtin_msa_flog2_d (v2f64);
+
+v4f32 __builtin_msa_fmadd_w (v4f32, v4f32, v4f32);
+v2f64 __builtin_msa_fmadd_d (v2f64, v2f64, v2f64);
+
+v4f32 __builtin_msa_fmax_w (v4f32, v4f32);
+v2f64 __builtin_msa_fmax_d (v2f64, v2f64);
+
+v4f32 __builtin_msa_fmax_a_w (v4f32, v4f32);
+v2f64 __builtin_msa_fmax_a_d (v2f64, v2f64);
+
+v4f32 __builtin_msa_fmin_w (v4f32, v4f32);
+v2f64 __builtin_msa_fmin_d (v2f64, v2f64);
+
+v4f32 __builtin_msa_fmin_a_w (v4f32, v4f32);
+v2f64 __builtin_msa_fmin_a_d (v2f64, v2f64);
+
+v4f32 __builtin_msa_fmsub_w (v4f32, v4f32, v4f32);
+v2f64 __builtin_msa_fmsub_d (v2f64, v2f64, v2f64);
+
+v4f32 __builtin_msa_fmul_w (v4f32, v4f32);
+v2f64 __builtin_msa_fmul_d (v2f64, v2f64);
+
+v4f32 __builtin_msa_frint_w (v4f32);
+v2f64 __builtin_msa_frint_d (v2f64);
+
+v4f32 __builtin_msa_frcp_w (v4f32);
+v2f64 __builtin_msa_frcp_d (v2f64);
+
+v4f32 __builtin_msa_frsqrt_w (v4f32);
+v2f64 __builtin_msa_frsqrt_d (v2f64);
+
+v4i32 __builtin_msa_fsaf_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsaf_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fseq_w (v4f32, v4f32);
+v2i64 __builtin_msa_fseq_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fsle_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsle_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fslt_w (v4f32, v4f32);
+v2i64 __builtin_msa_fslt_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fsne_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsne_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fsor_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsor_d (v2f64, v2f64);
+
+v4f32 __builtin_msa_fsqrt_w (v4f32);
+v2f64 __builtin_msa_fsqrt_d (v2f64);
+
+v4f32 __builtin_msa_fsub_w (v4f32, v4f32);
+v2f64 __builtin_msa_fsub_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fsueq_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsueq_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fsule_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsule_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fsult_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsult_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fsun_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsun_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_fsune_w (v4f32, v4f32);
+v2i64 __builtin_msa_fsune_d (v2f64, v2f64);
+
+v4i32 __builtin_msa_ftint_s_w (v4f32);
+v2i64 __builtin_msa_ftint_s_d (v2f64);
+
+v4u32 __builtin_msa_ftint_u_w (v4f32);
+v2u64 __builtin_msa_ftint_u_d (v2f64);
+
+v8i16 __builtin_msa_ftq_h (v4f32, v4f32);
+v4i32 __builtin_msa_ftq_w (v2f64, v2f64);
+
+v4i32 __builtin_msa_ftrunc_s_w (v4f32);
+v2i64 __builtin_msa_ftrunc_s_d (v2f64);
+
+v4u32 __builtin_msa_ftrunc_u_w (v4f32);
+v2u64 __builtin_msa_ftrunc_u_d (v2f64);
+
+v8i16 __builtin_msa_hadd_s_h (v16i8, v16i8);
+v4i32 __builtin_msa_hadd_s_w (v8i16, v8i16);
+v2i64 __builtin_msa_hadd_s_d (v4i32, v4i32);
+
+v8u16 __builtin_msa_hadd_u_h (v16u8, v16u8);
+v4u32 __builtin_msa_hadd_u_w (v8u16, v8u16);
+v2u64 __builtin_msa_hadd_u_d (v4u32, v4u32);
+
+v8i16 __builtin_msa_hsub_s_h (v16i8, v16i8);
+v4i32 __builtin_msa_hsub_s_w (v8i16, v8i16);
+v2i64 __builtin_msa_hsub_s_d (v4i32, v4i32);
+
+v8i16 __builtin_msa_hsub_u_h (v16u8, v16u8);
+v4i32 __builtin_msa_hsub_u_w (v8u16, v8u16);
+v2i64 __builtin_msa_hsub_u_d (v4u32, v4u32);
+
+v16i8 __builtin_msa_ilvev_b (v16i8, v16i8);
+v8i16 __builtin_msa_ilvev_h (v8i16, v8i16);
+v4i32 __builtin_msa_ilvev_w (v4i32, v4i32);
+v2i64 __builtin_msa_ilvev_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_ilvl_b (v16i8, v16i8);
+v8i16 __builtin_msa_ilvl_h (v8i16, v8i16);
+v4i32 __builtin_msa_ilvl_w (v4i32, v4i32);
+v2i64 __builtin_msa_ilvl_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_ilvod_b (v16i8, v16i8);
+v8i16 __builtin_msa_ilvod_h (v8i16, v8i16);
+v4i32 __builtin_msa_ilvod_w (v4i32, v4i32);
+v2i64 __builtin_msa_ilvod_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_ilvr_b (v16i8, v16i8);
+v8i16 __builtin_msa_ilvr_h (v8i16, v8i16);
+v4i32 __builtin_msa_ilvr_w (v4i32, v4i32);
+v2i64 __builtin_msa_ilvr_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_insert_b (v16i8, imm0_15, i32);
+v8i16 __builtin_msa_insert_h (v8i16, imm0_7, i32);
+v4i32 __builtin_msa_insert_w (v4i32, imm0_3, i32);
+v2i64 __builtin_msa_insert_d (v2i64, imm0_1, i64);
+
+v16i8 __builtin_msa_insve_b (v16i8, imm0_15, v16i8);
+v8i16 __builtin_msa_insve_h (v8i16, imm0_7, v8i16);
+v4i32 __builtin_msa_insve_w (v4i32, imm0_3, v4i32);
+v2i64 __builtin_msa_insve_d (v2i64, imm0_1, v2i64);
+
+v16i8 __builtin_msa_ld_b (void *, imm_n512_511);
+v8i16 __builtin_msa_ld_h (void *, imm_n1024_1022);
+v4i32 __builtin_msa_ld_w (void *, imm_n2048_2044);
+v2i64 __builtin_msa_ld_d (void *, imm_n4096_4088);
+
+v16i8 __builtin_msa_ldi_b (imm_n512_511);
+v8i16 __builtin_msa_ldi_h (imm_n512_511);
+v4i32 __builtin_msa_ldi_w (imm_n512_511);
+v2i64 __builtin_msa_ldi_d (imm_n512_511);
+
+v8i16 __builtin_msa_madd_q_h (v8i16, v8i16, v8i16);
+v4i32 __builtin_msa_madd_q_w (v4i32, v4i32, v4i32);
+
+v8i16 __builtin_msa_maddr_q_h (v8i16, v8i16, v8i16);
+v4i32 __builtin_msa_maddr_q_w (v4i32, v4i32, v4i32);
+
+v16i8 __builtin_msa_maddv_b (v16i8, v16i8, v16i8);
+v8i16 __builtin_msa_maddv_h (v8i16, v8i16, v8i16);
+v4i32 __builtin_msa_maddv_w (v4i32, v4i32, v4i32);
+v2i64 __builtin_msa_maddv_d (v2i64, v2i64, v2i64);
+
+v16i8 __builtin_msa_max_a_b (v16i8, v16i8);
+v8i16 __builtin_msa_max_a_h (v8i16, v8i16);
+v4i32 __builtin_msa_max_a_w (v4i32, v4i32);
+v2i64 __builtin_msa_max_a_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_max_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_max_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_max_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_max_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_max_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_max_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_max_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_max_u_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_maxi_s_b (v16i8, imm_n16_15);
+v8i16 __builtin_msa_maxi_s_h (v8i16, imm_n16_15);
+v4i32 __builtin_msa_maxi_s_w (v4i32, imm_n16_15);
+v2i64 __builtin_msa_maxi_s_d (v2i64, imm_n16_15);
+
+v16u8 __builtin_msa_maxi_u_b (v16u8, imm0_31);
+v8u16 __builtin_msa_maxi_u_h (v8u16, imm0_31);
+v4u32 __builtin_msa_maxi_u_w (v4u32, imm0_31);
+v2u64 __builtin_msa_maxi_u_d (v2u64, imm0_31);
+
+v16i8 __builtin_msa_min_a_b (v16i8, v16i8);
+v8i16 __builtin_msa_min_a_h (v8i16, v8i16);
+v4i32 __builtin_msa_min_a_w (v4i32, v4i32);
+v2i64 __builtin_msa_min_a_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_min_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_min_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_min_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_min_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_min_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_min_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_min_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_min_u_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_mini_s_b (v16i8, imm_n16_15);
+v8i16 __builtin_msa_mini_s_h (v8i16, imm_n16_15);
+v4i32 __builtin_msa_mini_s_w (v4i32, imm_n16_15);
+v2i64 __builtin_msa_mini_s_d (v2i64, imm_n16_15);
+
+v16u8 __builtin_msa_mini_u_b (v16u8, imm0_31);
+v8u16 __builtin_msa_mini_u_h (v8u16, imm0_31);
+v4u32 __builtin_msa_mini_u_w (v4u32, imm0_31);
+v2u64 __builtin_msa_mini_u_d (v2u64, imm0_31);
+
+v16i8 __builtin_msa_mod_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_mod_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_mod_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_mod_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_mod_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_mod_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_mod_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_mod_u_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_move_v (v16i8);
+
+v8i16 __builtin_msa_msub_q_h (v8i16, v8i16, v8i16);
+v4i32 __builtin_msa_msub_q_w (v4i32, v4i32, v4i32);
+
+v8i16 __builtin_msa_msubr_q_h (v8i16, v8i16, v8i16);
+v4i32 __builtin_msa_msubr_q_w (v4i32, v4i32, v4i32);
+
+v16i8 __builtin_msa_msubv_b (v16i8, v16i8, v16i8);
+v8i16 __builtin_msa_msubv_h (v8i16, v8i16, v8i16);
+v4i32 __builtin_msa_msubv_w (v4i32, v4i32, v4i32);
+v2i64 __builtin_msa_msubv_d (v2i64, v2i64, v2i64);
+
+v8i16 __builtin_msa_mul_q_h (v8i16, v8i16);
+v4i32 __builtin_msa_mul_q_w (v4i32, v4i32);
+
+v8i16 __builtin_msa_mulr_q_h (v8i16, v8i16);
+v4i32 __builtin_msa_mulr_q_w (v4i32, v4i32);
+
+v16i8 __builtin_msa_mulv_b (v16i8, v16i8);
+v8i16 __builtin_msa_mulv_h (v8i16, v8i16);
+v4i32 __builtin_msa_mulv_w (v4i32, v4i32);
+v2i64 __builtin_msa_mulv_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_nloc_b (v16i8);
+v8i16 __builtin_msa_nloc_h (v8i16);
+v4i32 __builtin_msa_nloc_w (v4i32);
+v2i64 __builtin_msa_nloc_d (v2i64);
+
+v16i8 __builtin_msa_nlzc_b (v16i8);
+v8i16 __builtin_msa_nlzc_h (v8i16);
+v4i32 __builtin_msa_nlzc_w (v4i32);
+v2i64 __builtin_msa_nlzc_d (v2i64);
+
+v16u8 __builtin_msa_nor_v (v16u8, v16u8);
+
+v16u8 __builtin_msa_nori_b (v16u8, imm0_255);
+
+v16u8 __builtin_msa_or_v (v16u8, v16u8);
+
+v16u8 __builtin_msa_ori_b (v16u8, imm0_255);
+
+v16i8 __builtin_msa_pckev_b (v16i8, v16i8);
+v8i16 __builtin_msa_pckev_h (v8i16, v8i16);
+v4i32 __builtin_msa_pckev_w (v4i32, v4i32);
+v2i64 __builtin_msa_pckev_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_pckod_b (v16i8, v16i8);
+v8i16 __builtin_msa_pckod_h (v8i16, v8i16);
+v4i32 __builtin_msa_pckod_w (v4i32, v4i32);
+v2i64 __builtin_msa_pckod_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_pcnt_b (v16i8);
+v8i16 __builtin_msa_pcnt_h (v8i16);
+v4i32 __builtin_msa_pcnt_w (v4i32);
+v2i64 __builtin_msa_pcnt_d (v2i64);
+
+v16i8 __builtin_msa_sat_s_b (v16i8, imm0_7);
+v8i16 __builtin_msa_sat_s_h (v8i16, imm0_15);
+v4i32 __builtin_msa_sat_s_w (v4i32, imm0_31);
+v2i64 __builtin_msa_sat_s_d (v2i64, imm0_63);
+
+v16u8 __builtin_msa_sat_u_b (v16u8, imm0_7);
+v8u16 __builtin_msa_sat_u_h (v8u16, imm0_15);
+v4u32 __builtin_msa_sat_u_w (v4u32, imm0_31);
+v2u64 __builtin_msa_sat_u_d (v2u64, imm0_63);
+
+v16i8 __builtin_msa_shf_b (v16i8, imm0_255);
+v8i16 __builtin_msa_shf_h (v8i16, imm0_255);
+v4i32 __builtin_msa_shf_w (v4i32, imm0_255);
+
+v16i8 __builtin_msa_sld_b (v16i8, v16i8, i32);
+v8i16 __builtin_msa_sld_h (v8i16, v8i16, i32);
+v4i32 __builtin_msa_sld_w (v4i32, v4i32, i32);
+v2i64 __builtin_msa_sld_d (v2i64, v2i64, i32);
+
+v16i8 __builtin_msa_sldi_b (v16i8, v16i8, imm0_15);
+v8i16 __builtin_msa_sldi_h (v8i16, v8i16, imm0_7);
+v4i32 __builtin_msa_sldi_w (v4i32, v4i32, imm0_3);
+v2i64 __builtin_msa_sldi_d (v2i64, v2i64, imm0_1);
+
+v16i8 __builtin_msa_sll_b (v16i8, v16i8);
+v8i16 __builtin_msa_sll_h (v8i16, v8i16);
+v4i32 __builtin_msa_sll_w (v4i32, v4i32);
+v2i64 __builtin_msa_sll_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_slli_b (v16i8, imm0_7);
+v8i16 __builtin_msa_slli_h (v8i16, imm0_15);
+v4i32 __builtin_msa_slli_w (v4i32, imm0_31);
+v2i64 __builtin_msa_slli_d (v2i64, imm0_63);
+
+v16i8 __builtin_msa_splat_b (v16i8, i32);
+v8i16 __builtin_msa_splat_h (v8i16, i32);
+v4i32 __builtin_msa_splat_w (v4i32, i32);
+v2i64 __builtin_msa_splat_d (v2i64, i32);
+
+v16i8 __builtin_msa_splati_b (v16i8, imm0_15);
+v8i16 __builtin_msa_splati_h (v8i16, imm0_7);
+v4i32 __builtin_msa_splati_w (v4i32, imm0_3);
+v2i64 __builtin_msa_splati_d (v2i64, imm0_1);
+
+v16i8 __builtin_msa_sra_b (v16i8, v16i8);
+v8i16 __builtin_msa_sra_h (v8i16, v8i16);
+v4i32 __builtin_msa_sra_w (v4i32, v4i32);
+v2i64 __builtin_msa_sra_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_srai_b (v16i8, imm0_7);
+v8i16 __builtin_msa_srai_h (v8i16, imm0_15);
+v4i32 __builtin_msa_srai_w (v4i32, imm0_31);
+v2i64 __builtin_msa_srai_d (v2i64, imm0_63);
+
+v16i8 __builtin_msa_srar_b (v16i8, v16i8);
+v8i16 __builtin_msa_srar_h (v8i16, v8i16);
+v4i32 __builtin_msa_srar_w (v4i32, v4i32);
+v2i64 __builtin_msa_srar_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_srari_b (v16i8, imm0_7);
+v8i16 __builtin_msa_srari_h (v8i16, imm0_15);
+v4i32 __builtin_msa_srari_w (v4i32, imm0_31);
+v2i64 __builtin_msa_srari_d (v2i64, imm0_63);
+
+v16i8 __builtin_msa_srl_b (v16i8, v16i8);
+v8i16 __builtin_msa_srl_h (v8i16, v8i16);
+v4i32 __builtin_msa_srl_w (v4i32, v4i32);
+v2i64 __builtin_msa_srl_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_srli_b (v16i8, imm0_7);
+v8i16 __builtin_msa_srli_h (v8i16, imm0_15);
+v4i32 __builtin_msa_srli_w (v4i32, imm0_31);
+v2i64 __builtin_msa_srli_d (v2i64, imm0_63);
+
+v16i8 __builtin_msa_srlr_b (v16i8, v16i8);
+v8i16 __builtin_msa_srlr_h (v8i16, v8i16);
+v4i32 __builtin_msa_srlr_w (v4i32, v4i32);
+v2i64 __builtin_msa_srlr_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_srlri_b (v16i8, imm0_7);
+v8i16 __builtin_msa_srlri_h (v8i16, imm0_15);
+v4i32 __builtin_msa_srlri_w (v4i32, imm0_31);
+v2i64 __builtin_msa_srlri_d (v2i64, imm0_63);
+
+void __builtin_msa_st_b (v16i8, void *, imm_n512_511);
+void __builtin_msa_st_h (v8i16, void *, imm_n1024_1022);
+void __builtin_msa_st_w (v4i32, void *, imm_n2048_2044);
+void __builtin_msa_st_d (v2i64, void *, imm_n4096_4088);
+
+v16i8 __builtin_msa_subs_s_b (v16i8, v16i8);
+v8i16 __builtin_msa_subs_s_h (v8i16, v8i16);
+v4i32 __builtin_msa_subs_s_w (v4i32, v4i32);
+v2i64 __builtin_msa_subs_s_d (v2i64, v2i64);
+
+v16u8 __builtin_msa_subs_u_b (v16u8, v16u8);
+v8u16 __builtin_msa_subs_u_h (v8u16, v8u16);
+v4u32 __builtin_msa_subs_u_w (v4u32, v4u32);
+v2u64 __builtin_msa_subs_u_d (v2u64, v2u64);
+
+v16u8 __builtin_msa_subsus_u_b (v16u8, v16i8);
+v8u16 __builtin_msa_subsus_u_h (v8u16, v8i16);
+v4u32 __builtin_msa_subsus_u_w (v4u32, v4i32);
+v2u64 __builtin_msa_subsus_u_d (v2u64, v2i64);
+
+v16i8 __builtin_msa_subsuu_s_b (v16u8, v16u8);
+v8i16 __builtin_msa_subsuu_s_h (v8u16, v8u16);
+v4i32 __builtin_msa_subsuu_s_w (v4u32, v4u32);
+v2i64 __builtin_msa_subsuu_s_d (v2u64, v2u64);
+
+v16i8 __builtin_msa_subv_b (v16i8, v16i8);
+v8i16 __builtin_msa_subv_h (v8i16, v8i16);
+v4i32 __builtin_msa_subv_w (v4i32, v4i32);
+v2i64 __builtin_msa_subv_d (v2i64, v2i64);
+
+v16i8 __builtin_msa_subvi_b (v16i8, imm0_31);
+v8i16 __builtin_msa_subvi_h (v8i16, imm0_31);
+v4i32 __builtin_msa_subvi_w (v4i32, imm0_31);
+v2i64 __builtin_msa_subvi_d (v2i64, imm0_31);
+
+v16i8 __builtin_msa_vshf_b (v16i8, v16i8, v16i8);
+v8i16 __builtin_msa_vshf_h (v8i16, v8i16, v8i16);
+v4i32 __builtin_msa_vshf_w (v4i32, v4i32, v4i32);
+v2i64 __builtin_msa_vshf_d (v2i64, v2i64, v2i64);
+
+v16u8 __builtin_msa_xor_v (v16u8, v16u8);
+
+v16u8 __builtin_msa_xori_b (v16u8, imm0_255);
+@end smallexample
+
@node Other MIPS Built-in Functions
@subsection Other MIPS Built-in Functions
@@ -13861,6 +14686,23 @@ The @code{__builtin_divde}, @code{__builtin_divdeo},
64-bit environment support ISA 2.06 or later.
The following built-in functions are available for the PowerPC family
+of processors, starting with ISA 3.0 or later (@option{-mcpu=power9}
+or @option{-mmodulo}):
+@smallexample
+long long __builtin_darn (void);
+long long __builtin_darn_raw (void);
+int __builtin_darn_32 (void);
+@end smallexample
+
+The @code{__builtin_darn} and @code{__builtin_darn_raw}
+functions require a
+64-bit environment supporting ISA 3.0 or later.
+The @code{__builtin_darn} function provides a 64-bit conditioned
+random number. The @code{__builtin_darn_raw} function provides a
+64-bit raw random number. The @code{__builtin_darn_32} function
+provides a 32-bit random number.
+
+The following built-in functions are available for the PowerPC family
of processors when hardware decimal floating point
(@option{-mhard-dfp}) is available:
@smallexample
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index e1ca26c9e38..373e82d97b4 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -362,6 +362,8 @@ together with GCC. Alternatively, if GMP is already installed but it
is not in your library search path, you will have to configure with the
@option{--with-gmp} configure option. See also @option{--with-gmp-lib}
and @option{--with-gmp-include}.
+The in-tree build is only supported with the GMP version that
+download_prerequisites installs.
@item MPFR Library version 2.4.2 (or later)
@@ -372,6 +374,8 @@ built together with GCC. Alternatively, if MPFR is already installed
but it is not in your default library search path, the
@option{--with-mpfr} configure option should be used. See also
@option{--with-mpfr-lib} and @option{--with-mpfr-include}.
+The in-tree build is only supported with the MPFR version that
+download_prerequisites installs.
@item MPC Library version 0.8.1 (or later)
@@ -382,6 +386,8 @@ will be built together with GCC. Alternatively, if MPC is already
installed but it is not in your default library search path, the
@option{--with-mpc} configure option should be used. See also
@option{--with-mpc-lib} and @option{--with-mpc-include}.
+The in-tree build is only supported with the MPC version that
+download_prerequisites installs.
@item isl Library version 0.16, 0.15, or 0.14.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 515d948ce71..f3d087f9cad 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -257,7 +257,8 @@ Objective-C and Objective-C++ Dialects}.
-Wc90-c99-compat -Wc99-c11-compat @gol
-Wc++-compat -Wc++11-compat -Wc++14-compat -Wcast-align -Wcast-qual @gol
-Wchar-subscripts -Wclobbered -Wcomment -Wconditionally-supported @gol
--Wconversion -Wcoverage-mismatch -Wno-cpp -Wdate-time -Wdelete-incomplete @gol
+-Wconversion -Wcoverage-mismatch -Wno-cpp -Wdangling-else -Wdate-time @gol
+-Wdelete-incomplete @gol
-Wno-deprecated -Wno-deprecated-declarations -Wno-designated-init @gol
-Wdisabled-optimization @gol
-Wno-discarded-qualifiers -Wno-discarded-array-qualifiers @gol
@@ -848,6 +849,7 @@ Objective-C and Objective-C++ Dialects}.
-mvirt -mno-virt @gol
-mxpa -mno-xpa @gol
-mmicromips -mno-micromips @gol
+-mmsa -mno-msa @gol
-mfpu=@var{fpu-type} @gol
-msmartmips -mno-smartmips @gol
-mpaired-single -mno-paired-single -mdmx -mno-mdmx @gol
@@ -946,7 +948,7 @@ See RS/6000 and PowerPC Options.
@emph{RL78 Options}
@gccoptlist{-msim -mmul=none -mmul=g13 -mmul=g14 -mallregs @gol
-mcpu=g10 -mcpu=g13 -mcpu=g14 -mg10 -mg13 -mg14 @gol
--m64bit-doubles -m32bit-doubles}
+-m64bit-doubles -m32bit-doubles -msave-mduc-in-interrupts}
@emph{RS/6000 and PowerPC Options}
@gccoptlist{-mcpu=@var{cpu-type} @gol
@@ -1004,7 +1006,8 @@ See RS/6000 and PowerPC Options.
-mupper-regs-df -mno-upper-regs-df -mupper-regs-sf -mno-upper-regs-sf @gol
-mupper-regs -mno-upper-regs -mmodulo -mno-modulo @gol
-mfloat128 -mno-float128 -mfloat128-hardware -mno-float128-hardware @gol
--mpower9-fusion -mno-mpower9-fusion -mpower9-vector -mno-power9-vector}
+-mpower9-fusion -mno-mpower9-fusion -mpower9-vector -mno-power9-vector @gol
+-mpower9-dform -mno-power9-dform -mlra -mno-lra}
@emph{RX Options}
@gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol
@@ -1050,7 +1053,7 @@ See RS/6000 and PowerPC Options.
-mb -ml -mdalign -mrelax @gol
-mbigtable -mfmovd -mrenesas -mno-renesas -mnomacsave @gol
-mieee -mno-ieee -mbitops -misize -minline-ic_invalidate -mpadstruct @gol
--mspace -mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
+-mprefergot -musermode -multcost=@var{number} -mdiv=@var{strategy} @gol
-mdivsi3_libfunc=@var{name} -mfixed-range=@var{register-range} @gol
-maccumulate-outgoing-args @gol
-matomic-model=@var{atomic-model} @gol
@@ -3539,6 +3542,7 @@ Options} and @ref{Objective-C and Objective-C++ Dialect Options}.
-Wc++11-compat -Wc++14-compat@gol
-Wchar-subscripts @gol
-Wcomment @gol
+-Wduplicate-decl-specifier @r{(C and Objective-C only)} @gol
-Wenum-compare @r{(in C/ObjC; this is on by default in C++)} @gol
-Wformat @gol
-Wimplicit @r{(C and Objective-C only)} @gol
@@ -3696,6 +3700,13 @@ float area(float radius)
the compiler performs the entire computation with @code{double}
because the floating-point literal is a @code{double}.
+@item -Wduplicate-decl-specifier @r{(C and Objective-C only)}
+@opindex Wduplicate-decl-specifier
+@opindex Wno-duplicate-decl-specifier
+Warn if a declaration has duplicate @code{const}, @code{volatile},
+@code{restrict} or @code{_Atomic} specifier. This warning is enabled by
+@option{-Wall}.
+
@item -Wformat
@itemx -Wformat=@var{n}
@opindex Wformat
@@ -3976,46 +3987,6 @@ Also warn if a comparison like @code{x<=y<=z} appears; this is
equivalent to @code{(x<=y ? 1 : 0) <= z}, which is a different
interpretation from that of ordinary mathematical notation.
-Also warn about constructions where there may be confusion to which
-@code{if} statement an @code{else} branch belongs. Here is an example of
-such a case:
-
-@smallexample
-@group
-@{
- if (a)
- if (b)
- foo ();
- else
- bar ();
-@}
-@end group
-@end smallexample
-
-In C/C++, every @code{else} branch belongs to the innermost possible
-@code{if} statement, which in this example is @code{if (b)}. This is
-often not what the programmer expected, as illustrated in the above
-example by indentation the programmer chose. When there is the
-potential for this confusion, GCC issues a warning when this flag
-is specified. To eliminate the warning, add explicit braces around
-the innermost @code{if} statement so there is no way the @code{else}
-can belong to the enclosing @code{if}. The resulting code
-looks like this:
-
-@smallexample
-@group
-@{
- if (a)
- @{
- if (b)
- foo ();
- else
- bar ();
- @}
-@}
-@end group
-@end smallexample
-
Also warn for dangerous uses of the GNU extension to
@code{?:} with omitted middle operand. When the condition
in the @code{?}: operator is a boolean expression, the omitted value is
@@ -5148,6 +5119,51 @@ compiler doesn't give this warning for types defined in the main .C
file, as those are unlikely to have multiple definitions.
@option{-Wsubobject-linkage} is enabled by default.
+@item -Wdangling-else
+@opindex Wdangling-else
+@opindex Wno-dangling-else
+Warn about constructions where there may be confusion to which
+@code{if} statement an @code{else} branch belongs. Here is an example of
+such a case:
+
+@smallexample
+@group
+@{
+ if (a)
+ if (b)
+ foo ();
+ else
+ bar ();
+@}
+@end group
+@end smallexample
+
+In C/C++, every @code{else} branch belongs to the innermost possible
+@code{if} statement, which in this example is @code{if (b)}. This is
+often not what the programmer expected, as illustrated in the above
+example by indentation the programmer chose. When there is the
+potential for this confusion, GCC issues a warning when this flag
+is specified. To eliminate the warning, add explicit braces around
+the innermost @code{if} statement so there is no way the @code{else}
+can belong to the enclosing @code{if}. The resulting code
+looks like this:
+
+@smallexample
+@group
+@{
+ if (a)
+ @{
+ if (b)
+ foo ();
+ else
+ bar ();
+ @}
+@}
+@end group
+@end smallexample
+
+This warning is enabled by @option{-Wparentheses}.
+
@item -Wdate-time
@opindex Wdate-time
@opindex Wno-date-time
@@ -6265,7 +6281,6 @@ also turns on the following optimization flags:
-foptimize-strlen @gol
-fpartial-inlining @gol
-fpeephole2 @gol
--frename-registers @gol
-freorder-blocks-algorithm=stc @gol
-freorder-blocks-and-partition -freorder-functions @gol
-frerun-cse-after-loop @gol
@@ -8573,8 +8588,7 @@ debug information format adopted by the target, however, it can
make debugging impossible, since variables no longer stay in
a ``home register''.
-Enabled by default with @option{-funroll-loops} and @option{-fpeel-loops},
-and also enabled at levels @option{-O2}, @option{-O3} and @option{-Os}.
+Enabled by default with @option{-funroll-loops} and @option{-fpeel-loops}.
@item -fschedule-fusion
@opindex fschedule-fusion
@@ -9020,6 +9034,10 @@ Large expressions slow the analyzer.
Bound on the complexity of the expressions in the scalar evolutions analyzer.
Complex expressions slow the analyzer.
+@item max-tree-if-conversion-phi-args
+Maximum number of arguments in a PHI supported by TREE if conversion
+unless the loop is marked with simd pragma.
+
@item vect-max-version-for-alignment-checks
The maximum number of run-time checks that can be performed when
doing loop versioning for alignment in the vectorizer.
@@ -9989,6 +10007,13 @@ for which this feature is experimental.
accepted, the former enables recovery for all sanitizers that support it,
the latter disables recovery for all sanitizers that support it.
+Even if a recovery mode is turned on the compiler side, it needs to be also
+enabled on the runtime library side, otherwise the failures are still fatal.
+The runtime library defaults to @code{halt_on_error=0} for
+ThreadSanitizer and UndefinedBehaviorSanitizer, while default value for
+AddressSanitizer is @code{halt_on_error=1}. This can be overridden through
+setting the @code{halt_on_error} flag in the corresponding environment variable.
+
Syntax without explicit @var{opts} parameter is deprecated. It is equivalent to
@smallexample
-fsanitize-recover=undefined,float-cast-overflow,float-divide-by-zero
@@ -12847,9 +12872,9 @@ These options are defined for AArch64 implementations:
@item -mabi=@var{name}
@opindex mabi
Generate code for the specified data model. Permissible values
-are @samp{ilp32} for SysV-like data model where int, long int and pointer
-are 32-bit, and @samp{lp64} for SysV-like data model where int is 32-bit,
-but long int and pointer are 64-bit.
+are @samp{ilp32} for SysV-like data model where int, long int and pointers
+are 32 bits, and @samp{lp64} for SysV-like data model where int is 32 bits,
+but long int and pointers are 64 bits.
The default depends on the specific target configuration. Note that
the LP64 and ILP32 ABIs are not link-compatible; you must compile your
@@ -12874,25 +12899,24 @@ Generate little-endian code. This is the default when GCC is configured for an
@item -mcmodel=tiny
@opindex mcmodel=tiny
Generate code for the tiny code model. The program and its statically defined
-symbols must be within 1GB of each other. Pointers are 64 bits. Programs can
-be statically or dynamically linked. This model is not fully implemented and
-mostly treated as @samp{small}.
+symbols must be within 1MB of each other. Programs can be statically or
+dynamically linked.
@item -mcmodel=small
@opindex mcmodel=small
Generate code for the small code model. The program and its statically defined
-symbols must be within 4GB of each other. Pointers are 64 bits. Programs can
-be statically or dynamically linked. This is the default code model.
+symbols must be within 4GB of each other. Programs can be statically or
+dynamically linked. This is the default code model.
@item -mcmodel=large
@opindex mcmodel=large
Generate code for the large code model. This makes no assumptions about
-addresses and sizes of sections. Pointers are 64 bits. Programs can be
-statically linked only.
+addresses and sizes of sections. Programs can be statically linked only.
@item -mstrict-align
@opindex mstrict-align
-Do not assume that unaligned memory references are handled by the system.
+Avoid generating memory accesses that may not be aligned on a natural object
+boundary as described in the architecture specification.
@item -momit-leaf-frame-pointer
@itemx -mno-omit-leaf-frame-pointer
@@ -12914,7 +12938,7 @@ of TLS variables.
@item -mtls-size=@var{size}
@opindex mtls-size
Specify bit size of immediate TLS offsets. Valid values are 12, 24, 32, 48.
-This option depends on binutils higher than 2.25.
+This option requires binutils 2.26 or newer.
@item -mfix-cortex-a53-835769
@itemx -mno-fix-cortex-a53-835769
@@ -12934,12 +12958,13 @@ corresponding flag to the linker.
@item -mlow-precision-recip-sqrt
@item -mno-low-precision-recip-sqrt
-@opindex -mlow-precision-recip-sqrt
-@opindex -mno-low-precision-recip-sqrt
-When calculating the reciprocal square root approximation,
-uses one less step than otherwise, thus reducing latency and precision.
-This is only relevant if @option{-ffast-math} enables the reciprocal square root
-approximation, which in turn depends on the target processor.
+@opindex mlow-precision-recip-sqrt
+@opindex mno-low-precision-recip-sqrt
+Enable or disable reciprocal square root approximation.
+This option only has an effect if @option{-ffast-math} or
+@option{-funsafe-math-optimizations} is used as well. Enabling this reduces
+precision of reciprocal square root results to about 16 bits for
+single precision and to 32 bits for double precision.
@item -march=@var{name}
@opindex march
@@ -12976,17 +13001,15 @@ Specify the name of the target processor for which GCC should tune the
performance of the code. Permissible values for this option are:
@samp{generic}, @samp{cortex-a35}, @samp{cortex-a53}, @samp{cortex-a57},
@samp{cortex-a72}, @samp{exynos-m1}, @samp{qdf24xx}, @samp{thunderx},
-@samp{xgene1}.
+@samp{xgene1}, @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53},
+@samp{native}.
-Additionally, this option can specify that GCC should tune the performance
-of the code for a big.LITTLE system. Permissible values for this
-option are: @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53}.
+The values @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53}
+specify that GCC should tune for a big.LITTLE system.
Additionally on native AArch64 GNU/Linux systems the value
-@samp{native} is available. This option causes the compiler to pick
-the architecture of and tune the performance of the code for the
-processor of the host system. This option has no effect if the
-compiler is unable to recognize the architecture of the host system.
+@samp{native} tunes performance to the host system. This option has no effect
+if the compiler is unable to recognize the processor of the host system.
Where none of @option{-mtune=}, @option{-mcpu=} or @option{-march=}
are specified, the code is tuned to perform well across a range
@@ -13006,12 +13029,6 @@ documented in the sub-section on
Feature Modifiers}. Where conflicting feature modifiers are
specified, the right-most feature is used.
-Additionally on native AArch64 GNU/Linux systems the value
-@samp{native} is available. This option causes the compiler to tune
-the performance of the code for the processor of the host system.
-This option has no effect if the compiler is unable to recognize the
-architecture of the host system.
-
GCC uses @var{name} to determine what kind of instructions it can emit when
generating assembly code (as if by @option{-march}) and to determine
the target processor for which to tune for performance (as if
@@ -13029,11 +13046,11 @@ across releases.
This option is only intended to be useful when developing GCC.
@item -mpc-relative-literal-loads
-@opindex mpcrelativeliteralloads
-Enable PC relative literal loads. If this option is used, literal
-pools are assumed to have a range of up to 1MiB and an appropriate
-instruction sequence is used. This option has no impact when used
-with @option{-mcmodel=tiny}.
+@opindex mpc-relative-literal-loads
+Enable PC-relative literal loads. With this option literal pools are
+accessed using a single instruction and emitted after each function. This
+limits the maximum size of functions to 1MB. This is enabled by default for
+@option{-mcmodel=tiny}.
@end table
@@ -13064,9 +13081,9 @@ Enable Large System Extension instructions. This is on by default for
@end table
-That is, @option{crypto} implies @option{simd} implies @option{fp}.
-Conversely, @option{nofp} (or equivalently, @option{-mgeneral-regs-only})
-implies @option{nosimd} implies @option{nocrypto}.
+Feature @option{crypto} implies @option{simd}, which implies @option{fp}.
+Conversely, @option{nofp} implies @option{nosimd}, which implies
+@option{nocrypto}.
@node Adapteva Epiphany Options
@subsection Adapteva Epiphany Options
@@ -13693,7 +13710,6 @@ Enable the use of indexed loads. This can be problematic because some
optimizers then assume that indexed stores exist, which is not
the case.
-@item -mlra
@opindex mlra
Enable Local Register Allocation. This is still experimental for ARC,
so by default the compiler uses standard reload
@@ -18106,7 +18122,7 @@ IEEE 754 floating-point data.
The @option{-mnan=legacy} option selects the legacy encoding. In this
case quiet NaNs (qNaNs) are denoted by the first bit of their trailing
-significand field being 0, whereas signalling NaNs (sNaNs) are denoted
+significand field being 0, whereas signaling NaNs (sNaNs) are denoted
by the first bit of their trailing significand field being 1.
The @option{-mnan=2008} option selects the IEEE 754-2008 encoding. In
@@ -19775,6 +19791,20 @@ Make the @code{double} data type be 64 bits (@option{-m64bit-doubles})
or 32 bits (@option{-m32bit-doubles}) in size. The default is
@option{-m32bit-doubles}.
+@item -msave-mduc-in-interrupts
+@item -mno-save-mduc-in-interrupts
+@opindex msave-mduc-in-interrupts
+@opindex mno-save-mduc-in-interrupts
+Specifies that interrupt handler functions should preserve the
+MDUC registers. This is only necessary if normal code might use
+the MDUC registers, for example because it performs multiplication
+and division operations. The default is to ignore the MDUC registers
+as this makes the interrupt handlers faster. The target option -mg13
+needs to be passed for this to work as this feature is only available
+on the G13 target (S2 core). The MDUC registers will only be saved
+if the interrupt handler performs a multiplication or division
+operation or it calls another function.
+
@end table
@node RS/6000 and PowerPC Options
@@ -19905,7 +19935,7 @@ following options:
-msimple-fpu -mstring -mmulhw -mdlmzb -mmfpgpr -mvsx @gol
-mcrypto -mdirect-move -mpower8-fusion -mpower8-vector @gol
-mquad-memory -mquad-memory-atomic -mmodulo -mfloat128 -mfloat128-hardware @gol
--mpower9-fusion -mpower9-vector}
+-mpower9-fusion -mpower9-vector -mpower9-dform}
The particular options set for any particular CPU varies between
compiler versions, depending on what setting seems to produce optimal
@@ -20029,6 +20059,12 @@ This switch enables or disables the generation of ISEL instructions.
This switch has been deprecated. Use @option{-misel} and
@option{-mno-isel} instead.
+@item -mlra
+@opindex mlra
+Enable Local Register Allocation. This is still experimental for PowerPC,
+so by default the compiler uses standard reload
+(i.e. @option{-mno-lra}).
+
@item -mspe
@itemx -mno-spe
@opindex mspe
@@ -20178,10 +20214,19 @@ processors.
@opindex mpower9-vector
@opindex mno-power9-vector
Generate code that uses (does not use) the vector and scalar
-instructions that were added in version 2.07 of the PowerPC ISA. Also
+instructions that were added in version 3.0 of the PowerPC ISA. Also
enable the use of built-in functions that allow more direct access to
the vector instructions.
+@item -mpower9-dform
+@itemx -mno-power9-dform
+@opindex mpower9-dform
+@opindex mno-power9-dform
+Enable (disable) scalar d-form (register + offset) memory instructions
+to load/store traditional Altivec registers. If the @var{LRA} register
+allocator is enabled, also enable (disable) vector d-form memory
+instructions.
+
@item -mfloat-gprs=@var{yes/single/double/no}
@itemx -mfloat-gprs
@opindex mfloat-gprs
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index 4c83719588a..e7b51c10593 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -3214,6 +3214,9 @@ Floating point register if the LFIWZX instruction is enabled or NO_REGS.
@item wD
Int constant that is the element number of the 64-bit scalar in a vector.
+@item wE
+Vector constant that can be loaded with the XXSPLTIB instruction.
+
@item wF
Memory operand suitable for power9 fusion load/stores.
@@ -3221,13 +3224,22 @@ Memory operand suitable for power9 fusion load/stores.
Memory operand suitable for TOC fusion memory references.
@item wL
-Int constant that is the element number that the MFVSRLD instruction
+Int constant that is the element number that the MFVSRLD instruction.
targets.
+@item wM
+Match vector constant with all 1's if the XXLORC instruction is available.
+
+@item wO
+A memory operand suitable for the ISA 3.0 vector d-form instructions.
+
@item wQ
A memory address that will work with the @code{lq} and @code{stq}
instructions.
+@item wS
+Vector constant that can be loaded with XXSPLTIB & sign extension.
+
@item h
@samp{MQ}, @samp{CTR}, or @samp{LINK} register
@@ -5015,7 +5027,7 @@ it is unspecified which of the two operands is returned as the result.
IEEE-conformant minimum and maximum operations. If one operand is a quiet
@code{NaN}, then the other operand is returned. If both operands are quiet
@code{NaN}, then a quiet @code{NaN} is returned. In the case when gcc supports
-signalling @code{NaN} (-fsignaling-nans) an invalid floating point exception is
+signaling @code{NaN} (-fsignaling-nans) an invalid floating point exception is
raised and a quiet @code{NaN} is returned.
All operands have mode @var{m}, which is a scalar or vector
@@ -6909,6 +6921,33 @@ The specific value that defines "set" is implementation defined, and
is normally based on what is performed by the native atomic test and set
instruction.
+@cindex @code{atomic_bit_test_and_set@var{mode}} instruction pattern
+@cindex @code{atomic_bit_test_and_complement@var{mode}} instruction pattern
+@cindex @code{atomic_bit_test_and_reset@var{mode}} instruction pattern
+@item @samp{atomic_bit_test_and_set@var{mode}}
+@itemx @samp{atomic_bit_test_and_complement@var{mode}}
+@itemx @samp{atomic_bit_test_and_reset@var{mode}}
+These patterns emit code for an atomic bitwise operation on memory with memory
+model semantics, and return the original value of the specified bit.
+Operand 0 is an output operand which contains the value of the specified bit
+from the memory location before the operation was performed. Operand 1 is the
+memory on which the atomic operation is performed. Operand 2 is the bit within
+the operand, starting with least significant bit. Operand 3 is the memory model
+to be used by the operation. Operand 4 is a flag - it is @code{const1_rtx}
+if operand 0 should contain the original value of the specified bit in the
+least significant bit of the operand, and @code{const0_rtx} if the bit should
+be in its original position in the operand.
+@code{atomic_bit_test_and_set@var{mode}} atomically sets the specified bit after
+remembering its original value, @code{atomic_bit_test_and_complement@var{mode}}
+inverts the specified bit and @code{atomic_bit_test_and_reset@var{mode}} clears
+the specified bit.
+
+If these patterns are not defined, attempts will be made to use
+@code{atomic_fetch_or@var{mode}}, @code{atomic_fetch_xor@var{mode}} or
+@code{atomic_fetch_and@var{mode}} instruction patterns, or their @code{sync}
+counterparts. If none of these are available a compare-and-swap
+loop will be used.
+
@cindex @code{mem_thread_fence@var{mode}} instruction pattern
@item @samp{mem_thread_fence@var{mode}}
This pattern emits code required to implement a thread fence with
diff --git a/gcc/doc/sourcebuild.texi b/gcc/doc/sourcebuild.texi
index 9a349a3f03a..3142cd53ae5 100644
--- a/gcc/doc/sourcebuild.texi
+++ b/gcc/doc/sourcebuild.texi
@@ -1641,6 +1641,9 @@ MIPS target can generate MIPS16 code.
MIPS target is a Loongson-2E or -2F target using an ABI that supports
the Loongson vector modes.
+@item mips_msa
+MIPS target supports @code{-mmsa}, MIPS SIMD Architecture (MSA).
+
@item mips_newabi_large_long_double
MIPS target supports @code{long double} larger than @code{double}
when using the new ABI.
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 057ac9aa517..8c7f2a124fe 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11504,20 +11504,6 @@ and @var{type2}, or @code{NULL} if validity should be determined by
the front end.
@end deftypefn
-@deftypefn {Target Hook} {const char *} TARGET_INVALID_PARAMETER_TYPE (const_tree @var{type})
-If defined, this macro returns the diagnostic message when it is
-invalid for functions to include parameters of type @var{type},
-or @code{NULL} if validity should be determined by
-the front end. This is currently used only by the C and C++ front ends.
-@end deftypefn
-
-@deftypefn {Target Hook} {const char *} TARGET_INVALID_RETURN_TYPE (const_tree @var{type})
-If defined, this macro returns the diagnostic message when it is
-invalid for functions to have return type @var{type},
-or @code{NULL} if validity should be determined by
-the front end. This is currently used only by the C and C++ front ends.
-@end deftypefn
-
@deftypefn {Target Hook} tree TARGET_PROMOTED_TYPE (const_tree @var{type})
If defined, this target hook returns the type to which values of
@var{type} should be promoted when they appear in expressions,
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 643f0eb2521..f963a586612 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -8173,10 +8173,6 @@ and scanf formatter settings.
@hook TARGET_INVALID_BINARY_OP
-@hook TARGET_INVALID_PARAMETER_TYPE
-
-@hook TARGET_INVALID_RETURN_TYPE
-
@hook TARGET_PROMOTED_TYPE
@hook TARGET_CONVERT_TO_TYPE
diff --git a/gcc/dse.c b/gcc/dse.c
index b03616102b5..68d06bb444f 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -2269,6 +2269,7 @@ scan_insn (bb_info_t bb_info, rtx_insn *insn)
if (CALL_P (insn))
{
bool const_call;
+ rtx call, sym;
tree memset_call = NULL_TREE;
insn_info->cannot_delete = true;
@@ -2278,24 +2279,16 @@ scan_insn (bb_info_t bb_info, rtx_insn *insn)
been pushed onto the stack.
memset and bzero don't read memory either. */
const_call = RTL_CONST_CALL_P (insn);
- if (!const_call)
- {
- rtx call = get_call_rtx_from (insn);
- if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
- {
- rtx symbol = XEXP (XEXP (call, 0), 0);
- if (SYMBOL_REF_DECL (symbol)
- && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL)
- {
- if ((DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol))
- == BUILT_IN_NORMAL
- && (DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol))
- == BUILT_IN_MEMSET))
- || SYMBOL_REF_DECL (symbol) == block_clear_fn)
- memset_call = SYMBOL_REF_DECL (symbol);
- }
- }
- }
+ if (!const_call
+ && (call = get_call_rtx_from (insn))
+ && (sym = XEXP (XEXP (call, 0), 0))
+ && GET_CODE (sym) == SYMBOL_REF
+ && SYMBOL_REF_DECL (sym)
+ && TREE_CODE (SYMBOL_REF_DECL (sym)) == FUNCTION_DECL
+ && DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (sym)) == BUILT_IN_NORMAL
+ && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (sym)) == BUILT_IN_MEMSET)
+ memset_call = SYMBOL_REF_DECL (sym);
+
if (const_call || memset_call)
{
insn_info_t i_ptr = active_local_stores;
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 463863dc381..b0173f7a5ce 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -15407,6 +15407,7 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
case DW_OP_swap:
case DW_OP_rot:
case DW_OP_abs:
+ case DW_OP_neg:
case DW_OP_not:
case DW_OP_plus_uconst:
case DW_OP_skip:
@@ -15543,7 +15544,6 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
case DW_OP_minus:
case DW_OP_mod:
case DW_OP_mul:
- case DW_OP_neg:
case DW_OP_or:
case DW_OP_plus:
case DW_OP_shl:
@@ -15571,7 +15571,7 @@ resolve_args_picking_1 (dw_loc_descr_ref loc, unsigned initial_frame_offset,
if (stack_usage == NULL)
return false;
- frame_offset += *stack_usage;
+ frame_offset_ += *stack_usage;
break;
}
@@ -17806,7 +17806,7 @@ native_encode_initializer (tree init, unsigned char *array, int size)
fieldsize = tree_to_shwi (DECL_SIZE_UNIT (field));
pos = int_byte_position (field);
gcc_assert (pos + fieldsize <= size);
- if (val
+ if (val && fieldsize != 0
&& !native_encode_initializer (val, array + pos, fieldsize))
return false;
}
@@ -18621,15 +18621,16 @@ add_prototyped_attribute (dw_die_ref die, tree func_type)
}
/* Add an 'abstract_origin' attribute below a given DIE. The DIE is found
- by looking in either the type declaration or object declaration
- equate table. */
+ by looking in the type declaration, the object declaration equate table or
+ the block mapping. */
static inline dw_die_ref
add_abstract_origin_attribute (dw_die_ref die, tree origin)
{
dw_die_ref origin_die = NULL;
- if (TREE_CODE (origin) != FUNCTION_DECL)
+ if (TREE_CODE (origin) != FUNCTION_DECL
+ && TREE_CODE (origin) != BLOCK)
{
/* We may have gotten separated from the block for the inlined
function, if we're in an exception handler or some such; make
@@ -18651,6 +18652,8 @@ add_abstract_origin_attribute (dw_die_ref die, tree origin)
origin_die = lookup_decl_die (origin);
else if (TYPE_P (origin))
origin_die = lookup_type_die (origin);
+ else if (TREE_CODE (origin) == BLOCK)
+ origin_die = BLOCK_DIE (origin);
/* XXX: Functions that are never lowered don't always have correct block
trees (in the case of java, they simply have no block tree, in some other
@@ -19402,11 +19405,13 @@ gen_entry_point_die (tree decl, dw_die_ref context_die)
static void
retry_incomplete_types (void)
{
+ set_early_dwarf s;
int i;
for (i = vec_safe_length (incomplete_types) - 1; i >= 0; i--)
if (should_emit_struct_debug ((*incomplete_types)[i], DINFO_USAGE_DIR_USE))
gen_type_die ((*incomplete_types)[i], comp_unit_die ());
+ vec_safe_truncate (incomplete_types, 0);
}
/* Determine what tag to use for a record type. */
@@ -21467,6 +21472,10 @@ gen_lexical_block_die (tree stmt, dw_die_ref context_die)
BLOCK_DIE (stmt) = stmt_die;
old_die = NULL;
}
+
+ tree origin = block_ultimate_origin (stmt);
+ if (origin != NULL_TREE && origin != stmt)
+ add_abstract_origin_attribute (stmt_die, origin);
}
if (old_die)
@@ -27383,10 +27392,6 @@ dwarf2out_finish (const char *filename)
resolve_addr (comp_unit_die ());
move_marked_base_types ();
- /* Walk through the list of incomplete types again, trying once more to
- emit full debugging info for them. */
- retry_incomplete_types ();
-
if (flag_eliminate_unused_debug_types)
prune_unused_types ();
@@ -27687,6 +27692,10 @@ dwarf2out_finish (const char *filename)
static void
dwarf2out_early_finish (void)
{
+ /* Walk through the list of incomplete types again, trying once more to
+ emit full debugging info for them. */
+ retry_incomplete_types ();
+
/* The point here is to flush out the limbo list so that it is empty
and we don't need to stream it for LTO. */
flush_limbo_die_list ();
diff --git a/gcc/except.c b/gcc/except.c
index cf1df8cc6ec..e494915514f 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -130,6 +130,7 @@ along with GCC; see the file COPYING3. If not see
#include "explow.h"
#include "stmt.h"
#include "expr.h"
+#include "calls.h"
#include "libfuncs.h"
#include "except.h"
#include "output.h"
@@ -1173,20 +1174,22 @@ sjlj_emit_function_enter (rtx_code_label *dispatch_label)
if (dispatch_label)
{
+ rtx addr = plus_constant (Pmode, XEXP (fc, 0), sjlj_fc_jbuf_ofs);
+
#ifdef DONT_USE_BUILTIN_SETJMP
- rtx x;
- x = emit_library_call_value (setjmp_libfunc, NULL_RTX, LCT_RETURNS_TWICE,
- TYPE_MODE (integer_type_node), 1,
- plus_constant (Pmode, XEXP (fc, 0),
- sjlj_fc_jbuf_ofs), Pmode);
+ addr = copy_addr_to_reg (addr);
+ addr = convert_memory_address (ptr_mode, addr);
+ tree addr_tree = make_tree (ptr_type_node, addr);
+
+ tree fn = builtin_decl_implicit (BUILT_IN_SETJMP);
+ tree call_expr = build_call_expr (fn, 1, addr_tree);
+ rtx x = expand_call (call_expr, NULL_RTX, false);
emit_cmp_and_jump_insns (x, const0_rtx, NE, 0,
TYPE_MODE (integer_type_node), 0,
dispatch_label, REG_BR_PROB_BASE / 100);
#else
- expand_builtin_setjmp_setup (plus_constant (Pmode, XEXP (fc, 0),
- sjlj_fc_jbuf_ofs),
- dispatch_label);
+ expand_builtin_setjmp_setup (addr, dispatch_label);
#endif
}
diff --git a/gcc/expr.c b/gcc/expr.c
index 812c5445278..3c7e71f7130 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -109,14 +109,12 @@ static bool block_move_libcall_safe_for_call_parm (void);
static bool emit_block_move_via_movmem (rtx, rtx, rtx, unsigned, unsigned, HOST_WIDE_INT,
unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT);
-static tree emit_block_move_libcall_fn (int);
static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned);
static rtx clear_by_pieces_1 (void *, HOST_WIDE_INT, machine_mode);
static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
static void store_by_pieces_1 (struct store_by_pieces_d *, unsigned int);
static void store_by_pieces_2 (insn_gen_fn, machine_mode,
struct store_by_pieces_d *);
-static tree clear_storage_libcall_fn (int);
static rtx_insn *compress_float_constant (rtx, rtx);
static rtx get_subtarget (rtx);
static void store_constructor_field (rtx, unsigned HOST_WIDE_INT,
@@ -1132,7 +1130,7 @@ emit_block_move_hints (rtx x, rtx y, rtx size, enum block_op_methods method,
mark_addressable (y_expr);
if (x_expr)
mark_addressable (x_expr);
- retval = emit_block_move_via_libcall (x, y, size,
+ retval = emit_block_copy_via_libcall (x, y, size,
method == BLOCK_OP_TAILCALL);
}
@@ -1175,7 +1173,7 @@ block_move_libcall_safe_for_call_parm (void)
/* If registers go on the stack anyway, any argument is sure to clobber
an outgoing argument. */
#if defined (REG_PARM_STACK_SPACE)
- fn = emit_block_move_libcall_fn (false);
+ fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
/* Avoid set but not used warning if *REG_PARM_STACK_SPACE doesn't
depend on its argument. */
(void) fn;
@@ -1191,7 +1189,7 @@ block_move_libcall_safe_for_call_parm (void)
cumulative_args_t args_so_far;
tree fn, arg;
- fn = emit_block_move_libcall_fn (false);
+ fn = builtin_decl_implicit (BUILT_IN_MEMCPY);
INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3);
args_so_far = pack_cumulative_args (&args_so_far_v);
@@ -1310,106 +1308,6 @@ emit_block_move_via_movmem (rtx x, rtx y, rtx size, unsigned int align,
return false;
}
-/* A subroutine of emit_block_move. Expand a call to memcpy.
- Return the return value from memcpy, 0 otherwise. */
-
-rtx
-emit_block_move_via_libcall (rtx dst, rtx src, rtx size, bool tailcall)
-{
- rtx dst_addr, src_addr;
- tree call_expr, fn, src_tree, dst_tree, size_tree;
- machine_mode size_mode;
- rtx retval;
-
- /* Emit code to copy the addresses of DST and SRC and SIZE into new
- pseudos. We can then place those new pseudos into a VAR_DECL and
- use them later. */
-
- dst_addr = copy_addr_to_reg (XEXP (dst, 0));
- src_addr = copy_addr_to_reg (XEXP (src, 0));
-
- dst_addr = convert_memory_address (ptr_mode, dst_addr);
- src_addr = convert_memory_address (ptr_mode, src_addr);
-
- dst_tree = make_tree (ptr_type_node, dst_addr);
- src_tree = make_tree (ptr_type_node, src_addr);
-
- size_mode = TYPE_MODE (sizetype);
-
- size = convert_to_mode (size_mode, size, 1);
- size = copy_to_mode_reg (size_mode, size);
-
- /* It is incorrect to use the libcall calling conventions to call
- memcpy in this context. This could be a user call to memcpy and
- the user may wish to examine the return value from memcpy. For
- targets where libcalls and normal calls have different conventions
- for returning pointers, we could end up generating incorrect code. */
-
- size_tree = make_tree (sizetype, size);
-
- fn = emit_block_move_libcall_fn (true);
- call_expr = build_call_expr (fn, 3, dst_tree, src_tree, size_tree);
- CALL_EXPR_TAILCALL (call_expr) = tailcall;
-
- retval = expand_normal (call_expr);
-
- return retval;
-}
-
-/* A subroutine of emit_block_move_via_libcall. Create the tree node
- for the function we use for block copies. */
-
-static GTY(()) tree block_move_fn;
-
-void
-init_block_move_fn (const char *asmspec)
-{
- if (!block_move_fn)
- {
- tree args, fn, attrs, attr_args;
-
- fn = get_identifier ("memcpy");
- args = build_function_type_list (ptr_type_node, ptr_type_node,
- const_ptr_type_node, sizetype,
- NULL_TREE);
-
- fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, fn, args);
- DECL_EXTERNAL (fn) = 1;
- TREE_PUBLIC (fn) = 1;
- DECL_ARTIFICIAL (fn) = 1;
- TREE_NOTHROW (fn) = 1;
- DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
- DECL_VISIBILITY_SPECIFIED (fn) = 1;
-
- attr_args = build_tree_list (NULL_TREE, build_string (1, "1"));
- attrs = tree_cons (get_identifier ("fn spec"), attr_args, NULL);
-
- decl_attributes (&fn, attrs, ATTR_FLAG_BUILT_IN);
-
- block_move_fn = fn;
- }
-
- if (asmspec)
- set_user_assembler_name (block_move_fn, asmspec);
-}
-
-static tree
-emit_block_move_libcall_fn (int for_call)
-{
- static bool emitted_extern;
-
- if (!block_move_fn)
- init_block_move_fn (NULL);
-
- if (for_call && !emitted_extern)
- {
- emitted_extern = true;
- make_decl_rtl (block_move_fn);
- }
-
- return block_move_fn;
-}
-
/* A subroutine of emit_block_move. Copy the data via an explicit
loop. This is used only when libcalls are forbidden. */
/* ??? It'd be nice to copy in hunks larger than QImode. */
@@ -1464,6 +1362,39 @@ emit_block_move_via_loop (rtx x, rtx y, rtx size,
true, top_label, REG_BR_PROB_BASE * 90 / 100);
}
+/* Expand a call to memcpy or memmove or memcmp, and return the result.
+ TAILCALL is true if this is a tail call. */
+
+rtx
+emit_block_op_via_libcall (enum built_in_function fncode, rtx dst, rtx src,
+ rtx size, bool tailcall)
+{
+ rtx dst_addr, src_addr;
+ tree call_expr, dst_tree, src_tree, size_tree;
+ machine_mode size_mode;
+
+ dst_addr = copy_addr_to_reg (XEXP (dst, 0));
+ dst_addr = convert_memory_address (ptr_mode, dst_addr);
+ dst_tree = make_tree (ptr_type_node, dst_addr);
+
+ src_addr = copy_addr_to_reg (XEXP (src, 0));
+ src_addr = convert_memory_address (ptr_mode, src_addr);
+ src_tree = make_tree (ptr_type_node, src_addr);
+
+ size_mode = TYPE_MODE (sizetype);
+ size = convert_to_mode (size_mode, size, 1);
+ size = copy_to_mode_reg (size_mode, size);
+ size_tree = make_tree (sizetype, size);
+
+ /* It is incorrect to use the libcall calling conventions for calls to
+ memcpy/memmove/memcmp because they can be provided by the user. */
+ tree fn = builtin_decl_implicit (fncode);
+ call_expr = build_call_expr (fn, 3, dst_tree, src_tree, size_tree);
+ CALL_EXPR_TAILCALL (call_expr) = tailcall;
+
+ return expand_call (call_expr, NULL_RTX, false);
+}
+
/* Copy all or part of a value X into registers starting at REGNO.
The number of registers to be filled is NREGS. */
@@ -2784,85 +2715,26 @@ set_storage_via_libcall (rtx object, rtx size, rtx val, bool tailcall)
{
tree call_expr, fn, object_tree, size_tree, val_tree;
machine_mode size_mode;
- rtx retval;
-
- /* Emit code to copy OBJECT and SIZE into new pseudos. We can then
- place those into new pseudos into a VAR_DECL and use them later. */
object = copy_addr_to_reg (XEXP (object, 0));
+ object_tree = make_tree (ptr_type_node, object);
+
+ if (!CONST_INT_P (val))
+ val = convert_to_mode (TYPE_MODE (integer_type_node), val, 1);
+ val_tree = make_tree (integer_type_node, val);
size_mode = TYPE_MODE (sizetype);
size = convert_to_mode (size_mode, size, 1);
size = copy_to_mode_reg (size_mode, size);
-
- /* It is incorrect to use the libcall calling conventions to call
- memset in this context. This could be a user call to memset and
- the user may wish to examine the return value from memset. For
- targets where libcalls and normal calls have different conventions
- for returning pointers, we could end up generating incorrect code. */
-
- object_tree = make_tree (ptr_type_node, object);
- if (!CONST_INT_P (val))
- val = convert_to_mode (TYPE_MODE (integer_type_node), val, 1);
size_tree = make_tree (sizetype, size);
- val_tree = make_tree (integer_type_node, val);
- fn = clear_storage_libcall_fn (true);
+ /* It is incorrect to use the libcall calling conventions for calls to
+ memset because it can be provided by the user. */
+ fn = builtin_decl_implicit (BUILT_IN_MEMSET);
call_expr = build_call_expr (fn, 3, object_tree, val_tree, size_tree);
CALL_EXPR_TAILCALL (call_expr) = tailcall;
- retval = expand_normal (call_expr);
-
- return retval;
-}
-
-/* A subroutine of set_storage_via_libcall. Create the tree node
- for the function we use for block clears. */
-
-tree block_clear_fn;
-
-void
-init_block_clear_fn (const char *asmspec)
-{
- if (!block_clear_fn)
- {
- tree fn, args;
-
- fn = get_identifier ("memset");
- args = build_function_type_list (ptr_type_node, ptr_type_node,
- integer_type_node, sizetype,
- NULL_TREE);
-
- fn = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL, fn, args);
- DECL_EXTERNAL (fn) = 1;
- TREE_PUBLIC (fn) = 1;
- DECL_ARTIFICIAL (fn) = 1;
- TREE_NOTHROW (fn) = 1;
- DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
- DECL_VISIBILITY_SPECIFIED (fn) = 1;
-
- block_clear_fn = fn;
- }
-
- if (asmspec)
- set_user_assembler_name (block_clear_fn, asmspec);
-}
-
-static tree
-clear_storage_libcall_fn (int for_call)
-{
- static bool emitted_extern;
-
- if (!block_clear_fn)
- init_block_clear_fn (NULL);
-
- if (for_call && !emitted_extern)
- {
- emitted_extern = true;
- make_decl_rtl (block_clear_fn);
- }
-
- return block_clear_fn;
+ return expand_call (call_expr, NULL_RTX, false);
}
/* Expand a setmem pattern; return true if successful. */
@@ -5157,12 +5029,7 @@ expand_assignment (tree to, tree from, bool nontemporal)
size = expr_size (from);
from_rtx = expand_normal (from);
- emit_library_call (memmove_libfunc, LCT_NORMAL,
- VOIDmode, 3, XEXP (to_rtx, 0), Pmode,
- XEXP (from_rtx, 0), Pmode,
- convert_to_mode (TYPE_MODE (sizetype),
- size, TYPE_UNSIGNED (sizetype)),
- TYPE_MODE (sizetype));
+ emit_block_move_via_libcall (XEXP (to_rtx, 0), XEXP (from_rtx, 0), size);
preserve_temp_slots (to_rtx);
pop_temp_slots ();
@@ -9358,6 +9225,23 @@ expand_expr_real_2 (sepops ops, rtx target, machine_mode tmode,
target = expand_vec_cond_expr (type, treeop0, treeop1, treeop2, target);
return target;
+ case BIT_INSERT_EXPR:
+ {
+ unsigned bitpos = tree_to_uhwi (treeop2);
+ unsigned bitsize;
+ if (INTEGRAL_TYPE_P (TREE_TYPE (treeop1)))
+ bitsize = TYPE_PRECISION (TREE_TYPE (treeop1));
+ else
+ bitsize = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (treeop1)));
+ rtx op0 = expand_normal (treeop0);
+ rtx op1 = expand_normal (treeop1);
+ rtx dst = gen_reg_rtx (mode);
+ emit_move_insn (dst, op0);
+ store_bit_field (dst, bitsize, bitpos, 0, 0,
+ TYPE_MODE (TREE_TYPE (treeop1)), op1, false);
+ return dst;
+ }
+
default:
gcc_unreachable ();
}
@@ -11653,5 +11537,3 @@ int_expr_size (tree exp)
return tree_to_shwi (size);
}
-
-#include "gt-expr.h"
diff --git a/gcc/expr.h b/gcc/expr.h
index c5b302a383b..fea69a27e3a 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -71,8 +71,29 @@ extern rtx convert_to_mode (machine_mode, rtx, int);
/* Convert an rtx to MODE from OLDMODE and return the result. */
extern rtx convert_modes (machine_mode, machine_mode, rtx, int);
-/* Emit code to move a block Y to a block X. */
+/* Expand a call to memcpy or memmove or memcmp, and return the result. */
+extern rtx emit_block_op_via_libcall (enum built_in_function, rtx, rtx, rtx,
+ bool);
+
+static inline rtx
+emit_block_copy_via_libcall (rtx dst, rtx src, rtx size, bool tailcall = false)
+{
+ return emit_block_op_via_libcall (BUILT_IN_MEMCPY, dst, src, size, tailcall);
+}
+static inline rtx
+emit_block_move_via_libcall (rtx dst, rtx src, rtx size, bool tailcall = false)
+{
+ return emit_block_op_via_libcall (BUILT_IN_MEMMOVE, dst, src, size, tailcall);
+}
+
+static inline rtx
+emit_block_comp_via_libcall (rtx dst, rtx src, rtx size, bool tailcall = false)
+{
+ return emit_block_op_via_libcall (BUILT_IN_MEMCMP, dst, src, size, tailcall);
+}
+
+/* Emit code to move a block Y to a block X. */
enum block_op_methods
{
BLOCK_OP_NORMAL,
@@ -82,12 +103,7 @@ enum block_op_methods
BLOCK_OP_TAILCALL
};
-extern GTY(()) tree block_clear_fn;
-extern void init_block_move_fn (const char *);
-extern void init_block_clear_fn (const char *);
-
extern rtx emit_block_move (rtx, rtx, rtx, enum block_op_methods);
-extern rtx emit_block_move_via_libcall (rtx, rtx, rtx, bool);
extern rtx emit_block_move_hints (rtx, rtx, rtx, enum block_op_methods,
unsigned int, HOST_WIDE_INT,
unsigned HOST_WIDE_INT,
@@ -166,7 +182,7 @@ extern rtx clear_storage_hints (rtx, rtx, enum block_op_methods,
unsigned HOST_WIDE_INT,
unsigned HOST_WIDE_INT);
/* The same, but always output an library call. */
-rtx set_storage_via_libcall (rtx, rtx, rtx, bool);
+extern rtx set_storage_via_libcall (rtx, rtx, rtx, bool = false);
/* Expand a setmem pattern; return true if successful. */
extern bool set_storage_via_setmem (rtx, rtx, rtx, unsigned int,
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 82016763621..dd57e167098 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -178,30 +178,6 @@ enum stack_check_type
FULL_BUILTIN_STACK_CHECK
};
-/* Names for the different levels of -Wstrict-overflow=N. The numeric
- values here correspond to N. */
-enum warn_strict_overflow_code
-{
- /* Overflow warning that should be issued with -Wall: a questionable
- construct that is easy to avoid even when using macros. Example:
- folding (x + CONSTANT > x) to 1. */
- WARN_STRICT_OVERFLOW_ALL = 1,
- /* Overflow warning about folding a comparison to a constant because
- of undefined signed overflow, other than cases covered by
- WARN_STRICT_OVERFLOW_ALL. Example: folding (abs (x) >= 0) to 1
- (this is false when x == INT_MIN). */
- WARN_STRICT_OVERFLOW_CONDITIONAL = 2,
- /* Overflow warning about changes to comparisons other than folding
- them to a constant. Example: folding (x + 1 > 1) to (x > 0). */
- WARN_STRICT_OVERFLOW_COMPARISON = 3,
- /* Overflow warnings not covered by the above cases. Example:
- folding ((x * 10) / 5) to (x * 2). */
- WARN_STRICT_OVERFLOW_MISC = 4,
- /* Overflow warnings about reducing magnitude of constants in
- comparison. Example: folding (x + 2 > y) to (x + 1 >= y). */
- WARN_STRICT_OVERFLOW_MAGNITUDE = 5
-};
-
/* Floating-point contraction mode. */
enum fp_contract_mode {
FP_CONTRACT_OFF = 0,
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3c389ee446e..556fc73a33d 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -117,14 +117,8 @@ static enum tree_code compcode_to_comparison (enum comparison_code);
static int operand_equal_for_comparison_p (tree, tree, tree);
static int twoval_comparison_p (tree, tree *, tree *, int *);
static tree eval_subst (location_t, tree, tree, tree, tree, tree);
-static tree make_bit_field_ref (location_t, tree, tree,
- HOST_WIDE_INT, HOST_WIDE_INT, int, int);
static tree optimize_bit_field_compare (location_t, enum tree_code,
tree, tree, tree);
-static tree decode_field_reference (location_t, tree, HOST_WIDE_INT *,
- HOST_WIDE_INT *,
- machine_mode *, int *, int *, int *,
- tree *, tree *);
static int simple_operand_p (const_tree);
static bool simple_operand_p_2 (tree);
static tree range_binop (enum tree_code, tree, tree, int, tree, int);
@@ -297,7 +291,7 @@ fold_deferring_overflow_warnings_p (void)
/* This is called when we fold something based on the fact that signed
overflow is undefined. */
-static void
+void
fold_overflow_warning (const char* gmsgid, enum warn_strict_overflow_code wc)
{
if (fold_deferring_overflow_warnings > 0)
@@ -836,11 +830,10 @@ split_tree (location_t loc, tree in, tree type, enum tree_code code,
*minus_litp = *litp, *litp = 0;
if (neg_conp_p)
*conp = negate_expr (*conp);
- if (neg_var_p)
+ if (neg_var_p && var)
{
- /* Convert to TYPE before negating a pointer type expr. */
- if (var && POINTER_TYPE_P (TREE_TYPE (var)))
- var = fold_convert_loc (loc, type, var);
+ /* Convert to TYPE before negating. */
+ var = fold_convert_loc (loc, type, var);
var = negate_expr (var);
}
}
@@ -863,10 +856,12 @@ split_tree (location_t loc, tree in, tree type, enum tree_code code,
else if (*minus_litp)
*litp = *minus_litp, *minus_litp = 0;
*conp = negate_expr (*conp);
- /* Convert to TYPE before negating a pointer type expr. */
- if (var && POINTER_TYPE_P (TREE_TYPE (var)))
- var = fold_convert_loc (loc, type, var);
- var = negate_expr (var);
+ if (var)
+ {
+ /* Convert to TYPE before negating. */
+ var = fold_convert_loc (loc, type, var);
+ var = negate_expr (var);
+ }
}
return var;
@@ -2758,8 +2753,8 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
if (arg0 != arg1)
{
inchash::hash hstate0 (0), hstate1 (0);
- inchash::add_expr (arg0, hstate0, flags);
- inchash::add_expr (arg1, hstate1, flags);
+ inchash::add_expr (arg0, hstate0, flags | OEP_HASH_CHECK);
+ inchash::add_expr (arg1, hstate1, flags | OEP_HASH_CHECK);
hashval_t h0 = hstate0.end ();
hashval_t h1 = hstate1.end ();
gcc_assert (h0 == h1);
@@ -3168,6 +3163,7 @@ operand_equal_p (const_tree arg0, const_tree arg1, unsigned int flags)
case VEC_COND_EXPR:
case DOT_PROD_EXPR:
+ case BIT_INSERT_EXPR:
return OP_SAME (0) && OP_SAME (1) && OP_SAME (2);
default:
@@ -3802,15 +3798,23 @@ distribute_real_division (location_t loc, enum tree_code code, tree type,
/* Return a BIT_FIELD_REF of type TYPE to refer to BITSIZE bits of INNER
starting at BITPOS. The field is unsigned if UNSIGNEDP is nonzero
- and uses reverse storage order if REVERSEP is nonzero. */
+ and uses reverse storage order if REVERSEP is nonzero. ORIG_INNER
+ is the original memory reference used to preserve the alias set of
+ the access. */
static tree
-make_bit_field_ref (location_t loc, tree inner, tree type,
+make_bit_field_ref (location_t loc, tree inner, tree orig_inner, tree type,
HOST_WIDE_INT bitsize, HOST_WIDE_INT bitpos,
int unsignedp, int reversep)
{
tree result, bftype;
+ if (get_alias_set (inner) != get_alias_set (orig_inner))
+ inner = fold_build2 (MEM_REF, TREE_TYPE (inner),
+ build_fold_addr_expr (inner),
+ build_int_cst
+ (reference_alias_ptr_type (orig_inner), 0));
+
if (bitpos == 0 && !reversep)
{
tree size = TYPE_SIZE (TREE_TYPE (inner));
@@ -3936,13 +3940,13 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
and return. */
return fold_build2_loc (loc, code, compare_type,
fold_build2_loc (loc, BIT_AND_EXPR, unsigned_type,
- make_bit_field_ref (loc, linner,
+ make_bit_field_ref (loc, linner, lhs,
unsigned_type,
nbitsize, nbitpos,
1, lreversep),
mask),
fold_build2_loc (loc, BIT_AND_EXPR, unsigned_type,
- make_bit_field_ref (loc, rinner,
+ make_bit_field_ref (loc, rinner, rhs,
unsigned_type,
nbitsize, nbitpos,
1, rreversep),
@@ -3987,8 +3991,8 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
/* Make a new bitfield reference, shift the constant over the
appropriate number of bits and mask it with the computed mask
(in case this was a signed field). If we changed it, make a new one. */
- lhs = make_bit_field_ref (loc, linner, unsigned_type, nbitsize, nbitpos, 1,
- lreversep);
+ lhs = make_bit_field_ref (loc, linner, lhs, unsigned_type,
+ nbitsize, nbitpos, 1, lreversep);
rhs = const_binop (BIT_AND_EXPR,
const_binop (LSHIFT_EXPR,
@@ -4027,11 +4031,12 @@ optimize_bit_field_compare (location_t loc, enum tree_code code,
do anything with. */
static tree
-decode_field_reference (location_t loc, tree exp, HOST_WIDE_INT *pbitsize,
+decode_field_reference (location_t loc, tree *exp_, HOST_WIDE_INT *pbitsize,
HOST_WIDE_INT *pbitpos, machine_mode *pmode,
int *punsignedp, int *preversep, int *pvolatilep,
tree *pmask, tree *pand_mask)
{
+ tree exp = *exp_;
tree outer_type = 0;
tree and_mask = 0;
tree mask, inner, offset;
@@ -4068,6 +4073,8 @@ decode_field_reference (location_t loc, tree exp, HOST_WIDE_INT *pbitsize,
|| TREE_CODE (inner) == PLACEHOLDER_EXPR)
return 0;
+ *exp_ = exp;
+
/* If the number of bits in the reference is the same as the bitsize of
the outer type, then the outer type gives the signedness. Otherwise
(in case of a small bitfield) the signedness is unchanged. */
@@ -5676,19 +5683,19 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type,
ll_reversep = lr_reversep = rl_reversep = rr_reversep = 0;
volatilep = 0;
- ll_inner = decode_field_reference (loc, ll_arg,
+ ll_inner = decode_field_reference (loc, &ll_arg,
&ll_bitsize, &ll_bitpos, &ll_mode,
&ll_unsignedp, &ll_reversep, &volatilep,
&ll_mask, &ll_and_mask);
- lr_inner = decode_field_reference (loc, lr_arg,
+ lr_inner = decode_field_reference (loc, &lr_arg,
&lr_bitsize, &lr_bitpos, &lr_mode,
&lr_unsignedp, &lr_reversep, &volatilep,
&lr_mask, &lr_and_mask);
- rl_inner = decode_field_reference (loc, rl_arg,
+ rl_inner = decode_field_reference (loc, &rl_arg,
&rl_bitsize, &rl_bitpos, &rl_mode,
&rl_unsignedp, &rl_reversep, &volatilep,
&rl_mask, &rl_and_mask);
- rr_inner = decode_field_reference (loc, rr_arg,
+ rr_inner = decode_field_reference (loc, &rr_arg,
&rr_bitsize, &rr_bitpos, &rr_mode,
&rr_unsignedp, &rr_reversep, &volatilep,
&rr_mask, &rr_and_mask);
@@ -5850,12 +5857,14 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type,
lr_mask = const_binop (BIT_IOR_EXPR, lr_mask, rr_mask);
if (lnbitsize == rnbitsize && xll_bitpos == xlr_bitpos)
{
- lhs = make_bit_field_ref (loc, ll_inner, lntype, lnbitsize, lnbitpos,
+ lhs = make_bit_field_ref (loc, ll_inner, ll_arg,
+ lntype, lnbitsize, lnbitpos,
ll_unsignedp || rl_unsignedp, ll_reversep);
if (! all_ones_mask_p (ll_mask, lnbitsize))
lhs = build2 (BIT_AND_EXPR, lntype, lhs, ll_mask);
- rhs = make_bit_field_ref (loc, lr_inner, rntype, rnbitsize, rnbitpos,
+ rhs = make_bit_field_ref (loc, lr_inner, lr_arg,
+ rntype, rnbitsize, rnbitpos,
lr_unsignedp || rr_unsignedp, lr_reversep);
if (! all_ones_mask_p (lr_mask, rnbitsize))
rhs = build2 (BIT_AND_EXPR, rntype, rhs, lr_mask);
@@ -5877,11 +5886,11 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type,
{
tree type;
- lhs = make_bit_field_ref (loc, ll_inner, lntype,
+ lhs = make_bit_field_ref (loc, ll_inner, ll_arg, lntype,
ll_bitsize + rl_bitsize,
MIN (ll_bitpos, rl_bitpos),
ll_unsignedp, ll_reversep);
- rhs = make_bit_field_ref (loc, lr_inner, rntype,
+ rhs = make_bit_field_ref (loc, lr_inner, lr_arg, rntype,
lr_bitsize + rr_bitsize,
MIN (lr_bitpos, rr_bitpos),
lr_unsignedp, lr_reversep);
@@ -5946,7 +5955,8 @@ fold_truth_andor_1 (location_t loc, enum tree_code code, tree truth_type,
reference we will make. Unless the mask is all ones the width of
that field, perform the mask operation. Then compare with the
merged constant. */
- result = make_bit_field_ref (loc, ll_inner, lntype, lnbitsize, lnbitpos,
+ result = make_bit_field_ref (loc, ll_inner, ll_arg,
+ lntype, lnbitsize, lnbitpos,
ll_unsignedp || rl_unsignedp, ll_reversep);
ll_mask = const_binop (BIT_IOR_EXPR, ll_mask, rl_mask);
@@ -8392,75 +8402,6 @@ fold_comparison (location_t loc, enum tree_code code, tree type,
STRIP_SIGN_NOPS (arg0);
STRIP_SIGN_NOPS (arg1);
- /* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 -+ C1. */
- if ((TREE_CODE (arg0) == PLUS_EXPR || TREE_CODE (arg0) == MINUS_EXPR)
- && (equality_code
- || (ANY_INTEGRAL_TYPE_P (TREE_TYPE (arg0))
- && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (arg0))))
- && TREE_CODE (TREE_OPERAND (arg0, 1)) == INTEGER_CST
- && !TREE_OVERFLOW (TREE_OPERAND (arg0, 1))
- && TREE_CODE (arg1) == INTEGER_CST
- && !TREE_OVERFLOW (arg1))
- {
- const enum tree_code
- reverse_op = TREE_CODE (arg0) == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR;
- tree const1 = TREE_OPERAND (arg0, 1);
- tree const2 = fold_convert_loc (loc, TREE_TYPE (const1), arg1);
- tree variable = TREE_OPERAND (arg0, 0);
- tree new_const = int_const_binop (reverse_op, const2, const1);
-
- /* If the constant operation overflowed this can be
- simplified as a comparison against INT_MAX/INT_MIN. */
- if (TREE_OVERFLOW (new_const)
- && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (arg0)))
- {
- int const1_sgn = tree_int_cst_sgn (const1);
- enum tree_code code2 = code;
-
- /* Get the sign of the constant on the lhs if the
- operation were VARIABLE + CONST1. */
- if (TREE_CODE (arg0) == MINUS_EXPR)
- const1_sgn = -const1_sgn;
-
- /* The sign of the constant determines if we overflowed
- INT_MAX (const1_sgn == -1) or INT_MIN (const1_sgn == 1).
- Canonicalize to the INT_MIN overflow by swapping the comparison
- if necessary. */
- if (const1_sgn == -1)
- code2 = swap_tree_comparison (code);
-
- /* We now can look at the canonicalized case
- VARIABLE + 1 CODE2 INT_MIN
- and decide on the result. */
- switch (code2)
- {
- case EQ_EXPR:
- case LT_EXPR:
- case LE_EXPR:
- return
- omit_one_operand_loc (loc, type, boolean_false_node, variable);
-
- case NE_EXPR:
- case GE_EXPR:
- case GT_EXPR:
- return
- omit_one_operand_loc (loc, type, boolean_true_node, variable);
-
- default:
- gcc_unreachable ();
- }
- }
- else
- {
- if (!equality_code)
- fold_overflow_warning ("assuming signed overflow does not occur "
- "when changing X +- C1 cmp C2 to "
- "X cmp C2 -+ C1",
- WARN_STRICT_OVERFLOW_COMPARISON);
- return fold_build2_loc (loc, code, type, variable, new_const);
- }
- }
-
/* For comparisons of pointers we can decompose it to a compile time
comparison of the base objects and the offsets into the object.
This requires at least one operand being an ADDR_EXPR or a
@@ -10139,45 +10080,6 @@ fold_binary_loc (location_t loc,
build_zero_cst (TREE_TYPE (tem)));
}
- /* Fold (X ^ Y) & Y as ~X & Y. */
- if (TREE_CODE (arg0) == BIT_XOR_EXPR
- && operand_equal_p (TREE_OPERAND (arg0, 1), arg1, 0))
- {
- tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 0));
- return fold_build2_loc (loc, BIT_AND_EXPR, type,
- fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
- fold_convert_loc (loc, type, arg1));
- }
- /* Fold (X ^ Y) & X as ~Y & X. */
- if (TREE_CODE (arg0) == BIT_XOR_EXPR
- && operand_equal_p (TREE_OPERAND (arg0, 0), arg1, 0)
- && reorder_operands_p (TREE_OPERAND (arg0, 1), arg1))
- {
- tem = fold_convert_loc (loc, type, TREE_OPERAND (arg0, 1));
- return fold_build2_loc (loc, BIT_AND_EXPR, type,
- fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
- fold_convert_loc (loc, type, arg1));
- }
- /* Fold X & (X ^ Y) as X & ~Y. */
- if (TREE_CODE (arg1) == BIT_XOR_EXPR
- && operand_equal_p (arg0, TREE_OPERAND (arg1, 0), 0))
- {
- tem = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 1));
- return fold_build2_loc (loc, BIT_AND_EXPR, type,
- fold_convert_loc (loc, type, arg0),
- fold_build1_loc (loc, BIT_NOT_EXPR, type, tem));
- }
- /* Fold X & (Y ^ X) as ~Y & X. */
- if (TREE_CODE (arg1) == BIT_XOR_EXPR
- && operand_equal_p (arg0, TREE_OPERAND (arg1, 1), 0)
- && reorder_operands_p (arg0, TREE_OPERAND (arg1, 0)))
- {
- tem = fold_convert_loc (loc, type, TREE_OPERAND (arg1, 0));
- return fold_build2_loc (loc, BIT_AND_EXPR, type,
- fold_build1_loc (loc, BIT_NOT_EXPR, type, tem),
- fold_convert_loc (loc, type, arg0));
- }
-
/* Fold (X * Y) & -(1 << CST) to X * Y if Y is a constant
multiple of 1 << CST. */
if (TREE_CODE (arg1) == INTEGER_CST)
@@ -11788,9 +11690,7 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
gcc_unreachable ();
case BIT_FIELD_REF:
- if ((TREE_CODE (arg0) == VECTOR_CST
- || (TREE_CODE (arg0) == CONSTRUCTOR
- && TREE_CODE (TREE_TYPE (arg0)) == VECTOR_TYPE))
+ if (TREE_CODE (arg0) == VECTOR_CST
&& (type == TREE_TYPE (TREE_TYPE (arg0))
|| (TREE_CODE (type) == VECTOR_TYPE
&& TREE_TYPE (type) == TREE_TYPE (TREE_TYPE (arg0)))))
@@ -11818,88 +11718,32 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
vals[i] = VECTOR_CST_ELT (arg0, idx + i);
return build_vector (type, vals);
}
-
- /* Constructor elements can be subvectors. */
- unsigned HOST_WIDE_INT k = 1;
- if (CONSTRUCTOR_NELTS (arg0) != 0)
- {
- tree cons_elem = TREE_TYPE (CONSTRUCTOR_ELT (arg0, 0)->value);
- if (TREE_CODE (cons_elem) == VECTOR_TYPE)
- k = TYPE_VECTOR_SUBPARTS (cons_elem);
- }
-
- /* We keep an exact subset of the constructor elements. */
- if ((idx % k) == 0 && (n % k) == 0)
- {
- if (CONSTRUCTOR_NELTS (arg0) == 0)
- return build_constructor (type, NULL);
- idx /= k;
- n /= k;
- if (n == 1)
- {
- if (idx < CONSTRUCTOR_NELTS (arg0))
- return CONSTRUCTOR_ELT (arg0, idx)->value;
- return build_zero_cst (type);
- }
-
- vec<constructor_elt, va_gc> *vals;
- vec_alloc (vals, n);
- for (unsigned i = 0;
- i < n && idx + i < CONSTRUCTOR_NELTS (arg0);
- ++i)
- CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
- CONSTRUCTOR_ELT
- (arg0, idx + i)->value);
- return build_constructor (type, vals);
- }
- /* The bitfield references a single constructor element. */
- else if (idx + n <= (idx / k + 1) * k)
- {
- if (CONSTRUCTOR_NELTS (arg0) <= idx / k)
- return build_zero_cst (type);
- else if (n == k)
- return CONSTRUCTOR_ELT (arg0, idx / k)->value;
- else
- return fold_build3_loc (loc, code, type,
- CONSTRUCTOR_ELT (arg0, idx / k)->value, op1,
- build_int_cst (TREE_TYPE (op2), (idx % k) * width));
- }
}
}
- /* A bit-field-ref that referenced the full argument can be stripped. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (arg0))
- && TYPE_PRECISION (TREE_TYPE (arg0)) == tree_to_uhwi (arg1)
- && integer_zerop (op2))
- return fold_convert_loc (loc, type, arg0);
-
/* On constants we can use native encode/interpret to constant
fold (nearly) all BIT_FIELD_REFs. */
if (CONSTANT_CLASS_P (arg0)
&& can_native_interpret_type_p (type)
- && tree_fits_uhwi_p (TYPE_SIZE_UNIT (TREE_TYPE (arg0)))
- /* This limitation should not be necessary, we just need to
- round this up to mode size. */
- && tree_to_uhwi (op1) % BITS_PER_UNIT == 0
- /* Need bit-shifting of the buffer to relax the following. */
- && tree_to_uhwi (op2) % BITS_PER_UNIT == 0)
+ && BITS_PER_UNIT == 8)
{
unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (op1);
- unsigned HOST_WIDE_INT clen;
- clen = tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (arg0)));
- /* ??? We cannot tell native_encode_expr to start at
- some random byte only. So limit us to a reasonable amount
- of work. */
- if (clen <= 4096)
+ /* Limit us to a reasonable amount of work. To relax the
+ other limitations we need bit-shifting of the buffer
+ and rounding up the size. */
+ if (bitpos % BITS_PER_UNIT == 0
+ && bitsize % BITS_PER_UNIT == 0
+ && bitsize <= MAX_BITSIZE_MODE_ANY_MODE)
{
- unsigned char *b = XALLOCAVEC (unsigned char, clen);
- unsigned HOST_WIDE_INT len = native_encode_expr (arg0, b, clen);
+ unsigned char b[MAX_BITSIZE_MODE_ANY_MODE / BITS_PER_UNIT];
+ unsigned HOST_WIDE_INT len
+ = native_encode_expr (arg0, b, bitsize / BITS_PER_UNIT,
+ bitpos / BITS_PER_UNIT);
if (len > 0
- && len * BITS_PER_UNIT >= bitpos + bitsize)
+ && len * BITS_PER_UNIT >= bitsize)
{
- tree v = native_interpret_expr (type,
- b + bitpos / BITS_PER_UNIT,
+ tree v = native_interpret_expr (type, b,
bitsize / BITS_PER_UNIT);
if (v)
return v;
@@ -12017,6 +11861,46 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
}
return NULL_TREE;
+ case BIT_INSERT_EXPR:
+ /* Perform (partial) constant folding of BIT_INSERT_EXPR. */
+ if (TREE_CODE (arg0) == INTEGER_CST
+ && TREE_CODE (arg1) == INTEGER_CST)
+ {
+ unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
+ unsigned bitsize = TYPE_PRECISION (TREE_TYPE (arg1));
+ wide_int tem = wi::bit_and (arg0,
+ wi::shifted_mask (bitpos, bitsize, true,
+ TYPE_PRECISION (type)));
+ wide_int tem2
+ = wi::lshift (wi::zext (wi::to_wide (arg1, TYPE_PRECISION (type)),
+ bitsize), bitpos);
+ return wide_int_to_tree (type, wi::bit_or (tem, tem2));
+ }
+ else if (TREE_CODE (arg0) == VECTOR_CST
+ && CONSTANT_CLASS_P (arg1)
+ && types_compatible_p (TREE_TYPE (TREE_TYPE (arg0)),
+ TREE_TYPE (arg1)))
+ {
+ unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (op2);
+ unsigned HOST_WIDE_INT elsize
+ = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (arg1)));
+ if (bitpos % elsize == 0)
+ {
+ unsigned k = bitpos / elsize;
+ if (operand_equal_p (VECTOR_CST_ELT (arg0, k), arg1, 0))
+ return arg0;
+ else
+ {
+ tree *elts = XALLOCAVEC (tree, TYPE_VECTOR_SUBPARTS (type));
+ memcpy (elts, VECTOR_CST_ELTS (arg0),
+ sizeof (tree) * TYPE_VECTOR_SUBPARTS (type));
+ elts[k] = arg1;
+ return build_vector (type, elts);
+ }
+ }
+ }
+ return NULL_TREE;
+
default:
return NULL_TREE;
} /* switch (code) */
@@ -12287,7 +12171,8 @@ fold_checksum_tree (const_tree expr, struct md5_ctx *ctx,
|| TYPE_REFERENCE_TO (expr)
|| TYPE_CACHED_VALUES_P (expr)
|| TYPE_CONTAINS_PLACEHOLDER_INTERNAL (expr)
- || TYPE_NEXT_VARIANT (expr)))
+ || TYPE_NEXT_VARIANT (expr)
+ || TYPE_ALIAS_SET_KNOWN_P (expr)))
{
/* Allow these fields to be modified. */
tree tmp;
@@ -12297,6 +12182,7 @@ fold_checksum_tree (const_tree expr, struct md5_ctx *ctx,
TYPE_POINTER_TO (tmp) = NULL;
TYPE_REFERENCE_TO (tmp) = NULL;
TYPE_NEXT_VARIANT (tmp) = NULL;
+ TYPE_ALIAS_SET (tmp) = -1;
if (TYPE_CACHED_VALUES_P (tmp))
{
TYPE_CACHED_VALUES_P (tmp) = 0;
diff --git a/gcc/fold-const.h b/gcc/fold-const.h
index 02f42709c4e..637e46b0d48 100644
--- a/gcc/fold-const.h
+++ b/gcc/fold-const.h
@@ -86,6 +86,7 @@ extern void fold_defer_overflow_warnings (void);
extern void fold_undefer_overflow_warnings (bool, const gimple *, int);
extern void fold_undefer_and_ignore_overflow_warnings (void);
extern bool fold_deferring_overflow_warnings_p (void);
+extern void fold_overflow_warning (const char*, enum warn_strict_overflow_code);
extern int operand_equal_p (const_tree, const_tree, unsigned int);
extern int multiple_of_p (tree, const_tree, const_tree);
#define omit_one_operand(T1,T2,T3)\
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 115586c5dae..d32c7d5100a 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,131 @@
+2016-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/71204
+ * frontend-passes.c (realloc_string_callback): Clear inserted_block
+ and changed_statement before calling create_var.
+
+2016-05-15 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/69603
+ * interface.c (compare_parameter): Check for non-NULL pointer.
+
+2016-05-14 Fritz Reese <fritzoreese@gmail.com>
+
+ * gfortran.texi: Update example of DEC UNION extension.
+
+2016-05-14 Fritz Reese <fritzoreese@gmail.com>
+
+ PR fortran/71047
+ * expr.c (gfc_default_initializer): Avoid extra component refs in
+ constructors for derived types and classes.
+
+2016-05-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/70855
+ * frontend-passes.c (inline_matmul_assign): Disable in !$omp workshare.
+
+2016-05-09 Richard Biener <rguenther@suse.de>
+
+ PR fortran/70937
+ * trans-decl.c: Include gimplify.h for unshare_expr.
+ (gfc_trans_vla_one_sizepos): Unshare exprs before inserting
+ them into the IL.
+
+2016-05-07 Fritz Reese <fritzoreese@gmail.com>
+
+ PR fortran/56226
+ * module.c (dt_upper_string): Rename to gfc_dt_upper_string
+ (dt_lower_string): Likewise.
+ * gfortran.h: Make new gfc_dt_upper/lower_string global.
+ * class.c: Use gfc_dt_upper_string.
+ * decl.c: Likewise.
+ * symbol.c: Likewise.
+ * resolve.c (resolve_component): New function.
+ (resolve_fl_derived0): Move component loop code to resolve_component.
+ * parse.c (check_component): New function.
+ (parse_derived): Move loop code to check_component.
+ * lang.opt, invoke.texi, options.c : New option -fdec-structure.
+ * libgfortran.h (bt): New basic type BT_UNION.
+ * gfortran.h (gfc_option): New option -fdec-structure.
+ (gfc_get_union_type, gfc_compare_union_types): New prototypes.
+ (gfc_bt_struct, gfc_fl_struct, case_bt_struct, case_fl_struct): New
+ macros.
+ (gfc_find_component): Change prototype.
+ * match.h (gfc_match_member_sep, gfc_match_map, gfc_match_union,
+ gfc_match_structure_decl): New prototypes.
+ * parse.h (gfc_comp_struct): New macro.
+ * symbol.c (gfc_find_component): Search for components in nested unions
+ * class.c (insert_component_ref, gfc_add_component_ref, add_proc_comp,
+ copy_vtab_proc_comps): Update calls to gfc_find_component.
+ * primary.c (gfc_convert_to_structure_constructor): Likewise.
+ * symbol.c (gfc_add_component): Likewise.
+ * resolve.c (resolve_typebound_function, resolve_typebound_subroutine,
+ resolve_typebound_procedure, resolve_component, resolve_fl_derived):
+ Likewise.
+ * expr.c (get_union_init, component_init): New functions.
+ * decl.c (match_clist_expr, match_record_decl, get_struct_decl,
+ gfc_match_map, gfc_match_union, gfc_match_structure_decl): Likewise.
+ * interface.c (compare_components, gfc_compare_union_types): Likewise.
+ * match.c (gfc_match_member_sep): Likewise.
+ * parse.c (check_component, parse_union, parse_struct_map): Likewise.
+ * resolve.c (resolve_fl_struct): Likewise.
+ * symbol.c (find_union_component): Likewise.
+ * trans-types.c (gfc_get_union_type): Likewise.
+ * parse.c (parse_derived): Use new functions.
+ * interface.c (gfc_compare_derived_types, gfc_compare_types): Likewise.
+ * expr.c (gfc_default_initializer): Likewise.
+ * gfortran.texi: Support for DEC structures, unions, and maps.
+ * gfortran.h (gfc_statement, sym_flavor): Likewise.
+ * check.c (gfc_check_kill_sub): Likewise.
+ * expr.c (gfc_copy_expr, simplify_const_ref,
+ gfc_has_default_initializer): Likewise.
+ * decl.c (build_sym, match_data_constant, add_init_expr_to_sym,
+ match_pointer_init, build_struct, variable_decl,
+ gfc_match_decl_type_spec, gfc_mach_data-decl, gfc_match_entry,
+ gfc_match_end, gfc_match_derived_decl): Likewise.
+ * interface.c (check_interface0, check_interface1,
+ gfc_search_interface): Likewise.
+ * misc.c (gfc_basic_typename, gfc_typename): Likewise.
+ * module.c (add_true_name, build_tnt, bt_types, mio_typespec,
+ fix_mio_expr, load_needed, mio_symbol, read_module, write_symbol,
+ gfc_get_module_backend_decl): Likewise.
+ * parse.h (gfc_compile_state): Likewise.
+ * parse.c (decode_specification_statement, decode_statement,
+ gfc_ascii_statement, verify_st_order, parse_spec): Likewise.
+ * primary.c (gfc_match_varspec, gfc_match_structure_constructor,
+ gfc_match_rvalue, match_variable): Likewise.
+ * resolve.c (find_arglists, resolve_structure_cons,
+ is_illegal_recursion, resolve_generic_f, get_declared_from_expr,
+ resolve_typebound_subroutine, resolve_allocate_expr,
+ nonscalar_typebound_assign, generate_component_assignments,
+ resolve_fl_variable_derived, check_defined_assignments,
+ resolve_component, resolve_symbol, resolve_equivalence_derived):
+ Likewise.
+ * symbol.c (flavors, check_conflict, gfc_add_flavor, gfc_use_derived,
+ gfc_restore_last_undo_checkpoint, gfc_type_compatible,
+ gfc_find_dt_in_generic): Likewise.
+ * trans-decl.c (gfc_get_module_backend_decl, create_function_arglist,
+ gfc_create_module_variable, check_constant_initializer): Likewise.
+ * trans-expr.c (gfc_conv_component_ref, gfc_conv_initializer,
+ gfc_trans_alloc_subarray_assign, gfc_trans_subcomponent_assign,
+ gfc_conv_structure, gfc_trans_scalar_assign, copyable_array_p):
+ Likewise.
+ * trans-io.c (transfer_namelist_element, transfer_expr,
+ gfc_trans_transfer): Likewise.
+ * trans-stmt.c (gfc_trans_deallocate): Likewise.
+ * trans-types.c (gfc_typenode_for_spec, gfc_copy_dt_decls_ifequal,
+ gfc_get_derived_type): Likewise.
+
+2016-05-05 Jakub Jelinek <jakub@redhat.com>
+
+ * openmp.c (gfc_match_omp_clauses): Restructuralize, so that clause
+ parsing is done in a big switch based on gfc_peek_ascii_char and
+ individual clauses under their first letters are sorted too.
+
+2016-05-02 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * trans-types.c (gfc_build_complex_type):
+
2016-05-02 Richard Biener <rguenther@suse.de>
* trans-array.c (gfc_trans_create_temp_array): Properly
diff --git a/gcc/fortran/check.c b/gcc/fortran/check.c
index 05133c32043..d26e45ec406 100644
--- a/gcc/fortran/check.c
+++ b/gcc/fortran/check.c
@@ -2592,7 +2592,7 @@ gfc_check_kill_sub (gfc_expr *pid, gfc_expr *sig, gfc_expr *status)
bool
gfc_check_kind (gfc_expr *x)
{
- if (x->ts.type == BT_DERIVED || x->ts.type == BT_CLASS)
+ if (gfc_bt_struct (x->ts.type) || x->ts.type == BT_CLASS)
{
gfc_error ("%qs argument of %qs intrinsic at %L must be of "
"intrinsic type", gfc_current_intrinsic_arg[0]->name,
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 6a7339f1bc1..3627828d21f 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -78,12 +78,11 @@ insert_component_ref (gfc_typespec *ts, gfc_ref **ref, const char * const name)
gcc_assert (ts->type == BT_DERIVED || ts->type == BT_CLASS);
type_sym = ts->u.derived;
- new_ref = gfc_get_ref ();
- new_ref->type = REF_COMPONENT;
- new_ref->next = *ref;
- new_ref->u.c.sym = type_sym;
- new_ref->u.c.component = gfc_find_component (type_sym, name, true, true);
+ gfc_find_component (type_sym, name, true, true, &new_ref);
gcc_assert (new_ref->u.c.component);
+ while (new_ref->next)
+ new_ref = new_ref->next;
+ new_ref->next = *ref;
if (new_ref->next)
{
@@ -206,8 +205,9 @@ gfc_fix_class_refs (gfc_expr *e)
void
gfc_add_component_ref (gfc_expr *e, const char *name)
{
+ gfc_component *c;
gfc_ref **tail = &(e->ref);
- gfc_ref *next = NULL;
+ gfc_ref *ref, *next = NULL;
gfc_symbol *derived = e->symtree->n.sym->ts.u.derived;
while (*tail != NULL)
{
@@ -237,14 +237,13 @@ gfc_add_component_ref (gfc_expr *e, const char *name)
else
/* Avoid losing memory. */
gfc_free_ref_list (*tail);
- (*tail) = gfc_get_ref();
- (*tail)->next = next;
- (*tail)->type = REF_COMPONENT;
- (*tail)->u.c.sym = derived;
- (*tail)->u.c.component = gfc_find_component (derived, name, true, true);
- gcc_assert((*tail)->u.c.component);
+ c = gfc_find_component (derived, name, true, true, tail);
+ gcc_assert (c);
+ for (ref = *tail; ref->next; ref = ref->next)
+ ;
+ ref->next = next;
if (!next)
- e->ts = (*tail)->u.c.component->ts;
+ e->ts = c->ts;
}
@@ -477,8 +476,7 @@ get_unique_type_string (char *string, gfc_symbol *derived)
if (derived->attr.unlimited_polymorphic)
strcpy (dt_name, "STAR");
else
- strcpy (dt_name, derived->name);
- dt_name[0] = TOUPPER (dt_name[0]);
+ strcpy (dt_name, gfc_dt_upper_string (derived->name));
if (derived->attr.unlimited_polymorphic)
sprintf (string, "_%s", dt_name);
else if (derived->module)
@@ -751,7 +749,7 @@ add_proc_comp (gfc_symbol *vtype, const char *name, gfc_typebound_proc *tb)
if (tb->non_overridable)
return;
- c = gfc_find_component (vtype, name, true, true);
+ c = gfc_find_component (vtype, name, true, true, NULL);
if (c == NULL)
{
@@ -820,7 +818,7 @@ copy_vtab_proc_comps (gfc_symbol *declared, gfc_symbol *vtype)
for (cmp = vtab->ts.u.derived->components; cmp; cmp = cmp->next)
{
- if (gfc_find_component (vtype, cmp->name, true, true))
+ if (gfc_find_component (vtype, cmp->name, true, true, NULL))
continue;
add_proc_comp (vtype, cmp->name, cmp->tb);
diff --git a/gcc/fortran/decl.c b/gcc/fortran/decl.c
index 80ec39cb86b..0b8787ac2b2 100644
--- a/gcc/fortran/decl.c
+++ b/gcc/fortran/decl.c
@@ -391,13 +391,13 @@ match_data_constant (gfc_expr **result)
if (sym == NULL
|| (sym->attr.flavor != FL_PARAMETER
- && (!dt_sym || dt_sym->attr.flavor != FL_DERIVED)))
+ && (!dt_sym || !gfc_fl_struct (dt_sym->attr.flavor))))
{
gfc_error ("Symbol %qs must be a PARAMETER in DATA statement at %C",
name);
return MATCH_ERROR;
}
- else if (dt_sym && dt_sym->attr.flavor == FL_DERIVED)
+ else if (dt_sym && gfc_fl_struct (dt_sym->attr.flavor))
return gfc_match_structure_constructor (dt_sym, result);
/* Check to see if the value is an initialization array expression. */
@@ -606,6 +606,161 @@ cleanup:
/************************ Declaration statements *********************/
+/* Like gfc_match_init_expr, but matches a 'clist' (old-style initialization
+ list). The difference here is the expression is a list of constants
+ and is surrounded by '/'.
+ The typespec ts must match the typespec of the variable which the
+ clist is initializing.
+ The arrayspec tells whether this should match a list of constants
+ corresponding to array elements or a scalar (as == NULL). */
+
+static match
+match_clist_expr (gfc_expr **result, gfc_typespec *ts, gfc_array_spec *as)
+{
+ gfc_constructor_base array_head = NULL;
+ gfc_expr *expr = NULL;
+ match m;
+ locus where;
+ mpz_t repeat, size;
+ bool scalar;
+ int cmp;
+
+ gcc_assert (ts);
+
+ mpz_init_set_ui (repeat, 0);
+ mpz_init (size);
+ scalar = !as || !as->rank;
+
+ /* We have already matched '/' - now look for a constant list, as with
+ top_val_list from decl.c, but append the result to an array. */
+ if (gfc_match ("/") == MATCH_YES)
+ {
+ gfc_error ("Empty old style initializer list at %C");
+ goto cleanup;
+ }
+
+ where = gfc_current_locus;
+ for (;;)
+ {
+ m = match_data_constant (&expr);
+ if (m != MATCH_YES)
+ expr = NULL; /* match_data_constant may set expr to garbage */
+ if (m == MATCH_NO)
+ goto syntax;
+ if (m == MATCH_ERROR)
+ goto cleanup;
+
+ /* Found r in repeat spec r*c; look for the constant to repeat. */
+ if ( gfc_match_char ('*') == MATCH_YES)
+ {
+ if (scalar)
+ {
+ gfc_error ("Repeat spec invalid in scalar initializer at %C");
+ goto cleanup;
+ }
+ if (expr->ts.type != BT_INTEGER)
+ {
+ gfc_error ("Repeat spec must be an integer at %C");
+ goto cleanup;
+ }
+ mpz_set (repeat, expr->value.integer);
+ gfc_free_expr (expr);
+ expr = NULL;
+
+ m = match_data_constant (&expr);
+ if (m == MATCH_NO)
+ gfc_error ("Expected data constant after repeat spec at %C");
+ if (m != MATCH_YES)
+ goto cleanup;
+ }
+ /* No repeat spec, we matched the data constant itself. */
+ else
+ mpz_set_ui (repeat, 1);
+
+ if (!scalar)
+ {
+ /* Add the constant initializer as many times as repeated. */
+ for (; mpz_cmp_ui (repeat, 0) > 0; mpz_sub_ui (repeat, repeat, 1))
+ {
+ /* Make sure types of elements match */
+ if(ts && !gfc_compare_types (&expr->ts, ts)
+ && !gfc_convert_type (expr, ts, 1))
+ goto cleanup;
+
+ gfc_constructor_append_expr (&array_head,
+ gfc_copy_expr (expr), &gfc_current_locus);
+ }
+
+ gfc_free_expr (expr);
+ expr = NULL;
+ }
+
+ /* For scalar initializers quit after one element. */
+ else
+ {
+ if(gfc_match_char ('/') != MATCH_YES)
+ {
+ gfc_error ("End of scalar initializer expected at %C");
+ goto cleanup;
+ }
+ break;
+ }
+
+ if (gfc_match_char ('/') == MATCH_YES)
+ break;
+ if (gfc_match_char (',') == MATCH_NO)
+ goto syntax;
+ }
+
+ /* Set up expr as an array constructor. */
+ if (!scalar)
+ {
+ expr = gfc_get_array_expr (ts->type, ts->kind, &where);
+ expr->ts = *ts;
+ expr->value.constructor = array_head;
+
+ expr->rank = as->rank;
+ expr->shape = gfc_get_shape (expr->rank);
+
+ /* Validate sizes. */
+ gcc_assert (gfc_array_size (expr, &size));
+ gcc_assert (spec_size (as, &repeat));
+ cmp = mpz_cmp (size, repeat);
+ if (cmp < 0)
+ gfc_error ("Not enough elements in array initializer at %C");
+ else if (cmp > 0)
+ gfc_error ("Too many elements in array initializer at %C");
+ if (cmp)
+ goto cleanup;
+ }
+
+ /* Make sure scalar types match. */
+ else if (!gfc_compare_types (&expr->ts, ts)
+ && !gfc_convert_type (expr, ts, 1))
+ goto cleanup;
+
+ if (expr->ts.u.cl)
+ expr->ts.u.cl->length_from_typespec = 1;
+
+ *result = expr;
+ mpz_clear (size);
+ mpz_clear (repeat);
+ return MATCH_YES;
+
+syntax:
+ gfc_error ("Syntax error in old style initializer list at %C");
+
+cleanup:
+ if (expr)
+ expr->value.constructor = NULL;
+ gfc_free_expr (expr);
+ gfc_constructor_free (array_head);
+ mpz_clear (size);
+ mpz_clear (repeat);
+ return MATCH_ERROR;
+}
+
+
/* Auxiliary function to merge DIMENSION and CODIMENSION array specs. */
static bool
@@ -1239,7 +1394,8 @@ build_sym (const char *name, gfc_charlen *cl, bool cl_deferred,
st = gfc_find_symtree (gfc_current_ns->sym_root, u_name);
- if (st != 0)
+ /* STRUCTURE types can alias symbol names */
+ if (st != 0 && st->n.sym->attr.flavor != FL_STRUCT)
{
gfc_error ("Symbol %qs at %C also declared as a type at %L", name,
&st->n.sym->declared_at);
@@ -1469,7 +1625,7 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus)
/* Check if the assignment can happen. This has to be put off
until later for derived type variables and procedure pointers. */
- if (sym->ts.type != BT_DERIVED && init->ts.type != BT_DERIVED
+ if (!gfc_bt_struct (sym->ts.type) && !gfc_bt_struct (init->ts.type)
&& sym->ts.type != BT_CLASS && init->ts.type != BT_CLASS
&& !sym->attr.proc_pointer
&& !gfc_check_assign_symbol (sym, NULL, init))
@@ -1608,7 +1764,7 @@ add_init_expr_to_sym (const char *name, gfc_expr **initp, locus *var_locus)
If we mark my_int as iso_c (since we can see it's value
is equal to one of the named constants), then my_int_2
will be considered C interoperable. */
- if (sym->ts.type != BT_CHARACTER && sym->ts.type != BT_DERIVED)
+ if (sym->ts.type != BT_CHARACTER && !gfc_bt_struct (sym->ts.type))
{
sym->ts.is_iso_c |= init->ts.is_iso_c;
sym->ts.is_c_interop |= init->ts.is_c_interop;
@@ -1666,6 +1822,7 @@ static bool
build_struct (const char *name, gfc_charlen *cl, gfc_expr **init,
gfc_array_spec **as)
{
+ gfc_state_data *s;
gfc_component *c;
bool t = true;
@@ -1689,6 +1846,35 @@ build_struct (const char *name, gfc_charlen *cl, gfc_expr **init,
}
}
+ /* If we are in a nested union/map definition, gfc_add_component will not
+ properly find repeated components because:
+ (i) gfc_add_component does a flat search, where components of unions
+ and maps are implicity chained so nested components may conflict.
+ (ii) Unions and maps are not linked as components of their parent
+ structures until after they are parsed.
+ For (i) we use gfc_find_component which searches recursively, and for (ii)
+ we search each block directly from the parse stack until we find the top
+ level structure. */
+
+ s = gfc_state_stack;
+ if (s->state == COMP_UNION || s->state == COMP_MAP)
+ {
+ while (s->state == COMP_UNION || gfc_comp_struct (s->state))
+ {
+ c = gfc_find_component (s->sym, name, true, true, NULL);
+ if (c != NULL)
+ {
+ gfc_error_now ("Component '%s' at %C already declared at %L",
+ name, &c->loc);
+ return false;
+ }
+ /* Break after we've searched the entire chain. */
+ if (s->state == COMP_DERIVED || s->state == COMP_STRUCTURE)
+ break;
+ s = s->previous;
+ }
+ }
+
if (!gfc_add_component (gfc_current_block(), name, &c))
return false;
@@ -1868,7 +2054,7 @@ match_pointer_init (gfc_expr **init, int procptr)
{
match m;
- if (gfc_pure (NULL) && gfc_state_stack->state != COMP_DERIVED)
+ if (gfc_pure (NULL) && !gfc_comp_struct (gfc_state_stack->state))
{
gfc_error ("Initialization of pointer at %C is not allowed in "
"a PURE procedure");
@@ -2062,7 +2248,7 @@ variable_decl (int elem)
/* If this symbol has already shown up in a Cray Pointer declaration,
and this is not a component declaration,
then we want to set the type & bail out. */
- if (flag_cray_pointer && gfc_current_state () != COMP_DERIVED)
+ if (flag_cray_pointer && !gfc_comp_struct (gfc_current_state ()))
{
gfc_find_symbol (name, gfc_current_ns, 1, &sym);
if (sym != NULL && sym->attr.cray_pointee)
@@ -2127,7 +2313,7 @@ variable_decl (int elem)
For components of derived types, it is not true, so we don't
create a symbol for those yet. If we fail to create the symbol,
bail out. */
- if (gfc_current_state () != COMP_DERIVED
+ if (!gfc_comp_struct (gfc_current_state ())
&& !build_sym (name, cl, cl_deferred, &as, &var_locus))
{
m = MATCH_ERROR;
@@ -2154,6 +2340,9 @@ variable_decl (int elem)
if (!gfc_notify_std (GFC_STD_GNU, "Old-style "
"initialization at %C"))
return MATCH_ERROR;
+
+ /* Allow old style initializations for components of STRUCTUREs and MAPs
+ but not components of derived types. */
else if (gfc_current_state () == COMP_DERIVED)
{
gfc_error ("Invalid old style initialization for derived type "
@@ -2162,7 +2351,23 @@ variable_decl (int elem)
goto cleanup;
}
- return match_old_style_init (name);
+ /* For structure components, read the initializer as a special
+ expression and let the rest of this function apply the initializer
+ as usual. */
+ else if (gfc_comp_struct (gfc_current_state ()))
+ {
+ m = match_clist_expr (&initializer, &current_ts, as);
+ if (m == MATCH_NO)
+ gfc_error ("Syntax error in old style initialization of %s at %C",
+ name);
+ if (m != MATCH_YES)
+ goto cleanup;
+ }
+
+ /* Otherwise we treat the old style initialization just like a
+ DATA declaration for the current variable. */
+ else
+ return match_old_style_init (name);
}
/* The double colon must be present in order to have initializers.
@@ -2200,7 +2405,7 @@ variable_decl (int elem)
}
if (current_attr.flavor != FL_PARAMETER && gfc_pure (NULL)
- && gfc_state_stack->state != COMP_DERIVED)
+ && !gfc_comp_struct (gfc_state_stack->state))
{
gfc_error ("Initialization of variable at %C is not allowed in "
"a PURE procedure");
@@ -2208,7 +2413,7 @@ variable_decl (int elem)
}
if (current_attr.flavor != FL_PARAMETER
- && gfc_state_stack->state != COMP_DERIVED)
+ && !gfc_comp_struct (gfc_state_stack->state))
gfc_unset_implicit_pure (gfc_current_ns->proc_name);
if (m != MATCH_YES)
@@ -2217,7 +2422,7 @@ variable_decl (int elem)
}
if (initializer != NULL && current_attr.allocatable
- && gfc_current_state () == COMP_DERIVED)
+ && gfc_comp_struct (gfc_current_state ()))
{
gfc_error ("Initialization of allocatable component at %C is not "
"allowed");
@@ -2228,7 +2433,7 @@ variable_decl (int elem)
/* Add the initializer. Note that it is fine if initializer is
NULL here, because we sometimes also need to check if a
declaration *must* have an initialization expression. */
- if (gfc_current_state () != COMP_DERIVED)
+ if (!gfc_comp_struct (gfc_current_state ()))
t = add_init_expr_to_sym (name, &initializer, &var_locus);
else
{
@@ -2236,6 +2441,12 @@ variable_decl (int elem)
&& !current_attr.pointer && !initializer)
initializer = gfc_default_initializer (&current_ts);
t = build_struct (name, cl, &initializer, &as);
+
+ /* If we match a nested structure definition we expect to see the
+ * body even if the variable declarations blow up, so we need to keep
+ * the structure declaration around. */
+ if (gfc_new_block && gfc_new_block->attr.flavor == FL_STRUCT)
+ gfc_commit_symbol (gfc_new_block);
}
m = (t) ? MATCH_YES : MATCH_ERROR;
@@ -2724,6 +2935,36 @@ done:
}
+/* Matches a RECORD declaration. */
+
+static match
+match_record_decl (const char *name)
+{
+ locus old_loc;
+ old_loc = gfc_current_locus;
+
+ if (gfc_match (" record") == MATCH_YES)
+ {
+ if (!gfc_option.flag_dec_structure)
+ {
+ gfc_current_locus = old_loc;
+ gfc_error ("RECORD at %C is an extension, enable it with "
+ "-fdec-structure");
+ return MATCH_ERROR;
+ }
+ if (gfc_match (" /%n/", name) != MATCH_YES)
+ {
+ gfc_error ("Structure name expected after RECORD at %C");
+ gfc_current_locus = old_loc;
+ return MATCH_ERROR;
+ }
+ return MATCH_YES;
+ }
+
+ gfc_current_locus = old_loc;
+ return MATCH_NO;
+}
+
/* Matches a declaration-type-spec (F03:R502). If successful, sets the ts
structure to the matched specification. This is necessary for FUNCTION and
IMPLICIT statements.
@@ -2781,7 +3022,7 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
{
if ((m = gfc_match ("*)")) != MATCH_YES)
return m;
- if (gfc_current_state () == COMP_DERIVED)
+ if (gfc_comp_struct (gfc_current_state ()))
{
gfc_error ("Assumed type at %C is not allowed for components");
return MATCH_ERROR;
@@ -2892,10 +3133,51 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
if (matched_type)
m = gfc_match_char (')');
- if (m == MATCH_YES)
- ts->type = BT_DERIVED;
+ if (m != MATCH_YES)
+ m = match_record_decl (name);
+
+ if (matched_type || m == MATCH_YES)
+ {
+ ts->type = BT_DERIVED;
+ /* We accept record/s/ or type(s) where s is a structure, but we
+ * don't need all the extra derived-type stuff for structures. */
+ if (gfc_find_symbol (gfc_dt_upper_string (name), NULL, 1, &sym))
+ {
+ gfc_error ("Type name '%s' at %C is ambiguous", name);
+ return MATCH_ERROR;
+ }
+ if (sym && sym->attr.flavor == FL_STRUCT)
+ {
+ ts->u.derived = sym;
+ return MATCH_YES;
+ }
+ /* Actually a derived type. */
+ }
+
else
{
+ /* Match nested STRUCTURE declarations; only valid within another
+ structure declaration. */
+ m = gfc_match (" structure");
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+ else if (m == MATCH_YES)
+ {
+ if ( gfc_current_state () != COMP_STRUCTURE
+ && gfc_current_state () != COMP_MAP)
+ return MATCH_ERROR;
+
+ m = gfc_match_structure_decl ();
+ if (m == MATCH_YES)
+ {
+ /* gfc_new_block is updated by match_structure_decl. */
+ ts->type = BT_DERIVED;
+ ts->u.derived = gfc_new_block;
+ return MATCH_YES;
+ }
+ return MATCH_ERROR;
+ }
+
/* Match CLASS declarations. */
m = gfc_match (" class ( * )");
if (m == MATCH_ERROR)
@@ -2964,9 +3246,7 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
stored in a symtree with the first letter of the name capitalized; the
symtree with the all lower-case name contains the associated
generic function. */
- dt_name = gfc_get_string ("%c%s",
- (char) TOUPPER ((unsigned char) name[0]),
- (const char*)&name[1]);
+ dt_name = gfc_dt_upper_string (name);
sym = NULL;
dt_sym = NULL;
if (ts->kind != -1)
@@ -2998,7 +3278,7 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
return MATCH_NO;
}
- if ((sym->attr.flavor != FL_UNKNOWN
+ if ((sym->attr.flavor != FL_UNKNOWN && sym->attr.flavor != FL_STRUCT
&& !(sym->attr.flavor == FL_PROCEDURE && sym->attr.generic))
|| sym->attr.subroutine)
{
@@ -3038,7 +3318,7 @@ gfc_match_decl_type_spec (gfc_typespec *ts, int implicit_flag)
gfc_set_sym_referenced (dt_sym);
- if (dt_sym->attr.flavor != FL_DERIVED
+ if (dt_sym->attr.flavor != FL_DERIVED && dt_sym->attr.flavor != FL_STRUCT
&& !gfc_add_flavor (&dt_sym->attr, FL_DERIVED, sym->name, NULL))
return MATCH_ERROR;
@@ -3480,9 +3760,7 @@ gfc_match_import (void)
letter of the name capitalized; the symtree with the all
lower-case name contains the associated generic function. */
st = gfc_new_symtree (&gfc_current_ns->sym_root,
- gfc_get_string ("%c%s",
- (char) TOUPPER ((unsigned char) name[0]),
- &name[1]));
+ gfc_dt_upper_string (name));
st->n.sym = sym;
sym->refs++;
sym->attr.imported = 1;
@@ -4497,7 +4775,7 @@ gfc_match_data_decl (void)
return m;
if ((current_ts.type == BT_DERIVED || current_ts.type == BT_CLASS)
- && gfc_current_state () != COMP_DERIVED)
+ && !gfc_comp_struct (gfc_current_state ()))
{
sym = gfc_use_derived (current_ts.u.derived);
@@ -4526,17 +4804,19 @@ gfc_match_data_decl (void)
&& !current_ts.u.derived->attr.zero_comp)
{
- if (current_attr.pointer && gfc_current_state () == COMP_DERIVED)
+ if (current_attr.pointer && gfc_comp_struct (gfc_current_state ()))
goto ok;
gfc_find_symbol (current_ts.u.derived->name,
current_ts.u.derived->ns, 1, &sym);
/* Any symbol that we find had better be a type definition
- which has its components defined. */
- if (sym != NULL && sym->attr.flavor == FL_DERIVED
+ which has its components defined, or be a structure definition
+ actively being parsed. */
+ if (sym != NULL && gfc_fl_struct (sym->attr.flavor)
&& (current_ts.u.derived->components != NULL
- || current_ts.u.derived->attr.zero_comp))
+ || current_ts.u.derived->attr.zero_comp
+ || current_ts.u.derived == gfc_new_block))
goto ok;
gfc_error ("Derived type at %C has not been previously defined "
@@ -5791,6 +6071,10 @@ gfc_match_entry (void)
gfc_error ("ENTRY statement at %C cannot appear within "
"an INTERFACE");
break;
+ case COMP_STRUCTURE:
+ gfc_error ("ENTRY statement at %C cannot appear within "
+ "a STRUCTURE block");
+ break;
case COMP_DERIVED:
gfc_error ("ENTRY statement at %C cannot appear within "
"a DERIVED TYPE block");
@@ -6450,6 +6734,24 @@ gfc_match_end (gfc_statement *st)
eos_ok = 0;
break;
+ case COMP_MAP:
+ *st = ST_END_MAP;
+ target = " map";
+ eos_ok = 0;
+ break;
+
+ case COMP_UNION:
+ *st = ST_END_UNION;
+ target = " union";
+ eos_ok = 0;
+ break;
+
+ case COMP_STRUCTURE:
+ *st = ST_END_STRUCTURE;
+ target = " structure";
+ eos_ok = 0;
+ break;
+
case COMP_DERIVED:
case COMP_DERIVED_CONTAINS:
*st = ST_END_TYPE;
@@ -8020,6 +8322,208 @@ gfc_get_type_attr_spec (symbol_attribute *attr, char *name)
}
+/* Common function for type declaration blocks similar to derived types, such
+ as STRUCTURES and MAPs. Unlike derived types, a structure type
+ does NOT have a generic symbol matching the name given by the user.
+ STRUCTUREs can share names with variables and PARAMETERs so we must allow
+ for the creation of an independent symbol.
+ Other parameters are a message to prefix errors with, the name of the new
+ type to be created, and the flavor to add to the resulting symbol. */
+
+static bool
+get_struct_decl (const char *name, sym_flavor fl, locus *decl,
+ gfc_symbol **result)
+{
+ gfc_symbol *sym;
+ locus where;
+
+ gcc_assert (name[0] == (char) TOUPPER (name[0]));
+
+ if (decl)
+ where = *decl;
+ else
+ where = gfc_current_locus;
+
+ if (gfc_get_symbol (name, NULL, &sym))
+ return false;
+
+ if (!sym)
+ {
+ gfc_internal_error ("Failed to create structure type '%s' at %C", name);
+ return false;
+ }
+
+ if (sym->components != NULL || sym->attr.zero_comp)
+ {
+ gfc_error ("Type definition of '%s' at %C was already defined at %L",
+ sym->name, &sym->declared_at);
+ return false;
+ }
+
+ sym->declared_at = where;
+
+ if (sym->attr.flavor != fl
+ && !gfc_add_flavor (&sym->attr, fl, sym->name, NULL))
+ return false;
+
+ if (!sym->hash_value)
+ /* Set the hash for the compound name for this type. */
+ sym->hash_value = gfc_hash_value (sym);
+
+ /* Normally the type is expected to have been completely parsed by the time
+ a field declaration with this type is seen. For unions, maps, and nested
+ structure declarations, we need to indicate that it is okay that we
+ haven't seen any components yet. This will be updated after the structure
+ is fully parsed. */
+ sym->attr.zero_comp = 0;
+
+ /* Structures always act like derived-types with the SEQUENCE attribute */
+ gfc_add_sequence (&sym->attr, sym->name, NULL);
+
+ if (result) *result = sym;
+
+ return true;
+}
+
+
+/* Match the opening of a MAP block. Like a struct within a union in C;
+ behaves identical to STRUCTURE blocks. */
+
+match
+gfc_match_map (void)
+{
+ /* Counter used to give unique internal names to map structures. */
+ static unsigned int gfc_map_id = 0;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ locus old_loc;
+
+ old_loc = gfc_current_locus;
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ gfc_error ("Junk after MAP statement at %C");
+ gfc_current_locus = old_loc;
+ return MATCH_ERROR;
+ }
+
+ /* Map blocks are anonymous so we make up unique names for the symbol table
+ which are invalid Fortran identifiers. */
+ snprintf (name, GFC_MAX_SYMBOL_LEN + 1, "MM$%u", gfc_map_id++);
+
+ if (!get_struct_decl (name, FL_STRUCT, &old_loc, &sym))
+ return MATCH_ERROR;
+
+ gfc_new_block = sym;
+
+ return MATCH_YES;
+}
+
+
+/* Match the opening of a UNION block. */
+
+match
+gfc_match_union (void)
+{
+ /* Counter used to give unique internal names to union types. */
+ static unsigned int gfc_union_id = 0;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ locus old_loc;
+
+ old_loc = gfc_current_locus;
+
+ if (gfc_match_eos () != MATCH_YES)
+ {
+ gfc_error ("Junk after UNION statement at %C");
+ gfc_current_locus = old_loc;
+ return MATCH_ERROR;
+ }
+
+ /* Unions are anonymous so we make up unique names for the symbol table
+ which are invalid Fortran identifiers. */
+ snprintf (name, GFC_MAX_SYMBOL_LEN + 1, "UU$%u", gfc_union_id++);
+
+ if (!get_struct_decl (name, FL_UNION, &old_loc, &sym))
+ return MATCH_ERROR;
+
+ gfc_new_block = sym;
+
+ return MATCH_YES;
+}
+
+
+/* Match the beginning of a STRUCTURE declaration. This is similar to
+ matching the beginning of a derived type declaration with a few
+ twists. The resulting type symbol has no access control or other
+ interesting attributes. */
+
+match
+gfc_match_structure_decl (void)
+{
+ /* Counter used to give unique internal names to anonymous structures. */
+ int gfc_structure_id = 0;
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ gfc_symbol *sym;
+ match m;
+ locus where;
+
+ if(!gfc_option.flag_dec_structure)
+ {
+ gfc_error ("STRUCTURE at %C is a DEC extension, enable with "
+ "-fdec-structure");
+ return MATCH_ERROR;
+ }
+
+ name[0] = '\0';
+
+ m = gfc_match (" /%n/", name);
+ if (m != MATCH_YES)
+ {
+ /* Non-nested structure declarations require a structure name. */
+ if (!gfc_comp_struct (gfc_current_state ()))
+ {
+ gfc_error ("Structure name expected in non-nested structure "
+ "declaration at %C");
+ return MATCH_ERROR;
+ }
+ /* This is an anonymous structure; make up a unique name for it
+ (upper-case letters never make it to symbol names from the source).
+ The important thing is initializing the type variable
+ and setting gfc_new_symbol, which is immediately used by
+ parse_structure () and variable_decl () to add components of
+ this type. */
+ snprintf (name, GFC_MAX_SYMBOL_LEN + 1, "SS$%u", gfc_structure_id++);
+ }
+
+ where = gfc_current_locus;
+ /* No field list allowed after non-nested structure declaration. */
+ if (!gfc_comp_struct (gfc_current_state ())
+ && gfc_match_eos () != MATCH_YES)
+ {
+ gfc_error ("Junk after non-nested STRUCTURE statement at %C");
+ return MATCH_ERROR;
+ }
+
+ /* Make sure the name is not the name of an intrinsic type. */
+ if (gfc_is_intrinsic_typename (name))
+ {
+ gfc_error ("Structure name '%s' at %C cannot be the same as an"
+ " intrinsic type", name);
+ return MATCH_ERROR;
+ }
+
+ /* Store the actual type symbol for the structure with an upper-case first
+ letter (an invalid Fortran identifier). */
+
+ sprintf (name, gfc_dt_upper_string (name));
+ if (!get_struct_decl (name, FL_STRUCT, &where, &sym))
+ return MATCH_ERROR;
+
+ gfc_new_block = sym;
+ return MATCH_YES;
+}
+
/* Match the beginning of a derived type declaration. If a type name
was the result of a function, then it is possible to have a symbol
already to be known as a derived type yet have no components. */
@@ -8037,7 +8541,7 @@ gfc_match_derived_decl (void)
bool seen_attr = false;
gfc_interface *intr = NULL, *head;
- if (gfc_current_state () == COMP_DERIVED)
+ if (gfc_comp_struct (gfc_current_state ()))
return MATCH_NO;
name[0] = '\0';
@@ -8111,9 +8615,7 @@ gfc_match_derived_decl (void)
if (!sym)
{
/* Use upper case to save the actual derived-type symbol. */
- gfc_get_symbol (gfc_get_string ("%c%s",
- (char) TOUPPER ((unsigned char) gensym->name[0]),
- &gensym->name[1]), NULL, &sym);
+ gfc_get_symbol (gfc_dt_upper_string (gensym->name), NULL, &sym);
sym->name = gfc_get_string (gensym->name);
head = gensym->generic;
intr = gfc_get_interface ();
diff --git a/gcc/fortran/dump-parse-tree.c b/gcc/fortran/dump-parse-tree.c
index 8d50d75fcf6..f50743475d3 100644
--- a/gcc/fortran/dump-parse-tree.c
+++ b/gcc/fortran/dump-parse-tree.c
@@ -106,6 +106,7 @@ show_typespec (gfc_typespec *ts)
{
case BT_DERIVED:
case BT_CLASS:
+ case BT_UNION:
fprintf (dumpfile, "%s", ts->u.derived->name);
break;
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index 1e8be6e4cf7..d1258cdf380 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -335,7 +335,7 @@ gfc_copy_expr (gfc_expr *p)
case BT_HOLLERITH:
case BT_LOGICAL:
- case BT_DERIVED:
+ case_bt_struct:
case BT_CLASS:
case BT_ASSUMED:
break; /* Already done. */
@@ -1279,7 +1279,7 @@ find_component_ref (gfc_constructor_base base, gfc_ref *ref)
/* For extended types, check if the desired component is in one of the
* parent types. */
while (ext > 0 && gfc_find_component (dt->components->ts.u.derived,
- pick->name, true, true))
+ pick->name, true, true, NULL))
{
dt = dt->components->ts.u.derived;
c = gfc_constructor_first (c->expr->value.constructor);
@@ -1649,7 +1649,7 @@ simplify_const_ref (gfc_expr *p)
case AR_FULL:
if (p->ref->next != NULL
- && (p->ts.type == BT_CHARACTER || p->ts.type == BT_DERIVED))
+ && (p->ts.type == BT_CHARACTER || gfc_bt_struct (p->ts.type)))
{
for (c = gfc_constructor_first (p->value.constructor);
c; c = gfc_constructor_next (c))
@@ -1659,7 +1659,7 @@ simplify_const_ref (gfc_expr *p)
return false;
}
- if (p->ts.type == BT_DERIVED
+ if (gfc_bt_struct (p->ts.type)
&& p->ref->next
&& (c = gfc_constructor_first (p->value.constructor)))
{
@@ -3926,9 +3926,9 @@ gfc_has_default_initializer (gfc_symbol *der)
{
gfc_component *c;
- gcc_assert (der->attr.flavor == FL_DERIVED);
+ gcc_assert (gfc_fl_struct (der->attr.flavor));
for (c = der->components; c; c = c->next)
- if (c->ts.type == BT_DERIVED)
+ if (gfc_bt_struct (c->ts.type))
{
if (!c->attr.pointer && !c->attr.proc_pointer
&& gfc_has_default_initializer (c->ts.u.derived))
@@ -3975,6 +3975,10 @@ gfc_default_initializer (gfc_typespec *ts)
if (comp->initializer)
{
+ /* Save the component ref for STRUCTUREs and UNIONs. */
+ if (ts->u.derived->attr.flavor == FL_STRUCT
+ || ts->u.derived->attr.flavor == FL_UNION)
+ ctor->n.component = comp;
ctor->expr = gfc_copy_expr (comp->initializer);
if ((comp->ts.type != comp->initializer->ts.type
|| comp->ts.kind != comp->initializer->ts.kind)
diff --git a/gcc/fortran/frontend-passes.c b/gcc/fortran/frontend-passes.c
index 7eeb5a68aa2..37c42bb5e34 100644
--- a/gcc/fortran/frontend-passes.c
+++ b/gcc/fortran/frontend-passes.c
@@ -174,8 +174,10 @@ realloc_string_callback (gfc_code **c, int *walk_subtrees ATTRIBUTE_UNUSED,
if (!gfc_check_dependency (expr1, expr2, true))
return 0;
-
+
current_code = c;
+ inserted_block = NULL;
+ changed_statement = NULL;
n = create_var (expr2, "trim");
co->expr2 = n;
return 0;
@@ -2812,6 +2814,12 @@ inline_matmul_assign (gfc_code **c, int *walk_subtrees,
if (in_where)
return 0;
+ /* For now don't do anything in OpenMP workshare, it confuses
+ its translation, which expects only the allowed statements in there.
+ We should figure out how to parallelize this eventually. */
+ if (in_omp_workshare)
+ return 0;
+
expr1 = co->expr1;
expr2 = co->expr2;
if (expr2->expr_type != EXPR_FUNCTION
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index a0fb5fda9e5..0bb71cb184d 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -62,6 +62,15 @@ not after.
#define gfc_is_whitespace(c) ((c==' ') || (c=='\t'))
+/* Macros to check for groups of structure-like types and flavors since
+ derived types, structures, maps, unions are often treated similarly. */
+#define gfc_bt_struct(t) \
+ ((t) == BT_DERIVED || (t) == BT_UNION)
+#define gfc_fl_struct(f) \
+ ((f) == FL_DERIVED || (f) == FL_UNION || (f) == FL_STRUCT)
+#define case_bt_struct case BT_DERIVED: case BT_UNION
+#define case_fl_struct case FL_DERIVED: case FL_UNION: case FL_STRUCT
+
/* Stringization. */
#define stringize(x) expand_macro(x)
#define expand_macro(x) # x
@@ -203,6 +212,8 @@ enum gfc_statement
ST_POINTER_ASSIGNMENT, ST_SELECT_CASE, ST_SEQUENCE, ST_SIMPLE_IF,
ST_STATEMENT_FUNCTION, ST_DERIVED_DECL, ST_LABEL_ASSIGNMENT, ST_ENUM,
ST_ENUMERATOR, ST_END_ENUM, ST_SELECT_TYPE, ST_TYPE_IS, ST_CLASS_IS,
+ ST_STRUCTURE_DECL, ST_END_STRUCTURE,
+ ST_UNION, ST_END_UNION, ST_MAP, ST_END_MAP,
ST_OACC_PARALLEL_LOOP, ST_OACC_END_PARALLEL_LOOP, ST_OACC_PARALLEL,
ST_OACC_END_PARALLEL, ST_OACC_KERNELS, ST_OACC_END_KERNELS, ST_OACC_DATA,
ST_OACC_END_DATA, ST_OACC_HOST_DATA, ST_OACC_END_HOST_DATA, ST_OACC_LOOP,
@@ -254,12 +265,12 @@ enum interface_type
};
/* Symbol flavors: these are all mutually exclusive.
- 10 elements = 4 bits. */
+ 12 elements = 4 bits. */
enum sym_flavor
{
FL_UNKNOWN = 0, FL_PROGRAM, FL_BLOCK_DATA, FL_MODULE, FL_VARIABLE,
FL_PARAMETER, FL_LABEL, FL_PROCEDURE, FL_DERIVED, FL_NAMELIST,
- FL_VOID
+ FL_UNION, FL_STRUCT, FL_VOID
};
/* Procedure types. 7 elements = 3 bits. */
@@ -2523,6 +2534,8 @@ typedef struct
int flag_init_character;
char flag_init_character_value;
+ int flag_dec_structure;
+
int fpe;
int fpe_summary;
int rtcheck;
@@ -2743,6 +2756,7 @@ bool gfc_check_any_c_kind (gfc_typespec *);
int gfc_validate_kind (bt, int, bool);
int gfc_get_int_kind_from_width_isofortranenv (int size);
int gfc_get_real_kind_from_width_isofortranenv (int size);
+tree gfc_get_union_type (gfc_symbol *);
tree gfc_get_derived_type (gfc_symbol * derived);
extern int gfc_index_integer_kind;
extern int gfc_default_integer_kind;
@@ -2831,7 +2845,8 @@ int gfc_copy_dummy_sym (gfc_symbol **, gfc_symbol *, int);
bool gfc_add_component (gfc_symbol *, const char *, gfc_component **);
gfc_symbol *gfc_use_derived (gfc_symbol *);
gfc_symtree *gfc_use_derived_tree (gfc_symtree *);
-gfc_component *gfc_find_component (gfc_symbol *, const char *, bool, bool);
+gfc_component *gfc_find_component (gfc_symbol *, const char *, bool, bool,
+ gfc_ref **);
gfc_st_label *gfc_get_st_label (int);
void gfc_free_st_label (gfc_st_label *);
@@ -3174,6 +3189,8 @@ void gfc_module_done_2 (void);
void gfc_dump_module (const char *, int);
bool gfc_check_symbol_access (gfc_symbol *);
void gfc_free_use_stmts (gfc_use_list *);
+const char *gfc_dt_lower_string (const char *);
+const char *gfc_dt_upper_string (const char *);
/* primary.c */
symbol_attribute gfc_variable_attr (gfc_expr *, gfc_typespec *);
diff --git a/gcc/fortran/gfortran.texi b/gcc/fortran/gfortran.texi
index 2704bc54978..4d288bafac3 100644
--- a/gcc/fortran/gfortran.texi
+++ b/gcc/fortran/gfortran.texi
@@ -474,9 +474,9 @@ The GNU Fortran compiler is able to compile nearly all
standard-compliant Fortran 95, Fortran 90, and Fortran 77 programs,
including a number of standard and non-standard extensions, and can be
used on real-world programs. In particular, the supported extensions
-include OpenMP, Cray-style pointers, and several Fortran 2003 and Fortran
-2008 features, including TR 15581. However, it is still under
-development and has a few remaining rough edges.
+include OpenMP, Cray-style pointers, some old vendor extensions, and several
+Fortran 2003 and Fortran 2008 features, including TR 15581. However, it is
+still under development and has a few remaining rough edges.
There also is initial support for OpenACC.
Note that this is an experimental feature, incomplete, and subject to
change in future versions of GCC. See
@@ -1459,6 +1459,8 @@ without warning.
* OpenACC::
* Argument list functions::
* Read/Write after EOF marker::
+* STRUCTURE and RECORD::
+* UNION and MAP::
@end menu
@node Old-style kind specifications
@@ -2117,40 +2119,6 @@ consider @code{BACKSPACE} or @code{REWIND} to properly position
the file before the EOF marker. As an extension, the run-time error may
be disabled using -std=legacy.
-@node Extensions not implemented in GNU Fortran
-@section Extensions not implemented in GNU Fortran
-@cindex extensions, not implemented
-
-The long history of the Fortran language, its wide use and broad
-userbase, the large number of different compiler vendors and the lack of
-some features crucial to users in the first standards have lead to the
-existence of a number of important extensions to the language. While
-some of the most useful or popular extensions are supported by the GNU
-Fortran compiler, not all existing extensions are supported. This section
-aims at listing these extensions and offering advice on how best make
-code that uses them running with the GNU Fortran compiler.
-
-@c More can be found here:
-@c -- https://gcc.gnu.org/onlinedocs/gcc-3.4.6/g77/Missing-Features.html
-@c -- the list of Fortran and libgfortran bugs closed as WONTFIX:
-@c http://tinyurl.com/2u4h5y
-
-@menu
-* STRUCTURE and RECORD::
-@c * UNION and MAP::
-* ENCODE and DECODE statements::
-* Variable FORMAT expressions::
-@c * Q edit descriptor::
-@c * AUTOMATIC statement::
-@c * TYPE and ACCEPT I/O Statements::
-@c * .XOR. operator::
-@c * CARRIAGECONTROL, DEFAULTFILE, DISPOSE and RECORDTYPE I/O specifiers::
-@c * Omitted arguments in procedure call::
-* Alternate complex function syntax::
-* Volatile COMMON blocks::
-* OPEN( ... NAME=)::
-@end menu
-
@node STRUCTURE and RECORD
@subsection @code{STRUCTURE} and @code{RECORD}
@@ -2226,16 +2194,211 @@ store_catalog(12) = pear
print *, store_catalog(12)
@end example
+@noindent
+GNU Fortran implements STRUCTURES like derived types with the following
+rules and exceptions:
+
+@itemize @bullet
+@item Structures act like derived types with the @code{SEQUENCE} attribute.
+Otherwise they may contain no specifiers.
+
+@item Structures may share names with other symbols. For example, the following
+is invalid for derived types, but valid for structures:
+
+@smallexample
+structure /header/
+ ! ...
+end structure
+record /header/ header
+@end smallexample
+
+@item Structure types may be declared nested within another parent structure.
+The syntax is:
+@smallexample
+structure /type-name/
+ ...
+ structure [/<type-name>/] <field-list>
+...
+@end smallexample
+
+The type name may be ommitted, in which case the structure type itself is
+anonymous, and other structures of the same type cannot be instantiated. The
+following shows some examples:
+
+@example
+structure /appointment/
+ ! nested structure definition: app_time is an array of two 'time'
+ structure /time/ app_time (2)
+ integer(1) hour, minute
+ end structure
+ character(10) memo
+end structure
+
+! The 'time' structure is still usable
+record /time/ now
+now = time(5, 30)
+
+...
+
+structure /appointment/
+ ! anonymous nested structure definition
+ structure start, end
+ integer(1) hour, minute
+ end structure
+ character(10) memo
+end structure
+@end example
+
+@item Structures may contain @code{UNION} blocks. For more detail see the
+section on @ref{UNION and MAP}.
-@c @node UNION and MAP
-@c @subsection @code{UNION} and @code{MAP}
-@c @cindex @code{UNION}
-@c @cindex @code{MAP}
-@c
-@c For help writing this one, see
-@c http://www.eng.umd.edu/~nsw/ench250/fortran1.htm#UNION and
-@c http://www.tacc.utexas.edu/services/userguides/pgi/pgiws_ug/pgi32u06.htm
+@item Structures support old-style initialization of components, like
+those described in @ref{Old-style variable initialization}. For array
+initializers, an initializer may contain a repeat specification of the form
+@code{<literal-integer> * <constant-initializer>}. The value of the integer
+indicates the number of times to repeat the constant initializer when expanding
+the initializer list.
+@end itemize
+
+@node UNION and MAP
+@subsection @code{UNION} and @code{MAP}
+@cindex @code{UNION}
+@cindex @code{MAP}
+
+Unions are an old vendor extension which were commonly used with the
+non-standard @ref{STRUCTURE and RECORD} extensions. Use of @code{UNION} and
+@code{MAP} is automatically enabled with @option{-fdec-structure}.
+
+A @code{UNION} declaration occurs within a structure; within the definition of
+each union is a number of @code{MAP} blocks. Each @code{MAP} shares storage
+with its sibling maps (in the same union), and the size of the union is the
+size of the largest map within it, just as with unions in C. The major
+difference is that component references do not indicate which union or map the
+component is in (the compiler gets to figure that out).
+
+Here is a small example:
+@smallexample
+structure /myunion/
+union
+ map
+ character(2) w0, w1, w2
+ end map
+ map
+ character(6) long
+ end map
+end union
+end structure
+
+record /myunion/ rec
+! After this assignment...
+rec.long = 'hello!'
+
+! The following is true:
+! rec.w0 === 'he'
+! rec.w1 === 'll'
+! rec.w2 === 'o!'
+@end smallexample
+
+The two maps share memory, and the size of the union is ultimately six bytes:
+
+@example
+0 1 2 3 4 5 6 Byte offset
+-------------------------------
+| | | | | | |
+-------------------------------
+
+^ W0 ^ W1 ^ W2 ^
+ \-------/ \-------/ \-------/
+
+^ LONG ^
+ \---------------------------/
+@end example
+
+Following is an example mirroring the layout of an Intel x86_64 register:
+
+@example
+structure /reg/
+ union ! U0 ! rax
+ map
+ character(16) rx
+ end map
+ map
+ character(8) rh ! rah
+ union ! U1
+ map
+ character(8) rl ! ral
+ end map
+ map
+ character(8) ex ! eax
+ end map
+ map
+ character(4) eh ! eah
+ union ! U2
+ map
+ character(4) el ! eal
+ end map
+ map
+ character(4) x ! ax
+ end map
+ map
+ character(2) h ! ah
+ character(2) l ! al
+ end map
+ end union
+ end map
+ end union
+ end map
+ end union
+end structure
+record /reg/ a
+
+! After this assignment...
+a.rx = 'AAAAAAAA.BBB.C.D'
+
+! The following is true:
+a.rx === 'AAAAAAAA.BBB.C.D'
+a.rh === 'AAAAAAAA'
+a.rl === '.BBB.C.D'
+a.ex === '.BBB.C.D'
+a.eh === '.BBB'
+a.el === '.C.D'
+a.x === '.C.D'
+a.h === '.C'
+a.l === '.D'
+@end example
+
+
+@node Extensions not implemented in GNU Fortran
+@section Extensions not implemented in GNU Fortran
+@cindex extensions, not implemented
+
+The long history of the Fortran language, its wide use and broad
+userbase, the large number of different compiler vendors and the lack of
+some features crucial to users in the first standards have lead to the
+existence of a number of important extensions to the language. While
+some of the most useful or popular extensions are supported by the GNU
+Fortran compiler, not all existing extensions are supported. This section
+aims at listing these extensions and offering advice on how best make
+code that uses them running with the GNU Fortran compiler.
+@c More can be found here:
+@c -- https://gcc.gnu.org/onlinedocs/gcc-3.4.6/g77/Missing-Features.html
+@c -- the list of Fortran and libgfortran bugs closed as WONTFIX:
+@c http://tinyurl.com/2u4h5y
+
+@menu
+* ENCODE and DECODE statements::
+* Variable FORMAT expressions::
+@c * Q edit descriptor::
+@c * AUTOMATIC statement::
+@c * TYPE and ACCEPT I/O Statements::
+@c * .XOR. operator::
+@c * CARRIAGECONTROL, DEFAULTFILE, DISPOSE and RECORDTYPE I/O specifiers::
+@c * Omitted arguments in procedure call::
+* Alternate complex function syntax::
+* Volatile COMMON blocks::
+* OPEN( ... NAME=)::
+@end menu
@node ENCODE and DECODE statements
@subsection @code{ENCODE} and @code{DECODE} statements
@@ -2355,7 +2518,6 @@ invalid standard Fortran syntax and is not supported by
@code{VOLATILE} variables in @code{COMMON} blocks since revision 4.3.
-
@node OPEN( ... NAME=)
@subsection @code{OPEN( ... NAME=)}
@cindex @code{NAM}
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 5c66c6ef31c..5bd1279291e 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -387,19 +387,147 @@ gfc_match_end_interface (void)
}
+/* Compare components according to 4.4.2 of the Fortran standard. */
+
+static int
+compare_components (gfc_component *cmp1, gfc_component *cmp2,
+ gfc_symbol *derived1, gfc_symbol *derived2)
+{
+ gfc_symbol *d1, *d2;
+ bool anonymous = false;
+
+ /* Unions, maps, and anonymous structures all have names like "[xX]X$\d+"
+ which should not be compared. */
+ d1 = cmp1->ts.u.derived;
+ d2 = cmp2->ts.u.derived;
+ if ( (d1 && (d1->attr.flavor == FL_STRUCT || d1->attr.flavor == FL_UNION)
+ && ISUPPER (cmp1->name[1]))
+ || (d2 && (d2->attr.flavor == FL_STRUCT || d2->attr.flavor == FL_UNION)
+ && ISUPPER (cmp1->name[1])))
+ anonymous = true;
+
+ if (!anonymous && strcmp (cmp1->name, cmp2->name) != 0)
+ return 0;
+
+ if (cmp1->attr.access != cmp2->attr.access)
+ return 0;
+
+ if (cmp1->attr.pointer != cmp2->attr.pointer)
+ return 0;
+
+ if (cmp1->attr.dimension != cmp2->attr.dimension)
+ return 0;
+
+ if (cmp1->attr.allocatable != cmp2->attr.allocatable)
+ return 0;
+
+ if (cmp1->attr.dimension && gfc_compare_array_spec (cmp1->as, cmp2->as) == 0)
+ return 0;
+
+ /* Make sure that link lists do not put this function into an
+ endless recursive loop! */
+ if (!(cmp1->ts.type == BT_DERIVED && derived1 == cmp1->ts.u.derived)
+ && !(cmp2->ts.type == BT_DERIVED && derived2 == cmp2->ts.u.derived)
+ && gfc_compare_types (&cmp1->ts, &cmp2->ts) == 0)
+ return 0;
+
+ else if ( (cmp1->ts.type == BT_DERIVED && derived1 == cmp1->ts.u.derived)
+ && !(cmp2->ts.type == BT_DERIVED && derived2 == cmp2->ts.u.derived))
+ return 0;
+
+ else if (!(cmp1->ts.type == BT_DERIVED && derived1 == cmp1->ts.u.derived)
+ && (cmp2->ts.type == BT_DERIVED && derived2 == cmp2->ts.u.derived))
+ return 0;
+
+ return 1;
+}
+
+
+/* Compare two union types by comparing the components of their maps.
+ Because unions and maps are anonymous their types get special internal
+ names; therefore the usual derived type comparison will fail on them.
+
+ Returns nonzero if equal, as with gfc_compare_derived_types. Also as with
+ gfc_compare_derived_types, 'equal' is closer to meaning 'duplicate
+ definitions' than 'equivalent structure'. */
+
+int
+gfc_compare_union_types (gfc_symbol *un1, gfc_symbol *un2)
+{
+ gfc_component *map1, *map2, *cmp1, *cmp2;
+
+ if (un1->attr.flavor != FL_UNION || un2->attr.flavor != FL_UNION)
+ return 0;
+
+ map1 = un1->components;
+ map2 = un2->components;
+
+ /* In terms of 'equality' here we are worried about types which are
+ declared the same in two places, not types that represent equivalent
+ structures. (This is common because of FORTRAN's weird scoping rules.)
+ Though two unions with their maps in different orders could be equivalent,
+ we will say they are not equal for the purposes of this test; therefore
+ we compare the maps sequentially. */
+ for (;;)
+ {
+ cmp1 = map1->ts.u.derived->components;
+ cmp2 = map2->ts.u.derived->components;
+ for (;;)
+ {
+ /* No two fields will ever point to the same map type unless they are
+ the same component, because one map field is created with its type
+ declaration. Therefore don't worry about recursion here. */
+ /* TODO: worry about recursion into parent types of the unions? */
+ if (compare_components (cmp1, cmp2,
+ map1->ts.u.derived, map2->ts.u.derived) == 0)
+ return 0;
+
+ cmp1 = cmp1->next;
+ cmp2 = cmp2->next;
+
+ if (cmp1 == NULL && cmp2 == NULL)
+ break;
+ if (cmp1 == NULL || cmp2 == NULL)
+ return 0;
+ }
+
+ map1 = map1->next;
+ map2 = map2->next;
+
+ if (map1 == NULL && map2 == NULL)
+ break;
+ if (map1 == NULL || map2 == NULL)
+ return 0;
+ }
+
+ return 1;
+}
+
+
+
/* Compare two derived types using the criteria in 4.4.2 of the standard,
recursing through gfc_compare_types for the components. */
int
gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2)
{
- gfc_component *dt1, *dt2;
+ gfc_component *cmp1, *cmp2;
+ bool anonymous = false;
if (derived1 == derived2)
return 1;
gcc_assert (derived1 && derived2);
+ /* MAP and anonymous STRUCTURE types have internal names of the form
+ mM* and sS* (we can get away this this because source names are converted
+ to lowerase). Compare anonymous type names specially because each
+ gets a unique name when it is declared. */
+ anonymous = (derived1->name[0] == derived2->name[0]
+ && derived1->name[1] && derived2->name[1] && derived2->name[2]
+ && derived1->name[1] == (char) TOUPPER (derived1->name[0])
+ && derived2->name[2] == (char) TOUPPER (derived2->name[0]));
+
/* Special case for comparing derived types across namespaces. If the
true names and module names are the same and the module name is
nonnull, then they are equal. */
@@ -409,9 +537,11 @@ gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2)
return 1;
/* Compare type via the rules of the standard. Both types must have
- the SEQUENCE or BIND(C) attribute to be equal. */
+ the SEQUENCE or BIND(C) attribute to be equal. STRUCTUREs are special
+ because they can be anonymous; therefore two structures with different
+ names may be equal. */
- if (strcmp (derived1->name, derived2->name))
+ if (strcmp (derived1->name, derived2->name) != 0 && !anonymous)
return 0;
if (derived1->component_access == ACCESS_PRIVATE
@@ -422,53 +552,30 @@ gfc_compare_derived_types (gfc_symbol *derived1, gfc_symbol *derived2)
&& !(derived1->attr.is_bind_c && derived2->attr.is_bind_c))
return 0;
- dt1 = derived1->components;
- dt2 = derived2->components;
+ /* Protect against null components. */
+ if (derived1->attr.zero_comp != derived2->attr.zero_comp)
+ return 0;
+
+ if (derived1->attr.zero_comp)
+ return 1;
+
+ cmp1 = derived1->components;
+ cmp2 = derived2->components;
/* Since subtypes of SEQUENCE types must be SEQUENCE types as well, a
simple test can speed things up. Otherwise, lots of things have to
match. */
for (;;)
{
- if (strcmp (dt1->name, dt2->name) != 0)
- return 0;
-
- if (dt1->attr.access != dt2->attr.access)
- return 0;
-
- if (dt1->attr.pointer != dt2->attr.pointer)
- return 0;
-
- if (dt1->attr.dimension != dt2->attr.dimension)
- return 0;
+ if (!compare_components (cmp1, cmp2, derived1, derived2))
+ return 0;
- if (dt1->attr.allocatable != dt2->attr.allocatable)
- return 0;
-
- if (dt1->attr.dimension && gfc_compare_array_spec (dt1->as, dt2->as) == 0)
- return 0;
-
- /* Make sure that link lists do not put this function into an
- endless recursive loop! */
- if (!(dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived)
- && !(dt2->ts.type == BT_DERIVED && derived2 == dt2->ts.u.derived)
- && gfc_compare_types (&dt1->ts, &dt2->ts) == 0)
- return 0;
+ cmp1 = cmp1->next;
+ cmp2 = cmp2->next;
- else if ((dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived)
- && !(dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived))
- return 0;
-
- else if (!(dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived)
- && (dt1->ts.type == BT_DERIVED && derived1 == dt1->ts.u.derived))
- return 0;
-
- dt1 = dt1->next;
- dt2 = dt2->next;
-
- if (dt1 == NULL && dt2 == NULL)
+ if (cmp1 == NULL && cmp2 == NULL)
break;
- if (dt1 == NULL || dt2 == NULL)
+ if (cmp1 == NULL || cmp2 == NULL)
return 0;
}
@@ -509,18 +616,18 @@ gfc_compare_types (gfc_typespec *ts1, gfc_typespec *ts2)
&& (ts1->u.derived->attr.sequence || ts1->u.derived->attr.is_bind_c))
return 1;
+ if (ts1->type == BT_UNION && ts2->type == BT_UNION)
+ return gfc_compare_union_types (ts1->u.derived, ts2->u.derived);
+
if (ts1->type != ts2->type
- && ((ts1->type != BT_DERIVED && ts1->type != BT_CLASS)
- || (ts2->type != BT_DERIVED && ts2->type != BT_CLASS)))
+ && ((!gfc_bt_struct (ts1->type) && ts1->type != BT_CLASS)
+ || (!gfc_bt_struct (ts2->type) && ts2->type != BT_CLASS)))
return 0;
if (ts1->type != BT_DERIVED && ts1->type != BT_CLASS)
return (ts1->kind == ts2->kind);
/* Compare derived types. */
- if (gfc_type_compatible (ts1, ts2))
- return 1;
-
- return gfc_compare_derived_types (ts1->u.derived ,ts2->u.derived);
+ return gfc_type_compatible (ts1, ts2);
}
@@ -1585,7 +1692,7 @@ check_interface0 (gfc_interface *p, const char *interface_name)
functions or subroutines. */
if (((!p->sym->attr.function && !p->sym->attr.subroutine)
|| !p->sym->attr.if_source)
- && p->sym->attr.flavor != FL_DERIVED)
+ && !gfc_fl_struct (p->sym->attr.flavor))
{
if (p->sym->attr.external)
gfc_error ("Procedure %qs in %s at %L has no explicit interface",
@@ -1599,14 +1706,14 @@ check_interface0 (gfc_interface *p, const char *interface_name)
/* Verify that procedures are either all SUBROUTINEs or all FUNCTIONs. */
if ((psave->sym->attr.function && !p->sym->attr.function
- && p->sym->attr.flavor != FL_DERIVED)
+ && !gfc_fl_struct (p->sym->attr.flavor))
|| (psave->sym->attr.subroutine && !p->sym->attr.subroutine))
{
- if (p->sym->attr.flavor != FL_DERIVED)
+ if (!gfc_fl_struct (p->sym->attr.flavor))
gfc_error ("In %s at %L procedures must be either all SUBROUTINEs"
" or all FUNCTIONs", interface_name,
&p->sym->declared_at);
- else
+ else if (p->sym->attr.flavor == FL_DERIVED)
gfc_error ("In %s at %L procedures must be all FUNCTIONs as the "
"generic name is also the name of a derived type",
interface_name, &p->sym->declared_at);
@@ -1666,8 +1773,8 @@ check_interface1 (gfc_interface *p, gfc_interface *q0,
if (p->sym->name == q->sym->name && p->sym->module == q->sym->module)
continue;
- if (p->sym->attr.flavor != FL_DERIVED
- && q->sym->attr.flavor != FL_DERIVED
+ if (!gfc_fl_struct (p->sym->attr.flavor)
+ && !gfc_fl_struct (q->sym->attr.flavor)
&& gfc_compare_interfaces (p->sym, q->sym, q->sym->name,
generic_flag, 0, NULL, 0, NULL, NULL))
{
@@ -2006,7 +2113,7 @@ compare_parameter (gfc_symbol *formal, gfc_expr *actual,
}
ppc = gfc_get_proc_ptr_comp (actual);
- if (ppc)
+ if (ppc && ppc->ts.interface)
{
if (!gfc_compare_interfaces (formal, ppc->ts.interface, ppc->name, 0, 1,
err, sizeof(err), NULL, NULL))
@@ -3550,7 +3657,7 @@ gfc_search_interface (gfc_interface *intr, int sub_flag,
for (; intr; intr = intr->next)
{
- if (intr->sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (intr->sym->attr.flavor))
continue;
if (sub_flag && intr->sym->attr.function)
continue;
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index e90656e4eef..e8b8409319e 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -115,7 +115,8 @@ by type. Explanations are in the following sections.
@item Fortran Language Options
@xref{Fortran Dialect Options,,Options controlling Fortran dialect}.
@gccoptlist{-fall-intrinsics -fbackslash -fcray-pointer -fd-lines-as-code @gol
--fd-lines-as-comments -fdefault-double-8 -fdefault-integer-8 @gol
+-fd-lines-as-comments @gol
+-fdec -fdec-structure -fdefault-double-8 -fdefault-integer-8 @gol
-fdefault-real-8 -fdollar-ok -ffixed-line-length-@var{n} @gol
-ffixed-line-length-none -ffree-form -ffree-line-length-@var{n} @gol
-ffree-line-length-none -fimplicit-none -finteger-4-integer-8 @gol
@@ -228,6 +229,24 @@ given they are treated as if the first column contained a blank. If the
@option{-fd-lines-as-comments} option is given, they are treated as
comment lines.
+@item -fdec
+@opindex @code{fdec}
+DEC compatibility mode. Enables extensions and other features that mimic
+the default behavior of older compilers (such as DEC).
+These features are non-standard and should be avoided at all costs.
+For details on GNU Fortran's implementation of these extensions see the
+full documentation.
+
+Other flags enabled by this switch are:
+@option{-fdollar-ok} @option{-fcray-pointer} @option{-fdec-structure}
+
+@item -fdec-structure
+@opindex @code{fdec-structure}
+Enable DEC @code{STRUCTURE} and @code{RECORD} as well as @code{UNION},
+@code{MAP}, and dot ('.') as a member separator (in addition to '%'). This is
+provided for compatibility only; Fortran 90 derived types should be used
+instead where possible.
+
@item -fdollar-ok
@opindex @code{fdollar-ok}
@cindex @code{$}
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 45428d8cf41..bdf5fa5fb4a 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -416,6 +416,14 @@ fd-lines-as-comments
Fortran RejectNegative
Treat lines with 'D' in column one as comments.
+fdec
+Fortran
+Enable all DEC language extensions.
+
+fdec-structure
+Fortran
+Enable support for DEC STRUCTURE/RECORD.
+
fdefault-double-8
Fortran Var(flag_default_double)
Set the default double precision kind to an 8 byte wide type.
diff --git a/gcc/fortran/libgfortran.h b/gcc/fortran/libgfortran.h
index 96063f796d0..e9132506367 100644
--- a/gcc/fortran/libgfortran.h
+++ b/gcc/fortran/libgfortran.h
@@ -164,6 +164,6 @@ typedef enum
typedef enum
{ BT_UNKNOWN = 0, BT_INTEGER, BT_LOGICAL, BT_REAL, BT_COMPLEX,
BT_DERIVED, BT_CHARACTER, BT_CLASS, BT_PROCEDURE, BT_HOLLERITH, BT_VOID,
- BT_ASSUMED
+ BT_ASSUMED, BT_UNION
}
bt;
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 2490f85626e..f3a4a43a34c 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -113,6 +113,128 @@ gfc_op2string (gfc_intrinsic_op op)
/******************** Generic matching subroutines ************************/
+/* Matches a member separator. With standard FORTRAN this is '%', but with
+ DEC structures we must carefully match dot ('.').
+ Because operators are spelled ".op.", a dotted string such as "x.y.z..."
+ can be either a component reference chain or a combination of binary
+ operations.
+ There is no real way to win because the string may be grammatically
+ ambiguous. The following rules help avoid ambiguities - they match
+ some behavior of other (older) compilers. If the rules here are changed
+ the test cases should be updated. If the user has problems with these rules
+ they probably deserve the consequences. Consider "x.y.z":
+ (1) If any user defined operator ".y." exists, this is always y(x,z)
+ (even if ".y." is the wrong type and/or x has a member y).
+ (2) Otherwise if x has a member y, and y is itself a derived type,
+ this is (x->y)->z, even if an intrinsic operator exists which
+ can handle (x,z).
+ (3) If x has no member y or (x->y) is not a derived type but ".y."
+ is an intrinsic operator (such as ".eq."), this is y(x,z).
+ (4) Lastly if there is no operator ".y." and x has no member "y", it is an
+ error.
+ It is worth noting that the logic here does not support mixed use of member
+ accessors within a single string. That is, even if x has component y and y
+ has component z, the following are all syntax errors:
+ "x%y.z" "x.y%z" "(x.y).z" "(x%y)%z"
+ */
+
+match
+gfc_match_member_sep(gfc_symbol *sym)
+{
+ char name[GFC_MAX_SYMBOL_LEN + 1];
+ locus dot_loc, start_loc;
+ gfc_intrinsic_op iop;
+ match m;
+ gfc_symbol *tsym;
+ gfc_component *c = NULL;
+
+ /* What a relief: '%' is an unambiguous member separator. */
+ if (gfc_match_char ('%') == MATCH_YES)
+ return MATCH_YES;
+
+ /* Beware ye who enter here. */
+ if (!gfc_option.flag_dec_structure || !sym)
+ return MATCH_NO;
+
+ tsym = NULL;
+
+ /* We may be given either a derived type variable or the derived type
+ declaration itself (which actually contains the components);
+ we need the latter to search for components. */
+ if (gfc_fl_struct (sym->attr.flavor))
+ tsym = sym;
+ else if (gfc_bt_struct (sym->ts.type))
+ tsym = sym->ts.u.derived;
+
+ iop = INTRINSIC_NONE;
+ name[0] = '\0';
+ m = MATCH_NO;
+
+ /* If we have to reject come back here later. */
+ start_loc = gfc_current_locus;
+
+ /* Look for a component access next. */
+ if (gfc_match_char ('.') != MATCH_YES)
+ return MATCH_NO;
+
+ /* If we accept, come back here. */
+ dot_loc = gfc_current_locus;
+
+ /* Try to match a symbol name following the dot. */
+ if (gfc_match_name (name) != MATCH_YES)
+ {
+ gfc_error ("Expected structure component or operator name "
+ "after '.' at %C");
+ goto error;
+ }
+
+ /* If no dot follows we have "x.y" which should be a component access. */
+ if (gfc_match_char ('.') != MATCH_YES)
+ goto yes;
+
+ /* Now we have a string "x.y.z" which could be a nested member access
+ (x->y)->z or a binary operation y on x and z. */
+
+ /* First use any user-defined operators ".y." */
+ if (gfc_find_uop (name, sym->ns) != NULL)
+ goto no;
+
+ /* Match accesses to existing derived-type components for
+ derived-type vars: "x.y.z" = (x->y)->z */
+ c = gfc_find_component(tsym, name, false, true, NULL);
+ if (c && (gfc_bt_struct (c->ts.type) || c->ts.type == BT_CLASS))
+ goto yes;
+
+ /* If y is not a component or has no members, try intrinsic operators. */
+ gfc_current_locus = start_loc;
+ if (gfc_match_intrinsic_op (&iop) != MATCH_YES)
+ {
+ /* If ".y." is not an intrinsic operator but y was a valid non-
+ structure component, match and leave the trailing dot to be
+ dealt with later. */
+ if (c)
+ goto yes;
+
+ gfc_error ("'%s' is neither a defined operator nor a "
+ "structure component in dotted string at %C", name);
+ goto error;
+ }
+
+ /* .y. is an intrinsic operator, overriding any possible member access. */
+ goto no;
+
+ /* Return keeping the current locus consistent with the match result. */
+error:
+ m = MATCH_ERROR;
+no:
+ gfc_current_locus = start_loc;
+ return m;
+yes:
+ gfc_current_locus = dot_loc;
+ return MATCH_YES;
+}
+
+
/* This function scans the current statement counting the opened and closed
parenthesis to make sure they are balanced. */
diff --git a/gcc/fortran/match.h b/gcc/fortran/match.h
index c3033add826..348ca701c92 100644
--- a/gcc/fortran/match.h
+++ b/gcc/fortran/match.h
@@ -60,6 +60,7 @@ match gfc_match (const char *, ...);
match gfc_match_iterator (gfc_iterator *, int);
match gfc_match_parens (void);
match gfc_match_type_spec (gfc_typespec *);
+match gfc_match_member_sep(gfc_symbol *);
/* Statement matchers. */
@@ -208,6 +209,9 @@ match gfc_match_function_decl (void);
match gfc_match_entry (void);
match gfc_match_subroutine (void);
match gfc_match_submod_proc (void);
+match gfc_match_map (void);
+match gfc_match_union (void);
+match gfc_match_structure_decl (void);
match gfc_match_derived_decl (void);
match gfc_match_final_decl (void);
diff --git a/gcc/fortran/misc.c b/gcc/fortran/misc.c
index 405bae072ba..1747ff2ac74 100644
--- a/gcc/fortran/misc.c
+++ b/gcc/fortran/misc.c
@@ -83,6 +83,9 @@ gfc_basic_typename (bt type)
case BT_HOLLERITH:
p = "HOLLERITH";
break;
+ case BT_UNION:
+ p = "UNION";
+ break;
case BT_DERIVED:
p = "DERIVED";
break;
@@ -144,6 +147,9 @@ gfc_typename (gfc_typespec *ts)
case BT_HOLLERITH:
sprintf (buffer, "HOLLERITH");
break;
+ case BT_UNION:
+ sprintf (buffer, "UNION(%s)", ts->u.derived->name);
+ break;
case BT_DERIVED:
sprintf (buffer, "TYPE(%s)", ts->u.derived->name);
break;
diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c
index 32ee526aa22..6d3860ef826 100644
--- a/gcc/fortran/module.c
+++ b/gcc/fortran/module.c
@@ -422,8 +422,8 @@ resolve_fixups (fixup_t *f, void *gp)
to convert the symtree name of a derived-type to the symbol name or to
the name of the associated generic function. */
-static const char *
-dt_lower_string (const char *name)
+const char *
+gfc_dt_lower_string (const char *name)
{
if (name[0] != (char) TOLOWER ((unsigned char) name[0]))
return gfc_get_string ("%c%s", (char) TOLOWER ((unsigned char) name[0]),
@@ -437,8 +437,8 @@ dt_lower_string (const char *name)
symtree/symbol name of the associated generic function start with a lower-
case character. */
-static const char *
-dt_upper_string (const char *name)
+const char *
+gfc_dt_upper_string (const char *name)
{
if (name[0] != (char) TOUPPER ((unsigned char) name[0]))
return gfc_get_string ("%c%s", (char) TOUPPER ((unsigned char) name[0]),
@@ -832,7 +832,7 @@ find_use_name_n (const char *name, int *inst, bool interface)
/* For derived types. */
if (name[0] != (char) TOLOWER ((unsigned char) name[0]))
- low_name = dt_lower_string (name);
+ low_name = gfc_dt_lower_string (name);
i = 0;
for (u = gfc_rename_list; u; u = u->next)
@@ -861,7 +861,7 @@ find_use_name_n (const char *name, int *inst, bool interface)
{
if (u->local_name[0] == '\0')
return name;
- return dt_upper_string (u->local_name);
+ return gfc_dt_upper_string (u->local_name);
}
return (u->local_name[0] != '\0') ? u->local_name : name;
@@ -989,8 +989,8 @@ add_true_name (gfc_symbol *sym)
t = XCNEW (true_name);
t->sym = sym;
- if (sym->attr.flavor == FL_DERIVED)
- t->name = dt_upper_string (sym->name);
+ if (gfc_fl_struct (sym->attr.flavor))
+ t->name = gfc_dt_upper_string (sym->name);
else
t->name = sym->name;
@@ -1011,8 +1011,8 @@ build_tnt (gfc_symtree *st)
build_tnt (st->left);
build_tnt (st->right);
- if (st->n.sym->attr.flavor == FL_DERIVED)
- name = dt_upper_string (st->n.sym->name);
+ if (gfc_fl_struct (st->n.sym->attr.flavor))
+ name = gfc_dt_upper_string (st->n.sym->name);
else
name = st->n.sym->name;
@@ -2452,6 +2452,7 @@ static const mstring bt_types[] = {
minit ("COMPLEX", BT_COMPLEX),
minit ("LOGICAL", BT_LOGICAL),
minit ("CHARACTER", BT_CHARACTER),
+ minit ("UNION", BT_UNION),
minit ("DERIVED", BT_DERIVED),
minit ("CLASS", BT_CLASS),
minit ("PROCEDURE", BT_PROCEDURE),
@@ -2505,7 +2506,7 @@ mio_typespec (gfc_typespec *ts)
ts->type = MIO_NAME (bt) (ts->type, bt_types);
- if (ts->type != BT_DERIVED && ts->type != BT_CLASS)
+ if (!gfc_bt_struct (ts->type) && ts->type != BT_CLASS)
mio_integer (&ts->kind);
else
mio_symbol_ref (&ts->u.derived);
@@ -3322,8 +3323,8 @@ fix_mio_expr (gfc_expr *e)
if (e->symtree->n.sym && check_unique_name (e->symtree->name))
{
const char *name = e->symtree->n.sym->name;
- if (e->symtree->n.sym->attr.flavor == FL_DERIVED)
- name = dt_upper_string (name);
+ if (gfc_fl_struct (e->symtree->n.sym->attr.flavor))
+ name = gfc_dt_upper_string (name);
ns_st = gfc_find_symtree (gfc_current_ns->sym_root, name);
}
@@ -4265,7 +4266,7 @@ mio_symbol (gfc_symbol *sym)
mio_integer (&(sym->intmod_sym_id));
- if (sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (sym->attr.flavor))
mio_integer (&(sym->hash_value));
if (sym->formal_ns
@@ -4845,7 +4846,7 @@ load_needed (pointer_info *p)
1, &ns->proc_name);
sym = gfc_new_symbol (p->u.rsym.true_name, ns);
- sym->name = dt_lower_string (p->u.rsym.true_name);
+ sym->name = gfc_dt_lower_string (p->u.rsym.true_name);
sym->module = gfc_get_string (p->u.rsym.module);
if (p->u.rsym.binding_label)
sym->binding_label = IDENTIFIER_POINTER (get_identifier
@@ -4857,6 +4858,12 @@ load_needed (pointer_info *p)
mio_symbol (sym);
sym->attr.use_assoc = 1;
+ /* Unliked derived types, a STRUCTURE may share names with other symbols.
+ We greedily converted the the symbol name to lowercase before we knew its
+ type, so now we must fix it. */
+ if (sym->attr.flavor == FL_STRUCT)
+ sym->name = gfc_dt_upper_string (sym->name);
+
/* Mark as only or rename for later diagnosis for explicitly imported
but not used warnings; don't mark internal symbols such as __vtab,
__def_init etc. Only mark them if they have been explicitly loaded. */
@@ -5059,7 +5066,7 @@ read_module (void)
can be used in expressions in the module. To avoid the module loading
failing, we need to associate the module's component pointer indexes
with the existing symbol's component pointers. */
- if (sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (sym->attr.flavor))
{
gfc_component *c;
@@ -5213,7 +5220,7 @@ read_module (void)
{
info->u.rsym.sym = gfc_new_symbol (info->u.rsym.true_name,
gfc_current_ns);
- info->u.rsym.sym->name = dt_lower_string (info->u.rsym.true_name);
+ info->u.rsym.sym->name = gfc_dt_lower_string (info->u.rsym.true_name);
sym = info->u.rsym.sym;
sym->module = gfc_get_string (info->u.rsym.module);
@@ -5557,10 +5564,10 @@ write_symbol (int n, gfc_symbol *sym)
mio_integer (&n);
- if (sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (sym->attr.flavor))
{
const char *name;
- name = dt_upper_string (sym->name);
+ name = gfc_dt_upper_string (sym->name);
mio_pool_string (&name);
}
else
@@ -6568,7 +6575,7 @@ create_derived_type (const char *name, const char *modname,
sym->attr.function = 1;
sym->attr.generic = 1;
- gfc_get_sym_tree (dt_upper_string (sym->name),
+ gfc_get_sym_tree (gfc_dt_upper_string (sym->name),
gfc_current_ns, &tmp_symtree, false);
dt_sym = tmp_symtree->n.sym;
dt_sym->name = gfc_get_string (sym->name);
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 0dd1a921370..1481719f6e6 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -640,646 +640,711 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, uint64_t mask,
needs_space = false;
first = false;
gfc_gobble_whitespace ();
- if ((mask & OMP_CLAUSE_ASYNC) && !c->async)
- if (gfc_match ("async") == MATCH_YES)
- {
- c->async = true;
- needs_space = false;
- if (gfc_match (" ( %e )", &c->async_expr) != MATCH_YES)
- {
- c->async_expr = gfc_get_constant_expr (BT_INTEGER,
- gfc_default_integer_kind,
- &gfc_current_locus);
- mpz_set_si (c->async_expr->value.integer, GOMP_ASYNC_NOVAL);
- }
- continue;
- }
- if ((mask & OMP_CLAUSE_GANG) && !c->gang)
- if (gfc_match ("gang") == MATCH_YES)
- {
- c->gang = true;
- if (match_oacc_clause_gang(c) == MATCH_YES)
- needs_space = false;
- else
- needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_WORKER) && !c->worker)
- if (gfc_match ("worker") == MATCH_YES)
- {
- c->worker = true;
- if (gfc_match (" ( num : %e )", &c->worker_expr) == MATCH_YES
- || gfc_match (" ( %e )", &c->worker_expr) == MATCH_YES)
- needs_space = false;
- else
- needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_VECTOR_LENGTH) && c->vector_length_expr == NULL
- && gfc_match ("vector_length ( %e )", &c->vector_length_expr)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_VECTOR) && !c->vector)
- if (gfc_match ("vector") == MATCH_YES)
- {
- c->vector = true;
- if (gfc_match (" ( length : %e )", &c->vector_expr) == MATCH_YES
- || gfc_match (" ( %e )", &c->vector_expr) == MATCH_YES)
- needs_space = false;
- else
- needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_IF) && c->if_expr == NULL
- && gfc_match ("if ( %e )", &c->if_expr) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_FINAL) && c->final_expr == NULL
- && gfc_match ("final ( %e )", &c->final_expr) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_NUM_THREADS) && c->num_threads == NULL
- && gfc_match ("num_threads ( %e )", &c->num_threads) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_PRIVATE)
- && gfc_match_omp_variable_list ("private (",
- &c->lists[OMP_LIST_PRIVATE], true)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
- && gfc_match_omp_variable_list ("firstprivate (",
- &c->lists[OMP_LIST_FIRSTPRIVATE],
- true)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_LASTPRIVATE)
- && gfc_match_omp_variable_list ("lastprivate (",
- &c->lists[OMP_LIST_LASTPRIVATE],
- true)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_COPYPRIVATE)
- && gfc_match_omp_variable_list ("copyprivate (",
- &c->lists[OMP_LIST_COPYPRIVATE],
- true)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_SHARED)
- && gfc_match_omp_variable_list ("shared (",
- &c->lists[OMP_LIST_SHARED], true)
- == MATCH_YES)
- continue;
- if (mask & OMP_CLAUSE_COPYIN)
- {
- if (openacc)
- {
- if (gfc_match ("copyin ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FORCE_TO))
- continue;
- }
- else if (gfc_match_omp_variable_list ("copyin (",
- &c->lists[OMP_LIST_COPYIN],
- true) == MATCH_YES)
- continue;
- }
- if ((mask & OMP_CLAUSE_NUM_GANGS) && c->num_gangs_expr == NULL
- && gfc_match ("num_gangs ( %e )", &c->num_gangs_expr) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_NUM_WORKERS) && c->num_workers_expr == NULL
- && gfc_match ("num_workers ( %e )", &c->num_workers_expr)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_COPY)
- && gfc_match ("copy ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FORCE_TOFROM))
- continue;
- if ((mask & OMP_CLAUSE_COPYOUT)
- && gfc_match ("copyout ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FORCE_FROM))
- continue;
- if ((mask & OMP_CLAUSE_CREATE)
- && gfc_match ("create ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FORCE_ALLOC))
- continue;
- if ((mask & OMP_CLAUSE_DELETE)
- && gfc_match ("delete ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_DELETE))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT)
- && gfc_match ("present ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FORCE_PRESENT))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT_OR_COPY)
- && gfc_match ("present_or_copy ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_TOFROM))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT_OR_COPY)
- && gfc_match ("pcopy ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_TOFROM))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT_OR_COPYIN)
- && gfc_match ("present_or_copyin ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_TO))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT_OR_COPYIN)
- && gfc_match ("pcopyin ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_TO))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT_OR_COPYOUT)
- && gfc_match ("present_or_copyout ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FROM))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT_OR_COPYOUT)
- && gfc_match ("pcopyout ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FROM))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT_OR_CREATE)
- && gfc_match ("present_or_create ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_ALLOC))
- continue;
- if ((mask & OMP_CLAUSE_PRESENT_OR_CREATE)
- && gfc_match ("pcreate ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_ALLOC))
- continue;
- if ((mask & OMP_CLAUSE_DEVICEPTR)
- && gfc_match ("deviceptr ( ") == MATCH_YES)
+ bool end_colon;
+ gfc_omp_namelist **head;
+ old_loc = gfc_current_locus;
+ char pc = gfc_peek_ascii_char ();
+ switch (pc)
{
- gfc_omp_namelist **list = &c->lists[OMP_LIST_MAP];
- gfc_omp_namelist **head = NULL;
- if (gfc_match_omp_variable_list ("", list, true, NULL, &head, false)
- == MATCH_YES)
+ case 'a':
+ end_colon = false;
+ head = NULL;
+ if ((mask & OMP_CLAUSE_ALIGNED)
+ && gfc_match_omp_variable_list ("aligned (",
+ &c->lists[OMP_LIST_ALIGNED],
+ false, &end_colon,
+ &head) == MATCH_YES)
{
+ gfc_expr *alignment = NULL;
gfc_omp_namelist *n;
+
+ if (end_colon && gfc_match (" %e )", &alignment) != MATCH_YES)
+ {
+ gfc_free_omp_namelist (*head);
+ gfc_current_locus = old_loc;
+ *head = NULL;
+ break;
+ }
for (n = *head; n; n = n->next)
- n->u.map_op = OMP_MAP_FORCE_DEVICEPTR;
+ if (n->next && alignment)
+ n->expr = gfc_copy_expr (alignment);
+ else
+ n->expr = alignment;
continue;
}
- }
- if ((mask & OMP_CLAUSE_USE_DEVICE)
- && gfc_match_omp_variable_list ("use_device (",
- &c->lists[OMP_LIST_USE_DEVICE], true)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_DEVICE_RESIDENT)
- && gfc_match_omp_variable_list ("device_resident (",
- &c->lists[OMP_LIST_DEVICE_RESIDENT],
- true)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_LINK)
- && gfc_match_oacc_clause_link ("link (",
- &c->lists[OMP_LIST_LINK])
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_OACC_DEVICE)
- && gfc_match ("device ( ") == MATCH_YES
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FORCE_TO))
- continue;
- if ((mask & OMP_CLAUSE_HOST_SELF)
- && (gfc_match ("host ( ") == MATCH_YES
- || gfc_match ("self ( ") == MATCH_YES)
- && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
- OMP_MAP_FORCE_FROM))
- continue;
- if ((mask & OMP_CLAUSE_TILE)
- && !c->tile_list
- && match_oacc_expr_list ("tile (", &c->tile_list, true) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_SEQ) && !c->seq
- && gfc_match ("seq") == MATCH_YES)
- {
- c->seq = true;
- needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_INDEPENDENT) && !c->independent
- && gfc_match ("independent") == MATCH_YES)
- {
- c->independent = true;
- needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_AUTO) && !c->par_auto
- && gfc_match ("auto") == MATCH_YES)
- {
- c->par_auto = true;
- needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_WAIT) && !c->wait
- && gfc_match ("wait") == MATCH_YES)
- {
- c->wait = true;
- match_oacc_expr_list (" (", &c->wait_list, false);
- continue;
- }
- old_loc = gfc_current_locus;
- if ((mask & OMP_CLAUSE_REDUCTION)
- && gfc_match ("reduction ( ") == MATCH_YES)
- {
- gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
- char buffer[GFC_MAX_SYMBOL_LEN + 3];
- if (gfc_match_char ('+') == MATCH_YES)
- rop = OMP_REDUCTION_PLUS;
- else if (gfc_match_char ('*') == MATCH_YES)
- rop = OMP_REDUCTION_TIMES;
- else if (gfc_match_char ('-') == MATCH_YES)
- rop = OMP_REDUCTION_MINUS;
- else if (gfc_match (".and.") == MATCH_YES)
- rop = OMP_REDUCTION_AND;
- else if (gfc_match (".or.") == MATCH_YES)
- rop = OMP_REDUCTION_OR;
- else if (gfc_match (".eqv.") == MATCH_YES)
- rop = OMP_REDUCTION_EQV;
- else if (gfc_match (".neqv.") == MATCH_YES)
- rop = OMP_REDUCTION_NEQV;
- if (rop != OMP_REDUCTION_NONE)
- snprintf (buffer, sizeof buffer,
- "operator %s", gfc_op2string ((gfc_intrinsic_op) rop));
- else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
+ if ((mask & OMP_CLAUSE_ASYNC)
+ && !c->async
+ && gfc_match ("async") == MATCH_YES)
+ {
+ c->async = true;
+ needs_space = false;
+ if (gfc_match (" ( %e )", &c->async_expr) != MATCH_YES)
+ {
+ c->async_expr
+ = gfc_get_constant_expr (BT_INTEGER,
+ gfc_default_integer_kind,
+ &gfc_current_locus);
+ mpz_set_si (c->async_expr->value.integer, GOMP_ASYNC_NOVAL);
+ }
+ continue;
+ }
+ if ((mask & OMP_CLAUSE_AUTO)
+ && !c->par_auto
+ && gfc_match ("auto") == MATCH_YES)
{
- buffer[0] = '.';
- strcat (buffer, ".");
+ c->par_auto = true;
+ needs_space = true;
+ continue;
}
- else if (gfc_match_name (buffer) == MATCH_YES)
+ break;
+ case 'c':
+ if ((mask & OMP_CLAUSE_COLLAPSE)
+ && !c->collapse)
{
- gfc_symbol *sym;
- const char *n = buffer;
+ gfc_expr *cexpr = NULL;
+ match m = gfc_match ("collapse ( %e )", &cexpr);
- gfc_find_symbol (buffer, NULL, 1, &sym);
- if (sym != NULL)
+ if (m == MATCH_YES)
{
- if (sym->attr.intrinsic)
- n = sym->name;
- else if ((sym->attr.flavor != FL_UNKNOWN
- && sym->attr.flavor != FL_PROCEDURE)
- || sym->attr.external
- || sym->attr.generic
- || sym->attr.entry
- || sym->attr.result
- || sym->attr.dummy
- || sym->attr.subroutine
- || sym->attr.pointer
- || sym->attr.target
- || sym->attr.cray_pointer
- || sym->attr.cray_pointee
- || (sym->attr.proc != PROC_UNKNOWN
- && sym->attr.proc != PROC_INTRINSIC)
- || sym->attr.if_source != IFSRC_UNKNOWN
- || sym == sym->ns->proc_name)
+ int collapse;
+ const char *p = gfc_extract_int (cexpr, &collapse);
+ if (p)
{
- sym = NULL;
- n = NULL;
+ gfc_error_now (p);
+ collapse = 1;
}
- else
- n = sym->name;
+ else if (collapse <= 0)
+ {
+ gfc_error_now ("COLLAPSE clause argument not"
+ " constant positive integer at %C");
+ collapse = 1;
+ }
+ c->collapse = collapse;
+ gfc_free_expr (cexpr);
+ continue;
}
- if (n == NULL)
- rop = OMP_REDUCTION_NONE;
- else if (strcmp (n, "max") == 0)
- rop = OMP_REDUCTION_MAX;
- else if (strcmp (n, "min") == 0)
- rop = OMP_REDUCTION_MIN;
- else if (strcmp (n, "iand") == 0)
- rop = OMP_REDUCTION_IAND;
- else if (strcmp (n, "ior") == 0)
- rop = OMP_REDUCTION_IOR;
- else if (strcmp (n, "ieor") == 0)
- rop = OMP_REDUCTION_IEOR;
- if (rop != OMP_REDUCTION_NONE
- && sym != NULL
- && ! sym->attr.intrinsic
- && ! sym->attr.use_assoc
- && ((sym->attr.flavor == FL_UNKNOWN
- && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
- sym->name, NULL))
- || !gfc_add_intrinsic (&sym->attr, NULL)))
- rop = OMP_REDUCTION_NONE;
}
- else
- buffer[0] = '\0';
- gfc_omp_udr *udr
- = (buffer[0]
- ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL);
- gfc_omp_namelist **head = NULL;
- if (rop == OMP_REDUCTION_NONE && udr)
- rop = OMP_REDUCTION_USER;
-
- if (gfc_match_omp_variable_list (" :",
- &c->lists[OMP_LIST_REDUCTION],
- false, NULL, &head, openacc)
- == MATCH_YES)
+ if ((mask & OMP_CLAUSE_COPY)
+ && gfc_match ("copy ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FORCE_TOFROM))
+ continue;
+ if (mask & OMP_CLAUSE_COPYIN)
{
- gfc_omp_namelist *n;
- if (rop == OMP_REDUCTION_NONE)
+ if (openacc)
{
- n = *head;
- *head = NULL;
- gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
- "at %L", buffer, &old_loc);
- gfc_free_omp_namelist (n);
+ if (gfc_match ("copyin ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FORCE_TO))
+ continue;
+ }
+ else if (gfc_match_omp_variable_list ("copyin (",
+ &c->lists[OMP_LIST_COPYIN],
+ true) == MATCH_YES)
+ continue;
+ }
+ if ((mask & OMP_CLAUSE_COPYOUT)
+ && gfc_match ("copyout ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FORCE_FROM))
+ continue;
+ if ((mask & OMP_CLAUSE_COPYPRIVATE)
+ && gfc_match_omp_variable_list ("copyprivate (",
+ &c->lists[OMP_LIST_COPYPRIVATE],
+ true) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_CREATE)
+ && gfc_match ("create ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FORCE_ALLOC))
+ continue;
+ break;
+ case 'd':
+ if ((mask & OMP_CLAUSE_DELETE)
+ && gfc_match ("delete ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_DELETE))
+ continue;
+ if ((mask & OMP_CLAUSE_DEFAULT)
+ && c->default_sharing == OMP_DEFAULT_UNKNOWN)
+ {
+ if (gfc_match ("default ( none )") == MATCH_YES)
+ c->default_sharing = OMP_DEFAULT_NONE;
+ else if (openacc)
+ /* c->default_sharing = OMP_DEFAULT_UNKNOWN */;
+ else if (gfc_match ("default ( shared )") == MATCH_YES)
+ c->default_sharing = OMP_DEFAULT_SHARED;
+ else if (gfc_match ("default ( private )") == MATCH_YES)
+ c->default_sharing = OMP_DEFAULT_PRIVATE;
+ else if (gfc_match ("default ( firstprivate )") == MATCH_YES)
+ c->default_sharing = OMP_DEFAULT_FIRSTPRIVATE;
+ if (c->default_sharing != OMP_DEFAULT_UNKNOWN)
+ continue;
+ }
+ if ((mask & OMP_CLAUSE_DEPEND)
+ && gfc_match ("depend ( ") == MATCH_YES)
+ {
+ match m = MATCH_YES;
+ gfc_omp_depend_op depend_op = OMP_DEPEND_OUT;
+ if (gfc_match ("inout") == MATCH_YES)
+ depend_op = OMP_DEPEND_INOUT;
+ else if (gfc_match ("in") == MATCH_YES)
+ depend_op = OMP_DEPEND_IN;
+ else if (gfc_match ("out") == MATCH_YES)
+ depend_op = OMP_DEPEND_OUT;
+ else
+ m = MATCH_NO;
+ head = NULL;
+ if (m == MATCH_YES
+ && gfc_match_omp_variable_list (" : ",
+ &c->lists[OMP_LIST_DEPEND],
+ false, NULL, &head,
+ true) == MATCH_YES)
+ {
+ gfc_omp_namelist *n;
+ for (n = *head; n; n = n->next)
+ n->u.depend_op = depend_op;
+ continue;
}
else
- for (n = *head; n; n = n->next)
- {
- n->u.reduction_op = rop;
- if (udr)
- {
- n->udr = gfc_get_omp_namelist_udr ();
- n->udr->udr = udr;
- }
- }
- continue;
+ gfc_current_locus = old_loc;
}
- else
- gfc_current_locus = old_loc;
- }
- if ((mask & OMP_CLAUSE_DEFAULT)
- && c->default_sharing == OMP_DEFAULT_UNKNOWN)
- {
- if (gfc_match ("default ( none )") == MATCH_YES)
- c->default_sharing = OMP_DEFAULT_NONE;
- else if (openacc)
- /* c->default_sharing = OMP_DEFAULT_UNKNOWN */;
- else if (gfc_match ("default ( shared )") == MATCH_YES)
- c->default_sharing = OMP_DEFAULT_SHARED;
- else if (gfc_match ("default ( private )") == MATCH_YES)
- c->default_sharing = OMP_DEFAULT_PRIVATE;
- else if (gfc_match ("default ( firstprivate )") == MATCH_YES)
- c->default_sharing = OMP_DEFAULT_FIRSTPRIVATE;
- if (c->default_sharing != OMP_DEFAULT_UNKNOWN)
+ if ((mask & OMP_CLAUSE_DEVICE)
+ && c->device == NULL
+ && gfc_match ("device ( %e )", &c->device) == MATCH_YES)
continue;
- }
- old_loc = gfc_current_locus;
- if ((mask & OMP_CLAUSE_SCHEDULE)
- && c->sched_kind == OMP_SCHED_NONE
- && gfc_match ("schedule ( ") == MATCH_YES)
- {
- if (gfc_match ("static") == MATCH_YES)
- c->sched_kind = OMP_SCHED_STATIC;
- else if (gfc_match ("dynamic") == MATCH_YES)
- c->sched_kind = OMP_SCHED_DYNAMIC;
- else if (gfc_match ("guided") == MATCH_YES)
- c->sched_kind = OMP_SCHED_GUIDED;
- else if (gfc_match ("runtime") == MATCH_YES)
- c->sched_kind = OMP_SCHED_RUNTIME;
- else if (gfc_match ("auto") == MATCH_YES)
- c->sched_kind = OMP_SCHED_AUTO;
- if (c->sched_kind != OMP_SCHED_NONE)
+ if ((mask & OMP_CLAUSE_OACC_DEVICE)
+ && gfc_match ("device ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FORCE_TO))
+ continue;
+ if ((mask & OMP_CLAUSE_DEVICEPTR)
+ && gfc_match ("deviceptr ( ") == MATCH_YES)
+ {
+ gfc_omp_namelist **list = &c->lists[OMP_LIST_MAP];
+ gfc_omp_namelist **head = NULL;
+ if (gfc_match_omp_variable_list ("", list, true, NULL,
+ &head, false) == MATCH_YES)
+ {
+ gfc_omp_namelist *n;
+ for (n = *head; n; n = n->next)
+ n->u.map_op = OMP_MAP_FORCE_DEVICEPTR;
+ continue;
+ }
+ }
+ if ((mask & OMP_CLAUSE_DEVICE_RESIDENT)
+ && gfc_match_omp_variable_list
+ ("device_resident (",
+ &c->lists[OMP_LIST_DEVICE_RESIDENT], true) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_DIST_SCHEDULE)
+ && c->dist_sched_kind == OMP_SCHED_NONE
+ && gfc_match ("dist_schedule ( static") == MATCH_YES)
{
match m = MATCH_NO;
- if (c->sched_kind != OMP_SCHED_RUNTIME
- && c->sched_kind != OMP_SCHED_AUTO)
- m = gfc_match (" , %e )", &c->chunk_size);
+ c->dist_sched_kind = OMP_SCHED_STATIC;
+ m = gfc_match (" , %e )", &c->dist_chunk_size);
if (m != MATCH_YES)
m = gfc_match_char (')');
if (m != MATCH_YES)
- c->sched_kind = OMP_SCHED_NONE;
+ {
+ c->dist_sched_kind = OMP_SCHED_NONE;
+ gfc_current_locus = old_loc;
+ }
+ else
+ continue;
}
- if (c->sched_kind != OMP_SCHED_NONE)
+ break;
+ case 'f':
+ if ((mask & OMP_CLAUSE_FINAL)
+ && c->final_expr == NULL
+ && gfc_match ("final ( %e )", &c->final_expr) == MATCH_YES)
continue;
- else
- gfc_current_locus = old_loc;
- }
- if ((mask & OMP_CLAUSE_ORDERED) && !c->ordered
- && gfc_match ("ordered") == MATCH_YES)
- {
- c->ordered = needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_UNTIED) && !c->untied
- && gfc_match ("untied") == MATCH_YES)
- {
- c->untied = needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_MERGEABLE) && !c->mergeable
- && gfc_match ("mergeable") == MATCH_YES)
- {
- c->mergeable = needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_COLLAPSE) && !c->collapse)
- {
- gfc_expr *cexpr = NULL;
- match m = gfc_match ("collapse ( %e )", &cexpr);
-
- if (m == MATCH_YES)
+ if ((mask & OMP_CLAUSE_FIRSTPRIVATE)
+ && gfc_match_omp_variable_list ("firstprivate (",
+ &c->lists[OMP_LIST_FIRSTPRIVATE],
+ true) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_FROM)
+ && gfc_match_omp_variable_list ("from (",
+ &c->lists[OMP_LIST_FROM], false,
+ NULL, &head, true) == MATCH_YES)
+ continue;
+ break;
+ case 'g':
+ if ((mask & OMP_CLAUSE_GANG)
+ && !c->gang
+ && gfc_match ("gang") == MATCH_YES)
+ {
+ c->gang = true;
+ if (match_oacc_clause_gang(c) == MATCH_YES)
+ needs_space = false;
+ else
+ needs_space = true;
+ continue;
+ }
+ break;
+ case 'h':
+ if ((mask & OMP_CLAUSE_HOST_SELF)
+ && gfc_match ("host ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FORCE_FROM))
+ continue;
+ break;
+ case 'i':
+ if ((mask & OMP_CLAUSE_IF)
+ && c->if_expr == NULL
+ && gfc_match ("if ( %e )", &c->if_expr) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_INBRANCH)
+ && !c->inbranch
+ && !c->notinbranch
+ && gfc_match ("inbranch") == MATCH_YES)
+ {
+ c->inbranch = needs_space = true;
+ continue;
+ }
+ if ((mask & OMP_CLAUSE_INDEPENDENT)
+ && !c->independent
+ && gfc_match ("independent") == MATCH_YES)
+ {
+ c->independent = true;
+ needs_space = true;
+ continue;
+ }
+ break;
+ case 'l':
+ if ((mask & OMP_CLAUSE_LASTPRIVATE)
+ && gfc_match_omp_variable_list ("lastprivate (",
+ &c->lists[OMP_LIST_LASTPRIVATE],
+ true) == MATCH_YES)
+ continue;
+ end_colon = false;
+ head = NULL;
+ if ((mask & OMP_CLAUSE_LINEAR)
+ && gfc_match_omp_variable_list ("linear (",
+ &c->lists[OMP_LIST_LINEAR],
+ false, &end_colon,
+ &head) == MATCH_YES)
{
- int collapse;
- const char *p = gfc_extract_int (cexpr, &collapse);
- if (p)
+ gfc_expr *step = NULL;
+
+ if (end_colon && gfc_match (" %e )", &step) != MATCH_YES)
{
- gfc_error_now (p);
- collapse = 1;
+ gfc_free_omp_namelist (*head);
+ gfc_current_locus = old_loc;
+ *head = NULL;
+ break;
}
- else if (collapse <= 0)
+ else if (!end_colon)
{
- gfc_error_now ("COLLAPSE clause argument not"
- " constant positive integer at %C");
- collapse = 1;
+ step = gfc_get_constant_expr (BT_INTEGER,
+ gfc_default_integer_kind,
+ &old_loc);
+ mpz_set_si (step->value.integer, 1);
}
- c->collapse = collapse;
- gfc_free_expr (cexpr);
+ (*head)->expr = step;
continue;
}
- }
- if ((mask & OMP_CLAUSE_INBRANCH) && !c->inbranch && !c->notinbranch
- && gfc_match ("inbranch") == MATCH_YES)
- {
- c->inbranch = needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_NOTINBRANCH) && !c->notinbranch && !c->inbranch
- && gfc_match ("notinbranch") == MATCH_YES)
- {
- c->notinbranch = needs_space = true;
- continue;
- }
- if ((mask & OMP_CLAUSE_PROC_BIND)
- && c->proc_bind == OMP_PROC_BIND_UNKNOWN)
- {
- if (gfc_match ("proc_bind ( master )") == MATCH_YES)
- c->proc_bind = OMP_PROC_BIND_MASTER;
- else if (gfc_match ("proc_bind ( spread )") == MATCH_YES)
- c->proc_bind = OMP_PROC_BIND_SPREAD;
- else if (gfc_match ("proc_bind ( close )") == MATCH_YES)
- c->proc_bind = OMP_PROC_BIND_CLOSE;
- if (c->proc_bind != OMP_PROC_BIND_UNKNOWN)
+ if ((mask & OMP_CLAUSE_LINK)
+ && (gfc_match_oacc_clause_link ("link (",
+ &c->lists[OMP_LIST_LINK])
+ == MATCH_YES))
continue;
- }
- if ((mask & OMP_CLAUSE_SAFELEN) && c->safelen_expr == NULL
- && gfc_match ("safelen ( %e )", &c->safelen_expr) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_SIMDLEN) && c->simdlen_expr == NULL
- && gfc_match ("simdlen ( %e )", &c->simdlen_expr) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_UNIFORM)
- && gfc_match_omp_variable_list ("uniform (",
- &c->lists[OMP_LIST_UNIFORM], false)
- == MATCH_YES)
- continue;
- bool end_colon = false;
- gfc_omp_namelist **head = NULL;
- old_loc = gfc_current_locus;
- if ((mask & OMP_CLAUSE_ALIGNED)
- && gfc_match_omp_variable_list ("aligned (",
- &c->lists[OMP_LIST_ALIGNED], false,
- &end_colon, &head)
- == MATCH_YES)
- {
- gfc_expr *alignment = NULL;
- gfc_omp_namelist *n;
-
- if (end_colon
- && gfc_match (" %e )", &alignment) != MATCH_YES)
+ break;
+ case 'm':
+ if ((mask & OMP_CLAUSE_MAP)
+ && gfc_match ("map ( ") == MATCH_YES)
{
- gfc_free_omp_namelist (*head);
- gfc_current_locus = old_loc;
- *head = NULL;
- break;
+ gfc_omp_map_op map_op = OMP_MAP_TOFROM;
+ if (gfc_match ("alloc : ") == MATCH_YES)
+ map_op = OMP_MAP_ALLOC;
+ else if (gfc_match ("tofrom : ") == MATCH_YES)
+ map_op = OMP_MAP_TOFROM;
+ else if (gfc_match ("to : ") == MATCH_YES)
+ map_op = OMP_MAP_TO;
+ else if (gfc_match ("from : ") == MATCH_YES)
+ map_op = OMP_MAP_FROM;
+ head = NULL;
+ if (gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_MAP],
+ false, NULL, &head,
+ true) == MATCH_YES)
+ {
+ gfc_omp_namelist *n;
+ for (n = *head; n; n = n->next)
+ n->u.map_op = map_op;
+ continue;
+ }
+ else
+ gfc_current_locus = old_loc;
}
- for (n = *head; n; n = n->next)
- if (n->next && alignment)
- n->expr = gfc_copy_expr (alignment);
- else
- n->expr = alignment;
- continue;
- }
- end_colon = false;
- head = NULL;
- old_loc = gfc_current_locus;
- if ((mask & OMP_CLAUSE_LINEAR)
- && gfc_match_omp_variable_list ("linear (",
- &c->lists[OMP_LIST_LINEAR], false,
- &end_colon, &head)
- == MATCH_YES)
- {
- gfc_expr *step = NULL;
+ if ((mask & OMP_CLAUSE_MERGEABLE) && !c->mergeable
+ && gfc_match ("mergeable") == MATCH_YES)
+ {
+ c->mergeable = needs_space = true;
+ continue;
+ }
+ break;
+ case 'n':
+ if ((mask & OMP_CLAUSE_NOTINBRANCH)
+ && !c->notinbranch
+ && !c->inbranch
+ && gfc_match ("notinbranch") == MATCH_YES)
+ {
+ c->notinbranch = needs_space = true;
+ continue;
+ }
+ if ((mask & OMP_CLAUSE_NUM_GANGS)
+ && c->num_gangs_expr == NULL
+ && gfc_match ("num_gangs ( %e )",
+ &c->num_gangs_expr) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_NUM_TEAMS)
+ && c->num_teams == NULL
+ && gfc_match ("num_teams ( %e )", &c->num_teams) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_NUM_THREADS)
+ && c->num_threads == NULL
+ && (gfc_match ("num_threads ( %e )", &c->num_threads)
+ == MATCH_YES))
+ continue;
+ if ((mask & OMP_CLAUSE_NUM_WORKERS)
+ && c->num_workers_expr == NULL
+ && gfc_match ("num_workers ( %e )",
+ &c->num_workers_expr) == MATCH_YES)
+ continue;
+ break;
+ case 'o':
+ if ((mask & OMP_CLAUSE_ORDERED)
+ && !c->ordered
+ && gfc_match ("ordered") == MATCH_YES)
+ {
+ c->ordered = needs_space = true;
+ continue;
+ }
+ break;
+ case 'p':
+ if ((mask & OMP_CLAUSE_PRESENT_OR_COPY)
+ && gfc_match ("pcopy ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_TOFROM))
+ continue;
+ if ((mask & OMP_CLAUSE_PRESENT_OR_COPYIN)
+ && gfc_match ("pcopyin ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_TO))
+ continue;
+ if ((mask & OMP_CLAUSE_PRESENT_OR_COPYOUT)
+ && gfc_match ("pcopyout ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FROM))
+ continue;
+ if ((mask & OMP_CLAUSE_PRESENT_OR_CREATE)
+ && gfc_match ("pcreate ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_ALLOC))
+ continue;
+ if ((mask & OMP_CLAUSE_PRESENT)
+ && gfc_match ("present ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FORCE_PRESENT))
+ continue;
+ if ((mask & OMP_CLAUSE_PRESENT_OR_COPY)
+ && gfc_match ("present_or_copy ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_TOFROM))
+ continue;
+ if ((mask & OMP_CLAUSE_PRESENT_OR_COPYIN)
+ && gfc_match ("present_or_copyin ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_TO))
+ continue;
+ if ((mask & OMP_CLAUSE_PRESENT_OR_COPYOUT)
+ && gfc_match ("present_or_copyout ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FROM))
+ continue;
+ if ((mask & OMP_CLAUSE_PRESENT_OR_CREATE)
+ && gfc_match ("present_or_create ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_ALLOC))
+ continue;
+ if ((mask & OMP_CLAUSE_PRIVATE)
+ && gfc_match_omp_variable_list ("private (",
+ &c->lists[OMP_LIST_PRIVATE],
+ true) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_PROC_BIND)
+ && c->proc_bind == OMP_PROC_BIND_UNKNOWN)
+ {
+ if (gfc_match ("proc_bind ( master )") == MATCH_YES)
+ c->proc_bind = OMP_PROC_BIND_MASTER;
+ else if (gfc_match ("proc_bind ( spread )") == MATCH_YES)
+ c->proc_bind = OMP_PROC_BIND_SPREAD;
+ else if (gfc_match ("proc_bind ( close )") == MATCH_YES)
+ c->proc_bind = OMP_PROC_BIND_CLOSE;
+ if (c->proc_bind != OMP_PROC_BIND_UNKNOWN)
+ continue;
+ }
+ break;
+ case 'r':
+ if ((mask & OMP_CLAUSE_REDUCTION)
+ && gfc_match ("reduction ( ") == MATCH_YES)
+ {
+ gfc_omp_reduction_op rop = OMP_REDUCTION_NONE;
+ char buffer[GFC_MAX_SYMBOL_LEN + 3];
+ if (gfc_match_char ('+') == MATCH_YES)
+ rop = OMP_REDUCTION_PLUS;
+ else if (gfc_match_char ('*') == MATCH_YES)
+ rop = OMP_REDUCTION_TIMES;
+ else if (gfc_match_char ('-') == MATCH_YES)
+ rop = OMP_REDUCTION_MINUS;
+ else if (gfc_match (".and.") == MATCH_YES)
+ rop = OMP_REDUCTION_AND;
+ else if (gfc_match (".or.") == MATCH_YES)
+ rop = OMP_REDUCTION_OR;
+ else if (gfc_match (".eqv.") == MATCH_YES)
+ rop = OMP_REDUCTION_EQV;
+ else if (gfc_match (".neqv.") == MATCH_YES)
+ rop = OMP_REDUCTION_NEQV;
+ if (rop != OMP_REDUCTION_NONE)
+ snprintf (buffer, sizeof buffer, "operator %s",
+ gfc_op2string ((gfc_intrinsic_op) rop));
+ else if (gfc_match_defined_op_name (buffer + 1, 1) == MATCH_YES)
+ {
+ buffer[0] = '.';
+ strcat (buffer, ".");
+ }
+ else if (gfc_match_name (buffer) == MATCH_YES)
+ {
+ gfc_symbol *sym;
+ const char *n = buffer;
- if (end_colon
- && gfc_match (" %e )", &step) != MATCH_YES)
+ gfc_find_symbol (buffer, NULL, 1, &sym);
+ if (sym != NULL)
+ {
+ if (sym->attr.intrinsic)
+ n = sym->name;
+ else if ((sym->attr.flavor != FL_UNKNOWN
+ && sym->attr.flavor != FL_PROCEDURE)
+ || sym->attr.external
+ || sym->attr.generic
+ || sym->attr.entry
+ || sym->attr.result
+ || sym->attr.dummy
+ || sym->attr.subroutine
+ || sym->attr.pointer
+ || sym->attr.target
+ || sym->attr.cray_pointer
+ || sym->attr.cray_pointee
+ || (sym->attr.proc != PROC_UNKNOWN
+ && sym->attr.proc != PROC_INTRINSIC)
+ || sym->attr.if_source != IFSRC_UNKNOWN
+ || sym == sym->ns->proc_name)
+ {
+ sym = NULL;
+ n = NULL;
+ }
+ else
+ n = sym->name;
+ }
+ if (n == NULL)
+ rop = OMP_REDUCTION_NONE;
+ else if (strcmp (n, "max") == 0)
+ rop = OMP_REDUCTION_MAX;
+ else if (strcmp (n, "min") == 0)
+ rop = OMP_REDUCTION_MIN;
+ else if (strcmp (n, "iand") == 0)
+ rop = OMP_REDUCTION_IAND;
+ else if (strcmp (n, "ior") == 0)
+ rop = OMP_REDUCTION_IOR;
+ else if (strcmp (n, "ieor") == 0)
+ rop = OMP_REDUCTION_IEOR;
+ if (rop != OMP_REDUCTION_NONE
+ && sym != NULL
+ && ! sym->attr.intrinsic
+ && ! sym->attr.use_assoc
+ && ((sym->attr.flavor == FL_UNKNOWN
+ && !gfc_add_flavor (&sym->attr, FL_PROCEDURE,
+ sym->name, NULL))
+ || !gfc_add_intrinsic (&sym->attr, NULL)))
+ rop = OMP_REDUCTION_NONE;
+ }
+ else
+ buffer[0] = '\0';
+ gfc_omp_udr *udr
+ = (buffer[0]
+ ? gfc_find_omp_udr (gfc_current_ns, buffer, NULL) : NULL);
+ gfc_omp_namelist **head = NULL;
+ if (rop == OMP_REDUCTION_NONE && udr)
+ rop = OMP_REDUCTION_USER;
+
+ if (gfc_match_omp_variable_list (" :",
+ &c->lists[OMP_LIST_REDUCTION],
+ false, NULL, &head,
+ openacc) == MATCH_YES)
+ {
+ gfc_omp_namelist *n;
+ if (rop == OMP_REDUCTION_NONE)
+ {
+ n = *head;
+ *head = NULL;
+ gfc_error_now ("!$OMP DECLARE REDUCTION %s not found "
+ "at %L", buffer, &old_loc);
+ gfc_free_omp_namelist (n);
+ }
+ else
+ for (n = *head; n; n = n->next)
+ {
+ n->u.reduction_op = rop;
+ if (udr)
+ {
+ n->udr = gfc_get_omp_namelist_udr ();
+ n->udr->udr = udr;
+ }
+ }
+ continue;
+ }
+ else
+ gfc_current_locus = old_loc;
+ }
+ break;
+ case 's':
+ if ((mask & OMP_CLAUSE_SAFELEN)
+ && c->safelen_expr == NULL
+ && gfc_match ("safelen ( %e )", &c->safelen_expr) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_SCHEDULE)
+ && c->sched_kind == OMP_SCHED_NONE
+ && gfc_match ("schedule ( ") == MATCH_YES)
{
- gfc_free_omp_namelist (*head);
- gfc_current_locus = old_loc;
- *head = NULL;
- break;
+ if (gfc_match ("static") == MATCH_YES)
+ c->sched_kind = OMP_SCHED_STATIC;
+ else if (gfc_match ("dynamic") == MATCH_YES)
+ c->sched_kind = OMP_SCHED_DYNAMIC;
+ else if (gfc_match ("guided") == MATCH_YES)
+ c->sched_kind = OMP_SCHED_GUIDED;
+ else if (gfc_match ("runtime") == MATCH_YES)
+ c->sched_kind = OMP_SCHED_RUNTIME;
+ else if (gfc_match ("auto") == MATCH_YES)
+ c->sched_kind = OMP_SCHED_AUTO;
+ if (c->sched_kind != OMP_SCHED_NONE)
+ {
+ match m = MATCH_NO;
+ if (c->sched_kind != OMP_SCHED_RUNTIME
+ && c->sched_kind != OMP_SCHED_AUTO)
+ m = gfc_match (" , %e )", &c->chunk_size);
+ if (m != MATCH_YES)
+ m = gfc_match_char (')');
+ if (m != MATCH_YES)
+ c->sched_kind = OMP_SCHED_NONE;
+ }
+ if (c->sched_kind != OMP_SCHED_NONE)
+ continue;
+ else
+ gfc_current_locus = old_loc;
}
- else if (!end_colon)
+ if ((mask & OMP_CLAUSE_HOST_SELF)
+ && gfc_match ("self ( ") == MATCH_YES
+ && gfc_match_omp_map_clause (&c->lists[OMP_LIST_MAP],
+ OMP_MAP_FORCE_FROM))
+ continue;
+ if ((mask & OMP_CLAUSE_SEQ)
+ && !c->seq
+ && gfc_match ("seq") == MATCH_YES)
{
- step = gfc_get_constant_expr (BT_INTEGER,
- gfc_default_integer_kind,
- &old_loc);
- mpz_set_si (step->value.integer, 1);
+ c->seq = true;
+ needs_space = true;
+ continue;
}
- (*head)->expr = step;
- continue;
- }
- if ((mask & OMP_CLAUSE_DEPEND)
- && gfc_match ("depend ( ") == MATCH_YES)
- {
- match m = MATCH_YES;
- gfc_omp_depend_op depend_op = OMP_DEPEND_OUT;
- if (gfc_match ("inout") == MATCH_YES)
- depend_op = OMP_DEPEND_INOUT;
- else if (gfc_match ("in") == MATCH_YES)
- depend_op = OMP_DEPEND_IN;
- else if (gfc_match ("out") == MATCH_YES)
- depend_op = OMP_DEPEND_OUT;
- else
- m = MATCH_NO;
- head = NULL;
- if (m == MATCH_YES
- && gfc_match_omp_variable_list (" : ",
- &c->lists[OMP_LIST_DEPEND],
- false, NULL, &head, true)
- == MATCH_YES)
+ if ((mask & OMP_CLAUSE_SHARED)
+ && gfc_match_omp_variable_list ("shared (",
+ &c->lists[OMP_LIST_SHARED],
+ true) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_SIMDLEN)
+ && c->simdlen_expr == NULL
+ && gfc_match ("simdlen ( %e )", &c->simdlen_expr) == MATCH_YES)
+ continue;
+ break;
+ case 't':
+ if ((mask & OMP_CLAUSE_THREAD_LIMIT)
+ && c->thread_limit == NULL
+ && gfc_match ("thread_limit ( %e )",
+ &c->thread_limit) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_TILE)
+ && !c->tile_list
+ && match_oacc_expr_list ("tile (", &c->tile_list,
+ true) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_TO)
+ && gfc_match_omp_variable_list ("to (",
+ &c->lists[OMP_LIST_TO], false,
+ NULL, &head, true) == MATCH_YES)
+ continue;
+ break;
+ case 'u':
+ if ((mask & OMP_CLAUSE_UNIFORM)
+ && gfc_match_omp_variable_list ("uniform (",
+ &c->lists[OMP_LIST_UNIFORM],
+ false) == MATCH_YES)
+ continue;
+ if ((mask & OMP_CLAUSE_UNTIED)
+ && !c->untied
+ && gfc_match ("untied") == MATCH_YES)
{
- gfc_omp_namelist *n;
- for (n = *head; n; n = n->next)
- n->u.depend_op = depend_op;
+ c->untied = needs_space = true;
continue;
}
- else
- gfc_current_locus = old_loc;
- }
- if ((mask & OMP_CLAUSE_DIST_SCHEDULE)
- && c->dist_sched_kind == OMP_SCHED_NONE
- && gfc_match ("dist_schedule ( static") == MATCH_YES)
- {
- match m = MATCH_NO;
- c->dist_sched_kind = OMP_SCHED_STATIC;
- m = gfc_match (" , %e )", &c->dist_chunk_size);
- if (m != MATCH_YES)
- m = gfc_match_char (')');
- if (m != MATCH_YES)
+ if ((mask & OMP_CLAUSE_USE_DEVICE)
+ && gfc_match_omp_variable_list ("use_device (",
+ &c->lists[OMP_LIST_USE_DEVICE],
+ true) == MATCH_YES)
+ continue;
+ break;
+ case 'v':
+ if ((mask & OMP_CLAUSE_VECTOR)
+ && !c->vector
+ && gfc_match ("vector") == MATCH_YES)
{
- c->dist_sched_kind = OMP_SCHED_NONE;
- gfc_current_locus = old_loc;
+ c->vector = true;
+ if (gfc_match (" ( length : %e )", &c->vector_expr) == MATCH_YES
+ || gfc_match (" ( %e )", &c->vector_expr) == MATCH_YES)
+ needs_space = false;
+ else
+ needs_space = true;
+ continue;
}
- else
+ if ((mask & OMP_CLAUSE_VECTOR_LENGTH)
+ && c->vector_length_expr == NULL
+ && (gfc_match ("vector_length ( %e )", &c->vector_length_expr)
+ == MATCH_YES))
continue;
- }
- if ((mask & OMP_CLAUSE_NUM_TEAMS) && c->num_teams == NULL
- && gfc_match ("num_teams ( %e )", &c->num_teams) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_DEVICE) && c->device == NULL
- && gfc_match ("device ( %e )", &c->device) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_THREAD_LIMIT) && c->thread_limit == NULL
- && gfc_match ("thread_limit ( %e )", &c->thread_limit) == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_MAP)
- && gfc_match ("map ( ") == MATCH_YES)
- {
- gfc_omp_map_op map_op = OMP_MAP_TOFROM;
- if (gfc_match ("alloc : ") == MATCH_YES)
- map_op = OMP_MAP_ALLOC;
- else if (gfc_match ("tofrom : ") == MATCH_YES)
- map_op = OMP_MAP_TOFROM;
- else if (gfc_match ("to : ") == MATCH_YES)
- map_op = OMP_MAP_TO;
- else if (gfc_match ("from : ") == MATCH_YES)
- map_op = OMP_MAP_FROM;
- head = NULL;
- if (gfc_match_omp_variable_list ("", &c->lists[OMP_LIST_MAP],
- false, NULL, &head, true)
- == MATCH_YES)
+ break;
+ case 'w':
+ if ((mask & OMP_CLAUSE_WAIT)
+ && !c->wait
+ && gfc_match ("wait") == MATCH_YES)
{
- gfc_omp_namelist *n;
- for (n = *head; n; n = n->next)
- n->u.map_op = map_op;
+ c->wait = true;
+ match_oacc_expr_list (" (", &c->wait_list, false);
continue;
}
- else
- gfc_current_locus = old_loc;
+ if ((mask & OMP_CLAUSE_WORKER)
+ && !c->worker
+ && gfc_match ("worker") == MATCH_YES)
+ {
+ c->worker = true;
+ if (gfc_match (" ( num : %e )", &c->worker_expr) == MATCH_YES
+ || gfc_match (" ( %e )", &c->worker_expr) == MATCH_YES)
+ needs_space = false;
+ else
+ needs_space = true;
+ continue;
+ }
+ break;
}
- if ((mask & OMP_CLAUSE_TO)
- && gfc_match_omp_variable_list ("to (",
- &c->lists[OMP_LIST_TO], false,
- NULL, &head, true)
- == MATCH_YES)
- continue;
- if ((mask & OMP_CLAUSE_FROM)
- && gfc_match_omp_variable_list ("from (",
- &c->lists[OMP_LIST_FROM], false,
- NULL, &head, true)
- == MATCH_YES)
- continue;
-
break;
}
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 0fcda1d4840..5a91ec1b209 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -47,6 +47,15 @@ set_default_std_flags (void)
}
+/* Set all the DEC extension flags. */
+
+static void
+set_dec_flags (int value)
+{
+ gfc_option.flag_dec_structure = value;
+}
+
+
/* Return language mask for Fortran options. */
unsigned int
@@ -102,6 +111,8 @@ gfc_init_options (unsigned int decoded_options_count,
if (!global_options_set.x_cpp_warn_missing_include_dirs)
global_options.x_cpp_warn_missing_include_dirs = 1;
+ set_dec_flags (0);
+
set_default_std_flags ();
/* Initialize cpp-related options. */
@@ -709,6 +720,15 @@ gfc_handle_option (size_t scode, const char *arg, int value,
case OPT_fcheck_:
gfc_handle_runtime_check_option (arg);
break;
+
+ case OPT_fdec:
+ /* Enable all DEC extensions. */
+ set_dec_flags (1);
+ break;
+
+ case OPT_fdec_structure:
+ gfc_option.flag_dec_structure = 1;
+ break;
}
Fortran_handle_option_auto (&global_options, &global_options_set,
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 7bce47fef0a..dd7aa6a4e13 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -256,6 +256,7 @@ decode_specification_statement (void)
case 's':
match ("save", gfc_match_save, ST_ATTR_DECL);
+ match ("structure", gfc_match_structure_decl, ST_STRUCTURE_DECL);
break;
case 't':
@@ -507,6 +508,7 @@ decode_statement (void)
break;
case 'm':
+ match ("map", gfc_match_map, ST_MAP);
match ("module% procedure", gfc_match_modproc, ST_MODULE_PROC);
match ("module", gfc_match_module, ST_MODULE);
break;
@@ -542,6 +544,7 @@ decode_statement (void)
break;
case 's':
+ match ("structure", gfc_match_structure_decl, ST_STRUCTURE_DECL);
match ("sequence", gfc_match_eos, ST_SEQUENCE);
match ("stop", gfc_match_stop, ST_STOP);
match ("save", gfc_match_save, ST_ATTR_DECL);
@@ -558,6 +561,7 @@ decode_statement (void)
break;
case 'u':
+ match ("union", gfc_match_union, ST_UNION);
match ("unlock", gfc_match_unlock, ST_UNLOCK);
break;
@@ -1642,6 +1646,15 @@ gfc_ascii_statement (gfc_statement st)
case ST_DEALLOCATE:
p = "DEALLOCATE";
break;
+ case ST_MAP:
+ p = "MAP";
+ break;
+ case ST_UNION:
+ p = "UNION";
+ break;
+ case ST_STRUCTURE_DECL:
+ p = "STRUCTURE";
+ break;
case ST_DERIVED_DECL:
p = _("derived type declaration");
break;
@@ -1711,6 +1724,15 @@ gfc_ascii_statement (gfc_statement st)
case ST_END_WHERE:
p = "END WHERE";
break;
+ case ST_END_STRUCTURE:
+ p = "END STRUCTURE";
+ break;
+ case ST_END_UNION:
+ p = "END UNION";
+ break;
+ case ST_END_MAP:
+ p = "END MAP";
+ break;
case ST_END_TYPE:
p = "END TYPE";
break;
@@ -2457,6 +2479,7 @@ verify_st_order (st_state *p, gfc_statement st, bool silent)
case ST_PUBLIC:
case ST_PRIVATE:
+ case ST_STRUCTURE_DECL:
case ST_DERIVED_DECL:
case_decl:
if (p->state >= ORDER_EXEC)
@@ -2646,6 +2669,358 @@ error:
}
+/* Set attributes for the parent symbol based on the attributes of a component
+ and raise errors if conflicting attributes are found for the component. */
+
+static void
+check_component (gfc_symbol *sym, gfc_component *c, gfc_component **lockp,
+ gfc_component **eventp)
+{
+ bool coarray, lock_type, event_type, allocatable, pointer;
+ coarray = lock_type = event_type = allocatable = pointer = false;
+ gfc_component *lock_comp = NULL, *event_comp = NULL;
+
+ if (lockp) lock_comp = *lockp;
+ if (eventp) event_comp = *eventp;
+
+ /* Look for allocatable components. */
+ if (c->attr.allocatable
+ || (c->ts.type == BT_CLASS && c->attr.class_ok
+ && CLASS_DATA (c)->attr.allocatable)
+ || (c->ts.type == BT_DERIVED && !c->attr.pointer
+ && c->ts.u.derived->attr.alloc_comp))
+ {
+ allocatable = true;
+ sym->attr.alloc_comp = 1;
+ }
+
+ /* Look for pointer components. */
+ if (c->attr.pointer
+ || (c->ts.type == BT_CLASS && c->attr.class_ok
+ && CLASS_DATA (c)->attr.class_pointer)
+ || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.pointer_comp))
+ {
+ pointer = true;
+ sym->attr.pointer_comp = 1;
+ }
+
+ /* Look for procedure pointer components. */
+ if (c->attr.proc_pointer
+ || (c->ts.type == BT_DERIVED
+ && c->ts.u.derived->attr.proc_pointer_comp))
+ sym->attr.proc_pointer_comp = 1;
+
+ /* Looking for coarray components. */
+ if (c->attr.codimension
+ || (c->ts.type == BT_CLASS && c->attr.class_ok
+ && CLASS_DATA (c)->attr.codimension))
+ {
+ coarray = true;
+ sym->attr.coarray_comp = 1;
+ }
+
+ if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.coarray_comp
+ && !c->attr.pointer)
+ {
+ coarray = true;
+ sym->attr.coarray_comp = 1;
+ }
+
+ /* Looking for lock_type components. */
+ if ((c->ts.type == BT_DERIVED
+ && c->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
+ && c->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
+ || (c->ts.type == BT_CLASS && c->attr.class_ok
+ && CLASS_DATA (c)->ts.u.derived->from_intmod
+ == INTMOD_ISO_FORTRAN_ENV
+ && CLASS_DATA (c)->ts.u.derived->intmod_sym_id
+ == ISOFORTRAN_LOCK_TYPE)
+ || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.lock_comp
+ && !allocatable && !pointer))
+ {
+ lock_type = 1;
+ lock_comp = c;
+ sym->attr.lock_comp = 1;
+ }
+
+ /* Looking for event_type components. */
+ if ((c->ts.type == BT_DERIVED
+ && c->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
+ && c->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
+ || (c->ts.type == BT_CLASS && c->attr.class_ok
+ && CLASS_DATA (c)->ts.u.derived->from_intmod
+ == INTMOD_ISO_FORTRAN_ENV
+ && CLASS_DATA (c)->ts.u.derived->intmod_sym_id
+ == ISOFORTRAN_EVENT_TYPE)
+ || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.event_comp
+ && !allocatable && !pointer))
+ {
+ event_type = 1;
+ event_comp = c;
+ sym->attr.event_comp = 1;
+ }
+
+ /* Check for F2008, C1302 - and recall that pointers may not be coarrays
+ (5.3.14) and that subobjects of coarray are coarray themselves (2.4.7),
+ unless there are nondirect [allocatable or pointer] components
+ involved (cf. 1.3.33.1 and 1.3.33.3). */
+
+ if (pointer && !coarray && lock_type)
+ gfc_error ("Component %s at %L of type LOCK_TYPE must have a "
+ "codimension or be a subcomponent of a coarray, "
+ "which is not possible as the component has the "
+ "pointer attribute", c->name, &c->loc);
+ else if (pointer && !coarray && c->ts.type == BT_DERIVED
+ && c->ts.u.derived->attr.lock_comp)
+ gfc_error ("Pointer component %s at %L has a noncoarray subcomponent "
+ "of type LOCK_TYPE, which must have a codimension or be a "
+ "subcomponent of a coarray", c->name, &c->loc);
+
+ if (lock_type && allocatable && !coarray)
+ gfc_error ("Allocatable component %s at %L of type LOCK_TYPE must have "
+ "a codimension", c->name, &c->loc);
+ else if (lock_type && allocatable && c->ts.type == BT_DERIVED
+ && c->ts.u.derived->attr.lock_comp)
+ gfc_error ("Allocatable component %s at %L must have a codimension as "
+ "it has a noncoarray subcomponent of type LOCK_TYPE",
+ c->name, &c->loc);
+
+ if (sym->attr.coarray_comp && !coarray && lock_type)
+ gfc_error ("Noncoarray component %s at %L of type LOCK_TYPE or with "
+ "subcomponent of type LOCK_TYPE must have a codimension or "
+ "be a subcomponent of a coarray. (Variables of type %s may "
+ "not have a codimension as already a coarray "
+ "subcomponent exists)", c->name, &c->loc, sym->name);
+
+ if (sym->attr.lock_comp && coarray && !lock_type)
+ gfc_error ("Noncoarray component %s at %L of type LOCK_TYPE or with "
+ "subcomponent of type LOCK_TYPE must have a codimension or "
+ "be a subcomponent of a coarray. (Variables of type %s may "
+ "not have a codimension as %s at %L has a codimension or a "
+ "coarray subcomponent)", lock_comp->name, &lock_comp->loc,
+ sym->name, c->name, &c->loc);
+
+ /* Similarly for EVENT TYPE. */
+
+ if (pointer && !coarray && event_type)
+ gfc_error ("Component %s at %L of type EVENT_TYPE must have a "
+ "codimension or be a subcomponent of a coarray, "
+ "which is not possible as the component has the "
+ "pointer attribute", c->name, &c->loc);
+ else if (pointer && !coarray && c->ts.type == BT_DERIVED
+ && c->ts.u.derived->attr.event_comp)
+ gfc_error ("Pointer component %s at %L has a noncoarray subcomponent "
+ "of type EVENT_TYPE, which must have a codimension or be a "
+ "subcomponent of a coarray", c->name, &c->loc);
+
+ if (event_type && allocatable && !coarray)
+ gfc_error ("Allocatable component %s at %L of type EVENT_TYPE must have "
+ "a codimension", c->name, &c->loc);
+ else if (event_type && allocatable && c->ts.type == BT_DERIVED
+ && c->ts.u.derived->attr.event_comp)
+ gfc_error ("Allocatable component %s at %L must have a codimension as "
+ "it has a noncoarray subcomponent of type EVENT_TYPE",
+ c->name, &c->loc);
+
+ if (sym->attr.coarray_comp && !coarray && event_type)
+ gfc_error ("Noncoarray component %s at %L of type EVENT_TYPE or with "
+ "subcomponent of type EVENT_TYPE must have a codimension or "
+ "be a subcomponent of a coarray. (Variables of type %s may "
+ "not have a codimension as already a coarray "
+ "subcomponent exists)", c->name, &c->loc, sym->name);
+
+ if (sym->attr.event_comp && coarray && !event_type)
+ gfc_error ("Noncoarray component %s at %L of type EVENT_TYPE or with "
+ "subcomponent of type EVENT_TYPE must have a codimension or "
+ "be a subcomponent of a coarray. (Variables of type %s may "
+ "not have a codimension as %s at %L has a codimension or a "
+ "coarray subcomponent)", event_comp->name, &event_comp->loc,
+ sym->name, c->name, &c->loc);
+
+ /* Look for private components. */
+ if (sym->component_access == ACCESS_PRIVATE
+ || c->attr.access == ACCESS_PRIVATE
+ || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.private_comp))
+ sym->attr.private_comp = 1;
+
+ if (lockp) *lockp = lock_comp;
+ if (eventp) *eventp = event_comp;
+}
+
+
+static void parse_struct_map (gfc_statement);
+
+/* Parse a union component definition within a structure definition. */
+
+static void
+parse_union (void)
+{
+ int compiling;
+ gfc_statement st;
+ gfc_state_data s;
+ gfc_component *c, *lock_comp = NULL, *event_comp = NULL;
+ gfc_symbol *un;
+
+ accept_statement(ST_UNION);
+ push_state (&s, COMP_UNION, gfc_new_block);
+ un = gfc_new_block;
+
+ compiling = 1;
+
+ while (compiling)
+ {
+ st = next_statement ();
+ /* Only MAP declarations valid within a union. */
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ case ST_MAP:
+ accept_statement (ST_MAP);
+ parse_struct_map (ST_MAP);
+ /* Add a component to the union for each map. */
+ if (!gfc_add_component (un, gfc_new_block->name, &c))
+ {
+ gfc_internal_error ("failed to create map component '%s'",
+ gfc_new_block->name);
+ reject_statement ();
+ return;
+ }
+ c->ts.type = BT_DERIVED;
+ c->ts.u.derived = gfc_new_block;
+ /* Normally components get their initialization expressions when they
+ are created in decl.c (build_struct) so we can look through the
+ flat component list for initializers during resolution. Unions and
+ maps create components along with their type definitions so we
+ have to generate initializers here. */
+ c->initializer = gfc_default_initializer (&c->ts);
+ break;
+
+ case ST_END_UNION:
+ compiling = 0;
+ accept_statement (ST_END_UNION);
+ break;
+
+ default:
+ unexpected_statement (st);
+ break;
+ }
+ }
+
+ for (c = un->components; c; c = c->next)
+ check_component (un, c, &lock_comp, &event_comp);
+
+ /* Add the union as a component in its parent structure. */
+ pop_state ();
+ if (!gfc_add_component (gfc_current_block (), un->name, &c))
+ {
+ gfc_internal_error ("failed to create union component '%s'", un->name);
+ reject_statement ();
+ return;
+ }
+ c->ts.type = BT_UNION;
+ c->ts.u.derived = un;
+ c->initializer = gfc_default_initializer (&c->ts);
+
+ un->attr.zero_comp = un->components == NULL;
+}
+
+
+/* Parse a STRUCTURE or MAP. */
+
+static void
+parse_struct_map (gfc_statement block)
+{
+ int compiling_type;
+ gfc_statement st;
+ gfc_state_data s;
+ gfc_symbol *sym;
+ gfc_component *c, *lock_comp = NULL, *event_comp = NULL;
+ gfc_compile_state comp;
+ gfc_statement ends;
+
+ if (block == ST_STRUCTURE_DECL)
+ {
+ comp = COMP_STRUCTURE;
+ ends = ST_END_STRUCTURE;
+ }
+ else
+ {
+ gcc_assert (block == ST_MAP);
+ comp = COMP_MAP;
+ ends = ST_END_MAP;
+ }
+
+ accept_statement(block);
+ push_state (&s, comp, gfc_new_block);
+
+ gfc_new_block->component_access = ACCESS_PUBLIC;
+ compiling_type = 1;
+
+ while (compiling_type)
+ {
+ st = next_statement ();
+ switch (st)
+ {
+ case ST_NONE:
+ unexpected_eof ();
+
+ /* Nested structure declarations will be captured as ST_DATA_DECL. */
+ case ST_STRUCTURE_DECL:
+ /* Let a more specific error make it to decode_statement(). */
+ if (gfc_error_check () == 0)
+ gfc_error ("Syntax error in nested structure declaration at %C");
+ reject_statement ();
+ /* Skip the rest of this statement. */
+ gfc_error_recovery ();
+ break;
+
+ case ST_UNION:
+ accept_statement (ST_UNION);
+ parse_union ();
+ break;
+
+ case ST_DATA_DECL:
+ /* The data declaration was a nested/ad-hoc STRUCTURE field. */
+ accept_statement (ST_DATA_DECL);
+ if (gfc_new_block && gfc_new_block != gfc_current_block ()
+ && gfc_new_block->attr.flavor == FL_STRUCT)
+ parse_struct_map (ST_STRUCTURE_DECL);
+ break;
+
+ case ST_END_STRUCTURE:
+ case ST_END_MAP:
+ if (st == ends)
+ {
+ accept_statement (st);
+ compiling_type = 0;
+ }
+ else
+ unexpected_statement (st);
+ break;
+
+ default:
+ unexpected_statement (st);
+ break;
+ }
+ }
+
+ /* Validate each component. */
+ sym = gfc_current_block ();
+ for (c = sym->components; c; c = c->next)
+ check_component (sym, c, &lock_comp, &event_comp);
+
+ sym->attr.zero_comp = (sym->components == NULL);
+
+ /* Allow parse_union to find this structure to add to its list of maps. */
+ if (block == ST_MAP)
+ gfc_new_block = gfc_current_block ();
+
+ pop_state ();
+}
+
+
/* Parse a derived type. */
static void
@@ -2762,170 +3137,7 @@ endType:
*/
sym = gfc_current_block ();
for (c = sym->components; c; c = c->next)
- {
- bool coarray, lock_type, event_type, allocatable, pointer;
- coarray = lock_type = event_type = allocatable = pointer = false;
-
- /* Look for allocatable components. */
- if (c->attr.allocatable
- || (c->ts.type == BT_CLASS && c->attr.class_ok
- && CLASS_DATA (c)->attr.allocatable)
- || (c->ts.type == BT_DERIVED && !c->attr.pointer
- && c->ts.u.derived->attr.alloc_comp))
- {
- allocatable = true;
- sym->attr.alloc_comp = 1;
- }
-
- /* Look for pointer components. */
- if (c->attr.pointer
- || (c->ts.type == BT_CLASS && c->attr.class_ok
- && CLASS_DATA (c)->attr.class_pointer)
- || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.pointer_comp))
- {
- pointer = true;
- sym->attr.pointer_comp = 1;
- }
-
- /* Look for procedure pointer components. */
- if (c->attr.proc_pointer
- || (c->ts.type == BT_DERIVED
- && c->ts.u.derived->attr.proc_pointer_comp))
- sym->attr.proc_pointer_comp = 1;
-
- /* Looking for coarray components. */
- if (c->attr.codimension
- || (c->ts.type == BT_CLASS && c->attr.class_ok
- && CLASS_DATA (c)->attr.codimension))
- {
- coarray = true;
- sym->attr.coarray_comp = 1;
- }
-
- if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.coarray_comp
- && !c->attr.pointer)
- {
- coarray = true;
- sym->attr.coarray_comp = 1;
- }
-
- /* Looking for lock_type components. */
- if ((c->ts.type == BT_DERIVED
- && c->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
- && c->ts.u.derived->intmod_sym_id == ISOFORTRAN_LOCK_TYPE)
- || (c->ts.type == BT_CLASS && c->attr.class_ok
- && CLASS_DATA (c)->ts.u.derived->from_intmod
- == INTMOD_ISO_FORTRAN_ENV
- && CLASS_DATA (c)->ts.u.derived->intmod_sym_id
- == ISOFORTRAN_LOCK_TYPE)
- || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.lock_comp
- && !allocatable && !pointer))
- {
- lock_type = 1;
- lock_comp = c;
- sym->attr.lock_comp = 1;
- }
-
- /* Looking for event_type components. */
- if ((c->ts.type == BT_DERIVED
- && c->ts.u.derived->from_intmod == INTMOD_ISO_FORTRAN_ENV
- && c->ts.u.derived->intmod_sym_id == ISOFORTRAN_EVENT_TYPE)
- || (c->ts.type == BT_CLASS && c->attr.class_ok
- && CLASS_DATA (c)->ts.u.derived->from_intmod
- == INTMOD_ISO_FORTRAN_ENV
- && CLASS_DATA (c)->ts.u.derived->intmod_sym_id
- == ISOFORTRAN_EVENT_TYPE)
- || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.event_comp
- && !allocatable && !pointer))
- {
- event_type = 1;
- event_comp = c;
- sym->attr.event_comp = 1;
- }
-
- /* Check for F2008, C1302 - and recall that pointers may not be coarrays
- (5.3.14) and that subobjects of coarray are coarray themselves (2.4.7),
- unless there are nondirect [allocatable or pointer] components
- involved (cf. 1.3.33.1 and 1.3.33.3). */
-
- if (pointer && !coarray && lock_type)
- gfc_error ("Component %s at %L of type LOCK_TYPE must have a "
- "codimension or be a subcomponent of a coarray, "
- "which is not possible as the component has the "
- "pointer attribute", c->name, &c->loc);
- else if (pointer && !coarray && c->ts.type == BT_DERIVED
- && c->ts.u.derived->attr.lock_comp)
- gfc_error ("Pointer component %s at %L has a noncoarray subcomponent "
- "of type LOCK_TYPE, which must have a codimension or be a "
- "subcomponent of a coarray", c->name, &c->loc);
-
- if (lock_type && allocatable && !coarray)
- gfc_error ("Allocatable component %s at %L of type LOCK_TYPE must have "
- "a codimension", c->name, &c->loc);
- else if (lock_type && allocatable && c->ts.type == BT_DERIVED
- && c->ts.u.derived->attr.lock_comp)
- gfc_error ("Allocatable component %s at %L must have a codimension as "
- "it has a noncoarray subcomponent of type LOCK_TYPE",
- c->name, &c->loc);
-
- if (sym->attr.coarray_comp && !coarray && lock_type)
- gfc_error ("Noncoarray component %s at %L of type LOCK_TYPE or with "
- "subcomponent of type LOCK_TYPE must have a codimension or "
- "be a subcomponent of a coarray. (Variables of type %s may "
- "not have a codimension as already a coarray "
- "subcomponent exists)", c->name, &c->loc, sym->name);
-
- if (sym->attr.lock_comp && coarray && !lock_type)
- gfc_error ("Noncoarray component %s at %L of type LOCK_TYPE or with "
- "subcomponent of type LOCK_TYPE must have a codimension or "
- "be a subcomponent of a coarray. (Variables of type %s may "
- "not have a codimension as %s at %L has a codimension or a "
- "coarray subcomponent)", lock_comp->name, &lock_comp->loc,
- sym->name, c->name, &c->loc);
-
- /* Similarly for EVENT TYPE. */
-
- if (pointer && !coarray && event_type)
- gfc_error ("Component %s at %L of type EVENT_TYPE must have a "
- "codimension or be a subcomponent of a coarray, "
- "which is not possible as the component has the "
- "pointer attribute", c->name, &c->loc);
- else if (pointer && !coarray && c->ts.type == BT_DERIVED
- && c->ts.u.derived->attr.event_comp)
- gfc_error ("Pointer component %s at %L has a noncoarray subcomponent "
- "of type EVENT_TYPE, which must have a codimension or be a "
- "subcomponent of a coarray", c->name, &c->loc);
-
- if (event_type && allocatable && !coarray)
- gfc_error ("Allocatable component %s at %L of type EVENT_TYPE must have "
- "a codimension", c->name, &c->loc);
- else if (event_type && allocatable && c->ts.type == BT_DERIVED
- && c->ts.u.derived->attr.event_comp)
- gfc_error ("Allocatable component %s at %L must have a codimension as "
- "it has a noncoarray subcomponent of type EVENT_TYPE",
- c->name, &c->loc);
-
- if (sym->attr.coarray_comp && !coarray && event_type)
- gfc_error ("Noncoarray component %s at %L of type EVENT_TYPE or with "
- "subcomponent of type EVENT_TYPE must have a codimension or "
- "be a subcomponent of a coarray. (Variables of type %s may "
- "not have a codimension as already a coarray "
- "subcomponent exists)", c->name, &c->loc, sym->name);
-
- if (sym->attr.event_comp && coarray && !event_type)
- gfc_error ("Noncoarray component %s at %L of type EVENT_TYPE or with "
- "subcomponent of type EVENT_TYPE must have a codimension or "
- "be a subcomponent of a coarray. (Variables of type %s may "
- "not have a codimension as %s at %L has a codimension or a "
- "coarray subcomponent)", event_comp->name, &event_comp->loc,
- sym->name, c->name, &c->loc);
-
- /* Look for private components. */
- if (sym->component_access == ACCESS_PRIVATE
- || c->attr.access == ACCESS_PRIVATE
- || (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.private_comp))
- sym->attr.private_comp = 1;
- }
+ check_component (sym, c, &lock_comp, &event_comp);
if (!seen_component)
sym->attr.zero_comp = 1;
@@ -3348,6 +3560,7 @@ loop:
case ST_PARAMETER:
case ST_PUBLIC:
case ST_PRIVATE:
+ case ST_STRUCTURE_DECL:
case ST_DERIVED_DECL:
case_decl:
declSt:
@@ -3364,6 +3577,10 @@ declSt:
parse_interface ();
break;
+ case ST_STRUCTURE_DECL:
+ parse_struct_map (ST_STRUCTURE_DECL);
+ break;
+
case ST_DERIVED_DECL:
parse_derived ();
break;
diff --git a/gcc/fortran/parse.h b/gcc/fortran/parse.h
index f12fd5e5d2b..e8f71cf3035 100644
--- a/gcc/fortran/parse.h
+++ b/gcc/fortran/parse.h
@@ -28,6 +28,7 @@ enum gfc_compile_state
COMP_NONE, COMP_PROGRAM, COMP_MODULE, COMP_SUBMODULE, COMP_SUBROUTINE,
COMP_FUNCTION, COMP_BLOCK_DATA, COMP_INTERFACE, COMP_DERIVED,
COMP_DERIVED_CONTAINS, COMP_BLOCK, COMP_ASSOCIATE, COMP_IF,
+ COMP_STRUCTURE, COMP_UNION, COMP_MAP,
COMP_DO, COMP_SELECT, COMP_FORALL, COMP_WHERE, COMP_CONTAINS, COMP_ENUM,
COMP_SELECT_TYPE, COMP_OMP_STRUCTURED_BLOCK, COMP_CRITICAL, COMP_DO_CONCURRENT
};
@@ -58,6 +59,8 @@ extern gfc_state_data *gfc_state_stack;
#define gfc_current_block() (gfc_state_stack->sym)
#define gfc_current_state() (gfc_state_stack->state)
+#define gfc_comp_struct(s) \
+ ((s) == COMP_DERIVED || (s) == COMP_STRUCTURE || (s) == COMP_MAP)
int gfc_check_do_variable (gfc_symtree *);
bool gfc_find_state (gfc_compile_state);
diff --git a/gcc/fortran/primary.c b/gcc/fortran/primary.c
index d25d3de66b0..c2faa0f3e10 100644
--- a/gcc/fortran/primary.c
+++ b/gcc/fortran/primary.c
@@ -1883,11 +1883,12 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
bool ppc_arg)
{
char name[GFC_MAX_SYMBOL_LEN + 1];
- gfc_ref *substring, *tail;
+ gfc_ref *substring, *tail, *tmp;
gfc_component *component;
gfc_symbol *sym = primary->symtree->n.sym;
match m;
bool unknown;
+ char sep;
tail = NULL;
@@ -1972,25 +1973,31 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
if (equiv_flag)
return MATCH_YES;
- if (sym->ts.type == BT_UNKNOWN && gfc_peek_ascii_char () == '%'
+ /* With DEC extensions, member separator may be '.' or '%'. */
+ sep = gfc_peek_ascii_char ();
+ m = gfc_match_member_sep (sym);
+ if (m == MATCH_ERROR)
+ return MATCH_ERROR;
+
+ if (sym->ts.type == BT_UNKNOWN && m == MATCH_YES
&& gfc_get_default_type (sym->name, sym->ns)->type == BT_DERIVED)
gfc_set_default_type (sym, 0, sym->ns);
- if (sym->ts.type == BT_UNKNOWN && gfc_match_char ('%') == MATCH_YES)
+ if (sym->ts.type == BT_UNKNOWN && m == MATCH_YES)
{
gfc_error ("Symbol %qs at %C has no IMPLICIT type", sym->name);
return MATCH_ERROR;
}
else if ((sym->ts.type != BT_DERIVED && sym->ts.type != BT_CLASS)
- && gfc_match_char ('%') == MATCH_YES)
+ && m == MATCH_YES)
{
- gfc_error ("Unexpected %<%%%> for nonderived-type variable %qs at %C",
- sym->name);
+ gfc_error ("Unexpected %<%c%> for nonderived-type variable %qs at %C",
+ sep, sym->name);
return MATCH_ERROR;
}
if ((sym->ts.type != BT_DERIVED && sym->ts.type != BT_CLASS)
- || gfc_match_char ('%') != MATCH_YES)
+ || m != MATCH_YES)
goto check_substring;
sym = sym->ts.u.derived;
@@ -2061,15 +2068,24 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
break;
}
- component = gfc_find_component (sym, name, false, false);
+ component = gfc_find_component (sym, name, false, false, &tmp);
if (component == NULL)
return MATCH_ERROR;
- tail = extend_ref (primary, tail);
- tail->type = REF_COMPONENT;
+ /* Extend the reference chain determined by gfc_find_component. */
+ if (primary->ref == NULL)
+ primary->ref = tmp;
+ else
+ {
+ /* Set by the for loop below for the last component ref. */
+ gcc_assert (tail != NULL);
+ tail->next = tmp;
+ }
- tail->u.c.component = component;
- tail->u.c.sym = sym;
+ /* The reference chain may be longer than one hop for union
+ subcomponents; find the new tail. */
+ for (tail = tmp; tail->next; tail = tail->next)
+ ;
primary->ts = component->ts;
@@ -2119,7 +2135,7 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
}
if ((component->ts.type != BT_DERIVED && component->ts.type != BT_CLASS)
- || gfc_match_char ('%') != MATCH_YES)
+ || gfc_match_member_sep (component->ts.u.derived) != MATCH_YES)
break;
sym = component->ts.u.derived;
@@ -2127,7 +2143,7 @@ gfc_match_varspec (gfc_expr *primary, int equiv_flag, bool sub_flag,
check_substring:
unknown = false;
- if (primary->ts.type == BT_UNKNOWN && sym->attr.flavor != FL_DERIVED)
+ if (primary->ts.type == BT_UNKNOWN && !gfc_fl_struct (sym->attr.flavor))
{
if (gfc_get_default_type (sym->name, sym->ns)->type == BT_CHARACTER)
{
@@ -2548,11 +2564,11 @@ gfc_convert_to_structure_constructor (gfc_expr *e, gfc_symbol *sym, gfc_expr **c
/* Find the current component in the structure definition and check
its access is not private. */
if (comp)
- this_comp = gfc_find_component (sym, comp->name, false, false);
+ this_comp = gfc_find_component (sym, comp->name, false, false, NULL);
else
{
this_comp = gfc_find_component (sym, (const char *)comp_tail->name,
- false, false);
+ false, false, NULL);
comp = NULL; /* Reset needed! */
}
@@ -2596,7 +2612,7 @@ gfc_convert_to_structure_constructor (gfc_expr *e, gfc_symbol *sym, gfc_expr **c
if (comp && comp == sym->components
&& sym->attr.extension
&& comp_tail->val
- && (comp_tail->val->ts.type != BT_DERIVED
+ && (!gfc_bt_struct (comp_tail->val->ts.type)
||
comp_tail->val->ts.u.derived != this_comp->ts.u.derived))
{
@@ -2697,7 +2713,7 @@ gfc_match_structure_constructor (gfc_symbol *sym, gfc_expr **result)
e->symtree = symtree;
e->expr_type = EXPR_FUNCTION;
- gcc_assert (sym->attr.flavor == FL_DERIVED
+ gcc_assert (gfc_fl_struct (sym->attr.flavor)
&& symtree->n.sym->attr.flavor == FL_PROCEDURE);
e->value.function.esym = sym;
e->symtree->n.sym->attr.generic = 1;
@@ -2795,15 +2811,29 @@ gfc_match_rvalue (gfc_expr **result)
if (m != MATCH_YES)
return m;
- if (gfc_find_state (COMP_INTERFACE)
- && !gfc_current_ns->has_import_set)
- i = gfc_get_sym_tree (name, NULL, &symtree, false);
- else
- i = gfc_get_ha_sym_tree (name, &symtree);
-
- if (i)
+ /* Check if the symbol exists. */
+ if (gfc_find_sym_tree (name, NULL, 1, &symtree))
return MATCH_ERROR;
+ /* If the symbol doesn't exist, create it unless the name matches a FL_STRUCT
+ type. For derived types we create a generic symbol which links to the
+ derived type symbol; STRUCTUREs are simpler and must not conflict with
+ variables. */
+ if (!symtree)
+ if (gfc_find_sym_tree (gfc_dt_upper_string (name), NULL, 1, &symtree))
+ return MATCH_ERROR;
+ if (!symtree || symtree->n.sym->attr.flavor != FL_STRUCT)
+ {
+ if (gfc_find_state (COMP_INTERFACE)
+ && !gfc_current_ns->has_import_set)
+ i = gfc_get_sym_tree (name, NULL, &symtree, false);
+ else
+ i = gfc_get_ha_sym_tree (name, &symtree);
+ if (i)
+ return MATCH_ERROR;
+ }
+
+
sym = symtree->n.sym;
e = NULL;
where = gfc_current_locus;
@@ -2914,6 +2944,7 @@ gfc_match_rvalue (gfc_expr **result)
break;
+ case FL_STRUCT:
case FL_DERIVED:
sym = gfc_use_derived (sym);
if (sym == NULL)
@@ -3054,10 +3085,12 @@ gfc_match_rvalue (gfc_expr **result)
via an IMPLICIT statement. This can't wait for the
resolution phase. */
- if (gfc_peek_ascii_char () == '%'
+ old_loc = gfc_current_locus;
+ if (gfc_match_member_sep (sym) == MATCH_YES
&& sym->ts.type == BT_UNKNOWN
&& gfc_get_default_type (sym->name, sym->ns)->type == BT_DERIVED)
gfc_set_default_type (sym, 0, sym->ns);
+ gfc_current_locus = old_loc;
/* If the symbol has a (co)dimension attribute, the expression is a
variable. */
@@ -3210,13 +3243,19 @@ gfc_match_rvalue (gfc_expr **result)
break;
generic_function:
- gfc_get_sym_tree (name, NULL, &symtree, false); /* Can't fail */
+ /* Look for symbol first; if not found, look for STRUCTURE type symbol
+ specially. Creates a generic symbol for derived types. */
+ gfc_find_sym_tree (name, NULL, 1, &symtree);
+ if (!symtree)
+ gfc_find_sym_tree (gfc_dt_upper_string (name), NULL, 1, &symtree);
+ if (!symtree || symtree->n.sym->attr.flavor != FL_STRUCT)
+ gfc_get_sym_tree (name, NULL, &symtree, false); /* Can't fail */
e = gfc_get_expr ();
e->symtree = symtree;
e->expr_type = EXPR_FUNCTION;
- if (sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (sym->attr.flavor))
{
e->value.function.esym = sym;
e->symtree->n.sym->attr.generic = 1;
@@ -3260,10 +3299,10 @@ gfc_match_rvalue (gfc_expr **result)
static match
match_variable (gfc_expr **result, int equiv_flag, int host_flag)
{
- gfc_symbol *sym;
+ gfc_symbol *sym, *dt_sym;
gfc_symtree *st;
gfc_expr *expr;
- locus where;
+ locus where, old_loc;
match m;
/* Since nothing has any business being an lvalue in a module
@@ -3294,6 +3333,17 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag)
sym->attr.implied_index = 0;
gfc_set_sym_referenced (sym);
+
+ /* STRUCTUREs may share names with variables, but derived types may not. */
+ if (sym->attr.flavor == FL_PROCEDURE && sym->generic
+ && (dt_sym = gfc_find_dt_in_generic (sym)))
+ {
+ if (dt_sym->attr.flavor == FL_DERIVED)
+ gfc_error ("Derived type '%s' cannot be used as a variable at %C",
+ sym->name);
+ return MATCH_ERROR;
+ }
+
switch (sym->attr.flavor)
{
case FL_VARIABLE:
@@ -3379,11 +3429,13 @@ match_variable (gfc_expr **result, int equiv_flag, int host_flag)
implicit_ns = gfc_current_ns;
else
implicit_ns = sym->ns;
-
- if (gfc_peek_ascii_char () == '%'
+
+ old_loc = gfc_current_locus;
+ if (gfc_match_member_sep (sym) == MATCH_YES
&& sym->ts.type == BT_UNKNOWN
&& gfc_get_default_type (sym->name, implicit_ns)->type == BT_DERIVED)
gfc_set_default_type (sym, 0, implicit_ns);
+ gfc_current_locus = old_loc;
}
expr = gfc_get_expr ();
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index f5cd588308a..2c68af2b7e8 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -535,7 +535,7 @@ static void
find_arglists (gfc_symbol *sym)
{
if (sym->attr.if_source == IFSRC_UNKNOWN || sym->ns != gfc_current_ns
- || sym->attr.flavor == FL_DERIVED || sym->attr.intrinsic)
+ || gfc_fl_struct (sym->attr.flavor) || sym->attr.intrinsic)
return;
resolve_formal_arglist (sym);
@@ -1116,6 +1116,7 @@ resolve_contained_functions (gfc_namespace *ns)
static bool resolve_fl_derived0 (gfc_symbol *sym);
+static bool resolve_fl_struct (gfc_symbol *sym);
/* Resolve all of the elements of a structure constructor and make sure that
@@ -1132,8 +1133,13 @@ resolve_structure_cons (gfc_expr *expr, int init)
t = true;
- if (expr->ts.type == BT_DERIVED)
- resolve_fl_derived0 (expr->ts.u.derived);
+ if (expr->ts.type == BT_DERIVED || expr->ts.type == BT_UNION)
+ {
+ if (expr->ts.u.derived->attr.flavor == FL_DERIVED)
+ resolve_fl_derived0 (expr->ts.u.derived);
+ else
+ resolve_fl_struct (expr->ts.u.derived);
+ }
cons = gfc_constructor_first (expr->value.constructor);
@@ -1561,7 +1567,7 @@ is_illegal_recursion (gfc_symbol* sym, gfc_namespace* context)
gfc_namespace* real_context;
if (sym->attr.flavor == FL_PROGRAM
- || sym->attr.flavor == FL_DERIVED)
+ || gfc_fl_struct (sym->attr.flavor))
return false;
gcc_assert (sym->attr.flavor == FL_PROCEDURE);
@@ -2548,7 +2554,7 @@ resolve_generic_f (gfc_expr *expr)
generic:
if (!intr)
for (intr = sym->generic; intr; intr = intr->next)
- if (intr->sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (intr->sym->attr.flavor))
break;
if (sym->ns->parent == NULL)
@@ -5715,7 +5721,7 @@ get_declared_from_expr (gfc_ref **class_ref, gfc_ref **new_ref,
continue;
if ((ref->u.c.component->ts.type == BT_CLASS
- || (check_types && ref->u.c.component->ts.type == BT_DERIVED))
+ || (check_types && gfc_bt_struct (ref->u.c.component->ts.type)))
&& ref->u.c.component->attr.flavor != FL_PROCEDURE)
{
declared = ref->u.c.component->ts.u.derived;
@@ -5978,7 +5984,7 @@ resolve_typebound_function (gfc_expr* e)
is present. */
ts = expr->ts;
declared = ts.u.derived;
- c = gfc_find_component (declared, "_vptr", true, true);
+ c = gfc_find_component (declared, "_vptr", true, true, NULL);
if (c->ts.u.derived == NULL)
c->ts.u.derived = gfc_find_derived_vtab (declared);
@@ -6025,14 +6031,14 @@ resolve_typebound_function (gfc_expr* e)
return false;
/* Weed out cases of the ultimate component being a derived type. */
- if ((class_ref && class_ref->u.c.component->ts.type == BT_DERIVED)
+ if ((class_ref && gfc_bt_struct (class_ref->u.c.component->ts.type))
|| (!class_ref && st->n.sym->ts.type != BT_CLASS))
{
gfc_free_ref_list (new_ref);
return resolve_compcall (e, NULL);
}
- c = gfc_find_component (declared, "_data", true, true);
+ c = gfc_find_component (declared, "_data", true, true, NULL);
declared = c->ts.u.derived;
/* Treat the call as if it is a typebound procedure, in order to roll
@@ -6111,7 +6117,7 @@ resolve_typebound_subroutine (gfc_code *code)
that any delays in resolution are corrected and that the vtab
is present. */
declared = expr->ts.u.derived;
- c = gfc_find_component (declared, "_vptr", true, true);
+ c = gfc_find_component (declared, "_vptr", true, true, NULL);
if (c->ts.u.derived == NULL)
c->ts.u.derived = gfc_find_derived_vtab (declared);
@@ -6156,7 +6162,7 @@ resolve_typebound_subroutine (gfc_code *code)
get_declared_from_expr (&class_ref, &new_ref, code->expr1, true);
/* Weed out cases of the ultimate component being a derived type. */
- if ((class_ref && class_ref->u.c.component->ts.type == BT_DERIVED)
+ if ((class_ref && gfc_bt_struct (class_ref->u.c.component->ts.type))
|| (!class_ref && st->n.sym->ts.type != BT_CLASS))
{
gfc_free_ref_list (new_ref);
@@ -7140,7 +7146,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code, bool *array_alloc_wo_spec)
gfc_typespec ts;
gfc_expr *init_e;
- if (code->ext.alloc.ts.type == BT_DERIVED)
+ if (gfc_bt_struct (code->ext.alloc.ts.type))
ts = code->ext.alloc.ts;
else
ts = e->ts;
@@ -7148,7 +7154,7 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code, bool *array_alloc_wo_spec)
if (ts.type == BT_CLASS)
ts = ts.u.derived->components->ts;
- if (ts.type == BT_DERIVED && (init_e = gfc_default_initializer (&ts)))
+ if (gfc_bt_struct (ts.type) && (init_e = gfc_default_initializer (&ts)))
{
gfc_code *init_st = gfc_get_code (EXEC_INIT_ASSIGN);
init_st->loc = code->loc;
@@ -7282,7 +7288,7 @@ check_symbols:
sym = a->expr->symtree->n.sym;
/* TODO - check derived type components. */
- if (sym->ts.type == BT_DERIVED || sym->ts.type == BT_CLASS)
+ if (gfc_bt_struct (sym->ts.type) || sym->ts.type == BT_CLASS)
continue;
if ((ar->start[i] != NULL
@@ -8220,7 +8226,7 @@ resolve_assoc_var (gfc_symbol* sym, bool resolve_target)
if (!gfc_build_class_symbol (&sym->ts, &attr, &as))
gcc_unreachable ();
/* Make sure the _vptr is set. */
- c = gfc_find_component (sym->ts.u.derived, "_vptr", true, true);
+ c = gfc_find_component (sym->ts.u.derived, "_vptr", true, true, NULL);
if (c->ts.u.derived == NULL)
c->ts.u.derived = gfc_find_derived_vtab (sym->ts.u.derived);
CLASS_DATA (sym)->attr.pointer = 1;
@@ -9911,7 +9917,7 @@ nonscalar_typebound_assign (gfc_symbol *derived, int depth)
for (c= derived->components; c; c = c->next)
{
- if ((c->ts.type != BT_DERIVED
+ if ((!gfc_bt_struct (c->ts.type)
|| c->attr.pointer
|| c->attr.allocatable
|| c->attr.proc_pointer_comp
@@ -10051,7 +10057,7 @@ generate_component_assignments (gfc_code **code, gfc_namespace *ns)
/* The intrinsic assignment does the right thing for pointers
of all kinds and allocatable components. */
- if (comp1->ts.type != BT_DERIVED
+ if (!gfc_bt_struct (comp1->ts.type)
|| comp1->attr.pointer
|| comp1->attr.allocatable
|| comp1->attr.proc_pointer_comp
@@ -11433,7 +11439,7 @@ resolve_fl_variable_derived (gfc_symbol *sym, int no_init_flag)
gfc_find_symbol (sym->ts.u.derived->name, sym->ns, 0, &s);
if (s && s->attr.generic)
s = gfc_find_dt_in_generic (s);
- if (s && s->attr.flavor != FL_DERIVED)
+ if (s && !gfc_fl_struct (s->attr.flavor))
{
gfc_error ("The type %qs cannot be host associated at %L "
"because it is blocked by an incompatible object "
@@ -12733,7 +12739,8 @@ resolve_typebound_procedure (gfc_symtree* stree)
}
/* Try to find a name collision with an inherited component. */
- if (super_type && gfc_find_component (super_type, stree->name, true, true))
+ if (super_type && gfc_find_component (super_type, stree->name, true, true,
+ NULL))
{
gfc_error ("Procedure %qs at %L has the same name as an inherited"
" component of %qs",
@@ -12881,7 +12888,7 @@ check_defined_assignments (gfc_symbol *derived)
for (c = derived->components; c; c = c->next)
{
- if (c->ts.type != BT_DERIVED
+ if (!gfc_bt_struct (c->ts.type)
|| c->attr.pointer
|| c->attr.allocatable
|| c->attr.proc_pointer_comp
@@ -12907,435 +12914,498 @@ check_defined_assignments (gfc_symbol *derived)
}
-/* Resolve the components of a derived type. This does not have to wait until
- resolution stage, but can be done as soon as the dt declaration has been
- parsed. */
+/* Resolve a single component of a derived type or structure. */
static bool
-resolve_fl_derived0 (gfc_symbol *sym)
+resolve_component (gfc_component *c, gfc_symbol *sym)
{
- gfc_symbol* super_type;
- gfc_component *c;
+ gfc_symbol *super_type;
- if (sym->attr.unlimited_polymorphic)
+ if (c->attr.artificial)
return true;
- super_type = gfc_get_derived_super_type (sym);
+ /* F2008, C442. */
+ if ((!sym->attr.is_class || c != sym->components)
+ && c->attr.codimension
+ && (!c->attr.allocatable || (c->as && c->as->type != AS_DEFERRED)))
+ {
+ gfc_error ("Coarray component %qs at %L must be allocatable with "
+ "deferred shape", c->name, &c->loc);
+ return false;
+ }
- /* F2008, C432. */
- if (super_type && sym->attr.coarray_comp && !super_type->attr.coarray_comp)
+ /* F2008, C443. */
+ if (c->attr.codimension && c->ts.type == BT_DERIVED
+ && c->ts.u.derived->ts.is_iso_c)
{
- gfc_error ("As extending type %qs at %L has a coarray component, "
- "parent type %qs shall also have one", sym->name,
- &sym->declared_at, super_type->name);
+ gfc_error ("Component %qs at %L of TYPE(C_PTR) or TYPE(C_FUNPTR) "
+ "shall not be a coarray", c->name, &c->loc);
return false;
}
- /* Ensure the extended type gets resolved before we do. */
- if (super_type && !resolve_fl_derived0 (super_type))
- return false;
+ /* F2008, C444. */
+ if (gfc_bt_struct (c->ts.type) && c->ts.u.derived->attr.coarray_comp
+ && (c->attr.codimension || c->attr.pointer || c->attr.dimension
+ || c->attr.allocatable))
+ {
+ gfc_error ("Component %qs at %L with coarray component "
+ "shall be a nonpointer, nonallocatable scalar",
+ c->name, &c->loc);
+ return false;
+ }
- /* An ABSTRACT type must be extensible. */
- if (sym->attr.abstract && !gfc_type_is_extensible (sym))
+ /* F2008, C448. */
+ if (c->attr.contiguous && (!c->attr.dimension || !c->attr.pointer))
{
- gfc_error ("Non-extensible derived-type %qs at %L must not be ABSTRACT",
- sym->name, &sym->declared_at);
+ gfc_error ("Component %qs at %L has the CONTIGUOUS attribute but "
+ "is not an array pointer", c->name, &c->loc);
return false;
}
- c = (sym->attr.is_class) ? sym->components->ts.u.derived->components
- : sym->components;
+ if (c->attr.proc_pointer && c->ts.interface)
+ {
+ gfc_symbol *ifc = c->ts.interface;
- bool success = true;
+ if (!sym->attr.vtype && !check_proc_interface (ifc, &c->loc))
+ {
+ c->tb->error = 1;
+ return false;
+ }
- for ( ; c != NULL; c = c->next)
+ if (ifc->attr.if_source || ifc->attr.intrinsic)
+ {
+ /* Resolve interface and copy attributes. */
+ if (ifc->formal && !ifc->formal_ns)
+ resolve_symbol (ifc);
+ if (ifc->attr.intrinsic)
+ gfc_resolve_intrinsic (ifc, &ifc->declared_at);
+
+ if (ifc->result)
+ {
+ c->ts = ifc->result->ts;
+ c->attr.allocatable = ifc->result->attr.allocatable;
+ c->attr.pointer = ifc->result->attr.pointer;
+ c->attr.dimension = ifc->result->attr.dimension;
+ c->as = gfc_copy_array_spec (ifc->result->as);
+ c->attr.class_ok = ifc->result->attr.class_ok;
+ }
+ else
+ {
+ c->ts = ifc->ts;
+ c->attr.allocatable = ifc->attr.allocatable;
+ c->attr.pointer = ifc->attr.pointer;
+ c->attr.dimension = ifc->attr.dimension;
+ c->as = gfc_copy_array_spec (ifc->as);
+ c->attr.class_ok = ifc->attr.class_ok;
+ }
+ c->ts.interface = ifc;
+ c->attr.function = ifc->attr.function;
+ c->attr.subroutine = ifc->attr.subroutine;
+
+ c->attr.pure = ifc->attr.pure;
+ c->attr.elemental = ifc->attr.elemental;
+ c->attr.recursive = ifc->attr.recursive;
+ c->attr.always_explicit = ifc->attr.always_explicit;
+ c->attr.ext_attr |= ifc->attr.ext_attr;
+ /* Copy char length. */
+ if (ifc->ts.type == BT_CHARACTER && ifc->ts.u.cl)
+ {
+ gfc_charlen *cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl);
+ if (cl->length && !cl->resolved
+ && !gfc_resolve_expr (cl->length))
+ {
+ c->tb->error = 1;
+ return false;
+ }
+ c->ts.u.cl = cl;
+ }
+ }
+ }
+ else if (c->attr.proc_pointer && c->ts.type == BT_UNKNOWN)
{
- if (c->attr.artificial)
- continue;
+ /* Since PPCs are not implicitly typed, a PPC without an explicit
+ interface must be a subroutine. */
+ gfc_add_subroutine (&c->attr, c->name, &c->loc);
+ }
- /* F2008, C442. */
- if ((!sym->attr.is_class || c != sym->components)
- && c->attr.codimension
- && (!c->attr.allocatable || (c->as && c->as->type != AS_DEFERRED)))
- {
- gfc_error ("Coarray component %qs at %L must be allocatable with "
- "deferred shape", c->name, &c->loc);
- success = false;
- continue;
- }
+ /* Procedure pointer components: Check PASS arg. */
+ if (c->attr.proc_pointer && !c->tb->nopass && c->tb->pass_arg_num == 0
+ && !sym->attr.vtype)
+ {
+ gfc_symbol* me_arg;
- /* F2008, C443. */
- if (c->attr.codimension && c->ts.type == BT_DERIVED
- && c->ts.u.derived->ts.is_iso_c)
- {
- gfc_error ("Component %qs at %L of TYPE(C_PTR) or TYPE(C_FUNPTR) "
- "shall not be a coarray", c->name, &c->loc);
- success = false;
- continue;
- }
+ if (c->tb->pass_arg)
+ {
+ gfc_formal_arglist* i;
- /* F2008, C444. */
- if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.coarray_comp
- && (c->attr.codimension || c->attr.pointer || c->attr.dimension
- || c->attr.allocatable))
- {
- gfc_error ("Component %qs at %L with coarray component "
- "shall be a nonpointer, nonallocatable scalar",
- c->name, &c->loc);
- success = false;
- continue;
- }
+ /* If an explicit passing argument name is given, walk the arg-list
+ and look for it. */
- /* F2008, C448. */
- if (c->attr.contiguous && (!c->attr.dimension || !c->attr.pointer))
- {
- gfc_error ("Component %qs at %L has the CONTIGUOUS attribute but "
- "is not an array pointer", c->name, &c->loc);
- success = false;
- continue;
- }
+ me_arg = NULL;
+ c->tb->pass_arg_num = 1;
+ for (i = c->ts.interface->formal; i; i = i->next)
+ {
+ if (!strcmp (i->sym->name, c->tb->pass_arg))
+ {
+ me_arg = i->sym;
+ break;
+ }
+ c->tb->pass_arg_num++;
+ }
- if (c->attr.proc_pointer && c->ts.interface)
- {
- gfc_symbol *ifc = c->ts.interface;
+ if (!me_arg)
+ {
+ gfc_error ("Procedure pointer component %qs with PASS(%s) "
+ "at %L has no argument %qs", c->name,
+ c->tb->pass_arg, &c->loc, c->tb->pass_arg);
+ c->tb->error = 1;
+ return false;
+ }
+ }
+ else
+ {
+ /* Otherwise, take the first one; there should in fact be at least
+ one. */
+ c->tb->pass_arg_num = 1;
+ if (!c->ts.interface->formal)
+ {
+ gfc_error ("Procedure pointer component %qs with PASS at %L "
+ "must have at least one argument",
+ c->name, &c->loc);
+ c->tb->error = 1;
+ return false;
+ }
+ me_arg = c->ts.interface->formal->sym;
+ }
- if (!sym->attr.vtype && !check_proc_interface (ifc, &c->loc))
- {
- c->tb->error = 1;
- success = false;
- continue;
- }
+ /* Now check that the argument-type matches. */
+ gcc_assert (me_arg);
+ if ((me_arg->ts.type != BT_DERIVED && me_arg->ts.type != BT_CLASS)
+ || (me_arg->ts.type == BT_DERIVED && me_arg->ts.u.derived != sym)
+ || (me_arg->ts.type == BT_CLASS
+ && CLASS_DATA (me_arg)->ts.u.derived != sym))
+ {
+ gfc_error ("Argument %qs of %qs with PASS(%s) at %L must be of"
+ " the derived type %qs", me_arg->name, c->name,
+ me_arg->name, &c->loc, sym->name);
+ c->tb->error = 1;
+ return false;
+ }
- if (ifc->attr.if_source || ifc->attr.intrinsic)
- {
- /* Resolve interface and copy attributes. */
- if (ifc->formal && !ifc->formal_ns)
- resolve_symbol (ifc);
- if (ifc->attr.intrinsic)
- gfc_resolve_intrinsic (ifc, &ifc->declared_at);
+ /* Check for C453. */
+ if (me_arg->attr.dimension)
+ {
+ gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
+ "must be scalar", me_arg->name, c->name, me_arg->name,
+ &c->loc);
+ c->tb->error = 1;
+ return false;
+ }
- if (ifc->result)
- {
- c->ts = ifc->result->ts;
- c->attr.allocatable = ifc->result->attr.allocatable;
- c->attr.pointer = ifc->result->attr.pointer;
- c->attr.dimension = ifc->result->attr.dimension;
- c->as = gfc_copy_array_spec (ifc->result->as);
- c->attr.class_ok = ifc->result->attr.class_ok;
- }
- else
- {
- c->ts = ifc->ts;
- c->attr.allocatable = ifc->attr.allocatable;
- c->attr.pointer = ifc->attr.pointer;
- c->attr.dimension = ifc->attr.dimension;
- c->as = gfc_copy_array_spec (ifc->as);
- c->attr.class_ok = ifc->attr.class_ok;
- }
- c->ts.interface = ifc;
- c->attr.function = ifc->attr.function;
- c->attr.subroutine = ifc->attr.subroutine;
-
- c->attr.pure = ifc->attr.pure;
- c->attr.elemental = ifc->attr.elemental;
- c->attr.recursive = ifc->attr.recursive;
- c->attr.always_explicit = ifc->attr.always_explicit;
- c->attr.ext_attr |= ifc->attr.ext_attr;
- /* Copy char length. */
- if (ifc->ts.type == BT_CHARACTER && ifc->ts.u.cl)
- {
- gfc_charlen *cl = gfc_new_charlen (sym->ns, ifc->ts.u.cl);
- if (cl->length && !cl->resolved
- && !gfc_resolve_expr (cl->length))
- {
- c->tb->error = 1;
- success = false;
- continue;
- }
- c->ts.u.cl = cl;
- }
- }
- }
- else if (c->attr.proc_pointer && c->ts.type == BT_UNKNOWN)
- {
- /* Since PPCs are not implicitly typed, a PPC without an explicit
- interface must be a subroutine. */
- gfc_add_subroutine (&c->attr, c->name, &c->loc);
- }
+ if (me_arg->attr.pointer)
+ {
+ gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
+ "may not have the POINTER attribute", me_arg->name,
+ c->name, me_arg->name, &c->loc);
+ c->tb->error = 1;
+ return false;
+ }
- /* Procedure pointer components: Check PASS arg. */
- if (c->attr.proc_pointer && !c->tb->nopass && c->tb->pass_arg_num == 0
- && !sym->attr.vtype)
- {
- gfc_symbol* me_arg;
+ if (me_arg->attr.allocatable)
+ {
+ gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
+ "may not be ALLOCATABLE", me_arg->name, c->name,
+ me_arg->name, &c->loc);
+ c->tb->error = 1;
+ return false;
+ }
- if (c->tb->pass_arg)
- {
- gfc_formal_arglist* i;
+ if (gfc_type_is_extensible (sym) && me_arg->ts.type != BT_CLASS)
+ {
+ gfc_error ("Non-polymorphic passed-object dummy argument of %qs"
+ " at %L", c->name, &c->loc);
+ return false;
+ }
- /* If an explicit passing argument name is given, walk the arg-list
- and look for it. */
+ }
- me_arg = NULL;
- c->tb->pass_arg_num = 1;
- for (i = c->ts.interface->formal; i; i = i->next)
- {
- if (!strcmp (i->sym->name, c->tb->pass_arg))
- {
- me_arg = i->sym;
- break;
- }
- c->tb->pass_arg_num++;
- }
+ /* Check type-spec if this is not the parent-type component. */
+ if (((sym->attr.is_class
+ && (!sym->components->ts.u.derived->attr.extension
+ || c != sym->components->ts.u.derived->components))
+ || (!sym->attr.is_class
+ && (!sym->attr.extension || c != sym->components)))
+ && !sym->attr.vtype
+ && !resolve_typespec_used (&c->ts, &c->loc, c->name))
+ return false;
- if (!me_arg)
- {
- gfc_error ("Procedure pointer component %qs with PASS(%s) "
- "at %L has no argument %qs", c->name,
- c->tb->pass_arg, &c->loc, c->tb->pass_arg);
- c->tb->error = 1;
- success = false;
- continue;
- }
- }
- else
- {
- /* Otherwise, take the first one; there should in fact be at least
- one. */
- c->tb->pass_arg_num = 1;
- if (!c->ts.interface->formal)
- {
- gfc_error ("Procedure pointer component %qs with PASS at %L "
- "must have at least one argument",
- c->name, &c->loc);
- c->tb->error = 1;
- success = false;
- continue;
- }
- me_arg = c->ts.interface->formal->sym;
- }
+ super_type = gfc_get_derived_super_type (sym);
- /* Now check that the argument-type matches. */
- gcc_assert (me_arg);
- if ((me_arg->ts.type != BT_DERIVED && me_arg->ts.type != BT_CLASS)
- || (me_arg->ts.type == BT_DERIVED && me_arg->ts.u.derived != sym)
- || (me_arg->ts.type == BT_CLASS
- && CLASS_DATA (me_arg)->ts.u.derived != sym))
- {
- gfc_error ("Argument %qs of %qs with PASS(%s) at %L must be of"
- " the derived type %qs", me_arg->name, c->name,
- me_arg->name, &c->loc, sym->name);
- c->tb->error = 1;
- success = false;
- continue;
- }
+ /* If this type is an extension, set the accessibility of the parent
+ component. */
+ if (super_type
+ && ((sym->attr.is_class
+ && c == sym->components->ts.u.derived->components)
+ || (!sym->attr.is_class && c == sym->components))
+ && strcmp (super_type->name, c->name) == 0)
+ c->attr.access = super_type->attr.access;
+
+ /* If this type is an extension, see if this component has the same name
+ as an inherited type-bound procedure. */
+ if (super_type && !sym->attr.is_class
+ && gfc_find_typebound_proc (super_type, NULL, c->name, true, NULL))
+ {
+ gfc_error ("Component %qs of %qs at %L has the same name as an"
+ " inherited type-bound procedure",
+ c->name, sym->name, &c->loc);
+ return false;
+ }
- /* Check for C453. */
- if (me_arg->attr.dimension)
- {
- gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
- "must be scalar", me_arg->name, c->name, me_arg->name,
- &c->loc);
- c->tb->error = 1;
- success = false;
- continue;
- }
+ if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
+ && !c->ts.deferred)
+ {
+ if (c->ts.u.cl->length == NULL
+ || (!resolve_charlen(c->ts.u.cl))
+ || !gfc_is_constant_expr (c->ts.u.cl->length))
+ {
+ gfc_error ("Character length of component %qs needs to "
+ "be a constant specification expression at %L",
+ c->name,
+ c->ts.u.cl->length ? &c->ts.u.cl->length->where : &c->loc);
+ return false;
+ }
+ }
- if (me_arg->attr.pointer)
- {
- gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
- "may not have the POINTER attribute", me_arg->name,
- c->name, me_arg->name, &c->loc);
- c->tb->error = 1;
- success = false;
- continue;
- }
+ if (c->ts.type == BT_CHARACTER && c->ts.deferred
+ && !c->attr.pointer && !c->attr.allocatable)
+ {
+ gfc_error ("Character component %qs of %qs at %L with deferred "
+ "length must be a POINTER or ALLOCATABLE",
+ c->name, sym->name, &c->loc);
+ return false;
+ }
- if (me_arg->attr.allocatable)
- {
- gfc_error ("Argument %qs of %qs with PASS(%s) at %L "
- "may not be ALLOCATABLE", me_arg->name, c->name,
- me_arg->name, &c->loc);
- c->tb->error = 1;
- success = false;
- continue;
- }
+ /* Add the hidden deferred length field. */
+ if (c->ts.type == BT_CHARACTER && c->ts.deferred && !c->attr.function
+ && !sym->attr.is_class)
+ {
+ char name[GFC_MAX_SYMBOL_LEN+9];
+ gfc_component *strlen;
+ sprintf (name, "_%s_length", c->name);
+ strlen = gfc_find_component (sym, name, true, true, NULL);
+ if (strlen == NULL)
+ {
+ if (!gfc_add_component (sym, name, &strlen))
+ return false;
+ strlen->ts.type = BT_INTEGER;
+ strlen->ts.kind = gfc_charlen_int_kind;
+ strlen->attr.access = ACCESS_PRIVATE;
+ strlen->attr.artificial = 1;
+ }
+ }
- if (gfc_type_is_extensible (sym) && me_arg->ts.type != BT_CLASS)
- {
- gfc_error ("Non-polymorphic passed-object dummy argument of %qs"
- " at %L", c->name, &c->loc);
- success = false;
- continue;
- }
+ if (c->ts.type == BT_DERIVED
+ && sym->component_access != ACCESS_PRIVATE
+ && gfc_check_symbol_access (sym)
+ && !is_sym_host_assoc (c->ts.u.derived, sym->ns)
+ && !c->ts.u.derived->attr.use_assoc
+ && !gfc_check_symbol_access (c->ts.u.derived)
+ && !gfc_notify_std (GFC_STD_F2003, "the component %qs is a "
+ "PRIVATE type and cannot be a component of "
+ "%qs, which is PUBLIC at %L", c->name,
+ sym->name, &sym->declared_at))
+ return false;
- }
+ if ((sym->attr.sequence || sym->attr.is_bind_c) && c->ts.type == BT_CLASS)
+ {
+ gfc_error ("Polymorphic component %s at %L in SEQUENCE or BIND(C) "
+ "type %s", c->name, &c->loc, sym->name);
+ return false;
+ }
- /* Check type-spec if this is not the parent-type component. */
- if (((sym->attr.is_class
- && (!sym->components->ts.u.derived->attr.extension
- || c != sym->components->ts.u.derived->components))
- || (!sym->attr.is_class
- && (!sym->attr.extension || c != sym->components)))
- && !sym->attr.vtype
- && !resolve_typespec_used (&c->ts, &c->loc, c->name))
- return false;
+ if (sym->attr.sequence)
+ {
+ if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.sequence == 0)
+ {
+ gfc_error ("Component %s of SEQUENCE type declared at %L does "
+ "not have the SEQUENCE attribute",
+ c->ts.u.derived->name, &sym->declared_at);
+ return false;
+ }
+ }
- /* If this type is an extension, set the accessibility of the parent
- component. */
- if (super_type
- && ((sym->attr.is_class
- && c == sym->components->ts.u.derived->components)
- || (!sym->attr.is_class && c == sym->components))
- && strcmp (super_type->name, c->name) == 0)
- c->attr.access = super_type->attr.access;
-
- /* If this type is an extension, see if this component has the same name
- as an inherited type-bound procedure. */
- if (super_type && !sym->attr.is_class
- && gfc_find_typebound_proc (super_type, NULL, c->name, true, NULL))
- {
- gfc_error ("Component %qs of %qs at %L has the same name as an"
- " inherited type-bound procedure",
- c->name, sym->name, &c->loc);
- return false;
- }
+ if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.generic)
+ c->ts.u.derived = gfc_find_dt_in_generic (c->ts.u.derived);
+ else if (c->ts.type == BT_CLASS && c->attr.class_ok
+ && CLASS_DATA (c)->ts.u.derived->attr.generic)
+ CLASS_DATA (c)->ts.u.derived
+ = gfc_find_dt_in_generic (CLASS_DATA (c)->ts.u.derived);
- if (c->ts.type == BT_CHARACTER && !c->attr.proc_pointer
- && !c->ts.deferred)
- {
- if (c->ts.u.cl->length == NULL
- || (!resolve_charlen(c->ts.u.cl))
- || !gfc_is_constant_expr (c->ts.u.cl->length))
- {
- gfc_error ("Character length of component %qs needs to "
- "be a constant specification expression at %L",
- c->name,
- c->ts.u.cl->length ? &c->ts.u.cl->length->where : &c->loc);
- return false;
- }
- }
+ if (!sym->attr.is_class && c->ts.type == BT_DERIVED && !sym->attr.vtype
+ && c->attr.pointer && c->ts.u.derived->components == NULL
+ && !c->ts.u.derived->attr.zero_comp)
+ {
+ gfc_error ("The pointer component %qs of %qs at %L is a type "
+ "that has not been declared", c->name, sym->name,
+ &c->loc);
+ return false;
+ }
- if (c->ts.type == BT_CHARACTER && c->ts.deferred
- && !c->attr.pointer && !c->attr.allocatable)
- {
- gfc_error ("Character component %qs of %qs at %L with deferred "
- "length must be a POINTER or ALLOCATABLE",
- c->name, sym->name, &c->loc);
- return false;
- }
+ if (c->ts.type == BT_CLASS && c->attr.class_ok
+ && CLASS_DATA (c)->attr.class_pointer
+ && CLASS_DATA (c)->ts.u.derived->components == NULL
+ && !CLASS_DATA (c)->ts.u.derived->attr.zero_comp
+ && !UNLIMITED_POLY (c))
+ {
+ gfc_error ("The pointer component %qs of %qs at %L is a type "
+ "that has not been declared", c->name, sym->name,
+ &c->loc);
+ return false;
+ }
- /* Add the hidden deferred length field. */
- if (c->ts.type == BT_CHARACTER && c->ts.deferred && !c->attr.function
- && !sym->attr.is_class)
- {
- char name[GFC_MAX_SYMBOL_LEN+9];
- gfc_component *strlen;
- sprintf (name, "_%s_length", c->name);
- strlen = gfc_find_component (sym, name, true, true);
- if (strlen == NULL)
- {
- if (!gfc_add_component (sym, name, &strlen))
- return false;
- strlen->ts.type = BT_INTEGER;
- strlen->ts.kind = gfc_charlen_int_kind;
- strlen->attr.access = ACCESS_PRIVATE;
- strlen->attr.artificial = 1;
- }
- }
+ /* C437. */
+ if (c->ts.type == BT_CLASS && c->attr.flavor != FL_PROCEDURE
+ && (!c->attr.class_ok
+ || !(CLASS_DATA (c)->attr.class_pointer
+ || CLASS_DATA (c)->attr.allocatable)))
+ {
+ gfc_error ("Component %qs with CLASS at %L must be allocatable "
+ "or pointer", c->name, &c->loc);
+ /* Prevent a recurrence of the error. */
+ c->ts.type = BT_UNKNOWN;
+ return false;
+ }
- if (c->ts.type == BT_DERIVED
- && sym->component_access != ACCESS_PRIVATE
- && gfc_check_symbol_access (sym)
- && !is_sym_host_assoc (c->ts.u.derived, sym->ns)
- && !c->ts.u.derived->attr.use_assoc
- && !gfc_check_symbol_access (c->ts.u.derived)
- && !gfc_notify_std (GFC_STD_F2003, "the component %qs is a "
- "PRIVATE type and cannot be a component of "
- "%qs, which is PUBLIC at %L", c->name,
- sym->name, &sym->declared_at))
- return false;
+ /* Ensure that all the derived type components are put on the
+ derived type list; even in formal namespaces, where derived type
+ pointer components might not have been declared. */
+ if (c->ts.type == BT_DERIVED
+ && c->ts.u.derived
+ && c->ts.u.derived->components
+ && c->attr.pointer
+ && sym != c->ts.u.derived)
+ add_dt_to_dt_list (c->ts.u.derived);
- if ((sym->attr.sequence || sym->attr.is_bind_c) && c->ts.type == BT_CLASS)
- {
- gfc_error ("Polymorphic component %s at %L in SEQUENCE or BIND(C) "
- "type %s", c->name, &c->loc, sym->name);
- return false;
- }
+ if (!gfc_resolve_array_spec (c->as,
+ !(c->attr.pointer || c->attr.proc_pointer
+ || c->attr.allocatable)))
+ return false;
- if (sym->attr.sequence)
- {
- if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.sequence == 0)
- {
- gfc_error ("Component %s of SEQUENCE type declared at %L does "
- "not have the SEQUENCE attribute",
- c->ts.u.derived->name, &sym->declared_at);
- return false;
- }
- }
+ if (c->initializer && !sym->attr.vtype
+ && !gfc_check_assign_symbol (sym, c, c->initializer))
+ return false;
- if (c->ts.type == BT_DERIVED && c->ts.u.derived->attr.generic)
- c->ts.u.derived = gfc_find_dt_in_generic (c->ts.u.derived);
- else if (c->ts.type == BT_CLASS && c->attr.class_ok
- && CLASS_DATA (c)->ts.u.derived->attr.generic)
- CLASS_DATA (c)->ts.u.derived
- = gfc_find_dt_in_generic (CLASS_DATA (c)->ts.u.derived);
+ return true;
+}
- if (!sym->attr.is_class && c->ts.type == BT_DERIVED && !sym->attr.vtype
- && c->attr.pointer && c->ts.u.derived->components == NULL
- && !c->ts.u.derived->attr.zero_comp)
- {
- gfc_error ("The pointer component %qs of %qs at %L is a type "
- "that has not been declared", c->name, sym->name,
- &c->loc);
- return false;
- }
- if (c->ts.type == BT_CLASS && c->attr.class_ok
- && CLASS_DATA (c)->attr.class_pointer
- && CLASS_DATA (c)->ts.u.derived->components == NULL
- && !CLASS_DATA (c)->ts.u.derived->attr.zero_comp
- && !UNLIMITED_POLY (c))
- {
- gfc_error ("The pointer component %qs of %qs at %L is a type "
- "that has not been declared", c->name, sym->name,
- &c->loc);
- return false;
- }
+/* Be nice about the locus for a structure expression - show the locus of the
+ first non-null sub-expression if we can. */
- /* C437. */
- if (c->ts.type == BT_CLASS && c->attr.flavor != FL_PROCEDURE
- && (!c->attr.class_ok
- || !(CLASS_DATA (c)->attr.class_pointer
- || CLASS_DATA (c)->attr.allocatable)))
- {
- gfc_error ("Component %qs with CLASS at %L must be allocatable "
- "or pointer", c->name, &c->loc);
- /* Prevent a recurrence of the error. */
- c->ts.type = BT_UNKNOWN;
- return false;
- }
+static locus *
+cons_where (gfc_expr *struct_expr)
+{
+ gfc_constructor *cons;
- /* Ensure that all the derived type components are put on the
- derived type list; even in formal namespaces, where derived type
- pointer components might not have been declared. */
- if (c->ts.type == BT_DERIVED
- && c->ts.u.derived
- && c->ts.u.derived->components
- && c->attr.pointer
- && sym != c->ts.u.derived)
- add_dt_to_dt_list (c->ts.u.derived);
+ gcc_assert (struct_expr && struct_expr->expr_type == EXPR_STRUCTURE);
- if (!gfc_resolve_array_spec (c->as,
- !(c->attr.pointer || c->attr.proc_pointer
- || c->attr.allocatable)))
- return false;
+ cons = gfc_constructor_first (struct_expr->value.constructor);
+ for (; cons; cons = gfc_constructor_next (cons))
+ {
+ if (cons->expr && cons->expr->expr_type != EXPR_NULL)
+ return &cons->expr->where;
+ }
- if (c->initializer && !sym->attr.vtype
- && !gfc_check_assign_symbol (sym, c, c->initializer))
- return false;
+ return &struct_expr->where;
+}
+
+/* Resolve the components of a structure type. Much less work than derived
+ types. */
+
+static bool
+resolve_fl_struct (gfc_symbol *sym)
+{
+ gfc_component *c;
+ gfc_expr *init = NULL;
+ bool success;
+
+ /* Make sure UNIONs do not have overlapping initializers. */
+ if (sym->attr.flavor == FL_UNION)
+ {
+ for (c = sym->components; c; c = c->next)
+ {
+ if (init && c->initializer)
+ {
+ gfc_error ("Conflicting initializers in union at %L and %L",
+ cons_where (init), cons_where (c->initializer));
+ gfc_free_expr (c->initializer);
+ c->initializer = NULL;
+ }
+ if (init == NULL)
+ init = c->initializer;
+ }
}
+ success = true;
+ for (c = sym->components; c; c = c->next)
+ if (!resolve_component (c, sym))
+ success = false;
+
+ if (!success)
+ return false;
+
+ if (sym->components)
+ add_dt_to_dt_list (sym);
+
+ return true;
+}
+
+
+/* Resolve the components of a derived type. This does not have to wait until
+ resolution stage, but can be done as soon as the dt declaration has been
+ parsed. */
+
+static bool
+resolve_fl_derived0 (gfc_symbol *sym)
+{
+ gfc_symbol* super_type;
+ gfc_component *c;
+ bool success;
+
+ if (sym->attr.unlimited_polymorphic)
+ return true;
+
+ super_type = gfc_get_derived_super_type (sym);
+
+ /* F2008, C432. */
+ if (super_type && sym->attr.coarray_comp && !super_type->attr.coarray_comp)
+ {
+ gfc_error ("As extending type %qs at %L has a coarray component, "
+ "parent type %qs shall also have one", sym->name,
+ &sym->declared_at, super_type->name);
+ return false;
+ }
+
+ /* Ensure the extended type gets resolved before we do. */
+ if (super_type && !resolve_fl_derived0 (super_type))
+ return false;
+
+ /* An ABSTRACT type must be extensible. */
+ if (sym->attr.abstract && !gfc_type_is_extensible (sym))
+ {
+ gfc_error ("Non-extensible derived-type %qs at %L must not be ABSTRACT",
+ sym->name, &sym->declared_at);
+ return false;
+ }
+
+ c = (sym->attr.is_class) ? sym->components->ts.u.derived->components
+ : sym->components;
+
+ success = true;
+ for ( ; c != NULL; c = c->next)
+ if (!resolve_component (c, sym))
+ success = false;
+
if (!success)
return false;
@@ -13396,8 +13466,8 @@ resolve_fl_derived (gfc_symbol *sym)
if (sym->attr.is_class && sym->ts.u.derived == NULL)
{
/* Fix up incomplete CLASS symbols. */
- gfc_component *data = gfc_find_component (sym, "_data", true, true);
- gfc_component *vptr = gfc_find_component (sym, "_vptr", true, true);
+ gfc_component *data = gfc_find_component (sym, "_data", true, true, NULL);
+ gfc_component *vptr = gfc_find_component (sym, "_vptr", true, true, NULL);
/* Nothing more to do for unlimited polymorphic entities. */
if (data->ts.u.derived->attr.unlimited_polymorphic)
@@ -13616,6 +13686,11 @@ resolve_symbol (gfc_symbol *sym)
return;
sym->resolved = 1;
+ /* No symbol will ever have union type; only components can be unions.
+ Union type declaration symbols have type BT_UNKNOWN but flavor FL_UNION
+ (just like derived type declaration symbols have flavor FL_DERIVED). */
+ gcc_assert (sym->ts.type != BT_UNION);
+
if (sym->attr.artificial)
return;
@@ -13687,6 +13762,10 @@ resolve_symbol (gfc_symbol *sym)
if (sym->attr.flavor == FL_DERIVED && !resolve_fl_derived (sym))
return;
+ else if ((sym->attr.flavor == FL_STRUCT || sym->attr.flavor == FL_UNION)
+ && !resolve_fl_struct (sym))
+ return;
+
/* Symbols that are module procedures with results (functions) have
the types and array specification copied for type checking in
procedures that call them, as well as for saving to a module
@@ -15030,7 +15109,7 @@ resolve_equivalence_derived (gfc_symbol *derived, gfc_symbol *sym, gfc_expr *e)
for (; c ; c = c->next)
{
- if (c->ts.type == BT_DERIVED
+ if (gfc_bt_struct (c->ts.type)
&& (!resolve_equivalence_derived(c->ts.u.derived, sym, e)))
return false;
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index 8efd12ca68b..0ee7decffd4 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -40,6 +40,7 @@ const mstring flavors[] =
minit ("VARIABLE", FL_VARIABLE), minit ("PARAMETER", FL_PARAMETER),
minit ("LABEL", FL_LABEL), minit ("PROCEDURE", FL_PROCEDURE),
minit ("DERIVED", FL_DERIVED), minit ("NAMELIST", FL_NAMELIST),
+ minit ("UNION", FL_UNION), minit ("STRUCTURE", FL_STRUCT),
minit (NULL, -1)
};
@@ -444,7 +445,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
case FL_BLOCK_DATA:
case FL_MODULE:
case FL_LABEL:
- case FL_DERIVED:
+ case_fl_struct:
case FL_PARAMETER:
a1 = gfc_code2string (flavors, attr->flavor);
a2 = save;
@@ -740,7 +741,7 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where)
break;
- case FL_DERIVED:
+ case_fl_struct:
conf2 (dummy);
conf2 (pointer);
conf2 (target);
@@ -1579,7 +1580,7 @@ gfc_add_flavor (symbol_attribute *attr, sym_flavor f, const char *name,
{
if ((f == FL_PROGRAM || f == FL_BLOCK_DATA || f == FL_MODULE
- || f == FL_PARAMETER || f == FL_LABEL || f == FL_DERIVED
+ || f == FL_PARAMETER || f == FL_LABEL || gfc_fl_struct(f)
|| f == FL_NAMELIST) && check_used (attr, name, where))
return false;
@@ -2048,6 +2049,11 @@ gfc_add_component (gfc_symbol *sym, const char *name,
{
gfc_component *p, *tail;
+ /* Check for existing components with the same name, but not for union
+ components or containers. Unions and maps are anonymous so they have
+ unique internal names which will never conflict.
+ Don't use gfc_find_component here because it calls gfc_use_derived,
+ but the derived type may not be fully defined yet. */
tail = NULL;
for (p = sym->components; p; p = p->next)
@@ -2063,7 +2069,8 @@ gfc_add_component (gfc_symbol *sym, const char *name,
}
if (sym->attr.extension
- && gfc_find_component (sym->components->ts.u.derived, name, true, true))
+ && gfc_find_component (sym->components->ts.u.derived,
+ name, true, true, NULL))
{
gfc_error ("Component %qs at %C already in the parent type "
"at %L", name, &sym->components->ts.u.derived->declared_at);
@@ -2154,7 +2161,7 @@ gfc_use_derived (gfc_symbol *sym)
return NULL;
}
- if (s == NULL || s->attr.flavor != FL_DERIVED)
+ if (s == NULL || !gfc_fl_struct (s->attr.flavor))
goto bad;
/* Get rid of symbol sym, translating all references to s. */
@@ -2188,28 +2195,113 @@ bad:
}
+/* Find the component with the given name in the union type symbol.
+ If ref is not NULL it will be set to the chain of components through which
+ the component can actually be accessed. This is necessary for unions because
+ intermediate structures may be maps, nested structures, or other unions,
+ all of which may (or must) be 'anonymous' to user code. */
+
+static gfc_component *
+find_union_component (gfc_symbol *un, const char *name,
+ bool noaccess, gfc_ref **ref)
+{
+ gfc_component *m, *check;
+ gfc_ref *sref, *tmp;
+
+ for (m = un->components; m; m = m->next)
+ {
+ check = gfc_find_component (m->ts.u.derived, name, noaccess, true, &tmp);
+ if (check == NULL)
+ continue;
+
+ /* Found component somewhere in m; chain the refs together. */
+ if (ref)
+ {
+ /* Map ref. */
+ sref = gfc_get_ref ();
+ sref->type = REF_COMPONENT;
+ sref->u.c.component = m;
+ sref->u.c.sym = m->ts.u.derived;
+ sref->next = tmp;
+
+ *ref = sref;
+ }
+ /* Other checks (such as access) were done in the recursive calls. */
+ return check;
+ }
+ return NULL;
+}
+
+
/* Given a derived type node and a component name, try to locate the
component structure. Returns the NULL pointer if the component is
not found or the components are private. If noaccess is set, no access
- checks are done. */
+ checks are done. If silent is set, an error will not be generated if
+ the component cannot be found or accessed.
+
+ If ref is not NULL, *ref is set to represent the chain of components
+ required to get to the ultimate component.
+
+ If the component is simply a direct subcomponent, or is inherited from a
+ parent derived type in the given derived type, this is a single ref with its
+ component set to the returned component.
+
+ Otherwise, *ref is constructed as a chain of subcomponents. This occurs
+ when the component is found through an implicit chain of nested union and
+ map components. Unions and maps are "anonymous" substructures in FORTRAN
+ which cannot be explicitly referenced, but the reference chain must be
+ considered as in C for backend translation to correctly compute layouts.
+ (For example, x.a may refer to x->(UNION)->(MAP)->(UNION)->(MAP)->a). */
gfc_component *
gfc_find_component (gfc_symbol *sym, const char *name,
- bool noaccess, bool silent)
+ bool noaccess, bool silent, gfc_ref **ref)
{
- gfc_component *p;
+ gfc_component *p, *check;
+ gfc_ref *sref = NULL, *tmp = NULL;
if (name == NULL || sym == NULL)
return NULL;
- sym = gfc_use_derived (sym);
+ if (sym->attr.flavor == FL_DERIVED)
+ sym = gfc_use_derived (sym);
+ else
+ gcc_assert (gfc_fl_struct (sym->attr.flavor));
if (sym == NULL)
return NULL;
+ /* Handle UNIONs specially - mutually recursive with gfc_find_component. */
+ if (sym->attr.flavor == FL_UNION)
+ return find_union_component (sym, name, noaccess, ref);
+
+ if (ref) *ref = NULL;
for (p = sym->components; p; p = p->next)
- if (strcmp (p->name, name) == 0)
- break;
+ {
+ /* Nest search into union's maps. */
+ if (p->ts.type == BT_UNION)
+ {
+ check = find_union_component (p->ts.u.derived, name, noaccess, &tmp);
+ if (check != NULL)
+ {
+ /* Union ref. */
+ if (ref)
+ {
+ sref = gfc_get_ref ();
+ sref->type = REF_COMPONENT;
+ sref->u.c.component = p;
+ sref->u.c.sym = p->ts.u.derived;
+ sref->next = tmp;
+ *ref = sref;
+ }
+ return check;
+ }
+ }
+ else if (strcmp (p->name, name) == 0)
+ break;
+
+ continue;
+ }
if (p && sym->attr.use_assoc && !noaccess)
{
@@ -2231,7 +2323,7 @@ gfc_find_component (gfc_symbol *sym, const char *name,
&& sym->components->ts.type == BT_DERIVED)
{
p = gfc_find_component (sym->components->ts.u.derived, name,
- noaccess, silent);
+ noaccess, silent, ref);
/* Do not overwrite the error. */
if (p == NULL)
return p;
@@ -2241,6 +2333,25 @@ gfc_find_component (gfc_symbol *sym, const char *name,
gfc_error ("%qs at %C is not a member of the %qs structure",
name, sym->name);
+ /* Component was found; build the ultimate component reference. */
+ if (p != NULL && ref)
+ {
+ tmp = gfc_get_ref ();
+ tmp->type = REF_COMPONENT;
+ tmp->u.c.component = p;
+ tmp->u.c.sym = sym;
+ /* Link the final component ref to the end of the chain of subrefs. */
+ if (sref)
+ {
+ *ref = sref;
+ for (; sref->next; sref = sref->next)
+ ;
+ sref->next = tmp;
+ }
+ else
+ *ref = tmp;
+ }
+
return p;
}
@@ -3338,11 +3449,9 @@ gfc_restore_last_undo_checkpoint (void)
/* The derived type is saved in the symtree with the first
letter capitalized; the all lower-case version to the
derived type contains its associated generic function. */
- if (p->attr.flavor == FL_DERIVED)
- gfc_delete_symtree (&p->ns->sym_root, gfc_get_string ("%c%s",
- (char) TOUPPER ((unsigned char) p->name[0]),
- &p->name[1]));
- else
+ if (gfc_fl_struct (p->attr.flavor))
+ gfc_delete_symtree (&p->ns->sym_root,gfc_dt_upper_string (p->name));
+ else
gfc_delete_symtree (&p->ns->sym_root, p->name);
gfc_release_symbol (p);
@@ -4526,10 +4635,7 @@ generate_isocbinding_symbol (const char *mod_name, iso_c_binding_symbol s,
const char *hidden_name;
gfc_interface *intr, *head;
- hidden_name = gfc_get_string ("%c%s",
- (char) TOUPPER ((unsigned char)
- tmp_sym->name[0]),
- &tmp_sym->name[1]);
+ hidden_name = gfc_dt_upper_string (tmp_sym->name);
tmp_symtree = gfc_find_symtree (gfc_current_ns->sym_root,
hidden_name);
gcc_assert (tmp_symtree == NULL);
@@ -4740,6 +4846,8 @@ gfc_type_compatible (gfc_typespec *ts1, gfc_typespec *ts2)
bool is_class2 = (ts2->type == BT_CLASS);
bool is_derived1 = (ts1->type == BT_DERIVED);
bool is_derived2 = (ts2->type == BT_DERIVED);
+ bool is_union1 = (ts1->type == BT_UNION);
+ bool is_union2 = (ts2->type == BT_UNION);
if (is_class1
&& ts1->u.derived->components
@@ -4749,10 +4857,11 @@ gfc_type_compatible (gfc_typespec *ts1, gfc_typespec *ts2)
|| ts1->u.derived->attr.unlimited_polymorphic))
return 1;
- if (!is_derived1 && !is_derived2 && !is_class1 && !is_class2)
+ if (!is_derived1 && !is_derived2 && !is_class1 && !is_class2
+ && !is_union1 && !is_union2)
return (ts1->type == ts2->type);
- if (is_derived1 && is_derived2)
+ if ((is_derived1 && is_derived2) || (is_union1 && is_union1))
return gfc_compare_derived_types (ts1->u.derived, ts2->u.derived);
if (is_derived1 && is_class2)
@@ -4821,12 +4930,12 @@ gfc_find_dt_in_generic (gfc_symbol *sym)
{
gfc_interface *intr = NULL;
- if (!sym || sym->attr.flavor == FL_DERIVED)
+ if (!sym || gfc_fl_struct (sym->attr.flavor))
return sym;
if (sym->attr.generic)
for (intr = sym->generic; intr; intr = intr->next)
- if (intr->sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (intr->sym->attr.flavor))
break;
return intr ? intr->sym : NULL;
}
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 309baf1c69e..2f5e4342afa 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -45,6 +45,7 @@ along with GCC; see the file COPYING3. If not see
/* Only for gfc_trans_code. Shouldn't need to include this. */
#include "trans-stmt.h"
#include "gomp-constants.h"
+#include "gimplify.h"
#define MAX_LABEL_VALUE 99999
@@ -732,6 +733,7 @@ gfc_get_module_backend_decl (gfc_symbol *sym)
st = NULL;
s = NULL;
+ /* Check for a symbol with the same name. */
if (gsym)
gfc_find_symbol (sym->name, gsym->ns, 0, &s);
@@ -748,22 +750,37 @@ gfc_get_module_backend_decl (gfc_symbol *sym)
st->n.sym = sym;
sym->refs++;
}
- else if (sym->attr.flavor == FL_DERIVED)
+ else if (gfc_fl_struct (sym->attr.flavor))
{
if (s && s->attr.flavor == FL_PROCEDURE)
{
gfc_interface *intr;
gcc_assert (s->attr.generic);
for (intr = s->generic; intr; intr = intr->next)
- if (intr->sym->attr.flavor == FL_DERIVED)
+ if (gfc_fl_struct (intr->sym->attr.flavor))
{
s = intr->sym;
break;
}
}
- if (!s->backend_decl)
- s->backend_decl = gfc_get_derived_type (s);
+ /* Normally we can assume that s is a derived-type symbol since it
+ shares a name with the derived-type sym. However if sym is a
+ STRUCTURE, it may in fact share a name with any other basic type
+ variable. If s is in fact of derived type then we can continue
+ looking for a duplicate type declaration. */
+ if (sym->attr.flavor == FL_STRUCT && s->ts.type == BT_DERIVED)
+ {
+ s = s->ts.u.derived;
+ }
+
+ if (gfc_fl_struct (s->attr.flavor) && !s->backend_decl)
+ {
+ if (s->attr.flavor == FL_UNION)
+ s->backend_decl = gfc_get_union_type (s);
+ else
+ s->backend_decl = gfc_get_derived_type (s);
+ }
gfc_copy_dt_decls_ifequal (s, sym, true);
return true;
}
@@ -2384,7 +2401,7 @@ create_function_arglist (gfc_symbol * sym)
Thus, we will use a hidden argument in that case. */
else if (f->sym->attr.optional && f->sym->attr.value
&& !f->sym->attr.dimension && f->sym->ts.type != BT_CLASS
- && f->sym->ts.type != BT_DERIVED)
+ && !gfc_bt_struct (f->sym->ts.type))
{
tree tmp;
strcpy (&name[1], f->sym->name);
@@ -3738,7 +3755,7 @@ gfc_trans_vla_one_sizepos (tree *tp, stmtblock_t *body)
var = gfc_create_var_np (TREE_TYPE (t), NULL);
gfc_add_decl_to_function (var);
- gfc_add_modify (body, var, val);
+ gfc_add_modify (body, var, unshare_expr (val));
if (TREE_CODE (t) == SAVE_EXPR)
TREE_OPERAND (t, 0) = var;
*tp = var;
@@ -4596,7 +4613,7 @@ gfc_create_module_variable (gfc_symbol * sym)
&& sym->ts.type == BT_DERIVED)
sym->backend_decl = gfc_typenode_for_spec (&(sym->ts));
- if (sym->attr.flavor == FL_DERIVED
+ if (gfc_fl_struct (sym->attr.flavor)
&& sym->backend_decl
&& TREE_CODE (sym->backend_decl) == RECORD_TYPE)
{
@@ -4839,7 +4856,7 @@ check_constant_initializer (gfc_expr *expr, gfc_typespec *ts, bool array,
}
else switch (ts->type)
{
- case BT_DERIVED:
+ case_bt_struct:
if (expr->expr_type != EXPR_STRUCTURE)
return false;
cm = expr->ts.u.derived->components;
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index 8d039a670b5..8f84712931b 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -2297,6 +2297,7 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
tree tmp;
tree decl;
tree field;
+ tree context;
c = ref->u.c.component;
@@ -2307,15 +2308,20 @@ gfc_conv_component_ref (gfc_se * se, gfc_ref * ref)
field = c->backend_decl;
gcc_assert (field && TREE_CODE (field) == FIELD_DECL);
decl = se->expr;
+ context = DECL_FIELD_CONTEXT (field);
/* Components can correspond to fields of different containing
types, as components are created without context, whereas
a concrete use of a component has the type of decl as context.
So, if the type doesn't match, we search the corresponding
FIELD_DECL in the parent type. To not waste too much time
- we cache this result in norestrict_decl. */
+ we cache this result in norestrict_decl.
+ On the other hand, if the context is a UNION or a MAP (a
+ RECORD_TYPE within a UNION_TYPE) always use the given FIELD_DECL. */
- if (DECL_FIELD_CONTEXT (field) != TREE_TYPE (decl))
+ if (context != TREE_TYPE (decl)
+ && !( TREE_CODE (TREE_TYPE (field)) == UNION_TYPE /* Field is union */
+ || TREE_CODE (context) == UNION_TYPE)) /* Field is map */
{
tree f2 = c->norestrict_decl;
if (!f2 || DECL_FIELD_CONTEXT (f2) != TREE_TYPE (decl))
@@ -6715,7 +6721,7 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
{
switch (ts->type)
{
- case BT_DERIVED:
+ case_bt_struct:
case BT_CLASS:
gfc_init_se (&se, NULL);
if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
@@ -6860,7 +6866,7 @@ gfc_trans_alloc_subarray_assign (tree dest, gfc_component * cm,
gfc_add_modify (&block, dest, se.expr);
/* Deal with arrays of derived types with allocatable components. */
- if (cm->ts.type == BT_DERIVED
+ if (gfc_bt_struct (cm->ts.type)
&& cm->ts.u.derived->attr.alloc_comp)
tmp = gfc_copy_alloc_comp (cm->ts.u.derived,
se.expr, dest,
@@ -7033,7 +7039,7 @@ alloc_scalar_allocatable_for_subcomponent_assignment (stmtblock_t *block,
/* Ensure that cm->ts.u.cl->backend_decl is a componentref to _%s_length
component. */
sprintf (name, "_%s_length", cm->name);
- strlen = gfc_find_component (sym, name, true, true);
+ strlen = gfc_find_component (sym, name, true, true, NULL);
lhs_cl_size = fold_build3_loc (input_location, COMPONENT_REF,
gfc_charlen_type_node,
TREE_OPERAND (comp, 0),
@@ -7245,7 +7251,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr,
fold_convert (TREE_TYPE (tmp), se.expr));
gfc_add_block_to_block (&block, &se.post);
}
- else if (expr->ts.type == BT_DERIVED && expr->ts.f90_type != BT_VOID)
+ else if (gfc_bt_struct (expr->ts.type) && expr->ts.f90_type != BT_VOID)
{
if (expr->expr_type != EXPR_STRUCTURE)
{
@@ -7416,6 +7422,24 @@ gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
return;
}
+ /* Though unions appear to have multiple map components, they must only
+ have a single initializer since each map overlaps. TODO: squash map
+ constructors? */
+ if (expr->ts.type == BT_UNION)
+ {
+ c = gfc_constructor_first (expr->value.constructor);
+ cm = c->n.component;
+ val = gfc_conv_initializer (c->expr, &expr->ts,
+ TREE_TYPE (cm->backend_decl),
+ cm->attr.dimension, cm->attr.pointer,
+ cm->attr.proc_pointer);
+ val = unshare_expr_without_location (val);
+
+ /* Append it to the constructor list. */
+ CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
+ goto finish;
+ }
+
cm = expr->ts.u.derived->components;
for (c = gfc_constructor_first (expr->value.constructor);
@@ -7462,6 +7486,7 @@ gfc_conv_structure (gfc_se * se, gfc_expr * expr, int init)
CONSTRUCTOR_APPEND_ELT (v, cm->backend_decl, val);
}
}
+finish:
se->expr = build_constructor (type, v);
if (init)
TREE_CONSTANT (se->expr) = 1;
@@ -8246,7 +8271,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
gfc_trans_string_copy (&block, llen, lse->expr, ts.kind, rlen,
rse->expr, ts.kind);
}
- else if (ts.type == BT_DERIVED && ts.u.derived->attr.alloc_comp)
+ else if (gfc_bt_struct (ts.type) && ts.u.derived->attr.alloc_comp)
{
tree tmp_var = NULL_TREE;
cond = NULL_TREE;
@@ -8299,7 +8324,7 @@ gfc_trans_scalar_assign (gfc_se * lse, gfc_se * rse, gfc_typespec ts,
gfc_add_expr_to_block (&block, tmp);
}
}
- else if (ts.type == BT_DERIVED || ts.type == BT_CLASS)
+ else if (gfc_bt_struct (ts.type) || ts.type == BT_CLASS)
{
gfc_add_block_to_block (&block, &lse->pre);
gfc_add_block_to_block (&block, &rse->pre);
@@ -9503,7 +9528,7 @@ copyable_array_p (gfc_expr * expr)
case BT_CHARACTER:
return false;
- case BT_DERIVED:
+ case_bt_struct:
return !expr->ts.u.derived->attr.alloc_comp;
default:
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index 7f649978863..aefa96dfbbb 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -1685,7 +1685,7 @@ transfer_namelist_element (stmtblock_t * block, const char * var_name,
gfc_add_expr_to_block (block, tmp);
}
- if (ts->type == BT_DERIVED && ts->u.derived->components)
+ if (gfc_bt_struct (ts->type) && ts->u.derived->components)
{
gfc_component *cmp;
@@ -2211,7 +2211,7 @@ transfer_expr (gfc_se * se, gfc_typespec * ts, tree addr_expr, gfc_code * code)
break;
- case BT_DERIVED:
+ case_bt_struct:
if (ts->u.derived->components == NULL)
return;
@@ -2330,7 +2330,7 @@ gfc_trans_transfer (gfc_code * code)
gcc_assert (ref && ref->type == REF_ARRAY);
}
- if (expr->ts.type != BT_DERIVED
+ if (!gfc_bt_struct (expr->ts.type)
&& ref && ref->next == NULL
&& !is_subref_array (expr))
{
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index 2fc43eddbe5..7d3cf8cae5a 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -6275,7 +6275,7 @@ gfc_trans_deallocate (gfc_code *code)
{
gfc_ref *ref;
- if (expr->ts.type == BT_DERIVED && expr->ts.u.derived->attr.alloc_comp
+ if (gfc_bt_struct (expr->ts.type) && expr->ts.u.derived->attr.alloc_comp
&& !gfc_is_finalizable (expr->ts.u.derived, NULL))
{
gfc_ref *last = NULL;
diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c
index dd945aa059a..0079d6cd422 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -828,6 +828,7 @@ gfc_build_complex_type (tree scalar_type)
new_type = make_node (COMPLEX_TYPE);
TREE_TYPE (new_type) = scalar_type;
+ SET_TYPE_MODE (new_type, GET_MODE_COMPLEX_MODE (TYPE_MODE (scalar_type)));
layout_type (new_type);
return new_type;
}
@@ -1101,6 +1102,10 @@ gfc_typenode_for_spec (gfc_typespec * spec)
gfc_index_one_node);
break;
+ case BT_UNION:
+ basetype = gfc_get_union_type (spec->u.derived);
+ break;
+
case BT_DERIVED:
case BT_CLASS:
basetype = gfc_get_derived_type (spec->u.derived);
@@ -2314,7 +2319,9 @@ gfc_copy_dt_decls_ifequal (gfc_symbol *from, gfc_symbol *to,
for (; to_cm; to_cm = to_cm->next, from_cm = from_cm->next)
{
to_cm->backend_decl = from_cm->backend_decl;
- if (from_cm->ts.type == BT_DERIVED
+ if (from_cm->ts.type == BT_UNION)
+ gfc_get_union_type (to_cm->ts.u.derived);
+ else if (from_cm->ts.type == BT_DERIVED
&& (!from_cm->attr.pointer || from_gsym))
gfc_get_derived_type (to_cm->ts.u.derived);
else if (from_cm->ts.type == BT_CLASS
@@ -2349,6 +2356,62 @@ gfc_get_ppc_type (gfc_component* c)
}
+/* Build a tree node for a union type. Requires building each map
+ structure which is an element of the union. */
+
+tree
+gfc_get_union_type (gfc_symbol *un)
+{
+ gfc_component *map = NULL;
+ tree typenode = NULL, map_type = NULL, map_field = NULL;
+ tree *chain = NULL;
+
+ if (un->backend_decl)
+ {
+ if (TYPE_FIELDS (un->backend_decl) || un->attr.proc_pointer_comp)
+ return un->backend_decl;
+ else
+ typenode = un->backend_decl;
+ }
+ else
+ {
+ typenode = make_node (UNION_TYPE);
+ TYPE_NAME (typenode) = get_identifier (un->name);
+ }
+
+ /* Add each contained MAP as a field. */
+ for (map = un->components; map; map = map->next)
+ {
+ gcc_assert (map->ts.type == BT_DERIVED);
+
+ /* The map's type node, which is defined within this union's context. */
+ map_type = gfc_get_derived_type (map->ts.u.derived);
+ TYPE_CONTEXT (map_type) = typenode;
+
+ /* The map field's declaration. */
+ map_field = gfc_add_field_to_struct(typenode, get_identifier(map->name),
+ map_type, &chain);
+ if (map->loc.lb)
+ gfc_set_decl_location (map_field, &map->loc);
+ else if (un->declared_at.lb)
+ gfc_set_decl_location (map_field, &un->declared_at);
+
+ DECL_PACKED (map_field) |= TYPE_PACKED (typenode);
+ DECL_NAMELESS(map_field) = true;
+
+ /* We should never clobber another backend declaration for this map,
+ because each map component is unique. */
+ if (!map->backend_decl)
+ map->backend_decl = map_field;
+ }
+
+ un->backend_decl = typenode;
+ gfc_finish_type (typenode);
+
+ return typenode;
+}
+
+
/* Build a tree node for a derived type. If there are equal
derived types, with different local names, these are built
at the same time. If an equal derived type has been built
@@ -2491,6 +2554,9 @@ gfc_get_derived_type (gfc_symbol * derived)
will be built and so we can return the type. */
for (c = derived->components; c; c = c->next)
{
+ if (c->ts.type == BT_UNION && c->ts.u.derived->backend_decl == NULL)
+ c->ts.u.derived->backend_decl = gfc_get_union_type (c->ts.u.derived);
+
if (c->ts.type != BT_DERIVED && c->ts.type != BT_CLASS)
continue;
@@ -2520,7 +2586,10 @@ gfc_get_derived_type (gfc_symbol * derived)
return derived->backend_decl;
/* Build the type member list. Install the newly created RECORD_TYPE
- node as DECL_CONTEXT of each FIELD_DECL. */
+ node as DECL_CONTEXT of each FIELD_DECL. In this case we must go
+ through only the top-level linked list of components so we correctly
+ build UNION_TYPE nodes for BT_UNION components. MAPs and other nested
+ types are built as part of gfc_get_union_type. */
for (c = derived->components; c; c = c->next)
{
/* Prevent infinite recursion, when the procedure pointer type is
diff --git a/gcc/function.c b/gcc/function.c
index 43a80b42875..726c20ca017 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -5753,49 +5753,6 @@ prologue_epilogue_contains (const_rtx insn)
return 0;
}
-/* Insert use of return register before the end of BB. */
-
-static void
-emit_use_return_register_into_block (basic_block bb)
-{
- start_sequence ();
- use_return_register ();
- rtx_insn *seq = get_insns ();
- end_sequence ();
- rtx_insn *insn = BB_END (bb);
- if (HAVE_cc0 && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
- insn = prev_cc0_setter (insn);
-
- emit_insn_before (seq, insn);
-}
-
-
-/* Create a return pattern, either simple_return or return, depending on
- simple_p. */
-
-static rtx_insn *
-gen_return_pattern (bool simple_p)
-{
- return (simple_p
- ? targetm.gen_simple_return ()
- : targetm.gen_return ());
-}
-
-/* Insert an appropriate return pattern at the end of block BB. This
- also means updating block_for_insn appropriately. SIMPLE_P is
- the same as in gen_return_pattern and passed to it. */
-
-void
-emit_return_into_block (bool simple_p, basic_block bb)
-{
- rtx_jump_insn *jump = emit_jump_insn_after (gen_return_pattern (simple_p),
- BB_END (bb));
- rtx pat = PATTERN (jump);
- if (GET_CODE (pat) == PARALLEL)
- pat = XVECEXP (pat, 0, 0);
- gcc_assert (ANY_RETURN_P (pat));
- JUMP_LABEL (jump) = pat;
-}
/* Set JUMP_LABEL for a return insn. */
@@ -5811,133 +5768,89 @@ set_return_jump_label (rtx_insn *returnjump)
JUMP_LABEL (returnjump) = ret_rtx;
}
-/* Return true if there are any active insns between HEAD and TAIL. */
-bool
-active_insn_between (rtx_insn *head, rtx_insn *tail)
-{
- while (tail)
- {
- if (active_insn_p (tail))
- return true;
- if (tail == head)
- return false;
- tail = PREV_INSN (tail);
- }
- return false;
-}
+/* Return a sequence to be used as the split prologue for the current
+ function, or NULL. */
-/* LAST_BB is a block that exits, and empty of active instructions.
- Examine its predecessors for jumps that can be converted to
- (conditional) returns. */
-vec<edge>
-convert_jumps_to_returns (basic_block last_bb, bool simple_p,
- vec<edge> unconverted ATTRIBUTE_UNUSED)
+static rtx_insn *
+make_split_prologue_seq (void)
{
- int i;
- basic_block bb;
- edge_iterator ei;
- edge e;
- auto_vec<basic_block> src_bbs (EDGE_COUNT (last_bb->preds));
+ if (!flag_split_stack
+ || lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl)))
+ return NULL;
- FOR_EACH_EDGE (e, ei, last_bb->preds)
- if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
- src_bbs.quick_push (e->src);
+ start_sequence ();
+ emit_insn (targetm.gen_split_stack_prologue ());
+ rtx_insn *seq = get_insns ();
+ end_sequence ();
- rtx_insn *label = BB_HEAD (last_bb);
+ record_insns (seq, NULL, &prologue_insn_hash);
+ set_insn_locations (seq, prologue_location);
- FOR_EACH_VEC_ELT (src_bbs, i, bb)
- {
- rtx_insn *jump = BB_END (bb);
+ return seq;
+}
- if (!JUMP_P (jump) || JUMP_LABEL (jump) != label)
- continue;
+/* Return a sequence to be used as the prologue for the current function,
+ or NULL. */
- e = find_edge (bb, last_bb);
+static rtx_insn *
+make_prologue_seq (void)
+{
+ if (!targetm.have_prologue ())
+ return NULL;
- /* If we have an unconditional jump, we can replace that
- with a simple return instruction. */
- if (simplejump_p (jump))
- {
- /* The use of the return register might be present in the exit
- fallthru block. Either:
- - removing the use is safe, and we should remove the use in
- the exit fallthru block, or
- - removing the use is not safe, and we should add it here.
- For now, we conservatively choose the latter. Either of the
- 2 helps in crossjumping. */
- emit_use_return_register_into_block (bb);
-
- emit_return_into_block (simple_p, bb);
- delete_insn (jump);
- }
+ start_sequence ();
+ rtx_insn *seq = targetm.gen_prologue ();
+ emit_insn (seq);
+
+ /* Insert an explicit USE for the frame pointer
+ if the profiling is on and the frame pointer is required. */
+ if (crtl->profile && frame_pointer_needed)
+ emit_use (hard_frame_pointer_rtx);
+
+ /* Retain a map of the prologue insns. */
+ record_insns (seq, NULL, &prologue_insn_hash);
+ emit_note (NOTE_INSN_PROLOGUE_END);
+
+ /* Ensure that instructions are not moved into the prologue when
+ profiling is on. The call to the profiling routine can be
+ emitted within the live range of a call-clobbered register. */
+ if (!targetm.profile_before_prologue () && crtl->profile)
+ emit_insn (gen_blockage ());
- /* If we have a conditional jump branching to the last
- block, we can try to replace that with a conditional
- return instruction. */
- else if (condjump_p (jump))
- {
- rtx dest;
+ seq = get_insns ();
+ end_sequence ();
+ set_insn_locations (seq, prologue_location);
- if (simple_p)
- dest = simple_return_rtx;
- else
- dest = ret_rtx;
- if (!redirect_jump (as_a <rtx_jump_insn *> (jump), dest, 0))
- {
- if (targetm.have_simple_return () && simple_p)
- {
- if (dump_file)
- fprintf (dump_file,
- "Failed to redirect bb %d branch.\n", bb->index);
- unconverted.safe_push (e);
- }
- continue;
- }
+ return seq;
+}
- /* See comment in simplejump_p case above. */
- emit_use_return_register_into_block (bb);
+/* Return a sequence to be used as the epilogue for the current function,
+ or NULL. */
- /* If this block has only one successor, it both jumps
- and falls through to the fallthru block, so we can't
- delete the edge. */
- if (single_succ_p (bb))
- continue;
- }
- else
- {
- if (targetm.have_simple_return () && simple_p)
- {
- if (dump_file)
- fprintf (dump_file,
- "Failed to redirect bb %d branch.\n", bb->index);
- unconverted.safe_push (e);
- }
- continue;
- }
+static rtx_insn *
+make_epilogue_seq (void)
+{
+ if (!targetm.have_epilogue ())
+ return NULL;
- /* Fix up the CFG for the successful change we just made. */
- redirect_edge_succ (e, EXIT_BLOCK_PTR_FOR_FN (cfun));
- e->flags &= ~EDGE_CROSSING;
- }
- src_bbs.release ();
- return unconverted;
-}
+ start_sequence ();
+ emit_note (NOTE_INSN_EPILOGUE_BEG);
+ rtx_insn *seq = targetm.gen_epilogue ();
+ if (seq)
+ emit_jump_insn (seq);
-/* Emit a return insn for the exit fallthru block. */
-basic_block
-emit_return_for_exit (edge exit_fallthru_edge, bool simple_p)
-{
- basic_block last_bb = exit_fallthru_edge->src;
+ /* Retain a map of the epilogue insns. */
+ record_insns (seq, NULL, &epilogue_insn_hash);
+ set_insn_locations (seq, epilogue_location);
- if (JUMP_P (BB_END (last_bb)))
- {
- last_bb = split_edge (exit_fallthru_edge);
- exit_fallthru_edge = single_succ_edge (last_bb);
- }
- emit_barrier_after (BB_END (last_bb));
- emit_return_into_block (simple_p, last_bb);
- exit_fallthru_edge->flags &= ~EDGE_FALLTHRU;
- return last_bb;
+ seq = get_insns ();
+ rtx_insn *returnjump = get_last_insn ();
+ end_sequence ();
+
+ if (JUMP_P (returnjump))
+ set_return_jump_label (returnjump);
+
+ return seq;
}
@@ -5992,137 +5905,29 @@ emit_return_for_exit (edge exit_fallthru_edge, bool simple_p)
void
thread_prologue_and_epilogue_insns (void)
{
- bool inserted;
- vec<edge> unconverted_simple_returns = vNULL;
- bitmap_head bb_flags;
- rtx_insn *returnjump;
- rtx_insn *epilogue_end ATTRIBUTE_UNUSED;
- rtx_insn *prologue_seq ATTRIBUTE_UNUSED, *split_prologue_seq ATTRIBUTE_UNUSED;
- edge e, entry_edge, orig_entry_edge, exit_fallthru_edge;
- edge_iterator ei;
-
df_analyze ();
- rtl_profile_for_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));
-
- inserted = false;
- epilogue_end = NULL;
- returnjump = NULL;
-
/* Can't deal with multiple successors of the entry block at the
moment. Function should always have at least one entry
point. */
gcc_assert (single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
- entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
- orig_entry_edge = entry_edge;
- split_prologue_seq = NULL;
- if (flag_split_stack
- && (lookup_attribute ("no_split_stack", DECL_ATTRIBUTES (cfun->decl))
- == NULL))
- {
- start_sequence ();
- emit_insn (targetm.gen_split_stack_prologue ());
- split_prologue_seq = get_insns ();
- end_sequence ();
-
- record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
- set_insn_locations (split_prologue_seq, prologue_location);
- }
+ edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ edge orig_entry_edge = entry_edge;
- prologue_seq = NULL;
- if (targetm.have_prologue ())
- {
- start_sequence ();
- rtx_insn *seq = targetm.gen_prologue ();
- emit_insn (seq);
-
- /* Insert an explicit USE for the frame pointer
- if the profiling is on and the frame pointer is required. */
- if (crtl->profile && frame_pointer_needed)
- emit_use (hard_frame_pointer_rtx);
-
- /* Retain a map of the prologue insns. */
- record_insns (seq, NULL, &prologue_insn_hash);
- emit_note (NOTE_INSN_PROLOGUE_END);
-
- /* Ensure that instructions are not moved into the prologue when
- profiling is on. The call to the profiling routine can be
- emitted within the live range of a call-clobbered register. */
- if (!targetm.profile_before_prologue () && crtl->profile)
- emit_insn (gen_blockage ());
-
- prologue_seq = get_insns ();
- end_sequence ();
- set_insn_locations (prologue_seq, prologue_location);
- }
-
- bitmap_initialize (&bb_flags, &bitmap_default_obstack);
+ rtx_insn *split_prologue_seq = make_split_prologue_seq ();
+ rtx_insn *prologue_seq = make_prologue_seq ();
+ rtx_insn *epilogue_seq = make_epilogue_seq ();
/* Try to perform a kind of shrink-wrapping, making sure the
prologue/epilogue is emitted only around those parts of the
function that require it. */
- try_shrink_wrapping (&entry_edge, &bb_flags, prologue_seq);
+ try_shrink_wrapping (&entry_edge, prologue_seq);
- if (split_prologue_seq != NULL_RTX)
- {
- insert_insn_on_edge (split_prologue_seq, orig_entry_edge);
- inserted = true;
- }
- if (prologue_seq != NULL_RTX)
- {
- insert_insn_on_edge (prologue_seq, entry_edge);
- inserted = true;
- }
-
- /* If the exit block has no non-fake predecessors, we don't need
- an epilogue. */
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
- if ((e->flags & EDGE_FAKE) == 0)
- break;
- if (e == NULL)
- goto epilogue_done;
rtl_profile_for_bb (EXIT_BLOCK_PTR_FOR_FN (cfun));
- exit_fallthru_edge = find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds);
-
- if (targetm.have_simple_return () && entry_edge != orig_entry_edge)
- exit_fallthru_edge
- = get_unconverted_simple_return (exit_fallthru_edge, bb_flags,
- &unconverted_simple_returns,
- &returnjump);
- if (targetm.have_return ())
- {
- if (exit_fallthru_edge == NULL)
- goto epilogue_done;
-
- if (optimize)
- {
- basic_block last_bb = exit_fallthru_edge->src;
-
- if (LABEL_P (BB_HEAD (last_bb))
- && !active_insn_between (BB_HEAD (last_bb), BB_END (last_bb)))
- convert_jumps_to_returns (last_bb, false, vNULL);
-
- if (EDGE_COUNT (last_bb->preds) != 0
- && single_succ_p (last_bb))
- {
- last_bb = emit_return_for_exit (exit_fallthru_edge, false);
- epilogue_end = returnjump = BB_END (last_bb);
-
- /* Emitting the return may add a basic block.
- Fix bb_flags for the added block. */
- if (targetm.have_simple_return ()
- && last_bb != exit_fallthru_edge->src)
- bitmap_set_bit (&bb_flags, last_bb->index);
-
- goto epilogue_done;
- }
- }
- }
-
/* A small fib -- epilogue is not yet completed, but we wish to re-use
this marker for the splits of EH_RETURN patterns, and nothing else
uses the flag in the meantime. */
@@ -6133,6 +5938,8 @@ thread_prologue_and_epilogue_insns (void)
code. In order to be able to properly annotate these with unwind
info, try to split them now. If we get a valid split, drop an
EPILOGUE_BEG note and mark the insns as epilogue insns. */
+ edge e;
+ edge_iterator ei;
FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
{
rtx_insn *prev, *last, *trial;
@@ -6152,105 +5959,85 @@ thread_prologue_and_epilogue_insns (void)
emit_note_after (NOTE_INSN_EPILOGUE_BEG, prev);
}
- /* If nothing falls through into the exit block, we don't need an
- epilogue. */
+ edge exit_fallthru_edge = find_fallthru_edge (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds);
- if (exit_fallthru_edge == NULL)
- goto epilogue_done;
-
- if (targetm.have_epilogue ())
+ if (exit_fallthru_edge)
{
- start_sequence ();
- epilogue_end = emit_note (NOTE_INSN_EPILOGUE_BEG);
- rtx_insn *seq = targetm.gen_epilogue ();
- if (seq)
- emit_jump_insn (seq);
-
- /* Retain a map of the epilogue insns. */
- record_insns (seq, NULL, &epilogue_insn_hash);
- set_insn_locations (seq, epilogue_location);
-
- seq = get_insns ();
- returnjump = get_last_insn ();
- end_sequence ();
-
- insert_insn_on_edge (seq, exit_fallthru_edge);
- inserted = true;
-
- if (JUMP_P (returnjump))
- set_return_jump_label (returnjump);
- }
- else
- {
- basic_block cur_bb;
+ if (epilogue_seq)
+ {
+ insert_insn_on_edge (epilogue_seq, exit_fallthru_edge);
+ commit_edge_insertions ();
- if (! next_active_insn (BB_END (exit_fallthru_edge->src)))
- goto epilogue_done;
- /* We have a fall-through edge to the exit block, the source is not
- at the end of the function, and there will be an assembler epilogue
- at the end of the function.
- We can't use force_nonfallthru here, because that would try to
- use return. Inserting a jump 'by hand' is extremely messy, so
- we take advantage of cfg_layout_finalize using
- fixup_fallthru_exit_predecessor. */
- cfg_layout_initialize (0);
- FOR_EACH_BB_FN (cur_bb, cfun)
- if (cur_bb->index >= NUM_FIXED_BLOCKS
- && cur_bb->next_bb->index >= NUM_FIXED_BLOCKS)
- cur_bb->aux = cur_bb->next_bb;
- cfg_layout_finalize ();
+ /* The epilogue insns we inserted may cause the exit edge to no longer
+ be fallthru. */
+ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
+ {
+ if (((e->flags & EDGE_FALLTHRU) != 0)
+ && returnjump_p (BB_END (e->src)))
+ e->flags &= ~EDGE_FALLTHRU;
+ }
+ }
+ else if (next_active_insn (BB_END (exit_fallthru_edge->src)))
+ {
+ /* We have a fall-through edge to the exit block, the source is not
+ at the end of the function, and there will be an assembler epilogue
+ at the end of the function.
+ We can't use force_nonfallthru here, because that would try to
+ use return. Inserting a jump 'by hand' is extremely messy, so
+ we take advantage of cfg_layout_finalize using
+ fixup_fallthru_exit_predecessor. */
+ cfg_layout_initialize (0);
+ basic_block cur_bb;
+ FOR_EACH_BB_FN (cur_bb, cfun)
+ if (cur_bb->index >= NUM_FIXED_BLOCKS
+ && cur_bb->next_bb->index >= NUM_FIXED_BLOCKS)
+ cur_bb->aux = cur_bb->next_bb;
+ cfg_layout_finalize ();
+ }
}
-epilogue_done:
+ /* Insert the prologue. */
- default_rtl_profile ();
+ rtl_profile_for_bb (ENTRY_BLOCK_PTR_FOR_FN (cfun));
- if (inserted)
+ if (split_prologue_seq || prologue_seq)
{
- sbitmap blocks;
+ if (split_prologue_seq)
+ insert_insn_on_edge (split_prologue_seq, orig_entry_edge);
+
+ if (prologue_seq)
+ insert_insn_on_edge (prologue_seq, entry_edge);
commit_edge_insertions ();
/* Look for basic blocks within the prologue insns. */
- blocks = sbitmap_alloc (last_basic_block_for_fn (cfun));
+ sbitmap blocks = sbitmap_alloc (last_basic_block_for_fn (cfun));
bitmap_clear (blocks);
bitmap_set_bit (blocks, entry_edge->dest->index);
bitmap_set_bit (blocks, orig_entry_edge->dest->index);
find_many_sub_basic_blocks (blocks);
sbitmap_free (blocks);
-
- /* The epilogue insns we inserted may cause the exit edge to no longer
- be fallthru. */
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
- {
- if (((e->flags & EDGE_FALLTHRU) != 0)
- && returnjump_p (BB_END (e->src)))
- e->flags &= ~EDGE_FALLTHRU;
- }
}
- if (targetm.have_simple_return ())
- convert_to_simple_return (entry_edge, orig_entry_edge, bb_flags,
- returnjump, unconverted_simple_returns);
+ default_rtl_profile ();
/* Emit sibling epilogues before any sibling call sites. */
- for (ei = ei_start (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); (e =
- ei_safe_edge (ei));
- )
- {
- basic_block bb = e->src;
- rtx_insn *insn = BB_END (bb);
-
- if (!CALL_P (insn)
- || ! SIBLING_CALL_P (insn)
- || (targetm.have_simple_return ()
- && entry_edge != orig_entry_edge
- && !bitmap_bit_p (&bb_flags, bb->index)))
+ for (ei = ei_start (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds);
+ (e = ei_safe_edge (ei));
+ ei_next (&ei))
+ {
+ /* Skip those already handled, the ones that run without prologue. */
+ if (e->flags & EDGE_IGNORE)
{
- ei_next (&ei);
+ e->flags &= ~EDGE_IGNORE;
continue;
}
+ rtx_insn *insn = BB_END (e->src);
+
+ if (!(CALL_P (insn) && SIBLING_CALL_P (insn)))
+ continue;
+
if (rtx_insn *ep_seq = targetm.gen_sibcall_epilogue ())
{
start_sequence ();
@@ -6267,10 +6054,9 @@ epilogue_done:
emit_insn_before (seq, insn);
}
- ei_next (&ei);
}
- if (epilogue_end)
+ if (epilogue_seq)
{
rtx_insn *insn, *next;
@@ -6279,17 +6065,15 @@ epilogue_done:
of such a note. Also possibly move
NOTE_INSN_FUNCTION_BEG notes, as those can be relevant for debug
info generation. */
- for (insn = epilogue_end; insn; insn = next)
+ for (insn = epilogue_seq; insn; insn = next)
{
next = NEXT_INSN (insn);
if (NOTE_P (insn)
&& (NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG))
- reorder_insns (insn, insn, PREV_INSN (epilogue_end));
+ reorder_insns (insn, insn, PREV_INSN (epilogue_seq));
}
}
- bitmap_clear (&bb_flags);
-
/* Threading the prologue and epilogue changes the artificial refs
in the entry and exit blocks. */
epilogue_completed = 1;
@@ -6578,8 +6362,10 @@ make_pass_leaf_regs (gcc::context *ctxt)
static unsigned int
rest_of_handle_thread_prologue_and_epilogue (void)
{
+ /* prepare_shrink_wrap is sensitive to the block structure of the control
+ flow graph, so clean it up first. */
if (optimize)
- cleanup_cfg (CLEANUP_EXPENSIVE);
+ cleanup_cfg (0);
/* On some machines, the prologue and epilogue code, or parts thereof,
can be represented as RTL. Doing so lets us schedule insns between
@@ -6593,7 +6379,7 @@ rest_of_handle_thread_prologue_and_epilogue (void)
/* Shrink-wrapping can result in unreachable edges in the epilogue,
see PR57320. */
- cleanup_cfg (0);
+ cleanup_cfg (optimize ? CLEANUP_EXPENSIVE : 0);
/* The stack usage info is finalized during prologue expansion. */
if (flag_stack_usage_info)
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index d8cb9fa3bbb..7834bca7f51 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -1461,7 +1461,6 @@ static unsigned int
fwprop (void)
{
unsigned i;
- bool need_cleanup = false;
fwprop_init ();
@@ -1479,12 +1478,10 @@ fwprop (void)
|| DF_REF_BB (use)->loop_father == NULL
/* The outer most loop is not really a loop. */
|| loop_outer (DF_REF_BB (use)->loop_father) == NULL)
- need_cleanup |= forward_propagate_into (use);
+ forward_propagate_into (use);
}
fwprop_done ();
- if (need_cleanup)
- cleanup_cfg (0);
return 0;
}
@@ -1528,7 +1525,6 @@ static unsigned int
fwprop_addr (void)
{
unsigned i;
- bool need_cleanup = false;
fwprop_init ();
@@ -1542,13 +1538,10 @@ fwprop_addr (void)
&& DF_REF_BB (use)->loop_father != NULL
/* The outer most loop is not really a loop. */
&& loop_outer (DF_REF_BB (use)->loop_father) != NULL)
- need_cleanup |= forward_propagate_into (use);
+ forward_propagate_into (use);
}
fwprop_done ();
-
- if (need_cleanup)
- cleanup_cfg (0);
return 0;
}
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 1af59209b31..7bcf3b375e5 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -989,9 +989,18 @@ proper position among the other output files. */
the vtable verification runtime functions are in libstdc++, so we use
the spec just below this one. */
#ifndef VTABLE_VERIFICATION_SPEC
+#if ENABLE_VTABLE_VERIFY
#define VTABLE_VERIFICATION_SPEC "\
%{!nostdlib:%{fvtable-verify=std: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}\
%{fvtable-verify=preinit: -lvtv -u_vtable_map_vars_start -u_vtable_map_vars_end}}"
+#else
+#define VTABLE_VERIFICATION_SPEC "\
+%{fvtable-verify=none:} \
+%{fvtable-verify=std: \
+ %e-fvtable-verify=std is not supported in this configuration} \
+%{fvtable-verify=preinit: \
+ %e-fvtable-verify=preinit is not supported in this configuration}"
+#endif
#endif
#ifndef CHKP_SPEC
diff --git a/gcc/genattr-common.c b/gcc/genattr-common.c
index e073faf7509..a11fbf707b1 100644
--- a/gcc/genattr-common.c
+++ b/gcc/genattr-common.c
@@ -61,7 +61,7 @@ gen_attr (md_rtx_info *info)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
bool have_delay = false;
bool have_sched = false;
diff --git a/gcc/genattr.c b/gcc/genattr.c
index c6db37fa942..77380e7f26b 100644
--- a/gcc/genattr.c
+++ b/gcc/genattr.c
@@ -138,7 +138,7 @@ find_tune_attr (rtx exp)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
bool have_annul_true = false;
bool have_annul_false = false;
@@ -240,11 +240,11 @@ main (int argc, char **argv)
printf ("/* Insn latency time on data consumed by the 2nd insn.\n");
printf (" Use the function if bypass_p returns nonzero for\n");
printf (" the 1st insn. */\n");
- printf ("extern int insn_latency (rtx, rtx);\n\n");
+ printf ("extern int insn_latency (rtx_insn *, rtx_insn *);\n\n");
printf ("/* Maximal insn latency time possible of all bypasses for this insn.\n");
printf (" Use the function if bypass_p returns nonzero for\n");
printf (" the 1st insn. */\n");
- printf ("extern int maximal_insn_latency (rtx);\n\n");
+ printf ("extern int maximal_insn_latency (rtx_insn *);\n\n");
printf ("\n#if AUTOMATON_ALTS\n");
printf ("/* The following function returns number of alternative\n");
printf (" reservations of given insn. It may be used for better\n");
@@ -290,8 +290,8 @@ main (int argc, char **argv)
printf (" state_transition should return negative value for\n");
printf (" the insn and the state). Data dependencies between\n");
printf (" the insns are ignored by the function. */\n");
- printf
- ("extern int min_insn_conflict_delay (state_t, rtx, rtx);\n");
+ printf ("extern int "
+ "min_insn_conflict_delay (state_t, rtx_insn *, rtx_insn *);\n");
printf ("/* The following function outputs reservations for given\n");
printf (" insn as they are described in the corresponding\n");
printf (" define_insn_reservation. */\n");
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index c956527cd42..d39d4a70e92 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -5197,7 +5197,7 @@ handle_arg (const char *arg)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
struct attr_desc *attr;
struct insn_def *id;
diff --git a/gcc/genautomata.c b/gcc/genautomata.c
index e3a6c59056d..92c8b5c390f 100644
--- a/gcc/genautomata.c
+++ b/gcc/genautomata.c
@@ -8113,14 +8113,10 @@ output_internal_trans_func (void)
/* Output code
- if (insn != 0)
- {
- insn_code = dfa_insn_code (insn);
- if (insn_code > DFA__ADVANCE_CYCLE)
- return code;
- }
- else
- insn_code = DFA__ADVANCE_CYCLE;
+ gcc_checking_assert (insn != 0);
+ insn_code = dfa_insn_code (insn);
+ if (insn_code >= DFA__ADVANCE_CYCLE)
+ return code;
where insn denotes INSN_NAME, insn_code denotes INSN_CODE_NAME, and
code denotes CODE. */
@@ -8129,21 +8125,12 @@ output_internal_insn_code_evaluation (const char *insn_name,
const char *insn_code_name,
int code)
{
- fprintf (output_file, "\n if (%s == 0)\n", insn_name);
- fprintf (output_file, " %s = %s;\n\n",
- insn_code_name, ADVANCE_CYCLE_VALUE_NAME);
- if (collapse_flag)
- {
- fprintf (output_file, "\n else if (%s == const0_rtx)\n", insn_name);
- fprintf (output_file, " %s = %s;\n\n",
- insn_code_name, COLLAPSE_NDFA_VALUE_NAME);
- }
- fprintf (output_file, "\n else\n {\n");
- fprintf (output_file,
- " %s = %s (as_a <rtx_insn *> (%s));\n",
- insn_code_name, DFA_INSN_CODE_FUNC_NAME, insn_name);
- fprintf (output_file, " if (%s > %s)\n return %d;\n }\n",
- insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
+ fprintf (output_file, " gcc_checking_assert (%s != 0);\n"
+ " %s = %s (%s);\n"
+ " if (%s >= %s)\n return %d;\n",
+ insn_name,
+ insn_code_name, DFA_INSN_CODE_FUNC_NAME, insn_name,
+ insn_code_name, ADVANCE_CYCLE_VALUE_NAME, code);
}
@@ -8204,8 +8191,22 @@ output_trans_func (void)
TRANSITION_FUNC_NAME, STATE_TYPE_NAME, STATE_NAME,
INSN_PARAMETER_NAME);
fprintf (output_file, "{\n int %s;\n", INTERNAL_INSN_CODE_NAME);
- output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
- INTERNAL_INSN_CODE_NAME, -1);
+ fprintf (output_file, "\n if (%s == 0)\n", INSN_PARAMETER_NAME);
+ fprintf (output_file, " %s = %s;\n",
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
+ if (collapse_flag)
+ {
+ fprintf (output_file, " else if (%s == const0_rtx)\n",
+ INSN_PARAMETER_NAME);
+ fprintf (output_file, " %s = %s;\n",
+ INTERNAL_INSN_CODE_NAME, COLLAPSE_NDFA_VALUE_NAME);
+ }
+ fprintf (output_file, " else\n {\n");
+ fprintf (output_file, " %s = %s (as_a <rtx_insn *> (%s));\n",
+ INTERNAL_INSN_CODE_NAME, DFA_INSN_CODE_FUNC_NAME,
+ INSN_PARAMETER_NAME);
+ fprintf (output_file, " if (%s > %s)\n return -1;\n }\n",
+ INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
fprintf (output_file, " return %s (%s, (struct %s *) %s);\n}\n\n",
INTERNAL_TRANSITION_FUNC_NAME, INTERNAL_INSN_CODE_NAME, CHIP_NAME, STATE_NAME);
}
@@ -8297,7 +8298,7 @@ static void
output_min_insn_conflict_delay_func (void)
{
fprintf (output_file,
- "int\n%s (%s %s, rtx %s, rtx %s)\n",
+ "int\n%s (%s %s, rtx_insn *%s, rtx_insn *%s)\n",
MIN_INSN_CONFLICT_DELAY_FUNC_NAME, STATE_TYPE_NAME,
STATE_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
fprintf (output_file, "{\n struct %s %s;\n int %s, %s, transition;\n",
@@ -8366,10 +8367,12 @@ output_internal_insn_latency_func (void)
decl_t decl;
struct bypass_decl *bypass;
- fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\tint %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
- INTERNAL_INSN_LATENCY_FUNC_NAME, INTERNAL_INSN_CODE_NAME,
- INTERNAL_INSN2_CODE_NAME, "insn_or_const0",
- "insn2_or_const0");
+ fprintf (output_file, "static int\n"
+ "%s (int %s ATTRIBUTE_UNUSED, int %s ATTRIBUTE_UNUSED,\n"
+ "\trtx_insn *%s ATTRIBUTE_UNUSED, rtx_insn *%s ATTRIBUTE_UNUSED)\n",
+ INTERNAL_INSN_LATENCY_FUNC_NAME,
+ INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME,
+ INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
fprintf (output_file, "{\n");
if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
@@ -8378,32 +8381,6 @@ output_internal_insn_latency_func (void)
return;
}
- fprintf (output_file, " if (%s >= %s || %s >= %s)\n return 0;\n",
- INTERNAL_INSN_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME,
- INTERNAL_INSN2_CODE_NAME, ADVANCE_CYCLE_VALUE_NAME);
-
- /* We've now rejected the case that
- INTERNAL_INSN_CODE_NAME >= ADVANCE_CYCLE_VALUE_NAME
- i.e. that
- insn_code >= DFA__ADVANCE_CYCLE,
- and similarly for insn2_code. */
- fprintf (output_file,
- " /* Within output_internal_insn_code_evaluation, the generated\n"
- " code sets \"code\" to NDFA__COLLAPSE for const0_rtx, and\n"
- " NDFA__COLLAPSE > DFA__ADVANCE_CYCLE. Hence we can't be\n"
- " dealing with const0_rtx instances at this point. */\n");
- if (collapse_flag)
- fprintf (output_file,
- " gcc_assert (NDFA__COLLAPSE > DFA__ADVANCE_CYCLE);\n");
- fprintf (output_file,
- (" gcc_assert (insn_or_const0 != const0_rtx);\n"
- " rtx_insn *%s ATTRIBUTE_UNUSED = safe_as_a <rtx_insn *> (insn_or_const0);\n"),
- INSN_PARAMETER_NAME);
- fprintf (output_file,
- (" gcc_assert (insn2_or_const0 != const0_rtx);\n"
- " rtx_insn *%s ATTRIBUTE_UNUSED = safe_as_a <rtx_insn *> (insn2_or_const0);\n"),
- INSN2_PARAMETER_NAME);
-
fprintf (output_file, " switch (%s)\n {\n", INTERNAL_INSN_CODE_NAME);
for (i = 0; i < description->decls_num; i++)
if (description->decls[i]->mode == dm_insn_reserv
@@ -8466,9 +8443,8 @@ output_internal_maximal_insn_latency_func (void)
int i;
int max;
- fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED,\n\trtx %s ATTRIBUTE_UNUSED)\n",
- "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME,
- INSN_PARAMETER_NAME);
+ fprintf (output_file, "static int\n%s (int %s ATTRIBUTE_UNUSED)\n",
+ "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME);
fprintf (output_file, "{\n");
if (DECL_INSN_RESERV (advance_cycle_insn_decl)->insn_num == 0)
@@ -8505,7 +8481,7 @@ output_internal_maximal_insn_latency_func (void)
static void
output_insn_latency_func (void)
{
- fprintf (output_file, "int\n%s (rtx %s, rtx %s)\n",
+ fprintf (output_file, "int\n%s (rtx_insn *%s, rtx_insn *%s)\n",
INSN_LATENCY_FUNC_NAME, INSN_PARAMETER_NAME, INSN2_PARAMETER_NAME);
fprintf (output_file, "{\n int %s, %s;\n",
INTERNAL_INSN_CODE_NAME, INTERNAL_INSN2_CODE_NAME);
@@ -8523,15 +8499,14 @@ output_insn_latency_func (void)
static void
output_maximal_insn_latency_func (void)
{
- fprintf (output_file, "int\n%s (rtx %s)\n",
+ fprintf (output_file, "int\n%s (rtx_insn *%s)\n",
"maximal_insn_latency", INSN_PARAMETER_NAME);
fprintf (output_file, "{\n int %s;\n",
INTERNAL_INSN_CODE_NAME);
output_internal_insn_code_evaluation (INSN_PARAMETER_NAME,
INTERNAL_INSN_CODE_NAME, 0);
- fprintf (output_file, " return %s (%s, %s);\n}\n\n",
- "internal_maximal_insn_latency",
- INTERNAL_INSN_CODE_NAME, INSN_PARAMETER_NAME);
+ fprintf (output_file, " return %s (%s);\n}\n\n",
+ "internal_maximal_insn_latency", INTERNAL_INSN_CODE_NAME);
}
/* The function outputs PHR interface function `print_reservation'. */
@@ -9300,7 +9275,7 @@ parse_automata_opt (const char *str)
/* The following is top level function to initialize the work of
pipeline hazards description translator. */
static void
-initiate_automaton_gen (char **argv)
+initiate_automaton_gen (const char **argv)
{
const char *base_name;
@@ -9592,7 +9567,7 @@ write_automata (void)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "genautomata";
diff --git a/gcc/gencodes.c b/gcc/gencodes.c
index e0dd32a9075..3b0fc5ce9f8 100644
--- a/gcc/gencodes.c
+++ b/gcc/gencodes.c
@@ -47,7 +47,7 @@ gen_insn (md_rtx_info *info)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "gencodes";
diff --git a/gcc/genconditions.c b/gcc/genconditions.c
index 8abf1c243a9..e4f45b097cd 100644
--- a/gcc/genconditions.c
+++ b/gcc/genconditions.c
@@ -212,7 +212,7 @@ write_writer (void)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "genconditions";
diff --git a/gcc/genconfig.c b/gcc/genconfig.c
index b6ca35ae6c4..815e30d7330 100644
--- a/gcc/genconfig.c
+++ b/gcc/genconfig.c
@@ -269,7 +269,7 @@ gen_peephole2 (md_rtx_info *info)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "genconfig";
diff --git a/gcc/genconstants.c b/gcc/genconstants.c
index b96bc509018..c10e3e34cd1 100644
--- a/gcc/genconstants.c
+++ b/gcc/genconstants.c
@@ -75,7 +75,7 @@ print_enum_type (void **slot, void *info ATTRIBUTE_UNUSED)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "genconstants";
diff --git a/gcc/genemit.c b/gcc/genemit.c
index 87f53010926..33040aac36d 100644
--- a/gcc/genemit.c
+++ b/gcc/genemit.c
@@ -745,7 +745,7 @@ output_peephole2_scratches (rtx split)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "genemit";
diff --git a/gcc/genenums.c b/gcc/genenums.c
index d0d80a662c5..db46a67b591 100644
--- a/gcc/genenums.c
+++ b/gcc/genenums.c
@@ -45,7 +45,7 @@ print_enum_type (void **slot, void *info ATTRIBUTE_UNUSED)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "genenums";
diff --git a/gcc/genextract.c b/gcc/genextract.c
index 52227b5645a..d5917813436 100644
--- a/gcc/genextract.c
+++ b/gcc/genextract.c
@@ -394,7 +394,7 @@ insn_extract (rtx_insn *insn)\n{\n\
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
unsigned int i;
struct extraction *p;
diff --git a/gcc/genflags.c b/gcc/genflags.c
index 5c3fa795539..8b37b151a1d 100644
--- a/gcc/genflags.c
+++ b/gcc/genflags.c
@@ -198,7 +198,7 @@ gen_insn (md_rtx_info *info)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
rtx dummy;
rtx *insns;
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index be496609dba..5479b8f09ab 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -1709,7 +1709,7 @@ open_base_files (void)
"config.h", "system.h", "coretypes.h", "backend.h", "predict.h", "tree.h",
"rtl.h", "gimple.h", "fold-const.h", "insn-codes.h", "splay-tree.h",
"alias.h", "insn-config.h", "flags.h", "expmed.h", "dojump.h",
- "explow.h", "calls.h", "emit-rtl.h", "varasm.h", "stmt.h",
+ "explow.h", "calls.h", "cilk.h", "emit-rtl.h", "varasm.h", "stmt.h",
"expr.h", "alloc-pool.h", "cselib.h", "insn-addr.h", "optabs.h",
"libfuncs.h", "debug.h", "internal-fn.h", "gimple-fold.h", "tree-eh.h",
"gimple-iterator.h", "gimple-ssa.h", "tree-cfg.h",
diff --git a/gcc/genmddeps.c b/gcc/genmddeps.c
index 078053142a9..fd26a3335f4 100644
--- a/gcc/genmddeps.c
+++ b/gcc/genmddeps.c
@@ -40,7 +40,7 @@ add_filedep (const char *pathname)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
struct filedep *d;
diff --git a/gcc/genmddump.c b/gcc/genmddump.c
index 35bc79c3c51..a9c93a83122 100644
--- a/gcc/genmddump.c
+++ b/gcc/genmddump.c
@@ -35,10 +35,10 @@
#include "gensupport.h"
-extern int main (int, char **);
+extern int main (int, const char **);
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "genmddump";
@@ -57,4 +57,3 @@ main (int argc, char **argv)
fflush (stdout);
return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
}
-
diff --git a/gcc/genmodes.c b/gcc/genmodes.c
index 2bfba3ef1b2..788031b7fff 100644
--- a/gcc/genmodes.c
+++ b/gcc/genmodes.c
@@ -66,6 +66,7 @@ struct mode_data
this mode as a component. */
struct mode_data *next_cont; /* Next mode in that list. */
+ struct mode_data *complex; /* complex type with mode as component. */
const char *file; /* file and line of definition, */
unsigned int line; /* for error reporting */
unsigned int counter; /* Rank ordering of modes */
@@ -83,7 +84,7 @@ static struct mode_data *void_mode;
static const struct mode_data blank_mode = {
0, "<unknown>", MAX_MODE_CLASS,
-1U, -1U, -1U, -1U,
- 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0,
"<unknown>", 0, 0, 0, 0, false, 0
};
@@ -472,6 +473,7 @@ make_complex_modes (enum mode_class cl,
c = new_mode (cclass, buf, file, line);
c->component = m;
+ m->complex = c;
}
}
@@ -1381,6 +1383,22 @@ emit_mode_wider (void)
}
static void
+emit_mode_complex (void)
+{
+ int c;
+ struct mode_data *m;
+
+ print_decl ("unsigned char", "mode_complex", "NUM_MACHINE_MODES");
+
+ for_all_modes (c, m)
+ tagged_printf ("%smode",
+ m->complex ? m->complex->name : void_mode->name,
+ m->name);
+
+ print_closer ();
+}
+
+static void
emit_mode_mask (void)
{
int c;
@@ -1745,6 +1763,7 @@ emit_insn_modes_c (void)
emit_mode_size ();
emit_mode_nunits ();
emit_mode_wider ();
+ emit_mode_complex ();
emit_mode_mask ();
emit_mode_inner ();
emit_mode_unit_size ();
diff --git a/gcc/genopinit.c b/gcc/genopinit.c
index 6d7ad4ffc38..5f4f354384e 100644
--- a/gcc/genopinit.c
+++ b/gcc/genopinit.c
@@ -105,7 +105,7 @@ open_outfile (const char *file_name)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
FILE *h_file, *s_file;
unsigned int i, j, n, last_kind[5];
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 6ca1bb89cf7..f8c25ac4df0 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -983,10 +983,10 @@ init_insn_for_nothing (void)
idata_end = &idata->next;
}
-extern int main (int, char **);
+extern int main (int, const char **);
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "genoutput";
diff --git a/gcc/genpeep.c b/gcc/genpeep.c
index aef9c74145f..132cdced690 100644
--- a/gcc/genpeep.c
+++ b/gcc/genpeep.c
@@ -340,10 +340,10 @@ print_code (RTX_CODE code)
putchar (TOUPPER (*p1));
}
-extern int main (int, char **);
+extern int main (int, const char **);
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
max_opno = -1;
diff --git a/gcc/genpreds.c b/gcc/genpreds.c
index c0d7ce4146c..dd7dbbfc6b7 100644
--- a/gcc/genpreds.c
+++ b/gcc/genpreds.c
@@ -1618,7 +1618,7 @@ parse_option (const char *opt)
/* Master control. */
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = argv[0];
if (argc <= 1)
diff --git a/gcc/genrecog.c b/gcc/genrecog.c
index 47e42660fcc..a9f5a4a1300 100644
--- a/gcc/genrecog.c
+++ b/gcc/genrecog.c
@@ -5223,7 +5223,7 @@ remove_clobbers (acceptance_type *acceptance_ptr, rtx *pattern_ptr)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
state insn_root, split_root, peephole2_root;
diff --git a/gcc/gensupport.c b/gcc/gensupport.c
index 8c5a1ab8602..0eb45919ec8 100644
--- a/gcc/gensupport.c
+++ b/gcc/gensupport.c
@@ -2501,7 +2501,7 @@ check_define_attr_duplicates ()
/* The entry point for initializing the reader. */
bool
-init_rtx_reader_args_cb (int argc, char **argv,
+init_rtx_reader_args_cb (int argc, const char **argv,
bool (*parse_opt) (const char *))
{
/* Prepare to read input. */
@@ -2538,7 +2538,7 @@ init_rtx_reader_args_cb (int argc, char **argv,
/* Programs that don't have their own options can use this entry point
instead. */
bool
-init_rtx_reader_args (int argc, char **argv)
+init_rtx_reader_args (int argc, const char **argv)
{
return init_rtx_reader_args_cb (argc, argv, 0);
}
diff --git a/gcc/gensupport.h b/gcc/gensupport.h
index 3620afd6b9e..645512c23f4 100644
--- a/gcc/gensupport.h
+++ b/gcc/gensupport.h
@@ -125,8 +125,9 @@ struct optab_pattern
};
extern rtx add_implicit_parallel (rtvec);
-extern bool init_rtx_reader_args_cb (int, char **, bool (*)(const char *));
-extern bool init_rtx_reader_args (int, char **);
+extern bool init_rtx_reader_args_cb (int, const char **,
+ bool (*)(const char *));
+extern bool init_rtx_reader_args (int, const char **);
extern bool read_md_rtx (md_rtx_info *);
extern unsigned int get_num_insn_codes ();
diff --git a/gcc/gentarget-def.c b/gcc/gentarget-def.c
index 606d7292767..adbb564ed46 100644
--- a/gcc/gentarget-def.c
+++ b/gcc/gentarget-def.c
@@ -279,7 +279,7 @@ add_insn (md_rtx_info *info)
}
int
-main (int argc, char **argv)
+main (int argc, const char **argv)
{
progname = "gentarget-def";
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 5607598210b..858f4844426 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -542,7 +542,7 @@ gimplify_and_update_call_from_tree (gimple_stmt_iterator *si_p, tree expr)
}
else
{
- tree tmp = get_initialized_tmp_var (expr, &stmts, NULL);
+ tree tmp = force_gimple_operand (expr, &stmts, false, NULL_TREE);
new_stmt = gimple_build_assign (lhs, tmp);
i = gsi_last (stmts);
gsi_insert_after_without_update (&i, new_stmt,
@@ -3039,10 +3039,25 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
}
if (targets.length () == 1)
{
- gimple_call_set_fndecl (stmt, targets[0]->decl);
+ tree fndecl = targets[0]->decl;
+ gimple_call_set_fndecl (stmt, fndecl);
changed = true;
+ /* If changing the call to __cxa_pure_virtual
+ or similar noreturn function, adjust gimple_call_fntype
+ too. */
+ if ((gimple_call_flags (stmt) & ECF_NORETURN)
+ && VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl)))
+ && TYPE_ARG_TYPES (TREE_TYPE (fndecl))
+ && (TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (fndecl)))
+ == void_type_node))
+ gimple_call_set_fntype (stmt, TREE_TYPE (fndecl));
/* If the call becomes noreturn, remove the lhs. */
- if (lhs && (gimple_call_flags (stmt) & ECF_NORETURN))
+ if (lhs
+ && (gimple_call_flags (stmt) & ECF_NORETURN)
+ && (VOID_TYPE_P (TREE_TYPE (gimple_call_fntype (stmt)))
+ || ((TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))
+ == INTEGER_CST)
+ && !TREE_ADDRESSABLE (TREE_TYPE (lhs)))))
{
if (TREE_CODE (lhs) == SSA_NAME)
{
@@ -3525,7 +3540,9 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
{
bool changed = false;
gimple *stmt = gsi_stmt (*gsi);
+ bool nowarning = gimple_no_warning_p (stmt);
unsigned i;
+ fold_defer_overflow_warnings ();
/* First do required canonicalization of [TARGET_]MEM_REF addresses
after propagation.
@@ -3818,6 +3835,7 @@ fold_stmt_1 (gimple_stmt_iterator *gsi, bool inplace, tree (*valueize) (tree))
}
}
+ fold_undefer_overflow_warnings (changed && !nowarning, stmt, 0);
return changed;
}
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index eb90d481a7d..9ea17af6637 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -740,7 +740,9 @@ lower_builtin_setjmp (gimple_stmt_iterator *gsi)
passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver. */
FORCED_LABEL (next_label) = 1;
- dest = gimple_call_lhs (stmt);
+ tree orig_dest = dest = gimple_call_lhs (stmt);
+ if (orig_dest && TREE_CODE (orig_dest) == SSA_NAME)
+ dest = create_tmp_reg (TREE_TYPE (orig_dest));
/* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert. */
arg = build_addr (next_label);
@@ -789,6 +791,13 @@ lower_builtin_setjmp (gimple_stmt_iterator *gsi)
g = gimple_build_label (cont_label);
gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ /* Build orig_dest = dest if necessary. */
+ if (dest != orig_dest)
+ {
+ g = gimple_build_assign (orig_dest, dest);
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ }
+
/* Remove the call to __builtin_setjmp. */
gsi_remove (gsi, false);
}
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index e27214fd1a8..48edacce148 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -478,6 +478,24 @@ dump_ternary_rhs (pretty_printer *buffer, gassign *gs, int spc, int flags)
pp_greater (buffer);
break;
+ case BIT_INSERT_EXPR:
+ pp_string (buffer, "BIT_INSERT_EXPR <");
+ dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
+ pp_string (buffer, ", ");
+ dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
+ pp_string (buffer, " (");
+ if (INTEGRAL_TYPE_P (TREE_TYPE (gimple_assign_rhs2 (gs))))
+ pp_decimal_int (buffer,
+ TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs2 (gs))));
+ else
+ dump_generic_node (buffer,
+ TYPE_SIZE (TREE_TYPE (gimple_assign_rhs2 (gs))),
+ spc, flags, false);
+ pp_string (buffer, " bits)>");
+ break;
+
default:
gcc_unreachable ();
}
@@ -632,17 +650,37 @@ pp_points_to_solution (pretty_printer *buffer, struct pt_solution *pt)
}
pp_right_brace (buffer);
if (pt->vars_contains_nonlocal
- && pt->vars_contains_escaped_heap)
- pp_string (buffer, " (nonlocal, escaped heap)");
- else if (pt->vars_contains_nonlocal
- && pt->vars_contains_escaped)
- pp_string (buffer, " (nonlocal, escaped)");
- else if (pt->vars_contains_nonlocal)
- pp_string (buffer, " (nonlocal)");
- else if (pt->vars_contains_escaped_heap)
- pp_string (buffer, " (escaped heap)");
- else if (pt->vars_contains_escaped)
- pp_string (buffer, " (escaped)");
+ || pt->vars_contains_escaped
+ || pt->vars_contains_escaped_heap
+ || pt->vars_contains_restrict)
+ {
+ const char *comma = "";
+ pp_string (buffer, " (");
+ if (pt->vars_contains_nonlocal)
+ {
+ pp_string (buffer, "nonlocal");
+ comma = ", ";
+ }
+ if (pt->vars_contains_escaped)
+ {
+ pp_string (buffer, comma);
+ pp_string (buffer, "escaped");
+ comma = ", ";
+ }
+ if (pt->vars_contains_escaped_heap)
+ {
+ pp_string (buffer, comma);
+ pp_string (buffer, "escaped heap");
+ comma = ", ";
+ }
+ if (pt->vars_contains_restrict)
+ {
+ pp_string (buffer, comma);
+ pp_string (buffer, "restrict");
+ }
+ pp_string (buffer, ")");
+ }
+
}
}
@@ -722,6 +760,8 @@ dump_gimple_call (pretty_printer *buffer, gcall *gs, int spc, int flags)
pp_string (buffer, " [return slot optimization]");
if (gimple_call_tail_p (gs))
pp_string (buffer, " [tail call]");
+ if (gimple_call_must_tail_p (gs))
+ pp_string (buffer, " [must tail call]");
if (fn == NULL)
return;
diff --git a/gcc/gimple.c b/gcc/gimple.c
index b0e19d515cf..226b0801072 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -359,6 +359,7 @@ gimple_build_call_from_tree (tree t)
/* Carry all the CALL_EXPR flags to the new GIMPLE_CALL. */
gimple_call_set_chain (call, CALL_EXPR_STATIC_CHAIN (t));
gimple_call_set_tail (call, CALL_EXPR_TAILCALL (t));
+ gimple_call_set_must_tail (call, CALL_EXPR_MUST_TAIL_CALL (t));
gimple_call_set_return_slot_opt (call, CALL_EXPR_RETURN_SLOT_OPT (t));
if (fndecl
&& DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_NORMAL
@@ -1355,7 +1356,8 @@ gimple_call_same_target_p (const gimple *c1, const gimple *c2)
if (gimple_call_internal_p (c1))
return (gimple_call_internal_p (c2)
&& gimple_call_internal_fn (c1) == gimple_call_internal_fn (c2)
- && !gimple_call_internal_unique_p (as_a <const gcall *> (c1)));
+ && (!gimple_call_internal_unique_p (as_a <const gcall *> (c1))
+ || c1 == c2));
else
return (gimple_call_fn (c1) == gimple_call_fn (c2)
|| (gimple_call_fndecl (c1)
@@ -2042,6 +2044,7 @@ get_gimple_rhs_num_ops (enum tree_code code)
|| (SYM) == REALIGN_LOAD_EXPR \
|| (SYM) == VEC_COND_EXPR \
|| (SYM) == VEC_PERM_EXPR \
+ || (SYM) == BIT_INSERT_EXPR \
|| (SYM) == FMA_EXPR) ? GIMPLE_TERNARY_RHS \
: ((SYM) == CONSTRUCTOR \
|| (SYM) == OBJ_TYPE_REF \
@@ -2486,7 +2489,16 @@ gimple_builtin_call_types_compatible_p (const gimple *stmt, tree fndecl)
if (!targs)
return true;
tree arg = gimple_call_arg (stmt, i);
- if (!useless_type_conversion_p (TREE_VALUE (targs), TREE_TYPE (arg)))
+ tree type = TREE_VALUE (targs);
+ if (!useless_type_conversion_p (type, TREE_TYPE (arg))
+ /* char/short integral arguments are promoted to int
+ by several frontends if targetm.calls.promote_prototypes
+ is true. Allow such promotion too. */
+ && !(INTEGRAL_TYPE_P (type)
+ && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)
+ && targetm.calls.promote_prototypes (TREE_TYPE (fndecl))
+ && useless_type_conversion_p (integer_type_node,
+ TREE_TYPE (arg))))
return false;
targs = TREE_CHAIN (targs);
}
@@ -2992,7 +3004,7 @@ gimple_seq_discard (gimple_seq seq)
/* See if STMT now calls function that takes no parameters and if so, drop
call arguments. This is used when devirtualization machinery redirects
- to __builtiln_unreacahble or __cxa_pure_virutal. */
+ to __builtin_unreachable or __cxa_pure_virtual. */
void
maybe_remove_unused_call_args (struct function *fn, gimple *stmt)
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 6d15dab5120..063e29d7897 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -145,6 +145,7 @@ enum gf_mask {
GF_CALL_INTERNAL = 1 << 6,
GF_CALL_CTRL_ALTERING = 1 << 7,
GF_CALL_WITH_BOUNDS = 1 << 8,
+ GF_CALL_MUST_TAIL_CALL = 1 << 9,
GF_OMP_PARALLEL_COMBINED = 1 << 0,
GF_OMP_PARALLEL_GRID_PHONY = 1 << 1,
GF_OMP_TASK_TASKLOOP = 1 << 0,
@@ -3209,6 +3210,25 @@ gimple_call_tail_p (gcall *s)
return (s->subcode & GF_CALL_TAILCALL) != 0;
}
+/* Mark (or clear) call statement S as requiring tail call optimization. */
+
+static inline void
+gimple_call_set_must_tail (gcall *s, bool must_tail_p)
+{
+ if (must_tail_p)
+ s->subcode |= GF_CALL_MUST_TAIL_CALL;
+ else
+ s->subcode &= ~GF_CALL_MUST_TAIL_CALL;
+}
+
+/* Return true if call statement has been marked as requiring
+ tail call optimization. */
+
+static inline bool
+gimple_call_must_tail_p (const gcall *s)
+{
+ return (s->subcode & GF_CALL_MUST_TAIL_CALL) != 0;
+}
/* If RETURN_SLOT_OPT_P is true mark GIMPLE_CALL S as valid for return
slot optimization. This transformation uses the target of the call
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index e223e592af5..4a544e3c8ee 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -185,6 +185,8 @@ static struct gimplify_omp_ctx *gimplify_omp_ctxp;
/* Forward declaration. */
static enum gimplify_status gimplify_compound_expr (tree *, gimple_seq *, bool);
static hash_map<tree, tree> *oacc_declare_returns;
+static enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
+ bool (*) (tree), fallback_t, bool);
/* Shorter alias name for the above function for use in gimplify.c
only. */
@@ -547,7 +549,7 @@ lookup_tmp_var (tree val, bool is_formal)
static tree
internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
- bool is_formal)
+ bool is_formal, bool allow_ssa)
{
tree t, mod;
@@ -556,9 +558,18 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
gimplify_expr (&val, pre_p, post_p, is_gimple_reg_rhs_or_call,
fb_rvalue);
- if (gimplify_ctxp->into_ssa
+ if (allow_ssa
+ && gimplify_ctxp->into_ssa
&& is_gimple_reg_type (TREE_TYPE (val)))
- t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
+ {
+ t = make_ssa_name (TYPE_MAIN_VARIANT (TREE_TYPE (val)));
+ if (! gimple_in_ssa_p (cfun))
+ {
+ const char *name = get_name (val);
+ if (name)
+ SET_SSA_NAME_VAR_OR_IDENTIFIER (t, create_tmp_var_name (name));
+ }
+ }
else
t = lookup_tmp_var (val, is_formal);
@@ -588,16 +599,17 @@ internal_get_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
tree
get_formal_tmp_var (tree val, gimple_seq *pre_p)
{
- return internal_get_tmp_var (val, pre_p, NULL, true);
+ return internal_get_tmp_var (val, pre_p, NULL, true, true);
}
/* Return a temporary variable initialized with VAL. PRE_P and POST_P
are as in gimplify_expr. */
tree
-get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p)
+get_initialized_tmp_var (tree val, gimple_seq *pre_p, gimple_seq *post_p,
+ bool allow_ssa)
{
- return internal_get_tmp_var (val, pre_p, post_p, false);
+ return internal_get_tmp_var (val, pre_p, post_p, false, allow_ssa);
}
/* Declare all the variables in VARS in SCOPE. If DEBUG_INFO is true,
@@ -2279,10 +2291,12 @@ maybe_with_size_expr (tree *expr_p)
/* Helper for gimplify_call_expr. Gimplify a single argument *ARG_P
Store any side-effects in PRE_P. CALL_LOCATION is the location of
- the CALL_EXPR. */
+ the CALL_EXPR. If ALLOW_SSA is set the actual parameter may be
+ gimplified to an SSA name. */
enum gimplify_status
-gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
+gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location,
+ bool allow_ssa)
{
bool (*test) (tree);
fallback_t fb;
@@ -2319,7 +2333,7 @@ gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
the argument list must occur before the actual call. So, when
gimplifying arguments, force gimplify_expr to use an internal
post queue which is then appended to the end of PRE_P. */
- return gimplify_expr (arg_p, pre_p, NULL, test, fb);
+ return gimplify_expr (arg_p, pre_p, NULL, test, fb, allow_ssa);
}
/* Don't fold inside offloading or taskreg regions: it can break code by
@@ -2423,25 +2437,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
}
break;
}
- case BUILT_IN_LINE:
- {
- *expr_p = build_int_cst (TREE_TYPE (*expr_p),
- LOCATION_LINE (EXPR_LOCATION (*expr_p)));
- return GS_OK;
- }
- case BUILT_IN_FILE:
- {
- const char *locfile = LOCATION_FILE (EXPR_LOCATION (*expr_p));
- *expr_p = build_string_literal (strlen (locfile) + 1, locfile);
- return GS_OK;
- }
- case BUILT_IN_FUNCTION:
- {
- const char *function;
- function = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
- *expr_p = build_string_literal (strlen (function) + 1, function);
- return GS_OK;
- }
+
default:
;
}
@@ -2522,6 +2518,12 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
}
}
+ /* If the call returns twice then after building the CFG the call
+ argument computations will no longer dominate the call because
+ we add an abnormal incoming edge to the call. So do not use SSA
+ vars there. */
+ bool returns_twice = call_expr_flags (*expr_p) & ECF_RETURNS_TWICE;
+
/* Gimplify the function arguments. */
if (nargs > 0)
{
@@ -2536,7 +2538,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
if ((i != 1) || !builtin_va_start_p)
{
t = gimplify_arg (&CALL_EXPR_ARG (*expr_p, i), pre_p,
- EXPR_LOCATION (*expr_p));
+ EXPR_LOCATION (*expr_p), ! returns_twice);
if (t == GS_ERROR)
ret = GS_ERROR;
@@ -2553,7 +2555,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
{
enum gimplify_status t;
t = gimplify_arg (&CALL_EXPR_STATIC_CHAIN (*expr_p), pre_p,
- EXPR_LOCATION (*expr_p));
+ EXPR_LOCATION (*expr_p), ! returns_twice);
if (t == GS_ERROR)
ret = GS_ERROR;
}
@@ -3316,7 +3318,8 @@ prepare_gimple_addressable (tree *expr_p, gimple_seq *seq_p)
expr_p = &TREE_OPERAND (*expr_p, 0);
if (is_gimple_reg (*expr_p))
{
- tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL);
+ /* Do not allow an SSA name as the temporary. */
+ tree var = get_initialized_tmp_var (*expr_p, seq_p, NULL, false);
DECL_GIMPLE_REG_P (var) = 0;
*expr_p = var;
}
@@ -4848,6 +4851,11 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
|| TREE_ADDRESSABLE (TREE_TYPE (*to_p))
|| TREE_CODE (TYPE_SIZE_UNIT (TREE_TYPE (*to_p))) != INTEGER_CST)
gimple_call_set_lhs (call_stmt, *to_p);
+ else if (TREE_CODE (*to_p) == SSA_NAME)
+ /* The above is somewhat premature, avoid ICEing later for a
+ SSA name w/o a definition. We may have uses in the GIMPLE IL.
+ ??? This doesn't make it a default-def. */
+ SSA_NAME_DEF_STMT (*to_p) = gimple_build_nop ();
assign = call_stmt;
}
else
@@ -4861,7 +4869,8 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
if (gimplify_ctxp->into_ssa && is_gimple_reg (*to_p))
{
/* We should have got an SSA name from the start. */
- gcc_assert (TREE_CODE (*to_p) == SSA_NAME);
+ gcc_assert (TREE_CODE (*to_p) == SSA_NAME
+ || ! gimple_in_ssa_p (cfun));
}
gimplify_seq_add_stmt (pre_p, assign);
@@ -4994,7 +5003,9 @@ gimplify_save_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p)
val = NULL;
}
else
- val = get_initialized_tmp_var (val, pre_p, post_p);
+ /* The temporary may not be an SSA name as later abnormal and EH
+ control flow may invalidate use/def domination. */
+ val = get_initialized_tmp_var (val, pre_p, post_p, false);
TREE_OPERAND (*expr_p, 0) = val;
SAVE_EXPR_RESOLVED_P (*expr_p) = 1;
@@ -6653,7 +6664,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
{
tree type = TREE_TYPE (decl);
if (gimplify_expr (&TYPE_MAX_VALUE (TYPE_DOMAIN (type)), pre_p,
- NULL, is_gimple_val, fb_rvalue) == GS_ERROR)
+ NULL, is_gimple_val, fb_rvalue, false)
+ == GS_ERROR)
{
remove = true;
break;
@@ -6668,7 +6680,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
if (TREE_CODE (decl) == POINTER_PLUS_EXPR)
{
if (gimplify_expr (&TREE_OPERAND (decl, 1), pre_p,
- NULL, is_gimple_val, fb_rvalue)
+ NULL, is_gimple_val, fb_rvalue, false)
== GS_ERROR)
{
remove = true;
@@ -6865,7 +6877,8 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
&& TREE_CODE (OMP_CLAUSE_SIZE (c)) != INTEGER_CST)
{
OMP_CLAUSE_SIZE (c)
- = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL);
+ = get_initialized_tmp_var (OMP_CLAUSE_SIZE (c), pre_p, NULL,
+ false);
omp_add_variable (ctx, OMP_CLAUSE_SIZE (c),
GOVD_FIRSTPRIVATE | GOVD_SEEN);
}
@@ -8609,7 +8622,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
TREE_OPERAND (t, 1)
= get_initialized_tmp_var (TREE_OPERAND (t, 1),
- pre_p, NULL);
+ pre_p, NULL, false);
tree c = build_omp_clause (input_location,
OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
@@ -8624,7 +8637,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
TREE_OPERAND (t, 1)
= get_initialized_tmp_var (TREE_OPERAND (t, 1),
gimple_seq_empty_p (for_pre_body)
- ? pre_p : &for_pre_body, NULL);
+ ? pre_p : &for_pre_body, NULL,
+ false);
tree c = build_omp_clause (input_location,
OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = TREE_OPERAND (t, 1);
@@ -8646,7 +8660,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
gimple_seq *seq = gimple_seq_empty_p (for_pre_body)
? pre_p : &for_pre_body;
- *tp = get_initialized_tmp_var (*tp, seq, NULL);
+ *tp = get_initialized_tmp_var (*tp, seq, NULL, false);
tree c = build_omp_clause (input_location,
OMP_CLAUSE_FIRSTPRIVATE);
OMP_CLAUSE_DECL (c) = *tp;
@@ -8982,7 +8996,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
var = decl;
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
- is_gimple_val, fb_rvalue);
+ is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
if (ret == GS_ERROR)
return ret;
@@ -8993,7 +9007,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gcc_assert (TREE_OPERAND (t, 0) == decl);
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
- is_gimple_val, fb_rvalue);
+ is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
/* Handle OMP_FOR_INCR. */
@@ -9060,7 +9074,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
- is_gimple_val, fb_rvalue);
+ is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
if (c)
{
@@ -9076,7 +9090,7 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
{
tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
&for_pre_body, NULL,
- is_gimple_val, fb_rvalue);
+ is_gimple_val, fb_rvalue, false);
ret = MIN (ret, tret);
}
}
@@ -9530,7 +9544,7 @@ optimize_target_teams (tree target, gimple_seq *pre_p)
}
*p = expr;
gimplify_omp_ctxp = gimplify_omp_ctxp->outer_context;
- if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue)
+ if (gimplify_expr (p, pre_p, NULL, is_gimple_val, fb_rvalue, false)
== GS_ERROR)
{
gimplify_omp_ctxp = target_ctx;
@@ -10248,7 +10262,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
required. */
if (fallback == fb_lvalue)
{
- *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
mark_addressable (*expr_p);
ret = GS_OK;
}
@@ -10263,7 +10277,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
required. */
if (fallback == fb_lvalue)
{
- *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
mark_addressable (*expr_p);
ret = GS_OK;
}
@@ -10438,7 +10452,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
in suitable form. Re-gimplifying would mark the address
operand addressable. Always gimplify when not in SSA form
as we still may have to gimplify decls with value-exprs. */
- if (!gimplify_ctxp || !gimplify_ctxp->into_ssa
+ if (!gimplify_ctxp || !gimple_in_ssa_p (cfun)
|| !is_gimple_mem_ref_addr (TREE_OPERAND (*expr_p, 0)))
{
ret = gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
@@ -10558,7 +10572,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
required. */
else if (fallback == fb_lvalue)
{
- *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p);
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, post_p, false);
mark_addressable (*expr_p);
ret = GS_OK;
}
@@ -10917,6 +10931,10 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
/* Classified as tcc_expression. */
goto expr_3;
+ case BIT_INSERT_EXPR:
+ /* Argument 3 is a constant. */
+ goto expr_2;
+
case POINTER_PLUS_EXPR:
{
enum gimplify_status r0, r1;
@@ -11256,6 +11274,35 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
return ret;
}
+/* Like gimplify_expr but make sure the gimplified result is not itself
+ a SSA name (but a decl if it were). Temporaries required by
+ evaluating *EXPR_P may be still SSA names. */
+
+static enum gimplify_status
+gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
+ bool (*gimple_test_f) (tree), fallback_t fallback,
+ bool allow_ssa)
+{
+ bool was_ssa_name_p = TREE_CODE (*expr_p) == SSA_NAME;
+ enum gimplify_status ret = gimplify_expr (expr_p, pre_p, post_p,
+ gimple_test_f, fallback);
+ if (! allow_ssa
+ && TREE_CODE (*expr_p) == SSA_NAME)
+ {
+ tree name = *expr_p;
+ if (was_ssa_name_p)
+ *expr_p = get_initialized_tmp_var (*expr_p, pre_p, NULL, false);
+ else
+ {
+ /* Avoid the extra copy if possible. */
+ *expr_p = create_tmp_reg (TREE_TYPE (name));
+ gimple_set_lhs (SSA_NAME_DEF_STMT (name), *expr_p);
+ release_ssa_name (name);
+ }
+ }
+ return ret;
+}
+
/* Look through TYPE for variable-sized objects and gimplify each such
size that we find. Add to LIST_P any statements generated. */
@@ -11378,7 +11425,9 @@ gimplify_one_sizepos (tree *expr_p, gimple_seq *stmt_p)
*expr_p = unshare_expr (expr);
- gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue);
+ /* SSA names in decl/type fields are a bad idea - they'll get reclaimed
+ if the def vanishes. */
+ gimplify_expr (expr_p, stmt_p, NULL, is_gimple_val, fb_rvalue, false);
}
/* Gimplify the body of statements of FNDECL and return a GIMPLE_BIND node
@@ -11396,12 +11445,14 @@ gimplify_body (tree fndecl, bool do_parms)
timevar_push (TV_TREE_GIMPLIFY);
+ init_tree_ssa (cfun);
+
/* Initialize for optimize_insn_for_s{ize,peed}_p possibly called during
gimplification. */
default_rtl_profile ();
gcc_assert (gimplify_ctxp == NULL);
- push_gimplify_context ();
+ push_gimplify_context (true);
if (flag_openacc || flag_openmp)
{
diff --git a/gcc/gimplify.h b/gcc/gimplify.h
index fd003a0e127..27823e6bb99 100644
--- a/gcc/gimplify.h
+++ b/gcc/gimplify.h
@@ -57,7 +57,8 @@ extern gbind *gimple_current_bind_expr (void);
extern vec<gbind *> gimple_bind_expr_stack (void);
extern void gimplify_and_add (tree, gimple_seq *);
extern tree get_formal_tmp_var (tree, gimple_seq *);
-extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *);
+extern tree get_initialized_tmp_var (tree, gimple_seq *, gimple_seq *,
+ bool = true);
extern void declare_vars (tree, gimple *, bool);
extern void gimple_add_tmp_var (tree);
extern void gimple_add_tmp_var_fn (struct function *, tree);
@@ -77,7 +78,8 @@ extern enum gimplify_status gimplify_expr (tree *, gimple_seq *, gimple_seq *,
extern void gimplify_type_sizes (tree, gimple_seq *);
extern void gimplify_one_sizepos (tree *, gimple_seq *);
extern gbind *gimplify_body (tree, bool);
-extern enum gimplify_status gimplify_arg (tree *, gimple_seq *, location_t);
+extern enum gimplify_status gimplify_arg (tree *, gimple_seq *, location_t,
+ bool = true);
extern void gimplify_function_tree (tree);
extern enum gimplify_status gimplify_va_arg_expr (tree *, gimple_seq *,
gimple_seq *);
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index c179e79e281..e486a305a01 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,8 @@
+2016-05-06 Chris Manghane <cmang@google.com>
+
+ * Make-lang.in (GO_OBJS): Add go/escape.o (based on an entirely
+ new escape.cc).
+
2016-04-29 Chris Manghane <cmang@google.com>
* Make-lang.in (GO_OBJS): Remove go/dataflow.o, go/escape.o.
diff --git a/gcc/go/Make-lang.in b/gcc/go/Make-lang.in
index df27e217828..d5b2a776776 100644
--- a/gcc/go/Make-lang.in
+++ b/gcc/go/Make-lang.in
@@ -50,6 +50,7 @@ go-warn = $(STRICT_WARN)
GO_OBJS = \
go/ast-dump.o \
+ go/escape.o \
go/export.o \
go/expressions.o \
go/go-backend.o \
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1874a2ea3be..8e0fd0fb63e 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-46b108136c0d102f181f0cc7c398e3db8c4d08a3
+a87af72757d9a2e4479062a459a41d4540398005
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/escape.cc b/gcc/go/gofrontend/escape.cc
new file mode 100644
index 00000000000..01f3da72421
--- /dev/null
+++ b/gcc/go/gofrontend/escape.cc
@@ -0,0 +1,526 @@
+// escape.cc -- Go escape analysis (based on Go compiler algorithm).
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#include <limits>
+#include <stack>
+
+#include "gogo.h"
+#include "types.h"
+#include "expressions.h"
+#include "statements.h"
+#include "escape.h"
+
+// class Node.
+
+// Return the node's type, if it makes sense for it to have one.
+
+Type*
+Node::type() const
+{
+ if (this->object() != NULL
+ && this->object()->is_variable())
+ return this->object()->var_value()->type();
+ else if (this->object() != NULL
+ && this->object()->is_function())
+ return this->object()->func_value()->type();
+ else if (this->expr() != NULL)
+ return this->expr()->type();
+ else
+ return NULL;
+}
+
+// A helper for reporting; return this node's location.
+
+Location
+Node::location() const
+{
+ if (this->object() != NULL && !this->object()->is_sink())
+ return this->object()->location();
+ else if (this->expr() != NULL)
+ return this->expr()->location();
+ else if (this->statement() != NULL)
+ return this->statement()->location();
+ else
+ return Linemap::unknown_location();
+}
+
+// Return this node's state, creating it if has not been initialized.
+
+Node::Escape_state*
+Node::state(Escape_context* context, Named_object* fn)
+{
+ if (this->state_ == NULL)
+ {
+ if (this->expr() != NULL && this->expr()->var_expression() != NULL)
+ {
+ // Tie state of variable references to underlying variables.
+ Named_object* var_no = this->expr()->var_expression()->named_object();
+ Node* var_node = Node::make_node(var_no);
+ this->state_ = var_node->state(context, fn);
+ }
+ else
+ {
+ this->state_ = new Node::Escape_state;
+ if (fn == NULL)
+ fn = context->current_function();
+
+ this->state_->fn = fn;
+ }
+ }
+ go_assert(this->state_ != NULL);
+ return this->state_;
+}
+
+void
+Node::set_encoding(int enc)
+{
+ this->encoding_ = enc;
+ if (this->expr() != NULL
+ && this->expr()->var_expression() != NULL)
+ {
+ // Set underlying object as well.
+ Named_object* no = this->expr()->var_expression()->named_object();
+ Node::make_node(no)->set_encoding(enc);
+ }
+}
+
+bool
+Node::is_sink() const
+{
+ if (this->object() != NULL
+ && this->object()->is_sink())
+ return true;
+ else if (this->expr() != NULL
+ && this->expr()->is_sink_expression())
+ return true;
+ return false;
+}
+
+std::map<Named_object*, Node*> Node::objects;
+std::map<Expression*, Node*> Node::expressions;
+std::map<Statement*, Node*> Node::statements;
+
+// Make a object node or return a cached node for this object.
+
+Node*
+Node::make_node(Named_object* no)
+{
+ if (Node::objects.find(no) != Node::objects.end())
+ return Node::objects[no];
+
+ Node* n = new Node(no);
+ std::pair<Named_object*, Node*> val(no, n);
+ Node::objects.insert(val);
+ return n;
+}
+
+// Make an expression node or return a cached node for this expression.
+
+Node*
+Node::make_node(Expression* e)
+{
+ if (Node::expressions.find(e) != Node::expressions.end())
+ return Node::expressions[e];
+
+ Node* n = new Node(e);
+ std::pair<Expression*, Node*> val(e, n);
+ Node::expressions.insert(val);
+ return n;
+}
+
+// Make a statement node or return a cached node for this statement.
+
+Node*
+Node::make_node(Statement* s)
+{
+ if (Node::statements.find(s) != Node::statements.end())
+ return Node::statements[s];
+
+ Node* n = new Node(s);
+ std::pair<Statement*, Node*> val(s, n);
+ Node::statements.insert(val);
+ return n;
+}
+
+// Returns the maximum of an exisiting escape value
+// (and its additional parameter flow flags) and a new escape type.
+
+int
+Node::max_encoding(int e, int etype)
+{
+ if ((e & ESCAPE_MASK) >= etype)
+ return e;
+ if (etype == Node::ESCAPE_NONE || etype == Node::ESCAPE_RETURN)
+ return (e & ~ESCAPE_MASK) | etype;
+ return etype;
+}
+
+// Return a modified encoding for an input parameter that flows into an
+// output parameter.
+
+// Class Escape_context.
+
+Escape_context::Escape_context(Gogo* gogo, bool recursive)
+ : gogo_(gogo), current_function_(NULL), recursive_(recursive),
+ sink_(Node::make_node(Named_object::make_sink())), loop_depth_(0)
+{
+ // The sink always escapes to heap and strictly lives outside of the
+ // current function i.e. loop_depth == -1.
+ this->sink_->set_encoding(Node::ESCAPE_HEAP);
+ Node::Escape_state* state = this->sink_->state(this, NULL);
+ state->loop_depth = -1;
+}
+
+// Initialize the dummy return values for this Node N using the results
+// in FNTYPE.
+
+void
+Escape_context::init_retvals(Node* n, Function_type* fntype)
+{
+ if (fntype == NULL || fntype->results() == NULL)
+ return;
+
+ Node::Escape_state* state = n->state(this, NULL);
+ Location loc = n->location();
+
+ int i = 0;
+ char buf[50];
+ for (Typed_identifier_list::const_iterator p = fntype->results()->begin();
+ p != fntype->results()->end();
+ ++p, ++i)
+ {
+ snprintf(buf, sizeof buf, ".out%d", i);
+ Variable* dummy_var = new Variable(p->type(), NULL, false, false,
+ false, loc);
+ dummy_var->set_is_used();
+ Named_object* dummy_no =
+ Named_object::make_variable(buf, NULL, dummy_var);
+ Node* dummy_node = Node::make_node(dummy_no);
+ // Initialize the state of the dummy output node.
+ dummy_node->state(this, NULL);
+
+ // Add dummy node to the retvals of n.
+ state->retvals.push_back(dummy_node);
+ }
+}
+
+
+// Apply an indirection to N and return the result.
+// This really only works if N is an expression node; it essentially becomes
+// Node::make_node(n->expr()->deref()). We need the escape context to set the
+// correct loop depth, however.
+
+Node*
+Escape_context::add_dereference(Node* n)
+{
+ // Just return the original node if we can't add an indirection.
+ if (n->object() != NULL || n->statement() != NULL)
+ return n;
+
+ Node* ind = Node::make_node(n->expr()->deref());
+ // Initialize the state if this node doesn't already exist.
+ ind->state(this, NULL);
+ return ind;
+}
+
+void
+Escape_context::track(Node* n)
+{
+ n->set_encoding(Node::ESCAPE_NONE);
+ // Initialize this node's state if it hasn't been encountered
+ // before.
+ Node::Escape_state* state = n->state(this, NULL);
+ state->loop_depth = this->loop_depth_;
+
+ this->noesc_.push_back(n);
+}
+
+// Return the string representation of an escapement encoding.
+
+std::string
+Escape_note::make_tag(int encoding)
+{
+ char buf[50];
+ snprintf(buf, sizeof buf, "esc:0x%x", encoding);
+ return buf;
+}
+
+// Return the escapement encoding for a string tag.
+
+int
+Escape_note::parse_tag(std::string* tag)
+{
+ if (tag == NULL || tag->substr(0, 4) != "esc:")
+ return Node::ESCAPE_UNKNOWN;
+ int encoding = (int)strtol(tag->substr(4).c_str(), NULL, 0);
+ if (encoding == 0)
+ return Node::ESCAPE_UNKNOWN;
+ return encoding;
+}
+
+// Analyze the program flow for escape information.
+
+void
+Gogo::analyze_escape()
+{
+ // Discover strongly connected groups of functions to analyze for escape
+ // information in this package.
+ this->discover_analysis_sets();
+
+ for (std::vector<Analysis_set>::iterator p = this->analysis_sets_.begin();
+ p != this->analysis_sets_.end();
+ ++p)
+ {
+ std::vector<Named_object*> stack = p->first;
+ Escape_context* context = new Escape_context(this, p->second);
+
+ // Analyze the flow of each function; build the connection graph.
+ // This is the assign phase.
+ for (std::vector<Named_object*>::reverse_iterator fn = stack.rbegin();
+ fn != stack.rend();
+ ++fn)
+ {
+ context->set_current_function(*fn);
+ this->assign_connectivity(context, *fn);
+ }
+
+ // Propagate levels across each dst. This is the flood phase.
+ std::set<Node*> dsts = context->dsts();
+ for (std::set<Node*>::iterator n = dsts.begin();
+ n != dsts.end();
+ ++n)
+ this->propagate_escape(context, *n);
+
+ // Tag each exported function's parameters with escape information.
+ for (std::vector<Named_object*>::iterator fn = stack.begin();
+ fn != stack.end();
+ ++fn)
+ this->tag_function(context, *fn);
+
+ delete context;
+ }
+}
+
+// Traverse the program, discovering the functions that are roots of strongly
+// connected components. The goal of this phase to produce a set of functions
+// that must be analyzed in order.
+
+class Escape_analysis_discover : public Traverse
+{
+ public:
+ Escape_analysis_discover(Gogo* gogo)
+ : Traverse(traverse_functions),
+ gogo_(gogo), component_ids_()
+ { }
+
+ int
+ function(Named_object*);
+
+ int
+ visit(Named_object*);
+
+ int
+ visit_code(Named_object*, int);
+
+ private:
+ // A counter used to generate the ID for the function node in the graph.
+ static int id;
+
+ // Type used to map functions to an ID in a graph of connected components.
+ typedef Unordered_map(Named_object*, int) Component_ids;
+
+ // The Go IR.
+ Gogo* gogo_;
+ // The list of functions encountered during connected component discovery.
+ Component_ids component_ids_;
+ // The stack of functions that this component consists of.
+ std::stack<Named_object*> stack_;
+};
+
+int Escape_analysis_discover::id = 0;
+
+// Visit each function.
+
+int
+Escape_analysis_discover::function(Named_object* fn)
+{
+ this->visit(fn);
+ return TRAVERSE_CONTINUE;
+}
+
+// Visit a function FN, adding it to the current stack of functions
+// in this connected component. If this is the root of the component,
+// create a set of functions to be analyzed later.
+//
+// Finding these sets is finding strongly connected components
+// in the static call graph. The algorithm for doing that is taken
+// from Sedgewick, Algorithms, Second Edition, p. 482, with two
+// adaptations.
+//
+// First, a closure (fn->func_value()->enclosing() == NULL) cannot be the
+// root of a connected component. Refusing to use it as a root
+// forces it into the component of the function in which it appears.
+// This is more convenient for escape analysis.
+//
+// Second, each function becomes two virtual nodes in the graph,
+// with numbers n and n+1. We record the function's node number as n
+// but search from node n+1. If the search tells us that the component
+// number (min) is n+1, we know that this is a trivial component: one function
+// plus its closures. If the search tells us that the component number is
+// n, then there was a path from node n+1 back to node n, meaning that
+// the function set is mutually recursive. The escape analysis can be
+// more precise when analyzing a single non-recursive function than
+// when analyzing a set of mutually recursive functions.
+
+int
+Escape_analysis_discover::visit(Named_object* fn)
+{
+ Component_ids::const_iterator p = this->component_ids_.find(fn);
+ if (p != this->component_ids_.end())
+ // Already visited.
+ return p->second;
+
+ this->id++;
+ int id = this->id;
+ this->component_ids_[fn] = id;
+ this->id++;
+ int min = this->id;
+
+ this->stack_.push(fn);
+ min = this->visit_code(fn, min);
+ if ((min == id || min == id + 1)
+ && fn->is_function()
+ && fn->func_value()->enclosing() == NULL)
+ {
+ bool recursive = min == id;
+ std::vector<Named_object*> group;
+
+ for (; !this->stack_.empty(); this->stack_.pop())
+ {
+ Named_object* n = this->stack_.top();
+ if (n == fn)
+ {
+ this->stack_.pop();
+ break;
+ }
+
+ group.push_back(n);
+ this->component_ids_[n] = std::numeric_limits<int>::max();
+ }
+ group.push_back(fn);
+ this->component_ids_[fn] = std::numeric_limits<int>::max();
+
+ std::reverse(group.begin(), group.end());
+ this->gogo_->add_analysis_set(group, recursive);
+ }
+
+ return min;
+}
+
+// Helper class for discovery step. Traverse expressions looking for
+// function calls and closures to visit during the discovery step.
+
+class Escape_discover_expr : public Traverse
+{
+ public:
+ Escape_discover_expr(Escape_analysis_discover* ead, int min)
+ : Traverse(traverse_expressions),
+ ead_(ead), min_(min)
+ { }
+
+ int
+ min()
+ { return this->min_; }
+
+ int
+ expression(Expression** pexpr);
+
+ private:
+ // The original discovery analysis.
+ Escape_analysis_discover* ead_;
+ // The minimum component ID in this group.
+ int min_;
+};
+
+// Visit any calls or closures found when discovering expressions.
+
+int
+Escape_discover_expr::expression(Expression** pexpr)
+{
+ Expression* e = *pexpr;
+ Named_object* fn = NULL;
+ if (e->call_expression() != NULL
+ && e->call_expression()->fn()->func_expression() != NULL)
+ {
+ // Method call or function call.
+ fn = e->call_expression()->fn()->func_expression()->named_object();
+ }
+ else if (e->func_expression() != NULL
+ && e->func_expression()->closure() != NULL)
+ {
+ // Closure.
+ fn = e->func_expression()->named_object();
+ }
+
+ if (fn != NULL)
+ this->min_ = std::min(this->min_, this->ead_->visit(fn));
+ return TRAVERSE_CONTINUE;
+}
+
+// Visit the body of each function, returns ID of the minimum connected
+// component found in the body.
+
+int
+Escape_analysis_discover::visit_code(Named_object* fn, int min)
+{
+ if (!fn->is_function())
+ return min;
+
+ Escape_discover_expr ede(this, min);
+ fn->func_value()->traverse(&ede);
+ return ede.min();
+}
+
+// Discover strongly connected groups of functions to analyze.
+
+void
+Gogo::discover_analysis_sets()
+{
+ Escape_analysis_discover ead(this);
+ this->traverse(&ead);
+}
+
+// Build a connectivity graph between nodes in the function being analyzed.
+
+void
+Gogo::assign_connectivity(Escape_context*, Named_object*)
+{
+ // TODO(cmang): Model the flow analysis of input parameters and results for a
+ // function.
+ // TODO(cmang): Analyze the current function's body.
+}
+
+// Propagate escape information across the nodes modeled in this Analysis_set.
+
+void
+Gogo::propagate_escape(Escape_context*, Node*)
+{
+ // TODO(cmang): Do a breadth-first traversal of a node's upstream, adjusting
+ // the Level appropriately.
+}
+
+
+// Tag each top-level function with escape information that will be used to
+// retain analysis results across imports.
+
+void
+Gogo::tag_function(Escape_context*, Named_object*)
+{
+ // TODO(cmang): Create escape information notes for each input and output
+ // parameter in a given function.
+ // Escape_analysis_tag eat(context, fn);
+ // this->traverse(&eat);
+}
diff --git a/gcc/go/gofrontend/escape.h b/gcc/go/gofrontend/escape.h
new file mode 100644
index 00000000000..c409acb310c
--- /dev/null
+++ b/gcc/go/gofrontend/escape.h
@@ -0,0 +1,442 @@
+// escape.h -- Go escape analysis (based on Go compiler algorithm).
+
+// Copyright 2016 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+#ifndef GO_ESCAPE_H
+#define GO_ESCAPE_H
+
+#include "gogo.h"
+
+class Named_object;
+class Expression;
+class Statement;
+class Escape_context;
+
+// There can be loops in the escape graph that lead to arbitrary recursions.
+// See comment in gc/esc.go.
+static const int MIN_LEVEL = -2;
+
+// Level models the escapement of a Node using two integers that are computed
+// by backwards-analyzing the flow of a function from its sink and increasing or
+// decreasing based on dereferences and addressing, respectively.
+// One integer, known as the level's VALUE (think absolute value), is just the
+// sum of indirections (via referencing or dereferencing) applied to the Node.
+// The second, known as the level's SUFFIX_VALUE, is the amount of indirections
+// applied after some data has been copied from the node. When accessing a
+// field F of an object O and then applying indirections, for example, the field
+// access O.F is assumed to copy that data from O before applying indirections.
+// With this, even if O.F escapes, it might mean that the content of O escape,
+// but not the object O itself.
+
+class Level
+{
+public:
+ Level()
+ : value_(0), suffix_value_(0)
+ { }
+
+ Level(int value, int suffix)
+ : value_(value), suffix_value_(suffix)
+ { }
+
+ // Return this level's value.
+ int
+ value() const
+ { return this->value_; }
+
+ // Return this level's suffix value.
+ int
+ suffix_value() const
+ { return this->suffix_value_; }
+
+ // Increase the level because a node is referenced.
+ Level
+ increase() const
+ {
+ if (this->value_ <= MIN_LEVEL)
+ return Level(MIN_LEVEL, 0);
+
+ return Level(this->value_ + 1, this->suffix_value_ + 1);
+ }
+
+ // Decrease the level because a node is dereferenced.
+ Level
+ decrease() const
+ {
+ if (this->value_ <= MIN_LEVEL)
+ return Level(MIN_LEVEL, 0);
+
+ return Level(this->value_ - 1, this->suffix_value_ - 1);
+ }
+
+ // Model a node being copied.
+ Level
+ copy() const
+ {
+ return Level(this->value_, std::max(this->suffix_value_, 0));
+ }
+
+ // Return a level with the minimum values of this level and l.
+ Level
+ min(const Level& l) const
+ {
+ return Level(std::min(this->value_, l.value()),
+ std::min(this->suffix_value_, l.suffix_value()));
+ }
+
+ // Compare two levels for equality.
+ bool
+ operator==(const Level& l) const
+ {
+ return (this->value_ == l.value()
+ && this->suffix_value_ == l.suffix_value());
+ }
+
+ // Create a level from an integer value.
+ static Level
+ From(int i)
+ {
+ if (i <= MIN_LEVEL)
+ return Level(MIN_LEVEL, 0);
+ return Level(i, 0);
+ }
+
+private:
+ // The sum of all indirects (-1) and references (+1) applied to a Node.
+ int value_;
+ // The sum of all indirects (-1) abd references (+1) applied to a copied Node.
+ int suffix_value_;
+};
+
+// A node in the escape graph. This node is an alias to a particular node
+// in the Go parse tree. Specifically, it can represent an expression node,
+// a statement node, or a named object node (a variable or function).
+
+class Node
+{
+ public:
+ // This classification represents type of nodes in the Go parse tree that are
+ // interesting during the analysis.
+ enum Node_classification
+ {
+ NODE_OBJECT,
+ NODE_EXPRESSION,
+ NODE_STATEMENT
+ };
+
+ // The state necessary to keep track of how a node escapes.
+ struct Escape_state
+ {
+ // The current function.
+ Named_object* fn;
+ // A list of source nodes that flow into this node.
+ std::set<Node*> flows;
+ // If the node is a function call, the list of nodes returned.
+ std::vector<Node*> retvals;
+ // The node's loop depth.
+ int loop_depth;
+ // There is an extra loop depth in the flood phase used to account for
+ // variables referenced across closures. This is the maximum value of the
+ // extra loop depth seen during the flood that touches this node.
+ int max_extra_loop_depth;
+ // The node's level.
+ Level level;
+ // An ID given to a node when it is encountered as a flow from the current
+ // dst node. This is used to avoid infinite recursion of cyclic nodes.
+ int flood_id;
+
+ Escape_state()
+ : fn(NULL), loop_depth(0), max_extra_loop_depth(0), flood_id(0)
+ { }
+ };
+
+ // Note: values in this enum appear in export data, and therefore MUST NOT
+ // change.
+ enum Escapement_encoding
+ {
+ ESCAPE_UNKNOWN,
+ // Does not escape to heap, result, or parameters.
+ ESCAPE_NONE,
+ // Is returned or reachable from a return statement.
+ ESCAPE_RETURN,
+ // Allocated in an inner loop, assigned to an outer loop,
+ // which allows construction of non-escaping but arbitrarily large linked
+ // data structures (i.e., not eligible for allocation in a fixed-size stack
+ // stack frame).
+ ESCAPE_SCOPE,
+ // Reachable from the heap.
+ ESCAPE_HEAP,
+ // By construction will not escape.
+ ESCAPE_NEVER
+ };
+
+ // Multiple constructors for each classification.
+ Node(Named_object* no)
+ : classification_(NODE_OBJECT), state_(NULL), encoding_(ESCAPE_UNKNOWN)
+ { this->u_.object_val = no; }
+
+ Node(Expression* e)
+ : classification_(NODE_EXPRESSION), state_(NULL), encoding_(ESCAPE_UNKNOWN)
+ { this->u_.expression_val = e; }
+
+ Node(Statement* s)
+ : classification_(NODE_STATEMENT), state_(NULL), encoding_(ESCAPE_UNKNOWN)
+ { this->u_.statement_val = s; }
+
+ // Return this node's type.
+ Type*
+ type() const;
+
+ // Return this node's location.
+ Location
+ location() const;
+
+ // Return this node's escape state.
+ Escape_state*
+ state(Escape_context* context, Named_object* fn);
+
+ // Return this node's escape encoding.
+ int
+ encoding() const
+ { return this->encoding_; }
+
+ // Set the node's escape encoding.
+ void
+ set_encoding(int enc);
+
+ // Is this node a sink?
+ bool
+ is_sink() const;
+
+ // Methods to return the underlying value in the Node union.
+ Named_object*
+ object() const
+ {
+ return (this->classification_ == NODE_OBJECT
+ ? this->u_.object_val
+ : NULL);
+ }
+
+ Expression*
+ expr() const
+ {
+ return (this->classification_ == NODE_EXPRESSION
+ ? this->u_.expression_val
+ : NULL);
+ }
+
+ Statement*
+ statement() const
+ {
+ return (this->classification_ == NODE_STATEMENT
+ ? this->u_.statement_val
+ : NULL);
+ }
+
+ // Static creation methods for each value supported in the union.
+ static Node*
+ make_node(Named_object*);
+
+ static Node*
+ make_node(Expression*);
+
+ static Node*
+ make_node(Statement*);
+
+ // Return the maximum of an existing escape encoding E and a new
+ // escape type.
+ static int
+ max_encoding(int e, int etype);
+
+ private:
+ // The classification of this Node.
+ Node_classification classification_;
+ // The value union.
+ union
+ {
+ // If NODE_OBJECT.
+ Named_object* object_val;
+ // If NODE_EXPRESSION.
+ Expression* expression_val;
+ // If NODE_STATEMENT.
+ Statement* statement_val;
+ } u_;
+ // The node's escape state.
+ Escape_state* state_;
+ // The node's escape encoding.
+ // The encoding:
+ // | Return Encoding: (width - ESCAPE_RETURN_BITS) |
+ // | Content Escapes bit: 1 |
+ // | Escapement_encoding: ESCAPE_BITS |
+ int encoding_;
+
+ // Cache all the Nodes created via Node::make_node to make the API simpler.
+ static std::map<Named_object*, Node*> objects;
+ static std::map<Expression*, Node*> expressions;
+ static std::map<Statement*, Node*> statements;
+};
+
+// The amount of bits used for the escapement encoding.
+static const int ESCAPE_BITS = 3;
+
+// Mask used to extract encoding.
+static const int ESCAPE_MASK = (1 << ESCAPE_BITS) - 1;
+
+// Value obtained by indirect of parameter escapes to heap.
+static const int ESCAPE_CONTENT_ESCAPES = 1 << ESCAPE_BITS;
+
+// The amount of bits used in encoding of return values.
+static const int ESCAPE_RETURN_BITS = ESCAPE_BITS + 1;
+
+// For each output, the number of bits for a tag.
+static const int ESCAPE_BITS_PER_OUTPUT_IN_TAG = 3;
+
+// The bit max to extract a single tag.
+static const int ESCAPE_BITS_MASK_FOR_TAG = (1 << ESCAPE_BITS_PER_OUTPUT_IN_TAG) - 1;
+
+// The largest level that can be stored in a tag.
+static const int ESCAPE_MAX_ENCODED_LEVEL = ESCAPE_BITS_MASK_FOR_TAG - 1;
+
+// A helper for converting escape notes from encoded integers to a
+// textual format and vice-versa.
+
+class Escape_note
+{
+ public:
+ // Return the string representation of an escapement encoding.
+ static std::string
+ make_tag(int encoding);
+
+ // Return the escapement encoding for a string tag.
+ static int
+ parse_tag(std::string* tag);
+};
+
+// The escape context for a set of functions being analyzed.
+
+class Escape_context
+{
+ public:
+ Escape_context(Gogo* gogo, bool recursive);
+
+ // Return the Go IR.
+ Gogo*
+ gogo() const
+ { return this->gogo_; }
+
+ // Return the current function being analyzed.
+ Named_object*
+ current_function() const
+ { return this->current_function_; }
+
+ // Change the function being analyzed.
+ void
+ set_current_function(Named_object* fn)
+ { this->current_function_ = fn; }
+
+ // Return true if this is the context for a mutually recursive set of functions.
+ bool
+ recursive() const
+ { return this->recursive_; }
+
+ // Return the special sink node for this context.
+ Node*
+ sink()
+ { return this->sink_; }
+
+ // Return the current loop depth.
+ int
+ loop_depth() const
+ { return this->loop_depth_; }
+
+ // Increase the loop depth.
+ void
+ increase_loop_depth()
+ { this->loop_depth_++; }
+
+ // Decrease the loop depth.
+ void
+ decrease_loop_depth()
+ { this->loop_depth_--; }
+
+ void
+ set_loop_depth(int depth)
+ { this->loop_depth_ = depth; }
+
+ // Return the destination nodes encountered in this context.
+ const std::set<Node*>&
+ dsts() const
+ { return this->dsts_; }
+
+ // Add a destination node.
+ void
+ add_dst(Node* dst)
+ { this->dsts_.insert(dst); }
+
+ // Return the nodes initially marked as non-escaping before flooding.
+ const std::vector<Node*>&
+ non_escaping_nodes() const
+ { return this->noesc_; }
+
+ // Initialize the dummy return values for this Node N using the results
+ // in FNTYPE.
+ void
+ init_retvals(Node* n, Function_type* fntype);
+
+ // Return the indirection of Node N.
+ Node*
+ add_dereference(Node* n);
+
+ // Keep track of possibly non-escaping node N.
+ void
+ track(Node* n);
+
+ int
+ flood_id() const
+ { return this->flood_id_; }
+
+ void
+ increase_flood_id()
+ { this->flood_id_++; }
+
+ int
+ pdepth() const
+ { return this->pdepth_; }
+
+ void
+ increase_pdepth()
+ { this->pdepth_++; }
+
+ void
+ decrease_pdepth()
+ { this->pdepth_--; }
+
+ private:
+ // The Go IR.
+ Gogo* gogo_;
+ // The current function being analyzed.
+ Named_object* current_function_;
+ // Return whether this is the context for a recursive function or a group of mutually
+ // recursive functions.
+ bool recursive_;
+ // The sink for this escape context. Nodes whose reference objects created
+ // outside the current function are assigned to the sink as well as nodes that
+ // the analysis loses track of.
+ Node* sink_;
+ // Used to detect nested loop scopes.
+ int loop_depth_;
+ // All the destination nodes considered in this set of analyzed functions.
+ std::set<Node*> dsts_;
+ // All the nodes that were noted as possibly not escaping in this context.
+ std::vector<Node*> noesc_;
+ // An ID given to each dst and the flows discovered through DFS of that dst.
+ // This is used to avoid infinite recursion from nodes that point to each
+ // other within the flooding phase.
+ int flood_id_;
+ // The current level of recursion within a flooded section; used to debug.
+ int pdepth_;
+};
+
+#endif // !defined(GO_ESCAPE_H)
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index 45c38578102..a04999e7f36 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -50,6 +50,8 @@ class Bblock;
class Bvariable;
class Blabel;
class Bfunction;
+class Escape_context;
+class Node;
// This file declares the basic classes used to hold the internal
// representation of Go which is built by the parser.
@@ -345,6 +347,16 @@ class Gogo
add_label_reference(const std::string&, Location,
bool issue_goto_errors);
+ // An analysis set is a list of functions paired with a boolean that indicates
+ // whether the list of functions are recursive.
+ typedef std::pair<std::vector<Named_object*>, bool> Analysis_set;
+
+ // Add a GROUP of possibly RECURSIVE functions to the Analysis_set for this
+ // package.
+ void
+ add_analysis_set(const std::vector<Named_object*>& group, bool recursive)
+ { this->analysis_sets_.push_back(std::make_pair(group, recursive)); }
+
// Return a snapshot of the current binding state.
Bindings_snapshot*
bindings_snapshot(Location);
@@ -544,6 +556,28 @@ class Gogo
void
check_return_statements();
+ // Analyze the program flow for escape information.
+ void
+ analyze_escape();
+
+ // Discover the groups of possibly recursive functions in this package.
+ void
+ discover_analysis_sets();
+
+ // Build a connectivity graph between the objects in each analyzed function.
+ void
+ assign_connectivity(Escape_context*, Named_object*);
+
+ // Traverse the objects in the connecitivty graph from the sink, adjusting the
+ // escape levels of each object.
+ void
+ propagate_escape(Escape_context*, Node*);
+
+ // Add notes about the escape level of a function's input and output
+ // parameters for exporting and importing top level functions.
+ void
+ tag_function(Escape_context*, Named_object*);
+
// Do all exports.
void
do_exports();
@@ -762,6 +796,9 @@ class Gogo
bool specific_type_functions_are_written_;
// Whether named types have been converted.
bool named_types_are_converted_;
+ // A list containing groups of possibly mutually recursive functions to be
+ // considered during escape analysis.
+ std::vector<Analysis_set> analysis_sets_;
};
// A block of statements.
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index bf673e63ca8..682f61145d2 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -8,6 +8,7 @@
#define GO_TYPES_H
#include "go-linemap.h"
+#include "escape.h"
class Gogo;
class Package;
@@ -1324,7 +1325,7 @@ class Typed_identifier
public:
Typed_identifier(const std::string& name, Type* type,
Location location)
- : name_(name), type_(type), location_(location)
+ : name_(name), type_(type), location_(location), note_(NULL)
{ }
// Get the name.
@@ -1351,6 +1352,16 @@ class Typed_identifier
this->type_ = type;
}
+ // Get the escape note.
+ std::string*
+ note() const
+ { return this->note_; }
+
+ // Set the escape note.
+ void
+ set_note(const std::string& note)
+ { this->note_ = new std::string(note); }
+
private:
// Identifier name.
std::string name_;
@@ -1358,6 +1369,9 @@ class Typed_identifier
Type* type_;
// The location where the name was seen.
Location location_;
+ // Escape note for this typed identifier. Used when importing and exporting
+ // functions.
+ std::string* note_;
};
// A list of Typed_identifiers.
@@ -1422,6 +1436,10 @@ class Typed_identifier_list
back() const
{ return this->entries_.back(); }
+ Typed_identifier&
+ at(size_t i)
+ { return this->entries_.at(i); }
+
const Typed_identifier&
at(size_t i) const
{ return this->entries_.at(i); }
@@ -1778,7 +1796,7 @@ class Function_type : public Type
: Type(TYPE_FUNCTION),
receiver_(receiver), parameters_(parameters), results_(results),
location_(location), is_varargs_(false), is_builtin_(false),
- fnbtype_(NULL)
+ fnbtype_(NULL), is_tagged_(false)
{ }
// Get the receiver.
@@ -1786,6 +1804,11 @@ class Function_type : public Type
receiver() const
{ return this->receiver_; }
+ // Add an escape note for the receiver.
+ void
+ add_receiver_note(int encoding)
+ { this->receiver_->set_note(Escape_note::make_tag(encoding)); }
+
// Get the return names and types.
const Typed_identifier_list*
results() const
@@ -1796,6 +1819,21 @@ class Function_type : public Type
parameters() const
{ return this->parameters_; }
+ // Add an escape note for the ith parameter.
+ void
+ add_parameter_note(int index, int encoding)
+ { this->parameters_->at(index).set_note(Escape_note::make_tag(encoding)); }
+
+ // Whether this function has been tagged during escape analysis.
+ bool
+ is_tagged() const
+ { return this->is_tagged_; }
+
+ // Mark this function as tagged after analyzing its escape.
+ void
+ set_is_tagged()
+ { this->is_tagged_ = true; }
+
// Whether this is a varargs function.
bool
is_varargs() const
@@ -1950,6 +1988,9 @@ class Function_type : public Type
// The backend representation of this type for backend function
// declarations and definitions.
Btype* fnbtype_;
+ // Whether this function has been analyzed by escape analysis. If this is
+ // TRUE, this function type's parameters contain a summary of the analysis.
+ bool is_tagged_;
};
// The type of a function's backend representation.
diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c
index 7615842b332..dd50a1e4ec0 100644
--- a/gcc/graphite-scop-detection.c
+++ b/gcc/graphite-scop-detection.c
@@ -1722,8 +1722,7 @@ static void
build_cross_bb_scalars_def (scop_p scop, tree def, basic_block def_bb,
vec<tree> *writes)
{
- gcc_assert (def);
- if (!is_gimple_reg (def))
+ if (!def || !is_gimple_reg (def))
return;
/* Do not gather scalar variables that can be analyzed by SCEV as they can be
diff --git a/gcc/hard-reg-set.h b/gcc/hard-reg-set.h
index 85541f7fda3..b94ebb3929f 100644
--- a/gcc/hard-reg-set.h
+++ b/gcc/hard-reg-set.h
@@ -660,6 +660,12 @@ struct target_hard_regs {
across calls even if we are willing to save and restore them. */
HARD_REG_SET x_call_fixed_reg_set;
+ /* Contains registers that are fixed use -- i.e. in fixed_reg_set -- but
+ only if they are not merely part of that set because they are global
+ regs. Global regs that are not otherwise fixed can still take part
+ in register allocation. */
+ HARD_REG_SET x_fixed_nonglobal_reg_set;
+
/* Contains 1 for registers that are set or clobbered by calls. */
/* ??? Ideally, this would be just call_used_regs plus global_regs, but
for someone's bright idea to have call_used_regs strictly include
@@ -722,6 +728,8 @@ extern struct target_hard_regs *this_target_hard_regs;
(this_target_hard_regs->x_fixed_regs)
#define fixed_reg_set \
(this_target_hard_regs->x_fixed_reg_set)
+#define fixed_nonglobal_reg_set \
+ (this_target_hard_regs->x_fixed_nonglobal_reg_set)
#define call_used_regs \
(this_target_hard_regs->x_call_used_regs)
#define call_really_used_regs \
diff --git a/gcc/hsa-gen.c b/gcc/hsa-gen.c
index 5baf6073e3b..cf7d434bce4 100644
--- a/gcc/hsa-gen.c
+++ b/gcc/hsa-gen.c
@@ -203,9 +203,13 @@ hsa_symbol::fillup_for_decl (tree decl)
{
m_decl = decl;
m_type = hsa_type_for_tree_type (TREE_TYPE (decl), &m_dim, false);
-
if (hsa_seen_error ())
- m_seen_error = true;
+ {
+ m_seen_error = true;
+ return;
+ }
+
+ m_align = MAX (m_align, hsa_natural_alignment (m_type));
}
/* Constructor of class representing global HSA function/kernel information and
@@ -929,6 +933,14 @@ get_symbol_for_decl (tree decl)
BRIG_LINKAGE_PROGRAM, true,
BRIG_ALLOCATION_PROGRAM, align);
hsa_cfun->m_global_symbols.safe_push (sym);
+ sym->fillup_for_decl (decl);
+ if (sym->m_align > align)
+ {
+ sym->m_seen_error = true;
+ HSA_SORRY_ATV (EXPR_LOCATION (decl),
+ "HSA specification requires that %E is at least "
+ "naturally aligned", decl);
+ }
}
else
{
@@ -944,12 +956,11 @@ get_symbol_for_decl (tree decl)
sym = new hsa_symbol (BRIG_TYPE_NONE, BRIG_SEGMENT_PRIVATE,
BRIG_LINKAGE_FUNCTION);
sym->m_align = align;
+ sym->fillup_for_decl (decl);
hsa_cfun->m_private_variables.safe_push (sym);
}
- sym->fillup_for_decl (decl);
sym->m_name = hsa_get_declaration_name (decl);
-
*slot = sym;
return sym;
}
@@ -3471,6 +3482,12 @@ gen_hsa_insns_for_switch_stmt (gswitch *s, hsa_bb *hbb)
basic_block default_label_bb = label_to_block_fn (func,
CASE_LABEL (default_label));
+ if (!gimple_seq_empty_p (phi_nodes (default_label_bb)))
+ {
+ default_label_bb = split_edge (find_edge (e->dest, default_label_bb));
+ hsa_init_new_bb (default_label_bb);
+ }
+
make_edge (e->src, default_label_bb, EDGE_FALSE_VALUE);
hsa_cfun->m_modified_cfg = true;
diff --git a/gcc/input.c b/gcc/input.c
index 9779198720d..61b1e4477fc 100644
--- a/gcc/input.c
+++ b/gcc/input.c
@@ -789,6 +789,16 @@ expansion_point_location_if_in_system_header (source_location location)
return location;
}
+/* If LOCATION is a virtual location for a token coming from the expansion
+ of a macro, unwind to the location of the expansion point of the macro. */
+
+source_location
+expansion_point_location (source_location location)
+{
+ return linemap_resolve_location (line_table, location,
+ LRK_MACRO_EXPANSION_POINT, NULL);
+}
+
#define ONE_K 1024
#define ONE_M (ONE_K * ONE_K)
diff --git a/gcc/input.h b/gcc/input.h
index 97c43332ee7..ae4fecfe11c 100644
--- a/gcc/input.h
+++ b/gcc/input.h
@@ -42,6 +42,7 @@ extern const char *location_get_source_line (const char *file_path, int line,
int *line_size);
extern expanded_location expand_location_to_spelling_point (source_location);
extern source_location expansion_point_location_if_in_system_header (source_location);
+extern source_location expansion_point_location (source_location);
/* Historically GCC used location_t, while cpp used source_location.
This could be removed but it hardly seems worth the effort. */
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index e70c73aba8a..c867ddc0ef7 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "expr.h"
#include "ubsan.h"
#include "recog.h"
+#include "builtins.h"
/* The names of each internal function, indexed by function number. */
const char *const internal_fn_name_array[] = {
@@ -2118,6 +2119,30 @@ expand_SET_EDOM (internal_fn, gcall *)
#endif
}
+/* Expand atomic bit test and set. */
+
+static void
+expand_ATOMIC_BIT_TEST_AND_SET (internal_fn, gcall *call)
+{
+ expand_ifn_atomic_bit_test_and (call);
+}
+
+/* Expand atomic bit test and complement. */
+
+static void
+expand_ATOMIC_BIT_TEST_AND_COMPLEMENT (internal_fn, gcall *call)
+{
+ expand_ifn_atomic_bit_test_and (call);
+}
+
+/* Expand atomic bit test and reset. */
+
+static void
+expand_ATOMIC_BIT_TEST_AND_RESET (internal_fn, gcall *call)
+{
+ expand_ifn_atomic_bit_test_and (call);
+}
+
/* Expand a call to FN using the operands in STMT. FN has a single
output operand and NARGS input operands. */
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index a62f3e8034e..e729d852a13 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -189,6 +189,11 @@ DEF_INTERNAL_FN (GOACC_REDUCTION, ECF_NOTHROW | ECF_LEAF, NULL)
current target. */
DEF_INTERNAL_FN (SET_EDOM, ECF_LEAF | ECF_NOTHROW, NULL)
+/* Atomic functions. */
+DEF_INTERNAL_FN (ATOMIC_BIT_TEST_AND_SET, ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (ATOMIC_BIT_TEST_AND_COMPLEMENT, ECF_LEAF | ECF_NOTHROW, NULL)
+DEF_INTERNAL_FN (ATOMIC_BIT_TEST_AND_RESET, ECF_LEAF | ECF_NOTHROW, NULL)
+
#undef DEF_INTERNAL_INT_FN
#undef DEF_INTERNAL_FLT_FN
#undef DEF_INTERNAL_OPTAB_FN
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 5900d4d9158..8caa973e46c 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1026,9 +1026,10 @@ ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
{
tree restype, res;
- gcc_checking_assert (is_gimple_ip_invariant (input));
if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
return input;
+ if (!is_gimple_ip_invariant (input))
+ return NULL_TREE;
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
== tcc_comparison)
@@ -1999,9 +2000,9 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
if (ie->indirect_info->agg_contents)
{
- if (agg_reps)
+ t = NULL;
+ if (agg_reps && ie->indirect_info->guaranteed_unmodified)
{
- t = NULL;
while (agg_reps)
{
if (agg_reps->index == param_index
@@ -2014,15 +2015,22 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
agg_reps = agg_reps->next;
}
}
- else if (known_aggs.length () > (unsigned int) param_index)
+ if (!t)
{
struct ipa_agg_jump_function *agg;
- agg = known_aggs[param_index];
- t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
- ie->indirect_info->by_ref);
+ if (known_aggs.length () > (unsigned int) param_index)
+ agg = known_aggs[param_index];
+ else
+ agg = NULL;
+ bool from_global_constant;
+ t = ipa_find_agg_cst_for_param (agg, known_csts[param_index],
+ ie->indirect_info->offset,
+ ie->indirect_info->by_ref,
+ &from_global_constant);
+ if (!from_global_constant
+ && !ie->indirect_info->guaranteed_unmodified)
+ t = NULL_TREE;
}
- else
- t = NULL;
}
else
t = known_csts[param_index];
@@ -2066,7 +2074,8 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
{
struct ipa_agg_jump_function *agg;
agg = known_aggs[param_index];
- t = ipa_find_agg_cst_for_param (agg, ie->indirect_info->offset,
+ t = ipa_find_agg_cst_for_param (agg, known_csts[param_index],
+ ie->indirect_info->offset,
true);
}
diff --git a/gcc/ipa-icf.c b/gcc/ipa-icf.c
index dda5cacc993..3c04b5abc32 100644
--- a/gcc/ipa-icf.c
+++ b/gcc/ipa-icf.c
@@ -2258,6 +2258,8 @@ sem_variable::merge (sem_item *alias_item)
varpool_node::create_alias (alias_var->decl, decl);
alias->resolve_alias (original);
+ if (DECL_PT_UID_SET_P (original->decl))
+ SET_DECL_PT_UID (alias->decl, DECL_PT_UID (original->decl));
if (dump_file)
fprintf (dump_file, "Unified; Variable alias has been created.\n\n");
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index f8ca825e24f..5d6721813d8 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -216,13 +216,14 @@ struct agg_position_info
bool by_ref;
};
-/* Add condition to condition list CONDS. AGGPOS describes whether the used
- oprand is loaded from an aggregate and where in the aggregate it is. It can
- be NULL, which means this not a load from an aggregate. */
+/* Add condition to condition list SUMMARY. OPERAND_NUM, SIZE, CODE and VAL
+ correspond to fields of condition structure. AGGPOS describes whether the
+ used operand is loaded from an aggregate and where in the aggregate it is.
+ It can be NULL, which means this not a load from an aggregate. */
static struct predicate
add_condition (struct inline_summary *summary, int operand_num,
- struct agg_position_info *aggpos,
+ HOST_WIDE_INT size, struct agg_position_info *aggpos,
enum tree_code code, tree val)
{
int i;
@@ -248,6 +249,7 @@ add_condition (struct inline_summary *summary, int operand_num,
for (i = 0; vec_safe_iterate (summary->conds, i, &c); i++)
{
if (c->operand_num == operand_num
+ && c->size == size
&& c->code == code
&& c->val == val
&& c->agg_contents == agg_contents
@@ -264,6 +266,7 @@ add_condition (struct inline_summary *summary, int operand_num,
new_cond.agg_contents = agg_contents;
new_cond.by_ref = by_ref;
new_cond.offset = offset;
+ new_cond.size = size;
vec_safe_push (summary->conds, new_cond);
return single_cond_predicate (i + predicate_first_dynamic_condition);
}
@@ -850,7 +853,8 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
if (known_aggs.exists ())
{
agg = known_aggs[c->operand_num];
- val = ipa_find_agg_cst_for_param (agg, c->offset, c->by_ref);
+ val = ipa_find_agg_cst_for_param (agg, known_vals[c->operand_num],
+ c->offset, c->by_ref);
}
else
val = NULL_TREE;
@@ -867,21 +871,25 @@ evaluate_conditions_for_known_args (struct cgraph_node *node,
clause |= 1 << (i + predicate_first_dynamic_condition);
continue;
}
- if (c->code == IS_NOT_CONSTANT || c->code == CHANGED)
+ if (c->code == CHANGED)
continue;
- if (operand_equal_p (TYPE_SIZE (TREE_TYPE (c->val)),
- TYPE_SIZE (TREE_TYPE (val)), 0))
+ if (tree_to_shwi (TYPE_SIZE (TREE_TYPE (val))) != c->size)
{
- val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val);
+ clause |= 1 << (i + predicate_first_dynamic_condition);
+ continue;
+ }
+ if (c->code == IS_NOT_CONSTANT)
+ continue;
- res = val
- ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val)
- : NULL;
+ val = fold_unary (VIEW_CONVERT_EXPR, TREE_TYPE (c->val), val);
+ res = val
+ ? fold_binary_to_constant (c->code, boolean_type_node, val, c->val)
+ : NULL;
+
+ if (res && integer_zerop (res))
+ continue;
- if (res && integer_zerop (res))
- continue;
- }
clause |= 1 << (i + predicate_first_dynamic_condition);
}
return clause;
@@ -1069,6 +1077,7 @@ reset_inline_summary (struct cgraph_node *node,
reset_inline_edge_summary (e);
for (e = node->indirect_calls; e; e = e->next_callee)
reset_inline_edge_summary (e);
+ info->fp_expressions = false;
}
/* Hook that is called by cgraph.c when a node is removed. */
@@ -1423,6 +1432,8 @@ dump_inline_summary (FILE *f, struct cgraph_node *node)
fprintf (f, " inlinable");
if (s->contains_cilk_spawn)
fprintf (f, " contains_cilk_spawn");
+ if (s->fp_expressions)
+ fprintf (f, " fp_expression");
fprintf (f, "\n self time: %i\n", s->self_time);
fprintf (f, " global time: %i\n", s->time);
fprintf (f, " self size: %i\n", s->self_size);
@@ -1487,19 +1498,23 @@ initialize_inline_failed (struct cgraph_edge *e)
{
struct cgraph_node *callee = e->callee;
- if (e->indirect_unknown_callee)
+ if (e->inline_failed && e->inline_failed != CIF_BODY_NOT_AVAILABLE
+ && cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
+ ;
+ else if (e->indirect_unknown_callee)
e->inline_failed = CIF_INDIRECT_UNKNOWN_CALL;
else if (!callee->definition)
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
else if (callee->local.redefined_extern_inline)
e->inline_failed = CIF_REDEFINED_EXTERN_INLINE;
- else if (e->call_stmt_cannot_inline_p)
- e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
else if (cfun && fn_contains_cilk_spawn_p (cfun))
/* We can't inline if the function is spawing a function. */
- e->inline_failed = CIF_FUNCTION_NOT_INLINABLE;
+ e->inline_failed = CIF_CILK_SPAWN;
else
e->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
+ gcc_checking_assert (!e->call_stmt_cannot_inline_p
+ || cgraph_inline_failed_type (e->inline_failed)
+ == CIF_FINAL_ERROR);
}
/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
@@ -1515,16 +1530,21 @@ mark_modified (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef ATTRIBUTE_UNUSED,
}
/* If OP refers to value of function parameter, return the corresponding
- parameter. */
+ parameter. If non-NULL, the size of the memory load (or the SSA_NAME of the
+ PARM_DECL) will be stored to *SIZE_P in that case too. */
static tree
-unmodified_parm_1 (gimple *stmt, tree op)
+unmodified_parm_1 (gimple *stmt, tree op, HOST_WIDE_INT *size_p)
{
/* SSA_NAME referring to parm default def? */
if (TREE_CODE (op) == SSA_NAME
&& SSA_NAME_IS_DEFAULT_DEF (op)
&& TREE_CODE (SSA_NAME_VAR (op)) == PARM_DECL)
- return SSA_NAME_VAR (op);
+ {
+ if (size_p)
+ *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
+ return SSA_NAME_VAR (op);
+ }
/* Non-SSA parm reference? */
if (TREE_CODE (op) == PARM_DECL)
{
@@ -1535,18 +1555,24 @@ unmodified_parm_1 (gimple *stmt, tree op)
walk_aliased_vdefs (&refd, gimple_vuse (stmt), mark_modified, &modified,
NULL);
if (!modified)
- return op;
+ {
+ if (size_p)
+ *size_p = tree_to_shwi (TYPE_SIZE (TREE_TYPE (op)));
+ return op;
+ }
}
return NULL_TREE;
}
/* If OP refers to value of function parameter, return the corresponding
- parameter. Also traverse chains of SSA register assignments. */
+ parameter. Also traverse chains of SSA register assignments. If non-NULL,
+ the size of the memory load (or the SSA_NAME of the PARM_DECL) will be
+ stored to *SIZE_P in that case too. */
static tree
-unmodified_parm (gimple *stmt, tree op)
+unmodified_parm (gimple *stmt, tree op, HOST_WIDE_INT *size_p)
{
- tree res = unmodified_parm_1 (stmt, op);
+ tree res = unmodified_parm_1 (stmt, op, size_p);
if (res)
return res;
@@ -1554,23 +1580,25 @@ unmodified_parm (gimple *stmt, tree op)
&& !SSA_NAME_IS_DEFAULT_DEF (op)
&& gimple_assign_single_p (SSA_NAME_DEF_STMT (op)))
return unmodified_parm (SSA_NAME_DEF_STMT (op),
- gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)));
+ gimple_assign_rhs1 (SSA_NAME_DEF_STMT (op)),
+ size_p);
return NULL_TREE;
}
/* If OP refers to a value of a function parameter or value loaded from an
aggregate passed to a parameter (either by value or reference), return TRUE
- and store the number of the parameter to *INDEX_P and information whether
- and how it has been loaded from an aggregate into *AGGPOS. INFO describes
- the function parameters, STMT is the statement in which OP is used or
- loaded. */
+ and store the number of the parameter to *INDEX_P, the access size into
+ *SIZE_P, and information whether and how it has been loaded from an
+ aggregate into *AGGPOS. INFO describes the function parameters, STMT is the
+ statement in which OP is used or loaded. */
static bool
unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
gimple *stmt, tree op, int *index_p,
+ HOST_WIDE_INT *size_p,
struct agg_position_info *aggpos)
{
- tree res = unmodified_parm_1 (stmt, op);
+ tree res = unmodified_parm_1 (stmt, op, size_p);
gcc_checking_assert (aggpos);
if (res)
@@ -1591,14 +1619,14 @@ unmodified_parm_or_parm_agg_item (struct ipa_func_body_info *fbi,
stmt = SSA_NAME_DEF_STMT (op);
op = gimple_assign_rhs1 (stmt);
if (!REFERENCE_CLASS_P (op))
- return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p,
+ return unmodified_parm_or_parm_agg_item (fbi, stmt, op, index_p, size_p,
aggpos);
}
aggpos->agg_contents = true;
return ipa_load_from_parm_agg (fbi, fbi->info->descriptors,
stmt, op, index_p, &aggpos->offset,
- NULL, &aggpos->by_ref);
+ size_p, &aggpos->by_ref);
}
/* See if statement might disappear after inlining.
@@ -1649,7 +1677,7 @@ eliminated_by_inlining_prob (gimple *stmt)
inner_lhs = lhs;
/* Reads of parameter are expected to be free. */
- if (unmodified_parm (stmt, inner_rhs))
+ if (unmodified_parm (stmt, inner_rhs, NULL))
rhs_free = true;
/* Match expressions of form &this->field. Those will most likely
combine with something upstream after inlining. */
@@ -1659,7 +1687,7 @@ eliminated_by_inlining_prob (gimple *stmt)
if (TREE_CODE (op) == PARM_DECL)
rhs_free = true;
else if (TREE_CODE (op) == MEM_REF
- && unmodified_parm (stmt, TREE_OPERAND (op, 0)))
+ && unmodified_parm (stmt, TREE_OPERAND (op, 0), NULL))
rhs_free = true;
}
@@ -1672,7 +1700,7 @@ eliminated_by_inlining_prob (gimple *stmt)
/* Reads of parameters passed by reference
expected to be free (i.e. optimized out after inlining). */
if (TREE_CODE (inner_rhs) == MEM_REF
- && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0)))
+ && unmodified_parm (stmt, TREE_OPERAND (inner_rhs, 0), NULL))
rhs_free = true;
/* Copying parameter passed by reference into gimple register is
@@ -1713,7 +1741,7 @@ eliminated_by_inlining_prob (gimple *stmt)
if (TREE_CODE (inner_lhs) == PARM_DECL
|| TREE_CODE (inner_lhs) == RESULT_DECL
|| (TREE_CODE (inner_lhs) == MEM_REF
- && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0))
+ && (unmodified_parm (stmt, TREE_OPERAND (inner_lhs, 0), NULL)
|| (TREE_CODE (TREE_OPERAND (inner_lhs, 0)) == SSA_NAME
&& SSA_NAME_VAR (TREE_OPERAND (inner_lhs, 0))
&& TREE_CODE (SSA_NAME_VAR (TREE_OPERAND
@@ -1744,6 +1772,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
gimple *last;
tree op;
int index;
+ HOST_WIDE_INT size;
struct agg_position_info aggpos;
enum tree_code code, inverted_code;
edge e;
@@ -1760,7 +1789,7 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
/* TODO: handle conditionals like
var = op0 < 4;
if (var != 0). */
- if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos))
+ if (unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
{
code = gimple_cond_code (last);
inverted_code = invert_tree_comparison (code, HONOR_NANS (op));
@@ -1774,9 +1803,10 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
unordered one. Be sure it is not confused with NON_CONSTANT. */
if (this_code != ERROR_MARK)
{
- struct predicate p = add_condition
- (summary, index, &aggpos, this_code,
- unshare_expr_without_location (gimple_cond_rhs (last)));
+ struct predicate p
+ = add_condition (summary, index, size, &aggpos, this_code,
+ unshare_expr_without_location
+ (gimple_cond_rhs (last)));
e->aux = edge_predicate_pool.allocate ();
*(struct predicate *) e->aux = p;
}
@@ -1803,11 +1833,12 @@ set_cond_stmt_execution_predicate (struct ipa_func_body_info *fbi,
|| gimple_call_num_args (set_stmt) != 1)
return;
op2 = gimple_call_arg (set_stmt, 0);
- if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &aggpos))
+ if (!unmodified_parm_or_parm_agg_item (fbi, set_stmt, op2, &index, &size,
+ &aggpos))
return;
FOR_EACH_EDGE (e, ei, bb->succs) if (e->flags & EDGE_FALSE_VALUE)
{
- struct predicate p = add_condition (summary, index, &aggpos,
+ struct predicate p = add_condition (summary, index, size, &aggpos,
IS_NOT_CONSTANT, NULL_TREE);
e->aux = edge_predicate_pool.allocate ();
*(struct predicate *) e->aux = p;
@@ -1826,6 +1857,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
gimple *lastg;
tree op;
int index;
+ HOST_WIDE_INT size;
struct agg_position_info aggpos;
edge e;
edge_iterator ei;
@@ -1837,7 +1869,7 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
return;
gswitch *last = as_a <gswitch *> (lastg);
op = gimple_switch_index (last);
- if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &aggpos))
+ if (!unmodified_parm_or_parm_agg_item (fbi, last, op, &index, &size, &aggpos))
return;
FOR_EACH_EDGE (e, ei, bb->succs)
@@ -1862,14 +1894,14 @@ set_switch_stmt_execution_predicate (struct ipa_func_body_info *fbi,
if (!min && !max)
p = true_predicate ();
else if (!max)
- p = add_condition (summary, index, &aggpos, EQ_EXPR,
+ p = add_condition (summary, index, size, &aggpos, EQ_EXPR,
unshare_expr_without_location (min));
else
{
struct predicate p1, p2;
- p1 = add_condition (summary, index, &aggpos, GE_EXPR,
+ p1 = add_condition (summary, index, size, &aggpos, GE_EXPR,
unshare_expr_without_location (min));
- p2 = add_condition (summary, index, &aggpos, LE_EXPR,
+ p2 = add_condition (summary, index, size, &aggpos, LE_EXPR,
unshare_expr_without_location (max));
p = and_predicates (summary->conds, &p1, &p2);
}
@@ -1970,13 +2002,14 @@ will_be_nonconstant_expr_predicate (struct ipa_node_params *info,
{
tree parm;
int index;
+ HOST_WIDE_INT size;
while (UNARY_CLASS_P (expr))
expr = TREE_OPERAND (expr, 0);
- parm = unmodified_parm (NULL, expr);
+ parm = unmodified_parm (NULL, expr, &size);
if (parm && (index = ipa_get_param_decl_index (info, parm)) >= 0)
- return add_condition (summary, index, NULL, CHANGED, NULL_TREE);
+ return add_condition (summary, index, size, NULL, CHANGED, NULL_TREE);
if (is_gimple_min_invariant (expr))
return false_predicate ();
if (TREE_CODE (expr) == SSA_NAME)
@@ -2037,6 +2070,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
struct predicate op_non_const;
bool is_load;
int base_index;
+ HOST_WIDE_INT size;
struct agg_position_info aggpos;
/* What statments might be optimized away
@@ -2060,7 +2094,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
tree op;
gcc_assert (gimple_assign_single_p (stmt));
op = gimple_assign_rhs1 (stmt);
- if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index,
+ if (!unmodified_parm_or_parm_agg_item (fbi, stmt, op, &base_index, &size,
&aggpos))
return p;
}
@@ -2071,7 +2105,7 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
adding conditionals. */
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
- tree parm = unmodified_parm (stmt, use);
+ tree parm = unmodified_parm (stmt, use, NULL);
/* For arguments we can build a condition. */
if (parm && ipa_get_param_decl_index (fbi->info, parm) >= 0)
continue;
@@ -2086,18 +2120,19 @@ will_be_nonconstant_predicate (struct ipa_func_body_info *fbi,
if (is_load)
op_non_const =
- add_condition (summary, base_index, &aggpos, CHANGED, NULL);
+ add_condition (summary, base_index, size, &aggpos, CHANGED, NULL);
else
op_non_const = false_predicate ();
FOR_EACH_SSA_TREE_OPERAND (use, stmt, iter, SSA_OP_USE)
{
- tree parm = unmodified_parm (stmt, use);
+ HOST_WIDE_INT size;
+ tree parm = unmodified_parm (stmt, use, &size);
int index;
if (parm && (index = ipa_get_param_decl_index (fbi->info, parm)) >= 0)
{
if (index != base_index)
- p = add_condition (summary, index, NULL, CHANGED, NULL_TREE);
+ p = add_condition (summary, index, size, NULL, CHANGED, NULL_TREE);
else
continue;
}
@@ -2459,6 +2494,21 @@ clobber_only_eh_bb_p (basic_block bb, bool need_eh = true)
return true;
}
+/* Return true if STMT compute a floating point expression that may be affected
+ by -ffast-math and similar flags. */
+
+static bool
+fp_expression_p (gimple *stmt)
+{
+ ssa_op_iter i;
+ tree op;
+
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_DEF|SSA_OP_USE)
+ if (FLOAT_TYPE_P (TREE_TYPE (op)))
+ return true;
+ return false;
+}
+
/* Compute function body size parameters for NODE.
When EARLY is true, we compute only simple summaries without
non-trivial predicates to drive the early inliner. */
@@ -2733,6 +2783,13 @@ estimate_function_body_sizes (struct cgraph_node *node, bool early)
this_time * (2 - prob), &p);
}
+ if (!info->fp_expressions && fp_expression_p (stmt))
+ {
+ info->fp_expressions = true;
+ if (dump_file)
+ fprintf (dump_file, " fp_expression set\n");
+ }
+
gcc_assert (time >= 0);
gcc_assert (size >= 0);
}
@@ -2891,67 +2948,78 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
info = inline_summaries->get (node);
reset_inline_summary (node, info);
- /* FIXME: Thunks are inlinable, but tree-inline don't know how to do that.
- Once this happen, we will need to more curefully predict call
- statement size. */
- if (node->thunk.thunk_p)
- {
- struct inline_edge_summary *es = inline_edge_summary (node->callees);
- struct predicate t = true_predicate ();
-
- info->inlinable = 0;
- node->callees->call_stmt_cannot_inline_p = true;
- node->local.can_change_signature = false;
- es->call_stmt_time = 1;
- es->call_stmt_size = 1;
- account_size_time (info, 0, 0, &t);
- return;
- }
-
- /* Even is_gimple_min_invariant rely on current_function_decl. */
- push_cfun (DECL_STRUCT_FUNCTION (node->decl));
-
/* Estimate the stack size for the function if we're optimizing. */
- self_stack_size = optimize ? estimated_stack_frame_size (node) : 0;
+ self_stack_size = optimize && !node->thunk.thunk_p
+ ? estimated_stack_frame_size (node) : 0;
info->estimated_self_stack_size = self_stack_size;
info->estimated_stack_size = self_stack_size;
info->stack_frame_offset = 0;
- /* Can this function be inlined at all? */
- if (!opt_for_fn (node->decl, optimize)
- && !lookup_attribute ("always_inline",
- DECL_ATTRIBUTES (node->decl)))
- info->inlinable = false;
- else
- info->inlinable = tree_inlinable_function_p (node->decl);
-
- info->contains_cilk_spawn = fn_contains_cilk_spawn_p (cfun);
-
- /* Type attributes can use parameter indices to describe them. */
- if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
- node->local.can_change_signature = false;
- else
+ if (node->thunk.thunk_p)
{
- /* Otherwise, inlinable functions always can change signature. */
- if (info->inlinable)
- node->local.can_change_signature = true;
- else
+ struct inline_edge_summary *es = inline_edge_summary (node->callees);
+ struct predicate t = true_predicate ();
+
+ node->local.can_change_signature = false;
+ es->call_stmt_size = eni_size_weights.call_cost;
+ es->call_stmt_time = eni_time_weights.call_cost;
+ account_size_time (info, INLINE_SIZE_SCALE * 2,
+ INLINE_TIME_SCALE * 2, &t);
+ t = not_inlined_predicate ();
+ account_size_time (info, 2 * INLINE_SIZE_SCALE, 0, &t);
+ inline_update_overall_summary (node);
+ info->self_size = info->size;
+ info->self_time = info->time;
+ /* We can not inline instrumetnation clones. */
+ if (node->thunk.add_pointer_bounds_args)
{
- /* Functions calling builtin_apply can not change signature. */
- for (e = node->callees; e; e = e->next_callee)
- {
- tree cdecl = e->callee->decl;
- if (DECL_BUILT_IN (cdecl)
- && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
- && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
- || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
- break;
- }
- node->local.can_change_signature = !e;
+ info->inlinable = false;
+ node->callees->inline_failed = CIF_CHKP;
}
+ else
+ info->inlinable = true;
}
- estimate_function_body_sizes (node, early);
-
+ else
+ {
+ /* Even is_gimple_min_invariant rely on current_function_decl. */
+ push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+
+ /* Can this function be inlined at all? */
+ if (!opt_for_fn (node->decl, optimize)
+ && !lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (node->decl)))
+ info->inlinable = false;
+ else
+ info->inlinable = tree_inlinable_function_p (node->decl);
+
+ info->contains_cilk_spawn = fn_contains_cilk_spawn_p (cfun);
+
+ /* Type attributes can use parameter indices to describe them. */
+ if (TYPE_ATTRIBUTES (TREE_TYPE (node->decl)))
+ node->local.can_change_signature = false;
+ else
+ {
+ /* Otherwise, inlinable functions always can change signature. */
+ if (info->inlinable)
+ node->local.can_change_signature = true;
+ else
+ {
+ /* Functions calling builtin_apply can not change signature. */
+ for (e = node->callees; e; e = e->next_callee)
+ {
+ tree cdecl = e->callee->decl;
+ if (DECL_BUILT_IN (cdecl)
+ && DECL_BUILT_IN_CLASS (cdecl) == BUILT_IN_NORMAL
+ && (DECL_FUNCTION_CODE (cdecl) == BUILT_IN_APPLY_ARGS
+ || DECL_FUNCTION_CODE (cdecl) == BUILT_IN_VA_START))
+ break;
+ }
+ node->local.can_change_signature = !e;
+ }
+ }
+ estimate_function_body_sizes (node, early);
+ pop_cfun ();
+ }
for (e = node->callees; e; e = e->next_callee)
if (e->callee->comdat_local_p ())
break;
@@ -2968,8 +3036,6 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
gcc_assert (info->time == info->self_time
&& info->size == info->self_size);
}
-
- pop_cfun ();
}
@@ -3377,7 +3443,8 @@ remap_predicate (struct inline_summary *info,
ap.by_ref = c->by_ref;
cond_predicate = add_condition (info,
operand_map[c->operand_num],
- &ap, c->code, c->val);
+ c->size, &ap, c->code,
+ c->val);
}
}
/* Fixed conditions remains same, construct single
@@ -3577,6 +3644,8 @@ inline_merge_summary (struct cgraph_edge *edge)
else
toplev_predicate = true_predicate ();
+ info->fp_expressions |= callee_info->fp_expressions;
+
if (callee_info->conds)
evaluate_properties_for_edge (edge, true, &clause, NULL, NULL, NULL);
if (ipa_node_params_sum && callee_info->conds)
@@ -4080,17 +4149,9 @@ inline_analyze_function (struct cgraph_node *node)
{
struct cgraph_edge *e;
for (e = node->callees; e; e = e->next_callee)
- {
- if (e->inline_failed == CIF_FUNCTION_NOT_CONSIDERED)
- e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
- e->call_stmt_cannot_inline_p = true;
- }
+ e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
for (e = node->indirect_calls; e; e = e->next_callee)
- {
- if (e->inline_failed == CIF_FUNCTION_NOT_CONSIDERED)
- e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
- e->call_stmt_cannot_inline_p = true;
- }
+ e->inline_failed = CIF_FUNCTION_NOT_OPTIMIZED;
}
pop_cfun ();
@@ -4229,6 +4290,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
bp = streamer_read_bitpack (&ib);
info->inlinable = bp_unpack_value (&bp, 1);
info->contains_cilk_spawn = bp_unpack_value (&bp, 1);
+ info->fp_expressions = bp_unpack_value (&bp, 1);
count2 = streamer_read_uhwi (&ib);
gcc_assert (!info->conds);
@@ -4236,6 +4298,7 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data,
{
struct condition c;
c.operand_num = streamer_read_uhwi (&ib);
+ c.size = streamer_read_uhwi (&ib);
c.code = (enum tree_code) streamer_read_uhwi (&ib);
c.val = stream_read_tree (&ib, data_in);
bp = streamer_read_bitpack (&ib);
@@ -4395,11 +4458,13 @@ inline_write_summary (void)
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, info->inlinable, 1);
bp_pack_value (&bp, info->contains_cilk_spawn, 1);
+ bp_pack_value (&bp, info->fp_expressions, 1);
streamer_write_bitpack (&bp);
streamer_write_uhwi (ob, vec_safe_length (info->conds));
for (i = 0; vec_safe_iterate (info->conds, i, &c); i++)
{
streamer_write_uhwi (ob, c->operand_num);
+ streamer_write_uhwi (ob, c->size);
streamer_write_uhwi (ob, c->code);
stream_write_tree (ob, c->val, true);
bp = bitpack_create (ob->main_stream);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index f966fb00ffb..90a0d7ebbb7 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -314,12 +314,20 @@ inline_call (struct cgraph_edge *e, bool update_original,
/* Don't even think of inlining inline clone. */
gcc_assert (!callee->global.inlined_to);
- e->inline_failed = CIF_OK;
- DECL_POSSIBLY_INLINED (callee->decl) = true;
-
to = e->caller;
if (to->global.inlined_to)
to = to->global.inlined_to;
+ if (to->thunk.thunk_p)
+ {
+ if (in_lto_p)
+ to->get_untransformed_body ();
+ to->expand_thunk (false, true);
+ e = to->callees;
+ }
+
+
+ e->inline_failed = CIF_OK;
+ DECL_POSSIBLY_INLINED (callee->decl) = true;
if (DECL_FUNCTION_PERSONALITY (callee->decl))
DECL_FUNCTION_PERSONALITY (to->decl)
@@ -338,6 +346,63 @@ inline_call (struct cgraph_edge *e, bool update_original,
DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)
= build_optimization_node (&opts);
}
+ inline_summary *caller_info = inline_summaries->get (to);
+ inline_summary *callee_info = inline_summaries->get (callee);
+ if (!caller_info->fp_expressions && callee_info->fp_expressions)
+ {
+ caller_info->fp_expressions = true;
+ if (opt_for_fn (callee->decl, flag_rounding_math)
+ != opt_for_fn (to->decl, flag_rounding_math)
+ || opt_for_fn (callee->decl, flag_trapping_math)
+ != opt_for_fn (to->decl, flag_trapping_math)
+ || opt_for_fn (callee->decl, flag_unsafe_math_optimizations)
+ != opt_for_fn (to->decl, flag_unsafe_math_optimizations)
+ || opt_for_fn (callee->decl, flag_finite_math_only)
+ != opt_for_fn (to->decl, flag_finite_math_only)
+ || opt_for_fn (callee->decl, flag_signaling_nans)
+ != opt_for_fn (to->decl, flag_signaling_nans)
+ || opt_for_fn (callee->decl, flag_cx_limited_range)
+ != opt_for_fn (to->decl, flag_cx_limited_range)
+ || opt_for_fn (callee->decl, flag_signed_zeros)
+ != opt_for_fn (to->decl, flag_signed_zeros)
+ || opt_for_fn (callee->decl, flag_associative_math)
+ != opt_for_fn (to->decl, flag_associative_math)
+ || opt_for_fn (callee->decl, flag_reciprocal_math)
+ != opt_for_fn (to->decl, flag_reciprocal_math)
+ || opt_for_fn (callee->decl, flag_errno_math)
+ != opt_for_fn (to->decl, flag_errno_math))
+ {
+ struct gcc_options opts = global_options;
+
+ cl_optimization_restore (&opts, opts_for_fn (to->decl));
+ opts.x_flag_rounding_math
+ = opt_for_fn (callee->decl, flag_rounding_math);
+ opts.x_flag_trapping_math
+ = opt_for_fn (callee->decl, flag_trapping_math);
+ opts.x_flag_unsafe_math_optimizations
+ = opt_for_fn (callee->decl, flag_unsafe_math_optimizations);
+ opts.x_flag_finite_math_only
+ = opt_for_fn (callee->decl, flag_finite_math_only);
+ opts.x_flag_signaling_nans
+ = opt_for_fn (callee->decl, flag_signaling_nans);
+ opts.x_flag_cx_limited_range
+ = opt_for_fn (callee->decl, flag_cx_limited_range);
+ opts.x_flag_signed_zeros
+ = opt_for_fn (callee->decl, flag_signed_zeros);
+ opts.x_flag_associative_math
+ = opt_for_fn (callee->decl, flag_associative_math);
+ opts.x_flag_reciprocal_math
+ = opt_for_fn (callee->decl, flag_reciprocal_math);
+ opts.x_flag_errno_math
+ = opt_for_fn (callee->decl, flag_errno_math);
+ if (dump_file)
+ fprintf (dump_file, "Copying FP flags from %s:%i to %s:%i\n",
+ callee->name (), callee->order, to->name (), to->order);
+ build_optimization_node (&opts);
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (to->decl)
+ = build_optimization_node (&opts);
+ }
+ }
/* If aliases are involved, redirect edge to the actual destination and
possibly remove the aliases. */
@@ -441,6 +506,22 @@ save_inline_function_body (struct cgraph_node *node)
/* first_clone will be turned into real function. */
first_clone = node->clones;
+
+ /* Arrange first clone to not be thunk as those do not have bodies. */
+ if (first_clone->thunk.thunk_p)
+ {
+ while (first_clone->thunk.thunk_p)
+ first_clone = first_clone->next_sibling_clone;
+ first_clone->prev_sibling_clone->next_sibling_clone
+ = first_clone->next_sibling_clone;
+ if (first_clone->next_sibling_clone)
+ first_clone->next_sibling_clone->prev_sibling_clone
+ = first_clone->prev_sibling_clone;
+ first_clone->next_sibling_clone = node->clones;
+ first_clone->prev_sibling_clone = NULL;
+ node->clones->prev_sibling_clone = first_clone;
+ node->clones = first_clone;
+ }
first_clone->decl = copy_node (node->decl);
first_clone->decl->decl_with_vis.symtab_node = first_clone;
gcc_assert (first_clone == cgraph_node::get (first_clone->decl));
@@ -449,7 +530,8 @@ save_inline_function_body (struct cgraph_node *node)
first_clone. */
if (first_clone->next_sibling_clone)
{
- for (n = first_clone->next_sibling_clone; n->next_sibling_clone; n = n->next_sibling_clone)
+ for (n = first_clone->next_sibling_clone; n->next_sibling_clone;
+ n = n->next_sibling_clone)
n->clone_of = first_clone;
n->clone_of = first_clone;
n->next_sibling_clone = first_clone->clones;
@@ -522,9 +604,10 @@ preserve_function_body_p (struct cgraph_node *node)
gcc_assert (symtab->global_info_ready);
gcc_assert (!node->alias && !node->thunk.thunk_p);
- /* Look if there is any clone around. */
- if (node->clones)
- return true;
+ /* Look if there is any non-thunk clone around. */
+ for (node = node->clones; node; node = node->next_sibling_clone)
+ if (!node->thunk.thunk_p)
+ return true;
return false;
}
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index b855fc7f07c..7f0761607b5 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -233,11 +233,11 @@ report_inline_failed_reason (struct cgraph_edge *e)
if ((e->inline_failed == CIF_TARGET_OPTION_MISMATCH
|| e->inline_failed == CIF_OPTIMIZATION_MISMATCH)
&& e->caller->lto_file_data
- && e->callee->function_symbol ()->lto_file_data)
+ && e->callee->ultimate_alias_target ()->lto_file_data)
{
fprintf (dump_file, " LTO objects: %s, %s\n",
e->caller->lto_file_data->file_name,
- e->callee->function_symbol ()->lto_file_data->file_name);
+ e->callee->ultimate_alias_target ()->lto_file_data->file_name);
}
if (e->inline_failed == CIF_TARGET_OPTION_MISMATCH)
cl_target_option_print_diff
@@ -335,12 +335,10 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
e->inline_failed = CIF_OVERWRITABLE;
inlinable = false;
}
+ /* All edges with call_stmt_cannot_inline_p should have inline_failed
+ initialized to one of FINAL_ERROR reasons. */
else if (e->call_stmt_cannot_inline_p)
- {
- if (e->inline_failed != CIF_FUNCTION_NOT_OPTIMIZED)
- e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
- inlinable = false;
- }
+ gcc_unreachable ();
/* Don't inline if the functions have different EH personalities. */
else if (DECL_FUNCTION_PERSONALITY (caller->decl)
&& DECL_FUNCTION_PERSONALITY (callee->decl)
@@ -396,6 +394,8 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
(DECL_DISREGARD_INLINE_LIMITS (callee->decl)
&& lookup_attribute ("always_inline",
DECL_ATTRIBUTES (callee->decl)));
+ inline_summary *caller_info = inline_summaries->get (caller);
+ inline_summary *callee_info = inline_summaries->get (callee);
/* Until GCC 4.9 we did not check the semantics alterning flags
bellow and inline across optimization boundry.
@@ -417,16 +417,21 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
== !opt_for_fn (callee->decl, optimize) || !always_inline))
|| check_match (flag_wrapv)
|| check_match (flag_trapv)
- /* Strictly speaking only when the callee uses FP math. */
- || check_maybe_up (flag_rounding_math)
- || check_maybe_up (flag_trapping_math)
- || check_maybe_down (flag_unsafe_math_optimizations)
- || check_maybe_down (flag_finite_math_only)
- || check_maybe_up (flag_signaling_nans)
- || check_maybe_down (flag_cx_limited_range)
- || check_maybe_up (flag_signed_zeros)
- || check_maybe_down (flag_associative_math)
- || check_maybe_down (flag_reciprocal_math)
+ /* When caller or callee does FP math, be sure FP codegen flags
+ compatible. */
+ || ((caller_info->fp_expressions && callee_info->fp_expressions)
+ && (check_maybe_up (flag_rounding_math)
+ || check_maybe_up (flag_trapping_math)
+ || check_maybe_down (flag_unsafe_math_optimizations)
+ || check_maybe_down (flag_finite_math_only)
+ || check_maybe_up (flag_signaling_nans)
+ || check_maybe_down (flag_cx_limited_range)
+ || check_maybe_up (flag_signed_zeros)
+ || check_maybe_down (flag_associative_math)
+ || check_maybe_down (flag_reciprocal_math)
+ /* Strictly speaking only when the callee contains function
+ calls that may end up setting errno. */
+ || check_maybe_up (flag_errno_math)))
/* We do not want to make code compiled with exceptions to be
brought into a non-EH function unless we know that the callee
does not throw.
@@ -435,9 +440,6 @@ can_inline_edge_p (struct cgraph_edge *e, bool report,
&& DECL_FUNCTION_PERSONALITY (callee->decl))
|| (check_maybe_up (flag_exceptions)
&& DECL_FUNCTION_PERSONALITY (callee->decl))
- /* Strictly speaking only when the callee contains function
- calls that may end up setting errno. */
- || check_maybe_up (flag_errno_math)
/* When devirtualization is diabled for callee, it is not safe
to inline it as we possibly mangled the type info.
Allow early inlining of always inlines. */
@@ -525,6 +527,8 @@ can_early_inline_edge_p (struct cgraph_edge *e)
/* Early inliner might get called at WPA stage when IPA pass adds new
function. In this case we can not really do any of early inlining
because function bodies are missing. */
+ if (cgraph_inline_failed_type (e->inline_failed) == CIF_FINAL_ERROR)
+ return false;
if (!gimple_has_body_p (callee->decl))
{
e->inline_failed = CIF_BODY_NOT_AVAILABLE;
@@ -2023,7 +2027,7 @@ inline_small_functions (void)
inline_call (edge, true, &new_indirect_edges, &overall_size, true);
add_new_edges_to_heap (&edge_heap, new_indirect_edges);
- reset_edge_caches (edge->callee->function_symbol ());
+ reset_edge_caches (edge->callee);
update_callee_keys (&edge_heap, where, updated_nodes);
}
@@ -2737,7 +2741,10 @@ early_inliner (function *fun)
if (edge->callee->decl
&& !gimple_check_call_matching_types (
edge->call_stmt, edge->callee->decl, false))
- edge->call_stmt_cannot_inline_p = true;
+ {
+ edge->inline_failed = CIF_MISMATCHED_ARGUMENTS;
+ edge->call_stmt_cannot_inline_p = true;
+ }
}
if (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - 1)
inline_update_overall_summary (node);
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index 4bf00243e4b..47f8832150a 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -34,6 +34,8 @@ struct GTY(()) condition
/* If agg_contents is set, this is the offset from which the used data was
loaded. */
HOST_WIDE_INT offset;
+ /* Size of the access reading the data (or the PARM_DECL SSA_NAME). */
+ HOST_WIDE_INT size;
tree val;
int operand_num;
ENUM_BITFIELD(tree_code) code : 16;
@@ -132,6 +134,8 @@ struct GTY(()) inline_summary
/* True wen there is only one caller of the function before small function
inlining. */
unsigned int single_caller : 1;
+ /* True if function contains any floating point expressions. */
+ unsigned int fp_expressions : 1;
/* Information about function that will result after applying all the
inline decisions present in the callgraph. Generally kept up to
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index 65482bad366..132b622639c 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -803,6 +803,11 @@ parm_preserved_before_stmt_p (struct ipa_func_body_info *fbi, int index,
bool modified = false;
ao_ref refd;
+ tree base = get_base_address (parm_load);
+ gcc_assert (TREE_CODE (base) == PARM_DECL);
+ if (TREE_READONLY (base))
+ return true;
+
/* FIXME: FBI can be NULL if we are being called from outside
ipa_node_analysis or ipcp_transform_function, which currently happens
during inlining analysis. It would be great to extend fbi's lifetime and
@@ -930,10 +935,15 @@ parm_ref_data_pass_through_p (struct ipa_func_body_info *fbi, int index,
return !modified;
}
-/* Return true if we can prove that OP is a memory reference loading unmodified
- data from an aggregate passed as a parameter and if the aggregate is passed
- by reference, that the alias type of the load corresponds to the type of the
- formal parameter (so that we can rely on this type for TBAA in callers).
+/* Return true if we can prove that OP is a memory reference loading
+ data from an aggregate passed as a parameter.
+
+ The function works in two modes. If GUARANTEED_UNMODIFIED is NULL, it return
+ false if it cannot prove that the value has not been modified before the
+ load in STMT. If GUARANTEED_UNMODIFIED is not NULL, it will return true even
+ if it cannot prove the value has not been modified, in that case it will
+ store false to *GUARANTEED_UNMODIFIED, otherwise it will store true there.
+
INFO and PARMS_AINFO describe parameters of the current function (but the
latter can be NULL), STMT is the load statement. If function returns true,
*INDEX_P, *OFFSET_P and *BY_REF is filled with the parameter index, offset
@@ -945,7 +955,7 @@ ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
vec<ipa_param_descriptor> descriptors,
gimple *stmt, tree op, int *index_p,
HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
- bool *by_ref_p)
+ bool *by_ref_p, bool *guaranteed_unmodified)
{
int index;
HOST_WIDE_INT size, max_size;
@@ -966,6 +976,8 @@ ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
*by_ref_p = false;
if (size_p)
*size_p = size;
+ if (guaranteed_unmodified)
+ *guaranteed_unmodified = true;
return true;
}
return false;
@@ -1002,13 +1014,18 @@ ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
index = load_from_unmodified_param (fbi, descriptors, def);
}
- if (index >= 0
- && parm_ref_data_preserved_p (fbi, index, stmt, op))
+ if (index >= 0)
{
+ bool data_preserved = parm_ref_data_preserved_p (fbi, index, stmt, op);
+ if (!data_preserved && !guaranteed_unmodified)
+ return false;
+
*index_p = index;
*by_ref_p = true;
if (size_p)
*size_p = size;
+ if (guaranteed_unmodified)
+ *guaranteed_unmodified = data_preserved;
return true;
}
return false;
@@ -1414,6 +1431,9 @@ determine_locally_known_aggregate_parts (gcall *call, tree arg,
bool check_ref, by_ref;
ao_ref r;
+ if (PARAM_VALUE (PARAM_IPA_MAX_AGG_ITEMS) == 0)
+ return;
+
/* The function operates in three stages. First, we prepare check_ref, r,
arg_base and arg_offset based on what is actually passed as an actual
argument. */
@@ -1654,7 +1674,10 @@ ipa_compute_jump_functions_for_edge (struct ipa_func_body_info *fbi,
else
gcc_assert (!jfunc->alignment.known);
- if (is_gimple_ip_invariant (arg))
+ if (is_gimple_ip_invariant (arg)
+ || (TREE_CODE (arg) == VAR_DECL
+ && is_global_var (arg)
+ && TREE_READONLY (arg)))
ipa_set_jf_constant (jfunc, arg, cs);
else if (!is_gimple_reg_type (TREE_TYPE (arg))
&& TREE_CODE (arg) == PARM_DECL)
@@ -1821,6 +1844,7 @@ ipa_note_param_call (struct cgraph_node *node, int param_index,
cs->indirect_info->param_index = param_index;
cs->indirect_info->agg_contents = 0;
cs->indirect_info->member_ptr = 0;
+ cs->indirect_info->guaranteed_unmodified = 0;
return cs;
}
@@ -1902,15 +1926,17 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
int index;
gimple *def = SSA_NAME_DEF_STMT (target);
+ bool guaranteed_unmodified;
if (gimple_assign_single_p (def)
&& ipa_load_from_parm_agg (fbi, info->descriptors, def,
gimple_assign_rhs1 (def), &index, &offset,
- NULL, &by_ref))
+ NULL, &by_ref, &guaranteed_unmodified))
{
struct cgraph_edge *cs = ipa_note_param_call (fbi->node, index, call);
cs->indirect_info->offset = offset;
cs->indirect_info->agg_contents = 1;
cs->indirect_info->by_ref = by_ref;
+ cs->indirect_info->guaranteed_unmodified = guaranteed_unmodified;
return;
}
@@ -2011,6 +2037,7 @@ ipa_analyze_indirect_call_uses (struct ipa_func_body_info *fbi, gcall *call,
cs->indirect_info->offset = offset;
cs->indirect_info->agg_contents = 1;
cs->indirect_info->member_ptr = 1;
+ cs->indirect_info->guaranteed_unmodified = 1;
}
return;
@@ -2698,18 +2725,125 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
return ie;
}
-/* Retrieve value from aggregate jump function AGG for the given OFFSET or
- return NULL if there is not any. BY_REF specifies whether the value has to
- be passed by reference or by value. */
+/* Attempt to locate an interprocedural constant at a given REQ_OFFSET in
+ CONSTRUCTOR and return it. Return NULL if the search fails for some
+ reason. */
+
+static tree
+find_constructor_constant_at_offset (tree constructor, HOST_WIDE_INT req_offset)
+{
+ tree type = TREE_TYPE (constructor);
+ if (TREE_CODE (type) != ARRAY_TYPE
+ && TREE_CODE (type) != RECORD_TYPE)
+ return NULL;
+
+ unsigned ix;
+ tree index, val;
+ FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (constructor), ix, index, val)
+ {
+ HOST_WIDE_INT elt_offset;
+ if (TREE_CODE (type) == ARRAY_TYPE)
+ {
+ offset_int off;
+ tree unit_size = TYPE_SIZE_UNIT (TREE_TYPE (type));
+ gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
+
+ if (index)
+ {
+ off = wi::to_offset (index);
+ if (TYPE_DOMAIN (type) && TYPE_MIN_VALUE (TYPE_DOMAIN (type)))
+ {
+ tree low_bound = TYPE_MIN_VALUE (TYPE_DOMAIN (type));
+ gcc_assert (TREE_CODE (unit_size) == INTEGER_CST);
+ off = wi::sext (off - wi::to_offset (low_bound),
+ TYPE_PRECISION (TREE_TYPE (index)));
+ }
+ off *= wi::to_offset (unit_size);
+ }
+ else
+ off = wi::to_offset (unit_size) * ix;
+
+ off = wi::lshift (off, LOG2_BITS_PER_UNIT);
+ if (!wi::fits_shwi_p (off) || wi::neg_p (off))
+ continue;
+ elt_offset = off.to_shwi ();
+ }
+ else if (TREE_CODE (type) == RECORD_TYPE)
+ {
+ gcc_checking_assert (index && TREE_CODE (index) == FIELD_DECL);
+ if (DECL_BIT_FIELD (index))
+ continue;
+ elt_offset = int_bit_position (index);
+ }
+ else
+ gcc_unreachable ();
+
+ if (elt_offset > req_offset)
+ return NULL;
+
+ if (TREE_CODE (val) == CONSTRUCTOR)
+ return find_constructor_constant_at_offset (val,
+ req_offset - elt_offset);
+
+ if (elt_offset == req_offset
+ && is_gimple_reg_type (TREE_TYPE (val))
+ && is_gimple_ip_invariant (val))
+ return val;
+ }
+ return NULL;
+}
+
+/* Check whether SCALAR could be used to look up an aggregate interprocedural
+ invariant from a static constructor and if so, return it. Otherwise return
+ NULL. */
+
+static tree
+ipa_find_agg_cst_from_init (tree scalar, HOST_WIDE_INT offset, bool by_ref)
+{
+ if (by_ref)
+ {
+ if (TREE_CODE (scalar) != ADDR_EXPR)
+ return NULL;
+ scalar = TREE_OPERAND (scalar, 0);
+ }
+
+ if (TREE_CODE (scalar) != VAR_DECL
+ || !is_global_var (scalar)
+ || !TREE_READONLY (scalar)
+ || !DECL_INITIAL (scalar)
+ || TREE_CODE (DECL_INITIAL (scalar)) != CONSTRUCTOR)
+ return NULL;
+
+ return find_constructor_constant_at_offset (DECL_INITIAL (scalar), offset);
+}
+
+/* Retrieve value from aggregate jump function AGG or static initializer of
+ SCALAR (which can be NULL) for the given OFFSET or return NULL if there is
+ none. BY_REF specifies whether the value has to be passed by reference or
+ by value. If FROM_GLOBAL_CONSTANT is non-NULL, then the boolean it points
+ to is set to true if the value comes from an initializer of a constant. */
tree
-ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
- HOST_WIDE_INT offset, bool by_ref)
+ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg, tree scalar,
+ HOST_WIDE_INT offset, bool by_ref,
+ bool *from_global_constant)
{
struct ipa_agg_jf_item *item;
int i;
- if (by_ref != agg->by_ref)
+ if (scalar)
+ {
+ tree res = ipa_find_agg_cst_from_init (scalar, offset, by_ref);
+ if (res)
+ {
+ if (from_global_constant)
+ *from_global_constant = true;
+ return res;
+ }
+ }
+
+ if (!agg
+ || by_ref != agg->by_ref)
return NULL;
FOR_EACH_VEC_SAFE_ELT (agg->items, i, item)
@@ -2718,6 +2852,8 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
/* Currently we do not have clobber values, return NULL for them once
we do. */
gcc_checking_assert (is_gimple_ip_invariant (item->value));
+ if (from_global_constant)
+ *from_global_constant = false;
return item->value;
}
return NULL;
@@ -2816,13 +2952,21 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
struct cgraph_edge *cs;
tree target;
bool agg_contents = ie->indirect_info->agg_contents;
-
- if (ie->indirect_info->agg_contents)
- target = ipa_find_agg_cst_for_param (&jfunc->agg,
- ie->indirect_info->offset,
- ie->indirect_info->by_ref);
+ tree scalar = ipa_value_from_jfunc (new_root_info, jfunc);
+ if (agg_contents)
+ {
+ bool from_global_constant;
+ target = ipa_find_agg_cst_for_param (&jfunc->agg, scalar,
+ ie->indirect_info->offset,
+ ie->indirect_info->by_ref,
+ &from_global_constant);
+ if (target
+ && !from_global_constant
+ && !ie->indirect_info->guaranteed_unmodified)
+ return NULL;
+ }
else
- target = ipa_value_from_jfunc (new_root_info, jfunc);
+ target = scalar;
if (!target)
return NULL;
cs = ipa_make_edge_direct_to_target (ie, target);
@@ -2890,7 +3034,9 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
{
tree vtable;
unsigned HOST_WIDE_INT offset;
- tree t = ipa_find_agg_cst_for_param (&jfunc->agg,
+ tree scalar = (jfunc->type == IPA_JF_CONST) ? ipa_get_jf_constant (jfunc)
+ : NULL;
+ tree t = ipa_find_agg_cst_for_param (&jfunc->agg, scalar,
ie->indirect_info->offset,
true);
if (t && vtable_pointer_value_to_vtable (t, &vtable, &offset))
@@ -4557,6 +4703,7 @@ ipa_write_indirect_edge_info (struct output_block *ob,
bp_pack_value (&bp, ii->agg_contents, 1);
bp_pack_value (&bp, ii->member_ptr, 1);
bp_pack_value (&bp, ii->by_ref, 1);
+ bp_pack_value (&bp, ii->guaranteed_unmodified, 1);
bp_pack_value (&bp, ii->vptr_changed, 1);
streamer_write_bitpack (&bp);
if (ii->agg_contents || ii->polymorphic)
@@ -4589,6 +4736,7 @@ ipa_read_indirect_edge_info (struct lto_input_block *ib,
ii->agg_contents = bp_unpack_value (&bp, 1);
ii->member_ptr = bp_unpack_value (&bp, 1);
ii->by_ref = bp_unpack_value (&bp, 1);
+ ii->guaranteed_unmodified = bp_unpack_value (&bp, 1);
ii->vptr_changed = bp_unpack_value (&bp, 1);
if (ii->agg_contents || ii->polymorphic)
ii->offset = (HOST_WIDE_INT) streamer_read_hwi (ib);
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index 4e11ca6d35c..e32d078edb3 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -636,11 +636,14 @@ tree ipa_impossible_devirt_target (struct cgraph_edge *, tree);
void ipa_analyze_node (struct cgraph_node *);
/* Aggregate jump function related functions. */
-tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *, HOST_WIDE_INT,
- bool);
-bool ipa_load_from_parm_agg (struct ipa_func_body_info *,
- vec<ipa_param_descriptor>, gimple *, tree, int *,
- HOST_WIDE_INT *, HOST_WIDE_INT *, bool *);
+tree ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg, tree scalar,
+ HOST_WIDE_INT offset, bool by_ref,
+ bool *from_global_constant = NULL);
+bool ipa_load_from_parm_agg (struct ipa_func_body_info *fbi,
+ vec<ipa_param_descriptor> descriptors,
+ gimple *stmt, tree op, int *index_p,
+ HOST_WIDE_INT *offset_p, HOST_WIDE_INT *size_p,
+ bool *by_ref, bool *guaranteed_unmodified = NULL);
/* Debugging interface. */
void ipa_print_node_params (FILE *, struct cgraph_node *node);
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index 7647a58fb26..a9570e4aa6c 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -258,6 +258,13 @@ set_function_state (struct cgraph_node *node, funct_state s)
if (!funct_state_vec.exists ()
|| funct_state_vec.length () <= (unsigned int)node->uid)
funct_state_vec.safe_grow_cleared (node->uid + 1);
+
+ /* If funct_state_vec already contains a funct_state, we have to release
+ it before it's going to be ovewritten. */
+ if (funct_state_vec[node->uid] != NULL
+ && funct_state_vec[node->uid] != &varying_state)
+ free (funct_state_vec[node->uid]);
+
funct_state_vec[node->uid] = s;
}
@@ -616,8 +623,10 @@ check_call (funct_state local, gcall *call, bool ipa)
/* Either callee is unknown or we are doing local analysis.
Look to see if there are any bits available for the callee (such as by
declaration or because it is builtin) and process solely on the basis of
- those bits. */
- else if (!ipa)
+ those bits. Handle internal calls always, those calls don't have
+ corresponding cgraph edges and thus aren't processed during
+ the propagation. */
+ else if (!ipa || gimple_call_internal_p (call))
{
enum pure_const_state_e call_state;
bool call_looping;
@@ -925,8 +934,6 @@ end:
static void
add_new_function (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
{
- if (node->get_availability () < AVAIL_INTERPOSABLE)
- return;
/* There are some shared nodes, in particular the initializers on
static declarations. We do not need to scan them more than once
since all we would be interested in are the addressof
@@ -956,12 +963,7 @@ static void
remove_node_data (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
{
if (has_function_state (node))
- {
- funct_state l = get_function_state (node);
- if (l != &varying_state)
- free (l);
- set_function_state (node, NULL);
- }
+ set_function_state (node, NULL);
}
@@ -1220,6 +1222,7 @@ propagate_pure_const (void)
int i;
struct ipa_dfs_info * w_info;
bool remove_p = false;
+ bool has_cdtor;
order_pos = ipa_reduced_postorder (order, true, false,
ignore_edge_for_pure_const);
@@ -1272,26 +1275,6 @@ propagate_pure_const (void)
if (pure_const_state == IPA_NEITHER)
break;
- /* For interposable nodes we can not assume anything.
- FIXME: It should be safe to remove this conditional and allow
- interposable functions with non-interposable aliases next
- stage 1. */
- if (w->get_availability () == AVAIL_INTERPOSABLE)
- {
- worse_state (&pure_const_state, &looping,
- w_l->state_previously_known,
- w_l->looping_previously_known,
- NULL, NULL);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file,
- " Interposable. state %s looping %i\n",
- pure_const_names[w_l->state_previously_known],
- w_l->looping_previously_known);
- }
- break;
- }
-
count++;
/* We consider recursive cycles as possibly infinite.
@@ -1504,9 +1487,22 @@ propagate_pure_const (void)
this_looping ? "looping " : "",
w->name ());
}
- remove_p |= w->call_for_symbol_and_aliases (cdtor_p,
- NULL, true);
- w->set_const_flag (true, this_looping);
+ /* Turning constructor or destructor to non-looping const/pure
+ enables us to possibly remove the function completely. */
+ if (this_looping)
+ has_cdtor = false;
+ else
+ has_cdtor = w->call_for_symbol_and_aliases (cdtor_p,
+ NULL, true);
+ if (w->set_const_flag (true, this_looping))
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Declaration updated to be %sconst: %s\n",
+ this_looping ? "looping " : "",
+ w->name ());
+ remove_p |= has_cdtor;
+ }
break;
case IPA_PURE:
@@ -1518,9 +1514,20 @@ propagate_pure_const (void)
this_looping ? "looping " : "",
w->name ());
}
- remove_p |= w->call_for_symbol_and_aliases (cdtor_p,
- NULL, true);
- w->set_pure_flag (true, this_looping);
+ if (this_looping)
+ has_cdtor = false;
+ else
+ has_cdtor = w->call_for_symbol_and_aliases (cdtor_p,
+ NULL, true);
+ if (w->set_pure_flag (true, this_looping))
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Declaration updated to be %spure: %s\n",
+ this_looping ? "looping " : "",
+ w->name ());
+ remove_p |= has_cdtor;
+ }
break;
default:
@@ -1721,11 +1728,14 @@ skip_function_for_local_pure_const (struct cgraph_node *node)
fprintf (dump_file, "Function called in recursive cycle; ignoring\n");
return true;
}
- if (node->get_availability () <= AVAIL_INTERPOSABLE)
+ /* Save some work and do not analyze functions which are interposable and
+ do not have any non-interposable aliases. */
+ if (node->get_availability () <= AVAIL_INTERPOSABLE
+ && !node->has_aliases_p ())
{
if (dump_file)
fprintf (dump_file,
- "Function is not available or interposable; not analyzing.\n");
+ "Function is interposable; not analyzing.\n");
return true;
}
return false;
@@ -1804,11 +1814,6 @@ pass_local_pure_const::execute (function *fun)
if (!TREE_READONLY (current_function_decl))
{
warn_function_const (current_function_decl, !l->looping);
- if (!skip)
- {
- node->set_const_flag (true, l->looping);
- changed = true;
- }
if (dump_file)
fprintf (dump_file, "Function found to be %sconst: %s\n",
l->looping ? "looping " : "",
@@ -1817,25 +1822,23 @@ pass_local_pure_const::execute (function *fun)
else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
&& !l->looping)
{
- if (!skip)
- {
- node->set_const_flag (true, false);
- changed = true;
- }
if (dump_file)
fprintf (dump_file, "Function found to be non-looping: %s\n",
current_function_name ());
}
+ if (!skip && node->set_const_flag (true, l->looping))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Declaration updated to be %sconst: %s\n",
+ l->looping ? "looping " : "",
+ current_function_name ());
+ changed = true;
+ }
break;
case IPA_PURE:
if (!DECL_PURE_P (current_function_decl))
{
- if (!skip)
- {
- node->set_pure_flag (true, l->looping);
- changed = true;
- }
warn_function_pure (current_function_decl, !l->looping);
if (dump_file)
fprintf (dump_file, "Function found to be %spure: %s\n",
@@ -1845,15 +1848,18 @@ pass_local_pure_const::execute (function *fun)
else if (DECL_LOOPING_CONST_OR_PURE_P (current_function_decl)
&& !l->looping)
{
- if (!skip)
- {
- node->set_pure_flag (true, false);
- changed = true;
- }
if (dump_file)
fprintf (dump_file, "Function found to be non-looping: %s\n",
current_function_name ());
}
+ if (!skip && node->set_pure_flag (true, l->looping))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Declaration updated to be %spure: %s\n",
+ l->looping ? "looping " : "",
+ current_function_name ());
+ changed = true;
+ }
break;
default:
diff --git a/gcc/ira.c b/gcc/ira.c
index a38e67e0b7c..55b4bd700be 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -512,7 +512,7 @@ setup_alloc_regs (bool use_hard_frame_p)
#ifdef ADJUST_REG_ALLOC_ORDER
ADJUST_REG_ALLOC_ORDER;
#endif
- COPY_HARD_REG_SET (no_unit_alloc_regs, fixed_reg_set);
+ COPY_HARD_REG_SET (no_unit_alloc_regs, fixed_nonglobal_reg_set);
if (! use_hard_frame_p)
SET_HARD_REG_BIT (no_unit_alloc_regs, HARD_FRAME_POINTER_REGNUM);
setup_class_hard_regs ();
@@ -3742,6 +3742,22 @@ combine_and_move_insns (void)
if (use_insn == BB_HEAD (use_bb))
BB_HEAD (use_bb) = new_insn;
+ /* We know regno dies in use_insn, but inside a loop
+ REG_DEAD notes might be missing when def_insn was in
+ another basic block. However, when we move def_insn into
+ this bb we'll definitely get a REG_DEAD note and reload
+ will see the death. It's possible that update_equiv_regs
+ set up an equivalence referencing regno for a reg set by
+ use_insn, when regno was seen as non-local. Now that
+ regno is local to this block, and dies, such an
+ equivalence is invalid. */
+ if (find_reg_note (use_insn, REG_EQUIV, NULL_RTX))
+ {
+ rtx set = single_set (use_insn);
+ if (set && REG_P (SET_DEST (set)))
+ no_equiv (SET_DEST (set), set, NULL);
+ }
+
ira_reg_equiv[regno].init_insns
= gen_rtx_INSN_LIST (VOIDmode, new_insn, NULL_RTX);
bitmap_set_bit (cleared_regs, regno);
diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog
index b9e9b588778..1c3e1fc8f21 100644
--- a/gcc/jit/ChangeLog
+++ b/gcc/jit/ChangeLog
@@ -1,3 +1,303 @@
+2016-05-20 David Malcolm <dmalcolm@redhat.com>
+
+ * docs/topics/compatibility.rst: Add LIBGCCJIT_ABI_6.
+ * docs/topics/expressions.rst (Function calls): Add documentation
+ of gcc_jit_rvalue_set_bool_require_tail_call.
+ * docs/_build/texinfo/libgccjit.texi: Regenerate.
+ * jit-common.h (gcc::jit::recording::base_call): Add forward decl.
+ * jit-playback.c: Within namespace gcc::jit::playback...
+ (context::build_call) Add "require_tail_call" param and use it
+ to set CALL_EXPR_MUST_TAIL_CALL.
+ (context::new_call): Add "require_tail_call" param.
+ (context::new_call_through_ptr): Likewise.
+ * jit-playback.h: Within namespace gcc::jit::playback...
+ (context::new_call: Add "require_tail_call" param.
+ (context::new_call_through_ptr): Likewise.
+ (context::build_call): Likewise.
+ * jit-recording.c: Within namespace gcc::jit::recording...
+ (base_call::base_call): New constructor.
+ (base_call::write_reproducer_tail_call): New method.
+ (call::call): Update for inheritance from base_call.
+ (call::replay_into): Provide m_require_tail_call to call
+ to new_call.
+ (call::write_reproducer): Call write_reproducer_tail_call.
+ (call_through_ptr::call_through_ptr): Update for inheritance from
+ base_call.
+ (call_through_ptr::replay_into): Provide m_require_tail_call to call
+ to new_call_through_ptr.
+ (recording::call_through_ptr::write_reproducer): Call
+ write_reproducer_tail_call.
+ * jit-recording.h: Within namespace gcc::jit::recording...
+ (rvalue::dyn_cast_base_call): New virtual function.
+ (class base_call): New subclass of class rvalue.
+ (class call): Inherit from base_call rather than directly from
+ rvalue, moving get_precedence and m_args to base_call.
+ (class call_through_ptr): Likewise.
+ * libgccjit.c (gcc_jit_rvalue_set_bool_require_tail_call): New
+ function.
+ * libgccjit.h
+ (LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call): New
+ macro.
+ (gcc_jit_rvalue_set_bool_require_tail_call): New function.
+ * libgccjit.map (LIBGCCJIT_ABI_6): New.
+ (gcc_jit_rvalue_set_bool_require_tail_call): Add.
+
+2016-05-17 David Malcolm <dmalcolm@redhat.com>
+
+ * dummy-frontend.c: Include diagnostic.h.
+ (jit_begin_diagnostic): New function.
+ (jit_end_diagnostic): New function.
+ (jit_langhook_init): Register jit_begin_diagnostic
+ and jit_end_diagnostic with the global_dc.
+ * jit-playback.c: Include diagnostic.h.
+ (gcc::jit::playback::context::add_diagnostic): New method.
+ * jit-playback.h (struct diagnostic_context): Add forward
+ declaration.
+ (gcc::jit::playback::context::add_diagnostic): New method.
+
+2016-05-17 David Malcolm <dmalcolm@redhat.com>
+
+ * docs/topics/expressions.rst (Function calls): Document
+ gcc_jit_context_new_call_through_ptr.
+ * docs/_build/texinfo/libgccjit.texi: Regenerate.
+
+2016-05-13 David Malcolm <dmalcolm@redhat.com>
+
+ * jit-playback.h: Within namespace gcc:jit::playback...
+ (compile_to_memory::postprocess): Mark with FINAL OVERRIDE.
+ (compile_to_file::postprocess): Likewise.
+ (function::finalizer): Likewise.
+ (block::finalizer): Likewise.
+ (source_file::finalizer): Likewise.
+ (source_line::finalizer): Likewise.
+ * jit-recording.c (gcc::jit::rvalue_usage_validator):: Likewise.
+ * jit-recording.h: Within namespace gcc::jit::recording...
+ (string::replay_into): Mark with FINAL OVERRIDE.
+ (string::make_debug_string): Likewise.
+ (string::write_reproducer): Likewise.
+ (location::replay_into): Likewise.
+ (location::dyn_cast_location): Likewise.
+ (location::make_debug_string): Likewise.
+ (location::write_reproducer): Likewise.
+ (memento_of_get_type::dereference): Likewise.
+ (memento_of_get_type::accepts_writes_from): Likewise.
+ (memento_of_get_type::is_int): Likewise.
+ (memento_of_get_type::is_float): Likewise.
+ (memento_of_get_type::is_bool): Likewise.
+ (memento_of_get_type::is_pointer): Likewise.
+ (memento_of_get_type::is_array): Likewise.
+ (memento_of_get_type::is_void): Likewise.
+ (memento_of_get_type::replay_into): Likewise.
+ (memento_of_get_type::make_debug_string): Likewise.
+ (memento_of_get_type::write_reproducer): Likewise.
+ (memento_of_get_pointer::dereference): Likewise.
+ (memento_of_get_pointer::accepts_writes_from): Likewise.
+ (memento_of_get_pointer::replay_into): Likewise.
+ (memento_of_get_pointer::is_int): Likewise.
+ (memento_of_get_pointer::is_float): Likewise.
+ (memento_of_get_pointer::is_bool): Likewise.
+ (memento_of_get_pointer::is_pointer): Likewise.
+ (memento_of_get_pointer::is_array): Likewise.
+ (memento_of_get_pointer::make_debug_string): Likewise.
+ (memento_of_get_pointer::write_reproducer): Likewise.
+ (memento_of_get_const::dereference): Likewise.
+ (memento_of_get_const::accepts_writes_from): Likewise.
+ (memento_of_get_const::unqualified): Likewise.
+ (memento_of_get_const::is_int): Likewise.
+ (memento_of_get_const::is_float): Likewise.
+ (memento_of_get_const::is_bool): Likewise.
+ (memento_of_get_const::is_pointer): Likewise.
+ (memento_of_get_const::is_array): Likewise.
+ (memento_of_get_const::void replay_into): Likewise;
+ (memento_of_get_const::make_debug_string): Likewise.
+ (memento_of_get_const::write_reproducer): Likewise.
+ (memento_of_get_volatile::dereference): Likewise.
+ (memento_of_get_volatile::unqualified): Likewise.
+ (memento_of_get_volatile::is_int): Likewise.
+ (memento_of_get_volatile::is_float): Likewise.
+ (memento_of_get_volatile::is_bool): Likewise.
+ (memento_of_get_volatile::is_pointer): Likewise.
+ (memento_of_get_volatile::is_array): Likewise.
+ (memento_of_get_volatile::replay_into): Likewise;
+ (memento_of_get_volatile::make_debug_string): Likewise.
+ (memento_of_get_volatile::write_reproducer): Likewise.
+ (array_type::dereference): Likewise.
+ (array_type::is_int): Likewise.
+ (array_type::is_float): Likewise.
+ (array_type::is_bool): Likewise.
+ (array_type::is_pointer): Likewise.
+ (array_type::is_array): Likewise.
+ (array_type::replay_into): Likewise;
+ (array_type::make_debug_string): Likewise.
+ (array_type::write_reproducer): Likewise.
+ (function_type::dereference): Likewise.
+ (function_type::function_dyn_cast_function_type): Likewise.
+ (function_type::function_as_a_function_type): Likewise.
+ (function_type::is_int): Likewise.
+ (function_type::is_float): Likewise.
+ (function_type::is_bool): Likewise.
+ (function_type::is_pointer): Likewise.
+ (function_type::is_array): Likewise.
+ (function_type::replay_into): Likewise;
+ (function_type::make_debug_string): Likewise.
+ (function_type::write_reproducer): Likewise.
+ (field::replay_into): Likewise;
+ (field::write_to_dump): Likewise.
+ (field::make_debug_string): Likewise.
+ (field::write_reproducer): Likewise.
+ (compound_type::dereference): Likewise.
+ (compound_type::is_int): Likewise.
+ (compound_type::is_float): Likewise.
+ (compound_type::is_bool): Likewise.
+ (compound_type::is_pointer): Likewise.
+ (compound_type::is_array): Likewise.
+ (compound_type::has_known_size): Likewise.
+ (struct_::dyn_cast_struct): Likewise.
+ (struct_::replay_into): Likewise.
+ (struct_::access_as_type): Likewise.
+ (struct_::make_debug_string): Likewise.
+ (struct_::write_reproducer): Likewise.
+ (fields::replay_into): Likewise.
+ (fields::write_to_dump): Likewise.
+ (fields::make_debug_string): Likewise.
+ (fields::write_reproducer): Likewise.
+ (union_::replay_into): Likewise.
+ (union_::make_debug_string): Likewise.
+ (union_::write_reproducer): Likewise.
+ (lvalue::access_as_rvalue): Mark with OVERRIDE.
+ (param::replay_into): Mark with FINAL OVERRIDE.
+ (param::visit_children): Likewise.
+ (param::dyn_cast_param): Likewise.
+ (param::access_as_rvalue): Likewise.
+ (param::access_as_lvalue): Likewise.
+ (param::make_debug_string): Likewise.
+ (param::write_reproducer): Likewise.
+ (param::get_precedence): Likewise.
+ (function::replay_into): Likewise.
+ (function::write_to_dump): Likewise.
+ (function::make_debug_string): Likewise.
+ (function::write_reproducer): Likewise.
+ (block::write_to_dump): Likewise.
+ (block::make_debug_string): Likewise.
+ (block::write_reproducer): Likewise.
+ (block::replay_into): Likewise.
+ (global::replay_into): Likewise;
+ (global::visit_children): Likewise.
+ (global::write_to_dump): Likewise.
+ (global::make_debug_string): Likewise.
+ (global::write_reproducer): Likewise.
+ (global::get_precedence): Likewise.
+ (memento_of_new_rvalue_from_const::replay_into): Likewise.
+ (memento_of_new_rvalue_from_const::visit_children): Likewise.
+ (memento_of_new_rvalue_from_const::is_constant): Likewise.
+ (memento_of_new_rvalue_from_const::get_wide_int): Likewise.
+ (memento_of_new_rvalue_from_const::make_debug_string): Likewise.
+ (memento_of_new_rvalue_from_const::write_reproducer): Likewise.
+ (memento_of_new_rvalue_from_const::get_precedence): Likewise.
+ (memento_of_new_string_literal::replay_into): Likewise.
+ (memento_of_new_string_literal::visit_children): Likewise.
+ (memento_of_new_string_literal::make_debug_string): Likewise.
+ (memento_of_new_string_literal::write_reproducer): Likewise.
+ (memento_of_new_string_literal::get_precedence): Likewise.
+ (unary_op::replay_into): Likewise.
+ (unary_op::visit_children): Likewise.
+ (unary_op::make_debug_string): Likewise.
+ (unary_op::write_reproducer): Likewise.
+ (unary_op::get_precedence): Likewise.
+ (binary_op::replay_into): Likewise.
+ (binary_op::visit_children): Likewise.
+ (binary_op::make_debug_string): Likewise.
+ (binary_op::write_reproducer): Likewise.
+ (binary_op::get_precedence): Likewise.
+ (comparison::replay_into): Likewise.
+ (comparison::visit_children): Likewise.
+ (comparison::make_debug_string): Likewise.
+ (comparison::write_reproducer): Likewise.
+ (comparison::get_precedence): Likewise.
+ (cast::replay_into): Likewise.
+ (cast::visit_children): Likewise.
+ (cast::make_debug_string): Likewise.
+ (cast::write_reproducer): Likewise.
+ (cast::get_precedence): Likewise.
+ (call::replay_into): Likewise.
+ (call::visit_children): Likewise.
+ (call::make_debug_string): Likewise.
+ (call::write_reproducer): Likewise.
+ (call::get_precedence): Likewise.
+ (call_through_ptr::replay_into): Likewise.
+ (call_through_ptr::visit_children): Likewise.
+ (call_through_ptr::make_debug_string): Likewise.
+ (call_through_ptr::write_reproducer): Likewise.
+ (call_through_ptr::get_precedence): Likewise.
+ (array_access::replay_into): Likewise.
+ (array_access::visit_children): Likewise.
+ (array_access::make_debug_string): Likewise.
+ (array_access::write_reproducer): Likewise.
+ (array_access::get_precedence): Likewise.
+ (access_field_of_lvalue::replay_into): Likewise.
+ (access_field_of_lvalue::visit_children): Likewise.
+ (access_field_of_lvalue::make_debug_string): Likewise.
+ (access_field_of_lvalue::write_reproducer): Likewise.
+ (access_field_of_lvalue::get_precedence): Likewise.
+ (access_field_rvalue::replay_into): Likewise.
+ (access_field_rvalue::visit_children): Likewise.
+ (access_field_rvalue::make_debug_string): Likewise.
+ (access_field_rvalue::write_reproducer): Likewise.
+ (access_field_rvalue::get_precedence): Likewise.
+ (dereference_field_rvalue::replay_into): Likewise.
+ (dereference_field_rvalue::visit_children): Likewise.
+ (dereference_field_rvalue::make_debug_string): Likewise.
+ (dereference_field_rvalue::write_reproducer): Likewise.
+ (dereference_field_rvalue::get_precedence): Likewise.
+ (dereference_rvalue::replay_into): Likewise.
+ (dereference_rvalue::visit_children): Likewise.
+ (dereference_rvalue::make_debug_string): Likewise.
+ (dereference_rvalue::write_reproducer): Likewise.
+ (dereference_rvalue::get_precedence): Likewise.
+ (get_address_of_lvalue::replay_into): Likewise.
+ (get_address_of_lvalue::visit_children): Likewise.
+ (get_address_of_lvalue::make_debug_string): Likewise.
+ (get_address_of_lvalue::write_reproducer): Likewise.
+ (get_address_of_lvalue::get_precedence): Likewise.
+ (local::replay_into): Likewise.
+ (local::visit_children): Likewise.
+ (local::write_to_dump): Likewise.
+ (local::make_debug_string): Likewise.
+ (local::write_reproducer): Likewise.
+ (local::get_precedence): Likewise.
+ (statement::write_to_dump): Likewise.
+ (eval::replay_into): Likewise.
+ (eval::make_debug_string): Likewise.
+ (eval::write_reproducer): Likewise.
+ (assignment::replay_into): Likewise.
+ (assignment::make_debug_string): Likewise.
+ (assignment::write_reproducer): Likewise.
+ (assignment_op::replay_into): Likewise.
+ (assignment_op::make_debug_string): Likewise.
+ (assignment_op::write_reproducer): Likewise.
+ (comment::replay_into): Likewise.
+ (comment::make_debug_string): Likewise.
+ (comment::write_reproducer): Likewise.
+ (conditional::replay_into): Likewise.
+ (conditional::get_successor_blocks): Likewise.
+ (conditional::make_debug_string): Likewise.
+ (conditional::write_reproducer): Likewise.
+ (jump::replay_into): Likewise.
+ (jump::get_successor_blocks): Likewise.
+ (jump::make_debug_string): Likewise.
+ (jump::write_reproducer): Likewise.
+ (return_::replay_into): Likewise.
+ (return_::get_successor_blocks): Likewise.
+ (return_::make_debug_string): Likewise.
+ (return_::write_reproducer): Likewise.
+ (case_::replay_into): Likewise.
+ (case_::write_reproducer): Likewise.
+ (case_::make_debug_string): Likewise.
+ (switch_::replay_into): Likewise.
+ (switch_::get_successor_blocks): Likewise.
+ (switch_::make_debug_string): Likewise.
+ (switch_::write_reproducer): Likewise.
+
2016-02-08 David Malcolm <dmalcolm@redhat.com>
* dummy-frontend.c (jit_langhook_init): Remove
diff --git a/gcc/jit/docs/_build/texinfo/libgccjit.texi b/gcc/jit/docs/_build/texinfo/libgccjit.texi
index 2043d664a04..f5c35497277 100644
--- a/gcc/jit/docs/_build/texinfo/libgccjit.texi
+++ b/gcc/jit/docs/_build/texinfo/libgccjit.texi
@@ -19,7 +19,7 @@
@copying
@quotation
-libgccjit 6.0.0 (experimental 20160108), January 19, 2016
+libgccjit 7.0.0 (experimental 20160517), May 17, 2016
David Malcolm
@@ -7034,13 +7034,28 @@ gcc_jit_block_add_eval (
@end cartouche
@end deffn
+@geindex gcc_jit_context_new_call_through_ptr (C function)
+@anchor{topics/expressions gcc_jit_context_new_call_through_ptr}@anchor{ae}
+@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_call_through_ptr (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*fn_ptr, int@w{ }numargs, gcc_jit_rvalue@w{ }**args)
+
+Given an rvalue of function pointer type, and the given table of
+argument rvalues, construct a call to the function pointer, with the
+result as an rvalue.
+
+@cartouche
+@quotation Note
+The same caveat as for @pxref{ac,,gcc_jit_context_new_call()} applies.
+@end quotation
+@end cartouche
+@end deffn
+
@node Type-coercion,,Function calls,Rvalues
-@anchor{topics/expressions type-coercion}@anchor{ae}
+@anchor{topics/expressions type-coercion}@anchor{af}
@subsubsection Type-coercion
@geindex gcc_jit_context_new_cast (C function)
-@anchor{topics/expressions gcc_jit_context_new_cast}@anchor{af}
+@anchor{topics/expressions gcc_jit_context_new_cast}@anchor{b0}
@deffn {C Function} gcc_jit_rvalue * gcc_jit_context_new_cast (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue, gcc_jit_type@w{ }*type)
Given an rvalue of T, construct another rvalue of another type.
@@ -7065,7 +7080,7 @@ P* <-> Q*, for pointer types P and Q
@end deffn
@node Lvalues,Working with pointers structs and unions,Rvalues,Expressions
-@anchor{topics/expressions lvalues}@anchor{b0}
+@anchor{topics/expressions lvalues}@anchor{b1}
@subsection Lvalues
@@ -7079,21 +7094,21 @@ a storage area (such as a variable). It is also usable as an rvalue,
where the rvalue is computed by reading from the storage area.
@geindex gcc_jit_lvalue_as_object (C function)
-@anchor{topics/expressions gcc_jit_lvalue_as_object}@anchor{b1}
+@anchor{topics/expressions gcc_jit_lvalue_as_object}@anchor{b2}
@deffn {C Function} gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue@w{ }*lvalue)
Upcast an lvalue to be an object.
@end deffn
@geindex gcc_jit_lvalue_as_rvalue (C function)
-@anchor{topics/expressions gcc_jit_lvalue_as_rvalue}@anchor{b2}
+@anchor{topics/expressions gcc_jit_lvalue_as_rvalue}@anchor{b3}
@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_as_rvalue (gcc_jit_lvalue@w{ }*lvalue)
Upcast an lvalue to be an rvalue.
@end deffn
@geindex gcc_jit_lvalue_get_address (C function)
-@anchor{topics/expressions gcc_jit_lvalue_get_address}@anchor{b3}
+@anchor{topics/expressions gcc_jit_lvalue_get_address}@anchor{b4}
@deffn {C Function} gcc_jit_rvalue * gcc_jit_lvalue_get_address (gcc_jit_lvalue@w{ }*lvalue, gcc_jit_location@w{ }*loc)
Take the address of an lvalue; analogous to:
@@ -7113,12 +7128,12 @@ in C.
@end menu
@node Global variables,,,Lvalues
-@anchor{topics/expressions global-variables}@anchor{b4}
+@anchor{topics/expressions global-variables}@anchor{b5}
@subsubsection Global variables
@geindex gcc_jit_context_new_global (C function)
-@anchor{topics/expressions gcc_jit_context_new_global}@anchor{b5}
+@anchor{topics/expressions gcc_jit_context_new_global}@anchor{b6}
@deffn {C Function} gcc_jit_lvalue * gcc_jit_context_new_global (gcc_jit_context@w{ }*ctxt, gcc_jit_location@w{ }*loc, enum gcc_jit_global_kind@w{ }kind, gcc_jit_type@w{ }*type, const char@w{ }*name)
Add a new global variable of the given type and name to the context.
@@ -7131,22 +7146,22 @@ The "kind" parameter determines the visibility of the "global" outside
of the @pxref{16,,gcc_jit_result}:
@geindex gcc_jit_global_kind (C type)
-@anchor{topics/expressions gcc_jit_global_kind}@anchor{b6}
+@anchor{topics/expressions gcc_jit_global_kind}@anchor{b7}
@deffn {C Type} enum gcc_jit_global_kind
@end deffn
@geindex GCC_JIT_GLOBAL_EXPORTED (C macro)
-@anchor{topics/expressions GCC_JIT_GLOBAL_EXPORTED}@anchor{b7}
+@anchor{topics/expressions GCC_JIT_GLOBAL_EXPORTED}@anchor{b8}
@deffn {C Macro} GCC_JIT_GLOBAL_EXPORTED
Global is defined by the client code and is visible
by name outside of this JIT context via
-@pxref{b8,,gcc_jit_result_get_global()} (and this value is required for
+@pxref{b9,,gcc_jit_result_get_global()} (and this value is required for
the global to be accessible via that entrypoint).
@end deffn
@geindex GCC_JIT_GLOBAL_INTERNAL (C macro)
-@anchor{topics/expressions GCC_JIT_GLOBAL_INTERNAL}@anchor{b9}
+@anchor{topics/expressions GCC_JIT_GLOBAL_INTERNAL}@anchor{ba}
@deffn {C Macro} GCC_JIT_GLOBAL_INTERNAL
Global is defined by the client code, but is invisible
@@ -7156,7 +7171,7 @@ context and within child contexts.
@end deffn
@geindex GCC_JIT_GLOBAL_IMPORTED (C macro)
-@anchor{topics/expressions GCC_JIT_GLOBAL_IMPORTED}@anchor{ba}
+@anchor{topics/expressions GCC_JIT_GLOBAL_IMPORTED}@anchor{bb}
@deffn {C Macro} GCC_JIT_GLOBAL_IMPORTED
Global is not defined by the client code; we're merely
@@ -7166,12 +7181,12 @@ header file.
@end deffn
@node Working with pointers structs and unions,,Lvalues,Expressions
-@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{bb}
+@anchor{topics/expressions working-with-pointers-structs-and-unions}@anchor{bc}
@subsection Working with pointers, structs and unions
@geindex gcc_jit_rvalue_dereference (C function)
-@anchor{topics/expressions gcc_jit_rvalue_dereference}@anchor{bc}
+@anchor{topics/expressions gcc_jit_rvalue_dereference}@anchor{bd}
@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference (gcc_jit_rvalue@w{ }*rvalue, gcc_jit_location@w{ }*loc)
Given an rvalue of pointer type @code{T *}, dereferencing the pointer,
@@ -7189,7 +7204,7 @@ in C.
Field access is provided separately for both lvalues and rvalues.
@geindex gcc_jit_lvalue_access_field (C function)
-@anchor{topics/expressions gcc_jit_lvalue_access_field}@anchor{bd}
+@anchor{topics/expressions gcc_jit_lvalue_access_field}@anchor{be}
@deffn {C Function} gcc_jit_lvalue * gcc_jit_lvalue_access_field (gcc_jit_lvalue@w{ }*struct_, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field)
Given an lvalue of struct or union type, access the given field,
@@ -7205,7 +7220,7 @@ in C.
@end deffn
@geindex gcc_jit_rvalue_access_field (C function)
-@anchor{topics/expressions gcc_jit_rvalue_access_field}@anchor{be}
+@anchor{topics/expressions gcc_jit_rvalue_access_field}@anchor{bf}
@deffn {C Function} gcc_jit_rvalue * gcc_jit_rvalue_access_field (gcc_jit_rvalue@w{ }*struct_, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field)
Given an rvalue of struct or union type, access the given field
@@ -7221,7 +7236,7 @@ in C.
@end deffn
@geindex gcc_jit_rvalue_dereference_field (C function)
-@anchor{topics/expressions gcc_jit_rvalue_dereference_field}@anchor{bf}
+@anchor{topics/expressions gcc_jit_rvalue_dereference_field}@anchor{c0}
@deffn {C Function} gcc_jit_lvalue * gcc_jit_rvalue_dereference_field (gcc_jit_rvalue@w{ }*ptr, gcc_jit_location@w{ }*loc, gcc_jit_field@w{ }*field)
Given an rvalue of pointer type @code{T *} where T is of struct or union
@@ -7272,7 +7287,7 @@ in C (or, indeed, to @code{PTR + INDEX}).
@c <http://www.gnu.org/licenses/>.
@node Creating and using functions,Source Locations,Expressions,Topic Reference
-@anchor{topics/functions doc}@anchor{c0}@anchor{topics/functions creating-and-using-functions}@anchor{c1}
+@anchor{topics/functions doc}@anchor{c1}@anchor{topics/functions creating-and-using-functions}@anchor{c2}
@section Creating and using functions
@@ -7285,7 +7300,7 @@ in C (or, indeed, to @code{PTR + INDEX}).
@end menu
@node Params,Functions,,Creating and using functions
-@anchor{topics/functions params}@anchor{c2}
+@anchor{topics/functions params}@anchor{c3}
@subsection Params
@@ -7312,28 +7327,28 @@ Parameters are lvalues, and thus are also rvalues (and objects), so the
following upcasts are available:
@geindex gcc_jit_param_as_lvalue (C function)
-@anchor{topics/functions gcc_jit_param_as_lvalue}@anchor{c3}
+@anchor{topics/functions gcc_jit_param_as_lvalue}@anchor{c4}
@deffn {C Function} gcc_jit_lvalue * gcc_jit_param_as_lvalue (gcc_jit_param@w{ }*param)
Upcasting from param to lvalue.
@end deffn
@geindex gcc_jit_param_as_rvalue (C function)
-@anchor{topics/functions gcc_jit_param_as_rvalue}@anchor{c4}
+@anchor{topics/functions gcc_jit_param_as_rvalue}@anchor{c5}
@deffn {C Function} gcc_jit_rvalue * gcc_jit_param_as_rvalue (gcc_jit_param@w{ }*param)
Upcasting from param to rvalue.
@end deffn
@geindex gcc_jit_param_as_object (C function)
-@anchor{topics/functions gcc_jit_param_as_object}@anchor{c5}
+@anchor{topics/functions gcc_jit_param_as_object}@anchor{c6}
@deffn {C Function} gcc_jit_object * gcc_jit_param_as_object (gcc_jit_param@w{ }*param)
Upcasting from param to object.
@end deffn
@node Functions,Blocks,Params,Creating and using functions
-@anchor{topics/functions functions}@anchor{c6}
+@anchor{topics/functions functions}@anchor{c7}
@subsection Functions
@@ -7352,7 +7367,7 @@ creating ourselves, or one that we're referencing.
Create a gcc_jit_function with the given name and parameters.
@geindex gcc_jit_function_kind (C type)
-@anchor{topics/functions gcc_jit_function_kind}@anchor{c7}
+@anchor{topics/functions gcc_jit_function_kind}@anchor{c8}
@deffn {C Type} enum gcc_jit_function_kind
@end deffn
@@ -7362,7 +7377,7 @@ values:
@quotation
@geindex GCC_JIT_FUNCTION_EXPORTED (C macro)
-@anchor{topics/functions GCC_JIT_FUNCTION_EXPORTED}@anchor{c8}
+@anchor{topics/functions GCC_JIT_FUNCTION_EXPORTED}@anchor{c9}
@deffn {C Macro} GCC_JIT_FUNCTION_EXPORTED
Function is defined by the client code and visible
@@ -7374,7 +7389,7 @@ for this function from a @pxref{16,,gcc_jit_result} via
@end deffn
@geindex GCC_JIT_FUNCTION_INTERNAL (C macro)
-@anchor{topics/functions GCC_JIT_FUNCTION_INTERNAL}@anchor{c9}
+@anchor{topics/functions GCC_JIT_FUNCTION_INTERNAL}@anchor{ca}
@deffn {C Macro} GCC_JIT_FUNCTION_INTERNAL
Function is defined by the client code, but is invisible
@@ -7382,7 +7397,7 @@ outside of the JIT. Analogous to a "static" function.
@end deffn
@geindex GCC_JIT_FUNCTION_IMPORTED (C macro)
-@anchor{topics/functions GCC_JIT_FUNCTION_IMPORTED}@anchor{ca}
+@anchor{topics/functions GCC_JIT_FUNCTION_IMPORTED}@anchor{cb}
@deffn {C Macro} GCC_JIT_FUNCTION_IMPORTED
Function is not defined by the client code; we're merely
@@ -7391,7 +7406,7 @@ header file.
@end deffn
@geindex GCC_JIT_FUNCTION_ALWAYS_INLINE (C macro)
-@anchor{topics/functions GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{cb}
+@anchor{topics/functions GCC_JIT_FUNCTION_ALWAYS_INLINE}@anchor{cc}
@deffn {C Macro} GCC_JIT_FUNCTION_ALWAYS_INLINE
Function is only ever inlined into other functions, and is
@@ -7412,19 +7427,19 @@ buffer.
@end deffn
@geindex gcc_jit_context_get_builtin_function (C function)
-@anchor{topics/functions gcc_jit_context_get_builtin_function}@anchor{cc}
+@anchor{topics/functions gcc_jit_context_get_builtin_function}@anchor{cd}
@deffn {C Function} gcc_jit_function *gcc_jit_context_get_builtin_function (gcc_jit_context@w{ }*ctxt, const char@w{ }*name)
@end deffn
@geindex gcc_jit_function_as_object (C function)
-@anchor{topics/functions gcc_jit_function_as_object}@anchor{cd}
+@anchor{topics/functions gcc_jit_function_as_object}@anchor{ce}
@deffn {C Function} gcc_jit_object * gcc_jit_function_as_object (gcc_jit_function@w{ }*func)
Upcasting from function to object.
@end deffn
@geindex gcc_jit_function_get_param (C function)
-@anchor{topics/functions gcc_jit_function_get_param}@anchor{ce}
+@anchor{topics/functions gcc_jit_function_get_param}@anchor{cf}
@deffn {C Function} gcc_jit_param * gcc_jit_function_get_param (gcc_jit_function@w{ }*func, int@w{ }index)
Get the param of the given index (0-based).
@@ -7450,7 +7465,7 @@ buffer.
@end deffn
@node Blocks,Statements,Functions,Creating and using functions
-@anchor{topics/functions blocks}@anchor{cf}
+@anchor{topics/functions blocks}@anchor{d0}
@subsection Blocks
@@ -7474,7 +7489,7 @@ one function.
@end deffn
@geindex gcc_jit_function_new_block (C function)
-@anchor{topics/functions gcc_jit_function_new_block}@anchor{d0}
+@anchor{topics/functions gcc_jit_function_new_block}@anchor{d1}
@deffn {C Function} gcc_jit_block * gcc_jit_function_new_block (gcc_jit_function@w{ }*func, const char@w{ }*name)
Create a basic block of the given name. The name may be NULL, but
@@ -7496,21 +7511,21 @@ for (pc = 0; pc < fn->fn_num_ops; pc++)
@end deffn
@geindex gcc_jit_block_as_object (C function)
-@anchor{topics/functions gcc_jit_block_as_object}@anchor{d1}
+@anchor{topics/functions gcc_jit_block_as_object}@anchor{d2}
@deffn {C Function} gcc_jit_object * gcc_jit_block_as_object (gcc_jit_block@w{ }*block)
Upcast from block to object.
@end deffn
@geindex gcc_jit_block_get_function (C function)
-@anchor{topics/functions gcc_jit_block_get_function}@anchor{d2}
+@anchor{topics/functions gcc_jit_block_get_function}@anchor{d3}
@deffn {C Function} gcc_jit_function * gcc_jit_block_get_function (gcc_jit_block@w{ }*block)
Which function is this block within?
@end deffn
@node Statements,,Blocks,Creating and using functions
-@anchor{topics/functions statements}@anchor{d3}
+@anchor{topics/functions statements}@anchor{d4}
@subsection Statements
@@ -7624,7 +7639,7 @@ block, boolval, on_true, and on_false must be non-NULL.
@end deffn
@geindex gcc_jit_block_end_with_jump (C function)
-@anchor{topics/functions gcc_jit_block_end_with_jump}@anchor{d4}
+@anchor{topics/functions gcc_jit_block_end_with_jump}@anchor{d5}
@deffn {C Function} void gcc_jit_block_end_with_jump (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_block@w{ }*target)
Terminate a block by adding a jump to the given target block.
@@ -7639,7 +7654,7 @@ goto target;
@end deffn
@geindex gcc_jit_block_end_with_return (C function)
-@anchor{topics/functions gcc_jit_block_end_with_return}@anchor{d5}
+@anchor{topics/functions gcc_jit_block_end_with_return}@anchor{d6}
@deffn {C Function} void gcc_jit_block_end_with_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*rvalue)
Terminate a block by adding evaluation of an rvalue, returning the value.
@@ -7654,7 +7669,7 @@ return expression;
@end deffn
@geindex gcc_jit_block_end_with_void_return (C function)
-@anchor{topics/functions gcc_jit_block_end_with_void_return}@anchor{d6}
+@anchor{topics/functions gcc_jit_block_end_with_void_return}@anchor{d7}
@deffn {C Function} void gcc_jit_block_end_with_void_return (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc)
Terminate a block by adding a valueless return, for use within a function
@@ -7670,7 +7685,7 @@ return;
@end deffn
@geindex gcc_jit_block_end_with_switch (C function)
-@anchor{topics/functions gcc_jit_block_end_with_switch}@anchor{d7}
+@anchor{topics/functions gcc_jit_block_end_with_switch}@anchor{d8}
@deffn {C Function} void gcc_jit_block_end_with_switch (gcc_jit_block@w{ }*block, gcc_jit_location@w{ }*loc, gcc_jit_rvalue@w{ }*expr, gcc_jit_block@w{ }*default_block, int@w{ }num_cases, gcc_jit_case@w{ }**cases)
Terminate a block by adding evalation of an rvalue, then performing
@@ -7718,17 +7733,17 @@ The API entrypoints relating to switch statements and cases:
@itemize *
@item
-@pxref{d7,,gcc_jit_block_end_with_switch()}
+@pxref{d8,,gcc_jit_block_end_with_switch()}
@item
-@pxref{d8,,gcc_jit_case_as_object()}
+@pxref{d9,,gcc_jit_case_as_object()}
@item
-@pxref{d9,,gcc_jit_context_new_case()}
+@pxref{da,,gcc_jit_context_new_case()}
@end itemize
@end quotation
-were added in @pxref{da,,LIBGCCJIT_ABI_3}; you can test for their presence
+were added in @pxref{db,,LIBGCCJIT_ABI_3}; you can test for their presence
using
@example
@@ -7738,20 +7753,20 @@ using
@noindent
@geindex gcc_jit_case (C type)
-@anchor{topics/functions gcc_jit_case}@anchor{db}
+@anchor{topics/functions gcc_jit_case}@anchor{dc}
@deffn {C Type} gcc_jit_case
@end deffn
A @cite{gcc_jit_case} represents a case within a switch statement, and
is created within a particular @pxref{8,,gcc_jit_context} using
-@pxref{d9,,gcc_jit_context_new_case()}.
+@pxref{da,,gcc_jit_context_new_case()}.
Each case expresses a multivalued range of integer values. You
can express single-valued cases by passing in the same value for
both @cite{min_value} and @cite{max_value}.
@geindex gcc_jit_context_new_case (C function)
-@anchor{topics/functions gcc_jit_context_new_case}@anchor{d9}
+@anchor{topics/functions gcc_jit_context_new_case}@anchor{da}
@deffn {C Function} gcc_jit_case * gcc_jit_context_new_case (gcc_jit_context@w{ }*ctxt, gcc_jit_rvalue@w{ }*min_value, gcc_jit_rvalue@w{ }*max_value, gcc_jit_block@w{ }*dest_block)
Create a new gcc_jit_case instance for use in a switch statement.
@@ -7763,7 +7778,7 @@ statement.
@end deffn
@geindex gcc_jit_case_as_object (C function)
-@anchor{topics/functions gcc_jit_case_as_object}@anchor{d8}
+@anchor{topics/functions gcc_jit_case_as_object}@anchor{d9}
@deffn {C Function} gcc_jit_object * gcc_jit_case_as_object (gcc_jit_case@w{ }*case_)
Upcast from a case to an object.
@@ -7898,7 +7913,7 @@ create_code (gcc_jit_context *ctxt, void *user_data)
@c <http://www.gnu.org/licenses/>.
@node Source Locations,Compiling a context,Creating and using functions,Topic Reference
-@anchor{topics/locations source-locations}@anchor{dc}@anchor{topics/locations doc}@anchor{dd}
+@anchor{topics/locations source-locations}@anchor{dd}@anchor{topics/locations doc}@anchor{de}
@section Source Locations
@@ -7948,7 +7963,7 @@ on-stack buffer.
@end menu
@node Faking it,,,Source Locations
-@anchor{topics/locations faking-it}@anchor{de}
+@anchor{topics/locations faking-it}@anchor{df}
@subsection Faking it
@@ -7986,7 +8001,7 @@ file, giving you @emph{something} you can step through in the debugger.
@c <http://www.gnu.org/licenses/>.
@node Compiling a context,ABI and API compatibility,Source Locations,Topic Reference
-@anchor{topics/compilation compiling-a-context}@anchor{df}@anchor{topics/compilation doc}@anchor{e0}
+@anchor{topics/compilation compiling-a-context}@anchor{e0}@anchor{topics/compilation doc}@anchor{e1}
@section Compiling a context
@@ -8005,7 +8020,7 @@ prevent any future compilation of that context.
@end menu
@node In-memory compilation,Ahead-of-time compilation,,Compiling a context
-@anchor{topics/compilation in-memory-compilation}@anchor{e1}
+@anchor{topics/compilation in-memory-compilation}@anchor{e2}
@subsection In-memory compilation
@@ -8040,7 +8055,7 @@ Functions are looked up by name. For this to succeed, a function
with a name matching @cite{funcname} must have been created on
@cite{result}'s context (or a parent context) via a call to
@pxref{11,,gcc_jit_context_new_function()} with @cite{kind}
-@pxref{c8,,GCC_JIT_FUNCTION_EXPORTED}:
+@pxref{c9,,GCC_JIT_FUNCTION_EXPORTED}:
@example
gcc_jit_context_new_function (ctxt,
@@ -8070,7 +8085,7 @@ to a segmentation fault.
@end deffn
@geindex gcc_jit_result_get_global (C function)
-@anchor{topics/compilation gcc_jit_result_get_global}@anchor{b8}
+@anchor{topics/compilation gcc_jit_result_get_global}@anchor{b9}
@deffn {C Function} void * gcc_jit_result_get_global (gcc_jit_result@w{ }*result, const char@w{ }*name)
Locate a given global within the built machine code.
@@ -8078,8 +8093,8 @@ Locate a given global within the built machine code.
Globals are looked up by name. For this to succeed, a global
with a name matching @cite{name} must have been created on
@cite{result}'s context (or a parent context) via a call to
-@pxref{b5,,gcc_jit_context_new_global()} with @cite{kind}
-@pxref{b7,,GCC_JIT_GLOBAL_EXPORTED}.
+@pxref{b6,,gcc_jit_context_new_global()} with @cite{kind}
+@pxref{b8,,GCC_JIT_GLOBAL_EXPORTED}.
If the global is found, the result will need to be cast to a
pointer of the correct type before it can be called.
@@ -8127,11 +8142,11 @@ Once we're done with the code, this unloads the built .so file.
This cleans up the result; after calling this, it's no longer
valid to use the result, or any code or globals that were obtained
by calling @pxref{17,,gcc_jit_result_get_code()} or
-@pxref{b8,,gcc_jit_result_get_global()} on it.
+@pxref{b9,,gcc_jit_result_get_global()} on it.
@end deffn
@node Ahead-of-time compilation,,In-memory compilation,Compiling a context
-@anchor{topics/compilation ahead-of-time-compilation}@anchor{e2}
+@anchor{topics/compilation ahead-of-time-compilation}@anchor{e3}
@subsection Ahead-of-time compilation
@@ -8160,7 +8175,7 @@ suffix of the output file when determining what to do.
@end cartouche
@geindex gcc_jit_output_kind (C type)
-@anchor{topics/compilation gcc_jit_output_kind}@anchor{e3}
+@anchor{topics/compilation gcc_jit_output_kind}@anchor{e4}
@deffn {C Type} enum gcc_jit_output_kind
@end deffn
@@ -8178,7 +8193,7 @@ Typical suffix
@item
-@pxref{e4,,GCC_JIT_OUTPUT_KIND_ASSEMBLER}
+@pxref{e5,,GCC_JIT_OUTPUT_KIND_ASSEMBLER}
@tab
@@ -8186,7 +8201,7 @@ Typical suffix
@item
-@pxref{e5,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE}
+@pxref{e6,,GCC_JIT_OUTPUT_KIND_OBJECT_FILE}
@tab
@@ -8194,7 +8209,7 @@ Typical suffix
@item
-@pxref{e6,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}
+@pxref{e7,,GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}
@tab
@@ -8202,7 +8217,7 @@ Typical suffix
@item
-@pxref{e7,,GCC_JIT_OUTPUT_KIND_EXECUTABLE}
+@pxref{e8,,GCC_JIT_OUTPUT_KIND_EXECUTABLE}
@tab
@@ -8212,21 +8227,21 @@ None, or .exe
@geindex GCC_JIT_OUTPUT_KIND_ASSEMBLER (C macro)
-@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{e4}
+@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_ASSEMBLER}@anchor{e5}
@deffn {C Macro} GCC_JIT_OUTPUT_KIND_ASSEMBLER
Compile the context to an assembler file.
@end deffn
@geindex GCC_JIT_OUTPUT_KIND_OBJECT_FILE (C macro)
-@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{e5}
+@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_OBJECT_FILE}@anchor{e6}
@deffn {C Macro} GCC_JIT_OUTPUT_KIND_OBJECT_FILE
Compile the context to an object file.
@end deffn
@geindex GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY (C macro)
-@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{e6}
+@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY}@anchor{e7}
@deffn {C Macro} GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY
Compile the context to a dynamic library.
@@ -8236,7 +8251,7 @@ against.
@end deffn
@geindex GCC_JIT_OUTPUT_KIND_EXECUTABLE (C macro)
-@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{e7}
+@anchor{topics/compilation GCC_JIT_OUTPUT_KIND_EXECUTABLE}@anchor{e8}
@deffn {C Macro} GCC_JIT_OUTPUT_KIND_EXECUTABLE
Compile the context to an executable.
@@ -8263,7 +8278,7 @@ against.
@c <http://www.gnu.org/licenses/>.
@node ABI and API compatibility,Performance,Compiling a context,Topic Reference
-@anchor{topics/compatibility abi-and-api-compatibility}@anchor{e8}@anchor{topics/compatibility doc}@anchor{e9}
+@anchor{topics/compatibility abi-and-api-compatibility}@anchor{e9}@anchor{topics/compatibility doc}@anchor{ea}
@section ABI and API compatibility
@@ -8332,7 +8347,7 @@ ABI symbol tags
@node ABI symbol tags,,,ABI and API compatibility
-@anchor{topics/compatibility abi-symbol-tags}@anchor{ea}
+@anchor{topics/compatibility abi-symbol-tags}@anchor{eb}
@subsection ABI symbol tags
@@ -8351,7 +8366,7 @@ Newer releases use the following tags.
@end menu
@node LIBGCCJIT_ABI_0,LIBGCCJIT_ABI_1,,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-0}@anchor{eb}@anchor{topics/compatibility id1}@anchor{ec}
+@anchor{topics/compatibility libgccjit-abi-0}@anchor{ec}@anchor{topics/compatibility id1}@anchor{ed}
@subsubsection @code{LIBGCCJIT_ABI_0}
@@ -8363,7 +8378,7 @@ continue to work, with this being handled transparently by the linker
(see this post@footnote{https://gcc.gnu.org/ml/gcc-patches/2015-06/msg02126.html})
@node LIBGCCJIT_ABI_1,LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_0,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-1}@anchor{73}@anchor{topics/compatibility id2}@anchor{ed}
+@anchor{topics/compatibility libgccjit-abi-1}@anchor{73}@anchor{topics/compatibility id2}@anchor{ee}
@subsubsection @code{LIBGCCJIT_ABI_1}
@@ -8371,7 +8386,7 @@ continue to work, with this being handled transparently by the linker
@pxref{72,,gcc_jit_context_add_command_line_option()}
@node LIBGCCJIT_ABI_2,LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_1,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}@anchor{topics/compatibility id3}@anchor{ee}
+@anchor{topics/compatibility libgccjit-abi-2}@anchor{6c}@anchor{topics/compatibility id3}@anchor{ef}
@subsubsection @code{LIBGCCJIT_ABI_2}
@@ -8379,7 +8394,7 @@ continue to work, with this being handled transparently by the linker
@pxref{6b,,gcc_jit_context_set_bool_allow_unreachable_blocks()}
@node LIBGCCJIT_ABI_3,LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_2,ABI symbol tags
-@anchor{topics/compatibility libgccjit-abi-3}@anchor{da}@anchor{topics/compatibility id4}@anchor{ef}
+@anchor{topics/compatibility libgccjit-abi-3}@anchor{db}@anchor{topics/compatibility id4}@anchor{f0}
@subsubsection @code{LIBGCCJIT_ABI_3}
@@ -8392,18 +8407,18 @@ entrypoints:
@itemize *
@item
-@pxref{d7,,gcc_jit_block_end_with_switch()}
+@pxref{d8,,gcc_jit_block_end_with_switch()}
@item
-@pxref{d8,,gcc_jit_case_as_object()}
+@pxref{d9,,gcc_jit_case_as_object()}
@item
-@pxref{d9,,gcc_jit_context_new_case()}
+@pxref{da,,gcc_jit_context_new_case()}
@end itemize
@end quotation
@node LIBGCCJIT_ABI_4,LIBGCCJIT_ABI_5,LIBGCCJIT_ABI_3,ABI symbol tags
-@anchor{topics/compatibility id5}@anchor{f0}@anchor{topics/compatibility libgccjit-abi-4}@anchor{f1}
+@anchor{topics/compatibility id5}@anchor{f1}@anchor{topics/compatibility libgccjit-abi-4}@anchor{f2}
@subsubsection @code{LIBGCCJIT_ABI_4}
@@ -8416,30 +8431,30 @@ entrypoints:
@itemize *
@item
-@pxref{f2,,gcc_jit_context_get_timer()}
+@pxref{f3,,gcc_jit_context_get_timer()}
@item
-@pxref{f3,,gcc_jit_context_set_timer()}
+@pxref{f4,,gcc_jit_context_set_timer()}
@item
-@pxref{f4,,gcc_jit_timer_new()}
+@pxref{f5,,gcc_jit_timer_new()}
@item
-@pxref{f5,,gcc_jit_timer_release()}
+@pxref{f6,,gcc_jit_timer_release()}
@item
-@pxref{f6,,gcc_jit_timer_push()}
+@pxref{f7,,gcc_jit_timer_push()}
@item
-@pxref{f7,,gcc_jit_timer_pop()}
+@pxref{f8,,gcc_jit_timer_pop()}
@item
-@pxref{f8,,gcc_jit_timer_print()}
+@pxref{f9,,gcc_jit_timer_print()}
@end itemize
@end quotation
@node LIBGCCJIT_ABI_5,,LIBGCCJIT_ABI_4,ABI symbol tags
-@anchor{topics/compatibility id6}@anchor{f9}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e}
+@anchor{topics/compatibility id6}@anchor{fa}@anchor{topics/compatibility libgccjit-abi-5}@anchor{6e}
@subsubsection @code{LIBGCCJIT_ABI_5}
@@ -8464,7 +8479,7 @@ entrypoints:
@c <http://www.gnu.org/licenses/>.
@node Performance,,ABI and API compatibility,Topic Reference
-@anchor{topics/performance performance}@anchor{fa}@anchor{topics/performance doc}@anchor{fb}
+@anchor{topics/performance performance}@anchor{fb}@anchor{topics/performance doc}@anchor{fc}
@section Performance
@@ -8474,14 +8489,14 @@ entrypoints:
@end menu
@node The timing API,,,Performance
-@anchor{topics/performance the-timing-api}@anchor{fc}
+@anchor{topics/performance the-timing-api}@anchor{fd}
@subsection The timing API
As of GCC 6, libgccjit exposes a timing API, for printing reports on
how long was spent in different parts of code.
-You can create a @pxref{fd,,gcc_jit_timer} instance, which will
+You can create a @pxref{fe,,gcc_jit_timer} instance, which will
measure time spent since its creation. The timer maintains a stack
of "timer items": as control flow moves through your code, you can push
and pop named items relating to your code onto the stack, and the timer
@@ -8583,7 +8598,7 @@ Client items:
The exact format is intended to be human-readable, and is subject to change.
@geindex LIBGCCJIT_HAVE_TIMING_API (C macro)
-@anchor{topics/performance LIBGCCJIT_HAVE_TIMING_API}@anchor{fe}
+@anchor{topics/performance LIBGCCJIT_HAVE_TIMING_API}@anchor{ff}
@deffn {C Macro} LIBGCCJIT_HAVE_TIMING_API
The timer API was added to libgccjit in GCC 6.
@@ -8602,15 +8617,15 @@ gcc_jit_context_set_timer (ctxt, t);
@end deffn
@geindex gcc_jit_timer (C type)
-@anchor{topics/performance gcc_jit_timer}@anchor{fd}
+@anchor{topics/performance gcc_jit_timer}@anchor{fe}
@deffn {C Type} gcc_jit_timer
@end deffn
@geindex gcc_jit_timer_new (C function)
-@anchor{topics/performance gcc_jit_timer_new}@anchor{f4}
+@anchor{topics/performance gcc_jit_timer_new}@anchor{f5}
@deffn {C Function} gcc_jit_timer * gcc_jit_timer_new (void)
-Create a @pxref{fd,,gcc_jit_timer} instance, and start timing:
+Create a @pxref{fe,,gcc_jit_timer} instance, and start timing:
@example
gcc_jit_timer *t = gcc_jit_timer_new ();
@@ -8618,7 +8633,7 @@ gcc_jit_timer *t = gcc_jit_timer_new ();
@noindent
-This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8629,10 +8644,10 @@ for its presence using
@end deffn
@geindex gcc_jit_timer_release (C function)
-@anchor{topics/performance gcc_jit_timer_release}@anchor{f5}
+@anchor{topics/performance gcc_jit_timer_release}@anchor{f6}
@deffn {C Function} void gcc_jit_timer_release (gcc_jit_timer@w{ }*timer)
-Release a @pxref{fd,,gcc_jit_timer} instance:
+Release a @pxref{fe,,gcc_jit_timer} instance:
@example
gcc_jit_timer_release (t);
@@ -8642,7 +8657,7 @@ gcc_jit_timer_release (t);
This should be called exactly once on a timer.
-This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8653,10 +8668,10 @@ for its presence using
@end deffn
@geindex gcc_jit_context_set_timer (C function)
-@anchor{topics/performance gcc_jit_context_set_timer}@anchor{f3}
+@anchor{topics/performance gcc_jit_context_set_timer}@anchor{f4}
@deffn {C Function} void gcc_jit_context_set_timer (gcc_jit_context@w{ }*ctxt, gcc_jit_timer@w{ }*timer)
-Associate a @pxref{fd,,gcc_jit_timer} instance with a context:
+Associate a @pxref{fe,,gcc_jit_timer} instance with a context:
@example
gcc_jit_context_set_timer (ctxt, t);
@@ -8671,7 +8686,7 @@ Timers have no locking, so if you have a multithreaded program, you
must provide your own locks if more than one thread could be working
with the same timer via timer-associated contexts.
-This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8682,12 +8697,12 @@ for its presence using
@end deffn
@geindex gcc_jit_context_get_timer (C function)
-@anchor{topics/performance gcc_jit_context_get_timer}@anchor{f2}
+@anchor{topics/performance gcc_jit_context_get_timer}@anchor{f3}
@deffn {C Function} gcc_jit_timer *gcc_jit_context_get_timer (gcc_jit_context@w{ }*ctxt)
Get the timer associated with a context (if any).
-This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8698,7 +8713,7 @@ for its presence using
@end deffn
@geindex gcc_jit_timer_push (C function)
-@anchor{topics/performance gcc_jit_timer_push}@anchor{f6}
+@anchor{topics/performance gcc_jit_timer_push}@anchor{f7}
@deffn {C Function} void gcc_jit_timer_push (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name)
Push the given item onto the timer's stack:
@@ -8711,7 +8726,7 @@ gcc_jit_timer_pop (t, "running code");
@noindent
-This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8722,7 +8737,7 @@ for its presence using
@end deffn
@geindex gcc_jit_timer_pop (C function)
-@anchor{topics/performance gcc_jit_timer_pop}@anchor{f7}
+@anchor{topics/performance gcc_jit_timer_pop}@anchor{f8}
@deffn {C Function} void gcc_jit_timer_pop (gcc_jit_timer@w{ }*timer, const char@w{ }*item_name)
Pop the top item from the timer's stack.
@@ -8730,7 +8745,7 @@ Pop the top item from the timer's stack.
If "item_name" is provided, it must match that of the top item.
Alternatively, @code{NULL} can be passed in, to suppress checking.
-This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8741,13 +8756,13 @@ for its presence using
@end deffn
@geindex gcc_jit_timer_print (C function)
-@anchor{topics/performance gcc_jit_timer_print}@anchor{f8}
+@anchor{topics/performance gcc_jit_timer_print}@anchor{f9}
@deffn {C Function} void gcc_jit_timer_print (gcc_jit_timer@w{ }*timer, FILE@w{ }*f_out)
Print timing information to the given stream about activity since
the timer was started.
-This API entrypoint was added in @pxref{f1,,LIBGCCJIT_ABI_4}; you can test
+This API entrypoint was added in @pxref{f2,,LIBGCCJIT_ABI_4}; you can test
for its presence using
@example
@@ -8775,7 +8790,7 @@ for its presence using
@c <http://www.gnu.org/licenses/>.
@node C++ bindings for libgccjit,Internals,Topic Reference,Top
-@anchor{cp/index c-bindings-for-libgccjit}@anchor{ff}@anchor{cp/index doc}@anchor{100}
+@anchor{cp/index c-bindings-for-libgccjit}@anchor{100}@anchor{cp/index doc}@anchor{101}
@chapter C++ bindings for libgccjit
@@ -8923,7 +8938,7 @@ Compiling a context
@node Tutorial<2>,Topic Reference<2>,,C++ bindings for libgccjit
-@anchor{cp/intro/index doc}@anchor{101}@anchor{cp/intro/index tutorial}@anchor{102}
+@anchor{cp/intro/index doc}@anchor{102}@anchor{cp/intro/index tutorial}@anchor{103}
@section Tutorial
@@ -8953,7 +8968,7 @@ Compiling a context
@end menu
@node Tutorial part 1 "Hello world"<2>,Tutorial part 2 Creating a trivial machine code function<2>,,Tutorial<2>
-@anchor{cp/intro/tutorial01 doc}@anchor{103}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{104}
+@anchor{cp/intro/tutorial01 doc}@anchor{104}@anchor{cp/intro/tutorial01 tutorial-part-1-hello-world}@anchor{105}
@subsection Tutorial part 1: "Hello world"
@@ -9123,7 +9138,7 @@ hello world
@c <http://www.gnu.org/licenses/>.
@node Tutorial part 2 Creating a trivial machine code function<2>,Tutorial part 3 Loops and variables<2>,Tutorial part 1 "Hello world"<2>,Tutorial<2>
-@anchor{cp/intro/tutorial02 doc}@anchor{105}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{106}
+@anchor{cp/intro/tutorial02 doc}@anchor{106}@anchor{cp/intro/tutorial02 tutorial-part-2-creating-a-trivial-machine-code-function}@anchor{107}
@subsection Tutorial part 2: Creating a trivial machine code function
@@ -9152,7 +9167,7 @@ All state associated with compilation is associated with a
@code{gccjit::context}, which is a thin C++ wrapper around the C API's
@pxref{8,,gcc_jit_context *}.
-Create one using @pxref{107,,gccjit;;context;;acquire()}:
+Create one using @pxref{108,,gccjit;;context;;acquire()}:
@example
gccjit::context ctxt;
@@ -9165,7 +9180,7 @@ The JIT library has a system of types. It is statically-typed: every
expression is of a specific type, fixed at compile-time. In our example,
all of the expressions are of the C @cite{int} type, so let's obtain this from
the context, as a @code{gccjit::type}, using
-@pxref{108,,gccjit;;context;;get_type()}:
+@pxref{109,,gccjit;;context;;get_type()}:
@example
gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
@@ -9178,7 +9193,7 @@ entity in the API is associated with a @code{gccjit::context}.
Memory management is easy: all such "contextual" objects are automatically
cleaned up for you when the context is released, using
-@pxref{109,,gccjit;;context;;release()}:
+@pxref{10a,,gccjit;;context;;release()}:
@example
ctxt.release ();
@@ -9211,7 +9226,7 @@ The C++ class hierarchy within the @code{gccjit} namespace looks like this:
One thing you can do with a @code{gccjit::object} is
to ask it for a human-readable description as a @code{std::string}, using
-@pxref{10a,,gccjit;;object;;get_debug_string()}:
+@pxref{10b,,gccjit;;object;;get_debug_string()}:
@example
printf ("obj: %s\n", obj.get_debug_string ().c_str ());
@@ -9231,7 +9246,7 @@ This is invaluable when debugging.
Let's create the function. To do so, we first need to construct
its single parameter, specifying its type and giving it a name,
-using @pxref{10b,,gccjit;;context;;new_param()}:
+using @pxref{10c,,gccjit;;context;;new_param()}:
@example
gccjit::param param_i = ctxt.new_param (int_type, "i");
@@ -9280,7 +9295,7 @@ gccjit::block block = func.new_block ();
Our basic block is relatively simple: it immediately terminates by
returning the value of an expression.
-We can build the expression using @pxref{10c,,gccjit;;context;;new_binary_op()}:
+We can build the expression using @pxref{10d,,gccjit;;context;;new_binary_op()}:
@example
gccjit::rvalue expr =
@@ -9293,7 +9308,7 @@ gccjit::rvalue expr =
A @code{gccjit::rvalue} is another example of a
@code{gccjit::object} subclass. As before, we can print it with
-@pxref{10a,,gccjit;;object;;get_debug_string()}.
+@pxref{10b,,gccjit;;object;;get_debug_string()}.
@example
printf ("expr: %s\n", expr.get_debug_string ().c_str ());
@@ -9330,7 +9345,7 @@ block.end_with_return (expr);
@noindent
OK, we've populated the context. We can now compile it using
-@pxref{10d,,gccjit;;context;;compile()}:
+@pxref{10e,,gccjit;;context;;compile()}:
@example
gcc_jit_result *result;
@@ -9380,12 +9395,12 @@ result: 25
@end menu
@node Options<3>,Full example<3>,,Tutorial part 2 Creating a trivial machine code function<2>
-@anchor{cp/intro/tutorial02 options}@anchor{10e}
+@anchor{cp/intro/tutorial02 options}@anchor{10f}
@subsubsection Options
To get more information on what's going on, you can set debugging flags
-on the context using @pxref{10f,,gccjit;;context;;set_bool_option()}.
+on the context using @pxref{110,,gccjit;;context;;set_bool_option()}.
@c (I'm deliberately not mentioning
@c :c:macro:`GCC_JIT_BOOL_OPTION_DUMP_INITIAL_TREE` here since I think
@@ -9457,7 +9472,7 @@ square:
By default, no optimizations are performed, the equivalent of GCC's
@cite{-O0} option. We can turn things up to e.g. @cite{-O3} by calling
-@pxref{110,,gccjit;;context;;set_int_option()} with
+@pxref{111,,gccjit;;context;;set_int_option()} with
@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
@example
@@ -9491,7 +9506,7 @@ square:
Naturally this has only a small effect on such a trivial function.
@node Full example<3>,,Options<3>,Tutorial part 2 Creating a trivial machine code function<2>
-@anchor{cp/intro/tutorial02 full-example}@anchor{111}
+@anchor{cp/intro/tutorial02 full-example}@anchor{112}
@subsubsection Full example
@@ -9634,7 +9649,7 @@ result: 25
@c <http://www.gnu.org/licenses/>.
@node Tutorial part 3 Loops and variables<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,Tutorial part 2 Creating a trivial machine code function<2>,Tutorial<2>
-@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{112}@anchor{cp/intro/tutorial03 doc}@anchor{113}
+@anchor{cp/intro/tutorial03 tutorial-part-3-loops-and-variables}@anchor{113}@anchor{cp/intro/tutorial03 doc}@anchor{114}
@subsection Tutorial part 3: Loops and variables
@@ -9758,7 +9773,7 @@ gccjit::function func =
@end menu
@node Expressions lvalues and rvalues<2>,Control flow<2>,,Tutorial part 3 Loops and variables<2>
-@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{114}
+@anchor{cp/intro/tutorial03 expressions-lvalues-and-rvalues}@anchor{115}
@subsubsection Expressions: lvalues and rvalues
@@ -9831,7 +9846,7 @@ body of a function.
Our new example has a new kind of expression: we have two local
variables. We create them by calling
-@pxref{115,,gccjit;;function;;new_local()}, supplying a type and a name:
+@pxref{116,,gccjit;;function;;new_local()}, supplying a type and a name:
@example
/* Build locals: */
@@ -9857,7 +9872,7 @@ Instead, having added the local to the function, we have to separately add
an assignment of @cite{0} to @cite{local_i} at the beginning of the function.
@node Control flow<2>,Visualizing the control flow graph<2>,Expressions lvalues and rvalues<2>,Tutorial part 3 Loops and variables<2>
-@anchor{cp/intro/tutorial03 control-flow}@anchor{116}
+@anchor{cp/intro/tutorial03 control-flow}@anchor{117}
@subsubsection Control flow
@@ -9896,8 +9911,8 @@ We now populate each block with statements.
The entry block @cite{b_initial} consists of initializations followed by a jump
to the conditional. We assign @cite{0} to @cite{i} and to @cite{sum}, using
-@pxref{117,,gccjit;;block;;add_assignment()} to add
-an assignment statement, and using @pxref{118,,gccjit;;context;;zero()} to get
+@pxref{118,,gccjit;;block;;add_assignment()} to add
+an assignment statement, and using @pxref{119,,gccjit;;context;;zero()} to get
the constant value @cite{0} for the relevant type for the right-hand side of
the assignment:
@@ -9924,7 +9939,7 @@ C example. It contains a single statement: a conditional, which jumps to
one of two destination blocks depending on a boolean
@code{gccjit::rvalue}, in this case the comparison of @cite{i} and @cite{n}.
-We could build the comparison using @pxref{119,,gccjit;;context;;new_comparison()}:
+We could build the comparison using @pxref{11a,,gccjit;;context;;new_comparison()}:
@example
gccjit::rvalue guard =
@@ -9935,7 +9950,7 @@ gccjit::rvalue guard =
@noindent
and can then use this to add @cite{b_loop_cond}'s sole statement, via
-@pxref{11a,,gccjit;;block;;end_with_conditional()}:
+@pxref{11b,,gccjit;;block;;end_with_conditional()}:
@example
b_loop_cond.end_with_conditional (guard,
@@ -9969,7 +9984,7 @@ Next, we populate the body of the loop.
The C statement @cite{sum += i * i;} is an assignment operation, where an
lvalue is modified "in-place". We use
-@pxref{11b,,gccjit;;block;;add_assignment_op()} to handle these operations:
+@pxref{11c,,gccjit;;block;;add_assignment_op()} to handle these operations:
@example
/* sum += i * i */
@@ -9997,7 +10012,7 @@ b_loop_body.add_assignment_op (i,
@cartouche
@quotation Note
For numeric constants other than 0 or 1, we could use
-@pxref{11c,,gccjit;;context;;new_rvalue()}, which has overloads
+@pxref{11d,,gccjit;;context;;new_rvalue()}, which has overloads
for both @code{int} and @code{double}.
@end quotation
@end cartouche
@@ -10073,12 +10088,12 @@ result: 285
@noindent
@node Visualizing the control flow graph<2>,Full example<4>,Control flow<2>,Tutorial part 3 Loops and variables<2>
-@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{11d}
+@anchor{cp/intro/tutorial03 visualizing-the-control-flow-graph}@anchor{11e}
@subsubsection Visualizing the control flow graph
You can see the control flow graph of a function using
-@pxref{11e,,gccjit;;function;;dump_to_dot()}:
+@pxref{11f,,gccjit;;function;;dump_to_dot()}:
@example
func.dump_to_dot ("/tmp/sum-of-squares.dot");
@@ -10112,7 +10127,7 @@ install it with @cite{yum install python-xdot}):
@end quotation
@node Full example<4>,,Visualizing the control flow graph<2>,Tutorial part 3 Loops and variables<2>
-@anchor{cp/intro/tutorial03 full-example}@anchor{11f}
+@anchor{cp/intro/tutorial03 full-example}@anchor{120}
@subsubsection Full example
@@ -10295,7 +10310,7 @@ loop_test returned: 285
@c <http://www.gnu.org/licenses/>.
@node Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>,,Tutorial part 3 Loops and variables<2>,Tutorial<2>
-@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{120}@anchor{cp/intro/tutorial04 doc}@anchor{121}
+@anchor{cp/intro/tutorial04 tutorial-part-4-adding-jit-compilation-to-a-toy-interpreter}@anchor{121}@anchor{cp/intro/tutorial04 doc}@anchor{122}
@subsection Tutorial part 4: Adding JIT-compilation to a toy interpreter
@@ -10317,7 +10332,7 @@ to it.
@end menu
@node Our toy interpreter<2>,Compiling to machine code<2>,,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{122}
+@anchor{cp/intro/tutorial04 our-toy-interpreter}@anchor{123}
@subsubsection Our toy interpreter
@@ -10725,7 +10740,7 @@ toyvm_function::interpret (int arg, FILE *trace)
@end quotation
@node Compiling to machine code<2>,Setting things up<2>,Our toy interpreter<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{123}
+@anchor{cp/intro/tutorial04 compiling-to-machine-code}@anchor{124}
@subsubsection Compiling to machine code
@@ -10805,7 +10820,7 @@ This means our compiler has the following state:
@end quotation
@node Setting things up<2>,Populating the function<2>,Compiling to machine code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 setting-things-up}@anchor{124}
+@anchor{cp/intro/tutorial04 setting-things-up}@anchor{125}
@subsubsection Setting things up
@@ -10973,7 +10988,7 @@ We create the locals within the function.
@end quotation
@node Populating the function<2>,Verifying the control flow graph<2>,Setting things up<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 populating-the-function}@anchor{125}
+@anchor{cp/intro/tutorial04 populating-the-function}@anchor{126}
@subsubsection Populating the function
@@ -11101,7 +11116,7 @@ stack into @code{y} instead erroneously assigned it to @code{x}, leaving @code{y
uninitialized.
To track this kind of thing down, we can use
-@pxref{126,,gccjit;;block;;add_comment()} to add descriptive comments
+@pxref{127,,gccjit;;block;;add_comment()} to add descriptive comments
to the internal representation. This is invaluable when looking through
the generated IR for, say @code{factorial}:
@@ -11250,14 +11265,14 @@ to the next block.
This is analogous to simply incrementing the program counter.
@node Verifying the control flow graph<2>,Compiling the context<2>,Populating the function<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{127}
+@anchor{cp/intro/tutorial04 verifying-the-control-flow-graph}@anchor{128}
@subsubsection Verifying the control flow graph
Having finished looping over the blocks, the context is complete.
As before, we can verify that the control flow and statements are sane by
-using @pxref{11e,,gccjit;;function;;dump_to_dot()}:
+using @pxref{11f,,gccjit;;function;;dump_to_dot()}:
@example
fn.dump_to_dot ("/tmp/factorial.dot");
@@ -11281,7 +11296,7 @@ errors in our compiler.
@end quotation
@node Compiling the context<2>,Single-stepping through the generated code<2>,Verifying the control flow graph<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{128}
+@anchor{cp/intro/tutorial04 compiling-the-context}@anchor{129}
@subsubsection Compiling the context
@@ -11338,7 +11353,7 @@ private:
@end quotation
@node Single-stepping through the generated code<2>,Examining the generated code<2>,Compiling the context<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{129}
+@anchor{cp/intro/tutorial04 single-stepping-through-the-generated-code}@anchor{12a}
@subsubsection Single-stepping through the generated code
@@ -11352,14 +11367,14 @@ It's possible to debug the generated code. To do this we need to both:
@item
Set up source code locations for our statements, so that we can
meaningfully step through the code. We did this above by
-calling @pxref{12a,,gccjit;;context;;new_location()} and using the
+calling @pxref{12b,,gccjit;;context;;new_location()} and using the
results.
@item
Enable the generation of debugging information, by setting
@pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
@code{gccjit::context} via
-@pxref{10f,,gccjit;;context;;set_bool_option()}:
+@pxref{110,,gccjit;;context;;set_bool_option()}:
@example
ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
@@ -11431,14 +11446,14 @@ optimization level in a regular compiler.
@end cartouche
@node Examining the generated code<2>,Putting it all together<2>,Single-stepping through the generated code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{12b}
+@anchor{cp/intro/tutorial04 examining-the-generated-code}@anchor{12c}
@subsubsection Examining the generated code
How good is the optimized code?
We can turn up optimizations, by calling
-@pxref{110,,gccjit;;context;;set_int_option()} with
+@pxref{111,,gccjit;;context;;set_int_option()} with
@pxref{1f,,GCC_JIT_INT_OPTION_OPTIMIZATION_LEVEL}:
@example
@@ -11620,7 +11635,7 @@ Note that the stack pushing and popping have been eliminated, as has the
recursive call (in favor of an iteration).
@node Putting it all together<2>,Behind the curtain How does our code get optimized?<2>,Examining the generated code<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{12c}
+@anchor{cp/intro/tutorial04 putting-it-all-together}@anchor{12d}
@subsubsection Putting it all together
@@ -11653,7 +11668,7 @@ compiler result: 55
@noindent
@node Behind the curtain How does our code get optimized?<2>,,Putting it all together<2>,Tutorial part 4 Adding JIT-compilation to a toy interpreter<2>
-@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{12d}
+@anchor{cp/intro/tutorial04 behind-the-curtain-how-does-our-code-get-optimized}@anchor{12e}
@subsubsection Behind the curtain: How does our code get optimized?
@@ -11854,7 +11869,7 @@ representation: @code{initial}, @code{instr4} and @code{instr9}.
@end menu
@node Optimizing away stack manipulation<2>,Elimination of tail recursion<2>,,Behind the curtain How does our code get optimized?<2>
-@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{12e}
+@anchor{cp/intro/tutorial04 optimizing-away-stack-manipulation}@anchor{12f}
@subsubsection Optimizing away stack manipulation
@@ -12134,7 +12149,7 @@ instr9:
@noindent
@node Elimination of tail recursion<2>,,Optimizing away stack manipulation<2>,Behind the curtain How does our code get optimized?<2>
-@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{12f}
+@anchor{cp/intro/tutorial04 elimination-of-tail-recursion}@anchor{130}
@subsubsection Elimination of tail recursion
@@ -12221,7 +12236,7 @@ instr9:
@c <http://www.gnu.org/licenses/>.
@node Topic Reference<2>,,Tutorial<2>,C++ bindings for libgccjit
-@anchor{cp/topics/index doc}@anchor{130}@anchor{cp/topics/index topic-reference}@anchor{131}
+@anchor{cp/topics/index doc}@anchor{131}@anchor{cp/topics/index topic-reference}@anchor{132}
@section Topic Reference
@@ -12311,22 +12326,22 @@ Compiling a context
@node Compilation contexts<2>,Objects<2>,,Topic Reference<2>
-@anchor{cp/topics/contexts compilation-contexts}@anchor{132}@anchor{cp/topics/contexts doc}@anchor{133}
+@anchor{cp/topics/contexts compilation-contexts}@anchor{133}@anchor{cp/topics/contexts doc}@anchor{134}
@subsection Compilation contexts
@geindex gccjit;;context (C++ class)
-@anchor{cp/topics/contexts gccjit context}@anchor{134}
+@anchor{cp/topics/contexts gccjit context}@anchor{135}
@deffn {C++ Class} gccjit::context
@end deffn
-The top-level of the C++ API is the @pxref{134,,gccjit;;context} type.
+The top-level of the C++ API is the @pxref{135,,gccjit;;context} type.
-A @pxref{134,,gccjit;;context} instance encapsulates the state of a
+A @pxref{135,,gccjit;;context} instance encapsulates the state of a
compilation.
You can set up options on it, and add types, functions and code.
-Invoking @pxref{10d,,gccjit;;context;;compile()} on it gives you a
+Invoking @pxref{10e,,gccjit;;context;;compile()} on it gives you a
@pxref{16,,gcc_jit_result *}.
It is a thin wrapper around the C API's @pxref{8,,gcc_jit_context *}.
@@ -12341,7 +12356,7 @@ It is a thin wrapper around the C API's @pxref{8,,gcc_jit_context *}.
@end menu
@node Lifetime-management<2>,Thread-safety<2>,,Compilation contexts<2>
-@anchor{cp/topics/contexts lifetime-management}@anchor{135}
+@anchor{cp/topics/contexts lifetime-management}@anchor{136}
@subsubsection Lifetime-management
@@ -12350,16 +12365,16 @@ have their lifetime bounded by the context they are created within, and
cleanup of such objects is done for you when the context is released.
@geindex gccjit;;context;;acquire (C++ function)
-@anchor{cp/topics/contexts gccjit context acquire}@anchor{107}
+@anchor{cp/topics/contexts gccjit context acquire}@anchor{108}
@deffn {C++ Function} gccjit::context gccjit::context::acquire ()
-This function acquires a new @pxref{134,,gccjit;;context} instance,
+This function acquires a new @pxref{135,,gccjit;;context} instance,
which is independent of any others that may be present within this
process.
@end deffn
@geindex gccjit;;context;;release (C++ function)
-@anchor{cp/topics/contexts gccjit context release}@anchor{109}
+@anchor{cp/topics/contexts gccjit context release}@anchor{10a}
@deffn {C++ Function} void gccjit::context::release ()
This function releases all resources associated with the given context.
@@ -12378,7 +12393,7 @@ ctxt.release ();
@end deffn
@geindex gccjit;;context;;new_child_context (C++ function)
-@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{136}
+@anchor{cp/topics/contexts gccjit context new_child_context}@anchor{137}
@deffn {C++ Function} gccjit::context gccjit::context::new_child_context ()
Given an existing JIT context, create a child context.
@@ -12410,16 +12425,16 @@ there will likely be a performance hit for such nesting.
@end deffn
@node Thread-safety<2>,Error-handling<3>,Lifetime-management<2>,Compilation contexts<2>
-@anchor{cp/topics/contexts thread-safety}@anchor{137}
+@anchor{cp/topics/contexts thread-safety}@anchor{138}
@subsubsection Thread-safety
-Instances of @pxref{134,,gccjit;;context} created via
-@pxref{107,,gccjit;;context;;acquire()} are independent from each other:
+Instances of @pxref{135,,gccjit;;context} created via
+@pxref{108,,gccjit;;context;;acquire()} are independent from each other:
only one thread may use a given context at once, but multiple threads
could each have their own contexts without needing locks.
-Contexts created via @pxref{136,,gccjit;;context;;new_child_context()} are
+Contexts created via @pxref{137,,gccjit;;context;;new_child_context()} are
related to their parent context. They can be partitioned by their
ultimate ancestor into independent "family trees". Only one thread
within a process may use a given "family tree" of such contexts at once,
@@ -12427,7 +12442,7 @@ and if you're using multiple threads you should provide your own locking
around entire such context partitions.
@node Error-handling<3>,Debugging<2>,Thread-safety<2>,Compilation contexts<2>
-@anchor{cp/topics/contexts error-handling}@anchor{138}
+@anchor{cp/topics/contexts error-handling}@anchor{139}
@subsubsection Error-handling
@@ -12440,10 +12455,10 @@ NULL. You don't have to check everywhere for NULL results, since the
API gracefully handles a NULL being passed in for any argument.
Errors are printed on stderr and can be queried using
-@pxref{139,,gccjit;;context;;get_first_error()}.
+@pxref{13a,,gccjit;;context;;get_first_error()}.
@geindex gccjit;;context;;get_first_error (C++ function)
-@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{139}
+@anchor{cp/topics/contexts gccjit context get_first_error__gccjit contextP}@anchor{13a}
@deffn {C++ Function} const char* gccjit::context::get_first_error (gccjit::context* ctxt)
Returns the first error message that occurred on the context.
@@ -12455,18 +12470,18 @@ If no errors occurred, this will be NULL.
@end deffn
@node Debugging<2>,Options<4>,Error-handling<3>,Compilation contexts<2>
-@anchor{cp/topics/contexts debugging}@anchor{13a}
+@anchor{cp/topics/contexts debugging}@anchor{13b}
@subsubsection Debugging
@geindex gccjit;;context;;dump_to_file (C++ function)
-@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{13b}
+@anchor{cp/topics/contexts gccjit context dump_to_file__ssCR i}@anchor{13c}
@deffn {C++ Function} void gccjit::context::dump_to_file (const std::string& path, int update_locations)
To help with debugging: dump a C-like representation to the given path,
describing what's been set up on the context.
-If "update_locations" is true, then also set up @pxref{13c,,gccjit;;location}
+If "update_locations" is true, then also set up @pxref{13d,,gccjit;;location}
information throughout the context, pointing at the dump file as if it
were a source file. This may be of use in conjunction with
@code{GCCJIT::BOOL_OPTION_DEBUGINFO} to allow stepping through the
@@ -12474,7 +12489,7 @@ code in a debugger.
@end deffn
@geindex gccjit;;context;;dump_reproducer_to_file (C++ function)
-@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{13d}
+@anchor{cp/topics/contexts gccjit context dump_reproducer_to_file__gcc_jit_contextP cCP}@anchor{13e}
@deffn {C++ Function} void gccjit::context::dump_reproducer_to_file (gcc_jit_context* ctxt, const char* path)
This is a thin wrapper around the C API
@@ -12486,7 +12501,7 @@ for seeing what the C++ bindings are doing at the C level.
@end deffn
@node Options<4>,,Debugging<2>,Compilation contexts<2>
-@anchor{cp/topics/contexts options}@anchor{13e}
+@anchor{cp/topics/contexts options}@anchor{13f}
@subsubsection Options
@@ -12499,12 +12514,12 @@ for seeing what the C++ bindings are doing at the C level.
@end menu
@node String Options<2>,Boolean options<2>,,Options<4>
-@anchor{cp/topics/contexts string-options}@anchor{13f}
+@anchor{cp/topics/contexts string-options}@anchor{140}
@subsubsection String Options
@geindex gccjit;;context;;set_str_option (C++ function)
-@anchor{cp/topics/contexts gccjit context set_str_option__enum cCP}@anchor{140}
+@anchor{cp/topics/contexts gccjit context set_str_option__enum cCP}@anchor{141}
@deffn {C++ Function} void gccjit::context::set_str_option (enum gcc_jit_str_option, const char* value)
Set a string option of the context.
@@ -12515,12 +12530,12 @@ meaning.
@end deffn
@node Boolean options<2>,Integer options<2>,String Options<2>,Options<4>
-@anchor{cp/topics/contexts boolean-options}@anchor{141}
+@anchor{cp/topics/contexts boolean-options}@anchor{142}
@subsubsection Boolean options
@geindex gccjit;;context;;set_bool_option (C++ function)
-@anchor{cp/topics/contexts gccjit context set_bool_option__enum i}@anchor{10f}
+@anchor{cp/topics/contexts gccjit context set_bool_option__enum i}@anchor{110}
@deffn {C++ Function} void gccjit::context::set_bool_option (enum gcc_jit_bool_option, int value)
Set a boolean option of the context.
@@ -12531,7 +12546,7 @@ meaning.
@end deffn
@geindex gccjit;;context;;set_bool_allow_unreachable_blocks (C++ function)
-@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{142}
+@anchor{cp/topics/contexts gccjit context set_bool_allow_unreachable_blocks__i}@anchor{143}
@deffn {C++ Function} void gccjit::context::set_bool_allow_unreachable_blocks (int bool_value)
By default, libgccjit will issue an error about unreachable blocks
@@ -12552,7 +12567,7 @@ its presence using
@end deffn
@geindex gccjit;;context;;set_bool_use_external_driver (C++ function)
-@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{143}
+@anchor{cp/topics/contexts gccjit context set_bool_use_external_driver__i}@anchor{144}
@deffn {C++ Function} void gccjit::context::set_bool_use_external_driver (int bool_value)
libgccjit internally generates assembler, and uses "driver" code
@@ -12576,12 +12591,12 @@ its presence using
@end deffn
@node Integer options<2>,Additional command-line options<2>,Boolean options<2>,Options<4>
-@anchor{cp/topics/contexts integer-options}@anchor{144}
+@anchor{cp/topics/contexts integer-options}@anchor{145}
@subsubsection Integer options
@geindex gccjit;;context;;set_int_option (C++ function)
-@anchor{cp/topics/contexts gccjit context set_int_option__enum i}@anchor{110}
+@anchor{cp/topics/contexts gccjit context set_int_option__enum i}@anchor{111}
@deffn {C++ Function} void gccjit::context::set_int_option (enum gcc_jit_int_option, int value)
Set an integer option of the context.
@@ -12592,12 +12607,12 @@ meaning.
@end deffn
@node Additional command-line options<2>,,Integer options<2>,Options<4>
-@anchor{cp/topics/contexts additional-command-line-options}@anchor{145}
+@anchor{cp/topics/contexts additional-command-line-options}@anchor{146}
@subsubsection Additional command-line options
@geindex gccjit;;context;;add_command_line_option (C++ function)
-@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{146}
+@anchor{cp/topics/contexts gccjit context add_command_line_option__cCP}@anchor{147}
@deffn {C++ Function} void gccjit::context::add_command_line_option (const char* optname)
Add an arbitrary gcc command-line option to the context for use
@@ -12634,18 +12649,18 @@ its presence using
@c <http://www.gnu.org/licenses/>.
@node Objects<2>,Types<2>,Compilation contexts<2>,Topic Reference<2>
-@anchor{cp/topics/objects objects}@anchor{147}@anchor{cp/topics/objects doc}@anchor{148}
+@anchor{cp/topics/objects objects}@anchor{148}@anchor{cp/topics/objects doc}@anchor{149}
@subsection Objects
@geindex gccjit;;object (C++ class)
-@anchor{cp/topics/objects gccjit object}@anchor{149}
+@anchor{cp/topics/objects gccjit object}@anchor{14a}
@deffn {C++ Class} gccjit::object
@end deffn
Almost every entity in the API (with the exception of
-@pxref{134,,gccjit;;context} and @pxref{16,,gcc_jit_result *}) is a
-"contextual" object, a @pxref{149,,gccjit;;object}.
+@pxref{135,,gccjit;;context} and @pxref{16,,gcc_jit_result *}) is a
+"contextual" object, a @pxref{14a,,gccjit;;object}.
A JIT object:
@@ -12655,7 +12670,7 @@ A JIT object:
@itemize *
@item
-is associated with a @pxref{134,,gccjit;;context}.
+is associated with a @pxref{135,,gccjit;;context}.
@item
is automatically cleaned up for you when its context is released so
@@ -12682,17 +12697,17 @@ The C++ class hierarchy within the @code{gccjit} namespace looks like this:
@noindent
-The @pxref{149,,gccjit;;object} base class has the following operations:
+The @pxref{14a,,gccjit;;object} base class has the following operations:
@geindex gccjit;;object;;get_context (C++ function)
-@anchor{cp/topics/objects gccjit object get_contextC}@anchor{14a}
+@anchor{cp/topics/objects gccjit object get_contextC}@anchor{14b}
@deffn {C++ Function} gccjit::context gccjit::object::get_context () const
Which context is the obj within?
@end deffn
@geindex gccjit;;object;;get_debug_string (C++ function)
-@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{10a}
+@anchor{cp/topics/objects gccjit object get_debug_stringC}@anchor{10b}
@deffn {C++ Function} std::string gccjit::object::get_debug_string () const
Generate a human-readable description for the given object.
@@ -12732,16 +12747,16 @@ obj: 4.0 * (float)i
@c <http://www.gnu.org/licenses/>.
@node Types<2>,Expressions<2>,Objects<2>,Topic Reference<2>
-@anchor{cp/topics/types doc}@anchor{14b}@anchor{cp/topics/types types}@anchor{14c}
+@anchor{cp/topics/types doc}@anchor{14c}@anchor{cp/topics/types types}@anchor{14d}
@subsection Types
@geindex gccjit;;type (C++ class)
-@anchor{cp/topics/types gccjit type}@anchor{14d}
+@anchor{cp/topics/types gccjit type}@anchor{14e}
@deffn {C++ Class} gccjit::type
gccjit::type represents a type within the library. It is a subclass
-of @pxref{149,,gccjit;;object}.
+of @pxref{14a,,gccjit;;object}.
@end deffn
Types can be created in several ways:
@@ -12751,7 +12766,7 @@ Types can be created in several ways:
@item
fundamental types can be accessed using
-@pxref{108,,gccjit;;context;;get_type()}:
+@pxref{109,,gccjit;;context;;get_type()}:
@example
gccjit::type int_type = ctxt.get_type (GCC_JIT_TYPE_INT);
@@ -12771,7 +12786,7 @@ See @pxref{b,,gcc_jit_context_get_type()} for the available types.
@item
derived types can be accessed by using functions such as
-@pxref{14e,,gccjit;;type;;get_pointer()} and @pxref{14f,,gccjit;;type;;get_const()}:
+@pxref{14f,,gccjit;;type;;get_pointer()} and @pxref{150,,gccjit;;type;;get_const()}:
@example
gccjit::type const_int_star = int_type.get_const ().get_pointer ();
@@ -12792,12 +12807,12 @@ by creating structures (see below).
@end menu
@node Standard types<2>,Pointers const and volatile<2>,,Types<2>
-@anchor{cp/topics/types standard-types}@anchor{150}
+@anchor{cp/topics/types standard-types}@anchor{151}
@subsubsection Standard types
@geindex gccjit;;context;;get_type (C++ function)
-@anchor{cp/topics/types gccjit context get_type__enum}@anchor{108}
+@anchor{cp/topics/types gccjit context get_type__enum}@anchor{109}
@deffn {C++ Function} gccjit::type gccjit::context::get_type (enum gcc_jit_types)
Access a specific type. This is a thin wrapper around
@@ -12805,14 +12820,14 @@ Access a specific type. This is a thin wrapper around
@end deffn
@geindex gccjit;;context;;get_int_type (C++ function)
-@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{151}
+@anchor{cp/topics/types gccjit context get_int_type__s i}@anchor{152}
@deffn {C++ Function} gccjit::type gccjit::context::get_int_type (size_t num_bytes, int is_signed)
Access the integer type of the given size.
@end deffn
@geindex gccjit;;context;;get_int_type<T> (C++ function)
-@anchor{cp/topics/types gccjit context get_int_type T}@anchor{152}
+@anchor{cp/topics/types gccjit context get_int_type T}@anchor{153}
@deffn {C++ Function} gccjit::type gccjit::context::get_int_type<T> ()
Access the given integer type. For example, you could map the
@@ -12826,12 +12841,12 @@ gccjit::type t = ctxt.get_int_type <unsigned short> ();
@end deffn
@node Pointers const and volatile<2>,Structures and unions<2>,Standard types<2>,Types<2>
-@anchor{cp/topics/types pointers-const-and-volatile}@anchor{153}
+@anchor{cp/topics/types pointers-const-and-volatile}@anchor{154}
@subsubsection Pointers, @cite{const}, and @cite{volatile}
@geindex gccjit;;type;;get_pointer (C++ function)
-@anchor{cp/topics/types gccjit type get_pointer}@anchor{14e}
+@anchor{cp/topics/types gccjit type get_pointer}@anchor{14f}
@deffn {C++ Function} gccjit::type gccjit::type::get_pointer ()
Given type "T", get type "T*".
@@ -12840,21 +12855,21 @@ Given type "T", get type "T*".
@c FIXME: get_const doesn't seem to exist
@geindex gccjit;;type;;get_const (C++ function)
-@anchor{cp/topics/types gccjit type get_const}@anchor{14f}
+@anchor{cp/topics/types gccjit type get_const}@anchor{150}
@deffn {C++ Function} gccjit::type gccjit::type::get_const ()
Given type "T", get type "const T".
@end deffn
@geindex gccjit;;type;;get_volatile (C++ function)
-@anchor{cp/topics/types gccjit type get_volatile}@anchor{154}
+@anchor{cp/topics/types gccjit type get_volatile}@anchor{155}
@deffn {C++ Function} gccjit::type gccjit::type::get_volatile ()
Given type "T", get type "volatile T".
@end deffn
@geindex gccjit;;context;;new_array_type (C++ function)
-@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{155}
+@anchor{cp/topics/types gccjit context new_array_type__gccjit type i gccjit location}@anchor{156}
@deffn {C++ Function} gccjit::type gccjit::context::new_array_type (gccjit::type element_type, int num_elements, gccjit::location loc)
Given type "T", get type "T[N]" (for a constant N).
@@ -12862,31 +12877,31 @@ Param "loc" is optional.
@end deffn
@node Structures and unions<2>,,Pointers const and volatile<2>,Types<2>
-@anchor{cp/topics/types structures-and-unions}@anchor{156}
+@anchor{cp/topics/types structures-and-unions}@anchor{157}
@subsubsection Structures and unions
@geindex gccjit;;struct_ (C++ class)
-@anchor{cp/topics/types gccjit struct_}@anchor{157}
+@anchor{cp/topics/types gccjit struct_}@anchor{158}
@deffn {C++ Class} gccjit::struct_
@end deffn
A compound type analagous to a C @cite{struct}.
-@pxref{157,,gccjit;;struct_} is a subclass of @pxref{14d,,gccjit;;type} (and thus
-of @pxref{149,,gccjit;;object} in turn).
+@pxref{158,,gccjit;;struct_} is a subclass of @pxref{14e,,gccjit;;type} (and thus
+of @pxref{14a,,gccjit;;object} in turn).
@geindex gccjit;;field (C++ class)
-@anchor{cp/topics/types gccjit field}@anchor{158}
+@anchor{cp/topics/types gccjit field}@anchor{159}
@deffn {C++ Class} gccjit::field
@end deffn
-A field within a @pxref{157,,gccjit;;struct_}.
+A field within a @pxref{158,,gccjit;;struct_}.
-@pxref{158,,gccjit;;field} is a subclass of @pxref{149,,gccjit;;object}.
+@pxref{159,,gccjit;;field} is a subclass of @pxref{14a,,gccjit;;object}.
-You can model C @cite{struct} types by creating @pxref{157,,gccjit;;struct_} and
-@pxref{158,,gccjit;;field} instances, in either order:
+You can model C @cite{struct} types by creating @pxref{158,,gccjit;;struct_} and
+@pxref{159,,gccjit;;field} instances, in either order:
@itemize *
@@ -12942,14 +12957,14 @@ node.set_fields (fields);
@c FIXME: the above API doesn't seem to exist yet
@geindex gccjit;;context;;new_field (C++ function)
-@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{159}
+@anchor{cp/topics/types gccjit context new_field__gccjit type cCP gccjit location}@anchor{15a}
@deffn {C++ Function} gccjit::field gccjit::context::new_field (gccjit::type type, const char* name, gccjit::location loc)
Construct a new field, with the given type and name.
@end deffn
@geindex gccjit;;context;;new_struct_type (C++ function)
-@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{15a}
+@anchor{cp/topics/types gccjit context new_struct_type__ssCR std vector field R gccjit location}@anchor{15b}
@deffn {C++ Function} gccjit::struct_ gccjit::context::new_struct_type (const std::string& name, std::vector<field>& fields, gccjit::location loc)
@quotation
@@ -12959,7 +12974,7 @@ Construct a new struct type, with the given name and fields.
@end deffn
@geindex gccjit;;context;;new_opaque_struct (C++ function)
-@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{15b}
+@anchor{cp/topics/types gccjit context new_opaque_struct__ssCR gccjit location}@anchor{15c}
@deffn {C++ Function} gccjit::struct_ gccjit::context::new_opaque_struct (const std::string& name, gccjit::location loc)
Construct a new struct type, with the given name, but without
@@ -12986,7 +13001,7 @@ size of the struct is not known), or later specified using
@c <http://www.gnu.org/licenses/>.
@node Expressions<2>,Creating and using functions<2>,Types<2>,Topic Reference<2>
-@anchor{cp/topics/expressions expressions}@anchor{15c}@anchor{cp/topics/expressions doc}@anchor{15d}
+@anchor{cp/topics/expressions expressions}@anchor{15d}@anchor{cp/topics/expressions doc}@anchor{15e}
@subsection Expressions
@@ -13012,17 +13027,17 @@ Lvalues
@node Rvalues<2>,Lvalues<2>,,Expressions<2>
-@anchor{cp/topics/expressions rvalues}@anchor{15e}
+@anchor{cp/topics/expressions rvalues}@anchor{15f}
@subsubsection Rvalues
@geindex gccjit;;rvalue (C++ class)
-@anchor{cp/topics/expressions gccjit rvalue}@anchor{15f}
+@anchor{cp/topics/expressions gccjit rvalue}@anchor{160}
@deffn {C++ Class} gccjit::rvalue
@end deffn
-A @pxref{15f,,gccjit;;rvalue} is an expression that can be computed. It is a
-subclass of @pxref{149,,gccjit;;object}, and is a thin wrapper around
+A @pxref{160,,gccjit;;rvalue} is an expression that can be computed. It is a
+subclass of @pxref{14a,,gccjit;;object}, and is a thin wrapper around
@pxref{13,,gcc_jit_rvalue *} from the C API.
It can be simple, e.g.:
@@ -13068,7 +13083,7 @@ Every rvalue has an associated type, and the API will check to ensure
that types match up correctly (otherwise the context will emit an error).
@geindex gccjit;;rvalue;;get_type (C++ function)
-@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{160}
+@anchor{cp/topics/expressions gccjit rvalue get_type}@anchor{161}
@deffn {C++ Function} gccjit::type gccjit::rvalue::get_type ()
Get the type of this rvalue.
@@ -13085,12 +13100,12 @@ Get the type of this rvalue.
@end menu
@node Simple expressions<2>,Unary Operations<2>,,Rvalues<2>
-@anchor{cp/topics/expressions simple-expressions}@anchor{161}
+@anchor{cp/topics/expressions simple-expressions}@anchor{162}
@subsubsection Simple expressions
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{11c}
+@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type iC}@anchor{11d}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, int value) const
Given a numeric type (integer or floating point), build an rvalue for
@@ -13098,7 +13113,7 @@ the given constant @code{int} value.
@end deffn
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{162}
+@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type lC}@anchor{163}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, long value) const
Given a numeric type (integer or floating point), build an rvalue for
@@ -13106,7 +13121,7 @@ the given constant @code{long} value.
@end deffn
@geindex gccjit;;context;;zero (C++ function)
-@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{118}
+@anchor{cp/topics/expressions gccjit context zero__gccjit typeC}@anchor{119}
@deffn {C++ Function} gccjit::rvalue gccjit::context::zero (gccjit::type numeric_type) const
Given a numeric type (integer or floating point), get the rvalue for
@@ -13120,7 +13135,7 @@ ctxt.new_rvalue (numeric_type, 0)
@end deffn
@geindex gccjit;;context;;one (C++ function)
-@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{163}
+@anchor{cp/topics/expressions gccjit context one__gccjit typeC}@anchor{164}
@deffn {C++ Function} gccjit::rvalue gccjit::context::one (gccjit::type numeric_type) const
Given a numeric type (integer or floating point), get the rvalue for
@@ -13134,7 +13149,7 @@ ctxt.new_rvalue (numeric_type, 1)
@end deffn
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{164}
+@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type doubleC}@anchor{165}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type numeric_type, double value) const
Given a numeric type (integer or floating point), build an rvalue for
@@ -13142,14 +13157,14 @@ the given constant @code{double} value.
@end deffn
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{165}
+@anchor{cp/topics/expressions gccjit context new_rvalue__gccjit type voidPC}@anchor{166}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (gccjit::type pointer_type, void* value) const
Given a pointer type, build an rvalue for the given address.
@end deffn
@geindex gccjit;;context;;new_rvalue (C++ function)
-@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{166}
+@anchor{cp/topics/expressions gccjit context new_rvalue__ssCRC}@anchor{167}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_rvalue (const std::string& value) const
Generate an rvalue of type @code{GCC_JIT_TYPE_CONST_CHAR_PTR} for
@@ -13157,12 +13172,12 @@ the given string. This is akin to a string literal.
@end deffn
@node Unary Operations<2>,Binary Operations<2>,Simple expressions<2>,Rvalues<2>
-@anchor{cp/topics/expressions unary-operations}@anchor{167}
+@anchor{cp/topics/expressions unary-operations}@anchor{168}
@subsubsection Unary Operations
@geindex gccjit;;context;;new_unary_op (C++ function)
-@anchor{cp/topics/expressions gccjit context new_unary_op__enum gccjit type gccjit rvalue gccjit location}@anchor{168}
+@anchor{cp/topics/expressions gccjit context new_unary_op__enum gccjit type gccjit rvalue gccjit location}@anchor{169}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_unary_op (enum gcc_jit_unary_op, gccjit::type result_type, gccjit::rvalue rvalue, gccjit::location loc)
Build a unary operation out of an input rvalue.
@@ -13178,7 +13193,7 @@ There are shorter ways to spell the various specific kinds of unary
operation:
@geindex gccjit;;context;;new_minus (C++ function)
-@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{169}
+@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit location}@anchor{16a}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
Negate an arithmetic value; for example:
@@ -13199,7 +13214,7 @@ builds the equivalent of this C expression:
@end deffn
@geindex new_bitwise_negate (C++ function)
-@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{16a}
+@anchor{cp/topics/expressions new_bitwise_negate__gccjit type gccjit rvalue gccjit location}@anchor{16b}
@deffn {C++ Function} gccjit::rvalue new_bitwise_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
Bitwise negation of an integer value (one's complement); for example:
@@ -13220,7 +13235,7 @@ builds the equivalent of this C expression:
@end deffn
@geindex new_logical_negate (C++ function)
-@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{16b}
+@anchor{cp/topics/expressions new_logical_negate__gccjit type gccjit rvalue gccjit location}@anchor{16c}
@deffn {C++ Function} gccjit::rvalue new_logical_negate (gccjit::type result_type, gccjit::rvalue a, gccjit::location loc)
Logical negation of an arithmetic or pointer value; for example:
@@ -13243,7 +13258,7 @@ builds the equivalent of this C expression:
The most concise way to spell them is with overloaded operators:
@geindex operator- (C++ function)
-@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{16c}
+@anchor{cp/topics/expressions sub-operator__gccjit rvalue}@anchor{16d}
@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a)
@example
@@ -13254,7 +13269,7 @@ gccjit::rvalue negpi = -pi;
@end deffn
@geindex operator~ (C++ function)
-@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{16d}
+@anchor{cp/topics/expressions inv-operator__gccjit rvalue}@anchor{16e}
@deffn {C++ Function} gccjit::rvalue operator~ (gccjit::rvalue a)
@example
@@ -13265,7 +13280,7 @@ gccjit::rvalue mask = ~a;
@end deffn
@geindex operator! (C++ function)
-@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{16e}
+@anchor{cp/topics/expressions not-operator__gccjit rvalue}@anchor{16f}
@deffn {C++ Function} gccjit::rvalue operator! (gccjit::rvalue a)
@example
@@ -13276,12 +13291,12 @@ gccjit::rvalue guard = !cond;
@end deffn
@node Binary Operations<2>,Comparisons<2>,Unary Operations<2>,Rvalues<2>
-@anchor{cp/topics/expressions binary-operations}@anchor{16f}
+@anchor{cp/topics/expressions binary-operations}@anchor{170}
@subsubsection Binary Operations
@geindex gccjit;;context;;new_binary_op (C++ function)
-@anchor{cp/topics/expressions gccjit context new_binary_op__enum gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{10c}
+@anchor{cp/topics/expressions gccjit context new_binary_op__enum gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{10d}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_binary_op (enum gcc_jit_binary_op, gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
Build a binary operation out of two constituent rvalues.
@@ -13297,59 +13312,59 @@ There are shorter ways to spell the various specific kinds of binary
operation:
@geindex gccjit;;context;;new_plus (C++ function)
-@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{170}
+@anchor{cp/topics/expressions gccjit context new_plus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{171}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_plus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_minus (C++ function)
-@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{171}
+@anchor{cp/topics/expressions gccjit context new_minus__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{172}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_minus (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_mult (C++ function)
-@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{172}
+@anchor{cp/topics/expressions gccjit context new_mult__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{173}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_mult (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_divide (C++ function)
-@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{173}
+@anchor{cp/topics/expressions gccjit context new_divide__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{174}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_divide (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_modulo (C++ function)
-@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{174}
+@anchor{cp/topics/expressions gccjit context new_modulo__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{175}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_modulo (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_bitwise_and (C++ function)
-@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{175}
+@anchor{cp/topics/expressions gccjit context new_bitwise_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{176}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_bitwise_xor (C++ function)
-@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{176}
+@anchor{cp/topics/expressions gccjit context new_bitwise_xor__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{177}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_xor (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_bitwise_or (C++ function)
-@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{177}
+@anchor{cp/topics/expressions gccjit context new_bitwise_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{178}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_bitwise_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_logical_and (C++ function)
-@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{178}
+@anchor{cp/topics/expressions gccjit context new_logical_and__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{179}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_and (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_logical_or (C++ function)
-@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{179}
+@anchor{cp/topics/expressions gccjit context new_logical_or__gccjit type gccjit rvalue gccjit rvalue gccjit location}@anchor{17a}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_logical_or (gccjit::type result_type, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
The most concise way to spell them is with overloaded operators:
@geindex operator+ (C++ function)
-@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{17a}
+@anchor{cp/topics/expressions add-operator__gccjit rvalue gccjit rvalue}@anchor{17b}
@deffn {C++ Function} gccjit::rvalue operator+ (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13360,7 +13375,7 @@ gccjit::rvalue sum = a + b;
@end deffn
@geindex operator- (C++ function)
-@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{17b}
+@anchor{cp/topics/expressions sub-operator__gccjit rvalue gccjit rvalue}@anchor{17c}
@deffn {C++ Function} gccjit::rvalue operator- (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13371,7 +13386,7 @@ gccjit::rvalue diff = a - b;
@end deffn
@geindex operator* (C++ function)
-@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{17c}
+@anchor{cp/topics/expressions mul-operator__gccjit rvalue gccjit rvalue}@anchor{17d}
@deffn {C++ Function} gccjit::rvalue operator* (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13382,7 +13397,7 @@ gccjit::rvalue prod = a * b;
@end deffn
@geindex operator/ (C++ function)
-@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{17d}
+@anchor{cp/topics/expressions div-operator__gccjit rvalue gccjit rvalue}@anchor{17e}
@deffn {C++ Function} gccjit::rvalue operator/ (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13393,7 +13408,7 @@ gccjit::rvalue result = a / b;
@end deffn
@geindex operator% (C++ function)
-@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{17e}
+@anchor{cp/topics/expressions mod-operator__gccjit rvalue gccjit rvalue}@anchor{17f}
@deffn {C++ Function} gccjit::rvalue operator% (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13404,7 +13419,7 @@ gccjit::rvalue mod = a % b;
@end deffn
@geindex operator& (C++ function)
-@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{17f}
+@anchor{cp/topics/expressions and-operator__gccjit rvalue gccjit rvalue}@anchor{180}
@deffn {C++ Function} gccjit::rvalue operator& (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13415,7 +13430,7 @@ gccjit::rvalue x = a & b;
@end deffn
@geindex operator^ (C++ function)
-@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{180}
+@anchor{cp/topics/expressions xor-operator__gccjit rvalue gccjit rvalue}@anchor{181}
@deffn {C++ Function} gccjit::rvalue operator^ (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13426,7 +13441,7 @@ gccjit::rvalue x = a ^ b;
@end deffn
@geindex operator| (C++ function)
-@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{181}
+@anchor{cp/topics/expressions or-operator__gccjit rvalue gccjit rvalue}@anchor{182}
@deffn {C++ Function} gccjit::rvalue operator| (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13437,7 +13452,7 @@ gccjit::rvalue x = a | b;
@end deffn
@geindex operator&& (C++ function)
-@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{182}
+@anchor{cp/topics/expressions sand-operator__gccjit rvalue gccjit rvalue}@anchor{183}
@deffn {C++ Function} gccjit::rvalue operator&& (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13448,7 +13463,7 @@ gccjit::rvalue cond = a && b;
@end deffn
@geindex operator|| (C++ function)
-@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{183}
+@anchor{cp/topics/expressions sor-operator__gccjit rvalue gccjit rvalue}@anchor{184}
@deffn {C++ Function} gccjit::rvalue operator|| (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13471,12 +13486,12 @@ gccjit::rvalue discriminant = (b * b) - (four * a * c);
@end quotation
@node Comparisons<2>,Function calls<2>,Binary Operations<2>,Rvalues<2>
-@anchor{cp/topics/expressions comparisons}@anchor{184}
+@anchor{cp/topics/expressions comparisons}@anchor{185}
@subsubsection Comparisons
@geindex gccjit;;context;;new_comparison (C++ function)
-@anchor{cp/topics/expressions gccjit context new_comparison__enum gccjit rvalue gccjit rvalue gccjit location}@anchor{119}
+@anchor{cp/topics/expressions gccjit context new_comparison__enum gccjit rvalue gccjit rvalue gccjit location}@anchor{11a}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_comparison (enum gcc_jit_comparison, gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
Build a boolean rvalue out of the comparison of two other rvalues.
@@ -13492,39 +13507,39 @@ There are shorter ways to spell the various specific kinds of binary
operation:
@geindex gccjit;;context;;new_eq (C++ function)
-@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{185}
+@anchor{cp/topics/expressions gccjit context new_eq__gccjit rvalue gccjit rvalue gccjit location}@anchor{186}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_eq (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_ne (C++ function)
-@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{186}
+@anchor{cp/topics/expressions gccjit context new_ne__gccjit rvalue gccjit rvalue gccjit location}@anchor{187}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ne (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_lt (C++ function)
-@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{187}
+@anchor{cp/topics/expressions gccjit context new_lt__gccjit rvalue gccjit rvalue gccjit location}@anchor{188}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_lt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_le (C++ function)
-@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{188}
+@anchor{cp/topics/expressions gccjit context new_le__gccjit rvalue gccjit rvalue gccjit location}@anchor{189}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_le (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_gt (C++ function)
-@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{189}
+@anchor{cp/topics/expressions gccjit context new_gt__gccjit rvalue gccjit rvalue gccjit location}@anchor{18a}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_gt (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
@geindex gccjit;;context;;new_ge (C++ function)
-@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{18a}
+@anchor{cp/topics/expressions gccjit context new_ge__gccjit rvalue gccjit rvalue gccjit location}@anchor{18b}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_ge (gccjit::rvalue a, gccjit::rvalue b, gccjit::location loc)
@end deffn
The most concise way to spell them is with overloaded operators:
@geindex operator== (C++ function)
-@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{18b}
+@anchor{cp/topics/expressions eq-operator__gccjit rvalue gccjit rvalue}@anchor{18c}
@deffn {C++ Function} gccjit::rvalue operator== (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13535,7 +13550,7 @@ gccjit::rvalue cond = (a == ctxt.zero (t_int));
@end deffn
@geindex operator!= (C++ function)
-@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{18c}
+@anchor{cp/topics/expressions neq-operator__gccjit rvalue gccjit rvalue}@anchor{18d}
@deffn {C++ Function} gccjit::rvalue operator!= (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13546,7 +13561,7 @@ gccjit::rvalue cond = (i != j);
@end deffn
@geindex operator< (C++ function)
-@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{18d}
+@anchor{cp/topics/expressions lt-operator__gccjit rvalue gccjit rvalue}@anchor{18e}
@deffn {C++ Function} gccjit::rvalue operator< (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13557,7 +13572,7 @@ gccjit::rvalue cond = i < n;
@end deffn
@geindex operator<= (C++ function)
-@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{18e}
+@anchor{cp/topics/expressions lte-operator__gccjit rvalue gccjit rvalue}@anchor{18f}
@deffn {C++ Function} gccjit::rvalue operator<= (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13568,7 +13583,7 @@ gccjit::rvalue cond = i <= n;
@end deffn
@geindex operator> (C++ function)
-@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{18f}
+@anchor{cp/topics/expressions gt-operator__gccjit rvalue gccjit rvalue}@anchor{190}
@deffn {C++ Function} gccjit::rvalue operator> (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13579,7 +13594,7 @@ gccjit::rvalue cond = (ch > limit);
@end deffn
@geindex operator>= (C++ function)
-@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{190}
+@anchor{cp/topics/expressions gte-operator__gccjit rvalue gccjit rvalue}@anchor{191}
@deffn {C++ Function} gccjit::rvalue operator>= (gccjit::rvalue a, gccjit::rvalue b)
@example
@@ -13592,12 +13607,12 @@ gccjit::rvalue cond = (score >= ctxt.new_rvalue (t_int, 100));
@c TODO: beyond this point
@node Function calls<2>,Type-coercion<2>,Comparisons<2>,Rvalues<2>
-@anchor{cp/topics/expressions function-calls}@anchor{191}
+@anchor{cp/topics/expressions function-calls}@anchor{192}
@subsubsection Function calls
@geindex gcc_jit_context_new_call (C++ function)
-@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{192}
+@anchor{cp/topics/expressions gcc_jit_context_new_call__gcc_jit_contextP gcc_jit_locationP gcc_jit_functionP i gcc_jit_rvaluePP}@anchor{193}
@deffn {C++ Function} gcc_jit_rvalue* gcc_jit_context_new_call (gcc_jit_context* ctxt, gcc_jit_location* loc, gcc_jit_function* func, int numargs, gcc_jit_rvalue** args)
Given a function and the given table of argument rvalues, construct a
@@ -13606,14 +13621,14 @@ call to the function, with the result as an rvalue.
@cartouche
@quotation Note
@code{gccjit::context::new_call()} merely builds a
-@pxref{15f,,gccjit;;rvalue} i.e. an expression that can be evaluated,
+@pxref{160,,gccjit;;rvalue} i.e. an expression that can be evaluated,
perhaps as part of a more complicated expression.
The call @emph{won't} happen unless you add a statement to a function
that evaluates the expression.
For example, if you want to call a function and discard the result
(or to call a function with @code{void} return type), use
-@pxref{193,,gccjit;;block;;add_eval()}:
+@pxref{194,,gccjit;;block;;add_eval()}:
@example
/* Add "(void)printf (arg0, arg1);". */
@@ -13626,12 +13641,12 @@ block.add_eval (ctxt.new_call (printf_func, arg0, arg1));
@end deffn
@node Type-coercion<2>,,Function calls<2>,Rvalues<2>
-@anchor{cp/topics/expressions type-coercion}@anchor{194}
+@anchor{cp/topics/expressions type-coercion}@anchor{195}
@subsubsection Type-coercion
@geindex gccjit;;context;;new_cast (C++ function)
-@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{195}
+@anchor{cp/topics/expressions gccjit context new_cast__gccjit rvalue gccjit type gccjit location}@anchor{196}
@deffn {C++ Function} gccjit::rvalue gccjit::context::new_cast (gccjit::rvalue rvalue, gccjit::type type, gccjit::location loc)
Given an rvalue of T, construct another rvalue of another type.
@@ -13656,24 +13671,24 @@ P* <-> Q*, for pointer types P and Q
@end deffn
@node Lvalues<2>,Working with pointers structs and unions<2>,Rvalues<2>,Expressions<2>
-@anchor{cp/topics/expressions lvalues}@anchor{196}
+@anchor{cp/topics/expressions lvalues}@anchor{197}
@subsubsection Lvalues
@geindex gccjit;;lvalue (C++ class)
-@anchor{cp/topics/expressions gccjit lvalue}@anchor{197}
+@anchor{cp/topics/expressions gccjit lvalue}@anchor{198}
@deffn {C++ Class} gccjit::lvalue
@end deffn
An lvalue is something that can of the @emph{left}-hand side of an assignment:
a storage area (such as a variable). It is a subclass of
-@pxref{15f,,gccjit;;rvalue}, where the rvalue is computed by reading from the
+@pxref{160,,gccjit;;rvalue}, where the rvalue is computed by reading from the
storage area.
It iss a thin wrapper around @pxref{24,,gcc_jit_lvalue *} from the C API.
@geindex gccjit;;lvalue;;get_address (C++ function)
-@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{198}
+@anchor{cp/topics/expressions gccjit lvalue get_address__gccjit location}@anchor{199}
@deffn {C++ Function} gccjit::rvalue gccjit::lvalue::get_address (gccjit::location loc)
Take the address of an lvalue; analogous to:
@@ -13695,27 +13710,27 @@ Parameter "loc" is optional.
@end menu
@node Global variables<2>,,,Lvalues<2>
-@anchor{cp/topics/expressions global-variables}@anchor{199}
+@anchor{cp/topics/expressions global-variables}@anchor{19a}
@subsubsection Global variables
@geindex gccjit;;context;;new_global (C++ function)
-@anchor{cp/topics/expressions gccjit context new_global__enum gccjit type cCP gccjit location}@anchor{19a}
+@anchor{cp/topics/expressions gccjit context new_global__enum gccjit type cCP gccjit location}@anchor{19b}
@deffn {C++ Function} gccjit::lvalue gccjit::context::new_global (enum gcc_jit_global_kind, gccjit::type type, const char* name, gccjit::location loc)
Add a new global variable of the given type and name to the context.
-This is a thin wrapper around @pxref{b5,,gcc_jit_context_new_global()} from
+This is a thin wrapper around @pxref{b6,,gcc_jit_context_new_global()} from
the C API; the "kind" parameter has the same meaning as there.
@end deffn
@node Working with pointers structs and unions<2>,,Lvalues<2>,Expressions<2>
-@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{19b}
+@anchor{cp/topics/expressions working-with-pointers-structs-and-unions}@anchor{19c}
@subsubsection Working with pointers, structs and unions
@geindex gccjit;;rvalue;;dereference (C++ function)
-@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{19c}
+@anchor{cp/topics/expressions gccjit rvalue dereference__gccjit location}@anchor{19d}
@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference (gccjit::location loc)
Given an rvalue of pointer type @code{T *}, dereferencing the pointer,
@@ -13736,7 +13751,7 @@ If you don't need to specify the location, this can also be expressed using
an overloaded operator:
@geindex gccjit;;rvalue;;operator* (C++ function)
-@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{19d}
+@anchor{cp/topics/expressions gccjit rvalue mul-operator}@anchor{19e}
@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::operator* ()
@example
@@ -13749,7 +13764,7 @@ gccjit::lvalue content = *ptr;
Field access is provided separately for both lvalues and rvalues:
@geindex gccjit;;lvalue;;access_field (C++ function)
-@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{19e}
+@anchor{cp/topics/expressions gccjit lvalue access_field__gccjit field gccjit location}@anchor{19f}
@deffn {C++ Function} gccjit::lvalue gccjit::lvalue::access_field (gccjit::field field, gccjit::location loc)
Given an lvalue of struct or union type, access the given field,
@@ -13765,7 +13780,7 @@ in C.
@end deffn
@geindex gccjit;;rvalue;;access_field (C++ function)
-@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{19f}
+@anchor{cp/topics/expressions gccjit rvalue access_field__gccjit field gccjit location}@anchor{1a0}
@deffn {C++ Function} gccjit::rvalue gccjit::rvalue::access_field (gccjit::field field, gccjit::location loc)
Given an rvalue of struct or union type, access the given field
@@ -13781,7 +13796,7 @@ in C.
@end deffn
@geindex gccjit;;rvalue;;dereference_field (C++ function)
-@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{1a0}
+@anchor{cp/topics/expressions gccjit rvalue dereference_field__gccjit field gccjit location}@anchor{1a1}
@deffn {C++ Function} gccjit::lvalue gccjit::rvalue::dereference_field (gccjit::field field, gccjit::location loc)
Given an rvalue of pointer type @code{T *} where T is of struct or union
@@ -13797,7 +13812,7 @@ in C, itself equivalent to @code{(*EXPR).FIELD}.
@end deffn
@geindex gccjit;;context;;new_array_access (C++ function)
-@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a1}
+@anchor{cp/topics/expressions gccjit context new_array_access__gccjit rvalue gccjit rvalue gccjit location}@anchor{1a2}
@deffn {C++ Function} gccjit::lvalue gccjit::context::new_array_access (gccjit::rvalue ptr, gccjit::rvalue index, gccjit::location loc)
Given an rvalue of pointer type @code{T *}, get at the element @cite{T} at
@@ -13816,7 +13831,7 @@ in C (or, indeed, to @code{PTR + INDEX}).
Parameter "loc" is optional.
@end deffn
-For array accesses where you don't need to specify a @pxref{13c,,gccjit;;location},
+For array accesses where you don't need to specify a @pxref{13d,,gccjit;;location},
two overloaded operators are available:
@quotation
@@ -13856,7 +13871,7 @@ gccjit::lvalue element = array[0];
@c <http://www.gnu.org/licenses/>.
@node Creating and using functions<2>,Source Locations<2>,Expressions<2>,Topic Reference<2>
-@anchor{cp/topics/functions doc}@anchor{1a2}@anchor{cp/topics/functions creating-and-using-functions}@anchor{1a3}
+@anchor{cp/topics/functions doc}@anchor{1a3}@anchor{cp/topics/functions creating-and-using-functions}@anchor{1a4}
@subsection Creating and using functions
@@ -13869,36 +13884,36 @@ gccjit::lvalue element = array[0];
@end menu
@node Params<2>,Functions<2>,,Creating and using functions<2>
-@anchor{cp/topics/functions params}@anchor{1a4}
+@anchor{cp/topics/functions params}@anchor{1a5}
@subsubsection Params
@geindex gccjit;;param (C++ class)
-@anchor{cp/topics/functions gccjit param}@anchor{1a5}
+@anchor{cp/topics/functions gccjit param}@anchor{1a6}
@deffn {C++ Class} gccjit::param
A @cite{gccjit::param} represents a parameter to a function.
@end deffn
@geindex gccjit;;context;;new_param (C++ function)
-@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{10b}
+@anchor{cp/topics/functions gccjit context new_param__gccjit type cCP gccjit location}@anchor{10c}
@deffn {C++ Function} gccjit::param gccjit::context::new_param (gccjit::type type, const char* name, gccjit::location loc)
In preparation for creating a function, create a new parameter of the
given type and name.
@end deffn
-@pxref{1a5,,gccjit;;param} is a subclass of @pxref{197,,gccjit;;lvalue} (and thus
-of @pxref{15f,,gccjit;;rvalue} and @pxref{149,,gccjit;;object}). It is a thin
+@pxref{1a6,,gccjit;;param} is a subclass of @pxref{198,,gccjit;;lvalue} (and thus
+of @pxref{160,,gccjit;;rvalue} and @pxref{14a,,gccjit;;object}). It is a thin
wrapper around the C API's @pxref{25,,gcc_jit_param *}.
@node Functions<2>,Blocks<2>,Params<2>,Creating and using functions<2>
-@anchor{cp/topics/functions functions}@anchor{1a6}
+@anchor{cp/topics/functions functions}@anchor{1a7}
@subsubsection Functions
@geindex gccjit;;function (C++ class)
-@anchor{cp/topics/functions gccjit function}@anchor{1a7}
+@anchor{cp/topics/functions gccjit function}@anchor{1a8}
@deffn {C++ Class} gccjit::function
A @cite{gccjit::function} represents a function - either one that we're
@@ -13906,7 +13921,7 @@ creating ourselves, or one that we're referencing.
@end deffn
@geindex gccjit;;context;;new_function (C++ function)
-@anchor{cp/topics/functions gccjit context new_function__enum gccjit type cCP std vector param R i gccjit location}@anchor{1a8}
+@anchor{cp/topics/functions gccjit context new_function__enum gccjit type cCP std vector param R i gccjit location}@anchor{1a9}
@deffn {C++ Function} gccjit::function gccjit::context::new_function (enum gcc_jit_function_kind, gccjit::type return_type, const char* name, std::vector<param>& params, int is_variadic, gccjit::location loc)
Create a gcc_jit_function with the given name and parameters.
@@ -13917,29 +13932,29 @@ This is a wrapper around the C API's @pxref{11,,gcc_jit_context_new_function()}.
@end deffn
@geindex gccjit;;context;;get_builtin_function (C++ function)
-@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{1a9}
+@anchor{cp/topics/functions gccjit context get_builtin_function__cCP}@anchor{1aa}
@deffn {C++ Function} gccjit::function gccjit::context::get_builtin_function (const char* name)
This is a wrapper around the C API's
-@pxref{cc,,gcc_jit_context_get_builtin_function()}.
+@pxref{cd,,gcc_jit_context_get_builtin_function()}.
@end deffn
@geindex gccjit;;function;;get_param (C++ function)
-@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{1aa}
+@anchor{cp/topics/functions gccjit function get_param__iC}@anchor{1ab}
@deffn {C++ Function} gccjit::param gccjit::function::get_param (int index) const
Get the param of the given index (0-based).
@end deffn
@geindex gccjit;;function;;dump_to_dot (C++ function)
-@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{11e}
+@anchor{cp/topics/functions gccjit function dump_to_dot__cCP}@anchor{11f}
@deffn {C++ Function} void gccjit::function::dump_to_dot (const char* path)
Emit the function in graphviz format to the given path.
@end deffn
@geindex gccjit;;function;;new_local (C++ function)
-@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{115}
+@anchor{cp/topics/functions gccjit function new_local__gccjit type cCP gccjit location}@anchor{116}
@deffn {C++ Function} gccjit::lvalue gccjit::function::new_local (gccjit::type type, const char* name, gccjit::location loc)
Create a new local variable within the function, of the given type and
@@ -13947,19 +13962,19 @@ name.
@end deffn
@node Blocks<2>,Statements<2>,Functions<2>,Creating and using functions<2>
-@anchor{cp/topics/functions blocks}@anchor{1ab}
+@anchor{cp/topics/functions blocks}@anchor{1ac}
@subsubsection Blocks
@geindex gccjit;;block (C++ class)
-@anchor{cp/topics/functions gccjit block}@anchor{1ac}
+@anchor{cp/topics/functions gccjit block}@anchor{1ad}
@deffn {C++ Class} gccjit::block
A @cite{gccjit::block} represents a basic block within a function i.e. a
sequence of statements with a single entry point and a single exit
point.
-@pxref{1ac,,gccjit;;block} is a subclass of @pxref{149,,gccjit;;object}.
+@pxref{1ad,,gccjit;;block} is a subclass of @pxref{14a,,gccjit;;object}.
The first basic block that you create within a function will
be the entrypoint.
@@ -13973,7 +13988,7 @@ one function.
@end deffn
@geindex gccjit;;function;;new_block (C++ function)
-@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{1ad}
+@anchor{cp/topics/functions gccjit function new_block__cCP}@anchor{1ae}
@deffn {C++ Function} gccjit::block gccjit::function::new_block (const char* name)
Create a basic block of the given name. The name may be NULL, but
@@ -13983,12 +13998,12 @@ messages.
@end deffn
@node Statements<2>,,Blocks<2>,Creating and using functions<2>
-@anchor{cp/topics/functions statements}@anchor{1ae}
+@anchor{cp/topics/functions statements}@anchor{1af}
@subsubsection Statements
@geindex gccjit;;block;;add_eval (C++ function)
-@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{193}
+@anchor{cp/topics/functions gccjit block add_eval__gccjit rvalue gccjit location}@anchor{194}
@deffn {C++ Function} void gccjit::block::add_eval (gccjit::rvalue rvalue, gccjit::location loc)
Add evaluation of an rvalue, discarding the result
@@ -14004,7 +14019,7 @@ This is equivalent to this C code:
@end deffn
@geindex gccjit;;block;;add_assignment (C++ function)
-@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{117}
+@anchor{cp/topics/functions gccjit block add_assignment__gccjit lvalue gccjit rvalue gccjit location}@anchor{118}
@deffn {C++ Function} void gccjit::block::add_assignment (gccjit::lvalue lvalue, gccjit::rvalue rvalue, gccjit::location loc)
Add evaluation of an rvalue, assigning the result to the given
@@ -14020,7 +14035,7 @@ lvalue = rvalue;
@end deffn
@geindex gccjit;;block;;add_assignment_op (C++ function)
-@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue enum gccjit rvalue gccjit location}@anchor{11b}
+@anchor{cp/topics/functions gccjit block add_assignment_op__gccjit lvalue enum gccjit rvalue gccjit location}@anchor{11c}
@deffn {C++ Function} void gccjit::block::add_assignment_op (gccjit::lvalue lvalue, enum gcc_jit_binary_op, gccjit::rvalue rvalue, gccjit::location loc)
Add evaluation of an rvalue, using the result to modify an
@@ -14050,7 +14065,7 @@ loop_body.add_assignment_op (
@end deffn
@geindex gccjit;;block;;add_comment (C++ function)
-@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{126}
+@anchor{cp/topics/functions gccjit block add_comment__cCP gccjit location}@anchor{127}
@deffn {C++ Function} void gccjit::block::add_comment (const char* text, gccjit::location loc)
Add a no-op textual comment to the internal representation of the
@@ -14064,7 +14079,7 @@ Parameter "loc" is optional.
@end deffn
@geindex gccjit;;block;;end_with_conditional (C++ function)
-@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{11a}
+@anchor{cp/topics/functions gccjit block end_with_conditional__gccjit rvalue gccjit block gccjit block gccjit location}@anchor{11b}
@deffn {C++ Function} void gccjit::block::end_with_conditional (gccjit::rvalue boolval, gccjit::block on_true, gccjit::block on_false, gccjit::location loc)
Terminate a block by adding evaluation of an rvalue, branching on the
@@ -14085,7 +14100,7 @@ block, boolval, on_true, and on_false must be non-NULL.
@end deffn
@geindex gccjit;;block;;end_with_jump (C++ function)
-@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{1af}
+@anchor{cp/topics/functions gccjit block end_with_jump__gccjit block gccjit location}@anchor{1b0}
@deffn {C++ Function} void gccjit::block::end_with_jump (gccjit::block target, gccjit::location loc)
Terminate a block by adding a jump to the given target block.
@@ -14100,7 +14115,7 @@ goto target;
@end deffn
@geindex gccjit;;block;;end_with_return (C++ function)
-@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{1b0}
+@anchor{cp/topics/functions gccjit block end_with_return__gccjit rvalue gccjit location}@anchor{1b1}
@deffn {C++ Function} void gccjit::block::end_with_return (gccjit::rvalue rvalue, gccjit::location loc)
Terminate a block.
@@ -14134,7 +14149,7 @@ return;
@end deffn
@geindex gccjit;;block;;end_with_switch (C++ function)
-@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{1b1}
+@anchor{cp/topics/functions gccjit block end_with_switch__gccjit rvalue gccjit block std vector gccjit case_ gccjit location}@anchor{1b2}
@deffn {C++ Function} void gccjit::block::end_with_switch (gccjit::rvalue expr, gccjit::block default_block, std::vector<gccjit::case_> cases, gccjit::location loc)
Terminate a block by adding evalation of an rvalue, then performing
@@ -14177,14 +14192,14 @@ The API entrypoints relating to switch statements and cases:
@itemize *
@item
-@pxref{1b1,,gccjit;;block;;end_with_switch()}
+@pxref{1b2,,gccjit;;block;;end_with_switch()}
@item
-@pxref{1b2,,gccjit;;context;;new_case()}
+@pxref{1b3,,gccjit;;context;;new_case()}
@end itemize
@end quotation
-were added in @pxref{da,,LIBGCCJIT_ABI_3}; you can test for their presence
+were added in @pxref{db,,LIBGCCJIT_ABI_3}; you can test for their presence
using
@example
@@ -14194,21 +14209,21 @@ using
@noindent
@geindex gccjit;;block;;end_with_switch;;gccjit;;case_ (C++ class)
-@anchor{cp/topics/functions gccjit block end_with_switch gccjit case_}@anchor{1b3}
+@anchor{cp/topics/functions gccjit block end_with_switch gccjit case_}@anchor{1b4}
@deffn {C++ Class} gccjit::case_
@end deffn
A @cite{gccjit::case_} represents a case within a switch statement, and
-is created within a particular @pxref{134,,gccjit;;context} using
-@pxref{1b2,,gccjit;;context;;new_case()}. It is a subclass of
-@pxref{149,,gccjit;;object}.
+is created within a particular @pxref{135,,gccjit;;context} using
+@pxref{1b3,,gccjit;;context;;new_case()}. It is a subclass of
+@pxref{14a,,gccjit;;object}.
Each case expresses a multivalued range of integer values. You
can express single-valued cases by passing in the same value for
both @cite{min_value} and @cite{max_value}.
@geindex gccjit;;block;;end_with_switch;;gccjit;;context;;new_case (C++ function)
-@anchor{cp/topics/functions gccjit block end_with_switch gccjit context new_case__gccjit rvalue gccjit rvalue gccjit block}@anchor{1b2}
+@anchor{cp/topics/functions gccjit block end_with_switch gccjit context new_case__gccjit rvalue gccjit rvalue gccjit block}@anchor{1b3}
@deffn {C++ Function} gccjit::case_* gccjit::context::new_case (gccjit::rvalue min_value, gccjit::rvalue max_value, gccjit::block dest_block)
Create a new gccjit::case for use in a switch statement.
@@ -14319,12 +14334,12 @@ create_code (gcc_jit_context *c_ctxt, void *user_data)
@c <http://www.gnu.org/licenses/>.
@node Source Locations<2>,Compiling a context<2>,Creating and using functions<2>,Topic Reference<2>
-@anchor{cp/topics/locations source-locations}@anchor{1b4}@anchor{cp/topics/locations doc}@anchor{1b5}
+@anchor{cp/topics/locations source-locations}@anchor{1b5}@anchor{cp/topics/locations doc}@anchor{1b6}
@subsection Source Locations
@geindex gccjit;;location (C++ class)
-@anchor{cp/topics/locations gccjit location}@anchor{13c}
+@anchor{cp/topics/locations gccjit location}@anchor{13d}
@deffn {C++ Class} gccjit::location
A @cite{gccjit::location} encapsulates a source code location, so that
@@ -14335,10 +14350,10 @@ single-step through your language.
@cite{gccjit::location} instances are optional: you can always omit them
from any C++ API entrypoint accepting one.
-You can construct them using @pxref{12a,,gccjit;;context;;new_location()}.
+You can construct them using @pxref{12b,,gccjit;;context;;new_location()}.
You need to enable @pxref{42,,GCC_JIT_BOOL_OPTION_DEBUGINFO} on the
-@pxref{134,,gccjit;;context} for these locations to actually be usable by
+@pxref{135,,gccjit;;context} for these locations to actually be usable by
the debugger:
@example
@@ -14349,7 +14364,7 @@ ctxt.set_bool_option (GCC_JIT_BOOL_OPTION_DEBUGINFO, 1);
@end deffn
@geindex gccjit;;context;;new_location (C++ function)
-@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{12a}
+@anchor{cp/topics/locations gccjit context new_location__cCP i i}@anchor{12b}
@deffn {C++ Function} gccjit::location gccjit::context::new_location (const char* filename, int line, int column)
Create a @cite{gccjit::location} instance representing the given source
@@ -14362,13 +14377,13 @@ location.
@end menu
@node Faking it<2>,,,Source Locations<2>
-@anchor{cp/topics/locations faking-it}@anchor{1b6}
+@anchor{cp/topics/locations faking-it}@anchor{1b7}
@subsubsection Faking it
If you don't have source code for your internal representation, but need
to debug, you can generate a C-like representation of the functions in
-your context using @pxref{13b,,gccjit;;context;;dump_to_file()}:
+your context using @pxref{13c,,gccjit;;context;;dump_to_file()}:
@example
ctxt.dump_to_file ("/tmp/something.c",
@@ -14400,13 +14415,13 @@ file, giving you @emph{something} you can step through in the debugger.
@c <http://www.gnu.org/licenses/>.
@node Compiling a context<2>,,Source Locations<2>,Topic Reference<2>
-@anchor{cp/topics/compilation compiling-a-context}@anchor{1b7}@anchor{cp/topics/compilation doc}@anchor{1b8}
+@anchor{cp/topics/compilation compiling-a-context}@anchor{1b8}@anchor{cp/topics/compilation doc}@anchor{1b9}
@subsection Compiling a context
-Once populated, a @pxref{134,,gccjit;;context} can be compiled to
-machine code, either in-memory via @pxref{10d,,gccjit;;context;;compile()} or
-to disk via @pxref{1b9,,gccjit;;context;;compile_to_file()}.
+Once populated, a @pxref{135,,gccjit;;context} can be compiled to
+machine code, either in-memory via @pxref{10e,,gccjit;;context;;compile()} or
+to disk via @pxref{1ba,,gccjit;;context;;compile_to_file()}.
You can compile a context multiple times (using either form of
compilation), although any errors that occur on the context will
@@ -14419,12 +14434,12 @@ prevent any future compilation of that context.
@end menu
@node In-memory compilation<2>,Ahead-of-time compilation<2>,,Compiling a context<2>
-@anchor{cp/topics/compilation in-memory-compilation}@anchor{1ba}
+@anchor{cp/topics/compilation in-memory-compilation}@anchor{1bb}
@subsubsection In-memory compilation
@geindex gccjit;;context;;compile (C++ function)
-@anchor{cp/topics/compilation gccjit context compile}@anchor{10d}
+@anchor{cp/topics/compilation gccjit context compile}@anchor{10e}
@deffn {C++ Function} gcc_jit_result* gccjit::context::compile ()
This calls into GCC and builds the code, returning a
@@ -14435,19 +14450,19 @@ This is a thin wrapper around the
@end deffn
@node Ahead-of-time compilation<2>,,In-memory compilation<2>,Compiling a context<2>
-@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{1bb}
+@anchor{cp/topics/compilation ahead-of-time-compilation}@anchor{1bc}
@subsubsection Ahead-of-time compilation
Although libgccjit is primarily aimed at just-in-time compilation, it
can also be used for implementing more traditional ahead-of-time
-compilers, via the @pxref{1b9,,gccjit;;context;;compile_to_file()} method.
+compilers, via the @pxref{1ba,,gccjit;;context;;compile_to_file()} method.
@geindex gccjit;;context;;compile_to_file (C++ function)
-@anchor{cp/topics/compilation gccjit context compile_to_file__enum cCP}@anchor{1b9}
+@anchor{cp/topics/compilation gccjit context compile_to_file__enum cCP}@anchor{1ba}
@deffn {C++ Function} void gccjit::context::compile_to_file (enum gcc_jit_output_kind, const char* output_path)
-Compile the @pxref{134,,gccjit;;context} to a file of the given
+Compile the @pxref{135,,gccjit;;context} to a file of the given
kind.
This is a thin wrapper around the
@@ -14472,7 +14487,7 @@ This is a thin wrapper around the
@c <http://www.gnu.org/licenses/>.
@node Internals,Indices and tables,C++ bindings for libgccjit,Top
-@anchor{internals/index internals}@anchor{1bc}@anchor{internals/index doc}@anchor{1bd}
+@anchor{internals/index internals}@anchor{1bd}@anchor{internals/index doc}@anchor{1be}
@chapter Internals
@@ -14488,7 +14503,7 @@ This is a thin wrapper around the
@end menu
@node Working on the JIT library,Running the test suite,,Internals
-@anchor{internals/index working-on-the-jit-library}@anchor{1be}
+@anchor{internals/index working-on-the-jit-library}@anchor{1bf}
@section Working on the JIT library
@@ -14525,7 +14540,7 @@ gcc/libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV),
Here's what those configuration options mean:
@geindex command line option; --enable-host-shared
-@anchor{internals/index cmdoption--enable-host-shared}@anchor{1bf}
+@anchor{internals/index cmdoption--enable-host-shared}@anchor{1c0}
@deffn {Option} --enable-host-shared
Configuring with this option means that the compiler is built as
@@ -14534,7 +14549,7 @@ but it necessary for a shared library.
@end deffn
@geindex command line option; --enable-languages=jit@comma{}c++
-@anchor{internals/index cmdoption--enable-languages}@anchor{1c0}
+@anchor{internals/index cmdoption--enable-languages}@anchor{1c1}
@deffn {Option} --enable-languages=jit,c++
This specifies which frontends to build. The JIT library looks like
@@ -14553,7 +14568,7 @@ c++: error trying to exec 'cc1plus': execvp: No such file or directory
@end deffn
@geindex command line option; --disable-bootstrap
-@anchor{internals/index cmdoption--disable-bootstrap}@anchor{1c1}
+@anchor{internals/index cmdoption--disable-bootstrap}@anchor{1c2}
@deffn {Option} --disable-bootstrap
For hacking on the "jit" subdirectory, performing a full
@@ -14563,7 +14578,7 @@ the compiler can still bootstrap itself.
@end deffn
@geindex command line option; --enable-checking=release
-@anchor{internals/index cmdoption--enable-checking}@anchor{1c2}
+@anchor{internals/index cmdoption--enable-checking}@anchor{1c3}
@deffn {Option} --enable-checking=release
The compile can perform extensive self-checking as it runs, useful when
@@ -14574,7 +14589,7 @@ disable this self-checking.
@end deffn
@node Running the test suite,Environment variables,Working on the JIT library,Internals
-@anchor{internals/index running-the-test-suite}@anchor{1c3}
+@anchor{internals/index running-the-test-suite}@anchor{1c4}
@section Running the test suite
@@ -14637,7 +14652,7 @@ and once a test has been compiled, you can debug it directly:
@end menu
@node Running under valgrind,,,Running the test suite
-@anchor{internals/index running-under-valgrind}@anchor{1c4}
+@anchor{internals/index running-under-valgrind}@anchor{1c5}
@subsection Running under valgrind
@@ -14685,7 +14700,7 @@ When running under valgrind, it's best to have configured gcc with
various known false positives.
@node Environment variables,Packaging notes,Running the test suite,Internals
-@anchor{internals/index environment-variables}@anchor{1c5}
+@anchor{internals/index environment-variables}@anchor{1c6}
@section Environment variables
@@ -14693,7 +14708,7 @@ When running client code against a locally-built libgccjit, three
environment variables need to be set up:
@geindex environment variable; LD_LIBRARY_PATH
-@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{1c6}
+@anchor{internals/index envvar-LD_LIBRARY_PATH}@anchor{1c7}
@deffn {Environment Variable} LD_LIBRARY_PATH
@quotation
@@ -14715,7 +14730,7 @@ libgccjit.so.0.0.1: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux),
@end deffn
@geindex environment variable; PATH
-@anchor{internals/index envvar-PATH}@anchor{1c7}
+@anchor{internals/index envvar-PATH}@anchor{1c8}
@deffn {Environment Variable} PATH
The library uses a driver executable for converting from .s assembler
@@ -14734,7 +14749,7 @@ of development.
@end deffn
@geindex environment variable; LIBRARY_PATH
-@anchor{internals/index envvar-LIBRARY_PATH}@anchor{1c8}
+@anchor{internals/index envvar-LIBRARY_PATH}@anchor{1c9}
@deffn {Environment Variable} LIBRARY_PATH
The driver executable invokes the linker, and the latter needs to locate
@@ -14770,11 +14785,11 @@ hello world
@noindent
@node Packaging notes,Overview of code structure,Environment variables,Internals
-@anchor{internals/index packaging-notes}@anchor{1c9}
+@anchor{internals/index packaging-notes}@anchor{1ca}
@section Packaging notes
-The configure-time option @pxref{1bf,,--enable-host-shared} is needed when
+The configure-time option @pxref{1c0,,--enable-host-shared} is needed when
building the jit in order to get position-independent code. This will
slow down the regular compiler by a few percent. Hence when packaging gcc
with libgccjit, please configure and build twice:
@@ -14785,10 +14800,10 @@ with libgccjit, please configure and build twice:
@itemize *
@item
-once without @pxref{1bf,,--enable-host-shared} for most languages, and
+once without @pxref{1c0,,--enable-host-shared} for most languages, and
@item
-once with @pxref{1bf,,--enable-host-shared} for the jit
+once with @pxref{1c0,,--enable-host-shared} for the jit
@end itemize
@end quotation
@@ -14832,7 +14847,7 @@ popd
@noindent
@node Overview of code structure,Design notes,Packaging notes,Internals
-@anchor{internals/index overview-of-code-structure}@anchor{1ca}
+@anchor{internals/index overview-of-code-structure}@anchor{1cb}
@section Overview of code structure
@@ -15307,7 +15322,7 @@ JIT: gcc::jit::logger::~logger()
@noindent
@node Design notes,Submitting patches,Overview of code structure,Internals
-@anchor{internals/index design-notes}@anchor{1cb}
+@anchor{internals/index design-notes}@anchor{1cc}
@section Design notes
@@ -15320,7 +15335,7 @@ close as possible to the error; failing that, a good place is within
@code{recording::context::validate ()} in jit-recording.c.
@node Submitting patches,,Design notes,Internals
-@anchor{internals/index submitting-patches}@anchor{1cc}
+@anchor{internals/index submitting-patches}@anchor{1cd}
@section Submitting patches
@@ -15454,7 +15469,7 @@ large and inconsequential (e.g. anchor renumbering), rather like generated
committing to svn.
@node Indices and tables,Index,Internals,Top
-@anchor{index indices-and-tables}@anchor{1cd}
+@anchor{index indices-and-tables}@anchor{1ce}
@unnumbered Indices and tables
diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst
index d9eacf27c6d..7abd0508e20 100644
--- a/gcc/jit/docs/topics/compatibility.rst
+++ b/gcc/jit/docs/topics/compatibility.rst
@@ -135,3 +135,10 @@ entrypoints:
-------------------
``LIBGCCJIT_ABI_5`` covers the addition of
:func:`gcc_jit_context_set_bool_use_external_driver`
+
+.. _LIBGCCJIT_ABI_6:
+
+``LIBGCCJIT_ABI_6``
+-------------------
+``LIBGCCJIT_ABI_6`` covers the addition of
+:func:`gcc_jit_rvalue_set_bool_require_tail_call`
diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst
index cb65c43838a..261483c78b0 100644
--- a/gcc/jit/docs/topics/expressions.rst
+++ b/gcc/jit/docs/topics/expressions.rst
@@ -409,6 +409,46 @@ Function calls
printf_func,
2, args));
+.. function:: gcc_jit_rvalue *\
+ gcc_jit_context_new_call_through_ptr (gcc_jit_context *ctxt,\
+ gcc_jit_location *loc,\
+ gcc_jit_rvalue *fn_ptr,\
+ int numargs, \
+ gcc_jit_rvalue **args)
+
+ Given an rvalue of function pointer type, and the given table of
+ argument rvalues, construct a call to the function pointer, with the
+ result as an rvalue.
+
+ .. note::
+
+ The same caveat as for :c:func:`gcc_jit_context_new_call` applies.
+
+.. function:: void\
+ gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *call,\
+ int require_tail_call)
+
+ Given an :c:type:`gcc_jit_rvalue *` for a call created through
+ :c:func:`gcc_jit_context_new_call` or
+ :c:func:`gcc_jit_context_new_call_through_ptr`, mark/clear the
+ call as needing tail-call optimization. The optimizer will
+ attempt to optimize the call into a jump instruction; if it is
+ unable to do do, an error will be emitted.
+
+ This may be useful when implementing functions that use the
+ continuation-passing style (e.g. for functional programming
+ languages), in which every function "returns" by calling a
+ "continuation" function pointer. This call must be
+ guaranteed to be implemented as a jump, otherwise the program
+ could consume an arbitrary amount of stack space as it executed.
+
+ This entrypoint was added in :ref:`LIBGCCJIT_ABI_6`; you can test for
+ its presence using
+
+ .. code-block:: c
+
+ #ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call
+
Type-coercion
*************
diff --git a/gcc/jit/dummy-frontend.c b/gcc/jit/dummy-frontend.c
index 7194ba68ac4..26311536186 100644
--- a/gcc/jit/dummy-frontend.c
+++ b/gcc/jit/dummy-frontend.c
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "debug.h"
#include "langhooks.h"
#include "langhooks-def.h"
+#include "diagnostic.h"
#include <mpfr.h>
@@ -90,6 +91,35 @@ struct ggc_root_tab jit_root_tab[] =
LAST_GGC_ROOT_TAB
};
+/* JIT-specific implementation of diagnostic callbacks. */
+
+/* Implementation of "begin_diagnostic". */
+
+static void
+jit_begin_diagnostic (diagnostic_context */*context*/,
+ diagnostic_info */*diagnostic*/)
+{
+ gcc_assert (gcc::jit::active_playback_ctxt);
+ JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
+
+ /* No-op (apart from logging); the real error-handling is done in the
+ "end_diagnostic" hook. */
+}
+
+/* Implementation of "end_diagnostic". */
+
+static void
+jit_end_diagnostic (diagnostic_context *context,
+ diagnostic_info *diagnostic)
+{
+ gcc_assert (gcc::jit::active_playback_ctxt);
+ JIT_LOG_SCOPE (gcc::jit::active_playback_ctxt->get_logger ());
+
+ /* Delegate to the playback context (and thence to the
+ recording context). */
+ gcc::jit::active_playback_ctxt->add_diagnostic (context, diagnostic);
+}
+
/* Language hooks. */
static bool
@@ -105,6 +135,10 @@ jit_langhook_init (void)
registered_root_tab = true;
}
+ gcc_assert (global_dc);
+ global_dc->begin_diagnostic = jit_begin_diagnostic;
+ global_dc->end_diagnostic = jit_end_diagnostic;
+
build_common_tree_nodes (false);
/* I don't know why this has to be done explicitly. */
diff --git a/gcc/jit/jit-common.h b/gcc/jit/jit-common.h
index 8a6cd7453a3..b48ea0db69d 100644
--- a/gcc/jit/jit-common.h
+++ b/gcc/jit/jit-common.h
@@ -126,6 +126,7 @@ namespace recording {
class local;
class global;
class param;
+ class base_call;
class statement;
class case_;
diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c
index 579230d3f98..c9f40848be0 100644
--- a/gcc/jit/jit-playback.c
+++ b/gcc/jit/jit-playback.c
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
#include "context.h"
#include "fold-const.h"
#include "gcc.h"
+#include "diagnostic.h"
#include <pthread.h>
@@ -853,7 +854,8 @@ playback::rvalue *
playback::context::
build_call (location *loc,
tree fn_ptr,
- const auto_vec<rvalue *> *args)
+ const auto_vec<rvalue *> *args,
+ bool require_tail_call)
{
vec<tree, va_gc> *tree_args;
vec_alloc (tree_args, args->length ());
@@ -867,9 +869,13 @@ build_call (location *loc,
tree fn_type = TREE_TYPE (fn);
tree return_type = TREE_TYPE (fn_type);
- return new rvalue (this,
- build_call_vec (return_type,
- fn_ptr, tree_args));
+ tree call = build_call_vec (return_type,
+ fn_ptr, tree_args);
+
+ if (require_tail_call)
+ CALL_EXPR_MUST_TAIL_CALL (call) = 1;
+
+ return new rvalue (this, call);
/* see c-typeck.c: build_function_call
which calls build_function_call_vec
@@ -889,7 +895,8 @@ playback::rvalue *
playback::context::
new_call (location *loc,
function *func,
- const auto_vec<rvalue *> *args)
+ const auto_vec<rvalue *> *args,
+ bool require_tail_call)
{
tree fndecl;
@@ -901,7 +908,7 @@ new_call (location *loc,
tree fn = build1 (ADDR_EXPR, build_pointer_type (fntype), fndecl);
- return build_call (loc, fn, args);
+ return build_call (loc, fn, args, require_tail_call);
}
/* Construct a playback::rvalue instance (wrapping a tree) for a
@@ -911,12 +918,13 @@ playback::rvalue *
playback::context::
new_call_through_ptr (location *loc,
rvalue *fn_ptr,
- const auto_vec<rvalue *> *args)
+ const auto_vec<rvalue *> *args,
+ bool require_tail_call)
{
gcc_assert (fn_ptr);
tree t_fn_ptr = fn_ptr->as_tree ();
- return build_call (loc, t_fn_ptr, args);
+ return build_call (loc, t_fn_ptr, args, require_tail_call);
}
/* Construct a tree for a cast. */
@@ -2833,6 +2841,43 @@ add_error_va (location *loc, const char *fmt, va_list ap)
fmt, ap);
}
+/* Report a diagnostic up to the jit context as an error,
+ so that the compilation is treated as a failure.
+ For now, any kind of diagnostic is treated as an error by the jit
+ API. */
+
+void
+playback::context::
+add_diagnostic (struct diagnostic_context *diag_context,
+ struct diagnostic_info *diagnostic)
+{
+ /* At this point the text has been formatted into the pretty-printer's
+ output buffer. */
+ pretty_printer *pp = diag_context->printer;
+ const char *text = pp_formatted_text (pp);
+
+ /* Get location information (if any) from the diagnostic.
+ The recording::context::add_error[_va] methods require a
+ recording::location. We can't lookup the playback::location
+ from the file/line/column since any playback location instances
+ may have been garbage-collected away by now, so instead we create
+ another recording::location directly. */
+ location_t gcc_loc = diagnostic_location (diagnostic);
+ recording::location *rec_loc = NULL;
+ if (gcc_loc)
+ {
+ expanded_location exploc = expand_location (gcc_loc);
+ if (exploc.file)
+ rec_loc = m_recording_ctxt->new_location (exploc.file,
+ exploc.line,
+ exploc.column,
+ false);
+ }
+
+ m_recording_ctxt->add_error (rec_loc, "%s", text);
+ pp_clear_output_area (pp);
+}
+
/* Dealing with the linemap API. */
/* Construct a playback::location for a recording::location, if it
diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h
index 7519bc40ece..c00c25820af 100644
--- a/gcc/jit/jit-playback.h
+++ b/gcc/jit/jit-playback.h
@@ -27,6 +27,9 @@ along with GCC; see the file COPYING3. If not see
#include "jit-recording.h"
+struct diagnostic_context;
+struct diagnostic_info;
+
namespace gcc {
namespace jit {
@@ -130,12 +133,14 @@ public:
rvalue *
new_call (location *loc,
function *func,
- const auto_vec<rvalue *> *args);
+ const auto_vec<rvalue *> *args,
+ bool require_tail_call);
rvalue *
new_call_through_ptr (location *loc,
rvalue *fn_ptr,
- const auto_vec<rvalue *> *args);
+ const auto_vec<rvalue *> *args,
+ bool require_tail_call);
rvalue *
new_cast (location *loc,
@@ -203,6 +208,10 @@ public:
get_first_error () const;
void
+ add_diagnostic (struct diagnostic_context *context,
+ struct diagnostic_info *diagnostic);
+
+ void
set_tree_location (tree t, location *loc);
tree
@@ -229,7 +238,8 @@ private:
rvalue *
build_call (location *loc,
tree fn_ptr,
- const auto_vec<rvalue *> *args);
+ const auto_vec<rvalue *> *args,
+ bool require_tail_call);
tree
build_cast (location *loc,
@@ -314,7 +324,7 @@ class compile_to_memory : public context
{
public:
compile_to_memory (recording::context *ctxt);
- void postprocess (const char *ctxt_progname);
+ void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
result *get_result_obj () const { return m_result; }
@@ -328,7 +338,7 @@ class compile_to_file : public context
compile_to_file (recording::context *ctxt,
enum gcc_jit_output_kind output_kind,
const char *output_path);
- void postprocess (const char *ctxt_progname);
+ void postprocess (const char *ctxt_progname) FINAL OVERRIDE;
private:
void
@@ -414,7 +424,7 @@ public:
function(context *ctxt, tree fndecl, enum gcc_jit_function_kind kind);
void gt_ggc_mx ();
- void finalizer ();
+ void finalizer () FINAL OVERRIDE;
tree get_return_type_as_tree () const;
@@ -475,7 +485,7 @@ public:
block (function *func,
const char *name);
- void finalizer ();
+ void finalizer () FINAL OVERRIDE;
tree as_label_decl () const { return m_label_decl; }
@@ -619,7 +629,7 @@ class source_file : public wrapper
{
public:
source_file (tree filename);
- void finalizer ();
+ void finalizer () FINAL OVERRIDE;
source_line *
get_source_line (int line_num);
@@ -640,7 +650,7 @@ class source_line : public wrapper
{
public:
source_line (source_file *file, int line_num);
- void finalizer ();
+ void finalizer () FINAL OVERRIDE;
location *
get_location (recording::location *rloc, int column_num);
diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c
index 41556db9309..937634207d6 100644
--- a/gcc/jit/jit-recording.c
+++ b/gcc/jit/jit-recording.c
@@ -3015,7 +3015,7 @@ class rvalue_usage_validator : public recording::rvalue_visitor
recording::statement *stmt);
void
- visit (recording::rvalue *rvalue);
+ visit (recording::rvalue *rvalue) FINAL OVERRIDE;
private:
const char *m_api_funcname;
@@ -4681,6 +4681,39 @@ recording::cast::write_reproducer (reproducer &r)
r.get_identifier_as_type (get_type ()));
}
+/* The implementation of class gcc::jit::recording::base_call. */
+
+/* The constructor for gcc::jit::recording::base_call. */
+
+recording::base_call::base_call (context *ctxt,
+ location *loc,
+ type *type_,
+ int numargs,
+ rvalue **args)
+: rvalue (ctxt, loc, type_),
+ m_args (),
+ m_require_tail_call (0)
+{
+ for (int i = 0; i< numargs; i++)
+ m_args.safe_push (args[i]);
+}
+
+/* Subroutine for use by call and call_though_ptr's write_reproducer
+ methods. */
+
+void
+recording::base_call::write_reproducer_tail_call (reproducer &r,
+ const char *id)
+{
+ if (m_require_tail_call)
+ {
+ r.write (" gcc_jit_rvalue_set_bool_require_tail_call (%s, /* gcc_jit_rvalue *call*/\n"
+ " %i); /* int require_tail_call*/\n",
+ id,
+ 1);
+ }
+}
+
/* The implementation of class gcc::jit::recording::call. */
/* The constructor for gcc::jit::recording::call. */
@@ -4690,12 +4723,9 @@ recording::call::call (recording::context *ctxt,
recording::function *func,
int numargs,
rvalue **args)
-: rvalue (ctxt, loc, func->get_return_type ()),
- m_func (func),
- m_args ()
+: base_call (ctxt, loc, func->get_return_type (), numargs, args),
+ m_func (func)
{
- for (int i = 0; i< numargs; i++)
- m_args.safe_push (args[i]);
}
/* Implementation of pure virtual hook recording::memento::replay_into
@@ -4711,7 +4741,8 @@ recording::call::replay_into (replayer *r)
set_playback_obj (r->new_call (playback_location (r, m_loc),
m_func->playback_function (),
- &playback_args));
+ &playback_args,
+ m_require_tail_call));
}
/* Implementation of pure virtual hook recording::rvalue::visit_children
@@ -4790,6 +4821,7 @@ recording::call::write_reproducer (reproducer &r)
r.get_identifier (m_func),
m_args.length (),
args_id);
+ write_reproducer_tail_call (r, id);
}
/* The implementation of class gcc::jit::recording::call_through_ptr. */
@@ -4801,14 +4833,12 @@ recording::call_through_ptr::call_through_ptr (recording::context *ctxt,
recording::rvalue *fn_ptr,
int numargs,
rvalue **args)
-: rvalue (ctxt, loc,
- fn_ptr->get_type ()->dereference ()
- ->as_a_function_type ()->get_return_type ()),
- m_fn_ptr (fn_ptr),
- m_args ()
+: base_call (ctxt, loc,
+ fn_ptr->get_type ()->dereference ()
+ ->as_a_function_type ()->get_return_type (),
+ numargs, args),
+ m_fn_ptr (fn_ptr)
{
- for (int i = 0; i< numargs; i++)
- m_args.safe_push (args[i]);
}
/* Implementation of pure virtual hook recording::memento::replay_into
@@ -4824,7 +4854,8 @@ recording::call_through_ptr::replay_into (replayer *r)
set_playback_obj (r->new_call_through_ptr (playback_location (r, m_loc),
m_fn_ptr->playback_rvalue (),
- &playback_args));
+ &playback_args,
+ m_require_tail_call));
}
/* Implementation of pure virtual hook recording::rvalue::visit_children
@@ -4907,6 +4938,7 @@ recording::call_through_ptr::write_reproducer (reproducer &r)
r.get_identifier_as_rvalue (m_fn_ptr),
m_args.length (),
args_id);
+ write_reproducer_tail_call (r, id);
}
/* The implementation of class gcc::jit::recording::array_access. */
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index d99c752fbec..0e3511c6a1c 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -401,11 +401,11 @@ public:
static string * from_printf (context *ctxt, const char *fmt, ...)
GNU_PRINTF(2, 3);
- void replay_into (replayer *) {}
+ void replay_into (replayer *) FINAL OVERRIDE {}
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
size_t m_len;
@@ -424,7 +424,7 @@ public:
m_created_by_user (created_by_user)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
playback::location *
playback_location (replayer *r)
@@ -453,12 +453,12 @@ public:
return static_cast <playback::location *> (m_playback_obj);
}
- location *dyn_cast_location () { return this; }
+ location *dyn_cast_location () FINAL OVERRIDE { return this; }
bool created_by_user () const { return m_created_by_user; }
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
string *m_filename;
@@ -538,9 +538,9 @@ public:
: type (ctxt),
m_kind (kind) {}
- type *dereference ();
+ type *dereference () FINAL OVERRIDE;
- bool accepts_writes_from (type *rtype)
+ bool accepts_writes_from (type *rtype) FINAL OVERRIDE
{
if (m_kind == GCC_JIT_TYPE_VOID_PTR)
if (rtype->is_pointer ())
@@ -553,19 +553,19 @@ public:
return type::accepts_writes_from (rtype);
}
- bool is_int () const;
- bool is_float () const;
- bool is_bool () const;
- type *is_pointer () { return dereference (); }
- type *is_array () { return NULL; }
- bool is_void () const { return m_kind == GCC_JIT_TYPE_VOID; }
+ bool is_int () const FINAL OVERRIDE;
+ bool is_float () const FINAL OVERRIDE;
+ bool is_bool () const FINAL OVERRIDE;
+ type *is_pointer () FINAL OVERRIDE { return dereference (); }
+ type *is_array () FINAL OVERRIDE { return NULL; }
+ bool is_void () const FINAL OVERRIDE { return m_kind == GCC_JIT_TYPE_VOID; }
public:
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
enum gcc_jit_types m_kind;
@@ -579,21 +579,21 @@ public:
: type (other_type->m_ctxt),
m_other_type (other_type) {}
- type *dereference () { return m_other_type; }
+ type *dereference () FINAL OVERRIDE { return m_other_type; }
- bool accepts_writes_from (type *rtype);
+ bool accepts_writes_from (type *rtype) FINAL OVERRIDE;
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- bool is_int () const { return false; }
- bool is_float () const { return false; }
- bool is_bool () const { return false; }
- type *is_pointer () { return m_other_type; }
- type *is_array () { return NULL; }
+ bool is_int () const FINAL OVERRIDE { return false; }
+ bool is_float () const FINAL OVERRIDE { return false; }
+ bool is_bool () const FINAL OVERRIDE { return false; }
+ type *is_pointer () FINAL OVERRIDE { return m_other_type; }
+ type *is_array () FINAL OVERRIDE { return NULL; }
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
type *m_other_type;
@@ -607,28 +607,28 @@ public:
: type (other_type->m_ctxt),
m_other_type (other_type) {}
- type *dereference () { return m_other_type->dereference (); }
+ type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
- bool accepts_writes_from (type */*rtype*/)
+ bool accepts_writes_from (type */*rtype*/) FINAL OVERRIDE
{
/* Can't write to a "const". */
return false;
}
/* Strip off the "const", giving the underlying type. */
- type *unqualified () { return m_other_type; }
+ type *unqualified () FINAL OVERRIDE { return m_other_type; }
- bool is_int () const { return m_other_type->is_int (); }
- bool is_float () const { return m_other_type->is_float (); }
- bool is_bool () const { return m_other_type->is_bool (); }
- type *is_pointer () { return m_other_type->is_pointer (); }
- type *is_array () { return m_other_type->is_array (); }
+ bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
+ bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
+ bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
+ type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
+ type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
- void replay_into (replayer *);
+ void replay_into (replayer *) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
type *m_other_type;
@@ -642,22 +642,22 @@ public:
: type (other_type->m_ctxt),
m_other_type (other_type) {}
- type *dereference () { return m_other_type->dereference (); }
+ type *dereference () FINAL OVERRIDE { return m_other_type->dereference (); }
/* Strip off the "volatile", giving the underlying type. */
- type *unqualified () { return m_other_type; }
+ type *unqualified () FINAL OVERRIDE { return m_other_type; }
- bool is_int () const { return m_other_type->is_int (); }
- bool is_float () const { return m_other_type->is_float (); }
- bool is_bool () const { return m_other_type->is_bool (); }
- type *is_pointer () { return m_other_type->is_pointer (); }
- type *is_array () { return m_other_type->is_array (); }
+ bool is_int () const FINAL OVERRIDE { return m_other_type->is_int (); }
+ bool is_float () const FINAL OVERRIDE { return m_other_type->is_float (); }
+ bool is_bool () const FINAL OVERRIDE { return m_other_type->is_bool (); }
+ type *is_pointer () FINAL OVERRIDE { return m_other_type->is_pointer (); }
+ type *is_array () FINAL OVERRIDE { return m_other_type->is_array (); }
- void replay_into (replayer *);
+ void replay_into (replayer *) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
type *m_other_type;
@@ -676,19 +676,19 @@ class array_type : public type
m_num_elements (num_elements)
{}
- type *dereference ();
+ type *dereference () FINAL OVERRIDE;
- bool is_int () const { return false; }
- bool is_float () const { return false; }
- bool is_bool () const { return false; }
- type *is_pointer () { return NULL; }
- type *is_array () { return m_element_type; }
+ bool is_int () const FINAL OVERRIDE { return false; }
+ bool is_float () const FINAL OVERRIDE { return false; }
+ bool is_bool () const FINAL OVERRIDE { return false; }
+ type *is_pointer () FINAL OVERRIDE { return NULL; }
+ type *is_array () FINAL OVERRIDE { return m_element_type; }
- void replay_into (replayer *);
+ void replay_into (replayer *) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
location *m_loc;
@@ -705,17 +705,17 @@ public:
type **param_types,
int is_variadic);
- type *dereference ();
- function_type *dyn_cast_function_type () { return this; }
- function_type *as_a_function_type () { return this; }
+ type *dereference () FINAL OVERRIDE;
+ function_type *dyn_cast_function_type () FINAL OVERRIDE { return this; }
+ function_type *as_a_function_type () FINAL OVERRIDE { return this; }
- bool is_int () const { return false; }
- bool is_float () const { return false; }
- bool is_bool () const { return false; }
- type *is_pointer () { return NULL; }
- type *is_array () { return NULL; }
+ bool is_int () const FINAL OVERRIDE { return false; }
+ bool is_float () const FINAL OVERRIDE { return false; }
+ bool is_bool () const FINAL OVERRIDE { return false; }
+ type *is_pointer () FINAL OVERRIDE { return NULL; }
+ type *is_array () FINAL OVERRIDE { return NULL; }
- void replay_into (replayer *);
+ void replay_into (replayer *) FINAL OVERRIDE;
type * get_return_type () const { return m_return_type; }
const vec<type *> &get_param_types () const { return m_param_types; }
@@ -728,9 +728,9 @@ public:
memento *ptr_type);
private:
- string * make_debug_string ();
+ string * make_debug_string () FINAL OVERRIDE;
string * make_debug_string_with (const char *);
- void write_reproducer (reproducer &r);
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
type *m_return_type;
@@ -757,9 +757,9 @@ public:
compound_type * get_container () const { return m_container; }
void set_container (compound_type *c) { m_container = c; }
- void replay_into (replayer *);
+ void replay_into (replayer *) FINAL OVERRIDE;
- void write_to_dump (dump &d);
+ void write_to_dump (dump &d) FINAL OVERRIDE;
playback::field *
playback_field () const
@@ -768,8 +768,8 @@ public:
}
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
location *m_loc;
@@ -795,15 +795,15 @@ public:
int num_fields,
field **fields);
- type *dereference ();
+ type *dereference () FINAL OVERRIDE;
- bool is_int () const { return false; }
- bool is_float () const { return false; }
- bool is_bool () const { return false; }
- type *is_pointer () { return NULL; }
- type *is_array () { return NULL; }
+ bool is_int () const FINAL OVERRIDE { return false; }
+ bool is_float () const FINAL OVERRIDE { return false; }
+ bool is_bool () const FINAL OVERRIDE { return false; }
+ type *is_pointer () FINAL OVERRIDE { return NULL; }
+ type *is_array () FINAL OVERRIDE { return NULL; }
- bool has_known_size () const { return m_fields != NULL; }
+ bool has_known_size () const FINAL OVERRIDE { return m_fields != NULL; }
playback::compound_type *
playback_compound_type ()
@@ -824,18 +824,18 @@ public:
location *loc,
string *name);
- struct_ *dyn_cast_struct () { return this; }
+ struct_ *dyn_cast_struct () FINAL OVERRIDE { return this; }
type *
as_type () { return this; }
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- const char *access_as_type (reproducer &r);
+ const char *access_as_type (reproducer &r) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
};
// memento of struct_::set_fields
@@ -846,16 +846,16 @@ public:
int num_fields,
field **fields);
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void write_to_dump (dump &d);
+ void write_to_dump (dump &d) FINAL OVERRIDE;
int length () const { return m_fields.length (); }
field *get_field (int i) const { return m_fields[i]; }
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
compound_type *m_struct_or_union;
@@ -869,11 +869,11 @@ public:
location *loc,
string *name);
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
location *m_loc;
@@ -960,8 +960,9 @@ public:
void set_scope (function *scope);
function *get_scope () const { return m_scope; }
- /* Dynamic cast. */
+ /* Dynamic casts. */
virtual param *dyn_cast_param () { return NULL; }
+ virtual base_call *dyn_cast_base_call () { return NULL; }
virtual const char *access_as_rvalue (reproducer &r);
@@ -1009,7 +1010,7 @@ public:
rvalue *
as_rvalue () { return this; }
- const char *access_as_rvalue (reproducer &r);
+ const char *access_as_rvalue (reproducer &r) OVERRIDE;
virtual const char *access_as_lvalue (reproducer &r);
};
@@ -1026,9 +1027,9 @@ public:
lvalue *
as_lvalue () { return this; }
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *) {}
+ void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
playback::param *
playback_param () const
@@ -1036,15 +1037,18 @@ public:
return static_cast <playback::param *> (m_playback_obj);
}
- param *dyn_cast_param () { return this; }
+ param *dyn_cast_param () FINAL OVERRIDE { return this; }
- const char *access_as_rvalue (reproducer &r);
- const char *access_as_lvalue (reproducer &r);
+ const char *access_as_rvalue (reproducer &r) FINAL OVERRIDE;
+ const char *access_as_lvalue (reproducer &r) FINAL OVERRIDE;
private:
- string * make_debug_string () { return m_name; }
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
+ string * make_debug_string () FINAL OVERRIDE { return m_name; }
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_PRIMARY;
+ }
private:
string *m_name;
@@ -1063,7 +1067,7 @@ public:
int is_variadic,
enum built_in_function builtin_id);
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
playback::function *
playback_function () const
@@ -1093,15 +1097,15 @@ public:
bool is_variadic () const { return m_is_variadic; }
- void write_to_dump (dump &d);
+ void write_to_dump (dump &d) FINAL OVERRIDE;
void validate ();
void dump_to_dot (const char *path);
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
location *m_loc;
@@ -1183,7 +1187,7 @@ public:
return static_cast <playback::block *> (m_playback_obj);
}
- void write_to_dump (dump &d);
+ void write_to_dump (dump &d) FINAL OVERRIDE;
bool validate ();
@@ -1195,10 +1199,10 @@ public:
vec <block *> get_successor_blocks () const;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
void dump_to_dot (pretty_printer *pp);
void dump_edges_to_dot (pretty_printer *pp);
@@ -1227,16 +1231,19 @@ public:
m_name (name)
{}
- void replay_into (replayer *);
+ void replay_into (replayer *) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *) {}
+ void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
- void write_to_dump (dump &d);
+ void write_to_dump (dump &d) FINAL OVERRIDE;
private:
- string * make_debug_string () { return m_name; }
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
+ string * make_debug_string () FINAL OVERRIDE { return m_name; }
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_PRIMARY;
+ }
private:
enum gcc_jit_global_kind m_kind;
@@ -1254,18 +1261,21 @@ public:
: rvalue (ctxt, loc, type),
m_value (value) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *) {}
+ void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
- bool is_constant () const { return true; }
+ bool is_constant () const FINAL OVERRIDE { return true; }
- bool get_wide_int (wide_int *out) const;
+ bool get_wide_int (wide_int *out) const FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_PRIMARY;
+ }
private:
HOST_TYPE m_value;
@@ -1280,14 +1290,17 @@ public:
: rvalue (ctxt, loc, ctxt->get_type (GCC_JIT_TYPE_CONST_CHAR_PTR)),
m_value (value) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *) {}
+ void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_PRIMARY;
+ }
private:
string *m_value;
@@ -1306,14 +1319,17 @@ public:
m_a (a)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const {return PRECEDENCE_UNARY;}
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_UNARY;
+ }
private:
enum gcc_jit_unary_op m_op;
@@ -1333,14 +1349,14 @@ public:
m_a (a),
m_b (b) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const;
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE;
private:
enum gcc_jit_binary_op m_op;
@@ -1361,14 +1377,14 @@ public:
m_b (b)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const;
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE;
private:
enum gcc_jit_comparison m_op;
@@ -1387,20 +1403,52 @@ public:
m_rvalue (a)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_CAST; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_CAST;
+ }
private:
rvalue *m_rvalue;
};
-class call : public rvalue
+class base_call : public rvalue
+{
+ public:
+ base_call (context *ctxt,
+ location *loc,
+ type *type_,
+ int numargs,
+ rvalue **args);
+
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_POSTFIX;
+ }
+
+ base_call *dyn_cast_base_call () FINAL OVERRIDE { return this; }
+
+ void set_require_tail_call (bool require_tail_call)
+ {
+ m_require_tail_call = require_tail_call;
+ }
+
+ protected:
+ void write_reproducer_tail_call (reproducer &r, const char *id);
+
+ protected:
+ auto_vec<rvalue *> m_args;
+ bool m_require_tail_call;
+};
+
+class call : public base_call
{
public:
call (context *ctxt,
@@ -1409,21 +1457,19 @@ public:
int numargs,
rvalue **args);
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
function *m_func;
- auto_vec<rvalue *> m_args;
};
-class call_through_ptr : public rvalue
+class call_through_ptr : public base_call
{
public:
call_through_ptr (context *ctxt,
@@ -1432,18 +1478,16 @@ public:
int numargs,
rvalue **args);
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
rvalue *m_fn_ptr;
- auto_vec<rvalue *> m_args;
};
class array_access : public lvalue
@@ -1458,14 +1502,17 @@ public:
m_index (index)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_POSTFIX;
+ }
private:
rvalue *m_ptr;
@@ -1484,14 +1531,17 @@ public:
m_field (field)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_POSTFIX;
+ }
private:
lvalue *m_lvalue;
@@ -1510,14 +1560,17 @@ public:
m_field (field)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_POSTFIX;
+ }
private:
rvalue *m_rvalue;
@@ -1536,14 +1589,17 @@ public:
m_field (field)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_POSTFIX; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_POSTFIX;
+ }
private:
rvalue *m_rvalue;
@@ -1559,14 +1615,17 @@ public:
: lvalue (ctxt, loc, val->get_type ()->dereference ()),
m_rvalue (val) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_UNARY; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_UNARY;
+ }
private:
rvalue *m_rvalue;
@@ -1582,14 +1641,17 @@ public:
m_lvalue (val)
{}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *v);
+ void visit_children (rvalue_visitor *v) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_UNARY; }
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_UNARY;
+ }
private:
lvalue *m_lvalue;
@@ -1606,16 +1668,19 @@ public:
set_scope (func);
}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- void visit_children (rvalue_visitor *) {}
+ void visit_children (rvalue_visitor *) FINAL OVERRIDE {}
- void write_to_dump (dump &d);
+ void write_to_dump (dump &d) FINAL OVERRIDE;
private:
- string * make_debug_string () { return m_name; }
- void write_reproducer (reproducer &r);
- enum precedence get_precedence () const { return PRECEDENCE_PRIMARY; }
+ string * make_debug_string () FINAL OVERRIDE { return m_name; }
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
+ enum precedence get_precedence () const FINAL OVERRIDE
+ {
+ return PRECEDENCE_PRIMARY;
+ }
private:
function *m_func;
@@ -1627,7 +1692,7 @@ class statement : public memento
public:
virtual vec <block *> get_successor_blocks () const;
- void write_to_dump (dump &d);
+ void write_to_dump (dump &d) FINAL OVERRIDE;
block *get_block () const { return m_block; }
location *get_loc () const { return m_loc; }
@@ -1658,11 +1723,11 @@ public:
: statement (b, loc),
m_rvalue (rvalue) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
rvalue *m_rvalue;
@@ -1679,11 +1744,11 @@ public:
m_lvalue (lvalue),
m_rvalue (rvalue) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
lvalue *m_lvalue;
@@ -1703,11 +1768,11 @@ public:
m_op (op),
m_rvalue (rvalue) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
lvalue *m_lvalue;
@@ -1724,11 +1789,11 @@ public:
: statement (b, loc),
m_text (text) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
string *m_text;
@@ -1747,13 +1812,13 @@ public:
m_on_true (on_true),
m_on_false (on_false) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- vec <block *> get_successor_blocks () const;
+ vec <block *> get_successor_blocks () const FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
rvalue *m_boolval;
@@ -1770,13 +1835,13 @@ public:
: statement (b, loc),
m_target (target) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- vec <block *> get_successor_blocks () const;
+ vec <block *> get_successor_blocks () const FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
block *m_target;
@@ -1791,13 +1856,13 @@ public:
: statement (b, loc),
m_rvalue (rvalue) {}
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- vec <block *> get_successor_blocks () const;
+ vec <block *> get_successor_blocks () const FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
rvalue *m_rvalue;
@@ -1820,12 +1885,12 @@ class case_ : public memento
rvalue *get_max_value () const { return m_max_value; }
block *get_dest_block () const { return m_dest_block; }
- void replay_into (replayer *) { /* empty */ }
+ void replay_into (replayer *) FINAL OVERRIDE { /* empty */ }
- void write_reproducer (reproducer &r);
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
- string * make_debug_string ();
+ string * make_debug_string () FINAL OVERRIDE;
private:
rvalue *m_min_value;
@@ -1843,13 +1908,13 @@ public:
int num_cases,
case_ **cases);
- void replay_into (replayer *r);
+ void replay_into (replayer *r) FINAL OVERRIDE;
- vec <block *> get_successor_blocks () const;
+ vec <block *> get_successor_blocks () const FINAL OVERRIDE;
private:
- string * make_debug_string ();
- void write_reproducer (reproducer &r);
+ string * make_debug_string () FINAL OVERRIDE;
+ void write_reproducer (reproducer &r) FINAL OVERRIDE;
private:
rvalue *m_expr;
diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c
index 02ff50c75a8..c2c6aeb5bfb 100644
--- a/gcc/jit/libgccjit.c
+++ b/gcc/jit/libgccjit.c
@@ -2950,3 +2950,23 @@ gcc_jit_timer_print (gcc_jit_timer *timer,
timer->start (TV_TOTAL);
timer->push (TV_JIT_CLIENT_CODE);
}
+
+/* Public entrypoint. See description in libgccjit.h.
+
+ After error-checking, the real work is effectively done by the
+ gcc::jit::base_call::set_require_tail_call setter in jit-recording.h. */
+
+void
+gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *rvalue,
+ int require_tail_call)
+{
+ RETURN_IF_FAIL (rvalue, NULL, NULL, "NULL call");
+ JIT_LOG_FUNC (rvalue->get_context ()->get_logger ());
+
+ /* Verify that it's a call. */
+ gcc::jit::recording::base_call *call = rvalue->dyn_cast_base_call ();
+ RETURN_IF_FAIL_PRINTF1 (call, NULL, NULL, "not a call: %s",
+ rvalue->get_debug_string ());
+
+ call->set_require_tail_call (require_tail_call);
+}
diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h
index a8b9f55dc1b..175cc16c01d 100644
--- a/gcc/jit/libgccjit.h
+++ b/gcc/jit/libgccjit.h
@@ -1374,6 +1374,19 @@ extern void
gcc_jit_timer_print (gcc_jit_timer *timer,
FILE *f_out);
+
+#define LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call
+
+/* Mark/clear a call as needing tail-call optimization.
+
+ This API entrypoint was added in LIBGCCJIT_ABI_6; you can test for its
+ presence using
+ #ifdef LIBGCCJIT_HAVE_gcc_jit_rvalue_set_bool_require_tail_call
+*/
+extern void
+gcc_jit_rvalue_set_bool_require_tail_call (gcc_jit_rvalue *call,
+ int require_tail_call);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map
index 65f3166f694..545b192b64c 100644
--- a/gcc/jit/libgccjit.map
+++ b/gcc/jit/libgccjit.map
@@ -145,3 +145,8 @@ LIBGCCJIT_ABI_5 {
global:
gcc_jit_context_set_bool_use_external_driver;
} LIBGCCJIT_ABI_4;
+
+LIBGCCJIT_ABI_6 {
+ global:
+ gcc_jit_rvalue_set_bool_require_tail_call;
+} LIBGCCJIT_ABI_5;
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index a2566ec30a9..034b3b7e84c 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -52,7 +52,7 @@ extern void lhd_print_error_function (diagnostic_context *,
const char *, struct diagnostic_info *);
extern void lhd_set_decl_assembler_name (tree);
extern bool lhd_warn_unused_global_decl (const_tree);
-extern void lhd_incomplete_type_error (const_tree, const_tree);
+extern void lhd_incomplete_type_error (location_t, const_tree, const_tree);
extern tree lhd_type_promotes_to (tree);
extern void lhd_register_builtin_type (tree, const char *);
extern bool lhd_decl_ok_for_sibcall (const_tree);
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 7c07175d810..3256a9d10cc 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -199,7 +199,8 @@ lhd_register_builtin_type (tree ARG_UNUSED (type),
/* Invalid use of an incomplete type. */
void
-lhd_incomplete_type_error (const_tree ARG_UNUSED (value), const_tree type)
+lhd_incomplete_type_error (location_t ARG_UNUSED (loc),
+ const_tree ARG_UNUSED (value), const_tree type)
{
gcc_assert (TREE_CODE (type) == ERROR_MARK);
return;
@@ -560,6 +561,8 @@ add_builtin_function_common (const char *name,
if (library_name)
{
tree libname = get_identifier (library_name);
+
+ libname = targetm.mangle_decl_assembler_name (decl, libname);
SET_DECL_ASSEMBLER_NAME (decl, libname);
}
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index bcfd389aa7e..0593424e026 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -100,8 +100,9 @@ struct lang_hooks_for_types
/* This routine is called in tree.c to print an error message for
invalid use of an incomplete type. VALUE is the expression that
was used (or 0 if that isn't known) and TYPE is the type that was
- invalid. */
- void (*incomplete_type_error) (const_tree value, const_tree type);
+ invalid. LOC is the location of the use. */
+ void (*incomplete_type_error) (location_t loc, const_tree value,
+ const_tree type);
/* Called from assign_temp to return the maximum size, if there is one,
for a type. */
diff --git a/gcc/libfuncs.h b/gcc/libfuncs.h
index 4211a457df5..8250d5b0017 100644
--- a/gcc/libfuncs.h
+++ b/gcc/libfuncs.h
@@ -24,25 +24,9 @@ along with GCC; see the file COPYING3. If not see
/* Enumeration of indexes into libfunc_table. */
enum libfunc_index
{
- LTI_abort,
- LTI_memcpy,
- LTI_memmove,
- LTI_memcmp,
- LTI_memset,
- LTI_setbits,
-
- LTI_setjmp,
- LTI_longjmp,
LTI_unwind_sjlj_register,
LTI_unwind_sjlj_unregister,
-
- LTI_profile_function_entry,
- LTI_profile_function_exit,
-
LTI_synchronize,
-
- LTI_gcov_flush,
-
LTI_MAX
};
@@ -89,26 +73,11 @@ extern struct target_libfuncs *this_target_libfuncs;
/* Accessor macros for libfunc_table. */
-#define abort_libfunc (libfunc_table[LTI_abort])
-#define memcpy_libfunc (libfunc_table[LTI_memcpy])
-#define memmove_libfunc (libfunc_table[LTI_memmove])
-#define memcmp_libfunc (libfunc_table[LTI_memcmp])
-#define memset_libfunc (libfunc_table[LTI_memset])
-#define setbits_libfunc (libfunc_table[LTI_setbits])
-
-#define setjmp_libfunc (libfunc_table[LTI_setjmp])
-#define longjmp_libfunc (libfunc_table[LTI_longjmp])
#define unwind_sjlj_register_libfunc (libfunc_table[LTI_unwind_sjlj_register])
#define unwind_sjlj_unregister_libfunc \
(libfunc_table[LTI_unwind_sjlj_unregister])
-
-#define profile_function_entry_libfunc (libfunc_table[LTI_profile_function_entry])
-#define profile_function_exit_libfunc (libfunc_table[LTI_profile_function_exit])
-
#define synchronize_libfunc (libfunc_table[LTI_synchronize])
-#define gcov_flush_libfunc (libfunc_table[LTI_gcov_flush])
-
/* In explow.c */
extern void set_stack_check_libfunc (const char *);
diff --git a/gcc/loop-doloop.c b/gcc/loop-doloop.c
index 940c966dc5a..6996c0bc0ef 100644
--- a/gcc/loop-doloop.c
+++ b/gcc/loop-doloop.c
@@ -610,7 +610,8 @@ doloop_optimize (struct loop *loop)
widest_int iterations, iterations_max;
rtx_code_label *start_label;
rtx condition;
- unsigned level, est_niter;
+ unsigned level;
+ HOST_WIDE_INT est_niter;
int max_cost;
struct niter_desc *desc;
unsigned word_mode_size;
@@ -635,21 +636,16 @@ doloop_optimize (struct loop *loop)
}
mode = desc->mode;
- est_niter = 3;
- if (desc->const_iter)
- est_niter = desc->niter;
- /* If the estimate on number of iterations is reliable (comes from profile
- feedback), use it. Do not use it normally, since the expected number
- of iterations of an unrolled loop is 2. */
- if (loop->header->count)
- est_niter = expected_loop_iterations (loop);
-
- if (est_niter < 3)
+ est_niter = get_estimated_loop_iterations_int (loop);
+ if (est_niter == -1)
+ est_niter = get_max_loop_iterations_int (loop);
+
+ if (est_niter >= 0 && est_niter < 3)
{
if (dump_file)
fprintf (dump_file,
"Doloop: Too few iterations (%u) to be profitable.\n",
- est_niter);
+ (unsigned int)est_niter);
return false;
}
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 14d5f1dc538..e4e6c8c47eb 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -1307,7 +1307,22 @@ process_addr_reg (rtx *loc, bool check_only_p, rtx_insn **before, rtx_insn **aft
subreg_p = GET_CODE (*loc) == SUBREG;
if (subreg_p)
- loc = &SUBREG_REG (*loc);
+ {
+ reg = SUBREG_REG (*loc);
+ mode = GET_MODE (reg);
+
+ /* For mode with size bigger than ptr_mode, there unlikely to be "mov"
+ between two registers with different classes, but there normally will
+ be "mov" which transfers element of vector register into the general
+ register, and this normally will be a subreg which should be reloaded
+ as a whole. This is particularly likely to be triggered when
+ -fno-split-wide-types specified. */
+ if (!REG_P (reg)
+ || in_class_p (reg, cl, &new_class)
+ || GET_MODE_SIZE (mode) <= GET_MODE_SIZE (ptr_mode))
+ loc = &SUBREG_REG (*loc);
+ }
+
reg = *loc;
mode = GET_MODE (reg);
if (! REG_P (reg))
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index 95c446d0696..5cef2bae159 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -259,7 +259,7 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
streamer_write_gcov_count_stream (ob->main_stream, edge->count);
bp = bitpack_create (ob->main_stream);
- uid = (!gimple_has_body_p (edge->caller->decl)
+ uid = (!gimple_has_body_p (edge->caller->decl) || edge->caller->thunk.thunk_p
? edge->lto_stmt_uid : gimple_uid (edge->call_stmt) + 1);
bp_pack_enum (&bp, cgraph_inline_failed_t,
CIF_N_REASONS, edge->inline_failed);
@@ -268,6 +268,8 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
bp_pack_value (&bp, edge->indirect_inlining_edge, 1);
bp_pack_value (&bp, edge->speculative, 1);
bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1);
+ gcc_assert (!edge->call_stmt_cannot_inline_p
+ || edge->inline_failed != CIF_BODY_NOT_AVAILABLE);
bp_pack_value (&bp, edge->can_throw_external, 1);
bp_pack_value (&bp, edge->in_polymorphic_cdtor, 1);
if (edge->indirect_unknown_callee)
@@ -396,7 +398,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
- if (node->analyzed && (!boundary_p || node->alias || node->thunk.thunk_p))
+ if (node->analyzed && (!boundary_p || node->alias
+ || (node->thunk.thunk_p && !node->global.inlined_to)))
tag = LTO_symtab_analyzed_node;
else
tag = LTO_symtab_unavail_node;
@@ -970,7 +973,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
if (node->alias && node->analyzed)
create_references (encoder, node);
if (cnode
- && cnode->thunk.thunk_p)
+ && cnode->thunk.thunk_p && !cnode->global.inlined_to)
add_node_to (encoder, cnode->callees->callee, false);
while (node->transparent_alias && node->analyzed)
{
@@ -1026,7 +1029,7 @@ output_symtab (void)
{
node = dyn_cast <cgraph_node *> (lto_symtab_encoder_deref (encoder, i));
if (node
- && (node->thunk.thunk_p
+ && ((node->thunk.thunk_p && !node->global.inlined_to)
|| lto_symtab_encoder_in_partition_p (encoder, node)))
{
output_outgoing_cgraph_edges (node->callees, ob, encoder);
diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c
index 93b82be81ff..d8e74d70745 100644
--- a/gcc/lto-section-in.c
+++ b/gcc/lto-section-in.c
@@ -168,7 +168,8 @@ lto_get_section_data (struct lto_file_decl_data *file_data,
}
lto_check_version (((const lto_header *)data)->major_version,
- ((const lto_header *)data)->minor_version);
+ ((const lto_header *)data)->minor_version,
+ file_data->file_name);
return data;
}
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 1970d45ee86..3a353cd0437 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -953,7 +953,8 @@ fixup_call_stmt_edges (struct cgraph_node *orig, gimple **stmts)
if (orig->clones)
for (node = orig->clones; node != orig;)
{
- fixup_call_stmt_edges_1 (node, stmts, fn);
+ if (!node->thunk.thunk_p)
+ fixup_call_stmt_edges_1 (node, stmts, fn);
if (node->clones)
node = node->clones;
else if (node->next_sibling_clone)
diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index 5e35aac8fe9..bfde1fe7763 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -376,12 +376,13 @@ lto_orig_address_remove (tree t)
/* Check that the version MAJOR.MINOR is the correct version number. */
void
-lto_check_version (int major, int minor)
+lto_check_version (int major, int minor, const char *file_name)
{
if (major != LTO_major_version || minor != LTO_minor_version)
fatal_error (input_location,
- "bytecode stream generated with LTO version %d.%d instead "
- "of the expected %d.%d",
+ "bytecode stream in file '%s' generated with LTO version "
+ "%d.%d instead of the expected %d.%d",
+ file_name,
major, minor,
LTO_major_version, LTO_minor_version);
}
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index f3911613b07..92efdb8e008 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -128,7 +128,7 @@ along with GCC; see the file COPYING3. If not see
String are represented in the table as pairs, a length in ULEB128
form followed by the data for the string. */
-#define LTO_major_version 5
+#define LTO_major_version 6
#define LTO_minor_version 0
typedef unsigned char lto_decl_flags_t;
@@ -844,7 +844,7 @@ extern void lto_orig_address_map (tree, intptr_t);
extern intptr_t lto_orig_address_get (tree);
extern void lto_orig_address_remove (tree);
#endif
-extern void lto_check_version (int, int);
+extern void lto_check_version (int, int, const char *);
extern void lto_streamer_hooks_init (void);
/* In lto-streamer-in.c */
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index b1421cbe733..06458d46033 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,11 @@
+2016-05-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * lto-partition.c (add_symbol_to_partition_1): Likewise.
+
+2016-05-03 Jan Hubicka <hubicka@ucw.cz>
+
+ * lto-symtab.c (lto_cgraph_replace_node): Initialize inline_failed.
+
2016-04-27 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
* lto-partition.h (lto_balanced_map): New parameter.
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index c191d24b497..453343a8471 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -163,7 +163,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
/* Add all thunks associated with the function. */
for (e = cnode->callers; e; e = e->next_caller)
- if (e->caller->thunk.thunk_p)
+ if (e->caller->thunk.thunk_p && !e->caller->global.inlined_to)
add_symbol_to_partition_1 (part, e->caller);
/* Instrumented version is actually the same function.
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 94b919b53e6..ce9e1465e3c 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -81,7 +81,10 @@ lto_cgraph_replace_node (struct cgraph_node *node,
??? We really need a way to match function signatures for ABI
compatibility and perform related promotions at inlining time. */
if (!compatible_p)
- e->call_stmt_cannot_inline_p = 1;
+ {
+ e->inline_failed = CIF_LTO_MISMATCHED_DECLARATIONS;
+ e->call_stmt_cannot_inline_p = 1;
+ }
}
/* Redirect incomming references. */
prevailing_node->clone_referring (node);
diff --git a/gcc/machmode.h b/gcc/machmode.h
index ef97d83de7e..3dcadd862f2 100644
--- a/gcc/machmode.h
+++ b/gcc/machmode.h
@@ -269,6 +269,10 @@ extern const unsigned char mode_wider[NUM_MACHINE_MODES];
extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
#define GET_MODE_2XWIDER_MODE(MODE) ((machine_mode) mode_2xwider[MODE])
+/* Get the complex mode from the component mode. */
+extern const unsigned char mode_complex[NUM_MACHINE_MODES];
+#define GET_MODE_COMPLEX_MODE(MODE) ((machine_mode) mode_complex[MODE])
+
/* Return the mode for data of a given size SIZE and mode class CLASS.
If LIMIT is nonzero, then don't use modes bigger than MAX_FIXED_MODE_SIZE.
The value is BLKmode if no other mode is found. */
diff --git a/gcc/match.pd b/gcc/match.pd
index 608afa3e25e..f11ce7c9712 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -503,6 +503,14 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bit_ior:c (bit_and @0 INTEGER_CST@2) (bit_and (bit_not @0) INTEGER_CST@1))
(if (wi::bit_not (@2) == @1)
(bit_xor @0 @1)))
+/* Simplify (~X & Y) to X ^ Y if we know that (X & ~Y) is 0. */
+#if GIMPLE
+(simplify
+ (bit_and (bit_not SSA_NAME@0) INTEGER_CST@1)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && (get_nonzero_bits (@0) & wi::bit_not (@1)) == 0)
+ (bit_xor @0 @1)))
+#endif
/* X % Y is smaller than Y. */
(for cmp (lt ge)
@@ -555,6 +563,15 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bitop @0 @0)
(non_lvalue @0)))
+/* x & C -> x if we know that x & ~C == 0. */
+#if GIMPLE
+(simplify
+ (bit_and SSA_NAME@0 INTEGER_CST@1)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && (get_nonzero_bits (@0) & wi::bit_not (@1)) == 0)
+ @0))
+#endif
+
/* x + (x & 1) -> (x + 1) & ~1 */
(simplify
(plus:c @0 (bit_and:s @0 integer_onep@1))
@@ -674,10 +691,12 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
(bit_xor (convert @0) (bit_not @1))))
-/* Fold (X & Y) ^ Y as ~X & Y. */
-(simplify
- (bit_xor:c (bit_and:c @0 @1) @1)
- (bit_and (bit_not @0) @1))
+/* Fold (X & Y) ^ Y and (X ^ Y) & Y as ~X & Y. */
+(for opo (bit_and bit_xor)
+ opi (bit_xor bit_and)
+ (simplify
+ (opo:c (opi:c @0 @1) @1)
+ (bit_and (bit_not @0) @1)))
/* Given a bit-wise operation CODE applied to ARG0 and ARG1, see if both
operands are another bit-wise operation with a common input. If so,
@@ -685,13 +704,43 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
constants are involved. For example, convert
(A | B) & (A | C) into A | (B & C)
Further simplification will occur if B and C are constants. */
-(for op (bit_and bit_ior)
- rop (bit_ior bit_and)
+(for op (bit_and bit_ior bit_xor)
+ rop (bit_ior bit_and bit_and)
(simplify
- (op (convert? (rop:c @0 @1)) (convert? (rop @0 @2)))
- (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+ (op (convert? (rop:c @0 @1)) (convert? (rop:c @0 @2)))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@1))
+ && tree_nop_conversion_p (type, TREE_TYPE (@2)))
(rop (convert @0) (op (convert @1) (convert @2))))))
+/* Some simple reassociation for bit operations, also handled in reassoc. */
+/* (X & Y) & Y -> X & Y
+ (X | Y) | Y -> X | Y */
+(for op (bit_and bit_ior)
+ (simplify
+ (op:c (convert?@2 (op:c @0 @1)) (convert? @1))
+ @2))
+/* (X ^ Y) ^ Y -> X */
+(simplify
+ (bit_xor:c (convert? (bit_xor:c @0 @1)) (convert? @1))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@0)))
+ (convert @0)))
+/* (X & Y) & (X & Z) -> (X & Y) & Z
+ (X | Y) | (X | Z) -> (X | Y) | Z */
+(for op (bit_and bit_ior)
+ (simplify
+ (op:c (convert1?@3 (op:c@4 @0 @1)) (convert2?@5 (op:c@6 @0 @2)))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@1))
+ && tree_nop_conversion_p (type, TREE_TYPE (@2)))
+ (if (single_use (@5) && single_use (@6))
+ (op @3 (convert @2))
+ (if (single_use (@3) && single_use (@4))
+ (op (convert @1) @5))))))
+/* (X ^ Y) ^ (X ^ Z) -> Y ^ Z */
+(simplify
+ (bit_xor (convert1? (bit_xor:c @0 @1)) (convert2? (bit_xor:c @0 @2)))
+ (if (tree_nop_conversion_p (type, TREE_TYPE (@1))
+ && tree_nop_conversion_p (type, TREE_TYPE (@2)))
+ (bit_xor (convert @1) (convert @2))))
(simplify
(abs (abs@1 @0))
@@ -787,12 +836,6 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(bitop:c (rbitop:c (bit_not @0) @1) @0)
(bitop @0 @1)))
-/* Simplify (A & B) OP0 (C & B) to (A OP0 C) & B. */
-(for bitop (bit_and bit_ior bit_xor)
- (simplify
- (bitop (bit_and:c @0 @1) (bit_and @2 @1))
- (bit_and (bitop @0 @2) @1)))
-
/* (x | CST1) & CST2 -> (x & CST2) | (CST1 & CST2) */
(simplify
(bit_and (bit_ior @0 CONSTANT_CLASS_P@1) CONSTANT_CLASS_P@2)
@@ -1458,6 +1501,27 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(with { tree mask = int_const_binop (shift, fold_convert (type, @2), @1); }
(bit_op (shift (convert @0) @1) { mask; }))))))
+/* ~(~X >> Y) -> X >> Y (for arithmetic shift). */
+(simplify
+ (bit_not (convert1?:s (rshift:s (convert2?@0 (bit_not @1)) @2)))
+ (if (!TYPE_UNSIGNED (TREE_TYPE (@0))
+ && element_precision (TREE_TYPE (@0))
+ <= element_precision (TREE_TYPE (@1))
+ && element_precision (type) <= element_precision (TREE_TYPE (@0)))
+ (with
+ { tree shift_type = TREE_TYPE (@0); }
+ (convert (rshift (convert:shift_type @1) @2)))))
+
+/* ~(~X >>r Y) -> X >>r Y
+ ~(~X <<r Y) -> X <<r Y */
+(for rotate (lrotate rrotate)
+ (simplify
+ (bit_not (convert1?:s (rotate:s (convert2?@0 (bit_not @1)) @2)))
+ (if (element_precision (TREE_TYPE (@0)) <= element_precision (TREE_TYPE (@1))
+ && element_precision (type) <= element_precision (TREE_TYPE (@0)))
+ (with
+ { tree rotate_type = TREE_TYPE (@0); }
+ (convert (rotate (convert:rotate_type @1) @2))))))
/* Simplifications of conversions. */
@@ -1921,6 +1985,10 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(simplify
(cmp @0 @0)
{ constant_boolean_node (true, type); }))
+(for cmp (unlt ungt)
+ (simplify
+ (cmp @0 @0)
+ (unordered @0 @0)))
(simplify
(ltgt @0 @0)
(if (!flag_trapping_math)
@@ -3186,3 +3254,145 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
(SIGNBIT @0)
(if (!HONOR_SIGNED_ZEROS (@0))
(convert (lt @0 { build_real (TREE_TYPE (@0), dconst0); }))))
+
+/* Transform comparisons of the form X +- C1 CMP C2 to X CMP C2 -+ C1. */
+(for cmp (eq ne)
+ (for op (plus minus)
+ rop (minus plus)
+ (simplify
+ (cmp (op@3 @0 INTEGER_CST@1) INTEGER_CST@2)
+ (if (!TREE_OVERFLOW (@1) && !TREE_OVERFLOW (@2)
+ && !TYPE_OVERFLOW_SANITIZED (TREE_TYPE (@0))
+ && !TYPE_OVERFLOW_TRAPS (TREE_TYPE (@0))
+ && !TYPE_SATURATING (TREE_TYPE (@0)))
+ (with { tree res = int_const_binop (rop, @2, @1); }
+ (if (TREE_OVERFLOW (res))
+ { constant_boolean_node (cmp == NE_EXPR, type); }
+ (if (single_use (@3))
+ (cmp @0 { res; }))))))))
+(for cmp (lt le gt ge)
+ (for op (plus minus)
+ rop (minus plus)
+ (simplify
+ (cmp (op@3 @0 INTEGER_CST@1) INTEGER_CST@2)
+ (if (!TREE_OVERFLOW (@1) && !TREE_OVERFLOW (@2)
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (@0)))
+ (with { tree res = int_const_binop (rop, @2, @1); }
+ (if (TREE_OVERFLOW (res))
+ {
+ fold_overflow_warning (("assuming signed overflow does not occur "
+ "when simplifying conditional to constant"),
+ WARN_STRICT_OVERFLOW_CONDITIONAL);
+ bool less = cmp == LE_EXPR || cmp == LT_EXPR;
+ /* wi::ges_p (@2, 0) should be sufficient for a signed type. */
+ bool ovf_high = wi::lt_p (@1, 0, TYPE_SIGN (TREE_TYPE (@1)))
+ != (op == MINUS_EXPR);
+ constant_boolean_node (less == ovf_high, type);
+ }
+ (if (single_use (@3))
+ (with
+ {
+ fold_overflow_warning (("assuming signed overflow does not occur "
+ "when changing X +- C1 cmp C2 to "
+ "X cmp C2 -+ C1"),
+ WARN_STRICT_OVERFLOW_COMPARISON);
+ }
+ (cmp @0 { res; })))))))))
+
+/* Canonicalizations of BIT_FIELD_REFs. */
+
+(simplify
+ (BIT_FIELD_REF @0 @1 @2)
+ (switch
+ (if (TREE_CODE (TREE_TYPE (@0)) == COMPLEX_TYPE
+ && tree_int_cst_equal (@1, TYPE_SIZE (TREE_TYPE (TREE_TYPE (@0)))))
+ (switch
+ (if (integer_zerop (@2))
+ (view_convert (realpart @0)))
+ (if (tree_int_cst_equal (@2, TYPE_SIZE (TREE_TYPE (TREE_TYPE (@0)))))
+ (view_convert (imagpart @0)))))
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0))
+ && INTEGRAL_TYPE_P (type)
+ /* On GIMPLE this should only apply to register arguments. */
+ && (! GIMPLE || is_gimple_reg (@0))
+ /* A bit-field-ref that referenced the full argument can be stripped. */
+ && ((compare_tree_int (@1, TYPE_PRECISION (TREE_TYPE (@0))) == 0
+ && integer_zerop (@2))
+ /* Low-parts can be reduced to integral conversions.
+ ??? The following doesn't work for PDP endian. */
+ || (BYTES_BIG_ENDIAN == WORDS_BIG_ENDIAN
+ /* Don't even think about BITS_BIG_ENDIAN. */
+ && TYPE_PRECISION (TREE_TYPE (@0)) % BITS_PER_UNIT == 0
+ && TYPE_PRECISION (type) % BITS_PER_UNIT == 0
+ && compare_tree_int (@2, (BYTES_BIG_ENDIAN
+ ? (TYPE_PRECISION (TREE_TYPE (@0))
+ - TYPE_PRECISION (type))
+ : 0)) == 0)))
+ (convert @0))))
+
+/* Simplify vector extracts. */
+
+(simplify
+ (BIT_FIELD_REF CONSTRUCTOR@0 @1 @2)
+ (if (VECTOR_TYPE_P (TREE_TYPE (@0))
+ && (types_match (type, TREE_TYPE (TREE_TYPE (@0)))
+ || (VECTOR_TYPE_P (type)
+ && types_match (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (@0))))))
+ (with
+ {
+ tree ctor = (TREE_CODE (@0) == SSA_NAME
+ ? gimple_assign_rhs1 (SSA_NAME_DEF_STMT (@0)) : @0);
+ tree eltype = TREE_TYPE (TREE_TYPE (ctor));
+ unsigned HOST_WIDE_INT width = tree_to_uhwi (TYPE_SIZE (eltype));
+ unsigned HOST_WIDE_INT n = tree_to_uhwi (@1);
+ unsigned HOST_WIDE_INT idx = tree_to_uhwi (@2);
+ }
+ (if (n != 0
+ && (idx % width) == 0
+ && (n % width) == 0
+ && ((idx + n) / width) <= TYPE_VECTOR_SUBPARTS (TREE_TYPE (ctor)))
+ (with
+ {
+ idx = idx / width;
+ n = n / width;
+ /* Constructor elements can be subvectors. */
+ unsigned HOST_WIDE_INT k = 1;
+ if (CONSTRUCTOR_NELTS (ctor) != 0)
+ {
+ tree cons_elem = TREE_TYPE (CONSTRUCTOR_ELT (ctor, 0)->value);
+ if (TREE_CODE (cons_elem) == VECTOR_TYPE)
+ k = TYPE_VECTOR_SUBPARTS (cons_elem);
+ }
+ }
+ (switch
+ /* We keep an exact subset of the constructor elements. */
+ (if ((idx % k) == 0 && (n % k) == 0)
+ (if (CONSTRUCTOR_NELTS (ctor) == 0)
+ { build_constructor (type, NULL); }
+ (with
+ {
+ idx /= k;
+ n /= k;
+ }
+ (if (n == 1)
+ (if (idx < CONSTRUCTOR_NELTS (ctor))
+ { CONSTRUCTOR_ELT (ctor, idx)->value; }
+ { build_zero_cst (type); })
+ {
+ vec<constructor_elt, va_gc> *vals;
+ vec_alloc (vals, n);
+ for (unsigned i = 0;
+ i < n && idx + i < CONSTRUCTOR_NELTS (ctor); ++i)
+ CONSTRUCTOR_APPEND_ELT (vals, NULL_TREE,
+ CONSTRUCTOR_ELT (ctor, idx + i)->value);
+ build_constructor (type, vals);
+ }))))
+ /* The bitfield references a single constructor element. */
+ (if (idx + n <= (idx / k + 1) * k)
+ (switch
+ (if (CONSTRUCTOR_NELTS (ctor) <= idx / k)
+ { build_zero_cst (type); })
+ (if (n == k)
+ { CONSTRUCTOR_ELT (ctor, idx / k)->value; })
+ (BIT_FIELD_REF { CONSTRUCTOR_ELT (ctor, idx / k)->value; }
+ @1 { bitsize_int ((idx % k) * width); })))))))))
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e4a1e4746db..a11f44b84a7 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -2570,6 +2570,7 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
it afterward. */
push_struct_function (decl);
cfun->function_end_locus = gimple_location (ctx->stmt);
+ init_tree_ssa (cfun);
pop_cfun ();
}
@@ -6402,12 +6403,10 @@ lower_oacc_head_tail (location_t loc, tree clauses,
gimple_seq_add_stmt (head, gimple_build_assign (ddvar, integer_zero_node));
unsigned count = lower_oacc_head_mark (loc, ddvar, clauses, head, ctx);
- if (!count)
- lower_oacc_loop_marker (loc, ddvar, false, integer_zero_node, tail);
-
tree fork_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_FORK);
tree join_kind = build_int_cst (unsigned_type_node, IFN_UNIQUE_OACC_JOIN);
+ gcc_assert (count);
for (unsigned done = 1; count; count--, done++)
{
gimple_seq fork_seq = NULL;
@@ -13674,6 +13673,7 @@ grid_expand_target_grid_body (struct omp_region *target)
DECL_INITIAL (kern_fndecl) = fniniblock;
push_struct_function (kern_fndecl);
cfun->function_end_locus = gimple_location (tgt_stmt);
+ init_tree_ssa (cfun);
pop_cfun ();
tree old_parm_decl = DECL_ARGUMENTS (kern_fndecl);
@@ -13681,6 +13681,9 @@ grid_expand_target_grid_body (struct omp_region *target)
tree new_parm_decl = copy_node (DECL_ARGUMENTS (kern_fndecl));
DECL_CONTEXT (new_parm_decl) = kern_fndecl;
DECL_ARGUMENTS (kern_fndecl) = new_parm_decl;
+ gcc_assert (VOID_TYPE_P (TREE_TYPE (DECL_RESULT (kern_fndecl))));
+ DECL_RESULT (kern_fndecl) = copy_node (DECL_RESULT (kern_fndecl));
+ DECL_CONTEXT (DECL_RESULT (kern_fndecl)) = kern_fndecl;
struct function *kern_cfun = DECL_STRUCT_FUNCTION (kern_fndecl);
kern_cfun->curr_properties = cfun->curr_properties;
@@ -19331,10 +19334,8 @@ oacc_loop_process (oacc_loop *loop)
oacc_loop_xform_loop (loop->head_end, loop->ifns, mask_arg, chunk_arg);
- for (ix = 0; ix != GOMP_DIM_MAX && loop->heads[ix]; ix++)
+ for (ix = 0; ix != GOMP_DIM_MAX && mask; ix++)
{
- gcc_assert (mask);
-
while (!(GOMP_DIM_MASK (dim) & mask))
dim++;
diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c
index fa6ffecb4c2..ad7e83b49e8 100644
--- a/gcc/omp-simd-clone.c
+++ b/gcc/omp-simd-clone.c
@@ -1079,6 +1079,7 @@ simd_clone_adjust (struct cgraph_node *node)
tree iter1 = make_ssa_name (iter);
tree iter2 = make_ssa_name (iter);
ipa_simd_modify_function_body (node, adjustments, retval, iter1);
+ adjustments.release ();
/* Initialize the iteration variable. */
basic_block entry_bb = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
diff --git a/gcc/optabs-libfuncs.c b/gcc/optabs-libfuncs.c
index b300096baa0..79a07d68b2c 100644
--- a/gcc/optabs-libfuncs.c
+++ b/gcc/optabs-libfuncs.c
@@ -731,14 +731,15 @@ static GTY (()) hash_table<libfunc_decl_hasher> *libfunc_decls;
tree
build_libfunc_function (const char *name)
{
+ /* ??? We don't have any type information; pretend this is "int foo ()". */
tree decl = build_decl (UNKNOWN_LOCATION, FUNCTION_DECL,
get_identifier (name),
build_function_type (integer_type_node, NULL_TREE));
- /* ??? We don't have any type information except for this is
- a function. Pretend this is "int foo ()". */
- DECL_ARTIFICIAL (decl) = 1;
DECL_EXTERNAL (decl) = 1;
TREE_PUBLIC (decl) = 1;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
+ DECL_VISIBILITY_SPECIFIED (decl) = 1;
gcc_assert (DECL_ASSEMBLER_NAME (decl));
/* Zap the nonsensical SYMBOL_REF_DECL for this. What we're left with
@@ -887,32 +888,10 @@ init_optabs (void)
set_optab_libfunc (abs_optab, TYPE_MODE (complex_double_type_node),
"cabs");
- abort_libfunc = init_one_libfunc ("abort");
- memcpy_libfunc = init_one_libfunc ("memcpy");
- memmove_libfunc = init_one_libfunc ("memmove");
- memcmp_libfunc = init_one_libfunc ("memcmp");
- memset_libfunc = init_one_libfunc ("memset");
- setbits_libfunc = init_one_libfunc ("__setbits");
-
-#ifndef DONT_USE_BUILTIN_SETJMP
- setjmp_libfunc = init_one_libfunc ("__builtin_setjmp");
- longjmp_libfunc = init_one_libfunc ("__builtin_longjmp");
-#else
- setjmp_libfunc = init_one_libfunc ("setjmp");
- longjmp_libfunc = init_one_libfunc ("longjmp");
-#endif
unwind_sjlj_register_libfunc = init_one_libfunc ("_Unwind_SjLj_Register");
unwind_sjlj_unregister_libfunc
= init_one_libfunc ("_Unwind_SjLj_Unregister");
- /* For function entry/exit instrumentation. */
- profile_function_entry_libfunc
- = init_one_libfunc ("__cyg_profile_func_enter");
- profile_function_exit_libfunc
- = init_one_libfunc ("__cyg_profile_func_exit");
-
- gcov_flush_libfunc = init_one_libfunc ("__gcov_flush");
-
/* Allow the target to add more libcalls or rename some, etc. */
targetm.init_libfuncs ();
}
diff --git a/gcc/optabs.c b/gcc/optabs.c
index a6d8822b87e..2bd81db5166 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -3776,8 +3776,6 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
{
machine_mode result_mode;
enum insn_code cmp_code;
- tree length_type;
- rtx libfunc;
rtx result;
rtx opalign
= GEN_INT (MIN (MEM_ALIGN (x), MEM_ALIGN (y)) / BITS_PER_UNIT);
@@ -3818,22 +3816,12 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size,
if (methods != OPTAB_LIB && methods != OPTAB_LIB_WIDEN)
goto fail;
- /* Otherwise call a library function, memcmp. */
- libfunc = memcmp_libfunc;
- length_type = sizetype;
- result_mode = TYPE_MODE (integer_type_node);
- cmp_mode = TYPE_MODE (length_type);
- size = convert_to_mode (TYPE_MODE (length_type), size,
- TYPE_UNSIGNED (length_type));
-
- result = emit_library_call_value (libfunc, 0, LCT_PURE,
- result_mode, 3,
- XEXP (x, 0), Pmode,
- XEXP (y, 0), Pmode,
- size, cmp_mode);
+ /* Otherwise call a library function. */
+ result = emit_block_comp_via_libcall (XEXP (x, 0), XEXP (y, 0), size);
+
x = result;
y = const0_rtx;
- mode = result_mode;
+ mode = TYPE_MODE (integer_type_node);
methods = OPTAB_LIB_WIDEN;
unsignedp = false;
}
diff --git a/gcc/optabs.def b/gcc/optabs.def
index c938b42ea4e..8875e30d416 100644
--- a/gcc/optabs.def
+++ b/gcc/optabs.def
@@ -337,6 +337,9 @@ OPTAB_D (atomic_add_fetch_optab, "atomic_add_fetch$I$a")
OPTAB_D (atomic_add_optab, "atomic_add$I$a")
OPTAB_D (atomic_and_fetch_optab, "atomic_and_fetch$I$a")
OPTAB_D (atomic_and_optab, "atomic_and$I$a")
+OPTAB_D (atomic_bit_test_and_set_optab, "atomic_bit_test_and_set$I$a")
+OPTAB_D (atomic_bit_test_and_complement_optab, "atomic_bit_test_and_complement$I$a")
+OPTAB_D (atomic_bit_test_and_reset_optab, "atomic_bit_test_and_reset$I$a")
OPTAB_D (atomic_compare_and_swap_optab, "atomic_compare_and_swap$I$a")
OPTAB_D (atomic_exchange_optab, "atomic_exchange$I$a")
OPTAB_D (atomic_fetch_add_optab, "atomic_fetch_add$I$a")
diff --git a/gcc/opts-common.c b/gcc/opts-common.c
index bb689827227..4e1ef497ed8 100644
--- a/gcc/opts-common.c
+++ b/gcc/opts-common.c
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "opts.h"
#include "options.h"
#include "diagnostic.h"
+#include "spellcheck.h"
static void prune_options (struct cl_decoded_option **, unsigned int *);
@@ -1113,6 +1114,7 @@ cmdline_handle_error (location_t loc, const struct cl_option *option,
for (i = 0; e->values[i].arg != NULL; i++)
len += strlen (e->values[i].arg) + 1;
+ auto_vec <const char *> candidates;
s = XALLOCAVEC (char, len);
p = s;
for (i = 0; e->values[i].arg != NULL; i++)
@@ -1123,9 +1125,16 @@ cmdline_handle_error (location_t loc, const struct cl_option *option,
memcpy (p, e->values[i].arg, arglen);
p[arglen] = ' ';
p += arglen + 1;
+ candidates.safe_push (e->values[i].arg);
}
p[-1] = 0;
- inform (loc, "valid arguments to %qs are: %s", option->opt_text, s);
+ const char *hint = find_closest_string (arg, &candidates);
+ if (hint)
+ inform (loc, "valid arguments to %qs are: %s; did you mean %qs?",
+ option->opt_text, s, hint);
+ else
+ inform (loc, "valid arguments to %qs are: %s", option->opt_text, s);
+
return true;
}
diff --git a/gcc/opts.c b/gcc/opts.c
index 649b84b3f6f..63d41ca9deb 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -498,7 +498,6 @@ static const struct default_options default_options_table[] =
{ OPT_LEVELS_2_PLUS, OPT_fstrict_overflow, NULL, 1 },
{ OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
REORDER_BLOCKS_ALGORITHM_STC },
- { OPT_LEVELS_2_PLUS, OPT_frename_registers, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
@@ -1596,7 +1595,7 @@ common_handle_option (struct gcc_options *opts,
case OPT__help_:
{
- const char * a = arg;
+ const char *a = arg;
unsigned int include_flags = 0;
/* Note - by default we include undocumented options when listing
specific classes. If you only want to see documented options
@@ -1613,11 +1612,11 @@ common_handle_option (struct gcc_options *opts,
arg = [^]{word}[,{arg}]
word = {optimizers|target|warnings|undocumented|
params|common|<language>} */
- while (* a != 0)
+ while (*a != 0)
{
static const struct
{
- const char * string;
+ const char *string;
unsigned int flag;
}
specifics[] =
@@ -1632,19 +1631,24 @@ common_handle_option (struct gcc_options *opts,
{ "common", CL_COMMON },
{ NULL, 0 }
};
- unsigned int * pflags;
- const char * comma;
+ unsigned int *pflags;
+ const char *comma;
unsigned int lang_flag, specific_flag;
unsigned int len;
unsigned int i;
- if (* a == '^')
+ if (*a == '^')
{
- ++ a;
- pflags = & exclude_flags;
+ ++a;
+ if (*a == '\0')
+ {
+ error_at (loc, "missing argument to %qs", "--help=^");
+ break;
+ }
+ pflags = &exclude_flags;
}
else
- pflags = & include_flags;
+ pflags = &include_flags;
comma = strchr (a, ',');
if (comma == NULL)
@@ -1681,7 +1685,7 @@ common_handle_option (struct gcc_options *opts,
if (specific_flag != 0)
{
if (lang_flag == 0)
- * pflags |= specific_flag;
+ *pflags |= specific_flag;
else
{
/* The option's argument matches both the start of a
@@ -1690,7 +1694,7 @@ common_handle_option (struct gcc_options *opts,
specified "--help=c", but otherwise we have to issue
a warning. */
if (strncasecmp (a, "c", len) == 0)
- * pflags |= lang_flag;
+ *pflags |= lang_flag;
else
warning_at (loc, 0,
"--help argument %q.*s is ambiguous, "
@@ -1699,7 +1703,7 @@ common_handle_option (struct gcc_options *opts,
}
}
else if (lang_flag != 0)
- * pflags |= lang_flag;
+ *pflags |= lang_flag;
else
warning_at (loc, 0,
"unrecognized argument to --help= option: %q.*s",
diff --git a/gcc/params.def b/gcc/params.def
index 9e05401f028..62a1e404a1a 100644
--- a/gcc/params.def
+++ b/gcc/params.def
@@ -530,6 +530,12 @@ DEFPARAM(PARAM_SCEV_MAX_EXPR_COMPLEXITY,
"Bound on the complexity of the expressions in the scalar evolutions analyzer.",
10, 0, 0)
+DEFPARAM (PARAM_MAX_TREE_IF_CONVERSION_PHI_ARGS,
+ "max-tree-if-conversion-phi-args",
+ "Maximum number of arguments in a PHI supported by TREE if-conversion "
+ "unless the loop is marked with simd pragma.",
+ 4, 2, 0)
+
DEFPARAM(PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
"vect-max-version-for-alignment-checks",
"Bound on number of runtime checks inserted by the vectorizer's loop versioning for alignment check.",
diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
index 4f89d316c80..464e25faaab 100644
--- a/gcc/pass_manager.h
+++ b/gcc/pass_manager.h
@@ -78,6 +78,10 @@ public:
opt_pass *get_pass_peephole2 () const { return pass_peephole2_1; }
opt_pass *get_pass_profile () const { return pass_profile_1; }
+ void register_pass_name (opt_pass *pass, const char *name);
+
+ opt_pass *get_pass_by_name (const char *name);
+
public:
/* The root of the compilation pass tree, once constructed. */
opt_pass *all_passes;
@@ -95,9 +99,11 @@ public:
private:
void set_pass_for_id (int id, opt_pass *pass);
void register_dump_files (opt_pass *pass);
+ void create_pass_tab () const;
private:
context *m_ctxt;
+ hash_map<nofree_string_hash, opt_pass *> *m_name_to_pass_map;
/* References to all of the individual passes.
These fields are generated via macro expansion.
diff --git a/gcc/passes.c b/gcc/passes.c
index 2b70846dd40..0565cfa144b 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -66,8 +66,6 @@ using namespace gcc;
The variable current_pass is also used for statistics and plugins. */
opt_pass *current_pass;
-static void register_pass_name (opt_pass *, const char *);
-
/* Most passes are single-instance (within their context) and thus don't
need to implement cloning, but passes that support multiple instances
*must* provide their own implementation of the clone method.
@@ -844,21 +842,19 @@ pass_manager::register_dump_files (opt_pass *pass)
while (pass);
}
-static hash_map<nofree_string_hash, opt_pass *> *name_to_pass_map;
-
/* Register PASS with NAME. */
-static void
-register_pass_name (opt_pass *pass, const char *name)
+void
+pass_manager::register_pass_name (opt_pass *pass, const char *name)
{
- if (!name_to_pass_map)
- name_to_pass_map = new hash_map<nofree_string_hash, opt_pass *> (256);
+ if (!m_name_to_pass_map)
+ m_name_to_pass_map = new hash_map<nofree_string_hash, opt_pass *> (256);
- if (name_to_pass_map->get (name))
+ if (m_name_to_pass_map->get (name))
return; /* Ignore plugin passes. */
- const char *unique_name = xstrdup (name);
- name_to_pass_map->put (unique_name, pass);
+ const char *unique_name = xstrdup (name);
+ m_name_to_pass_map->put (unique_name, pass);
}
/* Map from pass id to canonicalized pass name. */
@@ -882,14 +878,14 @@ passes_pass_traverse (const char *const &name, opt_pass *const &pass, void *)
/* The function traverses NAME_TO_PASS_MAP and creates a pass info
table for dumping purpose. */
-static void
-create_pass_tab (void)
+void
+pass_manager::create_pass_tab (void) const
{
if (!flag_dump_passes)
return;
- pass_tab.safe_grow_cleared (g->get_passes ()->passes_by_id_size + 1);
- name_to_pass_map->traverse <void *, passes_pass_traverse> (NULL);
+ pass_tab.safe_grow_cleared (passes_by_id_size + 1);
+ m_name_to_pass_map->traverse <void *, passes_pass_traverse> (NULL);
}
static bool override_gate_status (opt_pass *, tree, bool);
@@ -960,10 +956,10 @@ pass_manager::dump_passes () const
/* Returns the pass with NAME. */
-static opt_pass *
-get_pass_by_name (const char *name)
+opt_pass *
+pass_manager::get_pass_by_name (const char *name)
{
- opt_pass **p = name_to_pass_map->get (name);
+ opt_pass **p = m_name_to_pass_map->get (name);
if (p)
return *p;
@@ -1025,7 +1021,7 @@ enable_disable_pass (const char *arg, bool is_enable)
free (argstr);
return;
}
- pass = get_pass_by_name (phase_name);
+ pass = g->get_passes ()->get_pass_by_name (phase_name);
if (!pass || pass->static_pass_number == -1)
{
if (is_enable)
diff --git a/gcc/passes.def b/gcc/passes.def
index 834fea28aa6..993ed28628b 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -54,7 +54,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_build_ssa_passes);
PUSH_INSERT_PASSES_WITHIN (pass_build_ssa_passes)
NEXT_PASS (pass_fixup_cfg);
- NEXT_PASS (pass_init_datastructures);
NEXT_PASS (pass_build_ssa);
NEXT_PASS (pass_warn_nonnull_compare);
NEXT_PASS (pass_ubsan);
@@ -244,12 +243,14 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_cse_sincos);
NEXT_PASS (pass_optimize_bswap);
NEXT_PASS (pass_laddress);
+ NEXT_PASS (pass_lim);
NEXT_PASS (pass_split_crit_edges);
NEXT_PASS (pass_pre);
NEXT_PASS (pass_sink_code);
NEXT_PASS (pass_sancov);
NEXT_PASS (pass_asan);
NEXT_PASS (pass_tsan);
+ NEXT_PASS (pass_dce);
/* Pass group that runs when 1) enabled, 2) there are loops
in the function. Make sure to run pass_fix_loops before
to discover/remove loops before running the gate function
@@ -258,9 +259,6 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_tree_loop);
PUSH_INSERT_PASSES_WITHIN (pass_tree_loop)
NEXT_PASS (pass_tree_loop_init);
- NEXT_PASS (pass_lim);
- NEXT_PASS (pass_copy_prop);
- NEXT_PASS (pass_dce);
NEXT_PASS (pass_tree_unswitch);
NEXT_PASS (pass_scev_cprop);
NEXT_PASS (pass_record_bounds);
@@ -316,8 +314,8 @@ along with GCC; see the file COPYING3. If not see
only examines PHIs to discover const/copy propagation
opportunities. */
NEXT_PASS (pass_phi_only_cprop);
- NEXT_PASS (pass_cd_dce);
NEXT_PASS (pass_dse);
+ NEXT_PASS (pass_cd_dce);
NEXT_PASS (pass_forwprop);
NEXT_PASS (pass_phiopt);
NEXT_PASS (pass_fold_builtins);
diff --git a/gcc/po/ChangeLog b/gcc/po/ChangeLog
index 339de3c58b8..1eb55a2e9fe 100644
--- a/gcc/po/ChangeLog
+++ b/gcc/po/ChangeLog
@@ -1,3 +1,15 @@
+2016-05-18 Joseph Myers <joseph@codesourcery.com>
+
+ * da.po, sv.po: Update.
+
+2016-05-09 Joseph Myers <joseph@codesourcery.com>
+
+ * sv.po: Update.
+
+2016-05-02 Joseph Myers <joseph@codesourcery.com>
+
+ * sv.po, zh_CN.po: Update.
+
2016-04-30 Joseph Myers <joseph@codesourcery.com>
* zh_CN.po: Update.
diff --git a/gcc/po/da.po b/gcc/po/da.po
index 67aa3803101..b55d220924d 100644
--- a/gcc/po/da.po
+++ b/gcc/po/da.po
@@ -1,8 +1,8 @@
# Danish version of GCC strings.
-# Copyright (C) 2015 Free Software Foundation, Inc.
+# Copyright (C) 2016 Free Software Foundation, Inc.
# This file is distributed under the same license as the gcc package.
# Ole Laursen <olau@hardworking.dk>, 2001, 02, 03, 04.
-# Joe Hansen <joedalton2@yahoo.dk>, 2015.
+# Joe Hansen <joedalton2@yahoo.dk>, 2015, 2016.
#
# Konventioner:
#
@@ -30,6 +30,7 @@
# declared -> erklæret
# defaults to -> antages at være
# dereference -> følge
+# directory -> mappe
# discard -> fjerne
# discard -> kassere
# divide -> division
@@ -133,10 +134,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: gcc 5.2.0\n"
+"Project-Id-Version: gcc 6.1.0\n"
"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
"POT-Creation-Date: 2016-04-21 15:24+0000\n"
-"PO-Revision-Date: 2015-08-16 18:00+0200\n"
+"PO-Revision-Date: 2016-05-16 18:00+0200\n"
"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
"Language: da\n"
@@ -400,282 +401,196 @@ msgid "Options:\n"
msgstr "Tilvalg:\n"
#: gcc.c:3384
-#, fuzzy
-#| msgid " -pass-exit-codes Exit with highest error code from a phase\n"
msgid " -pass-exit-codes Exit with highest error code from a phase.\n"
-msgstr " -pass-exit-codes Afslut med den højeste fejlkode fra en fase\n"
+msgstr " -pass-exit-codes Afslut med den højeste fejlkode fra en fase.\n"
#: gcc.c:3385
-#, fuzzy
-#| msgid " --help Display this information\n"
msgid " --help Display this information.\n"
-msgstr " --help Vis disse oplysninger\n"
+msgstr " --help Vis disse oplysninger.\n"
#: gcc.c:3386
-#, fuzzy
-#| msgid " --target-help Display target specific command line options\n"
msgid " --target-help Display target specific command line options.\n"
-msgstr " --target-help Vis målspecifikke kommandolinjetilvalg\n"
+msgstr " --target-help Vis målspecifikke kommandolinjetilvalg.\n"
#: gcc.c:3387
msgid " --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...].\n"
msgstr ""
#: gcc.c:3388
-#, fuzzy
-#| msgid " Display specific types of command line options\n"
msgid " Display specific types of command line options.\n"
-msgstr " Vis specifikke typer af tilvalg for kommandolinjen\n"
+msgstr " Vis specifikke typer af tilvalg for kommandolinjen.\n"
#: gcc.c:3390
-#, fuzzy
-#| msgid " (Use '-v --help' to display command line options of sub-processes)\n"
msgid " (Use '-v --help' to display command line options of sub-processes).\n"
-msgstr " (benyt »-v --help« for at vise kommandolinjetilvalg for underprocesser)\n"
+msgstr " (benyt »-v --help« for at vise kommandolinjetilvalg for underprocesser).\n"
#: gcc.c:3391
-#, fuzzy
-#| msgid " --version Display compiler version information\n"
msgid " --version Display compiler version information.\n"
-msgstr " --version Udskriv oversætterens version\n"
+msgstr " --version Udskriv oversætterens version.\n"
#: gcc.c:3392
-#, fuzzy
-#| msgid " -dumpspecs Display all of the built in spec strings\n"
msgid " -dumpspecs Display all of the built in spec strings.\n"
-msgstr " -dumpspecs Vis alle de indbyggede specifikationsstrenge\n"
+msgstr " -dumpspecs Vis alle de indbyggede specifikationsstrenge.\n"
#: gcc.c:3393
-#, fuzzy
-#| msgid " -dumpversion Display the version of the compiler\n"
msgid " -dumpversion Display the version of the compiler.\n"
-msgstr " -dumpversion Vis oversætterens versionsnummer\n"
+msgstr " -dumpversion Vis oversætterens versionsnummer.\n"
#: gcc.c:3394
-#, fuzzy
-#| msgid " -dumpmachine Display the compiler's target processor\n"
msgid " -dumpmachine Display the compiler's target processor.\n"
-msgstr " -dumpmachine Vis oversætterens målprocessor\n"
+msgstr " -dumpmachine Vis oversætterens målprocessor.\n"
#: gcc.c:3395
-#, fuzzy
-#| msgid " -print-search-dirs Display the directories in the compiler's search path\n"
msgid " -print-search-dirs Display the directories in the compiler's search path.\n"
-msgstr " -print-search-dirs Vis katalogerne i oversætterens søgesti\n"
+msgstr " -print-search-dirs Vis mapperne i oversætterens søgesti.\n"
#: gcc.c:3396
-#, fuzzy
-#| msgid " -print-libgcc-file-name Display the name of the compiler's companion library\n"
msgid " -print-libgcc-file-name Display the name of the compiler's companion library.\n"
-msgstr " -print-libgcc-file-name Vis navnet på oversætterens tilhørende bibliotek\n"
+msgstr " -print-libgcc-file-name Vis navnet på oversætterens tilhørende bibliotek.\n"
#: gcc.c:3397
-#, fuzzy
-#| msgid " -print-file-name=<lib> Display the full path to library <lib>\n"
msgid " -print-file-name=<lib> Display the full path to library <lib>.\n"
-msgstr " -print-file-name=<bibl> Vis den komplette sti til biblioteket <bibl>\n"
+msgstr " -print-file-name=<bibl> Vis den komplette sti til biblioteket <bibl>.\n"
#: gcc.c:3398
-#, fuzzy
-#| msgid " -print-prog-name=<prog> Display the full path to compiler component <prog>\n"
msgid " -print-prog-name=<prog> Display the full path to compiler component <prog>.\n"
-msgstr " -print-prog-name=<prog> Vis den komplette sti til oversætterkomponenten <prog>\n"
+msgstr " -print-prog-name=<prog> Vis den komplette sti til oversætterkomponenten <prog>.\n"
#: gcc.c:3399
-#, fuzzy
-#| msgid ""
-#| " -print-multiarch Display the target's normalized GNU triplet, used as\n"
-#| " a component in the library path\n"
msgid ""
" -print-multiarch Display the target's normalized GNU triplet, used as\n"
" a component in the library path.\n"
msgstr ""
" -print-multi-lib Vis målets normaliseret GNU-triplet, brugt som\n"
-" en komponent i bibioteksstien\n"
+" en komponent i bibioteksstien.\n"
#: gcc.c:3402
-#, fuzzy
-#| msgid " -print-multi-directory Display the root directory for versions of libgcc\n"
msgid " -print-multi-directory Display the root directory for versions of libgcc.\n"
-msgstr " -print-multi-directory Vis rodkataloget for versioner af libgcc\n"
+msgstr " -print-multi-directory Vis rodmappen for versioner af libgcc.\n"
#: gcc.c:3403
-#, fuzzy
-#| msgid ""
-#| " -print-multi-lib Display the mapping between command line options and\n"
-#| " multiple library search directories\n"
msgid ""
" -print-multi-lib Display the mapping between command line options and\n"
" multiple library search directories.\n"
msgstr ""
" -print-multi-lib Vis afbildningen mellem kommandolinjetilvalg og\n"
-" flere bibliotekssøgekataloger\n"
+" flere bibliotekssøgemapper.\n"
#: gcc.c:3406
-#, fuzzy
-#| msgid " -print-multi-os-directory Display the relative path to OS libraries\n"
msgid " -print-multi-os-directory Display the relative path to OS libraries.\n"
-msgstr " -print-multi-os-directory Vis den relative sti for OS-biblioteker\n"
+msgstr " -print-multi-os-directory Vis den relative sti for OS-biblioteker.\n"
#: gcc.c:3407
-#, fuzzy
-#| msgid " -print-sysroot Display the target libraries directory\n"
msgid " -print-sysroot Display the target libraries directory.\n"
-msgstr " -print-sysroot Vis mappen for målets biblioteker\n"
+msgstr " -print-sysroot Vis mappen for målets biblioteker.\n"
#: gcc.c:3408
-#, fuzzy
-#| msgid " -print-sysroot-headers-suffix Display the sysroot suffix used to find headers\n"
msgid " -print-sysroot-headers-suffix Display the sysroot suffix used to find headers.\n"
-msgstr " -print-sysroot-headers-suffix Vis sysroot-suffikset brugt til at finde teksthoveder\n"
+msgstr " -print-sysroot-headers-suffix Vis sysroot-suffikset brugt til at finde teksthoveder.\n"
#: gcc.c:3409
-#, fuzzy
-#| msgid " -Wa,<options> Pass comma-separated <options> on to the assembler\n"
msgid " -Wa,<options> Pass comma-separated <options> on to the assembler.\n"
-msgstr " -Wa,<tilvalg> Videregiv komma-adskilte <tilvalg> til maskinkodeoversætteren\n"
+msgstr " -Wa,<tilvalg> Videregiv komma-adskilte <tilvalg> til maskinkodeoversætteren.\n"
#: gcc.c:3410
-#, fuzzy
-#| msgid " -Wp,<options> Pass comma-separated <options> on to the preprocessor\n"
msgid " -Wp,<options> Pass comma-separated <options> on to the preprocessor.\n"
-msgstr " -Wp,<tilvalg> Videregiv komma-adskilte <tilvalg> til præprocessoren\n"
+msgstr " -Wp,<tilvalg> Videregiv komma-adskilte <tilvalg> til forbrænderen.\n"
#: gcc.c:3411
-#, fuzzy
-#| msgid " -Wl,<options> Pass comma-separated <options> on to the linker\n"
msgid " -Wl,<options> Pass comma-separated <options> on to the linker.\n"
-msgstr " -Wl,<tilvalg> Videregiv komma-adskilte <tilvalg> til sammenkæderen\n"
+msgstr " -Wl,<tilvalg> Videregiv komma-adskilte <tilvalg> til sammenkæderen.\n"
#: gcc.c:3412
-#, fuzzy
-#| msgid " -Xassembler <arg> Pass <arg> on to the assembler\n"
msgid " -Xassembler <arg> Pass <arg> on to the assembler.\n"
-msgstr " -Xassembler <para> Videregiv <para> til maskinkodeoversætteren\n"
+msgstr " -Xassembler <para> Videregiv <para> til maskinkodeoversætteren.\n"
#: gcc.c:3413
-#, fuzzy
-#| msgid " -Xpreprocessor <arg> Pass <arg> on to the preprocessor\n"
msgid " -Xpreprocessor <arg> Pass <arg> on to the preprocessor.\n"
-msgstr " -Xpreprocessor <para> Videregiv <para> til forbrænderen\n"
+msgstr " -Xpreprocessor <para> Videregiv <para> til forbrænderen.\n"
#: gcc.c:3414
-#, fuzzy
-#| msgid " -Xlinker <arg> Pass <arg> on to the linker\n"
msgid " -Xlinker <arg> Pass <arg> on to the linker.\n"
-msgstr " -Xlinker <para> Videregiv <para> til sammenkæderen\n"
+msgstr " -Xlinker <para> Videregiv <para> til sammenkæderen.\n"
#: gcc.c:3415
-#, fuzzy
-#| msgid " -save-temps Do not delete intermediate files\n"
msgid " -save-temps Do not delete intermediate files.\n"
-msgstr " -save-temps Slet ikke midlertidige filer\n"
+msgstr " -save-temps Slet ikke midlertidige filer.\n"
#: gcc.c:3416
-#, fuzzy
-#| msgid " -save-temps=<arg> Do not delete intermediate files\n"
msgid " -save-temps=<arg> Do not delete intermediate files.\n"
-msgstr " -save-temps=<para> Slet ikke midlertidige filer\n"
+msgstr " -save-temps=<para> Slet ikke midlertidige filer.\n"
#: gcc.c:3417
msgid ""
" -no-canonical-prefixes Do not canonicalize paths when building relative\n"
" prefixes to other gcc components.\n"
msgstr ""
+" -no-canonical-prefixes Normaliser ikke stier når der bygges relative\n"
+" præfiks til andre gcc-komponenter.\n"
#: gcc.c:3420
-#, fuzzy
-#| msgid " -pipe Use pipes rather than intermediate files\n"
msgid " -pipe Use pipes rather than intermediate files.\n"
-msgstr " -pipe Brug datakanaler i stedet for midlertidige filer\n"
+msgstr " -pipe Brug datakanaler i stedet for midlertidige filer.\n"
#: gcc.c:3421
-#, fuzzy
-#| msgid " -time Time the execution of each subprocess\n"
msgid " -time Time the execution of each subprocess.\n"
-msgstr " -time Tag tid på udførslen af hver underproces\n"
+msgstr " -time Tag tid på udførslen af hver underproces.\n"
#: gcc.c:3422
-#, fuzzy
-#| msgid " -specs=<file> Override built-in specs with the contents of <file>\n"
msgid " -specs=<file> Override built-in specs with the contents of <file>.\n"
-msgstr " -specs=<fil> Overskriv indbyggede specifikationer med indholdet af <fil>\n"
+msgstr " -specs=<fil> Overskriv indbyggede specifikationer med indholdet af <fil>.\n"
#: gcc.c:3423
-#, fuzzy
-#| msgid " -std=<standard> Assume that the input sources are for <standard>\n"
msgid " -std=<standard> Assume that the input sources are for <standard>.\n"
-msgstr " -std=<standard> Antag at inddatakildekoden er skrevet til <standard>\n"
+msgstr " -std=<standard> Antag at inddatakildekoden er skrevet til <standard>.\n"
#: gcc.c:3424
msgid ""
" --sysroot=<directory> Use <directory> as the root directory for headers\n"
" and libraries.\n"
msgstr ""
+" --sysroot=<mappe> Brug <mappe> som rodmappen for teksthoveder\n"
+" og biblioteker.\n"
#: gcc.c:3427
-#, fuzzy
-#| msgid " -B <directory> Add <directory> to the compiler's search paths\n"
msgid " -B <directory> Add <directory> to the compiler's search paths.\n"
-msgstr " -B <katalog> Tilføj katalog til oversætterens søgestier\n"
+msgstr " -B <mappe> Tilføj mappe til oversætterens søgestier.\n"
#: gcc.c:3428
-#, fuzzy
-#| msgid " -v Display the programs invoked by the compiler\n"
msgid " -v Display the programs invoked by the compiler.\n"
-msgstr " -v Vis de programmer der startes af oversætteren\n"
+msgstr " -v Vis de programmer der startes af oversætteren.\n"
#: gcc.c:3429
-#, fuzzy
-#| msgid " -### Like -v but options quoted and commands not executed\n"
msgid " -### Like -v but options quoted and commands not executed.\n"
msgstr ""
" -### Som '-v', men tilvalg anbringes i anførselstegn\n"
-" og kommandoerne udføres ikke\n"
+" og kommandoerne udføres ikke.\n"
#: gcc.c:3430
-#, fuzzy
-#| msgid " -E Preprocess only; do not compile, assemble or link\n"
msgid " -E Preprocess only; do not compile, assemble or link.\n"
-msgstr " -E Forbehandl kun; oversæt og sammenkæd ikke\n"
+msgstr " -E Forbehandl kun; oversæt, maskinkodeoversæt og sammenkæd ikke.\n"
#: gcc.c:3431
-#, fuzzy
-#| msgid " -S Compile only; do not assemble or link\n"
msgid " -S Compile only; do not assemble or link.\n"
-msgstr " -S Oversæt kun; maskinekodeoversæt og sammenkæd ikke\n"
+msgstr " -S Oversæt kun; maskinekodeoversæt og sammenkæd ikke.\n"
#: gcc.c:3432
-#, fuzzy
-#| msgid " -c Compile and assemble, but do not link\n"
msgid " -c Compile and assemble, but do not link.\n"
-msgstr " -c Oversæt, også til maskinkode, men sammenkæd ikke\n"
+msgstr " -c Oversæt, også til maskinkode, men sammenkæd ikke.\n"
#: gcc.c:3433
-#, fuzzy
-#| msgid " -o <file> Place the output into <file>\n"
msgid " -o <file> Place the output into <file>.\n"
-msgstr " -o <fil> Anbring uddataene i <fil>\n"
+msgstr " -o <fil> Anbring uddataene i <fil>.\n"
#: gcc.c:3434
-#, fuzzy
-#| msgid " -pie Create a position independent executable\n"
msgid " -pie Create a position independent executable.\n"
-msgstr " -pie Opret en positionsuafhængig kørbar fil\n"
+msgstr " -pie Opret en positionsuafhængig kørbar fil.\n"
#: gcc.c:3435
-#, fuzzy
-#| msgid " -shared Create a shared library\n"
msgid " -shared Create a shared library.\n"
-msgstr " -shared Opret et delt bibliotek\n"
+msgstr " -shared Opret et delt bibliotek.\n"
#: gcc.c:3436
-#, fuzzy
-#| msgid ""
-#| " -x <language> Specify the language of the following input files\n"
-#| " Permissible languages include: c c++ assembler none\n"
-#| " 'none' means revert to the default behavior of\n"
-#| " guessing the language based on the file's extension\n"
msgid ""
" -x <language> Specify the language of the following input files.\n"
" Permissible languages include: c c++ assembler none\n"
@@ -684,8 +599,8 @@ msgid ""
msgstr ""
" -x <sprog> Angiv sproget for de følgende inddatafiler.\n"
" Tilladte sprog inkluderer: c c++ assembler none\n"
-" 'none' betyder at standardopførslen med at gætte\n"
-" sproget på filendelsen udføres\n"
+" »none« betyder at standardopførslen med at gætte\n"
+" sproget på filendelsen udføres.\n"
#: gcc.c:3443
#, c-format
@@ -699,7 +614,7 @@ msgstr ""
"Tilvalg der begynder med -g, -f, -m, -O, -W eller --param bliver automatisk\n"
" givet videre til de forskellige underprocesser som %s starter. For at\n"
" videregive andre indstillinger til disse processer kan tilvalg på formen\n"
-" '-W<bogstav>' bruges.\n"
+" »-W<bogstav>« bruges.\n"
#: gcc.c:5876
#, c-format
@@ -734,12 +649,12 @@ msgstr "gcc-styringsprogram version %s %skører gcc-version %s\n"
#: gcc.c:6682 gcc.c:6894
#, c-format
msgid "The bug is not reproducible, so it is likely a hardware or OS problem.\n"
-msgstr ""
+msgstr "Fejlen kan ikke genskabes, så det er sandsynligvis et udstyrsproblem eller et problem med operativsystemet.\n"
#: gcc.c:6818
#, c-format
msgid "Preprocessed source stored into %s file, please attach this to your bugreport.\n"
-msgstr ""
+msgstr "Forbrændt kilde lagret i %s-filen, vedhæft venligst den til din fejlrapport.\n"
#: gcc.c:7757
#, c-format
@@ -793,6 +708,10 @@ msgid ""
"==============\n"
"\n"
msgstr ""
+"\n"
+"Tilvalg for sammenkæder\n"
+"==============\n"
+"\n"
#: gcc.c:8205
#, c-format
@@ -800,6 +719,8 @@ msgid ""
"Use \"-Wl,OPTION\" to pass \"OPTION\" to the linker.\n"
"\n"
msgstr ""
+"Brug »-Wl,TILVALG« for at sende »TILVALG« til sammenkæderen.\n"
+"\n"
#: gcc.c:9497
#, c-format
@@ -808,6 +729,9 @@ msgid ""
"=================\n"
"\n"
msgstr ""
+"Tilvalg for maskinkodeoversætteren\n"
+"=================\n"
+"\n"
#: gcc.c:9498
#, c-format
@@ -815,11 +739,13 @@ msgid ""
"Use \"-Wa,OPTION\" to pass \"OPTION\" to the assembler.\n"
"\n"
msgstr ""
+"Brug »-Wa,TILVALG« til at sende »TILVALG« til maskinkodeoversætteren.\n"
+"\n"
#: gcov-tool.c:166
#, c-format
msgid " merge [options] <dir1> <dir2> Merge coverage file contents\n"
-msgstr ""
+msgstr " merge [tilvalg] <map1> <map2> Sammenføj dækningsfilindhold\n"
#: gcov-tool.c:167 gcov-tool.c:261 gcov-tool.c:417
#, c-format
@@ -827,10 +753,9 @@ msgid " -v, --verbose Verbose mode\n"
msgstr " -v, --verbose Uddybende tilstand\n"
#: gcov-tool.c:168 gcov-tool.c:262
-#, fuzzy, c-format
-#| msgid " -n, --no-output Do not create an output file\n"
+#, c-format
msgid " -o, --output <dir> Output directory\n"
-msgstr " -n, --no-output Opret ikke en uddatafil\n"
+msgstr " -o, --output <map> Vis mappe\n"
#: gcov-tool.c:169
#, c-format
@@ -840,12 +765,12 @@ msgstr ""
#: gcov-tool.c:185
#, c-format
msgid "Merge subcomand usage:"
-msgstr ""
+msgstr "Sammenføj brug af underkommando:"
#: gcov-tool.c:260
#, c-format
msgid " rewrite [options] <dir> Rewrite coverage file contents\n"
-msgstr ""
+msgstr " rewrite [tilvalg] <map> Genskriv dækningsfilindhold\n"
#: gcov-tool.c:263
#, c-format
@@ -875,46 +800,42 @@ msgstr ""
#: gcov-tool.c:359
#, c-format
msgid "normalization cannot co-exist with scaling\n"
-msgstr ""
+msgstr "normalisering kan ikke sameksistere med skalering\n"
#: gcov-tool.c:416
#, c-format
msgid " overlap [options] <dir1> <dir2> Compute the overlap of two profiles\n"
-msgstr ""
+msgstr " overlap [tilvalg] <map1> <map2> Beregn overlap for to profiler\n"
#: gcov-tool.c:418
-#, fuzzy, c-format
-#| msgid " -h, --help Print this help, then exit\n"
+#, c-format
msgid " -h, --hotonly Only print info for hot objects/functions\n"
-msgstr " -h, --help Udskriv denne hjælp og afslut\n"
+msgstr " -h, --hotonly Udskriv kun info for varme objekter/funktioner\n"
#: gcov-tool.c:419
-#, fuzzy, c-format
-#| msgid " -p Enable function profiling\n"
+#, c-format
msgid " -f, --function Print function level info\n"
-msgstr " -p Aktivér funktionsprofilering\n"
+msgstr " -f, --function Udskriv info om funktionsniveau\n"
#: gcov-tool.c:420
-#, fuzzy, c-format
-#| msgid " -h, --help Print this help, then exit\n"
+#, c-format
msgid " -F, --fullname Print full filename\n"
-msgstr " -h, --help Udskriv denne hjælp og afslut\n"
+msgstr " -F, --fullname Udskriv fuldt filnavn\n"
#: gcov-tool.c:421
-#, fuzzy, c-format
-#| msgid " -h, --help Print this help, then exit\n"
+#, c-format
msgid " -o, --object Print object level info\n"
-msgstr " -h, --help Udskriv denne hjælp og afslut\n"
+msgstr " -o, --object Udskriv info på objektniveau\n"
#: gcov-tool.c:422
#, c-format
msgid " -t <float>, --hot_threshold <float> Set the threshold for hotness\n"
-msgstr ""
+msgstr " -t <float>, --hot_threshold <float> Angiv tærskel for varme\n"
#: gcov-tool.c:442
#, c-format
msgid "Overlap subcomand usage:"
-msgstr ""
+msgstr "Overlap brug af underkommando:"
#: gcov-tool.c:508
#, c-format
@@ -956,21 +877,22 @@ msgstr ""
"%s.\n"
#: gcov-tool.c:526
-#, fuzzy, c-format
-#| msgid "Copyright %s 2014-2015 Free Software Foundation, Inc.\n"
+#, c-format
msgid "Copyright %s 2014-2016 Free Software Foundation, Inc.\n"
-msgstr "Ophavsret %s 2014-2015 Free Software Foundation, Inc.\n"
+msgstr "Ophavsret %s 2014-2016 Free Software Foundation, Inc.\n"
#: gcov-tool.c:529 gcov.c:506
-#, fuzzy, c-format
+#, c-format
msgid ""
"This is free software; see the source for copying conditions.\n"
"There is NO warranty; not even for MERCHANTABILITY or \n"
"FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n"
msgstr ""
-"Dette er et frit program; se kildekoden for kopieringsbetingelser. Der er\n"
-"INGEN garanti; ikke engang for SALGBARHED eller BRUGBARHED TIL NOGET FORMÅL.\n"
+"Dette er et frit program; se kildekoden for kopieringsbetingelser.\n"
+"Der er INGEN garanti; ikke engang for SALGBARHED eller\n"
+"BRUGBARHED TIL NOGET FORMÅL.\n"
+"\n"
#: gcov.c:472
#, c-format
@@ -1015,10 +937,9 @@ msgstr ""
" for procenter\n"
#: gcov.c:479
-#, fuzzy, c-format
-#| msgid " --help Display this information\n"
+#, c-format
msgid " -d, --display-progress Display progress information\n"
-msgstr " --help Vis disse oplysninger\n"
+msgstr " -d, --display-progress Vis statusinformation\n"
#: gcov.c:480
#, c-format
@@ -1028,14 +949,16 @@ msgstr " -f, --function-summaries Udskriv sammendrag for hver funktion\n
#: gcov.c:481
#, c-format
msgid " -i, --intermediate-format Output .gcov file in intermediate text format\n"
-msgstr ""
+msgstr " -i, --intermediate-format Vis .gcov-filen i melleliggende tekstformat\n"
#: gcov.c:482
#, c-format
msgid ""
" -l, --long-file-names Use long output file names for included\n"
" source files\n"
-msgstr " -l, --long-file-names Brug lange filnavne til inkluderede kildefiler\n"
+msgstr ""
+" -l, --long-file-names Brug lange filnavne til inkluderede\n"
+" kildefiler\n"
#: gcov.c:484
#, c-format
@@ -1058,10 +981,9 @@ msgid " -p, --preserve-paths Preserve all pathname components\n"
msgstr " -p, --preserve-paths Bevar alle stinavnskomponenter\n"
#: gcov.c:488
-#, fuzzy, c-format
-#| msgid " -a, --all-blocks Show information for every basic block\n"
+#, c-format
msgid " -r, --relative-only Only show data for relative sources\n"
-msgstr " -a, --all-blocks Vis oplysninger for alle basisblokke\n"
+msgstr " -r, --relative-only Vis kun data for relative kilder\n"
#: gcov.c:489
#, c-format
@@ -1119,10 +1041,9 @@ msgid "%s:source file is newer than notes file '%s'\n"
msgstr "%s: kildefil er nyere end notefil »%s«\n"
#: gcov.c:1144
-#, fuzzy, c-format
-#| msgid "(the message is only displayed one per source file)\n"
+#, c-format
msgid "(the message is displayed only once per source file)\n"
-msgstr "(beskeden er kun vist en per kildefil)\n"
+msgstr "(beskeden er kun vist en gang per kildefil)\n"
#: gcov.c:1169
#, c-format
@@ -1180,19 +1101,19 @@ msgid "%s:unknown function '%u'\n"
msgstr "%s:ukendt funktion »%u«\n"
#: gcov.c:1466
-#, fuzzy, c-format
+#, c-format
msgid "%s:profile mismatch for '%s'\n"
-msgstr "%s før '%s'"
+msgstr "%s:forskelige profiler for »%s«\n"
#: gcov.c:1485
-#, fuzzy, c-format
+#, c-format
msgid "%s:overflowed\n"
-msgstr "%s: overløbsintervalfejl"
+msgstr "%s: overløb\n"
#: gcov.c:1531
#, c-format
msgid "%s:'%s' lacks entry and/or exit blocks\n"
-msgstr ""
+msgstr "%s:»%s« mangler indgangs- og/eller afslutningsblokke\n"
#: gcov.c:1536
#, c-format
@@ -1205,9 +1126,9 @@ msgid "%s:'%s' has arcs from exit block\n"
msgstr ""
#: gcov.c:1752
-#, fuzzy, c-format
+#, c-format
msgid "%s:graph is unsolvable for '%s'\n"
-msgstr "%s før '%s'"
+msgstr "%s:graf kan ikke løses for »%s«\n"
#: gcov.c:1860
#, c-format
@@ -1310,17 +1231,17 @@ msgstr "funktion kan returnere adressen på en lokal variabel"
#: incpath.c:72
#, c-format
msgid "ignoring duplicate directory \"%s\"\n"
-msgstr "ignorerer mere end én angivelse af kataloget \"%s\"\n"
+msgstr "ignorerer mere end en angivelse af mappen »%s«\n"
#: incpath.c:75
#, c-format
msgid " as it is a non-system directory that duplicates a system directory\n"
-msgstr " da det er et ikke-systemkatalog som dublerer et systemkatalog\n"
+msgstr " da det ikke er en systemmappe, som dublerer en systemmappe\n"
#: incpath.c:79
#, c-format
msgid "ignoring nonexistent directory \"%s\"\n"
-msgstr "ignorerer det ikke-eksisterende katalog \"%s\"\n"
+msgstr "ignorerer den ikkeeksisterende mappe »%s«\n"
#: incpath.c:373
#, c-format
@@ -1348,64 +1269,55 @@ msgid "'"
msgstr "«"
#: ipa-pure-const.c:187
-#, fuzzy
-#| msgid "function might be possible candidate for attribute `noreturn'"
msgid "function might be candidate for attribute %<%s%>"
-msgstr "funktion er muligvis en kandidat til egenskaben 'noreturn'"
+msgstr "funktion er muligvis en kandidat til egenskaben %<%s%>"
#: ipa-pure-const.c:188
-#, fuzzy
-#| msgid "function might be possible candidate for attribute `noreturn'"
msgid "function might be candidate for attribute %<%s%> if it is known to return normally"
-msgstr "funktion er muligvis en kandidat til egenskaben 'noreturn'"
+msgstr "funktion er muligvis en kandidat til egenskaben %<%s%>, hvis den vides at returnere normalt"
#: langhooks.c:373
msgid "At top level:"
msgstr "Ved øverste niveau:"
#: langhooks.c:393 cp/error.c:3299
-#, fuzzy, c-format
-#| msgid "In member function `%s':"
+#, c-format
msgid "In member function %qs"
-msgstr "I medlemsfunktionen '%s':"
+msgstr "I medlemsfunktionen %qs"
#: langhooks.c:397 cp/error.c:3302
-#, fuzzy, c-format
-#| msgid "In function `%s':"
+#, c-format
msgid "In function %qs"
-msgstr "I funktionen '%s':"
+msgstr "I funktionen %qs"
#: langhooks.c:448 cp/error.c:3252
msgid " inlined from %qs at %r%s:%d:%d%R"
-msgstr ""
+msgstr " indlejret fra %qs ved %r%s:%d:%d%R"
#: langhooks.c:453 cp/error.c:3257
-#, fuzzy
-#| msgid "In file included from %s:%d"
msgid " inlined from %qs at %r%s:%d%R"
-msgstr "I filen inkluderet af %s:%d"
+msgstr " indlejret fra %qs ved %r%s:%d%R"
#: langhooks.c:459 cp/error.c:3263
-#, fuzzy, c-format
-#| msgid "In file included from %s:%u"
+#, c-format
msgid " inlined from %qs"
-msgstr "I filen inkluderet af %s:%u"
+msgstr " indlejret fra %qs"
#: loop-iv.c:3041 tree-ssa-loop-niter.c:2319
msgid "assuming that the loop is not infinite"
-msgstr ""
+msgstr "antager at loopet ikke er uendeligt"
#: loop-iv.c:3042 tree-ssa-loop-niter.c:2320
msgid "cannot optimize possibly infinite loops"
-msgstr ""
+msgstr "kan ikke opitmere eventuelle uendelige loop"
#: loop-iv.c:3050 tree-ssa-loop-niter.c:2324
msgid "assuming that the loop counter does not overflow"
-msgstr ""
+msgstr "antager at looptælleren ikke løber over"
#: loop-iv.c:3051 tree-ssa-loop-niter.c:2325
msgid "cannot optimize loop, the loop counter may overflow"
-msgstr ""
+msgstr "kan ikke optimere loop, looptælleren kan løbe over"
#: lra-assigns.c:1417 reload1.c:2089
msgid "this is the insn:"
@@ -1417,53 +1329,49 @@ msgstr "kunne ikke generere genindlæsninger for:"
#. What to print when a switch has no documentation.
#: opts.c:184
-#, fuzzy
-#| msgid "This switch lacks documentation"
msgid "This option lacks documentation."
-msgstr "Denne switch mangler dokumentation"
+msgstr "Dette tilvalg mangler dokumentation."
#: opts.c:185
msgid "Uses of this option are diagnosed."
-msgstr ""
+msgstr "Brug af dette tilvalg diagnosticeres."
#: opts.c:1061
#, c-format
msgid "default %d minimum %d maximum %d"
-msgstr ""
+msgstr "standard %d minimum %d maksimum %d"
#: opts.c:1128
#, c-format
msgid "Same as %s. Use the latter option instead."
-msgstr ""
+msgstr "Samme som %s. Brug det sidste tilvalg i stedet."
#: opts.c:1136
#, c-format
msgid "%s Same as %s."
-msgstr ""
+msgstr "%s Samme som %s."
#: opts.c:1207
msgid "[default]"
-msgstr ""
+msgstr "[standard]"
#: opts.c:1218
msgid "[enabled]"
-msgstr ""
+msgstr "[aktiveret]"
#: opts.c:1218
-#, fuzzy
-#| msgid "GCSE disabled"
msgid "[disabled]"
-msgstr "GCSE deaktiveret"
+msgstr "[deaktiveret]"
#: opts.c:1237
#, c-format
msgid " No options with the desired characteristics were found\n"
-msgstr ""
+msgstr " Ingen tilvalg med de ønskede karakteristika blev fundet\n"
#: opts.c:1246
#, c-format
msgid " None found. Use --help=%s to show *all* the options supported by the %s front-end.\n"
-msgstr ""
+msgstr " Ingen fundet. Brug --help=%s for at vise *alle* tilvalgene understøttet af brugerfladen %s.\n"
#: opts.c:1252
#, c-format
@@ -1479,21 +1387,16 @@ msgid "The following options control compiler warning messages"
msgstr "De følgende tilvalg kontrollerer advarselsbeskeder for oversætteren"
#: opts.c:1343
-#, fuzzy
msgid "The following options control optimizations"
-msgstr "Udfør løkkeoptimeringerne"
+msgstr "De følgende tilvalg kontrollerer optimeringer"
#: opts.c:1346 opts.c:1385
-#, fuzzy
-#| msgid "The following options are language-independent:\n"
msgid "The following options are language-independent"
-msgstr "De følgende tilvalg er sproguafhængige:\n"
+msgstr "De følgende tilvalg er sproguafhængige"
#: opts.c:1349
-#, fuzzy
-#| msgid "The --param option recognizes the following as parameters:\n"
msgid "The --param option recognizes the following as parameters"
-msgstr "Tilvalget --param genkender følgende som parametre:\n"
+msgstr "Tilvalget --param genkender følgende som parametre"
#: opts.c:1355
msgid "The following options are specific to just the language "
@@ -1508,16 +1411,12 @@ msgid "The following options are not documented"
msgstr "De følgende tilvalg er ikke dokumenterede"
#: opts.c:1370
-#, fuzzy
-#| msgid "The following options are language-independent:\n"
msgid "The following options take separate arguments"
-msgstr "De følgende tilvalg er sproguafhængige:\n"
+msgstr "De følgende tilvalg anvender forskellige parametre"
#: opts.c:1372
-#, fuzzy
-#| msgid "The following options are language-independent:\n"
msgid "The following options take joined arguments"
-msgstr "De følgende tilvalg er sproguafhængige:\n"
+msgstr "De følgende tilvalg anvender fælles parametre"
#: opts.c:1383
msgid "The following options are language-related"
@@ -1534,7 +1433,7 @@ msgstr "Udvidelsesmoduler"
#: plugin.c:828
#, c-format
msgid "*** WARNING *** there are active plugins, do not report this as a bug unless you can reproduce it without enabling any plugins.\n"
-msgstr ""
+msgstr "*** ADVARSEL *** der er aktive udvidelsesmoduler, rapporter ikke dette som en fejl med mindre, at du kan genskabe det uden at udvidelsesmoduler er aktiveret.\n"
#. It's the compiler's fault.
#: reload1.c:6113
@@ -1593,39 +1492,33 @@ msgid "collect: relinking\n"
msgstr "collect: kæder sammen igen\n"
#: toplev.c:331
-#, fuzzy, c-format
-#| msgid "internal error"
+#, c-format
msgid "unrecoverable error"
-msgstr "intern fejl"
+msgstr "uoprettelig fejl"
#: toplev.c:640
-#, fuzzy, c-format
-#| msgid ""
-#| "%s%s%s version %s (%s)\n"
-#| "%s\tcompiled by GNU C version %s.\n"
-#| "%s%s%s version %s (%s) compiled by CC.\n"
+#, c-format
msgid ""
"%s%s%s %sversion %s (%s)\n"
"%s\tcompiled by GNU C version %s, "
msgstr ""
-"%s%s%s version %s (%s)\n"
-"%s\toversat af GNU C version %s.\n"
-"%s%s%s version %s (%s) oversat af CC.\n"
+"%s%s%s %sversion %s (%s)\n"
+"%s\toversat af GNU C version %s, "
#: toplev.c:642
#, c-format
msgid "%s%s%s %sversion %s (%s) compiled by CC, "
-msgstr ""
+msgstr "%s%s%s %sversion %s (%s) oversat af CC, "
#: toplev.c:646
#, c-format
msgid "GMP version %s, MPFR version %s, MPC version %s, isl version %s\n"
-msgstr ""
+msgstr "GMP-version %s, MPFR-version %s, MPC-version %s, isl-version %s\n"
#: toplev.c:648
#, c-format
msgid "%s%swarning: %s header version %s differs from library version %s.\n"
-msgstr ""
+msgstr "%s%sadvarsel: %s teksthovedversion %s svarer ikke til biblioteksversion %s.\n"
#: toplev.c:650
#, c-format
@@ -1647,63 +1540,56 @@ msgid "<anonymous>"
msgstr "<anonym>"
#: cif-code.def:39
-#, fuzzy
msgid "function not considered for inlining"
-msgstr "funktion kan ikke indbygges"
+msgstr "funktion overvejes ikke for indbygning"
#: cif-code.def:43
msgid "caller is not optimized"
-msgstr ""
+msgstr "kalder er ikke optimeret"
#: cif-code.def:47
-#, fuzzy
msgid "function body not available"
-msgstr "funktion kan ikke indbygges"
+msgstr "funktionskrop er ikke tilgængelig"
#: cif-code.def:51
-#, fuzzy
msgid "redefined extern inline functions are not considered for inlining"
-msgstr "Advar når en inline funktion ikke kan indbygges"
+msgstr "omdefinerede eksterne indbyggede funktioner overvejes ikke for indlejring"
#: cif-code.def:56
-#, fuzzy
msgid "function not inlinable"
msgstr "funktion kan ikke indbygges"
#: cif-code.def:60
-#, fuzzy
-#| msgid "function cannot be inline"
msgid "function body can be overwritten at link time"
-msgstr "funktion kan ikke indbygges"
+msgstr "funktionskrop kan ikke overskrives på sammenkædningstidspunktet"
#: cif-code.def:64
-#, fuzzy
msgid "function not inline candidate"
-msgstr "funktion kan ikke indbygges"
+msgstr "funktion er ikke en indbygningskandidat"
#: cif-code.def:68
msgid "--param large-function-growth limit reached"
-msgstr ""
+msgstr "--param large-function-growth grænse nået"
#: cif-code.def:70
msgid "--param large-stack-frame-growth limit reached"
-msgstr ""
+msgstr "--param large-stack-frame-growth grænse nået"
#: cif-code.def:72
msgid "--param max-inline-insns-single limit reached"
-msgstr ""
+msgstr "--param max-inline-insns-single grænse nået"
#: cif-code.def:74
msgid "--param max-inline-insns-auto limit reached"
-msgstr ""
+msgstr "--param max-inline-insns-auto grænse nået"
#: cif-code.def:76
msgid "--param inline-unit-growth limit reached"
-msgstr ""
+msgstr "--param inline-unit-growth grænse nået"
#: cif-code.def:80
msgid "recursive inlining"
-msgstr ""
+msgstr "rekursiv indbygning"
#: cif-code.def:84
msgid "call is unlikely and code size would grow"
@@ -1760,7 +1646,7 @@ msgstr ""
#: cif-code.def:125
msgid "function attribute mismatch"
-msgstr ""
+msgstr "forskellige funktionsattributter"
#: cif-code.def:129
#, fuzzy
@@ -1770,7 +1656,7 @@ msgstr "funktion der bruger alloca, kan ikke indbygges"
#: cif-code.def:133
msgid "unreachable"
-msgstr ""
+msgstr "kan ikke nås"
#. The remainder are real diagnostic types.
#: diagnostic.def:33
@@ -1830,10 +1716,9 @@ msgid "The minimal estimated speedup allowing inliner to ignore inline-insns-sin
msgstr ""
#: params.def:71
-#, fuzzy, no-c-format
-#| msgid "The maximum number of instructions in a single function eligible for inlining"
+#, no-c-format
msgid "The maximum number of instructions in a single function eligible for inlining."
-msgstr "Det maksimale antal instruktioner i en enkelt funktion der må indbygges"
+msgstr "Det maksimale antal instruktioner i en enkelt funktion der må indbygges."
#: params.def:83
#, fuzzy, no-c-format
@@ -6049,10 +5934,9 @@ msgid " --classpath PATH Set path to find .class files\n"
msgstr ""
#: java/jcf-dump.c:1211
-#, fuzzy, c-format
-#| msgid " -B <directory> Add <directory> to the compiler's search paths\n"
+#, c-format
msgid " -IDIR Append directory to class path\n"
-msgstr " -B <katalog> Tilføj katalog til oversætterens søgestier\n"
+msgstr " -IDIR Tilføj mappe til klassesti\n"
#: java/jcf-dump.c:1212
#, c-format
@@ -18938,16 +18822,14 @@ msgid "Cannot read string table from %s."
msgstr ""
#: auto-profile.c:912
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "cannot find file for class %s"
+#, gcc-internal-format, gfc-internal-format
msgid "Cannot read function profile from %s."
-msgstr "kan ikke finde filen for klassen %s"
+msgstr "kan ikke læse funktionsprofil fra %s."
#: auto-profile.c:919
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "%s: cannot get working directory: %s\n"
+#, gcc-internal-format, gfc-internal-format
msgid "Cannot read working set from %s."
-msgstr "%s: kan ikke få fat i arbejdskataloget: %s\n"
+msgstr "Kan ikke læse arbejdssæt fra %s."
#: bt-load.c:1566
#, gcc-internal-format
@@ -21159,20 +21041,19 @@ msgid "error in removing %s\n"
msgstr "fejl ved skrivning til %s"
#: gcov-tool.c:103
-#, fuzzy, gcc-internal-format, gfc-internal-format
+#, gcc-internal-format, gfc-internal-format
msgid "Cannot make directory %s"
-msgstr "kan ikke oprette kataloget %s"
+msgstr "Kan ikke oprette mappen %s"
#: gcov-tool.c:111
-#, fuzzy, gcc-internal-format
-#| msgid "can't get current directory"
+#, gcc-internal-format
msgid "Cannot get current directory name"
-msgstr "kan ikke få fat i det aktuelle katalog"
+msgstr "Kan ikke få fat i det aktuelle mappenavn"
#: gcov-tool.c:115 gcov-tool.c:121
-#, fuzzy, gcc-internal-format, gfc-internal-format
+#, gcc-internal-format, gfc-internal-format
msgid "Cannot change directory to %s"
-msgstr "kan ikke oprette kataloget %s"
+msgstr "Kan ikke ændre mappen til %s"
#: gcov-tool.c:214
#, gcc-internal-format
@@ -21205,10 +21086,9 @@ msgid "DEF_INTERNAL_INT_FN (%s) has no associated built-in functions"
msgstr ""
#: gentarget-def.c:126
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "invalid operand code `%c'"
+#, gcc-internal-format, gfc-internal-format
msgid "invalid prototype for '%s'"
-msgstr "ugyldig operandkode '%c'"
+msgstr "ugyldig prototype for »%s«"
#: gentarget-def.c:131
#, gcc-internal-format, gfc-internal-format
@@ -22149,10 +22029,9 @@ msgid "Reference statement index not found"
msgstr "Advar hvis forældede tomme sætninger bliver fundet"
#: lto-streamer-in.c:1513
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "%s: cannot get working directory: %s\n"
+#, gcc-internal-format, gfc-internal-format
msgid "cannot read LTO mode table from %s"
-msgstr "%s: kan ikke få fat i arbejdskataloget: %s\n"
+msgstr "kan ikke læse LTO-tilstandstabel fra %s"
#: lto-streamer-in.c:1611
#, fuzzy, gcc-internal-format, gfc-internal-format
@@ -28174,9 +28053,9 @@ msgid "too late for # directive to set debug directory"
msgstr ""
#: c-family/c-pch.c:110
-#, fuzzy, gcc-internal-format
+#, gcc-internal-format
msgid "can%'t create precompiled header %s: %m"
-msgstr "kan ikke oprette kataloget %s"
+msgstr "kan ikke oprette prækompileret teksthoved %s: %m"
#: c-family/c-pch.c:133
#, fuzzy, gcc-internal-format
@@ -62004,21 +61883,19 @@ msgid "Contained procedure %qs at %L of a PURE procedure must also be PURE"
msgstr ""
#: fortran/scanner.c:330
-#, fuzzy, gcc-internal-format
+#, gcc-internal-format
msgid "Include directory %qs: %s"
-msgstr "kan ikke oprette kataloget %s"
+msgstr "Inkluder mappe %qs: %s"
#: fortran/scanner.c:334
-#, fuzzy, gcc-internal-format
-#| msgid "ignoring nonexistent directory \"%s\"\n"
+#, gcc-internal-format
msgid "Nonexistent include directory %qs"
-msgstr "ignorerer det ikke-eksisterende katalog \"%s\"\n"
+msgstr "Ikkeeksisterende include-mappe %qs"
#: fortran/scanner.c:339
-#, fuzzy, gcc-internal-format
-#| msgid "%s: Not a directory"
+#, gcc-internal-format
msgid "%qs is not a directory"
-msgstr "%s: ikke et katalog"
+msgstr "%qs er ikke en mappe"
#: fortran/scanner.c:742
#, gcc-internal-format, gfc-internal-format
@@ -66051,18 +65928,12 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ msgid "%s: usage '%s [ -VqfnkN ] [ -i <istring> ] [ filename ... ]'\n"
#~ msgstr "%s: brug '%s [ -VqfnkN ] [ -i <istreng> ] [ filenavn ... ]'\n"
-#~ msgid "%s: usage '%s [ -VqfnkNlgC ] [ -B <dirname> ] [ filename ... ]'\n"
-#~ msgstr "%s: brug '%s [ -VqfnkNlgC ] [ -B <katalognavn> ] [ filnavn ... ]'\n"
-
#~ msgid "%s: warning: no read access for file `%s'\n"
#~ msgstr "%s: advarsel: ingen læseadgang til filen '%s'\n"
#~ msgid "%s: warning: no write access for file `%s'\n"
#~ msgstr "%s: advarsel: ingen skriveadgang til filen '%s'\n"
-#~ msgid "%s: warning: no write access for dir containing `%s'\n"
-#~ msgstr "%s: advarsel: ingen skriveadgang til kataloget der indeholder '%s'\n"
-
#~ msgid "%s: invalid file name: %s\n"
#~ msgstr "%s: ugyldigt filnavn: %s\n"
@@ -69189,23 +69060,6 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ " -isystem <ktlg> Føj <ktlg> til begyndelsen af systeminkluderingsstien\n"
#~ msgid ""
-#~ " -idirafter <dir> Add <dir> to the end of the system include path\n"
-#~ " -I <dir> Add <dir> to the end of the main include path\n"
-#~ " -I- Fine-grained include path control; see info docs\n"
-#~ " -nostdinc Do not search system include directories\n"
-#~ " (dirs specified with -isystem will still be used)\n"
-#~ " -nostdinc++ Do not search system include directories for C++\n"
-#~ " -o <file> Put output into <file>\n"
-#~ msgstr ""
-#~ " -idirafter <ktlg> Føj <ktlg> til slutningen af systeminkluderingsstien\n"
-#~ " -I <ktlg> Føj <ktlg> til slutningen af den alm. inkluderingssti\n"
-#~ " -I- Nøje kontrolleret inkluderingssti; se info-hjælpen\n"
-#~ " -nostdinc Søg ikke i systeminkluderingskataloger\n"
-#~ " (kataloger angivet med -isystem søges dog stadig)\n"
-#~ " -nostdinc++ Søg ikke i systeminkluderingskataloger til C++\n"
-#~ " -o <fil> Send uddata til <fil>\n"
-
-#~ msgid ""
#~ " -trigraphs Support ISO C trigraphs\n"
#~ " -std=<std name> Specify the conformance standard; one of:\n"
#~ " gnu89, gnu99, c89, c99, iso9899:1990,\n"
@@ -69404,9 +69258,6 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ msgid "absolute file name in remap_filename"
#~ msgstr "absolut filnavn i remap_filename"
-#~ msgid "directory name missing after %s"
-#~ msgstr "et katalognavn mangler efter %s"
-
#~ msgid "file name missing after %s"
#~ msgstr "et filnavn mangler efter %s"
@@ -70178,9 +70029,6 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ msgid "Don't announce deprecation of compiler features"
#~ msgstr "Annoncér ikke forældelse af oversætterfaciliteter"
-#~ msgid "directory name must immediately follow -I"
-#~ msgstr "et katalognavn skal følge umiddelbart efter -I"
-
#~ msgid "Program does not use Unix-f77 dialectal features"
#~ msgstr "Program benytter ikke Unix f77-dialektiske faciliteter"
@@ -70190,9 +70038,6 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ msgid "Fortran-specific form of -fbounds-check"
#~ msgstr "Fortran-specifik form for -fbounds-check"
-#~ msgid "Add a directory for INCLUDE searching"
-#~ msgstr "Tilføj et katalog til INCLUDE-søgning"
-
#~ msgid "Set the maximum line length"
#~ msgstr "Angiv den maksimale linjelængde"
@@ -70208,12 +70053,6 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ msgid "Choose class whose main method should be used"
#~ msgstr "Vælg klasse hvis main-metode skal bruges"
-#~ msgid "Add directory to class path"
-#~ msgstr "Tilføj katalog til klassesti"
-
-#~ msgid "Directory where class files should be written"
-#~ msgstr "Katalog som klassefiler skrives i"
-
#~ msgid "`%s' cannot be statically allocated"
#~ msgstr "'%s' kan ikke allokeres statisk"
@@ -70412,21 +70251,6 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ msgid "operator '%s' has no left operand"
#~ msgstr "operatoren '%s' har ikke nogen venstre operand"
-#~ msgid "changing search order for system directory \"%s\""
-#~ msgstr "skifter søgeorden for systemkataloget \"%s\""
-
-#~ msgid " as it is the same as non-system directory \"%s\""
-#~ msgstr " da det er det samme som ikke-system-kataloget \"%s\""
-
-#~ msgid " as it has already been specified as a non-system directory"
-#~ msgstr " da det allerede er blevet angivet som et ikke-system-katalog"
-
-#~ msgid "I/O error on output"
-#~ msgstr "I/O-fejl på uddata"
-
-#~ msgid "number missing after %s"
-#~ msgstr "et tal mangler efter %s"
-
#~ msgid "GNU CPP version %s (cpplib)"
#~ msgstr "GNU CPP version %s (cpplib)"
@@ -70623,9 +70447,6 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ msgid "-trigraphs and -traditional are mutually exclusive"
#~ msgstr "-trigraphs og -traditional er indbyrdes uforenelige"
-#~ msgid "directory name missing after -I option"
-#~ msgstr "et katalognavn mangler efter '-I'-tilvalg"
-
#~ msgid "`/*' within comment"
#~ msgstr "'/*' i en kommentar"
@@ -71367,9 +71188,6 @@ msgstr "opretter vælger for ikke-eksisterende metode '%s'"
#~ " -idirafter <ktlg> Føj <ktlg> til slutningen af systeminkluderingsstien\n"
#~ " -I <ktlg> Føj <ktlg> til slutningen af den alm. inkluderingssti\n"
#~ " -I- Nøje kontrolleret inkluderingssti; se info-hjælpen\n"
-#~ " -nostdinc Søg ikke i systeminkluderingskataloger\n"
-#~ " (kataloger angivet med -isystem søges dog stadig)\n"
-#~ " -nostdinc++ Søg ikke i systeminkluderingskataloger til C++\n"
#~ " -o <fil> Send uddata til <fil>\n"
#~ " -pedantic Fremkom med alle advarsler påkrævet for nøje ISO C\n"
#~ " -pedantic-errors Behandl '-pedantic'-advarsler som fejl\n"
diff --git a/gcc/po/sv.po b/gcc/po/sv.po
index ef7031898bd..91485622be2 100644
--- a/gcc/po/sv.po
+++ b/gcc/po/sv.po
@@ -17,10 +17,10 @@
# store lagra
msgid ""
msgstr ""
-"Project-Id-Version: gcc 6.1-b20160131\n"
+"Project-Id-Version: gcc 6.1.0\n"
"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
"POT-Creation-Date: 2016-04-21 15:24+0000\n"
-"PO-Revision-Date: 2016-04-24 20:48+0200\n"
+"PO-Revision-Date: 2016-05-14 00:01+0200\n"
"Last-Translator: Göran Uddeborg <goeran@uddeborg.se>\n"
"Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
"Language: sv\n"
@@ -2440,7 +2440,7 @@ msgstr "Skalfaktor att använda på antalet satser i en trådningsväg vid jämf
#: params.def:1155
#, no-c-format
msgid "Maximum number of arguments a PHI may have before the FSM threader will not try to thread through its block."
-msgstr ""
+msgstr "Maximalt antal argument en PHI kan ha före FSM-trådaren kommer försöka tråda igenom dess block."
#: params.def:1160
#, no-c-format
@@ -2490,7 +2490,7 @@ msgstr "Nivå av pratsamhet om hsa-felsökningslagringar"
#: params.def:1209
#, no-c-format
msgid "Maximum number of may-defs visited when devirtualizing speculatively"
-msgstr ""
+msgstr "Maximalt antal av may-defs som besöks vid spekulativ avvirtualisering"
#: c-family/c-format.c:417
msgid "format"
@@ -5522,10 +5522,8 @@ msgid "-mbig-endian and -mlittle-endian may not be used together"
msgstr "-mbig-endian och -mlittle-endian får inte användas tillsammans"
#: config/moxie/moxiebox.h:43
-#, fuzzy
-#| msgid "R2 architecture is little-endian only"
msgid "this target is little-endian"
-msgstr "R2-arkitekturen har endast omvänd byteordning"
+msgstr "detta mål har omvänd byteordning"
#: ada/gcc-interface/lang-specs.h:34
msgid "-c or -S required for Ada"
@@ -6390,10 +6388,8 @@ msgid "Warn whenever type qualifiers are ignored."
msgstr "Varna när typkvalificerare ignoreras."
#: c-family/c.opt:487
-#, fuzzy
-#| msgid "Warn whenever type qualifiers are ignored."
msgid "Warn whenever attributes are ignored."
-msgstr "Varna när typkvalificerare ignoreras."
+msgstr "Varna när attribut ignoreras."
#: c-family/c.opt:491
msgid "Warn when there is a conversion between pointers that have incompatible types."
@@ -7132,7 +7128,7 @@ msgstr "Aktivera OpenACC."
#: c-family/c.opt:1393
msgid "Specify default OpenACC compute dimensions."
-msgstr ""
+msgstr "Ange standard-OpenACC-beräkningsdimensioner."
#: c-family/c.opt:1397
msgid "Enable OpenMP (implies -frecursive in Fortran)."
@@ -8111,10 +8107,8 @@ msgid "PC relative literal loads."
msgstr "PC-relativa literala laddningar."
#: config/aarch64/aarch64.opt:154
-#, fuzzy
-#| msgid "When calculating a sqrt approximation, run fewer steps."
msgid "When calculating the reciprocal square root approximation,"
-msgstr "Vid beräkning av sqrt-approximering, kör färre steg."
+msgstr "Vid beräkning av den reciproka kvardratrotsapproximeringen,"
#: config/linux.opt:24
msgid "Use Bionic C library."
@@ -8458,10 +8452,8 @@ msgid "Use LRA instead of reload."
msgstr "Använd LRA istället för omladdning."
#: config/ft32/ft32.opt:31
-#, fuzzy
-#| msgid "Allow the use of MDMX instructions."
msgid "Avoid use of the DIV and MOD instructions"
-msgstr "Tillåt användningen av MDMX-instruktioner."
+msgstr "Undvik att använda instruktionerna DIV och MOD"
#: config/h8300/h8300.opt:23
msgid "Generate H8S code."
@@ -9473,10 +9465,8 @@ msgid "Link in code for a __main kernel."
msgstr "Länka med kod för en __main-kärna."
#: config/nvptx/nvptx.opt:34
-#, fuzzy
-#| msgid "Optimize partition neutering"
msgid "Optimize partition neutering."
-msgstr "Optimera partitionssterilisering"
+msgstr "Optimera partitionssterilisering."
#: config/vxworks.opt:36
msgid "Assume the VxWorks RTP environment."
@@ -12964,10 +12954,8 @@ msgid "Enable double load/store instructions for ARC HS."
msgstr "Använd dubbla ladda/lagra-instruktioner för ARC HS."
#: config/arc/arc.opt:419
-#, fuzzy
-#| msgid "Specify the name of the target floating point hardware/format."
msgid "Specify the name of the target floating point configuration."
-msgstr "Ange namnet på målets flyttalshårdvara/-format."
+msgstr "Ange namnet på målets flyttalskonfiguration."
#: java/lang.opt:122
msgid "Warn if deprecated empty statements are found."
@@ -13220,7 +13208,7 @@ msgstr "-Wlarger-than=<antal>\tVarna för ett objekt är större än <antal> byt
#: common.opt:621
msgid "Warn if comparing pointer parameter with nonnull attribute with NULL."
-msgstr ""
+msgstr "Varna om en pekarparameter med attributet nonnull jämförs med NULL."
#: common.opt:625
msgid "Warn if dereferencing a NULL pointer may lead to erroneous or undefined behavior."
@@ -14639,7 +14627,7 @@ msgstr "Dela sökvägar som leder till bakåtbågar i slingor."
#: common.opt:2463
msgid "Assume common declarations may be overridden with ones with a larger"
-msgstr ""
+msgstr "Anta att gemensamma deklarationer kan åsidosättas med sådana med en större"
#: common.opt:2468
msgid "Compile whole compilation unit at a time."
@@ -15621,8 +15609,7 @@ msgid "second parameter of %<va_start%> not last named argument"
msgstr "andra parametern till %<va_start%> är inte det sista namngivna argumentet"
#: builtins.c:8989
-#, fuzzy, gcc-internal-format
-#| msgid "undefined behaviour when second parameter of %<va_start%> is declared with %<register%> storage"
+#, gcc-internal-format
msgid "undefined behavior when second parameter of %<va_start%> is declared with %<register%> storage"
msgstr "odefinierat beteende när andra parametern till %<va_start%> är deklarerad med lagringsklass %<register%>"
@@ -17708,13 +17695,12 @@ msgstr "omgivande OpenACC %qs-konstruktion"
#: gimplify.c:6160
#, gcc-internal-format
msgid "%qE with %<link%> clause used in %<routine%> function"
-msgstr ""
+msgstr "%qE med %<link%>-klausul använd i %<routine%>-funktion"
#: gimplify.c:6168
-#, fuzzy, gcc-internal-format
-#| msgid "%qE undeclared (first use in this function)"
+#, gcc-internal-format
msgid "%qE requires a %<declare%> directive for use in a %<routine%> function"
-msgstr "%qE är odeklarerad (första förekomsten i denna funktion)"
+msgstr "%qE behöver ett %<declare%>-direktiv att användas i en %<routine%>-funktion"
#: gimplify.c:6244 gimplify.c:6848
#, gcc-internal-format
@@ -17799,13 +17785,12 @@ msgstr "samma variabel använd i %<firstprivate%>- och %<lastprivate%>-klausuler
#: gimplify.c:8015
#, gcc-internal-format
msgid "incompatible data clause with reduction on %qE; promoting to present_or_copy"
-msgstr ""
+msgstr "inkompatibel dataklausul med reduktion på %qE; befordrar till present_or_copy"
#: gimplify.c:8159
-#, fuzzy, gcc-internal-format
-#| msgid "invalid template declaration of %qD"
+#, gcc-internal-format
msgid "invalid private reduction on %qE"
-msgstr "ogiltig malldeklaration av %qD"
+msgstr "ogiltig privat reduktion av %qE"
#: gimplify.c:9948 omp-low.c:3622
#, gcc-internal-format
@@ -18458,10 +18443,9 @@ msgid "malformed COLLECT_GCC_OPTIONS"
msgstr "felformaterad COLLECT_GCC_OPTIONS"
#: lto-wrapper.c:307
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "redeclaration %qD differs in %<constexpr%>"
+#, gcc-internal-format, gfc-internal-format
msgid "Option %s with different values"
-msgstr "omdeklaration av %qD skiljer i %<constexpr%>"
+msgstr "Flaggan %s med olika värden"
#: lto-wrapper.c:318 lto-wrapper.c:330
#, gcc-internal-format, gfc-internal-format
@@ -18484,10 +18468,9 @@ msgid "writing output file"
msgstr "skriver utdatafil"
#: lto-wrapper.c:870
-#, fuzzy, gcc-internal-format
-#| msgid "installation error, can't find crtoffloadbegin.o"
+#, gcc-internal-format
msgid "installation error, can't find crtoffloadtable.o"
-msgstr "installationsfel, kan inte hitta crtoffloadbegin.o"
+msgstr "installationsfel, kan inte hitta crtoffloadtable.o"
#: lto-wrapper.c:974
#, gcc-internal-format
@@ -18500,22 +18483,19 @@ msgid "environment variable COLLECT_GCC_OPTIONS must be set"
msgstr "miljövariabeln COLLECT_GCC_OPTIONS måste vara satt"
#: lto-wrapper.c:1135 lto-wrapper.c:1191
-#, fuzzy, gcc-internal-format
-#| msgid "can't open %s: %m"
+#, gcc-internal-format
msgid "cannot open %s: %m"
msgstr "det går inte att öppna %s: %m"
#: lto-wrapper.c:1138 lto-wrapper.c:1197
-#, fuzzy, gcc-internal-format
-#| msgid "can%'t read %s: %m"
+#, gcc-internal-format
msgid "cannot read %s: %m"
msgstr "kan inte läsa %s: %m"
#: lto-wrapper.c:1165
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "invalid operation (%s)"
+#, gcc-internal-format, gfc-internal-format
msgid "invalid format of %s"
-msgstr "ogiltig operation (%s)"
+msgstr "felaktigt format på %s"
#: lto-wrapper.c:1301
#, gcc-internal-format
@@ -18578,10 +18558,9 @@ msgid "argument not permitted on %qs clause in OpenACC %<parallel%>"
msgstr "argument är inte tillåtna på %qs-klausulen i OpenACC %<parallel%>"
#: omp-low.c:3251
-#, fuzzy, gcc-internal-format
-#| msgid "non-OpenACC construct inside of OpenACC region"
+#, gcc-internal-format
msgid "non-OpenACC construct inside of OpenACC routine"
-msgstr "icke-OpenACC-konstruktion inuti OpenACC-region"
+msgstr "icke-OpenACC-konstruktion inuti OpenACC-rutin"
#: omp-low.c:3260
#, gcc-internal-format
@@ -18706,7 +18685,7 @@ msgstr "%<teams%>-konstruktion inte vara nära innesluten inuti en %<target%>-ko
#: omp-low.c:3733
#, gcc-internal-format
msgid "OpenACC region inside of OpenACC routine, nested parallelism not supported yet"
-msgstr ""
+msgstr "OpenACC-region inuti OpenACC-rutin, nästad parallellism stödjs inte ännu"
#: omp-low.c:3746
#, gcc-internal-format
@@ -18772,7 +18751,7 @@ msgstr "ogiltig gren till/från strukturerat %s-block"
#: omp-low.c:18823
#, gcc-internal-format, gfc-internal-format
msgid "-fopenacc-dim operand is malformed at '%s'"
-msgstr ""
+msgstr "operand till -fopenacc-dim är felformulerad vid ”%s”"
#: omp-low.c:19410
#, gcc-internal-format, gfc-internal-format
@@ -20112,10 +20091,9 @@ msgid "integral result type precision does not match field size of BIT_FIELD_REF
msgstr "precisionen på typen på heltalsresultatet stämmer inte med fältstorleken på BIT_FIELD_REF"
#: tree-cfg.c:2965
-#, fuzzy, gcc-internal-format
-#| msgid "mode precision of non-integral result does not match field size of BIT_FIELD_REF"
+#, gcc-internal-format
msgid "mode size of non-integral result does not match field size of BIT_FIELD_REF"
-msgstr "lägesprecisionen på resultat av icke-heltalstyp stämmer inte med fältstorleken på BIT_FIELD_REF"
+msgstr "lägesstorleken på resultat av icke-heltalstyp stämmer inte med fältstorleken på BIT_FIELD_REF"
#: tree-cfg.c:2973
#, gcc-internal-format
@@ -22915,7 +22893,7 @@ msgstr "för många argument till funktionen %qE"
#: c-family/c-common.c:9852
#, gcc-internal-format
msgid "second argument to function %qE must be a constant integer power of 2 between %qi and %qu bits"
-msgstr ""
+msgstr "andra argumentet till funktionen %qE måste vara en konstant heltalsexponent till 2 mellan %qi och %qu bitar"
#: c-family/c-common.c:9873 c-family/c-common.c:9919
#, gcc-internal-format
@@ -23767,10 +23745,9 @@ msgid "-Wmisleading-indentation is disabled from this point onwards, since colum
msgstr "-Wmisleading-indentation är avaktiverad härifrån och framåt, eftersom kolumnspårning avaktiverades på grund av storleken på kod/huvuden."
#: c-family/c-indentation.c:607
-#, fuzzy, gcc-internal-format
-#| msgid "...this %qs clause, but it is not"
+#, gcc-internal-format
msgid "this %qs clause does not guard..."
-msgstr "… denna %qs-klausul, men är inte det"
+msgstr "denna %qs-klausul vaktar inte …"
#: c-family/c-lex.c:222
#, gcc-internal-format
@@ -25186,7 +25163,7 @@ msgstr "FPX-utvidgningar är inte tillgängliga för kärnor föra ARC600"
#: config/arc/arc.c:730
#, gcc-internal-format
msgid "No FPX/FPU mixing allowed"
-msgstr ""
+msgstr "Ingen FPX/FPU-blandning tillåten"
#: config/arc/arc.c:735
#, gcc-internal-format
@@ -25211,17 +25188,17 @@ msgstr "-mll64 stödjs endast för ARC HS-kärnor"
#: config/arc/arc.c:758
#, gcc-internal-format
msgid "FPU double precision options are available for ARC HS only"
-msgstr ""
+msgstr "FPU dubbelprecisionsalternativ är bara tillgängliga för ARC HS"
#: config/arc/arc.c:760
#, gcc-internal-format
msgid "FPU double precision assist options are not available for ARC HS"
-msgstr ""
+msgstr "FPU dubbelprecisions assistansalternativ är inte tillgängliga för ARC HS"
#: config/arc/arc.c:763
#, gcc-internal-format
msgid "FPU options are available for ARCv2 architecture only"
-msgstr ""
+msgstr "FPU-alternativ är bara tillgängliga för ARCv2-arkitekturen"
#: config/arc/arc.c:1293
#, gcc-internal-format, gfc-internal-format
@@ -29333,10 +29310,9 @@ msgid "%qs uses dynamic stack allocation"
msgstr "%qs använder dynamisk stackallokering"
#: config/s390/s390.c:11173
-#, fuzzy, gcc-internal-format
-#| msgid "Stack frame larger than 2G is not supported for -fsplit-stack"
+#, gcc-internal-format
msgid "CPUs older than z900 are not supported for -fsplit-stack"
-msgstr "Stackramar större än 2 G stödjs inte med -fsplit-stack"
+msgstr "CPU:er äldre än z900 stödjs inte med -fsplit-stack"
#: config/s390/s390.c:14172
#, gcc-internal-format, gfc-internal-format
@@ -35737,10 +35713,9 @@ msgid "call to non-constexpr function %qD"
msgstr "anrop av icke-constexpr-funktion %qD"
#: cp/constexpr.c:1379
-#, fuzzy, gcc-internal-format
-#| msgid "%qD called in a constant expression"
+#, gcc-internal-format
msgid "%qD called in a constant expression before its definition is complete"
-msgstr "%qD anropad i ett konstant uttryck"
+msgstr "%qD anropad i ett konstant uttryck före dess definition är komplett"
#. The definition of fun was somehow unsuitable.
#: cp/constexpr.c:1384
@@ -35794,16 +35769,14 @@ msgid "shift expression %q+E overflows"
msgstr "skiftuttrycket %q+E spiller över"
#: cp/constexpr.c:1942
-#, fuzzy, gcc-internal-format
-#| msgid "enumerator value %E is outside the range of underlying type %<%T%>"
+#, gcc-internal-format
msgid "array subscript value %qE is outside the bounds of array %qD of type %qT"
-msgstr "uppräkningsvärdet %E är utanför intervallet för den underliggande typen %<%T%>"
+msgstr "vektorindexvärdet %qE är utanför gränserna för vektorn %qD av typen %qT"
#: cp/constexpr.c:1947
-#, fuzzy, gcc-internal-format
-#| msgid "enumerator value %E is outside the range of underlying type %<%T%>"
+#, gcc-internal-format
msgid "array subscript value %qE is outside the bounds of array type %qT"
-msgstr "uppräkningsvärdet %E är utanför intervallet för den underliggande typen %<%T%>"
+msgstr "vektorindexvärdet %qE är utanför gränserna för vektortypen %qT"
#: cp/constexpr.c:2036
#, gcc-internal-format
@@ -35946,10 +35919,9 @@ msgid "division by zero is not a constant-expression"
msgstr "division med noll är inte ett konstantuttryck"
#: cp/constexpr.c:5094
-#, fuzzy, gcc-internal-format
-#| msgid "statement is not a constant-expression"
+#, gcc-internal-format
msgid "%<delete[]%> is not a constant-expression"
-msgstr "satsen är inte ett konstantuttryck"
+msgstr "%<delete[]%> är inte ett konstantuttryck"
#: cp/constexpr.c:5125
#, gcc-internal-format
@@ -38229,10 +38201,9 @@ msgid "declaration of %qD as member of %qT"
msgstr "deklaration av %qD som medlem av %qT"
#: cp/decl.c:11106
-#, fuzzy, gcc-internal-format
-#| msgid "a destructor cannot be %<constexpr%>"
+#, gcc-internal-format
msgid "a destructor cannot be %<concept%>"
-msgstr "en destruerare kan inte vara %<constexpr%>"
+msgstr "en destruerare kan inte vara %<concept%>"
#: cp/decl.c:11111
#, gcc-internal-format
@@ -38245,16 +38216,14 @@ msgid "expected qualified name in friend declaration for constructor %qD"
msgstr "kvalificerat namn förväntades i vändeklaration för konstruerare %qD"
#: cp/decl.c:11125
-#, fuzzy, gcc-internal-format
-#| msgid "a destructor cannot be %<constexpr%>"
+#, gcc-internal-format
msgid "a constructor cannot be %<concept%>"
-msgstr "en destruerare kan inte vara %<constexpr%>"
+msgstr "en konstruerare kan inte vara %<concept%>"
#: cp/decl.c:11130
-#, fuzzy, gcc-internal-format
-#| msgid "constructor cannot be static member function"
+#, gcc-internal-format
msgid "a concept cannot be a member function"
-msgstr "konstruerare kan inte vara en statisk medlemsfunktion"
+msgstr "ett koncept kan inte vara en medlemsfunktion"
#: cp/decl.c:11139
#, gcc-internal-format
@@ -38282,10 +38251,9 @@ msgid "%qE is neither function nor member function; cannot be declared friend"
msgstr "%qE är varken en funktion eller medlemsfunktion, kan inte deklareras som vän"
#: cp/decl.c:11272
-#, fuzzy, gcc-internal-format
-#| msgid "non-static data member %qE declared %<constexpr%>"
+#, gcc-internal-format
msgid "static data member %qE declared %<concept%>"
-msgstr "ickestatisk datamedlem %qE deklarerad %<constexpr%>"
+msgstr "statisk datamedlem %qE deklarerad %<concept%>"
#: cp/decl.c:11276
#, gcc-internal-format
@@ -38293,10 +38261,9 @@ msgid "constexpr static data member %qD must have an initializer"
msgstr "statisk constexpr-datamedlemmen %qD måste ha en initierare"
#: cp/decl.c:11284
-#, fuzzy, gcc-internal-format
-#| msgid "non-static data member %qE declared %<constexpr%>"
+#, gcc-internal-format
msgid "non-static data member %qE declared %<concept%>"
-msgstr "ickestatisk datamedlem %qE deklarerad %<constexpr%>"
+msgstr "ickestatisk datamedlem %qE deklarerad %<concept%>"
#: cp/decl.c:11288
#, gcc-internal-format
@@ -38646,7 +38613,7 @@ msgstr "tidigare deklaration här"
#: cp/decl.c:12657
#, gcc-internal-format
msgid "perhaps you want to explicitly add %<%T::%>"
-msgstr ""
+msgstr "kanske du vill explicit lägga till %<%T::%>"
#: cp/decl.c:12666 cp/name-lookup.c:2685 cp/name-lookup.c:3524
#: cp/name-lookup.c:3569 cp/parser.c:6043 cp/parser.c:24842
@@ -38680,10 +38647,9 @@ msgid "Java class %qT cannot have multiple bases"
msgstr "Javaklass %qT kan inte ha flera baser"
#: cp/decl.c:12978
-#, fuzzy, gcc-internal-format
-#| msgid "%qD is defined with tls model %s"
+#, gcc-internal-format
msgid "%qT defined with multiple direct bases"
-msgstr "%qD initieras med tls-modell %s"
+msgstr "%qT definierad med flera direkta baser"
#: cp/decl.c:12987
#, gcc-internal-format
@@ -38691,10 +38657,9 @@ msgid "Java class %qT cannot have virtual bases"
msgstr "Javaklass %qT kan inte ha virtuella baser"
#: cp/decl.c:12992
-#, fuzzy, gcc-internal-format
-#| msgid "type %qT is not a direct or virtual base of %qT"
+#, gcc-internal-format
msgid "%qT defined with direct virtual base"
-msgstr "typ %qT är inte en direkt eller virtuell bas till %qT"
+msgstr "%qT definerad med en direkt virtuell bas"
#: cp/decl.c:13010
#, gcc-internal-format
@@ -39013,16 +38978,14 @@ msgid "%<operator delete%> takes type %qT as first parameter"
msgstr "%<operator delete%> tar typen %qT som första parameter"
#: cp/decl2.c:2572
-#, fuzzy, gcc-internal-format
-#| msgid "%qT has a field %qD whose type uses the anonymous namespace"
+#, gcc-internal-format
msgid "%qT has a field %qD whose type has no linkage"
-msgstr "%qT har ett fält %qD vars typ använder den anonyma namnrymden"
+msgstr "%qT har ett fält %qD vars typ inte har någon länkklass"
#: cp/decl2.c:2576
-#, fuzzy, gcc-internal-format
-#| msgid "%qT has a field %qD whose type uses the anonymous namespace"
+#, gcc-internal-format
msgid "%qT has a field %qD whose type depends on the type %qT which has no linkage"
-msgstr "%qT har ett fält %qD vars typ använder den anonyma namnrymden"
+msgstr "%qT har ett fält %qD vars typ beror på typen %qT som inte har någon länkklass"
#: cp/decl2.c:2581
#, gcc-internal-format
@@ -39035,16 +38998,14 @@ msgid "%qT declared with greater visibility than the type of its field %qD"
msgstr "%qT är deklarerad med större synlighet än typen för dess fält %qD"
#: cp/decl2.c:2607
-#, fuzzy, gcc-internal-format
-#| msgid "%qT has a base %qT whose type uses the anonymous namespace"
+#, gcc-internal-format
msgid "%qT has a base %qT whose type has no linkage"
-msgstr "%qT har en bas %qT vars typ använder den anonyma namnrymden"
+msgstr "%qT har en bas %qT vars typ inte har någon länkklass"
#: cp/decl2.c:2611
-#, fuzzy, gcc-internal-format
-#| msgid "%qT has a base %qT whose type uses the anonymous namespace"
+#, gcc-internal-format
msgid "%qT has a base %qT whose type depends on the type %qT which has no linkage"
-msgstr "%qT har en bas %qT vars typ använder den anonyma namnrymden"
+msgstr "%qT har en bas %qT vars typ beror på typen %qT som inte har någon länkklass"
#: cp/decl2.c:2616
#, gcc-internal-format
@@ -39101,10 +39062,9 @@ msgid "the program should also define %qD"
msgstr "programmet borde även definiera %qD"
#: cp/decl2.c:4846
-#, fuzzy, gcc-internal-format
-#| msgid "inline function %q+D used but never defined"
+#, gcc-internal-format
msgid "inline function %qD used but never defined"
-msgstr "inline-funktion %q+D använd men aldrig definierad"
+msgstr "inline-funktion %qD använd men aldrig definierad"
#: cp/decl2.c:5037
#, gcc-internal-format
@@ -39306,10 +39266,9 @@ msgid "noexcept-expression evaluates to %<false%> because of a call to %qD"
msgstr "noexcept-uttrycket beräknas till %<false%> på grund av ett anrop till %qD"
#: cp/except.c:1211
-#, fuzzy, gcc-internal-format
-#| msgid "but %q+D does not throw; perhaps it should be declared %<noexcept%>"
+#, gcc-internal-format
msgid "but %qD does not throw; perhaps it should be declared %<noexcept%>"
-msgstr "men %q+D kastar inte, kanske den skulle deklareras %<noexcept%>"
+msgstr "men %qD kastar inte, kanske den skulle deklareras %<noexcept%>"
#: cp/friend.c:149
#, gcc-internal-format
@@ -39334,10 +39293,9 @@ msgid "partial specialization %qT declared %<friend%>"
msgstr "partiell specialisering %qT deklarerad %<friend%>"
#: cp/friend.c:266
-#, fuzzy, gcc-internal-format
-#| msgid "function template-id %qD in nested-name-specifier"
+#, gcc-internal-format
msgid "perhaps you need explicit template arguments in your nested-name-specifier"
-msgstr "funktionsmalls-id %qD i nästad namnspecificerare"
+msgstr "kanske du behöver explicita mallargument i din nästade-namn-specificerare"
#: cp/friend.c:274
#, gcc-internal-format
@@ -39427,10 +39385,9 @@ msgid "value-initialization of reference type %qT"
msgstr "värdeinitiering av referenstypen %qT"
#: cp/init.c:556
-#, fuzzy, gcc-internal-format
-#| msgid "pure virtual %q#D called from non-static data member initializer"
+#, gcc-internal-format
msgid "recursive instantiation of non-static data member initializer for %qD"
-msgstr "pure virtual %q#D anropad från initierare av ickestatisk datamedlem"
+msgstr "rekursiv instantiering av ickestatisk datamedleminitierare för %qD"
#: cp/init.c:580
#, gcc-internal-format
@@ -39469,10 +39426,9 @@ msgid "uninitialized reference member in %q#T"
msgstr "oinitierad referensmedlem i %q#T"
#: cp/init.c:950
-#, fuzzy, gcc-internal-format
-#| msgid "%q+D will be initialized after"
+#, gcc-internal-format
msgid "%qD will be initialized after"
-msgstr "%q+D kommer initieras efter"
+msgstr "%qD kommer initieras efter"
#: cp/init.c:953
#, gcc-internal-format
@@ -39480,10 +39436,9 @@ msgid "base %qT will be initialized after"
msgstr "basen %qT kommer initieras efter"
#: cp/init.c:957
-#, fuzzy, gcc-internal-format
-#| msgid " %q+#D"
+#, gcc-internal-format
msgid " %q#D"
-msgstr " %q+#D"
+msgstr " %q#D"
#: cp/init.c:959
#, gcc-internal-format
@@ -39666,10 +39621,9 @@ msgid "call to Java constructor with %qs undefined"
msgstr "anrop av Javakonstruerare med %qs odefinierad"
#: cp/init.c:2873
-#, fuzzy, gcc-internal-format
-#| msgid "%qD is not a function template"
+#, gcc-internal-format
msgid "%qD is not a function returning a pointer"
-msgstr "%qD är inte en funktionsmall"
+msgstr "%qD är inte en funktion som returnerar en pekare"
#: cp/init.c:2882
#, gcc-internal-format
@@ -39752,14 +39706,12 @@ msgid "neither the destructor nor the class-specific operator delete will be cal
msgstr "varken destrueraren eller den klasspecifika operatorn delete kommer anropas, även om de är deklarerade när klassen definieras"
#: cp/init.c:4395
-#, fuzzy, gcc-internal-format
-#| msgid "deleting object of abstract class type %qT which has non-virtual destructor will cause undefined behaviour"
+#, gcc-internal-format
msgid "deleting object of abstract class type %qT which has non-virtual destructor will cause undefined behavior"
msgstr "radering av objekt av den abstrakta klasstypen %qT som har en ej virtuell destruerare kommer medföra odefinierat beteende"
#: cp/init.c:4400
-#, fuzzy, gcc-internal-format
-#| msgid "deleting object of polymorphic class type %qT which has non-virtual destructor might cause undefined behaviour"
+#, gcc-internal-format
msgid "deleting object of polymorphic class type %qT which has non-virtual destructor might cause undefined behavior"
msgstr "radering av objekt av den polymorfa klasstypen %qT som har en ej virtuell destruerare kommer medföra odefinierat beteende"
@@ -39899,28 +39851,24 @@ msgid "a later -fabi-version= (or =0) avoids this error with a change in manglin
msgstr "en senare -fabi-version= (eller =0) undviker detta fel med en ändring av manglingen"
#: cp/mangle.c:3667
-#, fuzzy, gcc-internal-format
-#| msgid "the mangled name of %q+D changed between -fabi-version=%d (%D) and -fabi-version=%d (%D)"
+#, gcc-internal-format
msgid "the mangled name of %qD changed between -fabi-version=%d (%D) and -fabi-version=%d (%D)"
-msgstr "det manglade namnet för %q+D ändrades mellan -fabi-version=%d (%D) och -fabi-version=%d (%D)"
+msgstr "det manglade namnet på %qD ändrades mellan -fabi-version=%d (%D) och -fabi-version=%d (%D)"
#: cp/mangle.c:3673
-#, fuzzy, gcc-internal-format
-#| msgid "the mangled name of %q+D changes between -fabi-version=%d (%D) and -fabi-version=%d (%D)"
+#, gcc-internal-format
msgid "the mangled name of %qD changes between -fabi-version=%d (%D) and -fabi-version=%d (%D)"
-msgstr "det manglade namnet för %q+D ändras mellan -fabi-version=%d (%D) och -fabi-version=%d (%D)"
+msgstr "det manglade namnet på %qD ändras mellan -fabi-version=%d (%D) och -fabi-version=%d (%D)"
#: cp/mangle.c:3969
-#, fuzzy, gcc-internal-format
-#| msgid "the mangled name of %q+D changes between -fabi-version=%d (%D) and -fabi-version=%d (%D)"
+#, gcc-internal-format
msgid "the mangled name of %qD changes between -fabi-version=%d and -fabi-version=%d"
-msgstr "det manglade namnet för %q+D ändras mellan -fabi-version=%d (%D) och -fabi-version=%d (%D)"
+msgstr "det manglade namnet på %qD ändras mellan -fabi-version=%d och -fabi-version=%d"
#: cp/mangle.c:3974
-#, fuzzy, gcc-internal-format
-#| msgid "the mangled name of %q+D changes between -fabi-version=%d (%D) and -fabi-version=%d (%D)"
+#, gcc-internal-format
msgid "the mangled name of the initialization guard variable for%qD changes between -fabi-version=%d and -fabi-version=%d"
-msgstr "det manglade namnet för %q+D ändras mellan -fabi-version=%d (%D) och -fabi-version=%d (%D)"
+msgstr "det manglade namnet på initieringsvaktsvariabeln för %qD ändras mellan -fabi-version=%d och -fabi-version=%d"
#: cp/method.c:705 cp/method.c:1186
#, gcc-internal-format
@@ -39943,22 +39891,19 @@ msgid "union member %q+D with non-trivial %qD"
msgstr "union-medlem %q+D med icketrivial %qD"
#: cp/method.c:1145
-#, fuzzy, gcc-internal-format
-#| msgid "defaulted constructor calls non-constexpr %q+D"
+#, gcc-internal-format
msgid "defaulted constructor calls non-constexpr %qD"
-msgstr "standarddefinierad konstruerare anropar %q+D som inte är constexpr"
+msgstr "standarddefinierad konstruerare anropar %qD som inte är constexpr"
#: cp/method.c:1209
-#, fuzzy, gcc-internal-format
-#| msgid "initializer for %q+#D is invalid"
+#, gcc-internal-format
msgid "initializer for %q#D is invalid"
-msgstr "initieraren för %q+#D är ogiltig"
+msgstr "initieraren för %q#D är ogiltig"
#: cp/method.c:1261
-#, fuzzy, gcc-internal-format
-#| msgid "defaulted default constructor does not initialize %q+#D"
+#, gcc-internal-format
msgid "defaulted default constructor does not initialize %q#D"
-msgstr "den standarddefinierade standardkonstrueraren initierar inte %q+#D"
+msgstr "den standarddefinierade standardkonstrueraren initierar inte %q#D"
#: cp/method.c:1272
#, gcc-internal-format
@@ -39987,16 +39932,14 @@ msgid "a lambda closure type has a deleted copy assignment operator"
msgstr "en lambdahöljetyp har en raderad koperingstilldelningsoperator"
#: cp/method.c:1636
-#, fuzzy, gcc-internal-format
-#| msgid "%q+#D is implicitly declared as deleted because %qT declares a move constructor or move assignment operator"
+#, gcc-internal-format
msgid "%q#D is implicitly declared as deleted because %qT declares a move constructor or move assignment operator"
-msgstr "%q+#D är implicit deklarerad som raderad för att %qT deklarerar en flyttkonstruerare eller flyttilldelningsoperator"
+msgstr "%q#D är implicit deklarerad som raderad för att %qT deklarerar en flyttkonstruerare eller flyttilldelningsoperator"
#: cp/method.c:1656
-#, fuzzy, gcc-internal-format
-#| msgid "%q+#D is implicitly deleted because the default definition would be ill-formed:"
+#, gcc-internal-format
msgid "%q#D is implicitly deleted because the default definition would be ill-formed:"
-msgstr "%q+#D är underförstått raderad eftersom standarddefinitionen skulle vara felformulerad:"
+msgstr "%q#D är underförstått raderad eftersom standarddefinitionen skulle vara felformulerad:"
#: cp/method.c:1665
msgid "%q#F is implicitly deleted because its exception-specification does not match the implicit exception-specification %qX"
@@ -40068,10 +40011,9 @@ msgid "declaration of %q#D with C language linkage"
msgstr "deklaration av %q#D med C-länkklass"
#: cp/name-lookup.c:872 cp/name-lookup.c:887
-#, fuzzy, gcc-internal-format
-#| msgid "conflicts with previous declaration %q+#D"
+#, gcc-internal-format
msgid "conflicts with previous declaration %q#D"
-msgstr "står i konflikt med tidigare deklaration %q+#D"
+msgstr "står i konflikt med tidigare deklaration %q#D"
#: cp/name-lookup.c:875
#, gcc-internal-format
@@ -40084,10 +40026,9 @@ msgid "type mismatch with previous external decl of %q#D"
msgstr "typ stämmer inte med tidigare externdeklaration av %q#D"
#: cp/name-lookup.c:989
-#, fuzzy, gcc-internal-format
-#| msgid "previous external decl of %q+#D"
+#, gcc-internal-format
msgid "previous external decl of %q#D"
-msgstr "tidigare externdeklaration av %q+#D"
+msgstr "tidigare externdeklaration av %q#D"
#: cp/name-lookup.c:1077
#, gcc-internal-format
@@ -40095,10 +40036,9 @@ msgid "extern declaration of %q#D doesn%'t match"
msgstr "externdeklaration av %q#D stämmer inte"
#: cp/name-lookup.c:1079
-#, fuzzy, gcc-internal-format
-#| msgid "global declaration %q+#D"
+#, gcc-internal-format
msgid "global declaration %q#D"
-msgstr "global deklaration av %q+#D"
+msgstr "global deklaration av %q#D"
#: cp/name-lookup.c:1131 cp/name-lookup.c:1201
#, gcc-internal-format
@@ -40127,16 +40067,14 @@ msgid "name lookup of %qD changed"
msgstr "namnuppslagning av %qD ändrades"
#: cp/name-lookup.c:1408
-#, fuzzy, gcc-internal-format
-#| msgid " matches this %q+D under ISO standard rules"
+#, gcc-internal-format
msgid " matches this %qD under ISO standard rules"
msgstr " stämmer med denna %qD under ISO:s standardregler"
#: cp/name-lookup.c:1411
-#, fuzzy, gcc-internal-format
-#| msgid " matches this %q+D under old rules"
+#, gcc-internal-format
msgid " matches this %qD under old rules"
-msgstr " stämmer med denna %q+D under gamla regler"
+msgstr " stämmer med denna %qD under gamla regler"
#: cp/name-lookup.c:1429 cp/name-lookup.c:1437
#, gcc-internal-format
@@ -40149,10 +40087,9 @@ msgid " cannot use obsolete binding at %q+D because it has a destructor"
msgstr " det går inte att använda föråldrad bindning vid %q+D för att den har en destruerare"
#: cp/name-lookup.c:1441
-#, fuzzy, gcc-internal-format
-#| msgid " using obsolete binding at %q+D"
+#, gcc-internal-format
msgid " using obsolete binding at %qD"
-msgstr " använder föråldrad bindning vid %q+D"
+msgstr " använder föråldrad bindning vid %qD"
#: cp/name-lookup.c:1447
#, gcc-internal-format
@@ -40251,16 +40188,14 @@ msgid "explicit qualification in declaration of %qD"
msgstr "explicit-kvalifikation i deklaration av %qD"
#: cp/name-lookup.c:3583
-#, fuzzy, gcc-internal-format
-#| msgid "%qE has not been declared"
+#, gcc-internal-format
msgid "%qD has not been declared within %D"
-msgstr "%qE har inte deklarerats"
+msgstr "%qD har inte deklarerats inom %D"
#: cp/name-lookup.c:3584
-#, fuzzy, gcc-internal-format
-#| msgid "%q+D declared as a friend"
+#, gcc-internal-format
msgid "only here as a friend"
-msgstr "%q+D deklarerad som en vän"
+msgstr "endast här som en vän"
#: cp/name-lookup.c:3600
#, gcc-internal-format
@@ -40361,10 +40296,9 @@ msgstr "%<#pragma omp declare simd%> som inte omedelbart följs av en funktionsd
#: cp/parser.c:1387 cp/parser.c:36470 cp/parser.c:36575 cp/parser.c:36600
#: cp/parser.c:36657
-#, fuzzy, gcc-internal-format
-#| msgid "%<#pragma omp declare simd%> must be followed by function declaration or definition"
+#, gcc-internal-format
msgid "%<#pragma acc routine%> not followed by a function declaration or definition"
-msgstr "%<#pragma omp declare simd%> måste följas av en funktionsdeklaration eller -definition"
+msgstr "%<#pragma acc routine%> följs inte av en funktionsdeklaration eller -definition"
#: cp/parser.c:2773
#, gcc-internal-format
@@ -40574,10 +40508,9 @@ msgid "C++11 %<thread_local%> only available with -std=c++11 or -std=gnu++11"
msgstr "C++11 %<thread_local%> är endast tillgängligt med -std=c++11 eller -std=gnu++11"
#: cp/parser.c:3176
-#, fuzzy, gcc-internal-format
-#| msgid "C++11 %<noexcept%> only available with -std=c++11 or -std=gnu++11"
+#, gcc-internal-format
msgid "%<concept%> only available with -fconcepts"
-msgstr "C++11 %<noexcept%> är endast tillgängligt med -std=c++11 eller -std=gnu++11"
+msgstr "%<concept%> är endast tillgängligt -fconcepts"
#: cp/parser.c:3202
#, gcc-internal-format
@@ -40676,34 +40609,29 @@ msgid "expected declaration"
msgstr "en deklaration förväntades"
#: cp/parser.c:4609 cp/parser.c:4624
-#, fuzzy, gcc-internal-format
-#| msgid "expected operator"
+#, gcc-internal-format
msgid "expected binary operator"
-msgstr "operator förväntades"
+msgstr "binär operator förväntades"
#: cp/parser.c:4630
-#, fuzzy, gcc-internal-format
-#| msgid "expected %<...%>"
+#, gcc-internal-format
msgid "expected ..."
-msgstr "%<...%> förväntades"
+msgstr "... förväntades"
#: cp/parser.c:4640
-#, fuzzy, gcc-internal-format
-#| msgid "lambda-expression in a constant expression"
+#, gcc-internal-format
msgid "binary expression in operand of fold-expression"
-msgstr "lambdauttryck i ett konstantuttryck"
+msgstr "binärt uttryck i operanden till ett vikningsuttryck"
#: cp/parser.c:4643
-#, fuzzy, gcc-internal-format
-#| msgid "a transaction expression cannot appear in a constant-expression"
+#, gcc-internal-format
msgid "conditional expression in operand of fold-expression"
-msgstr "ett transaktionsuttryck får inte finnas i ett konstantuttryck"
+msgstr "villkorligt uttryck i operanden till ett vikningsuttryck"
#: cp/parser.c:4651
-#, fuzzy, gcc-internal-format
-#| msgid "type mismatch in sad expression"
+#, gcc-internal-format
msgid "mismatched operator in fold-expression"
-msgstr "typfel i sad-uttryck"
+msgstr "operator som inte stämmer i vikningsuttryck"
#: cp/parser.c:4755
#, gcc-internal-format
@@ -40721,10 +40649,9 @@ msgid "statement-expressions are not allowed outside functions nor in template-a
msgstr "satsuttryck är inte tillåtna utanför funktioner eller i mallargumentlistor"
#: cp/parser.c:4887
-#, fuzzy, gcc-internal-format
-#| msgid "lambda expressions only available with -std=c++11 or -std=gnu++11"
+#, gcc-internal-format
msgid "fold-expressions only available with -std=c++1z or -std=gnu++1z"
-msgstr "lambdauttryck är endast tillgängliga med -std=c++11 eller -std=gnu++11"
+msgstr "vikningsuttryck är endast tillgängliga med -std=c++1z eller -std=gnu++1z"
#: cp/parser.c:4945 cp/parser.c:5116 cp/parser.c:5294
#, gcc-internal-format
@@ -40887,16 +40814,14 @@ msgid "try removing the parentheses around the type-id"
msgstr "försök ta bort parenteserna runt typ-id:t"
#: cp/parser.c:8123
-#, fuzzy, gcc-internal-format
-#| msgid "direct-list-initialization of %<auto%> requires exactly one element"
+#, gcc-internal-format
msgid "initialization of new-expression for type %<auto%> requires exactly one element"
-msgstr "direkt listinitiering av %<auto%> tar precis ett element"
+msgstr "initiering av new-uttryck för typen %<auto%> tar precis ett element"
#: cp/parser.c:8171
-#, fuzzy, gcc-internal-format
-#| msgid "Expected expression type"
+#, gcc-internal-format
msgid "expected expression-list or type-id"
-msgstr "Uttryckstyp förväntades"
+msgstr "uttryckslista eller typ-id förväntades"
#: cp/parser.c:8200
#, gcc-internal-format
@@ -40964,10 +40889,9 @@ msgid "capture of non-variable %qD "
msgstr "fångst av en icke-variabel %qD"
#: cp/parser.c:9941 cp/parser.c:9951 cp/semantics.c:3371 cp/semantics.c:3381
-#, fuzzy, gcc-internal-format
-#| msgid "%q+#D declared here"
+#, gcc-internal-format
msgid "%q#D declared here"
-msgstr "%q+#D är deklarerad här"
+msgstr "%q#D är deklarerad här"
#: cp/parser.c:9947
#, gcc-internal-format
@@ -41148,10 +41072,9 @@ msgid "invalid linkage-specification"
msgstr "ogiltig länkklasspecifikation"
#: cp/parser.c:13021
-#, fuzzy, gcc-internal-format
-#| msgid "range-based for loop without a type-specifier only available with -std=c++1z or -std=gnu++1z"
+#, gcc-internal-format
msgid "static_assert without a message only available with -std=c++1z or -std=gnu++1z"
-msgstr "intervallbaserad for-slinga utan en typspecificerare är endast tillgänglig med -std=c++1z eller -std=gnu++1z"
+msgstr "static_assert utan ett meddelande är endast tillgänglig med -std=c++1z eller -std=gnu++1z"
#: cp/parser.c:13215
#, gcc-internal-format
@@ -41235,16 +41158,14 @@ msgid "keyword %<export%> not implemented, and will be ignored"
msgstr "nyckelordet %<export%> är inte implementerat och kommer ignoreras"
#: cp/parser.c:14264
-#, fuzzy, gcc-internal-format
-#| msgid "invalid template non-type parameter"
+#, gcc-internal-format
msgid "invalid constrained type parameter"
-msgstr "ogiltig mallparameter som inte är en typ"
+msgstr "ogiltig begränsad typparameter"
#: cp/parser.c:14272
-#, fuzzy, gcc-internal-format
-#| msgid "invalid template non-type parameter"
+#, gcc-internal-format
msgid "cv-qualified type parameter"
-msgstr "ogiltig mallparameter som inte är en typ"
+msgstr "cv-kvalificerad typparameter"
#: cp/parser.c:14357
#, gcc-internal-format
@@ -41252,10 +41173,9 @@ msgid "variadic constraint introduced without %<...%>"
msgstr "variadisk begränsning introducerad utan %<...%>"
#: cp/parser.c:14421
-#, fuzzy, gcc-internal-format
-#| msgid "invalid use of %<auto%> in template argument"
+#, gcc-internal-format
msgid "invalid use of %<auto%> in default template argument"
-msgstr "felaktig användning av %<auto%> i mallargument"
+msgstr "felaktig användning av %<auto%> i standardmallargument"
#: cp/parser.c:14656 cp/parser.c:14739 cp/parser.c:20599
#, gcc-internal-format
@@ -41405,10 +41325,9 @@ msgid "%qD is an enumeration template"
msgstr "%qD är en uppräkningsmall"
#: cp/parser.c:17081
-#, fuzzy, gcc-internal-format
-#| msgid "%qD does not have integral or enumeration type"
+#, gcc-internal-format
msgid "%qD does not name an enumeration in %qT"
-msgstr "%qD har inte heltals- eller uppräkningstyp"
+msgstr "%qD är inte namnet på en uppräkningstyp i %qT"
#: cp/parser.c:17096
#, gcc-internal-format
@@ -41426,10 +41345,9 @@ msgid "cannot add an enumerator list to a template instantiation"
msgstr "det går inte att lägga till en uppräkningslista till en mallinstansiering"
#: cp/parser.c:17214
-#, fuzzy, gcc-internal-format
-#| msgid "friend declaration does not name a class or function"
+#, gcc-internal-format
msgid "nested name specifier %qT for enum declaration does not name a class or namespace"
-msgstr "vändeklaration som inte namnger en klass eller funktion"
+msgstr "nästad namnspecificerare %qT för enum-deklaration som inte namnger en klass eller namnrymd"
#: cp/parser.c:17226 cp/parser.c:21835
#, gcc-internal-format
@@ -41472,34 +41390,29 @@ msgid "expected namespace-name"
msgstr "namnrymdsnamn förväntades"
#: cp/parser.c:17549
-#, fuzzy, gcc-internal-format
-#| msgid "%<namespace%> definition is not allowed here"
+#, gcc-internal-format
msgid "a nested namespace definition cannot have attributes"
-msgstr "%<namespace%>-definition är inte tillåten här"
+msgstr "en nästad namnrymdsdefinition kan inte ha attribut"
#: cp/parser.c:17552
-#, fuzzy, gcc-internal-format
-#| msgid "inline namespaces only available with -std=c++11 or -std=gnu++11"
+#, gcc-internal-format
msgid "nested namespace definitions only available with -std=c++1z or -std=gnu++1z"
-msgstr "inline-namnrymder är endast tillgängliga med -std=c++11 eller -std=gnu++11"
+msgstr "nästade namnrymdsdefinitioner är endast tillgängliga med -std=c++1z eller -std=gnu++1z"
#: cp/parser.c:17555
-#, fuzzy, gcc-internal-format
-#| msgid "Warn when an inlined function cannot be inlined"
+#, gcc-internal-format
msgid "a nested namespace definition cannot be inline"
-msgstr "Varna när en inline:ad funktion inte kan inline:as"
+msgstr "en nästad namnrymdsdefinition kan inte inline:as"
#: cp/parser.c:17563
-#, fuzzy, gcc-internal-format
-#| msgid "expected identifier"
+#, gcc-internal-format
msgid "nested identifier required"
-msgstr "identifierare förväntades"
+msgstr "nästad identifierare behövs"
#: cp/parser.c:17591
-#, fuzzy, gcc-internal-format
-#| msgid "use of namespace %qD as expression"
+#, gcc-internal-format
msgid "namespace %qD entered"
-msgstr "användning av namnrymden %q+D som uttryck"
+msgstr "gick in i namnrymden %qD"
#: cp/parser.c:17643
#, gcc-internal-format
@@ -41639,10 +41552,9 @@ msgid "multiple ref-qualifiers"
msgstr "upprepade ref-kvalificerare"
#: cp/parser.c:19650
-#, fuzzy, gcc-internal-format
-#| msgid "%<-mfpxx%> requires %<-mlra%>"
+#, gcc-internal-format
msgid "%E requires %<-fgnu-tm%>"
-msgstr "%<-mfpxx%> kräver %<-mlra%>"
+msgstr "%E kräver %<-fgnu-tm%>"
#: cp/parser.c:19706
#, gcc-internal-format
@@ -41865,10 +41777,9 @@ msgid "dynamic exception specifications are deprecated in C++0x; use %<noexcept%
msgstr "dynamiska undantagsspecifikationer undanbedes i C++0x, använd %<noexcept%> istället"
#: cp/parser.c:23153
-#, fuzzy, gcc-internal-format
-#| msgid "invalid use of %<auto%> in conversion operator"
+#, gcc-internal-format
msgid "invalid use of %<auto%> in exception-specification"
-msgstr "ogiltig användning av %<auto%> i konverteringsoperator"
+msgstr "ogiltig användning av %<auto%> i undantagsspecifikation"
#: cp/parser.c:23192
#, gcc-internal-format
@@ -41891,10 +41802,9 @@ msgid "%<deprecated%> is a C++14 feature; use %<gnu::deprecated%>"
msgstr "%<deprecated%> är en funktion i C++14; använd %<gnu::deprecated%>"
#: cp/parser.c:23998
-#, fuzzy, gcc-internal-format
-#| msgid "%qE attribute ignored due to conflict with attribute %qs"
+#, gcc-internal-format
msgid "attribute noreturn can appear at most once in an attribute-list"
-msgstr "attributet %qE ignoreras eftersom det står i konflikt med attributet %qs"
+msgstr "attributet noreturn får förekomma högst en gång i en attributlista"
#: cp/parser.c:24002
#, gcc-internal-format
@@ -41902,16 +41812,14 @@ msgid "attribute deprecated can appear at most once in an attribute-list"
msgstr "attributet deprecated kan förekomma högst en gång i en attributlista"
#: cp/parser.c:24273
-#, fuzzy, gcc-internal-format
-#| msgid "ref-qualifiers only available with -std=c++11 or -std=gnu++11"
+#, gcc-internal-format
msgid "%<requires%> only available with -fconcepts"
-msgstr "ref-kvalificerare är endast tillgängliga med -std=c++11 eller -std=gnu++11"
+msgstr "%<requires%> är endast tillgängligt med -fconcepts"
#: cp/parser.c:24305
-#, fuzzy, gcc-internal-format
-#| msgid "a transaction expression cannot appear in a constant-expression"
+#, gcc-internal-format
msgid "a requires expression cannot appear outside a template"
-msgstr "ett transaktionsuttryck får inte finnas i ett konstantuttryck"
+msgstr "ett transaktionsuttryck får inte finnas utanför en mall"
#: cp/parser.c:25001
#, gcc-internal-format
@@ -41953,16 +41861,14 @@ msgid "literal operator template %qD has invalid parameter list. Expected non-t
msgstr "den literala operatormallen %qD har ogiltig parameterlista. Ett mallargument som inte är en typ pack <char...> förväntades"
#: cp/parser.c:25582
-#, fuzzy, gcc-internal-format
-#| msgid "Enable multiply instructions"
+#, gcc-internal-format
msgid "empty introduction-list"
-msgstr "Använd multiplikationsinstruktioner"
+msgstr "tom introduktionslista"
#: cp/parser.c:25606
-#, fuzzy, gcc-internal-format
-#| msgid "no matching template for %qD found"
+#, gcc-internal-format
msgid "no matching concept for template-introduction"
-msgstr "det finns ingen matchande mall för %qD"
+msgstr "det finns inget matchande koncept för mallintroduktionen"
#: cp/parser.c:25628
#, gcc-internal-format
@@ -41985,10 +41891,9 @@ msgid "template declaration of %<typedef%>"
msgstr "malldeklaration av %<typedef%>"
#: cp/parser.c:25808
-#, fuzzy, gcc-internal-format
-#| msgid "declaration does not declare anything"
+#, gcc-internal-format
msgid "a class template declaration must not declare anything else"
-msgstr "deklaration som inte deklarerar något"
+msgstr "en klassmallsdeklaration får inte deklarera något annat"
#: cp/parser.c:25854
#, gcc-internal-format
@@ -42302,22 +42207,19 @@ msgid "not enough collapsed for loops"
msgstr "inte tillräcklig kollapsat för slingor"
#: cp/parser.c:34003
-#, fuzzy, gcc-internal-format
-#| msgid "%<#pragma omp barrier%> may only be used in compound statements"
+#, gcc-internal-format
msgid "%<#pragma omp ordered%> with %<depend%> clause may only be used in compound statements"
-msgstr "%<#pragma omp barrier%> får bara användas i sammansatta satser"
+msgstr "%<#pragma omp ordered%> med %<depend%>-klausul får bara användas i sammansatta satser"
#: cp/parser.c:34795
-#, fuzzy, gcc-internal-format
-#| msgid "%<#pragma omp target update%> must contain at least one %<from%> or %<to%> clauses"
+#, gcc-internal-format
msgid "%<#pragma omp target exit data%> with map-type other than %<from%>, %<release%> or %<delete%> on %<map%> clause"
-msgstr "%<#pragma omp target update%> måste innehålla åtminstone en %<from%>- eller %<to%>-klausul"
+msgstr "%<#pragma omp target exit data%> med en annan map-typ än %<from%>-, %<release%>- eller %<delete%> på %<map%>-klausul"
#: cp/parser.c:35658
-#, fuzzy, gcc-internal-format
-#| msgid "%<#pragma omp declare simd%> cannot be used in the same function marked as a Cilk Plus SIMD-enabled function"
+#, gcc-internal-format
msgid "%<#pragma omp declare simd%> of %<simd%> attribute cannot be used in the same function marked as a Cilk Plus SIMD-enabled function"
-msgstr "%<#pragma omp declare simd%> kan inte användas i samma funktion som är markerad som en Cilk Plus SIMD-aktiverad funktion"
+msgstr "%<#pragma omp declare simd%> av %<simd%>-attributkan inte användas i samma funktion som är markerad som en Cilk Plus SIMD-aktiverad funktion"
#: cp/parser.c:35668
#, gcc-internal-format
@@ -42370,22 +42272,19 @@ msgid "const, volatile or __restrict qualified type %qT in %<#pragma omp declare
msgstr "const-, volatile- eller __restrict-kvalificerad typ %qT i %<#pragma omp declare reduction%>"
#: cp/parser.c:36517
-#, fuzzy, gcc-internal-format
-#| msgid "%<#pragma acc enter data%> has no data movement clause"
+#, gcc-internal-format
msgid "%<#pragma acc routine%> names a set of overloads"
-msgstr "%<#pragma acc enter data%> har ingen dataflyttningsklausul"
+msgstr "%<#pragma acc routine%> namnger en mängd överlagrade"
#: cp/parser.c:36526
-#, fuzzy, gcc-internal-format
-#| msgid "%<#pragma cilk grainsize%> must be inside a function"
+#, gcc-internal-format
msgid "%<#pragma acc routine%> does not refer to a namespace scope function"
-msgstr "%<#pragma cilk grainsize%> måste vara inuti en funktion"
+msgstr "%<#pragma acc routine%> refererar inte till en funktion med namnrymdsräckvidd"
#: cp/parser.c:36535
-#, fuzzy, gcc-internal-format
-#| msgid "%<#pragma cilk grainsize%> must be inside a function"
+#, gcc-internal-format
msgid "%<#pragma acc routine%> does not refer to a function"
-msgstr "%<#pragma cilk grainsize%> måste vara inuti en funktion"
+msgstr "%<#pragma acc routine%> refererar inte till en funktion"
#. cancel-and-throw is unimplemented.
#: cp/parser.c:36873
@@ -42484,10 +42383,9 @@ msgid "specialization of %qD in different namespace"
msgstr "specialisering av %qD i en annan namnrymd"
#: cp/pt.c:797 cp/pt.c:1024
-#, fuzzy, gcc-internal-format
-#| msgid " from definition of %q+#D"
+#, gcc-internal-format
msgid " from definition of %q#D"
-msgstr " än definitionen av %q+#D"
+msgstr " från definitionen av %q#D"
#: cp/pt.c:814
#, gcc-internal-format
@@ -42619,10 +42517,9 @@ msgid "explicit specialization of %qD must be introduced by %<template <>%>"
msgstr "explicit specialisering av %qD måste inledas av %<template <>%>"
#: cp/pt.c:2715
-#, fuzzy, gcc-internal-format
-#| msgid "explicit specialization of non-template %qT"
+#, gcc-internal-format
msgid "explicit specialization declared %<concept%>"
-msgstr "explicit specialisering av icke-mall %qT"
+msgstr "explicit specialisering deklarerad %<concept%>"
#: cp/pt.c:2746
#, gcc-internal-format
@@ -42668,10 +42565,9 @@ msgid "%qD is not declared in %qD"
msgstr "%qD inte deklarerad i %qD"
#: cp/pt.c:3059
-#, fuzzy, gcc-internal-format
-#| msgid "explicit specialization of non-template %qT"
+#, gcc-internal-format
msgid "explicit specialization of function concept %qD"
-msgstr "explicit specialisering av icke-mall %qT"
+msgstr "explicit specialisering av funktionskonceptet %qD"
#: cp/pt.c:3654
#, gcc-internal-format
@@ -42704,28 +42600,24 @@ msgid " <anonymous>"
msgstr " <anonym>"
#: cp/pt.c:3905
-#, fuzzy, gcc-internal-format
-#| msgid "declaration of %q+D shadows a parameter"
+#, gcc-internal-format
msgid "declaration of template parameter %q+D shadows template parameter"
-msgstr "deklaration av %q+D skuggar en parameter"
+msgstr "deklaration av mallparametern %q+D skuggar en mallparameter"
#: cp/pt.c:3908
-#, fuzzy, gcc-internal-format
-#| msgid "declaration of %q+D shadows a parameter"
+#, gcc-internal-format
msgid "declaration of %q+#D shadows template parameter"
-msgstr "deklaration av %q+D skuggar en parameter"
+msgstr "deklaration av %q+#D skuggar en mallparameter"
#: cp/pt.c:3910
-#, fuzzy, gcc-internal-format
-#| msgid "template parameter type %qT declared %<friend%>"
+#, gcc-internal-format
msgid "template parameter %qD declared here"
-msgstr "mallparametertyp %qT deklarerad %<friend%>"
+msgstr "mallparametern %qD deklarerad här"
#: cp/pt.c:4449
-#, fuzzy, gcc-internal-format
-#| msgid "specialization of alias template %qD"
+#, gcc-internal-format
msgid "specialization of variable concept %q#D"
-msgstr "specialisering av aliasmall %qD"
+msgstr "specialisering av variabelkonceptet %q#D"
#: cp/pt.c:4508
#, gcc-internal-format
@@ -42733,16 +42625,14 @@ msgid "template parameters not deducible in partial specialization:"
msgstr "mallparameter är inte härledbara i partiell specialisering:"
#: cp/pt.c:4532
-#, fuzzy, gcc-internal-format
-#| msgid "partial specialization %qD does not specialize any template arguments"
+#, gcc-internal-format
msgid "partial specialization %q+D does not specialize any template arguments"
-msgstr "partiell specialisering %qD specialiserar inte något mallargument"
+msgstr "partiell specialisering %q+D specialiserar inte något mallargument"
#: cp/pt.c:4535
-#, fuzzy, gcc-internal-format
-#| msgid "partial specialization %qD does not specialize any template arguments"
+#, gcc-internal-format
msgid "partial specialization %q+D does not specialize any template arguments and is not more constrained than"
-msgstr "partiell specialisering %qD specialiserar inte något mallargument"
+msgstr "partiell specialisering %q+D specialiserar inte något mallargument och är inte mer begränsad än"
#: cp/pt.c:4537 cp/pt.c:4548
#, gcc-internal-format
@@ -42777,10 +42667,9 @@ msgstr[0] "typ %qT för mallargument %qE beror på en mallparameter"
msgstr[1] "typ %qT för mallargument %qE beror på mallparametrar"
#: cp/pt.c:4718
-#, fuzzy, gcc-internal-format
-#| msgid "ambiguous template instantiation for %q#D"
+#, gcc-internal-format
msgid "declaration of %qD ambiguates earlier template instantiation for %qD"
-msgstr "tvetydig mallinstansiering av %q#D"
+msgstr "deklaration av %qD gör tidigare mallinstansiering av %qD tvetydig"
#: cp/pt.c:4722
#, gcc-internal-format
@@ -42826,10 +42715,9 @@ msgid "default argument for template parameter for class enclosing %qD"
msgstr "standardargumentet för mallparameter för klass om omsluter %qD"
#: cp/pt.c:5122
-#, fuzzy, gcc-internal-format
-#| msgid "parameter %qD declared void"
+#, gcc-internal-format
msgid "template %qD declared"
-msgstr "parameter %qD deklarerad void"
+msgstr "mallen %qD deklarerad"
#: cp/pt.c:5129
#, gcc-internal-format
@@ -42904,13 +42792,11 @@ msgstr[0] "omdeklarerad med %d mallparameter"
msgstr[1] "omdeklarerad med %d mallparametrar"
#: cp/pt.c:5541
-#, fuzzy, gcc-internal-format
-#| msgid "previous declaration %q+D used %d template parameter"
-#| msgid_plural "previous declaration %q+D used %d template parameters"
+#, gcc-internal-format
msgid "previous declaration %qD used %d template parameter"
msgid_plural "previous declaration %qD used %d template parameters"
-msgstr[0] "tidigare deklaration av %q+D använde %d mallparameter"
-msgstr[1] "tidigare deklaration av %q+D använde %d mallparametrar"
+msgstr[0] "tidigare deklaration av %qD använde %d mallparameter"
+msgstr[1] "tidigare deklaration av %qD använde %d mallparametrar"
#: cp/pt.c:5578
#, gcc-internal-format
@@ -42937,16 +42823,14 @@ msgid "original definition appeared here"
msgstr "ursprunglig definition fanns här"
#: cp/pt.c:5616
-#, fuzzy, gcc-internal-format
-#| msgid "redeclaration %qD differs in %<constexpr%>"
+#, gcc-internal-format
msgid "redeclaration %q#D with different constraints"
-msgstr "omdeklaration av %qD skiljer i %<constexpr%>"
+msgstr "omdeklaration av %q#D med andra begränsningar"
#: cp/pt.c:5619
-#, fuzzy, gcc-internal-format
-#| msgid "original definition appeared here"
+#, gcc-internal-format
msgid "original declaration appeared here"
-msgstr "ursprunglig definition fanns här"
+msgstr "ursprunglig deklaration fanns här"
#: cp/pt.c:5872 cp/pt.c:5923
#, gcc-internal-format
@@ -43126,16 +43010,14 @@ msgid "%q#D is not a valid template argument for type %qT because a reference va
msgstr "%q#D är inte ett giltigt mallargument till typen %qT eftersom en referensvariabel inte har en konstant adress"
#: cp/pt.c:6533
-#, fuzzy, gcc-internal-format
-#| msgid "%qE is not a valid template argument for type %qT because it is not an object with external linkage"
+#, gcc-internal-format
msgid "%qE is not a valid template argument for type %qT because it is not an object with linkage"
-msgstr "%qE är inte ett giltigt mallargument för typen %qT eftersom det inte är ett objekt med extern länkklass"
+msgstr "%qE är inte ett giltigt mallargument för typen %qT eftersom det inte är ett objekt med länkklass"
#: cp/pt.c:6544
-#, fuzzy, gcc-internal-format
-#| msgid "%qE is not a valid template argument for type %qT because object %qD has not external linkage"
+#, gcc-internal-format
msgid "%qE is not a valid template argument for type %qT because object %qD does not have linkage"
-msgstr "%qE är inte ett giltigt mallargument för typ %qT eftersom objekt %qD inte har extern länkklass"
+msgstr "%qE är inte ett giltigt mallargument för typ %qT eftersom objekt %qD inte har någon länkklass"
#: cp/pt.c:6590
#, gcc-internal-format
@@ -43213,16 +43095,14 @@ msgid " expected a template of type %qD, got %qT"
msgstr " förväntade en mall av typen %qD, fick %qT"
#: cp/pt.c:7202
-#, fuzzy, gcc-internal-format
-#| msgid "type/value mismatch at argument %d in template parameter list for %qD"
+#, gcc-internal-format
msgid "constraint mismatch at argument %d in template parameter list for %qD"
-msgstr "typ/värde stämmer inte vid argument %d i mallparameterlistan till %qD"
+msgstr "begränsningar stämmer inte vid argument %d i mallparameterlistan till %qD"
#: cp/pt.c:7205
-#, fuzzy, gcc-internal-format
-#| msgid " expected a type, got %qE"
+#, gcc-internal-format
msgid " expected %qD but got %qD"
-msgstr " förväntade en typ, fick %qE"
+msgstr " %qD förväntades men fick %qD"
#. Not sure if this is reachable, but it doesn't hurt
#. to be robust.
@@ -43252,10 +43132,9 @@ msgid "wrong number of template arguments (%d, should be at least %d)"
msgstr "fel antal mallargument (%d, skulle vara åtminstone %d)"
#: cp/pt.c:7547
-#, fuzzy, gcc-internal-format
-#| msgid "provided for %q+D"
+#, gcc-internal-format
msgid "provided for %qD"
-msgstr "angivna till %q+D"
+msgstr "angivna till %qD"
#: cp/pt.c:7572
#, gcc-internal-format
@@ -43263,10 +43142,9 @@ msgid "pack expansion argument for non-pack parameter %qD of alias template %qD"
msgstr "pack-expansionsargument för icke-pack-parametern %qD till aliasmall %qD"
#: cp/pt.c:7576
-#, fuzzy, gcc-internal-format
-#| msgid "pack expansion argument for non-pack parameter %qD of alias template %qD"
+#, gcc-internal-format
msgid "pack expansion argument for non-pack parameter %qD of concept %qD"
-msgstr "pack-expansionsargument för icke-pack-parametern %qD till aliasmall %qD"
+msgstr "pack-expansionsargument för icke-pack-parametern %qD till konceptet %qD"
#: cp/pt.c:7668
#, gcc-internal-format
@@ -43294,16 +43172,14 @@ msgid "for template declaration %q+D"
msgstr "för malldeklaration %q+D"
#: cp/pt.c:8339
-#, fuzzy, gcc-internal-format
-#| msgid "internal consistency failure"
+#, gcc-internal-format
msgid "template constraint failure"
-msgstr "internt konsistensfel"
+msgstr "mallbegränsningsfel"
#: cp/pt.c:8683
-#, fuzzy, gcc-internal-format
-#| msgid "constructors may not be cv-qualified"
+#, gcc-internal-format
msgid "constraints for %qD not satisfied"
-msgstr "konstruerare får inte vara cv-kvalificerade"
+msgstr "begränsningarna för %qD är inte uppfyllda"
#: cp/pt.c:9075
#, gcc-internal-format, gfc-internal-format
@@ -43489,10 +43365,9 @@ msgid "use %<%T::%D%> instead"
msgstr "använd %<%T::%D%> istället"
#: cp/pt.c:16574
-#, fuzzy, gcc-internal-format
-#| msgid "%q+D declared here, later in the translation unit"
+#, gcc-internal-format
msgid "%qD declared here, later in the translation unit"
-msgstr "%q+D är deklarerad här, senare i översättningsenheten"
+msgstr "%qD är deklarerad här, senare i översättningsenheten"
#: cp/pt.c:16847
#, gcc-internal-format
@@ -43671,22 +43546,19 @@ msgid "placeholder constraints not satisfied"
msgstr "platshållabegränsningar är inte uppfyllt"
#: cp/pt.c:24036
-#, fuzzy, gcc-internal-format
-#| msgid "insn does not satisfy its constraints:"
+#, gcc-internal-format
msgid "deduced initializer does not satisfy placeholder constraints"
-msgstr "instruktionen håller inte sina begränsningar:"
+msgstr "härledd initierare uppfyller inte sina platshållarbegränsningar"
#: cp/pt.c:24040
-#, fuzzy, gcc-internal-format
-#| msgid "insn does not satisfy its constraints:"
+#, gcc-internal-format
msgid "deduced return type does not satisfy placeholder constraints"
-msgstr "instruktionen håller inte sina begränsningar:"
+msgstr "härledd returtyp uppfyller inte sina platshållarbegränsningar"
#: cp/pt.c:24044
-#, fuzzy, gcc-internal-format
-#| msgid "insn does not satisfy its constraints:"
+#, gcc-internal-format
msgid "deduced expression type does not saatisy placeholder constraints"
-msgstr "instruktionen håller inte sina begränsningar:"
+msgstr "härledd uttryckstyp uppfyller inte sina platshållarbegränsningar"
#: cp/repo.c:113
#, gcc-internal-format
@@ -43754,10 +43626,9 @@ msgid "invalid covariant return type for %q#D"
msgstr "ogiltig kovariant returtyp för %q#D"
#: cp/search.c:2054
-#, fuzzy, gcc-internal-format
-#| msgid " overriding %q+#D"
+#, gcc-internal-format
msgid " overriding %q#D"
-msgstr " åsidosätter %q+#D"
+msgstr " åsidosätter %q#D"
#: cp/search.c:2067
#, gcc-internal-format
@@ -43790,16 +43661,14 @@ msgid "conflicting type attributes specified for %q+#D"
msgstr "motstridiga typattribut angivna för %q+#D"
#: cp/search.c:2115
-#, fuzzy, gcc-internal-format
-#| msgid "expected %<__transaction_atomic%>"
+#, gcc-internal-format
msgid "%qD declared %<transaction_safe_dynamic%>"
-msgstr "%<__transaction_atomic%> förväntades"
+msgstr "%qD deklarerad %<transaction_safe_dynamic%>"
#: cp/search.c:2117
-#, fuzzy, gcc-internal-format
-#| msgid "variable %q+D declared %<inline%>"
+#, gcc-internal-format
msgid "overriding %qD declared %<transaction_safe%>"
-msgstr "variabeln %q+D deklarerad %<inline%>"
+msgstr "åsidosätter %qD deklarerad %<transaction_safe%>"
#: cp/search.c:2124
#, gcc-internal-format
@@ -44038,16 +43907,14 @@ msgid "user defined reduction lookup is ambiguous"
msgstr "användardefinierad reduktionsuppslagning är tvetydig"
#: cp/semantics.c:5496
-#, fuzzy, gcc-internal-format
-#| msgid "%qE in %<aligned%> clause is neither a pointer nor an array"
+#, gcc-internal-format
msgid "%qE in %<reduction%> clause is a zero size array"
-msgstr "%qE i %<aligned%>-klausul är varken en pekare eller en vektor"
+msgstr "%qE i %<reduction%>-klausul är en vektor med storlek noll"
#: cp/semantics.c:5544
-#, fuzzy, gcc-internal-format
-#| msgid "%qE has invalid type for %<reduction%>"
+#, gcc-internal-format
msgid "%qE has const type for %<reduction%>"
-msgstr "%qE har ogiltig typ för %<reduction%>"
+msgstr "%qE har const-typ för %<reduction%>"
#: cp/semantics.c:5656
#, gcc-internal-format
@@ -44055,10 +43922,9 @@ msgid "user defined reduction with constructor initializer for base class %qT"
msgstr "användardefinierad reduktion med konstruerarinitierare för basklassen %qT"
#: cp/semantics.c:5878
-#, fuzzy, gcc-internal-format
-#| msgid "linear clause applied to non-integral non-pointer variable with %qT type"
+#, gcc-internal-format
msgid "linear clause with %qs modifier applied to non-reference variable with %qT type"
-msgstr "linjär klausul tillämpad på en variabel som inte är heltal och inte pekare med typen %qT"
+msgstr "linjär klausul med modifieraren %qs tillämpad på en variabel som inte är en referens med typen %qT"
#: cp/semantics.c:5890
#, gcc-internal-format
@@ -44086,64 +43952,54 @@ msgid "%qD is not a variable in clause %<lastprivate%>"
msgstr "%qD är inte en variabel i klausul %<lastprivate%>"
#: cp/semantics.c:6154
-#, fuzzy, gcc-internal-format
-#| msgid "%<async%> expression must be integral"
+#, gcc-internal-format
msgid "%<gang%> static expression must be integral"
-msgstr "%<async%>-uttryck måste vara heltal"
+msgstr "%<gang%>-statisk uttryck måste vara heltal"
#: cp/semantics.c:6168
-#, fuzzy, gcc-internal-format
-#| msgid "%<num_gangs%> value must be positive"
+#, gcc-internal-format
msgid "%<gang%> static value must bepositive"
-msgstr "%<num_gangs%>-värdet måste vara positivt"
+msgstr "%<gang%>-statiskt värde måste vara positivt"
#: cp/semantics.c:6200
-#, fuzzy, gcc-internal-format
-#| msgid "%<async%> expression must be integral"
+#, gcc-internal-format
msgid "%<gang%> num expression must be integral"
-msgstr "%<async%>-uttryck måste vara heltal"
+msgstr "%<gang%>-numeriskt uttryck måste vara ett heltal"
#: cp/semantics.c:6203
-#, fuzzy, gcc-internal-format
-#| msgid "%qs length expression must be integral"
+#, gcc-internal-format
msgid "%<vector%> length expression must be integral"
-msgstr "%qs-längduttryck måste vara ett heltal"
+msgstr "%<vector%>-längduttryck måste vara ett heltal"
#: cp/semantics.c:6207
-#, fuzzy, gcc-internal-format
-#| msgid "%<wait%> expression must be integral"
+#, gcc-internal-format
msgid "%<worker%> num expression must be integral"
-msgstr "%<wait%>-uttryck måste vara heltal"
+msgstr "%<worker%>-numeriskt uttryck måste vara ett heltal"
#: cp/semantics.c:6211
-#, fuzzy, gcc-internal-format
-#| msgid "expression must be integral"
+#, gcc-internal-format
msgid "%qs expression must be integral"
-msgstr "uttrycket måste vara ett heltal"
+msgstr "%qs-uttrycket måste vara ett heltal"
#: cp/semantics.c:6229
-#, fuzzy, gcc-internal-format
-#| msgid "%<num_gangs%> value must be positive"
+#, gcc-internal-format
msgid "%<gang%> num value must be positive"
-msgstr "%<num_gangs%>-värdet måste vara positivt"
+msgstr "%<gang%>-numeriskt värde måste vara positivt"
#: cp/semantics.c:6233
-#, fuzzy, gcc-internal-format
-#| msgid "%<vector_length%> value must be positive"
+#, gcc-internal-format
msgid "%<vector%> length value must bepositive"
-msgstr "%<vector_length%>-värdet måste vara positivt"
+msgstr "%<vector%>-längdvärdet måste vara positivt"
#: cp/semantics.c:6238
-#, fuzzy, gcc-internal-format
-#| msgid "%<num_workers%> value must be positive"
+#, gcc-internal-format
msgid "%<worker%> num value must bepositive"
-msgstr "%<num_workers%>-värdet måste vara positivt"
+msgstr "%<worker%>-numerikst värde måste vara positivt"
#: cp/semantics.c:6243
-#, fuzzy, gcc-internal-format
-#| msgid "%<num_gangs%> value must be positive"
+#, gcc-internal-format
msgid "%qs value must be positive"
-msgstr "%<num_gangs%>-värdet måste vara positivt"
+msgstr "%qs-värdet måste vara positivt"
#: cp/semantics.c:6290
#, gcc-internal-format
@@ -44211,34 +44067,29 @@ msgid "overloaded function name %qE in clause %qs"
msgstr "överlagrad funktion med namnet %qE i klausulen %qs"
#: cp/semantics.c:6813
-#, fuzzy, gcc-internal-format
-#| msgid "too many %qs clauses"
+#, gcc-internal-format
msgid "template %qE in clause %qs"
-msgstr "för många %qs-klausuler"
+msgstr "mallen %qE i-klausulen %qs"
#: cp/semantics.c:6878
-#, fuzzy, gcc-internal-format
-#| msgid "%<wait%> expression must be integral"
+#, gcc-internal-format
msgid "%<grainsize%> expression must be integral"
-msgstr "%<wait%>-uttryck måste vara heltal"
+msgstr "%<grainsize%>-uttryck måste vara ett heltal"
#: cp/semantics.c:6907
-#, fuzzy, gcc-internal-format
-#| msgid "%<wait%> expression must be integral"
+#, gcc-internal-format
msgid "%<priority%> expression must be integral"
-msgstr "%<wait%>-uttryck måste vara heltal"
+msgstr "%<priority%>-uttryck måste vara ett heltal"
#: cp/semantics.c:6936
-#, fuzzy, gcc-internal-format
-#| msgid "%<num_teams%> expression must be integral"
+#, gcc-internal-format
msgid "%<num_tasks%> expression must be integral"
-msgstr "%<num_teams%>-uttryck måste vara heltal"
+msgstr "%<num_tasks%>-uttryck måste vara ett heltal"
#: cp/semantics.c:6965
-#, fuzzy, gcc-internal-format
-#| msgid "%qE in %<aligned%> clause is neither a pointer nor an array nor a reference to pointer or array"
+#, gcc-internal-format
msgid "%qs variable is neither a pointer, nor an arraynor reference to pointer or array"
-msgstr "%qE i %<aligned%>-klausul är varken en pekare eller en vektor eller en referens till pekare eller vektor"
+msgstr "%qs-variabeln är varken en pekare, eller en vektor eller en referens till pekare eller vektor"
#: cp/semantics.c:7421
#, gcc-internal-format
@@ -44266,10 +44117,9 @@ msgid "%<#pragma omp atomic update%> uses two different expressions for memory"
msgstr "%<#pragma omp atomic update%> använder två olika uttryck för minne"
#: cp/semantics.c:8705
-#, fuzzy, gcc-internal-format
-#| msgid "static assertion failed: %E"
+#, gcc-internal-format
msgid "static assertion failed"
-msgstr "statisk försäkran misslyckades: %E"
+msgstr "statisk försäkran misslyckades"
#: cp/semantics.c:8707
#, gcc-internal-format, gfc-internal-format
@@ -44292,16 +44142,14 @@ msgid "decltype cannot resolve address of overloaded function"
msgstr "decltype kan inte lösa upp adressen till en överlagrad funktion"
#: cp/semantics.c:9299
-#, fuzzy, gcc-internal-format
-#| msgid "third operand of conditional expression has no effect"
+#, gcc-internal-format
msgid "operand of fold expression has no unexpanded parameter packs"
-msgstr "tredje operanden av villkorsuttryck har ingen effekt"
+msgstr "operanden till vikningsuttrycket har inget oexpanderat parameterpaket"
#: cp/semantics.c:9352
-#, fuzzy, gcc-internal-format
-#| msgid "template argument %qE involves template parameter(s)"
+#, gcc-internal-format
msgid "both arguments in binary fold have unexpanded parameter packs"
-msgstr "mallargument %qE berör mallparametrar"
+msgstr "båda argumentet i en binär vikning har oexpanderade parameterpaket"
#: cp/semantics.c:9354
#, gcc-internal-format
@@ -44509,10 +44357,9 @@ msgid "ISO C++ forbids applying %<__alignof%> to an expression of function type"
msgstr "ISO C++ förbjuder användning av %<__alignof%> på ett uttryck med funktionstyp"
#: cp/typeck.c:1836
-#, fuzzy, gcc-internal-format
-#| msgid "invalid use of non-static member function %qD"
+#, gcc-internal-format
msgid "invalid use of non-static member function of type %qT"
-msgstr "ogiltig användning av icke-statisk medlemsfunktion %qD"
+msgstr "ogiltig användning av icke-statisk medlemsfunktion av typen %qT"
#: cp/typeck.c:2001
#, gcc-internal-format
@@ -44570,10 +44417,9 @@ msgid "%qT is not a base of %qT"
msgstr "%qT är inte en basklass till %qT"
#: cp/typeck.c:2820
-#, fuzzy, gcc-internal-format
-#| msgid "%q#T has no member named %qE"
+#, gcc-internal-format
msgid "%q#T has no member named %qE; did you mean %qE?"
-msgstr "%q#T har ingen medlem med namnet %qE"
+msgstr "%q#T har ingen medlem med namnet %qE, menade du %qE?"
#: cp/typeck.c:2824
#, gcc-internal-format
@@ -44636,10 +44482,9 @@ msgid "object missing in use of %qE"
msgstr "objekt saknas i användning av %qE"
#: cp/typeck.c:3535
-#, fuzzy, gcc-internal-format
-#| msgid "cannot disable built-in function %qs"
+#, gcc-internal-format
msgid "cannot call function %qD"
-msgstr "det går inte att avaktivera den inbyggda funktionen %qs"
+msgstr "det går inte att anropa funktionen %qD"
#: cp/typeck.c:3550
#, gcc-internal-format
@@ -44732,10 +44577,9 @@ msgid "the address of %qD will never be NULL"
msgstr "adressen till %qD kommer aldrig vara NULL"
#: cp/typeck.c:4004
-#, fuzzy, gcc-internal-format
-#| msgid "the comparison will always evaluate as %<true%> for the address of %qD will never be NULL"
+#, gcc-internal-format
msgid "the compiler can assume that the address of %qD will never be NULL"
-msgstr "jämförelsen kommer alltid beräknas till %<true%> för adressen till %qD kommer aldrig att vara NULL"
+msgstr "kompilatorn kan anta att adressen till %qD aldrig kommer att vara NULL"
#: cp/typeck.c:4123 cp/typeck.c:4134
#, gcc-internal-format
@@ -45150,10 +44994,9 @@ msgid "left-hand side of assignment might be a candidate for a format attribute"
msgstr "vänsterhandssida av tilldelning kan vara en kandidat för ett formatattribut"
#: cp/typeck.c:8523
-#, fuzzy, gcc-internal-format
-#| msgid "in passing argument %P of %q+D"
+#, gcc-internal-format
msgid "in passing argument %P of %qD"
-msgstr "när argument %P till %q+D skickades"
+msgstr "när argument %P till %qD skickades"
#: cp/typeck.c:8582
#, gcc-internal-format
@@ -45166,22 +45009,19 @@ msgid "reference to non-lvalue returned"
msgstr "referens till annat än lvärde returnerad"
#: cp/typeck.c:8604
-#, fuzzy, gcc-internal-format
-#| msgid "reference to local variable %q+D returned"
+#, gcc-internal-format
msgid "reference to local variable %qD returned"
-msgstr "referens till lokal variabel %q+D returnerad"
+msgstr "referens till lokal variabel %qD returnerad"
#: cp/typeck.c:8608
-#, fuzzy, gcc-internal-format
-#| msgid "address of label %q+D returned"
+#, gcc-internal-format
msgid "address of label %qD returned"
-msgstr "adressen till etiketten %q+D returnerad"
+msgstr "adressen till etiketten %qD returnerad"
#: cp/typeck.c:8612
-#, fuzzy, gcc-internal-format
-#| msgid "address of local variable %q+D returned"
+#, gcc-internal-format
msgid "address of local variable %qD returned"
-msgstr "adress till lokal variabel %q+D returnerad"
+msgstr "adress till lokal variabel %qD returnerad"
#: cp/typeck.c:8658
#, gcc-internal-format
@@ -45218,10 +45058,9 @@ msgid "inconsistent types %qT and %qT deduced for lambda return type"
msgstr "inkonsistenta typer %qT och %qT härledda för lambda-returtypen"
#: cp/typeck.c:8729
-#, fuzzy, gcc-internal-format
-#| msgid "inconsistent deduction for %qT: %qT and then %qT"
+#, gcc-internal-format
msgid "inconsistent deduction for auto return type: %qT and then %qT"
-msgstr "inkonsistent härledning för %qT: %qT och sedan %qT"
+msgstr "inkonsistent härledning för auto-returtyp: %qT och sedan %qT"
#: cp/typeck.c:8764
#, gcc-internal-format
@@ -45396,10 +45235,9 @@ msgid "declaration of %q#T"
msgstr "deklaration av %q#T"
#: cp/typeck2.c:472
-#, fuzzy, gcc-internal-format
-#| msgid "%q#D has incomplete type"
+#, gcc-internal-format
msgid "%qD has incomplete type"
-msgstr "%q#D har ofullständig typ"
+msgstr "%qD har ofullständig typ"
#: cp/typeck2.c:487
#, gcc-internal-format
@@ -45412,16 +45250,14 @@ msgid "invalid use of %qT"
msgstr "ogiltigt användning av %qT"
#: cp/typeck2.c:517
-#, fuzzy, gcc-internal-format
-#| msgid "invalid use of member function (did you forget the %<()%> ?)"
+#, gcc-internal-format
msgid "invalid use of member function %qD (did you forget the %<()%> ?)"
-msgstr "ogiltig användning av medlemsfunktion (glömde du %<()%> ?)"
+msgstr "ogiltig användning av medlemsfunktionen %qD (glömde du %<()%> ?)"
#: cp/typeck2.c:521
-#, fuzzy, gcc-internal-format
-#| msgid "invalid use of member (did you forget the %<&%> ?)"
+#, gcc-internal-format
msgid "invalid use of member %qD (did you forget the %<&%> ?)"
-msgstr "ogiltig användning av medlem (glömde du %<&%>?)"
+msgstr "ogiltig användning av medlem %qD (glömde du %<&%>?)"
#: cp/typeck2.c:532
#, gcc-internal-format
@@ -45474,10 +45310,9 @@ msgid "narrowing conversion of %qE from %qT to %qT inside { }"
msgstr "avsmalnande konvertering av %qE från %qT till %qT inuti { }"
#: cp/typeck2.c:958
-#, fuzzy, gcc-internal-format
-#| msgid "expression in static assertion is not an integer constant expression"
+#, gcc-internal-format
msgid " the expression has a constant value but is not a C++ constant-expression"
-msgstr "uttryck i statisk försäkran är inte ett konstant heltalsuttryck"
+msgstr " uttrycket har ett konstant värde men är inte ett C++ konstant uttryck"
#: cp/typeck2.c:1044
#, gcc-internal-format
@@ -45744,16 +45579,14 @@ msgstr "Konvertering från %qs till %qs vid %L"
#: fortran/arith.c:2075 fortran/arith.c:2108 fortran/arith.c:2147
#: fortran/arith.c:2205 fortran/arith.c:2257 fortran/arith.c:2317
#: fortran/arith.c:2386
-#, fuzzy, gcc-internal-format
-#| msgid "Change of value in conversion from %qs to %qs at %L"
+#, gcc-internal-format
msgid "Change of value in conversion from %qs to %qs at %L"
msgstr "Ändring av värde vid konvertering från %qs till %qs vid %L"
#: fortran/arith.c:2303 fortran/arith.c:2372
-#, fuzzy, gcc-internal-format
-#| msgid "Possible change of value in conversion from %qs to %qs at %L"
+#, gcc-internal-format
msgid "Non-zero imaginary part discarded in conversion from %qs to %qs at %L"
-msgstr "Möjlig ändring av värde vid konvertering från %qs till %qs vid %L"
+msgstr "Icke tom imaginär del kastades vid konvertering från %qs till %qs vid %L"
#: fortran/arith.c:2455
#, gcc-internal-format
@@ -45849,10 +45682,9 @@ msgid "Expected expression in array specification at %C"
msgstr "Förväntade uttryck i vektorspecifikation vid %C"
#: fortran/array.c:431 fortran/array.c:463
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Expected scalar initialization expression at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "Expecting a scalar INTEGER expression at %C, found %s"
-msgstr "Ett skalärt initieringsuttryck förväntades vid %C"
+msgstr "Ett skalärt INTEGER-uttryck förväntades vid %C, hittade %s"
#: fortran/array.c:500
#, gcc-internal-format, gfc-internal-format
@@ -45950,10 +45782,9 @@ msgid "Empty array constructor at %C is not allowed"
msgstr "Tom vektorkonstruerare vid %C är inte tillåtet"
#: fortran/array.c:1188 fortran/array.c:1198
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "incompatible type for argument %d of %qE"
+#, gcc-internal-format, gfc-internal-format
msgid "Incompatible typespec for array element at %L"
-msgstr "inkompatibel typ för argument %d av %qE"
+msgstr "Inkompatibel typspecifikation för vektorelement vid %L"
#: fortran/array.c:1264
#, gcc-internal-format, gfc-internal-format
@@ -46223,10 +46054,9 @@ msgid "ATOM argument at %L of the %s intrinsic function shall be a coarray or co
msgstr "ATOM-argumentet till vid %L till den inbyggda funktionen %s måste vara en co-vektor eller co-indexat"
#: fortran/check.c:1042
-#, fuzzy, gcc-internal-format
-#| msgid "'%s' argument of '%s' intrinsic at %L shall have the same type as '%s' at %L"
+#, gcc-internal-format
msgid "%qs argument of %qs intrinsic at %L shall have the same type as %qs at %L"
-msgstr "”%s”-argumentet till inbyggd ”%s” vid %L måste ha samma typ och sort som ”%s” vid %L"
+msgstr "%qs-argumentet till inbyggd %qs vid %L måste ha samma typ som %qs vid %L"
#: fortran/check.c:1060 fortran/check.c:1205
#, gcc-internal-format, gfc-internal-format
@@ -46254,22 +46084,19 @@ msgid "OLD argument of the %s intrinsic function at %L shall be definable"
msgstr "OLD-argumentet till den inbyggda funktionen %s vid %L måste vara definierbart"
#: fortran/check.c:1167
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "The A argument at %L to the intrinsic %s shall not be coindexed"
+#, gcc-internal-format, gfc-internal-format
msgid "EVENT argument at %L to the intrinsic EVENT_QUERY shall be of type EVENT_TYPE"
-msgstr "Argumentet A vid %L till den inbyggda %s skall inte vara co-indexerat"
+msgstr "EVENT-argumentetet vid %L till den inbyggda EVENT_QUERY skall ha typen EVENT_TYPE"
#: fortran/check.c:1177
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "OLD argument of the %s intrinsic function at %L shall be definable"
+#, gcc-internal-format, gfc-internal-format
msgid "COUNT argument of the EVENT_QUERY intrinsic function at %L shall be definable"
-msgstr "OLD-argumentet till den inbyggda funktionen %s vid %L måste vara definierbart"
+msgstr "COUNT-argumentet till den inbyggda funktionen EVENT_QUERY vid %L måste vara definierbart"
#: fortran/check.c:1190
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "OLD argument of the %s intrinsic function at %L shall be definable"
+#, gcc-internal-format, gfc-internal-format
msgid "COUNT argument of the EVENT_QUERY intrinsic function at %L shall have at least the range of the default integer"
-msgstr "OLD-argumentet till den inbyggda funktionen %s vid %L måste vara definierbart"
+msgstr "COUNT-argumentet till den inbyggda funktionen EVENT_QUERY vid %L måste ha åtminstone intervallet för standardheltal"
#: fortran/check.c:1269
#, gcc-internal-format, gfc-internal-format
@@ -46395,10 +46222,9 @@ msgid "The character length of the A argument at %L and of the function result o
msgstr "Teckenlängden för argumentet A vid %L och funktionsresultatet av OPERATOR vid %L skall vara samma"
#: fortran/check.c:1744
-#, fuzzy, gcc-internal-format
-#| msgid "'%s' argument of '%s' intrinsic at %L shall be of type integer, real or character"
+#, gcc-internal-format
msgid "%qs argument of %qs intrinsic at %L shall be of type integer, real or character"
-msgstr "Argument ”%s” till inbyggd ”%s” vid %L skall ha typen heltal, reell eller tecken"
+msgstr "Argument %qs till inbyggd %qs vid %L skall ha typen heltal, reell eller tecken"
#: fortran/check.c:1792 fortran/check.c:2324 fortran/check.c:2427
#: fortran/check.c:2628 fortran/check.c:2673 fortran/check.c:3984
@@ -46434,10 +46260,9 @@ msgid "%qs argument of %qs intrinsic at %L must be default real"
msgstr "%qs-argumentet till inbyggd %qs vid %L måste vara standard reell"
#: fortran/check.c:2020
-#, fuzzy, gcc-internal-format
-#| msgid "'I' at %L and 'J' at %L cannot both be BOZ literal constants"
+#, gcc-internal-format
msgid "%<I%> at %L and %<J%>' at %L cannot both be BOZ literal constants"
-msgstr "”I” vid %L och ”J” vid %L kan inte båda vara literala BOZ-konstanter"
+msgstr "%<I%> vid %L och %<J%> vid %L kan inte båda vara literala BOZ-konstanter"
#: fortran/check.c:2151
#, gcc-internal-format, gfc-internal-format
@@ -46625,10 +46450,9 @@ msgid "%qs argument of %qs intrinsic at %L has negative element (%d)"
msgstr "%qs-argumentet till inbyggd %qs vid %L har negativa element (%d)"
#: fortran/check.c:3799
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Complex argument of LOG at %L cannot be zero"
+#, gcc-internal-format, gfc-internal-format
msgid "Element %d of actual argument of RESHAPE at %L cannot be negative"
-msgstr "Komplext argument till LOG vid %L får inte vara noll"
+msgstr "Elementet %d av aktuellt argument till RESHAPE vid %L får inte vara negativt"
#: fortran/check.c:3837
#, gcc-internal-format
@@ -46641,10 +46465,9 @@ msgid "%qs argument of %qs intrinsic at %L has out-of-range dimension (%d)"
msgstr "%qs-argumentet till inbyggd %qs vid %L har dimension utanför giltigt intervall (%d)"
#: fortran/check.c:3864
-#, fuzzy, gcc-internal-format
-#| msgid "%qs argument of %qs intrinsic at %L has invalid permutation of dimensions (dimension %<%d%> duplicated)"
+#, gcc-internal-format
msgid "%qs argument of %qs intrinsic at %L has invalid permutation of dimensions (dimension %qd duplicated)"
-msgstr "%qs-argumentet till inbyggd %qs vid %L har en ogiltig permutation av dimensioner (dimension %<%d%> dubblerad)"
+msgstr "%qs-argumentet till inbyggd %qs vid %L har en ogiltig permutation av dimensioner (dimension %qd dubblerad)"
#: fortran/check.c:3900
#, gcc-internal-format, gfc-internal-format
@@ -46927,10 +46750,9 @@ msgid "fe_runtime_error string must be null terminated"
msgstr "fe_runtime_error-sträng måste vara null-terminerad"
#: fortran/check.c:5646
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "wrong number of template arguments (%d, should be %d)"
+#, gcc-internal-format, gfc-internal-format
msgid "fe_runtime_error: Wrong number of arguments (%d instead of %d)"
-msgstr "fel antal mallargument (%d, skulle vara %d)"
+msgstr "fe_runtime_error: Fel antal argument (%d istället för %d)"
#: fortran/check.c:5686
#, gcc-internal-format, gfc-internal-format
@@ -47010,16 +46832,14 @@ msgid "Unused initialization string at %L because variable has zero length"
msgstr "Oanvänd initieringssträng vid %L för att variabeln har nollängd"
#: fortran/data.c:176
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Initialization string starting at %L was truncated to fit the variable (%d/%d)"
+#, gcc-internal-format, gfc-internal-format
msgid "Initialization string at %L was truncated to fit the variable (%d/%d)"
-msgstr "Initieringssträng som startar vid %L höggs av för att stämma med variabeln (%d/%d)"
+msgstr "Initieringssträng vid %L höggs av för att stämma med variabeln (%d/%d)"
#: fortran/data.c:266
-#, fuzzy, gcc-internal-format
-#| msgid "'%s' at %L already is initialized at %L"
+#, gcc-internal-format
msgid "%qs at %L already is initialized at %L"
-msgstr "”%s” vid %L är redan initierad vid %L"
+msgstr "%qs vid %L är redan initierad vid %L"
#: fortran/data.c:290
#, gcc-internal-format, gfc-internal-format
@@ -47067,10 +46887,9 @@ msgid "Initialization at %C is not allowed in a PURE procedure"
msgstr "Initieringen vid %C får inte förekomma i en PURE-procedur"
#: fortran/decl.c:560
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "ENTRY statement at %C cannot appear within an INTERFACE"
+#, gcc-internal-format, gfc-internal-format
msgid "DATA statement at %C cannot appear within an INTERFACE"
-msgstr "ENTRY-sats vid %C kan inte förekomma inuti ett INTERFACE"
+msgstr "DATA-sats vid %C kan inte förekomma inuti ett INTERFACE"
#: fortran/decl.c:592
#, gcc-internal-format, gfc-internal-format
@@ -47108,22 +46927,19 @@ msgid "Syntax error in character length specification at %C"
msgstr "Syntaxfel i specifikation av teckenlängd vid %C"
#: fortran/decl.c:990
-#, fuzzy, gcc-internal-format
-#| msgid "Procedure '%s' at %C is already defined at %L"
+#, gcc-internal-format
msgid "Procedure %qs at %C is already defined at %L"
-msgstr "Proceduren ”%s” vid %C är redan definierad vid %L"
+msgstr "Proceduren %qs vid %C är redan definierad vid %L"
#: fortran/decl.c:998
-#, fuzzy, gcc-internal-format
-#| msgid "Name '%s' at %C is already defined as a generic interface at %L"
+#, gcc-internal-format
msgid "Name %qs at %C is already defined as a generic interface at %L"
-msgstr "Namnet ”%s” vid %C är redan definierat som ett generiskt gränssnitt vid %L"
+msgstr "Namnet %qs vid %C är redan definierat som ett generiskt gränssnitt vid %L"
#: fortran/decl.c:1011
-#, fuzzy, gcc-internal-format
-#| msgid "Procedure '%s' at %C has an explicit interface and must not have attributes declared at %L"
+#, gcc-internal-format
msgid "Procedure %qs at %C has an explicit interface and must not have attributes declared at %L"
-msgstr "Proceduren ”%s” vid %C har ett explicit gränssnitt och får inte ha attribut deklarerade vid %L"
+msgstr "Proceduren %qs vid %C har ett explicit gränssnitt och får inte ha attribut deklarerade vid %L"
#: fortran/decl.c:1082
#, gcc-internal-format
@@ -47176,16 +46992,14 @@ msgid "Variable %qs at %L with OPTIONAL attribute in procedure %qs which is BIND
msgstr "Variabeln %qs vid %L med attributet OPTIONAL i proceduren %qs som är BIND(C)"
#: fortran/decl.c:1195
-#, fuzzy, gcc-internal-format
-#| msgid "Assumed-shape array '%s' at %L as dummy argument to the BIND(C) procedure '%s' at %L"
+#, gcc-internal-format
msgid "Assumed-shape array %qs at %L as dummy argument to the BIND(C) procedure %qs at %L"
-msgstr "Vektorn ”%s” med antagen form vid %L som attrappargument till BIND(C)-proceduren ”%s” vid %L"
+msgstr "Vektorn %qs med antagen form vid %L som attrappargument till BIND(C)-proceduren %qs vid %L"
#: fortran/decl.c:1244
-#, fuzzy, gcc-internal-format
-#| msgid "Symbol %qs at %L already has basic type of %s"
+#, gcc-internal-format
msgid "Symbol %qs at %C also declared as a type at %L"
-msgstr "Symbolen %qs vid %L har redan grundtypen %s"
+msgstr "Symbolen %qs vid %C är också deklarerad som en typ vid %L"
#: fortran/decl.c:1303
#, gcc-internal-format
@@ -47435,10 +47249,9 @@ msgid "Type name %qs at %C is ambiguous"
msgstr "Typnamnet %qs vid %C är tvetydigt"
#: fortran/decl.c:3005
-#, fuzzy, gcc-internal-format
-#| msgid "Type name '%s' at %C conflicts with previously declared entity at %L, which has the same name"
+#, gcc-internal-format
msgid "Type name %qs at %C conflicts with previously declared entity at %L, which has the same name"
-msgstr "Typnamnet ”%s” vid %C står i konflikt med tidigare deklarerad enhet vid %L, som har samma namn"
+msgstr "Typnamnet %qs vid %C står i konflikt med tidigare deklarerad enhet vid %L, som har samma namn"
#: fortran/decl.c:3122
#, gcc-internal-format, gfc-internal-format
@@ -47476,10 +47289,9 @@ msgid "IMPORT statement at %C only permitted in an INTERFACE body"
msgstr "IMPORT-sats vid %C endast tillåten inuti en INTERFACE-kropp"
#: fortran/decl.c:3412
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "IMPORT statement at %C only permitted in an INTERFACE body"
+#, gcc-internal-format, gfc-internal-format
msgid "F2008: C1210 IMPORT statement at %C is not permitted in a module procedure interface body"
-msgstr "IMPORT-sats vid %C endast tillåten inuti en INTERFACE-kropp"
+msgstr "F2008: C1210 IMPORT-sats vid %C är inte tillåten i en moduls procedurgränssnittskropp"
#: fortran/decl.c:3417
#, gcc-internal-format, gfc-internal-format
@@ -47664,10 +47476,9 @@ msgid "Syntax error in data declaration at %C"
msgstr "Syntaxfel i datadeklaration vid %C"
#: fortran/decl.c:4615
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "IMPURE procedure at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "MODULE prefix at %C"
-msgstr "IMPURE-procedur vid %C"
+msgstr "MODULE-prefix vid %C"
#: fortran/decl.c:4660
#, gcc-internal-format, gfc-internal-format
@@ -47705,10 +47516,9 @@ msgid "Mismatch in MODULE PROCEDURE formal argument names (%s/%s) at %C"
msgstr "Formella argumentnamnen till MODULE PROCEDURE stämmer inte (%s/%s) vid %C"
#: fortran/decl.c:4876
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "double colon in MODULE PROCEDURE statement at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "Mismatch in number of MODULE PROCEDURE formal arguments at %C"
-msgstr "dubbelkolon i MODULE PROCEDURE-sats vid %L"
+msgstr "Antalet formella MODULE PROCEDURE-argument vid %C stämmer inte"
#: fortran/decl.c:4915
#, gcc-internal-format, gfc-internal-format
@@ -47813,10 +47623,9 @@ msgid "ENTRY statement at %C cannot appear within a MODULE"
msgstr "ENTRY-sats vid %C kan inte förekomma inuti en MODULE"
#: fortran/decl.c:5784
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "ENTRY statement at %C cannot appear within a MODULE"
+#, gcc-internal-format, gfc-internal-format
msgid "ENTRY statement at %C cannot appear within a SUBMODULE"
-msgstr "ENTRY-sats vid %C kan inte förekomma inuti en MODULE"
+msgstr "ENTRY-sats vid %C kan inte förekomma inuti en SUBMODULE"
#: fortran/decl.c:5787
#, gcc-internal-format, gfc-internal-format
@@ -48150,10 +47959,9 @@ msgid "Syntax error in ASYNCHRONOUS statement at %C"
msgstr "Syntaxfel i ASYNCHRONOUS-sats vid %C"
#: fortran/decl.c:7719
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "PROCEDURE list at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "MODULE PROCEDURE declaration at %C"
-msgstr "PROCEDURE-lista vid %C"
+msgstr "MODULE PROCEDURE-deklaration vid %C"
#: fortran/decl.c:7812
#, gcc-internal-format, gfc-internal-format
@@ -48881,10 +48689,9 @@ msgid "Procedure pointer target %qs at %L must be either an intrinsic, host or u
msgstr "Procedurpekarmålet %qs vid %L måste vara antingen en inbyggd, värd, värd- eller användningsassocierad, refererad eller ha attributet EXTERNAL"
#: fortran/expr.c:3635
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Data-pointer-object &L must be unlimited polymorphic, a sequence derived type or of a type with the BIND attribute assignment at %L to be compatible with an unlimited polymorphic target"
+#, gcc-internal-format, gfc-internal-format
msgid "Data-pointer-object at %L must be unlimited polymorphic, or of a type with the BIND or SEQUENCE attribute, to be compatible with an unlimited polymorphic target"
-msgstr "Datapekarobjekt &L måste vara obegränsat polymorft, en sekvens härledd typ eller av en typ med attibutet BIND-tilldelning vid %L för att vara kompatibel med ett obegränsat polymorft mål"
+msgstr "Datapekarobjekt vid %L måste vara obegränsat polymorft, eller av en typ med attributet BIND eller SEQUENCE, för att vara kompatibel med ett obegränsat polymorft mål"
#: fortran/expr.c:3640
#, gcc-internal-format, gfc-internal-format
@@ -48997,10 +48804,9 @@ msgid "Non-POINTER in pointer association context (%s) at %L"
msgstr "Icke-POINTER i pekarassociationssammanhang (%s) vid %L"
#: fortran/expr.c:4845
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Named constant %qs in variable definition context (%s) at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "Type inaccessible in variable definition context (%s) at %L"
-msgstr "Namngiven konstant %qs i variabeldefinitionssammanhang (%s) vid %L"
+msgstr "Typen är oåtkomlig i variabeldefinitionssammanhang (%s) vid %L"
#: fortran/expr.c:4858
#, gcc-internal-format, gfc-internal-format
@@ -49008,10 +48814,9 @@ msgid "LOCK_TYPE in variable definition context (%s) at %L"
msgstr "LOCK_TYPE i variabeldefinitionssammanhang (%s) vid %L"
#: fortran/expr.c:4871
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "LOCK_TYPE in variable definition context (%s) at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "LOCK_EVENT in variable definition context (%s) at %L"
-msgstr "LOCK_TYPE i variabeldefinitionssammanhang (%s) vid %L"
+msgstr "LOCK_EVENT i variabeldefinitionssammanhang (%s) vid %L"
#: fortran/expr.c:4900
#, gcc-internal-format
@@ -49049,10 +48854,9 @@ msgid "%qs at %L associated to expression can not be used in a variable definiti
msgstr "%qs vid %L som är associerad med uttryck kan inte användas i ett variabeldefinitionssammanhang (%s)"
#: fortran/expr.c:5015
-#, fuzzy, gcc-internal-format
-#| msgid "Associate-name '%s' can not appear in a variable definition context (%s) at %L because its target at %L can not, either"
+#, gcc-internal-format
msgid "Associate-name %qs can not appear in a variable definition context (%s) at %L because its target at %L can not, either"
-msgstr "Associationsnamn ”%s” kan inte förekomma i ett variabeldefinitionssammanhang (%s) vid %L eftersom dess mål vid %L inte heller kan"
+msgstr "Associationsnamn %qs kan inte förekomma i ett variabeldefinitionssammanhang (%s) vid %L eftersom dess mål vid %L inte heller kan"
#: fortran/expr.c:5057
#, gcc-internal-format, gfc-internal-format
@@ -49087,28 +48891,24 @@ msgid "illegal OP in optimize_comparison"
msgstr "otillåten OP i optimize_comparison"
#: fortran/frontend-passes.c:1887
-#, fuzzy, gcc-internal-format
-#| msgid "Variable '%s' at %L set to undefined value inside loop beginning at %L as INTENT(OUT) argument to subroutine '%s'"
+#, gcc-internal-format
msgid "Variable %qs at %L set to undefined value inside loop beginning at %L as INTENT(OUT) argument to subroutine %qs"
-msgstr "Variabeln ”%s” vid %L satt till odefinierad inuti en slinga som börjar vid %L är argument INTENT(OUT) till subrutin ”%s”"
+msgstr "Variabeln %qs vid %L satt till odefinierad inuti en slinga som börjar vid %L är argument INTENT(OUT) till subrutin %qs"
#: fortran/frontend-passes.c:1894
-#, fuzzy, gcc-internal-format
-#| msgid "Variable '%s' at %L not definable inside loop beginning at %L as INTENT(INOUT) argument to subroutine '%s'"
+#, gcc-internal-format
msgid "Variable %qs at %L not definable inside loop beginning at %L as INTENT(INOUT) argument to subroutine %qs"
-msgstr "Variabeln ”%s” vid %L ej definierbar inuti slingan som börjar vid %L är argument INTENT(INOUT) till subrutin ”%s”"
+msgstr "Variabeln %qs vid %L ej definierbar inuti slingan som börjar vid %L är argument INTENT(INOUT) till subrutin %qs"
#: fortran/frontend-passes.c:1959
-#, fuzzy, gcc-internal-format
-#| msgid "Variable '%s' at %L set to undefined value inside loop beginning at %L as INTENT(OUT) argument to function '%s'"
+#, gcc-internal-format
msgid "Variable %qs at %L set to undefined value inside loop beginning at %L as INTENT(OUT) argument to function %qs"
-msgstr "Variabeln ”%s” vid %L satt till odefinierad inuti slingan som börjar vid %L är argument INTENT(OUT) till funktionen ”%s”"
+msgstr "Variabeln %qs vid %L satt till odefinierad inuti slingan som börjar vid %L är argument INTENT(OUT) till funktionen %qs"
#: fortran/frontend-passes.c:1965
-#, fuzzy, gcc-internal-format
-#| msgid "Variable '%s' at %L not definable inside loop beginning at %L as INTENT(INOUT) argument to function '%s'"
+#, gcc-internal-format
msgid "Variable %qs at %L not definable inside loop beginning at %L as INTENT(INOUT) argument to function %qs"
-msgstr "Variabeln ”%s” vid %L ej definierbar inuti slingan som börjar vid %L är argument INTENT(INOUT) till funktionen ”%s”"
+msgstr "Variabeln %qs vid %L ej definierbar inuti slingan som börjar vid %L är argument INTENT(INOUT) till funktionen %qs"
#: fortran/frontend-passes.c:2213 fortran/trans-expr.c:1522
#, gcc-internal-format, gfc-internal-format
@@ -49371,10 +49171,9 @@ msgid "Corank mismatch in argument %qs at %L (%d and %d)"
msgstr "Co-ordning stämmer inte i argument %qs vid %L (%d och %d)"
#: fortran/interface.c:2142
-#, fuzzy, gcc-internal-format
-#| msgid "Actual argument to %qs at %L must be simply contiguous"
+#, gcc-internal-format
msgid "Actual argument to %qs at %L must be simply contiguous or an element of such an array"
-msgstr "Aktuellt argument till %qs vid %L måste vara enkelt sammanhängande"
+msgstr "Aktuellt argument till %qs vid %L måste vara enkelt sammanhängande eller ett element i en sådan vektor"
#: fortran/interface.c:2157
#, gcc-internal-format
@@ -49382,10 +49181,9 @@ msgid "Actual argument to non-INTENT(INOUT) dummy %qs at %L, which is LOCK_TYPE
msgstr "Aktuellt argument till icke-INTENT(INOUT)-attrappen %qs vid %L, som är LOCK_TYPE eller har en LOCK_TYPE-komponent"
#: fortran/interface.c:2172
-#, fuzzy, gcc-internal-format
-#| msgid "Actual argument to non-INTENT(INOUT) dummy %qs at %L, which is LOCK_TYPE or has a LOCK_TYPE component"
+#, gcc-internal-format
msgid "Actual argument to non-INTENT(INOUT) dummy %qs at %L, which is EVENT_TYPE or has a EVENT_TYPE component"
-msgstr "Aktuellt argument till icke-INTENT(INOUT)-attrappen %qs vid %L, som är LOCK_TYPE eller har en LOCK_TYPE-komponent"
+msgstr "Aktuellt argument till icke-INTENT(INOUT)-attrappen %qs vid %L, som är EVENT_TYPE eller har en EVENT_TYPE-komponent"
#: fortran/interface.c:2191
#, gcc-internal-format
@@ -49653,10 +49451,9 @@ msgid "Actual argument of LOCK_TYPE or with LOCK_TYPE component at %L requires a
msgstr "Aktuellt argument till LOCK_TYPE eller med LOCK_TYPE-komponent vid %L kräver ett explicit gränssnitt för proceduren %qs"
#: fortran/interface.c:3413
-#, fuzzy, gcc-internal-format
-#| msgid "Actual argument of LOCK_TYPE or with LOCK_TYPE component at %L requires an explicit interface for procedure %qs"
+#, gcc-internal-format
msgid "Actual argument of EVENT_TYPE or with EVENT_TYPE component at %L requires an explicit interface for procedure %qs"
-msgstr "Aktuellt argument till LOCK_TYPE eller med LOCK_TYPE-komponent vid %L kräver ett explicit gränssnitt för proceduren %qs"
+msgstr "Aktuellt argument till EVENT_TYPE eller med EVENT_TYPE-komponent vid %L kräver ett explicit gränssnitt för proceduren %qs"
#: fortran/interface.c:3422
#, gcc-internal-format, gfc-internal-format
@@ -50024,10 +49821,9 @@ msgid "Format statement in module main block at %C"
msgstr "Formatsats i modulhuvudblock vid %C"
#: fortran/io.c:1207
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "ENTRY statement at %C cannot appear within an INTERFACE"
+#, gcc-internal-format, gfc-internal-format
msgid "FORMAT statement at %C cannot appear within an INTERFACE"
-msgstr "ENTRY-sats vid %C kan inte förekomma inuti ett INTERFACE"
+msgstr "FORMAT-sats vid %C kan inte förekomma inuti ett INTERFACE"
#: fortran/io.c:1213
#, gcc-internal-format, gfc-internal-format
@@ -50245,10 +50041,9 @@ msgid "%s statement not allowed in PURE procedure at %C"
msgstr "%s-sats är inte tillåtet i PURE-procedur vid %C"
#: fortran/io.c:2534
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "UNIT number in INQUIRE statement at %L can not be -1"
+#, gcc-internal-format, gfc-internal-format
msgid "UNIT number missing in statement at %L"
-msgstr "UNIT-tal i INQUIRE-sats vid %L får inte vara -1"
+msgstr "UNIT-tal saknas i satsen vid %L"
#: fortran/io.c:2542 fortran/io.c:2979
#, gcc-internal-format, gfc-internal-format
@@ -50502,10 +50297,9 @@ msgid "Invalid character %<$%> at %L. Use %<-fdollar-ok%> to allow it as an exte
msgstr "Ogiltigt tecken %<$%> vid %L. Använd %<-fdollar-ok%> för att tillåta det som en utökning"
#: fortran/match.c:882
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Loop variable at %C cannot be a coarray"
+#, gcc-internal-format, gfc-internal-format
msgid "Loop variable at %C cannot be an array"
-msgstr "Slingvariabel vid %C får inte vara en co-vektor"
+msgstr "Slingvariabel vid %C får inte vara en vektor"
#: fortran/match.c:889
#, gcc-internal-format, gfc-internal-format
@@ -50774,22 +50568,19 @@ msgid "ERROR STOP statement at %C"
msgstr "ERROR STOP-sats vid %C"
#: fortran/match.c:2778
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Image control statement %s at %C in PURE procedure"
+#, gcc-internal-format, gfc-internal-format
msgid "Image control statement EVENT %s at %C in PURE procedure"
-msgstr "Bildstyrsats %s vid %C i PURE-procedur"
+msgstr "Bildstyrsats EVENT %s vid %C i PURE-procedur"
#: fortran/match.c:2793
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Image control statement %s at %C in CRITICAL block"
+#, gcc-internal-format, gfc-internal-format
msgid "Image control statement EVENT %s at %C in CRITICAL block"
-msgstr "Bildkontrollsatsen %s vid %C i CRITICAL-block"
+msgstr "Bildkontrollsatsen EVENT %s vid %C i CRITICAL-block"
#: fortran/match.c:2800
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Image control statement %s at %C in DO CONCURRENT block"
+#, gcc-internal-format, gfc-internal-format
msgid "Image control statement EVENT %s at %C in DO CONCURRENT block"
-msgstr "Bildkontrollsatsen %s vid %C i DO CONCURRENT-block"
+msgstr "Bildkontrollsatsen EVENT %s vid %C i DO CONCURRENT-block"
#: fortran/match.c:2830 fortran/match.c:3025 fortran/match.c:3237
#: fortran/match.c:3747 fortran/match.c:4084
@@ -50804,22 +50595,19 @@ msgid "Redundant ERRMSG tag found at %L "
msgstr "Överflödig ERRMSG-tagg funnen vid %L "
#: fortran/match.c:2872
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Redundant STAT tag found at %L "
+#, gcc-internal-format, gfc-internal-format
msgid "Redundant UNTIL_COUNT tag found at %L "
-msgstr "Överflödig STAT-tagg funnen vid %L "
+msgstr "Överflödig UNTIL_COUNT-tagg funnen vid %L "
#: fortran/match.c:2938
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "ENTRY statement at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "EVENT POST statement at %C"
-msgstr "ENTRY-sats vid %C"
+msgstr "ENTRY POST-sats vid %C"
#: fortran/match.c:2948
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "ENTRY statement at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "EVENT WAIT statement at %C"
-msgstr "ENTRY-sats vid %C"
+msgstr "ENTRY WAIT-sats vid %C"
#: fortran/match.c:2973
#, gcc-internal-format, gfc-internal-format
@@ -51065,10 +50853,9 @@ msgstr "Syntaxfel i common-blocknamn vid %C"
#. cause it's just semantic, and we can see if there
#. are more errors.
#: fortran/match.c:4543
-#, fuzzy, gcc-internal-format
-#| msgid "Variable '%s' at %L in common block '%s' at %C must be declared with a C interoperable kind since common block '%s' is bind(c)"
+#, gcc-internal-format
msgid "Variable %qs at %L in common block %qs at %C must be declared with a C interoperable kind since common block %qs is bind(c)"
-msgstr "Variabel ”%s” vid %L i common-block ”%s” vid %C måste deklareras med en C-interoperativ sort eftersom common-block ”%s” är bind(c)"
+msgstr "Variabel %qs vid %L i common-block %qs vid %C måste deklareras med en C-interoperativ sort eftersom common-block %qs är bind(c)"
#: fortran/match.c:4552
#, gcc-internal-format
@@ -51146,10 +50933,9 @@ msgid "Statement function at %L is recursive"
msgstr "Satsfunktion vid %L är rekursiv"
#: fortran/match.c:5124
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "ENTRY statement at %C cannot appear within an INTERFACE"
+#, gcc-internal-format, gfc-internal-format
msgid "Statement function at %L cannot appear within an INTERFACE"
-msgstr "ENTRY-sats vid %C kan inte förekomma inuti ett INTERFACE"
+msgstr "Satsfunktion vid %L kan inte förekomma inuti ett INTERFACE"
#: fortran/match.c:5129
#, gcc-internal-format, gfc-internal-format
@@ -51157,10 +50943,9 @@ msgid "Statement function at %C"
msgstr "Satsfunktion vid %C"
#: fortran/match.c:5254 fortran/match.c:5270
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Expression in CASE statement at %L must be scalar"
+#, gcc-internal-format, gfc-internal-format
msgid "Expression in CASE selector at %L cannot be %s"
-msgstr "Uttryck i CASE-sats vid %L måste vara skalärt"
+msgstr "Uttryck i CASE-sats vid %L får inte vara %s"
#: fortran/match.c:5292
#, gcc-internal-format, gfc-internal-format
@@ -51223,10 +51008,9 @@ msgid "Label %qs at %C doesn't match WHERE label %qs"
msgstr "Etiketten %qs vid %C stämmer inte med WHERE-etikett %qs"
#: fortran/matchexp.c:72
-#, fuzzy, gcc-internal-format
-#| msgid "Bad character %<%c%> in OPERATOR name at %C"
+#, gcc-internal-format
msgid "Bad character %qc in OPERATOR name at %C"
-msgstr "Felaktigt tecken %<%c%> i OPERATOR-namn vid %C"
+msgstr "Felaktigt tecken %qc i OPERATOR-namn vid %C"
#: fortran/matchexp.c:80
#, gcc-internal-format
@@ -51315,16 +51099,14 @@ msgid "The name %qs at %C has already been used as an external module name."
msgstr "Namnet %qs vid %C har redan använts som ett externt modulnamn."
#: fortran/module.c:744
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Coarray declaration at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "SUBMODULE declaration at %C"
-msgstr "Co-vektordeklaration vid %C"
+msgstr "SUBMODULE-deklaration vid %C"
#: fortran/module.c:814
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Syntax error in SAVE statement at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "Syntax error in SUBMODULE statement at %C"
-msgstr "Syntaxfel i SAVE-sats vid %C"
+msgstr "Syntaxfel i SUBMODULE-sats vid %C"
#: fortran/module.c:1159
#, gcc-internal-format
@@ -51538,10 +51320,9 @@ msgid "Cannot read module file %qs opened at %C, because it was created by a dif
msgstr "Kan inte läsa modulfilen %qs öppnad vid %C, eftersom den skapades av en annan version av GNU Fortran"
#: fortran/module.c:6967
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Can't USE the same module we're building!"
+#, gcc-internal-format, gfc-internal-format
msgid "Can't USE the same %smodule we're building!"
-msgstr "Det går inta att USE samma modul vi bygger!"
+msgstr "Det går inta att USE samma %smodul vi bygger!"
#: fortran/openmp.c:289 fortran/openmp.c:497 fortran/openmp.c:2399
#: fortran/openmp.c:2473
@@ -51560,22 +51341,19 @@ msgid "Syntax error in OpenACC expression list at %C"
msgstr "Syntaxfel i OpenACC-uttryckslista vid %C"
#: fortran/openmp.c:465
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Threadprivate variable at %C is an element of a COMMON block"
+#, gcc-internal-format, gfc-internal-format
msgid "Variable at %C is an element of a COMMON block"
-msgstr "Trådprivat variabel vid %C är ett element i ett COMMON-block"
+msgstr "Variabel vid %C är ett element i ett COMMON-block"
#: fortran/openmp.c:525
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Unexpected junk after !$ACC ROUTINE at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "Unexpected junk after !$ACC DECLARE at %C"
-msgstr "Oväntat skräp efter !$ACC ROUTINE vid %C"
+msgstr "Oväntat skräp efter !$ACC DECLARE vid %C"
#: fortran/openmp.c:535
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Syntax error in !$OMP DECLARE TARGET list at %C"
+#, gcc-internal-format, gfc-internal-format
msgid "Syntax error in !$ACC DECLARE list at %C"
-msgstr "Syntaxfel i !$OMP DECLARE TARGET-lista vid %C"
+msgstr "Syntaxfel i !$OMP DECLARE-lista vid %C"
#: fortran/openmp.c:991
#, gcc-internal-format, gfc-internal-format
@@ -51588,10 +51366,9 @@ msgid "COLLAPSE clause argument not constant positive integer at %C"
msgstr "COLLAPSE-klausulargument är inte ett konstant positivt heltal vid %C"
#: fortran/openmp.c:1476
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Invalid argument to $!ACC WAIT at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "Invalid clause in module with $!ACC DECLARE at %L"
-msgstr "Ogiltiga argument till $!ACC WAIT vid %L"
+msgstr "Ogiltig klausul i modul med $!ACC DECLARE vid %L"
#: fortran/openmp.c:1486
#, gcc-internal-format, gfc-internal-format
@@ -51599,16 +51376,14 @@ msgid "Variable is USE-associated with $!ACC DECLARE at %L"
msgstr "Variabel i USE-associated med $!ACC DECLARE vid %L"
#: fortran/openmp.c:1494
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Assumed size array %qs in %s clause at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "Assumed-size dummy array with $!ACC DECLARE at %L"
-msgstr "Vektor %qs med antagen storlek i %s-klausul vid %L"
+msgstr "Attrappvektor med antagen storlek med $!ACC DECLARE at %L"
#: fortran/openmp.c:1541
-#, fuzzy, gcc-internal-format
-#| msgid "%<#pragma acc update%> must contain at least one %<device%> or %<host/self%> clause"
+#, gcc-internal-format
msgid "%<acc update%> must contain at least one %<device%> or %<host%> or %<self%> clause at %L"
-msgstr "%<#pragma acc update%> måste innehålla åtminstone en %<device%>- eller %<host/self%>-klausul"
+msgstr "%<acc update%> måste innehålla åtminstone en %<device%>- eller %<host%>- eller %<self%>-klausul vid %L"
#: fortran/openmp.c:1591
#, gcc-internal-format, gfc-internal-format
@@ -51631,10 +51406,9 @@ msgid "ACC CACHE directive must be inside of loop %C"
msgstr "Direktivet ACC CACHE måste vara inuti en slinga %C"
#: fortran/openmp.c:1669
-#, fuzzy, gcc-internal-format
-#| msgid "storage class specified for typename"
+#, gcc-internal-format
msgid "Multiple loop axes specified for routine"
-msgstr "lagringsklass angiven för typnamn"
+msgstr "Multipla slingaxlar angivna för rutinen"
#: fortran/openmp.c:1695
#, gcc-internal-format, gfc-internal-format
@@ -51642,10 +51416,9 @@ msgid "Only the !$ACC ROUTINE form without list is allowed in interface block at
msgstr "Endast formen !$ACC ROUTINE utan en lista är tillåten i gränssnittsblock vid %C"
#: fortran/openmp.c:1722
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Syntax error in !$ACC ROUTINE ( NAME ) at %C, invalid function name %qs"
+#, gcc-internal-format, gfc-internal-format
msgid "Syntax error in !$ACC ROUTINE ( NAME ) at %C, invalid function name %s"
-msgstr "Syntaxfel i !$ACC ROUTINE ( NAMN ) vid %C, felaktigt funktionsnamn %qs"
+msgstr "Syntaxfel i !$ACC ROUTINE ( NAMN ) vid %C, felaktigt funktionsnamn %s"
#: fortran/openmp.c:1731
#, gcc-internal-format, gfc-internal-format
@@ -51915,10 +51688,9 @@ msgid "Symbol %qs present on multiple clauses at %L"
msgstr "Symbolen %qs finns i flera fall vid %L"
#: fortran/openmp.c:3322
-#, fuzzy, gcc-internal-format
-#| msgid "Variable %qs cannot appear in the expression at %L"
+#, gcc-internal-format
msgid "Array %qs is not permitted in reduction at %L"
-msgstr "Variabeln %qs kan inte förekomma i uttrycket vid %L"
+msgstr "Vektorn %qs får inte förekomma i reduktionen vid %L"
#: fortran/openmp.c:3335
#, gcc-internal-format
@@ -52247,10 +52019,9 @@ msgid "not enough DO loops for %s !$ACC LOOP at %L"
msgstr "inte tillräckligt med DO-slingor för %s !$ACC LOOP vid %L"
#: fortran/openmp.c:4747 fortran/openmp.c:4754
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "!$ACC LOOP %s in PARALLEL region doesn't allow non-static arguments at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "!$ACC LOOP %s in PARALLEL region doesn't allow %s arguments at %L"
-msgstr "!$ACC LOOP %s i PARALLEL-region tillåter inte icke-statiska argument vid %L"
+msgstr "!$ACC LOOP %s i PARALLEL-region tillåter inte %s-argument vid %L"
#: fortran/openmp.c:4776
#, gcc-internal-format, gfc-internal-format
@@ -52698,40 +52469,34 @@ msgid "Noncoarray component %s at %L of type LOCK_TYPE or with subcomponent of t
msgstr "Icke co-vektorkomponenten %s vid %L av typen LOCK_TYPE eller med en underkomponent av typen LOCK_TYPE måste ha en co-dimension eller vara en underkomponent till en co-vektor. (Variabler av typen %s får inte ha en co-dimension eftersom %s vid %L har en co-dimension eller en co-vektorunderkomponent)"
#: fortran/parse.c:2889
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Component %s at %L of type LOCK_TYPE must have a codimension or be a subcomponent of a coarray, which is not possible as the component has the pointer attribute"
+#, gcc-internal-format, gfc-internal-format
msgid "Component %s at %L of type EVENT_TYPE must have a codimension or be a subcomponent of a coarray, which is not possible as the component has the pointer attribute"
-msgstr "Komponenten %s vid %L av typen LOCK_TYPE måste ha en co-dimension eller vara en delkomponent till en co-vektor, vilket inte är möjligt eftersom komponenten har pekarattributet"
+msgstr "Komponenten %s vid %L av typen EVENT_TYPE måste ha en co-dimension eller vara en delkomponent till en co-vektor, vilket inte är möjligt eftersom komponenten har pekarattributet"
#: fortran/parse.c:2895
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Pointer component %s at %L has a noncoarray subcomponent of type LOCK_TYPE, which must have a codimension or be a subcomponent of a coarray"
+#, gcc-internal-format, gfc-internal-format
msgid "Pointer component %s at %L has a noncoarray subcomponent of type EVENT_TYPE, which must have a codimension or be a subcomponent of a coarray"
-msgstr "Pekarkomponenten %s vid %L har en icke co-vektordelkomponent av typen LOCK_TYPE, som måste ha en co-dimension eller vara en delkomponent av en co-vektor"
+msgstr "Pekarkomponenten %s vid %L har en icke co-vektordelkomponent av typen EVENT_TYPE, som måste ha en co-dimension eller vara en delkomponent av en co-vektor"
#: fortran/parse.c:2900
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Allocatable component %s at %L of type LOCK_TYPE must have a codimension"
+#, gcc-internal-format, gfc-internal-format
msgid "Allocatable component %s at %L of type EVENT_TYPE must have a codimension"
-msgstr "Allokerbar komponent %s vid %L av typen LOCK_TYPE måste ha en co-dimension"
+msgstr "Allokerbar komponent %s vid %L av typen EVENT_TYPE måste ha en co-dimension"
#: fortran/parse.c:2904
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Allocatable component %s at %L must have a codimension as it has a noncoarray subcomponent of type LOCK_TYPE"
+#, gcc-internal-format, gfc-internal-format
msgid "Allocatable component %s at %L must have a codimension as it has a noncoarray subcomponent of type EVENT_TYPE"
-msgstr "Den allokerbara komponenten %s vid %L måste ha en co-dimension eftersom den har en icke co-vektordelkomponent av typen LOCK_TYPE"
+msgstr "Den allokerbara komponenten %s vid %L måste ha en co-dimension eftersom den har en icke co-vektordelkomponent av typen EVENT_TYPE"
#: fortran/parse.c:2909
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Noncoarray component %s at %L of type LOCK_TYPE or with subcomponent of type LOCK_TYPE must have a codimension or be a subcomponent of a coarray. (Variables of type %s may not have a codimension as already a coarray subcomponent exists)"
+#, gcc-internal-format, gfc-internal-format
msgid "Noncoarray component %s at %L of type EVENT_TYPE or with subcomponent of type EVENT_TYPE must have a codimension or be a subcomponent of a coarray. (Variables of type %s may not have a codimension as already a coarray subcomponent exists)"
-msgstr "Icke co-vektorkomponenten %s vid %L av typen LOCK_TYPE eller med en underkomponent av typen LOCK_TYPE måste ha en co-dimension eller vara en underkomponent av en co-vektor. (Variabler av typen %s får inte ha en co-dimension eftersom det redan finns en co-vektorunderkomponent)"
+msgstr "Icke co-vektorkomponenten %s vid %L av typen EVENT_TYPE eller med en underkomponent av typen LOCK_TYPE måste ha en co-dimension eller vara en underkomponent av en co-vektor. (Variabler av typen %s får inte ha en co-dimension eftersom det redan finns en co-vektorunderkomponent)"
#: fortran/parse.c:2916
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Noncoarray component %s at %L of type LOCK_TYPE or with subcomponent of type LOCK_TYPE must have a codimension or be a subcomponent of a coarray. (Variables of type %s may not have a codimension as %s at %L has a codimension or a coarray subcomponent)"
+#, gcc-internal-format, gfc-internal-format
msgid "Noncoarray component %s at %L of type EVENT_TYPE or with subcomponent of type EVENT_TYPE must have a codimension or be a subcomponent of a coarray. (Variables of type %s may not have a codimension as %s at %L has a codimension or a coarray subcomponent)"
-msgstr "Icke co-vektorkomponenten %s vid %L av typen LOCK_TYPE eller med en underkomponent av typen LOCK_TYPE måste ha en co-dimension eller vara en underkomponent till en co-vektor. (Variabler av typen %s får inte ha en co-dimension eftersom %s vid %L har en co-dimension eller en co-vektorunderkomponent)"
+msgstr "Icke co-vektorkomponenten %s vid %L av typen EVENT_TYPE eller med en underkomponent av typen EVENT_TYPE måste ha en co-dimension eller vara en underkomponent till en co-vektor. (Variabler av typen %s får inte ha en co-dimension eftersom %s vid %L har en co-dimension eller en co-vektorunderkomponent)"
#: fortran/parse.c:2968
#, gcc-internal-format, gfc-internal-format
@@ -52824,10 +52589,9 @@ msgid "Expected TYPE IS, CLASS IS or END SELECT statement following SELECT TYPE
msgstr "En TYPE IS-, CLASS IS- eller END SELECT-sats förväntades följa efter SELECT TYPE vid %C"
#: fortran/parse.c:3855
-#, fuzzy, gcc-internal-format
-#| msgid "Variable '%s' at %C cannot be redefined inside loop beginning at %L"
+#, gcc-internal-format
msgid "Variable %qs at %C cannot be redefined inside loop beginning at %L"
-msgstr "Variabeln ”%s” vid %C får inte definieras om inuti slingan som börjar vid %L"
+msgstr "Variabeln %qs vid %C får inte definieras om inuti slingan som börjar vid %L"
#: fortran/parse.c:3888
#, gcc-internal-format, gfc-internal-format
@@ -52935,16 +52699,14 @@ msgid "gfc_global_used(): Bad type"
msgstr "gfc_global_used(): Felaktig typ"
#: fortran/parse.c:5306
-#, fuzzy, gcc-internal-format
-#| msgid "Global binding name '%s' at %L is already being used as a %s at %L"
+#, gcc-internal-format
msgid "Global binding name %qs at %L is already being used as a %s at %L"
-msgstr "Globalt bindningsnamn ”%s” vid %L används redan som en %s vid %L"
+msgstr "Globalt bindningsnamn %qs vid %L används redan som en %s vid %L"
#: fortran/parse.c:5309
-#, fuzzy, gcc-internal-format
-#| msgid "Global name '%s' at %L is already being used as a %s at %L"
+#, gcc-internal-format
msgid "Global name %qs at %L is already being used as a %s at %L"
-msgstr "Globalt namn ”%s” vid %L används redan som en %s vid %L"
+msgstr "Globalt namn %qs vid %L används redan som en %s vid %L"
#: fortran/parse.c:5330
#, gcc-internal-format, gfc-internal-format
@@ -53160,10 +52922,9 @@ msgid "Syntax error in COMPLEX constant at %C"
msgstr "Syntaxfel i COMPLEX-konstant vid %C"
#: fortran/primary.c:1557
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Namelist %s cannot be renamed by USE association to %s"
+#, gcc-internal-format, gfc-internal-format
msgid "Namelist '%s' can not be an argument at %L"
-msgstr "Namnlistan %s får inte namnändras av USE-association till %s"
+msgstr "Namnlistan ”%s” kan inte vara ett argument vid %L"
#: fortran/primary.c:1643
#, gcc-internal-format
@@ -53421,10 +53182,9 @@ msgid "Argument %qs of pure subroutine %qs at %L must have its INTENT specified
msgstr "Argumentet %qs till pure-subrutin %qs vid %L måste ha sitt INTENT angivet eller ha attributet VALUE"
#: fortran/resolve.c:419
-#, fuzzy, gcc-internal-format
-#| msgid "INTENT(OUT) argument '%s' of pure procedure %qs at %L may not be polymorphic"
+#, gcc-internal-format
msgid "INTENT(OUT) argument %qs of pure procedure %qs at %L may not be polymorphic"
-msgstr "INTENT(OUT)-argumentet ”%s” till den rena proceduren %qs vid %L får inte vara polymorf"
+msgstr "INTENT(OUT)-argumentet %qs till den rena proceduren %qs vid %L får inte vara polymorf"
#: fortran/resolve.c:452
#, gcc-internal-format
@@ -53552,22 +53312,19 @@ msgid "Derived type variable %qs in COMMON at %L may not have default initialize
msgstr "Härledd typvariabel %qs i COMMON vid %L får inte ha standardinitierare"
#: fortran/resolve.c:1000
-#, fuzzy, gcc-internal-format
-#| msgid "In Fortran 2003 COMMON '%s' block at %L is a global identifier and must thus have the same binding name as the same-named COMMON block at %L: %s vs %s"
+#, gcc-internal-format
msgid "In Fortran 2003 COMMON %qs block at %L is a global identifier and must thus have the same binding name as the same-named COMMON block at %L: %s vs %s"
-msgstr "I Fortran 2003 är COMMON ”%s”-block vid %L en global identifierare och måste således ha samma bindningsnamn som COMMON-blocket med samma namn vid %L: %s resp %s"
+msgstr "I Fortran 2003 är COMMON %qs-block vid %L en global identifierare och måste således ha samma bindningsnamn som COMMON-blocket med samma namn vid %L: %s resp %s"
#: fortran/resolve.c:1014
-#, fuzzy, gcc-internal-format
-#| msgid "COMMON block '%s' at %L uses the same global identifier as entity at %L"
+#, gcc-internal-format
msgid "COMMON block %qs at %L uses the same global identifier as entity at %L"
-msgstr "COMMON-block ”%s” vid %L använder samma globala identifierare som en enhet vid %L"
+msgstr "COMMON-block %qs vid %L använder samma globala identifierare som en enhet vid %L"
#: fortran/resolve.c:1022
-#, fuzzy, gcc-internal-format
-#| msgid "Fortran 2008: COMMON block '%s' with binding label at %L sharing the identifier with global non-COMMON-block entity at %L"
+#, gcc-internal-format
msgid "Fortran 2008: COMMON block %qs with binding label at %L sharing the identifier with global non-COMMON-block entity at %L"
-msgstr "Fortran 2008: COMMON-block ”%s” med bindningsetikett vid %L delar identifierare med ett globalt ej-COMMON-blockenhet vid %L"
+msgstr "Fortran 2008: COMMON-block %qs med bindningsetikett vid %L delar identifierare med ett globalt ej-COMMON-blockenhet vid %L"
#: fortran/resolve.c:1044
#, gcc-internal-format, gfc-internal-format
@@ -53575,10 +53332,9 @@ msgid "COMMON block at %L with binding label %s uses the same global identifier
msgstr "COMMON-block vid %L med bindningsetikett %s använder samma globala identifierare som enheten vid %L"
#: fortran/resolve.c:1065
-#, fuzzy, gcc-internal-format
-#| msgid "COMMON block '%s' at %L is used as PARAMETER at %L"
+#, gcc-internal-format
msgid "COMMON block %qs at %L is used as PARAMETER at %L"
-msgstr "COMMON-block ”%s” vid %L används som PARAMETER vid %L"
+msgstr "COMMON-block %qs vid %L används som PARAMETER vid %L"
#: fortran/resolve.c:1069
#, gcc-internal-format
@@ -53872,10 +53628,9 @@ msgid "Unable to resolve the specific subroutine %qs at %L"
msgstr "Kan inte slå upp den specifika subrutinen %qs vid %L"
#: fortran/resolve.c:3375
-#, fuzzy, gcc-internal-format
-#| msgid "'%s' at %L has a type, which is not consistent with the CALL at %L"
+#, gcc-internal-format
msgid "%qs at %L has a type, which is not consistent with the CALL at %L"
-msgstr "”%s” vid %L har en typ som inte är konsistent med CALL vid %L"
+msgstr "%qs vid %L har en typ som inte är konsistent med CALL vid %L"
#: fortran/resolve.c:3414
#, gcc-internal-format
@@ -54282,10 +54037,9 @@ msgid "The source-expr at %L shall neither be of type LOCK_TYPE nor have a LOCK_
msgstr "Källuttrycket vid %L skall varken vara av typen LOCK_TYPE eller ha en LOCK_TYPE-komponent om det allokerbara objektet vid %L är en co-vektor"
#: fortran/resolve.c:7073
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "The source-expr at %L shall neither be of type LOCK_TYPE nor have a LOCK_TYPE component if allocate-object at %L is a coarray"
+#, gcc-internal-format, gfc-internal-format
msgid "The source-expr at %L shall neither be of type EVENT_TYPE nor have a EVENT_TYPE component if allocate-object at %L is a coarray"
-msgstr "Källuttrycket vid %L skall varken vara av typen LOCK_TYPE eller ha en LOCK_TYPE-komponent om det allokerbara objektet vid %L är en co-vektor"
+msgstr "Källuttrycket vid %L skall varken vara av typen EVENT_TYPE eller ha en EVENT_TYPE-komponent om det allokerbara objektet vid %L är en co-vektor"
#: fortran/resolve.c:7086
#, gcc-internal-format, gfc-internal-format
@@ -54303,10 +54057,9 @@ msgid "Array specification required in ALLOCATE statement at %L"
msgstr "Vektorspecifikation krävs i ALLOCATE-sats vid %L"
#: fortran/resolve.c:7224
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Array specification required in ALLOCATE statement at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "Array specification or array-valued SOURCE= expression required in ALLOCATE statement at %L"
-msgstr "Vektorspecifikation krävs i ALLOCATE-sats vid %L"
+msgstr "Vektorspecifikation eller vektorvärt SOURCE=-uttryck krävs i ALLOCATE-sats vid %L"
#: fortran/resolve.c:7247
#, gcc-internal-format, gfc-internal-format
@@ -54524,22 +54277,19 @@ msgid "Lock variable at %L must be a scalar of type LOCK_TYPE"
msgstr "Låsvariabel vid %L måste vara en skalär av typen LOCK_TYPE"
#: fortran/resolve.c:8773
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Lock variable at %L must be a scalar of type LOCK_TYPE"
+#, gcc-internal-format, gfc-internal-format
msgid "Event variable at %L must be a scalar of type EVENT_TYPE"
-msgstr "Låsvariabel vid %L måste vara en skalär av typen LOCK_TYPE"
+msgstr "Händelsevariabeln vid %L måste vara en skalär av typen EVENT_TYPE"
#: fortran/resolve.c:8777
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Actual argument to %qs at %L must be a coarray"
+#, gcc-internal-format, gfc-internal-format
msgid "Event variable argument at %L must be a coarray or coindexed"
-msgstr "Aktuellt argument till %qs vid %L måste vara en co-vektor"
+msgstr "Händelsevariabelargumentet vid %L måste vara en co-vektor eller co-indexerat"
#: fortran/resolve.c:8780
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Actual argument to %qs at %L must be a coarray"
+#, gcc-internal-format, gfc-internal-format
msgid "Event variable argument at %L must be a coarray but not coindexed"
-msgstr "Aktuellt argument till %qs vid %L måste vara en co-vektor"
+msgstr "Händelsevariabelargumentet vid %L måste vara en co-vektor men inte co-indexerat"
#: fortran/resolve.c:8787 fortran/resolve.c:8905
#, gcc-internal-format, gfc-internal-format
@@ -54557,10 +54307,9 @@ msgid "ACQUIRED_LOCK= argument at %L must be a scalar LOGICAL variable"
msgstr "ACQUIRED_LOCK=-argumentet vid %L måste vara en skalär LOGICAL-variabel"
#: fortran/resolve.c:8822
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Imageset argument at %L must be a scalar or rank-1 INTEGER expression"
+#, gcc-internal-format, gfc-internal-format
msgid "UNTIL_COUNT= argument at %L must be a scalar INTEGER expression"
-msgstr "Bildmängdsargument vid %L måste vara ett skalärt eller ordning-1-uttryck"
+msgstr "UNTIL_COUNT=-argumentet vid %L måste vara ett skalärt INTEGER-uttryck"
#: fortran/resolve.c:8882
#, gcc-internal-format, gfc-internal-format
@@ -54706,16 +54455,14 @@ msgstr "ATT GÖRA: typbegränsad definierad tilldelning vid %L inte gjord för a
#. Even if standard does not support this feature, continue to build
#. the two statements to avoid upsetting frontend_passes.c.
#: fortran/resolve.c:10250
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Invalid procedure pointer assignment at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "Pointer procedure assignment at %L"
-msgstr "Ogiltig procedurpekartilldelning vid %L"
+msgstr "Procedurpekartilldelning vid %L"
#: fortran/resolve.c:10262
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Target expression in pointer assignment at %L must deliver a pointer result"
+#, gcc-internal-format, gfc-internal-format
msgid "The function result on the lhs of the assignment at %L must have the pointer attribute."
-msgstr "Måluttryck i pekartilldelning vid %L måste leverera ett pekarresultat"
+msgstr "Funktionsresultatet på vänstersidan av tilldelningen vid %L måste ha attributet pointer."
#: fortran/resolve.c:10489
#, gcc-internal-format, gfc-internal-format
@@ -54738,16 +54485,14 @@ msgid "ASSIGN statement at %L requires a scalar default INTEGER variable"
msgstr "ASSIGN-sats vid %L kräver en skalär standard-INTEGER-variabel"
#: fortran/resolve.c:10600
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Invalid kind for %s at %L"
+#, gcc-internal-format, gfc-internal-format
msgid "Invalid NULL at %L"
-msgstr "Ogiltig sort på %s vid %L"
+msgstr "Ogiltig NULL vid %L"
#: fortran/resolve.c:10604
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Arithmetic IF statement at %L requires a numeric expression"
+#, gcc-internal-format, gfc-internal-format
msgid "Arithmetic IF statement at %L requires a scalar REAL or INTEGER expression"
-msgstr "Aritmetisk IF-sats vid %L kräver ett numeriskt uttryck"
+msgstr "Aritmetisk IF-sats vid %L kräver ett skalärt REAL- eller INTEGER-uttryck"
#: fortran/resolve.c:10660
#, gcc-internal-format
@@ -54825,10 +54570,9 @@ msgid "CLASS variable %qs at %L must be dummy, allocatable or pointer"
msgstr "CLASS-variabel %qs vid %L måste vara en attrapp, allokerbar eller pekare"
#: fortran/resolve.c:11438
-#, fuzzy, gcc-internal-format
-#| msgid "The type '%s' cannot be host associated at %L because it is blocked by an incompatible object of the same name declared at %L"
+#, gcc-internal-format
msgid "The type %qs cannot be host associated at %L because it is blocked by an incompatible object of the same name declared at %L"
-msgstr "Typen ”%s” kan inte vara värdassocierad vid %L för att den blockeras av ett inkompatibelt objekt med samma namn deklarerat vid %L"
+msgstr "Typen %qs kan inte vara värdassocierad vid %L för att den blockeras av ett inkompatibelt objekt med samma namn deklarerat vid %L"
#: fortran/resolve.c:11460
#, gcc-internal-format
@@ -54838,10 +54582,9 @@ msgstr "Implicerad SAVE för modulvariabeln %qs vid %L, behövs på grund av sta
#. The shape of a main program or module array needs to be
#. constant.
#: fortran/resolve.c:11508
-#, fuzzy, gcc-internal-format
-#| msgid "The module or main program array '%s' at %L must have constant shape"
+#, gcc-internal-format
msgid "The module or main program array %qs at %L must have constant shape"
-msgstr "Modul- eller huvudprogramvektorn ”%s” vid %L måste ha konstant form"
+msgstr "Modul- eller huvudprogramvektorn %qs vid %L måste ha konstant form"
#: fortran/resolve.c:11520
#, gcc-internal-format
@@ -54854,10 +54597,9 @@ msgid "Entity with assumed character length at %L must be a dummy argument or a
msgstr "Entitet med antagen teckenlängd vid %L måste vara ett attrappargument eller en PARAMETER"
#: fortran/resolve.c:11557
-#, fuzzy, gcc-internal-format
-#| msgid "'%s' at %L must have constant character length in this context"
+#, gcc-internal-format
msgid "%qs at %L must have constant character length in this context"
-msgstr "”%s” vid %L måste ha konstant teckenlängd i detta sammanhang"
+msgstr "%qs vid %L måste ha konstant teckenlängd i detta sammanhang"
#: fortran/resolve.c:11564
#, gcc-internal-format
@@ -54895,10 +54637,9 @@ msgid "Automatic array %qs at %L cannot have an initializer"
msgstr "Automatisk vektor %qs vid %L kan inte ha en initierare"
#: fortran/resolve.c:11669
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "in %s, at %s:%d"
+#, gcc-internal-format, gfc-internal-format
msgid "%s at %L"
-msgstr "i %s, vid %s:%d"
+msgstr "%s vid %L"
#: fortran/resolve.c:11696
#, gcc-internal-format
@@ -55251,10 +54992,9 @@ msgid "Component %qs with CLASS at %L must be allocatable or pointer"
msgstr "Procedur %qs med CLASS vid %L måste vara allokerbar eller en pekare"
#: fortran/resolve.c:13380
-#, fuzzy, gcc-internal-format
-#| msgid "Generic name '%s' of function '%s' at %L being the same name as derived type at %L"
+#, gcc-internal-format
msgid "Generic name %qs of function %qs at %L being the same name as derived type at %L"
-msgstr "Det generiska namnet ”%s” på funktionen ”%s” vid %L är samma namn som den härledda typen vid %L"
+msgstr "Det generiska namnet %qs på funktionen %qs vid %L är samma namn som den härledda typen vid %L"
#: fortran/resolve.c:13436
#, gcc-internal-format
@@ -55449,10 +55189,9 @@ msgid "Variable %s at %L of type LOCK_TYPE or with subcomponent of type LOCK_TYP
msgstr "Variabeln %s vid %L av typen LOCK_TYPE eller med en delkomponent av typen LOCK_TYPE måste vara en co-vektor"
#: fortran/resolve.c:14078
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Variable %s at %L of type LOCK_TYPE or with subcomponent of type LOCK_TYPE must be a coarray"
+#, gcc-internal-format, gfc-internal-format
msgid "Variable %s at %L of type EVENT_TYPE or with subcomponent of type LOCK_TYPE must be a coarray"
-msgstr "Variabeln %s vid %L av typen LOCK_TYPE eller med en delkomponent av typen LOCK_TYPE måste vara en co-vektor"
+msgstr "Variabeln %s vid %L av typen EVENT_TYPE eller med en delkomponent av typen LOCK_TYPE måste vara en co-vektor"
#: fortran/resolve.c:14096
#, gcc-internal-format
@@ -55465,10 +55204,9 @@ msgid "Dummy argument %qs at %L of LOCK_TYPE shall not be INTENT(OUT)"
msgstr "Attrappargumentet %qs vid %L av LOCK_TYPE får inte vara INTENT(OUT)"
#: fortran/resolve.c:14117
-#, fuzzy, gcc-internal-format
-#| msgid "Dummy argument %qs at %L of LOCK_TYPE shall not be INTENT(OUT)"
+#, gcc-internal-format
msgid "Dummy argument %qs at %L of EVENT_TYPE shall not be INTENT(OUT)"
-msgstr "Attrappargumentet %qs vid %L av LOCK_TYPE får inte vara INTENT(OUT)"
+msgstr "Attrappargumentet %qs vid %L av EVENT_TYPE får inte vara INTENT(OUT)"
#: fortran/resolve.c:14129
#, gcc-internal-format
@@ -55521,10 +55259,9 @@ msgid "LOGICAL result variable %qs at %L with non-C_Bool kind in BIND(C) procedu
msgstr "LOGICAL-resultatvariabeln %qs vid %L med icke-C_Bool-sort i BIND(C)-proceduren %qs"
#: fortran/resolve.c:14248
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Namelist %s cannot be renamed by USE association to %s"
+#, gcc-internal-format, gfc-internal-format
msgid "Namelist '%s' can not be an argument to subroutine or function at %L"
-msgstr "Namnlistan %s får inte namnändras av USE-association till %s"
+msgstr "Namnlistan ”%s” får inte vara ett argument till en subrutin eller funktion vid %L"
#: fortran/resolve.c:14317
#, gcc-internal-format, gfc-internal-format
@@ -55762,16 +55499,14 @@ msgid "Nonconforming tab character in column %d of line %d"
msgstr "Ej konformt tabulatortecken i kolumn %d på rad %d"
#: fortran/scanner.c:2070
-#, fuzzy, gcc-internal-format
-#| msgid "%s:%d: file %s left but not entered"
+#, gcc-internal-format
msgid "file %qs left but not entered"
-msgstr "%s:%d: gått ifrån men inte till filen %s"
+msgstr "gått ifrån men inte till filen %qs"
#: fortran/scanner.c:2108
-#, fuzzy, gcc-internal-format
-#| msgid "%s:%d: Illegal preprocessor directive"
+#, gcc-internal-format
msgid "Illegal preprocessor directive"
-msgstr "%s:%d: Ogiltigt preprocessordirektiv"
+msgstr "Ogiltigt preprocessordirektiv"
#: fortran/scanner.c:2235
#, gcc-internal-format
@@ -56060,16 +55795,14 @@ msgid "Failure getting length of a constant array."
msgstr "Misslyckades att bestämma längden på en konstant vektor."
#: fortran/simplify.c:6118
-#, fuzzy, gcc-internal-format
-#| msgid "The number of elements in the array constructor at %L requires an increase of the allowed %d upper limit. See %<-fmax-array-constructor%> option"
+#, gcc-internal-format
msgid "The number of elements (%d) in the array constructor at %L requires an increase of the allowed %d upper limit. See %<-fmax-array-constructor%> option."
-msgstr "Antalet element i vektorkonstrueraren vid %L kräver en ökning av den tillåtna övre gränsen %d. Se flaggan %<-fmax-array-constructor%>"
+msgstr "Antalet element (%d) i vektorkonstrueraren vid %L kräver en ökning av den tillåtna övre gränsen %d. Se flaggan %<-fmax-array-constructor%>"
#: fortran/simplify.c:6184
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "directive not yet implemented"
+#, gcc-internal-format, gfc-internal-format
msgid "Simplification of SPREAD at %L not yet implemented"
-msgstr "direktivet är inte implementerat ännu"
+msgstr "Förenkling av SPREAD vid %L är inte implementerat ännu"
#: fortran/simplify.c:6209
#, gcc-internal-format, gfc-internal-format
@@ -56112,10 +55845,9 @@ msgid "IMPLICIT NONE (type) statement at %L following an IMPLICIT statement"
msgstr "IMPLICIT NONE (type)-sats vid %L följer en IMPLICIT-sats"
#: fortran/symbol.c:168
-#, fuzzy, gcc-internal-format
-#| msgid "Letter %<%c%> already set in IMPLICIT statement at %C"
+#, gcc-internal-format
msgid "Letter %qc already set in IMPLICIT statement at %C"
-msgstr "Tecknet %<%c%> redan satt i IMPLICIT-sats vid %C"
+msgstr "Tecknet %qc redan satt i IMPLICIT-sats vid %C"
#: fortran/symbol.c:190
#, gcc-internal-format, gfc-internal-format
@@ -56123,10 +55855,9 @@ msgid "Cannot specify IMPLICIT at %C after IMPLICIT NONE"
msgstr "Det går inte att ange IMPLICIT vid %C efter IMPLICIT NONE"
#: fortran/symbol.c:200
-#, fuzzy, gcc-internal-format
-#| msgid "Letter %c already has an IMPLICIT type at %C"
+#, gcc-internal-format
msgid "Letter %qc already has an IMPLICIT type at %C"
-msgstr "Tecknet %c har redan en IMPLICIT-typ vid %C"
+msgstr "Tecknet %qc har redan en IMPLICIT-typ vid %C"
#: fortran/symbol.c:224
#, gcc-internal-format
@@ -56177,10 +55908,9 @@ msgid "Namelist group name at %L cannot have the SAVE attribute"
msgstr "Namnlistegruppnamnet vid %L kan inte ha attributet SAVE"
#: fortran/symbol.c:468
-#, fuzzy, gcc-internal-format
-#| msgid "internal procedure '%s' at %L conflicts with DUMMY argument"
+#, gcc-internal-format
msgid "internal procedure %qs at %L conflicts with DUMMY argument"
-msgstr "den interna proceduren ”%s” vid %L står i konflikt med DUMMY-argument"
+msgstr "den interna proceduren %qs vid %L står i konflikt med DUMMY-argument"
#: fortran/symbol.c:494
#, gcc-internal-format, gfc-internal-format
@@ -56342,10 +56072,9 @@ msgid "%qs at %L has attributes specified outside its INTERFACE body"
msgstr "%qs vid %L har attribut angivna utanför dess INTERFACE-kropp"
#: fortran/symbol.c:1813
-#, fuzzy, gcc-internal-format
-#| msgid "Symbol '%s' at %L conflicts with symbol from module '%s', use-associated at %L"
+#, gcc-internal-format
msgid "Symbol %qs at %L conflicts with symbol from module %qs, use-associated at %L"
-msgstr "Symbolen ”%s” vid %L står i konflikt med symbolen från modulen ”%s”, användningsassocierad vid %L"
+msgstr "Symbolen %qs vid %L står i konflikt med symbolen från modulen %qs, användningsassocierad vid %L"
#: fortran/symbol.c:1817
#, gcc-internal-format
@@ -56363,16 +56092,14 @@ msgid "Symbol %qs at %L cannot have a type"
msgstr "Symbolen %qs vid %L kan inte ha en typ"
#: fortran/symbol.c:2057
-#, fuzzy, gcc-internal-format
-#| msgid "Component '%s' at %C already declared at %L"
+#, gcc-internal-format
msgid "Component %qs at %C already declared at %L"
-msgstr "Komponenten ”%s” vid %C är redan deklarerad vid %L"
+msgstr "Komponenten %qs vid %C är redan deklarerad vid %L"
#: fortran/symbol.c:2068
-#, fuzzy, gcc-internal-format
-#| msgid "Component '%s' at %C already in the parent type at %L"
+#, gcc-internal-format
msgid "Component %qs at %C already in the parent type at %L"
-msgstr "Komponenten ”%s” vid %C finns redan i föräldratypen vid %L"
+msgstr "Komponenten %qs vid %C finns redan i föräldratypen vid %L"
#: fortran/symbol.c:2153
#, gcc-internal-format
@@ -56467,22 +56194,19 @@ msgid "Derived type %qs with BIND(C) attribute at %L is empty, and may be inacce
msgstr "Härledd typ %qs med attributet BIND(C) vid %L är tom, och kan vara otillgängliga av C-följeslagarprocessorn"
#: fortran/symbol.c:4074
-#, fuzzy, gcc-internal-format
-#| msgid "Component '%s' at %L cannot have the POINTER attribute because it is a member of the BIND(C) derived type '%s' at %L"
+#, gcc-internal-format
msgid "Component %qs at %L cannot have the POINTER attribute because it is a member of the BIND(C) derived type %qs at %L"
-msgstr "Komponent ”%s” vid %L får inte ha attributet POINTER eftersom det är en medlem av den BIND(C)-härledda typen ”%s” vid %L"
+msgstr "Komponent %qs vid %L får inte ha attributet POINTER eftersom det är en medlem av den BIND(C)-härledda typen %qs vid %L"
#: fortran/symbol.c:4084
-#, fuzzy, gcc-internal-format
-#| msgid "Procedure pointer component '%s' at %L cannot be a member of the BIND(C) derived type '%s' at %L"
+#, gcc-internal-format
msgid "Procedure pointer component %qs at %L cannot be a member of the BIND(C) derived type %qs at %L"
-msgstr "Procedurpekarkomponenten ”%s” vid %L kan inte vara en medlem av den BIND(C)-härledda typen ”%s” vid %L"
+msgstr "Procedurpekarkomponenten %qs vid %L kan inte vara en medlem av den BIND(C)-härledda typen %qs vid %L"
#: fortran/symbol.c:4095
-#, fuzzy, gcc-internal-format
-#| msgid "Component '%s' at %L cannot have the ALLOCATABLE attribute because it is a member of the BIND(C) derived type '%s' at %L"
+#, gcc-internal-format
msgid "Component %qs at %L cannot have the ALLOCATABLE attribute because it is a member of the BIND(C) derived type %qs at %L"
-msgstr "Komponent ”%s” vid %L får inte ha attributet ALLOCATABLE eftersom det är en medlem av den BIND(C)-härledda typen ”%s” vid %L"
+msgstr "Komponent %qs vid %L får inte ha attributet ALLOCATABLE eftersom det är en medlem av den BIND(C)-härledda typen %qs vid %L"
#: fortran/symbol.c:4134
#, gcc-internal-format
@@ -56577,10 +56301,9 @@ msgid "Illegal reference type at %L as EQUIVALENCE object"
msgstr "Ogiltig referenstyp vid %L som EQUIVALENCE-objekt"
#: fortran/trans-common.c:913
-#, fuzzy, gcc-internal-format
-#| msgid "Inconsistent equivalence rules involving '%s' at %L and '%s' at %L"
+#, gcc-internal-format
msgid "Inconsistent equivalence rules involving %qs at %L and %qs at %L"
-msgstr "Inkonsistenta ekvivalensregler rörande ”%s” vid %L och ”%s” vid %L"
+msgstr "Inkonsistenta ekvivalensregler rörande %qs vid %L och %qs vid %L"
#. Aligning this field would misalign a previous field.
#: fortran/trans-common.c:1046
@@ -56609,10 +56332,9 @@ msgid "Padding of %d bytes required before %qs in COMMON at %L; reorder elements
msgstr "Utfyllnad med %d byte krävs före %qs i COMMON vid %L, byt ordning på element eller använd -fno-align-commons"
#: fortran/trans-common.c:1169
-#, fuzzy, gcc-internal-format
-#| msgid "COMMON '%s' at %L does not exist"
+#, gcc-internal-format
msgid "COMMON %qs at %L does not exist"
-msgstr "COMMON ”%s” vid %L existerar inte"
+msgstr "COMMON %qs vid %L finns inte"
#: fortran/trans-common.c:1178
#, gcc-internal-format
@@ -56756,16 +56478,14 @@ msgid "%<dim%> argument of %s intrinsic at %L is not a valid dimension index"
msgstr "%<dim%>-argumentet till inbyggd %s vid %L är inte ett giltigt dimensionsindex"
#: fortran/trans-intrinsic.c:9366 fortran/trans-stmt.c:919
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Sorry, the lock component of derived type at %L is not yet supported"
+#, gcc-internal-format, gfc-internal-format
msgid "Sorry, the event component of derived type at %L is not yet supported"
-msgstr "Ledsen, låskomponenten hos härledd typ vid %L stödjs inte ännu"
+msgstr "Ledsen, händelsekomponenten hos härledd typ vid %L stödjs inte ännu"
#: fortran/trans-intrinsic.c:9373
-#, fuzzy, gcc-internal-format, gfc-internal-format
-#| msgid "Pointer object at %C shall not be coindexed"
+#, gcc-internal-format, gfc-internal-format
msgid "The event variable at %L shall not be coindexed "
-msgstr "Pekarobjektet vid %C kan inte vara co-indexerat"
+msgstr "Händelsevariabeln vid %L får inte vara co-indexerat"
#: fortran/trans-io.c:1849
#, gcc-internal-format
@@ -57260,10 +56980,9 @@ msgid "previously defined here"
msgstr "tidigare definition här"
#: lto/lto-symtab.c:664
-#, fuzzy, gcc-internal-format
-#| msgid "type %qT violates one definition rule"
+#, gcc-internal-format
msgid "%qD violates the C++ One Definition Rule "
-msgstr "typen %qT bryter mot endefinitionsregeln "
+msgstr "%qD bryter mot C++ endefinitionsregel "
#: lto/lto-symtab.c:669
#, gcc-internal-format
@@ -57276,16 +56995,14 @@ msgid "alignment of %qD is bigger than original declaration"
msgstr "justering av %qD är större än originaldeklarationen"
#: lto/lto-symtab.c:695
-#, fuzzy, gcc-internal-format
-#| msgid "type of %qD does not match original declaration"
+#, gcc-internal-format
msgid "size of %qD differ from the size of original declaration"
-msgstr "typen på %qD stämmer inte med originaldeklarationen"
+msgstr "storleken på %qD skiljer från storleken på originaldeklarationen"
#: lto/lto-symtab.c:700
-#, fuzzy, gcc-internal-format
-#| msgid "%q#T was previously declared here"
+#, gcc-internal-format
msgid "%qD was previously declared here"
-msgstr "%q#T deklarerades tidigare här"
+msgstr "%qD deklarerades tidigare här"
#: lto/lto-symtab.c:703
#, gcc-internal-format
@@ -58353,388 +58070,3 @@ msgstr "%<-fobjc-sjlj-exceptions%> ignoreras för %<-fnext-runtime%> när %<-fob
#, gcc-internal-format
msgid "creating selector for nonexistent method %qE"
msgstr "skapar selektor för icke existerande metod %qE"
-
-#~ msgid "Use the same size for double as for float."
-#~ msgstr "Använd samma storlek för double som för float."
-
-#~ msgid "installation error, can't find crtoffloadend.o"
-#~ msgstr "installationsfel, kan inte hitta crtoffloadend.o"
-
-#~ msgid "try reducing the number of local variables"
-#~ msgstr "försök reducera antalet lokala variabler"
-
-#~ msgid "statement is indented as if it were guarded by..."
-#~ msgstr "satsen är indenterad som om den vore skyddad av …"
-
-#~ msgid "stabs debug format not supported"
-#~ msgstr "stabs felsökningsformat stödjs inte"
-
-#~ msgid "negative array subscript"
-#~ msgstr "negativt vektorindex"
-
-#~ msgid "array subscript out of bound"
-#~ msgstr "vektorindex är utanför gränserna"
-
-#~ msgid "comparison with string literal results in unspecified behaviour"
-#~ msgstr "jämförelse med strängkonstant resulterar i odefinierat beteende"
-
-#~ msgid "Bound on the number of variables in Omega constraint systems"
-#~ msgstr "Gräns för antalet variabler i Omegasystem av bivillkor"
-
-#~ msgid "Bound on the number of inequalities in Omega constraint systems"
-#~ msgstr "Gräns för antalet olikheter i Omegasystem av bivillkor"
-
-#~ msgid "Bound on the number of equalities in Omega constraint systems"
-#~ msgstr "Gräns för antalet likheter i Omegasystem av bivillkor"
-
-#~ msgid "Bound on the number of wild cards in Omega constraint systems"
-#~ msgstr "Gräns för antalet jokrar i Omegasystem av bivillkor"
-
-#~ msgid "Bound on the size of the hash table in Omega constraint systems"
-#~ msgstr "Gräns för storleken på hash-tabellen i Omegasystem av bivillkor"
-
-#~ msgid "Bound on the number of keys in Omega constraint systems"
-#~ msgstr "Gräns för antalet nycklar i Omegasystem av bivillkor"
-
-#~ msgid "When set to 1, use expensive methods to eliminate all redundant constraints"
-#~ msgstr "När satt till 1, använd dyra metoder för att eliminera alla överflödiga bivillkor"
-
-#~ msgid "size of unrolling factor for unroll-and-jam"
-#~ msgstr "storlek på utrullningsfaktorn för unroll-and-jam"
-
-#~ msgid "depth of unrolled loop for unroll-and-jam"
-#~ msgstr "djupet på utrullade slingor för unroll-and-jam"
-
-#~ msgid "invalid %%H value"
-#~ msgstr "ogiltigt %%H-värde"
-
-#~ msgid "invalid %%S value"
-#~ msgstr "ogiltigt %%S-värde"
-
-#~ msgid "memory reference expected for 'O' output modifier"
-#~ msgstr "minnesreferens förväntas för utmatningsmodifieraren ”O”"
-
-#~ msgid "memory reference expected for 'R' output modifier"
-#~ msgstr "minnesreferens förväntas för utmatningsmodifieraren ”R”"
-
-#~ msgid "long long constant not a valid immediate operand"
-#~ msgstr "long long-konstant inte en giltig omedelbar operand"
-
-#~ msgid "Warning:"
-#~ msgstr "Varning:"
-
-#~ msgid "Error:"
-#~ msgstr "Fel:"
-
-#~ msgid ""
-#~ "GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n"
-#~ "You may redistribute copies of GNU Fortran\n"
-#~ "under the terms of the GNU General Public License.\n"
-#~ "For more information about these matters, see the file named COPYING\n"
-#~ "\n"
-#~ msgstr ""
-#~ "GNU Fortran kommer UTAN GARANTI så långt lagen tillåter. Du kan\n"
-#~ "vidaredistribuera kopior av GNU Fortran enligt villkoren i GNU General\n"
-#~ "Public License. För mer information om detta ämne, se filen som heter\n"
-#~ "COPYING\n"
-#~ "\n"
-
-#~ msgid "Deprecated in favor of -Wc++11-compat"
-#~ msgstr "Bör undvikas till förmån för -Wc++11-compat"
-
-#~ msgid "Conform to the ISO 2014 C++ standard (experimental and incomplete support)"
-#~ msgstr "Följ standarden ISO 2014 C++ (experimentellt och ofullständigt stöd)"
-
-#~ msgid "Conform to the ISO 2011 C standard (experimental and incomplete support)"
-#~ msgstr "Följ standarden ISO 2011 C (experimentellt och ofullständigt stöd)"
-
-#~ msgid "Conform to the ISO 2011 C++ standard with GNU extensions (experimental and incomplete support)"
-#~ msgstr "Följ standarden ISO 2011 C++ med GNU-utökningar (experimentellt och ofullständigt stöd)"
-
-#~ msgid "Conform to the ISO 2014 C++ standard with GNU extensions (experimental and incomplete support)"
-#~ msgstr "Följ standarden ISO 2014 C++ med GNU-utökningar (experimentellt och ofullständigt stöd)"
-
-#~ msgid "Conform to the ISO 2011 C standard with GNU extensions (experimental and incomplete support)"
-#~ msgstr "Följ standarden ISO 2011 C med GNU-utökningar (experimentellt och ofullständigt stöd)"
-
-#~ msgid "Specify the name of the target architecture"
-#~ msgstr "Ange namnet på målarkitekturen"
-
-#~ msgid "Ignored (obsolete)"
-#~ msgstr "Ignorerad (föråldrad)"
-
-#~ msgid "mvcle use"
-#~ msgstr "använd mvcle"
-
-#~ msgid "Select hardware or software multiplication support."
-#~ msgstr "Välj hårdvaru- eller programvarustöd för multiplikation."
-
-#~ msgid "Target the RL78/G10 series"
-#~ msgstr "Sikta på serien RL78/G10"
-
-#~ msgid "Use big-endian byte order"
-#~ msgstr "Använd rak byteordning"
-
-#~ msgid "Use little-endian byte order"
-#~ msgstr "Använd omvänd byteordning"
-
-#~ msgid "Generate floating-point multiply-add instructions"
-#~ msgstr "Generera multiplicera-/adderainstruktioner för flyttal"
-
-#~ msgid "Generate ARCompact 32-bit code for ARCtangent-A5 processor"
-#~ msgstr "Generera ARCompact 32-bitars kod för processorn ARCtangent-A5"
-
-#~ msgid "Disable generation of cfi for epilogues."
-#~ msgstr "Avaktivera generering av cfi för epiloger."
-
-#~ msgid "Enable generation of cfi for epilogues."
-#~ msgstr "Aktivera generering av cfi för epiloger."
-
-#~ msgid "Compare the results of several data dependence analyzers."
-#~ msgstr "Jämför resultaten av flera analyserare av databeroende."
-
-#~ msgid "Enable Loop Strip Mining transformation"
-#~ msgstr "Aktivera transformationen utgrävning av remsor (strip mining) i slingor"
-
-#~ msgid "Enable Loop Interchange transformation"
-#~ msgstr "Aktivera transformationen utbyte (interchange) i slingor"
-
-#~ msgid "Enable Loop Blocking transformation"
-#~ msgstr "Aktivera slingblockeringstransformation"
-
-#~ msgid "Enable Loop Unroll Jam transformation"
-#~ msgstr "Aktivera transformationen av utrullningsstockningar i slingor"
-
-#~ msgid "Enable coalescing of copy-related user variables that are inlined"
-#~ msgstr "Aktivera sammanläggning av kopieringsrelaterade användarvariabler som är inline:ade"
-
-#~ msgid "Replace SSA temporaries with better names in copies"
-#~ msgstr "Ersätt SSA-temporärer med bättre namn i kopieringar"
-
-#~ msgid "expected integer or boolean type"
-#~ msgstr "heltal eller boolesk typ förväntades"
-
-#~ msgid "invalid argument to %<__builtin_frame_address%>"
-#~ msgstr "ogiltigt argument till %<__builtin_frame_address%>"
-
-#~ msgid "invalid argument to %<__builtin_return_address%>"
-#~ msgstr "ogiltigt argument till %<__builtin_return_address%>"
-
-#~ msgid "unsupported argument to %<__builtin_frame_address%>"
-#~ msgstr "ej stött argument till %<__builtin_frame_address%>"
-
-#~ msgid "unsupported argument to %<__builtin_return_address%>"
-#~ msgstr "ej stött argument till %<__builtin_return_address%>"
-
-#~ msgid "assuming signed overflow does not occur when negating a division"
-#~ msgstr "antar att teckenspill inte förekommer vid negering av en division"
-
-#~ msgid "assuming signed overflow does not occur when changing X - Y cmp 0 to X cmp Y"
-#~ msgstr "antar att teckenspill inte förekommer vid ändring av X - Y jmf 0 till X jmf Y ± K2"
-
-#~ msgid "%qE not specified in enclosing parallel"
-#~ msgstr "%qE inte angiven i omgivande parallel"
-
-#~ msgid "enclosing parallel"
-#~ msgstr "omgivande parallel"
-
-#~ msgid "type %qT defined in anonymous namespace can not match type %qT"
-#~ msgstr "typen %qT är definierad i en anonym namnrymd och kan inte matcha typen %qT"
-
-#~ msgid "the incompatible type defined in anonymous namespace in another translation unit"
-#~ msgstr "den inkompatibla typen är definierad i en anonym namnrymd i en annan översättningsenhet"
-
-#~ msgid "type %qT should match type %qT but is defined in different namespace "
-#~ msgstr "typen %qT borde matcha typen %qT men är definierad i en annan namnrymd "
-
-#~ msgid "type %qT should match type %qT that itself violate one definition rule"
-#~ msgstr "typen %qT borde matcha typen %qT som själv bryter mot endefinitionsregeln"
-
-#~ msgid "a type with attributes is defined in another translation unit"
-#~ msgstr "en typ med attribut är definierad i en annan översättningsenhet"
-
-#~ msgid "clause not supported yet"
-#~ msgstr "klausulen stödjs inte än"
-
-#~ msgid "no arguments allowed to gang, worker and vector clauses inside parallel"
-#~ msgstr "inga argument tillåtna i gang-, worker- och vector-klausuler inuti parallel"
-
-#~ msgid "gang, worker and vector may occur only once in a loop nest"
-#~ msgstr "gang, worker och vector får endast förekomma en gång i ett slingnäste"
-
-#~ msgid "gang, worker and vector must occur in this order in a loop nest"
-#~ msgstr "gang, worker och vector måste förekomma i denna ordning inuti ett slingnäste"
-
-#~ msgid "-fsanitize-recover=address is not supported"
-#~ msgstr "-fsanitize-recover=address stödjs inte"
-
-#~ msgid "-mcpu string too large"
-#~ msgstr "strängen till -mcpu är för stor"
-
-#~ msgid "%qs and floating point or vector arguments"
-#~ msgstr "%qs och flyttals- eller vektorargument"
-
-#~ msgid "operand 2 of %s instruction should be an unsigned %d-bit value"
-#~ msgstr "operand 2 till instruktionen %s skall vara ett teckenlöst %d-bits värde"
-
-#~ msgid "operand 2 of %s instruction should be an unsigned 8-bit value"
-#~ msgstr "operand 2 till instruktionen %s skall vara ett teckenlöst 8-bitars värde"
-
-#~ msgid "operand 1 of %s instruction should be an unsigned 3-bit value (DR0-DR7)"
-#~ msgstr "operand 1 till instruktionen %s skall vara ett teckenlöst 3-bitars värde (DR0-DR7)"
-
-#~ msgid "operand of %s instruction should be an unsigned 6-bit value"
-#~ msgstr "operanden till instruktionen %s skall vara ett teckenlöst 6-bitars värde"
-
-#~ msgid "operand 3 of %s instruction should be an unsigned 8-bit value"
-#~ msgstr "operand 3 till instruktionen %s skall vara ett teckenlöst 8-bitars värde"
-
-#~ msgid "incompatible type for argument %d, expected %<const int%>"
-#~ msgstr "inkompatibel typ för argument %d, %<const int%> förväntades"
-
-#~ msgid "unrecognizable argument of option -foffload-abi"
-#~ msgstr "okänt argument till flaggan -foffload-abi"
-
-#~ msgid "%q+D:'selectany' attribute applies only to initialized objects"
-#~ msgstr "%q+D: attributet ”selectany” tillämpas endast på initierade objekt"
-
-#~ msgid "-fPIC ignored for target (all code is position independent)"
-#~ msgstr "-fPIC ignoreras för målet (all kod är positionsoberoende)"
-
-#~ msgid "-f%s ignored for target (all code is position independent)"
-#~ msgstr "-f%s ignoreras för målet (all kod är positionsoberoende)"
-
-#~ msgid "-mbnu210 is ignored (option is obsolete)"
-#~ msgstr "-mbnu210 ignoreras (flaggan är föråldrad)"
-
-#~ msgid "the %<interrupt%> attribute requires %<-msoft-float%>"
-#~ msgstr "attributet %<interrupt%> kräver %<-msoft-float%>"
-
-#~ msgid "only register based stack limit is supported"
-#~ msgstr "endast registerbaserade stackgränser stödjs"
-
-#~ msgid "Transactional execution builtins not enabled (-mhtm)\n"
-#~ msgstr "Inbyggda för transaktionsvis körning är inte aktiverade (-mhtm)\n"
-
-#~ msgid "non-default Scalar_Storage_Order"
-#~ msgstr "ickestandard Scalar_Storage_Order"
-
-#~ msgid "%q+D in block scope inside of declare target directive"
-#~ msgstr "%q+D i blockräckvidd inuti ett deklarationsmålsdirektiv"
-
-#~ msgid "%<%s %E%> declared inside parameter list"
-#~ msgstr "%<%s %E%> deklarerad inuti parameterlista"
-
-#~ msgid "anonymous %s declared inside parameter list"
-#~ msgstr "anonym %s deklarerad inuti parameterlista"
-
-#~ msgid "its scope is only this definition or declaration, which is probably not what you want"
-#~ msgstr "dess scope-område är endast denna definition eller deklaration, vilket troligen inte är vad du vill."
-
-#~ msgid "selected for placement delete"
-#~ msgstr "vald för placerad delete"
-
-#~ msgid "%q+#D is private"
-#~ msgstr "%q+#D är privat"
-
-#~ msgid "%q+#D is protected"
-#~ msgstr "%q+#D är skyddad"
-
-#~ msgid " initializing argument %P of %q+D"
-#~ msgstr " initierar argument %P till %q+D"
-
-#~ msgid " in call to %q+D"
-#~ msgstr " i anrop till %q+D"
-
-#~ msgid "difference of two pointer expressions is not a constant expression"
-#~ msgstr "skillnaden mellan två pekaruttryck är inte ett konstant uttryck"
-
-#~ msgid "pointer comparison expression is not a constant expression"
-#~ msgstr "pekarjämförelseuttryck är inte ett konstant uttryck"
-
-#~ msgid "%qE implicitly determined as %<firstprivate%> has reference type"
-#~ msgstr "%qE som implicit bestämts som %<firstprivate%> har referenstyp"
-
-#~ msgid "variable %q+D set but not used"
-#~ msgstr "variabeln %q+D sätts men används inte"
-
-#~ msgid "declaration of %qF has a different exception specifier"
-#~ msgstr "deklaration av %qF har en annan undantagsspecificerare"
-
-#~ msgid "jump to label %q+D"
-#~ msgstr "hopp till etikett %q+D"
-
-#~ msgid "%<constexpr%> is not allowed in declaration of friend template specialization %qD"
-#~ msgstr "%<constexpr%> är inte tillåtet i deklaration av vänmallspecialisering %qD"
-
-#~ msgid "size of array %qs is too large"
-#~ msgstr "storleken på vektorn %qs är för stor"
-
-#~ msgid "type qualifiers specified for friend class declaration"
-#~ msgstr "typkvalificerare angivna för vänklassdeklaration"
-
-#~ msgid "no previous declaration for %q+D"
-#~ msgstr "ingen tidigare deklaration av %q+D"
-
-#~ msgid "parameter %q+D set but not used"
-#~ msgstr "parametern %q+D sätts men används inte"
-
-#~ msgid "%q+D declared here"
-#~ msgstr "%q+D är deklarerad här"
-
-#~ msgid "previous declaration %q+#D"
-#~ msgstr "tidigare deklaration %q+#D"
-
-#~ msgid "%qD is not an enumerator-name"
-#~ msgstr "%qD är inte ett uppräkningsnamn"
-
-#~ msgid "deprecated use of default argument for parameter of non-function"
-#~ msgstr "användning av standardargument för parametrar till annat än funktioner bör undvikas"
-
-#~ msgid "expected positive integer expression"
-#~ msgstr "positivt heltalsuttryck förväntades"
-
-#~ msgid "declaration of %q+#D"
-#~ msgstr "deklaration av %q+#D"
-
-#~ msgid " shadows template parm %q+#D"
-#~ msgstr " skuggar mallparameter %q+#D"
-
-#~ msgid "switch condition has type bool"
-#~ msgstr "switch-villkor har typen bool"
-
-#~ msgid "num_threads expression must be integral"
-#~ msgstr "num_threads-uttryck måste vara heltal"
-
-#~ msgid "%qE has reference type for %qs"
-#~ msgstr "%qE har referenstyp för %qs"
-
-#~ msgid "invalid use of non-static member function"
-#~ msgstr "ogiltig användning av icke-statisk medlemsfunktion"
-
-#~ msgid "\t%+#D"
-#~ msgstr "\t%+#D"
-
-#~ msgid "%q+D has incomplete type"
-#~ msgstr "%q+D har en ofullständig typ"
-
-#~ msgid "Conflict in attributes of function argument at %C"
-#~ msgstr "Konflikt i attribut för funktionsargument vid %C"
-
-#~ msgid "Error count reached limit of %d."
-#~ msgstr "Felantal nådde gränsen vid %d."
-
-#~ msgid "Clause GANG conflicts with WORKER at %L"
-#~ msgstr "Klausulen GANG står i konflikt med WORKER vid %L"
-
-#~ msgid "Clause GANG conflicts with VECTOR at %L"
-#~ msgstr "Klausulen GANG står i konflikt med VECTOR vid %L"
-
-#~ msgid "Clause WORKER conflicts with VECTOR at %L"
-#~ msgstr "WORKER-klausulen står i konflikt med VECTOR vid %L"
-
-#~ msgid "Sorry, !$ACC cache unimplemented yet"
-#~ msgstr "Ledsen, !$ACC-cache är fortfarande oimplementerat"
-
-#~ msgid "CHARACTER variable at %L has negative length %d, the length has been set to zero"
-#~ msgstr "CHARACTER-variabel vid %L har negativ längd %d, längden har satts till noll"
diff --git a/gcc/po/zh_CN.po b/gcc/po/zh_CN.po
index 119c6ce6dc0..d04028e5df0 100644
--- a/gcc/po/zh_CN.po
+++ b/gcc/po/zh_CN.po
@@ -5,6 +5,29 @@
# Jeff Bai <jeffbai@aosc.xyz>, 2015.
# Mingye Wang (Arthur2e5) <arthur200126@gmail.com>, 2015, 2016.
#
+# Fellow translatiors:
+# Many of the fuzzy strings are caused by an addition of a period (".")
+# mark in the original text. Consider writing a, e.g., python script
+# that parses the PO file with tools provided by translate-toolkit,
+# and adds a Chinese period ("。") to the msgstr and unfuzzy the string
+# if msgid string is really just (the '#| msgid' string) + (".").
+#
+# PO-escapes in translate-toolkit parsers are really a mess (I really
+# consider it an abstraction leak), so you may want to refer to my
+# (ugly) example at github.com/AOSC-Dev/translations/commit/f1d15d9.
+#
+# You may find some fuzzy strings perfectly fine. Some of them are
+# written by our friends in Taiwan, who seems to have done some similar
+# conversion work to give themselves a headstart. Remember to do some
+# concordance check. Find-and-replace is good for dealing with simple
+# differences in terminology, e.g. 型态 (TW) == 类型 (CN) == type (en).
+# Perhaps the only difference that forces you to do manual replacements
+# is that they have just the reverse ideas about 行 and 列 from us.
+#
+# The work may not be that difficult, it's just time-consuming and
+# somehow boring to fight a hill of fuzzy strings. Consider having some
+# caffeine along with this work. -- Arthur2e5, 2016-05-01.
+#
msgid ""
msgstr ""
"Project-Id-Version: gcc 6.1.0\n"
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index aa6593f28f4..58b611891e3 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -324,7 +324,7 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
if (TREE_PROTECTED (node))
fputs (" protected", file);
if (TREE_STATIC (node))
- fputs (" static", file);
+ fputs (code == CALL_EXPR ? " must-tail-call" : " static", file);
if (TREE_DEPRECATED (node))
fputs (" deprecated", file);
if (TREE_VISITED (node))
diff --git a/gcc/read-md.c b/gcc/read-md.c
index b5beb4ac9da..b422d8dc75c 100644
--- a/gcc/read-md.c
+++ b/gcc/read-md.c
@@ -391,6 +391,17 @@ read_skip_spaces (void)
}
}
+/* Consume any whitespace, then consume the next non-whitespace
+ character, issuing a fatal error if it is not EXPECTED. */
+
+void
+require_char_ws (char expected)
+{
+ int ch = read_skip_spaces ();
+ if (ch != expected)
+ fatal_expected_char (expected, ch);
+}
+
/* Read an rtx code name into NAME. It is terminated by any of the
punctuation chars of rtx printed syntax. */
@@ -603,11 +614,7 @@ read_string (int star_if_braced)
fatal_with_file_and_line ("expected `\"' or `{', found `%c'", c);
if (saw_paren)
- {
- c = read_skip_spaces ();
- if (c != ')')
- fatal_expected_char (')', c);
- }
+ require_char_ws (')');
set_md_ptr_loc (stringbuf, read_md_filename, old_lineno);
return stringbuf;
@@ -764,9 +771,7 @@ handle_constants (void)
int c;
htab_t defs;
- c = read_skip_spaces ();
- if (c != '[')
- fatal_expected_char ('[', c);
+ require_char_ws ('[');
/* Disable constant expansion during definition processing. */
defs = md_constants;
@@ -782,9 +787,7 @@ handle_constants (void)
read_name (&value);
add_constant (defs, xstrdup (name.string), xstrdup (value.string), 0);
- c = read_skip_spaces ();
- if (c != ')')
- fatal_expected_char (')', c);
+ require_char_ws (')');
}
md_constants = defs;
}
@@ -846,9 +849,7 @@ handle_enum (file_location loc, bool md_p)
*slot = def;
}
- c = read_skip_spaces ();
- if (c != '[')
- fatal_expected_char ('[', c);
+ require_char_ws ('[');
while ((c = read_skip_spaces ()) != ']')
{
@@ -1007,9 +1008,7 @@ handle_file (directive_handler_t handle_directive)
else
read_skip_construct (1, loc);
- c = read_skip_spaces ();
- if (c != ')')
- fatal_expected_char (')', c);
+ require_char_ws (')');
}
fclose (read_md_file);
}
@@ -1063,7 +1062,7 @@ parse_include (const char *arg)
details about the callback's interface. */
bool
-read_md_files (int argc, char **argv, bool (*parse_opt) (const char *),
+read_md_files (int argc, const char **argv, bool (*parse_opt) (const char *),
directive_handler_t handle_directive)
{
int i;
diff --git a/gcc/read-md.h b/gcc/read-md.h
index cc6a5be250d..fa259517a26 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -141,6 +141,7 @@ extern void fatal_with_file_and_line (const char *, ...)
ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
extern void fatal_expected_char (int, int) ATTRIBUTE_NORETURN;
extern int read_skip_spaces (void);
+extern void require_char_ws (char expected);
extern void read_name (struct md_name *);
extern char *read_quoted_string (void);
extern char *read_string (int);
@@ -150,7 +151,7 @@ extern void upcase_string (char *);
extern void traverse_md_constants (htab_trav, void *);
extern void traverse_enum_types (htab_trav, void *);
extern struct enum_type *lookup_enum_type (const char *);
-extern bool read_md_files (int, char **, bool (*) (const char *),
+extern bool read_md_files (int, const char **, bool (*) (const char *),
directive_handler_t);
#endif /* GCC_READ_MD_H */
diff --git a/gcc/read-rtl.c b/gcc/read-rtl.c
index 79f42bf01e6..dc3a336b45b 100644
--- a/gcc/read-rtl.c
+++ b/gcc/read-rtl.c
@@ -742,9 +742,7 @@ read_conditions (void)
{
int c;
- c = read_skip_spaces ();
- if (c != '[')
- fatal_expected_char ('[', c);
+ require_char_ws ('[');
while ( (c = read_skip_spaces ()) != ']')
{
@@ -759,14 +757,10 @@ read_conditions (void)
validate_const_int (name.string);
value = atoi (name.string);
- c = read_skip_spaces ();
- if (c != '"')
- fatal_expected_char ('"', c);
+ require_char_ws ('"');
expr = read_quoted_string ();
- c = read_skip_spaces ();
- if (c != ')')
- fatal_expected_char (')', c);
+ require_char_ws (')');
add_c_test (expr, value);
}
@@ -890,9 +884,7 @@ read_mapping (struct iterator_group *group, htab_t table)
read_name (&name);
m = add_mapping (group, table, name.string);
- c = read_skip_spaces ();
- if (c != '[')
- fatal_expected_char ('[', c);
+ require_char_ws ('[');
/* Read each value. */
end_ptr = &m->values;
@@ -912,9 +904,7 @@ read_mapping (struct iterator_group *group, htab_t table)
/* A "(name string)" pair. */
read_name (&name);
string = read_string (false);
- c = read_skip_spaces ();
- if (c != ')')
- fatal_expected_char (')', c);
+ require_char_ws (')');
}
number = group->find_builtin (name.string);
end_ptr = add_map_value (end_ptr, number, string);
@@ -1181,9 +1171,7 @@ read_rtx_code (const char *code_name)
int list_counter = 0;
rtvec return_vec = NULL_RTVEC;
- c = read_skip_spaces ();
- if (c != '[')
- fatal_expected_char ('[', c);
+ require_char_ws ('[');
/* Add expressions to a list, while keeping a count. */
obstack_init (&vector_stack);
@@ -1398,12 +1386,9 @@ static rtx
read_nested_rtx (void)
{
struct md_name name;
- int c;
rtx return_rtx;
- c = read_skip_spaces ();
- if (c != '(')
- fatal_expected_char ('(', c);
+ require_char_ws ('(');
read_name (&name);
if (strcmp (name.string, "nil") == 0)
@@ -1411,9 +1396,7 @@ read_nested_rtx (void)
else
return_rtx = read_rtx_code (name.string);
- c = read_skip_spaces ();
- if (c != ')')
- fatal_expected_char (')', c);
+ require_char_ws (')');
return return_rtx;
}
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index ccf53bfbc1f..f4dac083045 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -449,6 +449,7 @@ init_reg_sets_1 (void)
}
COPY_HARD_REG_SET (call_fixed_reg_set, fixed_reg_set);
+ COPY_HARD_REG_SET (fixed_nonglobal_reg_set, fixed_reg_set);
/* Preserve global registers if called more than once. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
diff --git a/gcc/regrename.c b/gcc/regrename.c
index 9643f328ea3..54c7768efa2 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -61,7 +61,10 @@
5. If a renaming register has been found, it is substituted in the chain.
Targets can parameterize the pass by specifying a preferred class for the
- renaming register for a given (super)class of registers to be renamed. */
+ renaming register for a given (super)class of registers to be renamed.
+
+ DEBUG_INSNs are treated specially, in particular registers occurring inside
+ them are treated as requiring ALL_REGS as a class. */
#if HOST_BITS_PER_WIDE_INT <= MAX_RECOG_OPERANDS
#error "Use a different bitmap implementation for untracked_operands."
@@ -1238,6 +1241,19 @@ scan_rtx_reg (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions act
}
}
+/* A wrapper around base_reg_class which returns ALL_REGS if INSN is a
+ DEBUG_INSN. The arguments MODE, AS, CODE and INDEX_CODE are as for
+ base_reg_class. */
+
+static reg_class
+base_reg_class_for_rename (rtx_insn *insn, machine_mode mode, addr_space_t as,
+ rtx_code code, rtx_code index_code)
+{
+ if (DEBUG_INSN_P (insn))
+ return ALL_REGS;
+ return base_reg_class (mode, as, code, index_code);
+}
+
/* Adapted from find_reloads_address_1. CL is INDEX_REG_CLASS or
BASE_REG_CLASS depending on how the register is being considered. */
@@ -1343,12 +1359,16 @@ scan_rtx_address (rtx_insn *insn, rtx *loc, enum reg_class cl,
}
if (locI)
- scan_rtx_address (insn, locI, INDEX_REG_CLASS, action, mode, as);
+ {
+ reg_class iclass = DEBUG_INSN_P (insn) ? ALL_REGS : INDEX_REG_CLASS;
+ scan_rtx_address (insn, locI, iclass, action, mode, as);
+ }
if (locB)
- scan_rtx_address (insn, locB,
- base_reg_class (mode, as, PLUS, index_code),
- action, mode, as);
-
+ {
+ reg_class bclass = base_reg_class_for_rename (insn, mode, as, PLUS,
+ index_code);
+ scan_rtx_address (insn, locB, bclass, action, mode, as);
+ }
return;
}
@@ -1366,10 +1386,13 @@ scan_rtx_address (rtx_insn *insn, rtx *loc, enum reg_class cl,
break;
case MEM:
- scan_rtx_address (insn, &XEXP (x, 0),
- base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x),
- MEM, SCRATCH),
- action, GET_MODE (x), MEM_ADDR_SPACE (x));
+ {
+ reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
+ MEM_ADDR_SPACE (x),
+ MEM, SCRATCH);
+ scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
+ MEM_ADDR_SPACE (x));
+ }
return;
case REG:
@@ -1416,10 +1439,14 @@ scan_rtx (rtx_insn *insn, rtx *loc, enum reg_class cl, enum scan_actions action,
return;
case MEM:
- scan_rtx_address (insn, &XEXP (x, 0),
- base_reg_class (GET_MODE (x), MEM_ADDR_SPACE (x),
- MEM, SCRATCH),
- action, GET_MODE (x), MEM_ADDR_SPACE (x));
+ {
+ reg_class bclass = base_reg_class_for_rename (insn, GET_MODE (x),
+ MEM_ADDR_SPACE (x),
+ MEM, SCRATCH);
+
+ scan_rtx_address (insn, &XEXP (x, 0), bclass, action, GET_MODE (x),
+ MEM_ADDR_SPACE (x));
+ }
return;
case SET:
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 5c8e020bb5b..41a6af25c79 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -2709,9 +2709,12 @@ sched_analyze_2 (struct deps_desc *deps, rtx x, rtx_insn *insn)
return;
}
- /* Force pending stores to memory in case a trap handler needs them. */
+ /* Force pending stores to memory in case a trap handler needs them.
+ Also force pending loads from memory; loads and stores can segfault
+ and the signal handler won't be triggered if the trap insn was moved
+ above load or store insn. */
case TRAP_IF:
- flush_pending_lists (deps, insn, true, false);
+ flush_pending_lists (deps, insn, true, true);
break;
case PREFETCH:
diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c
index fe795196709..b85b1c3b349 100644
--- a/gcc/shrink-wrap.c
+++ b/gcc/shrink-wrap.c
@@ -529,30 +529,49 @@ can_dup_for_shrink_wrapping (basic_block bb, basic_block pro, unsigned max_size)
return true;
}
-/* If the source of edge E has more than one successor, the verifier for
- branch probabilities gets confused by the fake edges we make where
- simple_return statements will be inserted later (because those are not
- marked as fallthrough edges). Fix this by creating an extra block just
- for that fallthrough. */
+/* Do whatever needs to be done for exits that run without prologue.
+ Sibcalls need nothing done. Normal exits get a simple_return inserted. */
-static edge
-fix_fake_fallthrough_edge (edge e)
+static void
+handle_simple_exit (edge e)
{
- if (EDGE_COUNT (e->src->succs) <= 1)
- return e;
- basic_block old_bb = e->src;
- rtx_insn *end = BB_END (old_bb);
- rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end);
- basic_block new_bb = create_basic_block (note, note, old_bb);
- BB_COPY_PARTITION (new_bb, old_bb);
- BB_END (old_bb) = end;
+ if (e->flags & EDGE_SIBCALL)
+ {
+ /* Tell function.c to take no further action on this edge. */
+ e->flags |= EDGE_IGNORE;
- redirect_edge_succ (e, new_bb);
- e->flags |= EDGE_FALLTHRU;
- e->flags &= ~EDGE_FAKE;
+ e->flags &= ~EDGE_FALLTHRU;
+ emit_barrier_after_bb (e->src);
+ return;
+ }
- return make_edge (new_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), EDGE_FAKE);
+ /* If the basic block the edge comes from has multiple successors,
+ split the edge. */
+ if (EDGE_COUNT (e->src->succs) > 1)
+ {
+ basic_block old_bb = e->src;
+ rtx_insn *end = BB_END (old_bb);
+ rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end);
+ basic_block new_bb = create_basic_block (note, note, old_bb);
+ BB_COPY_PARTITION (new_bb, old_bb);
+ BB_END (old_bb) = end;
+
+ redirect_edge_succ (e, new_bb);
+ e->flags |= EDGE_FALLTHRU;
+
+ e = make_edge (new_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+ }
+
+ e->flags &= ~EDGE_FALLTHRU;
+ rtx_jump_insn *ret = emit_jump_insn_after (targetm.gen_simple_return (),
+ BB_END (e->src));
+ JUMP_LABEL (ret) = simple_return_rtx;
+ emit_barrier_after_bb (e->src);
+
+ if (dump_file)
+ fprintf (dump_file, "Made simple_return with UID %d in bb %d\n",
+ INSN_UID (ret), e->src->index);
}
/* Try to perform a kind of shrink-wrapping, making sure the
@@ -610,13 +629,10 @@ fix_fake_fallthrough_edge (edge e)
(bb 4 is duplicated to 5; the prologue is inserted on the edge 5->3).
ENTRY_EDGE is the edge where the prologue will be placed, possibly
- changed by this function. BB_WITH is a bitmap that, if we do shrink-
- wrap, will on return contain the interesting blocks that run with
- prologue. PROLOGUE_SEQ is the prologue we will insert. */
+ changed by this function. PROLOGUE_SEQ is the prologue we will insert. */
void
-try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
- rtx_insn *prologue_seq)
+try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq)
{
/* If we cannot shrink-wrap, are told not to shrink-wrap, or it makes
no sense to shrink-wrap: then do not shrink-wrap! */
@@ -739,6 +755,7 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
reachable from PRO that we already found, and in VEC a stack of
those we still need to consider (to find successors). */
+ bitmap bb_with = BITMAP_ALLOC (NULL);
bitmap_set_bit (bb_with, pro->index);
vec<basic_block> vec;
@@ -851,6 +868,7 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
if (pro == entry)
{
+ BITMAP_FREE (bb_with);
free_dominance_info (CDI_DOMINATORS);
return;
}
@@ -946,22 +964,13 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
redirect_edge_and_branch_force (e, (basic_block) e->dest->aux);
}
- /* Change all the exits that should get a simple_return to FAKE.
- They will be converted later. */
+ /* Make a simple_return for those exits that run without prologue. */
- FOR_EACH_BB_FN (bb, cfun)
+ FOR_EACH_BB_REVERSE_FN (bb, cfun)
if (!bitmap_bit_p (bb_with, bb->index))
FOR_EACH_EDGE (e, ei, bb->succs)
if (e->dest == EXIT_BLOCK_PTR_FOR_FN (cfun))
- {
- e = fix_fake_fallthrough_edge (e);
-
- e->flags &= ~EDGE_FALLTHRU;
- if (!(e->flags & EDGE_SIBCALL))
- e->flags |= EDGE_FAKE;
-
- emit_barrier_after_bb (e->src);
- }
+ handle_simple_exit (e);
/* Finally, we want a single edge to put the prologue on. Make a new
block before the PRO block; the edge beteen them is the edge we want.
@@ -994,158 +1003,6 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
*entry_edge = make_single_succ_edge (new_bb, pro, EDGE_FALLTHRU);
force_nonfallthru (*entry_edge);
+ BITMAP_FREE (bb_with);
free_dominance_info (CDI_DOMINATORS);
}
-
-/* If we're allowed to generate a simple return instruction, then by
- definition we don't need a full epilogue. If the last basic
- block before the exit block does not contain active instructions,
- examine its predecessors and try to emit (conditional) return
- instructions. */
-
-edge
-get_unconverted_simple_return (edge exit_fallthru_edge, bitmap_head bb_flags,
- vec<edge> *unconverted_simple_returns,
- rtx_insn **returnjump)
-{
- if (optimize)
- {
- unsigned i, last;
-
- /* convert_jumps_to_returns may add to preds of the exit block
- (but won't remove). Stop at end of current preds. */
- last = EDGE_COUNT (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds);
- for (i = 0; i < last; i++)
- {
- edge e = EDGE_I (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds, i);
- if (LABEL_P (BB_HEAD (e->src))
- && !bitmap_bit_p (&bb_flags, e->src->index)
- && !active_insn_between (BB_HEAD (e->src), BB_END (e->src)))
- *unconverted_simple_returns
- = convert_jumps_to_returns (e->src, true,
- *unconverted_simple_returns);
- }
- }
-
- if (exit_fallthru_edge != NULL
- && EDGE_COUNT (exit_fallthru_edge->src->preds) != 0
- && !bitmap_bit_p (&bb_flags, exit_fallthru_edge->src->index))
- {
- basic_block last_bb;
-
- last_bb = emit_return_for_exit (exit_fallthru_edge, true);
- *returnjump = BB_END (last_bb);
- exit_fallthru_edge = NULL;
- }
- return exit_fallthru_edge;
-}
-
-/* If there were branches to an empty LAST_BB which we tried to
- convert to conditional simple_returns, but couldn't for some
- reason, create a block to hold a simple_return insn and redirect
- those remaining edges. */
-
-void
-convert_to_simple_return (edge entry_edge, edge orig_entry_edge,
- bitmap_head bb_flags, rtx_insn *returnjump,
- vec<edge> unconverted_simple_returns)
-{
- edge e;
- edge_iterator ei;
-
- if (!unconverted_simple_returns.is_empty ())
- {
- basic_block simple_return_block_hot = NULL;
- basic_block simple_return_block_cold = NULL;
- edge pending_edge_hot = NULL;
- edge pending_edge_cold = NULL;
- basic_block exit_pred;
- int i;
-
- gcc_assert (entry_edge != orig_entry_edge);
-
- /* See if we can reuse the last insn that was emitted for the
- epilogue. */
- if (returnjump != NULL_RTX
- && JUMP_LABEL (returnjump) == simple_return_rtx)
- {
- e = split_block (BLOCK_FOR_INSN (returnjump), PREV_INSN (returnjump));
- if (BB_PARTITION (e->src) == BB_HOT_PARTITION)
- simple_return_block_hot = e->dest;
- else
- simple_return_block_cold = e->dest;
- }
-
- /* Also check returns we might need to add to tail blocks. */
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
- if (EDGE_COUNT (e->src->preds) != 0
- && (e->flags & EDGE_FAKE) != 0
- && !bitmap_bit_p (&bb_flags, e->src->index))
- {
- if (BB_PARTITION (e->src) == BB_HOT_PARTITION)
- pending_edge_hot = e;
- else
- pending_edge_cold = e;
- }
-
- /* Save a pointer to the exit's predecessor BB for use in
- inserting new BBs at the end of the function. Do this
- after the call to split_block above which may split
- the original exit pred. */
- exit_pred = EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb;
-
- FOR_EACH_VEC_ELT (unconverted_simple_returns, i, e)
- {
- basic_block *pdest_bb;
- edge pending;
-
- if (BB_PARTITION (e->src) == BB_HOT_PARTITION)
- {
- pdest_bb = &simple_return_block_hot;
- pending = pending_edge_hot;
- }
- else
- {
- pdest_bb = &simple_return_block_cold;
- pending = pending_edge_cold;
- }
-
- if (*pdest_bb == NULL && pending != NULL)
- {
- emit_return_into_block (true, pending->src);
- pending->flags &= ~(EDGE_FALLTHRU | EDGE_FAKE);
- *pdest_bb = pending->src;
- }
- else if (*pdest_bb == NULL)
- {
- basic_block bb;
-
- bb = create_basic_block (NULL, NULL, exit_pred);
- BB_COPY_PARTITION (bb, e->src);
- rtx_insn *ret = targetm.gen_simple_return ();
- rtx_jump_insn *start = emit_jump_insn_after (ret, BB_END (bb));
- JUMP_LABEL (start) = simple_return_rtx;
- emit_barrier_after (start);
-
- *pdest_bb = bb;
- make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
- }
- redirect_edge_and_branch_force (e, *pdest_bb);
- }
- unconverted_simple_returns.release ();
- }
-
- if (entry_edge != orig_entry_edge)
- {
- FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
- if (EDGE_COUNT (e->src->preds) != 0
- && (e->flags & EDGE_FAKE) != 0
- && !bitmap_bit_p (&bb_flags, e->src->index))
- {
- e = fix_fake_fallthrough_edge (e);
-
- emit_return_into_block (true, e->src);
- e->flags &= ~(EDGE_FALLTHRU | EDGE_FAKE);
- }
- }
-}
diff --git a/gcc/shrink-wrap.h b/gcc/shrink-wrap.h
index 6e7a4f74864..e06ab37952f 100644
--- a/gcc/shrink-wrap.h
+++ b/gcc/shrink-wrap.h
@@ -24,14 +24,7 @@ along with GCC; see the file COPYING3. If not see
/* In shrink-wrap.c. */
extern bool requires_stack_frame_p (rtx_insn *, HARD_REG_SET, HARD_REG_SET);
-extern void try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_flags,
- rtx_insn *prologue_seq);
-extern edge get_unconverted_simple_return (edge, bitmap_head,
- vec<edge> *, rtx_insn **);
-extern void convert_to_simple_return (edge entry_edge, edge orig_entry_edge,
- bitmap_head bb_flags,
- rtx_insn *returnjump,
- vec<edge> unconverted_simple_returns);
+extern void try_shrink_wrapping (edge *entry_edge, rtx_insn *prologue_seq);
#define SHRINK_WRAPPING_ENABLED \
(flag_shrink_wrap && targetm.have_simple_return ())
diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c
index 02b8c64e456..bf8a978c062 100644
--- a/gcc/stor-layout.c
+++ b/gcc/stor-layout.c
@@ -2146,11 +2146,13 @@ layout_type (tree type)
case COMPLEX_TYPE:
TYPE_UNSIGNED (type) = TYPE_UNSIGNED (TREE_TYPE (type));
- SET_TYPE_MODE (type,
- mode_for_size (2 * TYPE_PRECISION (TREE_TYPE (type)),
- (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE
- ? MODE_COMPLEX_FLOAT : MODE_COMPLEX_INT),
- 0));
+
+ /* build_complex_type and fortran's gfc_build_complex_type have set the
+ expected mode to allow having multiple complex types for multiple
+ floating point types that have the same size such as the PowerPC with
+ __ibm128 and __float128. */
+ gcc_assert (TYPE_MODE (type) != VOIDmode);
+
TYPE_SIZE (type) = bitsize_int (GET_MODE_BITSIZE (TYPE_MODE (type)));
TYPE_SIZE_UNIT (type) = size_int (GET_MODE_SIZE (TYPE_MODE (type)));
break;
diff --git a/gcc/system.h b/gcc/system.h
index 984f302fbc9..78a7da63d8e 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -987,7 +987,9 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
TARGET_HANDLE_PRAGMA_EXTERN_PREFIX \
TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_EVEN \
TARGET_VECTORIZE_BUILTIN_MUL_WIDEN_ODD \
- TARGET_MD_ASM_CLOBBERS TARGET_RELAXED_ORDERING EXTENDED_SDB_BASIC_TYPES
+ TARGET_MD_ASM_CLOBBERS TARGET_RELAXED_ORDERING \
+ EXTENDED_SDB_BASIC_TYPES TARGET_INVALID_PARAMETER_TYPE \
+ TARGET_INVALID_RETURN_TYPE
/* Arrays that were deleted in favor of a functional interface. */
#pragma GCC poison built_in_decls implicit_built_in_decls
diff --git a/gcc/target.def b/gcc/target.def
index 20f2b32da1e..6392e73b197 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -4820,28 +4820,6 @@ the front end.",
const char *, (int op, const_tree type1, const_tree type2),
hook_constcharptr_int_const_tree_const_tree_null)
-/* Return the diagnostic message string if TYPE is not valid as a
- function parameter type, NULL otherwise. */
-DEFHOOK
-(invalid_parameter_type,
- "If defined, this macro returns the diagnostic message when it is\n\
-invalid for functions to include parameters of type @var{type},\n\
-or @code{NULL} if validity should be determined by\n\
-the front end. This is currently used only by the C and C++ front ends.",
- const char *, (const_tree type),
- hook_constcharptr_const_tree_null)
-
-/* Return the diagnostic message string if TYPE is not valid as a
- function return type, NULL otherwise. */
-DEFHOOK
-(invalid_return_type,
- "If defined, this macro returns the diagnostic message when it is\n\
-invalid for functions to have return type @var{type},\n\
-or @code{NULL} if validity should be determined by\n\
-the front end. This is currently used only by the C and C++ front ends.",
- const char *, (const_tree type),
- hook_constcharptr_const_tree_null)
-
/* If values of TYPE are promoted to some other type when used in
expressions (analogous to the integer promotions), return that type,
or NULL_TREE otherwise. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 27a5972024e..b0ba70f85c7 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,1033 @@
+2016-05-23 Venkataramanan Kumar <venkataramanan.kumar@amd.com>
+
+ * gcc.dg/vect/bb-slp-19.c: Remove XFAIL.
+ * gcc.dg/vect/pr58135.c: Add new.
+ * gfortran.dg/pr46519-1.f: Adjust test case.
+
+2016-05-23 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53401
+ * g++.dg/cpp0x/decltype64.C: New.
+
+2016-05-23 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c: Add fp16 tests.
+ * gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c: Likewise.
+ * gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c: Likewise.
+
+2016-05-23 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h (result):
+ Add poly64x1_t and poly64x2_t cases if supported.
+ * gcc.target/aarch64/advsimd-intrinsics/compute-ref-data.h
+ (buffer, buffer_pad, buffer_dup, buffer_dup_pad): Likewise.
+ * gcc.target/aarch64/advsimd-intrinsics/p64_p128.c: New file.
+ * gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c: New file.
+ * gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c: New file.
+
+2016-05-23 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vrnd.c: New.
+ * gcc.target/aarch64/advsimd-intrinsics/vrndX.inc: New.
+ * gcc.target/aarch64/advsimd-intrinsics/vrnda.c: New.
+ * gcc.target/aarch64/advsimd-intrinsics/vrndm.c: New.
+ * gcc.target/aarch64/advsimd-intrinsics/vrndn.c: New.
+ * gcc.target/aarch64/advsimd-intrinsics/vrndp.c: New.
+ * gcc.target/aarch64/advsimd-intrinsics/vrndx.c: New.
+
+2016-05-23 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c: Add fp16 tests.
+
+2016-05-23 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vtst.c: Add tests for
+ vtst_p8, vtstq_p8, vtst_p16 and vtstq_p16.
+
+2016-05-22 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.target/i386/avx512bw-kunpckdq-1.c (avx512bw_test): Use "m"
+ constraint instead of "r".
+ * gcc.target/i386/avx512f-additional-reg-names.c (foo): Use vpxord
+ insn instead of vxorpd.
+ * gcc.target/i386/strinline.c: Add dg-require-effective-target ia32.
+
+ * gcc.target/i386/avx512dq-vinsert-1.c: New test.
+ * gcc.target/i386/avx512vl-vinsert-1.c: New test.
+
+ * gcc.target/i386/avx512vl-vinserti32x4-3.c: New test.
+
+ * gcc.target/i386/avx512dq-vbroadcast-2.c: New test.
+ * gcc.target/i386/avx512vl-vbroadcast-2.c: New test.
+
+ * gcc.target/i386/avx512vl-vbroadcast-1.c: New test.
+
+2016-05-22 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR middle-end/40921
+ * gcc.dg/tree-ssa/pr40921.c: New test.
+
+2016-05-20 Pitchumani Sivanupandi <pitchumani.s@atmel.com>
+
+ PR target/71103
+ * gcc.target/avr/pr71103.c: New test.
+
+2016-05-21 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR middle-end/71179
+ * gcc.dg/tree-ssa/pr71179.c: New test.
+
+2016-05-20 Martin Sebor <msebor@redhat.com>
+
+ PR c/71115
+ * gcc.dg/init-excess-2.c: New test.
+
+2016-05-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/opt53.adb: New test.
+ * gnat.dg/opt54.adb: Likewise.
+
+2016-05-20 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/70884
+ * gcc.dg/tree-ssa/pr70919.c: New test.
+
+2016-05-20 Bill Seurer <seurer@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/vec-adde.c: Change dejagnu options, fix code
+ formatting.
+ * gcc.target/powerpc/vec-adde-int128.c: Change dejagnu options, fix code
+ formatting.
+
+2016-05-20 David Malcolm <dmalcolm@redhat.com>
+
+ * jit.dg/all-non-failing-tests.h: Add
+ test-factorial-must-tail-call.c.
+ * jit.dg/test-error-impossible-must-tail-call.c: New test case.
+ * jit.dg/test-factorial-must-tail-call.c: New test case.
+
+2016-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/71204
+ * gfortran.dg/pr71204.f90: New test.
+
+2016-05-20 Cesar Philippidis <cesar@codesourcery.com>
+
+ * gcc.target/nvptx/sincos.c: New test.
+
+2016-05-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/70572
+ * g++.dg/cpp1y/auto-fn31.C: New.
+
+2016-05-20 Bill Seurer <seurer@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/vec-addec.c: New test.
+ * gcc.target/powerpc/vec-addec-int128.c: New test.
+
+2016-05-20 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/must-tail-call-1.c: New test case.
+ * gcc.dg/plugin/must-tail-call-2.c: New test case.
+ * gcc.dg/plugin/must_tail_call_plugin.c: New file.
+ * gcc.dg/plugin/plugin.exp (plugin_test_list): Add the above.
+
+2016-05-20 Jan Hubicka <hubicka@ucw.cz>
+
+ * gcc.dg/tree-ssa/prefetch-5.c: xfail.
+
+2016-05-20 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/71210
+ * g++.dg/opt/pr71210-1.C: New test.
+ * g++.dg/opt/pr71210-2.C: New test.
+
+ PR tree-optimization/29756
+ gcc.dg/tree-ssa/vector-6.c: Add -Wno-psabi -w to dg-options.
+ Add -msse2 for x86 and -maltivec for powerpc. Use scan-tree-dump-times
+ only on selected targets where V4SImode vectors are known to be
+ supported.
+
+2016-05-20 Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/71079
+ PR tree-optimization/71206
+ * gcc.dg/tree-ssa/pr71206.c: New testcase.
+
+2016-05-20 Prathamesh Kulkarni <prathamesh.kulkarni@linaro.org>
+
+ * gcc.dg/vect/section-anchors-vect-70.c: New test-case.
+ * gcc.dg/vect/section-anchors-vect-71.c: Likewise.
+ * gcc.dg/vect/section-anchors-vect-72.c: Likewise.
+
+2016-05-20 Richard Guenther <rguenther@suse.de>
+
+ PR tree-optimization/29756
+ * gcc.dg/tree-ssa/vector-6.c: New testcase.
+
+2016-05-20 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71185
+ * gcc.dg/tree-ssa/pr71185.c: New testcase.
+
+2016-05-20 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/ifc-cd.c: Adjust.
+
+2016-05-19 Marek Polacek <polacek@redhat.com>
+
+ PR c++/71075
+ * g++.dg/diagnostic/pr71075.C: New test.
+
+2016-05-19 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/71184
+ * g++.dg/pr71184.C: New test case.
+
+2016-05-19 Kelvin Nilsen <kelvin@gcc.gnu.org>
+
+ * gcc.target/powerpc/darn-0.c: New test.
+ * gcc.target/powerpc/darn-1.c: New test.
+ * gcc.target/powerpc/darn-2.c: New test.
+
+2016-05-19 Marek Polacek <polacek@redhat.com>
+
+ PR tree-optimization/71031
+ * gcc.dg/tree-ssa/vrp100.c: New test.
+
+2016-05-19 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR rtl-optimization/71148
+ * gcc.dg/pr71148.c: New test.
+
+2016-05-19 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/71056
+ * gcc.target/arm/pr71056.c: New test.
+
+2016-05-19 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * c-c++-common/pr69669.c: Check the used mode.
+
+2016-05-19 Maxim Ostapenko <m.ostapenko@samsung.com>
+
+ PR sanitizer/64354
+ * c-c++-common/tsan/sanitize-thread-macro.c: New test.
+
+2016-05-19 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70729
+ * gcc.dg/autopar/outer-6.c: Adjust to avoid redundant store.
+ * gcc.dg/graphite/scop-18.c: Likewise.
+ * gcc.dg/pr41783.c: Disable LIM.
+ * gcc.dg/tree-ssa/loadpre10.c: Likewise.
+ * gcc.dg/tree-ssa/loadpre23.c: Likewise.
+ * gcc.dg/tree-ssa/loadpre24.c: Likewise.
+ * gcc.dg/tree-ssa/loadpre25.c: Likewise.
+ * gcc.dg/tree-ssa/loadpre4.c: Likewise.
+ * gcc.dg/tree-ssa/loadpre8.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-pre-16.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-pre-18.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-pre-20.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-pre-3.c: Likewise.
+ * gfortran.dg/pr42108.f90: Likewise.
+
+2016-05-18 David Malcolm <dmalcolm@redhat.com>
+
+ PR driver/69265
+ * gcc.dg/spellcheck-options-11.c: New test case.
+
+2016-05-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/71100
+ * g++.dg/opt/pr71100.C: New test.
+
+2016-05-18 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/69708
+ * gcc.dg/ipa/iinline-cstagg-2.c: New test.
+ * gcc.dg/ipa/ipcp-cstagg-5.c: Likewise.
+ * gcc.dg/ipa/ipcp-cstagg-6.c: Likewise.
+ * gcc.dg/ipa/ipcp-cstagg-7.c: Likewise.
+
+2016-05-18 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/69708
+ * gcc.dg/ipa/iinline-cstagg-1.c: New test.
+ * gcc.dg/ipa/ipcp-cstagg-1.c: Likewise.
+ * gcc.dg/ipa/ipcp-cstagg-2.c: Likewise.
+ * gcc.dg/ipa/ipcp-cstagg-3.c: Likewise.
+ * gcc.dg/ipa/ipcp-cstagg-4.c: Likewise.
+
+2016-05-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/69793
+ * g++.dg/template/crash122.C: New.
+
+2016-05-18 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/70466
+ * g++.dg/template/pr70466-1.C: New.
+ * g++.dg/template/pr70466-2.C: Likewise.
+
+2016-05-18 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/p9-splat-1.c: New tests for ISA 3.0 word
+ splat operations and the XXSPLTIB instruction.
+ * gcc.target/powerpc/p9-splat-2.c: Likewise.
+ * gcc.target/powerpc/p9-splat-3.c: Likewise.
+ * gcc.target/powerpc/pr47755.c: Allow vspltisw in addition to
+ xxlxor to clear a register.
+
+2016-05-18 Richard Sandiford <richard.sandiford@arm.com>
+
+ * gcc.dg/torture/pr71020.c: New test.
+
+2016-05-18 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/70646
+ * gcc.dg/ipa/pr70646.c: New test.
+
+2016-05-18 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vget_lane.c: Add fp16 tests.
+
+2016-05-18 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c: Add
+ missing tests for vreinterpretq_p{8,16}.
+
+2016-05-18 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vsli_n.c: Add checks for
+ vsliq_n_s64 and vsliq_n_u64.
+
+2016-05-18 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h (CHECK,
+ CHECK_FP, CHECK_CUMULATIVE_SAT): Print which type was checked.
+
+2016-05-18 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vmul.c: Remove useless #ifdef.
+ * gcc.target/aarch64/advsimd-intrinsics/vshl.c: Likewise.
+ * gcc.target/aarch64/advsimd-intrinsics/vtst.c: Likewise.
+
+2016-05-18 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c: Fix typo
+ in comment.
+
+2016-05-18 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.target/aarch64/noplt_3.c: Scan for "br\t".
+ * gcc.target/aarch64/tail_indirect_call_1.c: Scan for "br\t",
+ "blr\t" and switch to scan-assembler-times.
+
+2016-05-18 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h: Guard float64_t
+ with __aarch64__.
+ * gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c: Guard variable
+ declarations under __aarch64__ and __ARM_FEATURE_FMA.
+
+2016-05-18 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.target/i386/avx512bw-vpbroadcast-1.c: New test.
+ * gcc.target/i386/avx512bw-vpbroadcast-2.c: New test.
+ * gcc.target/i386/avx512bw-vpbroadcast-3.c: New test.
+ * gcc.target/i386/avx512vl-vpbroadcast-1.c: New test.
+ * gcc.target/i386/avx512vl-vpbroadcast-2.c: New test.
+ * gcc.target/i386/avx512vl-vpbroadcast-3.c: New test.
+
+ * gcc.target/i386/avx512vl-vpalignr-3.c: New test.
+ * gcc.target/i386/avx512bw-vpalignr-3.c: New test.
+
+ * gcc.target/i386/avx512vl-vpshufb-3.c: New test.
+ * gcc.target/i386/avx512bw-vpshufb-3.c: New test.
+
+ * gcc.target/i386/avx512vl-vpmulhrsw-3.c: New test.
+ * gcc.target/i386/avx512bw-vpmulhrsw-3.c: New test.
+
+ * gcc.target/i386/avx512bw-vpmaddubsw-3.c: New test.
+
+2016-05-18 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71168
+ * gcc.dg/torture/pr71168.c: New testcase.
+
+2016-05-17 Kugan Vivekanandarajah <kuganv@linaro.org>
+
+ PR middle-end/63586
+ * gcc.dg/tree-ssa/pr63586-2.c: New test.
+ * gcc.dg/tree-ssa/pr63586.c: New test.
+ * gcc.dg/tree-ssa/reassoc-14.c: Adjust multiplication count.
+
+2016-05-17 Nathan Sidwell <nathan@acm.org>
+
+ * gcc.c-torture/execute/20030222-1.c: Skip on ptx.
+ * gcc.dg/pr68671.c: Fix ptx xfail-if.
+ * gcc.dg/torture/pr54261-1.c: Allocate atomic var statically.
+ * gcc.dg/torture/type-generic-1.c: Enable UNSAFE for ptx.
+
+2016-05-17 Nathan Sidwell <nathan@acm.org>
+
+ * gcc.target/nvptx/abi-vararg-3.c: New.
+
+2016-05-17 Mikhail Maltsev <maltsevm@gmail.com>
+
+ PR tree-optimization/54579
+ PR middle-end/55299
+ * gcc.dg/fold-notrotate-1.c: New test.
+ * gcc.dg/fold-notshift-1.c: New test.
+ * gcc.dg/fold-notshift-2.c: New test.
+
+2016-05-17 Marek Polacek <polacek@redhat.com>
+
+ PR ipa/71146
+ * g++.dg/ipa/pr71146.C: New test.
+
+2016-05-17 David Malcolm <dmalcolm@redhat.com>
+
+ * jit.dg/test-error-array-bounds.c: New test case.
+
+2016-05-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.dg/tree-ssa/and-1.c: New testcase.
+
+2016-05-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.dg/tree-ssa/pr69270.c: Adjust.
+ * gcc.dg/tree-ssa/andnot-1.c: New testcase.
+
+2016-05-17 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.dg/tree-ssa/pr69270.c: Adjust.
+ * gcc.dg/tree-ssa/vrp99.c: New testcase.
+
+2016-05-17 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/aarch64/simd/vmul_elem_1.c: Use intrinsics.
+
+2016-05-17 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/aarch64/simd/vmul_elem_1.c: New.
+
+2016-05-17 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/aarch64/fmla_intrinsic_1.c: Allow ".d[index]" besides
+ ".2d[index]" when scan the assembly.
+ * gcc.target/aarch64/fmls_intrinsic_1.c: Likewise.
+ * gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h: New entry for
+ float64x1.
+ * gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c: New.
+
+2016-05-17 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71132
+ * gcc.dg/torture/pr71132.c: New testcase.
+
+2016-05-17 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * g++.dg/inherit/think1.C: Fix dg-do and dg-skip order.
+
+2016-05-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/70809
+ * gcc.target/aarch64/pr70809_1.c: New test.
+
+2016-05-17 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/aarch64/cpu-diagnostics-1.c: Skip if -mcpu is overriden.
+ * gcc.target/aarch64/cpu-diagnostics-2.c: Likewise.
+ * gcc.target/aarch64/cpu-diagnostics-3.c: Likewise.
+ * gcc.target/aarch64/cpu-diagnostics-4.c: Likewise.
+
+2016-05-17 Dominique d'Humieres <dominiq@lps.ens.fr>
+ Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR target/71114
+ * gcc.target/i386/pr70799-1.c: Fix scan for Darwin.
+
+2016-05-16 Jan Hubicka <hubicka@ucw.cz>
+
+ * g++.dg/ipa/ivinline-7.C: Do not xfail.
+ * g++.dg/ipa/ivinline-9.C: Do not xfail.
+
+2016-05-16 Matthew Wahab <matthew.wahab@arm.com>
+
+ * g++.dg/ext/arm-fp16/fp16-param-1.c: Update expected output. Add
+ test for __ARM_FP16_ARGS.
+ * g++.dg/ext/arm-fp16/fp16-return-1.c: Update expected output.
+ * gcc.target/arm/aapcs/neon-vect10.c: New.
+ * gcc.target/arm/aapcs/neon-vect9.c: New.
+ * gcc.target/arm/aapcs/vfp18.c: New.
+ * gcc.target/arm/aapcs/vfp19.c: New.
+ * gcc.target/arm/aapcs/vfp20.c: New.
+ * gcc.target/arm/aapcs/vfp21.c: New.
+ * gcc.target/arm/fp16-aapcs-1.c: New.
+ * g++.target/arm/fp16-param-1.c: Update expected output. Add
+ test for __ARM_FP16_ARGS.
+ * g++.target/arm/fp16-return-1.c: Update expected output.
+
+2016-05-16 Jiong Wang <jiong.wang@arm.com>
+
+ PR testsuite/70227
+ * g++.dg/lto/pr69589_0.C: Skip arm and aarch64 bare-metal targets.
+
+2016-05-15 Harald Anlauf <anlauf@gmx.de>
+
+ PR fortran/69603
+ * gfortran.dg/pr69603.f90: New testcase.
+
+2016-05-14 Fritz Reese <fritzoreese@gmail.com>
+
+ * gfortran.dg/dec_union_4.f90: Fix endian issue.
+
+2016-05-14 Fritz Reese <fritzoreese@gmail.com>
+
+ PR fortran/71047
+ * gfortran.dg/pr71047.f08: New test.
+
+2016-05-13 Joseph Myers <joseph@codesourcery.com>
+
+ * gcc.dg/qual-return-5.c, gcc.dg/qual-return-6.c: New tests.
+ * gcc.dg/call-diag-2.c, gcc.dg/qual-return-2.c ,
+ gcc.dg/qual-return-3.c, gcc.dg/qual-return-4.c: Use -std=gnu99.
+
+2016-05-13 Martin Sebor <msebor@redhat.com>
+
+ PR c++/60049
+ * g++.dg/cpp0x/constexpr-60049.C: New test.
+
+2016-05-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/71071
+ * gcc.dg/pr71071.c: New test.
+
+2016-05-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/vect/tree-vect.h (check_vect): Handle AVX2,
+ remove XOP handling.
+ * gcc.dg/vect/pr66636.c (foo): Add __attribute__((noinline,noclone)).
+
+2016-05-13 Nathan Sidwell <nathan@acm.org>
+
+ * gcc.dg/atomic-noinline-aux.c: Include stddef.h. Fix
+ __atomic_is_lock_free declaration.
+
+2016-05-13 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/42587
+ * gcc.dg/optimize-bswapsi-4.c: New testcase.
+
+2016-05-13 Martin Liska <mliska@suse.cz>
+
+ * g++.dg/tree-ssa/ivopts-3.C: Change test-case to follow
+ the new format of dump output.
+
+2016-05-13 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ * gcc.dg/pr71084.c: New test.
+
+2016-05-13 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ PR target/53440
+ * g++.dg/inherit/thunk1.C: Support arm / aarch64.
+
+2016-05-13 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
+
+ * gcc.target/aarch64/struct_return.c: New test.
+
+2016-05-12 Marek Polacek <polacek@redhat.com>
+
+ PR c/70756
+ * c-c++-common/pr70756-2.c: New test.
+ * c-c++-common/pr70756.c: New test.
+
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71059
+ * gcc.dg/torture/pr71059.c: New testcase.
+
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71062
+ * gcc.dg/torture/pr71062.c: New testcase.
+
+2016-05-12 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR tree-optimization/71006
+ * gcc.dg/pr71006.c: New test.
+
+2016-05-12 Marek Polacek <polacek@redhat.com>
+
+ PR driver/71063
+ * gcc.dg/opts-7.c: New test.
+
+2016-05-12 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR target/70830
+ * gcc.target/arm/interrupt-1.c: Change dg-compile to dg-assemble.
+ Add -save-temps to dg-options.
+ Scan for ldmfd rather than pop instruction.
+ * gcc.target/arm/interrupt-2.c: Likewise.
+ * gcc.target/arm/pr70830.c: New test.
+
+2016-05-12 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.target/i386/avx512bw-vpextr-1.c: New test.
+ * gcc.target/i386/avx512dq-vpextr-1.c: New test.
+
+ * gcc.target/i386/avx512bw-vpinsr-1.c: New test.
+ * gcc.target/i386/avx512dq-vpinsr-1.c: New test.
+ * gcc.target/i386/avx512vl-vpinsr-1.c: New test.
+
+ PR target/71019
+ * gcc.target/i386/avx512vl-pack-1.c: New test.
+ * gcc.target/i386/avx512vl-pack-2.c: New test.
+ * gcc.target/i386/avx512bw-pack-2.c: New test.
+
+ * gcc.target/i386/avx512vl-vinsertps-1.c: New test.
+
+ * gcc.target/i386/avx512dq-abs-copysign-1.c: New test.
+ * gcc.target/i386/avx512vl-abs-copysign-1.c: New test.
+ * gcc.target/i386/avx512vl-abs-copysign-2.c: New test.
+
+2016-05-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70986
+ * gcc.dg/torture/pr70986-1.c: New testcase.
+ * gcc.dg/torture/pr70986-2.c: Likewise.
+ * gcc.dg/torture/pr70986-3.c: Likewise.
+
+2016-05-11 Mikhail Maltsev <maltsevm@gmail.com>
+
+ PR c/43651
+ * gcc.dg/Wduplicate-decl-specifier-c11.c: New test.
+ * gcc.dg/Wduplicate-decl-specifier.c: Likewise.
+
+2016-05-11 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/sse-13.c: Add dg-add-options bind_pic_locally
+ directive.
+ * gcc.target/i386/pr66746.c: Ditto.
+
+2016-05-11 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/dform-3.c: New test for ISA 3.0 vector d-form
+ support.
+ * gcc.target/powerpc/dform-1.c: Add -mlra option to silence
+ warning when using -mvsx-timode.
+ * gcc.target/powerpc/p8vector-int128-1.c: Likewise.
+ * gcc.target/powerpc/dform-2.c: Likewise.
+ * gcc.target/powerpc/pr68805.c: Likewise.
+
+2016-05-11 Marek Polacek <polacek@redhat.com>
+
+ PR c++/71024
+ * c-c++-common/attributes-3.c: New test.
+
+2016-05-11 Nathan Sidwell <nathan@acm.org>
+
+ * gcc.dg/pr68671.c: Xfail on PTX -- assembler crash.
+ * gcc.c-torture/execute/pr68185.c: Likewise.
+ * gcc.dg/ipa/pr70306.c: Requires global constructors.
+ * gcc.dg/pr69634.c: Requires scheduling.
+ * gcc.dg/torture/pr66178.c: Require label values.
+ * gcc.dg/setjmp-6.c: Require indirect jumps.
+
+2016-05-11 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71055
+ * gcc.dg/torture/pr71055.c: New testcase.
+
+2016-05-11 Richard Biener <rguenther@suse.de>
+
+ PR debug/71057
+ * g++.dg/debug/pr71057.C: New testcase.
+
+2016-05-11 Jakub Jelinek <jakub@redhat.com>
+
+ PR fortran/70855
+ * gfortran.dg/gomp/pr70855.f90: New test.
+
+2016-05-11 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/71002
+ * g++.dg/torture/pr71002.C: New testcase.
+
+2016-05-11 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR middle-end/70807
+ * gcc.dg/pr70807.c: New test.
+
+2016-05-10 Martin Sebor <msebor@redhat.com>
+
+ PR c++/38611
+ * g++.dg/Wattributes.C: New test.
+
+2016-05-10 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.dg/tree-ssa/bit-assoc.c: New testcase.
+ * gcc.dg/tree-ssa/pr69270.c: Adjust.
+ * gcc.dg/tree-ssa/vrp59.c: Disable forwprop.
+
+2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR target/70799
+ * gcc.target/i386/pr70799-1.c: New test.
+
+2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * gnat.dg/debug6.adb, gnat.dg/debug6_pkg.ads: New testcase.
+
+2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR middle-end/70877
+ * gcc.target/i386/pr70877.c: New test.
+
+2016-05-10 Ilya Enkovich <ilya.enkovich@intel.com>
+
+ PR tree-optimization/70786
+ * gcc.target/i386/pr70876.c: New test.
+
+2016-05-10 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/70927
+ * gcc.target/i386/avx512vl-logic-1.c: New test.
+ * gcc.target/i386/avx512vl-logic-2.c: New test.
+ * gcc.target/i386/avx512dq-logic-2.c: New test.
+
+2016-05-10 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR target/70963
+ * gcc.target/powerpc/pr70963.c: New.
+
+2016-05-10 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/diagnostic-test-show-locus-bw.c
+ (test_very_wide_line): Add ruler to expected output.
+ * gcc.dg/plugin/diagnostic-test-show-locus-color.c
+ (test_very_wide_line): Likewise.
+ * gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
+ (test_show_locus): Within the handling of "test_very_wide_line",
+ enable show_ruler_p on the diagnostic context.
+
+2016-05-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/71039
+ * gcc.dg/torture/pr71039.c: New testcase.
+
+2016-05-10 Nathan Sidwell <nathan@acm.org>
+
+ * gcc.dg/nested-func-10.c: Requires alloca.
+ * gcc.dg/nested-func-9.c: Requires alloca.
+ * gcc.c-torture/execute/pr70460.c: Requires labels.
+ * gcc.c-torture/compile/pr70199.c: Requires labels.
+ * gcc.target/nvptx/decl.c: Compile only.
+ * gcc.target/nvptx/trailing-init.c: Compile only.
+ * gcc.target/nvptx/ary-init.c: Compile only.
+
+2016-05-10 Marek Polacek <polacek@redhat.com>
+
+ PR c/70255
+ * gcc.dg/attr-opt-1.c: New test.
+
+2016-05-10 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70497
+ PR tree-optimization/28367
+ * gcc.dg/torture/20160404-1.c: New testcase.
+ * gcc.dg/tree-ssa/ssa-fre-54.c: Likewise.
+ * gcc.dg/tree-ssa/ssa-fre-55.c: Likewise.
+
+2016-05-10 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * gcc.dg/debug/dwarf2/nested_fun.c: New testcase.
+
+2016-05-09 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.target/i386/fabsneg-1.c New test.
+
+2016-05-09 Alan Modra <amodra@gmail.com>
+
+ PR testsuite/70826
+ * gcc.target/powerpc/savres.c: Compile with -fno-rename-registers.
+
+2016-05-09 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70985
+ * gcc.dg/torture/pr70985.c: New testcase.
+
+2016-05-09 Bin Cheng <bin.cheng@arm.com>
+
+ * gcc.dg/tree-ssa/ifc-9.c: New test.
+ * gcc.dg/tree-ssa/ifc-10.c: New test.
+ * gcc.dg/tree-ssa/ifc-11.c: New test.
+ * gcc.dg/tree-ssa/ifc-12.c: New test.
+ * gcc.dg/vect/pr61194.c: Remove XFAIL.
+ * gcc.dg/vect/vect-23.c: Remove XFAIL.
+ * gcc.dg/vect/vect-mask-store-move-1.c: Revise test check.
+
+2016-05-09 Richard Biener <rguenther@suse.de>
+
+ PR fortran/70937
+ * gfortran.dg/pr70937.f90: New testcase.
+
+2016-05-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/ipa/pure-const-3.c: Scan local-pure-const1 dump.
+
+2016-05-07 Fritz Reese <fritzoreese@gmail.com>
+
+ PR fortran/56226
+ * gfortran.dg/dec_structure_1.f90: New testcase.
+ * gfortran.dg/dec_structure_2.f90: Ditto.
+ * gfortran.dg/dec_structure_3.f90: Ditto.
+ * gfortran.dg/dec_structure_4.f90: Ditto.
+ * gfortran.dg/dec_structure_5.f90: Ditto.
+ * gfortran.dg/dec_structure_6.f90: Ditto.
+ * gfortran.dg/dec_structure_7.f90: Ditto.
+ * gfortran.dg/dec_structure_8.f90: Ditto.
+ * gfortran.dg/dec_structure_9.f90: Ditto.
+ * gfortran.dg/dec_structure_10.f90: Ditto.
+ * gfortran.dg/dec_structure_11.f90: Ditto.
+ * gfortran.dg/dec_union_1.f90: Ditto.
+ * gfortran.dg/dec_union_2.f90: Ditto.
+ * gfortran.dg/dec_union_3.f90: Ditto.
+ * gfortran.dg/dec_union_4.f90: Ditto.
+ * gfortran.dg/dec_union_5.f90: Ditto.
+ * gfortran.dg/dec_union_6.f90: Ditto.
+ * gfortran.dg/dec_union_7.f90: Ditto.
+
+2016-05-07 Tom de Vries <tom@codesourcery.com>
+
+ PR tree-optimization/70956
+ * gcc.dg/graphite/pr70956.c: New test.
+
+2016-05-06 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/70941
+ * gcc.dg/torture/pr70941.c (abort): Remove prototype.
+ (a, b, c, d): Change type from char to signed char.
+ (main): Compare against (signed char) -1634678893 instead of
+ hardcoded -109. Use __builtin_abort instead of abort.
+
+ * gcc.target/i386/avx512bw-vpsraw-3.c: New test.
+ * gcc.target/i386/avx512vl-vpsrad-3.c: New test.
+
+ * gcc.target/i386/avx512bw-vpmaddwd-3.c: New test.
+
+2016-05-06 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ PR debug/70935
+ * gcc.dg/torture/pr70935.c: New test.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/58219
+ * gcc.target/sh/pr58219.c: New tests.
+
+2016-05-06 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/70960
+ * gfortran.fortran-torture/compile/pr70960.f90: New testcase.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/52933
+ * gcc.target/sh/pr52933-1.c (test_31, test_32, test_33, test_34,
+ test_35, test_36, test_37, test_38, test_39, test_40): New sub-tests.
+ Adjust expected instruction counts.
+ * gcc.target/sh/pr52933-2.c: Adjust expected instruction counts.
+
+2016-05-06 Marek Polacek <polacek@redhat.com>
+
+ PR sanitizer/70875
+ * gcc.dg/ubsan/bounds-3.c: New test.
+
+2016-05-06 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR target/54089
+ * gcc.target/sh/pr54089-1.c (test_24): Add new sub-test.
+
+2016-05-06 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/70931
+ * gfortran.dg/pr70931.f90: New testcase.
+
+2016-05-06 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/70941
+ * gcc.dg/torture/pr70941.c: New testcase.
+
+2016-05-05 Bin Cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/57206
+ * gcc.dg/vect/pr57206.c: New test.
+
+2016-05-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * gcc.dg/ipa/inline-8.c (isnanf): Declare.
+
+2016-05-05 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.target/i386/avx512f-vfmadd-1.c: New test.
+
+ * c-c++-common/Wdangling-else-4.c: New test.
+
+2016-05-04 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/70906
+ PR c++/70933
+ * g++.dg/opt/pr70906.C: New test.
+ * g++.dg/opt/pr70933.C: New test.
+
+ * gcc.target/i386/avx512vl-vmovq-1.c: New test.
+
+2016-05-04 Jan Hubicka <hubicka@ucw.cz>
+
+ * gcc.dg/ipa/pure-const-3.c: New testcase.
+
+2016-05-04 Marek Polacek <polacek@redhat.com>
+
+ * c-c++-common/Wdangling-else-1.c: New test.
+ * c-c++-common/Wdangling-else-2.c: New test.
+ * c-c++-common/Wdangling-else-3.c: New test.
+
+2016-05-04 Kwok Cheung Yeung <kcy@codesourcery.com>
+
+ * gcc.target/mips/mips16-attributes.c: Skip if -mmicromips
+ flag is present.
+
+2016-05-04 Marek Polacek <polacek@redhat.com>
+
+ PR c/48778
+ * gcc.dg/Waddress-2.c: New test.
+
+2016-05-04 Alan Modra <amodra@gmail.com>
+
+ * gcc.target/powerpc/pr70866.c: New.
+
+2016-05-03 Martin Sebor <msebor@redhat.com>
+
+ PR c++/66561
+ * c-c++-common/builtin_location.c: New test.
+ * g++.dg/cpp1y/builtin_location.C: New test.
+
+2016-05-03 Marek Polacek <polacek@redhat.com>
+
+ PR c/70859
+ * gcc.dg/pr70859.c: New test.
+ * gcc.dg/pr70859-2.c: New test.
+
+2016-05-03 Pierre-Marie de Rodat <derodat@adacore.com>
+
+ * gnat.dg/debug5.adb: New testcase.
+
+2016-05-03 Dominik Vogt <vogt@linux.vnet.ibm.com>
+
+ * gcc.target/s390/md/rXsbg_mode_sXl.c: New test.
+ * gcc.target/s390/s390.exp (check_effective_target_z10_instructions):
+ Procedure to check for z10 instruction set.
+
+2016-05-03 Christophe Lyon <christophe.lyon@linaro.org>
+
+ * gcc.dg/ipa/inline-8.c: Require c99_runtime.
+
+2016-05-03 Alan Modra <amodra@gmail.com>
+
+ * gcc.target/powerpc/savres.c: Add func using a single gpr.
+
+2016-05-03 Jakub Jelinek <jakub@redhat.com>
+
+ * gcc.target/i386/avx512f-cvt-1.c: New test.
+
+2016-05-03 H.J. Lu <hongjiu.lu@intel.com>
+
+ * gcc.dg/tree-ssa/ssa-thread-14.c: Replace -fdump-tree-vrp with
+ -fdump-tree-vrp-details.
+
+2016-05-03 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/pr30172-1.c: Adjust.
+ * gcc.dg/pr63743.c: Likewise.
+ * gcc.dg/tm/pr51696.c: Likewise.
+ * c-c++-common/tm/safe-1.c: Likewise.
+ * gcc.dg/tree-prof/val-prof-3.c: Likewise.
+ * gcc.dg/plugin/self-assign-test-1.c: XFAIL case that needs CSE.
+ * g++.dg/plugin/self-assign-test-1.C: Likewise.
+ * g++.dg/plugin/self-assign-test-2.C: Likewise.
+
+2016-05-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/70467
+ * gcc.target/i386/pr70467-3.c: New test.
+ * gcc.target/i386/pr70467-4.c: New test.
+
+ PR tree-optimization/70916
+ * gcc.c-torture/compile/pr70916.c: New test.
+
+ PR target/49244
+ * gcc.target/i386/pr49244-1.c: New test.
+ * gcc.target/i386/pr49244-2.c: New test.
+
+2016-05-03 Bernd Schmidt <bschmidt@redhat.com>
+
+ PR rtl-optimization/44281
+ * gcc.target/i386/pr44281.c: New test.
+
+2016-05-03 bin cheng <bin.cheng@arm.com>
+
+ PR tree-optimization/56541
+ * gcc.dg/tree-ssa/ifc-pr56541.c: new test.
+ * gcc.dg/vect/pr56541.c: new test.
+
+2016-05-02 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/float128-complex-1.c: New tests for complex
+ __float128.
+ * gcc.target/powerpc/float128-complex-2.c: Likewise.
+
+2016-05-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR testsuite/70520
+ * c-c++-common/asan/clone-test-1.c (main): Align child process
+ stack to 16 bytes.
+
+2016-05-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/62314
+ * g++.dg/spellcheck-fields-2.C: New test case.
+
+2016-05-02 David Malcolm <dmalcolm@redhat.com>
+
+ PR c++/62314
+ * g++.dg/pr62314.C: New test case.
+
+2016-05-02 Jan Hubicka <hubicka@ucw.cz>
+
+ * gcc.dg/ipa/inline-8.c: New testcase.
+
+2016-05-02 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/70467
+ * gcc.target/i386/pr70467-1.c: New test.
+
+2016-05-02 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * gcc.dg/spec-options.c: Run the test on all targets.
+ * gcc.dg/foo.specs: Use cpp_unique_options.
+
+2016-05-02 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.dg/tree-ssa/unord.c: New testcase.
+
+2016-05-02 Marc Glisse <marc.glisse@inria.fr>
+
+ * gcc.dg/tree-ssa/20040305-1.c: Adjust.
+
2016-05-02 Nathan Sidwell <nathan@codesourcery.com>
* c-c++-common/goacc/loop-auto-1.c: Adjust expected warnings.
diff --git a/gcc/testsuite/c-c++-common/Wdangling-else-1.c b/gcc/testsuite/c-c++-common/Wdangling-else-1.c
new file mode 100644
index 00000000000..28a5a8f53fb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wdangling-else-1.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wdangling-else" } */
+
+void bar (int);
+void
+foo (int a, int b)
+{
+ if (a) /* { dg-warning "suggest explicit braces to avoid ambiguous" } */
+ if (b)
+ bar (1);
+ else
+ bar (2);
+}
diff --git a/gcc/testsuite/c-c++-common/Wdangling-else-2.c b/gcc/testsuite/c-c++-common/Wdangling-else-2.c
new file mode 100644
index 00000000000..87ea1ab5687
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wdangling-else-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wparentheses" } */
+
+void bar (int);
+void
+foo (int a, int b)
+{
+ if (a) /* { dg-warning "suggest explicit braces to avoid ambiguous" } */
+ if (b)
+ bar (1);
+ else
+ bar (2);
+}
diff --git a/gcc/testsuite/c-c++-common/Wdangling-else-3.c b/gcc/testsuite/c-c++-common/Wdangling-else-3.c
new file mode 100644
index 00000000000..0dae0d54ec8
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wdangling-else-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-Wparentheses -Wno-dangling-else" } */
+
+void bar (int);
+void
+foo (int a, int b)
+{
+ if (a) /* { dg-bogus "suggest explicit braces to avoid ambiguous" } */
+ if (b)
+ bar (1);
+ else
+ bar (2);
+}
diff --git a/gcc/testsuite/c-c++-common/Wdangling-else-4.c b/gcc/testsuite/c-c++-common/Wdangling-else-4.c
new file mode 100644
index 00000000000..12cc1405a40
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wdangling-else-4.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-Wdangling-else" } */
+
+void bar (int);
+
+void
+foo (int a, int b, int c)
+{
+ if (a) /* { dg-warning "suggest explicit braces to avoid ambiguous .else." } */
+ switch (b)
+ case 0:
+ if (c)
+ bar (1);
+ else
+ bar (2);
+}
+
+void
+baz (int a, int b, int c)
+{
+ if (a)
+ switch (b)
+ {
+ case 0:
+ if (c)
+ bar (1);
+ }
+ else
+ bar (2);
+}
+
diff --git a/gcc/testsuite/c-c++-common/asan/clone-test-1.c b/gcc/testsuite/c-c++-common/asan/clone-test-1.c
index fd187aaadd2..eeca09f3e68 100644
--- a/gcc/testsuite/c-c++-common/asan/clone-test-1.c
+++ b/gcc/testsuite/c-c++-common/asan/clone-test-1.c
@@ -25,7 +25,7 @@ volatile int zero = 0;
int main(int argc, char **argv) {
int i;
const int kStackSize = 1 << 20;
- char child_stack[kStackSize + 1];
+ char __attribute__((aligned(16))) child_stack[kStackSize + 1];
char *sp = child_stack + kStackSize; /* Stack grows down. */
printf("Parent: %p\n", sp);
pid_t clone_pid = clone(Child, sp, CLONE_FILES | CLONE_VM, NULL, 0, 0, 0);
diff --git a/gcc/testsuite/c-c++-common/attr-opt-1.c b/gcc/testsuite/c-c++-common/attr-opt-1.c
new file mode 100644
index 00000000000..fc9b4a691b5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attr-opt-1.c
@@ -0,0 +1,37 @@
+/* PR c/70255 */
+/* { dg-do compile } */
+
+double
+fn1 (double h, double l) /* { dg-message "previous definition" } */
+{
+ return h + l;
+}
+double fn1 (double, double) __attribute__ ((optimize ("no-associative-math"))); /* { dg-warning "optimization attribute" } */
+
+__attribute__ ((optimize ("no-associative-math"))) double
+fn2 (double h, double l)
+{
+ return h + l;
+}
+double fn2 (double, double) __attribute__ ((optimize ("no-associative-math")));
+
+__attribute__ ((optimize ("no-associative-math"))) double
+fn3 (double h, double l) /* { dg-message "previous definition" } */
+{
+ return h + l;
+}
+double fn3 (double, double) __attribute__ ((optimize ("O2,no-associative-math"))); /* { dg-warning "optimization attribute" } */
+
+__attribute__ ((optimize ("no-associative-math,O2"))) double
+fn4 (double h, double l) /* { dg-message "previous definition" } */
+{
+ return h + l;
+}
+double fn4 (double, double) __attribute__ ((optimize ("O2,no-associative-math"))); /* { dg-warning "optimization attribute" } */
+
+__attribute__ ((optimize ("no-reciprocal-math"), optimize ("no-associative-math"))) int
+fn5 (void)
+{
+ return 0;
+}
+int __attribute__ ((optimize ("no-associative-math"), optimize ("no-reciprocal-math"))) fn5 (void);
diff --git a/gcc/testsuite/c-c++-common/attributes-3.c b/gcc/testsuite/c-c++-common/attributes-3.c
new file mode 100644
index 00000000000..821278c680f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/attributes-3.c
@@ -0,0 +1,27 @@
+/* PR c++/71024 */
+/* { dg-do compile } */
+/* { dg-prune-output "declared but never defined" } */
+
+void
+fn0 (void) /* { dg-message "previous definition" } */
+{
+}
+extern void __attribute__((optimize ("O2"))) fn0 (void); /* { dg-warning "optimization attribute" } */
+
+extern __attribute__((noinline)) int fn1 (void); /* { dg-message "previous declaration" } */
+extern inline int fn1 (void); /* { dg-warning "inline declaration of" } */
+
+extern inline int fn2 (void); /* { dg-message "previous declaration" } */
+extern __attribute__((noinline)) int fn2 (void); /* { dg-warning "attribute noinline follows inline declaration" } */
+
+extern __attribute__((always_inline)) int fn3 (void); /* { dg-message "previous declaration" } */
+extern __attribute__((noinline)) int fn3 (void); /* { dg-warning "attribute .noinline. follows declaration with attribute .always_inline." } */
+
+extern __attribute__((noinline)) int fn4 (void); /* { dg-message "previous declaration" } */
+extern __attribute__((always_inline)) int fn4 (void); /* { dg-warning "attribute .always_inline. follows declaration with attribute .noinline." } */
+
+extern __attribute__((hot)) int fn5 (void); /* { dg-message "previous declaration" } */
+extern __attribute__((cold)) int fn5 (void); /* { dg-warning "attribute .cold. follows declaration with attribute .hot." } */
+
+extern __attribute__((cold)) int fn6 (void); /* { dg-message "previous declaration" } */
+extern __attribute__((hot)) int fn6 (void); /* { dg-warning "attribute .hot. follows declaration with attribute .cold." } */
diff --git a/gcc/testsuite/c-c++-common/builtin_location.c b/gcc/testsuite/c-c++-common/builtin_location.c
new file mode 100644
index 00000000000..f3bcd17d84d
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/builtin_location.c
@@ -0,0 +1,57 @@
+/* PR c++/66561 - __builtin_LINE at al. should yield constant expressions */
+/* { dg-do compile } */
+
+#if __cplusplus >= 201103L
+# define Assert(expr) static_assert ((expr), #expr)
+#elif __STDC_VERSION__ >= 201112L
+# define Assert(expr) _Static_assert ((expr), #expr)
+#else
+# define CONCAT(a, b) a ## b
+# define CAT(a, b) CONCAT (a, b)
+# define Assert(expr) typedef int CAT (Assert_, __LINE__) [1 - 2 * !(expr)]
+#endif
+
+/* Verify (in C) that __builtin_FILE() yields an address constant.
+ This test is ineffective in C++ where initializers of global
+ objects need not be constant expressions. */
+const char* const file = __builtin_FILE ();
+
+/* Verify (in C) that __builtin_FUNCTION() yields an address constant. */
+const char* const function = __builtin_FUNCTION ();
+
+/* Also verify that __builtin_constant_p() returns true for both. */
+Assert (__builtin_constant_p (__builtin_FILE ()));
+Assert (__builtin_constant_p (__builtin_FUNCTION ()));
+
+/* Verify (in both C and C++ 11 and later) that both __builtin_FILE ()
+ and __builtin_FUNCTION() yield an address constant by making use
+ of a GCC extension that allows operands of arithmetic constant
+ expressions to be address constants. (Subtracting two literals
+ from one another is undefined in both C and C++ and should be
+ diagnosed. See c/70772.) */
+
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Waddress"
+
+enum E0 {
+ e0 = __FILE__ - __FILE__,
+ e1 = __builtin_FILE () - __builtin_FILE (),
+
+#if !__cplusplus || __cplusplus >= 201103L
+ /* Skip this test in C++ 98 where GCC rejects __FUNCTION__ in constant
+ expressions. */
+ e2 = __FUNCTION__ - __FUNCTION__,
+ e3 = __builtin_FUNCTION () - __builtin_FUNCTION ()
+
+#endif
+};
+
+#pragma GCC diagnostic pop
+
+/* Verify that __builtin_LINE () yields an integer constant expression. */
+#line 13
+int a [__builtin_LINE ()][__builtin_LINE ()];
+enum F { f0 = __builtin_LINE () };
+struct S { unsigned bitfield: __builtin_LINE (); } s;
+
+Assert (__builtin_constant_p (__builtin_LINE ()));
diff --git a/gcc/testsuite/c-c++-common/pr69669.c b/gcc/testsuite/c-c++-common/pr69669.c
index 9940afe8ffb..ebeb4109ffa 100644
--- a/gcc/testsuite/c-c++-common/pr69669.c
+++ b/gcc/testsuite/c-c++-common/pr69669.c
@@ -1,5 +1,6 @@
/* PR c/69669 */
/* { dg-do compile } */
+/* { dg-options "-fdump-rtl-final" } */
enum __attribute__((mode(QI))) E { F = 1 };
@@ -8,3 +9,5 @@ foo (enum E *x, int y)
{
*x = (enum E) y;
}
+
+/* { dg-final { scan-rtl-dump-times "mem:QI" 1 "final" } } */
diff --git a/gcc/testsuite/c-c++-common/pr70756-2.c b/gcc/testsuite/c-c++-common/pr70756-2.c
new file mode 100644
index 00000000000..b7df3b79853
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr70756-2.c
@@ -0,0 +1,12 @@
+/* PR c/70756 */
+/* { dg-do compile } */
+/* { dg-options "-Wpointer-arith" } */
+
+extern void bar (void);
+
+void
+fn (void *p)
+{
+ void *a = p + 1; /* { dg-warning "15:pointer of type" } */
+ void (*a2)(void) = &bar + 1; /* { dg-warning "27:pointer to a function" } */
+}
diff --git a/gcc/testsuite/c-c++-common/pr70756.c b/gcc/testsuite/c-c++-common/pr70756.c
new file mode 100644
index 00000000000..37259229be9
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr70756.c
@@ -0,0 +1,23 @@
+/* PR c/70756 */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+enum E e; /* { dg-error "storage size|use of enum" } */
+int (*A)[];
+
+void
+fn0 (void)
+{
+ struct
+ {
+ int x;
+ int y[];
+ } s;
+ 1234 && &s.y + 1; /* { dg-error "16:invalid use of" } */
+}
+
+void
+fn1 (void)
+{
+ 1234, A += 1; /* { dg-error "11:invalid use of array with unspecified bounds" } */
+}
diff --git a/gcc/testsuite/c-c++-common/tm/safe-1.c b/gcc/testsuite/c-c++-common/tm/safe-1.c
index b2a43530575..4a81a78c396 100644
--- a/gcc/testsuite/c-c++-common/tm/safe-1.c
+++ b/gcc/testsuite/c-c++-common/tm/safe-1.c
@@ -35,9 +35,9 @@ foo(void)
/* tu(); */
(*ps)();
- (*pc)(); /* { dg-error "unsafe function call" } */
- (*pi)(); /* { dg-error "unsafe function call" } */
- (*pu)(); /* { dg-error "unsafe function call" } */
+ (*pc)(); /* { dg-error "unsafe indirect function call" } */
+ (*pi)(); /* { dg-error "unsafe indirect function call" } */
+ (*pu)(); /* { dg-error "unsafe indirect function call" } */
asm(""); /* { dg-error "asm not allowed" } */
asm("" : "=g"(i)); /* { dg-error "asm not allowed" } */
@@ -57,10 +57,10 @@ bar(void)
tm();
(*ps)();
- (*pc)(); /* { dg-error "unsafe function call" } */
- (*pi)(); /* { dg-error "unsafe function call" } */
+ (*pc)(); /* { dg-error "unsafe indirect function call" } */
+ (*pi)(); /* { dg-error "unsafe indirect function call" } */
(*pm)();
- (*pu)(); /* { dg-error "unsafe function call" } */
+ (*pu)(); /* { dg-error "unsafe indirect function call" } */
asm(""); /* { dg-error "asm not allowed" } */
asm("" : "=g"(i)); /* { dg-error "asm not allowed" } */
diff --git a/gcc/testsuite/c-c++-common/tsan/sanitize-thread-macro.c b/gcc/testsuite/c-c++-common/tsan/sanitize-thread-macro.c
new file mode 100644
index 00000000000..2b8a840687c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/tsan/sanitize-thread-macro.c
@@ -0,0 +1,12 @@
+/* Check that -fsanitize=thread options defines __SANITIZE_THREAD__ macros. */
+/* { dg-do compile } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+int
+main ()
+{
+#ifndef __SANITIZE_THREAD__
+ bad construction
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/Wattributes.C b/gcc/testsuite/g++.dg/Wattributes.C
new file mode 100644
index 00000000000..35fae035683
--- /dev/null
+++ b/gcc/testsuite/g++.dg/Wattributes.C
@@ -0,0 +1,20 @@
+// PR c++/38611
+// { dg-do compile }
+
+struct A { unsigned char a [272]; };
+
+typedef struct __attribute__ ((aligned (128))) A B; // { dg-warning "attributes ignored" }
+typedef struct __attribute__ ((__may_alias__)) A C; // { dg-warning "attributes ignored" }
+
+#ifndef __cplusplus
+# define alignof _Alignof
+# define static_assert _Static_assert
+#elif __cplusplus < 201103L
+# define alignof __alignof__
+# define static_assert(expr, ignore) typedef int Assert [(expr) ? 1 : -1]
+#endif
+
+#define SA(expr) static_assert ((expr), #expr)
+
+SA (alignof (struct A) == alignof (B));
+
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-60049.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-60049.C
new file mode 100644
index 00000000000..3a1ee811c63
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-60049.C
@@ -0,0 +1,24 @@
+// PR c++/60049 - Right and left shift undefined behavior not an error
+// in a constexpr
+// { dg-do compile { target c++11 } }
+// { dg-additional-options "-Wno-shift-negative-value -Wno-shift-count-negative -Wno-shift-count-overflow" }
+
+constexpr int f1 (int n) { return 1 << n; } // { dg-error "shift expression" }
+constexpr int f2 (int n) { return 1 << n; } // { dg-error "shift expression" }
+constexpr int f3 (int n) { return n << 1; } // { dg-error "shift expression" }
+constexpr int f4 (int n) { return 1 >> n; } // { dg-error "shift expression" }
+constexpr int f5 (int n) { return 1 >> n; } // { dg-error "shift expression" }
+
+constexpr int X = __CHAR_BIT__ * sizeof (int) + 1;
+
+constexpr int x1 = f1 (X);
+constexpr int x2 = f2 (-1);
+constexpr int x3 = f3 (-1);
+constexpr int x4 = f4 (X);
+constexpr int x5 = f5 (-1);
+
+constexpr int y1 = 1 << X; // { dg-error "shift expression" }
+constexpr int y2 = 1 << -1; // { dg-error "shift expression" }
+constexpr int y3 = -1 << 1; // { dg-error "shift expression" }
+constexpr int y4 = 1 >> X; // { dg-error "shift expression" }
+constexpr int y5 = 1 >> -1; // { dg-error "shift expression" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/decltype64.C b/gcc/testsuite/g++.dg/cpp0x/decltype64.C
new file mode 100644
index 00000000000..46d18594c94
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/decltype64.C
@@ -0,0 +1,32 @@
+// PR c++/53401
+// { dg-do compile { target c++11 } }
+
+template<int I>
+struct index
+{};
+
+constexpr int recursive_impl(index<0u>)
+{
+ return 0;
+}
+
+template<int N>
+constexpr auto recursive_impl(index<N>)
+ -> decltype(recursive_impl(index<N - 1>())) // { dg-error "depth" }
+{
+ return recursive_impl(index<N - 1>());
+}
+
+template<int N>
+constexpr auto recursive()
+ -> decltype(recursive_impl(index<N>()))
+{
+ return recursive_impl(index<N>());
+}
+
+void f(int i)
+{
+ recursive<1>(); // { dg-message "from here" }
+}
+
+// { dg-prune-output "compilation terminated" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C
new file mode 100644
index 00000000000..1e0dc54092d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/fntmpdefarg6.C
@@ -0,0 +1,7 @@
+// { dg-do compile { target c++11 } }
+
+template <class T>
+struct A {
+ template <int I = 42, int J = (T)42> int f() { return I; }
+ template <int I = 42> int g() { return f(); }
+};
diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn31.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn31.C
new file mode 100644
index 00000000000..c99c59571e9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn31.C
@@ -0,0 +1,7 @@
+// PR c++/70572
+// { dg-do compile { target c++14 } }
+
+void foo ()
+{
+ decltype (auto) a = foo; // { dg-error "initializer" }
+}
diff --git a/gcc/testsuite/g++.dg/cpp1y/builtin_location.C b/gcc/testsuite/g++.dg/cpp1y/builtin_location.C
new file mode 100644
index 00000000000..b3b9b435b2c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/builtin_location.C
@@ -0,0 +1,175 @@
+// PR c++/66561 - __builtin_LINE at al. should yield constant expressions
+// { dg-do compile { target c++11 } }
+#define A(expr) static_assert ((expr), #expr)
+
+#define FILE_1 "file_name.suffix"
+#define FILE_2 "some_other_file_name.suffix"
+
+#line 1 FILE_1
+constexpr const char*
+file1 ()
+{
+#if __cplusplus >= 201402L
+ // Do extra checking in C++ 14 and later.
+ constexpr const char *f1 = __FILE__;
+ constexpr const char *f2 = __builtin_FILE ();
+ A (0 == __builtin_strcmp (f1, f2));
+ return f1;
+#else
+ // In C++ 11, a constexpr function body must consist of a single
+ // return statement and no declaratations.
+ return __builtin_FILE ();
+#endif
+}
+
+#line 1 FILE_2
+constexpr const char*
+file2 ()
+{
+#if __cplusplus >= 201402L
+ constexpr const char *f1 = __FILE__;
+ constexpr const char *f2 = __builtin_FILE ();
+ A (0 == __builtin_strcmp (f1, f2));
+ return f1;
+#else
+ return __builtin_FILE ();
+#endif
+}
+
+#line 1 "bogus file name"
+constexpr const char*
+this_file (const char *fname = __builtin_FILE ())
+{
+ return fname;
+}
+
+constexpr const char*
+function ()
+{
+#if __cplusplus >= 201402L
+ constexpr const char *f1 = __FUNCTION__;
+ constexpr const char *f2 = __builtin_FUNCTION ();
+ A (0 == __builtin_strcmp (f1, f2));
+ return f1;
+#else
+ return __builtin_FUNCTION ();
+#endif
+}
+
+constexpr const char*
+this_function (const char *func = __builtin_FUNCTION ())
+{
+ return func;
+}
+
+constexpr int
+line ()
+{
+#if __cplusplus >= 201402L
+#line 123
+ constexpr int n1 = __LINE__;
+ constexpr int n2 = __builtin_LINE ();
+ A (123 == n1);
+ A (n1 + 1 == n2);
+ return n2;
+#else
+#line 123
+ // Newline.
+ return __builtin_LINE ();
+#endif
+}
+
+constexpr int
+this_line (int line = __builtin_LINE ())
+{
+ return line;
+}
+
+
+// Exercise __builtin_FILE().
+#line 1 "foobar"
+constexpr const char* f1 = file1 ();
+A (0 == __builtin_strcmp (f1, FILE_1));
+
+#line 2 "foobar"
+constexpr const char* f2 = file2 ();
+A (0 == __builtin_strcmp (f2, FILE_2));
+
+#define FILE_3 "this_file_name_right_here.this_suffix"
+#line 1 FILE_3
+constexpr const char* f3 = this_file ();
+A (0 == __builtin_strcmp (f3, FILE_3));
+
+#define FILE_4 "next_file_name.another_suffix"
+#line 1 "foobar"
+constexpr const char* f4 = this_file
+ (
+#line 1 FILE_4
+ )
+#line 1 "foobar"
+ ;
+A (0 == __builtin_strcmp (f4, FILE_4));
+
+
+// Exercise __builtin_FUNCTION().
+
+// Verify that __builtin_FUNCTION() returns the name of the function
+// in which it is called.
+constexpr const char* fun1 = function ();
+A (0 == __builtin_strcmp (fun1, "function"));
+
+// Verify that __builtin_FUNCTION() returns the empty string when
+// it's invoked to set the default argument value in a function
+// called at file scope.
+constexpr const char* fun2 = this_function ();
+A (0 == __builtin_strcmp (fun2, ""));
+
+constexpr const char*
+named_function ()
+{
+ return this_function ();
+}
+
+constexpr const char* fun3 = named_function ();
+A (0 == __builtin_strcmp (fun3, "named_function"));
+
+
+// Exercise __builtin_LINE().
+// Verify the line numbe returned by the built-in.
+#line 4
+constexpr int n1 = __builtin_LINE ();
+A (n1 == 4);
+
+// Verify the line number obtained by a constexpr function.
+#line 5
+constexpr int n2 = line ();
+A (n2 == 124);
+
+// Verify the line number determined by the default argument.
+#line 6
+constexpr int n3 = this_line ();
+A (n3 == 6);
+
+// Verify that the line number accounts for each of the calls.
+#line 7
+constexpr int n4 = this_line () + this_line ();
+A (n4 == 14);
+
+// Verify that the line number accounts for each of the calls when
+// split over multiple lines.
+#line 1
+constexpr int n5 = this_line ()
+#line 8
+ + this_line ();
+A (n5 == 9);
+
+// Verify that the line number corresponds to the closing parenthesis
+// of the function call.
+#line 1
+constexpr int n6 = this_line
+ (
+#line 99
+ )
+#line 1
+ ;
+A (n6 == 99);
diff --git a/gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C b/gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C
new file mode 100644
index 00000000000..a83d7f4e1de
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/constexpr-sfinae.C
@@ -0,0 +1,287 @@
+// Test exercising SFINAE depending on the well-definedness of constexpr
+// functions.
+// { dg-do compile { target c++14 } }
+
+#define Assert(e) static_assert ((e), #e)
+
+// Exercise SFINAE based on the absence of integer division by zero.
+namespace DivByZero {
+
+// Define a pair of functions that have undefined and well-defined
+// behavior, respectively, due to division by zero, depending on
+// their arguments.
+
+// The following function is undefined when I is zero, well defined
+// otherwise.
+constexpr bool div_zero_0 (int i, int j) { return 1 + j / (i == 0); }
+
+// The following function is undefined when I is non-zero, and well
+// defined otherwise.
+constexpr bool div_zero_1 (int i, int j) { return 1 + j / (i != 0); }
+
+// Define a pair of overfloads each of which is viable when the constexpr
+// function it invokes has well-defined semantics and not otherwise.
+template <int I>
+constexpr int f (int (*)[div_zero_0 (I, 0)] = 0) { return 0; }
+
+template <int I>
+constexpr int f (int (*)[div_zero_1 (I, 0)] = 0) { return 1; }
+
+// Verify that the correct overload is selected based on the template
+// argument and without triggering a compilation error for the undefined
+// behavior in the non-viable constexpr function above.
+Assert (f<0>() == 0);
+Assert (f<1>() == 1);
+
+}
+
+// Exercise SFINAE based on the absence of signed integer overflow
+// in addition.
+namespace IntAddOverflow {
+
+constexpr int a [] = { 1234, __INT_MAX__ / 2 };
+
+constexpr int vflow_0 (int i) { return a [!i] * 7; }
+constexpr int vflow_1 (int i) { return a [i] * 11; }
+
+template <int I>
+constexpr int f (int (*)[vflow_0 (I)] = 0) { return 1; }
+
+template <int I>
+constexpr int f (int (*)[vflow_1 (I)] = 0) { return 0; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 0);
+Assert (n1 == 1);
+
+}
+
+// Exercise SFINAE based on the absence of signed integer overflow
+// in multiplication.
+namespace IntMulOverflow {
+
+constexpr long a [] = { 1234, __LONG_MAX__ / 2 };
+
+constexpr long vflow_0 (int i) { return a [!i] * 3; }
+constexpr long vflow_1 (int i) { return a [i] * 7; }
+
+template <int I>
+constexpr int f (int (*)[vflow_0 (I)] = 0) { return 1; }
+
+template <int I>
+constexpr int f (int (*)[vflow_1 (I)] = 0) { return 0; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 0);
+Assert (n1 == 1);
+
+}
+
+// Exercise SFINAE based on the absence of undefined pointer arithmetic
+// involving null pointers. Subtracting one null pointer from another
+// is well-defined, but subtracting a null pointer from a non-null one
+// is not.
+namespace NullPointerArithmetic {
+
+constexpr int i = 0;
+constexpr const int* a[] = { 0, &i };
+
+// Well-defined core constant expressoons involving null pointers.
+constexpr __PTRDIFF_TYPE__ d00 = a [0] - a [0];
+constexpr __PTRDIFF_TYPE__ d11 = a [1] - a [1];
+
+// Undefined core constant expressoons involving null pointers.
+// constexpr __PTRDIFF_TYPE__ d01 = a [0] - a [1];
+// constexpr __PTRDIFF_TYPE__ d10 = a [1] - a [0];
+
+constexpr bool nullptr_sub_0 (int i, int j) { return 1 + a [i != 0] - a [j]; }
+
+constexpr bool nullptr_sub_1 (int i, int j) { return 1 + a [i == 0] - a [j]; }
+
+template <int I>
+constexpr int f (int (*)[nullptr_sub_0 (I, 0)] = 0) { return 0; }
+
+template <int I>
+constexpr int f (int (*)[nullptr_sub_1 (I, 0)] = 0) { return 1; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 0);
+Assert (n1 == 1);
+
+}
+
+// Exercise SFINAE based on the absence of undefined pointer arithmetic
+// involving null poiinters. Subtracting one null pointer from another
+// is well-defined, but subtracting a null pointer from a non-null one
+// is not.
+namespace NullPointerDereference {
+
+struct S { int a, b; };
+
+constexpr S s = { };
+constexpr const S* a[] = { 0, &s };
+
+constexpr bool nullptr_ref_0 (int i) { return &a [i != 0]->b == &s.b; }
+constexpr bool nullptr_ref_1 (int i) { return &a [i == 0]->b == &s.b; }
+
+template <int I>
+constexpr int f (int (*)[nullptr_ref_0 (I)] = 0) { return 1; }
+
+template <int I>
+constexpr int f (int (*)[nullptr_ref_1 (I)] = 0) { return 0; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 0);
+Assert (n1 == 1);
+
+}
+
+// Exercise SFINAE based on whether or not two constexpr function
+// calls have a circular depency on one another such that a call
+// to one would not terminate.
+namespace CircularDependency {
+
+constexpr bool call_me (int i, bool (*f)(int)) { return f (i); }
+
+constexpr bool undefined_if_0 (int i) {
+ return i ? 1 : call_me (i, undefined_if_0);
+}
+
+constexpr bool undefined_if_1 (int i) {
+ return i ? call_me (i, undefined_if_1) : 1;
+}
+
+template <int I>
+constexpr int f (int (*)[undefined_if_0 (I)] = 0) { return 0; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_1 (I)] = 0) { return 1; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 1);
+Assert (n1 == 0);
+
+}
+
+// Exercise SFINAE based on whether constexpr functions flow off
+// the end without returning a value.
+namespace FlowOffTheEnd {
+
+constexpr bool undefined_if_0 (int i) { switch (i) case 1: return 1; }
+constexpr bool undefined_if_1 (int i) { switch (i) case 0: return 1; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_0 (I)] = 0) { return 1; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_1 (I)] = 0) { return 0; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 0);
+Assert (n1 == 1);
+
+}
+
+// Exercise SFINAE based on the presence and absence of a left shift
+// expression with a negative second operand.
+namespace NegativeLeftShift {
+
+constexpr int a [] = { -1, 1 };
+
+constexpr int undefined_if_0 (int i) { return 1 << a [i]; }
+constexpr int undefined_if_1 (int i) { return 1 << a [!i]; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_0 (I)] = 0) { return 0; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_1 (I)] = 0) { return 1; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 1);
+Assert (n1 == 0);
+
+}
+
+// Exercise SFINAE based on the presence and absence of a right shift
+// expression with a negative second operand.
+namespace NegativeRightShift {
+
+constexpr int a [] = { -1, 1 };
+
+constexpr int undefined_if_0 (int i) { return 2 >> a [i]; }
+constexpr int undefined_if_1 (int i) { return 2 >> a [!i]; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_0 (I)] = 0) { return 0; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_1 (I)] = 0) { return 1; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 1);
+Assert (n1 == 0);
+
+}
+
+// Exercise SFINAE based on the absence of signed integer overflow
+// in a signed left shift expression.
+namespace LeftShiftOverflow {
+
+constexpr int a[] = { 1234, 1 };
+
+constexpr int undefined_if_0 (int i) { return 1 << a [i]; }
+constexpr int undefined_if_1 (int i) { return 1 << a [!i]; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_0 (I)] = 0) { return 0; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_1 (I)] = 0) { return 1; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 1);
+Assert (n1 == 0);
+
+}
+
+// Exercise SFINAE based on the absence of using a negative array
+// index.
+namespace NegativeArrayIndex {
+
+constexpr int a [] = { -1, 1 };
+
+constexpr int undefined_if_0 (int i) { return 2 + a [a [i]]; }
+constexpr int undefined_if_1 (int i) { return 2 + a [a [!i]]; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_0 (I)] = 0) { return 0; }
+
+template <int I>
+constexpr int f (int (*)[undefined_if_1 (I)] = 0) { return 1; }
+
+constexpr int n0 = f<0>();
+constexpr int n1 = f<1>();
+
+Assert (n0 == 1);
+Assert (n1 == 0);
+
+}
diff --git a/gcc/testsuite/g++.dg/debug/pr71057.C b/gcc/testsuite/g++.dg/debug/pr71057.C
new file mode 100644
index 00000000000..2ed1eed988e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/pr71057.C
@@ -0,0 +1,12 @@
+// { dg-do compile }
+// { dg-options "-g" }
+template <typename _Tp> using decay_t = _Tp;
+template <typename> struct A;
+template <typename> struct B { B(A<int>); };
+template <typename> struct C {
+ template <typename U> using constructor = B<decay_t<U>>;
+ typedef constructor<int> dummy;
+};
+template <typename> struct D {};
+C<int> a;
+D<B<int>> fn1() { fn1, a; }
diff --git a/gcc/testsuite/g++.dg/diagnostic/pr71075.C b/gcc/testsuite/g++.dg/diagnostic/pr71075.C
new file mode 100644
index 00000000000..6bb1e68e0b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/diagnostic/pr71075.C
@@ -0,0 +1,8 @@
+// PR c++/71075
+
+template<typename T, int I> struct A {};
+template<typename T> void foo(A<T,1>) {}
+int main() {
+ foo(A<int,2>()); // { dg-error "no matching" }
+// { dg-message "template argument .2. does not match .1." "" { target *-*-* } 6 }
+}
diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C
index 03feb1a4d65..e89da154c82 100644
--- a/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C
+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-param-1.C
@@ -1,10 +1,14 @@
/* { dg-do compile { target arm*-*-* } } */
/* { dg-options "-mfp16-format=ieee" } */
-/* Functions cannot have parameters of type __fp16. */
-extern void f (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */
-extern void (*pf) (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */
+/* Test that the ACLE macro is defined. */
+#if __ARM_FP16_ARGS != 1
+#error Unexpected value for __ARM_FP16_ARGS
+#endif
+
+/* Test that __fp16 is supported as a parameter type. */
+extern void f (__fp16);
+extern void (*pf) (__fp16);
-/* These should be OK. */
extern void g (__fp16 *);
extern void (*pg) (__fp16 *);
diff --git a/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C
index 406dfacd399..b96532d1833 100644
--- a/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C
+++ b/gcc/testsuite/g++.dg/ext/arm-fp16/fp16-return-1.C
@@ -1,10 +1,9 @@
/* { dg-do compile { target arm*-*-* } } */
/* { dg-options "-mfp16-format=ieee" } */
-/* Functions cannot return type __fp16. */
-extern __fp16 f (void); /* { dg-error "cannot return __fp16" } */
-extern __fp16 (*pf) (void); /* { dg-error "cannot return __fp16" } */
+/* Test that __fp16 is supported as a return type. */
+extern __fp16 f (void);
+extern __fp16 (*pf) (void);
-/* These should be OK. */
extern __fp16 *g (void);
extern __fp16 *(*pg) (void);
diff --git a/gcc/testsuite/g++.dg/gomp/udr-4.C b/gcc/testsuite/g++.dg/gomp/udr-4.C
index 566d7d1321f..012ff0c97dd 100644
--- a/gcc/testsuite/g++.dg/gomp/udr-4.C
+++ b/gcc/testsuite/g++.dg/gomp/udr-4.C
@@ -1,7 +1,7 @@
// { dg-do compile }
struct S; // { dg-message "forward declaration" }
-#pragma omp declare reduction (+:S:omp_out.s += omp_in.s) // { dg-error "invalid use of incomplete type" }
+#pragma omp declare reduction (+:S:omp_out.s += omp_in.s) // { dg-error "incomplete type" }
struct S { int s; S () : s (1) {} };
#pragma omp declare reduction (*:S:omp_out.s *= omp_in.s)
diff --git a/gcc/testsuite/g++.dg/inherit/thunk1.C b/gcc/testsuite/g++.dg/inherit/thunk1.C
index 3bbd05069df..3d3c1fbc067 100644
--- a/gcc/testsuite/g++.dg/inherit/thunk1.C
+++ b/gcc/testsuite/g++.dg/inherit/thunk1.C
@@ -1,4 +1,5 @@
-// { dg-do run { target i?86-*-* x86_64-*-* s390*-*-* alpha*-*-* ia64-*-* sparc*-*-* } }
+// { dg-do run { target arm*-*-* aarch64*-*-* i?86-*-* x86_64-*-* s390*-*-* alpha*-*-* ia64-*-* sparc*-*-* } }
+// { dg-skip-if "" { arm_thumb1_ok } }
#include <stdarg.h>
diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-7.C b/gcc/testsuite/g++.dg/ipa/ivinline-7.C
index b725db5cb1d..a7b41e7bd59 100644
--- a/gcc/testsuite/g++.dg/ipa/ivinline-7.C
+++ b/gcc/testsuite/g++.dg/ipa/ivinline-7.C
@@ -76,4 +76,4 @@ int main (int argc, char *argv[])
}
/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo" "inline" } } */
-/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/ivinline-9.C b/gcc/testsuite/g++.dg/ipa/ivinline-9.C
index f6110c10076..41b2381877a 100644
--- a/gcc/testsuite/g++.dg/ipa/ivinline-9.C
+++ b/gcc/testsuite/g++.dg/ipa/ivinline-9.C
@@ -90,4 +90,4 @@ int main (int argc, char *argv[])
}
/* { dg-final { scan-ipa-dump "Discovered a virtual call to a known target.*B::.*foo" "inline" } } */
-/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" { xfail *-*-* } } } */
+/* { dg-final { scan-ipa-dump "B::foo\[^\\n\]*inline copy in int main" "inline" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/pr71146.C b/gcc/testsuite/g++.dg/ipa/pr71146.C
new file mode 100644
index 00000000000..b6bd64f4e8c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/pr71146.C
@@ -0,0 +1,29 @@
+// PR ipa/71146
+// { dg-do compile }
+// { dg-options "-O3" }
+
+typedef enum { X } E;
+struct A {
+ virtual void bar ();
+};
+struct B {
+ virtual E fn (const char *, int, int *) = 0;
+};
+struct C : A, B {
+ E fn (const char *, int, int *);
+ void fn2 ();
+ B *foo;
+};
+void C::fn2 () {
+ if (!foo)
+ return;
+ foo->fn (0, 0, 0);
+}
+E
+C::fn (const char *, int, int *)
+{
+ fn2 ();
+ foo = 0;
+ fn (0, 0, 0);
+ return X;
+}
diff --git a/gcc/testsuite/g++.dg/lookup/member4.C b/gcc/testsuite/g++.dg/lookup/member4.C
new file mode 100644
index 00000000000..6fab2f9d17b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/member4.C
@@ -0,0 +1,17 @@
+// PR c++/69753
+// { dg-do compile { target c++11 } }
+
+class A {
+public:
+ template <typename> void As();
+ static A *FromWebContents();
+ A *FromWebContents2();
+};
+template <typename T> class B : A {
+ void FromWebContents() {
+ auto guest = this->A::FromWebContents();
+ guest ? guest->As<T>() : nullptr;
+ auto guest2 = this->A::FromWebContents2();
+ guest2 ? guest2->As<T>() : nullptr;
+ }
+};
diff --git a/gcc/testsuite/g++.dg/lookup/member5.C b/gcc/testsuite/g++.dg/lookup/member5.C
new file mode 100644
index 00000000000..fec1ecd5bfd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/member5.C
@@ -0,0 +1,32 @@
+// PR c++/69753
+// { dg-do compile { target c++11 } }
+
+struct B {
+ template <class> void bfn ();
+};
+
+template <class T>
+constexpr int x(T) { return 42; }
+
+template <int I>
+struct C
+{
+ template <class> void cfn ();
+};
+
+template <typename T> struct A {
+ static B fn(int);
+ template <class U> static B ft(U);
+
+ void g()
+ {
+ auto b = this->fn(42);
+ b.bfn<int>();
+
+ auto b2 = this->ft(42);
+ b2.bfn<int>();
+
+ auto c = C<x(42)>();
+ c.cfn<int>();
+ }
+};
diff --git a/gcc/testsuite/g++.dg/lto/pr69589_0.C b/gcc/testsuite/g++.dg/lto/pr69589_0.C
index bbdcb73dfc7..1457d2eb13e 100644
--- a/gcc/testsuite/g++.dg/lto/pr69589_0.C
+++ b/gcc/testsuite/g++.dg/lto/pr69589_0.C
@@ -1,6 +1,8 @@
// { dg-lto-do link }
-// { dg-lto-options "-O2 -rdynamic" }
+// { dg-lto-options "-O2 -rdynamic" }
// { dg-extra-ld-options "-r -nostdlib" }
+// { dg-skip-if "Skip targets without -rdynamic support" { arm*-none-eabi aarch64*-*-elf } { "*" } { "" } }
+
#pragma GCC visibility push(hidden)
struct A { int &operator[] (long); };
template <typename> struct B;
diff --git a/gcc/testsuite/g++.dg/opt/pr70906.C b/gcc/testsuite/g++.dg/opt/pr70906.C
new file mode 100644
index 00000000000..19c91cd6aec
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr70906.C
@@ -0,0 +1,69 @@
+// PR c++/70906
+// { dg-do compile { target c++11 } }
+// { dg-options "-Wall" }
+
+template <typename> struct B;
+template <typename U> struct F { typedef U *t; };
+template <class> struct D {};
+template <class VP> struct L {
+ typedef VP np;
+ typedef typename F<D<VP>>::t cnp;
+};
+struct P { typedef L<void *> nt; };
+template <class N> struct I { typedef typename N::template A<int> t; };
+template <class O1> struct Q { typedef typename I<O1>::t t; };
+template <class T, class Hook, Hook T::*> struct G;
+template <typename P, typename M, M P::*PM>
+struct mh {
+ template <class> struct A { typedef G<P, M, PM> pvt; };
+};
+template <typename T> struct B<T *> { static T pt(T); };
+struct R : public D<void *> { typedef P ht; };
+class lmh : public R {};
+template <class T, class Hook, Hook T::*P> struct G {
+ typedef Hook Ht;
+ typedef typename Ht::ht::nt nt;
+ typedef T vt;
+ typedef typename nt::np np;
+ typedef typename nt::cnp cnp;
+ static np tnp(T &);
+ static cnp tnp(const T &p1) {
+ B<cnp>::pt(static_cast<const Ht &>(p1.*P));
+ return cnp ();
+ }
+};
+template <class T, class S> struct K {
+ template <S> struct J;
+ template <class U> static int foo(J<U::tnp> *, int);
+ static const int c = sizeof(foo<T>(0, 0));
+};
+template <class V> struct W1 {
+ typedef typename V::vt vt;
+ static const bool value = K<V, typename V::np (*)(vt &)>::c == K<V, typename V::cnp (*)(const vt &)>::c;
+};
+template <class V> struct O {
+ static const bool svt = W1<V>::value;
+};
+template <bool> struct M {};
+template <class V> class C {
+ static const bool svt = O<V>::svt;
+ M<svt> m;
+};
+template <class V> struct H {
+ C<V> bar();
+};
+template <class O1> struct ml {
+ typedef typename Q<O1>::t po;
+ typedef H<typename po::pvt> t;
+};
+template <class O1> class list : public ml<O1>::t {};
+struct N {
+ struct IV { lmh hk; };
+ typedef list<mh<IV, lmh, &IV::hk>> ISL;
+ friend void fn1(int &, N const &);
+};
+void fn1(int &, N const &) {
+ N::ISL xl;
+ for (xl.bar();;)
+ ;
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr70933.C b/gcc/testsuite/g++.dg/opt/pr70933.C
new file mode 100644
index 00000000000..f664d45777c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr70933.C
@@ -0,0 +1,29 @@
+// PR c++/70933
+// { dg-do compile }
+// { dg-options "-Wsequence-point" }
+
+struct A
+{
+ A (const char *);
+};
+
+template <class T>
+struct B
+{
+ typedef T U;
+ U &baz (const A &);
+};
+
+template <class T>
+void
+bar ()
+{
+ B<T> b;
+ T &p = b.baz ("p1") = T(4);
+}
+
+void
+foo ()
+{
+ bar<unsigned> ();
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr71100.C b/gcc/testsuite/g++.dg/opt/pr71100.C
new file mode 100644
index 00000000000..ff739e2e62a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr71100.C
@@ -0,0 +1,18 @@
+// PR c++/71100
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct D { ~D (); };
+struct E { D foo () { throw 1; } };
+
+inline void
+bar (D (E::*f) (), E *o)
+{
+ (o->*f) ();
+}
+
+void
+baz (E *o)
+{
+ bar (&E::foo, o);
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr71210-1.C b/gcc/testsuite/g++.dg/opt/pr71210-1.C
new file mode 100644
index 00000000000..03b1fb55c50
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr71210-1.C
@@ -0,0 +1,14 @@
+// PR c++/71210
+// { dg-do compile }
+// { dg-options "-O2" }
+
+#include <typeinfo>
+
+void f1 (const std::type_info&) __attribute__((noreturn));
+struct S1 { ~S1 (); };
+struct S2
+{
+ virtual S1 f2 () const { f1 (typeid (*this)); }
+ S1 f3 () const { return f2 (); }
+};
+void f4 () { S2 a; a.f3 (); }
diff --git a/gcc/testsuite/g++.dg/opt/pr71210-2.C b/gcc/testsuite/g++.dg/opt/pr71210-2.C
new file mode 100644
index 00000000000..02a31bd5fe8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr71210-2.C
@@ -0,0 +1,23 @@
+// PR c++/71210
+// { dg-do compile }
+// { dg-options "-O2" }
+
+struct C { int a; int b; C (); ~C (); };
+
+namespace
+{
+ struct A
+ {
+ A () {}
+ virtual C bar (int) = 0;
+ C baz (int x) { return bar (x); }
+ };
+}
+
+A *a;
+
+void
+foo ()
+{
+ C c = a->baz (0);
+}
diff --git a/gcc/testsuite/g++.dg/parse/dot1.C b/gcc/testsuite/g++.dg/parse/dot1.C
index 3b027d7c1f0..416ef925287 100644
--- a/gcc/testsuite/g++.dg/parse/dot1.C
+++ b/gcc/testsuite/g++.dg/parse/dot1.C
@@ -1,4 +1,4 @@
// PR c++/24560
struct A { void f(); };
-void g() { A().f.a; } // { dg-error "class" }
+void g() { A().f.a; } // { dg-error "invalid use of member function" }
diff --git a/gcc/testsuite/g++.dg/plugin/self-assign-test-1.C b/gcc/testsuite/g++.dg/plugin/self-assign-test-1.C
index 607381fb403..95d39dd0ce6 100644
--- a/gcc/testsuite/g++.dg/plugin/self-assign-test-1.C
+++ b/gcc/testsuite/g++.dg/plugin/self-assign-test-1.C
@@ -44,7 +44,7 @@ int func()
foo = foo; // { dg-warning "assigned to itself" }
foo.setA(5);
bar_array[3].c_ = bar_array[3].c_; // { dg-warning "assigned to itself" }
- bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" }
+ bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" "" { xfail *-*-* } }
y = x;
x = y;
}
diff --git a/gcc/testsuite/g++.dg/plugin/self-assign-test-2.C b/gcc/testsuite/g++.dg/plugin/self-assign-test-2.C
index 35e1fb8f893..da963c42db2 100644
--- a/gcc/testsuite/g++.dg/plugin/self-assign-test-2.C
+++ b/gcc/testsuite/g++.dg/plugin/self-assign-test-2.C
@@ -44,7 +44,7 @@ int func()
foo = foo; // { dg-bogus "assigned to itself" }
foo.setA(5);
bar_array[3].c_ = bar_array[3].c_; // { dg-warning "assigned to itself" }
- bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" }
+ bar_array[x+g].b_ = bar_array[x+g].b_; // { dg-warning "self-assignment detected" "" { xfail *-*-* } }
y = x;
x = y;
}
diff --git a/gcc/testsuite/g++.dg/pr62314.C b/gcc/testsuite/g++.dg/pr62314.C
new file mode 100644
index 00000000000..ebe75ecd705
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr62314.C
@@ -0,0 +1,17 @@
+// { dg-options "-fdiagnostics-show-caret" }
+
+template <typename T>
+struct iterator_traits {};
+
+struct file_iterator;
+
+struct iterator_traits<file_iterator> { // { dg-error "explicit specialization must be preceded by .template" }
+};
+
+/* Verify that we emit a fixit hint for this case. */
+
+/* { dg-begin-multiline-output "" }
+ struct iterator_traits<file_iterator>
+ ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ template <>
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/g++.dg/pr71184.C b/gcc/testsuite/g++.dg/pr71184.C
new file mode 100644
index 00000000000..452303e47a1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/pr71184.C
@@ -0,0 +1 @@
+operator new[ // { dg-error "expected type-specifier before 'new'" }
diff --git a/gcc/testsuite/g++.dg/spellcheck-fields-2.C b/gcc/testsuite/g++.dg/spellcheck-fields-2.C
new file mode 100644
index 00000000000..eb10b44e59e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/spellcheck-fields-2.C
@@ -0,0 +1,19 @@
+// { dg-options "-fdiagnostics-show-caret" }
+
+union u
+{
+ int color;
+ int shape;
+};
+
+int test (union u *ptr)
+{
+ return ptr->colour; // { dg-error "did you mean .color.?" }
+}
+
+// Verify that we get an underline and a fixit hint.
+/* { dg-begin-multiline-output "" }
+ return ptr->colour;
+ ^~~~~~
+ color
+ { dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/g++.dg/template/crash122.C b/gcc/testsuite/g++.dg/template/crash122.C
new file mode 100644
index 00000000000..028aec3e414
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/crash122.C
@@ -0,0 +1,4 @@
+// PR c++/69793
+
+class fpos;
+template < state > bool operator!= (fpos,; operator!= // { dg-error "declared|expected|type" }
diff --git a/gcc/testsuite/g++.dg/template/pr70466-1.C b/gcc/testsuite/g++.dg/template/pr70466-1.C
new file mode 100644
index 00000000000..7eb83eab957
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr70466-1.C
@@ -0,0 +1,27 @@
+// PR c++/70466
+
+template < class T, class T > // { dg-error "conflicting" }
+class A
+{
+public:
+ explicit A (T (S::*f) ()) {} // { dg-error "expected" }
+};
+
+template < class T, class S >
+A < T, S > foo (T (S::*f) ())
+{
+ return A < T, S > (f);
+}
+
+class B
+{
+public:
+ void bar () {}
+};
+
+int
+main ()
+{
+ foo (&B::bar);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/template/pr70466-2.C b/gcc/testsuite/g++.dg/template/pr70466-2.C
new file mode 100644
index 00000000000..7a7458a61f1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/pr70466-2.C
@@ -0,0 +1,25 @@
+// PR c++/70466
+
+template < class T, class S >
+struct A
+{
+ explicit A (...) {}
+};
+
+template < class T, class S >
+A < T, S > foo (T (S::*f) ())
+{
+ return A < T, S > (f);
+}
+
+struct B
+{
+ void bar () {}
+};
+
+int
+main ()
+{
+ foo (&B::bar);
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/template/pseudodtor3.C b/gcc/testsuite/g++.dg/template/pseudodtor3.C
index 8700bb95252..8f1f6a736a8 100644
--- a/gcc/testsuite/g++.dg/template/pseudodtor3.C
+++ b/gcc/testsuite/g++.dg/template/pseudodtor3.C
@@ -5,7 +5,7 @@ struct A
{
typedef int T;
T &foo ();
- A () { foo.~T (); } // { dg-error "10:does not have class type|expected" }
+ A () { foo.~T (); } // { dg-error "10:invalid use of member function|expected" }
};
template <typename T> struct B
diff --git a/gcc/testsuite/g++.dg/template/using14.C b/gcc/testsuite/g++.dg/template/using14.C
index 276c40b876c..f1d9799343b 100644
--- a/gcc/testsuite/g++.dg/template/using14.C
+++ b/gcc/testsuite/g++.dg/template/using14.C
@@ -17,5 +17,5 @@ template <class T> struct C : public B1<T>, public B2
int main()
{
C<int> c;
- c.f(); // { dg-message "required" }
+ c.f();
}
diff --git a/gcc/testsuite/g++.dg/torture/pr71002.C b/gcc/testsuite/g++.dg/torture/pr71002.C
new file mode 100644
index 00000000000..8a726809217
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr71002.C
@@ -0,0 +1,160 @@
+// { dg-do run }
+
+using size_t = __SIZE_TYPE__;
+
+inline void* operator new(size_t, void* p) noexcept
+{ return p; }
+
+inline void operator delete(void*, void*)
+{ }
+
+struct long_t
+{
+ size_t is_short : 1;
+ size_t length : (__SIZEOF_SIZE_T__ * __CHAR_BIT__ - 1);
+ size_t capacity;
+ char* pointer;
+};
+
+union long_raw_t {
+ unsigned char data[sizeof(long_t)];
+ struct __attribute__((aligned(alignof(long_t)))) { } align;
+};
+
+struct short_header
+{
+ unsigned char is_short : 1;
+ unsigned char length : (__CHAR_BIT__ - 1);
+};
+
+struct short_t
+{
+ short_header h;
+ char data[23];
+};
+
+union repr_t
+{
+ long_raw_t r;
+ short_t s;
+
+ const short_t& short_repr() const
+ { return s; }
+
+ const long_t& long_repr() const
+ { return *static_cast<const long_t*>(static_cast<const void*>(&r)); }
+
+ short_t& short_repr()
+ { return s; }
+
+ long_t& long_repr()
+ { return *static_cast<long_t*>(static_cast<void*>(&r)); }
+};
+
+class string
+{
+public:
+ string()
+ {
+ short_t& s = m_repr.short_repr();
+ s.h.is_short = 1;
+ s.h.length = 0;
+ s.data[0] = '\0';
+ }
+
+ string(const char* str)
+ {
+ size_t length = __builtin_strlen(str);
+ if (length + 1 > 23) {
+ long_t& l = m_repr.long_repr();
+ l.is_short = 0;
+ l.length = length;
+ l.capacity = length + 1;
+ l.pointer = new char[l.capacity];
+ __builtin_memcpy(l.pointer, str, length + 1);
+ } else {
+ short_t& s = m_repr.short_repr();
+ s.h.is_short = 1;
+ s.h.length = length;
+ __builtin_memcpy(s.data, str, length + 1);
+ }
+ }
+
+ string(string&& other)
+ : string{}
+ {
+ swap_data(other);
+ }
+
+ ~string()
+ {
+ if (!is_short()) {
+ delete[] m_repr.long_repr().pointer;
+ }
+ }
+
+ size_t length() const
+ { return is_short() ? short_length() : long_length(); }
+
+private:
+ bool is_short() const
+ { return m_repr.s.h.is_short != 0; }
+
+ size_t short_length() const
+ { return m_repr.short_repr().h.length; }
+
+ size_t long_length() const
+ { return m_repr.long_repr().length; }
+
+ void swap_data(string& other)
+ {
+ if (is_short()) {
+ if (other.is_short()) {
+ repr_t tmp(m_repr);
+ m_repr = other.m_repr;
+ other.m_repr = tmp;
+ } else {
+ short_t short_backup(m_repr.short_repr());
+ m_repr.short_repr().~short_t();
+ ::new(&m_repr.long_repr()) long_t(other.m_repr.long_repr());
+ other.m_repr.long_repr().~long_t();
+ ::new(&other.m_repr.short_repr()) short_t(short_backup);
+ }
+ } else {
+ if (other.is_short()) {
+ short_t short_backup(other.m_repr.short_repr());
+ other.m_repr.short_repr().~short_t();
+ ::new(&other.m_repr.long_repr()) long_t(m_repr.long_repr());
+ m_repr.long_repr().~long_t();
+ ::new(&m_repr.short_repr()) short_t(short_backup);
+ } else {
+ long_t tmp(m_repr.long_repr());
+ m_repr.long_repr() = other.m_repr.long_repr();
+ other.m_repr.long_repr() = tmp;
+ }
+ }
+ }
+
+ repr_t m_repr;
+};
+
+struct foo
+{
+ __attribute__((noinline))
+ foo(string str)
+ : m_str{static_cast<string&&>(str)},
+ m_len{m_str.length()}
+ { }
+
+ string m_str;
+ size_t m_len;
+};
+
+int main()
+{
+ foo f{"the quick brown fox jumps over the lazy dog"};
+ if (f.m_len == 0) {
+ __builtin_abort();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/ivopts-3.C b/gcc/testsuite/g++.dg/tree-ssa/ivopts-3.C
index 6194e9dc2df..eb72581390b 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/ivopts-3.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/ivopts-3.C
@@ -72,4 +72,4 @@ int main ( int , char** ) {
// Verify that on x86_64 and i?86 we use a single IV for the innermost loop
-// { dg-final { scan-tree-dump "Selected IV set for loop \[0-9\]* at \[^ \]*:64, 1 IVs" "ivopts" { target x86_64-*-* i?86-*-* } } }
+// { dg-final { scan-tree-dump "Selected IV set for loop \[0-9\]* at \[^ \]*:64, 3 avg niters, 1 expressions, 1 IVs" "ivopts" { target x86_64-*-* i?86-*-* } } }
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70199.c b/gcc/testsuite/gcc.c-torture/compile/pr70199.c
index a4323f09f23..03eab4f44d7 100644
--- a/gcc/testsuite/gcc.c-torture/compile/pr70199.c
+++ b/gcc/testsuite/gcc.c-torture/compile/pr70199.c
@@ -1,3 +1,6 @@
+/* { dg-require-effective-target indirect_jumps } */
+/* { dg-require-effective-target label_values } */
+
static volatile int v = 0;
static
void benchmark(long runs) {
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr70916.c b/gcc/testsuite/gcc.c-torture/compile/pr70916.c
new file mode 100644
index 00000000000..c3ea69fba9b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr70916.c
@@ -0,0 +1,28 @@
+/* PR tree-optimization/70916 */
+
+int a, b, c, d, i, k;
+int static *e = &b, *j;
+int **f;
+int static ***g = &f;
+int *h;
+void
+fn1 ()
+{
+ for (;;)
+ {
+ int l[1] = { };
+ int m = (__UINTPTR_TYPE__) l;
+ for (; d; d--)
+ {
+ int ****n;
+ int *****o = &n;
+ i = a & 7 ? : a;
+ *e = (((*o = &g) != (int ****) g) < h[c], 0) || k;
+ if (*e)
+ {
+ **n = &j;
+ *e = (__UINTPTR_TYPE__) h;
+ }
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20030222-1.c b/gcc/testsuite/gcc.c-torture/execute/20030222-1.c
index 385ae686192..a820cf206e1 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20030222-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20030222-1.c
@@ -4,6 +4,7 @@
actually truncated to int, in case a single register is wide enough
for a long long. */
/* { dg-skip-if "asm would require extra shift-left-4-byte" { spu-*-* } "*" "" } */
+/* { dg-skip-if "asm requires register allocation" { nvptx-*-* } "*" "" } */
#include <limits.h>
void
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr68185.c b/gcc/testsuite/gcc.c-torture/execute/pr68185.c
index 826531bf71b..5e078ae6f1c 100644
--- a/gcc/testsuite/gcc.c-torture/execute/pr68185.c
+++ b/gcc/testsuite/gcc.c-torture/execute/pr68185.c
@@ -1,3 +1,5 @@
+/* { dg-xfail-if "ptxas crashes" { nvptx-*-* } { "-O0" } { "" } } */
+
int a, b, d = 1, e, f, o, u, w = 1, z;
short c, q, t;
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr70460.c b/gcc/testsuite/gcc.c-torture/execute/pr70460.c
index bfecea0932e..acc57511ae2 100644
--- a/gcc/testsuite/gcc.c-torture/execute/pr70460.c
+++ b/gcc/testsuite/gcc.c-torture/execute/pr70460.c
@@ -1,3 +1,6 @@
+/* { dg-require-effective-target indirect_jumps } */
+/* { dg-require-effective-target label_values } */
+
/* PR rtl-optimization/70460 */
int c;
diff --git a/gcc/testsuite/gcc.dg/Waddress-2.c b/gcc/testsuite/gcc.dg/Waddress-2.c
new file mode 100644
index 00000000000..4d927f67694
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Waddress-2.c
@@ -0,0 +1,24 @@
+/* PR c/48778 */
+/* { dg-do compile } */
+/* { dg-options "-Waddress" } */
+
+#define NULL ((void *) 0)
+
+#define M1(b) ((b) != NULL ? 0 : (b))
+#define M2(b) ((b) == NULL ? 0 : (b))
+#define M3(b) (NULL != (b) ? 0 : (b))
+#define M4(b) (NULL == (b) ? 0 : (b))
+
+int
+func (int b)
+{
+ if (M1 (&b) > 0)
+ return 1;
+ if (M2 (&b) > 0)
+ return 2;
+ if (M3 (&b) > 0)
+ return 3;
+ if (M4 (&b) > 0)
+ return 4;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/Wduplicate-decl-specifier-c11.c b/gcc/testsuite/gcc.dg/Wduplicate-decl-specifier-c11.c
new file mode 100644
index 00000000000..c2db525aaf9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wduplicate-decl-specifier-c11.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -Wduplicate-decl-specifier" } */
+
+typedef _Atomic int AT1;
+#define AT2 _Atomic int
+
+void
+foo (void)
+{
+ _Atomic AT1 x1;
+ _Atomic AT2 x2;
+ AT1 _Atomic x3;
+ AT2 _Atomic x4;
+ _Atomic int _Atomic x5; /* { dg-warning "duplicate ._Atomic." } */
+}
+
+void a1(_Atomic AT1 t) { }
+void a2(_Atomic AT2 t) { }
+void a3(AT1 _Atomic t) { }
+void a4(AT2 _Atomic t) { }
+void a5(_Atomic int _Atomic t) { } /* { dg-warning "duplicate ._Atomic." } */
+
+typedef _Atomic AT1 AAT1;
+typedef _Atomic AT2 AAT2;
+typedef AT1 _Atomic AT1A;
+typedef AT2 _Atomic AT2A;
+typedef _Atomic int _Atomic AIA; /* { dg-warning "duplicate ._Atomic." } */
diff --git a/gcc/testsuite/gcc.dg/Wduplicate-decl-specifier.c b/gcc/testsuite/gcc.dg/Wduplicate-decl-specifier.c
new file mode 100644
index 00000000000..d7a3919649b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/Wduplicate-decl-specifier.c
@@ -0,0 +1,63 @@
+/* PR43651 */
+/* { dg-do compile } */
+/* { dg-options "-Wduplicate-decl-specifier" } */
+
+typedef const int CT1;
+#define CT2 const int
+typedef volatile int VT1;
+#define VT2 volatile int
+typedef char *restrict RT1;
+#define RT2 char *restrict
+
+void
+foo (void)
+{
+ const CT1 x1;
+ const CT2 x2;
+ CT1 const x3;
+ CT2 const x4;
+ const int const x5; /* { dg-warning "duplicate .const." } */
+ const int *const x6;
+ volatile VT1 y1;
+ volatile VT2 y2;
+ VT1 volatile y3;
+ VT2 volatile y4;
+ volatile int volatile y5; /* { dg-warning "duplicate .volatile." } */
+ volatile int *volatile y6;
+ RT1 restrict r1;
+ RT2 restrict r2;
+ restrict RT1 r3;
+ /* "restrict RT2" is invalid */
+ char *restrict restrict r4; /* { dg-warning "duplicate .restrict." } */
+ char *restrict *restrict r5;
+}
+
+void c1(const CT1 t) { }
+void c2(const CT2 t) { }
+void c3(CT1 const t) { }
+void c4(CT2 const t) { }
+void c5(const int const t) { } /* { dg-warning "duplicate .const." } */
+void v1(volatile VT1 t) { }
+void v2(volatile VT2 t) { }
+void v3(VT1 volatile t) { }
+void v4(VT2 volatile t) { }
+void v5(volatile int volatile t) { } /* { dg-warning "duplicate .volatile." } */
+void r1(restrict RT1 t) { }
+void r2(RT1 restrict t) { }
+void r3(RT2 restrict t) { }
+void r4(char *restrict restrict t) { } /* { dg-warning "duplicate .restrict." } */
+
+typedef const CT1 CCT1;
+typedef const CT2 CCT2;
+typedef CT1 const CT1C;
+typedef CT2 const CT2C;
+typedef const int const CIC; /* { dg-warning "duplicate .const." } */
+typedef volatile VT1 VVT1;
+typedef volatile VT2 VVT2;
+typedef VT1 volatile VT1V;
+typedef VT2 volatile VT2V;
+typedef volatile int volatile VIV; /* { dg-warning "duplicate .volatile." } */
+typedef RT1 restrict RT1R;
+typedef RT2 restrict RT2R;
+typedef restrict RT1 RRT1;
+typedef int *restrict restrict IRR; /* { dg-warning "duplicate .restrict." } */
diff --git a/gcc/testsuite/gcc.dg/Woverride-init-1.c b/gcc/testsuite/gcc.dg/Woverride-init-1.c
index 29eca3095cd..b01d8a29dcc 100644
--- a/gcc/testsuite/gcc.dg/Woverride-init-1.c
+++ b/gcc/testsuite/gcc.dg/Woverride-init-1.c
@@ -10,19 +10,19 @@ union u { char a; long long b; };
struct s s0 = {
.a = 1,
.b = 2,
- .a = 3, /* { dg-warning "initialized field overwritten|near init" } */
- 4, /* { dg-warning "initialized field overwritten|near init" } */
+ .a = 3, /* { dg-warning "initialized field overwritten" } */
+ 4, /* { dg-warning "initialized field overwritten" } */
5
};
union u u0 = {
.a = 1,
- .b = 2, /* { dg-warning "initialized field overwritten|near init" } */
- .a = 3 }; /* { dg-warning "initialized field overwritten|near init" } */
+ .b = 2, /* { dg-warning "initialized field overwritten" } */
+ .a = 3 }; /* { dg-warning "initialized field overwritten" } */
int a[5] = {
[0] = 1,
[1] = 2,
- [0] = 3, /* { dg-warning "initialized field overwritten|near init" } */
+ [0] = 3, /* { dg-warning "initialized field overwritten" } */
[2] = 4
};
diff --git a/gcc/testsuite/gcc.dg/Woverride-init-2.c b/gcc/testsuite/gcc.dg/Woverride-init-2.c
index c5490b5ad35..d0ece89eb6d 100644
--- a/gcc/testsuite/gcc.dg/Woverride-init-2.c
+++ b/gcc/testsuite/gcc.dg/Woverride-init-2.c
@@ -10,19 +10,19 @@ union u { char a; long long b; };
struct s s0 = {
.a = 1,
.b = 2,
- .a = 3, /* { dg-warning "initialized field overwritten|near init" } */
- 4, /* { dg-warning "initialized field overwritten|near init" } */
+ .a = 3, /* { dg-warning "initialized field overwritten" } */
+ 4, /* { dg-warning "initialized field overwritten" } */
5
};
union u u0 = {
.a = 1,
- .b = 2, /* { dg-warning "initialized field overwritten|near init" } */
- .a = 3 }; /* { dg-warning "initialized field overwritten|near init" } */
+ .b = 2, /* { dg-warning "initialized field overwritten" } */
+ .a = 3 }; /* { dg-warning "initialized field overwritten" } */
int a[5] = {
[0] = 1,
[1] = 2,
- [0] = 3, /* { dg-warning "initialized field overwritten|near init" } */
+ [0] = 3, /* { dg-warning "initialized field overwritten" } */
[2] = 4
};
diff --git a/gcc/testsuite/gcc.dg/atomic-noinline-aux.c b/gcc/testsuite/gcc.dg/atomic-noinline-aux.c
index 97989798fe5..f0e3387b980 100644
--- a/gcc/testsuite/gcc.dg/atomic-noinline-aux.c
+++ b/gcc/testsuite/gcc.dg/atomic-noinline-aux.c
@@ -7,6 +7,7 @@
the exact entry points the test file will require. All these routines
simply set the first parameter to 1, and the caller will test for that. */
+#include <stddef.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
@@ -64,7 +65,7 @@ __atomic_fetch_nand_1 (unsigned char *p, unsigned char v, int i)
return ret;
}
-bool __atomic_is_lock_free (int i, void *p)
+bool __atomic_is_lock_free (size_t i, void *p)
{
*(short *)p = 1;
return true;
diff --git a/gcc/testsuite/gcc.dg/autopar/outer-6.c b/gcc/testsuite/gcc.dg/autopar/outer-6.c
index fff7bce138a..7aae803acd9 100644
--- a/gcc/testsuite/gcc.dg/autopar/outer-6.c
+++ b/gcc/testsuite/gcc.dg/autopar/outer-6.c
@@ -24,7 +24,7 @@ void parloop (int N)
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
- y[i]=x[i][j];
+ y[i]+=x[i][j];
sum += y[i];
}
g_sum = sum;
diff --git a/gcc/testsuite/gcc.dg/call-diag-2.c b/gcc/testsuite/gcc.dg/call-diag-2.c
index c34252cd729..b998ea9d760 100644
--- a/gcc/testsuite/gcc.dg/call-diag-2.c
+++ b/gcc/testsuite/gcc.dg/call-diag-2.c
@@ -1,7 +1,7 @@
/* Test diagnostics for calling function returning qualified void or
other incomplete type other than void. PR 35210. */
/* { dg-do compile } */
-/* { dg-options "-pedantic-errors" } */
+/* { dg-options "-std=gnu99 -pedantic-errors" } */
const void f_cv (void);
struct s f_s (void);
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/nested_fun.c b/gcc/testsuite/gcc.dg/debug/dwarf2/nested_fun.c
new file mode 100644
index 00000000000..c783ac0c11a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/nested_fun.c
@@ -0,0 +1,65 @@
+/* As part of inlining, a BLOCK (described as DW_TAG_lexical_block DIE's) may
+ be present both as an abstract instance and a concrete one in the DWARF
+ output. This testcase attempts to make sure that the concrete ones refer to
+ the abstract ones thanks to the DW_AT_abstract_origin attribute.
+
+ Such a back-link enables debuggers to make entities present in the abstract
+ instance only available in concrete ones. */
+
+/* { dg-options "-O2 -g -std=gnu99 -gdwarf -dA" } */
+/* { dg-final { scan-assembler-times "\\(DIE \\(0x.*\\) DW_TAG_lexical_block\\)\[^)\]*DW_AT_abstract_origin" 1 } } */
+
+extern void *create (const char *);
+extern void destroy (void *);
+extern void do_nothing (char);
+
+struct string
+{
+ const char *data;
+ int lb;
+ int ub;
+};
+
+int
+main (void)
+{
+ void *o1 = create ("foo");
+
+ void
+ parent (void)
+ {
+ {
+ void *o2 = create ("bar");
+
+ int
+ child (struct string s)
+ {
+ int i = s.lb;
+
+ if (s.lb <= s.ub)
+ while (1)
+ {
+ char c = s.data[i - s.lb];
+ do_nothing (c);
+ if (c == 'o')
+ return 1;
+ if (i == s.ub)
+ break;
+ ++i;
+ }
+ return 0;
+ }
+
+ int r;
+
+ r = child ((struct string) {"baz", 1, 3});
+ r = child ((struct string) {"qux", 2, 4});
+ r = child ((struct string) {"foobar", 1, 6});
+ }
+
+ do_nothing (0);
+ }
+
+ parent ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/fold-notrotate-1.c b/gcc/testsuite/gcc.dg/fold-notrotate-1.c
new file mode 100644
index 00000000000..a9b38040f3a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-notrotate-1.c
@@ -0,0 +1,54 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+#define INT_BITS (sizeof (int) * __CHAR_BIT__)
+#define ROL(x, y) ((x) << (y) | (x) >> (INT_BITS - (y)))
+#define ROR(x, y) ((x) >> (y) | (x) << (INT_BITS - (y)))
+
+unsigned
+rol (unsigned a, unsigned b)
+{
+ return ~ROL (~a, b);
+}
+
+unsigned int
+ror (unsigned a, unsigned b)
+{
+ return ~ROR (~a, b);
+}
+
+int
+rol_conv1 (int a, unsigned b)
+{
+ return ~(int)ROL((unsigned)~a, b);
+}
+
+int
+rol_conv2 (int a, unsigned b)
+{
+ return ~ROL((unsigned)~a, b);
+}
+
+int
+rol_conv3 (unsigned a, unsigned b)
+{
+ return ~(int)ROL(~a, b);
+}
+
+#define LONG_BITS (sizeof (long) * __CHAR_BIT__)
+#define ROLL(x, y) ((x) << (y) | (x) >> (LONG_BITS - (y)))
+#define RORL(x, y) ((x) >> (y) | (x) << (LONG_BITS - (y)))
+
+unsigned long
+roll (unsigned long a, unsigned long b)
+{
+ return ~ROLL (~a, b);
+}
+
+unsigned long
+rorl (unsigned long a, unsigned long b)
+{
+ return ~RORL (~a, b);
+}
+
+/* { dg-final { scan-tree-dump-not "~" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-notshift-1.c b/gcc/testsuite/gcc.dg/fold-notshift-1.c
new file mode 100644
index 00000000000..2de236fc4d8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-notshift-1.c
@@ -0,0 +1,77 @@
+/* PR tree-optimization/54579
+ PR middle-end/55299 */
+
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-cddce1" } */
+
+int
+asr1 (int a, int b)
+{
+ return ~((~a) >> b);
+}
+
+long
+asr1l (long a, long b)
+{
+ return ~((~a) >> b);
+}
+
+int
+asr_conv (unsigned a, unsigned b)
+{
+ return ~((int)~a >> b);
+}
+
+unsigned
+asr_conv2 (unsigned a, unsigned b)
+{
+ return ~(unsigned)((int)~a >> b);
+}
+
+unsigned
+asr_conv3 (int a, int b)
+{
+ return ~(unsigned)(~a >> b);
+}
+
+typedef __INT32_TYPE__ int32_t;
+typedef __INT64_TYPE__ int64_t;
+
+int32_t
+asr_conv4 (int64_t a, int b)
+{
+ return ~((int32_t)~a >> b);
+}
+
+int32_t
+asr_conv5 (int64_t a, int b)
+{
+ return ~(int32_t)(~a >> b);
+}
+
+int
+asr2 (int a, int b)
+{
+ return -((-a - 1) >> b) - 1;
+}
+
+int
+asr3 (int a, int b)
+{
+ return a < 0 ? ~((~a) >> b) : a >> b;
+}
+
+int64_t
+asr3l (int64_t a, int b)
+{
+ return a < 0 ? ~((~a) >> b) : a >> b;
+}
+
+int
+asr4 (int a, int b)
+{
+ return a < 0 ? -((-a - 1) >> b) - 1 : a >> b;
+}
+
+/* { dg-final { scan-tree-dump-times ">>" 11 "cddce1" } } */
+/* { dg-final { scan-tree-dump-not "~" "cddce1" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-notshift-2.c b/gcc/testsuite/gcc.dg/fold-notshift-2.c
new file mode 100644
index 00000000000..32635f183d7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fold-notshift-2.c
@@ -0,0 +1,33 @@
+/* PR middle-end/55299 */
+
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-cddce1" } */
+
+unsigned int
+lsr (unsigned int a, unsigned int b)
+{
+ return ~((~a) >> b);
+}
+
+int
+sl (int a, int b)
+{
+ return ~((~a) << b);
+}
+
+typedef __INT32_TYPE__ int32_t;
+typedef __INT64_TYPE__ int64_t;
+
+int64_t
+asr_widen1 (int32_t a, int b)
+{
+ return ~((int64_t)(~a) >> b);
+}
+
+int64_t
+asr_widen2 (int32_t a, int b)
+{
+ return ~(int64_t)(~a >> b);
+}
+
+/* { dg-final { scan-tree-dump-times "~" 8 "cddce1" } } */
diff --git a/gcc/testsuite/gcc.dg/fold-perm.c b/gcc/testsuite/gcc.dg/fold-perm.c
index 9cfc2db36aa..0fa050eb292 100644
--- a/gcc/testsuite/gcc.dg/fold-perm.c
+++ b/gcc/testsuite/gcc.dg/fold-perm.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-ccp1" } */
+/* { dg-options "-O -fdump-tree-fre1" } */
typedef int veci __attribute__ ((vector_size (4 * sizeof (int))));
@@ -14,6 +14,6 @@ void fun (veci *f, veci *g, veci *h, veci *i)
*f = __builtin_shuffle (*f, *g, n);
}
-/* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 3, 3, 0, 2 }" "ccp1" } } */
-/* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 1, 1, 3, 2 }" "ccp1" } } */
-/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "ccp1" } } */
+/* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 3, 3, 0, 2 }" "fre1" } } */
+/* { dg-final { scan-tree-dump "VEC_PERM_EXPR.*{ 1, 1, 3, 2 }" "fre1" } } */
+/* { dg-final { scan-tree-dump-times "VEC_PERM_EXPR" 2 "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/foo.specs b/gcc/testsuite/gcc.dg/foo.specs
index 8819249fa34..45fc84306cd 100644
--- a/gcc/testsuite/gcc.dg/foo.specs
+++ b/gcc/testsuite/gcc.dg/foo.specs
@@ -1,2 +1,2 @@
-*cppruntime:
+*cpp_unique_options:
+ %{tfoo: -DFOO}
diff --git a/gcc/testsuite/gcc.dg/graphite/pr70956.c b/gcc/testsuite/gcc.dg/graphite/pr70956.c
new file mode 100644
index 00000000000..31fc25f4638
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/pr70956.c
@@ -0,0 +1,4 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fgraphite-identity" } */
+
+#include "../tree-ssa/vrp66.c"
diff --git a/gcc/testsuite/gcc.dg/graphite/scop-18.c b/gcc/testsuite/gcc.dg/graphite/scop-18.c
index 3416304075d..fe2a5bf9709 100644
--- a/gcc/testsuite/gcc.dg/graphite/scop-18.c
+++ b/gcc/testsuite/gcc.dg/graphite/scop-18.c
@@ -13,13 +13,13 @@ void test (void)
for (i = 0; i < 24; i++)
for (j = 0; j < 24; j++)
for (k = 0; k < 24; k++)
- A[i][j] = B[i][k] * C[k][j];
+ A[i][j] += B[i][k] * C[k][j];
/* These loops should still be strip mined. */
for (i = 0; i < 1000; i++)
for (j = 0; j < 1000; j++)
for (k = 0; k < 1000; k++)
- A[i][j] = B[i][k] * C[k][j];
+ A[i][j] += B[i][k] * C[k][j];
}
/* { dg-final { scan-tree-dump-times "number of SCoPs: 1" 1 "graphite"} } */
diff --git a/gcc/testsuite/gcc.dg/init-excess-2.c b/gcc/testsuite/gcc.dg/init-excess-2.c
new file mode 100644
index 00000000000..1bf0a96a880
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/init-excess-2.c
@@ -0,0 +1,47 @@
+/* Test for diagnostics about excess initializers when using a macro
+ defined in a system header:
+ c/71115 - Missing warning: excess elements in struct initializer. */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+#include <stddef.h>
+
+int* a[1] = {
+ 0,
+ NULL /* { dg-warning "excess elements|near init" } */
+};
+
+const char str[1] = {
+ 0,
+ NULL /* { dg-warning "excess elements|near init" } */
+};
+
+struct S {
+ int *a;
+} s = {
+ 0,
+ NULL /* { dg-warning "excess elements|near init" } */
+};
+
+struct __attribute__ ((designated_init)) S2 {
+ int *a;
+} s2 = {
+ NULL /* { dg-warning "positional initialization|near init" } */
+};
+
+union U {
+ int *a;
+} u = {
+ 0,
+ NULL /* { dg-warning "excess elements|near init" } */
+};
+
+int __attribute__ ((vector_size (16))) ivec = {
+ 0, 0, 0, 0,
+ NULL /* { dg-warning "excess elements|near init" } */
+};
+
+int* scal = {
+ 0,
+ NULL /* { dg-warning "excess elements|near init" } */
+};
diff --git a/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-1.c b/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-1.c
new file mode 100644
index 00000000000..8656cb336fa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-1.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-inline-details -fno-early-inlining -fno-ipa-sra -fno-ipa-cp" } */
+
+typedef struct S
+{
+ int add_offset;
+ int (*call)(int);
+} S;
+
+static int
+bar (const S *f, int x)
+{
+ x = f->call(x);
+ return x;
+}
+
+static int
+thisisthetarget (int x)
+{
+ return x * x;
+}
+
+static const S s = {16, thisisthetarget};
+
+int
+outerfunction (int x)
+{
+ return bar (&s, x);
+}
+
+int
+obfuscate (int x)
+{
+ return bar ((S *) 0, x);
+}
+
+/* { dg-final { scan-ipa-dump "thisisthetarget\[^\\n\]*inline copy in outerfunction" "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c b/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c
new file mode 100644
index 00000000000..546db87ea5d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/iinline-cstagg-2.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-inline-details -fno-early-inlining -fno-ipa-sra -fno-ipa-cp" } */
+
+typedef struct S
+{
+ int add_offset;
+ int (*call)(int);
+} S;
+
+static int
+bar (const S f, int x)
+{
+ x = f.call (x);
+ return x;
+}
+
+static int
+thisisthetarget (int x)
+{
+ return x * x;
+}
+
+int
+outerfunction (int x)
+{
+ return bar ((S){16, thisisthetarget}, x);
+}
+
+
+/* { dg-final { scan-ipa-dump "thisisthetarget\[^\\n\]*inline copy in outerfunction" "inline" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/inline-8.c b/gcc/testsuite/gcc.dg/ipa/inline-8.c
new file mode 100644
index 00000000000..df4a64deff9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/inline-8.c
@@ -0,0 +1,39 @@
+/* Verify that we do not inline isnanf test info -ffast-math code but that we
+ do inline trivial functions across -Ofast boundary. */
+/* { dg-do run } */
+/* { dg-require-effective-target c99_runtime } */
+/* { dg-options "-O2" } */
+/* { dg-add-options c99_runtime } */
+#include <math.h>
+extern int isnanf (float);
+/* Can't be inlined because isnanf will be optimized out. */
+int
+cmp (float a)
+{
+ return isnanf (a);
+}
+/* Can be inlined. */
+int
+move (int a)
+{
+ return a;
+}
+float a;
+void
+set ()
+{
+ a=nan("");
+}
+float b;
+__attribute__ ((optimize("Ofast")))
+int
+main()
+{
+ b++;
+ if (cmp(a))
+ __builtin_abort ();
+ float a = move (1);
+ if (!__builtin_constant_p (a))
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-1.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-1.c
new file mode 100644
index 00000000000..4d64ea7d4ce
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+typedef struct S
+{
+ int add_offset;
+ int (*call)(int);
+} S;
+
+extern const S *gs;
+
+static int __attribute__((noinline))
+bar (const S *f, int x)
+{
+ x = f->call(x);
+ x = f->call(x);
+ x = f->call(x);
+ gs = f;
+ return x;
+}
+
+static int
+sq (int x)
+{
+ return x * x;
+}
+
+static const S s = {16, sq};
+
+int
+g (int x)
+{
+ return bar (&s, x);
+}
+
+int
+obfuscate (int x)
+{
+ return bar ((S *) 0, x);
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-2.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-2.c
new file mode 100644
index 00000000000..f82014024d4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-2.c
@@ -0,0 +1,46 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+typedef struct S
+{
+ int (*call)(int);
+} S;
+
+static int __attribute__((noinline))
+bar (const S *f, int x)
+{
+ x = f->call(x);
+ return x;
+}
+
+extern void impossible_aa (void);
+
+static int __attribute__((noinline))
+baz (const S *f, int x)
+{
+ impossible_aa ();
+ return bar (f, x);
+}
+
+static int
+sq (int x)
+{
+ return x * x;
+}
+
+static const S s = {sq};
+
+int
+g (int x)
+{
+ return baz (&s, x);
+}
+
+int
+obfuscate (int x)
+{
+ return baz ((S *) 0, x);
+}
+
+/* { dg-final { scan-ipa-dump "Discovered an indirect call to a known target" "cp" } } */
+
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-3.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-3.c
new file mode 100644
index 00000000000..917f1389f3e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-3.c
@@ -0,0 +1,58 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+#define N 4
+
+typedef int (* const A[N])(int);
+
+extern const A *ga;
+
+static int __attribute__((noinline))
+bar (const A *f, int x)
+{
+ x = (*f)[2](x);
+ x = (*f)[2](x);
+ x = (*f)[2](x);
+ ga = f;
+ return x;
+}
+
+static int
+zero (int x)
+{
+ return 0;
+}
+
+static int
+addone (int x)
+{
+ return x + 1;
+}
+
+static int
+sq (int x)
+{
+ return x * x;
+}
+
+static int
+cube (int x)
+{
+ return x * x * x;
+}
+
+static const A a = {zero, addone, sq, cube};
+
+int
+g (int x)
+{
+ return bar (&a, x);
+}
+
+int
+obfuscate (int x)
+{
+ return bar ((A *) 0, x);
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-4.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-4.c
new file mode 100644
index 00000000000..7458402c88e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-4.c
@@ -0,0 +1,64 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+#define N 4
+
+typedef int (* const A[N])(int);
+
+typedef struct S
+{
+ int add_offset;
+ A a;
+} S;
+
+extern const S *gs;
+
+static int __attribute__((noinline))
+bar (const S *f, int x)
+{
+ gs = f;
+ x = f->a[2](x);
+ x = f->a[2](x);
+ x = f->a[2](x);
+ return x;
+}
+
+static int
+zero (int x)
+{
+ return 0;
+}
+
+static int
+addone (int x)
+{
+ return x + 1;
+}
+
+static int
+sq (int x)
+{
+ return x * x;
+}
+
+static int
+cube (int x)
+{
+ return x * x * x;
+}
+
+static const S s = {64, {zero, addone, sq, cube}};
+
+int
+g (int x)
+{
+ return bar (&s, x);
+}
+
+int
+obfuscate (int x)
+{
+ return bar ((S *) 0, x);
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c
new file mode 100644
index 00000000000..56d544e5a64
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-5.c
@@ -0,0 +1,37 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+typedef struct S
+{
+ int add_offset;
+ int (*call)(int);
+} S;
+
+extern const S *es;
+
+static int __attribute__((noinline))
+foo (const S f, int x)
+{
+ es = &f; /* This disables IPA-SRA */
+ x = f.call(x+f.add_offset);
+ x = f.call(x);
+ x = f.call(x);
+ return x;
+}
+
+static int
+sq (int x)
+{
+ return x * x;
+}
+
+static const S s = {16, sq};
+
+int
+h (int x)
+{
+ return foo (s, x);
+}
+
+/* { dg-final { scan-ipa-dump "Discovered an indirect call to a known target" "cp" } } */
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c
new file mode 100644
index 00000000000..7891082f785
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-6.c
@@ -0,0 +1,43 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+typedef struct S
+{
+ int add_offset;
+ int (*call)(int);
+} S;
+
+extern const S *es, *fs;
+
+static int __attribute__((noinline))
+foo (const S f, int x)
+{
+ es = &f; /* This disables IPA-SRA */
+ x = f.call(x+f.add_offset);
+ x = f.call(x);
+ x = f.call(x);
+ return x;
+}
+
+static int __attribute__((noinline))
+bar (const S f, int x)
+{
+ fs = &f; /* This disables IPA-SRA */
+ return foo (f, x);
+}
+
+static int
+sq (int x)
+{
+ return x * x;
+}
+
+static const S s = {16, sq};
+
+int
+h (int x)
+{
+ return bar (s, x);
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c
new file mode 100644
index 00000000000..6af8bda6d8e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-cstagg-7.c
@@ -0,0 +1,65 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-ipa-cp-details" } */
+
+#define N 4
+
+typedef int (* const A[N])(int);
+
+typedef struct S
+{
+ int add_offset;
+ A a;
+} S;
+
+extern const S *gs, *hs;
+
+static int __attribute__((noinline))
+foo (const S f, int x)
+{
+ gs = &f;
+ x = f.a[2](x);
+ x = f.a[2](x);
+ x = f.a[2](x);
+ return x;
+}
+
+static int __attribute__((noinline))
+bar (const S f, int x)
+{
+ hs = &f;
+ return foo (f, x);
+}
+
+static int
+zero (int x)
+{
+ return 0;
+}
+
+static int
+addone (int x)
+{
+ return x + 1;
+}
+
+static int
+sq (int x)
+{
+ return x * x;
+}
+
+static int
+cube (int x)
+{
+ return x * x * x;
+}
+
+static const S s = {64, {zero, addone, sq, cube}};
+
+int
+h (int x)
+{
+ return bar (s, x);
+}
+
+/* { dg-final { scan-ipa-dump-times "Discovered an indirect call to a known target" 3 "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr70306.c b/gcc/testsuite/gcc.dg/ipa/pr70306.c
index be18208afd4..f9327073ac8 100644
--- a/gcc/testsuite/gcc.dg/ipa/pr70306.c
+++ b/gcc/testsuite/gcc.dg/ipa/pr70306.c
@@ -1,5 +1,6 @@
/* { dg-options "-O2 -fdump-ipa-icf" } */
/* { dg-do run } */
+/* { dg-require-effective-target global_constructor } */
int ctor_counter = 1;
int dtor_counter;
diff --git a/gcc/testsuite/gcc.dg/ipa/pr70646.c b/gcc/testsuite/gcc.dg/ipa/pr70646.c
new file mode 100644
index 00000000000..f85816e7303
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr70646.c
@@ -0,0 +1,40 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+
+#pragma GCC optimize("no-unit-at-a-time")
+
+typedef unsigned char u8;
+typedef unsigned long long u64;
+
+static inline __attribute__((always_inline)) u64 __swab64p(const u64 *p)
+{
+ return (__builtin_constant_p((u64)(*p)) ? ((u64)( (((u64)(*p) & (u64)0x00000000000000ffULL) << 56) | (((u64)(*p) & (u64)0x000000000000ff00ULL) << 40) | (((u64)(*p) & (u64)0x0000000000ff0000ULL) << 24) | (((u64)(*p) & (u64)0x00000000ff000000ULL) << 8) | (((u64)(*p) & (u64)0x000000ff00000000ULL) >> 8) | (((u64)(*p) & (u64)0x0000ff0000000000ULL) >> 24) | (((u64)(*p) & (u64)0x00ff000000000000ULL) >> 40) | (((u64)(*p) & (u64)0xff00000000000000ULL) >> 56))) : __builtin_bswap64(*p));
+}
+
+static inline u64 wwn_to_u64(void *wwn)
+{
+ return __swab64p(wwn);
+}
+
+void __attribute__((noinline,noclone)) broken(u64* shost)
+{
+ u8 node_name[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
+ *shost = wwn_to_u64(node_name);
+}
+
+void __attribute__((noinline,noclone)) dummy(void)
+{
+ __builtin_abort();
+}
+
+int main(int argc, char* argv[])
+{
+ u64 v;
+
+ broken(&v);
+
+ if(v != (u64)-1)
+ __builtin_abort();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pure-const-3.c b/gcc/testsuite/gcc.dg/ipa/pure-const-3.c
new file mode 100644
index 00000000000..e3d27c10f33
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pure-const-3.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-require-alias "" } */
+/* { dg-options "-O2 -fdump-tree-local-pure-const1" } */
+
+__attribute__ ((weak))
+__attribute__ ((noinline))
+int a(int v)
+{
+ return v;
+}
+__attribute__ ((noinline))
+static int b(int v) __attribute__ ((alias("a")));
+int
+main()
+{
+ int c = a(1)==a(1);
+ int d = b(1)==b(1);
+ if (__builtin_constant_p (c))
+ __builtin_abort ();
+ if (!__builtin_constant_p (d))
+ __builtin_abort ();
+ return 0;
+}
+/* { dg-final { scan-tree-dump "found to be const" "local-pure-const1"} } */
diff --git a/gcc/testsuite/gcc.dg/nested-func-10.c b/gcc/testsuite/gcc.dg/nested-func-10.c
index ac6f76fbbe7..e017fba871e 100644
--- a/gcc/testsuite/gcc.dg/nested-func-10.c
+++ b/gcc/testsuite/gcc.dg/nested-func-10.c
@@ -1,6 +1,7 @@
/* PR c/70093 */
/* { dg-do compile } */
/* { dg-options "" } */
+/* { dg-require-effective-target alloca } */
void __attribute__((noinline, noclone))
foo (int n)
diff --git a/gcc/testsuite/gcc.dg/nested-func-9.c b/gcc/testsuite/gcc.dg/nested-func-9.c
index 902c2585393..633ab6993d0 100644
--- a/gcc/testsuite/gcc.dg/nested-func-9.c
+++ b/gcc/testsuite/gcc.dg/nested-func-9.c
@@ -1,6 +1,7 @@
/* PR c/70093 */
/* { dg-do run } */
/* { dg-options "" } */
+/* { dg-require-effective-target alloca } */
void
foo (int n)
diff --git a/gcc/testsuite/gcc.dg/optimize-bswapsi-4.c b/gcc/testsuite/gcc.dg/optimize-bswapsi-4.c
new file mode 100644
index 00000000000..a298486c439
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/optimize-bswapsi-4.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target bswap32 } */
+/* { dg-options "-O2 -fdump-tree-bswap" } */
+/* { dg-additional-options "-march=z900" { target s390-*-* } } */
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+union __anonunion
+{
+ u32 value;
+ u8 bytes[4];
+};
+
+u32
+acpi_ut_dword_byte_swap (u32 value)
+{
+ union __anonunion in;
+ in.value = value;
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ return ((in.bytes[0] << 24) | (in.bytes[1] << 16)
+ | (in.bytes[2] << 8) | in.bytes[3]);
+#else
+ return ((in.bytes[3] << 24) | (in.bytes[2] << 16)
+ | (in.bytes[1] << 8) | in.bytes[0]);
+#endif
+}
+
+/* { dg-final { scan-tree-dump "32 bit bswap implementation found at" "bswap" } } */
diff --git a/gcc/testsuite/gcc.dg/opts-7.c b/gcc/testsuite/gcc.dg/opts-7.c
new file mode 100644
index 00000000000..c54d0b8215a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/opts-7.c
@@ -0,0 +1,6 @@
+/* PR driver/71063 */
+/* Test we don't ICE. */
+/* { dg-do compile } */
+/* { dg-options "--help=^" } */
+
+/* { dg-error "missing argument to" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c
index 8d44078a29d..2748fa1f280 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-bw.c
@@ -117,6 +117,9 @@ void test_very_wide_line (void)
#if 0
float f = foo * bar; /* { dg-warning "95: test" } */
/* { dg-begin-multiline-output "" }
+ 0 0 0 0 0 0 1
+ 4 5 6 7 8 9 0
+ 6789012345678901234567890123456789012345678901234567890123456789012345
float f = foo * bar;
~~~~^~~~~
{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-color.c b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-color.c
index a59025870a6..ff2f4d45c85 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-color.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic-test-show-locus-color.c
@@ -117,6 +117,9 @@ void test_very_wide_line (void)
#if 0
float f = foo * bar; /* { dg-warning "95: test" } */
/* { dg-begin-multiline-output "" }
+ 0 0 0 0 0 0 1
+ 4 5 6 7 8 9 0
+ 6789012345678901234567890123456789012345678901234567890123456789012345
float f = foo * bar;
~~~~^~~~~
{ dg-end-multiline-output "" } */
diff --git a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
index 95078ce2f2b..a5f8f0cee93 100644
--- a/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
+++ b/gcc/testsuite/gcc.dg/plugin/diagnostic_plugin_test_show_locus.c
@@ -234,9 +234,11 @@ test_show_locus (function *fun)
if (0 == strcmp (fnname, "test_very_wide_line"))
{
const int line = fnstart_line + 2;
+ global_dc->show_ruler_p = true;
warning_at (make_location (get_loc (line, 94), get_loc (line, 90),
get_loc (line, 98)),
0, "test");
+ global_dc->show_ruler_p = false;
}
/* Example of multiple carets. */
diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c b/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c
new file mode 100644
index 00000000000..6d74955aa80
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-1.c
@@ -0,0 +1,22 @@
+extern void abort (void);
+
+int __attribute__((noinline,noclone))
+callee (int i)
+{
+ return i * i;
+}
+
+int __attribute__((noinline,noclone))
+caller (int i)
+{
+ return callee (i + 1);
+}
+
+int
+main (int argc, const char **argv)
+{
+ int result = caller (5);
+ if (result != 36)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c
new file mode 100644
index 00000000000..c5504f8eed4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/must-tail-call-2.c
@@ -0,0 +1,58 @@
+/* Allow nested functions. */
+/* { dg-options "-Wno-pedantic" } */
+
+struct box { char field[64]; int i; };
+
+struct box __attribute__((noinline,noclone))
+returns_struct (int i)
+{
+ struct box b;
+ b.i = i * i;
+ return b;
+}
+
+int __attribute__((noinline,noclone))
+test_1 (int i)
+{
+ return returns_struct (i * 5).i; /* { dg-error "cannot tail-call: callee returns a structure" } */
+}
+
+int __attribute__((noinline,noclone))
+test_2_callee (int i, struct box b)
+{
+ if (b.field[0])
+ return 5;
+ return i * i;
+}
+
+int __attribute__((noinline,noclone))
+test_2_caller (int i)
+{
+ struct box b;
+ return test_2_callee (i + 1, b); /* { dg-error "cannot tail-call: callee required more stack slots than the caller" } */
+}
+
+extern void setjmp (void);
+void
+test_3 (void)
+{
+ setjmp (); /* { dg-error "cannot tail-call: callee returns twice" } */
+}
+
+void
+test_4 (void)
+{
+ void nested (void)
+ {
+ }
+ nested (); /* { dg-error "cannot tail-call: nested function" } */
+}
+
+typedef void (fn_ptr_t) (void);
+volatile fn_ptr_t fn_ptr;
+
+void
+test_5 (void)
+{
+ fn_ptr (); /* { dg-error "cannot tail-call: callee does not return" } */
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/must_tail_call_plugin.c b/gcc/testsuite/gcc.dg/plugin/must_tail_call_plugin.c
new file mode 100644
index 00000000000..5294f28abbc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/plugin/must_tail_call_plugin.c
@@ -0,0 +1,76 @@
+/* { dg-options "-O" } */
+
+/* Mark all CALL_EXPRs not within "main" as requiring tail-call. */
+
+#include "gcc-plugin.h"
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tree.h"
+#include "stringpool.h"
+#include "toplev.h"
+#include "basic-block.h"
+#include "hash-table.h"
+#include "vec.h"
+#include "ggc.h"
+#include "basic-block.h"
+#include "tree-ssa-alias.h"
+#include "internal-fn.h"
+#include "gimple-fold.h"
+#include "tree-eh.h"
+#include "gimple-expr.h"
+#include "is-a.h"
+#include "tree.h"
+#include "tree-pass.h"
+#include "intl.h"
+#include "plugin-version.h"
+
+int plugin_is_GPL_compatible;
+
+tree
+cb_walk_tree_fn (tree * tp, int * walk_subtrees,
+ void * data ATTRIBUTE_UNUSED)
+{
+ if (TREE_CODE (*tp) != CALL_EXPR)
+ return NULL_TREE;
+
+ tree call_expr = *tp;
+
+ /* Forcibly mark the CALL_EXPR as requiring tail-call optimization. */
+ CALL_EXPR_MUST_TAIL_CALL (call_expr) = 1;
+
+ return NULL_TREE;
+}
+
+static void
+callback (void *gcc_data, void *user_data)
+{
+ tree fndecl = (tree)gcc_data;
+ gcc_assert (TREE_CODE (fndecl) == FUNCTION_DECL);
+
+ /* Don't mark calls inside "main". */
+ tree decl_name = DECL_NAME (fndecl);
+ if (decl_name)
+ if (0 == strcmp (IDENTIFIER_POINTER (decl_name), "main"))
+ return;
+
+ walk_tree (&DECL_SAVED_TREE (fndecl), cb_walk_tree_fn, NULL, NULL);
+}
+
+int
+plugin_init (struct plugin_name_args *plugin_info,
+ struct plugin_gcc_version *version)
+{
+ const char *plugin_name = plugin_info->base_name;
+
+ if (!plugin_default_version_check (version, &gcc_version))
+ return 1;
+
+ register_callback (plugin_name,
+ PLUGIN_PRE_GENERICIZE,
+ callback,
+ NULL);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/plugin/plugin.exp b/gcc/testsuite/gcc.dg/plugin/plugin.exp
index fd1e98e53c4..62f6797c813 100644
--- a/gcc/testsuite/gcc.dg/plugin/plugin.exp
+++ b/gcc/testsuite/gcc.dg/plugin/plugin.exp
@@ -74,6 +74,9 @@ set plugin_test_list [list \
{ location_overflow_plugin.c \
location-overflow-test-1.c \
location-overflow-test-2.c } \
+ { must_tail_call_plugin.c \
+ must-tail-call-1.c \
+ must-tail-call-2.c } \
]
foreach plugin_test $plugin_test_list {
diff --git a/gcc/testsuite/gcc.dg/plugin/self-assign-test-1.c b/gcc/testsuite/gcc.dg/plugin/self-assign-test-1.c
index f6dc5240f1e..28c14dd762a 100644
--- a/gcc/testsuite/gcc.dg/plugin/self-assign-test-1.c
+++ b/gcc/testsuite/gcc.dg/plugin/self-assign-test-1.c
@@ -16,7 +16,7 @@ int main()
static int y;
struct Bar b_array[5];
- b_array[x+g].b_ = b_array[x+g].b_; /* { dg-warning "self-assignment detected" } */
+ b_array[x+g].b_ = b_array[x+g].b_; /* { dg-warning "self-assignment detected" "" { xfail *-*-* } } */
g = g; /* { dg-warning "assigned to itself" } */
y = y; /* { dg-warning "assigned to itself" } */
bar->b_ = bar->b_; /* { dg-warning "assigned to itself" } */
diff --git a/gcc/testsuite/gcc.dg/pr18079-2.c b/gcc/testsuite/gcc.dg/pr18079-2.c
deleted file mode 100644
index 2c83b701e10..00000000000
--- a/gcc/testsuite/gcc.dg/pr18079-2.c
+++ /dev/null
@@ -1,16 +0,0 @@
-/* PR c/18079 */
-/* { dg-do compile } */
-/* { dg-options "-Wall" } */
-
-__attribute__ ((always_inline)) void fndecl1 (void);
-__attribute__ ((noinline)) void fndecl1 (void); /* { dg-warning "attribute 'noinline' follows declaration with attribute 'always_inline'" } */
-
-__attribute__ ((noinline)) void fndecl2 (void);
-__attribute__ ((always_inline)) void fndecl2 (void); /* { dg-warning "attribute 'always_inline' follows declaration with attribute 'noinline'" } */
-
-
-__attribute__ ((hot)) void fndecl3 (void);
-__attribute__ ((cold)) void fndecl3 (void); /* { dg-warning "attribute 'cold' follows declaration with attribute 'hot'" } */
-
-__attribute__ ((cold)) void fndecl4 (void);
-__attribute__ ((hot)) void fndecl4 (void); /* { dg-warning "attribute 'hot' follows declaration with attribute 'cold'" } */
diff --git a/gcc/testsuite/gcc.dg/pr30172-1.c b/gcc/testsuite/gcc.dg/pr30172-1.c
index 015b558d067..ee6efdeebb8 100644
--- a/gcc/testsuite/gcc.dg/pr30172-1.c
+++ b/gcc/testsuite/gcc.dg/pr30172-1.c
@@ -10,5 +10,5 @@ _Complex double test5 (double x, double y) { return (x + y * 1.i) * -1.i; }
/* { dg-final { scan-tree-dump "COMPLEX_EXPR <x, 1.0e\\+0>" "gimple" } } */
/* { dg-final { scan-tree-dump "COMPLEX_EXPR <1.0e\\+0, x>" "gimple" } } */
/* { dg-final { scan-tree-dump "COMPLEX_EXPR <x, y>" "gimple" } } */
-/* { dg-final { scan-tree-dump "D.* = -y;\n.*COMPLEX_EXPR <D.*, x>" "gimple" } } */
-/* { dg-final { scan-tree-dump "D.* = -x;\n.*COMPLEX_EXPR <y, D.*>" "gimple" } } */
+/* { dg-final { scan-tree-dump " = -y;\n.*COMPLEX_EXPR <\[^,\]*, x>" "gimple" } } */
+/* { dg-final { scan-tree-dump " = -x;\n.*COMPLEX_EXPR <y, " "gimple" } } */
diff --git a/gcc/testsuite/gcc.dg/pr41783.c b/gcc/testsuite/gcc.dg/pr41783.c
index 3d8006c579d..465b0af872c 100644
--- a/gcc/testsuite/gcc.dg/pr41783.c
+++ b/gcc/testsuite/gcc.dg/pr41783.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-tree-pre" } */
+/* { dg-options "-O3 -fdump-tree-pre -fno-tree-loop-im" } */
int db[100];
int a_global_var, fact;
int main()
diff --git a/gcc/testsuite/gcc.dg/pr63743.c b/gcc/testsuite/gcc.dg/pr63743.c
index 635ac381c55..ba492b9fe81 100644
--- a/gcc/testsuite/gcc.dg/pr63743.c
+++ b/gcc/testsuite/gcc.dg/pr63743.c
@@ -4,7 +4,8 @@
double
libcall_dep (double x, double y)
{
- return x * (x + y);
+ double tem = x + y;
+ return x * tem;
}
/* { dg-final { scan-rtl-dump-times "Swap operands" 1 "expand" } } */
diff --git a/gcc/testsuite/gcc.dg/pr68671.c b/gcc/testsuite/gcc.dg/pr68671.c
index bec4639f80a..09501561817 100644
--- a/gcc/testsuite/gcc.dg/pr68671.c
+++ b/gcc/testsuite/gcc.dg/pr68671.c
@@ -1,6 +1,7 @@
/* PR tree-optimization/68671 */
/* { dg-do run } */
/* { dg-options " -O2 -fno-tree-dce" } */
+/* { dg-xfail-if "ptxas crashes" { nvptx-*-* } { "*" } { "" } } */
volatile int a = -1;
volatile int b;
diff --git a/gcc/testsuite/gcc.dg/pr69634.c b/gcc/testsuite/gcc.dg/pr69634.c
index 59e37390714..e4032b6bbb6 100644
--- a/gcc/testsuite/gcc.dg/pr69634.c
+++ b/gcc/testsuite/gcc.dg/pr69634.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fno-dce -fschedule-insns -fno-tree-vrp -fcompare-debug" } */
/* { dg-additional-options "-Wno-psabi -mno-sse" { target i?86-*-* x86_64-*-* } } */
+/* { dg-require-effective-target scheduling } */
typedef unsigned short u16;
typedef short v16u16 __attribute__ ((vector_size (16)));
diff --git a/gcc/testsuite/gcc.dg/pr70807.c b/gcc/testsuite/gcc.dg/pr70807.c
new file mode 100644
index 00000000000..9ef2a4d9097
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr70807.c
@@ -0,0 +1,18 @@
+/* PR middle-end/70807 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+typedef int INT;
+int a, b, c, d, e, f;
+void fn1() {
+ INT g;
+ if (d && a)
+ ;
+ else if (e && b)
+ ;
+ else if (!a && !b && c)
+ ;
+ else if (b && d || a && e)
+ a = 0;
+ f = g || d;
+}
diff --git a/gcc/testsuite/gcc.dg/pr70859-2.c b/gcc/testsuite/gcc.dg/pr70859-2.c
new file mode 100644
index 00000000000..4817852a955
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr70859-2.c
@@ -0,0 +1,18 @@
+/* PR c/70859 */
+/* { dg-do compile } */
+
+#include <stdint.h>
+#define MAX __SIZE_MAX__
+#define MAX2 SIZE_MAX
+#define FIVE 5
+
+static void *p;
+
+void
+fn0 (int n)
+{
+ p = __builtin_alloca_with_align (n, SIZE_MAX); /* { dg-error "39:must be a constant integer" } */
+ p = __builtin_alloca_with_align (n, MAX); /* { dg-error "39:must be a constant integer" } */
+ p = __builtin_alloca_with_align (n, MAX2); /* { dg-error "39:must be a constant integer" } */
+ p = __builtin_alloca_with_align (n, FIVE); /* { dg-error "39:must be a constant integer" } */
+}
diff --git a/gcc/testsuite/gcc.dg/pr70859.c b/gcc/testsuite/gcc.dg/pr70859.c
new file mode 100644
index 00000000000..0a3c8437c66
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr70859.c
@@ -0,0 +1,69 @@
+/* PR c/70859 */
+/* { dg-do compile } */
+
+static void *p;
+static double *d;
+static int r;
+__extension__ static _Bool b;
+
+void
+fn0 (int n)
+{
+ p = __builtin_alloca_with_align (n, 6); /* { dg-error "39:must be a constant integer" } */
+
+ r += __builtin_isfinite (0); /* { dg-error "28:non-floating-point argument in call" } */
+ r += __builtin_isinf (0); /* { dg-error "25:non-floating-point argument in call" } */
+ r += __builtin_isinf_sign (0); /* { dg-error "30:non-floating-point argument in call" } */
+ r += __builtin_isnan (0); /* { dg-error "25:non-floating-point argument in call" } */
+ r += __builtin_isnormal (0); /* { dg-error "28:non-floating-point argument in call" } */
+ r += __builtin_signbit (0); /* { dg-error "27:non-floating-point argument in call" } */
+
+ r += __builtin_isgreater (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+ r += __builtin_isgreaterequal (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+ r += __builtin_isless (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+ r += __builtin_islessequal (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+ r += __builtin_islessgreater (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+ r += __builtin_isunordered (0, 0); /* { dg-error "8:non-floating-point arguments in call to function" } */
+
+ r += __builtin_fpclassify (1, 2, n, 4, 5, n); /* { dg-error "36:non-const integer argument 3 in call" } */
+ r += __builtin_fpclassify (1, 2, 3, 4, 5, 6); /* { dg-error "45:non-floating-point argument in call" } */
+
+ d = __builtin_assume_aligned (p, n, p); /* { dg-error "39:non-integer argument 3 in call" } */
+
+ b = __builtin_add_overflow (n, *d, &r); /* { dg-error "34:argument 2 in call to function" } */
+ b = __builtin_add_overflow (n, 5, d); /* { dg-error "37:argument 3 in call" } */
+ b = __builtin_sub_overflow (n, *d, &r); /* { dg-error "34:argument 2 in call to function" } */
+ b = __builtin_sub_overflow (n, 5, d); /* { dg-error "37:argument 3 in call" } */
+ b = __builtin_mul_overflow (n, *d, &r); /* { dg-error "34:argument 2 in call to function" } */
+ b = __builtin_mul_overflow (n, 5, d); /* { dg-error "37:argument 3 in call" } */
+}
+
+int
+fn1 (void)
+{
+ if (__builtin_constant_p ()) /* { dg-error "7:not enough" } */
+ return 0;
+ if (__builtin_constant_p (1, 2)) /* { dg-error "7:too many" } */
+ return 1;
+ if (__builtin_isfinite ()) /* { dg-error "7:not enough" } */
+ return 3;
+ if (__builtin_isfinite (1, 2)) /* { dg-error "7:too many" } */
+ return 4;
+ if (__builtin_isless (0)) /* { dg-error "7:not enough" } */
+ return 5;
+ if (__builtin_isless (1, 2, 3)) /* { dg-error "7:too many" } */
+ return 6;
+ if (__builtin_fpclassify (1, 2, 3, 4, 5)) /* { dg-error "7:not enough" } */
+ return 7;
+ if (__builtin_fpclassify (1, 2, 3, 4, 5, r, 6)) /* { dg-error "7:too many" } */
+ return 8;
+ if (__builtin_assume_aligned (p)) /* { dg-error "7:too few" } */
+ return 9;
+ if (__builtin_assume_aligned (p, r, p, p)) /* { dg-error "7:too many" } */
+ return 10;
+ if (__builtin_add_overflow ()) /* { dg-error "7:not enough" } */
+ return 11;
+ if (__builtin_add_overflow (1, 2, 3, &r)) /* { dg-error "7:too many" } */
+ return 12;
+ return -1;
+}
diff --git a/gcc/testsuite/gcc.dg/pr71006.c b/gcc/testsuite/gcc.dg/pr71006.c
new file mode 100644
index 00000000000..2b45aa01c7e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr71006.c
@@ -0,0 +1,16 @@
+/* PR target/71006 */
+/* { dg-do compile } */
+/* { dg-options "-O1 -ftree-vectorize" } */
+
+unsigned char uu, gu, e2;
+
+void
+fs (void)
+{
+ char *nq = (char *)&gu, *k4 = (char *)&gu;
+ while (*k4 < 1)
+ {
+ uu += (*nq != 0 || e2 != 0);
+ ++*k4;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/pr71071.c b/gcc/testsuite/gcc.dg/pr71071.c
new file mode 100644
index 00000000000..582f1f15a43
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr71071.c
@@ -0,0 +1,12 @@
+/* PR bootstrap/71071 */
+/* { dg-do compile } *
+/* { dg-options "-O2" } */
+
+struct S { unsigned b : 1; } a;
+
+void
+foo ()
+{
+ if (a.b)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/pr71084.c b/gcc/testsuite/gcc.dg/pr71084.c
new file mode 100644
index 00000000000..46fdf9fbe5c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr71084.c
@@ -0,0 +1,38 @@
+/* PR tree-optimization/71084 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void babl_format (void);
+void gimp_drawable_get_format (void);
+int _setjmp (void);
+
+enum {
+ GIMP_RGB_IMAGE,
+ GIMP_RGBA_IMAGE,
+ GIMP_GRAY_IMAGE,
+ GIMP_GRAYA_IMAGE,
+ GIMP_INDEXED_IMAGE
+} run_i;
+
+int run_height;
+
+void fn1 ()
+{
+ int type, width;
+ if (_setjmp ())
+ switch (type)
+ {
+ case GIMP_RGB_IMAGE:
+ babl_format ();
+ case GIMP_RGBA_IMAGE:
+ case GIMP_GRAY_IMAGE:
+ babl_format ();
+ case GIMP_GRAYA_IMAGE:
+ case GIMP_INDEXED_IMAGE:
+ gimp_drawable_get_format();
+ }
+ for (; run_height;)
+ for (; run_i < (long)fn1; ++run_i)
+ for (; width;)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/pr71148.c b/gcc/testsuite/gcc.dg/pr71148.c
new file mode 100644
index 00000000000..6aa4920d1d9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr71148.c
@@ -0,0 +1,46 @@
+/* PR rtl-optimization/71148 */
+/* { dg-do compile } */
+/* { dg-options "-O3 -funroll-loops" } */
+
+int rh, ok, kq, fu;
+
+void
+js (int cs)
+{
+ rh = fu;
+ if (fu != 0)
+ {
+ cs /= 3;
+ if (cs <= 0)
+ {
+ int z9;
+ for (z9 = 0; z9 < 2; ++z9)
+ {
+ z9 += cs;
+ ok += z9;
+ fu += ok;
+ }
+ }
+ }
+}
+
+void
+vy (int s3)
+{
+ int yo, g2 = 0;
+ sd:
+ js (g2);
+ for (yo = 0; yo < 2; ++yo)
+ {
+ if (fu != 0)
+ goto sd;
+ kq += (s3 != (g2 ? s3 : 0));
+ for (s3 = 0; s3 < 72; ++s3)
+ g2 *= (~0 - 1);
+ g2 -= yo;
+ }
+ for (fu = 0; fu < 18; ++fu)
+ for (yo = 0; yo < 17; ++yo)
+ if (g2 < 0)
+ goto sd;
+}
diff --git a/gcc/testsuite/gcc.dg/qual-return-2.c b/gcc/testsuite/gcc.dg/qual-return-2.c
index 22a1946b03f..1cd1253518b 100644
--- a/gcc/testsuite/gcc.dg/qual-return-2.c
+++ b/gcc/testsuite/gcc.dg/qual-return-2.c
@@ -1,7 +1,7 @@
/* Test for warnings for qualified function return types. -pedantic test. */
/* Origin: Joseph Myers <jsm28@cam.ac.uk> */
/* { dg-do compile } */
-/* { dg-options "-pedantic" } */
+/* { dg-options "-pedantic -std=gnu99" } */
/* Qualifying a function return type makes no sense. */
diff --git a/gcc/testsuite/gcc.dg/qual-return-3.c b/gcc/testsuite/gcc.dg/qual-return-3.c
index e65f86d547d..bd760799d98 100644
--- a/gcc/testsuite/gcc.dg/qual-return-3.c
+++ b/gcc/testsuite/gcc.dg/qual-return-3.c
@@ -4,7 +4,7 @@
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
-/* { dg-options "" } */
+/* { dg-options "-std=gnu99" } */
int foo (); /* { dg-message "note: previous declaration" "different qualifiers" } */
const int foo () { return 0; } /* { dg-error "conflicting types" "different qualifiers" } */
diff --git a/gcc/testsuite/gcc.dg/qual-return-4.c b/gcc/testsuite/gcc.dg/qual-return-4.c
index 9b61cfebf12..7bb5b691973 100644
--- a/gcc/testsuite/gcc.dg/qual-return-4.c
+++ b/gcc/testsuite/gcc.dg/qual-return-4.c
@@ -3,7 +3,7 @@
types, not other such types within the definition. */
/* Origin: Joseph Myers <jsm@polyomino.org.uk> */
/* { dg-do compile } */
-/* { dg-options "-pedantic" } */
+/* { dg-options "-pedantic -std=gnu99" } */
volatile void (*y)(int);
diff --git a/gcc/testsuite/gcc.dg/qual-return-5.c b/gcc/testsuite/gcc.dg/qual-return-5.c
new file mode 100644
index 00000000000..32a08f217d0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/qual-return-5.c
@@ -0,0 +1,32 @@
+/* Test qualifiers on function return types after DR#423: those
+ qualifiers are now ignored for all purposes (but _Atomic is not,
+ for this purpose, a qualifier). */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+int f1 (void);
+const int f1 (void);
+volatile int f1 (void) { return 0; }
+
+int *restrict f2 (void) { return 0; }
+int *f2 (void);
+
+const volatile long f3 (void);
+long f3 (void);
+
+const volatile void f4 (void) { }
+void f4 (void);
+
+_Atomic int f5 (void); /* { dg-message "previous declaration" } */
+int f5 (void); /* { dg-error "conflicting" } */
+
+int f6 (void); /* { dg-message "previous declaration" } */
+_Atomic int f6 (void) { return 0; } /* { dg-error "conflicting" } */
+
+/* The standard seems unclear regarding the case where restrict is
+ applied to a function return type that may not be
+ restrict-qualified; assume here that it is disallowed. */
+restrict int f7 (void); /* { dg-error "restrict" } */
+
+typedef void FT (void);
+FT *restrict f8 (void); /* { dg-error "restrict" } */
diff --git a/gcc/testsuite/gcc.dg/qual-return-6.c b/gcc/testsuite/gcc.dg/qual-return-6.c
new file mode 100644
index 00000000000..5b3ded0696a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/qual-return-6.c
@@ -0,0 +1,12 @@
+/* Test qualifiers on function return types after DR#423: those
+ qualifiers are now ignored for all purposes (except that _Atomic
+ still affects the type), but should still get warnings. */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -Wignored-qualifiers" } */
+
+const int f1 (void); /* { dg-warning "qualifiers ignored" } */
+volatile int f2 (void) { return 0; } /* { dg-warning "qualifiers ignored" } */
+const volatile void f3 (void) { } /* { dg-warning "qualifiers ignored" } */
+const void f4 (void); /* { dg-warning "qualifiers ignored" } */
+_Atomic int f5 (void); /* { dg-warning "qualifiers ignored" } */
+_Atomic int f6 (void) { return 0; } /* { dg-warning "qualifiers ignored" } */
diff --git a/gcc/testsuite/gcc.dg/setjmp-6.c b/gcc/testsuite/gcc.dg/setjmp-6.c
index 0781f055952..d821d230ce0 100644
--- a/gcc/testsuite/gcc.dg/setjmp-6.c
+++ b/gcc/testsuite/gcc.dg/setjmp-6.c
@@ -1,6 +1,7 @@
/* PR69569 */
/* { dg-do compile } */
/* { dg-options "-O3" } */
+/* { dg-require-effective-target indirect_jumps } */
#include <setjmp.h>
diff --git a/gcc/testsuite/gcc.dg/spec-options.c b/gcc/testsuite/gcc.dg/spec-options.c
index e3ab23ac110..01d0a0929e0 100644
--- a/gcc/testsuite/gcc.dg/spec-options.c
+++ b/gcc/testsuite/gcc.dg/spec-options.c
@@ -1,8 +1,7 @@
/* Check that -mfoo is accepted if defined in a user spec
and that it is not passed on the command line. */
/* Must be processed in EXTRA_SPECS to run. */
-/* { dg-do compile } */
-/* { dg-do run { target sh*-*-* } } */
+/* { dg-do run } */
/* { dg-options "-B${srcdir}/gcc.dg --specs=foo.specs -tfoo" } */
extern void abort(void);
diff --git a/gcc/testsuite/gcc.dg/spellcheck-options-11.c b/gcc/testsuite/gcc.dg/spellcheck-options-11.c
new file mode 100644
index 00000000000..8e271416aa2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/spellcheck-options-11.c
@@ -0,0 +1,7 @@
+/* Verify that we provide a hint if the user misspells an option argument
+ (PR driver/69265). */
+
+/* { dg-do compile } */
+/* { dg-options "-ftls-model=global-dinamic" } */
+/* { dg-error "unknown TLS model 'global-dinamic'" "" { target *-*-* } 0 } */
+/* { dg-message "valid arguments to '-ftls-model=' are: global-dynamic initial-exec local-dynamic local-exec; did you mean 'global-dynamic'?" "" { target *-*-* } 0 } */
diff --git a/gcc/testsuite/gcc.dg/tm/pr51696.c b/gcc/testsuite/gcc.dg/tm/pr51696.c
index 02ee3f517c0..e39c6ca140b 100644
--- a/gcc/testsuite/gcc.dg/tm/pr51696.c
+++ b/gcc/testsuite/gcc.dg/tm/pr51696.c
@@ -10,5 +10,5 @@ static void (*compare)();
__attribute__((transaction_safe))
static void func () {
listPtr->compare(); /* { dg-error "unsafe indirect function call" } */
- compare(); /* { dg-error "unsafe function call" } */
+ compare(); /* { dg-error "unsafe indirect function call" } */
}
diff --git a/gcc/testsuite/gcc.dg/torture/20160404-1.c b/gcc/testsuite/gcc.dg/torture/20160404-1.c
new file mode 100644
index 00000000000..b3a85b55ad7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/20160404-1.c
@@ -0,0 +1,21 @@
+/* { dg-do compile } */
+
+typedef __UINT64_TYPE__ UINT64;
+typedef union {
+ struct {
+ unsigned short lo4;
+ unsigned short lo3;
+ unsigned short lo2;
+ unsigned short lo1;
+ } i;
+ long double f;
+} BID_BINARY80LDOUBLE;
+UINT64 __binary80_to_bid32 (long double x)
+{
+ BID_BINARY80LDOUBLE x_in;
+ x_in.f = x;
+ return (x_in.i.lo4
+ + ((UINT64)x_in.i.lo3 << 16)
+ + ((UINT64)x_in.i.lo2 << 32)
+ + ((UINT64)x_in.i.lo1 << 48));
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr54261-1.c b/gcc/testsuite/gcc.dg/torture/pr54261-1.c
index 571727b0c95..071b3232d46 100644
--- a/gcc/testsuite/gcc.dg/torture/pr54261-1.c
+++ b/gcc/testsuite/gcc.dg/torture/pr54261-1.c
@@ -32,7 +32,10 @@ void g (int *at, int val)
int main(void)
{
- int x = 41;
+ /* On PTX it is not valid to perform atomic operations on auto
+ variables, which end up in .local. Making this static places it
+ in .global. */
+ static int x = 41;
int a = 1;
g (&x, a);
diff --git a/gcc/testsuite/gcc.dg/torture/pr66178.c b/gcc/testsuite/gcc.dg/torture/pr66178.c
index ebc626c6f5a..c42996df60a 100644
--- a/gcc/testsuite/gcc.dg/torture/pr66178.c
+++ b/gcc/testsuite/gcc.dg/torture/pr66178.c
@@ -1,4 +1,6 @@
/* { dg-do compile } */
+/* { dg-require-effective-target label_values } */
+
int test(void)
{
static int a = ((char *)&&l1-(char *)&&l2)-1;
diff --git a/gcc/testsuite/gcc.dg/torture/pr70935.c b/gcc/testsuite/gcc.dg/torture/pr70935.c
new file mode 100644
index 00000000000..eb7f034ce83
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70935.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -g" } */
+
+int d0, sj, v0, rp, zi;
+
+void
+zn(void)
+{
+ if (v0 != 0)
+ {
+ int *js, *r3;
+ int pm, gc;
+
+ for (gc = 0; gc < 1; ++gc)
+ {
+ sj = 1;
+ while (sj != 0)
+ ;
+ }
+ r3 = &pm;
+ *js = (long)&gc;
+ka:
+ for (d0 = 0; d0 < 2; ++d0)
+ {
+ d0 = zi;
+ if (zi)
+ for (pm = 2; pm != 0; --pm)
+ ;
+ }
+ while (*r3 != 0)
+ {
+ while (pm)
+ ;
+ ++r3;
+ }
+ }
+ rp = 0;
+ goto ka;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr70941.c b/gcc/testsuite/gcc.dg/torture/pr70941.c
new file mode 100644
index 00000000000..eb37a1fb293
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70941.c
@@ -0,0 +1,12 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+
+signed char a = 0, b = 0, c = 0, d = 0;
+
+int main()
+{
+ a = -(b - 405418259) - ((d && c) ^ 2040097152);
+ if (a != (signed char) -1634678893)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr70985.c b/gcc/testsuite/gcc.dg/torture/pr70985.c
new file mode 100644
index 00000000000..17273b029a4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70985.c
@@ -0,0 +1,28 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target int32plus } */
+
+struct
+{
+ int f0:24;
+} a, c, d;
+
+int b;
+
+int
+fn1 ()
+{
+ return 0;
+}
+
+void
+fn2 ()
+{
+ int e;
+ if (b)
+ for (; e;)
+ {
+ d = c;
+ if (fn1 (b))
+ b = a.f0;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr70986-1.c b/gcc/testsuite/gcc.dg/torture/pr70986-1.c
new file mode 100644
index 00000000000..4da1f54eef0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70986-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+
+int a, g;
+char b, c;
+short d, e, f;
+
+char
+fn1 ()
+{
+ return a ? a : 1;
+}
+
+void
+fn2 ()
+{
+ char h;
+ for (; d;)
+ for (; e; e++)
+ c = (fn1 () && h) & !(f |= 9 ^ (b > (g = c)));
+ for (;;)
+ ;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr70986-2.c b/gcc/testsuite/gcc.dg/torture/pr70986-2.c
new file mode 100644
index 00000000000..2f4d2b645e0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70986-2.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int gi, dg;
+
+void
+fe (void)
+{
+ int ka = gi;
+
+ for (;;)
+ {
+ if (ka != 0)
+ {
+ if (dg != 0)
+ gi = 0;
+ ++ka;
+ }
+ ++dg;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr70986-3.c b/gcc/testsuite/gcc.dg/torture/pr70986-3.c
new file mode 100644
index 00000000000..5b722d590a0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr70986-3.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+
+int a, b;
+int
+fn1 (int p1)
+{
+ return p1 < 0 ? p1 : a;
+}
+
+void
+fn2 ()
+{
+lbl_100:
+ b = 1;
+ for (; b != 21; b = fn1 (b))
+ ;
+ goto lbl_100;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71020.c b/gcc/testsuite/gcc.dg/torture/pr71020.c
new file mode 100644
index 00000000000..9b22280b8f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71020.c
@@ -0,0 +1,76 @@
+/* { dg-options "-funsafe-math-optimizations" } */
+
+double random_double (void);
+int setjmp (void *);
+void do_something (void);
+
+#define TEST_UNARY(FUNC) \
+ double \
+ FUNC##_dead (void *buffer) \
+ { \
+ double d = random_double (); \
+ setjmp (buffer); \
+ __builtin_##FUNC (d); \
+ d += 1; \
+ do_something (); \
+ return d; \
+ } \
+ \
+ double \
+ FUNC##_live (void *buffer) \
+ { \
+ double d = random_double (); \
+ setjmp (buffer); \
+ d = __builtin_##FUNC (d); \
+ do_something (); \
+ return d; \
+ }
+
+
+#define TEST_BINARY(FUNC) \
+ double \
+ FUNC##_dead (void *buffer) \
+ { \
+ double d1 = random_double (); \
+ double d2 = random_double (); \
+ setjmp (buffer); \
+ __builtin_##FUNC (d1, d2); \
+ d1 += 1; \
+ d2 += 1; \
+ do_something (); \
+ return d1 + d2; \
+ } \
+ \
+ double \
+ FUNC##_live (void *buffer) \
+ { \
+ double d1 = random_double (); \
+ double d2 = random_double (); \
+ setjmp (buffer); \
+ d1 = __builtin_##FUNC (d1, d2); \
+ d2 += 1; \
+ return d1 + d2; \
+ }
+
+TEST_UNARY (acos)
+TEST_UNARY (asin)
+TEST_UNARY (asinh)
+TEST_UNARY (atan)
+TEST_UNARY (atanh)
+TEST_UNARY (cos)
+TEST_UNARY (cosh)
+TEST_UNARY (exp)
+TEST_UNARY (expm1)
+TEST_UNARY (exp2)
+TEST_UNARY (exp10)
+TEST_UNARY (log)
+TEST_UNARY (log2)
+TEST_UNARY (log10)
+TEST_UNARY (log1p)
+TEST_UNARY (significand)
+TEST_UNARY (sin)
+TEST_UNARY (sinh)
+TEST_UNARY (sqrt)
+
+TEST_BINARY (fmod)
+TEST_BINARY (remainder)
diff --git a/gcc/testsuite/gcc.dg/torture/pr71039.c b/gcc/testsuite/gcc.dg/torture/pr71039.c
new file mode 100644
index 00000000000..e169bdca12c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71039.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+
+struct wv
+{
+ int qi;
+} qp, *ft;
+void *pb;
+
+void
+wz (void)
+{
+ struct wv *vf = pb ? (struct wv *)&pb : &qp;
+ *ft = *vf;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71055.c b/gcc/testsuite/gcc.dg/torture/pr71055.c
new file mode 100644
index 00000000000..7fe5a71ce06
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71055.c
@@ -0,0 +1,18 @@
+/* { dg-do run } */
+
+extern void abort (void);
+union U { int i; _Bool b; char c; };
+void __attribute__((noinline,noclone))
+foo (union U *u)
+{
+ if (u->c != 0)
+ abort ();
+}
+int main()
+{
+ union U u;
+ u.i = 10;
+ u.b = 0;
+ foo (&u);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71059.c b/gcc/testsuite/gcc.dg/torture/pr71059.c
new file mode 100644
index 00000000000..7c0ab7f1493
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71059.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+short a, c;
+union {
+ unsigned f0;
+ unsigned short f1;
+} b;
+volatile int d;
+short fn1(short p1) { return p1 + a; }
+void fn2()
+{
+ b.f0 = 0;
+ for (;; b.f0 = fn1(b.f0))
+ (c && b.f1) || d;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71062.c b/gcc/testsuite/gcc.dg/torture/pr71062.c
new file mode 100644
index 00000000000..cc01dda2de4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71062.c
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+char bar;
+
+int __attribute__((noinline,noclone))
+foo (char *__restrict p)
+{
+ if (p == &bar)
+ return 1;
+ return 0;
+}
+
+int main()
+{
+ if (foo (&bar) != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71132.c b/gcc/testsuite/gcc.dg/torture/pr71132.c
new file mode 100644
index 00000000000..2991718ad3a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71132.c
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+
+typedef unsigned size_t;
+struct {
+ unsigned char buf[sizeof(long)];
+} a;
+size_t b;
+int main()
+{
+ size_t c, i;
+ unsigned char *d;
+ for (; c < sizeof(long);)
+ {
+ d = a.buf;
+ b = 0;
+ for (; b < i; b++)
+ *d++ = '\0';
+ for (; c < b; c++)
+ *d++ = 'a';
+ c = 0;
+ for (; i < sizeof(long); i++)
+ ;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr71168.c b/gcc/testsuite/gcc.dg/torture/pr71168.c
new file mode 100644
index 00000000000..fdf4fffc875
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr71168.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+
+int a, b, c;
+long *d;
+void fn1()
+{
+ for (; 0 < a;)
+ a++;
+}
+void fn3()
+{
+ for (; c; c++)
+ d[c] = 0;
+}
+void fn2()
+{
+ if (b)
+ fn3();
+ fn1();
+}
diff --git a/gcc/testsuite/gcc.dg/torture/type-generic-1.c b/gcc/testsuite/gcc.dg/torture/type-generic-1.c
index 38978185827..ef32b78c1a5 100644
--- a/gcc/testsuite/gcc.dg/torture/type-generic-1.c
+++ b/gcc/testsuite/gcc.dg/torture/type-generic-1.c
@@ -3,7 +3,7 @@
/* { dg-do run } */
/* { dg-skip-if "No Inf/NaN support" { spu-*-* } } */
-/* { dg-options "-DUNSAFE" { target tic6x*-*-* visium-*-* } } */
+/* { dg-options "-DUNSAFE" { target tic6x*-*-* visium-*-* nvptx-*-* } } */
/* { dg-add-options ieee } */
#include "../tg-tests.h"
diff --git a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c
index 6da88a898f1..9a600c334ee 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/val-prof-3.c
@@ -27,5 +27,5 @@ main ()
/* { dg-final-use { scan-ipa-dump "Mod subtract transformation on insn" "profile" } } */
/* This is part of code checking that n is greater than the divisor so we are sure that it
didn't get optimized out. */
-/* { dg-final-use { scan-tree-dump "if \\(n_\[0-9\]* \\>" "optimized"} } */
+/* { dg-final-use { scan-tree-dump "if \\(_\[0-9\]* \\< n_\[0-9\]*" "optimized"} } */
/* { dg-final-use { scan-tree-dump-not "Invalid sum" "optimized"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c
index d00acba07e4..501e28cff54 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20040305-1.c
@@ -23,7 +23,7 @@ void foo(int edx, int eax)
/* Verify that we did a forward propagation. */
-/* { dg-final { scan-tree-dump-times "Replaced" 1 "forwprop1"} } */
+/* { dg-final { scan-tree-dump-times "gimple_simplified" 1 "forwprop1"} } */
/* After cddce we should have two IF statements remaining as the other
two tests can be threaded. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/71206.c b/gcc/testsuite/gcc.dg/tree-ssa/71206.c
new file mode 100644
index 00000000000..8e4cd36a24a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/71206.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+
+int f(int d, unsigned b) {
+ int i2 = b ^ 1;
+ int i4 = d ^ 1;
+ return i2 ^ i4;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/and-1.c b/gcc/testsuite/gcc.dg/tree-ssa/and-1.c
new file mode 100644
index 00000000000..276c2b9bd8a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/and-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized-raw" } */
+
+int f(int in) {
+ in = in | 3;
+ in = in ^ 1;
+ in = (in & ~(unsigned long)1);
+ return in;
+}
+
+/* { dg-final { scan-tree-dump-not "bit_and_expr" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/andnot-1.c b/gcc/testsuite/gcc.dg/tree-ssa/andnot-1.c
new file mode 100644
index 00000000000..7f161b672e5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/andnot-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized-raw" } */
+
+unsigned f(unsigned i){
+ i >>= __SIZEOF_INT__ * __CHAR_BIT__ - 3;
+ i = ~i;
+ return i & 7;
+}
+
+/* { dg-final { scan-tree-dump "bit_xor_expr" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "bit_not_expr" "optimized" } } */
+/* { dg-final { scan-tree-dump-not "bit_and_expr" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/bit-assoc.c b/gcc/testsuite/gcc.dg/tree-ssa/bit-assoc.c
new file mode 100644
index 00000000000..b563f5e404c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/bit-assoc.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-forwprop1-details -fdump-tree-ccp1-details" } */
+
+int f1(int a, int b){
+ int c = a & b;
+ return c & b;
+}
+int f2(int a, int b){
+ int c = a | b;
+ return b | c;
+}
+int g1(int a, int b, int c){
+ int d = a & b;
+ int e = b & c;
+ return d & e;
+}
+int g2(int a, int b, int c){
+ int d = a | b;
+ int e = c | b;
+ return d | e;
+}
+int g3(int a, int b, int c){
+ int d = a ^ b;
+ int e = b ^ c;
+ return e ^ d;
+}
+
+/* { dg-final { scan-tree-dump-times "Match-and-simplified" 2 "ccp1" } } */
+/* { dg-final { scan-tree-dump-times "gimple_simplified" 3 "forwprop1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
index a566f1ee6a4..1dabd39e569 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/forwprop-28.c
@@ -84,5 +84,5 @@ test_8 (int code)
the negated code == 22 compare to code != 22 first. It turns out if
we do that we even generate better code on x86 at least. */
-/* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* <" 4 "forwprop1"} } */
+/* { dg-final { scan-tree-dump-times "simplified to if \\\(\[^ ]* \[<>\]" 4 "forwprop1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-10.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-10.c
new file mode 100644
index 00000000000..70b74223892
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-10.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-ifcvt-stats" } */
+/* { dg-require-visibility "" } */
+
+int b[256] = {0}, y;
+void bar (int *);
+int foo (int x, int n)
+{
+ int i;
+ int a[128];
+
+ for (i = 0; i < n; i++)
+ {
+ a[i] = i;
+ if (x > i)
+ b[i] = y;
+ }
+ bar (a);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-11.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-11.c
new file mode 100644
index 00000000000..bacf428ec03
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-11.c
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-ifcvt-stats" } */
+/* { dg-require-visibility "" } */
+
+int a[1024] = {0.0};
+int b[1024] = {0.0};
+int c[1024] = {0.0};
+int foo (float *x)
+{
+ int i = 0;
+
+ for (i = 0; i < 1024; i++)
+ {
+ c[i] = (x[i] > 0.0) ? a[i] : b[i];
+ }
+
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c
new file mode 100644
index 00000000000..89d42b4d6fd
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-12.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-ifcvt-stats" } */
+/* { dg-require-visibility "" } */
+
+struct st
+{
+ int a[1024];
+ int b[1024];
+};
+
+struct st s = {0};
+int foo (int x)
+{
+ int i;
+ struct st *p = &s;
+
+ for (i = 0; i < 1024; i++)
+ {
+ if (x > i)
+ p->a[i] = p->b[i];
+ }
+
+ return 0;
+}
+/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-9.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-9.c
new file mode 100644
index 00000000000..24c19c064f4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-9.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-Ofast -fdump-tree-ifcvt-stats" } */
+/* { dg-require-visibility "" } */
+
+extern int b[256], y;
+void bar (int *, int);
+int foo (int x, int n)
+{
+ int i;
+ int a[128];
+
+ for (i = 0; i < n; i++)
+ {
+ a[i] = i;
+ if (x > i)
+ y = b[i];
+ }
+ bar (a, y);
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-cd.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-cd.c
index f800f72cf69..29e2559e42b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ifc-cd.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-cd.c
@@ -25,4 +25,4 @@ void foo (int *x1, int *x2, int *x3, int *x4, int *y)
}
}
-/* { dg-final { scan-tree-dump-times "Use predicate of bb" 8 "ifcvt" } } */
+/* { dg-final { scan-tree-dump-times "Use predicate of bb" 4 "ifcvt" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr56541.c b/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr56541.c
new file mode 100644
index 00000000000..a52bacacedf
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ifc-pr56541.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-ifcvt-stats" } */
+
+float a,b,c,d;
+
+float z[1024]; int ok[1024];
+const float rBig = 150.;
+
+void foo()
+{
+ int i;
+
+ for (i=0; i!=1024; ++i)
+ {
+ float rR = a*z[i];
+ float rL = b*z[i];
+ float rMin = (rR<rL) ? rR : rL;
+ float rMax = (rR<rL) ? rL : rR;
+ rMin = (rMax>0) ? rMin : rBig;
+ rMin = (rMin>0) ? rMin : rMax;
+ ok[i] = rMin-c<rMax+d;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "Applying if-conversion" 1 "ifcvt" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre10.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre10.c
index 543e1a69294..c6ee35c8d94 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre10.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre10.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */
struct tree_common
{
int code;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre23.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre23.c
index 9fa07315415..42b08f0dfa8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre23.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre23.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */
struct {
int a;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c
index bd7275f76e9..56e4279049c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre24.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */
int a;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre25.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre25.c
index 8418c309616..d1a9e4e105d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre25.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre25.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */
struct X { int i; };
int foo(struct X *a, int argc)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre4.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre4.c
index 2ca7e393cdf..6eaf6901892 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */
int main(int *a, int argc)
{
int i;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c b/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c
index db5937fc031..2abb0d21621 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loadpre8.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats -std=gnu89" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -std=gnu89 -fno-tree-loop-im" } */
typedef union tree_node *tree;
struct tree_common
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr40921.c b/gcc/testsuite/gcc.dg/tree-ssa/pr40921.c
new file mode 100644
index 00000000000..3a5a23a5e54
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr40921.c
@@ -0,0 +1,26 @@
+
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized -ffast-math" } */
+
+unsigned int foo (unsigned int x, unsigned int y, unsigned int z)
+{
+ return x + (-y * z * z);
+}
+
+float bar (float x, float y, float z)
+{
+ return x + (-y * z * z);
+}
+
+float bar2 (float x, float y, float z)
+{
+ return x + (-y * z * z * 5.0f);
+}
+
+float bar3 (float x, float y, float z)
+{
+ return x + (-y * x * -z);
+}
+
+
+/* { dg-final { scan-tree-dump-times "_* = -y_" 0 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr63586-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pr63586-2.c
new file mode 100644
index 00000000000..0dcfe327358
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr63586-2.c
@@ -0,0 +1,32 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math -fdump-tree-reassoc1" } */
+
+float f1_float (float x, float z)
+{
+ float y = x + z;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ return y;
+}
+
+float f1_float2 (float x)
+{
+ float y = x + 3 * x + x;
+ return y;
+}
+
+int f1_int (int x)
+{
+ int y = x + 4 * x + x;
+ return y;
+}
+
+/* { dg-final { scan-tree-dump-times "\\\* 8\\\.0e\\\+0" 1 "reassoc1" } } */
+/* { dg-final { scan-tree-dump-times "\\\* 5\\\.0e\\\+0" 1 "reassoc1" } } */
+/* { dg-final { scan-tree-dump-times "\\\* 6" 1 "reassoc1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr63586.c b/gcc/testsuite/gcc.dg/tree-ssa/pr63586.c
new file mode 100644
index 00000000000..470be8cea9e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr63586.c
@@ -0,0 +1,70 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-reassoc1" } */
+
+unsigned f1 (unsigned x, unsigned z)
+{
+ unsigned y = x + z;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ return y;
+}
+
+/* { dg-final { scan-tree-dump-times "\\\* 7" 1 "reassoc1" } } */
+
+unsigned f2 (unsigned x, unsigned z)
+{
+ unsigned y = x + z;
+ y = y + x;
+ y = y + x;
+ y = y + x;
+ y = y + z;
+ y = y + z;
+ y = y + z;
+ y = y + z;
+ return y;
+}
+
+/* { dg-final { scan-tree-dump-times "\\\* 5" 1 "reassoc1" } } */
+/* { dg-final { scan-tree-dump-times "\\\* 4" 1 "reassoc1" } } */
+
+unsigned f3 (unsigned x, unsigned z, unsigned k)
+{
+ unsigned y = x + z;
+ y = y + x;
+ y = y + z;
+ y = y + z;
+ y = y + k;
+ return y;
+}
+
+/* { dg-final { scan-tree-dump-times "\\\* 2" 1 "reassoc1" } } */
+/* { dg-final { scan-tree-dump-times "\\\* 3" 1 "reassoc1" } } */
+
+unsigned f4 (unsigned x, unsigned z, unsigned k)
+{
+ unsigned y = k + x;
+ y = y + z;
+ y = y + z;
+ y = y + z;
+ y = y + z;
+ y = y + z;
+ y = y + z;
+ y = y + z;
+ y = y + z;
+ return y;
+}
+/* { dg-final { scan-tree-dump-times "\\\* 8" 1 "reassoc1" } } */
+
+unsigned f5 (unsigned x, unsigned y, unsigned z)
+{
+ return x + y + y + y + y + y \
+ + y + z + z + z + z + z + z + z + z + z;
+}
+
+/* { dg-final { scan-tree-dump-times "\\\* 6" 1 "reassoc1" } } */
+/* { dg-final { scan-tree-dump-times "\\\* 9" 1 "reassoc1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c b/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c
index 529b5212a27..0d66cc4383f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr69270.c
@@ -7,8 +7,8 @@
/* { dg-final { scan-tree-dump-times "Replaced .bufferstep_\[0-9\]+. with constant .1." 1 "dom3"} } */
/* And some assignments ought to fold down to constants. */
-/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 1;" 2 "dom3"} } */
-/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 0;" 2 "dom3"} } */
+/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 1;" 1 "dom3"} } */
+/* { dg-final { scan-tree-dump-times "Folded to: _\[0-9\]+ = 0;" 1 "dom3"} } */
/* The XOR operations should have been optimized to constants. */
/* { dg-final { scan-tree-dump-not "bit_xor" "dom3"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr70919.c b/gcc/testsuite/gcc.dg/tree-ssa/pr70919.c
new file mode 100644
index 00000000000..bed0ab37a20
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr70919.c
@@ -0,0 +1,46 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+#pragma pack(1)
+struct S0
+{
+ int f0:24;
+};
+
+struct S1
+{
+ int f1;
+} a;
+
+int b, c;
+
+char
+fn1 (struct S1 p1)
+{
+ return 0;
+}
+
+int
+main ()
+{
+ c = fn1 (a);
+ if (b)
+ {
+ struct S0 f[3][9] =
+ { { { 0 }, { 0 }, { 1 }, { 1 }, { 0 }, { 0 }, { 0 }, { 1 }, { 1 } },
+ { { 0 }, { 0 }, { 1 }, { 1 }, { 0 }, { 0 }, { 0 }, { 1 }, { 1 } },
+ { { 0 }, { 0 }, { 1 }, { 1 }, { 0 }, { 0 }, { 0 }, { 1 }, { 1 } }
+ };
+ b = f[1][8].f0;
+ }
+ struct S0 g[3][9] =
+ { { { 0 }, { 0 }, { 1 }, { 1 }, { 0 }, { 0 }, { 0 }, { 1 }, { 1 } },
+ { { 0 }, { 0 }, { 1 }, { 1 }, { 0 }, { 0 }, { 0 }, { 1 }, { 1 } },
+ { { 0 }, { 0 }, { 1 }, { 1 }, { 0 }, { 0 }, { 0 }, { 1 }, { 1 } }
+ };
+
+ if (g[1][8].f0 != 1)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71179.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71179.c
new file mode 100644
index 00000000000..885c643b927
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71179.c
@@ -0,0 +1,10 @@
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -ffast-math" } */
+
+typedef float __m128 __attribute__ ((__vector_size__ (16), __may_alias__));
+
+__m128 foo (__m128 a)
+{
+ return a + a;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr71185.c b/gcc/testsuite/gcc.dg/tree-ssa/pr71185.c
new file mode 100644
index 00000000000..c2e246f1cd0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr71185.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+/* { dg-options "-O3 -march=barcelona" { target x86_64-*-* i?86-*-* } } */
+
+union U { struct S { int l; int m; } p; long long a; } b;
+int a, c;
+
+void
+foo ()
+{
+ for (; b.p.m; b.a += c)
+ a = b.p.l / 65536.0 * 65536.0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c
index f2b1d08d0ec..fc2c267b178 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/prefetch-5.c
@@ -54,5 +54,7 @@ int loop5 (int n, struct tail5 *x)
return s;
}
-/* { dg-final { scan-tree-dump-times "Issued prefetch" 2 "aprefetch" } } */
-/* { dg-final { scan-tree-dump-times "Not prefetching" 1 "aprefetch" } } */
+/* Until we are able to track likely upper bounds, we can't really work out that
+ small trailing arrays should not be prefetched. */
+/* { dg-final { scan-tree-dump-times "Issued prefetch" 2 "aprefetch" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "Not prefetching" 1 "aprefetch" { xfail *-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-14.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-14.c
index 62802d16ed3..16ebc86133f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-14.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-14.c
@@ -19,6 +19,7 @@ unsigned int test2 (unsigned int x, unsigned int y, unsigned int z,
return tmp1 + tmp2 + tmp3;
}
-/* There should be one multiplication left in test1 and three in test2. */
+/* There should be two multiplication left in test1 (inculding one generated
+ when converting addition to multiplication) and three in test2. */
-/* { dg-final { scan-tree-dump-times "\\\*" 4 "reassoc1" } } */
+/* { dg-final { scan-tree-dump-times "\\\*" 5 "reassoc1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c
index 1a837666c25..89cddcd7486 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-43.c
@@ -1,6 +1,6 @@
/* PR tree-optimization/64193 */
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-fre1-details" } */
+/* { dg-options "-O -fdump-tree-fre1" } */
double T,T2,E1[5];
int J;
@@ -24,5 +24,4 @@ L10:
/* We should remove 15 dead loads and some related stmts, fully propagating
their replacements with exactly 4 loads and 4 stores from/to E remaining. */
-/* { dg-final { scan-tree-dump-times "Removing dead stmt" 19 "fre1" } } */
-/* { dg-final { scan-tree-dump-not "Not changing value number" "fre1" } } */
+/* { dg-final { scan-tree-dump-times "MEM" 8 "fre1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-54.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-54.c
new file mode 100644
index 00000000000..be7537e80c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-54.c
@@ -0,0 +1,56 @@
+/* { dg-do run } */
+/* { dg-require-effective-target int32plus } */
+/* { dg-options "-O -fdump-tree-fre1 -fdump-tree-dse1" } */
+
+extern void abort (void);
+
+union U { int i; char c[4]; short s[2]; };
+
+char __attribute__((noinline,noclone)) foo(int i)
+{
+ union U u;
+ u.i = i;
+ /* This should be equivalent to (char) i. */
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ return u.c[0];
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ return u.c[3];
+#else
+ return 0x04;
+#endif
+}
+
+short __attribute__((noinline,noclone)) baz(int i)
+{
+ union U u;
+ u.i = i;
+ /* This should be equivalent to (char) i. */
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+ return u.s[0];
+#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ return u.s[1];
+#else
+ return 0x0304;
+#endif
+}
+
+char __attribute__((noinline,noclone)) bar(int j)
+{
+ union U u;
+ u.i = j;
+ /* This gets simplified to a BIT_FIELD_REF. */
+ return u.c[2];
+}
+
+int main()
+{
+ if (foo (0x01020304) != 0x04)
+ abort ();
+ if (baz (0x01020304) != 0x0304)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-tree-dump "\\(char\\) i_" "fre1" } } */
+/* { dg-final { scan-tree-dump "\\(short int\\) i_" "fre1" } } */
+/* { dg-final { scan-tree-dump-not "u.i =" "dse1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-55.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-55.c
new file mode 100644
index 00000000000..7bfa2847878
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-55.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+typedef int v4si __attribute__((vector_size(16)));
+
+int f(v4si t)
+{
+ union {
+ v4si t1;
+ int t2[4];
+ } u;
+ u.t1 = t;
+ return u.t2[1];
+}
+
+/* { dg-final { scan-tree-dump-not "u;" "optimized" } } */
+/* { dg-final { scan-tree-dump-times "BIT_FIELD_REF" 1 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c
index f2ec5d7eda2..69cc517f9de 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-16.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats -std=c99" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -std=c99 -fno-tree-loop-im" } */
int foo(int k, int *x)
{
int j=0;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-18.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-18.c
index 483f8228260..ea2a7aee56b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-18.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-18.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-details" } */
+/* { dg-options "-O2 -fdump-tree-pre-details -fno-tree-loop-im" } */
struct Bar { int a; int b; };
struct Foo { int x; struct Bar y; };
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c
index c8a23df8310..39ed2efb7c5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-20.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */
double pcheck;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c
index ba2c8eaaa8d..7e319ed2fbd 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-pre-stats" } */
+/* { dg-options "-O2 -fdump-tree-pre-stats -fno-tree-loop-im" } */
unsigned foo1 (unsigned a, unsigned b, unsigned j, unsigned k)
{
unsigned i;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-store-ccp-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-store-ccp-2.c
index cdc042061ec..51fc1b3d261 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-store-ccp-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-store-ccp-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fcommon" } */
const int conststaticvariable;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c
index db9ed3bb039..e2ac2f76c0b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-thread-14.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-additional-options "-O2 -fdump-tree-vrp" } */
+/* { dg-additional-options "-O2 -fdump-tree-vrp-details" } */
/* { dg-final { scan-tree-dump-times "Threaded jump" 8 "vrp1" } } */
void foo (void);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/unord.c b/gcc/testsuite/gcc.dg/tree-ssa/unord.c
new file mode 100644
index 00000000000..e0927925d5a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/unord.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-optimized" } */
+
+int f(double a){double b=a;return !__builtin_islessequal(a,b);}
+int g(double a){double b=a;return !__builtin_isgreaterequal(a,b);}
+
+/* { dg-final { scan-tree-dump-times " unord " 2 "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c
new file mode 100644
index 00000000000..785e5dfe424
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-6.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O -fdump-tree-ccp1 -Wno-psabi -w" } */
+/* { dg-additional-options "-msse2" { target i?86-*-* x86_64-*-* } } */
+/* { dg-additional-options "-maltivec" { target powerpc_altivec_ok } } */
+
+typedef int v4si __attribute__((vector_size (4 * sizeof (int))));
+
+v4si test1 (v4si v, int i)
+{
+ ((int *)&v)[0] = i;
+ return v;
+}
+
+v4si test2 (v4si v, int i)
+{
+ int *p = (int *)&v;
+ *p = i;
+ return v;
+}
+
+v4si test3 (v4si v, int i)
+{
+ ((int *)&v)[3] = i;
+ return v;
+}
+
+v4si test4 (v4si v, int i)
+{
+ int *p = (int *)&v;
+ p += 3;
+ *p = i;
+ return v;
+}
+
+/* { dg-final { scan-tree-dump-times "Now a gimple register: v" 4 "ccp1" { target { { i?86-*-* x86_64-*-* aarch64*-*-* spu*-*-* } || { powerpc_altivec_ok } } } } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp100.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
new file mode 100644
index 00000000000..c0fe4b50963
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp100.c
@@ -0,0 +1,32 @@
+/* PR tree-optimization/71031 */
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+int zj;
+int **yr;
+
+void
+nn (void)
+{
+ unsigned int od = 4;
+
+ for (;;)
+ {
+ int lk;
+
+ for (lk = 0; lk < 2; ++lk)
+ {
+ static int cm;
+
+ zj = 0;
+ if (od == 0)
+ return;
+ ++od;
+ for (cm = 0; cm < 2; ++cm)
+ {
+ --od;
+ **yr = 0;
+ }
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp59.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp59.c
index 0f5801dd785..5f6e9d956f0 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp59.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp59.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-tree-ccp -fdump-tree-vrp1" } */
+/* { dg-options "-O2 -fno-tree-ccp -fno-tree-forwprop -fdump-tree-vrp1" } */
int f(int x)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp99.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp99.c
new file mode 100644
index 00000000000..baa7a706fd9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp99.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1" } */
+
+unsigned f(unsigned i){
+ i >>= __SIZEOF_INT__ * __CHAR_BIT__ - 1;
+ return i == 0;
+}
+
+/* { dg-final { scan-tree-dump-not "\\(unsigned int\\)" "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/bounds-3.c b/gcc/testsuite/gcc.dg/ubsan/bounds-3.c
new file mode 100644
index 00000000000..50ad67389f8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/bounds-3.c
@@ -0,0 +1,22 @@
+/* PR sanitizer/70875 */
+/* { dg-do run } */
+/* { dg-options "-fsanitize=bounds" } */
+
+int
+foo (int n, int k)
+{
+ struct S
+ {
+ int i[n];
+ int value;
+ } s[2];
+ return s[k].value = 0;
+}
+
+int
+main ()
+{
+ return foo (2, 2);
+}
+
+/* { dg-output "index 2 out of bounds for type 'S \\\[2\\\]'" } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
index 42cd2949575..c2821551c86 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
@@ -53,5 +53,5 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr56541.c b/gcc/testsuite/gcc.dg/vect/pr56541.c
new file mode 100644
index 00000000000..16b8d7cb75b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr56541.c
@@ -0,0 +1,27 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+/* { dg-require-effective-target vect_float } */
+/* { dg-require-effective-target vect_condition } */
+
+float a,b,c,d;
+
+float z[1024]; int ok[1024];
+const float rBig = 150.;
+
+void foo()
+{
+ int i;
+
+ for (i=0; i!=1024; ++i)
+ {
+ float rR = a*z[i];
+ float rL = b*z[i];
+ float rMin = (rR<rL) ? rR : rL;
+ float rMax = (rR<rL) ? rL : rR;
+ rMin = (rMax>0) ? rMin : rBig;
+ rMin = (rMin>0) ? rMin : rMax;
+ ok[i] = rMin-c<rMax+d;
+ }
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr57206.c b/gcc/testsuite/gcc.dg/vect/pr57206.c
new file mode 100644
index 00000000000..009688e93b0
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr57206.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_float } */
+
+void bad0(float * d, unsigned int n)
+{
+ unsigned int i;
+ for (i=n; i>0; --i)
+ d[n-i] = 0.0;
+}
+
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr58135.c b/gcc/testsuite/gcc.dg/vect/pr58135.c
new file mode 100644
index 00000000000..ca250000c85
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/pr58135.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target vect_int } */
+
+int a[100];
+void foo ()
+{
+ a[0] = a[1] = a[2] = a[3] = a[4]= 0;
+}
+
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr61194.c b/gcc/testsuite/gcc.dg/vect/pr61194.c
index 8d74e009694..f7c71b91b48 100644
--- a/gcc/testsuite/gcc.dg/vect/pr61194.c
+++ b/gcc/testsuite/gcc.dg/vect/pr61194.c
@@ -38,4 +38,4 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr66636.c b/gcc/testsuite/gcc.dg/vect/pr66636.c
index 7e6e5f6752e..c0733ffa5a3 100644
--- a/gcc/testsuite/gcc.dg/vect/pr66636.c
+++ b/gcc/testsuite/gcc.dg/vect/pr66636.c
@@ -6,7 +6,8 @@ extern void abort (void);
struct X { double x; double y; };
-void foo (struct X *x, double px, int s)
+void __attribute__((noinline,noclone))
+foo (struct X *x, double px, int s)
{
int i;
for (i = 0; i < 256; ++i)
diff --git a/gcc/testsuite/gcc.dg/vect/section-anchors-vect-70.c b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-70.c
new file mode 100644
index 00000000000..7010a52b58d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-70.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target section_anchors } */
+/* { dg-require-effective-target vect_int } */
+
+#define N 32
+
+/* Increase alignment of struct if an array's offset is multiple of alignment of
+ vector type corresponding to it's scalar type.
+ For the below test-case:
+ offsetof(e) == 8 bytes.
+ i) For arm: let x = alignment of vector type corresponding to int,
+ x == 8 bytes.
+ Since offsetof(e) % x == 0, set DECL_ALIGN(a, b, c) to x.
+ ii) For aarch64, ppc: x == 16 bytes.
+ Since offsetof(e) % x != 0, don't increase alignment of a, b, c.
+*/
+
+static struct A {
+ int p1, p2;
+ int e[N];
+} a, b, c;
+
+int foo(void)
+{
+ for (int i = 0; i < N; i++)
+ a.e[i] = b.e[i] + c.e[i];
+
+ return a.e[0];
+}
+
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 0 "increase_alignment" { target aarch64*-*-* } } } */
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 0 "increase_alignment" { target powerpc64*-*-* } } } */
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 3 "increase_alignment" { target arm*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/section-anchors-vect-71.c b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-71.c
new file mode 100644
index 00000000000..7cbd1dcf304
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-71.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target section_anchors } */
+/* { dg-require-effective-target vect_int } */
+
+/* Should not increase alignment of the struct because
+ sizeof (A.e) < sizeof(corresponding vector type). */
+
+#define N 3
+
+static struct A {
+ int p1, p2;
+ int e[N];
+} a, b, c;
+
+int foo(void)
+{
+ for (int i = 0; i < N; i++)
+ a.e[i] = b.e[i] + c.e[i];
+
+ return a.e[0];
+}
+
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 0 "increase_alignment" { target aarch64*-*-* } } } */
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 0 "increase_alignment" { target powerpc64*-*-* } } } */
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 0 "increase_alignment" { target arm*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/section-anchors-vect-72.c b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-72.c
new file mode 100644
index 00000000000..873fabe9f52
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/vect/section-anchors-vect-72.c
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target section_anchors } */
+/* { dg-require-effective-target vect_int } */
+
+#define N 32
+
+/* Clone of section-anchors-vect-70.c having nested struct. */
+
+struct S
+{
+ int e[N];
+};
+
+static struct A {
+ int p1, p2;
+ struct S s;
+} a, b, c;
+
+int foo(void)
+{
+ for (int i = 0; i < N; i++)
+ a.s.e[i] = b.s.e[i] + c.s.e[i];
+
+ return a.s.e[0];
+}
+
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 0 "increase_alignment" { target aarch64*-*-* } } } */
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 0 "increase_alignment" { target powerpc64*-*-* } } } */
+/* { dg-final { scan-ipa-dump-times "Increasing alignment of decl" 3 "increase_alignment" { target arm*-*-* } } } */
diff --git a/gcc/testsuite/gcc.dg/vect/tree-vect.h b/gcc/testsuite/gcc.dg/vect/tree-vect.h
index 0853e3f76be..faf91d51238 100644
--- a/gcc/testsuite/gcc.dg/vect/tree-vect.h
+++ b/gcc/testsuite/gcc.dg/vect/tree-vect.h
@@ -32,25 +32,26 @@ check_vect (void)
asm volatile (".long 0x10000484");
#elif defined(__i386__) || defined(__x86_64__)
{
- unsigned int a, b, c, d, want_level, want_c, want_d;
+ unsigned int a, b, c, d,
+ want_level, want_b = 0, want_c = 0, want_d = 0;
/* Determine what instruction set we've been compiled for, and detect
that we're running with it. This allows us to at least do a compile
check for, e.g. SSE4.1 when the machine only supports SSE2. */
-# ifdef __XOP__
- want_level = 0x80000001, want_c = bit_XOP, want_d = 0;
+# if defined(__AVX2__)
+ want_level = 7, want_b = bit_AVX2;
# elif defined(__AVX__)
- want_level = 1, want_c = bit_AVX, want_d = 0;
+ want_level = 1, want_c = bit_AVX;
# elif defined(__SSE4_1__)
- want_level = 1, want_c = bit_SSE4_1, want_d = 0;
+ want_level = 1, want_c = bit_SSE4_1;
# elif defined(__SSSE3__)
- want_level = 1, want_c = bit_SSSE3, want_d = 0;
+ want_level = 1, want_c = bit_SSSE3;
# else
- want_level = 1, want_c = 0, want_d = bit_SSE2;
+ want_level = 1, want_d = bit_SSE2;
# endif
if (!__get_cpuid (want_level, &a, &b, &c, &d)
- || ((c & want_c) | (d & want_d)) == 0)
+ || ((b & want_b) | (c & want_c) | (d & want_d)) == 0)
exit (0);
}
#elif defined(__sparc__)
diff --git a/gcc/testsuite/gcc.dg/vect/vect-23.c b/gcc/testsuite/gcc.dg/vect/vect-23.c
index 44bed755fd3..e463f1b5cc9 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-23.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-23.c
@@ -123,5 +123,5 @@ int main (void)
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 3 loops" 1 "vect" } } */
/* { dg-final { scan-tree-dump-times "Vectorizing an unaligned access" 0 "vect" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/vect-mask-store-move-1.c b/gcc/testsuite/gcc.dg/vect/vect-mask-store-move-1.c
index f5cae4fcf75..f928dbf4c21 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-mask-store-move-1.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-mask-store-move-1.c
@@ -15,4 +15,4 @@ void foo (int n)
}
}
-/* { dg-final { scan-tree-dump-times "Move stmt to created bb" 6 "vect" { target { i?86-*-* x86_64-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "Move stmt to created bb" 4 "vect" { target { i?86-*-* x86_64-*-* } } } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h
index 49fbd843e50..3363a720862 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/arm-neon-ref.h
@@ -81,7 +81,7 @@ extern size_t strlen(const char *);
abort(); \
} \
} \
- fprintf(stderr, "CHECKED %s\n", MSG); \
+ fprintf(stderr, "CHECKED %s %s\n", STR(VECT_TYPE(T, W, N)), MSG); \
}
/* Floating-point variant. */
@@ -110,7 +110,7 @@ extern size_t strlen(const char *);
abort(); \
} \
} \
- fprintf(stderr, "CHECKED %s\n", MSG); \
+ fprintf(stderr, "CHECKED %s %s\n", STR(VECT_TYPE(T, W, N)), MSG); \
}
/* Clean buffer with a non-zero pattern to help diagnose buffer
@@ -133,10 +133,16 @@ static ARRAY(result, uint, 32, 2);
static ARRAY(result, uint, 64, 1);
static ARRAY(result, poly, 8, 8);
static ARRAY(result, poly, 16, 4);
+#if defined (__ARM_FEATURE_CRYPTO)
+static ARRAY(result, poly, 64, 1);
+#endif
#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
static ARRAY(result, float, 16, 4);
#endif
static ARRAY(result, float, 32, 2);
+#ifdef __aarch64__
+static ARRAY(result, float, 64, 1);
+#endif
static ARRAY(result, int, 8, 16);
static ARRAY(result, int, 16, 8);
static ARRAY(result, int, 32, 4);
@@ -147,6 +153,9 @@ static ARRAY(result, uint, 32, 4);
static ARRAY(result, uint, 64, 2);
static ARRAY(result, poly, 8, 16);
static ARRAY(result, poly, 16, 8);
+#if defined (__ARM_FEATURE_CRYPTO)
+static ARRAY(result, poly, 64, 2);
+#endif
#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
static ARRAY(result, float, 16, 8);
#endif
@@ -169,6 +178,7 @@ extern ARRAY(expected, poly, 8, 8);
extern ARRAY(expected, poly, 16, 4);
extern ARRAY(expected, hfloat, 16, 4);
extern ARRAY(expected, hfloat, 32, 2);
+extern ARRAY(expected, hfloat, 64, 1);
extern ARRAY(expected, int, 8, 16);
extern ARRAY(expected, int, 16, 8);
extern ARRAY(expected, int, 32, 4);
@@ -335,7 +345,8 @@ extern int VECT_VAR(expected_cumulative_sat, uint, 64, 2);
strlen(COMMENT) > 0 ? " " COMMENT : ""); \
abort(); \
} \
- fprintf(stderr, "CHECKED CUMULATIVE SAT %s\n", MSG); \
+ fprintf(stderr, "CHECKED CUMULATIVE SAT %s %s\n", \
+ STR(VECT_TYPE(T, W, N)), MSG); \
}
#define CHECK_CUMULATIVE_SAT_NAMED(test_name,EXPECTED,comment) \
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/compute-ref-data.h b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/compute-ref-data.h
index c8d43367bef..f8c4aefeec9 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/compute-ref-data.h
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/compute-ref-data.h
@@ -118,6 +118,10 @@ VECT_VAR_DECL_INIT(buffer, uint, 32, 2);
PAD(buffer_pad, uint, 32, 2);
VECT_VAR_DECL_INIT(buffer, uint, 64, 1);
PAD(buffer_pad, uint, 64, 1);
+#if defined (__ARM_FEATURE_CRYPTO)
+VECT_VAR_DECL_INIT(buffer, poly, 64, 1);
+PAD(buffer_pad, poly, 64, 1);
+#endif
#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
VECT_VAR_DECL_INIT(buffer, float, 16, 4);
PAD(buffer_pad, float, 16, 4);
@@ -144,6 +148,10 @@ VECT_VAR_DECL_INIT(buffer, poly, 8, 16);
PAD(buffer_pad, poly, 8, 16);
VECT_VAR_DECL_INIT(buffer, poly, 16, 8);
PAD(buffer_pad, poly, 16, 8);
+#if defined (__ARM_FEATURE_CRYPTO)
+VECT_VAR_DECL_INIT(buffer, poly, 64, 2);
+PAD(buffer_pad, poly, 64, 2);
+#endif
#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
VECT_VAR_DECL_INIT(buffer, float, 16, 8);
PAD(buffer_pad, float, 16, 8);
@@ -178,6 +186,10 @@ VECT_VAR_DECL_INIT(buffer_dup, poly, 8, 8);
VECT_VAR_DECL(buffer_dup_pad, poly, 8, 8);
VECT_VAR_DECL_INIT(buffer_dup, poly, 16, 4);
VECT_VAR_DECL(buffer_dup_pad, poly, 16, 4);
+#if defined (__ARM_FEATURE_CRYPTO)
+VECT_VAR_DECL_INIT4(buffer_dup, poly, 64, 1);
+VECT_VAR_DECL(buffer_dup_pad, poly, 64, 1);
+#endif
#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
VECT_VAR_DECL_INIT4(buffer_dup, float, 16, 4);
VECT_VAR_DECL(buffer_dup_pad, float, 16, 4);
@@ -205,6 +217,10 @@ VECT_VAR_DECL_INIT(buffer_dup, poly, 8, 16);
VECT_VAR_DECL(buffer_dup_pad, poly, 8, 16);
VECT_VAR_DECL_INIT(buffer_dup, poly, 16, 8);
VECT_VAR_DECL(buffer_dup_pad, poly, 16, 8);
+#if defined (__ARM_FEATURE_CRYPTO)
+VECT_VAR_DECL_INIT4(buffer_dup, poly, 64, 2);
+VECT_VAR_DECL(buffer_dup_pad, poly, 64, 2);
+#endif
#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
VECT_VAR_DECL_INIT(buffer_dup, float, 16, 8);
VECT_VAR_DECL(buffer_dup_pad, float, 16, 8);
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/p64_p128.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/p64_p128.c
new file mode 100644
index 00000000000..ced3884de52
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/p64_p128.c
@@ -0,0 +1,665 @@
+/* This file contains tests for all the *p64 intrinsics, except for
+ vreinterpret which have their own testcase. */
+
+/* { dg-require-effective-target arm_crypto_ok } */
+/* { dg-add-options arm_crypto } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results: vbsl. */
+VECT_VAR_DECL(vbsl_expected,poly,64,1) [] = { 0xfffffff1 };
+VECT_VAR_DECL(vbsl_expected,poly,64,2) [] = { 0xfffffff1,
+ 0xfffffff1 };
+
+/* Expected results: vceq. */
+VECT_VAR_DECL(vceq_expected,uint,64,1) [] = { 0x0 };
+
+/* Expected results: vcombine. */
+VECT_VAR_DECL(vcombine_expected,poly,64,2) [] = { 0xfffffffffffffff0, 0x88 };
+
+/* Expected results: vcreate. */
+VECT_VAR_DECL(vcreate_expected,poly,64,1) [] = { 0x123456789abcdef0 };
+
+/* Expected results: vdup_lane. */
+VECT_VAR_DECL(vdup_lane_expected,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vdup_lane_expected,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff0 };
+
+/* Expected results: vdup_n. */
+VECT_VAR_DECL(vdup_n_expected0,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vdup_n_expected0,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff0 };
+VECT_VAR_DECL(vdup_n_expected1,poly,64,1) [] = { 0xfffffffffffffff1 };
+VECT_VAR_DECL(vdup_n_expected1,poly,64,2) [] = { 0xfffffffffffffff1,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vdup_n_expected2,poly,64,1) [] = { 0xfffffffffffffff2 };
+VECT_VAR_DECL(vdup_n_expected2,poly,64,2) [] = { 0xfffffffffffffff2,
+ 0xfffffffffffffff2 };
+
+/* Expected results: vext. */
+VECT_VAR_DECL(vext_expected,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vext_expected,poly,64,2) [] = { 0xfffffffffffffff1, 0x88 };
+
+/* Expected results: vget_low. */
+VECT_VAR_DECL(vget_low_expected,poly,64,1) [] = { 0xfffffffffffffff0 };
+
+/* Expected results: vld1. */
+VECT_VAR_DECL(vld1_expected,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld1_expected,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+
+/* Expected results: vld1_dup. */
+VECT_VAR_DECL(vld1_dup_expected0,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld1_dup_expected0,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld1_dup_expected1,poly,64,1) [] = { 0xfffffffffffffff1 };
+VECT_VAR_DECL(vld1_dup_expected1,poly,64,2) [] = { 0xfffffffffffffff1,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vld1_dup_expected2,poly,64,1) [] = { 0xfffffffffffffff2 };
+VECT_VAR_DECL(vld1_dup_expected2,poly,64,2) [] = { 0xfffffffffffffff2,
+ 0xfffffffffffffff2 };
+
+/* Expected results: vld1_lane. */
+VECT_VAR_DECL(vld1_lane_expected,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld1_lane_expected,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xaaaaaaaaaaaaaaaa };
+
+/* Expected results: vldX. */
+VECT_VAR_DECL(vld2_expected_0,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld2_expected_1,poly,64,1) [] = { 0xfffffffffffffff1 };
+VECT_VAR_DECL(vld3_expected_0,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld3_expected_1,poly,64,1) [] = { 0xfffffffffffffff1 };
+VECT_VAR_DECL(vld3_expected_2,poly,64,1) [] = { 0xfffffffffffffff2 };
+VECT_VAR_DECL(vld4_expected_0,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld4_expected_1,poly,64,1) [] = { 0xfffffffffffffff1 };
+VECT_VAR_DECL(vld4_expected_2,poly,64,1) [] = { 0xfffffffffffffff2 };
+VECT_VAR_DECL(vld4_expected_3,poly,64,1) [] = { 0xfffffffffffffff3 };
+
+/* Expected results: vldX_dup. */
+VECT_VAR_DECL(vld2_dup_expected_0,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld2_dup_expected_1,poly,64,1) [] = { 0xfffffffffffffff1 };
+VECT_VAR_DECL(vld3_dup_expected_0,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld3_dup_expected_1,poly,64,1) [] = { 0xfffffffffffffff1 };
+VECT_VAR_DECL(vld3_dup_expected_2,poly,64,1) [] = { 0xfffffffffffffff2 };
+VECT_VAR_DECL(vld4_dup_expected_0,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vld4_dup_expected_1,poly,64,1) [] = { 0xfffffffffffffff1 };
+VECT_VAR_DECL(vld4_dup_expected_2,poly,64,1) [] = { 0xfffffffffffffff2 };
+VECT_VAR_DECL(vld4_dup_expected_3,poly,64,1) [] = { 0xfffffffffffffff3 };
+
+/* Expected results: vsli. */
+VECT_VAR_DECL(vsli_expected,poly,64,1) [] = { 0x10 };
+VECT_VAR_DECL(vsli_expected,poly,64,2) [] = { 0x7ffffffffffff0,
+ 0x7ffffffffffff1 };
+VECT_VAR_DECL(vsli_expected_max_shift,poly,64,1) [] = { 0x7ffffffffffffff0 };
+VECT_VAR_DECL(vsli_expected_max_shift,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+
+/* Expected results: vsri. */
+VECT_VAR_DECL(vsri_expected,poly,64,1) [] = { 0xe000000000000000 };
+VECT_VAR_DECL(vsri_expected,poly,64,2) [] = { 0xfffffffffffff800,
+ 0xfffffffffffff800 };
+VECT_VAR_DECL(vsri_expected_max_shift,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vsri_expected_max_shift,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+
+/* Expected results: vst1_lane. */
+VECT_VAR_DECL(vst1_lane_expected,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vst1_lane_expected,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0x3333333333333333 };
+
+int main (void)
+{
+ int i;
+
+ /* vbsl_p64 tests. */
+#define TEST_MSG "VBSL/VBSLQ"
+
+#define TEST_VBSL(T3, Q, T1, T2, W, N) \
+ VECT_VAR(vbsl_vector_res, T1, W, N) = \
+ vbsl##Q##_##T2##W(VECT_VAR(vbsl_vector_first, T3, W, N), \
+ VECT_VAR(vbsl_vector, T1, W, N), \
+ VECT_VAR(vbsl_vector2, T1, W, N)); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vbsl_vector_res, T1, W, N))
+
+ DECL_VARIABLE(vbsl_vector, poly, 64, 1);
+ DECL_VARIABLE(vbsl_vector, poly, 64, 2);
+ DECL_VARIABLE(vbsl_vector2, poly, 64, 1);
+ DECL_VARIABLE(vbsl_vector2, poly, 64, 2);
+ DECL_VARIABLE(vbsl_vector_res, poly, 64, 1);
+ DECL_VARIABLE(vbsl_vector_res, poly, 64, 2);
+
+ DECL_VARIABLE(vbsl_vector_first, uint, 64, 1);
+ DECL_VARIABLE(vbsl_vector_first, uint, 64, 2);
+
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ VLOAD(vbsl_vector, buffer, , poly, p, 64, 1);
+ VLOAD(vbsl_vector, buffer, q, poly, p, 64, 2);
+
+ VDUP(vbsl_vector2, , poly, p, 64, 1, 0xFFFFFFF3);
+ VDUP(vbsl_vector2, q, poly, p, 64, 2, 0xFFFFFFF3);
+
+ VDUP(vbsl_vector_first, , uint, u, 64, 1, 0xFFFFFFF2);
+ VDUP(vbsl_vector_first, q, uint, u, 64, 2, 0xFFFFFFF2);
+
+ TEST_VBSL(uint, , poly, p, 64, 1);
+ TEST_VBSL(uint, q, poly, p, 64, 2);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vbsl_expected, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vbsl_expected, "");
+
+ /* vceq_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VCEQ"
+
+#define TEST_VCOMP1(INSN, Q, T1, T2, T3, W, N) \
+ VECT_VAR(vceq_vector_res, T3, W, N) = \
+ INSN##Q##_##T2##W(VECT_VAR(vceq_vector, T1, W, N), \
+ VECT_VAR(vceq_vector2, T1, W, N)); \
+ vst1##Q##_u##W(VECT_VAR(result, T3, W, N), VECT_VAR(vceq_vector_res, T3, W, N))
+
+#define TEST_VCOMP(INSN, Q, T1, T2, T3, W, N) \
+ TEST_VCOMP1(INSN, Q, T1, T2, T3, W, N)
+
+ DECL_VARIABLE(vceq_vector, poly, 64, 1);
+ DECL_VARIABLE(vceq_vector2, poly, 64, 1);
+ DECL_VARIABLE(vceq_vector_res, uint, 64, 1);
+
+ CLEAN(result, uint, 64, 1);
+
+ VLOAD(vceq_vector, buffer, , poly, p, 64, 1);
+
+ VDUP(vceq_vector2, , poly, p, 64, 1, 0x88);
+
+ fprintf(stderr, "toto\n");
+ TEST_VCOMP(vceq, , poly, p, uint, 64, 1);
+
+ CHECK(TEST_MSG, uint, 64, 1, PRIx64, vceq_expected, "");
+ fprintf(stderr, "toto\n");
+
+ /* vcombine_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VCOMBINE"
+
+#define TEST_VCOMBINE(T1, T2, W, N, N2) \
+ VECT_VAR(vcombine_vector128, T1, W, N2) = \
+ vcombine_##T2##W(VECT_VAR(vcombine_vector64_a, T1, W, N), \
+ VECT_VAR(vcombine_vector64_b, T1, W, N)); \
+ vst1q_##T2##W(VECT_VAR(result, T1, W, N2), VECT_VAR(vcombine_vector128, T1, W, N2))
+
+ DECL_VARIABLE(vcombine_vector64_a, poly, 64, 1);
+ DECL_VARIABLE(vcombine_vector64_b, poly, 64, 1);
+ DECL_VARIABLE(vcombine_vector128, poly, 64, 2);
+
+ CLEAN(result, poly, 64, 2);
+
+ VLOAD(vcombine_vector64_a, buffer, , poly, p, 64, 1);
+
+ VDUP(vcombine_vector64_b, , poly, p, 64, 1, 0x88);
+
+ TEST_VCOMBINE(poly, p, 64, 1, 2);
+
+ CHECK(TEST_MSG, poly, 64, 2, PRIx16, vcombine_expected, "");
+
+ /* vcreate_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VCREATE"
+
+#define TEST_VCREATE(T1, T2, W, N) \
+ VECT_VAR(vcreate_vector_res, T1, W, N) = \
+ vcreate_##T2##W(VECT_VAR(vcreate_val, T1, W, N)); \
+ vst1_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vcreate_vector_res, T1, W, N))
+
+#define DECL_VAL(VAR, T1, W, N) \
+ uint64_t VECT_VAR(VAR, T1, W, N)
+
+ DECL_VAL(vcreate_val, poly, 64, 1);
+ DECL_VARIABLE(vcreate_vector_res, poly, 64, 1);
+
+ CLEAN(result, poly, 64, 2);
+
+ VECT_VAR(vcreate_val, poly, 64, 1) = 0x123456789abcdef0ULL;
+
+ TEST_VCREATE(poly, p, 64, 1);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vcreate_expected, "");
+
+ /* vdup_lane_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VDUP_LANE/VDUP_LANEQ"
+
+#define TEST_VDUP_LANE(Q, T1, T2, W, N, N2, L) \
+ VECT_VAR(vdup_lane_vector_res, T1, W, N) = \
+ vdup##Q##_lane_##T2##W(VECT_VAR(vdup_lane_vector, T1, W, N2), L); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vdup_lane_vector_res, T1, W, N))
+
+ DECL_VARIABLE(vdup_lane_vector, poly, 64, 1);
+ DECL_VARIABLE(vdup_lane_vector, poly, 64, 2);
+ DECL_VARIABLE(vdup_lane_vector_res, poly, 64, 1);
+ DECL_VARIABLE(vdup_lane_vector_res, poly, 64, 2);
+
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ VLOAD(vdup_lane_vector, buffer, , poly, p, 64, 1);
+
+ TEST_VDUP_LANE(, poly, p, 64, 1, 1, 0);
+ TEST_VDUP_LANE(q, poly, p, 64, 2, 1, 0);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vdup_lane_expected, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vdup_lane_expected, "");
+
+ /* vdup_n_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VDUP/VDUPQ"
+
+#define TEST_VDUP(Q, T1, T2, W, N) \
+ VECT_VAR(vdup_n_vector, T1, W, N) = \
+ vdup##Q##_n_##T2##W(VECT_VAR(buffer_dup, T1, W, N)[i]); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vdup_n_vector, T1, W, N))
+
+ DECL_VARIABLE(vdup_n_vector, poly, 64, 1);
+ DECL_VARIABLE(vdup_n_vector, poly, 64, 2);
+
+ /* Try to read different places from the input buffer. */
+ for (i=0; i< 3; i++) {
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ TEST_VDUP(, poly, p, 64, 1);
+ TEST_VDUP(q, poly, p, 64, 2);
+
+ switch (i) {
+ case 0:
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vdup_n_expected0, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vdup_n_expected0, "");
+ break;
+ case 1:
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vdup_n_expected1, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vdup_n_expected1, "");
+ break;
+ case 2:
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vdup_n_expected2, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vdup_n_expected2, "");
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /* vexit_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VEXT/VEXTQ"
+
+#define TEST_VEXT(Q, T1, T2, W, N, V) \
+ VECT_VAR(vext_vector_res, T1, W, N) = \
+ vext##Q##_##T2##W(VECT_VAR(vext_vector1, T1, W, N), \
+ VECT_VAR(vext_vector2, T1, W, N), \
+ V); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vext_vector_res, T1, W, N))
+
+ DECL_VARIABLE(vext_vector1, poly, 64, 1);
+ DECL_VARIABLE(vext_vector1, poly, 64, 2);
+ DECL_VARIABLE(vext_vector2, poly, 64, 1);
+ DECL_VARIABLE(vext_vector2, poly, 64, 2);
+ DECL_VARIABLE(vext_vector_res, poly, 64, 1);
+ DECL_VARIABLE(vext_vector_res, poly, 64, 2);
+
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ VLOAD(vext_vector1, buffer, , poly, p, 64, 1);
+ VLOAD(vext_vector1, buffer, q, poly, p, 64, 2);
+
+ VDUP(vext_vector2, , poly, p, 64, 1, 0x88);
+ VDUP(vext_vector2, q, poly, p, 64, 2, 0x88);
+
+ TEST_VEXT(, poly, p, 64, 1, 0);
+ TEST_VEXT(q, poly, p, 64, 2, 1);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vext_expected, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vext_expected, "");
+
+ /* vget_low_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VGET_LOW"
+
+#define TEST_VGET_LOW(T1, T2, W, N, N2) \
+ VECT_VAR(vget_low_vector64, T1, W, N) = \
+ vget_low_##T2##W(VECT_VAR(vget_low_vector128, T1, W, N2)); \
+ vst1_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vget_low_vector64, T1, W, N))
+
+ DECL_VARIABLE(vget_low_vector64, poly, 64, 1);
+ DECL_VARIABLE(vget_low_vector128, poly, 64, 2);
+
+ CLEAN(result, poly, 64, 1);
+
+ VLOAD(vget_low_vector128, buffer, q, poly, p, 64, 2);
+
+ TEST_VGET_LOW(poly, p, 64, 1, 2);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vget_low_expected, "");
+
+ /* vld1_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VLD1/VLD1Q"
+
+#define TEST_VLD1(VAR, BUF, Q, T1, T2, W, N) \
+ VECT_VAR(VAR, T1, W, N) = vld1##Q##_##T2##W(VECT_VAR(BUF, T1, W, N)); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(VAR, T1, W, N))
+
+ DECL_VARIABLE(vld1_vector, poly, 64, 1);
+ DECL_VARIABLE(vld1_vector, poly, 64, 2);
+
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ VLOAD(vld1_vector, buffer, , poly, p, 64, 1);
+ VLOAD(vld1_vector, buffer, q, poly, p, 64, 2);
+
+ TEST_VLD1(vld1_vector, buffer, , poly, p, 64, 1);
+ TEST_VLD1(vld1_vector, buffer, q, poly, p, 64, 2);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld1_expected, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vld1_expected, "");
+
+ /* vld1_dup_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VLD1_DUP/VLD1_DUPQ"
+
+#define TEST_VLD1_DUP(VAR, BUF, Q, T1, T2, W, N) \
+ VECT_VAR(VAR, T1, W, N) = \
+ vld1##Q##_dup_##T2##W(&VECT_VAR(BUF, T1, W, N)[i]); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(VAR, T1, W, N))
+
+ DECL_VARIABLE(vld1_dup_vector, poly, 64, 1);
+ DECL_VARIABLE(vld1_dup_vector, poly, 64, 2);
+
+ /* Try to read different places from the input buffer. */
+ for (i=0; i<3; i++) {
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ TEST_VLD1_DUP(vld1_dup_vector, buffer_dup, , poly, p, 64, 1);
+ TEST_VLD1_DUP(vld1_dup_vector, buffer_dup, q, poly, p, 64, 2);
+
+ switch (i) {
+ case 0:
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld1_dup_expected0, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vld1_dup_expected0, "");
+ break;
+ case 1:
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld1_dup_expected1, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vld1_dup_expected1, "");
+ break;
+ case 2:
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld1_dup_expected2, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vld1_dup_expected2, "");
+ break;
+ default:
+ abort();
+ }
+ }
+
+ /* vld1_lane_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VLD1_LANE/VLD1_LANEQ"
+
+#define TEST_VLD1_LANE(Q, T1, T2, W, N, L) \
+ memset (VECT_VAR(vld1_lane_buffer_src, T1, W, N), 0xAA, W/8*N); \
+ VECT_VAR(vld1_lane_vector_src, T1, W, N) = \
+ vld1##Q##_##T2##W(VECT_VAR(vld1_lane_buffer_src, T1, W, N)); \
+ VECT_VAR(vld1_lane_vector, T1, W, N) = \
+ vld1##Q##_lane_##T2##W(VECT_VAR(buffer, T1, W, N), \
+ VECT_VAR(vld1_lane_vector_src, T1, W, N), L); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vld1_lane_vector, T1, W, N))
+
+ DECL_VARIABLE(vld1_lane_vector, poly, 64, 1);
+ DECL_VARIABLE(vld1_lane_vector, poly, 64, 2);
+ DECL_VARIABLE(vld1_lane_vector_src, poly, 64, 1);
+ DECL_VARIABLE(vld1_lane_vector_src, poly, 64, 2);
+
+ ARRAY(vld1_lane_buffer_src, poly, 64, 1);
+ ARRAY(vld1_lane_buffer_src, poly, 64, 2);
+
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ TEST_VLD1_LANE(, poly, p, 64, 1, 0);
+ TEST_VLD1_LANE(q, poly, p, 64, 2, 0);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld1_lane_expected, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vld1_lane_expected, "");
+
+ /* vldX_p64 tests. */
+#define DECL_VLDX(T1, W, N, X) \
+ VECT_ARRAY_TYPE(T1, W, N, X) VECT_ARRAY_VAR(vldX_vector, T1, W, N, X); \
+ VECT_VAR_DECL(vldX_result_bis_##X, T1, W, N)[X * N]
+
+#define TEST_VLDX(Q, T1, T2, W, N, X) \
+ VECT_ARRAY_VAR(vldX_vector, T1, W, N, X) = \
+ /* Use dedicated init buffer, of size X */ \
+ vld##X##Q##_##T2##W(VECT_ARRAY_VAR(buffer_vld##X, T1, W, N, X)); \
+ vst##X##Q##_##T2##W(VECT_VAR(vldX_result_bis_##X, T1, W, N), \
+ VECT_ARRAY_VAR(vldX_vector, T1, W, N, X)); \
+ memcpy(VECT_VAR(result, T1, W, N), VECT_VAR(vldX_result_bis_##X, T1, W, N), \
+ sizeof(VECT_VAR(result, T1, W, N)));
+
+ /* Overwrite "result" with the contents of "result_bis"[Y]. */
+#define TEST_EXTRA_CHUNK(T1, W, N, X,Y) \
+ memcpy(VECT_VAR(result, T1, W, N), \
+ &(VECT_VAR(vldX_result_bis_##X, T1, W, N)[Y*N]), \
+ sizeof(VECT_VAR(result, T1, W, N)));
+
+ DECL_VLDX(poly, 64, 1, 2);
+ DECL_VLDX(poly, 64, 1, 3);
+ DECL_VLDX(poly, 64, 1, 4);
+
+ VECT_ARRAY_INIT2(buffer_vld2, poly, 64, 1);
+ PAD(buffer_vld2_pad, poly, 64, 1);
+ VECT_ARRAY_INIT3(buffer_vld3, poly, 64, 1);
+ PAD(buffer_vld3_pad, poly, 64, 1);
+ VECT_ARRAY_INIT4(buffer_vld4, poly, 64, 1);
+ PAD(buffer_vld4_pad, poly, 64, 1);
+
+#undef TEST_MSG
+#define TEST_MSG "VLD2/VLD2Q"
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX(, poly, p, 64, 1, 2);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld2_expected_0, "chunk 0");
+ CLEAN(result, poly, 64, 1);
+ TEST_EXTRA_CHUNK(poly, 64, 1, 2, 1);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld2_expected_1, "chunk 1");
+
+#undef TEST_MSG
+#define TEST_MSG "VLD3/VLD3Q"
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX(, poly, p, 64, 1, 3);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld3_expected_0, "chunk 0");
+ CLEAN(result, poly, 64, 1);
+ TEST_EXTRA_CHUNK(poly, 64, 1, 3, 1);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld3_expected_1, "chunk 1");
+ CLEAN(result, poly, 64, 1);
+ TEST_EXTRA_CHUNK(poly, 64, 1, 3, 2);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld3_expected_2, "chunk 2");
+
+#undef TEST_MSG
+#define TEST_MSG "VLD4/VLD4Q"
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX(, poly, p, 64, 1, 4);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld4_expected_0, "chunk 0");
+ CLEAN(result, poly, 64, 1);
+ TEST_EXTRA_CHUNK(poly, 64, 1, 4, 1);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld4_expected_1, "chunk 1");
+ CLEAN(result, poly, 64, 1);
+ TEST_EXTRA_CHUNK(poly, 64, 1, 4, 2);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld4_expected_2, "chunk 2");
+ CLEAN(result, poly, 64, 1);
+ TEST_EXTRA_CHUNK(poly, 64, 1, 4, 3);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld4_expected_3, "chunk 3");
+
+ /* vldX_dup_p64 tests. */
+#define DECL_VLDX_DUP(T1, W, N, X) \
+ VECT_ARRAY_TYPE(T1, W, N, X) VECT_ARRAY_VAR(vldX_dup_vector, T1, W, N, X); \
+ VECT_VAR_DECL(vldX_dup_result_bis_##X, T1, W, N)[X * N]
+
+#define TEST_VLDX_DUP(Q, T1, T2, W, N, X) \
+ VECT_ARRAY_VAR(vldX_dup_vector, T1, W, N, X) = \
+ vld##X##Q##_dup_##T2##W(&VECT_VAR(buffer_dup, T1, W, N)[0]); \
+ \
+ vst##X##Q##_##T2##W(VECT_VAR(vldX_dup_result_bis_##X, T1, W, N), \
+ VECT_ARRAY_VAR(vldX_dup_vector, T1, W, N, X)); \
+ memcpy(VECT_VAR(result, T1, W, N), VECT_VAR(vldX_dup_result_bis_##X, T1, W, N), \
+ sizeof(VECT_VAR(result, T1, W, N)));
+
+ /* Overwrite "result" with the contents of "result_bis"[Y]. */
+#define TEST_VLDX_DUP_EXTRA_CHUNK(T1, W, N, X,Y) \
+ memcpy(VECT_VAR(result, T1, W, N), \
+ &(VECT_VAR(vldX_dup_result_bis_##X, T1, W, N)[Y*N]), \
+ sizeof(VECT_VAR(result, T1, W, N)));
+
+ DECL_VLDX_DUP(poly, 64, 1, 2);
+ DECL_VLDX_DUP(poly, 64, 1, 3);
+ DECL_VLDX_DUP(poly, 64, 1, 4);
+
+
+#undef TEST_MSG
+#define TEST_MSG "VLD2_DUP/VLD2Q_DUP"
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP(, poly, p, 64, 1, 2);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld2_dup_expected_0, "chunk 0");
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP_EXTRA_CHUNK(poly, 64, 1, 2, 1);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld2_dup_expected_1, "chunk 1");
+
+#undef TEST_MSG
+#define TEST_MSG "VLD3_DUP/VLD3Q_DUP"
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP(, poly, p, 64, 1, 3);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld3_dup_expected_0, "chunk 0");
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP_EXTRA_CHUNK(poly, 64, 1, 3, 1);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld3_dup_expected_1, "chunk 1");
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP_EXTRA_CHUNK(poly, 64, 1, 3, 2);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld3_dup_expected_2, "chunk 2");
+
+#undef TEST_MSG
+#define TEST_MSG "VLD4_DUP/VLD4Q_DUP"
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP(, poly, p, 64, 1, 4);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld4_dup_expected_0, "chunk 0");
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP_EXTRA_CHUNK(poly, 64, 1, 4, 1);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld4_dup_expected_1, "chunk 1");
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP_EXTRA_CHUNK(poly, 64, 1, 4, 2);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld4_dup_expected_2, "chunk 2");
+ CLEAN(result, poly, 64, 1);
+ TEST_VLDX_DUP_EXTRA_CHUNK(poly, 64, 1, 4, 3);
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vld4_dup_expected_3, "chunk 3");
+
+ /* vsli_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VSLI"
+
+#define TEST_VSXI1(INSN, Q, T1, T2, W, N, V) \
+ VECT_VAR(vsXi_vector_res, T1, W, N) = \
+ INSN##Q##_n_##T2##W(VECT_VAR(vsXi_vector, T1, W, N), \
+ VECT_VAR(vsXi_vector2, T1, W, N), \
+ V); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), VECT_VAR(vsXi_vector_res, T1, W, N))
+
+#define TEST_VSXI(INSN, Q, T1, T2, W, N, V) \
+ TEST_VSXI1(INSN, Q, T1, T2, W, N, V)
+
+ DECL_VARIABLE(vsXi_vector, poly, 64, 1);
+ DECL_VARIABLE(vsXi_vector, poly, 64, 2);
+ DECL_VARIABLE(vsXi_vector2, poly, 64, 1);
+ DECL_VARIABLE(vsXi_vector2, poly, 64, 2);
+ DECL_VARIABLE(vsXi_vector_res, poly, 64, 1);
+ DECL_VARIABLE(vsXi_vector_res, poly, 64, 2);
+
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ VLOAD(vsXi_vector, buffer, , poly, p, 64, 1);
+ VLOAD(vsXi_vector, buffer, q, poly, p, 64, 2);
+
+ VDUP(vsXi_vector2, , poly, p, 64, 1, 2);
+ VDUP(vsXi_vector2, q, poly, p, 64, 2, 3);
+
+ TEST_VSXI(vsli, , poly, p, 64, 1, 3);
+ TEST_VSXI(vsli, q, poly, p, 64, 2, 53);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vsli_expected, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vsli_expected, "");
+
+ /* Test cases with maximum shift amount. */
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ TEST_VSXI(vsli, , poly, p, 64, 1, 63);
+ TEST_VSXI(vsli, q, poly, p, 64, 2, 63);
+
+#define COMMENT "(max shift amount)"
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vsli_expected_max_shift, COMMENT);
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vsli_expected_max_shift, COMMENT);
+
+ /* vsri_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VSRI"
+
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ VLOAD(vsXi_vector, buffer, , poly, p, 64, 1);
+ VLOAD(vsXi_vector, buffer, q, poly, p, 64, 2);
+
+ VDUP(vsXi_vector2, , poly, p, 64, 1, 2);
+ VDUP(vsXi_vector2, q, poly, p, 64, 2, 3);
+
+ TEST_VSXI(vsri, , poly, p, 64, 1, 3);
+ TEST_VSXI(vsri, q, poly, p, 64, 2, 53);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vsri_expected, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vsri_expected, "");
+
+ /* Test cases with maximum shift amount. */
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ TEST_VSXI(vsri, , poly, p, 64, 1, 64);
+ TEST_VSXI(vsri, q, poly, p, 64, 2, 64);
+
+#define COMMENT "(max shift amount)"
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vsri_expected_max_shift, COMMENT);
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vsri_expected_max_shift, COMMENT);
+
+ /* vst1_lane_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VST1_LANE/VST1_LANEQ"
+
+#define TEST_VST1_LANE(Q, T1, T2, W, N, L) \
+ VECT_VAR(vst1_lane_vector, T1, W, N) = \
+ vld1##Q##_##T2##W(VECT_VAR(buffer, T1, W, N)); \
+ vst1##Q##_lane_##T2##W(VECT_VAR(result, T1, W, N), \
+ VECT_VAR(vst1_lane_vector, T1, W, N), L)
+
+ DECL_VARIABLE(vst1_lane_vector, poly, 64, 1);
+ DECL_VARIABLE(vst1_lane_vector, poly, 64, 2);
+
+ CLEAN(result, poly, 64, 1);
+ CLEAN(result, poly, 64, 2);
+
+ TEST_VST1_LANE(, poly, p, 64, 1, 0);
+ TEST_VST1_LANE(q, poly, p, 64, 2, 0);
+
+ CHECK(TEST_MSG, poly, 64, 1, PRIx64, vst1_lane_expected, "");
+ CHECK(TEST_MSG, poly, 64, 2, PRIx64, vst1_lane_expected, "");
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c
new file mode 100644
index 00000000000..efa9b5f2ece
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vfms_vfma_n.c
@@ -0,0 +1,490 @@
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+#if defined(__aarch64__) && defined(__ARM_FEATURE_FMA)
+
+#define A0 123.4f
+#define A1 -3.8f
+#define A2 -29.4f
+#define A3 (__builtin_inff ())
+#define A4 0.0f
+#define A5 24.0f
+#define A6 124.0f
+#define A7 1024.0f
+
+#define B0 -5.8f
+#define B1 -0.0f
+#define B2 -10.8f
+#define B3 10.0f
+#define B4 23.4f
+#define B5 -1234.8f
+#define B6 8.9f
+#define B7 4.0f
+
+#define E0 9.8f
+#define E1 -1024.0f
+#define E2 (-__builtin_inff ())
+#define E3 479.0f
+float32_t elem0 = E0;
+float32_t elem1 = E1;
+float32_t elem2 = E2;
+float32_t elem3 = E3;
+
+#define DA0 1231234.4
+#define DA1 -3.8
+#define DA2 -2980.4
+#define DA3 -5.8
+#define DA4 0.01123
+#define DA5 24.0
+#define DA6 124.12345
+#define DA7 1024.0
+
+#define DB0 -5.8
+#define DB1 (__builtin_inf ())
+#define DB2 -105.8
+#define DB3 10.0
+#define DB4 (-__builtin_inf ())
+#define DB5 -1234.8
+#define DB6 848.9
+#define DB7 44444.0
+
+#define DE0 9.8
+#define DE1 -1024.0
+#define DE2 105.8
+#define DE3 479.0
+float64_t delem0 = DE0;
+float64_t delem1 = DE1;
+float64_t delem2 = DE2;
+float64_t delem3 = DE3;
+
+/* Expected results for vfms_n. */
+
+VECT_VAR_DECL(expectedfms0, float, 32, 2) [] = {A0 + -B0 * E0, A1 + -B1 * E0};
+VECT_VAR_DECL(expectedfms1, float, 32, 2) [] = {A2 + -B2 * E1, A3 + -B3 * E1};
+VECT_VAR_DECL(expectedfms2, float, 32, 2) [] = {A4 + -B4 * E2, A5 + -B5 * E2};
+VECT_VAR_DECL(expectedfms3, float, 32, 2) [] = {A6 + -B6 * E3, A7 + -B7 * E3};
+VECT_VAR_DECL(expectedfma0, float, 32, 2) [] = {A0 + B0 * E0, A1 + B1 * E0};
+VECT_VAR_DECL(expectedfma1, float, 32, 2) [] = {A2 + B2 * E1, A3 + B3 * E1};
+VECT_VAR_DECL(expectedfma2, float, 32, 2) [] = {A4 + B4 * E2, A5 + B5 * E2};
+VECT_VAR_DECL(expectedfma3, float, 32, 2) [] = {A6 + B6 * E3, A7 + B7 * E3};
+
+hfloat32_t * VECT_VAR (expectedfms0_static, hfloat, 32, 2) =
+ (hfloat32_t *) VECT_VAR (expectedfms0, float, 32, 2);
+hfloat32_t * VECT_VAR (expectedfms1_static, hfloat, 32, 2) =
+ (hfloat32_t *) VECT_VAR (expectedfms1, float, 32, 2);
+hfloat32_t * VECT_VAR (expectedfms2_static, hfloat, 32, 2) =
+ (hfloat32_t *) VECT_VAR (expectedfms2, float, 32, 2);
+hfloat32_t * VECT_VAR (expectedfms3_static, hfloat, 32, 2) =
+ (hfloat32_t *) VECT_VAR (expectedfms3, float, 32, 2);
+hfloat32_t * VECT_VAR (expectedfma0_static, hfloat, 32, 2) =
+ (hfloat32_t *) VECT_VAR (expectedfma0, float, 32, 2);
+hfloat32_t * VECT_VAR (expectedfma1_static, hfloat, 32, 2) =
+ (hfloat32_t *) VECT_VAR (expectedfma1, float, 32, 2);
+hfloat32_t * VECT_VAR (expectedfma2_static, hfloat, 32, 2) =
+ (hfloat32_t *) VECT_VAR (expectedfma2, float, 32, 2);
+hfloat32_t * VECT_VAR (expectedfma3_static, hfloat, 32, 2) =
+ (hfloat32_t *) VECT_VAR (expectedfma3, float, 32, 2);
+
+
+VECT_VAR_DECL(expectedfms0, float, 32, 4) [] = {A0 + -B0 * E0, A1 + -B1 * E0,
+ A2 + -B2 * E0, A3 + -B3 * E0};
+VECT_VAR_DECL(expectedfms1, float, 32, 4) [] = {A4 + -B4 * E1, A5 + -B5 * E1,
+ A6 + -B6 * E1, A7 + -B7 * E1};
+VECT_VAR_DECL(expectedfms2, float, 32, 4) [] = {A0 + -B0 * E2, A2 + -B2 * E2,
+ A4 + -B4 * E2, A6 + -B6 * E2};
+VECT_VAR_DECL(expectedfms3, float, 32, 4) [] = {A1 + -B1 * E3, A3 + -B3 * E3,
+ A5 + -B5 * E3, A7 + -B7 * E3};
+VECT_VAR_DECL(expectedfma0, float, 32, 4) [] = {A0 + B0 * E0, A1 + B1 * E0,
+ A2 + B2 * E0, A3 + B3 * E0};
+VECT_VAR_DECL(expectedfma1, float, 32, 4) [] = {A4 + B4 * E1, A5 + B5 * E1,
+ A6 + B6 * E1, A7 + B7 * E1};
+VECT_VAR_DECL(expectedfma2, float, 32, 4) [] = {A0 + B0 * E2, A2 + B2 * E2,
+ A4 + B4 * E2, A6 + B6 * E2};
+VECT_VAR_DECL(expectedfma3, float, 32, 4) [] = {A1 + B1 * E3, A3 + B3 * E3,
+ A5 + B5 * E3, A7 + B7 * E3};
+
+hfloat32_t * VECT_VAR (expectedfms0_static, hfloat, 32, 4) =
+ (hfloat32_t *) VECT_VAR (expectedfms0, float, 32, 4);
+hfloat32_t * VECT_VAR (expectedfms1_static, hfloat, 32, 4) =
+ (hfloat32_t *) VECT_VAR (expectedfms1, float, 32, 4);
+hfloat32_t * VECT_VAR (expectedfms2_static, hfloat, 32, 4) =
+ (hfloat32_t *) VECT_VAR (expectedfms2, float, 32, 4);
+hfloat32_t * VECT_VAR (expectedfms3_static, hfloat, 32, 4) =
+ (hfloat32_t *) VECT_VAR (expectedfms3, float, 32, 4);
+hfloat32_t * VECT_VAR (expectedfma0_static, hfloat, 32, 4) =
+ (hfloat32_t *) VECT_VAR (expectedfma0, float, 32, 4);
+hfloat32_t * VECT_VAR (expectedfma1_static, hfloat, 32, 4) =
+ (hfloat32_t *) VECT_VAR (expectedfma1, float, 32, 4);
+hfloat32_t * VECT_VAR (expectedfma2_static, hfloat, 32, 4) =
+ (hfloat32_t *) VECT_VAR (expectedfma2, float, 32, 4);
+hfloat32_t * VECT_VAR (expectedfma3_static, hfloat, 32, 4) =
+ (hfloat32_t *) VECT_VAR (expectedfma3, float, 32, 4);
+
+VECT_VAR_DECL(expectedfms0, float, 64, 2) [] = {DA0 + -DB0 * DE0,
+ DA1 + -DB1 * DE0};
+VECT_VAR_DECL(expectedfms1, float, 64, 2) [] = {DA2 + -DB2 * DE1,
+ DA3 + -DB3 * DE1};
+VECT_VAR_DECL(expectedfms2, float, 64, 2) [] = {DA4 + -DB4 * DE2,
+ DA5 + -DB5 * DE2};
+VECT_VAR_DECL(expectedfms3, float, 64, 2) [] = {DA6 + -DB6 * DE3,
+ DA7 + -DB7 * DE3};
+VECT_VAR_DECL(expectedfma0, float, 64, 2) [] = {DA0 + DB0 * DE0,
+ DA1 + DB1 * DE0};
+VECT_VAR_DECL(expectedfma1, float, 64, 2) [] = {DA2 + DB2 * DE1,
+ DA3 + DB3 * DE1};
+VECT_VAR_DECL(expectedfma2, float, 64, 2) [] = {DA4 + DB4 * DE2,
+ DA5 + DB5 * DE2};
+VECT_VAR_DECL(expectedfma3, float, 64, 2) [] = {DA6 + DB6 * DE3,
+ DA7 + DB7 * DE3};
+hfloat64_t * VECT_VAR (expectedfms0_static, hfloat, 64, 2) =
+ (hfloat64_t *) VECT_VAR (expectedfms0, float, 64, 2);
+hfloat64_t * VECT_VAR (expectedfms1_static, hfloat, 64, 2) =
+ (hfloat64_t *) VECT_VAR (expectedfms1, float, 64, 2);
+hfloat64_t * VECT_VAR (expectedfms2_static, hfloat, 64, 2) =
+ (hfloat64_t *) VECT_VAR (expectedfms2, float, 64, 2);
+hfloat64_t * VECT_VAR (expectedfms3_static, hfloat, 64, 2) =
+ (hfloat64_t *) VECT_VAR (expectedfms3, float, 64, 2);
+hfloat64_t * VECT_VAR (expectedfma0_static, hfloat, 64, 2) =
+ (hfloat64_t *) VECT_VAR (expectedfma0, float, 64, 2);
+hfloat64_t * VECT_VAR (expectedfma1_static, hfloat, 64, 2) =
+ (hfloat64_t *) VECT_VAR (expectedfma1, float, 64, 2);
+hfloat64_t * VECT_VAR (expectedfma2_static, hfloat, 64, 2) =
+ (hfloat64_t *) VECT_VAR (expectedfma2, float, 64, 2);
+hfloat64_t * VECT_VAR (expectedfma3_static, hfloat, 64, 2) =
+ (hfloat64_t *) VECT_VAR (expectedfma3, float, 64, 2);
+
+VECT_VAR_DECL(expectedfms0, float, 64, 1) [] = {DA0 + -DB0 * DE0};
+VECT_VAR_DECL(expectedfms1, float, 64, 1) [] = {DA2 + -DB2 * DE1};
+VECT_VAR_DECL(expectedfms2, float, 64, 1) [] = {DA4 + -DB4 * DE2};
+VECT_VAR_DECL(expectedfms3, float, 64, 1) [] = {DA6 + -DB6 * DE3};
+VECT_VAR_DECL(expectedfma0, float, 64, 1) [] = {DA0 + DB0 * DE0};
+VECT_VAR_DECL(expectedfma1, float, 64, 1) [] = {DA2 + DB2 * DE1};
+VECT_VAR_DECL(expectedfma2, float, 64, 1) [] = {DA4 + DB4 * DE2};
+VECT_VAR_DECL(expectedfma3, float, 64, 1) [] = {DA6 + DB6 * DE3};
+
+hfloat64_t * VECT_VAR (expectedfms0_static, hfloat, 64, 1) =
+ (hfloat64_t *) VECT_VAR (expectedfms0, float, 64, 1);
+hfloat64_t * VECT_VAR (expectedfms1_static, hfloat, 64, 1) =
+ (hfloat64_t *) VECT_VAR (expectedfms1, float, 64, 1);
+hfloat64_t * VECT_VAR (expectedfms2_static, hfloat, 64, 1) =
+ (hfloat64_t *) VECT_VAR (expectedfms2, float, 64, 1);
+hfloat64_t * VECT_VAR (expectedfms3_static, hfloat, 64, 1) =
+ (hfloat64_t *) VECT_VAR (expectedfms3, float, 64, 1);
+hfloat64_t * VECT_VAR (expectedfma0_static, hfloat, 64, 1) =
+ (hfloat64_t *) VECT_VAR (expectedfma0, float, 64, 1);
+hfloat64_t * VECT_VAR (expectedfma1_static, hfloat, 64, 1) =
+ (hfloat64_t *) VECT_VAR (expectedfma1, float, 64, 1);
+hfloat64_t * VECT_VAR (expectedfma2_static, hfloat, 64, 1) =
+ (hfloat64_t *) VECT_VAR (expectedfma2, float, 64, 1);
+hfloat64_t * VECT_VAR (expectedfma3_static, hfloat, 64, 1) =
+ (hfloat64_t *) VECT_VAR (expectedfma3, float, 64, 1);
+
+void exec_vfma_vfms_n (void)
+{
+#undef TEST_MSG
+#define TEST_MSG "VFMS_VFMA_N (FP32)"
+ clean_results ();
+
+ DECL_VARIABLE(vsrc_1, float, 32, 2);
+ DECL_VARIABLE(vsrc_2, float, 32, 2);
+ VECT_VAR_DECL (buf_src_1, float, 32, 2) [] = {A0, A1};
+ VECT_VAR_DECL (buf_src_2, float, 32, 2) [] = {B0, B1};
+ VLOAD (vsrc_1, buf_src_1, , float, f, 32, 2);
+ VLOAD (vsrc_2, buf_src_2, , float, f, 32, 2);
+ DECL_VARIABLE (vector_res, float, 32, 2) =
+ vfms_n_f32 (VECT_VAR (vsrc_1, float, 32, 2),
+ VECT_VAR (vsrc_2, float, 32, 2), elem0);
+ vst1_f32 (VECT_VAR (result, float, 32, 2),
+ VECT_VAR (vector_res, float, 32, 2));
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx16, expectedfms0_static, "");
+ VECT_VAR (vector_res, float, 32, 2) =
+ vfma_n_f32 (VECT_VAR (vsrc_1, float, 32, 2),
+ VECT_VAR (vsrc_2, float, 32, 2), elem0);
+ vst1_f32 (VECT_VAR (result, float, 32, 2),
+ VECT_VAR (vector_res, float, 32, 2));
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx16, expectedfma0_static, "");
+
+ VECT_VAR_DECL (buf_src_3, float, 32, 2) [] = {A2, A3};
+ VECT_VAR_DECL (buf_src_4, float, 32, 2) [] = {B2, B3};
+ VLOAD (vsrc_1, buf_src_3, , float, f, 32, 2);
+ VLOAD (vsrc_2, buf_src_4, , float, f, 32, 2);
+ VECT_VAR (vector_res, float, 32, 2) =
+ vfms_n_f32 (VECT_VAR (vsrc_1, float, 32, 2),
+ VECT_VAR (vsrc_2, float, 32, 2), elem1);
+ vst1_f32 (VECT_VAR (result, float, 32, 2),
+ VECT_VAR (vector_res, float, 32, 2));
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx16, expectedfms1_static, "");
+ VECT_VAR (vector_res, float, 32, 2) =
+ vfma_n_f32 (VECT_VAR (vsrc_1, float, 32, 2),
+ VECT_VAR (vsrc_2, float, 32, 2), elem1);
+ vst1_f32 (VECT_VAR (result, float, 32, 2),
+ VECT_VAR (vector_res, float, 32, 2));
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx16, expectedfma1_static, "");
+
+ VECT_VAR_DECL (buf_src_5, float, 32, 2) [] = {A4, A5};
+ VECT_VAR_DECL (buf_src_6, float, 32, 2) [] = {B4, B5};
+ VLOAD (vsrc_1, buf_src_5, , float, f, 32, 2);
+ VLOAD (vsrc_2, buf_src_6, , float, f, 32, 2);
+ VECT_VAR (vector_res, float, 32, 2) =
+ vfms_n_f32 (VECT_VAR (vsrc_1, float, 32, 2),
+ VECT_VAR (vsrc_2, float, 32, 2), elem2);
+ vst1_f32 (VECT_VAR (result, float, 32, 2),
+ VECT_VAR (vector_res, float, 32, 2));
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx16, expectedfms2_static, "");
+ VECT_VAR (vector_res, float, 32, 2) =
+ vfma_n_f32 (VECT_VAR (vsrc_1, float, 32, 2),
+ VECT_VAR (vsrc_2, float, 32, 2), elem2);
+ vst1_f32 (VECT_VAR (result, float, 32, 2),
+ VECT_VAR (vector_res, float, 32, 2));
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx16, expectedfma2_static, "");
+
+ VECT_VAR_DECL (buf_src_7, float, 32, 2) [] = {A6, A7};
+ VECT_VAR_DECL (buf_src_8, float, 32, 2) [] = {B6, B7};
+ VLOAD (vsrc_1, buf_src_7, , float, f, 32, 2);
+ VLOAD (vsrc_2, buf_src_8, , float, f, 32, 2);
+ VECT_VAR (vector_res, float, 32, 2) =
+ vfms_n_f32 (VECT_VAR (vsrc_1, float, 32, 2),
+ VECT_VAR (vsrc_2, float, 32, 2), elem3);
+ vst1_f32 (VECT_VAR (result, float, 32, 2),
+ VECT_VAR (vector_res, float, 32, 2));
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx16, expectedfms3_static, "");
+ VECT_VAR (vector_res, float, 32, 2) =
+ vfma_n_f32 (VECT_VAR (vsrc_1, float, 32, 2),
+ VECT_VAR (vsrc_2, float, 32, 2), elem3);
+ vst1_f32 (VECT_VAR (result, float, 32, 2),
+ VECT_VAR (vector_res, float, 32, 2));
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx16, expectedfma3_static, "");
+
+#undef TEST_MSG
+#define TEST_MSG "VFMSQ_VFMAQ_N (FP32)"
+ clean_results ();
+
+ DECL_VARIABLE(vsrc_1, float, 32, 4);
+ DECL_VARIABLE(vsrc_2, float, 32, 4);
+ VECT_VAR_DECL (buf_src_1, float, 32, 4) [] = {A0, A1, A2, A3};
+ VECT_VAR_DECL (buf_src_2, float, 32, 4) [] = {B0, B1, B2, B3};
+ VLOAD (vsrc_1, buf_src_1, q, float, f, 32, 4);
+ VLOAD (vsrc_2, buf_src_2, q, float, f, 32, 4);
+ DECL_VARIABLE (vector_res, float, 32, 4) =
+ vfmsq_n_f32 (VECT_VAR (vsrc_1, float, 32, 4),
+ VECT_VAR (vsrc_2, float, 32, 4), elem0);
+ vst1q_f32 (VECT_VAR (result, float, 32, 4),
+ VECT_VAR (vector_res, float, 32, 4));
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx16, expectedfms0_static, "");
+ VECT_VAR (vector_res, float, 32, 4) =
+ vfmaq_n_f32 (VECT_VAR (vsrc_1, float, 32, 4),
+ VECT_VAR (vsrc_2, float, 32, 4), elem0);
+ vst1q_f32 (VECT_VAR (result, float, 32, 4),
+ VECT_VAR (vector_res, float, 32, 4));
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx16, expectedfma0_static, "");
+
+ VECT_VAR_DECL (buf_src_3, float, 32, 4) [] = {A4, A5, A6, A7};
+ VECT_VAR_DECL (buf_src_4, float, 32, 4) [] = {B4, B5, B6, B7};
+ VLOAD (vsrc_1, buf_src_3, q, float, f, 32, 4);
+ VLOAD (vsrc_2, buf_src_4, q, float, f, 32, 4);
+ VECT_VAR (vector_res, float, 32, 4) =
+ vfmsq_n_f32 (VECT_VAR (vsrc_1, float, 32, 4),
+ VECT_VAR (vsrc_2, float, 32, 4), elem1);
+ vst1q_f32 (VECT_VAR (result, float, 32, 4),
+ VECT_VAR (vector_res, float, 32, 4));
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx16, expectedfms1_static, "");
+ VECT_VAR (vector_res, float, 32, 4) =
+ vfmaq_n_f32 (VECT_VAR (vsrc_1, float, 32, 4),
+ VECT_VAR (vsrc_2, float, 32, 4), elem1);
+ vst1q_f32 (VECT_VAR (result, float, 32, 4),
+ VECT_VAR (vector_res, float, 32, 4));
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx16, expectedfma1_static, "");
+
+ VECT_VAR_DECL (buf_src_5, float, 32, 4) [] = {A0, A2, A4, A6};
+ VECT_VAR_DECL (buf_src_6, float, 32, 4) [] = {B0, B2, B4, B6};
+ VLOAD (vsrc_1, buf_src_5, q, float, f, 32, 4);
+ VLOAD (vsrc_2, buf_src_6, q, float, f, 32, 4);
+ VECT_VAR (vector_res, float, 32, 4) =
+ vfmsq_n_f32 (VECT_VAR (vsrc_1, float, 32, 4),
+ VECT_VAR (vsrc_2, float, 32, 4), elem2);
+ vst1q_f32 (VECT_VAR (result, float, 32, 4),
+ VECT_VAR (vector_res, float, 32, 4));
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx16, expectedfms2_static, "");
+ VECT_VAR (vector_res, float, 32, 4) =
+ vfmaq_n_f32 (VECT_VAR (vsrc_1, float, 32, 4),
+ VECT_VAR (vsrc_2, float, 32, 4), elem2);
+ vst1q_f32 (VECT_VAR (result, float, 32, 4),
+ VECT_VAR (vector_res, float, 32, 4));
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx16, expectedfma2_static, "");
+
+ VECT_VAR_DECL (buf_src_7, float, 32, 4) [] = {A1, A3, A5, A7};
+ VECT_VAR_DECL (buf_src_8, float, 32, 4) [] = {B1, B3, B5, B7};
+ VLOAD (vsrc_1, buf_src_7, q, float, f, 32, 4);
+ VLOAD (vsrc_2, buf_src_8, q, float, f, 32, 4);
+ VECT_VAR (vector_res, float, 32, 4) =
+ vfmsq_n_f32 (VECT_VAR (vsrc_1, float, 32, 4),
+ VECT_VAR (vsrc_2, float, 32, 4), elem3);
+ vst1q_f32 (VECT_VAR (result, float, 32, 4),
+ VECT_VAR (vector_res, float, 32, 4));
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx16, expectedfms3_static, "");
+ VECT_VAR (vector_res, float, 32, 4) =
+ vfmaq_n_f32 (VECT_VAR (vsrc_1, float, 32, 4),
+ VECT_VAR (vsrc_2, float, 32, 4), elem3);
+ vst1q_f32 (VECT_VAR (result, float, 32, 4),
+ VECT_VAR (vector_res, float, 32, 4));
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx16, expectedfma3_static, "");
+
+#undef TEST_MSG
+#define TEST_MSG "VFMSQ_VFMAQ_N (FP64)"
+ clean_results ();
+
+ DECL_VARIABLE(vsrc_1, float, 64, 2);
+ DECL_VARIABLE(vsrc_2, float, 64, 2);
+ VECT_VAR_DECL (buf_src_1, float, 64, 2) [] = {DA0, DA1};
+ VECT_VAR_DECL (buf_src_2, float, 64, 2) [] = {DB0, DB1};
+ VLOAD (vsrc_1, buf_src_1, q, float, f, 64, 2);
+ VLOAD (vsrc_2, buf_src_2, q, float, f, 64, 2);
+ DECL_VARIABLE (vector_res, float, 64, 2) =
+ vfmsq_n_f64 (VECT_VAR (vsrc_1, float, 64, 2),
+ VECT_VAR (vsrc_2, float, 64, 2), delem0);
+ vst1q_f64 (VECT_VAR (result, float, 64, 2),
+ VECT_VAR (vector_res, float, 64, 2));
+ CHECK_FP (TEST_MSG, float, 64, 2, PRIx16, expectedfms0_static, "");
+ VECT_VAR (vector_res, float, 64, 2) =
+ vfmaq_n_f64 (VECT_VAR (vsrc_1, float, 64, 2),
+ VECT_VAR (vsrc_2, float, 64, 2), delem0);
+ vst1q_f64 (VECT_VAR (result, float, 64, 2),
+ VECT_VAR (vector_res, float, 64, 2));
+ CHECK_FP (TEST_MSG, float, 64, 2, PRIx16, expectedfma0_static, "");
+
+ VECT_VAR_DECL (buf_src_3, float, 64, 2) [] = {DA2, DA3};
+ VECT_VAR_DECL (buf_src_4, float, 64, 2) [] = {DB2, DB3};
+ VLOAD (vsrc_1, buf_src_3, q, float, f, 64, 2);
+ VLOAD (vsrc_2, buf_src_4, q, float, f, 64, 2);
+ VECT_VAR (vector_res, float, 64, 2) =
+ vfmsq_n_f64 (VECT_VAR (vsrc_1, float, 64, 2),
+ VECT_VAR (vsrc_2, float, 64, 2), delem1);
+ vst1q_f64 (VECT_VAR (result, float, 64, 2),
+ VECT_VAR (vector_res, float, 64, 2));
+ CHECK_FP (TEST_MSG, float, 64, 2, PRIx16, expectedfms1_static, "");
+ VECT_VAR (vector_res, float, 64, 2) =
+ vfmaq_n_f64 (VECT_VAR (vsrc_1, float, 64, 2),
+ VECT_VAR (vsrc_2, float, 64, 2), delem1);
+ vst1q_f64 (VECT_VAR (result, float, 64, 2),
+ VECT_VAR (vector_res, float, 64, 2));
+ CHECK_FP (TEST_MSG, float, 64, 2, PRIx16, expectedfma1_static, "");
+
+ VECT_VAR_DECL (buf_src_5, float, 64, 2) [] = {DA4, DA5};
+ VECT_VAR_DECL (buf_src_6, float, 64, 2) [] = {DB4, DB5};
+ VLOAD (vsrc_1, buf_src_5, q, float, f, 64, 2);
+ VLOAD (vsrc_2, buf_src_6, q, float, f, 64, 2);
+ VECT_VAR (vector_res, float, 64, 2) =
+ vfmsq_n_f64 (VECT_VAR (vsrc_1, float, 64, 2),
+ VECT_VAR (vsrc_2, float, 64, 2), delem2);
+ vst1q_f64 (VECT_VAR (result, float, 64, 2),
+ VECT_VAR (vector_res, float, 64, 2));
+ CHECK_FP (TEST_MSG, float, 64, 2, PRIx16, expectedfms2_static, "");
+ VECT_VAR (vector_res, float, 64, 2) =
+ vfmaq_n_f64 (VECT_VAR (vsrc_1, float, 64, 2),
+ VECT_VAR (vsrc_2, float, 64, 2), delem2);
+ vst1q_f64 (VECT_VAR (result, float, 64, 2),
+ VECT_VAR (vector_res, float, 64, 2));
+ CHECK_FP (TEST_MSG, float, 64, 2, PRIx16, expectedfma2_static, "");
+
+ VECT_VAR_DECL (buf_src_7, float, 64, 2) [] = {DA6, DA7};
+ VECT_VAR_DECL (buf_src_8, float, 64, 2) [] = {DB6, DB7};
+ VLOAD (vsrc_1, buf_src_7, q, float, f, 64, 2);
+ VLOAD (vsrc_2, buf_src_8, q, float, f, 64, 2);
+ VECT_VAR (vector_res, float, 64, 2) =
+ vfmsq_n_f64 (VECT_VAR (vsrc_1, float, 64, 2),
+ VECT_VAR (vsrc_2, float, 64, 2), delem3);
+ vst1q_f64 (VECT_VAR (result, float, 64, 2),
+ VECT_VAR (vector_res, float, 64, 2));
+ CHECK_FP (TEST_MSG, float, 64, 2, PRIx16, expectedfms3_static, "");
+ VECT_VAR (vector_res, float, 64, 2) =
+ vfmaq_n_f64 (VECT_VAR (vsrc_1, float, 64, 2),
+ VECT_VAR (vsrc_2, float, 64, 2), delem3);
+ vst1q_f64 (VECT_VAR (result, float, 64, 2),
+ VECT_VAR (vector_res, float, 64, 2));
+ CHECK_FP (TEST_MSG, float, 64, 2, PRIx16, expectedfma3_static, "");
+
+#undef TEST_MSG
+#define TEST_MSG "VFMS_VFMA_N (FP64)"
+ clean_results ();
+
+ DECL_VARIABLE(vsrc_1, float, 64, 1);
+ DECL_VARIABLE(vsrc_2, float, 64, 1);
+ VECT_VAR_DECL (buf_src_1, float, 64, 1) [] = {DA0};
+ VECT_VAR_DECL (buf_src_2, float, 64, 1) [] = {DB0};
+ VLOAD (vsrc_1, buf_src_1, , float, f, 64, 1);
+ VLOAD (vsrc_2, buf_src_2, , float, f, 64, 1);
+ DECL_VARIABLE (vector_res, float, 64, 1) =
+ vfms_n_f64 (VECT_VAR (vsrc_1, float, 64, 1),
+ VECT_VAR (vsrc_2, float, 64, 1), delem0);
+ vst1_f64 (VECT_VAR (result, float, 64, 1),
+ VECT_VAR (vector_res, float, 64, 1));
+ CHECK_FP (TEST_MSG, float, 64, 1, PRIx16, expectedfms0_static, "");
+ VECT_VAR (vector_res, float, 64, 1) =
+ vfma_n_f64 (VECT_VAR (vsrc_1, float, 64, 1),
+ VECT_VAR (vsrc_2, float, 64, 1), delem0);
+ vst1_f64 (VECT_VAR (result, float, 64, 1),
+ VECT_VAR (vector_res, float, 64, 1));
+ CHECK_FP (TEST_MSG, float, 64, 1, PRIx16, expectedfma0_static, "");
+
+ VECT_VAR_DECL (buf_src_3, float, 64, 1) [] = {DA2};
+ VECT_VAR_DECL (buf_src_4, float, 64, 1) [] = {DB2};
+ VLOAD (vsrc_1, buf_src_3, , float, f, 64, 1);
+ VLOAD (vsrc_2, buf_src_4, , float, f, 64, 1);
+ VECT_VAR (vector_res, float, 64, 1) =
+ vfms_n_f64 (VECT_VAR (vsrc_1, float, 64, 1),
+ VECT_VAR (vsrc_2, float, 64, 1), delem1);
+ vst1_f64 (VECT_VAR (result, float, 64, 1),
+ VECT_VAR (vector_res, float, 64, 1));
+ CHECK_FP (TEST_MSG, float, 64, 1, PRIx16, expectedfms1_static, "");
+ VECT_VAR (vector_res, float, 64, 1) =
+ vfma_n_f64 (VECT_VAR (vsrc_1, float, 64, 1),
+ VECT_VAR (vsrc_2, float, 64, 1), delem1);
+ vst1_f64 (VECT_VAR (result, float, 64, 1),
+ VECT_VAR (vector_res, float, 64, 1));
+ CHECK_FP (TEST_MSG, float, 64, 1, PRIx16, expectedfma1_static, "");
+
+ VECT_VAR_DECL (buf_src_5, float, 64, 1) [] = {DA4};
+ VECT_VAR_DECL (buf_src_6, float, 64, 1) [] = {DB4};
+ VLOAD (vsrc_1, buf_src_5, , float, f, 64, 1);
+ VLOAD (vsrc_2, buf_src_6, , float, f, 64, 1);
+ VECT_VAR (vector_res, float, 64, 1) =
+ vfms_n_f64 (VECT_VAR (vsrc_1, float, 64, 1),
+ VECT_VAR (vsrc_2, float, 64, 1), delem2);
+ vst1_f64 (VECT_VAR (result, float, 64, 1),
+ VECT_VAR (vector_res, float, 64, 1));
+ CHECK_FP (TEST_MSG, float, 64, 1, PRIx16, expectedfms2_static, "");
+ VECT_VAR (vector_res, float, 64, 1) =
+ vfma_n_f64 (VECT_VAR (vsrc_1, float, 64, 1),
+ VECT_VAR (vsrc_2, float, 64, 1), delem2);
+ vst1_f64 (VECT_VAR (result, float, 64, 1),
+ VECT_VAR (vector_res, float, 64, 1));
+ CHECK_FP (TEST_MSG, float, 64, 1, PRIx16, expectedfma2_static, "");
+
+ VECT_VAR_DECL (buf_src_7, float, 64, 1) [] = {DA6};
+ VECT_VAR_DECL (buf_src_8, float, 64, 1) [] = {DB6};
+ VLOAD (vsrc_1, buf_src_7, , float, f, 64, 1);
+ VLOAD (vsrc_2, buf_src_8, , float, f, 64, 1);
+ VECT_VAR (vector_res, float, 64, 1) =
+ vfms_n_f64 (VECT_VAR (vsrc_1, float, 64, 1),
+ VECT_VAR (vsrc_2, float, 64, 1), delem3);
+ vst1_f64 (VECT_VAR (result, float, 64, 1),
+ VECT_VAR (vector_res, float, 64, 1));
+ CHECK_FP (TEST_MSG, float, 64, 1, PRIx16, expectedfms3_static, "");
+ VECT_VAR (vector_res, float, 64, 1) =
+ vfma_n_f64 (VECT_VAR (vsrc_1, float, 64, 1),
+ VECT_VAR (vsrc_2, float, 64, 1), delem3);
+ vst1_f64 (VECT_VAR (result, float, 64, 1),
+ VECT_VAR (vector_res, float, 64, 1));
+ CHECK_FP (TEST_MSG, float, 64, 1, PRIx16, expectedfma3_static, "");
+}
+#endif
+
+int
+main (void)
+{
+#if defined(__aarch64__) && defined(__ARM_FEATURE_FMA)
+ exec_vfma_vfms_n ();
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vget_lane.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vget_lane.c
index 580605072bc..fe41c5fbe1d 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vget_lane.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vget_lane.c
@@ -13,6 +13,7 @@ uint32_t expected_u32 = 0xfffffff1;
uint64_t expected_u64 = 0xfffffffffffffff0;
poly8_t expected_p8 = 0xf6;
poly16_t expected_p16 = 0xfff2;
+hfloat16_t expected_f16 = 0xcb80;
hfloat32_t expected_f32 = 0xc1700000;
int8_t expectedq_s8 = 0xff;
@@ -25,6 +26,7 @@ uint32_t expectedq_u32 = 0xfffffff2;
uint64_t expectedq_u64 = 0xfffffffffffffff1;
poly8_t expectedq_p8 = 0xfe;
poly16_t expectedq_p16 = 0xfff6;
+hfloat16_t expectedq_f16 = 0xca80;
hfloat32_t expectedq_f32 = 0xc1500000;
int error_found = 0;
@@ -52,6 +54,10 @@ void exec_vget_lane (void)
uint32_t var_int32;
float32_t var_float32;
} var_int32_float32;
+ union {
+ uint16_t var_int16;
+ float16_t var_float16;
+ } var_int16_float16;
#define TEST_VGET_LANE_FP(Q, T1, T2, W, N, L) \
VAR(var, T1, W) = vget##Q##_lane_##T2##W(VECT_VAR(vector, T1, W, N), L); \
@@ -81,10 +87,17 @@ void exec_vget_lane (void)
VAR_DECL(var, uint, 64);
VAR_DECL(var, poly, 8);
VAR_DECL(var, poly, 16);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ VAR_DECL(var, float, 16);
+#endif
VAR_DECL(var, float, 32);
/* Initialize input values. */
TEST_MACRO_ALL_VARIANTS_2_5(VLOAD, vector, buffer);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ VLOAD(vector, buffer, , float, f, 16, 4);
+ VLOAD(vector, buffer, q, float, f, 16, 8);
+#endif
VLOAD(vector, buffer, , float, f, 32, 2);
VLOAD(vector, buffer, q, float, f, 32, 4);
@@ -99,6 +112,9 @@ void exec_vget_lane (void)
TEST_VGET_LANE(, uint, u, 64, 1, 0);
TEST_VGET_LANE(, poly, p, 8, 8, 6);
TEST_VGET_LANE(, poly, p, 16, 4, 2);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ TEST_VGET_LANE_FP(, float, f, 16, 4, 1);
+#endif
TEST_VGET_LANE_FP(, float, f, 32, 2, 1);
TEST_VGET_LANE(q, int, s, 8, 16, 15);
@@ -111,6 +127,9 @@ void exec_vget_lane (void)
TEST_VGET_LANE(q, uint, u, 64, 2, 1);
TEST_VGET_LANE(q, poly, p, 8, 16, 14);
TEST_VGET_LANE(q, poly, p, 16, 8, 6);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ TEST_VGET_LANE_FP(q, float, f, 16, 8, 3);
+#endif
TEST_VGET_LANE_FP(q, float, f, 32, 4, 3);
}
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmul.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmul.c
index 0cbb6565893..63f0d8d6320 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmul.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vmul.c
@@ -37,10 +37,8 @@ VECT_VAR_DECL(expected,poly,8,16) [] = { 0x60, 0xca, 0x34, 0x9e,
VECT_VAR_DECL(expected,hfloat,32,4) [] = { 0xc4c73333, 0xc4bac000,
0xc4ae4ccd, 0xc4a1d999 };
-#ifndef INSN_NAME
#define INSN_NAME vmul
#define TEST_MSG "VMUL"
-#endif
#define FNNAME1(NAME) exec_ ## NAME
#define FNNAME(NAME) FNNAME1(NAME)
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c
index 9e45e25cc3a..0de2ab37b20 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret.c
@@ -21,6 +21,8 @@ VECT_VAR_DECL(expected_s8_8,int,8,8) [] = { 0xf0, 0xf1, 0xf2, 0xf3,
0xf4, 0xf5, 0xf6, 0xf7 };
VECT_VAR_DECL(expected_s8_9,int,8,8) [] = { 0xf0, 0xff, 0xf1, 0xff,
0xf2, 0xff, 0xf3, 0xff };
+VECT_VAR_DECL(expected_s8_10,int,8,8) [] = { 0x00, 0xcc, 0x80, 0xcb,
+ 0x00, 0xcb, 0x80, 0xca };
/* Expected results for vreinterpret_s16_xx. */
VECT_VAR_DECL(expected_s16_1,int,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
@@ -32,6 +34,7 @@ VECT_VAR_DECL(expected_s16_6,int,16,4) [] = { 0xfff0, 0xffff, 0xfff1, 0xffff };
VECT_VAR_DECL(expected_s16_7,int,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
VECT_VAR_DECL(expected_s16_8,int,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
VECT_VAR_DECL(expected_s16_9,int,16,4) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3 };
+VECT_VAR_DECL(expected_s16_10,int,16,4) [] = { 0xcc00, 0xcb80, 0xcb00, 0xca80 };
/* Expected results for vreinterpret_s32_xx. */
VECT_VAR_DECL(expected_s32_1,int,32,2) [] = { 0xf3f2f1f0, 0xf7f6f5f4 };
@@ -43,6 +46,7 @@ VECT_VAR_DECL(expected_s32_6,int,32,2) [] = { 0xfffffff0, 0xfffffff1 };
VECT_VAR_DECL(expected_s32_7,int,32,2) [] = { 0xfffffff0, 0xffffffff };
VECT_VAR_DECL(expected_s32_8,int,32,2) [] = { 0xf3f2f1f0, 0xf7f6f5f4 };
VECT_VAR_DECL(expected_s32_9,int,32,2) [] = { 0xfff1fff0, 0xfff3fff2 };
+VECT_VAR_DECL(expected_s32_10,int,32,2) [] = { 0xcb80cc00, 0xca80cb00 };
/* Expected results for vreinterpret_s64_xx. */
VECT_VAR_DECL(expected_s64_1,int,64,1) [] = { 0xf7f6f5f4f3f2f1f0 };
@@ -54,6 +58,7 @@ VECT_VAR_DECL(expected_s64_6,int,64,1) [] = { 0xfffffff1fffffff0 };
VECT_VAR_DECL(expected_s64_7,int,64,1) [] = { 0xfffffffffffffff0 };
VECT_VAR_DECL(expected_s64_8,int,64,1) [] = { 0xf7f6f5f4f3f2f1f0 };
VECT_VAR_DECL(expected_s64_9,int,64,1) [] = { 0xfff3fff2fff1fff0 };
+VECT_VAR_DECL(expected_s64_10,int,64,1) [] = { 0xca80cb00cb80cc00 };
/* Expected results for vreinterpret_u8_xx. */
VECT_VAR_DECL(expected_u8_1,uint,8,8) [] = { 0xf0, 0xf1, 0xf2, 0xf3,
@@ -74,6 +79,8 @@ VECT_VAR_DECL(expected_u8_8,uint,8,8) [] = { 0xf0, 0xf1, 0xf2, 0xf3,
0xf4, 0xf5, 0xf6, 0xf7 };
VECT_VAR_DECL(expected_u8_9,uint,8,8) [] = { 0xf0, 0xff, 0xf1, 0xff,
0xf2, 0xff, 0xf3, 0xff };
+VECT_VAR_DECL(expected_u8_10,uint,8,8) [] = { 0x00, 0xcc, 0x80, 0xcb,
+ 0x00, 0xcb, 0x80, 0xca };
/* Expected results for vreinterpret_u16_xx. */
VECT_VAR_DECL(expected_u16_1,uint,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
@@ -85,6 +92,7 @@ VECT_VAR_DECL(expected_u16_6,uint,16,4) [] = { 0xfff0, 0xffff, 0xfff1, 0xffff };
VECT_VAR_DECL(expected_u16_7,uint,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
VECT_VAR_DECL(expected_u16_8,uint,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
VECT_VAR_DECL(expected_u16_9,uint,16,4) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3 };
+VECT_VAR_DECL(expected_u16_10,uint,16,4) [] = { 0xcc00, 0xcb80, 0xcb00, 0xca80 };
/* Expected results for vreinterpret_u32_xx. */
VECT_VAR_DECL(expected_u32_1,uint,32,2) [] = { 0xf3f2f1f0, 0xf7f6f5f4 };
@@ -96,6 +104,7 @@ VECT_VAR_DECL(expected_u32_6,uint,32,2) [] = { 0xfff1fff0, 0xfff3fff2 };
VECT_VAR_DECL(expected_u32_7,uint,32,2) [] = { 0xfffffff0, 0xffffffff };
VECT_VAR_DECL(expected_u32_8,uint,32,2) [] = { 0xf3f2f1f0, 0xf7f6f5f4 };
VECT_VAR_DECL(expected_u32_9,uint,32,2) [] = { 0xfff1fff0, 0xfff3fff2 };
+VECT_VAR_DECL(expected_u32_10,uint,32,2) [] = { 0xcb80cc00, 0xca80cb00 };
/* Expected results for vreinterpret_u64_xx. */
VECT_VAR_DECL(expected_u64_1,uint,64,1) [] = { 0xf7f6f5f4f3f2f1f0 };
@@ -107,6 +116,7 @@ VECT_VAR_DECL(expected_u64_6,uint,64,1) [] = { 0xfff3fff2fff1fff0 };
VECT_VAR_DECL(expected_u64_7,uint,64,1) [] = { 0xfffffff1fffffff0 };
VECT_VAR_DECL(expected_u64_8,uint,64,1) [] = { 0xf7f6f5f4f3f2f1f0 };
VECT_VAR_DECL(expected_u64_9,uint,64,1) [] = { 0xfff3fff2fff1fff0 };
+VECT_VAR_DECL(expected_u64_10,uint,64,1) [] = { 0xca80cb00cb80cc00 };
/* Expected results for vreinterpret_p8_xx. */
VECT_VAR_DECL(expected_p8_1,poly,8,8) [] = { 0xf0, 0xf1, 0xf2, 0xf3,
@@ -127,6 +137,8 @@ VECT_VAR_DECL(expected_p8_8,poly,8,8) [] = { 0xf0, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff };
VECT_VAR_DECL(expected_p8_9,poly,8,8) [] = { 0xf0, 0xff, 0xf1, 0xff,
0xf2, 0xff, 0xf3, 0xff };
+VECT_VAR_DECL(expected_p8_10,poly,8,8) [] = { 0x00, 0xcc, 0x80, 0xcb,
+ 0x00, 0xcb, 0x80, 0xca };
/* Expected results for vreinterpret_p16_xx. */
VECT_VAR_DECL(expected_p16_1,poly,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
@@ -138,6 +150,7 @@ VECT_VAR_DECL(expected_p16_6,poly,16,4) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3 };
VECT_VAR_DECL(expected_p16_7,poly,16,4) [] = { 0xfff0, 0xffff, 0xfff1, 0xffff };
VECT_VAR_DECL(expected_p16_8,poly,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
VECT_VAR_DECL(expected_p16_9,poly,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
+VECT_VAR_DECL(expected_p16_10,poly,16,4) [] = { 0xcc00, 0xcb80, 0xcb00, 0xca80 };
/* Expected results for vreinterpretq_s8_xx. */
VECT_VAR_DECL(expected_q_s8_1,int,8,16) [] = { 0xf0, 0xff, 0xf1, 0xff,
@@ -176,6 +189,10 @@ VECT_VAR_DECL(expected_q_s8_9,int,8,16) [] = { 0xf0, 0xff, 0xf1, 0xff,
0xf2, 0xff, 0xf3, 0xff,
0xf4, 0xff, 0xf5, 0xff,
0xf6, 0xff, 0xf7, 0xff };
+VECT_VAR_DECL(expected_q_s8_10,int,8,16) [] = { 0x00, 0xcc, 0x80, 0xcb,
+ 0x00, 0xcb, 0x80, 0xca,
+ 0x00, 0xca, 0x80, 0xc9,
+ 0x00, 0xc9, 0x80, 0xc8 };
/* Expected results for vreinterpretq_s16_xx. */
VECT_VAR_DECL(expected_q_s16_1,int,16,8) [] = { 0xf1f0, 0xf3f2,
@@ -214,6 +231,10 @@ VECT_VAR_DECL(expected_q_s16_9,int,16,8) [] = { 0xfff0, 0xfff1,
0xfff2, 0xfff3,
0xfff4, 0xfff5,
0xfff6, 0xfff7 };
+VECT_VAR_DECL(expected_q_s16_10,int,16,8) [] = { 0xcc00, 0xcb80,
+ 0xcb00, 0xca80,
+ 0xca00, 0xc980,
+ 0xc900, 0xc880 };
/* Expected results for vreinterpretq_s32_xx. */
VECT_VAR_DECL(expected_q_s32_1,int,32,4) [] = { 0xf3f2f1f0, 0xf7f6f5f4,
@@ -234,6 +255,8 @@ VECT_VAR_DECL(expected_q_s32_8,int,32,4) [] = { 0xf3f2f1f0, 0xf7f6f5f4,
0xfbfaf9f8, 0xfffefdfc };
VECT_VAR_DECL(expected_q_s32_9,int,32,4) [] = { 0xfff1fff0, 0xfff3fff2,
0xfff5fff4, 0xfff7fff6 };
+VECT_VAR_DECL(expected_q_s32_10,int,32,4) [] = { 0xcb80cc00, 0xca80cb00,
+ 0xc980ca00, 0xc880c900 };
/* Expected results for vreinterpretq_s64_xx. */
VECT_VAR_DECL(expected_q_s64_1,int,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
@@ -254,6 +277,8 @@ VECT_VAR_DECL(expected_q_s64_8,int,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
0xfffefdfcfbfaf9f8 };
VECT_VAR_DECL(expected_q_s64_9,int,64,2) [] = { 0xfff3fff2fff1fff0,
0xfff7fff6fff5fff4 };
+VECT_VAR_DECL(expected_q_s64_10,int,64,2) [] = { 0xca80cb00cb80cc00,
+ 0xc880c900c980ca00 };
/* Expected results for vreinterpretq_u8_xx. */
VECT_VAR_DECL(expected_q_u8_1,uint,8,16) [] = { 0xf0, 0xf1, 0xf2, 0xf3,
@@ -292,6 +317,10 @@ VECT_VAR_DECL(expected_q_u8_9,uint,8,16) [] = { 0xf0, 0xff, 0xf1, 0xff,
0xf2, 0xff, 0xf3, 0xff,
0xf4, 0xff, 0xf5, 0xff,
0xf6, 0xff, 0xf7, 0xff };
+VECT_VAR_DECL(expected_q_u8_10,uint,8,16) [] = { 0x00, 0xcc, 0x80, 0xcb,
+ 0x00, 0xcb, 0x80, 0xca,
+ 0x00, 0xca, 0x80, 0xc9,
+ 0x00, 0xc9, 0x80, 0xc8 };
/* Expected results for vreinterpretq_u16_xx. */
VECT_VAR_DECL(expected_q_u16_1,uint,16,8) [] = { 0xf1f0, 0xf3f2,
@@ -330,6 +359,10 @@ VECT_VAR_DECL(expected_q_u16_9,uint,16,8) [] = { 0xfff0, 0xfff1,
0xfff2, 0xfff3,
0xfff4, 0xfff5,
0xfff6, 0xfff7 };
+VECT_VAR_DECL(expected_q_u16_10,uint,16,8) [] = { 0xcc00, 0xcb80,
+ 0xcb00, 0xca80,
+ 0xca00, 0xc980,
+ 0xc900, 0xc880 };
/* Expected results for vreinterpretq_u32_xx. */
VECT_VAR_DECL(expected_q_u32_1,uint,32,4) [] = { 0xf3f2f1f0, 0xf7f6f5f4,
@@ -350,6 +383,8 @@ VECT_VAR_DECL(expected_q_u32_8,uint,32,4) [] = { 0xf3f2f1f0, 0xf7f6f5f4,
0xfbfaf9f8, 0xfffefdfc };
VECT_VAR_DECL(expected_q_u32_9,uint,32,4) [] = { 0xfff1fff0, 0xfff3fff2,
0xfff5fff4, 0xfff7fff6 };
+VECT_VAR_DECL(expected_q_u32_10,uint,32,4) [] = { 0xcb80cc00, 0xca80cb00,
+ 0xc980ca00, 0xc880c900 };
/* Expected results for vreinterpretq_u64_xx. */
VECT_VAR_DECL(expected_q_u64_1,uint,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
@@ -370,6 +405,92 @@ VECT_VAR_DECL(expected_q_u64_8,uint,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
0xfffefdfcfbfaf9f8 };
VECT_VAR_DECL(expected_q_u64_9,uint,64,2) [] = { 0xfff3fff2fff1fff0,
0xfff7fff6fff5fff4 };
+VECT_VAR_DECL(expected_q_u64_10,uint,64,2) [] = { 0xca80cb00cb80cc00,
+ 0xc880c900c980ca00 };
+
+/* Expected results for vreinterpretq_p8_xx. */
+VECT_VAR_DECL(expected_q_p8_1,poly,8,16) [] = { 0xf0, 0xf1, 0xf2, 0xf3,
+ 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb,
+ 0xfc, 0xfd, 0xfe, 0xff };
+VECT_VAR_DECL(expected_q_p8_2,poly,8,16) [] = { 0xf0, 0xff, 0xf1, 0xff,
+ 0xf2, 0xff, 0xf3, 0xff,
+ 0xf4, 0xff, 0xf5, 0xff,
+ 0xf6, 0xff, 0xf7, 0xff };
+VECT_VAR_DECL(expected_q_p8_3,poly,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xf2, 0xff, 0xff, 0xff,
+ 0xf3, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(expected_q_p8_4,poly,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(expected_q_p8_5,poly,8,16) [] = { 0xf0, 0xf1, 0xf2, 0xf3,
+ 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb,
+ 0xfc, 0xfd, 0xfe, 0xff };
+VECT_VAR_DECL(expected_q_p8_6,poly,8,16) [] = { 0xf0, 0xff, 0xf1, 0xff,
+ 0xf2, 0xff, 0xf3, 0xff,
+ 0xf4, 0xff, 0xf5, 0xff,
+ 0xf6, 0xff, 0xf7, 0xff };
+VECT_VAR_DECL(expected_q_p8_7,poly,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xf2, 0xff, 0xff, 0xff,
+ 0xf3, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(expected_q_p8_8,poly,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(expected_q_p8_9,poly,8,16) [] = { 0xf0, 0xff, 0xf1, 0xff,
+ 0xf2, 0xff, 0xf3, 0xff,
+ 0xf4, 0xff, 0xf5, 0xff,
+ 0xf6, 0xff, 0xf7, 0xff };
+VECT_VAR_DECL(expected_q_p8_10,poly,8,16) [] = { 0x00, 0xcc, 0x80, 0xcb,
+ 0x00, 0xcb, 0x80, 0xca,
+ 0x00, 0xca, 0x80, 0xc9,
+ 0x00, 0xc9, 0x80, 0xc8 };
+
+/* Expected results for vreinterpretq_p16_xx. */
+VECT_VAR_DECL(expected_q_p16_1,poly,16,8) [] = { 0xf1f0, 0xf3f2,
+ 0xf5f4, 0xf7f6,
+ 0xf9f8, 0xfbfa,
+ 0xfdfc, 0xfffe };
+VECT_VAR_DECL(expected_q_p16_2,poly,16,8) [] = { 0xfff0, 0xfff1,
+ 0xfff2, 0xfff3,
+ 0xfff4, 0xfff5,
+ 0xfff6, 0xfff7 };
+VECT_VAR_DECL(expected_q_p16_3,poly,16,8) [] = { 0xfff0, 0xffff,
+ 0xfff1, 0xffff,
+ 0xfff2, 0xffff,
+ 0xfff3, 0xffff };
+VECT_VAR_DECL(expected_q_p16_4,poly,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(expected_q_p16_5,poly,16,8) [] = { 0xf1f0, 0xf3f2,
+ 0xf5f4, 0xf7f6,
+ 0xf9f8, 0xfbfa,
+ 0xfdfc, 0xfffe };
+VECT_VAR_DECL(expected_q_p16_6,poly,16,8) [] = { 0xfff0, 0xfff1,
+ 0xfff2, 0xfff3,
+ 0xfff4, 0xfff5,
+ 0xfff6, 0xfff7 };
+VECT_VAR_DECL(expected_q_p16_7,poly,16,8) [] = { 0xfff0, 0xffff,
+ 0xfff1, 0xffff,
+ 0xfff2, 0xffff,
+ 0xfff3, 0xffff };
+VECT_VAR_DECL(expected_q_p16_8,poly,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(expected_q_p16_9,poly,16,8) [] = { 0xf1f0, 0xf3f2,
+ 0xf5f4, 0xf7f6,
+ 0xf9f8, 0xfbfa,
+ 0xfdfc, 0xfffe };
+VECT_VAR_DECL(expected_q_p16_10,poly,16,8) [] = { 0xcc00, 0xcb80,
+ 0xcb00, 0xca80,
+ 0xca00, 0xc980,
+ 0xc900, 0xc880 };
/* Expected results for vreinterpret_f32_xx. */
VECT_VAR_DECL(expected_f32_1,hfloat,32,2) [] = { 0xf3f2f1f0, 0xf7f6f5f4 };
@@ -382,6 +503,7 @@ VECT_VAR_DECL(expected_f32_7,hfloat,32,2) [] = { 0xfffffff0, 0xfffffff1 };
VECT_VAR_DECL(expected_f32_8,hfloat,32,2) [] = { 0xfffffff0, 0xffffffff };
VECT_VAR_DECL(expected_f32_9,hfloat,32,2) [] = { 0xf3f2f1f0, 0xf7f6f5f4 };
VECT_VAR_DECL(expected_f32_10,hfloat,32,2) [] = { 0xfff1fff0, 0xfff3fff2 };
+VECT_VAR_DECL(expected_f32_11,hfloat,32,2) [] = { 0xcb80cc00, 0xca80cb00 };
/* Expected results for vreinterpretq_f32_xx. */
VECT_VAR_DECL(expected_q_f32_1,hfloat,32,4) [] = { 0xf3f2f1f0, 0xf7f6f5f4,
@@ -404,8 +526,10 @@ VECT_VAR_DECL(expected_q_f32_9,hfloat,32,4) [] = { 0xf3f2f1f0, 0xf7f6f5f4,
0xfbfaf9f8, 0xfffefdfc };
VECT_VAR_DECL(expected_q_f32_10,hfloat,32,4) [] = { 0xfff1fff0, 0xfff3fff2,
0xfff5fff4, 0xfff7fff6 };
+VECT_VAR_DECL(expected_q_f32_11,hfloat,32,4) [] = { 0xcb80cc00, 0xca80cb00,
+ 0xc980ca00, 0xc880c900 };
-/* Expected results for vreinterpretq_xx_f32. */
+/* Expected results for vreinterpret_xx_f32. */
VECT_VAR_DECL(expected_xx_f32_1,int,8,8) [] = { 0x0, 0x0, 0x80, 0xc1,
0x0, 0x0, 0x70, 0xc1 };
VECT_VAR_DECL(expected_xx_f32_2,int,16,4) [] = { 0x0, 0xc180, 0x0, 0xc170 };
@@ -419,6 +543,7 @@ VECT_VAR_DECL(expected_xx_f32_8,uint,64,1) [] = { 0xc1700000c1800000 };
VECT_VAR_DECL(expected_xx_f32_9,poly,8,8) [] = { 0x0, 0x0, 0x80, 0xc1,
0x0, 0x0, 0x70, 0xc1 };
VECT_VAR_DECL(expected_xx_f32_10,poly,16,4) [] = { 0x0, 0xc180, 0x0, 0xc170 };
+VECT_VAR_DECL(expected_xx_f32_11,hfloat,16,4) [] = { 0x0, 0xc180, 0x0, 0xc170 };
/* Expected results for vreinterpretq_xx_f32. */
VECT_VAR_DECL(expected_q_xx_f32_1,int,8,16) [] = { 0x0, 0x0, 0x80, 0xc1,
@@ -447,6 +572,62 @@ VECT_VAR_DECL(expected_q_xx_f32_9,poly,8,16) [] = { 0x0, 0x0, 0x80, 0xc1,
0x0, 0x0, 0x50, 0xc1 };
VECT_VAR_DECL(expected_q_xx_f32_10,poly,16,8) [] = { 0x0, 0xc180, 0x0, 0xc170,
0x0, 0xc160, 0x0, 0xc150 };
+VECT_VAR_DECL(expected_q_xx_f32_11,hfloat,16,8) [] = { 0x0, 0xc180, 0x0, 0xc170,
+ 0x0, 0xc160, 0x0, 0xc150 };
+
+/* Expected results for vreinterpret_f16_xx. */
+VECT_VAR_DECL(expected_f16_1,hfloat,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
+VECT_VAR_DECL(expected_f16_2,hfloat,16,4) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3 };
+VECT_VAR_DECL(expected_f16_3,hfloat,16,4) [] = { 0xfff0, 0xffff, 0xfff1, 0xffff };
+VECT_VAR_DECL(expected_f16_4,hfloat,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
+VECT_VAR_DECL(expected_f16_5,hfloat,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
+VECT_VAR_DECL(expected_f16_6,hfloat,16,4) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3 };
+VECT_VAR_DECL(expected_f16_7,hfloat,16,4) [] = { 0xfff0, 0xffff, 0xfff1, 0xffff };
+VECT_VAR_DECL(expected_f16_8,hfloat,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
+VECT_VAR_DECL(expected_f16_9,hfloat,16,4) [] = { 0xf1f0, 0xf3f2, 0xf5f4, 0xf7f6 };
+VECT_VAR_DECL(expected_f16_10,hfloat,16,4) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3 };
+
+/* Expected results for vreinterpretq_f16_xx. */
+VECT_VAR_DECL(expected_q_f16_1,hfloat,16,8) [] = { 0xf1f0, 0xf3f2,
+ 0xf5f4, 0xf7f6,
+ 0xf9f8, 0xfbfa,
+ 0xfdfc, 0xfffe };
+VECT_VAR_DECL(expected_q_f16_2,hfloat,16,8) [] = { 0xfff0, 0xfff1,
+ 0xfff2, 0xfff3,
+ 0xfff4, 0xfff5,
+ 0xfff6, 0xfff7 };
+VECT_VAR_DECL(expected_q_f16_3,hfloat,16,8) [] = { 0xfff0, 0xffff,
+ 0xfff1, 0xffff,
+ 0xfff2, 0xffff,
+ 0xfff3, 0xffff };
+VECT_VAR_DECL(expected_q_f16_4,hfloat,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(expected_q_f16_5,hfloat,16,8) [] = { 0xf1f0, 0xf3f2,
+ 0xf5f4, 0xf7f6,
+ 0xf9f8, 0xfbfa,
+ 0xfdfc, 0xfffe };
+VECT_VAR_DECL(expected_q_f16_6,hfloat,16,8) [] = { 0xfff0, 0xfff1,
+ 0xfff2, 0xfff3,
+ 0xfff4, 0xfff5,
+ 0xfff6, 0xfff7 };
+VECT_VAR_DECL(expected_q_f16_7,hfloat,16,8) [] = { 0xfff0, 0xffff,
+ 0xfff1, 0xffff,
+ 0xfff2, 0xffff,
+ 0xfff3, 0xffff };
+VECT_VAR_DECL(expected_q_f16_8,hfloat,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(expected_q_f16_9,hfloat,16,8) [] = { 0xf1f0, 0xf3f2,
+ 0xf5f4, 0xf7f6,
+ 0xf9f8, 0xfbfa,
+ 0xfdfc, 0xfffe };
+VECT_VAR_DECL(expected_q_f16_10,hfloat,16,8) [] = { 0xfff0, 0xfff1,
+ 0xfff2, 0xfff3,
+ 0xfff4, 0xfff5,
+ 0xfff6, 0xfff7 };
#define TEST_MSG "VREINTERPRET/VREINTERPRETQ"
@@ -484,7 +665,9 @@ void exec_vreinterpret (void)
/* Initialize input "vector" from "buffer". */
TEST_MACRO_ALL_VARIANTS_2_5(VLOAD, vector, buffer);
+ VLOAD(vector, buffer, , float, f, 16, 4);
VLOAD(vector, buffer, , float, f, 32, 2);
+ VLOAD(vector, buffer, q, float, f, 16, 8);
VLOAD(vector, buffer, q, float, f, 32, 4);
/* vreinterpret_s8_xx. */
@@ -497,6 +680,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, int, s, 8, 8, uint, u, 64, 1, expected_s8_7);
TEST_VREINTERPRET(, int, s, 8, 8, poly, p, 8, 8, expected_s8_8);
TEST_VREINTERPRET(, int, s, 8, 8, poly, p, 16, 4, expected_s8_9);
+ TEST_VREINTERPRET(, int, s, 8, 8, float, f, 16, 4, expected_s8_10);
/* vreinterpret_s16_xx. */
TEST_VREINTERPRET(, int, s, 16, 4, int, s, 8, 8, expected_s16_1);
@@ -508,6 +692,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, int, s, 16, 4, uint, u, 64, 1, expected_s16_7);
TEST_VREINTERPRET(, int, s, 16, 4, poly, p, 8, 8, expected_s16_8);
TEST_VREINTERPRET(, int, s, 16, 4, poly, p, 16, 4, expected_s16_9);
+ TEST_VREINTERPRET(, int, s, 16, 4, float, f, 16, 4, expected_s16_10);
/* vreinterpret_s32_xx. */
TEST_VREINTERPRET(, int, s, 32, 2, int, s, 8, 8, expected_s32_1);
@@ -519,6 +704,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, int, s, 32, 2, uint, u, 64, 1, expected_s32_7);
TEST_VREINTERPRET(, int, s, 32, 2, poly, p, 8, 8, expected_s32_8);
TEST_VREINTERPRET(, int, s, 32, 2, poly, p, 16, 4, expected_s32_9);
+ TEST_VREINTERPRET(, int, s, 32, 2, float, f, 16, 4, expected_s32_10);
/* vreinterpret_s64_xx. */
TEST_VREINTERPRET(, int, s, 64, 1, int, s, 8, 8, expected_s64_1);
@@ -530,6 +716,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, int, s, 64, 1, uint, u, 64, 1, expected_s64_7);
TEST_VREINTERPRET(, int, s, 64, 1, poly, p, 8, 8, expected_s64_8);
TEST_VREINTERPRET(, int, s, 64, 1, poly, p, 16, 4, expected_s64_9);
+ TEST_VREINTERPRET(, int, s, 64, 1, float, f, 16, 4, expected_s64_10);
/* vreinterpret_u8_xx. */
TEST_VREINTERPRET(, uint, u, 8, 8, int, s, 8, 8, expected_u8_1);
@@ -541,6 +728,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, uint, u, 8, 8, uint, u, 64, 1, expected_u8_7);
TEST_VREINTERPRET(, uint, u, 8, 8, poly, p, 8, 8, expected_u8_8);
TEST_VREINTERPRET(, uint, u, 8, 8, poly, p, 16, 4, expected_u8_9);
+ TEST_VREINTERPRET(, uint, u, 8, 8, float, f, 16, 4, expected_u8_10);
/* vreinterpret_u16_xx. */
TEST_VREINTERPRET(, uint, u, 16, 4, int, s, 8, 8, expected_u16_1);
@@ -552,6 +740,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, uint, u, 16, 4, uint, u, 64, 1, expected_u16_7);
TEST_VREINTERPRET(, uint, u, 16, 4, poly, p, 8, 8, expected_u16_8);
TEST_VREINTERPRET(, uint, u, 16, 4, poly, p, 16, 4, expected_u16_9);
+ TEST_VREINTERPRET(, uint, u, 16, 4, float, f, 16, 4, expected_u16_10);
/* vreinterpret_u32_xx. */
TEST_VREINTERPRET(, uint, u, 32, 2, int, s, 8, 8, expected_u32_1);
@@ -563,6 +752,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, uint, u, 32, 2, uint, u, 64, 1, expected_u32_7);
TEST_VREINTERPRET(, uint, u, 32, 2, poly, p, 8, 8, expected_u32_8);
TEST_VREINTERPRET(, uint, u, 32, 2, poly, p, 16, 4, expected_u32_9);
+ TEST_VREINTERPRET(, uint, u, 32, 2, float, f, 16, 4, expected_u32_10);
/* vreinterpret_u64_xx. */
TEST_VREINTERPRET(, uint, u, 64, 1, int, s, 8, 8, expected_u64_1);
@@ -574,6 +764,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, uint, u, 64, 1, uint, u, 32, 2, expected_u64_7);
TEST_VREINTERPRET(, uint, u, 64, 1, poly, p, 8, 8, expected_u64_8);
TEST_VREINTERPRET(, uint, u, 64, 1, poly, p, 16, 4, expected_u64_9);
+ TEST_VREINTERPRET(, uint, u, 64, 1, float, f, 16, 4, expected_u64_10);
/* vreinterpret_p8_xx. */
TEST_VREINTERPRET_POLY(, poly, p, 8, 8, int, s, 8, 8, expected_p8_1);
@@ -585,6 +776,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET_POLY(, poly, p, 8, 8, uint, u, 32, 2, expected_p8_7);
TEST_VREINTERPRET_POLY(, poly, p, 8, 8, uint, u, 64, 1, expected_p8_8);
TEST_VREINTERPRET_POLY(, poly, p, 8, 8, poly, p, 16, 4, expected_p8_9);
+ TEST_VREINTERPRET_POLY(, poly, p, 8, 8, float, f, 16, 4, expected_p8_10);
/* vreinterpret_p16_xx. */
TEST_VREINTERPRET_POLY(, poly, p, 16, 4, int, s, 8, 8, expected_p16_1);
@@ -596,6 +788,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET_POLY(, poly, p, 16, 4, uint, u, 32, 2, expected_p16_7);
TEST_VREINTERPRET_POLY(, poly, p, 16, 4, uint, u, 64, 1, expected_p16_8);
TEST_VREINTERPRET_POLY(, poly, p, 16, 4, poly, p, 8, 8, expected_p16_9);
+ TEST_VREINTERPRET_POLY(, poly, p, 16, 4, float, f, 16, 4, expected_p16_10);
/* vreinterpretq_s8_xx. */
TEST_VREINTERPRET(q, int, s, 8, 16, int, s, 16, 8, expected_q_s8_1);
@@ -607,6 +800,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, int, s, 8, 16, uint, u, 64, 2, expected_q_s8_7);
TEST_VREINTERPRET(q, int, s, 8, 16, poly, p, 8, 16, expected_q_s8_8);
TEST_VREINTERPRET(q, int, s, 8, 16, poly, p, 16, 8, expected_q_s8_9);
+ TEST_VREINTERPRET(q, int, s, 8, 16, float, f, 16, 8, expected_q_s8_10);
/* vreinterpretq_s16_xx. */
TEST_VREINTERPRET(q, int, s, 16, 8, int, s, 8, 16, expected_q_s16_1);
@@ -618,6 +812,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, int, s, 16, 8, uint, u, 64, 2, expected_q_s16_7);
TEST_VREINTERPRET(q, int, s, 16, 8, poly, p, 8, 16, expected_q_s16_8);
TEST_VREINTERPRET(q, int, s, 16, 8, poly, p, 16, 8, expected_q_s16_9);
+ TEST_VREINTERPRET(q, int, s, 16, 8, float, f, 16, 8, expected_q_s16_10);
/* vreinterpretq_s32_xx. */
TEST_VREINTERPRET(q, int, s, 32, 4, int, s, 8, 16, expected_q_s32_1);
@@ -629,6 +824,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, int, s, 32, 4, uint, u, 64, 2, expected_q_s32_7);
TEST_VREINTERPRET(q, int, s, 32, 4, poly, p, 8, 16, expected_q_s32_8);
TEST_VREINTERPRET(q, int, s, 32, 4, poly, p, 16, 8, expected_q_s32_9);
+ TEST_VREINTERPRET(q, int, s, 32, 4, float, f, 16, 8, expected_q_s32_10);
/* vreinterpretq_s64_xx. */
TEST_VREINTERPRET(q, int, s, 64, 2, int, s, 8, 16, expected_q_s64_1);
@@ -640,6 +836,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, int, s, 64, 2, uint, u, 64, 2, expected_q_s64_7);
TEST_VREINTERPRET(q, int, s, 64, 2, poly, p, 8, 16, expected_q_s64_8);
TEST_VREINTERPRET(q, int, s, 64, 2, poly, p, 16, 8, expected_q_s64_9);
+ TEST_VREINTERPRET(q, int, s, 64, 2, float, f, 16, 8, expected_q_s64_10);
/* vreinterpretq_u8_xx. */
TEST_VREINTERPRET(q, uint, u, 8, 16, int, s, 8, 16, expected_q_u8_1);
@@ -651,6 +848,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, uint, u, 8, 16, uint, u, 64, 2, expected_q_u8_7);
TEST_VREINTERPRET(q, uint, u, 8, 16, poly, p, 8, 16, expected_q_u8_8);
TEST_VREINTERPRET(q, uint, u, 8, 16, poly, p, 16, 8, expected_q_u8_9);
+ TEST_VREINTERPRET(q, uint, u, 8, 16, float, f, 16, 8, expected_q_u8_10);
/* vreinterpretq_u16_xx. */
TEST_VREINTERPRET(q, uint, u, 16, 8, int, s, 8, 16, expected_q_u16_1);
@@ -662,6 +860,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, uint, u, 16, 8, uint, u, 64, 2, expected_q_u16_7);
TEST_VREINTERPRET(q, uint, u, 16, 8, poly, p, 8, 16, expected_q_u16_8);
TEST_VREINTERPRET(q, uint, u, 16, 8, poly, p, 16, 8, expected_q_u16_9);
+ TEST_VREINTERPRET(q, uint, u, 16, 8, float, f, 16, 8, expected_q_u16_10);
/* vreinterpretq_u32_xx. */
TEST_VREINTERPRET(q, uint, u, 32, 4, int, s, 8, 16, expected_q_u32_1);
@@ -673,6 +872,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, uint, u, 32, 4, uint, u, 64, 2, expected_q_u32_7);
TEST_VREINTERPRET(q, uint, u, 32, 4, poly, p, 8, 16, expected_q_u32_8);
TEST_VREINTERPRET(q, uint, u, 32, 4, poly, p, 16, 8, expected_q_u32_9);
+ TEST_VREINTERPRET(q, uint, u, 32, 4, float, f, 16, 8, expected_q_u32_10);
/* vreinterpretq_u64_xx. */
TEST_VREINTERPRET(q, uint, u, 64, 2, int, s, 8, 16, expected_q_u64_1);
@@ -684,6 +884,31 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, uint, u, 64, 2, uint, u, 32, 4, expected_q_u64_7);
TEST_VREINTERPRET(q, uint, u, 64, 2, poly, p, 8, 16, expected_q_u64_8);
TEST_VREINTERPRET(q, uint, u, 64, 2, poly, p, 16, 8, expected_q_u64_9);
+ TEST_VREINTERPRET(q, uint, u, 64, 2, float, f, 16, 8, expected_q_u64_10);
+
+ /* vreinterpretq_p8_xx. */
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, int, s, 8, 16, expected_q_p8_1);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, int, s, 16, 8, expected_q_p8_2);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, int, s, 32, 4, expected_q_p8_3);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, int, s, 64, 2, expected_q_p8_4);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, uint, u, 8, 16, expected_q_p8_5);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, uint, u, 16, 8, expected_q_p8_6);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, uint, u, 32, 4, expected_q_p8_7);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, uint, u, 64, 2, expected_q_p8_8);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, poly, p, 16, 8, expected_q_p8_9);
+ TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, float, f, 16, 8, expected_q_p8_10);
+
+ /* vreinterpretq_p16_xx. */
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, int, s, 8, 16, expected_q_p16_1);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, int, s, 16, 8, expected_q_p16_2);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, int, s, 32, 4, expected_q_p16_3);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, int, s, 64, 2, expected_q_p16_4);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, uint, u, 8, 16, expected_q_p16_5);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, uint, u, 16, 8, expected_q_p16_6);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, uint, u, 32, 4, expected_q_p16_7);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, uint, u, 64, 2, expected_q_p16_8);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, poly, p, 8, 16, expected_q_p16_9);
+ TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, float, f, 16, 8, expected_q_p16_10);
/* vreinterpret_f32_xx. */
TEST_VREINTERPRET_FP(, float, f, 32, 2, int, s, 8, 8, expected_f32_1);
@@ -696,6 +921,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET_FP(, float, f, 32, 2, uint, u, 64, 1, expected_f32_8);
TEST_VREINTERPRET_FP(, float, f, 32, 2, poly, p, 8, 8, expected_f32_9);
TEST_VREINTERPRET_FP(, float, f, 32, 2, poly, p, 16, 4, expected_f32_10);
+ TEST_VREINTERPRET_FP(, float, f, 32, 2, float, f, 16, 4, expected_f32_11);
/* vreinterpretq_f32_xx. */
TEST_VREINTERPRET_FP(q, float, f, 32, 4, int, s, 8, 16, expected_q_f32_1);
@@ -708,6 +934,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET_FP(q, float, f, 32, 4, uint, u, 64, 2, expected_q_f32_8);
TEST_VREINTERPRET_FP(q, float, f, 32, 4, poly, p, 8, 16, expected_q_f32_9);
TEST_VREINTERPRET_FP(q, float, f, 32, 4, poly, p, 16, 8, expected_q_f32_10);
+ TEST_VREINTERPRET_FP(q, float, f, 32, 4, float, f, 16, 8, expected_q_f32_11);
/* vreinterpret_xx_f32. */
TEST_VREINTERPRET(, int, s, 8, 8, float, f, 32, 2, expected_xx_f32_1);
@@ -720,6 +947,7 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(, uint, u, 64, 1, float, f, 32, 2, expected_xx_f32_8);
TEST_VREINTERPRET_POLY(, poly, p, 8, 8, float, f, 32, 2, expected_xx_f32_9);
TEST_VREINTERPRET_POLY(, poly, p, 16, 4, float, f, 32, 2, expected_xx_f32_10);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, float, f, 32, 2, expected_xx_f32_11);
/* vreinterpretq_xx_f32. */
TEST_VREINTERPRET(q, int, s, 8, 16, float, f, 32, 4, expected_q_xx_f32_1);
@@ -732,6 +960,31 @@ void exec_vreinterpret (void)
TEST_VREINTERPRET(q, uint, u, 64, 2, float, f, 32, 4, expected_q_xx_f32_8);
TEST_VREINTERPRET_POLY(q, poly, p, 8, 16, float, f, 32, 4, expected_q_xx_f32_9);
TEST_VREINTERPRET_POLY(q, poly, p, 16, 8, float, f, 32, 4, expected_q_xx_f32_10);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, float, f, 32, 4, expected_q_xx_f32_11);
+
+ /* vreinterpret_f16_xx. */
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, int, s, 8, 8, expected_f16_1);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, int, s, 16, 4, expected_f16_2);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, int, s, 32, 2, expected_f16_3);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, int, s, 64, 1, expected_f16_4);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, uint, u, 8, 8, expected_f16_5);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, uint, u, 16, 4, expected_f16_6);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, uint, u, 32, 2, expected_f16_7);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, uint, u, 64, 1, expected_f16_8);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, poly, p, 8, 8, expected_f16_9);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, poly, p, 16, 4, expected_f16_10);
+
+ /* vreinterpretq_f16_xx. */
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, int, s, 8, 16, expected_q_f16_1);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, int, s, 16, 8, expected_q_f16_2);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, int, s, 32, 4, expected_q_f16_3);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, int, s, 64, 2, expected_q_f16_4);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, uint, u, 8, 16, expected_q_f16_5);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, uint, u, 16, 8, expected_q_f16_6);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, uint, u, 32, 4, expected_q_f16_7);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, uint, u, 64, 2, expected_q_f16_8);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, poly, p, 8, 16, expected_q_f16_9);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, poly, p, 16, 8, expected_q_f16_10);
}
int main (void)
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c
new file mode 100644
index 00000000000..8ba5272bb10
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p128.c
@@ -0,0 +1,160 @@
+/* This file contains tests for the vreinterpret *p128 intrinsics. */
+
+/* { dg-require-effective-target arm_crypto_ok } */
+/* { dg-add-options arm_crypto } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results: vreinterpretq_p128_*. */
+VECT_VAR_DECL(vreint_expected_q_p128_s8,poly,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
+ 0xfffefdfcfbfaf9f8 };
+VECT_VAR_DECL(vreint_expected_q_p128_s16,poly,64,2) [] = { 0xfff3fff2fff1fff0,
+ 0xfff7fff6fff5fff4 };
+VECT_VAR_DECL(vreint_expected_q_p128_s32,poly,64,2) [] = { 0xfffffff1fffffff0,
+ 0xfffffff3fffffff2 };
+VECT_VAR_DECL(vreint_expected_q_p128_s64,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_p128_u8,poly,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
+ 0xfffefdfcfbfaf9f8 };
+VECT_VAR_DECL(vreint_expected_q_p128_u16,poly,64,2) [] = { 0xfff3fff2fff1fff0,
+ 0xfff7fff6fff5fff4 };
+VECT_VAR_DECL(vreint_expected_q_p128_u32,poly,64,2) [] = { 0xfffffff1fffffff0,
+ 0xfffffff3fffffff2 };
+VECT_VAR_DECL(vreint_expected_q_p128_u64,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_p128_p8,poly,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
+ 0xfffefdfcfbfaf9f8 };
+VECT_VAR_DECL(vreint_expected_q_p128_p16,poly,64,2) [] = { 0xfff3fff2fff1fff0,
+ 0xfff7fff6fff5fff4 };
+VECT_VAR_DECL(vreint_expected_q_p128_f32,poly,64,2) [] = { 0xc1700000c1800000,
+ 0xc1500000c1600000 };
+VECT_VAR_DECL(vreint_expected_q_p128_f16,poly,64,2) [] = { 0xca80cb00cb80cc00,
+ 0xc880c900c980ca00 };
+
+/* Expected results: vreinterpretq_*_p128. */
+VECT_VAR_DECL(vreint_expected_q_s8_p128,int,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_q_s16_p128,int,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_q_s32_p128,int,32,4) [] = { 0xfffffff0, 0xffffffff,
+ 0xfffffff1, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_q_s64_p128,int,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_u8_p128,uint,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_q_u16_p128,uint,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_q_u32_p128,uint,32,4) [] = { 0xfffffff0, 0xffffffff,
+ 0xfffffff1, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_q_u64_p128,uint,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_p8_p128,poly,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_q_p16_p128,poly,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_q_p64_p128,uint,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_f32_p128,hfloat,32,4) [] = { 0xfffffff0, 0xffffffff,
+ 0xfffffff1, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_q_f16_p128,hfloat,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+
+int main (void)
+{
+ DECL_VARIABLE_128BITS_VARIANTS(vreint_vector);
+ DECL_VARIABLE(vreint_vector, poly, 64, 2);
+ DECL_VARIABLE_128BITS_VARIANTS(vreint_vector_res);
+ DECL_VARIABLE(vreint_vector_res, poly, 64, 2);
+
+ clean_results ();
+
+ TEST_MACRO_128BITS_VARIANTS_2_5(VLOAD, vreint_vector, buffer);
+ VLOAD(vreint_vector, buffer, q, poly, p, 64, 2);
+ VLOAD(vreint_vector, buffer, q, float, f, 16, 8);
+ VLOAD(vreint_vector, buffer, q, float, f, 32, 4);
+
+ /* vreinterpretq_p128_* tests. */
+#undef TEST_MSG
+#define TEST_MSG "VREINTERPRETQ_P128_*"
+
+ /* Since there is no way to store a poly128_t value, convert to
+ poly64x2_t before storing. This means that we are not able to
+ test vreinterpretq_p128* alone, and that errors in
+ vreinterpretq_p64_p128 could compensate for errors in
+ vreinterpretq_p128*. */
+#define TEST_VREINTERPRET128(Q, T1, T2, W, N, TS1, TS2, WS, NS, EXPECTED) \
+ VECT_VAR(vreint_vector_res, poly, 64, 2) = vreinterpretq_p64_p128( \
+ vreinterpret##Q##_##T2##W##_##TS2##WS(VECT_VAR(vreint_vector, TS1, WS, NS))); \
+ vst1##Q##_##T2##64(VECT_VAR(result, poly, 64, 2), \
+ VECT_VAR(vreint_vector_res, poly, 64, 2)); \
+ CHECK(TEST_MSG, T1, 64, 2, PRIx##64, EXPECTED, "");
+
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, int, s, 8, 16, vreint_expected_q_p128_s8);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, int, s, 16, 8, vreint_expected_q_p128_s16);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, int, s, 32, 4, vreint_expected_q_p128_s32);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, int, s, 64, 2, vreint_expected_q_p128_s64);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, uint, u, 8, 16, vreint_expected_q_p128_u8);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, uint, u, 16, 8, vreint_expected_q_p128_u16);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, uint, u, 32, 4, vreint_expected_q_p128_u32);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, uint, u, 64, 2, vreint_expected_q_p128_u64);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, poly, p, 8, 16, vreint_expected_q_p128_p8);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, poly, p, 16, 8, vreint_expected_q_p128_p16);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, float, f, 16, 8, vreint_expected_q_p128_f16);
+ TEST_VREINTERPRET128(q, poly, p, 128, 1, float, f, 32, 4, vreint_expected_q_p128_f32);
+
+ /* vreinterpretq_*_p128 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VREINTERPRETQ_*_P128"
+
+ /* Since there is no way to load a poly128_t value, load a
+ poly64x2_t and convert it to poly128_t. This means that we are
+ not able to test vreinterpretq_*_p128 alone, and that errors in
+ vreinterpretq_p128_p64 could compensate for errors in
+ vreinterpretq_*_p128*. */
+#define TEST_VREINTERPRET_FROM_P128(Q, T1, T2, W, N, TS1, TS2, WS, NS, EXPECTED) \
+ VECT_VAR(vreint_vector_res, T1, W, N) = \
+ vreinterpret##Q##_##T2##W##_##TS2##WS( \
+ vreinterpretq_p128_p64(VECT_VAR(vreint_vector, TS1, 64, 2))); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), \
+ VECT_VAR(vreint_vector_res, T1, W, N)); \
+ CHECK(TEST_MSG, T1, W, N, PRIx##W, EXPECTED, "");
+
+#define TEST_VREINTERPRET_FP_FROM_P128(Q, T1, T2, W, N, TS1, TS2, WS, NS, EXPECTED) \
+ VECT_VAR(vreint_vector_res, T1, W, N) = \
+ vreinterpret##Q##_##T2##W##_##TS2##WS( \
+ vreinterpretq_p128_p64(VECT_VAR(vreint_vector, TS1, 64, 2))); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), \
+ VECT_VAR(vreint_vector_res, T1, W, N)); \
+ CHECK_FP(TEST_MSG, T1, W, N, PRIx##W, EXPECTED, "");
+
+ TEST_VREINTERPRET_FROM_P128(q, int, s, 8, 16, poly, p, 128, 1, vreint_expected_q_s8_p128);
+ TEST_VREINTERPRET_FROM_P128(q, int, s, 16, 8, poly, p, 128, 1, vreint_expected_q_s16_p128);
+ TEST_VREINTERPRET_FROM_P128(q, int, s, 32, 4, poly, p, 128, 1, vreint_expected_q_s32_p128);
+ TEST_VREINTERPRET_FROM_P128(q, int, s, 64, 2, poly, p, 128, 1, vreint_expected_q_s64_p128);
+ TEST_VREINTERPRET_FROM_P128(q, uint, u, 8, 16, poly, p, 128, 1, vreint_expected_q_u8_p128);
+ TEST_VREINTERPRET_FROM_P128(q, uint, u, 16, 8, poly, p, 128, 1, vreint_expected_q_u16_p128);
+ TEST_VREINTERPRET_FROM_P128(q, uint, u, 32, 4, poly, p, 128, 1, vreint_expected_q_u32_p128);
+ TEST_VREINTERPRET_FROM_P128(q, uint, u, 64, 2, poly, p, 128, 1, vreint_expected_q_u64_p128);
+ TEST_VREINTERPRET_FROM_P128(q, poly, p, 8, 16, poly, p, 128, 1, vreint_expected_q_p8_p128);
+ TEST_VREINTERPRET_FROM_P128(q, poly, p, 16, 8, poly, p, 128, 1, vreint_expected_q_p16_p128);
+ TEST_VREINTERPRET_FP_FROM_P128(q, float, f, 16, 8, poly, p, 128, 1, vreint_expected_q_f16_p128);
+ TEST_VREINTERPRET_FP_FROM_P128(q, float, f, 32, 4, poly, p, 128, 1, vreint_expected_q_f32_p128);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c
new file mode 100644
index 00000000000..b0007973d6a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vreinterpret_p64.c
@@ -0,0 +1,202 @@
+/* This file contains tests for the vreinterpret *p64 intrinsics. */
+
+/* { dg-require-effective-target arm_crypto_ok } */
+/* { dg-add-options arm_crypto } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results: vreinterpret_p64_*. */
+VECT_VAR_DECL(vreint_expected_p64_s8,poly,64,1) [] = { 0xf7f6f5f4f3f2f1f0 };
+VECT_VAR_DECL(vreint_expected_p64_s16,poly,64,1) [] = { 0xfff3fff2fff1fff0 };
+VECT_VAR_DECL(vreint_expected_p64_s32,poly,64,1) [] = { 0xfffffff1fffffff0 };
+VECT_VAR_DECL(vreint_expected_p64_s64,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vreint_expected_p64_u8,poly,64,1) [] = { 0xf7f6f5f4f3f2f1f0 };
+VECT_VAR_DECL(vreint_expected_p64_u16,poly,64,1) [] = { 0xfff3fff2fff1fff0 };
+VECT_VAR_DECL(vreint_expected_p64_u32,poly,64,1) [] = { 0xfffffff1fffffff0 };
+VECT_VAR_DECL(vreint_expected_p64_u64,poly,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vreint_expected_p64_p8,poly,64,1) [] = { 0xf7f6f5f4f3f2f1f0 };
+VECT_VAR_DECL(vreint_expected_p64_p16,poly,64,1) [] = { 0xfff3fff2fff1fff0 };
+VECT_VAR_DECL(vreint_expected_p64_f32,poly,64,1) [] = { 0xc1700000c1800000 };
+VECT_VAR_DECL(vreint_expected_p64_f16,poly,64,1) [] = { 0xca80cb00cb80cc00 };
+
+/* Expected results: vreinterpretq_p64_*. */
+VECT_VAR_DECL(vreint_expected_q_p64_s8,poly,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
+ 0xfffefdfcfbfaf9f8 };
+VECT_VAR_DECL(vreint_expected_q_p64_s16,poly,64,2) [] = { 0xfff3fff2fff1fff0,
+ 0xfff7fff6fff5fff4 };
+VECT_VAR_DECL(vreint_expected_q_p64_s32,poly,64,2) [] = { 0xfffffff1fffffff0,
+ 0xfffffff3fffffff2 };
+VECT_VAR_DECL(vreint_expected_q_p64_s64,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_p64_u8,poly,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
+ 0xfffefdfcfbfaf9f8 };
+VECT_VAR_DECL(vreint_expected_q_p64_u16,poly,64,2) [] = { 0xfff3fff2fff1fff0,
+ 0xfff7fff6fff5fff4 };
+VECT_VAR_DECL(vreint_expected_q_p64_u32,poly,64,2) [] = { 0xfffffff1fffffff0,
+ 0xfffffff3fffffff2 };
+VECT_VAR_DECL(vreint_expected_q_p64_u64,poly,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_p64_p8,poly,64,2) [] = { 0xf7f6f5f4f3f2f1f0,
+ 0xfffefdfcfbfaf9f8 };
+VECT_VAR_DECL(vreint_expected_q_p64_p16,poly,64,2) [] = { 0xfff3fff2fff1fff0,
+ 0xfff7fff6fff5fff4 };
+VECT_VAR_DECL(vreint_expected_q_p64_f32,poly,64,2) [] = { 0xc1700000c1800000,
+ 0xc1500000c1600000 };
+VECT_VAR_DECL(vreint_expected_q_p64_f16,poly,64,2) [] = { 0xca80cb00cb80cc00,
+ 0xc880c900c980ca00 };
+
+/* Expected results: vreinterpret_*_p64. */
+VECT_VAR_DECL(vreint_expected_s8_p64,int,8,8) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_s16_p64,int,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_s32_p64,int,32,2) [] = { 0xfffffff0, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_s64_p64,int,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vreint_expected_u8_p64,uint,8,8) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_u16_p64,uint,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_u32_p64,uint,32,2) [] = { 0xfffffff0, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_u64_p64,uint,64,1) [] = { 0xfffffffffffffff0 };
+VECT_VAR_DECL(vreint_expected_p8_p64,poly,8,8) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_p16_p64,poly,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_f32_p64,hfloat,32,2) [] = { 0xfffffff0, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_f16_p64,hfloat,16,4) [] = { 0xfff0, 0xffff, 0xffff, 0xffff };
+
+/* Expected results: vreinterpretq_*_p64. */
+VECT_VAR_DECL(vreint_expected_q_s8_p64,int,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_q_s16_p64,int,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_q_s32_p64,int,32,4) [] = { 0xfffffff0, 0xffffffff,
+ 0xfffffff1, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_q_s64_p64,int,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_u8_p64,uint,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_q_u16_p64,uint,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_q_u32_p64,uint,32,4) [] = { 0xfffffff0, 0xffffffff,
+ 0xfffffff1, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_q_u64_p64,uint,64,2) [] = { 0xfffffffffffffff0,
+ 0xfffffffffffffff1 };
+VECT_VAR_DECL(vreint_expected_q_p8_p64,poly,8,16) [] = { 0xf0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xf1, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(vreint_expected_q_p16_p64,poly,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+VECT_VAR_DECL(vreint_expected_q_f32_p64,hfloat,32,4) [] = { 0xfffffff0, 0xffffffff,
+ 0xfffffff1, 0xffffffff };
+VECT_VAR_DECL(vreint_expected_q_f16_p64,hfloat,16,8) [] = { 0xfff0, 0xffff,
+ 0xffff, 0xffff,
+ 0xfff1, 0xffff,
+ 0xffff, 0xffff };
+
+int main (void)
+{
+#define TEST_VREINTERPRET(Q, T1, T2, W, N, TS1, TS2, WS, NS, EXPECTED) \
+ VECT_VAR(vreint_vector_res, T1, W, N) = \
+ vreinterpret##Q##_##T2##W##_##TS2##WS(VECT_VAR(vreint_vector, TS1, WS, NS)); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), \
+ VECT_VAR(vreint_vector_res, T1, W, N)); \
+ CHECK(TEST_MSG, T1, W, N, PRIx##W, EXPECTED, "");
+
+#define TEST_VREINTERPRET_FP(Q, T1, T2, W, N, TS1, TS2, WS, NS, EXPECTED) \
+ VECT_VAR(vreint_vector_res, T1, W, N) = \
+ vreinterpret##Q##_##T2##W##_##TS2##WS(VECT_VAR(vreint_vector, TS1, WS, NS)); \
+ vst1##Q##_##T2##W(VECT_VAR(result, T1, W, N), \
+ VECT_VAR(vreint_vector_res, T1, W, N)); \
+ CHECK_FP(TEST_MSG, T1, W, N, PRIx##W, EXPECTED, "");
+
+ DECL_VARIABLE_ALL_VARIANTS(vreint_vector);
+ DECL_VARIABLE(vreint_vector, poly, 64, 1);
+ DECL_VARIABLE(vreint_vector, poly, 64, 2);
+ DECL_VARIABLE_ALL_VARIANTS(vreint_vector_res);
+ DECL_VARIABLE(vreint_vector_res, poly, 64, 1);
+ DECL_VARIABLE(vreint_vector_res, poly, 64, 2);
+
+ clean_results ();
+
+ TEST_MACRO_ALL_VARIANTS_2_5(VLOAD, vreint_vector, buffer);
+ VLOAD(vreint_vector, buffer, , poly, p, 64, 1);
+ VLOAD(vreint_vector, buffer, q, poly, p, 64, 2);
+ VLOAD(vreint_vector, buffer, , float, f, 16, 4);
+ VLOAD(vreint_vector, buffer, q, float, f, 16, 8);
+ VLOAD(vreint_vector, buffer, , float, f, 32, 2);
+ VLOAD(vreint_vector, buffer, q, float, f, 32, 4);
+
+ /* vreinterpret_p64_* tests. */
+#undef TEST_MSG
+#define TEST_MSG "VREINTERPRET_P64_*"
+ TEST_VREINTERPRET(, poly, p, 64, 1, int, s, 8, 8, vreint_expected_p64_s8);
+ TEST_VREINTERPRET(, poly, p, 64, 1, int, s, 16, 4, vreint_expected_p64_s16);
+ TEST_VREINTERPRET(, poly, p, 64, 1, int, s, 32, 2, vreint_expected_p64_s32);
+ TEST_VREINTERPRET(, poly, p, 64, 1, int, s, 64, 1, vreint_expected_p64_s64);
+ TEST_VREINTERPRET(, poly, p, 64, 1, uint, u, 8, 8, vreint_expected_p64_u8);
+ TEST_VREINTERPRET(, poly, p, 64, 1, uint, u, 16, 4, vreint_expected_p64_u16);
+ TEST_VREINTERPRET(, poly, p, 64, 1, uint, u, 32, 2, vreint_expected_p64_u32);
+ TEST_VREINTERPRET(, poly, p, 64, 1, uint, u, 64, 1, vreint_expected_p64_u64);
+ TEST_VREINTERPRET(, poly, p, 64, 1, poly, p, 8, 8, vreint_expected_p64_p8);
+ TEST_VREINTERPRET(, poly, p, 64, 1, poly, p, 16, 4, vreint_expected_p64_p16);
+ TEST_VREINTERPRET(, poly, p, 64, 1, float, f, 16, 4, vreint_expected_p64_f16);
+ TEST_VREINTERPRET(, poly, p, 64, 1, float, f, 32, 2, vreint_expected_p64_f32);
+
+ /* vreinterpretq_p64_* tests. */
+#undef TEST_MSG
+#define TEST_MSG "VREINTERPRETQ_P64_*"
+ TEST_VREINTERPRET(q, poly, p, 64, 2, int, s, 8, 16, vreint_expected_q_p64_s8);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, int, s, 16, 8, vreint_expected_q_p64_s16);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, int, s, 32, 4, vreint_expected_q_p64_s32);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, int, s, 64, 2, vreint_expected_q_p64_s64);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, uint, u, 8, 16, vreint_expected_q_p64_u8);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, uint, u, 16, 8, vreint_expected_q_p64_u16);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, uint, u, 32, 4, vreint_expected_q_p64_u32);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, uint, u, 64, 2, vreint_expected_q_p64_u64);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, poly, p, 8, 16, vreint_expected_q_p64_p8);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, poly, p, 16, 8, vreint_expected_q_p64_p16);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, float, f, 16, 8, vreint_expected_q_p64_f16);
+ TEST_VREINTERPRET(q, poly, p, 64, 2, float, f, 32, 4, vreint_expected_q_p64_f32);
+
+ /* vreinterpret_*_p64 tests. */
+#undef TEST_MSG
+#define TEST_MSG "VREINTERPRET_*_P64"
+
+ TEST_VREINTERPRET(, int, s, 8, 8, poly, p, 64, 1, vreint_expected_s8_p64);
+ TEST_VREINTERPRET(, int, s, 16, 4, poly, p, 64, 1, vreint_expected_s16_p64);
+ TEST_VREINTERPRET(, int, s, 32, 2, poly, p, 64, 1, vreint_expected_s32_p64);
+ TEST_VREINTERPRET(, int, s, 64, 1, poly, p, 64, 1, vreint_expected_s64_p64);
+ TEST_VREINTERPRET(, uint, u, 8, 8, poly, p, 64, 1, vreint_expected_u8_p64);
+ TEST_VREINTERPRET(, uint, u, 16, 4, poly, p, 64, 1, vreint_expected_u16_p64);
+ TEST_VREINTERPRET(, uint, u, 32, 2, poly, p, 64, 1, vreint_expected_u32_p64);
+ TEST_VREINTERPRET(, uint, u, 64, 1, poly, p, 64, 1, vreint_expected_u64_p64);
+ TEST_VREINTERPRET(, poly, p, 8, 8, poly, p, 64, 1, vreint_expected_p8_p64);
+ TEST_VREINTERPRET(, poly, p, 16, 4, poly, p, 64, 1, vreint_expected_p16_p64);
+ TEST_VREINTERPRET_FP(, float, f, 16, 4, poly, p, 64, 1, vreint_expected_f16_p64);
+ TEST_VREINTERPRET_FP(, float, f, 32, 2, poly, p, 64, 1, vreint_expected_f32_p64);
+ TEST_VREINTERPRET(q, int, s, 8, 16, poly, p, 64, 2, vreint_expected_q_s8_p64);
+ TEST_VREINTERPRET(q, int, s, 16, 8, poly, p, 64, 2, vreint_expected_q_s16_p64);
+ TEST_VREINTERPRET(q, int, s, 32, 4, poly, p, 64, 2, vreint_expected_q_s32_p64);
+ TEST_VREINTERPRET(q, int, s, 64, 2, poly, p, 64, 2, vreint_expected_q_s64_p64);
+ TEST_VREINTERPRET(q, uint, u, 8, 16, poly, p, 64, 2, vreint_expected_q_u8_p64);
+ TEST_VREINTERPRET(q, uint, u, 16, 8, poly, p, 64, 2, vreint_expected_q_u16_p64);
+ TEST_VREINTERPRET(q, uint, u, 32, 4, poly, p, 64, 2, vreint_expected_q_u32_p64);
+ TEST_VREINTERPRET(q, uint, u, 64, 2, poly, p, 64, 2, vreint_expected_q_u64_p64);
+ TEST_VREINTERPRET(q, poly, p, 8, 16, poly, p, 64, 2, vreint_expected_q_p8_p64);
+ TEST_VREINTERPRET(q, poly, p, 16, 8, poly, p, 64, 2, vreint_expected_q_p16_p64);
+ TEST_VREINTERPRET_FP(q, float, f, 16, 8, poly, p, 64, 2, vreint_expected_q_f16_p64);
+ TEST_VREINTERPRET_FP(q, float, f, 32, 4, poly, p, 64, 2, vreint_expected_q_f32_p64);
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrnd.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrnd.c
new file mode 100644
index 00000000000..5f492d41bff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrnd.c
@@ -0,0 +1,16 @@
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-add-options arm_v8_neon } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results. */
+VECT_VAR_DECL (expected, hfloat, 32, 2) [] = { 0xc1800000, 0xc1700000 };
+VECT_VAR_DECL (expected, hfloat, 32, 4) [] = { 0xc1800000, 0xc1700000,
+ 0xc1600000, 0xc1500000 };
+
+#define INSN vrnd
+#define TEST_MSG "VRND"
+
+#include "vrndX.inc"
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndX.inc b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndX.inc
new file mode 100644
index 00000000000..629240d3a23
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndX.inc
@@ -0,0 +1,43 @@
+#define FNNAME1(NAME) exec_ ## NAME
+#define FNNAME(NAME) FNNAME1 (NAME)
+
+void FNNAME (INSN) (void)
+{
+ /* vector_res = vrndX (vector), then store the result. */
+#define TEST_VRND2(INSN, Q, T1, T2, W, N) \
+ VECT_VAR (vector_res, T1, W, N) = \
+ INSN##Q##_##T2##W (VECT_VAR (vector, T1, W, N)); \
+ vst1##Q##_##T2##W (VECT_VAR (result, T1, W, N), \
+ VECT_VAR (vector_res, T1, W, N))
+
+ /* Two auxliary macros are necessary to expand INSN. */
+#define TEST_VRND1(INSN, Q, T1, T2, W, N) \
+ TEST_VRND2 (INSN, Q, T1, T2, W, N)
+
+#define TEST_VRND(Q, T1, T2, W, N) \
+ TEST_VRND1 (INSN, Q, T1, T2, W, N)
+
+ DECL_VARIABLE (vector, float, 32, 2);
+ DECL_VARIABLE (vector, float, 32, 4);
+
+ DECL_VARIABLE (vector_res, float, 32, 2);
+ DECL_VARIABLE (vector_res, float, 32, 4);
+
+ clean_results ();
+
+ VLOAD (vector, buffer, , float, f, 32, 2);
+ VLOAD (vector, buffer, q, float, f, 32, 4);
+
+ TEST_VRND ( , float, f, 32, 2);
+ TEST_VRND (q, float, f, 32, 4);
+
+ CHECK_FP (TEST_MSG, float, 32, 2, PRIx32, expected, "");
+ CHECK_FP (TEST_MSG, float, 32, 4, PRIx32, expected, "");
+}
+
+int
+main (void)
+{
+ FNNAME (INSN) ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrnda.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrnda.c
new file mode 100644
index 00000000000..816fd28dd19
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrnda.c
@@ -0,0 +1,16 @@
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-add-options arm_v8_neon } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results. */
+VECT_VAR_DECL (expected, hfloat, 32, 2) [] = { 0xc1800000, 0xc1700000 };
+VECT_VAR_DECL (expected, hfloat, 32, 4) [] = { 0xc1800000, 0xc1700000,
+ 0xc1600000, 0xc1500000 };
+
+#define INSN vrnda
+#define TEST_MSG "VRNDA"
+
+#include "vrndX.inc"
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndm.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndm.c
new file mode 100644
index 00000000000..029880c21f6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndm.c
@@ -0,0 +1,16 @@
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-add-options arm_v8_neon } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results. */
+VECT_VAR_DECL (expected, hfloat, 32, 2) [] = { 0xc1800000, 0xc1700000 };
+VECT_VAR_DECL (expected, hfloat, 32, 4) [] = { 0xc1800000, 0xc1700000,
+ 0xc1600000, 0xc1500000 };
+
+#define INSN vrndm
+#define TEST_MSG "VRNDM"
+
+#include "vrndX.inc"
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndn.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndn.c
new file mode 100644
index 00000000000..571243c4929
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndn.c
@@ -0,0 +1,16 @@
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-add-options arm_v8_neon } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results. */
+VECT_VAR_DECL (expected, hfloat, 32, 2) [] = { 0xc1800000, 0xc1700000 };
+VECT_VAR_DECL (expected, hfloat, 32, 4) [] = { 0xc1800000, 0xc1700000,
+ 0xc1600000, 0xc1500000 };
+
+#define INSN vrndn
+#define TEST_MSG "VRNDN"
+
+#include "vrndX.inc"
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndp.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndp.c
new file mode 100644
index 00000000000..ff4771c8789
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndp.c
@@ -0,0 +1,16 @@
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-add-options arm_v8_neon } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results. */
+VECT_VAR_DECL (expected, hfloat, 32, 2) [] = { 0xc1800000, 0xc1700000 };
+VECT_VAR_DECL (expected, hfloat, 32, 4) [] = { 0xc1800000, 0xc1700000,
+ 0xc1600000, 0xc1500000 };
+
+#define INSN vrndp
+#define TEST_MSG "VRNDP"
+
+#include "vrndX.inc"
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndx.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndx.c
new file mode 100644
index 00000000000..ff2357bebf3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vrndx.c
@@ -0,0 +1,16 @@
+/* { dg-require-effective-target arm_v8_neon_ok } */
+/* { dg-add-options arm_v8_neon } */
+
+#include <arm_neon.h>
+#include "arm-neon-ref.h"
+#include "compute-ref-data.h"
+
+/* Expected results. */
+VECT_VAR_DECL (expected, hfloat, 32, 2) [] = { 0xc1800000, 0xc1700000 };
+VECT_VAR_DECL (expected, hfloat, 32, 4) [] = { 0xc1800000, 0xc1700000,
+ 0xc1600000, 0xc1500000 };
+
+#define INSN vrndx
+#define TEST_MSG "VRNDX"
+
+#include "vrndX.inc"
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vshl.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vshl.c
index 821c11e2063..e8a57a4113d 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vshl.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vshl.c
@@ -101,10 +101,8 @@ VECT_VAR_DECL(expected_negative_shift,uint,64,2) [] = { 0x7ffffffffffffff,
0x7ffffffffffffff };
-#ifndef INSN_NAME
#define INSN_NAME vshl
#define TEST_MSG "VSHL/VSHLQ"
-#endif
#define FNNAME1(NAME) exec_ ## NAME
#define FNNAME(NAME) FNNAME1(NAME)
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vsli_n.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vsli_n.c
index 0285083425d..91115e5f426 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vsli_n.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vsli_n.c
@@ -166,9 +166,11 @@ void vsli_extra(void)
CHECK(TEST_MSG, int, 8, 16, PRIx8, expected_max_shift, COMMENT);
CHECK(TEST_MSG, int, 16, 8, PRIx16, expected_max_shift, COMMENT);
CHECK(TEST_MSG, int, 32, 4, PRIx32, expected_max_shift, COMMENT);
+ CHECK(TEST_MSG, int, 64, 2, PRIx64, expected_max_shift, COMMENT);
CHECK(TEST_MSG, uint, 8, 16, PRIx8, expected_max_shift, COMMENT);
CHECK(TEST_MSG, uint, 16, 8, PRIx16, expected_max_shift, COMMENT);
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_max_shift, COMMENT);
+ CHECK(TEST_MSG, uint, 64, 2, PRIx64, expected_max_shift, COMMENT);
CHECK(TEST_MSG, poly, 8, 16, PRIx8, expected_max_shift, COMMENT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_max_shift, COMMENT);
}
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c
index b923b644124..282edd591a0 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vstX_lane.c
@@ -14,6 +14,7 @@ VECT_VAR_DECL(expected_st2_0,uint,32,2) [] = { 0xfffffff0, 0xfffffff1 };
VECT_VAR_DECL(expected_st2_0,poly,8,8) [] = { 0xf0, 0xf1, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_0,poly,16,4) [] = { 0xfff0, 0xfff1, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st2_0,hfloat,16,4) [] = { 0xcc00, 0xcb80, 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_0,hfloat,32,2) [] = { 0xc1800000, 0xc1700000 };
VECT_VAR_DECL(expected_st2_0,int,16,8) [] = { 0xfff0, 0xfff1, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
@@ -24,6 +25,8 @@ VECT_VAR_DECL(expected_st2_0,uint,32,4) [] = { 0xfffffff0, 0xfffffff1,
0x0, 0x0 };
VECT_VAR_DECL(expected_st2_0,poly,16,8) [] = { 0xfff0, 0xfff1, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st2_0,hfloat,16,8) [] = { 0xcc00, 0xcb80, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_0,hfloat,32,4) [] = { 0xc1800000, 0xc1700000,
0x0, 0x0 };
@@ -39,6 +42,7 @@ VECT_VAR_DECL(expected_st2_1,uint,32,2) [] = { 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_1,poly,8,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_1,poly,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st2_1,hfloat,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_1,hfloat,32,2) [] = { 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_1,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
@@ -48,6 +52,8 @@ VECT_VAR_DECL(expected_st2_1,uint,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
VECT_VAR_DECL(expected_st2_1,uint,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_1,poly,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st2_1,hfloat,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st2_1,hfloat,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
/* Expected results for vst3, chunk 0. */
@@ -62,6 +68,7 @@ VECT_VAR_DECL(expected_st3_0,uint,32,2) [] = { 0xfffffff0, 0xfffffff1 };
VECT_VAR_DECL(expected_st3_0,poly,8,8) [] = { 0xf0, 0xf1, 0xf2, 0x0,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_0,poly,16,4) [] = { 0xfff0, 0xfff1, 0xfff2, 0x0 };
+VECT_VAR_DECL(expected_st3_0,hfloat,16,4) [] = { 0xcc00, 0xcb80, 0xcb00, 0x0 };
VECT_VAR_DECL(expected_st3_0,hfloat,32,2) [] = { 0xc1800000, 0xc1700000 };
VECT_VAR_DECL(expected_st3_0,int,16,8) [] = { 0xfff0, 0xfff1, 0xfff2, 0x0,
0x0, 0x0, 0x0, 0x0 };
@@ -73,6 +80,8 @@ VECT_VAR_DECL(expected_st3_0,uint,32,4) [] = { 0xfffffff0, 0xfffffff1,
0xfffffff2, 0x0 };
VECT_VAR_DECL(expected_st3_0,poly,16,8) [] = { 0xfff0, 0xfff1, 0xfff2, 0x0,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st3_0,hfloat,16,8) [] = { 0xcc00, 0xcb80, 0xcb00, 0x0,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_0,hfloat,32,4) [] = { 0xc1800000, 0xc1700000,
0xc1600000, 0x0 };
@@ -88,6 +97,7 @@ VECT_VAR_DECL(expected_st3_1,uint,32,2) [] = { 0xfffffff2, 0x0 };
VECT_VAR_DECL(expected_st3_1,poly,8,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_1,poly,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st3_1,hfloat,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_1,hfloat,32,2) [] = { 0xc1600000, 0x0 };
VECT_VAR_DECL(expected_st3_1,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
@@ -97,6 +107,8 @@ VECT_VAR_DECL(expected_st3_1,uint,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
VECT_VAR_DECL(expected_st3_1,uint,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_1,poly,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st3_1,hfloat,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_1,hfloat,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
/* Expected results for vst3, chunk 2. */
@@ -111,6 +123,7 @@ VECT_VAR_DECL(expected_st3_2,uint,32,2) [] = { 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_2,poly,8,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_2,poly,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st3_2,hfloat,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_2,hfloat,32,2) [] = { 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_2,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
@@ -120,6 +133,8 @@ VECT_VAR_DECL(expected_st3_2,uint,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
VECT_VAR_DECL(expected_st3_2,uint,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_2,poly,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st3_2,hfloat,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st3_2,hfloat,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
/* Expected results for vst4, chunk 0. */
@@ -134,6 +149,7 @@ VECT_VAR_DECL(expected_st4_0,uint,32,2) [] = { 0xfffffff0, 0xfffffff1 };
VECT_VAR_DECL(expected_st4_0,poly,8,8) [] = { 0xf0, 0xf1, 0xf2, 0xf3,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_0,poly,16,4) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3 };
+VECT_VAR_DECL(expected_st4_0,hfloat,16,4) [] = { 0xcc00, 0xcb80, 0xcb00, 0xca80 };
VECT_VAR_DECL(expected_st4_0,hfloat,32,2) [] = { 0xc1800000, 0xc1700000 };
VECT_VAR_DECL(expected_st4_0,int,16,8) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3,
0x0, 0x0, 0x0, 0x0 };
@@ -145,6 +161,8 @@ VECT_VAR_DECL(expected_st4_0,uint,32,4) [] = { 0xfffffff0, 0xfffffff1,
0xfffffff2, 0xfffffff3 };
VECT_VAR_DECL(expected_st4_0,poly,16,8) [] = { 0xfff0, 0xfff1, 0xfff2, 0xfff3,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st4_0,hfloat,16,8) [] = { 0xcc00, 0xcb80, 0xcb00, 0xca80,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_0,hfloat,32,4) [] = { 0xc1800000, 0xc1700000,
0xc1600000, 0xc1500000 };
@@ -160,6 +178,7 @@ VECT_VAR_DECL(expected_st4_1,uint,32,2) [] = { 0xfffffff2, 0xfffffff3 };
VECT_VAR_DECL(expected_st4_1,poly,8,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_1,poly,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st4_1,hfloat,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_1,hfloat,32,2) [] = { 0xc1600000, 0xc1500000 };
VECT_VAR_DECL(expected_st4_1,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
@@ -169,6 +188,8 @@ VECT_VAR_DECL(expected_st4_1,uint,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
VECT_VAR_DECL(expected_st4_1,uint,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_1,poly,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st4_1,hfloat,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_1,hfloat,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
/* Expected results for vst4, chunk 2. */
@@ -183,6 +204,7 @@ VECT_VAR_DECL(expected_st4_2,uint,32,2) [] = { 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_2,poly,8,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_2,poly,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st4_2,hfloat,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_2,hfloat,32,2) [] = { 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_2,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
@@ -192,6 +214,8 @@ VECT_VAR_DECL(expected_st4_2,uint,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
VECT_VAR_DECL(expected_st4_2,uint,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_2,poly,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st4_2,hfloat,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_2,hfloat,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
/* Expected results for vst4, chunk 3. */
@@ -206,6 +230,7 @@ VECT_VAR_DECL(expected_st4_3,uint,32,2) [] = { 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_3,poly,8,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_3,poly,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st4_3,hfloat,16,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_3,hfloat,32,2) [] = { 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_3,int,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
@@ -215,6 +240,8 @@ VECT_VAR_DECL(expected_st4_3,uint,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
VECT_VAR_DECL(expected_st4_3,uint,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_3,poly,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
0x0, 0x0, 0x0, 0x0 };
+VECT_VAR_DECL(expected_st4_3,hfloat,16,8) [] = { 0x0, 0x0, 0x0, 0x0,
+ 0x0, 0x0, 0x0, 0x0 };
VECT_VAR_DECL(expected_st4_3,hfloat,32,4) [] = { 0x0, 0x0, 0x0, 0x0 };
/* Declare additional input buffers as needed. */
@@ -229,6 +256,7 @@ VECT_VAR_DECL_INIT(buffer_vld2_lane, uint, 32, 2);
VECT_VAR_DECL_INIT(buffer_vld2_lane, uint, 64, 2);
VECT_VAR_DECL_INIT(buffer_vld2_lane, poly, 8, 2);
VECT_VAR_DECL_INIT(buffer_vld2_lane, poly, 16, 2);
+VECT_VAR_DECL_INIT(buffer_vld2_lane, float, 16, 2);
VECT_VAR_DECL_INIT(buffer_vld2_lane, float, 32, 2);
/* Input buffers for vld3_lane. */
@@ -242,6 +270,7 @@ VECT_VAR_DECL_INIT(buffer_vld3_lane, uint, 32, 3);
VECT_VAR_DECL_INIT(buffer_vld3_lane, uint, 64, 3);
VECT_VAR_DECL_INIT(buffer_vld3_lane, poly, 8, 3);
VECT_VAR_DECL_INIT(buffer_vld3_lane, poly, 16, 3);
+VECT_VAR_DECL_INIT(buffer_vld3_lane, float, 16, 3);
VECT_VAR_DECL_INIT(buffer_vld3_lane, float, 32, 3);
/* Input buffers for vld4_lane. */
@@ -255,6 +284,7 @@ VECT_VAR_DECL_INIT(buffer_vld4_lane, uint, 32, 4);
VECT_VAR_DECL_INIT(buffer_vld4_lane, uint, 64, 4);
VECT_VAR_DECL_INIT(buffer_vld4_lane, poly, 8, 4);
VECT_VAR_DECL_INIT(buffer_vld4_lane, poly, 16, 4);
+VECT_VAR_DECL_INIT(buffer_vld4_lane, float, 16, 4);
VECT_VAR_DECL_INIT(buffer_vld4_lane, float, 32, 4);
void exec_vstX_lane (void)
@@ -302,7 +332,7 @@ void exec_vstX_lane (void)
/* We need all variants in 64 bits, but there is no 64x2 variant,
nor 128 bits vectors of int8/uint8/poly8. */
-#define DECL_ALL_VSTX_LANE(X) \
+#define DECL_ALL_VSTX_LANE_NO_FP16(X) \
DECL_VSTX_LANE(int, 8, 8, X); \
DECL_VSTX_LANE(int, 16, 4, X); \
DECL_VSTX_LANE(int, 32, 2, X); \
@@ -319,11 +349,20 @@ void exec_vstX_lane (void)
DECL_VSTX_LANE(poly, 16, 8, X); \
DECL_VSTX_LANE(float, 32, 4, X)
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+#define DECL_ALL_VSTX_LANE(X) \
+ DECL_ALL_VSTX_LANE_NO_FP16(X); \
+ DECL_VSTX_LANE(float, 16, 4, X); \
+ DECL_VSTX_LANE(float, 16, 8, X)
+#else
+#define DECL_ALL_VSTX_LANE(X) DECL_ALL_VSTX_LANE_NO_FP16(X)
+#endif
+
#define DUMMY_ARRAY(V, T, W, N, L) VECT_VAR_DECL(V,T,W,N)[N*L]
/* Use the same lanes regardless of the size of the array (X), for
simplicity. */
-#define TEST_ALL_VSTX_LANE(X) \
+#define TEST_ALL_VSTX_LANE_NO_FP16(X) \
TEST_VSTX_LANE(, int, s, 8, 8, X, 7); \
TEST_VSTX_LANE(, int, s, 16, 4, X, 2); \
TEST_VSTX_LANE(, int, s, 32, 2, X, 0); \
@@ -340,7 +379,16 @@ void exec_vstX_lane (void)
TEST_VSTX_LANE(q, poly, p, 16, 8, X, 5); \
TEST_VSTX_LANE(q, float, f, 32, 4, X, 2)
-#define TEST_ALL_EXTRA_CHUNKS(X, Y) \
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+#define TEST_ALL_VSTX_LANE(X) \
+ TEST_ALL_VSTX_LANE_NO_FP16(X); \
+ TEST_VSTX_LANE(, float, f, 16, 4, X, 2); \
+ TEST_VSTX_LANE(q, float, f, 16, 8, X, 6)
+#else
+#define TEST_ALL_VSTX_LANE(X) TEST_ALL_VSTX_LANE_NO_FP16(X)
+#endif
+
+#define TEST_ALL_EXTRA_CHUNKS_NO_FP16(X, Y) \
TEST_EXTRA_CHUNK(int, 8, 8, X, Y); \
TEST_EXTRA_CHUNK(int, 16, 4, X, Y); \
TEST_EXTRA_CHUNK(int, 32, 2, X, Y); \
@@ -357,6 +405,15 @@ void exec_vstX_lane (void)
TEST_EXTRA_CHUNK(poly, 16, 8, X, Y); \
TEST_EXTRA_CHUNK(float, 32, 4, X, Y)
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+#define TEST_ALL_EXTRA_CHUNKS(X,Y) \
+ TEST_ALL_EXTRA_CHUNKS_NO_FP16(X, Y); \
+ TEST_EXTRA_CHUNK(float, 16, 4, X, Y); \
+ TEST_EXTRA_CHUNK(float, 16, 8, X, Y)
+#else
+#define TEST_ALL_EXTRA_CHUNKS(X,Y) TEST_ALL_EXTRA_CHUNKS_NO_FP16(X, Y)
+#endif
+
/* Declare the temporary buffers / variables. */
DECL_ALL_VSTX_LANE(2);
DECL_ALL_VSTX_LANE(3);
@@ -371,12 +428,18 @@ void exec_vstX_lane (void)
DUMMY_ARRAY(buffer_src, uint, 32, 2, 4);
DUMMY_ARRAY(buffer_src, poly, 8, 8, 4);
DUMMY_ARRAY(buffer_src, poly, 16, 4, 4);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ DUMMY_ARRAY(buffer_src, float, 16, 4, 4);
+#endif
DUMMY_ARRAY(buffer_src, float, 32, 2, 4);
DUMMY_ARRAY(buffer_src, int, 16, 8, 4);
DUMMY_ARRAY(buffer_src, int, 32, 4, 4);
DUMMY_ARRAY(buffer_src, uint, 16, 8, 4);
DUMMY_ARRAY(buffer_src, uint, 32, 4, 4);
DUMMY_ARRAY(buffer_src, poly, 16, 8, 4);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ DUMMY_ARRAY(buffer_src, float, 16, 8, 4);
+#endif
DUMMY_ARRAY(buffer_src, float, 32, 4, 4);
/* Check vst2_lane/vst2q_lane. */
@@ -400,6 +463,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st2_0, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st2_0, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st2_0, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st2_0, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st2_0, CMT);
+#endif
TEST_ALL_EXTRA_CHUNKS(2, 1);
#undef CMT
@@ -419,6 +486,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st2_1, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st2_1, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st2_1, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st2_1, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st2_1, CMT);
+#endif
/* Check vst3_lane/vst3q_lane. */
@@ -444,6 +515,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st3_0, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st3_0, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st3_0, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st3_0, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st3_0, CMT);
+#endif
TEST_ALL_EXTRA_CHUNKS(3, 1);
@@ -464,6 +539,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st3_1, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st3_1, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st3_1, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st3_1, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st3_1, CMT);
+#endif
TEST_ALL_EXTRA_CHUNKS(3, 2);
@@ -484,6 +563,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st3_2, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st3_2, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st3_2, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st3_2, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st3_2, CMT);
+#endif
/* Check vst4_lane/vst4q_lane. */
@@ -509,6 +592,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st4_0, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st4_0, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st4_0, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st4_0, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st4_0, CMT);
+#endif
TEST_ALL_EXTRA_CHUNKS(4, 1);
@@ -529,6 +616,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st4_1, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st4_1, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st4_1, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st4_1, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st4_1, CMT);
+#endif
TEST_ALL_EXTRA_CHUNKS(4, 2);
@@ -549,6 +640,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st4_2, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st4_2, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st4_2, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st4_2, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st4_2, CMT);
+#endif
TEST_ALL_EXTRA_CHUNKS(4, 3);
@@ -569,6 +664,10 @@ void exec_vstX_lane (void)
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_st4_3, CMT);
CHECK(TEST_MSG, poly, 16, 8, PRIx16, expected_st4_3, CMT);
CHECK_FP(TEST_MSG, float, 32, 4, PRIx32, expected_st4_3, CMT);
+#if defined (__ARM_FP16_FORMAT_IEEE) || defined (__ARM_FP16_FORMAT_ALTERNATIVE)
+ CHECK_FP(TEST_MSG, float, 16, 4, PRIx16, expected_st4_3, CMT);
+ CHECK_FP(TEST_MSG, float, 16, 8, PRIx16, expected_st4_3, CMT);
+#endif
}
int main (void)
diff --git a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vtst.c b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vtst.c
index 7f965407d67..8f9e6516144 100644
--- a/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vtst.c
+++ b/gcc/testsuite/gcc.target/aarch64/advsimd-intrinsics/vtst.c
@@ -32,10 +32,21 @@ VECT_VAR_DECL(expected_unsigned,uint,16,8) [] = { 0x0, 0xffff,
VECT_VAR_DECL(expected_unsigned,uint,32,4) [] = { 0x0, 0xffffffff,
0x0, 0xffffffff };
-#ifndef INSN_NAME
+/* Expected results with poly input. */
+VECT_VAR_DECL(expected_poly,uint,8,8) [] = { 0x0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(expected_poly,uint,8,16) [] = { 0x0, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff,
+ 0xff, 0xff, 0xff, 0xff };
+VECT_VAR_DECL(expected_poly,uint,16,4) [] = { 0x0, 0xffff, 0x0, 0xffff };
+VECT_VAR_DECL(expected_poly,uint,16,8) [] = { 0x0, 0xffff,
+ 0x0, 0xffff,
+ 0xffff, 0xffff,
+ 0xffff, 0xffff };
+
#define INSN_NAME vtst
#define TEST_MSG "VTST/VTSTQ"
-#endif
/* We can't use the standard ref_v_binary_op.c template because vtst
has no 64 bits variant, and outputs are always of uint type. */
@@ -73,12 +84,16 @@ FNNAME (INSN_NAME)
VDUP(vector2, , uint, u, 8, 8, 15);
VDUP(vector2, , uint, u, 16, 4, 5);
VDUP(vector2, , uint, u, 32, 2, 1);
+ VDUP(vector2, , poly, p, 8, 8, 15);
+ VDUP(vector2, , poly, p, 16, 4, 5);
VDUP(vector2, q, int, s, 8, 16, 15);
VDUP(vector2, q, int, s, 16, 8, 5);
VDUP(vector2, q, int, s, 32, 4, 1);
VDUP(vector2, q, uint, u, 8, 16, 15);
VDUP(vector2, q, uint, u, 16, 8, 5);
VDUP(vector2, q, uint, u, 32, 4, 1);
+ VDUP(vector2, q, poly, p, 8, 16, 15);
+ VDUP(vector2, q, poly, p, 16, 8, 5);
#define TEST_MACRO_NO64BIT_VARIANT_1_5(MACRO, VAR, T1, T2) \
MACRO(VAR, , T1, T2, 8, 8); \
@@ -111,6 +126,18 @@ FNNAME (INSN_NAME)
CHECK(TEST_MSG, uint, 8, 16, PRIx8, expected_unsigned, CMT);
CHECK(TEST_MSG, uint, 16, 8, PRIx16, expected_unsigned, CMT);
CHECK(TEST_MSG, uint, 32, 4, PRIx32, expected_unsigned, CMT);
+
+ /* Now, test the variants with poly8 and poly16 as input. */
+#undef CMT
+#define CMT " (poly input)"
+ TEST_BINARY_OP(INSN_NAME, , poly, p, 8, 8);
+ TEST_BINARY_OP(INSN_NAME, , poly, p, 16, 4);
+ TEST_BINARY_OP(INSN_NAME, q, poly, p, 8, 16);
+ TEST_BINARY_OP(INSN_NAME, q, poly, p, 16, 8);
+ CHECK(TEST_MSG, uint, 8, 8, PRIx8, expected_poly, CMT);
+ CHECK(TEST_MSG, uint, 16, 4, PRIx16, expected_poly, CMT);
+ CHECK(TEST_MSG, uint, 8, 16, PRIx8, expected_poly, CMT);
+ CHECK(TEST_MSG, uint, 16, 8, PRIx16, expected_poly, CMT);
}
int main (void)
diff --git a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-1.c b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-1.c
index de6b8a7da4d..ddba6554471 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-1.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-1.c
@@ -1,4 +1,5 @@
/* { dg-error "unknown" "" {target "aarch64*-*-*" } } */
+/* { dg-skip-if "do not override -mcpu" { *-*-* } { "-mcpu=*" } { "" } } */
/* { dg-options "-O2 -mcpu=dummy" } */
void f ()
diff --git a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c
index 2ca006598ff..ae42436031b 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-2.c
@@ -1,4 +1,5 @@
/* { dg-error "missing" "" {target "aarch64*-*-*" } } */
+/* { dg-skip-if "do not override -mcpu" { *-*-* } { "-mcpu=*" } { "" } } */
/* { dg-options "-O2 -mcpu=cortex-a53+no" } */
void f ()
diff --git a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c
index 807e3253e30..8bc6e2fe049 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-3.c
@@ -1,4 +1,5 @@
/* { dg-error "invalid feature" "" {target "aarch64*-*-*" } } */
+/* { dg-skip-if "do not override -mcpu" { *-*-* } { "-mcpu=*" } { "" } } */
/* { dg-options "-O2 -mcpu=cortex-a53+dummy" } */
void f ()
diff --git a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-4.c b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-4.c
index 4c246eb0172..58355b42f84 100644
--- a/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-4.c
+++ b/gcc/testsuite/gcc.target/aarch64/cpu-diagnostics-4.c
@@ -1,4 +1,5 @@
/* { dg-error "missing" "" {target "aarch64*-*-*" } } */
+/* { dg-skip-if "do not override -mcpu" { *-*-* } { "-mcpu=*" } { "" } } */
/* { dg-options "-O2 -mcpu=+dummy" } */
void f ()
diff --git a/gcc/testsuite/gcc.target/aarch64/fmla_intrinsic_1.c b/gcc/testsuite/gcc.target/aarch64/fmla_intrinsic_1.c
index 1ba1fed98a0..5b348827002 100644
--- a/gcc/testsuite/gcc.target/aarch64/fmla_intrinsic_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/fmla_intrinsic_1.c
@@ -110,6 +110,6 @@ main (int argc, char **argv)
/* vfmaq_lane_f64.
vfma_laneq_f64.
vfmaq_laneq_f64. */
-/* { dg-final { scan-assembler-times "fmla\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d\\\[\[0-9\]+\\\]" 3 } } */
+/* { dg-final { scan-assembler-times "fmla\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2?d\\\[\[0-9\]+\\\]" 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/fmls_intrinsic_1.c b/gcc/testsuite/gcc.target/aarch64/fmls_intrinsic_1.c
index 887ebae10da..6c194a023d3 100644
--- a/gcc/testsuite/gcc.target/aarch64/fmls_intrinsic_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/fmls_intrinsic_1.c
@@ -111,6 +111,6 @@ main (int argc, char **argv)
/* vfmsq_lane_f64.
vfms_laneq_f64.
vfmsq_laneq_f64. */
-/* { dg-final { scan-assembler-times "fmls\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2d\\\[\[0-9\]+\\\]" 3 } } */
+/* { dg-final { scan-assembler-times "fmls\\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.2?d\\\[\[0-9\]+\\\]" 3 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/noplt_3.c b/gcc/testsuite/gcc.target/aarch64/noplt_3.c
index ef6e65da8f6..a3826184549 100644
--- a/gcc/testsuite/gcc.target/aarch64/noplt_3.c
+++ b/gcc/testsuite/gcc.target/aarch64/noplt_3.c
@@ -16,5 +16,5 @@ cal_novalue (int a)
dec (a);
}
-/* { dg-final { scan-assembler-times "br" 2 } } */
+/* { dg-final { scan-assembler-times "br\t" 2 } } */
/* { dg-final { scan-assembler-not "b\t" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/pr70809_1.c b/gcc/testsuite/gcc.target/aarch64/pr70809_1.c
new file mode 100644
index 00000000000..df88c71c42a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/pr70809_1.c
@@ -0,0 +1,18 @@
+/* PR target/70809. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-vectorize -ffp-contract=off -mtune=xgene1" } */
+
+/* Check that vector FMLS is not generated when contraction is disabled. */
+
+void
+foo (float *__restrict__ __attribute__ ((aligned (16))) a,
+ float *__restrict__ __attribute__ ((aligned (16))) x,
+ float *__restrict__ __attribute__ ((aligned (16))) y,
+ float *__restrict__ __attribute__ ((aligned (16))) z)
+{
+ unsigned i = 0;
+ for (i = 0; i < 256; i++)
+ a[i] = x[i] - (y[i] * z[i]);
+}
+
+/* { dg-final { scan-assembler-not "fmls\tv.*" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/simd/vmul_elem_1.c b/gcc/testsuite/gcc.target/aarch64/simd/vmul_elem_1.c
new file mode 100644
index 00000000000..155cac3b4a5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/simd/vmul_elem_1.c
@@ -0,0 +1,519 @@
+/* Test the vmul_n_f64 AArch64 SIMD intrinsic. */
+
+/* { dg-do run } */
+/* { dg-options "-O2 --save-temps" } */
+
+#include "arm_neon.h"
+
+extern void abort (void);
+
+#define A (132.4f)
+#define B (-0.0f)
+#define C (-34.8f)
+#define D (289.34f)
+float32_t expected2_1[2] = {A * A, B * A};
+float32_t expected2_2[2] = {A * B, B * B};
+float32_t expected4_1[4] = {A * A, B * A, C * A, D * A};
+float32_t expected4_2[4] = {A * B, B * B, C * B, D * B};
+float32_t expected4_3[4] = {A * C, B * C, C * C, D * C};
+float32_t expected4_4[4] = {A * D, B * D, C * D, D * D};
+float32_t _elemA = A;
+float32_t _elemB = B;
+float32_t _elemC = C;
+float32_t _elemD = D;
+
+#define AD (1234.5)
+#define BD (-0.0)
+#define CD (71.3)
+#define DD (-1024.4)
+float64_t expectedd2_1[2] = {AD * CD, BD * CD};
+float64_t expectedd2_2[2] = {AD * DD, BD * DD};
+float64_t _elemdC = CD;
+float64_t _elemdD = DD;
+
+
+#define AS (1024)
+#define BS (-31)
+#define CS (0)
+#define DS (655)
+int32_t expecteds2_1[2] = {AS * AS, BS * AS};
+int32_t expecteds2_2[2] = {AS * BS, BS * BS};
+int32_t expecteds4_1[4] = {AS * AS, BS * AS, CS * AS, DS * AS};
+int32_t expecteds4_2[4] = {AS * BS, BS * BS, CS * BS, DS * BS};
+int32_t expecteds4_3[4] = {AS * CS, BS * CS, CS * CS, DS * CS};
+int32_t expecteds4_4[4] = {AS * DS, BS * DS, CS * DS, DS * DS};
+int32_t _elemsA = AS;
+int32_t _elemsB = BS;
+int32_t _elemsC = CS;
+int32_t _elemsD = DS;
+
+#define AH ((int16_t) 0)
+#define BH ((int16_t) -32)
+#define CH ((int16_t) 102)
+#define DH ((int16_t) -51)
+#define EH ((int16_t) 71)
+#define FH ((int16_t) -91)
+#define GH ((int16_t) 48)
+#define HH ((int16_t) 255)
+int16_t expectedh4_1[4] = {AH * AH, BH * AH, CH * AH, DH * AH};
+int16_t expectedh4_2[4] = {AH * BH, BH * BH, CH * BH, DH * BH};
+int16_t expectedh4_3[4] = {AH * CH, BH * CH, CH * CH, DH * CH};
+int16_t expectedh4_4[4] = {AH * DH, BH * DH, CH * DH, DH * DH};
+int16_t expectedh8_1[8] = {AH * AH, BH * AH, CH * AH, DH * AH,
+ EH * AH, FH * AH, GH * AH, HH * AH};
+int16_t expectedh8_2[8] = {AH * BH, BH * BH, CH * BH, DH * BH,
+ EH * BH, FH * BH, GH * BH, HH * BH};
+int16_t expectedh8_3[8] = {AH * CH, BH * CH, CH * CH, DH * CH,
+ EH * CH, FH * CH, GH * CH, HH * CH};
+int16_t expectedh8_4[8] = {AH * DH, BH * DH, CH * DH, DH * DH,
+ EH * DH, FH * DH, GH * DH, HH * DH};
+int16_t expectedh8_5[8] = {AH * EH, BH * EH, CH * EH, DH * EH,
+ EH * EH, FH * EH, GH * EH, HH * EH};
+int16_t expectedh8_6[8] = {AH * FH, BH * FH, CH * FH, DH * FH,
+ EH * FH, FH * FH, GH * FH, HH * FH};
+int16_t expectedh8_7[8] = {AH * GH, BH * GH, CH * GH, DH * GH,
+ EH * GH, FH * GH, GH * GH, HH * GH};
+int16_t expectedh8_8[8] = {AH * HH, BH * HH, CH * HH, DH * HH,
+ EH * HH, FH * HH, GH * HH, HH * HH};
+int16_t _elemhA = AH;
+int16_t _elemhB = BH;
+int16_t _elemhC = CH;
+int16_t _elemhD = DH;
+int16_t _elemhE = EH;
+int16_t _elemhF = FH;
+int16_t _elemhG = GH;
+int16_t _elemhH = HH;
+
+#define AUS (1024)
+#define BUS (31)
+#define CUS (0)
+#define DUS (655)
+uint32_t expectedus2_1[2] = {AUS * AUS, BUS * AUS};
+uint32_t expectedus2_2[2] = {AUS * BUS, BUS * BUS};
+uint32_t expectedus4_1[4] = {AUS * AUS, BUS * AUS, CUS * AUS, DUS * AUS};
+uint32_t expectedus4_2[4] = {AUS * BUS, BUS * BUS, CUS * BUS, DUS * BUS};
+uint32_t expectedus4_3[4] = {AUS * CUS, BUS * CUS, CUS * CUS, DUS * CUS};
+uint32_t expectedus4_4[4] = {AUS * DUS, BUS * DUS, CUS * DUS, DUS * DUS};
+uint32_t _elemusA = AUS;
+uint32_t _elemusB = BUS;
+uint32_t _elemusC = CUS;
+uint32_t _elemusD = DUS;
+
+#define AUH ((uint16_t) 0)
+#define BUH ((uint16_t) 32)
+#define CUH ((uint16_t) 102)
+#define DUH ((uint16_t) 51)
+#define EUH ((uint16_t) 71)
+#define FUH ((uint16_t) 91)
+#define GUH ((uint16_t) 48)
+#define HUH ((uint16_t) 255)
+uint16_t expecteduh4_1[4] = {AUH * AUH, BUH * AUH, CUH * AUH, DUH * AUH};
+uint16_t expecteduh4_2[4] = {AUH * BUH, BUH * BUH, CUH * BUH, DUH * BUH};
+uint16_t expecteduh4_3[4] = {AUH * CUH, BUH * CUH, CUH * CUH, DUH * CUH};
+uint16_t expecteduh4_4[4] = {AUH * DUH, BUH * DUH, CUH * DUH, DUH * DUH};
+uint16_t expecteduh8_1[8] = {AUH * AUH, BUH * AUH, CUH * AUH, DUH * AUH,
+ EUH * AUH, FUH * AUH, GUH * AUH, HUH * AUH};
+uint16_t expecteduh8_2[8] = {AUH * BUH, BUH * BUH, CUH * BUH, DUH * BUH,
+ EUH * BUH, FUH * BUH, GUH * BUH, HUH * BUH};
+uint16_t expecteduh8_3[8] = {AUH * CUH, BUH * CUH, CUH * CUH, DUH * CUH,
+ EUH * CUH, FUH * CUH, GUH * CUH, HUH * CUH};
+uint16_t expecteduh8_4[8] = {AUH * DUH, BUH * DUH, CUH * DUH, DUH * DUH,
+ EUH * DUH, FUH * DUH, GUH * DUH, HUH * DUH};
+uint16_t expecteduh8_5[8] = {AUH * EUH, BUH * EUH, CUH * EUH, DUH * EUH,
+ EUH * EUH, FUH * EUH, GUH * EUH, HUH * EUH};
+uint16_t expecteduh8_6[8] = {AUH * FUH, BUH * FUH, CUH * FUH, DUH * FUH,
+ EUH * FUH, FUH * FUH, GUH * FUH, HUH * FUH};
+uint16_t expecteduh8_7[8] = {AUH * GUH, BUH * GUH, CUH * GUH, DUH * GUH,
+ EUH * GUH, FUH * GUH, GUH * GUH, HUH * GUH};
+uint16_t expecteduh8_8[8] = {AUH * HUH, BUH * HUH, CUH * HUH, DUH * HUH,
+ EUH * HUH, FUH * HUH, GUH * HUH, HUH * HUH};
+uint16_t _elemuhA = AUH;
+uint16_t _elemuhB = BUH;
+uint16_t _elemuhC = CUH;
+uint16_t _elemuhD = DUH;
+uint16_t _elemuhE = EUH;
+uint16_t _elemuhF = FUH;
+uint16_t _elemuhG = GUH;
+uint16_t _elemuhH = HUH;
+
+void
+check_v2sf (float32_t elemA, float32_t elemB)
+{
+ int32_t indx;
+ const float32_t vec32x2_buf[2] = {A, B};
+ float32x2_t vec32x2_src = vld1_f32 (vec32x2_buf);
+ float32x2_t vec32x2_res = vmul_n_f32 (vec32x2_src, elemA);
+
+ for (indx = 0; indx < 2; indx++)
+ if (* (uint32_t *) &vec32x2_res[indx] != * (uint32_t *) &expected2_1[indx])
+ abort ();
+
+ vec32x2_res = vmul_n_f32 (vec32x2_src, elemB);
+
+ for (indx = 0; indx < 2; indx++)
+ if (* (uint32_t *) &vec32x2_res[indx] != * (uint32_t *) &expected2_2[indx])
+ abort ();
+
+/* { dg-final { scan-assembler-times "fmul\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.s\\\[0\\\]" 2 } } */
+}
+
+void
+check_v4sf (float32_t elemA, float32_t elemB, float32_t elemC, float32_t elemD)
+{
+ int32_t indx;
+ const float32_t vec32x4_buf[4] = {A, B, C, D};
+ float32x4_t vec32x4_src = vld1q_f32 (vec32x4_buf);
+ float32x4_t vec32x4_res = vmulq_n_f32 (vec32x4_src, elemA);
+
+ for (indx = 0; indx < 4; indx++)
+ if (* (uint32_t *) &vec32x4_res[indx] != * (uint32_t *) &expected4_1[indx])
+ abort ();
+
+ vec32x4_res = vmulq_n_f32 (vec32x4_src, elemB);
+
+ for (indx = 0; indx < 4; indx++)
+ if (* (uint32_t *) &vec32x4_res[indx] != * (uint32_t *) &expected4_2[indx])
+ abort ();
+
+ vec32x4_res = vmulq_n_f32 (vec32x4_src, elemC);
+
+ for (indx = 0; indx < 4; indx++)
+ if (* (uint32_t *) &vec32x4_res[indx] != * (uint32_t *) &expected4_3[indx])
+ abort ();
+
+ vec32x4_res = vmulq_n_f32 (vec32x4_src, elemD);
+
+ for (indx = 0; indx < 4; indx++)
+ if (* (uint32_t *) &vec32x4_res[indx] != * (uint32_t *) &expected4_4[indx])
+ abort ();
+
+/* { dg-final { scan-assembler-times "fmul\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.s\\\[0\\\]" 4 } } */
+}
+
+void
+check_v2df (float64_t elemdC, float64_t elemdD)
+{
+ int32_t indx;
+ const float64_t vec64x2_buf[2] = {AD, BD};
+ float64x2_t vec64x2_src = vld1q_f64 (vec64x2_buf);
+ float64x2_t vec64x2_res = vmulq_n_f64 (vec64x2_src, elemdC);
+
+ for (indx = 0; indx < 2; indx++)
+ if (* (uint64_t *) &vec64x2_res[indx] != * (uint64_t *) &expectedd2_1[indx])
+ abort ();
+
+ vec64x2_res = vmulq_n_f64 (vec64x2_src, elemdD);
+
+ for (indx = 0; indx < 2; indx++)
+ if (* (uint64_t *) &vec64x2_res[indx] != * (uint64_t *) &expectedd2_2[indx])
+ abort ();
+
+/* { dg-final { scan-assembler-times "fmul\tv\[0-9\]+\.2d, v\[0-9\]+\.2d, v\[0-9\]+\.d\\\[0\\\]" 2 } } */
+}
+
+void
+check_v2si (int32_t elemsA, int32_t elemsB)
+{
+ int32_t indx;
+ const int32_t vecs32x2_buf[2] = {AS, BS};
+ int32x2_t vecs32x2_src = vld1_s32 (vecs32x2_buf);
+ int32x2_t vecs32x2_res = vmul_n_s32 (vecs32x2_src, elemsA);
+
+ for (indx = 0; indx < 2; indx++)
+ if (vecs32x2_res[indx] != expecteds2_1[indx])
+ abort ();
+
+ vecs32x2_res = vmul_n_s32 (vecs32x2_src, elemsB);
+
+ for (indx = 0; indx < 2; indx++)
+ if (vecs32x2_res[indx] != expecteds2_2[indx])
+ abort ();
+}
+
+void
+check_v2si_unsigned (uint32_t elemusA, uint32_t elemusB)
+{
+ int indx;
+ const uint32_t vecus32x2_buf[2] = {AUS, BUS};
+ uint32x2_t vecus32x2_src = vld1_u32 (vecus32x2_buf);
+ uint32x2_t vecus32x2_res = vmul_n_u32 (vecus32x2_src, elemusA);
+
+ for (indx = 0; indx < 2; indx++)
+ if (vecus32x2_res[indx] != expectedus2_1[indx])
+ abort ();
+
+ vecus32x2_res = vmul_n_u32 (vecus32x2_src, elemusB);
+
+ for (indx = 0; indx < 2; indx++)
+ if (vecus32x2_res[indx] != expectedus2_2[indx])
+ abort ();
+
+/* { dg-final { scan-assembler-times "\tmul\tv\[0-9\]+\.2s, v\[0-9\]+\.2s, v\[0-9\]+\.s\\\[0\\\]" 4 } } */
+}
+
+void
+check_v4si (int32_t elemsA, int32_t elemsB, int32_t elemsC, int32_t elemsD)
+{
+ int32_t indx;
+ const int32_t vecs32x4_buf[4] = {AS, BS, CS, DS};
+ int32x4_t vecs32x4_src = vld1q_s32 (vecs32x4_buf);
+ int32x4_t vecs32x4_res = vmulq_n_s32 (vecs32x4_src, elemsA);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecs32x4_res[indx] != expecteds4_1[indx])
+ abort ();
+
+ vecs32x4_res = vmulq_n_s32 (vecs32x4_src, elemsB);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecs32x4_res[indx] != expecteds4_2[indx])
+ abort ();
+
+ vecs32x4_res = vmulq_n_s32 (vecs32x4_src, elemsC);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecs32x4_res[indx] != expecteds4_3[indx])
+ abort ();
+
+ vecs32x4_res = vmulq_n_s32 (vecs32x4_src, elemsD);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecs32x4_res[indx] != expecteds4_4[indx])
+ abort ();
+}
+
+void
+check_v4si_unsigned (uint32_t elemusA, uint32_t elemusB, uint32_t elemusC,
+ uint32_t elemusD)
+{
+ int indx;
+ const uint32_t vecus32x4_buf[4] = {AUS, BUS, CUS, DUS};
+ uint32x4_t vecus32x4_src = vld1q_u32 (vecus32x4_buf);
+ uint32x4_t vecus32x4_res = vmulq_n_u32 (vecus32x4_src, elemusA);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecus32x4_res[indx] != expectedus4_1[indx])
+ abort ();
+
+ vecus32x4_res = vmulq_n_u32 (vecus32x4_src, elemusB);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecus32x4_res[indx] != expectedus4_2[indx])
+ abort ();
+
+ vecus32x4_res = vmulq_n_u32 (vecus32x4_src, elemusC);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecus32x4_res[indx] != expectedus4_3[indx])
+ abort ();
+
+ vecus32x4_res = vmulq_n_u32 (vecus32x4_src, elemusD);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecus32x4_res[indx] != expectedus4_4[indx])
+ abort ();
+
+/* { dg-final { scan-assembler-times "\tmul\tv\[0-9\]+\.4s, v\[0-9\]+\.4s, v\[0-9\]+\.s\\\[0\\\]" 8 } } */
+}
+
+
+void
+check_v4hi (int16_t elemhA, int16_t elemhB, int16_t elemhC, int16_t elemhD)
+{
+ int32_t indx;
+ const int16_t vech16x4_buf[4] = {AH, BH, CH, DH};
+ int16x4_t vech16x4_src = vld1_s16 (vech16x4_buf);
+ int16x4_t vech16x4_res = vmul_n_s16 (vech16x4_src, elemhA);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vech16x4_res[indx] != expectedh4_1[indx])
+ abort ();
+
+ vech16x4_res = vmul_n_s16 (vech16x4_src, elemhB);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vech16x4_res[indx] != expectedh4_2[indx])
+ abort ();
+
+ vech16x4_res = vmul_n_s16 (vech16x4_src, elemhC);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vech16x4_res[indx] != expectedh4_3[indx])
+ abort ();
+
+ vech16x4_res = vmul_n_s16 (vech16x4_src, elemhD);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vech16x4_res[indx] != expectedh4_4[indx])
+ abort ();
+}
+
+void
+check_v4hi_unsigned (uint16_t elemuhA, uint16_t elemuhB, uint16_t elemuhC,
+ uint16_t elemuhD)
+{
+ int indx;
+ const uint16_t vecuh16x4_buf[4] = {AUH, BUH, CUH, DUH};
+ uint16x4_t vecuh16x4_src = vld1_u16 (vecuh16x4_buf);
+ uint16x4_t vecuh16x4_res = vmul_n_u16 (vecuh16x4_src, elemuhA);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecuh16x4_res[indx] != expecteduh4_1[indx])
+ abort ();
+
+ vecuh16x4_res = vmul_n_u16 (vecuh16x4_src, elemuhB);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecuh16x4_res[indx] != expecteduh4_2[indx])
+ abort ();
+
+ vecuh16x4_res = vmul_n_u16 (vecuh16x4_src, elemuhC);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecuh16x4_res[indx] != expecteduh4_3[indx])
+ abort ();
+
+ vecuh16x4_res = vmul_n_u16 (vecuh16x4_src, elemuhD);
+
+ for (indx = 0; indx < 4; indx++)
+ if (vecuh16x4_res[indx] != expecteduh4_4[indx])
+ abort ();
+
+/* { dg-final { scan-assembler-times "mul\tv\[0-9\]+\.4h, v\[0-9\]+\.4h, v\[0-9\]+\.h\\\[0\\\]" 8 } } */
+}
+
+void
+check_v8hi (int16_t elemhA, int16_t elemhB, int16_t elemhC, int16_t elemhD,
+ int16_t elemhE, int16_t elemhF, int16_t elemhG, int16_t elemhH)
+{
+ int32_t indx;
+ const int16_t vech16x8_buf[8] = {AH, BH, CH, DH, EH, FH, GH, HH};
+ int16x8_t vech16x8_src = vld1q_s16 (vech16x8_buf);
+ int16x8_t vech16x8_res = vmulq_n_s16 (vech16x8_src, elemhA);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vech16x8_res[indx] != expectedh8_1[indx])
+ abort ();
+
+ vech16x8_res = vmulq_n_s16 (vech16x8_src, elemhB);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vech16x8_res[indx] != expectedh8_2[indx])
+ abort ();
+
+ vech16x8_res = vmulq_n_s16 (vech16x8_src, elemhC);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vech16x8_res[indx] != expectedh8_3[indx])
+ abort ();
+
+ vech16x8_res = vmulq_n_s16 (vech16x8_src, elemhD);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vech16x8_res[indx] != expectedh8_4[indx])
+ abort ();
+
+ vech16x8_res = vmulq_n_s16 (vech16x8_src, elemhE);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vech16x8_res[indx] != expectedh8_5[indx])
+ abort ();
+
+ vech16x8_res = vmulq_n_s16 (vech16x8_src, elemhF);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vech16x8_res[indx] != expectedh8_6[indx])
+ abort ();
+
+ vech16x8_res = vmulq_n_s16 (vech16x8_src, elemhG);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vech16x8_res[indx] != expectedh8_7[indx])
+ abort ();
+
+ vech16x8_res = vmulq_n_s16 (vech16x8_src, elemhH);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vech16x8_res[indx] != expectedh8_8[indx])
+ abort ();
+}
+
+void
+check_v8hi_unsigned (uint16_t elemuhA, uint16_t elemuhB, uint16_t elemuhC,
+ uint16_t elemuhD, uint16_t elemuhE, uint16_t elemuhF,
+ uint16_t elemuhG, uint16_t elemuhH)
+{
+ int indx;
+ const uint16_t vecuh16x8_buf[8] = {AUH, BUH, CUH, DUH, EUH, FUH, GUH, HUH};
+ uint16x8_t vecuh16x8_src = vld1q_u16 (vecuh16x8_buf);
+ uint16x8_t vecuh16x8_res = vmulq_n_u16 (vecuh16x8_src, elemuhA);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vecuh16x8_res[indx] != expecteduh8_1[indx])
+ abort ();
+
+ vecuh16x8_res = vmulq_n_u16 (vecuh16x8_src, elemuhB);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vecuh16x8_res[indx] != expecteduh8_2[indx])
+ abort ();
+
+ vecuh16x8_res = vmulq_n_u16 (vecuh16x8_src, elemuhC);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vecuh16x8_res[indx] != expecteduh8_3[indx])
+ abort ();
+
+ vecuh16x8_res = vmulq_n_u16 (vecuh16x8_src, elemuhD);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vecuh16x8_res[indx] != expecteduh8_4[indx])
+ abort ();
+
+ vecuh16x8_res = vmulq_n_u16 (vecuh16x8_src, elemuhE);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vecuh16x8_res[indx] != expecteduh8_5[indx])
+ abort ();
+
+ vecuh16x8_res = vmulq_n_u16 (vecuh16x8_src, elemuhF);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vecuh16x8_res[indx] != expecteduh8_6[indx])
+ abort ();
+
+ vecuh16x8_res = vmulq_n_u16 (vecuh16x8_src, elemuhG);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vecuh16x8_res[indx] != expecteduh8_7[indx])
+ abort ();
+
+ vecuh16x8_res = vmulq_n_u16 (vecuh16x8_src, elemuhH);
+
+ for (indx = 0; indx < 8; indx++)
+ if (vecuh16x8_res[indx] != expecteduh8_8[indx])
+ abort ();
+
+/* { dg-final { scan-assembler-times "mul\tv\[0-9\]+\.8h, v\[0-9\]+\.8h, v\[0-9\]+\.h\\\[0\\\]" 16 } } */
+}
+
+int
+main (void)
+{
+ check_v2sf (_elemA, _elemB);
+ check_v4sf (_elemA, _elemB, _elemC, _elemD);
+ check_v2df (_elemdC, _elemdD);
+ check_v2si (_elemsA, _elemsB);
+ check_v4si (_elemsA, _elemsB, _elemsC, _elemsD);
+ check_v4hi (_elemhA, _elemhB, _elemhC, _elemhD);
+ check_v8hi (_elemhA, _elemhB, _elemhC, _elemhD,
+ _elemhE, _elemhF, _elemhG, _elemhH);
+ check_v2si_unsigned (_elemusA, _elemusB);
+ check_v4si_unsigned (_elemusA, _elemusB, _elemusC, _elemusD);
+ check_v4hi_unsigned (_elemuhA, _elemuhB, _elemuhC, _elemuhD);
+ check_v8hi_unsigned (_elemuhA, _elemuhB, _elemuhC, _elemuhD,
+ _elemuhE, _elemuhF, _elemuhG, _elemuhH);
+
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.target/aarch64/struct_return.c b/gcc/testsuite/gcc.target/aarch64/struct_return.c
new file mode 100644
index 00000000000..6d90b7e5953
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/struct_return.c
@@ -0,0 +1,31 @@
+/* Test the absence of a spurious move from x8 to x0 for functions
+ return structures. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct s
+{
+ long x;
+ long y;
+ long z;
+};
+
+struct s __attribute__((noinline))
+foo (long a, long d, long c)
+{
+ struct s b;
+ b.x = a;
+ b.y = d;
+ b.z = c;
+ return b;
+}
+
+int
+main (void)
+{
+ struct s x;
+ x = foo ( 10, 20, 30);
+ return x.x + x.y + x.z;
+}
+
+/* { dg-final { scan-assembler-not "mov\tx0, x8" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/tail_indirect_call_1.c b/gcc/testsuite/gcc.target/aarch64/tail_indirect_call_1.c
index 4759d20df9c..de8f12d6e22 100644
--- a/gcc/testsuite/gcc.target/aarch64/tail_indirect_call_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/tail_indirect_call_1.c
@@ -3,8 +3,8 @@
typedef void FP (int);
-/* { dg-final { scan-assembler "br" } } */
-/* { dg-final { scan-assembler-not "blr" } } */
+/* { dg-final { scan-assembler-times "br\t" 2 } } */
+/* { dg-final { scan-assembler-not "blr\t" } } */
void
f1 (FP fp, int n)
{
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/neon-vect10.c b/gcc/testsuite/gcc.target/arm/aapcs/neon-vect10.c
new file mode 100644
index 00000000000..680a3b560d7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aapcs/neon-vect10.c
@@ -0,0 +1,31 @@
+/* Test AAPCS layout (VFP variant for Neon types) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-add-options arm_neon_fp16 } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define NEON
+#define TESTFILE "neon-vect10.c"
+#include "neon-constants.h"
+
+#include "abitest.h"
+#else
+
+ARG (int32x4_t, i32x4_constvec2, Q0) /* D0, D1. */
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 3.0f, S4 + 2) /* D2, Q1. */
+#else
+ARG (__fp16, 3.0f, S4) /* D2, Q1. */
+#endif
+ARG (int32x4x2_t, i32x4x2_constvec1, Q2) /* Q2, Q3 - D4-D6 , s5-s12. */
+ARG (double, 12.0, D3) /* Backfill this particular argument. */
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 5.0f, S5 + 2) /* Backfill in S5. */
+#else
+ARG (__fp16, 5.0f, S5) /* Backfill in S5. */
+#endif
+ARG (int32x4x2_t, i32x4x2_constvec2, STACK)
+LAST_ARG (int, 3, R0)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/neon-vect9.c b/gcc/testsuite/gcc.target/arm/aapcs/neon-vect9.c
new file mode 100644
index 00000000000..fc2b13bf1b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aapcs/neon-vect9.c
@@ -0,0 +1,23 @@
+/* Test AAPCS layout (VFP variant for Neon types) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-add-options arm_neon_fp16 } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define NEON
+#define TESTFILE "neon-vect9.c"
+#include "neon-constants.h"
+
+#include "abitest.h"
+#else
+
+ARG (int32x4_t, i32x4_constvec2, Q0) /* D0, D1. */
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 3.0f, S4 + 2) /* D2, Q1 occupied. */
+#else
+ARG (__fp16, 3.0f, S4) /* D2, Q1 occupied. */
+#endif
+LAST_ARG (int, 3, R0)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/vfp18.c b/gcc/testsuite/gcc.target/arm/aapcs/vfp18.c
new file mode 100644
index 00000000000..225e9ce7c10
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp18.c
@@ -0,0 +1,27 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard -mfp16-format=ieee" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp18.c"
+#include "abitest.h"
+
+#else
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 1.0f, S0 + 2)
+#else
+ARG (__fp16, 1.0f, S0)
+#endif
+ARG (float, 2.0f, S1)
+ARG (double, 4.0, D1)
+ARG (float, 2.0f, S4)
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 1.0f, S5 + 2)
+#else
+ARG (__fp16, 1.0f, S5)
+#endif
+LAST_ARG (int, 3, R0)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/vfp19.c b/gcc/testsuite/gcc.target/arm/aapcs/vfp19.c
new file mode 100644
index 00000000000..8928b1562e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp19.c
@@ -0,0 +1,29 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard -mfp16-format=ieee" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp19.c"
+
+__complex__ x = 1.0+2.0i;
+
+#include "abitest.h"
+#else
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 1.0f, S0 + 2)
+#else
+ARG (__fp16, 1.0f, S0)
+#endif
+ARG (float, 2.0f, S1)
+ARG (__complex__ double, x, D1)
+ARG (float, 3.0f, S6)
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 2.0f, S7 + 2)
+#else
+ARG (__fp16, 2.0f, S7)
+#endif
+LAST_ARG (int, 3, R0)
+#endif
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/vfp20.c b/gcc/testsuite/gcc.target/arm/aapcs/vfp20.c
new file mode 100644
index 00000000000..61f07049f2c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp20.c
@@ -0,0 +1,21 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard -mfp16-format=ieee" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp20.c"
+
+#define PCSATTR __attribute__((pcs("aapcs")))
+
+#include "abitest.h"
+#else
+ARG (float, 1.0f, R0)
+ARG (double, 2.0, R2)
+ARG (float, 3.0f, STACK)
+ARG (__fp16, 2.0f, STACK+4)
+LAST_ARG (double, 4.0, STACK+8)
+#endif
+
diff --git a/gcc/testsuite/gcc.target/arm/aapcs/vfp21.c b/gcc/testsuite/gcc.target/arm/aapcs/vfp21.c
new file mode 100644
index 00000000000..15dff7d19f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/aapcs/vfp21.c
@@ -0,0 +1,25 @@
+/* Test AAPCS layout (VFP variant) */
+
+/* { dg-do run { target arm_eabi } } */
+/* { dg-require-effective-target arm_neon_fp16_ok } */
+/* { dg-options "-O -mfpu=vfp -mfloat-abi=hard -mfp16-format=ieee" } */
+
+#ifndef IN_FRAMEWORK
+#define VFP
+#define TESTFILE "vfp21.c"
+
+#define PCSATTR __attribute__((pcs("aapcs")))
+
+#include "abitest.h"
+#else
+#if defined (__ARM_BIG_ENDIAN)
+ARG (__fp16, 1.0f, R0 + 2)
+#else
+ARG (__fp16, 1.0f, R0)
+#endif
+ARG (double, 2.0, R2)
+ARG (__fp16, 3.0f, STACK)
+ARG (float, 2.0f, STACK+4)
+LAST_ARG (double, 4.0, STACK+8)
+#endif
+
diff --git a/gcc/testsuite/gcc.target/arm/fp16-aapcs-1.c b/gcc/testsuite/gcc.target/arm/fp16-aapcs-1.c
new file mode 100644
index 00000000000..5eab3e2ca78
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/fp16-aapcs-1.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_fp16_ok } */
+/* { dg-options "-mfp16-format=ieee -O2" } */
+/* { dg-add-options arm_fp16 } */
+
+/* Test __fp16 arguments and return value in registers. */
+
+__fp16 F (__fp16 a, __fp16 b, __fp16 c)
+{
+ if (a == b)
+ return c;
+ return a;
+}
+
+/* { dg-final { scan-assembler-times {vcvtb\.f32\.f16\ts[0-9]+, s0} 1 } } */
+/* { dg-final { scan-assembler-times {vcvtb\.f32\.f16\ts[0-9]+, s1} 1 } } */
+/* { dg-final { scan-assembler-times {vmov\ts0, r[0-9]+} 1 } } */
diff --git a/gcc/testsuite/gcc.target/arm/fp16-param-1.c b/gcc/testsuite/gcc.target/arm/fp16-param-1.c
index af4845f9fd5..9c527301c44 100644
--- a/gcc/testsuite/gcc.target/arm/fp16-param-1.c
+++ b/gcc/testsuite/gcc.target/arm/fp16-param-1.c
@@ -1,10 +1,14 @@
/* { dg-do compile } */
/* { dg-options "-mfp16-format=ieee" } */
-/* Functions cannot have parameters of type __fp16. */
-extern void f (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */
-extern void (*pf) (__fp16); /* { dg-error "parameters cannot have __fp16 type" } */
+/* Test that the ACLE macro is defined. */
+#if __ARM_FP16_ARGS != 1
+#error Unexpected value for __ARM_FP16_ARGS
+#endif
+
+/* Test that __fp16 is supported as a parameter type. */
+extern void f (__fp16);
+extern void (*pf) (__fp16);
-/* These should be OK. */
extern void g (__fp16 *);
extern void (*pg) (__fp16 *);
diff --git a/gcc/testsuite/gcc.target/arm/fp16-return-1.c b/gcc/testsuite/gcc.target/arm/fp16-return-1.c
index f763941268a..f97a8d7f585 100644
--- a/gcc/testsuite/gcc.target/arm/fp16-return-1.c
+++ b/gcc/testsuite/gcc.target/arm/fp16-return-1.c
@@ -1,10 +1,9 @@
/* { dg-do compile } */
/* { dg-options "-mfp16-format=ieee" } */
-/* Functions cannot return type __fp16. */
-extern __fp16 f (void); /* { dg-error "cannot return __fp16" } */
-extern __fp16 (*pf) (void); /* { dg-error "cannot return __fp16" } */
+/* Test that __fp16 is supported as a return type. */
+extern __fp16 f (void);
+extern __fp16 (*pf) (void);
-/* These should be OK. */
extern __fp16 *g (void);
extern __fp16 *(*pg) (void);
diff --git a/gcc/testsuite/gcc.target/arm/interrupt-1.c b/gcc/testsuite/gcc.target/arm/interrupt-1.c
index debbaf78cc8..fe94877cead 100644
--- a/gcc/testsuite/gcc.target/arm/interrupt-1.c
+++ b/gcc/testsuite/gcc.target/arm/interrupt-1.c
@@ -1,8 +1,8 @@
/* Verify that prologue and epilogue are correct for functions with
__attribute__ ((interrupt)). */
-/* { dg-do compile } */
+/* { dg-do assemble } */
/* { dg-require-effective-target arm_nothumb } */
-/* { dg-options "-O0 -marm" } */
+/* { dg-options "-O0 -marm -save-temps" } */
/* This test is not valid when -mthumb. */
extern void bar (int);
@@ -14,4 +14,4 @@ void foo ()
}
/* { dg-final { scan-assembler "push\t{r0, r1, r2, r3, r4, fp, ip, lr}" } } */
-/* { dg-final { scan-assembler "pop\t{r0, r1, r2, r3, r4, fp, ip, pc}\\^" } } */
+/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, fp, ip, pc}\\^" } } */
diff --git a/gcc/testsuite/gcc.target/arm/interrupt-2.c b/gcc/testsuite/gcc.target/arm/interrupt-2.c
index 92f8630e016..289eca0f640 100644
--- a/gcc/testsuite/gcc.target/arm/interrupt-2.c
+++ b/gcc/testsuite/gcc.target/arm/interrupt-2.c
@@ -1,8 +1,8 @@
/* Verify that prologue and epilogue are correct for functions with
__attribute__ ((interrupt)). */
-/* { dg-do compile } */
+/* { dg-do assemble } */
/* { dg-require-effective-target arm_nothumb } */
-/* { dg-options "-O1 -marm" } */
+/* { dg-options "-O1 -marm -save-temps" } */
/* This test is not valid when -mthumb. */
extern void bar (int);
@@ -16,4 +16,4 @@ void test()
}
/* { dg-final { scan-assembler "push\t{r0, r1, r2, r3, r4, r5, ip, lr}" } } */
-/* { dg-final { scan-assembler "pop\t{r0, r1, r2, r3, r4, r5, ip, pc}\\^" } } */
+/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, r4, r5, ip, pc}\\^" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pr70830.c b/gcc/testsuite/gcc.target/arm/pr70830.c
new file mode 100644
index 00000000000..cad903b0cf2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr70830.c
@@ -0,0 +1,14 @@
+/* PR target/70830. */
+/* { dg-do assemble } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-Os -marm -save-temps" } */
+
+/* This test is not valid when -mthumb. */
+
+extern void prints (char *);
+
+void __attribute__ ((interrupt ("IRQ"))) dm3730_IRQHandler(void)
+{
+ prints("IRQ" );
+}
+/* { dg-final { scan-assembler "ldmfd\tsp!, {r0, r1, r2, r3, ip, pc}\\^" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pr71056.c b/gcc/testsuite/gcc.target/arm/pr71056.c
new file mode 100644
index 00000000000..136754eb13c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr71056.c
@@ -0,0 +1,32 @@
+/* PR target/71056. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_vfp3_ok } */
+/* { dg-options "-O3 -mfpu=vfpv3" } */
+
+/* Check that compiling for a non-NEON target doesn't try to introduce
+ a NEON vectorized builtin. */
+
+extern char *buff;
+int f2 ();
+struct T1
+{
+ int reserved[2];
+ unsigned int ip;
+ unsigned short cs;
+ unsigned short rsrv2;
+};
+void
+f3 (const char *p)
+{
+ struct T1 x;
+ __builtin_memcpy (&x, p, sizeof (struct T1));
+ x.reserved[0] = __builtin_bswap32 (x.reserved[0]);
+ x.reserved[1] = __builtin_bswap32 (x.reserved[1]);
+ x.ip = __builtin_bswap32 (x.ip);
+ x.cs = x.cs << 8 | x.cs >> 8;
+ x.rsrv2 = x.rsrv2 << 8 | x.rsrv2 >> 8;
+ if (f2 ())
+ {
+ __builtin_memcpy (buff, "\n", 1);
+ }
+}
diff --git a/gcc/testsuite/gcc.target/avr/pr71103.c b/gcc/testsuite/gcc.target/avr/pr71103.c
new file mode 100644
index 00000000000..43244d15e97
--- /dev/null
+++ b/gcc/testsuite/gcc.target/avr/pr71103.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+
+struct ResponseStruct{
+ unsigned char responseLength;
+ char *response;
+};
+
+static char response[5];
+struct ResponseStruct something(){
+ struct ResponseStruct returnValue;
+ returnValue.responseLength = 5;
+ returnValue.response = response;
+ return returnValue;
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-kunpckdq-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-kunpckdq-1.c
index 7a974fecb94..a045921dfd8 100644
--- a/gcc/testsuite/gcc.target/i386/avx512bw-kunpckdq-1.c
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-kunpckdq-1.c
@@ -8,9 +8,10 @@ void
avx512bw_test () {
__mmask64 k1, k2, k3;
volatile __m512i x;
+ long long one = 1, two = 2;
- __asm__( "kmovq %1, %0" : "=k" (k1) : "r" (1) );
- __asm__( "kmovq %1, %0" : "=k" (k2) : "r" (2) );
+ __asm__( "kmovq %1, %0" : "=k" (k1) : "m" (one) );
+ __asm__( "kmovq %1, %0" : "=k" (k2) : "m" (two) );
k3 = _mm512_kunpackd (k1, k2);
x = _mm512_mask_avg_epu8 (x, k3, x, x);
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-pack-2.c b/gcc/testsuite/gcc.target/i386/avx512bw-pack-2.c
new file mode 100644
index 00000000000..3b9c201b042
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-pack-2.c
@@ -0,0 +1,100 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+#include <x86intrin.h>
+
+__m128i
+f1 (__m128i a, __m128i b)
+{
+ register __m128i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_packs_epi16 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpacksswb\[^\n\r\]*xmm16" 1 } } */
+
+__m128i
+f2 (__m128i a, __m128i b)
+{
+ register __m128i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_packs_epi32 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackssdw\[^\n\r\]*xmm16" 1 } } */
+
+__m128i
+f3 (__m128i a, __m128i b)
+{
+ register __m128i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_packus_epi16 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackuswb\[^\n\r\]*xmm16" 1 } } */
+
+__m128i
+f4 (__m128i a, __m128i b)
+{
+ register __m128i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_packus_epi32 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackusdw\[^\n\r\]*xmm16" 1 } } */
+
+__m256i
+f5 (__m256i a, __m256i b)
+{
+ register __m256i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_packs_epi16 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpacksswb\[^\n\r\]*ymm16" 1 } } */
+
+__m256i
+f6 (__m256i a, __m256i b)
+{
+ register __m256i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_packs_epi32 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackssdw\[^\n\r\]*ymm16" 1 } } */
+
+__m256i
+f7 (__m256i a, __m256i b)
+{
+ register __m256i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_packus_epi16 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackuswb\[^\n\r\]*ymm16" 1 } } */
+
+__m256i
+f8 (__m256i a, __m256i b)
+{
+ register __m256i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_packus_epi32 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackusdw\[^\n\r\]*ymm16" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpalignr-3.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpalignr-3.c
new file mode 100644
index 00000000000..aacd4255bb8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpalignr-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, __m128i y)
+{
+ register __m128i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm_alignr_epi8 (a, b, 3);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpalignr\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]" } } */
+
+void
+f2 (__m256i x, __m256i y)
+{
+ register __m256i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm256_alignr_epi8 (a, b, 3);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpalignr\[^\n\r]*ymm1\[67]\[^\n\r]*ymm1\[67]\[^\n\r]*ymm1\[67]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-1.c
new file mode 100644
index 00000000000..da6dba59d95
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-1.c
@@ -0,0 +1,104 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_broadcastb_epi8 (a);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastb\[^\n\r]*xmm16\[^\n\r]*xmm16" } } */
+
+void
+f2 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_broadcastw_epi16 (a);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastw\[^\n\r]*xmm16\[^\n\r]*xmm16" } } */
+
+void
+f3 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_broadcastd_epi32 (a);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastd\[^\n\r]*xmm16\[^\n\r]*xmm16" } } */
+
+void
+f4 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_broadcastq_epi64 (a);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastq\[^\n\r]*xmm16\[^\n\r]*xmm16" } } */
+
+void
+f5 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastb_epi8 (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastb\[^\n\r]*(xmm1\[67]\[^\n\r]*ymm1\[67]|ymm1\[67]\[^\n\r]*xmm1\[67])" } } */
+
+void
+f6 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastw_epi16 (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastw\[^\n\r]*(xmm1\[67]\[^\n\r]*ymm1\[67]|ymm1\[67]\[^\n\r]*xmm1\[67])" } } */
+
+void
+f7 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastd_epi32 (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastd\[^\n\r]*(xmm1\[67]\[^\n\r]*ymm1\[67]|ymm1\[67]\[^\n\r]*xmm1\[67])" } } */
+
+void
+f8 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastq_epi64 (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastq\[^\n\r]*(xmm1\[67]\[^\n\r]*ymm1\[67]|ymm1\[67]\[^\n\r]*xmm1\[67])" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-2.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-2.c
new file mode 100644
index 00000000000..2d623c6edf3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-2.c
@@ -0,0 +1,68 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+typedef char V1 __attribute__((vector_size (16)));
+typedef short V2 __attribute__((vector_size (16)));
+typedef char V5 __attribute__((vector_size (32)));
+typedef short V6 __attribute__((vector_size (32)));
+typedef int V7 __attribute__((vector_size (32)));
+
+void
+f1 (V1 x)
+{
+ register V1 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V1) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastb\[^\n\r]*xmm16\[^\n\r]*xmm16" } } */
+
+void
+f2 (V2 x)
+{
+ register V2 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V2) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastw\[^\n\r]*xmm16\[^\n\r]*xmm16" } } */
+
+void
+f5 (V5 x)
+{
+ register V5 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V5) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastb\[^\n\r]*(xmm16\[^\n\r]*ymm16|ymm16\[^\n\r]*xmm16)" } } */
+
+void
+f6 (V6 x)
+{
+ register V6 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V6) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastw\[^\n\r]*(xmm16\[^\n\r]*ymm16|ymm16\[^\n\r]*xmm16)" } } */
+
+void
+f7 (V7 x)
+{
+ register V7 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V7) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastd\[^\n\r]*(xmm16\[^\n\r]*ymm16|ymm16\[^\n\r]*xmm16)" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-3.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-3.c
new file mode 100644
index 00000000000..ff3d27580dd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpbroadcast-3.c
@@ -0,0 +1,58 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+typedef char V1 __attribute__((vector_size (16)));
+typedef short V2 __attribute__((vector_size (16)));
+typedef char V5 __attribute__((vector_size (32)));
+typedef short V6 __attribute__((vector_size (32)));
+typedef int V7 __attribute__((vector_size (32)));
+
+void
+f1 (V1 *x)
+{
+ register V1 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V1) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastb\[^\n\r]*xmm16" } } */
+
+void
+f2 (V2 *x)
+{
+ register V2 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V2) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastw\[^\n\r]*xmm16" } } */
+
+void
+f5 (V5 *x)
+{
+ register V5 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V5) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastb\[^\n\r]*ymm16" } } */
+
+void
+f6 (V6 *x)
+{
+ register V6 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V6) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastw\[^\n\r]*ymm16" } } */
+
+void
+f7 (V7 *x)
+{
+ register V7 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V7) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastd\[^\n\r]*ymm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpextr-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpextr-1.c
new file mode 100644
index 00000000000..f4eea9bf511
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpextr-1.c
@@ -0,0 +1,109 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+typedef char v16qi __attribute__((vector_size (16)));
+typedef short v8hi __attribute__((vector_size (16)));
+typedef int v4si __attribute__((vector_size (16)));
+typedef long long v2di __attribute__((vector_size (16)));
+
+void
+f1 (v16qi a)
+{
+ register v16qi c __asm ("xmm16") = a;
+ register unsigned char e __asm ("dl");
+ asm volatile ("" : "+v" (c));
+ v16qi d = c;
+ e = ((unsigned char *) &d)[3];
+ asm volatile ("" : : "q" (e));
+}
+
+unsigned short
+f2 (v8hi a)
+{
+ register v8hi c __asm ("xmm16") = a;
+ register unsigned short e __asm ("dx");
+ asm volatile ("" : "+v" (c));
+ v8hi d = c;
+ e = ((unsigned short *) &d)[3];
+ asm volatile ("" : : "r" (e));
+}
+
+unsigned int
+f3 (v16qi a)
+{
+ register v16qi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v16qi d = c;
+ return ((unsigned char *) &d)[3];
+}
+
+unsigned int
+f4 (v8hi a)
+{
+ register v8hi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v8hi d = c;
+ return ((unsigned short *) &d)[3];
+}
+
+unsigned long long
+f5 (v16qi a)
+{
+ register v16qi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v16qi d = c;
+ return ((unsigned char *) &d)[3];
+}
+
+unsigned long long
+f6 (v8hi a)
+{
+ register v8hi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v8hi d = c;
+ return ((unsigned short *) &d)[3];
+}
+
+void
+f7 (v16qi a, unsigned char *p)
+{
+ register v16qi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v16qi d = c;
+ *p = ((unsigned char *) &d)[3];
+}
+
+void
+f8 (v8hi a, unsigned short *p)
+{
+ register v8hi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v8hi d = c;
+ *p = ((unsigned short *) &d)[3];
+}
+
+void
+f9 (v4si a)
+{
+ register v4si c __asm ("xmm16") = a;
+ register unsigned int e __asm ("xmm17");
+ asm volatile ("" : "+v" (c));
+ v4si d = c;
+ e = ((unsigned int *) &d)[3];
+ asm volatile ("" : "+v" (e));
+}
+
+void
+f10 (v2di a)
+{
+ register v2di c __asm ("xmm16") = a;
+ register unsigned long long e __asm ("xmm17");
+ asm volatile ("" : "+v" (c));
+ v2di d = c;
+ e = ((unsigned long long *) &d)[1];
+ asm volatile ("" : "+v" (e));
+}
+
+/* { dg-final { scan-assembler-times "vpextrb\[^\n\r]*xmm16" 4 } } */
+/* { dg-final { scan-assembler-times "vpextrw\[^\n\r]*xmm16" 4 } } */
+/* { dg-final { scan-assembler-times "vpsrldq\[^\n\r]*xmm1\[67\]\[^\n\r]*xmm1\[67\]" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpinsr-1.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpinsr-1.c
new file mode 100644
index 00000000000..ff66dd4fd33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpinsr-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+typedef char v16qi __attribute__((vector_size (16)));
+typedef short v8hi __attribute__((vector_size (16)));
+
+v16qi
+f1 (v16qi a, char b)
+{
+ register v16qi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v16qi d = c;
+ ((char *) &d)[3] = b;
+ c = d;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler "vpinsrb\[^\n\r]*xmm16" } } */
+
+v8hi
+f2 (v8hi a, short b)
+{
+ register v8hi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v8hi d = c;
+ ((short *) &d)[3] = b;
+ c = d;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler "vpinsrw\[^\n\r]*xmm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpmaddubsw-3.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpmaddubsw-3.c
new file mode 100644
index 00000000000..24252e069f9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpmaddubsw-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, __m128i y)
+{
+ register __m128i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm_maddubs_epi16 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpmaddubsw\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]" } } */
+
+void
+f2 (__m256i x, __m256i y)
+{
+ register __m256i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm256_maddubs_epi16 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpmaddubsw\[^\n\r]*ymm1\[67]\[^\n\r]*ymm1\[67]\[^\n\r]*ymm1\[67]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpmaddwd-3.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpmaddwd-3.c
new file mode 100644
index 00000000000..d0c7c38e195
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpmaddwd-3.c
@@ -0,0 +1,24 @@
+/* { dg-do assemble { target { avx512bw && { avx512vl && { ! ia32 } } } } } */
+/* { dg-options "-O2 -mavx512bw -mavx512vl" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, __m128i y)
+{
+ register __m128i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x; b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm_madd_epi16 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (__m256i x, __m256i y)
+{
+ register __m256i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x; b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm256_madd_epi16 (a, b);
+ asm volatile ("" : "+v" (a));
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpmulhrsw-3.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpmulhrsw-3.c
new file mode 100644
index 00000000000..b7088ae1457
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpmulhrsw-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, __m128i y)
+{
+ register __m128i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm_mulhrs_epi16 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpmulhrsw\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]" } } */
+
+void
+f2 (__m256i x, __m256i y)
+{
+ register __m256i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm256_mulhrs_epi16 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpmulhrsw\[^\n\r]*ymm1\[67]\[^\n\r]*ymm1\[67]\[^\n\r]*ymm1\[67]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpshufb-3.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpshufb-3.c
new file mode 100644
index 00000000000..5c215ae4705
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpshufb-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, __m128i y)
+{
+ register __m128i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm_shuffle_epi8 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpshufb\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]" } } */
+
+void
+f2 (__m256i x, __m256i y)
+{
+ register __m256i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm256_shuffle_epi8 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpshufb\[^\n\r]*ymm1\[67]\[^\n\r]*ymm1\[67]\[^\n\r]*ymm1\[67]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512bw-vpsraw-3.c b/gcc/testsuite/gcc.target/i386/avx512bw-vpsraw-3.c
new file mode 100644
index 00000000000..305dbccb9a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512bw-vpsraw-3.c
@@ -0,0 +1,44 @@
+/* { dg-do assemble { target { avx512bw && { avx512vl && { ! ia32 } } } } } */
+/* { dg-options "-O2 -mavx512bw -mavx512vl" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, int y)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_srai_epi16 (a, y);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_srai_epi16 (a, 16);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f3 (__m256i x, int y)
+{
+ register __m256i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm256_srai_epi16 (a, y);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f4 (__m256i x)
+{
+ register __m256i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm256_srai_epi16 (a, 16);
+ asm volatile ("" : "+v" (a));
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512dq-abs-copysign-1.c b/gcc/testsuite/gcc.target/i386/avx512dq-abs-copysign-1.c
new file mode 100644
index 00000000000..cb542d09058
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512dq-abs-copysign-1.c
@@ -0,0 +1,71 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-Ofast -mavx512vl -mavx512dq" } */
+
+void
+f1 (float x)
+{
+ register float a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_fabsf (a);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (float x, float y)
+{
+ register float a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = __builtin_copysignf (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f3 (float x)
+{
+ register float a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = -a;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f4 (double x)
+{
+ register double a __asm ("xmm18");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_fabs (a);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f5 (double x, double y)
+{
+ register double a __asm ("xmm18"), b __asm ("xmm19");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = __builtin_copysign (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f6 (double x)
+{
+ register double a __asm ("xmm18");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = -a;
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vandps\[^\n\r\]*xmm16" } } */
+/* { dg-final { scan-assembler "vorps\[^\n\r\]*xmm16" } } */
+/* { dg-final { scan-assembler "vxorps\[^\n\r\]*xmm16" } } */
+/* { dg-final { scan-assembler "vandpd\[^\n\r\]*xmm18" } } */
+/* { dg-final { scan-assembler "vorpd\[^\n\r\]*xmm18" } } */
+/* { dg-final { scan-assembler "vxorpd\[^\n\r\]*xmm18" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512dq-logic-2.c b/gcc/testsuite/gcc.target/i386/avx512dq-logic-2.c
new file mode 100644
index 00000000000..e358ff56848
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512dq-logic-2.c
@@ -0,0 +1,196 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512dq" } */
+
+#include <x86intrin.h>
+
+__m128d
+f1 (__m128d a, __m128d b)
+{
+ register __m128d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_and_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vandpd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f2 (__m128d a, __m128d b)
+{
+ register __m128d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_or_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vorpd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f3 (__m128d a, __m128d b)
+{
+ register __m128d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_xor_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vxorpd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f4 (__m128d a, __m128d b)
+{
+ register __m128d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_andnot_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vandnpd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f5 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_and_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vandps\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f6 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_or_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vorps\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f7 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_xor_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vxorps\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f8 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_andnot_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vandnps\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m256d
+f9 (__m256d a, __m256d b)
+{
+ register __m256d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_and_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vandpd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f10 (__m256d a, __m256d b)
+{
+ register __m256d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_or_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vorpd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f11 (__m256d a, __m256d b)
+{
+ register __m256d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_xor_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vxorpd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f12 (__m256d a, __m256d b)
+{
+ register __m256d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_andnot_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vandnpd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f13 (__m256 a, __m256 b)
+{
+ register __m256 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_and_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vandps\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f14 (__m256 a, __m256 b)
+{
+ register __m256 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_or_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vorps\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f15 (__m256 a, __m256 b)
+{
+ register __m256 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_xor_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vxorps\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f16 (__m256 a, __m256 b)
+{
+ register __m256 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_andnot_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vandnps\[^\n\r\]*ymm\[0-9\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512dq-vbroadcast-2.c b/gcc/testsuite/gcc.target/i386/avx512dq-vbroadcast-2.c
new file mode 100644
index 00000000000..645765696e0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512dq-vbroadcast-2.c
@@ -0,0 +1,49 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512dq" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i c;
+ a = x;
+ asm volatile ("" : "+v" (a));
+ c = _mm256_broadcastsi128_si256 (a);
+ register __m256i b __asm ("xmm16");
+ b = c;
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vinserti64x2\[^\n\r]*(xmm16\[^\n\r]*ymm16\[^\n\r]*ymm16|ymm16\[^\n\r]*ymm16\[^\n\r]*xmm16)" } } */
+
+void
+f2 (__m128i *x)
+{
+ register __m256i a __asm ("xmm16");
+ a = _mm256_broadcastsi128_si256 (*x);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vbroadcasti64x2\[^\n\r]*ymm16" } } */
+
+void
+f3 (__m128 *x)
+{
+ register __m256 a __asm ("xmm16");
+ a = _mm256_broadcast_ps (x);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vbroadcastf32x4\[^\n\r]*ymm16" } } */
+
+void
+f4 (__m128d *x)
+{
+ register __m256d a __asm ("xmm16");
+ a = _mm256_broadcast_pd (x);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vbroadcastf64x2\[^\n\r]*ymm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512dq-vinsert-1.c b/gcc/testsuite/gcc.target/i386/avx512dq-vinsert-1.c
new file mode 100644
index 00000000000..5d42f44fef3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512dq-vinsert-1.c
@@ -0,0 +1,100 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512dq -masm=att" } */
+
+typedef int V1 __attribute__((vector_size (32)));
+typedef long long V2 __attribute__((vector_size (32)));
+typedef float V3 __attribute__((vector_size (32)));
+typedef double V4 __attribute__((vector_size (32)));
+
+void
+f1 (V1 x, int y)
+{
+ register V1 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (V1 x, int y)
+{
+ register V1 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[6] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f3 (V2 x, long long y)
+{
+ register V2 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[1] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f4 (V2 x, long long y)
+{
+ register V2 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f5 (V3 x, float y)
+{
+ register V3 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f6 (V3 x, float y)
+{
+ register V3 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[6] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f7 (V4 x, double y)
+{
+ register V4 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[1] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f8 (V4 x, double y)
+{
+ register V4 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-times "vinserti32x4\[^\n\r]*0x0\[^\n\r]*%ymm16" 1 } } */
+/* { dg-final { scan-assembler-times "vinserti32x4\[^\n\r]*0x1\[^\n\r]*%ymm16" 1 } } */
+/* { dg-final { scan-assembler-times "vinsertf32x4\[^\n\r]*0x0\[^\n\r]*%ymm16" 1 } } */
+/* { dg-final { scan-assembler-times "vinsertf32x4\[^\n\r]*0x1\[^\n\r]*%ymm16" 1 } } */
+/* { dg-final { scan-assembler-times "vextracti32x4\[^\n\r]*0x1\[^\n\r]*%\[yz]mm16" 1 } } */
+/* { dg-final { scan-assembler-times "vextractf32x4\[^\n\r]*0x1\[^\n\r]*%\[yz]mm16" 1 } } */
+/* { dg-final { scan-assembler-times "vinserti64x2\[^\n\r]*0x0\[^\n\r]*%ymm16" 1 } } */
+/* { dg-final { scan-assembler-times "vinserti64x2\[^\n\r]*0x1\[^\n\r]*%ymm16" 1 } } */
+/* { dg-final { scan-assembler-times "vinsertf64x2\[^\n\r]*0x0\[^\n\r]*%ymm16" 1 } } */
+/* { dg-final { scan-assembler-times "vinsertf64x2\[^\n\r]*0x1\[^\n\r]*%ymm16" 1 } } */
+/* { dg-final { scan-assembler-times "vextracti64x2\[^\n\r]*0x1\[^\n\r]*%\[yz]mm16" 1 } } */
+/* { dg-final { scan-assembler-times "vextractf64x2\[^\n\r]*0x1\[^\n\r]*%\[yz]mm16" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512dq-vpextr-1.c b/gcc/testsuite/gcc.target/i386/avx512dq-vpextr-1.c
new file mode 100644
index 00000000000..3c6abafc28f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512dq-vpextr-1.c
@@ -0,0 +1,53 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512dq" } */
+
+typedef int v4si __attribute__((vector_size (16)));
+typedef long long v2di __attribute__((vector_size (16)));
+
+unsigned int
+f1 (v4si a)
+{
+ register v4si c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v4si d = c;
+ return ((unsigned int *) &d)[3];
+}
+
+unsigned long long
+f2 (v2di a)
+{
+ register v2di c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v2di d = c;
+ return ((unsigned long long *) &d)[1];
+}
+
+unsigned long long
+f3 (v4si a)
+{
+ register v4si c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v4si d = c;
+ return ((unsigned int *) &d)[3];
+}
+
+void
+f4 (v4si a, unsigned int *p)
+{
+ register v4si c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v4si d = c;
+ *p = ((unsigned int *) &d)[3];
+}
+
+void
+f5 (v2di a, unsigned long long *p)
+{
+ register v2di c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v2di d = c;
+ *p = ((unsigned long long *) &d)[1];
+}
+
+/* { dg-final { scan-assembler-times "vpextrd\[^\n\r]*xmm16" 3 } } */
+/* { dg-final { scan-assembler-times "vpextrq\[^\n\r]*xmm16" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512dq-vpinsr-1.c b/gcc/testsuite/gcc.target/i386/avx512dq-vpinsr-1.c
new file mode 100644
index 00000000000..427b4e73a16
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512dq-vpinsr-1.c
@@ -0,0 +1,33 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mavx512dq" } */
+
+typedef int v4si __attribute__((vector_size (16)));
+typedef long long v2di __attribute__((vector_size (16)));
+
+v4si
+f1 (v4si a, int b)
+{
+ register v4si c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v4si d = c;
+ ((int *) &d)[3] = b;
+ c = d;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler "vpinsrd\[^\n\r]*xmm16" } } */
+
+v2di
+f2 (v2di a, long long b)
+{
+ register v2di c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v2di d = c;
+ ((long long *) &d)[1] = b;
+ c = d;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler "vpinsrq\[^\n\r]*xmm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-additional-reg-names.c b/gcc/testsuite/gcc.target/i386/avx512f-additional-reg-names.c
index e5ee08bcbd2..5c68731dcd7 100644
--- a/gcc/testsuite/gcc.target/i386/avx512f-additional-reg-names.c
+++ b/gcc/testsuite/gcc.target/i386/avx512f-additional-reg-names.c
@@ -5,5 +5,5 @@ void foo ()
{
register int zmm_var asm ("zmm6") __attribute__((unused));
- __asm__ __volatile__("vxorpd %%zmm0, %%zmm0, %%zmm7\n" : : : "zmm7" );
+ __asm__ __volatile__("vpxord %%zmm0, %%zmm0, %%zmm7\n" : : : "zmm7" );
}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-cvt-1.c b/gcc/testsuite/gcc.target/i386/avx512f-cvt-1.c
new file mode 100644
index 00000000000..acfbe311aac
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-cvt-1.c
@@ -0,0 +1,38 @@
+/* { dg-do assemble { target { avx512f && { ! ia32 } } } } */
+/* { dg-options "-O2 -mavx512f -mfpmath=387,sse" } */
+
+void
+f1 (double *p)
+{
+ register float x __asm ("xmm16");
+ x = *p;
+ __asm volatile ("" : "+v" (x));
+}
+
+void
+f2 (void)
+{
+ double d;
+ register float x __asm ("xmm16");
+ __asm volatile ("" : "=t" (d));
+ x = d;
+ __asm volatile ("" : "+v" (x));
+}
+
+void
+f3 (long double *p)
+{
+ register float x __asm ("xmm16");
+ x = *p;
+ __asm volatile ("" : "+v" (x));
+}
+
+void
+f4 (void)
+{
+ long double d;
+ register float x __asm ("xmm16");
+ __asm volatile ("" : "=t" (d));
+ x = d;
+ __asm volatile ("" : "+v" (x));
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512f-vfmadd-1.c b/gcc/testsuite/gcc.target/i386/avx512f-vfmadd-1.c
new file mode 100644
index 00000000000..f317ec66a3a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512f-vfmadd-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512f" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m512d x, __m512d y, __m512d z, __mmask8 m)
+{
+ register __m512d a __asm ("xmm16"), b __asm ("xmm17"), c __asm ("xmm18");
+ a = x; b = y; c = z;
+ asm volatile ("" : "+v" (a), "+v" (b), "+v" (c));
+ a = _mm512_mask3_fmadd_round_pd (c, b, a, m, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (__m512 x, __m512 y, __m512 z, __mmask8 m)
+{
+ register __m512 a __asm ("xmm16"), b __asm ("xmm17"), c __asm ("xmm18");
+ a = x; b = y; c = z;
+ asm volatile ("" : "+v" (a), "+v" (b), "+v" (c));
+ a = _mm512_mask3_fmadd_round_ps (c, b, a, m, _MM_FROUND_TO_NEG_INF | _MM_FROUND_NO_EXC);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vfmadd231pd\[^\n\r\]*zmm16" } } */
+/* { dg-final { scan-assembler "vfmadd231ps\[^\n\r\]*zmm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-1.c
new file mode 100644
index 00000000000..b375c5fad80
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-1.c
@@ -0,0 +1,71 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-Ofast -mavx512vl -mno-avx512dq" } */
+
+void
+f1 (float x)
+{
+ register float a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_fabsf (a);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (float x, float y)
+{
+ register float a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = __builtin_copysignf (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f3 (float x)
+{
+ register float a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = -a;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f4 (double x)
+{
+ register double a __asm ("xmm18");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_fabs (a);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f5 (double x, double y)
+{
+ register double a __asm ("xmm18"), b __asm ("xmm19");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = __builtin_copysign (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f6 (double x)
+{
+ register double a __asm ("xmm18");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = -a;
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpandd\[^\n\r\]*xmm16" } } */
+/* { dg-final { scan-assembler "vpord\[^\n\r\]*xmm16" } } */
+/* { dg-final { scan-assembler "vpxord\[^\n\r\]*xmm16" } } */
+/* { dg-final { scan-assembler "vpandq\[^\n\r\]*xmm18" } } */
+/* { dg-final { scan-assembler "vporq\[^\n\r\]*xmm18" } } */
+/* { dg-final { scan-assembler "vpxorq\[^\n\r\]*xmm18" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-2.c
new file mode 100644
index 00000000000..9082cdb5dba
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-abs-copysign-2.c
@@ -0,0 +1,49 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-Ofast -mavx512vl" } */
+
+void
+f1 (__float128 x)
+{
+ register __float128 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_fabsq (a);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (__float128 x, __float128 y)
+{
+ register __float128 a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = __builtin_copysignq (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f3 (__float128 x)
+{
+ register __float128 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = -a;
+ asm volatile ("" : "+v" (a));
+}
+
+__int128_t
+f4 (void)
+{
+ register __int128_t a __asm ("xmm16");
+ register __int128_t __attribute__((vector_size (16))) b __asm ("xmm17");
+ a = 1;
+ asm volatile ("" : "+v" (a));
+ b[0] = a;
+ asm volatile ("" : "+v" (b));
+ return b[0];
+}
+
+/* { dg-final { scan-assembler "vpandq\[^\n\r\]*xmm16" } } */
+/* { dg-final { scan-assembler "vporq\[^\n\r\]*xmm16" } } */
+/* { dg-final { scan-assembler "vpxorq\[^\n\r\]*xmm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-logic-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-logic-1.c
new file mode 100644
index 00000000000..ec5f3d980c1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-logic-1.c
@@ -0,0 +1,132 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512dq" } */
+
+#include <x86intrin.h>
+
+__m128d
+f1 (__m128d a, __m128d b)
+{
+ return _mm_and_pd (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vandpd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f2 (__m128d a, __m128d b)
+{
+ return _mm_or_pd (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vorpd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f3 (__m128d a, __m128d b)
+{
+ return _mm_xor_pd (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vxorpd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f4 (__m128d a, __m128d b)
+{
+ return _mm_andnot_pd (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vandnpd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f5 (__m128 a, __m128 b)
+{
+ return _mm_and_ps (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vandps\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f6 (__m128 a, __m128 b)
+{
+ return _mm_or_ps (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vorps\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f7 (__m128 a, __m128 b)
+{
+ return _mm_xor_ps (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vxorps\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f8 (__m128 a, __m128 b)
+{
+ return _mm_andnot_ps (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vandnps\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m256d
+f9 (__m256d a, __m256d b)
+{
+ return _mm256_and_pd (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vandpd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f10 (__m256d a, __m256d b)
+{
+ return _mm256_or_pd (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vorpd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f11 (__m256d a, __m256d b)
+{
+ return _mm256_xor_pd (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vxorpd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f12 (__m256d a, __m256d b)
+{
+ return _mm256_andnot_pd (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vandnpd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f13 (__m256 a, __m256 b)
+{
+ return _mm256_and_ps (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vandps\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f14 (__m256 a, __m256 b)
+{
+ return _mm256_or_ps (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vorps\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f15 (__m256 a, __m256 b)
+{
+ return _mm256_xor_ps (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vxorps\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f16 (__m256 a, __m256 b)
+{
+ return _mm256_andnot_ps (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vandnps\[^\n\r\]*ymm\[0-9\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-logic-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-logic-2.c
new file mode 100644
index 00000000000..7ccef279a8b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-logic-2.c
@@ -0,0 +1,196 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512dq" } */
+
+#include <x86intrin.h>
+
+__m128d
+f1 (__m128d a, __m128d b)
+{
+ register __m128d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_and_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpandq\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f2 (__m128d a, __m128d b)
+{
+ register __m128d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_or_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vporq\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f3 (__m128d a, __m128d b)
+{
+ register __m128d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_xor_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpxorq\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128d
+f4 (__m128d a, __m128d b)
+{
+ register __m128d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_andnot_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpandnq\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f5 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_and_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpandd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f6 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_or_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpord\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f7 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_xor_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpxord\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128
+f8 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_andnot_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpandnd\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m256d
+f9 (__m256d a, __m256d b)
+{
+ register __m256d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_and_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpandq\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f10 (__m256d a, __m256d b)
+{
+ register __m256d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_or_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vporq\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f11 (__m256d a, __m256d b)
+{
+ register __m256d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_xor_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpxorq\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256d
+f12 (__m256d a, __m256d b)
+{
+ register __m256d c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_andnot_pd (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpandnq\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f13 (__m256 a, __m256 b)
+{
+ register __m256 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_and_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpandd\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f14 (__m256 a, __m256 b)
+{
+ register __m256 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_or_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpord\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f15 (__m256 a, __m256 b)
+{
+ register __m256 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_xor_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpxord\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256
+f16 (__m256 a, __m256 b)
+{
+ register __m256 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_andnot_ps (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpandnd\[^\n\r\]*ymm\[0-9\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-pack-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-pack-1.c
new file mode 100644
index 00000000000..a589d63ed3b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-pack-1.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw" } */
+
+#include <x86intrin.h>
+
+__m128i
+f1 (__m128i a, __m128i b)
+{
+ return _mm_packs_epi16 (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vpacksswb\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128i
+f2 (__m128i a, __m128i b)
+{
+ return _mm_packs_epi32 (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vpackssdw\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128i
+f3 (__m128i a, __m128i b)
+{
+ return _mm_packus_epi16 (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vpackuswb\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m128i
+f4 (__m128i a, __m128i b)
+{
+ return _mm_packus_epi32 (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vpackusdw\[^\n\r\]*xmm\[0-9\]" 1 } } */
+
+__m256i
+f5 (__m256i a, __m256i b)
+{
+ return _mm256_packs_epi16 (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vpacksswb\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256i
+f6 (__m256i a, __m256i b)
+{
+ return _mm256_packs_epi32 (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vpackssdw\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256i
+f7 (__m256i a, __m256i b)
+{
+ return _mm256_packus_epi16 (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vpackuswb\[^\n\r\]*ymm\[0-9\]" 1 } } */
+
+__m256i
+f8 (__m256i a, __m256i b)
+{
+ return _mm256_packus_epi32 (a, b);
+}
+
+/* { dg-final { scan-assembler-times "vpackusdw\[^\n\r\]*ymm\[0-9\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-pack-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-pack-2.c
new file mode 100644
index 00000000000..05820065e9f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-pack-2.c
@@ -0,0 +1,108 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw" } */
+
+#include <x86intrin.h>
+
+__m128i
+f1 (__m128i a, __m128i b)
+{
+ register __m128i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_packs_epi16 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpacksswb\[^\n\r\]*xmm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-not "vpacksswb\[^\n\r\]*xmm16" } } */
+
+__m128i
+f2 (__m128i a, __m128i b)
+{
+ register __m128i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_packs_epi32 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackssdw\[^\n\r\]*xmm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-not "vpackssdw\[^\n\r\]*xmm16" } } */
+
+__m128i
+f3 (__m128i a, __m128i b)
+{
+ register __m128i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_packus_epi16 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackuswb\[^\n\r\]*xmm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-not "vpackuswb\[^\n\r\]*xmm16" } } */
+
+__m128i
+f4 (__m128i a, __m128i b)
+{
+ register __m128i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_packus_epi32 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackusdw\[^\n\r\]*xmm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-not "vpackusdw\[^\n\r\]*xmm16" } } */
+
+__m256i
+f5 (__m256i a, __m256i b)
+{
+ register __m256i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_packs_epi16 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpacksswb\[^\n\r\]*ymm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-not "vpacksswb\[^\n\r\]*ymm16" } } */
+
+__m256i
+f6 (__m256i a, __m256i b)
+{
+ register __m256i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_packs_epi32 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackssdw\[^\n\r\]*ymm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-not "vpackssdw\[^\n\r\]*ymm16" } } */
+
+__m256i
+f7 (__m256i a, __m256i b)
+{
+ register __m256i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_packus_epi16 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackuswb\[^\n\r\]*ymm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-not "vpackuswb\[^\n\r\]*ymm16" } } */
+
+__m256i
+f8 (__m256i a, __m256i b)
+{
+ register __m256i c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm256_packus_epi32 (c, b);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-times "vpackusdw\[^\n\r\]*ymm\[0-9\]" 1 } } */
+/* { dg-final { scan-assembler-not "vpackusdw\[^\n\r\]*ymm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vbroadcast-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vbroadcast-1.c
new file mode 100644
index 00000000000..8a74675f4dc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vbroadcast-1.c
@@ -0,0 +1,41 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128d x)
+{
+ register __m128d a __asm ("xmm16");
+ register __m256d b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastsd_pd (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vbroadcastsd\[^\n\r]*(xmm16\[^\n\r]*ymm17|ymm17\[^\n\r]*xmm16)" } } */
+
+void
+f2 (float const *x)
+{
+ register __m128 a __asm ("xmm16");
+ a = _mm_broadcast_ss (x);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vbroadcastss\[^\n\r]*(\\)\[^\n\r]*xmm16|xmm16\[^\n\r]*PTR)" } } */
+
+void
+f3 (float x)
+{
+ register float a __asm ("xmm16");
+ register __m128 b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ float c = a;
+ b = _mm_broadcast_ss (&c);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vbroadcastss\[^\n\r]*xmm1\[67]\[^\n\r]*xmm1\[67]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vbroadcast-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-vbroadcast-2.c
new file mode 100644
index 00000000000..22f4129f4f8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vbroadcast-2.c
@@ -0,0 +1,47 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512dq" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i c;
+ a = x;
+ asm volatile ("" : "+v" (a));
+ c = _mm256_broadcastsi128_si256 (a);
+ register __m256i b __asm ("xmm16");
+ b = c;
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vinserti32x4\[^\n\r]*(xmm16\[^\n\r]*ymm16\[^\n\r]*ymm16|ymm16\[^\n\r]*ymm16\[^\n\r]*xmm16)" } } */
+
+void
+f2 (__m128i *x)
+{
+ register __m256i a __asm ("xmm16");
+ a = _mm256_broadcastsi128_si256 (*x);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vbroadcasti32x4\[^\n\r]*ymm16" } } */
+
+void
+f3 (__m128 *x)
+{
+ register __m256 a __asm ("xmm16");
+ a = _mm256_broadcast_ps (x);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f4 (__m128d *x)
+{
+ register __m256d a __asm ("xmm16");
+ a = _mm256_broadcast_pd (x);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-times "vbroadcastf32x4\[^\n\r]*ymm16" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vinsert-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vinsert-1.c
new file mode 100644
index 00000000000..f12260a23f3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vinsert-1.c
@@ -0,0 +1,98 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512dq -masm=att" } */
+
+typedef int V1 __attribute__((vector_size (32)));
+typedef long long V2 __attribute__((vector_size (32)));
+typedef float V3 __attribute__((vector_size (32)));
+typedef double V4 __attribute__((vector_size (32)));
+
+void
+f1 (V1 x, int y)
+{
+ register V1 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (V1 x, int y)
+{
+ register V1 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[6] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f3 (V2 x, long long y)
+{
+ register V2 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[1] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f4 (V2 x, long long y)
+{
+ register V2 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f5 (V3 x, float y)
+{
+ register V3 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f6 (V3 x, float y)
+{
+ register V3 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[6] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f7 (V4 x, double y)
+{
+ register V4 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[1] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f8 (V4 x, double y)
+{
+ register V4 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-times "vinserti32x4\[^\n\r]*0x0\[^\n\r]*%ymm16" 2 } } */
+/* { dg-final { scan-assembler-times "vinserti32x4\[^\n\r]*0x1\[^\n\r]*%ymm16" 2 } } */
+/* { dg-final { scan-assembler-times "vinsertf32x4\[^\n\r]*0x0\[^\n\r]*%ymm16" 2 } } */
+/* { dg-final { scan-assembler-times "vinsertf32x4\[^\n\r]*0x1\[^\n\r]*%ymm16" 2 } } */
+/* { dg-final { scan-assembler-times "vextracti32x4\[^\n\r]*0x1\[^\n\r]*%\[yz]mm16" 2 } } */
+/* { dg-final { scan-assembler-times "vextractf32x4\[^\n\r]*0x1\[^\n\r]*%\[yz]mm16" 2 } } */
+/* { dg-final { scan-assembler-not "vinserti64x2" } } */
+/* { dg-final { scan-assembler-not "vinsertf64x2" } } */
+/* { dg-final { scan-assembler-not "vextracti64x2" } } */
+/* { dg-final { scan-assembler-not "vextracti64x2" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vinserti32x4-3.c b/gcc/testsuite/gcc.target/i386/avx512vl-vinserti32x4-3.c
new file mode 100644
index 00000000000..45b0122e925
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vinserti32x4-3.c
@@ -0,0 +1,49 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -masm=att" } */
+
+typedef char V1 __attribute__((vector_size (32)));
+typedef short V2 __attribute__((vector_size (32)));
+
+void
+f1 (V1 x, char y)
+{
+ register V1 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[7] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (V1 x, char y)
+{
+ register V1 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[28] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f3 (V2 x, short y)
+{
+ register V2 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[3] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f4 (V2 x, short y)
+{
+ register V2 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a[14] = y;
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-times "vinserti32x4\[^\n\r]*0x0\[^\n\r]*%ymm16" 2 } } */
+/* { dg-final { scan-assembler-times "vinserti32x4\[^\n\r]*0x1\[^\n\r]*%ymm16" 2 } } */
+/* { dg-final { scan-assembler-times "vextracti32x4\[^\n\r]*0x1\[^\n\r]*%\[yz]mm16" 2 } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vinsertps-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vinsertps-1.c
new file mode 100644
index 00000000000..ccadcc74d12
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vinsertps-1.c
@@ -0,0 +1,39 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl" } */
+
+#include <x86intrin.h>
+
+__m128
+f1 (__m128 a, __m128 b)
+{
+ register __m128 c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ c = _mm_insert_ps (c, b, 1);
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler "vinsertps\[^\n\r\]*xmm16" } } */
+
+__v4sf
+f2 (__v4sf a, float b)
+{
+ register __v4sf c __asm ("xmm17") = a;
+ asm volatile ("" : "+v" (c));
+ c[1] = b;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler "vinsertps\[^\n\r\]*xmm17" } } */
+
+__v4sf
+f3 (__v4sf a, float b)
+{
+ register float c __asm ("xmm18") = b;
+ asm volatile ("" : "+v" (c));
+ a[1] = c;
+ return a;
+}
+
+/* { dg-final { scan-assembler "vinsertps\[^\n\r\]*xmm18" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vmovq-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vmovq-1.c
new file mode 100644
index 00000000000..8f3d3460a6c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vmovq-1.c
@@ -0,0 +1,16 @@
+/* { dg-do assemble { target { avx512vl && { ! ia32 } } } } */
+/* { dg-options "-O2 -mavx512vl" } */
+
+#include <x86intrin.h>
+
+void
+foo (__m128i x, __m128i *y)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_move_epi64 (a);
+ asm volatile ("" : "+v" (a));
+ a = _mm_move_epi64 (*y);
+ asm volatile ("" : "+v" (a));
+}
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpalignr-3.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpalignr-3.c
new file mode 100644
index 00000000000..7066d2af83b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpalignr-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, __m128i y)
+{
+ register __m128i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm_alignr_epi8 (a, b, 3);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpalignr\[^\n\r]*xmm1\[67]" } } */
+
+void
+f2 (__m256i x, __m256i y)
+{
+ register __m256i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm256_alignr_epi8 (a, b, 3);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpalignr\[^\n\r]*ymm1\[67]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-1.c
new file mode 100644
index 00000000000..45458096ba3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-1.c
@@ -0,0 +1,104 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_broadcastb_epi8 (a);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastb\[^\n\r]*xmm16" } } */
+
+void
+f2 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_broadcastw_epi16 (a);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastw\[^\n\r]*xmm16" } } */
+
+void
+f3 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_broadcastd_epi32 (a);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastd\[^\n\r]*xmm16\[^\n\r]*xmm16" } } */
+
+void
+f4 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_broadcastq_epi64 (a);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastq\[^\n\r]*xmm16\[^\n\r]*xmm16" } } */
+
+void
+f5 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastb_epi8 (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastb\[^\n\r]*\[xy]mm1\[67]" } } */
+
+void
+f6 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastw_epi16 (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastw\[^\n\r]*\[xy]mm1\[67]" } } */
+
+void
+f7 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastd_epi32 (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastd\[^\n\r]*(xmm1\[67]\[^\n\r]*ymm1\[67]|ymm1\[67]\[^\n\r]*xmm1\[67])" } } */
+
+void
+f8 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ register __m256i b __asm ("xmm17");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ b = _mm256_broadcastq_epi64 (a);
+ asm volatile ("" : "+v" (b));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastq\[^\n\r]*(xmm1\[67]\[^\n\r]*ymm1\[67]|ymm1\[67]\[^\n\r]*xmm1\[67])" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-2.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-2.c
new file mode 100644
index 00000000000..aed9914b597
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-2.c
@@ -0,0 +1,68 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw" } */
+
+typedef char V1 __attribute__((vector_size (16)));
+typedef short V2 __attribute__((vector_size (16)));
+typedef char V5 __attribute__((vector_size (32)));
+typedef short V6 __attribute__((vector_size (32)));
+typedef int V7 __attribute__((vector_size (32)));
+
+void
+f1 (V1 x)
+{
+ register V1 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V1) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastb\[^\n\r]*xmm16" } } */
+
+void
+f2 (V2 x)
+{
+ register V2 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V2) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastw\[^\n\r]*xmm16" } } */
+
+void
+f5 (V5 x)
+{
+ register V5 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V5) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastb\[^\n\r]*\[xy]mm16" } } */
+
+void
+f6 (V6 x)
+{
+ register V6 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V6) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastw\[^\n\r]*\[xy]mm16" } } */
+
+void
+f7 (V7 x)
+{
+ register V7 a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = __builtin_shuffle (a, (V7) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastd\[^\n\r]*(xmm16\[^\n\r]*ymm16|ymm16\[^\n\r]*xmm16)" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-3.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-3.c
new file mode 100644
index 00000000000..b93bd362ed3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpbroadcast-3.c
@@ -0,0 +1,58 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw" } */
+
+typedef char V1 __attribute__((vector_size (16)));
+typedef short V2 __attribute__((vector_size (16)));
+typedef char V5 __attribute__((vector_size (32)));
+typedef short V6 __attribute__((vector_size (32)));
+typedef int V7 __attribute__((vector_size (32)));
+
+void
+f1 (V1 *x)
+{
+ register V1 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V1) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastb\[^\n\r]*xmm16" } } */
+
+void
+f2 (V2 *x)
+{
+ register V2 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V2) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastw\[^\n\r]*xmm16" } } */
+
+void
+f5 (V5 *x)
+{
+ register V5 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V5) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastb\[^\n\r]*ymm16" } } */
+
+void
+f6 (V6 *x)
+{
+ register V6 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V6) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpbroadcastw\[^\n\r]*ymm16" } } */
+
+void
+f7 (V7 *x)
+{
+ register V7 a __asm ("xmm16");
+ a = __builtin_shuffle (*x, (V7) { 0 });
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler "vpbroadcastd\[^\n\r]*ymm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpinsr-1.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpinsr-1.c
new file mode 100644
index 00000000000..9cfab9bf542
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpinsr-1.c
@@ -0,0 +1,63 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw -mno-avx512dq" } */
+
+typedef char v16qi __attribute__((vector_size (16)));
+typedef short v8hi __attribute__((vector_size (16)));
+typedef int v4si __attribute__((vector_size (16)));
+typedef long long v2di __attribute__((vector_size (16)));
+
+v16qi
+f1 (v16qi a, char b)
+{
+ register v16qi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v16qi d = c;
+ ((char *) &d)[3] = b;
+ c = d;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-not "vpinsrb\[^\n\r]*xmm16" } } */
+
+v8hi
+f2 (v8hi a, short b)
+{
+ register v8hi c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v8hi d = c;
+ ((short *) &d)[3] = b;
+ c = d;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-not "vpinsrw\[^\n\r]*xmm16" } } */
+
+v4si
+f3 (v4si a, int b)
+{
+ register v4si c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v4si d = c;
+ ((int *) &d)[3] = b;
+ c = d;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-not "vpinsrd\[^\n\r]*xmm16" } } */
+
+v2di
+f4 (v2di a, char b)
+{
+ register v2di c __asm ("xmm16") = a;
+ asm volatile ("" : "+v" (c));
+ v2di d = c;
+ ((long long *) &d)[1] = b;
+ c = d;
+ asm volatile ("" : "+v" (c));
+ return c;
+}
+
+/* { dg-final { scan-assembler-not "vpinsrq\[^\n\r]*xmm16" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpmulhrsw-3.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpmulhrsw-3.c
new file mode 100644
index 00000000000..10a2f158fd1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpmulhrsw-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, __m128i y)
+{
+ register __m128i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm_mulhrs_epi16 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpmulhrsw\[^\n\r]*xmm1\[67]" } } */
+
+void
+f2 (__m256i x, __m256i y)
+{
+ register __m256i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm256_mulhrs_epi16 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpmulhrsw\[^\n\r]*ymm1\[67]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpshufb-3.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpshufb-3.c
new file mode 100644
index 00000000000..ffdfad5cb1c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpshufb-3.c
@@ -0,0 +1,30 @@
+/* { dg-do compile { target { ! ia32 } } } */
+/* { dg-options "-O2 -mavx512vl -mno-avx512bw" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, __m128i y)
+{
+ register __m128i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm_shuffle_epi8 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpshufb\[^\n\r]*xmm1\[67]" } } */
+
+void
+f2 (__m256i x, __m256i y)
+{
+ register __m256i a __asm ("xmm16"), b __asm ("xmm17");
+ a = x;
+ b = y;
+ asm volatile ("" : "+v" (a), "+v" (b));
+ a = _mm256_shuffle_epi8 (a, b);
+ asm volatile ("" : "+v" (a));
+}
+
+/* { dg-final { scan-assembler-not "vpshufb\[^\n\r]*ymm1\[67]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/avx512vl-vpsrad-3.c b/gcc/testsuite/gcc.target/i386/avx512vl-vpsrad-3.c
new file mode 100644
index 00000000000..2e3f92b58b7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/avx512vl-vpsrad-3.c
@@ -0,0 +1,44 @@
+/* { dg-do assemble { target { avx512vl && { ! ia32 } } } } */
+/* { dg-options "-O2 -mavx512vl" } */
+
+#include <x86intrin.h>
+
+void
+f1 (__m128i x, int y)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_srai_epi32 (a, y);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f2 (__m128i x)
+{
+ register __m128i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm_srai_epi32 (a, 16);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f3 (__m256i x, int y)
+{
+ register __m256i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm256_srai_epi32 (a, y);
+ asm volatile ("" : "+v" (a));
+}
+
+void
+f4 (__m256i x)
+{
+ register __m256i a __asm ("xmm16");
+ a = x;
+ asm volatile ("" : "+v" (a));
+ a = _mm256_srai_epi32 (a, 16);
+ asm volatile ("" : "+v" (a));
+}
diff --git a/gcc/testsuite/gcc.target/i386/fabsneg-1.c b/gcc/testsuite/gcc.target/i386/fabsneg-1.c
new file mode 100644
index 00000000000..3cdf4566864
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/fabsneg-1.c
@@ -0,0 +1,36 @@
+/* { dg-do run } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-O2 -mtune=nocona" } */
+
+double x;
+
+void
+__attribute__ ((noinline, noclone))
+test_fabs (double a)
+{
+ asm volatile ("" : "+r" (a));
+ x = __builtin_fabs (a);
+}
+
+void
+__attribute__ ((noinline, noclone))
+test_neg (double a)
+{
+ asm volatile ("" : "+r" (a));
+ x = -a;
+}
+
+int main ()
+{
+ test_fabs (-1.0);
+
+ if (x != 1.0)
+ __builtin_abort ();
+
+ test_neg (-1.0);
+
+ if (x != 1.0)
+ __builtin_abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/mmx-2.c b/gcc/testsuite/gcc.target/i386/mmx-2.c
index 2bb54883b9b..4d016c7e83d 100644
--- a/gcc/testsuite/gcc.target/i386/mmx-2.c
+++ b/gcc/testsuite/gcc.target/i386/mmx-2.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O0 -Werror-implicit-function-declaration -mmmx" } */
-
/* { dg-add-options bind_pic_locally } */
+
/* Test that the intrinsics compile without optimization. All of them are
defined as inline functions in mmintrin.h that reference the proper
builtin functions. Defining away "extern" and "__inline" results in
diff --git a/gcc/testsuite/gcc.target/i386/pr44281.c b/gcc/testsuite/gcc.target/i386/pr44281.c
new file mode 100644
index 00000000000..e8e9edef319
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr44281.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-options "-std=gnu99 -O2" } */
+/* { dg-final { scan-assembler "salq\[ \\t\]+\\\$8, %rbx" } } */
+
+#include <stdint.h>
+
+register uint64_t global_flag_stack __asm__("rbx");
+
+void push_flag_into_global_reg_var(uint64_t a, uint64_t b) {
+ uint64_t flag = (a==b);
+ global_flag_stack <<= 8;
+ global_flag_stack |= flag;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr49244-1.c b/gcc/testsuite/gcc.target/i386/pr49244-1.c
new file mode 100644
index 00000000000..70ccf6e935a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr49244-1.c
@@ -0,0 +1,188 @@
+/* PR target/49244 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void bar (void);
+
+__attribute__((noinline, noclone)) int
+f1 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ return (__sync_fetch_and_or (a, mask) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f2 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ unsigned int t1 = __atomic_fetch_or (a, mask, __ATOMIC_RELAXED);
+ unsigned int t2 = t1 & mask;
+ return t2 != 0;
+}
+
+__attribute__((noinline, noclone)) long int
+f3 (long int *a, int bit)
+{
+ unsigned long int mask = (1ul << bit);
+ return (__atomic_fetch_or (a, mask, __ATOMIC_SEQ_CST) & mask) == 0;
+}
+
+__attribute__((noinline, noclone)) int
+f4 (int *a)
+{
+ unsigned int mask = (1u << 7);
+ return (__sync_fetch_and_or (a, mask) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f5 (int *a)
+{
+ unsigned int mask = (1u << 13);
+ return (__atomic_fetch_or (a, mask, __ATOMIC_RELAXED) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f6 (int *a)
+{
+ unsigned int mask = (1u << 0);
+ return (__atomic_fetch_or (a, mask, __ATOMIC_SEQ_CST) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) void
+f7 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ if ((__sync_fetch_and_xor (a, mask) & mask) != 0)
+ bar ();
+}
+
+__attribute__((noinline, noclone)) void
+f8 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ if ((__atomic_fetch_xor (a, mask, __ATOMIC_RELAXED) & mask) == 0)
+ bar ();
+}
+
+__attribute__((noinline, noclone)) int
+f9 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ return (__atomic_fetch_xor (a, mask, __ATOMIC_SEQ_CST) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f10 (int *a)
+{
+ unsigned int mask = (1u << 7);
+ return (__sync_fetch_and_xor (a, mask) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f11 (int *a)
+{
+ unsigned int mask = (1u << 13);
+ return (__atomic_fetch_xor (a, mask, __ATOMIC_RELAXED) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f12 (int *a)
+{
+ unsigned int mask = (1u << 0);
+ return (__atomic_fetch_xor (a, mask, __ATOMIC_SEQ_CST) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f13 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ return (__sync_fetch_and_and (a, ~mask) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f14 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ return (__atomic_fetch_and (a, ~mask, __ATOMIC_RELAXED) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f15 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ return (__atomic_fetch_and (a, ~mask, __ATOMIC_SEQ_CST) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f16 (int *a)
+{
+ unsigned int mask = (1u << 7);
+ return (__sync_fetch_and_and (a, ~mask) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f17 (int *a)
+{
+ unsigned int mask = (1u << 13);
+ return (__atomic_fetch_and (a, ~mask, __ATOMIC_RELAXED) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) int
+f18 (int *a)
+{
+ unsigned int mask = (1u << 0);
+ return (__atomic_fetch_and (a, ~mask, __ATOMIC_SEQ_CST) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) unsigned long int
+f19 (unsigned long int *a, int bit)
+{
+ unsigned long int mask = (1ul << bit);
+ return (__atomic_xor_fetch (a, mask, __ATOMIC_SEQ_CST) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) unsigned long int
+f20 (unsigned long int *a)
+{
+ unsigned long int mask = (1ul << 7);
+ return (__atomic_xor_fetch (a, mask, __ATOMIC_SEQ_CST) & mask) == 0;
+}
+
+__attribute__((noinline, noclone)) int
+f21 (int *a, int bit)
+{
+ unsigned int mask = (1u << bit);
+ return (__sync_fetch_and_or (a, mask) & mask);
+}
+
+__attribute__((noinline, noclone)) unsigned long int
+f22 (unsigned long int *a)
+{
+ unsigned long int mask = (1ul << 7);
+ return (__atomic_xor_fetch (a, mask, __ATOMIC_SEQ_CST) & mask);
+}
+
+__attribute__((noinline, noclone)) unsigned long int
+f23 (unsigned long int *a)
+{
+ unsigned long int mask = (1ul << 7);
+ return (__atomic_fetch_xor (a, mask, __ATOMIC_SEQ_CST) & mask);
+}
+
+__attribute__((noinline, noclone)) unsigned short int
+f24 (unsigned short int *a)
+{
+ unsigned short int mask = (1u << 7);
+ return (__sync_fetch_and_or (a, mask) & mask) != 0;
+}
+
+__attribute__((noinline, noclone)) unsigned short int
+f25 (unsigned short int *a)
+{
+ unsigned short int mask = (1u << 7);
+ return (__atomic_fetch_or (a, mask, __ATOMIC_SEQ_CST) & mask) != 0;
+}
+
+/* { dg-final { scan-assembler-times "lock;?\[ \t\]*bts" 9 } } */
+/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btc" 10 } } */
+/* { dg-final { scan-assembler-times "lock;?\[ \t\]*btr" 6 } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr49244-2.c b/gcc/testsuite/gcc.target/i386/pr49244-2.c
new file mode 100644
index 00000000000..847408e1a3f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr49244-2.c
@@ -0,0 +1,108 @@
+/* PR target/49244 */
+/* { dg-do run } */
+/* { dg-options "-O2 -g" } */
+
+int cnt;
+
+__attribute__((noinline, noclone)) void
+bar (void)
+{
+ cnt++;
+}
+
+#include "pr49244-1.c"
+
+int a;
+long int b;
+unsigned long int c;
+unsigned short int d;
+
+int
+main ()
+{
+ __atomic_store_n (&a, 15, __ATOMIC_RELAXED);
+ if (f1 (&a, 2) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 15
+ || f1 (&a, 4) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 31)
+ __builtin_abort ();
+ if (f2 (&a, 1) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 31
+ || f2 (&a, 5) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 63)
+ __builtin_abort ();
+ __atomic_store_n (&b, 24, __ATOMIC_RELAXED);
+ if (f3 (&b, 2) != 1 || __atomic_load_n (&b, __ATOMIC_RELAXED) != 28
+ || f3 (&b, 3) != 0 || __atomic_load_n (&b, __ATOMIC_RELAXED) != 28)
+ __builtin_abort ();
+ __atomic_store_n (&a, 0, __ATOMIC_RELAXED);
+ if (f4 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 128
+ || f4 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 128)
+ __builtin_abort ();
+ if (f5 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8320
+ || f5 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8320)
+ __builtin_abort ();
+ if (f6 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8321
+ || f6 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8321)
+ __builtin_abort ();
+ if (cnt != 0
+ || (f7 (&a, 7), cnt) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8193
+ || (f7 (&a, 7), cnt) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8321)
+ __builtin_abort ();
+ if ((f8 (&a, 7), cnt) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8193
+ || (f8 (&a, 7), cnt) != 2 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8321)
+ __builtin_abort ();
+ if (f9 (&a, 13) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 129
+ || f9 (&a, 13) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8321)
+ __builtin_abort ();
+ if (f10 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8193
+ || f10 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8321)
+ __builtin_abort ();
+ if (f11 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 129
+ || f11 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8321)
+ __builtin_abort ();
+ if (f12 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8320
+ || f12 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8321)
+ __builtin_abort ();
+ if (f13 (&a, 7) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8193
+ || f13 (&a, 7) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8193)
+ __builtin_abort ();
+ if (f14 (&a, 13) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 1
+ || f14 (&a, 13) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 1)
+ __builtin_abort ();
+ if (f15 (&a, 0) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 0
+ || f15 (&a, 0) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 0)
+ __builtin_abort ();
+ __atomic_store_n (&a, 8321, __ATOMIC_RELAXED);
+ if (f16 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8193
+ || f16 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 8193)
+ __builtin_abort ();
+ if (f17 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 1
+ || f17 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 1)
+ __builtin_abort ();
+ if (f18 (&a) != 1 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 0
+ || f18 (&a) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 0)
+ __builtin_abort ();
+ if (f19 (&c, 7) != 1 || __atomic_load_n (&c, __ATOMIC_RELAXED) != 128
+ || f19 (&c, 7) != 0 || __atomic_load_n (&c, __ATOMIC_RELAXED) != 0)
+ __builtin_abort ();
+ if (f20 (&c) != 0 || __atomic_load_n (&c, __ATOMIC_RELAXED) != 128
+ || f20 (&c) != 1 || __atomic_load_n (&c, __ATOMIC_RELAXED) != 0)
+ __builtin_abort ();
+ __atomic_store_n (&a, 128, __ATOMIC_RELAXED);
+ if (f21 (&a, 4) != 0 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 144
+ || f21 (&a, 4) != 16 || __atomic_load_n (&a, __ATOMIC_RELAXED) != 144)
+ __builtin_abort ();
+ __atomic_store_n (&c, 1, __ATOMIC_RELAXED);
+ if (f22 (&c) != 128 || __atomic_load_n (&c, __ATOMIC_RELAXED) != 129
+ || f22 (&c) != 0 || __atomic_load_n (&c, __ATOMIC_RELAXED) != 1)
+ __builtin_abort ();
+ if (f23 (&c) != 0 || __atomic_load_n (&c, __ATOMIC_RELAXED) != 129
+ || f23 (&c) != 128 || __atomic_load_n (&c, __ATOMIC_RELAXED) != 1)
+ __builtin_abort ();
+ if (f24 (&d) != 0 || __atomic_load_n (&d, __ATOMIC_RELAXED) != 128
+ || f24 (&d) != 1 || __atomic_load_n (&d, __ATOMIC_RELAXED) != 128)
+ __builtin_abort ();
+ __atomic_store_n (&d, 1, __ATOMIC_RELAXED);
+ if (f25 (&d) != 0 || __atomic_load_n (&d, __ATOMIC_RELAXED) != 129
+ || f25 (&d) != 1 || __atomic_load_n (&d, __ATOMIC_RELAXED) != 129
+ || cnt != 2)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr61599-1.c b/gcc/testsuite/gcc.target/i386/pr61599-1.c
index 847e736ac97..71b1c2f02dd 100644
--- a/gcc/testsuite/gcc.target/i386/pr61599-1.c
+++ b/gcc/testsuite/gcc.target/i386/pr61599-1.c
@@ -1,7 +1,7 @@
/* PR target/61599 */
-/* { dg-options "-mcmodel=medium -fdata-sections" { target lp64 } } */
-/* { dg-additional-sources pr61599-2.c } */
/* { dg-do run { target lp64 } } */
+/* { dg-additional-sources pr61599-2.c } */
+/* { dg-options "-mcmodel=medium -fdata-sections" } */
char a[1*1024*1024*1024];
char b[1*1024*1024*1024];
diff --git a/gcc/testsuite/gcc.target/i386/pr61599-2.c b/gcc/testsuite/gcc.target/i386/pr61599-2.c
index 22a53a45d00..f0d46020dea 100644
--- a/gcc/testsuite/gcc.target/i386/pr61599-2.c
+++ b/gcc/testsuite/gcc.target/i386/pr61599-2.c
@@ -1,7 +1,8 @@
/* PR target/61599 */
-/* With -mcmodel=medium, all the arrays will be treated as large data. */
-/* { dg-options "-mcmodel=medium -fdata-sections" { target lp64 } } */
/* { dg-do compile { target lp64 } } */
+/* { dg-options "-mcmodel=medium -fdata-sections" { target lp64 } } */
+
+/* With -mcmodel=medium, all the arrays will be treated as large data. */
extern char a[];
extern char b[];
diff --git a/gcc/testsuite/gcc.target/i386/pr66746.c b/gcc/testsuite/gcc.target/i386/pr66746.c
index 3ef77bf9473..d7f6699f132 100644
--- a/gcc/testsuite/gcc.target/i386/pr66746.c
+++ b/gcc/testsuite/gcc.target/i386/pr66746.c
@@ -1,5 +1,6 @@
/* { dg-do compile { target ia32 } } */
/* { dg-options "-O2 -miamcu" } */
+/* { dg-add-options bind_pic_locally } */
/* Defining away "extern" and "__inline" results in all of them being
compiled as proper functions. */
diff --git a/gcc/testsuite/gcc.target/i386/pr70467-1.c b/gcc/testsuite/gcc.target/i386/pr70467-1.c
new file mode 100644
index 00000000000..4e112c88d07
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70467-1.c
@@ -0,0 +1,55 @@
+/* PR rtl-optimization/70467 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-sse" } */
+
+void foo (unsigned long long *);
+
+void
+bar (void)
+{
+ unsigned long long a;
+ foo (&a);
+ a &= 0x7fffffffffffffffULL;
+ foo (&a);
+ a &= 0xffffffff7fffffffULL;
+ foo (&a);
+ a &= 0x7fffffff00000000ULL;
+ foo (&a);
+ a &= 0x000000007fffffffULL;
+ foo (&a);
+ a &= 0x00000000ffffffffULL;
+ foo (&a);
+ a &= 0xffffffff00000000ULL;
+ foo (&a);
+ a |= 0x7fffffffffffffffULL;
+ foo (&a);
+ a |= 0xffffffff7fffffffULL;
+ foo (&a);
+ a |= 0x7fffffff00000000ULL;
+ foo (&a);
+ a |= 0x000000007fffffffULL;
+ foo (&a);
+ a |= 0x00000000ffffffffULL;
+ foo (&a);
+ a |= 0xffffffff00000000ULL;
+ foo (&a);
+ a ^= 0x7fffffffffffffffULL;
+ foo (&a);
+ a ^= 0xffffffff7fffffffULL;
+ foo (&a);
+ a ^= 0x7fffffff00000000ULL;
+ foo (&a);
+ a ^= 0x000000007fffffffULL;
+ foo (&a);
+ a ^= 0x00000000ffffffffULL;
+ foo (&a);
+ a ^= 0xffffffff00000000ULL;
+ foo (&a);
+}
+
+/* { dg-final { scan-assembler-not "andl\[ \t\]*.-1," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "andl\[ \t\]*.0," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "orl\[ \t\]*.-1," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "orl\[ \t\]*.0," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "xorl\[ \t\]*.-1," { target ia32 } } } */
+/* { dg-final { scan-assembler-not "xorl\[ \t\]*.0," { target ia32 } } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr70467-3.c b/gcc/testsuite/gcc.target/i386/pr70467-3.c
new file mode 100644
index 00000000000..4d2a6cfaead
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70467-3.c
@@ -0,0 +1,19 @@
+/* PR rtl-optimization/70467 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+__uint128_t
+foo (__uint128_t x)
+{
+ return x + ((__uint128_t) 123456 << 64);
+}
+
+__uint128_t
+bar (__uint128_t x)
+{
+ return x - ((__uint128_t) 123456 << 64);
+}
+
+/* Make sure there are no unnecessary additions with carry. */
+/* { dg-final { scan-assembler-not "adcq\[^\n\r\]*%" } } */
+/* { dg-final { scan-assembler-not "sbbq\[^\n\r\]*%" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr70467-4.c b/gcc/testsuite/gcc.target/i386/pr70467-4.c
new file mode 100644
index 00000000000..91f9b6f43c9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70467-4.c
@@ -0,0 +1,18 @@
+/* PR rtl-optimization/70467 */
+/* { dg-do compile { target int128 } } */
+/* { dg-options "-O2" } */
+
+__uint128_t
+foo (__uint128_t x)
+{
+ return x + ((__uint128_t) 123456 << 64) + 0x1234567;
+}
+
+__uint128_t
+bar (__uint128_t x)
+{
+ return x - ((__uint128_t) 123456 << 64) + 0x1234567;
+}
+
+/* Make sure the immediates are not loaded into registers first. */
+/* { dg-final { scan-assembler-not "mov\[lq\]\[ \t\]*.\[0-9-\]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/pr70799-1.c b/gcc/testsuite/gcc.target/i386/pr70799-1.c
new file mode 100644
index 00000000000..f4e42fac5a0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70799-1.c
@@ -0,0 +1,41 @@
+/* PR target/pr70799 */
+/* { dg-do compile { target { ia32 } } } */
+/* { dg-options "-O2 -march=slm" } */
+/* { dg-final { scan-assembler "pxor" } } */
+/* { dg-final { scan-assembler "pcmpeqd" } } */
+/* { dg-final { scan-assembler "movdqa\[ \\t\]+.?LC0" } } */
+
+long long a, b, c;
+
+void test1 (void)
+{
+ long long t;
+ if (a)
+ t = 0LL;
+ else
+ t = b;
+ a = c & t;
+ b = c | t;
+}
+
+void test2 (void)
+{
+ long long t;
+ if (a)
+ t = -1LL;
+ else
+ t = b;
+ a = c & t;
+ b = c | t;
+}
+
+void test3 (void)
+{
+ long long t;
+ if (a)
+ t = 0xf0f0f0f0f0f0f0f0LL;
+ else
+ t = b;
+ a = c & t;
+ b = c | t;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70876.c b/gcc/testsuite/gcc.target/i386/pr70876.c
new file mode 100644
index 00000000000..c9bab690b33
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70876.c
@@ -0,0 +1,13 @@
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx -Wno-implicit-function-declaration" } */
+
+void f (char *s1, char *s2)
+{
+ int z = 5;
+
+ struct { char a[z]; } x;
+
+ s1[0] = s2[0];
+
+ foo (x, x);
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr70877.c b/gcc/testsuite/gcc.target/i386/pr70877.c
new file mode 100644
index 00000000000..4269e84daff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr70877.c
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { ! x32 } } } */
+/* { dg-options "-fcheck-pointer-bounds -mmpx" } */
+
+int foo(int);
+
+typedef struct {
+ double d;
+ int a;
+} str_t;
+
+void bar(double d, int i, str_t s)
+{
+ d = ((double (*) (int)) foo) (i); /* { dg-warning "function called through a non-compatible type" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/sse-13.c b/gcc/testsuite/gcc.target/i386/sse-13.c
index 1144e5d068b..5562fbc5d6e 100644
--- a/gcc/testsuite/gcc.target/i386/sse-13.c
+++ b/gcc/testsuite/gcc.target/i386/sse-13.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O2 -Werror-implicit-function-declaration -march=k8 -msse4a -m3dnow -mavx -mavx2 -mfma4 -mxop -maes -mpclmul -mpopcnt -mabm -mlzcnt -mbmi -mbmi2 -mtbm -mlwp -mfsgsbase -mrdrnd -mf16c -mfma -mrtm -mrdseed -mprfchw -madx -mfxsr -mxsaveopt -mavx512f -mavx512er -mavx512cd -mavx512pf -msha -mprefetchwt1 -mxsavec -mxsaves -mclflushopt -mavx512vl -mavx512dq -mavx512bw -mavx512vbmi -mavx512ifma -mclwb -mpcommit -mmwaitx -mclzero -mpku" } */
+/* { dg-add-options bind_pic_locally } */
#include <mm_malloc.h>
diff --git a/gcc/testsuite/gcc.target/i386/strinline.c b/gcc/testsuite/gcc.target/i386/strinline.c
index 2fe67141624..08b38d8296f 100644
--- a/gcc/testsuite/gcc.target/i386/strinline.c
+++ b/gcc/testsuite/gcc.target/i386/strinline.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-require-effective-target fpic } */
+/* { dg-require-effective-target ia32 } */
/* { dg-options "-O2 -fPIC" } */
typedef unsigned int size_t;
char *
@@ -8,7 +9,8 @@ __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
register char *__tmp = __dest;
register unsigned long int __d0, __d1;
__asm__ __volatile__
- ("shrl $1,%3\n\t"
+ (
+ "shrl $1,%3\n\t"
"jz 2f\n"
"1:\n\t"
"movl (%2),%0\n\t"
diff --git a/gcc/testsuite/gcc.target/mips/mips16-attributes.c b/gcc/testsuite/gcc.target/mips/mips16-attributes.c
index 28bb9aae7fa..d90ec66d037 100644
--- a/gcc/testsuite/gcc.target/mips/mips16-attributes.c
+++ b/gcc/testsuite/gcc.target/mips/mips16-attributes.c
@@ -3,6 +3,7 @@
function. */
/* { dg-do run } */
/* { dg-options "(-mips16)" } */
+/* { dg-skip-if "" { *-*-* } { "-mmicromips" } { "" } } */
#include <stdlib.h>
diff --git a/gcc/testsuite/gcc.target/nvptx/abi-vararg-3.c b/gcc/testsuite/gcc.target/nvptx/abi-vararg-3.c
new file mode 100644
index 00000000000..24fd684527d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/abi-vararg-3.c
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-additional-options "-Wno-pedantic -Wno-long-long" } */
+
+/* 64-bit var args should be aligned to 64 bits. */
+
+void Foo (const char *, ...);
+
+void Baz ()
+{
+ Foo ("", 0, 1ll);
+}
+
+/* { dg-final { scan-assembler "st.u64\t\\\[%stack\\+8\\\]," } } */
diff --git a/gcc/testsuite/gcc.target/nvptx/ary-init.c b/gcc/testsuite/gcc.target/nvptx/ary-init.c
index 93235fd30a2..71bcb7b0a03 100644
--- a/gcc/testsuite/gcc.target/nvptx/ary-init.c
+++ b/gcc/testsuite/gcc.target/nvptx/ary-init.c
@@ -1,3 +1,5 @@
+/* { dg-do compile } */
+
/* { dg-additional-options "-Wno-long-long" } */
char ca1[2] = {'a', 'b'};
diff --git a/gcc/testsuite/gcc.target/nvptx/decl.c b/gcc/testsuite/gcc.target/nvptx/decl.c
index 094cdb03fe0..190a64d5679 100644
--- a/gcc/testsuite/gcc.target/nvptx/decl.c
+++ b/gcc/testsuite/gcc.target/nvptx/decl.c
@@ -1,3 +1,4 @@
+/* { dg-do compile } */
static const int __attribute__ ((used)) cst_local = 4;
static int __attribute__ ((used)) glob_local = 5;
diff --git a/gcc/testsuite/gcc.target/nvptx/sincos.c b/gcc/testsuite/gcc.target/nvptx/sincos.c
new file mode 100644
index 00000000000..921ec41e690
--- /dev/null
+++ b/gcc/testsuite/gcc.target/nvptx/sincos.c
@@ -0,0 +1,17 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ffast-math" } */
+
+extern float sinf (float);
+extern float cosf (float);
+
+float
+sincos_add (float x)
+{
+ float s = sinf (x);
+ float c = cosf (x);
+
+ return s + c;
+}
+
+/* { dg-final { scan-assembler-times "sin.approx.f32" 1 } } */
+/* { dg-final { scan-assembler-times "cos.approx.f32" 1 } } */
diff --git a/gcc/testsuite/gcc.target/nvptx/trailing-init.c b/gcc/testsuite/gcc.target/nvptx/trailing-init.c
index 3fa916d0ac2..470ac0059d3 100644
--- a/gcc/testsuite/gcc.target/nvptx/trailing-init.c
+++ b/gcc/testsuite/gcc.target/nvptx/trailing-init.c
@@ -1,3 +1,4 @@
+/* { dg-do compile } */
/* { dg-additional-options "-Wno-pedantic" } */
struct trailing
diff --git a/gcc/testsuite/gcc.target/nvptx/uninit-decl.c b/gcc/testsuite/gcc.target/nvptx/uninit-decl.c
index 65c44f5b0f7..115d7036fb6 100644
--- a/gcc/testsuite/gcc.target/nvptx/uninit-decl.c
+++ b/gcc/testsuite/gcc.target/nvptx/uninit-decl.c
@@ -1,7 +1,21 @@
/* { dg-do compile } */
-int __attribute__ ((used)) common;
-static int __attribute__ ((used)) local;
+int __attribute__ ((common)) common;
+static int local;
+extern int external_decl;
+int external_defn;
+
+int foo ()
+{
+ return common + local + external_decl + external_defn;
+}
+
+void bar (int i)
+{
+ common = local = external_decl = external_defn = i;
+}
/* { dg-final { scan-assembler "\[\n\r\]\[\t \]*.weak .global\[^,\n\r\]*common" } } */
/* { dg-final { scan-assembler "\[\n\r\]\[\t \]*.global\[^,\n\r\]*local" } } */
+/* { dg-final { scan-assembler "\[\n\r\]\[\t \]*.extern .global\[^,\n\r\]*external_decl" } } */
+/* { dg-final { scan-assembler "\[\n\r\]\[\t \]*.visible .global\[^,\n\r\]*external_defn" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/darn-0.c b/gcc/testsuite/gcc.target/powerpc/darn-0.c
new file mode 100644
index 00000000000..ce2e25e22a1
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/darn-0.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power9" } */
+
+/* This test should succeed on both 32- and 64-bit configurations. */
+#include <altivec.h>
+
+int get_random ()
+{
+ return __builtin_darn_32 ();
+}
+
+/* { dg-final { scan-assembler "darn" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/darn-1.c b/gcc/testsuite/gcc.target/powerpc/darn-1.c
new file mode 100644
index 00000000000..d79e5c1b4d9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/darn-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power9" } */
+/* { dg-require-effective-target lp64 } */
+
+#include <altivec.h>
+
+long long get_conditioned_random ()
+{
+ return __builtin_darn ();
+}
+
+/* { dg-final { scan-assembler "darn" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/darn-2.c b/gcc/testsuite/gcc.target/powerpc/darn-2.c
new file mode 100644
index 00000000000..7f47332ec49
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/darn-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-mcpu=power9" } */
+/* { dg-require-effective-target lp64 } */
+
+#include <altivec.h>
+
+long long get_raw_random ()
+{
+ return __builtin_darn_raw ();
+}
+
+/* { dg-final { scan-assembler "darn" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/dform-1.c b/gcc/testsuite/gcc.target/powerpc/dform-1.c
index 37a30d1c92f..12623f20262 100644
--- a/gcc/testsuite/gcc.target/powerpc/dform-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/dform-1.c
@@ -1,7 +1,7 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p9vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
-/* { dg-options "-mcpu=power9 -mpower9-dform -O2" } */
+/* { dg-options "-mcpu=power9 -mpower9-dform -O2 -mlra" } */
#ifndef TYPE
#define TYPE double
diff --git a/gcc/testsuite/gcc.target/powerpc/dform-2.c b/gcc/testsuite/gcc.target/powerpc/dform-2.c
index b4c4199c0b3..86d65b5b1fd 100644
--- a/gcc/testsuite/gcc.target/powerpc/dform-2.c
+++ b/gcc/testsuite/gcc.target/powerpc/dform-2.c
@@ -1,7 +1,7 @@
/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
/* { dg-require-effective-target powerpc_p9vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
-/* { dg-options "-mcpu=power9 -mpower9-dform -O2" } */
+/* { dg-options "-mcpu=power9 -mpower9-dform -O2 -mlra" } */
#ifndef TYPE
#define TYPE float
diff --git a/gcc/testsuite/gcc.target/powerpc/dform-3.c b/gcc/testsuite/gcc.target/powerpc/dform-3.c
new file mode 100644
index 00000000000..b1c481fbf6d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dform-3.c
@@ -0,0 +1,39 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-mcpu=power9 -mpower9-dform -O2 -mlra" } */
+
+#ifndef TYPE
+#define TYPE vector double
+#endif
+
+struct foo {
+ TYPE a, b, c, d;
+};
+
+/* Test whether ISA 3.0 vector d-form instructions are implemented. */
+void
+add (struct foo *p)
+{
+ p->b = p->c + p->d;
+}
+
+/* Make sure we don't use direct moves to get stuff into GPR registers. */
+void
+gpr (struct foo *p)
+{
+ TYPE x = p->c;
+
+ __asm__ (" # reg = %0" : "+r" (x));
+
+ p->b = x;
+}
+
+/* { dg-final { scan-assembler "lxv " } } */
+/* { dg-final { scan-assembler "stxv " } } */
+/* { dg-final { scan-assembler-not "lxvx " } } */
+/* { dg-final { scan-assembler-not "stxvx " } } */
+/* { dg-final { scan-assembler-not "mfvsrd " } } */
+/* { dg-final { scan-assembler-not "mfvsrld " } } */
+/* { dg-final { scan-assembler "l\[dq\] " } } */
+/* { dg-final { scan-assembler "st\[dq\] " } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-complex-1.c b/gcc/testsuite/gcc.target/powerpc/float128-complex-1.c
new file mode 100644
index 00000000000..4e3b3253caf
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-complex-1.c
@@ -0,0 +1,157 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target powerpc_float128_sw_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
+/* { dg-options "-O2 -mcpu=power7 -mfloat128" } */
+
+#ifndef NO_FLOAT
+typedef _Complex float float_complex;
+extern float_complex cfloat1 (void);
+extern float_complex cfloat2 (void);
+
+#define FLOAT_ARG(NAME, OP) ARG_OP(float, float_complex, NAME, OP)
+#define FLOAT_PTR(NAME, OP) PTR_OP(float, float_complex, NAME, OP)
+#define FLOAT_CALL() CALL_OP(float, float_complex, cfloat1, cfloat2)
+
+#else
+#define FLOAT_ARG(NAME, OP)
+#define FLOAT_PTR(NAME, OP)
+#define FLOAT_CALL()
+#endif
+
+#ifndef NO_DOUBLE
+typedef _Complex double double_complex;
+extern double_complex cdouble1 (void);
+extern double_complex cdouble2 (void);
+
+#define DOUBLE_ARG(NAME, OP) ARG_OP(double, double_complex, NAME, OP)
+#define DOUBLE_PTR(NAME, OP) PTR_OP(double, double_complex, NAME, OP)
+#define DOUBLE_CALL() CALL_OP(double, double_complex, cdouble1, cdouble2)
+
+#else
+#define DOUBLE_ARG(NAME, OP)
+#define DOUBLE_PTR(NAME, OP)
+#define DOUBLE_CALL()
+#endif
+
+#ifndef NO_FLOAT128
+#ifdef __VSX__
+typedef _Complex float __attribute__((mode(KC))) float128_complex;
+#else
+typedef _Complex float __attribute__((mode(TC))) float128_complex;
+#endif
+
+extern float128_complex cfloat128_1 (void);
+extern float128_complex cfloat128_2 (void);
+
+#define FLOAT128_ARG(NAME, OP) ARG_OP(float128, float128_complex, NAME, OP)
+#define FLOAT128_PTR(NAME, OP) PTR_OP(float128, float128_complex, NAME, OP)
+#define FLOAT128_CALL() CALL_OP(float128, float128_complex, cfloat128_1, cfloat128_2)
+
+#else
+#define FLOAT128_ARG(NAME, OP)
+#define FLOAT128_PTR(NAME, OP)
+#define FLOAT128_CALL()
+#endif
+
+#ifndef NO_LDOUBLE
+typedef _Complex long double ldouble_complex;
+extern ldouble_complex cldouble1 (void);
+extern ldouble_complex cldouble2 (void);
+
+#define LDOUBLE_ARG(NAME, OP) ARG_OP(ldouble, ldouble_complex, NAME, OP)
+#define LDOUBLE_PTR(NAME, OP) PTR_OP(ldouble, ldouble_complex, NAME, OP)
+#define LDOUBLE_CALL() CALL_OP(ldouble, ldouble_complex, cldouble1, cldouble2)
+
+#else
+#define LDOUBLE_ARG(NAME, OP)
+#define LDOUBLE_PTR(NAME, OP)
+#define LDOUBLE_CALL()
+#endif
+
+
+#define ARG_OP(SUFFIX, TYPE, NAME, OP) \
+TYPE arg_ ## NAME ## _ ## SUFFIX (TYPE a, TYPE b) \
+{ \
+ return a OP b; \
+}
+
+#define PTR_OP(SUFFIX, TYPE, NAME, OP) \
+void ptr_ ## NAME ## _ ## SUFFIX (TYPE *p, TYPE *a, TYPE *b) \
+{ \
+ *p = *a OP *b; \
+}
+
+#define CALL_OP(SUFFIX, TYPE, FUNC1, FUNC2) \
+TYPE call_ ## SUFFIX (void) \
+{ \
+ TYPE value1 = FUNC1 (); \
+ TYPE value2 = FUNC2 (); \
+ return value1 + value2; \
+}
+
+#ifndef NO_ARG
+#ifndef NO_ADD
+FLOAT_ARG (add, +)
+DOUBLE_ARG (add, +)
+FLOAT128_ARG (add, +)
+LDOUBLE_ARG (add, +)
+#endif
+
+#ifndef NO_SUB
+FLOAT_ARG (sub, -)
+DOUBLE_ARG (sub, -)
+FLOAT128_ARG (sub, -)
+LDOUBLE_ARG (sub, -)
+#endif
+
+#ifndef NO_MUL
+FLOAT_ARG (mul, *)
+DOUBLE_ARG (mul, *)
+FLOAT128_ARG (mul, *)
+LDOUBLE_ARG (mul, *)
+#endif
+
+#ifndef NO_DIV
+FLOAT_ARG (div, /)
+DOUBLE_ARG (div, /)
+FLOAT128_ARG (div, /)
+LDOUBLE_ARG (div, /)
+#endif
+#endif
+
+#ifndef NO_PTR
+#ifndef NO_ADD
+FLOAT_PTR (add, +)
+DOUBLE_PTR (add, +)
+FLOAT128_PTR (add, +)
+LDOUBLE_PTR (add, +)
+#endif
+
+#ifndef NO_SUB
+FLOAT_PTR (sub, -)
+DOUBLE_PTR (sub, -)
+FLOAT128_PTR (sub, -)
+LDOUBLE_PTR (sub, -)
+#endif
+
+#ifndef NO_MUL
+FLOAT_PTR (mul, *)
+DOUBLE_PTR (mul, *)
+FLOAT128_PTR (mul, *)
+LDOUBLE_PTR (mul, *)
+#endif
+
+#ifndef NO_DIV
+FLOAT_PTR (div, /)
+DOUBLE_PTR (div, /)
+FLOAT128_PTR (div, /)
+LDOUBLE_PTR (div, /)
+#endif
+#endif
+
+#ifndef NO_CALL
+FLOAT_CALL ()
+DOUBLE_CALL ()
+FLOAT128_CALL ()
+LDOUBLE_CALL ()
+#endif
diff --git a/gcc/testsuite/gcc.target/powerpc/float128-complex-2.c b/gcc/testsuite/gcc.target/powerpc/float128-complex-2.c
new file mode 100644
index 00000000000..06dd8e2f01b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/float128-complex-2.c
@@ -0,0 +1,160 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-require-effective-target powerpc_float128_hw_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-O2 -mcpu=power9 -mfloat128 -mfloat128-hardware" } */
+
+#ifndef NO_FLOAT
+typedef _Complex float float_complex;
+extern float_complex cfloat1 (void);
+extern float_complex cfloat2 (void);
+
+#define FLOAT_ARG(NAME, OP) ARG_OP(float, float_complex, NAME, OP)
+#define FLOAT_PTR(NAME, OP) PTR_OP(float, float_complex, NAME, OP)
+#define FLOAT_CALL() CALL_OP(float, float_complex, cfloat1, cfloat2)
+
+#else
+#define FLOAT_ARG(NAME, OP)
+#define FLOAT_PTR(NAME, OP)
+#define FLOAT_CALL()
+#endif
+
+#ifndef NO_DOUBLE
+typedef _Complex double double_complex;
+extern double_complex cdouble1 (void);
+extern double_complex cdouble2 (void);
+
+#define DOUBLE_ARG(NAME, OP) ARG_OP(double, double_complex, NAME, OP)
+#define DOUBLE_PTR(NAME, OP) PTR_OP(double, double_complex, NAME, OP)
+#define DOUBLE_CALL() CALL_OP(double, double_complex, cdouble1, cdouble2)
+
+#else
+#define DOUBLE_ARG(NAME, OP)
+#define DOUBLE_PTR(NAME, OP)
+#define DOUBLE_CALL()
+#endif
+
+#ifndef NO_FLOAT128
+#ifdef __VSX__
+typedef _Complex float __attribute__((mode(KC))) float128_complex;
+#else
+typedef _Complex float __attribute__((mode(TC))) float128_complex;
+#endif
+
+extern float128_complex cfloat128_1 (void);
+extern float128_complex cfloat128_2 (void);
+
+#define FLOAT128_ARG(NAME, OP) ARG_OP(float128, float128_complex, NAME, OP)
+#define FLOAT128_PTR(NAME, OP) PTR_OP(float128, float128_complex, NAME, OP)
+#define FLOAT128_CALL() CALL_OP(float128, float128_complex, cfloat128_1, cfloat128_2)
+
+#else
+#define FLOAT128_ARG(NAME, OP)
+#define FLOAT128_PTR(NAME, OP)
+#define FLOAT128_CALL()
+#endif
+
+#ifndef NO_LDOUBLE
+typedef _Complex long double ldouble_complex;
+extern ldouble_complex cldouble1 (void);
+extern ldouble_complex cldouble2 (void);
+
+#define LDOUBLE_ARG(NAME, OP) ARG_OP(ldouble, ldouble_complex, NAME, OP)
+#define LDOUBLE_PTR(NAME, OP) PTR_OP(ldouble, ldouble_complex, NAME, OP)
+#define LDOUBLE_CALL() CALL_OP(ldouble, ldouble_complex, cldouble1, cldouble2)
+
+#else
+#define LDOUBLE_ARG(NAME, OP)
+#define LDOUBLE_PTR(NAME, OP)
+#define LDOUBLE_CALL()
+#endif
+
+
+#define ARG_OP(SUFFIX, TYPE, NAME, OP) \
+TYPE arg_ ## NAME ## _ ## SUFFIX (TYPE a, TYPE b) \
+{ \
+ return a OP b; \
+}
+
+#define PTR_OP(SUFFIX, TYPE, NAME, OP) \
+void ptr_ ## NAME ## _ ## SUFFIX (TYPE *p, TYPE *a, TYPE *b) \
+{ \
+ *p = *a OP *b; \
+}
+
+#define CALL_OP(SUFFIX, TYPE, FUNC1, FUNC2) \
+TYPE call_ ## SUFFIX (void) \
+{ \
+ TYPE value1 = FUNC1 (); \
+ TYPE value2 = FUNC2 (); \
+ return value1 + value2; \
+}
+
+#ifndef NO_ARG
+#ifndef NO_ADD
+FLOAT_ARG (add, +)
+DOUBLE_ARG (add, +)
+FLOAT128_ARG (add, +)
+LDOUBLE_ARG (add, +)
+#endif
+
+#ifndef NO_SUB
+FLOAT_ARG (sub, -)
+DOUBLE_ARG (sub, -)
+FLOAT128_ARG (sub, -)
+LDOUBLE_ARG (sub, -)
+#endif
+
+#ifndef NO_MUL
+FLOAT_ARG (mul, *)
+DOUBLE_ARG (mul, *)
+FLOAT128_ARG (mul, *)
+LDOUBLE_ARG (mul, *)
+#endif
+
+#ifndef NO_DIV
+FLOAT_ARG (div, /)
+DOUBLE_ARG (div, /)
+FLOAT128_ARG (div, /)
+LDOUBLE_ARG (div, /)
+#endif
+#endif
+
+#ifndef NO_PTR
+#ifndef NO_ADD
+FLOAT_PTR (add, +)
+DOUBLE_PTR (add, +)
+FLOAT128_PTR (add, +)
+LDOUBLE_PTR (add, +)
+#endif
+
+#ifndef NO_SUB
+FLOAT_PTR (sub, -)
+DOUBLE_PTR (sub, -)
+FLOAT128_PTR (sub, -)
+LDOUBLE_PTR (sub, -)
+#endif
+
+#ifndef NO_MUL
+FLOAT_PTR (mul, *)
+DOUBLE_PTR (mul, *)
+FLOAT128_PTR (mul, *)
+LDOUBLE_PTR (mul, *)
+#endif
+
+#ifndef NO_DIV
+FLOAT_PTR (div, /)
+DOUBLE_PTR (div, /)
+FLOAT128_PTR (div, /)
+LDOUBLE_PTR (div, /)
+#endif
+#endif
+
+#ifndef NO_CALL
+FLOAT_CALL ()
+DOUBLE_CALL ()
+FLOAT128_CALL ()
+LDOUBLE_CALL ()
+#endif
+
+/* { dg-final { scan-assembler "xsaddqp" } } */
+/* { dg-final { scan-assembler "xssubqp" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p8vector-int128-1.c b/gcc/testsuite/gcc.target/powerpc/p8vector-int128-1.c
index 31e07dd2b41..5ba772f5301 100644
--- a/gcc/testsuite/gcc.target/powerpc/p8vector-int128-1.c
+++ b/gcc/testsuite/gcc.target/powerpc/p8vector-int128-1.c
@@ -2,7 +2,7 @@
/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
-/* { dg-options "-mcpu=power8 -O3 -mvsx-timode" } */
+/* { dg-options "-mcpu=power8 -O3 -mvsx-timode -mlra" } */
#include <altivec.h>
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-splat-1.c b/gcc/testsuite/gcc.target/powerpc/p9-splat-1.c
new file mode 100644
index 00000000000..13b72872d74
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-splat-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-mcpu=power9 -O2" } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+
+#include <altivec.h>
+
+vector int
+foo_r (int a)
+{
+ return (vector int) { a, a, a, a }; /* mtvsrws */
+}
+
+vector int
+foo_r2 (int a)
+{
+ return vec_splats (a); /* mtvsrws */
+}
+
+vector int
+foo_p (int *a)
+{
+ return (vector int) { *a, *a, *a, *a }; /* lxvwsx */
+}
+
+/* { dg-final { scan-assembler-times "mtvsrws" 2 } } */
+/* { dg-final { scan-assembler-times "lxvwsx" 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-splat-2.c b/gcc/testsuite/gcc.target/powerpc/p9-splat-2.c
new file mode 100644
index 00000000000..2468e92dddb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-splat-2.c
@@ -0,0 +1,38 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-mcpu=power9 -O2" } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+
+#include <altivec.h>
+
+vector float
+foo_r (float a)
+{
+ return (vector float) { a, a, a, a }; /* xscvdpspn/xxspltw */
+}
+
+vector float
+foo_r2 (float a)
+{
+ return vec_splats (a); /* xscvdpspn/xxspltw */
+}
+
+vector float
+foo_g (float *a)
+{
+ float f = *a;
+
+ __asm__ (" # %0" : "+r" (f));
+ return (vector float) { f, f, f, f }; /* mtvsrws */
+}
+
+vector float
+foo_p (float *a)
+{
+ return (vector float) { *a, *a, *a, *a }; /* lxvwsx */
+}
+
+/* { dg-final { scan-assembler-times "xscvdpspn" 2 } } */
+/* { dg-final { scan-assembler-times "xxspltw" 2 } } */
+/* { dg-final { scan-assembler-times "mtvsrws" 1 } } */
+/* { dg-final { scan-assembler-times "lxvwsx" 1 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/p9-splat-3.c b/gcc/testsuite/gcc.target/powerpc/p9-splat-3.c
new file mode 100644
index 00000000000..8a121da2572
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/p9-splat-3.c
@@ -0,0 +1,61 @@
+/* { dg-do compile { target { powerpc64le-*-* } } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */
+/* { dg-options "-mcpu=power9 -O2" } */
+/* { dg-require-effective-target powerpc_p9vector_ok } */
+
+#include <altivec.h>
+
+typedef vector signed char v16qi_t;
+typedef vector short v8hi_t;
+typedef vector int v4si_t;
+typedef vector long long v2di_t;
+
+void v16qi_0a (v16qi_t *p) { *p = (v16qi_t) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; }
+void v8hi_0a (v8hi_t *p) { *p = (v8hi_t) { 0, 0, 0, 0, 0, 0, 0, 0 }; }
+void v4si_0a (v4si_t *p) { *p = (v4si_t) { 0, 0, 0, 0 }; }
+void v2di_0a (v2di_t *p) { *p = (v2di_t) { 0, 0 }; }
+
+void v16qi_0b (v16qi_t *p) { *p = (v16qi_t) vec_splats ((signed char)0); }
+void v8hi_0b (v8hi_t *p) { *p = (v8hi_t) vec_splats ((short)0); }
+void v4si_0b (v4si_t *p) { *p = (v4si_t) vec_splats ((int)0); }
+void v2di_0b (v2di_t *p) { *p = (v2di_t) vec_splats ((long long)0); }
+
+void v16qi_m1a (v16qi_t *p) { *p = (v16qi_t) { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; }
+void v8hi_m1a (v8hi_t *p) { *p = (v8hi_t) { -1, -1, -1, -1, -1, -1, -1, -1 }; }
+void v4si_m1a (v4si_t *p) { *p = (v4si_t) { -1, -1, -1, -1 }; }
+void v2di_m1a (v2di_t *p) { *p = (v2di_t) { -1, -1 }; }
+
+void v16qi_m1b (v16qi_t *p) { *p = (v16qi_t) vec_splats ((signed char)-1); }
+void v8hi_m1b (v8hi_t *p) { *p = (v8hi_t) vec_splats ((short)-1); }
+void v4si_m1b (v4si_t *p) { *p = (v4si_t) vec_splats ((int)-1); }
+void v2di_m1b (v2di_t *p) { *p = (v2di_t) vec_splats ((long long)-1); }
+
+void v16qi_5a (v16qi_t *p) { *p = (v16qi_t) { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 }; }
+void v8hi_5a (v8hi_t *p) { *p = (v8hi_t) { 5, 5, 5, 5, 5, 5, 5, 5 }; }
+void v4si_5a (v4si_t *p) { *p = (v4si_t) { 5, 5, 5, 5 }; }
+void v2di_5a (v2di_t *p) { *p = (v2di_t) { 5, 5 }; }
+
+void v16qi_5b (v16qi_t *p) { *p = (v16qi_t) vec_splats ((signed char)5); }
+void v8hi_5b (v8hi_t *p) { *p = (v8hi_t) vec_splats ((short)5); }
+void v4si_5b (v4si_t *p) { *p = (v4si_t) vec_splats ((int)5); }
+void v2di_5b (v2di_t *p) { *p = (v2di_t) vec_splats ((long long)5); }
+
+void v16qi_33a (v16qi_t *p) { *p = (v16qi_t) { 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33 }; }
+void v8hi_33a (v8hi_t *p) { *p = (v8hi_t) { 33, 33, 33, 33, 33, 33, 33, 33 }; }
+void v4si_33a (v4si_t *p) { *p = (v4si_t) { 33, 33, 33, 33 }; }
+void v2di_33a (v2di_t *p) { *p = (v2di_t) { 33, 33 }; }
+
+void v16qi_33b (v16qi_t *p) { *p = (v16qi_t) vec_splats ((signed char)33); }
+void v8hi_33b (v8hi_t *p) { *p = (v8hi_t) vec_splats ((short)33); }
+void v4si_33b (v4si_t *p) { *p = (v4si_t) vec_splats ((int)33); }
+void v2di_33b (v2di_t *p) { *p = (v2di_t) vec_splats ((long long)33); }
+
+/* { dg-final { scan-assembler "xxspltib" } } */
+/* { dg-final { scan-assembler "vextsb2d" } } */
+/* { dg-final { scan-assembler "vextsb2w" } } */
+/* { dg-final { scan-assembler "vupk\[hl\]sb" } } */
+/* { dg-final { scan-assembler-not "lxvd2x" } } */
+/* { dg-final { scan-assembler-not "lxvw4x" } } */
+/* { dg-final { scan-assembler-not "lxv " } } */
+/* { dg-final { scan-assembler-not "lxvx" } } */
+/* { dg-final { scan-assembler-not "lvx" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr47755.c b/gcc/testsuite/gcc.target/powerpc/pr47755.c
index 8feef291e56..d5feecac691 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr47755.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr47755.c
@@ -3,7 +3,7 @@
/* { dg-require-effective-target powerpc_vsx_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power7" } } */
/* { dg-options "-O3 -mcpu=power7" } */
-/* { dg-final { scan-assembler "xxlxor" } } */
+/* { dg-final { scan-assembler "xxlxor\|vspltis\[bhw\]" } } */
/* { dg-final { scan-assembler-not "lxvd2x" } } */
/* { dg-final { scan-assembler-not "lxvw4x" } } */
/* { dg-final { scan-assembler-not "lvx" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr68805.c b/gcc/testsuite/gcc.target/powerpc/pr68805.c
index f4454a9e2d2..5510811107d 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr68805.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr68805.c
@@ -1,6 +1,6 @@
/* { dg-do compile { target powerpc64le-*-* } } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
-/* { dg-options "-O2 -mvsx-timode -mcpu=power8" } */
+/* { dg-options "-O2 -mvsx-timode -mcpu=power8 -mlra" } */
typedef struct bar {
void *a;
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70866.c b/gcc/testsuite/gcc.target/powerpc/pr70866.c
new file mode 100644
index 00000000000..25fd05a1deb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr70866.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-ffixed-cr2 -ffixed-cr3 -ffixed-cr4" } */
+
+#define SET_CR(R,V) __asm__ __volatile__ ("mtcrf %0,%1" : : "n" (1<<(7-R)), "r" (V<<(4*(7-R))) : "cr" #R)
+
+void foo (void)
+{
+ SET_CR (2, 7);
+ SET_CR (3, 8);
+ SET_CR (4, 9);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pr70963.c b/gcc/testsuite/gcc.target/powerpc/pr70963.c
new file mode 100644
index 00000000000..128ebd9f09f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr70963.c
@@ -0,0 +1,44 @@
+/* { dg-do run { target powerpc64*-*-* } } */
+/* { dg-require-effective-target p8vector_hw } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8" } */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <altivec.h>
+
+static int failed;
+static void test (void);
+
+static void check (int result, const char *name)
+{
+ if (!result)
+ {
+ failed++;
+ printf ("fail %s\n", name);
+ }
+}
+
+int main (void)
+{
+ test ();
+ if (failed)
+ abort ();
+ return 0;
+}
+
+vector double x = { 81.0, 76.0 };
+vector long long y = { 81, 76 };
+
+static void test()
+{
+ vector long long a = vec_cts (x, 0);
+ vector double b = vec_ctf (a, 0);
+ vector long long c = __builtin_vsx_xvcvdpuxds_scale (x, 0);
+ vector double d = vec_ctf (c, 0);
+ check (vec_all_eq (a, y), "vec_cts");
+ check (vec_all_eq (b, x), "vec_ctf");
+ check (vec_all_eq (c, y), "xvcvdpuxds");
+ check (vec_all_eq (d, x), "vec_ctf unsigned");
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/savres.c b/gcc/testsuite/gcc.target/powerpc/savres.c
index f10c99a4b93..f724f308094 100644
--- a/gcc/testsuite/gcc.target/powerpc/savres.c
+++ b/gcc/testsuite/gcc.target/powerpc/savres.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-options "-fno-inline -fomit-frame-pointer" } */
+/* { dg-options "-fno-inline -fomit-frame-pointer -fno-rename-registers" } */
/* { dg-additional-options "-mdynamic-no-pic" { target *-*-darwin* } } */
/* -fno-inline -maltivec -m32/-m64 -mmultiple/no-multiple -Os/-O2. */
@@ -10,6 +10,13 @@
#define SET_GPR(R,V) SET (long, R, V)
#define SET_FPR(R,V) SET (double, R, V)
#define SET_VR(R,V) SET (__attribute__ ((vector_size (16))) int, R, V)
+/* There doesn't seem to be a way of letting gcc know that cr2, cr3
+ and cr4 are being used, and therefore should not be touched by
+ gcc. Unlike gpr, fpr and vr we can't do something like
+ register __attribute__ ((__mode__ ("__CC__"))) int cr2 __asm__ ("cr2");
+ This makes the test somewhat fragile, dependent on gcc not using
+ any of cr2, cr3 and cr4 in main(), and is why -fno-rename-registers
+ is required. */
#define SET_CR(R,V) __asm__ __volatile__ ("mtcrf %0,%1" : : "n" (1<<(7-R)), "r" (V<<(4*(7-R))) : "cr" #R)
#define TRASH_GPR(R) SET_GPR (R, 0)
#define TRASH_FPR(R) SET_FPR (R, 0)
@@ -441,6 +448,16 @@ void s_r (void)
__asm __volatile ("#%0" : "=m" (a) : : "r30", "r31");
}
+void s_r31 (void)
+{
+ char a[33];
+#ifndef NO_BODY
+ TRASH_GPR (r31);
+ __asm__ __volatile__ ("#%0" : : "r" (r31));
+#endif
+ __asm __volatile ("#%0" : "=m" (a) : : "r31");
+}
+
void s_c (void)
{
char a[33];
@@ -1053,7 +1070,18 @@ void ws_0 (void)
abort ();
}
-int main (void)
+/* We'd like to compile main with
+ __attribute__ ((__optimize__ ("fixed-cr2,fixed-cr3,fixed-cr4")))
+ but that doesn't do anything currently. Obviously we don't want to
+ compile the whole file with -ffixed-cr2 -ffixed-cr3 -ffixed-cr4 as
+ that would also tell gcc not to save/restore cr, and we're trying
+ to check that the above functions do save/restore cr.
+ __attribute__ ((__optimize__ ("no-rename-registers,omit-frame-pointer")))
+ works, but it seems odd to need omit-frame-pointer and raises the
+ question of whether darwin would need -mdynamic-no-pic.
+ So for now use -fno-rename-registers over the whole test. */
+int
+main (void)
{
INIT_REGS;
USE_ALL_CR;
@@ -1140,6 +1168,8 @@ int main (void)
VERIFY_REGS;
s_r ();
VERIFY_REGS;
+ s_r31 ();
+ VERIFY_REGS;
s_c ();
VERIFY_REGS;
s_0 ();
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-adde-int128.c b/gcc/testsuite/gcc.target/powerpc/vec-adde-int128.c
index f78622f11f2..4f951a993db 100644
--- a/gcc/testsuite/gcc.target/powerpc/vec-adde-int128.c
+++ b/gcc/testsuite/gcc.target/powerpc/vec-adde-int128.c
@@ -1,7 +1,9 @@
-/* { dg-do run { target { powerpc64-*-* } } } */
+/* { dg-do run { target { powerpc64*-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
/* { dg-options "-mcpu=power8 -O3" } */
+
/* Test that the vec_adde builtin works as expected. */
#include "altivec.h"
@@ -20,38 +22,43 @@ STYPE expected_##NAMESUFFIX[N]; \
\
__attribute__((noinline)) void vector_tests_##NAMESUFFIX () \
{ \
- int i; \
vector STYPE v1, v2, v3, tmp; \
- for (i = 0; i < N; i+=16/sizeof(STYPE)) { \
- /* result=addend1+addend2+(carry & 0x1) */ \
- v1 = (vector STYPE) { addend1_##NAMESUFFIX[i] }; \
- v2 = (vector STYPE) { addend2_##NAMESUFFIX[i] }; \
- v3 = (vector STYPE) { carry_##NAMESUFFIX[i] }; \
+ int i; \
+ for (i = 0; i < N; i+=16/sizeof (STYPE)) \
+ { \
+ /* result=addend1+addend2+(carry & 0x1). */ \
+ v1 = (vector STYPE) { addend1_##NAMESUFFIX[i] }; \
+ v2 = (vector STYPE) { addend2_##NAMESUFFIX[i] }; \
+ v3 = (vector STYPE) { carry_##NAMESUFFIX[i] }; \
\
- tmp = vec_adde (v1, v2, v3); \
- result_##NAMESUFFIX[i] = tmp[0]; \
- } \
+ tmp = vec_adde (v1, v2, v3); \
+ result_##NAMESUFFIX[i] = tmp[0]; \
+ } \
} \
\
__attribute__((noinline)) void init_##NAMESUFFIX () \
{ \
int i; \
- for (i = 0; i < N; ++i) { \
- result_##NAMESUFFIX[i] = 0; \
- addend1_##NAMESUFFIX[i] = 1; \
- addend2_##NAMESUFFIX[i] = 2; \
- carry_##NAMESUFFIX[i] = (i%12); \
- expected_##NAMESUFFIX[i] = addend1_##NAMESUFFIX[i] + \
- addend2_##NAMESUFFIX[i] + (carry_##NAMESUFFIX[i] & 0x1); \
- } \
+ for (i = 0; i < N; ++i) \
+ { \
+ result_##NAMESUFFIX[i] = 0; \
+ addend1_##NAMESUFFIX[i] = 1; \
+ addend2_##NAMESUFFIX[i] = 2; \
+ carry_##NAMESUFFIX[i] = (i%12); \
+ expected_##NAMESUFFIX[i] = addend1_##NAMESUFFIX[i] + \
+ addend2_##NAMESUFFIX[i] + \
+ (carry_##NAMESUFFIX[i] & 0x1); \
+ } \
} \
\
__attribute__((noinline)) void verify_results_##NAMESUFFIX () \
{ \
- for (int i = 0; i < N; ++i) { \
- if (result_##NAMESUFFIX[i] != expected_##NAMESUFFIX[i]) \
- abort(); \
- } \
+ int i; \
+ for (i = 0; i < N; ++i) \
+ { \
+ if (result_##NAMESUFFIX[i] != expected_##NAMESUFFIX[i]) \
+ abort (); \
+ } \
}
@@ -63,13 +70,13 @@ __attribute__((noinline)) void verify_results_##NAMESUFFIX () \
}
-define_test_functions(signed __int128, si128);
-define_test_functions(unsigned __int128, ui128);
+define_test_functions (signed __int128, si128);
+define_test_functions (unsigned __int128, ui128);
int main ()
{
- execute_test_functions(signed __int128, si128);
- execute_test_functions(unsigned __int128, ui128);
+ execute_test_functions (signed __int128, si128);
+ execute_test_functions (unsigned __int128, ui128);
return 0;
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-adde.c b/gcc/testsuite/gcc.target/powerpc/vec-adde.c
index b7d5b44b7a7..a235a1c987d 100644
--- a/gcc/testsuite/gcc.target/powerpc/vec-adde.c
+++ b/gcc/testsuite/gcc.target/powerpc/vec-adde.c
@@ -1,6 +1,6 @@
-/* { dg-do run { target { powerpc64-*-* } } } */
-/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
-/* { dg-options "-mcpu=power8 -O3" } */
+/* { dg-do run { target { powerpc64*-*-* } } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mvsx -O3" } */
/* Test that the vec_adde builtin works as expected. */
@@ -20,38 +20,43 @@ STYPE expected_##NAMESUFFIX[N]; \
\
__attribute__((noinline)) void vector_tests_##NAMESUFFIX () \
{ \
- int i; \
vector STYPE v1, v2, v3, tmp; \
- for (i = 0; i < N; i+=16/sizeof(STYPE)) { \
- /* result=addend1+addend2+(carry & 0x1) */ \
- v1 = vec_vsx_ld (0, &addend1_##NAMESUFFIX[i]); \
- v2 = vec_vsx_ld (0, &addend2_##NAMESUFFIX[i]); \
- v3 = vec_vsx_ld (0, &carry_##NAMESUFFIX[i]); \
+ int i; \
+ for (i = 0; i < N; i+=16/sizeof (STYPE)) \
+ { \
+ /* result=addend1+addend2+(carry & 0x1). */ \
+ v1 = vec_vsx_ld (0, &addend1_##NAMESUFFIX[i]); \
+ v2 = vec_vsx_ld (0, &addend2_##NAMESUFFIX[i]); \
+ v3 = vec_vsx_ld (0, &carry_##NAMESUFFIX[i]); \
\
- tmp = vec_adde (v1, v2, v3); \
- vec_vsx_st (tmp, 0, &result_##NAMESUFFIX[i]); \
- } \
+ tmp = vec_adde (v1, v2, v3); \
+ vec_vsx_st (tmp, 0, &result_##NAMESUFFIX[i]); \
+ } \
} \
\
__attribute__((noinline)) void init_##NAMESUFFIX () \
{ \
int i; \
- for (i = 0; i < N; ++i) { \
- result_##NAMESUFFIX[i] = 0; \
- addend1_##NAMESUFFIX[i] = 1; \
- addend2_##NAMESUFFIX[i] = 2; \
- carry_##NAMESUFFIX[i] = (i%12); \
- expected_##NAMESUFFIX[i] = addend1_##NAMESUFFIX[i] + \
- addend2_##NAMESUFFIX[i] + (carry_##NAMESUFFIX[i] & 0x1); \
- } \
+ for (i = 0; i < N; ++i) \
+ { \
+ result_##NAMESUFFIX[i] = 0; \
+ addend1_##NAMESUFFIX[i] = 1; \
+ addend2_##NAMESUFFIX[i] = 2; \
+ carry_##NAMESUFFIX[i] = (i%12); \
+ expected_##NAMESUFFIX[i] = addend1_##NAMESUFFIX[i] + \
+ addend2_##NAMESUFFIX[i] + \
+ (carry_##NAMESUFFIX[i] & 0x1); \
+ } \
} \
\
__attribute__((noinline)) void verify_results_##NAMESUFFIX () \
{ \
- for (int i = 0; i < N; ++i) { \
- if (result_##NAMESUFFIX[i] != expected_##NAMESUFFIX[i]) \
- abort(); \
- } \
+ int i; \
+ for (i = 0; i < N; ++i) \
+ { \
+ if (result_##NAMESUFFIX[i] != expected_##NAMESUFFIX[i]) \
+ abort (); \
+ } \
}
@@ -63,13 +68,13 @@ __attribute__((noinline)) void verify_results_##NAMESUFFIX () \
}
-define_test_functions(signed int, si);
-define_test_functions(unsigned int, ui);
+define_test_functions (signed int, si);
+define_test_functions (unsigned int, ui);
int main ()
{
- execute_test_functions(signed int, si);
- execute_test_functions(unsigned int, ui);
+ execute_test_functions (signed int, si);
+ execute_test_functions (unsigned int, ui);
return 0;
}
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-addec-int128.c b/gcc/testsuite/gcc.target/powerpc/vec-addec-int128.c
new file mode 100644
index 00000000000..f95143a7e0a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-addec-int128.c
@@ -0,0 +1,123 @@
+/* { dg-do run { target { powerpc64*-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -O3" } */
+
+/* Test that the vec_addec builtin works as expected. */
+
+#include "altivec.h"
+
+#define N 4096
+
+void abort ();
+
+#define define_test_functions(STYPE, NAMESUFFIX) \
+\
+STYPE result_##NAMESUFFIX[N]; \
+STYPE addend1_##NAMESUFFIX[N]; \
+STYPE addend2_##NAMESUFFIX[N]; \
+STYPE carry_##NAMESUFFIX[N]; \
+STYPE expected_##NAMESUFFIX[N]; \
+\
+__attribute__((noinline)) void vector_tests_##NAMESUFFIX () \
+{ \
+ vector STYPE v1, v2, v3, tmp; \
+ int i; \
+ for (i = 0; i < N; i+=16/sizeof (STYPE)) \
+ { \
+ /* result=carry of addend1+addend2+(carry & 0x1). */ \
+ v1 = (vector STYPE) { addend1_##NAMESUFFIX[i] }; \
+ v2 = (vector STYPE) { addend2_##NAMESUFFIX[i] }; \
+ v3 = (vector STYPE) { carry_##NAMESUFFIX[i] }; \
+\
+ tmp = vec_addec (v1, v2, v3); \
+ result_##NAMESUFFIX[i] = tmp[0]; \
+ } \
+} \
+\
+__attribute__((noinline)) void init_##NAMESUFFIX () \
+{ \
+ int i; \
+ for (i = 0; i < N; ++i) \
+ { \
+ result_##NAMESUFFIX[i] = 0; \
+ if (i%6 == 0) \
+ { \
+ addend1_##NAMESUFFIX[i] = ((__int128)0xffffffffffffffff << 64); \
+ addend2_##NAMESUFFIX[i] = 0xfffffffffffffffe; \
+ carry_##NAMESUFFIX[i] = 1; \
+ expected_##NAMESUFFIX[i] = 0; \
+ } \
+ else if (i%6 == 1) \
+ { \
+ addend1_##NAMESUFFIX[i] = ((__int128)0xffffffffffffffff << 64) + \
+ 0xffffffffffffffff; \
+ addend2_##NAMESUFFIX[i] = 1; \
+ carry_##NAMESUFFIX[i] = 0; \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ else if (i%6 == 2) \
+ { \
+ addend1_##NAMESUFFIX[i] = ((__int128)0xffffffffffffffff << 64) + \
+ 0xffffffffffffffff; \
+ addend2_##NAMESUFFIX[i] = 0; \
+ carry_##NAMESUFFIX[i] = 3; /* 3 should work like 1 here. */ \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ else if (i%6 == 3) \
+ { \
+ addend1_##NAMESUFFIX[i] = 1; \
+ addend2_##NAMESUFFIX[i] = ((__int128)0xffffffffffffffff << 64) + \
+ 0xffffffffffffffff; \
+ carry_##NAMESUFFIX[i] = 2; /* 2 should work like 0 here. */ \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ else if (i%6 == 4) \
+ { \
+ addend1_##NAMESUFFIX[i] = 0; \
+ addend2_##NAMESUFFIX[i] = ((__int128)0xffffffffffffffff << 64) + \
+ 0xffffffffffffffff; \
+ carry_##NAMESUFFIX[i] = 1; \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ else if (i%6 == 5) \
+ { \
+ addend1_##NAMESUFFIX[i] = ((__int128)0xffffffffffffffff << 64); \
+ addend2_##NAMESUFFIX[i] = 0xffffffffffffffff; \
+ carry_##NAMESUFFIX[i] = 1; \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ } \
+} \
+\
+__attribute__((noinline)) void verify_results_##NAMESUFFIX () \
+{ \
+ int i; \
+ for (i = 0; i < N; ++i) \
+ { \
+ if (result_##NAMESUFFIX[i] != expected_##NAMESUFFIX[i]) \
+ abort (); \
+ } \
+}
+
+
+#define execute_test_functions(STYPE, NAMESUFFIX) \
+{ \
+ init_##NAMESUFFIX (); \
+ vector_tests_##NAMESUFFIX (); \
+ verify_results_##NAMESUFFIX (); \
+}
+
+
+define_test_functions (signed __int128, si128);
+define_test_functions (unsigned __int128, ui128);
+
+int main ()
+{
+ execute_test_functions (signed __int128, si128);
+ execute_test_functions (unsigned __int128, ui128);
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.target/powerpc/vec-addec.c b/gcc/testsuite/gcc.target/powerpc/vec-addec.c
new file mode 100644
index 00000000000..53bd41f4b91
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/vec-addec.c
@@ -0,0 +1,119 @@
+/* { dg-do run { target { powerpc64*-*-* } } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */
+/* { dg-options "-mcpu=power8 -O3" } */
+
+/* Test that the vec_addec builtin works as expected. */
+
+#include "altivec.h"
+
+#define N 4096
+
+void abort ();
+
+#define define_test_functions(STYPE, NAMESUFFIX) \
+\
+STYPE result_##NAMESUFFIX[N]; \
+STYPE addend1_##NAMESUFFIX[N]; \
+STYPE addend2_##NAMESUFFIX[N]; \
+STYPE carry_##NAMESUFFIX[N]; \
+STYPE expected_##NAMESUFFIX[N]; \
+\
+__attribute__((noinline)) void vector_tests_##NAMESUFFIX () \
+{ \
+ vector STYPE v1, v2, v3, tmp; \
+ int i; \
+ for (i = 0; i < N; i+=16/sizeof (STYPE)) \
+ { \
+ /* result=carry of addend1+addend2+(carry & 0x1). */ \
+ v1 = vec_vsx_ld (0, &addend1_##NAMESUFFIX[i]); \
+ v2 = vec_vsx_ld (0, &addend2_##NAMESUFFIX[i]); \
+ v3 = vec_vsx_ld (0, &carry_##NAMESUFFIX[i]); \
+\
+ tmp = vec_addec (v1, v2, v3); \
+ vec_vsx_st (tmp, 0, &result_##NAMESUFFIX[i]); \
+ } \
+} \
+\
+__attribute__((noinline)) void init_##NAMESUFFIX () \
+{ \
+ int i; \
+ for (i = 0; i < N; ++i) \
+ { \
+ result_##NAMESUFFIX[i] = 0; \
+ if (i%6 == 0) \
+ { \
+ addend1_##NAMESUFFIX[i] = 0xfffffffd; \
+ addend2_##NAMESUFFIX[i] = 1; \
+ carry_##NAMESUFFIX[i] = 1; \
+ expected_##NAMESUFFIX[i] = 0; \
+ } \
+ else if (i%6 == 1) \
+ { \
+ addend1_##NAMESUFFIX[i] = 0xffffffff; \
+ addend2_##NAMESUFFIX[i] = 1; \
+ carry_##NAMESUFFIX[i] = 0; \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ else if (i%6 == 2) \
+ { \
+ addend1_##NAMESUFFIX[i] = 0xffffffff; \
+ addend2_##NAMESUFFIX[i] = 0; \
+ carry_##NAMESUFFIX[i] = 3; /* 3 should work like 1 here. */ \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ else if (i%6 == 3) \
+ { \
+ addend1_##NAMESUFFIX[i] = 1; \
+ addend2_##NAMESUFFIX[i] = 0xffffffff; \
+ carry_##NAMESUFFIX[i] = 2; /* 2 should work like 0 here. */ \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ else if (i%6 == 4) \
+ { \
+ addend1_##NAMESUFFIX[i] = 0; \
+ addend2_##NAMESUFFIX[i] = 0xffffffff; \
+ carry_##NAMESUFFIX[i] = 1; \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ else if (i%6 == 5) \
+ { \
+ addend1_##NAMESUFFIX[i] = 0xffff0000; \
+ addend2_##NAMESUFFIX[i] = 0x0000ffff; \
+ carry_##NAMESUFFIX[i] = 1; \
+ expected_##NAMESUFFIX[i] = 1; \
+ } \
+ } \
+} \
+\
+__attribute__((noinline)) void verify_results_##NAMESUFFIX () \
+{ \
+ int i; \
+ for (i = 0; i < N; ++i) \
+ { \
+ if (result_##NAMESUFFIX[i] != expected_##NAMESUFFIX[i]) \
+ abort (); \
+ } \
+}
+
+
+#define execute_test_functions(STYPE, NAMESUFFIX) \
+{ \
+ init_##NAMESUFFIX (); \
+ vector_tests_##NAMESUFFIX (); \
+ verify_results_##NAMESUFFIX (); \
+}
+
+
+define_test_functions (signed int, si);
+define_test_functions (unsigned int, ui);
+
+int main ()
+{
+ execute_test_functions (signed int, si);
+ execute_test_functions (unsigned int, ui);
+
+ return 0;
+}
+
+
diff --git a/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c b/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c
new file mode 100644
index 00000000000..178a537b1de
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/md/rXsbg_mode_sXl.c
@@ -0,0 +1,151 @@
+/* Machine description pattern tests. */
+
+/*
+ { dg-options "-mzarch -save-temps" }
+
+ Note that dejagnu-1.5.1 has a bug so that the action from the second dg-do
+ always wins, even if the condition is false. If this test is run on hardware
+ older than z10 with a buggy dejagnu release, the execution part will fail.
+
+ { dg-do assemble { target { ! z10_instructions } } }
+ { dg-do run { target { z10_instructions } } }
+
+ Skip test if -O0, -march=z900, -march=z9-109 or -march=z9-ec is present on
+ the command line:
+
+ { dg-skip-if "" { *-*-* } { "-march=z9*" "-O0" } { "" } }
+
+ Skip test if the -O or the -march= option is missing from the command line
+ because it's difficult to detect the default:
+
+ { dg-skip-if "" { *-*-* } { "*" } { "-O*" } }
+ { dg-skip-if "" { *-*-* } { "*" } { "-march=*" } }
+*/
+
+__attribute__ ((noinline)) unsigned int
+si_sll (unsigned int x)
+{
+ return (x << 1);
+}
+
+__attribute__ ((noinline)) unsigned int
+si_srl (unsigned int x)
+{
+ return (x >> 2);
+}
+
+__attribute__ ((noinline)) unsigned int
+rosbg_si_sll (unsigned int a, unsigned int b)
+{
+ return a | (b << 1);
+}
+/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,64-32,63-1,1" 1 } } */
+
+__attribute__ ((noinline)) unsigned int
+rosbg_si_srl (unsigned int a, unsigned int b)
+{
+ return a | (b >> 2);
+}
+/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,64-32\\+2,63,64-2" 1 } } */
+
+__attribute__ ((noinline)) unsigned int
+rxsbg_si_sll (unsigned int a, unsigned int b)
+{
+ return a ^ (b << 1);
+}
+/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,64-32,63-1,1" 1 } } */
+
+__attribute__ ((noinline)) unsigned int
+rxsbg_si_srl (unsigned int a, unsigned int b)
+{
+ return a ^ (b >> 2);
+}
+/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,64-32\\+2,63,64-2" 1 } } */
+
+__attribute__ ((noinline)) unsigned long long
+di_sll (unsigned long long x)
+{
+ return (x << 1);
+}
+
+__attribute__ ((noinline)) unsigned long long
+di_srl (unsigned long long x)
+{
+ return (x >> 2);
+}
+
+__attribute__ ((noinline)) unsigned long long
+rosbg_di_sll (unsigned long long a, unsigned long long b)
+{
+ return a | (b << 1);
+}
+/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,64-64,63-1,1" 1 } } */
+
+__attribute__ ((noinline)) unsigned long long
+rosbg_di_srl (unsigned long long a, unsigned long long b)
+{
+ return a | (b >> 2);
+}
+/* { dg-final { scan-assembler-times "rosbg\t%r.,%r.,64-64\\+2,63,64-2" 1 } } */
+
+__attribute__ ((noinline)) unsigned long long
+rxsbg_di_sll (unsigned long long a, unsigned long long b)
+{
+ return a ^ (b << 1);
+}
+/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,64-64,63-1,1" 1 } } */
+
+__attribute__ ((noinline)) unsigned long long
+rxsbg_di_srl (unsigned long long a, unsigned long long b)
+{
+ return a ^ (b >> 2);
+}
+/* { dg-final { scan-assembler-times "rxsbg\t%r.,%r.,64-64\\+2,63,64-2" 1 } } */
+
+int
+main (void)
+{
+ /* SIMode */
+ {
+ unsigned int r;
+ unsigned int a = 0x12488421u;
+ unsigned int b = 0x88881111u;
+ unsigned int csll = si_sll (b);
+ unsigned int csrl = si_srl (b);
+
+ r = rosbg_si_sll (a, b);
+ if (r != (a | csll))
+ __builtin_abort ();
+ r = rosbg_si_srl (a, b);
+ if (r != (a | csrl))
+ __builtin_abort ();
+ r = rxsbg_si_sll (a, b);
+ if (r != (a ^ csll))
+ __builtin_abort ();
+ r = rxsbg_si_srl (a, b);
+ if (r != (a ^ csrl))
+ __builtin_abort ();
+ }
+ /* DIMode */
+ {
+ unsigned long long r;
+ unsigned long long a = 0x1248357997538421lu;
+ unsigned long long b = 0x8888444422221111lu;
+ unsigned long long csll = di_sll (b);
+ unsigned long long csrl = di_srl (b);
+
+ r = rosbg_di_sll (a, b);
+ if (r != (a | csll))
+ __builtin_abort ();
+ r = rosbg_di_srl (a, b);
+ if (r != (a | csrl))
+ __builtin_abort ();
+ r = rxsbg_di_sll (a, b);
+ if (r != (a ^ csll))
+ __builtin_abort ();
+ r = rxsbg_di_srl (a, b);
+ if (r != (a ^ csrl))
+ __builtin_abort ();
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/s390/s390.exp b/gcc/testsuite/gcc.target/s390/s390.exp
index 680e7d95b71..f4ad7a1f25b 100644
--- a/gcc/testsuite/gcc.target/s390/s390.exp
+++ b/gcc/testsuite/gcc.target/s390/s390.exp
@@ -24,6 +24,17 @@ if ![istarget s390*-*-*] then {
# Load support procs.
load_lib gcc-dg.exp
+# Return 1 if z10 instructions work.
+proc check_effective_target_z10_instructions { } {
+ if { ![check_runtime s390_check_z10_instructions [subst {
+ int main (void)
+ {
+ asm ("rosbg %%r2,%%r2,0,0,0" : : );
+ return 0;
+ }
+ }] "-march=z10 -mzarch" ] } { return 0 } else { return 1 }
+}
+
# Return 1 if the the assembler understands .machine and .machinemode. The
# target attribute needs that feature to work.
proc check_effective_target_target_attribute { } {
diff --git a/gcc/testsuite/gcc.target/sh/pr52933-1.c b/gcc/testsuite/gcc.target/sh/pr52933-1.c
index 138de7f4914..81aa94fc8f0 100644
--- a/gcc/testsuite/gcc.target/sh/pr52933-1.c
+++ b/gcc/testsuite/gcc.target/sh/pr52933-1.c
@@ -4,13 +4,13 @@
logic usually show up as redundant tst insns. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-times "div0s" 32 } } */
+/* { dg-final { scan-assembler-times "div0s" 42 } } */
/* { dg-final { scan-assembler-not "tst" } } */
/* { dg-final { scan-assembler-not "not\t" } } */
/* { dg-final { scan-assembler-not "nott" } } */
-/* { dg-final { scan-assembler-times "negc" 9 { target { ! sh2a } } } } */
-/* { dg-final { scan-assembler-times "movrt" 9 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "negc" 10 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "movrt" 10 { target { sh2a } } } } */
typedef unsigned char bool;
@@ -212,3 +212,75 @@ test_30 (int a, int b)
{
return ((a >> 31) ^ (b >> 31)) & 1;
}
+
+// -------------------------------------------------------
+
+bool
+test_31 (int a, int b)
+{
+ /* 2x exts.w, div0s */
+ return ((a & 0x8000) ^ (b & 0x8000)) != 0;
+}
+
+bool
+test_32 (int a, int b)
+{
+ /* 2x exts.w, div0s */
+ return (a & 0x8000) != (b & 0x8000);
+}
+
+bool
+test_33 (int a, int b)
+{
+ /* 2x add/shll, div0s */
+ return ((a & (1<<30)) ^ (b & (1<<30))) != 0;
+}
+
+bool
+test_34 (int a, int b)
+{
+ /* 2x exts.b, div0s */
+ return (a & 0x80) != (b & 0x80);
+}
+
+bool
+test_35 (signed char a, signed char b)
+{
+ /* 2x exts.b, div0s */
+ return (a < 0) != (b < 0);
+}
+
+bool
+test_36 (short a, short b)
+{
+ /* 2x exts.w, div0s */
+ return (a < 0) != (b < 0);
+}
+
+int
+test_37 (short a, short b)
+{
+ /* 2x exts.w, div0s */
+ return (a < 0) != (b < 0) ? 40 : -10;
+}
+
+bool
+test_38 (int a, int b)
+{
+ /* 2x shll8, div0s */
+ return ((a & (1<<23)) ^ (b & (1<<23))) != 0;
+}
+
+bool
+test_39 (int a, int b)
+{
+ /* 2x shll2, div0s */
+ return ((a & (1<<29)) ^ (b & (1<<29))) != 0;
+}
+
+bool
+test_40 (short a, short b)
+{
+ /* 2x exts.w, div0s, negc */
+ return (a < 0) == (b < 0);
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr52933-2.c b/gcc/testsuite/gcc.target/sh/pr52933-2.c
index 4637f0ea17e..2b5d09ad0bb 100644
--- a/gcc/testsuite/gcc.target/sh/pr52933-2.c
+++ b/gcc/testsuite/gcc.target/sh/pr52933-2.c
@@ -5,12 +5,12 @@
logic usually show up as redundant tst insns. */
/* { dg-do compile } */
/* { dg-options "-O2 -mpretend-cmove" } */
-/* { dg-final { scan-assembler-times "div0s" 32 } } */
+/* { dg-final { scan-assembler-times "div0s" 42 } } */
/* { dg-final { scan-assembler-not "tst" } } */
/* { dg-final { scan-assembler-not "not\t" } } */
/* { dg-final { scan-assembler-not "nott" } } */
-/* { dg-final { scan-assembler-times "negc" 9 { target { ! sh2a } } } } */
-/* { dg-final { scan-assembler-times "movrt" 9 { target { sh2a } } } } */
+/* { dg-final { scan-assembler-times "negc" 10 { target { ! sh2a } } } } */
+/* { dg-final { scan-assembler-times "movrt" 10 { target { sh2a } } } } */
#include "pr52933-1.c"
diff --git a/gcc/testsuite/gcc.target/sh/pr54089-1.c b/gcc/testsuite/gcc.target/sh/pr54089-1.c
index 64f79ebc737..8b6a729f64c 100644
--- a/gcc/testsuite/gcc.target/sh/pr54089-1.c
+++ b/gcc/testsuite/gcc.target/sh/pr54089-1.c
@@ -1,7 +1,8 @@
/* Check that the rotcr instruction is generated. */
/* { dg-do compile } */
/* { dg-options "-O2" } */
-/* { dg-final { scan-assembler-times "rotcr" 24 } } */
+/* { dg-final { scan-assembler-times "rotcr" 25 } } */
+/* { dg-final { scan-assembler-times "sett" 1 } } */
/* { dg-final { scan-assembler-times "shll\t" 1 } } */
/* { dg-final { scan-assembler-not "and\t#1" } } */
/* { dg-final { scan-assembler-not "cmp/pl" } } */
@@ -173,3 +174,9 @@ test_23 (unsigned int a, int b, int c)
bool r = b != c;
return ((a >> 31) | (r << 31));
}
+
+unsigned int
+test_24 (unsigned int a)
+{
+ return (a >> 1) | (1 << 31);
+}
diff --git a/gcc/testsuite/gcc.target/sh/pr58219.c b/gcc/testsuite/gcc.target/sh/pr58219.c
new file mode 100644
index 00000000000..d900f72eae8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/sh/pr58219.c
@@ -0,0 +1,60 @@
+/* Check that move instructions have the correct length on SH2A. */
+/* { dg-do compile } */
+/* { dg-options "-O1 -dp" } */
+
+/* { dg-final { scan-assembler-times "length = 4" 10 { target { "sh2a" && any_fpu } } } } */
+/* { dg-final { scan-assembler-times "length = 4" 8 { target { "sh2a" && no_fpu } } } } */
+
+int
+test_00 (int* x)
+{
+ return x[0];
+}
+
+int
+test_01 (int* x)
+{
+ return x[1];
+}
+
+int
+test_02 (int* x)
+{
+ return x[100];
+}
+
+int
+test_03 (int* x, unsigned int y)
+{
+ return *(int*)((unsigned int)x + y);
+}
+
+float
+test_04 (float* x)
+{
+ return x[0];
+}
+
+float
+test_05 (float* x)
+{
+ return x[5];
+}
+
+float
+test_06 (float* x)
+{
+ return x[100];
+}
+
+int
+test_07 (void)
+{
+ return 1230;
+}
+
+int
+test_08 (void)
+{
+ return 0xFF0000;
+}
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_1.f90 b/gcc/testsuite/gfortran.dg/dec_structure_1.f90
new file mode 100644
index 00000000000..4dfee3c602e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_1.f90
@@ -0,0 +1,56 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Basic STRUCTURE test.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+! Basic structure
+structure /s1/ ! type s1
+ integer i1
+ logical l1
+ real r1
+ character c1
+end structure ! end type s1
+
+record /s1/ r1 ! type (s1) r1
+record /s1/ r1_a(3) ! type (s1) r1_a(3)
+
+! Basic records
+r1.i1 = 13579 ! r1%i1 = ...
+r1.l1 = .true.
+r1.r1 = 13.579
+r1.c1 = 'F'
+r1_a(2) = r1
+r1_a(3).r1 = 135.79
+
+if (r1.i1 .ne. 13579) then
+ call aborts("r1.i1")
+endif
+
+if (r1.l1 .neqv. .true.) then
+ call aborts("r1.l1")
+endif
+
+if (r1.r1 .ne. 13.579) then
+ call aborts("r1.r1")
+endif
+
+if (r1.c1 .ne. 'F') then
+ call aborts("r1.c1")
+endif
+
+if (r1_a(2).i1 .ne. 13579) then
+ call aborts("r1_a(2).i1")
+endif
+
+if (r1_a(3).r1 .ne. 135.79) then
+ call aborts("r1_a(3).r1")
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_10.f90 b/gcc/testsuite/gfortran.dg/dec_structure_10.f90
new file mode 100644
index 00000000000..2d92b1ad8fd
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_10.f90
@@ -0,0 +1,119 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Runtime tests for rules governing dot ('.') as a member accessor, including
+! voodoo with aliased user-defined vs. intrinsic operators and nested members.
+! See gcc/fortran/match.c (gfc_match_member_sep).
+!
+
+module dec_structure_10
+ ! Operator overload tests with .ne. and constant member
+ structure /s1/
+ integer i
+ integer ne
+ logical b
+ end structure
+
+ ! Operator overload tests with .eq., .test. and nested members
+ structure /s2/
+ record /s1/ eq
+ record /s1/ test
+ record /s1/ and
+ integer i
+ end structure
+
+ ! Deep nested access tests
+ structure /s3/
+ record /s2/ r2
+ end structure
+ structure /s4/
+ record /s3/ r3
+ end structure
+ structure /s5/
+ record /s4/ r4
+ end structure
+ structure /s6/
+ record /s5/ r5
+ end structure
+ structure /s7/
+ record /s6/ r6
+ end structure
+
+ ! Operator overloads to mess with nested member accesses
+ interface operator (.ne.)
+ module procedure ne_func
+ end interface operator (.ne.)
+ interface operator (.eq.)
+ module procedure eq_func
+ end interface operator (.eq.)
+ interface operator (.test.)
+ module procedure tstfunc
+ end interface operator (.test.)
+ contains
+ ! ne_func will be called on (x) .ne. (y)
+ function ne_func (r, i)
+ integer, intent(in) :: i
+ type(s1), intent(in) :: r
+ integer ne_func
+ ne_func = r%i + i
+ end function
+ ! eq_func will be called on (x) .eq. (y)
+ function eq_func (r, i)
+ integer, intent(in) :: i
+ type(s2), intent(in) :: r
+ integer eq_func
+ eq_func = r%eq%i + i
+ end function eq_func
+ ! tstfunc will be called on (x) .test. (y)
+ function tstfunc (r, i)
+ integer, intent(in) :: i
+ type(s2), intent(in) :: r
+ integer tstfunc
+ tstfunc = r%i + i
+ end function tstfunc
+end module
+
+use dec_structure_10
+
+record /s1/ r
+record /s2/ struct
+record /s7/ r7
+integer i, j
+logical l
+struct%eq%i = 5
+i = -5
+
+! Nested access: struct has a member and which has a member b
+l = struct .and. b ! struct%and%b
+l = struct .and. b .or. .false. ! (struct%and%b) .or. (.false.)
+
+! Intrinsic op: r has no member 'ne'
+j = r .ne. i ! <intrinsic> ne(r, i)
+j = (r) .ne. i ! <intrinsic> ne(r, i)
+
+! Intrinsic op; r has a member 'ne' but it is not a record
+j = r .ne. i ! <intrinsic> ne(r, i)
+j = (r) .ne. i ! <intrinsic> ne(r, i)
+
+! Nested access: struct has a member eq which has a member i
+j = struct .eq. i ! struct%eq%i
+if ( j .ne. struct%eq%i ) call abort()
+
+! User op: struct is compared to i with eq_func
+j = (struct) .eq. i ! eq_func(struct, i) -> struct%eq%i + i
+if ( j .ne. struct%eq%i + i ) call abort()
+
+! User op: struct has a member test which has a member i, but test is a uop
+j = struct .test. i ! tstfunc(struct, i) -> struct%i + i
+if ( j .ne. struct%i + i ) call abort()
+
+! User op: struct is compared to i with eq_func
+j = (struct) .test. i ! tstfunc(struct, i) -> struct%i + i
+if ( j .ne. struct%i + i ) call abort()
+
+! Deep nested access tests
+r7.r6.r5.r4.r3.r2.i = 1337
+j = r7.r6.r5.r4.r3.r2.i
+if ( j .ne. 1337 ) call abort()
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_11.f90 b/gcc/testsuite/gfortran.dg/dec_structure_11.f90
new file mode 100644
index 00000000000..f6f5b6f9d13
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_11.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure" }
+!
+! Tests for what CAN'T be done with dot ('.') as a member accessor.
+!
+
+structure /s1/
+ integer eq
+end structure
+
+record /s1/ r
+integer i, j, k
+
+j = i.j ! { dg-error "nonderived-type variable" }
+j = r .eq. i ! { dg-error "Operands of comparison" }
+j = r.i ! { dg-error "is not a member of" }
+j = r. ! { dg-error "Expected structure component or operator name" }
+j = .i ! { dg-error "Invalid character in name" }
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_2.f90 b/gcc/testsuite/gfortran.dg/dec_structure_2.f90
new file mode 100644
index 00000000000..18db719c149
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_2.f90
@@ -0,0 +1,41 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test STRUCTUREs containin other STRUCTUREs.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+! Basic structure
+structure /s1/
+ integer i1
+ logical l1
+ real r1
+ character c1
+end structure
+
+structure /s2/
+ integer i
+ record /s1/ r1
+endstructure
+
+record /s1/ r1
+record /s2/ r2, r2_a(10)
+
+! Nested and array records
+r2.r1.r1 = 135.79
+r2_a(3).r1.i1 = -13579
+
+if (r2.r1.r1 .ne. 135.79) then
+ call aborts("r1.r1.r1")
+endif
+
+if (r2_a(3).r1.i1 .ne. -13579) then
+ call aborts("r2_a(3).r1.i1")
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_3.f90 b/gcc/testsuite/gfortran.dg/dec_structure_3.f90
new file mode 100644
index 00000000000..9cb7adb6719
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_3.f90
@@ -0,0 +1,52 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test nested STRUCTURE definitions.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+structure /s3/
+ real p
+ structure /s4/ recrd, recrd_a(3)
+ integer i, j
+ end structure
+ real q
+end structure
+
+record /s3/ r3
+record /s4/ r4
+
+r3.p = 1.3579
+r4.i = 0
+r4.j = 1
+r3.recrd = r4
+r3.recrd_a(1) = r3.recrd
+r3.recrd_a(2).i = 1
+r3.recrd_a(2).j = 0
+
+if (r3.p .ne. 1.3579) then
+ call aborts("r3.p")
+endif
+
+if (r4.i .ne. 0) then
+ call aborts("r4.i")
+endif
+
+if (r4.j .ne. 1) then
+ call aborts("r4.j")
+endif
+
+if (r3.recrd.i .ne. 0 .or. r3.recrd.j .ne. 1) then
+ call aborts("r3.recrd")
+endif
+
+if (r3.recrd_a(2).i .ne. 1 .or. r3.recrd_a(2).j .ne. 0) then
+ call aborts("r3.recrd_a(2)")
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_4.f90 b/gcc/testsuite/gfortran.dg/dec_structure_4.f90
new file mode 100644
index 00000000000..a941c220b7e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_4.f90
@@ -0,0 +1,43 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test anonymous STRUCTURE definitions.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+structure /s5/
+ structure recrd, recrd_a(3)
+ real x, y
+ end structure
+end structure
+
+record /s5/ r5
+
+r5.recrd.x = 1.3
+r5.recrd.y = 5.7
+r5.recrd_a(1) = r5.recrd
+r5.recrd_a(2).x = 5.7
+r5.recrd_a(2).y = 1.3
+
+if (r5.recrd.x .ne. 1.3) then
+ call aborts("r5.recrd.x")
+endif
+
+if (r5.recrd.y .ne. 5.7) then
+ call aborts("r5.recrd.y")
+endif
+
+if (r5.recrd_a(1).x .ne. 1.3 .or. r5.recrd_a(1).y .ne. 5.7) then
+ call aborts("r5.recrd_a(1)")
+endif
+
+if (r5.recrd_a(2).x .ne. 5.7 .or. r5.recrd_a(2).y .ne. 1.3) then
+ call aborts("r5.recrd_a(2)")
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_5.f90 b/gcc/testsuite/gfortran.dg/dec_structure_5.f90
new file mode 100644
index 00000000000..abda3c3e9fb
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_5.f90
@@ -0,0 +1,49 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test STRUCTUREs which share names with variables.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+! Special regression where shared names within a module caused an ICE
+! from gfc_get_module_backend_decl
+module dec_structure_5m
+ structure /s6/
+ integer i
+ end structure
+
+ record /s6/ s6
+end module
+
+program dec_structure_5
+ use dec_structure_5m
+
+ structure /s7/
+ real r
+ end structure
+
+ record /s7/ s7(3)
+
+ s6.i = 0
+ s7(1).r = 1.0
+ s7(2).r = 2.0
+ s7(3).r = 3.0
+
+ if (s6.i .ne. 0) then
+ call aborts("s6.i")
+ endif
+
+ if (s7(1).r .ne. 1.0) then
+ call aborts("s7(1).r")
+ endif
+
+ if (s7(2).r .ne. 2.0) then
+ call aborts("s7(2).r")
+ endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_6.f90 b/gcc/testsuite/gfortran.dg/dec_structure_6.f90
new file mode 100644
index 00000000000..6494d71fd1c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_6.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test old-style CLIST initializers in STRUCTURE.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+integer, parameter :: as = 3
+structure /s8/
+ character*20 c /"HELLO"/ ! ok
+ integer*2 j /300_4/ ! ok, converted
+ integer k /65536_8/ ! ok, implicit
+ integer*4 l /200000/ ! ok, types match
+ integer m(5) /5,4,3,2,1/! ok
+ integer n(5) /1,3*2,1/ ! ok, with repeat spec (/1,2,2,2,1/)
+ integer o(as) /as*9/ ! ok, parameter array spec
+ integer p(2,2) /1,2,3,4/! ok
+ real q(3) /1_2,3.5,2.4E-12_8/ ! ok, with some implicit conversions
+ integer :: canary = z'3D3D3D3D'
+end structure
+
+record /s8/ r8
+
+! Old-style (clist) initializers in structures
+if ( r8.c /= "HELLO" ) call aborts ("r8.c")
+if ( r8.j /= 300 ) call aborts ("r8.j")
+if ( r8.k /= 65536 ) call aborts ("r8.k")
+if ( r8.l /= 200000 ) call aborts ("r8.l")
+if ( r8.m(1) /= 5 .or. r8.m(2) /= 4 .or. r8.m(3) /= 3 &
+ .or. r8.m(4) /= 2 .or. r8.m(5) /= 1) &
+ call aborts ("r8.m")
+if ( r8.n(1) /= 1 .or. r8.n(2) /= 2 .or. r8.n(3) /= 2 .or. r8.n(4) /= 2 &
+ .or. r8.n(5) /= 1) &
+ call aborts ("r8.n")
+if ( r8.o(1) /= 9 .or. r8.o(2) /= 9 .or. r8.o(3) /= 9 ) call aborts ("r8.o")
+if ( r8.p(1,1) /= 1 .or. r8.p(2,1) /= 2 .or. r8.p(1,2) /= 3 &
+ .or. r8.p(2,2) /= 4) &
+ call aborts ("r8.p")
+if ( r8.canary /= z'3D3D3D3D' ) call aborts ("r8.canary")
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_7.f90 b/gcc/testsuite/gfortran.dg/dec_structure_7.f90
new file mode 100644
index 00000000000..baba1ef2b5f
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_7.f90
@@ -0,0 +1,75 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test passing STRUCTUREs through functions and subroutines.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+module dec_structure_7m
+ structure /s1/
+ integer i1
+ logical l1
+ real r1
+ character c1
+ end structure
+
+ structure /s2/
+ integer i
+ record /s1/ r1
+ endstructure
+
+contains
+ ! Pass structure through subroutine
+ subroutine sub (rec1, i)
+ implicit none
+ integer, intent(in) :: i
+ record /s1/ rec1
+ rec1.i1 = i
+ end subroutine
+
+ ! Pass structure through function
+ function func (rec2, r)
+ implicit none
+ real, intent(in) :: r
+ record /s2/ rec2
+ real func
+ rec2.r1.r1 = r
+ func = rec2.r1.r1
+ return
+ end function
+end module
+
+program dec_structure_7
+ use dec_structure_7m
+
+ implicit none
+ record /s1/ r1
+ record /s2/ r2
+ real junk
+
+ ! Passing through functions and subroutines
+ r1.i1 = 0
+ call sub (r1, 10)
+
+ r2.r1.r1 = 0.0
+ junk = func (r2, -20.14)
+
+ if (r1.i1 .ne. 10) then
+ call aborts("sub(r1, 10)")
+ endif
+
+ if (r2.r1.r1 .ne. -20.14) then
+ call aborts("func(r2, -20.14)")
+ endif
+
+ if (junk .ne. -20.14) then
+ print *, junk
+ call aborts("junk = func()")
+ endif
+
+end program
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_8.f90 b/gcc/testsuite/gfortran.dg/dec_structure_8.f90
new file mode 100644
index 00000000000..160b92a8b96
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_8.f90
@@ -0,0 +1,60 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure -fmax-errors=0" }
+!
+! Comprehensive compile tests for what structures CAN'T do.
+!
+
+! Old-style (clist) initialization
+integer,parameter :: as = 3
+structure /t1/
+ integer*1 a /300_2/ ! { dg-error "Arithmetic overflow" }
+ integer b // ! { dg-error "Empty old style initializer list" }
+ integer c /2*3/ ! { dg-error "Repeat spec invalid in scalar" }
+ integer d /1,2,3/ ! { dg-error "End of scalar initializer expected" }
+ integer e /"HI"/ ! { dg-error "Can't convert" }
+ integer f(as) /4*9/ ! { dg-error "Too many elements" }
+ integer g(3) /1,3/ ! { dg-error "Not enough elements" }
+ integer h(3) /1,3,5,7/ ! { dg-error "Too many elements" }
+ integer i(3) /2*1/ ! { dg-error "Not enough elements" }
+ integer j(3) /10*1/ ! { dg-error "Too many elements" }
+ integer k(3) /2.5*3/ ! { dg-error "Repeat spec must be an integer" }
+ integer l(2) /2*/ ! { dg-error "Expected data constant" }
+ integer m(1) / ! { dg-error "Syntax error in old style" }
+ integer n(2) /1 ! { dg-error "Syntax error in old style" }
+ integer o(2) /1, ! { dg-error "Syntax error in old style" }
+ integer p(1) /x/ ! { dg-error "must be a PARAMETER" }
+end structure
+
+structure ! { dg-error "Structure name expected" }
+structure / ! { dg-error "Structure name expected" }
+structure // ! { dg-error "Structure name expected" }
+structure /.or./ ! { dg-error "Structure name expected" }
+structure /integer/ ! { dg-error "Structure name.*cannot be the same" }
+structure /foo/ bar ! { dg-error "Junk after" }
+structure /t1/ ! { dg-error "Type definition.*T1" }
+
+record ! { dg-error "Structure name expected" }
+record bar ! { dg-error "Structure name expected" }
+record / bar ! { dg-error "Structure name expected" }
+record // bar ! { dg-error "Structure name expected" }
+record foo/ bar ! { dg-error "Structure name expected" }
+record /foo bar ! { dg-error "Structure name expected" }
+record /foo/ bar ! { dg-error "used before it is defined" }
+record /t1/ ! { dg-error "Invalid character in name" }
+
+structure /t2/
+ ENTRY here ! { dg-error "ENTRY statement.*cannot appear" }
+ integer a
+ integer a ! { dg-error "Component.*already declared" }
+ structure $z ! { dg-error "Invalid character in name" }
+ structure // ! { dg-error "Invalid character in name" }
+ structure // x ! { dg-error "Invalid character in name" }
+ structure /t3/ ! { dg-error "Invalid character in name" }
+ structure /t3/ x,$y ! { dg-error "Invalid character in name" }
+ structure /t4/ y
+ integer i, j, k
+ end structure
+ structure /t4/ z ! { dg-error "Type definition.*T4" }
+end structure
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_structure_9.f90 b/gcc/testsuite/gfortran.dg/dec_structure_9.f90
new file mode 100644
index 00000000000..34c46c61c1c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_structure_9.f90
@@ -0,0 +1,42 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure" }
+!
+! Basic compile tests for what CAN be done with dot ('.') as a member accessor.
+!
+
+logical :: l, l2 = .true., l3 = .false., and
+integer i
+character(5) s
+real r
+
+structure /s1/
+ integer i
+ character(5) s
+ real r
+end structure
+
+record /s1/ r1
+
+! Basic
+l = l .and. l2 .or. l3
+l = and .and. and .and. and
+l = l2 .eqv. l3
+l = (l2) .eqv. l3
+
+! Integers
+l = .not. (i .eq. 0)
+l = .not. (0 .eq. i)
+l = .not. (r1.i .eq. 0)
+l = .not. (0 .eq. r1.i)
+! Characters
+l = .not. (s .eq. "hello")
+l = .not. ("hello" .eq. s)
+l = .not. (r1.s .eq. "hello")
+l = .not. ("hello" .eq. r1.s)
+! Reals
+l = .not. (r .eq. 3.14)
+l = .not. (3.14 .eq. r)
+l = .not. (r1.r .eq. 3.14)
+l = .not. (3.14 .eq. r1.r)
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_union_1.f90 b/gcc/testsuite/gfortran.dg/dec_union_1.f90
new file mode 100644
index 00000000000..36af53adfe1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_1.f90
@@ -0,0 +1,66 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test whether union backend declarations are corrently _not_ copied when they
+! are not in fact equal. The structure defined in sub() is seen later, but
+! where siz has a different value.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+subroutine sub ()
+ integer, parameter :: siz = 1024
+ structure /s6/
+ union ! U0
+ map ! M0
+ integer ibuf(siz)
+ end map
+ map ! M1
+ character(8) cbuf(siz)
+ end map
+ map ! M2
+ real rbuf(siz)
+ end map
+ end union
+ end structure
+ record /s6/ r6
+ r6.ibuf(1) = z'badbeef'
+ r6.ibuf(2) = z'badbeef'
+end subroutine
+
+! Repeat definition from subroutine sub with different size parameter.
+! If the structure definition is copied here the stack may get messed up.
+integer, parameter :: siz = 65536
+structure /s6/
+ union ! U12
+ map
+ integer ibuf(siz)
+ end map
+ map
+ character(8) cbuf(siz)
+ end map
+ map
+ real rbuf(siz)
+ end map
+ end union
+end structure
+
+record /s6/ r6
+integer :: r6_canary = 0
+
+! Copied type declaration - this should not cause problems
+i = 1
+do while (i < siz)
+ r6.ibuf(i) = z'badbeef'
+ i = i + 1
+end do
+
+if ( r6_canary .ne. 0 ) then
+ call aborts ('copied decls: overflow')
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_union_2.f90 b/gcc/testsuite/gfortran.dg/dec_union_2.f90
new file mode 100644
index 00000000000..61e4fd8bd80
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_2.f90
@@ -0,0 +1,60 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test basic UNION implementation.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+! Empty union
+structure /s0/
+ union ! U0
+ map ! M0
+ end map
+ map ! M1
+ end map
+ end union
+end structure
+
+! Basic unions
+structure /s1/
+ union ! U1
+ map ! M2
+ integer(4) a
+ end map
+ map ! M3
+ real(4) b
+ end map
+ end union
+end structure
+structure /s2/
+ union ! U2
+ map ! M4
+ integer(2) w1, w2
+ end map
+ map ! M5
+ integer(4) long
+ end map
+ end union
+end structure
+
+record /s1/ r1
+record /s2/ r2
+
+! Basic unions
+r1.a = 0
+r1.b = 1.33e7
+if ( r1.a .eq. 0 ) call aborts ("basic union 1")
+
+! Endian-agnostic runtime check
+r2.long = z'12345678'
+if (.not. ( (r2.w1 .eq. z'1234' .and. r2.w2 .eq. z'5678') &
+ .or. (r2.w1 .eq. z'5678' .and. r2.w2 .eq. z'1234')) ) then
+ call aborts ("basic union 2")
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_union_3.f90 b/gcc/testsuite/gfortran.dg/dec_union_3.f90
new file mode 100644
index 00000000000..ce5ae797859
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_3.f90
@@ -0,0 +1,35 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test UNIONs with initializations.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+! Initialization expressions
+structure /s3/
+ integer(4) :: i = 8
+ union ! U7
+ map
+ integer(4) :: x = 1600
+ integer(4) :: y = 1800
+ end map
+ map
+ integer(2) a, b, c
+ end map
+ end union
+end structure
+
+record /s3/ r3
+
+! Initialized unions
+if ( r3.x .ne. 1600 .or. r3.y .ne. 1800) then
+ r3.x = r3.y ! If r3 isn't used the initializations are optimized out
+ call aborts ("union initialization")
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_union_4.f90 b/gcc/testsuite/gfortran.dg/dec_union_4.f90
new file mode 100644
index 00000000000..4c1c6efe605
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_4.f90
@@ -0,0 +1,63 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test nested UNIONs.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+! Nested unions
+structure /s4/
+ union ! U0 ! rax
+ map
+ character(16) rx
+ end map
+ map
+ character(8) rh ! rah
+ union ! U1
+ map
+ character(8) rl ! ral
+ end map
+ map
+ character(8) ex ! eax
+ end map
+ map
+ character(4) eh ! eah
+ union ! U2
+ map
+ character(4) el ! eal
+ end map
+ map
+ character(4) x ! ax
+ end map
+ map
+ character(2) h ! ah
+ character(2) l ! al
+ end map
+ end union
+ end map
+ end union
+ end map
+ end union
+end structure
+record /s4/ r4
+
+
+! Nested unions
+r4.rx = 'AAAAAAAA.BBB.C.D'
+
+if ( r4.rx .ne. 'AAAAAAAA.BBB.C.D' ) call aborts ("rax")
+if ( r4.rh .ne. 'AAAAAAAA' ) call aborts ("rah")
+if ( r4.rl .ne. '.BBB.C.D' ) call aborts ("ral")
+if ( r4.ex .ne. '.BBB.C.D' ) call aborts ("eax")
+if ( r4.eh .ne. '.BBB' ) call aborts ("eah")
+if ( r4.el .ne. '.C.D' ) call aborts ("eal")
+if ( r4.x .ne. '.C.D' ) call aborts ("ax")
+if ( r4.h .ne. '.C' ) call aborts ("ah")
+if ( r4.l .ne. '.D' ) call aborts ("al")
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_union_5.f90 b/gcc/testsuite/gfortran.dg/dec_union_5.f90
new file mode 100644
index 00000000000..bb1611a0289
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_5.f90
@@ -0,0 +1,41 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! Test UNIONs with array components.
+!
+
+subroutine aborts (s)
+ character(*), intent(in) :: s
+ print *, s
+ call abort()
+end subroutine
+
+! Unions with arrays
+structure /s5/
+ union
+ map
+ character :: s(5)
+ end map
+ map
+ integer(1) :: a(5)
+ end map
+ end union
+end structure
+
+record /s5/ r5
+
+! Unions with arrays
+r5.a(1) = z'41'
+r5.a(2) = z'42'
+r5.a(3) = z'43'
+r5.a(4) = z'44'
+r5.a(5) = z'45'
+if ( r5.s(1) .ne. 'A' &
+ .or. r5.s(2) .ne. 'B' &
+ .or. r5.s(3) .ne. 'C' &
+ .or. r5.s(4) .ne. 'D' &
+ .or. r5.s(5) .ne. 'E') then
+ call aborts ("arrays")
+endif
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_union_6.f90 b/gcc/testsuite/gfortran.dg/dec_union_6.f90
new file mode 100644
index 00000000000..31059c46880
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_6.f90
@@ -0,0 +1,59 @@
+! { dg-do run }
+! { dg-options "-fdec-structure" }
+!
+! sub0 and sub1 test a regression where calling gfc_use_derived from
+! gfc_find_component on the structure type symbol being parsed caused the
+! symbol to be freed and swapped for the previously seen type symbol, leaving
+! dangling pointers and causing all sorts of mayhem.
+!
+
+subroutine sub0 (u)
+ structure /s/
+ union ! U0
+ map ! M0
+ integer i
+ end map
+ end union
+ end structure
+ record /s/ u
+ u.i = 0
+end subroutine sub0
+
+subroutine sub1 ()
+ structure /s/
+ union ! U1
+ map ! M1
+ integer i
+ end map
+ end union
+ end structure
+ record /s/ u
+ interface ! matches the declaration of sub0 above
+ subroutine sub0 (u)
+ structure /s/
+ union ! U2
+ map ! M2
+ integer i ! gfc_find_component should not call gfc_use_derived
+ end map ! here, otherwise this structure's type symbol is freed
+ end union ! out from under it
+ end structure
+ record /s/ u
+ end subroutine sub0
+ end interface
+ call sub0(u)
+end subroutine
+
+! If sub0 and sub1 aren't used they may be omitted
+structure /s/
+ union ! U1
+ map ! M3
+ integer i
+ end map
+ end union
+end structure
+record /s/ u
+
+call sub0(u)
+call sub1()
+
+end
diff --git a/gcc/testsuite/gfortran.dg/dec_union_7.f90 b/gcc/testsuite/gfortran.dg/dec_union_7.f90
new file mode 100644
index 00000000000..270f0fbd415
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_7.f90
@@ -0,0 +1,38 @@
+! { dg-do compile }
+! { dg-options "-fdec-structure" }
+!
+! Comprehensive compile tests for what unions CAN'T do.
+!
+
+! Syntax errors
+structure /s0/
+ union a b c ! { dg-error "Junk after UNION" }
+ union
+ map a b c ! { dg-error "Junk after MAP" }
+ integer x ! { dg-error "Unexpected" }
+ structure /s2/ ! { dg-error "Unexpected" }
+ map
+ map ! { dg-error "Unexpected" }
+ end map
+ end union
+end structure
+
+! Initialization expressions
+structure /s1/
+ union
+ map
+ integer(4) :: x = 1600 ! { dg-error "Conflicting initializers" }
+ integer(4) :: y = 1800
+ end map
+ map
+ integer(2) a, b, c, d
+ integer :: e = 0 ! { dg-error "Conflicting initializers" }
+ end map
+ map
+ real :: p = 1.3, q = 3.7 ! { dg-error "Conflicting initializers" }
+ end map
+ end union
+end structure
+record /s1/ r1
+
+end
diff --git a/gcc/testsuite/gfortran.dg/gomp/pr70855.f90 b/gcc/testsuite/gfortran.dg/gomp/pr70855.f90
new file mode 100644
index 00000000000..247e4edd6ff
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/pr70855.f90
@@ -0,0 +1,18 @@
+! PR fortran/70855
+! { dg-do compile }
+! { dg-additional-options "-O2" }
+
+program pr70855
+ integer, parameter :: m = 4
+ integer, parameter :: n = 2
+ real :: a(m,n)
+ real :: x(n)
+ real :: y(m)
+ a = 1.0
+ x = 1.0
+!$omp parallel
+!$omp workshare
+ y(1:m) = matmul ( a(1:m,1:n), x(1:n) )
+!$omp end workshare
+!$omp end parallel
+end program pr70855
diff --git a/gcc/testsuite/gfortran.dg/pr42108.f90 b/gcc/testsuite/gfortran.dg/pr42108.f90
index c823edbf792..eb93604e6b0 100644
--- a/gcc/testsuite/gfortran.dg/pr42108.f90
+++ b/gcc/testsuite/gfortran.dg/pr42108.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-! { dg-options "-O2 -fdump-tree-fre1 -fdump-tree-pre-details" }
+! { dg-options "-O2 -fdump-tree-fre1 -fdump-tree-pre-details -fno-tree-loop-im" }
subroutine eval(foo1,foo2,foo3,foo4,x,n,nnd)
implicit real*8 (a-h,o-z)
diff --git a/gcc/testsuite/gfortran.dg/pr46519-1.f b/gcc/testsuite/gfortran.dg/pr46519-1.f
index 51c64b87d28..46be9f590dd 100644
--- a/gcc/testsuite/gfortran.dg/pr46519-1.f
+++ b/gcc/testsuite/gfortran.dg/pr46519-1.f
@@ -1,5 +1,5 @@
! { dg-do compile { target i?86-*-* x86_64-*-* } }
-! { dg-options "-O3 -mavx -mvzeroupper -mtune=generic -dp" }
+! { dg-options "-O3 -mavx -mvzeroupper -fno-tree-slp-vectorize -mtune=generic -dp" }
PROGRAM MG3XDEMO
INTEGER LM, NM, NV, NR, NIT
diff --git a/gcc/testsuite/gfortran.dg/pr69603.f90 b/gcc/testsuite/gfortran.dg/pr69603.f90
new file mode 100644
index 00000000000..dca4eb15fc6
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr69603.f90
@@ -0,0 +1,16 @@
+! { dg-do compile }
+! { dg-options "-fimplicit-none" }
+! PR fortran/69603 - segfault with -fimplicit-none and proc_ptr_comp_24.f90
+! Based on reduced testcase by Dominique d'Humieres
+PROGRAM prog
+ implicit none
+ TYPE object
+ PROCEDURE(), POINTER, NOPASS :: f
+ END TYPE object
+ TYPE (object) :: o1
+ CALL set_func(o1%f)
+CONTAINS
+ SUBROUTINE set_func(f)
+ PROCEDURE(), POINTER :: f
+ END SUBROUTINE set_func
+END PROGRAM prog
diff --git a/gcc/testsuite/gfortran.dg/pr70931.f90 b/gcc/testsuite/gfortran.dg/pr70931.f90
new file mode 100644
index 00000000000..08ecd687752
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr70931.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-g" }
+program p
+ type t
+ integer :: a
+ integer :: b(0)
+ end type
+ type(t), parameter :: z = t(1, [2])
+ print *, z
+end
diff --git a/gcc/testsuite/gfortran.dg/pr70937.f90 b/gcc/testsuite/gfortran.dg/pr70937.f90
new file mode 100644
index 00000000000..3fb17bd227e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr70937.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+! { dg-options "-flto" }
+ SUBROUTINE dbcsr_test_read_args(narg, args)
+ CHARACTER(len=*), DIMENSION(:), &
+ INTENT(out) :: args
+ CHARACTER(len=80) :: line
+ DO
+ args(narg) = line
+ ENDDO
+ END SUBROUTINE dbcsr_test_read_args
diff --git a/gcc/testsuite/gfortran.dg/pr71047.f08 b/gcc/testsuite/gfortran.dg/pr71047.f08
new file mode 100644
index 00000000000..61a0ad4dc31
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr71047.f08
@@ -0,0 +1,48 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! Fortran/PR71047
+!
+
+module m
+ implicit none
+
+ type, abstract :: c_abstr
+ integer :: i = 0
+ end type c_abstr
+
+ type, extends(c_abstr) :: t_a
+ class(c_abstr), allocatable :: f
+ end type t_a
+
+ type, extends(c_abstr) :: t_b
+ end type t_b
+
+contains
+
+ subroutine set(y,x)
+ class(c_abstr), intent(in) :: x
+ type(t_a), intent(out) :: y
+ allocate( y%f , source=x )
+ end subroutine set
+
+end module m
+
+
+program p
+ use m
+ implicit none
+
+ type(t_a) :: res
+ type(t_b) :: var
+
+ call set( res , var )
+ write(*,*) res%i
+
+end program p
+
+!
+! Check to ensure the vtable is actually initialized.
+!
+! { dg-final { scan-tree-dump "t_a\\.\\d+\\.f\\._vptr =" "original" } }
+!
diff --git a/gcc/testsuite/gfortran.dg/pr71204.f90 b/gcc/testsuite/gfortran.dg/pr71204.f90
new file mode 100644
index 00000000000..1d1ee5c34a1
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr71204.f90
@@ -0,0 +1,17 @@
+! PR fortran/71204
+! { dg-do compile }
+! { dg-options "-O0" }
+
+module pr71204
+ character(10), allocatable :: z(:)
+end module
+
+subroutine s1
+ use pr71204
+ z(2) = z(1)
+end
+
+subroutine s2
+ use pr71204
+ z(2) = z(1)
+end
diff --git a/gcc/testsuite/gfortran.fortran-torture/compile/pr70960.f90 b/gcc/testsuite/gfortran.fortran-torture/compile/pr70960.f90
new file mode 100644
index 00000000000..675fb56ad6c
--- /dev/null
+++ b/gcc/testsuite/gfortran.fortran-torture/compile/pr70960.f90
@@ -0,0 +1,10 @@
+ SUBROUTINE calbrec(a,ai,error)
+ REAL(KIND=8) :: a(3,3), ai(3,3)
+ DO i = 1, 3
+ il = 1
+ IF (i==1) il = 2
+ DO j = 1, 3
+ ai(j,i) = (-1.0_8)**(i+j)*det*(a(il,jl)*a(iu,ju)-a(il,ju)*a(iu,jl))
+ END DO
+ END DO
+ END SUBROUTINE calbrec
diff --git a/gcc/testsuite/gnat.dg/debug5.adb b/gcc/testsuite/gnat.dg/debug5.adb
new file mode 100644
index 00000000000..6569a158029
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/debug5.adb
@@ -0,0 +1,22 @@
+-- { dg-do compile }
+-- { dg-options "-g" }
+
+procedure Debug5 is
+
+ type Record_Type (L1, L2 : Natural) is record
+ S1 : String (1 .. L1);
+ case L2 is
+ when 0 => null;
+ when others => S2 : String (L1 .. L2);
+ end case;
+ end record;
+
+ procedure Discard (R : Record_Type) is
+ begin
+ null;
+ end Discard;
+
+ R : constant Record_Type := (0, 0, others => <>);
+begin
+ Discard (R);
+end Debug5;
diff --git a/gcc/testsuite/gnat.dg/debug6.adb b/gcc/testsuite/gnat.dg/debug6.adb
new file mode 100644
index 00000000000..25fdef206df
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/debug6.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+-- { dg-options "-g" }
+
+with Debug6_Pkg; use Debug6_Pkg;
+
+procedure Debug6 is
+ V : Value := (Kind => Undefined);
+begin
+ Process (V);
+end Debug6;
diff --git a/gcc/testsuite/gnat.dg/debug6_pkg.ads b/gcc/testsuite/gnat.dg/debug6_pkg.ads
new file mode 100644
index 00000000000..dfc9744079b
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/debug6_pkg.ads
@@ -0,0 +1,16 @@
+package Debug6_Pkg is
+
+ type Vkind is (Int, Undefined);
+ for Vkind use (Int => -2 ** 31, Undefined => 0);
+
+ type Value (Kind : Vkind) is record
+ case Kind is
+ when Undefined => null;
+ when Int => Value : Integer;
+ when others => null;
+ end case;
+ end record;
+
+ procedure Process (V : Value);
+
+end Debug6_Pkg;
diff --git a/gcc/testsuite/gnat.dg/opt53.adb b/gcc/testsuite/gnat.dg/opt53.adb
new file mode 100644
index 00000000000..936277db85f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt53.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+-- { dg-options "-O2 -fdump-tree-optimized" }
+
+function Opt53 (Val, Max : Positive) return Positive is
+begin
+ if Val >= Max then
+ return Max;
+ end if;
+ return Val + 1;
+end;
+
+-- { dg-final { scan-tree-dump-not "gnat_rcheck" "optimized" } }
diff --git a/gcc/testsuite/gnat.dg/opt54.adb b/gcc/testsuite/gnat.dg/opt54.adb
new file mode 100644
index 00000000000..b4aaa0900e6
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/opt54.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+-- { dg-options "-O2 -fdump-tree-optimized" }
+
+function Opt54 (Val, Max : Integer) return Integer is
+begin
+ if Val >= Max then
+ return Max;
+ end if;
+ return Val + 1;
+end;
+
+-- { dg-final { scan-tree-dump-not "gnat_rcheck" "optimized" } }
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 463eefb2ad0..3e2b3b910fc 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -105,6 +105,13 @@
#undef create_code
#undef verify_code
+/* test-factorial-must-tail-call.c */
+#define create_code create_code_factorial_must_tail_call
+#define verify_code verify_code_factorial_must_tail_call
+#include "test-factorial-must-tail-call.c"
+#undef create_code
+#undef verify_code
+
/* test-fibonacci.c */
#define create_code create_code_fibonacci
#define verify_code verify_code_fibonacci
@@ -272,6 +279,9 @@ const struct testcase testcases[] = {
{"factorial",
create_code_factorial,
verify_code_factorial},
+ {"factorial_must_tail_call",
+ create_code_factorial_must_tail_call,
+ verify_code_factorial_must_tail_call},
{"fibonacci",
create_code_fibonacci,
verify_code_fibonacci},
diff --git a/gcc/testsuite/jit.dg/test-error-array-bounds.c b/gcc/testsuite/jit.dg/test-error-array-bounds.c
new file mode 100644
index 00000000000..732ec87bfd9
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-array-bounds.c
@@ -0,0 +1,72 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+ char
+ test_array_bounds (void)
+ {
+ char buffer[10];
+ return buffer[10];
+ }
+ with -Warray-bounds and -ftree-vrp and verify that the
+ out-of-bounds access is detected and reported as a jit error. */
+ gcc_jit_context_add_command_line_option (ctxt, "-Warray-bounds");
+ gcc_jit_context_add_command_line_option (ctxt, "-ftree-vrp");
+
+ /* Ensure that the error message doesn't contain colorization codes,
+ even if run at a TTY. */
+ gcc_jit_context_add_command_line_option (ctxt, "-fdiagnostics-color=never");
+
+ gcc_jit_type *char_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR);
+ gcc_jit_type *array_type =
+ gcc_jit_context_new_array_type (ctxt, NULL,
+ char_type, 10);
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+ /* Build the test_fn. */
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ char_type,
+ "test_array_bounds",
+ 0, NULL,
+ 0);
+ gcc_jit_lvalue *buffer =
+ gcc_jit_function_new_local (test_fn, NULL, array_type, "buffer");
+
+ /* tree-vrp.c:check_all_array_refs only checks array lookups that
+ have source locations. */
+ gcc_jit_location *dummy_loc =
+ gcc_jit_context_new_location (ctxt, "dummy.c", 10, 4);
+
+ gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+ gcc_jit_rvalue *index =
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 10);
+ gcc_jit_lvalue *read_of_the_buffer =
+ gcc_jit_context_new_array_access (ctxt, dummy_loc,
+ gcc_jit_lvalue_as_rvalue (buffer),
+ index);
+ gcc_jit_block_end_with_return (
+ block, dummy_loc,
+ gcc_jit_lvalue_as_rvalue (read_of_the_buffer));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Verify that the diagnostic led to the context failing... */
+ CHECK_VALUE (result, NULL);
+
+ /* ...and that the message was captured by the API. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "array subscript is above array bounds [-Warray-bounds]");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-impossible-must-tail-call.c b/gcc/testsuite/jit.dg/test-error-impossible-must-tail-call.c
new file mode 100644
index 00000000000..8848d3015a9
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-impossible-must-tail-call.c
@@ -0,0 +1,93 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ struct box { char dummy[64]; int i; };
+
+ extern struct box
+ returns_struct (int i);
+
+#ifdef __cplusplus
+}
+#endif
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+ int test (int i)
+ {
+ return [MUST TAIL CALL] returns_struct (i).i;
+ }
+
+ and verify that we get a sane error when the tail call
+ optimization can't be done. */
+
+ gcc_jit_type *char_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR);
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+ /* Declare "struct box. */
+ gcc_jit_type *array_type =
+ gcc_jit_context_new_array_type (ctxt, NULL, char_type, 64);
+ gcc_jit_field *field_dummy =
+ gcc_jit_context_new_field (ctxt, NULL, array_type, "dummy");
+ gcc_jit_field *field_i =
+ gcc_jit_context_new_field (ctxt, NULL, int_type, "i");
+ gcc_jit_field *fields[2] = {field_dummy, field_i};
+ gcc_jit_struct *struct_box =
+ gcc_jit_context_new_struct_type (ctxt, NULL, "box", 2, fields);
+
+ /* Declare the imported function. */
+ gcc_jit_param *called_fn_param_i =
+ gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
+ gcc_jit_function *called_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_IMPORTED,
+ gcc_jit_struct_as_type (struct_box),
+ "called_function",
+ 1, &called_fn_param_i,
+ 0);
+
+ /* Build the test_fn. */
+ gcc_jit_param *caller_param_i =
+ gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
+ gcc_jit_function *test_fn =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ "test_caller",
+ 1, &caller_param_i,
+ 0);
+ gcc_jit_rvalue *arg = gcc_jit_param_as_rvalue (caller_param_i);
+
+ gcc_jit_rvalue *call =
+ gcc_jit_context_new_call (ctxt, NULL,
+ called_fn,
+ 1, &arg);
+
+ /* Mark the call as requiring tail-call optimization. */
+ gcc_jit_rvalue_set_bool_require_tail_call (call, 1);
+
+ gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
+ gcc_jit_block_end_with_return (block, NULL,
+ gcc_jit_rvalue_access_field (call, NULL, field_i));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_VALUE (result, NULL);
+
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "cannot tail-call: callee returns a structure");
+}
diff --git a/gcc/testsuite/jit.dg/test-factorial-must-tail-call.c b/gcc/testsuite/jit.dg/test-factorial-must-tail-call.c
new file mode 100644
index 00000000000..c8626115708
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-factorial-must-tail-call.c
@@ -0,0 +1,109 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ /* Let's try to inject the equivalent of:
+
+ int
+ my_factorial_must_tail_call (int x)
+ {
+ if (x < 2)
+ return x;
+ else
+ return x * my_factorial_must_tail_call (x - 1);
+ }
+
+ and mark the call as requiring tail-call-optimization.
+ */
+ gcc_jit_type *the_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_type *return_type = the_type;
+
+ gcc_jit_param *x =
+ gcc_jit_context_new_param (ctxt, NULL, the_type, "x");
+ gcc_jit_param *params[1] = {x};
+ gcc_jit_function *func =
+ gcc_jit_context_new_function (ctxt, NULL,
+ GCC_JIT_FUNCTION_EXPORTED,
+ return_type,
+ "my_factorial_must_tail_call",
+ 1, params, 0);
+
+ gcc_jit_block *initial =
+ gcc_jit_function_new_block (func, "initial");
+ gcc_jit_block *on_true =
+ gcc_jit_function_new_block (func, "on_true");
+ gcc_jit_block *on_false =
+ gcc_jit_function_new_block (func, "on_false");
+
+ /* if (x < 2) */
+ gcc_jit_block_end_with_conditional (
+ initial, NULL,
+ gcc_jit_context_new_comparison (
+ ctxt, NULL,
+ GCC_JIT_COMPARISON_LT,
+ gcc_jit_param_as_rvalue (x),
+ gcc_jit_context_new_rvalue_from_int (
+ ctxt,
+ the_type,
+ 2)),
+ on_true,
+ on_false);
+
+ /* true branch: */
+ /* return x */
+ gcc_jit_block_end_with_return (
+ on_true,
+ NULL,
+ gcc_jit_param_as_rvalue (x));
+
+ /* false branch: */
+ gcc_jit_rvalue *x_minus_1 =
+ gcc_jit_context_new_binary_op (
+ ctxt, NULL,
+ GCC_JIT_BINARY_OP_MINUS, the_type,
+ gcc_jit_param_as_rvalue (x),
+ gcc_jit_context_new_rvalue_from_int (
+ ctxt,
+ the_type,
+ 1));
+ /* my_factorial_must_tail_call (x - 1) */
+ gcc_jit_rvalue *call =
+ gcc_jit_context_new_call (
+ ctxt, NULL,
+ func,
+ 1, &x_minus_1);
+
+ /* Mark the call as requiring tail-call optimization. */
+ gcc_jit_rvalue_set_bool_require_tail_call (call, 1);
+
+ gcc_jit_block_end_with_return (
+ on_false,
+ NULL,
+ gcc_jit_context_new_binary_op (
+ ctxt, NULL,
+ GCC_JIT_BINARY_OP_MULT, the_type,
+ gcc_jit_param_as_rvalue (x),
+ call));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ typedef int (*my_factorial_fn_type) (int);
+ CHECK_NON_NULL (result);
+ my_factorial_fn_type my_factorial_must_tail_call =
+ (my_factorial_fn_type)gcc_jit_result_get_code (result, "my_factorial_must_tail_call");
+ CHECK_NON_NULL (my_factorial_must_tail_call);
+ int val = my_factorial_must_tail_call (10);
+ note ("my_factorial_must_tail_call returned: %d", val);
+ CHECK_VALUE (val, 3628800);
+}
+
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 500071f94f1..2a6e101e9f2 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -726,7 +726,8 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
"atomic transaction", fn);
else
{
- if (!DECL_P (fn) || DECL_NAME (fn))
+ if ((!DECL_P (fn) || DECL_NAME (fn))
+ && TREE_CODE (fn) != SSA_NAME)
error_at (gimple_location (stmt),
"unsafe function call %qE within "
"atomic transaction", fn);
@@ -744,7 +745,8 @@ diagnose_tm_1 (gimple_stmt_iterator *gsi, bool *handled_ops_p,
"%<transaction_safe%> function", fn);
else
{
- if (!DECL_P (fn) || DECL_NAME (fn))
+ if ((!DECL_P (fn) || DECL_NAME (fn))
+ && TREE_CODE (fn) != SSA_NAME)
error_at (gimple_location (stmt),
"unsafe function call %qE within "
"%<transaction_safe%> function", fn);
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index 32f23013374..4884241134a 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -769,7 +769,7 @@ wide_int_constant_multiple_p (const widest_int &val, const widest_int &div,
if (val == 0)
{
- if (*mult_set && mult != 0)
+ if (*mult_set && *mult != 0)
return false;
*mult_set = true;
*mult = 0;
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 647be3937a3..8df9b08010f 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-into-ssa.h"
#include "builtins.h"
#include "internal-fn.h"
+#include "tree-dfa.h"
/* This pass serves two closely-related purposes:
@@ -349,6 +350,15 @@ edom_only_function (gcall *call)
return false;
}
}
+
+/* Return true if it is structurally possible to guard CALL. */
+
+static bool
+can_guard_call_p (gimple *call)
+{
+ return (!stmt_ends_bb_p (call)
+ || find_fallthru_edge (gimple_bb (call)->succs));
+}
/* A helper function to generate gimple statements for one bound
comparison, so that the built-in function is called whenever
@@ -747,11 +757,9 @@ gen_shrink_wrap_conditions (gcall *bi_call, vec<gimple *> conds,
#define ERR_PROB 0.01
/* Shrink-wrap BI_CALL so that it is only called when one of the NCONDS
- conditions in CONDS is false.
+ conditions in CONDS is false. */
- Return true on success, in which case the cfg will have been updated. */
-
-static bool
+static void
shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
unsigned int nconds)
{
@@ -795,11 +803,10 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
/* Now find the join target bb -- split bi_call_bb if needed. */
if (stmt_ends_bb_p (bi_call))
{
- /* If the call must be the last in the bb, don't split the block,
- it could e.g. have EH edges. */
+ /* We checked that there was a fallthrough edge in
+ can_guard_call_p. */
join_tgt_in_edge_from_call = find_fallthru_edge (bi_call_bb->succs);
- if (join_tgt_in_edge_from_call == NULL)
- return false;
+ gcc_assert (join_tgt_in_edge_from_call);
free_dominance_info (CDI_DOMINATORS);
}
else
@@ -898,28 +905,19 @@ shrink_wrap_one_built_in_call_with_conds (gcall *bi_call, vec <gimple *> conds,
" into error conditions.\n",
LOCATION_FILE (loc), LOCATION_LINE (loc));
}
-
- return true;
}
/* Shrink-wrap BI_CALL so that it is only called when it might set errno
- (but is always called if it would set errno).
-
- Return true on success, in which case the cfg will have been updated. */
+ (but is always called if it would set errno). */
-static bool
+static void
shrink_wrap_one_built_in_call (gcall *bi_call)
{
unsigned nconds = 0;
auto_vec<gimple *, 12> conds;
gen_shrink_wrap_conditions (bi_call, conds, &nconds);
- /* This can happen if the condition generator decides
- it is not beneficial to do the transformation. Just
- return false and do not do any transformation for
- the call. */
- if (nconds == 0)
- return false;
- return shrink_wrap_one_built_in_call_with_conds (bi_call, conds, nconds);
+ gcc_assert (nconds != 0);
+ shrink_wrap_one_built_in_call_with_conds (bi_call, conds, nconds);
}
/* Return true if built-in function call CALL could be implemented using
@@ -933,11 +931,6 @@ can_use_internal_fn (gcall *call)
if (!gimple_vdef (call))
return false;
- /* Punt if we can't conditionalize the call. */
- basic_block bb = gimple_bb (call);
- if (stmt_ends_bb_p (call) && !find_fallthru_edge (bb->succs))
- return false;
-
/* See whether there is an internal function for this built-in. */
if (replacement_internal_fn (call) == IFN_LAST)
return false;
@@ -951,18 +944,25 @@ can_use_internal_fn (gcall *call)
return true;
}
-/* Implement built-in function call CALL using an internal function.
- Return true on success, in which case the cfg will have changed. */
+/* Implement built-in function call CALL using an internal function. */
-static bool
+static void
use_internal_fn (gcall *call)
{
+ /* We'll be inserting another call with the same arguments after the
+ lhs has been set, so prevent any possible coalescing failure from
+ having both values live at once. See PR 71020. */
+ replace_abnormal_ssa_names (call);
+
unsigned nconds = 0;
auto_vec<gimple *, 12> conds;
if (can_test_argument_range (call))
- gen_shrink_wrap_conditions (call, conds, &nconds);
- if (nconds == 0 && !edom_only_function (call))
- return false;
+ {
+ gen_shrink_wrap_conditions (call, conds, &nconds);
+ gcc_assert (nconds != 0);
+ }
+ else
+ gcc_assert (edom_only_function (call));
internal_fn ifn = replacement_internal_fn (call);
gcc_assert (ifn != IFN_LAST);
@@ -1008,35 +1008,26 @@ use_internal_fn (gcall *call)
}
}
- if (!shrink_wrap_one_built_in_call_with_conds (call, conds, nconds))
- /* It's too late to back out now. */
- gcc_unreachable ();
- return true;
+ shrink_wrap_one_built_in_call_with_conds (call, conds, nconds);
}
/* The top level function for conditional dead code shrink
wrapping transformation. */
-static bool
+static void
shrink_wrap_conditional_dead_built_in_calls (vec<gcall *> calls)
{
- bool changed = false;
unsigned i = 0;
unsigned n = calls.length ();
- if (n == 0)
- return false;
-
for (; i < n ; i++)
{
gcall *bi_call = calls[i];
if (gimple_call_lhs (bi_call))
- changed |= use_internal_fn (bi_call);
+ use_internal_fn (bi_call);
else
- changed |= shrink_wrap_one_built_in_call (bi_call);
+ shrink_wrap_one_built_in_call (bi_call);
}
-
- return changed;
}
namespace {
@@ -1079,7 +1070,6 @@ pass_call_cdce::execute (function *fun)
{
basic_block bb;
gimple_stmt_iterator i;
- bool something_changed = false;
auto_vec<gcall *> cond_dead_built_in_calls;
FOR_EACH_BB_FN (bb, fun)
{
@@ -1096,7 +1086,8 @@ pass_call_cdce::execute (function *fun)
&& gimple_call_builtin_p (stmt, BUILT_IN_NORMAL)
&& (gimple_call_lhs (stmt)
? can_use_internal_fn (stmt)
- : can_test_argument_range (stmt)))
+ : can_test_argument_range (stmt))
+ && can_guard_call_p (stmt))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -1114,19 +1105,12 @@ pass_call_cdce::execute (function *fun)
if (!cond_dead_built_in_calls.exists ())
return 0;
- something_changed
- = shrink_wrap_conditional_dead_built_in_calls (cond_dead_built_in_calls);
-
- if (something_changed)
- {
- free_dominance_info (CDI_POST_DOMINATORS);
- /* As we introduced new control-flow we need to insert PHI-nodes
- for the call-clobbers of the remaining call. */
- mark_virtual_operands_for_renaming (fun);
- return TODO_update_ssa;
- }
-
- return 0;
+ shrink_wrap_conditional_dead_built_in_calls (cond_dead_built_in_calls);
+ free_dominance_info (CDI_POST_DOMINATORS);
+ /* As we introduced new control-flow we need to insert PHI-nodes
+ for the call-clobbers of the remaining call. */
+ mark_virtual_operands_for_renaming (fun);
+ return TODO_update_ssa;
}
} // anon namespace
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 4ce1eaa32b0..7c2ee78bdfb 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -2135,13 +2135,8 @@ remove_bb (basic_block bb)
}
else
{
- /* Release SSA definitions if we are in SSA. Note that we
- may be called when not in SSA. For example,
- final_cleanup calls this function via
- cleanup_tree_cfg. */
- if (gimple_in_ssa_p (cfun))
- release_defs (stmt);
-
+ /* Release SSA definitions. */
+ release_defs (stmt);
gsi_remove (&i, true);
}
@@ -4139,6 +4134,53 @@ verify_gimple_assign_ternary (gassign *stmt)
return false;
+ case BIT_INSERT_EXPR:
+ if (! useless_type_conversion_p (lhs_type, rhs1_type))
+ {
+ error ("type mismatch in BIT_INSERT_EXPR");
+ debug_generic_expr (lhs_type);
+ debug_generic_expr (rhs1_type);
+ return true;
+ }
+ if (! ((INTEGRAL_TYPE_P (rhs1_type)
+ && INTEGRAL_TYPE_P (rhs2_type))
+ || (VECTOR_TYPE_P (rhs1_type)
+ && types_compatible_p (TREE_TYPE (rhs1_type), rhs2_type))))
+ {
+ error ("not allowed type combination in BIT_INSERT_EXPR");
+ debug_generic_expr (rhs1_type);
+ debug_generic_expr (rhs2_type);
+ return true;
+ }
+ if (! tree_fits_uhwi_p (rhs3)
+ || ! tree_fits_uhwi_p (TYPE_SIZE (rhs2_type)))
+ {
+ error ("invalid position or size in BIT_INSERT_EXPR");
+ return true;
+ }
+ if (INTEGRAL_TYPE_P (rhs1_type))
+ {
+ unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (rhs3);
+ if (bitpos >= TYPE_PRECISION (rhs1_type)
+ || (bitpos + TYPE_PRECISION (rhs2_type)
+ > TYPE_PRECISION (rhs1_type)))
+ {
+ error ("insertion out of range in BIT_INSERT_EXPR");
+ return true;
+ }
+ }
+ else if (VECTOR_TYPE_P (rhs1_type))
+ {
+ unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (rhs3);
+ unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (TYPE_SIZE (rhs2_type));
+ if (bitpos % bitsize != 0)
+ {
+ error ("vector insertion not at element boundary");
+ return true;
+ }
+ }
+ return false;
+
case DOT_PROD_EXPR:
case REALIGN_LOAD_EXPR:
/* FIXME. */
diff --git a/gcc/tree-chkp.c b/gcc/tree-chkp.c
index 3fba12c2ae4..4ca2d34607c 100644
--- a/gcc/tree-chkp.c
+++ b/gcc/tree-chkp.c
@@ -1853,7 +1853,9 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
/* If function decl is available then use it for
formal arguments list. Otherwise use function type. */
- if (fndecl && DECL_ARGUMENTS (fndecl))
+ if (fndecl
+ && DECL_ARGUMENTS (fndecl)
+ && gimple_call_fntype (call) == TREE_TYPE (fndecl))
first_formal_arg = DECL_ARGUMENTS (fndecl);
else
{
@@ -1929,7 +1931,16 @@ chkp_add_bounds_to_call_stmt (gimple_stmt_iterator *gsi)
{
tree new_decl = chkp_maybe_create_clone (fndecl)->decl;
gimple_call_set_fndecl (new_call, new_decl);
- gimple_call_set_fntype (new_call, TREE_TYPE (new_decl));
+ /* In case of a type cast we should modify used function
+ type instead of using type of new fndecl. */
+ if (gimple_call_fntype (call) != TREE_TYPE (fndecl))
+ {
+ tree type = gimple_call_fntype (call);
+ type = chkp_copy_function_type_adding_bounds (type);
+ gimple_call_set_fntype (new_call, type);
+ }
+ else
+ gimple_call_set_fntype (new_call, TREE_TYPE (new_decl));
}
/* For indirect call we should fix function pointer type if
pass some bounds. */
@@ -3646,6 +3657,7 @@ chkp_find_bounds_1 (tree ptr, tree ptr_src, gimple_stmt_iterator *iter)
break;
case ADDR_EXPR:
+ case WITH_SIZE_EXPR:
bounds = chkp_make_addressed_object_bounds (TREE_OPERAND (ptr_src, 0), iter);
break;
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index d781a8aa014..d7baf227c7d 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -604,6 +604,21 @@ extract_component (gimple_stmt_iterator *gsi, tree t, bool imagpart_p,
case COMPLEX_EXPR:
gcc_unreachable ();
+ case BIT_FIELD_REF:
+ {
+ tree inner_type = TREE_TYPE (TREE_TYPE (t));
+ t = unshare_expr (t);
+ TREE_TYPE (t) = inner_type;
+ TREE_OPERAND (t, 1) = TYPE_SIZE (inner_type);
+ if (imagpart_p)
+ TREE_OPERAND (t, 2) = size_binop (PLUS_EXPR, TREE_OPERAND (t, 2),
+ TYPE_SIZE (inner_type));
+ if (gimple_p)
+ t = force_gimple_operand_gsi (gsi, t, true, NULL, true,
+ GSI_SAME_STMT);
+ return t;
+ }
+
case VAR_DECL:
case RESULT_DECL:
case PARM_DECL:
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
index 6d573d7b6d2..b0699284e0d 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -81,11 +81,14 @@ struct die_struct;
/* The function does not lead to calls within current function unit. */
#define ECF_LEAF (1 << 10)
+/* Nonzero if this call returns its first argument. */
+#define ECF_RET1 (1 << 11)
+
/* Nonzero if this call does not affect transactions. */
-#define ECF_TM_PURE (1 << 11)
+#define ECF_TM_PURE (1 << 12)
/* Nonzero if this call is into the transaction runtime library. */
-#define ECF_TM_BUILTIN (1 << 12)
+#define ECF_TM_BUILTIN (1 << 13)
/* Call argument flags. */
/* Nonzero if the argument is not dereferenced recursively, thus only
@@ -767,7 +770,9 @@ enum operand_equal_flag {
OEP_MATCH_SIDE_EFFECTS = 4,
OEP_ADDRESS_OF = 8,
/* Internal within operand_equal_p: */
- OEP_NO_HASH_CHECK = 16
+ OEP_NO_HASH_CHECK = 16,
+ /* Internal within inchash::add_expr: */
+ OEP_HASH_CHECK = 32
};
/* Enum and arrays used for tree allocation stats.
@@ -996,6 +1001,9 @@ struct GTY(()) tree_base {
SSA_NAME_ANTI_RANGE_P in
SSA_NAME
+ MUST_TAIL_CALL in
+ CALL_EXPR
+
public_flag:
TREE_OVERFLOW in
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index d6d9ffcaa34..ed28ca1d6e5 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -1538,8 +1538,13 @@ initialize_data_dependence_relation (struct data_reference *a,
}
/* If the references do not access the same object, we do not know
- whether they alias or not. */
- if (!operand_equal_p (DR_BASE_OBJECT (a), DR_BASE_OBJECT (b), 0))
+ whether they alias or not. We do not care about TBAA or alignment
+ info so we can use OEP_ADDRESS_OF to avoid false negatives.
+ But the accesses have to use compatible types as otherwise the
+ built indices would not match. */
+ if (!operand_equal_p (DR_BASE_OBJECT (a), DR_BASE_OBJECT (b), OEP_ADDRESS_OF)
+ || !types_compatible_p (TREE_TYPE (DR_BASE_OBJECT (a)),
+ TREE_TYPE (DR_BASE_OBJECT (b))))
{
DDR_ARE_DEPENDENT (res) = chrec_dont_know;
return res;
diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c
index f6986c1f0ca..9a3b072ae2f 100644
--- a/gcc/tree-dfa.c
+++ b/gcc/tree-dfa.c
@@ -823,6 +823,29 @@ stmt_references_abnormal_ssa_name (gimple *stmt)
return false;
}
+/* If STMT takes any abnormal PHI values as input, replace them with
+ local copies. */
+
+void
+replace_abnormal_ssa_names (gimple *stmt)
+{
+ ssa_op_iter oi;
+ use_operand_p use_p;
+
+ FOR_EACH_SSA_USE_OPERAND (use_p, stmt, oi, SSA_OP_USE)
+ {
+ tree op = USE_FROM_PTR (use_p);
+ if (TREE_CODE (op) == SSA_NAME && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ tree new_name = make_ssa_name (TREE_TYPE (op));
+ gassign *assign = gimple_build_assign (new_name, op);
+ gsi_insert_before (&gsi, assign, GSI_SAME_STMT);
+ SET_USE (use_p, new_name);
+ }
+ }
+}
+
/* Pair of tree and a sorting index, for dump_enumerated_decls. */
struct GTY(()) numbered_tree
{
diff --git a/gcc/tree-dfa.h b/gcc/tree-dfa.h
index c94dc557796..08864cf470b 100644
--- a/gcc/tree-dfa.h
+++ b/gcc/tree-dfa.h
@@ -35,6 +35,7 @@ extern tree get_addr_base_and_unit_offset_1 (tree, HOST_WIDE_INT *,
tree (*) (tree));
extern tree get_addr_base_and_unit_offset (tree, HOST_WIDE_INT *);
extern bool stmt_references_abnormal_ssa_name (gimple *);
+extern void replace_abnormal_ssa_names (gimple *);
extern void dump_enumerated_decls (FILE *, int);
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 32ced164081..3bfa69cfb50 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -106,6 +106,8 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree-data-ref.h"
#include "tree-scalar-evolution.h"
+#include "tree-ssa-loop.h"
+#include "tree-ssa-loop-niter.h"
#include "tree-ssa-loop-ivopts.h"
#include "tree-ssa-address.h"
#include "dbgcnt.h"
@@ -113,11 +115,23 @@ along with GCC; see the file COPYING3. If not see
#include "varasm.h"
#include "builtins.h"
#include "params.h"
-
+#include "cfganal.h"
+
+/* Only handle PHIs with no more arguments unless we are asked to by
+ simd pragma. */
+#define MAX_PHI_ARG_NUM \
+ ((unsigned) PARAM_VALUE (PARAM_MAX_TREE_IF_CONVERSION_PHI_ARGS))
+
/* Indicate if new load/store that needs to be predicated is introduced
during if conversion. */
static bool any_pred_load_store;
+/* Indicate if there are any complicated PHIs that need to be handled in
+ if-conversion. Complicated PHI has more than two arguments and can't
+ be degenerated to two arguments PHI. See more information in comment
+ before phi_convertible_by_degenerating_args. */
+static bool any_complicated_phi;
+
/* Hash for struct innermost_loop_behavior. It depends on the user to
free the memory. */
@@ -172,9 +186,6 @@ innermost_loop_behavior_hash::equal (const value_type &e1,
/* List of basic blocks in if-conversion-suitable order. */
static basic_block *ifc_bbs;
-/* Apply more aggressive (extended) if-conversion if true. */
-static bool aggressive_if_conv;
-
/* Hash table to store <DR's innermost loop behavior, DR> pairs. */
static hash_map<innermost_loop_behavior_hash,
data_reference_p> *innermost_DR_map;
@@ -246,7 +257,7 @@ set_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
static inline void
add_bb_predicate_gimplified_stmts (basic_block bb, gimple_seq stmts)
{
- gimple_seq_add_seq
+ gimple_seq_add_seq_without_update
(&(((struct bb_predicate *) bb->aux)->predicate_gimplified_stmts), stmts);
}
@@ -269,10 +280,11 @@ release_bb_predicate (basic_block bb)
gimple_seq stmts = bb_predicate_gimplified_stmts (bb);
if (stmts)
{
- gimple_stmt_iterator i;
+ if (flag_checking)
+ for (gimple_stmt_iterator i = gsi_start (stmts);
+ !gsi_end_p (i); gsi_next (&i))
+ gcc_assert (! gimple_use_ops (gsi_stmt (i)));
- for (i = gsi_start (stmts); !gsi_end_p (i); gsi_next (&i))
- free_stmt_operands (cfun, gsi_stmt (i));
set_bb_predicate_gimplified_stmts (bb, NULL);
}
}
@@ -408,24 +420,6 @@ fold_or_predicates (location_t loc, tree c1, tree c2)
return fold_build2_loc (loc, TRUTH_OR_EXPR, boolean_type_node, c1, c2);
}
-/* Returns true if N is either a constant or a SSA_NAME. */
-
-static bool
-constant_or_ssa_name (tree n)
-{
- switch (TREE_CODE (n))
- {
- case SSA_NAME:
- case INTEGER_CST:
- case REAL_CST:
- case COMPLEX_CST:
- case VECTOR_CST:
- return true;
- default:
- return false;
- }
-}
-
/* Returns either a COND_EXPR or the folded expression if the folded
expression is a MIN_EXPR, a MAX_EXPR, an ABS_EXPR,
a constant or a SSA_NAME. */
@@ -446,22 +440,21 @@ fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
&& (integer_zerop (op1)))
cond = op0;
}
- cond_expr = fold_ternary (COND_EXPR, type, cond,
- rhs, lhs);
+ cond_expr = fold_ternary (COND_EXPR, type, cond, rhs, lhs);
if (cond_expr == NULL_TREE)
return build3 (COND_EXPR, type, cond, rhs, lhs);
STRIP_USELESS_TYPE_CONVERSION (cond_expr);
- if (constant_or_ssa_name (cond_expr))
+ if (is_gimple_val (cond_expr))
return cond_expr;
if (TREE_CODE (cond_expr) == ABS_EXPR)
{
rhs1 = TREE_OPERAND (cond_expr, 1);
STRIP_USELESS_TYPE_CONVERSION (rhs1);
- if (constant_or_ssa_name (rhs1))
+ if (is_gimple_val (rhs1))
return build1 (ABS_EXPR, type, rhs1);
}
@@ -472,8 +465,7 @@ fold_build_cond_expr (tree type, tree cond, tree rhs, tree lhs)
STRIP_USELESS_TYPE_CONVERSION (lhs1);
rhs1 = TREE_OPERAND (cond_expr, 1);
STRIP_USELESS_TYPE_CONVERSION (rhs1);
- if (constant_or_ssa_name (rhs1)
- && constant_or_ssa_name (lhs1))
+ if (is_gimple_val (rhs1) && is_gimple_val (lhs1))
return build2 (TREE_CODE (cond_expr), type, lhs1, rhs1);
}
return build3 (COND_EXPR, type, cond, rhs, lhs);
@@ -639,13 +631,9 @@ phi_convertible_by_degenerating_args (gphi *phi)
}
/* Return true when PHI is if-convertible. PHI is part of loop LOOP
- and it belongs to basic block BB.
-
- PHI is not if-convertible if:
- - it has more than 2 arguments.
-
- When the aggressive_if_conv is set, PHI can have more than
- two arguments. */
+ and it belongs to basic block BB. Note at this point, it is sure
+ that PHI is if-convertible. This function updates global variable
+ ANY_COMPLICATED_PHI if PHI is complicated. */
static bool
if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi)
@@ -656,17 +644,10 @@ if_convertible_phi_p (struct loop *loop, basic_block bb, gphi *phi)
print_gimple_stmt (dump_file, phi, 0, TDF_SLIM);
}
- if (bb != loop->header)
- {
- if (gimple_phi_num_args (phi) > 2
- && !aggressive_if_conv
- && !phi_convertible_by_degenerating_args (phi))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Phi can't be predicated by single cond.\n");
- return false;
- }
- }
+ if (bb != loop->header
+ && gimple_phi_num_args (phi) > 2
+ && !phi_convertible_by_degenerating_args (phi))
+ any_complicated_phi = true;
return true;
}
@@ -740,6 +721,105 @@ hash_memrefs_baserefs_and_store_DRs_read_written_info (data_reference_p a)
}
}
+/* Return TRUE if can prove the index IDX of an array reference REF is
+ within array bound. Return false otherwise. */
+
+static bool
+idx_within_array_bound (tree ref, tree *idx, void *dta)
+{
+ bool overflow;
+ widest_int niter, valid_niter, delta, wi_step;
+ tree ev, init, step;
+ tree low, high;
+ struct loop *loop = (struct loop*) dta;
+
+ /* Only support within-bound access for array references. */
+ if (TREE_CODE (ref) != ARRAY_REF)
+ return false;
+
+ /* For arrays at the end of the structure, we are not guaranteed that they
+ do not really extend over their declared size. However, for arrays of
+ size greater than one, this is unlikely to be intended. */
+ if (array_at_struct_end_p (ref))
+ return false;
+
+ ev = analyze_scalar_evolution (loop, *idx);
+ ev = instantiate_parameters (loop, ev);
+ init = initial_condition (ev);
+ step = evolution_part_in_loop_num (ev, loop->num);
+
+ if (!init || TREE_CODE (init) != INTEGER_CST
+ || (step && TREE_CODE (step) != INTEGER_CST))
+ return false;
+
+ low = array_ref_low_bound (ref);
+ high = array_ref_up_bound (ref);
+
+ /* The case of nonconstant bounds could be handled, but it would be
+ complicated. */
+ if (TREE_CODE (low) != INTEGER_CST
+ || !high || TREE_CODE (high) != INTEGER_CST)
+ return false;
+
+ /* Check if the intial idx is within bound. */
+ if (wi::to_widest (init) < wi::to_widest (low)
+ || wi::to_widest (init) > wi::to_widest (high))
+ return false;
+
+ /* The idx is always within bound. */
+ if (!step || integer_zerop (step))
+ return true;
+
+ if (!max_loop_iterations (loop, &niter))
+ return false;
+
+ if (wi::to_widest (step) < 0)
+ {
+ delta = wi::to_widest (init) - wi::to_widest (low);
+ wi_step = -wi::to_widest (step);
+ }
+ else
+ {
+ delta = wi::to_widest (high) - wi::to_widest (init);
+ wi_step = wi::to_widest (step);
+ }
+
+ valid_niter = wi::div_floor (delta, wi_step, SIGNED, &overflow);
+ /* The iteration space of idx is within array bound. */
+ if (!overflow && niter <= valid_niter)
+ return true;
+
+ return false;
+}
+
+/* Return TRUE if ref is a within bound array reference. */
+
+static bool
+ref_within_array_bound (gimple *stmt, tree ref)
+{
+ struct loop *loop = loop_containing_stmt (stmt);
+
+ gcc_assert (loop != NULL);
+ return for_each_index (&ref, idx_within_array_bound, loop);
+}
+
+
+/* Given a memory reference expression T, return TRUE if base object
+ it refers to is writable. The base object of a memory reference
+ is the main object being referenced, which is returned by function
+ get_base_address. */
+
+static bool
+base_object_writable (tree ref)
+{
+ tree base_tree = get_base_address (ref);
+
+ return (base_tree
+ && DECL_P (base_tree)
+ && decl_binds_to_current_def_p (base_tree)
+ && !TREE_READONLY (base_tree));
+}
+
/* Return true when the memory references of STMT won't trap in the
if-converted code. There are two things that we have to check for:
@@ -787,8 +867,13 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
if (DR_W_UNCONDITIONALLY (*master_dr))
return true;
- /* If a is unconditionally accessed then ... */
- if (DR_RW_UNCONDITIONALLY (*master_dr))
+ /* If a is unconditionally accessed then ...
+
+ Even a is conditional access, we can treat it as an unconditional
+ one if it's an array reference and all its index are within array
+ bound. */
+ if (DR_RW_UNCONDITIONALLY (*master_dr)
+ || ref_within_array_bound (stmt, DR_REF (a)))
{
/* an unconditional read won't trap. */
if (DR_IS_READ (a))
@@ -799,16 +884,11 @@ ifcvt_memrefs_wont_trap (gimple *stmt, vec<data_reference_p> drs)
if (base_master_dr
&& DR_BASE_W_UNCONDITIONALLY (*base_master_dr))
return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES);
- else
- {
- /* or the base is know to be not readonly. */
- tree base_tree = get_base_address (DR_REF (a));
- if (DECL_P (base_tree)
- && decl_binds_to_current_def_p (base_tree)
- && ! TREE_READONLY (base_tree))
- return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES);
- }
+ /* or the base is known to be not readonly. */
+ else if (base_object_writable (DR_REF (a)))
+ return PARAM_VALUE (PARAM_ALLOW_STORE_DATA_RACES);
}
+
return false;
}
@@ -1012,8 +1092,6 @@ has_pred_critical_p (basic_block bb)
- it is after the exit block but before the latch,
- its edges are not normal.
- Last restriction is valid if aggressive_if_conv is false.
-
EXIT_BB is the basic block containing the exit of the LOOP. BB is
inside LOOP. */
@@ -1062,19 +1140,6 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
return false;
}
- /* At least one incoming edge has to be non-critical as otherwise edge
- predicates are not equal to basic-block predicates of the edge
- source. This check is skipped if aggressive_if_conv is true. */
- if (!aggressive_if_conv
- && EDGE_COUNT (bb->preds) > 1
- && bb != loop->header
- && all_preds_critical_p (bb))
- {
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "only critical predecessors\n");
- return false;
- }
-
return true;
}
@@ -1258,7 +1323,6 @@ if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs)
return false;
calculate_dominance_info (CDI_DOMINATORS);
- calculate_dominance_info (CDI_POST_DOMINATORS);
/* Allow statements that can be handled during if-conversion. */
ifc_bbs = get_loop_body_in_if_conv_order (loop);
@@ -1306,6 +1370,7 @@ if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs)
= new hash_map<innermost_loop_behavior_hash, data_reference_p>;
baseref_DR_map = new hash_map<tree_operand_hash, data_reference_p>;
+ calculate_dominance_info (CDI_POST_DOMINATORS);
predicate_bbs (loop);
for (i = 0; refs->iterate (i, &dr); i++)
@@ -1357,9 +1422,6 @@ if_convertible_loop_p_1 (struct loop *loop, vec<data_reference_p> *refs)
return false;
}
- for (i = 0; i < loop->num_nodes; i++)
- free_bb_predicate (ifc_bbs[i]);
-
/* Checking PHIs needs to be done after stmts, as the fact whether there
are any masked loads or stores affects the tests. */
for (i = 0; i < loop->num_nodes; i++)
@@ -2234,7 +2296,6 @@ combine_blocks (struct loop *loop)
edge e;
edge_iterator ei;
- predicate_bbs (loop);
remove_conditions_and_labels (loop);
insert_gimplified_predicates (loop);
predicate_all_scalar_phis (loop);
@@ -2364,13 +2425,23 @@ version_loop_for_if_conversion (struct loop *loop)
integer_zero_node);
gimple_call_set_lhs (g, cond);
+ /* Save BB->aux around loop_version as that uses the same field. */
+ void **saved_preds = XALLOCAVEC (void *, loop->num_nodes);
+ for (unsigned i = 0; i < loop->num_nodes; i++)
+ saved_preds[i] = ifc_bbs[i]->aux;
+
initialize_original_copy_tables ();
new_loop = loop_version (loop, cond, &cond_bb,
REG_BR_PROB_BASE, REG_BR_PROB_BASE,
REG_BR_PROB_BASE, true);
free_original_copy_tables ();
+
+ for (unsigned i = 0; i < loop->num_nodes; i++)
+ ifc_bbs[i]->aux = saved_preds[i];
+
if (new_loop == NULL)
return false;
+
new_loop->dont_vectorize = true;
new_loop->force_vectorize = false;
gsi = gsi_last_bb (cond_bb);
@@ -2380,11 +2451,16 @@ version_loop_for_if_conversion (struct loop *loop)
return true;
}
-/* Performs splitting of critical edges if aggressive_if_conv is true.
- Returns false if loop won't be if converted and true otherwise. */
+/* Performs splitting of critical edges. Skip splitting and return false
+ if LOOP will not be converted because:
+
+ - LOOP is not well formed.
+ - LOOP has PHI with more than MAX_PHI_ARG_NUM arguments.
+
+ Last restriction is valid only if AGGRESSIVE_IF_CONV is false. */
static bool
-ifcvt_split_critical_edges (struct loop *loop)
+ifcvt_split_critical_edges (struct loop *loop, bool aggressive_if_conv)
{
basic_block *body;
basic_block bb;
@@ -2393,30 +2469,50 @@ ifcvt_split_critical_edges (struct loop *loop)
gimple *stmt;
edge e;
edge_iterator ei;
+ auto_vec<edge> critical_edges;
- if (num <= 2)
- return false;
- if (loop->inner)
- return false;
- if (!single_exit (loop))
+ /* Loop is not well formed. */
+ if (num <= 2 || loop->inner || !single_exit (loop))
return false;
body = get_loop_body (loop);
for (i = 0; i < num; i++)
{
bb = body[i];
- if (bb == loop->latch
- || bb_with_exit_edge_p (loop, bb))
+ if (!aggressive_if_conv
+ && phi_nodes (bb)
+ && EDGE_COUNT (bb->preds) > MAX_PHI_ARG_NUM)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file,
+ "BB %d has complicated PHI with more than %u args.\n",
+ bb->index, MAX_PHI_ARG_NUM);
+
+ free (body);
+ return false;
+ }
+ if (bb == loop->latch || bb_with_exit_edge_p (loop, bb))
continue;
+
stmt = last_stmt (bb);
/* Skip basic blocks not ending with conditional branch. */
- if (!(stmt && gimple_code (stmt) == GIMPLE_COND))
+ if (!stmt || gimple_code (stmt) != GIMPLE_COND)
continue;
+
FOR_EACH_EDGE (e, ei, bb->succs)
if (EDGE_CRITICAL_P (e) && e->dest->loop_father == loop)
- split_edge (e);
+ critical_edges.safe_push (e);
}
free (body);
+
+ while (critical_edges.length () > 0)
+ {
+ e = critical_edges.pop ();
+ /* Don't split if bb can be predicated along non-critical edge. */
+ if (EDGE_COUNT (e->dest->preds) > 2 || all_preds_critical_p (e->dest))
+ split_edge (e);
+ }
+
return true;
}
@@ -2473,6 +2569,9 @@ ifcvt_walk_pattern_tree (tree var, vec<gimple *> *defuse_list,
enum tree_code code;
gimple *def_stmt;
+ if (TREE_CODE (var) != SSA_NAME)
+ return;
+
def_stmt = SSA_NAME_DEF_STMT (var);
if (gimple_code (def_stmt) != GIMPLE_ASSIGN)
return;
@@ -2559,8 +2658,8 @@ ifcvt_repair_bool_pattern (basic_block bb)
tree rhs;
gimple *stmt;
gimple_stmt_iterator gsi;
- vec<gimple *> defuse_list = vNULL;
- vec<gimple *> pattern_roots = vNULL;
+ auto_vec<gimple *> defuse_list;
+ auto_vec<gimple *> pattern_roots;
bool repeat = true;
int niter = 0;
unsigned int ix;
@@ -2713,12 +2812,16 @@ static unsigned int
tree_if_conversion (struct loop *loop)
{
unsigned int todo = 0;
+ bool aggressive_if_conv;
+
ifc_bbs = NULL;
any_pred_load_store = false;
+ any_complicated_phi = false;
- /* Set up aggressive if-conversion for loops marked with simd pragma. */
+ /* Apply more aggressive if-conversion when loop or its outer loop were
+ marked with simd pragma. When that's the case, we try to if-convert
+ loop containing PHIs with more than MAX_PHI_ARG_NUM arguments. */
aggressive_if_conv = loop->force_vectorize;
- /* Check either outer loop was marked with simd pragma. */
if (!aggressive_if_conv)
{
struct loop *outer_loop = loop_outer (loop);
@@ -2726,20 +2829,20 @@ tree_if_conversion (struct loop *loop)
aggressive_if_conv = true;
}
- if (aggressive_if_conv)
- if (!ifcvt_split_critical_edges (loop))
- goto cleanup;
+ if (!ifcvt_split_critical_edges (loop, aggressive_if_conv))
+ goto cleanup;
if (!if_convertible_loop_p (loop)
|| !dbg_cnt (if_conversion_tree))
goto cleanup;
- if (any_pred_load_store
+ if ((any_pred_load_store || any_complicated_phi)
&& ((!flag_tree_loop_vectorize && !loop->force_vectorize)
|| loop->dont_vectorize))
goto cleanup;
- if (any_pred_load_store && !version_loop_for_if_conversion (loop))
+ if ((any_pred_load_store || any_complicated_phi)
+ && !version_loop_for_if_conversion (loop))
goto cleanup;
/* Now all statements are if-convertible. Combine all the basic
@@ -2749,11 +2852,8 @@ tree_if_conversion (struct loop *loop)
/* Delete dead predicate computations and repair tree correspondent
to bool pattern to delete multiple uses of predicates. */
- if (aggressive_if_conv)
- {
- ifcvt_local_dce (loop->header);
- ifcvt_repair_bool_pattern (loop->header);
- }
+ ifcvt_local_dce (loop->header);
+ ifcvt_repair_bool_pattern (loop->header);
todo |= TODO_cleanup_cfg;
mark_virtual_operands_for_renaming (cfun);
@@ -2823,6 +2923,14 @@ pass_if_conversion::execute (function *fun)
if (number_of_loops (fun) <= 1)
return 0;
+ /* If there are infinite loops, during CDI_POST_DOMINATORS computation
+ we can pick pretty much random bb inside of the infinite loop that
+ has the fake edge. If we are unlucky enough, this can confuse the
+ add_to_predicate_list post-dominator check to optimize as if that
+ bb or some other one is a join block when it actually is not.
+ See PR70916. */
+ connect_infinite_loops_to_exit ();
+
FOR_EACH_LOOP (loop, 0)
if (flag_tree_loop_if_convert == 1
|| flag_tree_loop_if_convert_stores == 1
@@ -2830,6 +2938,8 @@ pass_if_conversion::execute (function *fun)
&& !loop->dont_vectorize))
todo |= tree_if_conversion (loop);
+ remove_fake_exit_edges ();
+
if (flag_checking)
{
basic_block bb;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 015a9074b78..07f6a83ff7c 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -840,7 +840,7 @@ is_parm (tree decl)
static unsigned short
remap_dependence_clique (copy_body_data *id, unsigned short clique)
{
- if (clique == 0)
+ if (clique == 0 || processing_debug_stmt)
return 0;
if (!id->dependence_map)
id->dependence_map = new hash_map<dependence_hash, unsigned short>;
@@ -2063,7 +2063,7 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
&& id->dst_node->definition
&& (fn = gimple_call_fndecl (stmt)) != NULL)
{
- struct cgraph_node *dest = cgraph_node::get (fn);
+ struct cgraph_node *dest = cgraph_node::get_create (fn);
/* We have missing edge in the callgraph. This can happen
when previous inlining turned an indirect call into a
@@ -2456,8 +2456,9 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
if (src_cfun->gimple_df)
{
init_tree_ssa (cfun);
- cfun->gimple_df->in_ssa_p = true;
- init_ssa_operands (cfun);
+ cfun->gimple_df->in_ssa_p = src_cfun->gimple_df->in_ssa_p;
+ if (cfun->gimple_df->in_ssa_p)
+ init_ssa_operands (cfun);
}
}
@@ -3940,6 +3941,10 @@ estimate_operator_cost (enum tree_code code, eni_weights *weights,
return weights->div_mod_cost;
return 1;
+ /* Bit-field insertion needs several shift and mask operations. */
+ case BIT_INSERT_EXPR:
+ return 3;
+
default:
/* We expect a copy assignment with no operator. */
gcc_assert (get_gimple_rhs_class (code) == GIMPLE_SINGLE_RHS);
@@ -4449,6 +4454,45 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
}
goto egress;
}
+ id->src_node = cg_edge->callee;
+
+ /* If callee is thunk, all we need is to adjust the THIS pointer
+ and redirect to function being thunked. */
+ if (id->src_node->thunk.thunk_p)
+ {
+ cgraph_edge *edge;
+ tree virtual_offset = NULL;
+ int freq = cg_edge->frequency;
+ gcov_type count = cg_edge->count;
+ tree op;
+ gimple_stmt_iterator iter = gsi_for_stmt (stmt);
+
+ cg_edge->remove ();
+ edge = id->src_node->callees->clone (id->dst_node, call_stmt,
+ gimple_uid (stmt),
+ REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
+ true);
+ edge->frequency = freq;
+ edge->count = count;
+ if (id->src_node->thunk.virtual_offset_p)
+ virtual_offset = size_int (id->src_node->thunk.virtual_value);
+ op = create_tmp_reg_fn (cfun, TREE_TYPE (gimple_call_arg (stmt, 0)),
+ NULL);
+ gsi_insert_before (&iter, gimple_build_assign (op,
+ gimple_call_arg (stmt, 0)),
+ GSI_NEW_STMT);
+ gcc_assert (id->src_node->thunk.this_adjusting);
+ op = thunk_adjust (&iter, op, 1, id->src_node->thunk.fixed_offset,
+ virtual_offset);
+
+ gimple_call_set_arg (stmt, 0, op);
+ gimple_call_set_fndecl (stmt, edge->callee->decl);
+ update_stmt (stmt);
+ id->src_node->remove ();
+ expand_call_inline (bb, stmt, id);
+ maybe_remove_unused_call_args (cfun, stmt);
+ return true;
+ }
fn = cg_edge->callee->decl;
cg_edge->callee->get_untransformed_body ();
@@ -4522,7 +4566,6 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
/* Record the function we are about to inline. */
id->src_fn = fn;
- id->src_node = cg_edge->callee;
id->src_cfun = DECL_STRUCT_FUNCTION (fn);
id->call_stmt = stmt;
@@ -4707,7 +4750,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
{
tree name = gimple_call_lhs (stmt);
tree var = SSA_NAME_VAR (name);
- tree def = ssa_default_def (cfun, var);
+ tree def = var ? ssa_default_def (cfun, var) : NULL;
if (def)
{
@@ -4718,6 +4761,11 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id)
}
else
{
+ if (!var)
+ {
+ tree var = create_tmp_reg_fn (cfun, TREE_TYPE (name), NULL);
+ SET_SSA_NAME_VAR_OR_IDENTIFIER (name, var);
+ }
/* Otherwise make this variable undefined. */
gsi_remove (&stmt_gsi, true);
set_ssa_default_def (cfun, var, name);
@@ -5119,10 +5167,21 @@ replace_locals_op (tree *tp, int *walk_subtrees, void *data)
tree *n;
tree expr = *tp;
+ /* For recursive invocations this is no longer the LHS itself. */
+ bool is_lhs = wi->is_lhs;
+ wi->is_lhs = false;
+
+ if (TREE_CODE (expr) == SSA_NAME)
+ {
+ *tp = remap_ssa_name (*tp, id);
+ *walk_subtrees = 0;
+ if (is_lhs)
+ SSA_NAME_DEF_STMT (*tp) = gsi_stmt (wi->gsi);
+ }
/* Only a local declaration (variable or label). */
- if ((TREE_CODE (expr) == VAR_DECL
- && !TREE_STATIC (expr))
- || TREE_CODE (expr) == LABEL_DECL)
+ else if ((TREE_CODE (expr) == VAR_DECL
+ && !TREE_STATIC (expr))
+ || TREE_CODE (expr) == LABEL_DECL)
{
/* Lookup the declaration. */
n = st->get (expr);
@@ -5262,6 +5321,7 @@ copy_gimple_seq_and_replace_locals (gimple_seq seq)
memset (&id, 0, sizeof (id));
id.src_fn = current_function_decl;
id.dst_fn = current_function_decl;
+ id.src_cfun = cfun;
id.decl_map = new hash_map<tree, tree>;
id.debug_map = NULL;
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 8dfcc333c93..f83cad2e936 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -666,6 +666,8 @@ mark_def_sites (basic_block bb, gimple *stmt, bitmap kills)
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
{
tree sym = USE_FROM_PTR (use_p);
+ if (TREE_CODE (sym) == SSA_NAME)
+ continue;
gcc_checking_assert (DECL_P (sym));
if (!bitmap_bit_p (kills, DECL_UID (sym)))
set_livein_block (sym, bb);
@@ -676,6 +678,8 @@ mark_def_sites (basic_block bb, gimple *stmt, bitmap kills)
each def to the set of killed symbols. */
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
{
+ if (TREE_CODE (def) == SSA_NAME)
+ continue;
gcc_checking_assert (DECL_P (def));
set_def_block (def, bb, false);
bitmap_set_bit (kills, DECL_UID (def));
@@ -1310,6 +1314,8 @@ rewrite_stmt (gimple_stmt_iterator *si)
FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_ALL_USES)
{
tree var = USE_FROM_PTR (use_p);
+ if (TREE_CODE (var) == SSA_NAME)
+ continue;
gcc_checking_assert (DECL_P (var));
SET_USE (use_p, get_reaching_def (var));
}
@@ -1323,6 +1329,8 @@ rewrite_stmt (gimple_stmt_iterator *si)
tree name;
tree tracked_var;
+ if (TREE_CODE (var) == SSA_NAME)
+ continue;
gcc_checking_assert (DECL_P (var));
if (gimple_clobber_p (stmt)
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 3e1074090ac..dbc8e3cdbdc 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -312,7 +312,7 @@ create_rdg_flow_edges (struct graph *rdg)
/* Creates the edges of the reduced dependence graph RDG. */
static void
-create_rdg_cd_edges (struct graph *rdg, control_dependences *cd)
+create_rdg_cd_edges (struct graph *rdg, control_dependences *cd, loop_p loop)
{
int i;
@@ -324,6 +324,7 @@ create_rdg_cd_edges (struct graph *rdg, control_dependences *cd)
edge_iterator ei;
edge e;
FOR_EACH_EDGE (e, ei, gimple_bb (stmt)->preds)
+ if (flow_bb_inside_loop_p (loop, e->src))
create_edge_for_control_dependence (rdg, e->src, i, cd);
}
else
@@ -455,7 +456,7 @@ build_rdg (vec<loop_p> loop_nest, control_dependences *cd)
create_rdg_flow_edges (rdg);
if (cd)
- create_rdg_cd_edges (rdg, cd);
+ create_rdg_cd_edges (rdg, cd, loop_nest[0]);
datarefs.release ();
@@ -917,9 +918,9 @@ destroy_loop (struct loop *loop)
recompute_dominator (CDI_DOMINATORS, dest));
}
-/* Generates code for PARTITION. */
+/* Generates code for PARTITION. Return whether LOOP needs to be destroyed. */
-static void
+static bool
generate_code_for_partition (struct loop *loop,
partition *partition, bool copy_p)
{
@@ -930,7 +931,7 @@ generate_code_for_partition (struct loop *loop,
gcc_assert (!partition_reduction_p (partition)
|| !copy_p);
generate_loops_for_partition (loop, partition, copy_p);
- return;
+ return false;
case PKIND_MEMSET:
generate_memset_builtin (loop, partition);
@@ -947,7 +948,8 @@ generate_code_for_partition (struct loop *loop,
/* Common tail for partitions we turn into a call. If this was the last
partition for which we generate code, we have to destroy the loop. */
if (!copy_p)
- destroy_loop (loop);
+ return true;
+ return false;
}
@@ -1397,11 +1399,12 @@ pgcmp (const void *v1_, const void *v2_)
/* Distributes the code from LOOP in such a way that producer
statements are placed before consumer statements. Tries to separate
only the statements from STMTS into separate loops.
- Returns the number of distributed loops. */
+ Returns the number of distributed loops. Set *DESTROY_P to whether
+ LOOP needs to be destroyed. */
static int
distribute_loop (struct loop *loop, vec<gimple *> stmts,
- control_dependences *cd, int *nb_calls)
+ control_dependences *cd, int *nb_calls, bool *destroy_p)
{
struct graph *rdg;
partition *partition;
@@ -1410,6 +1413,7 @@ distribute_loop (struct loop *loop, vec<gimple *> stmts,
graph *pg = NULL;
int num_sccs = 1;
+ *destroy_p = false;
*nb_calls = 0;
auto_vec<loop_p, 3> loop_nest;
if (!find_loop_nest (loop, &loop_nest))
@@ -1648,7 +1652,7 @@ distribute_loop (struct loop *loop, vec<gimple *> stmts,
{
if (partition_builtin_p (partition))
(*nb_calls)++;
- generate_code_for_partition (loop, partition, i < nbp - 1);
+ *destroy_p |= generate_code_for_partition (loop, partition, i < nbp - 1);
}
ldist_done:
@@ -1702,6 +1706,7 @@ pass_loop_distribution::execute (function *fun)
bool changed = false;
basic_block bb;
control_dependences *cd = NULL;
+ auto_vec<loop_p> loops_to_be_destroyed;
FOR_ALL_BB_FN (bb, fun)
{
@@ -1787,8 +1792,12 @@ out:
cd = new control_dependences (create_edge_list ());
free_dominance_info (CDI_POST_DOMINATORS);
}
+ bool destroy_p;
nb_generated_loops = distribute_loop (loop, work_list, cd,
- &nb_generated_calls);
+ &nb_generated_calls,
+ &destroy_p);
+ if (destroy_p)
+ loops_to_be_destroyed.safe_push (loop);
}
if (nb_generated_loops + nb_generated_calls > 0)
@@ -1806,6 +1815,12 @@ out:
if (cd)
delete cd;
+ /* Destroy loop bodies that could not be reused. Do this late as we
+ otherwise can end up refering to stale data in control dependences. */
+ unsigned i;
+ FOR_EACH_VEC_ELT (loops_to_be_destroyed, i, loop)
+ destroy_loop (loop);
+
if (changed)
{
/* Cached scalar evolutions now may refer to wrong or non-existing
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index 25a29bdcb28..f472717cec2 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -3168,6 +3168,7 @@ oacc_entry_exit_ok (struct loop *loop,
}
}
+ region_bbs.release ();
free (loop_bbs);
BITMAP_FREE (in_loop_bbs);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index cd8c3399f9f..66e103ae37e 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -506,7 +506,6 @@ extern ipa_opt_pass_d *make_pass_ipa_comdats (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_cleanup_cfg_post_optimizing (gcc::context
*ctxt);
-extern gimple_opt_pass *make_pass_init_datastructures (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_fixup_cfg (gcc::context *ctxt);
extern gimple_opt_pass *make_pass_backprop (gcc::context *ctxt);
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index c393d34b5ec..0e7fdd1fec4 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -1876,6 +1876,23 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, int flags,
pp_greater (pp);
break;
+ case BIT_INSERT_EXPR:
+ pp_string (pp, "BIT_INSERT_EXPR <");
+ dump_generic_node (pp, TREE_OPERAND (node, 0), spc, flags, false);
+ pp_string (pp, ", ");
+ dump_generic_node (pp, TREE_OPERAND (node, 1), spc, flags, false);
+ pp_string (pp, ", ");
+ dump_generic_node (pp, TREE_OPERAND (node, 2), spc, flags, false);
+ pp_string (pp, " (");
+ if (INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 1))))
+ pp_decimal_int (pp,
+ TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (node, 1))));
+ else
+ dump_generic_node (pp, TYPE_SIZE (TREE_TYPE (TREE_OPERAND (node, 1))),
+ spc, flags, false);
+ pp_string (pp, " bits)>");
+ break;
+
case ARRAY_REF:
case ARRAY_RANGE_REF:
op0 = TREE_OPERAND (node, 0);
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 936d3a6bfcf..7c0e90d84bc 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2074,7 +2074,8 @@ sort_and_splice_var_accesses (tree var)
access->grp_scalar_write = grp_scalar_write;
access->grp_assignment_read = grp_assignment_read;
access->grp_assignment_write = grp_assignment_write;
- access->grp_hint = multiple_scalar_reads || total_scalarization;
+ access->grp_hint = total_scalarization
+ || (multiple_scalar_reads && !constant_decl_p (var));
access->grp_total_scalarization = total_scalarization;
access->grp_partial_lhs = grp_partial_lhs;
access->grp_unscalarizable_region = unscalarizable_region;
@@ -3559,32 +3560,31 @@ initialize_constant_pool_replacements (void)
unsigned i;
EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi)
- if (bitmap_bit_p (should_scalarize_away_bitmap, i)
- && !bitmap_bit_p (cannot_scalarize_away_bitmap, i))
- {
- tree var = candidate (i);
- if (!constant_decl_p (var))
- continue;
- vec<access_p> *access_vec = get_base_access_vector (var);
- if (!access_vec)
- continue;
- for (unsigned i = 0; i < access_vec->length (); i++)
- {
- struct access *access = (*access_vec)[i];
- if (!access->replacement_decl)
- continue;
- gassign *stmt = gimple_build_assign (
- get_access_replacement (access), unshare_expr (access->expr));
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Generating constant initializer: ");
- print_gimple_stmt (dump_file, stmt, 0, 1);
- fprintf (dump_file, "\n");
- }
- gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
- update_stmt (stmt);
- }
- }
+ {
+ tree var = candidate (i);
+ if (!constant_decl_p (var))
+ continue;
+ vec<access_p> *access_vec = get_base_access_vector (var);
+ if (!access_vec)
+ continue;
+ for (unsigned i = 0; i < access_vec->length (); i++)
+ {
+ struct access *access = (*access_vec)[i];
+ if (!access->replacement_decl)
+ continue;
+ gassign *stmt
+ = gimple_build_assign (get_access_replacement (access),
+ unshare_expr (access->expr));
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Generating constant initializer: ");
+ print_gimple_stmt (dump_file, stmt, 0, 1);
+ fprintf (dump_file, "\n");
+ }
+ gsi_insert_after (&gsi, stmt, GSI_NEW_STMT);
+ update_stmt (stmt);
+ }
+ }
seq = gsi_seq (gsi);
if (seq)
diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c
index 58920e0d5b4..b663ddfb0d5 100644
--- a/gcc/tree-ssa-alias.c
+++ b/gcc/tree-ssa-alias.c
@@ -363,14 +363,17 @@ ptrs_compare_unequal (tree ptr1, tree ptr2)
else if (obj1 && TREE_CODE (ptr2) == SSA_NAME)
{
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr2);
- if (!pi)
+ /* We may not use restrict to optimize pointer comparisons.
+ See PR71062. So we have to assume that restrict-pointed-to
+ may be in fact obj1. */
+ if (!pi || pi->pt.vars_contains_restrict)
return false;
return !pt_solution_includes (&pi->pt, obj1);
}
else if (TREE_CODE (ptr1) == SSA_NAME && obj2)
{
struct ptr_info_def *pi = SSA_NAME_PTR_INFO (ptr1);
- if (!pi)
+ if (!pi || pi->pt.vars_contains_restrict)
return false;
return !pt_solution_includes (&pi->pt, obj2);
}
@@ -521,17 +524,31 @@ dump_points_to_solution (FILE *file, struct pt_solution *pt)
fprintf (file, ", points-to vars: ");
dump_decl_set (file, pt->vars);
if (pt->vars_contains_nonlocal
- && pt->vars_contains_escaped_heap)
- fprintf (file, " (nonlocal, escaped heap)");
- else if (pt->vars_contains_nonlocal
- && pt->vars_contains_escaped)
- fprintf (file, " (nonlocal, escaped)");
- else if (pt->vars_contains_nonlocal)
- fprintf (file, " (nonlocal)");
- else if (pt->vars_contains_escaped_heap)
- fprintf (file, " (escaped heap)");
- else if (pt->vars_contains_escaped)
- fprintf (file, " (escaped)");
+ || pt->vars_contains_escaped
+ || pt->vars_contains_escaped_heap
+ || pt->vars_contains_restrict)
+ {
+ const char *comma = "";
+ fprintf (file, " (");
+ if (pt->vars_contains_nonlocal)
+ {
+ fprintf (file, "nonlocal");
+ comma = ", ";
+ }
+ if (pt->vars_contains_escaped)
+ {
+ fprintf (file, "%sescaped", comma);
+ comma = ", ";
+ }
+ if (pt->vars_contains_escaped_heap)
+ {
+ fprintf (file, "%sescaped heap", comma);
+ comma = ", ";
+ }
+ if (pt->vars_contains_restrict)
+ fprintf (file, "%srestrict", comma);
+ fprintf (file, ")");
+ }
}
}
diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h
index 0593b05a7bc..6680cc0a1eb 100644
--- a/gcc/tree-ssa-alias.h
+++ b/gcc/tree-ssa-alias.h
@@ -47,7 +47,6 @@ struct GTY(()) pt_solution
includes memory at address NULL. */
unsigned int null : 1;
-
/* Nonzero if the vars bitmap includes a variable included in 'nonlocal'. */
unsigned int vars_contains_nonlocal : 1;
/* Nonzero if the vars bitmap includes a variable included in 'escaped'. */
@@ -55,6 +54,9 @@ struct GTY(()) pt_solution
/* Nonzero if the vars bitmap includes a anonymous heap variable that
escaped the function and thus became global. */
unsigned int vars_contains_escaped_heap : 1;
+ /* Nonzero if the vars bitmap includes a anonymous variable used to
+ represent storage pointed to by a restrict qualified pointer. */
+ unsigned int vars_contains_restrict : 1;
/* Set of variables that this pointer may point to. */
bitmap vars;
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index baae03f8042..ae120a8ff95 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -140,6 +140,8 @@ along with GCC; see the file COPYING3. If not see
#include "builtins.h"
#include "tree-chkp.h"
#include "cfgloop.h"
+#include "stor-layout.h"
+#include "optabs-query.h"
/* Possible lattice values. */
@@ -271,6 +273,7 @@ get_default_value (tree var)
can assume initially that it is UNDEFINED, otherwise we must
consider it VARYING. */
if (!virtual_operand_p (var)
+ && SSA_NAME_VAR (var)
&& TREE_CODE (SSA_NAME_VAR (var)) == VAR_DECL)
val.lattice_val = UNDEFINED;
else
@@ -2697,6 +2700,224 @@ optimize_unreachable (gimple_stmt_iterator i)
return ret;
}
+/* Optimize
+ mask_2 = 1 << cnt_1;
+ _4 = __atomic_fetch_or_* (ptr_6, mask_2, _3);
+ _5 = _4 & mask_2;
+ to
+ _4 = ATOMIC_BIT_TEST_AND_SET (ptr_6, cnt_1, 0, _3);
+ _5 = _4;
+ If _5 is only used in _5 != 0 or _5 == 0 comparisons, 1
+ is passed instead of 0, and the builtin just returns a zero
+ or 1 value instead of the actual bit.
+ Similarly for __sync_fetch_and_or_* (without the ", _3" part
+ in there), and/or if mask_2 is a power of 2 constant.
+ Similarly for xor instead of or, use ATOMIC_BIT_TEST_AND_COMPLEMENT
+ in that case. And similarly for and instead of or, except that
+ the second argument to the builtin needs to be one's complement
+ of the mask instead of mask. */
+
+static void
+optimize_atomic_bit_test_and (gimple_stmt_iterator *gsip,
+ enum internal_fn fn, bool has_model_arg,
+ bool after)
+{
+ gimple *call = gsi_stmt (*gsip);
+ tree lhs = gimple_call_lhs (call);
+ use_operand_p use_p;
+ gimple *use_stmt;
+ tree mask, bit;
+ optab optab;
+
+ if (!flag_inline_atomics
+ || optimize_debug
+ || !gimple_call_builtin_p (call, BUILT_IN_NORMAL)
+ || !lhs
+ || SSA_NAME_OCCURS_IN_ABNORMAL_PHI (lhs)
+ || !single_imm_use (lhs, &use_p, &use_stmt)
+ || !is_gimple_assign (use_stmt)
+ || gimple_assign_rhs_code (use_stmt) != BIT_AND_EXPR
+ || !gimple_vdef (call))
+ return;
+
+ switch (fn)
+ {
+ case IFN_ATOMIC_BIT_TEST_AND_SET:
+ optab = atomic_bit_test_and_set_optab;
+ break;
+ case IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT:
+ optab = atomic_bit_test_and_complement_optab;
+ break;
+ case IFN_ATOMIC_BIT_TEST_AND_RESET:
+ optab = atomic_bit_test_and_reset_optab;
+ break;
+ default:
+ return;
+ }
+
+ if (optab_handler (optab, TYPE_MODE (TREE_TYPE (lhs))) == CODE_FOR_nothing)
+ return;
+
+ mask = gimple_call_arg (call, 1);
+ tree use_lhs = gimple_assign_lhs (use_stmt);
+ if (!use_lhs)
+ return;
+
+ if (TREE_CODE (mask) == INTEGER_CST)
+ {
+ if (fn == IFN_ATOMIC_BIT_TEST_AND_RESET)
+ mask = const_unop (BIT_NOT_EXPR, TREE_TYPE (mask), mask);
+ mask = fold_convert (TREE_TYPE (lhs), mask);
+ int ibit = tree_log2 (mask);
+ if (ibit < 0)
+ return;
+ bit = build_int_cst (TREE_TYPE (lhs), ibit);
+ }
+ else if (TREE_CODE (mask) == SSA_NAME)
+ {
+ gimple *g = SSA_NAME_DEF_STMT (mask);
+ if (fn == IFN_ATOMIC_BIT_TEST_AND_RESET)
+ {
+ if (!is_gimple_assign (g)
+ || gimple_assign_rhs_code (g) != BIT_NOT_EXPR)
+ return;
+ mask = gimple_assign_rhs1 (g);
+ if (TREE_CODE (mask) != SSA_NAME)
+ return;
+ g = SSA_NAME_DEF_STMT (mask);
+ }
+ if (!is_gimple_assign (g)
+ || gimple_assign_rhs_code (g) != LSHIFT_EXPR
+ || !integer_onep (gimple_assign_rhs1 (g)))
+ return;
+ bit = gimple_assign_rhs2 (g);
+ }
+ else
+ return;
+
+ if (gimple_assign_rhs1 (use_stmt) == lhs)
+ {
+ if (!operand_equal_p (gimple_assign_rhs2 (use_stmt), mask, 0))
+ return;
+ }
+ else if (gimple_assign_rhs2 (use_stmt) != lhs
+ || !operand_equal_p (gimple_assign_rhs1 (use_stmt), mask, 0))
+ return;
+
+ bool use_bool = true;
+ bool has_debug_uses = false;
+ imm_use_iterator iter;
+ gimple *g;
+
+ if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use_lhs))
+ use_bool = false;
+ FOR_EACH_IMM_USE_STMT (g, iter, use_lhs)
+ {
+ enum tree_code code = ERROR_MARK;
+ tree op0, op1;
+ if (is_gimple_debug (g))
+ {
+ has_debug_uses = true;
+ continue;
+ }
+ else if (is_gimple_assign (g))
+ switch (gimple_assign_rhs_code (g))
+ {
+ case COND_EXPR:
+ op1 = gimple_assign_rhs1 (g);
+ code = TREE_CODE (op1);
+ op0 = TREE_OPERAND (op1, 0);
+ op1 = TREE_OPERAND (op1, 1);
+ break;
+ case EQ_EXPR:
+ case NE_EXPR:
+ code = gimple_assign_rhs_code (g);
+ op0 = gimple_assign_rhs1 (g);
+ op1 = gimple_assign_rhs2 (g);
+ break;
+ default:
+ break;
+ }
+ else if (gimple_code (g) == GIMPLE_COND)
+ {
+ code = gimple_cond_code (g);
+ op0 = gimple_cond_lhs (g);
+ op1 = gimple_cond_rhs (g);
+ }
+
+ if ((code == EQ_EXPR || code == NE_EXPR)
+ && op0 == use_lhs
+ && integer_zerop (op1))
+ {
+ use_operand_p use_p;
+ int n = 0;
+ FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ n++;
+ if (n == 1)
+ continue;
+ }
+
+ use_bool = false;
+ BREAK_FROM_IMM_USE_STMT (iter);
+ }
+
+ tree new_lhs = make_ssa_name (TREE_TYPE (lhs));
+ tree flag = build_int_cst (TREE_TYPE (lhs), use_bool);
+ if (has_model_arg)
+ g = gimple_build_call_internal (fn, 4, gimple_call_arg (call, 0),
+ bit, flag, gimple_call_arg (call, 2));
+ else
+ g = gimple_build_call_internal (fn, 3, gimple_call_arg (call, 0),
+ bit, flag);
+ gimple_call_set_lhs (g, new_lhs);
+ gimple_set_location (g, gimple_location (call));
+ gimple_set_vuse (g, gimple_vuse (call));
+ gimple_set_vdef (g, gimple_vdef (call));
+ SSA_NAME_DEF_STMT (gimple_vdef (call)) = g;
+ gimple_stmt_iterator gsi = *gsip;
+ gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+ if (after)
+ {
+ /* The internal function returns the value of the specified bit
+ before the atomic operation. If we are interested in the value
+ of the specified bit after the atomic operation (makes only sense
+ for xor, otherwise the bit content is compile time known),
+ we need to invert the bit. */
+ g = gimple_build_assign (make_ssa_name (TREE_TYPE (lhs)),
+ BIT_XOR_EXPR, new_lhs,
+ use_bool ? build_int_cst (TREE_TYPE (lhs), 1)
+ : mask);
+ new_lhs = gimple_assign_lhs (g);
+ gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+ }
+ if (use_bool && has_debug_uses)
+ {
+ tree temp = make_node (DEBUG_EXPR_DECL);
+ DECL_ARTIFICIAL (temp) = 1;
+ TREE_TYPE (temp) = TREE_TYPE (lhs);
+ DECL_MODE (temp) = TYPE_MODE (TREE_TYPE (lhs));
+ tree t = build2 (LSHIFT_EXPR, TREE_TYPE (lhs), new_lhs, bit);
+ g = gimple_build_debug_bind (temp, t, g);
+ gsi_insert_after (&gsi, g, GSI_NEW_STMT);
+ FOR_EACH_IMM_USE_STMT (g, iter, use_lhs)
+ if (is_gimple_debug (g))
+ {
+ use_operand_p use_p;
+ FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ SET_USE (use_p, temp);
+ update_stmt (g);
+ }
+ }
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_lhs)
+ = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (use_lhs);
+ replace_uses_by (use_lhs, new_lhs);
+ gsi = gsi_for_stmt (use_stmt);
+ gsi_remove (&gsi, true);
+ release_defs (use_stmt);
+ gsi_remove (gsip, true);
+ release_ssa_name (lhs);
+}
+
/* A simple pass that attempts to fold all builtin functions. This pass
is run after we've propagated as many constants as we can. */
@@ -2806,6 +3027,78 @@ pass_fold_builtins::execute (function *fun)
cfg_changed = true;
break;
+ case BUILT_IN_ATOMIC_FETCH_OR_1:
+ case BUILT_IN_ATOMIC_FETCH_OR_2:
+ case BUILT_IN_ATOMIC_FETCH_OR_4:
+ case BUILT_IN_ATOMIC_FETCH_OR_8:
+ case BUILT_IN_ATOMIC_FETCH_OR_16:
+ optimize_atomic_bit_test_and (&i,
+ IFN_ATOMIC_BIT_TEST_AND_SET,
+ true, false);
+ break;
+ case BUILT_IN_SYNC_FETCH_AND_OR_1:
+ case BUILT_IN_SYNC_FETCH_AND_OR_2:
+ case BUILT_IN_SYNC_FETCH_AND_OR_4:
+ case BUILT_IN_SYNC_FETCH_AND_OR_8:
+ case BUILT_IN_SYNC_FETCH_AND_OR_16:
+ optimize_atomic_bit_test_and (&i,
+ IFN_ATOMIC_BIT_TEST_AND_SET,
+ false, false);
+ break;
+
+ case BUILT_IN_ATOMIC_FETCH_XOR_1:
+ case BUILT_IN_ATOMIC_FETCH_XOR_2:
+ case BUILT_IN_ATOMIC_FETCH_XOR_4:
+ case BUILT_IN_ATOMIC_FETCH_XOR_8:
+ case BUILT_IN_ATOMIC_FETCH_XOR_16:
+ optimize_atomic_bit_test_and
+ (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, true, false);
+ break;
+ case BUILT_IN_SYNC_FETCH_AND_XOR_1:
+ case BUILT_IN_SYNC_FETCH_AND_XOR_2:
+ case BUILT_IN_SYNC_FETCH_AND_XOR_4:
+ case BUILT_IN_SYNC_FETCH_AND_XOR_8:
+ case BUILT_IN_SYNC_FETCH_AND_XOR_16:
+ optimize_atomic_bit_test_and
+ (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, false, false);
+ break;
+
+ case BUILT_IN_ATOMIC_XOR_FETCH_1:
+ case BUILT_IN_ATOMIC_XOR_FETCH_2:
+ case BUILT_IN_ATOMIC_XOR_FETCH_4:
+ case BUILT_IN_ATOMIC_XOR_FETCH_8:
+ case BUILT_IN_ATOMIC_XOR_FETCH_16:
+ optimize_atomic_bit_test_and
+ (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, true, true);
+ break;
+ case BUILT_IN_SYNC_XOR_AND_FETCH_1:
+ case BUILT_IN_SYNC_XOR_AND_FETCH_2:
+ case BUILT_IN_SYNC_XOR_AND_FETCH_4:
+ case BUILT_IN_SYNC_XOR_AND_FETCH_8:
+ case BUILT_IN_SYNC_XOR_AND_FETCH_16:
+ optimize_atomic_bit_test_and
+ (&i, IFN_ATOMIC_BIT_TEST_AND_COMPLEMENT, false, true);
+ break;
+
+ case BUILT_IN_ATOMIC_FETCH_AND_1:
+ case BUILT_IN_ATOMIC_FETCH_AND_2:
+ case BUILT_IN_ATOMIC_FETCH_AND_4:
+ case BUILT_IN_ATOMIC_FETCH_AND_8:
+ case BUILT_IN_ATOMIC_FETCH_AND_16:
+ optimize_atomic_bit_test_and (&i,
+ IFN_ATOMIC_BIT_TEST_AND_RESET,
+ true, false);
+ break;
+ case BUILT_IN_SYNC_FETCH_AND_AND_1:
+ case BUILT_IN_SYNC_FETCH_AND_AND_2:
+ case BUILT_IN_SYNC_FETCH_AND_AND_4:
+ case BUILT_IN_SYNC_FETCH_AND_AND_8:
+ case BUILT_IN_SYNC_FETCH_AND_AND_16:
+ optimize_atomic_bit_test_and (&i,
+ IFN_ATOMIC_BIT_TEST_AND_RESET,
+ false, false);
+ break;
+
case BUILT_IN_VA_START:
case BUILT_IN_VA_END:
case BUILT_IN_VA_COPY:
diff --git a/gcc/tree-ssa-coalesce.c b/gcc/tree-ssa-coalesce.c
index 4b0134d082c..34c3fa16ccf 100644
--- a/gcc/tree-ssa-coalesce.c
+++ b/gcc/tree-ssa-coalesce.c
@@ -1505,7 +1505,8 @@ dump_part_var_map (FILE *f, partition part, var_map map)
/* Given SSA_NAMEs NAME1 and NAME2, return true if they are candidates for
coalescing together, false otherwise.
- This must stay consistent with var_map_base_init in tree-ssa-live.c. */
+ This must stay consistent with compute_samebase_partition_bases and
+ compute_optimized_partition_bases. */
bool
gimple_can_coalesce_p (tree name1, tree name2)
@@ -1568,17 +1569,24 @@ gimple_can_coalesce_p (tree name1, tree name2)
var2 ? LOCAL_DECL_ALIGNMENT (var2) : TYPE_ALIGN (t2)))
return false;
- /* If the types are not the same, check for a canonical type match. This
+ /* If the types are not the same, see whether they are compatible. This
(for example) allows coalescing when the types are fundamentally the
- same, but just have different names.
+ same, but just have different names.
- Note pointer types with different address spaces may have the same
- canonical type. Those are rejected for coalescing by the
- types_compatible_p check. */
- if (TYPE_CANONICAL (t1)
- && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2)
- && types_compatible_p (t1, t2))
- goto check_modes;
+ In the non-optimized case, we must first test TYPE_CANONICAL because
+ we use it to compute the partition_to_base_index of the map. */
+ if (flag_tree_coalesce_vars)
+ {
+ if (types_compatible_p (t1, t2))
+ goto check_modes;
+ }
+ else
+ {
+ if (TYPE_CANONICAL (t1)
+ && TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2)
+ && types_compatible_p (t1, t2))
+ goto check_modes;
+ }
return false;
}
@@ -1759,7 +1767,7 @@ compute_samebase_partition_bases (var_map map)
else
/* This restricts what anonymous SSA names we can coalesce
as it restricts the sets we compute conflicts for.
- Using TREE_TYPE to generate sets is the easies as
+ Using TREE_TYPE to generate sets is the easiest as
type equivalency also holds for SSA names with the same
underlying decl.
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index ec0fb7fcb46..b9cd0f6bac6 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -717,7 +717,7 @@ determine_max_movement (gimple *stmt, bool must_preserve_exec)
return false;
def_data = get_lim_data (SSA_NAME_DEF_STMT (val));
if (def_data)
- total_cost += def_data->cost;
+ lim_data->cost += def_data->cost;
}
/* We want to avoid unconditionally executing very expensive
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 9b59b4466c3..e8f67953231 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -712,7 +712,7 @@ try_unroll_loop_completely (struct loop *loop,
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "Not unrolling loop %d "
- "(--param max-completely-peeled-times limit reached).\n",
+ "(--param max-completely-peel-times limit reached).\n",
loop->num);
return false;
}
@@ -807,7 +807,7 @@ try_unroll_loop_completely (struct loop *loop,
loop->num);
return false;
}
- /* Complette unrolling is major win when control flow is removed and
+ /* Complete unrolling is a major win when control flow is removed and
one big basic block is created. If the loop contains control flow
the optimization may still be a win because of eliminating the loop
overhead but it also may blow the branch predictor tables.
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 9314363b533..9ce6b649519 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -129,7 +129,7 @@ avg_loop_niter (struct loop *loop)
{
niter = max_stmt_executions_int (loop);
if (niter == -1 || niter > AVG_LOOP_NITER (loop))
- return AVG_LOOP_NITER (loop);
+ return AVG_LOOP_NITER (loop);
}
return niter;
@@ -184,6 +184,8 @@ struct comp_cost
static const comp_cost no_cost = {0, 0, 0};
static const comp_cost infinite_cost = {INFTY, INFTY, INFTY};
+struct iv_inv_expr_ent;
+
/* The candidate - cost pair. */
struct cost_pair
{
@@ -195,7 +197,7 @@ struct cost_pair
the final value of the iv. For iv elimination,
the new bound to compare with. */
enum tree_code comp; /* For iv elimination, the comparison. */
- int inv_expr_id; /* Loop invariant expression id. */
+ iv_inv_expr_ent *inv_expr; /* Loop invariant expression. */
};
/* Use. */
@@ -307,13 +309,36 @@ iv_common_cand_hasher::equal (const iv_common_cand *ccand1,
}
/* Loop invariant expression hashtable entry. */
+
struct iv_inv_expr_ent
{
+ /* Tree expression of the entry. */
tree expr;
+ /* Unique indentifier. */
int id;
+ /* Hash value. */
hashval_t hash;
};
+/* Sort iv_inv_expr_ent pair A and B by id field. */
+
+static int
+sort_iv_inv_expr_ent (const void *a, const void *b)
+{
+ const iv_inv_expr_ent * const *e1 = (const iv_inv_expr_ent * const *) (a);
+ const iv_inv_expr_ent * const *e2 = (const iv_inv_expr_ent * const *) (b);
+
+ unsigned id1 = (*e1)->id;
+ unsigned id2 = (*e2)->id;
+
+ if (id1 < id2)
+ return -1;
+ else if (id1 > id2)
+ return 1;
+ else
+ return 0;
+}
+
/* Hashtable helpers. */
struct iv_inv_expr_hasher : free_ptr_hash <iv_inv_expr_ent>
@@ -363,7 +388,7 @@ struct ivopts_data
hash_table<iv_inv_expr_hasher> *inv_expr_tab;
/* Loop invariant expression id. */
- int inv_expr_id;
+ int max_inv_expr_id;
/* The bitmap of indices in version_info whose value was changed. */
bitmap relevant;
@@ -443,12 +468,8 @@ struct iv_ca
/* Number of times each invariant is used. */
unsigned *n_invariant_uses;
- /* The array holding the number of uses of each loop
- invariant expressions created by ivopt. */
- unsigned *used_inv_expr;
-
- /* The number of created loop invariants. */
- unsigned num_used_inv_expr;
+ /* Hash set with used invariant expression. */
+ hash_map <iv_inv_expr_ent *, unsigned> *used_inv_exprs;
/* Total cost of the assignment. */
comp_cost cost;
@@ -840,8 +861,8 @@ niter_for_exit (struct ivopts_data *data, edge exit)
if (!slot)
{
/* Try to determine number of iterations. We cannot safely work with ssa
- names that appear in phi nodes on abnormal edges, so that we do not
- create overlapping life ranges for them (PR 27283). */
+ names that appear in phi nodes on abnormal edges, so that we do not
+ create overlapping life ranges for them (PR 27283). */
desc = XNEW (struct tree_niter_desc);
if (!number_of_iterations_exit (data->current_loop,
exit, desc, true)
@@ -888,7 +909,7 @@ tree_ssa_iv_optimize_init (struct ivopts_data *data)
data->vgroups.create (20);
data->vcands.create (20);
data->inv_expr_tab = new hash_table<iv_inv_expr_hasher> (10);
- data->inv_expr_id = 0;
+ data->max_inv_expr_id = 0;
data->name_expansion_cache = NULL;
data->iv_common_cand_tab = new hash_table<iv_common_cand_hasher> (10);
data->iv_common_cands.create (20);
@@ -930,7 +951,7 @@ determine_base_object (tree expr)
return determine_base_object (TREE_OPERAND (base, 0));
return fold_convert (ptr_type_node,
- build_fold_addr_expr (base));
+ build_fold_addr_expr (base));
case POINTER_PLUS_EXPR:
return determine_base_object (TREE_OPERAND (expr, 0));
@@ -989,7 +1010,7 @@ alloc_iv (struct ivopts_data *data, tree base, tree step,
By doing this:
1) More accurate cost can be computed for address expressions;
2) Duplicate candidates won't be created for bases in different
- forms, like &a[0] and &a. */
+ forms, like &a[0] and &a. */
STRIP_NOPS (expr);
if ((TREE_CODE (expr) == ADDR_EXPR && !DECL_P (TREE_OPERAND (expr, 0)))
|| contain_complex_addr_expr (expr))
@@ -2265,7 +2286,7 @@ find_interesting_uses_outside (struct ivopts_data *data, edge exit)
phi = psi.phi ();
def = PHI_ARG_DEF_FROM_EDGE (phi, exit);
if (!virtual_operand_p (def))
- find_interesting_uses_op (data, def);
+ find_interesting_uses_op (data, def);
}
}
@@ -2785,8 +2806,8 @@ add_candidate_1 (struct ivopts_data *data,
if (operand_equal_p (base, cand->iv->base, 0)
&& operand_equal_p (step, cand->iv->step, 0)
- && (TYPE_PRECISION (TREE_TYPE (base))
- == TYPE_PRECISION (TREE_TYPE (cand->iv->base))))
+ && (TYPE_PRECISION (TREE_TYPE (base))
+ == TYPE_PRECISION (TREE_TYPE (cand->iv->base))))
break;
}
@@ -2936,14 +2957,14 @@ add_standard_iv_candidates (struct ivopts_data *data)
/* The same for a double-integer type if it is still fast enough. */
if (TYPE_PRECISION
- (long_integer_type_node) > TYPE_PRECISION (integer_type_node)
+ (long_integer_type_node) > TYPE_PRECISION (integer_type_node)
&& TYPE_PRECISION (long_integer_type_node) <= BITS_PER_WORD)
add_candidate (data, build_int_cst (long_integer_type_node, 0),
build_int_cst (long_integer_type_node, 1), true, NULL);
/* The same for a double-integer type if it is still fast enough. */
if (TYPE_PRECISION
- (long_long_integer_type_node) > TYPE_PRECISION (long_integer_type_node)
+ (long_long_integer_type_node) > TYPE_PRECISION (long_integer_type_node)
&& TYPE_PRECISION (long_long_integer_type_node) <= BITS_PER_WORD)
add_candidate (data, build_int_cst (long_long_integer_type_node, 0),
build_int_cst (long_long_integer_type_node, 1), true, NULL);
@@ -3329,7 +3350,7 @@ static void
set_group_iv_cost (struct ivopts_data *data,
struct iv_group *group, struct iv_cand *cand,
comp_cost cost, bitmap depends_on, tree value,
- enum tree_code comp, int inv_expr_id)
+ enum tree_code comp, iv_inv_expr_ent *inv_expr)
{
unsigned i, s;
@@ -3346,7 +3367,7 @@ set_group_iv_cost (struct ivopts_data *data,
group->cost_map[cand->id].depends_on = depends_on;
group->cost_map[cand->id].value = value;
group->cost_map[cand->id].comp = comp;
- group->cost_map[cand->id].inv_expr_id = inv_expr_id;
+ group->cost_map[cand->id].inv_expr = inv_expr;
return;
}
@@ -3367,7 +3388,7 @@ found:
group->cost_map[i].depends_on = depends_on;
group->cost_map[i].value = value;
group->cost_map[i].comp = comp;
- group->cost_map[i].inv_expr_id = inv_expr_id;
+ group->cost_map[i].inv_expr = inv_expr;
}
/* Gets cost of (GROUP, CAND) pair. */
@@ -3454,7 +3475,7 @@ prepare_decl_rtl (tree *expr_p, int *ws, void *data)
continue;
obj = *expr_p;
if (DECL_P (obj) && HAS_RTL_P (obj) && !DECL_RTL_SET_P (obj))
- x = produce_memory_decl_rtl (obj, regno);
+ x = produce_memory_decl_rtl (obj, regno);
break;
case SSA_NAME:
@@ -3908,7 +3929,7 @@ get_address_cost (bool symbol_present, bool var_present,
}
}
if (i == -1)
- off = 0;
+ off = 0;
data->max_offset = off;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -4040,9 +4061,9 @@ get_address_cost (bool symbol_present, bool var_present,
However, the symbol will have to be loaded in any case before the
loop (and quite likely we have it in register already), so it does not
make much sense to penalize them too heavily. So make some final
- tweaks for the SYMBOL_PRESENT modes:
+ tweaks for the SYMBOL_PRESENT modes:
- If VAR_PRESENT is false, and the mode obtained by changing symbol to
+ If VAR_PRESENT is false, and the mode obtained by changing symbol to
var is cheaper, use this mode with small penalty.
If VAR_PRESENT is true, try whether the mode with
SYMBOL_PRESENT = false is cheaper even with cost of addition, and
@@ -4159,7 +4180,7 @@ get_address_cost (bool symbol_present, bool var_present,
static bool
get_shiftadd_cost (tree expr, machine_mode mode, comp_cost cost0,
- comp_cost cost1, tree mult, bool speed, comp_cost *cost)
+ comp_cost cost1, tree mult, bool speed, comp_cost *cost)
{
comp_cost res;
tree op1 = TREE_OPERAND (expr, 1);
@@ -4181,10 +4202,10 @@ get_shiftadd_cost (tree expr, machine_mode mode, comp_cost cost0,
/* If the target has a cheap shift-and-add or shift-and-sub instruction,
use that in preference to a shift insn followed by an add insn. */
sa_cost = (TREE_CODE (expr) != MINUS_EXPR
- ? shiftadd_cost (speed, mode, m)
- : (mult_in_op1
- ? shiftsub1_cost (speed, mode, m)
- : shiftsub0_cost (speed, mode, m)));
+ ? shiftadd_cost (speed, mode, m)
+ : (mult_in_op1
+ ? shiftsub1_cost (speed, mode, m)
+ : shiftsub0_cost (speed, mode, m)));
res = new_cost (MIN (as_cost, sa_cost), 0);
res = add_costs (res, mult_in_op1 ? cost0 : cost1);
@@ -4316,20 +4337,20 @@ force_expr_to_var_cost (tree expr, bool speed)
case NEGATE_EXPR:
cost = new_cost (add_cost (speed, mode), 0);
if (TREE_CODE (expr) != NEGATE_EXPR)
- {
- tree mult = NULL_TREE;
- comp_cost sa_cost;
- if (TREE_CODE (op1) == MULT_EXPR)
- mult = op1;
- else if (TREE_CODE (op0) == MULT_EXPR)
- mult = op0;
-
- if (mult != NULL_TREE
- && cst_and_fits_in_hwi (TREE_OPERAND (mult, 1))
- && get_shiftadd_cost (expr, mode, cost0, cost1, mult,
- speed, &sa_cost))
- return sa_cost;
- }
+ {
+ tree mult = NULL_TREE;
+ comp_cost sa_cost;
+ if (TREE_CODE (op1) == MULT_EXPR)
+ mult = op1;
+ else if (TREE_CODE (op0) == MULT_EXPR)
+ mult = op0;
+
+ if (mult != NULL_TREE
+ && cst_and_fits_in_hwi (TREE_OPERAND (mult, 1))
+ && get_shiftadd_cost (expr, mode, cost0, cost1, mult,
+ speed, &sa_cost))
+ return sa_cost;
+ }
break;
CASE_CONVERT:
@@ -4543,18 +4564,18 @@ compare_aff_trees (aff_tree *aff1, aff_tree *aff2)
for (i = 0; i < aff1->n; i++)
{
if (aff1->elts[i].coef != aff2->elts[i].coef)
- return false;
+ return false;
if (!operand_equal_p (aff1->elts[i].val, aff2->elts[i].val, 0))
- return false;
+ return false;
}
return true;
}
-/* Stores EXPR in DATA->inv_expr_tab, and assigns it an inv_expr_id. */
+/* Stores EXPR in DATA->inv_expr_tab, return pointer to iv_inv_expr_ent. */
-static int
-get_expr_id (struct ivopts_data *data, tree expr)
+static iv_inv_expr_ent *
+record_inv_expr (struct ivopts_data *data, tree expr)
{
struct iv_inv_expr_ent ent;
struct iv_inv_expr_ent **slot;
@@ -4562,25 +4583,27 @@ get_expr_id (struct ivopts_data *data, tree expr)
ent.expr = expr;
ent.hash = iterative_hash_expr (expr, 0);
slot = data->inv_expr_tab->find_slot (&ent, INSERT);
- if (*slot)
- return (*slot)->id;
- *slot = XNEW (struct iv_inv_expr_ent);
- (*slot)->expr = expr;
- (*slot)->hash = ent.hash;
- (*slot)->id = data->inv_expr_id++;
- return (*slot)->id;
+ if (!*slot)
+ {
+ *slot = XNEW (struct iv_inv_expr_ent);
+ (*slot)->expr = expr;
+ (*slot)->hash = ent.hash;
+ (*slot)->id = data->max_inv_expr_id++;
+ }
+
+ return *slot;
}
-/* Returns the pseudo expr id if expression UBASE - RATIO * CBASE
+/* Returns the invariant expression if expression UBASE - RATIO * CBASE
requires a new compiler generated temporary. Returns -1 otherwise.
ADDRESS_P is a flag indicating if the expression is for address
computation. */
-static int
-get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
- tree cbase, HOST_WIDE_INT ratio,
- bool address_p)
+static iv_inv_expr_ent *
+get_loop_invariant_expr (struct ivopts_data *data, tree ubase,
+ tree cbase, HOST_WIDE_INT ratio,
+ bool address_p)
{
aff_tree ubase_aff, cbase_aff;
tree expr, ub, cb;
@@ -4592,7 +4615,7 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
if ((TREE_CODE (ubase) == INTEGER_CST)
&& (TREE_CODE (cbase) == INTEGER_CST))
- return -1;
+ return NULL;
/* Strips the constant part. */
if (TREE_CODE (ubase) == PLUS_EXPR
@@ -4600,7 +4623,7 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|| TREE_CODE (ubase) == POINTER_PLUS_EXPR)
{
if (TREE_CODE (TREE_OPERAND (ubase, 1)) == INTEGER_CST)
- ubase = TREE_OPERAND (ubase, 0);
+ ubase = TREE_OPERAND (ubase, 0);
}
/* Strips the constant part. */
@@ -4609,60 +4632,60 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
|| TREE_CODE (cbase) == POINTER_PLUS_EXPR)
{
if (TREE_CODE (TREE_OPERAND (cbase, 1)) == INTEGER_CST)
- cbase = TREE_OPERAND (cbase, 0);
+ cbase = TREE_OPERAND (cbase, 0);
}
if (address_p)
{
if (((TREE_CODE (ubase) == SSA_NAME)
- || (TREE_CODE (ubase) == ADDR_EXPR
- && is_gimple_min_invariant (ubase)))
- && (TREE_CODE (cbase) == INTEGER_CST))
- return -1;
+ || (TREE_CODE (ubase) == ADDR_EXPR
+ && is_gimple_min_invariant (ubase)))
+ && (TREE_CODE (cbase) == INTEGER_CST))
+ return NULL;
if (((TREE_CODE (cbase) == SSA_NAME)
- || (TREE_CODE (cbase) == ADDR_EXPR
- && is_gimple_min_invariant (cbase)))
- && (TREE_CODE (ubase) == INTEGER_CST))
- return -1;
+ || (TREE_CODE (cbase) == ADDR_EXPR
+ && is_gimple_min_invariant (cbase)))
+ && (TREE_CODE (ubase) == INTEGER_CST))
+ return NULL;
}
if (ratio == 1)
{
if (operand_equal_p (ubase, cbase, 0))
- return -1;
+ return NULL;
if (TREE_CODE (ubase) == ADDR_EXPR
- && TREE_CODE (cbase) == ADDR_EXPR)
- {
- tree usym, csym;
-
- usym = TREE_OPERAND (ubase, 0);
- csym = TREE_OPERAND (cbase, 0);
- if (TREE_CODE (usym) == ARRAY_REF)
- {
- tree ind = TREE_OPERAND (usym, 1);
- if (TREE_CODE (ind) == INTEGER_CST
- && tree_fits_shwi_p (ind)
- && tree_to_shwi (ind) == 0)
- usym = TREE_OPERAND (usym, 0);
- }
- if (TREE_CODE (csym) == ARRAY_REF)
- {
- tree ind = TREE_OPERAND (csym, 1);
- if (TREE_CODE (ind) == INTEGER_CST
- && tree_fits_shwi_p (ind)
- && tree_to_shwi (ind) == 0)
- csym = TREE_OPERAND (csym, 0);
- }
- if (operand_equal_p (usym, csym, 0))
- return -1;
- }
+ && TREE_CODE (cbase) == ADDR_EXPR)
+ {
+ tree usym, csym;
+
+ usym = TREE_OPERAND (ubase, 0);
+ csym = TREE_OPERAND (cbase, 0);
+ if (TREE_CODE (usym) == ARRAY_REF)
+ {
+ tree ind = TREE_OPERAND (usym, 1);
+ if (TREE_CODE (ind) == INTEGER_CST
+ && tree_fits_shwi_p (ind)
+ && tree_to_shwi (ind) == 0)
+ usym = TREE_OPERAND (usym, 0);
+ }
+ if (TREE_CODE (csym) == ARRAY_REF)
+ {
+ tree ind = TREE_OPERAND (csym, 1);
+ if (TREE_CODE (ind) == INTEGER_CST
+ && tree_fits_shwi_p (ind)
+ && tree_to_shwi (ind) == 0)
+ csym = TREE_OPERAND (csym, 0);
+ }
+ if (operand_equal_p (usym, csym, 0))
+ return NULL;
+ }
/* Now do more complex comparison */
tree_to_aff_combination (ubase, TREE_TYPE (ubase), &ubase_aff);
tree_to_aff_combination (cbase, TREE_TYPE (cbase), &cbase_aff);
if (compare_aff_trees (&ubase_aff, &cbase_aff))
- return -1;
+ return NULL;
}
tree_to_aff_combination (ub, TREE_TYPE (ub), &ubase_aff);
@@ -4671,7 +4694,7 @@ get_loop_invariant_expr_id (struct ivopts_data *data, tree ubase,
aff_combination_scale (&cbase_aff, -1 * ratio);
aff_combination_add (&ubase_aff, &cbase_aff);
expr = aff_combination_to_tree (&ubase_aff);
- return get_expr_id (data, expr);
+ return record_inv_expr (data, expr);
}
@@ -4689,7 +4712,7 @@ get_computation_cost_at (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand,
bool address_p, bitmap *depends_on, gimple *at,
bool *can_autoinc,
- int *inv_expr_id)
+ iv_inv_expr_ent **inv_expr)
{
tree ubase = use->iv->base, ustep = use->iv->step;
tree cbase, cstep;
@@ -4790,17 +4813,17 @@ get_computation_cost_at (struct ivopts_data *data,
/* Check to see if any adjustment is needed. */
if (cstepi == 0 && stmt_is_after_inc)
- {
- aff_tree real_cbase_aff;
- aff_tree cstep_aff;
+ {
+ aff_tree real_cbase_aff;
+ aff_tree cstep_aff;
- tree_to_aff_combination (cbase, TREE_TYPE (real_cbase),
- &real_cbase_aff);
- tree_to_aff_combination (cstep, TREE_TYPE (cstep), &cstep_aff);
+ tree_to_aff_combination (cbase, TREE_TYPE (real_cbase),
+ &real_cbase_aff);
+ tree_to_aff_combination (cstep, TREE_TYPE (cstep), &cstep_aff);
- aff_combination_add (&real_cbase_aff, &cstep_aff);
- real_cbase = aff_combination_to_tree (&real_cbase_aff);
- }
+ aff_combination_add (&real_cbase_aff, &cstep_aff);
+ real_cbase = aff_combination_to_tree (&real_cbase_aff);
+ }
cost = difference_cost (data,
ubase, real_cbase,
@@ -4814,17 +4837,19 @@ get_computation_cost_at (struct ivopts_data *data,
(ratio, mem_mode,
TYPE_ADDR_SPACE (TREE_TYPE (utype))))
{
+ tree real_cbase = cbase;
+
if (cstepi == 0 && stmt_is_after_inc)
{
if (POINTER_TYPE_P (ctype))
- cbase = fold_build2 (POINTER_PLUS_EXPR, ctype, cbase, cstep);
+ real_cbase = fold_build2 (POINTER_PLUS_EXPR, ctype, cbase, cstep);
else
- cbase = fold_build2 (PLUS_EXPR, ctype, cbase, cstep);
+ real_cbase = fold_build2 (PLUS_EXPR, ctype, cbase, cstep);
}
- cbase
- = fold_build2 (MULT_EXPR, ctype, cbase, build_int_cst (ctype, ratio));
+ real_cbase = fold_build2 (MULT_EXPR, ctype, real_cbase,
+ build_int_cst (ctype, ratio));
cost = difference_cost (data,
- ubase, cbase,
+ ubase, real_cbase,
&symbol_present, &var_present, &offset,
depends_on);
cost.cost /= avg_loop_niter (data->current_loop);
@@ -4844,13 +4869,13 @@ get_computation_cost_at (struct ivopts_data *data,
/* Record setup cost in scrach field. */
cost.scratch = cost.cost;
- if (inv_expr_id)
+ if (inv_expr && depends_on && *depends_on)
{
- *inv_expr_id =
- get_loop_invariant_expr_id (data, ubase, cbase, ratio, address_p);
+ *inv_expr = get_loop_invariant_expr (data, ubase, cbase, ratio,
+ address_p);
/* Clear depends on. */
- if (*inv_expr_id != -1 && depends_on && *depends_on)
- bitmap_clear (*depends_on);
+ if (*inv_expr != NULL)
+ bitmap_clear (*depends_on);
}
/* If we are after the increment, the value of the candidate is higher by
@@ -4927,11 +4952,11 @@ static comp_cost
get_computation_cost (struct ivopts_data *data,
struct iv_use *use, struct iv_cand *cand,
bool address_p, bitmap *depends_on,
- bool *can_autoinc, int *inv_expr_id)
+ bool *can_autoinc, iv_inv_expr_ent **inv_expr)
{
return get_computation_cost_at (data,
use, cand, address_p, depends_on, use->stmt,
- can_autoinc, inv_expr_id);
+ can_autoinc, inv_expr);
}
/* Determines cost of computing the use in GROUP with CAND in a generic
@@ -4942,7 +4967,7 @@ determine_group_iv_cost_generic (struct ivopts_data *data,
struct iv_group *group, struct iv_cand *cand)
{
comp_cost cost;
- int inv_expr_id = -1;
+ iv_inv_expr_ent *inv_expr = NULL;
bitmap depends_on = NULL;
struct iv_use *use = group->vuses[0];
@@ -4954,10 +4979,10 @@ determine_group_iv_cost_generic (struct ivopts_data *data,
cost = no_cost;
else
cost = get_computation_cost (data, use, cand, false,
- &depends_on, NULL, &inv_expr_id);
+ &depends_on, NULL, &inv_expr);
set_group_iv_cost (data, group, cand, cost, depends_on,
- NULL_TREE, ERROR_MARK, inv_expr_id);
+ NULL_TREE, ERROR_MARK, inv_expr);
return !infinite_cost_p (cost);
}
@@ -4970,12 +4995,12 @@ determine_group_iv_cost_address (struct ivopts_data *data,
unsigned i;
bitmap depends_on;
bool can_autoinc, first = true;
- int inv_expr_id = -1;
+ iv_inv_expr_ent *inv_expr = NULL;
struct iv_use *use = group->vuses[0];
comp_cost sum_cost = no_cost, cost;
cost = get_computation_cost (data, use, cand, true,
- &depends_on, &can_autoinc, &inv_expr_id);
+ &depends_on, &can_autoinc, &inv_expr);
sum_cost = cost;
if (!infinite_cost_p (sum_cost) && cand->ainc_use == use)
@@ -5023,7 +5048,7 @@ determine_group_iv_cost_address (struct ivopts_data *data,
sum_cost = add_costs (sum_cost, cost);
}
set_group_iv_cost (data, group, cand, sum_cost, depends_on,
- NULL_TREE, ERROR_MARK, inv_expr_id);
+ NULL_TREE, ERROR_MARK, inv_expr);
return !infinite_cost_p (sum_cost);
}
@@ -5079,8 +5104,8 @@ iv_period (struct iv *iv)
pow2div = num_ending_zeros (step);
period = build_low_bits_mask (type,
- (TYPE_PRECISION (type)
- - tree_to_uhwi (pow2div)));
+ (TYPE_PRECISION (type)
+ - tree_to_uhwi (pow2div)));
return period;
}
@@ -5213,7 +5238,7 @@ difference_cannot_overflow_p (struct ivopts_data *data, tree base, tree offset)
static bool
iv_elimination_compare_lt (struct ivopts_data *data,
- struct iv_cand *cand, enum tree_code *comp_p,
+ struct iv_cand *cand, enum tree_code *comp_p,
struct tree_niter_desc *niter)
{
tree cand_type, a, b, mbz, nit_type = TREE_TYPE (niter->niter), offset;
@@ -5262,10 +5287,10 @@ iv_elimination_compare_lt (struct ivopts_data *data,
/* Handle b < a + 1. */
if (TREE_CODE (op1) == PLUS_EXPR && integer_onep (TREE_OPERAND (op1, 1)))
- {
- a = TREE_OPERAND (op1, 0);
- b = TREE_OPERAND (mbz, 0);
- }
+ {
+ a = TREE_OPERAND (op1, 0);
+ b = TREE_OPERAND (mbz, 0);
+ }
else
return false;
}
@@ -5351,15 +5376,15 @@ may_eliminate_iv (struct ivopts_data *data,
{
/* See cand_value_at. */
if (stmt_after_increment (loop, cand, use->stmt))
- {
- if (!tree_int_cst_lt (desc->niter, period))
- return false;
- }
+ {
+ if (!tree_int_cst_lt (desc->niter, period))
+ return false;
+ }
else
- {
- if (tree_int_cst_lt (period, desc->niter))
- return false;
- }
+ {
+ if (tree_int_cst_lt (period, desc->niter))
+ return false;
+ }
}
/* If not, and if this is the only possible exit of the loop, see whether
@@ -5371,22 +5396,23 @@ may_eliminate_iv (struct ivopts_data *data,
max_niter = desc->max;
if (stmt_after_increment (loop, cand, use->stmt))
- max_niter += 1;
+ max_niter += 1;
period_value = wi::to_widest (period);
if (wi::gtu_p (max_niter, period_value))
- {
- /* See if we can take advantage of inferred loop bound information. */
- if (data->loop_single_exit_p)
- {
- if (!max_loop_iterations (loop, &max_niter))
- return false;
- /* The loop bound is already adjusted by adding 1. */
- if (wi::gtu_p (max_niter, period_value))
- return false;
- }
- else
- return false;
- }
+ {
+ /* See if we can take advantage of inferred loop bound
+ information. */
+ if (data->loop_single_exit_p)
+ {
+ if (!max_loop_iterations (loop, &max_niter))
+ return false;
+ /* The loop bound is already adjusted by adding 1. */
+ if (wi::gtu_p (max_niter, period_value))
+ return false;
+ }
+ else
+ return false;
+ }
}
cand_value_at (loop, cand, use->stmt, desc->niter, &bnd);
@@ -5442,7 +5468,7 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
bitmap depends_on_elim = NULL, depends_on_express = NULL, depends_on;
comp_cost elim_cost, express_cost, cost, bound_cost;
bool ok;
- int elim_inv_expr_id = -1, express_inv_expr_id = -1, inv_expr_id;
+ iv_inv_expr_ent *elim_inv_expr = NULL, *express_inv_expr = NULL, *inv_expr;
tree *control_var, *bound_cst;
enum tree_code comp = ERROR_MARK;
struct iv_use *use = group->vuses[0];
@@ -5454,18 +5480,18 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
{
elim_cost = force_var_cost (data, bound, &depends_on_elim);
if (elim_cost.cost == 0)
- elim_cost.cost = parm_decl_cost (data, bound);
+ elim_cost.cost = parm_decl_cost (data, bound);
else if (TREE_CODE (bound) == INTEGER_CST)
- elim_cost.cost = 0;
+ elim_cost.cost = 0;
/* If we replace a loop condition 'i < n' with 'p < base + n',
depends_on_elim will have 'base' and 'n' set, which implies
that both 'base' and 'n' will be live during the loop. More likely,
'base + n' will be loop invariant, resulting in only one live value
during the loop. So in that case we clear depends_on_elim and set
- elim_inv_expr_id instead. */
+ elim_inv_expr_id instead. */
if (depends_on_elim && bitmap_count_bits (depends_on_elim) > 1)
{
- elim_inv_expr_id = get_expr_id (data, bound);
+ elim_inv_expr = record_inv_expr (data, bound);
bitmap_clear (depends_on_elim);
}
/* The bound is a loop invariant, so it will be only computed
@@ -5495,7 +5521,7 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
express_cost = get_computation_cost (data, use, cand, false,
&depends_on_express, NULL,
- &express_inv_expr_id);
+ &express_inv_expr);
fd_ivopts_data = data;
walk_tree (&cmp_iv->base, find_depends, &depends_on_express, NULL);
@@ -5513,7 +5539,7 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
cost = elim_cost;
depends_on = depends_on_elim;
depends_on_elim = NULL;
- inv_expr_id = elim_inv_expr_id;
+ inv_expr = elim_inv_expr;
}
else
{
@@ -5522,11 +5548,11 @@ determine_group_iv_cost_cond (struct ivopts_data *data,
depends_on_express = NULL;
bound = NULL_TREE;
comp = ERROR_MARK;
- inv_expr_id = express_inv_expr_id;
+ inv_expr = express_inv_expr;
}
set_group_iv_cost (data, group, cand, cost,
- depends_on, bound, comp, inv_expr_id);
+ depends_on, bound, comp, inv_expr);
if (depends_on_elim)
BITMAP_FREE (depends_on_elim);
@@ -5716,14 +5742,31 @@ determine_group_iv_costs (struct ivopts_data *data)
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "<Group-candidate Costs>:\n");
+ fprintf (dump_file, "\n<Invariant Expressions>:\n");
+ auto_vec <iv_inv_expr_ent *> list (data->inv_expr_tab->elements ());
+
+ for (hash_table<iv_inv_expr_hasher>::iterator it
+ = data->inv_expr_tab->begin (); it != data->inv_expr_tab->end ();
+ ++it)
+ list.safe_push (*it);
+
+ list.qsort (sort_iv_inv_expr_ent);
+
+ for (i = 0; i < list.length (); ++i)
+ {
+ fprintf (dump_file, "inv_expr %d: \t", i);
+ print_generic_expr (dump_file, list[i]->expr, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+
+ fprintf (dump_file, "\n<Group-candidate Costs>:\n");
for (i = 0; i < data->vgroups.length (); i++)
{
group = data->vgroups[i];
fprintf (dump_file, "Group %d:\n", i);
- fprintf (dump_file, " cand\tcost\tcompl.\tdepends on\n");
+ fprintf (dump_file, " cand\tcost\tcompl.\tinv.ex.\tdepends on\n");
for (j = 0; j < group->n_map_members; j++)
{
if (!group->cost_map[j].cand
@@ -5734,12 +5777,14 @@ determine_group_iv_costs (struct ivopts_data *data)
group->cost_map[j].cand->id,
group->cost_map[j].cost.cost,
group->cost_map[j].cost.complexity);
+ if (group->cost_map[j].inv_expr != NULL)
+ fprintf (dump_file, "%d\t",
+ group->cost_map[j].inv_expr->id);
+ else
+ fprintf (dump_file, "\t");
if (group->cost_map[j].depends_on)
bitmap_print (dump_file,
group->cost_map[j].depends_on, "","");
- if (group->cost_map[j].inv_expr_id != -1)
- fprintf (dump_file, " inv_expr:%d",
- group->cost_map[j].inv_expr_id);
fprintf (dump_file, "\n");
}
@@ -5940,7 +5985,8 @@ iv_ca_recount_cost (struct ivopts_data *data, struct iv_ca *ivs)
cost.cost += ivs->cand_cost;
cost.cost += ivopts_global_cost_for_size (data,
- ivs->n_regs + ivs->num_used_inv_expr);
+ ivs->n_regs
+ + ivs->used_inv_exprs->elements ());
ivs->cost = cost;
}
@@ -5960,7 +6006,7 @@ iv_ca_set_remove_invariants (struct iv_ca *ivs, bitmap invs)
{
ivs->n_invariant_uses[iid]--;
if (ivs->n_invariant_uses[iid] == 0)
- ivs->n_regs--;
+ ivs->n_regs--;
}
}
@@ -5998,11 +6044,12 @@ iv_ca_set_no_cp (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_set_remove_invariants (ivs, cp->depends_on);
- if (cp->inv_expr_id != -1)
+ if (cp->inv_expr != NULL)
{
- ivs->used_inv_expr[cp->inv_expr_id]--;
- if (ivs->used_inv_expr[cp->inv_expr_id] == 0)
- ivs->num_used_inv_expr--;
+ unsigned *slot = ivs->used_inv_exprs->get (cp->inv_expr);
+ --(*slot);
+ if (*slot == 0)
+ ivs->used_inv_exprs->remove (cp->inv_expr);
}
iv_ca_recount_cost (data, ivs);
}
@@ -6022,7 +6069,7 @@ iv_ca_set_add_invariants (struct iv_ca *ivs, bitmap invs)
{
ivs->n_invariant_uses[iid]++;
if (ivs->n_invariant_uses[iid] == 1)
- ivs->n_regs++;
+ ivs->n_regs++;
}
}
@@ -6062,12 +6109,11 @@ iv_ca_set_cp (struct ivopts_data *data, struct iv_ca *ivs,
ivs->cand_use_cost = add_costs (ivs->cand_use_cost, cp->cost);
iv_ca_set_add_invariants (ivs, cp->depends_on);
- if (cp->inv_expr_id != -1)
- {
- ivs->used_inv_expr[cp->inv_expr_id]++;
- if (ivs->used_inv_expr[cp->inv_expr_id] == 1)
- ivs->num_used_inv_expr++;
- }
+ if (cp->inv_expr != NULL)
+ {
+ unsigned *slot = &ivs->used_inv_exprs->get_or_insert (cp->inv_expr);
+ ++(*slot);
+ }
iv_ca_recount_cost (data, ivs);
}
}
@@ -6276,9 +6322,8 @@ iv_ca_new (struct ivopts_data *data)
nw->cand_use_cost = no_cost;
nw->cand_cost = 0;
nw->n_invariant_uses = XCNEWVEC (unsigned, data->max_inv_id + 1);
+ nw->used_inv_exprs = new hash_map <iv_inv_expr_ent *, unsigned> (13);
nw->cost = no_cost;
- nw->used_inv_expr = XCNEWVEC (unsigned, data->inv_expr_id + 1);
- nw->num_used_inv_expr = 0;
return nw;
}
@@ -6292,7 +6337,7 @@ iv_ca_free (struct iv_ca **ivs)
free ((*ivs)->n_cand_uses);
BITMAP_FREE ((*ivs)->cands);
free ((*ivs)->n_invariant_uses);
- free ((*ivs)->used_inv_expr);
+ delete ((*ivs)->used_inv_exprs);
free (*ivs);
*ivs = NULL;
}
@@ -6302,13 +6347,13 @@ iv_ca_free (struct iv_ca **ivs)
static void
iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
{
- const char *pref = " invariants ";
unsigned i;
comp_cost cost = iv_ca_cost (ivs);
fprintf (file, " cost: %d (complexity %d)\n", cost.cost, cost.complexity);
fprintf (file, " cand_cost: %d\n cand_group_cost: %d (complexity %d)\n",
- ivs->cand_cost, ivs->cand_use_cost.cost, ivs->cand_use_cost.complexity);
+ ivs->cand_cost, ivs->cand_use_cost.cost,
+ ivs->cand_use_cost.complexity);
bitmap_print (file, ivs->cands, " candidates: ","\n");
for (i = 0; i < ivs->upto; i++)
@@ -6322,12 +6367,24 @@ iv_ca_dump (struct ivopts_data *data, FILE *file, struct iv_ca *ivs)
fprintf (file, " group:%d --> ??\n", group->id);
}
+ const char *pref = "";
+ fprintf (file, " invariant variables: ");
for (i = 1; i <= data->max_inv_id; i++)
if (ivs->n_invariant_uses[i])
{
fprintf (file, "%s%d", pref, i);
pref = ", ";
}
+
+ pref = "";
+ fprintf (file, "\n invariant expressions: ");
+ for (hash_map<iv_inv_expr_ent *, unsigned>::iterator it
+ = ivs->used_inv_exprs->begin (); it != ivs->used_inv_exprs->end (); ++it)
+ {
+ fprintf (file, "%s%d", pref, (*it).first->id);
+ pref = ", ";
+ }
+
fprintf (file, "\n\n");
}
@@ -6364,7 +6421,7 @@ iv_ca_extend (struct ivopts_data *data, struct iv_ca *ivs,
continue;
if (!min_ncand && !cheaper_cost_pair (new_cp, old_cp))
- continue;
+ continue;
*delta = iv_ca_delta_add (group, old_cp, new_cp, *delta);
}
@@ -6668,7 +6725,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
continue;
if (iv_ca_cand_used_p (ivs, cand))
- continue;
+ continue;
cp = get_group_iv_cost (data, group, cand);
if (!cp)
@@ -6676,7 +6733,7 @@ try_add_cand_for (struct ivopts_data *data, struct iv_ca *ivs,
iv_ca_set_cp (data, ivs, group, cp);
act_cost = iv_ca_extend (data, ivs, cand, &act_delta, NULL,
- true);
+ true);
iv_ca_set_no_cp (data, ivs, group);
act_delta = iv_ca_delta_add (group, NULL, cp, act_delta);
@@ -6989,12 +7046,16 @@ create_new_ivs (struct ivopts_data *data, struct iv_ca *set)
if (data->loop_loc != UNKNOWN_LOCATION)
fprintf (dump_file, " at %s:%d", LOCATION_FILE (data->loop_loc),
LOCATION_LINE (data->loop_loc));
+ fprintf (dump_file, ", " HOST_WIDE_INT_PRINT_DEC " avg niters",
+ avg_loop_niter (data->current_loop));
+ fprintf (dump_file, ", " HOST_WIDE_INT_PRINT_UNSIGNED " expressions",
+ (unsigned HOST_WIDE_INT) set->used_inv_exprs->elements ());
fprintf (dump_file, ", %lu IVs:\n", bitmap_count_bits (set->cands));
EXECUTE_IF_SET_IN_BITMAP (set->cands, 0, i, bi)
- {
- cand = data->vcands[i];
- dump_cand (dump_file, cand);
- }
+ {
+ cand = data->vcands[i];
+ dump_cand (dump_file, cand);
+ }
fprintf (dump_file, "\n");
}
}
@@ -7249,10 +7310,10 @@ rewrite_use_compare (struct ivopts_data *data,
gimple_seq stmts;
if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Replacing exit test: ");
- print_gimple_stmt (dump_file, use->stmt, 0, TDF_SLIM);
- }
+ {
+ fprintf (dump_file, "Replacing exit test: ");
+ print_gimple_stmt (dump_file, use->stmt, 0, TDF_SLIM);
+ }
compare = cp->comp;
bound = unshare_expr (fold_convert (var_type, bound));
op = force_gimple_operand (bound, &stmts, true, NULL_TREE);
@@ -7540,7 +7601,7 @@ free_loop_data (struct ivopts_data *data)
decl_rtl_to_reset.truncate (0);
data->inv_expr_tab->empty ();
- data->inv_expr_id = 0;
+ data->max_inv_expr_id = 0;
data->iv_common_cand_tab->empty ();
data->iv_common_cands.truncate (0);
diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c
index c61083e7fd3..5afc9b3fdf0 100644
--- a/gcc/tree-ssa-loop-niter.c
+++ b/gcc/tree-ssa-loop-niter.c
@@ -3115,7 +3115,6 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
tree low, high, type, next;
bool sign, upper = true, at_end = false;
struct loop *loop = data->loop;
- bool reliable = true;
if (TREE_CODE (base) != ARRAY_REF)
return true;
@@ -3187,14 +3186,14 @@ idx_infer_loop_bounds (tree base, tree *idx, void *dta)
&& tree_int_cst_compare (next, high) <= 0)
return true;
- /* If access is not executed on every iteration, we must ensure that overlow may
- not make the access valid later. */
+ /* If access is not executed on every iteration, we must ensure that overlow
+ may not make the access valid later. */
if (!dominated_by_p (CDI_DOMINATORS, loop->latch, gimple_bb (data->stmt))
&& scev_probably_wraps_p (initial_condition_in_loop_num (ev, loop->num),
step, data->stmt, loop, true))
- reliable = false;
+ upper = false;
- record_nonwrapping_iv (loop, init, step, data->stmt, low, high, reliable, upper);
+ record_nonwrapping_iv (loop, init, step, data->stmt, low, high, false, upper);
return true;
}
diff --git a/gcc/tree-ssa-loop-prefetch.c b/gcc/tree-ssa-loop-prefetch.c
index c054c60203c..fb8c4763769 100644
--- a/gcc/tree-ssa-loop-prefetch.c
+++ b/gcc/tree-ssa-loop-prefetch.c
@@ -631,6 +631,9 @@ gather_memory_references (struct loop *loop, bool *no_other_refs, unsigned *ref_
continue;
}
+ if (! gimple_vuse (stmt))
+ continue;
+
lhs = gimple_assign_lhs (stmt);
rhs = gimple_assign_rhs1 (stmt);
@@ -1546,7 +1549,7 @@ determine_loop_nest_reuse (struct loop *loop, struct mem_ref_group *refs,
vec<ddr_p> dependences = vNULL;
struct mem_ref_group *gr;
struct mem_ref *ref, *refb;
- vec<loop_p> vloops = vNULL;
+ auto_vec<loop_p> vloops;
unsigned *loop_data_size;
unsigned i, j, n;
unsigned volume, dist, adist;
diff --git a/gcc/tree-ssa-loop-unswitch.c b/gcc/tree-ssa-loop-unswitch.c
index 77acd66e997..bf9fafa63b2 100644
--- a/gcc/tree-ssa-loop-unswitch.c
+++ b/gcc/tree-ssa-loop-unswitch.c
@@ -536,6 +536,12 @@ find_loop_guard (struct loop *loop)
guard_edge->src->index, guard_edge->dest->index);
return NULL;
}
+ if (guard_edge->dest == loop->latch)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Guard edge destination is loop latch.\n");
+ return NULL;
+ }
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index 3fcf24c4f9c..81688cd096c 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -2160,9 +2160,16 @@ perform_symbolic_merge (gimple *source_stmt1, struct symbolic_number *n1,
gimple *source_stmt;
struct symbolic_number *n_start;
+ tree rhs1 = gimple_assign_rhs1 (source_stmt1);
+ if (TREE_CODE (rhs1) == BIT_FIELD_REF)
+ rhs1 = TREE_OPERAND (rhs1, 0);
+ tree rhs2 = gimple_assign_rhs1 (source_stmt2);
+ if (TREE_CODE (rhs2) == BIT_FIELD_REF)
+ rhs2 = TREE_OPERAND (rhs2, 0);
+
/* Sources are different, cancel bswap if they are not memory location with
the same base (array, structure, ...). */
- if (gimple_assign_rhs1 (source_stmt1) != gimple_assign_rhs1 (source_stmt2))
+ if (rhs1 != rhs2)
{
uint64_t inc;
HOST_WIDE_INT start_sub, end_sub, end1, end2, end;
@@ -2285,6 +2292,39 @@ find_bswap_or_nop_1 (gimple *stmt, struct symbolic_number *n, int limit)
if (find_bswap_or_nop_load (stmt, rhs1, n))
return stmt;
+ /* Handle BIT_FIELD_REF. */
+ if (TREE_CODE (rhs1) == BIT_FIELD_REF
+ && TREE_CODE (TREE_OPERAND (rhs1, 0)) == SSA_NAME)
+ {
+ unsigned HOST_WIDE_INT bitsize = tree_to_uhwi (TREE_OPERAND (rhs1, 1));
+ unsigned HOST_WIDE_INT bitpos = tree_to_uhwi (TREE_OPERAND (rhs1, 2));
+ if (bitpos % BITS_PER_UNIT == 0
+ && bitsize % BITS_PER_UNIT == 0
+ && init_symbolic_number (n, TREE_OPERAND (rhs1, 0)))
+ {
+ /* Shift. */
+ if (!do_shift_rotate (RSHIFT_EXPR, n, bitpos))
+ return NULL;
+
+ /* Mask. */
+ uint64_t mask = 0;
+ uint64_t tmp = (1 << BITS_PER_UNIT) - 1;
+ for (unsigned i = 0; i < bitsize / BITS_PER_UNIT;
+ i++, tmp <<= BITS_PER_UNIT)
+ mask |= (uint64_t) MARKER_MASK << (i * BITS_PER_MARKER);
+ n->n &= mask;
+
+ /* Convert. */
+ n->type = TREE_TYPE (rhs1);
+ if (!n->base_addr)
+ n->range = TYPE_PRECISION (n->type) / BITS_PER_UNIT;
+
+ return verify_symbolic_number_p (n, stmt) ? stmt : NULL;
+ }
+
+ return NULL;
+ }
+
if (TREE_CODE (rhs1) != SSA_NAME)
return NULL;
@@ -2683,6 +2723,8 @@ bswap_replace (gimple *cur_stmt, gimple *src_stmt, tree fndecl,
}
src = val_tmp;
}
+ else if (TREE_CODE (src) == BIT_FIELD_REF)
+ src = TREE_OPERAND (src, 0);
if (n->range == 16)
bswap_stats.found_16bit++;
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 7d59bfda24b..eccea2f62b9 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -833,6 +833,7 @@ get_expr_operands (struct function *fn, gimple *stmt, tree *expr_p, int flags)
get_expr_operands (fn, stmt, &TREE_OPERAND (expr, 0), flags);
return;
+ case BIT_INSERT_EXPR:
case COMPOUND_EXPR:
case OBJ_TYPE_REF:
case ASSERT_EXPR:
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index 80d2fc4cf45..20fda6cb714 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimplify.h"
#include "gimple-iterator.h"
#include "stor-layout.h"
+#include "tree-ssa-loop.h"
/* This pass propagates indirect loads through the PHI node for its
address to make the load source possibly non-addressable and to
@@ -230,6 +231,19 @@ phiprop_insert_phi (basic_block bb, gphi *phi, gimple *use_stmt,
return res;
}
+/* Verify if *idx is available at *DATA. */
+
+static bool
+chk_uses (tree, tree *idx, void *data)
+{
+ basic_block dom = (basic_block) data;
+ if (TREE_CODE (*idx) == SSA_NAME)
+ return (SSA_NAME_IS_DEFAULT_DEF (*idx)
+ || ! dominated_by_p (CDI_DOMINATORS,
+ gimple_bb (SSA_NAME_DEF_STMT (*idx)), dom));
+ return true;
+}
+
/* Propagate between the phi node arguments of PHI in BB and phi result
users. For now this matches
# p_2 = PHI <&x, &y>
@@ -342,6 +356,13 @@ propagate_with_phi (basic_block bb, gphi *phi, struct phiprop_d *phivn,
insert aggregate copies on the edges instead. */
if (!is_gimple_reg_type (TREE_TYPE (TREE_TYPE (ptr))))
{
+ /* As we replicate the lhs on each incoming edge all
+ used SSA names have to be available there. */
+ if (! for_each_index (gimple_assign_lhs_ptr (use_stmt),
+ chk_uses,
+ get_immediate_dominator (CDI_DOMINATORS,
+ gimple_bb (phi))))
+ goto next;
phiprop_insert_phi (bb, phi, use_stmt, phivn, n);
/* Remove old stmt. The phi is taken care of by DCE. */
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 7b9eb2e5b9c..3ce87d9d23f 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -1464,6 +1464,12 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
pre_expr constant;
unsigned int new_val_id;
+ PRE_EXPR_NARY (expr) = newnary;
+ constant = fully_constant_expression (expr);
+ PRE_EXPR_NARY (expr) = nary;
+ if (constant != expr)
+ return constant;
+
tree result = vn_nary_op_lookup_pieces (newnary->length,
newnary->opcode,
newnary->type,
@@ -1478,10 +1484,6 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
if (nary)
{
PRE_EXPR_NARY (expr) = nary;
- constant = fully_constant_expression (expr);
- if (constant != expr)
- return constant;
-
new_val_id = nary->value_id;
get_or_alloc_expression_id (expr);
}
@@ -1495,9 +1497,6 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
&newnary->op[0],
result, new_val_id);
PRE_EXPR_NARY (expr) = nary;
- constant = fully_constant_expression (expr);
- if (constant != expr)
- return constant;
get_or_alloc_expression_id (expr);
}
add_to_value (new_val_id, expr);
@@ -3855,19 +3854,28 @@ eliminate_insert (gimple_stmt_iterator *gsi, tree val)
gimple *stmt = gimple_seq_first_stmt (VN_INFO (val)->expr);
if (!is_gimple_assign (stmt)
|| (!CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (stmt))
- && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR))
+ && gimple_assign_rhs_code (stmt) != VIEW_CONVERT_EXPR
+ && gimple_assign_rhs_code (stmt) != BIT_FIELD_REF))
return NULL_TREE;
tree op = gimple_assign_rhs1 (stmt);
- if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR)
+ if (gimple_assign_rhs_code (stmt) == VIEW_CONVERT_EXPR
+ || gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
op = TREE_OPERAND (op, 0);
tree leader = TREE_CODE (op) == SSA_NAME ? eliminate_avail (op) : op;
if (!leader)
return NULL_TREE;
gimple_seq stmts = NULL;
- tree res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
- TREE_TYPE (val), leader);
+ tree res;
+ if (gimple_assign_rhs_code (stmt) == BIT_FIELD_REF)
+ res = gimple_build (&stmts, BIT_FIELD_REF,
+ TREE_TYPE (val), leader,
+ TREE_OPERAND (gimple_assign_rhs1 (stmt), 1),
+ TREE_OPERAND (gimple_assign_rhs1 (stmt), 2));
+ else
+ res = gimple_build (&stmts, gimple_assign_rhs_code (stmt),
+ TREE_TYPE (val), leader);
gsi_insert_seq_before (gsi, stmts, GSI_SAME_STMT);
VN_INFO_GET (res)->valnum = val;
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 740897756bd..798931fee7a 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -732,7 +732,7 @@ eliminate_duplicate_pair (enum tree_code opcode,
if (ops->length () == 2)
{
- ops->create (0);
+ ops->truncate (0);
add_to_ops_vec (ops, build_zero_cst (TREE_TYPE (last->op)));
*all_done = true;
}
@@ -1756,6 +1756,83 @@ eliminate_redundant_comparison (enum tree_code opcode,
return false;
}
+/* Transform repeated addition of same values into multiply with
+ constant. */
+static bool
+transform_add_to_multiply (gimple *stmt, vec<operand_entry *> *ops)
+{
+ operand_entry *oe;
+ tree op = NULL_TREE;
+ int j;
+ int i, start = -1, end = 0, count = 0;
+ vec<std::pair <int, int> > indxs = vNULL;
+ bool changed = false;
+
+ if (!INTEGRAL_TYPE_P (TREE_TYPE ((*ops)[0]->op))
+ && (!SCALAR_FLOAT_TYPE_P (TREE_TYPE ((*ops)[0]->op))
+ || !flag_unsafe_math_optimizations))
+ return false;
+
+ /* Look for repeated operands. */
+ FOR_EACH_VEC_ELT (*ops, i, oe)
+ {
+ if (start == -1)
+ {
+ count = 1;
+ op = oe->op;
+ start = i;
+ }
+ else if (operand_equal_p (oe->op, op, 0))
+ {
+ count++;
+ end = i;
+ }
+ else
+ {
+ if (count > 1)
+ indxs.safe_push (std::make_pair (start, end));
+ count = 1;
+ op = oe->op;
+ start = i;
+ }
+ }
+
+ if (count > 1)
+ indxs.safe_push (std::make_pair (start, end));
+
+ for (j = indxs.length () - 1; j >= 0; --j)
+ {
+ /* Convert repeated operand addition to multiplication. */
+ start = indxs[j].first;
+ end = indxs[j].second;
+ op = (*ops)[start]->op;
+ count = end - start + 1;
+ for (i = end; i >= start; --i)
+ ops->unordered_remove (i);
+ tree tmp = make_ssa_name (TREE_TYPE (op));
+ tree cst = build_int_cst (integer_type_node, count);
+ gimple *def_stmt = SSA_NAME_DEF_STMT (op);
+ gassign *mul_stmt
+ = gimple_build_assign (tmp, MULT_EXPR,
+ op, fold_convert (TREE_TYPE (op), cst));
+ if (gimple_code (def_stmt) == GIMPLE_NOP
+ || gimple_bb (stmt) != gimple_bb (def_stmt))
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ gimple_set_uid (mul_stmt, gimple_uid (stmt));
+ gsi_insert_before (&gsi, mul_stmt, GSI_NEW_STMT);
+ }
+ else
+ insert_stmt_after (mul_stmt, def_stmt);
+ gimple_set_visited (mul_stmt, true);
+ add_to_ops_vec (ops, tmp);
+ changed = true;
+ }
+
+ return changed;
+}
+
+
/* Perform various identities and other optimizations on the list of
operand entries, stored in OPS. The tree code for the binary
operation between all the operands is OPCODE. */
@@ -4252,6 +4329,45 @@ acceptable_pow_call (gimple *stmt, tree *base, HOST_WIDE_INT *exponent)
return true;
}
+/* Try to derive and add operand entry for OP to *OPS. Return false if
+ unsuccessful. */
+
+static bool
+try_special_add_to_ops (vec<operand_entry *> *ops,
+ enum tree_code code,
+ tree op, gimple* def_stmt)
+{
+ tree base = NULL_TREE;
+ HOST_WIDE_INT exponent = 0;
+
+ if (TREE_CODE (op) != SSA_NAME)
+ return false;
+
+ if (code == MULT_EXPR
+ && acceptable_pow_call (def_stmt, &base, &exponent))
+ {
+ add_repeat_to_ops_vec (ops, base, exponent);
+ gimple_set_visited (def_stmt, true);
+ return true;
+ }
+ else if (code == MULT_EXPR
+ && is_gimple_assign (def_stmt)
+ && gimple_assign_rhs_code (def_stmt) == NEGATE_EXPR
+ && !HONOR_SNANS (TREE_TYPE (op))
+ && (!HONOR_SIGNED_ZEROS (TREE_TYPE (op))
+ || !COMPLEX_FLOAT_TYPE_P (TREE_TYPE (op))))
+ {
+ tree rhs1 = gimple_assign_rhs1 (def_stmt);
+ tree cst = build_minus_one_cst (TREE_TYPE (op));
+ add_to_ops_vec (ops, rhs1);
+ add_to_ops_vec (ops, cst);
+ gimple_set_visited (def_stmt, true);
+ return true;
+ }
+
+ return false;
+}
+
/* Recursively linearize a binary expression that is the RHS of STMT.
Place the operands of the expression tree in the vector named OPS. */
@@ -4266,8 +4382,6 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt,
bool binrhsisreassoc = false;
enum tree_code rhscode = gimple_assign_rhs_code (stmt);
struct loop *loop = loop_containing_stmt (stmt);
- tree base = NULL_TREE;
- HOST_WIDE_INT exponent = 0;
if (set_visited)
gimple_set_visited (stmt, true);
@@ -4303,24 +4417,10 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt,
if (!binrhsisreassoc)
{
- if (rhscode == MULT_EXPR
- && TREE_CODE (binrhs) == SSA_NAME
- && acceptable_pow_call (binrhsdef, &base, &exponent))
- {
- add_repeat_to_ops_vec (ops, base, exponent);
- gimple_set_visited (binrhsdef, true);
- }
- else
+ if (!try_special_add_to_ops (ops, rhscode, binrhs, binrhsdef))
add_to_ops_vec (ops, binrhs);
- if (rhscode == MULT_EXPR
- && TREE_CODE (binlhs) == SSA_NAME
- && acceptable_pow_call (binlhsdef, &base, &exponent))
- {
- add_repeat_to_ops_vec (ops, base, exponent);
- gimple_set_visited (binlhsdef, true);
- }
- else
+ if (!try_special_add_to_ops (ops, rhscode, binlhs, binlhsdef))
add_to_ops_vec (ops, binlhs);
return;
@@ -4360,14 +4460,7 @@ linearize_expr_tree (vec<operand_entry *> *ops, gimple *stmt,
linearize_expr_tree (ops, SSA_NAME_DEF_STMT (binlhs),
is_associative, set_visited);
- if (rhscode == MULT_EXPR
- && TREE_CODE (binrhs) == SSA_NAME
- && acceptable_pow_call (SSA_NAME_DEF_STMT (binrhs), &base, &exponent))
- {
- add_repeat_to_ops_vec (ops, base, exponent);
- gimple_set_visited (SSA_NAME_DEF_STMT (binrhs), true);
- }
- else
+ if (!try_special_add_to_ops (ops, rhscode, binrhs, binrhsdef))
add_to_ops_vec (ops, binrhs);
}
@@ -5110,6 +5203,10 @@ reassociate_bb (basic_block bb)
optimize_ops_list (rhs_code, &ops);
}
+ if (rhs_code == PLUS_EXPR
+ && transform_add_to_multiply (stmt, &ops))
+ ops.qsort (sort_by_operand_rank);
+
if (rhs_code == BIT_IOR_EXPR || rhs_code == BIT_AND_EXPR)
{
if (is_vector)
@@ -5127,6 +5224,24 @@ reassociate_bb (basic_block bb)
powi_result = attempt_builtin_powi (stmt, &ops);
}
+ operand_entry *last;
+ bool negate_result = false;
+ if (ops.length () > 1
+ && rhs_code == MULT_EXPR)
+ {
+ last = ops.last ();
+ if (((TREE_CODE (last->op) == INTEGER_CST
+ && integer_minus_onep (last->op))
+ || real_minus_onep (last->op))
+ && !HONOR_SNANS (TREE_TYPE (lhs))
+ && (!HONOR_SIGNED_ZEROS (TREE_TYPE (lhs))
+ || !COMPLEX_FLOAT_TYPE_P (TREE_TYPE (lhs))))
+ {
+ ops.pop ();
+ negate_result = true;
+ }
+ }
+
/* If the operand vector is now empty, all operands were
consumed by the __builtin_powi optimization. */
if (ops.length () == 0)
@@ -5189,6 +5304,18 @@ reassociate_bb (basic_block bb)
gsi_insert_after (&gsi, mul_stmt, GSI_NEW_STMT);
}
}
+
+ if (negate_result)
+ {
+ stmt = SSA_NAME_DEF_STMT (lhs);
+ tree tmp = make_ssa_name (TREE_TYPE (lhs));
+ gimple_set_lhs (stmt, tmp);
+ gassign *neg_stmt = gimple_build_assign (lhs, NEGATE_EXPR,
+ tmp);
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ gsi_insert_after (&gsi, neg_stmt, GSI_NEW_STMT);
+ update_stmt (stmt);
+ }
}
}
}
diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c
index 2dbe4084420..730db04ff8b 100644
--- a/gcc/tree-ssa-sccvn.c
+++ b/gcc/tree-ssa-sccvn.c
@@ -1610,6 +1610,115 @@ vn_reference_lookup_or_insert_for_pieces (tree vuse,
operands.copy (), value, value_id);
}
+static vn_nary_op_t vn_nary_op_insert_stmt (gimple *stmt, tree result);
+
+/* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */
+
+static tree
+vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops)
+{
+ if (!rcode.is_tree_code ())
+ return NULL_TREE;
+ vn_nary_op_t vnresult = NULL;
+ return vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode),
+ (tree_code) rcode, type, ops, &vnresult);
+}
+
+/* Return a value-number for RCODE OPS... either by looking up an existing
+ value-number for the simplified result or by inserting the operation. */
+
+static tree
+vn_nary_build_or_lookup (code_helper rcode, tree type, tree *ops)
+{
+ tree result = NULL_TREE;
+ /* We will be creating a value number for
+ RCODE (OPS...).
+ So first simplify and lookup this expression to see if it
+ is already available. */
+ mprts_hook = vn_lookup_simplify_result;
+ bool res = false;
+ switch (TREE_CODE_LENGTH ((tree_code) rcode))
+ {
+ case 1:
+ res = gimple_resimplify1 (NULL, &rcode, type, ops, vn_valueize);
+ break;
+ case 2:
+ res = gimple_resimplify2 (NULL, &rcode, type, ops, vn_valueize);
+ break;
+ case 3:
+ res = gimple_resimplify3 (NULL, &rcode, type, ops, vn_valueize);
+ break;
+ }
+ mprts_hook = NULL;
+ gimple *new_stmt = NULL;
+ if (res
+ && gimple_simplified_result_is_gimple_val (rcode, ops))
+ /* The expression is already available. */
+ result = ops[0];
+ else
+ {
+ tree val = vn_lookup_simplify_result (rcode, type, ops);
+ if (!val)
+ {
+ gimple_seq stmts = NULL;
+ result = maybe_push_res_to_seq (rcode, type, ops, &stmts);
+ if (result)
+ {
+ gcc_assert (gimple_seq_singleton_p (stmts));
+ new_stmt = gimple_seq_first_stmt (stmts);
+ }
+ }
+ else
+ /* The expression is already available. */
+ result = val;
+ }
+ if (new_stmt)
+ {
+ /* The expression is not yet available, value-number lhs to
+ the new SSA_NAME we created. */
+ /* Initialize value-number information properly. */
+ VN_INFO_GET (result)->valnum = result;
+ VN_INFO (result)->value_id = get_next_value_id ();
+ gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
+ new_stmt);
+ VN_INFO (result)->needs_insertion = true;
+ /* ??? PRE phi-translation inserts NARYs without corresponding
+ SSA name result. Re-use those but set their result according
+ to the stmt we just built. */
+ vn_nary_op_t nary = NULL;
+ vn_nary_op_lookup_stmt (new_stmt, &nary);
+ if (nary)
+ {
+ gcc_assert (nary->result == NULL_TREE);
+ nary->result = gimple_assign_lhs (new_stmt);
+ }
+ /* As all "inserted" statements are singleton SCCs, insert
+ to the valid table. This is strictly needed to
+ avoid re-generating new value SSA_NAMEs for the same
+ expression during SCC iteration over and over (the
+ optimistic table gets cleared after each iteration).
+ We do not need to insert into the optimistic table, as
+ lookups there will fall back to the valid table. */
+ else if (current_info == optimistic_info)
+ {
+ current_info = valid_info;
+ vn_nary_op_insert_stmt (new_stmt, result);
+ current_info = optimistic_info;
+ }
+ else
+ vn_nary_op_insert_stmt (new_stmt, result);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ fprintf (dump_file, "Inserting name ");
+ print_generic_expr (dump_file, result, 0);
+ fprintf (dump_file, " for expression ");
+ print_gimple_expr (dump_file, new_stmt, 0, TDF_SLIM);
+ fprintf (dump_file, "\n");
+ }
+ }
+ return result;
+}
+
/* Callback for walk_non_aliased_vuses. Tries to perform a lookup
from the statement defining VUSE and if not successful tries to
translate *REFP and VR_ through an aggregate copy at the definition
@@ -1772,15 +1881,16 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
/* 3) Assignment from a constant. We can use folds native encode/interpret
routines to extract the assigned bits. */
- else if (vn_walk_kind == VN_WALKREWRITE
- && CHAR_BIT == 8 && BITS_PER_UNIT == 8
- && ref->size == maxsize
- && maxsize % BITS_PER_UNIT == 0
- && offset % BITS_PER_UNIT == 0
+ else if (ref->size == maxsize
&& is_gimple_reg_type (vr->type)
&& !contains_storage_order_barrier_p (vr->operands)
&& gimple_assign_single_p (def_stmt)
- && is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt)))
+ && CHAR_BIT == 8 && BITS_PER_UNIT == 8
+ && maxsize % BITS_PER_UNIT == 0
+ && offset % BITS_PER_UNIT == 0
+ && (is_gimple_min_invariant (gimple_assign_rhs1 (def_stmt))
+ || (TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME
+ && is_gimple_min_invariant (SSA_VAL (gimple_assign_rhs1 (def_stmt))))))
{
tree base2;
HOST_WIDE_INT offset2, size2, maxsize2;
@@ -1800,18 +1910,41 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
unsigned char buffer[64];
int len;
+ tree rhs = gimple_assign_rhs1 (def_stmt);
+ if (TREE_CODE (rhs) == SSA_NAME)
+ rhs = SSA_VAL (rhs);
len = native_encode_expr (gimple_assign_rhs1 (def_stmt),
buffer, sizeof (buffer));
if (len > 0)
{
- tree val = native_interpret_expr (vr->type,
+ tree type = vr->type;
+ /* Make sure to interpret in a type that has a range
+ covering the whole access size. */
+ if (INTEGRAL_TYPE_P (vr->type)
+ && ref->size != TYPE_PRECISION (vr->type))
+ type = build_nonstandard_integer_type (ref->size,
+ TYPE_UNSIGNED (type));
+ tree val = native_interpret_expr (type,
buffer
+ ((offset - offset2)
/ BITS_PER_UNIT),
ref->size / BITS_PER_UNIT);
+ /* If we chop off bits because the types precision doesn't
+ match the memory access size this is ok when optimizing
+ reads but not when called from the DSE code during
+ elimination. */
+ if (val
+ && type != vr->type)
+ {
+ if (! int_fits_type_p (val, vr->type))
+ val = NULL_TREE;
+ else
+ val = fold_convert (vr->type, val);
+ }
+
if (val)
return vn_reference_lookup_or_insert_for_pieces
- (vuse, vr->set, vr->type, vr->operands, val);
+ (vuse, vr->set, vr->type, vr->operands, val);
}
}
}
@@ -1824,56 +1957,37 @@ vn_reference_lookup_3 (ao_ref *ref, tree vuse, void *vr_,
&& gimple_assign_single_p (def_stmt)
&& TREE_CODE (gimple_assign_rhs1 (def_stmt)) == SSA_NAME)
{
- tree rhs1 = gimple_assign_rhs1 (def_stmt);
- gimple *def_stmt2 = SSA_NAME_DEF_STMT (rhs1);
- if (is_gimple_assign (def_stmt2)
- && (gimple_assign_rhs_code (def_stmt2) == COMPLEX_EXPR
- || gimple_assign_rhs_code (def_stmt2) == CONSTRUCTOR)
- && types_compatible_p (vr->type, TREE_TYPE (TREE_TYPE (rhs1))))
+ tree base2;
+ HOST_WIDE_INT offset2, size2, maxsize2;
+ bool reverse;
+ base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
+ &offset2, &size2, &maxsize2,
+ &reverse);
+ if (!reverse
+ && maxsize2 != -1
+ && maxsize2 == size2
+ && operand_equal_p (base, base2, 0)
+ && offset2 <= offset
+ && offset2 + size2 >= offset + maxsize
+ /* ??? We can't handle bitfield precision extracts without
+ either using an alternate type for the BIT_FIELD_REF and
+ then doing a conversion or possibly adjusting the offset
+ according to endianess. */
+ && (! INTEGRAL_TYPE_P (vr->type)
+ || ref->size == TYPE_PRECISION (vr->type))
+ && ref->size % BITS_PER_UNIT == 0)
{
- tree base2;
- HOST_WIDE_INT offset2, size2, maxsize2, off;
- bool reverse;
- base2 = get_ref_base_and_extent (gimple_assign_lhs (def_stmt),
- &offset2, &size2, &maxsize2,
- &reverse);
- off = offset - offset2;
- if (!reverse
- && maxsize2 != -1
- && maxsize2 == size2
- && operand_equal_p (base, base2, 0)
- && offset2 <= offset
- && offset2 + size2 >= offset + maxsize)
+ code_helper rcode = BIT_FIELD_REF;
+ tree ops[3];
+ ops[0] = SSA_VAL (gimple_assign_rhs1 (def_stmt));
+ ops[1] = bitsize_int (ref->size);
+ ops[2] = bitsize_int (offset - offset2);
+ tree val = vn_nary_build_or_lookup (rcode, vr->type, ops);
+ if (val)
{
- tree val = NULL_TREE;
- HOST_WIDE_INT elsz
- = TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (TREE_TYPE (rhs1))));
- if (gimple_assign_rhs_code (def_stmt2) == COMPLEX_EXPR)
- {
- if (off == 0)
- val = gimple_assign_rhs1 (def_stmt2);
- else if (off == elsz)
- val = gimple_assign_rhs2 (def_stmt2);
- }
- else if (gimple_assign_rhs_code (def_stmt2) == CONSTRUCTOR
- && off % elsz == 0)
- {
- tree ctor = gimple_assign_rhs1 (def_stmt2);
- unsigned i = off / elsz;
- if (i < CONSTRUCTOR_NELTS (ctor))
- {
- constructor_elt *elt = CONSTRUCTOR_ELT (ctor, i);
- if (TREE_CODE (TREE_TYPE (rhs1)) == VECTOR_TYPE)
- {
- if (TREE_CODE (TREE_TYPE (elt->value))
- != VECTOR_TYPE)
- val = elt->value;
- }
- }
- }
- if (val)
- return vn_reference_lookup_or_insert_for_pieces
- (vuse, vr->set, vr->type, vr->operands, val);
+ vn_reference_t res = vn_reference_lookup_or_insert_for_pieces
+ (vuse, vr->set, vr->type, vr->operands, val);
+ return res;
}
}
}
@@ -2611,18 +2725,6 @@ vn_nary_op_lookup_stmt (gimple *stmt, vn_nary_op_t *vnresult)
return vn_nary_op_lookup_1 (vno1, vnresult);
}
-/* Hook for maybe_push_res_to_seq, lookup the expression in the VN tables. */
-
-static tree
-vn_lookup_simplify_result (code_helper rcode, tree type, tree *ops)
-{
- if (!rcode.is_tree_code ())
- return NULL_TREE;
- vn_nary_op_t vnresult = NULL;
- return vn_nary_op_lookup_pieces (TREE_CODE_LENGTH ((tree_code) rcode),
- (tree_code) rcode, type, ops, &vnresult);
-}
-
/* Allocate a vn_nary_op_t with LENGTH operands on STACK. */
static vn_nary_op_t
@@ -3371,69 +3473,9 @@ visit_reference_op_load (tree lhs, tree op, gimple *stmt)
of VIEW_CONVERT_EXPR <TREE_TYPE (result)> (result).
So first simplify and lookup this expression to see if it
is already available. */
- mprts_hook = vn_lookup_simplify_result;
code_helper rcode = VIEW_CONVERT_EXPR;
tree ops[3] = { result };
- bool res = gimple_resimplify1 (NULL, &rcode, TREE_TYPE (op), ops,
- vn_valueize);
- mprts_hook = NULL;
- gimple *new_stmt = NULL;
- if (res
- && gimple_simplified_result_is_gimple_val (rcode, ops))
- /* The expression is already available. */
- result = ops[0];
- else
- {
- tree val = vn_lookup_simplify_result (rcode, TREE_TYPE (op), ops);
- if (!val)
- {
- gimple_seq stmts = NULL;
- result = maybe_push_res_to_seq (rcode, TREE_TYPE (op), ops,
- &stmts);
- if (result)
- {
- gcc_assert (gimple_seq_singleton_p (stmts));
- new_stmt = gimple_seq_first_stmt (stmts);
- }
- }
- else
- /* The expression is already available. */
- result = val;
- }
- if (new_stmt)
- {
- /* The expression is not yet available, value-number lhs to
- the new SSA_NAME we created. */
- /* Initialize value-number information properly. */
- VN_INFO_GET (result)->valnum = result;
- VN_INFO (result)->value_id = get_next_value_id ();
- gimple_seq_add_stmt_without_update (&VN_INFO (result)->expr,
- new_stmt);
- VN_INFO (result)->needs_insertion = true;
- /* As all "inserted" statements are singleton SCCs, insert
- to the valid table. This is strictly needed to
- avoid re-generating new value SSA_NAMEs for the same
- expression during SCC iteration over and over (the
- optimistic table gets cleared after each iteration).
- We do not need to insert into the optimistic table, as
- lookups there will fall back to the valid table. */
- if (current_info == optimistic_info)
- {
- current_info = valid_info;
- vn_nary_op_insert_stmt (new_stmt, result);
- current_info = optimistic_info;
- }
- else
- vn_nary_op_insert_stmt (new_stmt, result);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "Inserting name ");
- print_generic_expr (dump_file, result, 0);
- fprintf (dump_file, " for expression ");
- print_gimple_expr (dump_file, new_stmt, 0, TDF_SLIM);
- fprintf (dump_file, "\n");
- }
- }
+ result = vn_nary_build_or_lookup (rcode, TREE_TYPE (op), ops);
}
if (result)
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index d66bdfa94ce..5e3c7d094b5 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -4492,7 +4492,7 @@ find_func_aliases_for_builtin_call (struct function *fn, gcall *t)
tree valist = gimple_call_arg (t, 0);
struct constraint_expr rhs, *lhsp;
unsigned i;
- get_constraint_for (valist, &lhsc);
+ get_constraint_for_ptr_offset (valist, NULL_TREE, &lhsc);
do_deref (&lhsc);
/* The va_list gets access to pointers in variadic
arguments. Which we know in the case of IPA analysis
@@ -6254,6 +6254,9 @@ set_uids_in_ptset (bitmap into, bitmap from, struct pt_solution *pt,
pt->vars_contains_escaped_heap = vi->is_heap_var;
}
+ if (vi->is_restrict_var)
+ pt->vars_contains_restrict = true;
+
if (TREE_CODE (vi->decl) == VAR_DECL
|| TREE_CODE (vi->decl) == PARM_DECL
|| TREE_CODE (vi->decl) == RESULT_DECL)
@@ -7505,7 +7508,7 @@ make_pass_build_ealias (gcc::context *ctxt)
/* IPA PTA solutions for ESCAPED. */
struct pt_solution ipa_escaped_pt
- = { true, false, false, false, false, false, false, false, NULL };
+ = { true, false, false, false, false, false, false, false, false, NULL };
/* Associate node with varinfo DATA. Worker for
cgraph_for_symbol_thunks_and_aliases. */
diff --git a/gcc/tree-ssa-tail-merge.c b/gcc/tree-ssa-tail-merge.c
index e95879fb8aa..3df41fd08fc 100644
--- a/gcc/tree-ssa-tail-merge.c
+++ b/gcc/tree-ssa-tail-merge.c
@@ -538,6 +538,9 @@ same_succ::equal (const same_succ *e1, const same_succ *e2)
gimple *s1, *s2;
basic_block bb1, bb2;
+ if (e1 == e2)
+ return 1;
+
if (e1->hashval != e2->hashval)
return 0;
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index ea3ceb8f101..941d575f848 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -35,16 +35,15 @@ along with GCC; see the file COPYING3. If not see
#include "tree-cfg.h"
/* This implements the pass that does predicate aware warning on uses of
- possibly uninitialized variables. The pass first collects the set of
- possibly uninitialized SSA names. For each such name, it walks through
- all its immediate uses. For each immediate use, it rebuilds the condition
- expression (the predicate) that guards the use. The predicate is then
+ possibly uninitialized variables. The pass first collects the set of
+ possibly uninitialized SSA names. For each such name, it walks through
+ all its immediate uses. For each immediate use, it rebuilds the condition
+ expression (the predicate) that guards the use. The predicate is then
examined to see if the variable is always defined under that same condition.
This is done either by pruning the unrealizable paths that lead to the
default definitions or by checking if the predicate set that guards the
defining paths is a superset of the use predicate. */
-
/* Pointer set of potentially undefined ssa names, i.e.,
ssa names that are defined by phi with operands that
are not defined or potentially undefined. */
@@ -56,7 +55,7 @@ static hash_set<tree> *possibly_undefined_names = 0;
#define MASK_EMPTY(mask) (mask == 0)
/* Returns the first bit position (starting from LSB)
- in mask that is non zero. Returns -1 if the mask is empty. */
+ in mask that is non zero. Returns -1 if the mask is empty. */
static int
get_mask_first_set_bit (unsigned mask)
{
@@ -80,13 +79,12 @@ has_undefined_value_p (tree t)
&& possibly_undefined_names->contains (t)));
}
-
-
/* Like has_undefined_value_p, but don't return true if TREE_NO_WARNING
is set on SSA_NAME_VAR. */
static inline bool
-uninit_undefined_value_p (tree t) {
+uninit_undefined_value_p (tree t)
+{
if (!has_undefined_value_p (t))
return false;
if (SSA_NAME_VAR (t) && TREE_NO_WARNING (SSA_NAME_VAR (t)))
@@ -112,7 +110,7 @@ uninit_undefined_value_p (tree t) {
/* Emit a warning for EXPR based on variable VAR at the point in the
program T, an SSA_NAME, is used being uninitialized. The exact
warning text is in MSGID and DATA is the gimple stmt with info about
- the location in source code. When DATA is a GIMPLE_PHI, PHIARG_IDX
+ the location in source code. When DATA is a GIMPLE_PHI, PHIARG_IDX
gives which argument of the phi node to take the location from. WC
is the warning code. */
@@ -149,8 +147,7 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree var,
else
location = DECL_SOURCE_LOCATION (var);
location = linemap_resolve_location (line_table, location,
- LRK_SPELLING_LOCATION,
- NULL);
+ LRK_SPELLING_LOCATION, NULL);
cfun_loc = DECL_SOURCE_LOCATION (cfun->decl);
xloc = expand_location (location);
floc = expand_location (cfun_loc);
@@ -161,10 +158,8 @@ warn_uninit (enum opt_code wc, tree t, tree expr, tree var,
if (location == DECL_SOURCE_LOCATION (var))
return;
if (xloc.file != floc.file
- || linemap_location_before_p (line_table,
- location, cfun_loc)
- || linemap_location_before_p (line_table,
- cfun->function_end_locus,
+ || linemap_location_before_p (line_table, location, cfun_loc)
+ || linemap_location_before_p (line_table, cfun->function_end_locus,
location))
inform (DECL_SOURCE_LOCATION (var), "%qD was declared here", var);
}
@@ -178,8 +173,8 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
FOR_EACH_BB_FN (bb, cfun)
{
- bool always_executed = dominated_by_p (CDI_POST_DOMINATORS,
- single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)), bb);
+ basic_block succ = single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ bool always_executed = dominated_by_p (CDI_POST_DOMINATORS, succ, bb);
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple *stmt = gsi_stmt (gsi);
@@ -196,13 +191,13 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
{
use = USE_FROM_PTR (use_p);
if (always_executed)
- warn_uninit (OPT_Wuninitialized, use,
- SSA_NAME_VAR (use), SSA_NAME_VAR (use),
- "%qD is used uninitialized in this function",
- stmt, UNKNOWN_LOCATION);
+ warn_uninit (OPT_Wuninitialized, use, SSA_NAME_VAR (use),
+ SSA_NAME_VAR (use),
+ "%qD is used uninitialized in this function", stmt,
+ UNKNOWN_LOCATION);
else if (warn_possibly_uninitialized)
- warn_uninit (OPT_Wmaybe_uninitialized, use,
- SSA_NAME_VAR (use), SSA_NAME_VAR (use),
+ warn_uninit (OPT_Wmaybe_uninitialized, use, SSA_NAME_VAR (use),
+ SSA_NAME_VAR (use),
"%qD may be used uninitialized in this function",
stmt, UNKNOWN_LOCATION);
}
@@ -232,9 +227,8 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
continue;
if (always_executed)
- warn_uninit (OPT_Wuninitialized, use,
- gimple_assign_rhs1 (stmt), base,
- "%qE is used uninitialized in this function",
+ warn_uninit (OPT_Wuninitialized, use, gimple_assign_rhs1 (stmt),
+ base, "%qE is used uninitialized in this function",
stmt, UNKNOWN_LOCATION);
else if (warn_possibly_uninitialized)
warn_uninit (OPT_Wmaybe_uninitialized, use,
@@ -250,9 +244,9 @@ warn_uninitialized_vars (bool warn_possibly_uninitialized)
/* Checks if the operand OPND of PHI is defined by
another phi with one operand defined by this PHI,
- but the rest operands are all defined. If yes,
+ but the rest operands are all defined. If yes,
returns true to skip this operand as being
- redundant. Can be enhanced to be more general. */
+ redundant. Can be enhanced to be more general. */
static bool
can_skip_redundant_opnd (tree opnd, gimple *phi)
@@ -318,37 +312,35 @@ compute_uninit_opnds_pos (gphi *phi)
static inline basic_block
find_pdom (basic_block block)
{
- if (block == EXIT_BLOCK_PTR_FOR_FN (cfun))
- return EXIT_BLOCK_PTR_FOR_FN (cfun);
- else
- {
- basic_block bb
- = get_immediate_dominator (CDI_POST_DOMINATORS, block);
- if (! bb)
- return EXIT_BLOCK_PTR_FOR_FN (cfun);
- return bb;
- }
+ if (block == EXIT_BLOCK_PTR_FOR_FN (cfun))
+ return EXIT_BLOCK_PTR_FOR_FN (cfun);
+ else
+ {
+ basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block);
+ if (!bb)
+ return EXIT_BLOCK_PTR_FOR_FN (cfun);
+ return bb;
+ }
}
-/* Find the immediate DOM of the specified
- basic block BLOCK. */
+/* Find the immediate DOM of the specified basic block BLOCK. */
static inline basic_block
find_dom (basic_block block)
{
- if (block == ENTRY_BLOCK_PTR_FOR_FN (cfun))
- return ENTRY_BLOCK_PTR_FOR_FN (cfun);
- else
- {
- basic_block bb = get_immediate_dominator (CDI_DOMINATORS, block);
- if (! bb)
- return ENTRY_BLOCK_PTR_FOR_FN (cfun);
- return bb;
- }
+ if (block == ENTRY_BLOCK_PTR_FOR_FN (cfun))
+ return ENTRY_BLOCK_PTR_FOR_FN (cfun);
+ else
+ {
+ basic_block bb = get_immediate_dominator (CDI_DOMINATORS, block);
+ if (!bb)
+ return ENTRY_BLOCK_PTR_FOR_FN (cfun);
+ return bb;
+ }
}
/* Returns true if BB1 is postdominating BB2 and BB1 is
- not a loop exit bb. The loop exit bb check is simple and does
+ not a loop exit bb. The loop exit bb check is simple and does
not cover all cases. */
static bool
@@ -366,7 +358,7 @@ is_non_loop_exit_postdominating (basic_block bb1, basic_block bb2)
/* Find the closest postdominator of a specified BB, which is control
equivalent to BB. */
-static inline basic_block
+static inline basic_block
find_control_equiv_block (basic_block bb)
{
basic_block pdom;
@@ -424,7 +416,7 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
for (i = 0; i < cur_chain_len; i++)
{
edge e = (*cur_cd_chain)[i];
- /* Cycle detected. */
+ /* Cycle detected. */
if (e->src == bb)
return false;
}
@@ -454,8 +446,8 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
}
/* Now check if DEP_BB is indirectly control dependent on BB. */
- if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains,
- num_chains, cur_cd_chain, num_calls))
+ if (compute_control_dep_chain (cd_bb, dep_bb, cd_chains, num_chains,
+ cur_cd_chain, num_calls))
{
found_cd_chain = true;
break;
@@ -463,8 +455,8 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
cd_bb = find_pdom (cd_bb);
post_dom_check++;
- if (cd_bb == EXIT_BLOCK_PTR_FOR_FN (cfun) || post_dom_check >
- MAX_POSTDOM_CHECK)
+ if (cd_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
+ || post_dom_check > MAX_POSTDOM_CHECK)
break;
}
cur_cd_chain->pop ();
@@ -475,7 +467,7 @@ compute_control_dep_chain (basic_block bb, basic_block dep_bb,
return found_cd_chain;
}
-/* The type to represent a simple predicate */
+/* The type to represent a simple predicate. */
struct pred_info
{
@@ -496,13 +488,13 @@ typedef vec<pred_info, va_heap, vl_ptr> pred_chain;
typedef vec<pred_chain, va_heap, vl_ptr> pred_chain_union;
/* Converts the chains of control dependence edges into a set of
- predicates. A control dependence chain is represented by a vector
- edges. DEP_CHAINS points to an array of dependence chains.
- NUM_CHAINS is the size of the chain array. One edge in a dependence
+ predicates. A control dependence chain is represented by a vector
+ edges. DEP_CHAINS points to an array of dependence chains.
+ NUM_CHAINS is the size of the chain array. One edge in a dependence
chain is mapped to predicate expression represented by pred_info
- type. One dependence chain is converted to a composite predicate that
+ type. One dependence chain is converted to a composite predicate that
is the result of AND operation of pred_info mapped to each edge.
- A composite predicate is presented by a vector of pred_info. On
+ A composite predicate is presented by a vector of pred_info. On
return, *PREDS points to the resulting array of composite predicates.
*NUM_PREDS is the number of composite predictes. */
@@ -543,13 +535,9 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
break;
}
cond_stmt = gsi_stmt (gsi);
- if (is_gimple_call (cond_stmt)
- && EDGE_COUNT (e->src->succs) >= 2)
- {
- /* Ignore EH edge. Can add assertion
- on the other edge's flag. */
- continue;
- }
+ if (is_gimple_call (cond_stmt) && EDGE_COUNT (e->src->succs) >= 2)
+ /* Ignore EH edge. Can add assertion on the other edge's flag. */
+ continue;
/* Skip if there is essentially one succesor. */
if (EDGE_COUNT (e->src->succs) == 2)
{
@@ -577,7 +565,7 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
t_chain.safe_push (one_pred);
has_valid_pred = true;
}
- else if (gswitch *gs = dyn_cast <gswitch *> (cond_stmt))
+ else if (gswitch *gs = dyn_cast<gswitch *> (cond_stmt))
{
/* Avoid quadratic behavior. */
if (gimple_switch_num_labels (gs) > MAX_SWITCH_CASES)
@@ -607,8 +595,8 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
fail. */
if (!l
|| !CASE_LOW (l)
- || (CASE_HIGH (l) && !operand_equal_p (CASE_LOW (l),
- CASE_HIGH (l), 0)))
+ || (CASE_HIGH (l)
+ && !operand_equal_p (CASE_LOW (l), CASE_HIGH (l), 0)))
{
has_valid_pred = false;
break;
@@ -635,7 +623,7 @@ convert_control_dep_chain_into_preds (vec<edge> *dep_chains,
return has_valid_pred;
}
-/* Computes all control dependence chains for USE_BB. The control
+/* Computes all control dependence chains for USE_BB. The control
dependence chains are then converted to an array of composite
predicates pointed to by PREDS. PHI_BB is the basic block of
the phi whose result is used in USE_BB. */
@@ -676,8 +664,8 @@ find_predicates (pred_chain_union *preds,
/* Computes the set of incoming edges of PHI that have non empty
definitions of a phi chain. The collection will be done
- recursively on operands that are defined by phis. CD_ROOT
- is the control dependence root. *EDGES holds the result, and
+ recursively on operands that are defined by phis. CD_ROOT
+ is the control dependence root. *EDGES holds the result, and
VISITED_PHIS is a pointer set for detecting cycles. */
static void
@@ -702,7 +690,7 @@ collect_phi_def_edges (gphi *phi, basic_block cd_root,
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int)i);
+ fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int) i);
print_gimple_stmt (dump_file, phi, 0, 0);
}
edges->safe_push (opnd_edge);
@@ -712,15 +700,15 @@ collect_phi_def_edges (gphi *phi, basic_block cd_root,
gimple *def = SSA_NAME_DEF_STMT (opnd);
if (gimple_code (def) == GIMPLE_PHI
- && dominated_by_p (CDI_DOMINATORS,
- gimple_bb (def), cd_root))
- collect_phi_def_edges (as_a <gphi *> (def), cd_root, edges,
+ && dominated_by_p (CDI_DOMINATORS, gimple_bb (def), cd_root))
+ collect_phi_def_edges (as_a<gphi *> (def), cd_root, edges,
visited_phis);
else if (!uninit_undefined_value_p (opnd))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
- fprintf (dump_file, "\n[CHECK] Found def edge %d in ", (int)i);
+ fprintf (dump_file, "\n[CHECK] Found def edge %d in ",
+ (int) i);
print_gimple_stmt (dump_file, phi, 0, 0);
}
edges->safe_push (opnd_edge);
@@ -745,7 +733,7 @@ find_def_preds (pred_chain_union *preds, gphi *phi)
phi_bb = gimple_bb (phi);
/* First find the closest dominating bb to be
- the control dependence root */
+ the control dependence root. */
cd_root = find_dom (phi_bb);
if (!cd_root)
return false;
@@ -789,8 +777,7 @@ find_def_preds (pred_chain_union *preds, gphi *phi)
/* Dumps the predicates (PREDS) for USESTMT. */
static void
-dump_predicates (gimple *usestmt, pred_chain_union preds,
- const char* msg)
+dump_predicates (gimple *usestmt, pred_chain_union preds, const char *msg)
{
size_t i, j;
pred_chain one_pred_chain = vNULL;
@@ -839,13 +826,11 @@ destroy_predicate_vecs (pred_chain_union *preds)
preds->release ();
}
-
/* Computes the 'normalized' conditional code with operand
swapping and condition inversion. */
static enum tree_code
-get_cmp_code (enum tree_code orig_cmp_code,
- bool swap_cond, bool invert)
+get_cmp_code (enum tree_code orig_cmp_code, bool swap_cond, bool invert)
{
enum tree_code tc = orig_cmp_code;
@@ -880,14 +865,12 @@ is_value_included_in (tree val, tree boundary, enum tree_code cmpc)
bool result;
/* Only handle integer constant here. */
- if (TREE_CODE (val) != INTEGER_CST
- || TREE_CODE (boundary) != INTEGER_CST)
+ if (TREE_CODE (val) != INTEGER_CST || TREE_CODE (boundary) != INTEGER_CST)
return true;
is_unsigned = TYPE_UNSIGNED (TREE_TYPE (val));
- if (cmpc == GE_EXPR || cmpc == GT_EXPR
- || cmpc == NE_EXPR)
+ if (cmpc == GE_EXPR || cmpc == GT_EXPR || cmpc == NE_EXPR)
{
cmpc = invert_tree_comparison (cmpc, false);
inverted = true;
@@ -949,7 +932,7 @@ find_matching_predicate_in_rest_chains (pred_info pred,
{
pred_info pred2 = one_chain[j];
/* Can relax the condition comparison to not
- use address comparison. However, the most common
+ use address comparison. However, the most common
case is that multiple control dependent paths share
a common path prefix, so address comparison should
be ok. */
@@ -969,16 +952,15 @@ find_matching_predicate_in_rest_chains (pred_info pred,
}
/* Forward declaration. */
-static bool
-is_use_properly_guarded (gimple *use_stmt,
- basic_block use_bb,
- gphi *phi,
- unsigned uninit_opnds,
- pred_chain_union *def_preds,
- hash_set<gphi *> *visited_phis);
-
-/* Returns true if all uninitialized opnds are pruned. Returns false
- otherwise. PHI is the phi node with uninitialized operands,
+static bool is_use_properly_guarded (gimple *use_stmt,
+ basic_block use_bb,
+ gphi *phi,
+ unsigned uninit_opnds,
+ pred_chain_union *def_preds,
+ hash_set<gphi *> *visited_phis);
+
+/* Returns true if all uninitialized opnds are pruned. Returns false
+ otherwise. PHI is the phi node with uninitialized operands,
UNINIT_OPNDS is the bitmap of the uninitialize operand positions,
FLAG_DEF is the statement defining the flag guarding the use of the
PHI output, BOUNDARY_CST is the const value used in the predicate
@@ -990,7 +972,7 @@ is_use_properly_guarded (gimple *use_stmt,
Example scenario:
BB1:
- flag_1 = phi <0, 1> // (1)
+ flag_1 = phi <0, 1> // (1)
var_1 = phi <undef, some_val>
@@ -1001,24 +983,20 @@ is_use_properly_guarded (gimple *use_stmt,
goto BB3;
BB3:
- use of var_2 // (3)
+ use of var_2 // (3)
Because some flag arg in (1) is not constant, if we do not look into the
flag phis recursively, it is conservatively treated as unknown and var_1
- is thought to be flowed into use at (3). Since var_1 is potentially uninitialized
- a false warning will be emitted. Checking recursively into (1), the compiler can
- find out that only some_val (which is defined) can flow into (3) which is OK.
-
-*/
+ is thought to be flowed into use at (3). Since var_1 is potentially
+ uninitialized a false warning will be emitted.
+ Checking recursively into (1), the compiler can find out that only some_val
+ (which is defined) can flow into (3) which is OK. */
static bool
-prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
- unsigned uninit_opnds,
- gphi *flag_def,
- tree boundary_cst,
- enum tree_code cmp_code,
- hash_set<gphi *> *visited_phis,
- bitmap *visited_flag_phis)
+prune_uninit_phi_opnds (gphi *phi, unsigned uninit_opnds, gphi *flag_def,
+ tree boundary_cst, enum tree_code cmp_code,
+ hash_set<gphi *> *visited_phis,
+ bitmap *visited_flag_phis)
{
unsigned i;
@@ -1038,7 +1016,7 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
if (TREE_CODE (flag_arg) != SSA_NAME)
return false;
- flag_arg_def = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (flag_arg));
+ flag_arg_def = dyn_cast<gphi *> (SSA_NAME_DEF_STMT (flag_arg));
if (!flag_arg_def)
return false;
@@ -1046,7 +1024,7 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
if (TREE_CODE (phi_arg) != SSA_NAME)
return false;
- phi_arg_def = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (phi_arg));
+ phi_arg_def = dyn_cast<gphi *> (SSA_NAME_DEF_STMT (phi_arg));
if (!phi_arg_def)
return false;
@@ -1056,8 +1034,8 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
if (!*visited_flag_phis)
*visited_flag_phis = BITMAP_ALLOC (NULL);
- if (bitmap_bit_p (*visited_flag_phis,
- SSA_NAME_VERSION (gimple_phi_result (flag_arg_def))))
+ tree phi_result = gimple_phi_result (flag_arg_def);
+ if (bitmap_bit_p (*visited_flag_phis, SSA_NAME_VERSION (phi_result)))
return false;
bitmap_set_bit (*visited_flag_phis,
@@ -1065,13 +1043,13 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
/* Now recursively prune the uninitialized phi args. */
uninit_opnds_arg_phi = compute_uninit_opnds_pos (phi_arg_def);
- if (!prune_uninit_phi_opnds_in_unrealizable_paths
- (phi_arg_def, uninit_opnds_arg_phi, flag_arg_def,
- boundary_cst, cmp_code, visited_phis, visited_flag_phis))
+ if (!prune_uninit_phi_opnds
+ (phi_arg_def, uninit_opnds_arg_phi, flag_arg_def, boundary_cst,
+ cmp_code, visited_phis, visited_flag_phis))
return false;
- bitmap_clear_bit (*visited_flag_phis,
- SSA_NAME_VERSION (gimple_phi_result (flag_arg_def)));
+ phi_result = gimple_phi_result (flag_arg_def);
+ bitmap_clear_bit (*visited_flag_phis, SSA_NAME_VERSION (phi_result));
continue;
}
@@ -1082,7 +1060,7 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
gimple *opnd_def;
/* Now that we know that this undefined edge is not
- pruned. If the operand is defined by another phi,
+ pruned. If the operand is defined by another phi,
we can further prune the incoming edges of that
phi by checking the predicates of this operands. */
@@ -1091,8 +1069,7 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
if (gphi *opnd_def_phi = dyn_cast <gphi *> (opnd_def))
{
edge opnd_edge;
- unsigned uninit_opnds2
- = compute_uninit_opnds_pos (opnd_def_phi);
+ unsigned uninit_opnds2 = compute_uninit_opnds_pos (opnd_def_phi);
if (!MASK_EMPTY (uninit_opnds2))
{
pred_chain_union def_preds = vNULL;
@@ -1143,11 +1120,11 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
return true;
}
- void foo(..)
+ void foo (..)
{
int x;
- if (!init_func(&x))
+ if (!init_func (&x))
return;
.. some_code ...
@@ -1179,7 +1156,7 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
<==> false
This implementation provides framework that can handle
- scenarios. (Note that many simple cases are handled properly
+ scenarios. (Note that many simple cases are handled properly
without the predicate analysis -- this is due to jump threading
transformation which eliminates the merge point thus makes
path sensitive analysis unnecessary.)
@@ -1187,10 +1164,9 @@ prune_uninit_phi_opnds_in_unrealizable_paths (gphi *phi,
NUM_PREDS is the number is the number predicate chains, PREDS is
the array of chains, PHI is the phi node whose incoming (undefined)
paths need to be pruned, and UNINIT_OPNDS is the bitmap holding
- uninit operand positions. VISITED_PHIS is the pointer set of phi
+ uninit operand positions. VISITED_PHIS is the pointer set of phi
stmts being checked. */
-
static bool
use_pred_not_overlap_with_undef_path_pred (pred_chain_union preds,
gphi *phi, unsigned uninit_opnds,
@@ -1198,7 +1174,7 @@ use_pred_not_overlap_with_undef_path_pred (pred_chain_union preds,
{
unsigned int i, n;
gimple *flag_def = 0;
- tree boundary_cst = 0;
+ tree boundary_cst = 0;
enum tree_code cmp_code;
bool swap_cond = false;
bool invert = false;
@@ -1265,13 +1241,9 @@ use_pred_not_overlap_with_undef_path_pred (pred_chain_union preds,
if (cmp_code == ERROR_MARK)
return false;
- all_pruned = prune_uninit_phi_opnds_in_unrealizable_paths (phi,
- uninit_opnds,
- as_a <gphi *> (flag_def),
- boundary_cst,
- cmp_code,
- visited_phis,
- &visited_flag_phis);
+ all_pruned = prune_uninit_phi_opnds
+ (phi, uninit_opnds, as_a<gphi *> (flag_def), boundary_cst, cmp_code,
+ visited_phis, &visited_flag_phis);
if (visited_flag_phis)
BITMAP_FREE (visited_flag_phis);
@@ -1280,7 +1252,7 @@ use_pred_not_overlap_with_undef_path_pred (pred_chain_union preds,
}
/* The helper function returns true if two predicates X1 and X2
- are equivalent. It assumes the expressions have already
+ are equivalent. It assumes the expressions have already
properly re-associated. */
static inline bool
@@ -1307,8 +1279,8 @@ static inline bool
is_neq_relop_p (pred_info pred)
{
- return (pred.cond_code == NE_EXPR && !pred.invert)
- || (pred.cond_code == EQ_EXPR && pred.invert);
+ return ((pred.cond_code == NE_EXPR && !pred.invert)
+ || (pred.cond_code == EQ_EXPR && pred.invert));
}
/* Returns true if pred is of the form X != 0. */
@@ -1335,7 +1307,7 @@ pred_expr_equal_p (pred_info x1, tree x2)
}
/* Returns true of the domain of single predicate expression
- EXPR1 is a subset of that of EXPR2. Returns false if it
+ EXPR1 is a subset of that of EXPR2. Returns false if it
can not be proved. */
static bool
@@ -1360,8 +1332,7 @@ is_pred_expr_subset_of (pred_info expr1, pred_info expr2)
if (expr2.invert)
code2 = invert_tree_comparison (code2, false);
- if ((code1 == EQ_EXPR || code1 == BIT_AND_EXPR)
- && code2 == BIT_AND_EXPR)
+ if ((code1 == EQ_EXPR || code1 == BIT_AND_EXPR) && code2 == BIT_AND_EXPR)
return wi::eq_p (expr1.pred_rhs,
wi::bit_and (expr1.pred_rhs, expr2.pred_rhs));
@@ -1375,11 +1346,10 @@ is_pred_expr_subset_of (pred_info expr1, pred_info expr2)
}
/* Returns true if the domain of PRED1 is a subset
- of that of PRED2. Returns false if it can not be proved so. */
+ of that of PRED2. Returns false if it can not be proved so. */
static bool
-is_pred_chain_subset_of (pred_chain pred1,
- pred_chain pred2)
+is_pred_chain_subset_of (pred_chain pred1, pred_chain pred2)
{
size_t np1, np2, i1, i2;
@@ -1407,7 +1377,7 @@ is_pred_chain_subset_of (pred_chain pred1,
/* Returns true if the domain defined by
one pred chain ONE_PRED is a subset of the domain
- of *PREDS. It returns false if ONE_PRED's domain is
+ of *PREDS. It returns false if ONE_PRED's domain is
not a subset of any of the sub-domains of PREDS
(corresponding to each individual chains in it), even
though it may be still be a subset of whole domain
@@ -1431,15 +1401,15 @@ is_included_in (pred_chain one_pred, pred_chain_union preds)
/* Compares two predicate sets PREDS1 and PREDS2 and returns
true if the domain defined by PREDS1 is a superset
- of PREDS2's domain. N1 and N2 are array sizes of PREDS1 and
- PREDS2 respectively. The implementation chooses not to build
+ of PREDS2's domain. N1 and N2 are array sizes of PREDS1 and
+ PREDS2 respectively. The implementation chooses not to build
generic trees (and relying on the folding capability of the
compiler), but instead performs brute force comparison of
individual predicate chains (won't be a compile time problem
- as the chains are pretty short). When the function returns
+ as the chains are pretty short). When the function returns
false, it does not necessarily mean *PREDS1 is not a superset
of *PREDS2, but mean it may not be so since the analysis can
- not prove it. In such cases, false warnings may still be
+ not prove it. In such cases, false warnings may still be
emitted. */
static bool
@@ -1536,19 +1506,19 @@ simplify_pred (pred_chain *one_chain)
if (pred_expr_equal_p (*b_pred, gimple_assign_rhs1 (def_stmt))
|| pred_expr_equal_p (*b_pred, gimple_assign_rhs2 (def_stmt)))
- {
- /* Mark a_pred for removal. */
- a_pred->pred_lhs = NULL;
- a_pred->pred_rhs = NULL;
- simplified = true;
- break;
- }
+ {
+ /* Mark a_pred for removal. */
+ a_pred->pred_lhs = NULL;
+ a_pred->pred_rhs = NULL;
+ simplified = true;
+ break;
+ }
}
}
}
if (!simplified)
- return;
+ return;
for (i = 0; i < n; i++)
{
@@ -1558,8 +1528,8 @@ simplify_pred (pred_chain *one_chain)
s_chain.safe_push (*a_pred);
}
- one_chain->release ();
- *one_chain = s_chain;
+ one_chain->release ();
+ *one_chain = s_chain;
}
/* The helper function implements the rule 2 for the
@@ -1746,8 +1716,7 @@ simplify_preds_4 (pred_chain_union *preds)
x2 = (*b_chain)[0];
y2 = (*b_chain)[1];
- if (!is_neq_zero_form_p (x2)
- || !is_neq_zero_form_p (y2))
+ if (!is_neq_zero_form_p (x2) || !is_neq_zero_form_p (y2))
continue;
if ((pred_expr_equal_p (x2, gimple_assign_rhs1 (def_stmt))
@@ -1780,7 +1749,6 @@ simplify_preds_4 (pred_chain_union *preds)
return simplified;
}
-
/* This function simplifies predicates in PREDS. */
static void
@@ -1815,14 +1783,14 @@ simplify_preds (pred_chain_union *preds, gimple *use_or_def, bool is_use)
if (simplify_preds_4 (preds))
changed = true;
-
- } while (changed);
+ }
+ while (changed);
return;
}
/* This is a helper function which attempts to normalize predicate chains
- by following UD chains. It basically builds up a big tree of either IOR
+ by following UD chains. It basically builds up a big tree of either IOR
operations or AND operations, and convert the IOR tree into a
pred_chain_union or BIT_AND tree into a pred_chain.
Example:
@@ -1895,7 +1863,7 @@ get_pred_info_from_cmp (gimple *cmp_assign)
}
/* Returns true if the PHI is a degenerated phi with
- all args with the same value (relop). In that case, *PRED
+ all args with the same value (relop). In that case, *PRED
will be updated to that value. */
static bool
@@ -1915,8 +1883,7 @@ is_degenerated_phi (gimple *phi, pred_info *pred_p)
def0 = SSA_NAME_DEF_STMT (op0);
if (gimple_code (def0) != GIMPLE_ASSIGN)
return false;
- if (TREE_CODE_CLASS (gimple_assign_rhs_code (def0))
- != tcc_comparison)
+ if (TREE_CODE_CLASS (gimple_assign_rhs_code (def0)) != tcc_comparison)
return false;
pred0 = get_pred_info_from_cmp (def0);
@@ -1932,8 +1899,7 @@ is_degenerated_phi (gimple *phi, pred_info *pred_p)
def = SSA_NAME_DEF_STMT (op);
if (gimple_code (def) != GIMPLE_ASSIGN)
return false;
- if (TREE_CODE_CLASS (gimple_assign_rhs_code (def))
- != tcc_comparison)
+ if (TREE_CODE_CLASS (gimple_assign_rhs_code (def)) != tcc_comparison)
return false;
pred = get_pred_info_from_cmp (def);
if (!pred_equal_p (pred, pred0))
@@ -1971,13 +1937,12 @@ normalize_one_pred_1 (pred_chain_union *norm_preds,
if (gimple_code (def_stmt) == GIMPLE_PHI
&& is_degenerated_phi (def_stmt, &pred))
work_list->safe_push (pred);
- else if (gimple_code (def_stmt) == GIMPLE_PHI
- && and_or_code == BIT_IOR_EXPR)
+ else if (gimple_code (def_stmt) == GIMPLE_PHI && and_or_code == BIT_IOR_EXPR)
{
int i, n;
n = gimple_phi_num_args (def_stmt);
- /* If we see non zero constant, we should punt. The predicate
+ /* If we see non zero constant, we should punt. The predicate
* should be one guarding the phi edge. */
for (i = 0; i < n; ++i)
{
@@ -2048,8 +2013,7 @@ normalize_one_pred_1 (pred_chain_union *norm_preds,
/* Normalize PRED and store the normalized predicates into NORM_PREDS. */
static void
-normalize_one_pred (pred_chain_union *norm_preds,
- pred_info pred)
+normalize_one_pred (pred_chain_union *norm_preds, pred_info pred)
{
vec<pred_info, va_heap, vl_ptr> work_list = vNULL;
enum tree_code and_or_code = ERROR_MARK;
@@ -2064,17 +2028,15 @@ normalize_one_pred (pred_chain_union *norm_preds,
gimple *def_stmt = SSA_NAME_DEF_STMT (pred.pred_lhs);
if (gimple_code (def_stmt) == GIMPLE_ASSIGN)
and_or_code = gimple_assign_rhs_code (def_stmt);
- if (and_or_code != BIT_IOR_EXPR
- && and_or_code != BIT_AND_EXPR)
+ if (and_or_code != BIT_IOR_EXPR && and_or_code != BIT_AND_EXPR)
{
- if (TREE_CODE_CLASS (and_or_code)
- == tcc_comparison)
+ if (TREE_CODE_CLASS (and_or_code) == tcc_comparison)
{
pred_info n_pred = get_pred_info_from_cmp (def_stmt);
push_pred (norm_preds, n_pred);
}
- else
- push_pred (norm_preds, pred);
+ else
+ push_pred (norm_preds, pred);
return;
}
@@ -2084,8 +2046,8 @@ normalize_one_pred (pred_chain_union *norm_preds,
while (!work_list.is_empty ())
{
pred_info a_pred = work_list.pop ();
- normalize_one_pred_1 (norm_preds, &norm_chain, a_pred,
- and_or_code, &work_list, &mark_set);
+ normalize_one_pred_1 (norm_preds, &norm_chain, a_pred, and_or_code,
+ &work_list, &mark_set);
}
if (and_or_code == BIT_AND_EXPR)
norm_preds->safe_push (norm_chain);
@@ -2094,8 +2056,7 @@ normalize_one_pred (pred_chain_union *norm_preds,
}
static void
-normalize_one_pred_chain (pred_chain_union *norm_preds,
- pred_chain one_chain)
+normalize_one_pred_chain (pred_chain_union *norm_preds, pred_chain one_chain)
{
vec<pred_info, va_heap, vl_ptr> work_list = vNULL;
hash_set<tree> mark_set;
@@ -2111,8 +2072,8 @@ normalize_one_pred_chain (pred_chain_union *norm_preds,
while (!work_list.is_empty ())
{
pred_info a_pred = work_list.pop ();
- normalize_one_pred_1 (0, &norm_chain, a_pred,
- BIT_AND_EXPR, &work_list, &mark_set);
+ normalize_one_pred_1 (0, &norm_chain, a_pred, BIT_AND_EXPR, &work_list,
+ &mark_set);
}
norm_preds->safe_push (norm_chain);
@@ -2148,26 +2109,26 @@ normalize_preds (pred_chain_union preds, gimple *use_or_def, bool is_use)
if (dump_file)
{
fprintf (dump_file, "[AFTER NORMALIZATION -- ");
- dump_predicates (use_or_def, norm_preds, is_use ? "[USE]:\n" : "[DEF]:\n");
+ dump_predicates (use_or_def, norm_preds,
+ is_use ? "[USE]:\n" : "[DEF]:\n");
}
destroy_predicate_vecs (&preds);
return norm_preds;
}
-
/* Computes the predicates that guard the use and checks
if the incoming paths that have empty (or possibly
- empty) definition can be pruned/filtered. The function returns
+ empty) definition can be pruned/filtered. The function returns
true if it can be determined that the use of PHI's def in
USE_STMT is guarded with a predicate set not overlapping with
predicate sets of all runtime paths that do not have a definition.
- Returns false if it is not or it can not be determined. USE_BB is
+ Returns false if it is not or it can not be determined. USE_BB is
the bb of the use (for phi operand use, the bb is not the bb of
the phi stmt, but the src bb of the operand edge).
- UNINIT_OPNDS is a bit vector. If an operand of PHI is uninitialized, the
+ UNINIT_OPNDS is a bit vector. If an operand of PHI is uninitialized, the
corresponding bit in the vector is 1. VISITED_PHIS is a pointer
set of phis being visited.
@@ -2206,7 +2167,7 @@ is_use_properly_guarded (gimple *use_stmt,
return false;
}
- /* Try to prune the dead incoming phi edges. */
+ /* Try to prune the dead incoming phi edges. */
is_properly_guarded
= use_pred_not_overlap_with_undef_path_pred (preds, phi, uninit_opnds,
visited_phis);
@@ -2242,11 +2203,11 @@ is_use_properly_guarded (gimple *use_stmt,
/* Searches through all uses of a potentially
uninitialized variable defined by PHI and returns a use
- statement if the use is not properly guarded. It returns
- NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
- holding the position(s) of uninit PHI operands. WORKLIST
+ statement if the use is not properly guarded. It returns
+ NULL if all uses are guarded. UNINIT_OPNDS is a bitvector
+ holding the position(s) of uninit PHI operands. WORKLIST
is the vector of candidate phis that may be updated by this
- function. ADDED_TO_WORKLIST is the pointer set tracking
+ function. ADDED_TO_WORKLIST is the pointer set tracking
if the new phi is already in the worklist. */
static gimple *
@@ -2271,7 +2232,7 @@ find_uninit_use (gphi *phi, unsigned uninit_opnds,
if (is_gimple_debug (use_stmt))
continue;
- if (gphi *use_phi = dyn_cast <gphi *> (use_stmt))
+ if (gphi *use_phi = dyn_cast<gphi *> (use_stmt))
use_bb = gimple_phi_arg_edge (use_phi,
PHI_ARG_INDEX_FROM_USE (use_p))->src;
else
@@ -2296,7 +2257,7 @@ find_uninit_use (gphi *phi, unsigned uninit_opnds,
/* Found a phi use that is not guarded,
add the phi to the worklist. */
- if (!added_to_worklist->add (as_a <gphi *> (use_stmt)))
+ if (!added_to_worklist->add (as_a<gphi *> (use_stmt)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
{
@@ -2304,7 +2265,7 @@ find_uninit_use (gphi *phi, unsigned uninit_opnds,
print_gimple_stmt (dump_file, use_stmt, 0, 0);
}
- worklist->safe_push (as_a <gphi *> (use_stmt));
+ worklist->safe_push (as_a<gphi *> (use_stmt));
possibly_undefined_names->add (phi_result);
}
}
@@ -2315,10 +2276,10 @@ find_uninit_use (gphi *phi, unsigned uninit_opnds,
/* Look for inputs to PHI that are SSA_NAMEs that have empty definitions
and gives warning if there exists a runtime path from the entry to a
- use of the PHI def that does not contain a definition. In other words,
- the warning is on the real use. The more dead paths that can be pruned
- by the compiler, the fewer false positives the warning is. WORKLIST
- is a vector of candidate phis to be examined. ADDED_TO_WORKLIST is
+ use of the PHI def that does not contain a definition. In other words,
+ the warning is on the real use. The more dead paths that can be pruned
+ by the compiler, the fewer false positives the warning is. WORKLIST
+ is a vector of candidate phis to be examined. ADDED_TO_WORKLIST is
a pointer set tracking if the new phi is added to the worklist or not. */
static void
@@ -2337,7 +2298,7 @@ warn_uninitialized_phi (gphi *phi, vec<gphi *> *worklist,
uninit_opnds = compute_uninit_opnds_pos (phi);
- if (MASK_EMPTY (uninit_opnds))
+ if (MASK_EMPTY (uninit_opnds))
return;
if (dump_file && (dump_flags & TDF_DETAILS))
@@ -2366,7 +2327,6 @@ warn_uninitialized_phi (gphi *phi, vec<gphi *> *worklist,
SSA_NAME_VAR (uninit_op),
"%qD may be used uninitialized in this function",
uninit_use_stmt, loc);
-
}
static bool
@@ -2398,7 +2358,7 @@ public:
{}
/* opt_pass methods: */
- opt_pass * clone () { return new pass_late_warn_uninitialized (m_ctxt); }
+ opt_pass *clone () { return new pass_late_warn_uninitialized (m_ctxt); }
virtual bool gate (function *) { return gate_warn_uninitialized (); }
virtual unsigned int execute (function *);
@@ -2439,8 +2399,7 @@ pass_late_warn_uninitialized::execute (function *fun)
for (i = 0; i < n; ++i)
{
tree op = gimple_phi_arg_def (phi, i);
- if (TREE_CODE (op) == SSA_NAME
- && uninit_undefined_value_p (op))
+ if (TREE_CODE (op) == SSA_NAME && uninit_undefined_value_p (op))
{
worklist.safe_push (phi);
added_to_worklist.add (phi);
@@ -2477,12 +2436,11 @@ make_pass_late_warn_uninitialized (gcc::context *ctxt)
return new pass_late_warn_uninitialized (ctxt);
}
-
static unsigned int
execute_early_warn_uninitialized (void)
{
/* Currently, this pass runs always but
- execute_late_warn_uninitialized only runs with optimization. With
+ execute_late_warn_uninitialized only runs with optimization. With
optimization we want to warn about possible uninitialized as late
as possible, thus don't do it here. However, without
optimization we need to warn here about "may be uninitialized". */
@@ -2490,14 +2448,13 @@ execute_early_warn_uninitialized (void)
warn_uninitialized_vars (/*warn_possibly_uninitialized=*/!optimize);
- /* Post-dominator information can not be reliably updated. Free it
+ /* Post-dominator information can not be reliably updated. Free it
after the use. */
free_dominance_info (CDI_POST_DOMINATORS);
return 0;
}
-
namespace {
const pass_data pass_data_early_warn_uninitialized =
@@ -2523,9 +2480,9 @@ public:
/* opt_pass methods: */
virtual bool gate (function *) { return gate_warn_uninitialized (); }
virtual unsigned int execute (function *)
- {
- return execute_early_warn_uninitialized ();
- }
+ {
+ return execute_early_warn_uninitialized ();
+ }
}; // class pass_early_warn_uninitialized
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 6a16d268e69..cf6e76405b3 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1051,62 +1051,6 @@ init_tree_ssa (struct function *fn)
init_ssanames (fn, 0);
}
-/* Do the actions required to initialize internal data structures used
- in tree-ssa optimization passes. */
-
-static unsigned int
-execute_init_datastructures (void)
-{
- /* Allocate hash tables, arrays and other structures. */
- gcc_assert (!cfun->gimple_df);
- init_tree_ssa (cfun);
- return 0;
-}
-
-namespace {
-
-const pass_data pass_data_init_datastructures =
-{
- GIMPLE_PASS, /* type */
- "*init_datastructures", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
-};
-
-class pass_init_datastructures : public gimple_opt_pass
-{
-public:
- pass_init_datastructures (gcc::context *ctxt)
- : gimple_opt_pass (pass_data_init_datastructures, ctxt)
- {}
-
- /* opt_pass methods: */
- virtual bool gate (function *fun)
- {
- /* Do nothing for funcions that was produced already in SSA form. */
- return !(fun->curr_properties & PROP_ssa);
- }
-
- virtual unsigned int execute (function *)
- {
- return execute_init_datastructures ();
- }
-
-}; // class pass_init_datastructures
-
-} // anon namespace
-
-gimple_opt_pass *
-make_pass_init_datastructures (gcc::context *ctxt)
-{
- return new pass_init_datastructures (ctxt);
-}
-
/* Deallocate memory associated with SSA data structures for FNDECL. */
void
@@ -1331,21 +1275,48 @@ non_rewritable_lvalue_p (tree lhs)
&& DECL_P (TREE_OPERAND (lhs, 0)))
return false;
- /* A decl that is wrapped inside a MEM-REF that covers
- it full is also rewritable.
- ??? The following could be relaxed allowing component
+ /* ??? The following could be relaxed allowing component
references that do not change the access size. */
if (TREE_CODE (lhs) == MEM_REF
- && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
- && integer_zerop (TREE_OPERAND (lhs, 1)))
+ && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR)
{
tree decl = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0);
- if (DECL_P (decl)
+
+ /* A decl that is wrapped inside a MEM-REF that covers
+ it full is also rewritable. */
+ if (integer_zerop (TREE_OPERAND (lhs, 1))
+ && DECL_P (decl)
&& DECL_SIZE (decl) == TYPE_SIZE (TREE_TYPE (lhs))
&& (TREE_THIS_VOLATILE (decl) == TREE_THIS_VOLATILE (lhs)))
return false;
+
+ /* A vector-insert using a MEM_REF or ARRAY_REF is rewritable
+ using a BIT_INSERT_EXPR. */
+ if (DECL_P (decl)
+ && VECTOR_TYPE_P (TREE_TYPE (decl))
+ && TYPE_MODE (TREE_TYPE (decl)) != BLKmode
+ && types_compatible_p (TREE_TYPE (lhs),
+ TREE_TYPE (TREE_TYPE (decl)))
+ && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1))
+ && tree_int_cst_lt (TREE_OPERAND (lhs, 1),
+ TYPE_SIZE_UNIT (TREE_TYPE (decl)))
+ && (tree_to_uhwi (TREE_OPERAND (lhs, 1))
+ % tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0)
+ return false;
}
+ /* A vector-insert using a BIT_FIELD_REF is rewritable using
+ BIT_INSERT_EXPR. */
+ if (TREE_CODE (lhs) == BIT_FIELD_REF
+ && DECL_P (TREE_OPERAND (lhs, 0))
+ && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0)))
+ && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode
+ && types_compatible_p (TREE_TYPE (lhs),
+ TREE_TYPE (TREE_TYPE (TREE_OPERAND (lhs, 0))))
+ && (tree_to_uhwi (TREE_OPERAND (lhs, 2))
+ % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs)))) == 0)
+ return false;
+
return true;
}
@@ -1567,6 +1538,62 @@ execute_update_addresses_taken (void)
continue;
}
+ /* Rewrite a vector insert via a BIT_FIELD_REF on the LHS
+ into a BIT_INSERT_EXPR. */
+ if (TREE_CODE (lhs) == BIT_FIELD_REF
+ && DECL_P (TREE_OPERAND (lhs, 0))
+ && bitmap_bit_p (suitable_for_renaming,
+ DECL_UID (TREE_OPERAND (lhs, 0)))
+ && VECTOR_TYPE_P (TREE_TYPE (TREE_OPERAND (lhs, 0)))
+ && TYPE_MODE (TREE_TYPE (TREE_OPERAND (lhs, 0))) != BLKmode
+ && types_compatible_p (TREE_TYPE (lhs),
+ TREE_TYPE (TREE_TYPE
+ (TREE_OPERAND (lhs, 0))))
+ && (tree_to_uhwi (TREE_OPERAND (lhs, 2))
+ % tree_to_uhwi (TYPE_SIZE (TREE_TYPE (lhs))) == 0))
+ {
+ tree var = TREE_OPERAND (lhs, 0);
+ tree val = gimple_assign_rhs1 (stmt);
+ tree bitpos = TREE_OPERAND (lhs, 2);
+ gimple_assign_set_lhs (stmt, var);
+ gimple_assign_set_rhs_with_ops
+ (&gsi, BIT_INSERT_EXPR, var, val, bitpos);
+ stmt = gsi_stmt (gsi);
+ unlink_stmt_vdef (stmt);
+ update_stmt (stmt);
+ continue;
+ }
+
+ /* Rewrite a vector insert using a MEM_REF on the LHS
+ into a BIT_INSERT_EXPR. */
+ if (TREE_CODE (lhs) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (lhs, 0)) == ADDR_EXPR
+ && (sym = TREE_OPERAND (TREE_OPERAND (lhs, 0), 0))
+ && DECL_P (sym)
+ && bitmap_bit_p (suitable_for_renaming, DECL_UID (sym))
+ && VECTOR_TYPE_P (TREE_TYPE (sym))
+ && TYPE_MODE (TREE_TYPE (sym)) != BLKmode
+ && types_compatible_p (TREE_TYPE (lhs),
+ TREE_TYPE (TREE_TYPE (sym)))
+ && tree_fits_uhwi_p (TREE_OPERAND (lhs, 1))
+ && tree_int_cst_lt (TREE_OPERAND (lhs, 1),
+ TYPE_SIZE_UNIT (TREE_TYPE (sym)))
+ && (tree_to_uhwi (TREE_OPERAND (lhs, 1))
+ % tree_to_uhwi (TYPE_SIZE_UNIT (TREE_TYPE (lhs)))) == 0)
+ {
+ tree val = gimple_assign_rhs1 (stmt);
+ tree bitpos
+ = wide_int_to_tree (bitsizetype,
+ mem_ref_offset (lhs) * BITS_PER_UNIT);
+ gimple_assign_set_lhs (stmt, sym);
+ gimple_assign_set_rhs_with_ops
+ (&gsi, BIT_INSERT_EXPR, sym, val, bitpos);
+ stmt = gsi_stmt (gsi);
+ unlink_stmt_vdef (stmt);
+ update_stmt (stmt);
+ continue;
+ }
+
/* We shouldn't have any fancy wrapping of
component-refs on the LHS, but look through
VIEW_CONVERT_EXPRs as that is easy. */
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index b72c7cb55b1..91a8f97ebea 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -740,10 +740,6 @@ release_defs (gimple *stmt)
tree def;
ssa_op_iter iter;
- /* Make sure that we are in SSA. Otherwise, operand cache may point
- to garbage. */
- gcc_assert (gimple_in_ssa_p (cfun));
-
FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_ALL_DEFS)
if (TREE_CODE (def) == SSA_NAME)
release_ssa_name (def);
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index da98211b27c..153372b4d3d 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -437,7 +437,9 @@ vect_determine_vectorization_factor (loop_vec_info loop_vinfo)
/* Bool ops don't participate in vectorization factor
computation. For comparison use compared types to
compute a factor. */
- if (TREE_CODE (scalar_type) == BOOLEAN_TYPE)
+ if (TREE_CODE (scalar_type) == BOOLEAN_TYPE
+ && is_gimple_assign (stmt)
+ && gimple_assign_rhs_code (stmt) != COND_EXPR)
{
if (STMT_VINFO_RELEVANT_P (stmt_info))
mask_producers.safe_push (stmt_info);
@@ -2063,6 +2065,8 @@ start_over:
estimated_niter
= estimated_stmt_executions_int (LOOP_VINFO_LOOP (loop_vinfo));
+ if (estimated_niter == -1)
+ estimated_niter = max_niter;
if (estimated_niter != -1
&& ((unsigned HOST_WIDE_INT) estimated_niter
<= MAX (th, (unsigned)min_profitable_estimate)))
@@ -6157,21 +6161,14 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
Finally, we update the phi (NEW_PHI_TREE) to take the value of
the new cond_expr (INDEX_COND_EXPR). */
- /* Turn the condition from vec_stmt into an ssa name. */
- gimple_stmt_iterator vec_stmt_gsi = gsi_for_stmt (*vec_stmt);
- tree ccompare = gimple_assign_rhs1 (*vec_stmt);
- tree ccompare_name = make_ssa_name (TREE_TYPE (ccompare));
- gimple *ccompare_stmt = gimple_build_assign (ccompare_name,
- ccompare);
- gsi_insert_before (&vec_stmt_gsi, ccompare_stmt, GSI_SAME_STMT);
- gimple_assign_set_rhs1 (*vec_stmt, ccompare_name);
- update_stmt (*vec_stmt);
+ /* Duplicate the condition from vec_stmt. */
+ tree ccompare = unshare_expr (gimple_assign_rhs1 (*vec_stmt));
/* Create a conditional, where the condition is taken from vec_stmt
- (CCOMPARE_NAME), then is the induction index (INDEX_BEFORE_INCR)
- and else is the phi (NEW_PHI_TREE). */
+ (CCOMPARE), then is the induction index (INDEX_BEFORE_INCR) and
+ else is the phi (NEW_PHI_TREE). */
tree index_cond_expr = build3 (VEC_COND_EXPR, cr_index_vector_type,
- ccompare_name, indx_before_incr,
+ ccompare, indx_before_incr,
new_phi_tree);
cond_name = make_ssa_name (cr_index_vector_type);
gimple *index_condition = gimple_build_assign (cond_name,
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 27080d28a1d..cc8c445863e 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -3570,7 +3570,8 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
{
gimple *last_stmt = stmts->pop ();
enum tree_code rhs_code;
- tree lhs, rhs1, rhs2, tmp, rhs1_type, rhs2_type, vectype1, vectype2;
+ tree lhs = NULL_TREE, rhs1, rhs2, tmp, rhs1_type, rhs2_type;
+ tree vectype1, vectype2;
stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt);
stmt_vec_info pattern_stmt_info;
vec_info *vinfo = stmt_vinfo->vinfo;
@@ -3673,8 +3674,10 @@ vect_recog_mask_conversion_pattern (vec<gimple *> *stmts, tree *type_in,
if (!rhs1_type)
return NULL;
}
- else
+ else if (COMPARISON_CLASS_P (rhs1))
rhs1_type = TREE_TYPE (TREE_OPERAND (rhs1, 0));
+ else
+ return NULL;
vectype2 = get_mask_type_for_scalar_type (rhs1_type);
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index d71384881b7..3de53d1188c 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1308,7 +1308,10 @@ vect_attempt_slp_rearrange_stmts (slp_instance slp_instn)
FOR_EACH_VEC_ELT (node->load_permutation, i, lidx)
{
if (lidx >= group_size)
- return false;
+ {
+ sbitmap_free (load_index);
+ return false;
+ }
if (bitmap_bit_p (load_index, lidx))
{
sbitmap_free (load_index);
@@ -1754,18 +1757,6 @@ vect_analyze_slp_instance (vec_info *vinfo,
}
nunits = TYPE_VECTOR_SUBPARTS (vectype);
- /* Calculate the unrolling factor. */
- unrolling_factor = least_common_multiple (nunits, group_size) / group_size;
- if (unrolling_factor != 1 && is_a <bb_vec_info> (vinfo))
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "Build SLP failed: unrolling required in basic"
- " block SLP\n");
-
- return false;
- }
-
/* Create a node (a root of the SLP tree) for the packed grouped stores. */
scalar_stmts.create (group_size);
next = stmt;
@@ -1801,26 +1792,36 @@ vect_analyze_slp_instance (vec_info *vinfo,
/* Build the tree for the SLP instance. */
bool *matches = XALLOCAVEC (bool, group_size);
unsigned npermutes = 0;
- if ((node = vect_build_slp_tree (vinfo, scalar_stmts, group_size,
+ node = vect_build_slp_tree (vinfo, scalar_stmts, group_size,
&max_nunits, &loads, matches, &npermutes,
- NULL, max_tree_size)) != NULL)
+ NULL, max_tree_size);
+ if (node != NULL)
{
/* Calculate the unrolling factor based on the smallest type. */
- if (max_nunits > nunits)
- unrolling_factor = least_common_multiple (max_nunits, group_size)
- / group_size;
+ unrolling_factor
+ = least_common_multiple (max_nunits, group_size) / group_size;
+
+ if (unrolling_factor != 1
+ && is_a <bb_vec_info> (vinfo))
+ {
- if (unrolling_factor != 1 && is_a <bb_vec_info> (vinfo))
+ if (max_nunits > group_size)
{
- if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "Build SLP failed: unrolling required in basic"
- " block SLP\n");
+ "Build SLP failed: store group "
+ "size not a multiple of the vector size "
+ "in basic block SLP\n");
vect_free_slp_tree (node);
loads.release ();
return false;
}
-
+ /* Fatal mismatch. */
+ matches[group_size/max_nunits * max_nunits] = false;
+ vect_free_slp_tree (node);
+ loads.release ();
+ }
+ else
+ {
/* Create a new SLP instance. */
new_instance = XNEW (struct _slp_instance);
SLP_INSTANCE_TREE (new_instance) = node;
@@ -1842,8 +1843,8 @@ vect_analyze_slp_instance (vec_info *vinfo,
(vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (load_node)[0]));
FOR_EACH_VEC_ELT (SLP_TREE_SCALAR_STMTS (load_node), j, load)
{
- int load_place
- = vect_get_place_in_interleaving_chain (load, first_stmt);
+ int load_place = vect_get_place_in_interleaving_chain
+ (load, first_stmt);
gcc_assert (load_place != -1);
if (load_place != j)
this_load_permuted = true;
@@ -1873,7 +1874,8 @@ vect_analyze_slp_instance (vec_info *vinfo,
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"Build SLP failed: unsupported load "
"permutation ");
- dump_gimple_stmt (MSG_MISSED_OPTIMIZATION, TDF_SLIM, stmt, 0);
+ dump_gimple_stmt (MSG_MISSED_OPTIMIZATION,
+ TDF_SLIM, stmt, 0);
dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
}
vect_free_slp_instance (new_instance);
@@ -1881,7 +1883,7 @@ vect_analyze_slp_instance (vec_info *vinfo,
}
}
- /* If the loads and stores can be handled with load/store-lane
+ /* If the loads and stores can be handled with load/store-lan
instructions do not generate this SLP instance. */
if (is_a <loop_vec_info> (vinfo)
&& loads_permuted
@@ -1893,7 +1895,8 @@ vect_analyze_slp_instance (vec_info *vinfo,
gimple *first_stmt = GROUP_FIRST_ELEMENT
(vinfo_for_stmt (SLP_TREE_SCALAR_STMTS (load_node)[0]));
stmt_vec_info stmt_vinfo = vinfo_for_stmt (first_stmt);
- /* Use SLP for strided accesses (or if we can't load-lanes). */
+ /* Use SLP for strided accesses (or if we
+ can't load-lanes). */
if (STMT_VINFO_STRIDED_P (stmt_vinfo)
|| ! vect_load_lanes_supported
(STMT_VINFO_VECTYPE (stmt_vinfo),
@@ -1922,11 +1925,14 @@ vect_analyze_slp_instance (vec_info *vinfo,
return true;
}
-
+ }
+ else
+ {
/* Failed to SLP. */
/* Free the allocated memory. */
scalar_stmts.release ();
loads.release ();
+ }
/* For basic block SLP, try to break the group up into multiples of the
vector size. */
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 9ab4af4f97e..3bcd0ce1946 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -2755,7 +2755,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
gimple *def_stmt;
gimple *new_stmt = NULL;
int ncopies, j;
- vec<simd_call_arg_info> arginfo = vNULL;
+ auto_vec<simd_call_arg_info> arginfo;
vec<tree> vargs = vNULL;
size_t i, nargs;
tree lhs, rtype, ratype;
@@ -2802,7 +2802,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
if (nargs == 0)
return false;
- arginfo.create (nargs);
+ arginfo.reserve (nargs, true);
for (i = 0; i < nargs; i++)
{
@@ -2822,7 +2822,6 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
"use not simple.\n");
- arginfo.release ();
return false;
}
@@ -2978,10 +2977,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
}
if (bestn == NULL)
- {
- arginfo.release ();
- return false;
- }
+ return false;
for (i = 0; i < nargs; i++)
if ((arginfo[i].dt == vect_constant_def
@@ -2994,10 +2990,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
if (arginfo[i].vectype == NULL
|| (TYPE_VECTOR_SUBPARTS (arginfo[i].vectype)
> bestn->simdclone->simdlen))
- {
- arginfo.release ();
- return false;
- }
+ return false;
}
fndecl = bestn->decl;
@@ -3009,10 +3002,7 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
performed using SIMD instructions. */
if ((loop == NULL || (unsigned) loop->safelen < nunits)
&& gimple_vuse (stmt))
- {
- arginfo.release ();
- return false;
- }
+ return false;
/* Sanity check: make sure that at least one copy of the vectorized stmt
needs to be generated. */
@@ -3041,7 +3031,6 @@ vectorizable_simd_clone_call (gimple *stmt, gimple_stmt_iterator *gsi,
dump_printf_loc (MSG_NOTE, vect_location,
"=== vectorizable_simd_clone_call ===\n");
/* vect_model_simple_cost (stmt_info, ncopies, dt, NULL, NULL); */
- arginfo.release ();
return true;
}
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 2b25b4503ac..26698135f54 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -794,38 +794,142 @@ make_pass_slp_vectorize (gcc::context *ctxt)
This should involve global alignment analysis and in the future also
array padding. */
+static unsigned get_vec_alignment_for_type (tree);
+static hash_map<tree, unsigned> *type_align_map;
+
+/* Return alignment of array's vector type corresponding to scalar type.
+ 0 if no vector type exists. */
+static unsigned
+get_vec_alignment_for_array_type (tree type)
+{
+ gcc_assert (TREE_CODE (type) == ARRAY_TYPE);
+
+ tree vectype = get_vectype_for_scalar_type (strip_array_types (type));
+ if (!vectype
+ || !TYPE_SIZE (type)
+ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
+ || tree_int_cst_lt (TYPE_SIZE (type), TYPE_SIZE (vectype)))
+ return 0;
+
+ return TYPE_ALIGN (vectype);
+}
+
+/* Return alignment of field having maximum alignment of vector type
+ corresponding to it's scalar type. For now, we only consider fields whose
+ offset is a multiple of it's vector alignment.
+ 0 if no suitable field is found. */
+static unsigned
+get_vec_alignment_for_record_type (tree type)
+{
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+
+ unsigned max_align = 0, alignment;
+ HOST_WIDE_INT offset;
+ tree offset_tree;
+
+ if (TYPE_PACKED (type))
+ return 0;
+
+ unsigned *slot = type_align_map->get (type);
+ if (slot)
+ return *slot;
+
+ for (tree field = first_field (type);
+ field != NULL_TREE;
+ field = DECL_CHAIN (field))
+ {
+ /* Skip if not FIELD_DECL or if alignment is set by user. */
+ if (TREE_CODE (field) != FIELD_DECL
+ || DECL_USER_ALIGN (field)
+ || DECL_ARTIFICIAL (field))
+ continue;
+
+ /* We don't need to process the type further if offset is variable,
+ since the offsets of remaining members will also be variable. */
+ if (TREE_CODE (DECL_FIELD_OFFSET (field)) != INTEGER_CST
+ || TREE_CODE (DECL_FIELD_BIT_OFFSET (field)) != INTEGER_CST)
+ break;
+
+ /* Similarly stop processing the type if offset_tree
+ does not fit in unsigned HOST_WIDE_INT. */
+ offset_tree = bit_position (field);
+ if (!tree_fits_uhwi_p (offset_tree))
+ break;
+
+ offset = tree_to_uhwi (offset_tree);
+ alignment = get_vec_alignment_for_type (TREE_TYPE (field));
+
+ /* Get maximum alignment of vectorized field/array among those members
+ whose offset is multiple of the vector alignment. */
+ if (alignment
+ && (offset % alignment == 0)
+ && (alignment > max_align))
+ max_align = alignment;
+ }
+
+ type_align_map->put (type, max_align);
+ return max_align;
+}
+
+/* Return alignment of vector type corresponding to decl's scalar type
+ or 0 if it doesn't exist or the vector alignment is lesser than
+ decl's alignment. */
+static unsigned
+get_vec_alignment_for_type (tree type)
+{
+ if (type == NULL_TREE)
+ return 0;
+
+ gcc_assert (TYPE_P (type));
+
+ static unsigned alignment = 0;
+ switch (TREE_CODE (type))
+ {
+ case ARRAY_TYPE:
+ alignment = get_vec_alignment_for_array_type (type);
+ break;
+ case RECORD_TYPE:
+ alignment = get_vec_alignment_for_record_type (type);
+ break;
+ default:
+ alignment = 0;
+ break;
+ }
+
+ return (alignment > TYPE_ALIGN (type)) ? alignment : 0;
+}
+
+/* Entry point to increase_alignment pass. */
static unsigned int
increase_alignment (void)
{
varpool_node *vnode;
vect_location = UNKNOWN_LOCATION;
+ type_align_map = new hash_map<tree, unsigned>;
/* Increase the alignment of all global arrays for vectorization. */
FOR_EACH_DEFINED_VARIABLE (vnode)
{
- tree vectype, decl = vnode->decl;
- tree t;
+ tree decl = vnode->decl;
unsigned int alignment;
- t = TREE_TYPE (decl);
- if (TREE_CODE (t) != ARRAY_TYPE)
- continue;
- vectype = get_vectype_for_scalar_type (strip_array_types (t));
- if (!vectype)
- continue;
- alignment = TYPE_ALIGN (vectype);
- if (DECL_ALIGN (decl) >= alignment)
- continue;
-
- if (vect_can_force_dr_alignment_p (decl, alignment))
+ if ((decl_in_symtab_p (decl)
+ && !symtab_node::get (decl)->can_increase_alignment_p ())
+ || DECL_USER_ALIGN (decl) || DECL_ARTIFICIAL (decl))
+ continue;
+
+ alignment = get_vec_alignment_for_type (TREE_TYPE (decl));
+ if (alignment && vect_can_force_dr_alignment_p (decl, alignment))
{
- vnode->increase_alignment (TYPE_ALIGN (vectype));
+ vnode->increase_alignment (alignment);
dump_printf (MSG_NOTE, "Increasing alignment of decl: ");
dump_generic_expr (MSG_NOTE, TDF_SLIM, decl);
dump_printf (MSG_NOTE, "\n");
}
}
+
+ delete type_align_map;
return 0;
}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 4cd1ab30b30..68f2e905424 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -1187,129 +1187,77 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
val2 = fold_convert (TREE_TYPE (val1), val2);
STRIP_USELESS_TYPE_CONVERSION (val2);
- if ((TREE_CODE (val1) == SSA_NAME
- || (TREE_CODE (val1) == NEGATE_EXPR
- && TREE_CODE (TREE_OPERAND (val1, 0)) == SSA_NAME)
- || TREE_CODE (val1) == PLUS_EXPR
- || TREE_CODE (val1) == MINUS_EXPR)
- && (TREE_CODE (val2) == SSA_NAME
- || (TREE_CODE (val2) == NEGATE_EXPR
- && TREE_CODE (TREE_OPERAND (val2, 0)) == SSA_NAME)
- || TREE_CODE (val2) == PLUS_EXPR
- || TREE_CODE (val2) == MINUS_EXPR))
- {
- tree n1, c1, n2, c2;
- enum tree_code code1, code2;
-
- /* If VAL1 and VAL2 are of the form '[-]NAME [+-] CST' or 'NAME',
- return -1 or +1 accordingly. If VAL1 and VAL2 don't use the
- same name, return -2. */
- if (TREE_CODE (val1) == SSA_NAME || TREE_CODE (val1) == NEGATE_EXPR)
- {
- code1 = SSA_NAME;
- n1 = val1;
- c1 = NULL_TREE;
- }
- else
- {
- code1 = TREE_CODE (val1);
- n1 = TREE_OPERAND (val1, 0);
- c1 = TREE_OPERAND (val1, 1);
- if (tree_int_cst_sgn (c1) == -1)
- {
- if (is_negative_overflow_infinity (c1))
- return -2;
- c1 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c1), c1);
- if (!c1)
- return -2;
- code1 = code1 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
- }
- }
-
- if (TREE_CODE (val2) == SSA_NAME || TREE_CODE (val2) == NEGATE_EXPR)
- {
- code2 = SSA_NAME;
- n2 = val2;
- c2 = NULL_TREE;
- }
- else
- {
- code2 = TREE_CODE (val2);
- n2 = TREE_OPERAND (val2, 0);
- c2 = TREE_OPERAND (val2, 1);
- if (tree_int_cst_sgn (c2) == -1)
- {
- if (is_negative_overflow_infinity (c2))
- return -2;
- c2 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c2), c2);
- if (!c2)
- return -2;
- code2 = code2 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
- }
- }
-
- /* Both values must use the same name. */
- if (TREE_CODE (n1) == NEGATE_EXPR && TREE_CODE (n2) == NEGATE_EXPR)
- {
- n1 = TREE_OPERAND (n1, 0);
- n2 = TREE_OPERAND (n2, 0);
- }
- if (n1 != n2)
+ const bool overflow_undefined
+ = INTEGRAL_TYPE_P (TREE_TYPE (val1))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1));
+ tree inv1, inv2;
+ bool neg1, neg2;
+ tree sym1 = get_single_symbol (val1, &neg1, &inv1);
+ tree sym2 = get_single_symbol (val2, &neg2, &inv2);
+
+ /* If VAL1 and VAL2 are of the form '[-]NAME [+ CST]', return -1 or +1
+ accordingly. If VAL1 and VAL2 don't use the same name, return -2. */
+ if (sym1 && sym2)
+ {
+ /* Both values must use the same name with the same sign. */
+ if (sym1 != sym2 || neg1 != neg2)
return -2;
- if (code1 == SSA_NAME && code2 == SSA_NAME)
- /* NAME == NAME */
+ /* [-]NAME + CST == [-]NAME + CST. */
+ if (inv1 == inv2)
return 0;
/* If overflow is defined we cannot simplify more. */
- if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1)))
+ if (!overflow_undefined)
return -2;
if (strict_overflow_p != NULL
- && (code1 == SSA_NAME || !TREE_NO_WARNING (val1))
- && (code2 == SSA_NAME || !TREE_NO_WARNING (val2)))
+ && (!inv1 || !TREE_NO_WARNING (val1))
+ && (!inv2 || !TREE_NO_WARNING (val2)))
*strict_overflow_p = true;
- if (code1 == SSA_NAME)
- {
- if (code2 == PLUS_EXPR)
- /* NAME < NAME + CST */
- return -1;
- else if (code2 == MINUS_EXPR)
- /* NAME > NAME - CST */
- return 1;
- }
- else if (code1 == PLUS_EXPR)
- {
- if (code2 == SSA_NAME)
- /* NAME + CST > NAME */
- return 1;
- else if (code2 == PLUS_EXPR)
- /* NAME + CST1 > NAME + CST2, if CST1 > CST2 */
- return compare_values_warnv (c1, c2, strict_overflow_p);
- else if (code2 == MINUS_EXPR)
- /* NAME + CST1 > NAME - CST2 */
- return 1;
- }
- else if (code1 == MINUS_EXPR)
+ if (!inv1)
+ inv1 = build_int_cst (TREE_TYPE (val1), 0);
+ if (!inv2)
+ inv2 = build_int_cst (TREE_TYPE (val2), 0);
+
+ return compare_values_warnv (inv1, inv2, strict_overflow_p);
+ }
+
+ const bool cst1 = is_gimple_min_invariant (val1);
+ const bool cst2 = is_gimple_min_invariant (val2);
+
+ /* If one is of the form '[-]NAME + CST' and the other is constant, then
+ it might be possible to say something depending on the constants. */
+ if ((sym1 && inv1 && cst2) || (sym2 && inv2 && cst1))
+ {
+ if (!overflow_undefined)
+ return -2;
+
+ if (strict_overflow_p != NULL
+ && (!sym1 || !TREE_NO_WARNING (val1))
+ && (!sym2 || !TREE_NO_WARNING (val2)))
+ *strict_overflow_p = true;
+
+ const signop sgn = TYPE_SIGN (TREE_TYPE (val1));
+ tree cst = cst1 ? val1 : val2;
+ tree inv = cst1 ? inv2 : inv1;
+
+ /* Compute the difference between the constants. If it overflows or
+ underflows, this means that we can trivially compare the NAME with
+ it and, consequently, the two values with each other. */
+ wide_int diff = wi::sub (cst, inv);
+ if (wi::cmp (0, inv, sgn) != wi::cmp (diff, cst, sgn))
{
- if (code2 == SSA_NAME)
- /* NAME - CST < NAME */
- return -1;
- else if (code2 == PLUS_EXPR)
- /* NAME - CST1 < NAME + CST2 */
- return -1;
- else if (code2 == MINUS_EXPR)
- /* NAME - CST1 > NAME - CST2, if CST1 < CST2. Notice that
- C1 and C2 are swapped in the call to compare_values. */
- return compare_values_warnv (c2, c1, strict_overflow_p);
+ const int res = wi::cmp (cst, inv, sgn);
+ return cst1 ? res : -res;
}
- gcc_unreachable ();
+ return -2;
}
- /* We cannot compare non-constants. */
- if (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2))
+ /* We cannot say anything more for non-constants. */
+ if (!cst1 || !cst2)
return -2;
if (!POINTER_TYPE_P (TREE_TYPE (val1)))
@@ -2519,20 +2467,13 @@ extract_range_from_binary_expr_1 (value_range *vr,
min = wide_int_to_tree (expr_type, tmin);
max = wide_int_to_tree (expr_type, tmax);
}
- else if (min_ovf == -1 && max_ovf == 1)
- {
- /* Underflow and overflow, drop to VR_VARYING. */
- set_value_range_to_varying (vr);
- return;
- }
- else
+ else if ((min_ovf == -1 && max_ovf == 0)
+ || (max_ovf == 1 && min_ovf == 0))
{
/* Min underflow or max overflow. The range kind
changes to VR_ANTI_RANGE. */
bool covers = false;
wide_int tem = tmin;
- gcc_assert ((min_ovf == -1 && max_ovf == 0)
- || (max_ovf == 1 && min_ovf == 0));
type = VR_ANTI_RANGE;
tmin = tmax + 1;
if (wi::cmp (tmin, tmax, sgn) < 0)
@@ -2551,6 +2492,12 @@ extract_range_from_binary_expr_1 (value_range *vr,
min = wide_int_to_tree (expr_type, tmin);
max = wide_int_to_tree (expr_type, tmax);
}
+ else
+ {
+ /* Other underflow and/or overflow, drop to VR_VARYING. */
+ set_value_range_to_varying (vr);
+ return;
+ }
}
else
{
@@ -8940,6 +8887,11 @@ simplify_truth_ops_using_ranges (gimple_stmt_iterator *gsi, gimple *stmt)
gassign *newop
= gimple_build_assign (tem, BIT_XOR_EXPR, op0, op1);
gsi_insert_before (gsi, newop, GSI_SAME_STMT);
+ if (INTEGRAL_TYPE_P (TREE_TYPE (tem))
+ && TYPE_PRECISION (TREE_TYPE (tem)) > 1)
+ set_range_info (tem, VR_RANGE,
+ wi::zero (TYPE_PRECISION (TREE_TYPE (tem))),
+ wi::one (TYPE_PRECISION (TREE_TYPE (tem))));
gimple_assign_set_rhs_with_ops (gsi, NOP_EXPR, tem);
}
/* Or without. */
@@ -9648,7 +9600,6 @@ simplify_conversion_using_ranges (gimple *stmt)
{
tree innerop, middleop, finaltype;
gimple *def_stmt;
- value_range *innervr;
signop inner_sgn, middle_sgn, final_sgn;
unsigned inner_prec, middle_prec, final_prec;
widest_int innermin, innermed, innermax, middlemin, middlemed, middlemax;
@@ -9666,18 +9617,17 @@ simplify_conversion_using_ranges (gimple *stmt)
|| SSA_NAME_OCCURS_IN_ABNORMAL_PHI (innerop))
return false;
- /* Get the value-range of the inner operand. */
- innervr = get_value_range (innerop);
- if (innervr->type != VR_RANGE
- || TREE_CODE (innervr->min) != INTEGER_CST
- || TREE_CODE (innervr->max) != INTEGER_CST)
+ /* Get the value-range of the inner operand. Use get_range_info in
+ case innerop was created during substitute-and-fold. */
+ wide_int imin, imax;
+ if (!INTEGRAL_TYPE_P (TREE_TYPE (innerop))
+ || get_range_info (innerop, &imin, &imax) != VR_RANGE)
return false;
+ innermin = widest_int::from (imin, TYPE_SIGN (TREE_TYPE (innerop)));
+ innermax = widest_int::from (imax, TYPE_SIGN (TREE_TYPE (innerop)));
/* Simulate the conversion chain to check if the result is equal if
the middle conversion is removed. */
- innermin = wi::to_widest (innervr->min);
- innermax = wi::to_widest (innervr->max);
-
inner_prec = TYPE_PRECISION (TREE_TYPE (innerop));
middle_prec = TYPE_PRECISION (TREE_TYPE (middleop));
final_prec = TYPE_PRECISION (finaltype);
diff --git a/gcc/tree.c b/gcc/tree.c
index f7366f63402..83dc7d8bc90 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -2939,7 +2939,7 @@ ctor_to_vec (tree ctor)
make_unsigned_type). */
tree
-size_in_bytes (const_tree type)
+size_in_bytes_loc (location_t loc, const_tree type)
{
tree t;
@@ -2951,7 +2951,7 @@ size_in_bytes (const_tree type)
if (t == 0)
{
- lang_hooks.types.incomplete_type_error (NULL_TREE, type);
+ lang_hooks.types.incomplete_type_error (loc, NULL_TREE, type);
return size_zero_node;
}
@@ -5418,7 +5418,7 @@ free_lang_data_in_decl (tree decl)
DECL_INITIAL (decl) = error_mark_node;
}
}
- if (gimple_has_body_p (decl))
+ if (gimple_has_body_p (decl) || (node && node->thunk.thunk_p))
{
tree t;
@@ -7915,9 +7915,12 @@ add_expr (const_tree t, inchash::hash &hstate, unsigned int flags)
&& integer_zerop (TREE_OPERAND (t, 1)))
inchash::add_expr (TREE_OPERAND (TREE_OPERAND (t, 0), 0),
hstate, flags);
+ /* Don't ICE on FE specific trees, or their arguments etc.
+ during operand_equal_p hash verification. */
+ else if (!IS_EXPR_CODE_CLASS (tclass))
+ gcc_assert (flags & OEP_HASH_CHECK);
else
{
- gcc_assert (IS_EXPR_CODE_CLASS (tclass));
unsigned int sflags = flags;
hstate.add_object (code);
@@ -7966,6 +7969,13 @@ add_expr (const_tree t, inchash::hash &hstate, unsigned int flags)
hstate.add_int (CALL_EXPR_IFN (t));
break;
+ case TARGET_EXPR:
+ /* For TARGET_EXPR, just hash on the TARGET_EXPR_SLOT.
+ Usually different TARGET_EXPRs just should use
+ different temporaries in their slots. */
+ inchash::add_expr (TARGET_EXPR_SLOT (t), hstate, flags);
+ return;
+
default:
break;
}
@@ -8774,6 +8784,7 @@ build_complex_type (tree component_type)
t = make_node (COMPLEX_TYPE);
TREE_TYPE (t) = TYPE_MAIN_VARIANT (component_type);
+ SET_TYPE_MODE (t, GET_MODE_COMPLEX_MODE (TYPE_MODE (component_type)));
/* If we already have such a type, use the old one. */
hstate.add_object (TYPE_HASH (component_type));
@@ -10440,6 +10451,11 @@ set_call_expr_flags (tree decl, int flags)
if (flags & ECF_LEAF)
DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
NULL, DECL_ATTRIBUTES (decl));
+ if (flags & ECF_RET1)
+ DECL_ATTRIBUTES (decl)
+ = tree_cons (get_identifier ("fn spec"),
+ build_tree_list (NULL_TREE, build_string (1, "1")),
+ DECL_ATTRIBUTES (decl));
if ((flags & ECF_TM_PURE) && flag_tm)
apply_tm_attr (decl, get_identifier ("transaction_pure"));
/* Looping const or pure is implied by noreturn.
@@ -10475,13 +10491,20 @@ build_common_builtin_nodes (void)
tree tmp, ftype;
int ecf_flags;
- if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE))
+ if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE)
+ || !builtin_decl_explicit_p (BUILT_IN_ABORT))
{
ftype = build_function_type (void_type_node, void_list_node);
- local_define_builtin ("__builtin_unreachable", ftype, BUILT_IN_UNREACHABLE,
- "__builtin_unreachable",
- ECF_NOTHROW | ECF_LEAF | ECF_NORETURN
- | ECF_CONST);
+ if (!builtin_decl_explicit_p (BUILT_IN_UNREACHABLE))
+ local_define_builtin ("__builtin_unreachable", ftype,
+ BUILT_IN_UNREACHABLE,
+ "__builtin_unreachable",
+ ECF_NOTHROW | ECF_LEAF | ECF_NORETURN
+ | ECF_CONST);
+ if (!builtin_decl_explicit_p (BUILT_IN_ABORT))
+ local_define_builtin ("__builtin_abort", ftype, BUILT_IN_ABORT,
+ "abort",
+ ECF_LEAF | ECF_NORETURN | ECF_CONST);
}
if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY)
@@ -10493,10 +10516,10 @@ build_common_builtin_nodes (void)
if (!builtin_decl_explicit_p (BUILT_IN_MEMCPY))
local_define_builtin ("__builtin_memcpy", ftype, BUILT_IN_MEMCPY,
- "memcpy", ECF_NOTHROW | ECF_LEAF);
+ "memcpy", ECF_NOTHROW | ECF_LEAF | ECF_RET1);
if (!builtin_decl_explicit_p (BUILT_IN_MEMMOVE))
local_define_builtin ("__builtin_memmove", ftype, BUILT_IN_MEMMOVE,
- "memmove", ECF_NOTHROW | ECF_LEAF);
+ "memmove", ECF_NOTHROW | ECF_LEAF | ECF_RET1);
}
if (!builtin_decl_explicit_p (BUILT_IN_MEMCMP))
@@ -10514,15 +10537,19 @@ build_common_builtin_nodes (void)
ptr_type_node, integer_type_node,
size_type_node, NULL_TREE);
local_define_builtin ("__builtin_memset", ftype, BUILT_IN_MEMSET,
- "memset", ECF_NOTHROW | ECF_LEAF);
+ "memset", ECF_NOTHROW | ECF_LEAF | ECF_RET1);
}
+ /* If we're checking the stack, `alloca' can throw. */
+ const int alloca_flags
+ = ECF_MALLOC | ECF_LEAF | (flag_stack_check ? 0 : ECF_NOTHROW);
+
if (!builtin_decl_explicit_p (BUILT_IN_ALLOCA))
{
ftype = build_function_type_list (ptr_type_node,
size_type_node, NULL_TREE);
local_define_builtin ("__builtin_alloca", ftype, BUILT_IN_ALLOCA,
- "alloca", ECF_MALLOC | ECF_NOTHROW | ECF_LEAF);
+ "alloca", alloca_flags);
}
ftype = build_function_type_list (ptr_type_node, size_type_node,
@@ -10530,14 +10557,7 @@ build_common_builtin_nodes (void)
local_define_builtin ("__builtin_alloca_with_align", ftype,
BUILT_IN_ALLOCA_WITH_ALIGN,
"__builtin_alloca_with_align",
- ECF_MALLOC | ECF_NOTHROW | ECF_LEAF);
-
- /* If we're checking the stack, `alloca' can throw. */
- if (flag_stack_check)
- {
- TREE_NOTHROW (builtin_decl_explicit (BUILT_IN_ALLOCA)) = 0;
- TREE_NOTHROW (builtin_decl_explicit (BUILT_IN_ALLOCA_WITH_ALIGN)) = 0;
- }
+ alloca_flags);
ftype = build_function_type_list (void_type_node,
ptr_type_node, ptr_type_node,
@@ -13056,9 +13076,28 @@ array_at_struct_end_p (tree ref)
ref = TREE_OPERAND (ref, 0);
}
+ tree size = NULL;
+
+ if (TREE_CODE (ref) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (ref, 0)) == ADDR_EXPR)
+ {
+ size = TYPE_SIZE (TREE_TYPE (ref));
+ ref = TREE_OPERAND (TREE_OPERAND (ref, 0), 0);
+ }
+
/* If the reference is based on a declared entity, the size of the array
is constrained by its given domain. (Do not trust commons PR/69368). */
if (DECL_P (ref)
+ /* Be sure the size of MEM_REF target match. For example:
+
+ char buf[10];
+ struct foo *str = (struct foo *)&buf;
+
+ str->trailin_array[2] = 1;
+
+ is valid because BUF allocate enough space. */
+
+ && (!size || operand_equal_p (DECL_SIZE (ref), size, 0))
&& !(flag_unconstrained_commons
&& TREE_CODE (ref) == VAR_DECL && DECL_COMMON (ref)))
return false;
diff --git a/gcc/tree.def b/gcc/tree.def
index 44130d7c77f..d16575aee62 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -852,6 +852,21 @@ DEFTREECODE (ADDR_EXPR, "addr_expr", tcc_expression, 1)
descriptor of type ptr_mode. */
DEFTREECODE (FDESC_EXPR, "fdesc_expr", tcc_expression, 2)
+/* Given a container value, a replacement value and a bit position within
+ the container, produce the value that results from replacing the part of
+ the container starting at the bit position with the replacement value.
+ Operand 0 is a tree for the container value of integral or vector type;
+ Operand 1 is a tree for the replacement value of another integral or
+ the vector element type;
+ Operand 2 is a tree giving the constant bit position;
+ The number of bits replaced is given by the precision of the type of the
+ replacement value if it is integral or by its size if it is non-integral.
+ ??? The reason to make the size of the replacement implicit is to avoid
+ introducing a quaternary operation.
+ The replaced bits shall be fully inside the container. If the container
+ is of vector type, then these bits shall be aligned with its elements. */
+DEFTREECODE (BIT_INSERT_EXPR, "bit_field_insert", tcc_expression, 3)
+
/* Given two real or integer operands of the same type,
returns a complex value of the corresponding complex type. */
DEFTREECODE (COMPLEX_EXPR, "complex_expr", tcc_binary, 2)
diff --git a/gcc/tree.h b/gcc/tree.h
index 6e52e3d74da..2510d166ea6 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -661,6 +661,11 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
#define CALL_EXPR_TAILCALL(NODE) \
(CALL_EXPR_CHECK (NODE)->base.addressable_flag)
+/* Set on a CALL_EXPR if the call has been marked as requiring tail call
+ optimization for correctness. */
+#define CALL_EXPR_MUST_TAIL_CALL(NODE) \
+ (CALL_EXPR_CHECK (NODE)->base.static_flag)
+
/* Used as a temporary field on a CASE_LABEL_EXPR to indicate that the
CASE_LOW operand has been processed. */
#define CASE_LOW_SEEN(NODE) \
@@ -4224,7 +4229,13 @@ extern tree type_hash_canon (unsigned int, tree);
extern tree convert (tree, tree);
extern unsigned int expr_align (const_tree);
-extern tree size_in_bytes (const_tree);
+extern tree size_in_bytes_loc (location_t, const_tree);
+inline tree
+size_in_bytes (const_tree t)
+{
+ return size_in_bytes_loc (input_location, t);
+}
+
extern HOST_WIDE_INT int_size_in_bytes (const_tree);
extern HOST_WIDE_INT max_int_size_in_bytes (const_tree);
extern tree bit_position (const_tree);
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
index 802341e9995..c5543f821d8 100644
--- a/gcc/ubsan.c
+++ b/gcc/ubsan.c
@@ -302,7 +302,6 @@ ubsan_source_location (location_t loc)
static unsigned short
get_ubsan_type_info_for_type (tree type)
{
- gcc_assert (TYPE_SIZE (type) && tree_fits_uhwi_p (TYPE_SIZE (type)));
if (TREE_CODE (type) == REAL_TYPE)
return tree_to_uhwi (TYPE_SIZE (type));
else if (INTEGRAL_TYPE_P (type))
diff --git a/gcc/wide-int.h b/gcc/wide-int.h
index 7dde74f532f..382d5f31fee 100644
--- a/gcc/wide-int.h
+++ b/gcc/wide-int.h
@@ -294,7 +294,7 @@ along with GCC; see the file COPYING3. If not see
HOST_WIDE_INT *VAL = RESULT.write_val ()
template <typename T> class generic_wide_int;
-template <int N> struct fixed_wide_int_storage;
+template <int N> class fixed_wide_int_storage;
class wide_int_storage;
/* An N-bit integer. Until we can use typedef templates, use this instead. */
diff --git a/gnattools/ChangeLog b/gnattools/ChangeLog
index 18aa7021d66..9432ce1add5 100644
--- a/gnattools/ChangeLog
+++ b/gnattools/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-16 Eric Botcazou <ebotcazou@adacore.com>
+
+ * configure.ac: Add ACX_NONCANONICAL_HOST.
+ * configure: Regenerate.
+ * Makefile.in: Replace host_alias with host_noncanonical.
+ (gnattools-cross): Do not rename the tools.
+
2016-04-04 Segher Boessenkool <segher@kernel.crashing.org>
PR bootstrap/70173
diff --git a/gnattools/Makefile.in b/gnattools/Makefile.in
index f949ca9b34b..b0860eaf96d 100644
--- a/gnattools/Makefile.in
+++ b/gnattools/Makefile.in
@@ -25,7 +25,6 @@ libdir = @libdir@
build = @build@
target = @target@
host = @host@
-host_alias = @host_alias@
prefix = @prefix@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
@@ -34,6 +33,7 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
# Nonstandard autoconf-set variables.
LN_S=@LN_S@
target_noncanonical=@target_noncanonical@
+host_noncanonical=@host_noncanonical@
# Variables for the user (or the top level) to override.
exeext = @EXEEXT@
@@ -118,10 +118,10 @@ ifeq ($(build), $(host))
GNATBIND_FOR_HOST=gnatbind
GNATLS_FOR_HOST=gnatls
else
- GNATMAKE_FOR_HOST=$(host_alias)-gnatmake
- GNATLINK_FOR_HOST=$(host_alias)-gnatlink
- GNATBIND_FOR_HOST=$(host_alias)-gnatbind
- GNATLS_FOR_HOST=$(host_alias)-gnatls
+ GNATMAKE_FOR_HOST=$(host_noncanonical)-gnatmake
+ GNATLINK_FOR_HOST=$(host_noncanonical)-gnatlink
+ GNATBIND_FOR_HOST=$(host_noncanonical)-gnatbind
+ GNATLS_FOR_HOST=$(host_noncanonical)-gnatls
endif
# Put the host RTS dir first in the PATH to hide the default runtime
@@ -219,50 +219,6 @@ gnattools-cross: $(GCC_DIR)/stamp-tools
# gnattools2
$(MAKE) -C $(GCC_DIR)/ada/tools -f ../Makefile \
$(TOOLS_FLAGS_TO_PASS_CROSS) common-tools
- # Rename cross tools to where the GCC makefile wants them when
- # installing. FIXME: installation should be done elsewhere.
- if [ -f $(GCC_DIR)/gnatbind$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatbind$(exeext) $(GCC_DIR)/gnatbind-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatchop$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatchop$(exeext) $(GCC_DIR)/gnatchop-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnat$(exeext) ] ; then \
- mv $(GCC_DIR)/gnat$(exeext) $(GCC_DIR)/gnat-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatkr$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatkr$(exeext) $(GCC_DIR)/gnatkr-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatlink$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatlink$(exeext) $(GCC_DIR)/gnatlink-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatls$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatls$(exeext) $(GCC_DIR)/gnatls-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatmake$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatmake$(exeext) $(GCC_DIR)/gnatmake-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatmem$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatmem$(exeext) $(GCC_DIR)/gnatmem-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatname$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatname$(exeext) $(GCC_DIR)/gnatname-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatprep$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatprep$(exeext) $(GCC_DIR)/gnatprep-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatxref$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatxref$(exeext) $(GCC_DIR)/gnatxref-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatfind$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatfind$(exeext) $(GCC_DIR)/gnatfind-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatclean$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatclean$(exeext) $(GCC_DIR)/gnatclean-cross$(exeext); \
- fi
- if [ -f $(GCC_DIR)/gnatsym$(exeext) ] ; then \
- mv $(GCC_DIR)/gnatsym$(exeext) $(GCC_DIR)/gnatsym-cross$(exeext); \
- fi
# Other
# -----
diff --git a/gnattools/configure b/gnattools/configure
index 5243ebd70e4..8c75cc06eb5 100755
--- a/gnattools/configure
+++ b/gnattools/configure
@@ -567,6 +567,7 @@ TOOLS_TARGET_PAIRS
default_gnattools_target
LN_S
target_noncanonical
+host_noncanonical
target_os
target_vendor
target_cpu
@@ -1990,6 +1991,8 @@ esac
*) host_noncanonical=${host_alias} ;;
esac
+
+
case ${target_alias} in
"") target_noncanonical=${host_noncanonical} ;;
*) target_noncanonical=${target_alias} ;;
diff --git a/gnattools/configure.ac b/gnattools/configure.ac
index 9a7c42ac818..86d8926b6c0 100644
--- a/gnattools/configure.ac
+++ b/gnattools/configure.ac
@@ -46,6 +46,7 @@ AC_CANONICAL_BUILD
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
+ACX_NONCANONICAL_HOST
ACX_NONCANONICAL_TARGET
# Need to pass this down for now :-P
diff --git a/include/ChangeLog b/include/ChangeLog
index f82f7974aa8..180a73915f4 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -58,6 +58,13 @@
* libiberty.h (dupargv): Change arg to char * const *.
(writeargv, countargv): Likewise.
+2015-11-27 Pedro Alves <palves@redhat.com>
+
+ PR other/61321
+ PR other/61233
+ * demangle.h (enum demangle_component_type)
+ <DEMANGLE_COMPONENT_CONVERSION>: New value.
+
2015-11-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* vtv-change-permission.h (VTV_PAGE_SIZE) [__sun__ && __svr4__ &&
diff --git a/libatomic/config/rtems/host-config.h b/libatomic/config/rtems/host-config.h
new file mode 100644
index 00000000000..d11e9efb01f
--- /dev/null
+++ b/libatomic/config/rtems/host-config.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+ Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
+
+ This file is part of the GNU Atomic Library (libatomic).
+
+ Libatomic 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.
+
+ Libatomic 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/>. */
+
+/* Included after all more target-specific host-config.h. */
+
+#include <machine/_libatomic.h>
+
+static inline UWORD
+protect_start (void *ptr)
+{
+ return _Libatomic_Protect_start (ptr);
+}
+
+static inline void
+protect_end (void *ptr, UWORD isr_level)
+{
+ _Libatomic_Protect_end (ptr, isr_level);
+}
+
+#include_next <host-config.h>
diff --git a/libatomic/config/rtems/lock.c b/libatomic/config/rtems/lock.c
new file mode 100644
index 00000000000..f999f9b6837
--- /dev/null
+++ b/libatomic/config/rtems/lock.c
@@ -0,0 +1,37 @@
+/* Copyright (C) 2016 Free Software Foundation, Inc.
+ Contributed by Sebastian Huber <sebastian.huber@embedded-brains.de>.
+
+ This file is part of the GNU Atomic Library (libatomic).
+
+ Libatomic 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.
+
+ Libatomic 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/>. */
+
+#include "libatomic_i.h"
+
+void
+libat_lock_n (void *ptr, size_t n)
+{
+ _Libatomic_Lock_n (ptr, n);
+}
+
+void
+libat_unlock_n (void *ptr, size_t n)
+{
+ _Libatomic_Unlock_n (ptr, n);
+}
diff --git a/libbacktrace/ChangeLog b/libbacktrace/ChangeLog
index eba34274385..acc07047f67 100644
--- a/libbacktrace/ChangeLog
+++ b/libbacktrace/ChangeLog
@@ -1,3 +1,9 @@
+2016-05-18 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/71161
+ * elf.c (phdr_callback) [__i386__]: Add
+ __attribute__((__force_align_arg_pointer__)).
+
2016-03-02 Maxim Ostapenko <m.ostapenko@partner.samsung.com>
* elf.c (backtrace_initialize): Properly initialize elf_fileline_fn to
@@ -15,12 +21,13 @@
2015-12-18 Andris Pavenis <andris.pavenis@iki.fi>
- * configure.ac: Specify that DJGPP do not have mmap even when sys/mman.h exists
+ * configure.ac: Specify that DJGPP do not have mmap
+ even when sys/mman.h exists.
* configure: Regenerate
2015-12-09 John David Anglin <danglin@gcc.gnu.org>
- PR 68115/libfortran
+ PR libgfortran/68115
* configure.ac: Set libbacktrace_cv_sys_sync to no on hppa*-*-hpux*.
* configure: Regenerate.
* elf.c (backtrace_initialize): Cast __sync_bool_compare_and_swap call
diff --git a/libbacktrace/elf.c b/libbacktrace/elf.c
index f85ac65d99f..81ba3440ab7 100644
--- a/libbacktrace/elf.c
+++ b/libbacktrace/elf.c
@@ -866,6 +866,9 @@ struct phdr_data
libraries. */
static int
+#ifdef __i386__
+__attribute__ ((__force_align_arg_pointer__))
+#endif
phdr_callback (struct dl_phdr_info *info, size_t size ATTRIBUTE_UNUSED,
void *pdata)
{
diff --git a/libcilkrts/ChangeLog b/libcilkrts/ChangeLog
index 8fada8a82a6..a665fb10b1b 100644
--- a/libcilkrts/ChangeLog
+++ b/libcilkrts/ChangeLog
@@ -1,3 +1,136 @@
+2016-05-10 Matthias Klose <doko@ubuntu.com>
+
+ * configure.ac: Move AC_USE_SYSTEM_EXTENSIONS behind AM_ENABLE_MULTILIB.
+ * configure: Regenerate.
+
+2016-05-04 Ilya Verbin <ilya.verbin@intel.com>
+
+ * Makefile.am: Merge from upstream, version 2.0.4420.0
+ <https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git>.
+ * README: Likewise.
+ * configure.ac: Likewise.
+ * configure.tgt: Likewise.
+ * include/cilk/cilk.h: Likewise.
+ * include/cilk/cilk_api.h: Likewise.
+ * include/cilk/cilk_api_linux.h: Likewise.
+ * include/cilk/cilk_stub.h: Likewise.
+ * include/cilk/cilk_undocumented.h: Likewise.
+ * include/cilk/common.h: Likewise.
+ * include/cilk/holder.h: Likewise.
+ * include/cilk/hyperobject_base.h: Likewise.
+ * include/cilk/metaprogramming.h: Likewise.
+ * include/cilk/reducer.h: Likewise.
+ * include/cilk/reducer_file.h: Likewise.
+ * include/cilk/reducer_list.h: Likewise.
+ * include/cilk/reducer_max.h: Likewise.
+ * include/cilk/reducer_min.h: Likewise.
+ * include/cilk/reducer_min_max.h: Likewise.
+ * include/cilk/reducer_opadd.h: Likewise.
+ * include/cilk/reducer_opand.h: Likewise.
+ * include/cilk/reducer_opmul.h: Likewise.
+ * include/cilk/reducer_opor.h: Likewise.
+ * include/cilk/reducer_opxor.h: Likewise.
+ * include/cilk/reducer_ostream.h: Likewise.
+ * include/cilk/reducer_string.h: Likewise.
+ * include/cilktools/cilkscreen.h: Likewise.
+ * include/cilktools/cilkview.h: Likewise.
+ * include/cilktools/fake_mutex.h: Likewise.
+ * include/cilktools/lock_guard.h: Likewise.
+ * include/internal/abi.h: Likewise.
+ * include/internal/cilk_fake.h: Likewise.
+ * include/internal/cilk_version.h: Likewise.
+ * include/internal/metacall.h: Likewise.
+ * include/internal/rev.mk: Likewise.
+ * mk/cilk-version.mk: Likewise.
+ * runtime/acknowledgements.dox: Likewise.
+ * runtime/bug.cpp: Likewise.
+ * runtime/bug.h: Likewise.
+ * runtime/c_reducers.c: Likewise.
+ * runtime/cilk-abi-cilk-for.cpp: Likewise.
+ * runtime/cilk-abi-vla-internal.c: Likewise.
+ * runtime/cilk-abi-vla-internal.h: Likewise.
+ * runtime/cilk-abi.c: Likewise.
+ * runtime/cilk-ittnotify.h: Likewise.
+ * runtime/cilk-tbb-interop.h: Likewise.
+ * runtime/cilk_api.c: Likewise.
+ * runtime/cilk_fiber-unix.cpp: Likewise.
+ * runtime/cilk_fiber-unix.h: Likewise.
+ * runtime/cilk_fiber.cpp: Likewise.
+ * runtime/cilk_fiber.h: Likewise.
+ * runtime/cilk_malloc.c: Likewise.
+ * runtime/cilk_malloc.h: Likewise.
+ * runtime/component.h: Likewise.
+ * runtime/config/generic/cilk-abi-vla.c: Likewise.
+ * runtime/config/generic/os-fence.h: Likewise.
+ * runtime/config/generic/os-unix-sysdep.c: Likewise.
+ * runtime/config/x86/cilk-abi-vla.c: Likewise.
+ * runtime/config/x86/os-fence.h: Likewise.
+ * runtime/config/x86/os-unix-sysdep.c: Likewise.
+ * runtime/doxygen-layout.xml: Likewise.
+ * runtime/doxygen.cfg: Likewise.
+ * runtime/except-gcc.cpp: Likewise.
+ * runtime/except-gcc.h: Likewise.
+ * runtime/except.h: Likewise.
+ * runtime/frame_malloc.c: Likewise.
+ * runtime/frame_malloc.h: Likewise.
+ * runtime/full_frame.c: Likewise.
+ * runtime/full_frame.h: Likewise.
+ * runtime/global_state.cpp: Likewise.
+ * runtime/global_state.h: Likewise.
+ * runtime/jmpbuf.c: Likewise.
+ * runtime/jmpbuf.h: Likewise.
+ * runtime/linux-symbols.ver: Likewise.
+ * runtime/local_state.c: Likewise.
+ * runtime/local_state.h: Likewise.
+ * runtime/mac-symbols.txt: Likewise.
+ * runtime/metacall_impl.c: Likewise.
+ * runtime/metacall_impl.h: Likewise.
+ * runtime/os-unix.c: Likewise.
+ * runtime/os.h: Likewise.
+ * runtime/os_mutex-unix.c: Likewise.
+ * runtime/os_mutex.h: Likewise.
+ * runtime/pedigrees.c: Likewise.
+ * runtime/pedigrees.h: Likewise.
+ * runtime/record-replay.cpp: Likewise.
+ * runtime/record-replay.h: Likewise.
+ * runtime/reducer_impl.cpp: Likewise.
+ * runtime/reducer_impl.h: Likewise.
+ * runtime/rts-common.h: Likewise.
+ * runtime/scheduler.c: Likewise.
+ * runtime/scheduler.h: Likewise.
+ * runtime/signal_node.c: Likewise.
+ * runtime/signal_node.h: Likewise.
+ * runtime/spin_mutex.c: Likewise.
+ * runtime/spin_mutex.h: Likewise.
+ * runtime/stats.c: Likewise.
+ * runtime/stats.h: Likewise.
+ * runtime/sysdep-unix.c: Likewise.
+ * runtime/sysdep.h: Likewise.
+ * runtime/worker_mutex.c: Likewise.
+ * runtime/worker_mutex.h: Likewise.
+ * include/cilk/reducer_vector.h: New.
+ * runtime/cilk_str_mem.h: New.
+ * runtime/config/arm/cilk-abi-vla.c: New.
+ * runtime/config/arm/os-fence.h: New.
+ * runtime/config/arm/os-unix-sysdep.c: New.
+ * runtime/declare-alloca.h: New.
+ * runtime/sslib/ignore_handler_s.c: New.
+ * runtime/sslib/safe_lib.h: New.
+ * runtime/sslib/safe_lib_errno.h: New.
+ * runtime/sslib/safe_str_constraint.c: New.
+ * runtime/sslib/safe_str_constraint.h: New.
+ * runtime/sslib/safe_str_lib.h: New.
+ * runtime/sslib/safe_types.h: New.
+ * runtime/sslib/safeclib_private.h: New.
+ * runtime/sslib/snprintf_s.h: New.
+ * runtime/sslib/snprintf_support.c: New.
+ * runtime/sslib/strcpy_s.c: New.
+ * runtime/sslib/strncpy_s.c: New.
+ * runtime/sslib/strnlen_s.c: New.
+ * runtime/symbol_test.c: Remove.
+ * Makefile.in: Regenerate.
+ * configure: Regenerate.
+
2016-04-26 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR target/60290
diff --git a/libcilkrts/Makefile.am b/libcilkrts/Makefile.am
index 4f944dd1a62..3736a636fb1 100644
--- a/libcilkrts/Makefile.am
+++ b/libcilkrts/Makefile.am
@@ -1,8 +1,6 @@
-# @copyright
-# Copyright (C) 2011, 2013, Intel Corporation
+# Copyright (C) 2011-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -17,7 +15,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -30,6 +27,20 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
AUTOMAKE_OPTIONS = foreign
@@ -37,7 +48,7 @@ AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I .. -I ../config
# Compiler and linker flags.
-GENERAL_FLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/runtime -I$(top_srcdir)/runtime/config/$(config_dir) -DIN_CILK_RUNTIME=1
+GENERAL_FLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/runtime -I$(top_srcdir)/runtime/config/$(config_dir) -I$(top_srcdir)/runtime/sslib -DIN_CILK_RUNTIME=1
# GENERAL_FLAGS += -D_Cilk_spawn="" -D_Cilk_sync="" -D_Cilk_for=for
# Enable Intel Cilk Plus extension
@@ -60,6 +71,19 @@ toolexeclib_LTLIBRARIES = libcilkrts.la
libcilkrts_la_SOURCES = \
runtime/config/$(config_dir)/cilk-abi-vla.c \
runtime/config/$(config_dir)/os-unix-sysdep.c \
+ runtime/sslib/ignore_handler_s.c \
+ runtime/sslib/safe_lib.h \
+ runtime/sslib/safe_lib_errno.h \
+ runtime/sslib/safe_str_constraint.c \
+ runtime/sslib/safe_str_constraint.h \
+ runtime/sslib/safe_str_lib.h \
+ runtime/sslib/safe_types.h \
+ runtime/sslib/safeclib_private.h \
+ runtime/sslib/snprintf_s.h \
+ runtime/sslib/snprintf_support.c \
+ runtime/sslib/strcpy_s.c \
+ runtime/sslib/strncpy_s.c \
+ runtime/sslib/strnlen_s.c \
runtime/bug.cpp \
runtime/cilk-abi.c \
runtime/cilk-abi-cilk-for.cpp \
@@ -85,7 +109,6 @@ libcilkrts_la_SOURCES = \
runtime/signal_node.c \
runtime/spin_mutex.c \
runtime/stats.c \
- runtime/symbol_test.c \
runtime/sysdep-unix.c \
runtime/worker_mutex.c
diff --git a/libcilkrts/Makefile.in b/libcilkrts/Makefile.in
index a25d1c6f50e..ff88e9dab89 100644
--- a/libcilkrts/Makefile.in
+++ b/libcilkrts/Makefile.in
@@ -15,11 +15,9 @@
@SET_MAKE@
-# @copyright
-# Copyright (C) 2011, 2013, Intel Corporation
+# Copyright (C) 2011-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -34,7 +32,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -47,14 +44,26 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
#########################################################################
#
-# @copyright
-# Copyright (C) 2011-2013, Intel Corporation
+# Copyright (C) 2011-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -69,7 +78,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -82,6 +90,20 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
###########################################################################
# DO NOT EDIT THIS FILE!
@@ -184,14 +206,16 @@ am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \
"$(DESTDIR)$(cilkincludedir)" "$(DESTDIR)$(toolexeclibdir)"
LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
libcilkrts_la_LIBADD =
-am_libcilkrts_la_OBJECTS = cilk-abi-vla.lo os-unix-sysdep.lo bug.lo \
- cilk-abi.lo cilk-abi-cilk-for.lo cilk-abi-vla-internal.lo \
- cilk_api.lo cilk_fiber.lo cilk_fiber-unix.lo cilk_malloc.lo \
- c_reducers.lo except-gcc.lo frame_malloc.lo full_frame.lo \
- global_state.lo jmpbuf.lo local_state.lo metacall_impl.lo \
- os_mutex-unix.lo os-unix.lo pedigrees.lo record-replay.lo \
- reducer_impl.lo scheduler.lo signal_node.lo spin_mutex.lo \
- stats.lo symbol_test.lo sysdep-unix.lo worker_mutex.lo
+am_libcilkrts_la_OBJECTS = cilk-abi-vla.lo os-unix-sysdep.lo \
+ ignore_handler_s.lo safe_str_constraint.lo snprintf_support.lo \
+ strcpy_s.lo strncpy_s.lo strnlen_s.lo bug.lo cilk-abi.lo \
+ cilk-abi-cilk-for.lo cilk-abi-vla-internal.lo cilk_api.lo \
+ cilk_fiber.lo cilk_fiber-unix.lo cilk_malloc.lo c_reducers.lo \
+ except-gcc.lo frame_malloc.lo full_frame.lo global_state.lo \
+ jmpbuf.lo local_state.lo metacall_impl.lo os_mutex-unix.lo \
+ os-unix.lo pedigrees.lo record-replay.lo reducer_impl.lo \
+ scheduler.lo signal_node.lo spin_mutex.lo stats.lo \
+ sysdep-unix.lo worker_mutex.lo
libcilkrts_la_OBJECTS = $(am_libcilkrts_la_OBJECTS)
libcilkrts_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
@@ -375,7 +399,8 @@ ACLOCAL_AMFLAGS = -I .. -I ../config
# Always generate unwind tables
GENERAL_FLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/runtime \
-I$(top_srcdir)/runtime/config/$(config_dir) \
- -DIN_CILK_RUNTIME=1 -fcilkplus -funwind-tables
+ -I$(top_srcdir)/runtime/sslib -DIN_CILK_RUNTIME=1 -fcilkplus \
+ -funwind-tables
AM_CFLAGS = $(XCFLAGS) $(GENERAL_FLAGS) -std=c99
AM_CPPFLAGS = $(GENERAL_FLAGS)
AM_LDFLAGS = $(XLDFLAGS)
@@ -389,6 +414,19 @@ toolexeclib_LTLIBRARIES = libcilkrts.la
libcilkrts_la_SOURCES = \
runtime/config/$(config_dir)/cilk-abi-vla.c \
runtime/config/$(config_dir)/os-unix-sysdep.c \
+ runtime/sslib/ignore_handler_s.c \
+ runtime/sslib/safe_lib.h \
+ runtime/sslib/safe_lib_errno.h \
+ runtime/sslib/safe_str_constraint.c \
+ runtime/sslib/safe_str_constraint.h \
+ runtime/sslib/safe_str_lib.h \
+ runtime/sslib/safe_types.h \
+ runtime/sslib/safeclib_private.h \
+ runtime/sslib/snprintf_s.h \
+ runtime/sslib/snprintf_support.c \
+ runtime/sslib/strcpy_s.c \
+ runtime/sslib/strncpy_s.c \
+ runtime/sslib/strnlen_s.c \
runtime/bug.cpp \
runtime/cilk-abi.c \
runtime/cilk-abi-cilk-for.cpp \
@@ -414,11 +452,10 @@ libcilkrts_la_SOURCES = \
runtime/signal_node.c \
runtime/spin_mutex.c \
runtime/stats.c \
- runtime/symbol_test.c \
runtime/sysdep-unix.c \
runtime/worker_mutex.c
-CILK_REVISION = 3902
+CILK_REVISION = 4420
# Load the $(REVISION) value.
@@ -591,6 +628,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/frame_malloc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/full_frame.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/global_state.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ignore_handler_s.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jmpbuf.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/local_state.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/metacall_impl.Plo@am__quote@
@@ -600,11 +638,15 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pedigrees.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/record-replay.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/reducer_impl.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/safe_str_constraint.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scheduler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/signal_node.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snprintf_support.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/spin_mutex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stats.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/symbol_test.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strcpy_s.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strncpy_s.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strnlen_s.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sysdep-unix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/worker_mutex.Plo@am__quote@
@@ -643,6 +685,48 @@ os-unix-sysdep.lo: runtime/config/$(config_dir)/os-unix-sysdep.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o os-unix-sysdep.lo `test -f 'runtime/config/$(config_dir)/os-unix-sysdep.c' || echo '$(srcdir)/'`runtime/config/$(config_dir)/os-unix-sysdep.c
+ignore_handler_s.lo: runtime/sslib/ignore_handler_s.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ignore_handler_s.lo -MD -MP -MF $(DEPDIR)/ignore_handler_s.Tpo -c -o ignore_handler_s.lo `test -f 'runtime/sslib/ignore_handler_s.c' || echo '$(srcdir)/'`runtime/sslib/ignore_handler_s.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ignore_handler_s.Tpo $(DEPDIR)/ignore_handler_s.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/sslib/ignore_handler_s.c' object='ignore_handler_s.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ignore_handler_s.lo `test -f 'runtime/sslib/ignore_handler_s.c' || echo '$(srcdir)/'`runtime/sslib/ignore_handler_s.c
+
+safe_str_constraint.lo: runtime/sslib/safe_str_constraint.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT safe_str_constraint.lo -MD -MP -MF $(DEPDIR)/safe_str_constraint.Tpo -c -o safe_str_constraint.lo `test -f 'runtime/sslib/safe_str_constraint.c' || echo '$(srcdir)/'`runtime/sslib/safe_str_constraint.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/safe_str_constraint.Tpo $(DEPDIR)/safe_str_constraint.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/sslib/safe_str_constraint.c' object='safe_str_constraint.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o safe_str_constraint.lo `test -f 'runtime/sslib/safe_str_constraint.c' || echo '$(srcdir)/'`runtime/sslib/safe_str_constraint.c
+
+snprintf_support.lo: runtime/sslib/snprintf_support.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT snprintf_support.lo -MD -MP -MF $(DEPDIR)/snprintf_support.Tpo -c -o snprintf_support.lo `test -f 'runtime/sslib/snprintf_support.c' || echo '$(srcdir)/'`runtime/sslib/snprintf_support.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/snprintf_support.Tpo $(DEPDIR)/snprintf_support.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/sslib/snprintf_support.c' object='snprintf_support.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o snprintf_support.lo `test -f 'runtime/sslib/snprintf_support.c' || echo '$(srcdir)/'`runtime/sslib/snprintf_support.c
+
+strcpy_s.lo: runtime/sslib/strcpy_s.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT strcpy_s.lo -MD -MP -MF $(DEPDIR)/strcpy_s.Tpo -c -o strcpy_s.lo `test -f 'runtime/sslib/strcpy_s.c' || echo '$(srcdir)/'`runtime/sslib/strcpy_s.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/strcpy_s.Tpo $(DEPDIR)/strcpy_s.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/sslib/strcpy_s.c' object='strcpy_s.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o strcpy_s.lo `test -f 'runtime/sslib/strcpy_s.c' || echo '$(srcdir)/'`runtime/sslib/strcpy_s.c
+
+strncpy_s.lo: runtime/sslib/strncpy_s.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT strncpy_s.lo -MD -MP -MF $(DEPDIR)/strncpy_s.Tpo -c -o strncpy_s.lo `test -f 'runtime/sslib/strncpy_s.c' || echo '$(srcdir)/'`runtime/sslib/strncpy_s.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/strncpy_s.Tpo $(DEPDIR)/strncpy_s.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/sslib/strncpy_s.c' object='strncpy_s.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o strncpy_s.lo `test -f 'runtime/sslib/strncpy_s.c' || echo '$(srcdir)/'`runtime/sslib/strncpy_s.c
+
+strnlen_s.lo: runtime/sslib/strnlen_s.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT strnlen_s.lo -MD -MP -MF $(DEPDIR)/strnlen_s.Tpo -c -o strnlen_s.lo `test -f 'runtime/sslib/strnlen_s.c' || echo '$(srcdir)/'`runtime/sslib/strnlen_s.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/strnlen_s.Tpo $(DEPDIR)/strnlen_s.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/sslib/strnlen_s.c' object='strnlen_s.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o strnlen_s.lo `test -f 'runtime/sslib/strnlen_s.c' || echo '$(srcdir)/'`runtime/sslib/strnlen_s.c
+
cilk-abi.lo: runtime/cilk-abi.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT cilk-abi.lo -MD -MP -MF $(DEPDIR)/cilk-abi.Tpo -c -o cilk-abi.lo `test -f 'runtime/cilk-abi.c' || echo '$(srcdir)/'`runtime/cilk-abi.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/cilk-abi.Tpo $(DEPDIR)/cilk-abi.Plo
@@ -762,13 +846,6 @@ stats.lo: runtime/stats.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o stats.lo `test -f 'runtime/stats.c' || echo '$(srcdir)/'`runtime/stats.c
-symbol_test.lo: runtime/symbol_test.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT symbol_test.lo -MD -MP -MF $(DEPDIR)/symbol_test.Tpo -c -o symbol_test.lo `test -f 'runtime/symbol_test.c' || echo '$(srcdir)/'`runtime/symbol_test.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/symbol_test.Tpo $(DEPDIR)/symbol_test.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='runtime/symbol_test.c' object='symbol_test.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o symbol_test.lo `test -f 'runtime/symbol_test.c' || echo '$(srcdir)/'`runtime/symbol_test.c
-
sysdep-unix.lo: runtime/sysdep-unix.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT sysdep-unix.lo -MD -MP -MF $(DEPDIR)/sysdep-unix.Tpo -c -o sysdep-unix.lo `test -f 'runtime/sysdep-unix.c' || echo '$(srcdir)/'`runtime/sysdep-unix.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/sysdep-unix.Tpo $(DEPDIR)/sysdep-unix.Plo
diff --git a/libcilkrts/README b/libcilkrts/README
index 7c101150ece..d3503f44e34 100644
--- a/libcilkrts/README
+++ b/libcilkrts/README
@@ -40,6 +40,9 @@ configure script:
% ./configure --prefix=/your/path/to/lib
+It is also possible to use CMake if the above method does not apply
+well in your environment. Instruction is available in CMakeLists.txt.
+
#
# 2. USING:
#
@@ -79,6 +82,9 @@ http://cilkplus.org/
Changes to the Intel Cilk Plus runtime are welcome and should be
contributed to the upstream version via http://cilkplus.org/.
+Thanks to Tobias Burnus for showing us the magic to make gcc and g++
+automatically include the Cilk Plus runtime.
+
------------------------
Intel and Cilk are trademarks of Intel Corporation in the U.S. and/or
other countries.
diff --git a/libcilkrts/configure b/libcilkrts/configure
index 4e1d459f812..2380bc6c0c1 100644
--- a/libcilkrts/configure
+++ b/libcilkrts/configure
@@ -632,9 +632,6 @@ MAC_LINKER_SCRIPT_TRUE
LINUX_LINKER_SCRIPT_FALSE
LINUX_LINKER_SCRIPT_TRUE
config_dir
-EGREP
-GREP
-CPP
ALLOCA
am__fastdepCXX_FALSE
am__fastdepCXX_TRUE
@@ -642,6 +639,9 @@ CXXDEPMODE
ac_ct_CXX
CXXFLAGS
CXX
+EGREP
+GREP
+CPP
am__fastdepCC_FALSE
am__fastdepCC_TRUE
CCDEPMODE
@@ -758,10 +758,10 @@ CFLAGS
LDFLAGS
LIBS
CPPFLAGS
+CPP
CXX
CXXFLAGS
CCC
-CPP
CXXCPP'
@@ -1413,9 +1413,9 @@ Some influential environment variables:
LIBS libraries to pass to the linker, e.g. -l<library>
CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
you have headers in a nonstandard directory <include dir>
+ CPP C preprocessor
CXX C++ compiler command
CXXFLAGS C++ compiler flags
- CPP C preprocessor
CXXCPP C++ preprocessor
Use these variables to override the choices made by `configure' or to help
@@ -1536,6 +1536,209 @@ fi
} # ac_fn_c_try_compile
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } >/dev/null && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+( cat <<\_ASBOX
+## ----------------------------- ##
+## Report this to cilk@intel.com ##
+## ----------------------------- ##
+_ASBOX
+ ) | sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+ return $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_compile
+
# ac_fn_cxx_try_compile LINENO
# ----------------------------
# Try to compile conftest.$ac_ext, and return whether this succeeded.
@@ -1620,43 +1823,6 @@ fi
} # ac_fn_c_try_link
-# ac_fn_c_try_cpp LINENO
-# ----------------------
-# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
-ac_fn_c_try_cpp ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_cpp conftest.$ac_ext"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
- ac_status=$?
- if test -s conftest.err; then
- grep -v '^ *+' conftest.err >conftest.er1
- cat conftest.er1 >&5
- mv -f conftest.er1 conftest.err
- fi
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } >/dev/null && {
- test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
- test ! -s conftest.err
- }; then :
- ac_retval=0
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=1
-fi
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_cpp
-
# ac_fn_c_check_func LINENO FUNC VAR
# ----------------------------------
# Tests whether FUNC exists, setting the cache variable VAR accordingly
@@ -1724,79 +1890,6 @@ $as_echo "$ac_res" >&6; }
} # ac_fn_c_check_func
-# ac_fn_c_try_run LINENO
-# ----------------------
-# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
-# that executables *can* be run.
-ac_fn_c_try_run ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- if { { ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_link") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
- { { case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
- (eval "$ac_try") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; }; then :
- ac_retval=0
-else
- $as_echo "$as_me: program exited with status $ac_status" >&5
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_retval=$ac_status
-fi
- rm -rf conftest.dSYM conftest_ipa8_conftest.oo
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
- return $ac_retval
-
-} # ac_fn_c_try_run
-
-# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
-# -------------------------------------------------------
-# Tests whether HEADER exists and can be compiled using the include files in
-# INCLUDES, setting the cache variable VAR accordingly.
-ac_fn_c_check_header_compile ()
-{
- as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
-$as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-$4
-#include <$2>
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- eval "$3=yes"
-else
- eval "$3=no"
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-eval ac_res=\$$3
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
- eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-
-} # ac_fn_c_check_header_compile
-
# ac_fn_cxx_try_cpp LINENO
# ------------------------
# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
@@ -2373,6 +2466,7 @@ test -n "$target_alias" &&
target_alias=${target_alias-$host_alias}
+
am__api_version='1.11'
# Find a good install program. We prefer a C program (faster),
@@ -2914,8 +3008,70 @@ fi
ac_config_commands="$ac_config_commands default-1"
-# Build a DLL on Windows
-# AC_LIBTOOL_WIN32_DLL
+# Test for GNU extensions. Will define _GNU_SOURCE if they're available
+DEPDIR="${am__leading_dot}deps"
+
+ac_config_commands="$ac_config_commands depfiles"
+
+
+am_make=${MAKE-make}
+cat > confinc << 'END'
+am__doit:
+ @echo this is the am__doit target
+.PHONY: am__doit
+END
+# If we don't find an include directive, just comment out the code.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
+$as_echo_n "checking for style of include used by $am_make... " >&6; }
+am__include="#"
+am__quote=
+_am_result=none
+# First try GNU make style include.
+echo "include confinc" > confmf
+# Ignore all kinds of additional output from `make'.
+case `$am_make -s -f confmf 2> /dev/null` in #(
+*the\ am__doit\ target*)
+ am__include=include
+ am__quote=
+ _am_result=GNU
+ ;;
+esac
+# Now try BSD make style include.
+if test "$am__include" = "#"; then
+ echo '.include "confinc"' > confmf
+ case `$am_make -s -f confmf 2> /dev/null` in #(
+ *the\ am__doit\ target*)
+ am__include=.include
+ am__quote="\""
+ _am_result=BSD
+ ;;
+ esac
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
+$as_echo "$_am_result" >&6; }
+rm -f confinc confmf
+
+# Check whether --enable-dependency-tracking was given.
+if test "${enable_dependency_tracking+set}" = set; then :
+ enableval=$enable_dependency_tracking;
+fi
+
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+ am__nodep='_no'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -3680,69 +3836,1137 @@ ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-DEPDIR="${am__leading_dot}deps"
-ac_config_commands="$ac_config_commands depfiles"
+depcc="$CC" am_compiler_list=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
+$as_echo_n "checking dependency style of $depcc... " >&6; }
+if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
+ # We make a subdir and do the tests there. Otherwise we can end up
+ # making bogus files that we don't know about and never remove. For
+ # instance it was reported that on HP-UX the gcc test will end up
+ # making a dummy file named `D' -- because `-MD' means `put the output
+ # in D'.
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ # Copy depcomp to subdir because otherwise we won't find it if we're
+ # using a relative directory.
+ cp "$am_depcomp" conftest.dir
+ cd conftest.dir
+ # We will build objects and dependencies in a subdirectory because
+ # it helps to detect inapplicable dependency modes. For instance
+ # both Tru64's cc and ICC support -MD to output dependencies as a
+ # side effect of compilation, but ICC will put the dependencies in
+ # the current directory while Tru64 will put them in the object
+ # directory.
+ mkdir sub
+ am_cv_CC_dependencies_compiler_type=none
+ if test "$am_compiler_list" = ""; then
+ am_compiler_list=`sed -n 's/^#*\([a-zA-Z0-9]*\))$/\1/p' < ./depcomp`
+ fi
+ am__universal=false
+ case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac
-am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5
-$as_echo_n "checking for style of include used by $am_make... " >&6; }
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
+ for depmode in $am_compiler_list; do
+ # Setup a source with many dependencies, because some compilers
+ # like to wrap large dependency lists on column 80 (with \), and
+ # we should not choose a depcomp mode which is confused by this.
+ #
+ # We need to recreate these files for each test, as the compiler may
+ # overwrite some of them when testing with obscure command lines.
+ # This happens at least with the AIX C compiler.
+ : > sub/conftest.c
+ for i in 1 2 3 4 5 6; do
+ echo '#include "conftst'$i'.h"' >> sub/conftest.c
+ # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
+ # Solaris 8's {/usr,}/bin/sh.
+ touch sub/conftst$i.h
+ done
+ echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
+
+ # We check with `-c' and `-o' for the sake of the "dashmstdout"
+ # mode. It turns out that the SunPro C++ compiler does not properly
+ # handle `-M -o', and we need to detect this. Also, some Intel
+ # versions had trouble with output in subdirs
+ am__obj=sub/conftest.${OBJEXT-o}
+ am__minus_obj="-o $am__obj"
+ case $depmode in
+ gcc)
+ # This depmode causes a compiler race in universal mode.
+ test "$am__universal" = false || continue
+ ;;
+ nosideeffect)
+ # after this tag, mechanisms are not by side-effect, so they'll
+ # only be used when explicitly requested
+ if test "x$enable_dependency_tracking" = xyes; then
+ continue
+ else
+ break
+ fi
+ ;;
+ msvc7 | msvc7msys | msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5
-$as_echo "$_am_result" >&6; }
-rm -f confinc confmf
-# Check whether --enable-dependency-tracking was given.
-if test "${enable_dependency_tracking+set}" = set; then :
- enableval=$enable_dependency_tracking;
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if test "${ac_cv_path_EGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
fi
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
- am__nodep='_no'
+ fi
fi
- if test "x$enable_dependency_tracking" != xno; then
- AMDEP_TRUE=
- AMDEP_FALSE='#'
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if test "${ac_cv_header_stdc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
else
- AMDEP_TRUE='#'
- AMDEP_FALSE=
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_header_stdc=yes
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then :
+ :
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ctype.h>
+#include <stdlib.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ return 2;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+
+else
+ ac_cv_header_stdc=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
+if test $ac_cv_header_stdc = yes; then
+
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+eval as_val=\$$as_ac_Header
+ if test "x$as_val" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+
+ ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
+if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+ MINIX=yes
+else
+ MINIX=
+fi
+
+
+ if test "$MINIX" = yes; then
+
+$as_echo "#define _POSIX_SOURCE 1" >>confdefs.h
+
+
+$as_echo "#define _POSIX_1_SOURCE 2" >>confdefs.h
+
+
+$as_echo "#define _MINIX 1" >>confdefs.h
+
+ fi
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
+$as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
+if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+# define __EXTENSIONS__ 1
+ $ac_includes_default
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_safe_to_define___extensions__=yes
+else
+ ac_cv_safe_to_define___extensions__=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_safe_to_define___extensions__" >&5
+$as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
+ test $ac_cv_safe_to_define___extensions__ = yes &&
+ $as_echo "#define __EXTENSIONS__ 1" >>confdefs.h
+
+ $as_echo "#define _ALL_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _GNU_SOURCE 1" >>confdefs.h
+
+ $as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
+
+ $as_echo "#define _TANDEM_SOURCE 1" >>confdefs.h
+
+
+
+# Build a DLL on Windows
+# AC_LIBTOOL_WIN32_DLL
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
depcc="$CC" am_compiler_list=
@@ -4261,405 +5485,6 @@ fi
# AC_CONFIG_MACRO_DIR([..])
ac_config_files="$ac_config_files Makefile libcilkrts.spec"
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
-$as_echo_n "checking how to run the C preprocessor... " >&6; }
-# On Suns, sometimes $CPP names a directory.
-if test -n "$CPP" && test -d "$CPP"; then
- CPP=
-fi
-if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- # Double quotes because CPP needs to be expanded
- for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
- do
- ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
- break
-fi
-
- done
- ac_cv_prog_CPP=$CPP
-
-fi
- CPP=$ac_cv_prog_CPP
-else
- ac_cv_prog_CPP=$CPP
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
-$as_echo "$CPP" >&6; }
-ac_preproc_ok=false
-for ac_c_preproc_warn_flag in '' yes
-do
- # Use a header file that comes with gcc, so configuring glibc
- # with a fresh cross-compiler works.
- # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- # <limits.h> exists even on freestanding compilers.
- # On the NeXT, cc -E runs the code through the compiler's parser,
- # not just through cpp. "Syntax error" is here to catch this case.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
- Syntax error
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
-
-else
- # Broken: fails on valid input.
-continue
-fi
-rm -f conftest.err conftest.$ac_ext
-
- # OK, works on sane cases. Now check whether nonexistent headers
- # can be detected and how.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ac_nonexistent.h>
-_ACEOF
-if ac_fn_c_try_cpp "$LINENO"; then :
- # Broken: success on invalid input.
-continue
-else
- # Passes both tests.
-ac_preproc_ok=:
-break
-fi
-rm -f conftest.err conftest.$ac_ext
-
-done
-# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then :
-
-else
- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
-$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if test -z "$GREP"; then
- ac_path_GREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in grep ggrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
-# Check for GNU ac_path_GREP and select it if it is found.
- # Check for GNU $ac_path_GREP
-case `"$ac_path_GREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'GREP' >> "conftest.nl"
- "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_GREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_GREP="$ac_path_GREP"
- ac_path_GREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_GREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_GREP"; then
- as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_GREP=$GREP
-fi
-
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
-$as_echo "$ac_cv_path_GREP" >&6; }
- GREP="$ac_cv_path_GREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
-$as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
- then ac_cv_path_EGREP="$GREP -E"
- else
- if test -z "$EGREP"; then
- ac_path_EGREP_found=false
- # Loop through the user's path and test for each of PROGNAME-LIST
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_prog in egrep; do
- for ac_exec_ext in '' $ac_executable_extensions; do
- ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
-# Check for GNU ac_path_EGREP and select it if it is found.
- # Check for GNU $ac_path_EGREP
-case `"$ac_path_EGREP" --version 2>&1` in
-*GNU*)
- ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
-*)
- ac_count=0
- $as_echo_n 0123456789 >"conftest.in"
- while :
- do
- cat "conftest.in" "conftest.in" >"conftest.tmp"
- mv "conftest.tmp" "conftest.in"
- cp "conftest.in" "conftest.nl"
- $as_echo 'EGREP' >> "conftest.nl"
- "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
- diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
- as_fn_arith $ac_count + 1 && ac_count=$as_val
- if test $ac_count -gt ${ac_path_EGREP_max-0}; then
- # Best one so far, save it but keep looking for a better one
- ac_cv_path_EGREP="$ac_path_EGREP"
- ac_path_EGREP_max=$ac_count
- fi
- # 10*(2^10) chars as input seems more than enough
- test $ac_count -gt 10 && break
- done
- rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
-esac
-
- $ac_path_EGREP_found && break 3
- done
- done
- done
-IFS=$as_save_IFS
- if test -z "$ac_cv_path_EGREP"; then
- as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
- fi
-else
- ac_cv_path_EGREP=$EGREP
-fi
-
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
-$as_echo "$ac_cv_path_EGREP" >&6; }
- EGREP="$ac_cv_path_EGREP"
-
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
-$as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_compile "$LINENO"; then :
- ac_cv_header_stdc=yes
-else
- ac_cv_header_stdc=no
-fi
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then :
- :
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-#include <ctype.h>
-#include <stdlib.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- return 2;
- return 0;
-}
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-
-else
- ac_cv_header_stdc=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
- conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
-$as_echo "$ac_cv_header_stdc" >&6; }
-if test $ac_cv_header_stdc = yes; then
-
-$as_echo "#define STDC_HEADERS 1" >>confdefs.h
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do :
- as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
-ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
-"
-eval as_val=\$$as_ac_Header
- if test "x$as_val" = x""yes; then :
- cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
# The Ultrix 4.2 mips builtin alloca declared by alloca.h only works
# for constant arguments. Useless!
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working alloca.h" >&5
@@ -4949,6 +5774,10 @@ case "${target}" in
config_dir="x86"
;;
+ arm-*-*)
+ config_dir="arm"
+ ;;
+
*)
config_dir="generic"
;;
@@ -9036,7 +9865,7 @@ _LT_EOF
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
- export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
aix_use_runtimelinking=no
@@ -11064,7 +11893,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11067 "configure"
+#line 11896 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11170,7 +11999,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11173 "configure"
+#line 12002 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13522,7 +14351,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
export_symbols_cmds_CXX='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
else
- export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+ export_symbols_cmds_CXX='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
fi
;;
pw32*)
@@ -14476,8 +15305,7 @@ rm -f core conftest.err conftest.$ac_objext \
# Check for pthread_{,attr_}[sg]etaffinity_np.
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-#define _GNU_SOURCE
- #include <pthread.h>
+#include <pthread.h>
int
main ()
{
@@ -14685,6 +15513,10 @@ if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
as_fn_error "conditional \"am__fastdepCC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
+ as_fn_error "conditional \"am__fastdepCC\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
as_fn_error "conditional \"am__fastdepCXX\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/libcilkrts/configure.ac b/libcilkrts/configure.ac
index 8ad647ea8e7..39efeb4f532 100644
--- a/libcilkrts/configure.ac
+++ b/libcilkrts/configure.ac
@@ -1,8 +1,6 @@
-# @copyright
-# Copyright (C) 2011-2013, Intel Corporation
+# Copyright (C) 2011-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -17,7 +15,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -30,6 +27,20 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
AC_INIT([Cilk Runtime Library], [2.0], [cilk@intel.com])
AC_PREREQ([2.64])
@@ -39,12 +50,16 @@ AC_PREREQ([2.64])
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
AC_SUBST(target_alias)
+
AM_INIT_AUTOMAKE(foreign no-dist)
AM_MAINTAINER_MODE
AM_ENABLE_MULTILIB(, ..)
+# Test for GNU extensions. Will define _GNU_SOURCE if they're available
+AC_USE_SYSTEM_EXTENSIONS
+
# Build a DLL on Windows
# AC_LIBTOOL_WIN32_DLL
AC_PROG_CC
@@ -134,6 +149,10 @@ case "${target}" in
config_dir="x86"
;;
+ arm-*-*)
+ config_dir="arm"
+ ;;
+
*)
config_dir="generic"
;;
@@ -189,8 +208,7 @@ AC_LINK_IFELSE(
# Check for pthread_{,attr_}[sg]etaffinity_np.
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(
- [#define _GNU_SOURCE
- #include <pthread.h>],
+ [#include <pthread.h>],
[cpu_set_t cpuset;
pthread_attr_t attr;
pthread_getaffinity_np (pthread_self (), sizeof (cpu_set_t), &cpuset);
diff --git a/libcilkrts/configure.tgt b/libcilkrts/configure.tgt
index fcda70fb68f..7f0befc870c 100644
--- a/libcilkrts/configure.tgt
+++ b/libcilkrts/configure.tgt
@@ -1,8 +1,6 @@
-# @copyright
-# Copyright (C) 2011-2013, Intel Corporation
+# Copyright (C) 2013-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -17,7 +15,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -30,13 +27,29 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
-# Disable Cilk Runtime library for non x86 architecture...for now.
+# Disable Cilk Runtime library for unsupported architectures.
case "${target}" in
x86_64-*-*)
;;
i?86-*-*)
;;
+ arm-*-*)
+ ;;
*-*-*)
UNSUPPORTED=1
;;
diff --git a/libcilkrts/include/cilk/cilk.h b/libcilkrts/include/cilk/cilk.h
index 2d0de0d293e..86038ac1adc 100644
--- a/libcilkrts/include/cilk/cilk.h
+++ b/libcilkrts/include/cilk/cilk.h
@@ -1,10 +1,8 @@
/* cilk.h -*-C++-*-
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,40 +29,54 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file cilk.h
*
- * @brief Provides convenient aliases for the Cilk language keywords.
+ * @brief Provides convenient aliases for Intel(R) Cilk(TM) language keywords.
*
* @details
- * Since Cilk is a nonstandard extension to both C and C++, the Cilk
- * language keywords all begin with “`_Cilk_`”, which guarantees that they
+ * Since Intel Cilk Plus is a nonstandard extension to both C and C++, the Intel
+ * Cilk language keywords all begin with "`_Cilk_`", which guarantees that they
* will not conflict with user-defined identifiers in properly written
- * programs, so that “standard” C and C++ programs can safely be
- * compiled a Cilk-enabled C or C++ compiler.
+ * programs. This way, a Cilk-enabled C or C++ compiler can safely compile
+ * "standard" C and C++ programs.
*
* However, this means that the keywords _look_ like something grafted on to
* the base language. Therefore, you can include this header:
*
* #include "cilk/cilk.h"
*
- * and then write the Cilk keywords with a “`cilk_`” prefix instead of
- * “`_Cilk_`”.
+ * and then write the Intel Cilk keywords with a "`cilk_`" prefix instead of
+ * "`_Cilk_`".
*
* @ingroup language
*/
/** @defgroup language Language Keywords
- * Definitions having to do with the Cilk language.
+ * Definitions for the Intel Cilk language.
* @{
*/
#ifndef cilk_spawn
# define cilk_spawn _Cilk_spawn ///< Spawn a task that can execute in parallel.
# define cilk_sync _Cilk_sync ///< Wait for spawned tasks to complete.
-# define cilk_for _Cilk_for ///< Execute iterations of a for loop in parallel.
+# define cilk_for _Cilk_for ///< Execute iterations of a `for` loop in parallel.
#endif
/// @}
diff --git a/libcilkrts/include/cilk/cilk_api.h b/libcilkrts/include/cilk/cilk_api.h
index a21687b7b32..6cc62c994b7 100644
--- a/libcilkrts/include/cilk/cilk_api.h
+++ b/libcilkrts/include/cilk/cilk_api.h
@@ -1,10 +1,8 @@
/* cilk_api.h
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,23 +29,37 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
-
+
/** @file cilk_api.h
*
- * @brief Defines the documented API exposed by the Cilk Plus for use
- * by applications.
+ * @brief Defines the Intel(R) Cilk(TM) Plus API for use by applications.
*
* @ingroup api
*/
-
+
#ifndef INCLUDED_CILK_API_H
#define INCLUDED_CILK_API_H
+
/** @defgroup api Runtime API
- * API to allow user programs to interact with the Cilk runtime.
- * @{
- */
+* API to interact with the Intel Cilk Plus runtime.
+* @{
+*/
#ifndef CILK_STUB /* Real (non-stub) definitions */
@@ -81,7 +92,7 @@
__CILKRTS_BEGIN_EXTERN_C
-/** Return values from __cilkrts_set_param() and __cilkrts_set_param_w()
+/** Return values from `__cilkrts_set_param()` and `__cilkrts_set_param_w()`
*/
enum __cilkrts_set_param_status {
__CILKRTS_SET_PARAM_SUCCESS = 0, /**< Success - parameter set */
@@ -91,79 +102,79 @@ enum __cilkrts_set_param_status {
__CILKRTS_SET_PARAM_LATE = 4 /**< Too late to change parameter value */
};
-/** Set user controllable runtime parameters
+/** Sets user controllable runtime parameters
*
- * Call this function to set runtime parameters that control the behavior
- * of the Cilk scheduler.
+ * Call this function to set runtime parameters that control the behavior
+ * of the Intel Cilk Plus scheduler.
*
* @param param A string specifying the parameter to be set. One of:
* - `"nworkers"`
* - `"force reduce"`
* @param value A string specifying the parameter value.
- * @returns A value from the @ref __cilkrts_set_param_status
+ * @returns A value from the @ref __cilkrts_set_param_status
* enumeration indicating the result of the operation.
*
* @par The "nworkers" parameter
*
* This parameter specifies the number of worker threads to be created by the
- * Cilk runtime. @a Value must be a string of digits to be parsed by
- * `strtol()`.
+ * Intel Cilk Plus runtime. @a Value must be a string of digits to be parsed by
+ * `strtol()` as a decimal number.
*
* The number of worker threads is:
- * 1. the value set with `__cilkrts_set_param("nworkers")`, if it is
+ * 1. the value set with `__cilkrts_set_param("nworkers")`, if it is
* positive; otherwise,
- * 2. the value of the CILK_NWORKERS environment variable, if it is
+ * 2. the value of the CILK_NWORKERS environment variable, if it is
* defined; otherwise
* 3. the number of cores available, as reported by the operating system.
*
* @note
- * Technically, Cilk distinguishes between the _user thread_ (the thread that
- * the user code was executing on when the Cilk runtime started), and
- * _worker threads_ (new threads created by the Cilk runtime to support
- * Cilk parallelism). `nworkers` actually includes both the user thread and
- * the worker threads; that is, it is one greater than the number of true
- * “worker threads”.
+ * Technically, Intel Cilk Plus distinguishes between the _user thread_ (the thread
+ * that the user code was executing on when the Intel Cilk Plus runtime started),
+ * and _worker threads_ (new threads created by the Intel Cilk Plus runtime to
+ * support Intel Cilk Plus parallelism). `nworkers` actually includes both the user
+ * thread and the worker threads; that is, it is one greater than the number of
+ * true "worker threads".
*
* @note
- * Setting `nworkers = 1` produces serial behavior. Cilk spawns and syncs will
- * be executed, but with only one worker, continuations will never be stolen,
- * so all code will execute in serial.
+ * Setting `nworkers = 1` produces serial behavior. Intel Cilk Plus spawns and syncs
+ * will be executed, but with only one worker, continuations will never be
+ * stolen, so all code will execute in serial.
*
* @warning
- * The number of worker threads can only be set *before* the runtime has
- * started. Attempting to set it when the runtime is running will have no
- * effect, and will return an error code. You can call __cilkrts_end_cilk()
+ * The number of worker threads can only be set *before* the runtime has
+ * started. Attempting to set it when the runtime is running will have no
+ * effect, and will return an error code. You can call __cilkrts_end_cilk()
* to shut down the runtime to change the number of workers.
*
* @warning
- * The default Cilk scheduler behavior is usually pretty good. The ability
- * to override `nworkers` can be useful for experimentation, but it won’t
- * usually be necessary for getting good performance.
+ * The default Intel Cilk scheduler behavior is usually pretty good. The
+ * ability to override `nworkers` can be useful for experimentation, but it
+ * won't usually be necessary for getting good performance.
*
* @par The "force reduce" parameter
*
* This parameter controls whether the runtime should allocate a new view
- * for a reducer for every parallel strand that it is accessed on. (See
- * @ref pagereducers.) @a Value must be `"1"` or `"true"` to enable the
- * “force reduce” behavior, or `"0"` or `"false"` to disable it.
+ * for a reducer for every parallel strand that it is accessed on. (See
+ * @ref pagereducers.) @a Value must be `"1"` or `"true"` to enable the
+ * "force reduce" behavior, or `"0"` or `"false"` to disable it.
*
- * “Force reduce” behavior will also be enabled if
+ * "Force reduce" behavior will also be enabled if
* `__cilkrts_set_param("force reduce")` is not called, but the
* `CILK_FORCE_REDUCE` environment variable is defined.
*
* @warning
- * When this option is enabled, `nworkers` should be set to `1`. Using “force
- * reduce” with more than one worker may result in runtime errors.
- *
+ * When this option is enabled, `nworkers` should be set to `1`. Using "force
+ * reduce" with more than one worker may result in runtime errors.
+ *
* @warning
- * Enabling this option can significantly reduce performance. It should
- * _only_ be used as a debugging tool.
+ * Enabling this option can significantly reduce performance. Use it
+ * _only_ as a debugging tool.
*/
CILK_API(int) __cilkrts_set_param(const char *param, const char *value);
#ifdef _WIN32
/**
- * Set user controllable parameters using wide strings
+ * Sets user controllable parameters using wide strings
*
* @note This variant of __cilkrts_set_param() is only available
* on Windows.
@@ -173,36 +184,36 @@ CILK_API(int) __cilkrts_set_param(const char *param, const char *value);
CILK_API(int) __cilkrts_set_param_w(const wchar_t *param, const wchar_t *value);
#endif
-/** Shut down and deallocate all Cilk state. The runtime will abort the
- * application if Cilk is still in use by this thread. Otherwise the runtime
- * will wait for all other threads using Cilk to exit.
+/** Shuts down and deallocates all Intel Cilk Plus states. If Intel Cilk Plus is still in
+ * use by the calling thread, the runtime aborts the application. Otherwise, the
+ * runtime waits for all other threads using Intel Cilk Plus to exit.
*/
CILK_API(void) __cilkrts_end_cilk(void);
-/** Initialize the Cilk data structures and start the runtime.
+/** Initializes Intel Cilk Plus data structures and start the runtime.
*/
CILK_API(void) __cilkrts_init(void);
-/** Return the runtime `nworkers` parameter. (See the discussion of `nworkers`
+/** Returns the runtime `nworkers` parameter. (See the discussion of `nworkers`
* in the documentation for __cilkrts_set_param().)
*/
CILK_API(int) __cilkrts_get_nworkers(void);
-/** Return the number of thread data structures.
+/** Returns the number of thread data structures.
*
- * This function returns the number of data structures that has been allocated
- * allocated by the runtime to hold information about user and worker threads.
+ * This function returns the number of data structures that have been allocated
+ * by the runtime to hold information about user and worker threads.
*
- * If you don’t already know what this is good for, then you probably don’t
- * need it.
+ * If you don't already know what this is good for, then you probably don't
+ * need it. :)
*/
CILK_API(int) __cilkrts_get_total_workers(void);
-/** What thread is the function running on?
+/** Returns a small integer identifying the current thread.
*
- * Return a small integer identifying the current thread. Each worker thread
- * started by the Cilk runtime library has a unique worker number in the range
- * `1 .. nworkers - 1`.
+ * What thread is the function running on? Each worker thread
+ * started by the Intel Cilk Plus runtime library has a unique worker number in the
+ * range `1 .. nworkers - 1`.
*
* All _user_ threads (threads started by the user, or by other libraries) are
* identified as worker number 0. Therefore, the worker number is not unique
@@ -210,13 +221,13 @@ CILK_API(int) __cilkrts_get_total_workers(void);
*/
CILK_API(int) __cilkrts_get_worker_number(void);
-/** Test whether “force reduce” behavior is enabled.
- *
+/** Tests whether "force reduce" behavior is enabled.
+ *
* @return Non-zero if force-reduce mode is on, zero if it is off.
*/
CILK_API(int) __cilkrts_get_force_reduce(void);
-/** Interact with tools
+/** Interacts with tools
*/
CILK_API(void)
__cilkrts_metacall(unsigned int tool, unsigned int code, void *data);
@@ -229,12 +240,13 @@ typedef struct _EXCEPTION_RECORD _EXCEPTION_RECORD;
*/
typedef void (*__cilkrts_pfn_seh_callback)(const _EXCEPTION_RECORD *exception);
-/** Specify a function to call when a non-C++ exception is caught.
+/** Specifies a function to call when a non-C++ exception is caught.
*
- * Cilk Plus parallelism plays nicely with C++ exception handling, but the
- * Cilk Plus runtime has no way to unwind the stack across a strand boundary
- * for Microsoft SEH (“Structured Exception Handling”) exceptions. Therefore,
- * when the runtime catches such an exception, it must abort the application.
+ * Intel Cilk Plus parallelism plays nicely with C++ exception handling, but
+ * the Intel Cilk Plus runtime has no way to unwind the stack across a strand
+ * boundary for Microsoft SEH ("Structured Exception Handling") exceptions.
+ * Therefore, when the runtime catches such an exception, it must abort the
+ * application.
*
* If an SEH callback has been set, the runtime will call it before aborting.
*
@@ -267,33 +279,33 @@ __cilkrts_bump_worker_rank_internal(__cilkrts_worker* w);
/// @endcond
-/** Get the current pedigree, in a linked list representation.
+/** Gets the current pedigree in a linked list representation.
*
* This routine returns a copy of the last node in the pedigree list.
* For example, if the current pedigree (in order) is <1, 2, 3, 4>,
* then this method returns a node with rank == 4, and whose parent
* field points to the node with rank of 3. In summary, following the
* nodes in the chain visits the terms of the pedigree in reverse.
- *
+ *
* The returned node is guaranteed to be valid only until the caller
* of this routine has returned.
*/
__CILKRTS_INLINE
-__cilkrts_pedigree __cilkrts_get_pedigree(void)
+__cilkrts_pedigree __cilkrts_get_pedigree(void)
{
- return __cilkrts_get_pedigree_internal(__cilkrts_get_tls_worker());
+ return __cilkrts_get_pedigree_internal(__cilkrts_get_tls_worker());
}
/** Context used by __cilkrts_get_pedigree_info.
*
* @deprecated
- * This data structure is only used by the deprecated
+ * This data structure is only used by the deprecated
* __cilkrts_get_pedigree_info function.
*
* Callers should initialize the `data` array to NULL and set the `size`
* field to `sizeof(__cilkrts_pedigree_context_t)` before the first call
- * to __cilkrts_get_pedigree_info(), and should not examine or modify it
- * thereafter.
+ * to `__cilkrts_get_pedigree_info()`. Also, callers should not examine or
+ * modify `data` thereafter.
*/
typedef struct
{
@@ -301,16 +313,16 @@ typedef struct
void *data[3]; /**< Opaque context data */
} __cilkrts_pedigree_context_t;
-/** Get pedigree information.
+/** Gets pedigree information.
*
* @deprecated
* Use __cilkrts_get_pedigree() instead.
*
- * This routine allows code to walk up the stack of Cilk frames to gather
+ * This routine allows code to walk up the stack of Intel Cilk Plus frames to gather
* the pedigree.
*
* Initialize the pedigree walk by filling the pedigree context with NULLs
- * and setting the size field to sizeof(__cilkrts_pedigree_context).
+ * and setting the size field to `sizeof(__cilkrts_pedigree_context)`.
* Other than initialization to NULL to start the walk, user coder should
* consider the pedigree context data opaque and should not examine or
* modify it.
@@ -326,7 +338,7 @@ CILK_API(int)
__cilkrts_get_pedigree_info(/* In/Out */ __cilkrts_pedigree_context_t *context,
/* Out */ uint64_t *sf_birthrank);
-/** Get the rank of the currently executing worker.
+/** Gets the rank of the currently executing worker.
*
* @deprecated
* Use `__cilkrts_get_pedigree().rank` instead.
@@ -335,16 +347,16 @@ __cilkrts_get_pedigree_info(/* In/Out */ __cilkrts_pedigree_context_t *context,
* @returns <0 - Failure - *rank is not changed
*/
CILK_EXPORT_AND_INLINE
-int __cilkrts_get_worker_rank(uint64_t *rank)
+int __cilkrts_get_worker_rank(uint64_t *rank)
{
*rank = __cilkrts_get_pedigree().rank;
return 0;
}
-/** Increment the pedigree rank of the currently executing worker.
+/** Increments the pedigree rank of the currently executing worker.
*
* @returns 0 - Success - rank was incremented
- * @returns-1 - Failure
+ * @returns -1 - Failure
*/
CILK_EXPORT_AND_INLINE
int __cilkrts_bump_worker_rank(void)
@@ -352,7 +364,7 @@ int __cilkrts_bump_worker_rank(void)
return __cilkrts_bump_worker_rank_internal(__cilkrts_get_tls_worker());
}
-/** Increment the pedigree rank for a cilk_for loop.
+/** Increments the pedigree rank for a `cilk_for` loop.
* Obsolete.
*
* @deprecated
@@ -362,7 +374,7 @@ int __cilkrts_bump_worker_rank(void)
* be called, but will have no effect.
*/
CILK_EXPORT_AND_INLINE
-int __cilkrts_bump_loop_rank(void)
+int __cilkrts_bump_loop_rank(void)
{
return 0;
}
@@ -375,7 +387,7 @@ __CILKRTS_END_EXTERN_C
#else /* CILK_STUB */
-// Programs compiled with CILK_STUB are not linked with the Cilk runtime
+// Programs compiled with CILK_STUB are not linked with the Intel Cilk Plus runtime
// library, so they should not have external references to runtime functions.
// Therefore, the functions are replaced with stubs.
@@ -401,8 +413,8 @@ __CILKRTS_END_EXTERN_C
/*
* A stub method for __cilkrts_get_pedigree.
- * Returns an empty __cilkrts_pedigree.
- */
+ * Returns an empty __cilkrts_pedigree.
+ */
__CILKRTS_INLINE
__cilkrts_pedigree __cilkrts_get_pedigree_stub(void)
{
diff --git a/libcilkrts/include/cilk/cilk_api_linux.h b/libcilkrts/include/cilk/cilk_api_linux.h
index ed9e70635f6..0ebd57cba21 100644
--- a/libcilkrts/include/cilk/cilk_api_linux.h
+++ b/libcilkrts/include/cilk/cilk_api_linux.h
@@ -1,9 +1,7 @@
/*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -18,7 +16,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -31,6 +28,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
*/
diff --git a/libcilkrts/include/cilk/cilk_stub.h b/libcilkrts/include/cilk/cilk_stub.h
index 116e3ff5541..b4a54f37c9b 100644
--- a/libcilkrts/include/cilk/cilk_stub.h
+++ b/libcilkrts/include/cilk/cilk_stub.h
@@ -1,10 +1,8 @@
/* cilk_stub.h -*-C++-*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,13 +29,27 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
*/
#ifndef INCLUDED_CILK_STUB_DOT_H
#define INCLUDED_CILK_STUB_DOT_H
-/* Definitions for creating a serialization from a Cilk program.
+/* Definitions for creating a serialization from an Intel(R) Cilk(TM) Plus program.
* These definitions are suitable for use by a compiler that is not
* Cilk-enabled.
*/
@@ -47,9 +58,14 @@
#undef __cilk
#define CILK_STUB
-/* Replace Cilk keywords with serial equivalents */
+/* Replace Intel Cilk keywords with serial equivalents */
#define _Cilk_spawn
#define _Cilk_sync
#define _Cilk_for for
+/* Replace simd-loop keywords with serial equivalents */
+#define _Simd
+#define _Safelen(...)
+#define _Reduction(...)
+
#endif /* ! defined(INCLUDED_CILK_STUB_DOT_H) */
diff --git a/libcilkrts/include/cilk/cilk_undocumented.h b/libcilkrts/include/cilk/cilk_undocumented.h
index 81cdd64bb89..5f4a8c5dff1 100644
--- a/libcilkrts/include/cilk/cilk_undocumented.h
+++ b/libcilkrts/include/cilk/cilk_undocumented.h
@@ -1,9 +1,7 @@
/*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -18,7 +16,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -31,6 +28,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
******************************************************************************
*
@@ -83,7 +94,7 @@ CILK_EXPORT __CILKRTS_NOTHROW
void *__cilkrts_get_sf(void);
/**
- * Returns the size of stacks created by Cilk.
+ * Returns the size of stacks created by Intel(R) Cilk(TM) Plus.
*/
CILK_EXPORT __CILKRTS_NOTHROW
size_t __cilkrts_get_stack_size(void);
diff --git a/libcilkrts/include/cilk/common.h b/libcilkrts/include/cilk/common.h
index 97dd66e0639..91b2928e7e6 100644
--- a/libcilkrts/include/cilk/common.h
+++ b/libcilkrts/include/cilk/common.h
@@ -1,10 +1,8 @@
/** common.h
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,18 +29,31 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file common.h
*
- * @brief Defines common macros and structures used by the Intel Cilk Plus
- * runtime.
+ * @brief Defines common macros and structures used by the Intel(R) Cilk(TM) Plus runtime.
*
* @ingroup common
*/
/** @defgroup common Common Definitions
- * Macro, structure, and class definitions used elsewhere in the runtime.
+ * Definitions for runtime macros, structures, and classes.
* @{
*/
@@ -51,18 +61,17 @@
#define INCLUDED_CILK_COMMON
#ifdef __cplusplus
-/** Namespace for all Cilk definitions that can be included in user code.
+/** Namespace for all Intel Cilk Plus definitions that can be included in user code.
*/
namespace cilk {
- /** Namespace for definitions that are primarily intended for use
- * in other Cilk definitions.
+ /** Namespace for definitions re-used in other Intel Cilk Plus definitions.
*/
namespace internal {}
}
#endif
-/** Cilk library version = 1.01
+/** Intel Cilk Plus library version = 1.02
*/
#define CILK_LIBRARY_VERSION 102
@@ -73,7 +82,7 @@ namespace cilk {
#endif
/**
- * Prefix standard library function and type names with __STDNS in order to
+ * Prefix standard library function and type names with __STDNS to
* get correct lookup in both C and C++.
*/
#ifdef __cplusplus
@@ -159,7 +168,7 @@ namespace cilk {
/**
* Macro to specify alignment of a data member in a structure.
- * Because of the way that gcc’s alignment attribute is defined, @a n must
+ * Because of the way that gcc's alignment attribute is defined, @a n must
* be a numeric literal, not just a compile-time constant expression.
*/
#ifdef _WIN32
@@ -231,7 +240,7 @@ namespace cilk {
/**
* OS-independent macro to specify a function that should be inlined
*/
-#ifdef __cpluspus
+#ifdef __cplusplus
// C++
# define __CILKRTS_INLINE inline
#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
@@ -247,7 +256,7 @@ namespace cilk {
/**
* Functions marked as CILK_EXPORT_AND_INLINE have both
- * inline versions defined in the Cilk API, as well as
+ * inline versions defined in the Intel Cilk Plus API, as well as
* non-inlined versions that are exported (for
* compatibility with previous versions that did not
* inline the functions).
@@ -306,13 +315,14 @@ namespace cilk {
#endif /* ! defined(_MSC_VER) || (_MSC_VER >= 1600) */
/**
- * @brief Application Binary Interface version of the Cilk runtime library.
+ * @brief Application Binary Interface (ABI) version of the Intel Cilk Plus runtime
+ * library.
*
- * The ABI version is determined by the compiler used. An object file
- * compiled with a higher ABI version is not compatible with a library that is
- * compiled with a lower ABI version. An object file compiled with a lower
- * ABI version, however, can be used with a library compiled with a higher ABI
- * version unless otherwise stated.
+ * The compiler determines the ABI version used for compilation. Object files
+ * compiled with higher ABI versions are not compatible with libraries compiled
+ * with lower ABI versions. However, an object file compiled with a lower ABI
+ * version can be used with a library compiled with a higher ABI version
+ * (unless otherwise stated.)
*/
#ifndef __CILKRTS_ABI_VERSION
# ifdef IN_CILK_RUNTIME
diff --git a/libcilkrts/include/cilk/holder.h b/libcilkrts/include/cilk/holder.h
index 8620c052f53..66899a25bc9 100644
--- a/libcilkrts/include/cilk/holder.h
+++ b/libcilkrts/include/cilk/holder.h
@@ -1,9 +1,7 @@
/*
- * @copyright
- * Copyright (C) 2011-2013, Intel Corporation
+ * Copyright (C) 2011-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -18,7 +16,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -31,6 +28,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
*/
@@ -60,8 +71,8 @@
* common variable where it is not necessary to preserve changes from
* different parallel strands. In effect, a holder acts a bit like
* thread-local storage, but has qualities that work better with the
- * fork-join structure of Cilk. In particular, a holder has the following
- * qualities:
+ * fork-join structure of Intel(R) Cilk(TM) Plus. In particular, a holder has the
+ * following qualities:
*
* - The view of a holder before the first spawn within a function is the same
* as the view after each sync (as in the case of a reducer).
@@ -220,7 +231,7 @@
* same as the view on entry to 'h'. More importantly, the view of the holder
* within the recursive call to 'compute' is the same as the view on entry to
* 'h', even if a different worker is executing the recursive call. Thus, the
- * holder view within a Cilk program has useful qualities not found in
+ * holder view within a Intel Cilk Plus program has useful qualities not found in
* thread-local storage.
*/
diff --git a/libcilkrts/include/cilk/hyperobject_base.h b/libcilkrts/include/cilk/hyperobject_base.h
index 484bf5f01ea..dd7ccfd9020 100644
--- a/libcilkrts/include/cilk/hyperobject_base.h
+++ b/libcilkrts/include/cilk/hyperobject_base.h
@@ -1,9 +1,7 @@
/*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -18,7 +16,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -31,6 +28,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
*/
@@ -49,7 +60,7 @@
#if defined _WIN32 || defined _WIN64
# if !defined CILK_STUB && !defined IN_CILK_RUNTIME
- /* bring in the Cilk library, which has definitions for some of these
+ /* bring in the Intel(R) Cilk(TM) Plus library, which has definitions for some of these
* functions. */
# pragma comment(lib, "cilkrts")
# endif
@@ -126,7 +137,7 @@ CILK_EXPORT
#else // CILK_STUB
-// Programs compiled with CILK_STUB are not linked with the Cilk runtime
+// Programs compiled with CILK_STUB are not linked with the Intel Cilk Plus runtime
// library, so they should not have external references to cilkrts functions.
// Furthermore, they don't need the hyperobject functionality, so the
// functions can be stubbed.
diff --git a/libcilkrts/include/cilk/metaprogramming.h b/libcilkrts/include/cilk/metaprogramming.h
index 29b0839e788..2df7cf6467c 100644
--- a/libcilkrts/include/cilk/metaprogramming.h
+++ b/libcilkrts/include/cilk/metaprogramming.h
@@ -1,10 +1,8 @@
/* metaprogramming.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2012-2013, Intel Corporation
+ * Copyright (C) 2012-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,11 +29,25 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file metaprogramming.h
*
- * @brief Defines metaprogramming utility classes used in the Cilk library.
+ * @brief Defines metaprogramming utility classes used in the Intel(R) Cilk(TM) Plus library.
*
* @ingroup common
*/
@@ -61,7 +72,7 @@ namespace internal {
/** Test if a class is empty.
*
* If @a Class is an empty (and therefore necessarily stateless) class, then
- * the “empty base-class optimization” guarantees that
+ * the "empty base-class optimization" guarantees that
* `sizeof(check_for_empty_class<Class>) == sizeof(char)`. Conversely, if
* `sizeof(check_for_empty_class<Class>) > sizeof(char)`, then @a Class is not
* empty, and we must discriminate distinct instances of @a Class.
@@ -84,7 +95,7 @@ namespace internal {
* @ingroup common
*/
template <class Class>
-class class_is_empty {
+class class_is_empty {
class check_for_empty_class : public Class
{
char m_data;
@@ -147,11 +158,11 @@ public:
* @tparam Size The required minimum size of the resulting class.
* @tparam Alignment The required alignment of the resulting class.
*
- * @pre @a Alignment shall be a power of 2 no greater then 64.
+ * @pre @a Alignment shall be a power of 2 no greater than 64.
*
* @note This is implemented using the `CILK_ALIGNAS` macro, which uses
* the non-standard, implementation-specific features
- * `__declspec(align(N))` on Windows, and
+ * `__declspec(align(N))` on Windows, and
* `__attribute__((__aligned__(N)))` on Unix. The `gcc` implementation
* of `__attribute__((__aligned__(N)))` requires a numeric literal `N`
* (_not_ an arbitrary compile-time constant expression). Therefore,
@@ -165,21 +176,22 @@ public:
template <std::size_t Size, std::size_t Alignment>
struct aligned_storage;
-template<std::size_t Size> class aligned_storage<Size, 1>
+/// @cond
+template<std::size_t Size> class aligned_storage<Size, 1>
{ CILK_ALIGNAS( 1) char m_bytes[Size]; };
-template<std::size_t Size> class aligned_storage<Size, 2>
+template<std::size_t Size> class aligned_storage<Size, 2>
{ CILK_ALIGNAS( 2) char m_bytes[Size]; };
-template<std::size_t Size> class aligned_storage<Size, 4>
+template<std::size_t Size> class aligned_storage<Size, 4>
{ CILK_ALIGNAS( 4) char m_bytes[Size]; };
-template<std::size_t Size> class aligned_storage<Size, 8>
+template<std::size_t Size> class aligned_storage<Size, 8>
{ CILK_ALIGNAS( 8) char m_bytes[Size]; };
-template<std::size_t Size> class aligned_storage<Size, 16>
+template<std::size_t Size> class aligned_storage<Size, 16>
{ CILK_ALIGNAS(16) char m_bytes[Size]; };
-template<std::size_t Size> class aligned_storage<Size, 32>
+template<std::size_t Size> class aligned_storage<Size, 32>
{ CILK_ALIGNAS(32) char m_bytes[Size]; };
-template<std::size_t Size> class aligned_storage<Size, 64>
+template<std::size_t Size> class aligned_storage<Size, 64>
{ CILK_ALIGNAS(64) char m_bytes[Size]; };
-
+/// @endcond
/** A buffer of uninitialized bytes with the same size and alignment as a
* specified type.
@@ -188,14 +200,14 @@ template<std::size_t Size> class aligned_storage<Size, 64>
* properties as `Type`, but it will contain only raw (uninitialized) bytes.
* This allows the definition of a data member which can contain a `Type`
* object which is initialized explicitly under program control, rather
- * than implicitly as part of the initialization of the containing class.
+ * than implicitly as part of the initialization of the containing class.
* For example:
*
* class C {
* storage_for_object<MemberClass> _member;
* public:
* C() ... // Does NOT initialize _member
- * void initialize(args)
+ * void initialize(args)
* { new (_member.pointer()) MemberClass(args); }
* const MemberClass& member() const { return _member.object(); }
* MemberClass& member() { return _member.object(); }
@@ -204,21 +216,22 @@ template<std::size_t Size> class aligned_storage<Size, 64>
* by this class.
*/
template <typename Type>
-class storage_for_object :
+class storage_for_object :
aligned_storage< sizeof(Type), align_of<Type>::value >
{
public:
/// Return a typed reference to the buffer.
const Type& object() const { return *reinterpret_cast<Type*>(this); }
+ /// Return a typed reference to the buffer.
Type& object() { return *reinterpret_cast<Type*>(this); }
};
/** Get the functor class corresponding to a binary function type.
*
- * The `binary_functor` template class class can be instantiated with a binary
+ * The `binary_functor` template class can be instantiated with a binary
* functor class or with a real binary function, and will yield an equivalent
- * binary functor class class in either case.
+ * binary functor class in either case.
*
* @tparam F A binary functor class, a binary function type, or a pointer to
* binary function type.
@@ -260,7 +273,7 @@ struct binary_functor<R(*)(A,B)> {
* `typed_indirect_binary_function<F>` is an `Adaptable Binary Function` class
* based on an existing binary functor class or binary function type @a F. If
* @a F is a stateless class, then this class will be empty, and its
- * `operator()` will invoke @a F’s `operator()`. Otherwise, an object of this
+ * `operator()` will invoke @a F's `operator()`. Otherwise, an object of this
* class will hold a pointer to an object of type @a F, and will refer its
* `operator()` calls to the pointed-to @a F object.
*
@@ -276,14 +289,15 @@ struct binary_functor<R(*)(A,B)> {
*
* @note Just to repeat: if `F` is an empty class, then
* `typed_indirect_binary_function\<F\>' is also an empty class.
- * This is critical for its use in the @ref min_max::view_base
+ * This is critical for its use in the
+ * @ref cilk::cilk_lib_1_1::min_max_internal::view_base
* "min/max reducer view classes", where it allows the view to
* call a comparison functor in the monoid without actually
- * having to allocate a pointer in the view class when the
+ * having to allocate a pointer in the view class when the
* comparison class is empty.
*
* @note If you have an `Adaptable Binary Function` class or a binary
- * function type, then you can use the
+ * function type, then you can use the
* @ref indirect_binary_function class, which derives the
* argument and result types parameter type instead of requiring
* you to specify them as template arguments.
@@ -312,7 +326,7 @@ class typed_indirect_binary_function : std::binary_function<A1, A2, R>
public:
/// Constructor captures a pointer to the wrapped function.
typed_indirect_binary_function(const F* f) : f(f) {}
-
+
/// Return the comparator pointer, or `NULL` if the comparator is stateless.
const F* pointer() const { return f; }
@@ -323,10 +337,10 @@ public:
/// @copydoc typed_indirect_binary_function
/// Specialization for an empty functor class. (This is only possible if @a F
-/// itself is an empty class. If @a F is a function or pointer-to-function
+/// itself is an empty class. If @a F is a function or pointer-to-function
/// type, then the functor will contain a pointer.)
template <typename F, typename A1, typename A2, typename R, typename Functor>
-class typed_indirect_binary_function<F, A1, A2, R, Functor, true> :
+class typed_indirect_binary_function<F, A1, A2, R, Functor, true> :
std::binary_function<A1, A2, R>
{
public:
@@ -335,7 +349,7 @@ public:
/// Constructor discards the pointer to a stateless functor class.
typed_indirect_binary_function(const F* f) {}
-
+
/// Create an instance of the stateless functor class and apply it to the arguments.
R operator()(const A1& a1, const A2& a2) const { return F()(a1, a2); }
};
@@ -343,28 +357,29 @@ public:
/** Indirect binary function class with inferred types.
*
- * This is identical to @ref typed_indirect_binary_function, except that it
- * derives the binary function argument and result types from the parameter
- * type @a F instead of taking them as additional template parameters. If @a F
- * is a class type, then it must be an `Adaptable Binary Function`.
+ * This is identical to @ref cilk::internal::typed_indirect_binary_function,
+ * except that it derives the binary function argument and result types from
+ * the parameter type @a F instead of taking them as additional template
+ * parameters. If @a F is a class type, then it must be an `Adaptable Binary
+ * Function`.
*
* @see typed_indirect_binary_function
*
* @ingroup common
*/
template <typename F, typename Functor = typename binary_functor<F>::type>
-class indirect_binary_function :
+class indirect_binary_function :
typed_indirect_binary_function< F
, typename Functor::first_argument_type
, typename Functor::second_argument_type
, typename Functor::result_type
- >
+ >
{
typedef typed_indirect_binary_function< F
, typename Functor::first_argument_type
, typename Functor::second_argument_type
, typename Functor::result_type
- >
+ >
base;
public:
indirect_binary_function(const F* f) : base(f) {} ///< Constructor
@@ -373,7 +388,7 @@ public:
/** Choose a type based on a boolean constant.
*
- * This metafunction is identical to C++11’s condition metafunction.
+ * This metafunction is identical to C++11's condition metafunction.
* It needs to be here until we can reasonably assume that users will be
* compiling with C++11.
*
@@ -407,12 +422,12 @@ struct condition<false, IfTrue, IfFalse>
* Causes a compilation error if a compile-time constant expression is false.
*
* @par Usage example.
- * This assertion is used in reducer_min_max.h to avoid defining
+ * This assertion is used in reducer_min_max.h to avoid defining
* legacy reducer classes that would not be binary-compatible with the
* same classes compiled with earlier versions of the reducer library.
*
* __CILKRTS_STATIC_ASSERT(
- * internal::class_is_empty< internal::binary_functor<Compare> >::value,
+ * internal::class_is_empty< internal::binary_functor<Compare> >::value,
* "cilk::reducer_max<Value, Compare> only works with an empty Compare class");
*
* @note In a C++11 compiler, this is just the language predefined
@@ -468,13 +483,13 @@ inline void* allocate_aligned(std::size_t size, std::size_t alignment)
#ifdef _WIN32
return _aligned_malloc(size, alignment);
#else
-#if defined(__ANDROID__)
+#if defined(__ANDROID__) || defined(__VXWORKS__)
return memalign(std::max(alignment, sizeof(void*)), size);
#else
void* ptr;
return (posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size) == 0) ? ptr : 0;
#endif
-#endif
+#endif
}
/** Implementation-specific aligned memory deallocation function.
@@ -487,13 +502,13 @@ inline void deallocate_aligned(void* ptr)
_aligned_free(ptr);
#else
std::free(ptr);
-#endif
+#endif
}
/** Class to allocate and guard an aligned pointer.
*
* A new_aligned_pointer object allocates aligned heap-allocated memory when
- * it is created, and automatically deallocates it when it is destroyed
+ * it is created, and automatically deallocates it when it is destroyed
* unless its `ok()` function is called.
*
* @tparam T The type of the object to allocate on the heap. The allocated
@@ -504,14 +519,14 @@ class new_aligned_pointer {
void* m_ptr;
public:
/// Constructor allocates the pointer.
- new_aligned_pointer() :
+ new_aligned_pointer() :
m_ptr(allocate_aligned(sizeof(T), internal::align_of<T>::value)) {}
/// Destructor deallocates the pointer.
~new_aligned_pointer() { if (m_ptr) deallocate_aligned(m_ptr); }
/// Get the pointer.
operator void*() { return m_ptr; }
/// Return the pointer and release the guard.
- T* ok() {
+ T* ok() {
T* ptr = static_cast<T*>(m_ptr);
m_ptr = 0;
return ptr;
diff --git a/libcilkrts/include/cilk/reducer.h b/libcilkrts/include/cilk/reducer.h
index a22651e1e6f..09c2e196903 100644
--- a/libcilkrts/include/cilk/reducer.h
+++ b/libcilkrts/include/cilk/reducer.h
@@ -1,10 +1,8 @@
/* reducer.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,11 +29,25 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
-
+
/** @file reducer.h
*
- * @brief Defines foundation classes for creating Cilk reducers.
+ * @brief Defines foundation classes for creating Intel(R) Cilk(TM) Plus reducers.
*
* @ingroup Reducers
*
@@ -44,7 +55,7 @@
*
* @defgroup Reducers Reducers
*/
-
+
#ifndef REDUCER_H_INCLUDED
#define REDUCER_H_INCLUDED
@@ -59,12 +70,96 @@
namespace cilk {
+/** Class for provisionally constructed objects.
+ *
+ * The monoid_base<T,V>::construct() functions manually construct both a
+ * monoid and a view. If one of these is constructed successfully, and the
+ * construction of the other (or some other initialization) fails, then the
+ * first one must be destroyed to avoid a memory leak. Because the
+ * construction is explicit, the destruction must be explicit, too.
+ *
+ * A provisional_guard object wraps a pointer to a newly constructed
+ * object. A call to its confirm() function confirms that the object is
+ * really going to be used. If the guard is destroyed without being
+ * confirmed, then the pointed-to object is destroyed (but not
+ * deallocated).
+ *
+ * Expected usage:
+ *
+ * provisional_guard<T1> x1_provisional( new (x1) T1 );
+ * … more initialization …
+ * x1_provisional.confirm();
+ *
+ * or
+ *
+ * provisional_guard<T1> x1_provisional( new (x1) T1 );
+ * x1_provisional.confirm_if( new (x2) T2 );
+ *
+ * If an exception is thrown in the "more initialization" code in the
+ * first example, or in the `T2` constructor in the second example, then
+ * `x1_provisional` will not be confirmed, so when its destructor is
+ * called during exception unwinding, the `T1` object that was constructed
+ * in `x1` will be destroyed.
+ *
+ * **NOTE**: Do *not* be tempted to chain a `provisional_guard`
+ * constructor with `confirm_if` as in this example:
+ *
+ * // BAD IDEA
+ * provisional_guard<T1>( new (x1) T1 ).confirm_if( new (x2) T2 );
+ *
+ * The code above is problematic because the evaluation of the T2
+ * constructor is unsequenced with respect to the call to the
+ * `provisional_guard` constructor (and with respect the T1 constructor).
+ * Thus, the compiler may choose to evaluate `new (x2) T2` before
+ * constructing the guard and leak the T1 object if the `T2` constructor
+ * throws.
+ *
+ * @tparam Type The type of the provisionally constructed object.
+ */
+template <typename Type>
+class provisional_guard {
+ Type* m_ptr;
+
+public:
+
+ /** Constructor. Creates a guard for a provisionally constructed object.
+ *
+ * @param ptr A pointer to the provisionally constructed object.
+ */
+ provisional_guard(Type* ptr) : m_ptr(ptr) {}
+
+ /** Destructor. Destroy the object pointed to by the contained pointer
+ * if it has not been confirmed.
+ */
+ ~provisional_guard() { if (m_ptr) m_ptr->~Type(); }
+
+ /** Confirm the provisional construction. Do *not* delete the contained
+ * pointer when the guard is destroyed.
+ */
+ void confirm() { m_ptr = 0; }
+
+ /** Confirm provisional construction if argument is non-null. Note that
+ * if an exception is thrown during evaluation of the argument
+ * expression, then this function will not be called, and the
+ * provisional object will not be confirmed. This allows the usage:
+ *
+ * x1_provisional.confirm_if( new (x2) T2() );
+ *
+ * @param cond An arbitrary pointer. The provisional object will be
+ * confirmed if @a cond is not null.
+ *
+ * @returns The value of the @a cond argument.
+ */
+ template <typename Cond>
+ Cond* confirm_if(Cond* cond) { if (cond) m_ptr = 0; return cond; }
+};
+
/** Base class for defining monoids.
*
* The monoid_base class template is useful for creating classes that model
* the monoid concept. It provides the core type and memory management
* functionality. A subclass of monoid_base need only declare and implement
- * the `identity` and `reduce` functions.
+ * the `identity` and `reduce` functions.
*
* The monoid_base class also manages the integration between the monoid, the
* reducer class that is based on it, and an optional view class which wraps
@@ -79,149 +174,51 @@ namespace cilk {
template <typename Value, typename View = Value>
class monoid_base
{
-protected:
-
- /** Class for provisionally constructed objects.
- *
- * The monoid_base::construct() functions manually construct both a monoid
- * and a view. If one of these is constructed successfully, and the
- * construction of the other (or some other initialization) fails, then
- * the first one must be destroyed to avoid a memory leak. Because the
- * construction is explicit, the destruction must be explicit, too.
- *
- * A provisional_guard object wraps a pointer to a newly constructed
- * object. A call to its confirm() function confirms that the object is
- * really going to be used. If the guard is destroyed without being
- * confirmed, then the pointed-to object is destroyed (but not
- * deallocated).
- *
- * Expected usage:
- *
- * provisional_guard<T1> x1_provisional( new (x1) T1() );
- * … more initialization …
- * x1_provisional.confirm();
- *
- * or
- *
- * provisional_guard<T1> x1_provisional( new (x1) T1() );
- * x1_provisional.confirm_if( new (x2) T2() );
- *
- * If an exception is thrown in the “more initialization” code in the
- * first example, or in the `T2` constructor in the second example, then
- * `x1_provisional` will not be confirmed, so when its destructor is
- * called during exception unwinding, the `T1` object that was constructed
- * in `x1` will be destroyed.
- *
- * @see provisional()
- *
- * @tparam Type The type of the provisionally constructed object.
- */
- template <typename Type>
- class provisional_guard {
- Type* m_ptr;
-
- public:
-
- /** Constructor. Creates a guard for a provisionally constructed object.
- *
- * @param ptr A pointer to the provisionally constructed object.
- */
- provisional_guard(Type* ptr) : m_ptr(ptr) {}
-
- /** Destructor. Destroy the object pointed to by the contained pointer
- * if it has not been confirmed.
- */
- ~provisional_guard() { if (m_ptr) m_ptr->~Type(); }
-
- /** Confirm the provisional construction. Do *not* delete the contained
- * pointer when the guard is destroyed.
- */
- void confirm() { m_ptr = 0; }
-
- /** Confirm provisional construction if argument is non-null. Note that
- * if an exception is thrown during evaluation of the argument
- * expression, then this function will not be called, and the
- * provisional object will not be confirmed. This allows the usage:
- *
- * x1_provisional.confirm_if( new (x2) T2() );
- *
- * @param cond An arbitrary pointer. The provisional object will be
- * confirmed if @a cond is not null.
- *
- * @returns The value of the @a cond argument.
- */
- template <typename Cond>
- Cond* confirm_if(Cond* cond) { if (cond) m_ptr = 0; return cond; }
- };
-
-
- /** Create a provisional_guard object. This function allows simpler code
- * when the only use of a provisional_guard is in a
- * provisional_guard::confirm_if() call immediately following its
- * creation. Instead of
- *
- * provisional_guard<T>guard( new (ptr_to_T) T() );
- * guard.confirm_if( new (ptr_to_U) U() );
- *
- * you can just write
- *
- * provisional( new (ptr_to_T) T() ).confirm_if( new (ptr_to_U) U() );
- *
- * @tparam Type The type of the provisionally constructed object.
- *
- * @param ptr A pointer to a provisionally constructed object.
- *
- * @returns A @ref provisional_guard object that guards the
- * provisionally constructed object pointed to by @a ptr.
- */
- template <typename Type>
- static provisional_guard<Type> provisional(Type* ptr)
- { return provisional_guard<Type>(ptr); }
public:
/** Value type of the monoid.
*/
typedef Value value_type;
-
+
/** View type of the monoid. Defaults to be the same as the value type.
* @see monoid_with_view
*/
typedef View view_type;
-
- enum {
+
+ enum {
/** Should reducers created with this monoid be aligned?
*
* @details
- * “Aligned” means that the view is allocated at a cache-line aligned
+ * "Aligned" means that the view is allocated at a cache-line aligned
* offset in the reducer, and the reducer must be cache-line aligned.
- * “Unaligned” means that the reducer as a whole is just naturally
- * aligned, but it contains a large enough block of uninitialized
+ * "Unaligned" means that the reducer as a whole is just naturally
+ * aligned, but it contains a large enough block of uninitialized
* storage for a cache-line aligned view to be allocated in it at
* reducer construction time.
*
- * Since the standard heap allocator (new reducer) does not allocate
+ * Since the standard heap allocator (new reducer) does not allocate
* cache-line aligned storage, only unaligned reducers can be safely
* allocated on the heap.
- *
+ *
* Default is false (unaligned) unless overridden in a subclass.
*
* @since 1.02
- * (In Cilk library versions 1.0 and 1.01, the default was true.
- * In Cilk library versions prior to 1.0, reducers were always aligned,
- * and this data member did not exist.)
+ * (In Intel Cilk Plus library versions 1.0 and 1.01, the default was true.
+ * In Intel Cilk Plus library versions prior to 1.0, reducers were always
+ * aligned, and this data member did not exist.)
*/
- align_reducer = false
+ align_reducer = false
};
-
- /** Destroy a view. Destroys (without deallocating) the @a View object
+
+ /** Destroys a view. Destroys (without deallocating) the @a View object
* pointed to by @a p.
*
* @param p The address of the @a View object to be destroyed.
*/
void destroy(view_type* p) const { p->~view_type(); }
- /** Allocate raw memory. Allocate @a s bytes of memory with no
+ /** Allocates raw memory. Allocate @a s bytes of memory with no
* initialization.
*
* @param s The number of bytes of memory to allocate.
@@ -229,7 +226,7 @@ public:
*/
void* allocate(size_t s) const { return operator new(s); }
- /** Deallocate raw memory. Deallocates the memory pointed to by @a p
+ /** Deallocates raw memory pointed to by @a p
* without doing any destruction.
*
* @param p Pointer to the memory to be deallocated.
@@ -239,10 +236,10 @@ public:
*/
void deallocate(void* p) const { operator delete(p); }
- /** Create the identity value. Constructs (without allocating) a @a View
+ /** Creates the identity value. Constructs (without allocating) a @a View
* object representing the default value of the @a Value type.
*
- * @param p A pointer to a block of raw memory large enough to hold a
+ * @param p A pointer to a block of raw memory large enough to hold a
* @a View object.
*
* @post The memory pointed to by @a p contains a @a View object that
@@ -255,128 +252,165 @@ public:
* this default definition.
*/
void identity(View* p) const { new ((void*) p) View(); }
-
-
- /** @name Construct the monoid and the view with arbitrary arguments.
+
+
+ /** @name Constructs the monoid and the view with arbitrary arguments.
*
* A @ref reducer object contains monoid and view data members, which are
* declared as raw storage (byte arrays), so that they are not implicitly
* constructed when the reducer is constructed. Instead, a reducer
- * constructor calls one of the monoid class’s static construct()
+ * constructor calls one of the monoid class's static construct()
* functions with the addresses of the monoid and the view, and the
* construct() function uses placement `new` to construct them.
- *
* This allows the monoid to determine the order in which the monoid and
* view are constructed, and to make one of them dependent on the other.
*
- * Any arguments to the reducer constructor are just passed on as
+ * Any arguments to the reducer constructor are just passed on as
* additional arguments to the construct() function (after the monoid
- * and view addresses).
+ * and view addresses are set).
*
- * Any monoid whose needs are satisfied by the suite of construct()
+ * A monoid whose needs are satisfied by the suite of construct()
* functions below, such as @ref monoid_with_view, can just inherit them
* from monoid_base. Other monoids will need to provide their own versions
* to override the monoid_base functions.
*/
//@{
-
- /** Default-construct the monoid, and pass zero to five const reference
- * arguments to the view constructor.
+
+ /** Default-constructs the monoid, identity-constructs the view.
+ *
+ * @param monoid Address of uninitialized monoid object.
+ * @param view Address of uninitialized initial view object.
*/
//@{
-
template <typename Monoid>
static void construct(Monoid* monoid, View* view)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- (monoid->identity(view), view) ); }
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid() );
+ monoid->identity(view);
+ guard.confirm();
+ }
+ //@}
+
+ /** Default-constructs the monoid, and passes one to five const reference
+ * arguments to the view constructor.
+ */
+ //@{
template <typename Monoid, typename T1>
static void construct(Monoid* monoid, View* view, const T1& x1)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(x1) ); }
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid() );
+ guard.confirm_if( new((void*) view) View(x1) );
+ }
template <typename Monoid, typename T1, typename T2>
- static void construct(Monoid* monoid, View* view,
+ static void construct(Monoid* monoid, View* view,
const T1& x1, const T2& x2)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(x1, x2) ); }
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid() );
+ guard.confirm_if( new((void*) view) View(x1, x2) );
+ }
template <typename Monoid, typename T1, typename T2, typename T3>
- static void construct(Monoid* monoid, View* view,
+ static void construct(Monoid* monoid, View* view,
const T1& x1, const T2& x2, const T3& x3)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(x1, x2, x3) ); }
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid() );
+ guard.confirm_if( new((void*) view) View(x1, x2, x3) );
+ }
- template <typename Monoid, typename T1, typename T2, typename T3,
+ template <typename Monoid, typename T1, typename T2, typename T3,
typename T4>
- static void construct(Monoid* monoid, View* view,
- const T1& x1, const T2& x2, const T3& x3,
+ static void construct(Monoid* monoid, View* view,
+ const T1& x1, const T2& x2, const T3& x3,
const T4& x4)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(x1, x2, x3, x4) ); }
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid() );
+ guard.confirm_if( new((void*) view) View(x1, x2, x3, x4) );
+ }
- template <typename Monoid, typename T1, typename T2, typename T3,
+ template <typename Monoid, typename T1, typename T2, typename T3,
typename T4, typename T5>
- static void construct(Monoid* monoid, View* view,
- const T1& x1, const T2& x2, const T3& x3,
+ static void construct(Monoid* monoid, View* view,
+ const T1& x1, const T2& x2, const T3& x3,
const T4& x4, const T5& x5)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(x1, x2, x3, x4, x5) ); }
-
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid() );
+ guard.confirm_if( new((void*) view) View(x1, x2, x3, x4, x5) );
+ }
+
//@}
-
- /** Default-construct the monoid, and pass one non-const reference argument
- * to the view constructor.
+
+ /** Default-constructs the monoid, and passes one non-const reference
+ * argument to the view constructor.
*/
//@{
template <typename Monoid, typename T1>
static void construct(Monoid* monoid, View* view, T1& x1)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(x1) ); }
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid() );
+ guard.confirm_if( new((void*) view) View(x1) );
+ }
//@}
- /** Copy-construct the monoid, and pass zero to four const reference
- * arguments to the view constructor.
+ /** Copy-constructs the monoid, and identity-constructs the view
+ * constructor.
+ *
+ * @param monoid Address of uninitialized monoid object.
+ * @param view Address of uninitialized initial view object.
+ * @param m Object to be copied into `*monoid`
*/
//@{
-
template <typename Monoid>
static void construct(Monoid* monoid, View* view, const Monoid& m)
- { provisional( new ((void*)monoid) Monoid(m) ).confirm_if(
- new ((void*)view) View() ); }
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid(m) );
+ monoid->identity(view);
+ guard.confirm();
+ }
+ //@}
+
+ /** Copy-constructs the monoid, and passes one to four const reference
+ * arguments to the view constructor.
+ */
+ //@{
template <typename Monoid, typename T1>
- static void construct(Monoid* monoid, View* view, const Monoid& m,
+ static void construct(Monoid* monoid, View* view, const Monoid& m,
const T1& x1)
- { provisional( new ((void*)monoid) Monoid(m) ).confirm_if(
- new ((void*)view) View(x1) ); }
-
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid(m) );
+ guard.confirm_if( new((void*) view) View(x1) );
+ }
+
template <typename Monoid, typename T1, typename T2>
- static void construct(Monoid* monoid, View* view, const Monoid& m,
+ static void construct(Monoid* monoid, View* view, const Monoid& m,
const T1& x1, const T2& x2)
- { provisional( new ((void*)monoid) Monoid(m) ).confirm_if(
- new ((void*)view) View(x1, x2) ); }
-
+ {
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid(m) );
+ guard.confirm_if( new((void*) view) View(x1, x2) );
+ }
+
template <typename Monoid, typename T1, typename T2, typename T3>
- static void construct(Monoid* monoid, View* view, const Monoid& m,
+ static void construct(Monoid* monoid, View* view, const Monoid& m,
const T1& x1, const T2& x2, const T3& x3)
{
- provisional( new ((void*)monoid) Monoid(m) ).confirm_if(
- new ((void*)view) View(x1, x2, x3) );
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid(m) );
+ guard.confirm_if( new((void*) view) View(x1, x2, x3) );
}
-
- template <typename Monoid, typename T1, typename T2, typename T3,
+
+ template <typename Monoid, typename T1, typename T2, typename T3,
typename T4>
- static void construct(Monoid* monoid, View* view, const Monoid& m,
- const T1& x1, const T2& x2, const T3& x3,
+ static void construct(Monoid* monoid, View* view, const Monoid& m,
+ const T1& x1, const T2& x2, const T3& x3,
const T4& x4)
{
- provisional( new ((void*)monoid) Monoid(m) ).confirm_if(
- new ((void*)view) View(x1, x2, x3, x4) );
+ provisional_guard<Monoid> guard( new((void*) monoid) Monoid(m) );
+ guard.confirm_if( new((void*) view) View(x1, x2, x3, x4) );
}
-
+
//@}
-
+
//@}
};
@@ -385,8 +419,8 @@ public:
* from its view.
*
* A simple implementation of the monoid-view-reducer architecture would
- * distribute knowledge about the type and operations for the reduction
- * between the monoid and the view — the identity and reduction operations are
+ * distribute knowledge about the type and operations for the reduction
+ * between the monoid and the view - the identity and reduction operations are
* specified in the monoid, the reduction operations are implemented in the
* view, and the value type is specified in both the monoid and the view.
* This is inelegant.
@@ -396,10 +430,11 @@ public:
* customization of the monoid_with_view class itself is needed beyond
* instantiating it with an appropriate view class. (Customized subclasses of
* monoid_with_view may be needed for other reasons, such as to keep some
- * state for the reducer.) All of the Cilk predefined reducers use
+ * state for the reducer.) All of the Intel Cilk Plus predefined reducers use
* monoid_with_view or one of its subclasses.
- *
- * The view class `View` of a monoid_with_view must provide the following public definitions:
+ *
+ * The view class `View` of a monoid_with_view must provide the following
+ * public definitions:
*
* Definition | Meaning
* ---------------------------------|--------
@@ -420,20 +455,20 @@ public:
/** Should reducers created with this monoid be aligned?
*/
enum { align_reducer = Align };
-
+
/** Create the identity value.
*
- * Implements the monoid `identity` operation by using the @a View class’s
+ * Implements the monoid `identity` operation by using the @a View class's
* default constructor.
*
- * @param p A pointer to a block of raw memory large enough to hold a
+ * @param p A pointer to a block of raw memory large enough to hold a
* @p View object.
*/
- void identity(View* p) const { new ((void*)p) View(); }
-
+ void identity(View* p) const { new((void*) p) View(); }
+
/** Reduce the values of two views.
*
- * Implements the monoid `reduce` operation by calling the left view’s
+ * Implements the monoid `reduce` operation by calling the left view's
* `%reduce()` function with the right view as an operand.
*
* @param left The left operand of the reduce operation.
@@ -452,7 +487,7 @@ public:
* required by a @ref monoid_with_view (but not the identity constructor and
* reduce operation, which are inherently specific to a particular kind of
* reduction). It also defines the value access functions which will be called
- * by the corresponding @ref reducer functions. (It uses copy semantics for
+ * by the corresponding @ref reducer functions. (It uses copy semantics for
* the view_move_in() and view_move_out() functions, which is appropriate
* for simple scalar types, but not necessarily for more complex types like
* STL containers.
@@ -469,15 +504,15 @@ public:
/** Value type definition required by @ref monoid_with_view.
*/
typedef Type value_type;
-
+
/** Default constructor.
*/
- scalar_view() : m_value() {}
-
+ scalar_view() : m_value() {}
+
/** Value constructor.
*/
scalar_view(const Type& v) : m_value(v) {}
-
+
/** @name Value functions required by the reducer class.
*
* Note that the move in/out functions use simple assignment semantics.
@@ -499,12 +534,16 @@ public:
/** Get the value of the view.
*/
Type const& view_get_value() const { return m_value; }
-
+
+ /** Type returned by view_get_value.
+ */
+ typedef Type const& return_type_for_get_value;
+
/** Get a reference to the value contained in the view. For legacy
* reducer support only.
*/
Type & view_get_reference() { return m_value; }
-
+
/** Get a reference to the value contained in the view. For legacy
* reducer support only.
*/
@@ -517,18 +556,18 @@ public:
*
* Some types allow their values to be _moved_ as an alternative to copying.
* Moving a value may be much faster than copying it, but may leave the value
- * of the move’s source undefined. Consider the `swap` operation provided by
+ * of the move's source undefined. Consider the `swap` operation provided by
* many STL container classes:
*
* list<T> x, y;
* x = y; // Copy
* x.swap(y); // Move
*
- * The assignment _copies_ the value of `y` into `x` in time linear in the
+ * The assignment _copies_ the value of `y` into `x` in time linear in the
* size of `y`, leaving `y` unchanged. The `swap` _moves_ the value of `y`
* into `x` in constant time, but it also moves the value of `x` into `y`,
* potentially leaving `y` undefined.
- *
+ *
* A move_in_wrapper simply wraps a pointer to an object. It is created by a
* call to cilk::move_in(). Passing a move_in_wrapper to a view constructor
* (actually, passing it to a reducer constructor, which passes it to the
@@ -538,18 +577,18 @@ public:
*
* A view class exercises this option by defining a _move-in constructor_,
* i.e., a constructor with a move_in_wrapper parameter. The constructor calls
- * the wrapper’s `value()` function to get a reference to its pointed-to
+ * the wrapper's `value()` function to get a reference to its pointed-to
* value, and can then use that reference in a move operation.
*
* A move_in_wrapper also has an implicit conversion to its pointed-to value,
- * so if a view class does not define a move-in constructor, its ordinary
+ * so if a view class does not define a move-in constructor, its ordinary
* value constructor will be called with the wrapped value. For example, an
* @ref ReducersAdd "op_add" view does not have a move-in constructor, so
*
* int x;
* reducer< op_add<int> > xr(move_in(x));
*
- * will simply call the `op_add_view(const int &)` constructor. But an
+ * will simply call the `op_add_view(const int &)` constructor. But an
* @ref ReducersList "op_list_append" view does have a move-in constructor,
* so
*
@@ -573,19 +612,19 @@ class move_in_wrapper
{
Type *m_pointer;
public:
-
+
/** Constructor that captures the address of its argument. This is almost
* always called from the @ref move_in function.
*/
explicit move_in_wrapper(Type& ref) : m_pointer(&ref) { }
-
+
/** Implicit conversion to the wrapped value. This allows a move_in_wrapper
* to be used where a value of the wrapped type is expected, in which case
* the wrapper is completely transparent.
*/
operator Type&() const { return *m_pointer; }
-
- /** Get a reference to the pointed-to value. This has the same effect as
+
+ /** Get a reference to the pointed-to value. This has the same effect as
* the implicit conversion, but makes the intent clearer in a move-in
* constructor.
*/
@@ -594,7 +633,7 @@ public:
/** Function to create a move_in_wrapper for a value.
*
- * @tparam Type The type of the argument, which will be the `type` of the
+ * @tparam Type The type of the argument, which will be the `type` of the
* created wrapper.
*
* @see move_in_wrapper
@@ -608,9 +647,9 @@ move_in_wrapper<Type> move_in(Type& ref)
/** @copydoc move_in(Type&)
*
* @note Applying a function that is explicitly specified as modifying its
- * argument to a const argument is obviously an irrational thing to
+ * argument to a const argument is obviously an irrational thing to
* do. This move_in() variant is just provided to allow calling a
- * move-in constructor with a function return value, which the
+ * move-in constructor with a function return value, which the
* language treats as a const. Using it for any other purpose will
* probably end in tears.
*/
@@ -622,37 +661,37 @@ move_in_wrapper<Type> move_in(const Type& ref)
/** Wrapper class to allow implicit downcasts to reducer subclasses.
*
- * The Cilk library contains a collection of reducer wrapper classes which
- * were created before the `cilk::reducer<Monoid>` style was developed. For
+ * The Intel Cilk Plus library contains a collection of reducer wrapper classes which
+ * were created before the `cilk::reducer<Monoid>` style was developed. For
* example, `cilk::reducer_opadd<Type>` provided essentially the same
- * functionality that is now provided by
- * `cilk::reducer< cilk::op_add<Type> >`. These legacy reducer classes are
- * deprecated, but still supported, and they have been reimplemented as
+ * functionality that is now provided by
+ * `cilk::reducer< cilk::op_add<Type> >`. These legacy reducer classes are
+ * deprecated, but still supported, and they have been reimplemented as
* subclasses of the corresponding `cilk::reducer` classes. For example:
*
* template <class T>
* reducer_opadd<T> : public reducer< op_add<T> > { ... };
*
- * This reimplementation allows transparent conversion between legacy and
- * new reducers. That is, a `reducer<op_add>*` or `reducer<op_add>&` can be
- * used anywhere that a `reducer_opadd*` or `reducer_opadd&` is expected,
- * and vice versa.
+ * This reimplementation allows transparent conversion between legacy and
+ * new reducers. That is, a `reducer<op_add>*` or `reducer<op_add>&` can be
+ * used anywhere that a `reducer_opadd*` or `reducer_opadd&` is expected,
+ * and vice versa.
*
- * The conversion from the legacy reducer to the new reducer is just an
- * up-cast, which is provided for free by C++. The conversion from the new
- * reducer to the legacy reducer is a down-cast, though, which requires an
+ * The conversion from the legacy reducer to the new reducer is just an
+ * up-cast, which is provided for free by C++. The conversion from the new
+ * reducer to the legacy reducer is a down-cast, though, which requires an
* explicit conversion member function in the `reducer` class. The challenge
* is to define a function in the reducer template class which will convert
- * each cilk::reducer specialization to the corresponding legacy reducer,
+ * each cilk::reducer specialization to the corresponding legacy reducer,
* if there is one.
*
* The trick is in the legacy_reducer_downcast template class, which provides
* a mapping from `cilk::reducer` specializations to legacy reducer classes.
- * `reducer<Monoid>` has a conversion function to convert itself to
+ * `reducer<Monoid>` has a conversion function to convert itself to
* `legacy_reducer_downcast< reducer<Monoid> >::%type`. By default,
* `legacy_reducer_downcast<Reducer>::%type` is just a trivial subclass of
* `Reducer`, which is uninteresting, but a reducer with a legacy counterpart
- * will have a specialization of `legacy_reducer_downcast` whose `type` is
+ * will have a specialization of `legacy_reducer_downcast` whose `type` is
* the corresponding legacy reducer. For example:
*
* template <typename Type>
@@ -662,16 +701,17 @@ move_in_wrapper<Type> move_in(const Type& ref)
* };
*
*
- * @tparam Reducer The new-style reducer class whose corresponding legacy reducer class
- * is `type`, if there is such a legacy reducer class.
+ * @tparam Reducer The new-style reducer class whose corresponding legacy
+ * reducer class is `type`, if there is such a legacy reducer
+ * class.
*/
template <typename Reducer>
struct legacy_reducer_downcast
{
/** The related legacy reducer class.
*
- * By default, this is just a trivial subclass of Reducer, but it can be
- * overridden in the specialization of legacy_reducer_downcast for
+ * By default, this is just a trivial subclass of Reducer, but it can be
+ * overridden in the specialization of legacy_reducer_downcast for
* a reducer that has a corresponding legacy reducers.
*/
struct type : Reducer { };
@@ -684,21 +724,51 @@ namespace internal {
template <typename Value, typename View>
struct reducer_set_get
{
- static View theView; // Declared but not defined
-
- // sizeof(notchar) is guaranteed larger than 1
+ // sizeof(notchar) != sizeof(char)
struct notchar { char x[2]; };
- // check_for_ref returns char if 'get_value' returns by value and notchar
- // if 'get_value' returns by reference.
- static char check_for_ref(Value, ...);
- static notchar check_for_ref(Value&, int);
+ // `does_view_define_return_type_for_get_value(View*)` returns `char` if
+ // `View` defines `return_type_for_get_value`, and `notchar` if it doesn't.
+
+ template <typename T>
+ struct using_type {};
+
+ template <typename T>
+ static char does_view_define_return_type_for_get_value(
+ using_type<typename T::return_type_for_get_value>*);
- enum { GET_VALUE_BY_VALUE =
- (1 == sizeof(check_for_ref(theView.view_get_value(), 0))) } ;
+ template <typename T>
+ static notchar does_view_define_return_type_for_get_value(...);
- typedef typename condition<GET_VALUE_BY_VALUE,
- Value, const Value&>::type get_value_type;
+ // `VIEW_DOES_DEFINE_RETURN_TYPE_FOR_GET_VALUE` is true if `View` defines
+ // `return_type_for_get_value`.
+
+ enum { VIEW_DOES_DEFINE_RETURN_TYPE_FOR_GET_VALUE =
+ sizeof( does_view_define_return_type_for_get_value<View>(0) )
+ == sizeof(char) } ;
+
+ // `return_type_for_get_value` is `View::return_type_for_get_value`
+ // if it is defined, and just `Value` otherwise.
+
+ template <typename InnerView, bool ViewDoesDefineReturnTypeForGetValue>
+ struct return_type_for_view_get_value {
+ typedef Value type;
+ };
+
+ template <typename InnerView>
+ struct return_type_for_view_get_value<InnerView, true> {
+ typedef typename InnerView::return_type_for_get_value type;
+ };
+
+public:
+
+ typedef
+ typename
+ return_type_for_view_get_value<
+ View,
+ VIEW_DOES_DEFINE_RETURN_TYPE_FOR_GET_VALUE
+ >::type
+ return_type_for_get_value;
static void move_in(View& view, Value& v) { view.view_move_in(v); }
static void move_out(View& view, Value& v) { view.view_move_out(v); }
@@ -706,21 +776,23 @@ struct reducer_set_get
static void set_value(View& view, const Value& v)
{ view.view_set_value(v); }
- static get_value_type get_value(const View& view)
+ static return_type_for_get_value get_value(const View& view)
{ return view.view_get_value(); }
};
template <typename Value>
struct reducer_set_get<Value, Value>
{
- typedef const Value& get_value_type;
+ typedef const Value& return_type_for_get_value;
static void move_in(Value& view, Value& v) { view = v; }
static void move_out(Value& view, Value& v) { v = view; }
- static void set_value(Value& view, const Value& v) { view = v; }
+ static void set_value(Value& view, const Value& v)
+ { view = v; }
- static get_value_type get_value(const Value& view) { return view; }
+ static return_type_for_get_value get_value(const Value& view)
+ { return view; }
};
/// @endcond
@@ -728,7 +800,7 @@ struct reducer_set_get<Value, Value>
/** Base class defining the data layout that is common to all reducers.
*/
-template <typename Monoid>
+template <typename Monoid>
class reducer_base {
typedef typename Monoid::view_type view_type;
@@ -746,20 +818,20 @@ class reducer_base {
// Used for sanity checking at destruction.
//
void* m_initialThis;
-
+
// The leftmost view comes next. It is defined in the derived
// reducer_content class.
-
+
/** @name C-callable wrappers for the C++-coded monoid dispatch functions.
*/
//@{
-
+
static void reduce_wrapper(void* r, void* lhs, void* rhs);
static void identity_wrapper(void* r, void* view);
static void destroy_wrapper(void* r, void* view);
static void* allocate_wrapper(void* r, __STDNS size_t bytes);
static void deallocate_wrapper(void* r, void* view);
-
+
//@}
protected:
@@ -768,7 +840,7 @@ protected:
*
* @param leftmost The address of the leftmost view in the reducer.
*/
- reducer_base(char* leftmost)
+ reducer_base(char* leftmost)
{
static const cilk_c_monoid c_monoid_initializer = {
(cilk_c_reducer_reduce_fn_t) &reduce_wrapper,
@@ -783,10 +855,10 @@ protected:
m_base.__view_offset = (char*)leftmost - (char*)this;
m_base.__view_size = sizeof(view_type);
m_initialThis = this;
-
+
__cilkrts_hyper_create(&m_base);
}
-
+
/** Destructor.
*/
__CILKRTS_STRAND_STALE(~reducer_base())
@@ -794,7 +866,7 @@ protected:
// Make sure we haven't been memcopy'd or corrupted
__CILKRTS_ASSERT(
this == m_initialThis ||
- // Allow for a layout bug that may put the initialThis field one
+ // Allow for a layout bug that may put the initialThis field one
// word later in 1.0 reducers than in 0.9 and 1.1 reducers.
this == *(&m_initialThis + 1)
);
@@ -803,63 +875,63 @@ protected:
/** Monoid data member.
*
- * @return A pointer to the reducer’s monoid data member.
+ * @return A pointer to the reducer's monoid data member.
*/
Monoid* monoid_ptr() { return &m_monoid.object(); }
/** Leftmost view data member.
*
- * @return A pointer to the reducer’s leftmost view data member.
+ * @return A pointer to the reducer's leftmost view data member.
*
- * @note This function returns the address of the *leftmost* view,
- * which is unique for the lifetime of the reducer. It is
- * intended to be used in constructors and destructors.
- * Use the reducer::view() function to access the per-strand
+ * @note This function returns the address of the *leftmost* view,
+ * which is unique for the lifetime of the reducer. It is
+ * intended to be used in constructors and destructors.
+ * Use the reducer::view() function to access the per-strand
* view instance.
*/
- view_type* leftmost_ptr()
+ view_type* leftmost_ptr()
{
char* view_addr = (char*)this + m_base.__view_offset;
return reinterpret_cast<view_type*>(view_addr);
}
-
+
public:
/** @name Access the current view.
*
- * These functions return a reference to the instance of the reducer’s
+ * These functions return a reference to the instance of the reducer's
* view that was created for the current strand of a parallel computation
- * (and create it if it doesn’t already exist). Note the difference from
+ * (and create it if it doesn't already exist). Note the difference from
* the (private) leftmost_ptr() function, which returns a pointer to the
* _leftmost_ view, which is the same in all strands.
*/
//@{
-
+
/** Per-strand view instance.
*
* @return A reference to the per-strand view instance.
*/
- view_type& view()
+ view_type& view()
{
- return *static_cast<view_type *>(__cilkrts_hyper_lookup(&m_base));
+ return *static_cast<view_type *>(__cilkrts_hyper_lookup(&m_base));
}
-
+
/** @copydoc view()
*/
- const view_type& view() const
- {
- return const_cast<reducer_base*>(this)->view();
+ const view_type& view() const
+ {
+ return const_cast<reducer_base*>(this)->view();
}
-
+
//@}
-
+
/** Initial view pointer field.
*
* @internal
*
* @return a reference to the m_initialThis field.
*
- * @note This function is provided for “white-box” testing of the
+ * @note This function is provided for "white-box" testing of the
* reducer layout code. There is never any reason for user code
* to call it.
*/
@@ -905,7 +977,7 @@ void reducer_base<Monoid>::deallocate_wrapper(void* r, void* view)
/** Base class defining the data members of a reducer.
*
- * @tparam Aligned The `m_view` data member, and therefore the entire
+ * @tparam Aligned The `m_view` data member, and therefore the entire
* structure, are cache-line aligned if this parameter
* is `true'.
*/
@@ -918,12 +990,12 @@ template <typename Monoid>
class reducer_content<Monoid, true> : public reducer_base<Monoid>
{
typedef typename Monoid::view_type view_type;
-
+
// The leftmost view is defined as raw bytes. It will be constructed
- // by the monoid `construct` function. It is cache-aligned, which
+ // by the monoid `construct` function. It is cache-aligned, which
// will push it into a new cache line. Furthermore, its alignment causes
- // the reducer as a whole to be cache-aligned, which makes the reducer
- // size a multiple of a cache line. Since there is nothing in the reducer
+ // the reducer as a whole to be cache-aligned, which makes the reducer
+ // size a multiple of a cache line. Since there is nothing in the reducer
// after the view, all this means that the leftmost view gets one or more
// cache lines all to itself, which prevents false sharing.
//
@@ -936,7 +1008,7 @@ class reducer_content<Monoid, true> : public reducer_base<Monoid>
*/
bool reducer_is_cache_aligned() const
{ return 0 == ((std::size_t) this & (__CILKRTS_CACHE_LINE__ - 1)); }
-
+
protected:
/** Constructor.
@@ -945,14 +1017,15 @@ protected:
{
#ifndef CILK_IGNORE_REDUCER_ALIGNMENT
assert(reducer_is_cache_aligned() &&
- "Reducer should be cache aligned. Please see comments following this assertion for explanation and fixes.");
+ "Reducer should be cache aligned. Please see comments following "
+ "this assertion for explanation and fixes.");
#endif
/* "REDUCER SHOULD BE CACHE ALIGNED" ASSERTION.
*
- * This Reducer class instantiation specifies cache-line alignment of the
+ * This Reducer class instantiation specifies cache-line alignment of the
* leftmost view field (and, implicitly, of the reducer itself). You got
* this assertion because a reducer with this class was allocated at a
- * non-cache-aligned address, probably because it was allocated on the
+ * non-cache-aligned address, probably because it was allocated on the
* heap with `new`. This can be a problem for two reasons:
*
* 1. If the leftmost view is not on a cache line by itself, there might
@@ -974,14 +1047,14 @@ protected:
*
* There are three ways that you can fix this assertion failure.
*
- * A. Rewrite your code to use the new-style `reducer< op_XXX<Type> >`
+ * A. Rewrite your code to use the new-style `reducer< op_XXX<Type> >`
* instead of the legacy `reducer_XXX<type>`. The new-style reducers
* are not declared to be cache-aligned, and will work properly if
* they are not cache-aligned.
*
* B. If you must allocate an old-style reducer or a structure containing
* a reducer on the heap, figure out how to align it correctly. The
- * suggested fix is to use `cilk::aligned_new()` and
+ * suggested fix is to use `cilk::aligned_new()` and
* `cilk::aligned_delete()` instead of `new` and `delete`, as follows:
*
* Type* ptr = cilk::aligned_new<Type>(constructor-arguments);
@@ -1003,7 +1076,7 @@ class reducer_content<Monoid, false> : public reducer_base<Monoid>
// Reserve space for the leftmost view. The view will be allocated at an
// aligned offset in this space at runtime, to guarantee that the view
- // will get one or more cache lines all to itself, to prevent false
+ // will get one or more cache lines all to itself, to prevent false
// sharing.
//
// The number of bytes to reserve is determined as follows:
@@ -1026,10 +1099,10 @@ class reducer_content<Monoid, false> : public reducer_base<Monoid>
protected:
/** Constructor. Find the first cache-aligned position in the reserved
- * area, and pass it to the base constructor as the leftmost view
+ * area, and pass it to the base constructor as the leftmost view
* address.
*/
- reducer_content() :
+ reducer_content() :
reducer_base<Monoid>(
(char*)( ((std::size_t)&m_leftmost + __CILKRTS_CACHE_LINE__ - 1)
& ~ (__CILKRTS_CACHE_LINE__ - 1) ) )
@@ -1056,8 +1129,9 @@ namespace stub {
* A reducer is instantiated on a Monoid. The Monoid provides the value
* type, associative reduce function, and identity for the reducer.
*
- * @tparam Monoid The monoid class that the reducer is instantiated on. It must model
- * the @ref reducers_monoid_concept "monoid concept".
+ * @tparam Monoid The monoid class that the reducer is instantiated on. It
+ * must model the @ref reducers_monoid_concept "monoid
+ * concept".
*
* @see @ref pagereducers
*/
@@ -1068,33 +1142,33 @@ class reducer : public internal::reducer_content<Monoid>
using base::monoid_ptr;
using base::leftmost_ptr;
public:
- typedef Monoid monoid_type; ///< The monoid type.
- typedef typename Monoid::value_type value_type; ///< The value type.
- typedef typename Monoid::view_type view_type; ///< The view type.
+ typedef Monoid monoid_type; ///< The monoid type.
+ typedef typename Monoid::value_type value_type; ///< The value type.
+ typedef typename Monoid::view_type view_type; ///< The view type.
private:
typedef internal::reducer_set_get<value_type, view_type> set_get;
-
+
reducer(const reducer&); ///< Disallow copying.
reducer& operator=(const reducer&); ///< Disallow assignment.
public:
-
+
/** @name Constructors
*
- * All reducer constructors call the static `construct()` function of the monoid class to
- * construct the reducer's monoid and leftmost view.
+ * All reducer constructors call the static `construct()` function of the
+ * monoid class to construct the reducer's monoid and leftmost view.
*
- * The reducer constructor arguments are simply passed through to the construct() function.
- * Thus, the constructor parameters accepted by a particular reducer class are determined
- * by its monoid class.
+ * The reducer constructor arguments are simply passed through to the
+ * construct() function. Thus, the constructor parameters accepted by a
+ * particular reducer class are determined by its monoid class.
*/
//@{
/** 0 – 6 const reference parameters.
*/
//@{
-
+
reducer()
{
monoid_type::construct(monoid_ptr(), leftmost_ptr());
@@ -1125,19 +1199,24 @@ class reducer : public internal::reducer_content<Monoid>
}
template <typename T1, typename T2, typename T3, typename T4, typename T5>
- reducer(const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5)
+ reducer(const T1& x1, const T2& x2, const T3& x3, const T4& x4,
+ const T5& x5)
{
- monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1, x2, x3, x4, x5);
+ monoid_type::construct(monoid_ptr(), leftmost_ptr(),
+ x1, x2, x3, x4, x5);
}
- template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
- reducer(const T1& x1, const T2& x2, const T3& x3, const T4& x4, const T5& x5, const T6& x6)
+ template <typename T1, typename T2, typename T3, typename T4,
+ typename T5, typename T6>
+ reducer(const T1& x1, const T2& x2, const T3& x3, const T4& x4,
+ const T5& x5, const T6& x6)
{
- monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1, x2, x3, x4, x5, x6);
+ monoid_type::construct(monoid_ptr(), leftmost_ptr(),
+ x1, x2, x3, x4, x5, x6);
}
-
+
//@}
-
+
/** 1 non-const reference parameter.
*/
//@{
@@ -1147,7 +1226,7 @@ class reducer : public internal::reducer_content<Monoid>
{
monoid_type::construct(monoid_ptr(), leftmost_ptr(), x1);
}
-
+
//@}
/** Destructor.
@@ -1164,29 +1243,29 @@ class reducer : public internal::reducer_content<Monoid>
* @return A reference to the monoid object belonging to this reducer.
*/
Monoid& monoid() { return *monoid_ptr(); }
-
- const Monoid& monoid() const
+
+ const Monoid& monoid() const
{ return const_cast<reducer*>(this)->monoid(); }
//@}
//@{
/** Access the current view.
*
- * Return a reference to the instance of the reducer’s view that was
+ * Return a reference to the instance of the reducer's view that was
* created for the current strand of a parallel computation (and create
- * it if it doesn’t already exist).
+ * it if it doesn't already exist).
*/
view_type& view() { return base::view(); }
const view_type& view() const { return base::view(); }
//@}
-
+
/** @name Dereference the reducer to get the view.
*
- * “Dereferencing” a reducer yields the view for the current strand. The
+ * "Dereferencing" a reducer yields the view for the current strand. The
* view, in turn, acts as a proxy for its contained value, exposing only
- * those operations which are consistent with the reducer’s monoid. Thus,
- * all modifications of the reducer’s accumulator variable are written as
+ * those operations which are consistent with the reducer's monoid. Thus,
+ * all modifications of the reducer's accumulator variable are written as
*
* *reducer OP ...
*
@@ -1194,7 +1273,7 @@ class reducer : public internal::reducer_content<Monoid>
*
* reducer->func(...)
*
- * (The permitted operations on a reducer’s accumulator are listed in the
+ * (The permitted operations on a reducer's accumulator are listed in the
* documentation for that particular kind of reducer.)
*
* @note `*r` is a synonym for `r.view()`. Recommended style is to use
@@ -1204,7 +1283,7 @@ class reducer : public internal::reducer_content<Monoid>
* call attention to the view itself.
*/
//@{
-
+
//@{
/** Dereference operator.
*
@@ -1222,12 +1301,12 @@ class reducer : public internal::reducer_content<Monoid>
view_type* operator->() { return &view(); }
view_type const* operator->() const { return &view(); }
//@}
-
+
//@{
/** Deprecated view access.
*
- * `r()` is a synonym for `*r` which was used with early versions of Cilk
- * reducers. `*r` is now the preferred usage.
+ * `r()` is a synonym for `*r` which was used with early versions of
+ * Intel Cilk Plus reducers. `*r` is now the preferred usage.
*
* @deprecated Use operator*() instead of operator()().
*
@@ -1236,9 +1315,9 @@ class reducer : public internal::reducer_content<Monoid>
view_type& operator()() { return view(); }
view_type const& operator()() const { return view(); }
//@}
-
+
//@}
-
+
/** @name Set and get the value.
*
* These functions are used to set an initial value for the reducer before
@@ -1247,25 +1326,25 @@ class reducer : public internal::reducer_content<Monoid>
*
* @note These functions are completely different from the view
* operations that are made available via operator*() and
- * operator->(), which are used to _modify_ the reducer’s value
+ * operator->(), which are used to _modify_ the reducer's value
* _during_ the reduction.
*
- * @warning These functions _can_ be called at any time, and in
+ * @warning These functions _can_ be called at any time, and in
* general, they will refer to the value contained in the view
* for the current strand. However, using them other than to
- * set the reduction’s initial value or get its final value
+ * set the reduction's initial value or get its final value
* will almost always result in undefined behavior.
*/
//@{
/** Move a value into the reducer.
*
- * This function is used to set the initial value of the reducer’s
+ * This function is used to set the initial value of the reducer's
* accumulator variable by either copying or _moving_ the value of @a obj
* into it. Moving a value can often be performed in constant time, even
* for large container objects, but has the side effect of leaving the
- * value of @a obj undefined. (See the description of the
- * @ref move_in_wrapper class for a discussion of moving values.)
+ * value of @a obj undefined. (See the description of the
+ * @ref move_in_wrapper class for a discussion of moving values.)
*
* @par Usage
* A move_in() call to initialize a reducer is often paired with a
@@ -1278,14 +1357,14 @@ class reducer : public internal::reducer_content<Monoid>
*
* @par Assumptions
* - You cannot assume either that this will function will copy its
- * value or that it will move it.
- * - You must assume that the value of @a obj will be undefined
- * after the call to move_in().
+ * value or that it will move it.
+ * - You must assume that the value of @a obj will be undefined
+ * after the call to move_in().
* - You can assume that move_in() will be at least as efficient as
* set_value(), and you should therefore prefer move_in() unless
* you need the value of @a obj to be unchanged after the call.
* (But you should usually prefer the move-in constructor over a
- * move_in() call — see the note below.)
+ * move_in() call - see the note below.)
*
* @note The behavior of a default constructor followed by move-in
* initialization:
@@ -1296,14 +1375,14 @@ class reducer : public internal::reducer_content<Monoid>
* @note is not necessarily the same as a move-in constructor:
*
* reducer<Type> xr(move_in(x));
- *
- * @note In particular, when @a Type is a container type with a
+ *
+ * @note In particular, when @a Type is a container type with a
* non-empty allocator, the move-in constructor will create the
* accumulator variable with the same allocator as the input
* argument @a x, while the default constructor will create the
* accumulator variable with a default allocator. The mismatch of
- * allocators in the latter case means that the input argument
- * @a x may have to be copied in linear time instead of being
+ * allocators in the latter case means that the input argument
+ * @a x may have to be copied in linear time instead of being
* moved in constant time.
*
* @note Best practice is to prefer the move-in constructor over the
@@ -1326,13 +1405,13 @@ class reducer : public internal::reducer_content<Monoid>
/** Move the value out of the reducer.
*
- * This function is used to retrieve the final value of the reducer’s
+ * This function is used to retrieve the final value of the reducer's
* accumulator variable by either copying or _moving_ the value of @a obj
* into it. Moving a value can often be performed in constant time, even
* for large container objects, but has the side effect of leaving the
- * value of the reducer’s accumulator variable undefined. (See the
- * description of the @ref move_in_wrapper class for a discussion of
- * moving values.)
+ * value of the reducer's accumulator variable undefined. (See the
+ * description of the @ref move_in_wrapper class for a discussion of
+ * moving values.)
*
* @par Usage
* A move_in() call to initialize a reducer is often paired with a
@@ -1345,15 +1424,15 @@ class reducer : public internal::reducer_content<Monoid>
*
* @par Assumptions
* - You cannot assume either that this will function will copy its
- * value or that it will move it.
- * - You must assume that the value of the reducer’s accumulator
+ * value or that it will move it.
+ * - You must assume that the value of the reducer's accumulator
* variable will be undefined after the call to move_out().
* - You can assume that move_out() will be at least as efficient as
* get_value(), and you should therefore prefer move_out() unless
* you need the accumulator variable to be preserved after the
* call.
*
- * @warning Calling this function other than to retrieve the final
+ * @warning Calling this function other than to retrieve the final
* value of a reduction will almost always result in undefined
* behavior.
*
@@ -1368,7 +1447,7 @@ class reducer : public internal::reducer_content<Monoid>
/** Set the value of the reducer.
*
- * This function sets the initial value of the reducer’s accumulator
+ * This function sets the initial value of the reducer's accumulator
* variable to the value of @a obj.
*
* @note The behavior of a default constructor followed by
@@ -1380,8 +1459,8 @@ class reducer : public internal::reducer_content<Monoid>
* @note is not necessarily the same as a value constructor:
*
* reducer<Type> xr(x);
- *
- * @note In particular, when @a Type is a container type with a
+ *
+ * @note In particular, when @a Type is a container type with a
* non-empty allocator, the value constructor will create the
* accumulator variable with the same allocator as the input
* argument @a x, while the default constructor will create the
@@ -1391,7 +1470,7 @@ class reducer : public internal::reducer_content<Monoid>
* for a reduction will almost always result in undefined
* behavior.
*
- * @param obj The object containing the value that will be copied into
+ * @param obj The object containing the value that will be copied into
* the reducer.
*
* @post The reducer contains a copy of the value in @a obj.
@@ -1402,10 +1481,10 @@ class reducer : public internal::reducer_content<Monoid>
/** Get the value of the reducer.
*
- * This function gets the final value of the reducer’s accumulator
+ * This function gets the final value of the reducer's accumulator
* variable.
*
- * @warning Calling this function other than to retrieve the final
+ * @warning Calling this function other than to retrieve the final
* value of a reduction will almost always result in undefined
* behavior.
*
@@ -1413,9 +1492,9 @@ class reducer : public internal::reducer_content<Monoid>
*
* @see move_out()
*/
- typename set_get::get_value_type get_value() const
+ typename set_get::return_type_for_get_value get_value() const
{ return set_get::get_value(view()); }
-
+
//@}
/** Implicit downcast to legacy reducer wrapper, if any.
@@ -1452,137 +1531,148 @@ using stub::reducer;
/** @page page_reducers_in_c Creating and Using Reducers in C
*
* @tableofcontents
- *
- * The Cilk runtime supports reducers written in C as well as in C++. The basic logic is the
- * same, but the implementation details are very different. The C++ reducer implementation uses
- * templates heavily to create very generic components. The C reducer implementation uses
- * macros, which are a much blunter instrument. The most immediate consequence is that the
- * monoid/view/reducer architecture is mostly implicit rather than explicit in C reducers.
- *
+ *
+ * The Intel Cilk Plus runtime supports reducers written in C as well as in C++. The
+ * basic logic is the same, but the implementation details are very
+ * different. The C++ reducer implementation uses templates heavily to create
+ * very generic components. The C reducer implementation uses macros, which
+ * are a much blunter instrument. The most immediate consequence is that the
+ * monoid/view/reducer architecture is mostly implicit rather than explicit
+ * in C reducers.
+ *
* @section reducers_c_overview Overview of Using Reducers in C
- *
+ *
* The basic usage pattern for C reducers is:
- *
+ *
* 1. Create and initialize a reducer object.
- * 2. Tell the Cilk runtime about the reducer.
+ * 2. Tell the Intel Cilk Plus runtime about the reducer.
* 3. Update the value contained in the reducer in a parallel computation.
- * 4. Tell the Cilk runtime that you are done with the reducer.
+ * 4. Tell the Intel Cilk Plus runtime that you are done with the reducer.
* 5. Retrieve the value from the reducer.
- *
+ *
* @subsection reducers_c_creation Creating and Initializing a C Reducer
- *
+ *
* The basic pattern for creating and initializing a reducer object in C is
- *
+ *
* CILK_C_DECLARE_REDUCER(value-type) reducer-name =
* CILK_C_INIT_REDUCER(value-type,
* reduce-function,
* identity-function,
* destroy-function,
* initial-value);
- *
- * This is simply an initialized definition of a variable named _reducer-name_. The
- * @ref CILK_C_DECLARE_REDUCER macro expands to an anonymous `struct` declaration for a reducer
- * object containing a view of type _value-type_, and the @ref CILK_C_INIT_REDUCER macro
- * expands to a struct initializer.
- *
+ *
+ * This is simply an initialized definition of a variable named
+ * _reducer-name_. The @ref CILK_C_DECLARE_REDUCER macro expands to an
+ * anonymous `struct` declaration for a reducer object containing a view of
+ * type _value-type_, and the @ref CILK_C_INIT_REDUCER macro expands to a
+ * struct initializer.
+ *
* @subsection reducers_c_reduce_func Reduce Functions
- *
- * The reduce function for a reducer is called when a parallel execution strand terminates, to
- * combine the values computed by the terminating strand and the strand to its left. It takes
- * three arguments:
- *
- * - `void* reducer` — the address of the reducer.
- * - `void* left` — the address of the value for the left strand.
- * - `void* right` — the address of the value for the right (terminating) strand.
- *
- * It must apply the reducer’s reduction operation to the `left` and `right` values, leaving
- * the result in the `left` value. The `right` value is undefined after the reduce function
- * call.
- *
+ *
+ * The reduce function for a reducer is called when a parallel execution
+ * strand terminates, to combine the values computed by the terminating
+ * strand and the strand to its left. It takes three arguments:
+ *
+ * - `void* reducer` - the address of the reducer.
+ * - `void* left` - the address of the value for the left strand.
+ * - `void* right` - the address of the value for the right (terminating)
+ * strand.
+ *
+ * It must apply the reducer's reduction operation to the `left` and `right`
+ * values, leaving the result in the `left` value. The `right` value is
+ * undefined after the reduce function call.
+ *
* @subsection reducers_c_identity_func Identity Functions
- *
- * The identity function for a reducer is called when a parallel execution strand begins, to
- * initialize its value to the reducer’s identity value. It takes two arguments:
- *
- * - `void* reducer` — the address of the reducer.
- * - `void* v` — the address of a freshly allocated block of memory of size
+ *
+ * The identity function for a reducer is called when a parallel execution
+ * strand begins, to initialize its value to the reducer's identity value. It
+ * takes two arguments:
+ *
+ * - `void* reducer` - the address of the reducer.
+ * - `void* v` - the address of a freshly allocated block of memory of size
* `sizeof(value-type)`.
- *
- * It must initialize the memory pointed to by `v` so that it contains the reducer’s identity
- * value.
- *
+ *
+ * It must initialize the memory pointed to by `v` so that it contains the
+ * reducer's identity value.
+ *
* @subsection reducers_c_destroy_func Destroy Functions
- *
- * The destroy function for a reducer is called when a parallel execution strand terminates, to
- * do any necessary cleanup before its value is deallocated. It takes two arguments:
- *
- * - `void* reducer` — the address of the reducer.
- * - `void* p` — the address of the value for the terminating strand.
- *
- * It must release any resources belonging to the value pointed to by `p`, to avoid a resource
- * leak when the memory containing the value is deallocated.
- *
- * The runtime function `__cilkrts_hyperobject_noop_destroy` can be used for the destructor
- * function if the reducer’s values do not need any cleanup.
- *
- * @subsection reducers_c_register Tell the Cilk Runtime About the Reducer
- *
- * Call the @ref CILK_C_REGISTER_REDUCER macro to register the reducer with the Cilk runtime:
- *
+ *
+ * The destroy function for a reducer is called when a parallel execution
+ * strand terminates, to do any necessary cleanup before its value is
+ * deallocated. It takes two arguments:
+ *
+ * - `void* reducer` - the address of the reducer.
+ * - `void* p` - the address of the value for the terminating strand.
+ *
+ * It must release any resources belonging to the value pointed to by `p`, to
+ * avoid a resource leak when the memory containing the value is deallocated.
+ *
+ * The runtime function `__cilkrts_hyperobject_noop_destroy` can be used for
+ * the destructor function if the reducer's values do not need any cleanup.
+ *
+ * @subsection reducers_c_register Tell the Intel Cilk Plus Runtime About the
+ * Reducer
+ *
+ * Call the @ref CILK_C_REGISTER_REDUCER macro to register the reducer with
+ * the Intel Cilk Plus runtime:
+ *
* CILK_C_REGISTER_REDUCER(reducer-name);
- *
- * The runtime will manage reducer values for all registered reducers when parallel execution
- * strands begin and end.
- *
+ *
+ * The runtime will manage reducer values for all registered reducers when
+ * parallel execution strands begin and end.
+ *
* @subsection reducers_c_update Update the Value Contained in the Reducer
- *
- * The @ref REDUCER_VIEW macro returns a reference to the reducer’s value for the current
- * parallel strand:
- *
+ *
+ * The @ref REDUCER_VIEW macro returns a reference to the reducer's value for
+ * the current parallel strand:
+ *
* REDUCER_VIEW(reducer-name) = REDUCER_VIEW(reducer-name) OP x;
- *
- * C++ reducer views restrict access to the wrapped value so that it can only be modified in
- * ways consistent with the reducer’s operation. No such protection is provided for C reducers.
- * It is
- * entirely the responsibility of the user to avoid modifying the value in any
- * inappropriate way.
- *
- * @subsection c_reducers_unregister Tell the Cilk Runtime That You Are Done with the Reducer
- *
- * When the parallel computation is complete, call the @ref CILK_C_UNREGISTER_REDUCER macro to
- * unregister the reducer with the Cilk runtime:
- *
+ *
+ * C++ reducer views restrict access to the wrapped value so that it can only
+ * be modified in ways consistent with the reducer's operation. No such
+ * protection is provided for C reducers. It is entirely the responsibility
+ * of the user to avoid modifying the value in any inappropriate way.
+ *
+ * @subsection c_reducers_unregister Tell the Intel Cilk Plus Runtime That You Are
+ * Done with the Reducer
+ *
+ * When the parallel computation is complete, call the @ref
+ * CILK_C_UNREGISTER_REDUCER macro to unregister the reducer with the
+ * Intel Cilk Plus runtime:
+ *
* CILK_C_UNREGISTER_REDUCER(reducer-name);
- *
+ *
* The runtime will stop managing reducer values for the reducer.
- *
+ *
* @subsection c_reducers_retrieve Retrieve the Value from the Reducer
- *
- * When the parallel computation is complete, use the @ref REDUCER_VIEW macro to retrieve the
- * final value computed by the reducer.
- *
- * @subsection reducers_c_example_custom Example — Creating and Using a Custom C Reducer
- *
+ *
+ * When the parallel computation is complete, use the @ref REDUCER_VIEW macro
+ * to retrieve the final value computed by the reducer.
+ *
+ * @subsection reducers_c_example_custom Example - Creating and Using a
+ * Custom C Reducer
+ *
* The `IntList` type represents a simple list of integers.
- *
+ *
* struct _intListNode {
* int value;
* _intListNode* next;
* } IntListNode;
* typedef struct { IntListNode* head; IntListNode* tail; } IntList;
- *
+ *
* // Initialize a list to be empty
* void IntList_init(IntList* list) { list->head = list->tail = 0; }
- *
+ *
* // Append an integer to the list
- * void IntList_append(IntList* list, int x)
- * {
+ * void IntList_append(IntList* list, int x)
+ * {
* IntListNode* node = (IntListNode*) malloc(sizeof(IntListNode));
* if (list->tail) list->tail->next = node; else list->head = node;
* list->tail = node;
* }
- *
- * // Append the right list to the left list, and leave the right list empty
+ *
+ * // Append the right list to the left list, and leave the right list
+ * // empty
* void IntList_concat(IntList* left, IntList* right)
* {
* if (left->head) {
@@ -1594,19 +1684,20 @@ using stub::reducer;
* }
* IntList_init(*right);
* }
- *
- * This code creates a reducer that supports creating an `IntList` by appending values to it.
- *
+ *
+ * This code creates a reducer that supports creating an `IntList` by
+ * appending values to it.
+ *
* void identity_IntList(void* reducer, void* list)
* {
* IntList_init((IntList*)list);
* }
- *
+ *
* void reduce_IntList(void* reducer, void* left, void* right)
* {
* IntList_concat((IntList*)left, (IntList*)right);
* }
- *
+ *
* CILK_C_DECLARE_REDUCER(IntList) my_list_int_reducer =
* CILK_C_INIT_REDUCER(IntList,
* reduce_int_list,
@@ -1620,28 +1711,29 @@ using stub::reducer;
* IntList_append(&REDUCER_VIEW(my_int_list_reducer), a[i]);
* }
* CILK_C_UNREGISTER_REDUCER(my_int_list_reducer);
- *
+ *
* IntList result = REDUCER_VIEW(my_int_list_reducer);
*
* @section reducers_c_predefined Predefined C Reducers
*
- * Some of the predefined reducer classes in the Cilk library come with a set of predefined
- * macros to provide the same capabilities in C. In general, two macros are provided for each
- * predefined reducer family:
+ * Some of the predefined reducer classes in the Intel Cilk Plus library come with
+ * a set of predefined macros to provide the same capabilities in C.
+ * In general, two macros are provided for each predefined reducer family:
*
- * - `CILK_C_REDUCER_operation(reducer-name, type-name, initial-value)` — Declares a
- * reducer object named _reducer-name_ with initial value _initial-value_ to perform
- * a reduction using the _operation_ on values of the type specified by _type-name_.
- * This is the equivalent of the general code described in @ref reducers_c_creation :
+ * - `CILK_C_REDUCER_operation(reducer-name, type-name, initial-value)` -
+ * Declares a reducer object named _reducer-name_ with initial value
+ * _initial-value_ to perform a reduction using the _operation_ on values
+ * of the type specified by _type-name_. This is the equivalent of the
+ * general code described in @ref reducers_c_creation :
*
* CILK_C_DECLARE_REDUCER(type) reducer-name =
* CILK_C_INIT_REDUCER(type, ..., initial-value);
*
- * where _type_ is the C type corresponding to _type_name_. See @ref reducers_c_type_names
- * below for the _type-names_ that you can use.
+ * where _type_ is the C type corresponding to _type_name_. See @ref
+ * reducers_c_type_names below for the _type-names_ that you can use.
*
- * - `CILK_C_REDUCER_operation_TYPE(type-name)` — Expands to the `typedef` name for the type
- * of the reducer object declared by
+ * - `CILK_C_REDUCER_operation_TYPE(type-name)` - Expands to the `typedef`
+ * name for the type of the reducer object declared by
* `CILK_C_REDUCER_operation(reducer-name, type-name, initial-value)`.
*
* See @ref reducers_c_example_predefined.
@@ -1651,22 +1743,23 @@ using stub::reducer;
* | Operation | Name | Documentation |
* |-------------------|---------------|-------------------------------|
* | addition | `OPADD` | @ref ReducersAdd |
- * | bitwise and | `OPAND` | @ref ReducersAnd |
- * | bitwise or | `OPOR` | @ref ReducersOr |
- * | bitwise xor | `OPXOR` | @ref ReducersXor |
+ * | bitwise AND | `OPAND` | @ref ReducersAnd |
+ * | bitwise OR | `OPOR` | @ref ReducersOr |
+ * | bitwise XOR | `OPXOR` | @ref ReducersXor |
* | multiplication | `OPMUL` | @ref ReducersMul |
* | minimum | `MIN` | @ref ReducersMinMax |
* | minimum & index | `MIN_INDEX` | @ref ReducersMinMax |
- * | maximum | `MIN` | @ref ReducersMinMax |
- * | maximum & index | `MIN_INDEX` | @ref ReducersMinMax |
- *
+ * | maximum | `MAX` | @ref ReducersMinMax |
+ * | maximum & index | `MAX_INDEX` | @ref ReducersMinMax |
+ *
* @subsection reducers_c_type_names Numeric Type Names
- *
- * The type and function names created by the C reducer definition macros incorporate both the
- * reducer kind (`opadd`, `opxor`, etc.) and the value type of the reducer (`int`, `double`,
- * etc.). The value type is represented by a _numeric type name_ string. The types supported
- * in C reducers, and their corresponding numeric type names, are given in the following table:
- *
+ *
+ * The type and function names created by the C reducer definition macros
+ * incorporate both the reducer kind (`opadd`, `opxor`, etc.) and the value
+ * type of the reducer (`int`, `double`, etc.). The value type is represented
+ * by a _numeric type name_ string. The types supported in C reducers, and
+ * their corresponding numeric type names, are given in the following table:
+ *
* | Type | Numeric Type Name |
* |-----------------------|-------------------------------|
* | `char` | `char` |
@@ -1685,8 +1778,9 @@ using stub::reducer;
* | `float` | `float` |
* | `double` | `double` |
* | `long double` | `longdouble` |
- *
- * @subsection reducers_c_example_predefined Example — Using a Predefined C Reducer
+ *
+ * @subsection reducers_c_example_predefined Example - Using a Predefined C
+ * Reducer
*
* To compute the sum of all the values in an array of `unsigned int`:
*
@@ -1699,7 +1793,7 @@ using stub::reducer;
* printf("The sum is %u\n", REDUCER_VIEW(sum));
*/
-
+
/** @name C language reducer macros
*
* These macros are used to declare and work with reducers in C code.
@@ -1712,7 +1806,8 @@ using stub::reducer;
/** @name Compound identifier macros.
*
- * These macros are used to construct an identifier by concatenating two or three identifiers.
+ * These macros are used to construct an identifier by concatenating two or
+ * three identifiers.
*/
//@{
@@ -1730,7 +1825,7 @@ using stub::reducer;
//@}
-/** Compiler-specific keyword for the “type of” operator.
+/** Compiler-specific keyword for the "type of" operator.
*/
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
# define _Typeof __typeof__
@@ -1738,15 +1833,16 @@ using stub::reducer;
/** @name Predefined reducer function declaration macros.
*
- * These macros are used to create the function headers for the identity, reduction,
- * and destructor functions for a builtin reducer family. The macro can be followed by
- * a semicolon to create a declaration, or by a brace-enclosed body to create a definition.
+ * These macros are used to create the function headers for the identity,
+ * reduction, and destructor functions for a builtin reducer family. The
+ * macro can be followed by a semicolon to create a declaration, or by a
+ * brace-enclosed body to create a definition.
*/
//@{
/** Create an identity function header.
*
- * @note The name of the function’s value pointer parameter will always be `v`.
+ * @note The name of the function's value pointer parameter will always be `v`.
*
* @param name The reducer family name.
* @param tn The type name.
@@ -1758,8 +1854,9 @@ using stub::reducer;
*
* @param name The reducer family name.
* @param tn The type name.
- * @param l The name to use for the function’s left value pointer parameter.
- * @param r The name to use for the function’s right value pointer parameter.
+ * @param l The name to use for the function's left value pointer parameter.
+ * @param r The name to use for the function's right value pointer
+ * parameter.
*/
#define __CILKRTS_DECLARE_REDUCER_REDUCE(name,tn,l,r) CILK_EXPORT \
void __CILKRTS_MKIDENT3(name,_reduce_,tn)(void* key, void* l, void* r)
@@ -1768,7 +1865,7 @@ using stub::reducer;
*
* @param name The reducer family name.
* @param tn The type name.
- * @param p The name to use for the function’s value pointer parameter.
+ * @param p The name to use for the function's value pointer parameter.
*/
#define __CILKRTS_DECLARE_REDUCER_DESTROY(name,tn,p) CILK_EXPORT \
void __CILKRTS_MKIDENT3(name,_destroy_,tn)(void* key, void* p)
@@ -1784,8 +1881,8 @@ using stub::reducer;
/** Declaration of a C reducer structure type.
*
- * This macro expands into an anonymous structure declaration for a C reducer structure
- * which contains a @a Type value. For example:
+ * This macro expands into an anonymous structure declaration for a C reducer
+ * structure which contains a @a Type value. For example:
*
* CILK_C_DECLARE_REDUCER(int) my_add_int_reducer =
* CILK_C_INIT_REDUCER(int, …);
@@ -1801,27 +1898,30 @@ using stub::reducer;
/** Initializer for a C reducer structure.
*
- * This macro expands into a brace-enclosed structure initializer for a C reducer structure
- * that was declared with `CILK_C_DECLARE_REDUCER(Type)`. For example:
+ * This macro expands into a brace-enclosed structure initializer for a C
+ * reducer structure that was declared with
+ * `CILK_C_DECLARE_REDUCER(Type)`. For example:
*
* CILK_C_DECLARE_REDUCER(int) my_add_int_reducer =
- * CILK_C_INIT_REDUCER(int,
- * add_int_reduce,
- * add_int_identity,
+ * CILK_C_INIT_REDUCER(int,
+ * add_int_reduce,
+ * add_int_identity,
* __cilkrts_hyperobject_noop_destroy,
* 0);
*
- * @param Type The type of the value contained in the reducer object. Must be the same as
- * the @a Type argument of the CILK_C_DECLARE_REDUCER macro call that created
- * the reducer.
- * @param Reduce The address of the @ref reducers_c_reduce_func "reduce function" for the
+ * @param Type The type of the value contained in the reducer object. Must
+ * be the same as the @a Type argument of the
+ * CILK_C_DECLARE_REDUCER macro call that created the
* reducer.
- * @param Identity The address of the @ref reducers_c_identity_func "identity function" for
- * the reducer.
- * @param Destroy The address of the @ref reducers_c_destroy_func "destroy function" for the
- * reducer.
- * @param ... The initial value for the reducer. (A single expression if @a Type is a
- * scalar type; a list of values if @a Type is a struct or array type.)
+ * @param Reduce The address of the @ref reducers_c_reduce_func
+ * "reduce function" for the reducer.
+ * @param Identity The address of the @ref reducers_c_identity_func
+ * "identity function" for the reducer.
+ * @param Destroy The address of the @ref reducers_c_destroy_func
+ * "destroy function" for the reducer.
+ * @param ... The initial value for the reducer. (A single expression if
+ * @a Type is a scalar type; a list of values if @a Type is a
+ * struct or array type.)
*
* @see @ref reducers_c_creation
*/
@@ -1840,10 +1940,10 @@ using stub::reducer;
, __VA_ARGS__ \
}
-/** Register a reducer with the Cilk runtime.
+/** Register a reducer with the Intel Cilk Plus runtime.
*
- * The runtime will manage reducer values for all registered reducers when parallel execution
- * strands begin and end. For example:
+ * The runtime will manage reducer values for all registered reducers when
+ * parallel execution strands begin and end. For example:
*
* CILK_C_REGISTER_REDUCER(my_add_int_reducer);
* cilk_for (int i = 0; i != n; ++i) {
@@ -1857,10 +1957,10 @@ using stub::reducer;
#define CILK_C_REGISTER_REDUCER(Expr) \
__cilkrts_hyper_create(&(Expr).__cilkrts_hyperbase)
-/** Unregister a reducer with the Cilk runtime.
+/** Unregister a reducer with the Intel Cilk Plus runtime.
*
- * The runtime will stop managing reducer values for a reducer after it is unregistered. For
- * example:
+ * The runtime will stop managing reducer values for a reducer after it is
+ * unregistered. For example:
*
* cilk_for (int i = 0; i != n; ++i) {
* …
@@ -1876,17 +1976,19 @@ using stub::reducer;
/** Get the current view for a reducer.
*
- * The `REDUCER_VIEW(reducer-name)` returns a reference to the reducer’s value for the
- * current parallel strand. This can be used to initialize thevalue of the reducer before it
- * is used, to modify the value of the reducer on the current parallel strand, or to retrieve
- * the final value of the reducer at the end of the parallel computation.
+ * The `REDUCER_VIEW(reducer-name)` returns a reference to the reducer's
+ * value for the current parallel strand. This can be used to initialize the
+ * value of the reducer before it is used, to modify the value of the reducer
+ * on the current parallel strand, or to retrieve the final value of the
+ * reducer at the end of the parallel computation.
*
* REDUCER_VIEW(my_add_int_reducer) = REDUCER_VIEW(my_add_int_reducer) + x;
*
- * @note C++ reducer views restrict access to the wrapped value so that it can only be
- * modified in ways consistent with the reducer’s operation. No such protection is provided
- * for C reducers. It is entirely the responsibility of the user to refrain from modifying the
- * value in any inappropriate way.
+ * @note C++ reducer views restrict access to the wrapped value so that it
+ * can only be modified in ways consistent with the reducer's operation. No
+ * such protection is provided for C reducers. It is entirely the
+ * responsibility of the user to refrain from modifying the value in any
+ * inappropriate way.
*
* @param Expr The reducer whose value is to be returned.
*
diff --git a/libcilkrts/include/cilk/reducer_file.h b/libcilkrts/include/cilk/reducer_file.h
index 75af994e9d4..a372cee7cda 100644
--- a/libcilkrts/include/cilk/reducer_file.h
+++ b/libcilkrts/include/cilk/reducer_file.h
@@ -1,9 +1,7 @@
/*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -18,7 +16,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -31,6 +28,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
*/
diff --git a/libcilkrts/include/cilk/reducer_list.h b/libcilkrts/include/cilk/reducer_list.h
index fc0be1e03d3..80204af1d9e 100644
--- a/libcilkrts/include/cilk/reducer_list.h
+++ b/libcilkrts/include/cilk/reducer_list.h
@@ -1,10 +1,8 @@
/* reducer_list.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,12 +29,26 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_list.h
*
- * @brief Defines classes for doing parallel list creation by appending or
- * prepending.
+ * @brief Defines classes for parallel list creation by appending or
+ * prepending reducers.
*
* @ingroup ReducersList
*
@@ -52,19 +63,19 @@
/** @defgroup ReducersList List Reducers
*
- * List append and prepend reducers allow the creation of a standard list by
+ * List-append and list-prepend reducers create standard lists by
* concatenating a set of lists or values in parallel.
*
* @ingroup Reducers
*
- * You should be familiar with @ref pagereducers "Cilk reducers", described in
- * file `reducers.md`, and particularly with @ref reducers_using, before trying
- * to use the information in this file.
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers"
+ * (from file `reducers.md`) and particularly with @ref reducers_using, before
+ * trying to use the information in this file.
*
* @section redlist_usage Usage Example
*
* // Create a list containing the labels of the nodes of a tree in
- * // “inorder” (left subtree, root, right subtree).
+ * // "inorder" (left subtree, root, right subtree).
*
* struct Tree { Tree* left; Tree* right; string label; ... };
*
@@ -72,8 +83,8 @@
* cilk::reducer< cilk::op_list_append<string> > xr(cilk::move_in(x));
* collect_labels(tree, xr);
* xr.move_out(x);
- *
- * void collect_labels(Tree* node,
+ *
+ * void collect_labels(Tree* node,
* cilk::reducer< cilk::op_list_append<string> >& xr)
* {
* if (node) {
@@ -88,39 +99,39 @@
*
* @subsection redlist_monoid_values Value Set
*
- * The value set of a list reducer is the set of values of the class
- * `std::list<Type, Allocator>`, which we refer to as “the reducer’s list
- * type”.
+ * The __value set__ of a list reducer is the set of values of the class
+ * `std::list<Type, Allocator>`, which we refer to as the reducer's _list
+ * type_.
*
* @subsection redlist_monoid_operator Operator
*
- * The operator of a list append reducer is defined as
+ * The operator of a list-append reducer is defined as
*
* x CAT y == (every element of x, followed by every element of y)
*
- * The operator of a list prepend reducer is defined as
+ * The operator of a list-prepend reducer is defined as
*
* x RCAT y == (every element of y, followed by every element of x)
*
* @subsection redlist_monoid_identity Identity
*
- * The identity value of a list reducer is the empty list, which is the value
+ * The identity value of a list reducer is the empty list, which is the value
* of the expression `std::list<Type, Allocator>([allocator])`.
*
* @section redlist_operations Operations
*
- * In the operation descriptions below, the type name `List` refers to the
- * reducer’s string type, `std::list<Type, Allocator>`.
+ * In the operation descriptions below, the type name `List` refers to the
+ * reducer's string type, `std::list<Type, Allocator>`.
*
* @subsection redlist_constructors Constructors
*
- * Any argument list which is valid for a `std::list` constructor is valid for
+ * Any argument list which is valid for a `std::list` constructor is valid for
* a list reducer constructor. The usual move-in constructor is also provided:
*
* reducer(move_in(List& variable))
*
- * A list reducer with no constructor arguments, or with only an allocator
- * argument, will initially contain the identity value, an empty list.
+ * A list reducer with no constructor arguments, or with only an allocator
+ * argument, will initially contain the identity value, an empty list.
*
* @subsection redlist_get_set Set and Get
*
@@ -131,19 +142,19 @@
*
* @subsection redlist_view_ops View Operations
*
- * The view of a list append reducer provides the following member functions:
+ * The view of a list-append reducer provides the following member functions:
*
- * void push_back(const Type& element)
- * void insert_back(List::size_type n, const Type& element)
+ * void push_back(const Type& element)
+ * void insert_back(List::size_type n, const Type& element)
* template <typename Iter> void insert_back(Iter first, Iter last)
* void splice_back(List& x)
* void splice_back(List& x, List::iterator i)
* void splice_back(List& x, List::iterator first, List::iterator last)
- *
- * The view of a list prepend reducer provides the following member functions:
*
- * void push_front(const Type& element)
- * void insert_front(List::size_type n, const Type& element)
+ * The view of a list-prepend reducer provides the following member functions:
+ *
+ * void push_front(const Type& element)
+ * void insert_front(List::size_type n, const Type& element)
* template <typename Iter> void insert_front(Iter first, Iter last)
* void splice_front(List& x)
* void splice_front(List& x, List::iterator i)
@@ -151,26 +162,26 @@
*
* The `push_back` and `push_front` functions are the same as the
* corresponding `std::list` functions. The `insert_back`, `splice_back`,
- * `insert_front`, and `splice_front` functions are the same as the
+ * `insert_front`, and `splice_front` functions are the same as the
* `std::list` `insert` and `splice` functions, with the first parameter
* fixed to the end or beginning of the list, respectively.
*
* @section redlist_performance Performance Considerations
*
- * An efficient reducer requires that combining the values of two views (using
+ * An efficient reducer requires that combining the values of two views (using
* the view `reduce()` function) be a constant-time operations. Two lists can
* be merged in constant time using the `splice()` function if they have the
* same allocator. Therefore, the lists for new views are created (by the view
* identity constructor) using the same allocator as the list that was created
* when the reducer was constructed.
*
- * The performance of adding elements to a list reducer depends on the view
+ * The performance of adding elements to a list reducer depends on the view
* operations that are used:
*
* * The `push` functions add a single element to the list, and therefore
* take constant time.
* * An `insert` function that inserts _N_ elements adds each of them
- * individually, and therefore takes _O(N)_ time.
+ * individually, and therefore takes _O(N)_ time.
* * A `splice` function that inserts _N_ elements just adjusts a couple of
* pointers, and therefore takes constant time, _if the splice is from a
* list with the same allocator as the reducer_. Otherwise, it is
@@ -183,7 +194,7 @@
* The reducer `move_in` and `move_out` functions do a constant-time `swap` if
* the variable has the same allocator as the reducer, and a linear-time copy
* otherwise.
- *
+ *
* Note that the allocator of a list reducer is determined when the reducer is
* constructed. The following two examples may have very different behavior:
*
@@ -199,16 +210,16 @@
* reducer2.move_out(a_list);
*
* * `reducer1` will be constructed with the same allocator as `a_list`,
- * because the list was was specified in the constructor. The `move_in`
- * and`move_out` can therefore be done with a `swap` in constant time.
+ * because the list was specified in the constructor. The `move_in`
+ * and `move_out` can therefore be done with a `swap` in constant time.
* * `reducer2` will be constructed with a _default_ allocator,
- * “`Allocator()`”, which may or may not be the same as the allocator of
+ * "`Allocator()`", which may or may not be the same as the allocator of
* `a_list`. Therefore, the `move_in` and `move_out` may have to be done
* with a copy in _O(N)_ time.
- *
+ *
* (All instances of an allocator type with no internal state (like
- * `std::allocator`) are “the same”. You only need to worry about the “same
- * allocator” issue when you create list reducers with custom allocator types.)
+ * `std::allocator`) are "the same". You only need to worry about the "same
+ * allocator" issue when you create list reducers with custom allocator types.)
*
* @section redlist_types Type and Operator Requirements
*
@@ -223,11 +234,11 @@ namespace internal {
/** @ingroup ReducersList */
//@{
-/** Base class for list append and prepend view classes.
+/** Base class for list-append and prepend view classes.
*
* @note This class provides the definitions that are required for a class
* that will be used as the parameter of a @ref list_monoid_base
- * specialization.
+ * specialization.
*
* @tparam Type The list element type (not the list type).
* @tparam Allocator The list's allocator class.
@@ -250,31 +261,31 @@ public:
/** @name Monoid support.
*/
//@{
-
+
/// Required by @ref monoid_with_view
typedef list_type value_type;
/// Required by @ref list_monoid_base
Allocator get_allocator() const
- {
- return m_value.get_allocator();
+ {
+ return m_value.get_allocator();
}
-
+
//@}
-
-
+
+
/** @name Constructors.
*/
//@{
-
+
/// Standard list constructor.
explicit list_view_base(const Allocator& a = Allocator()) : m_value(a) {}
explicit list_view_base(
- typename list_type::size_type n,
- const Type& value = Type(),
+ typename list_type::size_type n,
+ const Type& value = Type(),
const Allocator& a = Allocator() ) : m_value(n, value, a) {}
- template <typename Iter>
- list_view_base(Iter first, Iter last, const Allocator& a = Allocator()) :
+ template <typename Iter>
+ list_view_base(Iter first, Iter last, const Allocator& a = Allocator()) :
m_value(first, last, a) {}
list_view_base(const list_type& list) : m_value(list) {}
@@ -284,13 +295,13 @@ public:
{
m_value.swap(w.value());
}
-
+
//@}
-
+
/** @name Reducer support.
*/
//@{
-
+
/// Required by reducer::move_in()
void view_move_in(value_type& v)
{
@@ -302,7 +313,7 @@ public:
m_value = v;
v.clear();
}
-
+
/// Required by reducer::move_out()
void view_move_out(value_type& v)
{
@@ -314,43 +325,46 @@ public:
v = m_value;
m_value.clear();
}
-
+
/// Required by reducer::set_value()
void view_set_value(const value_type& v) { m_value = v; }
/// Required by reducer::get_value()
value_type const& view_get_value() const { return m_value; }
-
+
+ /// Type returned by view_get_value.
+ typedef value_type const& return_type_for_get_value;
+
// Required by legacy wrapper get_reference()
value_type & view_get_reference() { return m_value; }
value_type const& view_get_reference() const { return m_value; }
-
+
//@}
};
-/** Base class for list append and prepend monoid classes.
+/** Base class for list-append and prepend monoid classes.
*
* The key to efficient reducers is that the `identity` operation, which
* creates a new per-strand view, and the `reduce` operation, which combines
* two per-strand views, must be constant-time operations. Two lists can be
* concatenated in constant time only if they have the same allocator.
* Therefore, all the per-strand list accumulator variables must be created
- * with the same allocator as the leftmost view list.
+ * with the same allocator as the leftmost view list.
*
* This means that a list reduction monoid must have a copy of the allocator
- * of the leftmost view’s list, so that it can use it in the `identity`
+ * of the leftmost view's list, so that it can use it in the `identity`
* operation. This, in turn, requires that list reduction monoids have a
* specialized `construct()` function, which constructs the leftmost view
- * before the monoid, and then passes the leftmost view’s allocator to the
+ * before the monoid, and then passes the leftmost view's allocator to the
* monoid constructor.
*
- * @tparam View The list append or prepend view class.
+ * @tparam View The list-append or prepend view class.
* @tparam Align If `false` (the default), reducers instantiated on this
- * monoid will be naturally aligned (the Cilk library 1.0
+ * monoid will be naturally aligned (the Intel Cilk Plus library 1.0
* behavior). If `true`, reducers instantiated on this monoid
- * will be cache-aligned for binary compatibility with
- * reducers in Cilk library version 0.9.
+ * will be cache-aligned for binary compatibility with
+ * reducers in Intel Cilk Plus library version 0.9.
*
* @see ReducersList
* @see list_view_base
@@ -360,15 +374,15 @@ class list_monoid_base : public monoid_with_view<View, Align>
{
typedef typename View::value_type list_type;
typedef typename list_type::allocator_type allocator_type;
+ typedef provisional_guard<View> view_guard;
+
allocator_type m_allocator;
-
- using monoid_base<list_type, View>::provisional;
-
+
public:
/** Constructor.
*
- * There is no default constructor for list monoids, because the allocator
+ * There is no default constructor for list monoids, because the allocator
* must always be specified.
*
* @param allocator The list allocator to be used when
@@ -377,7 +391,7 @@ public:
list_monoid_base(const allocator_type& allocator = allocator_type()) :
m_allocator(allocator) {}
- /** Create an identity view.
+ /** Creates an identity view.
*
* List view identity constructors take the list allocator as an argument.
*
@@ -385,12 +399,12 @@ public:
* will be constructed.
*/
void identity(View *v) const { ::new((void*) v) View(m_allocator); }
-
+
/** @name construct functions
*
- * All `construct()` functions first construct the leftmost view, using
+ * All `construct()` functions first construct the leftmost view, using
* the optional @a x1, @a x2, and @a x3 arguments that were passed in from
- * the reducer constructor. They then call the view’s `get_allocator()`
+ * the reducer constructor. They then call the view's `get_allocator()`
* function to get the list allocator from its contained list, and pass it
* to the monoid constructor.
*/
@@ -398,24 +412,33 @@ public:
template <typename Monoid>
static void construct(Monoid* monoid, View* view)
- { provisional( new ((void*)view) View() ).confirm_if(
- new ((void*)monoid) Monoid(view->get_allocator()) ); }
+ {
+ view_guard vg( new((void*) view) View() );
+ vg.confirm_if( new((void*) monoid) Monoid(view->get_allocator()) );
+ }
template <typename Monoid, typename T1>
static void construct(Monoid* monoid, View* view, const T1& x1)
- { provisional( new ((void*)view) View(x1) ).confirm_if(
- new ((void*)monoid) Monoid(view->get_allocator()) ); }
+ {
+ view_guard vg( new((void*) view) View(x1) );
+ vg.confirm_if( new((void*) monoid) Monoid(view->get_allocator()) );
+ }
template <typename Monoid, typename T1, typename T2>
- static void construct(Monoid* monoid, View* view, const T1& x1, const T2& x2)
- { provisional( new ((void*)view) View(x1, x2) ).confirm_if(
- new ((void*)monoid) Monoid(view->get_allocator()) ); }
+ static void construct(Monoid* monoid, View* view,
+ const T1& x1, const T2& x2)
+ {
+ view_guard vg( new((void*) view) View(x1, x2) );
+ vg.confirm_if( new((void*) monoid) Monoid(view->get_allocator()) );
+ }
template <typename Monoid, typename T1, typename T2, typename T3>
- static void construct(Monoid* monoid, View* view, const T1& x1, const T2& x2,
- const T3& x3)
- { provisional( new ((void*)view) View(x1, x2, x3) ).confirm_if(
- new ((void*)monoid) Monoid(view->get_allocator()) ); }
+ static void construct(Monoid* monoid, View* view,
+ const T1& x1, const T2& x2, const T3& x3)
+ {
+ view_guard vg( new((void*) view) View(x1, x2, x3) );
+ vg.confirm_if( new((void*) monoid) Monoid(view->get_allocator()) );
+ }
//@}
};
@@ -428,17 +451,17 @@ public:
/** @ingroup ReducersList */
//@{
-/** The list append reducer view class.
+/** The list-append reducer view class.
*
- * This is the view class for reducers created with
+ * This is the view class for reducers created with
* `cilk::reducer< cilk::op_list_append<Type, Allocator> >`. It holds the
* accumulator variable for the reduction, and allows only append operations
* to be performed on it.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `push_back` operation would be used in an expression like
- * `r->push_back(a)`, where `r` is a list append reducer variable.
+ * `r->push_back(a)`, where `r` is a list-append reducer variable.
*
* @tparam Type The list element type (not the list type).
* @tparam Allocator The list allocator type.
@@ -446,14 +469,14 @@ public:
* @see ReducersList
* @see op_list_append
*/
-template <class Type,
+template <class Type,
class Allocator = typename std::list<Type>::allocator_type>
class op_list_append_view : public internal::list_view_base<Type, Allocator>
{
typedef internal::list_view_base<Type, Allocator> base;
typedef std::list<Type, Allocator> list_type;
typedef typename list_type::iterator iterator;
-
+
iterator end() { return this->m_value.end(); }
public:
@@ -467,40 +490,40 @@ public:
* forms, as well as the reducer move_in constructor form.
*/
//@{
-
+
op_list_append_view() : base() {}
-
+
template <typename T1>
op_list_append_view(const T1& x1) : base(x1) {}
-
+
template <typename T1, typename T2>
op_list_append_view(const T1& x1, const T2& x2) : base(x1, x2) {}
-
+
template <typename T1, typename T2, typename T3>
- op_list_append_view(const T1& x1, const T2& x2, const T3& x3) :
+ op_list_append_view(const T1& x1, const T2& x2, const T3& x3) :
base(x1, x2, x3) {}
- //@}
+ //@}
/** @name View modifier operations.
*/
//@{
-
- /** Add an element at the end of the list.
+
+ /** Adds an element at the end of the list.
*
* This is equivalent to `list.push_back(element)`
*/
- void push_back(const Type& element)
+ void push_back(const Type& element)
{ this->m_value.push_back(element); }
- /** Insert elements at the end of the list.
+ /** Inserts elements at the end of the list.
*
* This is equivalent to `list.insert(list.end(), n, element)`
*/
- void insert_back(typename list_type::size_type n, const Type& element)
+ void insert_back(typename list_type::size_type n, const Type& element)
{ this->m_value.insert(end(), n, element); }
- /** Insert elements at the end of the list.
+ /** Inserts elements at the end of the list.
*
* This is equivalent to `list.insert(list.end(), first, last)`
*/
@@ -508,7 +531,7 @@ public:
void insert_back(Iter first, Iter last)
{ this->m_value.insert(end(), first, last); }
- /** Splice elements at the end of the list.
+ /** Splices elements at the end of the list.
*
* This is equivalent to `list.splice(list.end(), x)`
*/
@@ -521,7 +544,7 @@ public:
}
}
- /** Splice elements at the end of the list.
+ /** Splices elements at the end of the list.
*
* This is equivalent to `list.splice(list.end(), x, i)`
*/
@@ -534,7 +557,7 @@ public:
}
}
- /** Splice elements at the end of the list.
+ /** Splices elements at the end of the list.
*
* This is equivalent to `list.splice(list.end(), x, first, last)`
*/
@@ -546,14 +569,14 @@ public:
x.erase(first, last);
}
}
-
+
//@}
- /** Reduction operation.
+ /** Reduces the views of two strands.
*
* This function is invoked by the @ref op_list_append monoid to combine
- * the views of two strands when the right strand merges with the left
- * one. It appends the value contained in the right-strand view to the
+ * the views of two strands when the right strand merges with the left
+ * one. It appends the value contained in the right-strand view to the
* value contained in the left-strand view, and leaves the value in the
* right-strand view undefined.
*
@@ -572,17 +595,17 @@ public:
};
-/** The list prepend reducer view class.
+/** The list-prepend reducer view class.
*
- * This is the view class for reducers created with
+ * This is the view class for reducers created with
* `cilk::reducer< cilk::op_list_prepend<Type, Allocator> >`. It holds the
* accumulator variable for the reduction, and allows only prepend operations
* to be performed on it.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `push_front` operation would be used in an expression like
- * `r->push_front(a)`, where `r` is a list prepend reducer variable.
+ * `r->push_front(a)`, where `r` is a list-prepend reducer variable.
*
* @tparam Type The list element type (not the list type).
* @tparam Allocator The list allocator type.
@@ -590,14 +613,14 @@ public:
* @see ReducersList
* @see op_list_prepend
*/
-template <class Type,
+template <class Type,
class Allocator = typename std::list<Type>::allocator_type>
class op_list_prepend_view : public internal::list_view_base<Type, Allocator>
{
typedef internal::list_view_base<Type, Allocator> base;
typedef std::list<Type, Allocator> list_type;
typedef typename list_type::iterator iterator;
-
+
iterator begin() { return this->m_value.begin(); }
public:
@@ -612,40 +635,40 @@ public:
*
*/
//@{
-
+
op_list_prepend_view() : base() {}
-
+
template <typename T1>
op_list_prepend_view(const T1& x1) : base(x1) {}
-
+
template <typename T1, typename T2>
op_list_prepend_view(const T1& x1, const T2& x2) : base(x1, x2) {}
-
+
template <typename T1, typename T2, typename T3>
- op_list_prepend_view(const T1& x1, const T2& x2, const T3& x3) :
+ op_list_prepend_view(const T1& x1, const T2& x2, const T3& x3) :
base(x1, x2, x3) {}
- //@}
+ //@}
/** @name View modifier operations.
*/
//@{
-
- /** Add an element at the beginning of the list.
+
+ /** Adds an element at the beginning of the list.
*
* This is equivalent to `list.push_front(element)`
*/
- void push_front(const Type& element)
+ void push_front(const Type& element)
{ this->m_value.push_front(element); }
- /** Insert elements at the beginning of the list.
+ /** Inserts elements at the beginning of the list.
*
* This is equivalent to `list.insert(list.begin(), n, element)`
*/
- void insert_front(typename list_type::size_type n, const Type& element)
+ void insert_front(typename list_type::size_type n, const Type& element)
{ this->m_value.insert(begin(), n, element); }
- /** Insert elements at the beginning of the list.
+ /** Inserts elements at the beginning of the list.
*
* This is equivalent to `list.insert(list.begin(), first, last)`
*/
@@ -653,7 +676,7 @@ public:
void insert_front(Iter first, Iter last)
{ this->m_value.insert(begin(), first, last); }
- /** Splice elements at the beginning of the list.
+ /** Splices elements at the beginning of the list.
*
* This is equivalent to `list.splice(list.begin(), x)`
*/
@@ -666,7 +689,7 @@ public:
}
}
- /** Splice elements at the beginning of the list.
+ /** Splices elements at the beginning of the list.
*
* This is equivalent to `list.splice(list.begin(), x, i)`
*/
@@ -679,7 +702,7 @@ public:
}
}
- /** Splice elements at the beginning of the list.
+ /** Splices elements at the beginning of the list.
*
* This is equivalent to `list.splice(list.begin(), x, first, last)`
*/
@@ -691,14 +714,14 @@ public:
x.erase(first, last);
}
}
-
+
//@}
- /** Reduction operation.
+ /** Reduces the views of two strands.
*
* This function is invoked by the @ref op_list_prepend monoid to combine
- * the views of two strands when the right strand merges with the left
- * one. It prepends the value contained in the right-strand view to the
+ * the views of two strands when the right strand merges with the left
+ * one. It prepends the value contained in the right-strand view to the
* value contained in the left-strand view, and leaves the value in the
* right-strand view undefined.
*
@@ -722,8 +745,8 @@ public:
-/** Monoid class for list append reductions. Instantiate the cilk::reducer
- * template class with a op_list_append monoid to create a list append reducer
+/** Monoid class for list-append reductions. Instantiate the cilk::reducer
+ * template class with a op_list_append monoid to create a list-append reducer
* class. For example, to create a list of strings:
*
* cilk::reducer< cilk::op_list_append<std::string> > r;
@@ -731,29 +754,29 @@ public:
* @tparam Type The list element type (not the list type).
* @tparam Alloc The list allocator type.
* @tparam Align If `false` (the default), reducers instantiated on this
- * monoid will be naturally aligned (the Cilk library 1.0
+ * monoid will be naturally aligned (the Intel Cilk Plus library 1.0
* behavior). If `true`, reducers instantiated on this monoid
- * will be cache-aligned for binary compatibility with
- * reducers in Cilk library version 0.9.
+ * will be cache-aligned for binary compatibility with
+ * reducers in Intel Cilk Plus library version 0.9.
*
* @see ReducersList
* @see op_list_append_view
*/
-template <typename Type,
+template <typename Type,
typename Allocator = typename std::list<Type>::allocator_type,
bool Align = false>
-struct op_list_append :
- public internal::list_monoid_base<op_list_append_view<Type, Allocator>, Align>
+struct op_list_append :
+ public internal::list_monoid_base<op_list_append_view<Type, Allocator>, Align>
{
/// Construct with default allocator.
op_list_append() {}
/// Construct with specified allocator.
- op_list_append(const Allocator& alloc) :
+ op_list_append(const Allocator& alloc) :
internal::list_monoid_base<op_list_append_view<Type, Allocator>, Align>(alloc) {}
};
-/** Monoid class for list prepend reductions. Instantiate the cilk::reducer
- * template class with a op_list_prepend monoid to create a list prepend
+/** Monoid class for list-prepend reductions. Instantiate the cilk::reducer
+ * template class with a op_list_prepend monoid to create a list-prepend
* reducer class. For example, to create a list of strings:
*
* cilk::reducer< cilk::op_list_prepend<std::string> > r;
@@ -761,45 +784,45 @@ struct op_list_append :
* @tparam Type The list element type (not the list type).
* @tparam Alloc The list allocator type.
* @tparam Align If `false` (the default), reducers instantiated on this
- * monoid will be naturally aligned (the Cilk library 1.0
+ * monoid will be naturally aligned (the Intel Cilk Plus library 1.0
* behavior). If `true`, reducers instantiated on this monoid
- * will be cache-aligned for binary compatibility with
- * reducers in Cilk library version 0.9.
+ * will be cache-aligned for binary compatibility with
+ * reducers in Intel Cilk Plus library version 0.9.
*
* @see ReducersList
* @see op_list_prepend_view
*/
-template <typename Type,
+template <typename Type,
typename Allocator = typename std::list<Type>::allocator_type,
bool Align = false>
-struct op_list_prepend :
- public internal::list_monoid_base<op_list_prepend_view<Type, Allocator>, Align>
+struct op_list_prepend :
+ public internal::list_monoid_base<op_list_prepend_view<Type, Allocator>, Align>
{
/// Construct with default allocator.
op_list_prepend() {}
/// Construct with specified allocator.
- op_list_prepend(const Allocator& alloc) :
+ op_list_prepend(const Allocator& alloc) :
internal::list_monoid_base<op_list_prepend_view<Type, Allocator>, Align>(alloc) {}
};
-/** Deprecated list append reducer wrapper class.
+/** Deprecated list-append reducer wrapper class.
*
- * reducer_list_append is the same as
+ * reducer_list_append is the same as
* @ref reducer<@ref op_list_append>, except that reducer_list_append is a
- * proxy for the contained view, so that accumulator variable update
+ * proxy for the contained view, so that accumulator variable update
* operations can be applied directly to the reducer. For example, an element
* is appended to a `reducer<%op_list_append>` with `r->push_back(a)`, but an
* element can be appended to a `%reducer_list_append` with `r.push_back(a)`.
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_list_append.
+ * reducers rather than the old wrappers like reducer_list_append.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_list_append`
+ * @note Implicit conversions are provided between `%reducer_list_append`
* and `reducer<%op_list_append>`. This allows incremental code
* conversion: old code that used `%reducer_list_append` can pass a
* `%reducer_list_append` to a converted function that now expects a
@@ -814,20 +837,20 @@ struct op_list_prepend :
* @see ReducersList
*/
template <class Type, class Allocator = std::allocator<Type> >
-class reducer_list_append :
+class reducer_list_append :
public reducer<op_list_append<Type, Allocator, true> >
{
typedef reducer<op_list_append<Type, Allocator, true> > base;
using base::view;
public:
- /// The reducer’s list type.
+ /// The reducer's list type.
typedef typename base::value_type list_type;
- /// The list’s element type.
+ /// The list's element type.
typedef Type list_value_type;
- /// The reducer’s primitive component type.
+ /// The reducer's primitive component type.
typedef Type basic_value_type;
/// The monoid type.
@@ -836,18 +859,18 @@ public:
/** @name Constructors
*/
//@{
-
- /** Construct a reducer with an empty list.
+
+ /** Constructs a reducer with an empty list.
*/
reducer_list_append() {}
- /** Construct a reducer with a specified initial list value.
+ /** Constructs a reducer with a specified initial list value.
*/
- reducer_list_append(const std::list<Type, Allocator> &initial_value) :
+ reducer_list_append(const std::list<Type, Allocator> &initial_value) :
base(initial_value) {}
-
+
//@}
-
+
/** @name Forwarded functions
* @details Functions that update the contained accumulator variable are
@@ -856,25 +879,25 @@ public:
/// @copydoc op_list_append_view::push_back(const Type&)
void push_back(const Type& element) { view().push_back(element); }
-
+
//@}
- /** Allow mutable access to the list within the current view.
- *
+ /** Allows mutable access to the list within the current view.
+ *
* @warning If this method is called before the parallel calculation is
* complete, the list returned by this method will be a partial
* result.
- *
+ *
* @returns A mutable reference to the list within the current view.
*/
list_type &get_reference() { return view().view_get_reference(); }
- /** Allow read-only access to the list within the current view.
- *
+ /** Allows read-only access to the list within the current view.
+ *
* @warning If this method is called before the parallel calculation is
* complete, the list returned by this method will be a partial
* result.
- *
+ *
* @returns A const reference to the list within the current view.
*/
list_type const &get_reference() const { return view().view_get_reference(); }
@@ -903,12 +926,12 @@ public:
reducer_list_append* operator->() { return this; }
reducer_list_append const* operator->() const { return this; }
//@}
-
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
@@ -923,18 +946,18 @@ public:
}
operator const reducer< op_list_append<Type, Allocator, false> >& () const
{
- return *reinterpret_cast<
- const reducer< op_list_append<Type, Allocator, false> >*
+ return *reinterpret_cast<
+ const reducer< op_list_append<Type, Allocator, false> >*
>(this);
}
//@}
-
+
};
-/** Deprecated list prepend reducer wrapper class.
+/** Deprecated list-prepend reducer wrapper class.
*
- * reducer_list_prepend is the same as
+ * reducer_list_prepend is the same as
* @ref reducer<@ref op_list_prepend>, except that reducer_list_prepend is a
* proxy for the contained view, so that accumulator variable update operations
* can be applied directly to the reducer. For example, an element is prepended
@@ -942,13 +965,13 @@ public:
* prepended to a `reducer_list_prepend` with `r.push_back(a)`.
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_list_prepend.
+ * reducers rather than the old wrappers like reducer_list_prepend.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_list_prepend`
+ * @note Implicit conversions are provided between `%reducer_list_prepend`
* and `reducer<%op_list_prepend>`. This allows incremental code
* conversion: old code that used `%reducer_list_prepend` can pass a
* `%reducer_list_prepend` to a converted function that now expects a
@@ -963,22 +986,22 @@ public:
* @see ReducersList
*/
template <class Type, class Allocator = std::allocator<Type> >
-class reducer_list_prepend :
+class reducer_list_prepend :
public reducer<op_list_prepend<Type, Allocator, true> >
{
typedef reducer<op_list_prepend<Type, Allocator, true> > base;
using base::view;
public:
- /** The reducer’s list type.
+ /** The reducer's list type.
*/
typedef typename base::value_type list_type;
- /** The list’s element type.
+ /** The list's element type.
*/
typedef Type list_value_type;
- /** The reducer’s primitive component type.
+ /** The reducer's primitive component type.
*/
typedef Type basic_value_type;
@@ -989,45 +1012,45 @@ public:
/** @name Constructors
*/
//@{
-
- /** Construct a reducer with an empty list.
+
+ /** Constructs a reducer with an empty list.
*/
reducer_list_prepend() {}
- /** Construct a reducer with a specified initial list value.
+ /** Constructs a reducer with a specified initial list value.
*/
- reducer_list_prepend(const std::list<Type, Allocator> &initial_value) :
+ reducer_list_prepend(const std::list<Type, Allocator> &initial_value) :
base(initial_value) {}
-
+
//@}
/** @name Forwarded functions
* @details Functions that update the contained accumulator variable are
- * simply forwarded to the contained @ref op_and_view.
+ * simply forwarded to the contained @ref op_and_view.
*/
//@{
/// @copydoc op_list_prepend_view::push_front(const Type&)
void push_front(const Type& element) { view().push_front(element); }
-
+
//@}
- /** Allow mutable access to the list within the current view.
- *
+ /** Allows mutable access to the list within the current view.
+ *
* @warning If this method is called before the parallel calculation is
* complete, the list returned by this method will be a partial
* result.
- *
+ *
* @returns A mutable reference to the list within the current view.
*/
list_type &get_reference() { return view().view_get_reference(); }
- /** Allow read-only access to the list within the current view.
- *
+ /** Allows read-only access to the list within the current view.
+ *
* @warning If this method is called before the parallel calculation is
* complete, the list returned by this method will be a partial
* result.
- *
+ *
* @returns A const reference to the list within the current view.
*/
list_type const &get_reference() const { return view().view_get_reference(); }
@@ -1055,12 +1078,12 @@ public:
reducer_list_prepend* operator->() { return this; }
reducer_list_prepend const* operator->() const { return this; }
//@}
-
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
@@ -1070,17 +1093,17 @@ public:
operator reducer< op_list_prepend<Type, Allocator, false> >& ()
{
return *reinterpret_cast<
- reducer< op_list_prepend<Type, Allocator, false> >*
+ reducer< op_list_prepend<Type, Allocator, false> >*
>(this);
}
operator const reducer< op_list_prepend<Type, Allocator, false> >& () const
{
return *reinterpret_cast<
- const reducer< op_list_prepend<Type, Allocator, false> >*
+ const reducer< op_list_prepend<Type, Allocator, false> >*
>(this);
}
//@}
-
+
};
/// @cond internal
@@ -1105,7 +1128,7 @@ struct legacy_reducer_downcast<reducer<op_list_append<Type, Allocator, Align> >
*
* This specialization of the @ref legacy_reducer_downcast template class
* defined in reducer.h causes the
- * `reducer< op_list_prepend<Type, Allocator> >` class to have an
+ * `reducer< op_list_prepend<Type, Allocator> >` class to have an
* `operator reducer_list_prepend<Type, Allocator>& ()` conversion operator
* that statically downcasts the `reducer<op_list_prepend>` to the
* corresponding `reducer_list_prepend` type. (The reverse conversion, from
diff --git a/libcilkrts/include/cilk/reducer_max.h b/libcilkrts/include/cilk/reducer_max.h
index 3ba3a0bc8ac..3982cb11c2a 100644
--- a/libcilkrts/include/cilk/reducer_max.h
+++ b/libcilkrts/include/cilk/reducer_max.h
@@ -1,10 +1,8 @@
/* reducer_max.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_max.h
diff --git a/libcilkrts/include/cilk/reducer_min.h b/libcilkrts/include/cilk/reducer_min.h
index f5a3910850e..912979d7229 100644
--- a/libcilkrts/include/cilk/reducer_min.h
+++ b/libcilkrts/include/cilk/reducer_min.h
@@ -1,10 +1,8 @@
/* reducer_min.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_min.h
diff --git a/libcilkrts/include/cilk/reducer_min_max.h b/libcilkrts/include/cilk/reducer_min_max.h
index 7fe09e8d605..641aa823901 100644
--- a/libcilkrts/include/cilk/reducer_min_max.h
+++ b/libcilkrts/include/cilk/reducer_min_max.h
@@ -1,10 +1,8 @@
/* reducer_min_max.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_min_max.h
@@ -60,9 +71,9 @@
*
* @ingroup Reducers
*
- * You should be familiar with @ref pagereducers "Cilk reducers", described in
- * file `reducers.md`, and particularly with @ref reducers_using, before trying
- * to use the information in this file.
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file `reducers.md`, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
*
* @section redminmax_usage Usage Examples
*
@@ -88,12 +99,13 @@
* @subsection redminmax_monoid_values Value Set
*
* The value set of a minimum or maximum reducer is the set of values of
- * `Type`, possibly augmented with a special identity value which is greater
- * than (less than) any value of `Type`.
+ * `Type`, augmented with a "special identity value" which is not a value of
+ * `Type`, but which is defined to be greater than (less than) any value of
+ * `Type`.
*
* @subsection redminmax_monoid_operator Operator
*
- * In the most common case, the operator of a minimum reducer is defined as
+ * By default, the operator of a minimum reducer is defined as
*
* x MIN y == (x < y) ? x : y
*
@@ -112,7 +124,7 @@
* Min/max reducers are not limited to finding the minimum or maximum value
* determined by the `<` or `>` operator. In fact, all min/max reducers use a
* _comparator_, which is either a function or an object of a function class
- * that defines a [strict weak ordering]
+ * that defines a [strict weak ordering]
* (http://en.wikipedia.org/wiki/Strict_weak_ordering#Strict_weak_orderings)
* on a set of values. (This is exactly the same as the requirement for the
* comparison predicate for STL associative containers and sorting
@@ -121,8 +133,8 @@
* Just as with STL algorithms and containers, the comparator type parameter
* for min/max reducers is optional. If it is omitted, it defaults to
* `std::less`, which gives the behavior described in the previous section.
- * Using non-default comparators (anything other than `std::less`) with
- * min/max reducers is just like using them with STL containers and
+ * Using non-default comparators (anything other than `std::less`) with
+ * min/max reducers is just like using them with STL containers and
* algorithms.
*
* Taking comparator objects into account, the reduction operation `MIN` for a
@@ -130,45 +142,44 @@
*
* x MIN y == compare(x, y) ? x : y
*
- * where `compare()` is the reducer’s comparator. Similarly, the reduction
+ * where `compare()` is the reducer's comparator. Similarly, the reduction
* operation MAX for a maximum reducer is defined as
*
* x MAX y == compare(y, x) ? x : y
*
- * (If `compare(x, y) == x < y`, then `compare(y, x) == x > y`.)
+ * (If `compare(x, y) == x < y`, then `compare(y, x) == x > y`.)
*
* @subsection redminmax_monoid_identity Identity
*
- * The identity value of the reducer is the value which is greater than (less
- * than) any other value in the value set of the reducer. This is the
- * [“special identity value”](#redminmax_monoid_values) if the reducer has
- * one, or the largest (smallest) value in the value set otherwise.
+ * The identity value of a min/max reducer is its monoid's
+ * ["special identity value"](#redminmax_monoid_values), which is not a value
+ * of the reducer's data type. (See @ref redminmax_initial.)
*
* @section redminmax_index Value and Index Reducers
*
- * Min/max reducers come in two families. The _value_ reducers, using `op_min`
- * and `op_max` monoids, simply find the smallest or largest value from a set
- * of values. The _index_ reducers, using `op_min_index` and `op_max_index`
- * monoids, also record an index value associated with the first occurrence of
- * the smallest or largest value.
+ * Min/max reducers come in two families. The _value_ reducers, with the
+ * `op_min` and `op_max` monoids, simply find the smallest or largest value
+ * from a set of values. The _index_ reducers, with the `op_min_index` and
+ * `op_max_index` monoids, also record an index value associated with the
+ * first occurrence of the smallest or largest value.
*
* In the `%op_min_index` usage example [above](#redminmax_usage), the values
* are taken from an array, and the index of a value is the index of the array
* element it comes from. More generally, though, an index can be any sort of
* key which identifies a particular value in a collection of values. For
- * example, if the values were taken from the nodes of a tree, then the
- * “index” of a value might be a pointer to the node containing that value.
+ * example, if the values were taken from the nodes of a tree, then the
+ * "index" of a value might be a pointer to the node containing that value.
*
* A min/max index reducer is essentially the same as a min/max value reducer
- * whose value type is an (index, value) pair, and whose comparator ignores
+ * whose value type is an (index, value) pair, and whose comparator ignores
* the index part of the pair. (index, value) pairs are represented by
- * `std::pair<Index, Type>` objects. This has the consequence that wherever
- * the interface of a min/max value reducer has a `Type`, the interface of the
- * corresponding min/max index reducer has a `std::pair<Index, Type>`. (There
- * are convenience variants of the `reducer(Type)` constructor and the
+ * `std::pair<Index, Type>` objects. This has the consequence that wherever
+ * the interface of a min/max value reducer has a `Type`, the interface of a
+ * min/max index reducer has a `std::pair<Index, Type>`. (There are
+ * convenience variants of the `reducer(Type)` constructor and the
* `calc_min()`, `calc_max()`, `%min_of()`, and `%max_of()` functions that
- * take an index argument and a value argument instead of an index/value
- * pair.)
+ * take an index argument and a value argument instead of a single index/value
+ * pair argument.)
*
* @section redminmax_operations Operations
*
@@ -194,6 +205,12 @@
* reducer(const Index& index, const Type& value, const Compare& compare)
* reducer(move_in(std::pair<Index, Type>& variable), const Compare& compare)
*
+ * See the explanation of the following two constructors in
+ * @ref redminmax_index_vector.
+ *
+ * reducer(const Index& index)
+ * reducer(const Index& index, const Compare& compare)
+ *
* @subsection redminmax_get_set Set and Get
*
* r.set_value(const Type& value)
@@ -207,51 +224,101 @@
*
* @subsection redminmax_initial Initial Values and is_set()
*
- * A minimum or maximum reducer without a specified initial value, before any
- * MIN or MAX operation has been performed on it, represents the [identity
- * value](#redminmax_monoid_identity) of its monoid. For value reducers with a
- * numeric type and default comparator (`std::less`), this will be a well
- * defined value. For example,
- *
- * reducer< op_max<unsigned> > r1;
- * // r1.get_value() == 0
- *
- * reducer< op_min<float> > r2;
- * // r2.get_value() == std::numeric_limits<float>::infinity
- *
- * In other cases, though (index reducers, non-numeric types, or non-default
- * comparators), the actual identity value for the monoid may be unknown, or
- * it may not even be a value of the reducer’s type. For example, there is no
- * “largest string” to serve as the initial value for a
- * `reducer< op_min<std::string> >`. In these cases, the result of calling
- * `get_value()` is undefined.
- *
- * To avoid calling `get_value()` when its result is undefined, you can call
- * the view’s `is_set()` function, which will return true if the reducer
- * has a well-defined value — either because a MIN or MAX operation has been
- * performed, or because it had a well-defined initial value:
- *
- * reducer< op_max<unsigned> > r1;
- * // r1->is_set() == true
- * // r1.get_value() == 0
- *
- * reducer< op_min<std::string> > r2;
- * // r2->is_set() == false
- * // r2.get_value() is undefined
- * r2->calc_min("xyzzy");
- * // r2->is_set() == true
- * // r2.get_value() == "xyzzy"
- *
- * > Note: For an index reducer without a specified initial value, the
- * > initial value of the index is the default value of the `Index` type.
+ * The initial value of the leftmost view of a default-initialized min/max
+ * reducer, or of a non-leftmost view (created for a stolen parallel strand)
+ * is the special identity value, which is not a value of the reducer's value
+ * type.
+ *
+ * A view will have a real (non-identity) value if:
+ *
+ * - it is the leftmost view of a reducer that was constructed with an
+ * initial value, or
+ * - it was assigned a value with a call to `reducer.set_value()` or
+ * `reducer.move_in()`, or
+ * - it has been updated with a call to `reducer->calc_min()` or
+ * `reducer->calc_max()`, or
+ * - it has been updated with an assignment `*reducer = min_of(*reducer, x)`
+ * or `*reducer = max_of(*reducer, x)`.
+ *
+ * Calling `get_value()` or `move_out()` on a reducer whose view has the
+ * special identity value will yield an undefined result. The `is_set()`
+ * function can be used to test whether a view has the special identity value
+ * or a real value. If a reducer's current view has the special identity
+ * value, then `reducer()->is_set()` will return `false` (and
+ * `reducer.get_value()` will return an undefined value); if the view has a
+ * real value, them `reducer->is_set()` will return `true` and
+ * `reducer.get_value()` will return the value.
+ *
+ * @subsubsection redminmax_index_vector Special Issues with Min/Max Index Reducers
+ *
+ * The index portion of the computed index/value pair will be wrong in the
+ * following special case:
+ *
+ * - The reducer's value type is a simple numeric type.
+ * - The reducer uses the default comparator (`std::less<Type>`).
+ * - The reducer is updated at least once with a call to `calc_min()` or
+ * `calc_max()` or an assignment with `min_of()` or `max_of()`.
+ * - The value in _every_ update to the reducer is the maximum value of the
+ * value type (for a min_index reducer) or the minimum value of the value
+ * type (for a max_index reducer).
+ *
+ * In this case, `reducer.get_value().first` should be the index argument from
+ * the first reducer update, but it will actually be the default value of the
+ * `Index` type. Now, in the common case where the index type is an integer
+ * type and the reducer is finding the smallest or largest element in an
+ * array, the default value of the index type will be zero, which is the
+ * index of the first element in the array, so everything will work out:
+ *
+ * unsigned a[3] = {0, 0, 0};
+ * reducer< op_max_index<int, unsigned> > r;
+ * for (int i = 0; i < 3; ++i) r->calc_max(i, a[i]);
+ * // r.get_value() = (0, 0)
+ *
+ * However, it doesn't always work out so well:
+ *
+ * typedef std::map<std::string, unsigned> my_map;
+ * my_map a;
+ * a["first"] = 0;
+ * a["second"] = 0;
+ * a["third"] = 0;
+ * reducer< op_max_index<std::string, unsigned> > r;
+ * for (typename my_map::iterator i = a.begin(); i != a.end(); ++i)
+ * r.calc_max(i->first, i->second);
+ * // r.get_value() = ("", 0), should be ("first", 0)
+ *
+ * If you know that no data value is associated with the default index value,
+ * then you can treat the default index value as a flag meaning "use the index
+ * of the first data value." But suppose that you don't know whether there is
+ * an element in the map with index `""`. Then you won't know what to do when
+ * `r.get_value().first == ""`.
+ *
+ * As a workaround for this conundrum, you can specify an alternative
+ * "default" index value. Either provide an index argument, _but not a
+ * value argument_, to the reducer constructor:
+ *
+ * reducer< op_max_index<std::string, unsigned> >
+ * r(a.empty() ? std::string() : a.begin()->first);
+ *
+ * or specify the default index with the view `set_default_index()` function:
+ *
+ * reducer< op_max_index<std::string, unsigned> > r;
+ * if (!a.empty()) r->set_default_index(a.begin()->first);
+ *
+ * Note that setting a default index, unlike setting an initial value, does
+ * not mark the view as having a non-identity value:
+ *
+ * reducer< op_min_index<int, int> > r;
+ * r->set_default_index(-1);
+ * // r->is_set() = false
+ * // r.get_value() is undefined
*
* @subsection redminmax_view_ops View Operations
*
- * The basic reduction operation is `x = x MIN a` for a minimum reducer, or
+ * The basic reduction operation is `x = x MIN a` for a minimum reducer, or
* `x = x MAX a` for a maximum reducer. The basic syntax for these operations
* uses the `calc_min()` and `calc_max()` member functions of the view class.
- * An assignment syntax is also provided, using the %cilk::min_of() and
- * %cilk::max_of() global functions:
+ * An assignment syntax is also provided, using the `%cilk::min_of()` and
+ * `%cilk::max_of()` global functions:
*
* Class | Modifier | Assignment
* ---------------|---------------------|-----------
@@ -260,7 +327,7 @@
* `op_min_index` | `r->calc_min(i, x)` | `*r = min_of(*r, i, x)` or `*r = min_of(i, x, *r)`
* `op_max_index` | `r->calc_max(i, x)` | `*r = max_of(*r, i, x)` or `*r = max_of(i, x, *r)`
*
- * Wherever an “`i`, `x`” argument pair is shown in the table above, a single
+ * Wherever an "`i`, `x`" argument pair is shown in the table above, a single
* pair argument may be passed instead. For example:
*
* Index index;
@@ -272,7 +339,7 @@
* *r = min_of(*r, index, value);
* *r = min_of(*r, ind_val);
*
- * The `calc_min()` and `calc_max()` member functions return a reference to
+ * The `calc_min()` and `calc_max()` member functions return a reference to
* the view, so they can be chained:
*
* r->calc_max(x).calc_max(y).calc_max(z);
@@ -290,58 +357,48 @@
* *r = max_of(max_of(max_of(*r, x), y), z);
* *r = min_of(i, a[i], min_of(j, a[j], min_of(k, a[k], *r)));
*
- * @section redminmax_compatibility Compatibility Issues
- *
- * Most Cilk library reducers provide
- * * Binary compatibility between `reducer_KIND` reducers compiled with Cilk
- * library version 0.9 (distributed with Intel® C++ Composer XE version
- * 13.0 and earlier) and the same reducers compiled with Cilk library
- * version 1.0 and later.
- * * Transparent casting between references to `reducer<op_KIND>` and
- * `reducer_KIND`.
- *
- * This compatibility is not available in all cases for min/max reducers.
- * There are two areas of incompatibility.
+ * @section redminmax_compatibility Binary Compatibility Issues
+ *
+ * Most Intel Cilk Plus library reducers provide binary compatibility between
+ * `reducer_KIND` reducers compiled with Intel Cilk Plus library version 0.9
+ * (distributed with Intel® C++ Composer XE version 13.0 and earlier) and the
+ * ame reducers compiled with Intel Cilk Plus library version 1.0 and later.
+ *
+ * Because of implementation changes that were needed to allow vectorization
+ * of loops containing min/max reducers, this binary compatibility is _not_
+ * generally available for min/max reducers, either between Intel Cilk Plus library
+ * versions 0.9 and 1.0, or between versions 1.0 and 1.1. (Code compiled with
+ * different versions can be linked together safely, but min/max reducers in
+ * different library versions are in different namespaces, so reducer objects
+ * cannot be shared between them.)
+ *
+ * If this is an inconvenience, the simplest solution is just to recompile any
+ * existing code you may have that uses min/max reducers. If that is
+ * impossible, you can define the `CILK_LIBRARY_0_9_REDUCER_MINMAX` macro (on
+ * the compiler command line, or in your source code before including
+ * `reducer_min_max.h`) when compiling with the new library. This will cause
+ * it to generate numeric reducers that will be link-time and run-time
+ * compatible with the 0.9 library.
*
* @subsection redminmax_compatibility_stateful Non-empty Comparators
*
- * There is no way to provide binary compatibility between the 0.9 and 1.0
- * definitions of min/max reducers that use a non-empty comparator class or a
- * comparator function. (Empty comparator classes like `std::less` are not a
- * problem.)
- *
- * To avoid run-time surprises, the legacy `reducer_{min|max}[_index]` classes
- * have been coded in the 1.0 library so that they will not even compile when
- * instantiated with a non-empty comparator class.
- *
- * @subsection redminmax_compatibility_optimized Numeric Optimization
- *
- * Min/max reducers with a numeric value type and the default comparator can
- * be implemented slightly more efficiently than other min/max reducers.
- * However, the optimization is incompatible with the 0.9 library
- * implementation of min/max reducers.
- *
- * The default min/max reducers implementation in the 1.0 library uses this
- * numeric optimization. Code using legacy reducers compiled with the 1.0
- * library can be safely used in the same program as code compiled with the
- * 0.9 library, but classes compiled with the different Cilk libraries will be
- * defined in different namespaces.
- *
- * The simplest solution is just to recompile the code that was compiled with
- * the older version of Cilk. However, if this is impossible, you can define
- * the `CILK_LIBRARY_0_9_REDUCER_MINMAX` macro (on the compiler command line,
- * or in your source code before including `reducer_min_max.h`) when compiling
- * with the new library. This will cause it to generate numeric reducers that
- * will be less efficient, but will be fully compatible with previously
- * compiled code. (Note that this macro has no effect on [the non-empty
- * comparator incompatibility] (redminmax_compatibility_stateful).)
+ * The representation of min/max reducers with non-empty comparator objects or
+ * with comparator functions is so different in between the 0.9 and 1.1
+ * libraries that there is no way to make them binary compatible, even when
+ * compiling with `CILK_LIBRARY_0_9_REDUCER_MINMAX`. Therefore, the
+ * `reducer_{min|max}[_index]` wrapper classes have been coded in the 1.0 and
+ * later library so that they will not even compile when instantiated with a
+ * non-empty comparator class.
+ *
+ * This is not a problem when using an empty comparator class, such as the
+ * default `std::less`.
*
* @section redminmax_types Type Requirements
*
* `Type` and `Index` must be `Copy Constructible`, `Default Constructible`,
* and `Assignable`.
*
- * `Compare` must be `Copy Constructible` if the reducer is constructed with a
+ * `Compare` must be `Copy Constructible` if the reducer is constructed with a
* `compare` argument, and `Default Constructible` otherwise.
*
* The `Compare` function must induce a strict weak ordering on the elements
@@ -353,8 +410,8 @@
*
* Declaration | Type | Operation
* -----------------------------|-----------------------------------|----------
- * @ref CILK_C_REDUCER_MIN |@ref CILK_C_REDUCER_MIN_TYPE |@ref CILK_C_REDUCER_MIN_CALC
- * @ref CILK_C_REDUCER_MAX |@ref CILK_C_REDUCER_MAX_TYPE |@ref CILK_C_REDUCER_MAX_CALC
+ * @ref CILK_C_REDUCER_MIN |@ref CILK_C_REDUCER_MIN_TYPE |@ref CILK_C_REDUCER_MIN_CALC
+ * @ref CILK_C_REDUCER_MAX |@ref CILK_C_REDUCER_MAX_TYPE |@ref CILK_C_REDUCER_MAX_CALC
* @ref CILK_C_REDUCER_MIN_INDEX |@ref CILK_C_REDUCER_MIN_INDEX_TYPE |@ref CILK_C_REDUCER_MIN_INDEX_CALC
* @ref CILK_C_REDUCER_MAX_INDEX |@ref CILK_C_REDUCER_MAX_INDEX_TYPE |@ref CILK_C_REDUCER_MAX_INDEX_CALC
*
@@ -375,7 +432,7 @@
* CILK_C_REDUCER_MAX_INDEX_CALC(r, i, a[i]);
* }
* CILK_C_UNREGISTER_REDUCER(r);
- * printf("The largest value in a is %u at %d\n",
+ * printf("The largest value in a is %u at %d\n",
* REDUCER_VIEW (r).value, REDUCER_VIEW(r).index);
*
* See @ref reducers_c_predefined.
@@ -385,39 +442,39 @@ namespace cilk {
/** @defgroup ReducersMinMaxBinComp Binary compatibility
*
- * If the macro CILK_LIBRARY_0_9_REDUCER_MINMAX is defined, then we generate
+ * If the macro `CILK_LIBRARY_0_9_REDUCER_MINMAX` is defined, then we generate
* reducer code and data structures which are binary-compatible with code that
* was compiled with the old min/max wrapper definitions, so we want the
* mangled names of the legacy min/max reducer wrapper classes to be the
* same as the names produced by the old definitions.
*
- * Conversely, if the macro is not defined, then we generate binary-
- * incompatible code, so we want different mangled names, to make sure that
+ * Conversely, if the macro is not defined, then we generate binary-
+ * incompatible code, so we want different mangled names, to make sure that
* the linker does not allow new and old compiled legacy wrappers to be passed
* to one another. (Global variables are a different, and probably insoluble,
* problem.)
*
- * Similarly, min/max classes compiled with and without
- * CILK_LIBRARY_0_9_REDUCER_MINMAX are binary-incompatible, and must get
+ * Similarly, min/max classes compiled with and without
+ * CILK_LIBRARY_0_9_REDUCER_MINMAX are binary-incompatible, and must get
* different mangled names.
*
* The trick is, when compiling in normal (non-compatibility) mode, wrap
* everything in an extra namespace, and then `use` it into the top-level cilk
- * namespace. Then
+ * namespace. Then
*
* * Classes and functions compiled in normal mode will be in
* different namespaces from the same classes and functions compiled in
* compatibility mode.
- * * The legacy wrapper classes and functions will be in the same namespace
- * as the same classes and functions compiled with the0.9 library if and
- * only if the are compiled in compatibility mode.
+ * * The legacy wrapper classes and functions will be in the same namespace
+ * as the same classes and functions compiled with the 0.9 library if and
+ * only if they are compiled in compatibility mode.
*
* @ingroup ReducersMinMax
*/
-
+
#ifndef CILK_LIBRARY_0_9_REDUCER_MINMAX
-/** Namespace to wrap min/max reducer definitions when not compiling in “binary
- * compatibility” mode.
+/** Namespace to wrap min/max reducer definitions when not compiling in "binary
+ * compatibility" mode.
*
* By default, all of the min/max reducer definitions are defined in this
* namespace and then imported into namespace ::cilk, so that they do not
@@ -430,7 +487,7 @@ namespace cilk {
* @ingroup ReducersMinMaxBinComp
* @ingroup ReducersMinMax
*/
-namespace cilk_lib_1_0 {
+namespace cilk_lib_1_1 {
#endif
/** Namespace containing internal implementation classes and functions for
@@ -444,12 +501,12 @@ using ::cilk::internal::binary_functor;
using ::cilk::internal::typed_indirect_binary_function;
using ::cilk::internal::class_is_empty;
-/** @defgroup ReducersMinMaxIsSet The “is_set optimization”
+/** @defgroup ReducersMinMaxIsSet The "is_set optimization"
*
* The obvious definition of the identity value for a max or min reducer is as
- * the smallest (or largest) value of the value type. However, for an
+ * the smallest (or largest) value of the value type. However, for an
* arbitrary comparator and/or an arbitrary value type, the largest / smallest
- * value may not be known. It may not even be defined — what is the largest
+ * value may not be known. It may not even be defined - what is the largest
* string?
*
* Therefore, min/max reducers represent their value internally as a pair
@@ -463,41 +520,41 @@ using ::cilk::internal::class_is_empty;
* smallest and largest values. Testing `is_set` for every comparison is then
* unnecessary and wasteful.
*
- * The “is_set optimization” just means generating code that doesn’t use
- * `is_set` when it isn’t needed. It is implemented using two metaprogramming
+ * The "is_set optimization" just means generating code that doesn't use
+ * `is_set` when it isn't needed. It is implemented using two metaprogramming
* classes:
*
* - do_is_set_optimization tests whether the optimization is applicable.
* - identity_value gets the appropriate identity value for a type.
*
* The is_set optimization is the reason that min/max reducers compiled with
- * Cilk library 1.0 are binary-incompatible with the same reducers compiled
- * with library 0.9, and therefore the optimization is suppressed when
- * compiling in
- * ReducersMinMaxBinComp "binary compatibility mode".
- *
+ * Intel Cilk Plus library 1.0 are binary-incompatible with the same reducers
+ * compiled with library 0.9, and therefore the optimization is suppressed when
+ * compiling in
+ * ReducersMinMaxBinComp "binary compatibility mode".
+ *
* @ingroup ReducersMinMax
*/
-/** Test whether the ReducersMinMaxIsSet "is_set optimization" is
+/** Tests whether the ReducersMinMaxIsSet "is_set optimization" is
* applicable.
*
* The @ref do_is_set_optimization class is used to test whether the is_set
* optimization should be applied for a particular reducer. It is instantiated
- * with a value type and a comparator, and defines a boolean constant,
+ * with a value type and a comparator, and defines a boolean constant,
* `value`. Then `%do_is_set_optimization<Type, Comp>::%value` can be used as
* a boolean template parameter to control the specialization of another
* class.
*
- * In ReducersMinMaxBinComp "binary compatibility mode", when the
- * `CILK_LIBRARY_0_9_REDUCER_MINMAX` macro is defined, `value` will always
+ * In ReducersMinMaxBinComp "binary compatibility mode" (i.e., when the
+ * `CILK_LIBRARY_0_9_REDUCER_MINMAX` macro is defined), `value` will always
* be false.
*
* @tparam Type The value type for the reducer.
* @tparam Compare The comparator type for the reducer.
*
- * @result The `value` data member will be `true` if @a Type is a numeric
- * type, @a Compare is `std::less<Type>`, and
+ * @result The `value` data member will be `true` if @a Type is a numeric
+ * type, @a Compare is `std::less<Type>`, and
* `CILK_LIBRARY_0_9_REDUCER_MINMAX` is not defined.
*
* @see ReducersMinMaxIsSet
@@ -505,10 +562,10 @@ using ::cilk::internal::class_is_empty;
*
* @ingroup ReducersMinMaxIsSet
*/
-template < typename Type,
+template < typename Type,
typename Compare >
-struct do_is_set_optimization
-{
+struct do_is_set_optimization
+{
/// `True` if the is_set optimization should be applied to min/max reducers
/// with this value type and comparator; `false` otherwise.
static const bool value = false;
@@ -517,8 +574,8 @@ struct do_is_set_optimization
#ifndef CILK_LIBRARY_0_9_REDUCER_MINMAX
/// @cond
template <typename Type>
-struct do_is_set_optimization<Type, std::less<Type> >
-{
+struct do_is_set_optimization<Type, std::less<Type> >
+{
/// True in the special case where optimization is possible.
static const bool value = std::numeric_limits<Type>::is_specialized;
};
@@ -526,7 +583,7 @@ struct do_is_set_optimization<Type, std::less<Type> >
#endif
-/** Get the identity value when using the ReducersMinMaxIsSet
+/** Gets the identity value when using the ReducersMinMaxIsSet
* "is_set optimization".
*
* This class defines a function which assigns the appropriate identity value
@@ -534,7 +591,7 @@ struct do_is_set_optimization<Type, std::less<Type> >
*
* @tparam Type The value type for the reducer.
* @tparam Compare The comparator type for the reducer.
- * @tparam ForMax `true` to get the identity value for a max reducer (i.e.,
+ * @tparam ForMax `true` to get the identity value for a max reducer (i.e.,
* the smallest value of @a Type), `false` to get the identity
* value for a min reducer (i.e., the largest value of
* @a Type).
@@ -549,8 +606,8 @@ struct do_is_set_optimization<Type, std::less<Type> >
* @ingroup ReducersMinMaxIsSet
* @see @ref view_content
*/
-template < typename Type,
- typename Compare,
+template < typename Type,
+ typename Compare,
bool ForMax,
bool = std::numeric_limits<Type>::is_specialized,
bool = std::numeric_limits<Type>::has_infinity >
@@ -563,7 +620,7 @@ struct identity_value {
template <typename Type>
struct identity_value<Type, std::less<Type>, true, true, true> {
/// Floating max identity is negative infinity.
- static void set_identity(Type& id)
+ static void set_identity(Type& id)
{ id = -std::numeric_limits<Type>::infinity(); }
};
@@ -599,25 +656,25 @@ struct identity_value<Type, std::less<Type>, false, true, false> {
* max(x, y) == (x < y) ? y : x
* min(x, y) == (y < x) ? y : x == (x > y) ? y : x
*
- * More generally, if `c` is a predicate defining a `Strict Weak Ordering`,
+ * More generally, if `c` is a predicate defining a `Strict Weak Ordering`,
* and `c*(x, y) == c(y, x)`, then
*
* max(x, y, c) == c(x, y) ? y : x
* min(x, y, c) == c(y, x) ? y : x == c*(x, y) ? y : x == max(x, y, c*)
*
- * For any predicate `C` with argument type `T`, the template class
+ * For any predicate `C` with argument type `T`, the template class
* `%reverse_predicate<C, T>` defines a predicate which is identical to `C`,
* except that its arguments are reversed. Thus, for example, we could
* implement `%op_min_view<Type, Compare>` as
- * `%op_max_view<Type, %reverse_predicate<Compare, Type> >`.
- * (Actually, op_min_view and op_max_view are both implemented as subclasses
+ * `%op_max_view<Type, %reverse_predicate<Compare, Type> >`.
+ * (Actually, op_min_view and op_max_view are both implemented as subclasses
* of a common base class, view_base.)
*
* @note If `C` is an empty functor class, then `reverse_predicate(C)` will
* also be an empty functor class.
*
* @tparam Predicate The predicate whose arguments are to be reversed.
- * @tparam Argument @a Predicate’s argument type.
+ * @tparam Argument @a Predicate's argument type.
*
* @ingroup ReducersMinMax
*/
@@ -629,7 +686,7 @@ public:
/// Default constructor
reverse_predicate() : base() {}
/// Constructor with predicate object
- reverse_predicate(const Predicate& p) : base(p) {}
+ reverse_predicate(const Predicate& p) : base(p) {}
/// The reversed predicate operation
bool operator()(const Argument& x, const Argument& y) const
{ return base::operator()(y, x); }
@@ -638,7 +695,7 @@ public:
/** Class to represent the comparator for a min/max view class.
*
- * This class is intended to accomplish two objectives in the implementation
+ * This class is intended to accomplish two objectives in the implementation
* of min/max views.
*
* 1. To minimize data bloat, when we have a reducer with a non-stateless
@@ -646,24 +703,24 @@ public:
* in the monoid, and just call it from the views.
* 2. In ReducersMinMaxBinComp "binary compatibility mode", views for
* reducers with a stateless comparator must have the same content as in
- * Cilk library 0.9 — that is, they must contain only `value` and
+ * Intel Cilk Plus library 0.9 - that is, they must contain only `value` and
* `is_set` data members.
*
- * To achieve the first objective, we use the
+ * To achieve the first objective, we use the
* @ref internal::typed_indirect_binary_function class defined in
* metaprogramming.h to wrap a pointer to the actual comparator. If no
- * pointer is needed because the actual comparator is stateless, the
+ * pointer is needed because the actual comparator is stateless, the
* `typed_indirect_binary_function` class will be empty, too.
*
* To achieve the second objective, we make the
* `typed_indirect_binary_function` class a base class of the view rather than
- * a data member, so the “empty base class” rule will ensure no that no
+ * a data member, so the "empty base class" rule will ensure no that no
* additional space is allocated in the view unless it is needed.
*
* We could simply use typed_indirect_binary_function as the base class of the
* view, but this would mean writing comparisons as `(*this)(x, y)`, which is
* just weird. So, instead, we comparator_base as a subclass of
- * typed_indirect_binary_function which provides function `compare()`
+ * typed_indirect_binary_function which provides function `compare()`
* as a synonym for `operator()`.
*
* @tparam Type The value type of the comparator class.
@@ -679,13 +736,13 @@ class comparator_base : private typed_indirect_binary_function<Compare, Type, Ty
typedef typed_indirect_binary_function<Compare, Type, Type, bool> base;
protected:
comparator_base(const Compare* f) : base(f) {} ///< Constructor.
-
+
/// Comparison function.
bool compare(const Type& a, const Type& b) const
{
- return base::operator()(a, b);
+ return base::operator()(a, b);
}
-
+
/// Get the comparator pointer.
const Compare* compare_pointer() const { return base::pointer(); }
};
@@ -695,7 +752,7 @@ protected:
*
* @ingroup ReducersMinMax
*
- * Minimum and maximum reducer view classes inherit from a “view content”
+ * Minimum and maximum reducer view classes inherit from a "view content"
* class. The content class defines the actual data members for the view,
* and provides typedefs and member functions for accessing the data members
* as needed to support the view functionality.
@@ -708,31 +765,32 @@ protected:
*
* @note An obvious, and arguably simpler, encapsulation strategy would be
* to just let the `Type` of a min/max view be an (index, value) pair
- * structure for min_index and max_index reducers. Then all views
+ * structure for min_index and max_index reducers. Then all views
* would just have a `Type` data member and an `is_set` data member,
* and the comparator for min_index and max_index views could be
* customized to consider only the value component of the (index,
* value) `Type` pair. Unfortunately, this would break binary
* compatibility with reducer_max_index and reducer_min_index in
- * Cilk library 0.9, because the memory layout of an (index, value)
- * pair followed by a `bool` is different from the memory layout of an
- * index data member followed by a value data member followed by a
- * `bool` data member. The content class is designed to exactly
- * replicate the layout of the views in library 0.9 reducers.
+ * Intel Cilk Plus library 0.9, because the memory layout of an
+ * (index, value) pair followed by a `bool` is different from the
+ * memory layout of an index data member followed by a value data
+ * member followed by a `bool` data member. The content class is
+ * designed to exactly replicate the layout of the views in library 0.9
+ * reducers.
*
* A content class `C`, and its objects `c`, must define the following:
*
* Definition | Meaning
* ------------------------------------|--------
* `C::value_type` | A typedef for `Type` of the view. (A `std::pair<Index, Type>` for min_index and max_index views).
- * `C::comp_value_type` | A typedef for the type of value compared by the view’s `compare()` function.
+ * `C::comp_value_type` | A typedef for the type of value compared by the view's `compare()` function.
* `C()` | Constructs the content with the identity value.
* `C(const value_type&)` | Constructs the content with a specified value.
* `c.is_set()` | Returns true if the content has a known value.
- * `c.value()` | Returns the content’s value.
- * `c.set_value(const value_type&)` | Sets the content’s value. (The value becomes known.)
- * `c.comp_value()` | Returns a const reference to the value or component of the value that is to be compared by the view’s comparator.
- * `C::comp_value(const value_type&)` | Returns a const reference to a value or component of a value that is to be compared by the view’s comparator.
+ * `c.value()` | Returns the content's value.
+ * `c.set_value(const value_type&)` | Sets the content's value. (The value becomes known.)
+ * `c.comp_value()` | Returns a const reference to the value or component of the value that is to be compared by the view's comparator.
+ * `C::comp_value(const value_type&)` | Returns a const reference to a value or component of a value that is to be compared by the view's comparator.
*
* @see view_base
*/
@@ -740,20 +798,20 @@ protected:
/** Content class for op_min_view and op_max_view.
*
* @tparam Type The value type of the op_min_view or op_max_view.
- * @tparam Compare The comparator class specified for the op_min_view or
+ * @tparam Compare The comparator class specified for the op_min_view or
* op_max_view. (_Not_ the derived comparator class actually
* used by the view_base. For example, the view_content of an
- * `op_min_view<int>` will have `Compare = std::less<int>`,
- * but its comparator_base will have
+ * `op_min_view<int>` will have `Compare = std::less<int>`,
+ * but its comparator_base will have
* `Compare = reverse_predicate< std::less<int> >`.)
* @tparam ForMax `true` if this is the content class for an op_max_view,
* `false` if it is for an op_min_view.
*
* @note The general implementation of view_content uses an `is_set` data
- * member. There is also a specialization which implements the
+ * member. There is also a specialization which implements the
* ReducersMinMaxIsSet "is_set optimization". View classes that
* inherit from view_content do not need to know anything about the
- * difference, though; the details are abstracted away in the
+ * difference, though; the details are abstracted away in the
* view_content interface.
*
* @see ReducersMinMaxViewContent
@@ -767,96 +825,94 @@ template < typename Type
, bool = do_is_set_optimization<Type, Compare>::value
>
class view_content {
+protected:
+/// @cond
Type m_value;
bool m_is_set;
+/// @endcond
public:
/// The value type of the view.
typedef Type value_type;
-
- /// The type compared by the view’s `compare()` function (which is the same
+
+ /// The type compared by the view's `compare()` function (which is the same
/// as the value type for view_content).
typedef Type comp_value_type;
-
+
/// Construct with the identity value.
view_content() : m_value(), m_is_set(false) {}
-
+
/// Construct with a defined value.
view_content(const value_type& value) : m_value(value), m_is_set(true) {}
-
- /// Get the value.
+
+ /// Gets the value.
value_type value() const { return m_value; }
-
- /// Set the value.
- void set_value(const value_type& value)
- {
+
+ /// Sets the value.
+ void set_value(const value_type& value)
+ {
m_value = value;
+ }
+
+ /// Sets the is_set flag.
+ void set_is_set()
+ {
m_is_set = true;
}
-
- /// Get the comparison value (which is the same as the value for
- /// view_content).
+
+ /// Sets the index part of the value (which is meaningless for non-index
+ ///reducers, but required for view_base).
+ void set_default_index(const value_type&) {}
+
+ /// Gets the comparison value (which, for view_content, is the same as the
+ /// value).
const comp_value_type& comp_value() const { return m_value; }
- /// Given an arbitrary value, get the corresponding comparison value (which
- /// is the same as the value for view_content).
- static const comp_value_type& comp_value(const value_type& value)
+ /// Given an arbitrary value, gets the corresponding comparison value
+ /// (which, for view_content, is the same as the value).
+ static const comp_value_type& comp_value(const value_type& value)
{
- return value;
+ return value;
}
-
- /// Get a const reference to value part of the value (which is the same as
+
+ /// Gets a const reference to value part of the value (which is the same as
/// the value for view_content).
const Type& get_reference() const { return m_value; }
-
- /// Get a const reference to the index part of the value (which is
+
+ /// Gets a const reference to the index part of the value (which is
/// meaningless for non-index reducers, but required for view_base.
const Type& get_index_reference() const { return m_value; }
-
- /// Test if the value is defined.
+
+ /// Tests if the value is defined.
bool is_set() const { return m_is_set; }
+
+ /// Tests if the view has a comparable value.
+ bool has_value() const { return is_set(); }
};
/// @cond
/* This is the specialization of the view_content class for cases where
- * `AssumeIsSet` is true (i.e., where the is_set optimization is applicable).
+ * the is_set optimization is applicable).
*/
template < typename Type
, typename Compare
- , bool ForMax
+ , bool ForMax
>
-class view_content<Type, Compare, ForMax, true> {
+class view_content<Type, Compare, ForMax, true> :
+ public view_content<Type, Compare, ForMax, false>
+{
+ typedef view_content<Type, Compare, ForMax, false> base;
typedef identity_value<Type, Compare, ForMax> Identity;
- Type m_value;
+
public:
- typedef Type value_type;
- typedef Type comp_value_type;
-
- /// Construct with identity value.
- view_content() { Identity::set_identity(m_value); }
-
- view_content(const value_type& value) : m_value(value) {}
-
- value_type value() const { return m_value; }
-
- void set_value(const value_type& value)
- {
- m_value = value;
- }
-
- const comp_value_type& comp_value() const { return m_value; }
+ typedef typename base::value_type value_type;;
+ typedef typename base::comp_value_type comp_value_type;;
- static const comp_value_type& comp_value(const value_type& value)
- {
- return value;
- }
-
- const Type& get_reference() const { return m_value; }
-
- const Type& get_index_reference() const { return m_value; }
-
- /// Test if the value is defined.
- bool is_set() const { return true; }
+ view_content() : base() { Identity::set_identity(this->m_value); }
+
+ view_content(const value_type& value) : base(value) {}
+
+ bool has_value() const { return true; }
};
/// @endcond
@@ -866,10 +922,10 @@ public:
*
* @tparam Index The index type of the op_min_index_view or
op_max_index_view.
- * @tparam Type The value type of the op_min_view or op_max_view. (_Not_
+ * @tparam Type The value type of the op_min_view or op_max_view. (_Not_
* the value type of the view, which will be
* `std::pair<Index, Type>`.)
- * @tparam Compare The comparator class specified for the op_min_index_view or
+ * @tparam Compare The comparator class specified for the op_min_index_view or
* op_max_index_view. (_Not_ the derived comparator class
* actually used by the view_base. For example, the
* index_view_content of an `op_min_index_view<int>` will have
@@ -887,93 +943,147 @@ public:
template < typename Index
, typename Type
, typename Compare
- , bool ForMax
+ , bool ForMax
+ , bool = do_is_set_optimization<Type, Compare>::value
>
class index_view_content {
- typedef identity_value<Type, Compare, ForMax> Identity;
-
+protected:
+/// @cond
Index m_index;
Type m_value;
bool m_is_set;
+/// @endcond
public:
- /// The value type of the view (which is an <index, value> pair for
+ /// The value type of the view (which is an <index, value> pair for
/// index_view_content).
typedef std::pair<Index, Type> value_type;
-
- /// The type compared by the view’s `compare()` function (which is the data
+
+ /// The type compared by the view's `compare()` function (which is the data
/// value type for index_view_content).
typedef Type comp_value_type;
-
+
/// Construct with the identity value.
index_view_content() : m_index(), m_value(), m_is_set(false) {}
-
+
/// Construct with an index/value pair.
- index_view_content(const value_type& value) :
+ index_view_content(const value_type& value) :
m_index(value.first), m_value(value.second), m_is_set(true) {}
-
+
/// Construct with an index and a value.
- index_view_content(const Index& index, const Type& value) :
+ index_view_content(const Index& index, const Type& value) :
m_index(index), m_value(value), m_is_set(true) {}
-
+
/// Construct with just an index.
- index_view_content(const Index& index) :
+ index_view_content(const Index& index) :
m_index(index), m_value(), m_is_set(false) {}
-
- /// Get the value.
+
+ /// Gets the value.
value_type value() const { return value_type(m_index, m_value); }
-
- /// Set value.
- void set_value(const value_type& value)
- {
- m_index = value.first;
+
+ /// Sets the value.
+ void set_value(const value_type& value)
+ {
+ m_index = value.first;
m_value = value.second;
+ }
+
+ /// Sets the is_set flag.
+ void set_is_set()
+ {
m_is_set = true;
}
-
- /// Get the comparison value (which is the value component of the
- /// index/value pair for index_view_content).
+
+ /// Sets the (initial) index, without marking the view as set.
+ void set_default_index(const Index& index)
+ {
+ m_index = index;
+ }
+
+ /// Gets the comparison value (which, for index_view_content, is the value
+ /// component of the index/value pair).
const comp_value_type& comp_value() const { return m_value; }
-
- /// Given an arbitrary value (i.e., index/value pair), get the
- /// corresponding comparison value (which is the value component of the
- /// index/value pair for index_view_content).
- static const comp_value_type& comp_value(const value_type& value)
+
+ /// Given an arbitrary value (i.e., index/value pair), gets the
+ /// corresponding comparison value (which, for index_view_content, is the
+ /// value component of the index/value pair).
+ static const comp_value_type& comp_value(const value_type& value)
{ return value.second; }
-
- /// Get a const reference to value part of the value.
+
+ /// Gets a const reference to the value part of the value.
const Type& get_reference() const { return m_value; }
-
- /// Get a const reference to the index part of the value.
+
+ /// Gets a const reference to the index part of the value.
const Index& get_index_reference() const { return m_index; }
-
- /// Test if the value is defined.
+
+ /// Tests if the value is defined.
bool is_set() const { return m_is_set; }
+
+ /// Tests if the view has a comparable value.
+ bool has_value() const { return is_set(); }
+};
+
+
+/// @cond
+
+/* This is the specialization of the index_view_content class for cases where
+ * the is_set optimization is applicable).
+ */
+template < typename Index
+ , typename Type
+ , typename Compare
+ , bool ForMax
+ >
+class index_view_content<Index, Type, Compare, ForMax, true> :
+ public index_view_content<Index, Type, Compare, ForMax, false>
+{
+ typedef index_view_content<Index, Type, Compare, ForMax, false> base;
+ typedef identity_value<Type, Compare, ForMax> Identity;
+public:
+ typedef typename base::value_type value_type;;
+ typedef typename base::comp_value_type comp_value_type;;
+
+ index_view_content() : base() { Identity::set_identity(this->m_value); }
+
+ index_view_content(const value_type& value) : base(value) {}
+
+ index_view_content(const Index& index, const Type& value) :
+ base(index, value) {}
+
+ index_view_content(const Index& index) : base() {
+ Identity::set_identity(this->m_value);
+ this->m_index = index;
+ }
+
+ /// Test if the view has a comparable value.
+ bool has_value() const { return true; }
};
+/// @endcond
+
template <typename View> class rhs_proxy;
-/** Create an rhs_proxy.
+/** Creates an rhs_proxy.
*/
template <typename View>
-inline rhs_proxy<View>
+inline rhs_proxy<View>
make_proxy(const typename View::value_type& value, const View& view);
template <typename Content, typename Less, typename Compare> class view_base;
-/** Class to represent the right-hand side of
+/** Class to represent the right-hand side of
* `*reducer = {min|max}_of(*reducer, value)`.
*
* The only assignment operator for a min/max view class takes a rhs_proxy as
* its operand. This results in the syntactic restriction that the only
* expressions that can be assigned to a min/max view are ones which generate
- * an rhs_proxy — that is, expressions of the form `max_of(view, value)` and
+ * an rhs_proxy - that is, expressions of the form `max_of(view, value)` and
* `min_of(view, value)`.
*
* @warning
- * The lhs and rhs views in such an assignment must be the same; otherwise,
- * the behavior will be undefined. (I.e., `*r1 = min_of(*r1, x)` is legal;
+ * The lhs and rhs views in such an assignment must be the same; otherwise,
+ * the behavior will be undefined. (I.e., `*r1 = min_of(*r1, x)` is legal;
* `*r1 = min_of(*r2, x)` is illegal.) This condition will be checked with a
* runtime assertion when compiled in debug mode.
*
@@ -991,12 +1101,12 @@ class rhs_proxy {
typedef typename View::value_type value_type;
typedef typename View::content_type content_type;
typedef typename content_type::comp_value_type comp_value_type;
-
+
friend class view_base<content_type, less_type, compare_type>;
friend rhs_proxy make_proxy<View>(
- const typename View::value_type& value,
+ const typename View::value_type& value,
const View& view);
-
+
typed_indirect_binary_function<
compare_type, comp_value_type, comp_value_type, bool>
m_comp;
@@ -1005,38 +1115,38 @@ class rhs_proxy {
rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator
rhs_proxy(); // Disable default constructor
-
+
// Constructor (called from view_base::make_proxy).
- rhs_proxy(const View* view,
+ rhs_proxy(const View* view,
const value_type& value,
- const compare_type* compare) :
+ const compare_type* compare) :
m_view(view), m_value(value), m_comp(compare) {}
-
- // Check matching view, then return value (called from view_base::assign).
+
+ // Checks matching view, then return value (called from view_base::assign).
value_type value(const typename View::base* view) const
- {
- __CILKRTS_ASSERT(view == m_view);
- return m_value;
+ {
+ __CILKRTS_ASSERT(view == m_view);
+ return m_value;
}
public:
- /** Support max_of(max_of(view, value), value) and the like.
+ /** Supports max_of(max_of(view, value), value) and the like.
*/
rhs_proxy calc(const value_type& x) const
{
return rhs_proxy(
- m_view,
- m_comp( content_type::comp_value(m_value),
+ m_view,
+ m_comp( content_type::comp_value(m_value),
content_type::comp_value(x)
) ? x : m_value,
m_comp.pointer());
}
};
-
-
+
+
template <typename View>
-inline rhs_proxy<View>
+inline rhs_proxy<View>
make_proxy(const typename View::value_type& value, const View& view)
{
return rhs_proxy<View>(&view, value, view.compare_pointer());
@@ -1058,14 +1168,14 @@ make_proxy(const typename View::value_type& value, const View& view)
* which is equivalent to `std::greater`, then the accumulated value is the
* first argument value which is not greater than any other argument value,
* i.e., the minimum.
- *
+ *
* @note This class provides the definitions that are required for a class
- * that will be used as the parameter of a
- * min_max_internal::monoid_base specialization.
+ * that will be used as the parameter of a
+ * min_max_internal::monoid_base specialization.
*
* @tparam Content A content class that provides the value types and data
* members for the view.
- * @tparam Less A “less than” binary predicate that defines the min or
+ * @tparam Less A "less than" binary predicate that defines the min or
* max function.
* @tparam Compare A binary predicate to be used to compare the values.
* (The same as @a Less for max reducers; its reversal for
@@ -1081,73 +1191,76 @@ make_proxy(const typename View::value_type& value, const View& view)
* @ingroup ReducersMinMax
*/
template <typename Content, typename Less, typename Compare>
-class view_base :
+class view_base :
// comparator_base comes first to ensure that it will get empty base class
// treatment
- private comparator_base<typename Content::comp_value_type, Compare>,
+ private comparator_base<typename Content::comp_value_type, Compare>,
private Content
{
typedef comparator_base<typename Content::comp_value_type, Compare> base;
using base::compare;
using Content::value;
using Content::set_value;
+ using Content::has_value;
+ using Content::set_is_set;
using Content::comp_value;
typedef Content content_type;
-
+
template <typename View> friend class rhs_proxy;
template <typename View>
friend rhs_proxy<View> make_proxy(const typename View::value_type& value, const View& view);
-
+
public:
-
+
/** @name Monoid support.
*/
//@{
-
+
/** Value type. Required by @ref monoid_with_view.
*/
typedef typename Content::value_type value_type;
-
- /** The type of the comparator specified by the user, that defines the
+
+ /** The type of the comparator specified by the user, that defines the
* ordering on @a Type. Required by min_max::monoid_base.
*/
typedef Less less_type;
-
- /** The type of the comparator actually used by the view. Required by
- * min_max::monoid_base. (This is the same as the @ref less_type for a
+
+ /** The type of the comparator actually used by the view. Required by
+ * min_max::monoid_base. (This is the same as the @ref less_type for a
* max reducer, or `reverse_predicate<less_type>` for a min reducer.)
*/
typedef Compare compare_type;
- /** Reduce operation. Required by @ref monoid_with_view.
+ /** Reduces two views. Required by @ref monoid_with_view.
*/
void reduce(view_base* other)
{
if ( other->is_set() &&
- ( !this->is_set() ||
+ ( !this->is_set() ||
compare(this->comp_value(), other->comp_value()) ) )
{
this->set_value(other->value());
+ this->set_is_set();
}
}
-
+
//@}
-
+
/** Default constructor. Initializes to identity value.
*/
- explicit view_base(const compare_type* compare) :
+ explicit view_base(const compare_type* compare) :
base(compare), Content() {}
-
+
/** Value constructor.
*/
template <typename T1>
- view_base(const T1& x1, const compare_type* compare) :
+ view_base(const T1& x1, const compare_type* compare) :
base(compare), Content(x1) {}
/** Value constructor.
*/
template <typename T1, typename T2>
- view_base(const T1& x1, const T2& x2, const compare_type* compare) :
+ view_base(const T1& x1, const T2& x2, const compare_type* compare) :
base(compare), Content(x1, x2) {}
@@ -1155,44 +1268,54 @@ public:
*/
explicit view_base(move_in_wrapper<value_type> w, const compare_type* compare) :
base(compare), Content(w.value()) {}
-
+
/** @name Reducer support.
*/
//@{
-
- void view_move_in(value_type& v) { set_value(v); }
- void view_move_out(value_type& v) { v = value(); }
- void view_set_value(const value_type& v) { set_value(v); }
- value_type view_get_value() const { return value(); }
+
+ void view_move_in(value_type& v)
+ { set_value(v); set_is_set();}
+ void view_move_out(value_type& v)
+ { v = value(); }
+ void view_set_value(const value_type& v)
+ { set_value(v); set_is_set(); }
+ value_type view_get_value() const
+ { return value(); }
// view_get_reference() NOT SUPPORTED
-
+
//@}
-
+
+ /** Sets the contained index data member, without marking the view as set.
+ * (Meaningless for non-index reducers.)
+ */
+ using Content::set_default_index;
+
/** Is the value defined?
*/
using Content::is_set;
-
+
/** Reference to contained value data member.
* @deprecated For legacy reducers only.
*/
using Content::get_reference;
-
+
/** Reference to contained index data member.
* (Meaningless for non-index reducers.)
* @deprecated For legacy reducers only.
*/
using Content::get_index_reference;
-
+
protected:
- /** Update the min/max value.
+ /** Updates the min/max value.
*/
void calc(const value_type& x)
{
- if (!is_set() || compare(comp_value(), comp_value(x))) set_value(x);
+ if (!has_value() || compare(comp_value(), comp_value(x))) set_value(x);
+ set_is_set();
}
-
- /** Assign the result of a `{min|max}_of(view, value)` expression to the
+
+ /** Assigns the result of a `{min|max}_of(view, value)` expression to the
* view.
*
* @see rhs_proxy
@@ -1202,21 +1325,21 @@ protected:
{
calc(rhs.value(this));
}
-
+
};
/** Base class for min and max monoid classes.
*
- * The unique characteristic of minimum and maximum reducers is that they
- * incorporate a comparator functor that defines what “minimum” or “maximum”
+ * The unique characteristic of minimum and maximum reducers is that they
+ * incorporate a comparator functor that defines what "minimum" or "maximum"
* means. The monoid for a reducer contains the comparator that will be used
* for the reduction. If the comparator is a function or a class with state,
* then each view will have a pointer to the comparator.
*
* This means that the `construct()` functions first construct the monoid
- * (possibly with an explicit comparator argument), and then construct the
- * view with a pointer to the monoid’s comparator.
+ * (possibly with an explicit comparator argument), and then construct the
+ * view with a pointer to the monoid's comparator.
*
* @tparam View The view class.
* @tparam Align If true, reducers instantiated on this monoid will be
@@ -1230,14 +1353,13 @@ protected:
template <typename View, bool Align = false>
class monoid_base : public monoid_with_view<View, Align>
{
- typedef typename View::compare_type compare_type;
- typedef typename View::less_type less_type;
- const compare_type m_compare;
+ typedef typename View::compare_type compare_type;
+ typedef typename View::less_type less_type;
+
+ const compare_type m_compare;
const compare_type* compare_pointer() const { return &m_compare; }
-
- using cilk::monoid_base<typename View::value_type, View>::provisional;
-
+
public:
/** Default constructor uses default comparator.
@@ -1250,51 +1372,68 @@ public:
*/
monoid_base(const compare_type& compare) : m_compare(compare) {}
- /** Create an identity view.
+ /** Creates an identity view.
*
* List view identity constructors take the list allocator as an argument.
*
- * @param v The address of the uninitialized memory in which the view
+ * @param v The address of the uninitialized memory in which the view
* will be constructed.
*/
void identity(View *v) const { ::new((void*) v) View(compare_pointer()); }
-
+
/** @name construct functions
*
* Min/max monoid `construct()` functions optionally take one or two value
* arguments, a @ref move_in argument, and/or a comparator argument.
*/
//@{
-
+
template <typename Monoid>
static void construct(Monoid* monoid, View* view)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(monoid->compare_pointer()) ); }
+ {
+ provisional_guard<Monoid> mg( new((void*) monoid) Monoid );
+ mg.confirm_if( new((void*) view) View(monoid->compare_pointer()) );
+ }
template <typename Monoid, typename T1>
static void construct(Monoid* monoid, View* view, const T1& x1)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(x1, monoid->compare_pointer()) ); }
+ {
+ provisional_guard<Monoid> mg( new((void*) monoid) Monoid );
+ mg.confirm_if( new((void*) view) View(x1, monoid->compare_pointer()) );
+ }
template <typename Monoid, typename T1, typename T2>
- static void construct(Monoid* monoid, View* view, const T1& x1, const T2& x2)
- { provisional( new ((void*)monoid) Monoid() ).confirm_if(
- new ((void*)view) View(x1, x2, monoid->compare_pointer()) ); }
+ static void construct(Monoid* monoid, View* view,
+ const T1& x1, const T2& x2)
+ {
+ provisional_guard<Monoid> mg( new((void*) monoid) Monoid );
+ mg.confirm_if( new((void*) view) View(x1, x2,
+ monoid->compare_pointer()) );
+ }
template <typename Monoid>
static void construct(Monoid* monoid, View* view, const less_type& compare)
- { provisional( new ((void*)monoid) Monoid(compare) ).confirm_if(
- new ((void*)view) View(monoid->compare_pointer()) ); }
+ {
+ provisional_guard<Monoid> mg( new((void*) monoid) Monoid(compare) );
+ mg.confirm_if( new((void*) view) View(monoid->compare_pointer()) );
+ }
template <typename Monoid, typename T1>
- static void construct(Monoid* monoid, View* view, const T1& x1, const less_type& compare)
- { provisional( new ((void*)monoid) Monoid(compare) ).confirm_if(
- new ((void*)view) View(x1, monoid->compare_pointer()) ); }
+ static void construct(Monoid* monoid, View* view, const T1& x1,
+ const less_type& compare)
+ {
+ provisional_guard<Monoid> mg( new((void*) monoid) Monoid(compare) );
+ mg.confirm_if( new((void*) view) View(x1, monoid->compare_pointer()) );
+ }
template <typename Monoid, typename T1, typename T2>
- static void construct(Monoid* monoid, View* view, const T1& x1, const T2& x2, const less_type& compare)
- { provisional( new ((void*)monoid) Monoid(compare) ).confirm_if(
- new ((void*)view) View(x1, x2, monoid->compare_pointer()) ); }
+ static void construct(Monoid* monoid, View* view,
+ const T1& x1, const T2& x2, const less_type& compare)
+ {
+ provisional_guard<Monoid> mg( new((void*) monoid) Monoid(compare) );
+ mg.confirm_if( new((void*) view) View(x1, x2,
+ monoid->compare_pointer()) );
+ }
//@}
};
@@ -1312,7 +1451,7 @@ public:
/** The maximum reducer view class.
*
- * This is the view class for reducers created with
+ * This is the view class for reducers created with
* `cilk::reducer< cilk::op_max<Type, Compare> >`. It accumulates the maximum,
* as determined by a comparator, of a set of values which have occurred as
* arguments to the `calc_max()` function. The accumulated value will be the
@@ -1323,16 +1462,16 @@ public:
* argument value which is not less than any other argument value, i.e., the
* maximum.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `calc_max()` function would be used in an expression like
* `r->calc_max(a)` where `r` is an op_max reducer variable.
*
* @tparam Type The type of the values compared by the reducer. This will
- * be the value type of a monoid_with_view that is
+ * be the value type of a monoid_with_view that is
* instantiated with this view.
* @tparam Compare A `Strict Weak Ordering` whose argument type is @a Type. It
- * defines the “less than” relation used to compute the
+ * defines the "less than" relation used to compute the
* maximum.
*
* @see ReducersMinMax
@@ -1340,56 +1479,54 @@ public:
*/
template <typename Type, typename Compare>
class op_max_view : public min_max_internal::view_base<
- min_max_internal::view_content<Type, Compare, true>,
+ min_max_internal::view_content<Type, Compare, true>,
Compare,
Compare>
{
typedef min_max_internal::view_base<
- min_max_internal::view_content<Type, Compare, true>,
+ min_max_internal::view_content<Type, Compare, true>,
Compare,
Compare> base;
using base::calc;
using base::assign;
friend class min_max_internal::rhs_proxy<op_max_view>;
-
+
public:
/** @name Constructors.
*
- * All op_max_view constructors simply pass their arguments on to the
+ * All op_max_view constructors simply pass their arguments on to the
* @ref view_base base class.
*/
//@{
-
- op_max_view() : base() {}
-
+
template <typename T1>
op_max_view(const T1& x1) : base(x1) {}
-
+
template <typename T1, typename T2>
op_max_view(const T1& x1, const T2& x2) : base(x1, x2) {}
-
- //@}
+
+ //@}
/** @name View modifier operations.
*/
//@{
-
- /** Maximize with a value.
+
+ /** Maximizes with a value.
*
- * If @a x is greater than the current value of the view (as defined by
- * the reducer’s comparator), or if the view was created without an
- * initial value and its value has never been updated (with `calc_max()`
+ * If @a x is greater than the current value of the view (as defined by
+ * the reducer's comparator), or if the view was created without an
+ * initial value and its value has never been updated (with `calc_max()`
* or `= max_of()`), then the value of the view is set to @a x.
*
- * @param x The value to maximize the view’s value with.
+ * @param x The value to maximize the view's value with.
*
* @return A reference to the view. (Allows chaining
* `view.comp_max(a).comp_max(b)…`.)
*/
op_max_view& calc_max(const Type& x) { calc(x); return *this; }
- /** Assign the result of a `max_of(view, value)` expression to the view.
+ /** Assigns the result of a `max_of(view, value)` expression to the view.
*
* @param rhs An rhs_proxy value created by a `max_of(view, value)`
* expression.
@@ -1398,16 +1535,16 @@ public:
*
* @see min_max_internal::view_base::rhs_proxy
*/
- op_max_view& operator=(const min_max_internal::rhs_proxy<op_max_view>& rhs)
+ op_max_view& operator=(const min_max_internal::rhs_proxy<op_max_view>& rhs)
{ assign(rhs); return *this; }
-
+
//@}
};
-/** Compute the maximum of the value in an op_max_view and another value.
+/** Computes the maximum of the value in an op_max_view and another value.
*
- * The result of this computation can only be assigned back to the original
+ * The result of this computation can only be assigned back to the original
* view or used in another max_of() call. For example,
*
* *reducer = max_of(*reducer, x);
@@ -1430,7 +1567,7 @@ max_of(const Type& value, const op_max_view<Type, Compare>& view)
return min_max_internal::make_proxy(value, view);
}
-/** Nested maximum computation.
+/** Computes nested maximum.
*
* Compute the maximum of the result of a max_of() call and another value.
*
@@ -1444,7 +1581,7 @@ max_of(const Type& value, const op_max_view<Type, Compare>& view)
*/
template <typename Type, typename Compare>
inline min_max_internal::rhs_proxy< op_max_view<Type, Compare> >
-max_of(const min_max_internal::rhs_proxy< op_max_view<Type, Compare> >& proxy,
+max_of(const min_max_internal::rhs_proxy< op_max_view<Type, Compare> >& proxy,
const Type& value)
{
return proxy.calc(value);
@@ -1453,7 +1590,7 @@ max_of(const min_max_internal::rhs_proxy< op_max_view<Type, Compare> >& proxy,
/// @copydoc max_of(const min_max_internal::rhs_proxy< op_max_view<Type, Compare> >&, const Type&)
template <typename Type, typename Compare>
inline min_max_internal::rhs_proxy< op_max_view<Type, Compare> >
-max_of(const Type& value,
+max_of(const Type& value,
const min_max_internal::rhs_proxy< op_max_view<Type, Compare> >& proxy)
{
return proxy.calc(value);
@@ -1470,8 +1607,8 @@ max_of(const Type& value,
* @see op_max_view
*/
template <typename Type, typename Compare=std::less<Type>, bool Align = false>
-class op_max :
- public min_max_internal::monoid_base<op_max_view<Type, Compare>, Align>
+class op_max :
+ public min_max_internal::monoid_base<op_max_view<Type, Compare>, Align>
{
typedef min_max_internal::monoid_base<op_max_view<Type, Compare>, Align>
base;
@@ -1495,7 +1632,7 @@ public:
/** The minimum reducer view class.
*
- * This is the view class for reducers created with
+ * This is the view class for reducers created with
* `cilk::reducer< cilk::op_min<Type, Compare> >`. It accumulates the minimum,
* as determined by a comparator, of a set of values which have occurred as
* arguments to the `calc_min()` function. The accumulated value will be the
@@ -1506,16 +1643,16 @@ public:
* argument value which no other argument value is less than, i.e., the
* minimum.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `calc_min()` function would be used in an expression like
* `r->calc_min(a)` where `r` is an op_min reducer variable.
*
- * @tparam Type The type of the values compared by the reducer. This will
- * be the value type of a monoid_with_view that is
+ * @tparam Type The type of the values compared by the reducer. This will
+ * be the value type of a monoid_with_view that is
* instantiated with this view.
- * @tparam Compare A `Strict Weak Ordering` whose argument type is @a Type. It
- * defines the “less than” relation used to compute the
+ * @tparam Compare A `Strict Weak Ordering` whose argument type is @a Type. It
+ * defines the "less than" relation used to compute the
* minimum.
*
* @see ReducersMinMax
@@ -1523,12 +1660,12 @@ public:
*/
template <typename Type, typename Compare>
class op_min_view : public min_max_internal::view_base<
- min_max_internal::view_content<Type, Compare, false>,
+ min_max_internal::view_content<Type, Compare, false>,
Compare,
min_max_internal::reverse_predicate<Compare, Type> >
{
typedef min_max_internal::view_base<
- min_max_internal::view_content<Type, Compare, false>,
+ min_max_internal::view_content<Type, Compare, false>,
Compare,
min_max_internal::reverse_predicate<Compare, Type> > base;
using base::calc;
@@ -1538,40 +1675,38 @@ class op_min_view : public min_max_internal::view_base<
public:
/** @name Constructors.
*
- * All op_min_view constructors simply pass their arguments on to the
+ * All op_min_view constructors simply pass their arguments on to the
* @ref view_base base class.
*/
//@{
-
- op_min_view() : base() {}
-
+
template <typename T1>
op_min_view(const T1& x1) : base(x1) {}
-
+
template <typename T1, typename T2>
op_min_view(const T1& x1, const T2& x2) : base(x1, x2) {}
-
- //@}
+
+ //@}
/** @name View modifier operations.
*/
//@{
-
- /** Minimize with a value.
+
+ /** Minimizes with a value.
*
* If @a x is less than the current value of the view (as defined by the
- * reducer’s comparator), or if the view was created without an initial
+ * reducer's comparator), or if the view was created without an initial
* value and its value has never been updated (with `calc_min()` or
* `= min_of()`), then the value of the view is set to @a x.
*
- * @param x The value to minimize the view’s value with.
+ * @param x The value to minimize the view's value with.
*
* @return A reference to the view. (Allows chaining
* `view.comp_min(a).comp_min(b)…`.)
*/
op_min_view& calc_min(const Type& x) { calc(x); return *this; }
- /** Assign the result of a `min_of(view, value)` expression to the view.
+ /** Assigns the result of a `min_of(view, value)` expression to the view.
*
* @param rhs An rhs_proxy value created by a `min_of(view, value)`
* expression.
@@ -1580,12 +1715,12 @@ public:
*
* @see min_max_internal::view_base::rhs_proxy
*/
- op_min_view& operator=(const min_max_internal::rhs_proxy<op_min_view>& rhs)
+ op_min_view& operator=(const min_max_internal::rhs_proxy<op_min_view>& rhs)
{ assign(rhs); return *this; }
};
-/** Compute the minimum of the value in a view and another value.
+/** Computes the minimum of the value in a view and another value.
*
* The result of this computation can only be assigned back to the original
* view or used in another min_of() call. For example,
@@ -1610,7 +1745,7 @@ min_of(const Type& value, const op_min_view<Type, Compare>& view)
return min_max_internal::make_proxy(value, view);
}
-/** Nested minimum computation.
+/** Computes nested minimum.
*
* Compute the minimum of the result of a min_of() call and another value.
*
@@ -1624,7 +1759,7 @@ min_of(const Type& value, const op_min_view<Type, Compare>& view)
*/
template <typename Type, typename Compare>
inline min_max_internal::rhs_proxy< op_min_view<Type, Compare> >
-min_of(const min_max_internal::rhs_proxy< op_min_view<Type, Compare> >& proxy,
+min_of(const min_max_internal::rhs_proxy< op_min_view<Type, Compare> >& proxy,
const Type& value)
{
return proxy.calc(value);
@@ -1633,7 +1768,7 @@ min_of(const min_max_internal::rhs_proxy< op_min_view<Type, Compare> >& proxy,
/// @copydoc min_of(const min_max_internal::rhs_proxy< op_min_view<Type, Compare> >&, const Type&)
template <typename Type, typename Compare>
inline min_max_internal::rhs_proxy< op_min_view<Type, Compare> >
-min_of(const Type& value,
+min_of(const Type& value,
const min_max_internal::rhs_proxy< op_min_view<Type, Compare> >& proxy)
{
return proxy.calc(value);
@@ -1673,7 +1808,7 @@ public:
/** The maximum index reducer view class.
*
- * This is the view class for reducers created with
+ * This is the view class for reducers created with
* `cilk::reducer< cilk::op_max_index<Index, Type, Compare> >`. It accumulates
* the maximum, as determined by a comparator, of a set of values which have
* occurred as arguments to the `calc_max()` function, and records the index
@@ -1684,33 +1819,33 @@ public:
* argument value which is not less than any other argument value, i.e., the
* maximum.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `calc_max()` function would be used in an expression like
* `r->calc_max(i, a)`where `r` is an op_max_index reducer
* variable.
*
- * @note The word “index” suggests an integer index into an array, but there
+ * @note The word "index" suggests an integer index into an array, but there
* is no restriction on the index type or how it should be used. In
- * general, it may be convenient to use it for any kind of key that
+ * general, it may be convenient to use it for any kind of key that
* can be used to locate the maximum value in the collection that it
- * came from — for example:
+ * came from - for example:
* - An index into an array.
* - A key into an STL map.
* - An iterator into any STL container.
*
- * @note A max_index reducer is essentially a max reducer whose value type
+ * @note A max_index reducer is essentially a max reducer whose value type
* is a `std::pair<Index, Type>`. This fact is camouflaged in the view
* `calc_max` function, the global `max_of` functions, and the reducer
* value constructor, which can all take an index argument and a value
* argument as an alternative to a single `std::pair` argument.
* However, the reducer `set_value()`, `get_value()`, `move_in()`, and
- * `move_out()` functions work only with pairs, not with individual
+ * `move_out()` functions work only with pairs, not with individual
* value and/or index arguments.
*
* @tparam Index The type of the indices associated with the values.
- * @tparam Type The type of the values compared by the reducer. This will
- * be the value type of a monoid_with_view that is
+ * @tparam Type The type of the values compared by the reducer. This will
+ * be the value type of a monoid_with_view that is
* instantiated with this view.
* @tparam Compare Used to compare the values. It must be a binary predicate.
* If it is omitted, then the view computes the conventional
@@ -1737,65 +1872,65 @@ class op_max_index_view : public min_max_internal::view_base<
public:
/** @name Constructors.
*
- * All op_max_index_view constructors simply pass their arguments on to the
+ * All op_max_index_view constructors simply pass their arguments on to the
* @ref view_base base class, except for the `(index, value [, compare])`
* constructors, which create a `std::pair` containing the index and value.
*/
//@{
-
+
op_max_index_view() : base() {}
-
+
template <typename T1>
op_max_index_view(const T1& x1) : base(x1) {}
-
+
template <typename T1, typename T2>
op_max_index_view(const T1& x1, const T2& x2) : base(x1, x2) {}
-
+
template <typename T1, typename T2, typename T3>
op_max_index_view(const T1& x1, const T2& x2, const T3& x3) : base(x1, x2, x3) {}
-
+
op_max_index_view(const Index& i, const Type& v) : base(pair_type(i, v)) {}
-
- op_max_index_view(const Index& i, const Type& v, const typename base::compare_type* c) :
+
+ op_max_index_view(const Index& i, const Type& v, const typename base::compare_type* c) :
base(pair_type(i, v), c) {}
-
- //@}
- /** Maximize with a value and index.
+ //@}
+
+ /** Maximizes with a value and index.
*
- * If @a x is greater than the current value of the view (as defined by
- * the reducer’s comparator), or if the view was created without an
- * initial value and its value has never been updated (with `calc_max()`
+ * If @a x is greater than the current value of the view (as defined by
+ * the reducer's comparator), or if the view was created without an
+ * initial value and its value has never been updated (with `calc_max()`
* or `= max_of()`), then the value of the view is set to @a x, and the
* index is set to @a i..
*
* @param i The index of the value @a x.
- * @param x The value to maximize the view’s value with.
+ * @param x The value to maximize the view's value with.
*
- * @return A reference to the view. (Allows
+ * @return A reference to the view. (Allows
* `view.comp_max(i, a).comp_max(j, b)…`.)
*/
- op_max_index_view& calc_max(const Index& i, const Type& x)
+ op_max_index_view& calc_max(const Index& i, const Type& x)
{ calc(pair_type(i, x)); return *this; }
- /** Maximize with an index/value pair.
+ /** Maximizes with an index/value pair.
*
* If @a pair.second is greater than the current value of the view (as
- * defined by the reducer’s comparator), or if the view was created
+ * defined by the reducer's comparator), or if the view was created
* without an initial value and its value has never been updated (with
* `calc_max()` or `= max_of()`), then the value of the view is set to
* @a pair.second, and the index is set to @a pair.first.
*
- * @param pair A pair containing a value to maximize the view’s value
+ * @param pair A pair containing a value to maximize the view's value
* with and its associated index.
*
* @return A reference to the view. (Allows
* `view.comp_max(p1).comp_max(p2)…`.)
*/
- op_max_index_view& calc_max(const pair_type& pair)
+ op_max_index_view& calc_max(const pair_type& pair)
{ calc(pair); return *this; }
- /** Assign the result of a `max_of(view, index, value)` expression to the
+ /** Assigns the result of a `max_of(view, index, value)` expression to the
* view.
*
* @param rhs An rhs_proxy value created by a `max_of(view, index, value)`
@@ -1805,12 +1940,12 @@ public:
*
* @see min_max_internal::view_base::rhs_proxy
*/
- op_max_index_view& operator=(const min_max_internal::rhs_proxy<op_max_index_view>& rhs)
+ op_max_index_view& operator=(const min_max_internal::rhs_proxy<op_max_index_view>& rhs)
{ assign(rhs); return *this; }
};
-/** Compute the maximum of the value in a view and another value.
+/** Computes the maximum of the value in a view and another value.
*
* The result of this computation can only be assigned back to the original
* view or used in another max_of() call. For example,
@@ -1855,7 +1990,7 @@ max_of(const std::pair<Index, Type>& pair,
return min_max_internal::make_proxy(pair, view);
}
-/** Nested computation of the maximum of the value in a view and other values.
+/** Computes the nested maximum between the value in a view and other values.
*
* Compute the maximum of the result of a max_of() call and another value.
*
@@ -1918,7 +2053,7 @@ template < typename Index
, typename Compare=std::less<Type>
, bool Align = false
>
-class op_max_index : public min_max_internal::monoid_base<op_max_index_view<Index, Type, Compare>, Align>
+class op_max_index : public min_max_internal::monoid_base<op_max_index_view<Index, Type, Compare>, Align>
{
typedef min_max_internal::monoid_base<
op_max_index_view<Index, Type, Compare>, Align> base;
@@ -1944,7 +2079,7 @@ public:
/** The minimum index reducer view class.
*
- * This is the view class for reducers created with
+ * This is the view class for reducers created with
* `cilk::reducer<cilk::op_min_index<Index, Type, Compare> >`. It accumulates
* the minimum, as determined by a comparator, of a set of values which have
* occurred as arguments to the `calc_min()` function, and records the index
@@ -1955,22 +2090,22 @@ public:
* argument value which no other argument value is less than, i.e., the
* minimum.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `calc_min()` function would be
* used in an expression like `r->calc_min(i, a)`where `r` is an
* op_min_index reducer variable.
*
- * @note The word “index” suggests an integer index into an array, but there
+ * @note The word "index" suggests an integer index into an array, but there
* is no restriction on the index type or how it should be used. In
- * general, it may be convenient to use it for any kind of key that
+ * general, it may be convenient to use it for any kind of key that
* can be used to locate the minimum value in the collection that it
- * came from — for example:
+ * came from - for example:
* - An index into an array.
* - A key into an STL map.
* - An iterator into any STL container.
*
- * @note A min_index reducer is essentially a min reducer whose value type
+ * @note A min_index reducer is essentially a min reducer whose value type
* is a `std::pair<Index, Type>`. This fact is camouflaged in the view
* `calc_min` function, the global `min_of` functions, and the reducer
* value constructor, which can all take an index argument and a value
@@ -1980,8 +2115,8 @@ public:
* value and/or index arguments.
*
* @tparam Index The type of the indices associated with the values.
- * @tparam Type The type of the values compared by the reducer. This will
- * be the value type of a monoid_with_view that is
+ * @tparam Type The type of the values compared by the reducer. This will
+ * be the value type of a monoid_with_view that is
* instantiated with this view.
* @tparam Compare Used to compare the values. It must be a binary predicate.
* If it is omitted, then the view computes the conventional
@@ -2008,65 +2143,65 @@ class op_min_index_view : public min_max_internal::view_base<
public:
/** @name Constructors.
*
- * All op_min_index_view constructors simply pass their arguments on to the
+ * All op_min_index_view constructors simply pass their arguments on to the
* @ref view_base base class, except for the `(index, value [, compare])`
* constructors, which create a `std::pair` containing the index and value.
*/
//@{
-
+
op_min_index_view() : base() {}
-
+
template <typename T1>
op_min_index_view(const T1& x1) : base(x1) {}
-
+
template <typename T1, typename T2>
op_min_index_view(const T1& x1, const T2& x2) : base(x1, x2) {}
-
+
template <typename T1, typename T2, typename T3>
op_min_index_view(const T1& x1, const T2& x2, const T3& x3) : base(x1, x2, x3) {}
-
+
op_min_index_view(const Index& i, const Type& v) : base(pair_type(i, v)) {}
-
- op_min_index_view(const Index& i, const Type& v, const typename base::compare_type* c) :
+
+ op_min_index_view(const Index& i, const Type& v, const typename base::compare_type* c) :
base(pair_type(i, v), c) {}
-
- //@}
- /** Minimize with a value and index.
+ //@}
+
+ /** Minimizes with a value and index.
*
- * If @a x is greater than the current value of the view (as defined by
- * the reducer’s comparator), or if the view was created without an
- * initial value and its value has never been updated (with `calc_min()`
+ * If @a x is greater than the current value of the view (as defined by
+ * the reducer's comparator), or if the view was created without an
+ * initial value and its value has never been updated (with `calc_min()`
* or `= min_of()`), then the value of the view is set to @a x, and the
* index is set to @a i..
*
* @param i The index of the value @a x.
- * @param x The value to minimize the view’s value with.
+ * @param x The value to minimize the view's value with.
*
- * @return A reference to the view. (Allows
+ * @return A reference to the view. (Allows
* `view.comp_min(i, a).comp_min(j, b)…`.)
*/
- op_min_index_view& calc_min(const Index& i, const Type& x)
+ op_min_index_view& calc_min(const Index& i, const Type& x)
{ calc(pair_type(i, x)); return *this; }
- /** Maximize with an index/value pair.
+ /** Maximizes with an index/value pair.
*
* If @a pair.second is less than the current value of the view (as
- * defined by the reducer’s comparator), or if the view was created
+ * defined by the reducer's comparator), or if the view was created
* without an initial value and its value has never been updated (with
* `calc_min()` or `= min_of()`), then the value of the view is set to
* @a pair.second, and the index is set to @a pair.first.
*
- * @param pair A pair containing a value to minimize the view’s value
+ * @param pair A pair containing a value to minimize the view's value
* with and its associated index.
*
* @return A reference to the view. (Allows
* `view.comp_min(p1).comp_min(p2)…`.)
*/
- op_min_index_view& calc_min(const pair_type& pair)
+ op_min_index_view& calc_min(const pair_type& pair)
{ calc(pair); return *this; }
- /** Assign the result of a `min_of(view, index, value)` expression to the
+ /** Assigns the result of a `min_of(view, index, value)` expression to the
* view.
*
* @param rhs An rhs_proxy value created by a `min_of(view, index, value)`
@@ -2076,12 +2211,12 @@ public:
*
* @see min_max_internal::view_base::rhs_proxy
*/
- op_min_index_view& operator=(const min_max_internal::rhs_proxy<op_min_index_view>& rhs)
+ op_min_index_view& operator=(const min_max_internal::rhs_proxy<op_min_index_view>& rhs)
{ assign(rhs); return *this; }
};
-/** Compute the minimum of the value in a view and another value.
+/** Computes the minimum of the value in a view and another value.
*
* The result of this computation can only be assigned back to the original
* view or used in another min_of() call. For example,
@@ -2126,7 +2261,7 @@ min_of(const std::pair<Index, Type>& pair,
return min_max_internal::make_proxy(pair, view);
}
-/** Nested computation of the minimum of the value in a view and other values.
+/** Computes nested minimum between the value in a view and other values.
*
* Compute the minimum of the result of a min_of() call and another value.
*
@@ -2176,7 +2311,7 @@ min_of(const std::pair<Index, Type>& pair,
/** Monoid class for minimum reductions with index. Instantiate the
* cilk::reducer template class with an op_min_index monoid to create a
- * min_index reducer class. For example, to compute the minimum of an array of
+ * min_index reducer class. For example, to compute the minimum of an array of
* `double` values and the array index of the min value:
*
* cilk::reducer< cilk::op_min_index<unsigned, double> > r;
@@ -2189,7 +2324,7 @@ template < typename Index
, typename Compare=std::less<Type>
, bool Align = false
>
-class op_min_index : public min_max_internal::monoid_base<op_min_index_view<Index, Type, Compare>, Align>
+class op_min_index : public min_max_internal::monoid_base<op_min_index_view<Index, Type, Compare>, Align>
{
typedef min_max_internal::monoid_base<
op_min_index_view<Index, Type, Compare>, Align> base;
@@ -2209,18 +2344,18 @@ public:
* reducer_max is a proxy for the contained view, so that accumulator
* variable update operations can be applied directly to the reducer. For
* example, a value is maximized with a `reducer<%op_max>` with
- * `r->calc_max(a)`, but a value can be maximized with a `%reducer_max` with
+ * `r->calc_max(a)`, but a value can be maximized with a `%reducer_max` with
* `r.calc_max(a)`.
*
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_max.
+ * reducers rather than the old wrappers like reducer_max.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_max`
+ * @note Implicit conversions are provided between `%reducer_max`
* and `reducer<%op_max>`. This allows incremental code
* conversion: old code that used `%reducer_max` can pass a
* `%reducer_max` to a converted function that now expects a
@@ -2228,7 +2363,7 @@ public:
* versa. **But see @ref redminmax_compatibility.**
*
* @tparam Type The value type of the reducer.
- * @tparam Compare The “less than” comparator type for the reducer.
+ * @tparam Compare The "less than" comparator type for the reducer.
*
* @see op_max
* @see op_max_view
@@ -2240,53 +2375,53 @@ template <typename Type, typename Compare=std::less<Type> >
class reducer_max : public reducer< op_max<Type, Compare, true> >
{
__CILKRTS_STATIC_ASSERT(
- ::cilk::internal::class_is_empty<
- typename ::cilk::internal::binary_functor<Compare>::type >::value,
+ ::cilk::internal::class_is_empty<
+ typename ::cilk::internal::binary_functor<Compare>::type >::value,
"cilk::reducer_max<Type, Compare> only works with "
"an empty Compare class");
typedef reducer< op_max<Type, Compare, true> > base;
public:
-
+
/// Type of data in a reducer_max.
typedef Type basic_value_type;
-
+
/// The view type for the reducer.
typedef typename base::view_type view_type;
-
+
/// The view type for the reducer.
typedef typename base::view_type View;
-
+
/// The monoid type for the reducer.
typedef typename base::monoid_type monoid_type;
-
+
/// The monoid type for the reducer.
typedef typename base::monoid_type Monoid;
- /// The view’s rhs proxy type.
+ /// The view's rhs proxy type.
typedef min_max_internal::rhs_proxy<View> rhs_proxy;
-
+
using base::view;
/** @name Constructors
*/
//@{
-
- /// Construct the wrapper in its identity state (either `!is_set()`, or
+
+ /// Constructs the wrapper in its identity state (either `!is_set()`, or
/// `value() == identity value`).
reducer_max() : base() {}
- /// Construct the wrapper with a specified initial value.
+ /// Constructs the wrapper with a specified initial value.
explicit reducer_max(const Type& initial_value) : base(initial_value) {}
- /// Construct the wrapper in its identity state with a specified
+ /// Constructs the wrapper in its identity state with a specified
/// comparator.
explicit reducer_max(const Compare& comp) : base(comp) {}
- /// Construct the wrapper with a specified initial value and a specified
+ /// Constructs the wrapper with a specified initial value and a specified
/// comparator.
reducer_max(const Type& initial_value, const Compare& comp)
: base(initial_value, comp) {}
-
+
//@}
/** @name Forwarded functions
@@ -2294,25 +2429,25 @@ public:
* simply forwarded to the contained @ref op_max_view. */
//@{
- /// @copydoc cilk_lib_1_0::min_max_internal::view_content::is_set() const
+ /// @copydoc cilk_lib_1_1::min_max_internal::view_content::is_set() const
bool is_set() const { return view().is_set(); }
/// @copydoc op_max_view::calc_max(const Type&)
- reducer_max& calc_max(const Type& x)
+ reducer_max& calc_max(const Type& x)
{ view().calc_max(x); return *this; }
- /// @copydoc op_max_view::operator=(const min_max_internal::rhs_proxy<op_max_view>&)
+ /// @copydoc op_max_view::operator=(const min_max_internal::rhs_proxy<op_max_view>&)
reducer_max& operator=(const rhs_proxy& rhs)
{ view() = rhs; return *this; }
-
+
//@}
- /** Allow read-only access to the value within the current view.
- *
+ /** Allows read-only access to the value within the current view.
+ *
* @returns A const reference to the value within the current view.
*/
const Type& get_reference() const { return view().get_reference(); }
-
+
/// @name Dereference
/** Dereferencing a wrapper is a no-op. It simply returns the wrapper.
* Combined with the rule that a wrapper forwards view operations to the
@@ -2336,12 +2471,12 @@ public:
reducer_max* operator->() { return this; }
reducer_max const* operator->() const { return this; }
//@}
-
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
@@ -2352,7 +2487,7 @@ public:
{
return *reinterpret_cast< reducer< op_max<Type, Compare, false> >* >(this);
}
-
+
operator const reducer< op_max<Type, Compare, false> >& () const
{
return *reinterpret_cast< const reducer< op_max<Type, Compare, false> >* >(this);
@@ -2363,18 +2498,18 @@ public:
/// @cond internal
// The legacy definition of max_of(reducer_max, value) has different
-// behavior and a different return type than this definition. We add an
+// behavior and a different return type than this definition. We add an
// unused third argument to this version of the function to give it a different
-// signature, so that they won’t end up sharing a single object file entry.
+// signature, so that they won't end up sharing a single object file entry.
struct max_of_1_0_t {};
const max_of_1_0_t max_of_1_0 = {};
/// @endcond
-/** Compute the maximum of the value in a reducer_max and another value.
+/** Computes the maximum of the value in a reducer_max and another value.
*
* @deprecated Because reducer_max is deprecated.
*
- * The result of this computation can only be assigned back to the original
+ * The result of this computation can only be assigned back to the original
* reducer or used in another max_of() call. For example,
*
* reducer = max_of(reducer, x);
@@ -2409,18 +2544,18 @@ max_of(const Type& value, const reducer_max<Type, Compare>& r,
* reducer_min is a proxy for the contained view, so that accumulator
* variable update operations can be applied directly to the reducer. For
* example, a value is minimized with a `reducer<%op_min>` with
- * `r->calc_min(a)`, but a value can be minimized with a `%reducer_min` with
+ * `r->calc_min(a)`, but a value can be minimized with a `%reducer_min` with
* `r.calc_min(a)`.
*
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_min.
+ * reducers rather than the old wrappers like reducer_min.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_min`
+ * @note Implicit conversions are provided between `%reducer_min`
* and `reducer<%op_min>`. This allows incremental code
* conversion: old code that used `%reducer_min` can pass a
* `%reducer_min` to a converted function that now expects a
@@ -2428,7 +2563,7 @@ max_of(const Type& value, const reducer_max<Type, Compare>& r,
* versa. **But see @ref redminmax_compatibility.**
*
* @tparam Type The value type of the reducer.
- * @tparam Compare The “less than” comparator type for the reducer.
+ * @tparam Compare The "less than" comparator type for the reducer.
*
* @see op_min
* @see op_min_view
@@ -2441,52 +2576,52 @@ class reducer_min : public reducer< op_min<Type, Compare, true> >
{
__CILKRTS_STATIC_ASSERT(
::cilk::internal::class_is_empty<
- typename ::cilk::internal::binary_functor<Compare>::type >::value,
+ typename ::cilk::internal::binary_functor<Compare>::type >::value,
"cilk::reducer_min<Type, Compare> only works with "
"an empty Compare class");
typedef reducer< op_min<Type, Compare, true> > base;
public:
-
+
/// Type of data in a reducer_min.
typedef Type basic_value_type;
-
+
/// The view type for the reducer.
typedef typename base::view_type view_type;
-
+
/// The view type for the reducer.
typedef typename base::view_type View;
-
+
/// The monoid type for the reducer.
typedef typename base::monoid_type monoid_type;
-
+
/// The monoid type for the reducer.
typedef typename base::monoid_type Monoid;
- /// The view’s rhs proxy type.
+ /// The view's rhs proxy type.
typedef min_max_internal::rhs_proxy<View> rhs_proxy;
-
+
using base::view;
/** @name Constructors
*/
//@{
-
- /// Construct the wrapper in its identity state (either `!is_set()`, or
+
+ /// Constructs the wrapper in its identity state (either `!is_set()`, or
/// `value() == identity value`).
reducer_min() : base() {}
- /// Construct the wrapper with a specified initial value.
+ /// Constructs the wrapper with a specified initial value.
explicit reducer_min(const Type& initial_value) : base(initial_value) {}
- /// Construct the wrapper in its identity state with a specified
+ /// Constructs the wrapper in its identity state with a specified
/// comparator.
explicit reducer_min(const Compare& comp) : base(comp) {}
- /// Construct the wrapper with a specified initial value and a specified
+ /// Constructs the wrapper with a specified initial value and a specified
/// comparator.
reducer_min(const Type& initial_value, const Compare& comp)
: base(initial_value, comp) {}
-
+
//@}
/** @name Forwarded functions
@@ -2494,25 +2629,25 @@ public:
* simply forwarded to the contained @ref op_min_view. */
//@{
- /// @copydoc cilk_lib_1_0::min_max_internal::view_content::is_set() const
+ /// @copydoc cilk_lib_1_1::min_max_internal::view_content::is_set() const
bool is_set() const { return view().is_set(); }
/// @copydoc op_min_view::calc_min(const Type&)
- reducer_min& calc_min(const Type& x)
+ reducer_min& calc_min(const Type& x)
{ view().calc_min(x); return *this; }
- /// @copydoc op_min_view::operator=(const min_max_internal::rhs_proxy<op_min_view>&)
+ /// @copydoc op_min_view::operator=(const min_max_internal::rhs_proxy<op_min_view>&)
reducer_min& operator=(const rhs_proxy& rhs)
{ view() = rhs; return *this; }
-
+
//@}
- /** Allow read-only access to the value within the current view.
- *
+ /** Allows read-only access to the value within the current view.
+ *
* @returns A const reference to the value within the current view.
*/
const Type& get_reference() const { return view().get_reference(); }
-
+
/// @name Dereference
/** Dereferencing a wrapper is a no-op. It simply returns the wrapper.
* Combined with the rule that a wrapper forwards view operations to the
@@ -2536,12 +2671,12 @@ public:
reducer_min* operator->() { return this; }
reducer_min const* operator->() const { return this; }
//@}
-
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
@@ -2552,7 +2687,7 @@ public:
{
return *reinterpret_cast< reducer< op_min<Type, Compare, false> >* >(this);
}
-
+
operator const reducer< op_min<Type, Compare, false> >& () const
{
return *reinterpret_cast< const reducer< op_min<Type, Compare, false> >* >(this);
@@ -2561,15 +2696,15 @@ public:
};
-/** Compute the minimum of a reducer and a value.
+/** Computes the minimum of a reducer and a value.
*
* @deprecated Because reducer_min is deprecated.
*/
//@{
// The legacy definition of min_of(reducer_min, value) has different
-// behavior and a different return type than this definition. We add an
+// behavior and a different return type than this definition. We add an
// unused third argument to this version of the function to give it a different
-// signature, so that they won’t end up sharing a single object file entry.
+// signature, so that they won't end up sharing a single object file entry.
struct min_of_1_0_t {};
const min_of_1_0_t min_of_1_0 = {};
@@ -2597,18 +2732,18 @@ min_of(const Type& value, const reducer_min<Type, Compare>& r,
* that reducer_max_index is a proxy for the contained view, so that
* accumulator variable update operations can be applied directly to the
* reducer. For example, a value is maximized with a `reducer<%op_max_index>`
- * with `r->calc_max(i, a)`, but a value can be maximized with a
+ * with `r->calc_max(i, a)`, but a value can be maximized with a
* `%reducer_max` with `r.calc_max(i, aa)`.
*
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_max.
+ * reducers rather than the old wrappers like reducer_max.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_max_index`
+ * @note Implicit conversions are provided between `%reducer_max_index`
* and `reducer<%op_max_index>`. This allows incremental code
* conversion: old code that used `%reducer_max_index` can pass a
* `%reducer_max_index` to a converted function that now expects a
@@ -2617,7 +2752,7 @@ min_of(const Type& value, const reducer_min<Type, Compare>& r,
*
* @tparam Index The index type of the reducer.
* @tparam Type The value type of the reducer.
- * @tparam Compare The “less than” comparator type for the reducer.
+ * @tparam Compare The "less than" comparator type for the reducer.
*
* @see op_max_index
* @see op_max_index_view
@@ -2629,42 +2764,42 @@ template < typename Index
, typename Type
, typename Compare = std::less<Type>
>
-class reducer_max_index :
+class reducer_max_index :
public reducer< op_max_index<Index, Type, Compare, true> >
{
__CILKRTS_STATIC_ASSERT(
- ::cilk::internal::class_is_empty<
- typename ::cilk::internal::binary_functor<Compare>::type >::value,
+ ::cilk::internal::class_is_empty<
+ typename ::cilk::internal::binary_functor<Compare>::type >::value,
"cilk::reducer_max_index<Type, Compare> only works with "
"an empty Compare class");
typedef reducer< op_max_index<Index, Type, Compare, true> > base;
public:
-
+
/// Type of data in a reducer_max_index.
typedef Type basic_value_type;
-
+
/// The view type for the reducer.
typedef typename base::view_type view_type;
-
+
/// The view type for the reducer.
typedef typename base::view_type View;
-
+
/// The monoid type for the reducer.
typedef typename base::monoid_type monoid_type;
-
+
/// The monoid type for the reducer.
typedef typename base::monoid_type Monoid;
- /// The view’s rhs proxy type.
+ /// The view's rhs proxy type.
typedef min_max_internal::rhs_proxy<View> rhs_proxy;
-
+
using base::view;
/** @name Constructors
*/
//@{
-
- /// Construct the wrapper in its identity state (`!is_set()`).
+
+ /// Constructs the wrapper in its identity state (`!is_set()`).
reducer_max_index() : base() {}
/// Construct with a specified initial index and value.
@@ -2672,10 +2807,10 @@ public:
const Type& initial_value)
: base(initial_index, initial_value) {}
- /// Construct the wrapper with a specified comparator.
+ /// Constructs the wrapper with a specified comparator.
explicit reducer_max_index(const Compare& comp) : base(comp) {}
- /// Construct the wrapper with a specified initial index, value,
+ /// Constructs the wrapper with a specified initial index, value,
/// and comparator.
reducer_max_index(const Index& initial_index,
const Type& initial_value,
@@ -2683,49 +2818,49 @@ public:
: base(initial_index, initial_value, comp) {}
//@}
-
+
/** @name Set / Get
*/
//@{
-
- /// Set the index and value of this object.
+
+ /// Sets the index and value of this object.
void set_value(const Index& index, const Type& value)
{ base::set_value(std::make_pair(index, value)); }
- /// Return the maximum value.
- const Type& get_value() const
+ /// Returns the maximum value.
+ const Type& get_value() const
{ return view().get_reference(); }
- /// Return the maximum index.
- const Index& get_index() const
+ /// Returns the maximum index.
+ const Index& get_index() const
{ return view().get_index_reference(); }
- /// Return a const reference to value data member in the view.
+ /// Returns a const reference to value data member in the view.
const Type& get_reference() const
{ return view().get_reference(); }
-
- /// Return a const reference to index data member in the view.
- const Index& get_index_reference() const
+
+ /// Returns a const reference to index data member in the view.
+ const Index& get_index_reference() const
{ return view().get_index_reference(); }
-
+
//@}
-
+
/** @name Forwarded functions
* @details Functions that update the contained accumulator variable are
* simply forwarded to the contained @ref op_max_view. */
//@{
- /// @copydoc cilk_lib_1_0::min_max_internal::view_content::is_set() const
+ /// @copydoc cilk_lib_1_1::min_max_internal::view_content::is_set() const
bool is_set() const { return view().is_set(); }
/// @copydoc op_max_index_view::calc_max(const Index&, const Type&)
- reducer_max_index& calc_max(const Index& i, const Type& x)
+ reducer_max_index& calc_max(const Index& i, const Type& x)
{ view().calc_max(i, x); return *this; }
- /// @copydoc op_max_view::operator=(const min_max_internal::rhs_proxy<op_max_view>&)
+ /// @copydoc op_max_view::operator=(const min_max_internal::rhs_proxy<op_max_view>&)
reducer_max_index& operator=(const rhs_proxy& rhs)
{ view() = rhs; return *this; }
-
+
//@}
/// @name Dereference
@@ -2751,12 +2886,12 @@ public:
reducer_max_index* operator->() { return this; }
reducer_max_index const* operator->() const { return this; }
//@}
-
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
@@ -2767,13 +2902,13 @@ public:
{
return *reinterpret_cast< reducer< op_max_index<Index, Type, Compare, false> >* >(this);
}
-
+
operator const reducer< op_max_index<Index, Type, Compare, false> >& () const
{
return *reinterpret_cast< const reducer< op_max_index<Index, Type, Compare, false> >* >(this);
}
//@}
-
+
};
@@ -2783,18 +2918,18 @@ public:
* that reducer_min_index is a proxy for the contained view, so that
* accumulator variable update operations can be applied directly to the
* reducer. For example, a value is minimized with a `reducer<%op_min_index>`
- * with `r->calc_min(i, a)`, but a value can be minimized with a
+ * with `r->calc_min(i, a)`, but a value can be minimized with a
* `%reducer_min` with `r.calc_min(i, aa)`.
*
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_min.
+ * reducers rather than the old wrappers like reducer_min.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_min_index`
+ * @note Implicit conversions are provided between `%reducer_min_index`
* and `reducer<%op_min_index>`. This allows incremental code
* conversion: old code that used `%reducer_min_index` can pass a
* `%reducer_min_index` to a converted function that now expects a
@@ -2803,7 +2938,7 @@ public:
*
* @tparam Index The index type of the reducer.
* @tparam Type The value type of the reducer.
- * @tparam Compare The “less than” comparator type for the reducer.
+ * @tparam Compare The "less than" comparator type for the reducer.
*
* @see op_min_index
* @see op_min_index_view
@@ -2815,42 +2950,42 @@ template < typename Index
, typename Type
, typename Compare = std::less<Type>
>
-class reducer_min_index :
+class reducer_min_index :
public reducer< op_min_index<Index, Type, Compare, true> >
{
__CILKRTS_STATIC_ASSERT(
- ::cilk::internal::class_is_empty<
- typename ::cilk::internal::binary_functor<Compare>::type >::value,
+ ::cilk::internal::class_is_empty<
+ typename ::cilk::internal::binary_functor<Compare>::type >::value,
"cilk::reducer_min_index<Type, Compare> only works with "
"an empty Compare class");
typedef reducer< op_min_index<Index, Type, Compare, true> > base;
public:
-
+
/// Type of data in a reducer_min_index.
typedef Type basic_value_type;
-
+
/// The view type for the reducer.
typedef typename base::view_type view_type;
-
+
/// The view type for the reducer.
typedef typename base::view_type View;
-
+
/// The monoid type for the reducer.
typedef typename base::monoid_type monoid_type;
-
+
/// The monoid type for the reducer.
typedef typename base::monoid_type Monoid;
- /// The view’s rhs proxy type.
+ /// The view's rhs proxy type.
typedef min_max_internal::rhs_proxy<View> rhs_proxy;
-
+
using base::view;
/** @name Constructors
*/
//@{
-
- /// Construct the wrapper in its identity state (`!is_set()`).
+
+ /// Constructs the wrapper in its identity state (`!is_set()`).
reducer_min_index() : base() {}
/// Construct with a specified initial index and value.
@@ -2858,10 +2993,10 @@ public:
const Type& initial_value)
: base(initial_index, initial_value) {}
- /// Construct the wrapper with a specified comparator.
+ /// Constructs the wrapper with a specified comparator.
explicit reducer_min_index(const Compare& comp) : base(comp) {}
- /// Construct the wrapper with a specified initial index, value,
+ /// Constructs the wrapper with a specified initial index, value,
/// and comparator.
reducer_min_index(const Index& initial_index,
const Type& initial_value,
@@ -2869,49 +3004,49 @@ public:
: base(initial_index, initial_value, comp) {}
//@}
-
+
/** @name Set / Get
*/
//@{
-
- /// Set the index and value of this object.
+
+ /// Sets the index and value of this object.
void set_value(const Index& index, const Type& value)
{ base::set_value(std::make_pair(index, value)); }
- /// Return the minimum value.
- const Type& get_value() const
+ /// Returns the minimum value.
+ const Type& get_value() const
{ return view().get_reference(); }
- /// Return the minimum index.
- const Index& get_index() const
+ /// Returns the minimum index.
+ const Index& get_index() const
{ return view().get_index_reference(); }
- /// Return a const reference to value data member in the view.
+ /// Returns a const reference to value data member in the view.
const Type& get_reference() const
{ return view().get_reference(); }
-
- /// Return a const reference to index data member in the view.
- const Index& get_index_reference() const
+
+ /// Returns a const reference to index data member in the view.
+ const Index& get_index_reference() const
{ return view().get_index_reference(); }
-
+
//@}
-
+
/** @name Forwarded functions
* @details Functions that update the contained accumulator variable are
* simply forwarded to the contained @ref op_min_view. */
//@{
- /// @copydoc cilk_lib_1_0::min_max_internal::view_content::is_set() const
+ /// @copydoc cilk_lib_1_1::min_max_internal::view_content::is_set() const
bool is_set() const { return view().is_set(); }
/// @copydoc op_min_index_view::calc_min(const Index&, const Type&)
- reducer_min_index& calc_min(const Index& i, const Type& x)
+ reducer_min_index& calc_min(const Index& i, const Type& x)
{ view().calc_min(i, x); return *this; }
- /// @copydoc op_min_view::operator=(const min_max_internal::rhs_proxy<op_min_view>&)
+ /// @copydoc op_min_view::operator=(const min_max_internal::rhs_proxy<op_min_view>&)
reducer_min_index& operator=(const rhs_proxy& rhs)
{ view() = rhs; return *this; }
-
+
//@}
/// @name Dereference
@@ -2937,12 +3072,12 @@ public:
reducer_min_index* operator->() { return this; }
reducer_min_index const* operator->() const { return this; }
//@}
-
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
@@ -2953,19 +3088,19 @@ public:
{
return *reinterpret_cast< reducer< op_min_index<Index, Type, Compare, false> >* >(this);
}
-
+
operator const reducer< op_min_index<Index, Type, Compare, false> >& () const
{
return *reinterpret_cast< const reducer< op_min_index<Index, Type, Compare, false> >* >(this);
}
//@}
-
+
};
#ifndef CILK_LIBRARY_0_9_REDUCER_MINMAX
-} // namespace cilk_lib_1_0
-using namespace cilk_lib_1_0;
+} // namespace cilk_lib_1_1
+using namespace cilk_lib_1_1;
#endif
@@ -3017,7 +3152,7 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig
* @see @ref page_reducers_in_c
*/
//@{
-
+
#ifdef CILK_C_DEFINE_REDUCERS
@@ -3045,7 +3180,7 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig
#endif
-/** Max reducer type name.
+/** Declares max reducer type name.
*
* This macro expands into the identifier which is the name of the max reducer
* type for a specified numeric type.
@@ -3058,7 +3193,7 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig
#define CILK_C_REDUCER_MAX_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_max_,tn)
-/** Declare a max reducer object.
+/** Declares a max reducer object.
*
* This macro expands into a declaration of a max reducer object for a specified numeric
* type. For example:
@@ -3068,7 +3203,7 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig
* @param obj The variable name to be used for the declared reducer object.
* @param tn The @ref reducers_c_type_names "numeric type name" specifying the type of the
* reducer.
- * @param v The initial value for the reducer. (A value which can be assigned to the
+ * @param v The initial value for the reducer. (A value which can be assigned to the
* numeric type represented by @a tn.)
*
* @see @ref reducers_c_predefined
@@ -3080,7 +3215,7 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig
__CILKRTS_MKIDENT(cilk_c_reducer_max_identity_,tn), \
__cilkrts_hyperobject_noop_destroy, v)
-/** Maximize with a value.
+/** Maximizes with a value.
*
* `CILK_C_REDUCER_MAX_CALC(reducer, v)` sets the current view of the
* reducer to the max of its previous value and a specified new value.
@@ -3100,27 +3235,27 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig
/// @cond internal
-/** Declare the max reducer functions for a numeric type.
+/** Declares the max reducer functions for a numeric type.
*
* This macro expands into external function declarations for functions which implement
* the reducer functionality for the max reducer type for a specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer type name,
+ * @param tn The value "type name" identifier, used to construct the reducer type name,
* function names, etc.
*/
#define CILK_C_REDUCER_MAX_DECLARATION(t,tn,id) \
typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_MAX_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_max,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_max,tn);
-
-/** Define the max reducer functions for a numeric type.
+
+/** Defines the max reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement the
* reducer functionality for the max reducer type for a specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer type name,
+ * @param tn The value "type name" identifier, used to construct the reducer type name,
* function names, etc.
*/
#define CILK_C_REDUCER_MAX_DEFINITION(t,tn,id) \
@@ -3129,9 +3264,9 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig
{ if (*(t*)l < *(t*)r) *(t*)l = *(t*)r; } \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_max,tn) \
{ *(t*)v = id; }
-
+
//@{
-/** @def CILK_C_REDUCER_MAX_INSTANCE
+/** @def CILK_C_REDUCER_MAX_INSTANCE
* @brief Declare or define implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` will be defined, and
@@ -3147,7 +3282,7 @@ struct legacy_reducer_downcast< reducer< op_min_index<Index, Type, Compare, Alig
#endif
//@}
-/* Declare or define an instance of the reducer type and its functions for each
+/* Declare or define an instance of the reducer type and its functions for each
* numeric type.
*/
__CILKRTS_BEGIN_EXTERN_C
@@ -3184,7 +3319,7 @@ __CILKRTS_END_EXTERN_C
#define CILK_C_REDUCER_MAX_INDEX_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_max_index_,tn)
-/** Declare an op_max_index reducer object.
+/** Declares an op_max_index reducer object.
*
* This macro expands into a declaration of a max_index reducer object for a specified
* numeric type. For example:
@@ -3194,7 +3329,7 @@ __CILKRTS_END_EXTERN_C
* @param obj The variable name to be used for the declared reducer object.
* @param tn The @ref reducers_c_type_names "numeric type name" specifying the type of the
* reducer.
- * @param v The initial value for the reducer. (A value which can be assigned to the
+ * @param v The initial value for the reducer. (A value which can be assigned to the
* numeric type represented by @a tn.)
*
* @see @ref reducers_c_predefined
@@ -3206,7 +3341,7 @@ __CILKRTS_END_EXTERN_C
__CILKRTS_MKIDENT(cilk_c_reducer_max_index_identity_,tn), \
__cilkrts_hyperobject_noop_destroy, {0, v})
-/** Maximize with a value.
+/** Maximizes with a value.
*
* `CILK_C_REDUCER_MAX_INDEX_CALC(reducer, i, v)` sets the current view of the
* reducer to the max of its previous value and a specified new value.
@@ -3215,7 +3350,7 @@ __CILKRTS_END_EXTERN_C
* REDUCER_VIEW(reducer) = max_index(REDUCER_VIEW(reducer), v)
*
* If the value of the reducer is changed to @a v, then the index of the reducer is
- * changed to @a i.
+ * changed to @a i.
*
* @param reducer The reducer whose contained value and index are to be updated.
* @param i The index associated with the new value.
@@ -3231,7 +3366,7 @@ __CILKRTS_END_EXTERN_C
/// @cond internal
-/** Declare the max_index view type.
+/** Declares the max_index view type.
*
* The view of a max_index reducer is a structure containing both the
* maximum value for the reducer and the index that was associated with
@@ -3243,13 +3378,13 @@ __CILKRTS_END_EXTERN_C
t value; \
} __CILKRTS_MKIDENT(cilk_c_reducer_max_index_view_,tn)
-/** Declare the max_index reducer functions for a numeric type.
+/** Declares the max_index reducer functions for a numeric type.
*
* This macro expands into external function declarations for functions which implement
* the reducer functionality for the max_index reducer type for a specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer type name,
+ * @param tn The value "type name" identifier, used to construct the reducer type name,
* function names, etc.
*/
#define CILK_C_REDUCER_MAX_INDEX_DECLARATION(t,tn,id) \
@@ -3259,14 +3394,14 @@ __CILKRTS_END_EXTERN_C
CILK_C_REDUCER_MAX_INDEX_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_max_index,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_max_index,tn);
-
-/** Define the max_index reducer functions for a numeric type.
+
+/** Defines the max_index reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement the
* reducer functionality for the max_index reducer type for a specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer type name,
+ * @param tn The value "type name" identifier, used to construct the reducer type name,
* function names, etc.
*/
#define CILK_C_REDUCER_MAX_INDEX_DEFINITION(t,tn,id) \
@@ -3281,9 +3416,9 @@ __CILKRTS_END_EXTERN_C
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_max_index,tn) \
{ typedef __CILKRTS_MKIDENT(cilk_c_reducer_max_index_view_,tn) view_t; \
((view_t*)v)->index = 0; ((view_t*)v)->value = id; }
-
+
//@{
-/** @def CILK_C_REDUCER_MAX_INDEX_INSTANCE
+/** @def CILK_C_REDUCER_MAX_INDEX_INSTANCE
* @brief Declare or define implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` will be defined, and
@@ -3299,7 +3434,7 @@ __CILKRTS_END_EXTERN_C
#endif
//@}
-/* Declare or define an instance of the reducer type and its functions for each
+/* Declares or defines an instance of the reducer type and its functions for each
* numeric type.
*/
__CILKRTS_BEGIN_EXTERN_C
@@ -3323,7 +3458,7 @@ __CILKRTS_END_EXTERN_C
/// @endcond
-/** Min reducer type name.
+/** Declares min reducer type name.
*
* This macro expands into the identifier which is the name of the min reducer
* type for a specified numeric type.
@@ -3336,7 +3471,7 @@ __CILKRTS_END_EXTERN_C
#define CILK_C_REDUCER_MIN_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_min_,tn)
-/** Declare a min reducer object.
+/** Declares a min reducer object.
*
* This macro expands into a declaration of a min reducer object for a specified numeric
* type. For example:
@@ -3346,7 +3481,7 @@ __CILKRTS_END_EXTERN_C
* @param obj The variable name to be used for the declared reducer object.
* @param tn The @ref reducers_c_type_names "numeric type name" specifying the type of the
* reducer.
- * @param v The initial value for the reducer. (A value which can be assigned to the
+ * @param v The initial value for the reducer. (A value which can be assigned to the
* numeric type represented by @a tn.)
*
* @see @ref reducers_c_predefined
@@ -3358,7 +3493,7 @@ __CILKRTS_END_EXTERN_C
__CILKRTS_MKIDENT(cilk_c_reducer_min_identity_,tn), \
__cilkrts_hyperobject_noop_destroy, v)
-/** Minimize with a value.
+/** Minimizes with a value.
*
* `CILK_C_REDUCER_MIN_CALC(reducer, v)` sets the current view of the
* reducer to the min of its previous value and a specified new value.
@@ -3378,27 +3513,27 @@ __CILKRTS_END_EXTERN_C
/// @cond internal
-/** Declare the min reducer functions for a numeric type.
+/** Declares the min reducer functions for a numeric type.
*
* This macro expands into external function declarations for functions which implement
* the reducer functionality for the min reducer type for a specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer type name,
+ * @param tn The value "type name" identifier, used to construct the reducer type name,
* function names, etc.
*/
#define CILK_C_REDUCER_MIN_DECLARATION(t,tn,id) \
typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_MIN_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_min,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_min,tn);
-
-/** Define the min reducer functions for a numeric type.
+
+/** Defines the min reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement the
* reducer functionality for the min reducer type for a specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer type name,
+ * @param tn The value "type name" identifier, used to construct the reducer type name,
* function names, etc.
*/
#define CILK_C_REDUCER_MIN_DEFINITION(t,tn,id) \
@@ -3407,9 +3542,9 @@ __CILKRTS_END_EXTERN_C
{ if (*(t*)l > *(t*)r) *(t*)l = *(t*)r; } \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_min,tn) \
{ *(t*)v = id; }
-
+
//@{
-/** @def CILK_C_REDUCER_MIN_INSTANCE
+/** @def CILK_C_REDUCER_MIN_INSTANCE
* @brief Declare or define implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` will be defined, and
@@ -3425,7 +3560,7 @@ __CILKRTS_END_EXTERN_C
#endif
//@}
-/* Declare or define an instance of the reducer type and its functions for each
+/* Declares or defines an instance of the reducer type and its functions for each
* numeric type.
*/
__CILKRTS_BEGIN_EXTERN_C
@@ -3449,7 +3584,7 @@ __CILKRTS_END_EXTERN_C
/// @endcond
-/** Min_index reducer type name.
+/** Declares `min_index` reducer type name.
*
* This macro expands into the identifier which is the name of the min_index reducer
* type for a specified numeric type.
@@ -3462,7 +3597,7 @@ __CILKRTS_END_EXTERN_C
#define CILK_C_REDUCER_MIN_INDEX_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_min_index_,tn)
-/** Declare an op_min_index reducer object.
+/** Declares an op_min_index reducer object.
*
* This macro expands into a declaration of a min_index reducer object for a specified
* numeric type. For example:
@@ -3472,7 +3607,7 @@ __CILKRTS_END_EXTERN_C
* @param obj The variable name to be used for the declared reducer object.
* @param tn The @ref reducers_c_type_names "numeric type name" specifying the type of the
* reducer.
- * @param v The initial value for the reducer. (A value which can be assigned to the
+ * @param v The initial value for the reducer. (A value which can be assigned to the
* numeric type represented by @a tn.)
*
* @see @ref reducers_c_predefined
@@ -3484,7 +3619,7 @@ __CILKRTS_END_EXTERN_C
__CILKRTS_MKIDENT(cilk_c_reducer_min_index_identity_,tn), \
__cilkrts_hyperobject_noop_destroy, {0, v})
-/** Minimize with a value.
+/** Minimizes with a value.
*
* `CILK_C_REDUCER_MIN_INDEX_CALC(reducer, i, v)` sets the current view of the
* reducer to the min of its previous value and a specified new value.
@@ -3493,7 +3628,7 @@ __CILKRTS_END_EXTERN_C
* REDUCER_VIEW(reducer) = min_index(REDUCER_VIEW(reducer), v)
*
* If the value of the reducer is changed to @a v, then the index of the reducer is
- * changed to @a i.
+ * changed to @a i.
*
* @param reducer The reducer whose contained value and index are to be updated.
* @param i The index associated with the new value.
@@ -3509,7 +3644,7 @@ __CILKRTS_END_EXTERN_C
/// @cond internal
-/** Declare the min_index view type.
+/** Declares the min_index view type.
*
* The view of a min_index reducer is a structure containing both the
* minimum value for the reducer and the index that was associated with
@@ -3521,13 +3656,13 @@ __CILKRTS_END_EXTERN_C
t value; \
} __CILKRTS_MKIDENT(cilk_c_reducer_min_index_view_,tn)
-/** Declare the min_index reducer functions for a numeric type.
+/** Declares the min_index reducer functions for a numeric type.
*
* This macro expands into external function declarations for functions which implement
* the reducer functionality for the min_index reducer type for a specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer type name,
+ * @param tn The value "type name" identifier, used to construct the reducer type name,
* function names, etc.
*/
#define CILK_C_REDUCER_MIN_INDEX_DECLARATION(t,tn,id) \
@@ -3537,14 +3672,14 @@ __CILKRTS_END_EXTERN_C
CILK_C_REDUCER_MIN_INDEX_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_min_index,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_min_index,tn);
-
-/** Define the min_index reducer functions for a numeric type.
+
+/** Defines the min_index reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement the
* reducer functionality for the min_index reducer type for a specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer type name,
+ * @param tn The value "type name" identifier, used to construct the reducer type name,
* function names, etc.
*/
#define CILK_C_REDUCER_MIN_INDEX_DEFINITION(t,tn,id) \
@@ -3559,10 +3694,10 @@ __CILKRTS_END_EXTERN_C
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_min_index,tn) \
{ typedef __CILKRTS_MKIDENT(cilk_c_reducer_min_index_view_,tn) view_t; \
((view_t*)v)->index = 0; ((view_t*)v)->value = id; }
-
+
//@{
-/** @def CILK_C_REDUCER_MIN_INDEX_INSTANCE
- * @brief Declare or define implementation functions for a reducer type.
+/** @def CILK_C_REDUCER_MIN_INDEX_INSTANCE
+ * @brief Declares or defines implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` will be defined, and
* this macro will generate reducer implementation functions. Everywhere else, `CILK_C_DEFINE_REDUCERS`
@@ -3577,7 +3712,7 @@ __CILKRTS_END_EXTERN_C
#endif
//@}
-/* Declare or define an instance of the reducer type and its functions for each
+/* Declares or defines an instance of the reducer type and its functions for each
* numeric type.
*/
__CILKRTS_BEGIN_EXTERN_C
@@ -3603,4 +3738,4 @@ __CILKRTS_END_EXTERN_C
//@}
-#endif // defined REDUCER_MAX_H_INCLUDED
+#endif // defined REDUCER_MIN_MAX_H_INCLUDED
diff --git a/libcilkrts/include/cilk/reducer_opadd.h b/libcilkrts/include/cilk/reducer_opadd.h
index 4b7a83f845d..46d4b6e9b57 100644
--- a/libcilkrts/include/cilk/reducer_opadd.h
+++ b/libcilkrts/include/cilk/reducer_opadd.h
@@ -1,10 +1,8 @@
/* reducer_opadd.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_opadd.h
@@ -55,9 +66,9 @@
*
* @ingroup Reducers
*
- * You should be familiar with @ref pagereducers "Cilk reducers", described in
- * file `reducers.md`, and particularly with @ref reducers_using, before trying
- * to use the information in this file.
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file `reducers.md`, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
*
* @section redopadd_usage Usage Example
*
@@ -78,11 +89,11 @@
* @subsection redopadd_monoid_operator Operator
*
* The operator of an addition reducer is the addition operator, defined by
- * the “`+`” binary operator on `Type`.
+ * the "`+`" binary operator on `Type`.
*
* @subsection redopadd_monoid_identity Identity
*
- * The identity value of the reducer is the numeric value “`0`”. This is
+ * The identity value of the reducer is the numeric value "`0`". This is
* expected to be the value of the default constructor `Type()`.
*
* @section redopadd_operations Operations
@@ -130,22 +141,22 @@
* @section redopadd_floating_point Issues with Floating-Point Types
*
* Because of precision and round-off issues, floating-point addition is not
- * really associative. For example, `(1e30 + -1e30) + 1 == 1`, but
+ * really associative. For example, `(1e30 + -1e30) + 1 == 1`, but
* `1e30 + (-1e30 + 1) == 0`.
*
- * In many cases, this won’t matter, but computations which have been
+ * In many cases, this won't matter, but computations which have been
* carefully ordered to control round-off errors may not deal well with
* being reassociated. In general, you should be sure to understand the
- * floating-point behavior of your program before doing any transformation
- * that will reassociate its computations.
+ * floating-point behavior of your program before doing any transformation
+ * that will reassociate its computations.
*
* @section redopadd_types Type and Operator Requirements
*
* `Type` must be `Copy Constructible`, `Default Constructible`, and
* `Assignable`.
*
- * The operator “`+=`” must be defined on `Type`, with `x += a` having the
- * same meaning as `x = x + a`. In addition, if the code uses the “`-=`”,
+ * The operator "`+=`" must be defined on `Type`, with `x += a` having the
+ * same meaning as `x = x + a`. In addition, if the code uses the "`-=`",
* pre-increment, post-increment, pre-decrement, or post-decrement operators,
* then the corresponding operators must be defined on `Type`.
*
@@ -174,18 +185,18 @@ namespace cilk {
/** The addition reducer view class.
*
- * This is the view class for reducers created with
- * `cilk::reducer< cilk::op_add<Type> >`. It holds the accumulator variable
- * for the reduction, and allows only addition and subtraction operations to
+ * This is the view class for reducers created with
+ * `cilk::reducer< cilk::op_add<Type> >`. It holds the accumulator variable
+ * for the reduction, and allows only addition and subtraction operations to
* be performed on it.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `+=` operation would be used in an expression like `*r += a`, where
* `r` is an op_add reducer variable.
*
- * @tparam Type The type of the contained accumulator variable. This will
- * be the value type of a monoid_with_view that is
+ * @tparam Type The type of the contained accumulator variable. This will
+ * be the value type of a monoid_with_view that is
* instantiated with this view.
*
* @see ReducersAdd
@@ -197,19 +208,19 @@ template <typename Type>
class op_add_view : public scalar_view<Type>
{
typedef scalar_view<Type> base;
-
+
public:
- /** Class to represent the right-hand side of
+ /** Class to represent the right-hand side of
* `*reducer = *reducer ± value`.
*
* The only assignment operator for the op_add_view class takes an
* rhs_proxy as its operand. This results in the syntactic restriction
* that the only expressions that can be assigned to an op_add_view are
- * ones which generate an rhs_proxy — that is, expressions of the form
+ * ones which generate an rhs_proxy - that is, expressions of the form
* `op_add_view ± value ... ± value`.
*
* @warning
- * The lhs and rhs views in such an assignment must be the same;
+ * The lhs and rhs views in such an assignment must be the same;
* otherwise, the behavior will be undefined. (I.e., `v1 = v1 + x` is
* legal; `v1 = v2 + x` is illegal.) This condition will be checked with a
* runtime assertion when compiled in debug mode.
@@ -222,7 +233,7 @@ public:
const op_add_view* m_view;
Type m_value;
- // Constructor is invoked only from op_add_view::operator+() and
+ // Constructor is invoked only from op_add_view::operator+() and
// op_add_view::operator-().
//
rhs_proxy(const op_add_view* view, const Type& value) :
@@ -232,13 +243,13 @@ public:
rhs_proxy(); // Disable default constructor
public:
- //@{
- /** Add or subtract an additional rhs value. If `v` is an op_add_view
- * and `a1` is a value, then the expression `v + a1` invokes the view’s
- * `operator+()` to create an rhs_proxy for `(v, a1)`; then
- * `v + a1 + a2` invokes the rhs_proxy’s `operator+()` to create a new
+ ///@{
+ /** Adds or subtracts an additional rhs value. If `v` is an op_add_view
+ * and `a1` is a value, then the expression `v + a1` invokes the view's
+ * `operator+()` to create an rhs_proxy for `(v, a1)`; then
+ * `v + a1 + a2` invokes the rhs_proxy's `operator+()` to create a new
* rhs_proxy for `(v, a1+a2)`. This allows the right-hand side of an
- * assignment to be not just `view ± value`, but
+ * assignment to be not just `view ± value`, but
* `view ± value ± value ... ± value`. The effect is that
*
* v = v ± a1 ± a2 ... ± an;
@@ -249,11 +260,11 @@ public:
*/
rhs_proxy& operator+(const Type& x) { m_value += x; return *this; }
rhs_proxy& operator-(const Type& x) { m_value -= x; return *this; }
- //@}
+ ///@}
};
-
- /** Default/identity constructor. This constructor initializes the
+
+ /** Default/identity constructor. This constructor initializes the
* contained value to `Type()`, which is expected to be the identity value
* for addition on `Type`.
*/
@@ -262,8 +273,8 @@ public:
/** Construct with a specified initial value.
*/
explicit op_add_view(const Type& v) : base(v) {}
-
- /** Reduction operation.
+
+ /** Reduces the views of two strands.
*
* This function is invoked by the @ref op_add monoid to combine the views
* of two strands when the right strand merges with the left one. It adds
@@ -284,13 +295,13 @@ public:
* These functions support the various syntaxes for incrementing or
* decrementing the accumulator variable contained in the view.
*/
- //@{
+ ///@{
- /** Increment the accumulator variable by @a x.
+ /** Increments the accumulator variable by @a x.
*/
op_add_view& operator+=(const Type& x) { this->m_value += x; return *this; }
- /** Decrement the accumulator variable by @a x.
+ /** Decrements the accumulator variable by @a x.
*/
op_add_view& operator-=(const Type& x) { this->m_value -= x; return *this; }
@@ -298,7 +309,7 @@ public:
*/
op_add_view& operator++() { ++this->m_value; return *this; }
- /** Post-increment.
+ /** Post-increments.
*
* @note Conventionally, post-increment operators return the old value
* of the incremented variable. However, reducer views do not
@@ -307,11 +318,11 @@ public:
*/
void operator++(int) { this->m_value++; }
- /** Pre-decrement.
+ /** Pre-decrements.
*/
op_add_view& operator--() { --this->m_value; return *this; }
- /** Post-decrement.
+ /** Post-decrements.
*
* @note Conventionally, post-decrement operators return the old value
* of the decremented variable. However, reducer views do not
@@ -320,19 +331,19 @@ public:
*/
void operator--(int) { this->m_value--; }
- /** Create an object representing `*this + x`.
+ /** Creates an object representing `*this + x`.
*
* @see rhs_proxy
*/
rhs_proxy operator+(const Type& x) const { return rhs_proxy(this, x); }
- /** Create an object representing `*this - x`.
+ /** Creates an object representing `*this - x`.
*
* @see rhs_proxy
*/
rhs_proxy operator-(const Type& x) const { return rhs_proxy(this, -x); }
- /** Assign the result of a `view ± value` expression to the view. Note that
+ /** Assigns the result of a `view ± value` expression to the view. Note that
* this is the only assignment operator for this class.
*
* @see rhs_proxy
@@ -342,12 +353,12 @@ public:
this->m_value += rhs.m_value;
return *this;
}
-
- //@}
+
+ ///@}
};
-/** Monoid class for addition reductions. Instantiate the cilk::reducer
+/** Monoid class for addition reductions. Instantiate the cilk::reducer
* template class with an op_add monoid to create an addition reducer class.
* For example, to compute
* the sum of a set of `int` values:
@@ -356,10 +367,10 @@ public:
*
* @tparam Type The reducer value type.
* @tparam Align If `false` (the default), reducers instantiated on this
- * monoid will be naturally aligned (the Cilk library 1.0
+ * monoid will be naturally aligned (the Intel Cilk Plus library 1.0
* behavior). If `true`, reducers instantiated on this monoid
- * will be cache-aligned for binary compatibility with
- * reducers in Cilk library version 0.9.
+ * will be cache-aligned for binary compatibility with
+ * reducers in Intel Cilk Plus library version 0.9.
*
* @see ReducersAdd
* @see op_add_view
@@ -378,13 +389,13 @@ struct op_add : public monoid_with_view<op_add_view<Type>, Align> {};
* value can be added to a `%reducer_opadd` with `r += a`.
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_opadd.
+ * reducers rather than the old wrappers like reducer_opadd.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_opadd`
+ * @note Implicit conversions are provided between `%reducer_opadd`
* and `reducer<%op_add>`. This allows incremental code
* conversion: old code that used `%reducer_opadd` can pass a
* `%reducer_opadd` to a converted function that now expects a
@@ -408,8 +419,8 @@ class reducer_opadd : public reducer< op_add<Type, true> >
public:
/// The view type for the reducer.
typedef typename base::view_type view_type;
-
- /// The view’s rhs proxy type.
+
+ /// The view's rhs proxy type.
typedef typename view_type::rhs_proxy rhs_proxy;
/// The view type for the reducer.
@@ -420,8 +431,8 @@ class reducer_opadd : public reducer< op_add<Type, true> >
/** @name Constructors
*/
- //@{
-
+ ///@{
+
/** Default (identity) constructor.
*
* Constructs the wrapper with the default initial value of `Type()`.
@@ -433,29 +444,29 @@ class reducer_opadd : public reducer< op_add<Type, true> >
* Constructs the wrapper with a specified initial value.
*/
explicit reducer_opadd(const Type& initial_value) : base(initial_value) {}
-
- //@}
+
+ ///@}
/** @name Forwarded functions
* @details Functions that update the contained accumulator variable are
* simply forwarded to the contained @ref op_add_view. */
- //@{
-
+ ///@{
+
/// @copydoc op_add_view::operator+=(const Type&)
reducer_opadd& operator+=(const Type& x) { view() += x; return *this; }
-
+
/// @copydoc op_add_view::operator-=(const Type&)
reducer_opadd& operator-=(const Type& x) { view() -= x; return *this; }
-
+
/// @copydoc op_add_view::operator++()
reducer_opadd& operator++() { ++view(); return *this; }
-
+
/// @copydoc op_add_view::operator++(int)
void operator++(int) { view()++; }
-
+
/// @copydoc op_add_view::operator-\-()
reducer_opadd& operator--() { --view(); return *this; }
-
+
/// @copydoc op_add_view::operator-\-(int)
void operator--(int) { view()--; }
@@ -463,26 +474,26 @@ class reducer_opadd : public reducer< op_add<Type, true> >
// reducer_opadd::operator-() have different behavior and a different
// return type than this definition. The legacy version is defined as a
// member function, so this new version is defined as a free function to
- // give it a different signature, so that they won’t end up sharing a
+ // give it a different signature, so that they won't end up sharing a
// single object file entry.
/// @copydoc op_add_view::operator+(const Type&) const
friend rhs_proxy operator+(const reducer_opadd& r, const Type& x)
- {
- return r.view() + x;
+ {
+ return r.view() + x;
}
/// @copydoc op_add_view::operator-(const Type&) const
friend rhs_proxy operator-(const reducer_opadd& r, const Type& x)
- {
- return r.view() - x;
+ {
+ return r.view() - x;
}
/// @copydoc op_add_view::operator=(const rhs_proxy&)
- reducer_opadd& operator=(const rhs_proxy& temp)
+ reducer_opadd& operator=(const rhs_proxy& temp)
{
view() = temp;
- return *this;
+ return *this;
}
- //@}
+ ///@}
/** @name Dereference
* @details Dereferencing a wrapper is a no-op. It simply returns the
@@ -501,25 +512,25 @@ class reducer_opadd : public reducer< op_add<Type, true> >
* // operator += is a wrapper member function that
* // calls the corresponding view function
*/
- //@{
+ ///@{
reducer_opadd& operator*() { return *this; }
reducer_opadd const& operator*() const { return *this; }
reducer_opadd* operator->() { return this; }
reducer_opadd const* operator->() const { return this; }
- //@}
-
+ ///@}
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
* pseudo-upcasts to the corresponding unaligned reducer class.
*/
- //@{
+ ///@{
operator reducer< op_add<Type, false> >& ()
{
return *reinterpret_cast< reducer< op_add<Type, false> >* >(this);
@@ -528,15 +539,15 @@ class reducer_opadd : public reducer< op_add<Type, true> >
{
return *reinterpret_cast< const reducer< op_add<Type, false> >* >(this);
}
- //@}
+ ///@}
};
/// @cond internal
/** Metafunction specialization for reducer conversion.
*
- * This specialization of the @ref legacy_reducer_downcast template class
- * defined in reducer.h causes the `reducer< op_add<Type> >` class to have an
- * `operator reducer_opadd<Type>& ()` conversion operator that statically
+ * This specialization of the @ref legacy_reducer_downcast template class
+ * defined in reducer.h causes the `reducer< op_add<Type> >` class to have an
+ * `operator reducer_opadd<Type>& ()` conversion operator that statically
* downcasts the `reducer<op_add>` to the corresponding `reducer_opadd` type.
* (The reverse conversion, from `reducer_opadd` to `reducer<op_add>`, is just
* an upcast, which is provided for free by the language.)
@@ -557,20 +568,20 @@ struct legacy_reducer_downcast<reducer<op_add<Type, Align> > >
/** @ingroup ReducersAdd
*/
-//@{
+///@{
/** @name C Language Reducer Macros
*
- * These macros are used to declare and work with numeric op_add reducers in
+ * These macros are used to declare and work with numeric op_add reducers in
* C code.
*
* @see @ref page_reducers_in_c
*/
- //@{
-
+ ///@{
+
__CILKRTS_BEGIN_EXTERN_C
-/** Opadd reducer type name.
+/** Declares opadd reducer type name.
*
* This macro expands into the identifier which is the name of the op_add
* reducer type for a specified numeric type.
@@ -584,7 +595,7 @@ __CILKRTS_BEGIN_EXTERN_C
#define CILK_C_REDUCER_OPADD_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_opadd_,tn)
-/** Declare an op_add reducer object.
+/** Declares an op_add reducer object.
*
* This macro expands into a declaration of an op_add reducer object for a
* specified numeric type. For example:
@@ -609,29 +620,29 @@ __CILKRTS_BEGIN_EXTERN_C
/// @cond internal
-/** Declare the op_add reducer functions for a numeric type.
+/** Declares the op_add reducer functions for a numeric type.
*
* This macro expands into external function declarations for functions which
* implement the reducer functionality for the op_add reducer type for a
* specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPADD_DECLARATION(t,tn) \
typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPADD_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opadd,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opadd,tn);
-
-/** Define the op_add reducer functions for a numeric type.
+
+/** Defines the op_add reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement
* the reducer functionality for the op_add reducer type for a specified
* numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPADD_DEFINITION(t,tn) \
@@ -640,13 +651,13 @@ __CILKRTS_BEGIN_EXTERN_C
{ *(t*)l += *(t*)r; } \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opadd,tn) \
{ *(t*)v = 0; }
-
-//@{
-/** @def CILK_C_REDUCER_OPADD_INSTANCE
- * @brief Declare or define implementation functions for a reducer type.
+
+///@{
+/** @def CILK_C_REDUCER_OPADD_INSTANCE
+ * @brief Declares or defines implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
- * will be defined, and this macro will generate reducer implementation
+ * will be defined, and this macro will generate reducer implementation
* functions. Everywhere else, `CILK_C_DEFINE_REDUCERS` will be undefined,
* and this macro will expand into external declarations for the functions.
*/
@@ -657,9 +668,9 @@ __CILKRTS_BEGIN_EXTERN_C
# define CILK_C_REDUCER_OPADD_INSTANCE(t,tn) \
CILK_C_REDUCER_OPADD_DECLARATION(t,tn)
#endif
-//@}
+///@}
-/* Declare or define an instance of the reducer type and its functions for each
+/* Declares or defines an instance of the reducer type and its functions for each
* numeric type.
*/
CILK_C_REDUCER_OPADD_INSTANCE(char, char)
@@ -683,8 +694,8 @@ CILK_C_REDUCER_OPADD_INSTANCE(long double, longdouble)
__CILKRTS_END_EXTERN_C
-//@}
+///@}
-//@}
+///@}
#endif /* REDUCER_OPADD_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_opand.h b/libcilkrts/include/cilk/reducer_opand.h
index 8a086c91818..44d537d4f36 100644
--- a/libcilkrts/include/cilk/reducer_opand.h
+++ b/libcilkrts/include/cilk/reducer_opand.h
@@ -1,10 +1,8 @@
/* reducer_opand.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,11 +29,25 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_opand.h
*
- * @brief Defines classes for doing parallel bitwise and reductions.
+ * @brief Defines classes for doing parallel bitwise AND reductions.
*
* @ingroup ReducersAnd
*
@@ -48,16 +59,16 @@
#include <cilk/reducer.h>
-/** @defgroup ReducersAnd Bitwise And Reducers
+/** @defgroup ReducersAnd Bitwise AND Reducers
*
- * Bitwise and reducers allow the computation of the bitwise and of a set of
+ * Bitwise AND reducers allow the computation of the bitwise AND of a set of
* values in parallel.
*
* @ingroup Reducers
*
- * You should be familiar with @ref pagereducers "Cilk reducers", described in
- * file `reducers.md`, and particularly with @ref reducers_using, before trying
- * to use the information in this file.
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file `reducers.md`, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
*
* @section redopand_usage Usage Example
*
@@ -72,19 +83,18 @@
*
* @subsection redopand_monoid_values Value Set
*
- * The value set of a bitwise and reducer is the set of values of `Type`,
+ * The value set of a bitwise AND reducer is the set of values of `Type`,
* which is expected to be a builtin integer type which has a representation
* as a sequence of bits (or something like it, such as `bool` or
* `std::bitset`).
*
* @subsection redopand_monoid_operator Operator
*
- * The operator of a bitwise and reducer is the bitwise and operator, defined
- * by the “`&`” binary operator on `Type`.
+ * The bitwise AND operator is defined by the "`&`" binary operator on `Type`.
*
* @subsection redopand_monoid_identity Identity
*
- * The identity value of the reducer is the value whose representation
+ * The identity value of the reducer is the value whose representation
* contains all 1-bits. This is expected to be the value of the expression
* `~Type()` (i.e., the bitwise negation operator applied to the default value
* of the value type).
@@ -106,7 +116,7 @@
*
* @subsection redopand_initial Initial Values
*
- * If a bitwise and reducer is constructed without an explicit initial value,
+ * If a bitwise AND reducer is constructed without an explicit initial value,
* then its initial value will be its identity value, as long as `Type`
* satisfies the requirements of @ref redopand_types.
*
@@ -121,17 +131,17 @@
* `Type` must be `Copy Constructible`, `Default Constructible`, and
* `Assignable`.
*
- * The operator “`&=`” must be defined on `Type`, with `x &= a` having the
+ * The operator "`&=`" must be defined on `Type`, with `x &= a` having the
* same meaning as `x = x & a`.
*
* The expression `~ Type()` must be a valid expression which yields the
* identity value (the value of `Type` whose representation consists of all
* 1-bits).
*
- * @section redopand_in_c Bitwise And Reducers in C
+ * @section redopand_in_c Bitwise AND Reducers in C
*
* The @ref CILK_C_REDUCER_OPAND and @ref CILK_C_REDUCER_OPAND_TYPE macros can
- * be used to do bitwise and reductions in C. For example:
+ * be used to do bitwise AND reductions in C. For example:
*
* CILK_C_REDUCER_OPAND(r, uint, ~0);
* CILK_C_REGISTER_REDUCER(r);
@@ -148,14 +158,14 @@
namespace cilk {
-/** The bitwise and reducer view class.
+/** The bitwise AND reducer view class.
*
- * This is the view class for reducers created with
- * `cilk::reducer< cilk::op_and<Type> >`. It holds the accumulator variable
- * for the reduction, and allows only `and` operations to be performed on it.
+ * This is the view class for reducers created with
+ * `cilk::reducer< cilk::op_and<Type> >`. It holds the accumulator variable
+ * for the reduction, and allows only AND operations to be performed on it.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `&=` operation would be used in an expression like `*r &= a`, where
* `r` is an opmod reducer variable.
*
@@ -172,18 +182,18 @@ template <typename Type>
class op_and_view : public scalar_view<Type>
{
typedef scalar_view<Type> base;
-
+
public:
/** Class to represent the right-hand side of `*reducer = *reducer & value`.
*
* The only assignment operator for the op_and_view class takes an
- * rhs_proxy as its operand. This results in the syntactic restriction
+ * rhs_proxy as its operand. This results in the syntactic restriction
* that the only expressions that can be assigned to an op_and_view are
- * ones which generate an rhs_proxy — that is, expressions of the form
+ * ones which generate an rhs_proxy - that is, expressions of the form
* `op_and_view & value ... & value`.
*
* @warning
- * The lhs and rhs views in such an assignment must be the same;
+ * The lhs and rhs views in such an assignment must be the same;
* otherwise, the behavior will be undefined. (I.e., `v1 = v1 & x` is
* legal; `v1 = v2 & x` is illegal.) This condition will be checked with
* a runtime assertion when compiled in debug mode.
@@ -205,12 +215,12 @@ public:
rhs_proxy(); // Disable default constructor
public:
- /** Bitwise and with an additional rhs value. If `v` is an op_and_view
+ /** Bitwise AND with an additional `rhs` value. If `v` is an op_and_view
* and `a1` is a value, then the expression `v & a1` invokes the
- * view’s `operator&()` to create an rhs_proxy for `(v, a1)`; then
- * `v & a1 & a2` invokes the rhs_proxy’s `operator&()` to create a new
+ * view's `operator&()` to create an rhs_proxy for `(v, a1)`; then
+ * `v & a1 & a2` invokes the rhs_proxy's `operator&()` to create a new
* rhs_proxy for `(v, a1&a2)`. This allows the right-hand side of an
- * assignment to be not just `view & value`, but
+ * assignment to be not just `view & value`, but
* `view & value & value ... & value`. The effect is that
*
* v = v & a1 & a2 ... & an;
@@ -231,13 +241,13 @@ public:
/** Construct with a specified initial value.
*/
explicit op_and_view(const Type& v) : base(v) {}
-
-
- /** Reduction operation.
+
+
+ /** Reduces the views of two strands.
*
* This function is invoked by the @ref op_and monoid to combine the views
* of two strands when the right strand merges with the left one. It
- * “ands” the value contained in the left-strand view with the value
+ * "ANDs" the value contained in the left-strand view with the value
* contained in the right-strand view, and leaves the value in the
* right-strand view undefined.
*
@@ -248,25 +258,25 @@ public:
* reduce operation.
*/
void reduce(op_and_view* right) { this->m_value &= right->m_value; }
-
+
/** @name Accumulator variable updates.
*
- * These functions support the various syntaxes for “anding” the
+ * These functions support the various syntaxes for "ANDing" the
* accumulator variable contained in the view with some value.
*/
- //@{
+ ///@{
- /** And the accumulator variable with @a x.
+ /** Performs AND between the accumulator variable and @a x.
*/
op_and_view& operator&=(const Type& x) { this->m_value &= x; return *this; }
- /** Create an object representing `*this & x`.
+ /** Creates an object representing `*this & x`.
*
* @see rhs_proxy
*/
rhs_proxy operator&(const Type& x) const { return rhs_proxy(this, x); }
- /** Assign the result of a `view & value` expression to the view. Note that
+ /** Assigns the result of a `view & value` expression to the view. Note that
* this is the only assignment operator for this class.
*
* @see rhs_proxy
@@ -276,23 +286,23 @@ public:
this->m_value &= rhs.m_value;
return *this;
}
-
- //@}
+
+ ///@}
};
-/** Monoid class for bitwise and reductions. Instantiate the cilk::reducer
- * template class with an op_and monoid to create a bitwise and reducer
- * class. For example, to compute the bitwise and of a set of `unsigned long`
+/** Monoid class for bitwise AND reductions. Instantiate the cilk::reducer
+ * template class with an op_and monoid to create a bitwise AND reducer
+ * class. For example, to compute the bitwise AND of a set of `unsigned long`
* values:
*
* cilk::reducer< cilk::op_and<unsigned long> > r;
*
* @tparam Type The reducer value type.
* @tparam Align If `false` (the default), reducers instantiated on this
- * monoid will be naturally aligned (the Cilk library 1.0
+ * monoid will be naturally aligned (the Intel Cilk Plus library 1.0
* behavior). If `true`, reducers instantiated on this monoid
- * will be cache-aligned for binary compatibility with
- * reducers in Cilk library version 0.9.
+ * will be cache-aligned for binary compatibility with
+ * reducers in Intel Cilk Plus library version 0.9.
*
* @see ReducersAnd
* @see op_and_view
@@ -302,22 +312,22 @@ public:
template <typename Type, bool Align = false>
struct op_and : public monoid_with_view<op_and_view<Type>, Align> {};
-/** Deprecated bitwise and reducer class.
+/** Deprecated bitwise AND reducer class.
*
* reducer_opand is the same as @ref reducer<@ref op_and>, except that
* reducer_opand is a proxy for the contained view, so that accumulator
* variable update operations can be applied directly to the reducer. For
- * example, a value is anded with a `reducer<%op_and>` with `*r &= a`, but a
- * value can be anded with a `%reducer_opand` with `r &= a`.
+ * example, a value is "ANDed" with a `reducer<%op_and>` with `*r &= a`, but a
+ * value can be "ANDed" with a `%reducer_opand` with `r &= a`.
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_opand.
+ * reducers rather than the old wrappers like reducer_opand.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_opand`
+ * @note Implicit conversions are provided between `%reducer_opand`
* and `reducer<%op_and>`. This allows incremental code
* conversion: old code that used `%reducer_opand` can pass a
* `%reducer_opand` to a converted function that now expects a
@@ -341,20 +351,20 @@ class reducer_opand : public reducer< op_and<Type, true> >
public:
/// The view type for the reducer.
typedef typename base::view_type view_type;
-
- /// The view’s rhs proxy type.
+
+ /// The view's rhs proxy type.
typedef typename view_type::rhs_proxy rhs_proxy;
-
+
/// The view type for the reducer.
typedef view_type View;
/// The monoid type for the reducer.
typedef typename base::monoid_type Monoid;
-
+
/** @name Constructors
*/
- //@{
-
+ ///@{
+
/** Default constructor.
*
* Constructs the wrapper with the default initial value of `Type()`
@@ -367,13 +377,13 @@ public:
* Constructs the wrapper with a specified initial value.
*/
explicit reducer_opand(const Type& initial_value) : base(initial_value) {}
-
- //@}
+
+ ///@}
/** @name Forwarded functions
* @details Functions that update the contained accumulator variable are
* simply forwarded to the contained @ref op_and_view. */
- //@{
+ ///@{
/// @copydoc op_and_view::operator&=(const Type&)
reducer_opand& operator&=(const Type& x)
@@ -381,26 +391,26 @@ public:
view() &= x;
return *this;
}
-
+
// The legacy definition of reducer_opand::operator&() has different
// behavior and a different return type than this definition. The legacy
// version is defined as a member function, so this new version is defined
- // as a free function to give it a different signature, so that they won’t
+ // as a free function to give it a different signature, so that they won't
// end up sharing a single object file entry.
-
+
/// @copydoc op_and_view::operator&(const Type&) const
friend rhs_proxy operator&(const reducer_opand& r, const Type& x)
- {
- return r.view() & x;
+ {
+ return r.view() & x;
}
/// @copydoc op_and_view::operator=(const rhs_proxy&)
- reducer_opand& operator=(const rhs_proxy& temp)
- {
+ reducer_opand& operator=(const rhs_proxy& temp)
+ {
view() = temp;
- return *this;
+ return *this;
}
- //@}
+ ///@}
/** @name Dereference
* @details Dereferencing a wrapper is a no-op. It simply returns the
@@ -419,25 +429,25 @@ public:
* // operator &= is a wrapper member function that
* // calls the corresponding view function
*/
- //@{
+ ///@{
reducer_opand& operator*() { return *this; }
reducer_opand const& operator*() const { return *this; }
reducer_opand* operator->() { return this; }
reducer_opand const* operator->() const { return this; }
- //@}
-
+ ///@}
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
* pseudo-upcasts to the corresponding unaligned reducer class.
*/
- //@{
+ ///@{
operator reducer< op_and<Type, false> >& ()
{
return *reinterpret_cast< reducer< op_and<Type, false> >* >(this);
@@ -446,14 +456,14 @@ public:
{
return *reinterpret_cast< const reducer< op_and<Type, false> >* >(this);
}
- //@}
+ ///@}
};
/// @cond internal
/** Metafunction specialization for reducer conversion.
*
- * This specialization of the @ref legacy_reducer_downcast template class
- * defined in reducer.h causes the `reducer< op_and<Type> >` class to have an
+ * This specialization of the @ref legacy_reducer_downcast template class
+ * defined in reducer.h causes the `reducer< op_and<Type> >` class to have an
* `operator reducer_opand<Type>& ()` conversion operator that statically
* downcasts the `reducer<op_and>` to the corresponding `reducer_opand` type.
* (The reverse conversion, from `reducer_opand` to `reducer<op_and>`, is just
@@ -475,7 +485,7 @@ struct legacy_reducer_downcast<reducer<op_and<Type, Align> > >
/** @ingroup ReducersAdd
*/
-//@{
+///@{
/** @name C language reducer macros
*
@@ -483,13 +493,13 @@ struct legacy_reducer_downcast<reducer<op_and<Type, Align> > >
*
* @see @ref page_reducers_in_c
*/
- //@{
-
+ ///@{
+
__CILKRTS_BEGIN_EXTERN_C
-/** Opand reducer type name.
+/** Declares `opand` reducer type name.
*
- * This macro expands into the identifier which is the name of the op_and
+ * This macro expands into the identifier which is the name of the op_and
* reducer type for a specified numeric type.
*
* @param tn The @ref reducers_c_type_names "numeric type name" specifying
@@ -501,7 +511,7 @@ __CILKRTS_BEGIN_EXTERN_C
#define CILK_C_REDUCER_OPAND_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_opand_,tn)
-/** Declare an op_and reducer object.
+/** Declares an op_and reducer object.
*
* This macro expands into a declaration of an op_and reducer object for a
* specified numeric type. For example:
@@ -526,29 +536,29 @@ __CILKRTS_BEGIN_EXTERN_C
/// @cond internal
-/** Declare the op_and reducer functions for a numeric type.
+/** Declares the op_and reducer functions for a numeric type.
*
* This macro expands into external function declarations for functions which
* implement the reducer functionality for the op_and reducer type for a
* specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPAND_DECLARATION(t,tn) \
typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPAND_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opand,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opand,tn);
-
-/** Define the op_and reducer functions for a numeric type.
+
+/** Defines the op_and reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement
* the reducer functionality for the op_and reducer type for a specified
* numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPAND_DEFINITION(t,tn) \
@@ -557,10 +567,10 @@ __CILKRTS_BEGIN_EXTERN_C
{ *(t*)l &= *(t*)r; } \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opand,tn) \
{ *(t*)v = ~((t)0); }
-
-//@{
-/** @def CILK_C_REDUCER_OPAND_INSTANCE
- * @brief Declare or define implementation functions for a reducer type.
+
+///@{
+/** @def CILK_C_REDUCER_OPAND_INSTANCE
+ * @brief Declares or defines implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
* will be defined, and this macro will generate reducer implementation
@@ -574,9 +584,9 @@ __CILKRTS_BEGIN_EXTERN_C
# define CILK_C_REDUCER_OPAND_INSTANCE(t,tn) \
CILK_C_REDUCER_OPAND_DECLARATION(t,tn)
#endif
-//@}
+///@}
-/* Declare or define an instance of the reducer type and its functions for
+/* Declares or defines an instance of the reducer type and its functions for
* each numeric type.
*/
CILK_C_REDUCER_OPAND_INSTANCE(char, char)
@@ -597,8 +607,8 @@ CILK_C_REDUCER_OPAND_INSTANCE(unsigned long long, ulonglong)
__CILKRTS_END_EXTERN_C
-//@}
+///@}
-//@}
+///@}
#endif /* REDUCER_OPAND_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_opmul.h b/libcilkrts/include/cilk/reducer_opmul.h
index 271529d787b..8a3e2d2a2a5 100644
--- a/libcilkrts/include/cilk/reducer_opmul.h
+++ b/libcilkrts/include/cilk/reducer_opmul.h
@@ -1,10 +1,8 @@
/* reducer_opmul.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2012-2013, Intel Corporation
+ * Copyright (C) 2012-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_opmul.h
@@ -55,9 +66,9 @@
*
* @ingroup Reducers
*
- * You should be familiar with @ref pagereducers "Cilk reducers", described in
- * file `reducers.md`, and particularly with @ref reducers_using, before trying
- * to use the information in this file.
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file `reducers.md`, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
*
* @section redopmul_usage Usage Example
*
@@ -79,11 +90,11 @@
* @subsection redopmul_monoid_operator Operator
*
* The operator of a multiplication reducer is the multiplication operation,
- * defined by the “`*`” binary operator on `Type`.
+ * defined by the "`*`" binary operator on `Type`.
*
* @subsection redopmul_monoid_identity Identity
*
- * The identity value of the reducer is the numeric value “`1`”. This is
+ * The identity value of the reducer is the numeric value "`1`". This is
* expected to be the value of the expression `Type(1)`.
*
* @section redopmul_operations Operations
@@ -119,18 +130,18 @@
* not really associative. For example, `(1e200 * 1e-200) * 1e-200 == 1e-200`,
* but `1e200 * (1e-200 * 1e-200 == 0.
*
- * In many cases, this won’t matter, but computations which have been
+ * In many cases, this won't matter, but computations which have been
* carefully ordered to control overflow and underflow may not deal well with
* being reassociated. In general, you should be sure to understand the
- * floating-point behavior of your program before doing any transformation
- * that will reassociate its computations.
+ * floating-point behavior of your program before doing any transformation
+ * that will reassociate its computations.
*
* @section redopmul_types Type and Operator Requirements
*
- * `Type` must be `Copy Constructible`, `Default Constructible`, and
+ * `Type` must be `Copy Constructible`, `Default Constructible`, and
* `Assignable`.
*
- * The operator “`*=`” must be defined on `Type`, with `x *= a` having the same
+ * The operator "`*=`" must be defined on `Type`, with `x *= a` having the same
* meaning as `x = x * a`.
*
* The expression `Type(1)` must be a valid expression which yields the
@@ -158,18 +169,18 @@ namespace cilk {
/** The multiplication reducer view class.
*
- * This is the view class for reducers created with
- * `cilk::reducer< cilk::op_mul<Type> >`. It holds the accumulator variable
- * for the reduction, and allows only multiplication operations to be
+ * This is the view class for reducers created with
+ * `cilk::reducer< cilk::op_mul<Type> >`. It holds the accumulator variable
+ * for the reduction, and allows only multiplication operations to be
* performed on it.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `*=` operation would be used in an expression like `*r *= a`, where
* `r` is an op_mul reducer variable.
*
- * @tparam Type The type of the contained accumulator variable. This will
- * be the value type of a monoid_with_view that is
+ * @tparam Type The type of the contained accumulator variable. This will
+ * be the value type of a monoid_with_view that is
* instantiated with this view.
*
* @see ReducersMul
@@ -181,18 +192,18 @@ template <typename Type>
class op_mul_view : public scalar_view<Type>
{
typedef scalar_view<Type> base;
-
+
public:
/** Class to represent the right-hand side of `*reducer = *reducer * value`.
*
- * The only assignment operator for the op_mul_view class takes an
- * rhs_proxy as its operand. This results in the syntactic restriction
+ * The only assignment operator for the op_mul_view class takes an
+ * rhs_proxy as its operand. This results in the syntactic restriction
* that the only expressions that can be assigned to an op_mul_view are
- * ones which generate an rhs_proxy — that is, expressions of the form
+ * ones which generate an rhs_proxy - that is, expressions of the form
* `op_mul_view * value ... * value`.
*
* @warning
- * The lhs and rhs views in such an assignment must be the same;
+ * The lhs and rhs views in such an assignment must be the same;
* otherwise, the behavior will be undefined. (I.e., `v1 = v1 * x` is
* legal; `v1 = v2 * x` is illegal.) This condition will be checked with a
* runtime assertion when compiled in debug mode.
@@ -213,12 +224,12 @@ public:
rhs_proxy(); // Disable default constructor
public:
- /** Multiply by an additional rhs value. If `v` is an op_mul_view and
- * `a1` is a value, then the expression `v * a1` invokes the view’s
- * `operator*()` to create an rhs_proxy for `(v, a1)`; then
- * `v * a1 * a2` invokes the rhs_proxy’s `operator*()` to create a
+ /** Multiplies by an additional `rhs` value. If `v` is an op_mul_view and
+ * `a1` is a value, then the expression `v * a1` invokes the view's
+ * `operator*()` to create an rhs_proxy for `(v, a1)`; then
+ * `v * a1 * a2` invokes the rhs_proxy's `operator*()` to create a
* new rhs_proxy for `(v, a1*a2)`. This allows the right-hand side of
- * an assignment to be not just `view * value`, but
+ * an assignment to be not just `view * value`, but
* `view * value * value ... * value`. The effect is that
*
* v = v * a1 * a2 ... * an;
@@ -231,7 +242,7 @@ public:
};
- /** Default/identity constructor. This constructor initializes the
+ /** Default/identity constructor. This constructor initializes the
* contained value to `Type(1)`, which is expected to be the identity
* value for multiplication on `Type`.
*/
@@ -240,8 +251,8 @@ public:
/** Construct with a specified initial value.
*/
explicit op_mul_view(const Type& v) : base(v) {}
-
- /** Reduction operation.
+
+ /** Reduces two strand views.
*
* This function is invoked by the @ref op_mul monoid to combine the views
* of two strands when the right strand merges with the left one. It
@@ -256,25 +267,25 @@ public:
* reduce operation.
*/
void reduce(op_mul_view* right) { this->m_value *= right->m_value; }
-
+
/** @name Accumulator variable updates.
*
* These functions support the various syntaxes for multiplying the
* accumulator variable contained in the view by some value.
*/
- //@{
+ ///@{
- /** Multiply the accumulator variable by @a x.
+ /** Multiplies the accumulator variable by @a x.
*/
op_mul_view& operator*=(const Type& x) { this->m_value *= x; return *this; }
- /** Create an object representing `*this * x`.
+ /** Creates an object representing `*this * x`.
*
* @see rhs_proxy
*/
rhs_proxy operator*(const Type& x) const { return rhs_proxy(this, x); }
- /** Assign the result of a `view * value` expression to the view. Note that
+ /** Assigns the result of a `view * value` expression to the view. Note that
* this is the only assignment operator for this class.
*
* @see rhs_proxy
@@ -284,8 +295,8 @@ public:
this->m_value *= rhs.m_value;
return *this;
}
-
- //@}
+
+ ///@}
};
/** Monoid class for multiplication reductions. Instantiate the cilk::reducer
@@ -309,7 +320,7 @@ struct op_mul : public monoid_with_view< op_mul_view<Type> > {};
/** @ingroup ReducersAdd
*/
-//@{
+///@{
/** @name C language reducer macros
*
@@ -318,11 +329,11 @@ struct op_mul : public monoid_with_view< op_mul_view<Type> > {};
*
* @see @ref page_reducers_in_c
*/
- //@{
-
+ ///@{
+
__CILKRTS_BEGIN_EXTERN_C
-/** Opmul reducer type name.
+/** Declares `opmul` reducer type name.
*
* This macro expands into the identifier which is the name of the op_mul
* reducer type for a specified numeric type.
@@ -336,7 +347,7 @@ __CILKRTS_BEGIN_EXTERN_C
#define CILK_C_REDUCER_OPMUL_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_opmul_,tn)
-/** Declare an op_mul reducer object.
+/** Declares an op_mul reducer object.
*
* This macro expands into a declaration of an op_mul reducer object for a
* specified numeric type. For example:
@@ -361,29 +372,29 @@ __CILKRTS_BEGIN_EXTERN_C
/// @cond internal
-/** Declare the op_mul reducer functions for a numeric type.
+/** Declares the op_mul reducer functions for a numeric type.
*
- * This macro expands into external function declarations for functions which
+ * This macro expands into external function declarations for functions which
* implement the reducer functionality for the op_mul reducer type for a
* specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPMUL_DECLARATION(t,tn) \
typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPMUL_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opmul,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opmul,tn);
-
-/** Define the op_mul reducer functions for a numeric type.
+
+/** Defines the op_mul reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement
* the reducer functionality for the op_mul reducer type for a specified
* numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPMUL_DEFINITION(t,tn) \
@@ -392,10 +403,10 @@ __CILKRTS_BEGIN_EXTERN_C
{ *(t*)l *= *(t*)r; } \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opmul,tn) \
{ *(t*)v = 1; }
-
-//@{
-/** @def CILK_C_REDUCER_OPMUL_INSTANCE
- * @brief Declare or define implementation functions for a reducer type.
+
+///@{
+/** @def CILK_C_REDUCER_OPMUL_INSTANCE
+ * @brief Declares or defines implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
* will be defined, and this macro will generate reducer implementation
@@ -409,9 +420,9 @@ __CILKRTS_BEGIN_EXTERN_C
# define CILK_C_REDUCER_OPMUL_INSTANCE(t,tn) \
CILK_C_REDUCER_OPMUL_DECLARATION(t,tn)
#endif
-//@}
+///@}
-/* Declare or define an instance of the reducer type and its functions for each
+/* Declares or defines an instance of the reducer type and its functions for each
* numeric type.
*/
CILK_C_REDUCER_OPMUL_INSTANCE(char, char)
@@ -435,8 +446,8 @@ CILK_C_REDUCER_OPMUL_INSTANCE(long double, longdouble)
__CILKRTS_END_EXTERN_C
-//@}
+///@}
-//@}
+///@}
#endif /* REDUCER_OPMUL_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_opor.h b/libcilkrts/include/cilk/reducer_opor.h
index 5c8e7bd972e..8d6d5202488 100644
--- a/libcilkrts/include/cilk/reducer_opor.h
+++ b/libcilkrts/include/cilk/reducer_opor.h
@@ -1,10 +1,8 @@
/* reducer_opor.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,11 +29,25 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_opor.h
*
- * @brief Defines classes for doing parallel bitwise or reductions.
+ * @brief Defines classes for doing parallel bitwise OR reductions.
*
* @ingroup ReducersOr
*
@@ -48,16 +59,16 @@
#include <cilk/reducer.h>
-/** @defgroup ReducersOr Bitwise Or Reducers
+/** @defgroup ReducersOr Bitwise `OR` Reducers
*
- * Bitwise and reducers allow the computation of the bitwise and of a set of
+ * Bitwise `OR` reducers allow the computation of the bitwise `OR` of a set of
* values in parallel.
*
* @ingroup Reducers
*
- * You should be familiar with @ref pagereducers "Cilk reducers", described in
- * file `reducers.md`, and particularly with @ref reducers_using, before trying
- * to use the information in this file.
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file `reducers.md`, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
*
* @section redopor_usage Usage Example
*
@@ -72,18 +83,18 @@
*
* @subsection redopor_monoid_values Value Set
*
- * The value set of a bitwise or reducer is the set of values of `Type`, which
+ * The value set of a bitwise `OR` reducer is the set of values of `Type`, which
* is expected to be a builtin integer type which has a representation as a
* sequence of bits (or something like it, such as `bool` or `std::bitset`).
*
* @subsection redopor_monoid_operator Operator
*
- * The operator of a bitwise or reducer is the bitwise or operator, defined by
- * the “`|`” binary operator on `Type`.
+ * The operator of a bitwise `OR` reducer is the bitwise OR operator, defined by
+ * the "`|`" binary operator on `Type`.
*
* @subsection redopor_monoid_identity Identity
*
- * The identity value of the reducer is the value whose representation
+ * The identity value of the reducer is the value whose representation
* contains all 0-bits. This is expected to be the value of the default
* constructor `Type()`.
*
@@ -104,8 +115,8 @@
*
* @subsection redopor_initial Initial Values
*
- * If a bitwise or reducer is constructed without an explicit initial value,
- * then its initial value will be its identity value, as long as `Type`
+ * If a bitwise OR reducer is constructed without an explicit initial value,
+ * then its initial value will be its identity value, as long as `Type`
* satisfies the requirements of @ref redopor_types.
*
* @subsection redopor_view_ops View Operations
@@ -119,17 +130,17 @@
* `Type` must be `Copy Constructible`, `Default Constructible`, and
* `Assignable`.
*
- * The operator “`|=`” must be defined on `Type`, with `x |= a` having the
+ * The operator "`|=`" must be defined on `Type`, with `x |= a` having the
* same meaning as `x = x | a`.
*
* The expression `Type()` must be a valid expression which yields the
* identity value (the value of `Type` whose representation consists of all
* 0-bits).
*
- * @section redopor_in_c Bitwise Or Reducers in C
+ * @section redopor_in_c Bitwise OR Reducers in C
*
* The @ref CILK_C_REDUCER_OPOR and @ref CILK_C_REDUCER_OPOR_TYPE macros can
- * be used to do bitwise or reductions in C. For example:
+ * be used to do bitwise OR reductions in C. For example:
*
* CILK_C_REDUCER_OPOR(r, uint, 0);
* CILK_C_REGISTER_REDUCER(r);
@@ -146,14 +157,14 @@
namespace cilk {
-/** The bitwise or reducer view class.
+/** The bitwise OR reducer view class.
*
- * This is the view class for reducers created with
+ * This is the view class for reducers created with
* `cilk::reducer< cilk::op_or<Type> >`. It holds the accumulator variable for
* the reduction, and allows only `or` operations to be performed on it.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `|=` operation would be used in an expression like `*r |= a`, where
* `r` is an opmod reducer variable.
*
@@ -170,18 +181,18 @@ template <typename Type>
class op_or_view : public scalar_view<Type>
{
typedef scalar_view<Type> base;
-
+
public:
/** Class to represent the right-hand side of `*reducer = *reducer | value`.
*
- * The only assignment operator for the op_or_view class takes an
+ * The only assignment operator for the op_or_view class takes an
* rhs_proxy as its operand. This results in the syntactic restriction
* that the only expressions that can be assigned to an op_or_view are
- * ones which generate an rhs_proxy — that is, expressions of the form
+ * ones which generate an rhs_proxy - that is, expressions of the form
* `op_or_view | value ... | value`.
*
* @warning
- * The lhs and rhs views in such an assignment must be the same;
+ * The lhs and rhs views in such an assignment must be the same;
* otherwise, the behavior will be undefined. (I.e., `v1 = v1 | x` is
* legal; `v1 = v2 | x` is illegal.) This condition will be checked with
* a runtime assertion when compiled in debug mode.
@@ -202,12 +213,12 @@ public:
rhs_proxy(); // Disable default constructor
public:
- /** Bitwise or with an additional rhs value. If `v` is an op_or_view
- * and `a1` is a value, then the expression `v | a1` invokes the
- * view’s `operator|()` to create an rhs_proxy for `(v, a1)`; then
- * `v | a1 | a2` invokes the rhs_proxy’s `operator|()` to create a new
+ /** bitwise OR with an additional rhs value. If `v` is an op_or_view
+ * and `a1` is a value, then the expression `v | a1` invokes the
+ * view's `operator|()` to create an rhs_proxy for `(v, a1)`; then
+ * `v | a1 | a2` invokes the rhs_proxy's `operator|()` to create a new
* rhs_proxy for `(v, a1|a2)`. This allows the right-hand side of an
- * assignment to be not just `view | value`, but
+ * assignment to be not just `view | value`, but
( `view | value | value ... | value`. The effect is that
*
* v = v | a1 | a2 ... | an;
@@ -228,12 +239,12 @@ public:
/** Construct with a specified initial value.
*/
explicit op_or_view(const Type& v) : base(v) {}
-
- /** Reduction operation.
+
+ /** Reduces the views of two strands.
*
* This function is invoked by the @ref op_or monoid to combine the views
* of two strands when the right strand merges with the left one. It
- * “ors” the value contained in the left-strand view by the value
+ * "ORs" the value contained in the left-strand view by the value
* contained in the right-strand view, and leaves the value in the
* right-strand view undefined.
*
@@ -244,25 +255,25 @@ public:
* reduce operation.
*/
void reduce(op_or_view* right) { this->m_value |= right->m_value; }
-
+
/** @name Accumulator variable updates.
*
- * These functions support the various syntaxes for “oring” the
+ * These functions support the various syntaxes for "ORing" the
* accumulator variable contained in the view with some value.
*/
- //@{
+ ///@{
- /** Or the accumulator variable with @a x.
+ /** Perfoms an OR operation between the accumulator variable and @a x.
*/
op_or_view& operator|=(const Type& x) { this->m_value |= x; return *this; }
- /** Create an object representing `*this | x`.
+ /** Creates an object representing `*this | x`.
*
* @see rhs_proxy
*/
rhs_proxy operator|(const Type& x) const { return rhs_proxy(this, x); }
- /** Assign the result of a `view | value` expression to the view. Note that
+ /** Assigns the result of a `view | value` expression to the view. Note that
* this is the only assignment operator for this class.
*
* @see rhs_proxy
@@ -272,23 +283,23 @@ public:
this->m_value |= rhs.m_value;
return *this;
}
-
- //@}
+
+ ///@}
};
-/** Monoid class for bitwise or reductions. Instantiate the cilk::reducer
- * template class with an op_or monoid to create a bitwise or reducer
- * class. For example, to compute the bitwise or of a set of `unsigned long`
+/** Monoid class for bitwise OR reductions. Instantiate the cilk::reducer
+ * template class with an op_or monoid to create a bitwise OR reducer
+ * class. For example, to compute the bitwise OR of a set of `unsigned long`
* values:
*
* cilk::reducer< cilk::op_or<unsigned long> > r;
*
* @tparam Type The reducer value type.
* @tparam Align If `false` (the default), reducers instantiated on this
- * monoid will be naturally aligned (the Cilk library 1.0
+ * monoid will be naturally aligned (the Intel Cilk Plus library 1.0
* behavior). If `true`, reducers instantiated on this monoid
- * will be cache-aligned for binary compatibility with
- * reducers in Cilk library version 0.9.
+ * will be cache-aligned for binary compatibility with
+ * reducers in Intel Cilk Plus library version 0.9.
*
* @see ReducersOr
* @see op_or_view
@@ -298,22 +309,22 @@ public:
template <typename Type, bool Align = false>
struct op_or : public monoid_with_view<op_or_view<Type>, Align> {};
-/** Deprecated bitwise or reducer class.
+/** Deprecated bitwise OR reducer class.
*
* reducer_opor is the same as @ref reducer<@ref op_or>, except that
* reducer_opor is a proxy for the contained view, so that accumulator
* variable update operations can be applied directly to the reducer. For
- * example, a value is ored with a `reducer<%op_or>` with `*r |= a`, but a
- * value can be ored with a `%reducer_opor` with `r |= a`.
+ * example, a value is "ORed" with a `reducer<%op_or>` with `*r |= a`, but a
+ * value can be "ORed" with a `%reducer_opor` with `r |= a`.
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_opor.
+ * reducers rather than the old wrappers like reducer_opor.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_opor`
+ * @note Implicit conversions are provided between `%reducer_opor`
* and `reducer<%op_or>`. This allows incremental code
* conversion: old code that used `%reducer_opor` can pass a
* `%reducer_opor` to a converted function that now expects a
@@ -337,20 +348,20 @@ class reducer_opor : public reducer< op_or<Type, true> >
public:
/// The view type for the reducer.
typedef typename base::view_type view_type;
-
- /// The view’s rhs proxy type.
+
+ /// The view's rhs proxy type.
typedef typename view_type::rhs_proxy rhs_proxy;
-
+
/// The view type for the reducer.
typedef view_type View;
/// The monoid type for the reducer.
typedef typename base::monoid_type Monoid;
-
+
/** @name Constructors
*/
- //@{
-
+ ///@{
+
/** Default (identity) constructor.
*
* Constructs the wrapper with the default initial value of `Type()`.
@@ -362,38 +373,38 @@ class reducer_opor : public reducer< op_or<Type, true> >
* Constructs the wrapper with a specified initial value.
*/
explicit reducer_opor(const Type& initial_value) : base(initial_value) {}
-
- //@}
+
+ ///@}
/** @name Forwarded functions
* @details Functions that update the contained accumulator variable are
* simply forwarded to the contained @ref op_and_view. */
- //@{
+ ///@{
/// @copydoc op_or_view::operator|=(const Type&)
reducer_opor& operator|=(const Type& x)
{
- view() |= x; return *this;
+ view() |= x; return *this;
}
-
+
// The legacy definition of reducer_opor::operator|() has different
// behavior and a different return type than this definition. The legacy
// version is defined as a member function, so this new version is defined
- // as a free function to give it a different signature, so that they won’t
+ // as a free function to give it a different signature, so that they won't
// end up sharing a single object file entry.
/// @copydoc op_or_view::operator|(const Type&) const
friend rhs_proxy operator|(const reducer_opor& r, const Type& x)
- {
- return r.view() | x;
+ {
+ return r.view() | x;
}
/// @copydoc op_and_view::operator=(const rhs_proxy&)
reducer_opor& operator=(const rhs_proxy& temp)
{
- view() = temp; return *this;
+ view() = temp; return *this;
}
- //@}
+ ///@}
/** @name Dereference
* @details Dereferencing a wrapper is a no-op. It simply returns the
@@ -412,25 +423,25 @@ class reducer_opor : public reducer< op_or<Type, true> >
* // operator &= is a wrapper member function that
* // calls the corresponding view function
*/
- //@{
+ ///@{
reducer_opor& operator*() { return *this; }
reducer_opor const& operator*() const { return *this; }
reducer_opor* operator->() { return this; }
reducer_opor const* operator->() const { return this; }
- //@}
-
+ ///@}
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
* pseudo-upcasts to the corresponding unaligned reducer class.
*/
- //@{
+ ///@{
operator reducer< op_or<Type, false> >& ()
{
return *reinterpret_cast< reducer< op_or<Type, false> >* >(this);
@@ -439,15 +450,15 @@ class reducer_opor : public reducer< op_or<Type, true> >
{
return *reinterpret_cast< const reducer< op_or<Type, false> >* >(this);
}
- //@}
-
+ ///@}
+
};
/// @cond internal
/** Metafunction specialization for reducer conversion.
*
- * This specialization of the @ref legacy_reducer_downcast template class
- * defined in reducer.h causes the `reducer< op_or<Type> >` class to have an
+ * This specialization of the @ref legacy_reducer_downcast template class
+ * defined in reducer.h causes the `reducer< op_or<Type> >` class to have an
* `operator reducer_opor<Type>& ()` conversion operator that statically
* downcasts the `reducer<op_or>` to the corresponding `reducer_opor` type.
* (The reverse conversion, from `reducer_opor` to `reducer<op_or>`, is just
@@ -469,7 +480,7 @@ struct legacy_reducer_downcast<reducer<op_or<Type, Align> > >
/** @ingroup ReducersOr
*/
-//@{
+///@{
/** @name C language reducer macros
*
@@ -477,11 +488,11 @@ struct legacy_reducer_downcast<reducer<op_or<Type, Align> > >
*
* @see @ref page_reducers_in_c
*/
- //@{
-
+ ///@{
+
__CILKRTS_BEGIN_EXTERN_C
-/** Opor reducer type name.
+/** Declares OPOR reducer type name.
*
* This macro expands into the identifier which is the name of the op_or
* reducer type for a specified numeric type.
@@ -495,7 +506,7 @@ __CILKRTS_BEGIN_EXTERN_C
#define CILK_C_REDUCER_OPOR_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_opor_,tn)
-/** Declare an op_or reducer object.
+/** Declares an op_or reducer object.
*
* This macro expands into a declaration of an op_or reducer object for a
* specified numeric type. For example:
@@ -520,29 +531,29 @@ __CILKRTS_BEGIN_EXTERN_C
/// @cond internal
-/** Declare the op_or reducer functions for a numeric type.
+/** Declares the op_or reducer functions for a numeric type.
*
* This macro expands into external function declarations for functions which
* implement the reducer functionality for the op_or reducer type for a
* specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPOR_DECLARATION(t,tn) \
typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPOR_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opor,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opor,tn);
-
-/** Define the op_or reducer functions for a numeric type.
+
+/** Defines the op_or reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement
- * the reducer functionality for the op_or reducer type for a specified
+ * the reducer functionality for the op_or reducer type for a specified
* numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPOR_DEFINITION(t,tn) \
@@ -551,10 +562,10 @@ __CILKRTS_BEGIN_EXTERN_C
{ *(t*)l |= *(t*)r; } \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opor,tn) \
{ *(t*)v = 0; }
-
-//@{
-/** @def CILK_C_REDUCER_OPOR_INSTANCE
- * @brief Declare or define implementation functions for a reducer type.
+
+///@{
+/** @def CILK_C_REDUCER_OPOR_INSTANCE
+ * @brief Declares or defines implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
* will be defined, and this macro will generate reducer implementation
@@ -568,9 +579,9 @@ __CILKRTS_BEGIN_EXTERN_C
# define CILK_C_REDUCER_OPOR_INSTANCE(t,tn) \
CILK_C_REDUCER_OPOR_DECLARATION(t,tn)
#endif
-//@}
+///@}
-/* Declare or define an instance of the reducer type and its functions for each
+/* Declare or define an instance of the reducer type and its functions for each
* numeric type.
*/
CILK_C_REDUCER_OPOR_INSTANCE(char, char)
@@ -591,8 +602,8 @@ CILK_C_REDUCER_OPOR_INSTANCE(unsigned long long, ulonglong)
__CILKRTS_END_EXTERN_C
-//@}
+///@}
-//@}
+///@}
#endif /* REDUCER_OPOR_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_opxor.h b/libcilkrts/include/cilk/reducer_opxor.h
index fed49943ef6..cb6560f9c57 100644
--- a/libcilkrts/include/cilk/reducer_opxor.h
+++ b/libcilkrts/include/cilk/reducer_opxor.h
@@ -1,10 +1,8 @@
/* reducer_opxor.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_opxor.h
@@ -48,16 +59,16 @@
#include <cilk/reducer.h>
-/** @defgroup ReducersXor Bitwise Xor Reducers
+/** @defgroup ReducersXor Bitwise XOR Reducers
*
- * Bitwise and reducers allow the computation of the bitwise and of a set of
+ * Bitwise XOR reducers allow the computation of the bitwise XOR of a set of
* values in parallel.
*
* @ingroup Reducers
*
- * You should be familiar with @ref pagereducers "Cilk reducers", described in
- * file `reducers.md`, and particularly with @ref reducers_using, before trying
- * to use the information in this file.
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file `reducers.md`, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
*
* @section redopxor_usage Usage Example
*
@@ -72,18 +83,17 @@
*
* @subsection redopxor_monoid_values Value Set
*
- * The value set of a bitwise xor reducer is the set of values of `Type`, which
+ * The value set of a bitwise XOR reducer is the set of values of `Type`, which
* is expected to be a builtin integer type which has a representation as a
* sequence of bits (or something like it, such as `bool` or `std::bitset`).
*
* @subsection redopxor_monoid_operator Operator
*
- * The operator of a bitwise xor reducer is the bitwise xor operator, defined
- * by the “`^`” binary operator on `Type`.
+ * The bitwise XOR operator is defined by the "`^`" binary operator on `Type`.
*
* @subsection redopxor_monoid_identity Identity
*
- * The identity value of the reducer is the value whose representation
+ * The identity value of the reducer is the value whose representation
* contains all 0-bits. This is expected to be the value of the default
* constructor `Type()`.
*
@@ -104,8 +114,8 @@
*
* @subsection redopxor_initial Initial Values
*
- * If a bitwise xor reducer is constructed without an explicit initial value,
- * then its initial value will be its identity value, as long as `Type`
+ * If a bitwise XOR reducer is constructed without an explicit initial value,
+ * then its initial value will be its identity value, as long as `Type`
* satisfies the requirements of @ref redopxor_types.
*
* @subsection redopxor_view_ops View Operations
@@ -119,17 +129,17 @@
* `Type` must be `Copy Constructible`, `Default Constructible`, and
* `Assignable`.
*
- * The operator “`^=`” must be defined on `Type`, with `x ^= a` having the
+ * The operator "`^=`" must be defined on `Type`, with `x ^= a` having the
* same meaning as `x = x ^ a`.
*
* The expression `Type()` must be a valid expression which yields the
* identity value (the value of `Type` whose representation consists of all
* 0-bits).
*
- * @section redopxor_in_c Bitwise Xor Reducers in C
+ * @section redopxor_in_c Bitwise XOR Reducers in C
*
* The @ref CILK_C_REDUCER_OPXOR and @ref CILK_C_REDUCER_OPXOR_TYPE macros can
- * be used to do bitwise xor reductions in C. For example:
+ * be used to do bitwise XOR reductions in C. For example:
*
* CILK_C_REDUCER_OPXOR(r, uint, 0);
* CILK_C_REGISTER_REDUCER(r);
@@ -146,14 +156,14 @@
namespace cilk {
-/** The bitwise xor reducer view class.
+/** The bitwise XOR reducer view class.
*
- * This is the view class for reducers created with
- * `cilk::reducer< cilk::op_xor<Type> >`. It holds the accumulator variable
+ * This is the view class for reducers created with
+ * `cilk::reducer< cilk::op_xor<Type> >`. It holds the accumulator variable
* for the reduction, and allows only `xor` operations to be performed on it.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `^=` operation would be used in an expression like `*r ^= a`, where
* `r` is an opmod reducer variable.
*
@@ -170,18 +180,18 @@ template <typename Type>
class op_xor_view : public scalar_view<Type>
{
typedef scalar_view<Type> base;
-
+
public:
/** Class to represent the right-hand side of `*reducer = *reducer ^ value`.
*
- * The only assignment operator for the op_xor_view class takes an
+ * The only assignment operator for the op_xor_view class takes an
* rhs_proxy as its operand. This results in the syntactic restriction
* that the only expressions that can be assigned to an op_xor_view are
- * ones which generate an rhs_proxy — that is, expressions of the form
+ * ones which generate an rhs_proxy - that is, expressions of the form
* `op_xor_view ^ value ... ^ value`.
*
* @warning
- * The lhs and rhs views in such an assignment must be the same;
+ * The lhs and rhs views in such an assignment must be the same;
* otherwise, the behavior will be undefined. (I.e., `v1 = v1 ^ x` is
* legal; `v1 = v2 ^ x` is illegal.) This condition will be checked with
* a runtime assertion when compiled in debug mode.
@@ -202,12 +212,12 @@ public:
rhs_proxy(); // Disable default constructor
public:
- /** Bitwise xor with an additional rhs value. If `v` is an op_xor_view
- * and `a1` is a value, then the expression `v ^ a1` invokes the
- * view’s `operator^()` to create an rhs_proxy for `(v, a1)`; then
- * `v ^ a1 ^ a2` invokes the rhs_proxy’s `operator^()` to create a new
+ /** bitwise XOR with an additional rhs value. If `v` is an op_xor_view
+ * and `a1` is a value, then the expression `v ^ a1` invokes the
+ * view's `operator^()` to create an rhs_proxy for `(v, a1)`; then
+ * `v ^ a1 ^ a2` invokes the rhs_proxy's `operator^()` to create a new
* rhs_proxy for `(v, a1^a2)`. This allows the right-hand side of an
- * assignment to be not just `view ^ value`, but
+ * assignment to be not just `view ^ value`, but
( `view ^ value ^ value ... ^ value`. The effect is that
*
* v = v ^ a1 ^ a2 ... ^ an;
@@ -228,12 +238,12 @@ public:
/** Construct with a specified initial value.
*/
explicit op_xor_view(const Type& v) : base(v) {}
-
- /** Reduction operation.
+
+ /** Reduces the views of two strands.
*
* This function is invoked by the @ref op_xor monoid to combine the views
* of two strands when the right strand merges with the left one. It
- * “xors” the value contained in the left-strand view by the value
+ * "XORs" the value contained in the left-strand view by the value
* contained in the right-strand view, and leaves the value in the
* right-strand view undefined.
*
@@ -244,25 +254,25 @@ public:
* reduce operation.
*/
void reduce(op_xor_view* right) { this->m_value ^= right->m_value; }
-
+
/** @name Accumulator variable updates.
*
- * These functions support the various syntaxes for “xoring” the
+ * These functions support the various syntaxes for "XORing" the
* accumulator variable contained in the view with some value.
*/
- //@{
+ ///@{
- /** Xor the accumulator variable with @a x.
+ /** Performs XOR operation between the accumulator variable and @a x.
*/
op_xor_view& operator^=(const Type& x) { this->m_value ^= x; return *this; }
- /** Create an object representing `*this ^ x`.
+ /** Creates an object representing `*this ^ x`.
*
* @see rhs_proxy
*/
rhs_proxy operator^(const Type& x) const { return rhs_proxy(this, x); }
- /** Assign the result of a `view ^ value` expression to the view. Note that
+ /** Assigns the result of a `view ^ value` expression to the view. Note that
* this is the only assignment operator for this class.
*
* @see rhs_proxy
@@ -272,23 +282,23 @@ public:
this->m_value ^= rhs.m_value;
return *this;
}
-
- //@}
+
+ ///@}
};
-/** Monoid class for bitwise xor reductions. Instantiate the cilk::reducer
- * template class with an op_xor monoid to create a bitwise xor reducer
- * class. For example, to compute the bitwise xor of a set of `unsigned long`
+/** Monoid class for bitwise XOR reductions. Instantiate the cilk::reducer
+ * template class with an op_xor monoid to create a bitwise XOR reducer
+ * class. For example, to compute the bitwise XOR of a set of `unsigned long`
* values:
*
* cilk::reducer< cilk::op_xor<unsigned long> > r;
*
* @tparam Type The reducer value type.
* @tparam Align If `false` (the default), reducers instantiated on this
- * monoid will be naturally aligned (the Cilk library 1.0
+ * monoid will be naturally aligned (the Intel Cilk Plus library 1.0
* behavior). If `true`, reducers instantiated on this monoid
- * will be cache-aligned for binary compatibility with
- * reducers in Cilk library version 0.9.
+ * will be cache-aligned for binary compatibility with
+ * reducers in Intel Cilk Plus library version 0.9.
*
* @see ReducersXor
* @see op_xor_view
@@ -298,22 +308,22 @@ public:
template <typename Type, bool Align = false>
struct op_xor : public monoid_with_view<op_xor_view<Type>, Align> {};
-/** Deprecated bitwise xor reducer class.
+/** Deprecated bitwise XOR reducer class.
*
* reducer_opxor is the same as @ref reducer<@ref op_xor>, except that
* reducer_opxor is a proxy for the contained view, so that accumulator
* variable update operations can be applied directly to the reducer. For
- * example, a value is xored with a `reducer<%op_xor>` with `*r ^= a`, but a
- * value can be xored with a `%reducer_opxor` with `r ^= a`.
+ * example, a value is "XORed" with a `reducer<%op_xor>` with `*r ^= a`, but a
+ * value can be "XORed" with a `%reducer_opxor` with `r ^= a`.
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_opand.
+ * reducers rather than the old wrappers like reducer_opand.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_opxor`
+ * @note Implicit conversions are provided between `%reducer_opxor`
* and `reducer<%op_xor>`. This allows incremental code
* conversion: old code that used `%reducer_opxor` can pass a
* `%reducer_opxor` to a converted function that now expects a
@@ -337,20 +347,20 @@ class reducer_opxor : public reducer< op_xor<Type, true> >
public:
/// The view type for the reducer.
typedef typename base::view_type view_type;
-
- /// The view’s rhs proxy type.
+
+ /// The view's rhs proxy type.
typedef typename view_type::rhs_proxy rhs_proxy;
-
+
/// The view type for the reducer.
typedef view_type View;
/// The monoid type for the reducer.
typedef typename base::monoid_type Monoid;
-
+
/** @name Constructors
*/
- //@{
-
+ ///@{
+
/** Default (identity) constructor.
*
* Constructs the wrapper with the default initial value of `Type()`.
@@ -362,38 +372,38 @@ class reducer_opxor : public reducer< op_xor<Type, true> >
* Constructs the wrapper with a specified initial value.
*/
explicit reducer_opxor(const Type& initial_value) : base(initial_value) {}
-
- //@}
+
+ ///@}
/** @name Forwarded functions
* @details Functions that update the contained accumulator variable are
* simply forwarded to the contained @ref op_and_view. */
- //@{
+ ///@{
/// @copydoc op_xor_view::operator^=(const Type&)
reducer_opxor& operator^=(const Type& x)
{
- view() ^= x; return *this;
+ view() ^= x; return *this;
}
-
+
// The legacy definition of reducer_opxor::operator^() has different
// behavior and a different return type than this definition. The legacy
// version is defined as a member function, so this new version is defined
- // as a free function to give it a different signature, so that they won’t
+ // as a free function to give it a different signature, so that they won't
// end up sharing a single object file entry.
/// @copydoc op_xor_view::operator^(const Type&) const
friend rhs_proxy operator^(const reducer_opxor& r, const Type& x)
- {
- return r.view() ^ x;
+ {
+ return r.view() ^ x;
}
/// @copydoc op_and_view::operator=(const rhs_proxy&)
reducer_opxor& operator=(const rhs_proxy& temp)
{
- view() = temp; return *this;
+ view() = temp; return *this;
}
- //@}
+ ///@}
/** @name Dereference
* @details Dereferencing a wrapper is a no-op. It simply returns the
@@ -412,25 +422,25 @@ class reducer_opxor : public reducer< op_xor<Type, true> >
* // operator &= is a wrapper member function that
* // calls the corresponding view function
*/
- //@{
+ ///@{
reducer_opxor& operator*() { return *this; }
reducer_opxor const& operator*() const { return *this; }
reducer_opxor* operator->() { return this; }
reducer_opxor const* operator->() const { return this; }
- //@}
-
+ ///@}
+
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
* pseudo-upcasts to the corresponding unaligned reducer class.
*/
- //@{
+ ///@{
operator reducer< op_xor<Type, false> >& ()
{
return *reinterpret_cast< reducer< op_xor<Type, false> >* >(this);
@@ -439,15 +449,15 @@ class reducer_opxor : public reducer< op_xor<Type, true> >
{
return *reinterpret_cast< const reducer< op_xor<Type, false> >* >(this);
}
- //@}
-
+ ///@}
+
};
/// @cond internal
/** Metafunction specialization for reducer conversion.
*
- * This specialization of the @ref legacy_reducer_downcast template class
- * defined in reducer.h causes the `reducer< op_xor<Type> >` class to have an
+ * This specialization of the @ref legacy_reducer_downcast template class
+ * defined in reducer.h causes the `reducer< op_xor<Type> >` class to have an
* `operator reducer_opxor<Type>& ()` conversion operator that statically
* downcasts the `reducer<op_xor>` to the corresponding `reducer_opxor` type.
* (The reverse conversion, from `reducer_opxor` to `reducer<op_xor>`, is just
@@ -469,7 +479,7 @@ struct legacy_reducer_downcast<reducer<op_xor<Type, Align> > >
/** @ingroup ReducersXor
*/
-//@{
+///@{
/** @name C language reducer macros
*
@@ -477,11 +487,11 @@ struct legacy_reducer_downcast<reducer<op_xor<Type, Align> > >
*
* @see @ref page_reducers_in_c
*/
- //@{
-
+ ///@{
+
__CILKRTS_BEGIN_EXTERN_C
-/** Opxor reducer type name.
+/** Declares OPXOR reducer type name.
*
* This macro expands into the identifier which is the name of the op_xor
* reducer type for a specified numeric type.
@@ -495,7 +505,7 @@ __CILKRTS_BEGIN_EXTERN_C
#define CILK_C_REDUCER_OPXOR_TYPE(tn) \
__CILKRTS_MKIDENT(cilk_c_reducer_opxor_,tn)
-/** Declare an op_xor reducer object.
+/** Declares an op_xor reducer object.
*
* This macro expands into a declaration of an op_xor reducer object for a
* specified numeric type. For example:
@@ -520,29 +530,29 @@ __CILKRTS_BEGIN_EXTERN_C
/// @cond internal
-/** Declare the op_xor reducer functions for a numeric type.
+/** Declares the op_xor reducer functions for a numeric type.
*
* This macro expands into external function declarations for functions which
* implement the reducer functionality for the op_xor reducer type for a
* specified numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPXOR_DECLARATION(t,tn) \
typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPXOR_TYPE(tn); \
__CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opxor,tn,l,r); \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opxor,tn);
-
-/** Define the op_xor reducer functions for a numeric type.
+
+/** Defines the op_xor reducer functions for a numeric type.
*
* This macro expands into function definitions for functions which implement
- * the reducer functionality for the op_xor reducer type for a specified
+ * the reducer functionality for the op_xor reducer type for a specified
* numeric type.
*
* @param t The value type of the reducer.
- * @param tn The value “type name” identifier, used to construct the reducer
+ * @param tn The value "type name" identifier, used to construct the reducer
* type name, function names, etc.
*/
#define CILK_C_REDUCER_OPXOR_DEFINITION(t,tn) \
@@ -551,10 +561,10 @@ __CILKRTS_BEGIN_EXTERN_C
{ *(t*)l ^= *(t*)r; } \
__CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opxor,tn) \
{ *(t*)v = 0; }
-
-//@{
-/** @def CILK_C_REDUCER_OPXOR_INSTANCE
- * @brief Declare or define implementation functions for a reducer type.
+
+///@{
+/** @def CILK_C_REDUCER_OPXOR_INSTANCE
+ * @brief Declares or defines implementation functions for a reducer type.
*
* In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS`
* will be defined, and this macro will generate reducer implementation
@@ -568,9 +578,9 @@ __CILKRTS_BEGIN_EXTERN_C
# define CILK_C_REDUCER_OPXOR_INSTANCE(t,tn) \
CILK_C_REDUCER_OPXOR_DECLARATION(t,tn)
#endif
-//@}
+///@}
-/* Declare or define an instance of the reducer type and its functions for each
+/* Declares or defines an instance of the reducer type and its functions for each
* numeric type.
*/
CILK_C_REDUCER_OPXOR_INSTANCE(char, char)
@@ -591,8 +601,8 @@ CILK_C_REDUCER_OPXOR_INSTANCE(unsigned long long, ulonglong)
__CILKRTS_END_EXTERN_C
-//@}
+///@}
-//@}
+///@}
#endif /* REDUCER_OPXOR_H_INCLUDED */
diff --git a/libcilkrts/include/cilk/reducer_ostream.h b/libcilkrts/include/cilk/reducer_ostream.h
index d9addeee89f..793c3c5020c 100644
--- a/libcilkrts/include/cilk/reducer_ostream.h
+++ b/libcilkrts/include/cilk/reducer_ostream.h
@@ -1,9 +1,8 @@
-/*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+/* reducer_ostream.h -*- C++ -*-
+ *
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -18,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -31,263 +29,489 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
- *
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
-/*
- * reducer_ostream.h
- *
- * Purpose: Hyper-object to write to 'std::ostream's
- *
- * Classes: reducer_ostream
- *
- * Description:
- * ============
- * Output streams ('std::ostream's) are a convenient means of writing text to
- * files, the user console, or sockets. In a serial program, text is written
- * to an ostream in a specific, logical order. For example, computing while
- * traversing a data structure and printing them to an 'ostream' will result
- * in the values being printed in the order of traversal. In a parallel
- * version of the same program, however, different parts of the data structure
- * may be traversed in a different order, resulting in a non-deterministic
- * ordering of the stream. Worse, multiple strands may write to the same
- * stream simultaneously, resulting in a data race. Replacing the
- * 'std::ostream' with a 'cilk::reducer_ostream' will solve both problems: Data
- * will appeaer in the stream in the same order as it would for the serial
- * program, and there will be no races (no locks) on the common stream.
- *
- * Usage Example:
- * ==============
- * Assume we wish to traverse an array of objects, performing an operation on
- * each object and writing the result to a file. Without a reducer_ostream,
- * we have a race on the 'output' file stream:
- *..
- * void compute(std::ostream& os, double x)
- * {
- * // Perform some significant computation and print the result:
- * os << std::asin(x);
- * }
- *
- * int test()
- * {
- * const std::size_t ARRAY_SIZE = 1000000;
- * extern double myArray[ARRAY_SIZE];
- *
- * std::ofstream output("output.txt");
- * cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
- * {
- * compute(output, myArray[i]);
- * }
+/** @file reducer_ostream.h
*
- * return 0;
- * }
- *..
- * The race is solved by using a reducer_ostream to proxy the 'output' file:
- *..
- * void compute(cilk::reducer_ostream& os, double x)
- * {
- * // Perform some significant computation and print the result:
- * *os << std::asin(x);
- * }
- *
- * int test()
- * {
- * const std::size_t ARRAY_SIZE = 1000000;
- * extern double myArray[ARRAY_SIZE];
- *
- * std::ofstream output("output.txt");
- * cilk::reducer_ostream hyper_output(output);
- * cilk_for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
- * {
- * compute(hyper_output, myArray[i]);
- * }
+ * @brief Defines a class for writing to an ostream in parallel.
*
- * return 0;
- * }
- *..
- *
- * Limitations:
- * ============
- * There are two possible values for the formatting flags immediately after a
- * 'cilk_spawn' statement: they may either have the value that was set by the
- * spawn function, or they may have default values. Because of
- * non-determinism in the processor scheduling, there is no way to determine
- * which it will be. Similarly, the formatting flags after a 'cilk_sync' may
- * or may not have the same value as before the sync. Therefore, one must use
- * a disciplined coding style to avoid formatting errors. There are two
- * approaches to mitigating the problem: The first is to eliminate the
- * difference between the two possible outcomes by ensuring that the spawned
- * function always returns the flags to their initial state:
- *..
- * void compute(cilk::reducer_ostream& os, double x)
- * {
- * // Perform some significant computation and print the result:
- * int saveprec = os.precision(5);
- * os << std::asin(x);
- * os.precision(saveprec);
- * }
- *..
- * The second approach is to write your streaming operations such that they
- * don't depend on the previous state of the formatting flags by setting any
- * important flags before every block of output:
- *..
- * cilk_spawn compute(hyper_output, value);
- *
- * hyper_output->precision(2); // Don't depend on previous precision
- * *hyper_output << f();
- * *hyper_output << g();
- *..
- * Another concern is memory usage. A reducer_ostream will buffer as much text
- * as necessary to ensure that the order of output matches that of the serial
- * version of the program. If all spawn branches perform an equal amount of
- * output, then one can expect that half of the output before a sync will be
- * buffered in memory. This hyperobject is therefore not well suited for
- * serializing very large quantities of text output.
+ * @ingroup ReducersOstream
+ *
+ * @see @ref ReducersOstream
*/
#ifndef REDUCER_OSTREAM_H_INCLUDED
#define REDUCER_OSTREAM_H_INCLUDED
#include <cilk/reducer.h>
-#include <iostream>
+#include <ostream>
#include <sstream>
+/** @defgroup ReducersOstream Ostream Reducers
+ *
+ * Ostream reducers allow multiple strands to write to an ostream in parallel.
+ *
+ * @ingroup Reducers
+ *
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file reducers.md, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
+ *
+ * @section redostream_usage Usage Example
+ *
+ * One of the most common debugging techniques is adding `print` statements
+ * to the code being debugged. When the code is parallelized, the results can
+ * be less than satisfactory, as output from multiple strands is mingled in an
+ * unpredictable way. Like other reducers, an ostream reducer requires minimal
+ * recoding to guarantee that the output from parallelized computation will be
+ * ordered the same as though the computation were executed serially.
+ *
+ * cilk::reducer<cilk::op_ostream> r(std::cerr);
+ * cilk_for (int i = 0; i != data.size(); ++i) {
+ * *r << "Iteration " << i << ":\n";
+ * ... some computation ...
+ * *r << " Step 1:" << some information;
+ * ... some more computation ...
+ * *r << " Step 2:" << some more information;
+ * ... still more computation ...
+ * *r << " Step 3:" << still more information;
+ * }
+ *
+ * Output on standard error:
+ *
+ * Iteration 1:
+ * Step 1: ...
+ * Step 2: ...
+ * Step 3: ...
+ * Iteration 2:
+ * Step 1: ...
+ * Step 2: ...
+ * Step 3: ...
+ * Iteration 3:
+ * Step 1: ...
+ * Step 2: ...
+ * Step 3: ...
+ * ...
+ *
+ * @section redostream_overview Overview
+ *
+ * An "ostream reducer" is not really a reducer. It uses the reducer
+ * technology to coordinate operations on parallel strands to achieve
+ * the same behavior in a parallel computation that would be seen in a
+ * serial computation, but it does not have a monoid. It has a "monoid
+ * class," because that is part of the implementation framework, but it
+ * does not represent a mathematical monoid: there is no value type, no
+ * associative operation, and no identity value. The reducer is used for
+ * its side effect rather than to construct a value.
+ *
+ * You might think of an ostream reducer as a relative of a
+ * @ref ReducersString "string reducer" which uses stream output
+ * syntax (`stream << value`) instead of string append syntax
+ * (`string += value`), and which writes its result string to an
+ * ostream instead of making it available as the reducer value.
+ *
+ * Another difference is that "real" reducers protect their contained
+ * value quite strongly from improper access by the user. Ostream reducers,
+ * on the other hand, pretty much have to expose the ostream, since normal
+ * use of an ostream involves accessing its internal state. Furthermore,
+ * the ostream reducer just coordinates output to an existing ostream -
+ * there is nothing to keep the user from writing directly to the attached
+ * stream, with unpredictable results.
+ *
+ * @section redostream_operations Operations
+ *
+ * In the operation descriptions below, the type name `Ostream` refers to the
+ * reducer's ostream type, `std::basic_ostream<Char, Traits>`.
+ *
+ * @subsection redostream_constructors Constructors
+ *
+ * The only constructor is
+ *
+ * reducer(const Ostream& os)
+ *
+ * This creates a reducer that is associated with the existing ostream `os`.
+ * Anything "written to" the reducer will (eventually) be written to `os`.
+ *
+ * @subsection redostream_get_set Set and Get
+ *
+ * Just as a stream does not have a "value," neither does an ostream
+ * reducer. Therefore, none of the usual `set_value`, `get_value`,
+ * `move_in`, or `move_out` functions are available for ostream reducers.
+ *
+ * @subsection redostream_initial Initial Values
+ *
+ * Ostream reducers do not have default constructors.
+ *
+ * @subsection redostream_view_ops View Operations
+ *
+ * An ostream reducer view is actually a kind of `std::ostream`. Therefore,
+ * any operation that can be used on an ostream can be used on an ostream
+ * reducer view. For example:
+ *
+ * reducer<op_ostream> r(cout);
+ * *r << setw(5) << (x=1) << endl;
+ *
+ *
+ * @section redostream_performance Performance Considerations
+ *
+ * Ostream reducers work by creating a string stream for each non-leftmost
+ * view. When two strands are merged, the contents of the string buffer of the
+ * right view are written to the left view. Since all non-leftmost strands are
+ * eventually merged, all output is eventually written to the associated
+ * ostream.
+ *
+ * This implementation has two consequences.
+ *
+ * First, all output written to an ostream reducer on a stolen strand is kept
+ * in memory (in a string buffer) until the strand is merged with the leftmost
+ * strand. This means that some portion of the output written to an ostream
+ * reducer during a parallel computation - half of the total output, on
+ * average - will temporarily be held in memory during the computation.
+ * Obviously, ostream reducers will work better for small and moderate amounts
+ * of output.
+ *
+ * Second, buffered ostream reducer content must be copied at every merge.
+ * The total amount of copying is potentially proportional to the total amount
+ * of output multiplied by the number of strands stolen during the computation.
+ *
+ * In short, writing to an ostream in a parallel computation with an ostream
+ * reducer will always be less efficient than writing the same output directly
+ * to the ostream in a serial computation. The value of the ostream
+ * reducer is not in the writing of the ostream itself, but in removing the
+ * race and serialization obstacles that the ostream output would cause in an
+ * otherwise parallelizable computation.
+ *
+ *
+ * @section redostream_state Stream State
+ *
+ * The reducer implementation can correctly order the output that is written
+ * to an ostream. However, an ostream has additional state that controls its
+ * behavior, such as its formatting attributes, error state, extensible arrays, * and registered callbacks. If these are modified during the computation, the * reducer implementation cannot guarantee that they will be the same in a
+ * parallel computation as in a serial computation. In particular:
+ *
+ * - In the serial execution, the ostream state in the continuation of a
+ * spawn will be the same as the state at the end of the spawned function.
+ * In the parallel execution, if the continuation is stolen, its view will
+ * contain a newly created ostream with the default initial state.
+ * - In the serial execution, the ostream state following a sync is the same
+ * as the state before the sync. In the parallel execution, if the
+ * continuation is stolen, then the state following the sync will be the
+ * same as the state at the end of some spawned function.
+ *
+ * In short, you must not make any assumptions about the stream state of an
+ * ostream reducer:
+ *
+ * - Following a `cilk_spawn`.
+ * - Following a `cilk_sync`.
+ * - At the start of an iteration of a `cilk_for` loop.
+ * - Following the completion of a `cilk_for` loop.
+ *
+ * @section redostream_types Type and Operator Requirements
+ *
+ * `std::basic_ostream<Char, Traits>` must be a valid type.
+*/
+
namespace cilk {
-/**
- * @brief Class 'reducer_ostream' is the representation of a hyperobject for
- * output text streaming.
+/** @ingroup ReducersOstream */
+//@{
+
+/** The ostream reducer view class.
+ *
+ * This is the view class for reducers created with
+ * `cilk::reducer< cilk::op_basic_ostream<Char, Traits> >`. It holds the
+ * actual ostream for a parallel strand, and allows only stream output
+ * operations to be performed on it.
+ *
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view
+ * class's `<<` operation would be used in an expression like
+ * `*r << "x = " << x`, where `r` is an ostream reducer.
+ *
+ * @tparam Char The ostream element type (not the ostream type).
+ * @tparam Traits The character traits type.
+ *
+ * @see ReducersOstream
+ * @see op_basic_ostream
*/
-class reducer_ostream
+template<typename Char, typename Traits>
+class op_basic_ostream_view : public std::basic_ostream<Char, Traits>
{
+ typedef std::basic_ostream<Char, Traits> base;
+ typedef std::basic_ostream<Char, Traits> ostream_type;
+
+ // A non-leftmost view is associated with a private string buffer. (The
+ // leftmost view is associated with the buffer of the reducer's associated
+ // ostream, so its private buffer is unused.)
+ //
+ std::basic_stringbuf<Char, Traits> m_buffer;
+
public:
- /// Internal representation of the per-strand view of the data for reducer_ostream
- class View: public std::ostream
+
+ /** Value type. Required by @ref monoid_with_view.
+ */
+ typedef ostream_type value_type;
+
+ /** Reduce operation. Required by @ref monoid_with_view.
+ */
+ void reduce(op_basic_ostream_view* other)
{
- public:
- /// Type of the std::stream reducer_ostream is based on
- typedef std::ostream Base;
-
- friend class reducer_ostream;
-
- View():
- std::ostream(0)
- {
- Base::rdbuf(&strbuf_);
- };
-
- private:
- void use_ostream (const std::ostream &os)
- {
- Base::rdbuf(os.rdbuf());
- Base::flags(os.flags()); // Copy formatting flags
- Base::setstate(os.rdstate()); // Copy error state
+ // Writing an empty buffer results in failure. Testing `sgetc()` is the
+ // easiest way of checking for an empty buffer.
+ if (other->m_buffer.sgetc() != Traits::eof()) {
+ *this << (&other->m_buffer);
}
+ }
- private:
- std::stringbuf strbuf_;
- };
+ /** Non-leftmost (identity) view constructor. The view is associated with
+ * its internal buffer. Required by @ref monoid_base.
+ */
+ op_basic_ostream_view() : base(&m_buffer) {}
-public:
- /// Definition of data view, operation, and identity for reducer_ostream
- struct Monoid: monoid_base< View >
+ /** Leftmost view constructor. The view is associated with an existing
+ * ostream.
+ */
+ op_basic_ostream_view(const ostream_type& os) : base(0)
{
- static void reduce (View *left, View *right);
- };
+ base::rdbuf(os.rdbuf()); // Copy stream buffer
+ base::flags(os.flags()); // Copy formatting flags
+ base::setstate(os.rdstate()); // Copy error state
+ }
-private:
- // Hyperobject to serve up views
- reducer<Monoid> imp_;
+ /** Sets/gets.
+ *
+ * These are all no-ops.
+ */
+ //@{
- // Methods that provide the API for the reducer
-public:
+ void view_set_value(const value_type&)
+ { assert("set_value() is not allowed on ostream reducers" && 0); }
+ const value_type& view_get_value() const
+ { assert("get_value() is not allowed on ostream reducers" && 0);
+ return *this; }
+ typedef value_type const& return_type_for_get_value;
+ void view_move_in(const value_type&)
+ { assert("move_in() is not allowed on ostream reducers" && 0); }
+ void view_move_out(const value_type&)
+ { assert("move_out() is not allowed on ostream reducers" && 0); }
- // Construct an initial 'reducer_ostream' from an 'std::ostream'. The
- // specified 'os' stream is used as the eventual destination for all
- // text streamed to this hyperobject.
- explicit reducer_ostream(const std::ostream &os);
+ //@}
+};
- // Return a modifiable reference to the underlying 'ostream' object.
- std::ostream& get_reference();
+/** Ostream monoid class. Instantiate the cilk::reducer template class with an
+ * op_basic_ostream monoid to create an ostream reducer class:
+ *
+ * cilk::reducer< cilk::op_basic_string<char> > r;
+ *
+ * @tparam Char The stream element type (not the stream type).
+ * @tparam Traits The character traits type.
+ *
+ * @see ReducersOstream
+ * @see op_basic_ostream_view
+ * @see reducer_ostream
+ * @see op_ostream
+ * @see op_wostream
+ */
+template<typename Char,
+ typename Traits = std::char_traits<Char>,
+ bool Align = false>
+class op_basic_ostream :
+ public monoid_with_view< op_basic_ostream_view<Char, Traits>, Align >
+{
+ typedef monoid_with_view< op_basic_ostream_view<Char, Traits>, Align >
+ base;
+ typedef std::basic_ostream<Char, Traits> ostream_type;
+ typedef provisional_guard<typename base::view_type> view_guard;
- /**
- * Append data from some type to the reducer_ostream
- *
- * @param v Value to be appended to the reducer_ostream
+public:
+
+ /** View type of the monoid.
*/
- template<typename T>
- std::ostream &
- operator<< (const T &v)
- {
- return imp_.view() << v;
- }
+ typedef typename base::view_type view_type;
- /**
- * Append data from a std::ostream to the reducer_ostream
+ /** @name Construct function.
*
- * @param _Pfn std::ostream to copy from
+ * The only supported ostream reducer constructor takes a reference to
+ * an existing ostream.
+ *
+ * @param os The ostream destination for receive all data written to the
+ * reducer.
*/
- std::ostream &
- operator<< (std::ostream &(*_Pfn)(std::ostream &))
+ static void construct(
+ op_basic_ostream* monoid,
+ view_type* view,
+ const ostream_type& os)
{
- View &v = imp_.view();
-
- return ((*_Pfn)(v));
+ view_guard vg( new((void*) view) view_type(os) );
+ vg.confirm_if( new((void*) monoid) op_basic_ostream );
}
-
- reducer_ostream& operator*() { return *this; }
- reducer_ostream const& operator*() const { return *this; }
-
- reducer_ostream* operator->() { return this; }
- reducer_ostream const* operator->() const { return this; }
};
-// -------------------------------------------
-// class reducer_ostream::Monoid
-// -------------------------------------------
+/**
+ * Convenience typedef for narrow ostreams.
+ */
+typedef op_basic_ostream<char> op_ostream;
/**
- * Appends string from "right" reducer_basic_string onto the end of
- * the "left". When done, the "right" reducer_basic_string is empty.
+ * Convenience typedef for wide ostreams.
*/
-void
-reducer_ostream::Monoid::reduce(View *left, View *right)
-{
- left->operator<< (&right->strbuf_);
-}
+typedef op_basic_ostream<wchar_t> op_wostream;
-// --------------------------
-// class reducer_ostream
-// --------------------------
+/// @cond internal
-/**
- * Construct a reducer_ostream which will write to the specified std::ostream
+class reducer_ostream;
+
+/** Metafunction specialization for reducer conversion.
*
- * @param os std::ostream to write to
+ * This specialization of the @ref legacy_reducer_downcast template class
+ * defined in reducer.h causes the `reducer<op_basic_ostream<char> >` class
+ * to have an `operator reducer_ostream& ()` conversion operator that
+ * statically downcasts the `reducer<op_basic_ostream<char> >` to
+ * `reducer_ostream`. (The reverse conversion, from `reducer_ostream` to
+ * `reducer<op_basic_ostream<char> >`, is just an upcast, which is provided
+ * for free by the language.)
*/
-inline
-reducer_ostream::reducer_ostream(const std::ostream &os) :
- imp_()
+template<bool Align>
+struct legacy_reducer_downcast<
+ reducer<op_basic_ostream<char, std::char_traits<char>, Align> > >
{
- View &v = imp_.view();
+ typedef reducer_ostream type;
+};
- v.use_ostream(os);
-}
+/// @endcond
-/**
- * Get a reference to the std::ostream
+/** Deprecated ostream reducer class.
+ *
+ * reducer_ostream is the same as @ref cilk::reducer<@ref op_ostream>, except
+ * that reducer_ostream is a proxy for the contained view, so that ostream
+ * operations can be applied directly to the reducer. For example, a number is
+ * written to a `reducer<op_ostream>` with `*r << x`, but a number can be
+ * written to a `reducer_ostream` with `r << x`.
+ *
+ * @deprecated Users are strongly encouraged to use `reducer<monoid>`
+ * reducers rather than the old wrappers like reducer_ostream. The
+ * `reducer<monoid>` reducers show the reducer/monoid/view
+ * architecture more clearly, are more consistent in their
+ * implementation, and present a simpler model for new
+ * user-implemented reducers.
+ *
+ * @note Implicit conversions are provided between `%reducer_ostream`
+ * and `reducer<%op_ostream>`. This allows incremental code
+ * conversion: old code that used `%reducer_ostream` can pass a
+ * `%reducer_ostream` to a converted function that now expects a
+ * pointer or reference to a `reducer<%op_ostream>`, and vice versa.
+ *
+ * @tparam Char The stream element type (not the stream type).
+ * @tparam Traits The character traits type.
+ *
+ * @see op_ostream
+ * @see reducer
+ * @see ReducersOstream
*/
-inline
-std::ostream &
-reducer_ostream::get_reference()
+class reducer_ostream :
+ public reducer<op_basic_ostream<char, std::char_traits<char>, true> >
{
- View &v = imp_.view();
+ typedef reducer<op_basic_ostream<char, std::char_traits<char>, true> > base;
+ using base::view;
+public:
- return v;
-}
+ /// The view type for the reducer.
+ typedef base::view_type View;
-} // namespace cilk
+ /// The monoid type for the reducer.
+ typedef base::monoid_type Monoid;
+
+ /** Constructs an initial `reducer_ostream` from a `std::ostream`. The
+ * specified stream is used as the eventual destination for all text
+ * streamed to this hyperobject.
+ */
+ explicit reducer_ostream(const std::ostream &os) : base(os) {}
+
+ /** Returns a modifiable reference to the underlying 'ostream' object.
+ */
+ std::ostream& get_reference() { return view(); }
+
+ /** Writes to the ostream.
+ */
+ template<typename T>
+ std::ostream& operator<< (const T &v)
+ {
+ return view() << v;
+ }
+
+ /**
+ * Calls a manipulator.
+ *
+ * @param _Pfn Pointer to the manipulator function.
+ */
+ reducer_ostream& operator<< (std::ostream &(*_Pfn)(std::ostream &))
+ {
+ (*_Pfn)(view());
+ return *this;
+ }
+
+ /** @name Dereference
+ * @details Dereferencing a wrapper is a no-op. It simply returns the
+ * wrapper. Combined with the rule that the wrapper forwards view
+ * operations to its contained view, this means that view operations can
+ * be written the same way on reducers and wrappers, which is convenient
+ * for incrementally converting old code using wrappers to use reducers
+ * instead. That is:
+ *
+ * reducer<op_ostream> r;
+ * *r << "a"; // *r returns the view
+ * // operator<<() is a view member function
+ *
+ * reducer_ostream w;
+ * *w << "a"; // *w returns the wrapper
+ * // operator<<() is a wrapper member function
+ * // that calls the corresponding view function
+ */
+ //@{
+ reducer_ostream& operator*() { return *this; }
+ reducer_ostream const& operator*() const { return *this; }
-#endif // REDUCER_OSTREAM_H_INCLUDED
+ reducer_ostream* operator->() { return this; }
+ reducer_ostream const* operator->() const { return this; }
+ //@}
+
+ /** @name Upcast
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
+ *
+ * This means that a wrapper will automatically be upcast to its aligned
+ * reducer base class. The following conversion operators provide
+ * pseudo-upcasts to the corresponding unaligned reducer class.
+ */
+ //@{
+ operator reducer<op_ostream>& ()
+ {
+ return *reinterpret_cast< reducer<op_ostream>* >(this);
+ }
+ operator const reducer<op_ostream>& () const
+ {
+ return *reinterpret_cast< const reducer<op_ostream>* >(this);
+ }
+ //@}
+};
+
+} // namespace cilk
+#endif // REDUCER_OSTREAM_H_INCLUDED
diff --git a/libcilkrts/include/cilk/reducer_string.h b/libcilkrts/include/cilk/reducer_string.h
index 0d70dd8b30a..9af65d55341 100644
--- a/libcilkrts/include/cilk/reducer_string.h
+++ b/libcilkrts/include/cilk/reducer_string.h
@@ -1,10 +1,8 @@
/* reducer_string.h -*- C++ -*-
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -19,7 +17,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*/
/** @file reducer_string.h
@@ -52,14 +63,14 @@
/** @defgroup ReducersString String Reducers
*
- * String reducers allow the creation of a string by concatenating a set of
+ * String reducers allow the creation of a string by concatenating a set of
* strings or characters in parallel.
*
* @ingroup Reducers
*
- * You should be familiar with @ref pagereducers "Cilk reducers", described in
- * file reducers.md, and particularly with @ref reducers_using, before trying
- * to use the information in this file.
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file reducers.md, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
*
* @section redstring_usage Usage Example
*
@@ -79,24 +90,24 @@
* @subsection redstring_monoid_values Value Set
*
* The value set of a string reducer is the set of values of the class
- * `std::basic_string<Char, Traits, Alloc>`, which we refer to as “the
- * reducer’s string type”.
+ * `std::basic_string<Char, Traits, Alloc>`, which we refer to as "the
+ * reducer's string type".
*
* @subsection redstring_monoid_operator Operator
*
- * The operator of a string reducer is the string concatenation operator,
- * defined by the “`+`” binary operator on the reducer’s string type.
+ * The operator of a string reducer is the string concatenation operator,
+ * defined by the "`+`" binary operator on the reducer's string type.
*
* @subsection redstring_monoid_identity Identity
*
- * The identity value of a string reducer is the empty string, which is the
+ * The identity value of a string reducer is the empty string, which is the
* value of the expression
* `std::basic_string<Char, Traits, Alloc>([allocator])`.
*
* @section redstring_operations Operations
*
* In the operation descriptions below, the type name `String` refers to the
- * reducer’s string type, `std::basic_string<Char, Traits, Alloc>`.
+ * reducer's string type, `std::basic_string<Char, Traits, Alloc>`.
*
* @subsection redstring_constructors Constructors
*
@@ -151,8 +162,8 @@
* the string computation.
*
* The strings for new views are created (by the view identity constructor)
- * using the same allocator as the string that was created when the reducer
- * was constructed. Note that this allocator is determined when the reducer is
+ * using the same allocator as the string that was created when the reducer
+ * was constructed. Note that this allocator is determined when the reducer is
* constructed. The following two examples may have very different behavior:
*
* string<Char, Traits, Allocator> a_string;
@@ -166,7 +177,7 @@
* ... parallel computation ...
* reducer2.move_out(a_string);
*
- * * `reducer1` will be constructed with the same allocator as `a_string`,
+ * * `reducer1` will be constructed with the same allocator as `a_string`,
* because the string was specified in the constructor. The `move_in`
* and `move_out` can therefore be done with a `swap` in constant time.
* * `reducer2` will be constructed with a _default_ allocator of type
@@ -175,8 +186,8 @@
* in _O(N)_ time.
*
* (All instances of an allocator type with no internal state (like
- * `std::allocator`) are “the same”. You only need to worry about the “same
- * allocator” issue when you create string reducers with custom allocator
+ * `std::allocator`) are "the same". You only need to worry about the "same
+ * allocator" issue when you create string reducers with custom allocator
* types.)
*
* @section redstring_types Type and Operator Requirements
@@ -192,12 +203,12 @@ namespace cilk {
/** The string append reducer view class.
*
* This is the view class for reducers created with
- * `cilk::reducer< cilk::op_basic_string<Type, Traits, Allocator> >`. It holds
+ * `cilk::reducer< cilk::op_basic_string<Char, Traits, Allocator> >`. It holds
* the accumulator variable for the reduction, and allows only append
* operations to be performed on it.
*
- * @note The reducer “dereference” operation (`reducer::operator *()`)
- * yields a reference to the view. Thus, for example, the view class’s
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view class's
* `append` operation would be used in an expression like
* `r->append(a)`, where `r` is a string append reducer variable.
*
@@ -215,7 +226,7 @@ class op_basic_string_view
typedef std::list<string_type> list_type;
typedef typename string_type::size_type size_type;
- // The view's value is represented by a list of strings and a single
+ // The view's value is represented by a list of strings and a single
// string. The value is the concatenation of the strings in the list with
// the single string at the end. All string operations apply to the single
// string; reduce operations cause lists of partial strings from multiple
@@ -224,7 +235,7 @@ class op_basic_string_view
mutable string_type m_string;
mutable list_type m_list;
- // Before returning the value of the reducer, concatenate all the strings
+ // Before returning the value of the reducer, concatenate all the strings
// in the list with the single string.
//
void flatten() const
@@ -263,11 +274,11 @@ public:
return m_string.get_allocator();
}
- /** Reduction operation.
+ /** Reduces the views of two strands.
*
* This function is invoked by the @ref op_basic_string monoid to combine
- * the views of two strands when the right strand merges with the left
- * one. It appends the value contained in the right-strand view to the
+ * the views of two strands when the right strand merges with the left
+ * one. It appends the value contained in the right-strand view to the
* value contained in the left-strand view, and leaves the value in the
* right-strand view undefined.
*
@@ -294,7 +305,7 @@ public:
//@}
- /** @name Pass constructor arguments through to the string constructor.
+ /** @name Passes constructor arguments to the string constructor.
*/
//@{
@@ -351,16 +362,18 @@ public:
m_string.clear();
}
- void view_set_value(const string_type& s)
+ void view_set_value(const string_type& s)
{ m_list.clear(); m_string = s; }
- string_type const& view_get_value() const
+ string_type const& view_get_value() const
{ flatten(); return m_string; }
- string_type & view_get_reference()
+ typedef string_type const& return_type_for_get_value;
+
+ string_type & view_get_reference()
{ flatten(); return m_string; }
- string_type const& view_get_reference() const
+ string_type const& view_get_reference() const
{ flatten(); return m_string; }
//@}
@@ -403,10 +416,10 @@ public:
* @tparam Traits The character traits type.
* @tparam Alloc The string allocator type.
* @tparam Align If `false` (the default), reducers instantiated on this
- * monoid will be naturally aligned (the Cilk library 1.0
+ * monoid will be naturally aligned (the Intel Cilk Plus library 1.0
* behavior). If `true`, reducers instantiated on this monoid
- * will be cache-aligned for binary compatibility with
- * reducers in Cilk library version 0.9.
+ * will be cache-aligned for binary compatibility with
+ * reducers in Intel Cilk Plus library version 0.9.
*
* @see ReducersString
* @see op_basic_string_view
@@ -418,11 +431,13 @@ template<typename Char,
typename Traits = std::char_traits<Char>,
typename Alloc = std::allocator<Char>,
bool Align = false>
-class op_basic_string :
+class op_basic_string :
public monoid_with_view< op_basic_string_view<Char, Traits, Alloc>, Align >
{
typedef monoid_with_view< op_basic_string_view<Char, Traits, Alloc>, Align >
base;
+ typedef provisional_guard<typename base::view_type> view_guard;
+
Alloc m_allocator;
public:
@@ -442,7 +457,7 @@ public:
op_basic_string(const Alloc& allocator = Alloc()) : m_allocator(allocator)
{}
- /** Create an identity view.
+ /** Creates an identity view.
*
* String view identity constructors take the string allocator as an
* argument.
@@ -450,48 +465,67 @@ public:
* @param v The address of the uninitialized memory in which the view
* will be constructed.
*/
- void identity(view_type *v) const { ::new((void*) v) view_type(m_allocator); }
+ void identity(view_type *v) const
+ { ::new((void*) v) view_type(m_allocator); }
/** @name Construct functions
*
* A string append reduction monoid must have a copy of the allocator of
- * the leftmost view’s string, so that it can use it in the `identity`
+ * the leftmost view's string, so that it can use it in the `identity`
* operation. This, in turn, requires that string reduction monoids have a
* specialized `construct()` function.
*
* All string reducer monoid `construct()` functions first construct the
* leftmost view, using the arguments that were passed in from the reducer
- * constructor. They then call the view’s `get_allocator()` function to
+ * constructor. They then call the view's `get_allocator()` function to
* get the string allocator from the string in the leftmost view, and pass
* that to the monoid constructor.
*/
//@{
static void construct(op_basic_string* monoid, view_type* view)
- { provisional( new ((void*)view) view_type() ).confirm_if(
- new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+ {
+ view_guard vg( new((void*) view) view_type() );
+ vg.confirm_if(
+ new((void*) monoid) op_basic_string(view->get_allocator()) );
+ }
template <typename T1>
- static void construct(op_basic_string* monoid, view_type* view, const T1& x1)
- { provisional( new ((void*)view) view_type(x1) ).confirm_if(
- new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+ static void construct(op_basic_string* monoid, view_type* view,
+ const T1& x1)
+ {
+ view_guard vg( new((void*) view) view_type(x1) );
+ vg.confirm_if(
+ new((void*) monoid) op_basic_string(view->get_allocator()) );
+ }
template <typename T1, typename T2>
- static void construct(op_basic_string* monoid, view_type* view, const T1& x1, const T2& x2)
- { provisional( new ((void*)view) view_type(x1, x2) ).confirm_if(
- new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+ static void construct(op_basic_string* monoid, view_type* view,
+ const T1& x1, const T2& x2)
+ {
+ view_guard vg( new((void*) view) view_type(x1, x2) );
+ vg.confirm_if(
+ new((void*) monoid) op_basic_string(view->get_allocator()) );
+ }
template <typename T1, typename T2, typename T3>
- static void construct(op_basic_string* monoid, view_type* view, const T1& x1, const T2& x2,
- const T3& x3)
- { provisional( new ((void*)view) view_type(x1, x2, x3) ).confirm_if(
- new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+ static void construct(op_basic_string* monoid, view_type* view,
+ const T1& x1, const T2& x2, const T3& x3)
+ {
+ view_guard vg( new((void*) view) view_type(x1, x2, x3) );
+ vg.confirm_if(
+ new((void*) monoid) op_basic_string(view->get_allocator()) );
+ }
template <typename T1, typename T2, typename T3, typename T4>
- static void construct(op_basic_string* monoid, view_type* view, const T1& x1, const T2& x2,
- const T3& x3, const T4& x4)
- { provisional( new ((void*)view) view_type(x1, x2, x3, x4) ).confirm_if(
- new ((void*)monoid) op_basic_string(view->get_allocator()) ); }
+ static void construct(op_basic_string* monoid, view_type* view,
+ const T1& x1, const T2& x2, const T3& x3,
+ const T4& x4)
+ {
+ view_guard vg( new((void*) view) view_type(x1, x2, x3, x4) );
+ vg.confirm_if(
+ new((void*) monoid) op_basic_string(view->get_allocator()) );
+ }
//@}
};
@@ -500,7 +534,7 @@ public:
/** Convenience typedef for 8-bit strings
*/
typedef op_basic_string<char> op_string;
-
+
/** Convenience typedef for 16-bit strings
*/
typedef op_basic_string<wchar_t> op_wstring;
@@ -516,13 +550,13 @@ typedef op_basic_string<wchar_t> op_wstring;
* with `r.push_back(a)`.
*
* @deprecated Users are strongly encouraged to use `reducer<monoid>`
- * reducers rather than the old wrappers like reducer_basic_string.
+ * reducers rather than the old wrappers like reducer_basic_string.
* The `reducer<monoid>` reducers show the reducer/monoid/view
* architecture more clearly, are more consistent in their
* implementation, and present a simpler model for new
* user-implemented reducers.
*
- * @note Implicit conversions are provided between `%reducer_basic_string`
+ * @note Implicit conversions are provided between `%reducer_basic_string`
* and `reducer<%op_basic_string>`. This allows incremental code
* conversion: old code that used `%reducer_basic_string` can pass a
* `%reducer_basic_string` to a converted function that now expects a
@@ -540,17 +574,17 @@ typedef op_basic_string<wchar_t> op_wstring;
template<typename Char,
typename Traits = std::char_traits<Char>,
typename Alloc = std::allocator<Char> >
-class reducer_basic_string :
+class reducer_basic_string :
public reducer< op_basic_string<Char, Traits, Alloc, true> >
{
typedef reducer< op_basic_string<Char, Traits, Alloc, true> > base;
using base::view;
public:
- /// The reducer’s string type.
+ /// The reducer's string type.
typedef typename base::value_type string_type;
- /// The reducer’s primitive component type.
+ /// The reducer's primitive component type.
typedef Char basic_value_type;
/// The string size type.
@@ -566,7 +600,7 @@ public:
/** @name Constructors
*/
//@{
-
+
/** @name Forward constructor calls to the base class.
*
* All basic_string constructor forms are supported.
@@ -575,15 +609,15 @@ public:
reducer_basic_string() {}
template <typename T1>
- reducer_basic_string(const T1& x1) :
+ reducer_basic_string(const T1& x1) :
base(x1) {}
template <typename T1, typename T2>
- reducer_basic_string(const T1& x1, const T2& x2) :
+ reducer_basic_string(const T1& x1, const T2& x2) :
base(x1, x2) {}
template <typename T1, typename T2, typename T3>
- reducer_basic_string(const T1& x1, const T2& x2, const T3& x3) :
+ reducer_basic_string(const T1& x1, const T2& x2, const T3& x3) :
base(x1, x2, x3) {}
template <typename T1, typename T2, typename T3, typename T4>
@@ -591,18 +625,18 @@ public:
base(x1, x2, x3, x4) {}
//@}
- /** Allow mutable access to the string within the current view.
+ /** Allows mutable access to the string within the current view.
*
- * @warning If this method is called before the parallel calculation is
+ * @warning If this method is called before the parallel calculation is
* complete, the string returned by this method will be a
* partial result.
*
* @returns A mutable reference to the string within the current view.
*/
- string_type &get_reference()
+ string_type &get_reference()
{ return view().view_get_reference(); }
- /** Allow read-only access to the string within the current view.
+ /** Allows read-only access to the string within the current view.
*
* @warning If this method is called before the parallel calculation is
* complete, the string returned by this method will be a
@@ -610,10 +644,10 @@ public:
*
* @returns A const reference to the string within the current view.
*/
- string_type const &get_reference() const
+ string_type const &get_reference() const
{ return view().view_get_reference(); }
- /** @name Append to the string.
+ /** @name Appends to the string.
*
* These operations are simply forwarded to the view.
*/
@@ -629,7 +663,7 @@ public:
void append(size_type count, Char ch)
{ view().append(count, ch); }
- // Append to the string
+ // Appends to the string
reducer_basic_string<Char, Traits, Alloc> &operator+=(Char ch)
{ view() += ch; return *this; }
reducer_basic_string<Char, Traits, Alloc> &operator+=(const Char *ptr)
@@ -664,10 +698,10 @@ public:
//@}
/** @name Upcast
- * @details In Cilk library 0.9, reducers were always cache-aligned. In
- * library 1.0, reducer cache alignment is optional. By default, reducers
- * are unaligned (i.e., just naturally aligned), but legacy wrappers
- * inherit from cache-aligned reducers for binary compatibility.
+ * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned.
+ * In library 1.0, reducer cache alignment is optional. By default,
+ * reducers are unaligned (i.e., just naturally aligned), but legacy
+ * wrappers inherit from cache-aligned reducers for binary compatibility.
*
* This means that a wrapper will automatically be upcast to its aligned
* reducer base class. The following conversion operators provide
@@ -676,14 +710,14 @@ public:
//@{
operator reducer< op_basic_string<Char, Traits, Alloc, false> >& ()
{
- return *reinterpret_cast< reducer<
- op_basic_string<Char, Traits, Alloc, false> >*
+ return *reinterpret_cast< reducer<
+ op_basic_string<Char, Traits, Alloc, false> >*
>(this);
}
operator const reducer< op_basic_string<Char, Traits, Alloc, false> >& () const
{
return *reinterpret_cast< const reducer<
- op_basic_string<Char, Traits, Alloc, false> >*
+ op_basic_string<Char, Traits, Alloc, false> >*
>(this);
}
//@}
@@ -703,11 +737,11 @@ typedef reducer_basic_string<wchar_t> reducer_wstring;
/// @cond internal
/** Metafunction specialization for reducer conversion.
*
- * This specialization of the @ref legacy_reducer_downcast template class
+ * This specialization of the @ref legacy_reducer_downcast template class
* defined in reducer.h causes the `reducer< op_basic_string<Char> >` class to
* have an `operator reducer_basic_string<Char>& ()` conversion operator that
* statically downcasts the `reducer<op_basic_string>` to the corresponding
- * `reducer_basic_string` type. (The reverse conversion, from
+ * `reducer_basic_string` type. (The reverse conversion, from
* `reducer_basic_string` to `reducer<op_basic_string>`, is just an upcast,
* which is provided for free by the language.)
*
diff --git a/libcilkrts/include/cilk/reducer_vector.h b/libcilkrts/include/cilk/reducer_vector.h
new file mode 100644
index 00000000000..fa53eee1d24
--- /dev/null
+++ b/libcilkrts/include/cilk/reducer_vector.h
@@ -0,0 +1,533 @@
+/* reducer_vector.h -*- C++ -*-
+ *
+ * Copyright (C) 2009-2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
+ */
+
+/** @file reducer_vector.h
+ *
+ * @brief Defines classes for doing parallel vector creation by appending.
+ *
+ * @ingroup ReducersVector
+ *
+ * @see ReducersVector
+ */
+
+#ifndef REDUCER_VECTOR_H_INCLUDED
+#define REDUCER_VECTOR_H_INCLUDED
+
+#include <cilk/reducer.h>
+#include <vector>
+#include <list>
+
+/** @defgroup ReducersVector Vector Reducers
+ *
+ * Vector reducers allow the creation of a standard vector by
+ * appending a set of elements in parallel.
+ *
+ * @ingroup Reducers
+ *
+ * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers",
+ * described in file `reducers.md`, and particularly with @ref reducers_using,
+ * before trying to use the information in this file.
+ *
+ * @section redvector_usage Usage Example
+ *
+ * typedef ... SourceData;
+ * typedef ... ResultData;
+ * vector<SourceData> input;
+ * ResultData expensive_computation(const SourceData& x);
+ * cilk::reducer< cilk::op_vector<ResultData> > r;
+ * cilk_for (int i = 0; i != input.size(); ++i) {
+ * r->push_back(expensive_computation(input[i]));
+ * }
+ * vector result;
+ * r.move_out(result);
+ *
+ * @section redvector_monoid The Monoid
+ *
+ * @subsection redvector_monoid_values Value Set
+ *
+ * The value set of a vector reducer is the set of values of the class
+ * `std::vector<Type, Alloc>`, which we refer to as "the reducer's vector
+ * type".
+ *
+ * @subsection redvector_monoid_operator Operator
+ *
+ * The operator of a vector reducer is vector concatenation.
+ *
+ * @subsection redvector_monoid_identity Identity
+ *
+ * The identity value of a vector reducer is the empty vector, which is the
+ * value of the expression `std::vector<Type, Alloc>([allocator])`.
+ *
+ * @section redvector_operations Operations
+ *
+ * In the operation descriptions below, the type name `Vector` refers to
+ * the reducer's vector type, `std::vector<Type, Alloc>`.
+ *
+ * @subsection redvector_constructors Constructors
+ *
+ * Any argument list which is valid for a `std::vector` constructor is valid
+ * for a vector reducer constructor. The usual move-in constructor is also
+ * provided:
+ *
+ * reducer(move_in(Vector& variable))
+ *
+ * @subsection redvector_get_set Set and Get
+ *
+ * void r.set_value(const Vector& value)
+ * const Vector& = r.get_value() const
+ * void r.move_in(Vector& variable)
+ * void r.move_out(Vector& variable)
+ *
+ * @subsection redvector_initial Initial Values
+ *
+ * A vector reducer with no constructor arguments, or with only an allocator
+ * argument, will initially contain the identity value, an empty vector.
+ *
+ * @subsection redvector_view_ops View Operations
+ *
+ * The view of a vector reducer provides the following member functions:
+ *
+ * void push_back(const Type& element)
+ * void insert_back(const Type& element)
+ * void insert_back(Vector::size_type n, const Type& element)
+ * template <typename Iter> void insert_back(Iter first, Iter last)
+ *
+ * The `push_back` functions is the same as the corresponding `std::vector`
+ * function. The `insert_back` function is the same as the `std::vector`
+ * `insert` function, with the first parameter fixed to the end of the vector.
+ *
+ * @section redvector_performance Performance Considerations
+ *
+ * Vector reducers work by creating a vector for each view, collecting those
+ * vectors in a list, and then concatenating them into a single result vector
+ * at the end of the computation. This last step takes place in serial code,
+ * and necessarily takes time proportional to the length of the result vector.
+ * Thus, a parallel vector reducer cannot actually speed up the time spent
+ * directly creating the vector. This trivial example would probably be slower
+ * (because of reducer overhead) than the corresponding serial code:
+ *
+ * vector<T> a;
+ * reducer<op_vector<T> > r;
+ * cilk_for (int i = 0; i != a.length(); ++i) {
+ * r->push_back(a[i]);
+ * }
+ * vector<T> result;
+ * r.move_out(result);
+ *
+ * What a vector reducer _can_ do is to allow the _remainder_ of the
+ * computation to be done in parallel, without having to worry about
+ * managing the vector computation.
+ *
+ * The vectors for new views are created (by the view identity constructor)
+ * using the same allocator as the vector that was created when the reducer
+ * was constructed. Note that this allocator is determined when the reducer
+ * is constructed. The following two examples may have very different
+ * behavior:
+ *
+ * vector<Type, Allocator> a_vector;
+ *
+ * reducer< op_vector<Type, Allocator> reducer1(move_in(a_vector));
+ * ... parallel computation ...
+ * reducer1.move_out(a_vector);
+ *
+ * reducer< op_vector<Type, Allocator> reducer2;
+ * reducer2.move_in(a_vector);
+ * ... parallel computation ...
+ * reducer2.move_out(a_vector);
+ *
+ * * `reducer1` will be constructed with the same allocator as `a_vector`,
+ * because the vector was specified in the constructor. The `move_in`
+ * and`move_out` can therefore be done with a `swap` in constant time.
+ * * `reducer2` will be constructed with a _default_ allocator of type
+ * `Allocator`, which may not be the same as the allocator of `a_vector`.
+ * Therefore, the `move_in` and `move_out` may have to be done with a
+ * copy in _O(N)_ time.
+ *
+ * (All instances of an allocator class with no internal state (like
+ * `std::allocator`) are "the same". You only need to worry about the "same
+ * allocator" issue when you create vector reducers with a custom allocator
+ * class that has data members.)
+ *
+ * @section redvector_types Type and Operator Requirements
+ *
+ * `std::vector<Type, Alloc>` must be a valid type.
+*/
+
+namespace cilk {
+
+/** @ingroup ReducersVector */
+//@{
+
+/** @brief The vector reducer view class.
+ *
+ * This is the view class for reducers created with
+ * `cilk::reducer< cilk::op_vector<Type, Allocator> >`. It holds the
+ * accumulator variable for the reduction, and allows only append operations
+ * to be performed on it.
+ *
+ * @note The reducer "dereference" operation (`reducer::operator *()`)
+ * yields a reference to the view. Thus, for example, the view
+ * class's `push_back` operation would be used in an expression like
+ * `r->push_back(a)`, where `r` is a vector reducer variable.
+ *
+ * @tparam Type The vector element type (not the vector type).
+ * @tparam Alloc The vector allocator type.
+ *
+ * @see @ref ReducersVector
+ * @see op_vector
+ */
+template<typename Type, typename Alloc>
+class op_vector_view
+{
+ typedef std::vector<Type, Alloc> vector_type;
+ typedef std::list<vector_type, typename Alloc::template rebind<vector_type>::other>
+ list_type;
+ typedef typename vector_type::size_type size_type;
+
+ // The view's value is represented by a list of vectors and a single
+ // vector. The value is the concatenation of the vectors in the list with
+ // the single vector at the end. All vector operations apply to the single
+ // vector; reduce operations cause lists of partial vectors from multiple
+ // strands to be combined.
+ //
+ mutable vector_type m_vector;
+ mutable list_type m_list;
+
+ // Before returning the value of the reducer, concatenate all the vectors
+ // in the list with the single vector.
+ //
+ void flatten() const
+ {
+ if (m_list.empty()) return;
+
+ typename list_type::iterator i;
+
+ size_type len = m_vector.size();
+ for (i = m_list.begin(); i != m_list.end(); ++i)
+ len += i->size();
+
+ vector_type result(get_allocator());
+ result.reserve(len);
+
+ for (i = m_list.begin(); i != m_list.end(); ++i)
+ result.insert(result.end(), i->begin(), i->end());
+ m_list.clear();
+
+ result.insert(result.end(), m_vector.begin(), m_vector.end());
+ result.swap(m_vector);
+ }
+
+public:
+
+ /** @name Monoid support.
+ */
+ //@{
+
+ /// Required by cilk::monoid_with_view
+ typedef vector_type value_type;
+
+ /// Required by @ref op_vector
+ Alloc get_allocator() const
+ {
+ return m_vector.get_allocator();
+ }
+
+ /** Reduces the views of two strands.
+ *
+ * This function is invoked by the @ref op_vector monoid to combine
+ * the views of two strands when the right strand merges with the left
+ * one. It appends the value contained in the right-strand view to the
+ * value contained in the left-strand view, and leaves the value in the
+ * right-strand view undefined.
+ *
+ * @param other A pointer to the right-strand view. (`this` points to
+ * the left-strand view.)
+ *
+ * @note Used only by the @ref op_vector monoid to implement the
+ * monoid reduce operation.
+ */
+ void reduce(op_vector_view* other)
+ {
+ if (!other->m_vector.empty() || !other->m_list.empty()) {
+ // (list, string) + (other_list, other_string) =>
+ // (list + {string} + other_list, other_string)
+ if (!m_vector.empty()) {
+ // simulate m_list.push_back(std::move(m_vector))
+ m_list.push_back(vector_type(get_allocator()));
+ m_list.back().swap(m_vector);
+ }
+ m_list.splice(m_list.end(), other->m_list);
+ m_vector.swap(other->m_vector);
+ }
+ }
+
+ //@}
+
+ /** @name Passes constructor arguments to the vector constructor.
+ */
+ //@{
+
+ op_vector_view() :
+ m_vector(), m_list(get_allocator()) {}
+
+ template <typename T1>
+ op_vector_view(const T1& x1) :
+ m_vector(x1), m_list(get_allocator()) {}
+
+ template <typename T1, typename T2>
+ op_vector_view(const T1& x1, const T2& x2) :
+ m_vector(x1, x2), m_list(get_allocator()) {}
+
+ template <typename T1, typename T2, typename T3>
+ op_vector_view(const T1& x1, const T2& x2, const T3& x3) :
+ m_vector(x1, x2, x3), m_list(get_allocator()) {}
+
+ template <typename T1, typename T2, typename T3, typename T4>
+ op_vector_view(const T1& x1, const T2& x2, const T3& x3, const T4& x4) :
+ m_vector(x1, x2, x3, x4), m_list(get_allocator()) {}
+
+ //@}
+
+ /** Move-in constructor.
+ */
+ explicit op_vector_view(cilk::move_in_wrapper<value_type> w) :
+ m_vector(w.value().get_allocator()),
+ m_list(w.value().get_allocator())
+ {
+ m_vector.swap(w.value());
+ }
+
+ /** @name Reducer support.
+ */
+ //@{
+
+ void view_move_in(vector_type& v)
+ {
+ m_list.clear();
+ if (get_allocator() == v.get_allocator()) {
+ // Equal allocators. Do a (fast) swap.
+ m_vector.swap(v);
+ }
+ else {
+ // Unequal allocators. Do a (slow) copy.
+ m_vector = v;
+ }
+ v.clear();
+ }
+
+ void view_move_out(vector_type& v)
+ {
+ flatten();
+ if (get_allocator() == v.get_allocator()) {
+ // Equal allocators. Do a (fast) swap.
+ m_vector.swap(v);
+ }
+ else {
+ // Unequal allocators. Do a (slow) copy.
+ v = m_vector;
+ m_vector.clear();
+ }
+ }
+
+ void view_set_value(const vector_type& v)
+ {
+ m_list.clear();
+ m_vector = v;
+ }
+
+ vector_type const& view_get_value() const
+ {
+ flatten();
+ return m_vector;
+ }
+
+ typedef vector_type const& return_type_for_get_value;
+
+ //@}
+
+ /** @name View modifier operations.
+ *
+ * @details These simply wrap the corresponding operations on the
+ * underlying vector.
+ */
+ //@{
+
+ /** Adds an element at the end of the list.
+ *
+ * Equivalent to `vector.push_back(…)`
+ */
+ void push_back(const Type x)
+ {
+ m_vector.push_back(x);
+ }
+
+ /** @name Insert elements at the end of the vector.
+ *
+ * Equivalent to `vector.insert(vector.end(), …)`
+ */
+ //@{
+
+ void insert_back(const Type& element)
+ { m_vector.insert(m_vector.end(), element); }
+
+ void insert_back(typename vector_type::size_type n, const Type& element)
+ { m_vector.insert(m_vector.end(), n, element); }
+
+ template <typename Iter>
+ void insert_back(Iter first, Iter last)
+ { m_vector.insert(m_vector.end(), first, last); }
+
+ //@}
+
+ //@}
+};
+
+
+/** @brief The vector append monoid class.
+ *
+ * Instantiate the cilk::reducer template class with an op_vector monoid to
+ * create a vector reducer class. For example, to concatenate a
+ * collection of integers:
+ *
+ * cilk::reducer< cilk::op_vector<int> > r;
+ *
+ * @tparam Type The vector element type (not the vector type).
+ * @tparam Alloc The vector allocator type.
+ *
+ * @see ReducersVector
+ * @see op_vector_view
+ * @ingroup ReducersVector
+ */
+template<typename Type, typename Alloc = std::allocator<Type> >
+class op_vector :
+ public cilk::monoid_with_view< op_vector_view<Type, Alloc>, false >
+{
+ typedef cilk::monoid_with_view< op_vector_view<Type, Alloc>, false > base;
+ typedef provisional_guard<typename base::view_type> view_guard;
+
+ // The allocator to be used when constructing new views.
+ Alloc m_allocator;
+
+public:
+
+ /// View type.
+ typedef typename base::view_type view_type;
+
+ /** Constructor.
+ *
+ * There is no default constructor for vector monoids, because the
+ * allocator must always be specified.
+ *
+ * @param allocator The list allocator to be used when
+ * identity-constructing new views.
+ */
+ op_vector(const Alloc& allocator = Alloc()) : m_allocator(allocator) {}
+
+ /** Creates an identity view.
+ *
+ * Vector view identity constructors take the vector allocator as an
+ * argument.
+ *
+ * @param v The address of the uninitialized memory in which the view
+ * will be constructed.
+ */
+ void identity(view_type *v) const
+ {
+ ::new((void*) v) view_type(m_allocator);
+ }
+
+ /** @name construct functions
+ *
+ * A vector append monoid must have a copy of the allocator of
+ * the leftmost view's vector, so that it can use it in the `identity`
+ * operation. This, in turn, requires that vector append monoids have a
+ * specialized `construct()` function.
+ *
+ * All vector append monoid `construct()` functions first construct the
+ * leftmost view, using the arguments that were passed in from the reducer
+ * constructor. They then call the view's `get_allocator()` function to
+ * get the vector allocator from the vector in the leftmost view, and pass
+ * that to the monoid constructor.
+ */
+ //@{
+
+ static void construct(op_vector* monoid, view_type* view)
+ {
+ view_guard vg( new((void*) view) view_type() );
+ vg.confirm_if( new((void*) monoid) op_vector(view->get_allocator()) );
+ }
+
+ template <typename T1>
+ static void construct(op_vector* monoid, view_type* view, const T1& x1)
+ {
+ view_guard vg( new((void*) view) view_type(x1) );
+ vg.confirm_if( new((void*) monoid) op_vector(view->get_allocator()) );
+ }
+
+ template <typename T1, typename T2>
+ static void construct(op_vector* monoid, view_type* view,
+ const T1& x1, const T2& x2)
+ {
+ view_guard vg( new((void*) view) view_type(x1, x2) );
+ vg.confirm_if( new((void*) monoid) op_vector(view->get_allocator()) );
+ }
+
+ template <typename T1, typename T2, typename T3>
+ static void construct(op_vector* monoid, view_type* view,
+ const T1& x1, const T2& x2, const T3& x3)
+ {
+ view_guard vg( new((void*) view) view_type(x1, x2, x3) );
+ vg.confirm_if( new((void*) monoid) op_vector(view->get_allocator()) );
+ }
+
+ //@}
+};
+
+
+} // namespace cilk
+
+#endif // REDUCER_VECTOR_H_INCLUDED
diff --git a/libcilkrts/include/cilktools/cilkscreen.h b/libcilkrts/include/cilktools/cilkscreen.h
index c6986ae7b08..1e26c450ebe 100644
--- a/libcilkrts/include/cilktools/cilkscreen.h
+++ b/libcilkrts/include/cilktools/cilkscreen.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
diff --git a/libcilkrts/include/cilktools/cilkview.h b/libcilkrts/include/cilktools/cilkview.h
index eb7d9d8c0e4..e98489368af 100644
--- a/libcilkrts/include/cilktools/cilkview.h
+++ b/libcilkrts/include/cilktools/cilkview.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
diff --git a/libcilkrts/include/cilktools/fake_mutex.h b/libcilkrts/include/cilktools/fake_mutex.h
index 9ae0678112f..b7facf83f6d 100644
--- a/libcilkrts/include/cilktools/fake_mutex.h
+++ b/libcilkrts/include/cilktools/fake_mutex.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2013-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************
*
diff --git a/libcilkrts/include/cilktools/lock_guard.h b/libcilkrts/include/cilktools/lock_guard.h
index d513e2b9734..e2e16382b75 100644
--- a/libcilkrts/include/cilktools/lock_guard.h
+++ b/libcilkrts/include/cilktools/lock_guard.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2011-2013, Intel Corporation
+ * Copyright (C) 2011-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************
*
diff --git a/libcilkrts/include/internal/abi.h b/libcilkrts/include/internal/abi.h
index f45b5bcb178..3f38485d26b 100644
--- a/libcilkrts/include/internal/abi.h
+++ b/libcilkrts/include/internal/abi.h
@@ -1,11 +1,9 @@
/*
* abi.h
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -20,7 +18,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,6 +30,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
******************************************************************************/
@@ -461,6 +472,20 @@ CILK_ABI(void) __cilkrts_enter_frame_fast_1(__cilkrts_stack_frame *sf);
CILK_ABI(void) __cilkrts_leave_frame(__cilkrts_stack_frame *sf);
/**
+ * Suspends the runtime by notifying the workers that they should not try to
+ * steal. This function is supposed to be called from a non-parallel region
+ * (i.e., after cilk_sync in the top-level spawning function). Otherwise,
+ * which workers are sleeping or busy is unpredictable in general.
+ * The runtime can be resumed by calling __cilkrts_resume().
+ */
+CILK_ABI(void) __cilkrts_suspend(void);
+
+/**
+ * Resumes the runtime by notifying the workers that they can steal.
+ */
+CILK_ABI(void) __cilkrts_resume(void);
+
+/**
* Wait for any spawned children of this function to complete before
* continuing. This function will only return when the join counter
* has gone to 0. Other workers will re-enter the scheduling loop to
diff --git a/libcilkrts/include/internal/cilk_fake.h b/libcilkrts/include/internal/cilk_fake.h
index 2386dd6bffa..7d09de29c1e 100644
--- a/libcilkrts/include/internal/cilk_fake.h
+++ b/libcilkrts/include/internal/cilk_fake.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2011-2013, Intel Corporation
+ * Copyright (C) 2011-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/include/internal/cilk_version.h b/libcilkrts/include/internal/cilk_version.h
index f628338f7d2..95e1f2ec544 100644
--- a/libcilkrts/include/internal/cilk_version.h
+++ b/libcilkrts/include/internal/cilk_version.h
@@ -1,10 +1,8 @@
// cilk_version.h
//
-// @copyright
-// Copyright (C) 2009-2013, Intel Corporation
+// Copyright (C) 2009-2016, Intel Corporation
// All rights reserved.
//
-// @copyright
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
@@ -19,7 +17,6 @@
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
-// @copyright
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,16 +29,30 @@
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
// WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
+//
+// *********************************************************************
+//
+// PLEASE NOTE: This file is a downstream copy of a file mainitained in
+// a repository at cilkplus.org. Changes made to this file that are not
+// submitted through the contribution process detailed at
+// http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+// time that a new version is released. Changes only submitted to the
+// GNU compiler collection or posted to the git repository at
+// https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+// not tracked.
+//
+// We welcome your contributions to this open source project. Thank you
+// for your assistance in helping us improve Cilk Plus.
// DO NOT EDIT THIS FILE!
//
// It was automatically generated by cilkrts/include/internal/Makefile
#define VERSION_MAJOR 2
#define VERSION_MINOR 0
-#define VERSION_BUILD 3902
+#define VERSION_BUILD 4420
#define VERSION_REV 0
-#define VERSION_STRING "2,0,3902,0"
-#define VERSION_HASH "b4e38f4f7e3e"
-#define VERSION_BRANCH "v14.0"
-#define TBB_REV_NUMBER ""
-#define VERSION_YEAR "2013"
+#define VERSION_STRING "2,0,4420,0"
+#define VERSION_HASH "3b2d6aa9059c"
+#define VERSION_BRANCH "eng"
+#define TBB_REV_NUMBER "14788"
+#define VERSION_YEAR "2015"
diff --git a/libcilkrts/include/internal/metacall.h b/libcilkrts/include/internal/metacall.h
index 886f49f9f83..00aa0f1598a 100644
--- a/libcilkrts/include/internal/metacall.h
+++ b/libcilkrts/include/internal/metacall.h
@@ -1,11 +1,9 @@
// -*- C++ -*-
/*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -20,7 +18,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,6 +30,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
******************************************************************************
*
diff --git a/libcilkrts/include/internal/rev.mk b/libcilkrts/include/internal/rev.mk
index f65ad6d57d0..96ffdc4aa4e 100644
--- a/libcilkrts/include/internal/rev.mk
+++ b/libcilkrts/include/internal/rev.mk
@@ -1,10 +1,8 @@
#########################################################################
#
-# @copyright
-# Copyright (C) 2011-2013, Intel Corporation
+# Copyright (C) 2011-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -19,7 +17,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,10 +29,24 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
###########################################################################
# DO NOT EDIT THIS FILE!
#
# It was automatically generated by cilkrts/include/internal/Makefile
-CILK_REVISION = 3902
+CILK_REVISION = 4420
diff --git a/libcilkrts/mk/cilk-version.mk b/libcilkrts/mk/cilk-version.mk
index 76f3f4ee38e..49f524a6809 100644
--- a/libcilkrts/mk/cilk-version.mk
+++ b/libcilkrts/mk/cilk-version.mk
@@ -1,10 +1,8 @@
#########################################################################
#
-# @copyright
-# Copyright (C) 2009-2013, Intel Corporation
+# Copyright (C) 2009-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -19,7 +17,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
###########################################################################
# cilk-version.mk
#
diff --git a/libcilkrts/runtime/acknowledgements.dox b/libcilkrts/runtime/acknowledgements.dox
index 79b5d876f33..7f6271ccafa 100644
--- a/libcilkrts/runtime/acknowledgements.dox
+++ b/libcilkrts/runtime/acknowledgements.dox
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/*
diff --git a/libcilkrts/runtime/bug.cpp b/libcilkrts/runtime/bug.cpp
index dbdf1fd3216..f2109852a57 100644
--- a/libcilkrts/runtime/bug.cpp
+++ b/libcilkrts/runtime/bug.cpp
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "bug.h"
@@ -54,7 +65,7 @@ __CILKRTS_BEGIN_EXTERN_C
COMMON_PORTABLE const char *const __cilkrts_assertion_failed =
"%s:%d: cilk assertion failed: %s\n";
-COMMON_PORTABLE void __cilkrts_bug(const char *fmt,...) cilk_nothrow
+COMMON_PORTABLE NORETURN __cilkrts_bug(const char *fmt,...) cilk_nothrow
{
#if defined (_WIN32) && defined(_DEBUG)
_CRTIMP void __cdecl _wassert(__in_z const wchar_t * _Message,
diff --git a/libcilkrts/runtime/bug.h b/libcilkrts/runtime/bug.h
index 1a64bea3a54..3b5493bace6 100644
--- a/libcilkrts/runtime/bug.h
+++ b/libcilkrts/runtime/bug.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/c_reducers.c b/libcilkrts/runtime/c_reducers.c
index 52615e93f43..f99ecbe6dd3 100644
--- a/libcilkrts/runtime/c_reducers.c
+++ b/libcilkrts/runtime/c_reducers.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
@@ -47,6 +58,13 @@
#define CILK_C_DEFINE_REDUCERS
+#ifdef _WRS_KERNEL
+#define WCHAR_MIN 0
+#define WCHAR_MAX USHRT_MAX
+#define WINT_MIN INT_MIN
+#define WINT_MAX INT_MAX
+#endif
+
#include <cilk/reducer_opadd.h>
#include <cilk/reducer_opand.h>
#include <cilk/reducer_opmul.h>
diff --git a/libcilkrts/runtime/cilk-abi-cilk-for.cpp b/libcilkrts/runtime/cilk-abi-cilk-for.cpp
index 4cd04f521cf..6e7c08a08af 100644
--- a/libcilkrts/runtime/cilk-abi-cilk-for.cpp
+++ b/libcilkrts/runtime/cilk-abi-cilk-for.cpp
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2011, 2013, Intel Corporation
+ * Copyright (C) 2011-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
@@ -405,6 +416,9 @@ CILK_ABI_THROWS_VOID __cilkrts_cilk_for_32(__cilk_abi_f32_t body, void *data,
CILK_ABI_THROWS_VOID __cilkrts_cilk_for_64(__cilk_abi_f64_t body, void *data,
cilk64_t count, int grain)
{
+ // Cilkscreen should not report this call in a stack trace
+ NOTIFY_ZC_INTRINSIC((char *)"cilkscreen_hide_call", 0);
+
// Check for an empty range here as an optimization - don't need to do any
// __cilkrts_stack_frame initialization
if (count > 0)
diff --git a/libcilkrts/runtime/cilk-abi-vla-internal.c b/libcilkrts/runtime/cilk-abi-vla-internal.c
index 6fb92677ad0..b7696611165 100644
--- a/libcilkrts/runtime/cilk-abi-vla-internal.c
+++ b/libcilkrts/runtime/cilk-abi-vla-internal.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2013-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/*
diff --git a/libcilkrts/runtime/cilk-abi-vla-internal.h b/libcilkrts/runtime/cilk-abi-vla-internal.h
index 909f08fa471..57fe51ce4c7 100644
--- a/libcilkrts/runtime/cilk-abi-vla-internal.h
+++ b/libcilkrts/runtime/cilk-abi-vla-internal.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2013-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/cilk-abi.c b/libcilkrts/runtime/cilk-abi.c
index 1da05239ebc..35bb413bf0a 100644
--- a/libcilkrts/runtime/cilk-abi.c
+++ b/libcilkrts/runtime/cilk-abi.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
@@ -296,6 +307,45 @@ CILK_ABI_VOID __cilkrts_sync(__cilkrts_stack_frame *sf)
__cilkrts_c_sync(w, sf);
}
+/**
+ * Suspends the runtime by notifying the workers that they should not try to
+ * steal. This function is supposed to be called from a non-parallel region
+ * (i.e., after cilk_sync in the top-level spawning function). Otherwise,
+ * which workers are sleeping or busy is unpredictable in general.
+ * The runtime can be resumed by calling __cilkrts_resume().
+ */
+CILK_ABI_VOID __cilkrts_suspend(void)
+{
+ global_state_t *g = cilkg_get_global_state();
+ if (NULL == g || g->P < 2)
+ return;
+ __cilkrts_worker *w = __cilkrts_get_tls_worker();
+ // Do nothing if worker/frame is not available
+ if (NULL == w || NULL == w->current_stack_frame)
+ return;
+ // Do nothing if this was called within a parallel region.
+ __cilkrts_stack_frame *sf = w->current_stack_frame;
+ if (0 == (sf->flags & CILK_FRAME_LAST) || (sf->flags & CILK_FRAME_UNSYNCHED))
+ return;
+ __cilkrts_worker *root = g->workers[0];
+ root->l->steal_failure_count = g->max_steal_failures + 1;
+ CILK_ASSERT(root->l->signal_node);
+ signal_node_msg(root->l->signal_node, 0);
+}
+
+/**
+ * Resumes the runtime by notifying the workers that they can steal.
+ */
+CILK_ABI_VOID __cilkrts_resume(void)
+{
+ global_state_t *g = cilkg_get_global_state();
+ if (NULL == g || g->P < 2)
+ return;
+ __cilkrts_worker *root = g->workers[0];
+ CILK_ASSERT(root->l->signal_node);
+ signal_node_msg(root->l->signal_node, 1);
+}
+
/*
* __cilkrts_get_sf
*
@@ -391,6 +441,10 @@ CILK_ABI_WORKER_PTR BIND_THREAD_RTN(void)
__cilkrts_set_tls_worker(w);
__cilkrts_cilkscreen_establish_worker(w);
+
+
+ START_INTERVAL(w, INTERVAL_IN_SCHEDULER);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
{
full_frame *ff = __cilkrts_make_full_frame(w, 0);
@@ -462,13 +516,10 @@ CILK_ABI_WORKER_PTR BIND_THREAD_RTN(void)
global_os_mutex_unlock();
- /* If there's only 1 worker, the counts will be started in
- * __cilkrts_scheduler */
- if (g->P > 1)
- {
- START_INTERVAL(w, INTERVAL_IN_SCHEDULER);
- START_INTERVAL(w, INTERVAL_WORKING);
- }
+ /* We are about to switch back into user code after binding the
+ thread. Start working again. */
+ STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+ START_INTERVAL(w, INTERVAL_WORKING);
ITT_SYNC_RELEASING(&unique_obj);
diff --git a/libcilkrts/runtime/cilk-ittnotify.h b/libcilkrts/runtime/cilk-ittnotify.h
index ff995db6fbb..256f334dcea 100644
--- a/libcilkrts/runtime/cilk-ittnotify.h
+++ b/libcilkrts/runtime/cilk-ittnotify.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#ifndef INCLUDED_CILK_ITTNOTIFY_DOT_H
diff --git a/libcilkrts/runtime/cilk-tbb-interop.h b/libcilkrts/runtime/cilk-tbb-interop.h
index cc5cff4b57e..c073ab172c6 100644
--- a/libcilkrts/runtime/cilk-tbb-interop.h
+++ b/libcilkrts/runtime/cilk-tbb-interop.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/cilk_api.c b/libcilkrts/runtime/cilk_api.c
index bbca984bc03..62798d29c76 100644
--- a/libcilkrts/runtime/cilk_api.c
+++ b/libcilkrts/runtime/cilk_api.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/*
diff --git a/libcilkrts/runtime/cilk_fiber-unix.cpp b/libcilkrts/runtime/cilk_fiber-unix.cpp
index b0ed53ad052..d59bfcae4cb 100644
--- a/libcilkrts/runtime/cilk_fiber-unix.cpp
+++ b/libcilkrts/runtime/cilk_fiber-unix.cpp
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2012-2013, Intel Corporation
+ * Copyright (C) 2012-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "cilk_fiber-unix.h"
@@ -47,33 +58,32 @@
#include <errno.h>
#include <sys/mman.h>
#include <unistd.h>
-
-// You'd think that getting a defintion for alloca would be easy. But you'd
-// be wrong. Here's a variant on what's recommended in the autoconf doc. I've
-// remove the Windows portion since this is Unix-specific code.
-#if defined HAVE_ALLOCA_H
-# include <alloca.h>
-#elif defined __GNUC__
-# define alloca __builtin_alloca
-#elif defined _AIX
-# define alloca __alloca
-#else
-# include <stddef.h>
-# ifdef __cplusplus
-extern "C"
-# endif
-void *alloca (size_t);
-#endif
+#include "declare-alloca.h"
// MAP_ANON is deprecated on Linux, but seems to be required on Mac...
#ifndef MAP_ANONYMOUS
-#define MAP_ANONYMOUS MAP_ANON
+# define MAP_ANONYMOUS MAP_ANON
+#endif
+
+// MAP_STACK and MAP_GROWSDOWN have no affect in Linux as of 2014-04-04, but
+// could be very useful in future versions. If they are not defined, then set
+// them to zero (no bits set).
+#ifndef MAP_STACK
+# define MAP_STACK 0
+#endif
+#ifndef MAP_GROWSDOWN
+# define MAP_GROWSDOWN 0
#endif
// Magic number for sanity checking fiber structure
const unsigned magic_number = 0x5afef00d;
-int cilk_fiber_sysdep::s_page_size = getpagesize();
+// Page size for stacks
+#ifdef _WRS_KERNEL
+long cilk_fiber_sysdep::s_page_size = 4096;
+#else
+long cilk_fiber_sysdep::s_page_size = sysconf(_SC_PAGESIZE);
+#endif
cilk_fiber_sysdep::cilk_fiber_sysdep(std::size_t stack_size)
: cilk_fiber(stack_size)
@@ -270,7 +280,7 @@ void cilk_fiber_sysdep::make_stack(size_t stack_size)
p = (char*)mmap(0, rounded_stack_size,
PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANONYMOUS,
+ MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK|MAP_GROWSDOWN,
-1, 0);
if (MAP_FAILED == p) {
// For whatever reason (probably ran out of memory), mmap() failed.
diff --git a/libcilkrts/runtime/cilk_fiber-unix.h b/libcilkrts/runtime/cilk_fiber-unix.h
index 9f47d5b0437..5ebe840616f 100644
--- a/libcilkrts/runtime/cilk_fiber-unix.h
+++ b/libcilkrts/runtime/cilk_fiber-unix.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2012-2013, Intel Corporation
+ * Copyright (C) 2012-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#ifndef INCLUDED_CILK_FIBER_UNIX_DOT_H
@@ -126,13 +137,12 @@ struct cilk_fiber_sysdep : public cilk_fiber
inline char* get_stack_base_sysdep() { return m_stack_base; }
private:
- char* m_stack_base; ///< The base of this fiber's stack.
- char* m_stack; // Stack memory (low address)
- __CILK_JUMP_BUFFER m_resume_jmpbuf; // Place to resume fiber
- unsigned m_magic; // Magic number for checking
+ char* m_stack_base; ///< The base of this fiber's stack.
+ char* m_stack; ///< Stack memory (low address)
+ __CILK_JUMP_BUFFER m_resume_jmpbuf; ///< Place to resume fiber
+ unsigned m_magic; ///< Magic number for checking
- static int s_page_size; // Page size for
- // stacks.
+ static long s_page_size; ///< Page size for stacks.
// Allocate memory for a stack. This method
// initializes m_stack and m_stack_base.
diff --git a/libcilkrts/runtime/cilk_fiber.cpp b/libcilkrts/runtime/cilk_fiber.cpp
index 0c66f234d3b..218c73ba813 100644
--- a/libcilkrts/runtime/cilk_fiber.cpp
+++ b/libcilkrts/runtime/cilk_fiber.cpp
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2012-2013, Intel Corporation
+ * Copyright (C) 2012-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/* Implementations of non-platform-specific aspects of cilk_fiber, especially
diff --git a/libcilkrts/runtime/cilk_fiber.h b/libcilkrts/runtime/cilk_fiber.h
index 2671f924681..d91687aa57a 100644
--- a/libcilkrts/runtime/cilk_fiber.h
+++ b/libcilkrts/runtime/cilk_fiber.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2012-2013, Intel Corporation
+ * Copyright (C) 2012-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/cilk_malloc.c b/libcilkrts/runtime/cilk_malloc.c
index 9d02c52d037..3ddaad67af3 100644
--- a/libcilkrts/runtime/cilk_malloc.c
+++ b/libcilkrts/runtime/cilk_malloc.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,12 +31,26 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "cilk_malloc.h"
#include <stdlib.h>
-#if defined _WIN32 || defined _WIN64 || defined __linux__
+#if defined _WIN32 || defined _WIN64 || defined __GLIBC__ || defined __linux__
#include <malloc.h>
#define HAS_MEMALIGN 1
#endif
diff --git a/libcilkrts/runtime/cilk_malloc.h b/libcilkrts/runtime/cilk_malloc.h
index fa0fa6d5c9d..d8ed58d2445 100644
--- a/libcilkrts/runtime/cilk_malloc.h
+++ b/libcilkrts/runtime/cilk_malloc.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/cilk_str_mem.h b/libcilkrts/runtime/cilk_str_mem.h
new file mode 100644
index 00000000000..0da50b40928
--- /dev/null
+++ b/libcilkrts/runtime/cilk_str_mem.h
@@ -0,0 +1,94 @@
+/* cilk_str_mem.h -*-C-*-
+ *
+ *************************************************************************
+ *
+ * Copyright (C) 2014-2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
+ **************************************************************************/
+
+/**
+ * @file cilk_str_mem.h
+ *
+ * @breif Interface to safe string/memmory C API to replace banned C API.
+ */
+
+#ifndef INCLUDED_CILK_STR_MEM_DOT_H
+#define INCLUDED_CILK_STR_MEM_DOT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _WIN32
+
+# include "safe_lib.h"
+# include "snprintf_s.h"
+
+#define cilk_strlen(str) strnlen_s(str, RSIZE_MAX_STR)
+#define cilk_strcpy_s strcpy_s
+// Different sprintf entries with different argument lists.
+#define cilk_snprintf_s snprintf_s_s
+#define cilk_snprintf_i snprintf_s_i
+#define cilk_snprintf_l snprintf_s_l
+#define cilk_snprintf_si snprintf_s_si
+#define cilk_snprintf_sl snprintf_s_sl
+
+#else // ! defined _WIN32
+
+#define CILK_MAX_STR (4UL << 10) // 4KB
+#define cilk_strlen(str) strnlen_s(str, CILK_MAX_STR)
+#define cilk_strcpy_s strcpy_s
+#define cilk_snprintf_s sprintf_s
+#define cilk_snprintf_i sprintf_s
+#define cilk_snprintf_l sprintf_s
+#define cilk_snprintf_si sprintf_s
+#define cilk_snprintf_sl sprintf_s
+
+#endif // ! defined _WIN32
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // INCLUDED_CILK_STR_MEM_DOT_H
diff --git a/libcilkrts/runtime/component.h b/libcilkrts/runtime/component.h
index 64ff3e5fc42..34776233f32 100644
--- a/libcilkrts/runtime/component.h
+++ b/libcilkrts/runtime/component.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#ifndef INCLUDED_COMPONENT_DOT_H
diff --git a/libcilkrts/runtime/config/arm/cilk-abi-vla.c b/libcilkrts/runtime/config/arm/cilk-abi-vla.c
new file mode 100644
index 00000000000..cf88d997046
--- /dev/null
+++ b/libcilkrts/runtime/config/arm/cilk-abi-vla.c
@@ -0,0 +1,115 @@
+/* cilk-abi-vla.cpp -*-C++-*-
+ *
+ *************************************************************************
+ *
+ * Copyright (C) 2013-2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
+ *
+ **************************************************************************/
+
+/*
+ * Implementation of Variable Length Array (VLA) ABI.
+ *
+ * The compiler calls these functions to allocate Variable Length Arrays
+ * at runtime. The compiler must guarantee that __cilkrts_stack_free() is
+ * called to cleanup any memory allocated by __cilkrts_stack_alloc().
+ *
+ * This generic implementation always allocates the memory from the heap.
+ * Optimally, the implementation should expand the frame of the calling
+ * function if possible, since that will be faster. See the x86 version
+ * for one possible implementation.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#include "internal/abi.h"
+#include "cilk-abi-vla-internal.h"
+
+// Allocate space for a variable length array
+CILK_ABI(__cilkrts_void_ptr)
+__cilkrts_stack_alloc(
+ __cilkrts_stack_frame *sf,
+ size_t size,
+ size_t distance_from_sp_to_alloca_area,
+ uint32_t align, // align is always >= minimum stack alignment and
+ // >= ptr_size as well, and must be a power of 2.
+ uint32_t needs_tag // non-zero if the pointer being returned needs to
+ // be tagged
+)
+{
+ // full_size will be a multiple of align, and contains
+ // enough extra space to allocate a marker.
+ size_t full_size = (size + align - 1) & ~(align - 1);
+
+ // Allocate memory from the heap. The compiler is responsible
+ // for guaranteeing us a chance to free it before the function
+ // exits
+
+ return (void *)vla_internal_heap_alloc(sf, full_size, align);
+}
+
+// Free the space allocated for a variable length array.
+CILK_ABI(void)
+__cilkrts_stack_free(
+ __cilkrts_stack_frame *sf,
+ void *p,
+ size_t size,
+ size_t distance_from_sp_to_alloca_area,
+ uint32_t align, // same requirements as for align in allocation,
+ // and must match alignment that was passed when
+ // doing the allocation
+ uint32_t known_from_stack // non-zero if this is known to be allocated
+ // on the stack, and therefore has no tag
+)
+{
+ // full_size will be a multiple of align, and contains
+ // enough extra space to allocate a marker if one was needed.
+ size_t full_size = (size + align - 1) & ~(align - 1);
+
+ // Just free the allocated memory to the heap since we don't know
+ // how to expand/contract the calling frame
+ vla_internal_heap_free(p, full_size);
+}
diff --git a/libcilkrts/runtime/config/arm/os-fence.h b/libcilkrts/runtime/config/arm/os-fence.h
new file mode 100644
index 00000000000..67e157a19e5
--- /dev/null
+++ b/libcilkrts/runtime/config/arm/os-fence.h
@@ -0,0 +1,64 @@
+/* os.h -*-C++-*-
+ *
+ *************************************************************************
+ *
+ * Copyright (C) 2009-2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
+ **************************************************************************/
+
+/*
+ * void __cilkrts_fence(void)
+ *
+ * Executes an MFENCE instruction to serialize all load and store instructions
+ * that were issued prior the MFENCE instruction. This serializing operation
+ * guarantees that every load and store instruction that precedes the MFENCE
+ * instruction is globally visible before any load or store instruction that
+ * follows the MFENCE instruction. The MFENCE instruction is ordered with
+ * respect to all load and store instructions, other MFENCE instructions, any
+ * SFENCE and LFENCE instructions, and any serializing instructions (such as
+ * the CPUID instruction).
+ */
+
+// COMMON_SYSDEP void __cilkrts_fence(void); ///< MFENCE instruction
+# define __cilkrts_fence() __asm__ __volatile__ ("mcr p15,0,%[t],c7,c10,4\n" :: [t] "r" (0) : "memory");
diff --git a/libcilkrts/runtime/config/arm/os-unix-sysdep.c b/libcilkrts/runtime/config/arm/os-unix-sysdep.c
new file mode 100644
index 00000000000..02d8c2bebff
--- /dev/null
+++ b/libcilkrts/runtime/config/arm/os-unix-sysdep.c
@@ -0,0 +1,105 @@
+/* os-unix-sysdep.c -*-C-*-
+ *
+ *************************************************************************
+ *
+ * Copyright (C) 2009-2016, Intel Corporation
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Intel Corporation nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
+ * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
+ *************************************************************************
+ *
+ * This file contains generic implementations of system-specific code for
+ * Unix-based systems
+ */
+
+#include "os.h"
+#include "sysdep.h"
+
+/*
+ * The cycle counter is used for debugging. This funciton is only called if
+ * CILK_PROFILE is defined when the runtime is built.
+ */
+COMMON_SYSDEP unsigned long long __cilkrts_getticks(void)
+{
+# warning "unimplemented cycle counter"
+ return 0;
+}
+
+/*
+ * A "short pause" - called from the Cilk runtime's spinloops.
+ */
+COMMON_SYSDEP void __cilkrts_short_pause(void)
+{
+# warning __cilkrts_short_pause empty
+}
+
+/*
+ * Interlocked exchange - used to implement the Cilk runtime's spinloops
+ */
+COMMON_SYSDEP int __cilkrts_xchg(volatile int *ptr, int x)
+{
+ x = __sync_lock_test_and_set(ptr, x);
+ return x;
+}
+
+
+/*
+ * Restore the floating point state that is stored in a stack frame at each
+ * spawn. This should be called each time a frame is resumed.
+ *
+ * Only valid for IA32 and Intel64 processors.
+ */
+void restore_x86_fp_state (__cilkrts_stack_frame *sf)
+{
+}
+
+
+/*
+ * Save the floating point state to the __cilkrts_stack_frame at each spawn.
+ *
+ * Architecture-specific - Should only be needed on IA32 and Intel64
+ * processors.
+ */
+void sysdep_save_fp_ctrl_state(__cilkrts_stack_frame *sf)
+{
+}
+
diff --git a/libcilkrts/runtime/config/generic/cilk-abi-vla.c b/libcilkrts/runtime/config/generic/cilk-abi-vla.c
index 98fefa101bd..d0b65381069 100644
--- a/libcilkrts/runtime/config/generic/cilk-abi-vla.c
+++ b/libcilkrts/runtime/config/generic/cilk-abi-vla.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2013-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
@@ -103,5 +114,5 @@ __cilkrts_stack_free(
// Just free the allocated memory to the heap since we don't know
// how to expand/contract the calling frame
- vla_internal_heap_free(t, full_size);
+ vla_internal_heap_free(p, full_size);
}
diff --git a/libcilkrts/runtime/config/generic/os-fence.h b/libcilkrts/runtime/config/generic/os-fence.h
index 841307a5296..231f136bd5e 100644
--- a/libcilkrts/runtime/config/generic/os-fence.h
+++ b/libcilkrts/runtime/config/generic/os-fence.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/*
diff --git a/libcilkrts/runtime/config/generic/os-unix-sysdep.c b/libcilkrts/runtime/config/generic/os-unix-sysdep.c
index fda7fc414bc..02d8c2bebff 100644
--- a/libcilkrts/runtime/config/generic/os-unix-sysdep.c
+++ b/libcilkrts/runtime/config/generic/os-unix-sysdep.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*************************************************************************
*
* This file contains generic implementations of system-specific code for
diff --git a/libcilkrts/runtime/config/x86/cilk-abi-vla.c b/libcilkrts/runtime/config/x86/cilk-abi-vla.c
index 38c2630a1e6..873757f98d8 100644
--- a/libcilkrts/runtime/config/x86/cilk-abi-vla.c
+++ b/libcilkrts/runtime/config/x86/cilk-abi-vla.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2013, Intel Corporation
+ * Copyright (C) 2013-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
@@ -58,37 +69,21 @@
#include <assert.h>
#include <stdlib.h>
#include <stdint.h>
-
-// Getting a definition for alloca appears to be a pain in the butt. Here's
-// a variant on what's recommended in the autoconf doc
-#if defined _MSC_VER
-# include <malloc.h>
-# define alloca _alloca
-#elif defined HAVE_ALLOCA_H
-# include <alloca.h>
-#elif defined __GNUC__
-# define alloca __builtin_alloca
-#elif defined _AIX
-# define alloca __alloca
-#else
-# include <stddef.h>
-# ifdef __cplusplus
-extern "C"
-# endif
-void *alloca (size_t);
-#endif
+#include "declare-alloca.h"
#ifdef _WIN32
-# define INLINE static __inline
-# pragma warning(disable:1025) // Don't whine about zero extending result of unary operation
+# define INLINE static __inline
+# pragma warning(disable:1025) // Don't whine about zero extending result of unary operation
#else
-# define INLINE static inline
+# define INLINE static inline
#endif
#include "internal/abi.h"
#include "cilk-abi-vla-internal.h"
+#ifdef __INTEL_COMPILER
+// These functions are used only within __INTEL_COMPILER.
#if defined(__x86_64) || defined(_M_X64)
INLINE void setsp(void *val)
{
@@ -151,7 +146,7 @@ INLINE void copy_frame_up_and_move_bp(
"movq %2, %%rcx;"
"shrq $3, %%rcx;"
"std; rep movsq; cld;"
- "movl %3, %%rbp;" :
+ "movq %3, %%rbp;" :
:
"rm"(dst), "rm"(src), "rm"(cpy_bytes), "rm"(new_ebp) :
"rsi", "rdi", "rcx", "rbp", "memory");
@@ -226,6 +221,7 @@ INLINE void copy_frame_up_and_move_bp(
}
#endif
+#endif // __INTEL_COMPILER
#define c_cilk_ptr_from_heap 0xc2f2f00d
#define c_cilk_ptr_from_stack 0xc3f30d0f
@@ -241,11 +237,17 @@ __cilkrts_stack_alloc(
// be tagged
)
{
-#ifdef __INTEL_COMPILER
// full_size will be a multiple of align, and contains
// enough extra space to allocate a marker.
size_t full_size = (size + align - 1) & ~(align - 1);
+#ifndef __INTEL_COMPILER
+ // Allocate memory from the heap. The compiler is responsible
+ // for guaranteeing us a chance to free it before the function
+ // exits
+ return (void *)vla_internal_heap_alloc(sf, full_size, align);
+
+#else
if (needs_tag) {
full_size += align;
}
@@ -336,10 +338,7 @@ __cilkrts_stack_alloc(
}
return t;
-#else // Not __INTEL_COMPILER
- // Not supported unless we can figure out how to get the size of the frame
- return NULL;
-#endif
+#endif // __INTEL_COMPILER
}
// This frees the space allocated for a variable length array.
@@ -356,12 +355,17 @@ __cilkrts_stack_free(
// on the stack, and therefore has no tag
)
{
-#ifdef __INTEL_COMPILER
- uint32_t *t = (uint32_t*)p;
-
// full_size will be a multiple of align, and contains
// enough extra space to allocate a marker if one was needed.
size_t full_size = (size + align - 1) & ~(align - 1);
+
+#ifndef __INTEL_COMPILER
+ // Just free the allocated memory to the heap since we don't know
+ // how to expand/contract the calling frame
+ vla_internal_heap_free(p, full_size);
+
+#else
+ uint32_t *t = (uint32_t*)p;
if (known_from_stack == 0) {
// if the compiler hasn't told the run-time that this is
// known to be on the stack, then this pointer must have been
@@ -435,7 +439,5 @@ __cilkrts_stack_free(
else {
vla_internal_heap_free(t, full_size);
}
-#else // Not __INTEL_COMPILER
- // Not supported unless we can figure out how to get the size of the frame
-#endif
+#endif // __INTEL_COMPILER
}
diff --git a/libcilkrts/runtime/config/x86/os-fence.h b/libcilkrts/runtime/config/x86/os-fence.h
index ec704e94ef2..520eb425541 100644
--- a/libcilkrts/runtime/config/x86/os-fence.h
+++ b/libcilkrts/runtime/config/x86/os-fence.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/* gcc before 4.4 does not implement __sync_synchronize properly */
diff --git a/libcilkrts/runtime/config/x86/os-unix-sysdep.c b/libcilkrts/runtime/config/x86/os-unix-sysdep.c
index cbc77343215..ce043803b02 100644
--- a/libcilkrts/runtime/config/x86/os-unix-sysdep.c
+++ b/libcilkrts/runtime/config/x86/os-unix-sysdep.c
@@ -2,7 +2,7 @@
*
*************************************************************************
*
- * Copyright (C) 2009-2014, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*************************************************************************
*
* This file contains system-specific code for Unix systems
@@ -96,7 +110,7 @@ COMMON_SYSDEP int __cilkrts_xchg(volatile int *ptr, int x)
* This declaration should generate an error when the Intel compiler adds
* supprt for the intrinsic.
*/
-#ifdef __INTEL_COMPILER
+#if defined(__INTEL_COMPILER) || defined(__clang__)
static inline int __builtin_cpu_supports(const char *feature)
{
return 1;
@@ -124,7 +138,6 @@ void restore_x86_fp_state (__cilkrts_stack_frame *sf) {
#endif
}
-
void sysdep_save_fp_ctrl_state(__cilkrts_stack_frame *sf)
{
// If we're not going to restore, don't bother saving it
@@ -135,7 +148,7 @@ void sysdep_save_fp_ctrl_state(__cilkrts_stack_frame *sf)
{
__asm__ ("stmxcsr %0" : "=m" (sf->mxcsr));
}
- __asm__ ("fnstcw %0" : "=m" (sf->fpcsr));
+ __asm__ ("fnstcw %0" : "=m" (sf->fpcsr));
}
#endif
}
diff --git a/libcilkrts/runtime/symbol_test.c b/libcilkrts/runtime/declare-alloca.h
index 8291d369a65..b0ed8b2fe0a 100644
--- a/libcilkrts/runtime/symbol_test.c
+++ b/libcilkrts/runtime/declare-alloca.h
@@ -1,12 +1,10 @@
-/* symbol_test.c -*-C-*-
+/* cilk-abi-vla.cpp -*-C++-*-
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2013-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,30 +31,41 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
+ *
**************************************************************************/
-/* simple program to verify that there are no undefined symbols in the runtime.
- * If the runtime uses any symbols that are not defined, compiling this program
- * will cause a linker error.
+/*
+ * You'd think that getting a declaration for alloca would be easy. But you'd
+ * be wrong. Here's a variant on what's recommended in the autoconf doc
*/
-#define _Cilk_for for
-extern void* __cilkrts_global_state;
-void *volatile p;
-
-void foo () { }
-int main ()
-{
- int i;
- long long j;
-
- _Cilk_spawn foo();
- _Cilk_for (i = 0; i < 2; ++i)
- foo();
- _Cilk_for (j = 0; j < 2; ++j)
- foo();
- p = __cilkrts_global_state;
- return 0;
-}
-
-/* End symbol_test.c */
+#if defined _MSC_VER
+# include <malloc.h>
+# define alloca _alloca
+#elif defined HAVE_ALLOCA_H
+# include <alloca.h>
+#elif defined __GNUC__
+# define alloca __builtin_alloca
+#elif defined _AIX
+# define alloca __alloca
+#else
+# include <stddef.h>
+# ifdef __cplusplus
+extern "C"
+# endif
+void *alloca (size_t);
+#endif
diff --git a/libcilkrts/runtime/doxygen-layout.xml b/libcilkrts/runtime/doxygen-layout.xml
index fabe0ab3cd8..3083cb6c0e3 100644
--- a/libcilkrts/runtime/doxygen-layout.xml
+++ b/libcilkrts/runtime/doxygen-layout.xml
@@ -1,11 +1,9 @@
<doxygenlayout version="1.0">
<!--
-# @copyright
-# Copyright (C) 2011-2013, Intel Corporation
+# Copyright (C) 2011-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -20,7 +18,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,6 +30,20 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
-->
<!-- Navigation index tabs for HTML output -->
diff --git a/libcilkrts/runtime/doxygen.cfg b/libcilkrts/runtime/doxygen.cfg
index 684dcb51b51..f9bf047d4b2 100644
--- a/libcilkrts/runtime/doxygen.cfg
+++ b/libcilkrts/runtime/doxygen.cfg
@@ -1,10 +1,8 @@
# Doxyfile 1.7.4
-# @copyright
-# Copyright (C) 2011-2013, Intel Corporation
+# Copyright (C) 2011-2016, Intel Corporation
# All rights reserved.
#
-# @copyright
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
@@ -19,7 +17,6 @@
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
-# @copyright
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -32,6 +29,20 @@
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
# WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
+#
+# *********************************************************************
+#
+# PLEASE NOTE: This file is a downstream copy of a file mainitained in
+# a repository at cilkplus.org. Changes made to this file that are not
+# submitted through the contribution process detailed at
+# http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+# time that a new version is released. Changes only submitted to the
+# GNU compiler collection or posted to the git repository at
+# https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+# not tracked.
+#
+# We welcome your contributions to this open source project. Thank you
+# for your assistance in helping us improve Cilk Plus.
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
diff --git a/libcilkrts/runtime/except-gcc.cpp b/libcilkrts/runtime/except-gcc.cpp
index bd08d1826b3..4940acb41f7 100644
--- a/libcilkrts/runtime/except-gcc.cpp
+++ b/libcilkrts/runtime/except-gcc.cpp
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "except-gcc.h"
@@ -100,12 +111,12 @@ static void
decode_exceptions(char *out, size_t len, struct pending_exception_info *info)
{
if (info->empty())
- snprintf(out, len, "[empty]");
+ cilk_snprintf_s(out, len, "%s", "[empty]");
else if (info->rethrow)
- snprintf(out, len, "[rethrow %p]",
- info->runtime_state.caughtExceptions);
+ cilk_snprintf_l(out, len, "[rethrow %p]",
+ info->runtime_state.caughtExceptions);
else
- snprintf(out, len, "[throw %p]", (void *)info->active);
+ cilk_snprintf_l(out, len, "[throw %p]", (void *)info->active);
}
#endif
diff --git a/libcilkrts/runtime/except-gcc.h b/libcilkrts/runtime/except-gcc.h
index aa76adbc233..3ef40616269 100644
--- a/libcilkrts/runtime/except-gcc.h
+++ b/libcilkrts/runtime/except-gcc.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/except.h b/libcilkrts/runtime/except.h
index 58e2238c581..6df7443e01a 100644
--- a/libcilkrts/runtime/except.h
+++ b/libcilkrts/runtime/except.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/frame_malloc.c b/libcilkrts/runtime/frame_malloc.c
index 0b38bd209a9..9cbea45d22c 100644
--- a/libcilkrts/runtime/frame_malloc.c
+++ b/libcilkrts/runtime/frame_malloc.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "frame_malloc.h"
diff --git a/libcilkrts/runtime/frame_malloc.h b/libcilkrts/runtime/frame_malloc.h
index d412fb620fe..6f4521e2bc3 100644
--- a/libcilkrts/runtime/frame_malloc.h
+++ b/libcilkrts/runtime/frame_malloc.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/full_frame.c b/libcilkrts/runtime/full_frame.c
index 9ccfd110d6b..5d1f2a1b5d0 100644
--- a/libcilkrts/runtime/full_frame.c
+++ b/libcilkrts/runtime/full_frame.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
diff --git a/libcilkrts/runtime/full_frame.h b/libcilkrts/runtime/full_frame.h
index 327a3337afe..185675db959 100644
--- a/libcilkrts/runtime/full_frame.h
+++ b/libcilkrts/runtime/full_frame.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#ifndef INCLUDED_FULL_FRAME_DOT_H
diff --git a/libcilkrts/runtime/global_state.cpp b/libcilkrts/runtime/global_state.cpp
index 02de54f43b1..2af6697b27a 100644
--- a/libcilkrts/runtime/global_state.cpp
+++ b/libcilkrts/runtime/global_state.cpp
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "global_state.h"
@@ -57,7 +68,7 @@
// TBD: There is a race when multiple threads try to initialize the
// user_settable_values??
-//
+//
// Set to true if the user settable values portion of the global state
// singleton is initialized, even if the rest of the singleton is not
// initialized.
@@ -69,9 +80,10 @@ namespace {
// cilkg_get_user_settable_values() is called and partially-zero-filled until
// cilkg_init_global_state() is called. The first field is filled in with
// the size of a void* for the debugger and must be valid before initialization
-global_state_t global_state_singleton =
+static global_state_t global_state_singleton =
{
- sizeof(void *), // addr_size
+ sizeof(void *), // addr_size
+ GLOBAL_STATE_VERSION, // structure version
};
@@ -93,13 +105,15 @@ inline bool strmatch(const char* a, const char* b)
return 0 == std::strcmp(a, b);
}
-// Returns the integer value represented by the null-terminated string at 's'.
+// Returns the integer value represented by the null-terminated, decimal string
+// at 's'.
+
inline long to_long(const char* s)
{
char *end;
errno = 0;
- return std::strtol(s, &end, 0);
+ return std::strtol(s, &end, 10);
}
#ifdef _WIN32
@@ -571,7 +585,6 @@ global_state_t* cilkg_init_global_state()
void cilkg_publish_global_state(global_state_t* g)
{
-
// TBD: which one of these needs to be executed first? I say
// cilkg_singleton_ptr needs to be set last, with a mfence in
// between, since it is the flag that cilkg_is_published_is
@@ -584,7 +597,15 @@ void cilkg_publish_global_state(global_state_t* g)
void cilkg_deinit_global_state()
{
cilkg_singleton_ptr = NULL;
- __cilkrts_global_state = NULL;
+
+ // The pointer to the global state needs to remain valid for the
+ // debugger. Thus, we can't clear the following pointer.
+ // __cilkrts_global_state = NULL;
+
+
+ // We also don't reset the global state, so that if we resume
+ // execution after ending Cilk, user set variables (e.g., # of
+ // workers) remains valid.
}
int cilkg_is_published(void)
diff --git a/libcilkrts/runtime/global_state.h b/libcilkrts/runtime/global_state.h
index ef455e479d5..527a4b54e45 100644
--- a/libcilkrts/runtime/global_state.h
+++ b/libcilkrts/runtime/global_state.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
@@ -70,6 +81,16 @@ enum record_replay_t {
};
/**
+ * @brief Global state structure version.
+ *
+ * Since the global state is exposed for debugger access, we need a version
+ * number to let it know that the version of the structure is what it expects
+ * to see. If any of the fields marked as (fixed) below are changed, the
+ * version number needs to be bumped.
+ */
+#define GLOBAL_STATE_VERSION 0
+
+/**
* @brief The global state is a structure that is shared by all workers in
* Cilk.
*
@@ -109,7 +130,9 @@ struct global_state_t { /* COMMON_PORTABLE */
* debugger integration library will need to be changed to match!!!
*************************************************************************/
- int addr_size; ///< Number of bytes for an address, used by debugger (fixed)
+ uint16_t addr_size; ///< Number of bytes for an address, used by debugger (fixed)
+
+ uint16_t version; ///< Version of this structure (fixed)
int system_workers; ///< Number of system workers (fixed)
diff --git a/libcilkrts/runtime/jmpbuf.c b/libcilkrts/runtime/jmpbuf.c
index 39b51a593ce..857e0210749 100644
--- a/libcilkrts/runtime/jmpbuf.c
+++ b/libcilkrts/runtime/jmpbuf.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "jmpbuf.h"
diff --git a/libcilkrts/runtime/jmpbuf.h b/libcilkrts/runtime/jmpbuf.h
index 60573f3a5fa..0ce7ff8dbb2 100644
--- a/libcilkrts/runtime/jmpbuf.h
+++ b/libcilkrts/runtime/jmpbuf.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/linux-symbols.ver b/libcilkrts/runtime/linux-symbols.ver
index aeb4a5fb13d..d6568421a50 100644
--- a/libcilkrts/runtime/linux-symbols.ver
+++ b/libcilkrts/runtime/linux-symbols.ver
@@ -1,11 +1,9 @@
/*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -20,7 +18,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,6 +30,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
CILKABI0
@@ -87,11 +98,13 @@ CILKABI1
__cilkrts_get_sf;
__cilkrts_get_stack_size;
__cilkrts_get_worker_rank;
+ __cilkrts_resume;
__cilkrts_save_fp_ctrl_state;
__cilkrts_stack_alloc;
__cilkrts_stack_free;
+ __cilkrts_suspend;
__cilkrts_watch_stack;
-} CILKABI0;
+};
CILKLIB1.02
{
diff --git a/libcilkrts/runtime/local_state.c b/libcilkrts/runtime/local_state.c
index 14ac8271936..ae070d4158d 100644
--- a/libcilkrts/runtime/local_state.c
+++ b/libcilkrts/runtime/local_state.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
diff --git a/libcilkrts/runtime/local_state.h b/libcilkrts/runtime/local_state.h
index 03f39897f51..d16599f1add 100644
--- a/libcilkrts/runtime/local_state.h
+++ b/libcilkrts/runtime/local_state.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/mac-symbols.txt b/libcilkrts/runtime/mac-symbols.txt
index 38d83a8675d..efec3e984fd 100644
--- a/libcilkrts/runtime/mac-symbols.txt
+++ b/libcilkrts/runtime/mac-symbols.txt
@@ -7,7 +7,7 @@ ___cilkrts_bump_worker_rank
___cilkrts_bump_worker_rank_internal
___cilkrts_cilk_for_32
___cilkrts_cilk_for_64
-___cilkrts_debugger_notification
+
___cilkrts_dump_stats
___cilkrts_end_cilk
___cilkrts_enter_frame
@@ -33,15 +33,17 @@ ___cilkrts_hyperobject_alloc
___cilkrts_hyperobject_dealloc
___cilkrts_hyperobject_noop_destroy
___cilkrts_init
-___cilkrts_irml_version
+
___cilkrts_leave_frame
___cilkrts_metacall
+___cilkrts_resume
___cilkrts_rethrow
___cilkrts_return_exception
___cilkrts_save_fp_ctrl_state
___cilkrts_set_param
___cilkrts_stack_alloc
___cilkrts_stack_free
+___cilkrts_suspend
___cilkrts_sync
___cilkrts_synched
___cilkrts_watch_stack
diff --git a/libcilkrts/runtime/metacall_impl.c b/libcilkrts/runtime/metacall_impl.c
index ce1c51a202b..e5b3f0f9d8b 100644
--- a/libcilkrts/runtime/metacall_impl.c
+++ b/libcilkrts/runtime/metacall_impl.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "metacall_impl.h"
diff --git a/libcilkrts/runtime/metacall_impl.h b/libcilkrts/runtime/metacall_impl.h
index 90cc7f95168..d395c523570 100644
--- a/libcilkrts/runtime/metacall_impl.h
+++ b/libcilkrts/runtime/metacall_impl.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
diff --git a/libcilkrts/runtime/os-unix.c b/libcilkrts/runtime/os-unix.c
index cb582dd7591..d339daf7026 100644
--- a/libcilkrts/runtime/os-unix.c
+++ b/libcilkrts/runtime/os-unix.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,15 +31,22 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
-#ifdef __linux__
- // define _GNU_SOURCE before *any* #include.
- // Even <stdint.h> will break later #includes if this macro is not
- // already defined when it is #included.
-# define _GNU_SOURCE
-#endif
-
#include "os.h"
#include "bug.h"
#include "cilk_malloc.h"
@@ -51,22 +55,27 @@
#if defined __linux__
# include <sys/sysinfo.h>
# include <sys/syscall.h>
+
#elif defined __APPLE__
# include <sys/sysctl.h>
// Uses sysconf(_SC_NPROCESSORS_ONLN) in verbose output
-#elif defined __DragonFly__
-// No additional include files
-#elif defined __FreeBSD__
-// No additional include files
-#elif defined __CYGWIN__
-// Cygwin on Windows - no additional include files
+
#elif defined __VXWORKS__
# include <vxWorks.h>
# include <vxCpuLib.h>
-# include <taskLib.h>
+# include <taskLib.h>
+
// Solaris
#elif defined __sun__ && defined __svr4__
# include <sched.h>
+
+// OSes we know about which don't require any additional files
+#elif defined __CYGWIN__ || \
+ defined __DragonFly__ || \
+ defined __FreeBSD__ || \
+ defined __GNU__
+// No additional include files
+
#else
# error "Unsupported OS"
#endif
@@ -311,39 +320,67 @@ static pid_t linux_gettid(void)
* mask is set by the offload library to force the offload code away from
* cores that have offload support threads running on them.
*/
-static int linux_get_affinity_count (int tid)
+static int linux_get_affinity_count ()
{
-#if !defined HAVE_PTHREAD_AFFINITY_NP
- return 0;
+ long system_cores = sysconf(_SC_NPROCESSORS_ONLN);
+ int affinity_cores = 0;
+
+#if defined HAVE_PTHREAD_AFFINITY_NP
+
+#if defined (CPU_ALLOC_SIZE) && ! defined(DONT_USE_CPU_ALLOC_SIZE)
+ // Statically allocated cpu_set_t's max out at 1024 cores. If
+ // CPU_ALLOC_SIZE is available, use it to support large numbers of cores
+ size_t cpusetsize = CPU_ALLOC_SIZE(system_cores);
+ cpu_set_t *process_mask = (cpu_set_t *)__cilkrts_malloc(cpusetsize);
+
+ // Get the affinity mask for this thread
+ int err = pthread_getaffinity_np(pthread_self(),
+ cpusetsize,
+ process_mask);
+
+ // Count the available cores.
+ if (0 == err)
+ affinity_cores = CPU_COUNT_S(cpusetsize, process_mask);
+
+ __cilkrts_free(process_mask);
+
#else
+ // CPU_ALLOC_SIZE isn't available, or this is the Intel compiler build
+ // and we have to support RHEL5. Use a statically allocated cpu_set_t
cpu_set_t process_mask;
// Extract the thread affinity mask
- int err = sched_getaffinity (tid, sizeof(process_mask),&process_mask);
+ int err = pthread_getaffinity_np(pthread_self(),
+ sizeof(process_mask),
+ &process_mask);
- if (0 != err)
+ if (0 == err)
{
- return 0;
- }
-
- // We have extracted the mask OK, so now we can count the number of threads
- // in it. This is linear in the maximum number of CPUs available, We
- // could do a logarithmic version, if we assume the format of the mask,
- // but it's not really worth it. We only call this at thread startup
- // anyway.
- int available_procs = 0;
- int i;
- for (i = 0; i < CPU_SETSIZE; i++)
- {
- if (CPU_ISSET(i, &process_mask))
+ // We have extracted the mask OK, so now we can count the number of
+ // threads in it. This is linear in the maximum number of CPUs
+ // available, We could do a logarithmic version, if we assume the
+ // format of the mask, but it's not really worth it. We only call
+ // this at thread startup anyway.
+ int i;
+ for (i = 0; i < CPU_SETSIZE; i++)
{
- available_procs++;
+ if (CPU_ISSET(i, &process_mask))
+ {
+ affinity_cores++;
+ }
}
}
-
- return available_procs;
-#endif
+#endif // CPU_ALLOC_SIZE
+#endif // ! defined HAVE_PTHREAD_AFFINITY_NP
+
+ // If we've got a count of cores this thread is supposed to use, that's
+ // the number or cores we'll use. Otherwise, default to the number of
+ // cores on the system.
+ if (0 == affinity_cores)
+ return system_cores;
+ else
+ return affinity_cores;
}
#endif // defined (__linux__) && ! defined(__ANDROID__)
@@ -356,43 +393,56 @@ static int linux_get_affinity_count (int tid)
COMMON_SYSDEP int __cilkrts_hardware_cpu_count(void)
{
-#if defined __ANDROID__ || (defined(__sun__) && defined(__svr4__))
- return sysconf (_SC_NPROCESSORS_ONLN);
+#if defined __ANDROID__ || \
+ defined __CYGWIN__ || \
+ defined __DragonFly__ || \
+ defined __FreeBSD__ || \
+ (defined(__sun__) && defined(__svr4__))
+ return (int)sysconf(_SC_NPROCESSORS_ONLN);
#elif defined __MIC__
/// HACK: Usually, the 3rd and 4th hyperthreads are not beneficial
/// on KNC. Also, ignore the last core.
- int P = sysconf (_SC_NPROCESSORS_ONLN);
- return P/2 - 2;
+ int count = (int)sysconf (_SC_NPROCESSORS_ONLN);
+ return count/2 - 2;
#elif defined __linux__
- int affinity_count = linux_get_affinity_count(linux_gettid());
-
- return (0 != affinity_count) ? affinity_count : sysconf (_SC_NPROCESSORS_ONLN);
+ return linux_get_affinity_count();
#elif defined __APPLE__
- int count = 0;
- int cmd[2] = { CTL_HW, HW_NCPU };
+ int count;
size_t len = sizeof count;
- int status = sysctl(cmd, 2, &count, &len, 0, 0);
- assert(status >= 0);
- assert((unsigned)count == count);
+ int status = sysctlbyname("hw.logicalcpu", &count, &len, 0, 0);
+ assert(0 == status);
return count;
-#elif defined __FreeBSD__ || defined __CYGWIN__ || defined __DragonFly__
- int ncores = sysconf(_SC_NPROCESSORS_ONLN);
-
- return ncores;
- // Just get the number of processors
-// return sysconf(_SC_NPROCESSORS_ONLN);
#elif defined __VXWORKS__
- return __builtin_popcount( vxCpuEnabledGet() );
+ return __builtin_popcount(vxCpuEnabledGet());
#else
-#error "Unknown architecture"
+#error "Unsupported architecture"
+#endif
+}
+
+COMMON_SYSDEP void __cilkrts_idle(void)
+{
+ // This is another version of __cilkrts_yield() to be used when
+ // silencing workers that are not stealing work.
+#if defined(__ANDROID__) || \
+ defined(__FreeBSD__) || \
+ defined(__VXWORKS__) || \
+ (defined(__sun__) && defined(__svr4__))
+ sched_yield();
+#elif defined(__MIC__)
+ _mm_delay_32(1024);
+#elif defined(__linux__) || \
+ defined(__APPLE__)
+ usleep(10000);
+#else
+# error "Unsupported architecture"
#endif
}
COMMON_SYSDEP void __cilkrts_sleep(void)
{
#ifdef __VXWORKS__
- taskDelay(1);
+ taskDelay(1);
#else
usleep(1);
#endif
@@ -400,13 +450,14 @@ COMMON_SYSDEP void __cilkrts_sleep(void)
COMMON_SYSDEP void __cilkrts_yield(void)
{
-#if __APPLE__ || __FreeBSD__ || __VXWORKS__
- // On MacOS, call sched_yield to yield quantum. I'm not sure why we
+#if defined(__ANDROID__) || \
+ defined(__APPLE__) || \
+ defined(__FreeBSD__) || \
+ defined(__VXWORKS__) || \
+ (defined(__sun__) && defined(__svr4__))
+ // Call sched_yield to yield quantum. I'm not sure why we
// don't do this on Linux also.
sched_yield();
-#elif defined(__DragonFly__)
- // On DragonFly BSD, call sched_yield to yield quantum.
- sched_yield();
#elif defined(__MIC__)
// On MIC, pthread_yield() really trashes things. Arch's measurements
// showed that calling _mm_delay_32() (or doing nothing) was a better
@@ -414,14 +465,12 @@ COMMON_SYSDEP void __cilkrts_yield(void)
// giving up the processor and latency starting up when work becomes
// available
_mm_delay_32(1024);
-#elif defined(__ANDROID__) || (defined(__sun__) && defined(__svr4__))
- // On Android and Solaris, call sched_yield to yield quantum. I'm not
- // sure why we don't do this on Linux also.
- sched_yield();
-#else
+#elif defined(__linux__)
// On Linux, call pthread_yield (which in turn will call sched_yield)
// to yield quantum.
pthread_yield();
+#else
+# error "Unsupported architecture"
#endif
}
@@ -434,11 +483,10 @@ COMMON_SYSDEP __STDNS size_t cilkos_getenv(char* value, __STDNS size_t vallen,
const char* envstr = getenv(varname);
if (envstr)
{
- size_t len = strlen(envstr);
+ size_t len = cilk_strlen(envstr);
if (len > vallen - 1)
return len + 1;
-
- strcpy(value, envstr);
+ cilk_strcpy_s(value, vallen, envstr);
return len;
}
else
@@ -479,11 +527,25 @@ COMMON_SYSDEP void cilkos_warning(const char *fmt, ...)
fflush(stderr);
}
+#ifdef __VXWORKS__
+#ifdef _WRS_KERNEL
+void cilkStart()
+{
+ __cilkrts_init_tls_variables();
+}
+#else
+_WRS_CONSTRUCTOR(cilkInit, 100)
+{
+ __cilkrts_init_tls_variables();
+}
+#endif
+#else
static void __attribute__((constructor)) init_once()
{
/*__cilkrts_debugger_notification_internal(CILK_DB_RUNTIME_LOADED);*/
__cilkrts_init_tls_variables();
}
+#endif
#define PAGE 4096
diff --git a/libcilkrts/runtime/os.h b/libcilkrts/runtime/os.h
index 8066f0313c2..bfdf0203c22 100644
--- a/libcilkrts/runtime/os.h
+++ b/libcilkrts/runtime/os.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
@@ -49,6 +60,7 @@
#include "rts-common.h"
#include "cilk/common.h"
#include "cilk-tbb-interop.h"
+#include "cilk_str_mem.h"
#ifdef __cplusplus
# include <cstddef>
@@ -156,6 +168,7 @@ COMMON_SYSDEP int __cilkrts_xchg(volatile int *ptr, int x);
COMMON_SYSDEP void __cilkrts_sleep(void); ///< Sleep briefly
COMMON_SYSDEP void __cilkrts_yield(void); ///< Yield quantum
+COMMON_SYSDEP void __cilkrts_idle(void); ///< Idle
/**
* @brief Gets environment variable 'varname' and copy its value into 'value'.
diff --git a/libcilkrts/runtime/os_mutex-unix.c b/libcilkrts/runtime/os_mutex-unix.c
index af398cdd089..e0f058eb4a9 100644
--- a/libcilkrts/runtime/os_mutex-unix.c
+++ b/libcilkrts/runtime/os_mutex-unix.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "os_mutex.h"
diff --git a/libcilkrts/runtime/os_mutex.h b/libcilkrts/runtime/os_mutex.h
index 71d9eb14e51..e2c12061a64 100644
--- a/libcilkrts/runtime/os_mutex.h
+++ b/libcilkrts/runtime/os_mutex.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/pedigrees.c b/libcilkrts/runtime/pedigrees.c
index dee4d9cb411..19b390ac74a 100644
--- a/libcilkrts/runtime/pedigrees.c
+++ b/libcilkrts/runtime/pedigrees.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2007-2013, Intel Corporation
+ * Copyright (C) 2007-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
diff --git a/libcilkrts/runtime/pedigrees.h b/libcilkrts/runtime/pedigrees.h
index 3f6ebb977f9..0e5c8d70da8 100644
--- a/libcilkrts/runtime/pedigrees.h
+++ b/libcilkrts/runtime/pedigrees.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#ifndef INCLUDED_PEDIGREES_DOT_H
diff --git a/libcilkrts/runtime/record-replay.cpp b/libcilkrts/runtime/record-replay.cpp
index bc5a79f2411..293c99ae65f 100644
--- a/libcilkrts/runtime/record-replay.cpp
+++ b/libcilkrts/runtime/record-replay.cpp
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2012-2013, Intel Corporation
+ * Copyright (C) 2012-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
@@ -46,8 +57,8 @@
#include <stdlib.h>
// clang is really strict about printf formats, so use the annoying integer
-// printf macros. Unfortunately they're not avaiable on Windows
-#ifdef _WIN32
+// printf macros. Unfortunately they're not available on Windows (or on VxWorks)
+#if defined(_WIN32) || defined(_WRS_KERNEL)
#define PRIu64 "llu"
#else
#define __STDC_FORMAT_MACROS 1
@@ -251,10 +262,9 @@ char * walk_pedigree_nodes(char *p, const __cilkrts_pedigree *pnode)
if (pnode->parent)
{
p = walk_pedigree_nodes(p, pnode->parent);
- p += sprintf(p, "_");
+ p += cilk_snprintf_s(p, PEDIGREE_BUFF_SIZE, "%s", (char *) "_");
}
-
- return p + sprintf(p, "%" PRIu64, pnode->rank);
+ return p + cilk_snprintf_l(p, PEDIGREE_BUFF_SIZE, "%" PRIu64, pnode->rank);
}
/**
@@ -278,7 +288,7 @@ void write_to_replay_log (__cilkrts_worker *w, const char *type,
// If we don't have an initial pedigree node, just use "0" to fill the slot
if (NULL == initial_node)
- strcpy(pedigree, "0");
+ cilk_strcpy_s(pedigree, PEDIGREE_BUFF_SIZE, "0");
else
walk_pedigree_nodes(pedigree, initial_node);
@@ -544,7 +554,9 @@ void load_recorded_log(__cilkrts_worker *w)
FILE *f;
// Open the log for reading
- sprintf(local_replay_file_name, "%s%d.cilklog", w->g->record_replay_file_name, w->self);
+ cilk_snprintf_si(local_replay_file_name, sizeof(local_replay_file_name),
+ "%s%d.cilklog", w->g->record_replay_file_name, w->self);
+
f = fopen(local_replay_file_name, "r");
// Make sure we found a log!
@@ -701,7 +713,8 @@ void replay_init_workers(global_state_t *g)
for(i = 0; i < g->total_workers; ++i)
{
__cilkrts_worker *w = g->workers[i];
- sprintf(worker_file_name, "replay_log_%d.cilklog", w->self);
+ cilk_snprintf_i(worker_file_name, sizeof(worker_file_name),
+ "replay_log_%d.cilklog", w->self);
w->l->record_replay_fptr = fopen(worker_file_name, "w+");
CILK_ASSERT(NULL != w->l->record_replay_fptr);
}
@@ -717,9 +730,8 @@ void replay_init_workers(global_state_t *g)
for(i = 0; i < g->total_workers; ++i)
{
__cilkrts_worker *w = g->workers[i];
- sprintf(worker_file_name, "%s%d.cilklog",
- g->record_replay_file_name,
- w->self);
+ cilk_snprintf_si(worker_file_name, sizeof(worker_file_name),
+ "%s%d.cilklog", g->record_replay_file_name, w->self);
w->l->record_replay_fptr = fopen(worker_file_name, "w+");
CILK_ASSERT(NULL != w->l->record_replay_fptr);
}
diff --git a/libcilkrts/runtime/record-replay.h b/libcilkrts/runtime/record-replay.h
index c1c5a68f579..a68790fc92c 100644
--- a/libcilkrts/runtime/record-replay.h
+++ b/libcilkrts/runtime/record-replay.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2012-2013, Intel Corporation
+ * Copyright (C) 2012-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
diff --git a/libcilkrts/runtime/reducer_impl.cpp b/libcilkrts/runtime/reducer_impl.cpp
index f20b9bc4592..f3acb3c30f1 100644
--- a/libcilkrts/runtime/reducer_impl.cpp
+++ b/libcilkrts/runtime/reducer_impl.cpp
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
* Patents Pending, Intel Corporation.
**************************************************************************/
diff --git a/libcilkrts/runtime/reducer_impl.h b/libcilkrts/runtime/reducer_impl.h
index 3425967ad8d..722eac14d10 100644
--- a/libcilkrts/runtime/reducer_impl.h
+++ b/libcilkrts/runtime/reducer_impl.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/rts-common.h b/libcilkrts/runtime/rts-common.h
index 4ffde7ccb1e..75a5efe7dba 100644
--- a/libcilkrts/runtime/rts-common.h
+++ b/libcilkrts/runtime/rts-common.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#ifndef INCLUDED_RTS_COMMON_DOT_H
@@ -64,8 +75,8 @@
#define COMMON_SYSDEP
#define NON_COMMON
-#if !(defined __GNUC__ || defined __ICC)
-# define __builtin_expect(a_, b_) a_
+#if !(defined __GNUC__ || defined __ICC) || defined(_WRS_KERNEL)
+# define __builtin_expect(a_, b_) (a_)
#endif
#ifdef __cplusplus
@@ -103,7 +114,7 @@
* intrinsics (__notify_intrinsic()). For those that don't, #undef the
* following definition:
*/
-//#define ENABLE_NOTIFY_ZC_INTRINSIC 1
+#define ENABLE_NOTIFY_ZC_INTRINSIC 1
#if defined(__INTEL_COMPILER)
/* The notify intrinsic was introduced in ICC 12.0. */
@@ -112,12 +123,16 @@
# endif
#elif defined(__VXWORKS__)
# undef ENABLE_NOTIFY_ZC_INTRINSIC
+#elif defined(__GNUC__)
+# // GCC doesn't support the notify intrinsic as of 4.9
+# undef ENABLE_NOTIFY_ZC_INTRINSIC
#elif defined(__clang__)
# if !defined(__has_extension) || !__has_extension(notify_zc_intrinsic)
# undef ENABLE_NOTIFY_ZC_INTRINSIC
# endif
-#elif defined(__arm__)
-// __notify_zc_intrinsic not yet supported by gcc for ARM
+#elif ! (defined(__x86_64__) || defined(__i386) \
+ || defined(_M_X64) || defined(_M_IX86))
+// __notify_zc_intrinsic currently supported only for intel architecture
# undef ENABLE_NOTIFY_ZC_INTRINSIC
#endif
diff --git a/libcilkrts/runtime/scheduler.c b/libcilkrts/runtime/scheduler.c
index bab6430d9db..538c43104f3 100644
--- a/libcilkrts/runtime/scheduler.c
+++ b/libcilkrts/runtime/scheduler.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2007-2013, Intel Corporation
+ * Copyright (C) 2007-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
@@ -1778,7 +1789,15 @@ static full_frame* check_for_work(__cilkrts_worker *w)
if (NULL == ff) {
// Punish the worker for failing to steal.
// No quantum for you!
- __cilkrts_yield();
+ if (w->l->steal_failure_count > 30000) {
+ // Punish more if the worker has been doing unsuccessful steals
+ // for a long time. After return from the idle state, it will
+ // be given a grace period to react quickly.
+ __cilkrts_idle();
+ w->l->steal_failure_count -= 300;
+ } else {
+ __cilkrts_yield();
+ }
w->l->steal_failure_count++;
} else {
// Reset steal_failure_count since there is obviously still work to
@@ -1808,6 +1827,7 @@ static full_frame* search_until_work_found_or_done(__cilkrts_worker *w)
ff = check_for_work(w);
break;
case SCHEDULE_WAIT: // go into wait-mode.
+ START_INTERVAL(w, INTERVAL_SCHEDULE_WAIT);
CILK_ASSERT(WORKER_SYSTEM == w->l->type);
// If we are about to wait, then we better not have
// a frame that we should execute...
@@ -1818,6 +1838,7 @@ static full_frame* search_until_work_found_or_done(__cilkrts_worker *w)
// Runtime is waking up.
notify_children_run(w);
w->l->steal_failure_count = 0;
+ STOP_INTERVAL(w, INTERVAL_SCHEDULE_WAIT);
break;
case SCHEDULE_EXIT: // exit the scheduler.
CILK_ASSERT(WORKER_USER != w->l->type);
@@ -2006,9 +2027,6 @@ static void worker_scheduler_init_function(__cilkrts_worker *w)
// The startup work varies, depending on the worker type.
switch (w->l->type) {
case WORKER_USER:
- // Stop working once we've entered the scheduler.
- // For user workers, INTERVAL_IN_SCHEDULER counts the time
- // since we called bind_thread.
break;
case WORKER_SYSTEM:
@@ -2022,11 +2040,6 @@ static void worker_scheduler_init_function(__cilkrts_worker *w)
// Runtime is waking up.
notify_children_run(w);
w->l->steal_failure_count = 0;
-
- // For system threads, count all the time this thread is
- // alive in the scheduling loop.
- START_INTERVAL(w, INTERVAL_IN_SCHEDULER);
- START_INTERVAL(w, INTERVAL_WORKING);
break;
default:
__cilkrts_bug("Unknown worker %p of type %d entering scheduling loop\n",
@@ -2047,8 +2060,6 @@ static void worker_scheduler_terminate_function(__cilkrts_worker *w)
// A user worker should never finish by falling through the
// scheduling loop.
CILK_ASSERT(WORKER_USER != w->l->type);
- STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
- STOP_INTERVAL(w, INTERVAL_IN_SCHEDULER);
}
/**
@@ -2060,30 +2071,36 @@ static void worker_scheduler_terminate_function(__cilkrts_worker *w)
*/
static void worker_scheduler_function(__cilkrts_worker *w)
{
+ START_INTERVAL(w, INTERVAL_INIT_WORKER);
worker_scheduler_init_function(w);
-
+ STOP_INTERVAL(w, INTERVAL_INIT_WORKER);
+
// The main scheduling loop body.
while (!w->g->work_done) {
- // Set intervals. Now we are in the runtime instead of working.
- START_INTERVAL(w, INTERVAL_IN_RUNTIME);
- STOP_INTERVAL(w, INTERVAL_WORKING);
-
// Execute the "body" of the scheduling loop, and figure
// out the fiber to jump to next.
+ START_INTERVAL(w, INTERVAL_SCHED_LOOP);
cilk_fiber* fiber_to_resume
= worker_scheduling_loop_body(w->l->scheduling_fiber, w);
-
+ STOP_INTERVAL(w, INTERVAL_SCHED_LOOP);
+
if (fiber_to_resume) {
// Suspend the current fiber and resume next one.
NOTE_INTERVAL(w, INTERVAL_SUSPEND_RESUME_OTHER);
+
+ // Whenever we jump to resume user code, we stop being in
+ // the runtime, and start working.
STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
START_INTERVAL(w, INTERVAL_WORKING);
cilk_fiber_suspend_self_and_resume_other(w->l->scheduling_fiber,
fiber_to_resume);
-
// Return here only when this (scheduling) fiber is
// resumed (i.e., this worker wants to reenter the runtime).
+
+ // We've already switched from WORKING to IN_RUNTIME in
+ // the runtime code that handles the fiber switch. Thus, at
+ // this point we are IN_RUNTIME already.
}
}
@@ -2183,6 +2200,8 @@ NORETURN __cilkrts_c_sync(__cilkrts_worker *w,
__cilkrts_stack_frame *sf_at_sync)
{
full_frame *ff;
+ STOP_INTERVAL(w, INTERVAL_WORKING);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
// Claim: This read of w->l->frame_ff can occur without
// holding the worker lock because when w has reached a sync
@@ -2343,6 +2362,11 @@ void __cilkrts_c_THE_exception_check(__cilkrts_worker *w,
int stolen_p;
__cilkrts_stack_frame *saved_sf = NULL;
+ // For the exception check, stop working and count as time in
+ // runtime.
+ STOP_INTERVAL(w, INTERVAL_WORKING);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
+
START_INTERVAL(w, INTERVAL_THE_EXCEPTION_CHECK);
BEGIN_WITH_WORKER_LOCK(w) {
@@ -2410,6 +2434,11 @@ void __cilkrts_c_THE_exception_check(__cilkrts_worker *w,
else
{
NOTE_INTERVAL(w, INTERVAL_THE_EXCEPTION_CHECK_USELESS);
+
+ // If we fail the exception check and return, then switch back
+ // to working.
+ STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+ START_INTERVAL(w, INTERVAL_WORKING);
return;
}
}
@@ -2419,6 +2448,9 @@ NORETURN __cilkrts_exception_from_spawn(__cilkrts_worker *w,
__cilkrts_stack_frame *returning_sf)
{
full_frame *ff = w->l->frame_ff;
+ STOP_INTERVAL(w, INTERVAL_WORKING);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
+
// This is almost the same as THE_exception_check, except
// the detach didn't happen, we don't need to undo the tail
// update.
@@ -2551,6 +2583,10 @@ __cilkrts_stack_frame *simulate_pop_tail(__cilkrts_worker *w)
void __cilkrts_return(__cilkrts_worker *w)
{
full_frame *ff, *parent_ff;
+
+ // Count time during the return as in the runtime.
+ STOP_INTERVAL(w, INTERVAL_WORKING);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
START_INTERVAL(w, INTERVAL_RETURNING);
BEGIN_WITH_WORKER_LOCK_OPTIONAL(w) {
@@ -2604,6 +2640,8 @@ void __cilkrts_return(__cilkrts_worker *w)
} END_WITH_WORKER_LOCK_OPTIONAL(w);
STOP_INTERVAL(w, INTERVAL_RETURNING);
+ STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+ START_INTERVAL(w, INTERVAL_WORKING);
}
static void __cilkrts_unbind_thread()
@@ -2619,13 +2657,10 @@ static void __cilkrts_unbind_thread()
if (w) {
g = w->g;
- // If there's only 1 worker, the counts will be stopped in
- // __cilkrts_scheduler
- if (g->P > 1)
- {
- STOP_INTERVAL(w, INTERVAL_WORKING);
- STOP_INTERVAL(w, INTERVAL_IN_SCHEDULER);
- }
+
+ // Matches the START in bind_thread in cilk-abi.c.
+ STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+ STOP_INTERVAL(w, INTERVAL_IN_SCHEDULER);
__cilkrts_set_tls_worker(0);
@@ -2658,6 +2693,11 @@ void __cilkrts_c_return_from_initial(__cilkrts_worker *w)
{
struct cilkred_map *rm;
+ // When we are returning from the initial frame, switch from
+ // INTERVAL_WORKING into INTERVAL_IN_RUNTIME.
+ STOP_INTERVAL(w, INTERVAL_WORKING);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
+
/* This is only called on a user thread worker. */
CILK_ASSERT(w->l->type == WORKER_USER);
@@ -3629,6 +3669,11 @@ slow_path_reductions_for_spawn_return(__cilkrts_worker *w,
// We have reductions to execute (and we can't hold locks).
__cilkrts_frame_unlock(w, ff->parent);
+ // After we've released the lock, start counting time as
+ // WORKING again.
+ STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+ START_INTERVAL(w, INTERVAL_WORKING);
+
// Merge all reducers into the left map.
left_map = repeated_merge_reducer_maps(&w,
left_map,
@@ -3649,6 +3694,9 @@ slow_path_reductions_for_spawn_return(__cilkrts_worker *w,
ff->pending_exception = w->l->pending_exception;
w->l->pending_exception = NULL;
+ STOP_INTERVAL(w, INTERVAL_WORKING);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
+
// Lock ff->parent for the next loop around.
__cilkrts_frame_lock(w, ff->parent);
@@ -3809,6 +3857,11 @@ slow_path_reductions_for_sync(__cilkrts_worker *w,
return w;
}
} END_WITH_FRAME_LOCK(w, ff);
+
+ // After we've released the lock, start counting time as
+ // WORKING again.
+ STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+ START_INTERVAL(w, INTERVAL_WORKING);
// If we get here, we have a nontrivial reduction to execute.
middle_map = repeated_merge_reducer_maps(&w,
@@ -3816,6 +3869,9 @@ slow_path_reductions_for_sync(__cilkrts_worker *w,
middle_map);
verify_current_wkr(w);
+ STOP_INTERVAL(w, INTERVAL_WORKING);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
+
// Save any exceptions generated because of the reduction
// process. These get merged the next time around the
// loop.
diff --git a/libcilkrts/runtime/scheduler.h b/libcilkrts/runtime/scheduler.h
index 543adaf68e0..74c45096fca 100644
--- a/libcilkrts/runtime/scheduler.h
+++ b/libcilkrts/runtime/scheduler.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/signal_node.c b/libcilkrts/runtime/signal_node.c
index 92c404b482c..bdf820c7a8e 100644
--- a/libcilkrts/runtime/signal_node.c
+++ b/libcilkrts/runtime/signal_node.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2011-2013, Intel Corporation
+ * Copyright (C) 2011-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************/
diff --git a/libcilkrts/runtime/signal_node.h b/libcilkrts/runtime/signal_node.h
index 0a1fe200201..354b4ac7456 100644
--- a/libcilkrts/runtime/signal_node.h
+++ b/libcilkrts/runtime/signal_node.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/spin_mutex.c b/libcilkrts/runtime/spin_mutex.c
index 03908f26322..f9d8c47675a 100644
--- a/libcilkrts/runtime/spin_mutex.c
+++ b/libcilkrts/runtime/spin_mutex.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "spin_mutex.h"
diff --git a/libcilkrts/runtime/spin_mutex.h b/libcilkrts/runtime/spin_mutex.h
index b0045ab9313..d46b956f974 100644
--- a/libcilkrts/runtime/spin_mutex.h
+++ b/libcilkrts/runtime/spin_mutex.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/sslib/ignore_handler_s.c b/libcilkrts/runtime/sslib/ignore_handler_s.c
new file mode 100644
index 00000000000..54b65c9a23f
--- /dev/null
+++ b/libcilkrts/runtime/sslib/ignore_handler_s.c
@@ -0,0 +1,72 @@
+/*------------------------------------------------------------------
+ * ignore_handler_s.c
+ *
+ * 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
+ *
+ * Copyright (c) 2012 Cisco Systems
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#include "safeclib_private.h"
+
+/**
+ * NAME
+ * ignore_handler_s
+ *
+ * SYNOPSIS
+ * #include "safe_lib.h"
+ * void ignore_handler_s(const char *msg, void *ptr, errno_t error)
+ *
+ * DESCRIPTION
+ * This function simply returns to the caller.
+ *
+ * SPECIFIED IN
+ * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
+ * and system software interfaces, Extensions to the C Library,
+ * Part I: Bounds-checking interfaces
+ *
+ * INPUT PARAMETERS
+ * msg Pointer to the message describing the error
+ *
+ * ptr Pointer to aassociated data. Can be NULL.
+ *
+ * error The error code encountered.
+ *
+ * RETURN VALUE
+ * Returns no value.
+ *
+ * ALSO SEE
+ * abort_handler_s()
+ *
+ */
+
+void ignore_handler_s(const char *msg, void *ptr, errno_t error)
+{
+
+ sldebug_printf("IGNORE CONSTRAINT HANDLER: (%u) %s\n", error,
+ (msg) ? msg : "Null message");
+ return;
+}
+EXPORT_SYMBOL(ignore_handler_s);
diff --git a/libcilkrts/runtime/sslib/safe_lib.h b/libcilkrts/runtime/sslib/safe_lib.h
new file mode 100644
index 00000000000..9ffb24e72ab
--- /dev/null
+++ b/libcilkrts/runtime/sslib/safe_lib.h
@@ -0,0 +1,61 @@
+/*------------------------------------------------------------------
+ * safe_lib.h -- Safe C Library
+ *
+ * October 2008, Bo Berry
+ * Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
+ *
+ * Copyright (c) 2008-2013 by Cisco Systems, Inc
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#ifndef __SAFE_LIB_H__
+#define __SAFE_LIB_H__
+
+#include "safe_types.h"
+#include "safe_lib_errno.h"
+
+/* C11 appendix K types - specific for bounds checking */
+typedef size_t rsize_t;
+
+/*
+ * We depart from the standard and allow memory and string operations to
+ * have different max sizes. See the respective safe_mem_lib.h or
+ * safe_str_lib.h files.
+ */
+/* #define RSIZE_MAX (~(rsize_t)0) - leave here for completeness */
+
+typedef void (*constraint_handler_t) (const char * /* msg */,
+ void * /* ptr */,
+ errno_t /* error */);
+
+extern void abort_handler_s(const char *msg, void *ptr, errno_t error);
+extern void ignore_handler_s(const char *msg, void *ptr, errno_t error);
+
+#define sl_default_handler ignore_handler_s
+
+//#include "safe_mem_lib.h"
+#include "safe_str_lib.h"
+
+#endif /* __SAFE_LIB_H__ */
diff --git a/libcilkrts/runtime/sslib/safe_lib_errno.h b/libcilkrts/runtime/sslib/safe_lib_errno.h
new file mode 100644
index 00000000000..8f27111c353
--- /dev/null
+++ b/libcilkrts/runtime/sslib/safe_lib_errno.h
@@ -0,0 +1,100 @@
+/*------------------------------------------------------------------
+ * safe_lib_errno.h -- Safe C Lib Error codes
+ *
+ * October 2008, Bo Berry
+ * Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
+ *
+ * Copyright (c) 2008-2013 by Cisco Systems, Inc
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#ifndef __SAFE_LIB_ERRNO_H__
+#define __SAFE_LIB_ERRNO_H__
+
+#ifdef __KERNEL__
+# include <linux/errno.h>
+#else
+#include <errno.h>
+#endif /* __KERNEL__ */
+
+/*
+ * Safe Lib specific errno codes. These can be added to the errno.h file
+ * if desired.
+ */
+#ifndef ESNULLP
+#define ESNULLP ( 400 ) /* null ptr */
+#endif
+
+#ifndef ESZEROL
+#define ESZEROL ( 401 ) /* length is zero */
+#endif
+
+#ifndef ESLEMIN
+#define ESLEMIN ( 402 ) /* length is below min */
+#endif
+
+#ifndef ESLEMAX
+#define ESLEMAX ( 403 ) /* length exceeds max */
+#endif
+
+#ifndef ESOVRLP
+#define ESOVRLP ( 404 ) /* overlap undefined */
+#endif
+
+#ifndef ESEMPTY
+#define ESEMPTY ( 405 ) /* empty string */
+#endif
+
+#ifndef ESNOSPC
+#define ESNOSPC ( 406 ) /* not enough space for s2 */
+#endif
+
+#ifndef ESUNTERM
+#define ESUNTERM ( 407 ) /* unterminated string */
+#endif
+
+#ifndef ESNODIFF
+#define ESNODIFF ( 408 ) /* no difference */
+#endif
+
+#ifndef ESNOTFND
+#define ESNOTFND ( 409 ) /* not found */
+#endif
+
+/* Additional for safe snprintf_s interfaces */
+#ifndef ESBADFMT
+#define ESBADFMT ( 410 ) /* bad format string */
+#endif
+
+#ifndef ESFMTTYP
+#define ESFMTTYP ( 411 ) /* bad format type */
+#endif
+
+/* EOK may or may not be defined in errno.h */
+#ifndef EOK
+#define EOK ( 0 )
+#endif
+
+#endif /* __SAFE_LIB_ERRNO_H__ */
diff --git a/libcilkrts/runtime/sslib/safe_str_constraint.c b/libcilkrts/runtime/sslib/safe_str_constraint.c
new file mode 100644
index 00000000000..17e7fbbb4d2
--- /dev/null
+++ b/libcilkrts/runtime/sslib/safe_str_constraint.c
@@ -0,0 +1,146 @@
+/*------------------------------------------------------------------
+ * safe_str_constraint.c
+ *
+ * October 2008, Bo Berry
+ * 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
+ *
+ * Copyright (c) 2008, 2009, 2012 Cisco Systems
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#include "safeclib_private.h"
+#include "safe_str_constraint.h"
+#include "safe_str_lib.h"
+
+
+static constraint_handler_t str_handler = NULL;
+
+
+/**
+ * NAME
+ * set_str_constraint_handler_s
+ *
+ * SYNOPSIS
+ * #include "safe_str_lib.h"
+ * constraint_handler_t
+ * set_str_constraint_handler_s(constraint_handler_t handler)
+ *
+ * DESCRIPTION
+ * The set_str_constraint_handler_s function sets the runtime-constraint
+ * handler to be handler. The runtime-constraint handler is the function to
+ * be called when a library function detects a runtime-constraint
+ * violation. Only the most recent handler registered with
+ * set_str_constraint_handler_s is called when a runtime-constraint
+ * violation occurs.
+ * When the handler is called, it is passed the following arguments in
+ * the following order:
+ * 1. A pointer to a character string describing the
+ * runtime-constraint violation.
+ * 2. A null pointer or a pointer to an implementation defined
+ * object.
+ * 3. If the function calling the handler has a return type declared
+ * as errno_t, the return value of the function is passed.
+ * Otherwise, a positive value of type errno_t is passed.
+ * The implementation has a default constraint handler that is used if no
+ * calls to the set_constraint_handler_s function have been made. The
+ * behavior of the default handler is implementation-defined, and it may
+ * cause the program to exit or abort. If the handler argument to
+ * set_constraint_handler_s is a null pointer, the implementation default
+ * handler becomes the current constraint handler.
+ *
+ * SPECIFIED IN
+ * ISO/IEC JTC1 SC22 WG14 N1172, Programming languages, environments
+ * and system software interfaces, Extensions to the C Library,
+ * Part I: Bounds-checking interfaces
+ *
+ * INPUT PARAMETERS
+ * *msg Pointer to the message describing the error
+ *
+ * *ptr Pointer to aassociated data. Can be NULL.
+ *
+ * error The error code encountered.
+ *
+ * OUTPUT PARAMETERS
+ * none
+ *
+ * RETURN VALUE
+ * none
+ *
+ * ALSO SEE
+ * set_str_constraint_handler_s()
+ */
+constraint_handler_t
+set_str_constraint_handler_s (constraint_handler_t handler)
+{
+ constraint_handler_t prev_handler = str_handler;
+ if (NULL == handler) {
+ str_handler = sl_default_handler;
+ } else {
+ str_handler = handler;
+ }
+ return prev_handler;
+}
+EXPORT_SYMBOL(set_str_constraint_handler_s);
+
+
+/**
+ * NAME
+ * invoke_safe_str_constraint_handler
+ *
+ * SYNOPSIS
+ * #include "safe_str_constraint.h"
+ * void
+ * invoke_safe_str_constraint_handler (const char *msg,
+ * void *ptr,
+ * errno_t error)
+ *
+ * DESCRIPTION
+ * Invokes the currently set constraint handler or the default.
+ *
+ * INPUT PARAMETERS
+ * *msg Pointer to the message describing the error
+ *
+ * *ptr Pointer to aassociated data. Can be NULL.
+ *
+ * error The error code encountered.
+ *
+ * OUTPUT PARAMETERS
+ * none
+ *
+ * RETURN VALUE
+ * none
+ *
+ */
+void
+invoke_safe_str_constraint_handler (const char *msg,
+ void *ptr,
+ errno_t error)
+{
+ if (NULL != str_handler) {
+ str_handler(msg, ptr, error);
+ } else {
+ sl_default_handler(msg, ptr, error);
+ }
+}
diff --git a/libcilkrts/runtime/sslib/safe_str_constraint.h b/libcilkrts/runtime/sslib/safe_str_constraint.h
new file mode 100644
index 00000000000..a1fba3e7e85
--- /dev/null
+++ b/libcilkrts/runtime/sslib/safe_str_constraint.h
@@ -0,0 +1,78 @@
+/*------------------------------------------------------------------
+ * safe_str_constraint.h
+ *
+ * October 2008, Bo Berry
+ *
+ * Copyright (c) 2008-2011 Cisco Systems
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#ifndef __SAFE_STR_CONSTRAINT_H__
+#define __SAFE_STR_CONSTRAINT_H__
+
+#include "safeclib_private.h"
+
+/*
+ * Function used by the libraries to invoke the registered
+ * runtime-constraint handler. Always needed.
+ */
+extern void invoke_safe_str_constraint_handler(
+ const char *msg,
+ void *ptr,
+ errno_t error);
+
+
+/*
+ * Safe C Lib internal string routine to consolidate error handling
+ */
+static inline void handle_error(char *orig_dest, rsize_t orig_dmax,
+ char *err_msg, errno_t err_code)
+{
+#ifdef SAFECLIB_STR_NULL_SLACK
+ /* null string to eliminate partial copy */
+ while (orig_dmax) { *orig_dest = '\0'; orig_dmax--; orig_dest++; }
+#else
+ *orig_dest = '\0';
+#endif
+
+ invoke_safe_str_constraint_handler(err_msg, NULL, err_code);
+ return;
+}
+
+static inline void handle_wc_error(wchar_t *orig_dest, rsize_t orig_dmax,
+ char *err_msg, errno_t err_code)
+{
+#ifdef SAFECLIB_STR_NULL_SLACK
+ /* null string to eliminate partial copy */
+ while (orig_dmax) { *orig_dest = L'\0'; orig_dmax--; orig_dest++; }
+#else
+ *orig_dest = L'\0';
+#endif
+
+ invoke_safe_str_constraint_handler(err_msg, NULL, err_code);
+ return;
+}
+
+#endif /* __SAFE_STR_CONSTRAINT_H__ */
diff --git a/libcilkrts/runtime/sslib/safe_str_lib.h b/libcilkrts/runtime/sslib/safe_str_lib.h
new file mode 100644
index 00000000000..3bc841ea551
--- /dev/null
+++ b/libcilkrts/runtime/sslib/safe_str_lib.h
@@ -0,0 +1,70 @@
+/*------------------------------------------------------------------
+ * safe_str_lib.h -- Safe C Library String APIs
+ *
+ * October 2008, Bo Berry
+ *
+ * Copyright (c) 2008-2011, 2013 by Cisco Systems, Inc.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#ifndef __SAFE_STR_LIB_H__
+#define __SAFE_STR_LIB_H__
+
+#include "safe_lib.h"
+
+/*
+ * The shortest string is a null string!!
+ */
+#define RSIZE_MIN_STR ( 1 )
+
+/* maximum sring length */
+#define RSIZE_MAX_STR ( 4UL << 10 ) /* 4KB */
+
+
+/* The makeup of a password */
+#define SAFE_STR_MIN_LOWERCASE ( 2 )
+#define SAFE_STR_MIN_UPPERCASE ( 2 )
+#define SAFE_STR_MIN_NUMBERS ( 1 )
+#define SAFE_STR_MIN_SPECIALS ( 1 )
+
+#define SAFE_STR_PASSWORD_MIN_LENGTH ( 6 )
+#define SAFE_STR_PASSWORD_MAX_LENGTH ( 32 )
+
+
+/* set string constraint handler */
+extern constraint_handler_t
+set_str_constraint_handler_s(constraint_handler_t handler);
+
+
+/* string copy */
+extern errno_t
+strcpy_s(char *dest, rsize_t dmax, const char *src);
+
+/* string length */
+extern rsize_t
+strnlen_s (const char *s, rsize_t smax);
+
+
+#endif /* __SAFE_STR_LIB_H__ */
diff --git a/libcilkrts/runtime/sslib/safe_types.h b/libcilkrts/runtime/sslib/safe_types.h
new file mode 100644
index 00000000000..5c2df9c6128
--- /dev/null
+++ b/libcilkrts/runtime/sslib/safe_types.h
@@ -0,0 +1,61 @@
+/*------------------------------------------------------------------
+ * safe_types.h - C99 std types & defs or Linux kernel equivalents
+ *
+ * March 2007, Bo Berry
+ * Modified 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
+ *
+ * Copyright (c) 2007-2013 by Cisco Systems, Inc
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#ifndef __SAFE_TYPES_H__
+#define __SAFE_TYPES_H__
+
+#ifdef __KERNEL__
+/* linux kernel environment */
+
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+
+/* errno_t isn't defined in the kernel */
+typedef int errno_t;
+
+#else
+
+#include <stdio.h>
+#include <sys/types.h>
+#ifndef _WRS_KERNEL
+#include <inttypes.h>
+#endif
+#include <stdint.h>
+#include <errno.h>
+
+typedef int errno_t;
+
+#include <stdbool.h>
+
+#endif /* __KERNEL__ */
+#endif /* __SAFE_TYPES_H__ */
diff --git a/libcilkrts/runtime/sslib/safeclib_private.h b/libcilkrts/runtime/sslib/safeclib_private.h
new file mode 100644
index 00000000000..7280e879a8e
--- /dev/null
+++ b/libcilkrts/runtime/sslib/safeclib_private.h
@@ -0,0 +1,93 @@
+/*------------------------------------------------------------------
+ * safeclib_private.h - Internal library references
+ *
+ * 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
+ *
+ * Copyright (c) 2012, 2013 by Cisco Systems, Inc
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#ifndef __SAFECLIB_PRIVATE_H__
+#define __SAFECLIB_PRIVATE_H__
+
+#ifdef __KERNEL__
+/* linux kernel environment */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ctype.h>
+
+#define RCNEGATE(x) ( -(x) )
+
+#define slprintf(...) printk(KERN_EMERG __VA_ARGS__)
+#define slabort()
+#ifdef DEBUG
+#define sldebug_printf(...) printk(KERN_DEBUG __VA_ARGS__)
+#endif
+
+#else /* !__KERNEL__ */
+
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <ctype.h>
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
+# include <memory.h>
+# endif
+# include <string.h>
+#endif
+#ifdef HAVE_LIMITS_H
+# include <limits.h>
+#endif
+
+#define EXPORT_SYMBOL(sym)
+#define RCNEGATE(x) (x)
+
+#define slprintf(...) fprintf(stderr, __VA_ARGS__)
+#define slabort() abort()
+#ifdef DEBUG
+#define sldebug_printf(...) printf(__VA_ARGS__)
+#endif
+
+#endif /* __KERNEL__ */
+
+#ifndef sldebug_printf
+#define sldebug_printf(...)
+#endif
+
+#include "safe_lib.h"
+
+#endif /* __SAFECLIB_PRIVATE_H__ */
diff --git a/libcilkrts/runtime/sslib/snprintf_s.h b/libcilkrts/runtime/sslib/snprintf_s.h
new file mode 100644
index 00000000000..b4abb8652c1
--- /dev/null
+++ b/libcilkrts/runtime/sslib/snprintf_s.h
@@ -0,0 +1,49 @@
+/*------------------------------------------------------------------
+ * sprintf_s.h -- Safe Sprintf Interfaces
+ *
+ * August 2014, D Wheeler
+ *
+ * Copyright (c) 2014 by Intel Corp
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+#ifndef SPRINTF_S_H_
+#define SPRINTF_S_H_
+
+#include <safe_lib_errno.h>
+
+
+#define SNPRFNEGATE(x) (-1*(x))
+
+
+
+int snprintf_s_s(char *dest, rsize_t dmax, const char *format, char *s);
+int snprintf_s_i(char *dest, rsize_t dmax, const char *format, int a);
+int snprintf_s_si(char *dest, rsize_t dmax, const char *format, char *s, int a);
+int snprintf_s_l(char *dest, rsize_t dmax, const char *format, long a);
+int snprintf_s_sl(char *dest, rsize_t dmax, const char *format, char *s, long a);
+
+
+
+#endif /* SPRINTF_S_H_ */
diff --git a/libcilkrts/runtime/sslib/snprintf_support.c b/libcilkrts/runtime/sslib/snprintf_support.c
new file mode 100644
index 00000000000..5ee0e3dd36b
--- /dev/null
+++ b/libcilkrts/runtime/sslib/snprintf_support.c
@@ -0,0 +1,353 @@
+/*------------------------------------------------------------------
+ * snprintf_support.c
+ *
+ * August 2014, D Wheeler
+ *
+ * Copyright (c) 2014 by Intel Corp
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+#include "safeclib_private.h"
+#include "safe_str_constraint.h"
+#include "safe_str_lib.h"
+#include "snprintf_s.h"
+
+#define FMT_CHAR 'c'
+#define FMT_WCHAR 'C'
+#define FMT_SHORT 'h'
+#define FMT_INT 'd'
+#define FMT_LONG 'l'
+#define FMT_STRING 's'
+#define FMT_WSTRING 'S'
+#define FMT_DOUBLE 'g'
+#define FMT_LDOUBLE 'G'
+#define FMT_VOID 'p'
+#define FMT_PCHAR '1'
+#define FMT_PSHORT '2'
+#define FMT_PINT '3'
+#define FMT_PLONG '4'
+
+
+
+#define MAX_FORMAT_ELEMENTS 16
+
+#define CHK_FORMAT(X,Y) (((X)==(Y))?1:0)
+
+
+unsigned int
+parse_format(const char *format, char pformatList[], unsigned int maxFormats)
+{
+ unsigned int numFormats = 0;
+ unsigned int index = 0;
+ unsigned int start = 0;
+ char lmod = 0;
+
+ while (index < RSIZE_MAX_STR && format[index] != '\0' && numFormats < maxFormats)
+ {
+ if (format[index] == '%') {
+ start = index; // remember where the format string started
+ // Check for flags
+ switch( format[++index]) {
+ case '\0': continue; // skip - end of format string
+ case '%' : continue; // skip - actually a percent character
+ case '#' : // convert to alternate form
+ case '0' : // zero pad
+ case '-' : // left adjust
+ case ' ' : // pad with spaces
+ case '+' : // force a sign be used
+ index++; // skip the flag character
+ break;
+ }
+ // check for and skip the optional field width
+ while ( format[index] != '\0' && format[index] >= '0' && format[index] <= '9') {
+ index++;
+ }
+ // Check for an skip the optional precision
+ if ( format[index] != '\0' && format[index] == '.') {
+ index++; // skip the period
+ while ( format[index] != '\0' && format[index] >= '0' && format[index] <= '9') {
+ index++;
+ }
+ }
+ // Check for and skip the optional length modifiers
+ lmod = ' ';
+ switch( format[index]) {
+ case 'h' : if ( format[++index] == 'h') {
+ ++index; //also recognize the 'hh' modifier
+ lmod = 'H'; // for char
+ } else {
+ lmod = 'h'; // for short
+ }
+ break;
+ case 'l' : if ( format[++index] == 'l') {
+ ++index; //also recognize the 'll' modifier
+ lmod = 'd'; // for long long
+ } else {
+ lmod = 'l'; // for long
+ }
+ break;
+ case 'L' : lmod = 'L'; break;
+ case 'j' :
+ case 'z' :
+ case 't' : index++;
+ break;
+ }
+
+ // Recognize and record the actual modifier
+ switch( format[index]) {
+ case 'c' :
+ if ( lmod == 'l') {
+ pformatList[numFormats] = FMT_WCHAR; // store the format character
+ } else {
+ pformatList[numFormats] = FMT_CHAR;
+ }
+ numFormats++;
+ index++; // skip the format character
+ break;
+
+ case 'd' : case 'i' : // signed
+ case 'o' : case 'u' : // unsigned
+ case 'x' : case 'X' : // unsigned
+ if ( lmod == 'H') {
+ pformatList[numFormats] = FMT_CHAR; // store the format character
+ } else if ( lmod == 'l') {
+ pformatList[numFormats] = FMT_LONG; // store the format character
+ } else if ( lmod == 'h') {
+ pformatList[numFormats] = FMT_SHORT; // store the format character
+ } else{
+ pformatList[numFormats] = FMT_INT;
+ }
+ numFormats++;
+ index++; // skip the format character
+ break;
+
+ case 'e' : case 'E' :
+ case 'f' : case 'F' :
+ case 'g' : case 'G' :
+ case 'a' : case 'A' :
+ if ( lmod == 'L') {
+ pformatList[numFormats] = FMT_LDOUBLE; // store the format character
+ } else{
+ pformatList[numFormats] = FMT_DOUBLE;
+ }
+ numFormats++;
+ index++; // skip the format character
+ break;
+
+ case 's' :
+ if ( lmod == 'l' || lmod == 'L') {
+ pformatList[numFormats] = FMT_WSTRING; // store the format character
+ } else {
+ pformatList[numFormats] = FMT_STRING;
+ }
+ numFormats++;
+ index++; // skip the format character
+ break;
+
+ case 'p' :
+ pformatList[numFormats] = FMT_VOID;
+ numFormats++;
+ index++; // skip the format character
+ break;
+
+ case 'n' :
+ if ( lmod == 'H') {
+ pformatList[numFormats] = FMT_PCHAR; // store the format character
+ } else if ( lmod == 'l') {
+ pformatList[numFormats] = FMT_PLONG; // store the format character
+ } else if ( lmod == 'h') {
+ pformatList[numFormats] = FMT_PSHORT; // store the format character
+ } else{
+ pformatList[numFormats] = FMT_PINT;
+ }
+ numFormats++;
+ index++; // skip the format character
+ break;
+ case 'm' :
+ // Does not represent an argument in the call stack
+ index++; // skip the format character
+ continue;
+ default:
+ printf("failed to recognize format string [");
+ for (;start<index; start++) { printf("%c", format[start]); }
+ puts("]");
+ break;
+ }
+ }
+ if (format[index] != '%')
+ // don't know why it skips over blindly, not handling cases such as "%s%d".
+ index++; // move past this character
+ }
+
+ return numFormats;
+}
+
+unsigned int
+check_integer_format(const char format)
+{
+ unsigned int retValue = 0; // default failure
+ switch( format) {
+ case FMT_CHAR :
+ case FMT_SHORT :
+ case FMT_INT :
+ retValue = 1;
+ break;
+ }
+ return retValue;
+}
+
+
+
+inline int snprintf_s_i(char *dest, rsize_t dmax, const char *format, int a)
+{
+ char pformatList[MAX_FORMAT_ELEMENTS];
+ unsigned int index = 0;
+
+ // Determine the number of format options in the format string
+ unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
+
+ // Check that there are not too many format options
+ if ( nfo != 1 ) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESBADFMT);
+ }
+ // Check that the format is for an integer type
+ if ( check_integer_format(pformatList[index]) == 0) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESFMTTYP);
+ }
+ index++;
+
+ return snprintf(dest, dmax, format, a);
+}
+
+
+
+inline int snprintf_s_l(char *dest, rsize_t dmax, const char *format, long a)
+{
+ char pformatList[MAX_FORMAT_ELEMENTS];
+ unsigned int index = 0;
+
+ // Determine the number of format options in the format string
+ unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
+
+ // Check that there are not too many format options
+ if ( nfo != 1 ) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESBADFMT);
+ }
+ // Check that the format is for an long type
+ if ( CHK_FORMAT(FMT_LONG, pformatList[index]) == 0) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESFMTTYP);
+ }
+ index++;
+
+ return snprintf(dest, dmax, format, a);
+}
+
+
+inline int snprintf_s_si(char *dest, rsize_t dmax, const char *format, char *s, int a)
+{
+ char pformatList[MAX_FORMAT_ELEMENTS];
+ unsigned int index = 0;
+
+ // Determine the number of format options in the format string
+ unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
+
+ // Check that there are not too many format options
+ if ( nfo != 2 ) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESBADFMT);
+ }
+ // Check first format is of string type
+ if ( CHK_FORMAT(FMT_STRING, pformatList[index]) == 0) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESFMTTYP);
+ }
+ index++;
+
+ // Check that the format is for an integer type
+ if ( check_integer_format(pformatList[index]) == 0) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESFMTTYP);
+ }
+ index++;
+
+ return snprintf(dest, dmax, format, s, a);
+}
+
+
+inline int snprintf_s_sl(char *dest, rsize_t dmax, const char *format, char *s, long a)
+{
+ char pformatList[MAX_FORMAT_ELEMENTS];
+ unsigned int index = 0;
+
+ // Determine the number of format options in the format string
+ unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
+
+ // Check that there are not too many format options
+ if ( nfo != 2 ) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESBADFMT);
+ }
+ // Check first format is of string type
+ if ( CHK_FORMAT(FMT_STRING, pformatList[index]) == 0) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESFMTTYP);
+ }
+ index++;
+
+ // Check that the format is for an integer type
+ if ( CHK_FORMAT(FMT_LONG, pformatList[index]) == 0) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESFMTTYP);
+ }
+ index++;
+
+ return snprintf(dest, dmax, format, s, a);
+}
+
+inline int snprintf_s_s(char *dest, rsize_t dmax, const char *format, char *s)
+{
+ char pformatList[MAX_FORMAT_ELEMENTS];
+ unsigned int index = 0;
+
+ // Determine the number of format options in the format string
+ unsigned int nfo = parse_format(format, &pformatList[0], MAX_FORMAT_ELEMENTS);
+
+ // Check that there are not too many format options
+ if ( nfo != 1 ) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESBADFMT);
+ }
+ // Check first format is of string type
+ if ( CHK_FORMAT(FMT_STRING, pformatList[index]) == 0) {
+ dest[0] = '\0';
+ return SNPRFNEGATE(ESFMTTYP);
+ }
+ index++;
+
+ return snprintf(dest, dmax, format, s);
+}
diff --git a/libcilkrts/runtime/sslib/strcpy_s.c b/libcilkrts/runtime/sslib/strcpy_s.c
new file mode 100644
index 00000000000..a0cbd6dc930
--- /dev/null
+++ b/libcilkrts/runtime/sslib/strcpy_s.c
@@ -0,0 +1,198 @@
+/*------------------------------------------------------------------
+ * strcpy_s.c
+ *
+ * October 2008, Bo Berry
+ *
+ * Copyright (c) 2008-2011 by Cisco Systems, Inc
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#include "safeclib_private.h"
+#include "safe_str_constraint.h"
+#include "safe_str_lib.h"
+
+
+/**
+ * NAME
+ * strcpy_s
+ *
+ * SYNOPSIS
+ * #include "safe_str_lib.h"
+ * errno_t
+ * strcpy_s(char *dest, rsize_t dmax, const char *src)
+ *
+ * DESCRIPTION
+ * The strcpy_s function copies the string pointed to by src
+ * (including the terminating null character) into the array
+ * pointed to by dest. All elements following the terminating
+ * null character (if any) written by strcpy_s in the array
+ * of dmax characters pointed to by dest are nulled when
+ * strcpy_s returns.
+ *
+ * SPECIFIED IN
+ * ISO/IEC TR 24731, Programming languages, environments
+ * and system software interfaces, Extensions to the C Library,
+ * Part I: Bounds-checking interfaces
+ *
+ * INPUT PARAMETERS
+ * dest pointer to string that will be replaced by src.
+ *
+ * dmax restricted maximum length of dest
+ *
+ * src pointer to the string that will be copied
+ * to dest
+ *
+ * OUTPUT PARAMETERS
+ * dest updated
+ *
+ * RUNTIME CONSTRAINTS
+ * Neither dest nor src shall be a null pointer.
+ * dmax shall not be greater than RSIZE_MAX_STR.
+ * dmax shall not equal zero.
+ * dmax shall be greater than strnlen_s(src, dmax).
+ * Copying shall not take place between objects that overlap.
+ * If there is a runtime-constraint violation, then if dest
+ * is not a null pointer and destmax is greater than zero and
+ * not greater than RSIZE_MAX_STR, then strcpy_s nulls dest.
+ *
+ * RETURN VALUE
+ * EOK successful operation, the characters in src were
+ * copied into dest and the result is null terminated.
+ * ESNULLP NULL pointer
+ * ESZEROL zero length
+ * ESLEMAX length exceeds max limit
+ * ESOVRLP strings overlap
+ * ESNOSPC not enough space to copy src
+ *
+ * ALSO SEE
+ * strcat_s(), strncat_s(), strncpy_s()
+ *
+ */
+errno_t
+strcpy_s (char *dest, rsize_t dmax, const char *src)
+{
+ rsize_t orig_dmax;
+ char *orig_dest;
+ const char *overlap_bumper;
+
+ if (dest == NULL) {
+ invoke_safe_str_constraint_handler("strcpy_s: dest is null",
+ NULL, ESNULLP);
+ return RCNEGATE(ESNULLP);
+ }
+
+ if (dmax == 0) {
+ invoke_safe_str_constraint_handler("strcpy_s: dmax is 0",
+ NULL, ESZEROL);
+ return RCNEGATE(ESZEROL);
+ }
+
+ if (dmax > RSIZE_MAX_STR) {
+ invoke_safe_str_constraint_handler("strcpy_s: dmax exceeds max",
+ NULL, ESLEMAX);
+ return RCNEGATE(ESLEMAX);
+ }
+
+ if (src == NULL) {
+#ifdef SAFECLIB_STR_NULL_SLACK
+ /* null string to clear data */
+ while (dmax) { *dest = '\0'; dmax--; dest++; }
+#else
+ *dest = '\0';
+#endif
+ invoke_safe_str_constraint_handler("strcpy_s: src is null",
+ NULL, ESNULLP);
+ return RCNEGATE(ESNULLP);
+ }
+
+ if (dest == src) {
+ return RCNEGATE(EOK);
+ }
+
+ /* hold base of dest in case src was not copied */
+ orig_dmax = dmax;
+ orig_dest = dest;
+
+ if (dest < src) {
+ overlap_bumper = src;
+
+ while (dmax > 0) {
+ if (dest == overlap_bumper) {
+ handle_error(orig_dest, orig_dmax, "strcpy_s: "
+ "overlapping objects",
+ ESOVRLP);
+ return RCNEGATE(ESOVRLP);
+ }
+
+ *dest = *src;
+ if (*dest == '\0') {
+#ifdef SAFECLIB_STR_NULL_SLACK
+ /* null slack to clear any data */
+ while (dmax) { *dest = '\0'; dmax--; dest++; }
+#endif
+ return RCNEGATE(EOK);
+ }
+
+ dmax--;
+ dest++;
+ src++;
+ }
+
+ } else {
+ overlap_bumper = dest;
+
+ while (dmax > 0) {
+ if (src == overlap_bumper) {
+ handle_error(orig_dest, orig_dmax, "strcpy_s: "
+ "overlapping objects",
+ ESOVRLP);
+ return RCNEGATE(ESOVRLP);
+ }
+
+ *dest = *src;
+ if (*dest == '\0') {
+#ifdef SAFECLIB_STR_NULL_SLACK
+ /* null slack to clear any data */
+ while (dmax) { *dest = '\0'; dmax--; dest++; }
+#endif
+ return RCNEGATE(EOK);
+ }
+
+ dmax--;
+ dest++;
+ src++;
+ }
+ }
+
+ /*
+ * the entire src must have been copied, if not reset dest
+ * to null the string.
+ */
+ handle_error(orig_dest, orig_dmax, "strcpy_s: not "
+ "enough space for src",
+ ESNOSPC);
+ return RCNEGATE(ESNOSPC);
+}
+EXPORT_SYMBOL(strcpy_s);
diff --git a/libcilkrts/runtime/sslib/strncpy_s.c b/libcilkrts/runtime/sslib/strncpy_s.c
new file mode 100644
index 00000000000..e1cdd6b1721
--- /dev/null
+++ b/libcilkrts/runtime/sslib/strncpy_s.c
@@ -0,0 +1,238 @@
+/*------------------------------------------------------------------
+ * strncpy_s.c
+ *
+ * October 2008, Bo Berry
+ *
+ * Copyright (c) 2008-2011 by Cisco Systems, Inc
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#include "safeclib_private.h"
+#include "safe_str_constraint.h"
+#include "safe_str_lib.h"
+
+
+/*
+ * NAME
+ * strncpy_s
+ *
+ * SYNOPSIS
+ * #include "safe_str_lib.h"
+ * errno_t
+ * strncpy_s(char *dest, rsize_t dmax, const char *src, rsize_t slen)
+ *
+ * DESCRIPTION
+ * The strncpy_s function copies not more than slen successive characters
+ * (characters that follow a null character are not copied) from the
+ * array pointed to by src to the array pointed to by dest. If no null
+ * character was copied from src, then dest[n] is set to a null character.
+ *
+ * All elements following the terminating null character (if any)
+ * written by strncpy_s in the array of dmax characters pointed to
+ * by dest take on the null value when strncpy_s returns.
+ *
+ * Specicified in:
+ * ISO/IEC TR 24731-1, Programming languages, environments
+ * and system software interfaces, Extensions to the C Library,
+ * Part I: Bounds-checking interfaces
+ *
+ * INPUT PARAMETERS
+ * dest pointer to string that will be replaced by src.
+ * The resulting string is null terminated.
+ *
+ * dmax restricted maximum length of the resulting dest,
+ * including the null
+ *
+ * src pointer to the string that will be copied
+ * to string dest
+ *
+ * slen the maximum number of characters to copy from src
+ *
+ * OUTPUT PARAMETERS
+ * dest updated with src string
+ *
+ * RUNTIME CONSTRAINTS
+ * Neither dmax nor slen shall be equal to zero.
+ * Neither dmax nor slen shall be equal zero.
+ * Neither dmax nor slen shall be greater than RSIZE_MAX_STR.
+ * If slen is either greater than or equal to dmax, then dmax
+ * should be more than strnlen_s(src,dmax)
+ * Copying shall not take place between objects that overlap.
+ * If there is a runtime-constraint violation, then if dest
+ * is not a null pointer and dmax greater than RSIZE_MAX_STR,
+ * then strncpy_s nulls dest.
+ *
+ * RETURN VALUE
+ * EOK successful operation, the characters in src were copied
+ * to dest and the result is null terminated.
+ * ESNULLP NULL pointer
+ * ESZEROL zero length
+ * ESLEMAX length exceeds max limit
+ * ESOVRLP strings overlap
+ * ESNOSPC not enough space to copy src
+ *
+ * ALSO SEE
+ * strcat_s(), strncat_s(), strcpy_s()
+ *-
+ */
+errno_t
+strncpy_s (char *dest, rsize_t dmax, const char *src, rsize_t slen)
+{
+ rsize_t orig_dmax;
+ char *orig_dest;
+ const char *overlap_bumper;
+
+ if (dest == NULL) {
+ invoke_safe_str_constraint_handler("strncpy_s: dest is null",
+ NULL, ESNULLP);
+ return RCNEGATE(ESNULLP);
+ }
+
+ if (dmax == 0) {
+ invoke_safe_str_constraint_handler("strncpy_s: dmax is 0",
+ NULL, ESZEROL);
+ return RCNEGATE(ESZEROL);
+ }
+
+ if (dmax > RSIZE_MAX_STR) {
+ invoke_safe_str_constraint_handler("strncpy_s: dmax exceeds max",
+ NULL, ESLEMAX);
+ return RCNEGATE(ESLEMAX);
+ }
+
+ /* hold base in case src was not copied */
+ orig_dmax = dmax;
+ orig_dest = dest;
+
+ if (src == NULL) {
+ handle_error(orig_dest, orig_dmax, "strncpy_s: "
+ "src is null",
+ ESNULLP);
+ return RCNEGATE(ESNULLP);
+ }
+
+ if (slen == 0) {
+ handle_error(orig_dest, orig_dmax, "strncpy_s: "
+ "slen is zero",
+ ESZEROL);
+ return RCNEGATE(ESZEROL);
+ }
+
+ if (slen > RSIZE_MAX_STR) {
+ handle_error(orig_dest, orig_dmax, "strncpy_s: "
+ "slen exceeds max",
+ ESLEMAX);
+ return RCNEGATE(ESLEMAX);
+ }
+
+
+ if (dest < src) {
+ overlap_bumper = src;
+
+ while (dmax > 0) {
+ if (dest == overlap_bumper) {
+ handle_error(orig_dest, orig_dmax, "strncpy_s: "
+ "overlapping objects",
+ ESOVRLP);
+ return RCNEGATE(ESOVRLP);
+ }
+
+ if (slen == 0) {
+ /*
+ * Copying truncated to slen chars. Note that the TR says to
+ * copy slen chars plus the null char. We null the slack.
+ */
+#ifdef SAFECLIB_STR_NULL_SLACK
+ while (dmax) { *dest = '\0'; dmax--; dest++; }
+#else
+ *dest = '\0';
+#endif
+ return RCNEGATE(EOK);
+ }
+
+ *dest = *src;
+ if (*dest == '\0') {
+#ifdef SAFECLIB_STR_NULL_SLACK
+ /* null slack */
+ while (dmax) { *dest = '\0'; dmax--; dest++; }
+#endif
+ return RCNEGATE(EOK);
+ }
+
+ dmax--;
+ slen--;
+ dest++;
+ src++;
+ }
+
+ } else {
+ overlap_bumper = dest;
+
+ while (dmax > 0) {
+ if (src == overlap_bumper) {
+ handle_error(orig_dest, orig_dmax, "strncpy_s: "
+ "overlapping objects",
+ ESOVRLP);
+ return RCNEGATE(ESOVRLP);
+ }
+
+ if (slen == 0) {
+ /*
+ * Copying truncated to slen chars. Note that the TR says to
+ * copy slen chars plus the null char. We null the slack.
+ */
+#ifdef SAFECLIB_STR_NULL_SLACK
+ while (dmax) { *dest = '\0'; dmax--; dest++; }
+#else
+ *dest = '\0';
+#endif
+ return RCNEGATE(EOK);
+ }
+
+ *dest = *src;
+ if (*dest == '\0') {
+#ifdef SAFECLIB_STR_NULL_SLACK
+ /* null slack */
+ while (dmax) { *dest = '\0'; dmax--; dest++; }
+#endif
+ return RCNEGATE(EOK);
+ }
+
+ dmax--;
+ slen--;
+ dest++;
+ src++;
+ }
+ }
+
+ /*
+ * the entire src was not copied, so zero the string
+ */
+ handle_error(orig_dest, orig_dmax, "strncpy_s: not enough "
+ "space for src",
+ ESNOSPC);
+ return RCNEGATE(ESNOSPC);
+}
+EXPORT_SYMBOL(strncpy_s);
diff --git a/libcilkrts/runtime/sslib/strnlen_s.c b/libcilkrts/runtime/sslib/strnlen_s.c
new file mode 100644
index 00000000000..e3cab9a6428
--- /dev/null
+++ b/libcilkrts/runtime/sslib/strnlen_s.c
@@ -0,0 +1,112 @@
+/*------------------------------------------------------------------
+ * strnlen_s.c
+ *
+ * October 2008, Bo Berry
+ *
+ * Copyright (c) 2008-2011 by Cisco Systems, Inc
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *------------------------------------------------------------------
+ */
+
+#include "safeclib_private.h"
+#include "safe_str_constraint.h"
+#include "safe_str_lib.h"
+
+
+/**
+ * NAME
+ * strnlen_s
+ *
+ * SYNOPSIS
+ * #include "safe_str_lib.h"
+ * rsize_t
+ * strnlen_s(const char *dest, rsize_t dmax)
+ *
+ * DESCRIPTION
+ * The strnlen_s function computes the length of the string pointed
+ * to by dest.
+ *
+ * SPECIFIED IN
+ * ISO/IEC TR 24731-1, Programming languages, environments
+ * and system software interfaces, Extensions to the C Library,
+ * Part I: Bounds-checking interfaces
+ *
+ * INPUT PARAMETERS
+ * dest pointer to string
+ *
+ * dmax restricted maximum length.
+ *
+ * OUTPUT PARAMETERS
+ * none
+ *
+ * RUNTIME CONSTRAINTS
+ * dest shall not be a null pointer
+ * dmax shall not be greater than RSIZE_MAX_STR
+ * dmax shall not equal zero
+ *
+ * RETURN VALUE
+ * The function returns the string length, excluding the terminating
+ * null character. If dest is NULL, then strnlen_s returns 0.
+ *
+ * Otherwise, the strnlen_s function returns the number of characters
+ * that precede the terminating null character. If there is no null
+ * character in the first dmax characters of dest then strnlen_s returns
+ * dmax. At most the first dmax characters of dest are accessed
+ * by strnlen_s.
+ *
+ * ALSO SEE
+ * strnterminate_s()
+ *
+ */
+rsize_t
+strnlen_s (const char *dest, rsize_t dmax)
+{
+ rsize_t count;
+
+ if (dest == NULL) {
+ return RCNEGATE(0);
+ }
+
+ if (dmax == 0) {
+ invoke_safe_str_constraint_handler("strnlen_s: dmax is 0",
+ NULL, ESZEROL);
+ return RCNEGATE(0);
+ }
+
+ if (dmax > RSIZE_MAX_STR) {
+ invoke_safe_str_constraint_handler("strnlen_s: dmax exceeds max",
+ NULL, ESLEMAX);
+ return RCNEGATE(0);
+ }
+
+ count = 0;
+ while (*dest && dmax) {
+ count++;
+ dmax--;
+ dest++;
+ }
+
+ return RCNEGATE(count);
+}
+EXPORT_SYMBOL(strnlen_s);
diff --git a/libcilkrts/runtime/stats.c b/libcilkrts/runtime/stats.c
index 3a420745039..407a85ddd98 100644
--- a/libcilkrts/runtime/stats.c
+++ b/libcilkrts/runtime/stats.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "stats.h"
@@ -51,7 +62,8 @@ static const char *names[] = {
/*[INTERVAL_IN_SCHEDULER]*/ "in scheduler",
/*[INTERVAL_WORKING]*/ " of which: working",
/*[INTERVAL_IN_RUNTIME]*/ " of which: in runtime",
- /*[INTERVAL_STEALING]*/ " of which: stealing",
+ /*[INTERVAL_IN_SCHED_LOOP]*/ " of which: in sched loop",
+ /*[INTERVAL_STEALING]*/ " of which: stealing",
/*[INTERVAL_STEAL_SUCCESS]*/ "steal success: detach",
/*[INTERVAL_STEAL_FAIL_EMPTYQ]*/ "steal fail: empty queue",
/*[INTERVAL_STEAL_FAIL_LOCK]*/ "steal fail: victim locked",
@@ -81,6 +93,8 @@ static const char *names[] = {
/*[INTERVAL_FIBER_DEALLOCATE_FROM_THREAD]*/ "fiber_deallocate (thread)",
/*[INTERVAL_SUSPEND_RESUME_OTHER]*/ "fiber suspend self + resume",
/*[INTERVAL_DEALLOCATE_RESUME_OTHER]*/ "fiber deallocate self + resume",
+ /*[INTERVAL_INIT_WORKER]*/ "init worker thread",
+ /*[INTERVAL_SCHEDULE_WAIT]*/ "schedule wait state",
};
#endif
@@ -144,27 +158,32 @@ void __cilkrts_stop_interval(__cilkrts_worker *w, enum interval i)
void dump_stats_to_file(FILE *stat_file, statistics *s)
{
- int i;
- fprintf(stat_file, "\nCILK PLUS RUNTIME SYSTEM STATISTICS:\n\n");
-
- fprintf(stat_file,
- " %-32s: %15s %10s %12s %10s\n",
- "event",
- "count",
- "ticks",
- "ticks/count",
- "%total"
- );
- for (i = 0; i < INTERVAL_N; ++i) {
- fprintf(stat_file, " %-32s: %15llu", names[i], s->count[i]);
- if (s->accum[i]) {
- fprintf(stat_file, " %10.3g %12.3g %10.2f",
- (double)s->accum[i],
- (double)s->accum[i] / (double)s->count[i],
- 100.0 * (double)s->accum[i] /
- (double)s->accum[INTERVAL_IN_SCHEDULER]);
+ // Only print out stats for worker if they are nonzero.
+ if (s->accum[INTERVAL_IN_SCHEDULER] > 0) {
+ int i;
+ fprintf(stat_file, "\nCILK PLUS RUNTIME SYSTEM STATISTICS:\n\n");
+ fprintf(stat_file,
+ " %-32s: %15s %10s %12s %10s\n",
+ "event",
+ "count",
+ "ticks",
+ "ticks/count",
+ "%total"
+ );
+ for (i = 0; i < INTERVAL_N; ++i) {
+ fprintf(stat_file, " %-32s: %15llu", names[i], s->count[i]);
+ if (s->accum[i]) {
+ fprintf(stat_file, " %10.3g %12.3g %10.2f",
+ (double)s->accum[i],
+ (double)s->accum[i] / (double)s->count[i],
+ 100.0 * (double)s->accum[i] /
+ (double)s->accum[INTERVAL_IN_SCHEDULER]);
+ }
+ fprintf(stat_file, "\n");
}
- fprintf(stat_file, "\n");
+ }
+ else {
+ fprintf(stat_file, "empty statistics\n");
}
}
#endif // CILK_PROFILE
diff --git a/libcilkrts/runtime/stats.h b/libcilkrts/runtime/stats.h
index aaa99274765..befc620a4d0 100644
--- a/libcilkrts/runtime/stats.h
+++ b/libcilkrts/runtime/stats.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
@@ -63,12 +74,45 @@
__CILKRTS_BEGIN_EXTERN_C
+// Some notes on the stats we are counting for the Cilk Plus runtime.
+//
+// INTERVAL_IN_SCHEDULER:
+//
+// For a user worker, it starts counting when the worker thread is
+// bound, and stops when the worker thread is unbound.
+//
+// For a system worker, it starts counting when the worker thread is
+// created, and stops after it returns from the scheduling loop
+// (which usually won't happen unless __cilkrts_end_cilk() is
+// called.)
+//
+// INTERVAL_WORKING + INTERVAL_IN_RUNTIME should be equal to
+// INTERVAL_IN_SCHEDULER (modulo overheads in instrumentation).
+//
+// INTERVAL_IN_RUNTIME tries to count all the time spent inside
+// runtime code. (leave_frame and reudctions blur the accounting a
+// bit). We switch from WORKING to IN_RUNTIME from:
+//
+// 1. __cilkrts_leave_frame, when we start doing an exception check
+// and might jump into the runtime, either when returning from a
+// spawn or have an exception to process.
+//
+// 2. __cilkrts_c_sync, when we are at a sync and the frame has
+// been stolen from.
+//
+// We switch back to WORKING when we are returning to user code.
+//
+// We also switch back to WORKING when we need to do a slow merge of
+// reducer maps. Otherwise, parallel reductions can mess up the stat
+// collection.
+
/** @brief Events that we measure. */
enum interval
{
INTERVAL_IN_SCHEDULER, ///< Time threads spend "bound" to Cilk
INTERVAL_WORKING, ///< Time spent working
- INTERVAL_IN_RUNTIME, ///< Time spent executing runtime scheduling loop
+ INTERVAL_IN_RUNTIME, ///< Time spent executing runtime code
+ INTERVAL_SCHED_LOOP, ///< Time spent in scheduling loop
INTERVAL_STEALING, ///< Time spent stealing work
INTERVAL_STEAL_SUCCESS, ///< Time to do a successful steal
INTERVAL_STEAL_FAIL_EMPTYQ, ///< Count of steal failures due to lack of stealable work
@@ -99,6 +143,8 @@ enum interval
INTERVAL_FIBER_DEALLOCATE_FROM_THREAD, ///< Time spent calling cilk_fiber_deallocate (from thread)
INTERVAL_SUSPEND_RESUME_OTHER, ///< Count of fiber suspend_self_and_resume_other
INTERVAL_DEALLOCATE_RESUME_OTHER, ///< Count of fiber deallocate_self_and_resume_other
+ INTERVAL_INIT_WORKER, ///< Time spent on initialization of worker thread
+ INTERVAL_SCHEDULE_WAIT, ///< Time worker spends in SCHEDULE_WAIT state
INTERVAL_N ///< Number of intervals, must be last
};
diff --git a/libcilkrts/runtime/sysdep-unix.c b/libcilkrts/runtime/sysdep-unix.c
index 1f82b6288a1..611934a9bbf 100644
--- a/libcilkrts/runtime/sysdep-unix.c
+++ b/libcilkrts/runtime/sysdep-unix.c
@@ -3,11 +3,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2010-2013, Intel Corporation
+ * Copyright (C) 2010-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -22,7 +20,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,17 +32,24 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
*
**************************************************************************
*/
-#ifdef __linux__
- // define _GNU_SOURCE before *any* #include.
- // Even <stdint.h> will break later #includes if this macro is not
- // already defined when it is #included.
-# define _GNU_SOURCE
-#endif
-
#include "sysdep.h"
#include "os.h"
#include "bug.h"
@@ -80,24 +84,7 @@
#include <string.h>
#include <pthread.h>
#include <unistd.h>
-
-#if defined HAVE_ALLOCA_H
-# include <alloca.h>
-#elif defined __GNUC__
-# define alloca __builtin_alloca
-#elif defined _AIX
-# define alloca __alloca
-#else
-# include <stddef.h>
-# ifdef __cplusplus
-extern "C"
-# endif
-void *alloca (size_t);
-#endif
-
-#ifdef __APPLE__
-//# include <scheduler.h> // Angle brackets include Apple's scheduler.h, not ours.
-#endif
+#include "declare-alloca.h"
#ifdef __linux__
# include <sys/resource.h>
@@ -205,11 +192,17 @@ NON_COMMON void* scheduler_thread_proc_for_system_worker(void *arg)
__cilkrts_set_tls_worker(w);
+ START_INTERVAL(w, INTERVAL_IN_SCHEDULER);
+ START_INTERVAL(w, INTERVAL_IN_RUNTIME);
+ START_INTERVAL(w, INTERVAL_INIT_WORKER);
+
// Create a cilk fiber for this worker on this thread.
START_INTERVAL(w, INTERVAL_FIBER_ALLOCATE_FROM_THREAD) {
w->l->scheduling_fiber = cilk_fiber_allocate_from_thread();
cilk_fiber_set_owner(w->l->scheduling_fiber, w);
} STOP_INTERVAL(w, INTERVAL_FIBER_ALLOCATE_FROM_THREAD);
+
+ STOP_INTERVAL(w, INTERVAL_INIT_WORKER);
internal_run_scheduler_with_exceptions(w);
@@ -225,35 +218,11 @@ NON_COMMON void* scheduler_thread_proc_for_system_worker(void *arg)
w->l->scheduling_fiber = NULL;
} STOP_INTERVAL(w, INTERVAL_FIBER_DEALLOCATE_FROM_THREAD);
+ STOP_INTERVAL(w, INTERVAL_IN_RUNTIME);
+ STOP_INTERVAL(w, INTERVAL_IN_SCHEDULER);
return 0;
}
-
-/*
- * __cilkrts_user_worker_scheduling_stub
- *
- * Routine for the scheduling fiber created for an imported user
- * worker thread. This method is analogous to
- * scheduler_thread_proc_for_system_worker.
- *
- */
-void __cilkrts_user_worker_scheduling_stub(cilk_fiber* fiber, void* null_arg)
-{
- __cilkrts_worker *w = __cilkrts_get_tls_worker();
-
- // Sanity check.
- CILK_ASSERT(WORKER_USER == w->l->type);
-
- // Enter the scheduling loop on the user worker.
- // This function will never return.
- __cilkrts_run_scheduler_with_exceptions(w);
-
- // A WORKER_USER, at some point, will resume on the original stack and leave
- // Cilk. Under no circumstances do we ever exit off of the bottom of this
- // stack.
- CILK_ASSERT(0);
-}
-
/**
* We are exporting a function with this name to Inspector?
* What a confusing name...
@@ -266,8 +235,6 @@ void* __cilkrts_worker_stub(void* arg)
return scheduler_thread_proc_for_system_worker(arg);
}
-
-
// /* Return the lesser of the argument and the operating system
// limit on the number of workers (threads) that may or ought
// to be created. */
@@ -571,64 +538,51 @@ void __cilkrts_make_unrunnable_sysdep(__cilkrts_worker *w,
}
}
-/*
- * __cilkrts_sysdep_is_worker_thread_id
- *
- * Returns true if the thread ID specified matches the thread ID we saved
- * for a worker.
- */
-
-int __cilkrts_sysdep_is_worker_thread_id(global_state_t *g,
- int i,
- void *thread_id)
-{
-#if defined( __linux__) || defined(__VXWORKS__)
- pthread_t tid = *(pthread_t *)thread_id;
- if (i < 0 || i > g->total_workers)
- return 0;
- return g->sysdep->threads[i] == tid;
-#else
- // Needs to be implemented
- return 0;
-#endif
-}
-
-
-
-
/*************************************************************
Version information:
*************************************************************/
+#ifndef _WRS_KERNEL
#include <dlfcn.h>
+#endif
#include "internal/cilk_version.h"
#include <stdio.h>
+#ifndef _WRS_KERNEL
#include <sys/utsname.h>
+#endif
#ifdef __VXWORKS__
#include <version.h>
-# endif
+#endif
/* (Non-static) dummy function is used by get_runtime_path() to find the path
* to the .so containing the Cilk runtime.
*/
void dummy_function() { }
-/* return a string with the path to the Cilk runtime, or "unknown" if the path
+/*
+ * Return a string with the path to the Cilk runtime, or "unknown" if the path
* cannot be determined.
*/
static const char *get_runtime_path ()
{
-#ifdef __CYGWIN__
- // Cygwin doesn't support dladdr, which sucks
- return "unknown";
-#else
+ // dladdr is a glibc extension. If it's available, use it to find the path
+ // for libcilkrts.so
+#ifdef _GNU_SOURCE
Dl_info info;
- if (0 == dladdr(dummy_function, &info)) return "unknown";
- return info.dli_fname;
+ if (0 != dladdr(dummy_function, &info))
+ return info.dli_fname;
#endif
+
+ // If dladdr isn't available, or dladdr failed, we can't know the path for
+ // the shared object
+ return "unknown";
}
+#ifdef _WRS_KERNEL
+#include <version.h>
+#include <sysLib.h>
+#endif
/* if the environment variable, CILK_VERSION, is defined, writes the version
* information to the specified file.
* g is the global state that was just created, and n is the number of workers
@@ -640,7 +594,9 @@ static void write_version_file (global_state_t *g, int n)
char buf[256]; // print buffer.
time_t t;
FILE *fp;
+#ifndef _WRS_KERNEL
struct utsname sys_info;
+#endif
int err; // error code from system calls.
// if CILK_VERSION is not set, or if the file cannot be opened, fail
@@ -711,15 +667,22 @@ static void write_version_file (global_state_t *g, int n)
// System OS: Linux, release 2.6.28-19-generic
// System architecture: x86_64
- err = uname(&sys_info);
fprintf(fp, "\nSystem information\n");
fprintf(fp, "==================\n");
fprintf(fp, "Cilk runtime path: %s\n", get_runtime_path());
+#ifndef _WRS_KERNEL
+ err = uname(&sys_info);
fprintf(fp, "System OS: %s, release %s\n",
err < 0 ? "unknown" : sys_info.sysname,
err < 0 ? "?" : sys_info.release);
fprintf(fp, "System architecture: %s\n",
err < 0 ? "unknown" : sys_info.machine);
+#else
+ fprintf(fp, "System OS: %s, release %s\n",
+ "VxWorks", RUNTIME_NAME RUNTIME_VERSION);
+ fprintf(fp, "System architecture: %s\n",
+ sysModel());
+#endif
// Print thread info. E.g.,
// Thread information
@@ -792,10 +755,12 @@ void __cilkrts_establish_c_stack(void)
static __attribute__((noinline))
void internal_enforce_global_visibility()
{
+#ifndef __VXWORKS__
void* handle = dlopen( get_runtime_path(), RTLD_GLOBAL|RTLD_LAZY );
/* For proper reference counting, close the handle immediately. */
if( handle) dlclose(handle);
+#endif
}
/*
diff --git a/libcilkrts/runtime/sysdep.h b/libcilkrts/runtime/sysdep.h
index ea939acc124..76ebc63d733 100644
--- a/libcilkrts/runtime/sysdep.h
+++ b/libcilkrts/runtime/sysdep.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcilkrts/runtime/worker_mutex.c b/libcilkrts/runtime/worker_mutex.c
index 380d6255a0c..94e39b0beaa 100644
--- a/libcilkrts/runtime/worker_mutex.c
+++ b/libcilkrts/runtime/worker_mutex.c
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
#include "worker_mutex.h"
diff --git a/libcilkrts/runtime/worker_mutex.h b/libcilkrts/runtime/worker_mutex.h
index c2c68247e0b..5faabd85d01 100644
--- a/libcilkrts/runtime/worker_mutex.h
+++ b/libcilkrts/runtime/worker_mutex.h
@@ -2,11 +2,9 @@
*
*************************************************************************
*
- * @copyright
- * Copyright (C) 2009-2013, Intel Corporation
+ * Copyright (C) 2009-2016, Intel Corporation
* All rights reserved.
*
- * @copyright
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -21,7 +19,6 @@
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
- * @copyright
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,6 +31,20 @@
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
* WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *********************************************************************
+ *
+ * PLEASE NOTE: This file is a downstream copy of a file mainitained in
+ * a repository at cilkplus.org. Changes made to this file that are not
+ * submitted through the contribution process detailed at
+ * http://www.cilkplus.org/submit-cilk-contribution will be lost the next
+ * time that a new version is released. Changes only submitted to the
+ * GNU compiler collection or posted to the git repository at
+ * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are
+ * not tracked.
+ *
+ * We welcome your contributions to this open source project. Thank you
+ * for your assistance in helping us improve Cilk Plus.
**************************************************************************/
/**
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index 1dc1c73bff2..d7a89d7d495 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,12 @@
+2016-05-20 Martin Liska <mliska@suse.cz>
+
+ * config.in: Regenerated.
+ * configure: Likewise.
+ * configure.ac: Handle --enable-valgrind-annotations.
+ * lex.c (new_buff): Use ENABLE_VALGRIND_ANNOTATIONS instead
+ of ENABLE_VALGRIND_CHECKING.
+ (_cpp_free_buff): Likewise.
+
2016-04-28 Eduard Sanou <dhole@openmailbox.org>
Matthias Klose <doko@debian.org>
diff --git a/libcpp/config.in b/libcpp/config.in
index e02ac5efbad..3bbffe7815e 100644
--- a/libcpp/config.in
+++ b/libcpp/config.in
@@ -21,6 +21,9 @@
language is requested. */
#undef ENABLE_NLS
+/* Define to get calls to the valgrind runtime enabled. */
+#undef ENABLE_VALGRIND_ANNOTATIONS
+
/* Define if you want to workaround valgrind (a memory checker) warnings about
possible memory leaks because of libcpp use of interior pointers. */
#undef ENABLE_VALGRIND_CHECKING
diff --git a/libcpp/configure b/libcpp/configure
index 0342f163c9c..b6f129c48b9 100755
--- a/libcpp/configure
+++ b/libcpp/configure
@@ -703,6 +703,7 @@ enable_maintainer_mode
enable_checking
enable_canonical_system_headers
enable_host_shared
+enable_valgrind_annotations
'
ac_precious_vars='build_alias
host_alias
@@ -1343,6 +1344,8 @@ Optional Features:
--enable-canonical-system-headers
enable or disable system headers canonicalization
--enable-host-shared build host code as shared libraries
+ --enable-valgrind-annotations
+ enable valgrind runtime interaction
Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
@@ -7355,6 +7358,25 @@ fi
+# Check whether --enable-valgrind-annotations was given.
+if test "${enable_valgrind_annotations+set}" = set; then :
+ enableval=$enable_valgrind_annotations;
+else
+ enable_valgrind_annotations=no
+fi
+
+if test x$enable_valgrind_annotations != xno \
+ || test x$ac_valgrind_checking != x; then
+ if (test $have_valgrind_h = no \
+ && test $gcc_cv_header_memcheck_h = no \
+ && test $gcc_cv_header_valgrind_memcheck_h = no); then
+ as_fn_error "*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h" "$LINENO" 5
+ fi
+
+$as_echo "#define ENABLE_VALGRIND_ANNOTATIONS 1" >>confdefs.h
+
+fi
+
# Output.
ac_config_headers="$ac_config_headers config.h:config.in"
diff --git a/libcpp/configure.ac b/libcpp/configure.ac
index 0005c589fcd..3077ee09768 100644
--- a/libcpp/configure.ac
+++ b/libcpp/configure.ac
@@ -200,6 +200,21 @@ AC_ARG_ENABLE(host-shared,
[PICFLAG=-fPIC], [PICFLAG=])
AC_SUBST(PICFLAG)
+AC_ARG_ENABLE(valgrind-annotations,
+[AS_HELP_STRING([--enable-valgrind-annotations],
+ [enable valgrind runtime interaction])], [],
+[enable_valgrind_annotations=no])
+if test x$enable_valgrind_annotations != xno \
+ || test x$ac_valgrind_checking != x; then
+ if (test $have_valgrind_h = no \
+ && test $gcc_cv_header_memcheck_h = no \
+ && test $gcc_cv_header_valgrind_memcheck_h = no); then
+ AC_MSG_ERROR([*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h])
+ fi
+ AC_DEFINE(ENABLE_VALGRIND_ANNOTATIONS, 1,
+[Define to get calls to the valgrind runtime enabled.])
+fi
+
# Output.
AC_CONFIG_HEADERS(config.h:config.in, [echo timestamp > stamp-h1])
diff --git a/libcpp/lex.c b/libcpp/lex.c
index e5a0397f309..236418dd781 100644
--- a/libcpp/lex.c
+++ b/libcpp/lex.c
@@ -3147,7 +3147,7 @@ new_buff (size_t len)
len = MIN_BUFF_SIZE;
len = CPP_ALIGN (len);
-#ifdef ENABLE_VALGRIND_CHECKING
+#ifdef ENABLE_VALGRIND_ANNOTATIONS
/* Valgrind warns about uses of interior pointers, so put _cpp_buff
struct first. */
size_t slen = CPP_ALIGN2 (sizeof (_cpp_buff), 2 * DEFAULT_ALIGNMENT);
@@ -3244,7 +3244,7 @@ _cpp_free_buff (_cpp_buff *buff)
for (; buff; buff = next)
{
next = buff->next;
-#ifdef ENABLE_VALGRIND_CHECKING
+#ifdef ENABLE_VALGRIND_ANNOTATIONS
free (buff);
#else
free (buff->base);
diff --git a/libcpp/po/ChangeLog b/libcpp/po/ChangeLog
index 0b07fe7be37..339d242393e 100644
--- a/libcpp/po/ChangeLog
+++ b/libcpp/po/ChangeLog
@@ -1,3 +1,15 @@
+2016-05-18 Joseph Myers <joseph@codesourcery.com>
+
+ * da.po: Update.
+
+2016-05-12 Joseph Myers <joseph@codesourcery.com>
+
+ * fi.po: Update.
+
+2016-05-03 Joseph Myers <joseph@codesourcery.com>
+
+ * nl.po: Update.
+
2016-04-30 Joseph Myers <joseph@codesourcery.com>
* sv.po: Update.
diff --git a/libcpp/po/da.po b/libcpp/po/da.po
index 5c8e82a805d..3f8bf85d8b6 100644
--- a/libcpp/po/da.po
+++ b/libcpp/po/da.po
@@ -128,10 +128,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: cpplib 6.1-b20160131\n"
+"Project-Id-Version: cpplib 6.1.0\n"
"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
"POT-Creation-Date: 2016-04-21 15:24+0000\n"
-"PO-Revision-Date: 2016-03-27 18:00+0200\n"
+"PO-Revision-Date: 2016-05-16 18:00+0200\n"
"Last-Translator: Joe Hansen <joedalton2@yahoo.dk>\n"
"Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
"Language: da\n"
@@ -394,7 +394,7 @@ msgstr "»%s« efter # er ikke et positivt heltal"
#: directives.c:1061
#, c-format
msgid "file \"%s\" linemarker ignored due to incorrect nesting"
-msgstr ""
+msgstr "filen »%s« linjemarkør ignoreret på grund af ukorrekt indlejring"
#: directives.c:1120 directives.c:1122 directives.c:1124 directives.c:1710
#, c-format
@@ -555,10 +555,8 @@ msgid "invalid prefix \"0b\" for floating constant"
msgstr "ugyldigt præfiks »0b« i kommatalskonstant"
#: expr.c:555
-#, fuzzy
-#| msgid "use of C++11 hexadecimal floating constant"
msgid "use of C++1z hexadecimal floating constant"
-msgstr "brug af C++11 hexadecimal kommatalskonstant"
+msgstr "brug af C++1z hexadecimal kommatalskonstant"
#: expr.c:558
msgid "use of C99 hexadecimal floating constant"
diff --git a/libcpp/po/fi.po b/libcpp/po/fi.po
index bbf184e3568..0f0ea9b9d13 100644
--- a/libcpp/po/fi.po
+++ b/libcpp/po/fi.po
@@ -6,10 +6,10 @@
#
msgid ""
msgstr ""
-"Project-Id-Version: cpplib 6.1-b20160131\n"
+"Project-Id-Version: cpplib 6.1.0\n"
"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
"POT-Creation-Date: 2016-04-21 15:24+0000\n"
-"PO-Revision-Date: 2016-02-09 22:14+0200\n"
+"PO-Revision-Date: 2016-05-12 23:30+0300\n"
"Last-Translator: Lauri Nurmi <lanurmi@iki.fi>\n"
"Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
"Language: fi\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 1.8.6\n"
+"X-Generator: Poedit 1.8.7\n"
#: charset.c:674
#, c-format
@@ -275,7 +275,7 @@ msgstr "#:n jälkeinen ”%s” ei ole positiivinen kokonaisluku"
#: directives.c:1061
#, c-format
msgid "file \"%s\" linemarker ignored due to incorrect nesting"
-msgstr ""
+msgstr "tiedoston ”%s” rivinmerkitsin jätetään huomiotta virheellisen sisäkkäisyyden vuoksi"
#: directives.c:1120 directives.c:1122 directives.c:1124 directives.c:1710
#, c-format
@@ -437,10 +437,8 @@ msgid "invalid prefix \"0b\" for floating constant"
msgstr "virheellinen etuliite ”0b” liukulukuvakiolle"
#: expr.c:555
-#, fuzzy
-#| msgid "use of C++11 hexadecimal floating constant"
msgid "use of C++1z hexadecimal floating constant"
-msgstr "C++11:n heksadesimaaliliukulukuvakion käyttö"
+msgstr "C++1z:n heksadesimaaliliukulukuvakion käyttö"
#: expr.c:558
msgid "use of C99 hexadecimal floating constant"
diff --git a/libcpp/po/nl.po b/libcpp/po/nl.po
index 78b32283d99..5a30f34ecb7 100644
--- a/libcpp/po/nl.po
+++ b/libcpp/po/nl.po
@@ -1,18 +1,17 @@
# Dutch translations for GNU cpplib.
-# Copyright (C) 2015 Free Software Foundation, Inc.
+# Copyright (C) 2016 Free Software Foundation, Inc.
# This file is distributed under the same license as the gcc package.
#
-# "If economists could manage to get themselves thought of as humble,
-# competent people, on a level with dentists, that would be splendid!"
+# « Vorsicht. Bissiger Mensch! »
#
# Tim Van Holder <tim.van.holder@telenet.be>, 2008, 2009, 2010.
-# Benno Schulenberg <benno@vertaalt.nl>, 2014, 2015.
+# Benno Schulenberg <benno@vertaalt.nl>, 2014, 2015, 2016.
msgid ""
msgstr ""
-"Project-Id-Version: cpplib 5.2.0\n"
+"Project-Id-Version: cpplib 6.1.0\n"
"Report-Msgid-Bugs-To: http://gcc.gnu.org/bugs.html\n"
"POT-Creation-Date: 2016-04-21 15:24+0000\n"
-"PO-Revision-Date: 2015-07-23 19:42+0200\n"
+"PO-Revision-Date: 2016-05-03 12:27+0200\n"
"Last-Translator: Benno Schulenberg <benno@vertaalt.nl>\n"
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
"Language: nl\n"
@@ -281,7 +280,7 @@ msgstr "\"%s\" (na #) is geen positieve integer"
#: directives.c:1061
#, c-format
msgid "file \"%s\" linemarker ignored due to incorrect nesting"
-msgstr ""
+msgstr "regelmarkering voor bestand \"%s\" is genegeerd wegens incorrecte nesting"
# FIXME: most likely shouldn't have been marked as translatable
#: directives.c:1120 directives.c:1122 directives.c:1124 directives.c:1710
@@ -452,10 +451,8 @@ msgid "invalid prefix \"0b\" for floating constant"
msgstr "ongeldige prefix \"0b\" voor floating-point constante"
#: expr.c:555
-#, fuzzy
-#| msgid "use of C++11 hexadecimal floating constant"
msgid "use of C++1z hexadecimal floating constant"
-msgstr "gebruik van een C++11 hexadecimale floating-point constante"
+msgstr "gebruik van een C++1z hexadecimale floating-point constante"
#: expr.c:558
msgid "use of C99 hexadecimal floating constant"
@@ -778,10 +775,8 @@ msgid "missing terminating %c character"
msgstr "afsluitend %c-teken ontbreekt"
#: lex.c:1932
-#, fuzzy
-#| msgid "invalid suffix on literal; C++11 requires a space between literal and string macro"
msgid "C++11 requires a space between string literal and macro"
-msgstr "ongeldige suffix aan constante; C++11 vereist een spatie tussen constante en stringmacro"
+msgstr "C++11 vereist een spatie tussen stringconstante en macro"
#: lex.c:2474 lex.c:2508
msgid "C++ style comments are not allowed in ISO C90"
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 58a3bc70bf5..6b20f9bd2f9 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,16 @@
+2016-05-19 Sandra Loosemore <sandra@codesourcery.com>
+
+ * config.host [x86_64-*-cygwin*]: Handle tmake_eh_file for mixed
+ dw2/seh configuration.
+ [x86_64-*-mingw*]: Likewise.
+
+2016-05-10 Joel Sherrill <joel@rtems.org>
+
+ PR libgcc/70720
+ * config.host (moxie-*-rtems*): Merge this stanza with other moxie
+ targets so the same extra_parts are built. Also have tmake_file add
+ on to its value rather than override.
+
2016-04-30 Oleg Endo <olegendo@gcc.gnu.org>
* config.host: Remove SH5 support.
diff --git a/libgcc/config.host b/libgcc/config.host
index 8bd7bb68a2b..7899216af6c 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -678,6 +678,9 @@ x86_64-*-cygwin*)
# This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h
if test x$ac_cv_sjlj_exceptions = xyes; then
tmake_eh_file="i386/t-sjlj-eh"
+ elif test "${host_address}" = 32; then
+ # biarch -m32 with --disable-sjlj-exceptions
+ tmake_eh_file="i386/t-dw2-eh"
else
tmake_eh_file="i386/t-seh-eh"
fi
@@ -730,6 +733,10 @@ x86_64-*-mingw*)
# This has to match the logic for DWARF2_UNWIND_INFO in gcc/config/i386/cygming.h
if test x$ac_cv_sjlj_exceptions = xyes; then
tmake_eh_file="i386/t-sjlj-eh"
+ elif test "${host_address}" = 32; then
+ # biarch -m32 with --disable-sjlj-exceptions
+ tmake_eh_file="i386/t-dw2-eh"
+ md_unwind_header=i386/w32-unwind.h
else
tmake_eh_file="i386/t-seh-eh"
fi
@@ -933,14 +940,9 @@ mmix-knuth-mmixware)
mn10300-*-*)
tmake_file=t-fdpbit
;;
-moxie-*-elf | moxie-*-moxiebox* | moxie-*-uclinux*)
- tmake_file="moxie/t-moxie t-softfp-sfdf t-softfp-excl t-softfp"
- extra_parts="$extra_parts crti.o crtn.o crtbegin.o crtend.o"
- ;;
-moxie-*-rtems*)
+moxie-*-elf | moxie-*-moxiebox* | moxie-*-uclinux* | moxie-*-rtems*)
tmake_file="$tmake_file moxie/t-moxie t-softfp-sfdf t-softfp-excl t-softfp"
- # Don't use default.
- extra_parts=
+ extra_parts="$extra_parts crti.o crtn.o crtbegin.o crtend.o"
;;
msp430*-*-elf)
tmake_file="$tm_file t-crtstuff t-fdpbit msp430/t-msp430"
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 9de04f57d73..6a390879ff1 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,22 @@
+2016-05-23 Martin Jambor <mjambor@suse.cz>
+
+ * testsuite/libgomp.hsa.c/switch-sbr-2.c: New test.
+
+2016-05-17 Chung-Lin Tang <cltang@codesourcery.com>
+
+ * oacc-init.c (acc_init): Remove !cached_base_dev condition on call
+ to gomp_init_targets_once.
+ (acc_set_device_type): Remove !cached_base_dev condition on call to
+ gomp_init_targets_once, move call to before acc_device_lock acquire,
+ to avoid deadlock.
+ (acc_get_device_num): Remove !cached_base_dev condition on call to
+ gomp_init_targets_once.
+ (acc_set_device_num): Likewise.
+
+2016-05-16 Martin Jambor <mjambor@suse.cz>
+
+ * testsuite/libgomp.hsa.c/complex-align-2.c: New test.
+
2016-05-02 Nathan Sidwell <nathan@codesourcery.com>
* testsuite/libgomp.oacc-c-c++-common/loop-auto-1.c: Adjust
diff --git a/libgomp/oacc-init.c b/libgomp/oacc-init.c
index 42d005da5f2..f6176eccd3f 100644
--- a/libgomp/oacc-init.c
+++ b/libgomp/oacc-init.c
@@ -433,8 +433,7 @@ goacc_attach_host_thread_to_device (int ord)
void
acc_init (acc_device_t d)
{
- if (!cached_base_dev)
- gomp_init_targets_once ();
+ gomp_init_targets_once ();
gomp_mutex_lock (&acc_device_lock);
@@ -498,10 +497,9 @@ acc_set_device_type (acc_device_t d)
struct gomp_device_descr *base_dev, *acc_dev;
struct goacc_thread *thr = goacc_thread ();
- gomp_mutex_lock (&acc_device_lock);
+ gomp_init_targets_once ();
- if (!cached_base_dev)
- gomp_init_targets_once ();
+ gomp_mutex_lock (&acc_device_lock);
cached_base_dev = base_dev = resolve_device (d, true);
acc_dev = &base_dev[goacc_device_num];
@@ -563,8 +561,7 @@ acc_get_device_num (acc_device_t d)
if (d >= _ACC_device_hwm)
gomp_fatal ("unknown device type %u", (unsigned) d);
- if (!cached_base_dev)
- gomp_init_targets_once ();
+ gomp_init_targets_once ();
gomp_mutex_lock (&acc_device_lock);
dev = resolve_device (d, true);
@@ -584,8 +581,7 @@ acc_set_device_num (int ord, acc_device_t d)
struct gomp_device_descr *base_dev, *acc_dev;
int num_devices;
- if (!cached_base_dev)
- gomp_init_targets_once ();
+ gomp_init_targets_once ();
if (ord < 0)
ord = goacc_device_num;
diff --git a/libgomp/testsuite/libgomp.hsa.c/complex-align-2.c b/libgomp/testsuite/libgomp.hsa.c/complex-align-2.c
new file mode 100644
index 00000000000..b2d7acff443
--- /dev/null
+++ b/libgomp/testsuite/libgomp.hsa.c/complex-align-2.c
@@ -0,0 +1,27 @@
+#pragma omp declare target
+ _Complex int *g;
+#pragma omp end declare target
+
+
+
+_Complex float f(void);
+
+int
+main ()
+{
+ _Complex int y;
+#pragma omp target map(from:y)
+ {
+ _Complex int x;
+ g = &x;
+ __imag__ x = 1;
+ __real__ x = 2;
+ y = x;
+ }
+
+ if ((__imag__ y != 1)
+ || (__real__ y != 2))
+ __builtin_abort ();
+ return 0;
+}
+
diff --git a/libgomp/testsuite/libgomp.hsa.c/switch-sbr-2.c b/libgomp/testsuite/libgomp.hsa.c/switch-sbr-2.c
new file mode 100644
index 00000000000..06990d1c2c0
--- /dev/null
+++ b/libgomp/testsuite/libgomp.hsa.c/switch-sbr-2.c
@@ -0,0 +1,59 @@
+/* { dg-additional-options "-fno-tree-switch-conversion" } */
+
+#pragma omp declare target
+int
+foo (unsigned a)
+{
+ switch (a)
+ {
+ case 1 ... 5:
+ return 1;
+ case 9 ... 11:
+ return a + 3;
+ case 12 ... 13:
+ return a + 3;
+ default:
+ return 44;
+ }
+}
+#pragma omp end declare target
+
+#define s 100
+
+void __attribute__((noinline, noclone))
+verify(int *a)
+{
+ if (a[0] != 44)
+ __builtin_abort ();
+
+ for (int i = 1; i <= 5; i++)
+ if (a[i] != 1)
+ __builtin_abort ();
+
+ for (int i = 6; i <= 8; i++)
+ if (a[i] != 44)
+ __builtin_abort ();
+
+ for (int i = 9; i <= 13; i++)
+ if (a[i] != i + 3)
+ __builtin_abort ();
+
+ for (int i = 14; i < s; i++)
+ if (a[i] != 44)
+ __builtin_abort ();
+}
+
+int main(int argc)
+{
+ int array[s];
+#pragma omp target
+ {
+ for (int i = 0; i < s; i++)
+ {
+ int v = foo (i);
+ array[i] = v;
+ }
+ }
+ verify (array);
+ return 0;
+}
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 7497392ea97..289617b2690 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,37 @@
+2016-05-19 Jakub Jelinek <jakub@redhat.com>
+
+ PR c++/70498
+ * cp-demangle.c (d_expression_1): Formatting fix.
+
+2016-05-18 Artemiy Volkov <artemiyv@acm.org>
+
+ * cplus-dem.c (enum type_kind_t): Add tk_rvalue_reference
+ constant.
+ (demangle_template_value_parm): Handle tk_rvalue_reference
+ type kind.
+ (do_type): Support 'O' type id (rvalue references).
+
+ * testsuite/demangle-expected: Add tests.
+
+2016-05-02 Marcel Böhme <boehme.marcel@gmail.com>
+
+ PR c++/70498
+ * cp-demangle.c: Parse numbers as integer instead of long to avoid
+ overflow after sanity checks. Include <limits.h> if available.
+ (INT_MAX): Define if necessary.
+ (d_make_template_param): Takes integer argument instead of long.
+ (d_make_function_param): Likewise.
+ (d_append_num): Likewise.
+ (d_identifier): Likewise.
+ (d_number): Parse as and return integer.
+ (d_compact_number): Handle overflow.
+ (d_source_name): Change variable type to integer for parsed number.
+ (d_java_resource): Likewise.
+ (d_special_name): Likewise.
+ (d_discriminator): Likewise.
+ (d_unnamed_type): Likewise.
+ * testsuite/demangle-expected: Add regression test cases.
+
2016-04-30 Oleg Endo <olegendo@gcc.gnu.org>
* configure: Remove SH5 support.
@@ -16,7 +50,7 @@
-1.
2016-03-31 Mikhail Maltsev <maltsevm@gmail.com>
- Marcel Bohme boehme.marcel@gmail.com
+ Marcel Bohme <boehme.marcel@gmail.com>
PR c++/67394
PR c++/70481
@@ -73,8 +107,6 @@
PR other/61321
PR other/61233
- * demangle.h (enum demangle_component_type)
- <DEMANGLE_COMPONENT_CONVERSION>: New value.
* cp-demangle.c (d_demangle_callback, d_make_comp): Handle
DEMANGLE_COMPONENT_CONVERSION.
(is_ctor_dtor_or_conversion): Handle DEMANGLE_COMPONENT_CONVERSION
@@ -661,11 +693,11 @@
2013-05-31 Matt Burgess <matthew@linuxfromscratch.org>
PR other/56780
- * libiberty/configure.ac: Move test for --enable-install-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
+ * configure: Regenerate.
+ * 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.
@@ -1465,7 +1497,6 @@
Daniel Jacobowitz <dan@codesourcery.com>
Pedro Alves <pedro@codesourcery.com>
- libiberty/
* argv.c (consume_whitespace): New function.
(only_whitespace): New function.
(buildargv): Always use ISSPACE by calling consume_whitespace.
@@ -1666,8 +1697,8 @@
2009-04-07 Arnaud Patard <apatard@mandriva.com>
- * libiberty/configure.ac: Fix Linux/MIPS matching rule.
- * libiberty/configure: Regenerate.
+ * configure.ac: Fix Linux/MIPS matching rule.
+ * configure: Regenerate.
2009-03-27 Ian Lance Taylor <iant@google.com>
@@ -1830,8 +1861,8 @@
2008-04-21 Aurelien Jarno <aurelien@aurel32.net>
- * libiberty/configure.ac: use -fPIC on Linux/MIPS hosts.
- * libiberty/configure: Regenerate.
+ * configure.ac: use -fPIC on Linux/MIPS hosts.
+ * configure: Regenerate.
2008-04-18 Kris Van Hees <kris.van.hees@oracle.com>
@@ -2037,7 +2068,7 @@
that are locale-independent.
* Makefile.in (filename_cmp.o): Add dependency on safe-ctype.h.
-2007-04-11 Thomas Neumann tneumann@users.sourceforge.net
+2007-04-11 Thomas Neumann <tneumann@users.sourceforge.net>
* argv.c: Use ANSI C declarations.
* make-relative-prefix.c: Likewise.
@@ -3609,7 +3640,7 @@
2003-12-15 Brendan Kehoe <brendan@zen.org>
- * libiberty/Makefile.in (floatformat.o): Add dependency on
+ * Makefile.in (floatformat.o): Add dependency on
config.h to accompany change of 2003-12-03.
2003-12-15 Ian Lance Taylor <ian@wasabisystems.com>
@@ -4305,7 +4336,7 @@
2002-10-06 Andreas Jaeger <aj@suse.de>
- * libiberty/cplus-dem.c (ada_demangle): Get rid of unneeded
+ * cplus-dem.c (ada_demangle): Get rid of unneeded
variable and of strict-aliasing warning.
(grow_vect): Use char as first parameter.
@@ -4573,7 +4604,7 @@
2002-01-31 Adam Megacz <adam@xwt.org>
- * gcc/libiberty/configure.in: Treat mingw the same as cywin
+ * configure.in: Treat mingw the same as cywin
wrt HAVE_SYS_ERRLIST.
2002-01-30 Phil Edwards <pme@gcc.gnu.org>
@@ -5081,8 +5112,8 @@ Tue Aug 21 12:35:04 2001 Christopher Faylor <cgf@cygnus.com>
2001-03-10 Neil Booth <neil@daikokuya.demon.co.uk>
John David Anglin <dave@hiauly1.hia.nrc.ca>
- * libiberty/lbasename.c: New file.
- * libiberty/Makefile.in: Update for lbasename.
+ * lbasename.c: New file.
+ * Makefile.in: Update for lbasename.
2001-03-06 Zack Weinberg <zackw@stanford.edu>
@@ -5455,13 +5486,13 @@ Tue Aug 21 12:35:04 2001 Christopher Faylor <cgf@cygnus.com>
2000-08-24 Greg McGary <greg@mcgary.org>
- * libiberty/random.c (end_ptr): Revert previous change.
+ * random.c (end_ptr): Revert previous change.
2000-08-24 Greg McGary <greg@mcgary.org>
- * libiberty/cplus-dem.c (cplus_demangle_opname, cplus_mangle_opname,
+ * cplus-dem.c (cplus_demangle_opname, cplus_mangle_opname,
demangle_expression, demangle_function_name): Use ARRAY_SIZE.
- * libiberty/random.c (end_ptr): Likewise.
+ * random.c (end_ptr): Likewise.
2000-08-23 Alex Samuel <samuel@codesourcery.com>
diff --git a/libiberty/cp-demangle.c b/libiberty/cp-demangle.c
index bd64bef8cf7..09d64699466 100644
--- a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -128,6 +128,13 @@ extern char *alloca ();
# endif /* alloca */
#endif /* HAVE_ALLOCA_H */
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#endif
+#ifndef INT_MAX
+# define INT_MAX (int)(((unsigned int) ~0) >> 1) /* 0x7FFFFFFF */
+#endif
+
#include "ansidecl.h"
#include "libiberty.h"
#include "demangle.h"
@@ -398,7 +405,7 @@ d_make_dtor (struct d_info *, enum gnu_v3_dtor_kinds,
struct demangle_component *);
static struct demangle_component *
-d_make_template_param (struct d_info *, long);
+d_make_template_param (struct d_info *, int);
static struct demangle_component *
d_make_sub (struct d_info *, const char *, int);
@@ -421,9 +428,9 @@ static struct demangle_component *d_unqualified_name (struct d_info *);
static struct demangle_component *d_source_name (struct d_info *);
-static long d_number (struct d_info *);
+static int d_number (struct d_info *);
-static struct demangle_component *d_identifier (struct d_info *, long);
+static struct demangle_component *d_identifier (struct d_info *, int);
static struct demangle_component *d_operator_name (struct d_info *);
@@ -1119,7 +1126,7 @@ d_make_dtor (struct d_info *di, enum gnu_v3_dtor_kinds kind,
/* Add a new template parameter. */
static struct demangle_component *
-d_make_template_param (struct d_info *di, long i)
+d_make_template_param (struct d_info *di, int i)
{
struct demangle_component *p;
@@ -1135,7 +1142,7 @@ d_make_template_param (struct d_info *di, long i)
/* Add a new function parameter. */
static struct demangle_component *
-d_make_function_param (struct d_info *di, long i)
+d_make_function_param (struct d_info *di, int i)
{
struct demangle_component *p;
@@ -1620,7 +1627,7 @@ d_unqualified_name (struct d_info *di)
static struct demangle_component *
d_source_name (struct d_info *di)
{
- long len;
+ int len;
struct demangle_component *ret;
len = d_number (di);
@@ -1633,12 +1640,12 @@ d_source_name (struct d_info *di)
/* number ::= [n] <(non-negative decimal integer)> */
-static long
+static int
d_number (struct d_info *di)
{
int negative;
char peek;
- long ret;
+ int ret;
negative = 0;
peek = d_peek_char (di);
@@ -1681,7 +1688,7 @@ d_number_component (struct d_info *di)
/* identifier ::= <(unqualified source code identifier)> */
static struct demangle_component *
-d_identifier (struct d_info *di, long len)
+d_identifier (struct d_info *di, int len)
{
const char *name;
@@ -1702,7 +1709,7 @@ d_identifier (struct d_info *di, long len)
/* Look for something which looks like a gcc encoding of an
anonymous namespace, and replace it with a more user friendly
name. */
- if (len >= (long) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
+ if (len >= (int) ANONYMOUS_NAMESPACE_PREFIX_LEN + 2
&& memcmp (name, ANONYMOUS_NAMESPACE_PREFIX,
ANONYMOUS_NAMESPACE_PREFIX_LEN) == 0)
{
@@ -1870,7 +1877,7 @@ d_java_resource (struct d_info *di)
{
struct demangle_component *p = NULL;
struct demangle_component *next = NULL;
- long len, i;
+ int len, i;
char c;
const char *str;
@@ -2012,7 +2019,7 @@ d_special_name (struct d_info *di)
case 'C':
{
struct demangle_component *derived_type;
- long offset;
+ int offset;
struct demangle_component *base_type;
derived_type = cplus_demangle_type (di);
@@ -2946,10 +2953,10 @@ d_pointer_to_member_type (struct d_info *di)
/* <non-negative number> _ */
-static long
+static int
d_compact_number (struct d_info *di)
{
- long num;
+ int num;
if (d_peek_char (di) == '_')
num = 0;
else if (d_peek_char (di) == 'n')
@@ -2957,7 +2964,7 @@ d_compact_number (struct d_info *di)
else
num = d_number (di) + 1;
- if (! d_check_char (di, '_'))
+ if (num < 0 || ! d_check_char (di, '_'))
return -1;
return num;
}
@@ -2969,7 +2976,7 @@ d_compact_number (struct d_info *di)
static struct demangle_component *
d_template_param (struct d_info *di)
{
- long param;
+ int param;
if (! d_check_char (di, 'T'))
return NULL;
@@ -3171,9 +3178,10 @@ d_expression_1 (struct d_info *di)
}
else
{
- index = d_compact_number (di) + 1;
- if (index == 0)
+ index = d_compact_number (di);
+ if (index == INT_MAX || index == -1)
return NULL;
+ index++;
}
return d_make_function_param (di, index);
}
@@ -3502,7 +3510,7 @@ d_local_name (struct d_info *di)
static int
d_discriminator (struct d_info *di)
{
- long discrim;
+ int discrim;
if (d_peek_char (di) != '_')
return 1;
@@ -3558,7 +3566,7 @@ static struct demangle_component *
d_unnamed_type (struct d_info *di)
{
struct demangle_component *ret;
- long num;
+ int num;
if (! d_check_char (di, 'U'))
return NULL;
@@ -4086,10 +4094,10 @@ d_append_string (struct d_print_info *dpi, const char *s)
}
static inline void
-d_append_num (struct d_print_info *dpi, long l)
+d_append_num (struct d_print_info *dpi, int l)
{
char buf[25];
- sprintf (buf,"%ld", l);
+ sprintf (buf,"%d", l);
d_append_string (dpi, buf);
}
diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c
index 7514e57913c..d04c32a904a 100644
--- a/libiberty/cplus-dem.c
+++ b/libiberty/cplus-dem.c
@@ -244,6 +244,7 @@ typedef enum type_kind_t
tk_none,
tk_pointer,
tk_reference,
+ tk_rvalue_reference,
tk_integral,
tk_bool,
tk_char,
@@ -2042,7 +2043,8 @@ demangle_template_value_parm (struct work_stuff *work, const char **mangled,
}
else if (tk == tk_real)
success = demangle_real_value (work, mangled, s);
- else if (tk == tk_pointer || tk == tk_reference)
+ else if (tk == tk_pointer || tk == tk_reference
+ || tk == tk_rvalue_reference)
{
if (**mangled == 'Q')
success = demangle_qualified (work, mangled, s,
@@ -3588,6 +3590,14 @@ do_type (struct work_stuff *work, const char **mangled, string *result)
tk = tk_reference;
break;
+ /* An rvalue reference type */
+ case 'O':
+ (*mangled)++;
+ string_prepend (&decl, "&&");
+ if (tk == tk_none)
+ tk = tk_rvalue_reference;
+ break;
+
/* An array */
case 'A':
{
@@ -3645,7 +3655,6 @@ do_type (struct work_stuff *work, const char **mangled, string *result)
break;
case 'M':
- case 'O':
{
type_quals = TYPE_UNQUALIFIED;
diff --git a/libiberty/testsuite/demangle-expected b/libiberty/testsuite/demangle-expected
index e214ee5a987..62ab18ca37d 100644
--- a/libiberty/testsuite/demangle-expected
+++ b/libiberty/testsuite/demangle-expected
@@ -31,6 +31,11 @@ ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &, Graphic *)
ArrowLine::ArrowheadIntersects
#
--format=gnu --no-params
+ArrowheadIntersects__9ArrowLineP9ArrowheadO6BoxObjP7Graphic
+ArrowLine::ArrowheadIntersects(Arrowhead *, BoxObj &&, Graphic *)
+ArrowLine::ArrowheadIntersects
+#
+--format=gnu --no-params
AtEnd__13ivRubberGroup
ivRubberGroup::AtEnd(void)
ivRubberGroup::AtEnd
@@ -51,6 +56,11 @@ TextCode::CoreConstDecls(ostream &)
TextCode::CoreConstDecls
#
--format=gnu --no-params
+CoreConstDecls__8TextCodeO7ostream
+TextCode::CoreConstDecls(ostream &&)
+TextCode::CoreConstDecls
+#
+--format=gnu --no-params
Detach__8StateVarP12StateVarView
StateVar::Detach(StateVarView *)
StateVar::Detach
@@ -66,21 +76,41 @@ RelateManip::Effect(ivEvent &)
RelateManip::Effect
#
--format=gnu --no-params
+Effect__11RelateManipO7ivEvent
+RelateManip::Effect(ivEvent &&)
+RelateManip::Effect
+#
+--format=gnu --no-params
FindFixed__FRP4CNetP4CNet
FindFixed(CNet *&, CNet *)
FindFixed
#
--format=gnu --no-params
+FindFixed__FOP4CNetP4CNet
+FindFixed(CNet *&&, CNet *)
+FindFixed
+#
+--format=gnu --no-params
Fix48_abort__FR8twolongs
Fix48_abort(twolongs &)
Fix48_abort
#
--format=gnu --no-params
+Fix48_abort__FO8twolongs
+Fix48_abort(twolongs &&)
+Fix48_abort
+#
+--format=gnu --no-params
GetBarInfo__15iv2_6_VScrollerP13ivPerspectiveRiT2
iv2_6_VScroller::GetBarInfo(ivPerspective *, int &, int &)
iv2_6_VScroller::GetBarInfo
#
--format=gnu --no-params
+GetBarInfo__15iv2_6_VScrollerP13ivPerspectiveOiT2
+iv2_6_VScroller::GetBarInfo(ivPerspective *, int &&, int &&)
+iv2_6_VScroller::GetBarInfo
+#
+--format=gnu --no-params
GetBgColor__C9ivPainter
ivPainter::GetBgColor(void) const
ivPainter::GetBgColor
@@ -986,11 +1016,21 @@ List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &)
List<VHDLEntity>::Pix::Pix
#
--format=gnu --no-params
+__Q2t4List1Z10VHDLEntity3PixOCQ2t4List1Z10VHDLEntity3Pix
+List<VHDLEntity>::Pix::Pix(List<VHDLEntity>::Pix const &&)
+List<VHDLEntity>::Pix::Pix
+#
+--format=gnu --no-params
__Q2t4List1Z10VHDLEntity7elementRC10VHDLEntityPT0
List<VHDLEntity>::element::element(VHDLEntity const &, List<VHDLEntity>::element *)
List<VHDLEntity>::element::element
#
--format=gnu --no-params
+__Q2t4List1Z10VHDLEntity7elementOC10VHDLEntityPT0
+List<VHDLEntity>::element::element(VHDLEntity const &&, List<VHDLEntity>::element *)
+List<VHDLEntity>::element::element
+#
+--format=gnu --no-params
__Q2t4List1Z10VHDLEntity7elementRCQ2t4List1Z10VHDLEntity7element
List<VHDLEntity>::element::element(List<VHDLEntity>::element const &)
List<VHDLEntity>::element::element
@@ -1036,6 +1076,11 @@ PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHD
PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX
#
--format=gnu --no-params
+__t4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntityOCt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity
+PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > const &&)
+PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> >::PixX
+#
+--format=gnu --no-params
nextE__C11VHDLLibraryRt4PixX3Z11VHDLLibraryZ14VHDLLibraryRepZt4List1Z10VHDLEntity
VHDLLibrary::nextE(PixX<VHDLLibrary, VHDLLibraryRep, List<VHDLEntity> > &) const
VHDLLibrary::nextE
@@ -1261,6 +1306,11 @@ smanip_int::smanip_int(ios &(*)(ios &, int), int)
smanip_int::smanip_int
#
--format=lucid --no-params
+__ct__10smanip_intFPFO3iosi_O3iosi
+smanip_int::smanip_int(ios &&(*)(ios &&, int), int)
+smanip_int::smanip_int
+#
+--format=lucid --no-params
__ct__11fstreambaseFi
fstreambase::fstreambase(int)
fstreambase::fstreambase
@@ -1281,6 +1331,11 @@ smanip_long::smanip_long(ios &(*)(ios &, long), long)
smanip_long::smanip_long
#
--format=lucid --no-params
+__ct__11smanip_longFPFO3iosl_O3iosl
+smanip_long::smanip_long(ios &&(*)(ios &&, long), long)
+smanip_long::smanip_long
+#
+--format=lucid --no-params
__ct__11stdiostreamFP4FILE
stdiostream::stdiostream(FILE *)
stdiostream::stdiostream
@@ -1321,6 +1376,11 @@ foo::foo(foo &)
foo::foo
#
--format=lucid --no-params
+__ct__3fooFO3foo
+foo::foo(foo &&)
+foo::foo
+#
+--format=lucid --no-params
__ct__3fooFi
foo::foo(int)
foo::foo
@@ -1336,6 +1396,11 @@ foo::foo(int, foo &, int, foo &, int, foo &)
foo::foo
#
--format=lucid --no-params
+__ct__3fooFiO3fooT1T2T1T2
+foo::foo(int, foo &&, int, foo &&, int, foo &&)
+foo::foo
+#
+--format=lucid --no-params
__ct__3iosFP9streambuf
ios::ios(streambuf *)
ios::ios
@@ -1811,6 +1876,11 @@ foo(int, foo &, int, foo &, int, foo &)
foo
#
--format=lucid --no-params
+foo__FiO3fooT1T2T1T2
+foo(int, foo &&, int, foo &&, int, foo &&)
+foo
+#
+--format=lucid --no-params
foo___3barFl
bar::foo_(long)
bar::foo_
@@ -2561,6 +2631,11 @@ DListNode<RLabel &>::DListNode(RLabel &, DListNode<RLabel &> *, DListNode<RLabel
DListNode<RLabel &>::DListNode
#
--format=arm --no-params
+__ct__25DListNode__pt__9_O6RLabelFO6RLabelP25DListNode__pt__9_O6RLabelT2
+DListNode<RLabel &&>::DListNode(RLabel &&, DListNode<RLabel &&> *, DListNode<RLabel &&> *)
+DListNode<RLabel &&>::DListNode
+#
+--format=arm --no-params
bar__3fooFiT16FooBar
foo::bar(int, int, FooBar)
foo::bar
@@ -2991,6 +3066,11 @@ DListNode<RLabel &>::DListNode(RLabel &, DListNode<RLabel &> *, DListNode<RLabel
DListNode<RLabel &>::DListNode
#
--format=hp --no-params
+__ct__9DListNodeXTO6RLabel__FO6RLabelP9DListNodeXTO6RLabel_T2
+DListNode<RLabel &&>::DListNode(RLabel &&, DListNode<RLabel &&> *, DListNode<RLabel &&> *)
+DListNode<RLabel &&>::DListNode
+#
+--format=hp --no-params
elem__6vectorXTiUP34__Fi
vector<int,34U>::elem(int)
vector<int,34U>::elem
@@ -3021,16 +3101,31 @@ vector<int,-67,4000U,short &>::elem(int)
vector<int,-67,4000U,short &>::elem
#
--format=hp --no-params
+elem__6vectorXTiSN67UP4000TOs__Fi
+vector<int,-67,4000U,short &&>::elem(int)
+vector<int,-67,4000U,short &&>::elem
+#
+--format=hp --no-params
elem__6vectorXTiSN67TRdTFPv_i__Fi
vector<int,-67,double &,int (void *)>::elem(int)
vector<int,-67,double &,int (void *)>::elem
#
--format=hp --no-params
+elem__6vectorXTiSN67TOdTFPv_i__Fi
+vector<int,-67,double &&,int (void *)>::elem(int)
+vector<int,-67,double &&,int (void *)>::elem
+#
+--format=hp --no-params
X__6vectorXTiSN67TdTPvUP5TRs
vector<int,-67,double,void *,5U,short &>::X
vector<int,-67,double,void *,5U,short &>::X
#
--format=hp --no-params
+X__6vectorXTiSN67TdTPvUP5TOs
+vector<int,-67,double,void *,5U,short &&>::X
+vector<int,-67,double,void *,5U,short &&>::X
+#
+--format=hp --no-params
elem__6vectorXTiA3foo__Fi
vector<int,&foo>::elem(int)
vector<int,&foo>::elem
@@ -3071,6 +3166,11 @@ Spec<int,int &,int>::spec(int *)
Spec<int,int &,int>::spec
#
--format=hp --no-params
+spec__17Spec<#1,#1.&&,#1>XTiTOiTi_FPi
+Spec<int,int &&,int>::spec(int *)
+Spec<int,int &&,int>::spec
+#
+--format=hp --no-params
add__XTc_FcT1
add<char>(char, char)
add<char>
@@ -3101,6 +3201,11 @@ C<Test, Test::output> call<Test>(Test &)
C<Test, Test::output> call<Test>
#
--format=gnu --no-params
+call__H1Z4Test_OX01_t1C2ZX01PMX01FPX01i_vQ2X016output
+C<Test, Test::output> call<Test>(Test &&)
+C<Test, Test::output> call<Test>
+#
+--format=gnu --no-params
fn__FPQ21n1cPMQ21n1cFPQ21n1c_i
fn(n::c *, int (n::c::*)(n::c *))
fn
@@ -3126,6 +3231,11 @@ int foo<TA<int const &, NA<9> > >(TA<int const &, NA<9> >)
int foo<TA<int const &, NA<9> > >
#
--format=gnu --no-params
+foo__H1Zt2TA2ZOCiZt2NA1Ui9_X01_i
+int foo<TA<int const &&, NA<9> > >(TA<int const &&, NA<9> >)
+int foo<TA<int const &&, NA<9> > >
+#
+--format=gnu --no-params
foo__H1Zt2TA2ZcZt2NA1Ui20_X01_i
int foo<TA<char, NA<20> > >(TA<char, NA<20> >)
int foo<TA<char, NA<20> > >
@@ -3402,6 +3512,11 @@ int* const volatile restrict _far
_Z3fooILi2EEvRAplT_Li1E_i
void foo<2>(int (&) [(2)+(1)])
foo<2>
+#
+--format=gnu-v3 --no-params
+_Z3fooILi2EEvOAplT_Li1E_i
+void foo<2>(int (&&) [(2)+(1)])
+foo<2>
#
--format=gnu-v3 --no-params
_Z1fM1AKFvvE
@@ -4422,12 +4537,22 @@ void baz<int>(A<sizeof (foo((int)(), (floatcomplex )00000000_00000000))>*)
_Z3fooI1FEN1XIXszdtcl1PclcvT__EEE5arrayEE4TypeEv
X<sizeof ((P(((F)())())).array)>::Type foo<F>()
#
-# Tests a use-after-free problem
+# Tests a use-after-free problem PR70481
_Q.__0
::Q.(void)
#
-# Tests a use-after-free problem
+# Tests a use-after-free problem PR70481
_Q10-__9cafebabe.
cafebabe.::-(void)
+#
+# Tests integer overflow problem PR70492
+
+__vt_90000000000cafebabe
+__vt_90000000000cafebabe
+#
+# Tests write access violation PR70498
+
+_Z80800000000000000000000
+_Z80800000000000000000000
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index 1268507b92b..063846922b6 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,9 @@
+2016-05-17 Jakub Jelinek <jakub@redhat.com>
+
+ PR sanitizer/71160
+ * asan/asan_malloc_linux.cc: Cherry pick upstream r254395
+ and r269633.
+
2016-04-21 Maxim Ostapenko <m.ostapenko@samsung.com>
PR sanitizer/70624
diff --git a/libsanitizer/asan/asan_malloc_linux.cc b/libsanitizer/asan/asan_malloc_linux.cc
index d03f1bb89c8..bfe72af69e6 100644
--- a/libsanitizer/asan/asan_malloc_linux.cc
+++ b/libsanitizer/asan/asan_malloc_linux.cc
@@ -24,39 +24,62 @@
// ---------------------- Replacement functions ---------------- {{{1
using namespace __asan; // NOLINT
+static uptr allocated_for_dlsym;
+static const uptr kDlsymAllocPoolSize = 1024;
+static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
+
+static bool IsInDlsymAllocPool(const void *ptr) {
+ uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
+ return off < sizeof(alloc_memory_for_dlsym);
+}
+
+static void *AllocateFromLocalPool(uptr size_in_bytes) {
+ uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize;
+ void *mem = (void*)&alloc_memory_for_dlsym[allocated_for_dlsym];
+ allocated_for_dlsym += size_in_words;
+ CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize);
+ return mem;
+}
+
INTERCEPTOR(void, free, void *ptr) {
GET_STACK_TRACE_FREE;
+ if (UNLIKELY(IsInDlsymAllocPool(ptr)))
+ return;
asan_free(ptr, &stack, FROM_MALLOC);
}
INTERCEPTOR(void, cfree, void *ptr) {
GET_STACK_TRACE_FREE;
+ if (UNLIKELY(IsInDlsymAllocPool(ptr)))
+ return;
asan_free(ptr, &stack, FROM_MALLOC);
}
INTERCEPTOR(void*, malloc, uptr size) {
+ if (UNLIKELY(!asan_inited))
+ // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym.
+ return AllocateFromLocalPool(size);
GET_STACK_TRACE_MALLOC;
return asan_malloc(size, &stack);
}
INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
- if (UNLIKELY(!asan_inited)) {
+ if (UNLIKELY(!asan_inited))
// Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
- const uptr kCallocPoolSize = 1024;
- static uptr calloc_memory_for_dlsym[kCallocPoolSize];
- static uptr allocated;
- uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
- void *mem = (void*)&calloc_memory_for_dlsym[allocated];
- allocated += size_in_words;
- CHECK(allocated < kCallocPoolSize);
- return mem;
- }
+ return AllocateFromLocalPool(nmemb * size);
GET_STACK_TRACE_MALLOC;
return asan_calloc(nmemb, size, &stack);
}
INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
GET_STACK_TRACE_MALLOC;
+ if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
+ uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
+ uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
+ void *new_ptr = asan_malloc(size, &stack);
+ internal_memcpy(new_ptr, ptr, copy_size);
+ return new_ptr;
+ }
return asan_realloc(ptr, size, &stack);
}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 39d599291cd..21e51c023b6 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,123 @@
+2016-05-20 Thomas Preud'homme <thomas.preudhomme@arm.com>
+
+ * testsuite/experimental/memory_resource/1.cc: Add required argument
+ to dg-require-atomic-builtins.
+
+2016-05-13 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/71073
+ * include/debug/bitset: Add #pragma GCC system_header.
+ * include/debug/deque: Likewise.
+ * include/debug/list: Likewise.
+ * include/debug/map: Likewise.
+ * include/debug/set: Likewise.
+ * include/debug/string: Likewise.
+ * include/debug/unordered_map: Likewise.
+ * include/debug/unordered_set: Likewise.
+ * include/debug/vector: Likewise.
+ * include/debug/functions.h: Adjust whitespace.
+
+2016-05-12 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/71081
+ * testsuite/experimental/memory_resource/1.cc: Require atomics.
+
+2016-05-11 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/71049
+ * src/c++11/cow-stdexcept.cc [!_GLIBCXX_USE_DUAL_ABI]: Don't define
+ exception constructors with __sso_string parameters.
+
+2016-05-10 Jonathan Wakely <jwakely@redhat.com>
+
+ * include/experimental/bits/fs_dir.h (begin, end): Add noexcept.
+ * testsuite/experimental/filesystem/iterators/directory_iterator.cc:
+ Test begin and end functions.
+ * testsuite/experimental/filesystem/iterators/
+ recursive_directory_iterator.cc: Likewise.
+
+ PR libstdc++/71038
+ * src/filesystem/ops.cc (do_copy_file): Fix backwards conditions.
+ * testsuite/experimental/filesystem/operations/copy_file.cc: New test.
+
+ * include/experimental/bits/fs_dir.h (__directory_iterator_proxy):
+ Overload operator* to move from rvalues.
+
+ PR libstdc++/71036
+ * src/filesystem/ops.cc (create_dir): Handle EEXIST from mkdir.
+ * testsuite/experimental/filesystem/operations/create_directory.cc:
+ New test.
+
+ PR libstdc++/71037
+ * src/filesystem/ops.cc (canonical(const path&, const path&)): Add
+ base path to exception.
+ * testsuite/experimental/filesystem/operations/canonical.cc: Test
+ paths contained in exception.
+
+ * testsuite/experimental/type_erased_allocator/2.cc: Remove unused
+ using declaration.
+
+ PR libstdc++/71005
+ * include/experimental/bits/fs_dir.h (__directory_iterator_proxy):
+ New type.
+ (directory_iterator::operator++(int)): Return proxy.
+ (recursive_directory_iterator::operator++(int)): Likewise.
+ * testsuite/experimental/filesystem/iterators/directory_iterator.cc:
+ Test post-increment.
+ * testsuite/experimental/filesystem/iterators/
+ recursive_directory_iterator.cc: Likewise.
+
+2016-05-09 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/71004
+ * testsuite/experimental/filesystem/iterators/
+ recursive_directory_iterator.cc: Fix test02 to not call member
+ functions on invalid iterator, and use VERIFY not assert.
+
+2016-05-09 Ville Voutilainen <ville.voutilainen@gmail.com>
+
+ Avoid endless run-time recursion for copying single-element
+ tuples where the element type is by-value constructible
+ from any type.
+ * include/std/tuple (_NotSameTuple): New.
+ * include/std/tuple (tuple(_UElements&&...): Use it.
+ * testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc: New.
+
+2016-05-09 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/71004
+ * include/experimental/bits/fs_dir.h (recursive_directory_iterator):
+ Initialize scalar member variables in default constructor.
+ * testsuite/experimental/filesystem/iterators/
+ recursive_directory_iterator.cc: Test default construction.
+
+2016-05-05 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * testsuite/lib/libstdc++.exp (libstdc++_init): Enable on *-*-solaris*.
+
+2016-05-05 Jonathan Wakely <jwakely@redhat.com>
+
+ * testsuite/experimental/filesystem/path/native/string.cc: Add
+ dg-require-filesystem-ts directive.
+
+2016-05-04 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/70940
+ * include/experimental/memory_resource
+ (__resource_adaptor_imp::do_allocate): Do not default-construct
+ rebound allocator.
+ (__resource_adaptor_imp::do_deallocate): Likewise. Use
+ allocator_traits to get pointer type.
+ (__null_memory_resource::do_allocate): Remove unused parameters.
+ (__null_memory_resource::do_deallocate): Likewise.
+ (__null_memory_resource::do_is_equal): Likewise. Add return statement.
+ * testsuite/experimental/type_erased_allocator/1.cc: Combine with ...
+ * testsuite/experimental/type_erased_allocator/1_neg.cc: This, and
+ move to ...
+ * testsuite/experimental/memory_resource/1.cc: Here.
+ * testsuite/experimental/memory_resource/null_memory_resource.cc: New.
+ * testsuite/experimental/memory_resource/resource_adaptor.cc: New.
+
2016-04-29 Chris Gregory <czipperz@gmail.com>
* config/*: Remove trailing whitespace.
diff --git a/libstdc++-v3/include/debug/bitset b/libstdc++-v3/include/debug/bitset
index 706a7b7681e..1353aa38074 100644
--- a/libstdc++-v3/include/debug/bitset
+++ b/libstdc++-v3/include/debug/bitset
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_BITSET
#define _GLIBCXX_DEBUG_BITSET
+#pragma GCC system_header
+
#include <bitset>
#include <debug/safe_sequence.h>
#include <debug/safe_iterator.h>
diff --git a/libstdc++-v3/include/debug/deque b/libstdc++-v3/include/debug/deque
index 72b65368396..f15faadbb7b 100644
--- a/libstdc++-v3/include/debug/deque
+++ b/libstdc++-v3/include/debug/deque
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_DEQUE
#define _GLIBCXX_DEBUG_DEQUE 1
+#pragma GCC system_header
+
#include <deque>
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h
index 547ec5cc127..35e7ae8395a 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -29,11 +29,10 @@
#ifndef _GLIBCXX_DEBUG_FUNCTIONS_H
#define _GLIBCXX_DEBUG_FUNCTIONS_H 1
-#include <bits/move.h> // for __addressof
-#include <bits/stl_function.h> // for less
+#include <bits/move.h> // for __addressof
+#include <bits/stl_function.h> // for less
#if __cplusplus >= 201103L
-# include <type_traits> // for is_lvalue_reference and
- // conditional.
+# include <type_traits> // for is_lvalue_reference and conditional.
#endif
#include <debug/helper_functions.h>
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index f1bfe35e032..09df483e8c1 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_LIST
#define _GLIBCXX_DEBUG_LIST 1
+#pragma GCC system_header
+
#include <list>
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
diff --git a/libstdc++-v3/include/debug/map b/libstdc++-v3/include/debug/map
index 3fa961d2ded..2cce7c0c4bc 100644
--- a/libstdc++-v3/include/debug/map
+++ b/libstdc++-v3/include/debug/map
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_MAP
#define _GLIBCXX_DEBUG_MAP 1
+#pragma GCC system_header
+
#include <map>
#include <debug/map.h>
#include <debug/multimap.h>
diff --git a/libstdc++-v3/include/debug/set b/libstdc++-v3/include/debug/set
index bfe1d36d1e3..82e39003050 100644
--- a/libstdc++-v3/include/debug/set
+++ b/libstdc++-v3/include/debug/set
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_SET
#define _GLIBCXX_DEBUG_SET 1
+#pragma GCC system_header
+
#include <set>
#include <debug/set.h>
#include <debug/multiset.h>
diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
index 7edc6658c0c..137974d724f 100644
--- a/libstdc++-v3/include/debug/string
+++ b/libstdc++-v3/include/debug/string
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_STRING
#define _GLIBCXX_DEBUG_STRING 1
+#pragma GCC system_header
+
#include <string>
#include <debug/safe_sequence.h>
#include <debug/safe_container.h>
diff --git a/libstdc++-v3/include/debug/unordered_map b/libstdc++-v3/include/debug/unordered_map
index cf6c8d44be3..873f36a3499 100644
--- a/libstdc++-v3/include/debug/unordered_map
+++ b/libstdc++-v3/include/debug/unordered_map
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_UNORDERED_MAP
#define _GLIBCXX_DEBUG_UNORDERED_MAP 1
+#pragma GCC system_header
+
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
diff --git a/libstdc++-v3/include/debug/unordered_set b/libstdc++-v3/include/debug/unordered_set
index 203900aa278..6a4dba6475d 100644
--- a/libstdc++-v3/include/debug/unordered_set
+++ b/libstdc++-v3/include/debug/unordered_set
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_UNORDERED_SET
#define _GLIBCXX_DEBUG_UNORDERED_SET 1
+#pragma GCC system_header
+
#if __cplusplus < 201103L
# include <bits/c++0x_warning.h>
#else
diff --git a/libstdc++-v3/include/debug/vector b/libstdc++-v3/include/debug/vector
index d2cd74f0877..9bcda733a70 100644
--- a/libstdc++-v3/include/debug/vector
+++ b/libstdc++-v3/include/debug/vector
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_DEBUG_VECTOR
#define _GLIBCXX_DEBUG_VECTOR 1
+#pragma GCC system_header
+
#include <vector>
#include <utility>
#include <debug/safe_sequence.h>
diff --git a/libstdc++-v3/include/experimental/bits/fs_dir.h b/libstdc++-v3/include/experimental/bits/fs_dir.h
index 4e28c8e9240..70a95ebfe66 100644
--- a/libstdc++-v3/include/experimental/bits/fs_dir.h
+++ b/libstdc++-v3/include/experimental/bits/fs_dir.h
@@ -153,8 +153,25 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
};
struct _Dir;
+ class directory_iterator;
class recursive_directory_iterator;
+ struct __directory_iterator_proxy
+ {
+ const directory_entry& operator*() const& noexcept { return _M_entry; }
+
+ directory_entry operator*() && noexcept { return std::move(_M_entry); }
+
+ private:
+ friend class directory_iterator;
+ friend class recursive_directory_iterator;
+
+ explicit
+ __directory_iterator_proxy(const directory_entry& __e) : _M_entry(__e) { }
+
+ directory_entry _M_entry;
+ };
+
class directory_iterator
{
public:
@@ -177,7 +194,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
: directory_iterator(__p, directory_options::none, __ec) { }
directory_iterator(const path& __p,
- directory_options __options, error_code& __ec) noexcept
+ directory_options __options,
+ error_code& __ec) noexcept
: directory_iterator(__p, __options, &__ec) { }
directory_iterator(const directory_iterator& __rhs) = default;
@@ -186,19 +204,22 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
~directory_iterator() = default;
- directory_iterator& operator=(const directory_iterator& __rhs) = default;
- directory_iterator& operator=(directory_iterator&& __rhs) noexcept = default;
+ directory_iterator&
+ operator=(const directory_iterator& __rhs) = default;
+
+ directory_iterator&
+ operator=(directory_iterator&& __rhs) noexcept = default;
const directory_entry& operator*() const;
const directory_entry* operator->() const { return &**this; }
directory_iterator& operator++();
directory_iterator& increment(error_code& __ec) noexcept;
- directory_iterator operator++(int)
+ __directory_iterator_proxy operator++(int)
{
- auto __tmp = *this;
+ __directory_iterator_proxy __pr{**this};
++*this;
- return __tmp;
+ return __pr;
}
private:
@@ -214,10 +235,12 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
};
inline directory_iterator
- begin(directory_iterator __iter) { return __iter; }
+ begin(directory_iterator __iter) noexcept
+ { return __iter; }
inline directory_iterator
- end(directory_iterator) { return directory_iterator(); }
+ end(directory_iterator) noexcept
+ { return directory_iterator(); }
inline bool
operator==(const directory_iterator& __lhs, const directory_iterator& __rhs)
@@ -274,18 +297,18 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
// modifiers
recursive_directory_iterator&
- operator=(const recursive_directory_iterator& __rhs) noexcept;
+ operator=(const recursive_directory_iterator& __rhs) noexcept;
recursive_directory_iterator&
- operator=(recursive_directory_iterator&& __rhs) noexcept;
+ operator=(recursive_directory_iterator&& __rhs) noexcept;
recursive_directory_iterator& operator++();
recursive_directory_iterator& increment(error_code& __ec) noexcept;
- recursive_directory_iterator operator++(int)
+ __directory_iterator_proxy operator++(int)
{
- auto __tmp = *this;
+ __directory_iterator_proxy __pr{**this};
++*this;
- return __tmp;
+ return __pr;
}
void pop();
@@ -301,15 +324,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
struct _Dir_stack;
std::shared_ptr<_Dir_stack> _M_dirs;
- directory_options _M_options;
- bool _M_pending;
+ directory_options _M_options = {};
+ bool _M_pending = false;
};
inline recursive_directory_iterator
- begin(recursive_directory_iterator __iter) { return __iter; }
+ begin(recursive_directory_iterator __iter) noexcept
+ { return __iter; }
inline recursive_directory_iterator
- end(recursive_directory_iterator) { return recursive_directory_iterator(); }
+ end(recursive_directory_iterator) noexcept
+ { return recursive_directory_iterator(); }
inline bool
operator==(const recursive_directory_iterator& __lhs,
diff --git a/libstdc++-v3/include/experimental/memory_resource b/libstdc++-v3/include/experimental/memory_resource
index ccdf5e66b01..ea8afb89e02 100644
--- a/libstdc++-v3/include/experimental/memory_resource
+++ b/libstdc++-v3/include/experimental/memory_resource
@@ -282,7 +282,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_t __new_size = _S_aligned_size(__bytes,
_S_supported(__alignment) ?
__alignment : _S_max_align);
- return _Aligned_alloc().allocate(__new_size);
+ return _Aligned_alloc(_M_alloc).allocate(__new_size);
}
virtual void
@@ -292,9 +292,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_t __new_size = _S_aligned_size(__bytes,
_S_supported(__alignment) ?
__alignment : _S_max_align);
- _Aligned_alloc().deallocate(static_cast<typename
- _Aligned_alloc::pointer>(__p),
- __new_size);
+ using _Ptr = typename allocator_traits<_Aligned_alloc>::pointer;
+ _Aligned_alloc(_M_alloc).deallocate(static_cast<_Ptr>(__p),
+ __new_size);
}
virtual bool
@@ -306,8 +306,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
// Calculate Aligned Size
- // Returns a size that is larger than or equal to __size and divided by
- // __alignment, where __alignment is required to be the power of 2.
+ // Returns a size that is larger than or equal to __size and divisible
+ // by __alignment, where __alignment is required to be the power of 2.
static size_t
_S_aligned_size(size_t __size, size_t __alignment)
{ return ((__size - 1)|(__alignment - 1)) + 1; }
@@ -342,16 +342,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
protected:
void*
- do_allocate(size_t __bytes, size_t __alignment)
+ do_allocate(size_t, size_t)
{ std::__throw_bad_alloc(); }
void
- do_deallocate(void* __p, size_t __bytes, size_t __alignment)
+ do_deallocate(void*, size_t, size_t) noexcept
{ }
bool
do_is_equal(const memory_resource& __other) const noexcept
- { }
+ { return this == &__other; }
friend memory_resource* null_memory_resource() noexcept;
};
diff --git a/libstdc++-v3/include/std/tuple b/libstdc++-v3/include/std/tuple
index 53f318455be..7522e435184 100644
--- a/libstdc++-v3/include/std/tuple
+++ b/libstdc++-v3/include/std/tuple
@@ -500,6 +500,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__not_<is_constructible<_Elements..., _SrcTuple>>
>::value;
}
+ template<typename... _UElements>
+ static constexpr bool _NotSameTuple()
+ {
+ return __not_<is_same<tuple<_Elements...>,
+ typename remove_const<
+ typename remove_reference<_UElements...>::type
+ >::type>>::value;
+ }
};
template<typename... _Elements>
@@ -534,6 +542,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
return true;
}
+ template<typename... _UElements>
+ static constexpr bool _NotSameTuple()
+ {
+ return true;
+ }
};
/// Primary class template, tuple
@@ -611,7 +624,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Elements...>;
template<typename... _UElements, typename
- enable_if<_TMC<_UElements...>::template
+ enable_if<
+ _TC<sizeof...(_UElements) == 1, _Elements...>::template
+ _NotSameTuple<_UElements...>()
+ && _TMC<_UElements...>::template
_MoveConstructibleTuple<_UElements...>()
&& _TMC<_UElements...>::template
_ImplicitlyMoveConvertibleTuple<_UElements...>()
@@ -621,7 +637,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _Inherited(std::forward<_UElements>(__elements)...) { }
template<typename... _UElements, typename
- enable_if<_TMC<_UElements...>::template
+ enable_if<
+ _TC<sizeof...(_UElements) == 1, _Elements...>::template
+ _NotSameTuple<_UElements...>()
+ && _TMC<_UElements...>::template
_MoveConstructibleTuple<_UElements...>()
&& !_TMC<_UElements...>::template
_ImplicitlyMoveConvertibleTuple<_UElements...>()
diff --git a/libstdc++-v3/src/c++11/cow-stdexcept.cc b/libstdc++-v3/src/c++11/cow-stdexcept.cc
index a0f505c2187..31a89dfd554 100644
--- a/libstdc++-v3/src/c++11/cow-stdexcept.cc
+++ b/libstdc++-v3/src/c++11/cow-stdexcept.cc
@@ -292,6 +292,7 @@ _txnal_cow_string_c_str(const void* that)
return (const char*) txnal_read_ptr((void**)&bs->_M_dataplus._M_p);
}
+#if _GLIBCXX_USE_DUAL_ABI
const char*
_txnal_sso_string_c_str(const void* that)
{
@@ -299,6 +300,7 @@ _txnal_sso_string_c_str(const void* that)
(void* const*)const_cast<char* const*>(
&((const std::__sso_string*) that)->_M_s._M_p));
}
+#endif
void
_txnal_cow_string_D1_commit(void* data)
@@ -344,9 +346,24 @@ _txnal_runtime_error_get_msg(void* e)
// result in undefined behavior, which is in this case not initializing this
// string.
#if _GLIBCXX_USE_DUAL_ABI
-#define CTORDTORSTRINGCSTR(s) _txnal_sso_string_c_str((s))
+#define CTORS_FROM_SSOSTRING(NAME, CLASS, BASE) \
+void \
+_ZGTtNSt##NAME##C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
+ CLASS* that, const std::__sso_string& s) \
+{ \
+ CLASS e(""); \
+ _ITM_memcpyRnWt(that, &e, sizeof(CLASS)); \
+ /* Get the C string from the SSO string. */ \
+ _txnal_cow_string_C1_for_exceptions(_txnal_##BASE##_get_msg(that), \
+ _txnal_sso_string_c_str(&s), that); \
+} \
+void \
+_ZGTtNSt##NAME##C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
+ CLASS*, const std::__sso_string&) __attribute__((alias \
+("_ZGTtNSt" #NAME \
+ "C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE")));
#else
-#define CTORDTORSTRINGCSTR(s) ""
+#define CTORS_FROM_SSOSTRING(NAME, CLASS, BASE)
#endif
// This macro defines transaction constructors and destructors for a specific
@@ -373,21 +390,7 @@ _ZGTtNSt##NAME##C1EPKc (CLASS* that, const char* s) \
void \
_ZGTtNSt##NAME##C2EPKc (CLASS*, const char*) \
__attribute__((alias ("_ZGTtNSt" #NAME "C1EPKc"))); \
-void \
-_ZGTtNSt##NAME##C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
- CLASS* that, const std::__sso_string& s) \
-{ \
- CLASS e(""); \
- _ITM_memcpyRnWt(that, &e, sizeof(CLASS)); \
- /* Get the C string from the SSO string. */ \
- _txnal_cow_string_C1_for_exceptions(_txnal_##BASE##_get_msg(that), \
- CTORDTORSTRINGCSTR(&s), that); \
-} \
-void \
-_ZGTtNSt##NAME##C2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE( \
- CLASS*, const std::__sso_string&) __attribute__((alias \
-("_ZGTtNSt" #NAME \
- "C1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"))); \
+CTORS_FROM_SSOSTRING(NAME, CLASS, BASE) \
void \
_ZGTtNSt##NAME##D1Ev(CLASS* that) \
{ _txnal_cow_string_D1(_txnal_##BASE##_get_msg(that)); } \
diff --git a/libstdc++-v3/src/filesystem/ops.cc b/libstdc++-v3/src/filesystem/ops.cc
index aa26cafa103..5b82088891e 100644
--- a/libstdc++-v3/src/filesystem/ops.cc
+++ b/libstdc++-v3/src/filesystem/ops.cc
@@ -220,8 +220,9 @@ fs::canonical(const path& p, const path& base)
{
error_code ec;
path can = canonical(p, base, ec);
- if (ec.value())
- _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot canonicalize", p, ec));
+ if (ec)
+ _GLIBCXX_THROW_OR_ABORT(filesystem_error("cannot canonicalize", p, base,
+ ec));
return can;
}
@@ -449,7 +450,7 @@ namespace
ec = std::make_error_code(std::errc::io_error);
return false;
}
- if (sbout.close() || sbin.close())
+ if (!sbout.close() || !sbin.close())
{
ec.assign(errno, std::generic_category());
return false;
@@ -659,22 +660,26 @@ namespace
bool
create_dir(const fs::path& p, fs::perms perm, std::error_code& ec)
{
+ bool created = false;
#ifdef _GLIBCXX_HAVE_SYS_STAT_H
::mode_t mode = static_cast<std::underlying_type_t<fs::perms>>(perm);
if (::mkdir(p.c_str(), mode))
{
- ec.assign(errno, std::generic_category());
- return false;
+ const int err = errno;
+ if (err != EEXIST || !is_directory(p))
+ ec.assign(err, std::generic_category());
+ else
+ ec.clear();
}
else
{
ec.clear();
- return true;
+ created = true;
}
#else
ec = std::make_error_code(std::errc::not_supported);
- return false;
#endif
+ return created;
}
} // namespace
diff --git a/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc b/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc
new file mode 100644
index 00000000000..fe9bea678a4
--- /dev/null
+++ b/libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc
@@ -0,0 +1,30 @@
+// Copyright (C) 2016 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/>.
+
+#include <tuple>
+using namespace std;
+
+struct Something {
+ Something() { }
+ template <typename T> Something(T) { }
+};
+
+int main() {
+ tuple<Something> t1;
+ tuple<Something> t2 = t1;
+}
+
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc
index 28b948f2b12..ffd97ce19d2 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/iterators/directory_iterator.cc
@@ -70,8 +70,79 @@ test01()
remove_all(p, ec);
}
+void
+test02()
+{
+ bool test __attribute__((unused)) = false;
+
+ std::error_code ec;
+ const auto p = __gnu_test::nonexistent_path();
+ create_directory(p, fs::current_path(), ec);
+ create_directory_symlink(p, p / "l", ec);
+ VERIFY( !ec );
+
+ // Test post-increment (libstdc++/71005)
+ auto iter = fs::directory_iterator(p, ec);
+ VERIFY( !ec );
+ VERIFY( iter != fs::directory_iterator() );
+ const auto entry1 = *iter;
+ const auto entry2 = *iter++;
+ VERIFY( entry1 == entry2 );
+ VERIFY( entry1.path() == p/"l" );
+ VERIFY( iter == fs::directory_iterator() );
+
+ remove_all(p, ec);
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = false;
+
+ std::error_code ec;
+ const auto p = __gnu_test::nonexistent_path();
+ create_directories(p / "longer_than_small_string_buffer", ec);
+ VERIFY( !ec );
+
+ // Test for no reallocation on each dereference (this is a GNU extension)
+ auto iter = fs::directory_iterator(p, ec);
+ const auto* s1 = iter->path().c_str();
+ const auto* s2 = iter->path().c_str();
+ VERIFY( s1 == s2 );
+
+ remove_all(p, ec);
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = false;
+
+ const fs::directory_iterator it;
+ VERIFY( it == fs::directory_iterator() );
+}
+
+void
+test05()
+{
+ bool test __attribute__((unused)) = false;
+
+ auto p = __gnu_test::nonexistent_path();
+ create_directory(p);
+ create_directory_symlink(p, p / "l");
+ fs::directory_iterator it(p), endit;
+ VERIFY( begin(it) == it );
+ static_assert( noexcept(begin(it)), "begin is noexcept" );
+ VERIFY( end(it) == endit );
+ static_assert( noexcept(end(it)), "end is noexcept" );
+}
+
int
main()
{
test01();
+ test02();
+ test03();
+ test04();
+ test05();
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
index 5d2e45b2e64..b44ff3f9e9b 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
@@ -97,8 +97,83 @@ test01()
remove_all(p, ec);
}
+void
+test02()
+{
+ bool test __attribute__((unused)) = false;
+
+ std::error_code ec;
+ const auto p = __gnu_test::nonexistent_path();
+ create_directories(p / "d1/d2", ec);
+ VERIFY( !ec );
+
+ // Test post-increment (libstdc++/71005)
+ auto iter = fs::recursive_directory_iterator(p, ec);
+ VERIFY( !ec );
+ VERIFY( iter != fs::recursive_directory_iterator() );
+ const auto entry1 = *iter;
+ const auto entry2 = *iter++;
+ VERIFY( entry1 == entry2 );
+ VERIFY( entry1.path() == p/"d1" );
+ const auto entry3 = *iter;
+ const auto entry4 = *iter++;
+ VERIFY( entry3 == entry4 );
+ VERIFY( entry3.path() == p/"d1/d2" );
+ VERIFY( iter == fs::recursive_directory_iterator() );
+
+ remove_all(p, ec);
+}
+
+void
+test03()
+{
+ bool test __attribute__((unused)) = false;
+
+ std::error_code ec;
+ const auto p = __gnu_test::nonexistent_path();
+ create_directories(p / "longer_than_small_string_buffer", ec);
+ VERIFY( !ec );
+
+ // Test for no reallocation on each dereference (this is a GNU extension)
+ auto iter = fs::recursive_directory_iterator(p, ec);
+ const auto* s1 = iter->path().c_str();
+ const auto* s2 = iter->path().c_str();
+ VERIFY( s1 == s2 );
+
+ remove_all(p, ec);
+}
+
+void
+test04()
+{
+ bool test __attribute__((unused)) = false;
+
+ // libstdc++/71004
+ const fs::recursive_directory_iterator it;
+ VERIFY( it == fs::recursive_directory_iterator() );
+}
+
+void
+test05()
+{
+ bool test __attribute__((unused)) = false;
+
+ auto p = __gnu_test::nonexistent_path();
+ create_directory(p);
+ create_directory_symlink(p, p / "l");
+ fs::recursive_directory_iterator it(p), endit;
+ VERIFY( begin(it) == it );
+ static_assert( noexcept(begin(it)), "begin is noexcept" );
+ VERIFY( end(it) == endit );
+ static_assert( noexcept(end(it)), "end is noexcept" );
+}
+
int
main()
{
test01();
+ test02();
+ test03();
+ test04();
+ test05();
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/canonical.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/canonical.cc
index e13c4bfe0a5..5b4c573eebf 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/operations/canonical.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/canonical.cc
@@ -59,8 +59,28 @@ test01()
VERIFY( !ec );
}
+void
+test02()
+{
+#if __cpp_exceptions
+ bool test __attribute__((unused)) = false;
+
+ fs::path p = "rel", base = __gnu_test::nonexistent_path();
+ fs::path e1, e2;
+ try {
+ canonical(p, base);
+ } catch (const fs::filesystem_error& e) {
+ e1 = e.path1();
+ e2 = e.path2();
+ }
+ VERIFY( e1 == p );
+ VERIFY( e2 == base );
+#endif
+}
+
int
main()
{
test01();
+ test02();
}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/copy_file.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/copy_file.cc
new file mode 100644
index 00000000000..cdb79111351
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/copy_file.cc
@@ -0,0 +1,82 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11 -lstdc++fs" }
+// { dg-require-filesystem-ts "" }
+
+// 15.4 Copy [fs.op.copy_file]
+
+#include <experimental/filesystem>
+#include <fstream>
+#include <testsuite_fs.h>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = false;
+ using std::experimental::filesystem::copy_options;
+ std::error_code ec;
+
+ auto from = __gnu_test::nonexistent_path();
+ auto to = __gnu_test::nonexistent_path();
+
+ // test non-existent file
+ bool b = copy_file(from, to, ec);
+ VERIFY( !b );
+ VERIFY( ec );
+ VERIFY( !exists(to) );
+
+ // test empty file
+ std::ofstream{from.native()};
+ VERIFY( exists(from) );
+ VERIFY( file_size(from) == 0 );
+
+ b = copy_file(from, to);
+ VERIFY( b );
+ VERIFY( exists(to) );
+ VERIFY( file_size(to) == 0 );
+ remove(to);
+ VERIFY( !exists(to) );
+ b = copy_file(from, to, copy_options::none, ec);
+ VERIFY( b );
+ VERIFY( !ec );
+ VERIFY( exists(to) );
+ VERIFY( file_size(to) == 0 );
+
+ std::ofstream{from.native()} << "Hello, filesystem!";
+ VERIFY( file_size(from) != 0 );
+ remove(to);
+ VERIFY( !exists(to) );
+ b = copy_file(from, to);
+ VERIFY( b );
+ VERIFY( exists(to) );
+ VERIFY( file_size(to) == file_size(from) );
+ remove(to);
+ VERIFY( !exists(to) );
+ b = copy_file(from, to);
+ VERIFY( b );
+ VERIFY( !ec );
+ VERIFY( exists(to) );
+ VERIFY( file_size(to) == file_size(from) );
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc b/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc
new file mode 100644
index 00000000000..66c2b3fb796
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/filesystem/operations/create_directory.cc
@@ -0,0 +1,63 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11 -lstdc++fs" }
+// { dg-require-filesystem-ts "" }
+
+#include <experimental/filesystem>
+#include <testsuite_hooks.h>
+#include <testsuite_fs.h>
+
+namespace fs = std::experimental::filesystem;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = false;
+ std::error_code ec;
+
+ // Test empty path.
+ fs::path p;
+ bool b = create_directory( p, ec );
+ VERIFY( ec );
+ VERIFY( !b );
+
+ // Test non-existent path
+ p = __gnu_test::nonexistent_path();
+ VERIFY( !exists(p) );
+
+ b = create_directory(p, ec); // create the directory once
+ VERIFY( !ec );
+ VERIFY( b );
+ VERIFY( exists(p) );
+
+ // Test existing path (libstdc++/71036).
+ b = create_directory(p, ec);
+ VERIFY( !ec );
+ VERIFY( !b );
+ b = create_directory(p);
+ VERIFY( !ec );
+ VERIFY( !b );
+
+ remove_all(p, ec);
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc b/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
index 05ff57c59a6..e56fda7b95f 100644
--- a/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
+++ b/libstdc++-v3/testsuite/experimental/filesystem/path/native/string.cc
@@ -16,6 +16,7 @@
// <http://www.gnu.org/licenses/>.
// { dg-options "-std=gnu++11 -lstdc++fs" }
+// { dg-require-filesystem-ts "" }
#include <experimental/filesystem>
#include <string>
diff --git a/libstdc++-v3/testsuite/experimental/type_erased_allocator/1.cc b/libstdc++-v3/testsuite/experimental/memory_resource/1.cc
index 924d728aa4e..08c02e5e31b 100644
--- a/libstdc++-v3/testsuite/experimental/type_erased_allocator/1.cc
+++ b/libstdc++-v3/testsuite/experimental/memory_resource/1.cc
@@ -1,4 +1,5 @@
// { dg-options "-std=gnu++14" }
+// { dg-require-atomic-builtins "" }
// Copyright (C) 2015-2016 Free Software Foundation, Inc.
//
@@ -17,9 +18,9 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include <memory>
#include <experimental/memory_resource>
#include <vector>
+#include <cstdlib>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
@@ -36,6 +37,7 @@ struct A
static int ctor_count;
static int dtor_count;
};
+
int A::ctor_count = 0;
int A::dtor_count = 0;
@@ -43,7 +45,7 @@ struct CountedResource : public memory_resource
{
public:
CountedResource() = default;
- ~ CountedResource() = default;
+ ~CountedResource() = default;
static size_t get_alloc_count() { return alloc_count; }
static size_t get_dalloc_count() { return dalloc_count; }
@@ -54,23 +56,23 @@ protected:
void* do_allocate(size_t bytes, size_t alignment)
{
alloc_count += bytes;
- if (auto ptr = std::malloc(bytes)) {
+ if (auto ptr = std::malloc(bytes))
return ptr;
- }
throw std::bad_alloc();
}
void do_deallocate(void *p, size_t bytes, size_t alignment)
{
dalloc_count += bytes;
- free(p);
+ std::free(p);
}
bool do_is_equal(const memory_resource& __other) const noexcept
{ return this == &__other; }
};
- size_t CountedResource::alloc_count = 0;
- size_t CountedResource::dalloc_count = 0;
+
+size_t CountedResource::alloc_count = 0;
+size_t CountedResource::dalloc_count = 0;
void clear()
{
@@ -81,8 +83,11 @@ void clear()
}
// memory resource
-void test01()
+void
+test01()
{
+ bool test __attribute((unused)) = false;
+
memory_resource* r = new_delete_resource();
VERIFY(get_default_resource() == r);
void *p = get_default_resource()->allocate(5);
@@ -101,8 +106,11 @@ void test01()
}
// polymorphic_allocator
-void test02()
+void
+test02()
{
+ bool test __attribute((unused)) = false;
+
clear();
{
CountedResource cr;
@@ -115,7 +123,11 @@ void test02()
VERIFY(CountedResource::get_dalloc_count() == 5);
}
-void test03() {
+void
+test03()
+{
+ bool test __attribute((unused)) = false;
+
clear();
CountedResource cr;
polymorphic_allocator<A> pa(&cr);
@@ -129,7 +141,11 @@ void test03() {
VERIFY(CountedResource::get_dalloc_count() == 1);
}
-void test04() {
+void
+test04()
+{
+ bool test __attribute((unused)) = false;
+
polymorphic_allocator<A> pa1(get_default_resource());
polymorphic_allocator<A> pa2(get_default_resource());
VERIFY(pa1 == pa2);
@@ -137,10 +153,10 @@ void test04() {
VERIFY(pa1 == pa3);
}
-int main() {
+int main()
+{
test01();
test02();
test03();
test04();
- return 0;
}
diff --git a/libstdc++-v3/testsuite/experimental/type_erased_allocator/1_neg.cc b/libstdc++-v3/testsuite/experimental/memory_resource/null_memory_resource.cc
index ce45dbf7c2f..c84436a2eba 100644
--- a/libstdc++-v3/testsuite/experimental/type_erased_allocator/1_neg.cc
+++ b/libstdc++-v3/testsuite/experimental/memory_resource/null_memory_resource.cc
@@ -1,7 +1,6 @@
-// { dg-do run { xfail *-*-* } }
// { dg-options "-std=gnu++14" }
-// Copyright (C) 2015-2016 Free Software Foundation, Inc.
+// Copyright (C) 2016 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
@@ -20,17 +19,34 @@
#include <experimental/memory_resource>
#include <testsuite_hooks.h>
-#include <testsuite_allocator.h>
-using std::experimental::pmr::polymorphic_allocator;
-using std::experimental::pmr::null_memory_resource;
using std::experimental::pmr::memory_resource;
+using std::experimental::pmr::null_memory_resource;
+using std::experimental::pmr::new_delete_resource;
+
+// null_memory_resource
+void
+test06()
+{
+ bool test __attribute((unused)) = false;
-void test01() {
memory_resource* r = null_memory_resource();
- auto p = r->allocate(1);
+ bool caught = false;
+
+ void* p = nullptr;
+ try {
+ p = r->allocate(1);
+ } catch (const std::bad_alloc&) {
+ caught = true;
+ }
+ VERIFY( caught );
+
+ VERIFY( *r == *r );
+ VERIFY( r->is_equal(*r) );
+ VERIFY( !r->is_equal(*new_delete_resource()) );
}
-int main() {
- test01();
+int main()
+{
+ test06();
}
diff --git a/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc b/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc
new file mode 100644
index 00000000000..299bb72ea4b
--- /dev/null
+++ b/libstdc++-v3/testsuite/experimental/memory_resource/resource_adaptor.cc
@@ -0,0 +1,87 @@
+// { dg-options "-std=gnu++14" }
+
+// Copyright (C) 2016 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/>.
+
+#include <experimental/memory_resource>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+using std::experimental::pmr::memory_resource;
+using std::experimental::pmr::resource_adaptor;
+
+template<typename T>
+ struct Allocator : __gnu_test::SimpleAllocator<T>
+ {
+ Allocator(int) { } // not default constructible
+
+ template<typename U>
+ Allocator(const Allocator<U>&) { }
+ };
+
+template<typename T>
+ bool aligned(void* p)
+ {
+ return (reinterpret_cast<std::uintptr_t>(p) % alignof(T)) == 0;
+ }
+
+// resource_adaptor
+void
+test05()
+{
+ bool test __attribute((unused)) = false;
+ using std::max_align_t;
+ using std::uintptr_t;
+ void* p = nullptr;
+
+ Allocator<int> a1(1), a2(2); // minimal interface allocators
+ resource_adaptor<decltype(a1)> r1(a1), r2(a2);
+ VERIFY( r1 == r1 );
+ VERIFY( r1 == r2 );
+ p = r1.allocate(1);
+ VERIFY( aligned<max_align_t>(p) );
+ r1.deallocate(p, 1);
+ p = r1.allocate(1, alignof(short));
+ VERIFY( aligned<short>(p) );
+ r1.deallocate(p, 1, alignof(short));
+ p = r1.allocate(1, alignof(long));
+ VERIFY( aligned<long>(p) );
+ r1.deallocate(p, 1, alignof(long));
+
+ __gnu_test::uneq_allocator<double> a3(3), a4(4); // non-equal allocators
+ resource_adaptor<decltype(a3)> r3(a3), r4(a4);
+ VERIFY( r3 == r3 );
+ VERIFY( r4 == r4 );
+ VERIFY( r3 != r4 );
+ p = r3.allocate(1);
+ VERIFY( aligned<max_align_t>(p) );
+ r3.deallocate(p, 1);
+ p = r3.allocate(1, alignof(short));
+ VERIFY( aligned<short>(p) );
+ r3.deallocate(p, 1, alignof(short));
+ p = r3.allocate(1, alignof(long));
+ VERIFY( aligned<long>(p) );
+ r3.deallocate(p, 1, alignof(long));
+
+ // TODO test with an allocator that doesn't use new or malloc, so
+ // returns pointers that are not suitably aligned for any type.
+}
+
+int main()
+{
+ test05();
+}
diff --git a/libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc b/libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc
index 8f7d0b5d24b..4460498c2e3 100644
--- a/libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc
+++ b/libstdc++-v3/testsuite/experimental/type_erased_allocator/2.cc
@@ -17,9 +17,9 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-#include <memory>
#include <experimental/memory_resource>
#include <experimental/utility>
+#include <memory>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
@@ -27,7 +27,6 @@ using std::experimental::pmr::polymorphic_allocator;
using std::experimental::pmr::memory_resource;
using std::experimental::pmr::new_delete_resource;
using std::experimental::pmr::get_default_resource;
-using std::experimental::pmr::set_default_resource;
using std::allocator_arg_t;
enum CtorType { Default, Copy, Move, Other, Tuple, Piecewise_Default, Piecewise_Copy};
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index 9a930de166f..0f7f6d0f29b 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -184,8 +184,9 @@ proc libstdc++_init { testfile } {
set v3-sharedlib 0
set sharedlibdir [lookfor_file $blddir src/.libs/libstdc++.$shlib_ext]
if {$sharedlibdir != ""} {
- if { ([string match "*-*-linux*" $target_triplet]
- || [string match "*-*-gnu*" $target_triplet])
+ if { ([string match "*-*-gnu*" $target_triplet]
+ || [string match "*-*-linux*" $target_triplet]
+ || [string match "*-*-solaris*" $target_triplet])
&& [isnative] } then {
set v3-sharedlib 1
verbose -log "shared library support detected"
diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog
index c6c75d39b03..4c9dda4a0a8 100644
--- a/libvtv/ChangeLog
+++ b/libvtv/ChangeLog
@@ -1,3 +1,10 @@
+2016-05-02 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * Makefile.am (toolexeclib_LTLIBRARIES): Only set if
+ ENABLE_VTABLE_VERIFY.
+ Simplify.
+ * Makefile.in: Regenerate.
+
2015-12-02 Matthias Klose <doko@ubuntu.com>
* configure.ac: Move AM_ENABLE_MULTILIB before
diff --git a/libvtv/Makefile.am b/libvtv/Makefile.am
index edfd5ae13d7..8c47d1afade 100644
--- a/libvtv/Makefile.am
+++ b/libvtv/Makefile.am
@@ -38,10 +38,11 @@ AM_CXXFLAGS = $(XCFLAGS)
AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
AM_CXXFLAGS += -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end
-if VTV_CYGMIN
- toolexeclib_LTLIBRARIES = libvtv.la libvtv_stubs.la
-else
+if ENABLE_VTABLE_VERIFY
toolexeclib_LTLIBRARIES = libvtv.la
+if VTV_CYGMIN
+ toolexeclib_LTLIBRARIES += libvtv_stubs.la
+endif
endif
vtv_headers = \
diff --git a/libvtv/Makefile.in b/libvtv/Makefile.in
index 4c8c3fb078e..05539277d92 100644
--- a/libvtv/Makefile.in
+++ b/libvtv/Makefile.in
@@ -53,7 +53,8 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-@ENABLE_VTABLE_VERIFY_TRUE@@VTV_NO_OBSTACK_TRUE@am__append_1 = obstack.c
+@ENABLE_VTABLE_VERIFY_TRUE@@VTV_CYGMIN_TRUE@am__append_1 = libvtv_stubs.la
+@ENABLE_VTABLE_VERIFY_TRUE@@VTV_NO_OBSTACK_TRUE@am__append_2 = obstack.c
subdir = .
DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/configure $(am__configure_deps) \
@@ -119,8 +120,8 @@ libvtv_la_OBJECTS = $(am_libvtv_la_OBJECTS)
libvtv_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libvtv_la_LDFLAGS) $(LDFLAGS) -o $@
-@VTV_CYGMIN_FALSE@am_libvtv_la_rpath = -rpath $(toolexeclibdir)
-@VTV_CYGMIN_TRUE@am_libvtv_la_rpath = -rpath $(toolexeclibdir)
+@ENABLE_VTABLE_VERIFY_TRUE@am_libvtv_la_rpath = -rpath \
+@ENABLE_VTABLE_VERIFY_TRUE@ $(toolexeclibdir)
libvtv_stubs_la_LIBADD =
am__objects_3 = vtv_start.lo vtv_stubs.lo vtv_end.lo
@ENABLE_VTABLE_VERIFY_TRUE@@VTV_CYGMIN_TRUE@am_libvtv_stubs_la_OBJECTS = \
@@ -129,7 +130,9 @@ libvtv_stubs_la_OBJECTS = $(am_libvtv_stubs_la_OBJECTS)
libvtv_stubs_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libvtv_stubs_la_LDFLAGS) $(LDFLAGS) -o $@
-@VTV_CYGMIN_TRUE@am_libvtv_stubs_la_rpath = -rpath $(toolexeclibdir)
+@ENABLE_VTABLE_VERIFY_TRUE@@VTV_CYGMIN_TRUE@am_libvtv_stubs_la_rpath = \
+@ENABLE_VTABLE_VERIFY_TRUE@@VTV_CYGMIN_TRUE@ -rpath \
+@ENABLE_VTABLE_VERIFY_TRUE@@VTV_CYGMIN_TRUE@ $(toolexeclibdir)
DEFAULT_INCLUDES = -I.@am__isrc@
depcomp = $(SHELL) $(top_srcdir)/../depcomp
am__depfiles_maybe = depfiles
@@ -323,8 +326,8 @@ AM_CFLAGS = $(XCFLAGS)
AM_CCASFLAGS = $(XCFLAGS)
AM_CXXFLAGS = $(XCFLAGS) $(LIBSTDCXX_RAW_CXX_CXXFLAGS) \
-Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end
-@VTV_CYGMIN_FALSE@toolexeclib_LTLIBRARIES = libvtv.la
-@VTV_CYGMIN_TRUE@toolexeclib_LTLIBRARIES = libvtv.la libvtv_stubs.la
+@ENABLE_VTABLE_VERIFY_TRUE@toolexeclib_LTLIBRARIES = libvtv.la \
+@ENABLE_VTABLE_VERIFY_TRUE@ $(am__append_1)
vtv_headers = \
vtv_map.h \
vtv_malloc.h \
@@ -354,7 +357,7 @@ BUILT_SOURCES = vtv_start.c vtv_end.c
@VTV_CYGMIN_TRUE@libvtv_stubs_la_LDFLAGS = $(lt_host_flags)
@ENABLE_VTABLE_VERIFY_FALSE@libvtv_la_SOURCES =
@ENABLE_VTABLE_VERIFY_TRUE@libvtv_la_SOURCES = $(vtv_sources) \
-@ENABLE_VTABLE_VERIFY_TRUE@ $(am__append_1)
+@ENABLE_VTABLE_VERIFY_TRUE@ $(am__append_2)
@ENABLE_VTABLE_VERIFY_TRUE@@VTV_CYGMIN_TRUE@libvtv_stubs_la_SOURCES = $(vtv_stubs_sources)
@ENABLE_VTABLE_VERIFY_FALSE@libvtv_include_HEADERS =
@ENABLE_VTABLE_VERIFY_TRUE@libvtv_include_HEADERS = $(vtv_headers)