aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Macleod <amacleod@redhat.com>2016-05-10 03:30:56 +0000
committerAndrew Macleod <amacleod@redhat.com>2016-05-10 03:30:56 +0000
commit357ceb7fe26970b6c6e12f0bb2ceecab6c6a2454 (patch)
tree48eb1f57289f4e995f069f38213ad5c8a16f0347
parent5ed230ef2005822d6402118e58a311db2a9cb0c7 (diff)
parent8a50780e586342528692744150d08651fb07fb43 (diff)
update to 2016-05-09ttype-2016-05-03
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/ttype-2016-05-03@236057 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog4
-rw-r--r--MAINTAINERS1
-rw-r--r--gcc/ChangeLog1104
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog17
-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/builtins.c42
-rw-r--r--gcc/c-family/ChangeLog13
-rw-r--r--gcc/c-family/c-common.c73
-rw-r--r--gcc/c-family/c-common.h3
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/ChangeLog24
-rw-r--r--gcc/c/c-parser.c10
-rw-r--r--gcc/c/c-typeck.c9
-rw-r--r--gcc/cfgcleanup.c122
-rw-r--r--gcc/cfgexpand.c2
-rw-r--r--gcc/cgraph.c35
-rw-r--r--gcc/cgraph.h32
-rw-r--r--gcc/cgraphclones.c2
-rw-r--r--gcc/cgraphunit.c3
-rw-r--r--gcc/cif-code.def8
-rw-r--r--gcc/combine.c2
-rw-r--r--gcc/config.gcc54
-rw-r--r--gcc/config.in6
-rw-r--r--gcc/config/arm/arm.md10
-rw-r--r--gcc/config/arm/vfp.md52
-rw-r--r--gcc/config/i386/i386-protos.h1
-rw-r--r--gcc/config/i386/i386.c20
-rw-r--r--gcc/config/i386/i386.md494
-rw-r--r--gcc/config/i386/predicates.md18
-rw-r--r--gcc/config/i386/sse.md354
-rw-r--r--gcc/config/mips/constraints.md55
-rw-r--r--gcc/config/mips/i6400.md177
-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.h86
-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/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/freebsd64.h5
-rw-r--r--gcc/config/rs6000/linux64.h5
-rw-r--r--gcc/config/rs6000/predicates.md7
-rw-r--r--gcc/config/rs6000/rs6000.c217
-rw-r--r--gcc/config/rs6000/rs6000.h13
-rw-r--r--gcc/config/rs6000/rs6000.md6
-rw-r--r--gcc/config/rs6000/sysv4.h36
-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.md423
-rw-r--r--gcc/config/sh/sh.opt16
-rw-r--r--gcc/config/sol2.h13
-rwxr-xr-xgcc/configure20
-rw-r--r--gcc/configure.ac8
-rw-r--r--gcc/coretypes.h25
-rw-r--r--gcc/cp/ChangeLog22
-rw-r--r--gcc/cp/call.c3
-rw-r--r--gcc/cp/decl.c3
-rw-r--r--gcc/cp/parser.c4
-rw-r--r--gcc/cp/tree.c10
-rw-r--r--gcc/doc/extend.texi862
-rw-r--r--gcc/doc/invoke.texi111
-rw-r--r--gcc/doc/sourcebuild.texi3
-rw-r--r--gcc/dwarf2out.c4
-rw-r--r--gcc/fold-const.c107
-rw-r--r--gcc/fortran/ChangeLog98
-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.c13
-rw-r--r--gcc/fortran/gfortran.h23
-rw-r--r--gcc/fortran/gfortran.texi261
-rw-r--r--gcc/fortran/interface.c215
-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.c72
-rw-r--r--gcc/function.c213
-rw-r--r--gcc/fwprop.c11
-rw-r--r--gcc/gcc.c9
-rw-r--r--gcc/genattr-common.c2
-rw-r--r--gcc/genattr.c2
-rw-r--r--gcc/genattrtab.c2
-rw-r--r--gcc/genautomata.c4
-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/genmddeps.c2
-rw-r--r--gcc/genmddump.c5
-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.c3
-rw-r--r--gcc/gimplify.c20
-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.cc347
-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/input.c10
-rw-r--r--gcc/input.h1
-rw-r--r--gcc/ipa-inline-analysis.c133
-rw-r--r--gcc/ipa-inline.c15
-rw-r--r--gcc/ipa-pure-const.c102
-rw-r--r--gcc/ira.c16
-rw-r--r--gcc/lto-cgraph.c2
-rw-r--r--gcc/lto/ChangeLog4
-rw-r--r--gcc/lto/lto-symtab.c5
-rw-r--r--gcc/match.pd113
-rw-r--r--gcc/opts.c1
-rw-r--r--gcc/pass_manager.h6
-rw-r--r--gcc/passes.c34
-rw-r--r--gcc/read-md.c2
-rw-r--r--gcc/read-md.h2
-rw-r--r--gcc/regrename.c55
-rw-r--r--gcc/shrink-wrap.c171
-rw-r--r--gcc/shrink-wrap.h6
-rw-r--r--gcc/testsuite/ChangeLog180
-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/builtin_location.c57
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/builtin_location.C175
-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/gcc.dg/Waddress-2.c24
-rw-r--r--gcc/testsuite/gcc.dg/graphite/pr70956.c4
-rw-r--r--gcc/testsuite/gcc.dg/ipa/inline-8.c1
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pure-const-3.c24
-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/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/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/ubsan/bounds-3.c22
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr57206.c11
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr61194.c2
-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/i386/avx512bw-vpmaddwd-3.c24
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512bw-vpsraw-3.c44
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512f-vfmadd-1.c27
-rw-r--r--gcc/testsuite/gcc.target/i386/avx512vl-vmovq-1.c16
-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/mips/mips16-attributes.c1
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr70866.c11
-rw-r--r--gcc/testsuite/gcc.target/powerpc/savres.c22
-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.f9062
-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/pr70931.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/pr70937.f9010
-rw-r--r--gcc/testsuite/gfortran.fortran-torture/compile/pr70960.f9010
-rw-r--r--gcc/testsuite/gnat.dg/debug5.adb22
-rw-r--r--gcc/tree-affine.c2
-rw-r--r--gcc/tree-core.h4
-rw-r--r--gcc/tree-if-conv.c140
-rw-r--r--gcc/tree-inline.c45
-rw-r--r--gcc/tree-ssa-coalesce.c30
-rw-r--r--gcc/tree-ssa-loop-unswitch.c6
-rw-r--r--gcc/tree-ssa-structalias.c2
-rw-r--r--gcc/tree-ssa-tail-merge.c3
-rw-r--r--gcc/tree-ssa-uninit.c401
-rw-r--r--gcc/tree.c12
-rw-r--r--gcc/ubsan.c1
-rw-r--r--libcilkrts/ChangeLog128
-rw-r--r--libcilkrts/Makefile.am35
-rw-r--r--libcilkrts/Makefile.in131
-rw-r--r--libcilkrts/README6
-rw-r--r--libcilkrts/configure2636
-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/po/ChangeLog4
-rw-r--r--libcpp/po/nl.po21
-rw-r--r--libstdc++-v3/ChangeLog51
-rw-r--r--libstdc++-v3/include/experimental/bits/fs_dir.h4
-rw-r--r--libstdc++-v3/include/experimental/memory_resource18
-rw-r--r--libstdc++-v3/include/std/tuple23
-rw-r--r--libstdc++-v3/testsuite/20_util/tuple/cons/element_accepts_anything_byval.cc30
-rw-r--r--libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc11
-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)41
-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/lib/libstdc++.exp5
376 files changed, 26886 insertions, 7918 deletions
diff --git a/ChangeLog b/ChangeLog
index 53a176695fb..eac1cc639ab 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+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.
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/gcc/ChangeLog b/gcc/ChangeLog
index 095e502adfa..0cd95344f1b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,1092 @@
+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")
@@ -13,8 +1102,7 @@
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.
+ *truncxfsf2_mixed, *truncxfdf2_mixed): Use v constraint instead of x.
2016-05-03 Richard Biener <rguenther@suse.de>
@@ -31,15 +1119,12 @@
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.
+ (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_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_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
@@ -141,7 +1226,7 @@
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>
+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.
@@ -2328,6 +3413,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 fbff49dd1e0..7aaf7de3afd 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20160503
+20160509
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index a48c2f5f6f1..7cd2d413b6a 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,20 @@
+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/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/builtins.c b/gcc/builtins.c
index 7d876199bca..476feb1eb16 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -8011,6 +8011,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. */
@@ -8021,6 +8054,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:
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index b34e8ed82c9..e1ba43945c6 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,16 @@
+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
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index d45bf1b67f6..63a18c866eb 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -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;
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index b1211384589..4454d084724 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 *);
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 05bfa7cbc6f..bdc6ee0f83b 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.
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index ae6275968c6..49c9064854f 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,27 @@
+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
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index 701ab45ff89..6523c08d63f 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)
{
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 0fa96539b95..861aa12ae2d 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -3046,7 +3046,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. */
@@ -11066,7 +11067,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 +11088,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,
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 6e92d4cdde2..726c068eceb 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,98 @@ 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
+ && 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..77a1964d4c0 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -4473,7 +4473,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))
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 3105aec8255..0c6ff93d625 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);
@@ -1996,6 +2004,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)
@@ -2279,7 +2289,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
@@ -2291,9 +2301,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);
@@ -2304,7 +2319,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
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 5ce032e1e57..8ad9f456a22 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -2299,6 +2299,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 +3097,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 +3105,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 +3126,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 +3147,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..43ee7352e5b 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -338,6 +338,7 @@ 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;
+ e->inline_failed = CIF_THUNK;
symtab->call_edge_duplication_hooks (thunk->callees, e);
symtab->call_cgraph_duplication_hooks (thunk, new_thunk);
return new_thunk;
@@ -435,6 +436,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;
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 57618807c49..4bfcad78f59 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -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 97a285857f4..f112e962aad 100644
--- a/gcc/cif-code.def
+++ b/gcc/cif-code.def
@@ -92,8 +92,12 @@ DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FINAL_ERROR,
N_("mismatched arguments"))
/* Caller and callee disagree on the arguments. */
-DEFCIFCODE(THUNK, CIF_FINAL_ERROR,
- N_("thunk call"))
+DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR,
+ N_("mismatched declarations during linktime optimization"))
+
+/* Caller is thunk. */
+DEFCIFCODE(THUNK, CIF_FINAL_ERROR,
+ N_("thunk call"))
/* Call was originally indirect. */
DEFCIFCODE(ORIGINALLY_INDIRECT_CALL, CIF_FINAL_NORMAL,
diff --git a/gcc/combine.c b/gcc/combine.c
index 0ab3f97db69..3554f515582 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),
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/arm/arm.md b/gcc/config/arm/arm.md
index 47171b99682..7cf87efd70a 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")))
@@ -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/vfp.md b/gcc/config/arm/vfp.md
index ac5f3b862b5..6edea802b3b 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -394,8 +394,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 +410,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 +461,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 +478,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/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..05476f37449 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -11219,6 +11219,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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index be7cfbfd64e..9b5407aa697 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -1024,6 +1024,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")])
@@ -2696,34 +2699,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"))]
@@ -3072,14 +3072,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")
@@ -3601,19 +3597,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")
@@ -3621,19 +3608,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
@@ -3777,20 +3755,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]);")
@@ -3828,7 +3804,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]);
@@ -3875,7 +3852,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]);
@@ -3988,8 +3966,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)));
}
@@ -4030,8 +4008,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])"
@@ -4052,19 +4030,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)));
@@ -4203,15 +4181,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
@@ -4231,12 +4209,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)
@@ -4253,13 +4231,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
@@ -4267,7 +4243,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
@@ -4283,21 +4259,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)
{
@@ -4316,18 +4291,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")
@@ -4370,9 +4343,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)
;
@@ -4392,12 +4365,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)
@@ -4415,9 +4388,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]);
@@ -4434,15 +4405,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)
@@ -4455,7 +4425,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)
{
@@ -4549,7 +4519,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
@@ -5155,11 +5125,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)"
@@ -5178,83 +5148,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));
})
@@ -5299,7 +5269,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
@@ -5631,7 +5601,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")
@@ -5639,7 +5608,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))
{
@@ -5688,7 +5657,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"))
@@ -5737,32 +5711,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")
@@ -5780,6 +5728,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")
@@ -6264,7 +6230,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)"
"#"
@@ -6286,7 +6252,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)"
@@ -6312,8 +6278,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])))"
@@ -6336,8 +6302,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]))"
"#"
@@ -7201,7 +7167,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)
@@ -8247,7 +8213,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")
@@ -8270,7 +8235,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"))
@@ -8346,7 +8316,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]);
@@ -8754,7 +8725,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")
@@ -8767,7 +8737,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"
@@ -9258,8 +9233,7 @@
[(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
(use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
(clobber (reg:CC FLAGS_REG))]
- "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
- || TARGET_80387"
+ "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
"#"
[(set (attr "enabled")
(if_then_else
@@ -9308,12 +9282,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]);
@@ -9332,7 +9306,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))]
@@ -9356,7 +9330,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))]
@@ -9394,7 +9368,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))]
@@ -9404,8 +9378,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);
@@ -9546,7 +9519,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")))]
@@ -9569,7 +9541,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"
@@ -9988,7 +9965,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")
@@ -10044,7 +10020,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"))
@@ -10091,31 +10072,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.
@@ -10123,15 +10094,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
@@ -11078,20 +11049,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
@@ -11103,20 +11073,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
@@ -11129,20 +11098,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>"
@@ -14063,9 +14031,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])
@@ -17239,7 +17207,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")
@@ -17295,7 +17263,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")
@@ -17845,7 +17813,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
@@ -17866,7 +17834,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)
@@ -17887,7 +17855,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
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index b3a471d8b76..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")
@@ -133,6 +123,14 @@
(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")))
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 42d553cfdaa..411f78e0ede 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -1076,10 +1076,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"
@@ -3327,10 +3327,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)
@@ -4735,9 +4735,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"
@@ -4949,6 +4949,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 +4993,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 +5092,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 +5786,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 +5804,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 +5831,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 +5849,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 +5893,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 +5998,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 +6029,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 +6042,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 +6261,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 +6292,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 +6330,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 +6345,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 +6383,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 +6399,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 +6414,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 +6457,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,v, 0,0, v,m, 0 , m")
(match_operand:SF 2 "vector_move_operand"
- " Yr,*x,x, m,m, m,C,*ym, C")))]
+ " Yr,*x,v, 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 +6479,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 +6500,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 +6512,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>"
@@ -6613,9 +6655,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 +6666,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 +6707,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 +7281,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 +7295,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 +7374,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 +7392,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 +7404,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 +7480,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 +7536,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 +7554,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 +7640,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 +7695,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 +7713,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 +8304,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 +8331,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,v,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 +8357,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 +8388,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 +8449,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 +8469,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 +8505,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 +8538,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 +8551,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 +8580,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>"
@@ -9803,19 +9859,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 +9892,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 +9923,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 +9948,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 +10130,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 +10163,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 +10500,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 +10585,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")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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/mips-cpus.def b/gcc/config/mips/mips-cpus.def
index 17034f2ea95..5df9807b192 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..1efa61a6ede 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -472,6 +472,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 +830,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 +848,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 +1182,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 +1326,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 +1498,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 +1575,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 +1686,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 +1817,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 +1909,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 +1942,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 +2409,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 +2641,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 +2803,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/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/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..3b40e3ad953 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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 61d39242b39..34495f3c99d 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -1755,6 +1755,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
@@ -8633,6 +8636,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)
@@ -20665,7 +20702,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)
@@ -23422,6 +23460,15 @@ 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)
@@ -23431,15 +23478,6 @@ rs6000_savres_strategy (rs6000_stack_t *info,
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
@@ -23452,6 +23490,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.
@@ -23689,9 +23733,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)
@@ -23856,7 +23900,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;
@@ -24712,7 +24758,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
@@ -24722,22 +24768,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
@@ -24752,79 +24804,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;
}
@@ -31334,13 +31354,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],");
@@ -31348,20 +31367,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;
@@ -31938,7 +31966,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);
@@ -31968,7 +31997,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);
@@ -32010,7 +32040,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 ())
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 12fa7275cdc..9647106fbcd 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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
@@ -2058,7 +2050,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)
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 5566185076a..ed1989cd2a6 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));
diff --git a/gcc/config/rs6000/sysv4.h b/gcc/config/rs6000/sysv4.h
index cbf909722da..46d2b4bcdbc 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)))
@@ -941,9 +946,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/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 2d9502b7aa7..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
@@ -3359,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")
@@ -4820,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
@@ -5065,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
@@ -5090,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)
@@ -5100,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)
@@ -5145,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)
@@ -5169,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" "")
@@ -5242,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>"
@@ -5261,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.
@@ -5346,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.
@@ -5444,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 */
@@ -5456,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
@@ -5465,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))"
@@ -5493,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")
@@ -5896,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
@@ -5914,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
@@ -5959,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)
@@ -6007,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)
@@ -6057,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..319dcc3125e 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -904,6 +904,7 @@ enable_decimal_float
enable_fixed_point
enable_threads
enable_tls
+enable_vtable_verify
enable_objc_gc
with_dwarf2
enable_shared
@@ -1619,6 +1620,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
@@ -7591,6 +7593,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 +18474,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 18477 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -18564,7 +18580,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 18583 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/gcc/configure.ac b/gcc/configure.ac
index e40d82a8306..d55f8458943 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -865,6 +865,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 2932d73e261..b3a91a6d5c5 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -361,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 497bc0ec967..9006b341a7a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,25 @@
+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
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 476e806d419..e9ebdbc171d 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7790,7 +7790,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;
}
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 5f9031f0664..8dbc730f3a6 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11422,7 +11422,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;
}
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index c4941a05996..f4c6f74b3d0 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -10951,7 +10951,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 +10978,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;
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index d7e9c7b8048..57fc5c1c54c 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;
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index daf1297350d..e4d6c1c88be 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8929,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
@@ -8943,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:
@@ -8985,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
@@ -11091,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})
@@ -11420,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::
@@ -13530,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
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index f5413faf116..a54a0af77b8 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
@@ -1050,7 +1052,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
@@ -3976,46 +3978,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 +5110,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 +6272,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 +8579,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
@@ -19779,6 +19784,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
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/dwarf2out.c b/gcc/dwarf2out.c
index 463863dc381..fb3f7b9eb3c 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -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;
}
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 0004f789d53..8aabe2155fa 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -836,11 +836,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 +862,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 +2759,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);
@@ -11719,9 +11720,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)))))
@@ -11749,88 +11748,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;
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index e1958be6b14..f683869f8c3 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,101 @@
+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):
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..6ebe08b7538 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,7 @@ gfc_default_initializer (gfc_typespec *ts)
if (comp->initializer)
{
+ 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/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..9d7d3d4b34b 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,218 @@ 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
+ integer(2) w, x, y, z
+ end map
+ map
+ integer(4) wx, yz
+ end map
+end union
+end structure
+
+record /myunion/ rec
+! After these assignments...
+rec.wx = z'0DEDBEEF'
+rec.y = z'0BAD'
+rec.z = z'0FAD'
+
+! The following is true:
+! rec.w === z'0DED'
+! rec.x === z'BEEF'
+! rec.yz === z'0BAD0FAD'
+@end smallexample
+
+The two maps share memory, and the size of the union is ultimately six bytes
+(subject to alignment):
+
+@example
+0 1 2 3 4 5 6 Byte offset
+-------------------------------
+| | | | | | |
+-------------------------------
+
+^ W0 ^ W1 ^ W2 ^
+ \-------/ \-------/ \-------/
+
+^ LONG ^ unused ^
+ \-----------------/ \-------/
+@end example
+
+Following is an example mirroring the layout of an Intel x86_64 register:
+
+@example
+structure /reg/
+ union ! rax
+ map
+ integer*8 rx ! rax
+ end map
+ map
+ integer*4 rh ! rah
+ union ! eax
+ map
+ integer*4 rl ! ral
+ end map
+ map
+ integer*4 ex ! eax
+ end map
+ map
+ integer*2 eh ! eah
+ union ! ax
+ map
+ integer*2 el ! eal
+ end map
+ map
+ integer*2 x ! ax
+ end map
+ map
+ integer*1 h ! ah
+ integer*1 l ! al
+ end map
+ end union ! ax
+ end map
+ end union ! eax
+ end map
+ end union ! rax
+end structure
+
+record /reg/ a
+
+! After this assignment...
+a.rx = z'AABBCCCCFFFFFFFF'
+
+! The following is true:
+!
+! a.rx == z'AABBCCCCFFFFFFFF'
+! a.rh == z'FFFFFFFF'
+! a.rl == z'AABBCCCC'
+!
+! a.ex == z'AABBCCCC'
+! a.eh == z'CCCC'
+! a.el == z'AABB'
+!
+! a.x == z'AABB'
+! a.h == z'BB'
+! a.l == z'AA'
+@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 +2525,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..b981e7c0991 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))
{
@@ -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 e6c5b8e8e91..0079d6cd422 100644
--- a/gcc/fortran/trans-types.c
+++ b/gcc/fortran/trans-types.c
@@ -1102,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);
@@ -2315,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
@@ -2350,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
@@ -2492,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;
@@ -2521,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..70584b95586 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,135 +5768,6 @@ 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;
-}
-
-/* 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)
-{
- int i;
- basic_block bb;
- edge_iterator ei;
- edge e;
- auto_vec<basic_block> src_bbs (EDGE_COUNT (last_bb->preds));
-
- FOR_EACH_EDGE (e, ei, last_bb->preds)
- if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
- src_bbs.quick_push (e->src);
-
- rtx_insn *label = BB_HEAD (last_bb);
-
- FOR_EACH_VEC_ELT (src_bbs, i, bb)
- {
- rtx_insn *jump = BB_END (bb);
-
- if (!JUMP_P (jump) || JUMP_LABEL (jump) != label)
- continue;
-
- e = find_edge (bb, last_bb);
-
- /* 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);
- }
-
- /* 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;
-
- 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;
- }
-
- /* See comment in simplejump_p case above. */
- emit_use_return_register_into_block (bb);
-
- /* 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;
- }
-
- /* 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;
-}
-
-/* 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;
-
- 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;
-}
-
/* Generate the prologue and epilogue RTL if the machine supports it. Thread
this into place with notes indicating where the prologue ends and where
@@ -5993,7 +5821,6 @@ 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;
@@ -6088,40 +5915,8 @@ thread_prologue_and_epilogue_insns (void)
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;
- }
- }
- }
+ if (targetm.have_return () && exit_fallthru_edge == NULL)
+ 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
@@ -6229,10 +6024,6 @@ epilogue_done:
}
}
- if (targetm.have_simple_return ())
- convert_to_simple_return (entry_edge, orig_entry_edge, bb_flags,
- returnjump, unconverted_simple_returns);
-
/* Emit sibling epilogues before any sibling call sites. */
for (ei = ei_start (EXIT_BLOCK_PTR_FOR_FN (cfun)->preds); (e =
ei_safe_edge (ei));
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..656a9a72b06 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;
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..dcde604f190 100644
--- a/gcc/genautomata.c
+++ b/gcc/genautomata.c
@@ -9300,7 +9300,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 +9592,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/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/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.c b/gcc/gimple.c
index 25d965cead2..1a22e8235f1 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -1355,7 +1355,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)
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 9fe9bd5ed89..f13980d80be 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -2437,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:
;
}
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..01f6e23183c 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-46b108136c0d102f181f0cc7c398e3db8c4d08a3
+7f5a9fde801eb755a5252fd4ff588b0a47475bd3
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..4a5c46c5522
--- /dev/null
+++ b/gcc/go/gofrontend/escape.cc
@@ -0,0 +1,347 @@
+// 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;
+ }
+}
+
+// Discover strongly connected groups of functions to analyze.
+
+void
+Gogo::discover_analysis_sets()
+{
+ // TODO(cmang): Implement Analysis_set discovery traversal.
+ // Escape_analysis_discover(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/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/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 4fbc2eddace..17b21d17c5f 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -1490,19 +1490,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
@@ -2916,67 +2920,70 @@ 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. */
+ /* Estimate the stack size for the function if we're optimizing. */
+ 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;
+
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->callees->inline_failed = CIF_THUNK;
node->local.can_change_signature = false;
- es->call_stmt_time = 1;
- es->call_stmt_size = 1;
- account_size_time (info, 0, 0, &t);
- return;
+ es->call_stmt_size = INLINE_SIZE_SCALE;
+ es->call_stmt_time = INLINE_TIME_SCALE;
+ account_size_time (info, INLINE_SIZE_SCALE * 2, INLINE_TIME_SCALE * 2, &t);
+ inline_update_overall_summary (node);
+ info->self_size = info->size;
+ info->self_time = info->time;
+ /* We can not inline instrumetnation clones. */
+ info->inlinable = !node->thunk.add_pointer_bounds_args;
}
-
- /* 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;
- 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
{
- /* 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);
-
+ /* 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;
@@ -2993,8 +3000,6 @@ compute_inline_parameters (struct cgraph_node *node, bool early)
gcc_assert (info->time == info->self_time
&& info->size == info->self_size);
}
-
- pop_cfun ();
}
@@ -4107,17 +4112,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 ();
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index d520c556d43..a5c5c9b382b 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -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 = e->caller->thunk.thunk_p ? CIF_THUNK : 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)
@@ -529,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;
@@ -2741,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-pure-const.c b/gcc/ipa-pure-const.c
index 63fbf581c71..ba76275a696 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -927,8 +927,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
@@ -1222,6 +1220,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);
@@ -1274,26 +1273,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.
@@ -1506,9 +1485,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:
@@ -1520,9 +1512,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:
@@ -1723,11 +1726,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;
@@ -1806,11 +1812,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 " : "",
@@ -1819,25 +1820,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",
@@ -1847,15 +1846,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 d383a551370..55b4bd700be 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -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/lto-cgraph.c b/gcc/lto-cgraph.c
index 95c446d0696..14302138efa 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -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)
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index b1421cbe733..80ffba329ad 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,7 @@
+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-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/match.pd b/gcc/match.pd
index 8de8858b151..e511e9a6b9b 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -685,11 +685,12 @@ 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))))))
@@ -787,12 +788,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)
@@ -3234,3 +3229,101 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
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/opts.c b/gcc/opts.c
index 649b84b3f6f..0f9431a0b32 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 },
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/read-md.c b/gcc/read-md.c
index b5beb4ac9da..6c588781978 100644
--- a/gcc/read-md.c
+++ b/gcc/read-md.c
@@ -1063,7 +1063,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..fc3b077325b 100644
--- a/gcc/read-md.h
+++ b/gcc/read-md.h
@@ -150,7 +150,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/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/shrink-wrap.c b/gcc/shrink-wrap.c
index fe795196709..0ba1fedf161 100644
--- a/gcc/shrink-wrap.c
+++ b/gcc/shrink-wrap.c
@@ -946,10 +946,9 @@ 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))
@@ -958,7 +957,18 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *bb_with,
e->flags &= ~EDGE_FALLTHRU;
if (!(e->flags & EDGE_SIBCALL))
- e->flags |= EDGE_FAKE;
+ {
+ rtx_insn *ret = targetm.gen_simple_return ();
+ rtx_insn *end = BB_END (e->src);
+ rtx_jump_insn *start = emit_jump_insn_after (ret, end);
+ JUMP_LABEL (start) = simple_return_rtx;
+ e->flags &= ~EDGE_FAKE;
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Made simple_return with UID %d in bb %d\n",
+ INSN_UID (start), e->src->index);
+ }
emit_barrier_after_bb (e->src);
}
@@ -996,156 +1006,3 @@ try_shrink_wrapping (edge *entry_edge, bitmap_head *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..4d821d73499 100644
--- a/gcc/shrink-wrap.h
+++ b/gcc/shrink-wrap.h
@@ -26,12 +26,6 @@ along with GCC; see the file COPYING3. If not see
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);
#define SHRINK_WRAPPING_ENABLED \
(flag_shrink_wrap && targetm.have_simple_return ())
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 3ff4ea4d8f8..29a9709e6ca 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,183 @@
+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.
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/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/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/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/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/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/ipa/inline-8.c b/gcc/testsuite/gcc.dg/ipa/inline-8.c
index 962906443c9..df4a64deff9 100644
--- a/gcc/testsuite/gcc.dg/ipa/inline-8.c
+++ b/gcc/testsuite/gcc.dg/ipa/inline-8.c
@@ -5,6 +5,7 @@
/* { 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)
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/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/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/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/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/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/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/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/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-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/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-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-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/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/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/savres.c b/gcc/testsuite/gcc.target/powerpc/savres.c
index f472f23e728..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)
@@ -1063,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;
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..3bf6d618a8e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/dec_union_4.f90
@@ -0,0 +1,62 @@
+! { 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
+ integer(8) rx
+ end map
+ map
+ integer(4) rh ! rah
+ union ! U1
+ map
+ integer(4) rl ! ral
+ end map
+ map
+ integer(4) ex ! eax
+ end map
+ map
+ integer(2) eh ! eah
+ union ! U2
+ map
+ integer(2) el ! eal
+ end map
+ map
+ integer(2) x ! ax
+ end map
+ map
+ integer(1) h ! ah
+ integer(1) l ! al
+ end map
+ end union
+ end map
+ end union
+ end map
+ end union
+end structure
+record /s4/ r4
+
+
+! Nested unions
+r4.rx = z'7A7B7CCC7FFFFFFF'
+if ( r4.rx .ne. z'7A7B7CCC7FFFFFFF' ) call aborts ("rax")
+if ( r4.rh .ne. z'7FFFFFFF' ) call aborts ("rah")
+if ( r4.rl .ne. z'7A7B7CCC' ) call aborts ("ral")
+if ( r4.ex .ne. z'7A7B7CCC' ) call aborts ("eax")
+if ( r4.eh .ne. z'7CCC' ) call aborts ("eah")
+if ( r4.el .ne. z'7A7B' ) call aborts ("eal")
+if ( r4.x .ne. z'7A7B' ) call aborts ("ax")
+if ( r4.h .ne. z'7B' ) call aborts ("ah")
+if ( r4.l .ne. z'7A' ) 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/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.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/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-core.h b/gcc/tree-core.h
index 6d573d7b6d2..ea832fa5344 100644
--- a/gcc/tree-core.h
+++ b/gcc/tree-core.h
@@ -767,7 +767,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.
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 72dca985d74..c38e21b32ce 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,6 +115,7 @@ 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. */
@@ -717,6 +720,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:
@@ -764,8 +866,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))
@@ -776,16 +883,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;
}
@@ -2360,7 +2462,7 @@ ifcvt_split_critical_edges (struct loop *loop, bool aggressive_if_conv)
gimple *stmt;
edge e;
edge_iterator ei;
- vec<edge> critical_edges = vNULL;
+ auto_vec<edge> critical_edges;
/* Loop is not well formed. */
if (num <= 2 || loop->inner || !single_exit (loop))
@@ -2380,7 +2482,6 @@ ifcvt_split_critical_edges (struct loop *loop, bool aggressive_if_conv)
bb->index, MAX_PHI_ARG_NUM);
free (body);
- critical_edges.release ();
return false;
}
if (bb == loop->latch || bb_with_exit_edge_p (loop, bb))
@@ -2461,6 +2562,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;
@@ -2812,6 +2916,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
@@ -2819,6 +2931,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 19f202e5371..2ee3f630b14 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -4450,6 +4450,43 @@ 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 ();
+ return true;
+ }
fn = cg_edge->callee->decl;
cg_edge->callee->get_untransformed_body ();
@@ -4523,7 +4560,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;
@@ -4708,7 +4744,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)
{
@@ -4719,6 +4755,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);
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-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-structalias.c b/gcc/tree-ssa-structalias.c
index d66bdfa94ce..3956efd4766 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
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.c b/gcc/tree.c
index ebec112d4b1..c5653372f18 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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;
}
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/libcilkrts/ChangeLog b/libcilkrts/ChangeLog
index 8fada8a82a6..df34aa52b54 100644
--- a/libcilkrts/ChangeLog
+++ b/libcilkrts/ChangeLog
@@ -1,3 +1,131 @@
+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..802b325eba6 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,10 @@ CXXDEPMODE
ac_ct_CXX
CXXFLAGS
CXX
+multi_basedir
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
am__fastdepCC_FALSE
am__fastdepCC_TRUE
CCDEPMODE
@@ -652,17 +653,6 @@ AMDEP_TRUE
am__quote
am__include
DEPDIR
-OBJEXT
-EXEEXT
-ac_ct_CC
-CPPFLAGS
-LDFLAGS
-CFLAGS
-CC
-multi_basedir
-MAINT
-MAINTAINER_MODE_FALSE
-MAINTAINER_MODE_TRUE
am__untar
am__tar
AMTAR
@@ -686,6 +676,16 @@ am__isrc
INSTALL_DATA
INSTALL_SCRIPT
INSTALL_PROGRAM
+EGREP
+GREP
+CPP
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
target_os
target_vendor
target_cpu
@@ -739,9 +739,9 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
+enable_dependency_tracking
enable_maintainer_mode
enable_multilib
-enable_dependency_tracking
enable_version_specific_runtime_libs
enable_shared
enable_static
@@ -758,10 +758,10 @@ CFLAGS
LDFLAGS
LIBS
CPPFLAGS
+CPP
CXX
CXXFLAGS
CCC
-CPP
CXXCPP'
@@ -1384,11 +1384,11 @@ Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
--enable-maintainer-mode enable make rules and dependencies not useful
(and sometimes confusing) to the casual installer
--enable-multilib build many library versions (default)
- --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors
--enable-version-specific-runtime-libs
Specify that runtime libraries should be installed
in a compi ler-specific directory
@@ -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,1234 @@ test -n "$target_alias" &&
target_alias=${target_alias-$host_alias}
+
+# Test for GNU extensions. Will define _GNU_SOURCE if they're available
+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
+
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+# Try to create an executable without -o first, disregard a.out.
+# It will help us diagnose broken compilers, and finding out an intuition
+# of exeext.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+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_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
+do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
+ ;;
+ [ab].out )
+ # We found the default executable, but exeext='' is most
+ # certainly right.
+ break;;
+ *.* )
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
+ break;;
+ * )
+ break;;
+ esac
+done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
+else
+ ac_file=''
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
+if test -z "$ac_file"; then :
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+{ as_fn_set_status 77
+as_fn_error "C compiler cannot create executables
+See \`config.log' for more details." "$LINENO" 5; }; }
+fi
+ac_exeext=$ac_cv_exeext
+
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+# If not cross compiling, check that we can run a simple program.
+if test "$cross_compiling" != yes; then
+ if { ac_try='./$ac_file'
+ { { 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
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ 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 "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details." "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+ac_clean_files=$ac_clean_files_save
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+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; }; then :
+ # If both `conftest.exe' and `conftest' are `present' (well, observable)
+# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
+# work properly (i.e., refer to `conftest.exe'), while it won't with
+# `rm'.
+for ac_file in conftest.exe conftest conftest.*; do
+ test -f "$ac_file" || continue
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ break;;
+ * ) break;;
+ esac
+done
+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 "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
+
+rm -f conftest.$ac_ext
+EXEEXT=$ac_cv_exeext
+ac_exeext=$EXEEXT
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if test "${ac_cv_objext+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.o conftest.obj
+if { { ac_try="$ac_compile"
+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_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
+ *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
+ break;;
+ esac
+done
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+rm -f conftest.$ac_cv_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
+OBJEXT=$ac_cv_objext
+ac_objext=$OBJEXT
+{ $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
+
+
+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
+
+
+
+ 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
+
+
+
am__api_version='1.11'
# Find a good install program. We prefer a C program (faster),
@@ -2789,6 +4110,69 @@ else
fi
rmdir .tst 2>/dev/null
+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
+
+
if test "`cd $srcdir && pwd`" != "`pwd`"; then
# Use -I$(srcdir) only when $(srcdir) != ., so that make's output
# is not polluted with repeated "-I."
@@ -2850,6 +4234,134 @@ am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
+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
+
+ 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
+
+
@@ -3244,231 +4756,6 @@ $as_echo "$ac_try_echo"; } >&5
test $ac_status = 0; }
done
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
-# Try to create an executable without -o first, disregard a.out.
-# It will help us diagnose broken compilers, and finding out an intuition
-# of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
-ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-
-# The possible output files:
-ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
-
-ac_rmfiles=
-for ac_file in $ac_files
-do
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- * ) ac_rmfiles="$ac_rmfiles $ac_file";;
- esac
-done
-rm -f $ac_rmfiles
-
-if { { ac_try="$ac_link_default"
-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_default") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
-# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
-# in a Makefile. We should not override ac_cv_exeext if it was cached,
-# so that the user can short-circuit this test for compilers unknown to
-# Autoconf.
-for ac_file in $ac_files ''
-do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
- ;;
- [ab].out )
- # We found the default executable, but exeext='' is most
- # certainly right.
- break;;
- *.* )
- if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
- then :; else
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- fi
- # We set ac_cv_exeext here because the later test for it is not
- # safe: cross compilers may not add the suffix if given an `-o'
- # argument, so we may need to know it at that point already.
- # Even if this section looks crufty: it has the advantage of
- # actually working.
- break;;
- * )
- break;;
- esac
-done
-test "$ac_cv_exeext" = no && ac_cv_exeext=
-
-else
- ac_file=''
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
-if test -z "$ac_file"; then :
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
-fi
-ac_exeext=$ac_cv_exeext
-
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { { 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
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- 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 "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
- fi
- fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
-ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
-$as_echo_n "checking for suffix of executables... " >&6; }
-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; }; then :
- # If both `conftest.exe' and `conftest' are `present' (well, observable)
-# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
-# work properly (i.e., refer to `conftest.exe'), while it won't with
-# `rm'.
-for ac_file in conftest.exe conftest conftest.*; do
- test -f "$ac_file" || continue
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
- *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- break;;
- * ) break;;
- esac
-done
-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 "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-rm -f conftest$ac_cv_exeext
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
-$as_echo "$ac_cv_exeext" >&6; }
-
-rm -f conftest.$ac_ext
-EXEEXT=$ac_cv_exeext
-ac_exeext=$EXEEXT
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
-$as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
- $as_echo_n "(cached) " >&6
-else
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h. */
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.o conftest.obj
-if { { ac_try="$ac_compile"
-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_compile") 2>&5
- ac_status=$?
- $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
- test $ac_status = 0; }; then :
- for ac_file in conftest.o conftest.obj conftest.*; do
- test -f "$ac_file" || continue;
- case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
- *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
- break;;
- esac
-done
-else
- $as_echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." "$LINENO" 5; }
-fi
-rm -f conftest.$ac_cv_objext conftest.$ac_ext
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
-$as_echo "$ac_cv_objext" >&6; }
-OBJEXT=$ac_cv_objext
-ac_objext=$OBJEXT
{ $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 :
@@ -3680,197 +4967,6 @@ 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"
-
-
-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
-
-
-
-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
-
- 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=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
@@ -4261,405 +5357,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 +5646,10 @@ case "${target}" in
config_dir="x86"
;;
+ arm-*-*)
+ config_dir="arm"
+ ;;
+
*)
config_dir="generic"
;;
@@ -9036,7 +9737,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 +11765,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 11768 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11170,7 +11871,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 11874 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -13522,7 +14223,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 +15177,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 ()
{
@@ -14665,6 +15365,14 @@ LIBOBJS=$ac_libobjs
LTLIBOBJS=$ac_ltlibobjs
+if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
+ as_fn_error "conditional \"AMDEP\" 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 -n "$EXEEXT"; then
am__EXEEXT_TRUE=
am__EXEEXT_FALSE='#'
@@ -14677,14 +15385,6 @@ if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
-if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
- as_fn_error "conditional \"AMDEP\" 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
@@ -15260,6 +15960,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
#
# INIT-COMMANDS
#
+AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
srcdir="$srcdir"
host="$host"
@@ -15274,7 +15975,6 @@ CC="$CC"
CXX="$CXX"
GFORTRAN="$GFORTRAN"
GCJ="$GCJ"
-AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
# The HP-UX ksh and POSIX shell print the target directory to stdout
@@ -15644,8 +16344,8 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
for ac_config_target in $ac_config_targets
do
case $ac_config_target in
- "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
"depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+ "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"libcilkrts.spec") CONFIG_FILES="$CONFIG_FILES libcilkrts.spec" ;;
"libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
@@ -16067,14 +16767,6 @@ $as_echo "$as_me: executing $ac_file commands" >&6;}
case $ac_file$ac_mode in
- "default-1":C)
-# Only add multilib support code if we just rebuilt the top-level
-# Makefile.
-case " $CONFIG_FILES " in
- *" Makefile "*)
- ac_file=Makefile . ${multi_basedir}/config-ml.in
- ;;
-esac ;;
"depfiles":C) test x"$AMDEP_TRUE" != x"" || {
# Autoconf 2.62 quotes --file arguments for eval, but not when files
# are listed without --file. Let's play safe and only enable the eval
@@ -16170,6 +16862,14 @@ $as_echo X"$file" |
done
}
;;
+ "default-1":C)
+# Only add multilib support code if we just rebuilt the top-level
+# Makefile.
+case " $CONFIG_FILES " in
+ *" Makefile "*)
+ ac_file=Makefile . ${multi_basedir}/config-ml.in
+ ;;
+esac ;;
"libtool":C)
# See if we are running on zsh, and set the options which allow our
diff --git a/libcilkrts/configure.ac b/libcilkrts/configure.ac
index 8ad647ea8e7..6edb9f7c917 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,6 +50,10 @@ AC_PREREQ([2.64])
AC_CANONICAL_SYSTEM
target_alias=${target_alias-$host_alias}
AC_SUBST(target_alias)
+
+# Test for GNU extensions. Will define _GNU_SOURCE if they're available
+AC_USE_SYSTEM_EXTENSIONS
+
AM_INIT_AUTOMAKE(foreign no-dist)
AM_MAINTAINER_MODE
@@ -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/po/ChangeLog b/libcpp/po/ChangeLog
index 0b07fe7be37..ea6ae0259ee 100644
--- a/libcpp/po/ChangeLog
+++ b/libcpp/po/ChangeLog
@@ -1,3 +1,7 @@
+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/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/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 39d599291cd..1cdb7f4e911 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,54 @@
+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: Teste 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/experimental/bits/fs_dir.h b/libstdc++-v3/include/experimental/bits/fs_dir.h
index 4e28c8e9240..f128ccecf7a 100644
--- a/libstdc++-v3/include/experimental/bits/fs_dir.h
+++ b/libstdc++-v3/include/experimental/bits/fs_dir.h
@@ -301,8 +301,8 @@ _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
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/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/recursive_directory_iterator.cc b/libstdc++-v3/testsuite/experimental/filesystem/iterators/recursive_directory_iterator.cc
index 5d2e45b2e64..b5f71be653d 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,19 @@ test01()
remove_all(p, ec);
}
+void
+test02()
+{
+ bool test __attribute__((unused)) = false;
+
+ // libstdc++71004
+ const fs::recursive_directory_iterator it;
+ VERIFY( it == fs::recursive_directory_iterator() );
+}
+
int
main()
{
test01();
+ test02();
}
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..38cbd2762f2 100644
--- a/libstdc++-v3/testsuite/experimental/type_erased_allocator/1.cc
+++ b/libstdc++-v3/testsuite/experimental/memory_resource/1.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 <vector>
+#include <cstdlib>
#include <testsuite_hooks.h>
#include <testsuite_allocator.h>
@@ -36,6 +36,7 @@ struct A
static int ctor_count;
static int dtor_count;
};
+
int A::ctor_count = 0;
int A::dtor_count = 0;
@@ -43,7 +44,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 +55,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 +82,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 +105,11 @@ void test01()
}
// polymorphic_allocator
-void test02()
+void
+test02()
{
+ bool test __attribute((unused)) = false;
+
clear();
{
CountedResource cr;
@@ -115,7 +122,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 +140,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 +152,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/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"