summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-09-09 15:57:43 +0000
committerbstarynk <bstarynk@138bc75d-0d04-0410-961f-82ee72b054a4>2013-09-09 15:57:43 +0000
commiteacbf1cd3aff3dbf47a71dc7fdb1d01dce8e777e (patch)
tree1bfb594134ffebca206d3ed2fe55693634759c1d
parent11fd42e7594bdb9c8d9cf10f9924cb8644752b78 (diff)
downloadgcc-eacbf1cd3aff3dbf47a71dc7fdb1d01dce8e777e.tar.gz
2013-09-09 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 202389 using svnmerge.py; notice that gcc/melt/xtramelt-ana-base.melt has been significantly updated, but some updates are yet missing... [gcc/] 2013-09-09 Basile Starynkevitch <basile@starynkevitch.net> {{When merging trunk GCC 4.9 with C++ passes}} * melt/xtramelt-ana-base.melt: Add GCC 4.9 specific code, still incomplete, for classy passes.... Only Gimple passes are yet possible... git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/melt-branch@202408 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--ChangeLog60
-rw-r--r--ChangeLog.MELT6
-rw-r--r--MAINTAINERS12
-rw-r--r--Makefile.def10
-rw-r--r--Makefile.in1026
-rw-r--r--boehm-gc/ChangeLog39
-rw-r--r--boehm-gc/Makefile.am2
-rw-r--r--boehm-gc/Makefile.in2
-rw-r--r--config/ChangeLog4
-rw-r--r--config/bootstrap-ubsan.mk7
-rwxr-xr-xconfigure89
-rw-r--r--configure.ac40
-rw-r--r--contrib/ChangeLog12
-rwxr-xr-xcontrib/gcc_update5
-rw-r--r--contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail201
-rw-r--r--fixincludes/ChangeLog6
-rw-r--r--fixincludes/fixincl.x55
-rw-r--r--fixincludes/inclhack.def14
-rw-r--r--fixincludes/tests/base/assert.h7
-rw-r--r--gcc/ChangeLog5813
-rw-r--r--gcc/ChangeLog.MELT5
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in93
-rw-r--r--gcc/aclocal.m410
-rw-r--r--gcc/ada/ChangeLog76
-rw-r--r--gcc/ada/gcc-interface/Make-lang.in10
-rw-r--r--gcc/ada/gcc-interface/Makefile.in23
-rw-r--r--gcc/ada/gcc-interface/decl.c22
-rw-r--r--gcc/ada/gcc-interface/misc.c4
-rw-r--r--gcc/ada/gcc-interface/trans.c87
-rw-r--r--gcc/ada/gcc-interface/utils.c2
-rw-r--r--gcc/ada/gcc-interface/utils2.c32
-rw-r--r--gcc/ada/sigtramp-ppcvxw.c2
-rw-r--r--gcc/ada/terminals.c2
-rw-r--r--gcc/asan.c183
-rw-r--r--gcc/auto-inc-dec.c52
-rw-r--r--gcc/basic-block.h21
-rw-r--r--gcc/bb-reorder.c292
-rw-r--r--gcc/bt-load.c108
-rw-r--r--gcc/builtin-attrs.def5
-rw-r--r--gcc/builtins.c60
-rw-r--r--gcc/builtins.def152
-rw-r--r--gcc/c-family/ChangeLog263
-rw-r--r--gcc/c-family/c-ada-spec.c43
-rw-r--r--gcc/c-family/c-common.c80
-rw-r--r--gcc/c-family/c-common.h5
-rw-r--r--gcc/c-family/c-pretty-print.c706
-rw-r--r--gcc/c-family/c-pretty-print.h158
-rw-r--r--gcc/c-family/c-ubsan.c158
-rw-r--r--gcc/c-family/c-ubsan.h27
-rw-r--r--gcc/c/ChangeLog44
-rw-r--r--gcc/c/c-array-notation.c14
-rw-r--r--gcc/c/c-objc-common.c23
-rw-r--r--gcc/c/c-typeck.c52
-rw-r--r--gcc/cfg.c15
-rw-r--r--gcc/cfganal.c114
-rw-r--r--gcc/cfgcleanup.c119
-rw-r--r--gcc/cfgexpand.c63
-rw-r--r--gcc/cfgloop.h14
-rw-r--r--gcc/cfgrtl.c309
-rw-r--r--gcc/cgraph.c648
-rw-r--r--gcc/cgraph.h77
-rw-r--r--gcc/cgraphbuild.c173
-rw-r--r--gcc/cgraphclones.c55
-rw-r--r--gcc/cgraphunit.c302
-rw-r--r--gcc/combine-stack-adj.c52
-rw-r--r--gcc/combine.c71
-rw-r--r--gcc/common.opt47
-rw-r--r--gcc/common/config/i386/i386-common.c69
-rw-r--r--gcc/compare-elim.c55
-rw-r--r--gcc/config.gcc82
-rw-r--r--gcc/config.in12
-rw-r--r--gcc/config/aarch64/aarch64-option-extensions.def1
-rw-r--r--gcc/config/aarch64/aarch64-simd-builtins.def8
-rw-r--r--gcc/config/aarch64/aarch64-simd.md123
-rw-r--r--gcc/config/aarch64/aarch64.c51
-rw-r--r--gcc/config/aarch64/aarch64.h2
-rw-r--r--gcc/config/aarch64/aarch64.md524
-rw-r--r--gcc/config/aarch64/arm_neon.h2314
-rw-r--r--gcc/config/aarch64/iterators.md31
-rw-r--r--gcc/config/aarch64/predicates.md5
-rw-r--r--gcc/config/aarch64/t-aarch645
-rw-r--r--gcc/config/alpha/alpha.c1
-rw-r--r--gcc/config/alpha/linux.h14
-rw-r--r--gcc/config/arm/aarch-common-protos.h36
-rw-r--r--gcc/config/arm/aarch-common.c278
-rw-r--r--gcc/config/arm/arm-fixed.md31
-rw-r--r--gcc/config/arm/arm-protos.h8
-rw-r--r--gcc/config/arm/arm.c524
-rw-r--r--gcc/config/arm/arm.h2
-rw-r--r--gcc/config/arm/arm.md1181
-rw-r--r--gcc/config/arm/arm1020e.md29
-rw-r--r--gcc/config/arm/arm1026ejs.md17
-rw-r--r--gcc/config/arm/arm1136jfs.md17
-rw-r--r--gcc/config/arm/arm926ejs.md15
-rw-r--r--gcc/config/arm/cortex-a15-neon.md170
-rw-r--r--gcc/config/arm/cortex-a15.md50
-rw-r--r--gcc/config/arm/cortex-a5.md26
-rw-r--r--gcc/config/arm/cortex-a53.md33
-rw-r--r--gcc/config/arm/cortex-a7.md150
-rw-r--r--gcc/config/arm/cortex-a8-neon.md128
-rw-r--r--gcc/config/arm/cortex-a8.md19
-rw-r--r--gcc/config/arm/cortex-a9-neon.md120
-rw-r--r--gcc/config/arm/cortex-a9.md30
-rw-r--r--gcc/config/arm/cortex-m4-fpu.md8
-rw-r--r--gcc/config/arm/cortex-m4.md14
-rw-r--r--gcc/config/arm/cortex-r4.md15
-rw-r--r--gcc/config/arm/cortex-r4f.md12
-rw-r--r--gcc/config/arm/fa526.md15
-rw-r--r--gcc/config/arm/fa606te.md14
-rw-r--r--gcc/config/arm/fa626te.md15
-rw-r--r--gcc/config/arm/fa726te.md13
-rw-r--r--gcc/config/arm/fmp626.md10
-rw-r--r--gcc/config/arm/iterators.md2
-rw-r--r--gcc/config/arm/iwmmxt.md6
-rw-r--r--gcc/config/arm/linux-eabi.h4
-rw-r--r--gcc/config/arm/linux-elf.h4
-rw-r--r--gcc/config/arm/marvell-pj4.md47
-rw-r--r--gcc/config/arm/neon-schedgen.ml2
-rw-r--r--gcc/config/arm/neon.md542
-rw-r--r--gcc/config/arm/t-arm5
-rw-r--r--gcc/config/arm/t-linux-eabi2
-rw-r--r--gcc/config/arm/thumb2.md140
-rw-r--r--gcc/config/arm/types.md563
-rw-r--r--gcc/config/arm/vfp.md70
-rw-r--r--gcc/config/arm/vfp11.md13
-rw-r--r--gcc/config/avr/avr-stdint.h4
-rw-r--r--gcc/config/avr/avr.c198
-rw-r--r--gcc/config/avr/avr.opt4
-rw-r--r--gcc/config/bfin/bfin.c1
-rw-r--r--gcc/config/bfin/uclinux.h3
-rw-r--r--gcc/config/c6x/uclinux-elf.h2
-rw-r--r--gcc/config/darwin-protos.h1
-rw-r--r--gcc/config/darwin.c13
-rw-r--r--gcc/config/darwin.h7
-rw-r--r--gcc/config/elfos.h3
-rw-r--r--gcc/config/epiphany/epiphany.c35
-rw-r--r--gcc/config/epiphany/epiphany.h4
-rw-r--r--gcc/config/epiphany/epiphany.md124
-rw-r--r--gcc/config/epiphany/mode-switch-use.c51
-rw-r--r--gcc/config/epiphany/predicates.md8
-rw-r--r--gcc/config/epiphany/resolve-sw-modes.c53
-rw-r--r--gcc/config/freebsd.h3
-rw-r--r--gcc/config/gnu-user.h31
-rw-r--r--gcc/config/i386/constraints.md9
-rw-r--r--gcc/config/i386/cpuid.h4
-rw-r--r--gcc/config/i386/cygming.h3
-rw-r--r--gcc/config/i386/djgpp.h14
-rw-r--r--gcc/config/i386/driver-i386.c43
-rw-r--r--gcc/config/i386/i386-c.c8
-rw-r--r--gcc/config/i386/i386-interix.h3
-rw-r--r--gcc/config/i386/i386-modes.def3
-rw-r--r--gcc/config/i386/i386-opts.h20
-rw-r--r--gcc/config/i386/i386-protos.h2
-rw-r--r--gcc/config/i386/i386.c1285
-rw-r--r--gcc/config/i386/i386.h217
-rw-r--r--gcc/config/i386/i386.md304
-rw-r--r--gcc/config/i386/i386.opt35
-rw-r--r--gcc/config/i386/linux-common.h2
-rw-r--r--gcc/config/i386/mmx.md12
-rw-r--r--gcc/config/i386/predicates.md6
-rw-r--r--gcc/config/i386/sse.md376
-rw-r--r--gcc/config/i386/stringop.def37
-rw-r--r--gcc/config/i386/stringop.opt31
-rw-r--r--gcc/config/i386/t-i3862
-rw-r--r--gcc/config/i386/x86-64.h3
-rw-r--r--gcc/config/i386/x86-tune.def232
-rw-r--r--gcc/config/ia64/hpux.h7
-rw-r--r--gcc/config/linux-android.c14
-rw-r--r--gcc/config/linux-protos.h2
-rw-r--r--gcc/config/linux.h14
-rw-r--r--gcc/config/lm32/uclinux-elf.h2
-rw-r--r--gcc/config/m68k/uclinux.h3
-rw-r--r--gcc/config/microblaze/microblaze.h4
-rw-r--r--gcc/config/mips/linux-common.h2
-rw-r--r--gcc/config/mips/linux.h7
-rw-r--r--gcc/config/mips/linux64.h20
-rw-r--r--gcc/config/mips/mips-modes.def7
-rw-r--r--gcc/config/mips/mips-opts.h7
-rw-r--r--gcc/config/mips/mips.c86
-rw-r--r--gcc/config/mips/mips.h14
-rw-r--r--gcc/config/mips/mips.md27
-rw-r--r--gcc/config/mips/mips.opt18
-rw-r--r--gcc/config/mips/mti-linux.h2
-rw-r--r--gcc/config/mips/t-mti-elf8
-rw-r--r--gcc/config/mips/t-mti-linux8
-rw-r--r--gcc/config/mmix/mmix.h4
-rw-r--r--gcc/config/moxie/uclinux.h3
-rw-r--r--gcc/config/netbsd.h3
-rw-r--r--gcc/config/openbsd.h6
-rw-r--r--gcc/config/pa/pa-hpux.h3
-rw-r--r--gcc/config/pa/pa.md16
-rw-r--r--gcc/config/pdp11/pdp11.h4
-rw-r--r--gcc/config/picochip/picochip.h4
-rw-r--r--gcc/config/rl78/rl78.c63
-rw-r--r--gcc/config/rs6000/aix43.h3
-rw-r--r--gcc/config/rs6000/aix51.h3
-rw-r--r--gcc/config/rs6000/aix52.h4
-rw-r--r--gcc/config/rs6000/aix53.h4
-rw-r--r--gcc/config/rs6000/aix61.h4
-rw-r--r--gcc/config/rs6000/darwin.h6
-rw-r--r--gcc/config/rs6000/dfp.md33
-rw-r--r--gcc/config/rs6000/linux.h15
-rw-r--r--gcc/config/rs6000/linux64.h15
-rw-r--r--gcc/config/rs6000/predicates.md96
-rw-r--r--gcc/config/rs6000/rs6000-modes.def4
-rw-r--r--gcc/config/rs6000/rs6000-protos.h3
-rw-r--r--gcc/config/rs6000/rs6000.c420
-rw-r--r--gcc/config/rs6000/rs6000.h15
-rw-r--r--gcc/config/rs6000/rs6000.md41
-rw-r--r--gcc/config/rs6000/rs6000.opt4
-rw-r--r--gcc/config/rs6000/rtems.h3
-rw-r--r--gcc/config/rs6000/t-linux6410
-rw-r--r--gcc/config/rs6000/t-linux64bele7
-rw-r--r--gcc/config/rs6000/t-linux64le3
-rw-r--r--gcc/config/rs6000/t-linux64lebe7
-rw-r--r--gcc/config/rs6000/vsx.md32
-rw-r--r--gcc/config/rx/rx.c6
-rw-r--r--gcc/config/rx/rx.h1
-rw-r--r--gcc/config/s390/2827.md23
-rw-r--r--gcc/config/s390/linux.h3
-rw-r--r--gcc/config/s390/s390.md106
-rw-r--r--gcc/config/s390/tpf.h7
-rw-r--r--gcc/config/sol2-10.h6
-rw-r--r--gcc/config/sol2.h3
-rw-r--r--gcc/config/sparc/sparc.c84
-rw-r--r--gcc/config/sparc/sparc.h12
-rw-r--r--gcc/config/sparc/sparc.opt6
-rw-r--r--gcc/config/sparc/sync.md7
-rw-r--r--gcc/config/sparc/t-sparc2
-rw-r--r--gcc/config/vms/vms.h3
-rw-r--r--gcc/config/vxworks.h3
-rwxr-xr-xgcc/configure78
-rw-r--r--gcc/configure.ac30
-rw-r--r--gcc/context.c6
-rw-r--r--gcc/context.h11
-rw-r--r--gcc/convert.c9
-rw-r--r--gcc/coretypes.h19
-rw-r--r--gcc/coverage.c66
-rw-r--r--gcc/coverage.h3
-rw-r--r--gcc/cp/ChangeLog613
-rw-r--r--gcc/cp/Make-lang.in11
-rw-r--r--gcc/cp/call.c56
-rw-r--r--gcc/cp/class.c153
-rw-r--r--gcc/cp/config-lang.in2
-rw-r--r--gcc/cp/cp-array-notation.c21
-rw-r--r--gcc/cp/cp-objcp-common.c18
-rw-r--r--gcc/cp/cp-tree.h50
-rw-r--r--gcc/cp/cvt.c23
-rw-r--r--gcc/cp/cxx-pretty-print.c858
-rw-r--r--gcc/cp/cxx-pretty-print.h77
-rw-r--r--gcc/cp/decl.c142
-rw-r--r--gcc/cp/decl2.c39
-rw-r--r--gcc/cp/error.c1420
-rw-r--r--gcc/cp/except.c49
-rw-r--r--gcc/cp/friend.c4
-rw-r--r--gcc/cp/init.c11
-rw-r--r--gcc/cp/mangle.c44
-rw-r--r--gcc/cp/name-lookup.c51
-rw-r--r--gcc/cp/name-lookup.h1
-rw-r--r--gcc/cp/parser.c50
-rw-r--r--gcc/cp/pt.c98
-rw-r--r--gcc/cp/rtti.c4
-rw-r--r--gcc/cp/semantics.c27
-rw-r--r--gcc/cp/tree.c2
-rw-r--r--gcc/cp/typeck.c78
-rw-r--r--gcc/cp/typeck2.c9
-rw-r--r--gcc/cp/vtable-class-hierarchy.c1342
-rw-r--r--gcc/cppbuiltin.c2
-rw-r--r--gcc/cprop.c55
-rw-r--r--gcc/cse.c166
-rw-r--r--gcc/dbgcnt.def2
-rw-r--r--gcc/dce.c104
-rw-r--r--gcc/defaults.h12
-rw-r--r--gcc/df-core.c161
-rw-r--r--gcc/diagnostic.c27
-rw-r--r--gcc/diagnostic.h2
-rw-r--r--gcc/doc/extend.texi5
-rw-r--r--gcc/doc/install.texi40
-rw-r--r--gcc/doc/invoke.texi235
-rw-r--r--gcc/doc/md.texi6
-rw-r--r--gcc/doc/rtl.texi4
-rw-r--r--gcc/doc/tm.texi26
-rw-r--r--gcc/doc/tm.texi.in21
-rw-r--r--gcc/double-int.c8
-rw-r--r--gcc/dse.c108
-rw-r--r--gcc/dumpfile.c16
-rw-r--r--gcc/dumpfile.h4
-rw-r--r--gcc/dwarf2cfi.c54
-rw-r--r--gcc/dwarf2out.c14
-rw-r--r--gcc/except.c107
-rw-r--r--gcc/expmed.c6
-rw-r--r--gcc/expr.c21
-rw-r--r--gcc/final.c291
-rw-r--r--gcc/flag-types.h19
-rw-r--r--gcc/fold-const.c79
-rw-r--r--gcc/fortran/ChangeLog150
-rw-r--r--gcc/fortran/array.c66
-rw-r--r--gcc/fortran/class.c192
-rw-r--r--gcc/fortran/dependency.c105
-rw-r--r--gcc/fortran/expr.c5
-rw-r--r--gcc/fortran/f95-lang.c4
-rw-r--r--gcc/fortran/gfortran.h6
-rw-r--r--gcc/fortran/interface.c92
-rw-r--r--gcc/fortran/intrinsic.c7
-rw-r--r--gcc/fortran/invoke.texi5
-rw-r--r--gcc/fortran/io.c18
-rw-r--r--gcc/fortran/lang.opt4
-rw-r--r--gcc/fortran/match.c105
-rw-r--r--gcc/fortran/openmp.c4
-rw-r--r--gcc/fortran/options.c6
-rw-r--r--gcc/fortran/parse.c4
-rw-r--r--gcc/fortran/resolve.c59
-rw-r--r--gcc/fortran/st.c6
-rw-r--r--gcc/fortran/symbol.c3
-rw-r--r--gcc/fortran/trans-array.c40
-rw-r--r--gcc/fortran/trans-decl.c35
-rw-r--r--gcc/fortran/trans-expr.c222
-rw-r--r--gcc/fortran/trans-intrinsic.c10
-rw-r--r--gcc/fortran/trans-io.c5
-rw-r--r--gcc/fortran/trans-stmt.c3
-rw-r--r--gcc/function.c293
-rw-r--r--gcc/function.h8
-rw-r--r--gcc/fwprop.c107
-rw-r--r--gcc/gcc.c127
-rw-r--r--gcc/gcov-io.h2
-rw-r--r--gcc/gcse.c108
-rw-r--r--gcc/gdbhooks.py397
-rw-r--r--gcc/gen-pass-instances.awk66
-rw-r--r--gcc/gengtype.c23
-rw-r--r--gcc/genoutput.c4
-rw-r--r--gcc/gimple-fold.c33
-rw-r--r--gcc/gimple-low.c51
-rw-r--r--gcc/gimple-pretty-print.c235
-rw-r--r--gcc/gimple-ssa-strength-reduction.c94
-rw-r--r--gcc/gimple-streamer-in.c7
-rw-r--r--gcc/gimple.c11
-rw-r--r--gcc/gimple.def8
-rw-r--r--gcc/gimple.h28
-rw-r--r--gcc/gimplify.c200
-rw-r--r--gcc/go/ChangeLog16
-rw-r--r--gcc/go/go-gcc.cc27
-rw-r--r--gcc/go/gofrontend/expressions.cc157
-rw-r--r--gcc/go/gofrontend/expressions.h13
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc87
-rw-r--r--gcc/go/gofrontend/gogo.cc152
-rw-r--r--gcc/go/gofrontend/gogo.h13
-rw-r--r--gcc/go/gofrontend/parse.cc3
-rw-r--r--gcc/go/gofrontend/statements.cc59
-rw-r--r--gcc/go/gofrontend/statements.h46
-rw-r--r--gcc/go/gofrontend/types.cc52
-rw-r--r--gcc/go/gofrontend/types.h12
-rw-r--r--gcc/graph.c32
-rw-r--r--gcc/gtm-builtins.def2
-rw-r--r--gcc/hwint.h4
-rw-r--r--gcc/ifcvt.c157
-rw-r--r--gcc/init-regs.c52
-rw-r--r--gcc/internal-fn.c24
-rw-r--r--gcc/internal-fn.def3
-rw-r--r--gcc/ipa-cp.c182
-rw-r--r--gcc/ipa-devirt.c1181
-rw-r--r--gcc/ipa-inline-analysis.c72
-rw-r--r--gcc/ipa-inline-transform.c31
-rw-r--r--gcc/ipa-inline.c484
-rw-r--r--gcc/ipa-inline.h1
-rw-r--r--gcc/ipa-profile.c754
-rw-r--r--gcc/ipa-prop.c517
-rw-r--r--gcc/ipa-prop.h47
-rw-r--r--gcc/ipa-pure-const.c131
-rw-r--r--gcc/ipa-ref.c92
-rw-r--r--gcc/ipa-ref.h6
-rw-r--r--gcc/ipa-reference.c72
-rw-r--r--gcc/ipa-split.c112
-rw-r--r--gcc/ipa-utils.c184
-rw-r--r--gcc/ipa-utils.h63
-rw-r--r--gcc/ipa.c790
-rw-r--r--gcc/ira.c113
-rw-r--r--gcc/jump.c51
-rw-r--r--gcc/langhooks.c4
-rw-r--r--gcc/loop-init.c378
-rw-r--r--gcc/loop-unroll.c19
-rw-r--r--gcc/lower-subreg.c106
-rw-r--r--gcc/lra-constraints.c203
-rw-r--r--gcc/lra.c18
-rw-r--r--gcc/lto-cgraph.c74
-rw-r--r--gcc/lto-section-in.c35
-rw-r--r--gcc/lto-streamer-in.c104
-rw-r--r--gcc/lto-streamer-out.c299
-rw-r--r--gcc/lto-streamer.h14
-rw-r--r--gcc/lto/ChangeLog97
-rw-r--r--gcc/lto/Make-lang.in8
-rw-r--r--gcc/lto/config-lang.in2
-rw-r--r--gcc/lto/lto-partition.c38
-rw-r--r--gcc/lto/lto-symtab.c (renamed from gcc/lto-symtab.c)34
-rw-r--r--gcc/lto/lto.c386
-rw-r--r--gcc/lto/lto.h4
-rw-r--r--gcc/melt-run.proto.h5
-rw-r--r--gcc/melt/xtramelt-ana-base.melt55
-rw-r--r--gcc/mode-switching.c63
-rw-r--r--gcc/modulo-sched.c57
-rw-r--r--gcc/omp-low.c1483
-rw-r--r--gcc/opts.c70
-rw-r--r--gcc/output.h4
-rw-r--r--gcc/pass_manager.h138
-rw-r--r--gcc/passes.c631
-rw-r--r--gcc/passes.def3
-rw-r--r--gcc/postreload-gcse.c53
-rw-r--r--gcc/postreload.c53
-rw-r--r--gcc/predict.c151
-rw-r--r--gcc/pretty-print.c176
-rw-r--r--gcc/pretty-print.h153
-rw-r--r--gcc/print-tree.c2
-rw-r--r--gcc/profile.c17
-rw-r--r--gcc/profile.h2
-rw-r--r--gcc/recog.c400
-rw-r--r--gcc/recog.h52
-rw-r--r--gcc/ree.c53
-rw-r--r--gcc/reg-stack.c102
-rw-r--r--gcc/regcprop.c53
-rw-r--r--gcc/reginfo.c72
-rw-r--r--gcc/regmove.c52
-rw-r--r--gcc/regrename.c53
-rw-r--r--gcc/reload.c4
-rw-r--r--gcc/reload.h2
-rw-r--r--gcc/reorg.c132
-rw-r--r--gcc/resource.c27
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c2
-rw-r--r--gcc/sanitizer.def14
-rw-r--r--gcc/sched-rgn.c112
-rw-r--r--gcc/sched-vis.c91
-rw-r--r--gcc/sel-sched.c15
-rw-r--r--gcc/simplify-rtx.c7
-rw-r--r--gcc/stack-ptr-mod.c51
-rw-r--r--gcc/statistics.c7
-rw-r--r--gcc/store-motion.c54
-rw-r--r--gcc/symtab.c138
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/target.def9
-rw-r--r--gcc/targhooks.h4
-rw-r--r--gcc/testsuite/ChangeLog1162
-rw-r--r--gcc/testsuite/c-c++-common/cilk-plus/AN/pr57490.c28
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr58257.c15
-rw-r--r--gcc/testsuite/c-c++-common/opaque-vector.c22
-rw-r--r--gcc/testsuite/c-c++-common/scal-to-vec1.c8
-rw-r--r--gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c2
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/const-char-1.c9
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/const-expr-1.c22
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c24
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c23
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c21
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/div-by-zero-4.c11
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/save-expr-1.c11
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/save-expr-2.c14
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/save-expr-3.c16
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/save-expr-4.c16
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/shift-1.c31
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/shift-2.c23
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/shift-3.c11
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/typedef-1.c12
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/unreachable-1.c10
-rw-r--r--gcc/testsuite/g++.dg/abi/mangle33.C4
-rw-r--r--gcc/testsuite/g++.dg/conversion/ambig2.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-0.C9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-33a.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C21
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C60
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-ice8.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C16
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/dc7.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/dc8.C66
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted2.C4
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/defaulted31.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/enum15.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/enum28.C17
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/error6.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/gen-attrs-32.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C30
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/nsdmi-sizeof.C7
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/override2.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/parse1.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr57416.C45
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr58072.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/pr58080.C14
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/ref-qual14.C18
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/scoped_enum.C2
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/temp_default4.C2
-rw-r--r--gcc/testsuite/g++.dg/debug/ra1.C77
-rw-r--r--gcc/testsuite/g++.dg/dg.exp1
-rw-r--r--gcc/testsuite/g++.dg/ext/attr-alias-3.C8
-rw-r--r--gcc/testsuite/g++.dg/ext/attrib32.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C18
-rw-r--r--gcc/testsuite/g++.dg/ext/mv13.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/mv7.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/mv9.C2
-rw-r--r--gcc/testsuite/g++.dg/ext/pr57362.C5
-rw-r--r--gcc/testsuite/g++.dg/ext/typeof10.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-11.C3
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-13.C22
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-14.C34
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-15.C40
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-16.C39
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-17.C44
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-18.C37
-rw-r--r--gcc/testsuite/g++.dg/ipa/remref-1.C36
-rw-r--r--gcc/testsuite/g++.dg/ipa/remref-2.C37
-rw-r--r--gcc/testsuite/g++.dg/ipa/type-inheritance-1.C28
-rw-r--r--gcc/testsuite/g++.dg/lookup/anon6.C8
-rw-r--r--gcc/testsuite/g++.dg/lookup/crash6.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/name-clash5.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/name-clash6.C2
-rw-r--r--gcc/testsuite/g++.dg/lookup/using9.C4
-rw-r--r--gcc/testsuite/g++.dg/opt/pr57661.C76
-rw-r--r--gcc/testsuite/g++.dg/opt/pr58006.C22
-rw-r--r--gcc/testsuite/g++.dg/opt/pr58165.C14
-rw-r--r--gcc/testsuite/g++.dg/other/anon4.C2
-rw-r--r--gcc/testsuite/g++.dg/other/error15.C28
-rw-r--r--gcc/testsuite/g++.dg/other/error8.C2
-rw-r--r--gcc/testsuite/g++.dg/other/redecl2.C2
-rw-r--r--gcc/testsuite/g++.dg/overload/new1.C1
-rw-r--r--gcc/testsuite/g++.dg/overload/using2.C8
-rw-r--r--gcc/testsuite/g++.dg/overload/using3.C16
-rw-r--r--gcc/testsuite/g++.dg/parse/access11.C35
-rw-r--r--gcc/testsuite/g++.dg/parse/crash16.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/crash21.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/crash38.C4
-rw-r--r--gcc/testsuite/g++.dg/parse/crash63.C10
-rw-r--r--gcc/testsuite/g++.dg/parse/redef2.C2
-rw-r--r--gcc/testsuite/g++.dg/parse/struct-as-enum1.C2
-rw-r--r--gcc/testsuite/g++.dg/plugin/dumb_plugin.c55
-rw-r--r--gcc/testsuite/g++.dg/plugin/selfassign.c55
-rw-r--r--gcc/testsuite/g++.dg/pr57878.C4
-rw-r--r--gcc/testsuite/g++.dg/template/abstract1.C12
-rw-r--r--gcc/testsuite/g++.dg/template/crash39.C2
-rw-r--r--gcc/testsuite/g++.dg/template/delete2.C26
-rw-r--r--gcc/testsuite/g++.dg/template/error54.C10
-rw-r--r--gcc/testsuite/g++.dg/template/meminit1.C2
-rw-r--r--gcc/testsuite/g++.dg/template/redecl3.C2
-rw-r--r--gcc/testsuite/g++.dg/template/using24.C30
-rw-r--r--gcc/testsuite/g++.dg/template/using25.C17
-rw-r--r--gcc/testsuite/g++.dg/template/using26.C49
-rw-r--r--gcc/testsuite/g++.dg/tls/diag-3.C4
-rw-r--r--gcc/testsuite/g++.dg/tm/noexcept-6.C23
-rw-r--r--gcc/testsuite/g++.dg/torture/PR58294.C20
-rw-r--r--gcc/testsuite/g++.dg/torture/pr58201.h24
-rw-r--r--gcc/testsuite/g++.dg/torture/pr58201_0.C9
-rw-r--r--gcc/testsuite/g++.dg/torture/pr58201_1.C10
-rw-r--r--gcc/testsuite/g++.dg/tree-prof/pr57451.C26
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C2
-rw-r--r--gcc/testsuite/g++.dg/tree-ssa/pr45453.C2
-rw-r--r--gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C9
-rw-r--r--gcc/testsuite/g++.dg/ubsan/cxx11-shift-2.C10
-rw-r--r--gcc/testsuite/g++.dg/ubsan/div-by-zero-1.C10
-rw-r--r--gcc/testsuite/g++.dg/ubsan/ubsan.exp34
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr50413.cc2
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr50819.cc2
-rw-r--r--gcc/testsuite/g++.dg/vect/slp-pr56812.cc2
-rw-r--r--gcc/testsuite/g++.dg/warn/Wredundant-decls-spec.C2
-rw-r--r--gcc/testsuite/g++.dg/warn/deprecated-7.C17
-rw-r--r--gcc/testsuite/g++.dg/warn/deprecated-8.C15
-rw-r--r--gcc/testsuite/g++.dg/warn/weak1.C1
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash16.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/crash18.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/err-msg4.C4
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/redecl1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.brendan/static3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.bugs/900127_02.C8
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/binding.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/crash4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/crash7.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/lineno.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.jason/scoping7.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/misc3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/net44.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.mike/ns3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/alias4.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.ns/ns11.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/crash23.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/decl8.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/linkage3.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/typeck1.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/typedef5.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/explicit34.C2
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/friend36.C2
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr58164.c8
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr58340.c16
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20101011-1.c3
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr56799.x7
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr57860.c25
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr57861.c33
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr57875.c21
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr57876.c27
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr57877.c28
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr58209.c32
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr58277-1.c102
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr58277-2.c98
-rw-r--r--gcc/testsuite/gcc.dg/asan/pr56417.c9
-rw-r--r--gcc/testsuite/gcc.dg/attr-weakref-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/autopar/pr49960.c6
-rw-r--r--gcc/testsuite/gcc.dg/builtin-apply2.c2
-rw-r--r--gcc/testsuite/gcc.dg/c99-stdint-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/aranges-fnsec-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/asm-line1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/c99-typedef1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/const-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/const-2b.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char3.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-dfp.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die3.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die5.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die6.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die7.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-file1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-float.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-merge.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-uninit.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2.exp4
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/fesd-any.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/fesd-baseonly.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/fesd-none.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/fesd-reduced.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/fesd-sys.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/global-used-types.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/inline1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/inline3.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/ipa-cp1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr31230.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr37726.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41543.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr41695.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr43237.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr51410.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/pr53948.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/static1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/struct-loc1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/var1.c2
-rw-r--r--gcc/testsuite/gcc.dg/debug/dwarf2/var2.c2
-rw-r--r--gcc/testsuite/gcc.dg/fork-instrumentation.c8
-rw-r--r--gcc/testsuite/gcc.dg/guality/param-1.c33
-rw-r--r--gcc/testsuite/gcc.dg/guality/param-2.c33
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-3.c6
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-5.c4
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-8.c4
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c3
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/ipa/ipcp-4.c4
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr57539.c218
-rw-r--r--gcc/testsuite/gcc.dg/ipa/pr58106.c50
-rw-r--r--gcc/testsuite/gcc.dg/lower-subreg-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/plugin/one_time_plugin.c66
-rw-r--r--gcc/testsuite/gcc.dg/plugin/selfassign.c55
-rw-r--r--gcc/testsuite/gcc.dg/pr26570.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr32773.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr40209.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr44214-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr44214-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr46647.c4
-rw-r--r--gcc/testsuite/gcc.dg/pr57287-2.c35
-rw-r--r--gcc/testsuite/gcc.dg/pr57662.c47
-rw-r--r--gcc/testsuite/gcc.dg/pr57980.c19
-rw-r--r--gcc/testsuite/gcc.dg/pr58010.c15
-rw-r--r--gcc/testsuite/gcc.dg/pr58145-1.c37
-rw-r--r--gcc/testsuite/gcc.dg/pr58145-2.c51
-rw-r--r--gcc/testsuite/gcc.dg/stack-usage-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-10.c5
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-11.c14
-rw-r--r--gcc/testsuite/gcc.dg/strlenopt-13.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr37868.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr53922.c1
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57521.c51
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57656.c13
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57685.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57993-2.cpp213
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr57993.c30
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58041.c33
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58079.c107
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58223.c16
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58228.c15
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr58246.c21
-rw-r--r--gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c7
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/crossmodule-indircall-1.c19
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/crossmodule-indircall-1a.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c23
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-23.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/loop-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr31261.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr42585.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr44258.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr54245.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/reassoc-31.c17
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/sccp-1.c15
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-2.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/slsr-3.c9
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-23.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c31
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vector-4.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp55.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp58.c3
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp87.c1
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/c99-shift-1.c10
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c10
-rw-r--r--gcc/testsuite/gcc.dg/ubsan/ubsan.exp36
-rw-r--r--gcc/testsuite/gcc.dg/unroll_1.c10
-rw-r--r--gcc/testsuite/gcc.dg/unroll_2.c2
-rw-r--r--gcc/testsuite/gcc.dg/unroll_3.c2
-rw-r--r--gcc/testsuite/gcc.dg/unroll_4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-10.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-11.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-13.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-14.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-16.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-17.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-18.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-19.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-20.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-21.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-22.c4
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-23.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-24.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-25.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-26.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-27.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-28.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-29.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-3.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-30.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-31.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-4.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-5.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-6.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8a.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-8b.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-9.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c2
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr56933.c6
-rw-r--r--gcc/testsuite/gcc.dg/vect/vect-iv-5.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c56
-rw-r--r--gcc/testsuite/gcc.target/aarch64/scalar_shift_1.c263
-rw-r--r--gcc/testsuite/gcc.target/aarch64/table-intrinsics.c32
-rw-r--r--gcc/testsuite/gcc.target/arc/arc.exp41
-rw-r--r--gcc/testsuite/gcc.target/arc/builtin_arc_aligned-1.c16
-rw-r--r--gcc/testsuite/gcc.target/arc/builtin_arc_aligned-2.c28
-rw-r--r--gcc/testsuite/gcc.target/arc/builtin_arc_aligned-3.c67
-rw-r--r--gcc/testsuite/gcc.target/arc/cond-set-use.c128
-rw-r--r--gcc/testsuite/gcc.target/arc/interrupt-1.c5
-rw-r--r--gcc/testsuite/gcc.target/arc/interrupt-2.c5
-rw-r--r--gcc/testsuite/gcc.target/arc/interrupt-3.c14
-rw-r--r--gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c28
-rw-r--r--gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c30
-rw-r--r--gcc/testsuite/gcc.target/arc/nv-cache.c9
-rw-r--r--gcc/testsuite/gcc.target/arc/sdata-1.c10
-rw-r--r--gcc/testsuite/gcc.target/arc/sdata-2.c10
-rw-r--r--gcc/testsuite/gcc.target/arc/v-cache.c9
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-acquire.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-char.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-consume.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-int.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-release.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/atomic-op-short.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c19
-rw-r--r--gcc/testsuite/gcc.target/arm/lp1189445.c18
-rw-r--r--gcc/testsuite/gcc.target/arm/neon-for-64bits-2.c57
-rw-r--r--gcc/testsuite/gcc.target/arm/pr19599.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/pr46975-2.c10
-rw-r--r--gcc/testsuite/gcc.target/arm/pr57637.c206
-rw-r--r--gcc/testsuite/gcc.target/arm/pr58041.c30
-rw-r--r--gcc/testsuite/gcc.target/avr/progmem-error-1.cpp2
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c12
-rw-r--r--gcc/testsuite/gcc.target/i386/memcpy-strategy-3.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/memset-strategy-1.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/movabs-1.c10
-rw-r--r--gcc/testsuite/gcc.target/i386/pr58048.c11
-rw-r--r--gcc/testsuite/gcc.target/i386/pr58137.c33
-rw-r--r--gcc/testsuite/gcc.target/i386/pr58218.c5
-rw-r--r--gcc/testsuite/gcc.target/mips/code-readable-1.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/code-readable-2.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/code-readable-3.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/code-readable-4.c8
-rw-r--r--gcc/testsuite/gcc.target/mips/fabs-2008.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/fabs-legacy.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/fabsf-2008.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/fabsf-legacy.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/fneg-2008.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/fneg-legacy.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/fnegf-2008.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/fnegf-legacy.c10
-rw-r--r--gcc/testsuite/gcc.target/mips/mips.exp20
-rw-r--r--gcc/testsuite/gcc.target/mips/mulsize-1.c1
-rw-r--r--gcc/testsuite/gcc.target/mips/mulsize-2.c3
-rw-r--r--gcc/testsuite/gcc.target/mips/nan-2008.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/nan-legacy.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/nanf-2008.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/nanf-legacy.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/nans-2008.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/nans-legacy.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/nansf-2008.c7
-rw-r--r--gcc/testsuite/gcc.target/mips/nansf-legacy.c7
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c26
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp-td-2.c29
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp-td-3.c29
-rw-r--r--gcc/testsuite/gcc.target/powerpc/fusion.c23
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr57744.c2
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr57949-1.c19
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pr57949-2.c19
-rw-r--r--gcc/testsuite/gcc.target/s390/nearestint-1.c48
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_11.f901
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_18.f901
-rw-r--r--gcc/testsuite/gfortran.dg/array_constructor_22.f901
-rw-r--r--gcc/testsuite/gfortran.dg/bounds_check_18.f909
-rw-r--r--gcc/testsuite/gfortran.dg/coarray_15.f902
-rw-r--r--gcc/testsuite/gfortran.dg/do_1.f901
-rw-r--r--gcc/testsuite/gfortran.dg/do_3.F902
-rw-r--r--gcc/testsuite/gfortran.dg/do_check_10.f907
-rw-r--r--gcc/testsuite/gfortran.dg/do_check_5.f902
-rw-r--r--gcc/testsuite/gfortran.dg/do_concurrent_3.f9013
-rw-r--r--gcc/testsuite/gfortran.dg/gomp/proc_ptr_1.f9028
-rw-r--r--gcc/testsuite/gfortran.dg/inline_sum_5.f9033
-rw-r--r--gcc/testsuite/gfortran.dg/intent_out_8.f9017
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_assign_10.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_assign_11.f9051
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_assign_8.f9046
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_assign_9.f9036
-rw-r--r--gcc/testsuite/gfortran.dg/pointer_init_8.f9026
-rw-r--r--gcc/testsuite/gfortran.dg/pr57987.f9024
-rw-r--r--gcc/testsuite/gfortran.dg/realloc_on_assign_14.f902
-rw-r--r--gcc/testsuite/gfortran.dg/realloc_on_assign_19.f9021
-rw-r--r--gcc/testsuite/gfortran.dg/reassoc_12.f9074
-rw-r--r--gcc/testsuite/gfortran.dg/select_type_34.f9010
-rw-r--r--gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f9020
-rw-r--r--gcc/testsuite/gfortran.dg/typebound_assignment_7.f9066
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization16.adb24
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization16_pkg.adb8
-rw-r--r--gcc/testsuite/gnat.dg/loop_optimization16_pkg.ads7
-rw-r--r--gcc/testsuite/gnat.dg/specs/linker_alias.ads10
-rw-r--r--gcc/testsuite/gnat.dg/stack_usage2.adb26
-rw-r--r--gcc/testsuite/gnat.dg/valued_proc.adb12
-rw-r--r--gcc/testsuite/gnat.dg/valued_proc_pkg.ads15
-rw-r--r--gcc/testsuite/gnat.dg/warn10.adb12
-rw-r--r--gcc/testsuite/gnat.dg/warn10.ads11
-rw-r--r--gcc/testsuite/gnat.dg/warn10_pkg.ads12
-rw-r--r--gcc/testsuite/gnat.dg/warn9.adb10
-rw-r--r--gcc/testsuite/go.test/test/fixedbugs/bug086.go4
-rw-r--r--gcc/testsuite/lib/file-format.exp3
-rw-r--r--gcc/testsuite/lib/plugin-support.exp4
-rw-r--r--gcc/testsuite/lib/target-supports.exp15
-rw-r--r--gcc/testsuite/lib/ubsan-dg.exp104
-rw-r--r--gcc/testsuite/obj-c++.dg/method-8.mm4
-rw-r--r--gcc/testsuite/obj-c++.dg/tls/diag-3.mm4
-rw-r--r--gcc/timevar.c5
-rw-r--r--gcc/timevar.def5
-rw-r--r--gcc/timevar.h2
-rw-r--r--gcc/toplev.c46
-rw-r--r--gcc/toplev.h1
-rw-r--r--gcc/tracer.c53
-rw-r--r--gcc/trans-mem.c378
-rw-r--r--gcc/tree-affine.c46
-rw-r--r--gcc/tree-call-cdce.c75
-rw-r--r--gcc/tree-cfg.c304
-rw-r--r--gcc/tree-cfgcleanup.c53
-rw-r--r--gcc/tree-complex.c106
-rw-r--r--gcc/tree-core.h1693
-rw-r--r--gcc/tree-data-ref.c23
-rw-r--r--gcc/tree-eh.c261
-rw-r--r--gcc/tree-emutls.c52
-rw-r--r--gcc/tree-flow.h3
-rw-r--r--gcc/tree-if-conv.c146
-rw-r--r--gcc/tree-inline.c235
-rw-r--r--gcc/tree-inline.h4
-rw-r--r--gcc/tree-into-ssa.c54
-rw-r--r--gcc/tree-loop-distribution.c73
-rw-r--r--gcc/tree-mudflap.c140
-rw-r--r--gcc/tree-nomudflap.c102
-rw-r--r--gcc/tree-nrv.c103
-rw-r--r--gcc/tree-object-size.c52
-rw-r--r--gcc/tree-optimize.c105
-rw-r--r--gcc/tree-parloops.c17
-rw-r--r--gcc/tree-pass.h636
-rw-r--r--gcc/tree-pretty-print.c339
-rw-r--r--gcc/tree-pretty-print.h7
-rw-r--r--gcc/tree-profile.c182
-rw-r--r--gcc/tree-scalar-evolution.c1
-rw-r--r--gcc/tree-sra.c182
-rw-r--r--gcc/tree-ssa-ccp.c148
-rw-r--r--gcc/tree-ssa-copy.c64
-rw-r--r--gcc/tree-ssa-copyrename.c53
-rw-r--r--gcc/tree-ssa-dce.c307
-rw-r--r--gcc/tree-ssa-dom.c140
-rw-r--r--gcc/tree-ssa-dse.c53
-rw-r--r--gcc/tree-ssa-forwprop.c54
-rw-r--r--gcc/tree-ssa-ifcombine.c53
-rw-r--r--gcc/tree-ssa-loop-ch.c55
-rw-r--r--gcc/tree-ssa-loop-ivcanon.c10
-rw-r--r--gcc/tree-ssa-loop-ivopts.c30
-rw-r--r--gcc/tree-ssa-loop.c979
-rw-r--r--gcc/tree-ssa-math-opts.c218
-rw-r--r--gcc/tree-ssa-phiopt.c111
-rw-r--r--gcc/tree-ssa-phiprop.c53
-rw-r--r--gcc/tree-ssa-pre.c112
-rw-r--r--gcc/tree-ssa-reassoc.c82
-rw-r--r--gcc/tree-ssa-sink.c56
-rw-r--r--gcc/tree-ssa-strlen.c74
-rw-r--r--gcc/tree-ssa-structalias.c169
-rw-r--r--gcc/tree-ssa-threadedge.c173
-rw-r--r--gcc/tree-ssa-threadupdate.c82
-rw-r--r--gcc/tree-ssa-uncprop.c53
-rw-r--r--gcc/tree-ssa-uninit.c53
-rw-r--r--gcc/tree-ssa.c153
-rw-r--r--gcc/tree-ssanames.c51
-rw-r--r--gcc/tree-stdarg.c68
-rw-r--r--gcc/tree-streamer-in.c27
-rw-r--r--gcc/tree-streamer-out.c28
-rw-r--r--gcc/tree-switch-conversion.c57
-rw-r--r--gcc/tree-tailcall.c156
-rw-r--r--gcc/tree-vect-data-refs.c123
-rw-r--r--gcc/tree-vect-generic.c116
-rw-r--r--gcc/tree-vect-loop-manip.c25
-rw-r--r--gcc/tree-vect-loop.c63
-rw-r--r--gcc/tree-vect-slp.c2
-rw-r--r--gcc/tree-vect-stmts.c178
-rw-r--r--gcc/tree-vectorizer.c412
-rw-r--r--gcc/tree-vectorizer.h35
-rw-r--r--gcc/tree-vrp.c98
-rw-r--r--gcc/tree.c201
-rw-r--r--gcc/tree.def4
-rw-r--r--gcc/tree.h1741
-rw-r--r--gcc/tsan.c109
-rw-r--r--gcc/ubsan.c417
-rw-r--r--gcc/ubsan.h31
-rw-r--r--gcc/value-prof.c192
-rw-r--r--gcc/value-prof.h4
-rw-r--r--gcc/var-tracking.c77
-rw-r--r--gcc/varasm.c72
-rw-r--r--gcc/varpool.c112
-rw-r--r--gcc/vtable-verify.c793
-rw-r--r--gcc/vtable-verify.h141
-rw-r--r--gcc/web.c52
-rw-r--r--gnattools/ChangeLog9
-rw-r--r--gnattools/Makefile.in9
-rw-r--r--include/ChangeLog14
-rw-r--r--include/dwarf2.def3
-rw-r--r--include/floatformat.h3
-rw-r--r--include/vtv-change-permission.h55
-rw-r--r--libcpp/ChangeLog5
-rwxr-xr-xlibcpp/configure4
-rw-r--r--libcpp/configure.ac4
-rw-r--r--libgcc/ChangeLog63
-rw-r--r--libgcc/Makefile.in19
-rw-r--r--libgcc/config.host17
-rw-r--r--libgcc/config/aarch64/sfp-machine.h35
-rw-r--r--libgcc/config/aarch64/sync-cache.c29
-rw-r--r--libgcc/config/i386/cpuinfo.c11
-rw-r--r--libgcc/config/ia64/unwind-ia64.h35
-rw-r--r--libgcc/config/mips/libgcc-mips16.ver38
-rw-r--r--libgcc/config/mips/mips16.S39
-rw-r--r--libgcc/config/mips/vr4120-div.S25
-rw-r--r--libgcc/configure16
-rw-r--r--libgcc/configure.ac10
-rw-r--r--libgcc/libgcov.c52
-rw-r--r--libgcc/vtv_end.c66
-rw-r--r--libgcc/vtv_end_preinit.c71
-rw-r--r--libgcc/vtv_start.c65
-rw-r--r--libgcc/vtv_start_preinit.c73
-rw-r--r--libgo/config/libtool.m412
-rwxr-xr-xlibgo/configure16
-rw-r--r--libgo/go/net/cgo_unix.go3
-rw-r--r--libgo/go/reflect/value.go7
-rw-r--r--libgo/go/syscall/mksyscall.awk4
-rw-r--r--libgo/runtime/go-reflect-call.c17
-rw-r--r--libgo/runtime/mgc0.c7
-rw-r--r--libgo/runtime/proc.c20
-rw-r--r--libgo/runtime/runtime.h4
-rw-r--r--libgo/runtime/time.goc8
-rw-r--r--libiberty/ChangeLog6
-rw-r--r--libiberty/floatformat.c13
-rw-r--r--libitm/ChangeLog37
-rw-r--r--libitm/beginend.cc46
-rw-r--r--libitm/config/linux/rwlock.h5
-rw-r--r--libitm/config/posix/rwlock.cc4
-rw-r--r--libitm/config/posix/rwlock.h16
-rw-r--r--libitm/config/s390/target.h4
-rw-r--r--libitm/config/x86/sjlj.S101
-rw-r--r--libitm/config/x86/target.h4
-rw-r--r--libitm/configure.tgt2
-rw-r--r--libitm/libitm.h15
-rw-r--r--libitm/libitm_i.h26
-rw-r--r--libsanitizer/ChangeLog16
-rw-r--r--libsanitizer/Makefile.am6
-rw-r--r--libsanitizer/Makefile.in8
-rwxr-xr-xlibsanitizer/configure14
-rw-r--r--libsanitizer/configure.ac2
-rwxr-xr-xlibsanitizer/merge.sh1
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_common.h3
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_printf.cc2
-rw-r--r--libsanitizer/sanitizer_common/sanitizer_report_decorator.h26
-rw-r--r--libsanitizer/ubsan/Makefile.am69
-rw-r--r--libsanitizer/ubsan/Makefile.in580
-rw-r--r--libsanitizer/ubsan/libtool-version6
-rw-r--r--libsanitizer/ubsan/ubsan_diag.cc261
-rw-r--r--libsanitizer/ubsan/ubsan_diag.h200
-rw-r--r--libsanitizer/ubsan/ubsan_handlers.cc258
-rw-r--r--libsanitizer/ubsan/ubsan_handlers.h115
-rw-r--r--libsanitizer/ubsan/ubsan_handlers_cxx.cc72
-rw-r--r--libsanitizer/ubsan/ubsan_handlers_cxx.h38
-rw-r--r--libsanitizer/ubsan/ubsan_type_hash.cc246
-rw-r--r--libsanitizer/ubsan/ubsan_type_hash.h61
-rw-r--r--libsanitizer/ubsan/ubsan_value.cc99
-rw-r--r--libsanitizer/ubsan/ubsan_value.h202
-rw-r--r--libstdc++-v3/ChangeLog495
-rw-r--r--libstdc++-v3/Makefile.in5
-rw-r--r--libstdc++-v3/acinclude.m432
-rw-r--r--libstdc++-v3/config/abi/pre/gnu.ver10
-rwxr-xr-xlibstdc++-v3/configure82
-rw-r--r--libstdc++-v3/configure.ac7
-rw-r--r--libstdc++-v3/doc/Makefile.in5
-rw-r--r--libstdc++-v3/doc/xml/manual/configure.xml12
-rw-r--r--libstdc++-v3/fragment.am6
-rw-r--r--libstdc++-v3/include/Makefile.am16
-rw-r--r--libstdc++-v3/include/Makefile.in21
-rw-r--r--libstdc++-v3/include/bits/basic_string.h7
-rw-r--r--libstdc++-v3/include/bits/hashtable.h349
-rw-r--r--libstdc++-v3/include/bits/hashtable_policy.h249
-rw-r--r--libstdc++-v3/include/bits/random.h8
-rw-r--r--libstdc++-v3/include/bits/random.tcc2
-rw-r--r--libstdc++-v3/include/bits/regex.h1170
-rw-r--r--libstdc++-v3/include/bits/regex_automaton.h285
-rw-r--r--libstdc++-v3/include/bits/regex_automaton.tcc207
-rw-r--r--libstdc++-v3/include/bits/regex_compiler.h1156
-rw-r--r--libstdc++-v3/include/bits/regex_compiler.tcc415
-rw-r--r--libstdc++-v3/include/bits/regex_constants.h212
-rw-r--r--libstdc++-v3/include/bits/regex_cursor.h105
-rw-r--r--libstdc++-v3/include/bits/regex_error.h2
-rw-r--r--libstdc++-v3/include/bits/regex_executor.h225
-rw-r--r--libstdc++-v3/include/bits/regex_executor.tcc330
-rw-r--r--libstdc++-v3/include/bits/regex_grep_matcher.h173
-rw-r--r--libstdc++-v3/include/bits/regex_grep_matcher.tcc243
-rw-r--r--libstdc++-v3/include/bits/regex_nfa.h415
-rw-r--r--libstdc++-v3/include/bits/regex_nfa.tcc174
-rw-r--r--libstdc++-v3/include/bits/regex_scanner.h196
-rw-r--r--libstdc++-v3/include/bits/regex_scanner.tcc611
-rw-r--r--libstdc++-v3/include/bits/stl_algobase.h2
-rw-r--r--libstdc++-v3/include/bits/stl_bvector.h2
-rw-r--r--libstdc++-v3/include/debug/formatter.h4
-rw-r--r--libstdc++-v3/include/debug/forward_list7
-rw-r--r--libstdc++-v3/include/debug/functions.h276
-rw-r--r--libstdc++-v3/include/debug/list9
-rw-r--r--libstdc++-v3/include/debug/macros.h61
-rw-r--r--libstdc++-v3/include/debug/safe_iterator.h3
-rw-r--r--libstdc++-v3/include/debug/safe_local_iterator.h3
-rw-r--r--libstdc++-v3/include/debug/string5
-rw-r--r--libstdc++-v3/include/ext/atomicity.h2
-rw-r--r--libstdc++-v3/include/ext/random2
-rw-r--r--libstdc++-v3/include/ext/vstring.h8
-rw-r--r--libstdc++-v3/include/std/atomic12
-rw-r--r--libstdc++-v3/include/std/bitset2
-rw-r--r--libstdc++-v3/include/std/regex9
-rw-r--r--libstdc++-v3/include/tr1/cmath19
-rw-r--r--libstdc++-v3/libsupc++/Makefile.am15
-rw-r--r--libstdc++-v3/libsupc++/Makefile.in24
-rw-r--r--libstdc++-v3/libsupc++/vtv_stubs.cc100
-rw-r--r--libstdc++-v3/po/Makefile.in5
-rw-r--r--libstdc++-v3/python/Makefile.in5
-rw-r--r--libstdc++-v3/python/libstdcxx/v6/printers.py12
-rwxr-xr-xlibstdc++-v3/scripts/testsuite_flags.in11
-rw-r--r--libstdc++-v3/src/Makefile.am5
-rw-r--r--libstdc++-v3/src/Makefile.in8
-rw-r--r--libstdc++-v3/src/c++11/Makefile.am7
-rw-r--r--libstdc++-v3/src/c++11/Makefile.in13
-rw-r--r--libstdc++-v3/src/c++11/debug.cc16
-rw-r--r--libstdc++-v3/src/c++11/functexcept.cc2
-rw-r--r--libstdc++-v3/src/c++11/hashtable_c++0x.cc1
-rw-r--r--libstdc++-v3/src/c++11/regex.cc3
-rw-r--r--libstdc++-v3/src/c++98/Makefile.am7
-rw-r--r--libstdc++-v3/src/c++98/Makefile.in13
-rw-r--r--libstdc++-v3/src/c++98/compatibility.cc19
-rw-r--r--libstdc++-v3/testsuite/17_intro/freestanding.cc2
-rw-r--r--libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c2
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/58163.cc39
-rw-r--r--libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/58163.cc39
-rw-r--r--libstdc++-v3/testsuite/23_containers/deque/debug/insert5_neg.cc33
-rw-r--r--libstdc++-v3/testsuite/23_containers/forward_list/debug/insert_after4_neg.cc35
-rw-r--r--libstdc++-v3/testsuite/23_containers/list/debug/insert5_neg.cc34
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/unordered_set/not_default_constructible_hash_neg.cc2
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/debug/57779_neg.cc38
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/debug/insert5_neg.cc33
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/debug/insert6_neg.cc48
-rw-r--r--libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/58148.cc35
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/operators/58302.cc34
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc2
-rw-r--r--libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc2
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc50
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc57
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc52
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc78
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc47
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc58
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc53
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc52
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc51
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc44
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/53622.cc35
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/57173.cc23
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc66
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc43
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc43
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc68
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc69
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc34
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc48
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc42
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc59
-rw-r--r--libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc53
-rw-r--r--libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc65
-rw-r--r--libstdc++-v3/testsuite/Makefile.in5
-rw-r--r--libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/default.cc4
-rw-r--r--libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/parms.cc4
-rw-r--r--libstdc++-v3/testsuite/ext/random/triangular_distribution/cons/default.cc (renamed from libstdc++-v3/testsuite/ext/triangular_distribution/cons/default.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/triangular_distribution/cons/parms.cc (renamed from libstdc++-v3/testsuite/ext/triangular_distribution/cons/parms.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/equal.cc (renamed from libstdc++-v3/testsuite/ext/triangular_distribution/operators/equal.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/inequal.cc (renamed from libstdc++-v3/testsuite/ext/triangular_distribution/operators/inequal.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/serialize.cc (renamed from libstdc++-v3/testsuite/ext/triangular_distribution/operators/serialize.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/triangular_distribution/requirements/explicit_instantiation/1.cc (renamed from libstdc++-v3/testsuite/ext/triangular_distribution/requirements/explicit_instantiation/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/triangular_distribution/requirements/typedefs.cc (renamed from libstdc++-v3/testsuite/ext/triangular_distribution/requirements/typedefs.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/von_mises_distribution/cons/default.cc (renamed from libstdc++-v3/testsuite/ext/von_mises_distribution/cons/default.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/von_mises_distribution/cons/parms.cc (renamed from libstdc++-v3/testsuite/ext/von_mises_distribution/cons/parms.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/equal.cc (renamed from libstdc++-v3/testsuite/ext/von_mises_distribution/operators/equal.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/inequal.cc (renamed from libstdc++-v3/testsuite/ext/von_mises_distribution/operators/inequal.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/serialize.cc (renamed from libstdc++-v3/testsuite/ext/von_mises_distribution/operators/serialize.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/von_mises_distribution/requirements/explicit_instantiation/1.cc (renamed from libstdc++-v3/testsuite/ext/von_mises_distribution/requirements/explicit_instantiation/1.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/random/von_mises_distribution/requirements/typedefs.cc (renamed from libstdc++-v3/testsuite/ext/von_mises_distribution/requirements/typedefs.cc)0
-rw-r--r--libstdc++-v3/testsuite/ext/vstring/element_access/char/58163.cc40
-rw-r--r--libstdc++-v3/testsuite/ext/vstring/element_access/wchar_t/58163.cc40
-rw-r--r--libstdc++-v3/testsuite/lib/libstdc++.exp17
-rw-r--r--libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc36
-rw-r--r--libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc33
-rw-r--r--libstdc++-v3/testsuite/util/debug/checks.h30
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_common_types.h17
-rw-r--r--libvtv/ChangeLog193
-rw-r--r--libvtv/Makefile.am78
-rw-r--r--libvtv/Makefile.in762
-rw-r--r--libvtv/acinclude.m447
-rw-r--r--libvtv/aclocal.m41016
-rwxr-xr-xlibvtv/configure17982
-rw-r--r--libvtv/configure.ac143
-rw-r--r--libvtv/configure.tgt37
-rw-r--r--libvtv/scripts/run-testsuite.sh226
-rw-r--r--libvtv/scripts/sum-vtv-counts.c150
-rw-r--r--libvtv/testsuite/Makefile.am11
-rw-r--r--libvtv/testsuite/Makefile.in400
-rw-r--r--libvtv/testsuite/config/default.exp17
-rw-r--r--libvtv/testsuite/lib/libvtv-dg.exp21
-rw-r--r--libvtv/testsuite/lib/libvtv.exp220
-rw-r--r--libvtv/testsuite/libvtv.cc/bb_tests.cc53
-rw-r--r--libvtv/testsuite/libvtv.cc/const_vtable.cc83
-rw-r--r--libvtv/testsuite/libvtv.cc/dataentry.cc39
-rw-r--r--libvtv/testsuite/libvtv.cc/derived-lib.cpp18
-rw-r--r--libvtv/testsuite/libvtv.cc/derived-main.cpp18
-rw-r--r--libvtv/testsuite/libvtv.cc/derived.list1
-rw-r--r--libvtv/testsuite/libvtv.cc/dup_name.cc62
-rw-r--r--libvtv/testsuite/libvtv.cc/environment.cc38
-rw-r--r--libvtv/testsuite/libvtv.cc/event-defintions.cpp10
-rw-r--r--libvtv/testsuite/libvtv.cc/event-main.cpp15
-rw-r--r--libvtv/testsuite/libvtv.cc/event-private.cpp10
-rw-r--r--libvtv/testsuite/libvtv.cc/event-private.h7
-rw-r--r--libvtv/testsuite/libvtv.cc/event.h29
-rw-r--r--libvtv/testsuite/libvtv.cc/event.list1
-rw-r--r--libvtv/testsuite/libvtv.cc/mul_inh.cc27
-rw-r--r--libvtv/testsuite/libvtv.cc/nested_vcall_test.cc77
-rw-r--r--libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.cpp16
-rw-r--r--libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.h14
-rw-r--r--libvtv/testsuite/libvtv.cc/parts-test-extra-parts.cpp15
-rw-r--r--libvtv/testsuite/libvtv.cc/parts-test-extra-parts.h13
-rw-r--r--libvtv/testsuite/libvtv.cc/parts-test-main.cpp39
-rw-r--r--libvtv/testsuite/libvtv.cc/parts-test-main.h15
-rw-r--r--libvtv/testsuite/libvtv.cc/parts-test.list1
-rw-r--r--libvtv/testsuite/libvtv.cc/povray-derived.cc74
-rw-r--r--libvtv/testsuite/libvtv.cc/register_set_pair.cc101
-rw-r--r--libvtv/testsuite/libvtv.cc/register_set_pair_inserts.cc106
-rw-r--r--libvtv/testsuite/libvtv.cc/template-list-iostream.cc120
-rw-r--r--libvtv/testsuite/libvtv.cc/template-list.cc94
-rw-r--r--libvtv/testsuite/libvtv.cc/template-list2.cc46
-rw-r--r--libvtv/testsuite/libvtv.cc/test1.cc74
-rw-r--r--libvtv/testsuite/libvtv.cc/thunk.cc37
-rw-r--r--libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc113
-rw-r--r--libvtv/testsuite/libvtv.cc/v8-test-2.cc97
-rw-r--r--libvtv/testsuite/libvtv.cc/virtfunc-test.cc222
-rw-r--r--libvtv/testsuite/libvtv.cc/virtual_inheritance.cc48
-rw-r--r--libvtv/testsuite/libvtv.cc/vtv.exp83
-rw-r--r--libvtv/testsuite/libvtv.cc/xlan-test.cc185
-rw-r--r--libvtv/testsuite/libvtv.mempool.cc/mempool.exp68
-rw-r--r--libvtv/testsuite/libvtv.mempool.cc/mempool_negative.cc193
-rw-r--r--libvtv/testsuite/libvtv.mempool.cc/mempool_positive.cc199
-rw-r--r--libvtv/testsuite/libvtv.mt.cc/mt.exp68
-rw-r--r--libvtv/testsuite/libvtv.mt.cc/register_set_pair_inserts_mt.cc156
-rw-r--r--libvtv/testsuite/libvtv.mt.cc/register_set_pair_mt.cc158
-rw-r--r--libvtv/testsuite/other-tests/Makefile.am52
-rw-r--r--libvtv/testsuite/other-tests/Makefile.in379
-rw-r--r--libvtv/testsuite/other-tests/README8
-rw-r--r--libvtv/testsuite/other-tests/dlopen.cc38
-rw-r--r--libvtv/testsuite/other-tests/dlopen_mt.cc112
-rw-r--r--libvtv/testsuite/other-tests/environment-fail-32.s514
-rw-r--r--libvtv/testsuite/other-tests/environment-fail-64.s425
-rw-r--r--libvtv/testsuite/other-tests/field-test.cc94
-rw-r--r--libvtv/testsuite/other-tests/replace-fail.cc11
-rw-r--r--libvtv/testsuite/other-tests/so.cc93
-rw-r--r--libvtv/testsuite/other-tests/temp_deriv.cc67
-rw-r--r--libvtv/testsuite/other-tests/temp_deriv2.cc69
-rw-r--r--libvtv/testsuite/other-tests/temp_deriv3.cc79
-rw-r--r--libvtv/vtv_fail.cc233
-rw-r--r--libvtv/vtv_fail.h59
-rw-r--r--libvtv/vtv_malloc.cc267
-rw-r--r--libvtv/vtv_malloc.h98
-rw-r--r--libvtv/vtv_map.h311
-rw-r--r--libvtv/vtv_rts.cc1523
-rw-r--r--libvtv/vtv_rts.h50
-rw-r--r--libvtv/vtv_set.h653
-rw-r--r--libvtv/vtv_utils.cc161
-rw-r--r--libvtv/vtv_utils.h63
1297 files changed, 90469 insertions, 21001 deletions
diff --git a/ChangeLog b/ChangeLog
index 712c2c2016d..1c74171eb2e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,57 @@
+2013-09-03 Richard Biener <rguenther@suse.de>
+
+ * configure.ac: Also allow ISL 0.12.
+ * configure: Regenerated.
+
+2013-08-30 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
+2013-08-27 David Malcolm <dmalcolm@redhat.com>
+
+ * MAINTAINERS (gdbhooks.py): Add myself as maintainer.
+
+2013-08-26 Caroline Tice <cmtice@google.com>
+
+ * MAINTAINERS: Correct earliers update: Move myself from libvtv
+ "Various Reviewers" to libvtv "Various Maintainers".
+
+2013-08-20 Steven Bosscher <steven@gcc.gnu.org>
+
+ * MAINTAINERS: Add myself as RTL optimizers reviewer.
+
+2013-08-19 Benjamin De Kosnik <bkoz@gnu.org>
+
+ * MAINTAINERS: Update name, email.
+
+2013-08-13 Adam Butcher <adam@jessamine.co.uk>
+
+ * MAINTAINERS (Write After Approval): Add myself.
+
+2013-08-12 Caroline Tice <cmtice@google.com>
+
+ * MAINTAINERS: Add myself as libvtv maintainer. Correct my email
+ address in the Write After Approval section.
+
+2013-08-09 Carlos O'Donell <carlos@redhat.com>
+
+ * MAINTAINERS (Write After Approval): Update email.
+
+2013-08-08 Benjamin Kosnik <bkoz@redhat.com>
+
+ * configure.ac: Adjust to check VTV_SUPPORTED.
+ * configure: Regenerated.
+
+2013-08-02 Caroline Tice <cmtice@google.com>
+
+ * configure.ac: Add target-libvtv to target_libraries; disable libvtv
+ on non-linux systems; add target-libvtv to noconfigdirs; add
+ libsupc++/.libs to C++ library search paths.
+ * configure: Regenerated.
+ * Makefile.def: Add libvtv to target_modules; make libvtv depend on
+ libstdc++ and libgcc.
+ * Makefile.in: Regenerated.
+
2013-07-19 Yvan Roux <yvan.roux@linaro.org>
* MAINTAINERS (Write After Approval): Add myself.
@@ -17,12 +71,6 @@
* configure.ac: Sync from binutils.
* configure: Regenerate.
-2013-07-10 Jack Howarth <howarth@bromo.med.uc.edu>
-
- PR target/57792
- * configure.ac: Use --with-sysroot=\"`xcrun --show-sdk-path`\" on darwin13 and later.
- * configure: Regenerated.
-
2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
* MAINTAINERS (Write After Approval): Add myself.
diff --git a/ChangeLog.MELT b/ChangeLog.MELT
index 72f26a4fcc5..f09fbf0569b 100644
--- a/ChangeLog.MELT
+++ b/ChangeLog.MELT
@@ -1,4 +1,10 @@
+2013-09-09 Basile Starynkevitch <basile@starynkevitch.net>
+
+ MELT branch merged with trunk rev 202389 using svnmerge.py; notice
+ that gcc/melt/xtramelt-ana-base.melt has been significantly
+ updated, but some updates are yet missing...
+
2013-07-29 Basile Starynkevitch <basile@starynkevitch.net>
MELT branch merged with trunk rev 201298 using svnmerge.py
diff --git a/MAINTAINERS b/MAINTAINERS
index ba0234c4151..cc89c2ce01d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -178,6 +178,7 @@ libobjc Nicola Pero nicola.pero@meta-innovation.com
libobjc Andrew Pinski pinskia@gmail.com
libquadmath Tobias Burnus burnus@net-b.de
libquadmath Jakub Jelinek jakub@redhat.com
+libvtv Caroline Tice cmtice@google.com
loop discovery Michael Hayes m.hayes@elec.canterbury.ac.nz
soft-fp Joseph Myers joseph@codesourcery.com
scheduler (+ haifa) Jim Wilson wilson@tuliptree.org
@@ -194,7 +195,7 @@ dwarf debugging code Cary Coutant ccoutant@google.com
c++ runtime libs Paolo Carlini paolo.carlini@oracle.com
c++ runtime libs Gabriel Dos Reis gdr@integrable-solutions.net
c++ runtime libs Ulrich Drepper drepper@gmail.com
-c++ runtime libs Benjamin Kosnik bkoz@redhat.com
+c++ runtime libs Benjamin De Kosnik bkoz@gnu.org
c++ runtime libs Loren J. Rittle ljrittle@acm.org
c++ runtime libs Jonathan Wakely redi@gcc.gnu.org
*synthetic multiply Torbjorn Granlund tege@swox.com
@@ -256,6 +257,7 @@ testsuite Rainer Orth ro@CeBiTec.Uni-Bielefeld.DE
testsuite Mike Stump mikestump@comcast.net
testsuite Janis Johnson janisjo@codesourcery.com
register allocation Vladimir Makarov vmakarov@redhat.com
+gdbhooks.py David Malcolm dmalcolm@redhat.com
Note that individuals who maintain parts of the compiler need approval to
check in changes outside of the parts of the compiler they maintain.
@@ -298,6 +300,7 @@ Plugin Le-Chun Wu lcwu@google.com
register allocation Peter Bergner bergner@vnet.ibm.com
register allocation Kenneth Zadeck zadeck@naturalbridge.com
register allocation Seongbae Park seongbae.park@gmail.com
+RTL optimizers Steven Bosscher steven@gcc.gnu.org
selective scheduling Andrey Belevantsev abel@ispras.ru
Note that while reviewers can approve changes to parts of the compiler
@@ -329,13 +332,13 @@ Ian Bolton ian.bolton@arm.com
Andrea Bona andrea.bona@st.com
Paolo Bonzini bonzini@gnu.org
Neil Booth neil@daikokuya.co.uk
-Steven Bosscher steven@gcc.gnu.org
Robert Bowdidge bowdidge@apple.com
Joel Brobecker brobecker@gnat.com
Dave Brolley brolley@redhat.com
Julian Brown julian@codesourcery.com
Christian Bruel christian.bruel@st.com
Kevin Buettner kevinb@redhat.com
+Adam Butcher adam@jessamine.co.uk
Andrew Cagney cagney@redhat.com
Daniel Carrera dcarrera@gmail.com
Stephane Carrez stcarrez@nerim.fr
@@ -359,6 +362,7 @@ Sameera Deshpande sameera.deshpande@arm.com
François Dumont fdumont@gcc.gnu.org
Benoit Dupont de Dinechin benoit.dupont-de-dinechin@st.com
Michael Eager eager@eagercon.com
+Bernd Edlinger bernd.edlinger@hotmail.de
Phil Edwards pme@gcc.gnu.org
Mohan Embar gnustuff@thisiscool.com
Oleg Endo olegendo@gcc.gnu.org
@@ -478,7 +482,7 @@ Thomas Neumann tneumann@users.sourceforge.net
Dan Nicolaescu dann@ics.uci.edu
Dorit Nuzman dorit@il.ibm.com
David O'Brien obrien@FreeBSD.org
-Carlos O'Donell carlos@codesourcery.com
+Carlos O'Donell carlos@redhat.com
Peter O'Gorman pogma@thewrittenword.com
Andrea Ornstein andrea.ornstein@st.com
Seongbae Park seongbae.park@gmail.com
@@ -537,7 +541,7 @@ Chung-Lin Tang cltang@codesourcery.com
Samuel Tardieu sam@rfc1149.net
Dinar Temirbulatov dinar@kugelworks.com
Kresten Krab Thorup krab@gcc.gnu.org
-Caroline Tice ctice@apple.com
+Caroline Tice cmtice@google.com
Kyrylo Tkachov kyrylo.tkachov@arm.com
Konrad Trifunovic konrad.trifunovic@inria.fr
David Ung davidu@mips.com
diff --git a/Makefile.def b/Makefile.def
index 90d9653d530..3ba1a5b9a3a 100644
--- a/Makefile.def
+++ b/Makefile.def
@@ -4,8 +4,7 @@ AutoGen definitions Makefile.tpl;
// Makefile.in is generated from Makefile.tpl by 'autogen Makefile.def'.
// This file was originally written by Nathanael Nerode.
//
-// Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
-// Free Software Foundation
+// Copyright 2002-2013 Free Software Foundation
//
// This file is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
@@ -123,6 +122,10 @@ target_modules = { module= libsanitizer;
bootstrap=true;
lib_path=.libs;
raw_cxx=true; };
+target_modules = { module= libvtv;
+ bootstrap=true;
+ lib_path=.libs;
+ raw_cxx=true; };
target_modules = { module= libssp; lib_path=.libs; };
target_modules = { module= newlib; };
target_modules = { module= libgcc; bootstrap=true; no_check=true; };
@@ -516,6 +519,7 @@ dependencies = { module=configure-target-libobjc; on=configure-target-boehm-gc;
dependencies = { module=all-target-libobjc; on=all-target-boehm-gc; };
dependencies = { module=configure-target-libstdc++-v3; on=configure-target-libgomp; };
dependencies = { module=configure-target-libsanitizer; on=all-target-libstdc++-v3; };
+dependencies = { module=configure-target-libvtv; on=all-target-libstdc++-v3; };
// parallel_list.o and parallel_settings.o depend on omp.h, which is
// generated by the libgomp configure. Unfortunately, due to the use of
// recursive make, we can't be that specific.
@@ -526,6 +530,8 @@ dependencies = { module=install-target-libgfortran; on=install-target-libquadmat
dependencies = { module=install-target-libgfortran; on=install-target-libgcc; };
dependencies = { module=install-target-libsanitizer; on=install-target-libstdc++-v3; };
dependencies = { module=install-target-libsanitizer; on=install-target-libgcc; };
+dependencies = { module=install-target-libvtv; on=install-target-libstdc++-v3; };
+dependencies = { module=install-target-libvtv; on=install-target-libgcc; };
dependencies = { module=install-target-libjava; on=install-target-libgcc; };
dependencies = { module=install-target-libitm; on=install-target-libgcc; };
dependencies = { module=install-target-libobjc; on=install-target-libgcc; };
diff --git a/Makefile.in b/Makefile.in
index bfbaf03417a..a13771d40eb 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -575,7 +575,7 @@ all:
# This is the list of directories that may be needed in RPATH_ENVVAR
# so that programs built for the target machine work.
-TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libmudflap)$(TARGET_LIB_PATH_libsanitizer)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libgomp)$(TARGET_LIB_PATH_libitm)$(TARGET_LIB_PATH_libatomic)$(HOST_LIB_PATH_gcc)
+TARGET_LIB_PATH = $(TARGET_LIB_PATH_libstdc++-v3)$(TARGET_LIB_PATH_libmudflap)$(TARGET_LIB_PATH_libsanitizer)$(TARGET_LIB_PATH_libvtv)$(TARGET_LIB_PATH_libssp)$(TARGET_LIB_PATH_libgomp)$(TARGET_LIB_PATH_libitm)$(TARGET_LIB_PATH_libatomic)$(HOST_LIB_PATH_gcc)
@if target-libstdc++-v3
TARGET_LIB_PATH_libstdc++-v3 = $$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs:
@@ -589,6 +589,10 @@ TARGET_LIB_PATH_libmudflap = $$r/$(TARGET_SUBDIR)/libmudflap/.libs:
TARGET_LIB_PATH_libsanitizer = $$r/$(TARGET_SUBDIR)/libsanitizer/.libs:
@endif target-libsanitizer
+@if target-libvtv
+TARGET_LIB_PATH_libvtv = $$r/$(TARGET_SUBDIR)/libvtv/.libs:
+@endif target-libvtv
+
@if target-libssp
TARGET_LIB_PATH_libssp = $$r/$(TARGET_SUBDIR)/libssp/.libs:
@endif target-libssp
@@ -925,6 +929,7 @@ configure-target: \
maybe-configure-target-libstdc++-v3 \
maybe-configure-target-libmudflap \
maybe-configure-target-libsanitizer \
+ maybe-configure-target-libvtv \
maybe-configure-target-libssp \
maybe-configure-target-newlib \
maybe-configure-target-libgcc \
@@ -1076,6 +1081,9 @@ all-target: maybe-all-target-libmudflap
@if target-libsanitizer-no-bootstrap
all-target: maybe-all-target-libsanitizer
@endif target-libsanitizer-no-bootstrap
+@if target-libvtv-no-bootstrap
+all-target: maybe-all-target-libvtv
+@endif target-libvtv-no-bootstrap
all-target: maybe-all-target-libssp
all-target: maybe-all-target-newlib
@if target-libgcc-no-bootstrap
@@ -1167,6 +1175,7 @@ info-host: maybe-info-lto-plugin
info-target: maybe-info-target-libstdc++-v3
info-target: maybe-info-target-libmudflap
info-target: maybe-info-target-libsanitizer
+info-target: maybe-info-target-libvtv
info-target: maybe-info-target-libssp
info-target: maybe-info-target-newlib
info-target: maybe-info-target-libgcc
@@ -1249,6 +1258,7 @@ dvi-host: maybe-dvi-lto-plugin
dvi-target: maybe-dvi-target-libstdc++-v3
dvi-target: maybe-dvi-target-libmudflap
dvi-target: maybe-dvi-target-libsanitizer
+dvi-target: maybe-dvi-target-libvtv
dvi-target: maybe-dvi-target-libssp
dvi-target: maybe-dvi-target-newlib
dvi-target: maybe-dvi-target-libgcc
@@ -1331,6 +1341,7 @@ pdf-host: maybe-pdf-lto-plugin
pdf-target: maybe-pdf-target-libstdc++-v3
pdf-target: maybe-pdf-target-libmudflap
pdf-target: maybe-pdf-target-libsanitizer
+pdf-target: maybe-pdf-target-libvtv
pdf-target: maybe-pdf-target-libssp
pdf-target: maybe-pdf-target-newlib
pdf-target: maybe-pdf-target-libgcc
@@ -1413,6 +1424,7 @@ html-host: maybe-html-lto-plugin
html-target: maybe-html-target-libstdc++-v3
html-target: maybe-html-target-libmudflap
html-target: maybe-html-target-libsanitizer
+html-target: maybe-html-target-libvtv
html-target: maybe-html-target-libssp
html-target: maybe-html-target-newlib
html-target: maybe-html-target-libgcc
@@ -1495,6 +1507,7 @@ TAGS-host: maybe-TAGS-lto-plugin
TAGS-target: maybe-TAGS-target-libstdc++-v3
TAGS-target: maybe-TAGS-target-libmudflap
TAGS-target: maybe-TAGS-target-libsanitizer
+TAGS-target: maybe-TAGS-target-libvtv
TAGS-target: maybe-TAGS-target-libssp
TAGS-target: maybe-TAGS-target-newlib
TAGS-target: maybe-TAGS-target-libgcc
@@ -1577,6 +1590,7 @@ install-info-host: maybe-install-info-lto-plugin
install-info-target: maybe-install-info-target-libstdc++-v3
install-info-target: maybe-install-info-target-libmudflap
install-info-target: maybe-install-info-target-libsanitizer
+install-info-target: maybe-install-info-target-libvtv
install-info-target: maybe-install-info-target-libssp
install-info-target: maybe-install-info-target-newlib
install-info-target: maybe-install-info-target-libgcc
@@ -1659,6 +1673,7 @@ install-pdf-host: maybe-install-pdf-lto-plugin
install-pdf-target: maybe-install-pdf-target-libstdc++-v3
install-pdf-target: maybe-install-pdf-target-libmudflap
install-pdf-target: maybe-install-pdf-target-libsanitizer
+install-pdf-target: maybe-install-pdf-target-libvtv
install-pdf-target: maybe-install-pdf-target-libssp
install-pdf-target: maybe-install-pdf-target-newlib
install-pdf-target: maybe-install-pdf-target-libgcc
@@ -1741,6 +1756,7 @@ install-html-host: maybe-install-html-lto-plugin
install-html-target: maybe-install-html-target-libstdc++-v3
install-html-target: maybe-install-html-target-libmudflap
install-html-target: maybe-install-html-target-libsanitizer
+install-html-target: maybe-install-html-target-libvtv
install-html-target: maybe-install-html-target-libssp
install-html-target: maybe-install-html-target-newlib
install-html-target: maybe-install-html-target-libgcc
@@ -1823,6 +1839,7 @@ installcheck-host: maybe-installcheck-lto-plugin
installcheck-target: maybe-installcheck-target-libstdc++-v3
installcheck-target: maybe-installcheck-target-libmudflap
installcheck-target: maybe-installcheck-target-libsanitizer
+installcheck-target: maybe-installcheck-target-libvtv
installcheck-target: maybe-installcheck-target-libssp
installcheck-target: maybe-installcheck-target-newlib
installcheck-target: maybe-installcheck-target-libgcc
@@ -1905,6 +1922,7 @@ mostlyclean-host: maybe-mostlyclean-lto-plugin
mostlyclean-target: maybe-mostlyclean-target-libstdc++-v3
mostlyclean-target: maybe-mostlyclean-target-libmudflap
mostlyclean-target: maybe-mostlyclean-target-libsanitizer
+mostlyclean-target: maybe-mostlyclean-target-libvtv
mostlyclean-target: maybe-mostlyclean-target-libssp
mostlyclean-target: maybe-mostlyclean-target-newlib
mostlyclean-target: maybe-mostlyclean-target-libgcc
@@ -1987,6 +2005,7 @@ clean-host: maybe-clean-lto-plugin
clean-target: maybe-clean-target-libstdc++-v3
clean-target: maybe-clean-target-libmudflap
clean-target: maybe-clean-target-libsanitizer
+clean-target: maybe-clean-target-libvtv
clean-target: maybe-clean-target-libssp
clean-target: maybe-clean-target-newlib
clean-target: maybe-clean-target-libgcc
@@ -2069,6 +2088,7 @@ distclean-host: maybe-distclean-lto-plugin
distclean-target: maybe-distclean-target-libstdc++-v3
distclean-target: maybe-distclean-target-libmudflap
distclean-target: maybe-distclean-target-libsanitizer
+distclean-target: maybe-distclean-target-libvtv
distclean-target: maybe-distclean-target-libssp
distclean-target: maybe-distclean-target-newlib
distclean-target: maybe-distclean-target-libgcc
@@ -2151,6 +2171,7 @@ maintainer-clean-host: maybe-maintainer-clean-lto-plugin
maintainer-clean-target: maybe-maintainer-clean-target-libstdc++-v3
maintainer-clean-target: maybe-maintainer-clean-target-libmudflap
maintainer-clean-target: maybe-maintainer-clean-target-libsanitizer
+maintainer-clean-target: maybe-maintainer-clean-target-libvtv
maintainer-clean-target: maybe-maintainer-clean-target-libssp
maintainer-clean-target: maybe-maintainer-clean-target-newlib
maintainer-clean-target: maybe-maintainer-clean-target-libgcc
@@ -2288,6 +2309,7 @@ check-target: \
maybe-check-target-libstdc++-v3 \
maybe-check-target-libmudflap \
maybe-check-target-libsanitizer \
+ maybe-check-target-libvtv \
maybe-check-target-libssp \
maybe-check-target-newlib \
maybe-check-target-libgcc \
@@ -2443,6 +2465,7 @@ install-target: \
maybe-install-target-libstdc++-v3 \
maybe-install-target-libmudflap \
maybe-install-target-libsanitizer \
+ maybe-install-target-libvtv \
maybe-install-target-libssp \
maybe-install-target-newlib \
maybe-install-target-libgcc \
@@ -2545,6 +2568,7 @@ install-strip-target: \
maybe-install-strip-target-libstdc++-v3 \
maybe-install-strip-target-libmudflap \
maybe-install-strip-target-libsanitizer \
+ maybe-install-strip-target-libvtv \
maybe-install-strip-target-libssp \
maybe-install-strip-target-newlib \
maybe-install-strip-target-libgcc \
@@ -33152,6 +33176,980 @@ maintainer-clean-target-libsanitizer:
+.PHONY: configure-target-libvtv maybe-configure-target-libvtv
+maybe-configure-target-libvtv:
+@if gcc-bootstrap
+configure-target-libvtv: stage_current
+@endif gcc-bootstrap
+@if target-libvtv
+maybe-configure-target-libvtv: configure-target-libvtv
+configure-target-libvtv:
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ echo "Checking multilib configuration for libvtv..."; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv ; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libvtv/multilib.tmp 2> /dev/null ; \
+ if test -r $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ if cmp -s $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ rm -f $(TARGET_SUBDIR)/libvtv/multilib.tmp; \
+ else \
+ rm -f $(TARGET_SUBDIR)/libvtv/Makefile; \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ test ! -f $(TARGET_SUBDIR)/libvtv/Makefile || exit 0; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv ; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo Configuring in $(TARGET_SUBDIR)/libvtv; \
+ cd "$(TARGET_SUBDIR)/libvtv" || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(TARGET_SUBDIR)/libvtv/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libvtv"; \
+ libsrcdir="$$s/libvtv"; \
+ rm -f no-such-file || : ; \
+ CONFIG_SITE=no-such-file $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ || exit 1
+@endif target-libvtv
+
+
+
+.PHONY: configure-stage1-target-libvtv maybe-configure-stage1-target-libvtv
+maybe-configure-stage1-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-configure-stage1-target-libvtv: configure-stage1-target-libvtv
+configure-stage1-target-libvtv:
+ @[ $(current_stage) = stage1 ] || $(MAKE) stage1-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE1_TFLAGS)"; \
+ echo "Checking multilib configuration for libvtv..."; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libvtv/multilib.tmp 2> /dev/null ; \
+ if test -r $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ if cmp -s $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ rm -f $(TARGET_SUBDIR)/libvtv/multilib.tmp; \
+ else \
+ rm -f $(TARGET_SUBDIR)/libvtv/Makefile; \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ test ! -f $(TARGET_SUBDIR)/libvtv/Makefile || exit 0; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS; \
+ echo Configuring stage 1 in $(TARGET_SUBDIR)/libvtv ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv ; \
+ cd $(TARGET_SUBDIR)/libvtv || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(TARGET_SUBDIR)/libvtv/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libvtv"; \
+ libsrcdir="$$s/libvtv"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ $(STAGE1_CONFIGURE_FLAGS)
+@endif target-libvtv-bootstrap
+
+.PHONY: configure-stage2-target-libvtv maybe-configure-stage2-target-libvtv
+maybe-configure-stage2-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-configure-stage2-target-libvtv: configure-stage2-target-libvtv
+configure-stage2-target-libvtv:
+ @[ $(current_stage) = stage2 ] || $(MAKE) stage2-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE2_TFLAGS)"; \
+ echo "Checking multilib configuration for libvtv..."; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libvtv/multilib.tmp 2> /dev/null ; \
+ if test -r $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ if cmp -s $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ rm -f $(TARGET_SUBDIR)/libvtv/multilib.tmp; \
+ else \
+ rm -f $(TARGET_SUBDIR)/libvtv/Makefile; \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ test ! -f $(TARGET_SUBDIR)/libvtv/Makefile || exit 0; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS; \
+ echo Configuring stage 2 in $(TARGET_SUBDIR)/libvtv ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv ; \
+ cd $(TARGET_SUBDIR)/libvtv || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(TARGET_SUBDIR)/libvtv/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libvtv"; \
+ libsrcdir="$$s/libvtv"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGE2_CONFIGURE_FLAGS)
+@endif target-libvtv-bootstrap
+
+.PHONY: configure-stage3-target-libvtv maybe-configure-stage3-target-libvtv
+maybe-configure-stage3-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-configure-stage3-target-libvtv: configure-stage3-target-libvtv
+configure-stage3-target-libvtv:
+ @[ $(current_stage) = stage3 ] || $(MAKE) stage3-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE3_TFLAGS)"; \
+ echo "Checking multilib configuration for libvtv..."; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libvtv/multilib.tmp 2> /dev/null ; \
+ if test -r $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ if cmp -s $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ rm -f $(TARGET_SUBDIR)/libvtv/multilib.tmp; \
+ else \
+ rm -f $(TARGET_SUBDIR)/libvtv/Makefile; \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ test ! -f $(TARGET_SUBDIR)/libvtv/Makefile || exit 0; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS; \
+ echo Configuring stage 3 in $(TARGET_SUBDIR)/libvtv ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv ; \
+ cd $(TARGET_SUBDIR)/libvtv || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(TARGET_SUBDIR)/libvtv/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libvtv"; \
+ libsrcdir="$$s/libvtv"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGE3_CONFIGURE_FLAGS)
+@endif target-libvtv-bootstrap
+
+.PHONY: configure-stage4-target-libvtv maybe-configure-stage4-target-libvtv
+maybe-configure-stage4-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-configure-stage4-target-libvtv: configure-stage4-target-libvtv
+configure-stage4-target-libvtv:
+ @[ $(current_stage) = stage4 ] || $(MAKE) stage4-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE4_TFLAGS)"; \
+ echo "Checking multilib configuration for libvtv..."; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libvtv/multilib.tmp 2> /dev/null ; \
+ if test -r $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ if cmp -s $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ rm -f $(TARGET_SUBDIR)/libvtv/multilib.tmp; \
+ else \
+ rm -f $(TARGET_SUBDIR)/libvtv/Makefile; \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ test ! -f $(TARGET_SUBDIR)/libvtv/Makefile || exit 0; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS; \
+ echo Configuring stage 4 in $(TARGET_SUBDIR)/libvtv ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv ; \
+ cd $(TARGET_SUBDIR)/libvtv || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(TARGET_SUBDIR)/libvtv/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libvtv"; \
+ libsrcdir="$$s/libvtv"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGE4_CONFIGURE_FLAGS)
+@endif target-libvtv-bootstrap
+
+.PHONY: configure-stageprofile-target-libvtv maybe-configure-stageprofile-target-libvtv
+maybe-configure-stageprofile-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-configure-stageprofile-target-libvtv: configure-stageprofile-target-libvtv
+configure-stageprofile-target-libvtv:
+ @[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGEprofile_TFLAGS)"; \
+ echo "Checking multilib configuration for libvtv..."; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libvtv/multilib.tmp 2> /dev/null ; \
+ if test -r $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ if cmp -s $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ rm -f $(TARGET_SUBDIR)/libvtv/multilib.tmp; \
+ else \
+ rm -f $(TARGET_SUBDIR)/libvtv/Makefile; \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ test ! -f $(TARGET_SUBDIR)/libvtv/Makefile || exit 0; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS; \
+ echo Configuring stage profile in $(TARGET_SUBDIR)/libvtv ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv ; \
+ cd $(TARGET_SUBDIR)/libvtv || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(TARGET_SUBDIR)/libvtv/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libvtv"; \
+ libsrcdir="$$s/libvtv"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGEprofile_CONFIGURE_FLAGS)
+@endif target-libvtv-bootstrap
+
+.PHONY: configure-stagefeedback-target-libvtv maybe-configure-stagefeedback-target-libvtv
+maybe-configure-stagefeedback-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-configure-stagefeedback-target-libvtv: configure-stagefeedback-target-libvtv
+configure-stagefeedback-target-libvtv:
+ @[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start
+ @$(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGEfeedback_TFLAGS)"; \
+ echo "Checking multilib configuration for libvtv..."; \
+ $(CC_FOR_TARGET) --print-multi-lib > $(TARGET_SUBDIR)/libvtv/multilib.tmp 2> /dev/null ; \
+ if test -r $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ if cmp -s $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; then \
+ rm -f $(TARGET_SUBDIR)/libvtv/multilib.tmp; \
+ else \
+ rm -f $(TARGET_SUBDIR)/libvtv/Makefile; \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ else \
+ mv $(TARGET_SUBDIR)/libvtv/multilib.tmp $(TARGET_SUBDIR)/libvtv/multilib.out; \
+ fi; \
+ test ! -f $(TARGET_SUBDIR)/libvtv/Makefile || exit 0; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ CFLAGS="$(CFLAGS_FOR_TARGET)"; export CFLAGS; \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)"; export CXXFLAGS; \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)"; export LIBCFLAGS; \
+ echo Configuring stage feedback in $(TARGET_SUBDIR)/libvtv ; \
+ $(SHELL) $(srcdir)/mkinstalldirs $(TARGET_SUBDIR)/libvtv ; \
+ cd $(TARGET_SUBDIR)/libvtv || exit 1; \
+ case $(srcdir) in \
+ /* | [A-Za-z]:[\\/]*) topdir=$(srcdir) ;; \
+ *) topdir=`echo $(TARGET_SUBDIR)/libvtv/ | \
+ sed -e 's,\./,,g' -e 's,[^/]*/,../,g' `$(srcdir) ;; \
+ esac; \
+ srcdiroption="--srcdir=$${topdir}/libvtv"; \
+ libsrcdir="$$s/libvtv"; \
+ $(SHELL) $${libsrcdir}/configure \
+ $(TARGET_CONFIGARGS) --build=${build_alias} --host=${target_alias} \
+ --target=${target_alias} $${srcdiroption} \
+ --with-build-libsubdir=$(HOST_SUBDIR) \
+ $(STAGEfeedback_CONFIGURE_FLAGS)
+@endif target-libvtv-bootstrap
+
+
+
+
+
+.PHONY: all-target-libvtv maybe-all-target-libvtv
+maybe-all-target-libvtv:
+@if gcc-bootstrap
+all-target-libvtv: stage_current
+@endif gcc-bootstrap
+@if target-libvtv
+TARGET-target-libvtv=all
+maybe-all-target-libvtv: all-target-libvtv
+all-target-libvtv: configure-target-libvtv
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' \
+ $(TARGET-target-libvtv))
+@endif target-libvtv
+
+
+
+.PHONY: all-stage1-target-libvtv maybe-all-stage1-target-libvtv
+.PHONY: clean-stage1-target-libvtv maybe-clean-stage1-target-libvtv
+maybe-all-stage1-target-libvtv:
+maybe-clean-stage1-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-all-stage1-target-libvtv: all-stage1-target-libvtv
+all-stage1: all-stage1-target-libvtv
+TARGET-stage1-target-libvtv = $(TARGET-target-libvtv)
+all-stage1-target-libvtv: configure-stage1-target-libvtv
+ @[ $(current_stage) = stage1 ] || $(MAKE) stage1-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE1_TFLAGS)"; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' \
+ \
+ TFLAGS="$(STAGE1_TFLAGS)" \
+ $(TARGET-stage1-target-libvtv)
+
+maybe-clean-stage1-target-libvtv: clean-stage1-target-libvtv
+clean-stage1: clean-stage1-target-libvtv
+clean-stage1-target-libvtv:
+ @if [ $(current_stage) = stage1 ]; then \
+ [ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0; \
+ else \
+ [ -f $(TARGET_SUBDIR)/stage1-libvtv/Makefile ] || exit 0; \
+ $(MAKE) stage1-start; \
+ fi; \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' \
+ clean
+@endif target-libvtv-bootstrap
+
+
+.PHONY: all-stage2-target-libvtv maybe-all-stage2-target-libvtv
+.PHONY: clean-stage2-target-libvtv maybe-clean-stage2-target-libvtv
+maybe-all-stage2-target-libvtv:
+maybe-clean-stage2-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-all-stage2-target-libvtv: all-stage2-target-libvtv
+all-stage2: all-stage2-target-libvtv
+TARGET-stage2-target-libvtv = $(TARGET-target-libvtv)
+all-stage2-target-libvtv: configure-stage2-target-libvtv
+ @[ $(current_stage) = stage2 ] || $(MAKE) stage2-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE2_TFLAGS)"; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' \
+ TFLAGS="$(STAGE2_TFLAGS)" \
+ $(TARGET-stage2-target-libvtv)
+
+maybe-clean-stage2-target-libvtv: clean-stage2-target-libvtv
+clean-stage2: clean-stage2-target-libvtv
+clean-stage2-target-libvtv:
+ @if [ $(current_stage) = stage2 ]; then \
+ [ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0; \
+ else \
+ [ -f $(TARGET_SUBDIR)/stage2-libvtv/Makefile ] || exit 0; \
+ $(MAKE) stage2-start; \
+ fi; \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' clean
+@endif target-libvtv-bootstrap
+
+
+.PHONY: all-stage3-target-libvtv maybe-all-stage3-target-libvtv
+.PHONY: clean-stage3-target-libvtv maybe-clean-stage3-target-libvtv
+maybe-all-stage3-target-libvtv:
+maybe-clean-stage3-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-all-stage3-target-libvtv: all-stage3-target-libvtv
+all-stage3: all-stage3-target-libvtv
+TARGET-stage3-target-libvtv = $(TARGET-target-libvtv)
+all-stage3-target-libvtv: configure-stage3-target-libvtv
+ @[ $(current_stage) = stage3 ] || $(MAKE) stage3-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE3_TFLAGS)"; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' \
+ TFLAGS="$(STAGE3_TFLAGS)" \
+ $(TARGET-stage3-target-libvtv)
+
+maybe-clean-stage3-target-libvtv: clean-stage3-target-libvtv
+clean-stage3: clean-stage3-target-libvtv
+clean-stage3-target-libvtv:
+ @if [ $(current_stage) = stage3 ]; then \
+ [ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0; \
+ else \
+ [ -f $(TARGET_SUBDIR)/stage3-libvtv/Makefile ] || exit 0; \
+ $(MAKE) stage3-start; \
+ fi; \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' clean
+@endif target-libvtv-bootstrap
+
+
+.PHONY: all-stage4-target-libvtv maybe-all-stage4-target-libvtv
+.PHONY: clean-stage4-target-libvtv maybe-clean-stage4-target-libvtv
+maybe-all-stage4-target-libvtv:
+maybe-clean-stage4-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-all-stage4-target-libvtv: all-stage4-target-libvtv
+all-stage4: all-stage4-target-libvtv
+TARGET-stage4-target-libvtv = $(TARGET-target-libvtv)
+all-stage4-target-libvtv: configure-stage4-target-libvtv
+ @[ $(current_stage) = stage4 ] || $(MAKE) stage4-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGE4_TFLAGS)"; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' \
+ TFLAGS="$(STAGE4_TFLAGS)" \
+ $(TARGET-stage4-target-libvtv)
+
+maybe-clean-stage4-target-libvtv: clean-stage4-target-libvtv
+clean-stage4: clean-stage4-target-libvtv
+clean-stage4-target-libvtv:
+ @if [ $(current_stage) = stage4 ]; then \
+ [ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0; \
+ else \
+ [ -f $(TARGET_SUBDIR)/stage4-libvtv/Makefile ] || exit 0; \
+ $(MAKE) stage4-start; \
+ fi; \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' clean
+@endif target-libvtv-bootstrap
+
+
+.PHONY: all-stageprofile-target-libvtv maybe-all-stageprofile-target-libvtv
+.PHONY: clean-stageprofile-target-libvtv maybe-clean-stageprofile-target-libvtv
+maybe-all-stageprofile-target-libvtv:
+maybe-clean-stageprofile-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-all-stageprofile-target-libvtv: all-stageprofile-target-libvtv
+all-stageprofile: all-stageprofile-target-libvtv
+TARGET-stageprofile-target-libvtv = $(TARGET-target-libvtv)
+all-stageprofile-target-libvtv: configure-stageprofile-target-libvtv
+ @[ $(current_stage) = stageprofile ] || $(MAKE) stageprofile-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGEprofile_TFLAGS)"; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' \
+ TFLAGS="$(STAGEprofile_TFLAGS)" \
+ $(TARGET-stageprofile-target-libvtv)
+
+maybe-clean-stageprofile-target-libvtv: clean-stageprofile-target-libvtv
+clean-stageprofile: clean-stageprofile-target-libvtv
+clean-stageprofile-target-libvtv:
+ @if [ $(current_stage) = stageprofile ]; then \
+ [ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0; \
+ else \
+ [ -f $(TARGET_SUBDIR)/stageprofile-libvtv/Makefile ] || exit 0; \
+ $(MAKE) stageprofile-start; \
+ fi; \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' clean
+@endif target-libvtv-bootstrap
+
+
+.PHONY: all-stagefeedback-target-libvtv maybe-all-stagefeedback-target-libvtv
+.PHONY: clean-stagefeedback-target-libvtv maybe-clean-stagefeedback-target-libvtv
+maybe-all-stagefeedback-target-libvtv:
+maybe-clean-stagefeedback-target-libvtv:
+@if target-libvtv-bootstrap
+maybe-all-stagefeedback-target-libvtv: all-stagefeedback-target-libvtv
+all-stagefeedback: all-stagefeedback-target-libvtv
+TARGET-stagefeedback-target-libvtv = $(TARGET-target-libvtv)
+all-stagefeedback-target-libvtv: configure-stagefeedback-target-libvtv
+ @[ $(current_stage) = stagefeedback ] || $(MAKE) stagefeedback-start
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ TFLAGS="$(STAGEfeedback_TFLAGS)"; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) \
+ CFLAGS="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS="$(LIBCFLAGS_FOR_TARGET)" \
+ CFLAGS_FOR_TARGET="$(CFLAGS_FOR_TARGET)" \
+ CXXFLAGS_FOR_TARGET="$(CXXFLAGS_FOR_TARGET)" \
+ LIBCFLAGS_FOR_TARGET="$(LIBCFLAGS_FOR_TARGET)" \
+ $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' \
+ TFLAGS="$(STAGEfeedback_TFLAGS)" \
+ $(TARGET-stagefeedback-target-libvtv)
+
+maybe-clean-stagefeedback-target-libvtv: clean-stagefeedback-target-libvtv
+clean-stagefeedback: clean-stagefeedback-target-libvtv
+clean-stagefeedback-target-libvtv:
+ @if [ $(current_stage) = stagefeedback ]; then \
+ [ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0; \
+ else \
+ [ -f $(TARGET_SUBDIR)/stagefeedback-libvtv/Makefile ] || exit 0; \
+ $(MAKE) stagefeedback-start; \
+ fi; \
+ cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(EXTRA_TARGET_FLAGS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' clean
+@endif target-libvtv-bootstrap
+
+
+
+
+
+
+.PHONY: check-target-libvtv maybe-check-target-libvtv
+maybe-check-target-libvtv:
+@if target-libvtv
+maybe-check-target-libvtv: check-target-libvtv
+
+check-target-libvtv:
+ @: $(MAKE); $(unstage)
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) 'CXX=$$(RAW_CXX_FOR_TARGET)' 'CXX_FOR_TARGET=$$(RAW_CXX_FOR_TARGET)' check)
+
+@endif target-libvtv
+
+.PHONY: install-target-libvtv maybe-install-target-libvtv
+maybe-install-target-libvtv:
+@if target-libvtv
+maybe-install-target-libvtv: install-target-libvtv
+
+install-target-libvtv: installdirs
+ @: $(MAKE); $(unstage)
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) install)
+
+@endif target-libvtv
+
+.PHONY: install-strip-target-libvtv maybe-install-strip-target-libvtv
+maybe-install-strip-target-libvtv:
+@if target-libvtv
+maybe-install-strip-target-libvtv: install-strip-target-libvtv
+
+install-strip-target-libvtv: installdirs
+ @: $(MAKE); $(unstage)
+ @r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(TARGET_FLAGS_TO_PASS) install-strip)
+
+@endif target-libvtv
+
+# Other targets (info, dvi, pdf, etc.)
+
+.PHONY: maybe-info-target-libvtv info-target-libvtv
+maybe-info-target-libvtv:
+@if target-libvtv
+maybe-info-target-libvtv: info-target-libvtv
+
+info-target-libvtv: \
+ configure-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing info in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ info) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-dvi-target-libvtv dvi-target-libvtv
+maybe-dvi-target-libvtv:
+@if target-libvtv
+maybe-dvi-target-libvtv: dvi-target-libvtv
+
+dvi-target-libvtv: \
+ configure-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing dvi in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ dvi) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-pdf-target-libvtv pdf-target-libvtv
+maybe-pdf-target-libvtv:
+@if target-libvtv
+maybe-pdf-target-libvtv: pdf-target-libvtv
+
+pdf-target-libvtv: \
+ configure-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing pdf in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ pdf) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-html-target-libvtv html-target-libvtv
+maybe-html-target-libvtv:
+@if target-libvtv
+maybe-html-target-libvtv: html-target-libvtv
+
+html-target-libvtv: \
+ configure-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing html in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ html) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-TAGS-target-libvtv TAGS-target-libvtv
+maybe-TAGS-target-libvtv:
+@if target-libvtv
+maybe-TAGS-target-libvtv: TAGS-target-libvtv
+
+TAGS-target-libvtv: \
+ configure-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing TAGS in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ TAGS) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-install-info-target-libvtv install-info-target-libvtv
+maybe-install-info-target-libvtv:
+@if target-libvtv
+maybe-install-info-target-libvtv: install-info-target-libvtv
+
+install-info-target-libvtv: \
+ configure-target-libvtv \
+ info-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing install-info in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ install-info) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-install-pdf-target-libvtv install-pdf-target-libvtv
+maybe-install-pdf-target-libvtv:
+@if target-libvtv
+maybe-install-pdf-target-libvtv: install-pdf-target-libvtv
+
+install-pdf-target-libvtv: \
+ configure-target-libvtv \
+ pdf-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing install-pdf in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ install-pdf) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-install-html-target-libvtv install-html-target-libvtv
+maybe-install-html-target-libvtv:
+@if target-libvtv
+maybe-install-html-target-libvtv: install-html-target-libvtv
+
+install-html-target-libvtv: \
+ configure-target-libvtv \
+ html-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing install-html in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ install-html) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-installcheck-target-libvtv installcheck-target-libvtv
+maybe-installcheck-target-libvtv:
+@if target-libvtv
+maybe-installcheck-target-libvtv: installcheck-target-libvtv
+
+installcheck-target-libvtv: \
+ configure-target-libvtv
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing installcheck in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ installcheck) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-mostlyclean-target-libvtv mostlyclean-target-libvtv
+maybe-mostlyclean-target-libvtv:
+@if target-libvtv
+maybe-mostlyclean-target-libvtv: mostlyclean-target-libvtv
+
+mostlyclean-target-libvtv:
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing mostlyclean in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ mostlyclean) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-clean-target-libvtv clean-target-libvtv
+maybe-clean-target-libvtv:
+@if target-libvtv
+maybe-clean-target-libvtv: clean-target-libvtv
+
+clean-target-libvtv:
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing clean in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ clean) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-distclean-target-libvtv distclean-target-libvtv
+maybe-distclean-target-libvtv:
+@if target-libvtv
+maybe-distclean-target-libvtv: distclean-target-libvtv
+
+distclean-target-libvtv:
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing distclean in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ distclean) \
+ || exit 1
+
+@endif target-libvtv
+
+.PHONY: maybe-maintainer-clean-target-libvtv maintainer-clean-target-libvtv
+maybe-maintainer-clean-target-libvtv:
+@if target-libvtv
+maybe-maintainer-clean-target-libvtv: maintainer-clean-target-libvtv
+
+maintainer-clean-target-libvtv:
+ @: $(MAKE); $(unstage)
+ @[ -f $(TARGET_SUBDIR)/libvtv/Makefile ] || exit 0 ; \
+ r=`${PWD_COMMAND}`; export r; \
+ s=`cd $(srcdir); ${PWD_COMMAND}`; export s; \
+ $(RAW_CXX_TARGET_EXPORTS) \
+ echo "Doing maintainer-clean in $(TARGET_SUBDIR)/libvtv" ; \
+ for flag in $(EXTRA_TARGET_FLAGS); do \
+ eval `echo "$$flag" | sed -e "s|^\([^=]*\)=\(.*\)|\1='\2'; export \1|"`; \
+ done; \
+ (cd $(TARGET_SUBDIR)/libvtv && \
+ $(MAKE) $(BASE_FLAGS_TO_PASS) "AR=$${AR}" "AS=$${AS}" \
+ "CC=$${CC}" "CXX=$${CXX}" "LD=$${LD}" "NM=$${NM}" \
+ "RANLIB=$${RANLIB}" \
+ "DLLTOOL=$${DLLTOOL}" "WINDRES=$${WINDRES}" "WINDMC=$${WINDMC}" \
+ maintainer-clean) \
+ || exit 1
+
+@endif target-libvtv
+
+
+
+
+
.PHONY: configure-target-libssp maybe-configure-target-libssp
maybe-configure-target-libssp:
@if gcc-bootstrap
@@ -45384,6 +46382,12 @@ configure-stage3-target-libsanitizer: maybe-all-stage3-gcc
configure-stage4-target-libsanitizer: maybe-all-stage4-gcc
configure-stageprofile-target-libsanitizer: maybe-all-stageprofile-gcc
configure-stagefeedback-target-libsanitizer: maybe-all-stagefeedback-gcc
+configure-stage1-target-libvtv: maybe-all-stage1-gcc
+configure-stage2-target-libvtv: maybe-all-stage2-gcc
+configure-stage3-target-libvtv: maybe-all-stage3-gcc
+configure-stage4-target-libvtv: maybe-all-stage4-gcc
+configure-stageprofile-target-libvtv: maybe-all-stageprofile-gcc
+configure-stagefeedback-target-libvtv: maybe-all-stagefeedback-gcc
configure-target-libssp: stage_last
configure-target-newlib: stage_last
configure-stage1-target-libgcc: maybe-all-stage1-gcc
@@ -45420,6 +46424,7 @@ configure-target-libatomic: stage_last
configure-target-libstdc++-v3: maybe-all-gcc
configure-target-libmudflap: maybe-all-gcc
configure-target-libsanitizer: maybe-all-gcc
+configure-target-libvtv: maybe-all-gcc
configure-target-libssp: maybe-all-gcc
configure-target-newlib: maybe-all-gcc
configure-target-libgcc: maybe-all-gcc
@@ -46195,6 +47200,14 @@ configure-stage3-target-libsanitizer: maybe-all-stage3-target-libstdc++-v3
configure-stage4-target-libsanitizer: maybe-all-stage4-target-libstdc++-v3
configure-stageprofile-target-libsanitizer: maybe-all-stageprofile-target-libstdc++-v3
configure-stagefeedback-target-libsanitizer: maybe-all-stagefeedback-target-libstdc++-v3
+configure-target-libvtv: maybe-all-target-libstdc++-v3
+
+configure-stage1-target-libvtv: maybe-all-stage1-target-libstdc++-v3
+configure-stage2-target-libvtv: maybe-all-stage2-target-libstdc++-v3
+configure-stage3-target-libvtv: maybe-all-stage3-target-libstdc++-v3
+configure-stage4-target-libvtv: maybe-all-stage4-target-libstdc++-v3
+configure-stageprofile-target-libvtv: maybe-all-stageprofile-target-libstdc++-v3
+configure-stagefeedback-target-libvtv: maybe-all-stagefeedback-target-libstdc++-v3
all-target-libstdc++-v3: maybe-configure-target-libgomp
all-stage1-target-libstdc++-v3: maybe-configure-stage1-target-libgomp
@@ -46208,6 +47221,8 @@ install-target-libgfortran: maybe-install-target-libquadmath
install-target-libgfortran: maybe-install-target-libgcc
install-target-libsanitizer: maybe-install-target-libstdc++-v3
install-target-libsanitizer: maybe-install-target-libgcc
+install-target-libvtv: maybe-install-target-libstdc++-v3
+install-target-libvtv: maybe-install-target-libgcc
install-target-libjava: maybe-install-target-libgcc
install-target-libitm: maybe-install-target-libgcc
install-target-libobjc: maybe-install-target-libgcc
@@ -46237,6 +47252,12 @@ configure-stage3-target-libsanitizer: maybe-all-stage3-target-libgcc
configure-stage4-target-libsanitizer: maybe-all-stage4-target-libgcc
configure-stageprofile-target-libsanitizer: maybe-all-stageprofile-target-libgcc
configure-stagefeedback-target-libsanitizer: maybe-all-stagefeedback-target-libgcc
+configure-stage1-target-libvtv: maybe-all-stage1-target-libgcc
+configure-stage2-target-libvtv: maybe-all-stage2-target-libgcc
+configure-stage3-target-libvtv: maybe-all-stage3-target-libgcc
+configure-stage4-target-libvtv: maybe-all-stage4-target-libgcc
+configure-stageprofile-target-libvtv: maybe-all-stageprofile-target-libgcc
+configure-stagefeedback-target-libvtv: maybe-all-stagefeedback-target-libgcc
configure-stage1-target-libgomp: maybe-all-stage1-target-libgcc
configure-stage2-target-libgomp: maybe-all-stage2-target-libgcc
configure-stage3-target-libgomp: maybe-all-stage3-target-libgcc
@@ -46249,6 +47270,7 @@ configure-stagefeedback-target-libgomp: maybe-all-stagefeedback-target-libgcc
configure-target-libstdc++-v3: maybe-all-target-libgcc
configure-target-libmudflap: maybe-all-target-libgcc
configure-target-libsanitizer: maybe-all-target-libgcc
+configure-target-libvtv: maybe-all-target-libgcc
configure-target-libssp: maybe-all-target-libgcc
configure-target-newlib: maybe-all-target-libgcc
configure-target-libbacktrace: maybe-all-target-libgcc
@@ -46277,6 +47299,8 @@ configure-target-libmudflap: maybe-all-target-newlib maybe-all-target-libgloss
configure-target-libsanitizer: maybe-all-target-newlib maybe-all-target-libgloss
+configure-target-libvtv: maybe-all-target-newlib maybe-all-target-libgloss
+
configure-target-libssp: maybe-all-target-newlib maybe-all-target-libgloss
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index e55cb37db73..0cd4dbec4d5 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,20 +1,25 @@
+2013-09-04 Matthias Klose <doko@ubuntu.com>
+
+ * Makefile.am (libgcjgc_la_LIBADD): Add EXTRA_TEST_LIBS.
+ * Makefile.in: Regenerate.
+
2013-03-16 Yvan Roux <yvan.roux@linaro.org>
- * include/private/gcconfig.h (AARCH64): New macro (defined only if
- __aarch64__).
- (CPP_WORDSZ): Define for AArch64.
- (MACH_TYPE): Likewise.
- (ALIGNMENT): Likewise.
- (HBLKSIZE): Likewise.
- (OS_TYPE): Likewise.
- (LINUX_STACKBOTTOM): Likewise.
- (USE_GENERIC_PUSH_REGS): Likewise.
- (DYNAMIC_LOADING): Likewise.
- (DATASTART): Likewise.
- (DATAEND): Likewise.
- (STACKBOTTOM): Likewise.
- (NOSYS): Likewise.
- (mach_type_known): Define for AArch64 and comment update.
+ * include/private/gcconfig.h (AARCH64): New macro (defined only if
+ __aarch64__).
+ (CPP_WORDSZ): Define for AArch64.
+ (MACH_TYPE): Likewise.
+ (ALIGNMENT): Likewise.
+ (HBLKSIZE): Likewise.
+ (OS_TYPE): Likewise.
+ (LINUX_STACKBOTTOM): Likewise.
+ (USE_GENERIC_PUSH_REGS): Likewise.
+ (DYNAMIC_LOADING): Likewise.
+ (DATASTART): Likewise.
+ (DATAEND): Likewise.
+ (STACKBOTTOM): Likewise.
+ (NOSYS): Likewise.
+ (mach_type_known): Define for AArch64 and comment update.
2013-03-06 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
@@ -432,7 +437,7 @@
* configure: Regenerate.
2008-09-26 Peter O'Gorman <pogma@thewrittenword.com>
- Steve Ellcey <sje@cup.hp.com>
+ Steve Ellcey <sje@cup.hp.com>
* configure: Regenerate for new libtool.
* Makefile.in: Ditto.
@@ -1073,7 +1078,7 @@
2004-04-25 Andreas Jaeger <aj@suse.de>
- * mark.c (GC_mark_from): Use pointer as prefetch argument.
+ * mark.c (GC_mark_from): Use pointer as prefetch argument.
2004-04-06 H.J. Lu <hongjiu.lu@intel.com>
diff --git a/boehm-gc/Makefile.am b/boehm-gc/Makefile.am
index 2b68938e18d..468e6ffc9b4 100644
--- a/boehm-gc/Makefile.am
+++ b/boehm-gc/Makefile.am
@@ -35,7 +35,7 @@ sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
# Include THREADLIBS here to ensure that the correct versions of
# linuxthread semaphore functions get linked:
-libgcjgc_la_LIBADD = $(addobjs) $(THREADLIBS)
+libgcjgc_la_LIBADD = $(addobjs) $(THREADLIBS) $(EXTRA_TEST_LIBS)
libgcjgc_la_DEPENDENCIES = $(addobjs)
libgcjgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info 1:2:0 -rpath $(toolexeclibdir)
libgcjgc_la_LINK = $(LINK) $(libgcjgc_la_LDFLAGS)
diff --git a/boehm-gc/Makefile.in b/boehm-gc/Makefile.in
index e1a3b70ca34..cd588103659 100644
--- a/boehm-gc/Makefile.in
+++ b/boehm-gc/Makefile.in
@@ -338,7 +338,7 @@ sparc_sunos4_mach_dep.s ia64_save_regs_in_stack.s
# Include THREADLIBS here to ensure that the correct versions of
# linuxthread semaphore functions get linked:
-libgcjgc_la_LIBADD = $(addobjs) $(THREADLIBS)
+libgcjgc_la_LIBADD = $(addobjs) $(THREADLIBS) $(EXTRA_TEST_LIBS)
libgcjgc_la_DEPENDENCIES = $(addobjs)
libgcjgc_la_LDFLAGS = $(extra_ldflags_libgc) -version-info 1:2:0 -rpath $(toolexeclibdir)
libgcjgc_la_LINK = $(LINK) $(libgcjgc_la_LDFLAGS)
diff --git a/config/ChangeLog b/config/ChangeLog
index cdc733c705a..ab34cbcc224 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,7 @@
+2013-08-30 Marek Polacek <polacek@redhat.com>
+
+ * bootstrap-ubsan.mk: New.
+
2013-03-27 Kai Tietz <ktietz@redhat.com>
* dfp.m4: Add support for cygwin x64 target.
diff --git a/config/bootstrap-ubsan.mk b/config/bootstrap-ubsan.mk
new file mode 100644
index 00000000000..2d21e832e21
--- /dev/null
+++ b/config/bootstrap-ubsan.mk
@@ -0,0 +1,7 @@
+# This option enables -fsanitize=undefined for stage2 and stage3.
+
+STAGE2_CFLAGS += -fsanitize=undefined
+STAGE3_CFLAGS += -fsanitize=undefined
+POSTSTAGE1_LDFLAGS += -fsanitize=undefined -static-libubsan -lpthread \
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/ \
+ -B$$r/prev-$(TARGET_SUBDIR)/libsanitizer/ubsan/.libs
diff --git a/configure b/configure
index 551389bc7c9..a91689ff419 100755
--- a/configure
+++ b/configure
@@ -2774,6 +2774,7 @@ target_libraries="target-libgcc \
target-libstdc++-v3 \
target-libmudflap \
target-libsanitizer \
+ target-libvtv \
target-libssp \
target-libquadmath \
target-libgfortran \
@@ -3215,6 +3216,25 @@ $as_echo "yes" >&6; }
fi
fi
+# Disable libvtv on unsupported systems.
+if test -d ${srcdir}/libvtv; then
+ if test x$enable_libvtv = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for libvtv support" >&5
+$as_echo_n "checking for libvtv support... " >&6; }
+ if (srcdir=${srcdir}/libvtv; \
+ . ${srcdir}/configure.tgt; \
+ test "$VTV_SUPPORTED" != "yes")
+ then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ noconfigdirs="$noconfigdirs target-libvtv"
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+ fi
+fi
+
# Disable libquadmath for some systems.
case "${target}" in
avr-*-*)
@@ -5945,6 +5965,55 @@ $as_echo "$gcc_cv_isl" >&6; }
fi
+ if test "${gcc_cv_isl}" = no ; then
+
+ if test "${ENABLE_ISL_CHECK}" = yes ; then
+ _isl_saved_CFLAGS=$CFLAGS
+ _isl_saved_LDFLAGS=$LDFLAGS
+ _isl_saved_LIBS=$LIBS
+
+ CFLAGS="${_isl_saved_CFLAGS} ${islinc} ${gmpinc}"
+ LDFLAGS="${_isl_saved_LDFLAGS} ${isllibs}"
+ LIBS="${_isl_saved_LIBS} -lisl"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for version 0.12 of ISL" >&5
+$as_echo_n "checking for version 0.12 of ISL... " >&6; }
+ if test "$cross_compiling" = yes; then :
+ gcc_cv_isl=yes
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <isl/version.h>
+ #include <string.h>
+int
+main ()
+{
+if (strncmp (isl_version (), "isl-0.12", strlen ("isl-0.12")) != 0)
+ return 1;
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+ gcc_cv_isl=yes
+else
+ gcc_cv_isl=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_isl" >&5
+$as_echo "$gcc_cv_isl" >&6; }
+
+ CFLAGS=$_isl_saved_CFLAGS
+ LDFLAGS=$_isl_saved_LDFLAGS
+ LIBS=$_isl_saved_LIBS
+ fi
+
+
+ fi
fi
@@ -6551,11 +6620,11 @@ case ,${enable_languages},:${enable_objc_gc} in
;;
esac
-# Disable libitm and libsanitizer if we're not building C++
+# Disable libitm, libsanitizer, libvtv if we're not building C++
case ,${enable_languages}, in
*,c++,*) ;;
*)
- noconfigdirs="$noconfigdirs target-libitm target-libsanitizer"
+ noconfigdirs="$noconfigdirs target-libitm target-libsanitizer target-libvtv"
;;
esac
@@ -7032,6 +7101,11 @@ if echo " ${target_configdirs} " | grep " libsanitizer " > /dev/null 2>&1 ; then
bootstrap_target_libs=${bootstrap_target_libs}target-libsanitizer,
fi
+# If we are building libvtv, bootstrap it.
+if echo " ${target_configdirs} " | grep " libvtv " > /dev/null 2>&1 ; then
+ bootstrap_target_libs=${bootstrap_target_libs}target-libvtv,
+fi
+
# Determine whether gdb needs tk/tcl or not.
# Use 'maybe' since enable_gdbtk might be true even if tk isn't available
# and in that case we want gdb to be built without tk. Ugh!
@@ -7420,13 +7494,6 @@ if test x${is_cross_compiler} = xyes ; then
target_configargs="--with-cross-host=${host_noncanonical} ${target_configargs}"
fi
-# Pass --with-sysroot on darwin without SDK in /
-case "${target}" in
- x86_64-*-darwin1[3-9]*)
- host_configargs="--with-sysroot=\"`xcrun --show-sdk-path`\" ${host_configargs}"
- ;;
-esac
-
# Default to --enable-multilib.
if test x${enable_multilib} = x ; then
target_configargs="--enable-multilib ${target_configargs}"
@@ -13754,7 +13821,7 @@ else
esac
if test $ok = yes; then
# An in-tree tool is available and we can use it
- CXX_FOR_TARGET='$$r/$(HOST_SUBDIR)/gcc/xg++ -B$$r/$(HOST_SUBDIR)/gcc/ -nostdinc++ `if test -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags; then $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags --build-includes; else echo -funconfigured-libstdc++-v3 ; fi` -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs'
+ CXX_FOR_TARGET='$$r/$(HOST_SUBDIR)/gcc/xg++ -B$$r/$(HOST_SUBDIR)/gcc/ -nostdinc++ `if test -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags; then $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags --build-includes; else echo -funconfigured-libstdc++-v3 ; fi` -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/libsupc++/.libs'
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: just compiled" >&5
$as_echo "just compiled" >&6; }
elif expr "x$CXX_FOR_TARGET" : "x/" > /dev/null; then
@@ -13799,7 +13866,7 @@ else
esac
if test $ok = yes; then
# An in-tree tool is available and we can use it
- RAW_CXX_FOR_TARGET='$$r/$(HOST_SUBDIR)/gcc/xgcc -shared-libgcc -B$$r/$(HOST_SUBDIR)/gcc -nostdinc++ -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs'
+ RAW_CXX_FOR_TARGET='$$r/$(HOST_SUBDIR)/gcc/xgcc -shared-libgcc -B$$r/$(HOST_SUBDIR)/gcc -nostdinc++ -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/libsupc++/.libs'
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: just compiled" >&5
$as_echo "just compiled" >&6; }
elif expr "x$RAW_CXX_FOR_TARGET" : "x/" > /dev/null; then
diff --git a/configure.ac b/configure.ac
index d4dc10bd725..d72b40a7af9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -161,6 +161,7 @@ target_libraries="target-libgcc \
target-libstdc++-v3 \
target-libmudflap \
target-libsanitizer \
+ target-libvtv \
target-libssp \
target-libquadmath \
target-libgfortran \
@@ -554,6 +555,22 @@ if test -d ${srcdir}/libsanitizer; then
fi
fi
+# Disable libvtv on unsupported systems.
+if test -d ${srcdir}/libvtv; then
+ if test x$enable_libvtv = x; then
+ AC_MSG_CHECKING([for libvtv support])
+ if (srcdir=${srcdir}/libvtv; \
+ . ${srcdir}/configure.tgt; \
+ test "$VTV_SUPPORTED" != "yes")
+ then
+ AC_MSG_RESULT([no])
+ noconfigdirs="$noconfigdirs target-libvtv"
+ else
+ AC_MSG_RESULT([yes])
+ fi
+ fi
+fi
+
# Disable libquadmath for some systems.
case "${target}" in
avr-*-*)
@@ -1636,6 +1653,9 @@ if test "x$with_isl" != "xno" &&
ISL_CHECK_VERSION(0,10)
if test "${gcc_cv_isl}" = no ; then
ISL_CHECK_VERSION(0,11)
+ if test "${gcc_cv_isl}" = no ; then
+ ISL_CHECK_VERSION(0,12)
+ fi
fi
dnl Only execute fail-action, if ISL has been requested.
ISL_IF_FAILED([
@@ -2037,11 +2057,11 @@ case ,${enable_languages},:${enable_objc_gc} in
;;
esac
-# Disable libitm and libsanitizer if we're not building C++
+# Disable libitm, libsanitizer, libvtv if we're not building C++
case ,${enable_languages}, in
*,c++,*) ;;
*)
- noconfigdirs="$noconfigdirs target-libitm target-libsanitizer"
+ noconfigdirs="$noconfigdirs target-libitm target-libsanitizer target-libvtv"
;;
esac
@@ -2467,6 +2487,11 @@ if echo " ${target_configdirs} " | grep " libsanitizer " > /dev/null 2>&1 ; then
bootstrap_target_libs=${bootstrap_target_libs}target-libsanitizer,
fi
+# If we are building libvtv, bootstrap it.
+if echo " ${target_configdirs} " | grep " libvtv " > /dev/null 2>&1 ; then
+ bootstrap_target_libs=${bootstrap_target_libs}target-libvtv,
+fi
+
# Determine whether gdb needs tk/tcl or not.
# Use 'maybe' since enable_gdbtk might be true even if tk isn't available
# and in that case we want gdb to be built without tk. Ugh!
@@ -2854,13 +2879,6 @@ if test x${is_cross_compiler} = xyes ; then
target_configargs="--with-cross-host=${host_noncanonical} ${target_configargs}"
fi
-# Pass --with-sysroot on darwin without SDK in /
-case "${target}" in
- x86_64-*-darwin1[[3-9]]*)
- host_configargs="--with-sysroot=\"`xcrun --show-sdk-path`\" ${host_configargs}"
- ;;
-esac
-
# Default to --enable-multilib.
if test x${enable_multilib} = x ; then
target_configargs="--enable-multilib ${target_configargs}"
@@ -3170,10 +3188,10 @@ GCC_TARGET_TOOL(as, AS_FOR_TARGET, AS, [gas/as-new])
GCC_TARGET_TOOL(cc, CC_FOR_TARGET, CC, [gcc/xgcc -B$$r/$(HOST_SUBDIR)/gcc/])
dnl see comments for CXX_FOR_TARGET_FLAG_TO_PASS
GCC_TARGET_TOOL(c++, CXX_FOR_TARGET, CXX,
- [gcc/xg++ -B$$r/$(HOST_SUBDIR)/gcc/ -nostdinc++ `if test -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags; then $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags --build-includes; else echo -funconfigured-libstdc++-v3 ; fi` -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs],
+ [gcc/xg++ -B$$r/$(HOST_SUBDIR)/gcc/ -nostdinc++ `if test -f $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags; then $(SHELL) $$r/$(TARGET_SUBDIR)/libstdc++-v3/scripts/testsuite_flags --build-includes; else echo -funconfigured-libstdc++-v3 ; fi` -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/libsupc++/.libs],
c++)
GCC_TARGET_TOOL(c++ for libstdc++, RAW_CXX_FOR_TARGET, CXX,
- [gcc/xgcc -shared-libgcc -B$$r/$(HOST_SUBDIR)/gcc -nostdinc++ -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs],
+ [gcc/xgcc -shared-libgcc -B$$r/$(HOST_SUBDIR)/gcc -nostdinc++ -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/src/.libs -L$$r/$(TARGET_SUBDIR)/libstdc++-v3/libsupc++/.libs],
c++)
GCC_TARGET_TOOL(dlltool, DLLTOOL_FOR_TARGET, DLLTOOL, [binutils/dlltool])
GCC_TARGET_TOOL(gcc, GCC_FOR_TARGET, , [gcc/xgcc -B$$r/$(HOST_SUBDIR)/gcc/])
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 1233e6acaea..d99dc3417bb 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,15 @@
+2013-08-31 Diego Novillo <dnovillo@google.com>
+
+ * testsuite-management/x86_64-unknown-linux-gnu.xfail: Update.
+
+2013-08-29 Mike Stump <mikestump@comcast.net>
+
+ * gcc_update (configure): Update to handle svn 1.8.1.
+
+2013-08-03 Caroline Tice4 <cmtice@google.com>
+
+ * gcc_update: Add libvtv files.
+
2013-06-06 Brooks Moses <bmoses@google.com>
* testsuite-management/validate_failures.py: Fix handling of
diff --git a/contrib/gcc_update b/contrib/gcc_update
index 10a5970f621..bdf89c4d128 100755
--- a/contrib/gcc_update
+++ b/contrib/gcc_update
@@ -158,6 +158,9 @@ libsanitizer/configure: libsanitizer/configure.ac libsanitizer/aclocal.m4
libsanitizer/asan/Makefile.in: libsanitizer/asan/Makefile.am libsanitizer/aclocal.m4
libsanitizer/interception/Makefile.in: libsanitizer/interception/Makefile.am libsanitizer/aclocal.m4
libsanitizer/sanitizer_common/Makefile.in: libsanitizer/sanitizer_common/Makefile.am libsanitizer/aclocal.m4
+libvtv/aclocal.m4: libvtv/configure.ac libvtv/acinclude.m4
+libvtv/Makefile.in: libvtv/Makefile.am libvtv/aclocal.m4
+libvtv/configure: libvtv/configure.ac libvtv/aclocal.m4
# Top level
Makefile.in: Makefile.tpl Makefile.def
configure: configure.ac config/acx.m4
@@ -382,7 +385,7 @@ case $vcs_type in
fi
revision=`$GCC_SVN info | awk '/Revision:/ { print $2 }'`
- branch=`$GCC_SVN info | sed -ne "/URL:/ {
+ branch=`$GCC_SVN info | sed -ne "/^URL:/ {
s,.*/trunk,trunk,
s,.*/branches/,,
s,.*/tags/,,
diff --git a/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail b/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
index 44460616914..32f2b0d04ce 100644
--- a/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
+++ b/contrib/testsuite-management/x86_64-unknown-linux-gnu.xfail
@@ -1,135 +1,122 @@
-FAIL: g++.dg/other/anon5.C -std=gnu++98 (test for excess errors)
-FAIL: g++.dg/other/anon5.C -std=gnu++11 (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -Os (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer -funroll-loops (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 -flto -flto-partition=none (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 -flto -flto-partition=none (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 -flto (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -g (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 -flto (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O1 (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -g (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (test for excess errors)
-FAIL: gcc.c-torture/compile/pr44119.c -O2 (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -Os (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O1 (internal compiler error)
-FAIL: gcc.c-torture/compile/pr44119.c -O3 -fomit-frame-pointer -funroll-loops (internal compiler error)
-UNRESOLVED: gcc.dg/attr-weakref-1.c compilation failed to produce executable
-FAIL: gcc.dg/attr-weakref-1.c (test for excess errors)
-FAIL: gcc.dg/autopar/pr49960.c scan-tree-dump-times optimized "loopfn" 0
-FAIL: gcc.dg/autopar/pr49960.c scan-tree-dump-times parloops "SUCCESS: may be parallelized" 0
-FAIL: gcc.dg/builtin-object-size-8.c execution test
-FAIL: gcc.dg/cproj-fails-with-broken-glibc.c execution test
-XPASS: gcc.dg/guality/example.c -O2 execution test
-XPASS: gcc.dg/guality/example.c -O2 -flto execution test
+FAIL: g++.dg/guality/pr55665.C -O2 line 23 p == 40
+FAIL: g++.dg/guality/pr55665.C -O3 -fomit-frame-pointer line 23 p == 40
+FAIL: g++.dg/guality/pr55665.C -O3 -g line 23 p == 40
+FAIL: gcc.dg/attr-ifunc-4.c execution test
XPASS: gcc.dg/guality/example.c -O0 execution test
-XPASS: gcc.dg/guality/example.c -O2 -flto -flto-partition=none execution test
-XPASS: gcc.dg/guality/guality.c -O2 -flto -flto-partition=none execution test
-XPASS: gcc.dg/guality/guality.c -O3 -fomit-frame-pointer execution test
+XPASS: gcc.dg/guality/example.c -O2 execution test
+XPASS: gcc.dg/guality/example.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
XPASS: gcc.dg/guality/guality.c -O0 execution test
+XPASS: gcc.dg/guality/guality.c -O1 execution test
+XPASS: gcc.dg/guality/guality.c -O2 execution test
+XPASS: gcc.dg/guality/guality.c -O3 -fomit-frame-pointer execution test
XPASS: gcc.dg/guality/guality.c -O3 -g execution test
XPASS: gcc.dg/guality/guality.c -Os execution test
-XPASS: gcc.dg/guality/guality.c -O2 -flto execution test
-XPASS: gcc.dg/guality/guality.c -O2 execution test
-XPASS: gcc.dg/guality/guality.c -O1 execution test
+XPASS: gcc.dg/guality/guality.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+XPASS: gcc.dg/guality/guality.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
XPASS: gcc.dg/guality/inline-params.c -O2 execution test
XPASS: gcc.dg/guality/inline-params.c -O3 -fomit-frame-pointer execution test
-XPASS: gcc.dg/guality/inline-params.c -O2 -flto execution test
-XPASS: gcc.dg/guality/inline-params.c -Os execution test
XPASS: gcc.dg/guality/inline-params.c -O3 -g execution test
-XPASS: gcc.dg/guality/inline-params.c -O2 -flto -flto-partition=none execution test
-XPASS: gcc.dg/guality/pr41353-1.c -O3 -g line 28 j == 28 + 37
+XPASS: gcc.dg/guality/inline-params.c -Os execution test
+XPASS: gcc.dg/guality/inline-params.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+XPASS: gcc.dg/guality/pr41353-1.c -O0 line 28 j == 28 + 37
XPASS: gcc.dg/guality/pr41353-1.c -O1 line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -O2 -flto -flto-partition=none line 28 j == 28 + 37
XPASS: gcc.dg/guality/pr41353-1.c -O2 line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -O2 -flto line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -Os line 28 j == 28 + 37
XPASS: gcc.dg/guality/pr41353-1.c -O3 -fomit-frame-pointer line 28 j == 28 + 37
-XPASS: gcc.dg/guality/pr41353-1.c -O0 line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41353-1.c -O3 -g line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41353-1.c -Os line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41353-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41353-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 28 j == 28 + 37
+XPASS: gcc.dg/guality/pr41447-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O1 execution test
-XPASS: gcc.dg/guality/pr41447-1.c -Os execution test
XPASS: gcc.dg/guality/pr41447-1.c -O2 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O3 -fomit-frame-pointer execution test
-XPASS: gcc.dg/guality/pr41447-1.c -O0 execution test
XPASS: gcc.dg/guality/pr41447-1.c -O3 -g execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto -flto-partition=none execution test
+XPASS: gcc.dg/guality/pr41447-1.c -Os execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+XPASS: gcc.dg/guality/pr41447-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects execution test
XPASS: gcc.dg/guality/pr41616-1.c -O0 execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O1 execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O2 execution test
XPASS: gcc.dg/guality/pr41616-1.c -O3 -fomit-frame-pointer execution test
XPASS: gcc.dg/guality/pr41616-1.c -O3 -g execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O1 execution test
XPASS: gcc.dg/guality/pr41616-1.c -Os execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O2 execution test
-XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto execution test
+XPASS: gcc.dg/guality/pr41616-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none execution test
+FAIL: gcc.dg/guality/pr43051-1.c -O3 -fomit-frame-pointer -funroll-loops line 39 c == &a[0]
+FAIL: gcc.dg/guality/pr43051-1.c -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions line 39 c == &a[0]
+FAIL: gcc.dg/guality/pr48437.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 14 i == 0
+FAIL: gcc.dg/guality/pr48437.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 14 i == 0
FAIL: gcc.dg/guality/pr54200.c -Os line 20 z == 3
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -flto-partition=none line 23 y == 117
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto line 20 y == 25
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto line 23 z == 8
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto line 20 z == 6
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -flto-partition=none line 23 z == 8
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto line 23 y == 117
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -flto-partition=none line 20 z == 6
-FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -flto-partition=none line 20 y == 25
-FAIL: gcc.dg/guality/pr54519-2.c -O2 -flto -flto-partition=none line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-2.c -O2 -flto line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-5.c -O2 -flto line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-5.c -O2 -flto -flto-partition=none line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-5.c -Os line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-5.c -O3 -fomit-frame-pointer line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-5.c -O2 line 17 y == 25
-FAIL: gcc.dg/guality/pr54519-5.c -O3 -g line 17 y == 25
-FAIL: gcc.dg/guality/vla-1.c -O2 -flto line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -O2 -flto line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O3 -g line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -O3 -fomit-frame-pointer line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 20 y == 25
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 20 z == 6
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 23 y == 117
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 23 z == 8
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 20 y == 25
+FAIL: gcc.dg/guality/pr54519-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 20 z == 6
+FAIL: gcc.dg/guality/pr54519-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-2.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 20 y == 25
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 20 z == 6
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 23 y == 117
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 23 z == 8
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 20 y == 25
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 20 z == 6
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 23 y == 117
+FAIL: gcc.dg/guality/pr54519-3.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 23 z == 8
+FAIL: gcc.dg/guality/pr54519-4.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-4.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-5.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 17 y == 25
+FAIL: gcc.dg/guality/pr54519-5.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 17 y == 25
+FAIL: gcc.dg/guality/pr54693-2.c -Os line 21 x == 10 - i
+FAIL: gcc.dg/guality/pr54693-2.c -Os line 21 y == 20 - 2 * i
+FAIL: gcc.dg/guality/vla-1.c -O0 line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O0 line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/vla-1.c -O1 line 17 sizeof (a) == 6
FAIL: gcc.dg/guality/vla-1.c -O1 line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -Os line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O2 -flto -flto-partition=none line 17 sizeof (a) == 6
FAIL: gcc.dg/guality/vla-1.c -O2 line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O3 -fomit-frame-pointer line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O0 line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -O2 -flto -flto-partition=none line 24 sizeof (a) == 17 * sizeof (short)
FAIL: gcc.dg/guality/vla-1.c -O2 line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-1.c -O1 line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O3 -fomit-frame-pointer line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O3 -fomit-frame-pointer line 24 sizeof (a) == 17 * sizeof (short)
FAIL: gcc.dg/guality/vla-1.c -O3 -g line 17 sizeof (a) == 6
-FAIL: gcc.dg/guality/vla-1.c -O0 line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O3 -g line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/vla-1.c -Os line 17 sizeof (a) == 6
FAIL: gcc.dg/guality/vla-1.c -Os line 24 sizeof (a) == 17 * sizeof (short)
-FAIL: gcc.dg/guality/vla-2.c -O3 -g line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O0 line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 24 sizeof (a) == 17 * sizeof (short)
+FAIL: gcc.dg/guality/vla-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 17 sizeof (a) == 6
+FAIL: gcc.dg/guality/vla-1.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 24 sizeof (a) == 17 * sizeof (short)
FAIL: gcc.dg/guality/vla-2.c -O0 line 16 sizeof (a) == 5 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O3 -fomit-frame-pointer line 16 sizeof (a) == 5 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 -flto line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -Os line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 line 16 sizeof (a) == 5 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O1 line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 -flto line 16 sizeof (a) == 5 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O3 -g line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O0 line 25 sizeof (a) == 6 * sizeof (int)
FAIL: gcc.dg/guality/vla-2.c -O1 line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O1 line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 line 16 sizeof (a) == 5 * sizeof (int)
FAIL: gcc.dg/guality/vla-2.c -O2 line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 -flto -flto-partition=none line 25 sizeof (a) == 6 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -O2 -flto -flto-partition=none line 16 sizeof (a) == 5 * sizeof (int)
-FAIL: gcc.dg/guality/vla-2.c -Os line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O3 -fomit-frame-pointer line 16 sizeof (a) == 5 * sizeof (int)
FAIL: gcc.dg/guality/vla-2.c -O3 -fomit-frame-pointer line 25 sizeof (a) == 6 * sizeof (int)
-XPASS: gcc.dg/inline_3.c (test for excess errors)
-XPASS: gcc.dg/inline_4.c (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 -flto (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O1 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -g (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -Os (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O0 (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O3 -fomit-frame-pointer (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 -flto -flto-partition=none (test for excess errors)
-FAIL: gcc.dg/torture/pr51106-2.c -O2 (test for excess errors)
-XPASS: gcc.dg/unroll_2.c (test for excess errors)
-XPASS: gcc.dg/unroll_3.c (test for excess errors)
-XPASS: gcc.dg/unroll_4.c (test for excess errors)
-FAIL: libmudflap.c++/pass55-frag.cxx (-O2) execution test
-FAIL: libmudflap.c++/pass55-frag.cxx ( -O) execution test
-FAIL: libmudflap.c++/pass55-frag.cxx (-O3) execution test
-FAIL: libmudflap.c/fail37-frag.c (-O3) output pattern test
-FAIL: libmudflap.c/fail37-frag.c (-O2) output pattern test
-FAIL: libmudflap.c/fail37-frag.c (-O3) crash test
-FAIL: libmudflap.c/fail37-frag.c (-O2) crash test
+FAIL: gcc.dg/guality/vla-2.c -O3 -g line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O3 -g line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -Os line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -Os line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 -flto -fno-use-linker-plugin -flto-partition=none line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 16 sizeof (a) == 5 * sizeof (int)
+FAIL: gcc.dg/guality/vla-2.c -O2 -flto -fuse-linker-plugin -fno-fat-lto-objects line 25 sizeof (a) == 6 * sizeof (int)
+FAIL: gcc.dg/lto/20090218-1 c_lto_20090218-1_0.o-c_lto_20090218-1_1.o link, -O0 -flto -flto-partition=none -fuse-linker-plugin
+UNRESOLVED: gcc.dg/lto/20090218-1 c_lto_20090218-1_0.o-c_lto_20090218-1_1.o execute -O0 -flto -flto-partition=none -fuse-linker-plugin
+FAIL: gcc.dg/lto/20090218-1 c_lto_20090218-1_0.o-c_lto_20090218-1_1.o link, -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
+UNRESOLVED: gcc.dg/lto/20090218-1 c_lto_20090218-1_0.o-c_lto_20090218-1_1.o execute -O0 -flto -flto-partition=1to1 -fno-use-linker-plugin
+FAIL: gcc.dg/lto/20090218-1 c_lto_20090218-1_0.o-c_lto_20090218-1_1.o link, -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects
+UNRESOLVED: gcc.dg/lto/20090218-1 c_lto_20090218-1_0.o-c_lto_20090218-1_1.o execute -O0 -flto -fuse-linker-plugin -fno-fat-lto-objects
+FAIL: gfortran.dg/round_4.f90 -O0 execution test
+FAIL: gfortran.dg/round_4.f90 -O1 execution test
+FAIL: gfortran.dg/round_4.f90 -O2 execution test
+FAIL: gfortran.dg/round_4.f90 -O3 -fomit-frame-pointer execution test
+FAIL: gfortran.dg/round_4.f90 -O3 -fomit-frame-pointer -funroll-loops execution test
+FAIL: gfortran.dg/round_4.f90 -O3 -fomit-frame-pointer -funroll-all-loops -finline-functions execution test
+FAIL: gfortran.dg/round_4.f90 -O3 -g execution test
+FAIL: gfortran.dg/round_4.f90 -Os execution test
+FAIL: libmudflap.c++/pass41-frag.cxx ( -O) execution test
+FAIL: libmudflap.c++/pass41-frag.cxx (-O2) execution test
+FAIL: libmudflap.c++/pass41-frag.cxx (-O3) execution test
+FAIL: sourcelocation output - source compiled test
+FAIL: sourcelocation -findirect-dispatch output - source compiled test
+FAIL: sourcelocation -O3 output - source compiled test
diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index 8471e027f89..4a9d22997ff 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,9 @@
+2013-09-02 David Edelsohn <dje.gcc@gmail.com>
+
+ * inclhack.def (aix_assert): New fix.
+ * fixincl.x: Regenerate.
+ * tests/base/assert.h [AIX_ASSERT_CHECK]: New check.
+
2013-07-06 Bruce Korb <bkorb@gnu.org>
* inclhack.def (cdef_cplusplus): removed, per Bug 51776
diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x
index 52cbc11bf98..cf35c5a25a0 100644
--- a/fixincludes/fixincl.x
+++ b/fixincludes/fixincl.x
@@ -2,11 +2,11 @@
*
* DO NOT EDIT THIS FILE (fixincl.x)
*
- * It has been AutoGen-ed July 12, 2013 at 10:18:23 AM by AutoGen 5.17.3
+ * It has been AutoGen-ed September 9, 2013 at 03:29:05 PM by AutoGen 5.18
* From the definitions inclhack.def
* and the template file fixincl
*/
-/* DO NOT SVN-MERGE THIS FILE, EITHER Fri Jul 12 10:18:23 CEST 2013
+/* DO NOT SVN-MERGE THIS FILE, EITHER Mon Sep 9 15:29:05 MEST 2013
*
* You must regenerate it. Use the ./genfixes script.
*
@@ -15,7 +15,7 @@
* certain ANSI-incompatible system header files which are fixed to work
* correctly with ANSI C and placed in a directory that GNU C will search.
*
- * This file contains 227 fixup descriptions.
+ * This file contains 228 fixup descriptions.
*
* See README for more information.
*
@@ -736,6 +736,45 @@ static const char* apzAab_Vxworks_UnistdPatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
+ * Description of Aix_Assert fix
+ */
+tSCC zAix_AssertName[] =
+ "aix_assert";
+
+/*
+ * File name selection pattern
+ */
+tSCC zAix_AssertList[] =
+ "assert.h\0";
+/*
+ * Machine/OS name selection pattern
+ */
+tSCC* apzAix_AssertMachs[] = {
+ "*-*-aix*",
+ (const char*)NULL };
+
+/*
+ * content selection pattern - do fix if pattern found
+ */
+tSCC zAix_AssertSelect0[] =
+ "#define[ \t]static_assert[ \t]_Static_assert";
+
+#define AIX_ASSERT_TEST_CT 1
+static tTestDesc aAix_AssertTests[] = {
+ { TT_EGREP, zAix_AssertSelect0, (regex_t*)NULL }, };
+
+/*
+ * Fix Command Arguments for Aix_Assert
+ */
+static const char* apzAix_AssertPatch[] = {
+ "format",
+ "#ifndef __cplusplus\n\
+%0\n\
+#endif",
+ (char*)NULL };
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * *
+ *
* Description of Aix_Complex fix
*/
tSCC zAix_ComplexName[] =
@@ -9329,9 +9368,9 @@ static const char* apzComplier_H_TradcppPatch[] = {
*
* List of all fixes
*/
-#define REGEX_COUNT 266
+#define REGEX_COUNT 267
#define MACH_LIST_SIZE_LIMIT 187
-#define FIX_COUNT 227
+#define FIX_COUNT 228
/*
* Enumerate the fixes
@@ -9349,6 +9388,7 @@ typedef enum {
AAB_VXWORKS_REGS_VXTYPES_FIXIDX,
AAB_VXWORKS_STDINT_FIXIDX,
AAB_VXWORKS_UNISTD_FIXIDX,
+ AIX_ASSERT_FIXIDX,
AIX_COMPLEX_FIXIDX,
AIX_MALLOC_FIXIDX,
AIX_NET_IF_ARP_FIXIDX,
@@ -9627,6 +9667,11 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
AAB_VXWORKS_UNISTD_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
aAab_Vxworks_UnistdTests, apzAab_Vxworks_UnistdPatch, 0 },
+ { zAix_AssertName, zAix_AssertList,
+ apzAix_AssertMachs,
+ AIX_ASSERT_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
+ aAix_AssertTests, apzAix_AssertPatch, 0 },
+
{ zAix_ComplexName, zAix_ComplexList,
apzAix_ComplexMachs,
AIX_COMPLEX_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
index c92170f4cd9..996356a3930 100644
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -569,6 +569,20 @@ fix = {
};
/*
+ * assert.h on AIX 7 redefines static_assert as _Static_assert without
+ * protecting C++.
+ */
+fix = {
+ hackname = aix_assert;
+ mach = "*-*-aix*";
+ files = assert.h;
+ select = "#define[ \t]static_assert[ \t]_Static_assert";
+ c_fix = format;
+ c_fix_arg = "#ifndef __cplusplus\n%0\n#endif";
+ test_text = "#define static_assert _Static_assert";
+};
+
+/*
* complex.h on AIX 5 and AIX 6 define _Complex_I and I in terms of __I,
* which only is provided by AIX xlc C99.
*/
diff --git a/fixincludes/tests/base/assert.h b/fixincludes/tests/base/assert.h
index 2642cbe49c4..19dc52575ee 100644
--- a/fixincludes/tests/base/assert.h
+++ b/fixincludes/tests/base/assert.h
@@ -19,6 +19,13 @@
#include <stdio.h>
+#if defined( AIX_ASSERT_CHECK )
+#ifndef __cplusplus
+#define static_assert _Static_assert
+#endif
+#endif /* AIX_ASSERT_CHECK */
+
+
#if defined( ALPHA___ASSERT_CHECK )
extern void __assert(const char *, const char *, int);
#endif /* ALPHA___ASSERT_CHECK */
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index db8db6f894a..ceaf0e50e55 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,5683 @@
+2013-09-09 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/58294
+ * value-prof.c (gimple_ic): Copy also abnormal edges.
+
+2013-09-09 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * asan.c (asan_shadow_cst): Use gen_int_mode.
+
+2013-09-08 Jan Hubicka <jh@suse.cz>
+
+ * ipa-profile.c: Add toplevel comment.
+ (ipa_propagate_frequency_1): Be more conservative when profile is read.
+ (contains_hot_call_p): New function.
+ (ipa_propagate_frequency): Set frequencies based on counts when
+ profile is read.
+ * predict.c (compute_function_frequency): Use PROFILE_READ gueard for
+ profile; do not tamper with profile after inlining if it is read.
+
+2013-09-08 Jan Hubicka <jh@suse.cz>
+
+ * ipa-prop.c (try_make_edge_direct_simple_call): Do not special case
+ speculative edges.
+
+2013-09-08 Jan Hubicka <jh@suse.cz>
+
+ * ipa.c (walk_polymorphic_call_targets): Fix redirection before IPA
+ summary generation.
+
+2013-09-08 Jeff Law <law@redhat.com>
+
+ PR bootstrap/58340
+ * tree-ssa-threadedge.c (thread_across_edge): Fix initialization
+ of 'found'.
+
+2013-09-08 Andi Kleen <ak@linux.intel.com>
+
+ * tree-inline.c (estimate_num_insns): Limit asm cost to 1000.
+
+2013-09-08 Jan Hubicka <jh@suse.cz>
+
+ * ipa.c (walk_polymorphic_call_targets): Fix inliner summary update.
+
+2013-09-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * ira.c (update_equiv_regs): Only call set_paradoxical_subreg
+ for non-debug insns.
+ * lra.c (new_insn_reg): Take the containing insn as a parameter.
+ Only modify lra_reg_info[].biggest_mode if it's non-debug insn.
+ (collect_non_operand_hard_regs, add_regs_to_insn_regno_info): Update
+ accordingly.
+
+2013-09-08 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (walk_polymorphic_call_targets): Permit 0 possible
+ targets and devirtualize to BUILT_IN_UNREACHABLE.
+ * timevar.def (TV_IPA_UNREACHABLE): New timevar.
+ * ipa.c (walk_polymorphic_call_targets): New function.
+ (symtab_remove_unreachable_nodes): Use it; do not keep all virtual
+ functions; use the new timevar.
+ * ipa-devirt.c (maybe_record_node): Do not insert static nodes that
+ was removed from the program.
+ (record_binfo): If BINFO corresponds to an anonymous namespace, we may
+ not consider it in the walk when its vtable is dead.
+ (possible_polymorphic_call_targets_1): Pass anonymous flag to
+ record_binfo.
+ (devirt_variable_node_removal_hook): New function.
+ (possible_polymorphic_call_targets): Also register
+ devirt_variable_node_removal_hook.
+ (ipa_devirt): Do not do non-speculative devirtualization.
+ (gate_ipa_devirt): One execute if devirtualizing speculatively.
+
+2013-09-08 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (varpool_node_hook, varpool_node_hook_list,
+ varpool_add_node_removal_hook, varpool_add_variable_insertion_hook,
+ varpool_remove_variable_insertion_hook): Declare.
+ * varpool.c (varpool_node_hook_list): New structure.
+ (first_varpool_node_removal_hook,
+ first_varpool_variable_insertion_hook): New variables.
+ (varpool_add_node_removal_hook, varpool_remove_node_removal_hook,
+ varpool_call_node_removal_hooks, varpool_add_variable_insertion_hook,
+ varpool_remove_variable_insertion_hook,
+ varpool_call_variable_insertion_hooks): New functions.
+ (varpool_remove_node): Use it.
+
+2013-09-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54941
+ * diagnostic.c (diagnostic_build_prefix): When s.file is
+ "<built-in>" don't output line and column numbers.
+
+2013-09-06 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (expand_thunk): Get body before touching arguments.
+ * lto-streamer-out.c: Stream thunks, too.
+ * lto-streamer-in.c (input_function): Pop cfun here
+ (lto_read_body): Instead of here.
+
+2013-09-06 Caroline Tice <cmtice@google.com>
+
+ * doc/install.texi: Add documentation for the --enable-vtable-verify
+ and the --disable-libvtv configure options.
+
+2013-09-06 Jeff Law <law@redhat.com>
+
+ * tree-ssa-dom.c (cprop_into_successor_phis): Also propagate
+ edge implied equivalences into successor phis.
+
+2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * resource.c (mark_referenced_resources): Handle COND_EXEC.
+
+2013-09-06 Claudiu Zissulescu <claziss@synopsys.com>
+
+ * resource.c (mark_target_live_regs): Compute resources taking
+ into account if a call is predicated or not.
+
+2013-09-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * toplev.c (output_stack_usage): Be prepared for suffixes created by
+ the compiler in the function names.
+
+2013-09-06 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/58094
+ * ipa-inline.c (has_caller_p): New function.
+ (want_inline_function_to_all_callers_p): Use it.
+ (sum_callers, inline_to_all_callers): Break out from ...
+ (ipa_inline): ... here.
+
+2013-09-06 Jan Hubicka <jh@suse.cz>
+
+ * config/i386/i386.c (ix86_hard_regno_mode_ok): AVX modes are valid
+ only when AVX is enabled.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64.md
+ (*movtf_aarch64): Use neon_<ls>dm_2 as type where v8type
+ is fpsimd_<load/store>2.
+ (load_pair<mode>): Likewise.
+ (store_pair<mode>): Likewise.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/arm/types.md (type): Add "mrs" type.
+ * config/aarch64/aarch64.md
+ (aarch64_load_tp_hard): Make type "mrs".
+ * config/arm/arm.md
+ (load_tp_hard): Make type "mrs".
+ * config/arm/cortex-a15.md: Update with new attributes.
+ * config/arm/cortex-a5.md: Update with new attributes.
+ * config/arm/cortex-a53.md: Update with new attributes.
+ * config/arm/cortex-a7.md: Update with new attributes.
+ * config/arm/cortex-a8.md: Update with new attributes.
+ * config/arm/cortex-a9.md: Update with new attributes.
+ * config/arm/cortex-m4.md: Update with new attributes.
+ * config/arm/cortex-r4.md: Update with new attributes.
+ * config/arm/fa526.md: Update with new attributes.
+ * config/arm/fa606te.md: Update with new attributes.
+ * config/arm/fa626te.md: Update with new attributes.
+ * config/arm/fa726te.md: Update with new attributes.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64.md
+ (*movti_aarch64): Use "multiple" for type where v8type is "move2".
+ (*movtf_aarch64): Likewise.
+ * config/arm/arm.md
+ (thumb1_movdi_insn): Use "multiple" for type where more than one
+ instruction is used for a move.
+ (*arm32_movhf): Likewise.
+ (*thumb_movdf_insn): Likewise.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/arm/types.md (type): Rename fcpys to fmov.
+ * config/arm/vfp.md
+ (*arm_movsi_vfp): Rename type fcpys as fmov.
+ (*thumb2_movsi_vfp): Likewise
+ (*movhf_vfp_neon): Likewise
+ (*movhf_vfp): Likewise
+ (*movsf_vfp): Likewise
+ (*thumb2_movsf_vfp): Likewise
+ (*movsfcc_vfp): Likewise
+ (*thumb2_movsfcc_vfp): Likewise
+ * config/aarch64/aarch64-simd.md
+ (move_lo_quad_<mode>): Replace type mov_reg with fmovs.
+ * config/aarch64/aarch64.md
+ (*movsi_aarch64): Replace type mov_reg with fmovs.
+ (*movdi_aarch64): Likewise
+ (*movsf_aarch64): Likewise
+ (*movdf_aarch64): Likewise
+ * config/arm/arm.c
+ (cortexa7_older_only): Rename TYPE_FCPYS to TYPE_FMOV.
+ * config/arm/iwmmxt.md
+ (*iwmmxt_movsi_insn): Rename type fcpys as fmov.
+ * config/arm/arm1020e.md: Update with new attributes.
+ * config/arm/cortex-a15-neon.md: Update with new attributes.
+ * config/arm/cortex-a5.md: Update with new attributes.
+ * config/arm/cortex-a53.md: Update with new attributes.
+ * config/arm/cortex-a7.md: Update with new attributes.
+ * config/arm/cortex-a8-neon.md: Update with new attributes.
+ * config/arm/cortex-a9.md: Update with new attributes.
+ * config/arm/cortex-m4-fpu.md: Update with new attributes.
+ * config/arm/cortex-r4f.md: Update with new attributes.
+ * config/arm/marvell-pj4.md: Update with new attributes.
+ * config/arm/vfp11.md: Update with new attributes.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64.md
+ (*madd<mode>): Fix type attribute.
+ (*maddsi_uxtw): Likewise.
+ (*msub<mode>): Likewise.
+ (*msubsi_uxtw): Likewise.
+ (<su_optab>maddsidi4): Likewise.
+ (<su_optab>msubsidi4): Likewise.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/arm/types.md: Split fdiv<sd> as fsqrt<sd>, fdiv<sd>.
+ * config/arm/arm.md (core_cycles): Remove fdiv.
+ * config/arm/vfp.md:
+ (*sqrtsf2_vfp): Update for attribute changes.
+ (*sqrtdf2_vfp): Likewise.
+ * config/aarch64/aarch64.md:
+ (sqrt<mode>2): Update for attribute changes.
+ * config/arm/arm1020e.md: Update with new attributes.
+ * config/arm/cortex-a15-neon.md: Update with new attributes.
+ * config/arm/cortex-a5.md: Update with new attributes.
+ * config/arm/cortex-a53.md: Update with new attributes.
+ * config/arm/cortex-a7.md: Update with new attributes.
+ * config/arm/cortex-a8-neon.md: Update with new attributes.
+ * config/arm/cortex-a9.md: Update with new attributes.
+ * config/arm/cortex-m4-fpu.md: Update with new attributes.
+ * config/arm/cortex-r4f.md: Update with new attributes.
+ * config/arm/marvell-pj4.md: Update with new attributes.
+ * config/arm/vfp11.md: Update with new attributes.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/arm/types.md
+ (type): Split f_cvt as f_cvt, f_cvtf2i, f_cvti2f.
+ * config/aarch64/aarch64.md
+ (l<fcvt_pattern><su_optab><GPF:mode><GPI:mode>2): Update with
+ new attributes.
+ (fix_trunc<GPF:mode><GPI:mode>2): Likewise.
+ (fixuns_trunc<GPF:mode><GPI:mode>2): Likewise.
+ (float<GPI:mode><GPF:mode>2): Likewise.
+ * config/arm/vfp.md
+ (*truncsisf2_vfp): Update with new attributes.
+ (*truncsidf2_vfp): Likewise.
+ (fixuns_truncsfsi2): Likewise.
+ (fixuns_truncdfsi2): Likewise.
+ (*floatsisf2_vfp): Likewise.
+ (*floatsidf2_vfp): Likewise.
+ (floatunssisf2): Likewise.
+ (floatunssidf2): Likewise.
+ (*combine_vcvt_f32_<FCVTI32typename>): Likewise.
+ (*combine_vcvt_f64_<FCVTI32typename>): Likewise.
+ * config/arm/arm1020e.md: Update with new attributes.
+ * config/arm/cortex-a15-neon.md: Update with new attributes.
+ * config/arm/cortex-a5.md: Update with new attributes.
+ * config/arm/cortex-a53.md: Update with new attributes.
+ * config/arm/cortex-a7.md: Update with new attributes.
+ * config/arm/cortex-a8-neon.md: Update with new attributes.
+ * config/arm/cortex-a9.md: Update with new attributes.
+ * config/arm/cortex-m4-fpu.md: Update with new attributes.
+ * config/arm/cortex-r4f.md: Update with new attributes.
+ * config/arm/marvell-pj4.md: Update with new attributes.
+ * config/arm/vfp11.md: Update with new attributes.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/arm_neon.h
+ (vqtbl<1,2,3,4><q>_s8): Fix control vector parameter type.
+ (vqtbx<1,2,3,4><q>_s8): Likewise.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/arm/types.md: Add "no_insn", "multiple" and "untyped"
+ types.
+ * config/arm/arm-fixed.md: Add type attribute to all insn
+ patterns.
+ (add<mode>3): Add type attribute.
+ (add<mode>3): Likewise.
+ (usadd<mode>3): Likewise.
+ (ssadd<mode>3): Likewise.
+ (sub<mode>3): Likewise.
+ (sub<mode>3): Likewise.
+ (ussub<mode>3): Likewise.
+ (sssub<mode>3): Likewise.
+ (ssmulsa3): Likewise.
+ (usmulusa3): Likewise.
+ (arm_usatsihi): Likewise.
+ * config/arm/vfp.md
+ (*movdi_vfp): Add types for all instructions.
+ (*movdi_vfp_cortexa8): Likewise.
+ (*movhf_vfp_neon): Likewise.
+ (*movhf_vfp): Likewise.
+ (*movdf_vfp): Likewise.
+ (*thumb2_movdf_vfp): Likewise.
+ (*thumb2_movdfcc_vfp): Likewise.
+ * config/arm/arm.md: Add type attribute to all insn patterns.
+ (*thumb1_adddi3): Add type attribute.
+ (*arm_adddi3): Likewise.
+ (*adddi_sesidi_di): Likewise.
+ (*adddi_zesidi_di): Likewise.
+ (*thumb1_addsi3): Likewise.
+ (addsi3_compare0): Likewise.
+ (*addsi3_compare0_scratch): Likewise.
+ (*compare_negsi_si): Likewise.
+ (cmpsi2_addneg): Likewise.
+ (*addsi3_carryin_<optab>): Likewise.
+ (*addsi3_carryin_alt2_<optab>): Likewise.
+ (*addsi3_carryin_clobercc_<optab>): Likewise.
+ (*subsi3_carryin): Likewise.
+ (*subsi3_carryin_const): Likewise.
+ (*subsi3_carryin_compare): Likewise.
+ (*subsi3_carryin_compare_const): Likewise.
+ (*arm_subdi3): Likewise.
+ (*thumb_subdi3): Likewise.
+ (*subdi_di_zesidi): Likewise.
+ (*subdi_di_sesidi): Likewise.
+ (*subdi_zesidi_di): Likewise.
+ (*subdi_sesidi_di): Likewise.
+ (*subdi_zesidi_ze): Likewise.
+ (thumb1_subsi3_insn): Likewise.
+ (*arm_subsi3_insn): Likewise.
+ (*anddi3_insn): Likewise.
+ (*anddi_zesidi_di): Likewise.
+ (*anddi_sesdi_di): Likewise.
+ (*ne_zeroextracts): Likewise.
+ (*ne_zeroextracts): Likewise.
+ (*ite_ne_zeroextr): Likewise.
+ (*ite_ne_zeroextr): Likewise.
+ (*anddi_notdi_di): Likewise.
+ (*anddi_notzesidi): Likewise.
+ (*anddi_notsesidi): Likewise.
+ (andsi_notsi_si): Likewise.
+ (thumb1_bicsi3): Likewise.
+ (*iordi3_insn): Likewise.
+ (*iordi_zesidi_di): Likewise.
+ (*iordi_sesidi_di): Likewise.
+ (*thumb1_iorsi3_insn): Likewise.
+ (*xordi3_insn): Likewise.
+ (*xordi_zesidi_di): Likewise.
+ (*xordi_sesidi_di): Likewise.
+ (*arm_xorsi3): Likewise.
+ (*andsi_iorsi3_no): Likewise.
+ (*smax_0): Likewise.
+ (*smax_m1): Likewise.
+ (*arm_smax_insn): Likewise.
+ (*smin_0): Likewise.
+ (*arm_smin_insn): Likewise.
+ (*arm_umaxsi3): Likewise.
+ (*arm_uminsi3): Likewise.
+ (*minmax_arithsi): Likewise.
+ (*minmax_arithsi_): Likewise.
+ (*satsi_<SAT:code>): Likewise.
+ (arm_ashldi3_1bit): Likewise.
+ (arm_ashrdi3_1bit): Likewise.
+ (arm_lshrdi3_1bit): Likewise.
+ (*arm_negdi2): Likewise.
+ (*thumb1_negdi2): Likewise.
+ (*arm_negsi2): Likewise.
+ (*thumb1_negsi2): Likewise.
+ (*negdi_extendsid): Likewise.
+ (*negdi_zero_extend): Likewise.
+ (*arm_abssi2): Likewise.
+ (*thumb1_abssi2): Likewise.
+ (*arm_neg_abssi2): Likewise.
+ (*thumb1_neg_abss): Likewise.
+ (one_cmpldi2): Likewise.
+ (extend<mode>di2): Likewise.
+ (*compareqi_eq0): Likewise.
+ (*arm_extendhisi2addsi): Likewise.
+ (*arm_movdi): Likewise.
+ (*thumb1_movdi_insn): Likewise.
+ (*arm_movt): Likewise.
+ (*thumb1_movsi_insn): Likewise.
+ (pic_add_dot_plus_four): Likewise.
+ (pic_add_dot_plus_eight): Likewise.
+ (tls_load_dot_plus_eight): Likewise.
+ (*thumb1_movhi_insn): Likewise.
+ (*thumb1_movsf_insn): Likewise.
+ (*movdf_soft_insn): Likewise.
+ (*thumb_movdf_insn): Likewise.
+ (cbranchsi4_insn): Likewise.
+ (cbranchsi4_scratch): Likewise.
+ (*negated_cbranchsi4): Likewise.
+ (*tbit_cbranch): Likewise.
+ (*tlobits_cbranch): Likewise.
+ (*tstsi3_cbranch): Likewise.
+ (*cbranchne_decr1): Likewise.
+ (*addsi3_cbranch): Likewise.
+ (*addsi3_cbranch_scratch): Likewise.
+ (*arm_cmpdi_insn): Likewise.
+ (*arm_cmpdi_unsig): Likewise.
+ (*arm_cmpdi_zero): Likewise.
+ (*thumb_cmpdi_zero): Likewise.
+ (*deleted_compare): Likewise.
+ (*mov_scc): Likewise.
+ (*mov_negscc): Likewise.
+ (*mov_notscc): Likewise.
+ (*cstoresi_eq0_thumb1_insn): Likewise.
+ (cstoresi_nltu_thumb1): Likewise.
+ (cstoresi_ltu_thu): Likewise.
+ (thumb1_addsi3_addgeu): Likewise.
+ (*arm_jump): Likewise.
+ (*thumb_jump): Likewise.
+ (*check_arch2): Likewise.
+ (arm_casesi_internal): Likewise.
+ (thumb1_casesi_dispatch): Likewise.
+ (*arm_indirect_jump): Likewise.
+ (*thumb1_indirect_jump): Likewise.
+ (nop): Likewise.
+ (*and_scc): Likewise.
+ (*ior_scc): Likewise.
+ (*compare_scc): Likewise.
+ (*cond_move): Likewise.
+ (*cond_arith): Likewise.
+ (*cond_sub): Likewise.
+ (*cmp_ite0): Likewise.
+ (*cmp_ite1): Likewise.
+ (*cmp_and): Likewise.
+ (*cmp_ior): Likewise.
+ (*ior_scc_scc): Likewise.
+ (*ior_scc_scc_cmp): Likewise.
+ (*and_scc_scc): Likewise.
+ (*and_scc_scc_cmp): Likewise.
+ (*and_scc_scc_nod): Likewise.
+ (*negscc): Likewise.
+ (movcond_addsi): Likewise.
+ (movcond): Likewise.
+ (*ifcompare_plus_move): Likewise.
+ (*if_plus_move): Likewise.
+ (*ifcompare_move_plus): Likewise.
+ (*if_move_plus): Likewise.
+ (*ifcompare_arith_arith): Likewise.
+ (*if_arith_arith): Likewise.
+ (*ifcompare_arith_move): Likewise.
+ (*if_arith_move): Likewise.
+ (*ifcompare_move_arith): Likewise.
+ (*if_move_arith): Likewise.
+ (*ifcompare_move_not): Likewise.
+ (*if_move_not): Likewise.
+ (*ifcompare_not_move): Likewise.
+ (*if_not_move): Likewise.
+ (*ifcompare_shift_move): Likewise.
+ (*if_shift_move): Likewise.
+ (*ifcompare_move_shift): Likewise.
+ (*if_move_shift): Likewise.
+ (*ifcompare_shift_shift): Likewise.
+ (*ifcompare_not_arith): Likewise.
+ (*ifcompare_arith_not): Likewise.
+ (*if_arith_not): Likewise.
+ (*ifcompare_neg_move): Likewise.
+ (*if_neg_move): Likewise.
+ (*ifcompare_move_neg): Likewise.
+ (*if_move_neg): Likewise.
+ (prologue_thumb1_interwork): Likewise.
+ (*cond_move_not): Likewise.
+ (*sign_extract_onebit): Likewise.
+ (*not_signextract_onebit): Likewise.
+ (stack_tie): Likewise.
+ (align_4): Likewise.
+ (align_8): Likewise.
+ (consttable_end): Likewise.
+ (consttable_1): Likewise.
+ (consttable_2): Likewise.
+ (consttable_4): Likewise.
+ (consttable_8): Likewise.
+ (consttable_16): Likewise.
+ (*thumb1_tablejump): Likewise.
+ (prefetch): Likewise.
+ (force_register_use): Likewise.
+ (thumb_eh_return): Likewise.
+ (load_tp_hard): Likewise.
+ (load_tp_soft): Likewise.
+ (tlscall): Likewise.
+ (*arm_movtas_ze): Likewise.
+ (*arm_rev): Likewise.
+ (*arm_revsh): Likewise.
+ (*arm_rev16): Likewise.
+ * config/arm/thumb2.md
+ (*thumb2_smaxsi3): Likewise.
+ (*thumb2_sminsi3): Likewise.
+ (*thumb32_umaxsi3): Likewise.
+ (*thumb2_uminsi3): Likewise.
+ (*thumb2_negdi2): Likewise.
+ (*thumb2_abssi2): Likewise.
+ (*thumb2_neg_abss): Likewise.
+ (*thumb2_movsi_insn): Likewise.
+ (tls_load_dot_plus_four): Likewise.
+ (*thumb2_movhi_insn): Likewise.
+ (*thumb2_mov_scc): Likewise.
+ (*thumb2_mov_negs): Likewise.
+ (*thumb2_mov_negs): Likewise.
+ (*thumb2_mov_nots): Likewise.
+ (*thumb2_mov_nots): Likewise.
+ (*thumb2_movsicc_): Likewise.
+ (*thumb2_movsfcc_soft_insn): Likewise.
+ (*thumb2_indirect_jump): Likewise.
+ (*thumb2_and_scc): Likewise.
+ (*thumb2_ior_scc): Likewise.
+ (*thumb2_ior_scc_strict_it): Likewise.
+ (*thumb2_cond_move): Likewise.
+ (*thumb2_cond_arith): Likewise.
+ (*thumb2_cond_ari): Likewise.
+ (*thumb2_cond_sub): Likewise.
+ (*thumb2_negscc): Likewise.
+ (*thumb2_movcond): Likewise.
+ (thumb2_casesi_internal): Likewise.
+ (thumb2_casesi_internal_pic): Likewise.
+ (*thumb2_alusi3_short): Likewise.
+ (*thumb2_mov<mode>_shortim): Likewise.
+ (*thumb2_addsi_short): Likewise.
+ (*thumb2_subsi_short): Likewise.
+ (thumb2_addsi3_compare0): Likewise.
+ (*thumb2_cbz): Likewise.
+ (*thumb2_cbnz): Likewise.
+ (*thumb2_one_cmplsi2_short): Likewise.
+ (*thumb2_negsi2_short): Likewise.
+ (*orsi_notsi_si): Likewise.
+ * config/arm/arm1020e.md: Update with new attributes.
+ * config/arm/arm1026ejs.md: Update with new attributes.
+ * config/arm/arm1136jfs.md: Update with new attributes.
+ * config/arm/arm926ejs.md: Update with new attributes.
+ * config/arm/cortex-a15.md: Update with new attributes.
+ * config/arm/cortex-a5.md: Update with new attributes.
+ * config/arm/cortex-a53.md: Update with new attributes.
+ * config/arm/cortex-a7.md: Update with new attributes.
+ * config/arm/cortex-a8.md: Update with new attributes.
+ * config/arm/cortex-a9.md: Update with new attributes.
+ * config/arm/cortex-m4.md: Update with new attributes.
+ * config/arm/cortex-r4.md: Update with new attributes.
+ * config/arm/fa526.md: Update with new attributes.
+ * config/arm/fa606te.md: Update with new attributes.
+ * config/arm/fa626te.md: Update with new attributes.
+ * config/arm/fa726te.md: Update with new attributes.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-simd.md
+ (aarch64_sqdml<SBINQOPS:as>l_n<mode>_internal): Use
+ <vwx> iterator to ensure correct register choice.
+ (aarch64_sqdml<SBINQOPS:as>l2_n<mode>_internal): Likewise.
+ (aarch64_sqdmull_n<mode>): Likewise.
+ (aarch64_sqdmull2_n<mode>_internal): Likewise.
+ * config/aarch64/arm_neon.h
+ (vml<as><q>_lane<q>_<su>16): Use 'x' constraint for element vector.
+ (vml<as><q>_n_<su>16): Likewise.
+ (vml<as>l_high_lane<q>_<su>16): Likewise.
+ (vml<as>l_high_n_<su>16): Likewise.
+ (vml<as>l_lane<q>_<su>16): Likewise.
+ (vml<as>l_n_<su>16): Likewise.
+ (vmul<q>_lane<q>_<su>16): Likewise.
+ (vmul<q>_n_<su>16): Likewise.
+ (vmull_lane<q>_<su>16): Likewise.
+ (vmull_n_<su>16): Likewise.
+ (vmull_high_lane<q>_<su>16): Likewise.
+ (vmull_high_n_<su>16): Likewise.
+ (vqrdmulh<q>_n_s16): Likewise.
+
+2013-09-06 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/arm_neon.h: Fix all vdup<bhsd_lane<q> intrinsics to
+ have the correct lane parameter.
+
+2013-09-06 Richard Biener <rguenther@suse.de>
+
+ * cfganal.c (control_dependences::~control_dependences):
+ Properly free all of the vector.
+
+2013-09-06 Kirill Yukhin <kirill.yukhin@intel.com>
+
+ PR target/58269
+ * config/i386/i386.c (ix86_conditional_register_usage):
+ Proper initialize extended SSE registers.
+
+2013-09-06 Jan Hubicka <jh@suse.cz>
+
+ PR tree-optimization/58311
+ * ipa-devirt.c (gate_ipa_devirt): Only execute when optimizing.
+
+2013-09-06 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (tree-sra.o): Update dependencies.
+ * tree-sra.c: Include ipa-utils.h
+ (scan_function): Use recursive_call_p.
+ (has_caller_p): New function.
+ (cgraph_for_node_and_aliases): Count also callers of aliases.
+
+2013-09-06 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/58094
+ * cgraph.h (symtab_semantically_equivalent_p): Declare.
+ * tree-tailcall.c: Include ipa-utils.h.
+ (find_tail_calls): Use it.
+ * ipa-pure-const.c (check_call): Likewise.
+ * ipa-utils.c (recursive_call_p): New function.
+ * ipa-utils.h (recursive_call_p): Dclare.
+ * symtab.c (symtab_nonoverwritable_alias): Fix formatting.
+ (symtab_semantically_equivalent_p): New function.
+ * Makefile.in (tree-tailcall.o): Update dependencies.
+
+2013-09-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * ipa-split.c (split_function): Set DECL_NO_INLINE_WARNING_P on the
+ non-inlinable part.
+
+2013-09-06 Richard Biener <rguenther@suse.de>
+
+ * lto-streamer.h (lto_global_var_decls): Remove.
+ * Makefile.in (OBJS): Remove lto-symtab.o.
+ (lto-symtab.o): Remove.
+ (GTFILES): Remove lto-symtab.c
+ * lto-symtab.c: Move to lto/
+
+2013-09-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * config/s390/s390.md (UNSPEC_FPINT_FLOOR, UNSPEC_FPINT_BTRUNC)
+ (UNSPEC_FPINT_ROUND, UNSPEC_FPINT_CEIL, UNSPEC_FPINT_NEARBYINT)
+ (UNSPEC_FPINT_RINT): New constant definitions.
+ (FPINT, fpint_name, fpint_roundingmode): New integer iterator
+ definition with 2 attributes.
+ ("<FPINT:fpint_name><BFP:mode>2", "rint<BFP:mode>2")
+ ("<FPINT:fpint_name><DFP:mode>2", "rint<DFP:mode>2"): New pattern
+ definitions.
+
+2013-09-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * config/s390/s390.md: Add "bcr_flush" value to mnemonic
+ attribute.
+ ("mem_thread_fence_1"): Use bcr 14,0 for z196 and later.
+ Set the mnemonic attribute to "bcr_flush". Set the "z196prop"
+ attribute to "z196_alone".
+ * config/s390/2827.md: Add "bcr_flush" to "ooo_groupalone" and
+ "zEC12_simple".
+
+2013-09-06 Richard Biener <rguenther@suse.de>
+
+ * basic-block.h (class control_dependences): New.
+ * tree-ssa-dce.c (control_dependence_map): Remove.
+ (cd): New global.
+ (EXECUTE_IF_CONTROL_DEPENDENT): Remove.
+ (set_control_dependence_map_bit, clear_control_dependence_bitmap,
+ find_pdom, find_control_dependence, find_all_control_dependences):
+ Move to cfganal.c.
+ (mark_control_dependent_edges_necessary, find_obviously_necessary_stmts,
+ propagate_necessity, tree_dce_init, tree_dce_done,
+ perform_tree_ssa_dce): Adjust.
+ * cfganal.c (set_control_dependence_map_bit,
+ clear_control_dependence_bitmap, find_pdom, find_control_dependence,
+ find_all_control_dependences): Move from tree-ssa-dce.c and
+ implement as methods of control_dependences class.
+ (control_dependences::control_dependences): New.
+ (control_dependences::~control_dependences): Likewise.
+ (control_dependences::get_edges_dependent_on): Likewise.
+ (control_dependences::get_edge): Likewise.
+
+2013-09-04 Jan Hubicka <jh@suse.cz>
+
+ * tree.c (types_same_for_odr): Drop overactive check.
+ * ipa-devirt.c (hash_type_name): Likewise.
+
+2013-09-04 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (walk_polymorphic_call_targets): Break out from ...
+ (analyze_functions): ... here.
+
+2013-09-04 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/58201
+ * cgraphunit.c (analyze_functions): Clear AUX fields
+ after processing; initialize assembler name has.
+
+2013-09-05 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadedge.c (thread_around_empty_blocks): Renamed
+ from thread_around_empty_block. Record threading path into PATH.
+ Recurse if threading through the initial block is successful.
+ (thread_across_edge): Corresponding changes to slightly simplify.
+
+2013-09-05 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64.md
+ (type): Remove frecpe, frecps, frecpx.
+ (aarch64_frecp<FRECP:frecp_suffix><mode>): Move to aarch64-simd.md,
+ fix to be a TARGET_SIMD instruction.
+ (aarch64_frecps): Remove.
+ * config/aarch64/aarch64-simd.md
+ (aarch64_frecp<FRECP:frecp_suffix><mode>): New, moved from aarch64.md
+ (aarch64_frecps<mode>): Handle all float/vector of float modes.
+
+2013-09-05 James Greenhalgh <james.greenhalgh@arm.com>
+ Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/arm/types.md (define_attr "type"):
+ Expand "arlo_imm"
+ into "adr", "alu_imm", "alus_imm", "logic_imm", "logics_imm".
+ Expand "arlo_reg"
+ into "adc_reg", "adc_imm", "adcs_reg", "adcs_imm", "alu_ext",
+ "alu_reg", "alus_ext", "alus_reg", "bfm", "csel", "logic_reg",
+ "logics_reg", "rev".
+ Expand "arlo_shift"
+ into "alu_shift_imm", "alus_shift_imm", "logic_shift_imm",
+ "logics_shift_imm".
+ Expand "arlo_shift_reg"
+ into "alu_shift_reg", "alus_shift_reg", "logic_shift_reg",
+ "logics_shift_reg".
+ Expand "clz" into "clz, "rbit".
+ Rename "shift" to "shift_imm".
+ * config/arm/arm.md (define_attr "core_cycles"): Update for attribute
+ changes.
+ Update for attribute changes all occurrences of arlo_* and
+ shift* types.
+ * config/arm/arm-fixed.md: Update for attribute changes
+ all occurrences of arlo_* types.
+ * config/arm/thumb2.md: Update for attribute changes all occurrences
+ of arlo_* types.
+ * config/arm/arm.c (xscale_sched_adjust_cost): (rtx insn, rtx
+ (cortexa7_older_only): Likewise.
+ (cortexa7_younger): Likewise.
+ * config/arm/arm1020e.md (1020alu_op): Update for attribute changes.
+ (1020alu_shift_op): Likewise.
+ (1020alu_shift_reg_op): Likewise.
+ * config/arm/arm1026ejs.md (alu_op): Update for attribute changes.
+ (alu_shift_op): Likewise.
+ (alu_shift_reg_op): Likewise.
+ * config/arm/arm1136jfs.md (11_alu_op): Update for
+ attribute changes.
+ (11_alu_shift_op): Likewise.
+ (11_alu_shift_reg_op): Likewise.
+ * config/arm/arm926ejs.md (9_alu_op): Update for attribute changes.
+ (9_alu_shift_reg_op): Likewise.
+ * config/arm/cortex-a15.md (cortex_a15_alu): Update for
+ attribute changes.
+ (cortex_a15_alu_shift): Likewise.
+ (cortex_a15_alu_shift_reg): Likewise.
+ * config/arm/cortex-a5.md (cortex_a5_alu): Update for
+ attribute changes.
+ (cortex_a5_alu_shift): Likewise.
+ * config/arm/cortex-a53.md
+ (cortex_a53_alu): Update for attribute changes.
+ (cortex_a53_alu_shift): Likewise.
+ * config/arm/cortex-a7.md
+ (cortex_a7_alu_imm): Update for attribute changes.
+ (cortex_a7_alu_reg): Likewise.
+ (cortex_a7_alu_shift): Likewise.
+ * config/arm/cortex-a8.md
+ (cortex_a8_alu): Update for attribute changes.
+ (cortex_a8_alu_shift): Likewise.
+ (cortex_a8_alu_shift_reg): Likewise.
+ * config/arm/cortex-a9.md
+ (cortex_a9_dp): Update for attribute changes.
+ (cortex_a9_dp_shift): Likewise.
+ * config/arm/cortex-m4.md
+ (cortex_m4_alu): Update for attribute changes.
+ * config/arm/cortex-r4.md
+ (cortex_r4_alu): Update for attribute changes.
+ (cortex_r4_mov): Likewise.
+ (cortex_r4_alu_shift_reg): Likewise.
+ * config/arm/fa526.md
+ (526_alu_op): Update for attribute changes.
+ (526_alu_shift_op): Likewise.
+ * config/arm/fa606te.md
+ (606te_alu_op): Update for attribute changes.
+ * config/arm/fa626te.md
+ (626te_alu_op): Update for attribute changes.
+ (626te_alu_shift_op): Likewise.
+ * config/arm/fa726te.md
+ (726te_alu_op): Update for attribute changes.
+ (726te_alu_shift_op): Likewise.
+ (726te_alu_shift_reg_op): Likewise.
+ * config/arm/fmp626.md (mp626_alu_op): Update for attribute changes.
+ (mp626_alu_shift_op): Likewise.
+ * config/arm/marvell-pj4.md (pj4_alu): Update for attribute changes.
+ (pj4_alu_conds): Likewise.
+ (pj4_shift): Likewise.
+ (pj4_shift_conds): Likewise.
+ (pj4_alu_shift): Likewise.
+ (pj4_alu_shift_conds): Likewise.
+ * config/aarch64/aarch64.md: Update for attribute change
+ all occurrences of arlo_* and shift* types.
+
+2013-09-05 Mike Stump <mikestump@comcast.net>
+
+ * tree.h: Move documentation for tree_function_decl to tree-core.h
+ with the declaration.
+
+2013-09-05 Peter Bergner <bergner@vnet.ibm.com>
+
+ PR target/58139
+ * reginfo.c (choose_hard_reg_mode): Scan through all mode classes
+ looking for widest mode.
+
+2013-09-05 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config.gcc (*-*-vxworks*): Do not override an existing extra_objs.
+
+2013-09-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58137
+ * tree-vect-stmts.c (get_vectype_for_scalar_type_and_size):
+ Do not create vectors of pointers.
+ * tree-vect-loop.c (get_initial_def_for_induction): Use proper
+ types for the components of the vector initializer.
+ * tree-cfg.c (verify_gimple_assign_binary): Remove special-casing
+ allowing pointer vectors with PLUS_EXPR/MINUS_EXPR.
+
+2013-09-05 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-prop.c (remove_described_reference): Accept missing references,
+ return false if that hppens, otherwise return true.
+ (cgraph_node_for_jfunc): New function.
+ (try_decrement_rdesc_refcount): Likewise.
+ (try_make_edge_direct_simple_call): Use them.
+ (ipa_edge_removal_hook): Remove references from rdescs.
+ (ipa_edge_duplication_hook): Clone rdescs and their references
+ when the new edge has the same caller as the old one.
+ * cgraph.c (cgraph_resolve_speculation): Remove speculative
+ reference before removing any edges.
+
+2013-09-05 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.c (thumb2_emit_strd_push): Rewrite to use pre-decrement on
+ initial store.
+ * thumb2.md (thumb2_storewb_parisi): New pattern.
+
+2013-09-05 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * config/aarch64/aarch64-option-extensions.def: Add
+ AARCH64_OPT_EXTENSION of 'crc'.
+ * config/aarch64/aarch64.h (AARCH64_FL_CRC): New define.
+ (AARCH64_ISA_CRC): Ditto.
+ * doc/invoke.texi (-march and -mcpu feature modifiers): Add
+ description of the CRC extension.
+
+2013-09-05 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ * config/rs6000/linux64.h: Define OPTION_BIONIC and OPTION_UCLIBC.
+ * config/rs6000/linux.h: Ditto.
+ * alpha/linux.h: Ditto.
+ * config/bfin/uclinux.h: Define TARGET_LIBC_HAS_FUNCTION as
+ no_c99_libc_has_function.
+ * config/c6x/uclinux-elf.h: Ditto.
+ * config/lm32/uclinux-elf.h: Ditto.
+ * config/m68k/uclinux.h: Ditto.
+ * config/moxie/uclinux.h: Ditto.
+ * config.gcc (bfin*-linux-uclibc*): Add t-linux-android to tmake_file.
+ (crisv32-*-linux*, cris-*-linux*): Ditto.
+ * config/bfin/bfin.c: Include "tm_p.h".
+
+2013-09-05 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-loop.c (vect_analyze_loop_operations): Properly
+ check for a definition without a basic-block.
+
+2013-09-05 James Greenhalgh <james.greenhalgh@arm.com>
+ Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/aarch64/aarch64.md
+ (*movti_aarch64): Rename r_2_f and f_2_r.
+ (*movsf_aarch64): Likewise.
+ (*movdf_aarch64): Likewise.
+ (*movtf_aarch64): Likewise.
+ (aarch64_movdi_<mode>low): Likewise.
+ (aarch64_movdi_<mode>high): Likewise.
+ (aarch64_mov<mode>high_di): Likewise.
+ (aarch64_mov<mode>low_di): Likewise.
+ (aarch64_movtilow_tilow): Likewise.
+ * config/arm/arm.md (attribute "neon_type"): Delete. Move attribute
+ values to config/arm/types.md
+ (attribute "conds"): Update for attribute change.
+ (anddi3_insn): Likewise.
+ (iordi3_insn): Likewise.
+ (xordi3_insn): Likewise.
+ (one_cmpldi2): Likewise.
+ * config/arm/types.md (type): Add Neon types.
+ * config/arm/neon.md (neon_mov<mode>): Remove "neon_type" attribute,
+ use "type" attribute.
+ (movmisalign<mode>_neon_store): Likewise.
+ (movmisalign<mode>_neon_load): Likewise.
+ (vec_set<mode>_internal): Likewise.
+ (vec_setv2di_internal): Likewise.
+ (vec_extract<mode>): Likewise.
+ (vec_extractv2di): Likewise.
+ (add<mode>3_neon): Likewise.
+ (adddi3_neon): Likewise.
+ (sub<mode>3_neon): Likewise.
+ (subdi3_neon): Likewise.
+ (mul<mode>3_neon): Likewise.
+ (mul<mode>3add<mode>_neon): Likewise.
+ (mul<mode>3neg<mode>add<mode>_neon): Likewise.
+ (fma<VCVTF:mode>4)): Likewise.
+ (fma<VCVTF:mode>4_intrinsic): Likewise.
+ (fmsub<VCVTF:mode>4)): Likewise.
+ (fmsub<VCVTF:mode>4_intrinsic): Likewise.
+ (neon_vrint<NEON_VRINT:nvrint_variant><VCVTF:mode>): Likewise.
+ (ior<mode>3): Likewise.
+ (and<mode>3): Likewise.
+ (anddi3_neon): Likewise.
+ (orn<mode>3_neon): Likewise.
+ (orndi3_neon): Likewise.
+ (bic<mode>3_neon): Likewise.
+ (bicdi3_neon): Likewise.
+ (xor<mode>3): Likewise.
+ (one_cmpl<mode>2): Likewise.
+ (abs<mode>2): Likewise.
+ (neg<mode>2): Likewise.
+ (umin<mode>3_neon): Likewise.
+ (umax<mode>3_neon): Likewise.
+ (smin<mode>3_neon): Likewise.
+ (smax<mode>3_neon): Likewise.
+ (vashl<mode>3): Likewise.
+ (vashr<mode>3_imm): Likewise.
+ (vlshr<mode>3_imm): Likewise.
+ (ashl<mode>3_signed): Likewise.
+ (ashl<mode>3_unsigned): Likewise.
+ (neon_load_count): Likewise.
+ (ashldi3_neon_noclobber): Likewise.
+ (signed_shift_di3_neon): Likewise.
+ (unsigned_shift_di3_neon): Likewise.
+ (ashrdi3_neon_imm_noclobber): Likewise.
+ (lshrdi3_neon_imm_noclobber): Likewise.
+ (widen_ssum<mode>3): Likewise.
+ (widen_usum<mode>3): Likewise.
+ (quad_halves_<code>v4si): Likewise.
+ (quad_halves_<code>v4sf): Likewise.
+ (quad_halves_<code>v8hi): Likewise.
+ (quad_halves_<code>v16qi): Likewise.
+ (reduc_splus_v2di): Likewise.
+ (neon_vpadd_internal<mode>): Likewise.
+ (neon_vpsmin<mode>): Likewise.
+ (neon_vpsmax<mode>): Likewise.
+ (neon_vpumin<mode>): Likewise.
+ (neon_vpumax<mode>): Likewise.
+ (ss_add<mode>_neon): Likewise.
+ (us_add<mode>_neon): Likewise.
+ (ss_sub<mode>_neon): Likewise.
+ (us_sub<mode>_neon): Likewise.
+ (neon_vadd<mode>_unspec): Likewise.
+ (neon_vaddl<mode>): Likewise.
+ (neon_vaddw<mode>): Likewise.
+ (neon_vhadd<mode>): Likewise.
+ (neon_vqadd<mode>): Likewise.
+ (neon_vaddhn<mode>): Likewise.
+ (neon_vmul<mode>): Likewise.
+ (neon_vmla<mode>): Likewise.
+ (neon_vmlal<mode>): Likewise.
+ (neon_vmls<mode>): Likewise.
+ (neon_vmlsl<mode>): Likewise.
+ (neon_vqdmulh<mode>): Likewise.
+ (neon_vqdmlal<mode>): Likewise.
+ (neon_vqdmlsl<mode>): Likewise.
+ (neon_vmull<mode>): Likewise.
+ (neon_vqdmull<mode>): Likewise.
+ (neon_vsub<mode>_unspec): Likewise.
+ (neon_vsubl<mode>): Likewise.
+ (neon_vsubw<mode>): Likewise.
+ (neon_vqsub<mode>): Likewise.
+ (neon_vhsub<mode>): Likewise.
+ (neon_vsubhn<mode>): Likewise.
+ (neon_vceq<mode>): Likewise.
+ (neon_vcge<mode>): Likewise.
+ (neon_vcgeu<mode>): Likewise.
+ (neon_vcgt<mode>): Likewise.
+ (neon_vcgtu<mode>): Likewise.
+ (neon_vcle<mode>): Likewise.
+ (neon_vclt<mode>): Likewise.
+ (neon_vcage<mode>): Likewise.
+ (neon_vcagt<mode>): Likewise.
+ (neon_vtst<mode>): Likewise.
+ (neon_vabd<mode>): Likewise.
+ (neon_vabdl<mode>): Likewise.
+ (neon_vaba<mode>): Likewise.
+ (neon_vabal<mode>): Likewise.
+ (neon_vmax<mode>): Likewise.
+ (neon_vmin<mode>): Likewise.
+ (neon_vpaddl<mode>): Likewise.
+ (neon_vpadal<mode>): Likewise.
+ (neon_vpmax<mode>): Likewise.
+ (neon_vpmin<mode>): Likewise.
+ (neon_vrecps<mode>): Likewise.
+ (neon_vrsqrts<mode>): Likewise.
+ (neon_vqabs<mode>): Likewise.
+ (neon_vqneg<mode>): Likewise.
+ (neon_vcls<mode>): Likewise.
+ (clz<mode>2): Likewise.
+ (popcount<mode>2): Likewise.
+ (neon_vrecpe): Likewise.
+ (neon_vrsqrte): Likewise.
+ (neon_vget_lane<mode>_sext_internal): Likewise.
+ (neon_vget_lane<mode>_zext_internal): Likewise.
+ (neon_vdup_n<mode>): Likewise.
+ (neon_vdup_nv2di): Likewise.
+ (neon_vdpu_lane<mode>_internal): Likewise.
+ (neon_vswp<mode>): Likewise.
+ (float<mode><V_cvtto>2): Likewise.
+ (floatuns<mode><V_cvtto>2): Likewise.
+ (fix_trunc<mode><V_cvtto>)2): Likewise
+ (fixuns_trunc<mode><V_cvtto)2): Likewise.
+ (neon_vcvt<mode>): Likewise.
+ (neon_vcvtv4sfv4hf): Likewise.
+ (neon_vcvtv4hfv4sf): Likewise.
+ (neon_vcvt_n<mode>): Likewise.
+ (neon_vmovn<mode>): Likewise.
+ (neon_vqmovn<mode>): Likewise.
+ (neon_vqmovun<mode>): Likewise.
+ (neon_vmovl<mode>): Likewise.
+ (neon_vmul_lane<mode>): Likewise.
+ (neon_vmull_lane<mode>): Likewise.
+ (neon_vqdmull_lane<mode>): Likewise.
+ (neon_vqdmulh_lane<mode>): Likewise.
+ (neon_vmla_lane<mode>): Likewise.
+ (neon_vmlal_lane<mode>): Likewise.
+ (neon_vqdmlal_lane<mode>): Likewise.
+ (neon_vmls_lane<mode>): Likewise.
+ (neon_vmlsl_lane<mode>): Likewise.
+ (neon_vqdmlsl_lane<mode>): Likewise.
+ (neon_vext<mode>): Likewise.
+ (neon_vrev64<mode>): Likewise.
+ (neon_vrev32<mode>): Likewise.
+ (neon_vrev16<mode>): Likewise.
+ (neon_vbsl<mode>_internal): Likewise.
+ (neon_vshl<mode>): Likewise.
+ (neon_vqshl<mode>): Likewise.
+ (neon_vshr_n<mode>): Likewise.
+ (neon_vshrn_n<mode>): Likewise.
+ (neon_vqshrn_n<mode>): Likewise.
+ (neon_vqshrun_n<mode>): Likewise.
+ (neon_vshl_n<mode>): Likewise.
+ (neon_vqshl_n<mode>): Likewise.
+ (neon_vqshlu_n<mode>): Likewise.
+ (neon_vshll_n<mode>): Likewise.
+ (neon_vsra_n<mode>): Likewise.
+ (neon_vsri_n<mode>): Likewise.
+ (neon_vsli_n<mode>): Likewise.
+ (neon_vtbl1v8qi): Likewise.
+ (neon_vtbl2v8qi): Likewise.
+ (neon_vtbl3v8qi): Likewise.
+ (neon_vtbl4v8qi): Likewise.
+ (neon_vtbx1v8qi): Likewise.
+ (neon_vtbx2v8qi): Likewise.
+ (neon_vtbx3v8qi): Likewise.
+ (neon_vtbx4v8qi): Likewise.
+ (neon_vtrn<mode>_internal): Likewise.
+ (neon_vzip<mode>_internal): Likewise.
+ (neon_vuzp<mode>_internal): Likewise.
+ (neon_vld1<mode>): Likewise.
+ (neon_vld1_lane<mode>): Likewise.
+ (neon_vld1_dup<mode>): Likewise.
+ (neon_vld1_dupv2di): Likewise.
+ (neon_vst1<mode>): Likewise.
+ (neon_vst1_lane<mode>): Likewise.
+ (neon_vld2<mode>): Likewise.
+ (neon_vld2_lane<mode>): Likewise.
+ (neon_vld2_dup<mode>): Likewise.
+ (neon_vst2<mode>): Likewise.
+ (neon_vst2_lane<mode>): Likewise.
+ (neon_vld3<mode>): Likewise.
+ (neon_vld3qa<mode>): Likewise.
+ (neon_vld3qb<mode>): Likewise.
+ (neon_vld3_lane<mode>): Likewise.
+ (neon_vld3_dup<mode>): Likewise.
+ (neon_vst3<mode>): Likewise.
+ (neon_vst3qa<mode>): Likewise.
+ (neon_vst3qb<mode>): Likewise.
+ (neon_vst3_lane<mode>): Likewise.
+ (neon_vld4<mode>): Likewise.
+ (neon_vld4qa<mode>): Likewise.
+ (neon_vld4qb<mode>): Likewise.
+ (neon_vld4_lane<mode>): Likewise.
+ (neon_vld4_dup<mode>): Likewise.
+ (neon_vst4<mode>): Likewise.
+ (neon_vst4qa<mode>): Likewise.
+ (neon_vst4qb<mode>): Likewise.
+ (neon_vst4_lane<mode>): Likewise.
+ (neon_vec_unpack<US>_lo_<mode>): Likewise.
+ (neon_vec_unpack<US>_hi_<mode>): Likewise.
+ (neon_vec_<US>mult_lo_<mode>): Likewise.
+ (neon_vec_<US>mult_hi_<mode>): Likewise.
+ (neon_vec_<US>shiftl_<mode>): Likewise.
+ (neon_unpack<US>_<mode>): Likewise.
+ (neon_vec_<US>mult_<mode>): Likewise.
+ (vec_pack_trunc_<mode>): Likewise.
+ (neon_vec_pack_trunk_<mode>): Likewise.
+ (neon_vabd<mode>_2): Likewise.
+ (neon_vabd<mode>_3): Likewise.
+ * config/arm/vfp.md (arm_movsi_vfp): Update for attribute changes.
+ (thumb2_movsi_vfp): Likewise.
+ (movdi_vfp): Likewise.
+ (movdi_vfp_cortexa8): Likewise.
+ (movhf_vfp_neon): Likewise.
+ (movhf_vfp): Likewiwse.
+ (movsf_vfp): Likewiwse.
+ (thumb2_movsf_vfp): Likewiwse.
+ (movdf_vfp): Likewise.
+ (thumb2_movdf_vfp): Likewise.
+ (movsfcc_vfp): Likewise.
+ (thumb2_movsfcc_vfp): Likewise.
+ (movdfcc_vfp): Likewise.
+ (thumb2_movdfcc_vfp): Likewise.
+ * config/arm/arm.c (cortexa7_older_only): Update for attribute change.
+ * config/arm/arm1020e.md (v10_c2v): Update for attribute change.
+ (v10_v2c): Likewise.
+ * config/arm/cortex-a15-neon.md (cortex_a15_neon_int_1): Update for
+ attribute change.
+ (cortex_a15_neon_int_2): Likewise.
+ (cortex_a15_neon_int_3): Likewise.
+ (cortex_a15_neon_int_4): Likewise.
+ (cortex_a15_neon_int_5): Likewise.
+ (cortex_a15_neon_vqneg_vqabs): Likewise.
+ (cortex_a15_neon_vmov): Likewise.
+ (cortex_a15_neon_vaba): Likewise.
+ (cortex_a15_neon_vaba_qqq): Likewise.
+ (cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long): Likewise.
+ (cortex_a15_neon_mul_qqq_8_16_32_ddd_32): Likewise.
+ (cortex_a15_neon_mul_qdd_64_32_long_qqd_16_ddd_32_\
+ scalar_64_32_long_scalar): Likewise.
+ (cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long): Likewise.
+ (cortex_a15_neon_mla_qqq_8_16): Likewise.
+ (cortex_a15_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_\
+ lotype_qdd_64_32_long): Likewise.
+ (cortex_a15_neon_mla_qqq_32_qqd_32_scalar): Likewise.
+ (cortex_a15_neon_mul_ddd_16_scalar_32_16_long_scalar): Likewise.
+ (cortex_a15_neon_mul_qqd_32_scalar): Likewise.
+ (cortex_a15_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar): Likewise.
+ (cortex_a15_neon_shift_1): Likewise.
+ (cortex_a15_neon_shift_2): Likewise.
+ (cortex_a15_neon_shift_3): Likewise.
+ (cortex_a15_neon_vshl_ddd): Likewise.
+ (cortex_a15_neon_vqshl_vrshl_vqrshl_qqq): Likewise.
+ (cortex_a15_neon_vsra_vrsra): Likewise.
+ (cortex_a15_neon_fp_vadd_ddd_vabs_dd): Likewise.
+ (cortex_a15_neon_fp_vadd_qqq_vabs_qq): Likewise.
+ (cortex_a15_neon_fp_vmul_ddd): Likewise.
+ (cortex_a15_neon_fp_vmul_qqd): Likewise.
+ (cortex_a15_neon_fp_vmla_ddd): Likewise.
+ (cortex_a15_neon_fp_vmla_qqq): Likewise.
+ (cortex_a15_neon_fp_vmla_ddd_scalar): Likewise.
+ (cortex_a15_neon_fp_vmla_qqq_scalar): Likewise.
+ (cortex_a15_neon_fp_vrecps_vrsqrts_ddd): Likewise.
+ (cortex_a15_neon_fp_vrecps_vrsqrts_qqq): Likewise.
+ (cortex_a15_neon_bp_simple): Likewise.
+ (cortex_a15_neon_bp_2cycle): Likewise.
+ (cortex_a15_neon_bp_3cycle): Likewise.
+ (cortex_a15_neon_vld1_1_2_regs): Likewise.
+ (cortex_a15_neon_vld1_3_4_regs): Likewise.
+ (cortex_a15_neon_vld2_2_regs_vld1_vld2_all_lanes): Likewise.
+ (cortex_a15_neon_vld2_4_regs): Likewise.
+ (cortex_a15_neon_vld3_vld4): Likewise.
+ (cortex_a15_neon_vst1_1_2_regs_vst2_2_regs): Likewise.
+ (cortex_a15_neon_vst1_3_4_regs): Likewise.
+ (cortex_a15_neon_vst2_4_regs_vst3_vst4): Likewise.
+ (cortex_a15_neon_vst3_vst4): Likewise.
+ (cortex_a15_neon_vld1_vld2_lane): Likewise.
+ (cortex_a15_neon_vld3_vld4_lane" 10
+ (cortex_a15_neon_vst1_vst2_lane): Likewise.
+ (cortex_a15_neon_vst3_vst4_lane): Likewise.
+ (cortex_a15_neon_vld3_vld4_all_lanes): Likewise.
+ (cortex_a15_neon_ldm_2): Likewise.0
+ (cortex_a15_neon_stm_2): Likewise.
+ (cortex_a15_neon_mcr): Likewise.
+ (cortex_a15_neon_mcr_2_mcrr): Likewise.
+ (cortex_a15_neon_mrc): Likewise.
+ (cortex_a15_neon_mrrc): Likewise.
+ * config/arm/cortex-a15.md (cortex_a15_alu): Update for attribute
+ change.
+ (cortex_a15_alu_shift): Likewise.
+ (cortex_a15_alu_shift_reg): Likewise.
+ (cortex_a15_mult32): Likewise.
+ (cortex_a15_mult64): Likewise.
+ (cortex_a15_block): Likewise.
+ (cortex_a15_branch): Likewise.
+ (cortex_a15_load1): Likewise.
+ (cortex_a15_load3): Likewise.
+ (cortex_a15_store1): Likewise.
+ (cortex_a15_store3): Likewise.
+ (cortex_a15_call): Likewise.
+ * config/arm/cortex-a5.md (cortex_a5_r2f): Update for attribute
+ change.
+ (cortex_a5_f2r): Likewise.
+ * config/arm/cortex-a53.md (cortex_a53_r2f): Update for attribute
+ change.
+ (cortex_a53_f2r): Likewise.
+ * config/arm/cortex-a7.md
+ (cortex_a7_branch): Update for attribute change.
+ (cortex_a7_call): Likewise.
+ (cortex_a7_alu_imm): Likewise.
+ (cortex_a7_alu_reg): Likewise.
+ (cortex_a7_alu_shift): Likewise.
+ (cortex_a7_mul): Likewise.
+ (cortex_a7_load1): Likewise.
+ (cortex_a7_store1): Likewise.
+ (cortex_a7_load2): Likewise.
+ (cortex_a7_store2): Likewise.
+ (cortex_a7_load3): Likewise.
+ (cortex_a7_store3): Likewise.
+ (cortex_a7_load4): Likewise.
+ (cortex_a7_store4): Likewise.
+ (cortex_a7_fpalu): Likewise.
+ (cortex_a7_fconst): Likewise.
+ (cortex_a7_fpmuls): Likewise.
+ (cortex_a7_neon_mul): Likewise.
+ (cortex_a7_fpmacs): Likewise.
+ (cortex_a7_neon_mla: Likewise.
+ (cortex_a7_fpmuld: Likewise.
+ (cortex_a7_fpmacd: Likewise.
+ (cortex_a7_fpfmad: Likewise.
+ (cortex_a7_fdivs: Likewise.
+ (cortex_a7_fdivd: Likewise.
+ (cortex_a7_r2f: Likewise.
+ (cortex_a7_f2r: Likewise.
+ (cortex_a7_f_flags: Likewise.
+ (cortex_a7_f_loads: Likewise.
+ (cortex_a7_f_loadd: Likewise.
+ (cortex_a7_f_stores: Likewise.
+ (cortex_a7_f_stored: Likewise.
+ (cortex_a7_neon): Likewise.
+ * config/arm/cortex-a8-neon.md
+ (cortex_a8_neon_mrc): Update for attribute change.
+ (cortex_a8_neon_mrrc): Likewise.
+ (cortex_a8_neon_int_1): Likewise.
+ (cortex_a8_neon_int_2): Likewise.
+ (cortex_a8_neon_int_3): Likewise.
+ (cortex_a8_neon_int_4): Likewise.
+ (cortex_a8_neon_int_5): Likewise.
+ (cortex_a8_neon_vqneg_vqabs): Likewise.
+ (cortex_a8_neon_vmov): Likewise.
+ (cortex_a8_neon_vaba): Likewise.
+ (cortex_a8_neon_vaba_qqq): Likewise.
+ (cortex_a8_neon_vsma): Likewise.
+ (cortex_a8_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long): Likewise.
+ (cortex_a8_neon_mul_qqq_8_16_32_ddd_32): Likewise.
+ (cortex_a8_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar):
+ Likewise.
+ (cortex_a8_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long): Likewise.
+ (cortex_a8_neon_mla_qqq_8_16): Likewise.
+ (cortex_a8_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_\
+ long_scalar_qdd_64_32_long): Likewise.
+ (cortex_a8_neon_mla_qqq_32_qqd_32_scalar): Likewise.
+ (cortex_a8_neon_mul_ddd_16_scalar_32_16_long_scalar): Likewise.
+ (cortex_a8_neon_mul_qqd_32_scalar): Likewise.
+ (cortex_a8_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar): Likewise.
+ (cortex_a8_neon_shift_1): Likewise.
+ (cortex_a8_neon_shift_2): Likewise.
+ (cortex_a8_neon_shift_3): Likewise.
+ (cortex_a8_neon_vshl_ddd): Likewise.
+ (cortex_a8_neon_vqshl_vrshl_vqrshl_qqq): Likewise.
+ (cortex_a8_neon_vsra_vrsra): Likewise.
+ (cortex_a8_neon_fp_vadd_ddd_vabs_dd): Likewise.
+ (cortex_a8_neon_fp_vadd_qqq_vabs_qq): Likewise.
+ (cortex_a8_neon_fp_vsum): Likewise.
+ (cortex_a8_neon_fp_vmul_ddd): Likewise.
+ (cortex_a8_neon_fp_vmul_qqd): Likewise.
+ (cortex_a8_neon_fp_vmla_ddd): Likewise.
+ (cortex_a8_neon_fp_vmla_qqq): Likewise.
+ (cortex_a8_neon_fp_vmla_ddd_scalar): Likewise.
+ (cortex_a8_neon_fp_vmla_qqq_scalar): Likewise.
+ (cortex_a8_neon_fp_vrecps_vrsqrts_ddd): Likewise.
+ (cortex_a8_neon_fp_vrecps_vrsqrts_qqq): Likewise.
+ (cortex_a8_neon_bp_simple): Likewise.
+ (cortex_a8_neon_bp_2cycle): Likewise.
+ (cortex_a8_neon_bp_3cycle): Likewise.
+ (cortex_a8_neon_ldr): Likewise.
+ (cortex_a8_neon_str): Likewise.
+ (cortex_a8_neon_vld1_1_2_regs): Likewise.
+ (cortex_a8_neon_vld1_3_4_regs): Likewise.
+ (cortex_a8_neon_vld2_2_regs_vld1_vld2_all_lanes): Likewise.
+ (cortex_a8_neon_vld2_4_regs): Likewise.
+ (cortex_a8_neon_vld3_vld4): Likewise.
+ (cortex_a8_neon_vst1_1_2_regs_vst2_2_regs): Likewise.
+ (cortex_a8_neon_vst1_3_4_regs): Likewise.
+ (cortex_a8_neon_vst2_4_regs_vst3_vst4): Likewise.
+ (cortex_a8_neon_vst3_vst4): Likewise.
+ (cortex_a8_neon_vld1_vld2_lane): Likewise.
+ (cortex_a8_neon_vld3_vld4_lane): Likewise.
+ (cortex_a8_neon_vst1_vst2_lane): Likewise.
+ (cortex_a8_neon_vst3_vst4_lane): Likewise.
+ (cortex_a8_neon_vld3_vld4_all_lanes): Likewise.
+ (cortex_a8_neon_mcr): Likewise.
+ (cortex_a8_neon_mcr_2_mcrr): Likewise.
+ * config/arm/cortex-a8.md (cortex_a8_alu): Update for attribute
+ change.
+ * config/arm/cortex-a9-neon.md (ca9_neon_mrc): Update for attribute
+ change.
+ (ca9_neon_mrrc): Likewise.
+ (cortex_a9_neon_int_1): Likewise.
+ (cortex_a9_neon_int_2): Likewise.
+ (cortex_a9_neon_int_3): Likewise.
+ (cortex_a9_neon_int_4): Likewise.
+ (cortex_a9_neon_int_5): Likewise.
+ (cortex_a9_neon_vqneg_vqabs): Likewise.
+ (cortex_a9_neon_vmov): Likewise.
+ (cortex_a9_neon_vaba): Likewise.
+ (cortex_a9_neon_vaba_qqq): Likewise.
+ (cortex_a9_neon_vsma): Likewise.
+ (cortex_a9_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long): Likewise.
+ (cortex_a9_neon_mul_qqq_8_16_32_ddd_32): Likewise.
+ (cortex_a9_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar):
+ Likewise.
+ (cortex_a9_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long): Likewise.
+ (cortex_a9_neon_mla_qqq_8_16): Likewise.
+ (cortex_a9_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_\
+ long_scalar_qdd_64_32_long): Likewise.
+ (cortex_a9_neon_mla_qqq_32_qqd_32_scalar): Likewise.
+ (cortex_a9_neon_mul_ddd_16_scalar_32_16_long_scalar): Likewise.
+ (cortex_a9_neon_mul_qqd_32_scalar): Likewise.
+ (cortex_a9_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar): Likewise.
+ (cortex_a9_neon_shift_1): Likewise.
+ (cortex_a9_neon_shift_2): Likewise.
+ (cortex_a9_neon_shift_3): Likewise.
+ (cortex_a9_neon_vshl_ddd): Likewise.
+ (cortex_a9_neon_vqshl_vrshl_vqrshl_qqq): Likewise.
+ (cortex_a9_neon_vsra_vrsra): Likewise.
+ (cortex_a9_neon_fp_vadd_ddd_vabs_dd): Likewise.
+ (cortex_a9_neon_fp_vadd_qqq_vabs_qq): Likewise.
+ (cortex_a9_neon_fp_vsum): Likewise.
+ (cortex_a9_neon_fp_vmul_ddd): Likewise.
+ (cortex_a9_neon_fp_vmul_qqd): Likewise.
+ (cortex_a9_neon_fp_vmla_ddd): Likewise.
+ (cortex_a9_neon_fp_vmla_qqq): Likewise.
+ (cortex_a9_neon_fp_vmla_ddd_scalar): Likewise.
+ (cortex_a9_neon_fp_vmla_qqq_scalar): Likewise.
+ (cortex_a9_neon_fp_vrecps_vrsqrts_ddd): Likewise.
+ (cortex_a9_neon_fp_vrecps_vrsqrts_qqq): Likewise.
+ (cortex_a9_neon_bp_simple): Likewise.
+ (cortex_a9_neon_bp_2cycle): Likewise.
+ (cortex_a9_neon_bp_3cycle): Likewise.
+ (cortex_a9_neon_ldr): Likewise.
+ (cortex_a9_neon_str): Likewise.
+ (cortex_a9_neon_vld1_1_2_regs): Likewise.
+ (cortex_a9_neon_vld1_3_4_regs): Likewise.
+ (cortex_a9_neon_vld2_2_regs_vld1_vld2_all_lanes): Likewise.
+ (cortex_a9_neon_vld2_4_regs): Likewise.
+ (cortex_a9_neon_vld3_vld4): Likewise.
+ (cortex_a9_neon_vst1_1_2_regs_vst2_2_regs): Likewise.
+ (cortex_a9_neon_vst1_3_4_regs): Likewise.
+ (cortex_a9_neon_vst2_4_regs_vst3_vst4): Likewise.
+ (cortex_a9_neon_vst3_vst4): Likewise.
+ (cortex_a9_neon_vld1_vld2_lane): Likewise.
+ (cortex_a9_neon_vld3_vld4_lane): Likewise.
+ (cortex_a9_neon_vst1_vst2_lane): Likewise.
+ (cortex_a9_neon_vst3_vst4_lane): Likewise.
+ (cortex_a9_neon_vld3_vld4_all_lanes): Likewise.
+ (cortex_a9_neon_mcr): Likewise.
+ (cortex_a9_neon_mcr_2_mcrr): Likewise.
+ * config/arm/cortex-a9.md (cortex_a9_dp): Update for attribute change.
+ (cortex_a9_fps): Likewise.
+ * config/arm/cortex-m4-fpu.md (cortex_m4_vmov_2): Update for attribute
+ change.
+ (cortex_m4_fmuls): Likewise.
+ * config/arm/cortex-r4f.md (cortex_r4_mcr): Update for attribute
+ change.
+ (cortex_r4_mrc): Likewise.
+ * config/arm/iterators.md: Update comment referring to neon_type.
+ * config/arm/iwmmxt.md
+ (iwmmxt_arm_movdi): Update for attribute change.
+ (iwmmxt_movsi_insn): Likewise.
+ * config/arm/marvell-pj4.md
+ (pj4_vfp_to_core): Update for attribute change.
+ (pj4_core_to_vfp): Likewise.
+ * config/arm/neon-schedgen.ml (emit_insn_reservations): Update for
+ attribute change.
+ * config/arm/vfp11.md (vfp_fload): Update for attribute change.
+ (vfp_fstore): Likewise.
+ * doc/md.texi: Change references to neon_type to refer to type.
+
+2013-09-04 Dodji Seketeli <dodji@redhat.com>
+
+ * tree.h (DECL_BUILT_IN): Fix typo in comment.
+
+2013-09-04 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/rs6000.h (ASM_OUTPUT_DEF_FROM_DECLS): Only emit
+ lglobl if not weak.
+
+2013-09-04 Easwaran Raman <eraman@google.com>
+
+ PR middle-end/57370
+ * tree-ssa-reassoc.c (get_stmt_uid_with_default): New function,
+ (build_and_add_sum): Use it.
+ (appears_later_in_bb): Simplify code.
+
+2013-09-04 Teresa Johnson <tejohnson@google.com>
+
+ * dumpfile.c (dump_finish): Don't close stderr/stdout.
+
+2013-09-04 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/arm_neon.h (vaddvq_<su>64): Fix return types.
+
+2013-09-04 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in (ipa-devirt.o): Add dependency on diagnostic.h
+ * ipa-devirt.c: Include diganostic.h
+ (odr_type_d): Add types and types_set.
+ (hash_type_name): Work for types with vtables during LTO.
+ (odr_hasher::remove): Fix comment; destroy types_set.
+ (add_type_duplicate): New function,
+ (get_odr_type): Use it.
+ (dump_type_inheritance_graph): Dump type duplicates.
+ * ipa.c (symtab_remove_unreachable_nodes): Build type inheritance
+ graph.
+ * tree.c (types_same_for_odr): Give exact answers on types with
+ virtual tables.
+
+2013-09-04 Dodji Seketeli <dodji@redhat.com>
+
+ * tree.h (DECL_BUILT_IN, DECL_IS_BUILTIN): Add more comments
+ explaining their differences.
+
+2013-09-04 Sandeep Kumar Singh<Sandeep.Singh2@kpitcummins.com>
+
+ * config/rx/rx.h: Add option -mcpu for target variants RX100 and RX200.
+
+2013-09-03 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadedge.c (thread_across_edge): Record entire path
+ when not threading through a joiner block. Pass joiner/no joiner
+ state to register_jump_thread.
+ * tree-ssa-threadupdate.c (register_jump_thread): Get joiner/no joiner
+ state from argument rather than implying on path length.
+ Dump the entire jump thread path into debugging dump.
+ * tree-flow.h (register_jump_thread): Update prototype.
+
+2013-08-29 Xinliang David Li <davidxl@google.com>
+
+ * tree-vect-data-refs.c (vect_compute_data_ref_alignment):
+ Remove a trivial gcc_assert.
+
+2013-08-29 Xinliang David Li <davidxl@google.com>
+
+ * tree-vect-slp.c (destroy_bb_vec_info): Data ref cleanup.
+ * tree-vect-loop.c (destroy_bb_vec_info): Ditto.
+ * tree-vect-data-refs.c (vect_compute_data_ref_alignment):
+ Delay base decl alignment adjustment.
+ * tree-vectorizer.c (vect_destroy_datarefs): New function.
+ * tree-vectorizer.h: New data structure.
+ (set_dr_misalignment): New function.
+ (dr_misalignment): Ditto.
+ * tree-vect-stmts.c (vectorizable_store): Ensure alignment.
+ (vectorizable_load): Ditto.
+ (ensure_base_align): New function.
+ (vectorize_loops): Add dbg_cnt support.
+ (execute_vect_slp): Ditto.
+ * dbgcnt.def: New debug counter.
+ * Makefile: New dependency.
+
+2013-09-03 Meador Inge <meadori@codesourcery.com>
+
+ Revert:
+
+ 2013-08-30 Meador Inge <meadori@codesourcery.com>
+
+ * tree-vrp.c (check_array_ref): Bail out on zero-length arrays.
+
+2013-09-03 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/rs6000.h (ASM_OUTPUT_DEF_FROM_DECLS): Emit lglobl for
+ function descriptor.
+
+2013-09-03 Richard Biener <rguenther@suse.de>
+
+ * tree-affine.c (add_elt_to_tree): Fix association issue,
+ avoid useless converts and make sure to always return a
+ properly typed result.
+
+2013-09-03 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57656
+ * fold-const.c (negate_expr_p): Fix division case.
+ (negate_expr): Likewise.
+
+2013-09-03 Richard Biener <rguenther@suse.de>
+
+ PR lto/58285
+ * tree-streamer-out.c: Include tm.h.
+ * Makefile.in (tree-streamer-out.o): Depend on $(TM_H).
+
+2013-09-03 Jan Hubicka <jh@suse.cz>
+
+ * tree-profile.c (tree_profiling): Cleanup CFG when done.
+
+2013-09-03 Alan Modra <amodra@gmail.com>
+
+ * config.gcc (powerpc*-*-linux*): Add support for little-endian
+ multilibs to big-endian target and vice versa.
+ * config/rs6000/t-linux64: Use := assignment on all vars.
+ (MULTILIB_EXTRA_OPTS): Remove fPIC.
+ (MULTILIB_OSDIRNAMES): Specify using mapping from multilib_options.
+ * config/rs6000/t-linux64le: New file.
+ * config/rs6000/t-linux64bele: New file.
+ * config/rs6000/t-linux64lebe: New file.
+
+2013-09-02 Jan Hubicka <jh@suse.cz>
+
+ * ipa-inline-transform.c (inline_transform): Do not
+ optimize_inline_calls when not optimizing.
+
+2013-09-02 Jan Hubicka <jh@suse.cz>
+
+ * lto-symtab.c (lto_symtab_merge_symbols): Add comments; merge
+ duplicated nodes for assembler names.
+ * symtab.c (symtab_unregister_node): Do not attempt to unlink
+ hard registers from assembler name hash.
+
+2013-09-02 Jan Hubicka <jh@suse.cz>
+
+ * ipa-split.c (execute_split_functions): Split externally visible
+ functions called once.
+
+2013-09-02 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/58106
+ * ipa-prop.c (ipa_edge_duplication_hook): Always put new rdesc to the
+ linked list. When finding the correct duplicate, also consider also
+ the caller in additon to its inlined_to node.
+
+2013-09-02 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-simd-builtins.def
+ (dup_lane_scalar): Remove.
+ * config/aarch64/aarch64-simd.md
+ (aarch64_simd_dup): Add 'w->w' alternative.
+ (aarch64_dup_lane<mode>): Allow for VALL.
+ (aarch64_dup_lane_scalar<mode>): Remove.
+ (aarch64_dup_lane_<vswap_width_name><mode>): New.
+ (aarch64_get_lane_signed<mode>): Add w->w altenative.
+ (aarch64_get_lane_unsigned<mode>): Likewise.
+ (aarch64_get_lane<mode>): Likewise.
+ * config/aarch64/aarch64.c (aarch64_evpc_dup): New.
+ (aarch64_expand_vec_perm_const_1): Use aarch64_evpc_dup.
+ * config/aarch64/iterators.md (VSWAP_WIDTH): New.
+ (VCON): Change container of V2SF.
+ (vswap_width_name): Likewise.
+ * config/aarch64/arm_neon.h
+ (__aarch64_vdup_lane_any): New.
+ (__aarch64_vdup<q>_lane<q>_<fpsu><8,16,32,64>): Likewise.
+ (vdup<q>_n_<psuf><8,16,32,64>): Convert to C implementation.
+ (vdup<q>_lane<q>_<fpsu><8,16,32,64>): Likewise.
+
+2013-09-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR middle-end/56382
+ * expr.c (emit_move_complex): Do not move complex FP values as parts if
+ the source or the destination is a single hard register.
+
+2013-09-02 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57511
+ * tree-scalar-evolution.c (instantiate_scev_name): Allow
+ non-linear SCEVs.
+
+2013-09-02 Richard Biener <rguenther@suse.de>
+
+ * tree-affine.c (add_elt_to_tree): Avoid converting all pointer
+ arithmetic to sizetype.
+
+2013-09-02 Bin Cheng <bin.cheng@arm.com>
+
+ * tree-ssa-loop-ivopts.c (set_autoinc_for_original_candidates):
+ Find auto-increment use both before and after candidate.
+
+2013-09-02 Marek Polacek <polacek@redhat.com>
+
+ * Makefile.in (ubsan.o): Add $(TM_P_H) dependency.
+
+2013-09-01 Jan Hubicka <jh@suse.cz>
+
+ * Makefile.in: Add ipa-profile.o
+ (ipa.o, ipa-devrit.o, ipa-inline-analysis.o): Adjust dependencies.
+ * cgraph.c (struct cgraph_propagate_frequency_data,
+ cgraph_propagate_frequency_1, cgraph_propagate_frequency): Move to
+ ipa-profile.c; replace cgraph_ by ipa_ prefix.
+ * cgraph.h (cgraph_propagate_frequency): Remove.
+ * ipa-inline-analysis.c: Include ipa-utils.h; drop duplicated cfgloop.h.
+ (inline_update_callee_summaries): Update.
+ * ipa-profile.c: New file.
+ * ipa-utils.h (ipa_propagate_frequency): Declare.
+ * ipa.c: Do not include pointer-set.h, hash-table.h, lto-streamer.h,
+ data-streamer.h, value-prof.h
+ (symtab_remove_unreachable_nodes): Update profile.
+ (struct histogram_entry, histogram, histogram_pool, histogram_hash,
+ account_time_size, cmp_counts, dump_histogram,
+ ipa_profile_generate_summary, ipa_profile_write_summary,
+ ipa_profile_read_summary, ipa_profile, gate_ipa_profile,
+ pass_data_ipa_profile, pass_ipa_profile, make_pass_ipa_profile):
+ Move to ipa-profile.c
+
+2013-09-01 John David Anglin <danglin@gcc.gnu.org>
+
+ * config/pa/pa.md: Allow "const 0" operand 1 in "scc" insns.
+
+2013-09-01 Jan Hubicka <jh@suse.cz>
+
+ * common.opt (fdevirtualize-speculatively): New function.
+ * invoke.texi (fdevirtualize-speculatively): Document.
+ * ipa-devirt.c: Include ipa-inline.h
+ (likely_target_p): New function.
+ (ipa_devirt): New function.
+ (gate_ipa_devirt): New function.
+ (pass_data_ipa_devirt): New static var.
+ (pass_ipa_devirt): Likewise.
+ (make_pass_ipa_devirt): New function.
+ * opts.c (default_options): Add OPT_fdevirtualize_speculatively.
+ (common_handle_option): Disable devirtualization when
+ value range profiling is available.
+ * passes.def (pass_ipa_devirt): Add.
+ * timever.def (TV_IPA_DEVIRT): New timevar.
+ * tree-pass.h (make_pass_ipa_devirt):
+
+2013-09-01 Iain Sandoe <iain@codesourcery.com>
+
+ * config/darwin.h (LINK_COMMAND_SPEC_A): Revise sanitizer specs to
+ include sanitize(undefined).
+
+2013-08-31 Diego Novillo <dnovillo@google.com>
+
+ * Makefile.in (TREE_CORE_H): Define.
+ (TREE_H): Use.
+ (GTFILES): Add tree-core.h.
+ * builtins.c (built_in_class_names): Use BUILT_IN_LAST to
+ size the array.
+ * tree-core.h: New file.
+ Move all data structures, enum, typedefs, global
+ declarations and constants from ...
+ * tree.h: ... here.
+
+2013-08-31 Jan Hubicka <jh@suse.cz>
+
+ * bulitins.c (expand_builtin): Do not early exit for gcov
+ instrumented functions.
+
+2013-08-31 Marek Polacek <polacek@redhat.com>
+
+ * ubsan.c: Include tm_p.h.
+
+2013-08-31 Jan Hubicka <jh@suse.cz>
+
+ * gimple-streamer-in.c (input_gimple_stmt): Silence parameter unused
+ warning.
+
+ * cgraph.c (cgraph_get_body): Update call of lto_input_function_body.
+ * gimple-streamer-in.c (input_gimple_stmt): Move sanity check to ...
+ * tree-cfg.c (verify_gimple_label): ... here.
+ * ipa-utils.c: Include lto-streamer.h, ipa-inline.h
+ (ipa_merge_profiles): New function.
+ * lto-streamer-in.c (lto_read_body): Take node instead of fn_decl.
+ (lto_input_function_body): Likewise.
+ * ipa-utils.h (ipa_merge_profiles): Declare.
+ * lto-streamer.h (lto_input_function_body): Update prototype.
+ (emit_label_in_global_context_p): Remove.
+ * lto-symtab.c: Include ipa-utils.h
+ (lto_cgraph_replace_node): Use ipa_merge_profiles.
+
+2013-08-31 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_speculative_call_info): Fix ref lookup
+
+2013-08-31 Jan Hubicka <jh@suse.cz>
+
+ * basic-block.h (apply_scale): Make scale parmeter gcov_type.
+
+2013-08-31 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/alpha/alpha.c (alpha_emit_conditional_move): Update
+ "cmp" RTX before signed_comparison_operator check to account
+ for "code" changes.
+
+2013-08-30 Jan Hubicka <jh@suse.cz>
+
+ * ipa-prop.c (ipa_set_jf_known_type): Check that we add only records.
+ (detect_type_change_1): Rename to ...
+ (detect_type_change): ... this one; early return on non-polymorphic
+ types.
+ (detect_type_change_ssa): Add comp_type parameter; update
+ use of detect_type_change.
+ (compute_complex_assign_jump_func): Add param_type parameter;
+ update use of detect_type_change_ssa.
+ (compute_complex_ancestor_jump_func): Likewise.
+ (ipa_get_callee_param_type): New function.
+ (ipa_compute_jump_functions_for_edge): Compute parameter type;
+ update calls to the jump function computation functions.
+
+2013-08-30 Teresa Johnson <tejohnson@google.com>
+ Steven Bosscher <steven@gcc.gnu.org>
+
+ * cfgrtl.c (fixup_new_cold_bb): New routine.
+ (commit_edge_insertions): Invoke fixup_partitions.
+ (find_partition_fixes): New routine.
+ (fixup_partitions): Ditto.
+ (verify_hot_cold_block_grouping): Update comments.
+ (rtl_verify_edges): Invoke find_partition_fixes.
+ (rtl_verify_bb_pointers): Update comments.
+ (rtl_verify_bb_layout): Ditto.
+ * basic-block.h (probably_never_executed_edge_p): Declare.
+ (fixup_partitions): Ditto.
+ * cfgcleanup.c (try_optimize_cfg): Invoke fixup_partitions.
+ * bb-reorder.c (sanitize_hot_paths): New function.
+ (find_rarely_executed_basic_blocks_and_crossing_edges): Invoke
+ sanitize_hot_paths.
+ * predict.c (probably_never_executed_edge_p): New routine.
+ * cfg.c (check_bb_profile): Add partition insanity warnings.
+
+2013-08-30 Meador Inge <meadori@codesourcery.com>
+
+ * tree-vrp.c (check_array_ref): Bail out on zero-length arrays.
+
+2013-08-30 Marek Polacek <polacek@redhat.com>
+
+ * Makefile.in (ubsan.o): Add.
+ (c-family/c-ubsan.o): Add.
+ (builtins.o): Add ubsan.h dependency.
+ * ubsan.h: New file.
+ * ubsan.c: New file.
+ * common.opt: Add -fsanitize=undefined option.
+ (flag_sanitize): Add variable.
+ (fsanitize=): Add option. Add Driver.
+ (fsanitize=thread): Remove option.
+ (fsanitize=address): Likewise.
+ (static-libubsan): New option.
+ * doc/invoke.texi: Document the new flag and -static-libubsan.
+ * sanitizer.def (DEF_SANITIZER_BUILTIN): Define.
+ (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE): Define.
+ * builtin-attrs.def (ATTR_COLD): Define.
+ (ATTR_COLD_NOTHROW_LEAF_LIST): Define.
+ * builtins.def (BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW,
+ BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS): Define.
+ * flag-types.h (sanitize_code): New enum.
+ * opts.c (common_handle_option): Parse command line arguments
+ of -fsanitize=. Add -fsanitize=unreachable option.
+ * varasm.c (get_variable_section): Adjust.
+ (assemble_noswitch_variable): Likewise.
+ (assemble_variable): Likewise.
+ (output_constant_def_contents): Likewise.
+ (categorize_decl_for_section): Likewise.
+ (place_block_symbol): Likewise.
+ (output_object_block): Likewise.
+ * builtins.def: Likewise.
+ * toplev.c (compile_file): Likewise.
+ (process_options): Likewise.
+ * cppbuiltin.c: Likewise.
+ * tsan.c (tsan_pass): Likewise.
+ (tsan_gate): Likewise.
+ (tsan_gate_O0): Likewise.
+ * cfgexpand.c (partition_stack_vars): Likewise.
+ (expand_stack_vars): Likewise.
+ (defer_stack_allocation): Likewise.
+ (expand_used_vars): Likewise.
+ * cfgcleanup.c (old_insns_match_p): Likewise.
+ * asan.c (asan_finish_file): Likewise.
+ (asan_instrument): Likewise.
+ (gate_asan): Likewise.
+ (initialize_sanitizer_builtins): Build BT_FN_VOID_PTR_PTR_PTR.
+ (ATTR_COLD_NOTHROW_LEAF_LIST): Define.
+ (asan_global_struct): Use pointer_sized_int_node instead
+ calling build_nonstandard_integer_type.
+ (initialize_sanitizer_builtins): Likewise.
+ (asan_finish_file): Likewise.
+ * gcc.c: Document %{%:function(args):X}.
+ (static_spec_functions): Add sanitize.
+ (handle_spec_function): Add retval_nonnull argument and if non-NULL,
+ store funcval != NULL there.
+ (do_spec_1): Adjust handle_spec_function caller.
+ (handle_braces): Allow %:function(args) as condition.
+ (sanitize_spec_function): New function.
+ (ADD_STATIC_LIBUBSAN_LIBS): Define.
+ (LIBUBSAN_SPEC): Likewise.
+ (LIBUBSAN_EARLY_SPEC): Likewise.
+ (SANITIZER_SPEC): Handle libubsan.
+ (SANITIZER_EARLY_SPEC): Likewise.
+ * config/darwin.h (LINK_COMMAND_SPEC_A): Use %:sanitize(address)
+ instead of fsanitize=address.
+ * config/arm/linux-eabi.h (ASAN_CC1_SPEC): Use %:sanitize(address)
+ instead of fsanitize=address*.
+ * builtins.c: Include ubsan.h.
+ (fold_builtin_0): Instrument __builtin_unreachable.
+ * config/rs6000/rs6000.h (FRAME_GROWS_DOWNWARD): Use flag_sanitize
+ instead of flag_asan.
+ * tree.h (enum tree_index): Add TI_POINTER_SIZED_TYPE.
+ (pointer_sized_int_node): Define.
+ * tree.c (build_common_tree_nodes): Initialize pointer_sized_int_node.
+
+2013-08-30 Mike Stump <mikestump@comcast.net>
+
+ * doc/install.texi (Prerequisites): Note regression in Tcl 8.6
+ with RE patterns.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_function_body_availability): Handle weakref
+ correctly.
+ * passes.def: Remove pass_fixup_cfg.
+ * ipa-inline.c (ipa_inline): When not optimizing, do not inline;
+ track when we need to remove functions.
+ (gate_ipa_inline): Execute inlining always; add comment why.
+ (pass_data_ipa_inline): Remove TODO_remove_functions.
+ * ipa-inline-analysis.c (inline_generate_summary): When not optimizing
+ do not produce summaries.
+ * symtab.c (change_decl_assembler_name): Handle renaming of weakrefs.
+ (symtab_nonoverwritable_alias): Assert we are not called on weakref.
+ * varpool.c (cgraph_variable_initializer_availability): Fix weakrefs,
+ constant pool and vtable.
+
+2013-08-30 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/arm_neon.h (__AARCH64_UINT64_C, __AARCH64_INT64_C):
+ New arm_neon.h's internal macros to specify 64-bit constants.
+ Avoid using stdint.h's macros.
+
+2013-08-30 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * recog.c (verify_changes): Verify that changes[i].old is non-zero
+ before applying REG_P.
+
+2013-08-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58277
+ * tree-ssa-strlen.c (strlen_enter_block): If do_invalidate gave up
+ after seeing too many stmts with vdef in between dombb and current
+ bb, invalidate everything.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ * fold-const.c (fold_single_bit_test): Fix overflow test.
+
+2013-08-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * function.c (assign_parm_setup_reg): For a parameter passed by pointer
+ and which can live in a register, always retrieve the value on entry.
+ * var-tracking.c (add_stores): Treat the copy on entry for a parameter
+ passed by invisible reference specially.
+ (emit_notes_in_bb) <MO_VAL_USE>: Emit notes before the instruction.
+ (vt_add_function_parameter): Correctly deal with a parameter passed by
+ invisible reference.
+
+2013-08-30 Jan Hubicka <jh@suse.cz>
+
+ * tree.c (set_call_expr_flags): Fix handling of TM_PURE.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58228
+ * tree-vect-data-refs.c (vect_analyze_data_ref_access): Do not
+ allow invariant loads in nested loop vectorization.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58223
+ * tree-loop-distribution.c (has_anti_dependence): Rename to ...
+ (has_anti_or_output_dependence): ... this and adjust to also
+ look for output dependences.
+ (mark_nodes_having_upstream_mem_writes): Adjust.
+ (rdg_flag_uses): Likewise.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58010
+ * tree-vect-loop.c (vect_create_epilog_for_reduction): Remove
+ assert that we have a loop-closed PHI.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * lto-symtab.c (lto_cgraph_replace_node): Free decl_in_state.
+ * cgraph.c (cgraph_release_function_body): Free decl_in_state.
+ * lto-section-in.c (lto_free_function_in_decl_state): New function.
+ (lto_free_function_in_decl_state_for_node): New function.
+
+2013-08-29 Xinliang David Li <davidxl@google.com>
+
+ * loop-unroll.c (report_unroll_peel): Minor message change.
+ * tree-vect-loop-manip.c (vect_do_peeling_for_alignment):
+ Emit alignment peeling message with default -fopt-info.
+ (vect_loop_versioning): Emit loop version info message.
+ * tree-vectorizer.c (vectorize_loops): Minor message change.
+ (execute_vect_slp): Ditto.
+
+2013-08-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cgraphclones.c (cgraph_create_virtual_clone): Compute the DECL_NAME
+ of the clone from the DECL_NAME of the original function.
+
+2013-08-29 Oleg Endo <olegendo@gcc.gnu.org>
+
+ * passes.c (register_pass): Add overload.
+ * tree-pass.h (register_pass): Forward declare it. Add comment.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * lto-streamer-out.c (hash_tree): Stream DECL_FINAL_P,
+ DECL_CXX_CONSTRUCTOR_P, DECL_CXX_DESTRUCTOR_P and TYPE_FINAL_P.
+ * lto-streamer-in.c (unpack_ts_decl_with_vis_value_fields): Stream
+ DECL_FINAL_P, DECL_CXX_CONSTRUCTOR_P and DECL_CXX_DESTRUCTOR_P.
+ (unpack_ts_type_common_value_fields): Stream TYPE_FINAL_P.
+ * tree-streamer-out.c (pack_ts_decl_with_vis_value_fields):
+ Add DECL_FINAL_P, DECL_CXX_CONSTRUCTOR_P and DECL_CXX_DESTRUCTOR_P.
+ (pack_ts_type_common_value_fields): Add TYPE_FINAL_P.
+
+2013-08-29 Teresa Johnson <tejohnson@google.com>
+
+ * dumpfile.c (dump_loc): Output column number.
+ * dumpfile.h (OPTGROUP_OTHER): Add and enable under OPTGROUP_ALL.
+ * doc/invoke.texi: Document optall -fopt-info flag.
+ * profile.c (read_profile_edge_counts): Use new dump framework.
+ (compute_branch_probabilities): Ditto.
+ * passes.c (pass_manager::register_one_dump_file): Use OPTGROUP_OTHER
+ when pass not in any opt group.
+ * pass_manager.h (pass_manager::get_pass_profile): New method.
+ * value-prof.c (check_counter): Use new dump framework.
+ (check_ic_target): Ditto.
+ * coverage.c (get_coverage_counts): Ditto.
+ (coverage_init): Setup new dump framework.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58246
+ * tree-ssa-dce.c (mark_aliased_reaching_defs_necessary_1): Properly
+ handle the dominance check inside a basic-block.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57287
+ * tree-ssa-copy.c (may_propagate_copy): Allow propagating
+ of default defs that appear in abnormal PHI nodes.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57685
+ * tree-vrp.c (register_edge_assert_for_1): Recurse only for
+ single-use operands to avoid exponential complexity.
+
+2013-08-28 Dehao Chen <dehao@google.com>
+
+ * ipa-inline.c (edge_badness): Fix integer underflow.
+
+2013-08-28 Uros Bizjak <ubizjak@gmail.com>
+
+ * gtm-builtins.def (_ITM_free): Declare leaf.
+
+2013-08-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/58067
+ * config/i386/i386.md (*tls_global_dynamic_64_largepic): New insn.
+ (*tls_local_dynamic_base_64_largepic): Likewise.
+ (tls_global_dynamic_64_<mode>, tls_local_dynamic_base_64_<mode>):
+ Remove predicate from call operand.
+ * config/i386/i386.c (ix86_tls_get_addr): For -mcmodel=large -fpic
+ return sum of pic_offset_table_rtx and UNSPEC_PLTOFF of the symbol.
+
+2013-08-28 Jeff Law <law@redhat.com>
+
+ * tree-ssa-threadedge.c (thread_around_empty_block): Remove
+ checks for the number of predecessors and successors allowed.
+ * tree-ssa-threadupdate.c (mark_threaded_blocks): Ignore requests
+ which require copying a joiner block if there is a request which
+ is a subpath that requires no joiner block copying.
+
+2013-08-28 Jan Hubicka <jh@suse.cz>
+
+ * lto-streamer-out.c (DFS_write_tree_body): Drop
+ BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX and BINFO_VPTR_INDEX.
+ (hash_tree): Do not hash DECL_DEFER_OUTPUT, BINFO_INHERITANCE_CHAIN,
+ BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX, DECL_IN_TEXT_SECTION.
+ * tree-streamer-in.c (unpack_ts_decl_common_value_fields):
+ Do not read DECL_ERROR_ISSUED.
+ (unpack_ts_decl_with_vis_value_fields): Do not read
+ DECL_DEFER_OUTPUT.
+ (lto_input_ts_binfo_tree_pointers): Do not read
+ BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX
+ * tree-streamer-out.c (pack_ts_decl_common_value_fields): Do not
+ write DECL_ERROR_ISSUED..
+ (pack_ts_decl_with_vis_value_fields): Do not write
+ DECL_DEFER_OUTPUT.
+ (write_ts_binfo_tree_pointers): Do not read BINFO_INHERITANCE_CHAIN,
+ BINFO_SUBVTT_INDEX, BINFO_VPTR_INDEX.
+ * print-tree.c (print_node): Do not print DECL_ERROR_ISSUED.
+ * tree.h (tree_decl_common): Update comment.
+ (DECL_ERROR_ISSUED): Remove.
+
+2013-08-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/58257
+ * omp-low.c (copy_var_decl): Copy over TREE_NO_WARNING flag.
+
+2013-08-28 Jan Hubicka <jh@suse.cz>
+
+ * builtins.def (free): Declare leaf.
+
+2013-08-27 David Malcolm <dmalcolm@redhat.com>
+
+ * gdbhooks.py: New.
+ * configure.ac (gdbinit.in): Add import of gcc/gdbhooks.py.
+ * configure: Regenerate.
+
+2013-08-27 Martin Jambor <mjambor@suse.cz>
+
+ * ipa-prop.h (ipa_pass_through_data): New field type_preserved.
+ (ipa_ancestor_jf_data): Likewise.
+ (ipa_get_jf_pass_through_agg_preserved): Fix comment typo.
+ (ipa_get_jf_pass_through_type_preserved): New function.
+ (ipa_get_jf_ancestor_agg_preserved): Fix comment typo.
+ (ipa_get_jf_ancestor_type_preserved): New function.
+ * ipa-cp.c (ipa_get_jf_pass_through_result): Honor type_preserved flag.
+ (ipa_get_jf_ancestor_result): Likewise.
+ (propagate_vals_accross_pass_through): Use
+ ipa_get_jf_pass_through_result to do all the value mappings.
+ * ipa-prop.c (ipa_print_node_jump_functions_for_edge): Dump the
+ type_preserved flag.
+ (ipa_set_jf_cst_copy): New function.
+ (ipa_set_jf_simple_pass_through): Set the type_preserved flag.
+ (ipa_set_jf_arith_pass_through): Likewise.
+ (ipa_set_ancestor_jf): Likewise.
+ (compute_complex_assign_jump_func): Set type_preserved instead of
+ punting.
+ (ipa_compute_jump_functions_for_edge): Likewise.
+ (combine_known_type_and_ancestor_jfs): Honor type_preserved.
+ (update_jump_functions_after_inlining): Update type_preserved.
+ Explicitely create jump functions when combining one with pass_through.
+ (ipa_write_jump_function): Stream the type_preserved flags.
+ (ipa_read_jump_function): Likewise.
+
+2013-08-27 Jakub Jelinek <jakub@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * Makefile.in (omp-low.o): Depend on $(TARGET_H).
+ * cfgloop.h (struct loop): Add safelen, force_vect, simduid.
+ * function.h (struct function): Add has_force_vect_loops and
+ has_simduid_loops.
+ * gimple-pretty-print.c (dump_gimple_omp_for): Handle GF_OMP_FOR_KIND*.
+ * gimple.c (gimple_build_omp_critical): Add KIND argument and
+ handle it.
+ * gimple.def: Update CLAUSES comments.
+ * gimple.h (enum gf_mask): Add GF_OMP_FOR_KIND_{FOR,SIMD}.
+ (gimple_build_omp_for): Add argument to prototype.
+ (gimple_omp_for_kind): New.
+ (gimple_omp_for_set_kind): New.
+ * gimplify.c (enum gimplify_omp_var_data): Add GOVD_LINEAR to
+ GOVD_DATA_SHARE_CLASS.
+ (enum omp_region_type): Add ORT_SIMD.
+ (gimple_add_tmp_var): Handle ORT_SIMD.
+ (gimplify_var_or_parm_decl): Same.
+ (is_gimple_stmt): Same.
+ (omp_firstprivatize_variable): Same.
+ (omp_add_variable): Only use splay_tree_insert if lookup failed.
+ (omp_notice_variable): Handle ORT_SIMD.
+ (omp_is_private): Add SIMD argument and handle it as well as ORT_SIMD.
+ (omp_check_private): Handle ORT_SIMD.
+ (gimplify_scan_omp_clauses): Handle OMP_CLAUSE_LINEAR and
+ OMP_CLAUSE_SAFELEN.
+ (gimplify_adjust_omp_clauses_1): Handle GOVD_LINEAR.
+ Handle OMP_CLAUSE_LASTPRIVATE.
+ (gimplify_adjust_omp_clauses): Handle OMP_CLAUSE_LINEAR and
+ OMP_CLAUSE_SAFELEN.
+ (gimplify_omp_for): Handle OMP_SIMD and OMP_CLAUSE_LINEAR.
+ (gimplify_expr): Handle OMP_SIMD.
+ * internal-fn.c (expand_GOMP_SIMD_LANE): New.
+ (expand_GOMP_SIMD_VF): New.
+ (expand_GOMP_SIMD_LAST_LANE): New.
+ * internal-fn.def (GOMP_SIMD_LANE): New.
+ (GOMP_SIMD_VF): New.
+ (GOMP_SIMD_LAST_LANE): New.
+ * omp-low.c: Include target.h.
+ (extract_omp_for_data): Handle OMP_SIMD, OMP_CLAUSE_LINEAR,
+ OMP_CLAUSE_SAFELEN.
+ (check_omp_nesting_restrictions): Same.
+ (omp_max_vf): New.
+ (lower_rec_simd_input_clauses): New.
+ (lower_rec_input_clauses): Handle OMP_SIMD, GF_OMP_FOR_KIND_SIMD,
+ OMP_CLAUSE_LINEAR.
+ (lower_lastprivate_clauses): Handle OMP_CLAUSE_LINEAR,
+ GF_OMP_FOR_KIND_SIMD, OMP_SIMD.
+ (expand_omp_build_assign): New.
+ (expand_omp_for_init_counts): New.
+ (expand_omp_for_init_vars): New.
+ (extract_omp_for_update_vars): New.
+ (expand_omp_for_generic): Use expand_omp_for_{init,update}_vars
+ and rewrite accordingly.
+ (expand_omp_simd): New.
+ (expand_omp_for): Use expand_omp_simd.
+ (lower_omp_for_lastprivate): Unshare vinit when appropriate.
+ (lower_omp_for): Do not lower the body.
+ * tree-data-ref (get_references_in_stmt): Allow IFN_GOMP_SIMD_LANE
+ in their own loops.
+ * tree-flow.h (find_omp_clause): Remove prototype.
+ * tree-if-conv.c (main_tree_if_conversion): Run if doing if conversion,
+ forcing vectorization of the loop, or if flag_tree_vectorize.
+ (gate_tree_if_conversion): Similarly.
+ * tree-inline.c (remap_gimple_stmt): Pass for kind argument to
+ gimple_build_omp_for.
+ (copy_cfg_body): set has_force_vect_loops and has_simduid_loops.
+ * tree-parloops (create_parallel_loop): Pass kind argument to
+ gimple_build_omp_for.
+ * tree-pretty-print.c (dump_omp_clause): Add cases for
+ OMP_CLAUSE_UNIFORM, OMP_CLAUSE_LINEAR, OMP_CLAUSE_SAFELEN,
+ OMP_CLAUSE__SIMDUID_.
+ (dump_generic_node): Handle OMP_SIMD.
+ * tree-ssa-ccp.c (likely_value): Handle IFN_GOMP_SIMD*.
+ * tree-ssa-loop-ivcanon.c (tree_unroll_loops_completely_1): Do not
+ unroll OMP_SIMD loops here.
+ * tree-ssa-loop.c (gate_tree_vectorize): Run if has_force_vect_loops.
+ * tree-vect-data-refs.c (vect_analyze_data_ref_dependence): Handle
+ loop->safelen.
+ (vect_analyze_data_refs): Handle simd loops.
+ * tree-vect-loop.c (vectorizable_live_operation): Handle
+ IFN_GOMP_SIMD*.
+ * tree-vect-stmts.c (vectorizable_call): Handle IFN_GOMP_SIMD_LANE.
+ (vectorizable_store): Handle STMT_VINFO_SIMD_LANE_ACCESS_P.
+ (vectorizable_load): Same.
+ * tree-vectorizer.c: Include hash-table.h and tree-ssa-propagate.h.
+ (struct simduid_to_vf): New.
+ (simduid_to_vf::hash): New.
+ (simduid_to-vf::equal): New.
+ (struct simd_array_to_simduid): New.
+ (simd_array_to_simduid::hash): New.
+ (simd_array_to_simduid::equal): New.
+ (adjust_simduid_builtins): New.
+ (struct note_simd_array_uses_struct): New.
+ (note_simd_array_uses_cb): New.
+ (note_simd_array_uses): New.
+ (vectorize_loops): Handle simd hints and adjust simd builtins
+ accordingly.
+ * tree-vectorizer.h (struct _stmt_vec_info): Add
+ simd_lane_access_p field.
+ (STMT_VINFO_SIMD_LANE_ACCESS_P): New macro.
+ * tree.c (omp_clause_num_ops): Add entries for OMP_CLAUSE_LINEAR,
+ OMP_CLAUSE_SAFELEN, OMP_CLAUSE__SIMDUID_, OMP_CLAUSE_UNIFORM.
+ (omp_clause_code_name): Same.
+ (walk_tree_1): Handle OMP_CLAUSE_UNIFORM, OMP_CLAUSE_SAFELEN,
+ OMP_CLAUSE__SIMDUID_, OMP_CLAUSE_LINEAR.
+ * tree.def (OMP_SIMD): New entry.
+ * tree.h (enum omp_clause_code): Add entries for OMP_CLAUSE_LINEAR,
+ OMP_CLAUSE_UNIFORM, OMP_CLAUSE_SAFELEN, OMP_CLAUSE__SIMDUID_.
+ (OMP_CLAUSE_DECL): Adjust range for new clauses.
+ (OMP_CLAUSE_LINEAR_NO_COPYIN): New.
+ (OMP_CLAUSE_LINEAR_NO_COPYOUT): New.
+ (OMP_CLAUSE_LINEAR_STEP): New.
+ (OMP_CLAUSE_SAFELEN_EXPR): New.
+ (OMP_CLAUSE__SIMDUID__DECL): New.
+ (find_omp_clause): New prototype.
+
+2013-08-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * config/i386/driver-i386.c (host_detect_local_cpu): Update
+ Haswell processor detection.
+
+2013-08-27 Christian Widmer <shadow@umbrox.de>
+
+ PR target/57927
+ * config/i386/driver-i386.c (host_detect_local_cpu): Add detection
+ of Ivy Bridge and Haswell processors. Assume core-avx2 for unknown
+ AVX2 capable processors.
+
+2013-08-27 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/arm_neon.h: Replace all inline asm implementations
+ of vget_low_* with implementations in terms of other intrinsics.
+
+2013-08-27 Marc Glisse <marc.glisse@inria.fr>
+
+ PR middle-end/57219
+ * doc/extend.texi (__builtin_isinf_sign): Restrict the return
+ values to -1, 0 and 1.
+
+2013-08-27 Vidya Praveen <vidyapraveen@arm.com>
+
+ * config/aarch64/aarch64.md (unspec): Add UNSPEC_SISD_SSHL,
+ UNSPEC_SISD_USHL, UNSPEC_USHL_2S, UNSPEC_SSHL_2S, UNSPEC_SISD_NEG.
+ (<optab><mode>3_insn): Remove.
+ (aarch64_ashl_sisd_or_int_<mode>3): New Pattern.
+ (aarch64_lshr_sisd_or_int_<mode>3): Likewise.
+ (aarch64_ashr_sisd_or_int_<mode>3): Likewise.
+ (define_split for aarch64_lshr_sisd_or_int_di3): Likewise.
+ (define_split for aarch64_lshr_sisd_or_int_si3): Likewise.
+ (define_split for aarch64_ashr_sisd_or_int_di3): Likewise.
+ (define_split for aarch64_ashr_sisd_or_int_si3): Likewise.
+ (aarch64_sisd_ushl, aarch64_sisd_sshl): Likewise.
+ (aarch64_ushl_2s, aarch64_sshl_2s, aarch64_sisd_neg_qi): Likewise.
+ (ror<mode>3_insn): Likewise.
+ * config/aarch64/predicates.md (aarch64_simd_register): New.
+
+2013-08-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57521
+ * tree-if-conv.c (if_convertible_bb_p): Verify that at least
+ one edge is non-critical.
+ (find_phi_replacement_condition): Make sure to use a non-critical
+ edge. Cleanup and remove old bug workarounds.
+ (bb_postdominates_preds): Remove.
+ (if_convertible_loop_p_1): Do not compute post-dominators.
+ (combine_blocks): Do not free post-dominators.
+ (main_tree_if_conversion): Likewise.
+ (pass_data_if_conversion): Add TODO_verify_ssa.
+
+2013-08-27 DJ Delorie <dj@redhat.com>
+
+ * config/i386/djgpp.h (ASM_DECLARE_FUNCTION_NAME): New.
+
+2013-08-27 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * function.c (assign_parm_find_data_types): Set passed_mode and
+ nominal_mode to the TYPE_MODE of nominal_type for the built
+ pointer type in case of the struct-pass-by-reference.
+
+2013-08-26 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/avr/avr-stdint.h (INT16_TYPE): Change default to "int".
+ (UINT16_TYPE): Change default to "unsigned int".
+
+ * config/avr/avr.opt (mfract-convert-truncate): New option.
+ * config/avr/avr.c (avr_out_fract): Unless TARGET_FRACT_CONV_TRUNC
+ is set, round negative fractional integers according to n1169
+ when converting to integer types.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_propagate_frequency): Do not assume that virtual
+ methods can not be called indirectly when their address is not taken.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * gimple-fold.c (gimple_get_virt_method_for_binfo): Use
+ ctor_for_folding.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * ipa.c (comdat_can_be_unshared_p_1): C++ constructors and destructors
+ can be unshared.
+
+2013-08-26 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * reload.c (find_valid_class): Allow classes that do not include
+ FIRST_PSEUDO_REGISTER - 1.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_redirect_edge_call_stmt_to_callee): Fix formatting;
+ fix edge count/frequency when speculation failed; fix type check
+ for the direct call.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * ipa-prop.c (ipa_print_node_params): Do not ICE during WPA.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * ipa-inline-transform.c (inline_transform): Be ready for basic block
+ to be changed by edge redirection.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_speculative_call_info): Fix parameter order and
+ formating; add sanity check.
+ (cgraph_resolve_speculation): Add FIXME about scaling profiles.
+ (cgraph_redirect_edge_call_stmt_to_callee): Fix ICE in debug dump.
+ * ipa-inline.c (heap_edge_removal_hook): Reset node growth cache.
+ (resolve_noninline_speculation): Update callee keys, too.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * tree.h (tree_decl_with_vis): Add cxx_constructor, cxx_destructor.
+ (DECL_CXX_CONSTRUCTOR_P, DECL_CXX_DESTRUCTOR_P): New macros.
+
+2013-08-26 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/i386/i386.c (x86_64_elf_select_section): Put ATTRIBUTE_UNUSED
+ into proper place.
+
+2013-08-26 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.c (ix86_debug_options): Remove prototype.
+ (x86_64_elf_select_section): Ditto.
+ (ix86_handle_tm_regparm_attribute): Remove ATTRIBUTE_UNUSED on used
+ arguments.
+ (ix86_pass_by_reference): Ditto.
+ (output_set_got): Ditto.
+ (ix86_unary_operator_ok): Ditto.
+ (ix86_expand_builtin): Ditto.
+
+2013-08-23 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_turn_edge_to_speculative): Fix debug output.
+
+2013-08-23 Jan Hubicka <jh@suse.cz>
+
+ * tree.h (TYPE_FINAL_P, DECL_FINAL_P): New macros.
+ (tree_decl_with_vis): Add FINAL field.
+
+2013-08-23 Jeff Law <law@redhat.com>
+
+ * tree-ssa-pre.c (do_regular_insertion): Include the expression in
+ the debugging dump when the expression is fully redundant.
+
+2013-08-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * diagnostic.c (diagnostic_set_caret_max_width): Use pp_buffer.
+ * gimple-pretty-print.c (gimple_dump_bb_buff): Likewise.
+ * pretty-print.c (pp_formatted_text_data): Likewise.
+ (pp_write_text_to_stream): Likewise.
+ (pp_write_text_as_dot_label_to_stream): Likewise.
+ (pp_append_r): Likewise.
+ (pp_format): Likewise.
+ (pp_flush): Likewise.
+ (pp_clear_output_area): Likewise.
+ (pp_append_text): Likewise.
+ (pp_formatted_text): Likewise.
+ (pp_remaining_character_count_for_line): Likewise.
+ (pp_newline): Likewise.
+ (pp_character): Likewise.
+ (output_buffer::~output_buffer): Define.
+ (pretty_printer::~pretty_printer): Destruct output buffer.
+ * pretty-print.h (output_buffer::~output_buffer): Declare.
+ (pretty_printer::~pretty_printer): Declare virtual.
+
+2013-08-24 Marc Glisse <marc.glisse@inria.fr>
+
+ PR other/57324
+ * hwint.h (HOST_WIDE_INT_UC, HOST_WIDE_INT_1U, HOST_WIDE_INT_M1,
+ HOST_WIDE_INT_M1U): New macros.
+ * fold-const.c (sign_bit_p, build_range_check, fold_unary_loc,
+ fold_binary_loc, fold_ternary_loc): Use the new macros. Use an
+ unsigned -1 for lshift.
+ * cse.c (cse_insn): Likewise.
+ * double-int.c (rshift_double, lshift_double): Likewise.
+ * builtins.c (fold_builtin_bitop): Likewise.
+ * combine.c (force_to_mode): Likewise.
+ * tree.c (integer_pow2p, tree_log2, tree_floor_log2): Likewise.
+ * simplify-rtx.c (simplify_const_unary_operation,
+ simplify_const_binary_operation): Likewise.
+ * tree-stdarg.c (va_list_counter_bump, va_list_ptr_read,
+ check_va_list_escapes): Likewise.
+ * rtlanal.c (nonzero_bits1): Likewise.
+ * expmed.c (expand_smod_pow2): Likewise.
+ * tree-ssa-structalias.c (UNKNOWN_OFFSET): Use HOST_WIDE_INT_MIN.
+
+2013-08-23 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_turn_edge_to_speculative): Mark target node
+ as having address taken.
+
+2013-08-23 Jan Hubicka <jh@suse.cz>
+
+ * ipa-utils.h (method_class_type): Declare.
+ * ipa-devirt.c (method_class_type): Export.
+
+ * cgraphunit.c (analyze_functions): Do basic devirtualization;
+ do not walk base classes of anonymous types.
+
+2013-08-23 Kaz Kojima <kkojima@gcc.gnu.org>
+
+ PR rtl-optimization/58220
+ PR regression/58221
+ * final.c (reemit_insn_block_notes): Use NEXT_INSN to
+ handle SEQUENCE insns properly.
+
+2013-08-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (pp_newline_and_flush): Declare. Remove macro
+ definition.
+ (pp_newline_and_indent): Likewise.
+ (pp_separate_with): Likewise.
+ * pretty-print.c (pp_newline_and_flush): Define.
+ (pp_newline_and_indent): Likewise.
+ (pp_separate_with): Likewise.
+
+2013-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/58218
+ * config/i386/x86-64.h (TARGET_SECTION_TYPE_FLAGS): Define.
+ * config/i386/i386.c (x86_64_elf_section_type_flags): New function.
+
+2013-08-23 Kirill Yukhin <kirill.yukhin@intel.com>
+
+ * gcc/config/i386/predicates.md (ext_sse_reg_operand): New.
+ * gcc/config/i386/i386.md (*movti_internal): Use
+ predicate to determine if EVEX is needed.
+ (*movsi_internal): Ditto.
+ (*movdf_internal): Ditto.
+ (*movsf_internal): Ditto.
+ * gcc/config/i386/mmx.md (*mov<mode>_internal): Ditto.
+
+2013-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58209
+ * tree-tailcall.c (process_assignment): Handle POINTER_PLUS_EXPR.
+ (find_tail_calls): Give up for pointer result types if m is non-NULL.
+ (adjust_return_value_with_ops): For PLUS_EXPR and pointer result type
+ emit POINTER_PLUS_EXPR.
+ (create_tailcall_accumulator): For pointer result type accumulate in
+ sizetype type.
+
+2013-08-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * configure.ac: Add backslashes missing from the last change.
+ * configure: Regenerate.
+
+2013-08-22 Jan Hubicka <jh@susue.cz>
+
+ * ipa.c (function_and_variable_visibility): First remember function
+ was global and then make it local.
+
+2013-08-22 Julian Brown <julian@codesourcery.com>
+
+ * configure.ac: Add aarch64 to list of arches which use "nop" in
+ debug_line test.
+ * configure: Regenerate.
+
+2013-08-22 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * config/s390/linux.h (TARGET_LIBC_HAS_FUNCTION): Define as
+ gnu_libc_has_function.
+ * config/s390/tpf.h: Likewise.
+
+2013-08-22 Jan Hubicka <jh@susue.cz>
+
+ * timevar.c (validate_phases): Add cast.
+
+2013-08-22 Jan Hubicka <jh@susue.cz>
+
+ * timevar.c (validate_phases): Use size_t for memory.
+ * timevar.h (struct timevar_time_def): Use size_t for ggc_mem.
+
+2013-08-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (output_buffer::output_buffer): Declare.
+ (pretty_printer::pretty_printer): Likewise.
+ (pp_construct): Remove.
+ * pretty-print.c (output_buffer::output_buffer): Define.
+ (pretty_printer::pretty_printer): Rename from pp_construct. Simplify.
+ * gimple-pretty-print.c (print_gimple_stmt): Do not call pp_construct.
+ (print_gimple_expr): Likewise.
+ (print_gimple_seq): Likewise.
+ (gimple_dump_bb): Likewise.
+ * sched-vis.c (dump_value_slim): Likewise.
+ (dump_insn_slim): Likewise.
+ (dump_rtl_slim): Likewise.
+ (str_pattern_slim): Likewise.
+ * tree-mudflap.c (mf_varname_tree): Likewise.
+ * graph.c (print_graph_cfg): Likewise.
+ (start_graph_dump): Likewise.
+ * tree-pretty-print.c (maybe_init_pretty_print): Likewise. Use
+ placement-new.
+ * diagnostic.c (diagnostic_initialize): Simplify early diagnostic
+ pretty printer initialization.
+ * coretypes.h (diagnostic_context): Remove superflous type alias
+ declaration.
+ (pretty_printer): Likewise. Declare directly as a class.
+ (pretty_print_info): Remove declaration as class.
+ * asan.c (asan_emit_stack_protection): Remove call to pp_construct
+ and pp_clear_output_area.
+ (asan_add_global): Likewise.
+
+2013-08-22 Jan Hubicka <jh@suse.cz>
+
+ * cgraphunit.c (analyze_functions) Use update_type_inheritance_graph.
+ * ipa-utils.h (update_type_inheritance_graph): Declare.
+ (possible_polymorphic_call_target_p): Declare.
+ (possible_polymorphic_call_target_p): New.
+ * ipa-devirt.c: Update toplevel comments.
+ (cached_polymorphic_call_targets): Move up.
+ (odr_type_d): Move ID down.
+ (polymorphic_type_binfo_p): Update comment.
+ (odr_hasher::remove): Likewise;
+ (get_odr_type): Set anonymous_namespace.
+ (dump_odr_type): Dump it.
+ (dump_type_inheritance_graph): Do not ICE when there are no ODR types.
+ (maybe_record_node): Record node in cached_polymorphic_call_targets.
+ (record_binfo): Add comment.
+ (free_polymorphic_call_targets_hash): Do not ICE when cache is not
+ built.
+ (devirt_node_removal_hook): Do not iCE when cache is freed.
+ (possible_polymorphic_call_target_p): New predicate.
+ (update_type_inheritance_graph): New function.
+
+2013-08-22 Alexander Ivchenko <alexander.ivchenko@intel.com>
+ Maxim Kuznetsov <maxim.kuznetsov@intel.com>
+ Sergey Lega <sergey.s.lega@intel.com>
+ Anna Tikhonova <anna.tikhonova@intel.com>
+ Ilya Tocar <ilya.tocar@intel.com>
+ Andrey Turetskiy <andrey.turetskiy@intel.com>
+ Ilya Verbin <ilya.verbin@intel.com>
+ Kirill Yukhin <kirill.yukhin@intel.com>
+ Michael Zolotukhin <michael.v.zolotukhin@intel.com>
+
+ * common/config/i386/i386-common.c (OPTION_MASK_ISA_AVX512F_SET): New.
+ (OPTION_MASK_ISA_AVX512CD_SET): Ditto.
+ (OPTION_MASK_ISA_AVX512PF_SET): Ditto.
+ (OPTION_MASK_ISA_AVX512ER_SET): Ditto.
+ (OPTION_MASK_ISA_AVX2_UNSET): Update.
+ (OPTION_MASK_ISA_AVX512F_UNSET): New.
+ (OPTION_MASK_ISA_AVX512CD_UNSET): Ditto.
+ (OPTION_MASK_ISA_AVX512PF_UNSET): Ditto.
+ (OPTION_MASK_ISA_AVX512ER_UNSET): Ditto.
+ (ix86_handle_option): Handle OPT_mavx512f, OPT_mavx512cd,
+ OPT_mavx512pf, OPT_mavx512er cases.
+ * config/i386/constraints.md (v): New constraint.
+ (Yi, Yj): Replace SSE_REGS with ALL_SSE_REGS.
+ * config/i386/cpuid.h (bit_AVX512F, bit_AVX512PF, bit_AVX512ER)
+ (bit_AVX512CD): New.
+ * config/i386/driver-i386.c (host_detect_local_cpu): Detect
+ AVX512F, AVX512ER, AVX512PF, AVX512CD features.
+ * config/i386/i386-c.c (ix86_target_macros_internal):
+ Conditionally define __AVX512F__, __AVX512ER__, __AVX512CD__,
+ __AVX512PF__.
+ * config/i386/i386-modes.def (VECTOR_MODES (INT, 128))
+ (VECTOR_MODES (FLOAT, 128), INT_MODE (XI, 64)): New modes.
+ * config/i386/i386.c (regclass_map, dbx_register_map)
+ (dbx64_register_map, svr4_dbx_register_map): Add new SSE registers.
+ (gate_insert_vzeroupper): Disable vzeroupper for TARGET_AVX512F.
+ (ix86_target_string): Define -mavx512f, -mavx512er, -mavx512cd,
+ -mavx512pf options.
+ (ix86_option_override_internal): Define PTA_AVX512F, PTA_AVX512ER,
+ PTA_AVX512PF, PTA_AVX512CD. Handle -mavx512f, -mavx512er, -mavx512cd,
+ -mavx512pf options. Fix formatting.
+ (ix86_conditional_register_usage): Squash EXT_REX_SSE_REGs for 32-bit
+ targets. Squash EVEX_SSE_REGS if AVX512F is disabled.
+ (ix86_valid_target_attribute_inner_p): Handle -mavx512f, -mavx512er,
+ -mavx512cd, -mavx512pf options.
+ (standard_sse_constant_opcode): Add vpternlogd for 512-bit modes.
+ (print_reg, ix86_print_operand): Handle 'g' to output 512-bit operands.
+ (ix86_preferred_output_reload_class): Replace SSE_REGS with
+ ALL_SSE_REGS.
+ (ix86_hard_regno_mode_ok): Support 512-bit registers.
+ (ix86_set_reg_reg_cost): Ditto.
+ (x86_order_regs_for_local_alloc): Ditto.
+ (MAX_VECT_LEN): Extend to 64-byte.
+ (ix86_spill_class): Replace SSE_REGS with ALL_SSE_REGS.
+ * config/i386/i386.h (TARGET_AVX512F, TARGET_AVX512PF)
+ (TARGET_AVX512ER, TARGET_AVX512CD): New.
+ (BIGGEST_ALIGNMENT): Extend to 512-bits.
+ (FIRST_PSEUDO_REGISTER, FIXED_REGISTERS): Add new registers.
+ (CALL_USED_REGISTERS, REG_ALLOC_ORDER): Likewise.
+ (VALID_AVX512F_SCALAR_MODE, VALID_AVX512F_REG_MODE): New.
+ (SSE_REG_MODE_P): Support new modes.
+ (FIRST_MMX_REG, FIRST_REX_INT_REG, FIRST_REX_SSE_REG): Add comments.
+ (FIRST_EXT_REX_SSE_REG, LAST_EXT_REX_SSE_REG): New.
+ (reg_class, REG_CLASS_NAMES): Add EVEX_SSE_REGS, ALL_SSE_REGS.
+ (SSE_CLASS_P, MAYBE_SSE_CLASS_P): Replace SSE_REGS with ALL_SSE_REGS.
+ (REG_CLASS_CONTENTS): Add new registers.
+ (SSE_REGNO_P, SSE_REGNO, HARD_REGNO_RENAME_OK): Support new registers.
+ (EXT_REX_SSE_REGNO_P): New.
+ (HI_REGISTER_NAMES): Add new registers.
+ * config/i386/i386.md: Define constants for new registers.
+ (mode): Add new 512-bit modes.
+ (prefix): Support evex prefix.
+ (isa): Support avx512f, noavx512f, fma_avx512f.
+ (ssemodesuffix): Add new 512-bit modes.
+ (movxi): New.
+ (*movxi_internal_avx512f): Ditto.
+ (*movdi_internal): Replace constraint "x" with the new constraint "v".
+ Support MODE_XI.
+ (*movsi_internal): Likewise.
+ (*movdf_internal): Likewise.
+ (*movsf_internal): Likewise.
+ (*fop_<mode>_comm_sse): Replace constraint "x" with new constraint "v".
+ (<code><mode>3): Likewise.
+ * config/i386/i386.opt (mavx512f, mavx512pf, mavx512er, mavx512cd):
+ New.
+ * config/i386/mmx.md (*mov<mode>_internal): Replace constraint "x"
+ with the new constraint "v".
+ * config/i386/sse.md (*mov<mode>_internal): Support new registers and
+ modes.
+ (<sse>_loadu<ssemodesuffix><avxsizesuffix>): Replace constraint "x"
+ with the new constraint "v".
+ (<sse2>_loaddqu<avxsizesuffix>): Likewise.
+ (<sse2>_storedqu<avxsizesuffix>): Likewise.
+ (*<plusminus_insn><mode>3): Likewise.
+ (<sse>_vm<plusminus_insn><mode>3): Likewise.
+ (*mul<mode>3): Likewise.
+ (<sse>_vmmul<mode>3): Likewise.
+ (<sse>_div<mode>3): Likewise.
+ (<sse>_vmdiv<mode>3): Likewise.
+ (<sse>_sqrt<mode>2): Likewise.
+ (<sse>_vmsqrt<mode>2): Likewise.
+ (*<code><mode>3_finite): Likewise.
+ (*<code><mode>3) <smaxmin>: Likewise.
+ (<sse>_vm<code><mode>3): Likewise.
+ (*<code><mode>3) <any_logic>: Likewise.
+ (*fma_fmadd_<mode>): Likewise.
+ (*fma_fmsub_<mode>): Likewise.
+ (*fma_fnmadd_<mode>): Likewise.
+ (*fma_fnmsub_<mode>): Likewise.
+ (*fma_fmaddsub_<mode>): Likewise.
+ (*fma_fmsubadd_<mode>): Likewise.
+ (*fmai_fmadd_<mode>): Likewise.
+ (*fmai_fmsub_<mode>): Likewise.
+ (*fmai_fnmadd_<mode>): Likewise.
+ (*fmai_fnmsub_<mode>): Likewise.
+ (sse_cvtsi2ss): Likewise.
+ (sse_cvtsi2ssq): Likewise.
+ (sse_cvtss2si): Likewise.
+ (sse_cvtss2si_2): Likewise.
+ (sse_cvtss2siq): Likewise.
+ (sse_cvtss2siq_2): Likewise.
+ (sse_cvttss2si): Likewise.
+ (sse_cvtss2siq_2): Likewise.
+ (float<sseintvecmodelower><mode>2): Likewise.
+ (sse2_cvtsd2si_2): Likewise.
+ (sse2_cvtsd2siq_2): Likewise.
+ (*<plusminus_insn><mode>3): Likewise.
+ (*<sse2_avx2>_<plusminus_insn><mode>3): Likewise.
+ (*<sse4_1_avx2>_mul<mode>3): Likewise.
+ (ashr<mode>3): Likewise.
+ (<shift_insn><mode>3): Likewise.
+ (avx2_<code><mode>3): Likewise.
+ (*avx2_<code><mode>3): Likewise.
+ (*andnot<mode>3): Likewise.
+ (*<code><mode>3) <any_logic>: Likewise.
+ (abs<mode>2): Likewise.
+ (avx2_permvar<mode>): Likewise.
+ (avx2_perm<mode>_1): Likewise.
+ (*avx_vpermilp<mode>): Likewise.
+ (avx_vpermilvar<mode>3): Likewise.
+ (avx2_ashrv<mode>): Likewise.
+ (avx2_<shift_insn>v<mode>): Likewise.
+ * doc/invoke.texi: Document -mavx512f, -mavx512pf, -mavx512er,
+ -mavx512cd.
+ * doc/rtl.texi: Document XImode.
+
+2013-08-21 Jeff Law <law@redhat.com>
+
+ * tree-flow.h (register_jump_thread): Pass vector of edges
+ instead of each important edge.
+ * tree-ssa-threadedge.c (thread_across_edge): Build the jump
+ thread path into a vector and pass that to register_jump_thread.
+ * tree-ssa-threadupdate.c (register_jump_thread): Conver the
+ passed in edge vector to the current 3-edge form.
+
+ Revert:
+ 2013-08-20 Alexey Makhalov <makhaloff@gmail.com>
+
+ * dce.c (fini_dce): Call df_analyze again just in case
+ delete_unmarked_insns removed anything.
+
+2013-08-21 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * reload.h (struct reg_equivs): Rename to ..
+ (struct reg_equivs_s): .. this.
+
+2013-08-20 Martin Liska <marxin.liska@gmail.com>
+
+ * ipa.c (ipa_profile_read_summary): Fix buffer overflow.
+
+2013-08-21 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config/sol2-10.h (TARGET_LIBC_HAS_FUNCTION): Don't nest comment.
+
+2013-08-21 Jeff Law <law@redhat.com>
+
+ * tree-vrp.c (simplify_stmt_for_jump_threading): Try to
+ simplify assignments too. If the RHS collapses to a singleton
+ range, then return the value for the range.
+
+2013-08-21 Kirill Yukhin <kirill.yukhin@intel.com>
+
+ * config/i386/sse.md (V16): Rename to...
+ (VMOVE): this.
+ (mov<mode>): Update iterator name.
+ (*mov<mode>_internal): Ditto.
+ (push<mode>1): Ditto.
+ (movmisalign<mode>): Ditto.
+
+2013-08-20 Jan Hubicka <jh@suse.cz>
+
+ PR bootstrap/58186
+ * cgraph.c (cgraph_add_edge_to_call_site_hash): Overwrite hash
+ entry for direct edges.
+ (cgraph_turn_edge_to_speculative): Fix setting of can_throw_external.
+
+2013-08-20 David Malcolm <dmalcolm@redhat.com>
+
+ Revert my last two changes, r201865 and r201864:
+
+ Revert r201865:
+ 2013-08-20 David Malcolm <dmalcolm@redhat.com>
+
+ Make opt_pass and gcc::pass_manager be GC-managed, so that pass
+ instances can own GC refs.
+
+ * Makefile.in (GTFILES): Add pass_manager.h and tree-pass.h.
+ * context.c (gcc::context::gt_ggc_mx): Traverse passes_.
+ (gcc::context::gt_pch_nx): Likewise.
+ (gcc::context::gt_pch_nx): Likewise.
+ * ggc.h (gt_ggc_mx <T>): New.
+ (gt_pch_nx_with_op <T>): New.
+ (gt_pch_nx <T>): New.
+ * passes.c (opt_pass::gt_ggc_mx): New.
+ (opt_pass::gt_pch_nx): New.
+ (opt_pass::gt_pch_nx_with_op): New.
+ (pass_manager::gt_ggc_mx): New.
+ (pass_manager::gt_pch_nx): New.
+ (pass_manager::gt_pch_nx_with_op): New.
+ (pass_manager::operator new): Use
+ ggc_internal_cleared_alloc_stat rather than xcalloc.
+ * pass_manager.h (class pass_manager): Add GTY((user)) marking.
+ (pass_manager::gt_ggc_mx): New.
+ (pass_manager::gt_pch_nx): New.
+ (pass_manager::gt_pch_nx_with_op): New.
+ * tree-pass.h (class opt_pass): Add GTY((user)) marking.
+ (opt_pass::operator new): New.
+ (opt_pass::gt_ggc_mx): New.
+ (opt_pass::gt_pch_nx): New.
+ (opt_pass::gt_pch_nx_with_op): New.
+
+ Revert r201864:
+ 2013-08-20 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (GTFILES): Add context.h.
+ * context.c (gcc::context::operator new): New.
+ (gcc::context::gt_ggc_mx): New.
+ (gcc::context::gt_pch_nx): New.
+ (gcc::context::gt_pch_nx): New.
+ * context.h (gcc::context): Add GTY((user)) marking.
+ (gcc::context::operator new): New.
+ (gcc::context::gt_ggc_mx): New.
+ (gcc::context::gt_pch_nx): New.
+ (gcc::context::gt_pch_nx): New.
+ (g): Add GTY marking.
+ (gt_ggc_mx (gcc::context *)): New.
+ (gt_pch_nx (gcc::context *)): New.
+ (gt_pch_nx (gcc::context *ctxt, gt_pointer_operator op,
+ void *cookie)): New.
+ * gengtype.c (open_base_files) <ifiles>: Add context.h.
+
+2013-08-20 Alexey Makhalov <makhaloff@gmail.com>
+
+ * dce.c (fini_dce): Call df_analyze again just in case
+ delete_unmarked_insns removed anything.
+
+2013-08-20 Teresa Johnson <tejohnson@google.com>
+
+ PR rtl-optimizations/57451
+ * final.c (reemit_insn_block_notes): Prevent lexical blocks
+ from crossing split section boundaries.
+
+2013-08-20 Matthew Gretton-Dann <matthew.gretton-dann@linaro.org>
+
+ * config/arm/linux-elf.h (MULTILIB_DEFAULTS): Remove definition.
+ * config/arm/t-linux-eabi (MULTILIB_OPTIONS): Document association
+ with MULTLIB_DEFAULTS.
+
+2013-08-20 Nick Clifton <nickc@redhat.com>
+
+ * target.def (narrow_volatile_bitfield): Note that the default
+ value is false, not !TARGET_STRICT_ALIGN.
+ * doc/tm.texi: Regenerate.
+
+2013-08-20 Pavel Chupin <pavel.v.chupin@intel.com>
+
+ Fix LIB_SPEC for systems without libpthread.
+
+ * config/gnu-user.h: Introduce GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC.
+ * config/arm/linux-eabi.h: Use GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC
+ for Android.
+ * config/i386/linux-common.h: Likewise.
+ * config/mips/linux-common.h: Likewise.
+
+2013-08-20 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
+
+ * tree-ssa-ccp.c (get_default_value): Remove redundant condition
+ checks.
+
+2013-08-20 David Malcolm <dmalcolm@redhat.com>
+
+ Make opt_pass and gcc::pass_manager be GC-managed, so that pass
+ instances can own GC refs.
+
+ * Makefile.in (GTFILES): Add pass_manager.h and tree-pass.h.
+ * context.c (gcc::context::gt_ggc_mx): Traverse passes_.
+ (gcc::context::gt_pch_nx): Likewise.
+ (gcc::context::gt_pch_nx): Likewise.
+ * ggc.h (gt_ggc_mx <T>): New.
+ (gt_pch_nx_with_op <T>): New.
+ (gt_pch_nx <T>): New.
+ * passes.c (opt_pass::gt_ggc_mx): New.
+ (opt_pass::gt_pch_nx): New.
+ (opt_pass::gt_pch_nx_with_op): New.
+ (pass_manager::gt_ggc_mx): New.
+ (pass_manager::gt_pch_nx): New.
+ (pass_manager::gt_pch_nx_with_op): New.
+ (pass_manager::operator new): Use
+ ggc_internal_cleared_alloc_stat rather than xcalloc.
+ * pass_manager.h (class pass_manager): Add GTY((user)) marking.
+ (pass_manager::gt_ggc_mx): New.
+ (pass_manager::gt_pch_nx): New.
+ (pass_manager::gt_pch_nx_with_op): New.
+ * tree-pass.h (class opt_pass): Add GTY((user)) marking.
+ (opt_pass::operator new): New.
+ (opt_pass::gt_ggc_mx): New.
+ (opt_pass::gt_pch_nx): New.
+ (opt_pass::gt_pch_nx_with_op): New.
+
+2013-08-20 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (GTFILES): Add context.h.
+ * context.c (gcc::context::operator new): New.
+ (gcc::context::gt_ggc_mx): New.
+ (gcc::context::gt_pch_nx): New.
+ (gcc::context::gt_pch_nx): New.
+ * context.h (gcc::context): Add GTY((user)) marking.
+ (gcc::context::operator new): New.
+ (gcc::context::gt_ggc_mx): New.
+ (gcc::context::gt_pch_nx): New.
+ (gcc::context::gt_pch_nx): New.
+ (g): Add GTY marking.
+ (gt_ggc_mx (gcc::context *)): New.
+ (gt_pch_nx (gcc::context *)): New.
+ (gt_pch_nx (gcc::context *ctxt, gt_pointer_operator op,
+ void *cookie)): New.
+ * gengtype.c (open_base_files) <ifiles>: Add context.h.
+
+2013-08-20 Alan Modra <amodra@gmail.com>
+
+ PR target/57865
+ * config/rs6000/rs6000.c (rs6000_emit_prologue): Correct ool_adjust.
+ (rs6000_emit_epilogue): Likewise.
+
+2013-08-19 Dehao Chen <dehao@google.com>
+
+ * value-prof.c (gimple_ic): Fix the bug of adding EH edge.
+
+2013-08-19 Peter Bergner <bergner@vnet.ibm.com>
+ Jakub Jelinek <jakub@redhat.com>
+
+ * builtins.def (BUILT_IN_FABSD32): New DFP ABS builtin.
+ (BUILT_IN_FABSD64): Likewise.
+ (BUILT_IN_FABSD128): Likewise.
+ * builtins.c (expand_builtin): Add support for new DFP ABS builtins.
+ (fold_builtin_1): Likewise.
+ * config/rs6000/dfp.md (*negtd2_fpr): Handle non-overlapping
+ destination and source operands.
+ (*abstd2_fpr): Likewise.
+ (*nabstd2_fpr): Likewise.
+
+2013-08-19 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips.c (mips_adjust_insn_length): Add checks for
+ JUMP_P and INSN_P.
+
+2013-08-19 Aldy Hernandez <aldyh@redhat.com>
+
+ * doc/invoke.texi (-fcilkplus): Clarify that implementation is
+ incomplete.
+
+2013-08-19 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ * target.def (TARGET_LIBC_HAS_FUNCTION): New target hook.
+ * builtins.c (default_libc_has_function): New.
+ (gnu_libc_has_function): Ditto.
+ (no_c99_libc_has_function): Ditto.
+ (expand_builtin_cexpi): Using new target hook TARGET_LIBC_HAS_FUNCTION
+ instead of TARGET_HAS_SINCOS and TARGET_C99_FUNCTIONS.
+ (fold_builtin_sincos): Likewise.
+ (fold_builtin_cexp): Likewise.
+ * builtins.def (DEF_C94_BUILTIN): Likewise.
+ (DEF_C99_BUILTIN): Likewise.
+ (DEF_C99_C90RES_BUILTIN): Likewise.
+ (DEF_C99_COMPL_BUILTIN): New define. Change all complex c99 builtin
+ definitions to using this define.
+ * config/darwin-protos.h (darwin_libc_has_function): New.
+ * config/darwin.c (darwin_libc_has_function): Ditto.
+ * config/alpha/linux.h: Remove TARGET_C99_FUNCTIONS and
+ TARGET_HAS_SINCOS. Redefine TARGET_LIBC_HAS_FUNCTION.
+ * config/darwin.h: Ditto.
+ * config/elfos.h: Ditto.
+ * config/freebsd.h: Ditto.
+ * config/i386/cygming.h: Ditto.
+ * config/i386/djgpp.h: Ditto.
+ * config/i386/i386-interix.h: Ditto.
+ * config/microblaze/microblaze.h: Ditto.
+ * config/mmix/mmix.h: Ditto.
+ * config/gnu-user.h: Ditto.
+ * config/ia64/hpux.h: Ditto.
+ * config/pa/pa-hpux.h: Ditto.
+ * config/pdp11/pdp11.h: Ditto.
+ * config/picochip/picochip.h: Ditto.
+ * config/linux.h: Ditto.
+ * config/netbsd.h: Ditto.
+ * config/openbsd.h: Ditto.
+ * config/rs6000/aix43.h: Ditto.
+ * config/rs6000/aix51.h: Ditto.
+ * config/rs6000/aix52.h: Ditto.
+ * config/rs6000/aix53.h: Ditto.
+ * config/rs6000/aix61.h: Ditto.
+ * config/rs6000/darwin.h: Ditto.
+ * config/rs6000/linux.h: Ditto.
+ * config/rs6000/linux64.h: Ditto.
+ * config/s390/tpf.h: Ditto.
+ * config/sol2-10.h: Ditto.
+ * config/sol2.h: Ditto.
+ * config/vms/vms.h: Ditto.
+ * config/vxworks.h: Ditto.
+ * config/linux-android.c (linux_android_libc_has_function):
+ New linux-specific implementation of TARGET_LIBC_HAS_FUNCTION.
+ * config/linux-protos.h (linux_android_libc_has_function):
+ New declaration.
+ * config/i386/i386.c (ix86_libc_has_function): New.
+ * config/i386/i386-protos.h
+ (ix86_libc_has_function): New declaration.
+ * config/i386/i386.md
+ ("isinfxf2"): Change condition for TARGET_LIBC_HAS_FUNCTION.
+ ("isinf<mode>2): Likewise.
+ * convert.c (convert_to_integer): Using new target hook
+ TARGET_LIBC_HAS_FUNCTION istead of TARGET_HAS_SINCOS and
+ TARGET_C99_FUNCTIONS.
+ * fortran/f95-lang.c (gfc_init_builtin_functions): Ditto.
+ * tree-ssa-math-opts.c (execute_cse_sincos): Ditto.
+ * coretypes.h (function_class): New enum for different
+ classes of functions.
+ * defaults.h: Remove TARGET_C99_FUNCTIONS and TARGET_HAS_SINCOS.
+ * doc/tm.texi.in (TARGET_C99_FUNCTIONS): Remove documentation.
+ (TARGET_HAS_SINCOS): Likewise.
+ (TARGET_LIBC_HAS_FUNCTION): New.
+ * doc/tm.texi: Regenerated.
+ * targhooks.h (default_libc_has_function): New declaration.
+ (no_c99_libc_has_function): Ditto.
+ (gnu_libc_has_function): Ditto.
+ * system.h: Add the poisoning of TARGET_C99_FUNCTIONS
+ and TARGET_HAS_SINCOS.
+
+2013-08-18 Jan Hubicka <jh@suse.cz>
+
+ * Makeifle-in (ipa-devirt.o): New.
+ (GTFILES): Add ipa-utils.h and ipa-devirt.c
+ * cgraphunit.c (decide_is_symbol_needed): Do not care about virtuals.
+ (analyze_functions): Look into possible targets of polymorphic call.
+ * dumpfile.c (dump_files): Add type-inheritance dump.
+ * dumpfile.h (TDI_inheritance): New.
+ * ipa-devirt.c: New file.
+ * ipa-utils.h (odr_type_d): Forward declare.
+ (odr_type): New type.
+ (build_type_inheritance_graph): Declare.
+ (possible_polymorphic_call_targets): Declare and introduce inline
+ variant when only edge is pased.
+ (dump_possible_polymorphic_call_targets): Likewise.
+ * timevar.def (TV_IPA_INHERITANCE, TV_IPA_VIRTUAL_CALL): New.
+ * tree.c (type_in_anonymous_namespace_p): Break out from ...
+ (types_same_for_odr): ... here.
+ * tree.h (type_in_anonymous_namespace_p): Declare.
+
+2013-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58006
+ * tree-parloops.c (take_address_of): Don't ICE if get_name
+ returns NULL.
+ (eliminate_local_variables_stmt): Remove clobber stmts.
+
+2013-08-18 Eric Botcazou <ebotcazou@adacore.com>
+
+ * cgraphunit.c (handle_alias_pairs): Reset the alias flag after the
+ error message is issued for an alias to undefined symbol.
+
+2013-08-18 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_create_indirect_edge): Discover
+ polymorphic calls and record basic info into indirect_info.
+ * gimple-fold.c (gimple_fold_call): When doing BINFO based
+ devirtualization, ignore objc function calls.
+ * ipa-cp.c (initialize_node_lattices): Be ready for polymorphic
+ call with no parm index info.
+ * ipa-prop.c (ipa_analyze_call_uses): Likewise.
+ * tree.c (virtual_method_call_p): New function.
+ * tree.h (virtual_method_call_p): Declare.
+
+2013-08-16 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/58179
+ * tree.c (obj_type_ref_class): Do not ICE on non-method calls.
+
+2013-08-16 David Edelsohn <dje.gcc@gmail.com>
+
+ * config/rs6000/rs6000.md (rs6000_get_timebase_ppc32): Add length
+ attribute.
+
+2013-08-16 David Malcolm <dmalcolm@redhat.com>
+
+ * gengtype.c (type_for_name): Add special-case support for
+ locating types within the "gcc::" namespace.
+ (open_base_files): Emit a "using namespace gcc" directive.
+
+2013-08-16 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ PR target/58160
+ * config/rs6000/predicates.md (fusion_gpr_mem_load): Allow the
+ memory rtx to contain ZERO_EXTEND and SIGN_EXTEND.
+
+ * config/rs6000/rs6000-protos.h (fusion_gpr_load_p): Pass operands
+ array instead of each individual operand as a separate argument.
+ (emit_fusion_gpr_load): Likewise.
+ (expand_fusion_gpr_load): Add new function declaration.
+
+ * config/rs6000/rs6000.c (fusion_gpr_load_p): Change the calling
+ signature to have the operands passed as an array, instead of as
+ separate arguments. Allow ZERO_EXTEND to be in the memory
+ address, and also SIGN_EXTEND if -mpower8-fusion-sign. Do not
+ depend on the register live/dead flags when peepholes are run.
+ (expand_fusion_gpr_load): New function to be called from the
+ peephole2 pass, to change the register that addis sets to be the
+ target register.
+ (emit_fusion_gpr_load): Change the calling signature to have the
+ operands passed as an array, instead of as separate arguments.
+ Allow ZERO_EXTEND to be in the memory address, and also
+ SIGN_EXTEND if -mpower8-fusion-sign.
+
+ * config/rs6000/rs6000.md (UNSPEC_FUSION_GPR): Delete unused
+ unspec enumeration.
+ (power8 fusion peephole/peephole2): Rework the fusion peepholes to
+ adjust the register addis loads up in the peephole2 pass. Do not
+ depend on the register live/dead state when the peephole pass is done.
+
+2013-08-16 David Malcolm <dmalcolm@redhat.com>
+
+ * gengtype.c (create_user_defined_type): Ensure that the kind
+ is set to TYPE_USER_STRUCT, fixing a bug seen when an incomplete
+ declaration is seen before the GTY((user)) marking.
+
+2013-08-16 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR target/58105
+ * config/i386/i386.c (make_resolver_func): Set DECL_UNINLINABLE.
+
+2013-08-16 Jan Hubicka <jh@suse.cz>
+
+ * gimple-fold.c (gimple_extract_devirt_binfo_from_cst): Add new
+ arugment expected_type.
+ (gimple_fold_call): Use it.
+ * gimple.h (gimple_extract_devirt_binfo_from_cst): Update prototype.
+ * ipa-cp.c (ipa_get_indirect_edge_target_1): Update.
+ * ipa-prop.c (ipa_analyze_virtual_call_uses): Use obj_type_ref_class.
+ (try_make_edge_direct_virtual_call): Likewise.
+ * tree.c (obj_type_ref_class): New.
+ * tree.h (obj_type_ref_class): Use it.
+
+2013-08-16 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * sched-vis.c (rtl_slim_pp_initialized): Remove.
+ (rtl_slim_pp): Likewise.
+ (init_rtl_slim_pretty_print): Likewise.
+ (dump_value_slim): Don't call it. Use local pretty printer.
+ (dump_insn_slim): Likewise.
+ (dump_rtl_slim): Likewise.
+ (str_pattern_slim): Likewise.
+ * tree-mudflap.c (mf_varname_tree): Use local pretty printer.
+ Simplify.
+
+2013-08-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58164
+ * gimple.c (walk_stmt_load_store_addr_ops): For visit_addr
+ walk gimple_goto_dest of GIMPLE_GOTO.
+
+ PR tree-optimization/58165
+ * tree-call-cdce.c (shrink_wrap_one_built_in_call): If
+ bi_call must be the last stmt in a bb, don't split_block, instead
+ use fallthru edge from it and give up if there is none.
+ Release conds vector when returning early.
+
+2013-08-14 Xinliang David Li <davidxl@google.com>
+
+ * config/i386/i386.c (ix86_option_override_internal):
+ Remove unused variable and field.
+
+2013-08-14 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR target/57949
+ * doc/invoke.texi: Add documentation of mcompat-align-parm option.
+ * config/rs6000/rs6000.opt: Add mcompat-align-parm option.
+ * config/rs6000/rs6000.c (rs6000_function_arg_boundary): For AIX
+ and Linux, correct BLKmode alignment when 128-bit alignment is
+ required and compatibility flag is not set.
+ (rs6000_gimplify_va_arg): For AIX and Linux, honor specified alignment
+ for zero-size arguments when compatibility flag is not set.
+
+2013-08-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58145
+ * tree-sra.c (build_ref_for_offset): If prev_base has
+ TREE_THIS_VOLATILE or TREE_SIDE_EFFECTS, propagate it to MEM_REF.
+
+2013-08-14 Xinliang David Li <davidxl@google.com>
+
+ * config/i386/i386.c (ix86_option_override_internal):
+ Fix uninitialized variable error.
+
+2013-08-14 Xinliang David Li <davidxl@google.com>
+
+ * config/i386/i386.opt: Define two new options.
+ * config/i386/x86-tune.def: Add arch selector field in macros.
+ * config/i386/i386.h: Adjust macro definition.
+ * config/i386/i386.c (ix86_option_override_internal):
+ Refactor the code.
+ (parse_mtune_ctrl_str): New function.
+ (set_ix86_tune_features): New function.
+ (ix86_function_specific_restore): Call the new helper function.
+
+2013-08-14 Andrey Belevantsev <abel@ispras.ru>
+
+ PR rtl-optimization/57662
+ * sel-sched.c (code_motion_process_successors): When the current insn
+ is removed after the recursive traversal, break from the loop.
+ Add comments and debug printouts.
+
+2013-08-14 Jakub Jelinek <jakub@redhat.com>
+ Alexandre Oliva <aoliva@redhat.com>
+
+ PR target/58067
+ * config/i386/i386.c (ix86_delegitimize_address): For CM_MEDIUM_PIC
+ and CM_LARGE_PIC ix86_cmodel fall thru into the -m32 code, handle
+ there also UNSPEC_PLTOFF.
+
+2013-08-14 Marek Polacek <polacek@redhat.com>
+
+ * ipa-inline-analysis.c (add_clause): Avoid shifting integer
+ NUM_CONDITIONS bit positions.
+
+2013-08-13 Cary Coutant <ccoutant@google.com>
+
+ * dwarf2out.c (CHECKSUM_BLOCK): New macro.
+ (attr_checksum): Hash vector contents instead of pointer.
+ (attr_checksum_ordered): Likewise.
+
+2013-08-13 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/sse.md (*sse2_maskmovdqu): Emit addr32 prefix
+ when Pmode != word_mode. Add length_address attribute.
+ (sse3_monitor_<mode>): Merge from sse3_monitor and
+ sse3_monitor64_<mode> insn patterns. Emit addr32 prefix when
+ Pmode != word_mode. Update insn length attribute.
+ * config/i386/i386.c (ix86_option_override_internal): Update
+ ix86_gen_monitor selection for merged sse3_monitor insn.
+
+2013-08-13 Julian Brown <julian@codesourcery.com>
+
+ * config/rs6000/rs6000.c (rs6000_legitimize_reload_address): Don't
+ perform invalid legitimization on greater-than-word-size modes for
+ TARGET_E500_DOUBLE.
+
+2013-08-13 Vladimir Makarov <vmakarov@redhat.com>
+
+ * ira.c (setup_class_translate_array): Use aclass instead of cl
+ for classes not fully covered by allocno classes.
+
+2013-08-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/57661
+ * tree-inline.h (struct copy_body_data): Add blocks_to_copy field.
+ * tree-inline.c (tree_function_versioning): Initialize it.
+ (remap_gimple_stmt): Return GIMPLE_NOP for MEM_REF lhs clobber stmts
+ if id->blocks_to_copy and MEM_REF's SSA_NAME is defined in a block
+ that is not being copied.
+
+ PR sanitizer/56417
+ * asan.c (instrument_strlen_call): Fix typo in comment.
+ Use char * type even for the lhs of POINTER_PLUS_EXPR.
+
+2013-08-13 Steve Ellcey <sellcey@mips.com>
+
+ * config/mips/mips.md (prefetch): Use lw instead of ld on
+ loongson in 32bit mode.
+
+2013-08-13 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc: (avr-linux): Allow for tmake_file not being empty.
+
+2013-08-13 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_turn_edge_to_speculative): Return newly
+ introduced edge; fix typo in sanity check.
+ (cgraph_resolve_speculation): Export; improve diagnostic.
+ (cgraph_redirect_edge_call_stmt_to_callee): Better diagnostic; cancel
+ speculation at type mismatch.
+ * cgraph.h (cgraph_turn_edge_to_speculative): Update.
+ (cgraph_resolve_speculation): Declare.
+ (symtab_can_be_discarded): New function.
+ * value-prof.c (gimple_ic_transform): Remove actual transform code.
+ * ipa-inline-transform.c (speculation_removed): New global var.
+ (clone_inlined_nodes): See if speculation can be removed.
+ (inline_call): If speculations was removed, we growths may not match.
+ * ipa-inline.c (can_inline_edge_p): Add DISREGARD_LIMITS parameter.
+ (speculation_useful_p): New function.
+ (resolve_noninline_speculation): New function.
+ (inline_small_functions): Resolve useless speculations.
+ * ipa-inline.h (speculation_useful_p): Declare
+ * ipa.c (can_replace_by_local_alias): Simplify.
+ (ipa_profile): Produce speculative calls in non-lto, too;
+ add simple cost model; produce local aliases.
+
+2013-08-13 David Malcolm <dmalcolm@redhat.com>
+
+ * config/i386/t-i386 (i386.o): Rename stray PIPELINE_H to
+ PASS_MANAGER_H.
+
+2013-08-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * config/i386/i386.c (ix86_function_versions): Use error + inform.
+
+2013-08-12 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (floatunssi<mode>2 expand): Use MODEF mode
+ iterator instead of X87MODEF.
+
+2013-08-12 Perez Read <netfirewall@gmail.com>
+
+ PR target/58132
+ * config/i386/i386.md (*movabs<mode>_1): Add <ptrsize> PTR before
+ operand 0 for intel asm alternative.
+ (*movabs<mode>_2): Ditto for operand 1.
+
+2013-08-12 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/arm_none.h
+ (vdup<bhsd>_lane_<su><8,16,32,64>): Fix macro call.
+
+2013-08-12 Nick Clifton <nickc@redhat.com>
+
+ * config.gcc (m32r-linux): Allow for tmake_file not being empty.
+
+2013-08-12 Yuri Rumyantsev <ysrumyan@gmail.com>
+
+ * config/i386/i386.md (floatunssi<mode>2 expand): Add new
+ expand for QI/HImode operand to produce more effictive code for
+ unsigned char(short) --> float(double) conversion.
+
+2013-08-12 Alexander Monakov <amonakov@ispras.ru>
+
+ * doc/invoke.texi: Mention that -ftls-model does not force the final
+ model.
+
+2013-08-12 Marek Polacek <polacek@redhat.com>
+ Marc Glisse <marc.glisse@inria.fr>
+
+ PR tree-optimization/57980
+ * tree-tailcall.c (process_assignment): Call build_minus_one_cst
+ when creating -1 constant.
+
+2013-08-10 Jan Hubicka <jh@suse.cz>
+
+ Workaround binutils PR14342.
+ * tree-profile.c (init_ic_make_global_vars): Add LTO path.
+ (gimple_init_edge_profiler): Likewise.
+ (gimple_gen_ic_func_profiler): Likewise.
+
+2013-08-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_create_edge_1): Clear speculative flag.
+
+2013-08-09 Xinliang David Li <davidxl@google.com>
+
+ * config/i386/stringop.def: New file.
+ * config/i386/stringop.opt: New file.
+ * config/i386/i386-opts.h: Include stringopt.def.
+ * config/i386/i386.opt: Include stringopt.opt.
+ * config/i386/i386.c (ix86_option_override_internal):
+ Override default size based stringop inline strategies with options.
+ * config/i386/i386.c (ix86_parse_stringop_strategy_string):
+ New function.
+
+2013-08-09 Jan Hubicka <jh@suse.cz>
+
+ * ipa-ref.c (ipa_clear_stmts_in_references): Clear lto_stmt_uid, too.
+
+2013-08-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_resolve_speculation): Cut frequency to
+ CGRAPH_FREQ_MAX.
+ (dump_cgraph_node): Dump profile-id.
+ * cgraph.h (cgraph_indirect_call_info): Add common_target_id
+ and common_target_probability.
+ * lto-cgraph.c (lto_output_edge): Stream common targets.
+ (lto_output_node): Stream profile ids.
+ (input_node): Stream profile ids.
+ (input_edge): Stream common targets.
+ * lto-streamer-in.c (fixup_call_stmt_edges_1): Fix formatting.
+ * ipa.c: Include value-prof.h
+ (ipa_profile_generate_summary): Turn indirect call statement histograms
+ into common targets.
+ (ipa_profile): Turn common targets into speculative edges.
+
+2013-08-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (cgraph_node): Add profile_id.
+ * value-prof.c (cgraph_node_map): Turn into pointer_map.
+ (init_node_map): Rewrite to handle hashes increas of incremental IDs.
+ (del_node_map): Update.
+ (find_func_by_funcdef_no): Replace by ...
+ (find_func_by_profile_id): ... this one.
+ (gimple_ic_transform): Do not remove useful histograms when
+ speculation is not done; dump info when indirect call removal
+ can happen at LTO.
+ * value-prof.h (find_func_by_profile_id, gimple_ic): Declare.
+ * gcov-io.h (__gcov_indirect_call_profiler): Replace by ...
+ (__gcov_indirect_call_profiler_v2): .. this one.
+ * profile.h (init_node_map): Update.
+ * coverage.c (coverage_compute_profile_id): New function.
+ * coverage.h (coverage_compute_profile_id): Declare.
+ * tree-profile.c (init_ic_make_global_vars): Make
+ __gcov_indirect_call_callee and __gcov_indirect_call_counters global.
+ (gimple_init_edge_profiler): Update prototype of
+ __gcov_indirect_call_profiler.
+ (gimple_gen_ic_func_profiler): Simplify.
+ (tree_profiling): Use init_node_map
+
+2013-08-09 Jan Hubicka <jh@suse.cz>
+
+ * cgraphbuild.c (cgraph_rebuild_references): Rebuild only
+ non-speculative refs.
+ * cgraph.c (cgraph_update_edge_in_call_site_hash): New function.
+ (cgraph_add_edge_to_call_site_hash): Deal with speculative calls.
+ (cgraph_set_call_stmt): Likewise.
+ (cgraph_create_edge_1): Fix release checking compilatoin;
+ clear lto_stmt_uid.
+ (cgraph_free_edge): Free indirect info.
+ (cgraph_turn_edge_to_speculative): New function.
+ (cgraph_speculative_call_info): New function.
+ (cgraph_make_edge_direct): Return direct edge; handle speculation.
+ (cgraph_redirect_edge_call_stmt_to_callee): Expand speculative edges.
+ (dump_cgraph_node): Dump speculation.
+ (verify_edge_count_and_frequency): Accept speculative edges.
+ (verify_edge_corresponds_to_fndecl): Handle partitioned cgraph.
+ (verify_cgraph_node): Handle speculation.
+ * cgraph.h (cgraph_edge): Add SPECULATIVE flag.
+ (cgraph_set_call_stmt): Update prototype.
+ (cgraph_make_edge_direct): Update prototype.
+ (cgraph_speculative_call_info): Declare.
+ * ipa-cp.c (ipcp_discover_new_direct_edges): Be ready for edge
+ to change; update call of ipa_find_references.
+ * ipa-ref.c (ipa_record_reference): Fix return value; clear
+ lto_stmt_uid and speculative flags.
+ (ipa_dump_references): Dump speculation.
+ (ipa_clone_references): Clone speculative flag.
+ (ipa_clone_referring): Likewise.
+ (ipa_clone_ref): New function.
+ (ipa_find_reference): Look into lto_stmt_uids
+ (ipa_clear_stmts_in_references): Do not clear speculative calls.
+ * ipa-ref.h (ipa_ref): Add lto_stmt_uid and speculative flags.
+ (ipa_find_reference): Update declaration.
+ (ipa_clone_ref): Declare.
+ * lto-cgraph.c (lto_output_edge): Make lto_stmt_uids start from 0;
+ stream speculative flag.
+ (lto_output_ref): Stream statements uids and speculation.
+ (input_ref): Likewise.
+ (input_edge): Stream speuclation.
+ * cgraphclones.c (cgraph_clone_edge): Clone speculation.
+ (cgraph_set_call_stmt_including_clones): Handle speculation.
+ * ipa-inline.c (heap_edge_removal_hook): New function.
+ (inline_small_functions): Register it.
+ * lto-streamer-in.c (fixup_call_stmt_edges_1): Bounds checking;
+ also initialize refs.
+ * ipa-prop.c (ipa_make_edge_direct_to_target): Be ready for
+ edge to change.
+ (try_make_edge_direct_simple_call): Likewise.
+ (try_make_edge_direct_simple_call): Likewise.
+ (update_indirect_edges_after_inlining): Likewise.
+ (remove_described_reference): Look proper lto_stmt_uid.
+ (propagate_controlled_uses): Likewise.
+ (propagate_controlled_uses): Liekwise.
+ * tree-inline.c (copy_bb): Copy speculative edges.
+ (redirect_all_calls): New function.
+ (copy_cfg_body): Do redirection after loop info is updated.
+ (delete_unreachable_blocks_update_callgraph): Updadte speculation.
+
+2013-08-09 Jan Hubicka <jh@suse.cz>
+
+ * lto-streamer-out.c (output_function): Renumber PHIs.
+ * lto-streamer-in.c (input_function): Likewise.
+
+2013-08-09 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * config/aarch64/aarch64-simd-builtins.def (get_lane_signed): Remove.
+ (get_lane_unsigned): Likewise.
+ (dup_lane_scalar): Likewise.
+ (get_lane): enable for VALL.
+ * config/aarch64/aarch64-simd.md
+ (aarch64_dup_lane_scalar<mode>): Remove.
+ (aarch64_get_lane_signed<mode>): Likewise.
+ (aarch64_get_lane_unsigned<mode>): Likewise.
+ (aarch64_get_lane_extend<GPI:mode><VDQQH:mode>): New.
+ (aarch64_get_lane_zero_extendsi<mode>): Likewise.
+ (aarch64_get_lane<mode>): Enable for all vector modes.
+ (aarch64_get_lanedi): Remove misleading constraints.
+ * config/aarch64/arm_neon.h
+ (__aarch64_vget_lane_any): Define.
+ (__aarch64_vget<q>_lane_<fpsu><8,16,32,64>): Likewise.
+ (vget<q>_lane_<fpsu><8,16,32,64>): Use __aarch64_vget_lane macros.
+ (vdup<bhsd>_lane_<su><8,16,32,64>): Likewise.
+ * config/aarch64/iterators.md (VDQQH): New.
+ (VDQQHS): Likewise.
+ (vwcore): Likewise.
+
+2013-08-09 Eric Botcazou <ebotcazou@adacore.com>
+
+ * configure.ac: Add GAS check for LEON instructions on SPARC.
+ * configure: Regenerate.
+ * config.in: Likewise.
+ * config.gcc (with_cpu): Remove sparc-leon*-* and deal with LEON in the
+ sparc*-*-* block.
+ * config/sparc/sparc.opt (LEON, LEON3): New masks.
+ * config/sparc/sparc.h (ASM_CPU32_DEFAULT_SPEC): Set to AS_LEON_FLAG
+ for LEON or LEON3.
+ (ASM_CPU_SPEC): Pass AS_LEON_FLAG if -mcpu=leon or -mcpu=leon3.
+ (AS_LEON_FLAG): New macro.
+ * config/sparc/sparc.c (sparc_option_override): Set MASK_LEON for leon
+ and MASK_LEON3 for leon3 and unset them if HAVE_AS_LEON is not defined.
+ Deal with LEON and LEON3 for the memory model.
+ * config/sparc/sync.md (atomic_compare_and_swap<mode>): Enable if LEON3
+ (atomic_compare_and_swap<mode>_1): Likewise.
+ (*atomic_compare_and_swap<mode>_1): Likewise.
+
+2013-08-09 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ * config/arm/neon.md (vcond): Fix floating-point vector
+ comparisons against 0.
+
+2013-08-08 Vladimir Makarov <vmakarov@redhat.com>
+
+ * lra-constraints.c (emit_spill_move): Remove assert.
+ (process_alt_operands): Add more debugging
+ output. Increase reject for spilling into memory. Decrease
+ reject for reloading scratch.
+ (split_reg): Use HARD_REGNO_CALLER_SAVE_MODE.
+
+2013-08-08 Steve Ellcey <sellcey@mips.com>
+
+ * config/mips/mti-linux.h (SYSROOT_SUFFIX_SPEC): Add nan2008.
+ * config/mips/t-mti-elf (MULTILIB_OPTIONS): Make mips16 and
+ micromips incompatible. Add nan2008.
+ (MULTILIB_DIRNAMES): Add nan2008.
+ (MULTILIB_EXCEPTIONS): Remove mips16/micromips entry.
+ * config/mips/t-mti-linux (MULTILIB_OPTIONS): Make mips16
+ and micromips incompatible. Add nan2008.
+ (MULTILIB_DIRNAMES): Add nan2008.
+ (MULTILIB_EXCEPTIONS): Remove mips16/micromips entry.
+
+2013-08-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ PR rtl-optimization/58079
+ * combine.c (combine_simplify_rtx): Avoid using SUBST if
+ simplify_comparison has widened a comparison with an integer.
+
+2013-08-08 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/neon.md (movmisalign<mode>): Disable when we
+ don't allow unaligned accesses.
+ (*movmisalign<mode>_neon_store): Likewise.
+ (*movmisalign<mode>_neon_load): Likewise.
+ (*movmisalign<mode>_neon_store): Likewise.
+ (*movmisalign<mode>_neon_load): Likewise.
+
+2013-08-08 Jan Hubicka <jh@suse.cz>
+
+ * cgraphbuild.c (build_cgraph_edges): Do not walk into debugs.
+ (make_pass_rebuild_cgraph_edges): Also clear references.
+ * cgraph.c (verify_cgraph_node): Add basic ipa-ref verifier.
+ * ipa-inline-transform.c (inline_transform): Remove all references
+ after inlining.
+ * cgraphunit.c (expand_function): Remove all references after
+ expansion.
+ * ipa-ref.c (ipa_ref_has_aliases_p): Fix formatting.
+ (ipa_find_reference): Rewrite to iterator.
+ (remove_stmt_references): Likewise.
+ (ipa_clear_stmts_in_references): New function.
+ * ipa-ref.h (ipa_clear_stmts_in_references): Declare.
+ * cgraphclones.c (cgraph_materialize_all_clones): Remove or
+ clear references.
+ * ipa-split.c (split_function): Remove references in split function.
+
+2013-08-08 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/57431
+ * config/arm/arm/neon.md (neon_vld1_dupdi): New expand pattern.
+ (neon_vld1_dup<mode> VD iterator): Iterate over VD not VDX.
+
+2013-08-08 Richard Earnshaw <rearnsha@arm.com>
+
+ PR target/56979
+ * config/arm/arm.c (aapcs_vfp_allocate): Decompose the argument if the
+ suggested mode for the assignment isn't compatible with the
+ registers required.
+
+2013-08-08 Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ PR target/58065
+ * config/arm/arm.h (MALLOC_ABI_ALIGNMENT): Define.
+
+2013-08-07 Xinliang David Li <davidxl@google.com>
+
+ * config/i386/i386.opt: New option -mtune-ctrl=.
+ * config/i386/x86-tune.def: New file.
+ * config/i386/i386.h: include x86-tune.def.
+ * config/i386/i386.c (ix86_option_override_internal):
+ Parsing -mtune-ctrl= option and set tune features.
+
+2013-08-07 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR other/12081
+ * config/rs6000/rs6000.c (gen_2arg_fn_t): Remove typedef.
+ (rs6000_emit_swdiv, rs6000_emit_swrsqrt): Don't cast result of GEN_FCN
+ to gen_2arg_fn_t.
+
+2013-08-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * rtl.h (update_alignments): Declare.
+ * final.c (grow_label_align): New function extracted from...
+ (shorten_branches): ...here. Call it.
+ (update_alignments): New function.
+ * reorg.c (sibling_labels): New variable.
+ (get_label_before): Add SIBLING parameter. If it is non-zero, push
+ the new label along with it onto the sibling_labels vector.
+ (fill_simple_delay_slots): Adjust call to get_label_before.
+ (fill_slots_from_thread): Likewise.
+ (relax_delay_slots): Likewise.
+ (make_return_insns): Likewise.
+ (dbr_schedule): Invoke update_alignment on the sibling_labels vector.
+
+2013-08-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * diagnostic.c (diagnostic_classify_diagnostic): Accept zero index and
+ document its semantics.
+ (diagnostic_report_diagnostic): Adjust accordingly.
+
+2013-08-07 David Malcolm <dmalcolm@redhat.com>
+
+ * config/sparc/sparc.c (insert_pass_work_around_errata): Move into...
+ (sparc_option_override): ...and port to new C++ pass API.
+ * config/sparc/t-sparc (sparc.o): Add dep on CONTEXT_H
+
+2013-08-07 Peter Bergner <bergner@vnet.ibm.com>
+
+ * config/rs6000/rs6000.c (htm_expand_builtin) <case 0>: Remove.
+
+2013-08-06 Caroline Tice <cmtice@google.com>
+
+ * gcc.c (VTABLE_VERIFICATION_SPEC): New definition.
+ (LINK_COMMAND_SPEC): Add VTABLE_VERIFICATION_SPEC.
+ * tree-pass.h: Add pass_vtable_verify.
+ * varasm.c (assemble_variable): Add code to properly set the comdat
+ section and name for the .vtable_map_vars section.
+ (assemble_vtyv_preinit_initializer): New function.
+ (default_sectin_type_flags): Make sure .vtable_map_vars section has
+ LINK_ONCE flag.
+ * output.h: Add function decl for assemble_vtv_preinit_initializer.
+ * vtable-verify.c: New file.
+ * vtable-verify.h: New file.
+ * flag-types.h (enum vtv_priority): Defintions for flag_vtable_verify
+ initialiation levels.
+ * timevar.def (TV_VTABLE_VERIFICATION): New definition.
+ * passes.def: Insert pass_vtable_verify.
+ * aclocal.m4: Reorder includes.
+ * doc/invoke.texi: Document the -fvtable-verify=, -fvtv-debug, and
+ -fvtv-counts options.
+ * config/gnu-user.h (GNU_USER_TARGET_STARTFILE_SPEC): Add vtv_start*.o,
+ as appropriate, if -fvtable-verify=... is used.
+ (GNU_USER_TARGET_ENDFILE_SPEC): Add vtv_end*.o as appropriate, if
+ -fvtable-verify=... is used.
+ * Makefile.in (OBJS): Add vtable-verify.o to list.
+ (vtable-verify.o): Add new build rule.
+ (GTFILES): Add vtable-verify.c to list.
+ * common.opt (fvtable-verify=): New flag.
+ (vtv_priority): Values for fvtable-verify= flag.
+ (fvtv-counts): New flag.
+ (fvtv-debug): New flag.
+ * tree.h (save_vtable_map_decl): New extern function decl.
+
+2013-08-07 David Malcolm <dmalcolm@redhat.com>
+
+ * config/rl78/rl78.c (rl78_devirt_pass): Convert from a struct to...
+ (pass_rl78_devirt): ...new subclass of rtl_opt_pass along with...
+ (pass_data_rl78_devirt): ...new pass_data instance and...
+ (make_pass_rl78_devirt): ...new function.
+ (rl78_asm_file_start): Port pass registration to new C++ API.
+
+2013-08-07 David Malcolm <dmalcolm@redhat.com>
+
+ * coretypes.h (rtl_opt_pass): Add.
+ (gcc::context): Add.
+ * config/epiphany/epiphany.c (pass_mode_switch_use): New.
+ (epiphany_init): Port to new C++ pass API.
+ (epiphany_optimize_mode_switching): Likewise.
+ * pass_manager.h (pass_manager::get_pass_split_all_insns): New.
+ (pass_manager::get_pass_mode_switching): New.
+ (pass_manager::get_pass_peephole2): New.
+ * mode-switching.c (pass_mode_switching): Add clone method.
+ * recog.c (pass_peephole2): Add clone method.
+ (pass_split_all_insns): Add clone method.
+
+2013-08-06 David Malcolm <dmalcolm@redhat.com>
+
+ * config/mips/mips.c (insert_pass_mips_machine_reorg2): Move into...
+ (mips_option_override): ...here, porting to new C++ API for passes.
+
+2013-08-06 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_get_body): New function based on lto.c
+ implementation.
+ * cgraph.h (cgraph_get_body): Declare.
+ * cgraphclones.c (cgraph_create_virtual_clone): Commonize WPA and
+ LTO paths.
+ * cgraphunit.c (expand_function): Get body prior expanding.
+ * ipa.c (function_and_variable_visibility): Use gimple_has_body_p test.
+ * lto-cgraph.c (lto_output_node): Do not stream bodies we don't
+ really need.
+ * passes.c (do_per_function_toporder): Get body.
+ * tree-inline.c (expand_call_inline): Get body prior inlining it.
+ * tree-ssa-structalias.c (ipa_pta_execute): Get body; skip clones.
+
+2013-08-06 Martin Jambor <mjambor@suse.cz>
+
+ PR fortran/57987
+ * cgraphunit.c (cgraph_finalize_function): Assert that nested function
+ is not re-finalized. Rename second parameter to no_collect.
+
+2013-08-06 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/58041
+ * gimple-ssa-strength-reduction.c (replace_ref): Make sure built
+ MEM_REF has proper alignment information.
+
+2013-08-05 Oleg Endo <olegendo@gcc.gnu.org>
+
+ PR other/12081
+ * recog.h (rtx (*insn_gen_fn) (rtx, ...)): Replace typedef with new
+ class insn_gen_fn.
+ * expr.c (move_by_pieces_1, store_by_pieces_2): Replace argument
+ rtx (*) (rtx, ...) with insn_gen_fn.
+ * genoutput.c (output_insn_data): Cast gen_? function pointers to
+ insn_gen_fn::stored_funcptr. Add initializer braces.
+
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ Rewrite how instances of passes are cloned to remove assumptions
+ about their sizes (thus allowing pass subclasses to have
+ additional data fields, albeit non-GC-managed ones at this point).
+
+ * passes.c (make_pass_instance): Now that passes have clone
+ methods, rewrite this function to eliminate XNEW and memcpy
+ calls that used hardcoded sizes. Since this function no longer
+ creates pass instances, rename it to...
+ (add_pass_instance): ...this. Document the old way that passes were
+ numbered and flagged, and rework this function to continue using it.
+ (next_pass_1): Add an initial_pass argument for use by
+ add_pass_instance.
+ (position_pass): When adding multiple instances of a pass, use
+ the pass's clone method, rather than relying on the XNEW/memcpy
+ within the former make_pass_instance (now add_pass_instance).
+ (pass_manager::pass_manager): When invoking next_pass_1, also supply
+ the initial instance of the current pass within the pass manager.
+
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ This is the automated part of the conversion of passes from C
+ structs to C++ classes.
+
+ Patch autogenerated by refactor_passes.py from
+ https://github.com/davidmalcolm/gcc-refactoring-scripts
+ revision 03fe39476a4c4ea450b49e087cfa817b5f92021e
+
+ * asan.c (pass_asan): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_asan): ...new pass_data instance and...
+ (make_pass_asan): ...new function.
+ (pass_asan_O0): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_asan_O0): ...new pass_data instance and...
+ (make_pass_asan_O0): ...new function.
+ * auto-inc-dec.c (pass_inc_dec): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_inc_dec): ...new pass_data instance and...
+ (make_pass_inc_dec): ...new function.
+ * bb-reorder.c (pass_reorder_blocks): Convert from a global struct to
+ a subclass of rtl_opt_pass along with...
+ (pass_data_reorder_blocks): ...new pass_data instance and...
+ (make_pass_reorder_blocks): ...new function.
+ (pass_duplicate_computed_gotos): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_duplicate_computed_gotos): ...new pass_data instance and...
+ (make_pass_duplicate_computed_gotos): ...new function.
+ (pass_partition_blocks): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_partition_blocks): ...new pass_data instance and...
+ (make_pass_partition_blocks): ...new function.
+ * bt-load.c (pass_branch_target_load_optimize1): Convert from a global
+ struct to a subclass of rtl_opt_pass along with...
+ (pass_data_branch_target_load_optimize1): ...new pass_data instance
+ and...
+ (make_pass_branch_target_load_optimize1): ...new function.
+ (pass_branch_target_load_optimize2): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_branch_target_load_optimize2): ...new pass_data instance
+ and...
+ (make_pass_branch_target_load_optimize2): ...new function.
+ * cfgcleanup.c (pass_jump): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_jump): ...new pass_data instance and...
+ (make_pass_jump): ...new function.
+ (pass_jump2): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_jump2): ...new pass_data instance and...
+ (make_pass_jump2): ...new function.
+ * cfgexpand.c (pass_expand): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_expand): ...new pass_data instance and...
+ (make_pass_expand): ...new function.
+ * cfgrtl.c (pass_free_cfg): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_free_cfg): ...new pass_data instance and...
+ (make_pass_free_cfg): ...new function.
+ (pass_into_cfg_layout_mode): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_into_cfg_layout_mode): ...new pass_data instance and...
+ (make_pass_into_cfg_layout_mode): ...new function.
+ (pass_outof_cfg_layout_mode): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_outof_cfg_layout_mode): ...new pass_data instance and...
+ (make_pass_outof_cfg_layout_mode): ...new function.
+ * cgraphbuild.c (pass_build_cgraph_edges): Convert from a global
+ struct to a subclass of gimple_opt_pass along with...
+ (pass_data_build_cgraph_edges): ...new pass_data instance and...
+ (make_pass_build_cgraph_edges): ...new function.
+ (pass_rebuild_cgraph_edges): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_rebuild_cgraph_edges): ...new pass_data instance and...
+ (make_pass_rebuild_cgraph_edges): ...new function.
+ (pass_remove_cgraph_callee_edges): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_remove_cgraph_callee_edges): ...new pass_data instance
+ and...
+ (make_pass_remove_cgraph_callee_edges): ...new function.
+ * combine-stack-adj.c (pass_stack_adjustments): Convert from a global
+ struct to a subclass of rtl_opt_pass along with...
+ (pass_data_stack_adjustments): ...new pass_data instance and...
+ (make_pass_stack_adjustments): ...new function.
+ * combine.c (pass_combine): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_combine): ...new pass_data instance and...
+ (make_pass_combine): ...new function.
+ * compare-elim.c (pass_compare_elim_after_reload): Convert from a
+ global struct to a subclass of rtl_opt_pass along with...
+ (pass_data_compare_elim_after_reload): ...new pass_data instance
+ and...
+ (make_pass_compare_elim_after_reload): ...new function.
+ * cprop.c (pass_rtl_cprop): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_rtl_cprop): ...new pass_data instance and...
+ (make_pass_rtl_cprop): ...new function.
+ * cse.c (pass_cse): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_cse): ...new pass_data instance and...
+ (make_pass_cse): ...new function.
+ (pass_cse2): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_cse2): ...new pass_data instance and...
+ (make_pass_cse2): ...new function.
+ (pass_cse_after_global_opts): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_cse_after_global_opts): ...new pass_data instance and...
+ (make_pass_cse_after_global_opts): ...new function.
+ * dce.c (pass_ud_rtl_dce): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_ud_rtl_dce): ...new pass_data instance and...
+ (make_pass_ud_rtl_dce): ...new function.
+ (pass_fast_rtl_dce): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_fast_rtl_dce): ...new pass_data instance and...
+ (make_pass_fast_rtl_dce): ...new function.
+ * df-core.c (pass_df_initialize_opt): Convert from a global struct to
+ a subclass of rtl_opt_pass along with...
+ (pass_data_df_initialize_opt): ...new pass_data instance and...
+ (make_pass_df_initialize_opt): ...new function.
+ (pass_df_initialize_no_opt): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_df_initialize_no_opt): ...new pass_data instance and...
+ (make_pass_df_initialize_no_opt): ...new function.
+ (pass_df_finish): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_df_finish): ...new pass_data instance and...
+ (make_pass_df_finish): ...new function.
+ * dse.c (pass_rtl_dse1): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_dse1): ...new pass_data instance and...
+ (make_pass_rtl_dse1): ...new function.
+ (pass_rtl_dse2): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_dse2): ...new pass_data instance and...
+ (make_pass_rtl_dse2): ...new function.
+ * dwarf2cfi.c (pass_dwarf2_frame): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_dwarf2_frame): ...new pass_data instance and...
+ (make_pass_dwarf2_frame): ...new function.
+ * except.c (pass_set_nothrow_function_flags): Convert from a global
+ struct to a subclass of rtl_opt_pass along with...
+ (pass_data_set_nothrow_function_flags): ...new pass_data instance
+ and...
+ (make_pass_set_nothrow_function_flags): ...new function.
+ (pass_convert_to_eh_region_ranges): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_convert_to_eh_region_ranges): ...new pass_data instance
+ and...
+ (make_pass_convert_to_eh_region_ranges): ...new function.
+ * final.c (pass_compute_alignments): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_compute_alignments): ...new pass_data instance and...
+ (make_pass_compute_alignments): ...new function.
+ (pass_final): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_final): ...new pass_data instance and...
+ (make_pass_final): ...new function.
+ (pass_shorten_branches): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_shorten_branches): ...new pass_data instance and...
+ (make_pass_shorten_branches): ...new function.
+ (pass_clean_state): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_clean_state): ...new pass_data instance and...
+ (make_pass_clean_state): ...new function.
+ * function.c (pass_instantiate_virtual_regs): Convert from a global
+ struct to a subclass of rtl_opt_pass along with...
+ (pass_data_instantiate_virtual_regs): ...new pass_data instance and...
+ (make_pass_instantiate_virtual_regs): ...new function.
+ (pass_leaf_regs): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_leaf_regs): ...new pass_data instance and...
+ (make_pass_leaf_regs): ...new function.
+ (pass_thread_prologue_and_epilogue): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_thread_prologue_and_epilogue): ...new pass_data instance
+ and...
+ (make_pass_thread_prologue_and_epilogue): ...new function.
+ (pass_match_asm_constraints): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_match_asm_constraints): ...new pass_data instance and...
+ (make_pass_match_asm_constraints): ...new function.
+ * fwprop.c (pass_rtl_fwprop): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_rtl_fwprop): ...new pass_data instance and...
+ (make_pass_rtl_fwprop): ...new function.
+ (pass_rtl_fwprop_addr): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_fwprop_addr): ...new pass_data instance and...
+ (make_pass_rtl_fwprop_addr): ...new function.
+ * gcse.c (pass_rtl_pre): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_pre): ...new pass_data instance and...
+ (make_pass_rtl_pre): ...new function.
+ (pass_rtl_hoist): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_hoist): ...new pass_data instance and...
+ (make_pass_rtl_hoist): ...new function.
+ * gimple-low.c (pass_lower_cf): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_lower_cf): ...new pass_data instance and...
+ (make_pass_lower_cf): ...new function.
+ * gimple-ssa-strength-reduction.c (pass_strength_reduction): Convert
+ from a global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_strength_reduction): ...new pass_data instance and...
+ (make_pass_strength_reduction): ...new function.
+ * ifcvt.c (pass_rtl_ifcvt): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_rtl_ifcvt): ...new pass_data instance and...
+ (make_pass_rtl_ifcvt): ...new function.
+ (pass_if_after_combine): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_if_after_combine): ...new pass_data instance and...
+ (make_pass_if_after_combine): ...new function.
+ (pass_if_after_reload): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_if_after_reload): ...new pass_data instance and...
+ (make_pass_if_after_reload): ...new function.
+ * init-regs.c (pass_initialize_regs): Convert from a global struct to
+ a subclass of rtl_opt_pass along with...
+ (pass_data_initialize_regs): ...new pass_data instance and...
+ (make_pass_initialize_regs): ...new function.
+ * ipa-cp.c (pass_ipa_cp): Convert from a global struct to a subclass
+ of ipa_opt_pass_d along with...
+ (pass_data_ipa_cp): ...new pass_data instance and...
+ (make_pass_ipa_cp): ...new function.
+ * ipa-inline-analysis.c (pass_inline_parameters): Convert from a
+ global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_inline_parameters): ...new pass_data instance and...
+ (make_pass_inline_parameters): ...new function.
+ * ipa-inline.c (pass_early_inline): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_early_inline): ...new pass_data instance and...
+ (make_pass_early_inline): ...new function.
+ (pass_ipa_inline): Convert from a global struct to a subclass of
+ ipa_opt_pass_d along with...
+ (pass_data_ipa_inline): ...new pass_data instance and...
+ (make_pass_ipa_inline): ...new function.
+ * ipa-pure-const.c (pass_local_pure_const): Convert from a global
+ struct to a subclass of gimple_opt_pass along with...
+ (pass_data_local_pure_const): ...new pass_data instance and...
+ (make_pass_local_pure_const): ...new function.
+ (pass_ipa_pure_const): Convert from a global struct to a subclass of
+ ipa_opt_pass_d along with...
+ (pass_data_ipa_pure_const): ...new pass_data instance and...
+ (make_pass_ipa_pure_const): ...new function.
+ * ipa-reference.c (pass_ipa_reference): Convert from a global struct
+ to a subclass of ipa_opt_pass_d along with...
+ (pass_data_ipa_reference): ...new pass_data instance and...
+ (make_pass_ipa_reference): ...new function.
+ * ipa-split.c (pass_split_functions): Convert from a global struct to
+ a subclass of gimple_opt_pass along with...
+ (pass_data_split_functions): ...new pass_data instance and...
+ (make_pass_split_functions): ...new function.
+ (pass_feedback_split_functions): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_feedback_split_functions): ...new pass_data instance and...
+ (make_pass_feedback_split_functions): ...new function.
+ * ipa.c (pass_ipa_function_and_variable_visibility): Convert from a
+ global struct to a subclass of simple_ipa_opt_pass along with...
+ (pass_data_ipa_function_and_variable_visibility): ...new pass_data
+ instance and...
+ (make_pass_ipa_function_and_variable_visibility): ...new function.
+ (pass_ipa_free_inline_summary): Convert from a global struct to a
+ subclass of simple_ipa_opt_pass along with...
+ (pass_data_ipa_free_inline_summary): ...new pass_data instance and...
+ (make_pass_ipa_free_inline_summary): ...new function.
+ (pass_ipa_whole_program_visibility): Convert from a global struct to a
+ subclass of ipa_opt_pass_d along with...
+ (pass_data_ipa_whole_program_visibility): ...new pass_data instance
+ and...
+ (make_pass_ipa_whole_program_visibility): ...new function.
+ (pass_ipa_profile): Convert from a global struct to a subclass of
+ ipa_opt_pass_d along with...
+ (pass_data_ipa_profile): ...new pass_data instance and...
+ (make_pass_ipa_profile): ...new function.
+ (pass_ipa_cdtor_merge): Convert from a global struct to a subclass of
+ ipa_opt_pass_d along with...
+ (pass_data_ipa_cdtor_merge): ...new pass_data instance and...
+ (make_pass_ipa_cdtor_merge): ...new function.
+ * ira.c (pass_ira): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_ira): ...new pass_data instance and...
+ (make_pass_ira): ...new function.
+ (pass_reload): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_reload): ...new pass_data instance and...
+ (make_pass_reload): ...new function.
+ * jump.c (pass_cleanup_barriers): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_cleanup_barriers): ...new pass_data instance and...
+ (make_pass_cleanup_barriers): ...new function.
+ * loop-init.c (pass_loop2): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_loop2): ...new pass_data instance and...
+ (make_pass_loop2): ...new function.
+ (pass_rtl_loop_init): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_loop_init): ...new pass_data instance and...
+ (make_pass_rtl_loop_init): ...new function.
+ (pass_rtl_loop_done): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_loop_done): ...new pass_data instance and...
+ (make_pass_rtl_loop_done): ...new function.
+ (pass_rtl_move_loop_invariants): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_rtl_move_loop_invariants): ...new pass_data instance and...
+ (make_pass_rtl_move_loop_invariants): ...new function.
+ (pass_rtl_unswitch): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_unswitch): ...new pass_data instance and...
+ (make_pass_rtl_unswitch): ...new function.
+ (pass_rtl_unroll_and_peel_loops): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_rtl_unroll_and_peel_loops): ...new pass_data instance
+ and...
+ (make_pass_rtl_unroll_and_peel_loops): ...new function.
+ (pass_rtl_doloop): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_rtl_doloop): ...new pass_data instance and...
+ (make_pass_rtl_doloop): ...new function.
+ * lower-subreg.c (pass_lower_subreg): Convert from a global struct to
+ a subclass of rtl_opt_pass along with...
+ (pass_data_lower_subreg): ...new pass_data instance and...
+ (make_pass_lower_subreg): ...new function.
+ (pass_lower_subreg2): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_lower_subreg2): ...new pass_data instance and...
+ (make_pass_lower_subreg2): ...new function.
+ * lto-streamer-out.c (pass_ipa_lto_gimple_out): Convert from a global
+ struct to a subclass of ipa_opt_pass_d along with...
+ (pass_data_ipa_lto_gimple_out): ...new pass_data instance and...
+ (make_pass_ipa_lto_gimple_out): ...new function.
+ (pass_ipa_lto_finish_out): Convert from a global struct to a subclass
+ of ipa_opt_pass_d along with...
+ (pass_data_ipa_lto_finish_out): ...new pass_data instance and...
+ (make_pass_ipa_lto_finish_out): ...new function.
+ * mode-switching.c (pass_mode_switching): Convert from a global struct
+ to a subclass of rtl_opt_pass along with...
+ (pass_data_mode_switching): ...new pass_data instance and...
+ (make_pass_mode_switching): ...new function.
+ * modulo-sched.c (pass_sms): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_sms): ...new pass_data instance and...
+ (make_pass_sms): ...new function.
+ * omp-low.c (pass_expand_omp): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_expand_omp): ...new pass_data instance and...
+ (make_pass_expand_omp): ...new function.
+ (pass_lower_omp): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_lower_omp): ...new pass_data instance and...
+ (make_pass_lower_omp): ...new function.
+ (pass_diagnose_omp_blocks): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_diagnose_omp_blocks): ...new pass_data instance and...
+ (make_pass_diagnose_omp_blocks): ...new function.
+ * passes.c (pass_early_local_passes): Convert from a global struct to
+ a subclass of simple_ipa_opt_pass along with...
+ (pass_data_early_local_passes): ...new pass_data instance and...
+ (make_pass_early_local_passes): ...new function.
+ (pass_all_early_optimizations): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_all_early_optimizations): ...new pass_data instance and...
+ (make_pass_all_early_optimizations): ...new function.
+ (pass_all_optimizations): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_all_optimizations): ...new pass_data instance and...
+ (make_pass_all_optimizations): ...new function.
+ (pass_all_optimizations_g): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_all_optimizations_g): ...new pass_data instance and...
+ (make_pass_all_optimizations_g): ...new function.
+ (pass_rest_of_compilation): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_rest_of_compilation): ...new pass_data instance and...
+ (make_pass_rest_of_compilation): ...new function.
+ (pass_postreload): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_postreload): ...new pass_data instance and...
+ (make_pass_postreload): ...new function.
+ * postreload-gcse.c (pass_gcse2): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_gcse2): ...new pass_data instance and...
+ (make_pass_gcse2): ...new function.
+ * postreload.c (pass_postreload_cse): Convert from a global struct to
+ a subclass of rtl_opt_pass along with...
+ (pass_data_postreload_cse): ...new pass_data instance and...
+ (make_pass_postreload_cse): ...new function.
+ * predict.c (pass_profile): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_profile): ...new pass_data instance and...
+ (make_pass_profile): ...new function.
+ (pass_strip_predict_hints): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_strip_predict_hints): ...new pass_data instance and...
+ (make_pass_strip_predict_hints): ...new function.
+ * recog.c (pass_peephole2): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_peephole2): ...new pass_data instance and...
+ (make_pass_peephole2): ...new function.
+ (pass_split_all_insns): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_split_all_insns): ...new pass_data instance and...
+ (make_pass_split_all_insns): ...new function.
+ (pass_split_after_reload): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_split_after_reload): ...new pass_data instance and...
+ (make_pass_split_after_reload): ...new function.
+ (pass_split_before_regstack): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_split_before_regstack): ...new pass_data instance and...
+ (make_pass_split_before_regstack): ...new function.
+ (pass_split_before_sched2): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_split_before_sched2): ...new pass_data instance and...
+ (make_pass_split_before_sched2): ...new function.
+ (pass_split_for_shorten_branches): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_split_for_shorten_branches): ...new pass_data instance
+ and...
+ (make_pass_split_for_shorten_branches): ...new function.
+ * ree.c (pass_ree): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_ree): ...new pass_data instance and...
+ (make_pass_ree): ...new function.
+ * reg-stack.c (pass_stack_regs): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_stack_regs): ...new pass_data instance and...
+ (make_pass_stack_regs): ...new function.
+ (pass_stack_regs_run): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_stack_regs_run): ...new pass_data instance and...
+ (make_pass_stack_regs_run): ...new function.
+ * regcprop.c (pass_cprop_hardreg): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_cprop_hardreg): ...new pass_data instance and...
+ (make_pass_cprop_hardreg): ...new function.
+ * reginfo.c (pass_reginfo_init): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_reginfo_init): ...new pass_data instance and...
+ (make_pass_reginfo_init): ...new function.
+ * regmove.c (pass_regmove): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_regmove): ...new pass_data instance and...
+ (make_pass_regmove): ...new function.
+ * regrename.c (pass_regrename): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_regrename): ...new pass_data instance and...
+ (make_pass_regrename): ...new function.
+ * reorg.c (pass_delay_slots): Convert from a global struct to a
+ subclass of rtl_opt_pass along with...
+ (pass_data_delay_slots): ...new pass_data instance and...
+ (make_pass_delay_slots): ...new function.
+ (pass_machine_reorg): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_machine_reorg): ...new pass_data instance and...
+ (make_pass_machine_reorg): ...new function.
+ * sched-rgn.c (pass_sched): Convert from a global struct to a subclass
+ of rtl_opt_pass along with...
+ (pass_data_sched): ...new pass_data instance and...
+ (make_pass_sched): ...new function.
+ (pass_sched2): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_sched2): ...new pass_data instance and...
+ (make_pass_sched2): ...new function.
+ * stack-ptr-mod.c (pass_stack_ptr_mod): Convert from a global struct
+ to a subclass of rtl_opt_pass along with...
+ (pass_data_stack_ptr_mod): ...new pass_data instance and...
+ (make_pass_stack_ptr_mod): ...new function.
+ * store-motion.c (pass_rtl_store_motion): Convert from a global struct
+ to a subclass of rtl_opt_pass along with...
+ (pass_data_rtl_store_motion): ...new pass_data instance and...
+ (make_pass_rtl_store_motion): ...new function.
+ * tracer.c (pass_tracer): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_tracer): ...new pass_data instance and...
+ (make_pass_tracer): ...new function.
+ * trans-mem.c (pass_diagnose_tm_blocks): Convert from a global struct
+ to a subclass of gimple_opt_pass along with...
+ (pass_data_diagnose_tm_blocks): ...new pass_data instance and...
+ (make_pass_diagnose_tm_blocks): ...new function.
+ (pass_lower_tm): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_lower_tm): ...new pass_data instance and...
+ (make_pass_lower_tm): ...new function.
+ (pass_tm_init): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tm_init): ...new pass_data instance and...
+ (make_pass_tm_init): ...new function.
+ (pass_tm_mark): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tm_mark): ...new pass_data instance and...
+ (make_pass_tm_mark): ...new function.
+ (pass_tm_edges): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tm_edges): ...new pass_data instance and...
+ (make_pass_tm_edges): ...new function.
+ (pass_tm_memopt): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tm_memopt): ...new pass_data instance and...
+ (make_pass_tm_memopt): ...new function.
+ (pass_ipa_tm): Convert from a global struct to a subclass of
+ simple_ipa_opt_pass along with...
+ (pass_data_ipa_tm): ...new pass_data instance and...
+ (make_pass_ipa_tm): ...new function.
+ * tree-call-cdce.c (pass_call_cdce): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_call_cdce): ...new pass_data instance and...
+ (make_pass_call_cdce): ...new function.
+ * tree-cfg.c (pass_build_cfg): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_build_cfg): ...new pass_data instance and...
+ (make_pass_build_cfg): ...new function.
+ (pass_split_crit_edges): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_split_crit_edges): ...new pass_data instance and...
+ (make_pass_split_crit_edges): ...new function.
+ (pass_warn_function_return): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_warn_function_return): ...new pass_data instance and...
+ (make_pass_warn_function_return): ...new function.
+ (pass_warn_function_noreturn): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_warn_function_noreturn): ...new pass_data instance and...
+ (make_pass_warn_function_noreturn): ...new function.
+ (pass_warn_unused_result): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_warn_unused_result): ...new pass_data instance and...
+ (make_pass_warn_unused_result): ...new function.
+ * tree-cfgcleanup.c (pass_merge_phi): Convert from a global struct to
+ a subclass of gimple_opt_pass along with...
+ (pass_data_merge_phi): ...new pass_data instance and...
+ (make_pass_merge_phi): ...new function.
+ * tree-complex.c (pass_lower_complex): Convert from a global struct to
+ a subclass of gimple_opt_pass along with...
+ (pass_data_lower_complex): ...new pass_data instance and...
+ (make_pass_lower_complex): ...new function.
+ (pass_lower_complex_O0): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_lower_complex_O0): ...new pass_data instance and...
+ (make_pass_lower_complex_O0): ...new function.
+ * tree-eh.c (pass_lower_eh): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_lower_eh): ...new pass_data instance and...
+ (make_pass_lower_eh): ...new function.
+ (pass_refactor_eh): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_refactor_eh): ...new pass_data instance and...
+ (make_pass_refactor_eh): ...new function.
+ (pass_lower_resx): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_lower_resx): ...new pass_data instance and...
+ (make_pass_lower_resx): ...new function.
+ (pass_lower_eh_dispatch): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_lower_eh_dispatch): ...new pass_data instance and...
+ (make_pass_lower_eh_dispatch): ...new function.
+ (pass_cleanup_eh): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_cleanup_eh): ...new pass_data instance and...
+ (make_pass_cleanup_eh): ...new function.
+ * tree-emutls.c (pass_ipa_lower_emutls): Convert from a global struct
+ to a subclass of simple_ipa_opt_pass along with...
+ (pass_data_ipa_lower_emutls): ...new pass_data instance and...
+ (make_pass_ipa_lower_emutls): ...new function.
+ * tree-if-conv.c (pass_if_conversion): Convert from a global struct to
+ a subclass of gimple_opt_pass along with...
+ (pass_data_if_conversion): ...new pass_data instance and...
+ (make_pass_if_conversion): ...new function.
+ * tree-into-ssa.c (pass_build_ssa): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_build_ssa): ...new pass_data instance and...
+ (make_pass_build_ssa): ...new function.
+ * tree-loop-distribution.c (pass_loop_distribution): Convert from a
+ global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_loop_distribution): ...new pass_data instance and...
+ (make_pass_loop_distribution): ...new function.
+ * tree-mudflap.c (pass_mudflap_1): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_mudflap_1): ...new pass_data instance and...
+ (make_pass_mudflap_1): ...new function.
+ (pass_mudflap_2): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_mudflap_2): ...new pass_data instance and...
+ (make_pass_mudflap_2): ...new function.
+ * tree-nomudflap.c (pass_mudflap_1): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_mudflap_1): ...new pass_data instance and...
+ (make_pass_mudflap_1): ...new function.
+ (pass_mudflap_2): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_mudflap_2): ...new pass_data instance and...
+ (make_pass_mudflap_2): ...new function.
+ * tree-nrv.c (pass_nrv): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_nrv): ...new pass_data instance and...
+ (make_pass_nrv): ...new function.
+ (pass_return_slot): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_return_slot): ...new pass_data instance and...
+ (make_pass_return_slot): ...new function.
+ * tree-object-size.c (pass_object_sizes): Convert from a global struct
+ to a subclass of gimple_opt_pass along with...
+ (pass_data_object_sizes): ...new pass_data instance and...
+ (make_pass_object_sizes): ...new function.
+ * tree-optimize.c (pass_cleanup_cfg_post_optimizing): Convert from a
+ global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_cleanup_cfg_post_optimizing): ...new pass_data instance
+ and...
+ (make_pass_cleanup_cfg_post_optimizing): ...new function.
+ (pass_fixup_cfg): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_fixup_cfg): ...new pass_data instance and...
+ (make_pass_fixup_cfg): ...new function.
+ * tree-pass.h (pass_mudflap_1): Replace declaration with that of...
+ (make_pass_mudflap_1): ...new function.
+ (pass_mudflap_2): Replace declaration with that of...
+ (make_pass_mudflap_2): ...new function.
+ (pass_asan): Replace declaration with that of...
+ (make_pass_asan): ...new function.
+ (pass_asan_O0): Replace declaration with that of...
+ (make_pass_asan_O0): ...new function.
+ (pass_tsan): Replace declaration with that of...
+ (make_pass_tsan): ...new function.
+ (pass_tsan_O0): Replace declaration with that of...
+ (make_pass_tsan_O0): ...new function.
+ (pass_lower_cf): Replace declaration with that of...
+ (make_pass_lower_cf): ...new function.
+ (pass_refactor_eh): Replace declaration with that of...
+ (make_pass_refactor_eh): ...new function.
+ (pass_lower_eh): Replace declaration with that of...
+ (make_pass_lower_eh): ...new function.
+ (pass_lower_eh_dispatch): Replace declaration with that of...
+ (make_pass_lower_eh_dispatch): ...new function.
+ (pass_lower_resx): Replace declaration with that of...
+ (make_pass_lower_resx): ...new function.
+ (pass_build_cfg): Replace declaration with that of...
+ (make_pass_build_cfg): ...new function.
+ (pass_early_tree_profile): Replace declaration with that of...
+ (make_pass_early_tree_profile): ...new function.
+ (pass_cleanup_eh): Replace declaration with that of...
+ (make_pass_cleanup_eh): ...new function.
+ (pass_sra): Replace declaration with that of...
+ (make_pass_sra): ...new function.
+ (pass_sra_early): Replace declaration with that of...
+ (make_pass_sra_early): ...new function.
+ (pass_early_ipa_sra): Replace declaration with that of...
+ (make_pass_early_ipa_sra): ...new function.
+ (pass_tail_recursion): Replace declaration with that of...
+ (make_pass_tail_recursion): ...new function.
+ (pass_tail_calls): Replace declaration with that of...
+ (make_pass_tail_calls): ...new function.
+ (pass_tree_loop): Replace declaration with that of...
+ (make_pass_tree_loop): ...new function.
+ (pass_tree_loop_init): Replace declaration with that of...
+ (make_pass_tree_loop_init): ...new function.
+ (pass_lim): Replace declaration with that of...
+ (make_pass_lim): ...new function.
+ (pass_tree_unswitch): Replace declaration with that of...
+ (make_pass_tree_unswitch): ...new function.
+ (pass_predcom): Replace declaration with that of...
+ (make_pass_predcom): ...new function.
+ (pass_iv_canon): Replace declaration with that of...
+ (make_pass_iv_canon): ...new function.
+ (pass_scev_cprop): Replace declaration with that of...
+ (make_pass_scev_cprop): ...new function.
+ (pass_empty_loop): Replace declaration with that of...
+ (make_pass_empty_loop): ...new function.
+ (pass_record_bounds): Replace declaration with that of...
+ (make_pass_record_bounds): ...new function.
+ (pass_graphite): Replace declaration with that of...
+ (make_pass_graphite): ...new function.
+ (pass_graphite_transforms): Replace declaration with that of...
+ (make_pass_graphite_transforms): ...new function.
+ (pass_if_conversion): Replace declaration with that of...
+ (make_pass_if_conversion): ...new function.
+ (pass_loop_distribution): Replace declaration with that of...
+ (make_pass_loop_distribution): ...new function.
+ (pass_vectorize): Replace declaration with that of...
+ (make_pass_vectorize): ...new function.
+ (pass_slp_vectorize): Replace declaration with that of...
+ (make_pass_slp_vectorize): ...new function.
+ (pass_complete_unroll): Replace declaration with that of...
+ (make_pass_complete_unroll): ...new function.
+ (pass_complete_unrolli): Replace declaration with that of...
+ (make_pass_complete_unrolli): ...new function.
+ (pass_parallelize_loops): Replace declaration with that of...
+ (make_pass_parallelize_loops): ...new function.
+ (pass_loop_prefetch): Replace declaration with that of...
+ (make_pass_loop_prefetch): ...new function.
+ (pass_iv_optimize): Replace declaration with that of...
+ (make_pass_iv_optimize): ...new function.
+ (pass_tree_loop_done): Replace declaration with that of...
+ (make_pass_tree_loop_done): ...new function.
+ (pass_ch): Replace declaration with that of...
+ (make_pass_ch): ...new function.
+ (pass_ccp): Replace declaration with that of...
+ (make_pass_ccp): ...new function.
+ (pass_phi_only_cprop): Replace declaration with that of...
+ (make_pass_phi_only_cprop): ...new function.
+ (pass_build_ssa): Replace declaration with that of...
+ (make_pass_build_ssa): ...new function.
+ (pass_build_alias): Replace declaration with that of...
+ (make_pass_build_alias): ...new function.
+ (pass_build_ealias): Replace declaration with that of...
+ (make_pass_build_ealias): ...new function.
+ (pass_dominator): Replace declaration with that of...
+ (make_pass_dominator): ...new function.
+ (pass_dce): Replace declaration with that of...
+ (make_pass_dce): ...new function.
+ (pass_dce_loop): Replace declaration with that of...
+ (make_pass_dce_loop): ...new function.
+ (pass_cd_dce): Replace declaration with that of...
+ (make_pass_cd_dce): ...new function.
+ (pass_call_cdce): Replace declaration with that of...
+ (make_pass_call_cdce): ...new function.
+ (pass_merge_phi): Replace declaration with that of...
+ (make_pass_merge_phi): ...new function.
+ (pass_split_crit_edges): Replace declaration with that of...
+ (make_pass_split_crit_edges): ...new function.
+ (pass_pre): Replace declaration with that of...
+ (make_pass_pre): ...new function.
+ (pass_profile): Replace declaration with that of...
+ (make_pass_profile): ...new function.
+ (pass_strip_predict_hints): Replace declaration with that of...
+ (make_pass_strip_predict_hints): ...new function.
+ (pass_lower_complex_O0): Replace declaration with that of...
+ (make_pass_lower_complex_O0): ...new function.
+ (pass_lower_complex): Replace declaration with that of...
+ (make_pass_lower_complex): ...new function.
+ (pass_lower_vector): Replace declaration with that of...
+ (make_pass_lower_vector): ...new function.
+ (pass_lower_vector_ssa): Replace declaration with that of...
+ (make_pass_lower_vector_ssa): ...new function.
+ (pass_lower_omp): Replace declaration with that of...
+ (make_pass_lower_omp): ...new function.
+ (pass_diagnose_omp_blocks): Replace declaration with that of...
+ (make_pass_diagnose_omp_blocks): ...new function.
+ (pass_expand_omp): Replace declaration with that of...
+ (make_pass_expand_omp): ...new function.
+ (pass_expand_omp_ssa): Replace declaration with that of...
+ (make_pass_expand_omp_ssa): ...new function.
+ (pass_object_sizes): Replace declaration with that of...
+ (make_pass_object_sizes): ...new function.
+ (pass_strlen): Replace declaration with that of...
+ (make_pass_strlen): ...new function.
+ (pass_fold_builtins): Replace declaration with that of...
+ (make_pass_fold_builtins): ...new function.
+ (pass_stdarg): Replace declaration with that of...
+ (make_pass_stdarg): ...new function.
+ (pass_early_warn_uninitialized): Replace declaration with that of...
+ (make_pass_early_warn_uninitialized): ...new function.
+ (pass_late_warn_uninitialized): Replace declaration with that of...
+ (make_pass_late_warn_uninitialized): ...new function.
+ (pass_cse_reciprocals): Replace declaration with that of...
+ (make_pass_cse_reciprocals): ...new function.
+ (pass_cse_sincos): Replace declaration with that of...
+ (make_pass_cse_sincos): ...new function.
+ (pass_optimize_bswap): Replace declaration with that of...
+ (make_pass_optimize_bswap): ...new function.
+ (pass_optimize_widening_mul): Replace declaration with that of...
+ (make_pass_optimize_widening_mul): ...new function.
+ (pass_warn_function_return): Replace declaration with that of...
+ (make_pass_warn_function_return): ...new function.
+ (pass_warn_function_noreturn): Replace declaration with that of...
+ (make_pass_warn_function_noreturn): ...new function.
+ (pass_cselim): Replace declaration with that of...
+ (make_pass_cselim): ...new function.
+ (pass_phiopt): Replace declaration with that of...
+ (make_pass_phiopt): ...new function.
+ (pass_forwprop): Replace declaration with that of...
+ (make_pass_forwprop): ...new function.
+ (pass_phiprop): Replace declaration with that of...
+ (make_pass_phiprop): ...new function.
+ (pass_tree_ifcombine): Replace declaration with that of...
+ (make_pass_tree_ifcombine): ...new function.
+ (pass_dse): Replace declaration with that of...
+ (make_pass_dse): ...new function.
+ (pass_nrv): Replace declaration with that of...
+ (make_pass_nrv): ...new function.
+ (pass_rename_ssa_copies): Replace declaration with that of...
+ (make_pass_rename_ssa_copies): ...new function.
+ (pass_sink_code): Replace declaration with that of...
+ (make_pass_sink_code): ...new function.
+ (pass_fre): Replace declaration with that of...
+ (make_pass_fre): ...new function.
+ (pass_check_data_deps): Replace declaration with that of...
+ (make_pass_check_data_deps): ...new function.
+ (pass_copy_prop): Replace declaration with that of...
+ (make_pass_copy_prop): ...new function.
+ (pass_vrp): Replace declaration with that of...
+ (make_pass_vrp): ...new function.
+ (pass_uncprop): Replace declaration with that of...
+ (make_pass_uncprop): ...new function.
+ (pass_return_slot): Replace declaration with that of...
+ (make_pass_return_slot): ...new function.
+ (pass_reassoc): Replace declaration with that of...
+ (make_pass_reassoc): ...new function.
+ (pass_rebuild_cgraph_edges): Replace declaration with that of...
+ (make_pass_rebuild_cgraph_edges): ...new function.
+ (pass_remove_cgraph_callee_edges): Replace declaration with that of...
+ (make_pass_remove_cgraph_callee_edges): ...new function.
+ (pass_build_cgraph_edges): Replace declaration with that of...
+ (make_pass_build_cgraph_edges): ...new function.
+ (pass_local_pure_const): Replace declaration with that of...
+ (make_pass_local_pure_const): ...new function.
+ (pass_tracer): Replace declaration with that of...
+ (make_pass_tracer): ...new function.
+ (pass_warn_unused_result): Replace declaration with that of...
+ (make_pass_warn_unused_result): ...new function.
+ (pass_diagnose_tm_blocks): Replace declaration with that of...
+ (make_pass_diagnose_tm_blocks): ...new function.
+ (pass_lower_tm): Replace declaration with that of...
+ (make_pass_lower_tm): ...new function.
+ (pass_tm_init): Replace declaration with that of...
+ (make_pass_tm_init): ...new function.
+ (pass_tm_mark): Replace declaration with that of...
+ (make_pass_tm_mark): ...new function.
+ (pass_tm_memopt): Replace declaration with that of...
+ (make_pass_tm_memopt): ...new function.
+ (pass_tm_edges): Replace declaration with that of...
+ (make_pass_tm_edges): ...new function.
+ (pass_split_functions): Replace declaration with that of...
+ (make_pass_split_functions): ...new function.
+ (pass_feedback_split_functions): Replace declaration with that of...
+ (make_pass_feedback_split_functions): ...new function.
+ (pass_strength_reduction): Replace declaration with that of...
+ (make_pass_strength_reduction): ...new function.
+ (pass_ipa_lower_emutls): Replace declaration with that of...
+ (make_pass_ipa_lower_emutls): ...new function.
+ (pass_ipa_function_and_variable_visibility): Replace declaration with
+ that of...
+ (make_pass_ipa_function_and_variable_visibility): ...new function.
+ (pass_ipa_tree_profile): Replace declaration with that of...
+ (make_pass_ipa_tree_profile): ...new function.
+ (pass_early_local_passes): Replace declaration with that of...
+ (make_pass_early_local_passes): ...new function.
+ (pass_ipa_whole_program_visibility): Replace declaration with that
+ of...
+ (make_pass_ipa_whole_program_visibility): ...new function.
+ (pass_ipa_lto_gimple_out): Replace declaration with that of...
+ (make_pass_ipa_lto_gimple_out): ...new function.
+ (pass_ipa_increase_alignment): Replace declaration with that of...
+ (make_pass_ipa_increase_alignment): ...new function.
+ (pass_ipa_inline): Replace declaration with that of...
+ (make_pass_ipa_inline): ...new function.
+ (pass_ipa_free_lang_data): Replace declaration with that of...
+ (make_pass_ipa_free_lang_data): ...new function.
+ (pass_ipa_free_inline_summary): Replace declaration with that of...
+ (make_pass_ipa_free_inline_summary): ...new function.
+ (pass_ipa_cp): Replace declaration with that of...
+ (make_pass_ipa_cp): ...new function.
+ (pass_ipa_reference): Replace declaration with that of...
+ (make_pass_ipa_reference): ...new function.
+ (pass_ipa_pure_const): Replace declaration with that of...
+ (make_pass_ipa_pure_const): ...new function.
+ (pass_ipa_pta): Replace declaration with that of...
+ (make_pass_ipa_pta): ...new function.
+ (pass_ipa_lto_finish_out): Replace declaration with that of...
+ (make_pass_ipa_lto_finish_out): ...new function.
+ (pass_ipa_tm): Replace declaration with that of...
+ (make_pass_ipa_tm): ...new function.
+ (pass_ipa_profile): Replace declaration with that of...
+ (make_pass_ipa_profile): ...new function.
+ (pass_ipa_cdtor_merge): Replace declaration with that of...
+ (make_pass_ipa_cdtor_merge): ...new function.
+ (pass_cleanup_cfg_post_optimizing): Replace declaration with that
+ of...
+ (make_pass_cleanup_cfg_post_optimizing): ...new function.
+ (pass_init_datastructures): Replace declaration with that of...
+ (make_pass_init_datastructures): ...new function.
+ (pass_fixup_cfg): Replace declaration with that of...
+ (make_pass_fixup_cfg): ...new function.
+ (pass_expand): Replace declaration with that of...
+ (make_pass_expand): ...new function.
+ (pass_instantiate_virtual_regs): Replace declaration with that of...
+ (make_pass_instantiate_virtual_regs): ...new function.
+ (pass_rtl_fwprop): Replace declaration with that of...
+ (make_pass_rtl_fwprop): ...new function.
+ (pass_rtl_fwprop_addr): Replace declaration with that of...
+ (make_pass_rtl_fwprop_addr): ...new function.
+ (pass_jump): Replace declaration with that of...
+ (make_pass_jump): ...new function.
+ (pass_jump2): Replace declaration with that of...
+ (make_pass_jump2): ...new function.
+ (pass_lower_subreg): Replace declaration with that of...
+ (make_pass_lower_subreg): ...new function.
+ (pass_cse): Replace declaration with that of...
+ (make_pass_cse): ...new function.
+ (pass_fast_rtl_dce): Replace declaration with that of...
+ (make_pass_fast_rtl_dce): ...new function.
+ (pass_ud_rtl_dce): Replace declaration with that of...
+ (make_pass_ud_rtl_dce): ...new function.
+ (pass_rtl_dce): Replace declaration with that of...
+ (make_pass_rtl_dce): ...new function.
+ (pass_rtl_dse1): Replace declaration with that of...
+ (make_pass_rtl_dse1): ...new function.
+ (pass_rtl_dse2): Replace declaration with that of...
+ (make_pass_rtl_dse2): ...new function.
+ (pass_rtl_dse3): Replace declaration with that of...
+ (make_pass_rtl_dse3): ...new function.
+ (pass_rtl_cprop): Replace declaration with that of...
+ (make_pass_rtl_cprop): ...new function.
+ (pass_rtl_pre): Replace declaration with that of...
+ (make_pass_rtl_pre): ...new function.
+ (pass_rtl_hoist): Replace declaration with that of...
+ (make_pass_rtl_hoist): ...new function.
+ (pass_rtl_store_motion): Replace declaration with that of...
+ (make_pass_rtl_store_motion): ...new function.
+ (pass_cse_after_global_opts): Replace declaration with that of...
+ (make_pass_cse_after_global_opts): ...new function.
+ (pass_rtl_ifcvt): Replace declaration with that of...
+ (make_pass_rtl_ifcvt): ...new function.
+ (pass_into_cfg_layout_mode): Replace declaration with that of...
+ (make_pass_into_cfg_layout_mode): ...new function.
+ (pass_outof_cfg_layout_mode): Replace declaration with that of...
+ (make_pass_outof_cfg_layout_mode): ...new function.
+ (pass_loop2): Replace declaration with that of...
+ (make_pass_loop2): ...new function.
+ (pass_rtl_loop_init): Replace declaration with that of...
+ (make_pass_rtl_loop_init): ...new function.
+ (pass_rtl_move_loop_invariants): Replace declaration with that of...
+ (make_pass_rtl_move_loop_invariants): ...new function.
+ (pass_rtl_unswitch): Replace declaration with that of...
+ (make_pass_rtl_unswitch): ...new function.
+ (pass_rtl_unroll_and_peel_loops): Replace declaration with that of...
+ (make_pass_rtl_unroll_and_peel_loops): ...new function.
+ (pass_rtl_doloop): Replace declaration with that of...
+ (make_pass_rtl_doloop): ...new function.
+ (pass_rtl_loop_done): Replace declaration with that of...
+ (make_pass_rtl_loop_done): ...new function.
+ (pass_web): Replace declaration with that of...
+ (make_pass_web): ...new function.
+ (pass_cse2): Replace declaration with that of...
+ (make_pass_cse2): ...new function.
+ (pass_df_initialize_opt): Replace declaration with that of...
+ (make_pass_df_initialize_opt): ...new function.
+ (pass_df_initialize_no_opt): Replace declaration with that of...
+ (make_pass_df_initialize_no_opt): ...new function.
+ (pass_reginfo_init): Replace declaration with that of...
+ (make_pass_reginfo_init): ...new function.
+ (pass_inc_dec): Replace declaration with that of...
+ (make_pass_inc_dec): ...new function.
+ (pass_stack_ptr_mod): Replace declaration with that of...
+ (make_pass_stack_ptr_mod): ...new function.
+ (pass_initialize_regs): Replace declaration with that of...
+ (make_pass_initialize_regs): ...new function.
+ (pass_combine): Replace declaration with that of...
+ (make_pass_combine): ...new function.
+ (pass_if_after_combine): Replace declaration with that of...
+ (make_pass_if_after_combine): ...new function.
+ (pass_ree): Replace declaration with that of...
+ (make_pass_ree): ...new function.
+ (pass_partition_blocks): Replace declaration with that of...
+ (make_pass_partition_blocks): ...new function.
+ (pass_match_asm_constraints): Replace declaration with that of...
+ (make_pass_match_asm_constraints): ...new function.
+ (pass_regmove): Replace declaration with that of...
+ (make_pass_regmove): ...new function.
+ (pass_split_all_insns): Replace declaration with that of...
+ (make_pass_split_all_insns): ...new function.
+ (pass_fast_rtl_byte_dce): Replace declaration with that of...
+ (make_pass_fast_rtl_byte_dce): ...new function.
+ (pass_lower_subreg2): Replace declaration with that of...
+ (make_pass_lower_subreg2): ...new function.
+ (pass_mode_switching): Replace declaration with that of...
+ (make_pass_mode_switching): ...new function.
+ (pass_sms): Replace declaration with that of...
+ (make_pass_sms): ...new function.
+ (pass_sched): Replace declaration with that of...
+ (make_pass_sched): ...new function.
+ (pass_ira): Replace declaration with that of...
+ (make_pass_ira): ...new function.
+ (pass_reload): Replace declaration with that of...
+ (make_pass_reload): ...new function.
+ (pass_clean_state): Replace declaration with that of...
+ (make_pass_clean_state): ...new function.
+ (pass_branch_prob): Replace declaration with that of...
+ (make_pass_branch_prob): ...new function.
+ (pass_value_profile_transformations): Replace declaration with that
+ of...
+ (make_pass_value_profile_transformations): ...new function.
+ (pass_postreload_cse): Replace declaration with that of...
+ (make_pass_postreload_cse): ...new function.
+ (pass_gcse2): Replace declaration with that of...
+ (make_pass_gcse2): ...new function.
+ (pass_split_after_reload): Replace declaration with that of...
+ (make_pass_split_after_reload): ...new function.
+ (pass_branch_target_load_optimize1): Replace declaration with that
+ of...
+ (make_pass_branch_target_load_optimize1): ...new function.
+ (pass_thread_prologue_and_epilogue): Replace declaration with that
+ of...
+ (make_pass_thread_prologue_and_epilogue): ...new function.
+ (pass_stack_adjustments): Replace declaration with that of...
+ (make_pass_stack_adjustments): ...new function.
+ (pass_peephole2): Replace declaration with that of...
+ (make_pass_peephole2): ...new function.
+ (pass_if_after_reload): Replace declaration with that of...
+ (make_pass_if_after_reload): ...new function.
+ (pass_regrename): Replace declaration with that of...
+ (make_pass_regrename): ...new function.
+ (pass_cprop_hardreg): Replace declaration with that of...
+ (make_pass_cprop_hardreg): ...new function.
+ (pass_reorder_blocks): Replace declaration with that of...
+ (make_pass_reorder_blocks): ...new function.
+ (pass_branch_target_load_optimize2): Replace declaration with that
+ of...
+ (make_pass_branch_target_load_optimize2): ...new function.
+ (pass_leaf_regs): Replace declaration with that of...
+ (make_pass_leaf_regs): ...new function.
+ (pass_split_before_sched2): Replace declaration with that of...
+ (make_pass_split_before_sched2): ...new function.
+ (pass_compare_elim_after_reload): Replace declaration with that of...
+ (make_pass_compare_elim_after_reload): ...new function.
+ (pass_sched2): Replace declaration with that of...
+ (make_pass_sched2): ...new function.
+ (pass_stack_regs): Replace declaration with that of...
+ (make_pass_stack_regs): ...new function.
+ (pass_stack_regs_run): Replace declaration with that of...
+ (make_pass_stack_regs_run): ...new function.
+ (pass_df_finish): Replace declaration with that of...
+ (make_pass_df_finish): ...new function.
+ (pass_compute_alignments): Replace declaration with that of...
+ (make_pass_compute_alignments): ...new function.
+ (pass_duplicate_computed_gotos): Replace declaration with that of...
+ (make_pass_duplicate_computed_gotos): ...new function.
+ (pass_variable_tracking): Replace declaration with that of...
+ (make_pass_variable_tracking): ...new function.
+ (pass_free_cfg): Replace declaration with that of...
+ (make_pass_free_cfg): ...new function.
+ (pass_machine_reorg): Replace declaration with that of...
+ (make_pass_machine_reorg): ...new function.
+ (pass_cleanup_barriers): Replace declaration with that of...
+ (make_pass_cleanup_barriers): ...new function.
+ (pass_delay_slots): Replace declaration with that of...
+ (make_pass_delay_slots): ...new function.
+ (pass_split_for_shorten_branches): Replace declaration with that of...
+ (make_pass_split_for_shorten_branches): ...new function.
+ (pass_split_before_regstack): Replace declaration with that of...
+ (make_pass_split_before_regstack): ...new function.
+ (pass_convert_to_eh_region_ranges): Replace declaration with that
+ of...
+ (make_pass_convert_to_eh_region_ranges): ...new function.
+ (pass_shorten_branches): Replace declaration with that of...
+ (make_pass_shorten_branches): ...new function.
+ (pass_set_nothrow_function_flags): Replace declaration with that of...
+ (make_pass_set_nothrow_function_flags): ...new function.
+ (pass_dwarf2_frame): Replace declaration with that of...
+ (make_pass_dwarf2_frame): ...new function.
+ (pass_final): Replace declaration with that of...
+ (make_pass_final): ...new function.
+ (pass_rtl_seqabstr): Replace declaration with that of...
+ (make_pass_rtl_seqabstr): ...new function.
+ (pass_release_ssa_names): Replace declaration with that of...
+ (make_pass_release_ssa_names): ...new function.
+ (pass_early_inline): Replace declaration with that of...
+ (make_pass_early_inline): ...new function.
+ (pass_inline_parameters): Replace declaration with that of...
+ (make_pass_inline_parameters): ...new function.
+ (pass_update_address_taken): Replace declaration with that of...
+ (make_pass_update_address_taken): ...new function.
+ (pass_convert_switch): Replace declaration with that of...
+ (make_pass_convert_switch): ...new function.
+ * tree-profile.c (pass_ipa_tree_profile): Convert from a global struct
+ to a subclass of simple_ipa_opt_pass along with...
+ (pass_data_ipa_tree_profile): ...new pass_data instance and...
+ (make_pass_ipa_tree_profile): ...new function.
+ * tree-sra.c (pass_sra_early): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_sra_early): ...new pass_data instance and...
+ (make_pass_sra_early): ...new function.
+ (pass_sra): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_sra): ...new pass_data instance and...
+ (make_pass_sra): ...new function.
+ (pass_early_ipa_sra): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_early_ipa_sra): ...new pass_data instance and...
+ (make_pass_early_ipa_sra): ...new function.
+ * tree-ssa-ccp.c (pass_ccp): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_ccp): ...new pass_data instance and...
+ (make_pass_ccp): ...new function.
+ (pass_fold_builtins): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_fold_builtins): ...new pass_data instance and...
+ (make_pass_fold_builtins): ...new function.
+ * tree-ssa-copy.c (pass_copy_prop): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_copy_prop): ...new pass_data instance and...
+ (make_pass_copy_prop): ...new function.
+ * tree-ssa-copyrename.c (pass_rename_ssa_copies): Convert from a
+ global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_rename_ssa_copies): ...new pass_data instance and...
+ (make_pass_rename_ssa_copies): ...new function.
+ * tree-ssa-dce.c (pass_dce): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_dce): ...new pass_data instance and...
+ (make_pass_dce): ...new function.
+ (pass_dce_loop): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_dce_loop): ...new pass_data instance and...
+ (make_pass_dce_loop): ...new function.
+ (pass_cd_dce): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_cd_dce): ...new pass_data instance and...
+ (make_pass_cd_dce): ...new function.
+ * tree-ssa-dom.c (pass_dominator): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_dominator): ...new pass_data instance and...
+ (make_pass_dominator): ...new function.
+ (pass_phi_only_cprop): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_phi_only_cprop): ...new pass_data instance and...
+ (make_pass_phi_only_cprop): ...new function.
+ * tree-ssa-dse.c (pass_dse): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_dse): ...new pass_data instance and...
+ (make_pass_dse): ...new function.
+ * tree-ssa-forwprop.c (pass_forwprop): Convert from a global struct to
+ a subclass of gimple_opt_pass along with...
+ (pass_data_forwprop): ...new pass_data instance and...
+ (make_pass_forwprop): ...new function.
+ * tree-ssa-ifcombine.c (pass_tree_ifcombine): Convert from a global
+ struct to a subclass of gimple_opt_pass along with...
+ (pass_data_tree_ifcombine): ...new pass_data instance and...
+ (make_pass_tree_ifcombine): ...new function.
+ * tree-ssa-loop-ch.c (pass_ch): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_ch): ...new pass_data instance and...
+ (make_pass_ch): ...new function.
+ * tree-ssa-loop.c (pass_tree_loop): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_tree_loop): ...new pass_data instance and...
+ (make_pass_tree_loop): ...new function.
+ (pass_tree_loop_init): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tree_loop_init): ...new pass_data instance and...
+ (make_pass_tree_loop_init): ...new function.
+ (pass_lim): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_lim): ...new pass_data instance and...
+ (make_pass_lim): ...new function.
+ (pass_tree_unswitch): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tree_unswitch): ...new pass_data instance and...
+ (make_pass_tree_unswitch): ...new function.
+ (pass_predcom): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_predcom): ...new pass_data instance and...
+ (make_pass_predcom): ...new function.
+ (pass_vectorize): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_vectorize): ...new pass_data instance and...
+ (make_pass_vectorize): ...new function.
+ (pass_graphite): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_graphite): ...new pass_data instance and...
+ (make_pass_graphite): ...new function.
+ (pass_graphite_transforms): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_graphite_transforms): ...new pass_data instance and...
+ (make_pass_graphite_transforms): ...new function.
+ (pass_check_data_deps): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_check_data_deps): ...new pass_data instance and...
+ (make_pass_check_data_deps): ...new function.
+ (pass_iv_canon): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_iv_canon): ...new pass_data instance and...
+ (make_pass_iv_canon): ...new function.
+ (pass_scev_cprop): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_scev_cprop): ...new pass_data instance and...
+ (make_pass_scev_cprop): ...new function.
+ (pass_record_bounds): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_record_bounds): ...new pass_data instance and...
+ (make_pass_record_bounds): ...new function.
+ (pass_complete_unroll): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_complete_unroll): ...new pass_data instance and...
+ (make_pass_complete_unroll): ...new function.
+ (pass_complete_unrolli): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_complete_unrolli): ...new pass_data instance and...
+ (make_pass_complete_unrolli): ...new function.
+ (pass_parallelize_loops): Convert from a global struct to a subclass
+ of gimple_opt_pass along with...
+ (pass_data_parallelize_loops): ...new pass_data instance and...
+ (make_pass_parallelize_loops): ...new function.
+ (pass_loop_prefetch): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_loop_prefetch): ...new pass_data instance and...
+ (make_pass_loop_prefetch): ...new function.
+ (pass_iv_optimize): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_iv_optimize): ...new pass_data instance and...
+ (make_pass_iv_optimize): ...new function.
+ (pass_tree_loop_done): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tree_loop_done): ...new pass_data instance and...
+ (make_pass_tree_loop_done): ...new function.
+ * tree-ssa-math-opts.c (pass_cse_reciprocals): Convert from a global
+ struct to a subclass of gimple_opt_pass along with...
+ (pass_data_cse_reciprocals): ...new pass_data instance and...
+ (make_pass_cse_reciprocals): ...new function.
+ (pass_cse_sincos): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_cse_sincos): ...new pass_data instance and...
+ (make_pass_cse_sincos): ...new function.
+ (pass_optimize_bswap): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_optimize_bswap): ...new pass_data instance and...
+ (make_pass_optimize_bswap): ...new function.
+ (pass_optimize_widening_mul): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_optimize_widening_mul): ...new pass_data instance and...
+ (make_pass_optimize_widening_mul): ...new function.
+ * tree-ssa-phiopt.c (pass_phiopt): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_phiopt): ...new pass_data instance and...
+ (make_pass_phiopt): ...new function.
+ (pass_cselim): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_cselim): ...new pass_data instance and...
+ (make_pass_cselim): ...new function.
+ * tree-ssa-phiprop.c (pass_phiprop): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_phiprop): ...new pass_data instance and...
+ (make_pass_phiprop): ...new function.
+ * tree-ssa-pre.c (pass_pre): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_pre): ...new pass_data instance and...
+ (make_pass_pre): ...new function.
+ (pass_fre): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_fre): ...new pass_data instance and...
+ (make_pass_fre): ...new function.
+ * tree-ssa-reassoc.c (pass_reassoc): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_reassoc): ...new pass_data instance and...
+ (make_pass_reassoc): ...new function.
+ * tree-ssa-sink.c (pass_sink_code): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_sink_code): ...new pass_data instance and...
+ (make_pass_sink_code): ...new function.
+ * tree-ssa-strlen.c (pass_strlen): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_strlen): ...new pass_data instance and...
+ (make_pass_strlen): ...new function.
+ * tree-ssa-structalias.c (pass_build_alias): Convert from a global
+ struct to a subclass of gimple_opt_pass along with...
+ (pass_data_build_alias): ...new pass_data instance and...
+ (make_pass_build_alias): ...new function.
+ (pass_build_ealias): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_build_ealias): ...new pass_data instance and...
+ (make_pass_build_ealias): ...new function.
+ (pass_ipa_pta): Convert from a global struct to a subclass of
+ simple_ipa_opt_pass along with...
+ (pass_data_ipa_pta): ...new pass_data instance and...
+ (make_pass_ipa_pta): ...new function.
+ * tree-ssa-uncprop.c (pass_uncprop): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_uncprop): ...new pass_data instance and...
+ (make_pass_uncprop): ...new function.
+ * tree-ssa-uninit.c (pass_late_warn_uninitialized): Convert from a
+ global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_late_warn_uninitialized): ...new pass_data instance and...
+ (make_pass_late_warn_uninitialized): ...new function.
+ * tree-ssa.c (pass_init_datastructures): Convert from a global struct
+ to a subclass of gimple_opt_pass along with...
+ (pass_data_init_datastructures): ...new pass_data instance and...
+ (make_pass_init_datastructures): ...new function.
+ (pass_early_warn_uninitialized): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_early_warn_uninitialized): ...new pass_data instance and...
+ (make_pass_early_warn_uninitialized): ...new function.
+ (pass_update_address_taken): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_update_address_taken): ...new pass_data instance and...
+ (make_pass_update_address_taken): ...new function.
+ * tree-ssanames.c (pass_release_ssa_names): Convert from a global
+ struct to a subclass of gimple_opt_pass along with...
+ (pass_data_release_ssa_names): ...new pass_data instance and...
+ (make_pass_release_ssa_names): ...new function.
+ * tree-stdarg.c (pass_stdarg): Convert from a global struct to a
+ subclass of gimple_opt_pass along with...
+ (pass_data_stdarg): ...new pass_data instance and...
+ (make_pass_stdarg): ...new function.
+ * tree-switch-conversion.c (pass_convert_switch): Convert from a
+ global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_convert_switch): ...new pass_data instance and...
+ (make_pass_convert_switch): ...new function.
+ * tree-tailcall.c (pass_tail_recursion): Convert from a global struct
+ to a subclass of gimple_opt_pass along with...
+ (pass_data_tail_recursion): ...new pass_data instance and...
+ (make_pass_tail_recursion): ...new function.
+ (pass_tail_calls): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tail_calls): ...new pass_data instance and...
+ (make_pass_tail_calls): ...new function.
+ * tree-vect-generic.c (pass_lower_vector): Convert from a global
+ struct to a subclass of gimple_opt_pass along with...
+ (pass_data_lower_vector): ...new pass_data instance and...
+ (make_pass_lower_vector): ...new function.
+ (pass_lower_vector_ssa): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_lower_vector_ssa): ...new pass_data instance and...
+ (make_pass_lower_vector_ssa): ...new function.
+ * tree-vectorizer.c (pass_slp_vectorize): Convert from a global struct
+ to a subclass of gimple_opt_pass along with...
+ (pass_data_slp_vectorize): ...new pass_data instance and...
+ (make_pass_slp_vectorize): ...new function.
+ (pass_ipa_increase_alignment): Convert from a global struct to a
+ subclass of simple_ipa_opt_pass along with...
+ (pass_data_ipa_increase_alignment): ...new pass_data instance and...
+ (make_pass_ipa_increase_alignment): ...new function.
+ * tree-vrp.c (pass_vrp): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_vrp): ...new pass_data instance and...
+ (make_pass_vrp): ...new function.
+ * tree.c (pass_ipa_free_lang_data): Convert from a global struct to a
+ subclass of simple_ipa_opt_pass along with...
+ (pass_data_ipa_free_lang_data): ...new pass_data instance and...
+ (make_pass_ipa_free_lang_data): ...new function.
+ * tsan.c (pass_tsan): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tsan): ...new pass_data instance and...
+ (make_pass_tsan): ...new function.
+ (pass_tsan_O0): Convert from a global struct to a subclass of
+ gimple_opt_pass along with...
+ (pass_data_tsan_O0): ...new pass_data instance and...
+ (make_pass_tsan_O0): ...new function.
+ * var-tracking.c (pass_variable_tracking): Convert from a global
+ struct to a subclass of rtl_opt_pass along with...
+ (pass_data_variable_tracking): ...new pass_data instance and...
+ (make_pass_variable_tracking): ...new function.
+ * web.c (pass_web): Convert from a global struct to a subclass of
+ rtl_opt_pass along with...
+ (pass_data_web): ...new pass_data instance and...
+ (make_pass_web): ...new function.
+ * config/epiphany/epiphany.h (pass_mode_switch_use): Replace
+ declaration with that of...
+ (make_pass_mode_switch_use): ...new function.
+ (pass_resolve_sw_modes): Replace declaration with that of...
+ (make_pass_resolve_sw_modes): ...new function.
+ * config/epiphany/mode-switch-use.c (pass_mode_switch_use): Convert
+ from a global struct to a subclass of rtl_opt_pass along with...
+ (pass_data_mode_switch_use): ...new pass_data instance and...
+ (make_pass_mode_switch_use): ...new function.
+ * config/epiphany/resolve-sw-modes.c (pass_resolve_sw_modes): Convert
+ from a global struct to a subclass of rtl_opt_pass along with...
+ (pass_data_resolve_sw_modes): ...new pass_data instance and...
+ (make_pass_resolve_sw_modes): ...new function.
+ * config/i386/i386.c (pass_insert_vzeroupper): Convert from a global
+ struct to a subclass of rtl_opt_pass along with...
+ (pass_data_insert_vzeroupper): ...new pass_data instance and...
+ (make_pass_insert_vzeroupper): ...new function.
+ * config/sparc/sparc.c (pass_work_around_errata): Convert from a
+ global struct to a subclass of rtl_opt_pass along with...
+ (pass_data_work_around_errata): ...new pass_data instance and...
+ (make_pass_work_around_errata): ...new function.
+ * config/mips/mips.c (pass_mips_machine_reorg2): Convert from a global
+ struct to a subclass of rtl_opt_pass along with...
+ (pass_data_mips_machine_reorg2): ...new pass_data instance and...
+ (make_pass_mips_machine_reorg2): ...new function.
+
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ * passes.c (pass_manager::operator new): New.
+
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ Handwritten part of conversion of passes to C++ classes.
+
+ * Makefile.in (PASS_MANAGER_H): Add dep on pass-instances.def.
+ (toplev.o): Add dep on PASS_MANAGER_H.
+ * cgraphunit.c (cgraph_process_new_functions): Rework invocation
+ of early local pases to reflect this moving from a global to a
+ member of gcc::pass_manager.
+ (cgraph_add_new_function): Likewise.
+ * lto-cgraph.c (lto_output_node): Update for conversion of
+ struct ipa_opt_pass_d to a C++ subclass of opt_pass.
+ * passes.c (opt_pass::clone): New.
+ (opt_pass::gate): New.
+ (opt_pass::execute): New.
+ (opt_pass::opt_pass): New.
+ (pass_manager::execute_early_local_passes): New.
+ (pass_manager::execute_pass_mode_switching): new.
+ (finish_optimization_passes): Convert to...
+ (pass_manager::finish_optimization_passes): ...this.
+ (finish_optimization_passes): Update for conversion of passes to
+ C++ classes.
+ (register_dump_files_1): Use has_gate since we cannot portably
+ check a vtable entry against NULL.
+ (dump_one_pass): Likewise.
+ (ipa_write_summaries_2): Likewise.
+ (ipa_write_optimization_summaries_1): Likewise.
+ (ipa_read_summaries_1): Likewise.
+ (ipa_read_optimization_summaries_1): Likewise.
+ (execute_ipa_stmt_fixups): Likewise.
+ (pass_manager::pass_manager): Rewrite pass-creation, invoking
+ pass-creation functions rather than wiring up globals, and
+ storing the results in fields of pass_manager generated using
+ pass-instances.def.
+ (pass_manager::dump_profile_report): Update for conversion of
+ passes to C++ classes.
+ (pass_manager::execute_ipa_summary_passes): Likewise.
+ (execute_one_ipa_transform_pass): Likewise.
+ (execute_one_pass): Use has_gate and has_execute since we cannot
+ portably check a vtable entry against NULL.
+ * pass_manager.h (pass_manager::finish_optimization_passes): New.
+ (pass_manager): Use pass-instances.def to add fields for the
+ various pass instances.
+ * toplev.c (finalize): Update for move of
+ finish_optimization_passes to a method of gcc::pass_manager.
+ * toplev.h (finish_optimization_passes): Move to method of class
+ pass_manager.
+ * tree-pass.h (struct pass_data): New.
+ (opt_pass): Convert to C++ class, make it a subclass of pass_data.
+ (opt_pass::gate): Convert to virtual function.
+ (opt_pass::~opt_pass): New.
+ (opt_pass::clone): New.
+ (opt_pass::execute): Convert to virtual function.
+ (opt_pass::opt_pass): New.
+ (opt_pass::ctxt_): new.
+ (gimple_opt_pass): Convert to subclass of opt_pass.
+ (gimple_opt_pass::gimple_opt_pass): New.
+ (rtl_opt_pass): Convert to subclass of opt_pass.
+ (rtl_opt_pass::rtl_opt_pass): New.
+ (ipa_opt_pass_d): Convert to subclass of opt_pass.
+ (ipa_opt_pass_d::ipa_opt_pass_d): New.
+ (simple_ipa_opt_pass): Convert to subclass of opt_pass.
+ (simple_ipa_opt_pass::simple_ipa_opt_pass): New.
+ * config/i386/i386.c (rest_of_handle_insert_vzeroupper): Rework
+ invocation of pass_mode_switching to reflect this moving from a
+ global to a member of gcc::pass_manager.
+ (ix86_option_override): Rework how pass_insert_vzeroupper is
+ added to the pass_manager to reflect autogenerated changes.
+ * config/i386/t-i386 (i386.o) Add deps on CONTEXT_H and PASS_MANAGER_H.
+
+2013-08-05 Richard Earnshaw <rearnsha@arm.com>
+
+ PR rtl-optimization/57708
+ * recog.c (peep2_find_free_register): Validate all regs in a
+ multi-reg mode.
+
+2013-08-05 Jan Hubicka <jh@suse.cz>
+
+ PR lto/57602
+ * cgraph.c (verify_cgraph_node): Accept local flags from other
+ partitions.
+ * ipa.c (symtab_remove_unreachable_nodes): Do not clear local flag.
+ (function_and_variable_visibility): Likewise.
+ * trans-mem.c (ipa_tm_create_version): TM versions are not local.
+
+2013-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * graph.c (init_graph_slim_pretty_print): Remove.
+ (print_graph_cfg): Do not call it. Use local pretty printer.
+ (start_graph_dump): Likewise.
+
+2013-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * gimple-pretty-print.c (buffer): Remove.
+ (initialized): Likewise.
+ (maybe_init_pretty_print): Likewise.
+ (print_gimple_stmt): Do not call it. Use non-static local
+ pretty_printer variable.
+ (print_gimple_expr): Likewise.
+ (print_gimple_seq): Likewise.
+ (gimple_dump_bb): Likewise.
+
+2013-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * asan.c (asan_pp): Remove.
+ (asan_pp_initialized): Likewise.
+ (asan_pp_initialize): Likewise.
+ (asan_pp_string): Take a pretty_printer parameter. Adjust callers.
+ (asan_emit_stack_protection): Tidy. Use local pretty printer.
+ (asan_add_global): Likewise.
+
+2013-08-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (pp_base): Remove. Adjust dependent macros.
+ * diagnostic.h (diagnostic_flush_buffer): Adjust.
+ * pretty-print.c (pp_formatted_text_data): Likewise.
+ (pp_indent): Rename from pp_base_indent.
+ (pp_format): Rename from pp_base_format.
+ (pp_output_formatted_text): Rename from pp_base_output_formatted_text.
+ (pp_format_verbatim): Rename from pp_base_format_verbatim.
+ (pp_flush): Rename from pp_base_flush.
+ (pp_set_line_maximum_length): Rename from
+ pp_base_set_line_maximum_length.
+ (pp_clear_output_area): Rename from pp_base_clear_output_area.
+ (pp_set_prefix): Rename from pp_base_set_prefix.
+ (pp_destroy_prefix): Rename from pp_base_destroy_prefix.
+ (pp_emit_prefix): Rename from pp_base_emit_prefix.
+ (pp_append_text): Rename from pp_base_append_text.
+ (pp_formatted_text): Rename from pp_base_formatted_text.
+ (pp_last_position_in_text): Rename from pp_base_last_position_in_text.
+ (pp_remaining_character_count_for_line): Rename from
+ pp_base_remaining_character_count_for_line.
+ (pp_newline): Rename from pp_base_newline.
+ (pp_character): Rename from pp_base_character.
+ (pp_string): Rename from pp_base_string.
+ (pp_maybe_space): Rename from pp_base_maybe_space.
+ * asan.c (asan_pp_string): Adjust.
+ (asan_emit_stack_protection): Likewise.
+ (asan_add_global): Likewise.
+ * sched-vis.c (str_pattern_slim): Adjust pretty printer function call.
+ * tree-mudflap.c (mf_varname_tree): Likewise.
+ * tree-pretty-print.c (pp_tree_identifier): Rename from
+ pp_base_tree_identifier.
+ * tree-pretty-print.h (pp_tree_identifier): Remove macro definition.
+ Declare as function.
+
+2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (pp_bar_bar): New.
+ (pp_ampersand_ampersand): Likewise.
+ (pp_less_equal): Likewise.
+ (pp_greater_equal): Likewise.
+ * gimple-pretty-print.c (dump_ternary_rhs): Use specialized pretty
+ printer functions instead of pp_string or operators and punctuators.
+ (dump_gimple_call): Likewise.
+ (dump_gimple_omp_for): Likewise.
+ (dump_gimple_transaction): Likewise.
+ (dump_gimple_phi): Likewise.
+ (pp_gimple_stmt_1): Likewise.
+ * sched-vis.c (print_insn): Likewise.
+ * tree-mudflap.c (mf_varname_tree): Likewise.
+ * tree-pretty-print.c (dump_block_node): Likewise.
+ (dump_generic_node): Likewise.
+
+2013-08-02 Jan Hubicka <jh@suse.cz>
+
+ * lto-cgraph.c (compute_ltrans_boundary): Add abstract origins into
+ boundaries.
+ * lto-streamer-out.c (tree_is_indexable): Results decls and
+ parm decls are not indexable.
+ (DFS_write_tree_body): Do not follow args and results.
+ (hash_tree): Likewise.
+ (output_functions): Rearrange so struct function is needed
+ only when real body is output; be able to also ouptut abstract
+ functions; output DECL_ARGUMENTS and DECL_RESULT.
+ (lto_output): When not in WPA, ale store abstract functions.
+ (write_symbol): Do not care about RESULT_DECL.
+ (output_symbol_p): Handle correctly sbtract decls.
+ * lto-streamer-in.c (input_function): Rearrange so struct
+ function can be NULL at entry; allow streaming of
+ functions w/o body; store DECL_ARGUMENTS and DECL_RESULT.
+ * ipa.c (symtab_remove_unreachable_nodes): Silence confused
+ sanity check during LTO.
+ * tree-streamer-out.c (write_ts_decl_non_common_tree_pointers): Skip
+ RESULT_DECl and DECL_ARGUMENTS.
+ * tree-streamer-in.c (lto_input_ts_decl_non_common_tree_pointers):
+ Likewise.
+
+2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * pretty-print.h (pp_underscore): New.
+ (pp_comma): Tidy.
+ * gimple-pretty-print.c (dump_unary_rhs): Use specialized pretty
+ printer functions instead of pp_character.
+ (dump_binary_rhs): Likewise.
+ (dump_ternary_rhs): Likewise.
+ (dump_gimple_call_args): Likewise.
+ (pp_points_to_solution): Likewise.
+ (dump_gimple_call): Likewise.
+ (dump_gimple_switch): Likewise.
+ (dump_gimple_cond): Likewise.
+ (dump_gimple_bind): Likewise.
+ (dump_gimple_try): Likewise.
+ (dump_gimple_omp_for): Likewise.
+ (dump_gimple_omp_continue): Likewise.
+ (dump_gimple_omp_single): Likewise.
+ (dump_gimple_omp_sections): Likewise.
+ (dump_gimple_omp_block): Likewise.
+ (dump_gimple_omp_critical): Likewise.
+ (dump_gimple_transaction): Likewise.
+ (dump_gimple_asm): Likewise.
+ (dump_gimple_phi): Likewise.
+ (dump_gimple_omp_parallel): Likewise.
+ (dump_gimple_omp_task): Likewise.
+ (dump_gimple_omp_atomic_load): Likewise.
+ (dump_gimple_omp_atomic_store): Likewise.
+ (dump_gimple_mem_ops): Likewise.
+ (pp_gimple_stmt_1): Likewise.
+ (pp_cfg_jump): Likewise.
+ (dump_implicit_edges): Likewise.
+ (gimple_dump_bb_for_graph): Likewise.
+ * graph.c (draw_cfg_node): Likewise.
+ * langhooks.c (lhd_print_error_function): Likewise.
+ * sched-vis.c (print_exp): Likewise.
+ (print_value): Likewise.
+ (print_pattern): Likewise.
+ (print_insn): Likewise.
+ (rtl_dump_bb_for_graph): Likewise.
+ * tree-pretty-print.c (dump_function_declaration): Likewise.
+ (dump_array_domain): Likewise.
+ (dump_omp_clause): Likewise.
+ (dump_location): Likewise.
+ (dump_generic_node): Likewise.
+ (print_struct_decl): Likewise.
+ * diagnostic.c (diagnostic_show_locus): Use pp_space.
+
+2013-08-03 Bill Schmidt <wschmidt@vnet.linux.ibm.com>
+
+ * gimple-ssa-strength-reduction.c (replace_mult_candidate): Update
+ candidate table when replacing a candidate statement.
+ (replace_rhs_if_not_dup): Likewise.
+ (replace_one_candidate): Likewise.
+
+2013-08-02 Jan Hubicka <jh@suse.cz>
+ Martin Liska <marxin.liska@gmail.com>
+
+ * cgraphunit.c (add_new_function): Fix logic when adding from
+ late IPA pass.
+ (assemble_thunk): Rename to ...
+ (expand_thunk); .. this one; export; get it working with
+ general functions; make produced gimple valid.
+ * cgraph.h (expand_thunk): Declare.
+
+2013-08-02 Jan Hubicka <jh@suse.cz>
+
+ * ipa-cp.c (gather_context_independent_values): Use
+ ipa_get_param_move_cost.
+ (get_replacement_map): Remove PARAM; move parameter folding
+ into tree-inline.c
+ (create_specialized_node): Update.
+ * ipa-prop.c (ipa_populate_param_decls): Do not look for origins;
+ assert that we have gimple body; update move_cost.
+ (count_formal_params): Assert that we have gimple body.
+ (ipa_dump_param): New function.
+ (ipa_alloc_node_params): Break out from ...
+ (ipa_initialize_node_params): ... here.
+ (ipa_get_vector_of_formal_parms): ICE when used in WPA.
+ (ipa_write_node_info): Stream move costs.
+ (ipa_read_node_info): Read move costs.
+ (ipa_update_after_lto_read): Do not recompute node params.
+ * ipa-prop.h (ipa_param_descriptor): Add move_cost.
+ (ipa_get_param): Check we are not in WPA.
+ (ipa_get_param_move_cost): New.
+ * tree-inline.c (tree_function_versioning): Fold replacement as needed.
+ * ipa-inline-analysis.c (inline_node_duplication_hook): Expect only
+ parm numbers to be present.
+
+2013-08-02 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/58048
+ * lra-constraints.c (process_alt_operands): Don't check asm
+ operand on register.
+
+2013-08-02 Eric Botcazou <ebotcazou@adacore.com>
+
+ * config/sparc/sparc.c (sparc_emit_membar_for_model) <SMM_TSO>: Add
+ the implied StoreLoad barrier for atomic operations if before.
+
+2013-08-02 Jan Hubicka <jh@suse.cz>
+ Martin Liska <marxin.liska@gmail.com>
+
+ * cgraph.c (cgraph_function_body_availability): Do not check
+ cgraph flags.
+ * cgraph.h (symtab_for_node_and_aliases, symtab_nonoverwritable_alias,
+ symtab_node_availability): Declare.
+ * ipa.c (can_replace_by_local_alias): New.
+ (function_and_variable_visibility): Use it.
+ * symtab.c (symtab_for_node_and_aliases,
+ symtab_nonoverwritable_alias_1, symtab_nonoverwritable_alias): New.
+
+2013-08-02 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/57963
+ * lra-constraints.c (reverse_equiv_p, contains_reloaded_insn_p): New.
+ (lra_constraints): Use them.
+
+2013-08-02 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/arm/types.md (define_attr "type"): Add "load_acq"
+ and "store_rel".
+ * config/arm/cortex-a53.md (cortex_a53_load1): Update for attribute
+ changes.
+ (cortex_a53_store1): Likewise.
+
+2013-08-01 Jan Hubicka <jh@suse.cz>
+
+ * ipa.c (symtab_remove_unreachable_nodes): Nodes in other
+ partitions are not needed.
+
+2013-08-01 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.h (MAYBE_NON_Q_CLASS_P): New.
+ * config/i386/i386.c (ix86_secondary_reload): Use INTEGER_CLASS_P and
+ MAYBE_NON_Q_CLASS_P where appropriate.
+
+2013-08-01 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.h (release_function_body): Declare.
+ * tree.c (free_lang_data_in_decl): Free, parameters and return values
+ of unused delcarations.
+
+2013-08-01 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.md (minmax_arithsi_non_canon): Emit canonical
+ RTL form when subtracting a constant.
+
+2013-08-01 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.md (peepholes for eq (reg1) (reg2/imm)):
+ Generate canonical plus rtx with negated immediate instead of minus
+ where appropriate.
+ * config/arm/arm.c (thumb2_reorg): Handle ADCS <Rd>, <Rn> case.
+
+2013-08-01 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_release_function_body): Use used_as_abstract_origin.
+ (cgraph_release_function_body): Likewise.
+ (cgraph_can_remove_if_no_direct_calls_p): Likewise.
+ * cgraph.h (cgrpah_node): Rename abstract_and_needed
+ to used_as_abstract_origin.
+ * tree-inline-transfrom.c (can_remove_node_now_p_1): Do not remove
+ symbols used as abstract origins.
+ * cgraphunit.c (analyze_functions): Update.
+ * ipa.c (symtab_remove_unreachable_nodes): Recompute
+ used_as_abstract_origin.
+ * tree-inline.c (tree_function_versioning): Update
+ used_as_abstract_origin; be ready for DECL_RESULT and
+ DECL_ARGUMENTS to be NULL.
+
+ * lto-symtab.c (lto_symtab_merge_symbols): Merge duplicated nodes
+ for abstract functions.
+ * cgraph.h (symtab_real_symbol_p): Abstract declarations are not
+ real symbols.
+
+2013-08-01 Jan Hubicka <jh@suse.cz>
+
+ * profile.c (compute_value_histograms): Fix thinko.
+
+2013-08-01 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config.gcc (aarch64*-*-*): Add aarch-common.o to extra_objs. Add
+ aarch-common-protos.h to extra_headers.
+ (aarch64*-*-*): Add arm/aarch-common-protos.h to tm_p_file.
+ * config/aarch64/aarch64.md: Include "../arm/cortex-a53.md".
+ * config/aarch64/t-aarch64 (aarch-common.o): Define.
+
+2013-08-01 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/aarch64/aarch64.md (define_attr "type"): Delete.
+ Include "../arm/types.md". Define "type" attribute for all patterns.
+ * config/aarch64/aarch64-simd.md (move_lo_quad_<mode>): Update for
+ attribute changes.
+
+2013-07-31 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * config/rs6000/predicates.md (fusion_gpr_addis): New predicates
+ to support power8 load fusion.
+ (fusion_gpr_mem_load): Likewise.
+
+ * config/rs6000/rs6000-modes.def (PTImode): Update a comment.
+
+ * config/rs6000/rs6000-protos.h (fusion_gpr_load_p): New
+ declarations for power8 load fusion.
+ (emit_fusion_gpr_load): Likewise.
+
+ * config/rs6000/rs6000.c (rs6000_option_override_internal): If
+ tuning for power8, turn on fusion mode by default. Turn on sign
+ extending fusion mode if normal fusion mode is on, and we are at
+ -O2 or -O3.
+ (fusion_gpr_load_p): New function, return true if we can fuse an
+ addis instruction with a dependent load to a GPR.
+ (emit_fusion_gpr_load): Emit the instructions for power8 load
+ fusion to GPRs.
+
+ * config/rs6000/vsx.md (VSX_M2): New iterator for fusion peepholes.
+ (VSX load fusion peepholes): New peepholes to fuse together an
+ addi instruction with a VSX load instruction.
+
+ * config/rs6000/rs6000.md (GPR load fusion peepholes): New
+ peepholes to fuse an addis instruction with a load to a GPR base
+ register. If we are supporting sign extending fusions, convert
+ sign extending loads to zero extending loads and add an explicit
+ sign extension.
+
+2013-07-31 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config.gcc (arm*-*-*): Add aarch-common.o to extra_objs. Add
+ aarch-common-protos.h to extra_headers.
+ (arm*-*-*): Add arm/aarch-common-protos.h to tm_p_file.
+ * config/arm/arm.c (arm_early_load_addr_dep): Move from here to ...
+ (arm_early_store_addr_dep): Likewise.
+ (arm_no_early_alu_shift_dep): Likewise.
+ (arm_no_early_alu_shift_value_dep): Likewise.
+ (arm_no_early_mul_dep): Likewise.
+ (arm_no_early_store_addr_dep): Likewise.
+ (arm_mac_accumulator_is_mul_result): Likewise.
+ (arm_mac_accumulator_is_result): Likewise.
+ * config/arm/aarch-common.c: ... here. New file.
+ * config/arm/arm-protos.h (arm_early_load_addr_dep): Move from
+ here to ...
+ (arm_early_store_addr_dep): Likewise.
+ (arm_no_early_alu_shift_dep): Likewise.
+ (arm_no_early_alu_shift_value_dep): Likewise.
+ (arm_no_early_mul_dep): Likewise.
+ (arm_no_early_store_addr_dep): Likewise.
+ (arm_mac_accumulator_is_mul_result): Likewise.
+ (arm_mac_accumulator_is_result): Likewise.
+ * config/arm/aarch-common-protos.h: ... here. New file.
+ * config/arm/t-arm (aarch-common.o): Define.
+
+2013-07-31 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/arm/arm.md: Include new file "types.md".
+ (define_attr "type"): Move from here to ...
+ (define_attr "mul32"): Likewise.
+ (define_attr "mul64"): Likewise.
+ * config/arm/types.md: ... here. New file.
+
+2013-07-31 Sebastian Huber <sebastian.huber@embedded-brains.de>
+
+ * config.gcc (*-*-rtems*): Use __cxa_atexit by default.
+ * config/rs6000/rtems.h (TARGET_LIBGCC_SDATA_SECTION): Define.
+
+2013-07-31 Jan-Benedict Glaw <jbglaw@lug-owl.de>
+
+ * gen-pass-instances.awk: Fix offset of substr().
+
+2013-07-31 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (pass-instances.def): New.
+ (passes.o): Replace dependency on passes.def with one on
+ pass-instances.def
+
+ * gen-pass-instances.awk: New.
+
+ * passes.c (pass_manager::pass_manager): Use pass-instances.def
+ rather than passes.def, updating local definition of NEXT_PASS
+ macro to add an extra NUM parameter (currently unused).
+
+2013-07-30 David Malcolm <dmalcolm@redhat.com>
+
+ * Makefile.in (PASS_MANAGER_H): New.
+ (lto-cgraph.o): Depend on CONTEXT_H and PASS_MANAGER_H.
+ (passes.o): Likewise.
+ (statistics.o): Likewise.
+ (cgraphunit.o): Likewise.
+ (context.o): Depend on PASS_MANAGER_H.
+
+ * pass_manager.h: New.
+
+ * cgraphunit.c (cgraph_add_new_function): Update for moves
+ of globals to fields of pass_manager.
+ (analyze_function): Likewise.
+ (expand_function): Likewise.
+ (ipa_passes): Likewise.
+ (compile): Likewise.
+
+ * context.c (context::context): New.
+ * context.h (context::context): New.
+ (context::get_passes): New.
+ (context::passes_): New.
+
+ * lto-cgraph.c (input_node): Update for moves of globals to
+ fields of pass_manager.
+
+ * passes.c (all_passes): Remove, in favor of a field of the
+ same name within the new class pass_manager.
+ (all_small_ipa_passes): Likewise.
+ (all_lowering_passes): Likewise.
+ (all_regular_ipa_passes): Likewise.
+ (all_late_ipa_passes): Likewise.
+ (all_lto_gen_passes): Likewise.
+ (passes_by_id): Likewise.
+ (passes_by_id_size): Likewise.
+ (gcc_pass_lists): Remove, in favor of "pass_lists" field within
+ the new class pass_manager.
+ (set_pass_for_id): Convert to...
+ (pass_manager::set_pass_for_id): ...method.
+ (get_pass_for_id): Convert to...
+ (pass_manager::get_pass_for_id): ...method.
+ (register_one_dump_file): Move body of implementation into...
+ (pass_manager::register_one_dump_file): ...here.
+ (register_dump_files_1): Convert to...
+ (pass_manager::register_dump_files_1): ...method.
+ (register_dump_files): Convert to...
+ (pass_manager::register_dump_files): ...method.
+ (create_pass_tab): Update for moves of globals to fields of
+ pass_manager.
+ (dump_passes): Move body of implementation into...
+ (pass_manager::dump_passes): ...here.
+ (register_pass): Move body of implementation into...
+ (pass_manager::register_pass): ...here.
+ (init_optimization_passes): Convert into...
+ (pass_manager::pass_manager): ...constructor for new
+ pass_manager class, and initialize the pass_lists array.
+ (check_profile_consistency): Update for moves of globals to
+ fields of pass_manager.
+ (dump_profile_report): Move body of implementation into...
+ (pass_manager::dump_profile_report): ...here.
+ (ipa_write_summaries_1): Update for moves of pass lists from
+ being globals to fields of pass_manager.
+ (ipa_write_optimization_summaries): Likewise.
+ (ipa_read_summaries): Likewise.
+ (ipa_read_optimization_summaries): Likewise.
+ (execute_all_ipa_stmt_fixups): Likewise.
+
+ * statistics.c (statistics_fini): Update for moves of globals to
+ fields of pass_manager.
+
+ * toplev.c (general_init): Replace call to
+ init_optimization_passes with construction of the pass_manager
+ instance.
+
+ * tree-pass.h (all_passes): Remove, in favor of a field of the
+ same name within the new class pass_manager.
+ (all_small_ipa_passes): Likewise.
+ (all_lowering_passes): Likewise.
+ (all_regular_ipa_passes): Likewise.
+ (all_lto_gen_passes): Likewise.
+ (all_late_ipa_passes): Likewise.
+ (passes_by_id): Likewise.
+ (passes_by_id_size): Likewise.
+ (gcc_pass_lists): Remove, in favor of "pass_lists" field within
+ the new class pass_manager.
+ (get_pass_for_id): Remove.
+
+2013-07-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * config.gcc (arm): Require 64-bit host-wide-int for all ARM target
+ configs.
+
+2013-07-30 Richard Earnshaw <rearnsha@arm.com>
+
+ * arm.md (mulhi3): New expand pattern.
+
+2013-07-30 Jan Hubicka <jh@suse.cz>
+ Martin Liska <marxin.liska@gmail.com>
+
+ * profile.c (compute_value_histograms): Do not ICE when
+ there is mismatch only on some counters.
+
+2013-07-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ PR rtl-optimization/57637
+ * function.c (move_insn_for_shrink_wrap): Also check the
+ GEN set of the LIVE problem for the liveness analysis
+ if it exists, otherwise give up.
+
+2013-07-29 Bill Schmidt <wschmidt@vnet.linux.ibm.com>
+
+ PR tree-optimization/57993
+ * gimple-ssa-strength-reduction.c (replace_mult_candidate): Record
+ replaced statement in the candidate table.
+ (phi_add_costs): Return infinite cost when the hidden basis does
+ not dominate all phis on which the candidate is dependent.
+ (replace_one_candidate): Record replaced statement in the
+ candidate table.
+
+2013-07-29 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * config/epiphany/epiphany.md (*isub_i+2): New peephole.
+ (ashlv2si3): New expander.
+ (*ashlv2si3_i): New define_insn_and_split.
+ * predicates.md (float_operation): Allow patterns with three
+ basic sub-patterns.
+
+ PR rtl-optimization/58021
+ * mode-switching.c (create_pre_exit): Always split off preceding
+ insns if we are not at the basic block head.
+
+2013-07-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config/mips/linux.h (GLIBC_DYNAMIC_LINKER): Handle `-mnan=2008'.
+ (UCLIBC_DYNAMIC_LINKER): New macro.
+ * config/mips/linux64.h (GLIBC_DYNAMIC_LINKER32): Handle
+ `-mnan=2008'.
+ (GLIBC_DYNAMIC_LINKER64, GLIBC_DYNAMIC_LINKERN32): Likewise.
+ (UCLIBC_DYNAMIC_LINKER32): Undefine macro first. Handle
+ `-mnan=2008'.
+ (UCLIBC_DYNAMIC_LINKER64): Redefine macro.
+ (UCLIBC_DYNAMIC_LINKERN32): Likewise.
+ * config/mips/mips-modes.def: Remove RESET_FLOAT_FORMAT calls
+ for SF and DF modes. Use ieee_quad_format for TF mode.
+ * config/mips/mips-opts.h (mips_ieee_754_setting): New enum.
+ * config/mips/mips.c (mips_file_start): Output a `.nan' directive.
+ (mips_option_override): Handle `-mnan=legacy'.
+ * config/mips/mips.h (TARGET_CPU_CPP_BUILTINS): Handle
+ `-mabs=2008' and `-mnan=2008'.
+ (OPTION_DEFAULT_SPECS): Add "nan" default.
+ (ASM_SPEC): Handle `-mnan='.
+ [!HAVE_AS_NAN] (HAVE_AS_NAN): New macro.
+ * config/mips/mips.md (abs<mode>2): Handle `-mabs=2008', update
+ comment accordingly.
+ (neg<mode>2): Likewise.
+ * config/mips/mips.opt (mabs, mnan): New options.
+ * doc/install.texi (Configuration): Document `--with-nan=' option.
+ * doc/invoke.texi (Option Summary): List MIPS `-mabs=' and
+ `-mnan=' options.
+ (MIPS Options): Document them.
+ * config.gcc <mips*-*-*>: Handle `--with-nan='.
+ * configure.ac <mips*-*-*>: Check for GAS `-mnan=2008' support.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+
+2013-07-29 Uros Bizjak <ubizjak@gmail.com>
+
+ * config/i386/i386.md (float post-reload splitters): Do not check
+ for subregs of SSE registers.
+
+2013-07-29 Uros Bizjak <ubizjak@gmail.com>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/57954
+ PR target/57988
+ * config/i386/i386.md (post-reload splitter
+ to avoid partial SSE reg dependency stalls): New pattern.
+
+2013-07-29 Dominik Vogt <vogt@linux.vnet.ibm.com>
+
+ * config/s390/s390.md ("movcc"): Swap load and store instructions.
+
2013-07-27 Joern Rennecke <joern.rennecke@embecosm.com>
* config/epiphany/epiphany.c (epiphany_compute_frame_size):
@@ -24,10 +5704,10 @@
* config/aarch64/iterators.md: Add attributes rtn and vas.
2013-07-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
- Richard Earnshaw <richard.earnshaw@arm.com>
+ Richard Earnshaw <richard.earnshaw@arm.com>
* combine.c (simplify_comparison): Re-canonicalize operands
- where appropriate.
+ where appropriate.
* config/arm/arm.md (movcond_addsi): New splitter.
2013-07-25 Sterling Augustine <saugustine@google.com>
@@ -104,7 +5784,7 @@
PR target/19599
PR target/57731
- PR target/57748
+ PR target/57837
* config/arm/arm.md ("*sibcall_insn): Replace use of
Ss with US. Adjust output for v5 and v4t.
(*sibcall_value_insn): Likewise and loosen predicate on operand0.
@@ -117,7 +5797,7 @@
shift_add/shift_sub0/shift_sub1 RTXs.
2013-07-24 Bill Schmidt <wschmidt@linux.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/altivec.md (altivec_vpkpx): Handle little endian.
(altivec_vpks<VI_char>ss): Likewise.
@@ -147,7 +5827,7 @@
don't set a return register to need a non-exit mode.
2013-07-24 Bill Schmidt <wschmidt@vnet.linux.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/vector.md (vec_realign_load_<mode>): Reorder input
operands to vperm for little endian.
@@ -155,7 +5835,7 @@
of lvsl to create the control mask for a vperm for little endian.
2013-07-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/rs6000.c (altivec_expand_vec_perm_const): Reverse
two operands for little-endian.
@@ -166,7 +5846,7 @@
(TARGET_CASE_VALUES_THRESHOLD): Define.
2013-07-23 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/rs6000.c (altivec_expand_vec_perm_const): Correct
selection of field for vector splat in little endian mode.
@@ -261,12 +5941,12 @@
(eqv<mode>3_internal2): Likewise.
(one_cmpl1<mode>3_internal): Likewise.
-2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
+2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/microblaze.c (microblaze_expand_prologue):
Rename flag_stack_usage to flag_stack_usage_info.
-2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
+2013-07-23 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/sync.md: New file.
* config/microblaze/microblaze.md: Include sync.md
@@ -403,7 +6083,7 @@
* config/avr/avr.md: Explain asm print modifier 'r' for REG.
2013-07-22 Bill Schmidt <wschmidt@vnet.linux.ibm.com>
- Anton Blanchard <anton@au1.ibm.com>
+ Anton Blanchard <anton@au1.ibm.com>
* config/rs6000/rs6000.c (rs6000_expand_vector_init): Fix
endianness when selecting field to splat.
@@ -686,12 +6366,12 @@
(avr_out_round): New function.
(avr_adjust_insn_length): Handle ADJUST_LEN_ROUND.
-2013-07-18 David Holsgrove <david.holsgrove@xilinx.com>
+2013-07-18 David Holsgrove <david.holsgrove@xilinx.com>
* config/microblaze/microblaze.c (microblaze_expand_prologue):
Add check for flag_stack_usage to handle -fstack-usage support
-2013-07-18 Pat Haugen <pthaugen@us.ibm.com>
+2013-07-18 Pat Haugen <pthaugen@us.ibm.com>
* config/rs6000/rs6000.c (rs6000_option_override_internal): Adjust flag
interaction for new Power8 flags and VSX.
@@ -1856,7 +7536,7 @@
* config/i386/i386.c (enum ix86_builtins, bdesc_args): Remove
IX86_BUILTIN_CMPNGTSS and IX86_BUILTIN_CMPNGESS.
-2013-06-27 Catherine Moore <clm@codesourcery.com>
+2013-06-27 Catherine Moore <clm@codesourcery.com>
* config/mips/mips-tables.opt: Regenerate.
* config/mips/mips-cpus.def: Add m14ke and m14kec.
@@ -1969,8 +7649,8 @@
(TARGET_CAN_SPLIT_STACK, TARGET_THREAD_SPLIT_STACK_OFFSET): Undefine.
2013-06-26 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/power8.md: New.
* config/rs6000/rs6000-cpus.def (RS6000_CPU table): Adjust processor
@@ -2099,7 +7779,7 @@
* common/config/i386/i386-common.c (ix86_handle_option): For OPT_mlzcnt
add missing return true.
-2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
+2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
PR target/52483
* config/sh/predicates.md (general_extend_operand): Invoke
@@ -2156,7 +7836,7 @@
* doc/extend.texi: Use __atomic_store_n instead of
__atomic_store in HLE example.
-2013-06-22 Oleg Endo <olegendo@gcc.gnu.org>
+2013-06-22 Oleg Endo <olegendo@gcc.gnu.org>
* config/sh/sh.c: Remove <cstdlib> workaround.
@@ -2179,7 +7859,7 @@
(get_binfo_at_offset): Use it.
* tree.h (types_same_for_odr): Declare.
-2013-06-20 Oleg Endo <olegendo@gcc.gnu.org>
+2013-06-20 Oleg Endo <olegendo@gcc.gnu.org>
Jason Merrill <jason@redhat.com>
* system.h: Include <cstdlib> as well as <stdlib.h>.
@@ -2194,7 +7874,7 @@
* lto-cgraph.c (input_symtab): Do not set cgraph state.
-2013-06-20 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-06-20 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57425
PR rtl-optimization/57569
@@ -2672,7 +8352,7 @@
Likewise. Remove default with_tune setting. Move default float
setting to its own block. Handle with_llsc in the same block as above.
-2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57425
PR rtl-optimization/57569
@@ -2708,7 +8388,7 @@
rs6000_output_move_128bit to handle emitting quad memory
operations. Set attribute length to 8 bytes.
-2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
+2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
* config/aarch64/aarch64-simd.md (aarch64_<su>mlal_lo<mode>):
New pattern.
@@ -2777,8 +8457,8 @@
* config/rs6000/spe.md (spe_abstf2_cmp, spe_abstf2_tst): Likewise.
2013-06-12 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/rs6000.c (emit_load_locked): Add support for
power8 byte, half-word, and quad-word atomic instructions.
@@ -2865,7 +8545,7 @@
* lto-symtab.c (lto_symtab_merge_symbols): Likewise.
* cgraph.h (cgraph_state): Add CGRAPH_LTO_STREAMING.
-2013-06-12 Roland Stigge <stigge@antcom.de>
+2013-06-12 Roland Stigge <stigge@antcom.de>
PR target/57578
* config/rs6000/t-linux (MULTIARCH_DIRNAME): Fix SPE version detection.
@@ -2951,6 +8631,11 @@
(symtab_alias_ultimate_target): Simplify.
* varpool.c (varpool_create_variable_alias): Set weakref flag.
+2013-06-11 Tom de Vries <tom@codesourcery.com>
+
+ * genautomata.c (gen_regexp_sequence): Handle els_num == -1. Handle
+ sequence_vect == NULL.
+
2013-06-11 DJ Delorie <dj@redhat.com>
* config/rl78/rl78.c (TARGET_UNWIND_WORD_MODE): Define.
@@ -3005,8 +8690,8 @@
for hash so that hash table traversal order is deterministic.
2013-06-10 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/vector.md (GPR move splitter): Do not split moves
of vectors in GPRS if they are direct moves or quad word load or
@@ -3234,8 +8919,8 @@
TARGET_VALID_POINTER_MODE.
2013-06-06 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* doc/extend.texi (PowerPC AltiVec/VSX Built-in Functions):
Document new power8 builtins.
@@ -3986,7 +9671,7 @@
* config/aarch64/aarch64.md (insv<mode>): New define_expand.
(*insv_reg<mode>): New define_insn.
-2013-05-30 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-30 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57439
* postreload.c (move2add_valid_value_p): Check that we have
@@ -4079,8 +9764,8 @@
functions are not yet marked as defined.
2013-05-29 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* config/rs6000/vector.md (VEC_I): Add support for new power8 V2DI
instructions.
@@ -4396,7 +10081,7 @@
(MULTILIB_DIRNAMES): Ditto.
(MULTILIB_EXCEPTIONS): Add new exceptions.
-2012-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+2012-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64-protos.h (aarch64_symbol_type): Define
@@ -4409,7 +10094,7 @@
Permit SYMBOL_TINY_ABSOLUTE.
* config/aarch64/predicates.md (aarch64_mov_operand): Permit CONST.
-2013-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+2013-05-29 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64.c (aarch64_classify_symbol): Remove comment.
@@ -4459,7 +10144,7 @@
* builtin-types.def: Define BT_FN_INT_PTR_PTR_PTR.
* cilkplus.def: New file.
-2013-05-28 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-28 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57439
* postreload.c (move2add_use_add2_insn): Use gen_lowpart_common.
@@ -4543,7 +10228,7 @@
(set_ssa_val_to): Compare addresses using
get_addr_base_and_unit_offset.
-2013-05-27 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-27 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/56833
* postreload.c (move2add_record_mode): New function.
@@ -4709,14 +10394,14 @@
PR debug/57351
* config/arm/arm.c (arm_dwarf_register_span): Do not use dbx number.
-2013-05-23 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+2013-05-23 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64.md (*movdi_aarch64): Replace Usa with S.
* config/aarch64/constraints.md (Usa): Remove.
* doc/md.texi (AArch64 Usa): Remove.
-2013-05-23 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
+2013-05-23 Chris Schlumberger-Socha <chris.schlumberger-socha@arm.com>
Marcus Shawcroft <marcus.shawcroft@arm.com>
* config/aarch64/aarch64-protos.h (aarch64_mov_operand_p): Define.
@@ -4724,7 +10409,7 @@
* config/aarch64/predicates.md (aarch64_const_address): Remove.
(aarch64_mov_operand): Use aarch64_mov_operand_p.
-2013-05-23 Vidya Praveen <vidyapraveen@arm.com>
+2013-05-23 Vidya Praveen <vidyapraveen@arm.com>
* config/aarch64/aarch64-simd.md (clzv4si2): Support for CLZ
instruction (AdvSIMD).
@@ -4779,8 +10464,8 @@
(exec_threshold): Ditto.
2013-05-22 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* doc/extend.texi (PowerPC AltiVec/VSX Built-in Functions): Add
documentation for the power8 crypto builtins.
@@ -4832,8 +10517,8 @@
instructions.
2013-05-22 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* doc/invoke.texi (Option Summary): Add power8 options.
(RS/6000 and PowerPC Options): Likewise.
@@ -5593,7 +11278,7 @@
* config/arm/arm.h (EPILOGUE_USES): Only return true
for LR_REGNUM after epilogue_completed.
-2013-05-14 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-14 Joern Rennecke <joern.rennecke@embecosm.com>
* config/avr/avr.c (avr_encode_section_info): Bail out if the type
is error_mark_node.
@@ -6476,7 +12161,7 @@
*vec_concatv2si_sse2 and vec_concatv2si_sse.
(vec_concatv2di): Merge with *vec_concatv2di_rex64.
-2013-05-03 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-03 Joern Rennecke <joern.rennecke@embecosm.com>
PR tree-optimization/57027
* tree-ssa-math-opts.c (convert_mult_to_fma): When checking
@@ -7843,7 +13528,7 @@
(scev_analysis): Likewise.
2013-04-02 Catherine Moore <clm@codesourcery.com>
- Chao-ying Fu <fu@mips.com>
+ Chao-ying Fu <fu@mips.com>
* config/mips/micromips.md (jraddiusp): New pattern.
* config/mips/mips.c (mips_expand_epilogue): Use the JRADDIUSP
@@ -8758,7 +14443,7 @@
(vect_get_constant_vectors): Handle mixed vect_external_def,
vect_constant_def types.
-2013-04-10 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-04-10 Joern Rennecke <joern.rennecke@embecosm.com>
PR tree-optimization/55524
* tree-ssa-math-opts.c
@@ -8766,7 +14451,7 @@
when we don't have an fms operation, but fnma, and it looks
likely that we'll be able to use the latter.
-2013-04-10 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
+2013-04-10 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
* cif-code.def (OVERWRITABLE): Correct the comment for overwritable
function.
@@ -9244,7 +14929,7 @@
* basic-block.h (gcov_working_set_t): Moved to gcov-io.h.
* gcov-dump.c (dump_working_sets): New function.
-2013-04-03 Kenneth Zadeck <zadeck@naturalbridge.com>
+2013-04-03 Kenneth Zadeck <zadeck@naturalbridge.com>
* hwint.c (sext_hwi, zext_hwi): New functions.
* hwint.h (HOST_BITS_PER_HALF_WIDE_INT, HOST_HALF_WIDE_INT,
@@ -10005,21 +15690,21 @@
2013-03-27 Alexander Ivchenko <alexander.ivchenko@intel.com>
- * target.def (TARGET_HAS_IFUNC_P): New target hook.
- * doc/tm.texi.in (TARGET_HAS_IFUNC_P): New.
- * doc/tm.texi: Regenerate.
- * targhooks.h (default_has_ifunc_p): New.
- * targhooks.c (default_has_ifunc_p): Ditto.
- * config/linux-protos.h: New file.
- * config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of
+ * gcc/target.def (TARGET_HAS_IFUNC_P): New target hook.
+ * gcc/doc/tm.texi.in (TARGET_HAS_IFUNC_P): New.
+ * gcc/doc/tm.texi: Regenerate.
+ * gcc/targhooks.h (default_has_ifunc_p): New.
+ * gcc/targhooks.c (default_has_ifunc_p): Ditto.
+ * gcc/config/linux-protos.h: New file.
+ * gcc/config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of
this hook for linux which disables support of indirect functions in
android.
- * config/linux-android.c: New file.
- * config/t-linux-android.c: Ditto.
- * config.gcc: Added new object file linux-android.o.
- * config/i386/i386.c (ix86_get_function_versions_dispatcher):
+ * gcc/config/linux-android.c: New file.
+ * gcc/config/t-linux-android.c: Ditto.
+ * gcc/config.gcc: Added new object file linux-android.o.
+ * gcc/config/i386/i386.c (ix86_get_function_versions_dispatcher):
Using TARGET_HAS_IFUNC hook instead of HAVE_GNU_INDIRECT_FUNCTION.
- * varasm.c (do_assemble_alias): Likewise.
+ * gcc/varasm.c (do_assemble_alias): Likewise.
* configure.ac: Define HAVE_GNU_INDIRECT_FUNCTION as zero if the target
doesn't support indirect functions.
* configure: Regenerate.
@@ -10772,7 +16457,7 @@
* params.def (PARAM_IPA_CP_ARRAY_INDEX_HINT_BONUS): New parameter.
* ipa-cp.c (hint_time_bonus): Add abonus for known array indices.
-2013-03-20 Pat Haugen <pthaugen@us.ibm.com>
+2013-03-20 Pat Haugen <pthaugen@us.ibm.com>
* config/rs6000/predicates.md (indexed_address, update_address_mem
update_indexed_address_mem): New predicates.
@@ -11079,10 +16764,10 @@
2013-03-20 Catherine Moore <clm@codesourcery.com>
Maciej W. Rozycki <macro@codesourcery.com>
Tom de Vries <tom@codesourcery.com>
- Nathan Sidwell <nathan@codesourcery.com>
+ Nathan Sidwell <nathan@codesourcery.com>
Iain Sandoe <iain@codesourcery.com>
Nathan Froyd <froydnj@codesourcery.com>
- Chao-ying Fu <fu@mips.com>
+ Chao-ying Fu <fu@mips.com>
* doc/extend.texi: (micromips, nomicromips, nocompression):
Document new function attributes.
@@ -11214,7 +16899,7 @@
remap_gimple_op_r.
2013-03-20 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
- Steven Bosscher <steven@gcc.gnu.org>
+ Steven Bosscher <steven@gcc.gnu.org>
PR rtl-optimization/56605
* loop-iv.c (implies_p): Handle equal RTXs and subregs.
diff --git a/gcc/ChangeLog.MELT b/gcc/ChangeLog.MELT
index a7c92c3e315..393ab46a14d 100644
--- a/gcc/ChangeLog.MELT
+++ b/gcc/ChangeLog.MELT
@@ -1,4 +1,9 @@
+2013-09-09 Basile Starynkevitch <basile@starynkevitch.net>
+ {{When merging trunk GCC 4.9 with C++ passes}}
+ * melt/xtramelt-ana-base.melt: Add GCC 4.9 specific code, still
+ incomplete, for classy passes.... Only Gimple passes are yet possible...
+
2013-09-06 Basile Starynkevitch <basile@starynkevitch.net>
* melt/warmelt-macro.melt: Replaced all error_... with
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index a7af27726c6..6ee74275c1d 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20130729
+20130909
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0b52ea14fd3..ac695aedc7a 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -872,11 +872,13 @@ BUILTINS_DEF = builtins.def sync-builtins.def omp-builtins.def \
gtm-builtins.def sanitizer.def cilkplus.def
INTERNAL_FN_DEF = internal-fn.def
INTERNAL_FN_H = internal-fn.h $(INTERNAL_FN_DEF)
-TREE_H = coretypes.h tree.h all-tree.def tree.def c-family/c-common.def \
- $(lang_tree_files) $(MACHMODE_H) tree-check.h $(BUILTINS_DEF) \
- $(INPUT_H) statistics.h $(VEC_H) treestruct.def $(HASHTAB_H) \
+TREE_CORE_H = tree-core.h coretypes.h all-tree.def tree.def \
+ c-family/c-common.def $(lang_tree_files) $(MACHMODE_H) \
+ $(BUILTINS_DEF) $(INPUT_H) statistics.h \
+ $(VEC_H) treestruct.def $(HASHTAB_H) \
double-int.h alias.h $(SYMTAB_H) $(FLAGS_H) \
$(REAL_H) $(FIXED_VALUE_H)
+TREE_H = tree.h $(TREE_CORE_H) tree-check.h
REGSET_H = regset.h $(BITMAP_H) hard-reg-set.h
BASIC_BLOCK_H = basic-block.h $(PREDICT_H) $(VEC_H) $(FUNCTION_H) \
cfg-flags.def cfghooks.h
@@ -987,6 +989,7 @@ PLUGIN_VERSION_H = plugin-version.h configargs.h
LIBFUNCS_H = libfuncs.h $(HASHTAB_H)
GRAPHITE_HTAB_H = graphite-htab.h graphite-clast-to-gimple.h $(HASH_TABLE_H)
CONTEXT_H = context.h
+PASS_MANAGER_H = pass_manager.h pass-instances.def
#
# Now figure out from those variables how to compile and link.
@@ -1154,7 +1157,7 @@ C_COMMON_OBJS = c-family/c-common.o c-family/c-cppbuiltin.o c-family/c-dump.o \
c-family/c-omp.o c-family/c-opts.o c-family/c-pch.o \
c-family/c-ppoutput.o c-family/c-pragma.o c-family/c-pretty-print.o \
c-family/c-semantics.o c-family/c-ada-spec.o tree-mudflap.o \
- c-family/array-notation-common.o
+ c-family/array-notation-common.o c-family/c-ubsan.o
# Language-independent object files.
# We put the insn-*.o files first so that a parallel make will build
@@ -1276,10 +1279,12 @@ OBJS = \
init-regs.o \
internal-fn.o \
ipa-cp.o \
+ ipa-devirt.o \
ipa-split.o \
ipa-inline.o \
ipa-inline-analysis.o \
ipa-inline-transform.o \
+ ipa-profile.o \
ipa-prop.o \
ipa-pure-const.o \
ipa-reference.o \
@@ -1317,7 +1322,6 @@ OBJS = \
lto-streamer-out.o \
lto-section-in.o \
lto-section-out.o \
- lto-symtab.o \
lto-opts.o \
lto-compress.o \
mcf.o \
@@ -1383,6 +1387,7 @@ OBJS = \
tree-affine.o \
asan.o \
tsan.o \
+ ubsan.o \
tree-call-cdce.o \
tree-cfg.o \
tree-cfgcleanup.o \
@@ -1474,6 +1479,7 @@ OBJS = \
varasm.o \
varpool.o \
vmsdbgout.o \
+ vtable-verify.o \
web.o \
xcoffout.o \
$(out_object_file) \
@@ -2036,6 +2042,10 @@ c-family/array-notation-common.o : c-family/array-notation-common.c $(TREE_H) \
c-family/stub-objc.o : c-family/stub-objc.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_H) $(C_COMMON_H) c-family/c-objc.h
+c-family/c-ubsan.o : c-family/c-ubsan.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(TREE_H) $(C_COMMON_H) c-family/c-ubsan.h \
+ alloc-pool.h $(CGRAPH_H) $(GIMPLE_H) $(HASH_TABLE_H) output.h \
+ toplev.h ubsan.h
default-c.o: config/default-c.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(C_TARGET_H) $(C_TARGET_DEF_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
@@ -2186,7 +2196,7 @@ tree-streamer-in.o: tree-streamer-in.c $(CONFIG_H) $(SYSTEM_H) \
$(DATA_STREAMER_H) $(STREAMER_HOOKS_H) $(LTO_STREAMER_H)
tree-streamer-out.o: tree-streamer-out.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(DIAGNOSTIC_H) $(TREE_STREAMER_H) $(DATA_STREAMER_H) \
- $(STREAMER_HOOKS_H)
+ $(STREAMER_HOOKS_H) $(TM_H)
streamer-hooks.o: streamer-hooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(STREAMER_HOOKS_H)
lto-cgraph.o: lto-cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
@@ -2194,7 +2204,8 @@ lto-cgraph.o: lto-cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(HASHTAB_H) langhooks.h $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) $(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(DIAGNOSTIC_CORE_H) \
$(EXCEPT_H) $(TIMEVAR_H) pointer-set.h $(LTO_STREAMER_H) \
- $(GCOV_IO_H) $(DATA_STREAMER_H) $(TREE_STREAMER_H) $(TREE_PASS_H) profile.h
+ $(GCOV_IO_H) $(DATA_STREAMER_H) $(TREE_STREAMER_H) $(TREE_PASS_H) \
+ profile.h $(CONTEXT_H) $(PASS_MANAGER_H)
lto-streamer-in.o: lto-streamer-in.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) toplev.h $(DIAGNOSTIC_CORE_H) $(EXPR_H) $(FLAGS_H) $(PARAMS_H) \
input.h $(HASHTAB_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TREE_PASS_H) \
@@ -2219,9 +2230,6 @@ lto-section-out.o : lto-section-out.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(CGRAPH_H) $(FUNCTION_H) $(GGC_H) $(EXCEPT_H) pointer-set.h \
$(BITMAP_H) langhooks.h $(LTO_STREAMER_H) lto-compress.h \
$(DATA_STREAMER_H)
-lto-symtab.o: lto-symtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TREE_H) $(GIMPLE_H) $(GGC_H) $(HASHTAB_H) \
- $(LTO_STREAMER_H) $(LINKER_PLUGIN_API_H)
lto-opts.o: lto-opts.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TREE_H) \
$(HASHTAB_H) $(GGC_H) $(BITMAP_H) $(FLAGS_H) $(OPTS_H) $(OPTIONS_H) \
$(COMMON_TARGET_H) $(DIAGNOSTIC_H) $(LTO_STREAMER_H)
@@ -2272,8 +2280,11 @@ tsan.o : $(CONFIG_H) $(SYSTEM_H) $(TREE_H) $(TREE_INLINE_H) \
$(TM_H) coretypes.h $(TREE_DUMP_H) $(TREE_PASS_H) $(CGRAPH_H) $(GGC_H) \
$(BASIC_BLOCK_H) $(FLAGS_H) $(FUNCTION_H) \
$(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_CORE_H) $(GIMPLE_H) tree-iterator.h \
- intl.h cfghooks.h output.h options.h c-family/c-common.h tsan.h asan.h \
+ intl.h cfghooks.h output.h options.h $(C_COMMON_H) tsan.h asan.h \
tree-ssa-propagate.h
+ubsan.o : ubsan.c ubsan.h $(CONFIG_H) $(SYSTEM_H) $(GIMPLE_H) \
+ output.h coretypes.h $(TREE_H) $(CGRAPH_H) $(HASHTAB_H) gt-ubsan.h \
+ toplev.h $(C_COMMON_H) $(TM_P_H)
tree-ssa-tail-merge.o: tree-ssa-tail-merge.c \
$(SYSTEM_H) $(CONFIG_H) coretypes.h $(TM_H) $(BITMAP_H) \
$(FLAGS_H) $(TM_P_H) $(BASIC_BLOCK_H) $(CFGLOOP_H) \
@@ -2432,7 +2443,7 @@ tree-tailcall.o : tree-tailcall.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(FUNCTION_H) $(TM_H) coretypes.h \
$(EXCEPT_H) $(TREE_PASS_H) $(FLAGS_H) langhooks.h \
$(BASIC_BLOCK_H) $(DBGCNT_H) $(GIMPLE_PRETTY_PRINT_H) $(TARGET_H) \
- $(COMMON_TARGET_H) $(CFGLOOP_H)
+ $(COMMON_TARGET_H) $(CFGLOOP_H) ipa-utils.h
tree-ssa-sink.o : tree-ssa-sink.c $(TREE_FLOW_H) $(CONFIG_H) \
$(SYSTEM_H) $(TREE_H) $(DIAGNOSTIC_H) \
$(TM_H) coretypes.h $(TREE_PASS_H) $(FLAGS_H) alloc-pool.h \
@@ -2572,7 +2583,7 @@ omp-low.o : omp-low.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(GIMPLE_H) $(TREE_INLINE_H) langhooks.h $(DIAGNOSTIC_CORE_H) \
$(TREE_FLOW_H) $(FLAGS_H) $(EXPR_H) $(DIAGNOSTIC_CORE_H) \
$(TREE_PASS_H) $(GGC_H) $(EXCEPT_H) $(SPLAY_TREE_H) $(OPTABS_H) \
- $(CFGLOOP_H) tree-iterator.h gt-omp-low.h
+ $(CFGLOOP_H) tree-iterator.h $(TARGET_H) gt-omp-low.h
tree-browser.o : tree-browser.c tree-browser.def $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(HASH_TABLE_H) $(TREE_H) $(TREE_PRETTY_PRINT_H)
omega.o : omega.c $(OMEGA_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) \
@@ -2652,7 +2663,13 @@ tree-vect-data-refs.o: tree-vect-data-refs.c $(CONFIG_H) $(SYSTEM_H) \
tree-vectorizer.o: tree-vectorizer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(DUMPFILE_H) $(TM_H) $(GGC_H) $(TREE_H) $(TREE_FLOW_H) \
$(CFGLOOP_H) $(TREE_PASS_H) $(TREE_VECTORIZER_H) \
- $(TREE_PRETTY_PRINT_H)
+ $(TREE_PRETTY_PRINT_H) $(DBGCNT_H)
+vtable-verify.o: vtable-verify.c vtable-verify.h $(CONFIG_H) \
+ $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) cp/cp-tree.h $(TM_P_H) \
+ $(BASIC_BLOCK_H) output.h $(TREE_FLOW_H) $(TREE_DUMP_H) $(TREE_PASS_H) \
+ $(TIMEVAR_H) $(CFGLOOP_H) $(FLAGS_H) $(TREE_INLINE_H) $(SCEV_H) \
+ $(DIAGNOSTIC_CORE_H) $(GIMPLE_PRETTY_PRINT_H) toplev.h langhooks.h \
+ gt-vtable-verify.h
tree-loop-distribution.o: tree-loop-distribution.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TREE_FLOW_H) $(CFGLOOP_H) $(TREE_DATA_REF_H) $(TREE_PASS_H)
tree-parloops.o: tree-parloops.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
@@ -2836,10 +2853,14 @@ toplev.o : toplev.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(OPTS_H) params.def tree-mudflap.h $(TREE_PASS_H) $(GIMPLE_H) \
tree-ssa-alias.h $(PLUGIN_H) realmpfr.h tree-diagnostic.h \
$(TREE_PRETTY_PRINT_H) opts-diagnostic.h $(COMMON_TARGET_H) \
- tsan.h diagnostic-color.h $(CONTEXT_H)
+ tsan.h diagnostic-color.h $(CONTEXT_H) $(PASS_MANAGER_H)
hwint.o : hwint.c $(CONFIG_H) $(SYSTEM_H) $(DIAGNOSTIC_CORE_H)
+pass-instances.def: $(srcdir)/passes.def $(srcdir)/gen-pass-instances.awk
+ $(AWK) -f $(srcdir)/gen-pass-instances.awk \
+ $(srcdir)/passes.def > pass-instances.def
+
passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(FUNCTION_H) $(FLAGS_H) $(INPUT_H) $(INSN_ATTR_H) output.h \
$(DIAGNOSTIC_CORE_H) debug.h insn-config.h intl.h $(RECOG_H) toplev.h \
@@ -2850,7 +2871,8 @@ passes.o : passes.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
hosthooks.h $(CGRAPH_H) $(COVERAGE_H) $(TREE_PASS_H) $(TREE_DUMP_H) \
$(GGC_H) $(OPTS_H) $(TREE_FLOW_H) $(TREE_INLINE_H) \
gt-passes.h $(DF_H) $(PREDICT_H) $(LTO_STREAMER_H) \
- $(PLUGIN_H) $(IPA_UTILS_H) passes.def
+ $(PLUGIN_H) $(IPA_UTILS_H) pass-instances.def \
+ $(CONTEXT_H) $(PASS_MANAGER_H)
plugin.o : plugin.c $(PLUGIN_H) $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(HASH_TABLE_H) $(DIAGNOSTIC_CORE_H) $(TREE_H) $(TREE_PASS_H) \
@@ -2891,7 +2913,8 @@ function.o : function.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_ERROR_
$(TREE_PASS_H) $(DF_H) $(PARAMS_H) bb-reorder.h \
$(COMMON_TARGET_H)
statistics.o : statistics.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TREE_PASS_H) $(TREE_DUMP_H) $(HASH_TABLE_H) statistics.h $(FUNCTION_H)
+ $(TREE_PASS_H) $(TREE_DUMP_H) $(HASH_TABLE_H) statistics.h \
+ $(FUNCTION_H) $(CONTEXT_H) $(PASS_MANAGER_H)
stmt.o : stmt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(DUMPFILE_H) $(TM_H) \
$(RTL_H) \
$(TREE_H) $(FLAGS_H) $(FUNCTION_H) insn-config.h hard-reg-set.h $(EXPR_H) \
@@ -2925,7 +2948,7 @@ builtins.o : builtins.c builtins.h $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
hard-reg-set.h $(DIAGNOSTIC_CORE_H) hard-reg-set.h $(EXCEPT_H) \
$(TM_P_H) $(PREDICT_H) $(LIBFUNCS_H) langhooks.h $(BASIC_BLOCK_H) \
tree-mudflap.h realmpfr.h $(BUILTINS_DEF) $(MACHMODE_H) \
- $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) value-prof.h
+ $(DIAGNOSTIC_CORE_H) $(TREE_FLOW_H) value-prof.h ubsan.h
calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \
$(TREE_H) $(FLAGS_H) $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
$(LIBFUNCS_H) $(REGS_H) $(DIAGNOSTIC_CORE_H) output.h \
@@ -3013,7 +3036,8 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(IPA_PROP_H) \
gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H) \
$(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(IPA_UTILS_H) $(CFGLOOP_H) \
- $(LTO_STREAMER_H) output.h $(REGSET_H) $(EXCEPT_H) $(GCC_PLUGIN_H) plugin.h
+ $(LTO_STREAMER_H) output.h $(REGSET_H) $(EXCEPT_H) $(GCC_PLUGIN_H) \
+ plugin.h $(CONTEXT_H) $(PASS_MANAGER_H)
cgraphclones.o : cgraphclones.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_H) \
@@ -3032,8 +3056,16 @@ varpool.o : varpool.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_FLOW_H)
ipa.o : ipa.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \
$(TREE_PASS_H) $(GIMPLE_H) $(TARGET_H) $(GGC_H) pointer-set.h \
- $(IPA_UTILS_H) tree-inline.h $(HASH_TABLE_H) profile.h $(PARAMS_H) \
- $(LTO_STREAMER_H) $(DATA_STREAMER_H)
+ $(IPA_UTILS_H) tree-inline.h profile.h $(PARAMS_H)
+ipa-profile.o : ipa-profile.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \
+ $(TREE_PASS_H) $(GIMPLE_H) $(TARGET_H) $(GGC_H) \
+ $(IPA_UTILS_H) $(HASH_TABLE_H) profile.h $(PARAMS_H) \
+ value-prof.h alloc-pool.h tree-inline.h $(LTO_STREAMER_H) $(DATA_STREAMER_H) \
+ ipa-inline.h
+ipa-devirt.o : ipa-devirt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(CGRAPH_H) \
+ $(GIMPLE_H) $(TARGET_H) $(GGC_H) pointer-set.h \
+ $(IPA_UTILS_H) $(HASH_TABLE_H) ipa-inline.h ipa-utils.h $(TREE_PRETTY_PRINT_H) \
+ $(DIAGNOSTIC_H)
ipa-prop.o : ipa-prop.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
langhooks.h $(GGC_H) $(TARGET_H) $(CGRAPH_H) $(IPA_PROP_H) $(DIAGNOSTIC_H) \
$(TREE_FLOW_H) $(TM_H) $(TREE_PASS_H) $(FLAGS_H) $(TREE_H) \
@@ -3057,13 +3089,14 @@ ipa-inline.o : ipa-inline.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(DIAGNOSTIC_H) $(FIBHEAP_H) $(PARAMS_H) $(TREE_PASS_H) \
$(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(RTL_H) $(IPA_PROP_H) \
$(EXCEPT_H) $(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(TARGET_H) \
- $(IPA_UTILS_H)
+ $(IPA_UTILS_H) sreal.h
ipa-inline-analysis.o : ipa-inline-analysis.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(DIAGNOSTIC_H) $(PARAMS_H) $(TREE_PASS_H) $(CFGLOOP_H) \
$(HASHTAB_H) $(COVERAGE_H) $(GGC_H) $(TREE_FLOW_H) $(IPA_PROP_H) \
$(GIMPLE_PRETTY_PRINT_H) $(IPA_INLINE_H) $(LTO_STREAMER_H) $(DATA_STREAMER_H) \
- $(TREE_STREAMER_H)
+ $(TREE_STREAMER_H) ipa-utils.h tree-scalar-evolution.h $(CFGLOOP_H) \
+ alloc-pool.h
ipa-inline-transform.o : ipa-inline-transform.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) $(FLAGS_H) $(CGRAPH_H) intl.h \
$(TREE_PASS_H) \
@@ -3176,7 +3209,7 @@ tree-sra.o : tree-sra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h alloc-pool.h \
$(HASH_TABLE_H) $(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) \
$(IPA_PROP_H) $(DIAGNOSTIC_H) statistics.h \
$(PARAMS_H) $(TARGET_H) $(FLAGS_H) \
- $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H)
+ $(DBGCNT_H) $(TREE_INLINE_H) $(GIMPLE_PRETTY_PRINT_H) ipa-utils.h
tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
$(TM_H) coretypes.h $(GIMPLE_H) $(CFGLOOP_H) \
@@ -3595,7 +3628,7 @@ $(out_object_file): $(out_file) $(CONFIG_H) coretypes.h $(TM_H) $(TREE_H) \
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) \
$(out_file) $(OUTPUT_OPTION)
context.o: context.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(GGC_H) \
- $(CONTEXT_H)
+ $(CONTEXT_H) $(PASS_MANAGER_H)
$(common_out_object_file): $(common_out_file) $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(COMMON_TARGET_H) $(COMMON_TARGET_DEF_H) $(PARAMS_H) \
@@ -3866,14 +3899,15 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(host_xm_file_list) \
$(tm_file_list) $(HASHTAB_H) $(SPLAY_TREE_H) $(srcdir)/bitmap.h \
$(srcdir)/alias.h $(srcdir)/coverage.c $(srcdir)/rtl.h \
- $(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/libfuncs.h $(SYMTAB_H) \
+ $(srcdir)/optabs.h $(srcdir)/tree.h $(srcdir)/tree-core.h \
+ $(srcdir)/libfuncs.h $(SYMTAB_H) \
$(srcdir)/real.h $(srcdir)/function.h $(srcdir)/insn-addr.h $(srcdir)/hwint.h \
$(srcdir)/fixed-value.h \
$(srcdir)/output.h $(srcdir)/cfgloop.h \
$(srcdir)/cselib.h $(srcdir)/basic-block.h $(srcdir)/ipa-ref.h $(srcdir)/cgraph.h \
$(srcdir)/reload.h $(srcdir)/caller-save.c $(srcdir)/symtab.c \
$(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \
- $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c \
+ $(srcdir)/ipa-prop.c $(srcdir)/ipa-cp.c $(srcdir)/ipa-utils.h \
$(srcdir)/dbxout.c \
$(srcdir)/dwarf2out.h \
$(srcdir)/dwarf2asm.c \
@@ -3907,7 +3941,6 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/cgraphclones.c \
$(srcdir)/tree-ssa-propagate.c \
$(srcdir)/tree-phinodes.c \
- $(srcdir)/lto-symtab.c \
$(srcdir)/tree-ssa-alias.h \
$(srcdir)/ipa-prop.h \
$(MELT_RUNTIME_C) \
@@ -3916,8 +3949,10 @@ GTFILES = $(CPP_ID_DATA_H) $(srcdir)/input.h $(srcdir)/coretypes.h \
$(srcdir)/lto-streamer.h \
$(srcdir)/target-globals.h \
$(srcdir)/ipa-inline.h \
+ $(srcdir)/vtable-verify.c \
$(srcdir)/asan.c \
- $(srcdir)/tsan.c \
+ $(srcdir)/ubsan.c \
+ $(srcdir)/tsan.c $(srcdir)/ipa-devirt.c \
@all_gtfiles@
# Compute the list of GT header files from the corresponding C sources,
diff --git a/gcc/aclocal.m4 b/gcc/aclocal.m4
index 33b9992b6e8..3fe609788b7 100644
--- a/gcc/aclocal.m4
+++ b/gcc/aclocal.m4
@@ -97,11 +97,6 @@ m4_define([AC_PROG_CC],
[m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
])
-m4_include([../libtool.m4])
-m4_include([../ltoptions.m4])
-m4_include([../ltsugar.m4])
-m4_include([../ltversion.m4])
-m4_include([../lt~obsolete.m4])
m4_include([../config/acx.m4])
m4_include([../config/codeset.m4])
m4_include([../config/dfp.m4])
@@ -117,4 +112,9 @@ m4_include([../config/picflag.m4])
m4_include([../config/progtest.m4])
m4_include([../config/stdint.m4])
m4_include([../config/warnings.m4])
+m4_include([../libtool.m4])
+m4_include([../ltoptions.m4])
+m4_include([../ltsugar.m4])
+m4_include([../ltversion.m4])
+m4_include([../lt~obsolete.m4])
m4_include([acinclude.m4])
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 4e0b0a8e349..61fd991bef2 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,6 +1,80 @@
+2013-09-01 Eric Botcazou <ebotcazou@adacore.com>
+ Iain Sandoe <iain@codesourcery.com>
+
+ PR ada/58239
+ * gcc-interface/Makefile.in (GCC_LINK_FLAGS): Add -static-libstdc++.
+ (GCC_LINK): Use CXX instead of CC.
+ * gcc-interface/Make-lang.in (CXX_LFLAGS): New.
+ (ADA_TOOLS_FLAGS_TO_PASS): Pass CXX, and CXX_LFLAGS for native.
+
+2013-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity): Do not bother about alias
+ sets of derived types in ASIS mode.
+
+2013-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity): Replace True with true.
+ (is_cplusplus_method): Likewise, and False with false.
+ (components_need_strict_alignment): Likewise.
+ * gcc-interface/misc.c (gnat_init_gcc_fp): Likewise.
+ * gcc-interface/trans.c (Loop_Statement_to_gnu): Likewise.
+ (Handled_Sequence_Of_Statements_to_gnu): Likewise.
+ (add_cleanup): Likewise.
+ (Sloc_to_locus1): Likewise.
+ (Sloc_to_locus): Likewise.
+ (set_expr_location_from_node): Likewise.
+ * gcc-interface/utils.c (potential_alignment_gap): Likewise.
+
+2013-08-13 Thomas Quinot <quinot@adacore.com>
+
+ * gcc-interface/trans.c (set_end_locus_from_node): Clear column info
+ for the end_locus of a block if it does not come from an End_Label.
+
+2013-08-13 Thomas Quinot <quinot@adacore.com>
+
+ * gcc-interface/trans.c (Handled_Sequence_Of_Statements_to_gnu): If
+ there is no End_Label, attach cleanup actions to the sloc of the HSS
+ node instead.
+ (Exception_Handler_to_gnu_zcx): Associate cleanup actions with the sloc
+ of the handler itself.
+ (add_cleanup): Clear column information in sloc of cleanup actions.
+ (Sloc_to_locus1): New static function.
+ (Sloc_to_locus): Call it.
+ (set_expr_location_from_node1): New static function.
+ (set_expr_location_from_node): Call it.
+
+2013-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (Call_to_gnu): Deal with specific conditional
+ expressions for misaligned actual parameters.
+
+2013-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/trans.c (can_equal_min_or_max_val_p): Be prepared for
+ values outside of the range of the type.
+
+2013-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/utils2.c (build_atomic_load): Do a mere view-conversion
+ to the original type before converting to the result type.
+ (build_atomic_store): First do a conversion to the original type before
+ view-converting to the effective type, but deal with a padded type
+ specially.
+
+2013-08-08 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/Makefile.in (TOOLS_LIBS): Pick C object files from the
+ compiler build and use standard library variables.
+ (../../vxaddr2line$(exeext): Do not depend on targext.o and adjust.
+ (gnatmake-re): Do not depend on targext.o.
+ (gnatlink-re): Do not depend on link.o and targext.o.
+ (../../gnatmake$(exeext): Likewise.
+ (../../gnatlink$(exeext): Likewise.
+
2013-07-21 Ondřej Bílka <neleai@seznam.cz>
- * gcc-interface/gigi.h: Likewise.
+ * gcc-interface/gigi.h: Fix typos.
* gcc-interface/trans.c: Likewise.
* gcc-interface/utils2.c: Likewise.
* gnat_rm.texi: Likewise.
diff --git a/gcc/ada/gcc-interface/Make-lang.in b/gcc/ada/gcc-interface/Make-lang.in
index 4fed34fc524..93250da561c 100644
--- a/gcc/ada/gcc-interface/Make-lang.in
+++ b/gcc/ada/gcc-interface/Make-lang.in
@@ -111,6 +111,12 @@ ada: gnat1$(exeext) gnatbind$(exeext)
# Tell GNU Make to ignore these, if they exist.
.PHONY: ada
+CXX_LFLAGS = \
+ -B../../../$(target_noncanonical)/libstdc++-v3/src/.libs \
+ -B../../../$(target_noncanonical)/libstdc++-v3/libsupc++/.libs \
+ -L../../../$(target_noncanonical)/libstdc++-v3/src/.libs \
+ -L../../../$(target_noncanonical)/libstdc++-v3/libsupc++/.libs
+
# There are too many Ada sources to check against here. Let's
# always force the recursive make.
ifeq ($(build), $(host))
@@ -119,6 +125,7 @@ ifeq ($(build), $(host))
# tree.
ADA_TOOLS_FLAGS_TO_PASS=\
CC="../../xgcc -B../../" \
+ CXX="../../xg++ -B../../ $(CXX_LFLAGS)" \
$(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
ADA_INCLUDES="-I- -I../rts" \
GNATMAKE="../../gnatmake" \
@@ -136,6 +143,7 @@ ifeq ($(build), $(host))
ADA_TOOLS_FLAGS_TO_PASS=\
CC="$(CC)" \
+ CXX="$(CXX)" \
$(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
ADA_INCLUDES="-I$(RTS_DIR)../adainclude -I$(RTS_DIR)" \
GNATMAKE="gnatmake" \
@@ -158,6 +166,7 @@ else
# built runtime.
ADA_TOOLS_FLAGS_TO_PASS=\
CC="$(CC)" \
+ CXX="$(CXX)" \
$(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
ADA_INCLUDES="-I../rts" \
GNATMAKE="$(GNATMAKE_FOR_HOST)" \
@@ -172,6 +181,7 @@ else
endif
ADA_TOOLS_FLAGS_TO_PASS=\
CC="$(CC)" \
+ CXX="$(CXX)" \
$(COMMON_FLAGS_TO_PASS) $(ADA_FLAGS_TO_PASS) \
ADA_INCLUDES="-I$(RTS_DIR)../adainclude -I$(RTS_DIR)" \
GNATMAKE="$(GNATMAKE_FOR_HOST)" \
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index 6aa93c4655a..0c4057c1019 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -198,7 +198,7 @@ RTSDIR = rts$(subst /,_,$(MULTISUBDIR))
# Link flags used to build gnat tools. By default we prefer to statically
# link with libgcc to avoid a dependency on shared libgcc (which is tricky
# to deal with as it may conflict with the libgcc provided by the system).
-GCC_LINK_FLAGS=-static-libgcc
+GCC_LINK_FLAGS=-static-libstdc++ -static-libgcc
# End of variables for you to override.
@@ -250,10 +250,9 @@ LIBS = $(LIBINTL) $(LIBICONV) $(LIBBACKTRACE) $(LIBIBERTY) $(SYSLIBS)
LIBDEPS = $(LIBINTL_DEP) $(LIBICONV_DEP) $(LIBBACKTRACE) $(LIBIBERTY)
# Default is no TGT_LIB; one might be passed down or something
TGT_LIB =
-TOOLS_LIBS = targext.o link.o ../../ggc-none.o ../../libcommon-target.a \
+TOOLS_LIBS = ../link.o ../targext.o ../../ggc-none.o ../../libcommon-target.a \
../../libcommon.a ../../../libcpp/libcpp.a $(LIBGNAT) $(LIBINTL) $(LIBICONV) \
- ../../../libbacktrace/.libs/libbacktrace.a ../../../libiberty/libiberty.a \
- $(SYSLIBS) $(TGT_LIB)
+ ../$(LIBBACKTRACE) ../$(LIBIBERTY) $(SYSLIBS) $(TGT_LIB)
# Convert the target variable into a space separated list of architecture,
# manufacturer, and operating system and assign each of those to its own
@@ -2276,7 +2275,7 @@ ifeq ($(strip $(filter-out darwin%,$(osys))),)
GMEM_LIB = gmemlib
LIBRARY_VERSION := $(LIB_VERSION)
soext = .dylib
- GCC_LINK_FLAGS=
+ GCC_LINK_FLAGS=-static-libstdc++
endif
# ARM Nucleus
@@ -2398,7 +2397,7 @@ TOOLS_FLAGS_TO_PASS= \
"GNATLINK=$(GNATLINK)" \
"GNATBIND=$(GNATBIND)"
-GCC_LINK=$(CC) $(GCC_LINK_FLAGS) $(ADA_INCLUDES)
+GCC_LINK=$(CXX) $(GCC_LINK_FLAGS) $(ADA_INCLUDES)
# Build directory for the tools. Let's copy the target-dependent
# sources using the same mechanism as for gnatlib. The other sources are
@@ -2491,12 +2490,12 @@ common-tools: ../stamp-tools
$(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) gnatdll
$(GNATLINK) -v gnatdll -o $@ --GCC="$(GCC_LINK)" $(TOOLS_LIBS)
-../../vxaddr2line$(exeext): ../stamp-tools targext.o
+../../vxaddr2line$(exeext): ../stamp-tools
$(GNATMAKE) -c $(ADA_INCLUDES) vxaddr2line --GCC="$(CC) $(ALL_ADAFLAGS)"
$(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) vxaddr2line
- $(GNATLINK) -v vxaddr2line -o $@ --GCC="$(GCC_LINK)" targext.o $(CLIB)
+ $(GNATLINK) -v vxaddr2line -o $@ --GCC="$(GCC_LINK)" ../targext.o $(CLIB)
-gnatmake-re: ../stamp-tools link.o targext.o
+gnatmake-re: ../stamp-tools
$(GNATMAKE) -j0 $(ADA_INCLUDES) -u sdefault --GCC="$(CC) $(MOST_ADA_FLAGS)"
$(GNATMAKE) -j0 -c $(ADA_INCLUDES) gnatmake --GCC="$(CC) $(ALL_ADAFLAGS)"
$(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) gnatmake
@@ -2507,7 +2506,7 @@ gnatmake-re: ../stamp-tools link.o targext.o
# with the former version of gnatlink itself which cannot override itself.
# gnatlink-re cannot be run at the same time as gnatmake-re, hence the
# dependency
-gnatlink-re: ../stamp-tools link.o targext.o gnatmake-re
+gnatlink-re: ../stamp-tools gnatmake-re
$(GNATMAKE) -j0 -c $(ADA_INCLUDES) gnatlink --GCC="$(CC) $(ALL_ADAFLAGS)"
$(GNATBIND) $(ADA_INCLUDES) $(GNATBIND_FLAGS) gnatlink
$(GNATLINK) -v gnatlink -o ../../gnatlinknew$(exeext) \
@@ -2519,11 +2518,11 @@ gnatlink-re: ../stamp-tools link.o targext.o gnatmake-re
# stamp target in the parent directory whenever gnat1 is rebuilt
# Likewise for the tools
-../../gnatmake$(exeext): $(P) b_gnatm.o link.o targext.o $(GNATMAKE_OBJS)
+../../gnatmake$(exeext): $(P) b_gnatm.o $(GNATMAKE_OBJS)
+$(GCC_LINK) $(ALL_CFLAGS) $(LDFLAGS) -o $@ b_gnatm.o $(GNATMAKE_OBJS) \
$(TOOLS_LIBS)
-../../gnatlink$(exeext): $(P) b_gnatl.o link.o targext.o $(GNATLINK_OBJS)
+../../gnatlink$(exeext): $(P) b_gnatl.o $(GNATLINK_OBJS)
+$(GCC_LINK) $(ALL_CFLAGS) $(LDFLAGS) -o $@ b_gnatl.o $(GNATLINK_OBJS) \
$(TOOLS_LIBS)
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index f632a3164e7..26342e2a012 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -4830,7 +4830,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
if (is_type && (!gnu_decl || this_made_decl))
{
/* Process the attributes, if not already done. Note that the type is
- already defined so we cannot pass True for IN_PLACE here. */
+ already defined so we cannot pass true for IN_PLACE here. */
process_attributes (&gnu_type, &attr_list, false, gnat_entity);
/* Tell the middle-end that objects of tagged types are guaranteed to
@@ -5153,7 +5153,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
to conflict with Comp2 and an alias set copy is required.
The language rules ensure the parent type is already frozen here. */
- if (Is_Derived_Type (gnat_entity))
+ if (Is_Derived_Type (gnat_entity) && !type_annotate_only)
{
tree gnu_parent_type = gnat_to_gnu_type (Etype (gnat_entity));
relate_alias_sets (gnu_type, gnu_parent_type,
@@ -5449,26 +5449,26 @@ bool
is_cplusplus_method (Entity_Id gnat_entity)
{
if (Convention (gnat_entity) != Convention_CPP)
- return False;
+ return false;
/* This is the main case: C++ method imported as a primitive operation. */
if (Is_Dispatching_Operation (gnat_entity))
- return True;
+ return true;
/* A thunk needs to be handled like its associated primitive operation. */
if (Is_Subprogram (gnat_entity) && Is_Thunk (gnat_entity))
- return True;
+ return true;
/* C++ classes with no virtual functions can be imported as limited
record types, but we need to return true for the constructors. */
if (Is_Constructor (gnat_entity))
- return True;
+ return true;
/* This is set on the E_Subprogram_Type built for a dispatching call. */
if (Is_Dispatch_Table_Entity (gnat_entity))
- return True;
+ return true;
- return False;
+ return false;
}
/* Finalize the processing of From_With_Type incomplete types. */
@@ -6727,13 +6727,13 @@ components_need_strict_alignment (Node_Id component_list)
Entity_Id gnat_field = Defining_Entity (component_decl);
if (Is_Aliased (gnat_field))
- return True;
+ return true;
if (Strict_Alignment (Etype (gnat_field)))
- return True;
+ return true;
}
- return False;
+ return false;
}
/* Return true if TYPE is a type with variable size or a padding type with a
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 7b168df4e03..3abe57b6bd9 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -385,13 +385,13 @@ void
gnat_init_gcc_fp (void)
{
/* Disable FP optimizations that ignore the signedness of zero if
- S'Signed_Zeros is True, but don't override the user if not. */
+ S'Signed_Zeros is true, but don't override the user if not. */
if (Signed_Zeros_On_Target)
flag_signed_zeros = 1;
else if (!global_options_set.x_flag_signed_zeros)
flag_signed_zeros = 0;
- /* Assume that FP operations can trap if S'Machine_Overflow is True,
+ /* Assume that FP operations can trap if S'Machine_Overflow is true,
but don't override the user if not.
??? Alpha/VMS enables FP traps without declaring it. */
diff --git a/gcc/ada/gcc-interface/trans.c b/gcc/ada/gcc-interface/trans.c
index f91f4b83a6e..4048e0aefe9 100644
--- a/gcc/ada/gcc-interface/trans.c
+++ b/gcc/ada/gcc-interface/trans.c
@@ -257,6 +257,8 @@ static tree pos_to_constructor (Node_Id, tree, Entity_Id);
static void validate_unchecked_conversion (Node_Id);
static tree maybe_implicit_deref (tree);
static void set_expr_location_from_node (tree, Node_Id);
+static void set_expr_location_from_node1 (tree, Node_Id, bool);
+static bool Sloc_to_locus1 (Source_Ptr, location_t *, bool);
static bool set_end_locus_from_node (tree, Node_Id);
static void set_gnu_expr_location_from_node (tree, Node_Id);
static int lvalue_required_p (Node_Id, tree, bool, bool, bool);
@@ -2391,7 +2393,10 @@ can_equal_min_or_max_val_p (tree val, tree type, bool max)
if (TREE_CODE (val) != INTEGER_CST)
return true;
- return tree_int_cst_equal (val, min_or_max_val) == 1;
+ if (max)
+ return tree_int_cst_lt (val, min_or_max_val) == 0;
+ else
+ return tree_int_cst_lt (min_or_max_val, val) == 0;
}
/* Return true if VAL (of type TYPE) can equal the minimum value of TYPE.
@@ -2716,7 +2721,7 @@ Loop_Statement_to_gnu (Node_Id gnat_node)
/* First, if we have computed a small number of invariant conditions for
range checks applied to the iteration variable, then initialize these
- conditions in front of the loop. Otherwise, leave them set to True.
+ conditions in front of the loop. Otherwise, leave them set to true.
??? The heuristics need to be improved, by taking into account the
following datapoints:
@@ -4019,9 +4024,19 @@ Call_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p, tree gnu_target,
/* Set up to move the copy back to the original if needed. */
if (!in_param)
{
- gnu_stmt = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_orig,
- gnu_temp);
+ /* If the original is a COND_EXPR whose first arm isn't meant to
+ be further used, just deal with the second arm. This is very
+ likely the conditional expression built for a check. */
+ if (TREE_CODE (gnu_orig) == COND_EXPR
+ && TREE_CODE (TREE_OPERAND (gnu_orig, 1)) == COMPOUND_EXPR
+ && integer_zerop
+ (TREE_OPERAND (TREE_OPERAND (gnu_orig, 1), 1)))
+ gnu_orig = TREE_OPERAND (gnu_orig, 2);
+
+ gnu_stmt
+ = build_binary_op (MODIFY_EXPR, NULL_TREE, gnu_orig, gnu_temp);
set_expr_location_from_node (gnu_stmt, gnat_node);
+
append_to_statement_list (gnu_stmt, &gnu_after_list);
}
}
@@ -4458,6 +4473,10 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
tree gnu_result;
tree gnu_expr;
Node_Id gnat_temp;
+ /* Node providing the sloc for the cleanup actions. */
+ Node_Id gnat_cleanup_loc_node = (Present (End_Label (gnat_node)) ?
+ End_Label (gnat_node) :
+ gnat_node);
/* The GCC exception handling mechanism can handle both ZCX and SJLJ schemes
and we have our own SJLJ mechanism. To call the GCC mechanism, we call
@@ -4507,7 +4526,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
/* When we exit this block, restore the saved value. */
add_cleanup (build_call_n_expr (set_jmpbuf_decl, 1, gnu_jmpsave_decl),
- End_Label (gnat_node));
+ gnat_cleanup_loc_node);
}
/* If we are to call a function when exiting this block, add a cleanup
@@ -4515,7 +4534,7 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
so we must register this cleanup after the EH cleanup just above. */
if (at_end)
add_cleanup (build_call_n_expr (gnat_to_gnu (At_End_Proc (gnat_node)), 0),
- End_Label (gnat_node));
+ gnat_cleanup_loc_node);
/* Now build the tree for the declarations and statements inside this block.
If this is SJLJ, set our jmp_buf as the current buffer. */
@@ -4628,14 +4647,18 @@ Handled_Sequence_Of_Statements_to_gnu (Node_Id gnat_node)
/* Now make the TRY_CATCH_EXPR for the block. */
gnu_result = build2 (TRY_CATCH_EXPR, void_type_node,
gnu_inner_block, gnu_handlers);
- /* Set a location. We need to find a uniq location for the dispatching
+ /* Set a location. We need to find a unique location for the dispatching
code, otherwise we can get coverage or debugging issues. Try with
the location of the end label. */
if (Present (End_Label (gnat_node))
&& Sloc_to_locus (Sloc (End_Label (gnat_node)), &locus))
SET_EXPR_LOCATION (gnu_result, locus);
else
- set_expr_location_from_node (gnu_result, gnat_node);
+ /* Clear column information so that the exception handler of an
+ implicit transient block does not incorrectly inherit the slocs
+ of a decision, which would otherwise confuse control flow based
+ coverage analysis tools. */
+ set_expr_location_from_node1 (gnu_result, gnat_node, true);
}
else
gnu_result = gnu_inner_block;
@@ -4830,9 +4853,10 @@ Exception_Handler_to_gnu_zcx (Node_Id gnat_node)
add_stmt_with_node (build_call_n_expr (begin_handler_decl, 1,
gnu_incoming_exc_ptr),
gnat_node);
- /* ??? We don't seem to have an End_Label at hand to set the location. */
+ /* We don't have an End_Label at hand to set the location of the cleanup
+ actions, so we use that of the exception handler itself instead. */
add_cleanup (build_call_n_expr (end_handler_decl, 1, gnu_incoming_exc_ptr),
- Empty);
+ gnat_node);
add_stmt_list (Statements (gnat_node));
gnat_poplevel ();
@@ -7384,13 +7408,15 @@ mark_visited (tree t)
}
/* Add GNU_CLEANUP, a cleanup action, to the current code group and
- set its location to that of GNAT_NODE if present. */
+ set its location to that of GNAT_NODE if present, but with column info
+ cleared so that conditional branches generated as part of the cleanup
+ code do not interfere with coverage analysis tools. */
static void
add_cleanup (tree gnu_cleanup, Node_Id gnat_node)
{
if (Present (gnat_node))
- set_expr_location_from_node (gnu_cleanup, gnat_node);
+ set_expr_location_from_node1 (gnu_cleanup, gnat_node, true);
append_to_statement_list (gnu_cleanup, &current_stmt_group->cleanups);
}
@@ -9005,10 +9031,11 @@ maybe_implicit_deref (tree exp)
/* Convert SLOC into LOCUS. Return true if SLOC corresponds to a source code
location and false if it doesn't. In the former case, set the Gigi global
- variable REF_FILENAME to the simple debug file name as given by sinput. */
+ variable REF_FILENAME to the simple debug file name as given by sinput.
+ If clear_column is true, set column information to 0. */
-bool
-Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
+static bool
+Sloc_to_locus1 (Source_Ptr Sloc, location_t *locus, bool clear_column)
{
if (Sloc == No_Location)
return false;
@@ -9022,7 +9049,7 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
{
Source_File_Index file = Get_Source_File_Index (Sloc);
Logical_Line_Number line = Get_Logical_Line_Number (Sloc);
- Column_Number column = Get_Column_Number (Sloc);
+ Column_Number column = (clear_column ? 0 : Get_Column_Number (Sloc));
struct line_map *map = LINEMAPS_ORDINARY_MAP_AT (line_table, file - 1);
/* We can have zero if pragma Source_Reference is in effect. */
@@ -9041,20 +9068,36 @@ Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
return true;
}
+/* Similar to the above, not clearing the column information. */
+
+bool
+Sloc_to_locus (Source_Ptr Sloc, location_t *locus)
+{
+ return Sloc_to_locus1 (Sloc, locus, false);
+}
+
/* Similar to set_expr_location, but start with the Sloc of GNAT_NODE and
don't do anything if it doesn't correspond to a source location. */
static void
-set_expr_location_from_node (tree node, Node_Id gnat_node)
+set_expr_location_from_node1 (tree node, Node_Id gnat_node, bool clear_column)
{
location_t locus;
- if (!Sloc_to_locus (Sloc (gnat_node), &locus))
+ if (!Sloc_to_locus1 (Sloc (gnat_node), &locus, clear_column))
return;
SET_EXPR_LOCATION (node, locus);
}
+/* Similar to the above, not clearing the column information. */
+
+static void
+set_expr_location_from_node (tree node, Node_Id gnat_node)
+{
+ set_expr_location_from_node1 (node, gnat_node, false);
+}
+
/* More elaborate version of set_expr_location_from_node to be used in more
general contexts, for example the result of the translation of a generic
GNAT node. */
@@ -9185,9 +9228,13 @@ set_end_locus_from_node (tree gnu_node, Node_Id gnat_node)
gnat_node = Present (gnat_end_label) ? gnat_end_label : gnat_node;
/* Some expanded subprograms have neither an End_Label nor a Sloc
- attached. Notify that to callers. */
+ attached. Notify that to callers. For a block statement with no
+ End_Label, clear column information, so that the tree for a
+ transient block does not receive the sloc of a source condition. */
- if (!Sloc_to_locus (Sloc (gnat_node), &end_locus))
+ if (!Sloc_to_locus1 (Sloc (gnat_node), &end_locus,
+ No (gnat_end_label) &&
+ (Nkind (gnat_node) == N_Block_Statement)))
return false;
switch (TREE_CODE (gnu_node))
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index 409c0dee94f..2c3e096f120 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -2573,7 +2573,7 @@ potential_alignment_gap (tree prev_field, tree curr_field, tree offset)
if (!prev_field)
return false;
- /* If the previous field is a union type, then return False: The only
+ /* If the previous field is a union type, then return false: The only
time when such a field is not the last field of the record is when
there are other components at fixed positions after it (meaning there
was a rep clause for every field), in which case we don't want the
diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c
index 7f7f6af034a..64f7564a75d 100644
--- a/gcc/ada/gcc-interface/utils2.c
+++ b/gcc/ada/gcc-interface/utils2.c
@@ -648,11 +648,11 @@ build_atomic_load (tree src)
(build_qualified_type (void_type_node, TYPE_QUAL_VOLATILE));
tree mem_model = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST);
tree orig_src = src;
- tree type = TREE_TYPE (src);
- tree t, val;
+ tree t, addr, val;
unsigned int size;
int fncode;
+ /* Remove conversions to get the address of the underlying object. */
src = remove_conversions (src, false);
size = resolve_atomic_size (TREE_TYPE (src));
if (size == 0)
@@ -661,10 +661,13 @@ build_atomic_load (tree src)
fncode = (int) BUILT_IN_ATOMIC_LOAD_N + exact_log2 (size) + 1;
t = builtin_decl_implicit ((enum built_in_function) fncode);
- src = build_unary_op (ADDR_EXPR, ptr_type, src);
- val = build_call_expr (t, 2, src, mem_model);
+ addr = build_unary_op (ADDR_EXPR, ptr_type, src);
+ val = build_call_expr (t, 2, addr, mem_model);
- return unchecked_convert (type, val, true);
+ /* First reinterpret the loaded bits in the original type of the load,
+ then convert to the expected result type. */
+ t = fold_build1 (VIEW_CONVERT_EXPR, TREE_TYPE (src), val);
+ return convert (TREE_TYPE (orig_src), t);
}
/* Build an atomic store from SRC to the underlying atomic object in DEST. */
@@ -677,10 +680,11 @@ build_atomic_store (tree dest, tree src)
(build_qualified_type (void_type_node, TYPE_QUAL_VOLATILE));
tree mem_model = build_int_cst (integer_type_node, MEMMODEL_SEQ_CST);
tree orig_dest = dest;
- tree t, int_type;
+ tree t, int_type, addr;
unsigned int size;
int fncode;
+ /* Remove conversions to get the address of the underlying object. */
dest = remove_conversions (dest, false);
size = resolve_atomic_size (TREE_TYPE (dest));
if (size == 0)
@@ -690,10 +694,20 @@ build_atomic_store (tree dest, tree src)
t = builtin_decl_implicit ((enum built_in_function) fncode);
int_type = gnat_type_for_size (BITS_PER_UNIT * size, 1);
- dest = build_unary_op (ADDR_EXPR, ptr_type, dest);
- src = unchecked_convert (int_type, src, true);
+ /* First convert the bits to be stored to the original type of the store,
+ then reinterpret them in the effective type. But if the original type
+ is a padded type with the same size, convert to the inner type instead,
+ as we don't want to artificially introduce a CONSTRUCTOR here. */
+ if (TYPE_IS_PADDING_P (TREE_TYPE (dest))
+ && TYPE_SIZE (TREE_TYPE (dest))
+ == TYPE_SIZE (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (dest)))))
+ src = convert (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (dest))), src);
+ else
+ src = convert (TREE_TYPE (dest), src);
+ src = fold_build1 (VIEW_CONVERT_EXPR, int_type, src);
+ addr = build_unary_op (ADDR_EXPR, ptr_type, dest);
- return build_call_expr (t, 3, dest, src, mem_model);
+ return build_call_expr (t, 3, addr, src, mem_model);
}
/* Make a binary operation of kind OP_CODE. RESULT_TYPE is the type
diff --git a/gcc/ada/sigtramp-ppcvxw.c b/gcc/ada/sigtramp-ppcvxw.c
index 69baa1420df..e7b318fa9bf 100644
--- a/gcc/ada/sigtramp-ppcvxw.c
+++ b/gcc/ada/sigtramp-ppcvxw.c
@@ -6,7 +6,7 @@
* *
* Asm Implementation File *
* *
- * Copyright (C) 2011-2012, Free Software Foundation, Inc. *
+ * Copyright (C) 2011-2013, Free Software Foundation, Inc. *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
diff --git a/gcc/ada/terminals.c b/gcc/ada/terminals.c
index dfadca8d6a9..8672ca372b6 100644
--- a/gcc/ada/terminals.c
+++ b/gcc/ada/terminals.c
@@ -6,7 +6,7 @@
* *
* C Implementation File *
* *
- * Copyright (C) 2008-2012, AdaCore *
+ * Copyright (C) 2008-2013, AdaCore *
* *
* GNAT is free software; you can redistribute it and/or modify it under *
* terms of the GNU General Public License as published by the Free Soft- *
diff --git a/gcc/asan.c b/gcc/asan.c
index b12cf447cc5..af215f681c3 100644
--- a/gcc/asan.c
+++ b/gcc/asan.c
@@ -842,25 +842,12 @@ asan_init_shadow_ptr_types (void)
initialize_sanitizer_builtins ();
}
-/* Asan pretty-printer, used for buidling of the description STRING_CSTs. */
-static pretty_printer asan_pp;
-static bool asan_pp_initialized;
-
-/* Initialize asan_pp. */
-
-static void
-asan_pp_initialize (void)
-{
- pp_construct (&asan_pp, /* prefix */NULL, /* line-width */0);
- asan_pp_initialized = true;
-}
-
-/* Create ADDR_EXPR of STRING_CST with asan_pp text. */
+/* Create ADDR_EXPR of STRING_CST with the PP pretty printer text. */
static tree
-asan_pp_string (void)
+asan_pp_string (pretty_printer *pp)
{
- const char *buf = pp_base_formatted_text (&asan_pp);
+ const char *buf = pp_formatted_text (pp);
size_t len = strlen (buf);
tree ret = build_string (len + 1, buf);
TREE_TYPE (ret)
@@ -882,7 +869,7 @@ asan_shadow_cst (unsigned char shadow_bytes[4])
for (i = 0; i < 4; i++)
val |= (unsigned HOST_WIDE_INT) shadow_bytes[BYTES_BIG_ENDIAN ? 3 - i : i]
<< (BITS_PER_UNIT * i);
- return GEN_INT (trunc_int_for_mode (val, SImode));
+ return gen_int_mode (val, SImode);
}
/* Clear shadow memory at SHADOW_MEM, LEN bytes. Can't call a library call here
@@ -950,12 +937,10 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls,
asan_init_shadow_ptr_types ();
/* First of all, prepare the description string. */
- if (!asan_pp_initialized)
- asan_pp_initialize ();
+ pretty_printer asan_pp;
- pp_clear_output_area (&asan_pp);
if (DECL_NAME (current_function_decl))
- pp_base_tree_identifier (&asan_pp, DECL_NAME (current_function_decl));
+ pp_tree_identifier (&asan_pp, DECL_NAME (current_function_decl));
else
pp_string (&asan_pp, "<unknown>");
pp_space (&asan_pp);
@@ -972,13 +957,13 @@ asan_emit_stack_protection (rtx base, HOST_WIDE_INT *offsets, tree *decls,
{
pp_decimal_int (&asan_pp, IDENTIFIER_LENGTH (DECL_NAME (decl)));
pp_space (&asan_pp);
- pp_base_tree_identifier (&asan_pp, DECL_NAME (decl));
+ pp_tree_identifier (&asan_pp, DECL_NAME (decl));
}
else
pp_string (&asan_pp, "9 <unknown>");
pp_space (&asan_pp);
}
- str_cst = asan_pp_string ();
+ str_cst = asan_pp_string (&asan_pp);
/* Emit the prologue sequence. */
base = expand_binop (Pmode, add_optab, base, GEN_INT (base_offset),
@@ -1648,7 +1633,7 @@ instrument_mem_region_access (tree base, tree len,
access to the last byte of the argument; it uses the result of the
call to deduce the offset of that last byte.
- Upon completion, iff the call has actullay been instrumented, this
+ Upon completion, iff the call has actually been instrumented, this
function returns TRUE and *ITER points to the statement logically
following the built-in strlen function call *ITER was initially
pointing to. Otherwise, the function returns FALSE and *ITER
@@ -1679,10 +1664,10 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
/* Instrument the access to the first byte of str_arg. i.e:
_1 = str_arg; instrument (_1); */
+ tree cptr_type = build_pointer_type (char_type_node);
gimple str_arg_ssa =
gimple_build_assign_with_ops (NOP_EXPR,
- make_ssa_name (build_pointer_type
- (char_type_node), NULL),
+ make_ssa_name (cptr_type, NULL),
str_arg, NULL);
gimple_set_location (str_arg_ssa, loc);
gimple_stmt_iterator gsi = *iter;
@@ -1701,8 +1686,7 @@ instrument_strlen_call (gimple_stmt_iterator *iter)
pointer_plus expr: (_1 + len). */
gimple stmt =
gimple_build_assign_with_ops (POINTER_PLUS_EXPR,
- make_ssa_name (TREE_TYPE (str_arg),
- NULL),
+ make_ssa_name (cptr_type, NULL),
gimple_assign_lhs (str_arg_ssa),
len);
gimple_set_location (stmt, loc);
@@ -1954,7 +1938,7 @@ asan_global_struct (void)
= build_decl (UNKNOWN_LOCATION, FIELD_DECL,
get_identifier (field_names[i]),
(i == 0 || i == 3) ? const_ptr_type_node
- : build_nonstandard_integer_type (POINTER_SIZE, 1));
+ : pointer_sized_int_node);
DECL_CONTEXT (fields[i]) = ret;
if (i)
DECL_CHAIN (fields[i - 1]) = fields[i];
@@ -1976,19 +1960,17 @@ asan_add_global (tree decl, tree type, vec<constructor_elt, va_gc> *v)
tree str_cst, refdecl = decl;
vec<constructor_elt, va_gc> *vinner = NULL;
- if (!asan_pp_initialized)
- asan_pp_initialize ();
+ pretty_printer asan_pp;
- pp_clear_output_area (&asan_pp);
if (DECL_NAME (decl))
- pp_base_tree_identifier (&asan_pp, DECL_NAME (decl));
+ pp_tree_identifier (&asan_pp, DECL_NAME (decl));
else
pp_string (&asan_pp, "<unknown>");
pp_space (&asan_pp);
pp_left_paren (&asan_pp);
pp_string (&asan_pp, main_input_filename);
pp_right_paren (&asan_pp);
- str_cst = asan_pp_string ();
+ str_cst = asan_pp_string (&asan_pp);
if (asan_needs_local_alias (decl))
{
@@ -2034,10 +2016,12 @@ initialize_sanitizer_builtins (void)
tree BT_FN_VOID = build_function_type_list (void_type_node, NULL_TREE);
tree BT_FN_VOID_PTR
= build_function_type_list (void_type_node, ptr_type_node, NULL_TREE);
+ tree BT_FN_VOID_PTR_PTR_PTR
+ = build_function_type_list (void_type_node, ptr_type_node,
+ ptr_type_node, ptr_type_node, NULL_TREE);
tree BT_FN_VOID_PTR_PTRMODE
= build_function_type_list (void_type_node, ptr_type_node,
- build_nonstandard_integer_type (POINTER_SIZE,
- 1), NULL_TREE);
+ pointer_sized_int_node, NULL_TREE);
tree BT_FN_VOID_INT
= build_function_type_list (void_type_node, integer_type_node, NULL_TREE);
tree BT_FN_BOOL_VPTR_PTR_IX_INT_INT[5];
@@ -2099,6 +2083,12 @@ initialize_sanitizer_builtins (void)
#undef ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST
#define ATTR_TMPURE_NORETURN_NOTHROW_LEAF_LIST \
ECF_TM_PURE | ATTR_NORETURN_NOTHROW_LEAF_LIST
+#undef ATTR_COLD_NOTHROW_LEAF_LIST
+#define ATTR_COLD_NOTHROW_LEAF_LIST \
+ /* ECF_COLD missing */ ATTR_NOTHROW_LEAF_LIST
+#undef ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST
+#define ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST \
+ /* ECF_COLD missing */ ATTR_NORETURN_NOTHROW_LEAF_LIST
#undef DEF_SANITIZER_BUILTIN
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
decl = add_builtin_function ("__builtin_" NAME, TYPE, ENUM, \
@@ -2175,7 +2165,7 @@ asan_finish_file (void)
/* Avoid instrumenting code in the asan ctors/dtors.
We don't need to insert padding after the description strings,
nor after .LASAN* array. */
- flag_asan = 0;
+ flag_sanitize &= ~SANITIZE_ADDRESS;
tree fn = builtin_decl_implicit (BUILT_IN_ASAN_INIT);
append_to_statement_list (build_call_expr (fn, 0), &asan_ctor_statements);
@@ -2188,7 +2178,6 @@ asan_finish_file (void)
if (gcount)
{
tree type = asan_global_struct (), var, ctor;
- tree uptr = build_nonstandard_integer_type (POINTER_SIZE, 1);
tree dtor_statements = NULL_TREE;
vec<constructor_elt, va_gc> *v;
char buf[20];
@@ -2217,22 +2206,23 @@ asan_finish_file (void)
varpool_assemble_decl (varpool_node_for_decl (var));
fn = builtin_decl_implicit (BUILT_IN_ASAN_REGISTER_GLOBALS);
+ tree gcount_tree = build_int_cst (pointer_sized_int_node, gcount);
append_to_statement_list (build_call_expr (fn, 2,
build_fold_addr_expr (var),
- build_int_cst (uptr, gcount)),
+ gcount_tree),
&asan_ctor_statements);
fn = builtin_decl_implicit (BUILT_IN_ASAN_UNREGISTER_GLOBALS);
append_to_statement_list (build_call_expr (fn, 2,
build_fold_addr_expr (var),
- build_int_cst (uptr, gcount)),
+ gcount_tree),
&dtor_statements);
cgraph_build_static_cdtor ('D', dtor_statements,
MAX_RESERVED_INIT_PRIORITY - 1);
}
cgraph_build_static_cdtor ('I', asan_ctor_statements,
MAX_RESERVED_INIT_PRIORITY - 1);
- flag_asan = 1;
+ flag_sanitize |= SANITIZE_ADDRESS;
}
/* Instrument the current function. */
@@ -2249,57 +2239,94 @@ asan_instrument (void)
static bool
gate_asan (void)
{
- return flag_asan != 0
+ return (flag_sanitize & SANITIZE_ADDRESS) != 0
&& !lookup_attribute ("no_sanitize_address",
DECL_ATTRIBUTES (current_function_decl));
}
-struct gimple_opt_pass pass_asan =
+namespace {
+
+const pass_data pass_data_asan =
{
- {
- GIMPLE_PASS,
- "asan", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_asan, /* gate */
- asan_instrument, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa | PROP_cfg | PROP_gimple_leh,/* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow | TODO_verify_stmts
- | TODO_update_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "asan", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_flow | TODO_verify_stmts
+ | TODO_update_ssa ), /* todo_flags_finish */
};
+class pass_asan : public gimple_opt_pass
+{
+public:
+ pass_asan(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_asan, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_asan (ctxt_); }
+ bool gate () { return gate_asan (); }
+ unsigned int execute () { return asan_instrument (); }
+
+}; // class pass_asan
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_asan (gcc::context *ctxt)
+{
+ return new pass_asan (ctxt);
+}
+
static bool
gate_asan_O0 (void)
{
return !optimize && gate_asan ();
}
-struct gimple_opt_pass pass_asan_O0 =
+namespace {
+
+const pass_data pass_data_asan_O0 =
{
- {
- GIMPLE_PASS,
- "asan0", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_asan_O0, /* gate */
- asan_instrument, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa | PROP_cfg | PROP_gimple_leh,/* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow | TODO_verify_stmts
- | TODO_update_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "asan0", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_flow | TODO_verify_stmts
+ | TODO_update_ssa ), /* todo_flags_finish */
};
+class pass_asan_O0 : public gimple_opt_pass
+{
+public:
+ pass_asan_O0(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_asan_O0, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_asan_O0 (); }
+ unsigned int execute () { return asan_instrument (); }
+
+}; // class pass_asan_O0
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_asan_O0 (gcc::context *ctxt)
+{
+ return new pass_asan_O0 (ctxt);
+}
+
#include "gt-asan.h"
diff --git a/gcc/auto-inc-dec.c b/gcc/auto-inc-dec.c
index 6119bb6e757..0d92b1d79b5 100644
--- a/gcc/auto-inc-dec.c
+++ b/gcc/auto-inc-dec.c
@@ -1506,22 +1506,40 @@ gate_auto_inc_dec (void)
}
-struct rtl_opt_pass pass_inc_dec =
+namespace {
+
+const pass_data pass_data_inc_dec =
{
- {
- RTL_PASS,
- "auto_inc_dec", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_auto_inc_dec, /* gate */
- rest_of_handle_auto_inc_dec, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_AUTO_INC_DEC, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "auto_inc_dec", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_AUTO_INC_DEC, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_df_finish, /* todo_flags_finish */
};
+
+class pass_inc_dec : public rtl_opt_pass
+{
+public:
+ pass_inc_dec(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_inc_dec, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_auto_inc_dec (); }
+ unsigned int execute () { return rest_of_handle_auto_inc_dec (); }
+
+}; // class pass_inc_dec
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_inc_dec (gcc::context *ctxt)
+{
+ return new pass_inc_dec (ctxt);
+}
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 154dc7a2c31..ad04d4de83e 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -465,6 +465,23 @@ struct edge_list
edge *index_to_edge;
};
+/* Class to compute and manage control dependences on an edge-list. */
+class control_dependences
+{
+public:
+ control_dependences (edge_list *);
+ ~control_dependences ();
+ bitmap get_edges_dependent_on (int);
+ edge get_edge (int);
+
+private:
+ void set_control_dependence_map_bit (basic_block, int);
+ void clear_control_dependence_bitmap (basic_block);
+ void find_control_dependence (int);
+ vec<bitmap> control_dependence_map;
+ edge_list *el;
+};
+
/* The base value for branch probability notes and edge probabilities. */
#define REG_BR_PROB_BASE 10000
@@ -726,6 +743,7 @@ extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
extern bool maybe_hot_bb_p (struct function *, const_basic_block);
extern bool maybe_hot_edge_p (edge);
extern bool probably_never_executed_bb_p (struct function *, const_basic_block);
+extern bool probably_never_executed_edge_p (struct function *, edge);
extern bool optimize_bb_for_size_p (const_basic_block);
extern bool optimize_bb_for_speed_p (const_basic_block);
extern bool optimize_edge_for_size_p (edge);
@@ -797,6 +815,7 @@ extern bool contains_no_active_insn_p (const_basic_block);
extern bool forwarder_block_p (const_basic_block);
extern bool can_fallthru (basic_block, basic_block);
extern void emit_barrier_after_bb (basic_block bb);
+extern void fixup_partitions (void);
/* In cfgbuild.c. */
extern void find_many_sub_basic_blocks (sbitmap);
@@ -958,7 +977,7 @@ combine_probabilities (int prob1, int prob2)
constrained to be < REG_BR_PROB_BASE. */
static inline gcov_type
-apply_scale (gcov_type freq, int scale)
+apply_scale (gcov_type freq, gcov_type scale)
{
return RDIV (freq * scale, REG_BR_PROB_BASE);
}
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c
index 2cbeb6ae9f3..6b034aba5c9 100644
--- a/gcc/bb-reorder.c
+++ b/gcc/bb-reorder.c
@@ -1444,25 +1444,155 @@ fix_up_crossing_landing_pad (eh_landing_pad old_lp, basic_block old_bb)
ei_next (&ei);
}
+
+/* Ensure that all hot bbs are included in a hot path through the
+ procedure. This is done by calling this function twice, once
+ with WALK_UP true (to look for paths from the entry to hot bbs) and
+ once with WALK_UP false (to look for paths from hot bbs to the exit).
+ Returns the updated value of COLD_BB_COUNT and adds newly-hot bbs
+ to BBS_IN_HOT_PARTITION. */
+
+static unsigned int
+sanitize_hot_paths (bool walk_up, unsigned int cold_bb_count,
+ vec<basic_block> *bbs_in_hot_partition)
+{
+ /* Callers check this. */
+ gcc_checking_assert (cold_bb_count);
+
+ /* Keep examining hot bbs while we still have some left to check
+ and there are remaining cold bbs. */
+ vec<basic_block> hot_bbs_to_check = bbs_in_hot_partition->copy ();
+ while (! hot_bbs_to_check.is_empty ()
+ && cold_bb_count)
+ {
+ basic_block bb = hot_bbs_to_check.pop ();
+ vec<edge, va_gc> *edges = walk_up ? bb->preds : bb->succs;
+ edge e;
+ edge_iterator ei;
+ int highest_probability = 0;
+ int highest_freq = 0;
+ gcov_type highest_count = 0;
+ bool found = false;
+
+ /* Walk the preds/succs and check if there is at least one already
+ marked hot. Keep track of the most frequent pred/succ so that we
+ can mark it hot if we don't find one. */
+ FOR_EACH_EDGE (e, ei, edges)
+ {
+ basic_block reach_bb = walk_up ? e->src : e->dest;
+
+ if (e->flags & EDGE_DFS_BACK)
+ continue;
+
+ if (BB_PARTITION (reach_bb) != BB_COLD_PARTITION)
+ {
+ found = true;
+ break;
+ }
+ /* The following loop will look for the hottest edge via
+ the edge count, if it is non-zero, then fallback to the edge
+ frequency and finally the edge probability. */
+ if (e->count > highest_count)
+ highest_count = e->count;
+ int edge_freq = EDGE_FREQUENCY (e);
+ if (edge_freq > highest_freq)
+ highest_freq = edge_freq;
+ if (e->probability > highest_probability)
+ highest_probability = e->probability;
+ }
+
+ /* If bb is reached by (or reaches, in the case of !WALK_UP) another hot
+ block (or unpartitioned, e.g. the entry block) then it is ok. If not,
+ then the most frequent pred (or succ) needs to be adjusted. In the
+ case where multiple preds/succs have the same frequency (e.g. a
+ 50-50 branch), then both will be adjusted. */
+ if (found)
+ continue;
+
+ FOR_EACH_EDGE (e, ei, edges)
+ {
+ if (e->flags & EDGE_DFS_BACK)
+ continue;
+ /* Select the hottest edge using the edge count, if it is non-zero,
+ then fallback to the edge frequency and finally the edge
+ probability. */
+ if (highest_count)
+ {
+ if (e->count < highest_count)
+ continue;
+ }
+ else if (highest_freq)
+ {
+ if (EDGE_FREQUENCY (e) < highest_freq)
+ continue;
+ }
+ else if (e->probability < highest_probability)
+ continue;
+
+ basic_block reach_bb = walk_up ? e->src : e->dest;
+
+ /* We have a hot bb with an immediate dominator that is cold.
+ The dominator needs to be re-marked hot. */
+ BB_SET_PARTITION (reach_bb, BB_HOT_PARTITION);
+ cold_bb_count--;
+
+ /* Now we need to examine newly-hot reach_bb to see if it is also
+ dominated by a cold bb. */
+ bbs_in_hot_partition->safe_push (reach_bb);
+ hot_bbs_to_check.safe_push (reach_bb);
+ }
+ }
+
+ return cold_bb_count;
+}
+
+
/* Find the basic blocks that are rarely executed and need to be moved to
a separate section of the .o file (to cut down on paging and improve
cache locality). Return a vector of all edges that cross. */
-static vec<edge>
+static vec<edge>
find_rarely_executed_basic_blocks_and_crossing_edges (void)
{
vec<edge> crossing_edges = vNULL;
basic_block bb;
edge e;
edge_iterator ei;
+ unsigned int cold_bb_count = 0;
+ vec<basic_block> bbs_in_hot_partition = vNULL;
/* Mark which partition (hot/cold) each basic block belongs in. */
FOR_EACH_BB (bb)
{
if (probably_never_executed_bb_p (cfun, bb))
- BB_SET_PARTITION (bb, BB_COLD_PARTITION);
+ {
+ BB_SET_PARTITION (bb, BB_COLD_PARTITION);
+ cold_bb_count++;
+ }
else
- BB_SET_PARTITION (bb, BB_HOT_PARTITION);
+ {
+ BB_SET_PARTITION (bb, BB_HOT_PARTITION);
+ bbs_in_hot_partition.safe_push (bb);
+ }
+ }
+
+ /* Ensure that hot bbs are included along a hot path from the entry to exit.
+ Several different possibilities may include cold bbs along all paths
+ to/from a hot bb. One is that there are edge weight insanities
+ due to optimization phases that do not properly update basic block profile
+ counts. The second is that the entry of the function may not be hot, because
+ it is entered fewer times than the number of profile training runs, but there
+ is a loop inside the function that causes blocks within the function to be
+ above the threshold for hotness. This is fixed by walking up from hot bbs
+ to the entry block, and then down from hot bbs to the exit, performing
+ partitioning fixups as necessary. */
+ if (cold_bb_count)
+ {
+ mark_dfs_back_edges ();
+ cold_bb_count = sanitize_hot_paths (true, cold_bb_count,
+ &bbs_in_hot_partition);
+ if (cold_bb_count)
+ sanitize_hot_paths (false, cold_bb_count, &bbs_in_hot_partition);
}
/* The format of .gcc_except_table does not allow landing pads to
@@ -2179,26 +2309,44 @@ rest_of_handle_reorder_blocks (void)
return 0;
}
-struct rtl_opt_pass pass_reorder_blocks =
+namespace {
+
+const pass_data pass_data_reorder_blocks =
{
- {
- RTL_PASS,
- "bbro", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_reorder_blocks, /* gate */
- rest_of_handle_reorder_blocks, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_REORDER_BLOCKS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "bbro", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_REORDER_BLOCKS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_reorder_blocks : public rtl_opt_pass
+{
+public:
+ pass_reorder_blocks(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_reorder_blocks, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_reorder_blocks (); }
+ unsigned int execute () { return rest_of_handle_reorder_blocks (); }
+
+}; // class pass_reorder_blocks
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_reorder_blocks (gcc::context *ctxt)
+{
+ return new pass_reorder_blocks (ctxt);
+}
+
/* Duplicate the blocks containing computed gotos. This basically unfactors
computed gotos that were factored early on in the compilation process to
speed up edge based data flow. We used to not unfactoring them again,
@@ -2327,26 +2475,44 @@ done:
return 0;
}
-struct rtl_opt_pass pass_duplicate_computed_gotos =
+namespace {
+
+const pass_data pass_data_duplicate_computed_gotos =
{
- {
- RTL_PASS,
- "compgotos", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_duplicate_computed_gotos, /* gate */
- duplicate_computed_gotos, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_REORDER_BLOCKS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing,/* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "compgotos", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_REORDER_BLOCKS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_duplicate_computed_gotos : public rtl_opt_pass
+{
+public:
+ pass_duplicate_computed_gotos(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_duplicate_computed_gotos, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_duplicate_computed_gotos (); }
+ unsigned int execute () { return duplicate_computed_gotos (); }
+
+}; // class pass_duplicate_computed_gotos
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_duplicate_computed_gotos (gcc::context *ctxt)
+{
+ return new pass_duplicate_computed_gotos (ctxt);
+}
+
static bool
gate_handle_partition_blocks (void)
{
@@ -2533,22 +2699,40 @@ partition_hot_cold_basic_blocks (void)
return TODO_verify_flow | TODO_verify_rtl_sharing;
}
-struct rtl_opt_pass pass_partition_blocks =
+namespace {
+
+const pass_data pass_data_partition_blocks =
{
- {
- RTL_PASS,
- "bbpart", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_partition_blocks, /* gate */
- partition_hot_cold_basic_blocks, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_REORDER_BLOCKS, /* tv_id */
- PROP_cfglayout, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "bbpart", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_REORDER_BLOCKS, /* tv_id */
+ PROP_cfglayout, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_partition_blocks : public rtl_opt_pass
+{
+public:
+ pass_partition_blocks(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_partition_blocks, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_partition_blocks (); }
+ unsigned int execute () { return partition_hot_cold_basic_blocks (); }
+
+}; // class pass_partition_blocks
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_partition_blocks (gcc::context *ctxt)
+{
+ return new pass_partition_blocks (ctxt);
+}
diff --git a/gcc/bt-load.c b/gcc/bt-load.c
index 9ca1bd98dcd..b53435680ec 100644
--- a/gcc/bt-load.c
+++ b/gcc/bt-load.c
@@ -1504,26 +1504,46 @@ rest_of_handle_branch_target_load_optimize1 (void)
return 0;
}
-struct rtl_opt_pass pass_branch_target_load_optimize1 =
+namespace {
+
+const pass_data pass_data_branch_target_load_optimize1 =
{
- {
- RTL_PASS,
- "btl1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_branch_target_load_optimize1, /* gate */
- rest_of_handle_branch_target_load_optimize1, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "btl1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_branch_target_load_optimize1 : public rtl_opt_pass
+{
+public:
+ pass_branch_target_load_optimize1(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_branch_target_load_optimize1, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_branch_target_load_optimize1 (); }
+ unsigned int execute () {
+ return rest_of_handle_branch_target_load_optimize1 ();
+ }
+
+}; // class pass_branch_target_load_optimize1
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_branch_target_load_optimize1 (gcc::context *ctxt)
+{
+ return new pass_branch_target_load_optimize1 (ctxt);
+}
+
static bool
gate_handle_branch_target_load_optimize2 (void)
{
@@ -1553,22 +1573,42 @@ rest_of_handle_branch_target_load_optimize2 (void)
return 0;
}
-struct rtl_opt_pass pass_branch_target_load_optimize2 =
+namespace {
+
+const pass_data pass_data_branch_target_load_optimize2 =
{
- {
- RTL_PASS,
- "btl2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_branch_target_load_optimize2, /* gate */
- rest_of_handle_branch_target_load_optimize2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "btl2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_branch_target_load_optimize2 : public rtl_opt_pass
+{
+public:
+ pass_branch_target_load_optimize2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_branch_target_load_optimize2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_branch_target_load_optimize2 (); }
+ unsigned int execute () {
+ return rest_of_handle_branch_target_load_optimize2 ();
+ }
+
+}; // class pass_branch_target_load_optimize2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_branch_target_load_optimize2 (gcc::context *ctxt)
+{
+ return new pass_branch_target_load_optimize2 (ctxt);
+}
diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index dcaeee9e68d..7939727015a 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -83,6 +83,7 @@ DEF_LIST_INT_INT (5,6)
#undef DEF_LIST_INT_INT
/* Construct trees for identifiers. */
+DEF_ATTR_IDENT (ATTR_COLD, "cold")
DEF_ATTR_IDENT (ATTR_CONST, "const")
DEF_ATTR_IDENT (ATTR_FORMAT, "format")
DEF_ATTR_IDENT (ATTR_FORMAT_ARG, "format_arg")
@@ -130,6 +131,10 @@ DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LEAF_LIST, ATTR_NORETURN,\
ATTR_NULL, ATTR_NOTHROW_LEAF_LIST)
+DEF_ATTR_TREE_LIST (ATTR_COLD_NOTHROW_LEAF_LIST, ATTR_COLD,\
+ ATTR_NULL, ATTR_NOTHROW_LEAF_LIST)
+DEF_ATTR_TREE_LIST (ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST, ATTR_COLD,\
+ ATTR_NULL, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_ATTR_TREE_LIST (ATTR_CONST_NORETURN_NOTHROW_LEAF_LIST, ATTR_CONST,\
ATTR_NULL, ATTR_NORETURN_NOTHROW_LEAF_LIST)
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \
diff --git a/gcc/builtins.c b/gcc/builtins.c
index 78b0d842cc0..bb44a7f9b01 100644
--- a/gcc/builtins.c
+++ b/gcc/builtins.c
@@ -48,6 +48,7 @@ along with GCC; see the file COPYING3. If not see
#include "value-prof.h"
#include "diagnostic-core.h"
#include "builtins.h"
+#include "ubsan.h"
#ifndef PAD_VARARGS_DOWN
@@ -61,7 +62,7 @@ struct target_builtins *this_target_builtins = &default_target_builtins;
#endif
/* Define the names of the builtin function types and codes. */
-const char *const built_in_class_names[4]
+const char *const built_in_class_names[BUILT_IN_LAST]
= {"NOT_BUILT_IN", "BUILT_IN_FRONTEND", "BUILT_IN_MD", "BUILT_IN_NORMAL"};
#define DEF_BUILTIN(X, N, C, T, LT, B, F, NA, AT, IM, COND) #X,
@@ -249,6 +250,30 @@ is_builtin_fn (tree decl)
return TREE_CODE (decl) == FUNCTION_DECL && DECL_BUILT_IN (decl);
}
+/* By default we assume that c99 functions are present at the runtime,
+ but sincos is not. */
+bool
+default_libc_has_function (enum function_class fn_class)
+{
+ if (fn_class == function_c94
+ || fn_class == function_c99_misc
+ || fn_class == function_c99_math_complex)
+ return true;
+
+ return false;
+}
+
+bool
+gnu_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
+{
+ return true;
+}
+
+bool
+no_c99_libc_has_function (enum function_class fn_class ATTRIBUTE_UNUSED)
+{
+ return false;
+}
/* Return true if NODE should be considered for inline expansion regardless
of the optimization level. This means whenever a function is invoked with
@@ -2548,7 +2573,7 @@ expand_builtin_cexpi (tree exp, rtx target)
/* Compute into op1 and op2. */
expand_twoval_unop (sincos_optab, op0, op2, op1, 0);
}
- else if (TARGET_HAS_SINCOS)
+ else if (targetm.libc_has_function (function_sincos))
{
tree call, fn = NULL_TREE;
tree top1, top2;
@@ -5826,6 +5851,13 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
set of builtins. */
if (!optimize
&& !called_as_built_in (fndecl)
+ && fcode != BUILT_IN_FORK
+ && fcode != BUILT_IN_EXECL
+ && fcode != BUILT_IN_EXECV
+ && fcode != BUILT_IN_EXECLP
+ && fcode != BUILT_IN_EXECLE
+ && fcode != BUILT_IN_EXECVP
+ && fcode != BUILT_IN_EXECVE
&& fcode != BUILT_IN_ALLOCA
&& fcode != BUILT_IN_ALLOCA_WITH_ALIGN
&& fcode != BUILT_IN_FREE)
@@ -5865,6 +5897,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, enum machine_mode mode,
switch (fcode)
{
CASE_FLT_FN (BUILT_IN_FABS):
+ case BUILT_IN_FABSD32:
+ case BUILT_IN_FABSD64:
+ case BUILT_IN_FABSD128:
target = expand_builtin_fabs (exp, target, subtarget);
if (target)
return target;
@@ -7810,7 +7845,7 @@ fold_builtin_sincos (location_t loc,
return res;
/* Canonicalize sincos to cexpi. */
- if (!TARGET_C99_FUNCTIONS)
+ if (!targetm.libc_has_function (function_c99_math_complex))
return NULL_TREE;
fn = mathfn_built_in (type, BUILT_IN_CEXPI);
if (!fn)
@@ -7850,7 +7885,7 @@ fold_builtin_cexp (location_t loc, tree arg0, tree type)
/* In case we can figure out the real part of arg0 and it is constant zero
fold to cexpi. */
- if (!TARGET_C99_FUNCTIONS)
+ if (!targetm.libc_has_function (function_c99_math_complex))
return NULL_TREE;
ifn = mathfn_built_in (rtype, BUILT_IN_CEXPI);
if (!ifn)
@@ -8106,14 +8141,13 @@ fold_builtin_bitop (tree fndecl, tree arg)
{
hi = TREE_INT_CST_HIGH (arg);
if (width < HOST_BITS_PER_DOUBLE_INT)
- hi &= ~((unsigned HOST_WIDE_INT) (-1)
- << (width - HOST_BITS_PER_WIDE_INT));
+ hi &= ~(HOST_WIDE_INT_M1U << (width - HOST_BITS_PER_WIDE_INT));
}
else
{
hi = 0;
if (width < HOST_BITS_PER_WIDE_INT)
- lo &= ~((unsigned HOST_WIDE_INT) (-1) << width);
+ lo &= ~(HOST_WIDE_INT_M1U << width);
}
switch (DECL_FUNCTION_CODE (fndecl))
@@ -8152,13 +8186,13 @@ fold_builtin_bitop (tree fndecl, tree arg)
&& (hi & ((unsigned HOST_WIDE_INT) 1
<< (width - HOST_BITS_PER_WIDE_INT - 1))) != 0)
{
- hi = ~hi & ~((unsigned HOST_WIDE_INT) (-1)
+ hi = ~hi & ~(HOST_WIDE_INT_M1U
<< (width - HOST_BITS_PER_WIDE_INT - 1));
lo = ~lo;
}
else if (width <= HOST_BITS_PER_WIDE_INT
&& (lo & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
- lo = ~lo & ~((unsigned HOST_WIDE_INT) (-1) << (width - 1));
+ lo = ~lo & ~(HOST_WIDE_INT_M1U << (width - 1));
if (hi != 0)
result = width - floor_log2 (hi) - 2 - HOST_BITS_PER_WIDE_INT;
else if (lo != 0)
@@ -10277,6 +10311,11 @@ fold_builtin_0 (location_t loc, tree fndecl, bool ignore ATTRIBUTE_UNUSED)
case BUILT_IN_CLASSIFY_TYPE:
return fold_builtin_classify_type (NULL_TREE);
+ case BUILT_IN_UNREACHABLE:
+ if (flag_sanitize & SANITIZE_UNREACHABLE)
+ return ubsan_instrument_unreachable (loc);
+ break;
+
default:
break;
}
@@ -10314,6 +10353,9 @@ fold_builtin_1 (location_t loc, tree fndecl, tree arg0, bool ignore)
return fold_builtin_strlen (loc, type, arg0);
CASE_FLT_FN (BUILT_IN_FABS):
+ case BUILT_IN_FABSD32:
+ case BUILT_IN_FABSD64:
+ case BUILT_IN_FABSD128:
return fold_builtin_fabs (loc, arg0, type);
case BUILT_IN_ABS:
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 9b55b1f7a96..8ccf3ae3578 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -102,14 +102,20 @@ along with GCC; see the file COPYING3. If not see
#undef DEF_C94_BUILTIN
#define DEF_C94_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, !flag_isoc94, ATTRS, TARGET_C99_FUNCTIONS, true)
+ true, true, !flag_isoc94, ATTRS, targetm.libc_has_function (function_c94), true)
/* Like DEF_LIB_BUILTIN, except that the function is only a part of
the standard in C99 or above. */
#undef DEF_C99_BUILTIN
#define DEF_C99_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+ true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true)
+
+/* Like DEF_C99_BUILTIN, but for complex math functions. */
+#undef DEF_C99_COMPL_BUILTIN
+#define DEF_C99_COMPL_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
+ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
+ true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_math_complex), true)
/* Builtin that is specified by C99 and C90 reserve the name for future use.
We can still recognize the builtin in C90 mode but we can't produce it
@@ -117,7 +123,7 @@ along with GCC; see the file COPYING3. If not see
#undef DEF_C99_C90RES_BUILTIN
#define DEF_C99_C90RES_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
- true, true, !flag_isoc99, ATTRS, TARGET_C99_FUNCTIONS, true)
+ true, true, !flag_isoc99, ATTRS, targetm.libc_has_function (function_c99_misc), true)
/* Builtin that C99 reserve the name for future use. We can still recognize
the builtin in C99 mode but we can't produce it implicitly. */
@@ -155,7 +161,8 @@ along with GCC; see the file COPYING3. If not see
#define DEF_SANITIZER_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \
true, true, true, ATTRS, true, \
- (flag_asan || flag_tsan))
+ (flag_sanitize & (SANITIZE_ADDRESS | SANITIZE_THREAD \
+ | SANITIZE_UNDEFINED)))
#undef DEF_CILKPLUS_BUILTIN
#define DEF_CILKPLUS_BUILTIN(ENUM, NAME, TYPE, ATTRS) \
@@ -257,6 +264,9 @@ DEF_C99_BUILTIN (BUILT_IN_EXPM1L, "expm1l", BT_FN_LONGDOUBLE_LONGDOUBLE,
DEF_LIB_BUILTIN (BUILT_IN_FABS, "fabs", BT_FN_DOUBLE_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSF, "fabsf", BT_FN_FLOAT_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_C90RES_BUILTIN (BUILT_IN_FABSL, "fabsl", BT_FN_LONGDOUBLE_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_FABSD32, "fabsd32", BT_FN_DFLOAT32_DFLOAT32, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_FABSD64, "fabsd64", BT_FN_DFLOAT64_DFLOAT64, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_GCC_BUILTIN (BUILT_IN_FABSD128, "fabsd128", BT_FN_DFLOAT128_DFLOAT128, ATTR_CONST_NOTHROW_LEAF_LIST)
DEF_C99_BUILTIN (BUILT_IN_FDIM, "fdim", BT_FN_DOUBLE_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_C99_BUILTIN (BUILT_IN_FDIMF, "fdimf", BT_FN_FLOAT_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING_ERRNO)
DEF_C99_BUILTIN (BUILT_IN_FDIML, "fdiml", BT_FN_LONGDOUBLE_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
@@ -463,78 +473,78 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_YNF, "ynf", BT_FN_FLOAT_INT_FLOAT, ATTR_MATHFN_
DEF_EXT_LIB_BUILTIN (BUILT_IN_YNL, "ynl", BT_FN_LONGDOUBLE_INT_LONGDOUBLE, ATTR_MATHFN_FPROUNDING_ERRNO)
/* Category: _Complex math builtins. */
-DEF_C99_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CABS, "cabs", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CABSF, "cabsf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CABSL, "cabsl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CACOS, "cacos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CACOSF, "cacosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CACOSH, "cacosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CACOSHF, "cacoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CACOSHL, "cacoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CACOSL, "cacosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CARG, "carg", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CARGF, "cargf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CARGL, "cargl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CASIN, "casin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CASINF, "casinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CASINH, "casinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CASINHF, "casinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CASINHL, "casinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CASINL, "casinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CATAN, "catan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CATANF, "catanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CATANH, "catanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CATANHF, "catanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CATANHL, "catanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CATANL, "catanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CCOS, "ccos", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CCOSF, "ccosf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CCOSH, "ccosh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CCOSHF, "ccoshf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CCOSHL, "ccoshl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CCOSL, "ccosl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CEXP, "cexp", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CEXPF, "cexpf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CEXPL, "cexpl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
DEF_GCC_BUILTIN (BUILT_IN_CEXPI, "cexpi", BT_FN_COMPLEX_DOUBLE_DOUBLE, ATTR_MATHFN_FPROUNDING)
DEF_GCC_BUILTIN (BUILT_IN_CEXPIF, "cexpif", BT_FN_COMPLEX_FLOAT_FLOAT, ATTR_MATHFN_FPROUNDING)
DEF_GCC_BUILTIN (BUILT_IN_CEXPIL, "cexpil", BT_FN_COMPLEX_LONGDOUBLE_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CIMAG, "cimag", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CIMAGF, "cimagf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CIMAGL, "cimagl", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CLOG, "clog", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CLOGF, "clogf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CLOGL, "clogl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10, "clog10", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10F, "clog10f", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
DEF_EXT_C99RES_BUILTIN (BUILT_IN_CLOG10L, "clog10l", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
-DEF_C99_BUILTIN (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
-DEF_C99_BUILTIN (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CONJ, "conj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CONJF, "conjf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CONJL, "conjl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CPOW, "cpow", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CPOWF, "cpowf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CPOWL, "cpowl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CPROJ, "cproj", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CPROJF, "cprojf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CPROJL, "cprojl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CREAL, "creal", BT_FN_DOUBLE_COMPLEX_DOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CREALF, "crealf", BT_FN_FLOAT_COMPLEX_FLOAT, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CREALL, "creall", BT_FN_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_CONST_NOTHROW_LEAF_LIST)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSIN, "csin", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSINF, "csinf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSINH, "csinh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSINHF, "csinhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSINHL, "csinhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSINL, "csinl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSQRT, "csqrt", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSQRTF, "csqrtf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CSQRTL, "csqrtl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CTAN, "ctan", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CTANF, "ctanf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CTANH, "ctanh", BT_FN_COMPLEX_DOUBLE_COMPLEX_DOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CTANHF, "ctanhf", BT_FN_COMPLEX_FLOAT_COMPLEX_FLOAT, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CTANHL, "ctanhl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
+DEF_C99_COMPL_BUILTIN (BUILT_IN_CTANL, "ctanl", BT_FN_COMPLEX_LONGDOUBLE_COMPLEX_LONGDOUBLE, ATTR_MATHFN_FPROUNDING)
/* Category: string/memory builtins. */
/* bcmp, bcopy and bzero have traditionally accepted NULL pointers
@@ -685,7 +695,7 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_FFSLL, "ffsll", BT_FN_INT_LONGLONG, ATTR_CONST_
DEF_EXT_LIB_BUILTIN (BUILT_IN_FORK, "fork", BT_FN_PID, ATTR_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_FRAME_ADDRESS, "frame_address", BT_FN_PTR_UINT, ATTR_NULL)
/* [trans-mem]: Adjust BUILT_IN_TM_FREE if BUILT_IN_FREE is changed. */
-DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LIST)
+DEF_LIB_BUILTIN (BUILT_IN_FREE, "free", BT_FN_VOID_PTR, ATTR_NOTHROW_LEAF_LIST)
DEF_GCC_BUILTIN (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", BT_FN_PTR_PTR, ATTR_NULL)
DEF_EXT_LIB_BUILTIN (BUILT_IN_GETTEXT, "gettext", BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
DEF_C99_BUILTIN (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, ATTR_CONST_NOTHROW_LEAF_LIST)
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 487f880e432..95babfa743f 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,266 @@
+2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * c-common.c (same_scalar_type_ignoring_signedness): Delete.
+ (vector_types_compatible_elements_p): New function.
+ * c-common.h: (same_scalar_type_ignoring_signedness): Delete
+ declaration.
+ (vector_types_compatible_elements_p): Declare.
+
+2013-09-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::simple_type_specifier): Now
+ a virtual member function.
+ (pp_simple_type_specifier): Remove.
+ (pp_c_type_specifier): Likewise.
+ * c-pretty-print.c (c_pretty_printer::simple_type_specifier):
+ Rename from pp_c_type_specifier. Adjust.
+ (c_pretty_printer::c_pretty_printer): Do not assign to
+ simple_type_specifier.
+
+2013-09-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::type_id): Now a virtual
+ member function.
+ (c_pretty_printer::storage_class_specifier): Likewise.
+ (c_pretty_printer::initializer): Likewise.
+ (pp_declaration): Remove.
+ (pp_declaration_specifiers): Likewise.
+ (pp_abstract_declarator): Likewise.
+ (pp_declarator): Likewise.
+ (pp_type_id): Likewise.
+ (pp_statement): Likewise.
+ (pp_constant): Likewise.
+ (pp_id_expression): Likewise.
+ (pp_primary_expression): Likewise.
+ (pp_unary_expression): Likewise.
+ (pp_multiplicative_expression): Likewise.
+ (pp_conditional_expression): Likewise.
+ (pp_assignment_expression): Likewise.
+ (pp_expression): Likewise.
+ (pp_c_type_id): Likewise.
+ (pp_c_storage_class_specifier): Likewise.
+ * c-pretty-print.c (pp_c_type_cast): Tidy.
+ (pp_c_pointer): Likewise.
+ (pp_c_type_specifier): Likewise.
+ (pp_c_parameter_type_list): Likewise.
+ (pp_c_function_definition): Likewise.
+ (pp_c_init_declarator): Likewise.
+ (pp_c_initializer_list): Likewise.
+ (pp_c_constructor_elts): Likewise.
+ (c_pretty_printer::direct_abstract_declarator): Likewise.
+ (c_pretty_printer::declaration_specifiers): Likewise.
+ (c_pretty_printer::primary_expression): Likewise.
+ (c_pretty_printer::postfix_expression): Likewise.
+ (c_pretty_printer::type_id): Rename from pp_c_type_id.
+ (c_pretty_printer::storage_class_specifier): Rename from
+ pp_c_storage_class_specifier.
+ (c_pretty_printer::initializer): Rename from pp_c_initializer.
+ (c_pretty_printer::c_pretty_printer): Do not assign to type_id,
+ storage_class_specifier, initializer, offset_list, flags.
+
+2013-08-30 Marek Polacek <polacek@redhat.com>
+
+ * c-ubsan.c: New file.
+ * c-ubsan.h: New file.
+
+2013-08-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::declaration): Now a virtual
+ member function.
+ (c_pretty_printer::declaration_specifiers): Likewise.
+ (c_pretty_printer::declarator): Likewise.
+ (c_pretty_printer::abstract_declarator): Likewise.
+ (c_pretty_printer::direct_abstract_declarator): Likewise.
+ (c_pretty_printer::direct_declarator): Likewise.
+ (c_pretty_printer::function_specifier): Likewise.
+ (pp_declaration): Adjust.
+ (pp_declaration_specifiers): Likewise.
+ (pp_abstract_declarator): Likewise.
+ (pp_direct_declarator): Likewise.
+ (pp_function_specifier): Likewise.
+ (pp_direct_abstract_declarator): Remove as unused.
+ (pp_c_declaration): Remove.
+ (pp_c_declaration_specifiers): Likewise.
+ (pp_c_declarator): Likewise.
+ (pp_c_direct_declarator): Likewise.
+ (pp_c_function_specifier): Likewise.
+ (pp_c_direct_abstract_declarator): Likewise.
+ * c-pretty-print.c (c_pretty_printer::abstract_declarator): Rename
+ from pp_c_abstract_declarator. Adjust.
+ (c_pretty_printer::direct_abstract_declarator): Rename from
+ pp_c_direct_abstract_declarator. Adjust.
+ (c_pretty_printer::function_specifier): Rename from
+ pp_c_function_specifier. Adjust.
+ (c_pretty_printer::declaration_specifiers): Rename from
+ pp_c_declaration_specifiers. Adjust.
+ (c_pretty_printer::direct_declarator): Rename from
+ pp_c_direct_declarator. Adjust.
+ (c_pretty_printer::declarator): Rename from pp_c_declarator. Adjust.
+ (c_pretty_printer::declaration): Rename from pp_c_declaration. Adjust.
+ (c_pretty_printer::c_pretty_printer): Do not assign to
+ declaration, declaration_specifiers, declarator,
+ direct_declarator, direct_abstract_declarator, function_specifier.
+
+2013-08-26 Gabriel Dos Reis <gdre@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::unary_expression): Now a
+ virtual member function.
+ (c_pretty_printer::multiplicative_expression): Likewise.
+ (c_pretty_printer::conditional_expression): Likewise.
+ (c_pretty_printer::assignment_expression): Likewise.
+ (c_pretty_printer::expression): Likewise.
+ (pp_unary_expression): Adjust.
+ (pp_multiplicative_expression): Likewise.
+ (pp_assignment_expression): Likewise.
+ (pp_conditional_expression): Likewise.
+ (pp_expression): Likewise.
+ * c-pretty-print.c (c_pretty_printer::unary_expression): Rename
+ from pp_c_unary_expression. Adjust.
+ (c_pretty_printer::multiplicative_expression): Rename from
+ pp_c_multiplicative_expression. Adjust.
+ (c_pretty_printer::conditional_expression): Rename from
+ pp_c_conditional_expression. Adjust.
+ (c_pretty_printer::assignment_expression): Rename from
+ pp_c_assignment_expression. Adjust.
+ (c_pretty_printer::expression): Rename from pp_c_expression. Adjust.
+ (c_pretty_printer::c_pretty_printer): Do not assign to
+ unary_expression, multiplicative_expression,
+ conditional_expression, expression.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::postfix_expression): Now a
+ virtual member function.
+ (pp_postfix_expression): Adjust.
+ (pp_c_postfix_expression): Remove.
+ * c-pretty-print.c (c_pretty_printer::postfix_expression): Rename
+ from pp_c_postfix_expression. Adjust.
+ (c_pretty_printer::c_pretty_printer): Do not assign to
+ postfix_expression.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::primary_expression): Now a
+ virtua member function.
+ (pp_primary_expression): Adjust.
+ (pp_c_primary_expression): Remove.
+ * c-pretty-print.c (c_pretty_printer::primary_expression): Rename
+ from pp_c_primary_expression. Adjust.
+ (pp_c_initializer_list): Use pp_primary_expression.
+ (c_pretty_printer::c_pretty_printer): Do not assign to
+ primary_expression.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::translate_string): Declare.
+ * c-pretty-print.c (M_): Remove.
+ (c_pretty_printer::translate_string): Define.
+ (pp_c_type_specifier): Use it.
+ (pp_c_primary_expression): Likewise.
+ (pp_c_expression): Likewise.
+
+2013-08-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::id_expression): Now a
+ virtual function.
+ (pp_c_id_expression): Remove.
+ (pp_id_expression): Adjust.
+ * c-pretty-print.c (c_pretty_printer::id_expression): Rename from
+ pp_c_id_expression. Adjust.
+ (pp_c_postfix_expression): Use pp_id_expression.
+ (c_pretty_printer::c_pretty_printer): Do not assign to id_expression.
+
+2013-08-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer::constant): Now a virtual
+ member function.
+ (pp_constant): Adjust.
+ (pp_c_constant): Remove.
+ * c-pretty-print.c (c_pretty_printer::constant): Rename from
+ pp_c_constant. Adjust.
+ (pp_c_constant)
+ (pp_c_primary_expression): Call pp_constant in lieu of pp_c_constant.
+ (c_pretty_printer::c_pretty_printer): Remove assignment to constant.
+
+2013-08-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (pp_c_pretty_printer_init): Remove.
+ (c_pretty_printer::c_pretty_printer): Declare.
+ * c-pretty-print.c (pretty_printer::c_pretty_printer): Rename from
+ c_pretty_printer_init. Adjust.
+ (print_c_tree): Do not call c_pretty_printer_init.
+ * c-ada-spec.c (dump_ads): Remove call to pp_construct.
+
+2013-08-09 Arnaud Charlet <charlet@adacore.com>
+
+ * c-ada-spec.c (print_ada_declaration): Prevent accessing null asm name
+
+2013-08-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58080
+ * c-common.c (pointer_int_sum): Add bool parameter.
+ * c-common.h (pointer_int_sum): Adjust declaration.
+
+2013-08-05 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.c (print_c_tree): Simplify. Use non-static local
+ c_pretty_printer variable.
+
+2013-08-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-pretty-print.h (c_pretty_printer): Derive from pretty_printer.
+ (pp_base): Remove.
+ (pp_c_base): Likewise. Adjust users.
+ * c-pretty-print.c (pp_c_maybe_whitespace): Adjust.
+ (pp_c_whitespace): Do not call pp_base.
+ (pp_c_left_paren): Likewise.
+ (pp_c_right_paren): Likewise.
+ (pp_c_left_brace): Likewise.
+ (pp_c_right_brace): Likewise.
+ (pp_c_left_bracket): Likewise.
+ (pp_c_right_bracket): Likewise.
+ (pp_c_dot): Likewise.
+ (pp_c_ampersand): Likewise.
+ (pp_c_star): Likewise.
+ (pp_c_arrow): Likewise.
+ (pp_c_semicolon): Likewise.
+ (pp_c_complement): Likewise.
+ (pp_c_exclamation): Likewise.
+ (pp_c_direct_declarator): Likewise.
+ (pp_c_ws_string): Likewise.
+ (pp_c_identifier): Likewise.
+ (pp_c_statement): Likewise.
+ (print_c_tree): Likewise.
+
+2013-08-04 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/58072
+ * c-common.c (c_parse_error): Catch user-defined literal tokens and
+ provide useful error strings.
+
+2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-ada-spec.c (pp_ada_tree_identifier): Use specialized pretty
+ printer functions instead of pp_string or operators and punctuators.
+ (dump_generic_ada_node): Likewise.
+ * c-pretty-print.c (pp_c_type_specifier): Likewise.
+ (pp_c_relational_expression): Likewise.
+ (pp_c_logical_or_expression): Likewise.
+
+2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-ada-spec.c (print_ada_macros): Use specialized pretty printer
+ functions instead of pp_character.
+ (pp_ada_tree_identifier): Likewise.
+ (dump_ada_double_name): Likewise.
+ (dump_ada_function_declaration): Likewise.
+ (dump_ada_array_domains): Likewise.
+ (dump_template_types): Likewise.
+ (dump_generic_ada_node): Likewise.
+ (print_ada_declaration): Likewise.
+ (print_ada_struct_decl): Likewise.
+ * c-pretty-print.c (pp_c_integer_constant): Likewise.
+
2013-07-23 Tom Tromey <tromey@redhat.com>
* c-common.h (enum rid) <RID_GENERIC>: New constant.
diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c
index 21cbfe94fba..eac57838752 100644
--- a/gcc/c-family/c-ada-spec.c
+++ b/gcc/c-family/c-ada-spec.c
@@ -418,7 +418,7 @@ print_ada_macros (pretty_printer *pp, cpp_hashnode **macros, int max_ada_macros)
pp_string (pp, "; -- ");
pp_string (pp, sloc.file);
- pp_character (pp, ':');
+ pp_colon (pp);
pp_scalar (pp, "%d", sloc.line);
pp_newline (pp);
}
@@ -1253,7 +1253,7 @@ pp_ada_tree_identifier (pretty_printer *buffer, tree node, tree type,
{
append_withs (s1, limited_access);
pp_string (buffer, s1);
- pp_character (buffer, '.');
+ pp_dot (buffer);
}
free (s1);
}
@@ -1266,7 +1266,7 @@ pp_ada_tree_identifier (pretty_printer *buffer, tree node, tree type,
{
pp_string (buffer, "Class_");
pp_string (buffer, s);
- pp_string (buffer, ".");
+ pp_dot (buffer);
}
}
@@ -1375,7 +1375,7 @@ dump_ada_double_name (pretty_printer *buffer, tree t1, tree t2, const char *s)
pp_scalar (buffer, "%d", TYPE_UID (TREE_TYPE (t1)));
}
- pp_character (buffer, '_');
+ pp_underscore (buffer);
if (DECL_NAME (t1))
pp_ada_tree_identifier (buffer, DECL_NAME (t2), t2, false);
@@ -1489,7 +1489,7 @@ dump_ada_function_declaration (pretty_printer *buffer, tree func,
if (num_args > 0)
{
pp_space (buffer);
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
}
if (TREE_CODE (func) == FUNCTION_DECL)
@@ -1550,7 +1550,7 @@ dump_ada_function_declaration (pretty_printer *buffer, tree func,
if (num < num_args)
{
- pp_character (buffer, ';');
+ pp_semicolon (buffer);
if (num_args > 2)
newline_and_indent (buffer, spc + INDENT_INCR);
@@ -1566,7 +1566,7 @@ dump_ada_function_declaration (pretty_printer *buffer, tree func,
}
if (num_args > 0)
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
return num_args;
}
@@ -1577,7 +1577,7 @@ static void
dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
{
int first = 1;
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
for (; TREE_CODE (node) == ARRAY_TYPE; node = TREE_TYPE (node))
{
@@ -1606,7 +1606,7 @@ dump_ada_array_domains (pretty_printer *buffer, tree node, int spc)
else
pp_string (buffer, "size_t");
}
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
/* Dump in BUFFER file:line information related to NODE. */
@@ -1626,7 +1626,7 @@ dump_sloc (pretty_printer *buffer, tree node)
if (xloc.file)
{
pp_string (buffer, xloc.file);
- pp_string (buffer, ":");
+ pp_colon (buffer);
pp_decimal_int (buffer, xloc.line);
}
}
@@ -1706,7 +1706,7 @@ dump_template_types (pretty_printer *buffer, tree types,
for (i = 0; i < len; i++)
{
tree elem = TREE_VEC_ELT (types, i);
- pp_character (buffer, '_');
+ pp_underscore (buffer);
if (!dump_generic_ada_node (buffer, elem, 0, cpp_check, spc, false, true))
{
pp_string (buffer, "unknown");
@@ -1886,14 +1886,14 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type,
bool first = true;
spc += INDENT_INCR;
newline_and_indent (buffer, spc - 1);
- pp_string (buffer, "(");
+ pp_left_paren (buffer);
for (; value; value = TREE_CHAIN (value))
{
if (first)
first = false;
else
{
- pp_string (buffer, ",");
+ pp_comma (buffer);
newline_and_indent (buffer, spc);
}
@@ -1907,7 +1907,7 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type,
dump_generic_ada_node
(buffer, DECL_NAME (type) ? type : TYPE_NAME (node), type,
cpp_check, spc, 0, true);
- pp_string (buffer, ")");
+ pp_right_paren (buffer);
}
else
{
@@ -2032,7 +2032,7 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type,
pp_string (buffer, "pragma Convention (C, ");
dump_generic_ada_node
(buffer, type, 0, cpp_check, spc, false, true);
- pp_string (buffer, ")");
+ pp_right_paren (buffer);
}
}
else
@@ -2215,7 +2215,7 @@ dump_generic_ada_node (pretty_printer *buffer, tree node, tree type,
if (tree_int_cst_sgn (val) < 0)
{
- pp_character (buffer, '-');
+ pp_minus (buffer);
high = ~high + !low;
low = -low;
}
@@ -2900,7 +2900,7 @@ print_ada_declaration (pretty_printer *buffer, tree t, tree type,
pp_string (buffer, " -- ");
dump_sloc (buffer, t);
- if (is_abstract)
+ if (is_abstract || !DECL_ASSEMBLER_NAME (t))
return 1;
newline_and_indent (buffer, spc);
@@ -2986,7 +2986,7 @@ print_ada_declaration (pretty_printer *buffer, tree t, tree type,
dump_generic_ada_node
(buffer, TYPE_NAME (TREE_TYPE (t)), type, cpp_check,
spc, false, true);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
print_ada_methods (buffer, TREE_TYPE (t), cpp_check, spc);
}
@@ -3226,7 +3226,7 @@ print_ada_struct_decl (pretty_printer *buffer, tree node, tree type,
dump_generic_ada_node
(buffer, TREE_TYPE (type), type, cpp_check, spc, false, true);
package_prefix = true;
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
if (is_union)
{
@@ -3236,7 +3236,7 @@ print_ada_struct_decl (pretty_printer *buffer, tree node, tree type,
dump_generic_ada_node
(buffer, TREE_TYPE (type), type, cpp_check, spc, false, true);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
if (bitfield_used)
@@ -3246,7 +3246,7 @@ print_ada_struct_decl (pretty_printer *buffer, tree node, tree type,
pp_string (buffer, "pragma Pack (");
dump_generic_ada_node
(buffer, TREE_TYPE (type), type, cpp_check, spc, false, true);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
bitfield_used = false;
}
@@ -3304,7 +3304,6 @@ dump_ads (const char *source_file,
{
pretty_printer pp;
- pp_construct (&pp, NULL, 0);
pp_needs_newline (&pp) = true;
pp.buffer->stream = f;
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 7bba376f369..62aa9fcec2b 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2199,6 +2199,14 @@ check_main_parameter_types (tree decl)
"%q+D takes only zero or two arguments", decl);
}
+/* vector_targets_convertible_p is used for vector pointer types. The
+ callers perform various checks that the qualifiers are satisfactory,
+ while OTOH vector_targets_convertible_p ignores the number of elements
+ in the vectors. That's fine with vector pointers as we can consider,
+ say, a vector of 8 elements as two consecutive vectors of 4 elements,
+ and that does not require and conversion of the pointer values.
+ In contrast, vector_types_convertible_p and
+ vector_types_compatible_elements_p are used for vector value types. */
/* True if pointers to distinct types T1 and T2 can be converted to
each other without an explicit cast. Only returns true for opaque
vector types. */
@@ -2213,6 +2221,17 @@ vector_targets_convertible_p (const_tree t1, const_tree t2)
return false;
}
+/* vector_types_convertible_p is used for vector value types.
+ It could in principle call vector_targets_convertible_p as a subroutine,
+ but then the check for vector type would be duplicated with its callers,
+ and also the purpose of vector_targets_convertible_p would become
+ muddled.
+ Where vector_types_convertible_p returns true, a conversion might still be
+ needed to make the types match.
+ In contrast, vector_targets_convertible_p is used for vector pointer
+ values, and vector_types_compatible_elements_p is used specifically
+ in the context for binary operators, as a check if use is possible without
+ conversion. */
/* True if vector types T1 and T2 can be converted to each other
without an explicit cast. If EMIT_LAX_NOTE is true, and T1 and T2
can only be converted with -flax-vector-conversions yet that is not
@@ -4284,7 +4303,7 @@ shorten_compare (tree *op0_ptr, tree *op1_ptr, tree *restype_ptr,
tree
pointer_int_sum (location_t loc, enum tree_code resultcode,
- tree ptrop, tree intop)
+ tree ptrop, tree intop, bool complain)
{
tree size_exp, ret;
@@ -4293,14 +4312,20 @@ pointer_int_sum (location_t loc, enum tree_code resultcode,
if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE)
{
- pedwarn (loc, OPT_Wpointer_arith,
- "pointer of type %<void *%> used in arithmetic");
+ if (complain && warn_pointer_arith)
+ pedwarn (loc, OPT_Wpointer_arith,
+ "pointer of type %<void *%> used in arithmetic");
+ else if (!complain)
+ return error_mark_node;
size_exp = integer_one_node;
}
else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE)
{
- pedwarn (loc, OPT_Wpointer_arith,
- "pointer to a function used in arithmetic");
+ if (complain && warn_pointer_arith)
+ pedwarn (loc, OPT_Wpointer_arith,
+ "pointer to a function used in arithmetic");
+ else if (!complain)
+ return error_mark_node;
size_exp = integer_one_node;
}
else
@@ -9352,6 +9377,18 @@ c_parse_error (const char *gmsgid, enum cpp_ttype token_type,
free (message);
message = NULL;
}
+ else if (token_type == CPP_CHAR_USERDEF
+ || token_type == CPP_WCHAR_USERDEF
+ || token_type == CPP_CHAR16_USERDEF
+ || token_type == CPP_CHAR32_USERDEF)
+ message = catenate_messages (gmsgid,
+ " before user-defined character literal");
+ else if (token_type == CPP_STRING_USERDEF
+ || token_type == CPP_WSTRING_USERDEF
+ || token_type == CPP_STRING16_USERDEF
+ || token_type == CPP_STRING32_USERDEF
+ || token_type == CPP_UTF8STRING_USERDEF)
+ message = catenate_messages (gmsgid, " before user-defined string literal");
else if (token_type == CPP_STRING
|| token_type == CPP_WSTRING
|| token_type == CPP_STRING16
@@ -10672,20 +10709,45 @@ resolve_overloaded_builtin (location_t loc, tree function,
}
}
-/* Ignoring their sign, return true if two scalar types are the same. */
+/* vector_types_compatible_elements_p is used in type checks of vectors
+ values used as operands of binary operators. Where it returns true, and
+ the other checks of the caller succeed (being vector types in he first
+ place, and matching number of elements), we can just treat the types
+ as essentially the same.
+ Contrast with vector_targets_convertible_p, which is used for vector
+ pointer types, and vector_types_convertible_p, which will allow
+ language-specific matches under the control of flag_lax_vector_conversions,
+ and might still require a conversion. */
+/* True if vector types T1 and T2 can be inputs to the same binary
+ operator without conversion.
+ We don't check the overall vector size here because some of our callers
+ want to give different error messages when the vectors are compatible
+ except for the element count. */
+
bool
-same_scalar_type_ignoring_signedness (tree t1, tree t2)
+vector_types_compatible_elements_p (tree t1, tree t2)
{
+ bool opaque = TYPE_VECTOR_OPAQUE (t1) || TYPE_VECTOR_OPAQUE (t2);
+ t1 = TREE_TYPE (t1);
+ t2 = TREE_TYPE (t2);
+
enum tree_code c1 = TREE_CODE (t1), c2 = TREE_CODE (t2);
gcc_assert ((c1 == INTEGER_TYPE || c1 == REAL_TYPE || c1 == FIXED_POINT_TYPE)
&& (c2 == INTEGER_TYPE || c2 == REAL_TYPE
|| c2 == FIXED_POINT_TYPE));
+ t1 = c_common_signed_type (t1);
+ t2 = c_common_signed_type (t2);
/* Equality works here because c_common_signed_type uses
TYPE_MAIN_VARIANT. */
- return c_common_signed_type (t1)
- == c_common_signed_type (t2);
+ if (t1 == t2)
+ return true;
+ if (opaque && c1 == c2
+ && (c1 == INTEGER_TYPE || c1 == REAL_TYPE)
+ && TYPE_PRECISION (t1) == TYPE_PRECISION (t2))
+ return true;
+ return false;
}
/* Check for missing format attributes on function pointers. LTYPE is
diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h
index dc430c3859c..722ba6e5c15 100644
--- a/gcc/c-family/c-common.h
+++ b/gcc/c-family/c-common.h
@@ -766,7 +766,7 @@ extern void warn_logical_operator (location_t, enum tree_code, tree,
enum tree_code, tree, enum tree_code, tree);
extern void check_main_parameter_types (tree decl);
extern bool c_determine_visibility (tree);
-extern bool same_scalar_type_ignoring_signedness (tree, tree);
+extern bool vector_types_compatible_elements_p (tree, tree);
extern void mark_valid_location_for_stdc_pragma (bool);
extern bool valid_location_for_stdc_pragma_p (void);
extern void set_float_const_decimal64 (void);
@@ -790,7 +790,8 @@ extern tree shorten_binary_op (tree result_type, tree op0, tree op1, bool bitwis
and, if so, perhaps change them both back to their original type. */
extern tree shorten_compare (tree *, tree *, tree *, enum tree_code *);
-extern tree pointer_int_sum (location_t, enum tree_code, tree, tree);
+extern tree pointer_int_sum (location_t, enum tree_code, tree, tree,
+ bool = true);
/* Add qualifiers to a type, in the fashion for C. */
extern tree c_build_qualified_type (tree, int);
diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index b8af90c053c..d0283e8af4d 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -29,10 +29,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-iterator.h"
#include "diagnostic.h"
-/* Translate if being used for diagnostics, but not for dump files or
- __PRETTY_FUNCTION. */
-#define M_(msgid) (pp_translate_identifiers (pp) ? _(msgid) : (msgid))
-
/* The pretty-printer code is primarily designed to closely follow
(GNU) C and C++ grammars. That is to be contrasted with spaghetti
codes we used to have in the past. Following a structured
@@ -43,7 +39,7 @@ along with GCC; see the file COPYING3. If not see
#define pp_c_maybe_whitespace(PP) \
do { \
- if (pp_base (PP)->padding == pp_before) \
+ if ((PP)->padding == pp_before) \
pp_c_whitespace (PP); \
} while (0)
@@ -54,7 +50,6 @@ static void pp_c_char (c_pretty_printer *, int);
static void pp_c_initializer_list (c_pretty_printer *, tree);
static void pp_c_brace_enclosed_initializer_list (c_pretty_printer *, tree);
-static void pp_c_multiplicative_expression (c_pretty_printer *, tree);
static void pp_c_additive_expression (c_pretty_printer *, tree);
static void pp_c_shift_expression (c_pretty_printer *, tree);
static void pp_c_relational_expression (c_pretty_printer *, tree);
@@ -63,8 +58,6 @@ static void pp_c_and_expression (c_pretty_printer *, tree);
static void pp_c_exclusive_or_expression (c_pretty_printer *, tree);
static void pp_c_inclusive_or_expression (c_pretty_printer *, tree);
static void pp_c_logical_and_expression (c_pretty_printer *, tree);
-static void pp_c_conditional_expression (c_pretty_printer *, tree);
-static void pp_c_assignment_expression (c_pretty_printer *, tree);
/* declarations. */
@@ -75,98 +68,98 @@ void
pp_c_whitespace (c_pretty_printer *pp)
{
pp_space (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_left_paren (c_pretty_printer *pp)
{
pp_left_paren (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_right_paren (c_pretty_printer *pp)
{
pp_right_paren (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_left_brace (c_pretty_printer *pp)
{
pp_left_brace (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_right_brace (c_pretty_printer *pp)
{
pp_right_brace (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_left_bracket (c_pretty_printer *pp)
{
pp_left_bracket (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_right_bracket (c_pretty_printer *pp)
{
pp_right_bracket (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_dot (c_pretty_printer *pp)
{
pp_dot (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_ampersand (c_pretty_printer *pp)
{
pp_ampersand (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_star (c_pretty_printer *pp)
{
pp_star (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_arrow (c_pretty_printer *pp)
{
pp_arrow (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_semicolon (c_pretty_printer *pp)
{
pp_semicolon (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_complement (c_pretty_printer *pp)
{
pp_complement (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
pp_c_exclamation (c_pretty_printer *pp)
{
pp_exclamation (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
/* Print out the external representation of QUALIFIERS. */
@@ -215,7 +208,7 @@ static void
pp_c_type_cast (c_pretty_printer *pp, tree t)
{
pp_c_left_paren (pp);
- pp_type_id (pp, t);
+ pp->type_id (t);
pp_c_right_paren (pp);
}
@@ -303,7 +296,7 @@ pp_c_pointer (c_pretty_printer *pp, tree t)
/* ??? This node is now in GENERIC and so shouldn't be here. But
we'll fix that later. */
case DECL_EXPR:
- pp_declaration (pp, DECL_EXPR_DECL (t));
+ pp->declaration (DECL_EXPR_DECL (t));
pp_needs_newline (pp) = true;
break;
@@ -312,7 +305,10 @@ pp_c_pointer (c_pretty_printer *pp, tree t)
}
}
-/* type-specifier:
+/* simple-type-specifier:
+ type-specifier
+
+ type-specifier:
void
char
short
@@ -335,17 +331,17 @@ pp_c_pointer (c_pretty_printer *pp, tree t)
__vector__ */
void
-pp_c_type_specifier (c_pretty_printer *pp, tree t)
+c_pretty_printer::simple_type_specifier (tree t)
{
const enum tree_code code = TREE_CODE (t);
switch (code)
{
case ERROR_MARK:
- pp_c_ws_string (pp, M_("<type-error>"));
+ translate_string ("<type-error>");
break;
case IDENTIFIER_NODE:
- pp_c_identifier (pp, IDENTIFIER_POINTER (t));
+ pp_c_identifier (this, IDENTIFIER_POINTER (t));
break;
case VOID_TYPE:
@@ -356,7 +352,7 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
if (TYPE_NAME (t))
{
t = TYPE_NAME (t);
- pp_c_type_specifier (pp, t);
+ simple_type_specifier (t);
}
else
{
@@ -367,11 +363,11 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
t = c_common_type_for_mode (TYPE_MODE (t), TYPE_UNSIGNED (t));
if (TYPE_NAME (t))
{
- pp_c_type_specifier (pp, t);
+ simple_type_specifier (t);
if (TYPE_PRECISION (t) != prec)
{
- pp_string (pp, ":");
- pp_decimal_int (pp, prec);
+ pp_colon (this);
+ pp_decimal_int (this, prec);
}
}
else
@@ -379,52 +375,52 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
switch (code)
{
case INTEGER_TYPE:
- pp_string (pp, (TYPE_UNSIGNED (t)
- ? M_("<unnamed-unsigned:")
- : M_("<unnamed-signed:")));
+ translate_string (TYPE_UNSIGNED (t)
+ ? "<unnamed-unsigned:"
+ : "<unnamed-signed:");
break;
case REAL_TYPE:
- pp_string (pp, M_("<unnamed-float:"));
+ translate_string ("<unnamed-float:");
break;
case FIXED_POINT_TYPE:
- pp_string (pp, M_("<unnamed-fixed:"));
+ translate_string ("<unnamed-fixed:");
break;
default:
gcc_unreachable ();
}
- pp_decimal_int (pp, prec);
- pp_string (pp, ">");
+ pp_decimal_int (this, prec);
+ pp_greater (this);
}
}
break;
case TYPE_DECL:
if (DECL_NAME (t))
- pp_id_expression (pp, t);
+ id_expression (t);
else
- pp_c_ws_string (pp, M_("<typedef-error>"));
+ translate_string ("<typedef-error>");
break;
case UNION_TYPE:
case RECORD_TYPE:
case ENUMERAL_TYPE:
if (code == UNION_TYPE)
- pp_c_ws_string (pp, "union");
+ pp_c_ws_string (this, "union");
else if (code == RECORD_TYPE)
- pp_c_ws_string (pp, "struct");
+ pp_c_ws_string (this, "struct");
else if (code == ENUMERAL_TYPE)
- pp_c_ws_string (pp, "enum");
+ pp_c_ws_string (this, "enum");
else
- pp_c_ws_string (pp, M_("<tag-error>"));
+ translate_string ("<tag-error>");
if (TYPE_NAME (t))
- pp_id_expression (pp, TYPE_NAME (t));
+ id_expression (TYPE_NAME (t));
else
- pp_c_ws_string (pp, M_("<anonymous>"));
+ translate_string ("<anonymous>");
break;
default:
- pp_unsupported_tree (pp, t);
+ pp_unsupported_tree (this, t);
break;
}
}
@@ -438,7 +434,7 @@ pp_c_type_specifier (c_pretty_printer *pp, tree t)
function declarations, this routine prints not just the
specifier-qualifier-list of such entities or types of such entities,
but also the 'pointer' production part of their declarators. The
- remaining part is done by pp_declarator or pp_c_abstract_declarator. */
+ remaining part is done by declarator() or abstract_declarator(). */
void
pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
@@ -490,7 +486,7 @@ pp_c_specifier_qualifier_list (c_pretty_printer *pp, tree t)
break;
default:
- pp_simple_type_specifier (pp, t);
+ pp->simple_type_specifier (t);
break;
}
if ((pp->flags & pp_c_flag_gnu_v3) && code != POINTER_TYPE)
@@ -525,12 +521,12 @@ pp_c_parameter_type_list (c_pretty_printer *pp, tree t)
if (!first)
pp_separate_with (pp, ',');
first = false;
- pp_declaration_specifiers
- (pp, want_parm_decl ? parms : TREE_VALUE (parms));
+ pp->declaration_specifiers
+ (want_parm_decl ? parms : TREE_VALUE (parms));
if (want_parm_decl)
- pp_declarator (pp, parms);
+ pp->declarator (parms);
else
- pp_abstract_declarator (pp, TREE_VALUE (parms));
+ pp->abstract_declarator (TREE_VALUE (parms));
}
}
pp_c_right_paren (pp);
@@ -540,18 +536,18 @@ pp_c_parameter_type_list (c_pretty_printer *pp, tree t)
pointer
pointer(opt) direct-abstract-declarator */
-static void
-pp_c_abstract_declarator (c_pretty_printer *pp, tree t)
+void
+c_pretty_printer::abstract_declarator (tree t)
{
if (TREE_CODE (t) == POINTER_TYPE)
{
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
- pp_c_right_paren (pp);
+ pp_c_right_paren (this);
t = TREE_TYPE (t);
}
- pp_direct_abstract_declarator (pp, t);
+ direct_abstract_declarator (t);
}
/* direct-abstract-declarator:
@@ -561,34 +557,34 @@ pp_c_abstract_declarator (c_pretty_printer *pp, tree t)
direct-abstract-declarator(opt) ( parameter-type-list(opt) ) */
void
-pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t)
+c_pretty_printer::direct_abstract_declarator (tree t)
{
switch (TREE_CODE (t))
{
case POINTER_TYPE:
- pp_abstract_declarator (pp, t);
+ abstract_declarator (t);
break;
case FUNCTION_TYPE:
- pp_c_parameter_type_list (pp, t);
- pp_direct_abstract_declarator (pp, TREE_TYPE (t));
+ pp_c_parameter_type_list (this, t);
+ direct_abstract_declarator (TREE_TYPE (t));
break;
case ARRAY_TYPE:
- pp_c_left_bracket (pp);
+ pp_c_left_bracket (this);
if (TYPE_DOMAIN (t) && TYPE_MAX_VALUE (TYPE_DOMAIN (t)))
{
tree maxval = TYPE_MAX_VALUE (TYPE_DOMAIN (t));
tree type = TREE_TYPE (maxval);
if (host_integerp (maxval, 0))
- pp_wide_integer (pp, tree_low_cst (maxval, 0) + 1);
+ pp_wide_integer (this, tree_low_cst (maxval, 0) + 1);
else
- pp_expression (pp, fold_build2 (PLUS_EXPR, type, maxval,
- build_int_cst (type, 1)));
+ expression (fold_build2 (PLUS_EXPR, type, maxval,
+ build_int_cst (type, 1)));
}
- pp_c_right_bracket (pp);
- pp_direct_abstract_declarator (pp, TREE_TYPE (t));
+ pp_c_right_bracket (this);
+ direct_abstract_declarator (TREE_TYPE (t));
break;
case IDENTIFIER_NODE:
@@ -606,7 +602,7 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t)
break;
default:
- pp_unsupported_tree (pp, t);
+ pp_unsupported_tree (this, t);
break;
}
}
@@ -615,10 +611,10 @@ pp_c_direct_abstract_declarator (c_pretty_printer *pp, tree t)
specifier-qualifier-list abstract-declarator(opt) */
void
-pp_c_type_id (c_pretty_printer *pp, tree t)
+c_pretty_printer::type_id (tree t)
{
- pp_c_specifier_qualifier_list (pp, t);
- pp_abstract_declarator (pp, t);
+ pp_c_specifier_qualifier_list (this, t);
+ abstract_declarator (t);
}
/* storage-class-specifier:
@@ -629,16 +625,16 @@ pp_c_type_id (c_pretty_printer *pp, tree t)
register */
void
-pp_c_storage_class_specifier (c_pretty_printer *pp, tree t)
+c_pretty_printer::storage_class_specifier (tree t)
{
if (TREE_CODE (t) == TYPE_DECL)
- pp_c_ws_string (pp, "typedef");
+ pp_c_ws_string (this, "typedef");
else if (DECL_P (t))
{
if (DECL_REGISTER (t))
- pp_c_ws_string (pp, "register");
+ pp_c_ws_string (this, "register");
else if (TREE_STATIC (t) && TREE_CODE (t) == VAR_DECL)
- pp_c_ws_string (pp, "static");
+ pp_c_ws_string (this, "static");
}
}
@@ -646,10 +642,10 @@ pp_c_storage_class_specifier (c_pretty_printer *pp, tree t)
inline */
void
-pp_c_function_specifier (c_pretty_printer *pp, tree t)
+c_pretty_printer::function_specifier (tree t)
{
if (TREE_CODE (t) == FUNCTION_DECL && DECL_DECLARED_INLINE_P (t))
- pp_c_ws_string (pp, "inline");
+ pp_c_ws_string (this, "inline");
}
/* declaration-specifiers:
@@ -659,11 +655,11 @@ pp_c_function_specifier (c_pretty_printer *pp, tree t)
function-specifier declaration-specifiers(opt) */
void
-pp_c_declaration_specifiers (c_pretty_printer *pp, tree t)
+c_pretty_printer::declaration_specifiers (tree t)
{
- pp_storage_class_specifier (pp, t);
- pp_function_specifier (pp, t);
- pp_c_specifier_qualifier_list (pp, DECL_P (t) ? TREE_TYPE (t) : t);
+ storage_class_specifier (t);
+ function_specifier (t);
+ pp_c_specifier_qualifier_list (this, DECL_P (t) ? TREE_TYPE (t) : t);
}
/* direct-declarator
@@ -677,7 +673,7 @@ pp_c_declaration_specifiers (c_pretty_printer *pp, tree t)
direct-declarator ( identifier-list(opt) ) */
void
-pp_c_direct_declarator (c_pretty_printer *pp, tree t)
+c_pretty_printer::direct_declarator (tree t)
{
switch (TREE_CODE (t))
{
@@ -686,29 +682,29 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t)
case TYPE_DECL:
case FIELD_DECL:
case LABEL_DECL:
- pp_c_space_for_pointer_operator (pp, TREE_TYPE (t));
- pp_c_tree_decl_identifier (pp, t);
+ pp_c_space_for_pointer_operator (this, TREE_TYPE (t));
+ pp_c_tree_decl_identifier (this, t);
break;
case ARRAY_TYPE:
case POINTER_TYPE:
- pp_abstract_declarator (pp, TREE_TYPE (t));
+ abstract_declarator (TREE_TYPE (t));
break;
case FUNCTION_TYPE:
- pp_parameter_list (pp, t);
- pp_abstract_declarator (pp, TREE_TYPE (t));
+ pp_parameter_list (this, t);
+ abstract_declarator (TREE_TYPE (t));
break;
case FUNCTION_DECL:
- pp_c_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
- pp_c_tree_decl_identifier (pp, t);
- if (pp_c_base (pp)->flags & pp_c_flag_abstract)
- pp_abstract_declarator (pp, TREE_TYPE (t));
+ pp_c_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
+ pp_c_tree_decl_identifier (this, t);
+ if (flags & pp_c_flag_abstract)
+ abstract_declarator (TREE_TYPE (t));
else
{
- pp_parameter_list (pp, t);
- pp_abstract_declarator (pp, TREE_TYPE (TREE_TYPE (t)));
+ pp_parameter_list (this, t);
+ abstract_declarator (TREE_TYPE (TREE_TYPE (t)));
}
break;
@@ -721,7 +717,7 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t)
break;
default:
- pp_unsupported_tree (pp, t);
+ pp_unsupported_tree (this, t);
break;
}
}
@@ -731,7 +727,7 @@ pp_c_direct_declarator (c_pretty_printer *pp, tree t)
pointer(opt) direct-declarator */
void
-pp_c_declarator (c_pretty_printer *pp, tree t)
+c_pretty_printer::declarator (tree t)
{
switch (TREE_CODE (t))
{
@@ -750,12 +746,12 @@ pp_c_declarator (c_pretty_printer *pp, tree t)
case FUNCTION_TYPE:
case FUNCTION_DECL:
case TYPE_DECL:
- pp_direct_declarator (pp, t);
+ direct_declarator (t);
break;
default:
- pp_unsupported_tree (pp, t);
+ pp_unsupported_tree (this, t);
break;
}
}
@@ -764,10 +760,10 @@ pp_c_declarator (c_pretty_printer *pp, tree t)
declaration-specifiers init-declarator-list(opt) ; */
void
-pp_c_declaration (c_pretty_printer *pp, tree t)
+c_pretty_printer::declaration (tree t)
{
- pp_declaration_specifiers (pp, t);
- pp_c_init_declarator (pp, t);
+ declaration_specifiers (t);
+ pp_c_init_declarator (this, t);
}
/* Pretty-print ATTRIBUTES using GNU C extension syntax. */
@@ -841,10 +837,10 @@ pp_c_attributes_display (c_pretty_printer *pp, tree a)
void
pp_c_function_definition (c_pretty_printer *pp, tree t)
{
- pp_declaration_specifiers (pp, t);
- pp_declarator (pp, t);
+ pp->declaration_specifiers (t);
+ pp->declarator (t);
pp_needs_newline (pp) = true;
- pp_statement (pp, DECL_SAVED_TREE (t));
+ pp->statement (DECL_SAVED_TREE (t));
pp_newline_and_flush (pp);
}
@@ -920,7 +916,7 @@ pp_c_integer_constant (c_pretty_printer *pp, tree i)
HOST_WIDE_INT high = TREE_INT_CST_HIGH (i);
if (tree_int_cst_sgn (i) < 0)
{
- pp_character (pp, '-');
+ pp_minus (pp);
high = ~high + !low;
low = -low;
}
@@ -1004,7 +1000,7 @@ pp_c_enumeration_constant (c_pretty_printer *pp, tree e)
;
if (value != NULL_TREE)
- pp_id_expression (pp, TREE_PURPOSE (value));
+ pp->id_expression (TREE_PURPOSE (value));
else
{
/* Value must have been cast. */
@@ -1104,7 +1100,7 @@ pp_c_complex_expr (c_pretty_printer *pp, tree e)
== TREE_OPERAND (TREE_OPERAND (imagexpr, 0), 0))
{
pp_c_type_cast (pp, type);
- pp_expression (pp, TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0));
+ pp->expression (TREE_OPERAND (TREE_OPERAND (realexpr, 0), 0));
return;
}
@@ -1115,7 +1111,7 @@ pp_c_complex_expr (c_pretty_printer *pp, tree e)
pp_c_type_cast (pp, type);
if (TREE_CODE (realexpr) == NOP_EXPR)
realexpr = TREE_OPERAND (realexpr, 0);
- pp_expression (pp, realexpr);
+ pp->expression (realexpr);
return;
}
@@ -1130,7 +1126,7 @@ pp_c_complex_expr (c_pretty_printer *pp, tree e)
character-constant */
void
-pp_c_constant (c_pretty_printer *pp, tree e)
+c_pretty_printer::constant (tree e)
{
const enum tree_code code = TREE_CODE (e);
@@ -1140,38 +1136,38 @@ pp_c_constant (c_pretty_printer *pp, tree e)
{
tree type = TREE_TYPE (e);
if (type == boolean_type_node)
- pp_c_bool_constant (pp, e);
+ pp_c_bool_constant (this, e);
else if (type == char_type_node)
- pp_c_character_constant (pp, e);
+ pp_c_character_constant (this, e);
else if (TREE_CODE (type) == ENUMERAL_TYPE
- && pp_c_enumeration_constant (pp, e))
+ && pp_c_enumeration_constant (this, e))
;
else
- pp_c_integer_constant (pp, e);
+ pp_c_integer_constant (this, e);
}
break;
case REAL_CST:
- pp_c_floating_constant (pp, e);
+ pp_c_floating_constant (this, e);
break;
case FIXED_CST:
- pp_c_fixed_constant (pp, e);
+ pp_c_fixed_constant (this, e);
break;
case STRING_CST:
- pp_c_string_literal (pp, e);
+ pp_c_string_literal (this, e);
break;
case COMPLEX_CST:
/* Sometimes, we are confused and we think a complex literal
is a constant. Such thing is a compound literal which
grammatically belongs to postfix-expr production. */
- pp_c_compound_literal (pp, e);
+ pp_c_compound_literal (this, e);
break;
default:
- pp_unsupported_tree (pp, e);
+ pp_unsupported_tree (this, e);
break;
}
}
@@ -1184,7 +1180,16 @@ pp_c_ws_string (c_pretty_printer *pp, const char *str)
{
pp_c_maybe_whitespace (pp);
pp_string (pp, str);
- pp_base (pp)->padding = pp_before;
+ pp->padding = pp_before;
+}
+
+void
+c_pretty_printer::translate_string (const char *gmsgid)
+{
+ if (pp_translate_identifiers (this))
+ pp_c_ws_string (this, _(gmsgid));
+ else
+ pp_c_ws_string (this, gmsgid);
}
/* Pretty-print an IDENTIFIER_NODE, which may contain UTF-8 sequences
@@ -1196,7 +1201,7 @@ pp_c_identifier (c_pretty_printer *pp, const char *id)
{
pp_c_maybe_whitespace (pp);
pp_identifier (pp, id);
- pp_base (pp)->padding = pp_before;
+ pp->padding = pp_before;
}
/* Pretty-print a C primary-expression.
@@ -1207,7 +1212,7 @@ pp_c_identifier (c_pretty_printer *pp, const char *id)
( expression ) */
void
-pp_c_primary_expression (c_pretty_printer *pp, tree e)
+c_pretty_printer::primary_expression (tree e)
{
switch (TREE_CODE (e))
{
@@ -1217,49 +1222,49 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e)
case CONST_DECL:
case FUNCTION_DECL:
case LABEL_DECL:
- pp_c_tree_decl_identifier (pp, e);
+ pp_c_tree_decl_identifier (this, e);
break;
case IDENTIFIER_NODE:
- pp_c_tree_identifier (pp, e);
+ pp_c_tree_identifier (this, e);
break;
case ERROR_MARK:
- pp_c_ws_string (pp, M_("<erroneous-expression>"));
+ translate_string ("<erroneous-expression>");
break;
case RESULT_DECL:
- pp_c_ws_string (pp, M_("<return-value>"));
+ translate_string ("<return-value>");
break;
case INTEGER_CST:
case REAL_CST:
case FIXED_CST:
case STRING_CST:
- pp_c_constant (pp, e);
+ constant (e);
break;
case TARGET_EXPR:
- pp_c_ws_string (pp, "__builtin_memcpy");
- pp_c_left_paren (pp);
- pp_ampersand (pp);
- pp_primary_expression (pp, TREE_OPERAND (e, 0));
- pp_separate_with (pp, ',');
- pp_ampersand (pp);
- pp_initializer (pp, TREE_OPERAND (e, 1));
+ pp_c_ws_string (this, "__builtin_memcpy");
+ pp_c_left_paren (this);
+ pp_ampersand (this);
+ primary_expression (TREE_OPERAND (e, 0));
+ pp_separate_with (this, ',');
+ pp_ampersand (this);
+ initializer (TREE_OPERAND (e, 1));
if (TREE_OPERAND (e, 2))
{
- pp_separate_with (pp, ',');
- pp_c_expression (pp, TREE_OPERAND (e, 2));
+ pp_separate_with (this, ',');
+ expression (TREE_OPERAND (e, 2));
}
- pp_c_right_paren (pp);
+ pp_c_right_paren (this);
break;
default:
/* FIXME: Make sure we won't get into an infinite loop. */
- pp_c_left_paren (pp);
- pp_expression (pp, e);
- pp_c_right_paren (pp);
+ pp_c_left_paren (this);
+ expression (e);
+ pp_c_right_paren (this);
break;
}
}
@@ -1270,13 +1275,13 @@ pp_c_primary_expression (c_pretty_printer *pp, tree e)
{ initializer-list }
{ initializer-list , } */
-static void
-pp_c_initializer (c_pretty_printer *pp, tree e)
+void
+c_pretty_printer::initializer (tree e)
{
if (TREE_CODE (e) == CONSTRUCTOR)
- pp_c_brace_enclosed_initializer_list (pp, e);
+ pp_c_brace_enclosed_initializer_list (this, e);
else
- pp_expression (pp, e);
+ expression (e);
}
/* init-declarator:
@@ -1286,7 +1291,7 @@ pp_c_initializer (c_pretty_printer *pp, tree e)
void
pp_c_init_declarator (c_pretty_printer *pp, tree t)
{
- pp_declarator (pp, t);
+ pp->declarator (t);
/* We don't want to output function definitions here. There are handled
elsewhere (and the syntactic form is bogus anyway). */
if (TREE_CODE (t) != FUNCTION_DECL && DECL_INITIAL (t))
@@ -1299,7 +1304,7 @@ pp_c_init_declarator (c_pretty_printer *pp, tree t)
if (TREE_CODE (init) == TREE_LIST)
{
pp_c_left_paren (pp);
- pp_expression (pp, TREE_VALUE (init));
+ pp->expression (TREE_VALUE (init));
pp_right_paren (pp);
}
else
@@ -1307,7 +1312,7 @@ pp_c_init_declarator (c_pretty_printer *pp, tree t)
pp_space (pp);
pp_equal (pp);
pp_space (pp);
- pp_c_initializer (pp, init);
+ pp->initializer (init);
}
}
}
@@ -1351,19 +1356,19 @@ pp_c_initializer_list (c_pretty_printer *pp, tree e)
if (code == RECORD_TYPE || code == UNION_TYPE)
{
pp_c_dot (pp);
- pp_c_primary_expression (pp, TREE_PURPOSE (init));
+ pp->primary_expression (TREE_PURPOSE (init));
}
else
{
pp_c_left_bracket (pp);
if (TREE_PURPOSE (init))
- pp_c_constant (pp, TREE_PURPOSE (init));
+ pp->constant (TREE_PURPOSE (init));
pp_c_right_bracket (pp);
}
pp_c_whitespace (pp);
pp_equal (pp);
pp_c_whitespace (pp);
- pp_initializer (pp, TREE_VALUE (init));
+ pp->initializer (TREE_VALUE (init));
if (TREE_CHAIN (init))
pp_separate_with (pp, ',');
}
@@ -1378,7 +1383,7 @@ pp_c_initializer_list (c_pretty_printer *pp, tree e)
{
if (i > 0)
pp_separate_with (pp, ',');
- pp_expression (pp, VECTOR_CST_ELT (e, i));
+ pp->expression (VECTOR_CST_ELT (e, i));
}
}
else
@@ -1389,9 +1394,9 @@ pp_c_initializer_list (c_pretty_printer *pp, tree e)
if (TREE_CODE (e) == COMPLEX_CST || TREE_CODE (e) == COMPLEX_EXPR)
{
const bool cst = TREE_CODE (e) == COMPLEX_CST;
- pp_expression (pp, cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
+ pp->expression (cst ? TREE_REALPART (e) : TREE_OPERAND (e, 0));
pp_separate_with (pp, ',');
- pp_expression (pp, cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
+ pp->expression (cst ? TREE_IMAGPART (e) : TREE_OPERAND (e, 1));
}
else
break;
@@ -1422,7 +1427,7 @@ pp_c_brace_enclosed_initializer_list (c_pretty_printer *pp, tree l)
identifier */
void
-pp_c_id_expression (c_pretty_printer *pp, tree t)
+c_pretty_printer::id_expression (tree t)
{
switch (TREE_CODE (t))
{
@@ -1433,15 +1438,15 @@ pp_c_id_expression (c_pretty_printer *pp, tree t)
case FUNCTION_DECL:
case FIELD_DECL:
case LABEL_DECL:
- pp_c_tree_decl_identifier (pp, t);
+ pp_c_tree_decl_identifier (this, t);
break;
case IDENTIFIER_NODE:
- pp_c_tree_identifier (pp, t);
+ pp_c_tree_identifier (this, t);
break;
default:
- pp_unsupported_tree (pp, t);
+ pp_unsupported_tree (this, t);
break;
}
}
@@ -1458,112 +1463,112 @@ pp_c_id_expression (c_pretty_printer *pp, tree t)
( type-name ) { initializer-list , } */
void
-pp_c_postfix_expression (c_pretty_printer *pp, tree e)
+c_pretty_printer::postfix_expression (tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
{
case POSTINCREMENT_EXPR:
case POSTDECREMENT_EXPR:
- pp_postfix_expression (pp, TREE_OPERAND (e, 0));
- pp_string (pp, code == POSTINCREMENT_EXPR ? "++" : "--");
+ postfix_expression (TREE_OPERAND (e, 0));
+ pp_string (this, code == POSTINCREMENT_EXPR ? "++" : "--");
break;
case ARRAY_REF:
- pp_postfix_expression (pp, TREE_OPERAND (e, 0));
- pp_c_left_bracket (pp);
- pp_expression (pp, TREE_OPERAND (e, 1));
- pp_c_right_bracket (pp);
+ postfix_expression (TREE_OPERAND (e, 0));
+ pp_c_left_bracket (this);
+ expression (TREE_OPERAND (e, 1));
+ pp_c_right_bracket (this);
break;
case ARRAY_NOTATION_REF:
- pp_postfix_expression (pp, ARRAY_NOTATION_ARRAY (e));
- pp_c_left_bracket (pp);
- pp_expression (pp, ARRAY_NOTATION_START (e));
- pp_colon (pp);
- pp_expression (pp, ARRAY_NOTATION_LENGTH (e));
- pp_colon (pp);
- pp_expression (pp, ARRAY_NOTATION_STRIDE (e));
- pp_c_right_bracket (pp);
+ postfix_expression (ARRAY_NOTATION_ARRAY (e));
+ pp_c_left_bracket (this);
+ expression (ARRAY_NOTATION_START (e));
+ pp_colon (this);
+ expression (ARRAY_NOTATION_LENGTH (e));
+ pp_colon (this);
+ expression (ARRAY_NOTATION_STRIDE (e));
+ pp_c_right_bracket (this);
break;
case CALL_EXPR:
{
call_expr_arg_iterator iter;
tree arg;
- pp_postfix_expression (pp, CALL_EXPR_FN (e));
- pp_c_left_paren (pp);
+ postfix_expression (CALL_EXPR_FN (e));
+ pp_c_left_paren (this);
FOR_EACH_CALL_EXPR_ARG (arg, iter, e)
{
- pp_expression (pp, arg);
+ expression (arg);
if (more_call_expr_args_p (&iter))
- pp_separate_with (pp, ',');
+ pp_separate_with (this, ',');
}
- pp_c_right_paren (pp);
+ pp_c_right_paren (this);
break;
}
case UNORDERED_EXPR:
- pp_c_ws_string (pp, flag_isoc99
+ pp_c_ws_string (this, flag_isoc99
? "isunordered"
: "__builtin_isunordered");
goto two_args_fun;
case ORDERED_EXPR:
- pp_c_ws_string (pp, flag_isoc99
+ pp_c_ws_string (this, flag_isoc99
? "!isunordered"
: "!__builtin_isunordered");
goto two_args_fun;
case UNLT_EXPR:
- pp_c_ws_string (pp, flag_isoc99
+ pp_c_ws_string (this, flag_isoc99
? "!isgreaterequal"
: "!__builtin_isgreaterequal");
goto two_args_fun;
case UNLE_EXPR:
- pp_c_ws_string (pp, flag_isoc99
+ pp_c_ws_string (this, flag_isoc99
? "!isgreater"
: "!__builtin_isgreater");
goto two_args_fun;
case UNGT_EXPR:
- pp_c_ws_string (pp, flag_isoc99
+ pp_c_ws_string (this, flag_isoc99
? "!islessequal"
: "!__builtin_islessequal");
goto two_args_fun;
case UNGE_EXPR:
- pp_c_ws_string (pp, flag_isoc99
+ pp_c_ws_string (this, flag_isoc99
? "!isless"
: "!__builtin_isless");
goto two_args_fun;
case UNEQ_EXPR:
- pp_c_ws_string (pp, flag_isoc99
+ pp_c_ws_string (this, flag_isoc99
? "!islessgreater"
: "!__builtin_islessgreater");
goto two_args_fun;
case LTGT_EXPR:
- pp_c_ws_string (pp, flag_isoc99
+ pp_c_ws_string (this, flag_isoc99
? "islessgreater"
: "__builtin_islessgreater");
goto two_args_fun;
two_args_fun:
- pp_c_left_paren (pp);
- pp_expression (pp, TREE_OPERAND (e, 0));
- pp_separate_with (pp, ',');
- pp_expression (pp, TREE_OPERAND (e, 1));
- pp_c_right_paren (pp);
+ pp_c_left_paren (this);
+ expression (TREE_OPERAND (e, 0));
+ pp_separate_with (this, ',');
+ expression (TREE_OPERAND (e, 1));
+ pp_c_right_paren (this);
break;
case ABS_EXPR:
- pp_c_ws_string (pp, "__builtin_abs");
- pp_c_left_paren (pp);
- pp_expression (pp, TREE_OPERAND (e, 0));
- pp_c_right_paren (pp);
+ pp_c_ws_string (this, "__builtin_abs");
+ pp_c_left_paren (this);
+ expression (TREE_OPERAND (e, 0));
+ pp_c_right_paren (this);
break;
case COMPONENT_REF:
@@ -1571,15 +1576,15 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e)
tree object = TREE_OPERAND (e, 0);
if (TREE_CODE (object) == INDIRECT_REF)
{
- pp_postfix_expression (pp, TREE_OPERAND (object, 0));
- pp_c_arrow (pp);
+ postfix_expression (TREE_OPERAND (object, 0));
+ pp_c_arrow (this);
}
else
{
- pp_postfix_expression (pp, object);
- pp_c_dot (pp);
+ postfix_expression (object);
+ pp_c_dot (this);
}
- pp_expression (pp, TREE_OPERAND (e, 1));
+ expression (TREE_OPERAND (e, 1));
}
break;
@@ -1595,63 +1600,63 @@ pp_c_postfix_expression (c_pretty_printer *pp, tree e)
HOST_WIDE_INT size = tree_low_cst (TYPE_SIZE (type), 0);
if ((bitpos % size) == 0)
{
- pp_c_left_paren (pp);
- pp_c_left_paren (pp);
- pp_type_id (pp, type);
- pp_c_star (pp);
- pp_c_right_paren (pp);
- pp_c_ampersand (pp);
- pp_expression (pp, TREE_OPERAND (e, 0));
- pp_c_right_paren (pp);
- pp_c_left_bracket (pp);
- pp_wide_integer (pp, bitpos / size);
- pp_c_right_bracket (pp);
+ pp_c_left_paren (this);
+ pp_c_left_paren (this);
+ type_id (type);
+ pp_c_star (this);
+ pp_c_right_paren (this);
+ pp_c_ampersand (this);
+ expression (TREE_OPERAND (e, 0));
+ pp_c_right_paren (this);
+ pp_c_left_bracket (this);
+ pp_wide_integer (this, bitpos / size);
+ pp_c_right_bracket (this);
break;
}
}
- pp_unsupported_tree (pp, e);
+ pp_unsupported_tree (this, e);
}
break;
case MEM_REF:
- pp_c_expression (pp, e);
+ expression (e);
break;
case COMPLEX_CST:
case VECTOR_CST:
- pp_c_compound_literal (pp, e);
+ pp_c_compound_literal (this, e);
break;
case COMPLEX_EXPR:
- pp_c_complex_expr (pp, e);
+ pp_c_complex_expr (this, e);
break;
case COMPOUND_LITERAL_EXPR:
e = DECL_INITIAL (COMPOUND_LITERAL_EXPR_DECL (e));
/* Fall through. */
case CONSTRUCTOR:
- pp_initializer (pp, e);
+ initializer (e);
break;
case VA_ARG_EXPR:
- pp_c_ws_string (pp, "__builtin_va_arg");
- pp_c_left_paren (pp);
- pp_assignment_expression (pp, TREE_OPERAND (e, 0));
- pp_separate_with (pp, ',');
- pp_type_id (pp, TREE_TYPE (e));
- pp_c_right_paren (pp);
+ pp_c_ws_string (this, "__builtin_va_arg");
+ pp_c_left_paren (this);
+ assignment_expression (TREE_OPERAND (e, 0));
+ pp_separate_with (this, ',');
+ type_id (TREE_TYPE (e));
+ pp_c_right_paren (this);
break;
case ADDR_EXPR:
if (TREE_CODE (TREE_OPERAND (e, 0)) == FUNCTION_DECL)
{
- pp_c_id_expression (pp, TREE_OPERAND (e, 0));
+ id_expression (TREE_OPERAND (e, 0));
break;
}
/* else fall through. */
default:
- pp_primary_expression (pp, e);
+ primary_expression (e);
break;
}
}
@@ -1663,7 +1668,7 @@ pp_c_expression_list (c_pretty_printer *pp, tree e)
{
for (; e != NULL_TREE; e = TREE_CHAIN (e))
{
- pp_expression (pp, TREE_VALUE (e));
+ pp->expression (TREE_VALUE (e));
if (TREE_CHAIN (e))
pp_separate_with (pp, ',');
}
@@ -1679,7 +1684,7 @@ pp_c_constructor_elts (c_pretty_printer *pp, vec<constructor_elt, va_gc> *v)
FOR_EACH_CONSTRUCTOR_VALUE (v, ix, value)
{
- pp_expression (pp, value);
+ pp->expression (value);
if (ix != vec_safe_length (v) - 1)
pp_separate_with (pp, ',');
}
@@ -1716,15 +1721,15 @@ pp_c_call_argument_list (c_pretty_printer *pp, tree t)
__imag__ unary-expression */
void
-pp_c_unary_expression (c_pretty_printer *pp, tree e)
+c_pretty_printer::unary_expression (tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
{
case PREINCREMENT_EXPR:
case PREDECREMENT_EXPR:
- pp_string (pp, code == PREINCREMENT_EXPR ? "++" : "--");
- pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
+ pp_string (this, code == PREINCREMENT_EXPR ? "++" : "--");
+ unary_expression (TREE_OPERAND (e, 0));
break;
case ADDR_EXPR:
@@ -1735,53 +1740,53 @@ pp_c_unary_expression (c_pretty_printer *pp, tree e)
case CONJ_EXPR:
/* String literal are used by address. */
if (code == ADDR_EXPR && TREE_CODE (TREE_OPERAND (e, 0)) != STRING_CST)
- pp_ampersand (pp);
+ pp_ampersand (this);
else if (code == INDIRECT_REF)
- pp_c_star (pp);
+ pp_c_star (this);
else if (code == NEGATE_EXPR)
- pp_minus (pp);
+ pp_minus (this);
else if (code == BIT_NOT_EXPR || code == CONJ_EXPR)
- pp_complement (pp);
+ pp_complement (this);
else if (code == TRUTH_NOT_EXPR)
- pp_exclamation (pp);
- pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
+ pp_exclamation (this);
+ pp_c_cast_expression (this, TREE_OPERAND (e, 0));
break;
case MEM_REF:
if (TREE_CODE (TREE_OPERAND (e, 0)) == ADDR_EXPR
&& integer_zerop (TREE_OPERAND (e, 1)))
- pp_c_expression (pp, TREE_OPERAND (TREE_OPERAND (e, 0), 0));
+ expression (TREE_OPERAND (TREE_OPERAND (e, 0), 0));
else
{
- pp_c_star (pp);
+ pp_c_star (this);
if (!integer_zerop (TREE_OPERAND (e, 1)))
{
- pp_c_left_paren (pp);
+ pp_c_left_paren (this);
if (!integer_onep (TYPE_SIZE_UNIT
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (e, 0))))))
- pp_c_type_cast (pp, ptr_type_node);
+ pp_c_type_cast (this, ptr_type_node);
}
- pp_c_cast_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_cast_expression (this, TREE_OPERAND (e, 0));
if (!integer_zerop (TREE_OPERAND (e, 1)))
{
- pp_plus (pp);
- pp_c_integer_constant (pp,
+ pp_plus (this);
+ pp_c_integer_constant (this,
fold_convert (ssizetype,
TREE_OPERAND (e, 1)));
- pp_c_right_paren (pp);
+ pp_c_right_paren (this);
}
}
break;
case REALPART_EXPR:
case IMAGPART_EXPR:
- pp_c_ws_string (pp, code == REALPART_EXPR ? "__real__" : "__imag__");
- pp_c_whitespace (pp);
- pp_unary_expression (pp, TREE_OPERAND (e, 0));
+ pp_c_ws_string (this, code == REALPART_EXPR ? "__real__" : "__imag__");
+ pp_c_whitespace (this);
+ unary_expression (TREE_OPERAND (e, 0));
break;
default:
- pp_postfix_expression (pp, e);
+ postfix_expression (e);
break;
}
}
@@ -1804,7 +1809,7 @@ pp_c_cast_expression (c_pretty_printer *pp, tree e)
break;
default:
- pp_unary_expression (pp, e);
+ pp->unary_expression (e);
}
}
@@ -1814,8 +1819,8 @@ pp_c_cast_expression (c_pretty_printer *pp, tree e)
multiplicative-expression / cast-expression
multiplicative-expression % cast-expression */
-static void
-pp_c_multiplicative_expression (c_pretty_printer *pp, tree e)
+void
+c_pretty_printer::multiplicative_expression (tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
@@ -1823,20 +1828,20 @@ pp_c_multiplicative_expression (c_pretty_printer *pp, tree e)
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
- pp_multiplicative_expression (pp, TREE_OPERAND (e, 0));
- pp_c_whitespace (pp);
+ multiplicative_expression (TREE_OPERAND (e, 0));
+ pp_c_whitespace (this);
if (code == MULT_EXPR)
- pp_c_star (pp);
+ pp_c_star (this);
else if (code == TRUNC_DIV_EXPR)
- pp_slash (pp);
+ pp_slash (this);
else
- pp_modulo (pp);
- pp_c_whitespace (pp);
- pp_c_cast_expression (pp, TREE_OPERAND (e, 1));
+ pp_modulo (this);
+ pp_c_whitespace (this);
+ pp_c_cast_expression (this, TREE_OPERAND (e, 1));
break;
default:
- pp_c_cast_expression (pp, e);
+ pp_c_cast_expression (this, e);
break;
}
}
@@ -1862,11 +1867,11 @@ pp_c_additive_expression (c_pretty_printer *pp, tree e)
else
pp_minus (pp);
pp_c_whitespace (pp);
- pp_multiplicative_expression (pp, TREE_OPERAND (e, 1));
+ pp->multiplicative_expression (TREE_OPERAND (e, 1));
break;
default:
- pp_multiplicative_expression (pp, e);
+ pp->multiplicative_expression (e);
break;
}
}
@@ -1920,9 +1925,9 @@ pp_c_relational_expression (c_pretty_printer *pp, tree e)
else if (code == GT_EXPR)
pp_greater (pp);
else if (code == LE_EXPR)
- pp_string (pp, "<=");
+ pp_less_equal (pp);
else if (code == GE_EXPR)
- pp_string (pp, ">=");
+ pp_greater_equal (pp);
pp_c_whitespace (pp);
pp_c_shift_expression (pp, TREE_OPERAND (e, 1));
break;
@@ -2032,7 +2037,7 @@ pp_c_logical_and_expression (c_pretty_printer *pp, tree e)
{
pp_c_logical_and_expression (pp, TREE_OPERAND (e, 0));
pp_c_whitespace (pp);
- pp_string (pp, "&&");
+ pp_ampersand_ampersand (pp);
pp_c_whitespace (pp);
pp_c_inclusive_or_expression (pp, TREE_OPERAND (e, 1));
}
@@ -2052,7 +2057,7 @@ pp_c_logical_or_expression (c_pretty_printer *pp, tree e)
{
pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
pp_c_whitespace (pp);
- pp_string (pp, "||");
+ pp_bar_bar (pp);
pp_c_whitespace (pp);
pp_c_logical_and_expression (pp, TREE_OPERAND (e, 1));
}
@@ -2064,23 +2069,23 @@ pp_c_logical_or_expression (c_pretty_printer *pp, tree e)
logical-OR-expression
logical-OR-expression ? expression : conditional-expression */
-static void
-pp_c_conditional_expression (c_pretty_printer *pp, tree e)
+void
+c_pretty_printer::conditional_expression (tree e)
{
if (TREE_CODE (e) == COND_EXPR)
{
- pp_c_logical_or_expression (pp, TREE_OPERAND (e, 0));
- pp_c_whitespace (pp);
- pp_question (pp);
- pp_c_whitespace (pp);
- pp_expression (pp, TREE_OPERAND (e, 1));
- pp_c_whitespace (pp);
- pp_colon (pp);
- pp_c_whitespace (pp);
- pp_c_conditional_expression (pp, TREE_OPERAND (e, 2));
+ pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
+ pp_c_whitespace (this);
+ pp_question (this);
+ pp_c_whitespace (this);
+ expression (TREE_OPERAND (e, 1));
+ pp_c_whitespace (this);
+ pp_colon (this);
+ pp_c_whitespace (this);
+ conditional_expression (TREE_OPERAND (e, 2));
}
else
- pp_c_logical_or_expression (pp, e);
+ pp_c_logical_or_expression (this, e);
}
@@ -2091,20 +2096,20 @@ pp_c_conditional_expression (c_pretty_printer *pp, tree e)
assignment-expression: one of
= *= /= %= += -= >>= <<= &= ^= |= */
-static void
-pp_c_assignment_expression (c_pretty_printer *pp, tree e)
+void
+c_pretty_printer::assignment_expression (tree e)
{
if (TREE_CODE (e) == MODIFY_EXPR
|| TREE_CODE (e) == INIT_EXPR)
{
- pp_c_unary_expression (pp, TREE_OPERAND (e, 0));
- pp_c_whitespace (pp);
- pp_equal (pp);
- pp_space (pp);
- pp_c_expression (pp, TREE_OPERAND (e, 1));
+ unary_expression (TREE_OPERAND (e, 0));
+ pp_c_whitespace (this);
+ pp_equal (this);
+ pp_space (this);
+ expression (TREE_OPERAND (e, 1));
}
else
- pp_c_conditional_expression (pp, e);
+ conditional_expression (e);
}
/* expression:
@@ -2114,28 +2119,28 @@ pp_c_assignment_expression (c_pretty_printer *pp, tree e)
Implementation note: instead of going through the usual recursion
chain, I take the liberty of dispatching nodes to the appropriate
functions. This makes some redundancy, but it worths it. That also
- prevents a possible infinite recursion between pp_c_primary_expression ()
- and pp_c_expression (). */
+ prevents a possible infinite recursion between primary_expression ()
+ and expression (). */
void
-pp_c_expression (c_pretty_printer *pp, tree e)
+c_pretty_printer::expression (tree e)
{
switch (TREE_CODE (e))
{
case INTEGER_CST:
- pp_c_integer_constant (pp, e);
+ pp_c_integer_constant (this, e);
break;
case REAL_CST:
- pp_c_floating_constant (pp, e);
+ pp_c_floating_constant (this, e);
break;
case FIXED_CST:
- pp_c_fixed_constant (pp, e);
+ pp_c_fixed_constant (this, e);
break;
case STRING_CST:
- pp_c_string_literal (pp, e);
+ pp_c_string_literal (this, e);
break;
case IDENTIFIER_NODE:
@@ -2147,15 +2152,15 @@ pp_c_expression (c_pretty_printer *pp, tree e)
case FIELD_DECL:
case LABEL_DECL:
case ERROR_MARK:
- pp_primary_expression (pp, e);
+ primary_expression (e);
break;
case SSA_NAME:
if (SSA_NAME_VAR (e)
&& !DECL_ARTIFICIAL (SSA_NAME_VAR (e)))
- pp_c_expression (pp, SSA_NAME_VAR (e));
+ expression (SSA_NAME_VAR (e));
else
- pp_c_ws_string (pp, M_("<unknown>"));
+ translate_string ("<unknown>");
break;
case POSTINCREMENT_EXPR:
@@ -2180,7 +2185,7 @@ pp_c_expression (c_pretty_printer *pp, tree e)
case CONSTRUCTOR:
case COMPOUND_LITERAL_EXPR:
case VA_ARG_EXPR:
- pp_postfix_expression (pp, e);
+ postfix_expression (e);
break;
case CONJ_EXPR:
@@ -2194,107 +2199,107 @@ pp_c_expression (c_pretty_printer *pp, tree e)
case PREDECREMENT_EXPR:
case REALPART_EXPR:
case IMAGPART_EXPR:
- pp_c_unary_expression (pp, e);
+ unary_expression (e);
break;
case FLOAT_EXPR:
case FIX_TRUNC_EXPR:
CASE_CONVERT:
case VIEW_CONVERT_EXPR:
- pp_c_cast_expression (pp, e);
+ pp_c_cast_expression (this, e);
break;
case MULT_EXPR:
case TRUNC_MOD_EXPR:
case TRUNC_DIV_EXPR:
- pp_multiplicative_expression (pp, e);
+ multiplicative_expression (e);
break;
case LSHIFT_EXPR:
case RSHIFT_EXPR:
- pp_c_shift_expression (pp, e);
+ pp_c_shift_expression (this, e);
break;
case LT_EXPR:
case GT_EXPR:
case LE_EXPR:
case GE_EXPR:
- pp_c_relational_expression (pp, e);
+ pp_c_relational_expression (this, e);
break;
case BIT_AND_EXPR:
- pp_c_and_expression (pp, e);
+ pp_c_and_expression (this, e);
break;
case BIT_XOR_EXPR:
case TRUTH_XOR_EXPR:
- pp_c_exclusive_or_expression (pp, e);
+ pp_c_exclusive_or_expression (this, e);
break;
case BIT_IOR_EXPR:
- pp_c_inclusive_or_expression (pp, e);
+ pp_c_inclusive_or_expression (this, e);
break;
case TRUTH_ANDIF_EXPR:
case TRUTH_AND_EXPR:
- pp_c_logical_and_expression (pp, e);
+ pp_c_logical_and_expression (this, e);
break;
case TRUTH_ORIF_EXPR:
case TRUTH_OR_EXPR:
- pp_c_logical_or_expression (pp, e);
+ pp_c_logical_or_expression (this, e);
break;
case EQ_EXPR:
case NE_EXPR:
- pp_c_equality_expression (pp, e);
+ pp_c_equality_expression (this, e);
break;
case COND_EXPR:
- pp_conditional_expression (pp, e);
+ conditional_expression (e);
break;
case POINTER_PLUS_EXPR:
case PLUS_EXPR:
case MINUS_EXPR:
- pp_c_additive_expression (pp, e);
+ pp_c_additive_expression (this, e);
break;
case MODIFY_EXPR:
case INIT_EXPR:
- pp_assignment_expression (pp, e);
+ assignment_expression (e);
break;
case COMPOUND_EXPR:
- pp_c_left_paren (pp);
- pp_expression (pp, TREE_OPERAND (e, 0));
- pp_separate_with (pp, ',');
- pp_assignment_expression (pp, TREE_OPERAND (e, 1));
- pp_c_right_paren (pp);
+ pp_c_left_paren (this);
+ expression (TREE_OPERAND (e, 0));
+ pp_separate_with (this, ',');
+ assignment_expression (TREE_OPERAND (e, 1));
+ pp_c_right_paren (this);
break;
case NON_LVALUE_EXPR:
case SAVE_EXPR:
- pp_expression (pp, TREE_OPERAND (e, 0));
+ expression (TREE_OPERAND (e, 0));
break;
case TARGET_EXPR:
- pp_postfix_expression (pp, TREE_OPERAND (e, 1));
+ postfix_expression (TREE_OPERAND (e, 1));
break;
case BIND_EXPR:
case GOTO_EXPR:
/* We don't yet have a way of dumping statements in a
human-readable format. */
- pp_string (pp, "({...})");
+ pp_string (this, "({...})");
break;
case C_MAYBE_CONST_EXPR:
- pp_c_expression (pp, C_MAYBE_CONST_EXPR_EXPR (e));
+ expression (C_MAYBE_CONST_EXPR_EXPR (e));
break;
default:
- pp_unsupported_tree (pp, e);
+ pp_unsupported_tree (this, e);
break;
}
}
@@ -2304,53 +2309,28 @@ pp_c_expression (c_pretty_printer *pp, tree e)
/* Statements. */
void
-pp_c_statement (c_pretty_printer *pp, tree stmt)
+c_pretty_printer::statement (tree stmt)
{
if (stmt == NULL)
return;
- if (pp_needs_newline (pp))
- pp_newline_and_indent (pp, 0);
+ if (pp_needs_newline (this))
+ pp_newline_and_indent (this, 0);
- dump_generic_node (pp_base (pp), stmt, pp_indentation (pp), 0, true);
+ dump_generic_node (this, stmt, pp_indentation (this), 0, true);
}
/* Initialize the PRETTY-PRINTER for handling C codes. */
-void
-pp_c_pretty_printer_init (c_pretty_printer *pp)
+c_pretty_printer::c_pretty_printer ()
+ : pretty_printer (),
+ offset_list (),
+ flags ()
{
- pp->offset_list = 0;
-
- pp->flags = 0;
-
- pp->declaration = pp_c_declaration;
- pp->declaration_specifiers = pp_c_declaration_specifiers;
- pp->declarator = pp_c_declarator;
- pp->direct_declarator = pp_c_direct_declarator;
- pp->type_specifier_seq = pp_c_specifier_qualifier_list;
- pp->abstract_declarator = pp_c_abstract_declarator;
- pp->direct_abstract_declarator = pp_c_direct_abstract_declarator;
- pp->ptr_operator = pp_c_pointer;
- pp->parameter_list = pp_c_parameter_type_list;
- pp->type_id = pp_c_type_id;
- pp->simple_type_specifier = pp_c_type_specifier;
- pp->function_specifier = pp_c_function_specifier;
- pp->storage_class_specifier = pp_c_storage_class_specifier;
-
- pp->statement = pp_c_statement;
-
- pp->constant = pp_c_constant;
- pp->id_expression = pp_c_id_expression;
- pp->primary_expression = pp_c_primary_expression;
- pp->postfix_expression = pp_c_postfix_expression;
- pp->unary_expression = pp_c_unary_expression;
- pp->initializer = pp_c_initializer;
- pp->multiplicative_expression = pp_c_multiplicative_expression;
- pp->conditional_expression = pp_c_conditional_expression;
- pp->assignment_expression = pp_c_assignment_expression;
- pp->expression = pp_c_expression;
+ type_specifier_seq = pp_c_specifier_qualifier_list;
+ ptr_operator = pp_c_pointer;
+ parameter_list = pp_c_parameter_type_list;
}
@@ -2359,22 +2339,12 @@ pp_c_pretty_printer_init (c_pretty_printer *pp)
void
print_c_tree (FILE *file, tree t)
{
- static c_pretty_printer pp_rec;
- static bool initialized = 0;
- c_pretty_printer *pp = &pp_rec;
+ c_pretty_printer pp;
- if (!initialized)
- {
- initialized = 1;
- pp_construct (pp_base (pp), NULL, 0);
- pp_c_pretty_printer_init (pp);
- pp_needs_newline (pp) = true;
- }
- pp_base (pp)->buffer->stream = file;
-
- pp_statement (pp, t);
-
- pp_newline_and_flush (pp);
+ pp_needs_newline (&pp) = true;
+ pp.buffer->stream = file;
+ pp.statement (t);
+ pp_newline_and_flush (&pp);
}
/* Print the tree T in full, on stderr. */
diff --git a/gcc/c-family/c-pretty-print.h b/gcc/c-family/c-pretty-print.h
index 04b72c49d1a..aa046e51dad 100644
--- a/gcc/c-family/c-pretty-print.h
+++ b/gcc/c-family/c-pretty-print.h
@@ -26,35 +26,58 @@ along with GCC; see the file COPYING3. If not see
#include "pretty-print.h"
-typedef enum
+enum pp_c_pretty_print_flags
{
pp_c_flag_abstract = 1 << 1,
pp_c_flag_gnu_v3 = 1 << 2,
pp_c_flag_last_bit = 3
- } pp_c_pretty_print_flags;
+ };
/* The data type used to bundle information necessary for pretty-printing
a C or C++ entity. */
-typedef struct c_pretty_print_info c_pretty_printer;
+struct c_pretty_printer;
/* The type of a C pretty-printer 'member' function. */
typedef void (*c_pretty_print_fn) (c_pretty_printer *, tree);
/* The datatype that contains information necessary for pretty-printing
a tree that represents a C construct. Any pretty-printer for a
- language using C/c++ syntax can derive from this datatype and reuse
- facilities provided here. It can do so by having a subobject of type
- c_pretty_printer and override the macro pp_c_base to return a pointer
- to that subobject. Such a pretty-printer has the responsibility to
- initialize the pp_base() part, then call pp_c_pretty_printer_init
- to set up the components that are specific to the C pretty-printer.
- A derived pretty-printer can override any function listed in the
- vtable below. See cp/cxx-pretty-print.h and cp/cxx-pretty-print.c
- for an example of derivation. */
-struct c_pretty_print_info
+ language using C syntax can derive from this datatype and reuse
+ facilities provided here. A derived pretty-printer can override
+ any function listed in the vtable below. See cp/cxx-pretty-print.h
+ and cp/cxx-pretty-print.c for an example of derivation. */
+struct c_pretty_printer : pretty_printer
{
- pretty_printer base;
+ c_pretty_printer ();
+
+ // Format string, possibly translated.
+ void translate_string (const char *);
+
+ virtual void constant (tree);
+ virtual void id_expression (tree);
+ virtual void primary_expression (tree);
+ virtual void postfix_expression (tree);
+ virtual void unary_expression (tree);
+ virtual void multiplicative_expression (tree);
+ virtual void conditional_expression (tree);
+ virtual void assignment_expression (tree);
+ virtual void expression (tree);
+
+ virtual void type_id (tree);
+ virtual void statement (tree);
+
+ virtual void declaration (tree);
+ virtual void declaration_specifiers (tree);
+ virtual void simple_type_specifier (tree);
+ virtual void function_specifier (tree);
+ virtual void storage_class_specifier (tree);
+ virtual void declarator (tree);
+ virtual void direct_declarator (tree);
+ virtual void abstract_declarator (tree);
+ virtual void direct_abstract_declarator (tree);
+
+ virtual void initializer (tree);
/* Points to the first element of an array of offset-list.
Not used yet. */
int *offset_list;
@@ -63,100 +86,18 @@ struct c_pretty_print_info
/* These must be overridden by each of the C and C++ front-end to
reflect their understanding of syntactic productions when they differ. */
- c_pretty_print_fn declaration;
- c_pretty_print_fn declaration_specifiers;
- c_pretty_print_fn declarator;
- c_pretty_print_fn abstract_declarator;
- c_pretty_print_fn direct_abstract_declarator;
c_pretty_print_fn type_specifier_seq;
- c_pretty_print_fn direct_declarator;
c_pretty_print_fn ptr_operator;
c_pretty_print_fn parameter_list;
- c_pretty_print_fn type_id;
- c_pretty_print_fn simple_type_specifier;
- c_pretty_print_fn function_specifier;
- c_pretty_print_fn storage_class_specifier;
- c_pretty_print_fn initializer;
-
- c_pretty_print_fn statement;
-
- c_pretty_print_fn constant;
- c_pretty_print_fn id_expression;
- c_pretty_print_fn primary_expression;
- c_pretty_print_fn postfix_expression;
- c_pretty_print_fn unary_expression;
- c_pretty_print_fn multiplicative_expression;
- c_pretty_print_fn conditional_expression;
- c_pretty_print_fn assignment_expression;
- c_pretty_print_fn expression;
};
-/* Override the pp_base macro. Derived pretty-printers should not
- touch this macro. Instead they should override pp_c_base instead. */
-#undef pp_base
-#define pp_base(PP) (&pp_c_base (PP)->base)
-
-
#define pp_c_tree_identifier(PPI, ID) \
pp_c_identifier (PPI, IDENTIFIER_POINTER (ID))
-#define pp_declaration(PPI, T) \
- pp_c_base (PPI)->declaration (pp_c_base (PPI), T)
-#define pp_declaration_specifiers(PPI, D) \
- pp_c_base (PPI)->declaration_specifiers (pp_c_base (PPI), D)
-#define pp_abstract_declarator(PP, D) \
- pp_c_base (PP)->abstract_declarator (pp_c_base (PP), D)
-#define pp_type_specifier_seq(PPI, D) \
- pp_c_base (PPI)->type_specifier_seq (pp_c_base (PPI), D)
-#define pp_declarator(PPI, D) \
- pp_c_base (PPI)->declarator (pp_c_base (PPI), D)
-#define pp_direct_declarator(PPI, D) \
- pp_c_base (PPI)->direct_declarator (pp_c_base (PPI), D)
-#define pp_direct_abstract_declarator(PP, D) \
- pp_c_base (PP)->direct_abstract_declarator (pp_c_base (PP), D)
-#define pp_ptr_operator(PP, D) \
- pp_c_base (PP)->ptr_operator (pp_c_base (PP), D)
-#define pp_parameter_list(PPI, T) \
- pp_c_base (PPI)->parameter_list (pp_c_base (PPI), T)
-#define pp_type_id(PPI, D) \
- pp_c_base (PPI)->type_id (pp_c_base (PPI), D)
-#define pp_simple_type_specifier(PP, T) \
- pp_c_base (PP)->simple_type_specifier (pp_c_base (PP), T)
-#define pp_function_specifier(PP, D) \
- pp_c_base (PP)->function_specifier (pp_c_base (PP), D)
-#define pp_storage_class_specifier(PP, D) \
- pp_c_base (PP)->storage_class_specifier (pp_c_base (PP), D);
-
-#define pp_statement(PPI, S) \
- pp_c_base (PPI)->statement (pp_c_base (PPI), S)
-
-#define pp_constant(PP, E) \
- pp_c_base (PP)->constant (pp_c_base (PP), E)
-#define pp_id_expression(PP, E) \
- pp_c_base (PP)->id_expression (pp_c_base (PP), E)
-#define pp_primary_expression(PPI, E) \
- pp_c_base (PPI)->primary_expression (pp_c_base (PPI), E)
-#define pp_postfix_expression(PPI, E) \
- pp_c_base (PPI)->postfix_expression (pp_c_base (PPI), E)
-#define pp_unary_expression(PPI, E) \
- pp_c_base (PPI)->unary_expression (pp_c_base (PPI), E)
-#define pp_initializer(PPI, E) \
- pp_c_base (PPI)->initializer (pp_c_base (PPI), E)
-#define pp_multiplicative_expression(PPI, E) \
- pp_c_base (PPI)->multiplicative_expression (pp_c_base (PPI), E)
-#define pp_conditional_expression(PPI, E) \
- pp_c_base (PPI)->conditional_expression (pp_c_base (PPI), E)
-#define pp_assignment_expression(PPI, E) \
- pp_c_base (PPI)->assignment_expression (pp_c_base (PPI), E)
-#define pp_expression(PP, E) \
- pp_c_base (PP)->expression (pp_c_base (PP), E)
-
-
-/* Returns the c_pretty_printer base object of PRETTY-PRINTER. This
- macro must be overridden by any subclass of c_pretty_print_info. */
-#define pp_c_base(PP) (PP)
-
-extern void pp_c_pretty_printer_init (c_pretty_printer *);
+#define pp_type_specifier_seq(PP, D) (PP)->type_specifier_seq (PP, D)
+#define pp_ptr_operator(PP, D) (PP)->ptr_operator (PP, D)
+#define pp_parameter_list(PP, T) (PP)->parameter_list (PP, T)
+
void pp_c_whitespace (c_pretty_printer *);
void pp_c_left_paren (c_pretty_printer *);
void pp_c_right_paren (c_pretty_printer *);
@@ -181,31 +122,14 @@ void pp_c_attributes_display (c_pretty_printer *, tree);
void pp_c_cv_qualifiers (c_pretty_printer *pp, int qualifiers, bool func_type);
void pp_c_type_qualifier_list (c_pretty_printer *, tree);
void pp_c_parameter_type_list (c_pretty_printer *, tree);
-void pp_c_declaration (c_pretty_printer *, tree);
-void pp_c_declaration_specifiers (c_pretty_printer *, tree);
-void pp_c_declarator (c_pretty_printer *, tree);
-void pp_c_direct_declarator (c_pretty_printer *, tree);
void pp_c_specifier_qualifier_list (c_pretty_printer *, tree);
-void pp_c_function_specifier (c_pretty_printer *, tree);
-void pp_c_type_id (c_pretty_printer *, tree);
-void pp_c_direct_abstract_declarator (c_pretty_printer *, tree);
-void pp_c_type_specifier (c_pretty_printer *, tree);
-void pp_c_storage_class_specifier (c_pretty_printer *, tree);
-/* Statements. */
-void pp_c_statement (c_pretty_printer *, tree);
/* Expressions. */
-void pp_c_expression (c_pretty_printer *, tree);
void pp_c_logical_or_expression (c_pretty_printer *, tree);
void pp_c_expression_list (c_pretty_printer *, tree);
void pp_c_constructor_elts (c_pretty_printer *, vec<constructor_elt, va_gc> *);
void pp_c_call_argument_list (c_pretty_printer *, tree);
-void pp_c_unary_expression (c_pretty_printer *, tree);
void pp_c_cast_expression (c_pretty_printer *, tree);
-void pp_c_postfix_expression (c_pretty_printer *, tree);
-void pp_c_primary_expression (c_pretty_printer *, tree);
void pp_c_init_declarator (c_pretty_printer *, tree);
-void pp_c_constant (c_pretty_printer *, tree);
-void pp_c_id_expression (c_pretty_printer *, tree);
void pp_c_ws_string (c_pretty_printer *, const char *);
void pp_c_identifier (c_pretty_printer *, const char *);
void pp_c_string_literal (c_pretty_printer *, tree);
diff --git a/gcc/c-family/c-ubsan.c b/gcc/c-family/c-ubsan.c
new file mode 100644
index 00000000000..9f43f6d55b8
--- /dev/null
+++ b/gcc/c-family/c-ubsan.c
@@ -0,0 +1,158 @@
+/* UndefinedBehaviorSanitizer, undefined behavior detector.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Marek Polacek <polacek@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "alloc-pool.h"
+#include "cgraph.h"
+#include "gimple.h"
+#include "hash-table.h"
+#include "output.h"
+#include "toplev.h"
+#include "ubsan.h"
+#include "c-family/c-common.h"
+#include "c-family/c-ubsan.h"
+
+/* Instrument division by zero and INT_MIN / -1. If not instrumenting,
+ return NULL_TREE. */
+
+tree
+ubsan_instrument_division (location_t loc, tree op0, tree op1)
+{
+ tree t, tt;
+ tree type = TREE_TYPE (op0);
+
+ /* At this point both operands should have the same type,
+ because they are already converted to RESULT_TYPE.
+ Use TYPE_MAIN_VARIANT since typedefs can confuse us. */
+ gcc_assert (TYPE_MAIN_VARIANT (TREE_TYPE (op0))
+ == TYPE_MAIN_VARIANT (TREE_TYPE (op1)));
+
+ /* TODO: REAL_TYPE is not supported yet. */
+ if (TREE_CODE (type) != INTEGER_TYPE)
+ return NULL_TREE;
+
+ /* If we *know* that the divisor is not -1 or 0, we don't have to
+ instrument this expression.
+ ??? We could use decl_constant_value to cover up more cases. */
+ if (TREE_CODE (op1) == INTEGER_CST
+ && integer_nonzerop (op1)
+ && !integer_minus_onep (op1))
+ return NULL_TREE;
+
+ t = fold_build2 (EQ_EXPR, boolean_type_node,
+ op1, build_int_cst (type, 0));
+
+ /* We check INT_MIN / -1 only for signed types. */
+ if (!TYPE_UNSIGNED (type))
+ {
+ tree x;
+ tt = fold_build2 (EQ_EXPR, boolean_type_node, op1,
+ build_int_cst (type, -1));
+ x = fold_build2 (EQ_EXPR, boolean_type_node, op0,
+ TYPE_MIN_VALUE (type));
+ x = fold_build2 (TRUTH_AND_EXPR, boolean_type_node, x, tt);
+ t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t, x);
+ }
+
+ /* In case we have a SAVE_EXPR in a conditional context, we need to
+ make sure it gets evaluated before the condition. */
+ t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
+ tree data = ubsan_create_data ("__ubsan_overflow_data",
+ loc, ubsan_type_descriptor (type),
+ NULL_TREE);
+ data = build_fold_addr_expr_loc (loc, data);
+ tt = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW);
+ tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
+ ubsan_encode_value (op1));
+ t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_zero_node);
+
+ return t;
+}
+
+/* Instrument left and right shifts. If not instrumenting, return
+ NULL_TREE. */
+
+tree
+ubsan_instrument_shift (location_t loc, enum tree_code code,
+ tree op0, tree op1)
+{
+ tree t, tt = NULL_TREE;
+ tree type0 = TREE_TYPE (op0);
+ tree type1 = TREE_TYPE (op1);
+ tree op1_utype = unsigned_type_for (type1);
+ HOST_WIDE_INT op0_prec = TYPE_PRECISION (type0);
+ tree uprecm1 = build_int_cst (op1_utype, op0_prec - 1);
+ tree precm1 = build_int_cst (type1, op0_prec - 1);
+
+ t = fold_convert_loc (loc, op1_utype, op1);
+ t = fold_build2 (GT_EXPR, boolean_type_node, t, uprecm1);
+
+ /* For signed x << y, in C99/C11, the following:
+ (unsigned) x >> (precm1 - y)
+ if non-zero, is undefined. */
+ if (code == LSHIFT_EXPR
+ && !TYPE_UNSIGNED (type0)
+ && flag_isoc99)
+ {
+ tree x = fold_build2 (MINUS_EXPR, integer_type_node, precm1, op1);
+ tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
+ tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
+ tt = fold_build2 (NE_EXPR, boolean_type_node, tt,
+ build_int_cst (TREE_TYPE (tt), 0));
+ }
+
+ /* For signed x << y, in C++11/C++14, the following:
+ x < 0 || ((unsigned) x >> (precm1 - y))
+ if > 1, is undefined. */
+ if (code == LSHIFT_EXPR
+ && !TYPE_UNSIGNED (TREE_TYPE (op0))
+ && (cxx_dialect == cxx11 || cxx_dialect == cxx1y))
+ {
+ tree x = fold_build2 (MINUS_EXPR, integer_type_node, precm1, op1);
+ tt = fold_convert_loc (loc, unsigned_type_for (type0), op0);
+ tt = fold_build2 (RSHIFT_EXPR, TREE_TYPE (tt), tt, x);
+ tt = fold_build2 (GT_EXPR, boolean_type_node, tt,
+ build_int_cst (TREE_TYPE (tt), 1));
+ x = fold_build2 (LT_EXPR, boolean_type_node, op0,
+ build_int_cst (type0, 0));
+ tt = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, x, tt);
+ }
+
+ /* In case we have a SAVE_EXPR in a conditional context, we need to
+ make sure it gets evaluated before the condition. */
+ t = fold_build2 (COMPOUND_EXPR, TREE_TYPE (t), op0, t);
+ tree data = ubsan_create_data ("__ubsan_shift_data",
+ loc, ubsan_type_descriptor (type0),
+ ubsan_type_descriptor (type1), NULL_TREE);
+
+ data = build_fold_addr_expr_loc (loc, data);
+
+ t = fold_build2 (TRUTH_OR_EXPR, boolean_type_node, t,
+ tt ? tt : integer_zero_node);
+ tt = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS);
+ tt = build_call_expr_loc (loc, tt, 3, data, ubsan_encode_value (op0),
+ ubsan_encode_value (op1));
+ t = fold_build3 (COND_EXPR, void_type_node, t, tt, void_zero_node);
+
+ return t;
+}
diff --git a/gcc/c-family/c-ubsan.h b/gcc/c-family/c-ubsan.h
new file mode 100644
index 00000000000..b032b707cc3
--- /dev/null
+++ b/gcc/c-family/c-ubsan.h
@@ -0,0 +1,27 @@
+/* UndefinedBehaviorSanitizer, undefined behavior detector.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Marek Polacek <polacek@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_C_UBSAN_H
+#define GCC_C_UBSAN_H
+
+extern tree ubsan_instrument_division (location_t, tree, tree);
+extern tree ubsan_instrument_shift (location_t, enum tree_code, tree, tree);
+
+#endif /* GCC_C_UBSAN_H */
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index e2df48f93ea..1b4b2977294 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,47 @@
+2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * c-typeck.c (build_binary_op): Use vector_types_compatible_elements_p.
+
+2013-09-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-objc-common.c (c_tree_printer): Tidy.
+
+2013-08-30 Marek Polacek <polacek@redhat.com>
+
+ * c-typeck.c (build_binary_op): Add division by zero and shift
+ instrumentation.
+
+2013-08-26 Joern Rennecke <joern.rennecke@embecosm.com>
+ Joseph Myers <joseph@codesourcery.com>
+
+ PR c/35649
+ * c-typeck.c (c_common_type): Prefer double_type_node over
+ other REAL_TYPE types with the same precision.
+ (convert_arguments): Likewise.
+
+2013-08-23 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-objc-common.c (c_tree_printer): Document the nature of the cast.
+ (c_initialize_diagnostics): Call a destructor for the early printer.
+
+2013-08-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-objc-common.c (c_initialize_diagnostics): Simplify C pretty
+ printer initialization.
+
+2013-08-19 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c/57490
+ * c-array-notation.c (fix_conditional_array_notations_1): Added a
+ check for truth values.
+ (expand_array_notation_exprs): Added truth values case. Removed an
+ unwanted else. Added for-loop to walk through subtrees in default
+ case.
+
+2013-08-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * c-objc-common.c (c_initialize_diagnostics): Don't call pp_base.
+
2013-07-23 Joseph Myers <joseph@codesourcery.com>
* c-parser.c (struct c_generic_association): Fix typo.
diff --git a/gcc/c/c-array-notation.c b/gcc/c/c-array-notation.c
index 7788f7bf145..5747bcb5ca8 100644
--- a/gcc/c/c-array-notation.c
+++ b/gcc/c/c-array-notation.c
@@ -906,6 +906,8 @@ fix_conditional_array_notations_1 (tree stmt)
cond = COND_EXPR_COND (stmt);
else if (TREE_CODE (stmt) == SWITCH_EXPR)
cond = SWITCH_COND (stmt);
+ else if (truth_value_p (TREE_CODE (stmt)))
+ cond = TREE_OPERAND (stmt, 0);
else
/* Otherwise dont even touch the statement. */
return stmt;
@@ -1232,6 +1234,12 @@ expand_array_notation_exprs (tree t)
case BIND_EXPR:
t = expand_array_notation_exprs (BIND_EXPR_BODY (t));
return t;
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_XOR_EXPR:
+ case TRUTH_NOT_EXPR:
case COND_EXPR:
t = fix_conditional_array_notations (t);
@@ -1246,8 +1254,6 @@ expand_array_notation_exprs (tree t)
COND_EXPR_ELSE (t) =
expand_array_notation_exprs (COND_EXPR_ELSE (t));
}
- else
- t = expand_array_notation_exprs (t);
return t;
case STATEMENT_LIST:
{
@@ -1284,6 +1290,10 @@ expand_array_notation_exprs (tree t)
Replace those with just void zero node. */
t = void_zero_node;
default:
+ for (int ii = 0; ii < TREE_CODE_LENGTH (TREE_CODE (t)); ii++)
+ if (contains_array_notation_expr (TREE_OPERAND (t, ii)))
+ TREE_OPERAND (t, ii) =
+ expand_array_notation_exprs (TREE_OPERAND (t, ii));
return t;
}
return t;
diff --git a/gcc/c/c-objc-common.c b/gcc/c/c-objc-common.c
index 8e73856ac18..e6be6ac89fd 100644
--- a/gcc/c/c-objc-common.c
+++ b/gcc/c/c-objc-common.c
@@ -30,6 +30,8 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "c-objc-common.h"
+#include <new> // For placement new.
+
static bool c_tree_printer (pretty_printer *, text_info *, const char *,
int, bool, bool, bool);
@@ -90,6 +92,7 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
{
tree t = NULL_TREE;
tree name;
+ // FIXME: the next cast should be a dynamic_cast, when it is permitted.
c_pretty_printer *cpp = (c_pretty_printer *) pp;
pp->padding = pp_none;
@@ -117,7 +120,7 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
t = DECL_DEBUG_EXPR (t);
if (!DECL_P (t))
{
- pp_c_expression (cpp, t);
+ cpp->expression (t);
return true;
}
}
@@ -140,12 +143,12 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
if (DECL_NAME (name))
pp_identifier (cpp, lang_hooks.decl_printable_name (name, 2));
else
- pp_type_id (cpp, t);
+ cpp->type_id (t);
return true;
}
else
{
- pp_type_id (cpp, t);
+ cpp->type_id (t);
return true;
}
break;
@@ -154,7 +157,7 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
if (TREE_CODE (t) == IDENTIFIER_NODE)
pp_identifier (cpp, IDENTIFIER_POINTER (t));
else
- pp_expression (cpp, t);
+ cpp->expression (t);
return true;
case 'V':
@@ -183,18 +186,14 @@ has_c_linkage (const_tree decl ATTRIBUTE_UNUSED)
void
c_initialize_diagnostics (diagnostic_context *context)
{
- pretty_printer *base;
- c_pretty_printer *pp;
-
c_common_initialize_diagnostics (context);
- base = context->printer;
- pp = XNEW (c_pretty_printer);
- memcpy (pp_base (pp), base, sizeof (pretty_printer));
- pp_c_pretty_printer_init (pp);
- context->printer = (pretty_printer *) pp;
+ pretty_printer *base = context->printer;
+ c_pretty_printer *pp = XNEW (c_pretty_printer);
+ context->printer = new (pp) c_pretty_printer ();
/* It is safe to free this object because it was previously XNEW()'d. */
+ base->~pretty_printer ();
XDELETE (base);
}
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 30871db3623..e52533ecd6d 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see
#include "gimple.h"
#include "c-family/c-objc.h"
#include "c-family/c-common.h"
+#include "c-family/c-ubsan.h"
/* Possible cases of implicit bad conversions. Used to select
diagnostic messages in convert_for_assignment. */
@@ -919,6 +920,13 @@ c_common_type (tree t1, tree t2)
|| TYPE_MAIN_VARIANT (t2) == long_double_type_node)
return long_double_type_node;
+ /* Likewise, prefer double to float even if same size.
+ We got a couple of embedded targets with 32 bit doubles, and the
+ pdp11 might have 64 bit floats. */
+ if (TYPE_MAIN_VARIANT (t1) == double_type_node
+ || TYPE_MAIN_VARIANT (t2) == double_type_node)
+ return double_type_node;
+
/* Otherwise prefer the unsigned one. */
if (TYPE_UNSIGNED (t1))
@@ -3156,7 +3164,9 @@ convert_arguments (tree typelist, vec<tree, va_gc> *values,
}
else if (TREE_CODE (valtype) == REAL_TYPE
&& (TYPE_PRECISION (valtype)
- < TYPE_PRECISION (double_type_node))
+ <= TYPE_PRECISION (double_type_node))
+ && TYPE_MAIN_VARIANT (valtype) != double_type_node
+ && TYPE_MAIN_VARIANT (valtype) != long_double_type_node
&& !DECIMAL_FLOAT_MODE_P (TYPE_MODE (valtype)))
{
if (type_generic)
@@ -9532,6 +9542,15 @@ build_binary_op (location_t location, enum tree_code code,
operands to truth-values. */
bool boolean_op = false;
+ /* Remember whether we're doing / or %. */
+ bool doing_div_or_mod = false;
+
+ /* Remember whether we're doing << or >>. */
+ bool doing_shift = false;
+
+ /* Tree holding instrumentation expression. */
+ tree instrument_expr = NULL;
+
if (location == UNKNOWN_LOCATION)
location = input_location;
@@ -9733,6 +9752,7 @@ build_binary_op (location_t location, enum tree_code code,
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case EXACT_DIV_EXPR:
+ doing_div_or_mod = true;
warn_for_div_by_zero (location, op1);
if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE
@@ -9780,6 +9800,7 @@ build_binary_op (location_t location, enum tree_code code,
case TRUNC_MOD_EXPR:
case FLOOR_MOD_EXPR:
+ doing_div_or_mod = true;
warn_for_div_by_zero (location, op1);
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
@@ -9878,6 +9899,7 @@ build_binary_op (location_t location, enum tree_code code,
else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE)
&& code1 == INTEGER_TYPE)
{
+ doing_shift = true;
if (TREE_CODE (op1) == INTEGER_CST)
{
if (tree_int_cst_sgn (op1) < 0)
@@ -9930,6 +9952,7 @@ build_binary_op (location_t location, enum tree_code code,
else if ((code0 == INTEGER_TYPE || code0 == FIXED_POINT_TYPE)
&& code1 == INTEGER_TYPE)
{
+ doing_shift = true;
if (TREE_CODE (op1) == INTEGER_CST)
{
if (tree_int_cst_sgn (op1) < 0)
@@ -9964,7 +9987,7 @@ build_binary_op (location_t location, enum tree_code code,
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
{
tree intt;
- if (TREE_TYPE (type0) != TREE_TYPE (type1))
+ if (!vector_types_compatible_elements_p (type0, type1))
{
error_at (location, "comparing vectors with different "
"element types");
@@ -10101,7 +10124,7 @@ build_binary_op (location_t location, enum tree_code code,
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
{
tree intt;
- if (TREE_TYPE (type0) != TREE_TYPE (type1))
+ if (!vector_types_compatible_elements_p (type0, type1))
{
error_at (location, "comparing vectors with different "
"element types");
@@ -10207,8 +10230,7 @@ build_binary_op (location_t location, enum tree_code code,
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
&& (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
- || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
- TREE_TYPE (type1))))
+ || !vector_types_compatible_elements_p (type0, type1)))
{
binary_op_error (location, code, type0, type1);
return error_mark_node;
@@ -10474,6 +10496,21 @@ build_binary_op (location_t location, enum tree_code code,
return error_mark_node;
}
+ if (flag_sanitize & SANITIZE_UNDEFINED
+ && current_function_decl != 0
+ && (doing_div_or_mod || doing_shift))
+ {
+ /* OP0 and/or OP1 might have side-effects. */
+ op0 = c_save_expr (op0);
+ op1 = c_save_expr (op1);
+ op0 = c_fully_fold (op0, false, NULL);
+ op1 = c_fully_fold (op1, false, NULL);
+ if (doing_div_or_mod)
+ instrument_expr = ubsan_instrument_division (location, op0, op1);
+ else if (doing_shift)
+ instrument_expr = ubsan_instrument_shift (location, code, op0, op1);
+ }
+
/* Treat expressions in initializers specially as they can't trap. */
if (int_const_or_overflow)
ret = (require_constant_value
@@ -10497,6 +10534,11 @@ build_binary_op (location_t location, enum tree_code code,
if (semantic_result_type)
ret = build1 (EXCESS_PRECISION_EXPR, semantic_result_type, ret);
protected_set_expr_location (ret, location);
+
+ if ((flag_sanitize & SANITIZE_UNDEFINED) && instrument_expr != NULL)
+ ret = fold_build2 (COMPOUND_EXPR, TREE_TYPE (ret),
+ instrument_expr, ret);
+
return ret;
}
diff --git a/gcc/cfg.c b/gcc/cfg.c
index 9c6c939139c..cfada7395db 100644
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -446,6 +446,21 @@ check_bb_profile (basic_block bb, FILE * file, int indent, int flags)
(flags & TDF_COMMENT) ? ";; " : "", s_indent,
(int) lsum, (int) bb->count);
}
+ if (BB_PARTITION (bb) == BB_COLD_PARTITION)
+ {
+ /* Warn about inconsistencies in the partitioning that are
+ currently caused by profile insanities created via optimization. */
+ if (!probably_never_executed_bb_p (fun, bb))
+ fprintf (file, "%s%sBlock in cold partition with hot count\n",
+ (flags & TDF_COMMENT) ? ";; " : "", s_indent);
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ if (!probably_never_executed_edge_p (fun, e))
+ fprintf (file,
+ "%s%sBlock in cold partition with incoming hot edge\n",
+ (flags & TDF_COMMENT) ? ";; " : "", s_indent);
+ }
+ }
}
void
diff --git a/gcc/cfganal.c b/gcc/cfganal.c
index 63d17cede2b..c4ea7dd0a1f 100644
--- a/gcc/cfganal.c
+++ b/gcc/cfganal.c
@@ -340,6 +340,120 @@ verify_edge_list (FILE *f, struct edge_list *elist)
}
}
+
+/* Functions to compute control dependences. */
+
+/* Indicate block BB is control dependent on an edge with index EDGE_INDEX. */
+void
+control_dependences::set_control_dependence_map_bit (basic_block bb,
+ int edge_index)
+{
+ if (bb == ENTRY_BLOCK_PTR)
+ return;
+ gcc_assert (bb != EXIT_BLOCK_PTR);
+ bitmap_set_bit (control_dependence_map[bb->index], edge_index);
+}
+
+/* Clear all control dependences for block BB. */
+void
+control_dependences::clear_control_dependence_bitmap (basic_block bb)
+{
+ bitmap_clear (control_dependence_map[bb->index]);
+}
+
+/* Find the immediate postdominator PDOM of the specified basic block BLOCK.
+ This function is necessary because some blocks have negative numbers. */
+
+static inline basic_block
+find_pdom (basic_block block)
+{
+ gcc_assert (block != ENTRY_BLOCK_PTR);
+
+ if (block == EXIT_BLOCK_PTR)
+ return EXIT_BLOCK_PTR;
+ else
+ {
+ basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block);
+ if (! bb)
+ return EXIT_BLOCK_PTR;
+ return bb;
+ }
+}
+
+/* Determine all blocks' control dependences on the given edge with edge_list
+ EL index EDGE_INDEX, ala Morgan, Section 3.6. */
+
+void
+control_dependences::find_control_dependence (int edge_index)
+{
+ basic_block current_block;
+ basic_block ending_block;
+
+ gcc_assert (INDEX_EDGE_PRED_BB (el, edge_index) != EXIT_BLOCK_PTR);
+
+ if (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR)
+ ending_block = single_succ (ENTRY_BLOCK_PTR);
+ else
+ ending_block = find_pdom (INDEX_EDGE_PRED_BB (el, edge_index));
+
+ for (current_block = INDEX_EDGE_SUCC_BB (el, edge_index);
+ current_block != ending_block && current_block != EXIT_BLOCK_PTR;
+ current_block = find_pdom (current_block))
+ {
+ edge e = INDEX_EDGE (el, edge_index);
+
+ /* For abnormal edges, we don't make current_block control
+ dependent because instructions that throw are always necessary
+ anyway. */
+ if (e->flags & EDGE_ABNORMAL)
+ continue;
+
+ set_control_dependence_map_bit (current_block, edge_index);
+ }
+}
+
+/* Record all blocks' control dependences on all edges in the edge
+ list EL, ala Morgan, Section 3.6. */
+
+control_dependences::control_dependences (struct edge_list *edges)
+ : el (edges)
+{
+ timevar_push (TV_CONTROL_DEPENDENCES);
+ control_dependence_map.create (last_basic_block);
+ for (int i = 0; i < last_basic_block; ++i)
+ control_dependence_map.quick_push (BITMAP_ALLOC (NULL));
+ for (int i = 0; i < NUM_EDGES (el); ++i)
+ find_control_dependence (i);
+ timevar_pop (TV_CONTROL_DEPENDENCES);
+}
+
+/* Free control dependences and the associated edge list. */
+
+control_dependences::~control_dependences ()
+{
+ for (unsigned i = 0; i < control_dependence_map.length (); ++i)
+ BITMAP_FREE (control_dependence_map[i]);
+ control_dependence_map.release ();
+ free_edge_list (el);
+}
+
+/* Returns the bitmap of edges the basic-block I is dependent on. */
+
+bitmap
+control_dependences::get_edges_dependent_on (int i)
+{
+ return control_dependence_map[i];
+}
+
+/* Returns the edge with index I from the edge list. */
+
+edge
+control_dependences::get_edge (int i)
+{
+ return INDEX_EDGE (el, i);
+}
+
+
/* Given PRED and SUCC blocks, return the edge which connects the blocks.
If no such edge exists, return NULL. */
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 99e0baa756e..6836a9e6e84 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -1137,7 +1137,7 @@ old_insns_match_p (int mode ATTRIBUTE_UNUSED, rtx i1, rtx i2)
/* For address sanitizer, never crossjump __asan_report_* builtins,
otherwise errors might be reported on incorrect lines. */
- if (flag_asan)
+ if (flag_sanitize & SANITIZE_ADDRESS)
{
rtx call = get_call_rtx_from (i1);
if (call && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF)
@@ -2807,10 +2807,21 @@ try_optimize_cfg (int mode)
df_analyze ();
}
-#ifdef ENABLE_CHECKING
if (changed)
- verify_flow_info ();
+ {
+ /* Edge forwarding in particular can cause hot blocks previously
+ reached by both hot and cold blocks to become dominated only
+ by cold blocks. This will cause the verification below to fail,
+ and lead to now cold code in the hot section. This is not easy
+ to detect and fix during edge forwarding, and in some cases
+ is only visible after newly unreachable blocks are deleted,
+ which will be done in fixup_partitions. */
+ fixup_partitions ();
+
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
#endif
+ }
changed_overall |= changed;
first_pass = false;
@@ -3040,25 +3051,42 @@ execute_jump (void)
return 0;
}
-struct rtl_opt_pass pass_jump =
+namespace {
+
+const pass_data pass_data_jump =
{
- {
- RTL_PASS,
- "jump", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_jump, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_JUMP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "jump", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_JUMP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+
+class pass_jump : public rtl_opt_pass
+{
+public:
+ pass_jump(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_jump, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_jump (); }
+
+}; // class pass_jump
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_jump (gcc::context *ctxt)
+{
+ return new pass_jump (ctxt);
+}
static unsigned int
execute_jump2 (void)
@@ -3067,22 +3095,39 @@ execute_jump2 (void)
return 0;
}
-struct rtl_opt_pass pass_jump2 =
+namespace {
+
+const pass_data pass_data_jump2 =
{
- {
- RTL_PASS,
- "jump2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_jump2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_JUMP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "jump2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_JUMP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+
+class pass_jump2 : public rtl_opt_pass
+{
+public:
+ pass_jump2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_jump2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_jump2 (); }
+
+}; // class pass_jump2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_jump2 (gcc::context *ctxt)
+{
+ return new pass_jump2 (ctxt);
+}
diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c
index c1872731240..4da5e7ea0cf 100644
--- a/gcc/cfgexpand.c
+++ b/gcc/cfgexpand.c
@@ -764,7 +764,7 @@ partition_stack_vars (void)
sizes, as the shorter vars wouldn't be adequately protected.
Don't do that for "large" (unsupported) alignment objects,
those aren't protected anyway. */
- if (flag_asan && isize != jsize
+ if ((flag_sanitize & SANITIZE_ADDRESS) && isize != jsize
&& ialign * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
break;
@@ -940,7 +940,7 @@ expand_stack_vars (bool (*pred) (size_t), struct stack_vars_data *data)
alignb = stack_vars[i].alignb;
if (alignb * BITS_PER_UNIT <= MAX_SUPPORTED_STACK_ALIGNMENT)
{
- if (flag_asan && pred)
+ if ((flag_sanitize & SANITIZE_ADDRESS) && pred)
{
HOST_WIDE_INT prev_offset = frame_offset;
tree repr_decl = NULL_TREE;
@@ -1110,7 +1110,7 @@ defer_stack_allocation (tree var, bool toplevel)
/* If stack protection is enabled, *all* stack variables must be deferred,
so that we can re-order the strings to the top of the frame.
Similarly for Address Sanitizer. */
- if (flag_stack_protect || flag_asan)
+ if (flag_stack_protect || (flag_sanitize & SANITIZE_ADDRESS))
return true;
/* We handle "large" alignment via dynamic allocation. We want to handle
@@ -1753,7 +1753,7 @@ expand_used_vars (void)
expand_stack_vars (stack_protect_decl_phase_2, &data);
}
- if (flag_asan)
+ if (flag_sanitize & SANITIZE_ADDRESS)
/* Phase 3, any partitions that need asan protection
in addition to phase 1 and 2. */
expand_stack_vars (asan_decl_phase_3, &data);
@@ -4906,25 +4906,42 @@ gimple_expand_cfg (void)
return 0;
}
-struct rtl_opt_pass pass_expand =
+namespace {
+
+const pass_data pass_data_expand =
{
- {
- RTL_PASS,
- "expand", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- gimple_expand_cfg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_EXPAND, /* tv_id */
- PROP_ssa | PROP_gimple_leh | PROP_cfg
+ RTL_PASS, /* type */
+ "expand", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_EXPAND, /* tv_id */
+ ( PROP_ssa | PROP_gimple_leh | PROP_cfg
| PROP_gimple_lcx
- | PROP_gimple_lvec, /* properties_required */
- PROP_rtl, /* properties_provided */
- PROP_ssa | PROP_trees, /* properties_destroyed */
- TODO_verify_ssa | TODO_verify_flow
- | TODO_verify_stmts, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ | PROP_gimple_lvec ), /* properties_required */
+ PROP_rtl, /* properties_provided */
+ ( PROP_ssa | PROP_trees ), /* properties_destroyed */
+ ( TODO_verify_ssa | TODO_verify_flow
+ | TODO_verify_stmts ), /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_expand : public rtl_opt_pass
+{
+public:
+ pass_expand(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_expand, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return gimple_expand_cfg (); }
+
+}; // class pass_expand
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_expand (gcc::context *ctxt)
+{
+ return new pass_expand (ctxt);
+}
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 0f247996630..cd2f527bb47 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -168,6 +168,20 @@ struct GTY ((chain_next ("%h.next"))) loop {
describes what is the state of the estimation. */
enum loop_estimation estimate_state;
+ /* If > 0, an integer, where the user asserted that for any
+ I in [ 0, nb_iterations ) and for any J in
+ [ I, min ( I + safelen, nb_iterations ) ), the Ith and Jth iterations
+ of the loop can be safely evaluated concurrently. */
+ int safelen;
+
+ /* True if we should try harder to vectorize this loop. */
+ bool force_vect;
+
+ /* For SIMD loops, this is a unique identifier of the loop, referenced
+ by IFN_GOMP_SIMD_VF, IFN_GOMP_SIMD_LANE and IFN_GOMP_SIMD_LAST_LANE
+ builtins. */
+ tree simduid;
+
/* Upper bound on number of iterations of a loop. */
struct nb_iter_bound *bounds;
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 36438b8409b..eb6b312d5c8 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -459,26 +459,43 @@ rest_of_pass_free_cfg (void)
return 0;
}
-struct rtl_opt_pass pass_free_cfg =
+namespace {
+
+const pass_data pass_data_free_cfg =
{
- {
- RTL_PASS,
- "*free_cfg", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_pass_free_cfg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- PROP_cfg, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "*free_cfg", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ PROP_cfg, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_free_cfg : public rtl_opt_pass
+{
+public:
+ pass_free_cfg(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_free_cfg, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_pass_free_cfg (); }
+
+}; // class pass_free_cfg
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_free_cfg (gcc::context *ctxt)
+{
+ return new pass_free_cfg (ctxt);
+}
+
/* Return RTX to emit after when we want to emit code on the entry of function. */
rtx
entry_of_function (void)
@@ -1341,6 +1358,43 @@ fixup_partition_crossing (edge e)
}
}
+/* Called when block BB has been reassigned to the cold partition,
+ because it is now dominated by another cold block,
+ to ensure that the region crossing attributes are updated. */
+
+static void
+fixup_new_cold_bb (basic_block bb)
+{
+ edge e;
+ edge_iterator ei;
+
+ /* This is called when a hot bb is found to now be dominated
+ by a cold bb and therefore needs to become cold. Therefore,
+ its preds will no longer be region crossing. Any non-dominating
+ preds that were previously hot would also have become cold
+ in the caller for the same region. Any preds that were previously
+ region-crossing will be adjusted in fixup_partition_crossing. */
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ {
+ fixup_partition_crossing (e);
+ }
+
+ /* Possibly need to make bb's successor edges region crossing,
+ or remove stale region crossing. */
+ FOR_EACH_EDGE (e, ei, bb->succs)
+ {
+ /* We can't have fall-through edges across partition boundaries.
+ Note that force_nonfallthru will do any necessary partition
+ boundary fixup by calling fixup_partition_crossing itself. */
+ if ((e->flags & EDGE_FALLTHRU)
+ && BB_PARTITION (bb) != BB_PARTITION (e->dest)
+ && e->dest != EXIT_BLOCK_PTR)
+ force_nonfallthru (e);
+ else
+ fixup_partition_crossing (e);
+ }
+}
+
/* Attempt to change code to redirect edge E to TARGET. Don't do that on
expense of adding new instructions or reordering basic blocks.
@@ -1979,6 +2033,14 @@ commit_edge_insertions (void)
{
basic_block bb;
+ /* Optimization passes that invoke this routine can cause hot blocks
+ previously reached by both hot and cold blocks to become dominated only
+ by cold blocks. This will cause the verification below to fail,
+ and lead to now cold code in the hot section. In some cases this
+ may only be visible after newly unreachable blocks are deleted,
+ which will be done by fixup_partitions. */
+ fixup_partitions ();
+
#ifdef ENABLE_CHECKING
verify_flow_info ();
#endif
@@ -2173,6 +2235,101 @@ get_last_bb_insn (basic_block bb)
return end;
}
+/* Sanity check partition hotness to ensure that basic blocks in
+   the cold partition don't dominate basic blocks in the hot partition.
+ If FLAG_ONLY is true, report violations as errors. Otherwise
+ re-mark the dominated blocks as cold, since this is run after
+ cfg optimizations that may make hot blocks previously reached
+ by both hot and cold blocks now only reachable along cold paths. */
+
+static vec<basic_block>
+find_partition_fixes (bool flag_only)
+{
+ basic_block bb;
+ vec<basic_block> bbs_in_cold_partition = vNULL;
+ vec<basic_block> bbs_to_fix = vNULL;
+
+ /* Callers check this. */
+ gcc_checking_assert (crtl->has_bb_partition);
+
+ FOR_EACH_BB (bb)
+ if ((BB_PARTITION (bb) == BB_COLD_PARTITION))
+ bbs_in_cold_partition.safe_push (bb);
+
+ if (bbs_in_cold_partition.is_empty ())
+ return vNULL;
+
+ bool dom_calculated_here = !dom_info_available_p (CDI_DOMINATORS);
+
+ if (dom_calculated_here)
+ calculate_dominance_info (CDI_DOMINATORS);
+
+ while (! bbs_in_cold_partition.is_empty ())
+ {
+ bb = bbs_in_cold_partition.pop ();
+ /* Any blocks dominated by a block in the cold section
+ must also be cold. */
+ basic_block son;
+ for (son = first_dom_son (CDI_DOMINATORS, bb);
+ son;
+ son = next_dom_son (CDI_DOMINATORS, son))
+ {
+ /* If son is not yet cold, then mark it cold here and
+ enqueue it for further processing. */
+ if ((BB_PARTITION (son) != BB_COLD_PARTITION))
+ {
+ if (flag_only)
+ error ("non-cold basic block %d dominated "
+ "by a block in the cold partition (%d)", son->index, bb->index);
+ else
+ BB_SET_PARTITION (son, BB_COLD_PARTITION);
+ bbs_to_fix.safe_push (son);
+ bbs_in_cold_partition.safe_push (son);
+ }
+ }
+ }
+
+ if (dom_calculated_here)
+ free_dominance_info (CDI_DOMINATORS);
+
+ return bbs_to_fix;
+}
+
+/* Perform cleanup on the hot/cold bb partitioning after optimization
+ passes that modify the cfg. */
+
+void
+fixup_partitions (void)
+{
+ basic_block bb;
+
+ if (!crtl->has_bb_partition)
+ return;
+
+ /* Delete any blocks that became unreachable and weren't
+ already cleaned up, for example during edge forwarding
+ and convert_jumps_to_returns. This will expose more
+ opportunities for fixing the partition boundaries here.
+ Also, the calculation of the dominance graph during verification
+ will assert if there are unreachable nodes. */
+ delete_unreachable_blocks ();
+
+ /* If there are partitions, do a sanity check on them: A basic block in
+   a cold partition cannot dominate a basic block in a hot partition.
+ Fixup any that now violate this requirement, as a result of edge
+ forwarding and unreachable block deletion.  */
+ vec<basic_block> bbs_to_fix = find_partition_fixes (false);
+
+ /* Do the partition fixup after all necessary blocks have been converted to
+ cold, so that we only update the region crossings the minimum number of
+ places, which can require forcing edges to be non fallthru. */
+ while (! bbs_to_fix.is_empty ())
+ {
+ bb = bbs_to_fix.pop ();
+ fixup_new_cold_bb (bb);
+ }
+}
+
/* Verify, in the basic block chain, that there is at most one switch
between hot/cold partitions. This condition will not be true until
after reorder_basic_blocks is called. */
@@ -2219,7 +2376,8 @@ verify_hot_cold_block_grouping (void)
/* Perform several checks on the edges out of each block, such as
the consistency of the branch probabilities, the correctness
of hot/cold partition crossing edges, and the number of expected
- successor edges. */
+ successor edges. Also verify that the dominance relationship
+ between hot/cold blocks is sane. */
static int
rtl_verify_edges (void)
@@ -2382,6 +2540,14 @@ rtl_verify_edges (void)
}
}
+ /* If there are partitions, do a sanity check on them: A basic block in
+   a cold partition cannot dominate a basic block in a hot partition.  */
+ if (crtl->has_bb_partition && !err)
+ {
+ vec<basic_block> bbs_to_fix = find_partition_fixes (true);
+ err = !bbs_to_fix.is_empty ();
+ }
+
/* Clean up. */
return err;
}
@@ -2515,7 +2681,7 @@ rtl_verify_bb_pointers (void)
and NOTE_INSN_BASIC_BLOCK
- verify that no fall_thru edge crosses hot/cold partition boundaries
- verify that there are no pending RTL branch predictions
- - verify that there is a single hot/cold partition boundary after bbro
+ - verify that hot blocks are not dominated by cold blocks
In future it can be extended check a lot of other stuff as well
(reachability of basic blocks, life information, etc. etc.). */
@@ -2761,7 +2927,8 @@ rtl_verify_bb_layout (void)
- check that all insns are in the basic blocks
(except the switch handling code, barriers and notes)
- check that all returns are followed by barriers
- - check that all fallthru edge points to the adjacent blocks. */
+ - check that all fallthru edge points to the adjacent blocks
+ - verify that there is a single hot/cold partition boundary after bbro */
static int
rtl_verify_flow_info (void)
@@ -3297,45 +3464,79 @@ outof_cfg_layout_mode (void)
return 0;
}
-struct rtl_opt_pass pass_into_cfg_layout_mode =
+namespace {
+
+const pass_data pass_data_into_cfg_layout_mode =
{
- {
- RTL_PASS,
- "into_cfglayout", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- into_cfg_layout_mode, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CFG, /* tv_id */
- 0, /* properties_required */
- PROP_cfglayout, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "into_cfglayout", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_CFG, /* tv_id */
+ 0, /* properties_required */
+ PROP_cfglayout, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
-struct rtl_opt_pass pass_outof_cfg_layout_mode =
+class pass_into_cfg_layout_mode : public rtl_opt_pass
+{
+public:
+ pass_into_cfg_layout_mode(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_into_cfg_layout_mode, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return into_cfg_layout_mode (); }
+
+}; // class pass_into_cfg_layout_mode
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_into_cfg_layout_mode (gcc::context *ctxt)
{
- {
- RTL_PASS,
- "outof_cfglayout", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- outof_cfg_layout_mode, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CFG, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- PROP_cfglayout, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ return new pass_into_cfg_layout_mode (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_outof_cfg_layout_mode =
+{
+ RTL_PASS, /* type */
+ "outof_cfglayout", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_CFG, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ PROP_cfglayout, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_outof_cfg_layout_mode : public rtl_opt_pass
+{
+public:
+ pass_outof_cfg_layout_mode(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_outof_cfg_layout_mode, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return outof_cfg_layout_mode (); }
+
+}; // class pass_outof_cfg_layout_mode
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_outof_cfg_layout_mode (gcc::context *ctxt)
+{
+ return new pass_outof_cfg_layout_mode (ctxt);
+}
/* Link the basic blocks in the correct order, compacting the basic
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index be3411d6a07..f12bf1ba4be 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -674,14 +674,38 @@ edge_eq (const void *x, const void *y)
/* Add call graph edge E to call site hash of its caller. */
static inline void
+cgraph_update_edge_in_call_site_hash (struct cgraph_edge *e)
+{
+ void **slot;
+ slot = htab_find_slot_with_hash (e->caller->call_site_hash,
+ e->call_stmt,
+ htab_hash_pointer (e->call_stmt),
+ INSERT);
+ *slot = e;
+}
+
+/* Add call graph edge E to call site hash of its caller. */
+
+static inline void
cgraph_add_edge_to_call_site_hash (struct cgraph_edge *e)
{
void **slot;
+ /* There are two speculative edges for every statement (one direct,
+ one indirect); always hash the direct one. */
+ if (e->speculative && e->indirect_unknown_callee)
+ return;
slot = htab_find_slot_with_hash (e->caller->call_site_hash,
e->call_stmt,
htab_hash_pointer (e->call_stmt),
INSERT);
- gcc_assert (!*slot);
+ if (*slot)
+ {
+ gcc_assert (((struct cgraph_edge *)*slot)->speculative);
+ if (e->callee)
+ *slot = e;
+ return;
+ }
+ gcc_assert (!*slot || e->speculative);
*slot = e;
}
@@ -732,14 +756,33 @@ cgraph_edge (struct cgraph_node *node, gimple call_stmt)
}
-/* Change field call_stmt of edge E to NEW_STMT. */
+/* Change field call_stmt of edge E to NEW_STMT.
+ If UPDATE_SPECULATIVE and E is any component of speculative
+ edge, then update all components. */
void
-cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt)
+cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt,
+ bool update_speculative)
{
tree decl;
- if (e->caller->call_site_hash)
+ /* Speculative edges has three component, update all of them
+ when asked to. */
+ if (update_speculative && e->speculative)
+ {
+ struct cgraph_edge *direct, *indirect;
+ struct ipa_ref *ref;
+
+ cgraph_speculative_call_info (e, direct, indirect, ref);
+ cgraph_set_call_stmt (direct, new_stmt, false);
+ cgraph_set_call_stmt (indirect, new_stmt, false);
+ ref->stmt = new_stmt;
+ return;
+ }
+
+ /* Only direct speculative edges go to call_site_hash. */
+ if (e->caller->call_site_hash
+ && (!e->speculative || !e->indirect_unknown_callee))
{
htab_remove_elt_with_hash (e->caller->call_site_hash,
e->call_stmt,
@@ -755,7 +798,7 @@ cgraph_set_call_stmt (struct cgraph_edge *e, gimple new_stmt)
struct cgraph_node *new_callee = cgraph_get_node (decl);
gcc_checking_assert (new_callee);
- cgraph_make_edge_direct (e, new_callee);
+ e = cgraph_make_edge_direct (e, new_callee);
}
push_cfun (DECL_STRUCT_FUNCTION (e->caller->symbol.decl));
@@ -781,7 +824,10 @@ cgraph_create_edge_1 (struct cgraph_node *caller, struct cgraph_node *callee,
{
/* This is a rather expensive check possibly triggering
construction of call stmt hashtable. */
- gcc_checking_assert (!cgraph_edge (caller, call_stmt));
+#ifdef ENABLE_CHECKING
+ struct cgraph_edge *e;
+ gcc_checking_assert (!(e=cgraph_edge (caller, call_stmt)) || e->speculative);
+#endif
gcc_assert (is_gimple_call (call_stmt));
}
@@ -804,6 +850,7 @@ cgraph_create_edge_1 (struct cgraph_node *caller, struct cgraph_node *callee,
edge->next_caller = NULL;
edge->prev_callee = NULL;
edge->next_callee = NULL;
+ edge->lto_stmt_uid = 0;
edge->count = count;
gcc_assert (count >= 0);
@@ -828,6 +875,7 @@ cgraph_create_edge_1 (struct cgraph_node *caller, struct cgraph_node *callee,
edge->indirect_info = NULL;
edge->indirect_inlining_edge = 0;
+ edge->speculative = false;
return edge;
}
@@ -879,6 +927,7 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
{
struct cgraph_edge *edge = cgraph_create_edge_1 (caller, NULL, call_stmt,
count, freq);
+ tree target;
edge->indirect_unknown_callee = 1;
initialize_inline_failed (edge);
@@ -886,6 +935,23 @@ cgraph_create_indirect_edge (struct cgraph_node *caller, gimple call_stmt,
edge->indirect_info = cgraph_allocate_init_indirect_info ();
edge->indirect_info->ecf_flags = ecf_flags;
+ /* Record polymorphic call info. */
+ if (call_stmt
+ && (target = gimple_call_fn (call_stmt))
+ && virtual_method_call_p (target))
+ {
+ tree type = obj_type_ref_class (target);
+
+
+ /* Only record types can have virtual calls. */
+ gcc_assert (TREE_CODE (type) == RECORD_TYPE);
+ edge->indirect_info->param_index = -1;
+ edge->indirect_info->otr_token
+ = tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1);
+ edge->indirect_info->otr_type = type;
+ edge->indirect_info->polymorphic = 1;
+ }
+
edge->next_callee = caller->indirect_calls;
if (caller->indirect_calls)
caller->indirect_calls->prev_callee = edge;
@@ -937,6 +1003,9 @@ cgraph_free_edge (struct cgraph_edge *e)
{
int uid = e->uid;
+ if (e->indirect_info)
+ ggc_free (e->indirect_info);
+
/* Clear out the edge so we do not dangle pointers. */
memset (e, 0, sizeof (*e));
e->uid = uid;
@@ -977,6 +1046,123 @@ cgraph_set_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
e->callee = n;
}
+/* Turn edge E into speculative call calling N2. Update
+ the profile so the direct call is taken COUNT times
+ with FREQUENCY.
+
+ At clone materialization time, the indirect call E will
+ be expanded as:
+
+ if (call_dest == N2)
+ n2 ();
+ else
+ call call_dest
+
+ At this time the function just creates the direct call,
+ the referencd representing the if conditional and attaches
+ them all to the orginal indirect call statement.
+
+ Return direct edge created. */
+
+struct cgraph_edge *
+cgraph_turn_edge_to_speculative (struct cgraph_edge *e,
+ struct cgraph_node *n2,
+ gcov_type direct_count,
+ int direct_frequency)
+{
+ struct cgraph_node *n = e->caller;
+ struct ipa_ref *ref;
+ struct cgraph_edge *e2;
+
+ if (dump_file)
+ {
+ fprintf (dump_file, "Indirect call -> speculative call"
+ " %s/%i => %s/%i\n",
+ xstrdup (cgraph_node_name (n)), n->symbol.order,
+ xstrdup (cgraph_node_name (n2)), n2->symbol.order);
+ }
+ e->speculative = true;
+ e2 = cgraph_create_edge (n, n2, e->call_stmt, direct_count, direct_frequency);
+ initialize_inline_failed (e2);
+ e2->speculative = true;
+ if (TREE_NOTHROW (n2->symbol.decl))
+ e2->can_throw_external = false;
+ else
+ e2->can_throw_external = e->can_throw_external;
+ e2->lto_stmt_uid = e->lto_stmt_uid;
+ e->count -= e2->count;
+ e->frequency -= e2->frequency;
+ cgraph_call_edge_duplication_hooks (e, e2);
+ ref = ipa_record_reference ((symtab_node)n, (symtab_node)n2,
+ IPA_REF_ADDR, e->call_stmt);
+ ref->lto_stmt_uid = e->lto_stmt_uid;
+ ref->speculative = e->speculative;
+ cgraph_mark_address_taken_node (n2);
+ return e2;
+}
+
+/* Speculative call consist of three components:
+ 1) an indirect edge representing the original call
+ 2) an direct edge representing the new call
+ 3) ADDR_EXPR reference representing the speculative check.
+ All three components are attached to single statement (the indirect
+ call) and if one of them exists, all of them must exist.
+
+ Given speculative call edge E, return all three components.
+ */
+
+void
+cgraph_speculative_call_info (struct cgraph_edge *e,
+ struct cgraph_edge *&direct,
+ struct cgraph_edge *&indirect,
+ struct ipa_ref *&reference)
+{
+ struct ipa_ref *ref;
+ int i;
+ struct cgraph_edge *e2;
+
+ if (!e->indirect_unknown_callee)
+ for (e2 = e->caller->indirect_calls;
+ e2->call_stmt != e->call_stmt || e2->lto_stmt_uid != e->lto_stmt_uid;
+ e2 = e2->next_callee)
+ ;
+ else
+ {
+ e2 = e;
+ /* We can take advantage of the call stmt hash. */
+ if (e2->call_stmt)
+ {
+ e = cgraph_edge (e->caller, e2->call_stmt);
+ gcc_assert (e->speculative && !e->indirect_unknown_callee);
+ }
+ else
+ for (e = e->caller->callees;
+ e2->call_stmt != e->call_stmt
+ || e2->lto_stmt_uid != e->lto_stmt_uid;
+ e = e->next_callee)
+ ;
+ }
+ gcc_assert (e->speculative && e2->speculative);
+ direct = e;
+ indirect = e2;
+
+ reference = NULL;
+ for (i = 0; ipa_ref_list_reference_iterate (&e->caller->symbol.ref_list,
+ i, ref); i++)
+ if (ref->speculative
+ && ((ref->stmt && ref->stmt == e->call_stmt)
+ || (!ref->stmt && ref->lto_stmt_uid == e->lto_stmt_uid)))
+ {
+ reference = ref;
+ break;
+ }
+
+ /* Speculative edge always consist of all three components - direct edge,
+ indirect and reference. */
+
+ gcc_assert (e && e2 && ref);
+}
+
/* Redirect callee of E to N. The function does not update underlying
call expression. */
@@ -990,14 +1176,87 @@ cgraph_redirect_edge_callee (struct cgraph_edge *e, struct cgraph_node *n)
cgraph_set_edge_callee (e, n);
}
+/* Speculative call EDGE turned out to be direct call to CALLE_DECL.
+ Remove the speculative call sequence and return edge representing the call.
+ It is up to caller to redirect the call as appropriate. */
+
+struct cgraph_edge *
+cgraph_resolve_speculation (struct cgraph_edge *edge, tree callee_decl)
+{
+ struct cgraph_edge *e2;
+ struct ipa_ref *ref;
+
+ gcc_assert (edge->speculative);
+ cgraph_speculative_call_info (edge, e2, edge, ref);
+ if (ref->referred->symbol.decl != callee_decl)
+ {
+ if (dump_file)
+ {
+ if (callee_decl)
+ {
+ fprintf (dump_file, "Speculative indirect call %s/%i => %s/%i has "
+ "turned out to have contradicting known target ",
+ xstrdup (cgraph_node_name (edge->caller)), edge->caller->symbol.order,
+ xstrdup (cgraph_node_name (e2->callee)), e2->callee->symbol.order);
+ print_generic_expr (dump_file, callee_decl, 0);
+ fprintf (dump_file, "\n");
+ }
+ else
+ {
+ fprintf (dump_file, "Removing speculative call %s/%i => %s/%i\n",
+ xstrdup (cgraph_node_name (edge->caller)), edge->caller->symbol.order,
+ xstrdup (cgraph_node_name (e2->callee)), e2->callee->symbol.order);
+ }
+ }
+ }
+ else
+ {
+ struct cgraph_edge *tmp = edge;
+ if (dump_file)
+ fprintf (dump_file, "Speculative call turned into direct call.\n");
+ edge = e2;
+ e2 = tmp;
+ /* FIXME: If EDGE is inlined, we should scale up the frequencies and counts
+ in the functions inlined through it. */
+ }
+ edge->count += e2->count;
+ edge->frequency += e2->frequency;
+ if (edge->frequency > CGRAPH_FREQ_MAX)
+ edge->frequency = CGRAPH_FREQ_MAX;
+ edge->speculative = false;
+ e2->speculative = false;
+ ipa_remove_reference (ref);
+ if (e2->indirect_unknown_callee || e2->inline_failed)
+ cgraph_remove_edge (e2);
+ else
+ cgraph_remove_node_and_inline_clones (e2->callee, NULL);
+ if (edge->caller->call_site_hash)
+ cgraph_update_edge_in_call_site_hash (edge);
+ return edge;
+}
+
/* Make an indirect EDGE with an unknown callee an ordinary edge leading to
CALLEE. DELTA is an integer constant that is to be added to the this
pointer (first parameter) to compensate for skipping a thunk adjustment. */
-void
+struct cgraph_edge *
cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee)
{
+ gcc_assert (edge->indirect_unknown_callee);
+
+ /* If we are redirecting speculative call, make it non-speculative. */
+ if (edge->indirect_unknown_callee && edge->speculative)
+ {
+ edge = cgraph_resolve_speculation (edge, callee->symbol.decl);
+
+ /* On successful speculation just return the pre existing direct edge. */
+ if (!edge->indirect_unknown_callee)
+ return edge;
+ }
+
edge->indirect_unknown_callee = 0;
+ ggc_free (edge->indirect_info);
+ edge->indirect_info = NULL;
/* Get the edge out of the indirect edge list. */
if (edge->prev_callee)
@@ -1024,6 +1283,7 @@ cgraph_make_edge_direct (struct cgraph_edge *edge, struct cgraph_node *callee)
/* We need to re-determine the inlining status of the edge. */
initialize_inline_failed (edge);
+ return edge;
}
/* If necessary, change the function declaration in the call statement
@@ -1039,6 +1299,82 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
struct cgraph_node *node;
#endif
+ if (e->speculative)
+ {
+ struct cgraph_edge *e2;
+ gimple new_stmt;
+ struct ipa_ref *ref;
+
+ cgraph_speculative_call_info (e, e, e2, ref);
+ /* If there already is an direct call (i.e. as a result of inliner's
+ substitution), forget about speculating. */
+ if (decl)
+ e = cgraph_resolve_speculation (e, decl);
+ /* If types do not match, speculation was likely wrong.
+ The direct edge was posisbly redirected to the clone with a different
+ signature. We did not update the call statement yet, so compare it
+ with the reference that still points to the proper type. */
+ else if (!gimple_check_call_matching_types (e->call_stmt,
+ ref->referred->symbol.decl,
+ true))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Not expanding speculative call of %s/%i -> %s/%i\n"
+ "Type mismatch.\n",
+ xstrdup (cgraph_node_name (e->caller)),
+ e->caller->symbol.order,
+ xstrdup (cgraph_node_name (e->callee)),
+ e->callee->symbol.order);
+ e = cgraph_resolve_speculation (e, NULL);
+ /* We are producing the final function body and will throw away the
+ callgraph edges really soon. Reset the counts/frequencies to
+ keep verifier happy in the case of roundoff errors. */
+ e->count = gimple_bb (e->call_stmt)->count;
+ e->frequency = compute_call_stmt_bb_frequency
+ (e->caller->symbol.decl, gimple_bb (e->call_stmt));
+ }
+ /* Expand speculation into GIMPLE code. */
+ else
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Expanding speculative call of %s/%i -> %s/%i count:"
+ HOST_WIDEST_INT_PRINT_DEC"\n",
+ xstrdup (cgraph_node_name (e->caller)),
+ e->caller->symbol.order,
+ xstrdup (cgraph_node_name (e->callee)),
+ e->callee->symbol.order,
+ (HOST_WIDEST_INT)e->count);
+ gcc_assert (e2->speculative);
+ push_cfun (DECL_STRUCT_FUNCTION (e->caller->symbol.decl));
+ new_stmt = gimple_ic (e->call_stmt, cgraph (ref->referred),
+ e->count || e2->count
+ ? RDIV (e->count * REG_BR_PROB_BASE,
+ e->count + e2->count)
+ : e->frequency || e2->frequency
+ ? RDIV (e->frequency * REG_BR_PROB_BASE,
+ e->frequency + e2->frequency)
+ : REG_BR_PROB_BASE / 2,
+ e->count, e->count + e2->count);
+ e->speculative = false;
+ cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt,
+ new_stmt, false);
+ e->frequency = compute_call_stmt_bb_frequency
+ (e->caller->symbol.decl, gimple_bb (e->call_stmt));
+ e2->frequency = compute_call_stmt_bb_frequency
+ (e2->caller->symbol.decl, gimple_bb (e2->call_stmt));
+ e2->speculative = false;
+ ref->speculative = false;
+ ref->stmt = NULL;
+ /* Indirect edges are not both in the call site hash.
+ get it updated. */
+ if (e->caller->call_site_hash)
+ cgraph_update_edge_in_call_site_hash (e2);
+ pop_cfun ();
+ /* Continue redirecting E to proper target. */
+ }
+ }
+
if (e->indirect_unknown_callee
|| decl == e->callee->symbol.decl)
return e->call_stmt;
@@ -1099,7 +1435,7 @@ cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
update_stmt (new_stmt);
}
- cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
+ cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt, false);
if (cgraph_dump_file)
{
@@ -1316,7 +1652,7 @@ void
cgraph_release_function_body (struct cgraph_node *node)
{
node->ipa_transforms_to_apply.release ();
- if (!node->abstract_and_needed && cgraph_state != CGRAPH_STATE_PARSING)
+ if (!node->used_as_abstract_origin && cgraph_state != CGRAPH_STATE_PARSING)
{
DECL_RESULT (node->symbol.decl) = NULL;
DECL_ARGUMENTS (node->symbol.decl) = NULL;
@@ -1324,9 +1660,11 @@ cgraph_release_function_body (struct cgraph_node *node)
/* If the node is abstract and needed, then do not clear DECL_INITIAL
of its associated function function declaration because it's
needed to emit debug info later. */
- if (!node->abstract_and_needed && DECL_INITIAL (node->symbol.decl))
+ if (!node->used_as_abstract_origin && DECL_INITIAL (node->symbol.decl))
DECL_INITIAL (node->symbol.decl) = error_mark_node;
release_function_body (node->symbol.decl);
+ if (node->symbol.lto_file_data)
+ lto_free_function_in_decl_state_for_node ((symtab_node) node);
}
/* Remove the node from cgraph. */
@@ -1544,6 +1882,9 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " Availability: %s\n",
cgraph_availability_names [cgraph_function_body_availability (node)]);
+ if (node->profile_id)
+ fprintf (f, " Profile id: %i\n",
+ node->profile_id);
fprintf (f, " Function flags:");
if (node->count)
fprintf (f, " executed "HOST_WIDEST_INT_PRINT_DEC"x",
@@ -1603,6 +1944,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
if (edge->frequency)
fprintf (f, "(%.2f per call) ",
edge->frequency / (double)CGRAPH_FREQ_BASE);
+ if (edge->speculative)
+ fprintf(f, "(speculative) ");
if (!edge->inline_failed)
fprintf(f, "(inlined) ");
if (edge->indirect_inlining_edge)
@@ -1616,6 +1959,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
{
fprintf (f, "%s/%i ", cgraph_node_asm_name (edge->callee),
edge->callee->symbol.order);
+ if (edge->speculative)
+ fprintf(f, "(speculative) ");
if (!edge->inline_failed)
fprintf(f, "(inlined) ");
if (edge->indirect_inlining_edge)
@@ -1697,11 +2042,12 @@ enum availability
cgraph_function_body_availability (struct cgraph_node *node)
{
enum availability avail;
- gcc_assert (cgraph_function_flags_ready);
if (!node->symbol.analyzed)
avail = AVAIL_NOT_AVAILABLE;
else if (node->local.local)
avail = AVAIL_LOCAL;
+ else if (node->symbol.alias && node->symbol.weakref)
+ cgraph_function_or_thunk_node (node, &avail);
else if (!node->symbol.externally_visible)
avail = AVAIL_AVAILABLE;
/* Inline functions are safe to be analyzed even if their symbol can
@@ -1933,128 +2279,6 @@ cgraph_set_pure_flag (struct cgraph_node *node, bool pure, bool looping)
false);
}
-/* Data used by cgraph_propagate_frequency. */
-
-struct cgraph_propagate_frequency_data
-{
- bool maybe_unlikely_executed;
- bool maybe_executed_once;
- bool only_called_at_startup;
- bool only_called_at_exit;
-};
-
-/* Worker for cgraph_propagate_frequency_1. */
-
-static bool
-cgraph_propagate_frequency_1 (struct cgraph_node *node, void *data)
-{
- struct cgraph_propagate_frequency_data *d;
- struct cgraph_edge *edge;
-
- d = (struct cgraph_propagate_frequency_data *)data;
- for (edge = node->callers;
- edge && (d->maybe_unlikely_executed || d->maybe_executed_once
- || d->only_called_at_startup || d->only_called_at_exit);
- edge = edge->next_caller)
- {
- if (edge->caller != node)
- {
- d->only_called_at_startup &= edge->caller->only_called_at_startup;
- /* It makes sense to put main() together with the static constructors.
- It will be executed for sure, but rest of functions called from
- main are definitely not at startup only. */
- if (MAIN_NAME_P (DECL_NAME (edge->caller->symbol.decl)))
- d->only_called_at_startup = 0;
- d->only_called_at_exit &= edge->caller->only_called_at_exit;
- }
- if (!edge->frequency)
- continue;
- switch (edge->caller->frequency)
- {
- case NODE_FREQUENCY_UNLIKELY_EXECUTED:
- break;
- case NODE_FREQUENCY_EXECUTED_ONCE:
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " Called by %s that is executed once\n",
- cgraph_node_name (edge->caller));
- d->maybe_unlikely_executed = false;
- if (inline_edge_summary (edge)->loop_depth)
- {
- d->maybe_executed_once = false;
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " Called in loop\n");
- }
- break;
- case NODE_FREQUENCY_HOT:
- case NODE_FREQUENCY_NORMAL:
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, " Called by %s that is normal or hot\n",
- cgraph_node_name (edge->caller));
- d->maybe_unlikely_executed = false;
- d->maybe_executed_once = false;
- break;
- }
- }
- return edge != NULL;
-}
-
-/* See if the frequency of NODE can be updated based on frequencies of its
- callers. */
-bool
-cgraph_propagate_frequency (struct cgraph_node *node)
-{
- struct cgraph_propagate_frequency_data d = {true, true, true, true};
- bool changed = false;
-
- if (!node->local.local)
- return false;
- gcc_assert (node->symbol.analyzed);
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Processing frequency %s\n", cgraph_node_name (node));
-
- cgraph_for_node_and_aliases (node, cgraph_propagate_frequency_1, &d, true);
-
- if ((d.only_called_at_startup && !d.only_called_at_exit)
- && !node->only_called_at_startup)
- {
- node->only_called_at_startup = true;
- if (dump_file)
- fprintf (dump_file, "Node %s promoted to only called at startup.\n",
- cgraph_node_name (node));
- changed = true;
- }
- if ((d.only_called_at_exit && !d.only_called_at_startup)
- && !node->only_called_at_exit)
- {
- node->only_called_at_exit = true;
- if (dump_file)
- fprintf (dump_file, "Node %s promoted to only called at exit.\n",
- cgraph_node_name (node));
- changed = true;
- }
- /* These come either from profile or user hints; never update them. */
- if (node->frequency == NODE_FREQUENCY_HOT
- || node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
- return changed;
- if (d.maybe_unlikely_executed)
- {
- node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
- if (dump_file)
- fprintf (dump_file, "Node %s promoted to unlikely executed.\n",
- cgraph_node_name (node));
- changed = true;
- }
- else if (d.maybe_executed_once && node->frequency != NODE_FREQUENCY_EXECUTED_ONCE)
- {
- node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
- if (dump_file)
- fprintf (dump_file, "Node %s promoted to executed once.\n",
- cgraph_node_name (node));
- changed = true;
- }
- return changed;
-}
-
/* Return true when NODE can not return or throw and thus
it is safe to ignore its side effects for IPA analysis. */
@@ -2263,6 +2487,7 @@ verify_edge_count_and_frequency (struct cgraph_edge *e)
}
if (gimple_has_body_p (e->caller->symbol.decl)
&& !e->caller->global.inlined_to
+ && !e->speculative
/* FIXME: Inline-analysis sets frequency to 0 when edge is optimized out.
Remove this once edges are actually removed from the function at that time. */
&& (e->frequency
@@ -2317,7 +2542,7 @@ verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
/* We do not know if a node from a different partition is an alias or what it
aliases and therefore cannot do the former_clone_of check reliably. */
- if (!node || node->symbol.in_other_partition)
+ if (!node || node->symbol.in_other_partition || e->callee->symbol.in_other_partition)
return false;
node = cgraph_function_or_thunk_node (node, NULL);
@@ -2364,7 +2589,7 @@ verify_cgraph_node (struct cgraph_node *node)
error ("inline clone in same comdat group list");
error_found = true;
}
- if (!node->symbol.definition && node->local.local)
+ if (!node->symbol.definition && !node->symbol.in_other_partition && node->local.local)
{
error ("local symbols must be defined");
error_found = true;
@@ -2538,55 +2763,75 @@ verify_cgraph_node (struct cgraph_node *node)
{
if (this_cfun->cfg)
{
+ pointer_set_t *stmts = pointer_set_create ();
+ int i;
+ struct ipa_ref *ref;
+
/* Reach the trees by walking over the CFG, and note the
enclosing basic-blocks in the call edges. */
FOR_EACH_BB_FN (this_block, this_cfun)
- for (gsi = gsi_start_bb (this_block);
- !gsi_end_p (gsi);
- gsi_next (&gsi))
- {
- gimple stmt = gsi_stmt (gsi);
- if (is_gimple_call (stmt))
- {
- struct cgraph_edge *e = cgraph_edge (node, stmt);
- tree decl = gimple_call_fndecl (stmt);
- if (e)
- {
- if (e->aux)
- {
- error ("shared call_stmt:");
- cgraph_debug_gimple_stmt (this_cfun, stmt);
- error_found = true;
- }
- if (!e->indirect_unknown_callee)
- {
- if (verify_edge_corresponds_to_fndecl (e, decl))
- {
- error ("edge points to wrong declaration:");
- debug_tree (e->callee->symbol.decl);
- fprintf (stderr," Instead of:");
- debug_tree (decl);
- error_found = true;
- }
- }
- else if (decl)
- {
- error ("an indirect edge with unknown callee "
- "corresponding to a call_stmt with "
- "a known declaration:");
- error_found = true;
- cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
- }
- e->aux = (void *)1;
- }
- else if (decl)
- {
- error ("missing callgraph edge for call stmt:");
- cgraph_debug_gimple_stmt (this_cfun, stmt);
- error_found = true;
- }
- }
+ {
+ for (gsi = gsi_start_phis (this_block);
+ !gsi_end_p (gsi); gsi_next (&gsi))
+ pointer_set_insert (stmts, gsi_stmt (gsi));
+ for (gsi = gsi_start_bb (this_block);
+ !gsi_end_p (gsi);
+ gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ pointer_set_insert (stmts, stmt);
+ if (is_gimple_call (stmt))
+ {
+ struct cgraph_edge *e = cgraph_edge (node, stmt);
+ tree decl = gimple_call_fndecl (stmt);
+ if (e)
+ {
+ if (e->aux)
+ {
+ error ("shared call_stmt:");
+ cgraph_debug_gimple_stmt (this_cfun, stmt);
+ error_found = true;
+ }
+ if (!e->indirect_unknown_callee)
+ {
+ if (verify_edge_corresponds_to_fndecl (e, decl))
+ {
+ error ("edge points to wrong declaration:");
+ debug_tree (e->callee->symbol.decl);
+ fprintf (stderr," Instead of:");
+ debug_tree (decl);
+ error_found = true;
+ }
+ }
+ else if (decl)
+ {
+ error ("an indirect edge with unknown callee "
+ "corresponding to a call_stmt with "
+ "a known declaration:");
+ error_found = true;
+ cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
+ }
+ e->aux = (void *)1;
+ }
+ else if (decl)
+ {
+ error ("missing callgraph edge for call stmt:");
+ cgraph_debug_gimple_stmt (this_cfun, stmt);
+ error_found = true;
+ }
+ }
+ }
}
+ for (i = 0;
+ ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref);
+ i++)
+ if (ref->stmt && !pointer_set_contains (stmts, ref->stmt))
+ {
+ error ("reference to dead statement");
+ cgraph_debug_gimple_stmt (this_cfun, ref->stmt);
+ error_found = true;
+ }
+ pointer_set_destroy (stmts);
}
else
/* No CFG available?! */
@@ -2606,7 +2851,7 @@ verify_cgraph_node (struct cgraph_node *node)
}
for (e = node->indirect_calls; e; e = e->next_callee)
{
- if (!e->aux)
+ if (!e->aux && !e->speculative)
{
error ("an indirect edge from %s has no corresponding call_stmt",
identifier_to_locale (cgraph_node_name (e->caller)));
@@ -2708,4 +2953,45 @@ cgraph_function_node (struct cgraph_node *node, enum availability *availability)
return node;
}
+/* When doing LTO, read NODE's body from disk if it is not already present. */
+
+bool
+cgraph_get_body (struct cgraph_node *node)
+{
+ struct lto_file_decl_data *file_data;
+ const char *data, *name;
+ size_t len;
+ tree decl = node->symbol.decl;
+
+ if (DECL_RESULT (decl))
+ return false;
+
+ gcc_assert (in_lto_p);
+
+ file_data = node->symbol.lto_file_data;
+ name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
+
+ /* We may have renamed the declaration, e.g., a static function. */
+ name = lto_get_decl_name_mapping (file_data, name);
+
+ data = lto_get_section_data (file_data, LTO_section_function_body,
+ name, &len);
+ if (!data)
+ {
+ dump_cgraph_node (stderr, node);
+ fatal_error ("%s: section %s is missing",
+ file_data->file_name,
+ name);
+ }
+
+ gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
+
+ lto_input_function_body (file_data, node, data);
+ lto_stats.num_function_bodies++;
+ lto_free_section_data (file_data, LTO_section_function_body, name,
+ data, len);
+ lto_free_function_in_decl_state_for_node ((symtab_node) node);
+ return true;
+}
+
#include "gt-cgraph.h"
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 3d6f3876f9c..a6a0a2438f7 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -300,10 +300,12 @@ struct GTY(()) cgraph_node {
int count_materialization_scale;
/* Unique id of the node. */
int uid;
+ /* ID assigned by the profiling. */
+ unsigned int profile_id;
/* Set when decl is an abstract function pointed to by the
ABSTRACT_DECL_ORIGIN of a reachable function. */
- unsigned abstract_and_needed : 1;
+ unsigned used_as_abstract_origin : 1;
/* Set once the function is lowered (i.e. its CFG is built). */
unsigned lowered : 1;
/* Set once the function has been instantiated and its callee
@@ -433,6 +435,10 @@ struct GTY(()) cgraph_indirect_call_info
int param_index;
/* ECF flags determined from the caller. */
int ecf_flags;
+ /* Profile_id of common target obtrained from profile. */
+ int common_target_id;
+ /* Probability that call will land in function with COMMON_TARGET_ID. */
+ int common_target_probability;
/* Set when the call is a virtual call with the parameter being the
associated object pointer rather than a simple direct call. */
@@ -483,6 +489,24 @@ struct GTY((chain_next ("%h.next_caller"), chain_prev ("%h.prev_caller"))) cgrap
unsigned int call_stmt_cannot_inline_p : 1;
/* Can this call throw externally? */
unsigned int can_throw_external : 1;
+ /* Edges with SPECULATIVE flag represents indirect calls that was
+ speculatively turned into direct (i.e. by profile feedback).
+ The final code sequence will have form:
+
+ if (call_target == expected_fn)
+ expected_fn ();
+ else
+ call_target ();
+
+ Every speculative call is represented by three components attached
+ to a same call statement:
+ 1) a direct call (to expected_fn)
+ 2) an indirect call (to call_target)
+ 3) a IPA_REF_ADDR refrence to expected_fn.
+
+ Optimizers may later redirect direct call to clone, so 1) and 3)
+ do not need to necesarily agree with destination. */
+ unsigned int speculative : 1;
};
#define CGRAPH_FREQ_BASE 1000
@@ -597,6 +621,13 @@ symtab_node symtab_alias_ultimate_target (symtab_node,
enum availability *avail = NULL);
bool symtab_resolve_alias (symtab_node node, symtab_node target);
void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target);
+bool symtab_for_node_and_aliases (symtab_node,
+ bool (*) (symtab_node, void *),
+ void *,
+ bool);
+symtab_node symtab_nonoverwritable_alias (symtab_node);
+enum availability symtab_node_availability (symtab_node);
+bool symtab_semantically_equivalent_p (symtab_node, symtab_node);
/* In cgraph.c */
void dump_cgraph (FILE *);
@@ -606,6 +637,7 @@ void debug_cgraph_node (struct cgraph_node *);
void cgraph_remove_edge (struct cgraph_edge *);
void cgraph_remove_node (struct cgraph_node *);
void cgraph_release_function_body (struct cgraph_node *);
+void release_function_body (tree);
void cgraph_node_remove_callees (struct cgraph_node *node);
struct cgraph_edge *cgraph_create_edge (struct cgraph_node *,
struct cgraph_node *,
@@ -622,7 +654,7 @@ struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, H
HOST_WIDE_INT, tree, tree);
struct cgraph_node *cgraph_node_for_asm (tree);
struct cgraph_edge *cgraph_edge (struct cgraph_node *, gimple);
-void cgraph_set_call_stmt (struct cgraph_edge *, gimple);
+void cgraph_set_call_stmt (struct cgraph_edge *, gimple, bool update_speculative = true);
void cgraph_update_edges_for_call_stmt (gimple, tree, gimple);
struct cgraph_local_info *cgraph_local_info (tree);
struct cgraph_global_info *cgraph_global_info (tree);
@@ -634,7 +666,7 @@ void cgraph_call_edge_duplication_hooks (struct cgraph_edge *,
struct cgraph_edge *);
void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
-void cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *);
+struct cgraph_edge *cgraph_make_edge_direct (struct cgraph_edge *, struct cgraph_node *);
bool cgraph_only_called_directly_p (struct cgraph_node *);
bool cgraph_function_possibly_inlined_p (tree);
@@ -669,12 +701,14 @@ void cgraph_mark_address_taken_node (struct cgraph_node *);
typedef void (*cgraph_edge_hook)(struct cgraph_edge *, void *);
typedef void (*cgraph_node_hook)(struct cgraph_node *, void *);
+typedef void (*varpool_node_hook)(struct varpool_node *, void *);
typedef void (*cgraph_2edge_hook)(struct cgraph_edge *, struct cgraph_edge *,
void *);
typedef void (*cgraph_2node_hook)(struct cgraph_node *, struct cgraph_node *,
void *);
struct cgraph_edge_hook_list;
struct cgraph_node_hook_list;
+struct varpool_node_hook_list;
struct cgraph_2edge_hook_list;
struct cgraph_2node_hook_list;
struct cgraph_edge_hook_list *cgraph_add_edge_removal_hook (cgraph_edge_hook, void *);
@@ -682,18 +716,32 @@ void cgraph_remove_edge_removal_hook (struct cgraph_edge_hook_list *);
struct cgraph_node_hook_list *cgraph_add_node_removal_hook (cgraph_node_hook,
void *);
void cgraph_remove_node_removal_hook (struct cgraph_node_hook_list *);
+struct varpool_node_hook_list *varpool_add_node_removal_hook (varpool_node_hook,
+ void *);
+void varpool_remove_node_removal_hook (struct varpool_node_hook_list *);
struct cgraph_node_hook_list *cgraph_add_function_insertion_hook (cgraph_node_hook,
void *);
void cgraph_remove_function_insertion_hook (struct cgraph_node_hook_list *);
+struct varpool_node_hook_list *varpool_add_variable_insertion_hook (varpool_node_hook,
+ void *);
+void varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *);
void cgraph_call_function_insertion_hooks (struct cgraph_node *node);
struct cgraph_2edge_hook_list *cgraph_add_edge_duplication_hook (cgraph_2edge_hook, void *);
void cgraph_remove_edge_duplication_hook (struct cgraph_2edge_hook_list *);
struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_hook, void *);
void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
-bool cgraph_propagate_frequency (struct cgraph_node *node);
struct cgraph_node * cgraph_function_node (struct cgraph_node *,
enum availability *avail = NULL);
+bool cgraph_get_body (struct cgraph_node *node);
+struct cgraph_edge *
+cgraph_turn_edge_to_speculative (struct cgraph_edge *,
+ struct cgraph_node *,
+ gcov_type, int);
+void cgraph_speculative_call_info (struct cgraph_edge *,
+ struct cgraph_edge *&,
+ struct cgraph_edge *&,
+ struct ipa_ref *&);
/* In cgraphunit.c */
struct asm_node *add_asm_node (tree);
@@ -709,6 +757,7 @@ void fixup_same_cpp_alias_visibility (symtab_node, symtab_node target, tree);
IN_SSA is true if the gimple is in SSA. */
basic_block init_lowered_empty_function (tree, bool);
void cgraph_reset_node (struct cgraph_node *);
+void expand_thunk (struct cgraph_node *);
/* In cgraphclones.c */
@@ -726,7 +775,8 @@ struct cgraph_node * cgraph_create_virtual_clone (struct cgraph_node *old_node,
const char *clone_name);
struct cgraph_node *cgraph_find_replacement_node (struct cgraph_node *);
bool cgraph_remove_node_and_inline_clones (struct cgraph_node *, struct cgraph_node *);
-void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple);
+void cgraph_set_call_stmt_including_clones (struct cgraph_node *, gimple, gimple,
+ bool update_speculative = true);
void cgraph_create_edge_including_clones (struct cgraph_node *,
struct cgraph_node *,
gimple, gimple, gcov_type, int,
@@ -741,6 +791,7 @@ struct cgraph_node *cgraph_function_versioning (struct cgraph_node *,
basic_block, const char *);
void tree_function_versioning (tree, tree, vec<ipa_replace_map_p, va_gc> *,
bool, bitmap, bool, bitmap, basic_block);
+struct cgraph_edge *cgraph_resolve_speculation (struct cgraph_edge *, tree);
/* In cgraphbuild.c */
unsigned int rebuild_cgraph_edges (void);
@@ -1347,13 +1398,25 @@ symtab_real_symbol_p (symtab_node node)
{
struct cgraph_node *cnode;
+ if (DECL_ABSTRACT (node->symbol.decl))
+ return false;
if (!is_a <cgraph_node> (node))
return true;
cnode = cgraph (node);
if (cnode->global.inlined_to)
return false;
- if (cnode->abstract_and_needed)
- return false;
return true;
}
+
+/* Return true if NODE can be discarded by linker from the binary. */
+
+static inline bool
+symtab_can_be_discarded (symtab_node node)
+{
+ return (DECL_EXTERNAL (node->symbol.decl)
+ || (DECL_ONE_ONLY (node->symbol.decl)
+ && node->symbol.resolution != LDPR_PREVAILING_DEF
+ && node->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY
+ && node->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY_EXP));
+}
#endif /* GCC_CGRAPH_H */
diff --git a/gcc/cgraphbuild.c b/gcc/cgraphbuild.c
index fb1515d6037..b9c112fef4d 100644
--- a/gcc/cgraphbuild.c
+++ b/gcc/cgraphbuild.c
@@ -318,6 +318,9 @@ build_cgraph_edges (void)
gimple stmt = gsi_stmt (gsi);
tree decl;
+ if (is_gimple_debug (stmt))
+ continue;
+
if (is_gimple_call (stmt))
{
int freq = compute_call_stmt_bb_frequency (current_function_decl,
@@ -370,26 +373,43 @@ build_cgraph_edges (void)
return 0;
}
-struct gimple_opt_pass pass_build_cgraph_edges =
+namespace {
+
+const pass_data pass_data_build_cgraph_edges =
{
- {
- GIMPLE_PASS,
- "*build_cgraph_edges", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- build_cgraph_edges, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "*build_cgraph_edges", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_build_cgraph_edges : public gimple_opt_pass
+{
+public:
+ pass_build_cgraph_edges(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_build_cgraph_edges, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return build_cgraph_edges (); }
+
+}; // class pass_build_cgraph_edges
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_build_cgraph_edges (gcc::context *ctxt)
+{
+ return new pass_build_cgraph_edges (ctxt);
+}
+
/* Record references to functions and other variables present in the
initial value of DECL, a variable.
When ONLY_VARS is true, we mark needed only variables, not functions. */
@@ -463,8 +483,15 @@ cgraph_rebuild_references (void)
basic_block bb;
struct cgraph_node *node = cgraph_get_node (current_function_decl);
gimple_stmt_iterator gsi;
+ struct ipa_ref *ref;
+ int i;
- ipa_remove_all_references (&node->symbol.ref_list);
+ /* Keep speculative references for further cgraph edge expansion. */
+ for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref);)
+ if (!ref->speculative)
+ ipa_remove_reference (ref);
+ else
+ i++;
node->count = ENTRY_BLOCK_PTR->count;
@@ -478,50 +505,90 @@ cgraph_rebuild_references (void)
record_eh_tables (node, cfun);
}
-struct gimple_opt_pass pass_rebuild_cgraph_edges =
+namespace {
+
+const pass_data pass_data_rebuild_cgraph_edges =
{
- {
- GIMPLE_PASS,
- "*rebuild_cgraph_edges", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rebuild_cgraph_edges, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CGRAPH, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "*rebuild_cgraph_edges", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_CGRAPH, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_rebuild_cgraph_edges : public gimple_opt_pass
+{
+public:
+ pass_rebuild_cgraph_edges(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_rebuild_cgraph_edges, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_rebuild_cgraph_edges (ctxt_); }
+ unsigned int execute () { return rebuild_cgraph_edges (); }
+
+}; // class pass_rebuild_cgraph_edges
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_rebuild_cgraph_edges (gcc::context *ctxt)
+{
+ return new pass_rebuild_cgraph_edges (ctxt);
+}
+
static unsigned int
remove_cgraph_callee_edges (void)
{
- cgraph_node_remove_callees (cgraph_get_node (current_function_decl));
+ struct cgraph_node *node = cgraph_get_node (current_function_decl);
+ cgraph_node_remove_callees (node);
+ ipa_remove_all_references (&node->symbol.ref_list);
return 0;
}
-struct gimple_opt_pass pass_remove_cgraph_callee_edges =
+namespace {
+
+const pass_data pass_data_remove_cgraph_callee_edges =
{
- {
- GIMPLE_PASS,
- "*remove_cgraph_callee_edges", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- remove_cgraph_callee_edges, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "*remove_cgraph_callee_edges", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_remove_cgraph_callee_edges : public gimple_opt_pass
+{
+public:
+ pass_remove_cgraph_callee_edges(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_remove_cgraph_callee_edges, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () {
+ return new pass_remove_cgraph_callee_edges (ctxt_);
+ }
+ unsigned int execute () { return remove_cgraph_callee_edges (); }
+
+}; // class pass_remove_cgraph_callee_edges
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_remove_cgraph_callee_edges (gcc::context *ctxt)
+{
+ return new pass_remove_cgraph_callee_edges (ctxt);
+}
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 04cb990cc86..54b97b91c78 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -147,6 +147,7 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
/* Clone flags that depend on call_stmt availability manually. */
new_edge->can_throw_external = e->can_throw_external;
new_edge->call_stmt_cannot_inline_p = e->call_stmt_cannot_inline_p;
+ new_edge->speculative = e->speculative;
if (update_original)
{
e->count -= new_edge->count;
@@ -251,7 +252,7 @@ cgraph_clone_node (struct cgraph_node *n, tree decl, gcov_type count, int freq,
return new_node;
}
-/* Create a new name for clone of DECL, add SUFFIX. Returns an identifier. */
+/* Return a new assembler name for a clone of DECL with SUFFIX. */
static GTY(()) unsigned int clone_fn_id_num;
@@ -292,10 +293,11 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
tree old_decl = old_node->symbol.decl;
struct cgraph_node *new_node = NULL;
tree new_decl;
- size_t i;
+ size_t len, i;
struct ipa_replace_map *map;
+ char *name;
- if (!flag_wpa)
+ if (!in_lto_p)
gcc_checking_assert (tree_versionable_function_p (old_decl));
gcc_assert (old_node->local.can_change_signature || !args_to_skip);
@@ -317,8 +319,13 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
sometimes storing only clone decl instead of original. */
/* Generate a new name for the new version. */
- DECL_NAME (new_decl) = clone_function_name (old_decl, suffix);
- SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
+ len = IDENTIFIER_LENGTH (DECL_NAME (old_decl));
+ name = XALLOCAVEC (char, len + strlen (suffix) + 2);
+ memcpy (name, IDENTIFIER_POINTER (DECL_NAME (old_decl)), len);
+ strcpy (name + len + 1, suffix);
+ name[len] = '.';
+ DECL_NAME (new_decl) = get_identifier (name);
+ SET_DECL_ASSEMBLER_NAME (new_decl, clone_function_name (old_decl, suffix));
SET_DECL_RTL (new_decl, NULL);
new_node = cgraph_clone_node (old_node, new_decl, old_node->count,
@@ -474,17 +481,21 @@ cgraph_find_replacement_node (struct cgraph_node *node)
}
/* Like cgraph_set_call_stmt but walk the clone tree and update all
- clones sharing the same function body. */
+ clones sharing the same function body.
+ When WHOLE_SPECULATIVE_EDGES is true, all three components of
+ speculative edge gets updated. Otherwise we update only direct
+ call. */
void
cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
- gimple old_stmt, gimple new_stmt)
+ gimple old_stmt, gimple new_stmt,
+ bool update_speculative)
{
struct cgraph_node *node;
struct cgraph_edge *edge = cgraph_edge (orig, old_stmt);
if (edge)
- cgraph_set_call_stmt (edge, new_stmt);
+ cgraph_set_call_stmt (edge, new_stmt, update_speculative);
node = orig->clones;
if (node)
@@ -492,7 +503,23 @@ cgraph_set_call_stmt_including_clones (struct cgraph_node *orig,
{
struct cgraph_edge *edge = cgraph_edge (node, old_stmt);
if (edge)
- cgraph_set_call_stmt (edge, new_stmt);
+ {
+ cgraph_set_call_stmt (edge, new_stmt, update_speculative);
+ /* If UPDATE_SPECULATIVE is false, it means that we are turning
+ speculative call into a real code sequence. Update the
+ callgraph edges. */
+ if (edge->speculative && !update_speculative)
+ {
+ struct cgraph_edge *direct, *indirect;
+ struct ipa_ref *ref;
+
+ gcc_assert (!edge->indirect_unknown_callee);
+ cgraph_speculative_call_info (edge, direct, indirect, ref);
+ direct->speculative = false;
+ indirect->speculative = false;
+ ref->speculative = false;
+ }
+ }
if (node->clones)
node = node->clones;
else if (node->next_sibling_clone)
@@ -811,6 +838,7 @@ cgraph_materialize_all_clones (void)
{
struct cgraph_node *node;
bool stabilized = false;
+
if (cgraph_dump_file)
fprintf (cgraph_dump_file, "Materializing clones\n");
@@ -829,6 +857,8 @@ cgraph_materialize_all_clones (void)
if (node->clone_of && node->symbol.decl != node->clone_of->symbol.decl
&& !gimple_has_body_p (node->symbol.decl))
{
+ if (!node->clone_of->clone_of)
+ cgraph_get_body (node->clone_of);
if (gimple_has_body_p (node->clone_of->symbol.decl))
{
if (cgraph_dump_file)
@@ -874,7 +904,12 @@ cgraph_materialize_all_clones (void)
}
FOR_EACH_FUNCTION (node)
if (!node->symbol.analyzed && node->callees)
- cgraph_node_remove_callees (node);
+ {
+ cgraph_node_remove_callees (node);
+ ipa_remove_all_references (&node->symbol.ref_list);
+ }
+ else
+ ipa_clear_stmts_in_references ((symtab_node)node);
if (cgraph_dump_file)
fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
#ifdef ENABLE_CHECKING
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index b82c2e01b57..9681df518cd 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -194,6 +194,8 @@ along with GCC; see the file COPYING3. If not see
#include "except.h"
#include "cfgloop.h"
#include "regset.h" /* FIXME: For reg_obstack. */
+#include "context.h"
+#include "pass_manager.h"
/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
secondary queue used during optimization to accommodate passes that
@@ -233,10 +235,6 @@ decide_is_symbol_needed (symtab_node node)
if (!node->symbol.definition)
return false;
- /* Devirtualization may access these. */
- if (DECL_VIRTUAL_P (decl) && optimize)
- return true;
-
if (DECL_EXTERNAL (decl))
return false;
@@ -321,13 +319,10 @@ cgraph_process_new_functions (void)
if (!node->symbol.analyzed)
analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
- if ((cgraph_state == CGRAPH_STATE_IPA_SSA
+ if (cgraph_state == CGRAPH_STATE_IPA_SSA
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
- /* When not optimizing, be sure we run early local passes anyway
- to expand OMP. */
- || !optimize)
- execute_pass_list (pass_early_local_passes.pass.sub);
- else
+ g->get_passes ()->execute_early_local_passes ();
+ else if (inline_summary_vec != NULL)
compute_inline_parameters (node, true);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
@@ -405,17 +400,20 @@ referred_to_p (symtab_node node)
}
/* DECL has been parsed. Take it, queue it, compile it at the whim of the
- logic in effect. If NESTED is true, then our caller cannot stand to have
+ logic in effect. If NO_COLLECT is true, then our caller cannot stand to have
the garbage collector run at the moment. We would need to either create
a new GC context, or just not compile right now. */
void
-cgraph_finalize_function (tree decl, bool nested)
+cgraph_finalize_function (tree decl, bool no_collect)
{
struct cgraph_node *node = cgraph_get_create_node (decl);
if (node->symbol.definition)
{
+ /* Nested functions should only be defined once. */
+ gcc_assert (!DECL_CONTEXT (decl)
+ || TREE_CODE (DECL_CONTEXT (decl)) != FUNCTION_DECL);
cgraph_reset_node (node);
node->local.redefined_extern_inline = true;
}
@@ -454,7 +452,7 @@ cgraph_finalize_function (tree decl, bool nested)
if (warn_unused_parameter)
do_warn_unused_parameter (decl);
- if (!nested)
+ if (!no_collect)
ggc_collect ();
if (cgraph_state == CGRAPH_STATE_CONSTRUCTION
@@ -478,6 +476,7 @@ cgraph_finalize_function (tree decl, bool nested)
void
cgraph_add_new_function (tree fndecl, bool lowered)
{
+ gcc::pass_manager *passes = g->get_passes ();
struct cgraph_node *node;
switch (cgraph_state)
{
@@ -508,8 +507,8 @@ cgraph_add_new_function (tree fndecl, bool lowered)
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
- execute_pass_list (all_lowering_passes);
- execute_pass_list (pass_early_local_passes.pass.sub);
+ execute_pass_list (passes->all_lowering_passes);
+ passes->execute_early_local_passes ();
bitmap_obstack_release (NULL);
pop_cfun ();
@@ -534,7 +533,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
- execute_pass_list (pass_early_local_passes.pass.sub);
+ g->get_passes ()->execute_early_local_passes ();
bitmap_obstack_release (NULL);
pop_cfun ();
expand_function (node);
@@ -640,7 +639,7 @@ analyze_function (struct cgraph_node *node)
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
- execute_pass_list (all_lowering_passes);
+ execute_pass_list (g->get_passes ()->all_lowering_passes);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
compact_blocks ();
@@ -822,6 +821,82 @@ varpool_finalize_decl (tree decl)
varpool_assemble_decl (node);
}
+/* EDGE is an polymorphic call. Mark all possible targets as reachable
+ and if there is only one target, perform trivial devirtualization.
+ REACHABLE_CALL_TARGETS collects target lists we already walked to
+ avoid udplicate work. */
+
+static void
+walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
+ struct cgraph_edge *edge)
+{
+ unsigned int i;
+ void *cache_token;
+ bool final;
+ vec <cgraph_node *>targets
+ = possible_polymorphic_call_targets
+ (edge, &final, &cache_token);
+
+ if (!pointer_set_insert (reachable_call_targets,
+ cache_token))
+ {
+ if (cgraph_dump_file)
+ dump_possible_polymorphic_call_targets
+ (cgraph_dump_file, edge);
+
+ for (i = 0; i < targets.length(); i++)
+ {
+ /* Do not bother to mark virtual methods in anonymous namespace;
+ either we will find use of virtual table defining it, or it is
+ unused. */
+ if (targets[i]->symbol.definition
+ && TREE_CODE
+ (TREE_TYPE (targets[i]->symbol.decl))
+ == METHOD_TYPE
+ && !type_in_anonymous_namespace_p
+ (method_class_type
+ (TREE_TYPE (targets[i]->symbol.decl))))
+ enqueue_node ((symtab_node) targets[i]);
+ }
+ }
+
+ /* Very trivial devirtualization; when the type is
+ final or anonymous (so we know all its derivation)
+ and there is only one possible virtual call target,
+ make the edge direct. */
+ if (final)
+ {
+ if (targets.length() <= 1)
+ {
+ cgraph_node *target;
+ if (targets.length () == 1)
+ target = targets[0];
+ else
+ target = cgraph_get_create_node
+ (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
+
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file,
+ "Devirtualizing call: ");
+ print_gimple_stmt (cgraph_dump_file,
+ edge->call_stmt, 0,
+ TDF_SLIM);
+ }
+ cgraph_make_edge_direct (edge, target);
+ cgraph_redirect_edge_call_stmt_to_callee (edge);
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file,
+ "Devirtualized as: ");
+ print_gimple_stmt (cgraph_dump_file,
+ edge->call_stmt, 0,
+ TDF_SLIM);
+ }
+ }
+ }
+}
+
/* Discover all functions and variables that are trivially needed, analyze
them as well as all functions and variables referred by them */
@@ -835,6 +910,7 @@ analyze_functions (void)
struct cgraph_node *first_handled = first_analyzed;
static struct varpool_node *first_analyzed_var;
struct varpool_node *first_handled_var = first_analyzed_var;
+ struct pointer_set_t *reachable_call_targets = pointer_set_create ();
symtab_node node, next;
int i;
@@ -850,6 +926,8 @@ analyze_functions (void)
FOR_EACH_SYMBOL (node)
if (node->symbol.cpp_implicit_alias)
fixup_same_cpp_alias_visibility (node, symtab_alias_target (node));
+ if (optimize && flag_devirtualize)
+ build_type_inheritance_graph ();
/* Analysis adds static variables that in turn adds references to new functions.
So we need to iterate the process until it stabilize. */
@@ -872,6 +950,8 @@ analyze_functions (void)
changed = true;
if (cgraph_dump_file)
fprintf (cgraph_dump_file, " %s", symtab_node_asm_name (node));
+ if (!changed && cgraph_dump_file)
+ fprintf (cgraph_dump_file, "\n");
}
if (node == (symtab_node)first_analyzed
|| node == (symtab_node)first_analyzed_var)
@@ -916,6 +996,18 @@ analyze_functions (void)
for (edge = cnode->callees; edge; edge = edge->next_callee)
if (edge->callee->symbol.definition)
enqueue_node ((symtab_node)edge->callee);
+ if (optimize && flag_devirtualize)
+ {
+ struct cgraph_edge *next;
+
+ for (edge = cnode->indirect_calls; edge; edge = next)
+ {
+ next = edge->next_callee;
+ if (edge->indirect_info->polymorphic)
+ walk_polymorphic_call_targets (reachable_call_targets,
+ edge);
+ }
+ }
/* If decl is a clone of an abstract function,
mark that abstract function so that we don't release its body.
@@ -925,7 +1017,7 @@ analyze_functions (void)
{
struct cgraph_node *origin_node
= cgraph_get_node (DECL_ABSTRACT_ORIGIN (decl));
- origin_node->abstract_and_needed = true;
+ origin_node->used_as_abstract_origin = true;
}
}
else
@@ -949,6 +1041,8 @@ analyze_functions (void)
cgraph_process_new_functions ();
}
}
+ if (optimize && flag_devirtualize)
+ update_type_inheritance_graph ();
/* Collect entry points to the unit. */
if (cgraph_dump_file)
@@ -988,6 +1082,8 @@ analyze_functions (void)
}
node->symbol.aux = NULL;
}
+ for (;node; node = node->symbol.next)
+ node->symbol.aux = NULL;
first_analyzed = cgraph_first_function ();
first_analyzed_var = varpool_first_variable ();
if (cgraph_dump_file)
@@ -996,12 +1092,18 @@ analyze_functions (void)
dump_symtab (cgraph_dump_file);
}
bitmap_obstack_release (NULL);
+ pointer_set_destroy (reachable_call_targets);
ggc_collect ();
+ /* Initialize assembler name hash, in particular we want to trigger C++
+ mangling and same body alias creation before we free DECL_ARGUMENTS
+ used by it. */
+ if (!seen_error ())
+ symtab_initialize_asm_name_hash ();
}
/* Translate the ugly representation of aliases as alias pairs into nice
representation in callgraph. We don't handle all cases yet,
- unforutnately. */
+ unfortunately. */
static void
handle_alias_pairs (void)
@@ -1013,10 +1115,11 @@ handle_alias_pairs (void)
{
symtab_node target_node = symtab_node_for_asm (p->target);
- /* Weakrefs with target not defined in current unit are easy to handle; they
- behave just as external variables except we need to note the alias flag
- to later output the weakref pseudo op into asm file. */
- if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
+ /* Weakrefs with target not defined in current unit are easy to handle:
+ they behave just as external variables except we need to note the
+ alias flag to later output the weakref pseudo op into asm file. */
+ if (!target_node
+ && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
{
symtab_node node = symtab_get_node (p->decl);
if (node)
@@ -1031,6 +1134,9 @@ handle_alias_pairs (void)
else if (!target_node)
{
error ("%q+D aliased to undefined symbol %qE", p->decl, p->target);
+ symtab_node node = symtab_get_node (p->decl);
+ if (node)
+ node->symbol.alias = false;
alias_pairs->unordered_remove (i);
continue;
}
@@ -1324,8 +1430,8 @@ thunk_adjust (gimple_stmt_iterator * bsi,
/* Produce assembler for thunk NODE. */
-static void
-assemble_thunk (struct cgraph_node *node)
+void
+expand_thunk (struct cgraph_node *node)
{
bool this_adjusting = node->thunk.this_adjusting;
HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
@@ -1333,7 +1439,11 @@ assemble_thunk (struct cgraph_node *node)
tree virtual_offset = NULL;
tree alias = node->callees->callee->symbol.decl;
tree thunk_fndecl = node->symbol.decl;
- tree a = DECL_ARGUMENTS (thunk_fndecl);
+ tree a;
+
+ if (in_lto_p)
+ cgraph_get_body (node);
+ a = DECL_ARGUMENTS (thunk_fndecl);
current_function_decl = thunk_fndecl;
@@ -1417,7 +1527,9 @@ assemble_thunk (struct cgraph_node *node)
/* Build call to the function being thunked. */
if (!VOID_TYPE_P (restype))
{
- if (!is_gimple_reg_type (restype))
+ if (DECL_BY_REFERENCE (resdecl))
+ restmp = gimple_fold_indirect_ref (resdecl);
+ else if (!is_gimple_reg_type (restype))
{
restmp = resdecl;
add_local_decl (cfun, restmp);
@@ -1433,74 +1545,91 @@ assemble_thunk (struct cgraph_node *node)
if (this_adjusting)
vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
virtual_offset));
- else
+ else if (nargs)
vargs.quick_push (a);
- for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
- vargs.quick_push (arg);
+
+ if (nargs)
+ for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
+ vargs.quick_push (arg);
call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs);
vargs.release ();
gimple_call_set_from_thunk (call, true);
if (restmp)
- gimple_call_set_lhs (call, restmp);
+ {
+ gimple_call_set_lhs (call, restmp);
+ gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
+ TREE_TYPE (TREE_TYPE (alias))));
+ }
gsi_insert_after (&bsi, call, GSI_NEW_STMT);
+ if (!(gimple_call_flags (call) & ECF_NORETURN))
+ {
+ if (restmp && !this_adjusting
+ && (fixed_offset || virtual_offset))
+ {
+ tree true_label = NULL_TREE;
- if (restmp && !this_adjusting)
- {
- tree true_label = NULL_TREE;
+ if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
+ {
+ gimple stmt;
+ /* If the return type is a pointer, we need to
+ protect against NULL. We know there will be an
+ adjustment, because that's why we're emitting a
+ thunk. */
+ then_bb = create_basic_block (NULL, (void *) 0, bb);
+ return_bb = create_basic_block (NULL, (void *) 0, then_bb);
+ else_bb = create_basic_block (NULL, (void *) 0, else_bb);
+ add_bb_to_loop (then_bb, bb->loop_father);
+ add_bb_to_loop (return_bb, bb->loop_father);
+ add_bb_to_loop (else_bb, bb->loop_father);
+ remove_edge (single_succ_edge (bb));
+ true_label = gimple_block_label (then_bb);
+ stmt = gimple_build_cond (NE_EXPR, restmp,
+ build_zero_cst (TREE_TYPE (restmp)),
+ NULL_TREE, NULL_TREE);
+ gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
+ make_edge (bb, then_bb, EDGE_TRUE_VALUE);
+ make_edge (bb, else_bb, EDGE_FALSE_VALUE);
+ make_edge (return_bb, EXIT_BLOCK_PTR, 0);
+ make_edge (then_bb, return_bb, EDGE_FALLTHRU);
+ make_edge (else_bb, return_bb, EDGE_FALLTHRU);
+ bsi = gsi_last_bb (then_bb);
+ }
- if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
- {
- gimple stmt;
- /* If the return type is a pointer, we need to
- protect against NULL. We know there will be an
- adjustment, because that's why we're emitting a
- thunk. */
- then_bb = create_basic_block (NULL, (void *) 0, bb);
- return_bb = create_basic_block (NULL, (void *) 0, then_bb);
- else_bb = create_basic_block (NULL, (void *) 0, else_bb);
- add_bb_to_loop (then_bb, bb->loop_father);
- add_bb_to_loop (return_bb, bb->loop_father);
- add_bb_to_loop (else_bb, bb->loop_father);
- remove_edge (single_succ_edge (bb));
- true_label = gimple_block_label (then_bb);
- stmt = gimple_build_cond (NE_EXPR, restmp,
- build_zero_cst (TREE_TYPE (restmp)),
- NULL_TREE, NULL_TREE);
- gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
- make_edge (bb, then_bb, EDGE_TRUE_VALUE);
- make_edge (bb, else_bb, EDGE_FALSE_VALUE);
- make_edge (return_bb, EXIT_BLOCK_PTR, 0);
- make_edge (then_bb, return_bb, EDGE_FALLTHRU);
- make_edge (else_bb, return_bb, EDGE_FALLTHRU);
- bsi = gsi_last_bb (then_bb);
+ restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
+ fixed_offset, virtual_offset);
+ if (true_label)
+ {
+ gimple stmt;
+ bsi = gsi_last_bb (else_bb);
+ stmt = gimple_build_assign (restmp,
+ build_zero_cst (TREE_TYPE (restmp)));
+ gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
+ bsi = gsi_last_bb (return_bb);
+ }
}
+ else
+ gimple_call_set_tail (call, true);
- restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0,
- fixed_offset, virtual_offset);
- if (true_label)
- {
- gimple stmt;
- bsi = gsi_last_bb (else_bb);
- stmt = gimple_build_assign (restmp,
- build_zero_cst (TREE_TYPE (restmp)));
- gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
- bsi = gsi_last_bb (return_bb);
- }
+ /* Build return value. */
+ ret = gimple_build_return (restmp);
+ gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
}
else
- gimple_call_set_tail (call, true);
-
- /* Build return value. */
- ret = gimple_build_return (restmp);
- gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
+ {
+ gimple_call_set_tail (call, true);
+ remove_edge (single_succ_edge (bb));
+ }
delete_unreachable_blocks ();
update_ssa (TODO_update_ssa);
+#ifdef ENABLE_CHECKING
+ verify_flow_info ();
+#endif
/* Since we want to emit the thunk, we explicitly mark its name as
referenced. */
node->thunk.thunk_p = false;
- cgraph_node_remove_callees (node);
+ rebuild_cgraph_edges ();
cgraph_add_new_function (thunk_fndecl, true);
bitmap_obstack_release (NULL);
}
@@ -1508,8 +1637,6 @@ assemble_thunk (struct cgraph_node *node)
set_cfun (NULL);
}
-
-
/* Assemble thunks and aliases associated to NODE. */
static void
@@ -1526,7 +1653,7 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
e = e->next_caller;
assemble_thunks_and_aliases (thunk);
- assemble_thunk (thunk);
+ expand_thunk (thunk);
}
else
e = e->next_caller;
@@ -1561,6 +1688,7 @@ expand_function (struct cgraph_node *node)
announce_function (decl);
node->process = 0;
gcc_assert (node->lowered);
+ cgraph_get_body (node);
/* Generate RTL for the body of DECL. */
@@ -1588,7 +1716,7 @@ expand_function (struct cgraph_node *node)
/* Signal the start of passes. */
invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
- execute_pass_list (all_passes);
+ execute_pass_list (g->get_passes ()->all_passes);
/* Signal the end of passes. */
invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
@@ -1656,6 +1784,7 @@ expand_function (struct cgraph_node *node)
/* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
points to the dead function body. */
cgraph_node_remove_callees (node);
+ ipa_remove_all_references (&node->symbol.ref_list);
}
@@ -1807,6 +1936,8 @@ output_in_order (void)
static void
ipa_passes (void)
{
+ gcc::pass_manager *passes = g->get_passes ();
+
set_cfun (NULL);
current_function_decl = NULL;
gimple_register_cfg_hooks ();
@@ -1816,7 +1947,7 @@ ipa_passes (void)
if (!in_lto_p)
{
- execute_ipa_pass_list (all_small_ipa_passes);
+ execute_ipa_pass_list (passes->all_small_ipa_passes);
if (seen_error ())
return;
}
@@ -1843,14 +1974,15 @@ ipa_passes (void)
cgraph_process_new_functions ();
execute_ipa_summary_passes
- ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
+ ((struct ipa_opt_pass_d *) passes->all_regular_ipa_passes);
}
/* Some targets need to handle LTO assembler output specially. */
if (flag_generate_lto)
targetm.asm_out.lto_start ();
- execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
+ execute_ipa_summary_passes ((struct ipa_opt_pass_d *)
+ passes->all_lto_gen_passes);
if (!in_lto_p)
ipa_write_summaries ();
@@ -1859,7 +1991,7 @@ ipa_passes (void)
targetm.asm_out.lto_end ();
if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
- execute_ipa_pass_list (all_regular_ipa_passes);
+ execute_ipa_pass_list (passes->all_regular_ipa_passes);
invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
bitmap_obstack_release (NULL);
@@ -1985,7 +2117,7 @@ compile (void)
cgraph_materialize_all_clones ();
bitmap_obstack_initialize (NULL);
- execute_ipa_pass_list (all_late_ipa_passes);
+ execute_ipa_pass_list (g->get_passes ()->all_late_ipa_passes);
symtab_remove_unreachable_nodes (true, dump_file);
#ifdef ENABLE_CHECKING
verify_symtab ();
diff --git a/gcc/combine-stack-adj.c b/gcc/combine-stack-adj.c
index 7392b92b3f5..be47665ebc0 100644
--- a/gcc/combine-stack-adj.c
+++ b/gcc/combine-stack-adj.c
@@ -643,22 +643,40 @@ rest_of_handle_stack_adjustments (void)
return 0;
}
-struct rtl_opt_pass pass_stack_adjustments =
+namespace {
+
+const pass_data pass_data_stack_adjustments =
{
- {
- RTL_PASS,
- "csa", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_stack_adjustments, /* gate */
- rest_of_handle_stack_adjustments, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_COMBINE_STACK_ADJUST, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "csa", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_COMBINE_STACK_ADJUST, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_stack_adjustments : public rtl_opt_pass
+{
+public:
+ pass_stack_adjustments(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_stack_adjustments, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_stack_adjustments (); }
+ unsigned int execute () { return rest_of_handle_stack_adjustments (); }
+
+}; // class pass_stack_adjustments
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_stack_adjustments (gcc::context *ctxt)
+{
+ return new pass_stack_adjustments (ctxt);
+}
diff --git a/gcc/combine.c b/gcc/combine.c
index 754cd341f45..fc566c55c16 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -5803,8 +5803,15 @@ combine_simplify_rtx (rtx x, enum machine_mode op0_mode, int in_dest,
return x;
}
- /* If the code changed, return a whole new comparison. */
- if (new_code != code)
+ /* If the code changed, return a whole new comparison.
+ We also need to avoid using SUBST in cases where
+ simplify_comparison has widened a comparison with a CONST_INT,
+ since in that case the wider CONST_INT may fail the sanity
+ checks in do_SUBST. */
+ if (new_code != code
+ || (CONST_INT_P (op1)
+ && GET_MODE (op0) != GET_MODE (XEXP (x, 0))
+ && GET_MODE (op0) != GET_MODE (XEXP (x, 1))))
return gen_rtx_fmt_ee (new_code, mode, op0, op1);
/* Otherwise, keep this operation, but maybe change its operands.
@@ -8122,8 +8129,8 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
/* If MODE is narrower than HOST_WIDE_INT and CVAL is a negative
number, sign extend it. */
if (width > 0 && width < HOST_BITS_PER_WIDE_INT
- && (cval & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
- cval |= (unsigned HOST_WIDE_INT) -1 << width;
+ && (cval & (HOST_WIDE_INT_1U << (width - 1))) != 0)
+ cval |= HOST_WIDE_INT_M1U << width;
y = simplify_gen_binary (AND, GET_MODE (x),
XEXP (x, 0), GEN_INT (cval));
@@ -8151,8 +8158,8 @@ force_to_mode (rtx x, enum machine_mode mode, unsigned HOST_WIDE_INT mask,
number, sign extend it. */
if (width < HOST_BITS_PER_WIDE_INT
- && (smask & ((unsigned HOST_WIDE_INT) 1 << (width - 1))) != 0)
- smask |= (unsigned HOST_WIDE_INT) (-1) << width;
+ && (smask & (HOST_WIDE_INT_1U << (width - 1))) != 0)
+ smask |= HOST_WIDE_INT_M1U << width;
if (CONST_INT_P (XEXP (x, 1))
&& exact_log2 (- smask) >= 0
@@ -13840,22 +13847,40 @@ rest_of_handle_combine (void)
return 0;
}
-struct rtl_opt_pass pass_combine =
+namespace {
+
+const pass_data pass_data_combine =
{
- {
- RTL_PASS,
- "combine", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_combine, /* gate */
- rest_of_handle_combine, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_COMBINE, /* tv_id */
- PROP_cfglayout, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "combine", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_COMBINE, /* tv_id */
+ PROP_cfglayout, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_combine : public rtl_opt_pass
+{
+public:
+ pass_combine(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_combine, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_combine (); }
+ unsigned int execute () { return rest_of_handle_combine (); }
+
+}; // class pass_combine
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_combine (gcc::context *ctxt)
+{
+ return new pass_combine (ctxt);
+}
diff --git a/gcc/common.opt b/gcc/common.opt
index 7f8cfe8f399..27a22a0d5de 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -207,6 +207,10 @@ unsigned int help_columns
Variable
bool flag_opts_finished
+; What the sanitizer should instrument
+Variable
+unsigned int flag_sanitize
+
###
Driver
@@ -850,13 +854,9 @@ fargument-noalias-anything
Common Ignore
Does nothing. Preserved for backward compatibility.
-fsanitize=address
-Common Report Var(flag_asan)
-Enable AddressSanitizer, a memory error detector
-
-fsanitize=thread
-Common Report Var(flag_tsan)
-Enable ThreadSanitizer, a data race detector
+fsanitize=
+Common Driver Report Joined
+Select what to sanitize
fasynchronous-unwind-tables
Common Report Var(flag_asynchronous_unwind_tables) Optimization
@@ -1155,6 +1155,10 @@ fdelete-null-pointer-checks
Common Report Var(flag_delete_null_pointer_checks) Init(1) Optimization
Delete useless null pointer checks
+fdevirtualize-speculatively
+Common Report Var(flag_devirtualize_speculatively) Optimization
+Perform speculative devirtualization
+
fdevirtualize
Common Report Var(flag_devirtualize) Optimization
Try to convert virtual calls to direct ones.
@@ -1518,7 +1522,7 @@ Common RejectNegative Joined
fipa-cp
Common Report Var(flag_ipa_cp) Optimization
-Perform Interprocedural constant propagation
+Perform interprocedural constant propagation
fipa-cp-clone
Common Report Var(flag_ipa_cp_clone) Optimization
@@ -2463,6 +2467,30 @@ Enum(symbol_visibility) String(hidden) Value(VISIBILITY_HIDDEN)
EnumValue
Enum(symbol_visibility) String(protected) Value(VISIBILITY_PROTECTED)
+fvtable-verify=
+Common Joined RejectNegative Enum(vtv_priority) Var(flag_vtable_verify) Init(VTV_NO_PRIORITY)
+Validate vtable pointers before using them.
+
+Enum
+Name(vtv_priority) Type(enum vtv_priority) UnknownError(unknown vtable verify initialization priority %qs)
+
+EnumValue
+Enum(vtv_priority) String(none) Value(VTV_NO_PRIORITY)
+
+EnumValue
+Enum(vtv_priority) String(std) Value(VTV_STANDARD_PRIORITY)
+
+EnumValue
+Enum(vtv_priority) String(preinit) Value(VTV_PREINIT_PRIORITY)
+
+fvtv-counts
+Common Var(flag_vtv_counts)
+Output vtable verification counters.
+
+fvtv-debug
+Common Var(flag_vtv_debug)
+Output vtable verification pointer sets information.
+
fvpt
Common Report Var(flag_value_profile_transformations) Optimization
Use expression value profiles in optimizations
@@ -2732,6 +2760,9 @@ Driver
static-libtsan
Driver
+static-libubsan
+Driver
+
symbolic
Driver
diff --git a/gcc/common/config/i386/i386-common.c b/gcc/common/config/i386/i386-common.c
index b73e369bb32..8ca74b9be49 100644
--- a/gcc/common/config/i386/i386-common.c
+++ b/gcc/common/config/i386/i386-common.c
@@ -57,6 +57,14 @@ along with GCC; see the file COPYING3. If not see
#define OPTION_MASK_ISA_XSAVE_SET OPTION_MASK_ISA_XSAVE
#define OPTION_MASK_ISA_XSAVEOPT_SET \
(OPTION_MASK_ISA_XSAVEOPT | OPTION_MASK_ISA_XSAVE)
+#define OPTION_MASK_ISA_AVX512F_SET \
+ (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX2_SET)
+#define OPTION_MASK_ISA_AVX512CD_SET \
+ (OPTION_MASK_ISA_AVX512CD | OPTION_MASK_ISA_AVX512F_SET)
+#define OPTION_MASK_ISA_AVX512PF_SET \
+ (OPTION_MASK_ISA_AVX512PF | OPTION_MASK_ISA_AVX512F_SET)
+#define OPTION_MASK_ISA_AVX512ER_SET \
+ (OPTION_MASK_ISA_AVX512ER | OPTION_MASK_ISA_AVX512F_SET)
#define OPTION_MASK_ISA_RTM_SET OPTION_MASK_ISA_RTM
#define OPTION_MASK_ISA_PRFCHW_SET OPTION_MASK_ISA_PRFCHW
#define OPTION_MASK_ISA_RDSEED_SET OPTION_MASK_ISA_RDSEED
@@ -128,11 +136,18 @@ along with GCC; see the file COPYING3. If not see
| OPTION_MASK_ISA_FMA4_UNSET | OPTION_MASK_ISA_F16C_UNSET \
| OPTION_MASK_ISA_AVX2_UNSET | OPTION_MASK_ISA_XSAVE_UNSET)
#define OPTION_MASK_ISA_FMA_UNSET OPTION_MASK_ISA_FMA
-#define OPTION_MASK_ISA_AVX2_UNSET OPTION_MASK_ISA_AVX2
#define OPTION_MASK_ISA_FXSR_UNSET OPTION_MASK_ISA_FXSR
#define OPTION_MASK_ISA_XSAVE_UNSET \
(OPTION_MASK_ISA_XSAVE | OPTION_MASK_ISA_XSAVEOPT_UNSET)
#define OPTION_MASK_ISA_XSAVEOPT_UNSET OPTION_MASK_ISA_XSAVEOPT
+#define OPTION_MASK_ISA_AVX2_UNSET \
+ (OPTION_MASK_ISA_AVX2 | OPTION_MASK_ISA_AVX512F_UNSET)
+#define OPTION_MASK_ISA_AVX512F_UNSET \
+ (OPTION_MASK_ISA_AVX512F | OPTION_MASK_ISA_AVX512CD_UNSET \
+ | OPTION_MASK_ISA_AVX512PF_UNSET | OPTION_MASK_ISA_AVX512ER_UNSET)
+#define OPTION_MASK_ISA_AVX512CD_UNSET OPTION_MASK_ISA_AVX512CD
+#define OPTION_MASK_ISA_AVX512PF_UNSET OPTION_MASK_ISA_AVX512PF
+#define OPTION_MASK_ISA_AVX512ER_UNSET OPTION_MASK_ISA_AVX512ER
#define OPTION_MASK_ISA_RTM_UNSET OPTION_MASK_ISA_RTM
#define OPTION_MASK_ISA_PRFCHW_UNSET OPTION_MASK_ISA_PRFCHW
#define OPTION_MASK_ISA_RDSEED_UNSET OPTION_MASK_ISA_RDSEED
@@ -313,6 +328,58 @@ ix86_handle_option (struct gcc_options *opts,
}
return true;
+ case OPT_mavx512f:
+ if (value)
+ {
+ opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512F_SET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512F_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512F_UNSET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512F_UNSET;
+ }
+ return true;
+
+ case OPT_mavx512cd:
+ if (value)
+ {
+ opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512CD_SET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512CD_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512CD_UNSET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512CD_UNSET;
+ }
+ return true;
+
+ case OPT_mavx512pf:
+ if (value)
+ {
+ opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512PF_SET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512PF_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512PF_UNSET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512PF_UNSET;
+ }
+ return true;
+
+ case OPT_mavx512er:
+ if (value)
+ {
+ opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512ER_SET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512ER_SET;
+ }
+ else
+ {
+ opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_AVX512ER_UNSET;
+ opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_AVX512ER_UNSET;
+ }
+ return true;
+
case OPT_mfma:
if (value)
{
diff --git a/gcc/compare-elim.c b/gcc/compare-elim.c
index 367cd8ea8dc..e907376c577 100644
--- a/gcc/compare-elim.c
+++ b/gcc/compare-elim.c
@@ -651,24 +651,41 @@ gate_compare_elim_after_reload (void)
return flag_compare_elim_after_reload;
}
-struct rtl_opt_pass pass_compare_elim_after_reload =
+namespace {
+
+const pass_data pass_data_compare_elim_after_reload =
{
- {
- RTL_PASS,
- "cmpelim", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_compare_elim_after_reload, /* gate */
- execute_compare_elim_after_reload, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish
- | TODO_df_verify
- | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "cmpelim", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_df_verify
+ | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_compare_elim_after_reload : public rtl_opt_pass
+{
+public:
+ pass_compare_elim_after_reload(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_compare_elim_after_reload, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_compare_elim_after_reload (); }
+ unsigned int execute () { return execute_compare_elim_after_reload (); }
+
+}; // class pass_compare_elim_after_reload
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_compare_elim_after_reload (gcc::context *ctxt)
+{
+ return new pass_compare_elim_after_reload (ctxt);
+}
diff --git a/gcc/config.gcc b/gcc/config.gcc
index e09ba64d675..36d5ae82dd1 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -313,7 +313,7 @@ aarch64*-*-*)
cpu_type=aarch64
need_64bit_hwint=yes
extra_headers="arm_neon.h"
- extra_objs="aarch64-builtins.o"
+ extra_objs="aarch64-builtins.o aarch-common.o"
target_has_targetm_common=yes
;;
alpha*-*-*)
@@ -327,9 +327,11 @@ am33_2.0-*-linux*)
arm*-*-*)
cpu_type=arm
extra_headers="mmintrin.h arm_neon.h"
+ extra_objs="aarch-common.o"
target_type_format_char='%'
c_target_objs="arm-c.o"
cxx_target_objs="arm-c.o"
+ need_64bit_hwint=yes
extra_options="${extra_options} arm/arm-tables.opt"
;;
avr-*-*)
@@ -499,6 +501,7 @@ fi
case ${target} in
aarch64*-*-*)
+ tm_p_file="${tm_p_file} arm/aarch-common-protos.h"
case ${with_abi} in
"")
if test "x$with_multilib_list" = xilp32; then
@@ -558,7 +561,11 @@ x86_64-*-*)
fi
tm_file="vxworks-dummy.h ${tm_file}"
;;
-arm*-*-* | mips*-*-* | sh*-*-* | sparc*-*-*)
+arm*-*-*)
+ tm_p_file="${tm_p_file} arm/aarch-common-protos.h"
+ tm_file="vxworks-dummy.h ${tm_file}"
+ ;;
+mips*-*-* | sh*-*-* | sparc*-*-*)
tm_file="vxworks-dummy.h ${tm_file}"
;;
esac
@@ -759,6 +766,7 @@ case ${target} in
yes) thread_file='rtems' ;;
esac
extra_options="${extra_options} rtems.opt"
+ default_use_cxa_atexit=yes
use_gcc_stdint=wrap
;;
*-*-uclinux*)
@@ -823,7 +831,7 @@ case ${target} in
tmake_file=t-vxworks
xm_defines=POSIX
extra_options="${extra_options} vxworks.opt"
- extra_objs=vxworks.o
+ extra_objs="$extra_objs vxworks.o"
case ${enable_threads} in
no) ;;
"" | yes | vxworks) thread_file='vxworks' ;;
@@ -943,10 +951,6 @@ arm*-*-linux-*) # ARM GNU/Linux with ELF
tmake_file="$tmake_file arm/t-linux-androideabi"
;;
esac
- # The BPABI long long divmod functions return a 128-bit value in
- # registers r0-r3. Correctly modeling that requires the use of
- # TImode.
- need_64bit_hwint=yes
# The EABI requires the use of __cxa_atexit.
default_use_cxa_atexit=yes
with_tls=${with_tls:-gnu}
@@ -955,10 +959,6 @@ arm*-*-uclinux*eabi*) # ARM ucLinux
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/linux-gas.h arm/uclinux-elf.h glibc-stdint.h"
tmake_file="arm/t-arm arm/t-arm-elf arm/t-bpabi"
tm_file="$tm_file arm/bpabi.h arm/uclinux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h"
- # The BPABI long long divmod functions return a 128-bit value in
- # registers r0-r3. Correctly modeling that requires the use of
- # TImode.
- need_64bit_hwint=yes
# The EABI requires the use of __cxa_atexit.
default_use_cxa_atexit=yes
;;
@@ -967,10 +967,6 @@ arm*-*-eabi* | arm*-*-symbianelf* | arm*-*-rtems*)
arm*eb-*-eabi*)
tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
esac
- # The BPABI long long divmod functions return a 128-bit value in
- # registers r0-r3. Correctly modeling that requires the use of
- # TImode.
- need_64bit_hwint=yes
default_use_cxa_atexit=yes
tm_file="dbxelf.h elfos.h arm/unknown-elf.h arm/elf.h arm/bpabi.h"
tmake_file="arm/t-arm arm/t-arm-elf"
@@ -1005,7 +1001,7 @@ avr-*-*)
tm_file="${tm_file} ${cpu_type}/avrlibc.h"
tm_defines="${tm_defines} WITH_AVRLIBC"
fi
- tmake_file="avr/t-avr avr/t-multilib"
+ tmake_file="${tmake_file} avr/t-avr avr/t-multilib"
use_gcc_stdint=wrap
extra_gcc_objs="driver-avr.o avr-devices.o"
extra_objs="avr-devices.o avr-log.o"
@@ -1022,7 +1018,7 @@ bfin*-uclinux*)
;;
bfin*-linux-uclibc*)
tm_file="${tm_file} dbxelf.h elfos.h bfin/elf.h gnu-user.h linux.h glibc-stdint.h bfin/linux.h ./linux-sysroot-suffix.h"
- tmake_file="bfin/t-bfin-linux t-slibgcc"
+ tmake_file="bfin/t-bfin-linux t-slibgcc t-linux-android"
use_collect2=no
;;
bfin*-rtems*)
@@ -1057,7 +1053,7 @@ cris-*-elf | cris-*-none)
crisv32-*-linux* | cris-*-linux*)
tm_file="dbxelf.h elfos.h ${tm_file} gnu-user.h linux.h glibc-stdint.h cris/linux.h"
# We need to avoid using t-linux, so override default tmake_file
- tmake_file="cris/t-cris cris/t-linux t-slibgcc"
+ tmake_file="cris/t-cris cris/t-linux t-slibgcc t-linux-android"
extra_options="${extra_options} cris/linux.opt"
case $target in
cris-*-*)
@@ -1709,8 +1705,7 @@ m32r-*-rtems*)
;;
m32r-*-linux*)
tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} m32r/linux.h"
- # We override the tmake_file for linux -- why?
- tmake_file="m32r/t-linux t-slibgcc"
+ tmake_file="${tmake_file} m32r/t-linux t-slibgcc"
gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
@@ -1718,8 +1713,7 @@ m32r-*-linux*)
;;
m32rle-*-linux*)
tm_file="dbxelf.h elfos.h gnu-user.h linux.h glibc-stdint.h m32r/little.h ${tm_file} m32r/linux.h"
- # We override the tmake_file for linux -- why?
- tmake_file="m32r/t-linux t-slibgcc"
+ tmake_file="${tmake_file} m32r/t-linux t-slibgcc"
gnu_ld=yes
if test x$enable_threads = xyes; then
thread_file='posix'
@@ -2145,7 +2139,7 @@ powerpc*-*-linux*)
tmake_file="rs6000/t-fprules rs6000/t-ppcos ${tmake_file} rs6000/t-ppccomm"
case ${target} in
powerpc*le-*-*)
- tm_file="${tm_file} rs6000/sysv4le.h" ;;
+ tm_file="${tm_file} rs6000/sysv4le.h" ;;
esac
maybe_biarch=yes
case ${target} in
@@ -2168,6 +2162,19 @@ powerpc*-*-linux*)
fi
tm_file="rs6000/biarch64.h ${tm_file} rs6000/linux64.h glibc-stdint.h"
tmake_file="$tmake_file rs6000/t-linux64"
+ case ${target} in
+ powerpc*le-*-*)
+ tmake_file="$tmake_file rs6000/t-linux64le"
+ case ${enable_targets} in
+ all | *powerpc64-* | *powerpc-*)
+ tmake_file="$tmake_file rs6000/t-linux64lebe" ;;
+ esac ;;
+ *)
+ case ${enable_targets} in
+ all | *powerpc64le-* | *powerpcle-*)
+ tmake_file="$tmake_file rs6000/t-linux64bele" ;;
+ esac ;;
+ esac
extra_options="${extra_options} rs6000/linux64.opt"
;;
*)
@@ -3040,11 +3047,18 @@ if test x$with_cpu = x ; then
with_cpu=8540
fi
;;
- sparc-leon*-*)
- with_cpu=v8;
- ;;
sparc*-*-*)
- with_cpu="`echo ${target} | sed 's/-.*$//'`"
+ case ${target} in
+ *-leon-*)
+ with_cpu=leon
+ ;;
+ *-leon[3-9]*)
+ with_cpu=leon3
+ ;;
+ *)
+ with_cpu="`echo ${target} | sed 's/-.*$//'`"
+ ;;
+ esac
;;
esac
@@ -3532,7 +3546,7 @@ case "${target}" in
;;
mips*-*-*)
- supported_defaults="abi arch arch_32 arch_64 float fpu tune tune_32 tune_64 divide llsc mips-plt synci"
+ supported_defaults="abi arch arch_32 arch_64 float fpu nan tune tune_32 tune_64 divide llsc mips-plt synci"
case ${with_float} in
"" | soft | hard)
@@ -3554,6 +3568,16 @@ case "${target}" in
;;
esac
+ case ${with_nan} in
+ "" | 2008 | legacy)
+ # OK
+ ;;
+ *)
+ echo "Unknown NaN encoding used in --with-nan=$with_nan" 1>&2
+ exit 1
+ ;;
+ esac
+
case ${with_abi} in
"" | 32 | o64 | n32 | 64 | eabi)
# OK
@@ -3913,7 +3937,7 @@ case ${target} in
esac
t=
-all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu divide llsc mips-plt synci tls"
+all_defaults="abi cpu cpu_32 cpu_64 arch arch_32 arch_64 tune tune_32 tune_64 schedule float mode fpu nan divide llsc mips-plt synci tls"
for option in $all_defaults
do
eval "val=\$with_"`echo $option | sed s/-/_/g`
diff --git a/gcc/config.in b/gcc/config.in
index 288c11f9377..44f9a320c27 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -387,6 +387,12 @@
#endif
+/* Define if your assembler supports LEON instructions. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_LEON
+#endif
+
+
/* Define if the assembler won't complain about a line such as # 0 "" 2. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_LINE_ZERO
@@ -417,6 +423,12 @@
#endif
+/* Define if the assembler understands -mnan=. */
+#ifndef USED_FOR_TARGET
+#undef HAVE_AS_NAN
+#endif
+
+
/* Define if your assembler supports the -no-mul-bug-abort option. */
#ifndef USED_FOR_TARGET
#undef HAVE_AS_NO_MUL_BUG_ABORT_OPTION
diff --git a/gcc/config/aarch64/aarch64-option-extensions.def b/gcc/config/aarch64/aarch64-option-extensions.def
index 58e815471a6..371e74c7f94 100644
--- a/gcc/config/aarch64/aarch64-option-extensions.def
+++ b/gcc/config/aarch64/aarch64-option-extensions.def
@@ -35,3 +35,4 @@
AARCH64_OPT_EXTENSION("fp", AARCH64_FL_FP, AARCH64_FL_FPSIMD | AARCH64_FL_CRYPTO)
AARCH64_OPT_EXTENSION("simd", AARCH64_FL_FPSIMD, AARCH64_FL_SIMD | AARCH64_FL_CRYPTO)
AARCH64_OPT_EXTENSION("crypto", AARCH64_FL_CRYPTO | AARCH64_FL_FPSIMD, AARCH64_FL_CRYPTO)
+AARCH64_OPT_EXTENSION("crc", AARCH64_FL_CRC, AARCH64_FL_CRC)
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def
index 55dead6e404..4046d7a7001 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -40,10 +40,6 @@
10 - CODE_FOR_<name><mode>. */
BUILTIN_VD_RE (CREATE, create, 0)
- BUILTIN_VQ_S (GETLANE, get_lane_signed, 0)
- BUILTIN_VDQ (GETLANE, get_lane_unsigned, 0)
- BUILTIN_VDQF (GETLANE, get_lane, 0)
- VAR1 (GETLANE, get_lane, 0, di)
BUILTIN_VDC (COMBINE, combine, 0)
BUILTIN_VB (BINOP, pmul, 0)
BUILTIN_VDQF (UNOP, sqrt, 2)
@@ -51,6 +47,9 @@
VAR1 (UNOP, addp, 0, di)
VAR1 (UNOP, clz, 2, v4si)
+ BUILTIN_VALL (GETLANE, get_lane, 0)
+ VAR1 (GETLANE, get_lane, 0, di)
+
BUILTIN_VD_RE (REINTERP, reinterpretdi, 0)
BUILTIN_VDC (REINTERP, reinterpretv8qi, 0)
BUILTIN_VDC (REINTERP, reinterpretv4hi, 0)
@@ -64,7 +63,6 @@
BUILTIN_VQ (REINTERP, reinterpretv2df, 0)
BUILTIN_VDQ_I (BINOP, dup_lane, 0)
- BUILTIN_VDQ_I (BINOP, dup_lane_scalar, 0)
/* Implemented by aarch64_<sur>q<r>shl<mode>. */
BUILTIN_VSDQ_I (BINOP, sqshl, 0)
BUILTIN_VSDQ_I (BINOP, uqshl, 0)
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 178efdc964e..9805197a22b 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -336,46 +336,47 @@
})
(define_insn "aarch64_simd_dup<mode>"
- [(set (match_operand:VDQ 0 "register_operand" "=w")
- (vec_duplicate:VDQ (match_operand:<VEL> 1 "register_operand" "r")))]
+ [(set (match_operand:VDQ 0 "register_operand" "=w, w")
+ (vec_duplicate:VDQ (match_operand:<VEL> 1 "register_operand" "r, w")))]
"TARGET_SIMD"
- "dup\\t%0.<Vtype>, %<vw>1"
- [(set_attr "simd_type" "simd_dupgp")
+ "@
+ dup\\t%0.<Vtype>, %<vw>1
+ dup\\t%0.<Vtype>, %1.<Vetype>[0]"
+ [(set_attr "simd_type" "simd_dupgp, simd_dup")
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "aarch64_dup_lane<mode>"
- [(set (match_operand:VDQ_I 0 "register_operand" "=w")
- (vec_duplicate:VDQ_I
- (vec_select:<VEL>
- (match_operand:<VCON> 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")])
- )))]
+(define_insn "aarch64_simd_dup<mode>"
+ [(set (match_operand:VDQF 0 "register_operand" "=w")
+ (vec_duplicate:VDQF (match_operand:<VEL> 1 "register_operand" "w")))]
"TARGET_SIMD"
- "dup\\t%<v>0<Vmtype>, %1.<Vetype>[%2]"
+ "dup\\t%0.<Vtype>, %1.<Vetype>[0]"
[(set_attr "simd_type" "simd_dup")
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "aarch64_dup_lane_scalar<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=w, r")
- (vec_select:<VEL>
- (match_operand:VDQ 1 "register_operand" "w, w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i, i")])
- ))]
+(define_insn "aarch64_dup_lane<mode>"
+ [(set (match_operand:VALL 0 "register_operand" "=w")
+ (vec_duplicate:VALL
+ (vec_select:<VEL>
+ (match_operand:VALL 1 "register_operand" "w")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i")])
+ )))]
"TARGET_SIMD"
- "@
- dup\\t%<Vetype>0, %1.<Vetype>[%2]
- umov\\t%<vw>0, %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_dup, simd_movgp")
+ "dup\\t%0.<Vtype>, %1.<Vetype>[%2]"
+ [(set_attr "simd_type" "simd_dup")
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "aarch64_simd_dup<mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (vec_duplicate:VDQF (match_operand:<VEL> 1 "register_operand" "w")))]
+(define_insn "aarch64_dup_lane_<vswap_width_name><mode>"
+ [(set (match_operand:VALL 0 "register_operand" "=w")
+ (vec_duplicate:VALL
+ (vec_select:<VEL>
+ (match_operand:<VSWAP_WIDTH> 1 "register_operand" "w")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i")])
+ )))]
"TARGET_SIMD"
- "dup\\t%0.<Vtype>, %1.<Vetype>[0]"
+ "dup\\t%0.<Vtype>, %1.<Vetype>[%2]"
[(set_attr "simd_type" "simd_dup")
(set_attr "simd_mode" "<MODE>")]
)
@@ -1051,6 +1052,7 @@
fmov\\t%d0, %1
dup\\t%d0, %1"
[(set_attr "v8type" "*,fmov,*")
+ (set_attr "type" "*,fmov,*")
(set_attr "simd_type" "simd_dup,*,simd_dup")
(set_attr "simd_mode" "<MODE>")
(set_attr "simd" "yes,*,yes")
@@ -2146,45 +2148,50 @@
DONE;
})
-(define_insn "aarch64_get_lane_signed<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=r")
- (sign_extend:<VEL>
+;; Lane extraction with sign extension to general purpose register.
+(define_insn "*aarch64_get_lane_extend<GPI:mode><VDQQH:mode>"
+ [(set (match_operand:GPI 0 "register_operand" "=r")
+ (sign_extend:GPI
(vec_select:<VEL>
- (match_operand:VQ_S 1 "register_operand" "w")
+ (match_operand:VDQQH 1 "register_operand" "w")
(parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
"TARGET_SIMD"
- "smov\\t%0, %1.<Vetype>[%2]"
+ "smov\\t%<GPI:w>0, %1.<VDQQH:Vetype>[%2]"
[(set_attr "simd_type" "simd_movgp")
- (set_attr "simd_mode" "<MODE>")]
+ (set_attr "simd_mode" "<VDQQH:MODE>")]
)
-(define_insn "aarch64_get_lane_unsigned<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=r")
- (zero_extend:<VEL>
+(define_insn "*aarch64_get_lane_zero_extendsi<mode>"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (zero_extend:SI
(vec_select:<VEL>
- (match_operand:VDQ 1 "register_operand" "w")
+ (match_operand:VDQQH 1 "register_operand" "w")
(parallel [(match_operand:SI 2 "immediate_operand" "i")]))))]
"TARGET_SIMD"
- "umov\\t%<vw>0, %1.<Vetype>[%2]"
+ "umov\\t%w0, %1.<Vetype>[%2]"
[(set_attr "simd_type" "simd_movgp")
(set_attr "simd_mode" "<MODE>")]
)
+;; Lane extraction of a value, neither sign nor zero extension
+;; is guaranteed so upper bits should be considered undefined.
(define_insn "aarch64_get_lane<mode>"
- [(set (match_operand:<VEL> 0 "register_operand" "=w")
+ [(set (match_operand:<VEL> 0 "register_operand" "=r, w")
(vec_select:<VEL>
- (match_operand:VDQF 1 "register_operand" "w")
- (parallel [(match_operand:SI 2 "immediate_operand" "i")])))]
+ (match_operand:VALL 1 "register_operand" "w, w")
+ (parallel [(match_operand:SI 2 "immediate_operand" "i, i")])))]
"TARGET_SIMD"
- "mov\\t%0.<Vetype>[0], %1.<Vetype>[%2]"
- [(set_attr "simd_type" "simd_ins")
+ "@
+ umov\\t%<vwcore>0, %1.<Vetype>[%2]
+ dup\\t%<Vetype>0, %1.<Vetype>[%2]"
+ [(set_attr "simd_type" "simd_movgp, simd_dup")
(set_attr "simd_mode" "<MODE>")]
)
(define_expand "aarch64_get_lanedi"
- [(match_operand:DI 0 "register_operand" "=r")
- (match_operand:DI 1 "register_operand" "w")
- (match_operand:SI 2 "immediate_operand" "i")]
+ [(match_operand:DI 0 "register_operand")
+ (match_operand:DI 1 "register_operand")
+ (match_operand:SI 2 "immediate_operand")]
"TARGET_SIMD"
{
aarch64_simd_lane_bounds (operands[2], 0, 1);
@@ -2790,7 +2797,7 @@
(match_operand:VD_HSI 2 "register_operand" "w"))
(sign_extend:<VWIDE>
(vec_duplicate:VD_HSI
- (match_operand:<VEL> 3 "register_operand" "w"))))
+ (match_operand:<VEL> 3 "register_operand" "<vwx>"))))
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
@@ -2948,7 +2955,7 @@
(match_operand:VQ_HSI 4 "vect_par_cnst_hi_half" "")))
(sign_extend:<VWIDE>
(vec_duplicate:<VHALF>
- (match_operand:<VEL> 3 "register_operand" "w"))))
+ (match_operand:<VEL> 3 "register_operand" "<vwx>"))))
(const_int 1))))]
"TARGET_SIMD"
"sqdml<SBINQOPS:as>l2\\t%<vw2>0<Vmwtype>, %<v>2<Vmtype>, %3.<Vetype>[0]"
@@ -3076,7 +3083,7 @@
(match_operand:VD_HSI 1 "register_operand" "w"))
(sign_extend:<VWIDE>
(vec_duplicate:VD_HSI
- (match_operand:<VEL> 2 "register_operand" "w")))
+ (match_operand:<VEL> 2 "register_operand" "<vwx>")))
)
(const_int 1)))]
"TARGET_SIMD"
@@ -3186,7 +3193,7 @@
(match_operand:VQ_HSI 3 "vect_par_cnst_hi_half" "")))
(sign_extend:<VWIDE>
(vec_duplicate:<VHALF>
- (match_operand:<VEL> 2 "register_operand" "w")))
+ (match_operand:<VEL> 2 "register_operand" "<vwx>")))
)
(const_int 1)))]
"TARGET_SIMD"
@@ -4172,13 +4179,23 @@
(set_attr "simd_mode" "<MODE>")]
)
+(define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
+ [(set (match_operand:GPF 0 "register_operand" "=w")
+ (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
+ FRECP))]
+ "TARGET_SIMD"
+ "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
+ [(set_attr "simd_type" "simd_frecp<FRECP:frecp_suffix>")
+ (set_attr "mode" "<MODE>")]
+)
+
(define_insn "aarch64_frecps<mode>"
- [(set (match_operand:VDQF 0 "register_operand" "=w")
- (unspec:VDQF [(match_operand:VDQF 1 "register_operand" "w")
- (match_operand:VDQF 2 "register_operand" "w")]
+ [(set (match_operand:VALLF 0 "register_operand" "=w")
+ (unspec:VALLF [(match_operand:VALLF 1 "register_operand" "w")
+ (match_operand:VALLF 2 "register_operand" "w")]
UNSPEC_FRECPS))]
"TARGET_SIMD"
- "frecps\\t%0.<Vtype>, %1.<Vtype>, %2.<Vtype>"
+ "frecps\\t%<v>0<Vmtype>, %<v>1<Vmtype>, %<v>2<Vmtype>"
[(set_attr "simd_type" "simd_frecps")
(set_attr "simd_mode" "<MODE>")]
)
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index aed035a434e..7635e1e2679 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -7932,6 +7932,55 @@ aarch64_evpc_zip (struct expand_vec_perm_d *d)
}
static bool
+aarch64_evpc_dup (struct expand_vec_perm_d *d)
+{
+ rtx (*gen) (rtx, rtx, rtx);
+ rtx out = d->target;
+ rtx in0;
+ enum machine_mode vmode = d->vmode;
+ unsigned int i, elt, nelt = d->nelt;
+ rtx lane;
+
+ /* TODO: This may not be big-endian safe. */
+ if (BYTES_BIG_ENDIAN)
+ return false;
+
+ elt = d->perm[0];
+ for (i = 1; i < nelt; i++)
+ {
+ if (elt != d->perm[i])
+ return false;
+ }
+
+ /* The generic preparation in aarch64_expand_vec_perm_const_1
+ swaps the operand order and the permute indices if it finds
+ d->perm[0] to be in the second operand. Thus, we can always
+ use d->op0 and need not do any extra arithmetic to get the
+ correct lane number. */
+ in0 = d->op0;
+ lane = GEN_INT (elt);
+
+ switch (vmode)
+ {
+ case V16QImode: gen = gen_aarch64_dup_lanev16qi; break;
+ case V8QImode: gen = gen_aarch64_dup_lanev8qi; break;
+ case V8HImode: gen = gen_aarch64_dup_lanev8hi; break;
+ case V4HImode: gen = gen_aarch64_dup_lanev4hi; break;
+ case V4SImode: gen = gen_aarch64_dup_lanev4si; break;
+ case V2SImode: gen = gen_aarch64_dup_lanev2si; break;
+ case V2DImode: gen = gen_aarch64_dup_lanev2di; break;
+ case V4SFmode: gen = gen_aarch64_dup_lanev4sf; break;
+ case V2SFmode: gen = gen_aarch64_dup_lanev2sf; break;
+ case V2DFmode: gen = gen_aarch64_dup_lanev2df; break;
+ default:
+ return false;
+ }
+
+ emit_insn (gen (out, in0, lane));
+ return true;
+}
+
+static bool
aarch64_evpc_tbl (struct expand_vec_perm_d *d)
{
rtx rperm[MAX_VECT_LEN], sel;
@@ -7988,6 +8037,8 @@ aarch64_expand_vec_perm_const_1 (struct expand_vec_perm_d *d)
return true;
else if (aarch64_evpc_trn (d))
return true;
+ else if (aarch64_evpc_dup (d))
+ return true;
return aarch64_evpc_tbl (d);
}
return false;
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 092426973c6..d8012f88049 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -158,6 +158,7 @@
#define AARCH64_FL_FP (1 << 1) /* Has FP. */
#define AARCH64_FL_CRYPTO (1 << 2) /* Has crypto. */
#define AARCH64_FL_SLOWMUL (1 << 3) /* A slow multiply core. */
+#define AARCH64_FL_CRC (1 << 4) /* Has CRC. */
/* Has FP and SIMD. */
#define AARCH64_FL_FPSIMD (AARCH64_FL_FP | AARCH64_FL_SIMD)
@@ -170,6 +171,7 @@
/* Macros to test ISA flags. */
extern unsigned long aarch64_isa_flags;
+#define AARCH64_ISA_CRC (aarch64_isa_flags & AARCH64_FL_CRC)
#define AARCH64_ISA_CRYPTO (aarch64_isa_flags & AARCH64_FL_CRYPTO)
#define AARCH64_ISA_FP (aarch64_isa_flags & AARCH64_FL_FP)
#define AARCH64_ISA_SIMD (aarch64_isa_flags & AARCH64_FL_SIMD)
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 5d64228351b..f37f98f9994 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -88,11 +88,16 @@
UNSPEC_NOP
UNSPEC_PRLG_STK
UNSPEC_RBIT
+ UNSPEC_SISD_NEG
+ UNSPEC_SISD_SSHL
+ UNSPEC_SISD_USHL
+ UNSPEC_SSHL_2S
UNSPEC_ST2
UNSPEC_ST3
UNSPEC_ST4
UNSPEC_TLS
UNSPEC_TLSDESC
+ UNSPEC_USHL_2S
UNSPEC_VSTRUCTDUMMY
])
@@ -235,9 +240,6 @@
fmovf2i,\
fmovi2f,\
fmul,\
- frecpe,\
- frecps,\
- frecpx,\
frint,\
fsqrt,\
load_acq,\
@@ -272,48 +274,9 @@
udiv"
(const_string "alu"))
-
-; The "type" attribute is used by the AArch32 backend. Below is a mapping
-; from "v8type" to "type".
-
-(define_attr "type"
- "alu,alu_shift,block,branch,call,f_2_r,f_cvt,f_flag,f_loads,
- f_loadd,f_stored,f_stores,faddd,fadds,fcmpd,fcmps,fconstd,fconsts,
- fcpys,fdivd,fdivs,ffarithd,ffariths,fmacd,fmacs,fmuld,fmuls,load_byte,
- load1,load2,mult,r_2_f,store1,store2"
- (cond [
- (eq_attr "v8type" "alu_shift,alus_shift,logic_shift,logics_shift") (const_string "alu_shift")
- (eq_attr "v8type" "branch") (const_string "branch")
- (eq_attr "v8type" "call") (const_string "call")
- (eq_attr "v8type" "fmovf2i") (const_string "f_2_r")
- (eq_attr "v8type" "fcvt,fcvtf2i,fcvti2f") (const_string "f_cvt")
- (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "SF")) (const_string "f_loads")
- (and (eq_attr "v8type" "fpsimd_load") (eq_attr "mode" "DF")) (const_string "f_loadd")
- (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "SF")) (const_string "f_stores")
- (and (eq_attr "v8type" "fpsimd_store") (eq_attr "mode" "DF")) (const_string "f_stored")
- (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "DF")) (const_string "faddd")
- (and (eq_attr "v8type" "fadd,fminmax") (eq_attr "mode" "SF")) (const_string "fadds")
- (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "DF")) (const_string "fcmpd")
- (and (eq_attr "v8type" "fcmp,fccmp") (eq_attr "mode" "SF")) (const_string "fcmps")
- (and (eq_attr "v8type" "fconst") (eq_attr "mode" "DF")) (const_string "fconstd")
- (and (eq_attr "v8type" "fconst") (eq_attr "mode" "SF")) (const_string "fconsts")
- (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "DF")) (const_string "fdivd")
- (and (eq_attr "v8type" "fdiv,fsqrt") (eq_attr "mode" "SF")) (const_string "fdivs")
- (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "DF")) (const_string "ffarithd")
- (and (eq_attr "v8type" "ffarith") (eq_attr "mode" "SF")) (const_string "ffariths")
- (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "DF")) (const_string "fmacd")
- (and (eq_attr "v8type" "fmadd") (eq_attr "mode" "SF")) (const_string "fmacs")
- (and (eq_attr "v8type" "fmul") (eq_attr "mode" "DF")) (const_string "fmuld")
- (and (eq_attr "v8type" "fmul") (eq_attr "mode" "SF")) (const_string "fmuls")
- (and (eq_attr "v8type" "load1") (eq_attr "mode" "QI,HI")) (const_string "load_byte")
- (and (eq_attr "v8type" "load1") (eq_attr "mode" "SI,DI,TI")) (const_string "load1")
- (eq_attr "v8type" "load2") (const_string "load2")
- (and (eq_attr "v8type" "mulh,mult,mull,madd,sdiv,udiv") (eq_attr "mode" "SI")) (const_string "mult")
- (eq_attr "v8type" "fmovi2f") (const_string "r_2_f")
- (eq_attr "v8type" "store1") (const_string "store1")
- (eq_attr "v8type" "store2") (const_string "store2")
- ]
- (const_string "alu")))
+; The "type" attribute is is included here from AArch32 backend to be able
+; to share pipeline descriptions.
+(include "../arm/types.md")
;; Attribute that specifies whether or not the instruction touches fp
;; registers.
@@ -349,6 +312,7 @@
(include "aarch64-generic.md")
(include "large.md")
(include "small.md")
+(include "../arm/cortex-a53.md")
;; -------------------------------------------------------------------
;; Jumps and other miscellaneous insns
@@ -358,14 +322,16 @@
[(set (pc) (match_operand:DI 0 "register_operand" "r"))]
""
"br\\t%0"
- [(set_attr "v8type" "branch")]
+ [(set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
)
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
"b\\t%l0"
- [(set_attr "v8type" "branch")]
+ [(set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
)
(define_expand "cbranch<mode>4"
@@ -403,7 +369,8 @@
(pc)))]
""
"b%m0\\t%l2"
- [(set_attr "v8type" "branch")]
+ [(set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
)
(define_expand "casesi"
@@ -467,7 +434,8 @@
return aarch64_output_casesi (operands);
"
[(set_attr "length" "16")
- (set_attr "v8type" "branch")]
+ (set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
)
(define_insn "nop"
@@ -508,7 +476,8 @@
[(return)]
""
"ret"
- [(set_attr "v8type" "branch")]
+ [(set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
)
(define_insn "eh_return"
@@ -516,7 +485,9 @@
UNSPECV_EH_RETURN)]
""
"#"
- [(set_attr "v8type" "branch")]
+ [(set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
+
)
(define_split
@@ -536,7 +507,9 @@
(pc)))]
""
"<cbz>\\t%<w>0, %l1"
- [(set_attr "v8type" "branch")]
+ [(set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
+
)
(define_insn "*tb<optab><mode>1"
@@ -555,6 +528,7 @@
return \"<tbz>\\t%<w>0, %1, %l2\";
"
[(set_attr "v8type" "branch")
+ (set_attr "type" "branch")
(set_attr "mode" "<MODE>")
(set (attr "length")
(if_then_else (and (ge (minus (match_dup 2) (pc)) (const_int -32768))
@@ -576,6 +550,7 @@
return \"<tbz>\\t%<w>0, <sizem1>, %l1\";
"
[(set_attr "v8type" "branch")
+ (set_attr "type" "branch")
(set_attr "mode" "<MODE>")
(set (attr "length")
(if_then_else (and (ge (minus (match_dup 1) (pc)) (const_int -32768))
@@ -620,7 +595,8 @@
(clobber (reg:DI LR_REGNUM))]
""
"blr\\t%0"
- [(set_attr "v8type" "call")]
+ [(set_attr "v8type" "call")
+ (set_attr "type" "call")]
)
(define_insn "*call_symbol"
@@ -631,7 +607,8 @@
"GET_CODE (operands[0]) == SYMBOL_REF
&& !aarch64_is_long_call_p (operands[0])"
"bl\\t%a0"
- [(set_attr "v8type" "call")]
+ [(set_attr "v8type" "call")
+ (set_attr "type" "call")]
)
(define_expand "call_value"
@@ -668,7 +645,9 @@
(clobber (reg:DI LR_REGNUM))]
""
"blr\\t%1"
- [(set_attr "v8type" "call")]
+ [(set_attr "v8type" "call")
+ (set_attr "type" "call")]
+
)
(define_insn "*call_value_symbol"
@@ -680,7 +659,8 @@
"GET_CODE (operands[1]) == SYMBOL_REF
&& !aarch64_is_long_call_p (operands[1])"
"bl\\t%a1"
- [(set_attr "v8type" "call")]
+ [(set_attr "v8type" "call")
+ (set_attr "type" "call")]
)
(define_expand "sibcall"
@@ -715,7 +695,9 @@
(use (match_operand 2 "" ""))]
"GET_CODE (operands[0]) == SYMBOL_REF"
"b\\t%a0"
- [(set_attr "v8type" "branch")]
+ [(set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
+
)
(define_insn "*sibcall_value_insn"
@@ -726,7 +708,8 @@
(use (match_operand 3 "" ""))]
"GET_CODE (operands[1]) == SYMBOL_REF"
"b\\t%a1"
- [(set_attr "v8type" "branch")]
+ [(set_attr "v8type" "branch")
+ (set_attr "type" "branch")]
)
;; Call subroutine returning any type.
@@ -804,6 +787,7 @@
}
}
[(set_attr "v8type" "move,alu,alu,load1,load1,store1,store1,*,*,*")
+ (set_attr "type" "mov_reg,mov_imm,mov_imm,load1,load1,store1,store1,*,*,*")
(set_attr "simd_type" "*,*,simd_move_imm,*,*,*,*,simd_movgp,simd_dupgp,simd_dup")
(set_attr "simd" "*,*,yes,*,*,*,*,yes,yes,yes")
(set_attr "mode" "<MODE>")
@@ -846,6 +830,8 @@
fmov\\t%w0, %s1
fmov\\t%s0, %s1"
[(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov")
+ (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
+ adr,adr,fmov,fmov,fmov")
(set_attr "mode" "SI")
(set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes")]
)
@@ -871,6 +857,8 @@
fmov\\t%d0, %d1
movi\\t%d0, %1"
[(set_attr "v8type" "move,move,move,alu,load1,load1,store1,store1,adr,adr,fmov,fmov,fmov,fmov")
+ (set_attr "type" "mov_reg,mov_reg,mov_reg,mov_imm,load1,load1,store1,store1,\
+ adr,adr,fmov,fmov,fmov,fmov")
(set_attr "mode" "DI")
(set_attr "fp" "*,*,*,*,*,yes,*,yes,*,*,yes,yes,yes,*")
(set_attr "simd" "*,*,*,*,*,*,*,*,*,*,*,*,*,yes")]
@@ -885,6 +873,7 @@
&& UINTVAL (operands[1]) % 16 == 0"
"movk\\t%<w>0, %X2, lsl %1"
[(set_attr "v8type" "movk")
+ (set_attr "type" "mov_imm")
(set_attr "mode" "<MODE>")]
)
@@ -917,6 +906,8 @@
str\\t%q1, %0"
[(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
load2,store2,store2,fpsimd_load,fpsimd_store")
+ (set_attr "type" "multiple,f_mcr,f_mrc,*, \
+ load2,store2,store2,f_loadd,f_stored")
(set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
(set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
(set_attr "length" "8,8,8,4,4,4,4,4,4")
@@ -970,6 +961,8 @@
[(set_attr "v8type" "fmovi2f,fmovf2i,\
fmov,fconst,fpsimd_load,\
fpsimd_store,fpsimd_load,fpsimd_store,fmov")
+ (set_attr "type" "f_mcr,f_mrc,fmov,fconsts,\
+ f_loads,f_stores,f_loads,f_stores,fmov")
(set_attr "mode" "SF")]
)
@@ -991,6 +984,8 @@
[(set_attr "v8type" "fmovi2f,fmovf2i,\
fmov,fconst,fpsimd_load,\
fpsimd_store,fpsimd_load,fpsimd_store,move")
+ (set_attr "type" "f_mcr,f_mrc,fmov,fconstd,\
+ f_loadd,f_stored,f_loadd,f_stored,mov_reg")
(set_attr "mode" "DF")]
)
@@ -1029,6 +1024,8 @@
ldp\\t%0, %H0, %1
stp\\t%1, %H1, %0"
[(set_attr "v8type" "logic,move2,fmovi2f,fmovf2i,fconst,fconst,fpsimd_load,fpsimd_store,fpsimd_load2,fpsimd_store2")
+ (set_attr "type" "logic_reg,multiple,f_mcr,f_mrc,fconstd,fconstd,\
+ f_loadd,f_stored,neon_ldm_2,neon_stm_2")
(set_attr "mode" "DF,DF,DF,DF,DF,DF,TF,TF,DF,DF")
(set_attr "length" "4,8,8,8,4,4,4,4,4,4")
(set_attr "fp" "*,*,yes,yes,*,yes,yes,yes,*,*")
@@ -1059,6 +1056,7 @@
GET_MODE_SIZE (<MODE>mode)))"
"ldp\\t%<w>0, %<w>2, %1"
[(set_attr "v8type" "load2")
+ (set_attr "type" "load2")
(set_attr "mode" "<MODE>")]
)
@@ -1075,6 +1073,7 @@
GET_MODE_SIZE (<MODE>mode)))"
"stp\\t%<w>1, %<w>3, %0"
[(set_attr "v8type" "store2")
+ (set_attr "type" "store2")
(set_attr "mode" "<MODE>")]
)
@@ -1091,6 +1090,7 @@
GET_MODE_SIZE (<MODE>mode)))"
"ldp\\t%<w>0, %<w>2, %1"
[(set_attr "v8type" "fpsimd_load2")
+ (set_attr "type" "neon_ldm_2")
(set_attr "mode" "<MODE>")]
)
@@ -1106,7 +1106,8 @@
XEXP (operands[0], 0),
GET_MODE_SIZE (<MODE>mode)))"
"stp\\t%<w>1, %<w>3, %0"
- [(set_attr "v8type" "fpsimd_load2")
+ [(set_attr "v8type" "fpsimd_store2")
+ (set_attr "type" "neon_stm_2")
(set_attr "mode" "<MODE>")]
)
@@ -1126,6 +1127,7 @@
"INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
"ldp\\t%<w>2, %<w>3, [%1], %4"
[(set_attr "v8type" "load2")
+ (set_attr "type" "load2")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1145,6 +1147,7 @@
"INTVAL (operands[5]) == INTVAL (operands[4]) + GET_MODE_SIZE (<GPI:MODE>mode)"
"stp\\t%<w>2, %<w>3, [%0, %4]!"
[(set_attr "v8type" "store2")
+ (set_attr "type" "store2")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1166,6 +1169,7 @@
sxtw\t%0, %w1
ldrsw\t%0, %1"
[(set_attr "v8type" "extend,load1")
+ (set_attr "type" "extend,load1")
(set_attr "mode" "DI")]
)
@@ -1177,6 +1181,7 @@
uxtw\t%0, %w1
ldr\t%w0, %1"
[(set_attr "v8type" "extend,load1")
+ (set_attr "type" "extend,load1")
(set_attr "mode" "DI")]
)
@@ -1194,6 +1199,7 @@
sxt<SHORT:size>\t%<GPI:w>0, %w1
ldrs<SHORT:size>\t%<GPI:w>0, %1"
[(set_attr "v8type" "extend,load1")
+ (set_attr "type" "extend,load1")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1206,6 +1212,7 @@
ldr<SHORT:size>\t%w0, %1
ldr\t%<SHORT:size>0, %1"
[(set_attr "v8type" "extend,load1,load1")
+ (set_attr "type" "extend,load1,load1")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1223,6 +1230,7 @@
<su>xtb\t%w0, %w1
<ldrxt>b\t%w0, %1"
[(set_attr "v8type" "extend,load1")
+ (set_attr "type" "extend,load1")
(set_attr "mode" "HI")]
)
@@ -1267,6 +1275,7 @@
add\\t%w0, %w1, %w2
sub\\t%w0, %w1, #%n2"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_imm,alu_reg,alu_imm")
(set_attr "mode" "SI")]
)
@@ -1283,6 +1292,7 @@
add\\t%w0, %w1, %w2
sub\\t%w0, %w1, #%n2"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_imm,alu_reg,alu_imm")
(set_attr "mode" "SI")]
)
@@ -1299,6 +1309,7 @@
sub\\t%x0, %x1, #%n2
add\\t%d0, %d1, %d2"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_imm,alu_reg,alu_imm,alu_reg")
(set_attr "mode" "DI")
(set_attr "simd" "*,*,*,yes")]
)
@@ -1306,16 +1317,18 @@
(define_insn "*add<mode>3_compare0"
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ
- (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r")
- (match_operand:GPI 2 "aarch64_plus_operand" "rI,J"))
+ (plus:GPI (match_operand:GPI 1 "register_operand" "%r,r,r")
+ (match_operand:GPI 2 "aarch64_plus_operand" "r,I,J"))
(const_int 0)))
- (set (match_operand:GPI 0 "register_operand" "=r,r")
+ (set (match_operand:GPI 0 "register_operand" "=r,r,r")
(plus:GPI (match_dup 1) (match_dup 2)))]
""
"@
adds\\t%<w>0, %<w>1, %<w>2
+ adds\\t%<w>0, %<w>1, %<w>2
subs\\t%<w>0, %<w>1, #%n2"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg,alus_imm,alus_imm")
(set_attr "mode" "<MODE>")]
)
@@ -1323,16 +1336,18 @@
(define_insn "*addsi3_compare0_uxtw"
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ
- (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
- (match_operand:SI 2 "aarch64_plus_operand" "rI,J"))
+ (plus:SI (match_operand:SI 1 "register_operand" "%r,r,r")
+ (match_operand:SI 2 "aarch64_plus_operand" "r,I,J"))
(const_int 0)))
- (set (match_operand:DI 0 "register_operand" "=r,r")
+ (set (match_operand:DI 0 "register_operand" "=r,r,r")
(zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
""
"@
adds\\t%w0, %w1, %w2
+ adds\\t%w0, %w1, %w2
subs\\t%w0, %w1, #%n2"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg,alus_imm,alus_imm")
(set_attr "mode" "SI")]
)
@@ -1350,6 +1365,7 @@
""
"adds\\t%<w>0, %<w>3, %<w>1, lsl %p2"
[(set_attr "v8type" "alus_shift")
+ (set_attr "type" "alus_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -1367,6 +1383,7 @@
""
"subs\\t%<w>0, %<w>1, %<w>2, lsl %p3"
[(set_attr "v8type" "alus_shift")
+ (set_attr "type" "alus_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -1382,6 +1399,7 @@
""
"adds\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
[(set_attr "v8type" "alus_ext")
+ (set_attr "type" "alus_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1397,6 +1415,7 @@
""
"subs\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
[(set_attr "v8type" "alus_ext")
+ (set_attr "type" "alus_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1418,6 +1437,7 @@
"aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
"adds\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
[(set_attr "v8type" "alus_ext")
+ (set_attr "type" "alus_ext")
(set_attr "mode" "<MODE>")]
)
@@ -1439,20 +1459,23 @@
"aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
"subs\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
[(set_attr "v8type" "alus_ext")
+ (set_attr "type" "alus_ext")
(set_attr "mode" "<MODE>")]
)
(define_insn "*add<mode>3nr_compare0"
[(set (reg:CC_NZ CC_REGNUM)
(compare:CC_NZ
- (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r")
- (match_operand:GPI 1 "aarch64_plus_operand" "rI,J"))
+ (plus:GPI (match_operand:GPI 0 "register_operand" "%r,r,r")
+ (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J"))
(const_int 0)))]
""
"@
cmn\\t%<w>0, %<w>1
+ cmn\\t%<w>0, %<w>1
cmp\\t%<w>0, #%n1"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg,alus_imm,alus_imm")
(set_attr "mode" "<MODE>")]
)
@@ -1464,6 +1487,7 @@
""
"cmn\\t%<w>0, %<w>1"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg")
(set_attr "mode" "<MODE>")]
)
@@ -1475,6 +1499,7 @@
""
"add\\t%<w>0, %<w>3, %<w>1, <shift> %2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -1488,6 +1513,7 @@
""
"add\\t%w0, %w3, %w1, <shift> %2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "SI")]
)
@@ -1499,6 +1525,7 @@
""
"add\\t%<w>0, %<w>3, %<w>1, lsl %p2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -1509,6 +1536,7 @@
""
"add\\t%<GPI:w>0, %<GPI:w>2, %<GPI:w>1, <su>xt<ALLX:size>"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1521,6 +1549,7 @@
""
"add\\t%w0, %w2, %w1, <su>xt<SHORT:size>"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -1533,6 +1562,7 @@
""
"add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %2"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1547,6 +1577,7 @@
""
"add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %2"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -1559,6 +1590,7 @@
""
"add\\t%<GPI:w>0, %<GPI:w>3, %<GPI:w>1, <su>xt<ALLX:size> %p2"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1572,6 +1604,7 @@
""
"add\\t%w0, %w3, %w1, <su>xt<SHORT:size> %p2"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -1586,6 +1619,7 @@
"aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
"add\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<MODE>")]
)
@@ -1602,6 +1636,7 @@
"aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
"add\\t%w0, %w4, %w1, <su>xt%e3 %p2"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -1615,6 +1650,7 @@
""
"adc\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "<MODE>")]
)
@@ -1630,6 +1666,7 @@
""
"adc\\t%w0, %w1, %w2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "SI")]
)
@@ -1643,6 +1680,7 @@
""
"adc\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "<MODE>")]
)
@@ -1658,6 +1696,7 @@
""
"adc\\t%w0, %w1, %w2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "SI")]
)
@@ -1671,6 +1710,7 @@
""
"adc\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "<MODE>")]
)
@@ -1686,6 +1726,7 @@
""
"adc\\t%w0, %w1, %w2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "SI")]
)
@@ -1699,6 +1740,7 @@
""
"adc\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "<MODE>")]
)
@@ -1714,6 +1756,7 @@
""
"adc\\t%w0, %w1, %w2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "SI")]
)
@@ -1730,6 +1773,7 @@
INTVAL (operands[3])));
return \"add\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<MODE>")]
)
@@ -1748,6 +1792,7 @@
INTVAL (operands[3])));
return \"add\t%w0, %w4, %w1, uxt%e3 %p2\";"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -1758,6 +1803,7 @@
""
"sub\\t%w0, %w1, %w2"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_reg")
(set_attr "mode" "SI")]
)
@@ -1770,6 +1816,7 @@
""
"sub\\t%w0, %w1, %w2"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_reg")
(set_attr "mode" "SI")]
)
@@ -1782,6 +1829,7 @@
sub\\t%x0, %x1, %x2
sub\\t%d0, %d1, %d2"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_reg")
(set_attr "mode" "DI")
(set_attr "simd" "*,yes")]
)
@@ -1797,6 +1845,7 @@
""
"subs\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg")
(set_attr "mode" "<MODE>")]
)
@@ -1811,6 +1860,7 @@
""
"subs\\t%w0, %w1, %w2"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg")
(set_attr "mode" "SI")]
)
@@ -1823,6 +1873,7 @@
""
"sub\\t%<w>0, %<w>3, %<w>1, <shift> %2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -1837,6 +1888,7 @@
""
"sub\\t%w0, %w3, %w1, <shift> %2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "SI")]
)
@@ -1849,6 +1901,7 @@
""
"sub\\t%<w>0, %<w>3, %<w>1, lsl %p2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -1863,6 +1916,7 @@
""
"sub\\t%w0, %w3, %w1, lsl %p2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "SI")]
)
@@ -1874,6 +1928,7 @@
""
"sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size>"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1887,6 +1942,7 @@
""
"sub\\t%w0, %w1, %w2, <su>xt<SHORT:size>"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -1899,6 +1955,7 @@
""
"sub\\t%<GPI:w>0, %<GPI:w>1, %<GPI:w>2, <su>xt<ALLX:size> %3"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -1913,6 +1970,7 @@
""
"sub\\t%w0, %w1, %w2, <su>xt<SHORT:size> %3"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -1927,6 +1985,7 @@
"aarch64_is_extend_from_extract (<MODE>mode, operands[2], operands[3])"
"sub\\t%<w>0, %<w>4, %<w>1, <su>xt%e3 %p2"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<MODE>")]
)
@@ -1943,6 +2002,7 @@
"aarch64_is_extend_from_extract (SImode, operands[2], operands[3])"
"sub\\t%w0, %w4, %w1, <su>xt%e3 %p2"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -1956,6 +2016,7 @@
""
"sbc\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "<MODE>")]
)
@@ -1971,6 +2032,7 @@
""
"sbc\\t%w0, %w1, %w2"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "SI")]
)
@@ -1987,6 +2049,7 @@
INTVAL (operands[3])));
return \"sub\t%<w>0, %<w>4, %<w>1, uxt%e3 %p2\";"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "<MODE>")]
)
@@ -2005,6 +2068,7 @@
INTVAL (operands[3])));
return \"sub\t%w0, %w4, %w1, uxt%e3 %p2\";"
[(set_attr "v8type" "alu_ext")
+ (set_attr "type" "alu_ext")
(set_attr "mode" "SI")]
)
@@ -2037,6 +2101,7 @@
DONE;
}
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_reg")
(set_attr "mode" "DI")]
)
@@ -2048,6 +2113,7 @@
neg\\t%<w>0, %<w>1
neg\\t%<rtn>0<vas>, %<rtn>1<vas>"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_reg")
(set_attr "simd_type" "*,simd_negabs")
(set_attr "simd" "*,yes")
(set_attr "mode" "<MODE>")
@@ -2061,6 +2127,7 @@
""
"neg\\t%w0, %w1"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_reg")
(set_attr "mode" "SI")]
)
@@ -2071,6 +2138,7 @@
""
"ngc\\t%<w>0, %<w>1"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "<MODE>")]
)
@@ -2082,6 +2150,7 @@
""
"ngc\\t%w0, %w1"
[(set_attr "v8type" "adc")
+ (set_attr "type" "adc_reg")
(set_attr "mode" "SI")]
)
@@ -2094,6 +2163,7 @@
""
"negs\\t%<w>0, %<w>1"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg")
(set_attr "mode" "<MODE>")]
)
@@ -2107,6 +2177,7 @@
""
"negs\\t%w0, %w1"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg")
(set_attr "mode" "SI")]
)
@@ -2122,6 +2193,7 @@
""
"negs\\t%<w>0, %<w>1, <shift> %2"
[(set_attr "v8type" "alus_shift")
+ (set_attr "type" "alus_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -2133,6 +2205,7 @@
""
"neg\\t%<w>0, %<w>1, <shift> %2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -2146,6 +2219,7 @@
""
"neg\\t%w0, %w1, <shift> %2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "SI")]
)
@@ -2157,6 +2231,7 @@
""
"neg\\t%<w>0, %<w>1, lsl %p2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -2170,6 +2245,7 @@
""
"neg\\t%w0, %w1, lsl %p2"
[(set_attr "v8type" "alu_shift")
+ (set_attr "type" "alu_shift_imm")
(set_attr "mode" "SI")]
)
@@ -2180,6 +2256,7 @@
""
"mul\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "mult")
+ (set_attr "type" "mul")
(set_attr "mode" "<MODE>")]
)
@@ -2192,6 +2269,7 @@
""
"mul\\t%w0, %w1, %w2"
[(set_attr "v8type" "mult")
+ (set_attr "type" "mul")
(set_attr "mode" "SI")]
)
@@ -2203,6 +2281,7 @@
""
"madd\\t%<w>0, %<w>1, %<w>2, %<w>3"
[(set_attr "v8type" "madd")
+ (set_attr "type" "mla")
(set_attr "mode" "<MODE>")]
)
@@ -2216,6 +2295,7 @@
""
"madd\\t%w0, %w1, %w2, %w3"
[(set_attr "v8type" "madd")
+ (set_attr "type" "mla")
(set_attr "mode" "SI")]
)
@@ -2228,6 +2308,7 @@
""
"msub\\t%<w>0, %<w>1, %<w>2, %<w>3"
[(set_attr "v8type" "madd")
+ (set_attr "type" "mla")
(set_attr "mode" "<MODE>")]
)
@@ -2242,6 +2323,7 @@
""
"msub\\t%w0, %w1, %w2, %w3"
[(set_attr "v8type" "madd")
+ (set_attr "type" "mla")
(set_attr "mode" "SI")]
)
@@ -2253,6 +2335,7 @@
""
"mneg\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "mult")
+ (set_attr "type" "mul")
(set_attr "mode" "<MODE>")]
)
@@ -2266,6 +2349,7 @@
""
"mneg\\t%w0, %w1, %w2"
[(set_attr "v8type" "mult")
+ (set_attr "type" "mul")
(set_attr "mode" "SI")]
)
@@ -2276,6 +2360,7 @@
""
"<su>mull\\t%0, %w1, %w2"
[(set_attr "v8type" "mull")
+ (set_attr "type" "<su>mull")
(set_attr "mode" "DI")]
)
@@ -2288,6 +2373,7 @@
""
"<su>maddl\\t%0, %w1, %w2, %3"
[(set_attr "v8type" "maddl")
+ (set_attr "type" "<su>mlal")
(set_attr "mode" "DI")]
)
@@ -2301,6 +2387,7 @@
""
"<su>msubl\\t%0, %w1, %w2, %3"
[(set_attr "v8type" "maddl")
+ (set_attr "type" "<su>mlal")
(set_attr "mode" "DI")]
)
@@ -2312,6 +2399,7 @@
""
"<su>mnegl\\t%0, %w1, %w2"
[(set_attr "v8type" "mull")
+ (set_attr "type" "<su>mull")
(set_attr "mode" "DI")]
)
@@ -2326,6 +2414,7 @@
""
"<su>mulh\\t%0, %1, %2"
[(set_attr "v8type" "mulh")
+ (set_attr "type" "<su>mull")
(set_attr "mode" "DI")]
)
@@ -2336,6 +2425,7 @@
""
"<su>div\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "<su>div")
+ (set_attr "type" "<su>div")
(set_attr "mode" "<MODE>")]
)
@@ -2348,6 +2438,7 @@
""
"<su>div\\t%w0, %w1, %w2"
[(set_attr "v8type" "<su>div")
+ (set_attr "type" "<su>div")
(set_attr "mode" "SI")]
)
@@ -2357,13 +2448,15 @@
(define_insn "*cmp<mode>"
[(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand:GPI 0 "register_operand" "r,r")
- (match_operand:GPI 1 "aarch64_plus_operand" "rI,J")))]
+ (compare:CC (match_operand:GPI 0 "register_operand" "r,r,r")
+ (match_operand:GPI 1 "aarch64_plus_operand" "r,I,J")))]
""
"@
cmp\\t%<w>0, %<w>1
+ cmp\\t%<w>0, %<w>1
cmn\\t%<w>0, #%n1"
[(set_attr "v8type" "alus")
+ (set_attr "type" "alus_reg,alus_imm,alus_imm")
(set_attr "mode" "<MODE>")]
)
@@ -2376,6 +2469,7 @@
fcmp\\t%<s>0, #0.0
fcmp\\t%<s>0, %<s>1"
[(set_attr "v8type" "fcmp")
+ (set_attr "type" "fcmp<s>")
(set_attr "mode" "<MODE>")]
)
@@ -2388,6 +2482,7 @@
fcmpe\\t%<s>0, #0.0
fcmpe\\t%<s>0, %<s>1"
[(set_attr "v8type" "fcmp")
+ (set_attr "type" "fcmp<s>")
(set_attr "mode" "<MODE>")]
)
@@ -2400,6 +2495,7 @@
""
"cmp\\t%<w>2, %<w>0, <shift> %1"
[(set_attr "v8type" "alus_shift")
+ (set_attr "type" "alus_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -2411,6 +2507,7 @@
""
"cmp\\t%<GPI:w>1, %<GPI:w>0, <su>xt<ALLX:size>"
[(set_attr "v8type" "alus_ext")
+ (set_attr "type" "alus_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -2424,6 +2521,7 @@
""
"cmp\\t%<GPI:w>2, %<GPI:w>0, <su>xt<ALLX:size> %1"
[(set_attr "v8type" "alus_ext")
+ (set_attr "type" "alus_ext")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -2464,6 +2562,7 @@
""
"cset\\t%<w>0, %m1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "<MODE>")]
)
@@ -2476,6 +2575,7 @@
""
"cset\\t%w0, %m1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "SI")]
)
@@ -2486,6 +2586,7 @@
""
"csetm\\t%<w>0, %m1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "<MODE>")]
)
@@ -2498,6 +2599,7 @@
""
"csetm\\t%w0, %m1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "SI")]
)
@@ -2552,6 +2654,7 @@
mov\\t%<w>0, -1
mov\\t%<w>0, 1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "<MODE>")]
)
@@ -2576,6 +2679,7 @@
mov\\t%w0, -1
mov\\t%w0, 1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "SI")]
)
@@ -2589,6 +2693,7 @@
"TARGET_FLOAT"
"fcsel\\t%<s>0, %<s>3, %<s>4, %m1"
[(set_attr "v8type" "fcsel")
+ (set_attr "type" "fcsel")
(set_attr "mode" "<MODE>")]
)
@@ -2638,6 +2743,7 @@
""
"csinc\\t%<w>0, %<w>1, %<w>1, %M2"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "<MODE>")])
(define_insn "csinc3<mode>_insn"
@@ -2651,6 +2757,7 @@
""
"csinc\\t%<w>0, %<w>4, %<w>3, %M1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "<MODE>")]
)
@@ -2664,6 +2771,7 @@
""
"csinv\\t%<w>0, %<w>4, %<w>3, %M1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "<MODE>")])
(define_insn "*csneg3<mode>_insn"
@@ -2676,6 +2784,7 @@
""
"csneg\\t%<w>0, %<w>4, %<w>3, %M1"
[(set_attr "v8type" "csel")
+ (set_attr "type" "csel")
(set_attr "mode" "<MODE>")])
;; -------------------------------------------------------------------
@@ -2689,6 +2798,7 @@
""
"<logical>\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "logic,logic_imm")
+ (set_attr "type" "logic_reg,logic_imm")
(set_attr "mode" "<MODE>")])
;; zero_extend version of above
@@ -2700,6 +2810,7 @@
""
"<logical>\\t%w0, %w1, %w2"
[(set_attr "v8type" "logic,logic_imm")
+ (set_attr "type" "logic_reg,logic_imm")
(set_attr "mode" "SI")])
(define_insn "*and<mode>3_compare0"
@@ -2713,6 +2824,7 @@
""
"ands\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "logics,logics_imm")
+ (set_attr "type" "logics_reg,logics_imm")
(set_attr "mode" "<MODE>")]
)
@@ -2728,6 +2840,7 @@
""
"ands\\t%w0, %w1, %w2"
[(set_attr "v8type" "logics,logics_imm")
+ (set_attr "type" "logics_reg,logics_imm")
(set_attr "mode" "SI")]
)
@@ -2744,6 +2857,7 @@
""
"ands\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
[(set_attr "v8type" "logics_shift")
+ (set_attr "type" "logics_shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -2762,6 +2876,7 @@
""
"ands\\t%w0, %w3, %w1, <SHIFT:shift> %2"
[(set_attr "v8type" "logics_shift")
+ (set_attr "type" "logics_shift_imm")
(set_attr "mode" "SI")]
)
@@ -2774,6 +2889,7 @@
""
"<LOGICAL:logical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
[(set_attr "v8type" "logic_shift")
+ (set_attr "type" "logic_shift_imm")
(set_attr "mode" "<MODE>")])
;; zero_extend version of above
@@ -2787,6 +2903,7 @@
""
"<LOGICAL:logical>\\t%w0, %w3, %w1, <SHIFT:shift> %2"
[(set_attr "v8type" "logic_shift")
+ (set_attr "type" "logic_shift_imm")
(set_attr "mode" "SI")])
(define_insn "one_cmpl<mode>2"
@@ -2795,6 +2912,7 @@
""
"mvn\\t%<w>0, %<w>1"
[(set_attr "v8type" "logic")
+ (set_attr "type" "logic_reg")
(set_attr "mode" "<MODE>")])
(define_insn "*one_cmpl_<optab><mode>2"
@@ -2804,6 +2922,7 @@
""
"mvn\\t%<w>0, %<w>1, <shift> %2"
[(set_attr "v8type" "logic_shift")
+ (set_attr "type" "logic_shift_imm")
(set_attr "mode" "<MODE>")])
(define_insn "*<LOGICAL:optab>_one_cmpl<mode>3"
@@ -2814,6 +2933,7 @@
""
"<LOGICAL:nlogical>\\t%<w>0, %<w>2, %<w>1"
[(set_attr "v8type" "logic")
+ (set_attr "type" "logic_reg")
(set_attr "mode" "<MODE>")])
(define_insn "*and_one_cmpl<mode>3_compare0"
@@ -2828,6 +2948,7 @@
""
"bics\\t%<w>0, %<w>2, %<w>1"
[(set_attr "v8type" "logics")
+ (set_attr "type" "logics_reg")
(set_attr "mode" "<MODE>")])
;; zero_extend version of above
@@ -2843,6 +2964,7 @@
""
"bics\\t%w0, %w2, %w1"
[(set_attr "v8type" "logics")
+ (set_attr "type" "logics_reg")
(set_attr "mode" "SI")])
(define_insn "*<LOGICAL:optab>_one_cmpl_<SHIFT:optab><mode>3"
@@ -2855,6 +2977,7 @@
""
"<LOGICAL:nlogical>\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
[(set_attr "v8type" "logic_shift")
+ (set_attr "type" "logics_shift_imm")
(set_attr "mode" "<MODE>")])
(define_insn "*and_one_cmpl_<SHIFT:optab><mode>3_compare0"
@@ -2873,6 +2996,7 @@
""
"bics\\t%<w>0, %<w>3, %<w>1, <SHIFT:shift> %2"
[(set_attr "v8type" "logics_shift")
+ (set_attr "type" "logics_shift_imm")
(set_attr "mode" "<MODE>")])
;; zero_extend version of above
@@ -2892,6 +3016,7 @@
""
"bics\\t%w0, %w3, %w1, <SHIFT:shift> %2"
[(set_attr "v8type" "logics_shift")
+ (set_attr "type" "logics_shift_imm")
(set_attr "mode" "SI")])
(define_insn "clz<mode>2"
@@ -2900,6 +3025,7 @@
""
"clz\\t%<w>0, %<w>1"
[(set_attr "v8type" "clz")
+ (set_attr "type" "clz")
(set_attr "mode" "<MODE>")])
(define_expand "ffs<mode>2"
@@ -2923,6 +3049,7 @@
""
"cls\\t%<w>0, %<w>1"
[(set_attr "v8type" "clz")
+ (set_attr "type" "clz")
(set_attr "mode" "<MODE>")])
(define_insn "rbit<mode>2"
@@ -2931,6 +3058,7 @@
""
"rbit\\t%<w>0, %<w>1"
[(set_attr "v8type" "rbit")
+ (set_attr "type" "rbit")
(set_attr "mode" "<MODE>")])
(define_expand "ctz<mode>2"
@@ -2953,6 +3081,7 @@
""
"tst\\t%<w>0, %<w>1"
[(set_attr "v8type" "logics")
+ (set_attr "type" "logics_reg")
(set_attr "mode" "<MODE>")])
(define_insn "*and_<SHIFT:optab><mode>3nr_compare0"
@@ -2966,6 +3095,7 @@
""
"tst\\t%<w>2, %<w>0, <SHIFT:shift> %1"
[(set_attr "v8type" "logics_shift")
+ (set_attr "type" "logics_shift_imm")
(set_attr "mode" "<MODE>")])
;; -------------------------------------------------------------------
@@ -3055,14 +3185,184 @@
}
)
-(define_insn "*<optab><mode>3_insn"
+;; Logical left shift using SISD or Integer instruction
+(define_insn "*aarch64_ashl_sisd_or_int_<mode>3"
+ [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
+ (ashift:GPI
+ (match_operand:GPI 1 "register_operand" "w,w,r")
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
+ ""
+ "@
+ shl\t%<rtn>0<vas>, %<rtn>1<vas>, %2
+ ushl\t%<rtn>0<vas>, %<rtn>1<vas>, %<rtn>2<vas>
+ lsl\t%<w>0, %<w>1, %<w>2"
+ [(set_attr "simd" "yes,yes,no")
+ (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
+ (set_attr "simd_mode" "<MODE>,<MODE>,*")
+ (set_attr "v8type" "*,*,shift")
+ (set_attr "type" "*,*,shift_reg")
+ (set_attr "mode" "*,*,<MODE>")]
+)
+
+;; Logical right shift using SISD or Integer instruction
+(define_insn "*aarch64_lshr_sisd_or_int_<mode>3"
+ [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
+ (lshiftrt:GPI
+ (match_operand:GPI 1 "register_operand" "w,w,r")
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "Us<cmode>,w,rUs<cmode>")))]
+ ""
+ "@
+ ushr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
+ #
+ lsr\t%<w>0, %<w>1, %<w>2"
+ [(set_attr "simd" "yes,yes,no")
+ (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
+ (set_attr "simd_mode" "<MODE>,<MODE>,*")
+ (set_attr "v8type" "*,*,shift")
+ (set_attr "type" "*,*,shift_reg")
+ (set_attr "mode" "*,*,<MODE>")]
+)
+
+(define_split
+ [(set (match_operand:DI 0 "aarch64_simd_register")
+ (lshiftrt:DI
+ (match_operand:DI 1 "aarch64_simd_register")
+ (match_operand:QI 2 "aarch64_simd_register")))]
+ "TARGET_SIMD && reload_completed"
+ [(set (match_dup 2)
+ (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
+ (set (match_dup 0)
+ (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_USHL))]
+ ""
+)
+
+(define_split
+ [(set (match_operand:SI 0 "aarch64_simd_register")
+ (lshiftrt:SI
+ (match_operand:SI 1 "aarch64_simd_register")
+ (match_operand:QI 2 "aarch64_simd_register")))]
+ "TARGET_SIMD && reload_completed"
+ [(set (match_dup 2)
+ (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
+ (set (match_dup 0)
+ (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_USHL_2S))]
+ ""
+)
+
+;; Arithmetic right shift using SISD or Integer instruction
+(define_insn "*aarch64_ashr_sisd_or_int_<mode>3"
+ [(set (match_operand:GPI 0 "register_operand" "=w,w,r")
+ (ashiftrt:GPI
+ (match_operand:GPI 1 "register_operand" "w,w,r")
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_di" "Us<cmode>,w,rUs<cmode>")))]
+ ""
+ "@
+ sshr\t%<rtn>0<vas>, %<rtn>1<vas>, %2
+ #
+ asr\t%<w>0, %<w>1, %<w>2"
+ [(set_attr "simd" "yes,yes,no")
+ (set_attr "simd_type" "simd_shift_imm,simd_shift,*")
+ (set_attr "simd_mode" "<MODE>,<MODE>,*")
+ (set_attr "v8type" "*,*,shift")
+ (set_attr "type" "*,*,shift_reg")
+ (set_attr "mode" "*,*,<MODE>")]
+)
+
+(define_split
+ [(set (match_operand:DI 0 "aarch64_simd_register")
+ (ashiftrt:DI
+ (match_operand:DI 1 "aarch64_simd_register")
+ (match_operand:QI 2 "aarch64_simd_register")))]
+ "TARGET_SIMD && reload_completed"
+ [(set (match_dup 2)
+ (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
+ (set (match_dup 0)
+ (unspec:DI [(match_dup 1) (match_dup 2)] UNSPEC_SISD_SSHL))]
+ ""
+)
+
+(define_split
+ [(set (match_operand:SI 0 "aarch64_simd_register")
+ (ashiftrt:SI
+ (match_operand:SI 1 "aarch64_simd_register")
+ (match_operand:QI 2 "aarch64_simd_register")))]
+ "TARGET_SIMD && reload_completed"
+ [(set (match_dup 2)
+ (unspec:QI [(match_dup 2)] UNSPEC_SISD_NEG))
+ (set (match_dup 0)
+ (unspec:SI [(match_dup 1) (match_dup 2)] UNSPEC_SSHL_2S))]
+ ""
+)
+
+(define_insn "*aarch64_sisd_ushl"
+ [(set (match_operand:DI 0 "register_operand" "=w")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "w")
+ (match_operand:QI 2 "register_operand" "w")]
+ UNSPEC_SISD_USHL))]
+ "TARGET_SIMD"
+ "ushl\t%d0, %d1, %d2"
+ [(set_attr "simd" "yes")
+ (set_attr "simd_type" "simd_shift")
+ (set_attr "simd_mode" "DI")]
+)
+
+(define_insn "*aarch64_ushl_2s"
+ [(set (match_operand:SI 0 "register_operand" "=w")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "w")
+ (match_operand:QI 2 "register_operand" "w")]
+ UNSPEC_USHL_2S))]
+ "TARGET_SIMD"
+ "ushl\t%0.2s, %1.2s, %2.2s"
+ [(set_attr "simd" "yes")
+ (set_attr "simd_type" "simd_shift")
+ (set_attr "simd_mode" "DI")]
+)
+
+(define_insn "*aarch64_sisd_sshl"
+ [(set (match_operand:DI 0 "register_operand" "=w")
+ (unspec:DI [(match_operand:DI 1 "register_operand" "w")
+ (match_operand:QI 2 "register_operand" "w")]
+ UNSPEC_SISD_SSHL))]
+ "TARGET_SIMD"
+ "sshl\t%d0, %d1, %d2"
+ [(set_attr "simd" "yes")
+ (set_attr "simd_type" "simd_shift")
+ (set_attr "simd_mode" "DI")]
+)
+
+(define_insn "*aarch64_sshl_2s"
+ [(set (match_operand:SI 0 "register_operand" "=w")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "w")
+ (match_operand:QI 2 "register_operand" "w")]
+ UNSPEC_SSHL_2S))]
+ "TARGET_SIMD"
+ "sshl\t%0.2s, %1.2s, %2.2s"
+ [(set_attr "simd" "yes")
+ (set_attr "simd_type" "simd_shift")
+ (set_attr "simd_mode" "DI")]
+)
+
+(define_insn "*aarch64_sisd_neg_qi"
+ [(set (match_operand:QI 0 "register_operand" "=w")
+ (unspec:QI [(match_operand:QI 1 "register_operand" "w")]
+ UNSPEC_SISD_NEG))]
+ "TARGET_SIMD"
+ "neg\t%d0, %d1"
+ [(set_attr "simd" "yes")
+ (set_attr "simd_type" "simd_negabs")
+ (set_attr "simd_mode" "QI")]
+)
+
+;; Rotate right
+(define_insn "*ror<mode>3_insn"
[(set (match_operand:GPI 0 "register_operand" "=r")
- (SHIFT:GPI
- (match_operand:GPI 1 "register_operand" "r")
- (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
+ (rotatert:GPI
+ (match_operand:GPI 1 "register_operand" "r")
+ (match_operand:QI 2 "aarch64_reg_or_shift_imm_<mode>" "rUs<cmode>")))]
""
- "<shift>\\t%<w>0, %<w>1, %<w>2"
+ "ror\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "shift")
+ (set_attr "type" "shift_reg")
(set_attr "mode" "<MODE>")]
)
@@ -3075,6 +3375,7 @@
""
"<shift>\\t%w0, %w1, %w2"
[(set_attr "v8type" "shift")
+ (set_attr "type" "shift_reg")
(set_attr "mode" "SI")]
)
@@ -3085,6 +3386,7 @@
""
"lsl\\t%<w>0, %<w>1, %<w>2"
[(set_attr "v8type" "shift")
+ (set_attr "type" "shift_reg")
(set_attr "mode" "<MODE>")]
)
@@ -3098,6 +3400,7 @@
return "<bfshift>\t%w0, %w1, %2, %3";
}
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<MODE>")]
)
@@ -3111,6 +3414,7 @@
(UINTVAL (operands[3]) + UINTVAL (operands[4]) == GET_MODE_BITSIZE (<MODE>mode))"
"extr\\t%<w>0, %<w>1, %<w>2, %4"
[(set_attr "v8type" "shift")
+ (set_attr "type" "shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -3126,6 +3430,7 @@
(UINTVAL (operands[3]) + UINTVAL (operands[4]) == 32)"
"extr\\t%w0, %w1, %w2, %4"
[(set_attr "v8type" "shift")
+ (set_attr "type" "shift_imm")
(set_attr "mode" "SI")]
)
@@ -3139,6 +3444,7 @@
return "ror\\t%<w>0, %<w>1, %3";
}
[(set_attr "v8type" "shift")
+ (set_attr "type" "shift_imm")
(set_attr "mode" "<MODE>")]
)
@@ -3154,6 +3460,7 @@
return "ror\\t%w0, %w1, %3";
}
[(set_attr "v8type" "shift")
+ (set_attr "type" "shift_imm")
(set_attr "mode" "SI")]
)
@@ -3168,6 +3475,7 @@
return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
}
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -3182,6 +3490,7 @@
return "ubfx\t%<GPI:w>0, %<GPI:w>1, %2, %3";
}
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -3196,6 +3505,7 @@
return "sbfx\\t%<GPI:w>0, %<GPI:w>1, %2, %3";
}
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -3220,6 +3530,7 @@
""
"<su>bfx\\t%<w>0, %<w>1, %3, %2"
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<MODE>")]
)
@@ -3264,6 +3575,7 @@
> GET_MODE_BITSIZE (<MODE>mode)))"
"bfi\\t%<w>0, %<w>3, %2, %1"
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<MODE>")]
)
@@ -3279,6 +3591,7 @@
> GET_MODE_BITSIZE (<MODE>mode)))"
"bfxil\\t%<w>0, %<w>2, %3, %1"
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<MODE>")]
)
@@ -3295,6 +3608,7 @@
return "<su>bfiz\t%<GPI:w>0, %<GPI:w>1, %2, %3";
}
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<GPI:MODE>")]
)
@@ -3309,6 +3623,7 @@
&& (INTVAL (operands[3]) & ((1 << INTVAL (operands[2])) - 1)) == 0"
"ubfiz\\t%<w>0, %<w>1, %2, %P3"
[(set_attr "v8type" "bfm")
+ (set_attr "type" "bfm")
(set_attr "mode" "<MODE>")]
)
@@ -3318,6 +3633,7 @@
""
"rev\\t%<w>0, %<w>1"
[(set_attr "v8type" "rev")
+ (set_attr "type" "rev")
(set_attr "mode" "<MODE>")]
)
@@ -3327,6 +3643,7 @@
""
"rev16\\t%w0, %w1"
[(set_attr "v8type" "rev")
+ (set_attr "type" "rev")
(set_attr "mode" "HI")]
)
@@ -3337,6 +3654,7 @@
""
"rev\\t%w0, %w1"
[(set_attr "v8type" "rev")
+ (set_attr "type" "rev")
(set_attr "mode" "SI")]
)
@@ -3354,6 +3672,7 @@
"TARGET_FLOAT"
"frint<frint_suffix>\\t%<s>0, %<s>1"
[(set_attr "v8type" "frint")
+ (set_attr "type" "f_rint<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3366,6 +3685,7 @@
"TARGET_FLOAT"
"fcvt<frint_suffix><su>\\t%<GPI:w>0, %<GPF:s>1"
[(set_attr "v8type" "fcvtf2i")
+ (set_attr "type" "f_cvtf2i")
(set_attr "mode" "<GPF:MODE>")
(set_attr "mode2" "<GPI:MODE>")]
)
@@ -3380,6 +3700,7 @@
"TARGET_FLOAT"
"fmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
[(set_attr "v8type" "fmadd")
+ (set_attr "type" "fmac<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3391,6 +3712,7 @@
"TARGET_FLOAT"
"fmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
[(set_attr "v8type" "fmadd")
+ (set_attr "type" "fmac<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3402,6 +3724,7 @@
"TARGET_FLOAT"
"fnmsub\\t%<s>0, %<s>1, %<s>2, %<s>3"
[(set_attr "v8type" "fmadd")
+ (set_attr "type" "fmac<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3413,6 +3736,7 @@
"TARGET_FLOAT"
"fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
[(set_attr "v8type" "fmadd")
+ (set_attr "type" "fmac<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3425,6 +3749,7 @@
"!HONOR_SIGNED_ZEROS (<MODE>mode) && TARGET_FLOAT"
"fnmadd\\t%<s>0, %<s>1, %<s>2, %<s>3"
[(set_attr "v8type" "fmadd")
+ (set_attr "type" "fmac<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3438,6 +3763,7 @@
"TARGET_FLOAT"
"fcvt\\t%d0, %s1"
[(set_attr "v8type" "fcvt")
+ (set_attr "type" "f_cvt")
(set_attr "mode" "DF")
(set_attr "mode2" "SF")]
)
@@ -3448,6 +3774,7 @@
"TARGET_FLOAT"
"fcvt\\t%s0, %d1"
[(set_attr "v8type" "fcvt")
+ (set_attr "type" "f_cvt")
(set_attr "mode" "SF")
(set_attr "mode2" "DF")]
)
@@ -3458,6 +3785,7 @@
"TARGET_FLOAT"
"fcvtzs\\t%<GPI:w>0, %<GPF:s>1"
[(set_attr "v8type" "fcvtf2i")
+ (set_attr "type" "f_cvtf2i")
(set_attr "mode" "<GPF:MODE>")
(set_attr "mode2" "<GPI:MODE>")]
)
@@ -3468,6 +3796,7 @@
"TARGET_FLOAT"
"fcvtzu\\t%<GPI:w>0, %<GPF:s>1"
[(set_attr "v8type" "fcvtf2i")
+ (set_attr "type" "f_cvtf2i")
(set_attr "mode" "<GPF:MODE>")
(set_attr "mode2" "<GPI:MODE>")]
)
@@ -3478,6 +3807,7 @@
"TARGET_FLOAT"
"scvtf\\t%<GPF:s>0, %<GPI:w>1"
[(set_attr "v8type" "fcvti2f")
+ (set_attr "type" "f_cvti2f")
(set_attr "mode" "<GPF:MODE>")
(set_attr "mode2" "<GPI:MODE>")]
)
@@ -3488,6 +3818,7 @@
"TARGET_FLOAT"
"ucvtf\\t%<GPF:s>0, %<GPI:w>1"
[(set_attr "v8type" "fcvt")
+ (set_attr "type" "f_cvt")
(set_attr "mode" "<GPF:MODE>")
(set_attr "mode2" "<GPI:MODE>")]
)
@@ -3504,6 +3835,7 @@
"TARGET_FLOAT"
"fadd\\t%<s>0, %<s>1, %<s>2"
[(set_attr "v8type" "fadd")
+ (set_attr "type" "fadd<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3515,6 +3847,7 @@
"TARGET_FLOAT"
"fsub\\t%<s>0, %<s>1, %<s>2"
[(set_attr "v8type" "fadd")
+ (set_attr "type" "fadd<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3526,6 +3859,7 @@
"TARGET_FLOAT"
"fmul\\t%<s>0, %<s>1, %<s>2"
[(set_attr "v8type" "fmul")
+ (set_attr "type" "fmul<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3537,6 +3871,7 @@
"TARGET_FLOAT"
"fnmul\\t%<s>0, %<s>1, %<s>2"
[(set_attr "v8type" "fmul")
+ (set_attr "type" "fmul<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3548,6 +3883,7 @@
"TARGET_FLOAT"
"fdiv\\t%<s>0, %<s>1, %<s>2"
[(set_attr "v8type" "fdiv")
+ (set_attr "type" "fdiv<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3557,6 +3893,7 @@
"TARGET_FLOAT"
"fneg\\t%<s>0, %<s>1"
[(set_attr "v8type" "ffarith")
+ (set_attr "type" "ffarith<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3566,6 +3903,7 @@
"TARGET_FLOAT"
"fsqrt\\t%<s>0, %<s>1"
[(set_attr "v8type" "fsqrt")
+ (set_attr "type" "fsqrt<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3575,6 +3913,7 @@
"TARGET_FLOAT"
"fabs\\t%<s>0, %<s>1"
[(set_attr "v8type" "ffarith")
+ (set_attr "type" "ffarith<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3589,6 +3928,7 @@
"TARGET_FLOAT"
"fmaxnm\\t%<s>0, %<s>1, %<s>2"
[(set_attr "v8type" "fminmax")
+ (set_attr "type" "f_minmax<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3599,27 +3939,7 @@
"TARGET_FLOAT"
"fminnm\\t%<s>0, %<s>1, %<s>2"
[(set_attr "v8type" "fminmax")
- (set_attr "mode" "<MODE>")]
-)
-
-(define_insn "aarch64_frecp<FRECP:frecp_suffix><mode>"
- [(set (match_operand:GPF 0 "register_operand" "=w")
- (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")]
- FRECP))]
- "TARGET_FLOAT"
- "frecp<FRECP:frecp_suffix>\\t%<s>0, %<s>1"
- [(set_attr "v8type" "frecp<FRECP:frecp_suffix>")
- (set_attr "mode" "<MODE>")]
-)
-
-(define_insn "aarch64_frecps<mode>"
- [(set (match_operand:GPF 0 "register_operand" "=w")
- (unspec:GPF [(match_operand:GPF 1 "register_operand" "w")
- (match_operand:GPF 2 "register_operand" "w")]
- UNSPEC_FRECPS))]
- "TARGET_FLOAT"
- "frecps\\t%<s>0, %<s>1, %<s>2"
- [(set_attr "v8type" "frecps")
+ (set_attr "type" "f_minmax<s>")
(set_attr "mode" "<MODE>")]
)
@@ -3685,6 +4005,7 @@
"reload_completed || reload_in_progress"
"fmov\\t%x0, %d1"
[(set_attr "v8type" "fmovf2i")
+ (set_attr "type" "f_mrc")
(set_attr "mode" "DI")
(set_attr "length" "4")
])
@@ -3697,6 +4018,7 @@
"reload_completed || reload_in_progress"
"fmov\\t%x0, %1.d[1]"
[(set_attr "v8type" "fmovf2i")
+ (set_attr "type" "f_mrc")
(set_attr "mode" "DI")
(set_attr "length" "4")
])
@@ -3708,6 +4030,7 @@
"reload_completed || reload_in_progress"
"fmov\\t%0.d[1], %x1"
[(set_attr "v8type" "fmovi2f")
+ (set_attr "type" "f_mcr")
(set_attr "mode" "DI")
(set_attr "length" "4")
])
@@ -3718,6 +4041,7 @@
"reload_completed || reload_in_progress"
"fmov\\t%d0, %x1"
[(set_attr "v8type" "fmovi2f")
+ (set_attr "type" "f_mcr")
(set_attr "mode" "DI")
(set_attr "length" "4")
])
@@ -3729,6 +4053,7 @@
"reload_completed || reload_in_progress"
"fmov\\t%d0, %d1"
[(set_attr "v8type" "fmovi2f")
+ (set_attr "type" "f_mcr")
(set_attr "mode" "DI")
(set_attr "length" "4")
])
@@ -3761,6 +4086,7 @@
""
"add\\t%<w>0, %<w>1, :lo12:%a2"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_reg")
(set_attr "mode" "<MODE>")]
)
@@ -3773,6 +4099,7 @@
""
"ldr\\t%<w>0, [%1, #:got_lo12:%a2]"
[(set_attr "v8type" "load1")
+ (set_attr "type" "load1")
(set_attr "mode" "<MODE>")]
)
@@ -3786,6 +4113,7 @@
"TARGET_ILP32"
"ldr\\t%w0, [%1, #:got_lo12:%a2]"
[(set_attr "v8type" "load1")
+ (set_attr "type" "load1")
(set_attr "mode" "DI")]
)
@@ -3796,6 +4124,7 @@
""
"ldr\\t%0, %L1"
[(set_attr "v8type" "load1")
+ (set_attr "type" "load1")
(set_attr "mode" "DI")]
)
@@ -3805,6 +4134,7 @@
""
"mrs\\t%0, tpidr_el0"
[(set_attr "v8type" "mrs")
+ (set_attr "type" "mrs")
(set_attr "mode" "DI")]
)
@@ -3830,6 +4160,7 @@
""
"adrp\\tx0, %A1\;add\\tx0, x0, %L1\;bl\\t%2\;nop"
[(set_attr "v8type" "call")
+ (set_attr "type" "call")
(set_attr "length" "16")])
(define_insn "tlsie_small"
@@ -3839,6 +4170,7 @@
""
"adrp\\t%0, %A1\;ldr\\t%0, [%0, #%L1]"
[(set_attr "v8type" "load1")
+ (set_attr "type" "load1")
(set_attr "mode" "DI")
(set_attr "length" "8")]
)
@@ -3851,6 +4183,7 @@
""
"add\\t%0, %1, #%G2\;add\\t%0, %0, #%L2"
[(set_attr "v8type" "alu")
+ (set_attr "type" "alu_reg")
(set_attr "mode" "DI")
(set_attr "length" "8")]
)
@@ -3864,6 +4197,7 @@
"TARGET_TLS_DESC"
"adrp\\tx0, %A0\;ldr\\t%1, [x0, #%L0]\;add\\tx0, x0, %L0\;.tlsdesccall\\t%0\;blr\\t%1"
[(set_attr "v8type" "call")
+ (set_attr "type" "call")
(set_attr "length" "16")])
(define_insn "stack_tie"
diff --git a/gcc/config/aarch64/arm_neon.h b/gcc/config/aarch64/arm_neon.h
index 99cf123e29e..521b7e817e6 100644
--- a/gcc/config/aarch64/arm_neon.h
+++ b/gcc/config/aarch64/arm_neon.h
@@ -29,6 +29,9 @@
#include <stdint.h>
+#define __AARCH64_UINT64_C(__C) ((uint64_t) __C)
+#define __AARCH64_INT64_C(__C) ((int64_t) __C)
+
typedef __builtin_aarch64_simd_qi int8x8_t
__attribute__ ((__vector_size__ (8)));
typedef __builtin_aarch64_simd_hi int16x4_t
@@ -446,7 +449,167 @@ typedef struct poly16x8x4_t
poly16x8_t val[4];
} poly16x8x4_t;
-
+/* vget_lane internal macros. */
+
+#define __aarch64_vget_lane_any(__size, __cast_ret, __cast_a, __a, __b) \
+ (__cast_ret \
+ __builtin_aarch64_get_lane##__size (__cast_a __a, __b))
+
+#define __aarch64_vget_lane_f32(__a, __b) \
+ __aarch64_vget_lane_any (v2sf, , , __a, __b)
+#define __aarch64_vget_lane_f64(__a, __b) (__a)
+
+#define __aarch64_vget_lane_p8(__a, __b) \
+ __aarch64_vget_lane_any (v8qi, (poly8_t), (int8x8_t), __a, __b)
+#define __aarch64_vget_lane_p16(__a, __b) \
+ __aarch64_vget_lane_any (v4hi, (poly16_t), (int16x4_t), __a, __b)
+
+#define __aarch64_vget_lane_s8(__a, __b) \
+ __aarch64_vget_lane_any (v8qi, , ,__a, __b)
+#define __aarch64_vget_lane_s16(__a, __b) \
+ __aarch64_vget_lane_any (v4hi, , ,__a, __b)
+#define __aarch64_vget_lane_s32(__a, __b) \
+ __aarch64_vget_lane_any (v2si, , ,__a, __b)
+#define __aarch64_vget_lane_s64(__a, __b) (__a)
+
+#define __aarch64_vget_lane_u8(__a, __b) \
+ __aarch64_vget_lane_any (v8qi, (uint8_t), (int8x8_t), __a, __b)
+#define __aarch64_vget_lane_u16(__a, __b) \
+ __aarch64_vget_lane_any (v4hi, (uint16_t), (int16x4_t), __a, __b)
+#define __aarch64_vget_lane_u32(__a, __b) \
+ __aarch64_vget_lane_any (v2si, (uint32_t), (int32x2_t), __a, __b)
+#define __aarch64_vget_lane_u64(__a, __b) (__a)
+
+#define __aarch64_vgetq_lane_f32(__a, __b) \
+ __aarch64_vget_lane_any (v4sf, , , __a, __b)
+#define __aarch64_vgetq_lane_f64(__a, __b) \
+ __aarch64_vget_lane_any (v2df, , , __a, __b)
+
+#define __aarch64_vgetq_lane_p8(__a, __b) \
+ __aarch64_vget_lane_any (v16qi, (poly8_t), (int8x16_t), __a, __b)
+#define __aarch64_vgetq_lane_p16(__a, __b) \
+ __aarch64_vget_lane_any (v8hi, (poly16_t), (int16x8_t), __a, __b)
+
+#define __aarch64_vgetq_lane_s8(__a, __b) \
+ __aarch64_vget_lane_any (v16qi, , ,__a, __b)
+#define __aarch64_vgetq_lane_s16(__a, __b) \
+ __aarch64_vget_lane_any (v8hi, , ,__a, __b)
+#define __aarch64_vgetq_lane_s32(__a, __b) \
+ __aarch64_vget_lane_any (v4si, , ,__a, __b)
+#define __aarch64_vgetq_lane_s64(__a, __b) \
+ __aarch64_vget_lane_any (v2di, , ,__a, __b)
+
+#define __aarch64_vgetq_lane_u8(__a, __b) \
+ __aarch64_vget_lane_any (v16qi, (uint8_t), (int8x16_t), __a, __b)
+#define __aarch64_vgetq_lane_u16(__a, __b) \
+ __aarch64_vget_lane_any (v8hi, (uint16_t), (int16x8_t), __a, __b)
+#define __aarch64_vgetq_lane_u32(__a, __b) \
+ __aarch64_vget_lane_any (v4si, (uint32_t), (int32x4_t), __a, __b)
+#define __aarch64_vgetq_lane_u64(__a, __b) \
+ __aarch64_vget_lane_any (v2di, (uint64_t), (int64x2_t), __a, __b)
+
+/* __aarch64_vdup_lane internal macros. */
+#define __aarch64_vdup_lane_any(__size, __q1, __q2, __a, __b) \
+ vdup##__q1##_n_##__size (__aarch64_vget##__q2##_lane_##__size (__a, __b))
+
+#define __aarch64_vdup_lane_f32(__a, __b) \
+ __aarch64_vdup_lane_any (f32, , , __a, __b)
+#define __aarch64_vdup_lane_f64(__a, __b) (__a)
+#define __aarch64_vdup_lane_p8(__a, __b) \
+ __aarch64_vdup_lane_any (p8, , , __a, __b)
+#define __aarch64_vdup_lane_p16(__a, __b) \
+ __aarch64_vdup_lane_any (p16, , , __a, __b)
+#define __aarch64_vdup_lane_s8(__a, __b) \
+ __aarch64_vdup_lane_any (s8, , , __a, __b)
+#define __aarch64_vdup_lane_s16(__a, __b) \
+ __aarch64_vdup_lane_any (s16, , , __a, __b)
+#define __aarch64_vdup_lane_s32(__a, __b) \
+ __aarch64_vdup_lane_any (s32, , , __a, __b)
+#define __aarch64_vdup_lane_s64(__a, __b) (__a)
+#define __aarch64_vdup_lane_u8(__a, __b) \
+ __aarch64_vdup_lane_any (u8, , , __a, __b)
+#define __aarch64_vdup_lane_u16(__a, __b) \
+ __aarch64_vdup_lane_any (u16, , , __a, __b)
+#define __aarch64_vdup_lane_u32(__a, __b) \
+ __aarch64_vdup_lane_any (u32, , , __a, __b)
+#define __aarch64_vdup_lane_u64(__a, __b) (__a)
+
+/* __aarch64_vdup_laneq internal macros. */
+#define __aarch64_vdup_laneq_f32(__a, __b) \
+ __aarch64_vdup_lane_any (f32, , q, __a, __b)
+#define __aarch64_vdup_laneq_f64(__a, __b) \
+ __aarch64_vdup_lane_any (f64, , q, __a, __b)
+#define __aarch64_vdup_laneq_p8(__a, __b) \
+ __aarch64_vdup_lane_any (p8, , q, __a, __b)
+#define __aarch64_vdup_laneq_p16(__a, __b) \
+ __aarch64_vdup_lane_any (p16, , q, __a, __b)
+#define __aarch64_vdup_laneq_s8(__a, __b) \
+ __aarch64_vdup_lane_any (s8, , q, __a, __b)
+#define __aarch64_vdup_laneq_s16(__a, __b) \
+ __aarch64_vdup_lane_any (s16, , q, __a, __b)
+#define __aarch64_vdup_laneq_s32(__a, __b) \
+ __aarch64_vdup_lane_any (s32, , q, __a, __b)
+#define __aarch64_vdup_laneq_s64(__a, __b) \
+ __aarch64_vdup_lane_any (s64, , q, __a, __b)
+#define __aarch64_vdup_laneq_u8(__a, __b) \
+ __aarch64_vdup_lane_any (u8, , q, __a, __b)
+#define __aarch64_vdup_laneq_u16(__a, __b) \
+ __aarch64_vdup_lane_any (u16, , q, __a, __b)
+#define __aarch64_vdup_laneq_u32(__a, __b) \
+ __aarch64_vdup_lane_any (u32, , q, __a, __b)
+#define __aarch64_vdup_laneq_u64(__a, __b) \
+ __aarch64_vdup_lane_any (u64, , q, __a, __b)
+
+/* __aarch64_vdupq_lane internal macros. */
+#define __aarch64_vdupq_lane_f32(__a, __b) \
+ __aarch64_vdup_lane_any (f32, q, , __a, __b)
+#define __aarch64_vdupq_lane_f64(__a, __b) (vdupq_n_f64 (__a))
+#define __aarch64_vdupq_lane_p8(__a, __b) \
+ __aarch64_vdup_lane_any (p8, q, , __a, __b)
+#define __aarch64_vdupq_lane_p16(__a, __b) \
+ __aarch64_vdup_lane_any (p16, q, , __a, __b)
+#define __aarch64_vdupq_lane_s8(__a, __b) \
+ __aarch64_vdup_lane_any (s8, q, , __a, __b)
+#define __aarch64_vdupq_lane_s16(__a, __b) \
+ __aarch64_vdup_lane_any (s16, q, , __a, __b)
+#define __aarch64_vdupq_lane_s32(__a, __b) \
+ __aarch64_vdup_lane_any (s32, q, , __a, __b)
+#define __aarch64_vdupq_lane_s64(__a, __b) (vdupq_n_s64 (__a))
+#define __aarch64_vdupq_lane_u8(__a, __b) \
+ __aarch64_vdup_lane_any (u8, q, , __a, __b)
+#define __aarch64_vdupq_lane_u16(__a, __b) \
+ __aarch64_vdup_lane_any (u16, q, , __a, __b)
+#define __aarch64_vdupq_lane_u32(__a, __b) \
+ __aarch64_vdup_lane_any (u32, q, , __a, __b)
+#define __aarch64_vdupq_lane_u64(__a, __b) (vdupq_n_u64 (__a))
+
+/* __aarch64_vdupq_laneq internal macros. */
+#define __aarch64_vdupq_laneq_f32(__a, __b) \
+ __aarch64_vdup_lane_any (f32, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_f64(__a, __b) \
+ __aarch64_vdup_lane_any (f64, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_p8(__a, __b) \
+ __aarch64_vdup_lane_any (p8, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_p16(__a, __b) \
+ __aarch64_vdup_lane_any (p16, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_s8(__a, __b) \
+ __aarch64_vdup_lane_any (s8, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_s16(__a, __b) \
+ __aarch64_vdup_lane_any (s16, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_s32(__a, __b) \
+ __aarch64_vdup_lane_any (s32, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_s64(__a, __b) \
+ __aarch64_vdup_lane_any (s64, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_u8(__a, __b) \
+ __aarch64_vdup_lane_any (u8, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_u16(__a, __b) \
+ __aarch64_vdup_lane_any (u16, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_u32(__a, __b) \
+ __aarch64_vdup_lane_any (u32, q, q, __a, __b)
+#define __aarch64_vdupq_laneq_u64(__a, __b) \
+ __aarch64_vdup_lane_any (u64, q, q, __a, __b)
+
+/* vadd */
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
vadd_s8 (int8x8_t __a, int8x8_t __b)
{
@@ -2307,155 +2470,156 @@ vcreate_p16 (uint64_t __a)
return (poly16x4_t) __a;
}
+/* vget_lane */
+
+__extension__ static __inline float32_t __attribute__ ((__always_inline__))
+vget_lane_f32 (float32x2_t __a, const int __b)
+{
+ return __aarch64_vget_lane_f32 (__a, __b);
+}
+
+__extension__ static __inline float64_t __attribute__ ((__always_inline__))
+vget_lane_f64 (float64x1_t __a, const int __b)
+{
+ return __aarch64_vget_lane_f64 (__a, __b);
+}
+
+__extension__ static __inline poly8_t __attribute__ ((__always_inline__))
+vget_lane_p8 (poly8x8_t __a, const int __b)
+{
+ return __aarch64_vget_lane_p8 (__a, __b);
+}
+
+__extension__ static __inline poly16_t __attribute__ ((__always_inline__))
+vget_lane_p16 (poly16x4_t __a, const int __b)
+{
+ return __aarch64_vget_lane_p16 (__a, __b);
+}
+
__extension__ static __inline int8_t __attribute__ ((__always_inline__))
vget_lane_s8 (int8x8_t __a, const int __b)
{
- return (int8_t) __builtin_aarch64_get_lane_signedv8qi (__a, __b);
+ return __aarch64_vget_lane_s8 (__a, __b);
}
__extension__ static __inline int16_t __attribute__ ((__always_inline__))
vget_lane_s16 (int16x4_t __a, const int __b)
{
- return (int16_t) __builtin_aarch64_get_lane_signedv4hi (__a, __b);
+ return __aarch64_vget_lane_s16 (__a, __b);
}
__extension__ static __inline int32_t __attribute__ ((__always_inline__))
vget_lane_s32 (int32x2_t __a, const int __b)
{
- return (int32_t) __builtin_aarch64_get_lane_signedv2si (__a, __b);
+ return __aarch64_vget_lane_s32 (__a, __b);
}
-__extension__ static __inline float32_t __attribute__ ((__always_inline__))
-vget_lane_f32 (float32x2_t __a, const int __b)
+__extension__ static __inline int64_t __attribute__ ((__always_inline__))
+vget_lane_s64 (int64x1_t __a, const int __b)
{
- return (float32_t) __builtin_aarch64_get_lanev2sf (__a, __b);
+ return __aarch64_vget_lane_s64 (__a, __b);
}
__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
vget_lane_u8 (uint8x8_t __a, const int __b)
{
- return (uint8_t) __builtin_aarch64_get_lane_unsignedv8qi ((int8x8_t) __a,
- __b);
+ return __aarch64_vget_lane_u8 (__a, __b);
}
__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
vget_lane_u16 (uint16x4_t __a, const int __b)
{
- return (uint16_t) __builtin_aarch64_get_lane_unsignedv4hi ((int16x4_t) __a,
- __b);
+ return __aarch64_vget_lane_u16 (__a, __b);
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
vget_lane_u32 (uint32x2_t __a, const int __b)
{
- return (uint32_t) __builtin_aarch64_get_lane_unsignedv2si ((int32x2_t) __a,
- __b);
+ return __aarch64_vget_lane_u32 (__a, __b);
}
-__extension__ static __inline poly8_t __attribute__ ((__always_inline__))
-vget_lane_p8 (poly8x8_t __a, const int __b)
+__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
+vget_lane_u64 (uint64x1_t __a, const int __b)
{
- return (poly8_t) __builtin_aarch64_get_lane_unsignedv8qi ((int8x8_t) __a,
- __b);
+ return __aarch64_vget_lane_u64 (__a, __b);
}
-__extension__ static __inline poly16_t __attribute__ ((__always_inline__))
-vget_lane_p16 (poly16x4_t __a, const int __b)
+/* vgetq_lane */
+
+__extension__ static __inline float32_t __attribute__ ((__always_inline__))
+vgetq_lane_f32 (float32x4_t __a, const int __b)
{
- return (poly16_t) __builtin_aarch64_get_lane_unsignedv4hi ((int16x4_t) __a,
- __b);
+ return __aarch64_vgetq_lane_f32 (__a, __b);
}
-__extension__ static __inline int64_t __attribute__ ((__always_inline__))
-vget_lane_s64 (int64x1_t __a, const int __b)
+__extension__ static __inline float64_t __attribute__ ((__always_inline__))
+vgetq_lane_f64 (float64x2_t __a, const int __b)
{
- return (int64_t) __builtin_aarch64_get_lanedi (__a, __b);
+ return __aarch64_vgetq_lane_f64 (__a, __b);
}
-__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
-vget_lane_u64 (uint64x1_t __a, const int __b)
+__extension__ static __inline poly8_t __attribute__ ((__always_inline__))
+vgetq_lane_p8 (poly8x16_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_p8 (__a, __b);
+}
+
+__extension__ static __inline poly16_t __attribute__ ((__always_inline__))
+vgetq_lane_p16 (poly16x8_t __a, const int __b)
{
- return (uint64_t) __builtin_aarch64_get_lanedi ((int64x1_t) __a, __b);
+ return __aarch64_vgetq_lane_p16 (__a, __b);
}
__extension__ static __inline int8_t __attribute__ ((__always_inline__))
vgetq_lane_s8 (int8x16_t __a, const int __b)
{
- return (int8_t) __builtin_aarch64_get_lane_signedv16qi (__a, __b);
+ return __aarch64_vgetq_lane_s8 (__a, __b);
}
__extension__ static __inline int16_t __attribute__ ((__always_inline__))
vgetq_lane_s16 (int16x8_t __a, const int __b)
{
- return (int16_t) __builtin_aarch64_get_lane_signedv8hi (__a, __b);
+ return __aarch64_vgetq_lane_s16 (__a, __b);
}
__extension__ static __inline int32_t __attribute__ ((__always_inline__))
vgetq_lane_s32 (int32x4_t __a, const int __b)
{
- return (int32_t) __builtin_aarch64_get_lane_signedv4si (__a, __b);
+ return __aarch64_vgetq_lane_s32 (__a, __b);
}
-__extension__ static __inline float32_t __attribute__ ((__always_inline__))
-vgetq_lane_f32 (float32x4_t __a, const int __b)
-{
- return (float32_t) __builtin_aarch64_get_lanev4sf (__a, __b);
-}
-
-__extension__ static __inline float64_t __attribute__ ((__always_inline__))
-vgetq_lane_f64 (float64x2_t __a, const int __b)
+__extension__ static __inline int64_t __attribute__ ((__always_inline__))
+vgetq_lane_s64 (int64x2_t __a, const int __b)
{
- return (float64_t) __builtin_aarch64_get_lanev2df (__a, __b);
+ return __aarch64_vgetq_lane_s64 (__a, __b);
}
__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
vgetq_lane_u8 (uint8x16_t __a, const int __b)
{
- return (uint8_t) __builtin_aarch64_get_lane_unsignedv16qi ((int8x16_t) __a,
- __b);
+ return __aarch64_vgetq_lane_u8 (__a, __b);
}
__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
vgetq_lane_u16 (uint16x8_t __a, const int __b)
{
- return (uint16_t) __builtin_aarch64_get_lane_unsignedv8hi ((int16x8_t) __a,
- __b);
+ return __aarch64_vgetq_lane_u16 (__a, __b);
}
__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
vgetq_lane_u32 (uint32x4_t __a, const int __b)
{
- return (uint32_t) __builtin_aarch64_get_lane_unsignedv4si ((int32x4_t) __a,
- __b);
-}
-
-__extension__ static __inline poly8_t __attribute__ ((__always_inline__))
-vgetq_lane_p8 (poly8x16_t __a, const int __b)
-{
- return (poly8_t) __builtin_aarch64_get_lane_unsignedv16qi ((int8x16_t) __a,
- __b);
-}
-
-__extension__ static __inline poly16_t __attribute__ ((__always_inline__))
-vgetq_lane_p16 (poly16x8_t __a, const int __b)
-{
- return (poly16_t) __builtin_aarch64_get_lane_unsignedv8hi ((int16x8_t) __a,
- __b);
-}
-
-__extension__ static __inline int64_t __attribute__ ((__always_inline__))
-vgetq_lane_s64 (int64x2_t __a, const int __b)
-{
- return __builtin_aarch64_get_lane_unsignedv2di (__a, __b);
+ return __aarch64_vgetq_lane_u32 (__a, __b);
}
__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
vgetq_lane_u64 (uint64x2_t __a, const int __b)
{
- return (uint64_t) __builtin_aarch64_get_lane_unsignedv2di ((int64x2_t) __a,
- __b);
+ return __aarch64_vgetq_lane_u64 (__a, __b);
}
+/* vreinterpret */
+
__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
vreinterpret_p8_s8 (int8x8_t __a)
{
@@ -3805,6 +3969,85 @@ vreinterpretq_u32_p16 (poly16x8_t __a)
return (uint32x4_t) __builtin_aarch64_reinterpretv4siv8hi ((int16x8_t) __a);
}
+#define __GET_LOW(__TYPE) \
+ uint64x2_t tmp = vreinterpretq_u64_##__TYPE (__a); \
+ uint64_t lo = vgetq_lane_u64 (tmp, 0); \
+ return vreinterpret_##__TYPE##_u64 (lo);
+
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vget_low_f32 (float32x4_t __a)
+{
+ __GET_LOW (f32);
+}
+
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vget_low_f64 (float64x2_t __a)
+{
+ return vgetq_lane_f64 (__a, 0);
+}
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vget_low_p8 (poly8x16_t __a)
+{
+ __GET_LOW (p8);
+}
+
+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
+vget_low_p16 (poly16x8_t __a)
+{
+ __GET_LOW (p16);
+}
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vget_low_s8 (int8x16_t __a)
+{
+ __GET_LOW (s8);
+}
+
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vget_low_s16 (int16x8_t __a)
+{
+ __GET_LOW (s16);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vget_low_s32 (int32x4_t __a)
+{
+ __GET_LOW (s32);
+}
+
+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
+vget_low_s64 (int64x2_t __a)
+{
+ return vgetq_lane_s64 (__a, 0);
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vget_low_u8 (uint8x16_t __a)
+{
+ __GET_LOW (u8);
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vget_low_u16 (uint16x8_t __a)
+{
+ __GET_LOW (u16);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vget_low_u32 (uint32x4_t __a)
+{
+ __GET_LOW (u32);
+}
+
+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
+vget_low_u64 (uint64x2_t __a)
+{
+ return vgetq_lane_u64 (__a, 0);
+}
+
+#undef __GET_LOW
+
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
vcombine_s8 (int8x8_t __a, int8x8_t __b)
{
@@ -5534,559 +5777,6 @@ vcvtxd_f32_f64 (float64_t a)
return result;
}
-#define vdup_lane_f32(a, b) \
- __extension__ \
- ({ \
- float32x2_t a_ = (a); \
- float32x2_t result; \
- __asm__ ("dup %0.2s,%1.s[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_p8(a, b) \
- __extension__ \
- ({ \
- poly8x8_t a_ = (a); \
- poly8x8_t result; \
- __asm__ ("dup %0.8b,%1.b[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_p16(a, b) \
- __extension__ \
- ({ \
- poly16x4_t a_ = (a); \
- poly16x4_t result; \
- __asm__ ("dup %0.4h,%1.h[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_s8(a, b) \
- __extension__ \
- ({ \
- int8x8_t a_ = (a); \
- int8x8_t result; \
- __asm__ ("dup %0.8b,%1.b[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_s16(a, b) \
- __extension__ \
- ({ \
- int16x4_t a_ = (a); \
- int16x4_t result; \
- __asm__ ("dup %0.4h,%1.h[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_s32(a, b) \
- __extension__ \
- ({ \
- int32x2_t a_ = (a); \
- int32x2_t result; \
- __asm__ ("dup %0.2s,%1.s[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_s64(a, b) \
- __extension__ \
- ({ \
- int64x1_t a_ = (a); \
- int64x1_t result; \
- __asm__ ("ins %0.d[0],%1.d[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_u8(a, b) \
- __extension__ \
- ({ \
- uint8x8_t a_ = (a); \
- uint8x8_t result; \
- __asm__ ("dup %0.8b,%1.b[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_u16(a, b) \
- __extension__ \
- ({ \
- uint16x4_t a_ = (a); \
- uint16x4_t result; \
- __asm__ ("dup %0.4h,%1.h[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_u32(a, b) \
- __extension__ \
- ({ \
- uint32x2_t a_ = (a); \
- uint32x2_t result; \
- __asm__ ("dup %0.2s,%1.s[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdup_lane_u64(a, b) \
- __extension__ \
- ({ \
- uint64x1_t a_ = (a); \
- uint64x1_t result; \
- __asm__ ("ins %0.d[0],%1.d[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
-vdup_n_f32 (float32_t a)
-{
- float32x2_t result;
- __asm__ ("dup %0.2s, %w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vdup_n_p8 (uint32_t a)
-{
- poly8x8_t result;
- __asm__ ("dup %0.8b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
-vdup_n_p16 (uint32_t a)
-{
- poly16x4_t result;
- __asm__ ("dup %0.4h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vdup_n_s8 (int32_t a)
-{
- int8x8_t result;
- __asm__ ("dup %0.8b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
-vdup_n_s16 (int32_t a)
-{
- int16x4_t result;
- __asm__ ("dup %0.4h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
-vdup_n_s32 (int32_t a)
-{
- int32x2_t result;
- __asm__ ("dup %0.2s,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
-vdup_n_s64 (int64_t a)
-{
- int64x1_t result;
- __asm__ ("ins %0.d[0],%x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vdup_n_u8 (uint32_t a)
-{
- uint8x8_t result;
- __asm__ ("dup %0.8b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-vdup_n_u16 (uint32_t a)
-{
- uint16x4_t result;
- __asm__ ("dup %0.4h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
-vdup_n_u32 (uint32_t a)
-{
- uint32x2_t result;
- __asm__ ("dup %0.2s,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
-vdup_n_u64 (uint64_t a)
-{
- uint64x1_t result;
- __asm__ ("ins %0.d[0],%x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-#define vdupd_lane_f64(a, b) \
- __extension__ \
- ({ \
- float64x2_t a_ = (a); \
- float64_t result; \
- __asm__ ("dup %d0, %1.d[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_f32(a, b) \
- __extension__ \
- ({ \
- float32x2_t a_ = (a); \
- float32x4_t result; \
- __asm__ ("dup %0.4s,%1.s[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_f64(a, b) \
- __extension__ \
- ({ \
- float64x1_t a_ = (a); \
- float64x2_t result; \
- __asm__ ("dup %0.2d,%1.d[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_p8(a, b) \
- __extension__ \
- ({ \
- poly8x8_t a_ = (a); \
- poly8x16_t result; \
- __asm__ ("dup %0.16b,%1.b[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_p16(a, b) \
- __extension__ \
- ({ \
- poly16x4_t a_ = (a); \
- poly16x8_t result; \
- __asm__ ("dup %0.8h,%1.h[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_s8(a, b) \
- __extension__ \
- ({ \
- int8x8_t a_ = (a); \
- int8x16_t result; \
- __asm__ ("dup %0.16b,%1.b[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_s16(a, b) \
- __extension__ \
- ({ \
- int16x4_t a_ = (a); \
- int16x8_t result; \
- __asm__ ("dup %0.8h,%1.h[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_s32(a, b) \
- __extension__ \
- ({ \
- int32x2_t a_ = (a); \
- int32x4_t result; \
- __asm__ ("dup %0.4s,%1.s[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_s64(a, b) \
- __extension__ \
- ({ \
- int64x1_t a_ = (a); \
- int64x2_t result; \
- __asm__ ("dup %0.2d,%1.d[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_u8(a, b) \
- __extension__ \
- ({ \
- uint8x8_t a_ = (a); \
- uint8x16_t result; \
- __asm__ ("dup %0.16b,%1.b[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_u16(a, b) \
- __extension__ \
- ({ \
- uint16x4_t a_ = (a); \
- uint16x8_t result; \
- __asm__ ("dup %0.8h,%1.h[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_u32(a, b) \
- __extension__ \
- ({ \
- uint32x2_t a_ = (a); \
- uint32x4_t result; \
- __asm__ ("dup %0.4s,%1.s[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-#define vdupq_lane_u64(a, b) \
- __extension__ \
- ({ \
- uint64x1_t a_ = (a); \
- uint64x2_t result; \
- __asm__ ("dup %0.2d,%1.d[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
-vdupq_n_f32 (float32_t a)
-{
- float32x4_t result;
- __asm__ ("dup %0.4s, %w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
-vdupq_n_f64 (float64_t a)
-{
- float64x2_t result;
- __asm__ ("dup %0.2d, %x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
-vdupq_n_p8 (uint32_t a)
-{
- poly8x16_t result;
- __asm__ ("dup %0.16b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__))
-vdupq_n_p16 (uint32_t a)
-{
- poly16x8_t result;
- __asm__ ("dup %0.8h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vdupq_n_s8 (int32_t a)
-{
- int8x16_t result;
- __asm__ ("dup %0.16b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
-vdupq_n_s16 (int32_t a)
-{
- int16x8_t result;
- __asm__ ("dup %0.8h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
-vdupq_n_s32 (int32_t a)
-{
- int32x4_t result;
- __asm__ ("dup %0.4s,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
-vdupq_n_s64 (int64_t a)
-{
- int64x2_t result;
- __asm__ ("dup %0.2d,%x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
-vdupq_n_u8 (uint32_t a)
-{
- uint8x16_t result;
- __asm__ ("dup %0.16b,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
-vdupq_n_u16 (uint32_t a)
-{
- uint16x8_t result;
- __asm__ ("dup %0.8h,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
-vdupq_n_u32 (uint32_t a)
-{
- uint32x4_t result;
- __asm__ ("dup %0.4s,%w1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__))
-vdupq_n_u64 (uint64_t a)
-{
- uint64x2_t result;
- __asm__ ("dup %0.2d,%x1"
- : "=w"(result)
- : "r"(a)
- : /* No clobbers */);
- return result;
-}
-
-#define vdups_lane_f32(a, b) \
- __extension__ \
- ({ \
- float32x4_t a_ = (a); \
- float32_t result; \
- __asm__ ("dup %s0, %1.s[%2]" \
- : "=w"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
#define vext_f32(a, b, c) \
__extension__ \
({ \
@@ -6724,150 +6414,6 @@ vget_high_u64 (uint64x2_t a)
return result;
}
-#define vget_lane_f64(a, b) \
- __extension__ \
- ({ \
- float64x1_t a_ = (a); \
- float64_t result; \
- __asm__ ("umov %x0, %1.d[%2]" \
- : "=r"(result) \
- : "w"(a_), "i"(b) \
- : /* No clobbers */); \
- result; \
- })
-
-__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
-vget_low_f32 (float32x4_t a)
-{
- float32x2_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
-vget_low_f64 (float64x2_t a)
-{
- float64x1_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
-vget_low_p8 (poly8x16_t a)
-{
- poly8x8_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
-vget_low_p16 (poly16x8_t a)
-{
- poly16x4_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vget_low_s8 (int8x16_t a)
-{
- int8x8_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
-vget_low_s16 (int16x8_t a)
-{
- int16x4_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
-vget_low_s32 (int32x4_t a)
-{
- int32x2_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
-vget_low_s64 (int64x2_t a)
-{
- int64x1_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
-vget_low_u8 (uint8x16_t a)
-{
- uint8x8_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
-vget_low_u16 (uint16x8_t a)
-{
- uint16x4_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
-vget_low_u32 (uint32x4_t a)
-{
- uint32x2_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
-__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
-vget_low_u64 (uint64x2_t a)
-{
- uint64x1_t result;
- __asm__ ("ins %0.d[0], %1.d[0]"
- : "=w"(result)
- : "w"(a)
- : /* No clobbers */);
- return result;
-}
-
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
vhsub_s8 (int8x8_t a, int8x8_t b)
{
@@ -7600,7 +7146,7 @@ vld1q_dup_u64 (const uint64_t * a)
int16x4_t result; \
__asm__ ("mla %0.4h, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -7628,7 +7174,7 @@ vld1q_dup_u64 (const uint64_t * a)
uint16x4_t result; \
__asm__ ("mla %0.4h, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -7656,7 +7202,7 @@ vld1q_dup_u64 (const uint64_t * a)
int16x4_t result; \
__asm__ ("mla %0.4h, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -7684,7 +7230,7 @@ vld1q_dup_u64 (const uint64_t * a)
uint16x4_t result; \
__asm__ ("mla %0.4h, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -7721,7 +7267,7 @@ vmla_n_s16 (int16x4_t a, int16x4_t b, int16_t c)
int16x4_t result;
__asm__ ("mla %0.4h,%2.4h,%3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -7743,7 +7289,7 @@ vmla_n_u16 (uint16x4_t a, uint16x4_t b, uint16_t c)
uint16x4_t result;
__asm__ ("mla %0.4h,%2.4h,%3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -7834,7 +7380,7 @@ vmla_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
int32x4_t result; \
__asm__ ("smlal2 %0.4s, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -7862,7 +7408,7 @@ vmla_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
uint32x4_t result; \
__asm__ ("umlal2 %0.4s, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -7890,7 +7436,7 @@ vmla_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
int32x4_t result; \
__asm__ ("smlal2 %0.4s, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -7918,7 +7464,7 @@ vmla_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
uint32x4_t result; \
__asm__ ("umlal2 %0.4s, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -7943,7 +7489,7 @@ vmlal_high_n_s16 (int32x4_t a, int16x8_t b, int16_t c)
int32x4_t result;
__asm__ ("smlal2 %0.4s,%2.8h,%3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -7965,7 +7511,7 @@ vmlal_high_n_u16 (uint32x4_t a, uint16x8_t b, uint16_t c)
uint32x4_t result;
__asm__ ("umlal2 %0.4s,%2.8h,%3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8056,7 +7602,7 @@ vmlal_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c)
int32x4_t result; \
__asm__ ("smlal %0.4s,%2.4h,%3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8084,7 +7630,7 @@ vmlal_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c)
uint32x4_t result; \
__asm__ ("umlal %0.4s,%2.4h,%3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8112,7 +7658,7 @@ vmlal_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c)
int32x4_t result; \
__asm__ ("smlal %0.4s, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8140,7 +7686,7 @@ vmlal_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c)
uint32x4_t result; \
__asm__ ("umlal %0.4s, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8165,7 +7711,7 @@ vmlal_n_s16 (int32x4_t a, int16x4_t b, int16_t c)
int32x4_t result;
__asm__ ("smlal %0.4s,%2.4h,%3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8187,7 +7733,7 @@ vmlal_n_u16 (uint32x4_t a, uint16x4_t b, uint16_t c)
uint32x4_t result;
__asm__ ("umlal %0.4s,%2.4h,%3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8293,7 +7839,7 @@ vmlal_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c)
int16x8_t result; \
__asm__ ("mla %0.8h, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8321,7 +7867,7 @@ vmlal_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c)
uint16x8_t result; \
__asm__ ("mla %0.8h, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8349,7 +7895,7 @@ vmlal_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c)
int16x8_t result; \
__asm__ ("mla %0.8h, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8377,7 +7923,7 @@ vmlal_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c)
uint16x8_t result; \
__asm__ ("mla %0.8h, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8426,7 +7972,7 @@ vmlaq_n_s16 (int16x8_t a, int16x8_t b, int16_t c)
int16x8_t result;
__asm__ ("mla %0.8h,%2.8h,%3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8448,7 +7994,7 @@ vmlaq_n_u16 (uint16x8_t a, uint16x8_t b, uint16_t c)
uint16x8_t result;
__asm__ ("mla %0.8h,%2.8h,%3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8554,7 +8100,7 @@ vmlaq_u32 (uint32x4_t a, uint32x4_t b, uint32x4_t c)
int16x4_t result; \
__asm__ ("mls %0.4h,%2.4h,%3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8582,7 +8128,7 @@ vmlaq_u32 (uint32x4_t a, uint32x4_t b, uint32x4_t c)
uint16x4_t result; \
__asm__ ("mls %0.4h,%2.4h,%3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8619,7 +8165,7 @@ vmls_n_s16 (int16x4_t a, int16x4_t b, int16_t c)
int16x4_t result;
__asm__ ("mls %0.4h, %2.4h, %3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8641,7 +8187,7 @@ vmls_n_u16 (uint16x4_t a, uint16x4_t b, uint16_t c)
uint16x4_t result;
__asm__ ("mls %0.4h, %2.4h, %3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8732,7 +8278,7 @@ vmls_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
int32x4_t result; \
__asm__ ("smlsl2 %0.4s, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8760,7 +8306,7 @@ vmls_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
uint32x4_t result; \
__asm__ ("umlsl2 %0.4s, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8788,7 +8334,7 @@ vmls_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
int32x4_t result; \
__asm__ ("smlsl2 %0.4s, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8816,7 +8362,7 @@ vmls_u32 (uint32x2_t a, uint32x2_t b, uint32x2_t c)
uint32x4_t result; \
__asm__ ("umlsl2 %0.4s, %2.8h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8841,7 +8387,7 @@ vmlsl_high_n_s16 (int32x4_t a, int16x8_t b, int16_t c)
int32x4_t result;
__asm__ ("smlsl2 %0.4s, %2.8h, %3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8863,7 +8409,7 @@ vmlsl_high_n_u16 (uint32x4_t a, uint16x8_t b, uint16_t c)
uint32x4_t result;
__asm__ ("umlsl2 %0.4s, %2.8h, %3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -8954,7 +8500,7 @@ vmlsl_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c)
int32x4_t result; \
__asm__ ("smlsl %0.4s, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -8982,7 +8528,7 @@ vmlsl_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c)
uint32x4_t result; \
__asm__ ("umlsl %0.4s, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -9010,7 +8556,7 @@ vmlsl_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c)
int32x4_t result; \
__asm__ ("smlsl %0.4s, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -9038,7 +8584,7 @@ vmlsl_high_u32 (uint64x2_t a, uint32x4_t b, uint32x4_t c)
uint32x4_t result; \
__asm__ ("umlsl %0.4s, %2.4h, %3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -9063,7 +8609,7 @@ vmlsl_n_s16 (int32x4_t a, int16x4_t b, int16_t c)
int32x4_t result;
__asm__ ("smlsl %0.4s, %2.4h, %3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -9085,7 +8631,7 @@ vmlsl_n_u16 (uint32x4_t a, uint16x4_t b, uint16_t c)
uint32x4_t result;
__asm__ ("umlsl %0.4s, %2.4h, %3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -9191,7 +8737,7 @@ vmlsl_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c)
int16x8_t result; \
__asm__ ("mls %0.8h,%2.8h,%3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -9219,7 +8765,7 @@ vmlsl_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c)
uint16x8_t result; \
__asm__ ("mls %0.8h,%2.8h,%3.h[%4]" \
: "=w"(result) \
- : "0"(a_), "w"(b_), "w"(c_), "i"(d) \
+ : "0"(a_), "w"(b_), "x"(c_), "i"(d) \
: /* No clobbers */); \
result; \
})
@@ -9262,7 +8808,7 @@ vmlsl_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c)
int16x8_t __result; \
__asm__ ("mls %0.8h, %2.8h, %3.h[%4]" \
: "=w"(__result) \
- : "0"(__a_), "w"(__b_), "w"(__c_), "i"(__d) \
+ : "0"(__a_), "w"(__b_), "x"(__c_), "i"(__d) \
: /* No clobbers */); \
__result; \
})
@@ -9290,7 +8836,7 @@ vmlsl_u32 (uint64x2_t a, uint32x2_t b, uint32x2_t c)
uint16x8_t __result; \
__asm__ ("mls %0.8h, %2.8h, %3.h[%4]" \
: "=w"(__result) \
- : "0"(__a_), "w"(__b_), "w"(__c_), "i"(__d) \
+ : "0"(__a_), "w"(__b_), "x"(__c_), "i"(__d) \
: /* No clobbers */); \
__result; \
})
@@ -9328,7 +8874,7 @@ vmlsq_n_f64 (float64x2_t a, float64x2_t b, float64_t c)
float64x2_t t1;
__asm__ ("fmul %1.2d, %3.2d, %4.d[0]; fsub %0.2d, %0.2d, %1.2d"
: "=w"(result), "=w"(t1)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -9339,7 +8885,7 @@ vmlsq_n_s16 (int16x8_t a, int16x8_t b, int16_t c)
int16x8_t result;
__asm__ ("mls %0.8h, %2.8h, %3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -9361,7 +8907,7 @@ vmlsq_n_u16 (uint16x8_t a, uint16x8_t b, uint16_t c)
uint16x8_t result;
__asm__ ("mls %0.8h, %2.8h, %3.h[0]"
: "=w"(result)
- : "0"(a), "w"(b), "w"(c)
+ : "0"(a), "w"(b), "x"(c)
: /* No clobbers */);
return result;
}
@@ -9699,7 +9245,7 @@ vmovl_u32 (uint32x2_t a)
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
vmovn_high_s16 (int8x8_t a, int16x8_t b)
{
- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0)));
+ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("xtn2 %0.16b,%1.8h"
: "+w"(result)
: "w"(b)
@@ -9710,7 +9256,7 @@ vmovn_high_s16 (int8x8_t a, int16x8_t b)
__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
vmovn_high_s32 (int16x4_t a, int32x4_t b)
{
- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0)));
+ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("xtn2 %0.8h,%1.4s"
: "+w"(result)
: "w"(b)
@@ -9721,7 +9267,7 @@ vmovn_high_s32 (int16x4_t a, int32x4_t b)
__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
vmovn_high_s64 (int32x2_t a, int64x2_t b)
{
- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0)));
+ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("xtn2 %0.4s,%1.2d"
: "+w"(result)
: "w"(b)
@@ -9732,7 +9278,7 @@ vmovn_high_s64 (int32x2_t a, int64x2_t b)
__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
vmovn_high_u16 (uint8x8_t a, uint16x8_t b)
{
- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0)));
+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("xtn2 %0.16b,%1.8h"
: "+w"(result)
: "w"(b)
@@ -9743,7 +9289,7 @@ vmovn_high_u16 (uint8x8_t a, uint16x8_t b)
__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
vmovn_high_u32 (uint16x4_t a, uint32x4_t b)
{
- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0)));
+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("xtn2 %0.8h,%1.4s"
: "+w"(result)
: "w"(b)
@@ -9754,7 +9300,7 @@ vmovn_high_u32 (uint16x4_t a, uint32x4_t b)
__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
vmovn_high_u64 (uint32x2_t a, uint64x2_t b)
{
- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0)));
+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("xtn2 %0.4s,%1.2d"
: "+w"(result)
: "w"(b)
@@ -10102,7 +9648,7 @@ vmul_n_s16 (int16x4_t a, int16_t b)
int16x4_t result;
__asm__ ("mul %0.4h,%1.4h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -10124,7 +9670,7 @@ vmul_n_u16 (uint16x4_t a, uint16_t b)
uint16x4_t result;
__asm__ ("mul %0.4h,%1.4h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -10161,7 +9707,7 @@ vmul_n_u32 (uint32x2_t a, uint32_t b)
int32x4_t result; \
__asm__ ("smull2 %0.4s, %1.8h, %2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10187,7 +9733,7 @@ vmul_n_u32 (uint32x2_t a, uint32_t b)
uint32x4_t result; \
__asm__ ("umull2 %0.4s, %1.8h, %2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10213,7 +9759,7 @@ vmul_n_u32 (uint32x2_t a, uint32_t b)
int32x4_t result; \
__asm__ ("smull2 %0.4s, %1.8h, %2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10239,7 +9785,7 @@ vmul_n_u32 (uint32x2_t a, uint32_t b)
uint32x4_t result; \
__asm__ ("umull2 %0.4s, %1.8h, %2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10263,7 +9809,7 @@ vmull_high_n_s16 (int16x8_t a, int16_t b)
int32x4_t result;
__asm__ ("smull2 %0.4s,%1.8h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -10285,7 +9831,7 @@ vmull_high_n_u16 (uint16x8_t a, uint16_t b)
uint32x4_t result;
__asm__ ("umull2 %0.4s,%1.8h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -10386,7 +9932,7 @@ vmull_high_u32 (uint32x4_t a, uint32x4_t b)
int32x4_t result; \
__asm__ ("smull %0.4s,%1.4h,%2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10412,7 +9958,7 @@ vmull_high_u32 (uint32x4_t a, uint32x4_t b)
uint32x4_t result; \
__asm__ ("umull %0.4s,%1.4h,%2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10438,7 +9984,7 @@ vmull_high_u32 (uint32x4_t a, uint32x4_t b)
int32x4_t result; \
__asm__ ("smull %0.4s, %1.4h, %2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10464,7 +10010,7 @@ vmull_high_u32 (uint32x4_t a, uint32x4_t b)
uint32x4_t result; \
__asm__ ("umull %0.4s, %1.4h, %2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10488,7 +10034,7 @@ vmull_n_s16 (int16x4_t a, int16_t b)
int32x4_t result;
__asm__ ("smull %0.4s,%1.4h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -10510,7 +10056,7 @@ vmull_n_u16 (uint16x4_t a, uint16_t b)
uint32x4_t result;
__asm__ ("umull %0.4s,%1.4h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -10637,7 +10183,7 @@ vmull_u32 (uint32x2_t a, uint32x2_t b)
int16x8_t result; \
__asm__ ("mul %0.8h,%1.8h,%2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10663,7 +10209,7 @@ vmull_u32 (uint32x2_t a, uint32x2_t b)
uint16x8_t result; \
__asm__ ("mul %0.8h,%1.8h,%2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10715,7 +10261,7 @@ vmull_u32 (uint32x2_t a, uint32x2_t b)
int16x8_t result; \
__asm__ ("mul %0.8h, %1.8h, %2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10741,7 +10287,7 @@ vmull_u32 (uint32x2_t a, uint32x2_t b)
uint16x8_t result; \
__asm__ ("mul %0.8h, %1.8h, %2.h[%3]" \
: "=w"(result) \
- : "w"(a_), "w"(b_), "i"(c) \
+ : "w"(a_), "x"(b_), "i"(c) \
: /* No clobbers */); \
result; \
})
@@ -10787,7 +10333,7 @@ vmulq_n_s16 (int16x8_t a, int16_t b)
int16x8_t result;
__asm__ ("mul %0.8h,%1.8h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -10809,7 +10355,7 @@ vmulq_n_u16 (uint16x8_t a, uint16_t b)
uint16x8_t result;
__asm__ ("mul %0.8h,%1.8h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -12173,7 +11719,7 @@ vqdmulhq_n_s32 (int32x4_t a, int32_t b)
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
vqmovn_high_s16 (int8x8_t a, int16x8_t b)
{
- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0)));
+ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("sqxtn2 %0.16b, %1.8h"
: "+w"(result)
: "w"(b)
@@ -12184,7 +11730,7 @@ vqmovn_high_s16 (int8x8_t a, int16x8_t b)
__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
vqmovn_high_s32 (int16x4_t a, int32x4_t b)
{
- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0)));
+ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("sqxtn2 %0.8h, %1.4s"
: "+w"(result)
: "w"(b)
@@ -12195,7 +11741,7 @@ vqmovn_high_s32 (int16x4_t a, int32x4_t b)
__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
vqmovn_high_s64 (int32x2_t a, int64x2_t b)
{
- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0)));
+ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("sqxtn2 %0.4s, %1.2d"
: "+w"(result)
: "w"(b)
@@ -12206,7 +11752,7 @@ vqmovn_high_s64 (int32x2_t a, int64x2_t b)
__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
vqmovn_high_u16 (uint8x8_t a, uint16x8_t b)
{
- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0)));
+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("uqxtn2 %0.16b, %1.8h"
: "+w"(result)
: "w"(b)
@@ -12217,7 +11763,7 @@ vqmovn_high_u16 (uint8x8_t a, uint16x8_t b)
__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
vqmovn_high_u32 (uint16x4_t a, uint32x4_t b)
{
- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0)));
+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("uqxtn2 %0.8h, %1.4s"
: "+w"(result)
: "w"(b)
@@ -12228,7 +11774,7 @@ vqmovn_high_u32 (uint16x4_t a, uint32x4_t b)
__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
vqmovn_high_u64 (uint32x2_t a, uint64x2_t b)
{
- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0)));
+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("uqxtn2 %0.4s, %1.2d"
: "+w"(result)
: "w"(b)
@@ -12239,7 +11785,7 @@ vqmovn_high_u64 (uint32x2_t a, uint64x2_t b)
__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
vqmovun_high_s16 (uint8x8_t a, int16x8_t b)
{
- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0)));
+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("sqxtun2 %0.16b, %1.8h"
: "+w"(result)
: "w"(b)
@@ -12250,7 +11796,7 @@ vqmovun_high_s16 (uint8x8_t a, int16x8_t b)
__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
vqmovun_high_s32 (uint16x4_t a, int32x4_t b)
{
- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0)));
+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("sqxtun2 %0.8h, %1.4s"
: "+w"(result)
: "w"(b)
@@ -12261,7 +11807,7 @@ vqmovun_high_s32 (uint16x4_t a, int32x4_t b)
__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
vqmovun_high_s64 (uint32x2_t a, int64x2_t b)
{
- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0)));
+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("sqxtun2 %0.4s, %1.2d"
: "+w"(result)
: "w"(b)
@@ -12275,7 +11821,7 @@ vqrdmulh_n_s16 (int16x4_t a, int16_t b)
int16x4_t result;
__asm__ ("sqrdmulh %0.4h,%1.4h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -12297,7 +11843,7 @@ vqrdmulhq_n_s16 (int16x8_t a, int16_t b)
int16x8_t result;
__asm__ ("sqrdmulh %0.8h,%1.8h,%2.h[0]"
: "=w"(result)
- : "w"(a), "w"(b)
+ : "w"(a), "x"(b)
: /* No clobbers */);
return result;
}
@@ -12319,7 +11865,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int16x8_t b_ = (b); \
int8x8_t a_ = (a); \
int8x16_t result = vcombine_s8 \
- (a_, vcreate_s8 (UINT64_C (0x0))); \
+ (a_, vcreate_s8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqrshrn2 %0.16b, %1.8h, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12333,7 +11880,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int32x4_t b_ = (b); \
int16x4_t a_ = (a); \
int16x8_t result = vcombine_s16 \
- (a_, vcreate_s16 (UINT64_C (0x0))); \
+ (a_, vcreate_s16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqrshrn2 %0.8h, %1.4s, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12347,7 +11895,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int64x2_t b_ = (b); \
int32x2_t a_ = (a); \
int32x4_t result = vcombine_s32 \
- (a_, vcreate_s32 (UINT64_C (0x0))); \
+ (a_, vcreate_s32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqrshrn2 %0.4s, %1.2d, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12361,7 +11910,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
uint16x8_t b_ = (b); \
uint8x8_t a_ = (a); \
uint8x16_t result = vcombine_u8 \
- (a_, vcreate_u8 (UINT64_C (0x0))); \
+ (a_, vcreate_u8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("uqrshrn2 %0.16b, %1.8h, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12375,7 +11925,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
uint32x4_t b_ = (b); \
uint16x4_t a_ = (a); \
uint16x8_t result = vcombine_u16 \
- (a_, vcreate_u16 (UINT64_C (0x0))); \
+ (a_, vcreate_u16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("uqrshrn2 %0.8h, %1.4s, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12389,7 +11940,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
uint64x2_t b_ = (b); \
uint32x2_t a_ = (a); \
uint32x4_t result = vcombine_u32 \
- (a_, vcreate_u32 (UINT64_C (0x0))); \
+ (a_, vcreate_u32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("uqrshrn2 %0.4s, %1.2d, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12403,7 +11955,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int16x8_t b_ = (b); \
uint8x8_t a_ = (a); \
uint8x16_t result = vcombine_u8 \
- (a_, vcreate_u8 (UINT64_C (0x0))); \
+ (a_, vcreate_u8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqrshrun2 %0.16b, %1.8h, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12417,7 +11970,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int32x4_t b_ = (b); \
uint16x4_t a_ = (a); \
uint16x8_t result = vcombine_u16 \
- (a_, vcreate_u16 (UINT64_C (0x0))); \
+ (a_, vcreate_u16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqrshrun2 %0.8h, %1.4s, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12431,7 +11985,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int64x2_t b_ = (b); \
uint32x2_t a_ = (a); \
uint32x4_t result = vcombine_u32 \
- (a_, vcreate_u32 (UINT64_C (0x0))); \
+ (a_, vcreate_u32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqrshrun2 %0.4s, %1.2d, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12445,7 +12000,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int16x8_t b_ = (b); \
int8x8_t a_ = (a); \
int8x16_t result = vcombine_s8 \
- (a_, vcreate_s8 (UINT64_C (0x0))); \
+ (a_, vcreate_s8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqshrn2 %0.16b, %1.8h, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12459,7 +12015,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int32x4_t b_ = (b); \
int16x4_t a_ = (a); \
int16x8_t result = vcombine_s16 \
- (a_, vcreate_s16 (UINT64_C (0x0))); \
+ (a_, vcreate_s16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqshrn2 %0.8h, %1.4s, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12473,7 +12030,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int64x2_t b_ = (b); \
int32x2_t a_ = (a); \
int32x4_t result = vcombine_s32 \
- (a_, vcreate_s32 (UINT64_C (0x0))); \
+ (a_, vcreate_s32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqshrn2 %0.4s, %1.2d, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12487,7 +12045,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
uint16x8_t b_ = (b); \
uint8x8_t a_ = (a); \
uint8x16_t result = vcombine_u8 \
- (a_, vcreate_u8 (UINT64_C (0x0))); \
+ (a_, vcreate_u8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("uqshrn2 %0.16b, %1.8h, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12501,7 +12060,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
uint32x4_t b_ = (b); \
uint16x4_t a_ = (a); \
uint16x8_t result = vcombine_u16 \
- (a_, vcreate_u16 (UINT64_C (0x0))); \
+ (a_, vcreate_u16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("uqshrn2 %0.8h, %1.4s, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12515,7 +12075,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
uint64x2_t b_ = (b); \
uint32x2_t a_ = (a); \
uint32x4_t result = vcombine_u32 \
- (a_, vcreate_u32 (UINT64_C (0x0))); \
+ (a_, vcreate_u32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("uqshrn2 %0.4s, %1.2d, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12529,7 +12090,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int16x8_t b_ = (b); \
uint8x8_t a_ = (a); \
uint8x16_t result = vcombine_u8 \
- (a_, vcreate_u8 (UINT64_C (0x0))); \
+ (a_, vcreate_u8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqshrun2 %0.16b, %1.8h, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12543,7 +12105,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int32x4_t b_ = (b); \
uint16x4_t a_ = (a); \
uint16x8_t result = vcombine_u16 \
- (a_, vcreate_u16 (UINT64_C (0x0))); \
+ (a_, vcreate_u16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqshrun2 %0.8h, %1.4s, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -12557,7 +12120,8 @@ vqrdmulhq_n_s32 (int32x4_t a, int32_t b)
int64x2_t b_ = (b); \
uint32x2_t a_ = (a); \
uint32x4_t result = vcombine_u32 \
- (a_, vcreate_u32 (UINT64_C (0x0))); \
+ (a_, vcreate_u32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("sqshrun2 %0.4s, %1.2d, #%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13033,7 +12597,8 @@ vrev64q_u32 (uint32x4_t a)
int16x8_t b_ = (b); \
int8x8_t a_ = (a); \
int8x16_t result = vcombine_s8 \
- (a_, vcreate_s8 (UINT64_C (0x0))); \
+ (a_, vcreate_s8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("rshrn2 %0.16b,%1.8h,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13047,7 +12612,8 @@ vrev64q_u32 (uint32x4_t a)
int32x4_t b_ = (b); \
int16x4_t a_ = (a); \
int16x8_t result = vcombine_s16 \
- (a_, vcreate_s16 (UINT64_C (0x0))); \
+ (a_, vcreate_s16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("rshrn2 %0.8h,%1.4s,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13061,7 +12627,8 @@ vrev64q_u32 (uint32x4_t a)
int64x2_t b_ = (b); \
int32x2_t a_ = (a); \
int32x4_t result = vcombine_s32 \
- (a_, vcreate_s32 (UINT64_C (0x0))); \
+ (a_, vcreate_s32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("rshrn2 %0.4s,%1.2d,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13075,7 +12642,8 @@ vrev64q_u32 (uint32x4_t a)
uint16x8_t b_ = (b); \
uint8x8_t a_ = (a); \
uint8x16_t result = vcombine_u8 \
- (a_, vcreate_u8 (UINT64_C (0x0))); \
+ (a_, vcreate_u8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("rshrn2 %0.16b,%1.8h,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13089,7 +12657,8 @@ vrev64q_u32 (uint32x4_t a)
uint32x4_t b_ = (b); \
uint16x4_t a_ = (a); \
uint16x8_t result = vcombine_u16 \
- (a_, vcreate_u16 (UINT64_C (0x0))); \
+ (a_, vcreate_u16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("rshrn2 %0.8h,%1.4s,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13103,7 +12672,8 @@ vrev64q_u32 (uint32x4_t a)
uint64x2_t b_ = (b); \
uint32x2_t a_ = (a); \
uint32x4_t result = vcombine_u32 \
- (a_, vcreate_u32 (UINT64_C (0x0))); \
+ (a_, vcreate_u32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("rshrn2 %0.4s,%1.2d,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13340,7 +12910,7 @@ vrsrtsq_f64 (float64x2_t a, float64x2_t b)
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
vrsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c)
{
- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0)));
+ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("rsubhn2 %0.16b, %1.8h, %2.8h"
: "+w"(result)
: "w"(b), "w"(c)
@@ -13351,7 +12921,7 @@ vrsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c)
__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
vrsubhn_high_s32 (int16x4_t a, int32x4_t b, int32x4_t c)
{
- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0)));
+ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("rsubhn2 %0.8h, %1.4s, %2.4s"
: "+w"(result)
: "w"(b), "w"(c)
@@ -13362,7 +12932,7 @@ vrsubhn_high_s32 (int16x4_t a, int32x4_t b, int32x4_t c)
__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
vrsubhn_high_s64 (int32x2_t a, int64x2_t b, int64x2_t c)
{
- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0)));
+ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("rsubhn2 %0.4s, %1.2d, %2.2d"
: "+w"(result)
: "w"(b), "w"(c)
@@ -13373,7 +12943,7 @@ vrsubhn_high_s64 (int32x2_t a, int64x2_t b, int64x2_t c)
__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
vrsubhn_high_u16 (uint8x8_t a, uint16x8_t b, uint16x8_t c)
{
- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0)));
+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("rsubhn2 %0.16b, %1.8h, %2.8h"
: "+w"(result)
: "w"(b), "w"(c)
@@ -13384,7 +12954,7 @@ vrsubhn_high_u16 (uint8x8_t a, uint16x8_t b, uint16x8_t c)
__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
vrsubhn_high_u32 (uint16x4_t a, uint32x4_t b, uint32x4_t c)
{
- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0)));
+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("rsubhn2 %0.8h, %1.4s, %2.4s"
: "+w"(result)
: "w"(b), "w"(c)
@@ -13395,7 +12965,7 @@ vrsubhn_high_u32 (uint16x4_t a, uint32x4_t b, uint32x4_t c)
__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
vrsubhn_high_u64 (uint32x2_t a, uint64x2_t b, uint64x2_t c)
{
- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0)));
+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("rsubhn2 %0.4s, %1.2d, %2.2d"
: "+w"(result)
: "w"(b), "w"(c)
@@ -13787,7 +13357,8 @@ vrsubhn_u64 (uint64x2_t a, uint64x2_t b)
int16x8_t b_ = (b); \
int8x8_t a_ = (a); \
int8x16_t result = vcombine_s8 \
- (a_, vcreate_s8 (UINT64_C (0x0))); \
+ (a_, vcreate_s8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("shrn2 %0.16b,%1.8h,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13801,7 +13372,8 @@ vrsubhn_u64 (uint64x2_t a, uint64x2_t b)
int32x4_t b_ = (b); \
int16x4_t a_ = (a); \
int16x8_t result = vcombine_s16 \
- (a_, vcreate_s16 (UINT64_C (0x0))); \
+ (a_, vcreate_s16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("shrn2 %0.8h,%1.4s,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13815,7 +13387,8 @@ vrsubhn_u64 (uint64x2_t a, uint64x2_t b)
int64x2_t b_ = (b); \
int32x2_t a_ = (a); \
int32x4_t result = vcombine_s32 \
- (a_, vcreate_s32 (UINT64_C (0x0))); \
+ (a_, vcreate_s32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("shrn2 %0.4s,%1.2d,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13829,7 +13402,8 @@ vrsubhn_u64 (uint64x2_t a, uint64x2_t b)
uint16x8_t b_ = (b); \
uint8x8_t a_ = (a); \
uint8x16_t result = vcombine_u8 \
- (a_, vcreate_u8 (UINT64_C (0x0))); \
+ (a_, vcreate_u8 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("shrn2 %0.16b,%1.8h,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13843,7 +13417,8 @@ vrsubhn_u64 (uint64x2_t a, uint64x2_t b)
uint32x4_t b_ = (b); \
uint16x4_t a_ = (a); \
uint16x8_t result = vcombine_u16 \
- (a_, vcreate_u16 (UINT64_C (0x0))); \
+ (a_, vcreate_u16 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("shrn2 %0.8h,%1.4s,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -13857,7 +13432,8 @@ vrsubhn_u64 (uint64x2_t a, uint64x2_t b)
uint64x2_t b_ = (b); \
uint32x2_t a_ = (a); \
uint32x4_t result = vcombine_u32 \
- (a_, vcreate_u32 (UINT64_C (0x0))); \
+ (a_, vcreate_u32 \
+ (__AARCH64_UINT64_C (0x0))); \
__asm__ ("shrn2 %0.4s,%1.2d,#%2" \
: "+w"(result) \
: "w"(b_), "i"(c) \
@@ -14309,7 +13885,7 @@ vrsubhn_u64 (uint64x2_t a, uint64x2_t b)
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
vsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c)
{
- int8x16_t result = vcombine_s8 (a, vcreate_s8 (UINT64_C (0x0)));
+ int8x16_t result = vcombine_s8 (a, vcreate_s8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("subhn2 %0.16b, %1.8h, %2.8h"
: "+w"(result)
: "w"(b), "w"(c)
@@ -14320,7 +13896,7 @@ vsubhn_high_s16 (int8x8_t a, int16x8_t b, int16x8_t c)
__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
vsubhn_high_s32 (int16x4_t a, int32x4_t b, int32x4_t c)
{
- int16x8_t result = vcombine_s16 (a, vcreate_s16 (UINT64_C (0x0)));
+ int16x8_t result = vcombine_s16 (a, vcreate_s16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("subhn2 %0.8h, %1.4s, %2.4s"
: "+w"(result)
: "w"(b), "w"(c)
@@ -14331,7 +13907,7 @@ vsubhn_high_s32 (int16x4_t a, int32x4_t b, int32x4_t c)
__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
vsubhn_high_s64 (int32x2_t a, int64x2_t b, int64x2_t c)
{
- int32x4_t result = vcombine_s32 (a, vcreate_s32 (UINT64_C (0x0)));
+ int32x4_t result = vcombine_s32 (a, vcreate_s32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("subhn2 %0.4s, %1.2d, %2.2d"
: "+w"(result)
: "w"(b), "w"(c)
@@ -14342,7 +13918,7 @@ vsubhn_high_s64 (int32x2_t a, int64x2_t b, int64x2_t c)
__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
vsubhn_high_u16 (uint8x8_t a, uint16x8_t b, uint16x8_t c)
{
- uint8x16_t result = vcombine_u8 (a, vcreate_u8 (UINT64_C (0x0)));
+ uint8x16_t result = vcombine_u8 (a, vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("subhn2 %0.16b, %1.8h, %2.8h"
: "+w"(result)
: "w"(b), "w"(c)
@@ -14353,7 +13929,7 @@ vsubhn_high_u16 (uint8x8_t a, uint16x8_t b, uint16x8_t c)
__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
vsubhn_high_u32 (uint16x4_t a, uint32x4_t b, uint32x4_t c)
{
- uint16x8_t result = vcombine_u16 (a, vcreate_u16 (UINT64_C (0x0)));
+ uint16x8_t result = vcombine_u16 (a, vcreate_u16 (__AARCH64_UINT64_C (0x0)));
__asm__ ("subhn2 %0.8h, %1.4s, %2.4s"
: "+w"(result)
: "w"(b), "w"(c)
@@ -14364,7 +13940,7 @@ vsubhn_high_u32 (uint16x4_t a, uint32x4_t b, uint32x4_t c)
__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
vsubhn_high_u64 (uint32x2_t a, uint64x2_t b, uint64x2_t c)
{
- uint32x4_t result = vcombine_u32 (a, vcreate_u32 (UINT64_C (0x0)));
+ uint32x4_t result = vcombine_u32 (a, vcreate_u32 (__AARCH64_UINT64_C (0x0)));
__asm__ ("subhn2 %0.4s, %1.2d, %2.2d"
: "+w"(result)
: "w"(b), "w"(c)
@@ -16397,7 +15973,7 @@ vqtbl1_p8 (poly8x16_t a, uint8x8_t b)
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vqtbl1_s8 (int8x16_t a, int8x8_t b)
+vqtbl1_s8 (int8x16_t a, uint8x8_t b)
{
int8x8_t result;
__asm__ ("tbl %0.8b, {%1.16b}, %2.8b"
@@ -16430,7 +16006,7 @@ vqtbl1q_p8 (poly8x16_t a, uint8x16_t b)
}
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vqtbl1q_s8 (int8x16_t a, int8x16_t b)
+vqtbl1q_s8 (int8x16_t a, uint8x16_t b)
{
int8x16_t result;
__asm__ ("tbl %0.16b, {%1.16b}, %2.16b"
@@ -16452,7 +16028,7 @@ vqtbl1q_u8 (uint8x16_t a, uint8x16_t b)
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vqtbl2_s8 (int8x16x2_t tab, int8x8_t idx)
+vqtbl2_s8 (int8x16x2_t tab, uint8x8_t idx)
{
int8x8_t result;
__asm__ ("ld1 {v16.16b, v17.16b}, %1\n\t"
@@ -16488,7 +16064,7 @@ vqtbl2_p8 (poly8x16x2_t tab, uint8x8_t idx)
}
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vqtbl2q_s8 (int8x16x2_t tab, int8x16_t idx)
+vqtbl2q_s8 (int8x16x2_t tab, uint8x16_t idx)
{
int8x16_t result;
__asm__ ("ld1 {v16.16b, v17.16b}, %1\n\t"
@@ -16524,7 +16100,7 @@ vqtbl2q_p8 (poly8x16x2_t tab, uint8x16_t idx)
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vqtbl3_s8 (int8x16x3_t tab, int8x8_t idx)
+vqtbl3_s8 (int8x16x3_t tab, uint8x8_t idx)
{
int8x8_t result;
__asm__ ("ld1 {v16.16b - v18.16b}, %1\n\t"
@@ -16560,7 +16136,7 @@ vqtbl3_p8 (poly8x16x3_t tab, uint8x8_t idx)
}
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vqtbl3q_s8 (int8x16x3_t tab, int8x16_t idx)
+vqtbl3q_s8 (int8x16x3_t tab, uint8x16_t idx)
{
int8x16_t result;
__asm__ ("ld1 {v16.16b - v18.16b}, %1\n\t"
@@ -16596,7 +16172,7 @@ vqtbl3q_p8 (poly8x16x3_t tab, uint8x16_t idx)
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vqtbl4_s8 (int8x16x4_t tab, int8x8_t idx)
+vqtbl4_s8 (int8x16x4_t tab, uint8x8_t idx)
{
int8x8_t result;
__asm__ ("ld1 {v16.16b - v19.16b}, %1\n\t"
@@ -16633,7 +16209,7 @@ vqtbl4_p8 (poly8x16x4_t tab, uint8x8_t idx)
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vqtbl4q_s8 (int8x16x4_t tab, int8x16_t idx)
+vqtbl4q_s8 (int8x16x4_t tab, uint8x16_t idx)
{
int8x16_t result;
__asm__ ("ld1 {v16.16b - v19.16b}, %1\n\t"
@@ -16670,7 +16246,7 @@ vqtbl4q_p8 (poly8x16x4_t tab, uint8x16_t idx)
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vqtbx1_s8 (int8x8_t r, int8x16_t tab, int8x8_t idx)
+vqtbx1_s8 (int8x8_t r, int8x16_t tab, uint8x8_t idx)
{
int8x8_t result = r;
__asm__ ("tbx %0.8b,{%1.16b},%2.8b"
@@ -16703,7 +16279,7 @@ vqtbx1_p8 (poly8x8_t r, poly8x16_t tab, uint8x8_t idx)
}
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vqtbx1q_s8 (int8x16_t r, int8x16_t tab, int8x16_t idx)
+vqtbx1q_s8 (int8x16_t r, int8x16_t tab, uint8x16_t idx)
{
int8x16_t result = r;
__asm__ ("tbx %0.16b,{%1.16b},%2.16b"
@@ -16736,7 +16312,7 @@ vqtbx1q_p8 (poly8x16_t r, poly8x16_t tab, uint8x16_t idx)
}
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vqtbx2_s8 (int8x8_t r, int8x16x2_t tab, int8x8_t idx)
+vqtbx2_s8 (int8x8_t r, int8x16x2_t tab, uint8x8_t idx)
{
int8x8_t result = r;
__asm__ ("ld1 {v16.16b, v17.16b}, %1\n\t"
@@ -16773,7 +16349,7 @@ vqtbx2_p8 (poly8x8_t r, poly8x16x2_t tab, uint8x8_t idx)
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vqtbx2q_s8 (int8x16_t r, int8x16x2_t tab, int8x16_t idx)
+vqtbx2q_s8 (int8x16_t r, int8x16x2_t tab, uint8x16_t idx)
{
int8x16_t result = r;
__asm__ ("ld1 {v16.16b, v17.16b}, %1\n\t"
@@ -16810,7 +16386,7 @@ vqtbx2q_p8 (poly8x16_t r, poly8x16x2_t tab, uint8x16_t idx)
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vqtbx3_s8 (int8x8_t r, int8x16x3_t tab, int8x8_t idx)
+vqtbx3_s8 (int8x8_t r, int8x16x3_t tab, uint8x8_t idx)
{
int8x8_t result = r;
__asm__ ("ld1 {v16.16b - v18.16b}, %1\n\t"
@@ -16847,7 +16423,7 @@ vqtbx3_p8 (poly8x8_t r, poly8x16x3_t tab, uint8x8_t idx)
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vqtbx3q_s8 (int8x16_t r, int8x16x3_t tab, int8x16_t idx)
+vqtbx3q_s8 (int8x16_t r, int8x16x3_t tab, uint8x16_t idx)
{
int8x16_t result = r;
__asm__ ("ld1 {v16.16b - v18.16b}, %1\n\t"
@@ -16884,7 +16460,7 @@ vqtbx3q_p8 (poly8x16_t r, poly8x16x3_t tab, uint8x16_t idx)
__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
-vqtbx4_s8 (int8x8_t r, int8x16x4_t tab, int8x8_t idx)
+vqtbx4_s8 (int8x8_t r, int8x16x4_t tab, uint8x8_t idx)
{
int8x8_t result = r;
__asm__ ("ld1 {v16.16b - v19.16b}, %1\n\t"
@@ -16921,7 +16497,7 @@ vqtbx4_p8 (poly8x8_t r, poly8x16x4_t tab, uint8x8_t idx)
__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
-vqtbx4q_s8 (int8x16_t r, int8x16x4_t tab, int8x16_t idx)
+vqtbx4q_s8 (int8x16_t r, int8x16x4_t tab, uint8x16_t idx)
{
int8x16_t result = r;
__asm__ ("ld1 {v16.16b - v19.16b}, %1\n\t"
@@ -16962,7 +16538,7 @@ __extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
vtbl1_s8 (int8x8_t tab, int8x8_t idx)
{
int8x8_t result;
- int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (UINT64_C (0x0)));
+ int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("tbl %0.8b, {%1.16b}, %2.8b"
: "=w"(result)
: "w"(temp), "w"(idx)
@@ -16974,7 +16550,7 @@ __extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
vtbl1_u8 (uint8x8_t tab, uint8x8_t idx)
{
uint8x8_t result;
- uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (UINT64_C (0x0)));
+ uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("tbl %0.8b, {%1.16b}, %2.8b"
: "=w"(result)
: "w"(temp), "w"(idx)
@@ -16986,7 +16562,7 @@ __extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
vtbl1_p8 (poly8x8_t tab, uint8x8_t idx)
{
poly8x8_t result;
- poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (UINT64_C (0x0)));
+ poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("tbl %0.8b, {%1.16b}, %2.8b"
: "=w"(result)
: "w"(temp), "w"(idx)
@@ -17036,7 +16612,7 @@ vtbl3_s8 (int8x8x3_t tab, int8x8_t idx)
int8x8_t result;
int8x16x2_t temp;
temp.val[0] = vcombine_s8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (UINT64_C (0x0)));
+ temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t"
"tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t"
: "=w"(result)
@@ -17051,7 +16627,7 @@ vtbl3_u8 (uint8x8x3_t tab, uint8x8_t idx)
uint8x8_t result;
uint8x16x2_t temp;
temp.val[0] = vcombine_u8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (UINT64_C (0x0)));
+ temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t"
"tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t"
: "=w"(result)
@@ -17066,7 +16642,7 @@ vtbl3_p8 (poly8x8x3_t tab, uint8x8_t idx)
poly8x8_t result;
poly8x16x2_t temp;
temp.val[0] = vcombine_p8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (UINT64_C (0x0)));
+ temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("ld1 {v16.16b - v17.16b }, %1\n\t"
"tbl %0.8b, {v16.16b - v17.16b}, %2.8b\n\t"
: "=w"(result)
@@ -17125,7 +16701,7 @@ vtbx1_s8 (int8x8_t r, int8x8_t tab, int8x8_t idx)
{
int8x8_t result;
int8x8_t tmp1;
- int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (UINT64_C (0x0)));
+ int8x16_t temp = vcombine_s8 (tab, vcreate_s8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("movi %0.8b, 8\n\t"
"cmhs %0.8b, %3.8b, %0.8b\n\t"
"tbl %1.8b, {%2.16b}, %3.8b\n\t"
@@ -17141,7 +16717,7 @@ vtbx1_u8 (uint8x8_t r, uint8x8_t tab, uint8x8_t idx)
{
uint8x8_t result;
uint8x8_t tmp1;
- uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (UINT64_C (0x0)));
+ uint8x16_t temp = vcombine_u8 (tab, vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("movi %0.8b, 8\n\t"
"cmhs %0.8b, %3.8b, %0.8b\n\t"
"tbl %1.8b, {%2.16b}, %3.8b\n\t"
@@ -17157,7 +16733,7 @@ vtbx1_p8 (poly8x8_t r, poly8x8_t tab, uint8x8_t idx)
{
poly8x8_t result;
poly8x8_t tmp1;
- poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (UINT64_C (0x0)));
+ poly8x16_t temp = vcombine_p8 (tab, vcreate_p8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("movi %0.8b, 8\n\t"
"cmhs %0.8b, %3.8b, %0.8b\n\t"
"tbl %1.8b, {%2.16b}, %3.8b\n\t"
@@ -17211,7 +16787,7 @@ vtbx3_s8 (int8x8_t r, int8x8x3_t tab, int8x8_t idx)
int8x8_t tmp1;
int8x16x2_t temp;
temp.val[0] = vcombine_s8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (UINT64_C (0x0)));
+ temp.val[1] = vcombine_s8 (tab.val[2], vcreate_s8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t"
"movi %0.8b, 24\n\t"
"cmhs %0.8b, %3.8b, %0.8b\n\t"
@@ -17230,7 +16806,7 @@ vtbx3_u8 (uint8x8_t r, uint8x8x3_t tab, uint8x8_t idx)
uint8x8_t tmp1;
uint8x16x2_t temp;
temp.val[0] = vcombine_u8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (UINT64_C (0x0)));
+ temp.val[1] = vcombine_u8 (tab.val[2], vcreate_u8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t"
"movi %0.8b, 24\n\t"
"cmhs %0.8b, %3.8b, %0.8b\n\t"
@@ -17249,7 +16825,7 @@ vtbx3_p8 (poly8x8_t r, poly8x8x3_t tab, uint8x8_t idx)
poly8x8_t tmp1;
poly8x16x2_t temp;
temp.val[0] = vcombine_p8 (tab.val[0], tab.val[1]);
- temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (UINT64_C (0x0)));
+ temp.val[1] = vcombine_p8 (tab.val[2], vcreate_p8 (__AARCH64_UINT64_C (0x0)));
__asm__ ("ld1 {v16.16b - v17.16b}, %2\n\t"
"movi %0.8b, 24\n\t"
"cmhs %0.8b, %3.8b, %0.8b\n\t"
@@ -17457,7 +17033,7 @@ vaddvq_s32 (int32x4_t __a)
return vgetq_lane_s32 (__builtin_aarch64_reduc_splus_v4si (__a), 0);
}
-__extension__ static __inline int32_t __attribute__ ((__always_inline__))
+__extension__ static __inline int64_t __attribute__ ((__always_inline__))
vaddvq_s64 (int64x2_t __a)
{
return vgetq_lane_s64 (__builtin_aarch64_reduc_splus_v2di (__a), 0);
@@ -17484,7 +17060,7 @@ vaddvq_u32 (uint32x4_t __a)
__builtin_aarch64_reduc_uplus_v4si ((int32x4_t) __a), 0);
}
-__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
vaddvq_u64 (uint64x2_t __a)
{
return vgetq_lane_u64 ((uint64x2_t)
@@ -19727,54 +19303,601 @@ vcvtpq_u64_f64 (float64x2_t __a)
return (uint64x2_t) __builtin_aarch64_lceiluv2dfv2di (__a);
}
-/* vdup */
+/* vdup_n */
-__extension__ static __inline int8x1_t __attribute__ ((__always_inline__))
-vdupb_lane_s8 (int8x16_t a, int const b)
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vdup_n_f32 (float32_t __a)
{
- return __builtin_aarch64_dup_lane_scalarv16qi (a, b);
+ return (float32x2_t) {__a, __a};
}
-__extension__ static __inline uint8x1_t __attribute__ ((__always_inline__))
-vdupb_lane_u8 (uint8x16_t a, int const b)
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vdup_n_f64 (float64_t __a)
{
- return (uint8x1_t) __builtin_aarch64_dup_lane_scalarv16qi ((int8x16_t) a, b);
+ return __a;
}
-__extension__ static __inline int16x1_t __attribute__ ((__always_inline__))
-vduph_lane_s16 (int16x8_t a, int const b)
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vdup_n_p8 (poly8_t __a)
{
- return __builtin_aarch64_dup_lane_scalarv8hi (a, b);
+ return (poly8x8_t) {__a, __a, __a, __a, __a, __a, __a, __a};
}
-__extension__ static __inline uint16x1_t __attribute__ ((__always_inline__))
-vduph_lane_u16 (uint16x8_t a, int const b)
+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
+vdup_n_p16 (poly16_t __a)
{
- return (uint16x1_t) __builtin_aarch64_dup_lane_scalarv8hi ((int16x8_t) a, b);
+ return (poly16x4_t) {__a, __a, __a, __a};
}
-__extension__ static __inline int32x1_t __attribute__ ((__always_inline__))
-vdups_lane_s32 (int32x4_t a, int const b)
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vdup_n_s8 (int8_t __a)
{
- return __builtin_aarch64_dup_lane_scalarv4si (a, b);
+ return (int8x8_t) {__a, __a, __a, __a, __a, __a, __a, __a};
}
-__extension__ static __inline uint32x1_t __attribute__ ((__always_inline__))
-vdups_lane_u32 (uint32x4_t a, int const b)
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vdup_n_s16 (int16_t __a)
+{
+ return (int16x4_t) {__a, __a, __a, __a};
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vdup_n_s32 (int32_t __a)
+{
+ return (int32x2_t) {__a, __a};
+}
+
+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
+vdup_n_s64 (int64_t __a)
+{
+ return __a;
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vdup_n_u8 (uint8_t __a)
+{
+ return (uint8x8_t) {__a, __a, __a, __a, __a, __a, __a, __a};
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vdup_n_u16 (uint16_t __a)
+{
+ return (uint16x4_t) {__a, __a, __a, __a};
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vdup_n_u32 (uint32_t __a)
+{
+ return (uint32x2_t) {__a, __a};
+}
+
+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
+vdup_n_u64 (uint64_t __a)
+{
+ return __a;
+}
+
+/* vdupq_n */
+
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vdupq_n_f32 (float32_t __a)
+{
+ return (float32x4_t) {__a, __a, __a, __a};
+}
+
+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+vdupq_n_f64 (float64_t __a)
+{
+ return (float64x2_t) {__a, __a};
+}
+
+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
+vdupq_n_p8 (uint32_t __a)
+{
+ return (poly8x16_t) {__a, __a, __a, __a, __a, __a, __a, __a,
+ __a, __a, __a, __a, __a, __a, __a, __a};
+}
+
+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__))
+vdupq_n_p16 (uint32_t __a)
+{
+ return (poly16x8_t) {__a, __a, __a, __a, __a, __a, __a, __a};
+}
+
+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
+vdupq_n_s8 (int32_t __a)
+{
+ return (int8x16_t) {__a, __a, __a, __a, __a, __a, __a, __a,
+ __a, __a, __a, __a, __a, __a, __a, __a};
+}
+
+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
+vdupq_n_s16 (int32_t __a)
+{
+ return (int16x8_t) {__a, __a, __a, __a, __a, __a, __a, __a};
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vdupq_n_s32 (int32_t __a)
+{
+ return (int32x4_t) {__a, __a, __a, __a};
+}
+
+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
+vdupq_n_s64 (int64_t __a)
+{
+ return (int64x2_t) {__a, __a};
+}
+
+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
+vdupq_n_u8 (uint32_t __a)
+{
+ return (uint8x16_t) {__a, __a, __a, __a, __a, __a, __a, __a,
+ __a, __a, __a, __a, __a, __a, __a, __a};
+}
+
+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
+vdupq_n_u16 (uint32_t __a)
+{
+ return (uint16x8_t) {__a, __a, __a, __a, __a, __a, __a, __a};
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vdupq_n_u32 (uint32_t __a)
+{
+ return (uint32x4_t) {__a, __a, __a, __a};
+}
+
+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__))
+vdupq_n_u64 (uint64_t __a)
{
- return (uint32x1_t) __builtin_aarch64_dup_lane_scalarv4si ((int32x4_t) a, b);
+ return (uint64x2_t) {__a, __a};
+}
+
+/* vdup_lane */
+
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vdup_lane_f32 (float32x2_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_f32 (__a, __b);
+}
+
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vdup_lane_f64 (float64x1_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_f64 (__a, __b);
+}
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vdup_lane_p8 (poly8x8_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_p8 (__a, __b);
+}
+
+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
+vdup_lane_p16 (poly16x4_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_p16 (__a, __b);
+}
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vdup_lane_s8 (int8x8_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_s8 (__a, __b);
+}
+
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vdup_lane_s16 (int16x4_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_s16 (__a, __b);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vdup_lane_s32 (int32x2_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_s32 (__a, __b);
}
__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
-vdupd_lane_s64 (int64x2_t a, int const b)
+vdup_lane_s64 (int64x1_t __a, const int __b)
{
- return __builtin_aarch64_dup_lane_scalarv2di (a, b);
+ return __aarch64_vdup_lane_s64 (__a, __b);
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vdup_lane_u8 (uint8x8_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_u8 (__a, __b);
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vdup_lane_u16 (uint16x4_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_u16 (__a, __b);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vdup_lane_u32 (uint32x2_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_u32 (__a, __b);
}
__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
-vdupd_lane_u64 (uint64x2_t a, int const b)
+vdup_lane_u64 (uint64x1_t __a, const int __b)
+{
+ return __aarch64_vdup_lane_u64 (__a, __b);
+}
+
+/* vdup_laneq */
+
+__extension__ static __inline float32x2_t __attribute__ ((__always_inline__))
+vdup_laneq_f32 (float32x4_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_f32 (__a, __b);
+}
+
+__extension__ static __inline float64x1_t __attribute__ ((__always_inline__))
+vdup_laneq_f64 (float64x2_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_f64 (__a, __b);
+}
+
+__extension__ static __inline poly8x8_t __attribute__ ((__always_inline__))
+vdup_laneq_p8 (poly8x16_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_p8 (__a, __b);
+}
+
+__extension__ static __inline poly16x4_t __attribute__ ((__always_inline__))
+vdup_laneq_p16 (poly16x8_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_p16 (__a, __b);
+}
+
+__extension__ static __inline int8x8_t __attribute__ ((__always_inline__))
+vdup_laneq_s8 (int8x16_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_s8 (__a, __b);
+}
+
+__extension__ static __inline int16x4_t __attribute__ ((__always_inline__))
+vdup_laneq_s16 (int16x8_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_s16 (__a, __b);
+}
+
+__extension__ static __inline int32x2_t __attribute__ ((__always_inline__))
+vdup_laneq_s32 (int32x4_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_s32 (__a, __b);
+}
+
+__extension__ static __inline int64x1_t __attribute__ ((__always_inline__))
+vdup_laneq_s64 (int64x2_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_s64 (__a, __b);
+}
+
+__extension__ static __inline uint8x8_t __attribute__ ((__always_inline__))
+vdup_laneq_u8 (uint8x16_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_u8 (__a, __b);
+}
+
+__extension__ static __inline uint16x4_t __attribute__ ((__always_inline__))
+vdup_laneq_u16 (uint16x8_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_u16 (__a, __b);
+}
+
+__extension__ static __inline uint32x2_t __attribute__ ((__always_inline__))
+vdup_laneq_u32 (uint32x4_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_u32 (__a, __b);
+}
+
+__extension__ static __inline uint64x1_t __attribute__ ((__always_inline__))
+vdup_laneq_u64 (uint64x2_t __a, const int __b)
+{
+ return __aarch64_vdup_laneq_u64 (__a, __b);
+}
+
+/* vdupq_lane */
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vdupq_lane_f32 (float32x2_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_f32 (__a, __b);
+}
+
+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+vdupq_lane_f64 (float64x1_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_f64 (__a, __b);
+}
+
+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
+vdupq_lane_p8 (poly8x8_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_p8 (__a, __b);
+}
+
+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__))
+vdupq_lane_p16 (poly16x4_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_p16 (__a, __b);
+}
+
+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
+vdupq_lane_s8 (int8x8_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_s8 (__a, __b);
+}
+
+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
+vdupq_lane_s16 (int16x4_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_s16 (__a, __b);
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vdupq_lane_s32 (int32x2_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_s32 (__a, __b);
+}
+
+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
+vdupq_lane_s64 (int64x1_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_s64 (__a, __b);
+}
+
+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
+vdupq_lane_u8 (uint8x8_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_u8 (__a, __b);
+}
+
+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
+vdupq_lane_u16 (uint16x4_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_u16 (__a, __b);
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vdupq_lane_u32 (uint32x2_t __a, const int __b)
+{
+ return __aarch64_vdupq_lane_u32 (__a, __b);
+}
+
+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__))
+vdupq_lane_u64 (uint64x1_t __a, const int __b)
{
- return (uint64x1_t) __builtin_aarch64_dup_lane_scalarv2di ((int64x2_t) a, b);
+ return __aarch64_vdupq_lane_u64 (__a, __b);
+}
+
+/* vdupq_laneq */
+__extension__ static __inline float32x4_t __attribute__ ((__always_inline__))
+vdupq_laneq_f32 (float32x4_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_f32 (__a, __b);
+}
+
+__extension__ static __inline float64x2_t __attribute__ ((__always_inline__))
+vdupq_laneq_f64 (float64x2_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_f64 (__a, __b);
+}
+
+__extension__ static __inline poly8x16_t __attribute__ ((__always_inline__))
+vdupq_laneq_p8 (poly8x16_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_p8 (__a, __b);
+}
+
+__extension__ static __inline poly16x8_t __attribute__ ((__always_inline__))
+vdupq_laneq_p16 (poly16x8_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_p16 (__a, __b);
+}
+
+__extension__ static __inline int8x16_t __attribute__ ((__always_inline__))
+vdupq_laneq_s8 (int8x16_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_s8 (__a, __b);
+}
+
+__extension__ static __inline int16x8_t __attribute__ ((__always_inline__))
+vdupq_laneq_s16 (int16x8_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_s16 (__a, __b);
+}
+
+__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
+vdupq_laneq_s32 (int32x4_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_s32 (__a, __b);
+}
+
+__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
+vdupq_laneq_s64 (int64x2_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_s64 (__a, __b);
+}
+
+__extension__ static __inline uint8x16_t __attribute__ ((__always_inline__))
+vdupq_laneq_u8 (uint8x16_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_u8 (__a, __b);
+}
+
+__extension__ static __inline uint16x8_t __attribute__ ((__always_inline__))
+vdupq_laneq_u16 (uint16x8_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_u16 (__a, __b);
+}
+
+__extension__ static __inline uint32x4_t __attribute__ ((__always_inline__))
+vdupq_laneq_u32 (uint32x4_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_u32 (__a, __b);
+}
+
+__extension__ static __inline uint64x2_t __attribute__ ((__always_inline__))
+vdupq_laneq_u64 (uint64x2_t __a, const int __b)
+{
+ return __aarch64_vdupq_laneq_u64 (__a, __b);
+}
+
+/* vdupb_lane */
+__extension__ static __inline poly8_t __attribute__ ((__always_inline__))
+vdupb_lane_p8 (poly8x8_t __a, const int __b)
+{
+ return __aarch64_vget_lane_p8 (__a, __b);
+}
+
+__extension__ static __inline int8_t __attribute__ ((__always_inline__))
+vdupb_lane_s8 (int8x8_t __a, const int __b)
+{
+ return __aarch64_vget_lane_s8 (__a, __b);
+}
+
+__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
+vdupb_lane_u8 (uint8x8_t __a, const int __b)
+{
+ return __aarch64_vget_lane_u8 (__a, __b);
+}
+
+/* vduph_lane */
+__extension__ static __inline poly16_t __attribute__ ((__always_inline__))
+vduph_lane_p16 (poly16x4_t __a, const int __b)
+{
+ return __aarch64_vget_lane_p16 (__a, __b);
+}
+
+__extension__ static __inline int16_t __attribute__ ((__always_inline__))
+vduph_lane_s16 (int16x4_t __a, const int __b)
+{
+ return __aarch64_vget_lane_s16 (__a, __b);
+}
+
+__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
+vduph_lane_u16 (uint16x4_t __a, const int __b)
+{
+ return __aarch64_vget_lane_u16 (__a, __b);
+}
+
+/* vdups_lane */
+__extension__ static __inline float32_t __attribute__ ((__always_inline__))
+vdups_lane_f32 (float32x2_t __a, const int __b)
+{
+ return __aarch64_vget_lane_f32 (__a, __b);
+}
+
+__extension__ static __inline int32_t __attribute__ ((__always_inline__))
+vdups_lane_s32 (int32x2_t __a, const int __b)
+{
+ return __aarch64_vget_lane_s32 (__a, __b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+vdups_lane_u32 (uint32x2_t __a, const int __b)
+{
+ return __aarch64_vget_lane_u32 (__a, __b);
+}
+
+/* vdupd_lane */
+__extension__ static __inline float64_t __attribute__ ((__always_inline__))
+vdupd_lane_f64 (float64x1_t __a, const int __attribute__ ((unused)) __b)
+{
+ return __a;
+}
+
+__extension__ static __inline int64_t __attribute__ ((__always_inline__))
+vdupd_lane_s64 (int64x1_t __a, const int __attribute__ ((unused)) __b)
+{
+ return __a;
+}
+
+__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
+vdupd_lane_u64 (uint64x1_t __a, const int __attribute__ ((unused)) __b)
+{
+ return __a;
+}
+
+/* vdupb_laneq */
+__extension__ static __inline poly8_t __attribute__ ((__always_inline__))
+vdupb_laneq_p8 (poly8x16_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_p8 (__a, __b);
+}
+
+__extension__ static __inline int8_t __attribute__ ((__always_inline__))
+vdupb_laneq_s8 (int8x16_t __a, const int __attribute__ ((unused)) __b)
+{
+ return __aarch64_vgetq_lane_s8 (__a, __b);
+}
+
+__extension__ static __inline uint8_t __attribute__ ((__always_inline__))
+vdupb_laneq_u8 (uint8x16_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_u8 (__a, __b);
+}
+
+/* vduph_laneq */
+__extension__ static __inline poly16_t __attribute__ ((__always_inline__))
+vduph_laneq_p16 (poly16x8_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_p16 (__a, __b);
+}
+
+__extension__ static __inline int16_t __attribute__ ((__always_inline__))
+vduph_laneq_s16 (int16x8_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_s16 (__a, __b);
+}
+
+__extension__ static __inline uint16_t __attribute__ ((__always_inline__))
+vduph_laneq_u16 (uint16x8_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_u16 (__a, __b);
+}
+
+/* vdups_laneq */
+__extension__ static __inline float32_t __attribute__ ((__always_inline__))
+vdups_laneq_f32 (float32x4_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_f32 (__a, __b);
+}
+
+__extension__ static __inline int32_t __attribute__ ((__always_inline__))
+vdups_laneq_s32 (int32x4_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_s32 (__a, __b);
+}
+
+__extension__ static __inline uint32_t __attribute__ ((__always_inline__))
+vdups_laneq_u32 (uint32x4_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_u32 (__a, __b);
+}
+
+/* vdupd_laneq */
+__extension__ static __inline float64_t __attribute__ ((__always_inline__))
+vdupd_laneq_f64 (float64x2_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_f64 (__a, __b);
+}
+
+__extension__ static __inline int64_t __attribute__ ((__always_inline__))
+vdupd_laneq_s64 (int64x2_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_s64 (__a, __b);
+}
+
+__extension__ static __inline uint64_t __attribute__ ((__always_inline__))
+vdupd_laneq_u64 (uint64x2_t __a, const int __b)
+{
+ return __aarch64_vgetq_lane_u64 (__a, __b);
}
/* vld1 */
@@ -21425,7 +21548,7 @@ vqdmlal_high_n_s16 (int32x4_t __a, int16x8_t __b, int16_t __c)
__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
vqdmlal_lane_s16 (int32x4_t __a, int16x4_t __b, int16x4_t __c, int const __d)
{
- int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (INT64_C (0)));
+ int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (__AARCH64_INT64_C (0)));
return __builtin_aarch64_sqdmlal_lanev4hi (__a, __b, __tmp, __d);
}
@@ -21476,7 +21599,7 @@ vqdmlal_high_n_s32 (int64x2_t __a, int32x4_t __b, int32_t __c)
__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
vqdmlal_lane_s32 (int64x2_t __a, int32x2_t __b, int32x2_t __c, int const __d)
{
- int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (INT64_C (0)));
+ int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (__AARCH64_INT64_C (0)));
return __builtin_aarch64_sqdmlal_lanev2si (__a, __b, __tmp, __d);
}
@@ -21553,7 +21676,7 @@ vqdmlsl_high_n_s16 (int32x4_t __a, int16x8_t __b, int16_t __c)
__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
vqdmlsl_lane_s16 (int32x4_t __a, int16x4_t __b, int16x4_t __c, int const __d)
{
- int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (INT64_C (0)));
+ int16x8_t __tmp = vcombine_s16 (__c, vcreate_s16 (__AARCH64_INT64_C (0)));
return __builtin_aarch64_sqdmlsl_lanev4hi (__a, __b, __tmp, __d);
}
@@ -21604,7 +21727,7 @@ vqdmlsl_high_n_s32 (int64x2_t __a, int32x4_t __b, int32_t __c)
__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
vqdmlsl_lane_s32 (int64x2_t __a, int32x2_t __b, int32x2_t __c, int const __d)
{
- int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (INT64_C (0)));
+ int32x4_t __tmp = vcombine_s32 (__c, vcreate_s32 (__AARCH64_INT64_C (0)));
return __builtin_aarch64_sqdmlsl_lanev2si (__a, __b, __tmp, __d);
}
@@ -21729,7 +21852,7 @@ vqdmull_high_n_s16 (int16x8_t __a, int16_t __b)
__extension__ static __inline int32x4_t __attribute__ ((__always_inline__))
vqdmull_lane_s16 (int16x4_t __a, int16x4_t __b, int const __c)
{
- int16x8_t __tmp = vcombine_s16 (__b, vcreate_s16 (INT64_C (0)));
+ int16x8_t __tmp = vcombine_s16 (__b, vcreate_s16 (__AARCH64_INT64_C (0)));
return __builtin_aarch64_sqdmull_lanev4hi (__a, __tmp, __c);
}
@@ -21778,7 +21901,7 @@ vqdmull_high_n_s32 (int32x4_t __a, int32_t __b)
__extension__ static __inline int64x2_t __attribute__ ((__always_inline__))
vqdmull_lane_s32 (int32x2_t __a, int32x2_t __b, int const __c)
{
- int32x4_t __tmp = vcombine_s32 (__b, vcreate_s32 (INT64_C (0)));
+ int32x4_t __tmp = vcombine_s32 (__b, vcreate_s32 (__AARCH64_INT64_C (0)));
return __builtin_aarch64_sqdmull_lanev2si (__a, __tmp, __c);
}
@@ -24365,8 +24488,8 @@ vst2_s64 (int64_t * __a, int64x1x2_t val)
{
__builtin_aarch64_simd_oi __o;
int64x2x2_t temp;
- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0)));
- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0)));
+ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[1], 1);
__builtin_aarch64_st2di ((__builtin_aarch64_simd_di *) __a, __o);
@@ -24377,8 +24500,8 @@ vst2_u64 (uint64_t * __a, uint64x1x2_t val)
{
__builtin_aarch64_simd_oi __o;
uint64x2x2_t temp;
- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0)));
- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0)));
+ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv2di (__o, (int64x2_t) temp.val[1], 1);
__builtin_aarch64_st2di ((__builtin_aarch64_simd_di *) __a, __o);
@@ -24389,8 +24512,8 @@ vst2_f64 (float64_t * __a, float64x1x2_t val)
{
__builtin_aarch64_simd_oi __o;
float64x2x2_t temp;
- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0)));
- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0)));
+ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregoiv2df (__o, (float64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv2df (__o, (float64x2_t) temp.val[1], 1);
__builtin_aarch64_st2df ((__builtin_aarch64_simd_df *) __a, __o);
@@ -24401,8 +24524,8 @@ vst2_s8 (int8_t * __a, int8x8x2_t val)
{
__builtin_aarch64_simd_oi __o;
int8x16x2_t temp;
- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0)));
- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0)));
+ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1);
__builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o);
@@ -24413,8 +24536,8 @@ vst2_p8 (poly8_t * __a, poly8x8x2_t val)
{
__builtin_aarch64_simd_oi __o;
poly8x16x2_t temp;
- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0)));
- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0)));
+ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1);
__builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o);
@@ -24425,8 +24548,8 @@ vst2_s16 (int16_t * __a, int16x4x2_t val)
{
__builtin_aarch64_simd_oi __o;
int16x8x2_t temp;
- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0)));
- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0)));
+ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1);
__builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o);
@@ -24437,8 +24560,8 @@ vst2_p16 (poly16_t * __a, poly16x4x2_t val)
{
__builtin_aarch64_simd_oi __o;
poly16x8x2_t temp;
- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0)));
- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0)));
+ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1);
__builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o);
@@ -24449,8 +24572,8 @@ vst2_s32 (int32_t * __a, int32x2x2_t val)
{
__builtin_aarch64_simd_oi __o;
int32x4x2_t temp;
- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0)));
- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0)));
+ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[1], 1);
__builtin_aarch64_st2v2si ((__builtin_aarch64_simd_si *) __a, __o);
@@ -24461,8 +24584,8 @@ vst2_u8 (uint8_t * __a, uint8x8x2_t val)
{
__builtin_aarch64_simd_oi __o;
uint8x16x2_t temp;
- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0)));
- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0)));
+ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv16qi (__o, (int8x16_t) temp.val[1], 1);
__builtin_aarch64_st2v8qi ((__builtin_aarch64_simd_qi *) __a, __o);
@@ -24473,8 +24596,8 @@ vst2_u16 (uint16_t * __a, uint16x4x2_t val)
{
__builtin_aarch64_simd_oi __o;
uint16x8x2_t temp;
- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0)));
- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0)));
+ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv8hi (__o, (int16x8_t) temp.val[1], 1);
__builtin_aarch64_st2v4hi ((__builtin_aarch64_simd_hi *) __a, __o);
@@ -24485,8 +24608,8 @@ vst2_u32 (uint32_t * __a, uint32x2x2_t val)
{
__builtin_aarch64_simd_oi __o;
uint32x4x2_t temp;
- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0)));
- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0)));
+ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv4si (__o, (int32x4_t) temp.val[1], 1);
__builtin_aarch64_st2v2si ((__builtin_aarch64_simd_si *) __a, __o);
@@ -24497,8 +24620,8 @@ vst2_f32 (float32_t * __a, float32x2x2_t val)
{
__builtin_aarch64_simd_oi __o;
float32x4x2_t temp;
- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0)));
- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0)));
+ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregoiv4sf (__o, (float32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregoiv4sf (__o, (float32x4_t) temp.val[1], 1);
__builtin_aarch64_st2v2sf ((__builtin_aarch64_simd_sf *) __a, __o);
@@ -24617,9 +24740,9 @@ vst3_s64 (int64_t * __a, int64x1x3_t val)
{
__builtin_aarch64_simd_ci __o;
int64x2x3_t temp;
- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0)));
- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0)));
- temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (INT64_C (0)));
+ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0)));
+ temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[2], 2);
@@ -24631,9 +24754,9 @@ vst3_u64 (uint64_t * __a, uint64x1x3_t val)
{
__builtin_aarch64_simd_ci __o;
uint64x2x3_t temp;
- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0)));
- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0)));
- temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (UINT64_C (0)));
+ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv2di (__o, (int64x2_t) temp.val[2], 2);
@@ -24645,9 +24768,9 @@ vst3_f64 (float64_t * __a, float64x1x3_t val)
{
__builtin_aarch64_simd_ci __o;
float64x2x3_t temp;
- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0)));
- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0)));
- temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (UINT64_C (0)));
+ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv2df (__o, (float64x2_t) temp.val[2], 2);
@@ -24659,9 +24782,9 @@ vst3_s8 (int8_t * __a, int8x8x3_t val)
{
__builtin_aarch64_simd_ci __o;
int8x16x3_t temp;
- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0)));
- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0)));
- temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (INT64_C (0)));
+ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0)));
+ temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2);
@@ -24673,9 +24796,9 @@ vst3_p8 (poly8_t * __a, poly8x8x3_t val)
{
__builtin_aarch64_simd_ci __o;
poly8x16x3_t temp;
- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0)));
- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0)));
- temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (UINT64_C (0)));
+ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2);
@@ -24687,9 +24810,9 @@ vst3_s16 (int16_t * __a, int16x4x3_t val)
{
__builtin_aarch64_simd_ci __o;
int16x8x3_t temp;
- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0)));
- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0)));
- temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (INT64_C (0)));
+ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0)));
+ temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2);
@@ -24701,9 +24824,9 @@ vst3_p16 (poly16_t * __a, poly16x4x3_t val)
{
__builtin_aarch64_simd_ci __o;
poly16x8x3_t temp;
- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0)));
- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0)));
- temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (UINT64_C (0)));
+ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2);
@@ -24715,9 +24838,9 @@ vst3_s32 (int32_t * __a, int32x2x3_t val)
{
__builtin_aarch64_simd_ci __o;
int32x4x3_t temp;
- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0)));
- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0)));
- temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (INT64_C (0)));
+ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0)));
+ temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[2], 2);
@@ -24729,9 +24852,9 @@ vst3_u8 (uint8_t * __a, uint8x8x3_t val)
{
__builtin_aarch64_simd_ci __o;
uint8x16x3_t temp;
- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0)));
- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0)));
- temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (UINT64_C (0)));
+ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv16qi (__o, (int8x16_t) temp.val[2], 2);
@@ -24743,9 +24866,9 @@ vst3_u16 (uint16_t * __a, uint16x4x3_t val)
{
__builtin_aarch64_simd_ci __o;
uint16x8x3_t temp;
- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0)));
- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0)));
- temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (UINT64_C (0)));
+ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv8hi (__o, (int16x8_t) temp.val[2], 2);
@@ -24757,9 +24880,9 @@ vst3_u32 (uint32_t * __a, uint32x2x3_t val)
{
__builtin_aarch64_simd_ci __o;
uint32x4x3_t temp;
- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0)));
- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0)));
- temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (UINT64_C (0)));
+ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv4si (__o, (int32x4_t) temp.val[2], 2);
@@ -24771,9 +24894,9 @@ vst3_f32 (float32_t * __a, float32x2x3_t val)
{
__builtin_aarch64_simd_ci __o;
float32x4x3_t temp;
- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0)));
- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0)));
- temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (UINT64_C (0)));
+ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregciv4sf (__o, (float32x4_t) temp.val[2], 2);
@@ -24905,10 +25028,10 @@ vst4_s64 (int64_t * __a, int64x1x4_t val)
{
__builtin_aarch64_simd_xi __o;
int64x2x4_t temp;
- temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (INT64_C (0)));
- temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (INT64_C (0)));
- temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (INT64_C (0)));
- temp.val[3] = vcombine_s64 (val.val[3], vcreate_s64 (INT64_C (0)));
+ temp.val[0] = vcombine_s64 (val.val[0], vcreate_s64 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s64 (val.val[1], vcreate_s64 (__AARCH64_INT64_C (0)));
+ temp.val[2] = vcombine_s64 (val.val[2], vcreate_s64 (__AARCH64_INT64_C (0)));
+ temp.val[3] = vcombine_s64 (val.val[3], vcreate_s64 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[2], 2);
@@ -24921,10 +25044,10 @@ vst4_u64 (uint64_t * __a, uint64x1x4_t val)
{
__builtin_aarch64_simd_xi __o;
uint64x2x4_t temp;
- temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (UINT64_C (0)));
- temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (UINT64_C (0)));
- temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (UINT64_C (0)));
- temp.val[3] = vcombine_u64 (val.val[3], vcreate_u64 (UINT64_C (0)));
+ temp.val[0] = vcombine_u64 (val.val[0], vcreate_u64 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u64 (val.val[1], vcreate_u64 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_u64 (val.val[2], vcreate_u64 (__AARCH64_UINT64_C (0)));
+ temp.val[3] = vcombine_u64 (val.val[3], vcreate_u64 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv2di (__o, (int64x2_t) temp.val[2], 2);
@@ -24937,10 +25060,10 @@ vst4_f64 (float64_t * __a, float64x1x4_t val)
{
__builtin_aarch64_simd_xi __o;
float64x2x4_t temp;
- temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (UINT64_C (0)));
- temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (UINT64_C (0)));
- temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (UINT64_C (0)));
- temp.val[3] = vcombine_f64 (val.val[3], vcreate_f64 (UINT64_C (0)));
+ temp.val[0] = vcombine_f64 (val.val[0], vcreate_f64 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_f64 (val.val[1], vcreate_f64 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_f64 (val.val[2], vcreate_f64 (__AARCH64_UINT64_C (0)));
+ temp.val[3] = vcombine_f64 (val.val[3], vcreate_f64 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv2df (__o, (float64x2_t) temp.val[2], 2);
@@ -24953,10 +25076,10 @@ vst4_s8 (int8_t * __a, int8x8x4_t val)
{
__builtin_aarch64_simd_xi __o;
int8x16x4_t temp;
- temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (INT64_C (0)));
- temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (INT64_C (0)));
- temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (INT64_C (0)));
- temp.val[3] = vcombine_s8 (val.val[3], vcreate_s8 (INT64_C (0)));
+ temp.val[0] = vcombine_s8 (val.val[0], vcreate_s8 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s8 (val.val[1], vcreate_s8 (__AARCH64_INT64_C (0)));
+ temp.val[2] = vcombine_s8 (val.val[2], vcreate_s8 (__AARCH64_INT64_C (0)));
+ temp.val[3] = vcombine_s8 (val.val[3], vcreate_s8 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2);
@@ -24969,10 +25092,10 @@ vst4_p8 (poly8_t * __a, poly8x8x4_t val)
{
__builtin_aarch64_simd_xi __o;
poly8x16x4_t temp;
- temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (UINT64_C (0)));
- temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (UINT64_C (0)));
- temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (UINT64_C (0)));
- temp.val[3] = vcombine_p8 (val.val[3], vcreate_p8 (UINT64_C (0)));
+ temp.val[0] = vcombine_p8 (val.val[0], vcreate_p8 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_p8 (val.val[1], vcreate_p8 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_p8 (val.val[2], vcreate_p8 (__AARCH64_UINT64_C (0)));
+ temp.val[3] = vcombine_p8 (val.val[3], vcreate_p8 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2);
@@ -24985,10 +25108,10 @@ vst4_s16 (int16_t * __a, int16x4x4_t val)
{
__builtin_aarch64_simd_xi __o;
int16x8x4_t temp;
- temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (INT64_C (0)));
- temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (INT64_C (0)));
- temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (INT64_C (0)));
- temp.val[3] = vcombine_s16 (val.val[3], vcreate_s16 (INT64_C (0)));
+ temp.val[0] = vcombine_s16 (val.val[0], vcreate_s16 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s16 (val.val[1], vcreate_s16 (__AARCH64_INT64_C (0)));
+ temp.val[2] = vcombine_s16 (val.val[2], vcreate_s16 (__AARCH64_INT64_C (0)));
+ temp.val[3] = vcombine_s16 (val.val[3], vcreate_s16 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2);
@@ -25001,10 +25124,10 @@ vst4_p16 (poly16_t * __a, poly16x4x4_t val)
{
__builtin_aarch64_simd_xi __o;
poly16x8x4_t temp;
- temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (UINT64_C (0)));
- temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (UINT64_C (0)));
- temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (UINT64_C (0)));
- temp.val[3] = vcombine_p16 (val.val[3], vcreate_p16 (UINT64_C (0)));
+ temp.val[0] = vcombine_p16 (val.val[0], vcreate_p16 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_p16 (val.val[1], vcreate_p16 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_p16 (val.val[2], vcreate_p16 (__AARCH64_UINT64_C (0)));
+ temp.val[3] = vcombine_p16 (val.val[3], vcreate_p16 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2);
@@ -25017,10 +25140,10 @@ vst4_s32 (int32_t * __a, int32x2x4_t val)
{
__builtin_aarch64_simd_xi __o;
int32x4x4_t temp;
- temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (INT64_C (0)));
- temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (INT64_C (0)));
- temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (INT64_C (0)));
- temp.val[3] = vcombine_s32 (val.val[3], vcreate_s32 (INT64_C (0)));
+ temp.val[0] = vcombine_s32 (val.val[0], vcreate_s32 (__AARCH64_INT64_C (0)));
+ temp.val[1] = vcombine_s32 (val.val[1], vcreate_s32 (__AARCH64_INT64_C (0)));
+ temp.val[2] = vcombine_s32 (val.val[2], vcreate_s32 (__AARCH64_INT64_C (0)));
+ temp.val[3] = vcombine_s32 (val.val[3], vcreate_s32 (__AARCH64_INT64_C (0)));
__o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[2], 2);
@@ -25033,10 +25156,10 @@ vst4_u8 (uint8_t * __a, uint8x8x4_t val)
{
__builtin_aarch64_simd_xi __o;
uint8x16x4_t temp;
- temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (UINT64_C (0)));
- temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (UINT64_C (0)));
- temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (UINT64_C (0)));
- temp.val[3] = vcombine_u8 (val.val[3], vcreate_u8 (UINT64_C (0)));
+ temp.val[0] = vcombine_u8 (val.val[0], vcreate_u8 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u8 (val.val[1], vcreate_u8 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_u8 (val.val[2], vcreate_u8 (__AARCH64_UINT64_C (0)));
+ temp.val[3] = vcombine_u8 (val.val[3], vcreate_u8 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv16qi (__o, (int8x16_t) temp.val[2], 2);
@@ -25049,10 +25172,10 @@ vst4_u16 (uint16_t * __a, uint16x4x4_t val)
{
__builtin_aarch64_simd_xi __o;
uint16x8x4_t temp;
- temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (UINT64_C (0)));
- temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (UINT64_C (0)));
- temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (UINT64_C (0)));
- temp.val[3] = vcombine_u16 (val.val[3], vcreate_u16 (UINT64_C (0)));
+ temp.val[0] = vcombine_u16 (val.val[0], vcreate_u16 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u16 (val.val[1], vcreate_u16 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_u16 (val.val[2], vcreate_u16 (__AARCH64_UINT64_C (0)));
+ temp.val[3] = vcombine_u16 (val.val[3], vcreate_u16 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv8hi (__o, (int16x8_t) temp.val[2], 2);
@@ -25065,10 +25188,10 @@ vst4_u32 (uint32_t * __a, uint32x2x4_t val)
{
__builtin_aarch64_simd_xi __o;
uint32x4x4_t temp;
- temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (UINT64_C (0)));
- temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (UINT64_C (0)));
- temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (UINT64_C (0)));
- temp.val[3] = vcombine_u32 (val.val[3], vcreate_u32 (UINT64_C (0)));
+ temp.val[0] = vcombine_u32 (val.val[0], vcreate_u32 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_u32 (val.val[1], vcreate_u32 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_u32 (val.val[2], vcreate_u32 (__AARCH64_UINT64_C (0)));
+ temp.val[3] = vcombine_u32 (val.val[3], vcreate_u32 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv4si (__o, (int32x4_t) temp.val[2], 2);
@@ -25081,10 +25204,10 @@ vst4_f32 (float32_t * __a, float32x2x4_t val)
{
__builtin_aarch64_simd_xi __o;
float32x4x4_t temp;
- temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (UINT64_C (0)));
- temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (UINT64_C (0)));
- temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (UINT64_C (0)));
- temp.val[3] = vcombine_f32 (val.val[3], vcreate_f32 (UINT64_C (0)));
+ temp.val[0] = vcombine_f32 (val.val[0], vcreate_f32 (__AARCH64_UINT64_C (0)));
+ temp.val[1] = vcombine_f32 (val.val[1], vcreate_f32 (__AARCH64_UINT64_C (0)));
+ temp.val[2] = vcombine_f32 (val.val[2], vcreate_f32 (__AARCH64_UINT64_C (0)));
+ temp.val[3] = vcombine_f32 (val.val[3], vcreate_f32 (__AARCH64_UINT64_C (0)));
__o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[0], 0);
__o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[1], 1);
__o = __builtin_aarch64_set_qregxiv4sf (__o, (float32x4_t) temp.val[2], 2);
@@ -25581,4 +25704,81 @@ __INTERLEAVE_LIST (zip)
/* End of optimal implementations in approved order. */
+#undef __aarch64_vget_lane_any
+#undef __aarch64_vget_lane_f32
+#undef __aarch64_vget_lane_f64
+#undef __aarch64_vget_lane_p8
+#undef __aarch64_vget_lane_p16
+#undef __aarch64_vget_lane_s8
+#undef __aarch64_vget_lane_s16
+#undef __aarch64_vget_lane_s32
+#undef __aarch64_vget_lane_s64
+#undef __aarch64_vget_lane_u8
+#undef __aarch64_vget_lane_u16
+#undef __aarch64_vget_lane_u32
+#undef __aarch64_vget_lane_u64
+
+#undef __aarch64_vgetq_lane_f32
+#undef __aarch64_vgetq_lane_f64
+#undef __aarch64_vgetq_lane_p8
+#undef __aarch64_vgetq_lane_p16
+#undef __aarch64_vgetq_lane_s8
+#undef __aarch64_vgetq_lane_s16
+#undef __aarch64_vgetq_lane_s32
+#undef __aarch64_vgetq_lane_s64
+#undef __aarch64_vgetq_lane_u8
+#undef __aarch64_vgetq_lane_u16
+#undef __aarch64_vgetq_lane_u32
+#undef __aarch64_vgetq_lane_u64
+
+#undef __aarch64_vdup_lane_any
+#undef __aarch64_vdup_lane_f32
+#undef __aarch64_vdup_lane_f64
+#undef __aarch64_vdup_lane_p8
+#undef __aarch64_vdup_lane_p16
+#undef __aarch64_vdup_lane_s8
+#undef __aarch64_vdup_lane_s16
+#undef __aarch64_vdup_lane_s32
+#undef __aarch64_vdup_lane_s64
+#undef __aarch64_vdup_lane_u8
+#undef __aarch64_vdup_lane_u16
+#undef __aarch64_vdup_lane_u32
+#undef __aarch64_vdup_lane_u64
+#undef __aarch64_vdup_laneq_f32
+#undef __aarch64_vdup_laneq_f64
+#undef __aarch64_vdup_laneq_p8
+#undef __aarch64_vdup_laneq_p16
+#undef __aarch64_vdup_laneq_s8
+#undef __aarch64_vdup_laneq_s16
+#undef __aarch64_vdup_laneq_s32
+#undef __aarch64_vdup_laneq_s64
+#undef __aarch64_vdup_laneq_u8
+#undef __aarch64_vdup_laneq_u16
+#undef __aarch64_vdup_laneq_u32
+#undef __aarch64_vdup_laneq_u64
+#undef __aarch64_vdupq_lane_f32
+#undef __aarch64_vdupq_lane_f64
+#undef __aarch64_vdupq_lane_p8
+#undef __aarch64_vdupq_lane_p16
+#undef __aarch64_vdupq_lane_s8
+#undef __aarch64_vdupq_lane_s16
+#undef __aarch64_vdupq_lane_s32
+#undef __aarch64_vdupq_lane_s64
+#undef __aarch64_vdupq_lane_u8
+#undef __aarch64_vdupq_lane_u16
+#undef __aarch64_vdupq_lane_u32
+#undef __aarch64_vdupq_lane_u64
+#undef __aarch64_vdupq_laneq_f32
+#undef __aarch64_vdupq_laneq_f64
+#undef __aarch64_vdupq_laneq_p8
+#undef __aarch64_vdupq_laneq_p16
+#undef __aarch64_vdupq_laneq_s8
+#undef __aarch64_vdupq_laneq_s16
+#undef __aarch64_vdupq_laneq_s32
+#undef __aarch64_vdupq_laneq_s64
+#undef __aarch64_vdupq_laneq_u8
+#undef __aarch64_vdupq_laneq_u16
+#undef __aarch64_vdupq_laneq_u32
+#undef __aarch64_vdupq_laneq_u64
+
#endif
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 3ec889f28fd..ffe125b5583 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -134,9 +134,15 @@
;; Vector modes except double int.
(define_mode_iterator VDQIF [V8QI V16QI V4HI V8HI V2SI V4SI V2SF V4SF V2DF])
+;; Vector modes for Q and H types.
+(define_mode_iterator VDQQH [V8QI V16QI V4HI V8HI])
+
;; Vector modes for H and S types.
(define_mode_iterator VDQHS [V4HI V8HI V2SI V4SI])
+;; Vector modes for Q, H and S types.
+(define_mode_iterator VDQQHS [V8QI V16QI V4HI V8HI V2SI V4SI])
+
;; Vector and scalar integer modes for H and S
(define_mode_iterator VSDQ_HSI [V4HI V8HI V2SI V4SI HI SI])
@@ -377,7 +383,7 @@
(V4HI "V8HI") (V8HI "V8HI")
(V2SI "V4SI") (V4SI "V4SI")
(DI "V2DI") (V2DI "V2DI")
- (V2SF "V2SF") (V4SF "V4SF")
+ (V2SF "V4SF") (V4SF "V4SF")
(V2DF "V2DF") (SI "V4SI")
(HI "V8HI") (QI "V16QI")])
@@ -453,6 +459,15 @@
(V2SF "s") (V4SF "s")
(V2DF "d")])
+;; Corresponding core element mode for each vector mode. This is a
+;; variation on <vw> mapping FP modes to GP regs.
+(define_mode_attr vwcore [(V8QI "w") (V16QI "w")
+ (V4HI "w") (V8HI "w")
+ (V2SI "w") (V4SI "w")
+ (DI "x") (V2DI "x")
+ (V2SF "w") (V4SF "w")
+ (V2DF "x")])
+
;; Double vector types for ALLX.
(define_mode_attr Vallxd [(QI "8b") (HI "4h") (SI "2s")])
@@ -512,6 +527,20 @@
(define_mode_attr fcvt_target [(V2DF "v2di") (V4SF "v4si") (V2SF "v2si")])
(define_mode_attr FCVT_TARGET [(V2DF "V2DI") (V4SF "V4SI") (V2SF "V2SI")])
+(define_mode_attr VSWAP_WIDTH [(V8QI "V16QI") (V16QI "V8QI")
+ (V4HI "V8HI") (V8HI "V4HI")
+ (V2SI "V4SI") (V4SI "V2SI")
+ (DI "V2DI") (V2DI "DI")
+ (V2SF "V4SF") (V4SF "V2SF")
+ (DF "V2DF") (V2DF "DF")])
+
+(define_mode_attr vswap_width_name [(V8QI "to_128") (V16QI "to_64")
+ (V4HI "to_128") (V8HI "to_64")
+ (V2SI "to_128") (V4SI "to_64")
+ (DI "to_128") (V2DI "to_64")
+ (V2SF "to_128") (V4SF "to_64")
+ (DF "to_128") (V2DF "to_64")])
+
;; -------------------------------------------------------------------
;; Code Iterators
;; -------------------------------------------------------------------
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index 3e2b6b34357..dbc90826665 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -26,6 +26,11 @@
&& GET_MODE_CLASS (GET_MODE (op)) == MODE_CC"))))
)
+(define_predicate "aarch64_simd_register"
+ (and (match_code "reg")
+ (ior (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_LO_REGS")
+ (match_test "REGNO_REG_CLASS (REGNO (op)) == FP_REGS"))))
+
(define_predicate "aarch64_reg_or_zero"
(and (match_code "reg,subreg,const_int")
(ior (match_operand 0 "register_operand")
diff --git a/gcc/config/aarch64/t-aarch64 b/gcc/config/aarch64/t-aarch64
index 2975850dcb9..9f8d8cd6e0d 100644
--- a/gcc/config/aarch64/t-aarch64
+++ b/gcc/config/aarch64/t-aarch64
@@ -35,6 +35,11 @@ aarch64-builtins.o: $(srcdir)/config/aarch64/aarch64-builtins.c $(CONFIG_H) \
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/aarch64/aarch64-builtins.c
+aarch-common.o: $(srcdir)/config/arm/aarch-common.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(TM_H) $(TM_P_H) $(RTL_H) $(TREE_H) output.h $(C_COMMON_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/arm/aarch-common.c
+
comma=,
MULTILIB_OPTIONS = $(patsubst %, mabi=%, $(subst $(comma), ,$(TM_MULTILIB_CONFIG)))
MULTILIB_DIRNAMES = $(subst $(comma), ,$(TM_MULTILIB_CONFIG))
diff --git a/gcc/config/alpha/alpha.c b/gcc/config/alpha/alpha.c
index 5f5b33e347b..a8fb92964eb 100644
--- a/gcc/config/alpha/alpha.c
+++ b/gcc/config/alpha/alpha.c
@@ -2659,6 +2659,7 @@ alpha_emit_conditional_move (rtx cmp, enum machine_mode mode)
cmp_mode = cmp_mode == DImode ? DFmode : DImode;
op0 = gen_lowpart (cmp_mode, tem);
op1 = CONST0_RTX (cmp_mode);
+ cmp = gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
local_fast_math = 1;
}
diff --git a/gcc/config/alpha/linux.h b/gcc/config/alpha/linux.h
index fbf4a07eb45..da5842fda85 100644
--- a/gcc/config/alpha/linux.h
+++ b/gcc/config/alpha/linux.h
@@ -59,16 +59,18 @@ along with GCC; see the file COPYING3. If not see
#ifdef SINGLE_LIBC
#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
+#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
+#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
#else
#define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
+#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
+#define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
#endif
-/* Determine whether the entire c99 runtime is present in the
- runtime library. */
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension. */
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+ this includes full c99 runtime and sincos. */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
#define TARGET_POSIX_IO
diff --git a/gcc/config/arm/aarch-common-protos.h b/gcc/config/arm/aarch-common-protos.h
new file mode 100644
index 00000000000..97768fce0ca
--- /dev/null
+++ b/gcc/config/arm/aarch-common-protos.h
@@ -0,0 +1,36 @@
+/* Function prototypes for instruction scheduling dependeoncy routines,
+ defined in aarch-common.c
+
+ Copyright (C) 1991-2013 Free Software Foundation, Inc.
+ Contributed by ARM 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.
+
+ You should have received a copy of the GNU General Public License
+ along with GCC; see the file COPYING3. If not see
+ <http://www.gnu.org/licenses/>. */
+
+
+#ifndef GCC_AARCH_COMMON_PROTOS_H
+#define GCC_AARCH_COMMON_PROTOS_H
+
+extern int arm_early_load_addr_dep (rtx, rtx);
+extern int arm_early_store_addr_dep (rtx, rtx);
+extern int arm_mac_accumulator_is_mul_result (rtx, rtx);
+extern int arm_mac_accumulator_is_result (rtx, rtx);
+extern int arm_no_early_alu_shift_dep (rtx, rtx);
+extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
+extern int arm_no_early_mul_dep (rtx, rtx);
+extern int arm_no_early_store_addr_dep (rtx, rtx);
+
+#endif /* GCC_AARCH_COMMON_PROTOS_H */
diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c
new file mode 100644
index 00000000000..69366af9bd5
--- /dev/null
+++ b/gcc/config/arm/aarch-common.c
@@ -0,0 +1,278 @@
+/* Dependency checks for instruction scheduling, shared between ARM and
+ AARCH64.
+
+ Copyright (C) 1991-2013 Free Software Foundation, Inc.
+ Contributed by ARM 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.
+
+ 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/>. */
+
+
+/* Return nonzero if the CONSUMER instruction (a load) does need
+ PRODUCER's value to calculate the address. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "tm_p.h"
+#include "rtl.h"
+#include "tree.h"
+#include "c-family/c-common.h"
+#include "rtl.h"
+
+int
+arm_early_load_addr_dep (rtx producer, rtx consumer)
+{
+ rtx value = PATTERN (producer);
+ rtx addr = PATTERN (consumer);
+
+ if (GET_CODE (value) == COND_EXEC)
+ value = COND_EXEC_CODE (value);
+ if (GET_CODE (value) == PARALLEL)
+ value = XVECEXP (value, 0, 0);
+ value = XEXP (value, 0);
+ if (GET_CODE (addr) == COND_EXEC)
+ addr = COND_EXEC_CODE (addr);
+ if (GET_CODE (addr) == PARALLEL)
+ {
+ if (GET_CODE (XVECEXP (addr, 0, 0)) == RETURN)
+ addr = XVECEXP (addr, 0, 1);
+ else
+ addr = XVECEXP (addr, 0, 0);
+ }
+ addr = XEXP (addr, 1);
+
+ return reg_overlap_mentioned_p (value, addr);
+}
+
+/* Return nonzero if the CONSUMER instruction (an ALU op) does not
+ have an early register shift value or amount dependency on the
+ result of PRODUCER. */
+
+int
+arm_no_early_alu_shift_dep (rtx producer, rtx consumer)
+{
+ rtx value = PATTERN (producer);
+ rtx op = PATTERN (consumer);
+ rtx early_op;
+
+ if (GET_CODE (value) == COND_EXEC)
+ value = COND_EXEC_CODE (value);
+ if (GET_CODE (value) == PARALLEL)
+ value = XVECEXP (value, 0, 0);
+ value = XEXP (value, 0);
+ if (GET_CODE (op) == COND_EXEC)
+ op = COND_EXEC_CODE (op);
+ if (GET_CODE (op) == PARALLEL)
+ op = XVECEXP (op, 0, 0);
+ op = XEXP (op, 1);
+
+ early_op = XEXP (op, 0);
+ /* This is either an actual independent shift, or a shift applied to
+ the first operand of another operation. We want the whole shift
+ operation. */
+ if (REG_P (early_op))
+ early_op = op;
+
+ return !reg_overlap_mentioned_p (value, early_op);
+}
+
+/* Return nonzero if the CONSUMER instruction (an ALU op) does not
+ have an early register shift value dependency on the result of
+ PRODUCER. */
+
+int
+arm_no_early_alu_shift_value_dep (rtx producer, rtx consumer)
+{
+ rtx value = PATTERN (producer);
+ rtx op = PATTERN (consumer);
+ rtx early_op;
+
+ if (GET_CODE (value) == COND_EXEC)
+ value = COND_EXEC_CODE (value);
+ if (GET_CODE (value) == PARALLEL)
+ value = XVECEXP (value, 0, 0);
+ value = XEXP (value, 0);
+ if (GET_CODE (op) == COND_EXEC)
+ op = COND_EXEC_CODE (op);
+ if (GET_CODE (op) == PARALLEL)
+ op = XVECEXP (op, 0, 0);
+ op = XEXP (op, 1);
+
+ early_op = XEXP (op, 0);
+
+ /* This is either an actual independent shift, or a shift applied to
+ the first operand of another operation. We want the value being
+ shifted, in either case. */
+ if (!REG_P (early_op))
+ early_op = XEXP (early_op, 0);
+
+ return !reg_overlap_mentioned_p (value, early_op);
+}
+
+/* Return nonzero if the CONSUMER (a mul or mac op) does not
+ have an early register mult dependency on the result of
+ PRODUCER. */
+
+int
+arm_no_early_mul_dep (rtx producer, rtx consumer)
+{
+ rtx value = PATTERN (producer);
+ rtx op = PATTERN (consumer);
+
+ if (GET_CODE (value) == COND_EXEC)
+ value = COND_EXEC_CODE (value);
+ if (GET_CODE (value) == PARALLEL)
+ value = XVECEXP (value, 0, 0);
+ value = XEXP (value, 0);
+ if (GET_CODE (op) == COND_EXEC)
+ op = COND_EXEC_CODE (op);
+ if (GET_CODE (op) == PARALLEL)
+ op = XVECEXP (op, 0, 0);
+ op = XEXP (op, 1);
+
+ if (GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
+ {
+ if (GET_CODE (XEXP (op, 0)) == MULT)
+ return !reg_overlap_mentioned_p (value, XEXP (op, 0));
+ else
+ return !reg_overlap_mentioned_p (value, XEXP (op, 1));
+ }
+
+ return 0;
+}
+
+/* Return nonzero if the CONSUMER instruction (a store) does not need
+ PRODUCER's value to calculate the address. */
+
+int
+arm_no_early_store_addr_dep (rtx producer, rtx consumer)
+{
+ rtx value = PATTERN (producer);
+ rtx addr = PATTERN (consumer);
+
+ if (GET_CODE (value) == COND_EXEC)
+ value = COND_EXEC_CODE (value);
+ if (GET_CODE (value) == PARALLEL)
+ value = XVECEXP (value, 0, 0);
+ value = XEXP (value, 0);
+ if (GET_CODE (addr) == COND_EXEC)
+ addr = COND_EXEC_CODE (addr);
+ if (GET_CODE (addr) == PARALLEL)
+ addr = XVECEXP (addr, 0, 0);
+ addr = XEXP (addr, 0);
+
+ return !reg_overlap_mentioned_p (value, addr);
+}
+
+/* Return nonzero if the CONSUMER instruction (a store) does need
+ PRODUCER's value to calculate the address. */
+
+int
+arm_early_store_addr_dep (rtx producer, rtx consumer)
+{
+ return !arm_no_early_store_addr_dep (producer, consumer);
+}
+
+/* Return non-zero iff the consumer (a multiply-accumulate or a
+ multiple-subtract instruction) has an accumulator dependency on the
+ result of the producer and no other dependency on that result. It
+ does not check if the producer is multiply-accumulate instruction. */
+int
+arm_mac_accumulator_is_result (rtx producer, rtx consumer)
+{
+ rtx result;
+ rtx op0, op1, acc;
+
+ producer = PATTERN (producer);
+ consumer = PATTERN (consumer);
+
+ if (GET_CODE (producer) == COND_EXEC)
+ producer = COND_EXEC_CODE (producer);
+ if (GET_CODE (consumer) == COND_EXEC)
+ consumer = COND_EXEC_CODE (consumer);
+
+ if (GET_CODE (producer) != SET)
+ return 0;
+
+ result = XEXP (producer, 0);
+
+ if (GET_CODE (consumer) != SET)
+ return 0;
+
+ /* Check that the consumer is of the form
+ (set (...) (plus (mult ...) (...)))
+ or
+ (set (...) (minus (...) (mult ...))). */
+ if (GET_CODE (XEXP (consumer, 1)) == PLUS)
+ {
+ if (GET_CODE (XEXP (XEXP (consumer, 1), 0)) != MULT)
+ return 0;
+
+ op0 = XEXP (XEXP (XEXP (consumer, 1), 0), 0);
+ op1 = XEXP (XEXP (XEXP (consumer, 1), 0), 1);
+ acc = XEXP (XEXP (consumer, 1), 1);
+ }
+ else if (GET_CODE (XEXP (consumer, 1)) == MINUS)
+ {
+ if (GET_CODE (XEXP (XEXP (consumer, 1), 1)) != MULT)
+ return 0;
+
+ op0 = XEXP (XEXP (XEXP (consumer, 1), 1), 0);
+ op1 = XEXP (XEXP (XEXP (consumer, 1), 1), 1);
+ acc = XEXP (XEXP (consumer, 1), 0);
+ }
+ else
+ return 0;
+
+ return (reg_overlap_mentioned_p (result, acc)
+ && !reg_overlap_mentioned_p (result, op0)
+ && !reg_overlap_mentioned_p (result, op1));
+}
+
+/* Return non-zero if the consumer (a multiply-accumulate instruction)
+ has an accumulator dependency on the result of the producer (a
+ multiplication instruction) and no other dependency on that result. */
+int
+arm_mac_accumulator_is_mul_result (rtx producer, rtx consumer)
+{
+ rtx mul = PATTERN (producer);
+ rtx mac = PATTERN (consumer);
+ rtx mul_result;
+ rtx mac_op0, mac_op1, mac_acc;
+
+ if (GET_CODE (mul) == COND_EXEC)
+ mul = COND_EXEC_CODE (mul);
+ if (GET_CODE (mac) == COND_EXEC)
+ mac = COND_EXEC_CODE (mac);
+
+ /* Check that mul is of the form (set (...) (mult ...))
+ and mla is of the form (set (...) (plus (mult ...) (...))). */
+ if ((GET_CODE (mul) != SET || GET_CODE (XEXP (mul, 1)) != MULT)
+ || (GET_CODE (mac) != SET || GET_CODE (XEXP (mac, 1)) != PLUS
+ || GET_CODE (XEXP (XEXP (mac, 1), 0)) != MULT))
+ return 0;
+
+ mul_result = XEXP (mul, 0);
+ mac_op0 = XEXP (XEXP (XEXP (mac, 1), 0), 0);
+ mac_op1 = XEXP (XEXP (XEXP (mac, 1), 0), 1);
+ mac_acc = XEXP (XEXP (mac, 1), 1);
+
+ return (reg_overlap_mentioned_p (mul_result, mac_acc)
+ && !reg_overlap_mentioned_p (mul_result, mac_op0)
+ && !reg_overlap_mentioned_p (mul_result, mac_op1));
+}
diff --git a/gcc/config/arm/arm-fixed.md b/gcc/config/arm/arm-fixed.md
index dc8e7ac8c14..3972a850990 100644
--- a/gcc/config/arm/arm-fixed.md
+++ b/gcc/config/arm/arm-fixed.md
@@ -25,7 +25,8 @@
"TARGET_32BIT"
"add%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "yes,no")])
+ (set_attr "predicable_short_it" "yes,no")
+ (set_attr "type" "alu_reg")])
(define_insn "add<mode>3"
[(set (match_operand:ADDSUB 0 "s_register_operand" "=r")
@@ -34,7 +35,8 @@
"TARGET_INT_SIMD"
"sadd<qaddsub_suf>%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")])
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "alu_reg")])
(define_insn "usadd<mode>3"
[(set (match_operand:UQADDSUB 0 "s_register_operand" "=r")
@@ -43,7 +45,8 @@
"TARGET_INT_SIMD"
"uqadd<qaddsub_suf>%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")])
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "alu_reg")])
(define_insn "ssadd<mode>3"
[(set (match_operand:QADDSUB 0 "s_register_operand" "=r")
@@ -52,7 +55,8 @@
"TARGET_INT_SIMD"
"qadd<qaddsub_suf>%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")])
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "alu_reg")])
(define_insn "sub<mode>3"
[(set (match_operand:FIXED 0 "s_register_operand" "=l,r")
@@ -61,7 +65,8 @@
"TARGET_32BIT"
"sub%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "yes,no")])
+ (set_attr "predicable_short_it" "yes,no")
+ (set_attr "type" "alu_reg")])
(define_insn "sub<mode>3"
[(set (match_operand:ADDSUB 0 "s_register_operand" "=r")
@@ -70,7 +75,8 @@
"TARGET_INT_SIMD"
"ssub<qaddsub_suf>%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")])
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "alu_reg")])
(define_insn "ussub<mode>3"
[(set (match_operand:UQADDSUB 0 "s_register_operand" "=r")
@@ -80,7 +86,8 @@
"TARGET_INT_SIMD"
"uqsub<qaddsub_suf>%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")])
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "alu_reg")])
(define_insn "sssub<mode>3"
[(set (match_operand:QADDSUB 0 "s_register_operand" "=r")
@@ -89,7 +96,8 @@
"TARGET_INT_SIMD"
"qsub<qaddsub_suf>%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")])
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "alu_reg")])
;; Fractional multiplies.
@@ -246,6 +254,7 @@
return "";
}
[(set_attr "conds" "clob")
+ (set_attr "type" "multiple")
(set (attr "length")
(if_then_else (eq_attr "is_thumb" "yes")
(if_then_else (match_test "arm_restrict_it")
@@ -305,6 +314,7 @@
return "";
}
[(set_attr "conds" "clob")
+ (set_attr "type" "multiple")
(set (attr "length")
(if_then_else (eq_attr "is_thumb" "yes")
(if_then_else (match_test "arm_restrict_it")
@@ -406,7 +416,7 @@
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "shift" "1")
- (set_attr "type" "arlo_shift")])
+ (set_attr "type" "alu_shift_imm")])
(define_insn "arm_usatsihi"
[(set (match_operand:HI 0 "s_register_operand" "=r")
@@ -414,5 +424,6 @@
"TARGET_INT_SIMD"
"usat%?\\t%0, #16, %1"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "alu_imm")]
)
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index ef94bbcea25..f694dfdaae2 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -97,14 +97,6 @@ extern bool arm_tls_referenced_p (rtx);
extern int arm_coproc_mem_operand (rtx, bool);
extern int neon_vector_mem_operand (rtx, int, bool);
extern int neon_struct_mem_operand (rtx);
-extern int arm_no_early_store_addr_dep (rtx, rtx);
-extern int arm_early_store_addr_dep (rtx, rtx);
-extern int arm_early_load_addr_dep (rtx, rtx);
-extern int arm_no_early_alu_shift_dep (rtx, rtx);
-extern int arm_no_early_alu_shift_value_dep (rtx, rtx);
-extern int arm_no_early_mul_dep (rtx, rtx);
-extern int arm_mac_accumulator_is_result (rtx, rtx);
-extern int arm_mac_accumulator_is_mul_result (rtx, rtx);
extern int tls_mentioned_p (rtx);
extern int symbol_mentioned_p (rtx);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 294de80a73b..f9027ddd2e7 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -4544,7 +4544,9 @@ aapcs_vfp_allocate (CUMULATIVE_ARGS *pcum, enum machine_mode mode,
if (((pcum->aapcs_vfp_regs_free >> regno) & mask) == mask)
{
pcum->aapcs_vfp_reg_alloc = mask << regno;
- if (mode == BLKmode || (mode == TImode && !TARGET_NEON))
+ if (mode == BLKmode
+ || (mode == TImode && ! TARGET_NEON)
+ || ! arm_hard_regno_mode_ok (FIRST_VFP_REGNUM + regno, mode))
{
int i;
int rcount = pcum->aapcs_vfp_rcount;
@@ -8662,8 +8664,14 @@ xscale_sched_adjust_cost (rtx insn, rtx link, rtx dep, int * cost)
instruction we depend on is another ALU instruction, then we may
have to account for an additional stall. */
if (shift_opnum != 0
- && (attr_type == TYPE_ARLO_SHIFT
- || attr_type == TYPE_ARLO_SHIFT_REG
+ && (attr_type == TYPE_ALU_SHIFT_IMM
+ || attr_type == TYPE_ALUS_SHIFT_IMM
+ || attr_type == TYPE_LOGIC_SHIFT_IMM
+ || attr_type == TYPE_LOGICS_SHIFT_IMM
+ || attr_type == TYPE_ALU_SHIFT_REG
+ || attr_type == TYPE_ALUS_SHIFT_REG
+ || attr_type == TYPE_LOGIC_SHIFT_REG
+ || attr_type == TYPE_LOGICS_SHIFT_REG
|| attr_type == TYPE_MOV_SHIFT
|| attr_type == TYPE_MVN_SHIFT
|| attr_type == TYPE_MOV_SHIFT_REG
@@ -8950,9 +8958,17 @@ cortexa7_older_only (rtx insn)
switch (get_attr_type (insn))
{
- case TYPE_ARLO_REG:
+ case TYPE_ALU_REG:
+ case TYPE_ALUS_REG:
+ case TYPE_LOGIC_REG:
+ case TYPE_LOGICS_REG:
+ case TYPE_ADC_REG:
+ case TYPE_ADCS_REG:
+ case TYPE_ADR:
+ case TYPE_BFM:
+ case TYPE_REV:
case TYPE_MVN_REG:
- case TYPE_SHIFT:
+ case TYPE_SHIFT_IMM:
case TYPE_SHIFT_REG:
case TYPE_LOAD_BYTE:
case TYPE_LOAD1:
@@ -8961,7 +8977,7 @@ cortexa7_older_only (rtx insn)
case TYPE_FADDS:
case TYPE_FFARITHD:
case TYPE_FADDD:
- case TYPE_FCPYS:
+ case TYPE_FMOV:
case TYPE_F_CVT:
case TYPE_FCMPS:
case TYPE_FCMPD:
@@ -8973,7 +8989,8 @@ cortexa7_older_only (rtx insn)
case TYPE_FMACD:
case TYPE_FDIVS:
case TYPE_FDIVD:
- case TYPE_F_2_R:
+ case TYPE_F_MRC:
+ case TYPE_F_MRRC:
case TYPE_F_FLAG:
case TYPE_F_LOADS:
case TYPE_F_STORES:
@@ -8996,7 +9013,10 @@ cortexa7_younger (FILE *file, int verbose, rtx insn)
switch (get_attr_type (insn))
{
- case TYPE_ARLO_IMM:
+ case TYPE_ALU_IMM:
+ case TYPE_ALUS_IMM:
+ case TYPE_LOGIC_IMM:
+ case TYPE_LOGICS_IMM:
case TYPE_EXTEND:
case TYPE_MVN_IMM:
case TYPE_MOV_IMM:
@@ -14360,6 +14380,16 @@ thumb2_reorg (void)
&& IN_RANGE (INTVAL (op1), -7, 7))
action = CONV;
}
+ /* ADCS <Rd>, <Rn> */
+ else if (GET_CODE (XEXP (src, 0)) == PLUS
+ && rtx_equal_p (XEXP (XEXP (src, 0), 0), dst)
+ && low_register_operand (XEXP (XEXP (src, 0), 1),
+ SImode)
+ && COMPARISON_P (op1)
+ && cc_register (XEXP (op1, 0), VOIDmode)
+ && maybe_get_arm_condition_code (op1) == ARM_CS
+ && XEXP (op1, 1) == const0_rtx)
+ action = CONV;
break;
case MINUS:
@@ -16801,123 +16831,165 @@ arm_output_function_epilogue (FILE *file ATTRIBUTE_UNUSED,
}
}
-/* Generate and emit a pattern that will be recognized as STRD pattern. If even
- number of registers are being pushed, multiple STRD patterns are created for
- all register pairs. If odd number of registers are pushed, emit a
- combination of STRDs and STR for the prologue saves. */
+/* Generate and emit a sequence of insns equivalent to PUSH, but using
+ STR and STRD. If an even number of registers are being pushed, one
+ or more STRD patterns are created for each register pair. If an
+ odd number of registers are pushed, emit an initial STR followed by
+ as many STRD instructions as are needed. This works best when the
+ stack is initially 64-bit aligned (the normal case), since it
+ ensures that each STRD is also 64-bit aligned. */
static void
thumb2_emit_strd_push (unsigned long saved_regs_mask)
{
int num_regs = 0;
- int i, j;
+ int i;
+ int regno;
rtx par = NULL_RTX;
- rtx insn = NULL_RTX;
rtx dwarf = NULL_RTX;
- rtx tmp, reg, tmp1;
-
- for (i = 0; i <= LAST_ARM_REGNUM; i++)
- if (saved_regs_mask & (1 << i))
- num_regs++;
+ rtx tmp;
+ bool first = true;
- gcc_assert (num_regs && num_regs <= 16);
+ num_regs = bit_count (saved_regs_mask);
- /* Pre-decrement the stack pointer, based on there being num_regs 4-byte
- registers to push. */
- tmp = gen_rtx_SET (VOIDmode,
- stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs));
- RTX_FRAME_RELATED_P (tmp) = 1;
- insn = emit_insn (tmp);
+ /* Must be at least one register to save, and can't save SP or PC. */
+ gcc_assert (num_regs > 0 && num_regs <= 14);
+ gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM)));
+ gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM)));
- /* Create sequence for DWARF info. */
+ /* Create sequence for DWARF info. All the frame-related data for
+ debugging is held in this wrapper. */
dwarf = gen_rtx_SEQUENCE (VOIDmode, rtvec_alloc (num_regs + 1));
- /* RTLs cannot be shared, hence create new copy for dwarf. */
- tmp1 = gen_rtx_SET (VOIDmode,
- stack_pointer_rtx,
- plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs));
- RTX_FRAME_RELATED_P (tmp1) = 1;
- XVECEXP (dwarf, 0, 0) = tmp1;
+ /* Describe the stack adjustment. */
+ tmp = gen_rtx_SET (VOIDmode,
+ stack_pointer_rtx,
+ plus_constant (Pmode, stack_pointer_rtx, -4 * num_regs));
+ RTX_FRAME_RELATED_P (tmp) = 1;
+ XVECEXP (dwarf, 0, 0) = tmp;
- gcc_assert (!(saved_regs_mask & (1 << SP_REGNUM)));
- gcc_assert (!(saved_regs_mask & (1 << PC_REGNUM)));
+ /* Find the first register. */
+ for (regno = 0; (saved_regs_mask & (1 << regno)) == 0; regno++)
+ ;
- /* Var j iterates over all the registers to gather all the registers in
- saved_regs_mask. Var i gives index of register R_j in stack frame.
- A PARALLEL RTX of register-pair is created here, so that pattern for
- STRD can be matched. If num_regs is odd, 1st register will be pushed
- using STR and remaining registers will be pushed with STRD in pairs.
- If num_regs is even, all registers are pushed with STRD in pairs.
- Hence, skip first element for odd num_regs. */
- for (i = num_regs - 1, j = LAST_ARM_REGNUM; i >= (num_regs % 2); j--)
- if (saved_regs_mask & (1 << j))
- {
- /* Create RTX for store. New RTX is created for dwarf as
- they are not sharable. */
- reg = gen_rtx_REG (SImode, j);
- tmp = gen_rtx_SET (SImode,
- gen_frame_mem
- (SImode,
- plus_constant (Pmode, stack_pointer_rtx, 4 * i)),
- reg);
+ i = 0;
- tmp1 = gen_rtx_SET (SImode,
- gen_frame_mem
- (SImode,
- plus_constant (Pmode, stack_pointer_rtx, 4 * i)),
- reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
- RTX_FRAME_RELATED_P (tmp1) = 1;
-
- if (((i - (num_regs % 2)) % 2) == 1)
- /* When (i - (num_regs % 2)) is odd, the RTX to be emitted is yet to
- be created. Hence create it first. The STRD pattern we are
- generating is :
- [ (SET (MEM (PLUS (SP) (NUM))) (reg_t1))
- (SET (MEM (PLUS (SP) (NUM + 4))) (reg_t2)) ]
- where the target registers need not be consecutive. */
- par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
+ /* If there's an odd number of registers to push. Start off by
+ pushing a single register. This ensures that subsequent strd
+ operations are dword aligned (assuming that SP was originally
+ 64-bit aligned). */
+ if ((num_regs & 1) != 0)
+ {
+ rtx reg, mem, insn;
- /* Register R_j is added in PARALLEL RTX. If (i - (num_regs % 2)) is
- even, the reg_j is added as 0th element and if it is odd, reg_i is
- added as 1st element of STRD pattern shown above. */
- XVECEXP (par, 0, ((i - (num_regs % 2)) % 2)) = tmp;
- XVECEXP (dwarf, 0, (i + 1)) = tmp1;
+ reg = gen_rtx_REG (SImode, regno);
+ if (num_regs == 1)
+ mem = gen_frame_mem (Pmode, gen_rtx_PRE_DEC (Pmode,
+ stack_pointer_rtx));
+ else
+ mem = gen_frame_mem (Pmode,
+ gen_rtx_PRE_MODIFY
+ (Pmode, stack_pointer_rtx,
+ plus_constant (Pmode, stack_pointer_rtx,
+ -4 * num_regs)));
- if (((i - (num_regs % 2)) % 2) == 0)
- /* When (i - (num_regs % 2)) is even, RTXs for both the registers
- to be loaded are generated in above given STRD pattern, and the
- pattern can be emitted now. */
- emit_insn (par);
+ tmp = gen_rtx_SET (VOIDmode, mem, reg);
+ RTX_FRAME_RELATED_P (tmp) = 1;
+ insn = emit_insn (tmp);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
+ tmp = gen_rtx_SET (VOIDmode, gen_frame_mem (Pmode, stack_pointer_rtx),
+ reg);
+ RTX_FRAME_RELATED_P (tmp) = 1;
+ i++;
+ regno++;
+ XVECEXP (dwarf, 0, i) = tmp;
+ first = false;
+ }
- i--;
- }
+ while (i < num_regs)
+ if (saved_regs_mask & (1 << regno))
+ {
+ rtx reg1, reg2, mem1, mem2;
+ rtx tmp0, tmp1, tmp2;
+ int regno2;
- if ((num_regs % 2) == 1)
- {
- /* If odd number of registers are pushed, generate STR pattern to store
- lone register. */
- for (; (saved_regs_mask & (1 << j)) == 0; j--);
+ /* Find the register to pair with this one. */
+ for (regno2 = regno + 1; (saved_regs_mask & (1 << regno2)) == 0;
+ regno2++)
+ ;
- tmp1 = gen_frame_mem (SImode, plus_constant (Pmode,
- stack_pointer_rtx, 4 * i));
- reg = gen_rtx_REG (SImode, j);
- tmp = gen_rtx_SET (SImode, tmp1, reg);
- RTX_FRAME_RELATED_P (tmp) = 1;
+ reg1 = gen_rtx_REG (SImode, regno);
+ reg2 = gen_rtx_REG (SImode, regno2);
- emit_insn (tmp);
+ if (first)
+ {
+ rtx insn;
+
+ first = false;
+ mem1 = gen_frame_mem (Pmode, plus_constant (Pmode,
+ stack_pointer_rtx,
+ -4 * num_regs));
+ mem2 = gen_frame_mem (Pmode, plus_constant (Pmode,
+ stack_pointer_rtx,
+ -4 * (num_regs - 1)));
+ tmp0 = gen_rtx_SET (VOIDmode, stack_pointer_rtx,
+ plus_constant (Pmode, stack_pointer_rtx,
+ -4 * (num_regs)));
+ tmp1 = gen_rtx_SET (VOIDmode, mem1, reg1);
+ tmp2 = gen_rtx_SET (VOIDmode, mem2, reg2);
+ RTX_FRAME_RELATED_P (tmp0) = 1;
+ RTX_FRAME_RELATED_P (tmp1) = 1;
+ RTX_FRAME_RELATED_P (tmp2) = 1;
+ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (3));
+ XVECEXP (par, 0, 0) = tmp0;
+ XVECEXP (par, 0, 1) = tmp1;
+ XVECEXP (par, 0, 2) = tmp2;
+ insn = emit_insn (par);
+ RTX_FRAME_RELATED_P (insn) = 1;
+ add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
+ }
+ else
+ {
+ mem1 = gen_frame_mem (Pmode, plus_constant (Pmode,
+ stack_pointer_rtx,
+ 4 * i));
+ mem2 = gen_frame_mem (Pmode, plus_constant (Pmode,
+ stack_pointer_rtx,
+ 4 * (i + 1)));
+ tmp1 = gen_rtx_SET (VOIDmode, mem1, reg1);
+ tmp2 = gen_rtx_SET (VOIDmode, mem2, reg2);
+ RTX_FRAME_RELATED_P (tmp1) = 1;
+ RTX_FRAME_RELATED_P (tmp2) = 1;
+ par = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
+ XVECEXP (par, 0, 0) = tmp1;
+ XVECEXP (par, 0, 1) = tmp2;
+ emit_insn (par);
+ }
- tmp1 = gen_rtx_SET (SImode,
- gen_frame_mem
- (SImode,
- plus_constant (Pmode, stack_pointer_rtx, 4 * i)),
- reg);
- RTX_FRAME_RELATED_P (tmp1) = 1;
- XVECEXP (dwarf, 0, (i + 1)) = tmp1;
- }
+ /* Create unwind information. This is an approximation. */
+ tmp1 = gen_rtx_SET (VOIDmode,
+ gen_frame_mem (Pmode,
+ plus_constant (Pmode,
+ stack_pointer_rtx,
+ 4 * i)),
+ reg1);
+ tmp2 = gen_rtx_SET (VOIDmode,
+ gen_frame_mem (Pmode,
+ plus_constant (Pmode,
+ stack_pointer_rtx,
+ 4 * (i + 1))),
+ reg2);
+
+ RTX_FRAME_RELATED_P (tmp1) = 1;
+ RTX_FRAME_RELATED_P (tmp2) = 1;
+ XVECEXP (dwarf, 0, i + 1) = tmp1;
+ XVECEXP (dwarf, 0, i + 2) = tmp2;
+ i += 2;
+ regno = regno2 + 1;
+ }
+ else
+ regno++;
- add_reg_note (insn, REG_FRAME_RELATED_EXPR, dwarf);
- RTX_FRAME_RELATED_P (insn) = 1;
return;
}
@@ -25394,163 +25466,6 @@ arm_setup_incoming_varargs (cumulative_args_t pcum_v,
*pretend_size = (NUM_ARG_REGS - nregs) * UNITS_PER_WORD;
}
-/* Return nonzero if the CONSUMER instruction (a store) does not need
- PRODUCER's value to calculate the address. */
-
-int
-arm_no_early_store_addr_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx addr = PATTERN (consumer);
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (addr) == COND_EXEC)
- addr = COND_EXEC_CODE (addr);
- if (GET_CODE (addr) == PARALLEL)
- addr = XVECEXP (addr, 0, 0);
- addr = XEXP (addr, 0);
-
- return !reg_overlap_mentioned_p (value, addr);
-}
-
-/* Return nonzero if the CONSUMER instruction (a store) does need
- PRODUCER's value to calculate the address. */
-
-int
-arm_early_store_addr_dep (rtx producer, rtx consumer)
-{
- return !arm_no_early_store_addr_dep (producer, consumer);
-}
-
-/* Return nonzero if the CONSUMER instruction (a load) does need
- PRODUCER's value to calculate the address. */
-
-int
-arm_early_load_addr_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx addr = PATTERN (consumer);
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (addr) == COND_EXEC)
- addr = COND_EXEC_CODE (addr);
- if (GET_CODE (addr) == PARALLEL)
- {
- if (GET_CODE (XVECEXP (addr, 0, 0)) == RETURN)
- addr = XVECEXP (addr, 0, 1);
- else
- addr = XVECEXP (addr, 0, 0);
- }
- addr = XEXP (addr, 1);
-
- return reg_overlap_mentioned_p (value, addr);
-}
-
-/* Return nonzero if the CONSUMER instruction (an ALU op) does not
- have an early register shift value or amount dependency on the
- result of PRODUCER. */
-
-int
-arm_no_early_alu_shift_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx op = PATTERN (consumer);
- rtx early_op;
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (op) == COND_EXEC)
- op = COND_EXEC_CODE (op);
- if (GET_CODE (op) == PARALLEL)
- op = XVECEXP (op, 0, 0);
- op = XEXP (op, 1);
-
- early_op = XEXP (op, 0);
- /* This is either an actual independent shift, or a shift applied to
- the first operand of another operation. We want the whole shift
- operation. */
- if (REG_P (early_op))
- early_op = op;
-
- return !reg_overlap_mentioned_p (value, early_op);
-}
-
-/* Return nonzero if the CONSUMER instruction (an ALU op) does not
- have an early register shift value dependency on the result of
- PRODUCER. */
-
-int
-arm_no_early_alu_shift_value_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx op = PATTERN (consumer);
- rtx early_op;
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (op) == COND_EXEC)
- op = COND_EXEC_CODE (op);
- if (GET_CODE (op) == PARALLEL)
- op = XVECEXP (op, 0, 0);
- op = XEXP (op, 1);
-
- early_op = XEXP (op, 0);
-
- /* This is either an actual independent shift, or a shift applied to
- the first operand of another operation. We want the value being
- shifted, in either case. */
- if (!REG_P (early_op))
- early_op = XEXP (early_op, 0);
-
- return !reg_overlap_mentioned_p (value, early_op);
-}
-
-/* Return nonzero if the CONSUMER (a mul or mac op) does not
- have an early register mult dependency on the result of
- PRODUCER. */
-
-int
-arm_no_early_mul_dep (rtx producer, rtx consumer)
-{
- rtx value = PATTERN (producer);
- rtx op = PATTERN (consumer);
-
- if (GET_CODE (value) == COND_EXEC)
- value = COND_EXEC_CODE (value);
- if (GET_CODE (value) == PARALLEL)
- value = XVECEXP (value, 0, 0);
- value = XEXP (value, 0);
- if (GET_CODE (op) == COND_EXEC)
- op = COND_EXEC_CODE (op);
- if (GET_CODE (op) == PARALLEL)
- op = XVECEXP (op, 0, 0);
- op = XEXP (op, 1);
-
- if (GET_CODE (op) == PLUS || GET_CODE (op) == MINUS)
- {
- if (GET_CODE (XEXP (op, 0)) == MULT)
- return !reg_overlap_mentioned_p (value, XEXP (op, 0));
- else
- return !reg_overlap_mentioned_p (value, XEXP (op, 1));
- }
-
- return 0;
-}
-
/* We can't rely on the caller doing the proper promotion when
using APCS or ATPCS. */
@@ -25600,95 +25515,6 @@ arm_cxx_guard_type (void)
return TARGET_AAPCS_BASED ? integer_type_node : long_long_integer_type_node;
}
-/* Return non-zero iff the consumer (a multiply-accumulate or a
- multiple-subtract instruction) has an accumulator dependency on the
- result of the producer and no other dependency on that result. It
- does not check if the producer is multiply-accumulate instruction. */
-int
-arm_mac_accumulator_is_result (rtx producer, rtx consumer)
-{
- rtx result;
- rtx op0, op1, acc;
-
- producer = PATTERN (producer);
- consumer = PATTERN (consumer);
-
- if (GET_CODE (producer) == COND_EXEC)
- producer = COND_EXEC_CODE (producer);
- if (GET_CODE (consumer) == COND_EXEC)
- consumer = COND_EXEC_CODE (consumer);
-
- if (GET_CODE (producer) != SET)
- return 0;
-
- result = XEXP (producer, 0);
-
- if (GET_CODE (consumer) != SET)
- return 0;
-
- /* Check that the consumer is of the form
- (set (...) (plus (mult ...) (...)))
- or
- (set (...) (minus (...) (mult ...))). */
- if (GET_CODE (XEXP (consumer, 1)) == PLUS)
- {
- if (GET_CODE (XEXP (XEXP (consumer, 1), 0)) != MULT)
- return 0;
-
- op0 = XEXP (XEXP (XEXP (consumer, 1), 0), 0);
- op1 = XEXP (XEXP (XEXP (consumer, 1), 0), 1);
- acc = XEXP (XEXP (consumer, 1), 1);
- }
- else if (GET_CODE (XEXP (consumer, 1)) == MINUS)
- {
- if (GET_CODE (XEXP (XEXP (consumer, 1), 1)) != MULT)
- return 0;
-
- op0 = XEXP (XEXP (XEXP (consumer, 1), 1), 0);
- op1 = XEXP (XEXP (XEXP (consumer, 1), 1), 1);
- acc = XEXP (XEXP (consumer, 1), 0);
- }
- else
- return 0;
-
- return (reg_overlap_mentioned_p (result, acc)
- && !reg_overlap_mentioned_p (result, op0)
- && !reg_overlap_mentioned_p (result, op1));
-}
-
-/* Return non-zero if the consumer (a multiply-accumulate instruction)
- has an accumulator dependency on the result of the producer (a
- multiplication instruction) and no other dependency on that result. */
-int
-arm_mac_accumulator_is_mul_result (rtx producer, rtx consumer)
-{
- rtx mul = PATTERN (producer);
- rtx mac = PATTERN (consumer);
- rtx mul_result;
- rtx mac_op0, mac_op1, mac_acc;
-
- if (GET_CODE (mul) == COND_EXEC)
- mul = COND_EXEC_CODE (mul);
- if (GET_CODE (mac) == COND_EXEC)
- mac = COND_EXEC_CODE (mac);
-
- /* Check that mul is of the form (set (...) (mult ...))
- and mla is of the form (set (...) (plus (mult ...) (...))). */
- if ((GET_CODE (mul) != SET || GET_CODE (XEXP (mul, 1)) != MULT)
- || (GET_CODE (mac) != SET || GET_CODE (XEXP (mac, 1)) != PLUS
- || GET_CODE (XEXP (XEXP (mac, 1), 0)) != MULT))
- return 0;
-
- mul_result = XEXP (mul, 0);
- mac_op0 = XEXP (XEXP (XEXP (mac, 1), 0), 0);
- mac_op1 = XEXP (XEXP (XEXP (mac, 1), 0), 1);
- mac_acc = XEXP (XEXP (mac, 1), 1);
-
- return (reg_overlap_mentioned_p (mul_result, mac_acc)
- && !reg_overlap_mentioned_p (mul_result, mac_op0)
- && !reg_overlap_mentioned_p (mul_result, mac_op1));
-}
-
/* The EABI says test the least significant bit of a guard variable. */
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 387d2717431..1781b75b34b 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -645,6 +645,8 @@ extern int prefer_neon_for_64bits;
#define BIGGEST_ALIGNMENT (ARM_DOUBLEWORD_ALIGN ? DOUBLEWORD_ALIGNMENT : 32)
+#define MALLOC_ABI_ALIGNMENT BIGGEST_ALIGNMENT
+
/* XXX Blah -- this macro is used directly by libobjc. Since it
supports no vector modes, cut out the complexity and fall back
on BIGGEST_FIELD_ALIGNMENT. */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index fceb04c1272..8a482b570ec 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -245,411 +245,13 @@
(set_attr "length" "4")
(set_attr "pool_range" "250")])
-; TYPE attribute is used to classify instructions for use in scheduling.
-;
-; Instruction classification:
-;
-; arlo_imm any arithmetic or logical instruction that doesn't have
-; a shifted operand and has an immediate operand. This
-; excludes MOV, MVN and RSB(S) immediate.
-; arlo_reg any arithmetic or logical instruction that doesn't have
-; a shifted or an immediate operand. This excludes
-; MOV and MVN but includes MOVT. This is also the default.
-; arlo_shift any arithmetic or logical instruction that has a source
-; operand shifted by a constant. This excludes
-; simple shifts.
-; arlo_shift_reg as arlo_shift, with the shift amount specified in a
-; register.
-; block blockage insn, this blocks all functional units.
-; branch branch.
-; call subroutine call.
-; clz count leading zeros (CLZ).
-; extend extend instruction (SXTB, SXTH, UXTB, UXTH).
-; f_2_r transfer from float to core (no memory needed).
-; f_cvt conversion between float and integral.
-; f_flag transfer of co-processor flags to the CPSR.
-; f_load[d,s] double/single load from memory. Used for VFP unit.
-; f_minmax[d,s] double/single floating point minimum/maximum.
-; f_rint[d,s] double/single floating point rount to integral.
-; f_sel[d,s] double/single floating byte select.
-; f_store[d,s] double/single store to memory. Used for VFP unit.
-; fadd[d,s] double/single floating-point scalar addition.
-; fcmp[d,s] double/single floating-point compare.
-; fconst[d,s] double/single load immediate.
-; fcpys single precision floating point cpy.
-; fdiv[d,s] double/single precision floating point division.
-; ffarith[d,s] double/single floating point abs/neg/cpy.
-; ffma[d,s] double/single floating point fused multiply-accumulate.
-; float floating point arithmetic operation.
-; fmac[d,s] double/single floating point multiply-accumulate.
-; fmul[d,s] double/single floating point multiply.
-; load_byte load byte(s) from memory to arm registers.
-; load1 load 1 word from memory to arm registers.
-; load2 load 2 words from memory to arm registers.
-; load3 load 3 words from memory to arm registers.
-; load4 load 4 words from memory to arm registers.
-; mla integer multiply accumulate.
-; mlas integer multiply accumulate, flag setting.
-; mov_imm simple MOV instruction that moves an immediate to
-; register. This includes MOVW, but not MOVT.
-; mov_reg simple MOV instruction that moves a register to another
-; register. This includes MOVW, but not MOVT.
-; mov_shift simple MOV instruction, shifted operand by a constant.
-; mov_shift_reg simple MOV instruction, shifted operand by a register.
-; mul integer multiply.
-; muls integer multiply, flag setting.
-; mvn_imm inverting move instruction, immediate.
-; mvn_reg inverting move instruction, register.
-; mvn_shift inverting move instruction, shifted operand by a constant.
-; mvn_shift_reg inverting move instruction, shifted operand by a register.
-; r_2_f transfer from core to float.
-; sdiv signed division.
-; shift simple shift operation (LSL, LSR, ASR, ROR) with an
-; immediate.
-; shift_reg simple shift by a register.
-; smlad signed multiply accumulate dual.
-; smladx signed multiply accumulate dual reverse.
-; smlal signed multiply accumulate long.
-; smlald signed multiply accumulate long dual.
-; smlals signed multiply accumulate long, flag setting.
-; smlalxy signed multiply accumulate, 16x16-bit, 64-bit accumulate.
-; smlawx signed multiply accumulate, 32x16-bit, 32-bit accumulate.
-; smlawy signed multiply accumulate wide, 32x16-bit,
-; 32-bit accumulate.
-; smlaxy signed multiply accumulate, 16x16-bit, 32-bit accumulate.
-; smlsd signed multiply subtract dual.
-; smlsdx signed multiply subtract dual reverse.
-; smlsld signed multiply subtract long dual.
-; smmla signed most significant word multiply accumulate.
-; smmul signed most significant word multiply.
-; smmulr signed most significant word multiply, rounded.
-; smuad signed dual multiply add.
-; smuadx signed dual multiply add reverse.
-; smull signed multiply long.
-; smulls signed multiply long, flag setting.
-; smulwy signed multiply wide, 32x16-bit, 32-bit accumulate.
-; smulxy signed multiply, 16x16-bit, 32-bit accumulate.
-; smusd signed dual multiply subtract.
-; smusdx signed dual multiply subtract reverse.
-; store1 store 1 word to memory from arm registers.
-; store2 store 2 words to memory from arm registers.
-; store3 store 3 words to memory from arm registers.
-; store4 store 4 (or more) words to memory from arm registers.
-; udiv unsigned division.
-; umaal unsigned multiply accumulate accumulate long.
-; umlal unsigned multiply accumulate long.
-; umlals unsigned multiply accumulate long, flag setting.
-; umull unsigned multiply long.
-; umulls unsigned multiply long, flag setting.
-;
-; The classification below is for instructions used by the Wireless MMX
-; Technology. Each attribute value is used to classify an instruction of the
-; same name or family.
-;
-; wmmx_tandc
-; wmmx_tbcst
-; wmmx_textrc
-; wmmx_textrm
-; wmmx_tinsr
-; wmmx_tmcr
-; wmmx_tmcrr
-; wmmx_tmia
-; wmmx_tmiaph
-; wmmx_tmiaxy
-; wmmx_tmrc
-; wmmx_tmrrc
-; wmmx_tmovmsk
-; wmmx_torc
-; wmmx_torvsc
-; wmmx_wabs
-; wmmx_wdiff
-; wmmx_wacc
-; wmmx_wadd
-; wmmx_waddbhus
-; wmmx_waddsubhx
-; wmmx_waligni
-; wmmx_walignr
-; wmmx_wand
-; wmmx_wandn
-; wmmx_wavg2
-; wmmx_wavg4
-; wmmx_wcmpeq
-; wmmx_wcmpgt
-; wmmx_wmac
-; wmmx_wmadd
-; wmmx_wmax
-; wmmx_wmerge
-; wmmx_wmiawxy
-; wmmx_wmiaxy
-; wmmx_wmin
-; wmmx_wmov
-; wmmx_wmul
-; wmmx_wmulw
-; wmmx_wldr
-; wmmx_wor
-; wmmx_wpack
-; wmmx_wqmiaxy
-; wmmx_wqmulm
-; wmmx_wqmulwm
-; wmmx_wror
-; wmmx_wsad
-; wmmx_wshufh
-; wmmx_wsll
-; wmmx_wsra
-; wmmx_wsrl
-; wmmx_wstr
-; wmmx_wsub
-; wmmx_wsubaddhx
-; wmmx_wunpckeh
-; wmmx_wunpckel
-; wmmx_wunpckih
-; wmmx_wunpckil
-; wmmx_wxor
-
-(define_attr "type"
- "arlo_imm,\
- arlo_reg,\
- arlo_shift,\
- arlo_shift_reg,\
- block,\
- branch,\
- call,\
- clz,\
- extend,\
- f_2_r,\
- f_cvt,\
- f_flag,\
- f_loadd,\
- f_loads,\
- f_minmaxd,\
- f_minmaxs,\
- f_rintd,\
- f_rints,\
- f_seld,\
- f_sels,\
- f_stored,\
- f_stores,\
- faddd,\
- fadds,\
- fcmpd,\
- fcmps,\
- fconstd,\
- fconsts,\
- fcpys,\
- fdivd,\
- fdivs,\
- ffarithd,\
- ffariths,\
- ffmad,\
- ffmas,\
- float,\
- fmacd,\
- fmacs,\
- fmuld,\
- fmuls,\
- load_byte,\
- load1,\
- load2,\
- load3,\
- load4,\
- mla,\
- mlas,\
- mov_imm,\
- mov_reg,\
- mov_shift,\
- mov_shift_reg,\
- mul,\
- muls,\
- mvn_imm,\
- mvn_reg,\
- mvn_shift,\
- mvn_shift_reg,\
- r_2_f,\
- sdiv,\
- shift,\
- shift_reg,\
- smlad,\
- smladx,\
- smlal,\
- smlald,\
- smlals,\
- smlalxy,\
- smlawx,\
- smlawy,\
- smlaxy,\
- smlsd,\
- smlsdx,\
- smlsld,\
- smmla,\
- smmul,\
- smmulr,\
- smuad,\
- smuadx,\
- smull,\
- smulls,\
- smulwy,\
- smulxy,\
- smusd,\
- smusdx,\
- store1,\
- store2,\
- store3,\
- store4,\
- udiv,\
- umaal,\
- umlal,\
- umlals,\
- umull,\
- umulls,\
- wmmx_tandc,\
- wmmx_tbcst,\
- wmmx_textrc,\
- wmmx_textrm,\
- wmmx_tinsr,\
- wmmx_tmcr,\
- wmmx_tmcrr,\
- wmmx_tmia,\
- wmmx_tmiaph,\
- wmmx_tmiaxy,\
- wmmx_tmrc,\
- wmmx_tmrrc,\
- wmmx_tmovmsk,\
- wmmx_torc,\
- wmmx_torvsc,\
- wmmx_wabs,\
- wmmx_wabsdiff,\
- wmmx_wacc,\
- wmmx_wadd,\
- wmmx_waddbhus,\
- wmmx_waddsubhx,\
- wmmx_waligni,\
- wmmx_walignr,\
- wmmx_wand,\
- wmmx_wandn,\
- wmmx_wavg2,\
- wmmx_wavg4,\
- wmmx_wcmpeq,\
- wmmx_wcmpgt,\
- wmmx_wmac,\
- wmmx_wmadd,\
- wmmx_wmax,\
- wmmx_wmerge,\
- wmmx_wmiawxy,\
- wmmx_wmiaxy,\
- wmmx_wmin,\
- wmmx_wmov,\
- wmmx_wmul,\
- wmmx_wmulw,\
- wmmx_wldr,\
- wmmx_wor,\
- wmmx_wpack,\
- wmmx_wqmiaxy,\
- wmmx_wqmulm,\
- wmmx_wqmulwm,\
- wmmx_wror,\
- wmmx_wsad,\
- wmmx_wshufh,\
- wmmx_wsll,\
- wmmx_wsra,\
- wmmx_wsrl,\
- wmmx_wstr,\
- wmmx_wsub,\
- wmmx_wsubaddhx,\
- wmmx_wunpckeh,\
- wmmx_wunpckel,\
- wmmx_wunpckih,\
- wmmx_wunpckil,\
- wmmx_wxor"
- (const_string "arlo_reg"))
-
-; Is this an (integer side) multiply with a 32-bit (or smaller) result?
-(define_attr "mul32" "no,yes"
- (if_then_else
- (eq_attr "type"
- "smulxy,smlaxy,smulwy,smlawx,mul,muls,mla,mlas,smlawy,smuad,smuadx,\
- smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,smlald,smlsld")
- (const_string "yes")
- (const_string "no")))
-
-; Is this an (integer side) multiply with a 64-bit result?
-(define_attr "mul64" "no,yes"
- (if_then_else
- (eq_attr "type"
- "smlalxy,umull,umulls,umaal,umlal,umlals,smull,smulls,smlal,smlals")
- (const_string "yes")
- (const_string "no")))
+;; Instruction classification types
+(include "types.md")
; Load scheduling, set from the arm_ld_sched variable
; initialized by arm_option_override()
(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched")))
-;; Classification of NEON instructions for scheduling purposes.
-(define_attr "neon_type"
- "neon_int_1,\
- neon_int_2,\
- neon_int_3,\
- neon_int_4,\
- neon_int_5,\
- neon_vqneg_vqabs,\
- neon_vmov,\
- neon_vaba,\
- neon_vsma,\
- neon_vaba_qqq,\
- neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
- neon_mul_qqq_8_16_32_ddd_32,\
- neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
- neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
- neon_mla_qqq_8_16,\
- neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
- neon_mla_qqq_32_qqd_32_scalar,\
- neon_mul_ddd_16_scalar_32_16_long_scalar,\
- neon_mul_qqd_32_scalar,\
- neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
- neon_shift_1,\
- neon_shift_2,\
- neon_shift_3,\
- neon_vshl_ddd,\
- neon_vqshl_vrshl_vqrshl_qqq,\
- neon_vsra_vrsra,\
- neon_fp_vadd_ddd_vabs_dd,\
- neon_fp_vadd_qqq_vabs_qq,\
- neon_fp_vsum,\
- neon_fp_vmul_ddd,\
- neon_fp_vmul_qqd,\
- neon_fp_vmla_ddd,\
- neon_fp_vmla_qqq,\
- neon_fp_vmla_ddd_scalar,\
- neon_fp_vmla_qqq_scalar,\
- neon_fp_vrecps_vrsqrts_ddd,\
- neon_fp_vrecps_vrsqrts_qqq,\
- neon_bp_simple,\
- neon_bp_2cycle,\
- neon_bp_3cycle,\
- neon_ldr,\
- neon_str,\
- neon_vld1_1_2_regs,\
- neon_vld1_3_4_regs,\
- neon_vld2_2_regs_vld1_vld2_all_lanes,\
- neon_vld2_4_regs,\
- neon_vld3_vld4,\
- neon_vst1_1_2_regs_vst2_2_regs,\
- neon_vst1_3_4_regs,\
- neon_vst2_4_regs_vst3_vst4,\
- neon_vst3_vst4,\
- neon_vld1_vld2_lane,\
- neon_vld3_vld4_lane,\
- neon_vst1_vst2_lane,\
- neon_vst3_vst4_lane,\
- neon_vld3_vld4_all_lanes,\
- neon_mcr,\
- neon_mcr_2_mcrr,\
- neon_mrc,\
- neon_mrrc,\
- neon_ldm_2,\
- neon_stm_2,\
- none"
- (const_string "none"))
-
; condition codes: this one is used by final_prescan_insn to speed up
; conditionalizing instructions. It saves having to scan the rtl to see if
; it uses or alters the condition codes.
@@ -675,9 +277,34 @@
(ior (eq_attr "is_thumb1" "yes")
(eq_attr "type" "call"))
(const_string "clob")
- (if_then_else (eq_attr "neon_type" "none")
- (const_string "nocond")
- (const_string "unconditional"))))
+ (if_then_else (eq_attr "type"
+ "!neon_int_1, neon_int_2, neon_int_3, neon_int_4, neon_int_5,\
+ neon_vqneg_vqabs, neon_vmov, neon_vaba, neon_vsma, neon_vaba_qqq,\
+ neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ neon_mul_qqq_8_16_32_ddd_32,\
+ neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
+ neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ neon_mla_qqq_8_16,\
+ neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
+ neon_mla_qqq_32_qqd_32_scalar,\
+ neon_mul_ddd_16_scalar_32_16_long_scalar, neon_mul_qqd_32_scalar,\
+ neon_mla_ddd_16_scalar_qdd_32_16_long_scalar, neon_shift_1,\
+ neon_shift_2, neon_shift_3, neon_vshl_ddd,\
+ neon_vqshl_vrshl_vqrshl_qqq, neon_vsra_vrsra,\
+ neon_fp_vadd_ddd_vabs_dd, neon_fp_vadd_qqq_vabs_qq, neon_fp_vsum,\
+ neon_fp_vmul_ddd, neon_fp_vmul_qqd, neon_fp_vmla_ddd,\
+ neon_fp_vmla_qqq, neon_fp_vmla_ddd_scalar, neon_fp_vmla_qqq_scalar,\
+ neon_fp_vrecps_vrsqrts_ddd, neon_fp_vrecps_vrsqrts_qqq,\
+ neon_bp_simple, neon_bp_2cycle, neon_bp_3cycle, neon_ldr, neon_str,\
+ neon_vld1_1_2_regs, neon_vld1_3_4_regs,\
+ neon_vld2_2_regs_vld1_vld2_all_lanes, neon_vld2_4_regs,\
+ neon_vld3_vld4, neon_vst1_1_2_regs_vst2_2_regs, neon_vst1_3_4_regs,\
+ neon_vst2_4_regs_vst3_vst4, neon_vst3_vst4, neon_vld1_vld2_lane,\
+ neon_vld3_vld4_lane, neon_vst1_vst2_lane, neon_vst3_vst4_lane,\
+ neon_vld3_vld4_all_lanes, neon_mcr, neon_mcr_2_mcrr, neon_mrc,\
+ neon_mrrc, neon_ldm_2, neon_stm_2")
+ (const_string "nocond")
+ (const_string "unconditional"))))
; Predicable means that the insn can be conditionally executed based on
; an automatically added predicate (additional patterns are generated by
@@ -703,8 +330,11 @@
; than one on the main cpu execution unit.
(define_attr "core_cycles" "single,multi"
(if_then_else (eq_attr "type"
- "arlo_imm, arlo_reg,\
- extend, shift, arlo_shift, float, fdivd, fdivs,\
+ "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_reg,\
+ alu_shift_imm, alu_shift_reg, alus_ext, alus_imm, alus_reg,\
+ alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\
+ logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\
+ logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\
wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\
wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\
wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\
@@ -830,7 +460,8 @@
]
"TARGET_THUMB1"
"add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*arm_adddi3"
@@ -858,7 +489,8 @@
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*adddi_sesidi_di"
@@ -887,7 +519,8 @@
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*adddi_zesidi_di"
@@ -914,7 +547,8 @@
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_expand "addsi3"
@@ -989,8 +623,8 @@
(set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no")
(set_attr "arch" "t2,t2,t2,t2,*,*,*,t2,t2,*,*,a,t2,t2,*")
(set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "arlo_imm")
- (const_string "arlo_reg")))
+ (const_string "alu_imm")
+ (const_string "alu_reg")))
]
)
@@ -1040,7 +674,9 @@
operands[3] = GEN_INT (offset);
operands[2] = GEN_INT (INTVAL (operands[2]) - offset);
}
- [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")]
+ [(set_attr "length" "2,2,2,2,2,2,2,4,4,4")
+ (set_attr "type" "alus_imm,alus_imm,alus_reg,alus_reg,alus_reg,
+ alus_reg,alus_reg,multiple,multiple,multiple")]
)
;; Reloading and elimination of the frame pointer can
@@ -1071,7 +707,7 @@
sub%.\\t%0, %1, #%n2
add%.\\t%0, %1, %2"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,arlo_imm,*")]
+ (set_attr "type" "alus_imm,alus_imm,alus_reg")]
)
(define_insn "*addsi3_compare0_scratch"
@@ -1087,8 +723,7 @@
cmn%?\\t%0, %1"
[(set_attr "conds" "set")
(set_attr "predicable" "yes")
- (set_attr "type" "arlo_imm,arlo_imm,*")
- ]
+ (set_attr "type" "alus_imm,alus_imm,alus_reg")]
)
(define_insn "*compare_negsi_si"
@@ -1102,7 +737,8 @@
(set_attr "predicable" "yes")
(set_attr "arch" "t2,*")
(set_attr "length" "2,4")
- (set_attr "predicable_short_it" "yes,no")]
+ (set_attr "predicable_short_it" "yes,no")
+ (set_attr "type" "alus_reg")]
)
;; This is the canonicalization of addsi3_compare0_for_combiner when the
@@ -1119,7 +755,8 @@
"@
add%.\\t%0, %1, %3
sub%.\\t%0, %1, #%n3"
- [(set_attr "conds" "set")]
+ [(set_attr "conds" "set")
+ (set_attr "type" "alus_reg")]
)
;; Convert the sequence
@@ -1177,7 +814,7 @@
sub%.\\t%0, %1, #%n2
add%.\\t%0, %1, %2"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,arlo_imm,*")]
+ (set_attr "type" "alus_imm,alus_imm,alus_reg")]
)
(define_insn "*addsi3_compare_op2"
@@ -1194,7 +831,7 @@
add%.\\t%0, %1, %2
sub%.\\t%0, %1, #%n2"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,arlo_imm,*")]
+ (set_attr "type" "alus_imm,alus_imm,alus_reg")]
)
(define_insn "*compare_addsi2_op0"
@@ -1215,7 +852,7 @@
(set_attr "arch" "t2,t2,*,*,*")
(set_attr "predicable_short_it" "yes,yes,no,no,no")
(set_attr "length" "2,2,4,4,4")
- (set_attr "type" "arlo_imm,*,arlo_imm,arlo_imm,*")]
+ (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
)
(define_insn "*compare_addsi2_op1"
@@ -1236,8 +873,7 @@
(set_attr "arch" "t2,t2,*,*,*")
(set_attr "predicable_short_it" "yes,yes,no,no,no")
(set_attr "length" "2,2,4,4,4")
- (set_attr "type"
- "arlo_imm,*,arlo_imm,arlo_imm,*")]
+ (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_imm,alus_reg")]
)
(define_insn "*addsi3_carryin_<optab>"
@@ -1254,7 +890,8 @@
(set_attr "predicable" "yes")
(set_attr "arch" "t2,*,*")
(set_attr "length" "4")
- (set_attr "predicable_short_it" "yes,no,no")]
+ (set_attr "predicable_short_it" "yes,no,no")
+ (set_attr "type" "adc_reg,adc_reg,adc_imm")]
)
(define_insn "*addsi3_carryin_alt2_<optab>"
@@ -1271,7 +908,8 @@
(set_attr "predicable" "yes")
(set_attr "arch" "t2,*,*")
(set_attr "length" "4")
- (set_attr "predicable_short_it" "yes,no,no")]
+ (set_attr "predicable_short_it" "yes,no,no")
+ (set_attr "type" "adc_reg,adc_reg,adc_imm")]
)
(define_insn "*addsi3_carryin_shift_<optab>"
@@ -1288,8 +926,8 @@
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
- (const_string "arlo_shift")
- (const_string "arlo_shift_reg")))]
+ (const_string "alu_shift_imm")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*addsi3_carryin_clobercc_<optab>"
@@ -1300,7 +938,8 @@
(clobber (reg:CC CC_REGNUM))]
"TARGET_32BIT"
"adc%.\\t%0, %1, %2"
- [(set_attr "conds" "set")]
+ [(set_attr "conds" "set")
+ (set_attr "type" "adcs_reg")]
)
(define_insn "*subsi3_carryin"
@@ -1315,7 +954,8 @@
[(set_attr "conds" "use")
(set_attr "arch" "*,a")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "adc_reg,adc_imm")]
)
(define_insn "*subsi3_carryin_const"
@@ -1325,7 +965,8 @@
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
"TARGET_32BIT"
"sbc\\t%0, %1, #%B2"
- [(set_attr "conds" "use")]
+ [(set_attr "conds" "use")
+ (set_attr "type" "adc_imm")]
)
(define_insn "*subsi3_carryin_compare"
@@ -1338,7 +979,8 @@
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
"TARGET_32BIT"
"sbcs\\t%0, %1, %2"
- [(set_attr "conds" "set")]
+ [(set_attr "conds" "set")
+ (set_attr "type" "adcs_reg")]
)
(define_insn "*subsi3_carryin_compare_const"
@@ -1351,7 +993,8 @@
(ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
"TARGET_32BIT"
"sbcs\\t%0, %1, #%B2"
- [(set_attr "conds" "set")]
+ [(set_attr "conds" "set")
+ (set_attr "type" "adcs_imm")]
)
(define_insn "*subsi3_carryin_shift"
@@ -1367,8 +1010,8 @@
[(set_attr "conds" "use")
(set_attr "predicable" "yes")
(set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
- (const_string "arlo_shift")
- (const_string "arlo_shift_reg")))]
+ (const_string "alu_shift_imm")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*rsbsi3_carryin_shift"
@@ -1384,8 +1027,8 @@
[(set_attr "conds" "use")
(set_attr "predicable" "yes")
(set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "")
- (const_string "arlo_shift")
- (const_string "arlo_shift_reg")))]
+ (const_string "alu_shift_imm")
+ (const_string "alu_shift_reg")))]
)
; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant.
@@ -1458,7 +1101,8 @@
operands[2] = gen_lowpart (SImode, operands[2]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb_subdi3"
@@ -1468,7 +1112,8 @@
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB1"
"sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*subdi_di_zesidi"
@@ -1493,7 +1138,8 @@
operands[5] = GEN_INT (~0);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*subdi_di_sesidi"
@@ -1519,7 +1165,8 @@
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*subdi_zesidi_di"
@@ -1545,7 +1192,8 @@
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*subdi_sesidi_di"
@@ -1574,7 +1222,8 @@
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*subdi_zesidi_zesidi"
@@ -1597,7 +1246,8 @@
operands[0] = gen_lowpart (SImode, operands[0]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_expand "subsi3"
@@ -1628,7 +1278,9 @@
"TARGET_THUMB1"
"sub\\t%0, %1, %2"
[(set_attr "length" "2")
- (set_attr "conds" "set")])
+ (set_attr "conds" "set")
+ (set_attr "type" "alus_reg")]
+)
; ??? Check Thumb-2 split length
(define_insn_and_split "*arm_subsi3_insn"
@@ -1658,7 +1310,7 @@
(set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no")
- (set_attr "type" "*,*,*,*,arlo_imm,arlo_imm,*,*,arlo_imm")]
+ (set_attr "type" "alu_reg,alu_reg,alu_reg,alu_reg,alu_imm,alu_imm,alu_reg,alu_reg,multiple")]
)
(define_peephole2
@@ -1688,7 +1340,7 @@
sub%.\\t%0, %1, %2
rsb%.\\t%0, %2, %1"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,*,*")]
+ (set_attr "type" "alus_imm,alus_reg,alus_reg")]
)
(define_insn "subsi3_compare"
@@ -1703,7 +1355,7 @@
sub%.\\t%0, %1, %2
rsb%.\\t%0, %2, %1"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,*,*")]
+ (set_attr "type" "alus_imm,alus_reg,alus_reg")]
)
(define_expand "subsf3"
@@ -1725,6 +1377,20 @@
;; Multiplication insns
+(define_expand "mulhi3"
+ [(set (match_operand:HI 0 "s_register_operand" "")
+ (mult:HI (match_operand:HI 1 "s_register_operand" "")
+ (match_operand:HI 2 "s_register_operand" "")))]
+ "TARGET_DSP_MULTIPLY"
+ "
+ {
+ rtx result = gen_reg_rtx (SImode);
+ emit_insn (gen_mulhisi3 (result, operands[1], operands[2]));
+ emit_move_insn (operands[0], gen_lowpart (HImode, result));
+ DONE;
+ }"
+)
+
(define_expand "mulsi3"
[(set (match_operand:SI 0 "s_register_operand" "")
(mult:SI (match_operand:SI 2 "s_register_operand" "")
@@ -2496,7 +2162,7 @@
gen_highpart_mode (SImode, DImode, operands[2]));
}"
- [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,*,*,neon_int_1,neon_int_1")
+ [(set_attr "type" "neon_int_1,neon_int_1,multiple,multiple,multiple,multiple,neon_int_1,neon_int_1")
(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,
avoid_neon_for_64bits,avoid_neon_for_64bits")
(set_attr "length" "*,*,8,8,8,8,*,*")
@@ -2521,7 +2187,8 @@
operands[0] = gen_lowpart (SImode, operands[0]);
operands[1] = gen_lowpart (SImode, operands[1]);
}"
- [(set_attr "length" "8")]
+ [(set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn "*anddi_sesdi_di"
@@ -2531,7 +2198,8 @@
(match_operand:DI 1 "s_register_operand" "0,r")))]
"TARGET_32BIT"
"#"
- [(set_attr "length" "8")]
+ [(set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_expand "andsi3"
@@ -2638,8 +2306,7 @@
[(set_attr "length" "4,4,4,4,16")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no,yes,no,no,no")
- (set_attr "type"
- "arlo_imm,arlo_imm,*,*,arlo_imm")]
+ (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")]
)
(define_insn "*thumb1_andsi3_insn"
@@ -2649,7 +2316,7 @@
"TARGET_THUMB1"
"and\\t%0, %2"
[(set_attr "length" "2")
- (set_attr "type" "arlo_imm")
+ (set_attr "type" "logic_imm")
(set_attr "conds" "set")])
(define_insn "*andsi3_compare0"
@@ -2666,7 +2333,7 @@
bic%.\\t%0, %1, #%B2
and%.\\t%0, %1, %2"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,arlo_imm,*")]
+ (set_attr "type" "logics_imm,logics_imm,logics_reg")]
)
(define_insn "*andsi3_compare0_scratch"
@@ -2682,7 +2349,7 @@
bic%.\\t%2, %0, #%B1
tst%?\\t%0, %1"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,arlo_imm,*")]
+ (set_attr "type" "logics_imm,logics_imm,logics_reg")]
)
(define_insn "*zeroextractsi_compare0_scratch"
@@ -2706,7 +2373,7 @@
[(set_attr "conds" "set")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "arlo_imm")]
+ (set_attr "type" "logics_imm")]
)
(define_insn_and_split "*ne_zeroextractsi"
@@ -2743,7 +2410,8 @@
(set (attr "length")
(if_then_else (eq_attr "is_thumb" "yes")
(const_int 12)
- (const_int 8)))]
+ (const_int 8)))
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*ne_zeroextractsi_shifted"
@@ -2768,7 +2436,8 @@
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
"
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*ite_ne_zeroextractsi"
@@ -2806,7 +2475,8 @@
<< INTVAL (operands[3]));
"
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*ite_ne_zeroextractsi_shifted"
@@ -2833,7 +2503,8 @@
operands[2] = GEN_INT (32 - INTVAL (operands[2]));
"
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_split
@@ -3134,7 +2805,8 @@
"bfc%?\t%0, %2, %1"
[(set_attr "length" "4")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "bfm")]
)
(define_insn "insv_t2"
@@ -3146,7 +2818,8 @@
"bfi%?\t%0, %3, %2, %1"
[(set_attr "length" "4")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "bfm")]
)
; constants for op 2 will never be given to these patterns.
@@ -3171,7 +2844,8 @@
operands[2] = gen_lowpart (SImode, operands[2]);
}"
[(set_attr "length" "8")
- (set_attr "predicable" "yes")]
+ (set_attr "predicable" "yes")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*anddi_notzesidi_di"
@@ -3199,7 +2873,8 @@
}"
[(set_attr "length" "4,8")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*anddi_notsesidi_di"
@@ -3223,7 +2898,8 @@
}"
[(set_attr "length" "8")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "multiple")]
)
(define_insn "andsi_notsi_si"
@@ -3233,7 +2909,8 @@
"TARGET_32BIT"
"bic%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "logic_reg")]
)
(define_insn "thumb1_bicsi3"
@@ -3243,7 +2920,9 @@
"TARGET_THUMB1"
"bic\\t%0, %1"
[(set_attr "length" "2")
- (set_attr "conds" "set")])
+ (set_attr "conds" "set")
+ (set_attr "type" "logics_reg")]
+)
(define_insn "andsi_not_shiftsi_si"
[(set (match_operand:SI 0 "s_register_operand" "=r")
@@ -3256,8 +2935,8 @@
[(set_attr "predicable" "yes")
(set_attr "shift" "2")
(set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "arlo_shift")
- (const_string "arlo_shift_reg")))]
+ (const_string "logic_shift_imm")
+ (const_string "logic_shift_reg")))]
)
(define_insn "*andsi_notsi_si_compare0"
@@ -3270,7 +2949,8 @@
(and:SI (not:SI (match_dup 2)) (match_dup 1)))]
"TARGET_32BIT"
"bic%.\\t%0, %1, %2"
- [(set_attr "conds" "set")]
+ [(set_attr "conds" "set")
+ (set_attr "type" "logics_shift_reg")]
)
(define_insn "*andsi_notsi_si_compare0_scratch"
@@ -3282,7 +2962,8 @@
(clobber (match_scratch:SI 0 "=r"))]
"TARGET_32BIT"
"bic%.\\t%0, %1, %2"
- [(set_attr "conds" "set")]
+ [(set_attr "conds" "set")
+ (set_attr "type" "logics_shift_reg")]
)
(define_expand "iordi3"
@@ -3331,7 +3012,7 @@
gen_highpart_mode (SImode, DImode, operands[2]));
}"
- [(set_attr "neon_type" "neon_int_1,neon_int_1,*,*,*,*,neon_int_1,neon_int_1")
+ [(set_attr "type" "neon_int_1,neon_int_1,multiple,multiple,multiple,multiple,neon_int_1,neon_int_1")
(set_attr "length" "*,*,8,8,8,8,*,*")
(set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")]
)
@@ -3347,7 +3028,8 @@
#"
[(set_attr "length" "4,8")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "logic_reg,multiple")]
)
(define_insn "*iordi_sesidi_di"
@@ -3358,7 +3040,8 @@
"TARGET_32BIT"
"#"
[(set_attr "length" "8")
- (set_attr "predicable" "yes")]
+ (set_attr "predicable" "yes")
+ (set_attr "type" "multiple")]
)
(define_expand "iorsi3"
@@ -3416,7 +3099,7 @@
(set_attr "arch" "32,t2,t2,32,32")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no,yes,no,no,no")
- (set_attr "type" "arlo_imm,*,arlo_imm,*,*")]
+ (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")]
)
(define_insn "*thumb1_iorsi3_insn"
@@ -3426,7 +3109,8 @@
"TARGET_THUMB1"
"orr\\t%0, %2"
[(set_attr "length" "2")
- (set_attr "conds" "set")])
+ (set_attr "conds" "set")
+ (set_attr "type" "logics_reg")])
(define_peephole2
[(match_scratch:SI 3 "r")
@@ -3451,7 +3135,7 @@
"TARGET_32BIT"
"orr%.\\t%0, %1, %2"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,*")]
+ (set_attr "type" "logics_imm,logics_reg")]
)
(define_insn "*iorsi3_compare0_scratch"
@@ -3463,7 +3147,7 @@
"TARGET_32BIT"
"orr%.\\t%0, %1, %2"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,*")]
+ (set_attr "type" "logics_imm,logics_reg")]
)
(define_expand "xordi3"
@@ -3510,7 +3194,7 @@
}"
[(set_attr "length" "*,8,8,8,8,*")
- (set_attr "neon_type" "neon_int_1,*,*,*,*,neon_int_1")
+ (set_attr "type" "neon_int_1,multiple,multiple,multiple,multiple,neon_int_1")
(set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")]
)
@@ -3525,7 +3209,8 @@
#"
[(set_attr "length" "4,8")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "logic_reg")]
)
(define_insn "*xordi_sesidi_di"
@@ -3536,7 +3221,8 @@
"TARGET_32BIT"
"#"
[(set_attr "length" "8")
- (set_attr "predicable" "yes")]
+ (set_attr "predicable" "yes")
+ (set_attr "type" "multiple")]
)
(define_expand "xorsi3"
@@ -3589,7 +3275,7 @@
[(set_attr "length" "4,4,4,16")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no,yes,no,no")
- (set_attr "type" "arlo_imm,*,*,*")]
+ (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")]
)
(define_insn "*thumb1_xorsi3_insn"
@@ -3600,7 +3286,7 @@
"eor\\t%0, %2"
[(set_attr "length" "2")
(set_attr "conds" "set")
- (set_attr "type" "arlo_imm")]
+ (set_attr "type" "logics_reg")]
)
(define_insn "*xorsi3_compare0"
@@ -3613,7 +3299,7 @@
"TARGET_32BIT"
"eor%.\\t%0, %1, %2"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,*")]
+ (set_attr "type" "logics_imm,logics_reg")]
)
(define_insn "*xorsi3_compare0_scratch"
@@ -3624,7 +3310,7 @@
"TARGET_32BIT"
"teq%?\\t%0, %1"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,*")]
+ (set_attr "type" "logics_imm,logics_reg")]
)
; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C),
@@ -3658,7 +3344,8 @@
[(set_attr "length" "8")
(set_attr "ce_count" "2")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "multiple")]
)
; ??? Are these four splitters still beneficial when the Thumb-2 bitfield
@@ -3795,7 +3482,8 @@
"TARGET_32BIT"
"bic%?\\t%0, %1, %1, asr #31"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "logic_shift_reg")]
)
(define_insn "*smax_m1"
@@ -3805,7 +3493,8 @@
"TARGET_32BIT"
"orr%?\\t%0, %1, %1, asr #31"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "logic_shift_reg")]
)
(define_insn_and_split "*arm_smax_insn"
@@ -3826,7 +3515,8 @@
(match_dup 2)))]
""
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_expand "sminsi3"
@@ -3854,7 +3544,8 @@
"TARGET_32BIT"
"and%?\\t%0, %1, %1, asr #31"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "logic_shift_reg")]
)
(define_insn_and_split "*arm_smin_insn"
@@ -3875,7 +3566,8 @@
(match_dup 2)))]
""
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple,multiple")]
)
(define_expand "umaxsi3"
@@ -3907,7 +3599,8 @@
(match_dup 2)))]
""
[(set_attr "conds" "clob")
- (set_attr "length" "8,8,12")]
+ (set_attr "length" "8,8,12")
+ (set_attr "type" "store1")]
)
(define_expand "uminsi3"
@@ -3939,7 +3632,8 @@
(match_dup 2)))]
""
[(set_attr "conds" "clob")
- (set_attr "length" "8,8,12")]
+ (set_attr "length" "8,8,12")
+ (set_attr "type" "store1")]
)
(define_insn "*store_minmaxsi"
@@ -4008,7 +3702,8 @@
(set (attr "length")
(if_then_else (eq_attr "is_thumb" "yes")
(const_int 14)
- (const_int 12)))]
+ (const_int 12)))
+ (set_attr "type" "multiple")]
)
; Reject the frame pointer in operand[1], since reloading this after
@@ -4034,8 +3729,7 @@
(match_dup 2))))
(cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)])
(set (match_dup 0)
- (minus:SI (match_dup 1)
- (match_dup 3))))]
+ (match_dup 6)))]
{
enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]),
operands[2], operands[3]);
@@ -4048,12 +3742,17 @@
else
rc = reverse_condition (rc);
operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]);
+ if (CONST_INT_P (operands[3]))
+ operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3]));
+ else
+ operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]);
}
[(set_attr "conds" "clob")
(set (attr "length")
(if_then_else (eq_attr "is_thumb" "yes")
(const_int 14)
- (const_int 12)))]
+ (const_int 12)))
+ (set_attr "type" "multiple")]
)
(define_code_iterator SAT [smin smax])
@@ -4082,7 +3781,8 @@
return "usat%?\t%0, %1, %3";
}
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "alus_imm")]
)
(define_insn "*satsi_<SAT:code>_shift"
@@ -4110,7 +3810,7 @@
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "shift" "3")
- (set_attr "type" "arlo_shift")])
+ (set_attr "type" "logic_shift_reg")])
;; Shift and rotation insns
@@ -4188,7 +3888,8 @@
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_expand "ashlsi3"
@@ -4213,7 +3914,7 @@
"TARGET_THUMB1"
"lsl\\t%0, %1, %2"
[(set_attr "length" "2")
- (set_attr "type" "shift,shift_reg")
+ (set_attr "type" "shift_imm,shift_reg")
(set_attr "conds" "set")])
(define_expand "ashrdi3"
@@ -4285,7 +3986,8 @@
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn "*rrx"
@@ -4318,7 +4020,7 @@
"TARGET_THUMB1"
"asr\\t%0, %1, %2"
[(set_attr "length" "2")
- (set_attr "type" "shift,shift_reg")
+ (set_attr "type" "shift_imm,shift_reg")
(set_attr "conds" "set")])
(define_expand "lshrdi3"
@@ -4390,7 +4092,8 @@
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_expand "lshrsi3"
@@ -4415,7 +4118,7 @@
"TARGET_THUMB1"
"lsr\\t%0, %1, %2"
[(set_attr "length" "2")
- (set_attr "type" "shift,shift_reg")
+ (set_attr "type" "shift_imm,shift_reg")
(set_attr "conds" "set")])
(define_expand "rotlsi3"
@@ -4477,7 +4180,7 @@
(set_attr "predicable_short_it" "yes,no,no")
(set_attr "length" "4")
(set_attr "shift" "1")
- (set_attr "type" "arlo_shift_reg,arlo_shift,arlo_shift_reg")]
+ (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_reg")]
)
(define_insn "*shiftsi3_compare"
@@ -4492,7 +4195,7 @@
"* return arm_output_shift(operands, 1);"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- (set_attr "type" "arlo_shift,arlo_shift_reg")]
+ (set_attr "type" "alus_shift_imm,alus_shift_reg")]
)
(define_insn "*shiftsi3_compare0"
@@ -4507,7 +4210,7 @@
"* return arm_output_shift(operands, 1);"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- (set_attr "type" "arlo_shift,arlo_shift_reg")]
+ (set_attr "type" "alus_shift_imm,alus_shift_reg")]
)
(define_insn "*shiftsi3_compare0_scratch"
@@ -4521,7 +4224,7 @@
"* return arm_output_shift(operands, 1);"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- (set_attr "type" "shift,shift_reg")]
+ (set_attr "type" "shift_imm,shift_reg")]
)
(define_insn "*not_shiftsi"
@@ -4863,7 +4566,8 @@
"sbfx%?\t%0, %1, %3, %2"
[(set_attr "length" "4")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "bfm")]
)
(define_insn "extzv_t2"
@@ -4875,7 +4579,8 @@
"ubfx%?\t%0, %1, %3, %2"
[(set_attr "length" "4")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "bfm")]
)
@@ -4941,7 +4646,8 @@
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb1_negdi2"
@@ -4950,7 +4656,8 @@
(clobber (reg:CC CC_REGNUM))]
"TARGET_THUMB1"
"mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1"
- [(set_attr "length" "6")]
+ [(set_attr "length" "6")
+ (set_attr "type" "multiple")]
)
(define_expand "negsi2"
@@ -4968,7 +4675,8 @@
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "yes,no")
(set_attr "arch" "t2,*")
- (set_attr "length" "4")]
+ (set_attr "length" "4")
+ (set_attr "type" "alu_reg")]
)
(define_insn "*thumb1_negsi2"
@@ -4976,7 +4684,8 @@
(neg:SI (match_operand:SI 1 "register_operand" "l")))]
"TARGET_THUMB1"
"neg\\t%0, %1"
- [(set_attr "length" "2")]
+ [(set_attr "length" "2")
+ (set_attr "type" "alu_imm")]
)
(define_expand "negsf2"
@@ -5034,7 +4743,8 @@
DONE;
}
[(set_attr "length" "8,8,4,4")
- (set_attr "arch" "a,a,t2,t2")]
+ (set_attr "arch" "a,a,t2,t2")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*negdi_zero_extendsidi"
@@ -5056,7 +4766,8 @@
operands[0] = gen_lowpart (SImode, operands[0]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")] ;; length in thumb is 4
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")] ;; length in thumb is 4
)
;; abssi2 doesn't really clobber the condition codes if a different register
@@ -5141,7 +4852,8 @@
[(set_attr "conds" "clob,*")
(set_attr "shift" "1")
(set_attr "predicable" "no, yes")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb1_abssi2"
@@ -5155,7 +4867,8 @@
(set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
""
- [(set_attr "length" "6")]
+ [(set_attr "length" "6")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*arm_neg_abssi2"
@@ -5211,7 +4924,8 @@
[(set_attr "conds" "clob,*")
(set_attr "shift" "1")
(set_attr "predicable" "no, yes")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb1_neg_abssi2"
@@ -5225,7 +4939,8 @@
(set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))
(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 2)))]
""
- [(set_attr "length" "6")]
+ [(set_attr "length" "6")
+ (set_attr "type" "multiple")]
)
(define_expand "abssf2"
@@ -5274,7 +4989,7 @@
}"
[(set_attr "length" "*,8,8,*")
(set_attr "predicable" "no,yes,yes,no")
- (set_attr "neon_type" "neon_int_1,*,*,neon_int_1")
+ (set_attr "type" "neon_int_1,multiple,multiple,neon_int_1")
(set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")]
)
@@ -5461,7 +5176,8 @@
(set_attr "ce_count" "2")
(set_attr "shift" "1")
(set_attr "predicable" "yes")
- (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")]
+ (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits")
+ (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")]
)
;; Splits for all extensions to DImode
@@ -5597,7 +5313,7 @@
"@
#
ldr%(h%)\\t%0, %1"
- [(set_attr "type" "arlo_shift,load_byte")
+ [(set_attr "type" "alu_shift_reg,load_byte")
(set_attr "predicable" "yes")]
)
@@ -5618,7 +5334,7 @@
(match_operand:SI 2 "s_register_operand" "r")))]
"TARGET_INT_SIMD"
"uxtah%?\\t%0, %2, %1"
- [(set_attr "type" "arlo_shift")
+ [(set_attr "type" "alu_shift_reg")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")]
)
@@ -5668,7 +5384,7 @@
#
ldrb\\t%0, %1"
[(set_attr "length" "4,2")
- (set_attr "type" "arlo_shift,load_byte")
+ (set_attr "type" "alu_shift_reg,load_byte")
(set_attr "pool_range" "*,32")]
)
@@ -5691,7 +5407,7 @@
#
ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
[(set_attr "length" "8,4")
- (set_attr "type" "arlo_shift,load_byte")
+ (set_attr "type" "alu_shift_reg,load_byte")
(set_attr "predicable" "yes")]
)
@@ -5714,7 +5430,7 @@
"uxtab%?\\t%0, %2, %1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "arlo_shift")]
+ (set_attr "type" "alu_shift_reg")]
)
(define_split
@@ -5766,7 +5482,8 @@
"tst%?\\t%0, #255"
[(set_attr "conds" "set")
(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "logic_imm")]
)
(define_expand "extendhisi2"
@@ -5936,7 +5653,7 @@
#
ldr%(sh%)\\t%0, %1"
[(set_attr "length" "8,4")
- (set_attr "type" "arlo_shift,load_byte")
+ (set_attr "type" "alu_shift_reg,load_byte")
(set_attr "predicable" "yes")
(set_attr "pool_range" "*,256")
(set_attr "neg_pool_range" "*,244")]
@@ -5963,6 +5680,7 @@
(match_operand:SI 2 "s_register_operand" "r")))]
"TARGET_INT_SIMD"
"sxtah%?\\t%0, %2, %1"
+ [(set_attr "type" "alu_shift_reg")]
)
(define_expand "extendqihi2"
@@ -6037,7 +5755,7 @@
#
ldr%(sb%)\\t%0, %1"
[(set_attr "length" "8,4")
- (set_attr "type" "arlo_shift,load_byte")
+ (set_attr "type" "alu_shift_reg,load_byte")
(set_attr "predicable" "yes")
(set_attr "pool_range" "*,256")
(set_attr "neg_pool_range" "*,244")]
@@ -6063,7 +5781,7 @@
(match_operand:SI 2 "s_register_operand" "r")))]
"TARGET_INT_SIMD"
"sxtab%?\\t%0, %2, %1"
- [(set_attr "type" "arlo_shift")
+ [(set_attr "type" "alu_shift_reg")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")]
)
@@ -6283,7 +6001,7 @@
}
"
[(set_attr "length" "8,12,16,8,8")
- (set_attr "type" "*,*,*,load2,store2")
+ (set_attr "type" "multiple,multiple,multiple,load2,store2")
(set_attr "arm_pool_range" "*,*,*,1020,*")
(set_attr "arm_neg_pool_range" "*,*,*,1004,*")
(set_attr "thumb2_pool_range" "*,*,*,4094,*")
@@ -6423,7 +6141,7 @@
}
}"
[(set_attr "length" "4,4,6,2,2,6,4,4")
- (set_attr "type" "*,mov_reg,*,load2,store2,load2,store2,mov_reg")
+ (set_attr "type" "multiple,multiple,multiple,load2,store2,load2,store2,multiple")
(set_attr "pool_range" "*,*,*,*,*,1018,*,*")]
)
@@ -6521,7 +6239,8 @@
"movt%?\t%0, #:upper16:%c2"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "length" "4")]
+ (set_attr "length" "4")
+ (set_attr "type" "mov_imm")]
)
(define_insn "*arm_movsi_insn"
@@ -6593,7 +6312,7 @@
str\\t%1, %0
mov\\t%0, %1"
[(set_attr "length" "2,2,4,4,2,2,2,2,2")
- (set_attr "type" "*,*,*,*,load1,store1,load1,store1,*")
+ (set_attr "type" "mov_reg,mov_imm,multiple,multiple,load1,store1,load1,store1,mov_reg")
(set_attr "pool_range" "*,*,*,*,*,*,1018,*,*")
(set_attr "conds" "set,clob,*,*,nocond,nocond,nocond,nocond,nocond")])
@@ -6749,7 +6468,8 @@
INTVAL (operands[2]));
return \"add\\t%0, %|pc\";
"
- [(set_attr "length" "2")]
+ [(set_attr "length" "2")
+ (set_attr "type" "alu_reg")]
)
(define_insn "pic_add_dot_plus_eight"
@@ -6764,7 +6484,8 @@
INTVAL (operands[2]));
return \"add%?\\t%0, %|pc, %1\";
"
- [(set_attr "predicable" "yes")]
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "alu_reg")]
)
(define_insn "tls_load_dot_plus_eight"
@@ -6779,7 +6500,8 @@
INTVAL (operands[2]));
return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\";
"
- [(set_attr "predicable" "yes")]
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "load1")]
)
;; PIC references to local variables can generate pic_add_dot_plus_eight
@@ -6840,7 +6562,7 @@
cmp%?\\t%0, #0
sub%.\\t%0, %1, #0"
[(set_attr "conds" "set")
- (set_attr "type" "arlo_imm,arlo_imm")]
+ (set_attr "type" "alus_imm,alus_imm")]
)
;; Subroutine to store a half word from a register into memory.
@@ -7186,7 +6908,7 @@
return \"ldrh %0, %1\";
}"
[(set_attr "length" "2,4,2,2,2,2")
- (set_attr "type" "*,load1,store1,*,*,*")
+ (set_attr "type" "alus_imm,load1,store1,mov_reg,mov_reg,mov_imm")
(set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
@@ -7434,7 +7156,7 @@
mov\\t%0, %1
mov\\t%0, %1"
[(set_attr "length" "2")
- (set_attr "type" "arlo_imm,load1,store1,mov_reg,mov_imm,mov_imm")
+ (set_attr "type" "alu_imm,load1,store1,mov_reg,mov_imm,mov_imm")
(set_attr "pool_range" "*,32,*,*,*,*")
(set_attr "conds" "clob,nocond,nocond,nocond,nocond,clob")])
@@ -7499,7 +7221,7 @@
}
"
[(set_attr "conds" "unconditional")
- (set_attr "type" "load1,store1,mov_reg,mov_reg")
+ (set_attr "type" "load1,store1,mov_reg,multiple")
(set_attr "length" "4,4,4,8")
(set_attr "predicable" "yes")]
)
@@ -7612,7 +7334,7 @@
mov\\t%0, %1
mov\\t%0, %1"
[(set_attr "length" "2")
- (set_attr "type" "*,load1,store1,load1,store1,mov_reg,mov_reg")
+ (set_attr "type" "alus_imm,load1,store1,load1,store1,mov_reg,mov_reg")
(set_attr "pool_range" "*,*,*,1018,*,*,*")
(set_attr "conds" "clob,nocond,nocond,nocond,nocond,nocond,nocond")]
)
@@ -7700,7 +7422,7 @@
}
"
[(set_attr "length" "8,12,16,8,8")
- (set_attr "type" "*,*,*,load2,store2")
+ (set_attr "type" "multiple,multiple,multiple,load2,store2")
(set_attr "arm_pool_range" "*,*,*,1020,*")
(set_attr "thumb2_pool_range" "*,*,*,1018,*")
(set_attr "arm_neg_pool_range" "*,*,*,1004,*")
@@ -7744,7 +7466,7 @@
}
"
[(set_attr "length" "4,2,2,6,4,4")
- (set_attr "type" "*,load2,store2,load2,store2,mov_reg")
+ (set_attr "type" "multiple,load2,store2,load2,store2,multiple")
(set_attr "pool_range" "*,*,*,1018,*,*")]
)
@@ -8052,7 +7774,8 @@
(and (ge (minus (match_dup 3) (pc)) (const_int -2040))
(le (minus (match_dup 3) (pc)) (const_int 2048)))
(const_int 6)
- (const_int 8))))]
+ (const_int 8))))
+ (set_attr "type" "multiple")]
)
(define_insn "cbranchsi4_scratch"
@@ -8088,7 +7811,8 @@
(and (ge (minus (match_dup 3) (pc)) (const_int -2040))
(le (minus (match_dup 3) (pc)) (const_int 2048)))
(const_int 6)
- (const_int 8))))]
+ (const_int 8))))
+ (set_attr "type" "multiple")]
)
(define_insn "*negated_cbranchsi4"
@@ -8123,7 +7847,8 @@
(and (ge (minus (match_dup 3) (pc)) (const_int -2040))
(le (minus (match_dup 3) (pc)) (const_int 2048)))
(const_int 6)
- (const_int 8))))]
+ (const_int 8))))
+ (set_attr "type" "multiple")]
)
(define_insn "*tbit_cbranch"
@@ -8167,7 +7892,8 @@
(and (ge (minus (match_dup 3) (pc)) (const_int -2040))
(le (minus (match_dup 3) (pc)) (const_int 2048)))
(const_int 6)
- (const_int 8))))]
+ (const_int 8))))
+ (set_attr "type" "multiple")]
)
(define_insn "*tlobits_cbranch"
@@ -8211,7 +7937,8 @@
(and (ge (minus (match_dup 3) (pc)) (const_int -2040))
(le (minus (match_dup 3) (pc)) (const_int 2048)))
(const_int 6)
- (const_int 8))))]
+ (const_int 8))))
+ (set_attr "type" "multiple")]
)
(define_insn "*tstsi3_cbranch"
@@ -8248,7 +7975,8 @@
(and (ge (minus (match_dup 2) (pc)) (const_int -2040))
(le (minus (match_dup 2) (pc)) (const_int 2048)))
(const_int 6)
- (const_int 8))))]
+ (const_int 8))))
+ (set_attr "type" "multiple")]
)
(define_insn "*cbranchne_decr1"
@@ -8351,7 +8079,8 @@
(and (ge (minus (match_dup 4) (pc)) (const_int -2038))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 8)
- (const_int 10)))])]
+ (const_int 10)))])
+ (set_attr "type" "multiple")]
)
(define_insn "*addsi3_cbranch"
@@ -8432,7 +8161,8 @@
(and (ge (minus (match_dup 5) (pc)) (const_int -2038))
(le (minus (match_dup 5) (pc)) (const_int 2048)))
(const_int 8)
- (const_int 10)))))]
+ (const_int 10)))))
+ (set_attr "type" "multiple")]
)
(define_insn "*addsi3_cbranch_scratch"
@@ -8500,7 +8230,8 @@
(and (ge (minus (match_dup 4) (pc)) (const_int -2040))
(le (minus (match_dup 4) (pc)) (const_int 2048)))
(const_int 6)
- (const_int 8))))]
+ (const_int 8))))
+ (set_attr "type" "multiple")]
)
@@ -8520,34 +8251,34 @@
(set_attr "arch" "t2,t2,any,any")
(set_attr "length" "2,2,4,4")
(set_attr "predicable" "yes")
- (set_attr "type" "*,*,*,arlo_imm")]
+ (set_attr "type" "alus_reg,alus_reg,alus_reg,alus_imm")]
)
(define_insn "*cmpsi_shiftsi"
[(set (reg:CC CC_REGNUM)
- (compare:CC (match_operand:SI 0 "s_register_operand" "r,r")
+ (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r")
(match_operator:SI 3 "shift_operator"
- [(match_operand:SI 1 "s_register_operand" "r,r")
- (match_operand:SI 2 "shift_amount_operand" "M,rM")])))]
+ [(match_operand:SI 1 "s_register_operand" "r,r,r")
+ (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))]
"TARGET_32BIT"
"cmp%?\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- (set_attr "arch" "32,a")
- (set_attr "type" "arlo_shift,arlo_shift_reg")])
+ (set_attr "arch" "32,a,a")
+ (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
(define_insn "*cmpsi_shiftsi_swp"
[(set (reg:CC_SWP CC_REGNUM)
(compare:CC_SWP (match_operator:SI 3 "shift_operator"
- [(match_operand:SI 1 "s_register_operand" "r,r")
- (match_operand:SI 2 "shift_amount_operand" "M,rM")])
- (match_operand:SI 0 "s_register_operand" "r,r")))]
+ [(match_operand:SI 1 "s_register_operand" "r,r,r")
+ (match_operand:SI 2 "shift_amount_operand" "M,r,M")])
+ (match_operand:SI 0 "s_register_operand" "r,r,r")))]
"TARGET_32BIT"
"cmp%?\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- (set_attr "arch" "32,a")
- (set_attr "type" "arlo_shift,arlo_shift_reg")])
+ (set_attr "arch" "32,a,a")
+ (set_attr "type" "alus_shift_imm,alu_shift_reg,alus_shift_imm")])
(define_insn "*arm_cmpsi_negshiftsi_si"
[(set (reg:CC_Z CC_REGNUM)
@@ -8560,8 +8291,8 @@
"cmn%?\\t%0, %2%S1"
[(set_attr "conds" "set")
(set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "arlo_shift")
- (const_string "arlo_shift_reg")))
+ (const_string "alus_shift_imm")
+ (const_string "alus_shift_reg")))
(set_attr "predicable" "yes")]
)
@@ -8603,7 +8334,8 @@
operands[2] = gen_lowpart (SImode, operands[2]);
}
[(set_attr "conds" "set")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*arm_cmpdi_unsigned"
@@ -8631,7 +8363,8 @@
[(set_attr "conds" "set")
(set_attr "enabled_for_depr_it" "yes,yes,no")
(set_attr "arch" "t2,t2,*")
- (set_attr "length" "6,6,8")]
+ (set_attr "length" "6,6,8")
+ (set_attr "type" "multiple")]
)
(define_insn "*arm_cmpdi_zero"
@@ -8641,7 +8374,8 @@
(clobber (match_scratch:SI 1 "=r"))]
"TARGET_32BIT"
"orr%.\\t%1, %Q0, %R0"
- [(set_attr "conds" "set")]
+ [(set_attr "conds" "set")
+ (set_attr "type" "logics_reg")]
)
(define_insn "*thumb_cmpdi_zero"
@@ -8652,7 +8386,8 @@
"TARGET_THUMB1"
"orr\\t%1, %Q0, %R0"
[(set_attr "conds" "set")
- (set_attr "length" "2")]
+ (set_attr "length" "2")
+ (set_attr "type" "logics_reg")]
)
; This insn allows redundant compares to be removed by cse, nothing should
@@ -8666,7 +8401,8 @@
"TARGET_32BIT"
"\\t%@ deleted compare"
[(set_attr "conds" "set")
- (set_attr "length" "0")]
+ (set_attr "length" "0")
+ (set_attr "type" "no_insn")]
)
@@ -8767,7 +8503,8 @@
(const_int 0)))]
""
[(set_attr "conds" "use")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*mov_negscc"
@@ -8785,7 +8522,8 @@
operands[3] = GEN_INT (~0);
}
[(set_attr "conds" "use")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*mov_notscc"
@@ -8804,7 +8542,8 @@
operands[4] = GEN_INT (~0);
}
[(set_attr "conds" "use")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_expand "cstoresi4"
@@ -9009,7 +8748,8 @@
"@
neg\\t%0, %1\;adc\\t%0, %0, %1
neg\\t%2, %1\;adc\\t%0, %1, %2"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "multiple")]
)
(define_insn "*cstoresi_ne0_thumb1_insn"
@@ -9029,7 +8769,8 @@
(match_operand:SI 2 "thumb1_cmp_operand" "lI*h,*r"))))]
"TARGET_THUMB1"
"cmp\\t%1, %2\;sbc\\t%0, %0, %0"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "cstoresi_ltu_thumb1"
@@ -9043,7 +8784,8 @@
(neg:SI (ltu:SI (match_dup 1) (match_dup 2))))
(set (match_dup 0) (neg:SI (match_dup 3)))]
"operands[3] = gen_reg_rtx (SImode);"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "multiple")]
)
;; Used as part of the expansion of thumb les sequence.
@@ -9055,7 +8797,8 @@
(match_operand:SI 4 "thumb1_cmp_operand" "lI"))))]
"TARGET_THUMB1"
"cmp\\t%3, %4\;adc\\t%0, %1, %2"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "multiple")]
)
@@ -9273,7 +9016,8 @@
(and (ge (minus (match_dup 0) (pc)) (const_int -2044))
(le (minus (match_dup 0) (pc)) (const_int 2048))))
(const_int 2)
- (const_int 4)))]
+ (const_int 4)))
+ (set_attr "type" "branch")]
)
(define_insn "*thumb_jump"
@@ -9295,7 +9039,8 @@
(and (ge (minus (match_dup 0) (pc)) (const_int -2044))
(le (minus (match_dup 0) (pc)) (const_int 2048)))
(const_int 2)
- (const_int 4)))]
+ (const_int 4)))
+ (set_attr "type" "branch")]
)
(define_expand "call"
@@ -9779,7 +9524,8 @@
"TARGET_ARM"
"teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc"
[(set_attr "length" "8")
- (set_attr "conds" "set")]
+ (set_attr "conds" "set")
+ (set_attr "type" "multiple")]
)
;; Call subroutine returning any type.
@@ -9970,7 +9716,8 @@
return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
(define_expand "thumb1_casesi_internal_pic"
@@ -10001,7 +9748,8 @@
(clobber (reg:SI LR_REGNUM))])]
"TARGET_THUMB1"
"* return thumb1_output_casesi(operands);"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "multiple")]
)
(define_expand "indirect_jump"
@@ -10027,7 +9775,8 @@
(match_operand:SI 0 "s_register_operand" "r"))]
"TARGET_ARM"
"mov%?\\t%|pc, %0\\t%@ indirect register jump"
- [(set_attr "predicable" "yes")]
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "branch")]
)
(define_insn "*load_indirect_jump"
@@ -10048,7 +9797,8 @@
"TARGET_THUMB1"
"mov\\tpc, %0"
[(set_attr "conds" "clob")
- (set_attr "length" "2")]
+ (set_attr "length" "2")
+ (set_attr "type" "branch")]
)
@@ -10067,7 +9817,8 @@
[(set (attr "length")
(if_then_else (eq_attr "is_thumb" "yes")
(const_int 2)
- (const_int 4)))]
+ (const_int 4)))
+ (set_attr "type" "mov_reg")]
)
@@ -10103,7 +9854,7 @@
(if_then_else
(match_operand:SI 3 "mult_operator" "")
(const_string "no") (const_string "yes"))])
- (set_attr "type" "arlo_shift,arlo_shift,arlo_shift,arlo_shift_reg")])
+ (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_imm,alu_shift_reg")])
(define_split
[(set (match_operand:SI 0 "s_register_operand" "")
@@ -10140,7 +9891,7 @@
[(set_attr "conds" "set")
(set_attr "shift" "4")
(set_attr "arch" "32,a")
- (set_attr "type" "arlo_shift,arlo_shift_reg")])
+ (set_attr "type" "alus_shift_imm,alus_shift_reg")])
(define_insn "*arith_shiftsi_compare0_scratch"
[(set (reg:CC_NOOV CC_REGNUM)
@@ -10157,7 +9908,7 @@
[(set_attr "conds" "set")
(set_attr "shift" "4")
(set_attr "arch" "32,a")
- (set_attr "type" "arlo_shift,arlo_shift_reg")])
+ (set_attr "type" "alus_shift_imm,alus_shift_reg")])
(define_insn "*sub_shiftsi"
[(set (match_operand:SI 0 "s_register_operand" "=r,r")
@@ -10170,41 +9921,41 @@
[(set_attr "predicable" "yes")
(set_attr "shift" "3")
(set_attr "arch" "32,a")
- (set_attr "type" "arlo_shift,arlo_shift_reg")])
+ (set_attr "type" "alus_shift_imm,alus_shift_reg")])
(define_insn "*sub_shiftsi_compare0"
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV
- (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
+ (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
(match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r,r")
- (match_operand:SI 4 "shift_amount_operand" "M,rM")]))
+ [(match_operand:SI 3 "s_register_operand" "r,r,r")
+ (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
(const_int 0)))
- (set (match_operand:SI 0 "s_register_operand" "=r,r")
+ (set (match_operand:SI 0 "s_register_operand" "=r,r,r")
(minus:SI (match_dup 1)
(match_op_dup 2 [(match_dup 3) (match_dup 4)])))]
"TARGET_32BIT"
"sub%.\\t%0, %1, %3%S2"
[(set_attr "conds" "set")
(set_attr "shift" "3")
- (set_attr "arch" "32,a")
- (set_attr "type" "arlo_shift,arlo_shift_reg")])
+ (set_attr "arch" "32,a,a")
+ (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
(define_insn "*sub_shiftsi_compare0_scratch"
[(set (reg:CC_NOOV CC_REGNUM)
(compare:CC_NOOV
- (minus:SI (match_operand:SI 1 "s_register_operand" "r,r")
+ (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
(match_operator:SI 2 "shift_operator"
- [(match_operand:SI 3 "s_register_operand" "r,r")
- (match_operand:SI 4 "shift_amount_operand" "M,rM")]))
+ [(match_operand:SI 3 "s_register_operand" "r,r,r")
+ (match_operand:SI 4 "shift_amount_operand" "M,r,M")]))
(const_int 0)))
- (clobber (match_scratch:SI 0 "=r,r"))]
+ (clobber (match_scratch:SI 0 "=r,r,r"))]
"TARGET_32BIT"
"sub%.\\t%0, %1, %3%S2"
[(set_attr "conds" "set")
(set_attr "shift" "3")
- (set_attr "arch" "32,a")
- (set_attr "type" "arlo_shift,arlo_shift_reg")])
+ (set_attr "arch" "32,a,a")
+ (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")])
(define_insn_and_split "*and_scc"
@@ -10232,7 +9983,7 @@
operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
}
[(set_attr "conds" "use")
- (set_attr "type" "mov_reg")
+ (set_attr "type" "multiple")
(set_attr "length" "8")]
)
@@ -10266,7 +10017,8 @@
operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
}
[(set_attr "conds" "use")
- (set_attr "length" "4,8")]
+ (set_attr "length" "4,8")
+ (set_attr "type" "logic_imm,multiple")]
)
; A series of splitters for the compare_scc pattern below. Note that
@@ -10368,7 +10120,9 @@
else
rc = reverse_condition (rc);
operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx);
-})
+}
+ [(set_attr "type" "multiple")]
+)
;; Attempt to improve the sequence generated by the compare_scc splitters
;; not to use conditional execution.
@@ -10411,7 +10165,7 @@
(geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
)
-;; Rd = (eq (reg1) (reg2/imm)) // ARMv5
+;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed.
;; sub Rd, Reg1, reg2
;; clz Rd, Rd
;; lsr Rd, Rd, #5
@@ -10423,14 +10177,15 @@
(set (match_operand:SI 0 "register_operand" "") (const_int 0)))
(cond_exec (eq (reg:CC CC_REGNUM) (const_int 0))
(set (match_dup 0) (const_int 1)))]
- "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
+ "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)
+ && !(TARGET_THUMB2 && optimize_insn_for_size_p ())"
[(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))
(set (match_dup 0) (clz:SI (match_dup 0)))
(set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))]
)
-;; Rd = (eq (reg1) (reg2/imm)) // ! ARMv5
+;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size.
;; sub T1, Reg1, reg2
;; negs Rd, T1
;; adc Rd, Rd, T1
@@ -10444,7 +10199,7 @@
(set (match_dup 0) (const_int 1)))
(match_scratch:SI 3 "r")]
"TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)"
- [(set (match_dup 3) (minus:SI (match_dup 1) (match_dup 2)))
+ [(set (match_dup 3) (match_dup 4))
(parallel
[(set (reg:CC CC_REGNUM)
(compare:CC (const_int 0) (match_dup 3)))
@@ -10452,7 +10207,12 @@
(set (match_dup 0)
(plus:SI (plus:SI (match_dup 0) (match_dup 3))
(geu:SI (reg:CC CC_REGNUM) (const_int 0))))]
-)
+ "
+ if (CONST_INT_P (operands[2]))
+ operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2]));
+ else
+ operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]);
+ ")
(define_insn "*cond_move"
[(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
@@ -10479,7 +10239,7 @@
return \"\";
"
[(set_attr "conds" "use")
- (set_attr "type" "mov_reg")
+ (set_attr "type" "mov_reg,mov_reg,multiple")
(set_attr "length" "4,4,8")]
)
@@ -10506,7 +10266,8 @@
return \"%i5%d4\\t%0, %1, #1\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
(define_insn "*cond_sub"
@@ -10524,7 +10285,8 @@
return \"sub%d4\\t%0, %1, #1\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*cmp_ite0"
@@ -10588,6 +10350,7 @@
}"
[(set_attr "conds" "set")
(set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any")
+ (set_attr "type" "multiple")
(set_attr_alternative "length"
[(const_int 6)
(const_int 8)
@@ -10687,7 +10450,8 @@
(const_int 10))
(if_then_else (eq_attr "is_thumb" "no")
(const_int 8)
- (const_int 10))])]
+ (const_int 10))])
+ (set_attr "type" "multiple")]
)
(define_insn "*cmp_and"
@@ -10768,7 +10532,8 @@
(const_int 10))
(if_then_else (eq_attr "is_thumb" "no")
(const_int 8)
- (const_int 10))])]
+ (const_int 10))])
+ (set_attr "type" "multiple")]
)
(define_insn "*cmp_ior"
@@ -10849,7 +10614,8 @@
(const_int 10))
(if_then_else (eq_attr "is_thumb" "no")
(const_int 8)
- (const_int 10))])]
+ (const_int 10))])
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*ior_scc_scc"
@@ -10878,7 +10644,9 @@
DOM_CC_X_OR_Y),
CC_REGNUM);"
[(set_attr "conds" "clob")
- (set_attr "length" "16")])
+ (set_attr "length" "16")
+ (set_attr "type" "multiple")]
+)
; If the above pattern is followed by a CMP insn, then the compare is
; redundant, since we can rework the conditional instruction that follows.
@@ -10906,7 +10674,9 @@
(set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
""
[(set_attr "conds" "set")
- (set_attr "length" "16")])
+ (set_attr "length" "16")
+ (set_attr "type" "multiple")]
+)
(define_insn_and_split "*and_scc_scc"
[(set (match_operand:SI 0 "s_register_operand" "=Ts")
@@ -10936,7 +10706,9 @@
DOM_CC_X_AND_Y),
CC_REGNUM);"
[(set_attr "conds" "clob")
- (set_attr "length" "16")])
+ (set_attr "length" "16")
+ (set_attr "type" "multiple")]
+)
; If the above pattern is followed by a CMP insn, then the compare is
; redundant, since we can rework the conditional instruction that follows.
@@ -10964,7 +10736,9 @@
(set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))]
""
[(set_attr "conds" "set")
- (set_attr "length" "16")])
+ (set_attr "length" "16")
+ (set_attr "type" "multiple")]
+)
;; If there is no dominance in the comparison, then we can still save an
;; instruction in the AND case, since we can know that the second compare
@@ -10998,7 +10772,9 @@
operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4],
operands[5]);"
[(set_attr "conds" "clob")
- (set_attr "length" "20")])
+ (set_attr "length" "20")
+ (set_attr "type" "multiple")]
+)
(define_split
[(set (reg:CC_NOOV CC_REGNUM)
@@ -11109,7 +10885,8 @@
FAIL;
}
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "movcond_addsi"
@@ -11147,7 +10924,8 @@
}
"
[(set_attr "conds" "clob")
- (set_attr "enabled_for_depr_it" "no,yes,yes")]
+ (set_attr "enabled_for_depr_it" "no,yes,yes")
+ (set_attr "type" "multiple")]
)
(define_insn "movcond"
@@ -11210,7 +10988,8 @@
return \"\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "8,8,12")]
+ (set_attr "length" "8,8,12")
+ (set_attr "type" "multiple")]
)
;; ??? The patterns below need checking for Thumb-2 usefulness.
@@ -11228,7 +11007,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_plus_move"
@@ -11250,11 +11030,11 @@
(set_attr "length" "4,4,8,8")
(set_attr_alternative "type"
[(if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "arlo_imm" )
- (const_string "*"))
- (const_string "arlo_imm")
- (const_string "*")
- (const_string "*")])]
+ (const_string "alu_imm" )
+ (const_string "alu_reg"))
+ (const_string "alu_imm")
+ (const_string "alu_reg")
+ (const_string "alu_reg")])]
)
(define_insn "*ifcompare_move_plus"
@@ -11270,7 +11050,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_move_plus"
@@ -11290,13 +11071,7 @@
sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1"
[(set_attr "conds" "use")
(set_attr "length" "4,4,8,8")
- (set_attr_alternative "type"
- [(if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "arlo_imm" )
- (const_string "*"))
- (const_string "arlo_imm")
- (const_string "*")
- (const_string "*")])]
+ (set_attr "type" "alu_reg,alu_imm,multiple,multiple")]
)
(define_insn "*ifcompare_arith_arith"
@@ -11314,7 +11089,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_arith_arith"
@@ -11330,7 +11106,8 @@
"TARGET_ARM"
"%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4"
[(set_attr "conds" "use")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn "*ifcompare_arith_move"
@@ -11371,7 +11148,8 @@
return \"\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_arith_move"
@@ -11388,7 +11166,7 @@
%I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1"
[(set_attr "conds" "use")
(set_attr "length" "4,8")
- (set_attr "type" "*,*")]
+ (set_attr "type" "alu_shift_reg,multiple")]
)
(define_insn "*ifcompare_move_arith"
@@ -11430,7 +11208,8 @@
return \"%I7%D6\\t%0, %2, %3\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_move_arith"
@@ -11448,7 +11227,7 @@
%I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1"
[(set_attr "conds" "use")
(set_attr "length" "4,8")
- (set_attr "type" "*,*")]
+ (set_attr "type" "alu_shift_reg,multiple")]
)
(define_insn "*ifcompare_move_not"
@@ -11464,7 +11243,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_move_not"
@@ -11481,7 +11261,8 @@
mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2"
[(set_attr "conds" "use")
(set_attr "type" "mvn_reg")
- (set_attr "length" "4,8,8")]
+ (set_attr "length" "4,8,8")
+ (set_attr "type" "mvn_reg,multiple,multiple")]
)
(define_insn "*ifcompare_not_move"
@@ -11497,7 +11278,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_not_move"
@@ -11513,7 +11295,7 @@
mov%D4\\t%0, %1\;mvn%d4\\t%0, %2
mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2"
[(set_attr "conds" "use")
- (set_attr "type" "mvn_reg")
+ (set_attr "type" "mvn_reg,multiple,multiple")
(set_attr "length" "4,8,8")]
)
@@ -11531,7 +11313,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_shift_move"
@@ -11551,9 +11334,7 @@
[(set_attr "conds" "use")
(set_attr "shift" "2")
(set_attr "length" "4,8,8")
- (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "mov_shift")
- (const_string "mov_shift_reg")))]
+ (set_attr "type" "mov_shift_reg,multiple,multiple")]
)
(define_insn "*ifcompare_move_shift"
@@ -11570,7 +11351,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_move_shift"
@@ -11590,9 +11372,7 @@
[(set_attr "conds" "use")
(set_attr "shift" "2")
(set_attr "length" "4,8,8")
- (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "")
- (const_string "mov_shift")
- (const_string "mov_shift_reg")))]
+ (set_attr "type" "mov_shift_reg,multiple,multiple")]
)
(define_insn "*ifcompare_shift_shift"
@@ -11611,7 +11391,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_shift_shift"
@@ -11651,7 +11432,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_not_arith"
@@ -11684,7 +11466,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_arith_not"
@@ -11699,7 +11482,7 @@
"TARGET_ARM"
"mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3"
[(set_attr "conds" "use")
- (set_attr "type" "mvn_reg")
+ (set_attr "type" "multiple")
(set_attr "length" "8")]
)
@@ -11715,7 +11498,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_neg_move"
@@ -11731,7 +11515,8 @@
mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0
mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0"
[(set_attr "conds" "use")
- (set_attr "length" "4,8,8")]
+ (set_attr "length" "4,8,8")
+ (set_attr "type" "logic_shift_imm,multiple,multiple")]
)
(define_insn "*ifcompare_move_neg"
@@ -11746,7 +11531,8 @@
"TARGET_ARM"
"#"
[(set_attr "conds" "clob")
- (set_attr "length" "8,12")]
+ (set_attr "length" "8,12")
+ (set_attr "type" "multiple")]
)
(define_insn "*if_move_neg"
@@ -11762,7 +11548,8 @@
mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0
mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0"
[(set_attr "conds" "use")
- (set_attr "length" "4,8,8")]
+ (set_attr "length" "4,8,8")
+ (set_attr "type" "logic_shift_imm,multiple,multiple")]
)
(define_insn "*arith_adjacentmem"
@@ -11960,7 +11747,8 @@
[(unspec_volatile [(const_int 0)] VUNSPEC_THUMB1_INTERWORK)]
"TARGET_THUMB1"
"* return thumb1_output_interwork ();"
- [(set_attr "length" "8")]
+ [(set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
;; Note - although unspec_volatile's USE all hard registers,
@@ -12147,7 +11935,7 @@
mvn%D4\\t%0, %2
mov%d4\\t%0, %1\;mvn%D4\\t%0, %2"
[(set_attr "conds" "use")
- (set_attr "type" "mvn_reg")
+ (set_attr "type" "mvn_reg,multiple")
(set_attr "length" "4,8")]
)
@@ -12167,7 +11955,8 @@
return \"mvnne\\t%0, #0\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn "*not_signextract_onebit"
@@ -12185,7 +11974,8 @@
return \"movne\\t%0, #0\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
;; ??? The above patterns need auditing for Thumb-2
@@ -12247,7 +12037,8 @@
UNSPEC_PRLG_STK))]
""
""
- [(set_attr "length" "0")]
+ [(set_attr "length" "0")
+ (set_attr "type" "block")]
)
;; Pop (as used in epilogue RTL)
@@ -12377,6 +12168,7 @@
assemble_align (32);
return \"\";
"
+ [(set_attr "type" "no_insn")]
)
(define_insn "align_8"
@@ -12386,6 +12178,7 @@
assemble_align (64);
return \"\";
"
+ [(set_attr "type" "no_insn")]
)
(define_insn "consttable_end"
@@ -12395,6 +12188,7 @@
making_const_table = FALSE;
return \"\";
"
+ [(set_attr "type" "no_insn")]
)
(define_insn "consttable_1"
@@ -12406,7 +12200,8 @@
assemble_zeros (3);
return \"\";
"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "no_insn")]
)
(define_insn "consttable_2"
@@ -12419,7 +12214,8 @@
assemble_zeros (2);
return \"\";
"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "no_insn")]
)
(define_insn "consttable_4"
@@ -12455,7 +12251,8 @@
}
return \"\";
}"
- [(set_attr "length" "4")]
+ [(set_attr "length" "4")
+ (set_attr "type" "no_insn")]
)
(define_insn "consttable_8"
@@ -12479,7 +12276,8 @@
}
return \"\";
}"
- [(set_attr "length" "8")]
+ [(set_attr "length" "8")
+ (set_attr "type" "no_insn")]
)
(define_insn "consttable_16"
@@ -12503,7 +12301,8 @@
}
return \"\";
}"
- [(set_attr "length" "16")]
+ [(set_attr "length" "16")
+ (set_attr "type" "no_insn")]
)
;; Miscellaneous Thumb patterns
@@ -12531,7 +12330,8 @@
(use (label_ref (match_operand 1 "" "")))]
"TARGET_THUMB1"
"mov\\t%|pc, %0"
- [(set_attr "length" "2")]
+ [(set_attr "length" "2")
+ (set_attr "type" "no_insn")]
)
;; V5 Instructions,
@@ -12573,7 +12373,9 @@
(match_operand:SI 1 "" "")
(match_operand:SI 2 "" ""))]
"TARGET_32BIT && arm_arch5e"
- "pld\\t%a0")
+ "pld\\t%a0"
+ [(set_attr "type" "load1")]
+)
;; General predication pattern
@@ -12590,7 +12392,8 @@
[(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)]
""
"%@ %0 needed"
- [(set_attr "length" "0")]
+ [(set_attr "length" "0")
+ (set_attr "type" "no_insn")]
)
@@ -12638,6 +12441,7 @@
thumb_set_return_address (operands[0], operands[1]);
DONE;
}"
+ [(set_attr "type" "mov_reg")]
)
@@ -12648,7 +12452,8 @@
(unspec:SI [(const_int 0)] UNSPEC_TLS))]
"TARGET_HARD_TP"
"mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard"
- [(set_attr "predicable" "yes")]
+ [(set_attr "predicable" "yes")
+ (set_attr "type" "mrs")]
)
;; Doesn't clobber R1-R3. Must use r0 for the first operand.
@@ -12659,7 +12464,8 @@
(clobber (reg:CC CC_REGNUM))]
"TARGET_SOFT_TP"
"bl\\t__aeabi_read_tp\\t@ load_tp_soft"
- [(set_attr "conds" "clob")]
+ [(set_attr "conds" "clob")
+ (set_attr "type" "branch")]
)
;; tls descriptor call
@@ -12678,7 +12484,8 @@
return "bl\\t%c0(tlscall)";
}
[(set_attr "conds" "clob")
- (set_attr "length" "4")]
+ (set_attr "length" "4")
+ (set_attr "type" "branch")]
)
;; For thread pointer builtin
@@ -12704,7 +12511,8 @@
"movt%?\t%0, %L1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "length" "4")]
+ (set_attr "length" "4")
+ (set_attr "type" "mov_imm")]
)
(define_insn "*arm_rev"
@@ -12716,7 +12524,8 @@
rev%?\t%0, %1
rev%?\t%0, %1"
[(set_attr "arch" "t1,t2,32")
- (set_attr "length" "2,2,4")]
+ (set_attr "length" "2,2,4")
+ (set_attr "type" "rev")]
)
(define_expand "arm_legacy_rev"
@@ -12816,7 +12625,8 @@
revsh%?\t%0, %1
revsh%?\t%0, %1"
[(set_attr "arch" "t1,t2,32")
- (set_attr "length" "2,2,4")]
+ (set_attr "length" "2,2,4")
+ (set_attr "type" "rev")]
)
(define_insn "*arm_rev16"
@@ -12828,7 +12638,8 @@
rev16%?\t%0, %1
rev16%?\t%0, %1"
[(set_attr "arch" "t1,t2,32")
- (set_attr "length" "2,2,4")]
+ (set_attr "length" "2,2,4")
+ (set_attr "type" "rev")]
)
(define_expand "bswaphi2"
diff --git a/gcc/config/arm/arm1020e.md b/gcc/config/arm/arm1020e.md
index 317e4cd4ad6..7df84d52481 100644
--- a/gcc/config/arm/arm1020e.md
+++ b/gcc/config/arm/arm1020e.md
@@ -66,14 +66,21 @@
;; ALU operations with no shifted operand
(define_insn_reservation "1020alu_op" 1
(and (eq_attr "tune" "arm1020e,arm1022e")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,mvn_imm,mvn_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,mvn_imm,mvn_reg,\
+ multiple,no_insn"))
"1020a_e,1020a_m,1020a_w")
;; ALU operations with a shift-by-constant operand
(define_insn_reservation "1020alu_shift_op" 1
(and (eq_attr "tune" "arm1020e,arm1022e")
- (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift"))
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ extend,mov_shift,mvn_shift"))
"1020a_e,1020a_m,1020a_w")
;; ALU operations with a shift-by-register operand
@@ -82,7 +89,9 @@
;; the execute stage.
(define_insn_reservation "1020alu_shift_reg_op" 2
(and (eq_attr "tune" "arm1020e,arm1022e")
- (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg"))
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift_reg,mvn_shift_reg"))
"1020a_e*2,1020a_m,1020a_w")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -270,7 +279,7 @@
;; first execute state. We model this by using 1020a_e in the first cycle.
(define_insn_reservation "v10_ffarith" 5
(and (eq_attr "vfp10" "yes")
- (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd"))
+ (eq_attr "type" "fmov,ffariths,ffarithd,fcmps,fcmpd"))
"1020a_e+v10_fmac")
(define_insn_reservation "v10_farith" 5
@@ -280,7 +289,7 @@
(define_insn_reservation "v10_cvt" 5
(and (eq_attr "vfp10" "yes")
- (eq_attr "type" "f_cvt"))
+ (eq_attr "type" "f_cvt,f_cvti2f,f_cvtf2i"))
"1020a_e+v10_fmac")
(define_insn_reservation "v10_fmul" 6
@@ -290,12 +299,12 @@
(define_insn_reservation "v10_fdivs" 18
(and (eq_attr "vfp10" "yes")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"1020a_e+v10_ds*14")
(define_insn_reservation "v10_fdivd" 32
(and (eq_attr "vfp10" "yes")
- (eq_attr "type" "fdivd"))
+ (eq_attr "type" "fdivd, fsqrtd"))
"1020a_e+v10_fmac+v10_ds*28")
(define_insn_reservation "v10_floads" 4
@@ -316,7 +325,7 @@
(define_insn_reservation "v10_c2v" 4
(and (eq_attr "vfp10" "yes")
- (eq_attr "type" "r_2_f"))
+ (eq_attr "type" "f_mcr,f_mcrr"))
"1020a_e+1020l_e+v10_ls1,v10_ls2")
(define_insn_reservation "v10_fstores" 1
@@ -331,7 +340,7 @@
(define_insn_reservation "v10_v2c" 1
(and (eq_attr "vfp10" "yes")
- (eq_attr "type" "f_2_r"))
+ (eq_attr "type" "f_mrc,f_mrrc"))
"1020a_e+1020l_e,1020l_m,1020l_w")
(define_insn_reservation "v10_to_cpsr" 2
diff --git a/gcc/config/arm/arm1026ejs.md b/gcc/config/arm/arm1026ejs.md
index 9112122d67b..f5a0447f5da 100644
--- a/gcc/config/arm/arm1026ejs.md
+++ b/gcc/config/arm/arm1026ejs.md
@@ -66,14 +66,21 @@
;; ALU operations with no shifted operand
(define_insn_reservation "alu_op" 1
(and (eq_attr "tune" "arm1026ejs")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,mvn_imm,mvn_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,mvn_imm,mvn_reg,\
+ multiple,no_insn"))
"a_e,a_m,a_w")
;; ALU operations with a shift-by-constant operand
(define_insn_reservation "alu_shift_op" 1
(and (eq_attr "tune" "arm1026ejs")
- (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift"))
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ extend,mov_shift,mvn_shift"))
"a_e,a_m,a_w")
;; ALU operations with a shift-by-register operand
@@ -82,7 +89,9 @@
;; the execute stage.
(define_insn_reservation "alu_shift_reg_op" 2
(and (eq_attr "tune" "arm1026ejs")
- (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg"))
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift_reg,mvn_shift_reg"))
"a_e*2,a_m,a_w")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/gcc/config/arm/arm1136jfs.md b/gcc/config/arm/arm1136jfs.md
index f83b9d14f2b..f6e0b8da8b6 100644
--- a/gcc/config/arm/arm1136jfs.md
+++ b/gcc/config/arm/arm1136jfs.md
@@ -75,14 +75,21 @@
;; ALU operations with no shifted operand
(define_insn_reservation "11_alu_op" 2
(and (eq_attr "tune" "arm1136js,arm1136jfs")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,mvn_imm,mvn_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,mvn_imm,mvn_reg,\
+ multiple,no_insn"))
"e_1,e_2,e_3,e_wb")
;; ALU operations with a shift-by-constant operand
(define_insn_reservation "11_alu_shift_op" 2
(and (eq_attr "tune" "arm1136js,arm1136jfs")
- (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift"))
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ extend,mov_shift,mvn_shift"))
"e_1,e_2,e_3,e_wb")
;; ALU operations with a shift-by-register operand
@@ -91,7 +98,9 @@
;; the shift stage.
(define_insn_reservation "11_alu_shift_reg_op" 3
(and (eq_attr "tune" "arm1136js,arm1136jfs")
- (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg"))
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift_reg,mvn_shift_reg"))
"e_1*2,e_2,e_3,e_wb")
;; alu_ops can start sooner, if there is no shifter dependency
diff --git a/gcc/config/arm/arm926ejs.md b/gcc/config/arm/arm926ejs.md
index 8c38e86ce66..d2b0e9e3cf8 100644
--- a/gcc/config/arm/arm926ejs.md
+++ b/gcc/config/arm/arm926ejs.md
@@ -58,9 +58,16 @@
;; ALU operations with no shifted operand
(define_insn_reservation "9_alu_op" 1
(and (eq_attr "tune" "arm926ejs")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,extend,arlo_shift,\
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ shift_imm,shift_reg,extend,\
mov_imm,mov_reg,mov_shift,\
- mvn_imm,mvn_reg,mvn_shift"))
+ mvn_imm,mvn_reg,mvn_shift,\
+ multiple,no_insn"))
"e,m,w")
;; ALU operations with a shift-by-register operand
@@ -69,7 +76,9 @@
;; the execute stage.
(define_insn_reservation "9_alu_shift_reg_op" 2
(and (eq_attr "tune" "arm926ejs")
- (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg"))
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift_reg,mvn_shift_reg"))
"e*2,m,w")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/gcc/config/arm/cortex-a15-neon.md b/gcc/config/arm/cortex-a15-neon.md
index bfa2f5e8818..6eb8268321a 100644
--- a/gcc/config/arm/cortex-a15-neon.md
+++ b/gcc/config/arm/cortex-a15-neon.md
@@ -93,389 +93,345 @@
(define_insn_reservation "cortex_a15_neon_int_1" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_int_1"))
+ (eq_attr "type" "neon_int_1"))
"ca15_issue1,ca15_cx_ialu")
(define_insn_reservation "cortex_a15_neon_int_2" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_int_2"))
+ (eq_attr "type" "neon_int_2"))
"ca15_issue1,ca15_cx_ialu")
(define_insn_reservation "cortex_a15_neon_int_3" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_int_3"))
+ (eq_attr "type" "neon_int_3"))
"ca15_issue1,ca15_cx_ialu")
(define_insn_reservation "cortex_a15_neon_int_4" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_int_4"))
+ (eq_attr "type" "neon_int_4"))
"ca15_issue1,ca15_cx_ialu")
(define_insn_reservation "cortex_a15_neon_int_5" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_int_5"))
+ (eq_attr "type" "neon_int_5"))
"ca15_issue1,ca15_cx_ialu")
(define_insn_reservation "cortex_a15_neon_vqneg_vqabs" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_vqneg_vqabs"))
+ (eq_attr "type" "neon_vqneg_vqabs"))
"ca15_issue1,ca15_cx_ialu")
(define_insn_reservation "cortex_a15_neon_vmov" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_vmov"))
+ (eq_attr "type" "neon_vmov"))
"ca15_issue1,ca15_cx_ialu")
(define_insn_reservation "cortex_a15_neon_vaba" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_vaba"))
+ (eq_attr "type" "neon_vaba"))
"ca15_issue1,ca15_cx_ialu_with_acc")
(define_insn_reservation "cortex_a15_neon_vaba_qqq" 8
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_vaba_qqq"))
+ (eq_attr "type" "neon_vaba_qqq"))
"ca15_issue2,ca15_cx_ialu_with_acc*2")
(define_insn_reservation
"cortex_a15_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long"))
+ (eq_attr "type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long"))
"ca15_issue1,ca15_cx_imac")
(define_insn_reservation "cortex_a15_neon_mul_qqq_8_16_32_ddd_32" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type" "neon_mul_qqq_8_16_32_ddd_32"))
+ (eq_attr "type" "neon_mul_qqq_8_16_32_ddd_32"))
"ca15_issue1,ca15_cx_imac*2")
(define_insn_reservation
"cortex_a15_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
+ (eq_attr "type"
"neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))
"ca15_issue1,ca15_cx_imac*2")
(define_insn_reservation
"cortex_a15_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
+ (eq_attr "type"
"neon_mla_ddd_8_16_qdd_16_8_long_32_16_long"))
"ca15_issue1,ca15_cx_imac")
(define_insn_reservation
"cortex_a15_neon_mla_qqq_8_16" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
+ (eq_attr "type"
"neon_mla_qqq_8_16"))
"ca15_issue1,ca15_cx_imac*2")
(define_insn_reservation
"cortex_a15_neon_mla_ddd_32_qqd_16_ddd_32_scalar_\
- qdd_64_32_long_scalar_qdd_64_32_long" 7
+ qdd_64_32_lotype_qdd_64_32_long" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
+ (eq_attr "type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
"ca15_issue1,ca15_cx_imac")
(define_insn_reservation
"cortex_a15_neon_mla_qqq_32_qqd_32_scalar" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mla_qqq_32_qqd_32_scalar"))
+ (eq_attr "type" "neon_mla_qqq_32_qqd_32_scalar"))
"ca15_issue1,ca15_cx_imac*2")
(define_insn_reservation
"cortex_a15_neon_mul_ddd_16_scalar_32_16_long_scalar" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mul_ddd_16_scalar_32_16_long_scalar"))
+ (eq_attr "type" "neon_mul_ddd_16_scalar_32_16_long_scalar"))
"ca15_issue1,ca15_cx_imac")
(define_insn_reservation
"cortex_a15_neon_mul_qqd_32_scalar" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mul_qqd_32_scalar"))
+ (eq_attr "type" "neon_mul_qqd_32_scalar"))
"ca15_issue1,ca15_cx_imac*2")
(define_insn_reservation
"cortex_a15_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar"))
+ (eq_attr "type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar"))
"ca15_issue1,ca15_cx_imac")
(define_insn_reservation
"cortex_a15_neon_shift_1" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_shift_1"))
+ (eq_attr "type" "neon_shift_1"))
"ca15_issue1,ca15_cx_ik+ca15_cx_ishf")
(define_insn_reservation
"cortex_a15_neon_shift_2" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_shift_2"))
+ (eq_attr "type" "neon_shift_2"))
"ca15_issue1,ca15_cx_ik+ca15_cx_ishf")
(define_insn_reservation
"cortex_a15_neon_shift_3" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_shift_3"))
+ (eq_attr "type" "neon_shift_3"))
"ca15_issue2,(ca15_cx_ik+ca15_cx_ishf)*2")
(define_insn_reservation
"cortex_a15_neon_vshl_ddd" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vshl_ddd"))
+ (eq_attr "type" "neon_vshl_ddd"))
"ca15_issue1,ca15_cx_ik+ca15_cx_ishf")
(define_insn_reservation
"cortex_a15_neon_vqshl_vrshl_vqrshl_qqq" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vqshl_vrshl_vqrshl_qqq"))
+ (eq_attr "type" "neon_vqshl_vrshl_vqrshl_qqq"))
"ca15_issue2,(ca15_cx_ik+ca15_cx_ishf)*2")
(define_insn_reservation
"cortex_a15_neon_vsra_vrsra" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vsra_vrsra"))
+ (eq_attr "type" "neon_vsra_vrsra"))
"ca15_issue1,ca15_cx_ishf_with_acc")
(define_insn_reservation
"cortex_a15_neon_fp_vadd_ddd_vabs_dd" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vadd_ddd_vabs_dd"))
+ (eq_attr "type" "neon_fp_vadd_ddd_vabs_dd"))
"ca15_issue1,ca15_cx_falu")
(define_insn_reservation
"cortex_a15_neon_fp_vadd_qqq_vabs_qq" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vadd_qqq_vabs_qq"))
+ (eq_attr "type" "neon_fp_vadd_qqq_vabs_qq"))
"ca15_issue2,ca15_cx_falu_2")
(define_insn_reservation
"cortex_a15_neon_fp_vmul_ddd" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vmul_ddd"))
+ (eq_attr "type" "neon_fp_vmul_ddd"))
"ca15_issue1,ca15_cx_fmul")
(define_insn_reservation
"cortex_a15_neon_fp_vmul_qqd" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vmul_qqd"))
+ (eq_attr "type" "neon_fp_vmul_qqd"))
"ca15_issue2,ca15_cx_fmul_2")
(define_insn_reservation
"cortex_a15_neon_fp_vmla_ddd" 9
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vmla_ddd"))
+ (eq_attr "type" "neon_fp_vmla_ddd"))
"ca15_issue1,ca15_cx_fmac")
(define_insn_reservation
"cortex_a15_neon_fp_vmla_qqq" 11
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vmla_qqq"))
+ (eq_attr "type" "neon_fp_vmla_qqq"))
"ca15_issue2,ca15_cx_fmac_2")
(define_insn_reservation
"cortex_a15_neon_fp_vmla_ddd_scalar" 9
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vmla_ddd_scalar"))
+ (eq_attr "type" "neon_fp_vmla_ddd_scalar"))
"ca15_issue1,ca15_cx_fmac")
(define_insn_reservation
"cortex_a15_neon_fp_vmla_qqq_scalar" 11
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vmla_qqq_scalar"))
+ (eq_attr "type" "neon_fp_vmla_qqq_scalar"))
"ca15_issue2,ca15_cx_fmac_2")
(define_insn_reservation
"cortex_a15_neon_fp_vrecps_vrsqrts_ddd" 9
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vrecps_vrsqrts_ddd"))
+ (eq_attr "type" "neon_fp_vrecps_vrsqrts_ddd"))
"ca15_issue1,ca15_cx_fmac")
(define_insn_reservation
"cortex_a15_neon_fp_vrecps_vrsqrts_qqq" 11
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_fp_vrecps_vrsqrts_qqq"))
+ (eq_attr "type" "neon_fp_vrecps_vrsqrts_qqq"))
"ca15_issue2,ca15_cx_fmac_2")
(define_insn_reservation
"cortex_a15_neon_bp_simple" 4
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_bp_simple"))
+ (eq_attr "type" "neon_bp_simple"))
"ca15_issue3,ca15_ls+ca15_cx_perm_2,ca15_cx_perm")
(define_insn_reservation
"cortex_a15_neon_bp_2cycle" 4
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_bp_2cycle"))
+ (eq_attr "type" "neon_bp_2cycle"))
"ca15_issue1,ca15_cx_perm")
(define_insn_reservation
"cortex_a15_neon_bp_3cycle" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_bp_3cycle"))
+ (eq_attr "type" "neon_bp_3cycle"))
"ca15_issue3,ca15_cx_ialu+ca15_cx_perm_2,ca15_cx_perm")
(define_insn_reservation
"cortex_a15_neon_vld1_1_2_regs" 7
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vld1_1_2_regs"))
+ (eq_attr "type" "neon_vld1_1_2_regs"))
"ca15_issue2,ca15_ls,ca15_ldr")
(define_insn_reservation
"cortex_a15_neon_vld1_3_4_regs" 8
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vld1_3_4_regs"))
+ (eq_attr "type" "neon_vld1_3_4_regs"))
"ca15_issue3,ca15_ls1+ca15_ls2,ca15_ldr,ca15_ldr")
(define_insn_reservation
"cortex_a15_neon_vld2_2_regs_vld1_vld2_all_lanes" 9
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vld2_2_regs_vld1_vld2_all_lanes"))
+ (eq_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes"))
"ca15_issue3,ca15_ls,ca15_ldr")
(define_insn_reservation
"cortex_a15_neon_vld2_4_regs" 12
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vld2_4_regs"))
+ (eq_attr "type" "neon_vld2_4_regs"))
"ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_ldr*2")
(define_insn_reservation
"cortex_a15_neon_vld3_vld4" 12
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vld3_vld4"))
+ (eq_attr "type" "neon_vld3_vld4"))
"ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_ldr*2")
(define_insn_reservation
"cortex_a15_neon_vst1_1_2_regs_vst2_2_regs" 0
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vst1_1_2_regs_vst2_2_regs"))
+ (eq_attr "type" "neon_vst1_1_2_regs_vst2_2_regs"))
"ca15_issue3,ca15_issue3+ca15_cx_perm+ca15_ls1+ca15_ls2,ca15_str*2")
(define_insn_reservation
"cortex_a15_neon_vst1_3_4_regs" 0
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vst1_3_4_regs"))
+ (eq_attr "type" "neon_vst1_3_4_regs"))
"ca15_issue3,ca15_issue3+ca15_ls1+ca15_ls2,ca15_str*3")
(define_insn_reservation
"cortex_a15_neon_vst2_4_regs_vst3_vst4" 0
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vst2_4_regs_vst3_vst4"))
+ (eq_attr "type" "neon_vst2_4_regs_vst3_vst4"))
"ca15_issue3,ca15_issue3+ca15_cx_perm_2+ca15_ls1+ca15_ls2,\
ca15_issue3+ca15_str,ca15_str*3")
(define_insn_reservation
"cortex_a15_neon_vst3_vst4" 0
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vst3_vst4"))
+ (eq_attr "type" "neon_vst3_vst4"))
"ca15_issue3,ca15_issue3+ca15_cx_perm_2+ca15_ls1+ca15_ls2,ca15_str*4")
(define_insn_reservation
"cortex_a15_neon_vld1_vld2_lane" 9
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vld1_vld2_lane"))
+ (eq_attr "type" "neon_vld1_vld2_lane"))
"ca15_issue3,ca15_ls,ca15_ldr")
(define_insn_reservation
"cortex_a15_neon_vld3_vld4_lane" 10
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vld3_vld4_lane"))
+ (eq_attr "type" "neon_vld3_vld4_lane"))
"ca15_issue3,ca15_issue3+ca15_ls,ca15_issue3+ca15_ldr")
(define_insn_reservation
"cortex_a15_neon_vst1_vst2_lane" 0
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vst1_vst2_lane"))
+ (eq_attr "type" "neon_vst1_vst2_lane"))
"ca15_issue3,ca15_cx_perm+ca15_ls,ca15_str")
(define_insn_reservation
"cortex_a15_neon_vst3_vst4_lane" 0
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vst3_vst4_lane"))
+ (eq_attr "type" "neon_vst3_vst4_lane"))
"ca15_issue3,ca15_issue3+ca15_cx_perm+ca15_ls1+ca15_ls2,ca15_str*2")
(define_insn_reservation
"cortex_a15_neon_vld3_vld4_all_lanes" 11
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_vld3_vld4_all_lanes"))
+ (eq_attr "type" "neon_vld3_vld4_all_lanes"))
"ca15_issue3,ca15_issue3+ca15_ls,ca15_ldr")
(define_insn_reservation
"cortex_a15_neon_ldm_2" 20
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_ldm_2"))
+ (eq_attr "type" "neon_ldm_2"))
"ca15_issue3*6")
(define_insn_reservation
"cortex_a15_neon_stm_2" 0
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_stm_2"))
+ (eq_attr "type" "neon_stm_2"))
"ca15_issue3*6")
(define_insn_reservation
"cortex_a15_neon_mcr" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mcr"))
+ (eq_attr "type" "neon_mcr"))
"ca15_issue2,ca15_ls,ca15_cx_perm")
(define_insn_reservation
"cortex_a15_neon_mcr_2_mcrr" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mcr_2_mcrr"))
+ (eq_attr "type" "neon_mcr_2_mcrr"))
"ca15_issue2,ca15_ls1+ca15_ls2")
(define_insn_reservation
"cortex_a15_neon_mrc" 5
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mrc"))
+ (eq_attr "type" "neon_mrc"))
"ca15_issue1,ca15_ls")
(define_insn_reservation
"cortex_a15_neon_mrrc" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "neon_type"
- "neon_mrrc"))
+ (eq_attr "type" "neon_mrrc"))
"ca15_issue2,ca15_ls1+ca15_ls2")
(define_insn_reservation "cortex_a15_vfp_const" 4
@@ -515,7 +471,7 @@
(define_insn_reservation "cortex_a15_vfp_cvt" 6
(and (eq_attr "tune" "cortexa15")
- (eq_attr "type" "f_cvt"))
+ (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f"))
"ca15_issue1,ca15_cx_vfp")
(define_insn_reservation "cortex_a15_vfp_cmpd" 8
@@ -535,7 +491,7 @@
(define_insn_reservation "cortex_a15_vfp_cpys" 4
(and (eq_attr "tune" "cortexa15")
- (eq_attr "type" "fcpys"))
+ (eq_attr "type" "fmov"))
"ca15_issue1,ca15_cx_perm")
(define_insn_reservation "cortex_a15_vfp_ariths" 7
@@ -545,12 +501,12 @@
(define_insn_reservation "cortex_a15_vfp_divs" 10
(and (eq_attr "tune" "cortexa15")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"ca15_issue1,ca15_cx_ik")
(define_insn_reservation "cortex_a15_vfp_divd" 18
(and (eq_attr "tune" "cortexa15")
- (eq_attr "type" "fdivd"))
+ (eq_attr "type" "fdivd, fsqrtd"))
"ca15_issue1,ca15_cx_ik")
;; Define bypasses.
diff --git a/gcc/config/arm/cortex-a15.md b/gcc/config/arm/cortex-a15.md
index 4ad87121d6d..ccad6207608 100644
--- a/gcc/config/arm/cortex-a15.md
+++ b/gcc/config/arm/cortex-a15.md
@@ -61,25 +61,32 @@
;; Simple ALU without shift
(define_insn_reservation "cortex_a15_alu" 2
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,\
- mvn_imm,mvn_reg")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,\
+ mvn_imm,mvn_reg,\
+ mrs,multiple,no_insn"))
"ca15_issue1,(ca15_sx1,ca15_sx1_alu)|(ca15_sx2,ca15_sx2_alu)")
;; ALU ops with immediate shift
(define_insn_reservation "cortex_a15_alu_shift" 3
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "extend,arlo_shift,,mov_shift,mvn_shift")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "extend,\
+ alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ mov_shift,mvn_shift"))
"ca15_issue1,(ca15_sx1,ca15_sx1+ca15_sx1_shf,ca15_sx1_alu)\
|(ca15_sx2,ca15_sx2+ca15_sx2_shf,ca15_sx2_alu)")
;; ALU ops with register controlled shift
(define_insn_reservation "cortex_a15_alu_shift_reg" 3
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift_reg,mvn_shift_reg"))
"(ca15_issue2,ca15_sx1+ca15_sx2,ca15_sx1_shf,ca15_sx2_alu)\
|(ca15_issue1,(ca15_issue1+ca15_sx2,ca15_sx1+ca15_sx2_shf)\
|(ca15_issue1+ca15_sx1,ca15_sx1+ca15_sx1_shf),ca15_sx1_alu)")
@@ -89,15 +96,13 @@
;; 32-bit multiplies
(define_insn_reservation "cortex_a15_mult32" 3
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "mul32" "yes")
- (eq_attr "neon_type" "none")))
+ (eq_attr "mul32" "yes"))
"ca15_issue1,ca15_mx")
;; 64-bit multiplies
(define_insn_reservation "cortex_a15_mult64" 4
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "mul64" "yes")
- (eq_attr "neon_type" "none")))
+ (eq_attr "mul64" "yes"))
"ca15_issue1,ca15_mx*2")
;; Integer divide
@@ -114,8 +119,7 @@
;; Block all issue pipes for a cycle
(define_insn_reservation "cortex_a15_block" 1
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "block")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "block"))
"ca15_issue3")
;; Branch execution Unit
@@ -124,8 +128,7 @@
;; No latency as there is no result
(define_insn_reservation "cortex_a15_branch" 0
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "branch")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "branch"))
"ca15_issue1,ca15_bx")
;; Load-store execution Unit
@@ -133,29 +136,25 @@
;; Loads of up to two words.
(define_insn_reservation "cortex_a15_load1" 4
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "load_byte,load1,load2")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "load_byte,load1,load2"))
"ca15_issue1,ca15_ls,ca15_ldr,nothing")
;; Loads of three or four words.
(define_insn_reservation "cortex_a15_load3" 5
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "load3,load4")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "load3,load4"))
"ca15_issue2,ca15_ls1+ca15_ls2,ca15_ldr,ca15_ldr,nothing")
;; Stores of up to two words.
(define_insn_reservation "cortex_a15_store1" 0
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "store1,store2")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "store1,store2"))
"ca15_issue1,ca15_ls,ca15_str")
;; Stores of three or four words.
(define_insn_reservation "cortex_a15_store3" 0
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "store3,store4")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "store3,store4"))
"ca15_issue2,ca15_ls1+ca15_ls2,ca15_str,ca15_str")
;; We include Neon.md here to ensure that the branch can block the Neon units.
@@ -165,8 +164,7 @@
;; pipeline. The result however is available the next cycle.
(define_insn_reservation "cortex_a15_call" 1
(and (eq_attr "tune" "cortexa15")
- (and (eq_attr "type" "call")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "call"))
"ca15_issue3,\
ca15_sx1+ca15_sx2+ca15_bx+ca15_mx+ca15_cx_ij+ca15_cx_ik+ca15_ls1+ca15_ls2+\
ca15_cx_imac1+ca15_cx_ialu1+ca15_cx_ialu2+ca15_cx_ishf+\
diff --git a/gcc/config/arm/cortex-a5.md b/gcc/config/arm/cortex-a5.md
index 1400c47d95a..22e0a08f38e 100644
--- a/gcc/config/arm/cortex-a5.md
+++ b/gcc/config/arm/cortex-a5.md
@@ -58,13 +58,22 @@
(define_insn_reservation "cortex_a5_alu" 2
(and (eq_attr "tune" "cortexa5")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,mvn_imm,mvn_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,mvn_imm,mvn_reg,\
+ mrs,multiple,no_insn"))
"cortex_a5_ex1")
(define_insn_reservation "cortex_a5_alu_shift" 2
(and (eq_attr "tune" "cortexa5")
- (eq_attr "type" "extend,arlo_shift,arlo_shift_reg,\
+ (eq_attr "type" "extend,\
+ alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
mov_shift,mov_shift_reg,\
mvn_shift,mvn_shift_reg"))
"cortex_a5_ex1")
@@ -159,7 +168,8 @@
(define_insn_reservation "cortex_a5_fpalu" 4
(and (eq_attr "tune" "cortexa5")
- (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fcpys, fmuls, f_cvt,\
+ (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fmov, fmuls,\
+ f_cvt,f_cvtf2i,f_cvti2f,\
fcmps, fcmpd"))
"cortex_a5_ex1+cortex_a5_fpadd_pipe")
@@ -223,14 +233,14 @@
(define_insn_reservation "cortex_a5_fdivs" 14
(and (eq_attr "tune" "cortexa5")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"cortex_a5_ex1, cortex_a5_fp_div_sqrt * 13")
;; ??? Similarly for fdivd.
(define_insn_reservation "cortex_a5_fdivd" 29
(and (eq_attr "tune" "cortexa5")
- (eq_attr "type" "fdivd"))
+ (eq_attr "type" "fdivd, fsqrtd"))
"cortex_a5_ex1, cortex_a5_fp_div_sqrt * 28")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -243,12 +253,12 @@
(define_insn_reservation "cortex_a5_r2f" 4
(and (eq_attr "tune" "cortexa5")
- (eq_attr "type" "r_2_f"))
+ (eq_attr "type" "f_mcr,f_mcrr"))
"cortex_a5_ex1")
(define_insn_reservation "cortex_a5_f2r" 2
(and (eq_attr "tune" "cortexa5")
- (eq_attr "type" "f_2_r"))
+ (eq_attr "type" "f_mrc,f_mrrc"))
"cortex_a5_ex1")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/gcc/config/arm/cortex-a53.md b/gcc/config/arm/cortex-a53.md
index 2f9107994c9..48d0d03853f 100644
--- a/gcc/config/arm/cortex-a53.md
+++ b/gcc/config/arm/cortex-a53.md
@@ -67,14 +67,22 @@
(define_insn_reservation "cortex_a53_alu" 2
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,mvn_imm,mvn_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,csel,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,mvn_imm,mvn_reg,\
+ mrs,multiple,no_insn"))
"cortex_a53_slot_any")
(define_insn_reservation "cortex_a53_alu_shift" 2
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "arlo_shift,arlo_shift_reg,\
- mov_shift,mov_shift_reg,\
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ extend,mov_shift,mov_shift_reg,\
mvn_shift,mvn_shift_reg"))
"cortex_a53_slot_any")
@@ -130,12 +138,12 @@
(define_insn_reservation "cortex_a53_load1" 3
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "load_byte,load1"))
+ (eq_attr "type" "load_byte,load1,load_acq"))
"cortex_a53_slot_any+cortex_a53_ls")
(define_insn_reservation "cortex_a53_store1" 2
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "store1"))
+ (eq_attr "type" "store1,store_rel"))
"cortex_a53_slot_any+cortex_a53_ls+cortex_a53_store")
(define_insn_reservation "cortex_a53_load2" 3
@@ -201,8 +209,9 @@
(define_insn_reservation "cortex_a53_fpalu" 4
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fcpys, fmuls, f_cvt,\
- fcmps, fcmpd"))
+ (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fmov, fmuls,\
+ f_cvt,f_cvtf2i,f_cvti2f,\
+ fcmps, fcmpd, fcsel"))
"cortex_a53_slot0+cortex_a53_fpadd_pipe")
(define_insn_reservation "cortex_a53_fconst" 2
@@ -230,12 +239,12 @@
(define_insn_reservation "cortex_a53_fdivs" 14
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"cortex_a53_slot0, cortex_a53_fp_div_sqrt * 13")
(define_insn_reservation "cortex_a53_fdivd" 29
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "fdivd"))
+ (eq_attr "type" "fdivd, fsqrtd"))
"cortex_a53_slot0, cortex_a53_fp_div_sqrt * 28")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -244,12 +253,12 @@
(define_insn_reservation "cortex_a53_r2f" 4
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "r_2_f"))
+ (eq_attr "type" "f_mcr,f_mcrr"))
"cortex_a53_slot0")
(define_insn_reservation "cortex_a53_f2r" 2
(and (eq_attr "tune" "cortexa53")
- (eq_attr "type" "f_2_r"))
+ (eq_attr "type" "f_mrc,f_mrrc"))
"cortex_a53_slot0")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/gcc/config/arm/cortex-a7.md b/gcc/config/arm/cortex-a7.md
index e14413d5083..a72a88d90af 100644
--- a/gcc/config/arm/cortex-a7.md
+++ b/gcc/config/arm/cortex-a7.md
@@ -67,8 +67,7 @@
(define_insn_reservation "cortex_a7_branch" 0
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "branch")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "branch"))
"(cortex_a7_ex2|cortex_a7_ex1)+cortex_a7_branch")
;; Call cannot dual-issue as an older instruction. It can dual-issue
@@ -77,8 +76,7 @@
;; cycle.
(define_insn_reservation "cortex_a7_call" 1
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "call")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "call"))
"(cortex_a7_ex2|cortex_a7_both)+cortex_a7_branch")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -88,27 +86,31 @@
;; ALU instruction with an immediate operand can dual-issue.
(define_insn_reservation "cortex_a7_alu_imm" 2
(and (eq_attr "tune" "cortexa7")
- (and (ior (eq_attr "type" "arlo_imm,mov_imm,mvn_imm")
- (ior (eq_attr "type" "extend")
- (and (eq_attr "type" "mov_reg,mov_shift,mov_shift_reg")
- (not (eq_attr "length" "8")))))
- (eq_attr "neon_type" "none")))
+ (ior (eq_attr "type" "adr,alu_imm,alus_imm,logic_imm,logics_imm,\
+ mov_imm,mvn_imm,extend")
+ (and (eq_attr "type" "mov_reg,mov_shift,mov_shift_reg")
+ (not (eq_attr "length" "8")))))
"cortex_a7_ex2|cortex_a7_ex1")
;; ALU instruction with register operands can dual-issue
;; with a younger immediate-based instruction.
(define_insn_reservation "cortex_a7_alu_reg" 2
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "arlo_reg,shift,shift_reg,mov_reg,mvn_reg")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ bfm,rev,\
+ shift_imm,shift_reg,mov_reg,mvn_reg"))
"cortex_a7_ex1")
(define_insn_reservation "cortex_a7_alu_shift" 2
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "arlo_shift,arlo_shift_reg,\
- mov_shift,mov_shift_reg,\
- mvn_shift,mvn_shift_reg")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift,mov_shift_reg,\
+ mvn_shift,mvn_shift_reg,\
+ mrs,multiple,no_insn"))
"cortex_a7_ex1")
;; Forwarding path for unshifted operands.
@@ -129,9 +131,8 @@
(define_insn_reservation "cortex_a7_mul" 2
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "neon_type" "none")
- (ior (eq_attr "mul32" "yes")
- (eq_attr "mul64" "yes"))))
+ (ior (eq_attr "mul32" "yes")
+ (eq_attr "mul64" "yes")))
"cortex_a7_both")
;; Forward the result of a multiply operation to the accumulator
@@ -156,50 +157,42 @@
(define_insn_reservation "cortex_a7_load1" 2
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "load_byte,load1")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "load_byte,load1"))
"cortex_a7_ex1")
(define_insn_reservation "cortex_a7_store1" 0
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "store1")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "store1"))
"cortex_a7_ex1")
(define_insn_reservation "cortex_a7_load2" 2
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "load2")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "load2"))
"cortex_a7_both")
(define_insn_reservation "cortex_a7_store2" 0
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "store2")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "store2"))
"cortex_a7_both")
(define_insn_reservation "cortex_a7_load3" 3
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "load3")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "load3"))
"cortex_a7_both, cortex_a7_ex1")
(define_insn_reservation "cortex_a7_store3" 0
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "store4")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "store4"))
"cortex_a7_both, cortex_a7_ex1")
(define_insn_reservation "cortex_a7_load4" 3
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "load4")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "load4"))
"cortex_a7_both, cortex_a7_both")
(define_insn_reservation "cortex_a7_store4" 0
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "store3")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "store3"))
"cortex_a7_both, cortex_a7_both")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -211,9 +204,8 @@
(define_insn_reservation "cortex_a7_fpalu" 4
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fcpys,\
- f_cvt, fcmps, fcmpd")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "ffariths, fadds, ffarithd, faddd, fmov,\
+ f_cvt, f_cvtf2i, f_cvti2f, fcmps, fcmpd"))
"cortex_a7_ex1+cortex_a7_fpadd_pipe")
;; For fconsts and fconstd, 8-bit immediate data is passed directly from
@@ -221,8 +213,7 @@
(define_insn_reservation "cortex_a7_fconst" 3
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "fconsts,fconstd")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "fconsts,fconstd"))
"cortex_a7_ex1+cortex_a7_fpadd_pipe")
;; We should try not to attempt to issue a single-precision multiplication in
@@ -231,13 +222,12 @@
(define_insn_reservation "cortex_a7_fpmuls" 4
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "fmuls")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "fmuls"))
"cortex_a7_ex1+cortex_a7_fpmul_pipe")
(define_insn_reservation "cortex_a7_neon_mul" 4
(and (eq_attr "tune" "cortexa7")
- (eq_attr "neon_type"
+ (eq_attr "type"
"neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
neon_mul_qqq_8_16_32_ddd_32,\
neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
@@ -249,13 +239,12 @@
(define_insn_reservation "cortex_a7_fpmacs" 8
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "fmacs,ffmas")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "fmacs,ffmas"))
"cortex_a7_ex1+cortex_a7_fpmul_pipe")
(define_insn_reservation "cortex_a7_neon_mla" 8
(and (eq_attr "tune" "cortexa7")
- (eq_attr "neon_type"
+ (eq_attr "type"
"neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
neon_mla_qqq_8_16,\
neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
@@ -276,20 +265,17 @@
(define_insn_reservation "cortex_a7_fpmuld" 7
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "fmuld")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "fmuld"))
"cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*3")
(define_insn_reservation "cortex_a7_fpmacd" 11
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "fmacd")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "fmacd"))
"cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*3")
(define_insn_reservation "cortex_a7_fpfmad" 8
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "ffmad")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "ffmad"))
"cortex_a7_ex1+cortex_a7_fpmul_pipe, cortex_a7_fpmul_pipe*4")
(define_bypass 7 "cortex_a7_fpmacd"
@@ -302,14 +288,12 @@
(define_insn_reservation "cortex_a7_fdivs" 16
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "fdivs")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "fdivs, fsqrts"))
"cortex_a7_ex1+cortex_a7_fp_div_sqrt, cortex_a7_fp_div_sqrt * 13")
(define_insn_reservation "cortex_a7_fdivd" 31
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "fdivd")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "fdivd, fsqrtd"))
"cortex_a7_ex1+cortex_a7_fp_div_sqrt, cortex_a7_fp_div_sqrt * 28")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -320,14 +304,12 @@
(define_insn_reservation "cortex_a7_r2f" 4
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "r_2_f")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "f_mcr,f_mcrr"))
"cortex_a7_both")
(define_insn_reservation "cortex_a7_f2r" 2
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "f_2_r")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "f_mrc,f_mrrc"))
"cortex_a7_ex1")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -339,8 +321,7 @@
(define_insn_reservation "cortex_a7_f_flags" 4
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "f_flag")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "f_flag"))
"cortex_a7_ex1")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -349,26 +330,22 @@
(define_insn_reservation "cortex_a7_f_loads" 4
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "f_loads")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "f_loads"))
"cortex_a7_ex1")
(define_insn_reservation "cortex_a7_f_loadd" 4
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "f_loadd")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "f_loadd"))
"cortex_a7_both")
(define_insn_reservation "cortex_a7_f_stores" 0
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "f_stores")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "f_stores"))
"cortex_a7_ex1")
(define_insn_reservation "cortex_a7_f_stored" 0
(and (eq_attr "tune" "cortexa7")
- (and (eq_attr "type" "f_stored")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "f_stored"))
"cortex_a7_both")
;; Load-to-use for floating-point values has a penalty of one cycle,
@@ -389,22 +366,21 @@
(define_insn_reservation "cortex_a7_neon" 4
(and (eq_attr "tune" "cortexa7")
- (eq_attr "neon_type"
- "!none,\
- neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
- neon_mul_qqq_8_16_32_ddd_32,\
- neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
- neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
- neon_mla_qqq_8_16,\
- neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
- neon_mla_qqq_32_qqd_32_scalar,\
- neon_mul_ddd_16_scalar_32_16_long_scalar,\
- neon_mul_qqd_32_scalar,\
- neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
- neon_fp_vmul_ddd,\
- neon_fp_vmul_qqd,\
- neon_fp_vmla_ddd,\
- neon_fp_vmla_qqq,\
- neon_fp_vmla_ddd_scalar,\
- neon_fp_vmla_qqq_scalar"))
+ (eq_attr "type"
+ "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ neon_mul_qqq_8_16_32_ddd_32,\
+ neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
+ neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ neon_mla_qqq_8_16,\
+ neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
+ neon_mla_qqq_32_qqd_32_scalar,\
+ neon_mul_ddd_16_scalar_32_16_long_scalar,\
+ neon_mul_qqd_32_scalar,\
+ neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
+ neon_fp_vmul_ddd,\
+ neon_fp_vmul_qqd,\
+ neon_fp_vmla_ddd,\
+ neon_fp_vmla_qqq,\
+ neon_fp_vmla_ddd_scalar,\
+ neon_fp_vmla_qqq_scalar"))
"cortex_a7_both*2")
diff --git a/gcc/config/arm/cortex-a8-neon.md b/gcc/config/arm/cortex-a8-neon.md
index 2f0cc7b3a5a..b7773891669 100644
--- a/gcc/config/arm/cortex-a8-neon.md
+++ b/gcc/config/arm/cortex-a8-neon.md
@@ -159,12 +159,12 @@
(define_insn_reservation "cortex_a8_vfp_divs" 37
(and (eq_attr "tune" "cortexa8")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"cortex_a8_vfp,cortex_a8_vfplite*36")
(define_insn_reservation "cortex_a8_vfp_divd" 65
(and (eq_attr "tune" "cortexa8")
- (eq_attr "type" "fdivd"))
+ (eq_attr "type" "fdivd, fsqrtd"))
"cortex_a8_vfp,cortex_a8_vfplite*64")
;; Comparisons can actually take 7 cycles sometimes instead of four,
@@ -172,24 +172,24 @@
;; take four cycles, we pick that latency.
(define_insn_reservation "cortex_a8_vfp_farith" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "type" "fcpys,ffariths,ffarithd,fconsts,fconstd,fcmps,fcmpd"))
+ (eq_attr "type" "fmov,ffariths,ffarithd,fconsts,fconstd,fcmps,fcmpd"))
"cortex_a8_vfp,cortex_a8_vfplite*3")
(define_insn_reservation "cortex_a8_vfp_cvt" 7
(and (eq_attr "tune" "cortexa8")
- (eq_attr "type" "f_cvt"))
+ (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f"))
"cortex_a8_vfp,cortex_a8_vfplite*6")
;; NEON -> core transfers.
(define_insn_reservation "cortex_a8_neon_mrc" 20
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mrc"))
+ (eq_attr "type" "neon_mrc"))
"cortex_a8_neon_ls")
(define_insn_reservation "cortex_a8_neon_mrrc" 21
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mrrc"))
+ (eq_attr "type" "neon_mrrc"))
"cortex_a8_neon_ls_2")
;; The remainder of this file is auto-generated by neon-schedgen.
@@ -198,48 +198,48 @@
;; produce a result at N3.
(define_insn_reservation "cortex_a8_neon_int_1" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_int_1"))
+ (eq_attr "type" "neon_int_1"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their (D|Q)m operands at N1,
;; their (D|Q)n operands at N2, and produce a result at N3.
(define_insn_reservation "cortex_a8_neon_int_2" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_int_2"))
+ (eq_attr "type" "neon_int_2"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N3.
(define_insn_reservation "cortex_a8_neon_int_3" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_int_3"))
+ (eq_attr "type" "neon_int_3"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N4.
(define_insn_reservation "cortex_a8_neon_int_4" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_int_4"))
+ (eq_attr "type" "neon_int_4"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their (D|Q)m operands at N1,
;; their (D|Q)n operands at N2, and produce a result at N4.
(define_insn_reservation "cortex_a8_neon_int_5" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_int_5"))
+ (eq_attr "type" "neon_int_5"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N4.
(define_insn_reservation "cortex_a8_neon_vqneg_vqabs" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vqneg_vqabs"))
+ (eq_attr "type" "neon_vqneg_vqabs"))
"cortex_a8_neon_dp")
;; Instructions using this reservation produce a result at N3.
(define_insn_reservation "cortex_a8_neon_vmov" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vmov"))
+ (eq_attr "type" "neon_vmov"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -247,7 +247,7 @@
;; produce a result at N6.
(define_insn_reservation "cortex_a8_neon_vaba" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vaba"))
+ (eq_attr "type" "neon_vaba"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -255,35 +255,35 @@
;; produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a8_neon_vaba_qqq" 7
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vaba_qqq"))
+ (eq_attr "type" "neon_vaba_qqq"))
"cortex_a8_neon_dp_2")
;; Instructions using this reservation read their (D|Q)m operands at N1,
;; their (D|Q)d operands at N3, and produce a result at N6.
(define_insn_reservation "cortex_a8_neon_vsma" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vsma"))
+ (eq_attr "type" "neon_vsma"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N6.
(define_insn_reservation "cortex_a8_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long"))
+ (eq_attr "type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a8_neon_mul_qqq_8_16_32_ddd_32" 7
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mul_qqq_8_16_32_ddd_32"))
+ (eq_attr "type" "neon_mul_qqq_8_16_32_ddd_32"))
"cortex_a8_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a8_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar" 7
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))
+ (eq_attr "type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))
"cortex_a8_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -291,7 +291,7 @@
;; produce a result at N6.
(define_insn_reservation "cortex_a8_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long"))
+ (eq_attr "type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -299,7 +299,7 @@
;; produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a8_neon_mla_qqq_8_16" 7
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mla_qqq_8_16"))
+ (eq_attr "type" "neon_mla_qqq_8_16"))
"cortex_a8_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -307,7 +307,7 @@
;; produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a8_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long" 7
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
+ (eq_attr "type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
"cortex_a8_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -315,21 +315,21 @@
;; produce a result at N6 on cycle 4.
(define_insn_reservation "cortex_a8_neon_mla_qqq_32_qqd_32_scalar" 9
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mla_qqq_32_qqd_32_scalar"))
+ (eq_attr "type" "neon_mla_qqq_32_qqd_32_scalar"))
"cortex_a8_neon_dp_4")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N6.
(define_insn_reservation "cortex_a8_neon_mul_ddd_16_scalar_32_16_long_scalar" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mul_ddd_16_scalar_32_16_long_scalar"))
+ (eq_attr "type" "neon_mul_ddd_16_scalar_32_16_long_scalar"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N6 on cycle 4.
(define_insn_reservation "cortex_a8_neon_mul_qqd_32_scalar" 9
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mul_qqd_32_scalar"))
+ (eq_attr "type" "neon_mul_qqd_32_scalar"))
"cortex_a8_neon_dp_4")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -337,84 +337,84 @@
;; produce a result at N6.
(define_insn_reservation "cortex_a8_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar"))
+ (eq_attr "type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N3.
(define_insn_reservation "cortex_a8_neon_shift_1" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_shift_1"))
+ (eq_attr "type" "neon_shift_1"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N4.
(define_insn_reservation "cortex_a8_neon_shift_2" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_shift_2"))
+ (eq_attr "type" "neon_shift_2"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N3 on cycle 2.
(define_insn_reservation "cortex_a8_neon_shift_3" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_shift_3"))
+ (eq_attr "type" "neon_shift_3"))
"cortex_a8_neon_dp_2")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N1.
(define_insn_reservation "cortex_a8_neon_vshl_ddd" 1
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vshl_ddd"))
+ (eq_attr "type" "neon_vshl_ddd"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N4 on cycle 2.
(define_insn_reservation "cortex_a8_neon_vqshl_vrshl_vqrshl_qqq" 5
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vqshl_vrshl_vqrshl_qqq"))
+ (eq_attr "type" "neon_vqshl_vrshl_vqrshl_qqq"))
"cortex_a8_neon_dp_2")
;; Instructions using this reservation read their (D|Q)m operands at N1,
;; their (D|Q)d operands at N3, and produce a result at N6.
(define_insn_reservation "cortex_a8_neon_vsra_vrsra" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vsra_vrsra"))
+ (eq_attr "type" "neon_vsra_vrsra"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N5.
(define_insn_reservation "cortex_a8_neon_fp_vadd_ddd_vabs_dd" 5
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd"))
+ (eq_attr "type" "neon_fp_vadd_ddd_vabs_dd"))
"cortex_a8_neon_fadd")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N5 on cycle 2.
(define_insn_reservation "cortex_a8_neon_fp_vadd_qqq_vabs_qq" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vadd_qqq_vabs_qq"))
+ (eq_attr "type" "neon_fp_vadd_qqq_vabs_qq"))
"cortex_a8_neon_fadd_2")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N5.
(define_insn_reservation "cortex_a8_neon_fp_vsum" 5
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vsum"))
+ (eq_attr "type" "neon_fp_vsum"))
"cortex_a8_neon_fadd")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N5.
(define_insn_reservation "cortex_a8_neon_fp_vmul_ddd" 5
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vmul_ddd"))
+ (eq_attr "type" "neon_fp_vmul_ddd"))
"cortex_a8_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N5 on cycle 2.
(define_insn_reservation "cortex_a8_neon_fp_vmul_qqd" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vmul_qqd"))
+ (eq_attr "type" "neon_fp_vmul_qqd"))
"cortex_a8_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -422,7 +422,7 @@
;; produce a result at N9.
(define_insn_reservation "cortex_a8_neon_fp_vmla_ddd" 9
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vmla_ddd"))
+ (eq_attr "type" "neon_fp_vmla_ddd"))
"cortex_a8_neon_fmul_then_fadd")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -430,7 +430,7 @@
;; produce a result at N9 on cycle 2.
(define_insn_reservation "cortex_a8_neon_fp_vmla_qqq" 10
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vmla_qqq"))
+ (eq_attr "type" "neon_fp_vmla_qqq"))
"cortex_a8_neon_fmul_then_fadd_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -438,7 +438,7 @@
;; produce a result at N9.
(define_insn_reservation "cortex_a8_neon_fp_vmla_ddd_scalar" 9
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vmla_ddd_scalar"))
+ (eq_attr "type" "neon_fp_vmla_ddd_scalar"))
"cortex_a8_neon_fmul_then_fadd")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -446,152 +446,152 @@
;; produce a result at N9 on cycle 2.
(define_insn_reservation "cortex_a8_neon_fp_vmla_qqq_scalar" 10
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vmla_qqq_scalar"))
+ (eq_attr "type" "neon_fp_vmla_qqq_scalar"))
"cortex_a8_neon_fmul_then_fadd_2")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N9.
(define_insn_reservation "cortex_a8_neon_fp_vrecps_vrsqrts_ddd" 9
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vrecps_vrsqrts_ddd"))
+ (eq_attr "type" "neon_fp_vrecps_vrsqrts_ddd"))
"cortex_a8_neon_fmul_then_fadd")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N9 on cycle 2.
(define_insn_reservation "cortex_a8_neon_fp_vrecps_vrsqrts_qqq" 10
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_fp_vrecps_vrsqrts_qqq"))
+ (eq_attr "type" "neon_fp_vrecps_vrsqrts_qqq"))
"cortex_a8_neon_fmul_then_fadd_2")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2.
(define_insn_reservation "cortex_a8_neon_bp_simple" 2
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_bp_simple"))
+ (eq_attr "type" "neon_bp_simple"))
"cortex_a8_neon_perm")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2 on cycle 2.
(define_insn_reservation "cortex_a8_neon_bp_2cycle" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_bp_2cycle"))
+ (eq_attr "type" "neon_bp_2cycle"))
"cortex_a8_neon_perm_2")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2 on cycle 3.
(define_insn_reservation "cortex_a8_neon_bp_3cycle" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_bp_3cycle"))
+ (eq_attr "type" "neon_bp_3cycle"))
"cortex_a8_neon_perm_3")
;; Instructions using this reservation produce a result at N1.
(define_insn_reservation "cortex_a8_neon_ldr" 1
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_ldr"))
+ (eq_attr "type" "neon_ldr"))
"cortex_a8_neon_ls")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a8_neon_str" 0
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_str"))
+ (eq_attr "type" "neon_str"))
"cortex_a8_neon_ls")
;; Instructions using this reservation produce a result at N1 on cycle 2.
(define_insn_reservation "cortex_a8_neon_vld1_1_2_regs" 2
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vld1_1_2_regs"))
+ (eq_attr "type" "neon_vld1_1_2_regs"))
"cortex_a8_neon_ls_2")
;; Instructions using this reservation produce a result at N1 on cycle 3.
(define_insn_reservation "cortex_a8_neon_vld1_3_4_regs" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vld1_3_4_regs"))
+ (eq_attr "type" "neon_vld1_3_4_regs"))
"cortex_a8_neon_ls_3")
;; Instructions using this reservation produce a result at N2 on cycle 2.
(define_insn_reservation "cortex_a8_neon_vld2_2_regs_vld1_vld2_all_lanes" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes"))
+ (eq_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes"))
"cortex_a8_neon_ls_2")
;; Instructions using this reservation produce a result at N2 on cycle 3.
(define_insn_reservation "cortex_a8_neon_vld2_4_regs" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vld2_4_regs"))
+ (eq_attr "type" "neon_vld2_4_regs"))
"cortex_a8_neon_ls_3")
;; Instructions using this reservation produce a result at N2 on cycle 4.
(define_insn_reservation "cortex_a8_neon_vld3_vld4" 5
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vld3_vld4"))
+ (eq_attr "type" "neon_vld3_vld4"))
"cortex_a8_neon_ls_4")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a8_neon_vst1_1_2_regs_vst2_2_regs" 0
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs"))
+ (eq_attr "type" "neon_vst1_1_2_regs_vst2_2_regs"))
"cortex_a8_neon_ls_2")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a8_neon_vst1_3_4_regs" 0
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vst1_3_4_regs"))
+ (eq_attr "type" "neon_vst1_3_4_regs"))
"cortex_a8_neon_ls_3")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a8_neon_vst2_4_regs_vst3_vst4" 0
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vst2_4_regs_vst3_vst4"))
+ (eq_attr "type" "neon_vst2_4_regs_vst3_vst4"))
"cortex_a8_neon_ls_4")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a8_neon_vst3_vst4" 0
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vst3_vst4"))
+ (eq_attr "type" "neon_vst3_vst4"))
"cortex_a8_neon_ls_4")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2 on cycle 3.
(define_insn_reservation "cortex_a8_neon_vld1_vld2_lane" 4
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vld1_vld2_lane"))
+ (eq_attr "type" "neon_vld1_vld2_lane"))
"cortex_a8_neon_ls_3")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2 on cycle 5.
(define_insn_reservation "cortex_a8_neon_vld3_vld4_lane" 6
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vld3_vld4_lane"))
+ (eq_attr "type" "neon_vld3_vld4_lane"))
"cortex_a8_neon_ls_5")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a8_neon_vst1_vst2_lane" 0
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vst1_vst2_lane"))
+ (eq_attr "type" "neon_vst1_vst2_lane"))
"cortex_a8_neon_ls_2")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a8_neon_vst3_vst4_lane" 0
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vst3_vst4_lane"))
+ (eq_attr "type" "neon_vst3_vst4_lane"))
"cortex_a8_neon_ls_3")
;; Instructions using this reservation produce a result at N2 on cycle 2.
(define_insn_reservation "cortex_a8_neon_vld3_vld4_all_lanes" 3
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_vld3_vld4_all_lanes"))
+ (eq_attr "type" "neon_vld3_vld4_all_lanes"))
"cortex_a8_neon_ls_3")
;; Instructions using this reservation produce a result at N2.
(define_insn_reservation "cortex_a8_neon_mcr" 2
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mcr"))
+ (eq_attr "type" "neon_mcr"))
"cortex_a8_neon_perm")
;; Instructions using this reservation produce a result at N2.
(define_insn_reservation "cortex_a8_neon_mcr_2_mcrr" 2
(and (eq_attr "tune" "cortexa8")
- (eq_attr "neon_type" "neon_mcr_2_mcrr"))
+ (eq_attr "type" "neon_mcr_2_mcrr"))
"cortex_a8_neon_perm_2")
;; Exceptions to the default latencies.
diff --git a/gcc/config/arm/cortex-a8.md b/gcc/config/arm/cortex-a8.md
index 1113a45ff0e..1eade5e1244 100644
--- a/gcc/config/arm/cortex-a8.md
+++ b/gcc/config/arm/cortex-a8.md
@@ -85,19 +85,25 @@
;; (source read in E2 and destination available at the end of that cycle).
(define_insn_reservation "cortex_a8_alu" 2
(and (eq_attr "tune" "cortexa8")
- (ior (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg")
- (eq_attr "neon_type" "none"))
- (eq_attr "type" "clz")))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,clz,rbit,rev,\
+ shift_imm,shift_reg,\
+ multiple,no_insn"))
"cortex_a8_default")
(define_insn_reservation "cortex_a8_alu_shift" 2
(and (eq_attr "tune" "cortexa8")
- (eq_attr "type" "extend,arlo_shift"))
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ extend"))
"cortex_a8_default")
(define_insn_reservation "cortex_a8_alu_shift_reg" 2
(and (eq_attr "tune" "cortexa8")
- (eq_attr "type" "arlo_shift_reg"))
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg"))
"cortex_a8_default")
;; Move instructions.
@@ -105,7 +111,8 @@
(define_insn_reservation "cortex_a8_mov" 1
(and (eq_attr "tune" "cortexa8")
(eq_attr "type" "mov_imm,mov_reg,mov_shift,mov_shift_reg,\
- mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg"))
+ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg,\
+ mrs"))
"cortex_a8_default")
;; Exceptions to the default latencies for data processing instructions.
diff --git a/gcc/config/arm/cortex-a9-neon.md b/gcc/config/arm/cortex-a9-neon.md
index 9688edc8f72..2c9d5db5bd8 100644
--- a/gcc/config/arm/cortex-a9-neon.md
+++ b/gcc/config/arm/cortex-a9-neon.md
@@ -109,12 +109,12 @@
;; NEON -> core transfers.
(define_insn_reservation "ca9_neon_mrc" 1
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mrc"))
+ (eq_attr "type" "neon_mrc"))
"ca9_issue_vfp_neon + cortex_a9_neon_mcr")
(define_insn_reservation "ca9_neon_mrrc" 1
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mrrc"))
+ (eq_attr "type" "neon_mrrc"))
"ca9_issue_vfp_neon + cortex_a9_neon_mcr")
;; The remainder of this file is auto-generated by neon-schedgen.
@@ -123,48 +123,48 @@
;; produce a result at N3.
(define_insn_reservation "cortex_a9_neon_int_1" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_int_1"))
+ (eq_attr "type" "neon_int_1"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their (D|Q)m operands at N1,
;; their (D|Q)n operands at N2, and produce a result at N3.
(define_insn_reservation "cortex_a9_neon_int_2" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_int_2"))
+ (eq_attr "type" "neon_int_2"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N3.
(define_insn_reservation "cortex_a9_neon_int_3" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_int_3"))
+ (eq_attr "type" "neon_int_3"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N4.
(define_insn_reservation "cortex_a9_neon_int_4" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_int_4"))
+ (eq_attr "type" "neon_int_4"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their (D|Q)m operands at N1,
;; their (D|Q)n operands at N2, and produce a result at N4.
(define_insn_reservation "cortex_a9_neon_int_5" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_int_5"))
+ (eq_attr "type" "neon_int_5"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N4.
(define_insn_reservation "cortex_a9_neon_vqneg_vqabs" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vqneg_vqabs"))
+ (eq_attr "type" "neon_vqneg_vqabs"))
"cortex_a9_neon_dp")
;; Instructions using this reservation produce a result at N3.
(define_insn_reservation "cortex_a9_neon_vmov" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vmov"))
+ (eq_attr "type" "neon_vmov"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -172,7 +172,7 @@
;; produce a result at N6.
(define_insn_reservation "cortex_a9_neon_vaba" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vaba"))
+ (eq_attr "type" "neon_vaba"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -180,35 +180,35 @@
;; produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a9_neon_vaba_qqq" 7
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vaba_qqq"))
+ (eq_attr "type" "neon_vaba_qqq"))
"cortex_a9_neon_dp_2")
;; Instructions using this reservation read their (D|Q)m operands at N1,
;; their (D|Q)d operands at N3, and produce a result at N6.
(define_insn_reservation "cortex_a9_neon_vsma" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vsma"))
+ (eq_attr "type" "neon_vsma"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N6.
(define_insn_reservation "cortex_a9_neon_mul_ddd_8_16_qdd_16_8_long_32_16_long" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long"))
+ (eq_attr "type" "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a9_neon_mul_qqq_8_16_32_ddd_32" 7
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mul_qqq_8_16_32_ddd_32"))
+ (eq_attr "type" "neon_mul_qqq_8_16_32_ddd_32"))
"cortex_a9_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a9_neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar" 7
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))
+ (eq_attr "type" "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar"))
"cortex_a9_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -216,7 +216,7 @@
;; produce a result at N6.
(define_insn_reservation "cortex_a9_neon_mla_ddd_8_16_qdd_16_8_long_32_16_long" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long"))
+ (eq_attr "type" "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -224,7 +224,7 @@
;; produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a9_neon_mla_qqq_8_16" 7
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mla_qqq_8_16"))
+ (eq_attr "type" "neon_mla_qqq_8_16"))
"cortex_a9_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -232,7 +232,7 @@
;; produce a result at N6 on cycle 2.
(define_insn_reservation "cortex_a9_neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long" 7
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
+ (eq_attr "type" "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long"))
"cortex_a9_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -240,21 +240,21 @@
;; produce a result at N6 on cycle 4.
(define_insn_reservation "cortex_a9_neon_mla_qqq_32_qqd_32_scalar" 9
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mla_qqq_32_qqd_32_scalar"))
+ (eq_attr "type" "neon_mla_qqq_32_qqd_32_scalar"))
"cortex_a9_neon_dp_4")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N6.
(define_insn_reservation "cortex_a9_neon_mul_ddd_16_scalar_32_16_long_scalar" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mul_ddd_16_scalar_32_16_long_scalar"))
+ (eq_attr "type" "neon_mul_ddd_16_scalar_32_16_long_scalar"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N6 on cycle 4.
(define_insn_reservation "cortex_a9_neon_mul_qqd_32_scalar" 9
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mul_qqd_32_scalar"))
+ (eq_attr "type" "neon_mul_qqd_32_scalar"))
"cortex_a9_neon_dp_4")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -262,84 +262,84 @@
;; produce a result at N6.
(define_insn_reservation "cortex_a9_neon_mla_ddd_16_scalar_qdd_32_16_long_scalar" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar"))
+ (eq_attr "type" "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N3.
(define_insn_reservation "cortex_a9_neon_shift_1" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_shift_1"))
+ (eq_attr "type" "neon_shift_1"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N4.
(define_insn_reservation "cortex_a9_neon_shift_2" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_shift_2"))
+ (eq_attr "type" "neon_shift_2"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N3 on cycle 2.
(define_insn_reservation "cortex_a9_neon_shift_3" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_shift_3"))
+ (eq_attr "type" "neon_shift_3"))
"cortex_a9_neon_dp_2")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N1.
(define_insn_reservation "cortex_a9_neon_vshl_ddd" 1
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vshl_ddd"))
+ (eq_attr "type" "neon_vshl_ddd"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N4 on cycle 2.
(define_insn_reservation "cortex_a9_neon_vqshl_vrshl_vqrshl_qqq" 5
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vqshl_vrshl_vqrshl_qqq"))
+ (eq_attr "type" "neon_vqshl_vrshl_vqrshl_qqq"))
"cortex_a9_neon_dp_2")
;; Instructions using this reservation read their (D|Q)m operands at N1,
;; their (D|Q)d operands at N3, and produce a result at N6.
(define_insn_reservation "cortex_a9_neon_vsra_vrsra" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vsra_vrsra"))
+ (eq_attr "type" "neon_vsra_vrsra"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N5.
(define_insn_reservation "cortex_a9_neon_fp_vadd_ddd_vabs_dd" 5
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd"))
+ (eq_attr "type" "neon_fp_vadd_ddd_vabs_dd"))
"cortex_a9_neon_fadd")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N5 on cycle 2.
(define_insn_reservation "cortex_a9_neon_fp_vadd_qqq_vabs_qq" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vadd_qqq_vabs_qq"))
+ (eq_attr "type" "neon_fp_vadd_qqq_vabs_qq"))
"cortex_a9_neon_fadd_2")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N5.
(define_insn_reservation "cortex_a9_neon_fp_vsum" 5
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vsum"))
+ (eq_attr "type" "neon_fp_vsum"))
"cortex_a9_neon_fadd")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N5.
(define_insn_reservation "cortex_a9_neon_fp_vmul_ddd" 5
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vmul_ddd"))
+ (eq_attr "type" "neon_fp_vmul_ddd"))
"cortex_a9_neon_dp")
;; Instructions using this reservation read their (D|Q)n operands at N2,
;; their (D|Q)m operands at N1, and produce a result at N5 on cycle 2.
(define_insn_reservation "cortex_a9_neon_fp_vmul_qqd" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vmul_qqd"))
+ (eq_attr "type" "neon_fp_vmul_qqd"))
"cortex_a9_neon_dp_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -347,7 +347,7 @@
;; produce a result at N9.
(define_insn_reservation "cortex_a9_neon_fp_vmla_ddd" 9
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vmla_ddd"))
+ (eq_attr "type" "neon_fp_vmla_ddd"))
"cortex_a9_neon_fmul_then_fadd")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -355,7 +355,7 @@
;; produce a result at N9 on cycle 2.
(define_insn_reservation "cortex_a9_neon_fp_vmla_qqq" 10
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vmla_qqq"))
+ (eq_attr "type" "neon_fp_vmla_qqq"))
"cortex_a9_neon_fmul_then_fadd_2")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -363,7 +363,7 @@
;; produce a result at N9.
(define_insn_reservation "cortex_a9_neon_fp_vmla_ddd_scalar" 9
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vmla_ddd_scalar"))
+ (eq_attr "type" "neon_fp_vmla_ddd_scalar"))
"cortex_a9_neon_fmul_then_fadd")
;; Instructions using this reservation read their (D|Q)n operands at N2,
@@ -371,152 +371,152 @@
;; produce a result at N9 on cycle 2.
(define_insn_reservation "cortex_a9_neon_fp_vmla_qqq_scalar" 10
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vmla_qqq_scalar"))
+ (eq_attr "type" "neon_fp_vmla_qqq_scalar"))
"cortex_a9_neon_fmul_then_fadd_2")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N9.
(define_insn_reservation "cortex_a9_neon_fp_vrecps_vrsqrts_ddd" 9
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vrecps_vrsqrts_ddd"))
+ (eq_attr "type" "neon_fp_vrecps_vrsqrts_ddd"))
"cortex_a9_neon_fmul_then_fadd")
;; Instructions using this reservation read their source operands at N2, and
;; produce a result at N9 on cycle 2.
(define_insn_reservation "cortex_a9_neon_fp_vrecps_vrsqrts_qqq" 10
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_fp_vrecps_vrsqrts_qqq"))
+ (eq_attr "type" "neon_fp_vrecps_vrsqrts_qqq"))
"cortex_a9_neon_fmul_then_fadd_2")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2.
(define_insn_reservation "cortex_a9_neon_bp_simple" 2
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_bp_simple"))
+ (eq_attr "type" "neon_bp_simple"))
"cortex_a9_neon_perm")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2 on cycle 2.
(define_insn_reservation "cortex_a9_neon_bp_2cycle" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_bp_2cycle"))
+ (eq_attr "type" "neon_bp_2cycle"))
"cortex_a9_neon_perm_2")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2 on cycle 3.
(define_insn_reservation "cortex_a9_neon_bp_3cycle" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_bp_3cycle"))
+ (eq_attr "type" "neon_bp_3cycle"))
"cortex_a9_neon_perm_3")
;; Instructions using this reservation produce a result at N1.
(define_insn_reservation "cortex_a9_neon_ldr" 1
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_ldr"))
+ (eq_attr "type" "neon_ldr"))
"cortex_a9_neon_ls")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a9_neon_str" 0
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_str"))
+ (eq_attr "type" "neon_str"))
"cortex_a9_neon_ls")
;; Instructions using this reservation produce a result at N1 on cycle 2.
(define_insn_reservation "cortex_a9_neon_vld1_1_2_regs" 2
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vld1_1_2_regs"))
+ (eq_attr "type" "neon_vld1_1_2_regs"))
"cortex_a9_neon_ls_2")
;; Instructions using this reservation produce a result at N1 on cycle 3.
(define_insn_reservation "cortex_a9_neon_vld1_3_4_regs" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vld1_3_4_regs"))
+ (eq_attr "type" "neon_vld1_3_4_regs"))
"cortex_a9_neon_ls_3")
;; Instructions using this reservation produce a result at N2 on cycle 2.
(define_insn_reservation "cortex_a9_neon_vld2_2_regs_vld1_vld2_all_lanes" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes"))
+ (eq_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes"))
"cortex_a9_neon_ls_2")
;; Instructions using this reservation produce a result at N2 on cycle 3.
(define_insn_reservation "cortex_a9_neon_vld2_4_regs" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vld2_4_regs"))
+ (eq_attr "type" "neon_vld2_4_regs"))
"cortex_a9_neon_ls_3")
;; Instructions using this reservation produce a result at N2 on cycle 4.
(define_insn_reservation "cortex_a9_neon_vld3_vld4" 5
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vld3_vld4"))
+ (eq_attr "type" "neon_vld3_vld4"))
"cortex_a9_neon_ls_4")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a9_neon_vst1_1_2_regs_vst2_2_regs" 0
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs"))
+ (eq_attr "type" "neon_vst1_1_2_regs_vst2_2_regs"))
"cortex_a9_neon_ls_2")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a9_neon_vst1_3_4_regs" 0
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vst1_3_4_regs"))
+ (eq_attr "type" "neon_vst1_3_4_regs"))
"cortex_a9_neon_ls_3")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a9_neon_vst2_4_regs_vst3_vst4" 0
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vst2_4_regs_vst3_vst4"))
+ (eq_attr "type" "neon_vst2_4_regs_vst3_vst4"))
"cortex_a9_neon_ls_4")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a9_neon_vst3_vst4" 0
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vst3_vst4"))
+ (eq_attr "type" "neon_vst3_vst4"))
"cortex_a9_neon_ls_4")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2 on cycle 3.
(define_insn_reservation "cortex_a9_neon_vld1_vld2_lane" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vld1_vld2_lane"))
+ (eq_attr "type" "neon_vld1_vld2_lane"))
"cortex_a9_neon_ls_3")
;; Instructions using this reservation read their source operands at N1, and
;; produce a result at N2 on cycle 5.
(define_insn_reservation "cortex_a9_neon_vld3_vld4_lane" 6
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vld3_vld4_lane"))
+ (eq_attr "type" "neon_vld3_vld4_lane"))
"cortex_a9_neon_ls_5")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a9_neon_vst1_vst2_lane" 0
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vst1_vst2_lane"))
+ (eq_attr "type" "neon_vst1_vst2_lane"))
"cortex_a9_neon_ls_2")
;; Instructions using this reservation read their source operands at N1.
(define_insn_reservation "cortex_a9_neon_vst3_vst4_lane" 0
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vst3_vst4_lane"))
+ (eq_attr "type" "neon_vst3_vst4_lane"))
"cortex_a9_neon_ls_3")
;; Instructions using this reservation produce a result at N2 on cycle 2.
(define_insn_reservation "cortex_a9_neon_vld3_vld4_all_lanes" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_vld3_vld4_all_lanes"))
+ (eq_attr "type" "neon_vld3_vld4_all_lanes"))
"cortex_a9_neon_ls_3")
;; Instructions using this reservation produce a result at N2.
(define_insn_reservation "cortex_a9_neon_mcr" 2
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mcr"))
+ (eq_attr "type" "neon_mcr"))
"cortex_a9_neon_perm")
;; Instructions using this reservation produce a result at N2.
(define_insn_reservation "cortex_a9_neon_mcr_2_mcrr" 2
(and (eq_attr "tune" "cortexa9")
- (eq_attr "neon_type" "neon_mcr_2_mcrr"))
+ (eq_attr "type" "neon_mcr_2_mcrr"))
"cortex_a9_neon_perm_2")
;; Exceptions to the default latencies.
diff --git a/gcc/config/arm/cortex-a9.md b/gcc/config/arm/cortex-a9.md
index 11dc0b32c38..7c62d8489ae 100644
--- a/gcc/config/arm/cortex-a9.md
+++ b/gcc/config/arm/cortex-a9.md
@@ -80,17 +80,24 @@ cortex_a9_p1_e2 + cortex_a9_p0_e1 + cortex_a9_p1_e1")
;; which can go down E2 without any problem.
(define_insn_reservation "cortex_a9_dp" 2
(and (eq_attr "tune" "cortexa9")
- (and (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,mvn_imm,mvn_reg,\
- mov_shift_reg,mov_shift")
- (eq_attr "neon_type" "none")))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,mvn_imm,mvn_reg,\
+ mov_shift_reg,mov_shift,\
+ mrs,multiple,no_insn"))
"cortex_a9_p0_default|cortex_a9_p1_default")
;; An instruction using the shifter will go down E1.
(define_insn_reservation "cortex_a9_dp_shift" 3
(and (eq_attr "tune" "cortexa9")
- (eq_attr "type" "arlo_shift_reg,extend,arlo_shift,\
- mvn_shift,mvn_shift_reg"))
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ extend,mvn_shift,mvn_shift_reg"))
"cortex_a9_p0_shift | cortex_a9_p1_shift")
;; Loads have a latency of 4 cycles.
@@ -200,7 +207,7 @@ cortex_a9_store3_4, cortex_a9_store1_2, cortex_a9_load3_4")
;; Pipelining for VFP instructions.
;; Issue happens either along load store unit or the VFP / Neon unit.
;; Pipeline Instruction Classification.
-;; FPS - fcpys, ffariths, ffarithd,r_2_f,f_2_r
+;; FPS - fmov, ffariths, ffarithd,f_mcr,f_mcrr,f_mrc,f_mrrc
;; FP_ADD - fadds, faddd, fcmps (1)
;; FPMUL - fmul{s,d}, fmac{s,d}, ffma{s,d}
;; FPDIV - fdiv{s,d}
@@ -213,7 +220,8 @@ cortex_a9_store3_4, cortex_a9_store1_2, cortex_a9_load3_4")
;; fmrs, fmrrd, fmstat and fmrx - The data is available after 1 cycle.
(define_insn_reservation "cortex_a9_fps" 2
(and (eq_attr "tune" "cortexa9")
- (eq_attr "type" "fcpys, fconsts, fconstd, ffariths, ffarithd, r_2_f, f_2_r, f_flag"))
+ (eq_attr "type" "fmov, fconsts, fconstd, ffariths, ffarithd,\
+ f_mcr, f_mcrr, f_mrc, f_mrrc, f_flag"))
"ca9_issue_vfp_neon + ca9fps")
(define_bypass 1
@@ -225,7 +233,7 @@ cortex_a9_store3_4, cortex_a9_store1_2, cortex_a9_load3_4")
(define_insn_reservation "cortex_a9_fadd" 4
(and (eq_attr "tune" "cortexa9")
- (eq_attr "type" "fadds, faddd, f_cvt"))
+ (eq_attr "type" "fadds, faddd, f_cvt, f_cvtf2i, f_cvti2f"))
"ca9fp_add")
(define_insn_reservation "cortex_a9_fcmp" 1
@@ -263,12 +271,12 @@ cortex_a9_store3_4, cortex_a9_store1_2, cortex_a9_load3_4")
;; Division pipeline description.
(define_insn_reservation "cortex_a9_fdivs" 15
(and (eq_attr "tune" "cortexa9")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"ca9fp_ds1 + ca9_issue_vfp_neon, nothing*14")
(define_insn_reservation "cortex_a9_fdivd" 25
(and (eq_attr "tune" "cortexa9")
- (eq_attr "type" "fdivd"))
+ (eq_attr "type" "fdivd, fsqrtd"))
"ca9fp_ds1 + ca9_issue_vfp_neon, nothing*24")
;; Include Neon pipeline description
diff --git a/gcc/config/arm/cortex-m4-fpu.md b/gcc/config/arm/cortex-m4-fpu.md
index 4ce3f10f0de..2190938b65c 100644
--- a/gcc/config/arm/cortex-m4-fpu.md
+++ b/gcc/config/arm/cortex-m4-fpu.md
@@ -30,17 +30,17 @@
;; Integer instructions following VDIV or VSQRT complete out-of-order.
(define_insn_reservation "cortex_m4_fdivs" 15
(and (eq_attr "tune" "cortexm4")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"cortex_m4_ex_v,cortex_m4_v*13")
(define_insn_reservation "cortex_m4_vmov_1" 1
(and (eq_attr "tune" "cortexm4")
- (eq_attr "type" "fcpys,fconsts"))
+ (eq_attr "type" "fmov,fconsts"))
"cortex_m4_ex_v")
(define_insn_reservation "cortex_m4_vmov_2" 2
(and (eq_attr "tune" "cortexm4")
- (eq_attr "type" "f_2_r,r_2_f"))
+ (eq_attr "type" "f_mrc,f_mrrc,f_mcr,f_mcrr"))
"cortex_m4_ex_v*2")
(define_insn_reservation "cortex_m4_fmuls" 2
@@ -77,7 +77,7 @@
(define_insn_reservation "cortex_m4_f_cvt" 2
(and (eq_attr "tune" "cortexm4")
- (eq_attr "type" "f_cvt"))
+ (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f"))
"cortex_m4_ex_v")
(define_insn_reservation "cortex_m4_f_load" 2
diff --git a/gcc/config/arm/cortex-m4.md b/gcc/config/arm/cortex-m4.md
index 53bd60cd98f..9ae4cc3143b 100644
--- a/gcc/config/arm/cortex-m4.md
+++ b/gcc/config/arm/cortex-m4.md
@@ -31,10 +31,18 @@
;; ALU and multiply is one cycle.
(define_insn_reservation "cortex_m4_alu" 1
(and (eq_attr "tune" "cortexm4")
- (ior (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,extend,\
- arlo_shift,arlo_shift_reg,\
+ (ior (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,extend,\
+ alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
mov_imm,mov_reg,mov_shift,mov_shift_reg,\
- mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg")
+ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg,\
+ mrs,multiple,no_insn")
(ior (eq_attr "mul32" "yes")
(eq_attr "mul64" "yes"))))
"cortex_m4_ex")
diff --git a/gcc/config/arm/cortex-r4.md b/gcc/config/arm/cortex-r4.md
index 597774dbd89..7a3ceeb15d7 100644
--- a/gcc/config/arm/cortex-r4.md
+++ b/gcc/config/arm/cortex-r4.md
@@ -78,7 +78,11 @@
;; for the purposes of the dual-issue constraints above.
(define_insn_reservation "cortex_r4_alu" 2
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,mvn_imm,mvn_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,mvn_imm,mvn_reg"))
"cortex_r4_alu")
(define_insn_reservation "cortex_r4_mov" 2
@@ -88,12 +92,17 @@
(define_insn_reservation "cortex_r4_alu_shift" 2
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "extend,arlo_shift,mov_shift,mvn_shift"))
+ (eq_attr "type" "alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ extend,mov_shift,mvn_shift"))
"cortex_r4_alu")
(define_insn_reservation "cortex_r4_alu_shift_reg" 2
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "arlo_shift_reg,mov_shift_reg,mvn_shift_reg"))
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
+ mov_shift_reg,mvn_shift_reg,\
+ mrs,multiple,no_insn"))
"cortex_r4_alu_shift_reg")
;; An ALU instruction followed by an ALU instruction with no early dep.
diff --git a/gcc/config/arm/cortex-r4f.md b/gcc/config/arm/cortex-r4f.md
index 0c0bae0cd74..1bc4249d4d1 100644
--- a/gcc/config/arm/cortex-r4f.md
+++ b/gcc/config/arm/cortex-r4f.md
@@ -48,7 +48,7 @@
(define_insn_reservation "cortex_r4_fcpys" 2
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "fcpys"))
+ (eq_attr "type" "fmov"))
"cortex_r4_issue_ab")
(define_insn_reservation "cortex_r4_ffariths" 2
@@ -68,7 +68,7 @@
(define_insn_reservation "cortex_r4_fdivs" 17
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"cortex_r4_issue_ab+cortex_r4_v1,cortex_r4_issue_a+cortex_r4_v1")
(define_insn_reservation "cortex_r4_floads" 2
@@ -83,12 +83,12 @@
(define_insn_reservation "cortex_r4_mcr" 2
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "r_2_f"))
+ (eq_attr "type" "f_mcr,f_mcrr"))
"cortex_r4_issue_ab")
(define_insn_reservation "cortex_r4_mrc" 3
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "f_2_r"))
+ (eq_attr "type" "f_mrc,f_mrrc"))
"cortex_r4_issue_ab")
;; Bypasses for normal (not early) regs.
@@ -131,7 +131,7 @@
;; out of order. Chances are this is not a pipelined operation.
(define_insn_reservation "cortex_r4_fdivd" 97
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "fdivd"))
+ (eq_attr "type" "fdivd, fsqrtd"))
"cortex_r4_single_issue*3")
(define_insn_reservation "cortex_r4_ffarithd" 2
@@ -146,7 +146,7 @@
(define_insn_reservation "cortex_r4_f_cvt" 8
(and (eq_attr "tune_cortexr4" "yes")
- (eq_attr "type" "f_cvt"))
+ (eq_attr "type" "f_cvt,f_cvtf2i,f_cvti2f"))
"cortex_r4_single_issue*3")
(define_insn_reservation "cortex_r4_f_memd" 8
diff --git a/gcc/config/arm/fa526.md b/gcc/config/arm/fa526.md
index 9ec92d60dc5..401abd3c0a0 100644
--- a/gcc/config/arm/fa526.md
+++ b/gcc/config/arm/fa526.md
@@ -62,13 +62,22 @@
;; ALU operations
(define_insn_reservation "526_alu_op" 1
(and (eq_attr "tune" "fa526")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,mvn_imm,mvn_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,mvn_imm,mvn_reg,\
+ mrs,multiple,no_insn"))
"fa526_core")
(define_insn_reservation "526_alu_shift_op" 2
(and (eq_attr "tune" "fa526")
- (eq_attr "type" "extend,arlo_shift,arlo_shift_reg,\
+ (eq_attr "type" "extend,\
+ alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
mov_shift,mov_shift_reg,\
mvn_shift,mvn_shift_reg"))
"fa526_core")
diff --git a/gcc/config/arm/fa606te.md b/gcc/config/arm/fa606te.md
index e61242886d7..88347bc2d96 100644
--- a/gcc/config/arm/fa606te.md
+++ b/gcc/config/arm/fa606te.md
@@ -62,10 +62,18 @@
;; ALU operations
(define_insn_reservation "606te_alu_op" 1
(and (eq_attr "tune" "fa606te")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,
- extend,arlo_shift,arlo_shift_reg,\
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,extend,\
+ alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
mov_imm,mov_reg,mov_shift,mov_shift_reg,\
- mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg"))
+ mvn_imm,mvn_reg,mvn_shift,mvn_shift_reg,\
+ mrs,multiple,no_insn"))
"fa606te_core")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/gcc/config/arm/fa626te.md b/gcc/config/arm/fa626te.md
index 04d2a5cf33f..e6790a21215 100644
--- a/gcc/config/arm/fa626te.md
+++ b/gcc/config/arm/fa626te.md
@@ -68,13 +68,22 @@
;; ALU operations
(define_insn_reservation "626te_alu_op" 1
(and (eq_attr "tune" "fa626,fa626te")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
- mov_imm,mov_reg,mvn_imm,mvn_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mov_imm,mov_reg,mvn_imm,mvn_reg,\
+ mrs,multiple,no_insn"))
"fa626te_core")
(define_insn_reservation "626te_alu_shift_op" 2
(and (eq_attr "tune" "fa626,fa626te")
- (eq_attr "type" "extend,arlo_shift,arlo_shift_reg,\
+ (eq_attr "type" "extend,\
+ alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm,\
+ alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg,\
mov_shift,mov_shift_reg,\
mvn_shift,mvn_shift_reg"))
"fa626te_core")
diff --git a/gcc/config/arm/fa726te.md b/gcc/config/arm/fa726te.md
index 342b9bf5d33..d0a03981eec 100644
--- a/gcc/config/arm/fa726te.md
+++ b/gcc/config/arm/fa726te.md
@@ -86,7 +86,12 @@
;; Other ALU instructions 2 cycles.
(define_insn_reservation "726te_alu_op" 1
(and (eq_attr "tune" "fa726te")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg"))
+ (eq_attr "type" "alu_imm,alus_imm,logic_imm,logics_imm,\
+ alu_reg,alus_reg,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
+ mrs,multiple,no_insn"))
"fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)")
;; ALU operations with a shift-by-register operand.
@@ -95,12 +100,14 @@
;; it takes 3 cycles.
(define_insn_reservation "726te_alu_shift_op" 3
(and (eq_attr "tune" "fa726te")
- (eq_attr "type" "extend,arlo_shift"))
+ (eq_attr "type" "extend,alu_shift_imm,alus_shift_imm,\
+ logic_shift_imm,logics_shift_imm"))
"fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)")
(define_insn_reservation "726te_alu_shift_reg_op" 3
(and (eq_attr "tune" "fa726te")
- (eq_attr "type" "arlo_shift_reg"))
+ (eq_attr "type" "alu_shift_reg,alus_shift_reg,\
+ logic_shift_reg,logics_shift_reg"))
"fa726te_issue+(fa726te_alu0_pipe|fa726te_alu1_pipe)")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Multiplication Instructions
diff --git a/gcc/config/arm/fmp626.md b/gcc/config/arm/fmp626.md
index 944645b9ead..ffb68570e37 100644
--- a/gcc/config/arm/fmp626.md
+++ b/gcc/config/arm/fmp626.md
@@ -63,13 +63,19 @@
;; ALU operations
(define_insn_reservation "mp626_alu_op" 1
(and (eq_attr "tune" "fmp626")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg,\
+ (eq_attr "type" "alu_imm,alus_imm,alu_reg,alus_reg,\
+ logic_imm,logics_imm,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg,\
mov_imm,mov_reg,mvn_imm,mvn_reg"))
"fmp626_core")
(define_insn_reservation "mp626_alu_shift_op" 2
(and (eq_attr "tune" "fmp626")
- (eq_attr "type" "extend,arlo_shift,arlo_shift_reg,\
+ (eq_attr "type" "alu_shift_imm,logic_shift_imm,alus_shift_imm,logics_shift_imm,\
+ alu_shift_reg,logic_shift_reg,alus_shift_reg,logics_shift_reg,\
+ extend,\
mov_shift,mov_shift_reg,\
mvn_shift,mvn_shift_reg"))
"fmp626_core")
diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md
index d84929f3d1f..c7d7079b9de 100644
--- a/gcc/config/arm/iterators.md
+++ b/gcc/config/arm/iterators.md
@@ -391,7 +391,7 @@
(define_mode_attr scalar_mul_constraint [(V4HI "x") (V2SI "t") (V2SF "t")
(V8HI "x") (V4SI "t") (V4SF "t")])
-;; Predicates used for setting neon_type
+;; Predicates used for setting type for neon instructions
(define_mode_attr Is_float_mode [(V8QI "false") (V16QI "false")
(V4HI "false") (V8HI "false")
diff --git a/gcc/config/arm/iwmmxt.md b/gcc/config/arm/iwmmxt.md
index f1f0a5c5150..62cdae21e3f 100644
--- a/gcc/config/arm/iwmmxt.md
+++ b/gcc/config/arm/iwmmxt.md
@@ -155,7 +155,8 @@
(const_int 8)
(const_int 4))]
(const_int 4)))
- (set_attr "type" "*,*,*,load2,store2,wmmx_wmov,wmmx_tmcrr,wmmx_tmrrc,wmmx_wldr,wmmx_wstr,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
+ (set_attr "type" "*,*,*,load2,store2,*,*,*,*,*,f_mcrr,f_mrrc,\
+ ffarithd,f_loadd,f_stored")
(set_attr "arm_pool_range" "*,*,*,1020,*,*,*,*,*,*,*,*,*,1020,*")
(set_attr "arm_neg_pool_range" "*,*,*,1008,*,*,*,*,*,*,*,*,*,1008,*")]
)
@@ -187,7 +188,8 @@
default:
gcc_unreachable ();
}"
- [(set_attr "type" "*,*,*,*,load1,store1,wmmx_tmcr,wmmx_tmrc,wmmx_wldr,wmmx_wstr,r_2_f,f_2_r,fcpys,f_loads,f_stores")
+ [(set_attr "type" "*,*,*,*,load1,store1,*,*,*,*,f_mcr,f_mrc,\
+ fmov,f_loads,f_stores")
(set_attr "length" "*,*,*,*,*, *,*,*, 16, *,*,*,*,*,*")
(set_attr "pool_range" "*,*,*,*,4096, *,*,*,1024, *,*,*,*,1020,*")
(set_attr "neg_pool_range" "*,*,*,*,4084, *,*,*, *, 1012,*,*,*,1008,*")
diff --git a/gcc/config/arm/linux-eabi.h b/gcc/config/arm/linux-eabi.h
index cb0aad19c34..232c38d28ff 100644
--- a/gcc/config/arm/linux-eabi.h
+++ b/gcc/config/arm/linux-eabi.h
@@ -85,7 +85,7 @@
LINUX_TARGET_LINK_SPEC " " ANDROID_LINK_SPEC)
#undef ASAN_CC1_SPEC
-#define ASAN_CC1_SPEC "%{fsanitize=*:-funwind-tables}"
+#define ASAN_CC1_SPEC "%{%:sanitize(address):-funwind-tables}"
#undef CC1_SPEC
#define CC1_SPEC \
@@ -99,7 +99,7 @@
#undef LIB_SPEC
#define LIB_SPEC \
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \
- GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC)
+ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC " " ANDROID_LIB_SPEC)
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
diff --git a/gcc/config/arm/linux-elf.h b/gcc/config/arm/linux-elf.h
index 488efa4ba15..475e22079fc 100644
--- a/gcc/config/arm/linux-elf.h
+++ b/gcc/config/arm/linux-elf.h
@@ -44,9 +44,9 @@
#define SUBTARGET_EXTRA_LINK_SPEC " -m " TARGET_LINKER_EMULATION " -p"
+/* We do not have any MULTILIB_OPTIONS specified, so there are no
+ MULTILIB_DEFAULTS. */
#undef MULTILIB_DEFAULTS
-#define MULTILIB_DEFAULTS \
- { "marm", "mlittle-endian", "mfloat-abi=hard", "mno-thumb-interwork" }
/* Now we define the strings used to build the spec file. */
#undef LIB_SPEC
diff --git a/gcc/config/arm/marvell-pj4.md b/gcc/config/arm/marvell-pj4.md
index 0e2c443721e..880789600e0 100644
--- a/gcc/config/arm/marvell-pj4.md
+++ b/gcc/config/arm/marvell-pj4.md
@@ -53,26 +53,42 @@
(define_insn_reservation "pj4_alu" 1
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg")
+ (eq_attr "type" "alu_imm,alus_imm,alu_reg,alus_reg,\
+ logic_imm,logics_imm,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg")
(not (eq_attr "conds" "set")))
"pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)")
(define_insn_reservation "pj4_alu_conds" 4
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "arlo_imm,arlo_reg,shift,shift_reg")
+ (eq_attr "type" "alu_imm,alus_imm,alu_reg,alus_reg,\
+ logic_imm,logics_imm,logic_reg,logics_reg,\
+ adc_imm,adcs_imm,adc_reg,adcs_reg,\
+ adr,bfm,rev,\
+ shift_imm,shift_reg")
(eq_attr "conds" "set"))
"pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)")
(define_insn_reservation "pj4_shift" 1
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\
+ (eq_attr "type" "alu_shift_imm,logic_shift_imm,\
+ alus_shift_imm,logics_shift_imm,\
+ alu_shift_reg,logic_shift_reg,\
+ alus_shift_reg,logics_shift_reg,\
+ extend,\
mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg")
(not (eq_attr "conds" "set"))
(eq_attr "shift" "1")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)")
(define_insn_reservation "pj4_shift_conds" 4
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\
+ (eq_attr "type" "alu_shift_imm,logic_shift_imm,\
+ alus_shift_imm,logics_shift_imm,\
+ alu_shift_reg,logic_shift_reg,\
+ alus_shift_reg,logics_shift_reg,\
+ extend,\
mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg")
(eq_attr "conds" "set")
(eq_attr "shift" "1")) "pj4_is,(pj4_alu1,pj4_w1+pj4_cp)|(pj4_alu2,pj4_w2+pj4_cp)")
@@ -80,14 +96,20 @@
(define_insn_reservation "pj4_alu_shift" 1
(and (eq_attr "tune" "marvell_pj4")
(not (eq_attr "conds" "set"))
- (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\
+ (eq_attr "type" "alu_shift_imm,logic_shift_imm,\
+ alus_shift_imm,logics_shift_imm,\
+ alu_shift_reg,logic_shift_reg,\
+ alus_shift_reg,logics_shift_reg,\
+ extend,\
mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg"))
"pj4_is,(pj4_alu1,nothing,pj4_w1+pj4_cp)|(pj4_alu2,nothing,pj4_w2+pj4_cp)")
(define_insn_reservation "pj4_alu_shift_conds" 4
(and (eq_attr "tune" "marvell_pj4")
(eq_attr "conds" "set")
- (eq_attr "type" "arlo_shift,arlo_shift_reg,extend,\
+ (eq_attr "type" "alu_shift_imm,logic_shift_imm,alus_shift_imm,logics_shift_imm,\
+ alu_shift_reg,logic_shift_reg,alus_shift_reg,logics_shift_reg,\
+ extend,\
mov_shift,mvn_shift,mov_shift_reg,mvn_shift_reg"))
"pj4_is,(pj4_alu1,nothing,pj4_w1+pj4_cp)|(pj4_alu2,nothing,pj4_w2+pj4_cp)")
@@ -171,11 +193,11 @@
(define_insn_reservation "pj4_vfp_divs" 20
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "fdivs")) "pj4_is,nothing*2,vissue,vdiv*18,nothing")
+ (eq_attr "type" "fdivs, fsqrts")) "pj4_is,nothing*2,vissue,vdiv*18,nothing")
(define_insn_reservation "pj4_vfp_divd" 34
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "fdivd")) "pj4_is,nothing*2,vissue,vdiv*32,nothing")
+ (eq_attr "type" "fdivd, fsqrtd")) "pj4_is,nothing*2,vissue,vdiv*32,nothing")
(define_insn_reservation "pj4_vfp_mac" 9
(and (eq_attr "tune" "marvell_pj4")
@@ -186,8 +208,9 @@
(define_insn_reservation "pj4_vfp_cpy" 4
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "fcpys,ffariths,ffarithd,fconsts,fconstd,\
- fcmps,fcmpd,f_cvt")) "pj4_is,nothing*2,vissue,vfast,nothing*2")
+ (eq_attr "type" "fmov,ffariths,ffarithd,fconsts,fconstd,\
+ fcmps,fcmpd,f_cvt,f_cvtf2i,f_cvti2f"))
+"pj4_is,nothing*2,vissue,vfast,nothing*2")
;; Enlarge latency, and wish that more nondependent insns are
;; scheduled immediately after VFP load.
@@ -201,9 +224,9 @@
(define_insn_reservation "pj4_vfp_to_core" 7
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "f_2_r,f_flag")) "pj4_isb,nothing,nothing,vissue,vfast,nothing*2")
+ (eq_attr "type" "f_mrc,f_mrrc,f_flag")) "pj4_isb,nothing,nothing,vissue,vfast,nothing*2")
(define_insn_reservation "pj4_core_to_vfp" 2
(and (eq_attr "tune" "marvell_pj4")
- (eq_attr "type" "r_2_f")) "pj4_isb,pj4_alu1,pj4_w1,vissue,pj4_cp")
+ (eq_attr "type" "f_mcr,f_mcrr")) "pj4_isb,pj4_alu1,pj4_w1,vissue,pj4_cp")
diff --git a/gcc/config/arm/neon-schedgen.ml b/gcc/config/arm/neon-schedgen.ml
index 7dacbab2625..b3699563d48 100644
--- a/gcc/config/arm/neon-schedgen.ml
+++ b/gcc/config/arm/neon-schedgen.ml
@@ -480,7 +480,7 @@ let emit_insn_reservations core =
Printf.printf "(define_insn_reservation \"%s_%s\" %d\n"
corestring producer latency;
Printf.printf " (and (eq_attr \"tune\" \"%s\")\n" tunestring;
- Printf.printf " (eq_attr \"neon_type\" \"%s\"))\n" producer;
+ Printf.printf " (eq_attr \"type\" \"%s\"))\n" producer;
let str =
match reservation with
Mul -> "dp" | Mul_2cycle -> "dp_2" | Mul_4cycle -> "dp_4"
diff --git a/gcc/config/arm/neon.md b/gcc/config/arm/neon.md
index e8d2285fa81..ae83dba5f89 100644
--- a/gcc/config/arm/neon.md
+++ b/gcc/config/arm/neon.md
@@ -20,7 +20,7 @@
;; Attribute used to permit string comparisons against <VQH_mnem> in
-;; neon_type attribute definitions.
+;; type attribute definitions.
(define_attr "vqh_mnem" "vadd,vmin,vmax" (const_string "vadd"))
(define_insn "*neon_mov<mode>"
@@ -60,8 +60,8 @@
default: return output_move_double (operands, true, NULL);
}
}
- [(set_attr "neon_type" "neon_int_1,*,neon_vmov,*,neon_mrrc,neon_mcr_2_mcrr,*,*,*")
- (set_attr "type" "*,f_stored,*,f_loadd,*,*,mov_reg,load2,store2")
+ [(set_attr "type" "neon_int_1,f_stored,neon_vmov,f_loadd,neon_mrrc,\
+ neon_mcr_2_mcrr,mov_reg,load2,store2")
(set_attr "length" "4,4,4,4,4,4,8,8,8")
(set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*")
(set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*")
@@ -104,9 +104,8 @@
default: return output_move_quad (operands);
}
}
- [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
- neon_mrrc,neon_mcr_2_mcrr,*,*,*")
- (set_attr "type" "*,*,*,*,*,*,mov_reg,load4,store4")
+ [(set_attr "type" "neon_int_1,neon_stm_2,neon_vmov,neon_ldm_2,\
+ neon_mrrc,neon_mcr_2_mcrr,mov_reg,load4,store4")
(set_attr "length" "4,8,4,8,8,8,16,8,16")
(set_attr "arm_pool_range" "*,*,*,1020,*,*,*,1020,*")
(set_attr "thumb2_pool_range" "*,*,*,1018,*,*,*,1018,*")
@@ -150,7 +149,7 @@
default: gcc_unreachable ();
}
}
- [(set_attr "neon_type" "neon_int_1,neon_stm_2,neon_ldm_2")
+ [(set_attr "type" "neon_int_1,neon_stm_2,neon_ldm_2")
(set (attr "length") (symbol_ref "arm_attr_length_move_neon (insn)"))])
(define_split
@@ -242,7 +241,7 @@
[(set (match_operand:VDQX 0 "neon_perm_struct_or_reg_operand")
(unspec:VDQX [(match_operand:VDQX 1 "neon_perm_struct_or_reg_operand")]
UNSPEC_MISALIGNED_ACCESS))]
- "TARGET_NEON && !BYTES_BIG_ENDIAN"
+ "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
{
/* This pattern is not permitted to fail during expansion: if both arguments
are non-registers (e.g. memory := constant, which can be created by the
@@ -256,35 +255,35 @@
[(set (match_operand:VDX 0 "neon_permissive_struct_operand" "=Um")
(unspec:VDX [(match_operand:VDX 1 "s_register_operand" " w")]
UNSPEC_MISALIGNED_ACCESS))]
- "TARGET_NEON && !BYTES_BIG_ENDIAN"
+ "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
"vst1.<V_sz_elem>\t{%P1}, %A0"
- [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
+ [(set_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")])
(define_insn "*movmisalign<mode>_neon_load"
[(set (match_operand:VDX 0 "s_register_operand" "=w")
(unspec:VDX [(match_operand:VDX 1 "neon_permissive_struct_operand"
" Um")]
UNSPEC_MISALIGNED_ACCESS))]
- "TARGET_NEON && !BYTES_BIG_ENDIAN"
+ "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
"vld1.<V_sz_elem>\t{%P0}, %A1"
- [(set_attr "neon_type" "neon_vld1_1_2_regs")])
+ [(set_attr "type" "neon_vld1_1_2_regs")])
(define_insn "*movmisalign<mode>_neon_store"
[(set (match_operand:VQX 0 "neon_permissive_struct_operand" "=Um")
(unspec:VQX [(match_operand:VQX 1 "s_register_operand" " w")]
UNSPEC_MISALIGNED_ACCESS))]
- "TARGET_NEON && !BYTES_BIG_ENDIAN"
+ "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
"vst1.<V_sz_elem>\t{%q1}, %A0"
- [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
+ [(set_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")])
(define_insn "*movmisalign<mode>_neon_load"
[(set (match_operand:VQX 0 "s_register_operand" "=w")
(unspec:VQX [(match_operand:VQX 1 "neon_permissive_struct_operand"
" Um")]
UNSPEC_MISALIGNED_ACCESS))]
- "TARGET_NEON && !BYTES_BIG_ENDIAN"
+ "TARGET_NEON && !BYTES_BIG_ENDIAN && unaligned_access"
"vld1.<V_sz_elem>\t{%q0}, %A1"
- [(set_attr "neon_type" "neon_vld1_1_2_regs")])
+ [(set_attr "type" "neon_vld1_1_2_regs")])
(define_insn "vec_set<mode>_internal"
[(set (match_operand:VD 0 "s_register_operand" "=w,w")
@@ -305,7 +304,7 @@
else
return "vmov.<V_sz_elem>\t%P0[%c2], %1";
}
- [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")])
+ [(set_attr "type" "neon_vld1_vld2_lane,neon_mcr")])
(define_insn "vec_set<mode>_internal"
[(set (match_operand:VQ 0 "s_register_operand" "=w,w")
@@ -333,7 +332,7 @@
else
return "vmov.<V_sz_elem>\t%P0[%c2], %1";
}
- [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
+ [(set_attr "type" "neon_vld1_vld2_lane,neon_mcr")]
)
(define_insn "vec_setv2di_internal"
@@ -355,7 +354,7 @@
else
return "vmov\t%P0, %Q1, %R1";
}
- [(set_attr "neon_type" "neon_vld1_1_2_regs,neon_mcr_2_mcrr")]
+ [(set_attr "type" "neon_vld1_1_2_regs,neon_mcr_2_mcrr")]
)
(define_expand "vec_set<mode>"
@@ -389,7 +388,7 @@
else
return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
}
- [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
+ [(set_attr "type" "neon_vst1_vst2_lane,neon_bp_simple")]
)
(define_insn "vec_extract<mode>"
@@ -415,7 +414,7 @@
else
return "vmov.<V_uf_sclr>\t%0, %P1[%c2]";
}
- [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_bp_simple")]
+ [(set_attr "type" "neon_vst1_vst2_lane,neon_bp_simple")]
)
(define_insn "vec_extractv2di"
@@ -434,7 +433,7 @@
else
return "vmov\t%Q0, %R0, %P1 @ v2di";
}
- [(set_attr "neon_type" "neon_vst1_vst2_lane,neon_int_1")]
+ [(set_attr "type" "neon_vst1_vst2_lane,neon_int_1")]
)
(define_expand "vec_init<mode>"
@@ -457,7 +456,7 @@
(match_operand:VDQ 2 "s_register_operand" "w")))]
"TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
"vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -484,7 +483,7 @@
default: gcc_unreachable ();
}
}
- [(set_attr "neon_type" "neon_int_1,*,*,neon_int_1,*,*,*")
+ [(set_attr "type" "neon_int_1,*,*,neon_int_1,*,*,*")
(set_attr "conds" "*,clob,clob,*,clob,clob,clob")
(set_attr "length" "*,8,8,*,8,8,8")
(set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits,*,*,*")]
@@ -496,7 +495,7 @@
(match_operand:VDQ 2 "s_register_operand" "w")))]
"TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
"vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -521,7 +520,7 @@
default: gcc_unreachable ();
}
}
- [(set_attr "neon_type" "neon_int_2,*,*,*,neon_int_2")
+ [(set_attr "type" "neon_int_2,*,*,*,neon_int_2")
(set_attr "conds" "*,clob,clob,clob,*")
(set_attr "length" "*,8,8,8,*")
(set_attr "arch" "neon_for_64bits,*,*,*,avoid_neon_for_64bits")]
@@ -533,7 +532,7 @@
(match_operand:VDQ 2 "s_register_operand" "w")))]
"TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
"vmul.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -555,7 +554,7 @@
(match_operand:VDQ 1 "s_register_operand" "0")))]
"TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
"vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vmla_ddd")
@@ -577,7 +576,7 @@
(match_operand:VDQ 3 "s_register_operand" "w"))))]
"TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
"vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vmla_ddd")
@@ -604,7 +603,7 @@
(match_operand:VCVTF 3 "register_operand" "0")))]
"TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations"
"vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vmla_ddd")
(const_string "neon_fp_vmla_qqq")))]
@@ -617,7 +616,7 @@
(match_operand:VCVTF 3 "register_operand" "0")))]
"TARGET_NEON && TARGET_FMA"
"vfma%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vmla_ddd")
(const_string "neon_fp_vmla_qqq")))]
@@ -630,7 +629,7 @@
(match_operand:VCVTF 3 "register_operand" "0")))]
"TARGET_NEON && TARGET_FMA && flag_unsafe_math_optimizations"
"vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vmla_ddd")
(const_string "neon_fp_vmla_qqq")))]
@@ -643,7 +642,7 @@
(match_operand:VCVTF 3 "register_operand" "0")))]
"TARGET_NEON && TARGET_FMA"
"vfms%?.<V_if_elem>\\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vmla_ddd")
(const_string "neon_fp_vmla_qqq")))]
@@ -656,7 +655,7 @@
NEON_VRINT))]
"TARGET_NEON && TARGET_FPU_ARMV8"
"vrint<nvrint_variant>%?.f32\\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -676,7 +675,7 @@
default: gcc_unreachable ();
}
}
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
;; The concrete forms of the Neon immediate-logic instructions are vbic and
@@ -698,7 +697,7 @@
default: gcc_unreachable ();
}
}
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
(define_insn "orn<mode>3_neon"
@@ -707,7 +706,7 @@
(match_operand:VDQ 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vorn\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
;; TODO: investigate whether we should disable
@@ -745,7 +744,7 @@
DONE;
}
}"
- [(set_attr "neon_type" "neon_int_1,*,*,*")
+ [(set_attr "type" "neon_int_1,*,*,*")
(set_attr "length" "*,16,8,8")
(set_attr "arch" "any,a,t2,t2")]
)
@@ -756,7 +755,7 @@
(match_operand:VDQ 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vbic\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
;; Compare to *anddi_notdi_di.
@@ -769,7 +768,7 @@
vbic\t%P0, %P1, %P2
#
#"
- [(set_attr "neon_type" "neon_int_1,*,*")
+ [(set_attr "type" "neon_int_1,*,*")
(set_attr "length" "*,8,8")]
)
@@ -779,7 +778,7 @@
(match_operand:VDQ 2 "s_register_operand" "w")))]
"TARGET_NEON"
"veor\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
(define_insn "one_cmpl<mode>2"
@@ -787,7 +786,7 @@
(not:VDQ (match_operand:VDQ 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vmvn\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
(define_insn "abs<mode>2"
@@ -795,7 +794,7 @@
(abs:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -808,7 +807,7 @@
(neg:VDQW (match_operand:VDQW 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -861,7 +860,7 @@
(match_operand:VDQIW 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vmin.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
(define_insn "*umax<mode>3_neon"
@@ -870,7 +869,7 @@
(match_operand:VDQIW 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vmax.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
(define_insn "*smin<mode>3_neon"
@@ -879,7 +878,7 @@
(match_operand:VDQW 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vmin.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_int_5")))]
@@ -891,7 +890,7 @@
(match_operand:VDQW 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vmax.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_int_5")))]
@@ -917,7 +916,7 @@
default: gcc_unreachable ();
}
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_vshl_ddd")
(const_string "neon_shift_3")))]
@@ -933,7 +932,7 @@
<MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
false);
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_vshl_ddd")
(const_string "neon_shift_3")))]
@@ -949,7 +948,7 @@
<MODE>mode, VALID_NEON_QREG_MODE (<MODE>mode),
false);
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_vshl_ddd")
(const_string "neon_shift_3")))]
@@ -967,7 +966,7 @@
UNSPEC_ASHIFT_SIGNED))]
"TARGET_NEON"
"vshl.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_vshl_ddd")
(const_string "neon_shift_3")))]
@@ -983,7 +982,7 @@
UNSPEC_ASHIFT_UNSIGNED))]
"TARGET_NEON"
"vshl.<V_u_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_vshl_ddd")
(const_string "neon_shift_3")))]
@@ -1038,7 +1037,7 @@
"@
vld1.32\t{%P0[0]}, %A1
vmov.32\t%P0[0], %1"
- [(set_attr "neon_type" "neon_vld1_vld2_lane,neon_mcr")]
+ [(set_attr "type" "neon_vld1_vld2_lane,neon_mcr")]
)
(define_insn "ashldi3_neon_noclobber"
@@ -1051,7 +1050,7 @@
"@
vshl.u64\t%P0, %P1, %2
vshl.u64\t%P0, %P1, %P2"
- [(set_attr "neon_type" "neon_vshl_ddd,neon_vshl_ddd")]
+ [(set_attr "type" "neon_vshl_ddd,neon_vshl_ddd")]
)
(define_insn_and_split "ashldi3_neon"
@@ -1113,7 +1112,7 @@
UNSPEC_ASHIFT_SIGNED))]
"TARGET_NEON && reload_completed"
"vshl.s64\t%P0, %P1, %P2"
- [(set_attr "neon_type" "neon_vshl_ddd")]
+ [(set_attr "type" "neon_vshl_ddd")]
)
; The shift amount needs to be negated for right-shifts
@@ -1124,7 +1123,7 @@
UNSPEC_ASHIFT_UNSIGNED))]
"TARGET_NEON && reload_completed"
"vshl.u64\t%P0, %P1, %P2"
- [(set_attr "neon_type" "neon_vshl_ddd")]
+ [(set_attr "type" "neon_vshl_ddd")]
)
(define_insn "ashrdi3_neon_imm_noclobber"
@@ -1134,7 +1133,7 @@
"TARGET_NEON && reload_completed
&& INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
"vshr.s64\t%P0, %P1, %2"
- [(set_attr "neon_type" "neon_vshl_ddd")]
+ [(set_attr "type" "neon_vshl_ddd")]
)
(define_insn "lshrdi3_neon_imm_noclobber"
@@ -1144,7 +1143,7 @@
"TARGET_NEON && reload_completed
&& INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 64"
"vshr.u64\t%P0, %P1, %2"
- [(set_attr "neon_type" "neon_vshl_ddd")]
+ [(set_attr "type" "neon_vshl_ddd")]
)
;; ashrdi3_neon
@@ -1215,7 +1214,7 @@
(match_operand:<V_widen> 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vaddw.<V_s_elem>\t%q0, %q2, %P1"
- [(set_attr "neon_type" "neon_int_3")]
+ [(set_attr "type" "neon_int_3")]
)
(define_insn "widen_usum<mode>3"
@@ -1225,7 +1224,7 @@
(match_operand:<V_widen> 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vaddw.<V_u_elem>\t%q0, %q2, %P1"
- [(set_attr "neon_type" "neon_int_3")]
+ [(set_attr "type" "neon_int_3")]
)
;; VEXT can be used to synthesize coarse whole-vector shifts with 8-bit
@@ -1309,7 +1308,7 @@
"TARGET_NEON"
"<VQH_mnem>.<VQH_sign>32\t%P0, %e1, %f1"
[(set_attr "vqh_mnem" "<VQH_mnem>")
- (set (attr "neon_type")
+ (set (attr "type")
(if_then_else (eq_attr "vqh_mnem" "vadd")
(const_string "neon_int_1") (const_string "neon_int_5")))]
)
@@ -1324,7 +1323,7 @@
"TARGET_NEON && flag_unsafe_math_optimizations"
"<VQH_mnem>.f32\t%P0, %e1, %f1"
[(set_attr "vqh_mnem" "<VQH_mnem>")
- (set (attr "neon_type")
+ (set (attr "type")
(if_then_else (eq_attr "vqh_mnem" "vadd")
(const_string "neon_int_1") (const_string "neon_int_5")))]
)
@@ -1341,7 +1340,7 @@
"TARGET_NEON"
"<VQH_mnem>.<VQH_sign>16\t%P0, %e1, %f1"
[(set_attr "vqh_mnem" "<VQH_mnem>")
- (set (attr "neon_type")
+ (set (attr "type")
(if_then_else (eq_attr "vqh_mnem" "vadd")
(const_string "neon_int_1") (const_string "neon_int_5")))]
)
@@ -1362,7 +1361,7 @@
"TARGET_NEON"
"<VQH_mnem>.<VQH_sign>8\t%P0, %e1, %f1"
[(set_attr "vqh_mnem" "<VQH_mnem>")
- (set (attr "neon_type")
+ (set (attr "type")
(if_then_else (eq_attr "vqh_mnem" "vadd")
(const_string "neon_int_1") (const_string "neon_int_5")))]
)
@@ -1423,7 +1422,7 @@
UNSPEC_VPADD))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vadd.i64\t%e0, %e1, %f1"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
;; NEON does not distinguish between signed and unsigned addition except on
@@ -1547,7 +1546,7 @@
"TARGET_NEON"
"vpadd.<V_if_elem>\t%P0, %P1, %P2"
;; Assume this schedules like vadd.
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -1563,7 +1562,7 @@
"TARGET_NEON"
"vpmin.<V_s_elem>\t%P0, %P1, %P2"
;; Assume this schedules like vmin.
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_int_5")))]
@@ -1577,7 +1576,7 @@
"TARGET_NEON"
"vpmax.<V_s_elem>\t%P0, %P1, %P2"
;; Assume this schedules like vmax.
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_int_5")))]
@@ -1591,7 +1590,7 @@
"TARGET_NEON"
"vpmin.<V_u_elem>\t%P0, %P1, %P2"
;; Assume this schedules like umin.
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
(define_insn "neon_vpumax<mode>"
@@ -1602,7 +1601,7 @@
"TARGET_NEON"
"vpmax.<V_u_elem>\t%P0, %P1, %P2"
;; Assume this schedules like umax.
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
;; Saturating arithmetic
@@ -1619,7 +1618,7 @@
(match_operand:VD 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vqadd.<V_s_elem>\t%P0, %P1, %P2"
- [(set_attr "neon_type" "neon_int_4")]
+ [(set_attr "type" "neon_int_4")]
)
(define_insn "*us_add<mode>_neon"
@@ -1628,7 +1627,7 @@
(match_operand:VD 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vqadd.<V_u_elem>\t%P0, %P1, %P2"
- [(set_attr "neon_type" "neon_int_4")]
+ [(set_attr "type" "neon_int_4")]
)
(define_insn "*ss_sub<mode>_neon"
@@ -1637,7 +1636,7 @@
(match_operand:VD 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vqsub.<V_s_elem>\t%P0, %P1, %P2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
(define_insn "*us_sub<mode>_neon"
@@ -1646,7 +1645,7 @@
(match_operand:VD 2 "s_register_operand" "w")))]
"TARGET_NEON"
"vqsub.<V_u_elem>\t%P0, %P1, %P2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
;; Conditional instructions. These are comparisons with conditional moves for
@@ -1671,6 +1670,7 @@
? 3 : 1;
rtx magic_rtx = GEN_INT (magic_word);
int inverse = 0;
+ int use_zero_form = 0;
int swap_bsl_operands = 0;
rtx mask = gen_reg_rtx (<V_cmp_result>mode);
rtx tmp = gen_reg_rtx (<V_cmp_result>mode);
@@ -1681,12 +1681,16 @@
switch (GET_CODE (operands[3]))
{
case GE:
+ case GT:
case LE:
+ case LT:
case EQ:
- if (!REG_P (operands[5])
- && (operands[5] != CONST0_RTX (<MODE>mode)))
- operands[5] = force_reg (<MODE>mode, operands[5]);
- break;
+ if (operands[5] == CONST0_RTX (<MODE>mode))
+ {
+ use_zero_form = 1;
+ break;
+ }
+ /* Fall through. */
default:
if (!REG_P (operands[5]))
operands[5] = force_reg (<MODE>mode, operands[5]);
@@ -1737,7 +1741,26 @@
a GT b -> a GT b
a LE b -> b GE a
a LT b -> b GT a
- a EQ b -> a EQ b */
+ a EQ b -> a EQ b
+ Note that there also exist direct comparison against 0 forms,
+ so catch those as a special case. */
+ if (use_zero_form)
+ {
+ inverse = 0;
+ switch (GET_CODE (operands[3]))
+ {
+ case LT:
+ base_comparison = gen_neon_vclt<mode>;
+ break;
+ case LE:
+ base_comparison = gen_neon_vcle<mode>;
+ break;
+ default:
+ /* Do nothing, other zero form cases already have the correct
+ base_comparison. */
+ break;
+ }
+ }
if (!inverse)
emit_insn (base_comparison (mask, operands[4], operands[5], magic_rtx));
@@ -1914,7 +1937,7 @@
UNSPEC_VADD))]
"TARGET_NEON"
"vadd.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -1934,7 +1957,7 @@
UNSPEC_VADDL))]
"TARGET_NEON"
"vaddl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
- [(set_attr "neon_type" "neon_int_3")]
+ [(set_attr "type" "neon_int_3")]
)
(define_insn "neon_vaddw<mode>"
@@ -1945,7 +1968,7 @@
UNSPEC_VADDW))]
"TARGET_NEON"
"vaddw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
- [(set_attr "neon_type" "neon_int_2")]
+ [(set_attr "type" "neon_int_2")]
)
; vhadd and vrhadd.
@@ -1958,7 +1981,7 @@
UNSPEC_VHADD))]
"TARGET_NEON"
"v%O3hadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_4")]
+ [(set_attr "type" "neon_int_4")]
)
(define_insn "neon_vqadd<mode>"
@@ -1969,7 +1992,7 @@
UNSPEC_VQADD))]
"TARGET_NEON"
"vqadd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_4")]
+ [(set_attr "type" "neon_int_4")]
)
(define_insn "neon_vaddhn<mode>"
@@ -1980,7 +2003,7 @@
UNSPEC_VADDHN))]
"TARGET_NEON"
"v%O3addhn.<V_if_elem>\t%P0, %q1, %q2"
- [(set_attr "neon_type" "neon_int_4")]
+ [(set_attr "type" "neon_int_4")]
)
;; We cannot replace this unspec with mul<mode>3 because of the odd
@@ -1993,7 +2016,7 @@
UNSPEC_VMUL))]
"TARGET_NEON"
"vmul.%F3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2061,7 +2084,7 @@
UNSPEC_VMLA))]
"TARGET_NEON"
"vmla.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vmla_ddd")
@@ -2085,7 +2108,7 @@
UNSPEC_VMLAL))]
"TARGET_NEON"
"vmlal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
(const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
@@ -2118,7 +2141,7 @@
UNSPEC_VMLS))]
"TARGET_NEON"
"vmls.<V_if_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vmla_ddd")
@@ -2143,7 +2166,7 @@
UNSPEC_VMLSL))]
"TARGET_NEON"
"vmlsl.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
(const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
@@ -2157,7 +2180,7 @@
UNSPEC_VQDMULH))]
"TARGET_NEON"
"vq%O3dmulh.<V_s_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
@@ -2176,7 +2199,7 @@
UNSPEC_VQDMLAL))]
"TARGET_NEON"
"vqdmlal.<V_s_elem>\t%q0, %P2, %P3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
(const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
@@ -2191,7 +2214,7 @@
UNSPEC_VQDMLSL))]
"TARGET_NEON"
"vqdmlsl.<V_s_elem>\t%q0, %P2, %P3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mla_ddd_8_16_qdd_16_8_long_32_16_long")
(const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
@@ -2205,7 +2228,7 @@
UNSPEC_VMULL))]
"TARGET_NEON"
"vmull.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
(const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
@@ -2219,7 +2242,7 @@
UNSPEC_VQDMULL))]
"TARGET_NEON"
"vqdmull.<V_s_elem>\t%q0, %P1, %P2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mul_ddd_8_16_qdd_16_8_long_32_16_long")
(const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
@@ -2249,7 +2272,7 @@
UNSPEC_VSUB))]
"TARGET_NEON"
"vsub.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2265,7 +2288,7 @@
UNSPEC_VSUBL))]
"TARGET_NEON"
"vsubl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
- [(set_attr "neon_type" "neon_int_2")]
+ [(set_attr "type" "neon_int_2")]
)
(define_insn "neon_vsubw<mode>"
@@ -2276,7 +2299,7 @@
UNSPEC_VSUBW))]
"TARGET_NEON"
"vsubw.%T3%#<V_sz_elem>\t%q0, %q1, %P2"
- [(set_attr "neon_type" "neon_int_2")]
+ [(set_attr "type" "neon_int_2")]
)
(define_insn "neon_vqsub<mode>"
@@ -2287,7 +2310,7 @@
UNSPEC_VQSUB))]
"TARGET_NEON"
"vqsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
(define_insn "neon_vhsub<mode>"
@@ -2298,7 +2321,7 @@
UNSPEC_VHSUB))]
"TARGET_NEON"
"vhsub.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
(define_insn "neon_vsubhn<mode>"
@@ -2309,7 +2332,7 @@
UNSPEC_VSUBHN))]
"TARGET_NEON"
"v%O3subhn.<V_if_elem>\t%P0, %q1, %q2"
- [(set_attr "neon_type" "neon_int_4")]
+ [(set_attr "type" "neon_int_4")]
)
(define_insn "neon_vceq<mode>"
@@ -2323,7 +2346,7 @@
"@
vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
vceq.<V_if_elem>\t%<V_reg>0, %<V_reg>1, #0"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2342,7 +2365,7 @@
"@
vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2359,7 +2382,7 @@
UNSPEC_VCGEU))]
"TARGET_NEON"
"vcge.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
(define_insn "neon_vcgt<mode>"
@@ -2373,7 +2396,7 @@
"@
vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2
vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2390,7 +2413,7 @@
UNSPEC_VCGTU))]
"TARGET_NEON"
"vcgt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
;; VCLE and VCLT only support comparisons with immediate zero (register
@@ -2405,7 +2428,7 @@
UNSPEC_VCLE))]
"TARGET_NEON"
"vcle.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2422,7 +2445,7 @@
UNSPEC_VCLT))]
"TARGET_NEON"
"vclt.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, #0"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2438,7 +2461,7 @@
UNSPEC_VCAGE))]
"TARGET_NEON"
"vacge.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -2452,7 +2475,7 @@
UNSPEC_VCAGT))]
"TARGET_NEON"
"vacgt.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -2466,7 +2489,7 @@
UNSPEC_VTST))]
"TARGET_NEON"
"vtst.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set_attr "neon_type" "neon_int_4")]
+ [(set_attr "type" "neon_int_4")]
)
(define_insn "neon_vabd<mode>"
@@ -2477,7 +2500,7 @@
UNSPEC_VABD))]
"TARGET_NEON"
"vabd.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2493,7 +2516,7 @@
UNSPEC_VABDL))]
"TARGET_NEON"
"vabdl.%T3%#<V_sz_elem>\t%q0, %P1, %P2"
- [(set_attr "neon_type" "neon_int_5")]
+ [(set_attr "type" "neon_int_5")]
)
(define_insn "neon_vaba<mode>"
@@ -2505,7 +2528,7 @@
(match_operand:VDQIW 1 "s_register_operand" "0")))]
"TARGET_NEON"
"vaba.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %<V_reg>3"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_vaba") (const_string "neon_vaba_qqq")))]
)
@@ -2519,7 +2542,7 @@
(match_operand:<V_widen> 1 "s_register_operand" "0")))]
"TARGET_NEON"
"vabal.%T4%#<V_sz_elem>\t%q0, %P2, %P3"
- [(set_attr "neon_type" "neon_vaba")]
+ [(set_attr "type" "neon_vaba")]
)
(define_insn "neon_vmax<mode>"
@@ -2530,7 +2553,7 @@
UNSPEC_VMAX))]
"TARGET_NEON"
"vmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2546,7 +2569,7 @@
UNSPEC_VMIN))]
"TARGET_NEON"
"vmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -2574,7 +2597,7 @@
"TARGET_NEON"
"vpaddl.%T2%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
;; Assume this schedules like vaddl.
- [(set_attr "neon_type" "neon_int_3")]
+ [(set_attr "type" "neon_int_3")]
)
(define_insn "neon_vpadal<mode>"
@@ -2586,7 +2609,7 @@
"TARGET_NEON"
"vpadal.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
;; Assume this schedules like vpadd.
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
(define_insn "neon_vpmax<mode>"
@@ -2598,7 +2621,7 @@
"TARGET_NEON"
"vpmax.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
;; Assume this schedules like vmax.
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_int_5")))]
@@ -2613,7 +2636,7 @@
"TARGET_NEON"
"vpmin.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
;; Assume this schedules like vmin.
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_int_5")))]
@@ -2627,7 +2650,7 @@
UNSPEC_VRECPS))]
"TARGET_NEON"
"vrecps.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vrecps_vrsqrts_ddd")
(const_string "neon_fp_vrecps_vrsqrts_qqq")))]
@@ -2641,7 +2664,7 @@
UNSPEC_VRSQRTS))]
"TARGET_NEON"
"vrsqrts.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vrecps_vrsqrts_ddd")
(const_string "neon_fp_vrecps_vrsqrts_qqq")))]
@@ -2664,7 +2687,7 @@
UNSPEC_VQABS))]
"TARGET_NEON"
"vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_vqneg_vqabs")]
+ [(set_attr "type" "neon_vqneg_vqabs")]
)
(define_expand "neon_vneg<mode>"
@@ -2684,7 +2707,7 @@
UNSPEC_VQNEG))]
"TARGET_NEON"
"vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_vqneg_vqabs")]
+ [(set_attr "type" "neon_vqneg_vqabs")]
)
(define_insn "neon_vcls<mode>"
@@ -2694,7 +2717,7 @@
UNSPEC_VCLS))]
"TARGET_NEON"
"vcls.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
(define_insn "clz<mode>2"
@@ -2702,7 +2725,7 @@
(clz:VDQIW (match_operand:VDQIW 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vclz.<V_if_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
(define_expand "neon_vclz<mode>"
@@ -2720,7 +2743,7 @@
(popcount:VE (match_operand:VE 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vcnt.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
(define_expand "neon_vcnt<mode>"
@@ -2740,7 +2763,7 @@
UNSPEC_VRECPE))]
"TARGET_NEON"
"vrecpe.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -2753,7 +2776,7 @@
UNSPEC_VRSQRTE))]
"TARGET_NEON"
"vrsqrte.<V_u_elem>\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -2785,7 +2808,7 @@
}
return "vmov.s<V_sz_elem>\t%0, %P1[%c2]";
}
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_insn "neon_vget_lane<mode>_zext_internal"
@@ -2804,7 +2827,7 @@
}
return "vmov.u<V_sz_elem>\t%0, %P1[%c2]";
}
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_insn "neon_vget_lane<mode>_sext_internal"
@@ -2831,7 +2854,7 @@
return "";
}
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_insn "neon_vget_lane<mode>_zext_internal"
@@ -2858,7 +2881,7 @@
return "";
}
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_expand "neon_vget_lane<mode>"
@@ -2991,7 +3014,7 @@
"TARGET_NEON"
"vdup.<V_sz_elem>\t%<V_reg>0, %1"
;; Assume this schedules like vmov.
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_insn "neon_vdup_n<mode>"
@@ -3002,7 +3025,7 @@
vdup.<V_sz_elem>\t%<V_reg>0, %1
vdup.<V_sz_elem>\t%<V_reg>0, %y1"
;; Assume this schedules like vmov.
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_expand "neon_vdup_ndi"
@@ -3023,7 +3046,7 @@
vmov\t%e0, %Q1, %R1\;vmov\t%f0, %Q1, %R1
vmov\t%e0, %P1\;vmov\t%f0, %P1"
[(set_attr "length" "8")
- (set_attr "neon_type" "neon_bp_simple")]
+ (set_attr "type" "neon_bp_simple")]
)
(define_insn "neon_vdup_lane<mode>_internal"
@@ -3046,7 +3069,7 @@
return "vdup.<V_sz_elem>\t%q0, %P1[%c2]";
}
;; Assume this schedules like vmov.
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_expand "neon_vdup_lane<mode>"
@@ -3101,7 +3124,7 @@
(set (match_dup 1) (match_dup 0))]
"TARGET_NEON && reload_completed"
"vswp\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_bp_simple")
(const_string "neon_bp_2cycle")))]
@@ -3155,7 +3178,7 @@
(float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
"TARGET_NEON && !flag_rounding_math"
"vcvt.f32.s32\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -3166,7 +3189,7 @@
(unsigned_float:<V_CVTTO> (match_operand:VCVTI 1 "s_register_operand" "w")))]
"TARGET_NEON && !flag_rounding_math"
"vcvt.f32.u32\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -3177,7 +3200,7 @@
(fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vcvt.s32.f32\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -3188,7 +3211,7 @@
(unsigned_fix:<V_CVTTO> (match_operand:VCVTF 1 "s_register_operand" "w")))]
"TARGET_NEON"
"vcvt.u32.f32\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -3201,7 +3224,7 @@
UNSPEC_VCVT))]
"TARGET_NEON"
"vcvt.%T2%#32.f32\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -3214,7 +3237,7 @@
UNSPEC_VCVT))]
"TARGET_NEON"
"vcvt.f32.%T2%#32\t%<V_reg>0, %<V_reg>1"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -3226,7 +3249,7 @@
UNSPEC_VCVT))]
"TARGET_NEON && TARGET_FP16"
"vcvt.f32.f16\t%q0, %P1"
- [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")]
+ [(set_attr "type" "neon_fp_vadd_ddd_vabs_dd")]
)
(define_insn "neon_vcvtv4hfv4sf"
@@ -3235,7 +3258,7 @@
UNSPEC_VCVT))]
"TARGET_NEON && TARGET_FP16"
"vcvt.f16.f32\t%P0, %q1"
- [(set_attr "neon_type" "neon_fp_vadd_ddd_vabs_dd")]
+ [(set_attr "type" "neon_fp_vadd_ddd_vabs_dd")]
)
(define_insn "neon_vcvt_n<mode>"
@@ -3249,7 +3272,7 @@
neon_const_bounds (operands[2], 1, 33);
return "vcvt.%T3%#32.f32\t%<V_reg>0, %<V_reg>1, %2";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -3266,7 +3289,7 @@
neon_const_bounds (operands[2], 1, 33);
return "vcvt.f32.%T3%#32\t%<V_reg>0, %<V_reg>1, %2";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_fp_vadd_ddd_vabs_dd")
(const_string "neon_fp_vadd_qqq_vabs_qq")))]
@@ -3279,7 +3302,7 @@
UNSPEC_VMOVN))]
"TARGET_NEON"
"vmovn.<V_if_elem>\t%P0, %q1"
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_insn "neon_vqmovn<mode>"
@@ -3289,7 +3312,7 @@
UNSPEC_VQMOVN))]
"TARGET_NEON"
"vqmovn.%T2%#<V_sz_elem>\t%P0, %q1"
- [(set_attr "neon_type" "neon_shift_2")]
+ [(set_attr "type" "neon_shift_2")]
)
(define_insn "neon_vqmovun<mode>"
@@ -3299,7 +3322,7 @@
UNSPEC_VQMOVUN))]
"TARGET_NEON"
"vqmovun.<V_s_elem>\t%P0, %q1"
- [(set_attr "neon_type" "neon_shift_2")]
+ [(set_attr "type" "neon_shift_2")]
)
(define_insn "neon_vmovl<mode>"
@@ -3309,7 +3332,7 @@
UNSPEC_VMOVL))]
"TARGET_NEON"
"vmovl.%T2%#<V_sz_elem>\t%q0, %P1"
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_insn "neon_vmul_lane<mode>"
@@ -3325,7 +3348,7 @@
neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
return "vmul.<V_if_elem>\t%P0, %P1, %P2[%c3]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vmul_ddd")
(if_then_else (match_test "<Scalar_mul_8_16>")
@@ -3346,7 +3369,7 @@
neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<V_HALF>mode));
return "vmul.<V_if_elem>\t%q0, %q1, %P2[%c3]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vmul_qqd")
(if_then_else (match_test "<Scalar_mul_8_16>")
@@ -3367,7 +3390,7 @@
neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
return "vmull.%T4%#<V_sz_elem>\t%q0, %P1, %P2[%c3]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
(const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
@@ -3386,7 +3409,7 @@
neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
return "vqdmull.<V_s_elem>\t%q0, %P1, %P2[%c3]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
(const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
@@ -3405,7 +3428,7 @@
neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
return "vq%O4dmulh.%T4%#<V_sz_elem>\t%q0, %q1, %P2[%c3]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")
(const_string "neon_mul_qqd_32_scalar")))]
@@ -3424,7 +3447,7 @@
neon_lane_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
return "vq%O4dmulh.%T4%#<V_sz_elem>\t%P0, %P1, %P2[%c3]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mul_ddd_16_scalar_32_16_long_scalar")
(const_string "neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar")))]
@@ -3444,7 +3467,7 @@
neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
return "vmla.<V_if_elem>\t%P0, %P2, %P3[%c4]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vmla_ddd_scalar")
(if_then_else (match_test "<Scalar_mul_8_16>")
@@ -3466,7 +3489,7 @@
neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
return "vmla.<V_if_elem>\t%q0, %q2, %P3[%c4]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vmla_qqq_scalar")
(if_then_else (match_test "<Scalar_mul_8_16>")
@@ -3488,7 +3511,7 @@
neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
return "vmlal.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
(const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
@@ -3508,7 +3531,7 @@
neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
return "vqdmlal.<V_s_elem>\t%q0, %P2, %P3[%c4]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
(const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
@@ -3528,7 +3551,7 @@
neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
return "vmls.<V_if_elem>\t%P0, %P2, %P3[%c4]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vmla_ddd_scalar")
(if_then_else (match_test "<Scalar_mul_8_16>")
@@ -3550,7 +3573,7 @@
neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
return "vmls.<V_if_elem>\t%q0, %q2, %P3[%c4]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_float_mode>")
(const_string "neon_fp_vmla_qqq_scalar")
(if_then_else (match_test "<Scalar_mul_8_16>")
@@ -3572,7 +3595,7 @@
neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
return "vmlsl.%T5%#<V_sz_elem>\t%q0, %P2, %P3[%c4]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
(const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
@@ -3592,7 +3615,7 @@
neon_lane_bounds (operands[4], 0, GET_MODE_NUNITS (<MODE>mode));
return "vqdmlsl.<V_s_elem>\t%q0, %P2, %P3[%c4]";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Scalar_mul_8_16>")
(const_string "neon_mla_ddd_16_scalar_qdd_32_16_long_scalar")
(const_string "neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long")))]
@@ -3820,7 +3843,7 @@
neon_const_bounds (operands[3], 0, GET_MODE_NUNITS (<MODE>mode));
return "vext.<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2, %3";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_bp_simple")
(const_string "neon_bp_2cycle")))]
@@ -3833,7 +3856,7 @@
UNSPEC_VREV64))]
"TARGET_NEON"
"vrev64.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_insn "neon_vrev32<mode>"
@@ -3843,7 +3866,7 @@
UNSPEC_VREV32))]
"TARGET_NEON"
"vrev32.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
(define_insn "neon_vrev16<mode>"
@@ -3853,7 +3876,7 @@
UNSPEC_VREV16))]
"TARGET_NEON"
"vrev16.<V_sz_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_bp_simple")]
+ [(set_attr "type" "neon_bp_simple")]
)
; vbsl_* intrinsics may compile to any of vbsl/vbif/vbit depending on register
@@ -3875,7 +3898,7 @@
vbsl\t%<V_reg>0, %<V_reg>2, %<V_reg>3
vbit\t%<V_reg>0, %<V_reg>2, %<V_reg>1
vbif\t%<V_reg>0, %<V_reg>3, %<V_reg>1"
- [(set_attr "neon_type" "neon_int_1")]
+ [(set_attr "type" "neon_int_1")]
)
(define_expand "neon_vbsl<mode>"
@@ -3898,7 +3921,7 @@
UNSPEC_VSHL))]
"TARGET_NEON"
"v%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_vshl_ddd")
(const_string "neon_shift_3")))]
@@ -3912,7 +3935,7 @@
UNSPEC_VQSHL))]
"TARGET_NEON"
"vq%O3shl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_shift_2")
(const_string "neon_vqshl_vrshl_vqrshl_qqq")))]
@@ -3929,7 +3952,7 @@
neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) + 1);
return "v%O3shr.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
}
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_insn "neon_vshrn_n<mode>"
@@ -3943,7 +3966,7 @@
neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
return "v%O3shrn.<V_if_elem>\t%P0, %q1, %2";
}
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_insn "neon_vqshrn_n<mode>"
@@ -3957,7 +3980,7 @@
neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
return "vq%O3shrn.%T3%#<V_sz_elem>\t%P0, %q1, %2";
}
- [(set_attr "neon_type" "neon_shift_2")]
+ [(set_attr "type" "neon_shift_2")]
)
(define_insn "neon_vqshrun_n<mode>"
@@ -3971,7 +3994,7 @@
neon_const_bounds (operands[2], 1, neon_element_bits (<MODE>mode) / 2 + 1);
return "vq%O3shrun.%T3%#<V_sz_elem>\t%P0, %q1, %2";
}
- [(set_attr "neon_type" "neon_shift_2")]
+ [(set_attr "type" "neon_shift_2")]
)
(define_insn "neon_vshl_n<mode>"
@@ -3985,7 +4008,7 @@
neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
return "vshl.<V_if_elem>\t%<V_reg>0, %<V_reg>1, %2";
}
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_insn "neon_vqshl_n<mode>"
@@ -3999,7 +4022,7 @@
neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
return "vqshl.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
}
- [(set_attr "neon_type" "neon_shift_2")]
+ [(set_attr "type" "neon_shift_2")]
)
(define_insn "neon_vqshlu_n<mode>"
@@ -4013,7 +4036,7 @@
neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode));
return "vqshlu.%T3%#<V_sz_elem>\t%<V_reg>0, %<V_reg>1, %2";
}
- [(set_attr "neon_type" "neon_shift_2")]
+ [(set_attr "type" "neon_shift_2")]
)
(define_insn "neon_vshll_n<mode>"
@@ -4028,7 +4051,7 @@
neon_const_bounds (operands[2], 0, neon_element_bits (<MODE>mode) + 1);
return "vshll.%T3%#<V_sz_elem>\t%q0, %P1, %2";
}
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_insn "neon_vsra_n<mode>"
@@ -4043,7 +4066,7 @@
neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
return "v%O4sra.%T4%#<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
}
- [(set_attr "neon_type" "neon_vsra_vrsra")]
+ [(set_attr "type" "neon_vsra_vrsra")]
)
(define_insn "neon_vsri_n<mode>"
@@ -4057,7 +4080,7 @@
neon_const_bounds (operands[3], 1, neon_element_bits (<MODE>mode) + 1);
return "vsri.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_shift_1")
(const_string "neon_shift_3")))]
@@ -4074,7 +4097,7 @@
neon_const_bounds (operands[3], 0, neon_element_bits (<MODE>mode));
return "vsli.<V_sz_elem>\t%<V_reg>0, %<V_reg>2, %3";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_shift_1")
(const_string "neon_shift_3")))]
@@ -4087,7 +4110,7 @@
UNSPEC_VTBL))]
"TARGET_NEON"
"vtbl.8\t%P0, {%P1}, %P2"
- [(set_attr "neon_type" "neon_bp_2cycle")]
+ [(set_attr "type" "neon_bp_2cycle")]
)
(define_insn "neon_vtbl2v8qi"
@@ -4108,7 +4131,7 @@
return "";
}
- [(set_attr "neon_type" "neon_bp_2cycle")]
+ [(set_attr "type" "neon_bp_2cycle")]
)
(define_insn "neon_vtbl3v8qi"
@@ -4130,7 +4153,7 @@
return "";
}
- [(set_attr "neon_type" "neon_bp_3cycle")]
+ [(set_attr "type" "neon_bp_3cycle")]
)
(define_insn "neon_vtbl4v8qi"
@@ -4153,7 +4176,7 @@
return "";
}
- [(set_attr "neon_type" "neon_bp_3cycle")]
+ [(set_attr "type" "neon_bp_3cycle")]
)
;; These three are used by the vec_perm infrastructure for V16QImode.
@@ -4241,7 +4264,7 @@
UNSPEC_VTBX))]
"TARGET_NEON"
"vtbx.8\t%P0, {%P2}, %P3"
- [(set_attr "neon_type" "neon_bp_2cycle")]
+ [(set_attr "type" "neon_bp_2cycle")]
)
(define_insn "neon_vtbx2v8qi"
@@ -4263,7 +4286,7 @@
return "";
}
- [(set_attr "neon_type" "neon_bp_2cycle")]
+ [(set_attr "type" "neon_bp_2cycle")]
)
(define_insn "neon_vtbx3v8qi"
@@ -4286,7 +4309,7 @@
return "";
}
- [(set_attr "neon_type" "neon_bp_3cycle")]
+ [(set_attr "type" "neon_bp_3cycle")]
)
(define_insn "neon_vtbx4v8qi"
@@ -4310,7 +4333,7 @@
return "";
}
- [(set_attr "neon_type" "neon_bp_3cycle")]
+ [(set_attr "type" "neon_bp_3cycle")]
)
(define_expand "neon_vtrn<mode>_internal"
@@ -4336,7 +4359,7 @@
UNSPEC_VTRN2))]
"TARGET_NEON"
"vtrn.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_bp_simple")
(const_string "neon_bp_3cycle")))]
@@ -4376,7 +4399,7 @@
UNSPEC_VZIP2))]
"TARGET_NEON"
"vzip.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_bp_simple")
(const_string "neon_bp_3cycle")))]
@@ -4416,7 +4439,7 @@
UNSPEC_VUZP2))]
"TARGET_NEON"
"vuzp.<V_sz_elem>\t%<V_reg>0, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (match_test "<Is_d_reg>")
(const_string "neon_bp_simple")
(const_string "neon_bp_3cycle")))]
@@ -4535,7 +4558,7 @@
UNSPEC_VLD1))]
"TARGET_NEON"
"vld1.<V_sz_elem>\t%h0, %A1"
- [(set_attr "neon_type" "neon_vld1_1_2_regs")]
+ [(set_attr "type" "neon_vld1_1_2_regs")]
)
(define_insn "neon_vld1_lane<mode>"
@@ -4555,7 +4578,7 @@
else
return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
(const_string "neon_vld1_1_2_regs")
(const_string "neon_vld1_vld2_lane")))]
@@ -4586,26 +4609,27 @@
else
return "vld1.<V_sz_elem>\t{%P0[%c3]}, %A1";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_mode_nunits>") (const_int 2))
(const_string "neon_vld1_1_2_regs")
(const_string "neon_vld1_vld2_lane")))]
)
(define_insn "neon_vld1_dup<mode>"
- [(set (match_operand:VDX 0 "s_register_operand" "=w")
- (vec_duplicate:VDX (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
+ [(set (match_operand:VD 0 "s_register_operand" "=w")
+ (vec_duplicate:VD (match_operand:<V_elem> 1 "neon_struct_operand" "Um")))]
"TARGET_NEON"
-{
- if (GET_MODE_NUNITS (<MODE>mode) > 1)
- return "vld1.<V_sz_elem>\t{%P0[]}, %A1";
- else
- return "vld1.<V_sz_elem>\t%h0, %A1";
-}
- [(set (attr "neon_type")
- (if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
- (const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
- (const_string "neon_vld1_1_2_regs")))]
+ "vld1.<V_sz_elem>\t{%P0[]}, %A1"
+ [(set_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
+)
+
+;; Special case for DImode. Treat it exactly like a simple load.
+(define_expand "neon_vld1_dupdi"
+ [(set (match_operand:DI 0 "s_register_operand" "")
+ (unspec:DI [(match_operand:DI 1 "neon_struct_operand" "")]
+ UNSPEC_VLD1))]
+ "TARGET_NEON"
+ ""
)
(define_insn "neon_vld1_dup<mode>"
@@ -4615,7 +4639,7 @@
{
return "vld1.<V_sz_elem>\t{%e0[], %f0[]}, %A1";
}
- [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
+ [(set_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
)
(define_insn_and_split "neon_vld1_dupv2di"
@@ -4632,7 +4656,7 @@
DONE;
}
[(set_attr "length" "8")
- (set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
+ (set_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")]
)
(define_expand "vec_store_lanes<mode><mode>"
@@ -4647,7 +4671,7 @@
UNSPEC_VST1))]
"TARGET_NEON"
"vst1.<V_sz_elem>\t%h1, %A0"
- [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")])
+ [(set_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")])
(define_insn "neon_vst1_lane<mode>"
[(set (match_operand:<V_elem> 0 "neon_struct_operand" "=Um")
@@ -4666,7 +4690,7 @@
else
return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_mode_nunits>") (const_int 1))
(const_string "neon_vst1_1_2_regs_vst2_2_regs")
(const_string "neon_vst1_vst2_lane")))])
@@ -4696,7 +4720,7 @@
else
return "vst1.<V_sz_elem>\t{%P1[%c2]}, %A0";
}
- [(set_attr "neon_type" "neon_vst1_vst2_lane")]
+ [(set_attr "type" "neon_vst1_vst2_lane")]
)
(define_expand "vec_load_lanesti<mode>"
@@ -4718,7 +4742,7 @@
else
return "vld2.<V_sz_elem>\t%h0, %A1";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
(const_string "neon_vld1_1_2_regs")
(const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")))]
@@ -4738,7 +4762,7 @@
UNSPEC_VLD2))]
"TARGET_NEON"
"vld2.<V_sz_elem>\t%h0, %A1"
- [(set_attr "neon_type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
+ [(set_attr "type" "neon_vld2_2_regs_vld1_vld2_all_lanes")])
(define_insn "neon_vld2_lane<mode>"
[(set (match_operand:TI 0 "s_register_operand" "=w")
@@ -4762,7 +4786,7 @@
output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
return "";
}
- [(set_attr "neon_type" "neon_vld1_vld2_lane")]
+ [(set_attr "type" "neon_vld1_vld2_lane")]
)
(define_insn "neon_vld2_lane<mode>"
@@ -4792,7 +4816,7 @@
output_asm_insn ("vld2.<V_sz_elem>\t{%P0[%c3], %P1[%c3]}, %A2", ops);
return "";
}
- [(set_attr "neon_type" "neon_vld1_vld2_lane")]
+ [(set_attr "type" "neon_vld1_vld2_lane")]
)
(define_insn "neon_vld2_dup<mode>"
@@ -4807,7 +4831,7 @@
else
return "vld1.<V_sz_elem>\t%h0, %A1";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
(const_string "neon_vld2_2_regs_vld1_vld2_all_lanes")
(const_string "neon_vld1_1_2_regs")))]
@@ -4832,7 +4856,7 @@
else
return "vst2.<V_sz_elem>\t%h1, %A0";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
(const_string "neon_vst1_1_2_regs_vst2_2_regs")
(const_string "neon_vst1_1_2_regs_vst2_2_regs")))]
@@ -4852,7 +4876,7 @@
UNSPEC_VST2))]
"TARGET_NEON"
"vst2.<V_sz_elem>\t%h1, %A0"
- [(set_attr "neon_type" "neon_vst1_1_2_regs_vst2_2_regs")]
+ [(set_attr "type" "neon_vst1_1_2_regs_vst2_2_regs")]
)
(define_insn "neon_vst2_lane<mode>"
@@ -4877,7 +4901,7 @@
output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
return "";
}
- [(set_attr "neon_type" "neon_vst1_vst2_lane")]
+ [(set_attr "type" "neon_vst1_vst2_lane")]
)
(define_insn "neon_vst2_lane<mode>"
@@ -4907,7 +4931,7 @@
output_asm_insn ("vst2.<V_sz_elem>\t{%P1[%c3], %P2[%c3]}, %A0", ops);
return "";
}
- [(set_attr "neon_type" "neon_vst1_vst2_lane")]
+ [(set_attr "type" "neon_vst1_vst2_lane")]
)
(define_expand "vec_load_lanesei<mode>"
@@ -4929,7 +4953,7 @@
else
return "vld3.<V_sz_elem>\t%h0, %A1";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
(const_string "neon_vld1_1_2_regs")
(const_string "neon_vld3_vld4")))]
@@ -4976,7 +5000,7 @@
output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
return "";
}
- [(set_attr "neon_type" "neon_vld3_vld4")]
+ [(set_attr "type" "neon_vld3_vld4")]
)
(define_insn "neon_vld3qb<mode>"
@@ -4996,7 +5020,7 @@
output_asm_insn ("vld3.<V_sz_elem>\t{%P0, %P1, %P2}, %A3", ops);
return "";
}
- [(set_attr "neon_type" "neon_vld3_vld4")]
+ [(set_attr "type" "neon_vld3_vld4")]
)
(define_insn "neon_vld3_lane<mode>"
@@ -5023,7 +5047,7 @@
ops);
return "";
}
- [(set_attr "neon_type" "neon_vld3_vld4_lane")]
+ [(set_attr "type" "neon_vld3_vld4_lane")]
)
(define_insn "neon_vld3_lane<mode>"
@@ -5055,7 +5079,7 @@
ops);
return "";
}
- [(set_attr "neon_type" "neon_vld3_vld4_lane")]
+ [(set_attr "type" "neon_vld3_vld4_lane")]
)
(define_insn "neon_vld3_dup<mode>"
@@ -5079,7 +5103,7 @@
else
return "vld1.<V_sz_elem>\t%h0, %A1";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
(const_string "neon_vld3_vld4_all_lanes")
(const_string "neon_vld1_1_2_regs")))])
@@ -5103,7 +5127,7 @@
else
return "vst3.<V_sz_elem>\t%h1, %A0";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
(const_string "neon_vst1_1_2_regs_vst2_2_regs")
(const_string "neon_vst2_4_regs_vst3_vst4")))])
@@ -5149,7 +5173,7 @@
output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
return "";
}
- [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
+ [(set_attr "type" "neon_vst2_4_regs_vst3_vst4")]
)
(define_insn "neon_vst3qb<mode>"
@@ -5168,7 +5192,7 @@
output_asm_insn ("vst3.<V_sz_elem>\t{%P1, %P2, %P3}, %A0", ops);
return "";
}
- [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
+ [(set_attr "type" "neon_vst2_4_regs_vst3_vst4")]
)
(define_insn "neon_vst3_lane<mode>"
@@ -5195,7 +5219,7 @@
ops);
return "";
}
- [(set_attr "neon_type" "neon_vst3_vst4_lane")]
+ [(set_attr "type" "neon_vst3_vst4_lane")]
)
(define_insn "neon_vst3_lane<mode>"
@@ -5227,7 +5251,7 @@
ops);
return "";
}
-[(set_attr "neon_type" "neon_vst3_vst4_lane")])
+[(set_attr "type" "neon_vst3_vst4_lane")])
(define_expand "vec_load_lanesoi<mode>"
[(set (match_operand:OI 0 "s_register_operand")
@@ -5248,7 +5272,7 @@
else
return "vld4.<V_sz_elem>\t%h0, %A1";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
(const_string "neon_vld1_1_2_regs")
(const_string "neon_vld3_vld4")))]
@@ -5296,7 +5320,7 @@
output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
return "";
}
- [(set_attr "neon_type" "neon_vld3_vld4")]
+ [(set_attr "type" "neon_vld3_vld4")]
)
(define_insn "neon_vld4qb<mode>"
@@ -5317,7 +5341,7 @@
output_asm_insn ("vld4.<V_sz_elem>\t{%P0, %P1, %P2, %P3}, %A4", ops);
return "";
}
- [(set_attr "neon_type" "neon_vld3_vld4")]
+ [(set_attr "type" "neon_vld3_vld4")]
)
(define_insn "neon_vld4_lane<mode>"
@@ -5345,7 +5369,7 @@
ops);
return "";
}
- [(set_attr "neon_type" "neon_vld3_vld4_lane")]
+ [(set_attr "type" "neon_vld3_vld4_lane")]
)
(define_insn "neon_vld4_lane<mode>"
@@ -5378,7 +5402,7 @@
ops);
return "";
}
- [(set_attr "neon_type" "neon_vld3_vld4_lane")]
+ [(set_attr "type" "neon_vld3_vld4_lane")]
)
(define_insn "neon_vld4_dup<mode>"
@@ -5404,7 +5428,7 @@
else
return "vld1.<V_sz_elem>\t%h0, %A1";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (gt (const_string "<V_mode_nunits>") (const_string "1"))
(const_string "neon_vld3_vld4_all_lanes")
(const_string "neon_vld1_1_2_regs")))]
@@ -5429,7 +5453,7 @@
else
return "vst4.<V_sz_elem>\t%h1, %A0";
}
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (eq (const_string "<V_sz_elem>") (const_string "64"))
(const_string "neon_vst1_1_2_regs_vst2_2_regs")
(const_string "neon_vst2_4_regs_vst3_vst4")))]
@@ -5477,7 +5501,7 @@
output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
return "";
}
- [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
+ [(set_attr "type" "neon_vst2_4_regs_vst3_vst4")]
)
(define_insn "neon_vst4qb<mode>"
@@ -5497,7 +5521,7 @@
output_asm_insn ("vst4.<V_sz_elem>\t{%P1, %P2, %P3, %P4}, %A0", ops);
return "";
}
- [(set_attr "neon_type" "neon_vst2_4_regs_vst3_vst4")]
+ [(set_attr "type" "neon_vst2_4_regs_vst3_vst4")]
)
(define_insn "neon_vst4_lane<mode>"
@@ -5525,7 +5549,7 @@
ops);
return "";
}
- [(set_attr "neon_type" "neon_vst3_vst4_lane")]
+ [(set_attr "type" "neon_vst3_vst4_lane")]
)
(define_insn "neon_vst4_lane<mode>"
@@ -5558,7 +5582,7 @@
ops);
return "";
}
- [(set_attr "neon_type" "neon_vst3_vst4_lane")]
+ [(set_attr "type" "neon_vst3_vst4_lane")]
)
(define_expand "neon_vand<mode>"
@@ -5623,7 +5647,7 @@
(match_operand:VU 2 "vect_par_constant_low" ""))))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vmovl.<US><V_sz_elem> %q0, %e1"
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_insn "neon_vec_unpack<US>_hi_<mode>"
@@ -5633,7 +5657,7 @@
(match_operand:VU 2 "vect_par_constant_high" ""))))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vmovl.<US><V_sz_elem> %q0, %f1"
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_expand "vec_unpack<US>_hi_<mode>"
@@ -5683,7 +5707,7 @@
(match_dup 2)))))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vmull.<US><V_sz_elem> %q0, %e1, %e3"
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_expand "vec_widen_<US>mult_lo_<mode>"
@@ -5717,7 +5741,7 @@
(match_dup 2)))))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vmull.<US><V_sz_elem> %q0, %f1, %f3"
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_expand "vec_widen_<US>mult_hi_<mode>"
@@ -5750,7 +5774,7 @@
{
return "vshll.<US><V_sz_elem> %q0, %P1, %2";
}
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_expand "vec_widen_<US>shiftl_lo_<mode>"
@@ -5786,7 +5810,7 @@
(SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
"TARGET_NEON"
"vmovl.<US><V_sz_elem> %q0, %P1"
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_expand "vec_unpack<US>_lo_<mode>"
@@ -5823,7 +5847,7 @@
(match_operand:VDI 2 "register_operand" "w"))))]
"TARGET_NEON"
"vmull.<US><V_sz_elem> %q0, %P1, %P2"
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_expand "vec_widen_<US>mult_hi_<mode>"
@@ -5897,7 +5921,7 @@
(match_operand:VN 2 "register_operand" "w"))))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vmovn.i<V_sz_elem>\t%e0, %q1\;vmovn.i<V_sz_elem>\t%f0, %q2"
- [(set_attr "neon_type" "neon_shift_1")
+ [(set_attr "type" "neon_shift_1")
(set_attr "length" "8")]
)
@@ -5907,7 +5931,7 @@
(truncate:<V_narrow> (match_operand:VN 1 "register_operand" "w")))]
"TARGET_NEON && !BYTES_BIG_ENDIAN"
"vmovn.i<V_sz_elem>\t%P0, %q1"
- [(set_attr "neon_type" "neon_shift_1")]
+ [(set_attr "type" "neon_shift_1")]
)
(define_expand "vec_pack_trunc_<mode>"
@@ -5930,7 +5954,7 @@
(match_operand:VDQ 2 "s_register_operand" "w"))))]
"TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
"vabd.<V_s_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
(if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
(const_string "neon_fp_vadd_ddd_vabs_dd")
@@ -5945,7 +5969,7 @@
UNSPEC_VSUB)))]
"TARGET_NEON && (!<Is_float_mode> || flag_unsafe_math_optimizations)"
"vabd.<V_if_elem> %<V_reg>0, %<V_reg>1, %<V_reg>2"
- [(set (attr "neon_type")
+ [(set (attr "type")
(if_then_else (ne (symbol_ref "<Is_float_mode>") (const_int 0))
(if_then_else (ne (symbol_ref "<Is_d_reg>") (const_int 0))
(const_string "neon_fp_vadd_ddd_vabs_dd")
diff --git a/gcc/config/arm/t-arm b/gcc/config/arm/t-arm
index 246f0f5b540..20e79ef2680 100644
--- a/gcc/config/arm/t-arm
+++ b/gcc/config/arm/t-arm
@@ -78,6 +78,11 @@ $(srcdir)/config/arm/arm-tables.opt: $(srcdir)/config/arm/genopt.sh \
$(SHELL) $(srcdir)/config/arm/genopt.sh $(srcdir)/config/arm > \
$(srcdir)/config/arm/arm-tables.opt
+aarch-common.o: $(srcdir)/config/arm/aarch-common.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(TM_H) $(TM_P_H) $(RTL_H) $(TREE_H) output.h $(C_COMMON_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/arm/aarch-common.c
+
arm.o: $(srcdir)/config/arm/arm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(RTL_H) $(TREE_H) $(HASH_TABLE_H) $(OBSTACK_H) $(REGS_H) hard-reg-set.h \
insn-config.h conditions.h output.h dumpfile.h \
diff --git a/gcc/config/arm/t-linux-eabi b/gcc/config/arm/t-linux-eabi
index 2f2f8ffa5e2..07e32b38de8 100644
--- a/gcc/config/arm/t-linux-eabi
+++ b/gcc/config/arm/t-linux-eabi
@@ -18,6 +18,8 @@
# We do not build a Thumb multilib for Linux because the definition of
# CLEAR_INSN_CACHE in linux-gas.h does not work in Thumb mode.
+# If you set MULTILIB_OPTIONS to a non-empty value you should also set
+# MULTILIB_DEFAULTS in linux-elf.h.
MULTILIB_OPTIONS =
MULTILIB_DIRNAMES =
diff --git a/gcc/config/arm/thumb2.md b/gcc/config/arm/thumb2.md
index 8b184a80c2e..3b5944a014a 100644
--- a/gcc/config/arm/thumb2.md
+++ b/gcc/config/arm/thumb2.md
@@ -36,7 +36,7 @@
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "shift" "2")
- (set_attr "type" "arlo_shift")]
+ (set_attr "type" "alu_shift_imm")]
)
;; We use the '0' constraint for operand 1 because reload should
@@ -58,7 +58,8 @@
""
[(set_attr "conds" "clob")
(set_attr "enabled_for_depr_it" "yes,yes,no")
- (set_attr "length" "6,6,10")]
+ (set_attr "length" "6,6,10")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_sminsi3"
@@ -78,7 +79,8 @@
""
[(set_attr "conds" "clob")
(set_attr "enabled_for_depr_it" "yes,yes,no")
- (set_attr "length" "6,6,10")]
+ (set_attr "length" "6,6,10")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb32_umaxsi3"
@@ -98,7 +100,8 @@
""
[(set_attr "conds" "clob")
(set_attr "length" "6,6,10")
- (set_attr "enabled_for_depr_it" "yes,yes,no")]
+ (set_attr "enabled_for_depr_it" "yes,yes,no")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_uminsi3"
@@ -118,7 +121,8 @@
""
[(set_attr "conds" "clob")
(set_attr "length" "6,6,10")
- (set_attr "enabled_for_depr_it" "yes,yes,no")]
+ (set_attr "enabled_for_depr_it" "yes,yes,no")
+ (set_attr "type" "multiple")]
)
;; Thumb-2 does not have rsc, so use a clever trick with shifter operands.
@@ -143,7 +147,8 @@
operands[1] = gen_lowpart (SImode, operands[1]);
}
[(set_attr "conds" "clob")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_abssi2"
@@ -200,7 +205,8 @@
(set_attr "predicable_short_it" "no")
(set_attr "enabled_for_depr_it" "yes,yes,no")
(set_attr "ce_count" "2")
- (set_attr "length" "8,6,10")]
+ (set_attr "length" "8,6,10")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_neg_abssi2"
@@ -257,7 +263,8 @@
(set_attr "enabled_for_depr_it" "yes,yes,no")
(set_attr "predicable_short_it" "no")
(set_attr "ce_count" "2")
- (set_attr "length" "8,6,10")]
+ (set_attr "length" "8,6,10")
+ (set_attr "type" "multiple")]
)
;; We have two alternatives here for memory loads (and similarly for stores)
@@ -282,7 +289,7 @@
ldr%?\\t%0, %1
str%?\\t%1, %0
str%?\\t%1, %0"
- [(set_attr "type" "*,arlo_imm,arlo_imm,arlo_imm,*,load1,load1,store1,store1")
+ [(set_attr "type" "mov_reg,alu_imm,alu_imm,alu_imm,mov_imm,load1,load1,store1,store1")
(set_attr "length" "2,4,2,4,4,4,4,4,4")
(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no")
@@ -303,7 +310,8 @@
INTVAL (operands[3]));
return \"add\\t%2, %|pc\;ldr%?\\t%0, [%2]\";
"
- [(set_attr "length" "4,4,6,6")]
+ [(set_attr "length" "4,4,6,6")
+ (set_attr "type" "multiple")]
)
;; Thumb-2 always has load/store halfword instructions, so we can avoid a lot
@@ -319,12 +327,27 @@
movw%?\\t%0, %L1\\t%@ movhi
str%(h%)\\t%1, %0\\t%@ movhi
ldr%(h%)\\t%0, %1\\t%@ movhi"
- [(set_attr "type" "*,*,store1,load1")
+ [(set_attr "type" "mov_imm,mov_reg,store1,load1")
(set_attr "predicable" "yes")
(set_attr "pool_range" "*,*,*,4094")
(set_attr "neg_pool_range" "*,*,*,250")]
)
+(define_insn "*thumb2_storewb_pairsi"
+ [(set (match_operand:SI 0 "register_operand" "=&kr")
+ (plus:SI (match_operand:SI 1 "register_operand" "0")
+ (match_operand:SI 2 "const_int_operand" "n")))
+ (set (mem:SI (plus:SI (match_dup 0) (match_dup 2)))
+ (match_operand:SI 3 "register_operand" "r"))
+ (set (mem:SI (plus:SI (match_dup 0)
+ (match_operand:SI 5 "const_int_operand" "n")))
+ (match_operand:SI 4 "register_operand" "r"))]
+ "TARGET_THUMB2
+ && INTVAL (operands[5]) == INTVAL (operands[2]) + 4"
+ "strd\\t%3, %4, [%0, %2]!"
+ [(set_attr "type" "store2")]
+)
+
(define_insn "*thumb2_cmpsi_neg_shiftsi"
[(set (reg:CC CC_REGNUM)
(compare:CC (match_operand:SI 0 "s_register_operand" "r")
@@ -335,7 +358,7 @@
"cmn%?\\t%0, %1%S3"
[(set_attr "conds" "set")
(set_attr "shift" "1")
- (set_attr "type" "arlo_shift")]
+ (set_attr "type" "alus_shift_imm")]
)
(define_insn_and_split "*thumb2_mov_scc"
@@ -352,7 +375,8 @@
""
[(set_attr "conds" "use")
(set_attr "enabled_for_depr_it" "yes,no")
- (set_attr "length" "8,10")]
+ (set_attr "length" "8,10")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_mov_negscc"
@@ -370,7 +394,8 @@
operands[3] = GEN_INT (~0);
}
[(set_attr "conds" "use")
- (set_attr "length" "10")]
+ (set_attr "length" "10")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_mov_negscc_strict_it"
@@ -398,7 +423,8 @@
}
[(set_attr "conds" "use")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_mov_notscc"
@@ -417,7 +443,8 @@
operands[4] = GEN_INT (~0);
}
[(set_attr "conds" "use")
- (set_attr "length" "10")]
+ (set_attr "length" "10")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_mov_notscc_strict_it"
@@ -439,7 +466,8 @@
VOIDmode, operands[2], const0_rtx);
}
[(set_attr "conds" "use")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_movsicc_insn"
@@ -499,7 +527,8 @@
}
[(set_attr "length" "4,4,6,6,6,6,10,10,10,10,6")
(set_attr "enabled_for_depr_it" "yes,yes,no,no,no,no,no,no,no,no,yes")
- (set_attr "conds" "use")]
+ (set_attr "conds" "use")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb2_movsfcc_soft_insn"
@@ -513,7 +542,8 @@
it\\t%D3\;mov%D3\\t%0, %2
it\\t%d3\;mov%d3\\t%0, %1"
[(set_attr "length" "6,6")
- (set_attr "conds" "use")]
+ (set_attr "conds" "use")
+ (set_attr "type" "multiple")]
)
(define_insn "*call_reg_thumb2"
@@ -542,7 +572,8 @@
(match_operand:SI 0 "register_operand" "l*r"))]
"TARGET_THUMB2"
"bx\\t%0"
- [(set_attr "conds" "clob")]
+ [(set_attr "conds" "clob")
+ (set_attr "type" "branch")]
)
;; Don't define thumb2_load_indirect_jump because we can't guarantee label
;; addresses will have the thumb bit set correctly.
@@ -570,6 +601,7 @@
operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
}
[(set_attr "conds" "use")
+ (set_attr "type" "multiple")
(set (attr "length") (if_then_else (match_test "arm_restrict_it")
(const_int 8)
(const_int 10)))]
@@ -602,7 +634,8 @@
operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
}
[(set_attr "conds" "use")
- (set_attr "length" "6,10")]
+ (set_attr "length" "6,10")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb2_ior_scc_strict_it"
@@ -615,7 +648,8 @@
it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1
mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1"
[(set_attr "conds" "use")
- (set_attr "length" "8")]
+ (set_attr "length" "8")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb2_cond_move"
@@ -664,7 +698,8 @@
return \"\";
"
[(set_attr "conds" "use")
- (set_attr "length" "6,6,10")]
+ (set_attr "length" "6,6,10")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb2_cond_arith"
@@ -701,7 +736,8 @@
return \"%i5%d4\\t%0, %1, #1\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "14")]
+ (set_attr "length" "14")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_cond_arith_strict_it"
@@ -770,7 +806,8 @@
FAIL;
}
[(set_attr "conds" "clob")
- (set_attr "length" "12")]
+ (set_attr "length" "12")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb2_cond_sub"
@@ -801,7 +838,8 @@
return \"sub%d4\\t%0, %1, #1\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "10,14")]
+ (set_attr "length" "10,14")
+ (set_attr "type" "multiple")]
)
(define_insn_and_split "*thumb2_negscc"
@@ -869,7 +907,8 @@
FAIL;
}
[(set_attr "conds" "clob")
- (set_attr "length" "14")]
+ (set_attr "length" "14")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb2_movcond"
@@ -952,7 +991,8 @@
return \"\";
"
[(set_attr "conds" "clob")
- (set_attr "length" "10,10,14")]
+ (set_attr "length" "10,10,14")
+ (set_attr "type" "multiple")]
)
;; Zero and sign extension instructions.
@@ -1015,7 +1055,8 @@
"TARGET_THUMB2 && !flag_pic"
"* return thumb2_output_casesi(operands);"
[(set_attr "conds" "clob")
- (set_attr "length" "16")]
+ (set_attr "length" "16")
+ (set_attr "type" "multiple")]
)
(define_insn "thumb2_casesi_internal_pic"
@@ -1033,7 +1074,8 @@
"TARGET_THUMB2 && flag_pic"
"* return thumb2_output_casesi(operands);"
[(set_attr "conds" "clob")
- (set_attr "length" "20")]
+ (set_attr "length" "20")
+ (set_attr "type" "multiple")]
)
(define_insn "*thumb2_return"
@@ -1070,7 +1112,8 @@
&& GET_CODE(operands[3]) != MINUS"
"%I3%!\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "2")]
+ (set_attr "length" "2")
+ (set_attr "type" "alu_reg")]
)
(define_insn "*thumb2_shiftsi3_short"
@@ -1087,8 +1130,8 @@
(set_attr "shift" "1")
(set_attr "length" "2")
(set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
- (const_string "arlo_shift")
- (const_string "arlo_shift_reg")))]
+ (const_string "alu_shift_imm")
+ (const_string "alu_shift_reg")))]
)
(define_insn "*thumb2_mov<mode>_shortim"
@@ -1098,7 +1141,8 @@
"TARGET_THUMB2 && reload_completed"
"mov%!\t%0, %1"
[(set_attr "predicable" "yes")
- (set_attr "length" "2")]
+ (set_attr "length" "2")
+ (set_attr "type" "mov_imm")]
)
(define_insn "*thumb2_addsi_short"
@@ -1122,7 +1166,8 @@
return \"add%!\\t%0, %1, %2\";
"
[(set_attr "predicable" "yes")
- (set_attr "length" "2")]
+ (set_attr "length" "2")
+ (set_attr "type" "alu_reg")]
)
(define_insn "*thumb2_subsi_short"
@@ -1133,7 +1178,8 @@
"TARGET_THUMB2 && reload_completed"
"sub%!\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "length" "2")]
+ (set_attr "length" "2")
+ (set_attr "type" "alu_reg")]
)
(define_peephole2
@@ -1185,7 +1231,8 @@
return \"adds\\t%0, %1, %2\";
"
[(set_attr "conds" "set")
- (set_attr "length" "2,2,4")]
+ (set_attr "length" "2,2,4")
+ (set_attr "type" "alu_reg")]
)
(define_insn "*thumb2_addsi3_compare0_scratch"
@@ -1210,7 +1257,7 @@
"
[(set_attr "conds" "set")
(set_attr "length" "2,2,4,4")
- (set_attr "type" "arlo_imm,*,arlo_imm,*")]
+ (set_attr "type" "alus_imm,alus_reg,alus_imm,alus_reg")]
)
(define_insn "*thumb2_mulsi_short"
@@ -1269,7 +1316,8 @@
(le (minus (match_dup 1) (pc)) (const_int 128))
(not (match_test "which_alternative")))
(const_int 2)
- (const_int 8)))]
+ (const_int 8)))
+ (set_attr "type" "branch,multiple")]
)
(define_insn "*thumb2_cbnz"
@@ -1292,7 +1340,8 @@
(le (minus (match_dup 1) (pc)) (const_int 128))
(not (match_test "which_alternative")))
(const_int 2)
- (const_int 8)))]
+ (const_int 8)))
+ (set_attr "type" "branch,multiple")]
)
(define_insn "*thumb2_one_cmplsi2_short"
@@ -1302,7 +1351,8 @@
"TARGET_THUMB2 && reload_completed"
"mvn%!\t%0, %1"
[(set_attr "predicable" "yes")
- (set_attr "length" "2")]
+ (set_attr "length" "2")
+ (set_attr "type" "mvn_reg")]
)
(define_insn "*thumb2_negsi2_short"
@@ -1312,7 +1362,8 @@
"TARGET_THUMB2 && reload_completed"
"neg%!\t%0, %1"
[(set_attr "predicable" "yes")
- (set_attr "length" "2")]
+ (set_attr "length" "2")
+ (set_attr "type" "alu_reg")]
)
(define_insn "*orsi_notsi_si"
@@ -1322,7 +1373,8 @@
"TARGET_THUMB2"
"orn%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
- (set_attr "predicable_short_it" "no")]
+ (set_attr "predicable_short_it" "no")
+ (set_attr "type" "logic_reg")]
)
(define_insn "*orsi_not_shiftsi_si"
@@ -1336,7 +1388,7 @@
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "shift" "2")
- (set_attr "type" "arlo_shift")]
+ (set_attr "type" "alu_shift_imm")]
)
(define_peephole2
diff --git a/gcc/config/arm/types.md b/gcc/config/arm/types.md
new file mode 100644
index 00000000000..7a96438fd48
--- /dev/null
+++ b/gcc/config/arm/types.md
@@ -0,0 +1,563 @@
+;; Instruction Classification for ARM for GNU compiler.
+
+;; Copyright (C) 1991-2013 Free Software Foundation, Inc.
+;; Contributed by ARM 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.
+
+;; 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/>.
+
+; TYPE attribute is used to classify instructions for use in scheduling.
+;
+; Instruction classification:
+;
+; adc_imm add/subtract with carry and with an immediate operand.
+; adc_reg add/subtract with carry and no immediate operand.
+; adcs_imm as adc_imm, setting condition flags.
+; adcs_reg as adc_reg, setting condition flags.
+; adr calculate address.
+; alu_ext From ARMv8-A: any arithmetic instruction that has a
+; sign/zero-extended.
+; AArch64 Only.
+; source operand
+; alu_imm any arithmetic instruction that doesn't have a shifted
+; operand and has an immediate operand. This
+; excludes MOV, MVN and RSB(S) immediate.
+; alu_reg any arithmetic instruction that doesn't have a shifted
+; or an immediate operand. This excludes
+; MOV and MVN but includes MOVT. This is also the default.
+; alu_shift_imm any arithmetic instruction that has a source operand
+; shifted by a constant. This excludes simple shifts.
+; alu_shift_reg as alu_shift_imm, with the shift amount specified in a
+; register.
+; alus_ext From ARMv8-A: as alu_ext, setting condition flags.
+; AArch64 Only.
+; alus_imm as alu_imm, setting condition flags.
+; alus_reg as alu_reg, setting condition flags.
+; alus_shift_imm as alu_shift_imm, setting condition flags.
+; alus_shift_reg as alu_shift_reg, setting condition flags.
+; bfm bitfield move operation.
+; block blockage insn, this blocks all functional units.
+; branch branch.
+; call subroutine call.
+; clz count leading zeros (CLZ).
+; csel From ARMv8-A: conditional select.
+; extend extend instruction (SXTB, SXTH, UXTB, UXTH).
+; f_cvt conversion between float representations.
+; f_cvtf2i conversion between float and integral types.
+; f_cvti2f conversion between integral and float types.
+; f_flag transfer of co-processor flags to the CPSR.
+; f_load[d,s] double/single load from memory. Used for VFP unit.
+; f_mcr transfer arm to vfp reg.
+; f_mcrr transfer two arm regs to vfp reg.
+; f_minmax[d,s] double/single floating point minimum/maximum.
+; f_mrc transfer vfp to arm reg.
+; f_mrrc transfer vfp to two arm regs.
+; f_rint[d,s] double/single floating point rount to integral.
+; f_sel[d,s] double/single floating byte select.
+; f_store[d,s] double/single store to memory. Used for VFP unit.
+; fadd[d,s] double/single floating-point scalar addition.
+; fcmp[d,s] double/single floating-point compare.
+; fconst[d,s] double/single load immediate.
+; fcsel From ARMv8-A: Floating-point conditional select.
+; fdiv[d,s] double/single precision floating point division.
+; ffarith[d,s] double/single floating point abs/neg/cpy.
+; ffma[d,s] double/single floating point fused multiply-accumulate.
+; float floating point arithmetic operation.
+; fmac[d,s] double/single floating point multiply-accumulate.
+; fmov floating point to floating point register move.
+; fmul[d,s] double/single floating point multiply.
+; fsqrt[d,s] double/single precision floating point square root.
+; load_acq load-acquire.
+; load_byte load byte(s) from memory to arm registers.
+; load1 load 1 word from memory to arm registers.
+; load2 load 2 words from memory to arm registers.
+; load3 load 3 words from memory to arm registers.
+; load4 load 4 words from memory to arm registers.
+; logic_imm any logical instruction that doesn't have a shifted
+; operand and has an immediate operand.
+; logic_reg any logical instruction that doesn't have a shifted
+; operand or an immediate operand.
+; logic_shift_imm any logical instruction that has a source operand
+; shifted by a constant. This excludes simple shifts.
+; logic_shift_reg as logic_shift_imm, with the shift amount specified in a
+; register.
+; logics_imm as logic_imm, setting condition flags.
+; logics_reg as logic_reg, setting condition flags.
+; logics_shift_imm as logic_shift_imm, setting condition flags.
+; logics_shift_reg as logic_shift_reg, setting condition flags.
+; mla integer multiply accumulate.
+; mlas integer multiply accumulate, flag setting.
+; mov_imm simple MOV instruction that moves an immediate to
+; register. This includes MOVW, but not MOVT.
+; mov_reg simple MOV instruction that moves a register to another
+; register. This includes MOVW, but not MOVT.
+; mov_shift simple MOV instruction, shifted operand by a constant.
+; mov_shift_reg simple MOV instruction, shifted operand by a register.
+; mrs system/special/co-processor register move.
+; mul integer multiply.
+; muls integer multiply, flag setting.
+; multiple more than one instruction, candidate for future
+; splitting, or better modeling.
+; mvn_imm inverting move instruction, immediate.
+; mvn_reg inverting move instruction, register.
+; mvn_shift inverting move instruction, shifted operand by a constant.
+; mvn_shift_reg inverting move instruction, shifted operand by a register.
+; no_insn an insn which does not represent an instruction in the
+; final output, thus having no impact on scheduling.
+; rbit reverse bits.
+; rev reverse bytes.
+; sdiv signed division.
+; shift_imm simple shift operation (LSL, LSR, ASR, ROR) with an
+; immediate.
+; shift_reg simple shift by a register.
+; smlad signed multiply accumulate dual.
+; smladx signed multiply accumulate dual reverse.
+; smlal signed multiply accumulate long.
+; smlald signed multiply accumulate long dual.
+; smlals signed multiply accumulate long, flag setting.
+; smlalxy signed multiply accumulate, 16x16-bit, 64-bit accumulate.
+; smlawx signed multiply accumulate, 32x16-bit, 32-bit accumulate.
+; smlawy signed multiply accumulate wide, 32x16-bit,
+; 32-bit accumulate.
+; smlaxy signed multiply accumulate, 16x16-bit, 32-bit accumulate.
+; smlsd signed multiply subtract dual.
+; smlsdx signed multiply subtract dual reverse.
+; smlsld signed multiply subtract long dual.
+; smmla signed most significant word multiply accumulate.
+; smmul signed most significant word multiply.
+; smmulr signed most significant word multiply, rounded.
+; smuad signed dual multiply add.
+; smuadx signed dual multiply add reverse.
+; smull signed multiply long.
+; smulls signed multiply long, flag setting.
+; smulwy signed multiply wide, 32x16-bit, 32-bit accumulate.
+; smulxy signed multiply, 16x16-bit, 32-bit accumulate.
+; smusd signed dual multiply subtract.
+; smusdx signed dual multiply subtract reverse.
+; store_rel store-release.
+; store1 store 1 word to memory from arm registers.
+; store2 store 2 words to memory from arm registers.
+; store3 store 3 words to memory from arm registers.
+; store4 store 4 (or more) words to memory from arm registers.
+; udiv unsigned division.
+; umaal unsigned multiply accumulate accumulate long.
+; umlal unsigned multiply accumulate long.
+; umlals unsigned multiply accumulate long, flag setting.
+; umull unsigned multiply long.
+; umulls unsigned multiply long, flag setting.
+; untyped insn without type information - default, and error,
+; case.
+;
+; The classification below is for instructions used by the Wireless MMX
+; Technology. Each attribute value is used to classify an instruction of the
+; same name or family.
+;
+; wmmx_tandc
+; wmmx_tbcst
+; wmmx_textrc
+; wmmx_textrm
+; wmmx_tinsr
+; wmmx_tmcr
+; wmmx_tmcrr
+; wmmx_tmia
+; wmmx_tmiaph
+; wmmx_tmiaxy
+; wmmx_tmrc
+; wmmx_tmrrc
+; wmmx_tmovmsk
+; wmmx_torc
+; wmmx_torvsc
+; wmmx_wabs
+; wmmx_wdiff
+; wmmx_wacc
+; wmmx_wadd
+; wmmx_waddbhus
+; wmmx_waddsubhx
+; wmmx_waligni
+; wmmx_walignr
+; wmmx_wand
+; wmmx_wandn
+; wmmx_wavg2
+; wmmx_wavg4
+; wmmx_wcmpeq
+; wmmx_wcmpgt
+; wmmx_wmac
+; wmmx_wmadd
+; wmmx_wmax
+; wmmx_wmerge
+; wmmx_wmiawxy
+; wmmx_wmiaxy
+; wmmx_wmin
+; wmmx_wmov
+; wmmx_wmul
+; wmmx_wmulw
+; wmmx_wldr
+; wmmx_wor
+; wmmx_wpack
+; wmmx_wqmiaxy
+; wmmx_wqmulm
+; wmmx_wqmulwm
+; wmmx_wror
+; wmmx_wsad
+; wmmx_wshufh
+; wmmx_wsll
+; wmmx_wsra
+; wmmx_wsrl
+; wmmx_wstr
+; wmmx_wsub
+; wmmx_wsubaddhx
+; wmmx_wunpckeh
+; wmmx_wunpckel
+; wmmx_wunpckih
+; wmmx_wunpckil
+; wmmx_wxor
+;
+; The classification below is for NEON instructions.
+;
+; neon_bp_2cycle
+; neon_bp_3cycle
+; neon_bp_simple
+; neon_fp_vadd_ddd_vabs_dd
+; neon_fp_vadd_qqq_vabs_qq
+; neon_fp_vmla_ddd_scalar
+; neon_fp_vmla_ddd
+; neon_fp_vmla_qqq_scalar
+; neon_fp_vmla_qqq
+; neon_fp_vmul_ddd
+; neon_fp_vmul_qqd
+; neon_fp_vrecps_vrsqrts_ddd
+; neon_fp_vrecps_vrsqrts_qqq
+; neon_fp_vsum
+; neon_int_1
+; neon_int_2
+; neon_int_3
+; neon_int_4
+; neon_int_5
+; neon_ldm_2
+; neon_ldr
+; neon_mcr_2_mcrr
+; neon_mcr
+; neon_mla_ddd_16_scalar_qdd_32_16_long_scalar
+; neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long
+; neon_mla_ddd_8_16_qdd_16_8_long_32_16_long
+; neon_mla_qqq_32_qqd_32_scalar
+; neon_mla_qqq_8_16
+; neon_mrc
+; neon_mrrc
+; neon_mul_ddd_16_scalar_32_16_long_scalar
+; neon_mul_ddd_8_16_qdd_16_8_long_32_16_long
+; neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar
+; neon_mul_qqd_32_scalar
+; neon_mul_qqq_8_16_32_ddd_32
+; neon_shift_1
+; neon_shift_2
+; neon_shift_3
+; neon_stm_2
+; neon_str
+; neon_vaba_qqq
+; neon_vaba
+; neon_vld1_1_2_regs
+; neon_vld1_3_4_regs
+; neon_vld1_vld2_lane
+; neon_vld2_2_regs_vld1_vld2_all_lanes
+; neon_vld2_4_regs
+; neon_vld3_vld4_all_lanes
+; neon_vld3_vld4_lane
+; neon_vld3_vld4
+; neon_vmov
+; neon_vqneg_vqabs
+; neon_vqshl_vrshl_vqrshl_qqq
+; neon_vshl_ddd
+; neon_vsma
+; neon_vsra_vrsra
+; neon_vst1_1_2_regs_vst2_2_regs
+; neon_vst1_3_4_regs
+; neon_vst1_vst2_lane
+; neon_vst2_4_regs_vst3_vst4
+; neon_vst3_vst4_lane
+; neon_vst3_vst4
+
+(define_attr "type"
+ "adc_imm,\
+ adc_reg,\
+ adcs_imm,\
+ adcs_reg,\
+ adr,\
+ alu_ext,\
+ alu_imm,\
+ alu_reg,\
+ alu_shift_imm,\
+ alu_shift_reg,\
+ alus_ext,\
+ alus_imm,\
+ alus_reg,\
+ alus_shift_imm,\
+ alus_shift_reg,\
+ bfm,\
+ block,\
+ branch,\
+ call,\
+ clz,\
+ no_insn,\
+ csel,\
+ extend,\
+ f_cvt,\
+ f_cvtf2i,\
+ f_cvti2f,\
+ f_flag,\
+ f_loadd,\
+ f_loads,\
+ f_mcr,\
+ f_mcrr,\
+ f_minmaxd,\
+ f_minmaxs,\
+ f_mrc,\
+ f_mrrc,\
+ f_rintd,\
+ f_rints,\
+ f_seld,\
+ f_sels,\
+ f_stored,\
+ f_stores,\
+ faddd,\
+ fadds,\
+ fcmpd,\
+ fcmps,\
+ fconstd,\
+ fconsts,\
+ fcsel,\
+ fdivd,\
+ fdivs,\
+ ffarithd,\
+ ffariths,\
+ ffmad,\
+ ffmas,\
+ float,\
+ fmacd,\
+ fmacs,\
+ fmov,\
+ fmuld,\
+ fmuls,\
+ fsqrts,\
+ fsqrtd,\
+ load_acq,\
+ load_byte,\
+ load1,\
+ load2,\
+ load3,\
+ load4,\
+ logic_imm,\
+ logic_reg,\
+ logic_shift_imm,\
+ logic_shift_reg,\
+ logics_imm,\
+ logics_reg,\
+ logics_shift_imm,\
+ logics_shift_reg,\
+ mla,\
+ mlas,\
+ mov_imm,\
+ mov_reg,\
+ mov_shift,\
+ mov_shift_reg,\
+ mrs,\
+ mul,\
+ muls,\
+ multiple,\
+ mvn_imm,\
+ mvn_reg,\
+ mvn_shift,\
+ mvn_shift_reg,\
+ nop,\
+ rbit,\
+ rev,\
+ sdiv,\
+ shift_imm,\
+ shift_reg,\
+ smlad,\
+ smladx,\
+ smlal,\
+ smlald,\
+ smlals,\
+ smlalxy,\
+ smlawx,\
+ smlawy,\
+ smlaxy,\
+ smlsd,\
+ smlsdx,\
+ smlsld,\
+ smmla,\
+ smmul,\
+ smmulr,\
+ smuad,\
+ smuadx,\
+ smull,\
+ smulls,\
+ smulwy,\
+ smulxy,\
+ smusd,\
+ smusdx,\
+ store_rel,\
+ store1,\
+ store2,\
+ store3,\
+ store4,\
+ udiv,\
+ umaal,\
+ umlal,\
+ umlals,\
+ umull,\
+ umulls,\
+ untyped,\
+ wmmx_tandc,\
+ wmmx_tbcst,\
+ wmmx_textrc,\
+ wmmx_textrm,\
+ wmmx_tinsr,\
+ wmmx_tmcr,\
+ wmmx_tmcrr,\
+ wmmx_tmia,\
+ wmmx_tmiaph,\
+ wmmx_tmiaxy,\
+ wmmx_tmrc,\
+ wmmx_tmrrc,\
+ wmmx_tmovmsk,\
+ wmmx_torc,\
+ wmmx_torvsc,\
+ wmmx_wabs,\
+ wmmx_wabsdiff,\
+ wmmx_wacc,\
+ wmmx_wadd,\
+ wmmx_waddbhus,\
+ wmmx_waddsubhx,\
+ wmmx_waligni,\
+ wmmx_walignr,\
+ wmmx_wand,\
+ wmmx_wandn,\
+ wmmx_wavg2,\
+ wmmx_wavg4,\
+ wmmx_wcmpeq,\
+ wmmx_wcmpgt,\
+ wmmx_wmac,\
+ wmmx_wmadd,\
+ wmmx_wmax,\
+ wmmx_wmerge,\
+ wmmx_wmiawxy,\
+ wmmx_wmiaxy,\
+ wmmx_wmin,\
+ wmmx_wmov,\
+ wmmx_wmul,\
+ wmmx_wmulw,\
+ wmmx_wldr,\
+ wmmx_wor,\
+ wmmx_wpack,\
+ wmmx_wqmiaxy,\
+ wmmx_wqmulm,\
+ wmmx_wqmulwm,\
+ wmmx_wror,\
+ wmmx_wsad,\
+ wmmx_wshufh,\
+ wmmx_wsll,\
+ wmmx_wsra,\
+ wmmx_wsrl,\
+ wmmx_wstr,\
+ wmmx_wsub,\
+ wmmx_wsubaddhx,\
+ wmmx_wunpckeh,\
+ wmmx_wunpckel,\
+ wmmx_wunpckih,\
+ wmmx_wunpckil,\
+ wmmx_wxor,\
+ neon_bp_2cycle,\
+ neon_bp_3cycle,\
+ neon_bp_simple,\
+ neon_fp_vadd_ddd_vabs_dd,\
+ neon_fp_vadd_qqq_vabs_qq,\
+ neon_fp_vmla_ddd_scalar,\
+ neon_fp_vmla_ddd,\
+ neon_fp_vmla_qqq_scalar,\
+ neon_fp_vmla_qqq,\
+ neon_fp_vmul_ddd,\
+ neon_fp_vmul_qqd,\
+ neon_fp_vrecps_vrsqrts_ddd,\
+ neon_fp_vrecps_vrsqrts_qqq,\
+ neon_fp_vsum,\
+ neon_int_1,\
+ neon_int_2,\
+ neon_int_3,\
+ neon_int_4,\
+ neon_int_5,\
+ neon_ldm_2,\
+ neon_ldr,\
+ neon_mcr_2_mcrr,\
+ neon_mcr,\
+ neon_mla_ddd_16_scalar_qdd_32_16_long_scalar,\
+ neon_mla_ddd_32_qqd_16_ddd_32_scalar_qdd_64_32_long_scalar_qdd_64_32_long,\
+ neon_mla_ddd_8_16_qdd_16_8_long_32_16_long,\
+ neon_mla_qqq_32_qqd_32_scalar,\
+ neon_mla_qqq_8_16,\
+ neon_mrc,\
+ neon_mrrc,\
+ neon_mul_ddd_16_scalar_32_16_long_scalar,\
+ neon_mul_ddd_8_16_qdd_16_8_long_32_16_long,\
+ neon_mul_qdd_64_32_long_qqd_16_ddd_32_scalar_64_32_long_scalar,\
+ neon_mul_qqd_32_scalar,\
+ neon_mul_qqq_8_16_32_ddd_32,\
+ neon_shift_1,\
+ neon_shift_2,\
+ neon_shift_3,\
+ neon_stm_2,\
+ neon_str,\
+ neon_vaba_qqq,\
+ neon_vaba,\
+ neon_vld1_1_2_regs,\
+ neon_vld1_3_4_regs,\
+ neon_vld1_vld2_lane,\
+ neon_vld2_2_regs_vld1_vld2_all_lanes,\
+ neon_vld2_4_regs,\
+ neon_vld3_vld4_all_lanes,\
+ neon_vld3_vld4_lane,\
+ neon_vld3_vld4,\
+ neon_vmov,\
+ neon_vqneg_vqabs,\
+ neon_vqshl_vrshl_vqrshl_qqq,\
+ neon_vshl_ddd,\
+ neon_vsma,\
+ neon_vsra_vrsra,\
+ neon_vst1_1_2_regs_vst2_2_regs,\
+ neon_vst1_3_4_regs,\
+ neon_vst1_vst2_lane,\
+ neon_vst2_4_regs_vst3_vst4,\
+ neon_vst3_vst4_lane,\
+ neon_vst3_vst4"
+ (const_string "untyped"))
+
+; Is this an (integer side) multiply with a 32-bit (or smaller) result?
+(define_attr "mul32" "no,yes"
+ (if_then_else
+ (eq_attr "type"
+ "smulxy,smlaxy,smulwy,smlawx,mul,muls,mla,mlas,smlawy,smuad,smuadx,\
+ smlad,smladx,smusd,smusdx,smlsd,smlsdx,smmul,smmulr,smmla,smlald,smlsld")
+ (const_string "yes")
+ (const_string "no")))
+
+; Is this an (integer side) multiply with a 64-bit result?
+(define_attr "mul64" "no,yes"
+ (if_then_else
+ (eq_attr "type"
+ "smlalxy,umull,umulls,umaal,umlal,umlals,smull,smulls,smlal,smlals")
+ (const_string "yes")
+ (const_string "no")))
diff --git a/gcc/config/arm/vfp.md b/gcc/config/arm/vfp.md
index ef8777a900b..9318e49d9ea 100644
--- a/gcc/config/arm/vfp.md
+++ b/gcc/config/arm/vfp.md
@@ -53,8 +53,7 @@
}
"
[(set_attr "predicable" "yes")
- (set_attr "type" "mov_reg,mov_reg,mvn_imm,mov_imm,load1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores")
- (set_attr "neon_type" "*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*")
+ (set_attr "type" "mov_reg,mov_reg,mvn_imm,mov_imm,load1,store1,f_mcr,f_mrc,fmov,f_loads,f_stores")
(set_attr "pool_range" "*,*,*,*,4096,*,*,*,*,1020,*")
(set_attr "neg_pool_range" "*,*,*,*,4084,*,*,*,*,1008,*")]
)
@@ -101,9 +100,8 @@
"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no,no,no,no,no,no")
- (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_reg,load1,load1,store1,store1,r_2_f,f_2_r,fcpys,f_loads,f_stores")
+ (set_attr "type" "mov_reg,mov_reg,mov_reg,mvn_reg,mov_reg,load1,load1,store1,store1,f_mcr,f_mrc,fmov,f_loads,f_stores")
(set_attr "length" "2,4,2,4,4,4,4,4,4,4,4,4,4,4")
- (set_attr "neon_type" "*,*,*,*,*,*,*,*,*,neon_mcr,neon_mrc,neon_vmov,*,*")
(set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*,*,*,*,1018,*")
(set_attr "neg_pool_range" "*,*,*,*,*, 0, 0,*,*,*,*,*,1008,*")]
)
@@ -146,8 +144,7 @@
gcc_unreachable ();
}
"
- [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
- (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
+ [(set_attr "type" "multiple,multiple,multiple,multiple,load2,load2,store2,f_mcrr,f_mrrc,ffarithd,f_loadd,f_stored")
(set (attr "length") (cond [(eq_attr "alternative" "1,4,5,6") (const_int 8)
(eq_attr "alternative" "2") (const_int 12)
(eq_attr "alternative" "3") (const_int 16)
@@ -195,8 +192,7 @@
gcc_unreachable ();
}
"
- [(set_attr "type" "*,*,*,*,load2,load2,store2,r_2_f,f_2_r,ffarithd,f_loadd,f_stored")
- (set_attr "neon_type" "*,*,*,*,*,*,*,neon_mcr_2_mcrr,neon_mrrc,neon_vmov,*,*")
+ [(set_attr "type" "multiple,multiple,multiple,multiple,load2,load2,store2,f_mcrr,f_mrrc,ffarithd,f_loadd,f_stored")
(set (attr "length") (cond [(eq_attr "alternative" "1") (const_int 8)
(eq_attr "alternative" "2") (const_int 12)
(eq_attr "alternative" "3") (const_int 16)
@@ -264,8 +260,8 @@
}
"
[(set_attr "conds" "unconditional")
- (set_attr "type" "*,*,load1,store1,fcpys,*,r_2_f,f_2_r,*")
- (set_attr "neon_type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,*,*,*,*,*,*,*")
+ (set_attr "type" "neon_vld1_1_2_regs,neon_vst1_1_2_regs_vst2_2_regs,\
+ load1,store1,fmov,mov_reg,f_mcr,f_mrc,multiple")
(set_attr "length" "4,4,4,4,4,4,4,4,8")]
)
@@ -315,7 +311,7 @@
}
"
[(set_attr "conds" "unconditional")
- (set_attr "type" "load1,store1,fcpys,*,r_2_f,f_2_r,*")
+ (set_attr "type" "load1,store1,fmov,mov_reg,f_mcr,f_mrc,multiple")
(set_attr "length" "4,4,4,4,4,4,8")]
)
@@ -355,8 +351,7 @@
"
[(set_attr "predicable" "yes")
(set_attr "type"
- "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,mov_reg")
- (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*")
+ "f_mcr,f_mrc,fconsts,f_loads,f_stores,load1,store1,fmov,mov_reg")
(set_attr "pool_range" "*,*,*,1020,*,4096,*,*,*")
(set_attr "neg_pool_range" "*,*,*,1008,*,4080,*,*,*")]
)
@@ -393,8 +388,7 @@
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
(set_attr "type"
- "r_2_f,f_2_r,fconsts,f_loads,f_stores,load1,store1,fcpys,mov_reg")
- (set_attr "neon_type" "neon_mcr,neon_mrc,*,*,*,*,*,neon_vmov,*")
+ "f_mcr,f_mrc,fconsts,f_loads,f_stores,load1,store1,fmov,mov_reg")
(set_attr "pool_range" "*,*,*,1018,*,4090,*,*,*")
(set_attr "neg_pool_range" "*,*,*,1008,*,0,*,*,*")]
)
@@ -434,9 +428,8 @@
}
}
"
- [(set_attr "type"
- "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*")
- (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*")
+ [(set_attr "type" "f_mcrr,f_mrrc,fconstd,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")
(if_then_else
@@ -480,9 +473,8 @@
}
}
"
- [(set_attr "type"
- "r_2_f,f_2_r,fconstd,f_loadd,f_stored,load2,store2,ffarithd,*")
- (set_attr "neon_type" "neon_mcr_2_mcrr,neon_mrrc,*,*,*,*,*,neon_vmov,*")
+ [(set_attr "type" "f_mcrr,f_mrrc,fconstd,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")
(if_then_else
@@ -517,8 +509,7 @@
fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
[(set_attr "conds" "use")
(set_attr "length" "4,4,8,4,4,8,4,4,8")
- (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
- (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")]
+ (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")]
)
(define_insn "*thumb2_movsfcc_vfp"
@@ -541,8 +532,7 @@
ite\\t%D3\;fmrs%D3\\t%0, %2\;fmrs%d3\\t%0, %1"
[(set_attr "conds" "use")
(set_attr "length" "6,6,10,6,6,10,6,6,10")
- (set_attr "type" "fcpys,fcpys,fcpys,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
- (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr,neon_mcr,neon_mcr,neon_mrc,neon_mrc,neon_mrc")]
+ (set_attr "type" "fmov,fmov,fmov,f_mcr,f_mcr,f_mcr,f_mrc,f_mrc,f_mrc")]
)
(define_insn "*movdfcc_vfp"
@@ -565,8 +555,7 @@
fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
[(set_attr "conds" "use")
(set_attr "length" "4,4,8,4,4,8,4,4,8")
- (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
- (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")]
+ (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcr,f_mrrc,f_mrrc,f_mrrc")]
)
(define_insn "*thumb2_movdfcc_vfp"
@@ -589,8 +578,7 @@
ite\\t%D3\;fmrrd%D3\\t%Q0, %R0, %P2\;fmrrd%d3\\t%Q0, %R0, %P1"
[(set_attr "conds" "use")
(set_attr "length" "6,6,10,6,6,10,6,6,10")
- (set_attr "type" "ffarithd,ffarithd,ffarithd,r_2_f,r_2_f,r_2_f,f_2_r,f_2_r,f_2_r")
- (set_attr "neon_type" "neon_vmov,neon_vmov,neon_vmov,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mcr_2_mcrr,neon_mrrc,neon_mrrc,neon_mrrc")]
+ (set_attr "type" "ffarithd,ffarithd,ffarithd,f_mcr,f_mcr,f_mcrr,f_mrrc,f_mrrc,f_mrrc")]
)
@@ -1003,7 +991,7 @@
"ftosizs%?\\t%0, %1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvtf2i")]
)
(define_insn "*truncsidf2_vfp"
@@ -1013,7 +1001,7 @@
"ftosizd%?\\t%0, %P1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvtf2i")]
)
@@ -1024,7 +1012,7 @@
"ftouizs%?\\t%0, %1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvtf2i")]
)
(define_insn "fixuns_truncdfsi2"
@@ -1034,7 +1022,7 @@
"ftouizd%?\\t%0, %P1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvtf2i")]
)
@@ -1045,7 +1033,7 @@
"fsitos%?\\t%0, %1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvti2f")]
)
(define_insn "*floatsidf2_vfp"
@@ -1055,7 +1043,7 @@
"fsitod%?\\t%P0, %1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvti2f")]
)
@@ -1066,7 +1054,7 @@
"fuitos%?\\t%0, %1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvti2f")]
)
(define_insn "floatunssidf2"
@@ -1076,7 +1064,7 @@
"fuitod%?\\t%P0, %1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvti2f")]
)
@@ -1089,7 +1077,7 @@
"fsqrts%?\\t%0, %1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "fdivs")]
+ (set_attr "type" "fsqrts")]
)
(define_insn "*sqrtdf2_vfp"
@@ -1099,7 +1087,7 @@
"fsqrtd%?\\t%P0, %P1"
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")
- (set_attr "type" "fdivd")]
+ (set_attr "type" "fsqrtd")]
)
@@ -1241,7 +1229,7 @@
"TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP3 && !flag_rounding_math"
"vcvt.f32.<FCVTI32typename>\\t%0, %1, %v2"
[(set_attr "predicable" "no")
- (set_attr "type" "f_cvt")]
+ (set_attr "type" "f_cvti2f")]
)
;; Not the ideal way of implementing this. Ideally we would be able to split
@@ -1258,7 +1246,7 @@
vmov.f32\\t%0, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2
vmov.f64\\t%P0, %1, %1\;vcvt.f64.<FCVTI32typename>\\t%P0, %P0, %v2"
[(set_attr "predicable" "no")
- (set_attr "type" "f_cvt")
+ (set_attr "type" "f_cvti2f")
(set_attr "length" "8")]
)
diff --git a/gcc/config/arm/vfp11.md b/gcc/config/arm/vfp11.md
index b027fe6c3cd..4cfa69efc24 100644
--- a/gcc/config/arm/vfp11.md
+++ b/gcc/config/arm/vfp11.md
@@ -51,12 +51,13 @@
(define_insn_reservation "vfp_ffarith" 4
(and (eq_attr "generic_vfp" "yes")
- (eq_attr "type" "fcpys,ffariths,ffarithd,fcmps,fcmpd"))
+ (eq_attr "type" "fmov,ffariths,ffarithd,fcmps,fcmpd"))
"fmac")
(define_insn_reservation "vfp_farith" 8
(and (eq_attr "generic_vfp" "yes")
- (eq_attr "type" "fadds,faddd,fconsts,fconstd,f_cvt,fmuls,fmacs,ffmas"))
+ (eq_attr "type" "fadds,faddd,fconsts,fconstd,f_cvt,f_cvtf2i,f_cvti2f,\
+ fmuls,fmacs,ffmas"))
"fmac")
(define_insn_reservation "vfp_fmul" 9
@@ -66,23 +67,23 @@
(define_insn_reservation "vfp_fdivs" 19
(and (eq_attr "generic_vfp" "yes")
- (eq_attr "type" "fdivs"))
+ (eq_attr "type" "fdivs, fsqrts"))
"ds*15")
(define_insn_reservation "vfp_fdivd" 33
(and (eq_attr "generic_vfp" "yes")
- (eq_attr "type" "fdivd"))
+ (eq_attr "type" "fdivd, fsqrtd"))
"fmac+ds*29")
;; Moves to/from arm regs also use the load/store pipeline.
(define_insn_reservation "vfp_fload" 4
(and (eq_attr "generic_vfp" "yes")
- (eq_attr "type" "f_loads,f_loadd,r_2_f"))
+ (eq_attr "type" "f_loads,f_loadd,f_mcr,f_mcrr"))
"vfp_ls")
(define_insn_reservation "vfp_fstore" 4
(and (eq_attr "generic_vfp" "yes")
- (eq_attr "type" "f_stores,f_stored,f_2_r"))
+ (eq_attr "type" "f_stores,f_stored,f_mrc,f_mrrc"))
"vfp_ls")
(define_insn_reservation "vfp_to_cpsr" 4
diff --git a/gcc/config/avr/avr-stdint.h b/gcc/config/avr/avr-stdint.h
index 8e7278f389a..4137b0689a5 100644
--- a/gcc/config/avr/avr-stdint.h
+++ b/gcc/config/avr/avr-stdint.h
@@ -34,11 +34,11 @@ along with GCC; see the file COPYING3. If not see
#define SIG_ATOMIC_TYPE "char"
#define INT8_TYPE "signed char"
-#define INT16_TYPE (INT_TYPE_SIZE == 16 ? "short int" : "long int")
+#define INT16_TYPE (INT_TYPE_SIZE == 16 ? "int" : "long int")
#define INT32_TYPE (INT_TYPE_SIZE == 16 ? "long int" : "long long int")
#define INT64_TYPE (INT_TYPE_SIZE == 16 ? "long long int" : 0)
#define UINT8_TYPE "unsigned char"
-#define UINT16_TYPE (INT_TYPE_SIZE == 16 ? "short unsigned int" : "long unsigned int")
+#define UINT16_TYPE (INT_TYPE_SIZE == 16 ? "unsigned int" : "long unsigned int")
#define UINT32_TYPE (INT_TYPE_SIZE == 16 ? "long unsigned int" : "long long unsigned int")
#define UINT64_TYPE (INT_TYPE_SIZE == 16 ? "long long unsigned int" : 0)
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 14a3eee7c72..f6d88856bec 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -7030,7 +7030,9 @@ avr_out_fract (rtx insn, rtx operands[], bool intsigned, int *plen)
RTX_CODE shift = UNKNOWN;
bool sign_in_carry = false;
bool msb_in_carry = false;
+ bool lsb_in_tmp_reg = false;
bool lsb_in_carry = false;
+ bool frac_rounded = false;
const char *code_ashift = "lsl %0";
@@ -7038,6 +7040,7 @@ avr_out_fract (rtx insn, rtx operands[], bool intsigned, int *plen)
/* Shorthand used below. */ \
((sign_bytes \
&& IN_RANGE (RR, dest.regno_msb - sign_bytes + 1, dest.regno_msb)) \
+ || (offset && IN_RANGE (RR, dest.regno, dest.regno_msb)) \
|| (reg_unused_after (insn, all_regs_rtx[RR]) \
&& !IN_RANGE (RR, dest.regno, dest.regno_msb)))
@@ -7112,13 +7115,119 @@ avr_out_fract (rtx insn, rtx operands[], bool intsigned, int *plen)
else
gcc_unreachable();
+ /* If we need to round the fraction part, we might need to save/round it
+ before clobbering any of it in Step 1. Also, we might to want to do
+ the rounding now to make use of LD_REGS. */
+ if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
+ && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
+ && !TARGET_FRACT_CONV_TRUNC)
+ {
+ bool overlap
+ = (src.regno <=
+ (offset ? dest.regno_msb - sign_bytes : dest.regno + zero_bytes - 1)
+ && dest.regno - offset -1 >= dest.regno);
+ unsigned s0 = dest.regno - offset -1;
+ bool use_src = true;
+ unsigned sn;
+ unsigned copied_msb = src.regno_msb;
+ bool have_carry = false;
+
+ if (src.ibyte > dest.ibyte)
+ copied_msb -= src.ibyte - dest.ibyte;
+
+ for (sn = s0; sn <= copied_msb; sn++)
+ if (!IN_RANGE (sn, dest.regno, dest.regno_msb)
+ && !reg_unused_after (insn, all_regs_rtx[sn]))
+ use_src = false;
+ if (use_src && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0))
+ {
+ avr_asm_len ("tst %0" CR_TAB "brpl 0f",
+ &all_regs_rtx[src.regno_msb], plen, 2);
+ sn = src.regno;
+ if (sn < s0)
+ {
+ if (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], sn))
+ avr_asm_len ("cpi %0,1", &all_regs_rtx[sn], plen, 1);
+ else
+ avr_asm_len ("sec" CR_TAB "cpc %0,__zero_reg__",
+ &all_regs_rtx[sn], plen, 2);
+ have_carry = true;
+ }
+ while (++sn < s0)
+ avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
+ avr_asm_len (have_carry ? "sbci %0,128" : "subi %0,129",
+ &all_regs_rtx[s0], plen, 1);
+ for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
+ avr_asm_len ("sbci %0,255", &all_regs_rtx[sn], plen, 1);
+ avr_asm_len ("\n0:", NULL, plen, 0);
+ frac_rounded = true;
+ }
+ else if (use_src && overlap)
+ {
+ avr_asm_len ("clr __tmp_reg__" CR_TAB
+ "sbrc %1,0" CR_TAB "dec __tmp_reg__", xop, plen, 1);
+ sn = src.regno;
+ if (sn < s0)
+ {
+ avr_asm_len ("add %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
+ have_carry = true;
+ }
+ while (++sn < s0)
+ avr_asm_len ("adc %0,__tmp_reg__", &all_regs_rtx[sn], plen, 1);
+ if (have_carry)
+ avr_asm_len ("clt" CR_TAB "bld __tmp_reg__,7" CR_TAB
+ "adc %0,__tmp_reg__",
+ &all_regs_rtx[s0], plen, 1);
+ else
+ avr_asm_len ("lsr __tmp_reg" CR_TAB "add %0,__tmp_reg__",
+ &all_regs_rtx[s0], plen, 2);
+ for (sn = src.regno + src.fbyte; sn <= copied_msb; sn++)
+ avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
+ frac_rounded = true;
+ }
+ else if (overlap)
+ {
+ bool use_src
+ = (TEST_HARD_REG_BIT (reg_class_contents[LD_REGS], s0)
+ && (IN_RANGE (s0, dest.regno, dest.regno_msb)
+ || reg_unused_after (insn, all_regs_rtx[s0])));
+ xop[2] = all_regs_rtx[s0];
+ unsigned sn = src.regno;
+ if (!use_src || sn == s0)
+ avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
+ /* We need to consider to-be-discarded bits
+ if the value is negative. */
+ if (sn < s0)
+ {
+ avr_asm_len ("tst %0" CR_TAB "brpl 0f",
+ &all_regs_rtx[src.regno_msb], plen, 2);
+ /* Test to-be-discarded bytes for any nozero bits.
+ ??? Could use OR or SBIW to test two registers at once. */
+ if (sn < s0)
+ avr_asm_len ("cp %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
+ while (++sn < s0)
+ avr_asm_len ("cpc %0,__zero_reg__", &all_regs_rtx[sn], plen, 1);
+ /* Set bit 0 in __tmp_reg__ if any of the lower bits was set. */
+ if (use_src)
+ avr_asm_len ("breq 0f" CR_TAB
+ "ori %2,1" "\n0:\t" "mov __tmp_reg__,%2",
+ xop, plen, 3);
+ else
+ avr_asm_len ("breq 0f" CR_TAB
+ "set" CR_TAB "bld __tmp_reg__,0\n0:",
+ xop, plen, 3);
+ }
+ lsb_in_tmp_reg = true;
+ }
+ }
+
/* Step 1: Clear bytes at the low end and copy payload bits from source
====== to destination. */
int step = offset < 0 ? 1 : -1;
unsigned d0 = offset < 0 ? dest.regno : dest.regno_msb;
- // We leared at least that number of registers.
+ // We cleared at least that number of registers.
int clr_n = 0;
for (; d0 >= dest.regno && d0 <= dest.regno_msb; d0 += step)
@@ -7208,6 +7317,7 @@ avr_out_fract (rtx insn, rtx operands[], bool intsigned, int *plen)
unsigned src_lsb = dest.regno - offset -1;
if (shift == ASHIFT && src.fbyte > dest.fbyte && !lsb_in_carry
+ && !lsb_in_tmp_reg
&& (d0 == src_lsb || d0 + stepw == src_lsb))
{
/* We are going to override the new LSB; store it into carry. */
@@ -7229,7 +7339,91 @@ avr_out_fract (rtx insn, rtx operands[], bool intsigned, int *plen)
{
unsigned s0 = dest.regno - offset -1;
- if (MAY_CLOBBER (s0))
+ /* n1169 4.1.4 says:
+ "Conversions from a fixed-point to an integer type round toward zero."
+ Hence, converting a fract type to integer only gives a non-zero result
+ for -1. */
+ if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
+ && SCALAR_FRACT_MODE_P (GET_MODE (xop[1]))
+ && !TARGET_FRACT_CONV_TRUNC)
+ {
+ gcc_assert (s0 == src.regno_msb);
+ /* Check if the input is -1. We do that by checking if negating
+ the input causes an integer overflow. */
+ unsigned sn = src.regno;
+ avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
+ while (sn <= s0)
+ avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn++], plen, 1);
+
+ /* Overflow goes with set carry. Clear carry otherwise. */
+ avr_asm_len ("brvs 0f" CR_TAB "clc\n0:", NULL, plen, 2);
+ }
+ /* Likewise, when converting from accumulator types to integer, we
+ need to round up negative values. */
+ else if (SCALAR_INT_MODE_P (GET_MODE (xop[0]))
+ && SCALAR_ACCUM_MODE_P (GET_MODE (xop[1]))
+ && !TARGET_FRACT_CONV_TRUNC
+ && !frac_rounded)
+ {
+ bool have_carry = false;
+
+ xop[2] = all_regs_rtx[s0];
+ if (!lsb_in_tmp_reg && !MAY_CLOBBER (s0))
+ avr_asm_len ("mov __tmp_reg__,%2", xop, plen, 1);
+ avr_asm_len ("tst %0" CR_TAB "brpl 0f",
+ &all_regs_rtx[src.regno_msb], plen, 2);
+ if (!lsb_in_tmp_reg)
+ {
+ unsigned sn = src.regno;
+ if (sn < s0)
+ {
+ avr_asm_len ("cp __zero_reg__,%0", &all_regs_rtx[sn],
+ plen, 1);
+ have_carry = true;
+ }
+ while (++sn < s0)
+ avr_asm_len ("cpc __zero_reg__,%0", &all_regs_rtx[sn], plen, 1);
+ lsb_in_tmp_reg = !MAY_CLOBBER (s0);
+ }
+ /* Add in C and the rounding value 127. */
+ /* If the destination msb is a sign byte, and in LD_REGS,
+ grab it as a temporary. */
+ if (sign_bytes
+ && TEST_HARD_REG_BIT (reg_class_contents[LD_REGS],
+ dest.regno_msb))
+ {
+ xop[3] = all_regs_rtx[dest.regno_msb];
+ avr_asm_len ("ldi %3,127", xop, plen, 1);
+ avr_asm_len ((have_carry && lsb_in_tmp_reg ? "adc __tmp_reg__,%3"
+ : have_carry ? "adc %2,%3"
+ : lsb_in_tmp_reg ? "add __tmp_reg__,%3"
+ : "add %2,%3"),
+ xop, plen, 1);
+ }
+ else
+ {
+ /* Fall back to use __zero_reg__ as a temporary. */
+ avr_asm_len ("dec __zero_reg__", NULL, plen, 1);
+ if (have_carry)
+ avr_asm_len ("clt" CR_TAB "bld __zero_reg__,7", NULL, plen, 2);
+ else
+ avr_asm_len ("lsr __zero_reg__", NULL, plen, 1);
+ avr_asm_len ((have_carry && lsb_in_tmp_reg
+ ? "adc __tmp_reg__,__zero_reg__"
+ : have_carry ? "adc %2,__zero_reg__"
+ : lsb_in_tmp_reg ? "add __tmp_reg__,__zero_reg__"
+ : "add %2,__zero_reg__"),
+ xop, plen, 1);
+ avr_asm_len ("eor __zero_reg__,__zero_reg__", NULL, plen, 1);
+ }
+ for (d0 = dest.regno + zero_bytes;
+ d0 <= dest.regno_msb - sign_bytes; d0++)
+ avr_asm_len ("adc %0,__zero_reg__", &all_regs_rtx[d0], plen, 1);
+ avr_asm_len (lsb_in_tmp_reg
+ ? "\n0:\t" "lsl __tmp_reg__" : "\n0:\t" "lsl %2",
+ xop, plen, 1);
+ }
+ else if (MAY_CLOBBER (s0))
avr_asm_len ("lsl %0", &all_regs_rtx[s0], plen, 1);
else
avr_asm_len ("mov __tmp_reg__,%0" CR_TAB
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt
index 4b990775b7f..9b0f782d385 100644
--- a/gcc/config/avr/avr.opt
+++ b/gcc/config/avr/avr.opt
@@ -78,3 +78,7 @@ The device has no SPH special function register. This option will be overridden
Waddr-space-convert
Warning C Report Var(avr_warn_addr_space_convert) Init(0)
Warn if the address space of an address is changed.
+
+mfract-convert-truncate
+Target Report Mask(FRACT_CONV_TRUNC)
+Allow to use truncation instead of rounding towards 0 for fractional int types
diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c
index 7fab975a673..18457f8f7b6 100644
--- a/gcc/config/bfin/bfin.c
+++ b/gcc/config/bfin/bfin.c
@@ -46,6 +46,7 @@
#include "cgraph.h"
#include "langhooks.h"
#include "bfin-protos.h"
+#include "tm_p.h"
#include "tm-preds.h"
#include "tm-constrs.h"
#include "gt-bfin.h"
diff --git a/gcc/config/bfin/uclinux.h b/gcc/config/bfin/uclinux.h
index ca0f4ee8a35..63cba99cec6 100644
--- a/gcc/config/bfin/uclinux.h
+++ b/gcc/config/bfin/uclinux.h
@@ -44,3 +44,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_SUPPORTS_SYNC_CALLS 1
#define SUBTARGET_FDPIC_NOT_SUPPORTED
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/c6x/uclinux-elf.h b/gcc/config/c6x/uclinux-elf.h
index 5d61f4dc4ec..fa0937ed268 100644
--- a/gcc/config/c6x/uclinux-elf.h
+++ b/gcc/config/c6x/uclinux-elf.h
@@ -62,3 +62,5 @@
: "0" (_beg), "b" (_end), "b" (_scno)); \
}
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/darwin-protos.h b/gcc/config/darwin-protos.h
index 70b7fb00959..36d16b9e57a 100644
--- a/gcc/config/darwin-protos.h
+++ b/gcc/config/darwin-protos.h
@@ -123,3 +123,4 @@ extern bool darwin_kextabi_p (void);
extern void darwin_override_options (void);
extern void darwin_patch_builtins (void);
extern void darwin_rename_builtins (void);
+extern bool darwin_libc_has_function (enum function_class fn_class);
diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c
index e07fa4c8324..6c5d9c00623 100644
--- a/gcc/config/darwin.c
+++ b/gcc/config/darwin.c
@@ -3357,6 +3357,19 @@ darwin_rename_builtins (void)
}
}
+bool
+darwin_libc_has_function (enum function_class fn_class)
+{
+ if (fn_class == function_sincos)
+ return false;
+ if (fn_class == function_c99_math_complex
+ || fn_class == function_c99_misc)
+ return (TARGET_64BIT
+ || strverscmp (darwin_macosx_version_min, "10.3") >= 0);
+
+ return true;
+}
+
static hashval_t
cfstring_hash (const void *ptr)
{
diff --git a/gcc/config/darwin.h b/gcc/config/darwin.h
index 82a42c8598b..596c9ef11f0 100644
--- a/gcc/config/darwin.h
+++ b/gcc/config/darwin.h
@@ -178,10 +178,11 @@ extern GTY(()) int darwin_ms_struct;
%{L*} %(link_libgcc) %o %{fprofile-arcs|fprofile-generate*|coverage:-lgcov} \
%{fopenmp|ftree-parallelize-loops=*: \
%{static|static-libgcc|static-libstdc++|static-libgfortran: libgomp.a%s; : -lgomp } } \
- %{fsanitize=address: -lasan } \
%{fgnu-tm: \
%{static|static-libgcc|static-libstdc++|static-libgfortran: libitm.a%s; : -litm } } \
%{!nostdlib:%{!nodefaultlibs:\
+ %{%:sanitize(address): -lasan } \
+ %{%:sanitize(undefined): -lubsan } \
%(link_ssp) %(link_gcc_c_sequence)\
}}\
%{!nostdlib:%{!nostartfiles:%E}} %{T*} %{F*} }}}}}}}"
@@ -874,10 +875,6 @@ void add_framework_path (char *);
#define TARGET_POSIX_IO
-/* All new versions of Darwin have C99 functions. */
-
-#define TARGET_C99_FUNCTIONS 1
-
#define WINT_TYPE "int"
/* Every program on darwin links against libSystem which contains the pthread
diff --git a/gcc/config/elfos.h b/gcc/config/elfos.h
index 438302345cf..9606fe0f85c 100644
--- a/gcc/config/elfos.h
+++ b/gcc/config/elfos.h
@@ -433,3 +433,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
default_elf_asm_output_external (FILE, DECL, NAME)
#endif
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/epiphany/epiphany.c b/gcc/config/epiphany/epiphany.c
index 1dcdc4b3808..fd4c01c49a4 100644
--- a/gcc/config/epiphany/epiphany.c
+++ b/gcc/config/epiphany/epiphany.c
@@ -45,6 +45,8 @@ along with GCC; see the file COPYING3. If not see
#include "ggc.h"
#include "tm-constrs.h"
#include "tree-pass.h" /* for current_pass */
+#include "context.h"
+#include "pass_manager.h"
/* Which cpu we're compiling for. */
int epiphany_cpu_type;
@@ -59,6 +61,9 @@ char epiphany_punct_chars[256];
/* The rounding mode that we generally use for floating point. */
int epiphany_normal_fp_rounding;
+/* The pass instance, for use in epiphany_optimize_mode_switching. */
+static opt_pass *pass_mode_switch_use;
+
static void epiphany_init_reg_tables (void);
static int get_epiphany_condition_code (rtx);
static tree epiphany_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
@@ -165,20 +170,26 @@ epiphany_init (void)
pass because of the side offect of epiphany_mode_needed on
MACHINE_FUNCTION(cfun)->unknown_mode_uses. But it must run before
pass_resolve_sw_modes. */
- static struct register_pass_info insert_use_info
- = { &pass_mode_switch_use.pass, "mode_sw",
+ pass_mode_switch_use = make_pass_mode_switch_use (g);
+ struct register_pass_info insert_use_info
+ = { pass_mode_switch_use, "mode_sw",
1, PASS_POS_INSERT_AFTER
};
- static struct register_pass_info mode_sw2_info
- = { &pass_mode_switching.pass, "mode_sw",
+ opt_pass *mode_sw2
+ = g->get_passes()->get_pass_mode_switching ()->clone ();
+ struct register_pass_info mode_sw2_info
+ = { mode_sw2, "mode_sw",
1, PASS_POS_INSERT_AFTER
};
- static struct register_pass_info mode_sw3_info
- = { &pass_resolve_sw_modes.pass, "mode_sw",
+ opt_pass *mode_sw3 = make_pass_resolve_sw_modes (g);
+ struct register_pass_info mode_sw3_info
+ = { mode_sw3, "mode_sw",
1, PASS_POS_INSERT_AFTER
};
- static struct register_pass_info mode_sw4_info
- = { &pass_split_all_insns.pass, "mode_sw",
+ opt_pass *mode_sw4
+ = g->get_passes()->get_pass_split_all_insns ()->clone ();
+ struct register_pass_info mode_sw4_info
+ = { mode_sw4, "mode_sw",
1, PASS_POS_INSERT_AFTER
};
static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
@@ -205,8 +216,10 @@ epiphany_init (void)
(see http://gcc.gnu.org/ml/gcc-patches/2011-10/msg02819.html,)
we need a second peephole2 pass to get reasonable code. */
{
- static struct register_pass_info peep2_2_info
- = { &pass_peephole2.pass, "peephole2",
+ opt_pass *extra_peephole2
+ = g->get_passes ()->get_pass_peephole2 ()->clone ();
+ struct register_pass_info peep2_2_info
+ = { extra_peephole2, "peephole2",
1, PASS_POS_INSERT_AFTER
};
@@ -2256,7 +2269,7 @@ epiphany_optimize_mode_switching (int entity)
return (MACHINE_FUNCTION (cfun)->sw_entities_processed
& (1 << EPIPHANY_MSW_ENTITY_ROUND_UNKNOWN)) != 0;
case EPIPHANY_MSW_ENTITY_FPU_OMNIBUS:
- return optimize == 0 || current_pass == &pass_mode_switch_use.pass;
+ return optimize == 0 || current_pass == pass_mode_switch_use;
}
gcc_unreachable ();
}
diff --git a/gcc/config/epiphany/epiphany.h b/gcc/config/epiphany/epiphany.h
index bd84b5c793f..f16ab85dde9 100644
--- a/gcc/config/epiphany/epiphany.h
+++ b/gcc/config/epiphany/epiphany.h
@@ -929,8 +929,8 @@ enum
};
extern int epiphany_normal_fp_rounding;
-extern struct rtl_opt_pass pass_mode_switch_use;
-extern struct rtl_opt_pass pass_resolve_sw_modes;
+extern rtl_opt_pass *make_pass_mode_switch_use (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_resolve_sw_modes (gcc::context *ctxt);
/* This will need to be adjusted when FP_CONTRACT_ON is properly
implemented. */
diff --git a/gcc/config/epiphany/epiphany.md b/gcc/config/epiphany/epiphany.md
index 1e2d2ab02ed..e8756ad8e23 100644
--- a/gcc/config/epiphany/epiphany.md
+++ b/gcc/config/epiphany/epiphany.md
@@ -587,7 +587,7 @@
; After mode-switching, floating point operations, fp_sfuncs and calls
; must exhibit the use of the control register, lest the setting of the
; control register could be deleted or moved. OTOH a use of a hard register
-; greatly coundounds optimizers like the rtl loop optimizers or combine.
+; greatly counfounds optimizers like the rtl loop optimizers or combine.
; Therefore, we put an extra pass immediately after the mode switching pass
; that inserts the USEs of the control registers, and sets a flag in struct
; machine_function that float_operation can henceforth only match with that
@@ -1058,6 +1058,28 @@
(clobber (reg:CC CC_REGNUM))])]
)
+(define_peephole2
+ [(match_parallel 3 "float_operation"
+ [(set (match_operand:SI 0 "gpr_operand" "")
+ (mult:SI
+ (match_operand:SI 1 "gpr_operand" "")
+ (match_operand:SI 2 "gpr_operand" "")))
+ (clobber (reg:CC_FP CCFP_REGNUM))])]
+ "prev_active_insn (peep2_next_insn (0))
+ && get_attr_sched_use_fpu (prev_active_insn (peep2_next_insn (0)))
+ && peep2_regno_dead_p (1, CC_REGNUM)
+ && get_attr_sched_use_fpu (next_active_insn (peep2_next_insn (0)))
+ && find_reg_note (insn, REG_EQUAL, NULL_RTX) != NULL_RTX
+ && GET_CODE (XEXP (find_reg_note (insn, REG_EQUAL, NULL_RTX), 0)) == MULT
+ && CONST_INT_P (XEXP (XEXP (find_reg_note (insn, REG_EQUAL, NULL_RTX), 0),
+ 1))"
+ [(parallel [(set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 4)))
+ (clobber (reg:CC CC_REGNUM))])]
+{
+ operands[4]
+ = XEXP (XEXP (find_reg_note (curr_insn, REG_EQUAL, NULL_RTX), 0), 1);
+})
+
(define_expand "mulsi3"
[(parallel
[(set (match_operand:SI 0 "gpr_operand" "")
@@ -2530,6 +2552,106 @@
[(set_attr "length" "8")
(set_attr "type" "v2fp")])
+(define_expand "ashlv2si3"
+ [(parallel
+ [(set (match_operand:V2SI 0 "gpr_operand" "")
+ (ashift:V2SI (match_operand:V2SI 1 "gpr_operand" "")
+ (match_operand:SI 2 "general_operand")))
+ (use (match_dup 3))
+ (clobber (reg:CC_FP CCFP_REGNUM))])]
+ ""
+{
+ if (const_int_operand (operands[2], VOIDmode))
+ operands[3]
+ = copy_to_mode_reg (SImode, GEN_INT (1 << INTVAL (operands[2])));
+ else
+ {
+ int o, i;
+ rtx xop[2], last_out = pc_rtx;
+
+ for (o = 0; o <= UNITS_PER_WORD; o += UNITS_PER_WORD)
+ {
+ for (i = 0; i < 2; i++)
+ {
+ xop[i]
+ = (i == 2 ? operands[2]
+ : simplify_gen_subreg (SImode, operands[i], V2SImode, o));
+ gcc_assert (!reg_overlap_mentioned_p (last_out, xop[i])
+ /* ??? reg_overlap_mentioned_p doesn't understand
+ about multi-word SUBREGs. */
+ || (GET_CODE (last_out) == SUBREG
+ && GET_CODE (xop[i]) == SUBREG
+ && SUBREG_REG (last_out) == SUBREG_REG (xop[i])
+ && ((SUBREG_BYTE (last_out) & -UNITS_PER_WORD)
+ != (SUBREG_BYTE (xop[i]) & -UNITS_PER_WORD))));
+ }
+ emit_insn (gen_ashlsi3 (xop[0], xop[1], operands[2]));
+ last_out = xop[0];
+ }
+ DONE;
+ }
+})
+
+(define_insn_and_split "*ashlv2si3_i"
+ [(match_parallel 3 "float_operation"
+ [(set (match_operand:V2SI 0 "gpr_operand" "=&r,*1*2")
+ (ashift:V2SI (match_operand:V2SI 1 "gpr_operand" "r,r")
+ (match_operand 2 "const_int_operand" "n,n")))
+ (use (match_operand:SI 4 "gpr_operand" "r,r"))
+ (clobber (reg:CC_FP CCFP_REGNUM))])]
+ ""
+ "#"
+ "reload_completed"
+ [(parallel
+ [(set (match_dup 5) (mult:SI (match_dup 6) (match_dup 4)))
+ (clobber (reg:CC_FP CCFP_REGNUM))
+ (match_dup 9)
+ (match_dup 10)])
+ (parallel
+ [(set (match_dup 7) (mult:SI (match_dup 8) (match_dup 4)))
+ (clobber (reg:CC_FP CCFP_REGNUM))
+ (match_dup 9)
+ (match_dup 10)])]
+{
+ operands[5] = simplify_gen_subreg (SImode, operands[0], V2SImode, 0);
+ operands[6] = simplify_gen_subreg (SImode, operands[1], V2SImode, 0);
+ operands[7] = simplify_gen_subreg (SImode, operands[0],
+ V2SImode, UNITS_PER_WORD);
+ operands[8] = simplify_gen_subreg (SImode, operands[1],
+ V2SImode, UNITS_PER_WORD);
+ gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[8]));
+ gcc_assert (!reg_overlap_mentioned_p (operands[5], operands[4]));
+ operands[9] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 2);
+ operands[10] = XVECEXP (operands[3], 0, XVECLEN (operands[3], 0) - 1);
+ rtx insn
+ = (gen_rtx_PARALLEL
+ (VOIDmode,
+ gen_rtvec
+ (4,
+ gen_rtx_SET (VOIDmode, operands[5],
+ gen_rtx_MULT (SImode, operands[6], operands[4])),
+ gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CC_FPmode, CCFP_REGNUM)),
+ operands[9], operands[10])));
+ insn = emit_insn (insn);
+ add_reg_note (insn, REG_EQUAL,
+ gen_rtx_ASHIFT (SImode, operands[6], operands[2]));
+ insn
+ = (gen_rtx_PARALLEL
+ (VOIDmode,
+ gen_rtvec
+ (4,
+ gen_rtx_SET (VOIDmode, operands[7],
+ gen_rtx_MULT (SImode, operands[8], operands[4])),
+ gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CC_FPmode, CCFP_REGNUM)),
+ operands[9], operands[10])));
+ insn = emit_insn (insn);
+ add_reg_note (insn, REG_EQUAL,
+ gen_rtx_ASHIFT (SImode, operands[7], operands[2]));
+ DONE;
+}
+ [(set_attr "length" "8")
+ (set_attr "type" "fp_int")])
+
(define_expand "mul<mode>3"
[(parallel
[(set (match_operand:DWV2MODE 0 "gpr_operand" "")
diff --git a/gcc/config/epiphany/mode-switch-use.c b/gcc/config/epiphany/mode-switch-use.c
index 66529636801..8e278583215 100644
--- a/gcc/config/epiphany/mode-switch-use.c
+++ b/gcc/config/epiphany/mode-switch-use.c
@@ -71,22 +71,39 @@ insert_uses (void)
return 0;
}
-struct rtl_opt_pass pass_mode_switch_use =
+namespace {
+
+const pass_data pass_data_mode_switch_use =
{
- {
- RTL_PASS,
- "mode_switch_use", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- insert_uses, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "mode_switch_use", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_mode_switch_use : public rtl_opt_pass
+{
+public:
+ pass_mode_switch_use(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_mode_switch_use, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return insert_uses (); }
+
+}; // class pass_mode_switch_use
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_mode_switch_use (gcc::context *ctxt)
+{
+ return new pass_mode_switch_use (ctxt);
+}
diff --git a/gcc/config/epiphany/predicates.md b/gcc/config/epiphany/predicates.md
index af60d7c73f7..b77867cc851 100644
--- a/gcc/config/epiphany/predicates.md
+++ b/gcc/config/epiphany/predicates.md
@@ -292,7 +292,11 @@
bool inserted = MACHINE_FUNCTION (cfun)->control_use_inserted;
int i;
- if (count == 2)
+ if (count == 2
+ /* Vector ashift has an extra use for the constant factor required to
+ implement the shift as multiply. */
+ || (count == 3 && GET_CODE (XVECEXP (op, 0, 0)) == SET
+ && GET_CODE (XEXP (XVECEXP (op, 0, 0), 1)) == ASHIFT))
return !inserted;
/* combine / recog will pass any old garbage here before checking the
@@ -302,7 +306,7 @@
i = 1;
if (count > 4)
- for (i = 4; i < count; i++)
+ for (i = 2; i < count; i++)
{
rtx x = XVECEXP (op, 0, i);
diff --git a/gcc/config/epiphany/resolve-sw-modes.c b/gcc/config/epiphany/resolve-sw-modes.c
index 729a0ffc9b7..b43b4d953cd 100644
--- a/gcc/config/epiphany/resolve-sw-modes.c
+++ b/gcc/config/epiphany/resolve-sw-modes.c
@@ -161,23 +161,40 @@ resolve_sw_modes (void)
return 0;
}
-struct rtl_opt_pass pass_resolve_sw_modes =
+namespace {
+
+const pass_data pass_data_resolve_sw_modes =
{
- {
- RTL_PASS,
- "resolve_sw_modes", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_resolve_sw_modes, /* gate */
- resolve_sw_modes, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_MODE_SWITCH, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "resolve_sw_modes", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_MODE_SWITCH, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */
};
+
+class pass_resolve_sw_modes : public rtl_opt_pass
+{
+public:
+ pass_resolve_sw_modes(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_resolve_sw_modes, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_resolve_sw_modes (); }
+ unsigned int execute () { return resolve_sw_modes (); }
+
+}; // class pass_resolve_sw_modes
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_resolve_sw_modes (gcc::context *ctxt)
+{
+ return new pass_resolve_sw_modes (ctxt);
+}
diff --git a/gcc/config/freebsd.h b/gcc/config/freebsd.h
index 87c0acf1d89..da66253e660 100644
--- a/gcc/config/freebsd.h
+++ b/gcc/config/freebsd.h
@@ -52,6 +52,9 @@ along with GCC; see the file COPYING3. If not see
#define LINK_SSP_SPEC "%{fstack-protector|fstack-protector-all:-lssp_nonshared}"
#endif
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
/* Use --as-needed -lgcc_s for eh support. */
#ifdef HAVE_LD_AS_NEEDED
#define USE_LD_AS_NEEDED 1
diff --git a/gcc/config/gnu-user.h b/gcc/config/gnu-user.h
index bcdf0e6cc5a..6f6915842b9 100644
--- a/gcc/config/gnu-user.h
+++ b/gcc/config/gnu-user.h
@@ -39,15 +39,21 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
the GNU userspace magical crtbegin.o file (see crtstuff.c) which
provides part of the support for getting C++ file-scope static
object constructed before entering `main'. */
-
+
#if defined HAVE_LD_PIE
#define GNU_USER_TARGET_STARTFILE_SPEC \
"%{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} \
- crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s} \
+ %{fvtable-verify=none:%s; \
+ fvtable-verify=preinit:vtv_start_preinit.o%s; \
+ fvtable-verify=std:vtv_start.o%s}"
#else
#define GNU_USER_TARGET_STARTFILE_SPEC \
"%{!shared: %{pg|p|profile:gcrt1.o%s;:crt1.o%s}} \
- crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}"
+ crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s} \
+ %{fvtable-verify=none:%s; \
+ fvtable-verify=preinit:vtv_start_preinit.o%s; \
+ fvtable-verify=std:vtv_start.o%s}"
#endif
#undef STARTFILE_SPEC
#define STARTFILE_SPEC GNU_USER_TARGET_STARTFILE_SPEC
@@ -59,7 +65,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
GNU userspace "finalizer" file, `crtn.o'. */
#define GNU_USER_TARGET_ENDFILE_SPEC \
- "%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
+ "%{fvtable-verify=none:%s; \
+ fvtable-verify=preinit:vtv_end_preinit.o%s; \
+ fvtable-verify=std:vtv_end.o%s} \
+ %{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC GNU_USER_TARGET_ENDFILE_SPEC
@@ -73,10 +82,14 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#undef CPLUSPLUS_CPP_SPEC
#define CPLUSPLUS_CPP_SPEC "-D_GNU_SOURCE %(cpp)"
-#define GNU_USER_TARGET_LIB_SPEC \
- "%{pthread:-lpthread} \
- %{shared:-lc} \
+#define GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC \
+ "%{shared:-lc} \
%{!shared:%{mieee-fp:-lieee} %{profile:-lc_p}%{!profile:-lc}}"
+
+#define GNU_USER_TARGET_LIB_SPEC \
+ "%{pthread:-lpthread} " \
+ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC
+
#undef LIB_SPEC
#define LIB_SPEC GNU_USER_TARGET_LIB_SPEC
@@ -95,8 +108,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_POSIX_IO
-#define TARGET_C99_FUNCTIONS 1
-#define TARGET_HAS_SINCOS 1
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
/* Link -lasan early on the command line. For -static-libasan, don't link
it for -shared link, the executable should be compiled with -static-libasan
diff --git a/gcc/config/i386/constraints.md b/gcc/config/i386/constraints.md
index 6cb53b8aafb..28e626ff3be 100644
--- a/gcc/config/i386/constraints.md
+++ b/gcc/config/i386/constraints.md
@@ -19,7 +19,7 @@
;;; Unused letters:
;;; B H T
-;;; h jk v
+;;; h jk
;; Integer register constraints.
;; It is not necessary to define 'r' here.
@@ -101,11 +101,11 @@
"First SSE register (@code{%xmm0}).")
(define_register_constraint "Yi"
- "TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC ? SSE_REGS : NO_REGS"
+ "TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC ? ALL_SSE_REGS : NO_REGS"
"@internal Any SSE register, when SSE2 and inter-unit moves to vector registers are enabled.")
(define_register_constraint "Yj"
- "TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC ? SSE_REGS : NO_REGS"
+ "TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_FROM_VEC ? ALL_SSE_REGS : NO_REGS"
"@internal Any SSE register, when SSE2 and inter-unit moves from vector registers are enabled.")
(define_register_constraint "Ym"
@@ -138,6 +138,9 @@
"(ix86_fpmath & FPMATH_387) ? FLOAT_REGS : NO_REGS"
"@internal Any x87 register when 80387 FP arithmetic is enabled.")
+(define_register_constraint "v" "TARGET_SSE ? ALL_SSE_REGS : NO_REGS"
+ "Any EVEX encodable SSE register (@code{%xmm0-%xmm31}).")
+
(define_constraint "z"
"@internal Constant call address operand."
(match_operand 0 "constant_call_address_operand"))
diff --git a/gcc/config/i386/cpuid.h b/gcc/config/i386/cpuid.h
index c1e1eba12f1..aa91e1ab8d8 100644
--- a/gcc/config/i386/cpuid.h
+++ b/gcc/config/i386/cpuid.h
@@ -71,8 +71,12 @@
#define bit_AVX2 (1 << 5)
#define bit_BMI2 (1 << 8)
#define bit_RTM (1 << 11)
+#define bit_AVX512F (1 << 16)
#define bit_RDSEED (1 << 18)
#define bit_ADX (1 << 19)
+#define bit_AVX512PF (1 << 26)
+#define bit_AVX512ER (1 << 27)
+#define bit_AVX512CD (1 << 28)
/* Extended State Enumeration Sub-leaf (%eax == 13, %ecx == 1) */
#define bit_XSAVEOPT (1 << 0)
diff --git a/gcc/config/i386/cygming.h b/gcc/config/i386/cygming.h
index 27187641aad..9cb66d646be 100644
--- a/gcc/config/i386/cygming.h
+++ b/gcc/config/i386/cygming.h
@@ -171,6 +171,9 @@ along with GCC; see the file COPYING3. If not see
#undef MATH_LIBRARY
#define MATH_LIBRARY ""
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
#define SIZE_TYPE (TARGET_64BIT ? "long long unsigned int" : "unsigned int")
#define PTRDIFF_TYPE (TARGET_64BIT ? "long long int" : "int")
diff --git a/gcc/config/i386/djgpp.h b/gcc/config/i386/djgpp.h
index 05f9dfda71d..cc420d0a6d6 100644
--- a/gcc/config/i386/djgpp.h
+++ b/gcc/config/i386/djgpp.h
@@ -117,6 +117,17 @@ along with GCC; see the file COPYING3. If not see
#define ASM_OUTPUT_ALIGNED_BSS(FILE, DECL, NAME, SIZE, ALIGN) \
asm_output_aligned_bss ((FILE), (DECL), (NAME), (SIZE), (ALIGN))
+/* Write the extra assembler code needed to declare a function properly. */
+
+#ifndef ASM_DECLARE_FUNCTION_NAME
+#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
+ do \
+ { \
+ ASM_OUTPUT_FUNCTION_LABEL (FILE, NAME, DECL); \
+ } \
+ while (0)
+#endif
+
/* This is how to tell assembler that a symbol is weak */
#undef ASM_WEAKEN_LABEL
#define ASM_WEAKEN_LABEL(FILE,NAME) \
@@ -127,6 +138,9 @@ along with GCC; see the file COPYING3. If not see
in libgcc, nor call one in main(). */
#define HAS_INIT_SECTION
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
/* Definitions for types and sizes. Wide characters are 16-bits long so
Win32 compiler add-ons will be wide character compatible. */
#undef WCHAR_TYPE_SIZE
diff --git a/gcc/config/i386/driver-i386.c b/gcc/config/i386/driver-i386.c
index c8b71c8edf9..4cb9907b5ed 100644
--- a/gcc/config/i386/driver-i386.c
+++ b/gcc/config/i386/driver-i386.c
@@ -390,6 +390,8 @@ const char *host_detect_local_cpu (int argc, const char **argv)
unsigned int has_rdrnd = 0, has_f16c = 0, has_fsgsbase = 0;
unsigned int has_rdseed = 0, has_prfchw = 0, has_adx = 0;
unsigned int has_osxsave = 0, has_fxsr = 0, has_xsave = 0, has_xsaveopt = 0;
+ unsigned int has_avx512er = 0, has_avx512pf = 0, has_avx512cd = 0;
+ unsigned int has_avx512f = 0;
bool arch;
@@ -461,6 +463,10 @@ const char *host_detect_local_cpu (int argc, const char **argv)
has_fsgsbase = ebx & bit_FSGSBASE;
has_rdseed = ebx & bit_RDSEED;
has_adx = ebx & bit_ADX;
+ has_avx512f = ebx & bit_AVX512F;
+ has_avx512er = ebx & bit_AVX512ER;
+ has_avx512pf = ebx & bit_AVX512PF;
+ has_avx512cd = ebx & bit_AVX512CD;
}
if (max_level >= 13)
@@ -638,13 +644,18 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* Atom. */
cpu = "atom";
break;
+ case 0x0f:
+ /* Merom. */
+ case 0x17:
+ case 0x1d:
+ /* Penryn. */
+ cpu = "core2";
+ break;
case 0x1a:
case 0x1e:
case 0x1f:
case 0x2e:
/* Nehalem. */
- cpu = "corei7";
- break;
case 0x25:
case 0x2c:
case 0x2f:
@@ -656,20 +667,25 @@ const char *host_detect_local_cpu (int argc, const char **argv)
/* Sandy Bridge. */
cpu = "corei7-avx";
break;
- case 0x17:
- case 0x1d:
- /* Penryn. */
- cpu = "core2";
+ case 0x3a:
+ case 0x3e:
+ /* Ivy Bridge. */
+ cpu = "core-avx-i";
break;
- case 0x0f:
- /* Merom. */
- cpu = "core2";
+ case 0x3c:
+ case 0x45:
+ case 0x46:
+ /* Haswell. */
+ cpu = "core-avx2";
break;
default:
if (arch)
{
/* This is unknown family 0x6 CPU. */
- if (has_avx)
+ if (has_avx2)
+ /* Assume Haswell. */
+ cpu = "core-avx2";
+ else if (has_avx)
/* Assume Sandy Bridge. */
cpu = "corei7-avx";
else if (has_sse4_2)
@@ -828,13 +844,18 @@ const char *host_detect_local_cpu (int argc, const char **argv)
const char *fxsr = has_fxsr ? " -mfxsr" : " -mno-fxsr";
const char *xsave = has_xsave ? " -mxsave" : " -mno-xsave";
const char *xsaveopt = has_xsaveopt ? " -mxsaveopt" : " -mno-xsaveopt";
+ const char *avx512f = has_avx512f ? " -mavx512f" : " -mno-avx512f";
+ const char *avx512er = has_avx512er ? " -mavx512er" : " -mno-avx512er";
+ const char *avx512cd = has_avx512cd ? " -mavx512cd" : " -mno-avx512cd";
+ const char *avx512pf = has_avx512pf ? " -mavx512pf" : " -mno-avx512pf";
options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3,
sse4a, cx16, sahf, movbe, aes, pclmul,
popcnt, abm, lwp, fma, fma4, xop, bmi, bmi2,
tbm, avx, avx2, sse4_2, sse4_1, lzcnt, rtm,
hle, rdrnd, f16c, fsgsbase, rdseed, prfchw, adx,
- fxsr, xsave, xsaveopt, NULL);
+ fxsr, xsave, xsaveopt, avx512f, avx512er,
+ avx512cd, avx512pf, NULL);
}
done:
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index 31dd28a94cb..14349be0af5 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -306,6 +306,14 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag,
def_or_undef (parse_in, "__AVX__");
if (isa_flag & OPTION_MASK_ISA_AVX2)
def_or_undef (parse_in, "__AVX2__");
+ if (isa_flag & OPTION_MASK_ISA_AVX512F)
+ def_or_undef (parse_in, "__AVX512F__");
+ if (isa_flag & OPTION_MASK_ISA_AVX512ER)
+ def_or_undef (parse_in, "__AVX512ER__");
+ if (isa_flag & OPTION_MASK_ISA_AVX512CD)
+ def_or_undef (parse_in, "__AVX512CD__");
+ if (isa_flag & OPTION_MASK_ISA_AVX512PF)
+ def_or_undef (parse_in, "__AVX512PF__");
if (isa_flag & OPTION_MASK_ISA_FMA)
def_or_undef (parse_in, "__FMA__");
if (isa_flag & OPTION_MASK_ISA_RTM)
diff --git a/gcc/config/i386/i386-interix.h b/gcc/config/i386/i386-interix.h
index c74e008b0d9..b99f4d9b908 100644
--- a/gcc/config/i386/i386-interix.h
+++ b/gcc/config/i386/i386-interix.h
@@ -143,6 +143,9 @@ do { \
#undef LIBGCC2_LONG_DOUBLE_TYPE_SIZE
#define LIBGCC2_LONG_DOUBLE_TYPE_SIZE 64
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
/* The following are needed for us to be able to use winnt.c, but are not
otherwise meaningful to Interix. (The functions that use these are
never called because we don't do DLLs.) */
diff --git a/gcc/config/i386/i386-modes.def b/gcc/config/i386/i386-modes.def
index 393cd4a23be..e0b8fc826ab 100644
--- a/gcc/config/i386/i386-modes.def
+++ b/gcc/config/i386/i386-modes.def
@@ -76,16 +76,19 @@ VECTOR_MODES (INT, 8); /* V8QI V4HI V2SI */
VECTOR_MODES (INT, 16); /* V16QI V8HI V4SI V2DI */
VECTOR_MODES (INT, 32); /* V32QI V16HI V8SI V4DI */
VECTOR_MODES (INT, 64); /* V64QI V32HI V16SI V8DI */
+VECTOR_MODES (INT, 128); /* V128QI V64HI V32SI V16DI */
VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */
VECTOR_MODES (FLOAT, 32); /* V16HF V8SF V4DF */
VECTOR_MODES (FLOAT, 64); /* V32HF V16SF V8DF */
+VECTOR_MODES (FLOAT, 128); /* V64HF V32SF V16DF */
VECTOR_MODE (INT, TI, 1); /* V1TI */
VECTOR_MODE (INT, DI, 1); /* V1DI */
VECTOR_MODE (INT, SI, 1); /* V1SI */
VECTOR_MODE (INT, QI, 2); /* V2QI */
INT_MODE (OI, 32);
+INT_MODE (XI, 64);
/* The symbol Pmode stands for one of the above machine modes (usually SImode).
The tm.h file specifies which one. It is not a distinct mode. */
diff --git a/gcc/config/i386/i386-opts.h b/gcc/config/i386/i386-opts.h
index bea1c257830..5fcbd6b5776 100644
--- a/gcc/config/i386/i386-opts.h
+++ b/gcc/config/i386/i386-opts.h
@@ -28,15 +28,17 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
/* Algorithm to expand string function with. */
enum stringop_alg
{
- no_stringop,
- libcall,
- rep_prefix_1_byte,
- rep_prefix_4_byte,
- rep_prefix_8_byte,
- loop_1_byte,
- loop,
- unrolled_loop,
- vector_loop
+#undef DEF_ENUM
+#define DEF_ENUM
+
+#undef DEF_ALG
+#define DEF_ALG(alg, name) alg,
+
+#include "stringop.def"
+last_alg
+
+#undef DEF_ENUM
+#undef DEF_ALG
};
/* Available call abi. */
diff --git a/gcc/config/i386/i386-protos.h b/gcc/config/i386/i386-protos.h
index 09667893910..3ab2f3a2ac8 100644
--- a/gcc/config/i386/i386-protos.h
+++ b/gcc/config/i386/i386-protos.h
@@ -173,6 +173,8 @@ extern int ix86_mode_after (int, int, rtx);
extern int ix86_mode_entry (int);
extern int ix86_mode_exit (int);
+extern bool ix86_libc_has_function (enum function_class fn_class);
+
#ifdef HARD_CONST
extern void ix86_emit_mode_set (int, int, HARD_REG_SET);
#endif
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 0c546af00b2..e2fa71a369a 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -62,6 +62,8 @@ along with GCC; see the file COPYING3. If not see
#include "dumpfile.h"
#include "tree-pass.h"
#include "tree-flow.h"
+#include "context.h"
+#include "pass_manager.h"
static rtx legitimize_dllimport_symbol (rtx, bool);
static rtx legitimize_pe_coff_extern_decl (rtx, bool);
@@ -85,6 +87,13 @@ static rtx legitimize_pe_coff_symbol (rtx, bool);
#define DUMMY_STRINGOP_ALGS {libcall, {{-1, libcall, false}}}
+static stringop_algs ix86_size_memcpy[2] = {
+ {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
+ {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}};
+static stringop_algs ix86_size_memset[2] = {
+ {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
+ {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}};
+
const
struct processor_costs ix86_size_cost = {/* costs for tuning for size */
COSTS_N_BYTES (2), /* cost of an add instruction */
@@ -138,10 +147,8 @@ struct processor_costs ix86_size_cost = {/* costs for tuning for size */
COSTS_N_BYTES (2), /* cost of FABS instruction. */
COSTS_N_BYTES (2), /* cost of FCHS instruction. */
COSTS_N_BYTES (2), /* cost of FSQRT instruction. */
- {{rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
- {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}},
- {{rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
- {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}}},
+ ix86_size_memcpy,
+ ix86_size_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -156,6 +163,13 @@ struct processor_costs ix86_size_cost = {/* costs for tuning for size */
};
/* Processor costs (relative to an add) */
+static stringop_algs i386_memcpy[2] = {
+ {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs i386_memset[2] = {
+ {rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
+ DUMMY_STRINGOP_ALGS};
+
static const
struct processor_costs i386_cost = { /* 386 specific costs */
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -209,10 +223,8 @@ struct processor_costs i386_cost = { /* 386 specific costs */
COSTS_N_INSNS (22), /* cost of FABS instruction. */
COSTS_N_INSNS (24), /* cost of FCHS instruction. */
COSTS_N_INSNS (122), /* cost of FSQRT instruction. */
- {{rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- {{rep_prefix_1_byte, {{-1, rep_prefix_1_byte, false}}},
- DUMMY_STRINGOP_ALGS},
+ i386_memcpy,
+ i386_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -226,6 +238,13 @@ struct processor_costs i386_cost = { /* 386 specific costs */
1, /* cond_not_taken_branch_cost. */
};
+static stringop_algs i486_memcpy[2] = {
+ {rep_prefix_4_byte, {{-1, rep_prefix_4_byte, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs i486_memset[2] = {
+ {rep_prefix_4_byte, {{-1, rep_prefix_4_byte, false}}},
+ DUMMY_STRINGOP_ALGS};
+
static const
struct processor_costs i486_cost = { /* 486 specific costs */
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -281,10 +300,8 @@ struct processor_costs i486_cost = { /* 486 specific costs */
COSTS_N_INSNS (3), /* cost of FABS instruction. */
COSTS_N_INSNS (3), /* cost of FCHS instruction. */
COSTS_N_INSNS (83), /* cost of FSQRT instruction. */
- {{rep_prefix_4_byte, {{-1, rep_prefix_4_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- {{rep_prefix_4_byte, {{-1, rep_prefix_4_byte, false}}},
- DUMMY_STRINGOP_ALGS},
+ i486_memcpy,
+ i486_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -298,6 +315,13 @@ struct processor_costs i486_cost = { /* 486 specific costs */
1, /* cond_not_taken_branch_cost. */
};
+static stringop_algs pentium_memcpy[2] = {
+ {libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs pentium_memset[2] = {
+ {libcall, {{-1, rep_prefix_4_byte, false}}},
+ DUMMY_STRINGOP_ALGS};
+
static const
struct processor_costs pentium_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -351,10 +375,8 @@ struct processor_costs pentium_cost = {
COSTS_N_INSNS (1), /* cost of FABS instruction. */
COSTS_N_INSNS (1), /* cost of FCHS instruction. */
COSTS_N_INSNS (70), /* cost of FSQRT instruction. */
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{-1, rep_prefix_4_byte, false}}},
- DUMMY_STRINGOP_ALGS},
+ pentium_memcpy,
+ pentium_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -368,6 +390,21 @@ struct processor_costs pentium_cost = {
1, /* cond_not_taken_branch_cost. */
};
+/* PentiumPro has optimized rep instructions for blocks aligned by 8 bytes
+ (we ensure the alignment). For small blocks inline loop is still a
+ noticeable win, for bigger blocks either rep movsl or rep movsb is
+ way to go. Rep movsb has apparently more expensive startup time in CPU,
+ but after 4K the difference is down in the noise. */
+static stringop_algs pentiumpro_memcpy[2] = {
+ {rep_prefix_4_byte, {{128, loop, false}, {1024, unrolled_loop, false},
+ {8192, rep_prefix_4_byte, false},
+ {-1, rep_prefix_1_byte, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs pentiumpro_memset[2] = {
+ {rep_prefix_4_byte, {{1024, unrolled_loop, false},
+ {8192, rep_prefix_4_byte, false},
+ {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
static const
struct processor_costs pentiumpro_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -421,19 +458,8 @@ struct processor_costs pentiumpro_cost = {
COSTS_N_INSNS (2), /* cost of FABS instruction. */
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (56), /* cost of FSQRT instruction. */
- /* PentiumPro has optimized rep instructions for blocks aligned by 8 bytes
- (we ensure the alignment). For small blocks inline loop is still a
- noticeable win, for bigger blocks either rep movsl or rep movsb is
- way to go. Rep movsb has apparently more expensive startup time in CPU,
- but after 4K the difference is down in the noise. */
- {{rep_prefix_4_byte, {{128, loop, false}, {1024, unrolled_loop, false},
- {8192, rep_prefix_4_byte, false},
- {-1, rep_prefix_1_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- {{rep_prefix_4_byte, {{1024, unrolled_loop, false},
- {8192, rep_prefix_4_byte, false},
- {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
+ pentiumpro_memcpy,
+ pentiumpro_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -447,6 +473,12 @@ struct processor_costs pentiumpro_cost = {
1, /* cond_not_taken_branch_cost. */
};
+static stringop_algs geode_memcpy[2] = {
+ {libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs geode_memset[2] = {
+ {libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
static const
struct processor_costs geode_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -501,10 +533,8 @@ struct processor_costs geode_cost = {
COSTS_N_INSNS (1), /* cost of FABS instruction. */
COSTS_N_INSNS (1), /* cost of FCHS instruction. */
COSTS_N_INSNS (54), /* cost of FSQRT instruction. */
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
+ geode_memcpy,
+ geode_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -518,6 +548,12 @@ struct processor_costs geode_cost = {
1, /* cond_not_taken_branch_cost. */
};
+static stringop_algs k6_memcpy[2] = {
+ {libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs k6_memset[2] = {
+ {libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
static const
struct processor_costs k6_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -574,10 +610,8 @@ struct processor_costs k6_cost = {
COSTS_N_INSNS (2), /* cost of FABS instruction. */
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (56), /* cost of FSQRT instruction. */
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{256, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
+ k6_memcpy,
+ k6_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -591,6 +625,15 @@ struct processor_costs k6_cost = {
1, /* cond_not_taken_branch_cost. */
};
+/* For some reason, Athlon deals better with REP prefix (relative to loops)
+ compared to K8. Alignment becomes important after 8 bytes for memcpy and
+ 128 bytes for memset. */
+static stringop_algs athlon_memcpy[2] = {
+ {libcall, {{2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs athlon_memset[2] = {
+ {libcall, {{2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
static const
struct processor_costs athlon_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -644,13 +687,8 @@ struct processor_costs athlon_cost = {
COSTS_N_INSNS (2), /* cost of FABS instruction. */
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
- /* For some reason, Athlon deals better with REP prefix (relative to loops)
- compared to K8. Alignment becomes important after 8 bytes for memcpy and
- 128 bytes for memset. */
- {{libcall, {{2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
+ athlon_memcpy,
+ athlon_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -664,6 +702,19 @@ struct processor_costs athlon_cost = {
1, /* cond_not_taken_branch_cost. */
};
+/* K8 has optimized REP instruction for medium sized blocks, but for very
+ small blocks it is better to use loop. For large blocks, libcall can
+ do nontemporary accesses and beat inline considerably. */
+static stringop_algs k8_memcpy[2] = {
+ {libcall, {{6, loop, false}, {14, unrolled_loop, false},
+ {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+static stringop_algs k8_memset[2] = {
+ {libcall, {{8, loop, false}, {24, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{48, unrolled_loop, false},
+ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static const
struct processor_costs k8_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -722,17 +773,9 @@ struct processor_costs k8_cost = {
COSTS_N_INSNS (2), /* cost of FABS instruction. */
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
- /* K8 has optimized REP instruction for medium sized blocks, but for very
- small blocks it is better to use loop. For large blocks, libcall can
- do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
+
+ k8_memcpy,
+ k8_memset,
4, /* scalar_stmt_cost. */
2, /* scalar load_cost. */
2, /* scalar_store_cost. */
@@ -746,6 +789,19 @@ struct processor_costs k8_cost = {
2, /* cond_not_taken_branch_cost. */
};
+/* AMDFAM10 has optimized REP instruction for medium sized blocks, but for
+ very small blocks it is better to use loop. For large blocks, libcall can
+ do nontemporary accesses and beat inline considerably. */
+static stringop_algs amdfam10_memcpy[2] = {
+ {libcall, {{6, loop, false}, {14, unrolled_loop, false},
+ {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+static stringop_algs amdfam10_memset[2] = {
+ {libcall, {{8, loop, false}, {24, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
struct processor_costs amdfam10_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (2), /* cost of a lea instruction */
@@ -812,17 +868,8 @@ struct processor_costs amdfam10_cost = {
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
- /* AMDFAM10 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall can
- do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
+ amdfam10_memcpy,
+ amdfam10_memset,
4, /* scalar_stmt_cost. */
2, /* scalar load_cost. */
2, /* scalar_store_cost. */
@@ -836,7 +883,21 @@ struct processor_costs amdfam10_cost = {
1, /* cond_not_taken_branch_cost. */
};
-struct processor_costs bdver1_cost = {
+/* BDVER1 has optimized REP instruction for medium sized blocks, but for
+ very small blocks it is better to use loop. For large blocks, libcall
+ can do nontemporary accesses and beat inline considerably. */
+static stringop_algs bdver1_memcpy[2] = {
+ {libcall, {{6, loop, false}, {14, unrolled_loop, false},
+ {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+static stringop_algs bdver1_memset[2] = {
+ {libcall, {{8, loop, false}, {24, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+
+const struct processor_costs bdver1_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -902,17 +963,8 @@ struct processor_costs bdver1_cost = {
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (52), /* cost of FSQRT instruction. */
- /* BDVER1 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall
- can do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
+ bdver1_memcpy,
+ bdver1_memset,
6, /* scalar_stmt_cost. */
4, /* scalar load_cost. */
4, /* scalar_store_cost. */
@@ -926,7 +978,22 @@ struct processor_costs bdver1_cost = {
1, /* cond_not_taken_branch_cost. */
};
-struct processor_costs bdver2_cost = {
+/* BDVER2 has optimized REP instruction for medium sized blocks, but for
+ very small blocks it is better to use loop. For large blocks, libcall
+ can do nontemporary accesses and beat inline considerably. */
+
+static stringop_algs bdver2_memcpy[2] = {
+ {libcall, {{6, loop, false}, {14, unrolled_loop, false},
+ {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+static stringop_algs bdver2_memset[2] = {
+ {libcall, {{8, loop, false}, {24, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+
+const struct processor_costs bdver2_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -992,17 +1059,8 @@ struct processor_costs bdver2_cost = {
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (52), /* cost of FSQRT instruction. */
- /* BDVER2 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall
- can do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
+ bdver2_memcpy,
+ bdver2_memset,
6, /* scalar_stmt_cost. */
4, /* scalar load_cost. */
4, /* scalar_store_cost. */
@@ -1016,6 +1074,20 @@ struct processor_costs bdver2_cost = {
1, /* cond_not_taken_branch_cost. */
};
+
+ /* BDVER3 has optimized REP instruction for medium sized blocks, but for
+ very small blocks it is better to use loop. For large blocks, libcall
+ can do nontemporary accesses and beat inline considerably. */
+static stringop_algs bdver3_memcpy[2] = {
+ {libcall, {{6, loop, false}, {14, unrolled_loop, false},
+ {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+static stringop_algs bdver3_memset[2] = {
+ {libcall, {{8, loop, false}, {24, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
struct processor_costs bdver3_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (1), /* cost of a lea instruction */
@@ -1074,17 +1146,8 @@ struct processor_costs bdver3_cost = {
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (52), /* cost of FSQRT instruction. */
- /* BDVER3 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall
- can do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
+ bdver3_memcpy,
+ bdver3_memset,
6, /* scalar_stmt_cost. */
4, /* scalar load_cost. */
4, /* scalar_store_cost. */
@@ -1098,7 +1161,20 @@ struct processor_costs bdver3_cost = {
1, /* cond_not_taken_branch_cost. */
};
-struct processor_costs btver1_cost = {
+ /* BTVER1 has optimized REP instruction for medium sized blocks, but for
+ very small blocks it is better to use loop. For large blocks, libcall can
+ do nontemporary accesses and beat inline considerably. */
+static stringop_algs btver1_memcpy[2] = {
+ {libcall, {{6, loop, false}, {14, unrolled_loop, false},
+ {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+static stringop_algs btver1_memset[2] = {
+ {libcall, {{8, loop, false}, {24, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+const struct processor_costs btver1_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (2), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1159,17 +1235,8 @@ struct processor_costs btver1_cost = {
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
- /* BTVER1 has optimized REP instruction for medium sized blocks, but for
- very small blocks it is better to use loop. For large blocks, libcall can
- do nontemporary accesses and beat inline considerably. */
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
+ btver1_memcpy,
+ btver1_memset,
4, /* scalar_stmt_cost. */
2, /* scalar load_cost. */
2, /* scalar_store_cost. */
@@ -1183,7 +1250,17 @@ struct processor_costs btver1_cost = {
1, /* cond_not_taken_branch_cost. */
};
-struct processor_costs btver2_cost = {
+static stringop_algs btver2_memcpy[2] = {
+ {libcall, {{6, loop, false}, {14, unrolled_loop, false},
+ {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+static stringop_algs btver2_memset[2] = {
+ {libcall, {{8, loop, false}, {24, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+const struct processor_costs btver2_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
COSTS_N_INSNS (2), /* cost of a lea instruction */
COSTS_N_INSNS (1), /* variable shift costs */
@@ -1243,15 +1320,8 @@ struct processor_costs btver2_cost = {
COSTS_N_INSNS (2), /* cost of FABS instruction. */
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (35), /* cost of FSQRT instruction. */
-
- {{libcall, {{6, loop, false}, {14, unrolled_loop, false},
- {-1, rep_prefix_4_byte, false}}},
- {libcall, {{16, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {24, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{48, unrolled_loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
+ btver2_memcpy,
+ btver2_memset,
4, /* scalar_stmt_cost. */
2, /* scalar load_cost. */
2, /* scalar_store_cost. */
@@ -1265,6 +1335,14 @@ struct processor_costs btver2_cost = {
1, /* cond_not_taken_branch_cost. */
};
+static stringop_algs pentium4_memcpy[2] = {
+ {libcall, {{12, loop_1_byte, false}, {-1, rep_prefix_4_byte, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs pentium4_memset[2] = {
+ {libcall, {{6, loop_1_byte, false}, {48, loop, false},
+ {20480, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
+
static const
struct processor_costs pentium4_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -1318,11 +1396,8 @@ struct processor_costs pentium4_cost = {
COSTS_N_INSNS (2), /* cost of FABS instruction. */
COSTS_N_INSNS (2), /* cost of FCHS instruction. */
COSTS_N_INSNS (43), /* cost of FSQRT instruction. */
- {{libcall, {{12, loop_1_byte, false}, {-1, rep_prefix_4_byte, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{6, loop_1_byte, false}, {48, loop, false},
- {20480, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
+ pentium4_memcpy,
+ pentium4_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -1336,6 +1411,17 @@ struct processor_costs pentium4_cost = {
1, /* cond_not_taken_branch_cost. */
};
+static stringop_algs nocona_memcpy[2] = {
+ {libcall, {{12, loop_1_byte, false}, {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{32, loop, false}, {20000, rep_prefix_8_byte, false},
+ {100000, unrolled_loop, false}, {-1, libcall, false}}}};
+
+static stringop_algs nocona_memset[2] = {
+ {libcall, {{6, loop_1_byte, false}, {48, loop, false},
+ {20480, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{24, loop, false}, {64, unrolled_loop, false},
+ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
+
static const
struct processor_costs nocona_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -1389,13 +1475,8 @@ struct processor_costs nocona_cost = {
COSTS_N_INSNS (3), /* cost of FABS instruction. */
COSTS_N_INSNS (3), /* cost of FCHS instruction. */
COSTS_N_INSNS (44), /* cost of FSQRT instruction. */
- {{libcall, {{12, loop_1_byte, false}, {-1, rep_prefix_4_byte, false}}},
- {libcall, {{32, loop, false}, {20000, rep_prefix_8_byte, false},
- {100000, unrolled_loop, false}, {-1, libcall, false}}}},
- {{libcall, {{6, loop_1_byte, false}, {48, loop, false},
- {20480, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{24, loop, false}, {64, unrolled_loop, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
+ nocona_memcpy,
+ nocona_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -1409,6 +1490,15 @@ struct processor_costs nocona_cost = {
1, /* cond_not_taken_branch_cost. */
};
+static stringop_algs atom_memcpy[2] = {
+ {libcall, {{11, loop, false}, {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false},
+ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
+static stringop_algs atom_memset[2] = {
+ {libcall, {{8, loop, false}, {15, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{24, loop, false}, {32, unrolled_loop, false},
+ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static const
struct processor_costs atom_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -1462,13 +1552,8 @@ struct processor_costs atom_cost = {
COSTS_N_INSNS (8), /* cost of FABS instruction. */
COSTS_N_INSNS (8), /* cost of FCHS instruction. */
COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
- {{libcall, {{11, loop, false}, {-1, rep_prefix_4_byte, false}}},
- {libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {15, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{24, loop, false}, {32, unrolled_loop, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
+ atom_memcpy,
+ atom_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -1482,6 +1567,15 @@ struct processor_costs atom_cost = {
1, /* cond_not_taken_branch_cost. */
};
+static stringop_algs slm_memcpy[2] = {
+ {libcall, {{11, loop, false}, {-1, rep_prefix_4_byte, false}}},
+ {libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false},
+ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
+static stringop_algs slm_memset[2] = {
+ {libcall, {{8, loop, false}, {15, unrolled_loop, false},
+ {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
+ {libcall, {{24, loop, false}, {32, unrolled_loop, false},
+ {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}};
static const
struct processor_costs slm_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -1535,13 +1629,8 @@ struct processor_costs slm_cost = {
COSTS_N_INSNS (8), /* cost of FABS instruction. */
COSTS_N_INSNS (8), /* cost of FCHS instruction. */
COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
- {{libcall, {{11, loop, false}, {-1, rep_prefix_4_byte, false}}},
- {libcall, {{32, loop, false}, {64, rep_prefix_4_byte, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
- {{libcall, {{8, loop, false}, {15, unrolled_loop, false},
- {2048, rep_prefix_4_byte, false}, {-1, libcall, false}}},
- {libcall, {{24, loop, false}, {32, unrolled_loop, false},
- {8192, rep_prefix_8_byte, false}, {-1, libcall, false}}}},
+ slm_memcpy,
+ slm_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -1556,6 +1645,15 @@ struct processor_costs slm_cost = {
};
/* Generic64 should produce code tuned for Nocona and K8. */
+
+static stringop_algs generic64_memcpy[2] = {
+ DUMMY_STRINGOP_ALGS,
+ {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
+static stringop_algs generic64_memset[2] = {
+ DUMMY_STRINGOP_ALGS,
+ {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false},
+ {-1, libcall, false}}}};
static const
struct processor_costs generic64_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -1615,12 +1713,8 @@ struct processor_costs generic64_cost = {
COSTS_N_INSNS (8), /* cost of FABS instruction. */
COSTS_N_INSNS (8), /* cost of FCHS instruction. */
COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
- {DUMMY_STRINGOP_ALGS,
- {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
- {DUMMY_STRINGOP_ALGS,
- {libcall, {{32, loop, false}, {8192, rep_prefix_8_byte, false},
- {-1, libcall, false}}}},
+ generic64_memcpy,
+ generic64_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -1635,6 +1729,18 @@ struct processor_costs generic64_cost = {
};
/* core_cost should produce code tuned for Core familly of CPUs. */
+static stringop_algs core_memcpy[2] = {
+ {libcall, {{1024, rep_prefix_4_byte, true}, {-1, libcall, false}}},
+ {libcall, {{24, loop, true}, {128, rep_prefix_8_byte, true},
+ {-1, libcall, false}}}};
+static stringop_algs core_memset[2] = {
+ {libcall, {{6, loop_1_byte, true},
+ {24, loop, true},
+ {8192, rep_prefix_4_byte, true},
+ {-1, libcall, false}}},
+ {libcall, {{24, loop, true}, {512, rep_prefix_8_byte, true},
+ {-1, libcall, false}}}};
+
static const
struct processor_costs core_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -1693,15 +1799,8 @@ struct processor_costs core_cost = {
COSTS_N_INSNS (8), /* cost of FABS instruction. */
COSTS_N_INSNS (8), /* cost of FCHS instruction. */
COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
- {{libcall, {{1024, rep_prefix_4_byte, true}, {-1, libcall, false}}},
- {libcall, {{24, loop, true}, {128, rep_prefix_8_byte, true},
- {-1, libcall, false}}}},
- {{libcall, {{6, loop_1_byte, true},
- {24, loop, true},
- {8192, rep_prefix_4_byte, true},
- {-1, libcall, false}}},
- {libcall, {{24, loop, true}, {512, rep_prefix_8_byte, true},
- {-1, libcall, false}}}},
+ core_memcpy,
+ core_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -1717,6 +1816,14 @@ struct processor_costs core_cost = {
/* Generic32 should produce code tuned for PPro, Pentium4, Nocona,
Athlon and K8. */
+static stringop_algs generic32_memcpy[2] = {
+ {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false},
+ {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
+static stringop_algs generic32_memset[2] = {
+ {libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false},
+ {-1, libcall, false}}},
+ DUMMY_STRINGOP_ALGS};
static const
struct processor_costs generic32_cost = {
COSTS_N_INSNS (1), /* cost of an add instruction */
@@ -1770,12 +1877,8 @@ struct processor_costs generic32_cost = {
COSTS_N_INSNS (8), /* cost of FABS instruction. */
COSTS_N_INSNS (8), /* cost of FCHS instruction. */
COSTS_N_INSNS (40), /* cost of FSQRT instruction. */
- {{libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false},
- {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
- {{libcall, {{32, loop, false}, {8192, rep_prefix_4_byte, false},
- {-1, libcall, false}}},
- DUMMY_STRINGOP_ALGS},
+ generic32_memcpy,
+ generic32_memset,
1, /* scalar_stmt_cost. */
1, /* scalar load_cost. */
1, /* scalar_store_cost. */
@@ -1833,287 +1936,23 @@ const struct processor_costs *ix86_cost = &pentium_cost;
(PPro/PENT4/NOCONA/CORE2/Athlon/K8). */
#define m_GENERIC (m_GENERIC32 | m_GENERIC64)
+const char* ix86_tune_feature_names[X86_TUNE_LAST] = {
+#undef DEF_TUNE
+#define DEF_TUNE(tune, name, selector) name,
+#include "x86-tune.def"
+#undef DEF_TUNE
+};
+
/* Feature tests against the various tunings. */
unsigned char ix86_tune_features[X86_TUNE_LAST];
/* Feature tests against the various tunings used to create ix86_tune_features
based on the processor mask. */
static unsigned int initial_ix86_tune_features[X86_TUNE_LAST] = {
- /* X86_TUNE_USE_LEAVE: Leave does not affect Nocona SPEC2000 results
- negatively, so enabling for Generic64 seems like good code size
- tradeoff. We can't enable it for 32bit generic because it does not
- work well with PPro base chips. */
- m_386 | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC64,
-
- /* X86_TUNE_PUSH_MEMORY */
- m_386 | m_P4_NOCONA | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_ZERO_EXTEND_WITH_AND */
- m_486 | m_PENT,
-
- /* X86_TUNE_UNROLL_STRLEN */
- m_486 | m_PENT | m_PPRO | m_ATOM | m_SLM | m_CORE_ALL | m_K6 | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_BRANCH_PREDICTION_HINTS: Branch hints were put in P4 based
- on simulation result. But after P4 was made, no performance benefit
- was observed with branch hints. It also increases the code size.
- As a result, icc never generates branch hints. */
- 0,
-
- /* X86_TUNE_DOUBLE_WITH_ADD */
- ~m_386,
-
- /* X86_TUNE_USE_SAHF */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC,
-
- /* X86_TUNE_MOVX: Enable to zero extend integer registers to avoid
- partial dependencies. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GEODE | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_PARTIAL_REG_STALL: We probably ought to watch for partial
- register stalls on Generic32 compilation setting as well. However
- in current implementation the partial register stalls are not eliminated
- very well - they can be introduced via subregs synthesized by combine
- and can happen in caller/callee saving sequences. Because this option
- pays back little on PPro based chips and is in conflict with partial reg
- dependencies used by Athlon/P4 based chips, it is better to leave it off
- for generic32 for now. */
- m_PPRO,
-
- /* X86_TUNE_PARTIAL_FLAG_REG_STALL */
- m_CORE_ALL | m_GENERIC,
-
- /* X86_TUNE_LCP_STALL: Avoid an expensive length-changing prefix stall
- * on 16-bit immediate moves into memory on Core2 and Corei7. */
- m_CORE_ALL | m_GENERIC,
-
- /* X86_TUNE_USE_HIMODE_FIOP */
- m_386 | m_486 | m_K6_GEODE,
-
- /* X86_TUNE_USE_SIMODE_FIOP */
- ~(m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC),
-
- /* X86_TUNE_USE_MOV0 */
- m_K6,
-
- /* X86_TUNE_USE_CLTD */
- ~(m_PENT | m_ATOM | m_SLM | m_K6),
-
- /* X86_TUNE_USE_XCHGB: Use xchgb %rh,%rl instead of rolw/rorw $8,rx. */
- m_PENT4,
-
- /* X86_TUNE_SPLIT_LONG_MOVES */
- m_PPRO,
-
- /* X86_TUNE_READ_MODIFY_WRITE */
- ~m_PENT,
-
- /* X86_TUNE_READ_MODIFY */
- ~(m_PENT | m_PPRO),
-
- /* X86_TUNE_PROMOTE_QIMODE */
- m_386 | m_486 | m_PENT | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_FAST_PREFIX */
- ~(m_386 | m_486 | m_PENT),
-
- /* X86_TUNE_SINGLE_STRINGOP */
- m_386 | m_P4_NOCONA,
-
- /* X86_TUNE_QIMODE_MATH */
- ~0,
-
- /* X86_TUNE_HIMODE_MATH: On PPro this flag is meant to avoid partial
- register stalls. Just like X86_TUNE_PARTIAL_REG_STALL this option
- might be considered for Generic32 if our scheme for avoiding partial
- stalls was more effective. */
- ~m_PPRO,
-
- /* X86_TUNE_PROMOTE_QI_REGS */
- 0,
-
- /* X86_TUNE_PROMOTE_HI_REGS */
- m_PPRO,
-
- /* X86_TUNE_SINGLE_POP: Enable if single pop insn is preferred
- over esp addition. */
- m_386 | m_486 | m_PENT | m_PPRO,
-
- /* X86_TUNE_DOUBLE_POP: Enable if double pop insn is preferred
- over esp addition. */
- m_PENT,
-
- /* X86_TUNE_SINGLE_PUSH: Enable if single push insn is preferred
- over esp subtraction. */
- m_386 | m_486 | m_PENT | m_K6_GEODE,
-
- /* X86_TUNE_DOUBLE_PUSH. Enable if double push insn is preferred
- over esp subtraction. */
- m_PENT | m_K6_GEODE,
-
- /* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
- for DFmode copies */
- ~(m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GEODE | m_AMD_MULTIPLE | m_GENERIC),
-
- /* X86_TUNE_PARTIAL_REG_DEPENDENCY */
- m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: In the Generic model we have a
- conflict here in between PPro/Pentium4 based chips that thread 128bit
- SSE registers as single units versus K8 based chips that divide SSE
- registers to two 64bit halves. This knob promotes all store destinations
- to be 128bit to allow register renaming on 128bit SSE units, but usually
- results in one extra microop on 64bit SSE units. Experimental results
- shows that disabling this option on P4 brings over 20% SPECfp regression,
- while enabling it on K8 brings roughly 2.4% regression that can be partly
- masked by careful scheduling of moves. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMDFAM10 | m_BDVER | m_GENERIC,
-
- /* X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL */
- m_COREI7 | m_AMDFAM10 | m_BDVER | m_BTVER | m_SLM,
-
- /* X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL */
- m_COREI7 | m_BDVER | m_SLM,
-
- /* X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL */
- m_BDVER ,
-
- /* X86_TUNE_SSE_SPLIT_REGS: Set for machines where the type and dependencies
- are resolved on SSE register parts instead of whole registers, so we may
- maintain just lower part of scalar values in proper format leaving the
- upper part undefined. */
- m_ATHLON_K8,
-
- /* X86_TUNE_SSE_TYPELESS_STORES */
- m_AMD_MULTIPLE,
-
- /* X86_TUNE_SSE_LOAD0_BY_PXOR */
- m_PPRO | m_P4_NOCONA,
-
- /* X86_TUNE_MEMORY_MISMATCH_STALL */
- m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_PROLOGUE_USING_MOVE */
- m_PPRO | m_ATHLON_K8,
-
- /* X86_TUNE_EPILOGUE_USING_MOVE */
- m_PPRO | m_ATHLON_K8,
-
- /* X86_TUNE_SHIFT1 */
- ~m_486,
-
- /* X86_TUNE_USE_FFREEP */
- m_AMD_MULTIPLE,
-
- /* X86_TUNE_INTER_UNIT_MOVES_TO_VEC */
- ~(m_AMD_MULTIPLE | m_GENERIC),
-
- /* X86_TUNE_INTER_UNIT_MOVES_FROM_VEC */
- ~m_ATHLON_K8,
-
- /* X86_TUNE_INTER_UNIT_CONVERSIONS */
- ~(m_AMDFAM10 | m_BDVER ),
-
- /* X86_TUNE_FOUR_JUMP_LIMIT: Some CPU cores are not able to predict more
- than 4 branch instructions in the 16 byte window. */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_SCHEDULE */
- m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_USE_BT */
- m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_USE_INCDEC */
- ~(m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GENERIC),
-
- /* X86_TUNE_PAD_RETURNS */
- m_CORE_ALL | m_AMD_MULTIPLE | m_GENERIC,
-
- /* X86_TUNE_PAD_SHORT_FUNCTION: Pad short function. */
- m_ATOM,
-
- /* X86_TUNE_EXT_80387_CONSTANTS */
- m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE | m_ATHLON_K8 | m_GENERIC,
-
- /* X86_TUNE_AVOID_VECTOR_DECODE */
- m_CORE_ALL | m_K8 | m_GENERIC64,
-
- /* X86_TUNE_PROMOTE_HIMODE_IMUL: Modern CPUs have same latency for HImode
- and SImode multiply, but 386 and 486 do HImode multiply faster. */
- ~(m_386 | m_486),
-
- /* X86_TUNE_SLOW_IMUL_IMM32_MEM: Imul of 32-bit constant and memory is
- vector path on AMD machines. */
- m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC64,
-
- /* X86_TUNE_SLOW_IMUL_IMM8: Imul of 8-bit constant is vector path on AMD
- machines. */
- m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC64,
-
- /* X86_TUNE_MOVE_M1_VIA_OR: On pentiums, it is faster to load -1 via OR
- than a MOV. */
- m_PENT,
-
- /* X86_TUNE_NOT_UNPAIRABLE: NOT is not pairable on Pentium, while XOR is,
- but one byte longer. */
- m_PENT,
-
- /* X86_TUNE_NOT_VECTORMODE: On AMD K6, NOT is vector decoded with memory
- operand that cannot be represented using a modRM byte. The XOR
- replacement is long decoded, so this split helps here as well. */
- m_K6,
-
- /* X86_TUNE_USE_VECTOR_FP_CONVERTS: Prefer vector packed SSE conversion
- from FP to FP. */
- m_CORE_ALL | m_AMDFAM10 | m_GENERIC,
-
- /* X86_TUNE_USE_VECTOR_CONVERTS: Prefer vector packed SSE conversion
- from integer to FP. */
- m_AMDFAM10,
-
- /* X86_TUNE_FUSE_CMP_AND_BRANCH: Fuse a compare or test instruction
- with a subsequent conditional jump instruction into a single
- compare-and-branch uop. */
- m_BDVER,
-
- /* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
- will impact LEA instruction selection. */
- m_ATOM | m_SLM,
-
- /* X86_TUNE_VECTORIZE_DOUBLE: Enable double precision vector
- instructions. */
- ~m_ATOM,
-
- /* X86_TUNE_SOFTWARE_PREFETCHING_BENEFICIAL: Enable software prefetching
- at -O3. For the moment, the prefetching seems badly tuned for Intel
- chips. */
- m_K6_GEODE | m_AMD_MULTIPLE,
-
- /* X86_TUNE_AVX128_OPTIMAL: Enable 128-bit AVX instruction generation for
- the auto-vectorizer. */
- m_BDVER | m_BTVER2,
-
- /* X86_TUNE_REASSOC_INT_TO_PARALLEL: Try to produce parallel computations
- during reassociation of integer computation. */
- m_ATOM,
-
- /* X86_TUNE_REASSOC_FP_TO_PARALLEL: Try to produce parallel computations
- during reassociation of fp computation. */
- m_ATOM | m_SLM | m_HASWELL | m_BDVER1 | m_BDVER2,
-
- /* X86_TUNE_GENERAL_REGS_SSE_SPILL: Try to spill general regs to SSE
- regs instead of memory. */
- m_CORE_ALL,
-
- /* X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE: Try to avoid memory operands for
- a conditional move. */
- m_ATOM,
-
- /* X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS: Try to split memory operand for
- fp converts to destination register. */
- m_SLM
-
+#undef DEF_TUNE
+#define DEF_TUNE(tune, name, selector) selector,
+#include "x86-tune.def"
+#undef DEF_TUNE
};
/* Feature tests against the various architecture variations. */
@@ -2188,6 +2027,11 @@ enum reg_class const regclass_map[FIRST_PSEUDO_REGISTER] =
/* SSE REX registers */
SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS, SSE_REGS,
SSE_REGS, SSE_REGS,
+ /* AVX-512 SSE registers */
+ EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS,
+ EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS,
+ EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS,
+ EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS, EVEX_SSE_REGS,
};
/* The "default" register map used in 32bit mode. */
@@ -2201,6 +2045,8 @@ int const dbx_register_map[FIRST_PSEUDO_REGISTER] =
29, 30, 31, 32, 33, 34, 35, 36, /* MMX */
-1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */
-1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 16-23*/
+ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 24-31*/
};
/* The "default" register map used in 64bit mode. */
@@ -2214,6 +2060,8 @@ int const dbx64_register_map[FIRST_PSEUDO_REGISTER] =
41, 42, 43, 44, 45, 46, 47, 48, /* MMX */
8,9,10,11,12,13,14,15, /* extended integer registers */
25, 26, 27, 28, 29, 30, 31, 32, /* extended SSE registers */
+ 67, 68, 69, 70, 71, 72, 73, 74, /* AVX-512 registers 16-23 */
+ 75, 76, 77, 78, 79, 80, 81, 82, /* AVX-512 registers 24-31 */
};
/* Define the register numbers to be used in Dwarf debugging information.
@@ -2279,6 +2127,8 @@ int const svr4_dbx_register_map[FIRST_PSEUDO_REGISTER] =
29, 30, 31, 32, 33, 34, 35, 36, /* MMX registers */
-1, -1, -1, -1, -1, -1, -1, -1, /* extended integer registers */
-1, -1, -1, -1, -1, -1, -1, -1, /* extended SSE registers */
+ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 16-23*/
+ -1, -1, -1, -1, -1, -1, -1, -1, /* AVX-512 registers 24-31*/
};
/* Define parameter passing and return registers. */
@@ -2471,7 +2321,6 @@ enum ix86_function_specific_strings
static char *ix86_target_string (HOST_WIDE_INT, int, const char *,
const char *, enum fpmath_unit, bool);
-static void ix86_debug_options (void) ATTRIBUTE_UNUSED;
static void ix86_function_specific_save (struct cl_target_option *);
static void ix86_function_specific_restore (struct cl_target_option *);
static void ix86_function_specific_print (FILE *, int,
@@ -2578,7 +2427,7 @@ static const char *const cpu_names[TARGET_CPU_DEFAULT_max] =
static bool
gate_insert_vzeroupper (void)
{
- return TARGET_AVX && TARGET_VZEROUPPER;
+ return TARGET_AVX && !TARGET_AVX512F && TARGET_VZEROUPPER;
}
static unsigned int
@@ -2596,31 +2445,48 @@ rest_of_handle_insert_vzeroupper (void)
ix86_optimize_mode_switching[AVX_U128] = 1;
/* Call optimize_mode_switching. */
- pass_mode_switching.pass.execute ();
+ g->get_passes ()->execute_pass_mode_switching ();
return 0;
}
-struct rtl_opt_pass pass_insert_vzeroupper =
+namespace {
+
+const pass_data pass_data_insert_vzeroupper =
{
- {
- RTL_PASS,
- "vzeroupper", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_insert_vzeroupper, /* gate */
- rest_of_handle_insert_vzeroupper, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- 0, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "vzeroupper", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */
};
+class pass_insert_vzeroupper : public rtl_opt_pass
+{
+public:
+ pass_insert_vzeroupper(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_insert_vzeroupper, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_insert_vzeroupper (); }
+ unsigned int execute () { return rest_of_handle_insert_vzeroupper (); }
+
+}; // class pass_insert_vzeroupper
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_insert_vzeroupper (gcc::context *ctxt)
+{
+ return new pass_insert_vzeroupper (ctxt);
+}
+
/* Return true if a red-zone is in use. */
static inline bool
@@ -2651,6 +2517,10 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch,
{ "-mfma", OPTION_MASK_ISA_FMA },
{ "-mxop", OPTION_MASK_ISA_XOP },
{ "-mlwp", OPTION_MASK_ISA_LWP },
+ { "-mavx512f", OPTION_MASK_ISA_AVX512F },
+ { "-mavx512er", OPTION_MASK_ISA_AVX512ER },
+ { "-mavx512cd", OPTION_MASK_ISA_AVX512CD },
+ { "-mavx512pf", OPTION_MASK_ISA_AVX512PF },
{ "-msse4a", OPTION_MASK_ISA_SSE4A },
{ "-msse4.2", OPTION_MASK_ISA_SSE4_2 },
{ "-msse4.1", OPTION_MASK_ISA_SSE4_1 },
@@ -2883,7 +2753,7 @@ ix86_profile_before_prologue (void)
/* Function that is callable from the debugger to print the current
options. */
-void
+void ATTRIBUTE_UNUSED
ix86_debug_options (void)
{
char *opts = ix86_target_string (ix86_isa_flags, target_flags,
@@ -2900,7 +2770,222 @@ ix86_debug_options (void)
return;
}
+
+static const char *stringop_alg_names[] = {
+#define DEF_ENUM
+#define DEF_ALG(alg, name) #name,
+#include "stringop.def"
+#undef DEF_ENUM
+#undef DEF_ALG
+};
+
+/* Parse parameter string passed to -mmemcpy-strategy= or -mmemset-strategy=.
+ The string is of the following form (or comma separated list of it):
+
+ strategy_alg:max_size:[align|noalign]
+
+ where the full size range for the strategy is either [0, max_size] or
+ [min_size, max_size], in which min_size is the max_size + 1 of the
+ preceding range. The last size range must have max_size == -1.
+
+ Examples:
+
+ 1.
+ -mmemcpy-strategy=libcall:-1:noalign
+
+ this is equivalent to (for known size memcpy) -mstringop-strategy=libcall
+
+
+ 2.
+ -mmemset-strategy=rep_8byte:16:noalign,vector_loop:2048:align,libcall:-1:noalign
+
+ This is to tell the compiler to use the following strategy for memset
+ 1) when the expected size is between [1, 16], use rep_8byte strategy;
+ 2) when the size is between [17, 2048], use vector_loop;
+ 3) when the size is > 2048, use libcall. */
+
+struct stringop_size_range
+{
+ int max;
+ stringop_alg alg;
+ bool noalign;
+};
+
+static void
+ix86_parse_stringop_strategy_string (char *strategy_str, bool is_memset)
+{
+ const struct stringop_algs *default_algs;
+ stringop_size_range input_ranges[MAX_STRINGOP_ALGS];
+ char *curr_range_str, *next_range_str;
+ int i = 0, n = 0;
+
+ if (is_memset)
+ default_algs = &ix86_cost->memset[TARGET_64BIT != 0];
+ else
+ default_algs = &ix86_cost->memcpy[TARGET_64BIT != 0];
+
+ curr_range_str = strategy_str;
+
+ do
+ {
+ int maxs;
+ stringop_alg alg;
+ char alg_name[128];
+ char align[16];
+ next_range_str = strchr (curr_range_str, ',');
+ if (next_range_str)
+ *next_range_str++ = '\0';
+
+ if (3 != sscanf (curr_range_str, "%20[^:]:%d:%10s",
+ alg_name, &maxs, align))
+ {
+ error ("wrong arg %s to option %s", curr_range_str,
+ is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+ return;
+ }
+
+ if (n > 0 && (maxs < (input_ranges[n - 1].max + 1) && maxs != -1))
+ {
+ error ("size ranges of option %s should be increasing",
+ is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+ return;
+ }
+
+ for (i = 0; i < last_alg; i++)
+ {
+ if (!strcmp (alg_name, stringop_alg_names[i]))
+ {
+ alg = (stringop_alg) i;
+ break;
+ }
+ }
+
+ if (i == last_alg)
+ {
+ error ("wrong stringop strategy name %s specified for option %s",
+ alg_name,
+ is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+ return;
+ }
+
+ input_ranges[n].max = maxs;
+ input_ranges[n].alg = alg;
+ if (!strcmp (align, "align"))
+ input_ranges[n].noalign = false;
+ else if (!strcmp (align, "noalign"))
+ input_ranges[n].noalign = true;
+ else
+ {
+ error ("unknown alignment %s specified for option %s",
+ align, is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+ return;
+ }
+ n++;
+ curr_range_str = next_range_str;
+ }
+ while (curr_range_str);
+
+ if (input_ranges[n - 1].max != -1)
+ {
+ error ("the max value for the last size range should be -1"
+ " for option %s",
+ is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+ return;
+ }
+
+ if (n > MAX_STRINGOP_ALGS)
+ {
+ error ("too many size ranges specified in option %s",
+ is_memset ? "-mmemset_strategy=" : "-mmemcpy_strategy=");
+ return;
+ }
+
+ /* Now override the default algs array. */
+ for (i = 0; i < n; i++)
+ {
+ *const_cast<int *>(&default_algs->size[i].max) = input_ranges[i].max;
+ *const_cast<stringop_alg *>(&default_algs->size[i].alg)
+ = input_ranges[i].alg;
+ *const_cast<int *>(&default_algs->size[i].noalign)
+ = input_ranges[i].noalign;
+ }
+}
+
+/* parse -mtune-ctrl= option. When DUMP is true,
+ print the features that are explicitly set. */
+
+static void
+parse_mtune_ctrl_str (bool dump)
+{
+ if (!ix86_tune_ctrl_string)
+ return;
+
+ char *next_feature_string = NULL;
+ char *curr_feature_string = xstrdup (ix86_tune_ctrl_string);
+ char *orig = curr_feature_string;
+ int i;
+ do
+ {
+ bool clear = false;
+
+ next_feature_string = strchr (curr_feature_string, ',');
+ if (next_feature_string)
+ *next_feature_string++ = '\0';
+ if (*curr_feature_string == '^')
+ {
+ curr_feature_string++;
+ clear = true;
+ }
+ for (i = 0; i < X86_TUNE_LAST; i++)
+ {
+ if (!strcmp (curr_feature_string, ix86_tune_feature_names[i]))
+ {
+ ix86_tune_features[i] = !clear;
+ if (dump)
+ fprintf (stderr, "Explicitly %s feature %s\n",
+ clear ? "clear" : "set", ix86_tune_feature_names[i]);
+ break;
+ }
+ }
+ if (i == X86_TUNE_LAST)
+ error ("Unknown parameter to option -mtune-ctrl: %s",
+ clear ? curr_feature_string - 1 : curr_feature_string);
+ curr_feature_string = next_feature_string;
+ }
+ while (curr_feature_string);
+ free (orig);
+}
+
+/* Helper function to set ix86_tune_features. IX86_TUNE is the
+ processor type. */
+
+static void
+set_ix86_tune_features (enum processor_type ix86_tune, bool dump)
+{
+ unsigned int ix86_tune_mask = 1u << ix86_tune;
+ int i;
+
+ for (i = 0; i < X86_TUNE_LAST; ++i)
+ {
+ if (ix86_tune_no_default)
+ ix86_tune_features[i] = 0;
+ else
+ ix86_tune_features[i] = !!(initial_ix86_tune_features[i] & ix86_tune_mask);
+ }
+
+ if (dump)
+ {
+ fprintf (stderr, "List of x86 specific tuning parameter names:\n");
+ for (i = 0; i < X86_TUNE_LAST; i++)
+ fprintf (stderr, "%s : %s\n", ix86_tune_feature_names[i],
+ ix86_tune_features[i] ? "on" : "off");
+ }
+
+ parse_mtune_ctrl_str (dump);
+}
+
+
/* Override various settings based on options. If MAIN_ARGS_P, the
options are from the command line, otherwise they are from
attributes. */
@@ -2955,6 +3040,10 @@ ix86_option_override_internal (bool main_args_p)
#define PTA_FXSR (HOST_WIDE_INT_1 << 37)
#define PTA_XSAVE (HOST_WIDE_INT_1 << 38)
#define PTA_XSAVEOPT (HOST_WIDE_INT_1 << 39)
+#define PTA_AVX512F (HOST_WIDE_INT_1 << 40)
+#define PTA_AVX512ER (HOST_WIDE_INT_1 << 41)
+#define PTA_AVX512PF (HOST_WIDE_INT_1 << 42)
+#define PTA_AVX512CD (HOST_WIDE_INT_1 << 43)
/* if this reaches 64, need to widen struct pta flags below */
@@ -3476,6 +3565,18 @@ ix86_option_override_internal (bool main_args_p)
if (processor_alias_table[i].flags & PTA_XSAVEOPT
&& !(ix86_isa_flags_explicit & OPTION_MASK_ISA_XSAVEOPT))
ix86_isa_flags |= OPTION_MASK_ISA_XSAVEOPT;
+ if (processor_alias_table[i].flags & PTA_AVX512F
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512F))
+ ix86_isa_flags |= OPTION_MASK_ISA_AVX512F;
+ if (processor_alias_table[i].flags & PTA_AVX512ER
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512ER))
+ ix86_isa_flags |= OPTION_MASK_ISA_AVX512ER;
+ if (processor_alias_table[i].flags & PTA_AVX512PF
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512PF))
+ ix86_isa_flags |= OPTION_MASK_ISA_AVX512PF;
+ if (processor_alias_table[i].flags & PTA_AVX512CD
+ && !(ix86_isa_flags_explicit & OPTION_MASK_ISA_AVX512CD))
+ ix86_isa_flags |= OPTION_MASK_ISA_AVX512CD;
if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE))
x86_prefetch_sse = true;
@@ -3546,9 +3647,7 @@ ix86_option_override_internal (bool main_args_p)
error ("bad value (%s) for %stune=%s %s",
ix86_tune_string, prefix, suffix, sw);
- ix86_tune_mask = 1u << ix86_tune;
- for (i = 0; i < X86_TUNE_LAST; ++i)
- ix86_tune_features[i] = !!(initial_ix86_tune_features[i] & ix86_tune_mask);
+ set_ix86_tune_features (ix86_tune, ix86_dump_tunes);
#ifndef USE_IX86_FRAME_POINTER
#define USE_IX86_FRAME_POINTER 0
@@ -3784,6 +3883,7 @@ ix86_option_override_internal (bool main_args_p)
gcc_unreachable ();
}
+ ix86_tune_mask = 1u << ix86_tune;
if ((!USE_IX86_FRAME_POINTER
|| (x86_accumulate_outgoing_args & ix86_tune_mask))
&& !(target_flags_explicit & MASK_ACCUMULATE_OUTGOING_ARGS)
@@ -3866,24 +3966,19 @@ ix86_option_override_internal (bool main_args_p)
ix86_gen_leave = gen_leave_rex64;
if (Pmode == DImode)
{
- ix86_gen_monitor = gen_sse3_monitor64_di;
ix86_gen_tls_global_dynamic_64 = gen_tls_global_dynamic_64_di;
ix86_gen_tls_local_dynamic_base_64
= gen_tls_local_dynamic_base_64_di;
}
else
{
- ix86_gen_monitor = gen_sse3_monitor64_si;
ix86_gen_tls_global_dynamic_64 = gen_tls_global_dynamic_64_si;
ix86_gen_tls_local_dynamic_base_64
= gen_tls_local_dynamic_base_64_si;
}
}
else
- {
- ix86_gen_leave = gen_leave;
- ix86_gen_monitor = gen_sse3_monitor;
- }
+ ix86_gen_leave = gen_leave;
if (Pmode == DImode)
{
@@ -3895,6 +3990,7 @@ ix86_option_override_internal (bool main_args_p)
ix86_gen_allocate_stack_worker = gen_allocate_stack_worker_probe_di;
ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probedi;
ix86_gen_probe_stack_range = gen_probe_stack_rangedi;
+ ix86_gen_monitor = gen_sse3_monitor_di;
}
else
{
@@ -3906,6 +4002,7 @@ ix86_option_override_internal (bool main_args_p)
ix86_gen_allocate_stack_worker = gen_allocate_stack_worker_probe_si;
ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probesi;
ix86_gen_probe_stack_range = gen_probe_stack_rangesi;
+ ix86_gen_monitor = gen_sse3_monitor_si;
}
#ifdef USE_IX86_CLD
@@ -3940,22 +4037,22 @@ ix86_option_override_internal (bool main_args_p)
TARGET_AVX with -fexpensive-optimizations and split 32-byte
AVX unaligned load/store. */
if (!optimize_size)
- {
- if (flag_expensive_optimizations
- && !(target_flags_explicit & MASK_VZEROUPPER))
+ {
+ if (flag_expensive_optimizations
+ && !(target_flags_explicit & MASK_VZEROUPPER))
target_flags |= MASK_VZEROUPPER;
- if ((x86_avx256_split_unaligned_load & ix86_tune_mask)
- && !(target_flags_explicit & MASK_AVX256_SPLIT_UNALIGNED_LOAD))
+ if ((x86_avx256_split_unaligned_load & ix86_tune_mask)
+ && !(target_flags_explicit & MASK_AVX256_SPLIT_UNALIGNED_LOAD))
target_flags |= MASK_AVX256_SPLIT_UNALIGNED_LOAD;
- if ((x86_avx256_split_unaligned_store & ix86_tune_mask)
- && !(target_flags_explicit & MASK_AVX256_SPLIT_UNALIGNED_STORE))
+ if ((x86_avx256_split_unaligned_store & ix86_tune_mask)
+ && !(target_flags_explicit & MASK_AVX256_SPLIT_UNALIGNED_STORE))
target_flags |= MASK_AVX256_SPLIT_UNALIGNED_STORE;
- /* Enable 128-bit AVX instruction generation
- for the auto-vectorizer. */
- if (TARGET_AVX128_OPTIMAL
- && !(target_flags_explicit & MASK_PREFER_AVX128))
+ /* Enable 128-bit AVX instruction generation
+ for the auto-vectorizer. */
+ if (TARGET_AVX128_OPTIMAL
+ && !(target_flags_explicit & MASK_PREFER_AVX128))
target_flags |= MASK_PREFER_AVX128;
- }
+ }
if (ix86_recip_name)
{
@@ -4021,6 +4118,21 @@ ix86_option_override_internal (bool main_args_p)
/* Handle stack protector */
if (!global_options_set.x_ix86_stack_protector_guard)
ix86_stack_protector_guard = TARGET_HAS_BIONIC ? SSP_GLOBAL : SSP_TLS;
+
+ /* Handle -mmemcpy-strategy= and -mmemset-strategy= */
+ if (ix86_tune_memcpy_strategy)
+ {
+ char *str = xstrdup (ix86_tune_memcpy_strategy);
+ ix86_parse_stringop_strategy_string (str, false);
+ free (str);
+ }
+
+ if (ix86_tune_memset_strategy)
+ {
+ char *str = xstrdup (ix86_tune_memset_strategy);
+ ix86_parse_stringop_strategy_string (str, true);
+ free (str);
+ }
}
/* Implement the TARGET_OPTION_OVERRIDE hook. */
@@ -4028,8 +4140,9 @@ ix86_option_override_internal (bool main_args_p)
static void
ix86_option_override (void)
{
+ opt_pass *pass_insert_vzeroupper = make_pass_insert_vzeroupper (g);
static struct register_pass_info insert_vzeroupper_info
- = { &pass_insert_vzeroupper.pass, "reload",
+ = { pass_insert_vzeroupper, "reload",
1, PASS_POS_INSERT_AFTER
};
@@ -4060,6 +4173,8 @@ ix86_conditional_register_usage (void)
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
+ for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
+ fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
}
/* See the definition of CALL_USED_REGISTERS in i386.h. */
@@ -4100,6 +4215,11 @@ ix86_conditional_register_usage (void)
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (TEST_HARD_REG_BIT (reg_class_contents[(int)FLOAT_REGS], i))
fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
+
+ /* If AVX512F is disabled, squash the registers. */
+ if (! TARGET_AVX512F)
+ for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
+ fixed_regs[i] = call_used_regs[i] = 1, reg_names[i] = "";
}
@@ -4133,7 +4253,7 @@ ix86_function_specific_restore (struct cl_target_option *ptr)
{
enum processor_type old_tune = ix86_tune;
enum processor_type old_arch = ix86_arch;
- unsigned int ix86_arch_mask, ix86_tune_mask;
+ unsigned int ix86_arch_mask;
int i;
ix86_arch = (enum processor_type) ptr->arch;
@@ -4157,12 +4277,7 @@ ix86_function_specific_restore (struct cl_target_option *ptr)
/* Recreate the tune optimization tests */
if (old_tune != ix86_tune)
- {
- ix86_tune_mask = 1u << ix86_tune;
- for (i = 0; i < X86_TUNE_LAST; ++i)
- ix86_tune_features[i]
- = !!(initial_ix86_tune_features[i] & ix86_tune_mask);
- }
+ set_ix86_tune_features (ix86_tune, false);
}
/* Print the current options */
@@ -4244,6 +4359,10 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[],
IX86_ATTR_ISA ("aes", OPT_maes),
IX86_ATTR_ISA ("avx", OPT_mavx),
IX86_ATTR_ISA ("avx2", OPT_mavx2),
+ IX86_ATTR_ISA ("avx512f", OPT_mavx512f),
+ IX86_ATTR_ISA ("avx512pf", OPT_mavx512pf),
+ IX86_ATTR_ISA ("avx512er", OPT_mavx512er),
+ IX86_ATTR_ISA ("avx512cd", OPT_mavx512cd),
IX86_ATTR_ISA ("mmx", OPT_mmmx),
IX86_ATTR_ISA ("pclmul", OPT_mpclmul),
IX86_ATTR_ISA ("popcnt", OPT_mpopcnt),
@@ -4728,10 +4847,7 @@ ix86_in_large_data_p (tree exp)
RELOC indicates whether forming the initial value of DECL requires
link-time relocations. */
-static section * x86_64_elf_select_section (tree, int, unsigned HOST_WIDE_INT)
- ATTRIBUTE_UNUSED;
-
-static section *
+ATTRIBUTE_UNUSED static section *
x86_64_elf_select_section (tree decl, int reloc,
unsigned HOST_WIDE_INT align)
{
@@ -4792,6 +4908,28 @@ x86_64_elf_select_section (tree decl, int reloc,
return default_elf_select_section (decl, reloc, align);
}
+/* Select a set of attributes for section NAME based on the properties
+ of DECL and whether or not RELOC indicates that DECL's initializer
+ might contain runtime relocations. */
+
+static unsigned int ATTRIBUTE_UNUSED
+x86_64_elf_section_type_flags (tree decl, const char *name, int reloc)
+{
+ unsigned int flags = default_section_type_flags (decl, name, reloc);
+
+ if (decl == NULL_TREE
+ && (strcmp (name, ".ldata.rel.ro") == 0
+ || strcmp (name, ".ldata.rel.ro.local") == 0))
+ flags |= SECTION_RELRO;
+
+ if (strcmp (name, ".lbss") == 0
+ || strncmp (name, ".lbss.", 5) == 0
+ || strncmp (name, ".gnu.linkonce.lb.", 16) == 0)
+ flags |= SECTION_BSS;
+
+ return flags;
+}
+
/* Build up a unique section name, expressed as a
STRING_CST node, and assign it to DECL_SECTION_NAME (decl).
RELOC indicates whether the initial value of EXP requires
@@ -5161,8 +5299,7 @@ ix86_handle_cconv_attribute (tree *node, tree name,
static tree
ix86_handle_tm_regparm_attribute (tree *node, tree name ATTRIBUTE_UNUSED,
tree args ATTRIBUTE_UNUSED,
- int flags ATTRIBUTE_UNUSED,
- bool *no_add_attrs)
+ int flags, bool *no_add_attrs)
{
tree alt;
@@ -5651,6 +5788,14 @@ ix86_function_type_abi (const_tree fntype)
return ix86_abi;
}
+/* We add this as a workaround in order to use libc_has_function
+ hook in i386.md. */
+bool
+ix86_libc_has_function (enum function_class fn_class)
+{
+ return targetm.libc_has_function (fn_class);
+}
+
static bool
ix86_function_ms_hook_prologue (const_tree fn)
{
@@ -7078,8 +7223,7 @@ ix86_function_arg (cumulative_args_t cum_v, enum machine_mode omode,
appropriate for passing a pointer to that type. */
static bool
-ix86_pass_by_reference (cumulative_args_t cum_v ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
+ix86_pass_by_reference (cumulative_args_t cum_v, enum machine_mode mode,
const_tree type, bool named ATTRIBUTE_UNUSED)
{
CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
@@ -8562,6 +8706,10 @@ standard_sse_constant_opcode (rtx insn, rtx x)
}
case 2:
+ if (get_attr_mode (insn) == MODE_XI
+ || get_attr_mode (insn) == MODE_V8DF
+ || get_attr_mode (insn) == MODE_V16SF)
+ return "vpternlogd\t{$0xFF, %g0, %g0, %g0|%g0, %g0, %g0, 0xFF}";
if (TARGET_AVX)
return "vpcmpeqd\t%0, %0, %0";
else
@@ -8796,7 +8944,7 @@ ix86_code_end (void)
/* Emit code for the SET_GOT patterns. */
const char *
-output_set_got (rtx dest, rtx label ATTRIBUTE_UNUSED)
+output_set_got (rtx dest, rtx label)
{
rtx xops[3];
@@ -12900,6 +13048,14 @@ ix86_tls_get_addr (void)
ix86_tls_symbol = gen_rtx_SYMBOL_REF (Pmode, sym);
}
+ if (ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF)
+ {
+ rtx unspec = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, ix86_tls_symbol),
+ UNSPEC_PLTOFF);
+ return gen_rtx_PLUS (Pmode, pic_offset_table_rtx,
+ gen_rtx_CONST (Pmode, unspec));
+ }
+
return ix86_tls_symbol;
}
@@ -13807,21 +13963,29 @@ ix86_delegitimize_address (rtx x)
x = replace_equiv_address_nv (orig_x, x);
return x;
}
- if (GET_CODE (x) != CONST
- || GET_CODE (XEXP (x, 0)) != UNSPEC
- || (XINT (XEXP (x, 0), 1) != UNSPEC_GOTPCREL
- && XINT (XEXP (x, 0), 1) != UNSPEC_PCREL)
- || (!MEM_P (orig_x) && XINT (XEXP (x, 0), 1) != UNSPEC_PCREL))
- return ix86_delegitimize_tls_address (orig_x);
- x = XVECEXP (XEXP (x, 0), 0, 0);
- if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
+
+ if (GET_CODE (x) == CONST
+ && GET_CODE (XEXP (x, 0)) == UNSPEC
+ && (XINT (XEXP (x, 0), 1) == UNSPEC_GOTPCREL
+ || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL)
+ && (MEM_P (orig_x) || XINT (XEXP (x, 0), 1) == UNSPEC_PCREL))
{
- x = simplify_gen_subreg (GET_MODE (orig_x), x,
- GET_MODE (x), 0);
- if (x == NULL_RTX)
- return orig_x;
+ x = XVECEXP (XEXP (x, 0), 0, 0);
+ if (GET_MODE (orig_x) != GET_MODE (x) && MEM_P (orig_x))
+ {
+ x = simplify_gen_subreg (GET_MODE (orig_x), x,
+ GET_MODE (x), 0);
+ if (x == NULL_RTX)
+ return orig_x;
+ }
+ return x;
}
- return x;
+
+ if (ix86_cmodel != CM_MEDIUM_PIC && ix86_cmodel != CM_LARGE_PIC)
+ return ix86_delegitimize_tls_address (orig_x);
+
+ /* Fall thru into the code shared with -m32 for -mcmodel=large -fpic
+ and -mcmodel=medium -fpic. */
}
if (GET_CODE (x) != PLUS
@@ -13858,10 +14022,12 @@ ix86_delegitimize_address (rtx x)
if (GET_CODE (x) == UNSPEC
&& ((XINT (x, 1) == UNSPEC_GOT && MEM_P (orig_x) && !addend)
- || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))))
+ || (XINT (x, 1) == UNSPEC_GOTOFF && !MEM_P (orig_x))
+ || (XINT (x, 1) == UNSPEC_PLTOFF && ix86_cmodel == CM_LARGE_PIC
+ && !MEM_P (orig_x) && !addend)))
result = XVECEXP (x, 0, 0);
- if (TARGET_MACHO && darwin_local_data_pic (x)
+ if (!TARGET_64BIT && TARGET_MACHO && darwin_local_data_pic (x)
&& !MEM_P (orig_x))
result = XVECEXP (x, 0, 0);
@@ -14077,6 +14243,7 @@ put_condition_code (enum rtx_code code, enum machine_mode mode, bool reverse,
If CODE is 'q', pretend the mode is DImode.
If CODE is 'x', pretend the mode is V4SFmode.
If CODE is 't', pretend the mode is V8SFmode.
+ If CODE is 'g', pretend the mode is V16SFmode.
If CODE is 'h', pretend the reg is the 'high' byte register.
If CODE is 'y', print "st(0)" instead of "st", if the reg is stack op.
If CODE is 'd', duplicate the operand for AVX instruction.
@@ -14122,6 +14289,8 @@ print_reg (rtx x, int code, FILE *file)
code = 16;
else if (code == 't')
code = 32;
+ else if (code == 'g')
+ code = 64;
else
code = GET_MODE_SIZE (GET_MODE (x));
@@ -14195,6 +14364,14 @@ print_reg (rtx x, int code, FILE *file)
fputs (hi_reg_name[regno] + 1, file);
return;
}
+ case 64:
+ if (SSE_REG_P (x))
+ {
+ gcc_assert (!duplicated);
+ putc ('z', file);
+ fputs (hi_reg_name[REGNO (x)] + 1, file);
+ return;
+ }
break;
default:
gcc_unreachable ();
@@ -14268,6 +14445,7 @@ get_some_local_dynamic_name (void)
q -- likewise, print the DImode name of the register.
x -- likewise, print the V4SFmode name of the register.
t -- likewise, print the V8SFmode name of the register.
+ g -- likewise, print the V16SFmode name of the register.
h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
y -- print "st(0)" instead of "st" as a register.
d -- print duplicated register operand for AVX instruction.
@@ -14497,6 +14675,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
case 'q':
case 'h':
case 't':
+ case 'g':
case 'y':
case 'x':
case 'X':
@@ -14805,6 +14984,7 @@ ix86_print_operand (FILE *file, rtx x, int code)
size = "XMMWORD";
break;
case 32: size = "YMMWORD"; break;
+ case 64: size = "ZMMWORD"; break;
default:
gcc_unreachable ();
}
@@ -17882,7 +18062,7 @@ ix86_dep_by_shift_count (const_rtx set_insn, const_rtx use_insn)
bool
ix86_unary_operator_ok (enum rtx_code code ATTRIBUTE_UNUSED,
enum machine_mode mode ATTRIBUTE_UNUSED,
- rtx operands[2] ATTRIBUTE_UNUSED)
+ rtx operands[2])
{
/* If one of operands is memory, source and destination must match. */
if ((MEM_P (operands[0])
@@ -22903,6 +23083,7 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
{
case libcall:
case no_stringop:
+ case last_alg:
gcc_unreachable ();
case loop_1_byte:
need_zero_guard = true;
@@ -23093,6 +23274,7 @@ ix86_expand_movmem (rtx dst, rtx src, rtx count_exp, rtx align_exp,
{
case libcall:
case no_stringop:
+ case last_alg:
gcc_unreachable ();
case loop_1_byte:
case loop:
@@ -23304,6 +23486,7 @@ ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp,
{
case libcall:
case no_stringop:
+ case last_alg:
gcc_unreachable ();
case loop:
need_zero_guard = true;
@@ -23481,6 +23664,7 @@ ix86_expand_setmem (rtx dst, rtx count_exp, rtx val_exp, rtx align_exp,
{
case libcall:
case no_stringop:
+ case last_alg:
gcc_unreachable ();
case loop_1_byte:
case loop:
@@ -29546,8 +29730,8 @@ ix86_function_versions (tree fn1, tree fn2)
error_at (DECL_SOURCE_LOCATION (fn2),
"missing %<target%> attribute for multi-versioned %D",
fn2);
- error_at (DECL_SOURCE_LOCATION (fn1),
- "previous declaration of %D", fn1);
+ inform (DECL_SOURCE_LOCATION (fn1),
+ "previous declaration of %D", fn1);
/* Prevent diagnosing of the same error multiple times. */
DECL_ATTRIBUTES (fn2)
= tree_cons (get_identifier ("target"),
@@ -29830,7 +30014,7 @@ make_resolver_func (const tree default_decl,
DECL_IGNORED_P (decl) = 0;
/* IFUNC resolvers have to be externally visible. */
TREE_PUBLIC (decl) = 1;
- DECL_UNINLINABLE (decl) = 0;
+ DECL_UNINLINABLE (decl) = 1;
/* Resolver is not external, body is generated. */
DECL_EXTERNAL (decl) = 0;
@@ -31972,9 +32156,8 @@ ix86_expand_vec_set_builtin (tree exp)
IGNORE is nonzero if the value is to be ignored. */
static rtx
-ix86_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED,
- enum machine_mode mode ATTRIBUTE_UNUSED,
- int ignore ATTRIBUTE_UNUSED)
+ix86_expand_builtin (tree exp, rtx target, rtx subtarget,
+ enum machine_mode mode, int ignore)
{
const struct builtin_description *d;
size_t i;
@@ -33798,7 +33981,7 @@ ix86_preferred_output_reload_class (rtx x, reg_class_t regclass)
alternative: if reload cannot do this, it will still use its choice. */
mode = GET_MODE (x);
if (TARGET_SSE_MATH && SSE_FLOAT_MODE_P (mode))
- return MAYBE_SSE_CLASS_P (regclass) ? SSE_REGS : NO_REGS;
+ return MAYBE_SSE_CLASS_P (regclass) ? ALL_SSE_REGS : NO_REGS;
if (X87_FLOAT_MODE_P (mode))
{
@@ -33822,7 +34005,7 @@ ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
if (TARGET_64BIT
&& MEM_P (x)
&& GET_MODE_SIZE (mode) > UNITS_PER_WORD
- && rclass == GENERAL_REGS
+ && INTEGER_CLASS_P (rclass)
&& !offsettable_memref_p (x))
{
sri->icode = (in_p
@@ -33838,12 +34021,8 @@ ix86_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
intermediate register on 32bit targets. */
if (!TARGET_64BIT
&& !in_p && mode == QImode
- && (rclass == GENERAL_REGS
- || rclass == LEGACY_REGS
- || rclass == NON_Q_REGS
- || rclass == SIREG
- || rclass == DIREG
- || rclass == INDEX_REGS))
+ && INTEGER_CLASS_P (rclass)
+ && MAYBE_NON_Q_CLASS_P (rclass))
{
int regno;
@@ -34269,10 +34448,25 @@ ix86_hard_regno_mode_ok (int regno, enum machine_mode mode)
{
/* We implement the move patterns for all vector modes into and
out of SSE registers, even when no operation instructions
- are available. OImode move is available only when AVX is
- enabled. */
+ are available. */
+
+ /* For AVX-512 we allow, regardless of regno:
+ - XI mode
+ - any of 512-bit wide vector mode
+ - any scalar mode. */
+ if (TARGET_AVX512F
+ && (mode == XImode
+ || VALID_AVX512F_REG_MODE (mode)
+ || VALID_AVX512F_SCALAR_MODE (mode)))
+ return true;
+
+ /* xmm16-xmm31 are only available for AVX-512. */
+ if (EXT_REX_SSE_REGNO_P (regno))
+ return false;
+
+ /* OImode move is available only when AVX is enabled. */
return ((TARGET_AVX && mode == OImode)
- || VALID_AVX256_REG_MODE (mode)
+ || (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
|| VALID_SSE_REG_MODE (mode)
|| VALID_SSE2_REG_MODE (mode)
|| VALID_MMX_REG_MODE (mode)
@@ -34422,7 +34616,8 @@ ix86_set_reg_reg_cost (enum machine_mode mode)
case MODE_VECTOR_INT:
case MODE_VECTOR_FLOAT:
- if ((TARGET_AVX && VALID_AVX256_REG_MODE (mode))
+ if ((TARGET_AVX512F && VALID_AVX512F_REG_MODE (mode))
+ || (TARGET_AVX && VALID_AVX256_REG_MODE (mode))
|| (TARGET_SSE2 && VALID_SSE2_REG_MODE (mode))
|| (TARGET_SSE && VALID_SSE_REG_MODE (mode))
|| (TARGET_MMX && VALID_MMX_REG_MODE (mode)))
@@ -35054,6 +35249,10 @@ x86_order_regs_for_local_alloc (void)
for (i = FIRST_REX_SSE_REG; i <= LAST_REX_SSE_REG; i++)
reg_alloc_order [pos++] = i;
+ /* Extended REX SSE registers. */
+ for (i = FIRST_EXT_REX_SSE_REG; i <= LAST_EXT_REX_SSE_REG; i++)
+ reg_alloc_order [pos++] = i;
+
/* x87 registers. */
if (TARGET_SSE_MATH)
for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
@@ -36051,9 +36250,9 @@ x86_emit_floatuns (rtx operands[2])
emit_label (donelab);
}
-/* AVX2 does support 32-byte integer vector operations,
- thus the longest vector we are faced with is V32QImode. */
-#define MAX_VECT_LEN 32
+/* AVX512F does support 64-byte integer vector operations,
+ thus the longest vector we are faced with is V64QImode. */
+#define MAX_VECT_LEN 64
struct expand_vec_perm_d
{
@@ -42590,7 +42789,7 @@ ix86_spill_class (reg_class_t rclass, enum machine_mode mode)
if (TARGET_SSE && TARGET_GENERAL_REGS_SSE_SPILL && ! TARGET_MMX
&& (mode == SImode || (TARGET_64BIT && mode == DImode))
&& INTEGER_CLASS_P (rclass))
- return SSE_REGS;
+ return ALL_SSE_REGS;
return NO_REGS;
}
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 7d940f98804..e820aa65ac5 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -51,6 +51,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define TARGET_SSE4_2 TARGET_ISA_SSE4_2
#define TARGET_AVX TARGET_ISA_AVX
#define TARGET_AVX2 TARGET_ISA_AVX2
+#define TARGET_AVX512F TARGET_ISA_AVX512F
+#define TARGET_AVX512PF TARGET_ISA_AVX512PF
+#define TARGET_AVX512ER TARGET_ISA_AVX512ER
+#define TARGET_AVX512CD TARGET_ISA_AVX512CD
#define TARGET_FMA TARGET_ISA_FMA
#define TARGET_SSE4A TARGET_ISA_SSE4A
#define TARGET_FMA4 TARGET_ISA_FMA4
@@ -170,7 +174,7 @@ struct processor_costs {
const int fsqrt; /* cost of FSQRT instruction. */
/* Specify what algorithm
to use for stringops on unknown size. */
- struct stringop_algs memcpy[2], memset[2];
+ struct stringop_algs *memcpy, *memset;
const int scalar_stmt_cost; /* Cost of any scalar operation, excluding
load and store. */
const int scalar_load_cost; /* Cost of scalar load. */
@@ -261,81 +265,11 @@ extern const struct processor_costs ix86_size_cost;
/* Feature tests against the various tunings. */
enum ix86_tune_indices {
- X86_TUNE_USE_LEAVE,
- X86_TUNE_PUSH_MEMORY,
- X86_TUNE_ZERO_EXTEND_WITH_AND,
- X86_TUNE_UNROLL_STRLEN,
- X86_TUNE_BRANCH_PREDICTION_HINTS,
- X86_TUNE_DOUBLE_WITH_ADD,
- X86_TUNE_USE_SAHF,
- X86_TUNE_MOVX,
- X86_TUNE_PARTIAL_REG_STALL,
- X86_TUNE_PARTIAL_FLAG_REG_STALL,
- X86_TUNE_LCP_STALL,
- X86_TUNE_USE_HIMODE_FIOP,
- X86_TUNE_USE_SIMODE_FIOP,
- X86_TUNE_USE_MOV0,
- X86_TUNE_USE_CLTD,
- X86_TUNE_USE_XCHGB,
- X86_TUNE_SPLIT_LONG_MOVES,
- X86_TUNE_READ_MODIFY_WRITE,
- X86_TUNE_READ_MODIFY,
- X86_TUNE_PROMOTE_QIMODE,
- X86_TUNE_FAST_PREFIX,
- X86_TUNE_SINGLE_STRINGOP,
- X86_TUNE_QIMODE_MATH,
- X86_TUNE_HIMODE_MATH,
- X86_TUNE_PROMOTE_QI_REGS,
- X86_TUNE_PROMOTE_HI_REGS,
- X86_TUNE_SINGLE_POP,
- X86_TUNE_DOUBLE_POP,
- X86_TUNE_SINGLE_PUSH,
- X86_TUNE_DOUBLE_PUSH,
- X86_TUNE_INTEGER_DFMODE_MOVES,
- X86_TUNE_PARTIAL_REG_DEPENDENCY,
- X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY,
- X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL,
- X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL,
- X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL,
- X86_TUNE_SSE_SPLIT_REGS,
- X86_TUNE_SSE_TYPELESS_STORES,
- X86_TUNE_SSE_LOAD0_BY_PXOR,
- X86_TUNE_MEMORY_MISMATCH_STALL,
- X86_TUNE_PROLOGUE_USING_MOVE,
- X86_TUNE_EPILOGUE_USING_MOVE,
- X86_TUNE_SHIFT1,
- X86_TUNE_USE_FFREEP,
- X86_TUNE_INTER_UNIT_MOVES_TO_VEC,
- X86_TUNE_INTER_UNIT_MOVES_FROM_VEC,
- X86_TUNE_INTER_UNIT_CONVERSIONS,
- X86_TUNE_FOUR_JUMP_LIMIT,
- X86_TUNE_SCHEDULE,
- X86_TUNE_USE_BT,
- X86_TUNE_USE_INCDEC,
- X86_TUNE_PAD_RETURNS,
- X86_TUNE_PAD_SHORT_FUNCTION,
- X86_TUNE_EXT_80387_CONSTANTS,
- X86_TUNE_AVOID_VECTOR_DECODE,
- X86_TUNE_PROMOTE_HIMODE_IMUL,
- X86_TUNE_SLOW_IMUL_IMM32_MEM,
- X86_TUNE_SLOW_IMUL_IMM8,
- X86_TUNE_MOVE_M1_VIA_OR,
- X86_TUNE_NOT_UNPAIRABLE,
- X86_TUNE_NOT_VECTORMODE,
- X86_TUNE_USE_VECTOR_FP_CONVERTS,
- X86_TUNE_USE_VECTOR_CONVERTS,
- X86_TUNE_FUSE_CMP_AND_BRANCH,
- X86_TUNE_OPT_AGU,
- X86_TUNE_VECTORIZE_DOUBLE,
- X86_TUNE_SOFTWARE_PREFETCHING_BENEFICIAL,
- X86_TUNE_AVX128_OPTIMAL,
- X86_TUNE_REASSOC_INT_TO_PARALLEL,
- X86_TUNE_REASSOC_FP_TO_PARALLEL,
- X86_TUNE_GENERAL_REGS_SSE_SPILL,
- X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE,
- X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS,
-
- X86_TUNE_LAST
+#undef DEF_TUNE
+#define DEF_TUNE(tune, name, selector) tune,
+#include "x86-tune.def"
+#undef DEF_TUNE
+X86_TUNE_LAST
};
extern unsigned char ix86_tune_features[X86_TUNE_LAST];
@@ -802,7 +736,8 @@ enum target_cpu_default
Pentium+ prefers DFmode values to be aligned to 64 bit boundary
and Pentium Pro XFmode values at 128 bit boundaries. */
-#define BIGGEST_ALIGNMENT (TARGET_AVX ? 256 : 128)
+#define BIGGEST_ALIGNMENT \
+ (TARGET_AVX512F ? 512 : (TARGET_AVX ? 256 : 128))
/* Maximum stack alignment. */
#define MAX_STACK_ALIGNMENT MAX_OFILE_ALIGNMENT
@@ -958,7 +893,7 @@ enum target_cpu_default
eliminated during reloading in favor of either the stack or frame
pointer. */
-#define FIRST_PSEUDO_REGISTER 53
+#define FIRST_PSEUDO_REGISTER 69
/* Number of hardware registers that go into the DWARF-2 unwind info.
If not defined, equals FIRST_PSEUDO_REGISTER. */
@@ -984,6 +919,10 @@ enum target_cpu_default
/* r8, r9, r10, r11, r12, r13, r14, r15*/ \
0, 0, 0, 0, 0, 0, 0, 0, \
/*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+/*xmm16,xmm17,xmm18,xmm19,xmm20,xmm21,xmm22,xmm23*/ \
+ 0, 0, 0, 0, 0, 0, 0, 0, \
+/*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \
0, 0, 0, 0, 0, 0, 0, 0 }
/* 1 for registers not available across function calls.
@@ -1012,7 +951,11 @@ enum target_cpu_default
/* r8, r9, r10, r11, r12, r13, r14, r15*/ \
1, 1, 1, 1, 2, 2, 2, 2, \
/*xmm8,xmm9,xmm10,xmm11,xmm12,xmm13,xmm14,xmm15*/ \
- 6, 6, 6, 6, 6, 6, 6, 6 }
+ 6, 6, 6, 6, 6, 6, 6, 6, \
+/*xmm16,xmm17,xmm18,xmm19,xmm20,xmm21,xmm22,xmm23*/ \
+ 6, 6, 6, 6, 6, 6, 6, 6, \
+/*xmm24,xmm25,xmm26,xmm27,xmm28,xmm29,xmm30,xmm31*/ \
+ 6, 6, 6, 6, 6, 6, 6, 6 }
/* Order in which to allocate registers. Each register must be
listed once, even those in FIXED_REGISTERS. List frame pointer
@@ -1027,7 +970,8 @@ enum target_cpu_default
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,\
18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, \
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \
- 48, 49, 50, 51, 52 }
+ 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, \
+ 63, 64, 65, 66, 67, 68 }
/* ADJUST_REG_ALLOC_ORDER is a macro which permits reg_alloc_order
to be rearranged based on a particular function. When using sse math,
@@ -1073,6 +1017,14 @@ enum target_cpu_default
#define VALID_AVX256_REG_OR_OI_MODE(MODE) \
(VALID_AVX256_REG_MODE (MODE) || (MODE) == OImode)
+#define VALID_AVX512F_SCALAR_MODE(MODE) \
+ ((MODE) == DImode || (MODE) == DFmode || (MODE) == SImode \
+ || (MODE) == SFmode)
+
+#define VALID_AVX512F_REG_MODE(MODE) \
+ ((MODE) == V8DImode || (MODE) == V8DFmode || (MODE) == V64QImode \
+ || (MODE) == V16SImode || (MODE) == V16SFmode || (MODE) == V32HImode)
+
#define VALID_SSE2_REG_MODE(MODE) \
((MODE) == V16QImode || (MODE) == V8HImode || (MODE) == V2DFmode \
|| (MODE) == V2DImode || (MODE) == DFmode)
@@ -1112,7 +1064,9 @@ enum target_cpu_default
|| (MODE) == V2DImode || (MODE) == V4SFmode || (MODE) == V4SImode \
|| (MODE) == V32QImode || (MODE) == V16HImode || (MODE) == V8SImode \
|| (MODE) == V4DImode || (MODE) == V8SFmode || (MODE) == V4DFmode \
- || (MODE) == V2TImode)
+ || (MODE) == V2TImode || (MODE) == V8DImode || (MODE) == V64QImode \
+ || (MODE) == V16SImode || (MODE) == V32HImode || (MODE) == V8DFmode \
+ || (MODE) == V16SFmode)
/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */
@@ -1175,15 +1129,18 @@ enum target_cpu_default
#define FIRST_SSE_REG (FRAME_POINTER_REGNUM + 1)
#define LAST_SSE_REG (FIRST_SSE_REG + 7)
-#define FIRST_MMX_REG (LAST_SSE_REG + 1)
+#define FIRST_MMX_REG (LAST_SSE_REG + 1) /*29*/
#define LAST_MMX_REG (FIRST_MMX_REG + 7)
-#define FIRST_REX_INT_REG (LAST_MMX_REG + 1)
+#define FIRST_REX_INT_REG (LAST_MMX_REG + 1) /*37*/
#define LAST_REX_INT_REG (FIRST_REX_INT_REG + 7)
-#define FIRST_REX_SSE_REG (LAST_REX_INT_REG + 1)
+#define FIRST_REX_SSE_REG (LAST_REX_INT_REG + 1) /*45*/
#define LAST_REX_SSE_REG (FIRST_REX_SSE_REG + 7)
+#define FIRST_EXT_REX_SSE_REG (LAST_REX_SSE_REG + 1) /*53*/
+#define LAST_EXT_REX_SSE_REG (FIRST_EXT_REX_SSE_REG + 15) /*68*/
+
/* Override this in other tm.h files to cope with various OS lossage
requiring a frame pointer. */
#ifndef SUBTARGET_FRAME_POINTER_REQUIRED
@@ -1263,6 +1220,8 @@ enum reg_class
FLOAT_REGS,
SSE_FIRST_REG,
SSE_REGS,
+ EVEX_SSE_REGS,
+ ALL_SSE_REGS,
MMX_REGS,
FP_TOP_SSE_REGS,
FP_SECOND_SSE_REGS,
@@ -1280,7 +1239,7 @@ enum reg_class
#define FLOAT_CLASS_P(CLASS) \
reg_class_subset_p ((CLASS), FLOAT_REGS)
#define SSE_CLASS_P(CLASS) \
- reg_class_subset_p ((CLASS), SSE_REGS)
+ reg_class_subset_p ((CLASS), ALL_SSE_REGS)
#define MMX_CLASS_P(CLASS) \
((CLASS) == MMX_REGS)
#define MAYBE_INTEGER_CLASS_P(CLASS) \
@@ -1288,13 +1247,16 @@ enum reg_class
#define MAYBE_FLOAT_CLASS_P(CLASS) \
reg_classes_intersect_p ((CLASS), FLOAT_REGS)
#define MAYBE_SSE_CLASS_P(CLASS) \
- reg_classes_intersect_p (SSE_REGS, (CLASS))
+ reg_classes_intersect_p ((CLASS), ALL_SSE_REGS)
#define MAYBE_MMX_CLASS_P(CLASS) \
- reg_classes_intersect_p (MMX_REGS, (CLASS))
+ reg_classes_intersect_p ((CLASS), MMX_REGS)
#define Q_CLASS_P(CLASS) \
reg_class_subset_p ((CLASS), Q_REGS)
+#define MAYBE_NON_Q_CLASS_P(CLASS) \
+ reg_classes_intersect_p ((CLASS), NON_Q_REGS)
+
/* Give names of register classes as strings for dump file. */
#define REG_CLASS_NAMES \
@@ -1311,6 +1273,8 @@ enum reg_class
"FLOAT_REGS", \
"SSE_FIRST_REG", \
"SSE_REGS", \
+ "EVEX_SSE_REGS", \
+ "ALL_SSE_REGS", \
"MMX_REGS", \
"FP_TOP_SSE_REGS", \
"FP_SECOND_SSE_REGS", \
@@ -1326,30 +1290,36 @@ enum reg_class
Note that CLOBBERED_REGS are calculated by
TARGET_CONDITIONAL_REGISTER_USAGE. */
-#define REG_CLASS_CONTENTS \
-{ { 0x00, 0x0 }, \
- { 0x01, 0x0 }, { 0x02, 0x0 }, /* AREG, DREG */ \
- { 0x04, 0x0 }, { 0x08, 0x0 }, /* CREG, BREG */ \
- { 0x10, 0x0 }, { 0x20, 0x0 }, /* SIREG, DIREG */ \
- { 0x03, 0x0 }, /* AD_REGS */ \
- { 0x0f, 0x0 }, /* Q_REGS */ \
- { 0x1100f0, 0x1fe0 }, /* NON_Q_REGS */ \
- { 0x7f, 0x1fe0 }, /* INDEX_REGS */ \
- { 0x1100ff, 0x0 }, /* LEGACY_REGS */ \
- { 0x00, 0x0 }, /* CLOBBERED_REGS */ \
- { 0x1100ff, 0x1fe0 }, /* GENERAL_REGS */ \
- { 0x100, 0x0 }, { 0x0200, 0x0 },/* FP_TOP_REG, FP_SECOND_REG */\
- { 0xff00, 0x0 }, /* FLOAT_REGS */ \
- { 0x200000, 0x0 }, /* SSE_FIRST_REG */ \
-{ 0x1fe00000,0x1fe000 }, /* SSE_REGS */ \
-{ 0xe0000000, 0x1f }, /* MMX_REGS */ \
-{ 0x1fe00100,0x1fe000 }, /* FP_TOP_SSE_REG */ \
-{ 0x1fe00200,0x1fe000 }, /* FP_SECOND_SSE_REG */ \
-{ 0x1fe0ff00,0x1fe000 }, /* FLOAT_SSE_REGS */ \
- { 0x11ffff, 0x1fe0 }, /* FLOAT_INT_REGS */ \
-{ 0x1ff100ff,0x1fffe0 }, /* INT_SSE_REGS */ \
-{ 0x1ff1ffff,0x1fffe0 }, /* FLOAT_INT_SSE_REGS */ \
-{ 0xffffffff,0x1fffff } \
+#define REG_CLASS_CONTENTS \
+{ { 0x00, 0x0, 0x0 }, \
+ { 0x01, 0x0, 0x0 }, /* AREG */ \
+ { 0x02, 0x0, 0x0 }, /* DREG */ \
+ { 0x04, 0x0, 0x0 }, /* CREG */ \
+ { 0x08, 0x0, 0x0 }, /* BREG */ \
+ { 0x10, 0x0, 0x0 }, /* SIREG */ \
+ { 0x20, 0x0, 0x0 }, /* DIREG */ \
+ { 0x03, 0x0, 0x0 }, /* AD_REGS */ \
+ { 0x0f, 0x0, 0x0 }, /* Q_REGS */ \
+ { 0x1100f0, 0x1fe0, 0x0 }, /* NON_Q_REGS */ \
+ { 0x7f, 0x1fe0, 0x0 }, /* INDEX_REGS */ \
+ { 0x1100ff, 0x0, 0x0 }, /* LEGACY_REGS */ \
+ { 0x07, 0x0, 0x0 }, /* CLOBBERED_REGS */ \
+ { 0x1100ff, 0x1fe0, 0x0 }, /* GENERAL_REGS */ \
+ { 0x100, 0x0, 0x0 }, /* FP_TOP_REG */ \
+ { 0x0200, 0x0, 0x0 }, /* FP_SECOND_REG */ \
+ { 0xff00, 0x0, 0x0 }, /* FLOAT_REGS */ \
+ { 0x200000, 0x0, 0x0 }, /* SSE_FIRST_REG */ \
+{ 0x1fe00000, 0x1fe000, 0x0 }, /* SSE_REGS */ \
+ { 0x0,0xffe00000, 0x1f }, /* EVEX_SSE_REGS */ \
+{ 0x1fe00000,0xffffe000, 0x1f }, /* ALL_SSE_REGS */ \
+{ 0xe0000000, 0x1f, 0x0 }, /* MMX_REGS */ \
+{ 0x1fe00100,0xffffe000, 0x1f }, /* FP_TOP_SSE_REG */ \
+{ 0x1fe00200,0xffffe000, 0x1f }, /* FP_SECOND_SSE_REG */ \
+{ 0x1fe0ff00,0xffffe000, 0x1f }, /* FLOAT_SSE_REGS */ \
+{ 0x11ffff, 0x1fe0, 0x0 }, /* FLOAT_INT_REGS */ \
+{ 0x1ff100ff,0xffffffe0, 0x1f }, /* INT_SSE_REGS */ \
+{ 0x1ff1ffff,0xffffffe0, 0x1f }, /* FLOAT_INT_SSE_REGS */ \
+{ 0xffffffff,0xffffffff, 0x1f } \
}
/* The same information, inverted:
@@ -1393,13 +1363,20 @@ enum reg_class
#define SSE_REG_P(X) (REG_P (X) && SSE_REGNO_P (REGNO (X)))
#define SSE_REGNO_P(N) \
(IN_RANGE ((N), FIRST_SSE_REG, LAST_SSE_REG) \
- || REX_SSE_REGNO_P (N))
+ || REX_SSE_REGNO_P (N) \
+ || EXT_REX_SSE_REGNO_P (N))
#define REX_SSE_REGNO_P(N) \
IN_RANGE ((N), FIRST_REX_SSE_REG, LAST_REX_SSE_REG)
+#define EXT_REX_SSE_REGNO_P(N) \
+ IN_RANGE ((N), FIRST_EXT_REX_SSE_REG, LAST_EXT_REX_SSE_REG)
+
#define SSE_REGNO(N) \
- ((N) < 8 ? FIRST_SSE_REG + (N) : FIRST_REX_SSE_REG + (N) - 8)
+ ((N) < 8 ? FIRST_SSE_REG + (N) \
+ : (N) <= LAST_REX_SSE_REG ? (FIRST_REX_SSE_REG + (N) - 8) \
+ : (FIRST_EXT_REX_SSE_REG + (N) - 16))
+
#define SSE_FLOAT_MODE_P(MODE) \
((TARGET_SSE && (MODE) == SFmode) || (TARGET_SSE2 && (MODE) == DFmode))
@@ -1952,7 +1929,11 @@ do { \
"xmm0","xmm1","xmm2","xmm3","xmm4","xmm5","xmm6","xmm7", \
"mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", \
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", \
- "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15"}
+ "xmm8", "xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15", \
+ "xmm16", "xmm17", "xmm18", "xmm19", \
+ "xmm20", "xmm21", "xmm22", "xmm23", \
+ "xmm24", "xmm25", "xmm26", "xmm27", \
+ "xmm28", "xmm29", "xmm30", "xmm31" }
#define REGISTER_NAMES HI_REGISTER_NAMES
@@ -2273,9 +2254,13 @@ enum avx_u128_state
scheduling just increases amount of live registers at time and in
the turn amount of fxch instructions needed.
- ??? Maybe Pentium chips benefits from renaming, someone can try.... */
+ ??? Maybe Pentium chips benefits from renaming, someone can try....
+
+ Don't rename evex to non-evex sse registers. */
-#define HARD_REGNO_RENAME_OK(SRC, TARGET) !STACK_REGNO_P (SRC)
+#define HARD_REGNO_RENAME_OK(SRC, TARGET) (!STACK_REGNO_P (SRC) && \
+ (EXT_REX_SSE_REGNO_P (SRC) == \
+ EXT_REX_SSE_REGNO_P (TARGET)))
#define FASTCALL_PREFIX '@'
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index c67ed31923e..3307b081aaa 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -312,6 +312,22 @@
(XMM13_REG 50)
(XMM14_REG 51)
(XMM15_REG 52)
+ (XMM16_REG 53)
+ (XMM17_REG 54)
+ (XMM18_REG 55)
+ (XMM19_REG 56)
+ (XMM20_REG 57)
+ (XMM21_REG 58)
+ (XMM22_REG 59)
+ (XMM23_REG 60)
+ (XMM24_REG 61)
+ (XMM25_REG 62)
+ (XMM26_REG 63)
+ (XMM27_REG 64)
+ (XMM28_REG 65)
+ (XMM29_REG 66)
+ (XMM30_REG 67)
+ (XMM31_REG 68)
])
;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
@@ -350,7 +366,8 @@
;; Main data type used by the insn
(define_attr "mode"
- "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
+ "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
+ V2DF,V2SF,V1DF,V8DF"
(const_string "unknown"))
;; The CPU unit operations uses.
@@ -471,10 +488,13 @@
(const_int 0)))
;; Prefix used: original, VEX or maybe VEX.
-(define_attr "prefix" "orig,vex,maybe_vex"
- (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
- (const_string "vex")
- (const_string "orig")))
+(define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
+ (cond [(eq_attr "mode" "OI,V8SF,V4DF")
+ (const_string "vex")
+ (eq_attr "mode" "XI,V16SF,V8DF")
+ (const_string "evex")
+ ]
+ (const_string "orig")))
;; VEX W bit is used.
(define_attr "prefix_vex_w" "" (const_int 0))
@@ -493,6 +513,9 @@
(symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
(symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
+;; 4-bytes evex prefix and 1 byte opcode.
+(define_attr "length_evex" "" (const_int 5))
+
;; Set when modrm byte is used.
(define_attr "modrm" ""
(cond [(eq_attr "type" "str,leave")
@@ -544,8 +567,17 @@
(plus (const_int 2)
(plus (attr "prefix_data16")
(attr "length_address")))
+ (ior (eq_attr "prefix" "evex")
+ (and (ior (eq_attr "prefix" "maybe_evex")
+ (eq_attr "prefix" "maybe_vex"))
+ (match_test "TARGET_AVX512F")))
+ (plus (attr "length_evex")
+ (plus (attr "length_immediate")
+ (plus (attr "modrm")
+ (attr "length_address"))))
(ior (eq_attr "prefix" "vex")
- (and (eq_attr "prefix" "maybe_vex")
+ (and (ior (eq_attr "prefix" "maybe_vex")
+ (eq_attr "prefix" "maybe_evex"))
(match_test "TARGET_AVX")))
(plus (attr "length_vex")
(plus (attr "length_immediate")
@@ -663,7 +695,7 @@
;; Used to control the "enabled" attribute on a per-instruction basis.
(define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
- avx2,noavx2,bmi2,fma4,fma"
+ avx2,noavx2,bmi2,fma4,fma,avx512f,noavx512f,fma_avx512f"
(const_string "base"))
(define_attr "enabled" ""
@@ -689,6 +721,10 @@
(eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
(eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
(eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
+ (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
+ (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
+ (eq_attr "isa" "fma_avx512f")
+ (symbol_ref "TARGET_FMA || TARGET_AVX512F")
]
(const_int 1)))
@@ -924,10 +960,12 @@
;; SSE instruction suffix for various modes
(define_mode_attr ssemodesuffix
[(SF "ss") (DF "sd")
+ (V16SF "ps") (V8DF "pd")
(V8SF "ps") (V4DF "pd")
(V4SF "ps") (V2DF "pd")
(V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
- (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
+ (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
+ (V64QI "b") (V16SI "d") (V8DI "q")])
;; SSE vector suffix for floating point modes
(define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
@@ -1649,6 +1687,12 @@
;; Move instructions.
+(define_expand "movxi"
+ [(set (match_operand:XI 0 "nonimmediate_operand")
+ (match_operand:XI 1 "general_operand"))]
+ "TARGET_AVX512F"
+ "ix86_expand_move (XImode, operands); DONE;")
+
;; Reload patterns to support multi-word load/store
;; with non-offsetable address.
(define_expand "reload_noff_store"
@@ -1746,6 +1790,30 @@
(set_attr "mode" "<MODE>")
(set_attr "length_immediate" "1")])
+(define_insn "*movxi_internal_avx512f"
+ [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
+ (match_operand:XI 1 "vector_move_operand" "C ,xm,x"))]
+ "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
+{
+ switch (which_alternative)
+ {
+ case 0:
+ return standard_sse_constant_opcode (insn, operands[1]);
+ case 1:
+ case 2:
+ if (misaligned_operand (operands[0], XImode)
+ || misaligned_operand (operands[1], XImode))
+ return "vmovdqu32\t{%1, %0|%0, %1}";
+ else
+ return "vmovdqa32\t{%1, %0|%0, %1}";
+ default:
+ gcc_unreachable ();
+ }
+}
+ [(set_attr "type" "sselog1,ssemov,ssemov")
+ (set_attr "prefix" "evex")
+ (set_attr "mode" "XI")])
+
(define_insn "*movoi_internal_avx"
[(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
(match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
@@ -1857,9 +1925,9 @@
(define_insn "*movdi_internal"
[(set (match_operand:DI 0 "nonimmediate_operand"
- "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
+ "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
(match_operand:DI 1 "general_operand"
- "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*x,m ,*x,*Yj,*x,r ,*Yj ,*Yn"))]
+ "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*v,m ,*v,*Yj,*v,r ,*Yj ,*Yn"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (get_attr_type (insn))
@@ -1896,6 +1964,8 @@
return "%vmovq\t{%1, %0|%0, %1}";
case MODE_TI:
return "%vmovdqa\t{%1, %0|%0, %1}";
+ case MODE_XI:
+ return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
case MODE_V2SF:
gcc_assert (!TARGET_AVX);
@@ -1989,7 +2059,10 @@
(cond [(eq_attr "alternative" "2")
(const_string "SI")
(eq_attr "alternative" "12,13")
- (cond [(ior (not (match_test "TARGET_SSE2"))
+ (cond [(ior (match_operand 0 "ext_sse_reg_operand")
+ (match_operand 1 "ext_sse_reg_operand"))
+ (const_string "XI")
+ (ior (not (match_test "TARGET_SSE2"))
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "V4SF")
(match_test "TARGET_AVX")
@@ -2018,9 +2091,9 @@
(define_insn "*movsi_internal"
[(set (match_operand:SI 0 "nonimmediate_operand"
- "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?r,?*Yi")
+ "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi")
(match_operand:SI 1 "general_operand"
- "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,*x,r"))]
+ "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
switch (get_attr_type (insn))
@@ -2038,6 +2111,8 @@
return "%vmovd\t{%1, %0|%0, %1}";
case MODE_TI:
return "%vmovdqa\t{%1, %0|%0, %1}";
+ case MODE_XI:
+ return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
case MODE_V4SF:
return "%vmovaps\t{%1, %0|%0, %1}";
@@ -2116,7 +2191,10 @@
(cond [(eq_attr "alternative" "2,3")
(const_string "DI")
(eq_attr "alternative" "6,7")
- (cond [(ior (not (match_test "TARGET_SSE2"))
+ (cond [(ior (match_operand 0 "ext_sse_reg_operand")
+ (match_operand 1 "ext_sse_reg_operand"))
+ (const_string "XI")
+ (ior (not (match_test "TARGET_SSE2"))
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "V4SF")
(match_test "TARGET_AVX")
@@ -2255,7 +2333,7 @@
"TARGET_LP64 && ix86_check_movabs (insn, 0)"
"@
movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
- mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
+ mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
[(set_attr "type" "imov")
(set_attr "modrm" "0,*")
(set_attr "length_address" "8,0")
@@ -2269,7 +2347,7 @@
"TARGET_LP64 && ix86_check_movabs (insn, 1)"
"@
movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
- mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
+ mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
[(set_attr "type" "imov")
(set_attr "modrm" "0,*")
(set_attr "length_address" "8,0")
@@ -2703,9 +2781,9 @@
;; Possible store forwarding (partial memory) stall in alternative 4.
(define_insn "*movdf_internal"
[(set (match_operand:DF 0 "nonimmediate_operand"
- "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
+ "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
(match_operand:DF 1 "general_operand"
- "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yj,r"))]
+ "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (!can_create_pseudo_p ()
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
@@ -2750,6 +2828,8 @@
case MODE_V4SF:
return "%vmovaps\t{%1, %0|%0, %1}";
+ case MODE_V8DF:
+ return "vmovapd\t{%g1, %g0|%g0, %g1}";
case MODE_V2DF:
return "%vmovapd\t{%1, %0|%0, %1}";
@@ -2824,6 +2904,8 @@
(eq_attr "alternative" "9,13")
(cond [(not (match_test "TARGET_SSE2"))
(const_string "V4SF")
+ (match_test "TARGET_AVX512F")
+ (const_string "XI")
(match_test "TARGET_AVX")
(const_string "V2DF")
(match_test "optimize_function_for_size_p (cfun)")
@@ -2839,7 +2921,10 @@
/* movaps is one byte shorter for non-AVX targets. */
(eq_attr "alternative" "10,14")
- (cond [(ior (not (match_test "TARGET_SSE2"))
+ (cond [(ior (match_operand 0 "ext_sse_reg_operand")
+ (match_operand 1 "ext_sse_reg_operand"))
+ (const_string "V8DF")
+ (ior (not (match_test "TARGET_SSE2"))
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
(const_string "V4SF")
(match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
@@ -2872,9 +2957,9 @@
(define_insn "*movsf_internal"
[(set (match_operand:SF 0 "nonimmediate_operand"
- "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
+ "=Yf*f,m ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
(match_operand:SF 1 "general_operand"
- "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,Yj,r ,*y ,m ,*y,*Yn,r"))]
+ "Yf*fm,Yf*f,G ,rmF,rF,C,v,m,v,Yj,r ,*y ,m ,*y,*Yn,r"))]
"!(MEM_P (operands[0]) && MEM_P (operands[1]))
&& (!can_create_pseudo_p ()
|| (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
@@ -2907,6 +2992,8 @@
return "vmovss\t{%1, %0, %0|%0, %0, %1}";
return "%vmovss\t{%1, %0|%0, %1}";
+ case MODE_V16SF:
+ return "vmovaps\t{%g1, %g0|%g0, %g1}";
case MODE_V4SF:
return "%vmovaps\t{%1, %0|%0, %1}";
@@ -2960,6 +3047,8 @@
(eq_attr "alternative" "5")
(cond [(not (match_test "TARGET_SSE2"))
(const_string "V4SF")
+ (match_test "TARGET_AVX512F")
+ (const_string "V16SF")
(match_test "TARGET_AVX")
(const_string "V4SF")
(match_test "optimize_function_for_size_p (cfun)")
@@ -2979,10 +3068,15 @@
of instructions to load just part of the register. It is
better to maintain the whole registers in single format
to avoid problems on using packed logical operations. */
- (and (eq_attr "alternative" "6")
- (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
- (match_test "TARGET_SSE_SPLIT_REGS")))
- (const_string "V4SF")
+ (eq_attr "alternative" "6")
+ (cond [(ior (match_operand 0 "ext_sse_reg_operand")
+ (match_operand 1 "ext_sse_reg_operand"))
+ (const_string "V16SF")
+ (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
+ (match_test "TARGET_SSE_SPLIT_REGS"))
+ (const_string "V4SF")
+ ]
+ (const_string "SF"))
]
(const_string "SF")))])
@@ -4596,10 +4690,7 @@
(clobber (match_operand:SWI48 2 "memory_operand"))]
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
&& TARGET_INTER_UNIT_CONVERSIONS
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(set (match_dup 0) (float:MODEF (match_dup 1)))])
(define_split
@@ -4608,10 +4699,7 @@
(clobber (match_operand:SWI48 2 "memory_operand"))]
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
&& !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (float:MODEF (match_dup 2)))])
@@ -4697,10 +4785,7 @@
(clobber (match_operand:SI 2 "memory_operand"))]
"TARGET_SSE2 && TARGET_SSE_MATH
&& TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(const_int 0)]
{
rtx op1 = operands[1];
@@ -4740,10 +4825,7 @@
(clobber (match_operand:SI 2 "memory_operand"))]
"TARGET_SSE2 && TARGET_SSE_MATH
&& TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(const_int 0)]
{
operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
@@ -4764,10 +4846,7 @@
(float:MODEF (match_operand:SI 1 "register_operand")))]
"TARGET_SSE2 && TARGET_SSE_MATH
&& TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(const_int 0)]
{
rtx op1 = operands[1];
@@ -4810,10 +4889,7 @@
(float:MODEF (match_operand:SI 1 "memory_operand")))]
"TARGET_SSE2 && TARGET_SSE_MATH
&& TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(const_int 0)]
{
operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
@@ -4872,10 +4948,7 @@
(clobber (match_operand:SWI48 2 "memory_operand"))]
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
&& (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(set (match_dup 0) (float:MODEF (match_dup 1)))])
(define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
@@ -4905,10 +4978,7 @@
(clobber (match_operand:SWI48 2 "memory_operand"))]
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
&& !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(set (match_dup 2) (match_dup 1))
(set (match_dup 0) (float:MODEF (match_dup 2)))])
@@ -4917,10 +4987,7 @@
(float:MODEF (match_operand:SWI48 1 "memory_operand")))
(clobber (match_operand:SWI48 2 "memory_operand"))]
"SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
- && reload_completed
- && (SSE_REG_P (operands[0])
- || (GET_CODE (operands[0]) == SUBREG
- && SSE_REG_P (SUBREG_REG (operands[0]))))"
+ && reload_completed && SSE_REG_P (operands[0])"
[(set (match_dup 0) (float:MODEF (match_dup 1)))])
(define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
@@ -4968,6 +5035,46 @@
&& reload_completed"
[(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
+;; Avoid partial SSE register dependency stalls
+
+(define_split
+ [(set (match_operand:MODEF 0 "register_operand")
+ (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
+ "TARGET_SSE2 && TARGET_SSE_MATH
+ && TARGET_SSE_PARTIAL_REG_DEPENDENCY
+ && optimize_function_for_speed_p (cfun)
+ && reload_completed && SSE_REG_P (operands[0])"
+ [(set (match_dup 0)
+ (vec_merge:<ssevecmode>
+ (vec_duplicate:<ssevecmode>
+ (float:MODEF (match_dup 1)))
+ (match_dup 0)
+ (const_int 1)))]
+{
+ operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
+ <MODE>mode, 0);
+ emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
+})
+
+(define_split
+ [(set (match_operand:MODEF 0 "register_operand")
+ (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
+ "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
+ && TARGET_SSE_PARTIAL_REG_DEPENDENCY
+ && optimize_function_for_speed_p (cfun)
+ && reload_completed && SSE_REG_P (operands[0])"
+ [(set (match_dup 0)
+ (vec_merge:<ssevecmode>
+ (vec_duplicate:<ssevecmode>
+ (float:MODEF (match_dup 1)))
+ (match_dup 0)
+ (const_int 1)))]
+{
+ operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
+ <MODE>mode, 0);
+ emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
+})
+
;; Avoid store forwarding (partial memory) stall penalty
;; by passing DImode value through XMM registers. */
@@ -5024,6 +5131,18 @@
&& reload_completed"
[(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
+(define_expand "floatuns<SWI12:mode><MODEF:mode>2"
+ [(set (match_operand:MODEF 0 "register_operand")
+ (unsigned_float:MODEF
+ (match_operand:SWI12 1 "nonimmediate_operand")))]
+ "!TARGET_64BIT
+ && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
+{
+ operands[1] = convert_to_mode (SImode, operands[1], 1);
+ emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
+ DONE;
+})
+
;; Avoid store forwarding (partial memory) stall penalty by extending
;; SImode value to DImode through XMM register instead of pushing two
;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
@@ -12278,11 +12397,33 @@
(set (attr "length")
(symbol_ref "TARGET_X32 ? 15 : 16"))])
+(define_insn "*tls_global_dynamic_64_largepic"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (call:DI
+ (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
+ (match_operand:DI 3 "immediate_operand" "i")))
+ (match_operand 4)))
+ (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
+ UNSPEC_TLS_GD)]
+ "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
+ && GET_CODE (operands[3]) == CONST
+ && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
+ && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
+{
+ output_asm_insn
+ ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
+ output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
+ output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
+ return "call\t{*%%rax|rax}";
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "22")])
+
(define_expand "tls_global_dynamic_64_<mode>"
[(parallel
[(set (match_operand:P 0 "register_operand")
(call:P
- (mem:QI (match_operand 2 "constant_call_address_operand"))
+ (mem:QI (match_operand 2))
(const_int 0)))
(unspec:P [(match_operand 1 "tls_symbolic_operand")]
UNSPEC_TLS_GD)])]
@@ -12340,11 +12481,32 @@
[(set_attr "type" "multi")
(set_attr "length" "12")])
+(define_insn "*tls_local_dynamic_base_64_largepic"
+ [(set (match_operand:DI 0 "register_operand" "=a")
+ (call:DI
+ (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
+ (match_operand:DI 2 "immediate_operand" "i")))
+ (match_operand 3)))
+ (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
+ "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
+ && GET_CODE (operands[2]) == CONST
+ && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
+ && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
+{
+ output_asm_insn
+ ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
+ output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
+ output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
+ return "call\t{*%%rax|rax}";
+}
+ [(set_attr "type" "multi")
+ (set_attr "length" "22")])
+
(define_expand "tls_local_dynamic_base_64_<mode>"
[(parallel
[(set (match_operand:P 0 "register_operand")
(call:P
- (mem:QI (match_operand 1 "constant_call_address_operand"))
+ (mem:QI (match_operand 1))
(const_int 0)))
(unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
"TARGET_64BIT")
@@ -12629,10 +12791,10 @@
(set_attr "mode" "<MODE>")])
(define_insn "*fop_<mode>_comm_sse"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,v")
(match_operator:MODEF 3 "binary_fp_operator"
- [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
+ [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
+ (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
&& COMMUTATIVE_ARITH_P (operands[3])
&& !(MEM_P (operands[1]) && MEM_P (operands[2]))"
@@ -14884,7 +15046,7 @@
[(use (match_operand:SI 0 "register_operand"))
(use (match_operand:XF 1 "register_operand"))]
"TARGET_USE_FANCY_MATH_387
- && TARGET_C99_FUNCTIONS"
+ && ix86_libc_has_function (function_c99_misc)"
{
rtx mask = GEN_INT (0x45);
rtx val = GEN_INT (0x05);
@@ -14910,7 +15072,7 @@
[(use (match_operand:SI 0 "register_operand"))
(use (match_operand:MODEF 1 "nonimmediate_operand"))]
"TARGET_USE_FANCY_MATH_387
- && TARGET_C99_FUNCTIONS
+ && ix86_libc_has_function (function_c99_misc)
&& !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
{
rtx mask = GEN_INT (0x45);
@@ -15977,10 +16139,10 @@
;; are undefined in this condition, we're certain this is correct.
(define_insn "<code><mode>3"
- [(set (match_operand:MODEF 0 "register_operand" "=x,x")
+ [(set (match_operand:MODEF 0 "register_operand" "=x,v")
(smaxmin:MODEF
- (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
- (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
+ (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
"SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
"@
<maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
diff --git a/gcc/config/i386/i386.opt b/gcc/config/i386/i386.opt
index 9fbf5451e9c..5495c295f57 100644
--- a/gcc/config/i386/i386.opt
+++ b/gcc/config/i386/i386.opt
@@ -316,6 +316,14 @@ mstack-arg-probe
Target Report Mask(STACK_PROBE) Save
Enable stack probing
+mmemcpy-strategy=
+Target RejectNegative Joined Var(ix86_tune_memcpy_strategy)
+Specify memcpy expansion strategy when expected size is known
+
+mmemset-strategy=
+Target RejectNegative Joined Var(ix86_tune_memset_strategy)
+Specify memset expansion strategy when expected size is known
+
mstringop-strategy=
Target RejectNegative Joined Enum(stringop_alg) Var(ix86_stringop_alg) Init(no_stringop)
Chose strategy to generate stringop using
@@ -370,6 +378,17 @@ mtune=
Target RejectNegative Joined Var(ix86_tune_string)
Schedule code for given CPU
+mtune-ctrl=
+Target RejectNegative Joined Var(ix86_tune_ctrl_string)
+Fine grain control of tune features
+
+mno-default
+Target RejectNegative Var(ix86_tune_no_default) Init(0)
+Clear all tune features
+
+mdump-tune-features
+Target RejectNegative Var(ix86_dump_tunes) Init(0)
+
mabi=
Target RejectNegative Joined Var(ix86_abi) Enum(calling_abi) Init(SYSV_ABI)
Generate code that conforms to the given ABI
@@ -498,6 +517,22 @@ mavx2
Target Report Mask(ISA_AVX2) Var(ix86_isa_flags) Save
Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and AVX2 built-in functions and code generation
+mavx512f
+Target Report Mask(ISA_AVX512F) Var(ix86_isa_flags) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F built-in functions and code generation
+
+mavx512pf
+Target Report Mask(ISA_AVX512PF) Var(ix86_isa_flags) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512PF built-in functions and code generation
+
+mavx512er
+Target Report Mask(ISA_AVX512ER) Var(ix86_isa_flags) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512ER built-in functions and code generation
+
+mavx512cd
+Target Report Mask(ISA_AVX512CD) Var(ix86_isa_flags) Save
+Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 and AVX512F and AVX512CD built-in functions and code generation
+
mfma
Target Report Mask(ISA_FMA) Var(ix86_isa_flags) Save
Support MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX and FMA built-in functions and code generation
diff --git a/gcc/config/i386/linux-common.h b/gcc/config/i386/linux-common.h
index 1e8bf6b2dc0..52f0baf202e 100644
--- a/gcc/config/i386/linux-common.h
+++ b/gcc/config/i386/linux-common.h
@@ -40,7 +40,7 @@ along with GCC; see the file COPYING3. If not see
#undef LIB_SPEC
#define LIB_SPEC \
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \
- GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC)
+ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC " " ANDROID_LIB_SPEC)
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
diff --git a/gcc/config/i386/mmx.md b/gcc/config/i386/mmx.md
index 12c062687c0..17e24999258 100644
--- a/gcc/config/i386/mmx.md
+++ b/gcc/config/i386/mmx.md
@@ -78,9 +78,9 @@
(define_insn "*mov<mode>_internal"
[(set (match_operand:MMXMODE 0 "nonimmediate_operand"
- "=r ,o ,r,r ,m ,?!y,!y,?!y,m ,r ,?!Ym,x,x,x,m,*x,*x,*x,m ,r ,Yi,!Ym,*Yi")
+ "=r ,o ,r,r ,m ,?!y,!y,?!y,m ,r ,?!Ym,v,v,v,m,*x,*x,*x,m ,r ,Yi,!Ym,*Yi")
(match_operand:MMXMODE 1 "vector_move_operand"
- "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!Yn,r ,C,x,m,x,C ,*x,m ,*x,Yj,r ,*Yj,!Yn"))]
+ "rCo,rC,C,rm,rC,C ,!y,m ,?!y,?!Yn,r ,C,v,m,v,C ,*x,m ,*x,Yj,r ,*Yj,!Yn"))]
"TARGET_MMX
&& !(MEM_P (operands[0]) && MEM_P (operands[1]))"
{
@@ -128,6 +128,9 @@
case MODE_TI:
return "%vmovdqa\t{%1, %0|%0, %1}";
+ case MODE_XI:
+ return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
+
case MODE_V2SF:
if (TARGET_AVX && REG_P (operands[0]))
return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
@@ -182,7 +185,10 @@
(cond [(eq_attr "alternative" "2")
(const_string "SI")
(eq_attr "alternative" "11,12,15,16")
- (cond [(match_test "<MODE>mode == V2SFmode")
+ (cond [(ior (match_operand 0 "ext_sse_reg_operand")
+ (match_operand 1 "ext_sse_reg_operand"))
+ (const_string "XI")
+ (match_test "<MODE>mode == V2SFmode")
(const_string "V4SF")
(ior (not (match_test "TARGET_SSE2"))
(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
diff --git a/gcc/config/i386/predicates.md b/gcc/config/i386/predicates.md
index b64ef6999ee..3959c3892e4 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -47,6 +47,12 @@
(and (match_code "reg")
(match_test "SSE_REGNO_P (REGNO (op))")))
+;; True if the operand is an AVX-512 new register.
+(define_predicate "ext_sse_reg_operand"
+ (and (match_code "reg")
+ (match_test "EXT_REX_SSE_REGNO_P (REGNO (op))")))
+
+
;; True if the operand is a Q_REGS class register.
(define_predicate "q_regs_operand"
(match_operand 0 "register_operand")
diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md
index 439749877f2..9d9469e2c62 100644
--- a/gcc/config/i386/sse.md
+++ b/gcc/config/i386/sse.md
@@ -96,7 +96,7 @@
])
;; All vector modes including V?TImode, used in move patterns.
-(define_mode_iterator V16
+(define_mode_iterator VMOVE
[(V32QI "TARGET_AVX") V16QI
(V16HI "TARGET_AVX") V8HI
(V8SI "TARGET_AVX") V4SI
@@ -244,6 +244,13 @@
(V4SI "vec") (V8SI "avx2")
(V2DI "vec") (V4DI "avx2")])
+(define_mode_attr shuffletype
+ [(V16SF "f") (V16SI "i") (V8DF "f") (V8DI "i")
+ (V8SF "f") (V8SI "i") (V4DF "f") (V4DI "i")
+ (V4SF "f") (V4SI "i") (V2DF "f") (V2DI "i")
+ (V32QI "i") (V16HI "u") (V16QI "i") (V8HI "i")
+ (V64QI "i") (V1TI "i") (V2TI "i")])
+
(define_mode_attr ssedoublemode
[(V16HI "V16SI") (V8HI "V8SI") (V4HI "V4SI")
(V32QI "V32HI") (V16QI "V16HI")])
@@ -301,8 +308,10 @@
;; SSE instruction mode
(define_mode_attr sseinsnmode
- [(V32QI "OI") (V16HI "OI") (V8SI "OI") (V4DI "OI") (V2TI "OI")
+ [(V64QI "XI") (V32HI "XI") (V16SI "XI") (V8DI "XI")
+ (V32QI "OI") (V16HI "OI") (V8SI "OI") (V4DI "OI") (V2TI "OI")
(V16QI "TI") (V8HI "TI") (V4SI "TI") (V2DI "TI") (V1TI "TI")
+ (V16SF "V16SF") (V8DF "V8DF")
(V8SF "V8SF") (V4DF "V4DF")
(V4SF "V4SF") (V2DF "V2DF")
(TI "TI")])
@@ -435,8 +444,8 @@
;; This is essential for maintaining stable calling conventions.
(define_expand "mov<mode>"
- [(set (match_operand:V16 0 "nonimmediate_operand")
- (match_operand:V16 1 "nonimmediate_operand"))]
+ [(set (match_operand:VMOVE 0 "nonimmediate_operand")
+ (match_operand:VMOVE 1 "nonimmediate_operand"))]
"TARGET_SSE"
{
ix86_expand_vector_move (<MODE>mode, operands);
@@ -444,20 +453,64 @@
})
(define_insn "*mov<mode>_internal"
- [(set (match_operand:V16 0 "nonimmediate_operand" "=x,x ,m")
- (match_operand:V16 1 "nonimmediate_or_sse_const_operand" "C ,xm,x"))]
+ [(set (match_operand:VMOVE 0 "nonimmediate_operand" "=v,v ,m")
+ (match_operand:VMOVE 1 "nonimmediate_or_sse_const_operand" "C ,vm,v"))]
"TARGET_SSE
&& (register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode))"
{
+ int mode = get_attr_mode (insn);
switch (which_alternative)
{
case 0:
return standard_sse_constant_opcode (insn, operands[1]);
case 1:
case 2:
- switch (get_attr_mode (insn))
+ /* There is no evex-encoded vmov* for sizes smaller than 64-bytes
+ in avx512f, so we need to use workarounds, to access sse registers
+ 16-31, which are evex-only. */
+ if (TARGET_AVX512F && GET_MODE_SIZE (<MODE>mode) < 64
+ && (EXT_REX_SSE_REGNO_P (REGNO (operands[0]))
+ || EXT_REX_SSE_REGNO_P (REGNO (operands[1]))))
{
+ if (memory_operand (operands[0], <MODE>mode))
+ {
+ if (GET_MODE_SIZE (<MODE>mode) == 32)
+ return "vextract<shuffletype>64x4\t{$0x0, %g1, %0|%0, %g1, 0x0}";
+ else if (GET_MODE_SIZE (<MODE>mode) == 16)
+ return "vextract<shuffletype>32x4\t{$0x0, %g1, %0|%0, %g1, 0x0}";
+ else
+ gcc_unreachable ();
+ }
+ else if (memory_operand (operands[1], <MODE>mode))
+ {
+ if (GET_MODE_SIZE (<MODE>mode) == 32)
+ return "vbroadcast<shuffletype>64x4\t{%1, %g0|%g0, %1}";
+ else if (GET_MODE_SIZE (<MODE>mode) == 16)
+ return "vbroadcast<shuffletype>32x4\t{%1, %g0|%g0, %1}";
+ else
+ gcc_unreachable ();
+ }
+ else
+ /* Reg -> reg move is always aligned. Just use wider move. */
+ switch (mode)
+ {
+ case MODE_V8SF:
+ case MODE_V4SF:
+ return "vmovaps\t{%g1, %g0|%g0, %g1}";
+ case MODE_V4DF:
+ case MODE_V2DF:
+ return "vmovapd\t{%g1, %g0|%g0, %g1}";
+ case MODE_OI:
+ case MODE_TI:
+ return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
+ default:
+ gcc_unreachable ();
+ }
+ }
+ switch (mode)
+ {
+ case MODE_V16SF:
case MODE_V8SF:
case MODE_V4SF:
if (TARGET_AVX
@@ -467,6 +520,7 @@
else
return "%vmovaps\t{%1, %0|%0, %1}";
+ case MODE_V8DF:
case MODE_V4DF:
case MODE_V2DF:
if (TARGET_AVX
@@ -484,6 +538,12 @@
return "vmovdqu\t{%1, %0|%0, %1}";
else
return "%vmovdqa\t{%1, %0|%0, %1}";
+ case MODE_XI:
+ if (misaligned_operand (operands[0], <MODE>mode)
+ || misaligned_operand (operands[1], <MODE>mode))
+ return "vmovdqu64\t{%1, %0|%0, %1}";
+ else
+ return "vmovdqa64\t{%1, %0|%0, %1}";
default:
gcc_unreachable ();
@@ -586,7 +646,7 @@
})
(define_expand "push<mode>1"
- [(match_operand:V16 0 "register_operand")]
+ [(match_operand:VMOVE 0 "register_operand")]
"TARGET_SSE"
{
ix86_expand_push (<MODE>mode, operands[0]);
@@ -594,8 +654,8 @@
})
(define_expand "movmisalign<mode>"
- [(set (match_operand:V16 0 "nonimmediate_operand")
- (match_operand:V16 1 "nonimmediate_operand"))]
+ [(set (match_operand:VMOVE 0 "nonimmediate_operand")
+ (match_operand:VMOVE 1 "nonimmediate_operand"))]
"TARGET_SSE"
{
ix86_expand_vector_move_misalign (<MODE>mode, operands);
@@ -603,7 +663,7 @@
})
(define_insn "<sse>_loadu<ssemodesuffix><avxsizesuffix>"
- [(set (match_operand:VF 0 "register_operand" "=x")
+ [(set (match_operand:VF 0 "register_operand" "=v")
(unspec:VF
[(match_operand:VF 1 "memory_operand" "m")]
UNSPEC_LOADU))]
@@ -662,7 +722,7 @@
(const_string "<MODE>")))])
(define_insn "<sse2>_loaddqu<avxsizesuffix>"
- [(set (match_operand:VI1 0 "register_operand" "=x")
+ [(set (match_operand:VI1 0 "register_operand" "=v")
(unspec:VI1 [(match_operand:VI1 1 "memory_operand" "m")]
UNSPEC_LOADU))]
"TARGET_SSE2"
@@ -696,7 +756,7 @@
(define_insn "<sse2>_storedqu<avxsizesuffix>"
[(set (match_operand:VI1 0 "memory_operand" "=m")
- (unspec:VI1 [(match_operand:VI1 1 "register_operand" "x")]
+ (unspec:VI1 [(match_operand:VI1 1 "register_operand" "v")]
UNSPEC_STOREU))]
"TARGET_SSE2"
{
@@ -863,10 +923,10 @@
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
(define_insn "*<plusminus_insn><mode>3"
- [(set (match_operand:VF 0 "register_operand" "=x,x")
+ [(set (match_operand:VF 0 "register_operand" "=x,v")
(plusminus:VF
- (match_operand:VF 1 "nonimmediate_operand" "<comm>0,x")
- (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VF 1 "nonimmediate_operand" "<comm>0,v")
+ (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
"@
<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
@@ -877,11 +937,11 @@
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_vm<plusminus_insn><mode>3"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=x,v")
(vec_merge:VF_128
(plusminus:VF_128
- (match_operand:VF_128 1 "register_operand" "0,x")
- (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
+ (match_operand:VF_128 1 "register_operand" "0,v")
+ (match_operand:VF_128 2 "nonimmediate_operand" "xm,vm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
@@ -917,11 +977,11 @@
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_vmmul<mode>3"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=x,v")
(vec_merge:VF_128
(mult:VF_128
- (match_operand:VF_128 1 "register_operand" "0,x")
- (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
+ (match_operand:VF_128 1 "register_operand" "0,v")
+ (match_operand:VF_128 2 "nonimmediate_operand" "xm,vm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
@@ -960,10 +1020,10 @@
})
(define_insn "<sse>_div<mode>3"
- [(set (match_operand:VF 0 "register_operand" "=x,x")
+ [(set (match_operand:VF 0 "register_operand" "=x,v")
(div:VF
- (match_operand:VF 1 "register_operand" "0,x")
- (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VF 1 "register_operand" "0,v")
+ (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE"
"@
div<ssemodesuffix>\t{%2, %0|%0, %2}
@@ -974,11 +1034,11 @@
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_vmdiv<mode>3"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=x,v")
(vec_merge:VF_128
(div:VF_128
- (match_operand:VF_128 1 "register_operand" "0,x")
- (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
+ (match_operand:VF_128 1 "register_operand" "0,v")
+ (match_operand:VF_128 2 "nonimmediate_operand" "xm,vm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
@@ -1043,8 +1103,8 @@
})
(define_insn "<sse>_sqrt<mode>2"
- [(set (match_operand:VF 0 "register_operand" "=x")
- (sqrt:VF (match_operand:VF 1 "nonimmediate_operand" "xm")))]
+ [(set (match_operand:VF 0 "register_operand" "=v")
+ (sqrt:VF (match_operand:VF 1 "nonimmediate_operand" "vm")))]
"TARGET_SSE"
"%vsqrt<ssemodesuffix>\t{%1, %0|%0, %1}"
[(set_attr "type" "sse")
@@ -1054,11 +1114,11 @@
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_vmsqrt<mode>2"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=x,v")
(vec_merge:VF_128
(sqrt:VF_128
- (match_operand:VF_128 1 "nonimmediate_operand" "xm,xm"))
- (match_operand:VF_128 2 "register_operand" "0,x")
+ (match_operand:VF_128 1 "nonimmediate_operand" "xm,vm"))
+ (match_operand:VF_128 2 "register_operand" "0,v")
(const_int 1)))]
"TARGET_SSE"
"@
@@ -1124,10 +1184,10 @@
})
(define_insn "*<code><mode>3_finite"
- [(set (match_operand:VF 0 "register_operand" "=x,x")
+ [(set (match_operand:VF 0 "register_operand" "=x,v")
(smaxmin:VF
- (match_operand:VF 1 "nonimmediate_operand" "%0,x")
- (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VF 1 "nonimmediate_operand" "%0,v")
+ (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE && flag_finite_math_only
&& ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
"@
@@ -1140,10 +1200,10 @@
(set_attr "mode" "<MODE>")])
(define_insn "*<code><mode>3"
- [(set (match_operand:VF 0 "register_operand" "=x,x")
+ [(set (match_operand:VF 0 "register_operand" "=x,v")
(smaxmin:VF
- (match_operand:VF 1 "register_operand" "0,x")
- (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VF 1 "register_operand" "0,v")
+ (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE && !flag_finite_math_only"
"@
<maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
@@ -1155,11 +1215,11 @@
(set_attr "mode" "<MODE>")])
(define_insn "<sse>_vm<code><mode>3"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=x,v")
(vec_merge:VF_128
(smaxmin:VF_128
- (match_operand:VF_128 1 "register_operand" "0,x")
- (match_operand:VF_128 2 "nonimmediate_operand" "xm,xm"))
+ (match_operand:VF_128 1 "register_operand" "0,v")
+ (match_operand:VF_128 2 "nonimmediate_operand" "xm,vm"))
(match_dup 1)
(const_int 1)))]
"TARGET_SSE"
@@ -1790,10 +1850,10 @@
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
(define_insn "*<code><mode>3"
- [(set (match_operand:VF 0 "register_operand" "=x,x")
+ [(set (match_operand:VF 0 "register_operand" "=x,v")
(any_logic:VF
- (match_operand:VF 1 "nonimmediate_operand" "%0,x")
- (match_operand:VF 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VF 1 "nonimmediate_operand" "%0,v")
+ (match_operand:VF 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
{
static char buf[32];
@@ -2101,11 +2161,11 @@
"TARGET_FMA || TARGET_FMA4")
(define_insn "*fma_fmadd_<mode>"
- [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x,x,x")
+ [(set (match_operand:FMAMODE 0 "register_operand" "=v,v,v,x,x")
(fma:FMAMODE
- (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x, x,x")
- (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm,x,m")
- (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0,xm,x")))]
+ (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0, v, x,x")
+ (match_operand:FMAMODE 2 "nonimmediate_operand" "vm, v,vm, x,m")
+ (match_operand:FMAMODE 3 "nonimmediate_operand" " v,vm, 0,xm,x")))]
"TARGET_FMA || TARGET_FMA4"
"@
vfmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
@@ -2113,17 +2173,17 @@
vfmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
vfmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
- [(set_attr "isa" "fma,fma,fma,fma4,fma4")
+ [(set_attr "isa" "fma_avx512f,fma_avx512f,fma_avx512f,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
(define_insn "*fma_fmsub_<mode>"
- [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x,x,x")
+ [(set (match_operand:FMAMODE 0 "register_operand" "=v,v,v,x,x")
(fma:FMAMODE
- (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x, x,x")
- (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm,x,m")
+ (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0, v, x,x")
+ (match_operand:FMAMODE 2 "nonimmediate_operand" "vm, v,vm, x,m")
(neg:FMAMODE
- (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0,xm,x"))))]
+ (match_operand:FMAMODE 3 "nonimmediate_operand" " v,vm, 0,xm,x"))))]
"TARGET_FMA || TARGET_FMA4"
"@
vfmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
@@ -2131,17 +2191,17 @@
vfmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
vfmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
- [(set_attr "isa" "fma,fma,fma,fma4,fma4")
+ [(set_attr "isa" "fma_avx512f,fma_avx512f,fma_avx512f,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
(define_insn "*fma_fnmadd_<mode>"
- [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x,x,x")
+ [(set (match_operand:FMAMODE 0 "register_operand" "=v,v,v,x,x")
(fma:FMAMODE
(neg:FMAMODE
- (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x, x,x"))
- (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm,x,m")
- (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0,xm,x")))]
+ (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0, v, x,x"))
+ (match_operand:FMAMODE 2 "nonimmediate_operand" "vm, v,vm, x,m")
+ (match_operand:FMAMODE 3 "nonimmediate_operand" " v,vm, 0,xm,x")))]
"TARGET_FMA || TARGET_FMA4"
"@
vfnmadd132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
@@ -2149,18 +2209,18 @@
vfnmadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
vfnmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfnmadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
- [(set_attr "isa" "fma,fma,fma,fma4,fma4")
+ [(set_attr "isa" "fma_avx512f,fma_avx512f,fma_avx512f,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
(define_insn "*fma_fnmsub_<mode>"
- [(set (match_operand:FMAMODE 0 "register_operand" "=x,x,x,x,x")
+ [(set (match_operand:FMAMODE 0 "register_operand" "=v,v,v,x,x")
(fma:FMAMODE
(neg:FMAMODE
- (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0,x, x,x"))
- (match_operand:FMAMODE 2 "nonimmediate_operand" "xm, x,xm,x,m")
+ (match_operand:FMAMODE 1 "nonimmediate_operand" "%0, 0, v, x,x"))
+ (match_operand:FMAMODE 2 "nonimmediate_operand" "vm, v,vm, x,m")
(neg:FMAMODE
- (match_operand:FMAMODE 3 "nonimmediate_operand" " x,xm,0,xm,x"))))]
+ (match_operand:FMAMODE 3 "nonimmediate_operand" " v,vm, 0,xm,x"))))]
"TARGET_FMA || TARGET_FMA4"
"@
vfnmsub132<ssemodesuffix>\t{%2, %3, %0|%0, %3, %2}
@@ -2168,7 +2228,7 @@
vfnmsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
vfnmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfnmsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
- [(set_attr "isa" "fma,fma,fma,fma4,fma4")
+ [(set_attr "isa" "fma_avx512f,fma_avx512f,fma_avx512f,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -2193,11 +2253,11 @@
"TARGET_FMA || TARGET_FMA4")
(define_insn "*fma_fmaddsub_<mode>"
- [(set (match_operand:VF 0 "register_operand" "=x,x,x,x,x")
+ [(set (match_operand:VF 0 "register_operand" "=v,v,v,x,x")
(unspec:VF
- [(match_operand:VF 1 "nonimmediate_operand" "%0, 0,x, x,x")
- (match_operand:VF 2 "nonimmediate_operand" "xm, x,xm,x,m")
- (match_operand:VF 3 "nonimmediate_operand" " x,xm,0,xm,x")]
+ [(match_operand:VF 1 "nonimmediate_operand" "%0, 0, v, x,x")
+ (match_operand:VF 2 "nonimmediate_operand" "vm, v,vm, x,m")
+ (match_operand:VF 3 "nonimmediate_operand" " v,vm, 0,xm,x")]
UNSPEC_FMADDSUB))]
"TARGET_FMA || TARGET_FMA4"
"@
@@ -2206,17 +2266,17 @@
vfmaddsub231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
vfmaddsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfmaddsub<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
- [(set_attr "isa" "fma,fma,fma,fma4,fma4")
+ [(set_attr "isa" "fma_avx512f,fma_avx512f,fma_avx512f,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
(define_insn "*fma_fmsubadd_<mode>"
- [(set (match_operand:VF 0 "register_operand" "=x,x,x,x,x")
+ [(set (match_operand:VF 0 "register_operand" "=v,v,v,x,x")
(unspec:VF
- [(match_operand:VF 1 "nonimmediate_operand" "%0, 0,x, x,x")
- (match_operand:VF 2 "nonimmediate_operand" "xm, x,xm,x,m")
+ [(match_operand:VF 1 "nonimmediate_operand" "%0, 0, v, x,x")
+ (match_operand:VF 2 "nonimmediate_operand" "vm, v,vm, x,m")
(neg:VF
- (match_operand:VF 3 "nonimmediate_operand" " x,xm,0,xm,x"))]
+ (match_operand:VF 3 "nonimmediate_operand" " v,vm, 0,xm,x"))]
UNSPEC_FMADDSUB))]
"TARGET_FMA || TARGET_FMA4"
"@
@@ -2225,7 +2285,7 @@
vfmsubadd231<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}
vfmsubadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}
vfmsubadd<ssemodesuffix>\t{%3, %2, %1, %0|%0, %1, %2, %3}"
- [(set_attr "isa" "fma,fma,fma,fma4,fma4")
+ [(set_attr "isa" "fma_avx512f,fma_avx512f,fma_avx512f,fma4,fma4")
(set_attr "type" "ssemuladd")
(set_attr "mode" "<MODE>")])
@@ -2244,12 +2304,12 @@
"TARGET_FMA")
(define_insn "*fmai_fmadd_<mode>"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=v,v")
(vec_merge:VF_128
(fma:VF_128
(match_operand:VF_128 1 "nonimmediate_operand" " 0, 0")
- (match_operand:VF_128 2 "nonimmediate_operand" "xm, x")
- (match_operand:VF_128 3 "nonimmediate_operand" " x,xm"))
+ (match_operand:VF_128 2 "nonimmediate_operand" "vm, v")
+ (match_operand:VF_128 3 "nonimmediate_operand" " v,vm"))
(match_dup 1)
(const_int 1)))]
"TARGET_FMA"
@@ -2260,13 +2320,13 @@
(set_attr "mode" "<MODE>")])
(define_insn "*fmai_fmsub_<mode>"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=v,v")
(vec_merge:VF_128
(fma:VF_128
(match_operand:VF_128 1 "nonimmediate_operand" " 0, 0")
- (match_operand:VF_128 2 "nonimmediate_operand" "xm, x")
+ (match_operand:VF_128 2 "nonimmediate_operand" "vm, v")
(neg:VF_128
- (match_operand:VF_128 3 "nonimmediate_operand" " x,xm")))
+ (match_operand:VF_128 3 "nonimmediate_operand" " v,vm")))
(match_dup 1)
(const_int 1)))]
"TARGET_FMA"
@@ -2277,13 +2337,13 @@
(set_attr "mode" "<MODE>")])
(define_insn "*fmai_fnmadd_<mode>"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=v,v")
(vec_merge:VF_128
(fma:VF_128
(neg:VF_128
- (match_operand:VF_128 2 "nonimmediate_operand" "xm, x"))
+ (match_operand:VF_128 2 "nonimmediate_operand" "vm, v"))
(match_operand:VF_128 1 "nonimmediate_operand" " 0, 0")
- (match_operand:VF_128 3 "nonimmediate_operand" " x,xm"))
+ (match_operand:VF_128 3 "nonimmediate_operand" " v,vm"))
(match_dup 1)
(const_int 1)))]
"TARGET_FMA"
@@ -2294,14 +2354,14 @@
(set_attr "mode" "<MODE>")])
(define_insn "*fmai_fnmsub_<mode>"
- [(set (match_operand:VF_128 0 "register_operand" "=x,x")
+ [(set (match_operand:VF_128 0 "register_operand" "=v,v")
(vec_merge:VF_128
(fma:VF_128
(neg:VF_128
- (match_operand:VF_128 2 "nonimmediate_operand" "xm, x"))
+ (match_operand:VF_128 2 "nonimmediate_operand" "vm, v"))
(match_operand:VF_128 1 "nonimmediate_operand" " 0, 0")
(neg:VF_128
- (match_operand:VF_128 3 "nonimmediate_operand" " x,xm")))
+ (match_operand:VF_128 3 "nonimmediate_operand" " v,vm")))
(match_dup 1)
(const_int 1)))]
"TARGET_FMA"
@@ -2429,11 +2489,11 @@
(set_attr "mode" "SF")])
(define_insn "sse_cvtsi2ss"
- [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,x,v")
(vec_merge:V4SF
(vec_duplicate:V4SF
(float:SF (match_operand:SI 2 "nonimmediate_operand" "r,m,rm")))
- (match_operand:V4SF 1 "register_operand" "0,0,x")
+ (match_operand:V4SF 1 "register_operand" "0,0,v")
(const_int 1)))]
"TARGET_SSE"
"@
@@ -2450,11 +2510,11 @@
(set_attr "mode" "SF")])
(define_insn "sse_cvtsi2ssq"
- [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,x,v")
(vec_merge:V4SF
(vec_duplicate:V4SF
(float:SF (match_operand:DI 2 "nonimmediate_operand" "r,m,rm")))
- (match_operand:V4SF 1 "register_operand" "0,0,x")
+ (match_operand:V4SF 1 "register_operand" "0,0,v")
(const_int 1)))]
"TARGET_SSE && TARGET_64BIT"
"@
@@ -2476,7 +2536,7 @@
[(set (match_operand:SI 0 "register_operand" "=r,r")
(unspec:SI
[(vec_select:SF
- (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
+ (match_operand:V4SF 1 "nonimmediate_operand" "v,m")
(parallel [(const_int 0)]))]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE"
@@ -2490,7 +2550,7 @@
(define_insn "sse_cvtss2si_2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "x,m")]
+ (unspec:SI [(match_operand:SF 1 "nonimmediate_operand" "v,m")]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE"
"%vcvtss2si\t{%1, %0|%0, %k1}"
@@ -2506,7 +2566,7 @@
[(set (match_operand:DI 0 "register_operand" "=r,r")
(unspec:DI
[(vec_select:SF
- (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
+ (match_operand:V4SF 1 "nonimmediate_operand" "v,m")
(parallel [(const_int 0)]))]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE && TARGET_64BIT"
@@ -2536,7 +2596,7 @@
[(set (match_operand:SI 0 "register_operand" "=r,r")
(fix:SI
(vec_select:SF
- (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
+ (match_operand:V4SF 1 "nonimmediate_operand" "v,m")
(parallel [(const_int 0)]))))]
"TARGET_SSE"
"%vcvttss2si\t{%1, %0|%0, %k1}"
@@ -2552,7 +2612,7 @@
[(set (match_operand:DI 0 "register_operand" "=r,r")
(fix:DI
(vec_select:SF
- (match_operand:V4SF 1 "nonimmediate_operand" "x,m")
+ (match_operand:V4SF 1 "nonimmediate_operand" "v,m")
(parallel [(const_int 0)]))))]
"TARGET_SSE && TARGET_64BIT"
"%vcvttss2si{q}\t{%1, %0|%0, %k1}"
@@ -2565,9 +2625,9 @@
(set_attr "mode" "DI")])
(define_insn "float<sseintvecmodelower><mode>2"
- [(set (match_operand:VF1 0 "register_operand" "=x")
+ [(set (match_operand:VF1 0 "register_operand" "=v")
(float:VF1
- (match_operand:<sseintvecmode> 1 "nonimmediate_operand" "xm")))]
+ (match_operand:<sseintvecmode> 1 "nonimmediate_operand" "vm")))]
"TARGET_SSE2"
"%vcvtdq2ps\t{%1, %0|%0, %1}"
[(set_attr "type" "ssecvt")
@@ -2752,7 +2812,7 @@
(define_insn "sse2_cvtsd2si_2"
[(set (match_operand:SI 0 "register_operand" "=r,r")
- (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
+ (unspec:SI [(match_operand:DF 1 "nonimmediate_operand" "v,m")]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE2"
"%vcvtsd2si\t{%1, %0|%0, %q1}"
@@ -2782,7 +2842,7 @@
(define_insn "sse2_cvtsd2siq_2"
[(set (match_operand:DI 0 "register_operand" "=r,r")
- (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "x,m")]
+ (unspec:DI [(match_operand:DF 1 "nonimmediate_operand" "v,m")]
UNSPEC_FIX_NOTRUNC))]
"TARGET_SSE2 && TARGET_64BIT"
"%vcvtsd2si{q}\t{%1, %0|%0, %q1}"
@@ -2981,12 +3041,12 @@
(set_attr "mode" "TI")])
(define_insn "sse2_cvtsd2ss"
- [(set (match_operand:V4SF 0 "register_operand" "=x,x,x")
+ [(set (match_operand:V4SF 0 "register_operand" "=x,x,v")
(vec_merge:V4SF
(vec_duplicate:V4SF
(float_truncate:V2SF
- (match_operand:V2DF 2 "nonimmediate_operand" "x,m,xm")))
- (match_operand:V4SF 1 "register_operand" "0,0,x")
+ (match_operand:V2DF 2 "nonimmediate_operand" "x,m,vm")))
+ (match_operand:V4SF 1 "register_operand" "0,0,v")
(const_int 1)))]
"TARGET_SSE2"
"@
@@ -3003,13 +3063,13 @@
(set_attr "mode" "SF")])
(define_insn "sse2_cvtss2sd"
- [(set (match_operand:V2DF 0 "register_operand" "=x,x,x")
+ [(set (match_operand:V2DF 0 "register_operand" "=x,x,v")
(vec_merge:V2DF
(float_extend:V2DF
(vec_select:V2SF
- (match_operand:V4SF 2 "nonimmediate_operand" "x,m,xm")
+ (match_operand:V4SF 2 "nonimmediate_operand" "x,m,vm")
(parallel [(const_int 0) (const_int 1)])))
- (match_operand:V2DF 1 "register_operand" "0,0,x")
+ (match_operand:V2DF 1 "register_operand" "0,0,v")
(const_int 1)))]
"TARGET_SSE2"
"@
@@ -5243,10 +5303,10 @@
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
(define_insn "*<plusminus_insn><mode>3"
- [(set (match_operand:VI_AVX2 0 "register_operand" "=x,x")
+ [(set (match_operand:VI_AVX2 0 "register_operand" "=x,v")
(plusminus:VI_AVX2
- (match_operand:VI_AVX2 1 "nonimmediate_operand" "<comm>0,x")
- (match_operand:VI_AVX2 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VI_AVX2 1 "nonimmediate_operand" "<comm>0,v")
+ (match_operand:VI_AVX2 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
"@
p<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
@@ -5266,10 +5326,10 @@
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
(define_insn "*<sse2_avx2>_<plusminus_insn><mode>3"
- [(set (match_operand:VI12_AVX2 0 "register_operand" "=x,x")
+ [(set (match_operand:VI12_AVX2 0 "register_operand" "=x,v")
(sat_plusminus:VI12_AVX2
- (match_operand:VI12_AVX2 1 "nonimmediate_operand" "<comm>0,x")
- (match_operand:VI12_AVX2 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VI12_AVX2 1 "nonimmediate_operand" "<comm>0,v")
+ (match_operand:VI12_AVX2 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
"@
p<plusminus_mnemonic><ssemodesuffix>\t{%2, %0|%0, %2}
@@ -5641,10 +5701,10 @@
})
(define_insn "*<sse4_1_avx2>_mul<mode>3"
- [(set (match_operand:VI4_AVX2 0 "register_operand" "=x,x")
+ [(set (match_operand:VI4_AVX2 0 "register_operand" "=x,v")
(mult:VI4_AVX2
- (match_operand:VI4_AVX2 1 "nonimmediate_operand" "%0,x")
- (match_operand:VI4_AVX2 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VI4_AVX2 1 "nonimmediate_operand" "%0,v")
+ (match_operand:VI4_AVX2 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE4_1 && ix86_binary_operator_ok (MULT, <MODE>mode, operands)"
"@
pmulld\t{%2, %0|%0, %2}
@@ -5765,9 +5825,9 @@
(set_attr "mode" "<sseinsnmode>")])
(define_insn "<shift_insn><mode>3"
- [(set (match_operand:VI248_AVX2 0 "register_operand" "=x,x")
+ [(set (match_operand:VI248_AVX2 0 "register_operand" "=x,v")
(any_lshift:VI248_AVX2
- (match_operand:VI248_AVX2 1 "register_operand" "0,x")
+ (match_operand:VI248_AVX2 1 "register_operand" "0,v")
(match_operand:SI 2 "nonmemory_operand" "xN,xN")))]
"TARGET_SSE2"
"@
@@ -5868,10 +5928,10 @@
"ix86_fixup_binary_operands_no_copy (<CODE>, <MODE>mode, operands);")
(define_insn "*avx2_<code><mode>3"
- [(set (match_operand:VI124_256 0 "register_operand" "=x")
+ [(set (match_operand:VI124_256 0 "register_operand" "=v")
(maxmin:VI124_256
- (match_operand:VI124_256 1 "nonimmediate_operand" "%x")
- (match_operand:VI124_256 2 "nonimmediate_operand" "xm")))]
+ (match_operand:VI124_256 1 "nonimmediate_operand" "%v")
+ (match_operand:VI124_256 2 "nonimmediate_operand" "vm")))]
"TARGET_AVX2 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
"vp<maxmin_int><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseiadd")
@@ -6345,10 +6405,10 @@
"TARGET_SSE2")
(define_insn "*andnot<mode>3"
- [(set (match_operand:VI 0 "register_operand" "=x,x")
+ [(set (match_operand:VI 0 "register_operand" "=x,v")
(and:VI
- (not:VI (match_operand:VI 1 "register_operand" "0,x"))
- (match_operand:VI 2 "nonimmediate_operand" "xm,xm")))]
+ (not:VI (match_operand:VI 1 "register_operand" "0,v"))
+ (match_operand:VI 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE"
{
static char buf[32];
@@ -6429,10 +6489,10 @@
})
(define_insn "*<code><mode>3"
- [(set (match_operand:VI 0 "register_operand" "=x,x")
+ [(set (match_operand:VI 0 "register_operand" "=x,v")
(any_logic:VI
- (match_operand:VI 1 "nonimmediate_operand" "%0,x")
- (match_operand:VI 2 "nonimmediate_operand" "xm,xm")))]
+ (match_operand:VI 1 "nonimmediate_operand" "%0,v")
+ (match_operand:VI 2 "nonimmediate_operand" "xm,vm")))]
"TARGET_SSE
&& ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
{
@@ -7731,9 +7791,17 @@
(mem:V16QI (match_dup 0))]
UNSPEC_MASKMOV))]
"TARGET_SSE2"
- "%vmaskmovdqu\t{%2, %1|%1, %2}"
+{
+ /* We can't use %^ here due to ASM_OUTPUT_OPCODE processing
+ that requires %v to be at the beginning of the opcode name. */
+ if (Pmode != word_mode)
+ fputs ("\taddr32", asm_out_file);
+ return "%vmaskmovdqu\t{%2, %1|%1, %2}";
+}
[(set_attr "type" "ssemov")
(set_attr "prefix_data16" "1")
+ (set (attr "length_address")
+ (symbol_ref ("Pmode != word_mode")))
;; The implicit %rdi operand confuses default length_vex computation.
(set (attr "length_vex")
(symbol_ref ("3 + REX_SSE_REGNO_P (REGNO (operands[2]))")))
@@ -7781,26 +7849,18 @@
"mwait"
[(set_attr "length" "3")])
-(define_insn "sse3_monitor"
- [(unspec_volatile [(match_operand:SI 0 "register_operand" "a")
- (match_operand:SI 1 "register_operand" "c")
- (match_operand:SI 2 "register_operand" "d")]
- UNSPECV_MONITOR)]
- "TARGET_SSE3 && !TARGET_64BIT"
- "monitor\t%0, %1, %2"
- [(set_attr "length" "3")])
-
-(define_insn "sse3_monitor64_<mode>"
+(define_insn "sse3_monitor_<mode>"
[(unspec_volatile [(match_operand:P 0 "register_operand" "a")
(match_operand:SI 1 "register_operand" "c")
(match_operand:SI 2 "register_operand" "d")]
UNSPECV_MONITOR)]
- "TARGET_SSE3 && TARGET_64BIT"
+ "TARGET_SSE3"
;; 64bit version is "monitor %rax,%rcx,%rdx". But only lower 32bits in
;; RCX and RDX are used. Since 32bit register operands are implicitly
;; zero extended to 64bit, we only need to set up 32bit registers.
- "monitor"
- [(set_attr "length" "3")])
+ "%^monitor"
+ [(set (attr "length")
+ (symbol_ref ("(Pmode != word_mode) + 3")))])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
@@ -8368,9 +8428,9 @@
(set_attr "mode" "DI")])
(define_insn "abs<mode>2"
- [(set (match_operand:VI124_AVX2 0 "register_operand" "=x")
+ [(set (match_operand:VI124_AVX2 0 "register_operand" "=v")
(abs:VI124_AVX2
- (match_operand:VI124_AVX2 1 "nonimmediate_operand" "xm")))]
+ (match_operand:VI124_AVX2 1 "nonimmediate_operand" "vm")))]
"TARGET_SSSE3"
"%vpabs<ssemodesuffix>\t{%1, %0|%0, %1}"
[(set_attr "type" "sselog1")
@@ -10481,10 +10541,10 @@
(set_attr "mode" "<sseinsnmode>")])
(define_insn "avx2_permvar<mode>"
- [(set (match_operand:VI4F_256 0 "register_operand" "=x")
+ [(set (match_operand:VI4F_256 0 "register_operand" "=v")
(unspec:VI4F_256
- [(match_operand:VI4F_256 1 "nonimmediate_operand" "xm")
- (match_operand:V8SI 2 "register_operand" "x")]
+ [(match_operand:VI4F_256 1 "nonimmediate_operand" "vm")
+ (match_operand:V8SI 2 "register_operand" "v")]
UNSPEC_VPERMVAR))]
"TARGET_AVX2"
"vperm<ssemodesuffix>\t{%1, %2, %0|%0, %2, %1}"
@@ -10508,9 +10568,9 @@
})
(define_insn "avx2_perm<mode>_1"
- [(set (match_operand:VI8F_256 0 "register_operand" "=x")
+ [(set (match_operand:VI8F_256 0 "register_operand" "=v")
(vec_select:VI8F_256
- (match_operand:VI8F_256 1 "nonimmediate_operand" "xm")
+ (match_operand:VI8F_256 1 "nonimmediate_operand" "vm")
(parallel [(match_operand 2 "const_0_to_3_operand")
(match_operand 3 "const_0_to_3_operand")
(match_operand 4 "const_0_to_3_operand")
@@ -10735,9 +10795,9 @@
})
(define_insn "*avx_vpermilp<mode>"
- [(set (match_operand:VF 0 "register_operand" "=x")
+ [(set (match_operand:VF 0 "register_operand" "=v")
(vec_select:VF
- (match_operand:VF 1 "nonimmediate_operand" "xm")
+ (match_operand:VF 1 "nonimmediate_operand" "vm")
(match_parallel 2 ""
[(match_operand 3 "const_int_operand")])))]
"TARGET_AVX
@@ -10754,10 +10814,10 @@
(set_attr "mode" "<MODE>")])
(define_insn "avx_vpermilvar<mode>3"
- [(set (match_operand:VF 0 "register_operand" "=x")
+ [(set (match_operand:VF 0 "register_operand" "=v")
(unspec:VF
- [(match_operand:VF 1 "register_operand" "x")
- (match_operand:<sseintvecmode> 2 "nonimmediate_operand" "xm")]
+ [(match_operand:VF 1 "register_operand" "v")
+ (match_operand:<sseintvecmode> 2 "nonimmediate_operand" "vm")]
UNSPEC_VPERMIL))]
"TARGET_AVX"
"vpermil<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
@@ -11149,10 +11209,10 @@
})
(define_insn "avx2_ashrv<mode>"
- [(set (match_operand:VI4_AVX2 0 "register_operand" "=x")
+ [(set (match_operand:VI4_AVX2 0 "register_operand" "=v")
(ashiftrt:VI4_AVX2
- (match_operand:VI4_AVX2 1 "register_operand" "x")
- (match_operand:VI4_AVX2 2 "nonimmediate_operand" "xm")))]
+ (match_operand:VI4_AVX2 1 "register_operand" "v")
+ (match_operand:VI4_AVX2 2 "nonimmediate_operand" "vm")))]
"TARGET_AVX2"
"vpsravd\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
@@ -11160,10 +11220,10 @@
(set_attr "mode" "<sseinsnmode>")])
(define_insn "avx2_<shift_insn>v<mode>"
- [(set (match_operand:VI48_AVX2 0 "register_operand" "=x")
+ [(set (match_operand:VI48_AVX2 0 "register_operand" "=v")
(any_lshift:VI48_AVX2
- (match_operand:VI48_AVX2 1 "register_operand" "x")
- (match_operand:VI48_AVX2 2 "nonimmediate_operand" "xm")))]
+ (match_operand:VI48_AVX2 1 "register_operand" "v")
+ (match_operand:VI48_AVX2 2 "nonimmediate_operand" "vm")))]
"TARGET_AVX2"
"vp<vshift>v<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
[(set_attr "type" "sseishft")
diff --git a/gcc/config/i386/stringop.def b/gcc/config/i386/stringop.def
new file mode 100644
index 00000000000..1a7d1e88f65
--- /dev/null
+++ b/gcc/config/i386/stringop.def
@@ -0,0 +1,37 @@
+/* Definitions for stringop strategy for IA-32.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the files COPYING3. If not,
+see <http://www.gnu.org/licenses/>. */
+
+DEF_ENUM
+DEF_ALG (no_stringop, no_stringop)
+DEF_ENUM
+DEF_ALG (libcall, libcall)
+DEF_ENUM
+DEF_ALG (rep_prefix_1_byte, rep_byte)
+DEF_ENUM
+DEF_ALG (rep_prefix_4_byte, rep_4byte)
+DEF_ENUM
+DEF_ALG (rep_prefix_8_byte, rep_8byte)
+DEF_ENUM
+DEF_ALG (loop_1_byte, byte_loop)
+DEF_ENUM
+DEF_ALG (loop, loop)
+DEF_ENUM
+DEF_ALG (unrolled_loop, unrolled_loop)
+DEF_ENUM
+DEF_ALG (vector_loop, vector_loop)
diff --git a/gcc/config/i386/stringop.opt b/gcc/config/i386/stringop.opt
new file mode 100644
index 00000000000..5c5fc906a33
--- /dev/null
+++ b/gcc/config/i386/stringop.opt
@@ -0,0 +1,31 @@
+/* Definitions for stringop option handling for IA-32.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the files COPYING3. If not,
+see <http://www.gnu.org/licenses/>. */
+
+Enum(stringop_alg) String(rep_byte) Value(rep_prefix_1_byte)
+
+#undef DEF_ENUM
+#define DEF_ENUM EnumValue
+
+#undef DEF_ALG
+#define DEF_ALG(alg, name) Enum(stringop_alg) String(name) Value(alg)
+
+#include "stringop.def"
+
+#undef DEF_ENUM
+#undef DEF_ALG
diff --git a/gcc/config/i386/t-i386 b/gcc/config/i386/t-i386
index 3a77e14f5ca..07624cc575e 100644
--- a/gcc/config/i386/t-i386
+++ b/gcc/config/i386/t-i386
@@ -24,7 +24,7 @@ i386.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(TM_H) \
$(GGC_H) $(TARGET_H) $(TARGET_DEF_H) langhooks.h $(CGRAPH_H) \
$(TREE_GIMPLE_H) $(DWARF2_H) $(DF_H) tm-constrs.h $(PARAMS_H) \
i386-builtin-types.inc debug.h dwarf2out.h sbitmap.h $(FIBHEAP_H) \
- $(OPTS_H) $(DIAGNOSTIC_H) $(COMMON_TARGET_H)
+ $(OPTS_H) $(DIAGNOSTIC_H) $(COMMON_TARGET_H) $(CONTEXT_H) $(PASS_MANAGER_H)
i386-c.o: $(srcdir)/config/i386/i386-c.c \
$(srcdir)/config/i386/i386-protos.h $(CONFIG_H) $(SYSTEM_H) coretypes.h \
diff --git a/gcc/config/i386/x86-64.h b/gcc/config/i386/x86-64.h
index 336343927c8..0c62723ae22 100644
--- a/gcc/config/i386/x86-64.h
+++ b/gcc/config/i386/x86-64.h
@@ -103,3 +103,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#undef TARGET_ASM_UNIQUE_SECTION
#define TARGET_ASM_UNIQUE_SECTION x86_64_elf_unique_section
+
+#undef TARGET_SECTION_TYPE_FLAGS
+#define TARGET_SECTION_TYPE_FLAGS x86_64_elf_section_type_flags
diff --git a/gcc/config/i386/x86-tune.def b/gcc/config/i386/x86-tune.def
new file mode 100644
index 00000000000..e3a34ee7b2e
--- /dev/null
+++ b/gcc/config/i386/x86-tune.def
@@ -0,0 +1,232 @@
+/* Definitions of x86 tunable features.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License 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/>. */
+
+/* X86_TUNE_USE_LEAVE: Leave does not affect Nocona SPEC2000 results
+ negatively, so enabling for Generic64 seems like good code size
+ tradeoff. We can't enable it for 32bit generic because it does not
+ work well with PPro base chips. */
+DEF_TUNE (X86_TUNE_USE_LEAVE, "use_leave",
+ m_386 | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC64)
+DEF_TUNE (X86_TUNE_PUSH_MEMORY, "push_memory",
+ m_386 | m_P4_NOCONA | m_CORE_ALL | m_K6_GEODE | m_AMD_MULTIPLE
+ | m_GENERIC)
+DEF_TUNE (X86_TUNE_ZERO_EXTEND_WITH_AND, "zero_extend_with_and", m_486 | m_PENT)
+DEF_TUNE (X86_TUNE_UNROLL_STRLEN, "unroll_strlen",
+ m_486 | m_PENT | m_PPRO | m_ATOM | m_SLM | m_CORE_ALL | m_K6
+ | m_AMD_MULTIPLE | m_GENERIC)
+/* X86_TUNE_BRANCH_PREDICTION_HINTS: Branch hints were put in P4 based
+ on simulation result. But after P4 was made, no performance benefit
+ was observed with branch hints. It also increases the code size.
+ As a result, icc never generates branch hints. */
+DEF_TUNE (X86_TUNE_BRANCH_PREDICTION_HINTS, "branch_prediction_hints", 0)
+DEF_TUNE (X86_TUNE_DOUBLE_WITH_ADD, "double_with_add", ~m_386)
+DEF_TUNE (X86_TUNE_USE_SAHF, "use_sahf",
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE
+ | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC)
+/* X86_TUNE_MOVX: Enable to zero extend integer registers to avoid
+ partial dependencies. */
+DEF_TUNE (X86_TUNE_MOVX, "movx",
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GEODE
+ | m_AMD_MULTIPLE | m_GENERIC)
+/* X86_TUNE_PARTIAL_REG_STALL: We probably ought to watch for partial
+ register stalls on Generic32 compilation setting as well. However
+ in current implementation the partial register stalls are not eliminated
+ very well - they can be introduced via subregs synthesized by combine
+ and can happen in caller/callee saving sequences. Because this option
+ pays back little on PPro based chips and is in conflict with partial reg
+ dependencies used by Athlon/P4 based chips, it is better to leave it off
+ for generic32 for now. */
+DEF_TUNE (X86_TUNE_PARTIAL_REG_STALL, "partial_reg_stall", m_PPRO)
+DEF_TUNE (X86_TUNE_PARTIAL_FLAG_REG_STALL, "partial_flag_reg_stall",
+ m_CORE_ALL | m_GENERIC)
+/* X86_TUNE_LCP_STALL: Avoid an expensive length-changing prefix stall
+ * on 16-bit immediate moves into memory on Core2 and Corei7. */
+DEF_TUNE (X86_TUNE_LCP_STALL, "lcp_stall", m_CORE_ALL | m_GENERIC)
+DEF_TUNE (X86_TUNE_USE_HIMODE_FIOP, "use_himode_fiop",
+ m_386 | m_486 | m_K6_GEODE)
+DEF_TUNE (X86_TUNE_USE_SIMODE_FIOP, "use_simode_fiop",
+ ~(m_PENT | m_PPRO | m_CORE_ALL | m_ATOM
+ | m_SLM | m_AMD_MULTIPLE | m_GENERIC))
+DEF_TUNE (X86_TUNE_USE_MOV0, "use_mov0", m_K6)
+DEF_TUNE (X86_TUNE_USE_CLTD, "use_cltd", ~(m_PENT | m_ATOM | m_SLM | m_K6))
+/* X86_TUNE_USE_XCHGB: Use xchgb %rh,%rl instead of rolw/rorw $8,rx. */
+DEF_TUNE (X86_TUNE_USE_XCHGB, "use_xchgb", m_PENT4)
+DEF_TUNE (X86_TUNE_SPLIT_LONG_MOVES, "split_long_moves", m_PPRO)
+DEF_TUNE (X86_TUNE_READ_MODIFY_WRITE, "read_modify_write", ~m_PENT)
+DEF_TUNE (X86_TUNE_READ_MODIFY, "read_modify", ~(m_PENT | m_PPRO))
+DEF_TUNE (X86_TUNE_PROMOTE_QIMODE, "promote_qimode",
+ m_386 | m_486 | m_PENT | m_CORE_ALL | m_ATOM | m_SLM
+ | m_K6_GEODE | m_AMD_MULTIPLE | m_GENERIC)
+DEF_TUNE (X86_TUNE_FAST_PREFIX, "fast_prefix", ~(m_386 | m_486 | m_PENT))
+DEF_TUNE (X86_TUNE_SINGLE_STRINGOP, "single_stringop", m_386 | m_P4_NOCONA)
+DEF_TUNE (X86_TUNE_QIMODE_MATH, "qimode_math", ~0)
+/* X86_TUNE_HIMODE_MATH: On PPro this flag is meant to avoid partial
+ register stalls. Just like X86_TUNE_PARTIAL_REG_STALL this option
+ might be considered for Generic32 if our scheme for avoiding partial
+ stalls was more effective. */
+DEF_TUNE (X86_TUNE_HIMODE_MATH, "himode_math", ~m_PPRO)
+DEF_TUNE (X86_TUNE_PROMOTE_QI_REGS, "promote_qi_regs", 0)
+DEF_TUNE (X86_TUNE_PROMOTE_HI_REGS, "promote_hi_regs", m_PPRO)
+/* X86_TUNE_SINGLE_POP: Enable if single pop insn is preferred
+ over esp addition. */
+DEF_TUNE (X86_TUNE_SINGLE_POP, "single_pop", m_386 | m_486 | m_PENT | m_PPRO)
+/* X86_TUNE_DOUBLE_POP: Enable if double pop insn is preferred
+ over esp addition. */
+DEF_TUNE (X86_TUNE_DOUBLE_POP, "double_pop", m_PENT)
+/* X86_TUNE_SINGLE_PUSH: Enable if single push insn is preferred
+ over esp subtraction. */
+DEF_TUNE (X86_TUNE_SINGLE_PUSH, "single_push", m_386 | m_486 | m_PENT
+ | m_K6_GEODE)
+/* X86_TUNE_DOUBLE_PUSH. Enable if double push insn is preferred
+ over esp subtraction. */
+DEF_TUNE (X86_TUNE_DOUBLE_PUSH, "double_push", m_PENT | m_K6_GEODE)
+/* X86_TUNE_INTEGER_DFMODE_MOVES: Enable if integer moves are preferred
+ for DFmode copies */
+DEF_TUNE (X86_TUNE_INTEGER_DFMODE_MOVES, "integer_dfmode_moves",
+ ~(m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM
+ | m_GEODE | m_AMD_MULTIPLE | m_GENERIC))
+DEF_TUNE (X86_TUNE_PARTIAL_REG_DEPENDENCY, "partial_reg_dependency",
+ m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE
+ | m_GENERIC)
+/* X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY: In the Generic model we have a
+ conflict here in between PPro/Pentium4 based chips that thread 128bit
+ SSE registers as single units versus K8 based chips that divide SSE
+ registers to two 64bit halves. This knob promotes all store destinations
+ to be 128bit to allow register renaming on 128bit SSE units, but usually
+ results in one extra microop on 64bit SSE units. Experimental results
+ shows that disabling this option on P4 brings over 20% SPECfp regression,
+ while enabling it on K8 brings roughly 2.4% regression that can be partly
+ masked by careful scheduling of moves. */
+DEF_TUNE (X86_TUNE_SSE_PARTIAL_REG_DEPENDENCY, "sse_partial_reg_dependency",
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMDFAM10
+ | m_BDVER | m_GENERIC)
+DEF_TUNE (X86_TUNE_SSE_UNALIGNED_LOAD_OPTIMAL, "sse_unaligned_load_optimal",
+ m_COREI7 | m_AMDFAM10 | m_BDVER | m_BTVER | m_SLM)
+DEF_TUNE (X86_TUNE_SSE_UNALIGNED_STORE_OPTIMAL, "sse_unaligned_store_optimal",
+ m_COREI7 | m_BDVER | m_SLM)
+DEF_TUNE (X86_TUNE_SSE_PACKED_SINGLE_INSN_OPTIMAL, "sse_packed_single_insn_optimal",
+ m_BDVER)
+/* X86_TUNE_SSE_SPLIT_REGS: Set for machines where the type and dependencies
+ are resolved on SSE register parts instead of whole registers, so we may
+ maintain just lower part of scalar values in proper format leaving the
+ upper part undefined. */
+DEF_TUNE (X86_TUNE_SSE_SPLIT_REGS, "sse_split_regs", m_ATHLON_K8)
+DEF_TUNE (X86_TUNE_SSE_TYPELESS_STORES, "sse_typeless_stores", m_AMD_MULTIPLE)
+DEF_TUNE (X86_TUNE_SSE_LOAD0_BY_PXOR, "sse_load0_by_pxor", m_PPRO | m_P4_NOCONA)
+DEF_TUNE (X86_TUNE_MEMORY_MISMATCH_STALL, "memory_mismatch_stall",
+ m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC)
+DEF_TUNE (X86_TUNE_PROLOGUE_USING_MOVE, "prologue_using_move",
+ m_PPRO | m_ATHLON_K8)
+DEF_TUNE (X86_TUNE_EPILOGUE_USING_MOVE, "epilogue_using_move",
+ m_PPRO | m_ATHLON_K8)
+DEF_TUNE (X86_TUNE_SHIFT1, "shift1", ~m_486)
+DEF_TUNE (X86_TUNE_USE_FFREEP, "use_ffreep", m_AMD_MULTIPLE)
+DEF_TUNE (X86_TUNE_INTER_UNIT_MOVES_TO_VEC, "inter_unit_moves_to_vec",
+ ~(m_AMD_MULTIPLE | m_GENERIC))
+DEF_TUNE (X86_TUNE_INTER_UNIT_MOVES_FROM_VEC, "inter_unit_moves_from_vec",
+ ~m_ATHLON_K8)
+DEF_TUNE (X86_TUNE_INTER_UNIT_CONVERSIONS, "inter_unit_conversions",
+ ~(m_AMDFAM10 | m_BDVER ))
+/* X86_TUNE_FOUR_JUMP_LIMIT: Some CPU cores are not able to predict more
+ than 4 branch instructions in the 16 byte window. */
+DEF_TUNE (X86_TUNE_FOUR_JUMP_LIMIT, "four_jump_limit",
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM| m_AMD_MULTIPLE
+ | m_GENERIC)
+DEF_TUNE (X86_TUNE_SCHEDULE, "schedule",
+ m_PENT | m_PPRO | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE
+ | m_AMD_MULTIPLE | m_GENERIC)
+DEF_TUNE (X86_TUNE_USE_BT, "use_bt",
+ m_CORE_ALL | m_ATOM | m_SLM | m_AMD_MULTIPLE | m_GENERIC)
+DEF_TUNE (X86_TUNE_USE_INCDEC, "use_incdec",
+ ~(m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_GENERIC))
+DEF_TUNE (X86_TUNE_PAD_RETURNS, "pad_returns",
+ m_CORE_ALL | m_AMD_MULTIPLE | m_GENERIC)
+DEF_TUNE (X86_TUNE_PAD_SHORT_FUNCTION, "pad_short_function", m_ATOM)
+DEF_TUNE (X86_TUNE_EXT_80387_CONSTANTS, "ext_80387_constants",
+ m_PPRO | m_P4_NOCONA | m_CORE_ALL | m_ATOM | m_SLM | m_K6_GEODE
+ | m_ATHLON_K8 | m_GENERIC)
+DEF_TUNE (X86_TUNE_AVOID_VECTOR_DECODE, "avoid_vector_decode",
+ m_CORE_ALL | m_K8 | m_GENERIC64)
+/* X86_TUNE_PROMOTE_HIMODE_IMUL: Modern CPUs have same latency for HImode
+ and SImode multiply, but 386 and 486 do HImode multiply faster. */
+DEF_TUNE (X86_TUNE_PROMOTE_HIMODE_IMUL, "promote_himode_imul",
+ ~(m_386 | m_486))
+/* X86_TUNE_SLOW_IMUL_IMM32_MEM: Imul of 32-bit constant and memory is
+ vector path on AMD machines. */
+DEF_TUNE (X86_TUNE_SLOW_IMUL_IMM32_MEM, "slow_imul_imm32_mem",
+ m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC64)
+/* X86_TUNE_SLOW_IMUL_IMM8: Imul of 8-bit constant is vector path on AMD
+ machines. */
+DEF_TUNE (X86_TUNE_SLOW_IMUL_IMM8, "slow_imul_imm8",
+ m_CORE_ALL | m_K8 | m_AMDFAM10 | m_BDVER | m_BTVER | m_GENERIC64)
+/* X86_TUNE_MOVE_M1_VIA_OR: On pentiums, it is faster to load -1 via OR
+ than a MOV. */
+DEF_TUNE (X86_TUNE_MOVE_M1_VIA_OR, "move_m1_via_or", m_PENT)
+/* X86_TUNE_NOT_UNPAIRABLE: NOT is not pairable on Pentium, while XOR is,
+ but one byte longer. */
+DEF_TUNE (X86_TUNE_NOT_UNPAIRABLE, "not_unpairable", m_PENT)
+/* X86_TUNE_NOT_VECTORMODE: On AMD K6, NOT is vector decoded with memory
+ operand that cannot be represented using a modRM byte. The XOR
+ replacement is long decoded, so this split helps here as well. */
+DEF_TUNE (X86_TUNE_NOT_VECTORMODE, "not_vectormode", m_K6)
+/* X86_TUNE_USE_VECTOR_FP_CONVERTS: Prefer vector packed SSE conversion
+ from FP to FP. */
+DEF_TUNE (X86_TUNE_USE_VECTOR_FP_CONVERTS, "use_vector_fp_converts",
+ m_CORE_ALL | m_AMDFAM10 | m_GENERIC)
+/* X86_TUNE_USE_VECTOR_CONVERTS: Prefer vector packed SSE conversion
+ from integer to FP. */
+DEF_TUNE (X86_TUNE_USE_VECTOR_CONVERTS, "use_vector_converts", m_AMDFAM10)
+/* X86_TUNE_FUSE_CMP_AND_BRANCH: Fuse a compare or test instruction
+ with a subsequent conditional jump instruction into a single
+ compare-and-branch uop. */
+DEF_TUNE (X86_TUNE_FUSE_CMP_AND_BRANCH, "fuse_cmp_and_branch", m_BDVER)
+/* X86_TUNE_OPT_AGU: Optimize for Address Generation Unit. This flag
+ will impact LEA instruction selection. */
+DEF_TUNE (X86_TUNE_OPT_AGU, "opt_agu", m_ATOM | m_SLM)
+/* X86_TUNE_VECTORIZE_DOUBLE: Enable double precision vector
+ instructions. */
+DEF_TUNE (X86_TUNE_VECTORIZE_DOUBLE, "vectorize_double", ~m_ATOM)
+/* X86_TUNE_SOFTWARE_PREFETCHING_BENEFICIAL: Enable software prefetching
+ at -O3. For the moment, the prefetching seems badly tuned for Intel
+ chips. */
+DEF_TUNE (X86_TUNE_SOFTWARE_PREFETCHING_BENEFICIAL, "software_prefetching_beneficial",
+ m_K6_GEODE | m_AMD_MULTIPLE)
+/* X86_TUNE_AVX128_OPTIMAL: Enable 128-bit AVX instruction generation for
+ the auto-vectorizer. */
+DEF_TUNE (X86_TUNE_AVX128_OPTIMAL, "avx128_optimal", m_BDVER | m_BTVER2)
+/* X86_TUNE_REASSOC_INT_TO_PARALLEL: Try to produce parallel computations
+ during reassociation of integer computation. */
+DEF_TUNE (X86_TUNE_REASSOC_INT_TO_PARALLEL, "reassoc_int_to_parallel",
+ m_ATOM)
+/* X86_TUNE_REASSOC_FP_TO_PARALLEL: Try to produce parallel computations
+ during reassociation of fp computation. */
+DEF_TUNE (X86_TUNE_REASSOC_FP_TO_PARALLEL, "reassoc_fp_to_parallel",
+ m_ATOM | m_SLM | m_HASWELL | m_BDVER1 | m_BDVER2)
+/* X86_TUNE_GENERAL_REGS_SSE_SPILL: Try to spill general regs to SSE
+ regs instead of memory. */
+DEF_TUNE (X86_TUNE_GENERAL_REGS_SSE_SPILL, "general_regs_sse_spill",
+ m_CORE_ALL)
+/* X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE: Try to avoid memory operands for
+ a conditional move. */
+DEF_TUNE (X86_TUNE_AVOID_MEM_OPND_FOR_CMOVE, "avoid_mem_opnd_for_cmove", m_ATOM)
+/* X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS: Try to split memory operand for
+ fp converts to destination register. */
+DEF_TUNE (X86_TUNE_SPLIT_MEM_OPND_FOR_FP_CONVERTS, "split_mem_opnd_for_fp_converts",
+ m_SLM)
diff --git a/gcc/config/ia64/hpux.h b/gcc/config/ia64/hpux.h
index 22cfe9f6677..ca592e4bc26 100644
--- a/gcc/config/ia64/hpux.h
+++ b/gcc/config/ia64/hpux.h
@@ -179,9 +179,10 @@ do { \
#undef TARGET_ASM_RELOC_RW_MASK
#define TARGET_ASM_RELOC_RW_MASK ia64_hpux_reloc_rw_mask
-/* ia64 HPUX has the float and long double forms of math functions. */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
+/* ia64 HPUX has the float and long double forms of math functions.
+ We redefine this hook so the version from elfos.h header won't be used. */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION default_c99_libc_has_function
#undef TARGET_INIT_LIBFUNCS
#define TARGET_INIT_LIBFUNCS ia64_hpux_init_libfuncs
diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
index d6e47a70e7a..4a4b48d9882 100644
--- a/gcc/config/linux-android.c
+++ b/gcc/config/linux-android.c
@@ -31,3 +31,17 @@ linux_android_has_ifunc_p (void)
{
return TARGET_ANDROID ? false : HAVE_GNU_INDIRECT_FUNCTION;
}
+
+bool
+linux_android_libc_has_function (enum function_class fn_class)
+{
+ if (OPTION_GLIBC)
+ return true;
+ if (OPTION_BIONIC)
+ if (fn_class == function_c94
+ || fn_class == function_c99_misc
+ || fn_class == function_sincos)
+ return true;
+
+ return false;
+}
diff --git a/gcc/config/linux-protos.h b/gcc/config/linux-protos.h
index 3f926e5dffd..d1f0f926367 100644
--- a/gcc/config/linux-protos.h
+++ b/gcc/config/linux-protos.h
@@ -19,3 +19,5 @@ along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
extern bool linux_android_has_ifunc_p (void);
+
+extern bool linux_android_libc_has_function (enum function_class fn_class);
diff --git a/gcc/config/linux.h b/gcc/config/linux.h
index 2be1079b92f..8116e698d94 100644
--- a/gcc/config/linux.h
+++ b/gcc/config/linux.h
@@ -95,15 +95,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERX32, UCLIBC_DYNAMIC_LINKERX32, \
BIONIC_DYNAMIC_LINKERX32)
-/* Determine whether the entire c99 runtime
- is present in the runtime library. */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension. */
-#undef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC || OPTION_BIONIC)
-
/* Whether we have Bionic libc runtime */
#undef TARGET_HAS_BIONIC
#define TARGET_HAS_BIONIC (OPTION_BIONIC)
+
+/* Determine what functions are present at the runtime;
+ this includes full c99 runtime and sincos. */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
diff --git a/gcc/config/lm32/uclinux-elf.h b/gcc/config/lm32/uclinux-elf.h
index 3a556d7258d..a5e8163cf6f 100644
--- a/gcc/config/lm32/uclinux-elf.h
+++ b/gcc/config/lm32/uclinux-elf.h
@@ -77,3 +77,5 @@
#undef CC1_SPEC
#define CC1_SPEC "%{G*} %{!fno-PIC:-fPIC}"
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/m68k/uclinux.h b/gcc/config/m68k/uclinux.h
index 8d743126547..b1af7d2c585 100644
--- a/gcc/config/m68k/uclinux.h
+++ b/gcc/config/m68k/uclinux.h
@@ -67,3 +67,6 @@ along with GCC; see the file COPYING3. If not see
sections. */
#undef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
#define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/microblaze/microblaze.h b/gcc/config/microblaze/microblaze.h
index bc4d9a128d1..eb8e45ce17b 100644
--- a/gcc/config/microblaze/microblaze.h
+++ b/gcc/config/microblaze/microblaze.h
@@ -892,6 +892,10 @@ do { \
%{pg:-start-group -lxilprofile -lgloss -lxil -lc -lm -end-group } \
%{!pg:-start-group -lgloss -lxil -lc -lm -end-group }} "
+/* microblaze-unknown-elf target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtend.o%s crtn.o%s"
diff --git a/gcc/config/mips/linux-common.h b/gcc/config/mips/linux-common.h
index ca4ea0705a6..ebc67a28d90 100644
--- a/gcc/config/mips/linux-common.h
+++ b/gcc/config/mips/linux-common.h
@@ -44,7 +44,7 @@ along with GCC; see the file COPYING3. If not see
#undef LIB_SPEC
#define LIB_SPEC \
LINUX_OR_ANDROID_LD (GNU_USER_TARGET_LIB_SPEC, \
- GNU_USER_TARGET_LIB_SPEC " " ANDROID_LIB_SPEC)
+ GNU_USER_TARGET_NO_PTHREADS_LIB_SPEC " " ANDROID_LIB_SPEC)
#undef STARTFILE_SPEC
#define STARTFILE_SPEC \
diff --git a/gcc/config/mips/linux.h b/gcc/config/mips/linux.h
index 9b4c68db6ee..6736295eb36 100644
--- a/gcc/config/mips/linux.h
+++ b/gcc/config/mips/linux.h
@@ -17,4 +17,9 @@ 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 GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
+#define GLIBC_DYNAMIC_LINKER \
+ "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}"
+
+#undef UCLIBC_DYNAMIC_LINKER
+#define UCLIBC_DYNAMIC_LINKER \
+ "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}"
diff --git a/gcc/config/mips/linux64.h b/gcc/config/mips/linux64.h
index dbba47a1a13..421a53a1085 100644
--- a/gcc/config/mips/linux64.h
+++ b/gcc/config/mips/linux64.h
@@ -22,10 +22,22 @@ along with GCC; see the file COPYING3. If not see
#define GNU_USER_LINK_EMULATION64 "elf64%{EB:b}%{EL:l}tsmip"
#define GNU_USER_LINK_EMULATIONN32 "elf32%{EB:b}%{EL:l}tsmipn32"
-#define GLIBC_DYNAMIC_LINKER32 "/lib/ld.so.1"
-#define GLIBC_DYNAMIC_LINKER64 "/lib64/ld.so.1"
-#define GLIBC_DYNAMIC_LINKERN32 "/lib32/ld.so.1"
-#define UCLIBC_DYNAMIC_LINKERN32 "/lib32/ld-uClibc.so.0"
+#define GLIBC_DYNAMIC_LINKER32 \
+ "%{mnan=2008:/lib/ld-linux-mipsn8.so.1;:/lib/ld.so.1}"
+#define GLIBC_DYNAMIC_LINKER64 \
+ "%{mnan=2008:/lib64/ld-linux-mipsn8.so.1;:/lib64/ld.so.1}"
+#define GLIBC_DYNAMIC_LINKERN32 \
+ "%{mnan=2008:/lib32/ld-linux-mipsn8.so.1;:/lib32/ld.so.1}"
+
+#undef UCLIBC_DYNAMIC_LINKER32
+#define UCLIBC_DYNAMIC_LINKER32 \
+ "%{mnan=2008:/lib/ld-uClibc-mipsn8.so.0;:/lib/ld-uClibc.so.0}"
+#undef UCLIBC_DYNAMIC_LINKER64
+#define UCLIBC_DYNAMIC_LINKER64 \
+ "%{mnan=2008:/lib/ld64-uClibc-mipsn8.so.0;:/lib/ld64-uClibc.so.0}"
+#define UCLIBC_DYNAMIC_LINKERN32 \
+ "%{mnan=2008:/lib32/ld-uClibc-mipsn8.so.0;:/lib32/ld-uClibc.so.0}"
+
#define BIONIC_DYNAMIC_LINKERN32 "/system/bin/linker32"
#define GNU_USER_DYNAMIC_LINKERN32 \
CHOOSE_DYNAMIC_LINKER (GLIBC_DYNAMIC_LINKERN32, UCLIBC_DYNAMIC_LINKERN32, \
diff --git a/gcc/config/mips/mips-modes.def b/gcc/config/mips/mips-modes.def
index ecb7f181d8f..383d2cb6d43 100644
--- a/gcc/config/mips/mips-modes.def
+++ b/gcc/config/mips/mips-modes.def
@@ -17,12 +17,7 @@ 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/>. */
-/* MIPS has a quirky almost-IEEE format for all its
- floating point. */
-RESET_FLOAT_FORMAT (SF, mips_single_format);
-RESET_FLOAT_FORMAT (DF, mips_double_format);
-
-FLOAT_MODE (TF, 16, mips_quad_format);
+FLOAT_MODE (TF, 16, ieee_quad_format);
/* Vector modes. */
VECTOR_MODES (INT, 4); /* V4QI V2HI */
diff --git a/gcc/config/mips/mips-opts.h b/gcc/config/mips/mips-opts.h
index dbfcfad0b04..56249d94c4e 100644
--- a/gcc/config/mips/mips-opts.h
+++ b/gcc/config/mips/mips-opts.h
@@ -27,6 +27,13 @@ enum mips_code_readable_setting {
CODE_READABLE_YES
};
+/* Enumerates the setting of the -mabs and -mnan options. */
+enum mips_ieee_754_setting {
+ MIPS_IEEE_754_DEFAULT,
+ MIPS_IEEE_754_LEGACY,
+ MIPS_IEEE_754_2008
+};
+
/* Enumerates the setting of the -mr10k-cache-barrier option. */
enum mips_r10k_cache_barrier_setting {
R10K_CACHE_BARRIER_NONE,
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index a56757c877f..5993aabe578 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -56,6 +56,7 @@ along with GCC; see the file COPYING3. If not see
#include "target-globals.h"
#include "opts.h"
#include "tree-pass.h"
+#include "context.h"
/* True if X is an UNSPEC wrapper around a SYMBOL_REF or LABEL_REF. */
#define UNSPEC_ADDRESS_P(X) \
@@ -8843,6 +8844,11 @@ mips_file_start (void)
fprintf (asm_out_file, "\t.section .gcc_compiled_long%d\n"
"\t.previous\n", TARGET_LONG64 ? 64 : 32);
+ /* Record the NaN encoding. */
+ if (HAVE_AS_NAN || mips_nan != MIPS_IEEE_754_DEFAULT)
+ fprintf (asm_out_file, "\t.nan\t%s\n",
+ mips_nan == MIPS_IEEE_754_2008 ? "2008" : "legacy");
+
#ifdef HAVE_AS_GNU_ATTRIBUTE
{
int attr;
@@ -12291,6 +12297,7 @@ mips_adjust_insn_length (rtx insn, int length)
/* mips.md uses MAX_PIC_BRANCH_LENGTH as a placeholder for the length
of a PIC long-branch sequence. Substitute the correct value. */
if (length == MAX_PIC_BRANCH_LENGTH
+ && JUMP_P (insn)
&& INSN_CODE (insn) >= 0
&& get_attr_type (insn) == TYPE_BRANCH)
{
@@ -12312,7 +12319,9 @@ mips_adjust_insn_length (rtx insn, int length)
length += TARGET_MIPS16 ? 2 : 4;
/* See how many nops might be needed to avoid hardware hazards. */
- if (!cfun->machine->ignore_hazard_length_p && INSN_CODE (insn) >= 0)
+ if (!cfun->machine->ignore_hazard_length_p
+ && INSN_P (insn)
+ && INSN_CODE (insn) >= 0)
switch (get_attr_hazard (insn))
{
case HAZARD_NONE:
@@ -16332,33 +16341,43 @@ mips_machine_reorg2 (void)
return 0;
}
-struct rtl_opt_pass pass_mips_machine_reorg2 =
-{
- {
- RTL_PASS,
- "mach2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- mips_machine_reorg2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_MACH_DEP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
-};
+namespace {
-struct register_pass_info insert_pass_mips_machine_reorg2 =
+const pass_data pass_data_mips_machine_reorg2 =
{
- &pass_mips_machine_reorg2.pass, /* pass */
- "dbr", /* reference_pass_name */
- 1, /* ref_pass_instance_number */
- PASS_POS_INSERT_AFTER /* po_op */
+ RTL_PASS, /* type */
+ "mach2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_MACH_DEP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+
+class pass_mips_machine_reorg2 : public rtl_opt_pass
+{
+public:
+ pass_mips_machine_reorg2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_mips_machine_reorg2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return mips_machine_reorg2 (); }
+
+}; // class pass_mips_machine_reorg2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_mips_machine_reorg2 (gcc::context *ctxt)
+{
+ return new pass_mips_machine_reorg2 (ctxt);
+}
+
/* Implement TARGET_ASM_OUTPUT_MI_THUNK. Generate rtl rather than asm text
in order to avoid duplicating too much logic from elsewhere. */
@@ -16980,6 +16999,15 @@ mips_option_override (void)
}
}
+ /* Pre-IEEE 754-2008 MIPS hardware has a quirky almost-IEEE format
+ for all its floating point. */
+ if (mips_nan != MIPS_IEEE_754_2008)
+ {
+ REAL_MODE_FORMAT (SFmode) = &mips_single_format;
+ REAL_MODE_FORMAT (DFmode) = &mips_double_format;
+ REAL_MODE_FORMAT (TFmode) = &mips_quad_format;
+ }
+
/* Make sure that the user didn't turn off paired single support when
MIPS-3D support is requested. */
if (TARGET_MIPS3D
@@ -17143,6 +17171,14 @@ mips_option_override (void)
/* We register a second machine specific reorg pass after delay slot
filling. Registering the pass must be done at start up. It's
convenient to do it here. */
+ opt_pass *new_pass = make_pass_mips_machine_reorg2 (g);
+ struct register_pass_info insert_pass_mips_machine_reorg2 =
+ {
+ new_pass, /* pass */
+ "dbr", /* reference_pass_name */
+ 1, /* ref_pass_instance_number */
+ PASS_POS_INSERT_AFTER /* po_op */
+ };
register_pass (&insert_pass_mips_machine_reorg2);
if (TARGET_HARD_FLOAT_ABI && TARGET_MIPS5900)
diff --git a/gcc/config/mips/mips.h b/gcc/config/mips/mips.h
index 2dcccd48b8f..af7eeee6682 100644
--- a/gcc/config/mips/mips.h
+++ b/gcc/config/mips/mips.h
@@ -507,6 +507,12 @@ struct mips_cpu_info {
if (TARGET_PAIRED_SINGLE_FLOAT) \
builtin_define ("__mips_paired_single_float"); \
\
+ if (mips_abs == MIPS_IEEE_754_2008) \
+ builtin_define ("__mips_abs2008"); \
+ \
+ if (mips_nan == MIPS_IEEE_754_2008) \
+ builtin_define ("__mips_nan2008"); \
+ \
if (TARGET_BIG_ENDIAN) \
{ \
builtin_define_std ("MIPSEB"); \
@@ -743,6 +749,7 @@ struct mips_cpu_info {
--with-abi is ignored if -mabi is specified.
--with-float is ignored if -mhard-float or -msoft-float are
specified.
+ --with-nan is ignored if -mnan is specified.
--with-divide is ignored if -mdivide-traps or -mdivide-breaks are
specified. */
#define OPTION_DEFAULT_SPECS \
@@ -755,6 +762,7 @@ struct mips_cpu_info {
{"abi", "%{!mabi=*:-mabi=%(VALUE)}" }, \
{"float", "%{!msoft-float:%{!mhard-float:-m%(VALUE)-float}}" }, \
{"fpu", "%{!msingle-float:%{!mdouble-float:-m%(VALUE)-float}}" }, \
+ {"nan", "%{!mnan=*:-mnan=%(VALUE)}" }, \
{"divide", "%{!mdivide-traps:%{!mdivide-breaks:-mdivide-%(VALUE)}}" }, \
{"llsc", "%{!mllsc:%{!mno-llsc:-m%(VALUE)}}" }, \
{"mips-plt", "%{!mplt:%{!mno-plt:-m%(VALUE)}}" }, \
@@ -1160,7 +1168,7 @@ struct mips_cpu_info {
%(subtarget_asm_debugging_spec) \
%{mabi=*} %{!mabi=*: %(asm_abi_default_spec)} \
%{mgp32} %{mgp64} %{march=*} %{mxgot:-xgot} \
-%{mfp32} %{mfp64} \
+%{mfp32} %{mfp64} %{mnan=*} \
%{mshared} %{mno-shared} \
%{msym32} %{mno-sym32} \
%{mtune=*} \
@@ -2897,6 +2905,10 @@ while (0)
#define HAVE_AS_TLS 0
#endif
+#ifndef HAVE_AS_NAN
+#define HAVE_AS_NAN 0
+#endif
+
#ifndef USED_FOR_TARGET
/* Information about ".set noFOO; ...; .set FOO" blocks. */
struct mips_asm_switch {
diff --git a/gcc/config/mips/mips.md b/gcc/config/mips/mips.md
index ca79a31e29a..0cda169224f 100644
--- a/gcc/config/mips/mips.md
+++ b/gcc/config/mips/mips.md
@@ -2711,14 +2711,15 @@
;; Do not use the integer abs macro instruction, since that signals an
;; exception on -2147483648 (sigh).
-;; abs.fmt is an arithmetic instruction and treats all NaN inputs as
-;; invalid; it does not clear their sign bits. We therefore can't use
-;; abs.fmt if the signs of NaNs matter.
+;; The "legacy" (as opposed to "2008") form of ABS.fmt is an arithmetic
+;; instruction that treats all NaN inputs as invalid; it does not clear
+;; their sign bit. We therefore can't use that form if the signs of
+;; NaNs matter.
(define_insn "abs<mode>2"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(abs:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
- "!HONOR_NANS (<MODE>mode)"
+ "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
"abs.<fmt>\t%0,%1"
[(set_attr "type" "fabs")
(set_attr "mode" "<UNITMODE>")])
@@ -2793,14 +2794,15 @@
[(set_attr "alu_type" "sub")
(set_attr "mode" "DI")])
-;; neg.fmt is an arithmetic instruction and treats all NaN inputs as
-;; invalid; it does not flip their sign bit. We therefore can't use
-;; neg.fmt if the signs of NaNs matter.
+;; The "legacy" (as opposed to "2008") form of NEG.fmt is an arithmetic
+;; instruction that treats all NaN inputs as invalid; it does not flip
+;; their sign bit. We therefore can't use that form if the signs of
+;; NaNs matter.
(define_insn "neg<mode>2"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(neg:ANYF (match_operand:ANYF 1 "register_operand" "f")))]
- "!HONOR_NANS (<MODE>mode)"
+ "mips_abs == MIPS_IEEE_754_2008 || !HONOR_NANS (<MODE>mode)"
"neg.<fmt>\t%0,%1"
[(set_attr "type" "fneg")
(set_attr "mode" "<UNITMODE>")])
@@ -6671,8 +6673,13 @@
"ISA_HAS_PREFETCH && TARGET_EXPLICIT_RELOCS"
{
if (TARGET_LOONGSON_2EF || TARGET_LOONGSON_3A)
- /* Loongson 2[ef] and Loongson 3a use load to $0 to perform prefetching. */
- return "ld\t$0,%a0";
+ {
+ /* Loongson 2[ef] and Loongson 3a use load to $0 for prefetching. */
+ if (TARGET_64BIT)
+ return "ld\t$0,%a0";
+ else
+ return "lw\t$0,%a0";
+ }
operands[1] = mips_prefetch_cookie (operands[1], operands[2]);
return "pref\t%1,%a0";
}
diff --git a/gcc/config/mips/mips.opt b/gcc/config/mips/mips.opt
index 08ab29b1810..0324041dbea 100644
--- a/gcc/config/mips/mips.opt
+++ b/gcc/config/mips/mips.opt
@@ -205,6 +205,24 @@ mfused-madd
Target Report Mask(FUSED_MADD)
Generate floating-point multiply-add instructions
+mabs=
+Target RejectNegative Joined Enum(mips_ieee_754_value) Var(mips_abs) Init(MIPS_IEEE_754_DEFAULT)
+-mabs=MODE Select the IEEE 754 ABS/NEG instruction execution mode
+
+mnan=
+Target RejectNegative Joined Enum(mips_ieee_754_value) Var(mips_nan) Init(MIPS_IEEE_754_DEFAULT)
+-mnan=ENCODING Select the IEEE 754 NaN data encoding
+
+Enum
+Name(mips_ieee_754_value) Type(int)
+Known MIPS IEEE 754 settings (for use with the -mabs= and -mnan= options):
+
+EnumValue
+Enum(mips_ieee_754_value) String(2008) Value(MIPS_IEEE_754_2008)
+
+EnumValue
+Enum(mips_ieee_754_value) String(legacy) Value(MIPS_IEEE_754_LEGACY)
+
mgp32
Target Report RejectNegative InverseMask(64BIT)
Use 32-bit general registers
diff --git a/gcc/config/mips/mti-linux.h b/gcc/config/mips/mti-linux.h
index 45bc0b88107..96dcac4dfb3 100644
--- a/gcc/config/mips/mti-linux.h
+++ b/gcc/config/mips/mti-linux.h
@@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see
/* This target is a multilib target, specify the sysroot paths. */
#undef SYSROOT_SUFFIX_SPEC
#define SYSROOT_SUFFIX_SPEC \
- "%{mips32:/mips32}%{mips64:/mips64}%{mips64r2:/mips64r2}%{mips16:/mips16}%{mmicromips:/micromips}%{mabi=64:/64}%{mel|EL:/el}%{msoft-float:/sof}"
+ "%{mips32:/mips32}%{mips64:/mips64}%{mips64r2:/mips64r2}%{mips16:/mips16}%{mmicromips:/micromips}%{mabi=64:/64}%{mel|EL:/el}%{msoft-float:/sof}%{mnan=2008:/nan2008}"
#undef DRIVER_SELF_SPECS
#define DRIVER_SELF_SPECS \
diff --git a/gcc/config/mips/t-mti-elf b/gcc/config/mips/t-mti-elf
index bce8f063452..4aec70cb807 100644
--- a/gcc/config/mips/t-mti-elf
+++ b/gcc/config/mips/t-mti-elf
@@ -19,8 +19,8 @@
# The default build is mips32r2, hard-float big-endian. Add mips32,
# soft-float, and little-endian variations.
-MULTILIB_OPTIONS = mips32/mips64/mips64r2 mips16 mmicromips mabi=64 EL msoft-float
-MULTILIB_DIRNAMES = mips32 mips64 mips64r2 mips16 micromips 64 el sof
+MULTILIB_OPTIONS = mips32/mips64/mips64r2 mips16/mmicromips mabi=64 EL msoft-float/mnan=2008
+MULTILIB_DIRNAMES = mips32 mips64 mips64r2 mips16 micromips 64 el sof nan2008
MULTILIB_MATCHES = EL=mel EB=meb
# The 64 bit ABI is not supported on the mips32 architecture.
@@ -36,9 +36,7 @@ MULTILIB_EXCEPTIONS += mabi=64*
MULTILIB_EXCEPTIONS += *mips64*/*mips16*
MULTILIB_EXCEPTIONS += *mips16/mabi=64*
-# We only want micromips for mips32r2 architecture and we do not want
-# it used in conjunction with -mips16.
-MULTILIB_EXCEPTIONS += *mips16/mmicromips*
+# We only want micromips for mips32r2 architecture.
MULTILIB_EXCEPTIONS += *mips64*/mmicromips*
MULTILIB_EXCEPTIONS += *mips32/mmicromips*
MULTILIB_EXCEPTIONS += *mmicromips/mabi=64*
diff --git a/gcc/config/mips/t-mti-linux b/gcc/config/mips/t-mti-linux
index bce8f063452..4aec70cb807 100644
--- a/gcc/config/mips/t-mti-linux
+++ b/gcc/config/mips/t-mti-linux
@@ -19,8 +19,8 @@
# The default build is mips32r2, hard-float big-endian. Add mips32,
# soft-float, and little-endian variations.
-MULTILIB_OPTIONS = mips32/mips64/mips64r2 mips16 mmicromips mabi=64 EL msoft-float
-MULTILIB_DIRNAMES = mips32 mips64 mips64r2 mips16 micromips 64 el sof
+MULTILIB_OPTIONS = mips32/mips64/mips64r2 mips16/mmicromips mabi=64 EL msoft-float/mnan=2008
+MULTILIB_DIRNAMES = mips32 mips64 mips64r2 mips16 micromips 64 el sof nan2008
MULTILIB_MATCHES = EL=mel EB=meb
# The 64 bit ABI is not supported on the mips32 architecture.
@@ -36,9 +36,7 @@ MULTILIB_EXCEPTIONS += mabi=64*
MULTILIB_EXCEPTIONS += *mips64*/*mips16*
MULTILIB_EXCEPTIONS += *mips16/mabi=64*
-# We only want micromips for mips32r2 architecture and we do not want
-# it used in conjunction with -mips16.
-MULTILIB_EXCEPTIONS += *mips16/mmicromips*
+# We only want micromips for mips32r2 architecture.
MULTILIB_EXCEPTIONS += *mips64*/mmicromips*
MULTILIB_EXCEPTIONS += *mips32/mmicromips*
MULTILIB_EXCEPTIONS += *mmicromips/mabi=64*
diff --git a/gcc/config/mmix/mmix.h b/gcc/config/mmix/mmix.h
index c5edc5777a9..2d5e1a8a392 100644
--- a/gcc/config/mmix/mmix.h
+++ b/gcc/config/mmix/mmix.h
@@ -813,6 +813,10 @@ typedef struct { int regs; int lib; } CUMULATIVE_ARGS;
#define NO_IMPLICIT_EXTERN_C
+/* mmix-knuth-mmixware target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
/* These are checked. */
#define DOLLARS_IN_IDENTIFIERS 0
#define NO_DOLLAR_IN_LABEL
diff --git a/gcc/config/moxie/uclinux.h b/gcc/config/moxie/uclinux.h
index 498037e8072..85c65f257ce 100644
--- a/gcc/config/moxie/uclinux.h
+++ b/gcc/config/moxie/uclinux.h
@@ -37,3 +37,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
--wrap=mmap --wrap=munmap --wrap=alloca\
%{fmudflapth: --wrap=pthread_create\
}} %{fmudflap|fmudflapth: --wrap=main}"
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/netbsd.h b/gcc/config/netbsd.h
index 71c9183be0d..dd50dcc0ec4 100644
--- a/gcc/config/netbsd.h
+++ b/gcc/config/netbsd.h
@@ -139,6 +139,9 @@ along with GCC; see the file COPYING3. If not see
#undef LIBGCC_SPEC
#define LIBGCC_SPEC NETBSD_LIBGCC_SPEC
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
/* When building shared libraries, the initialization and finalization
functions for the library are .init and .fini respectively. */
diff --git a/gcc/config/openbsd.h b/gcc/config/openbsd.h
index 6537451f5f5..0d118b46328 100644
--- a/gcc/config/openbsd.h
+++ b/gcc/config/openbsd.h
@@ -145,8 +145,10 @@ while (0)
#define TARGET_POSIX_IO
-/* All new versions of OpenBSD have C99 functions. */
-#define TARGET_C99_FUNCTIONS 1
+/* All new versions of OpenBSD have C99 functions. We redefine this hook
+ so the version from elfos.h header won't be used. */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION default_libc_has_function
/* Runtime target specification. */
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h
index c384824fbf6..9685bb25a57 100644
--- a/gcc/config/pa/pa-hpux.h
+++ b/gcc/config/pa/pa-hpux.h
@@ -114,3 +114,6 @@ along with GCC; see the file COPYING3. If not see
compatibility with the HP-UX unwind library. */
#undef TARGET_HPUX_UNWIND_LIBRARY
#define TARGET_HPUX_UNWIND_LIBRARY 1
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index be07d2a229a..80c4d43401d 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -833,7 +833,7 @@
(define_insn "scc"
[(set (match_operand:SI 0 "register_operand" "=r")
(match_operator:SI 3 "comparison_operator"
- [(match_operand:SI 1 "register_operand" "r")
+ [(match_operand:SI 1 "reg_or_0_operand" "rM")
(match_operand:SI 2 "arith11_operand" "rI")]))]
""
"{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi 1,%0"
@@ -843,7 +843,7 @@
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
(match_operator:DI 3 "comparison_operator"
- [(match_operand:DI 1 "register_operand" "r")
+ [(match_operand:DI 1 "reg_or_0_operand" "rM")
(match_operand:DI 2 "arith11_operand" "rI")]))]
"TARGET_64BIT"
"cmp%I2clr,*%B3 %2,%1,%0\;ldi 1,%0"
@@ -853,10 +853,10 @@
(define_insn "iorscc"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (match_operator:SI 3 "comparison_operator"
- [(match_operand:SI 1 "register_operand" "r")
+ [(match_operand:SI 1 "reg_or_0_operand" "rM")
(match_operand:SI 2 "arith11_operand" "rI")])
(match_operator:SI 6 "comparison_operator"
- [(match_operand:SI 4 "register_operand" "r")
+ [(match_operand:SI 4 "reg_or_0_operand" "rM")
(match_operand:SI 5 "arith11_operand" "rI")])))]
""
"{com%I2clr|cmp%I2clr},%S3 %2,%1,%%r0\;{com%I5clr|cmp%I5clr},%B6 %5,%4,%0\;ldi 1,%0"
@@ -866,10 +866,10 @@
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
(ior:DI (match_operator:DI 3 "comparison_operator"
- [(match_operand:DI 1 "register_operand" "r")
+ [(match_operand:DI 1 "reg_or_0_operand" "rM")
(match_operand:DI 2 "arith11_operand" "rI")])
(match_operator:DI 6 "comparison_operator"
- [(match_operand:DI 4 "register_operand" "r")
+ [(match_operand:DI 4 "reg_or_0_operand" "rM")
(match_operand:DI 5 "arith11_operand" "rI")])))]
"TARGET_64BIT"
"cmp%I2clr,*%S3 %2,%1,%%r0\;cmp%I5clr,*%B6 %5,%4,%0\;ldi 1,%0"
@@ -881,7 +881,7 @@
(define_insn "negscc"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_operator:SI 3 "comparison_operator"
- [(match_operand:SI 1 "register_operand" "r")
+ [(match_operand:SI 1 "reg_or_0_operand" "rM")
(match_operand:SI 2 "arith11_operand" "rI")])))]
""
"{com%I2clr|cmp%I2clr},%B3 %2,%1,%0\;ldi -1,%0"
@@ -891,7 +891,7 @@
(define_insn ""
[(set (match_operand:DI 0 "register_operand" "=r")
(neg:DI (match_operator:DI 3 "comparison_operator"
- [(match_operand:DI 1 "register_operand" "r")
+ [(match_operand:DI 1 "reg_or_0_operand" "rM")
(match_operand:DI 2 "arith11_operand" "rI")])))]
"TARGET_64BIT"
"cmp%I2clr,*%B3 %2,%1,%0\;ldi -1,%0"
diff --git a/gcc/config/pdp11/pdp11.h b/gcc/config/pdp11/pdp11.h
index d61db4c3bd0..d4bc19a00f1 100644
--- a/gcc/config/pdp11/pdp11.h
+++ b/gcc/config/pdp11/pdp11.h
@@ -666,3 +666,7 @@ extern rtx cc0_reg_rtx;
#define COMPARE_FLAG_MODE HImode
#define TARGET_HAVE_NAMED_SECTIONS false
+
+/* pdp11-unknown-aout target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/picochip/picochip.h b/gcc/config/picochip/picochip.h
index d43ec20e440..13414c6cc9c 100644
--- a/gcc/config/picochip/picochip.h
+++ b/gcc/config/picochip/picochip.h
@@ -656,4 +656,8 @@ enum picochip_builtins
not detecting this. */
#define HAVE_AS_LEB128 1
+/* picochip-unknown-none target has no support of C99 runtime */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
/* The End */
diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c
index c2ed7389bc4..d7cacc16352 100644
--- a/gcc/config/rl78/rl78.c
+++ b/gcc/config/rl78/rl78.c
@@ -49,6 +49,7 @@
#include "rl78-protos.h"
#include "dumpfile.h"
#include "tree-pass.h"
+#include "context.h"
static inline bool is_interrupt_func (const_tree decl);
static inline bool is_brk_interrupt_func (const_tree decl);
@@ -129,30 +130,45 @@ devirt_pass (void)
/* This pass converts virtual instructions using virtual registers, to
real instructions using real registers. Rather than run it as
reorg, we reschedule it before vartrack to help with debugging. */
-static struct opt_pass rl78_devirt_pass =
-{
- RTL_PASS,
- "devirt",
- OPTGROUP_NONE, /* optinfo_flags */
- devirt_gate,
- devirt_pass,
- NULL,
- NULL,
- 212,
- TV_MACH_DEP,
- 0, 0, 0,
- 0,
- 0
+namespace {
+
+const pass_data pass_data_rl78_devirt =
+{
+ RTL_PASS, /* type */
+ "devirt", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_MACH_DEP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
-static struct register_pass_info rl78_devirt_info =
+class pass_rl78_devirt : public rtl_opt_pass
{
- & rl78_devirt_pass,
- "vartrack",
- 1,
- PASS_POS_INSERT_BEFORE
+public:
+ pass_rl78_devirt(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rl78_devirt, ctxt)
+ {
+ }
+
+ /* opt_pass methods: */
+ bool gate () { return devirt_gate (); }
+ unsigned int execute () { return devirt_pass (); }
};
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rl78_devirt (gcc::context *ctxt)
+{
+ return new pass_rl78_devirt (ctxt);
+}
+
+
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START rl78_asm_file_start
@@ -167,6 +183,15 @@ rl78_asm_file_start (void)
fprintf (asm_out_file, "r%d\t=\t0x%x\n", 16 + i, 0xffee8 + i);
}
+ opt_pass *rl78_devirt_pass = make_pass_rl78_devirt (g);
+ struct register_pass_info rl78_devirt_info =
+ {
+ rl78_devirt_pass,
+ "vartrack",
+ 1,
+ PASS_POS_INSERT_BEFORE
+ };
+
register_pass (& rl78_devirt_info);
}
diff --git a/gcc/config/rs6000/aix43.h b/gcc/config/rs6000/aix43.h
index 70db7f7482f..b27c046021a 100644
--- a/gcc/config/rs6000/aix43.h
+++ b/gcc/config/rs6000/aix43.h
@@ -159,3 +159,6 @@ do { \
#define TARGET_USES_AIX64_OPT 1
#define TARGET_AIX_VERSION 43
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/rs6000/aix51.h b/gcc/config/rs6000/aix51.h
index 669dbbe03f3..3837bfdc0bb 100644
--- a/gcc/config/rs6000/aix51.h
+++ b/gcc/config/rs6000/aix51.h
@@ -163,3 +163,6 @@ do { \
#define TARGET_USE_JCR_SECTION 0
#define TARGET_AIX_VERSION 51
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/rs6000/aix52.h b/gcc/config/rs6000/aix52.h
index c57271a5a58..51954718b2e 100644
--- a/gcc/config/rs6000/aix52.h
+++ b/gcc/config/rs6000/aix52.h
@@ -166,10 +166,6 @@ do { \
#undef LD_INIT_SWITCH
#define LD_INIT_SWITCH "-binitfini"
-/* AIX 5.2 has the float and long double forms of math functions. */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
-
#ifndef _AIX52
extern long long int atoll(const char *);
#endif
diff --git a/gcc/config/rs6000/aix53.h b/gcc/config/rs6000/aix53.h
index b1b0759e7ff..b3bd73a6988 100644
--- a/gcc/config/rs6000/aix53.h
+++ b/gcc/config/rs6000/aix53.h
@@ -166,10 +166,6 @@ do { \
#undef LD_INIT_SWITCH
#define LD_INIT_SWITCH "-binitfini"
-/* AIX 5.2 has the float and long double forms of math functions. */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
-
#ifndef _AIX52
extern long long int atoll(const char *);
#endif
diff --git a/gcc/config/rs6000/aix61.h b/gcc/config/rs6000/aix61.h
index cd341b97eea..b0778143773 100644
--- a/gcc/config/rs6000/aix61.h
+++ b/gcc/config/rs6000/aix61.h
@@ -190,10 +190,6 @@ do { \
#undef LD_INIT_SWITCH
#define LD_INIT_SWITCH "-binitfini"
-/* AIX 5.2 has the float and long double forms of math functions. */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
-
#ifndef _AIX52
extern long long int atoll(const char *);
#endif
diff --git a/gcc/config/rs6000/darwin.h b/gcc/config/rs6000/darwin.h
index 0cf2f4c346d..d5919c4c71d 100644
--- a/gcc/config/rs6000/darwin.h
+++ b/gcc/config/rs6000/darwin.h
@@ -386,10 +386,8 @@ extern int darwin_emit_branch_islands;
#define OFFS_ASSIGNIVAR_FAST 0xFFFEFEC0
/* Old versions of Mac OS/Darwin don't have C99 functions available. */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS \
- (TARGET_64BIT \
- || strverscmp (darwin_macosx_version_min, "10.3") >= 0)
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION darwin_libc_has_function
/* When generating kernel code or kexts, we don't use Altivec by
default, as kernel code doesn't save/restore those registers. */
diff --git a/gcc/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md
index 052ac482e0f..9a846239b04 100644
--- a/gcc/config/rs6000/dfp.md
+++ b/gcc/config/rs6000/dfp.md
@@ -132,11 +132,14 @@
"")
(define_insn "*negtd2_fpr"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (neg:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
+ [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
+ (neg:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
- "fneg %0,%1"
- [(set_attr "type" "fp")])
+ "@
+ fneg %0,%1
+ fneg %0,%1\;fmr %L0,%L1"
+ [(set_attr "type" "fp")
+ (set_attr "length" "4,8")])
(define_expand "abstd2"
[(set (match_operand:TD 0 "gpc_reg_operand" "")
@@ -145,18 +148,24 @@
"")
(define_insn "*abstd2_fpr"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d")))]
+ [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
+ (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d")))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
- "fabs %0,%1"
- [(set_attr "type" "fp")])
+ "@
+ fabs %0,%1
+ fabs %0,%1\;fmr %L0,%L1"
+ [(set_attr "type" "fp")
+ (set_attr "length" "4,8")])
(define_insn "*nabstd2_fpr"
- [(set (match_operand:TD 0 "gpc_reg_operand" "=d")
- (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "d"))))]
+ [(set (match_operand:TD 0 "gpc_reg_operand" "=d,d")
+ (neg:TD (abs:TD (match_operand:TD 1 "gpc_reg_operand" "0,d"))))]
"TARGET_HARD_FLOAT && TARGET_FPRS"
- "fnabs %0,%1"
- [(set_attr "type" "fp")])
+ "@
+ fnabs %0,%1
+ fnabs %0,%1\;fmr %L0,%L1"
+ [(set_attr "type" "fp")
+ (set_attr "length" "4,8")])
;; Hardware support for decimal floating point operations.
diff --git a/gcc/config/rs6000/linux.h b/gcc/config/rs6000/linux.h
index f7f2d80c4f2..2e5a56b3929 100644
--- a/gcc/config/rs6000/linux.h
+++ b/gcc/config/rs6000/linux.h
@@ -28,17 +28,18 @@
#ifdef SINGLE_LIBC
#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
+#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
+#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
#else
#define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
+#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
+#define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
#endif
-/* glibc has float and long double forms of math functions. */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension. */
-#undef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+ this includes full c99 runtime and sincos. */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
diff --git a/gcc/config/rs6000/linux64.h b/gcc/config/rs6000/linux64.h
index 79f0f0b5f00..439f53f2d23 100644
--- a/gcc/config/rs6000/linux64.h
+++ b/gcc/config/rs6000/linux64.h
@@ -288,17 +288,18 @@ extern int dot_symbols;
#ifdef SINGLE_LIBC
#define OPTION_GLIBC (DEFAULT_LIBC == LIBC_GLIBC)
+#define OPTION_UCLIBC (DEFAULT_LIBC == LIBC_UCLIBC)
+#define OPTION_BIONIC (DEFAULT_LIBC == LIBC_BIONIC)
#else
#define OPTION_GLIBC (linux_libc == LIBC_GLIBC)
+#define OPTION_UCLIBC (linux_libc == LIBC_UCLIBC)
+#define OPTION_BIONIC (linux_libc == LIBC_BIONIC)
#endif
-/* glibc has float and long double forms of math functions. */
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS (OPTION_GLIBC)
-
-/* Whether we have sincos that follows the GNU extension. */
-#undef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS (OPTION_GLIBC)
+/* Determine what functions are present at the runtime;
+ this includes full c99 runtime and sincos. */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION linux_android_libc_has_function
#undef TARGET_OS_CPP_BUILTINS
#define TARGET_OS_CPP_BUILTINS() \
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 18912f15a4a..7338e764c5c 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1702,3 +1702,99 @@
return GET_CODE (op) == UNSPEC && XINT (op, 1) == UNSPEC_TOCREL;
})
+
+;; Match the first insn (addis) in fusing the combination of addis and loads to
+;; GPR registers on power8.
+(define_predicate "fusion_gpr_addis"
+ (match_code "const_int,high,plus")
+{
+ HOST_WIDE_INT value;
+ rtx int_const;
+
+ if (GET_CODE (op) == HIGH)
+ return 1;
+
+ if (CONST_INT_P (op))
+ int_const = op;
+
+ else if (GET_CODE (op) == PLUS
+ && base_reg_operand (XEXP (op, 0), Pmode)
+ && CONST_INT_P (XEXP (op, 1)))
+ int_const = XEXP (op, 1);
+
+ else
+ return 0;
+
+ /* Power8 currently will only do the fusion if the top 11 bits of the addis
+ value are all 1's or 0's. */
+ value = INTVAL (int_const);
+ if ((value & (HOST_WIDE_INT)0xffff) != 0)
+ return 0;
+
+ if ((value & (HOST_WIDE_INT)0xffff0000) == 0)
+ return 0;
+
+ return (IN_RANGE (value >> 16, -32, 31));
+})
+
+;; Match the second insn (lbz, lhz, lwz, ld) in fusing the combination of addis
+;; and loads to GPR registers on power8.
+(define_predicate "fusion_gpr_mem_load"
+ (match_code "mem,sign_extend,zero_extend")
+{
+ rtx addr;
+
+ /* Handle sign/zero extend. */
+ if (GET_CODE (op) == ZERO_EXTEND
+ || (TARGET_P8_FUSION_SIGN && GET_CODE (op) == SIGN_EXTEND))
+ {
+ op = XEXP (op, 0);
+ mode = GET_MODE (op);
+ }
+
+ if (!MEM_P (op))
+ return 0;
+
+ switch (mode)
+ {
+ case QImode:
+ case HImode:
+ case SImode:
+ break;
+
+ case DImode:
+ if (!TARGET_POWERPC64)
+ return 0;
+ break;
+
+ default:
+ return 0;
+ }
+
+ addr = XEXP (op, 0);
+ if (GET_CODE (addr) == PLUS)
+ {
+ rtx base = XEXP (addr, 0);
+ rtx offset = XEXP (addr, 1);
+
+ return (base_reg_operand (base, GET_MODE (base))
+ && satisfies_constraint_I (offset));
+ }
+
+ else if (GET_CODE (addr) == LO_SUM)
+ {
+ rtx base = XEXP (addr, 0);
+ rtx offset = XEXP (addr, 1);
+
+ if (!base_reg_operand (base, GET_MODE (base)))
+ return 0;
+
+ else if (TARGET_XCOFF || (TARGET_ELF && TARGET_POWERPC64))
+ return small_toc_ref (offset, GET_MODE (offset));
+
+ else if (TARGET_ELF && !TARGET_POWERPC64)
+ return CONSTANT_P (offset);
+ }
+
+ return 0;
+})
diff --git a/gcc/config/rs6000/rs6000-modes.def b/gcc/config/rs6000/rs6000-modes.def
index 54548be7038..5124e1665d4 100644
--- a/gcc/config/rs6000/rs6000-modes.def
+++ b/gcc/config/rs6000/rs6000-modes.def
@@ -42,5 +42,7 @@ VECTOR_MODES (FLOAT, 8); /* V4HF V2SF */
VECTOR_MODES (FLOAT, 16); /* V8HF V4SF V2DF */
VECTOR_MODES (FLOAT, 32); /* V16HF V8SF V4DF */
-/* Replacement for TImode that only is allowed in GPRs. */
+/* Replacement for TImode that only is allowed in GPRs. We also use PTImode
+ for quad memory atomic operations to force getting an even/odd register
+ combination. */
PARTIAL_INT_MODE (TI);
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 3a7b37a8270..3ddabb81c39 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -73,6 +73,9 @@ extern int mems_ok_for_quad_peep (rtx, rtx);
extern bool gpr_or_gpr_p (rtx, rtx);
extern bool direct_move_p (rtx, rtx);
extern bool quad_load_store_p (rtx, rtx);
+extern bool fusion_gpr_load_p (rtx *, bool);
+extern void expand_fusion_gpr_load (rtx *);
+extern const char *emit_fusion_gpr_load (rtx *);
extern enum reg_class (*rs6000_preferred_reload_class_ptr) (rtx,
enum reg_class);
extern enum reg_class (*rs6000_secondary_reload_class_ptr) (enum reg_class,
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8b939d8e826..c1acbd825ea 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -284,9 +284,6 @@ static struct
{ "rsqrtd", (RECIP_DF_RSQRT | RECIP_V2DF_RSQRT) },
};
-/* 2 argument gen function typedef. */
-typedef rtx (*gen_2arg_fn_t) (rtx, rtx, rtx);
-
/* Pointer to function (in rs6000-c.c) that can define or undefine target
macros that have changed. Languages that don't support the preprocessor
don't link in rs6000-c.c, so we can't call it directly. */
@@ -3074,6 +3071,21 @@ rs6000_option_override_internal (bool global_init_p)
rs6000_isa_flags &= ~OPTION_MASK_QUAD_MEMORY;
}
+ /* Enable power8 fusion if we are tuning for power8, even if we aren't
+ generating power8 instructions. */
+ if (!(rs6000_isa_flags_explicit & OPTION_MASK_P8_FUSION))
+ rs6000_isa_flags |= (processor_target_table[tune_index].target_enable
+ & OPTION_MASK_P8_FUSION);
+
+ /* Power8 does not fuse sign extended loads with the addis. If we are
+ optimizing at high levels for speed, convert a sign extended load into a
+ zero extending load, and an explicit sign extension. */
+ if (TARGET_P8_FUSION
+ && !(rs6000_isa_flags_explicit & OPTION_MASK_P8_FUSION_SIGN)
+ && optimize_function_for_speed_p (cfun)
+ && optimize >= 3)
+ rs6000_isa_flags |= OPTION_MASK_P8_FUSION_SIGN;
+
if (TARGET_DEBUG_REG || TARGET_DEBUG_TARGET)
rs6000_print_isa_options (stderr, 0, "after defaults", rs6000_isa_flags);
@@ -6918,9 +6930,7 @@ rs6000_legitimize_reload_address (rtx x, enum machine_mode mode,
&& GET_CODE (XEXP (x, 1)) == CONST_INT
&& reg_offset_p
&& !SPE_VECTOR_MODE (mode)
- && !(TARGET_E500_DOUBLE && (mode == DFmode || mode == TFmode
- || mode == DDmode || mode == TDmode
- || mode == DImode))
+ && !(TARGET_E500_DOUBLE && GET_MODE_SIZE (mode) > UNITS_PER_WORD)
&& (!VECTOR_MODE_P (mode) || VECTOR_MEM_NONE_P (mode)))
{
HOST_WIDE_INT val = INTVAL (XEXP (x, 1));
@@ -8329,8 +8339,8 @@ rs6000_function_arg_boundary (enum machine_mode mode, const_tree type)
|| (type && TREE_CODE (type) == VECTOR_TYPE
&& int_size_in_bytes (type) >= 16))
return 128;
- else if (TARGET_MACHO
- && rs6000_darwin64_abi
+ else if (((TARGET_MACHO && rs6000_darwin64_abi)
+ || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
&& mode == BLKmode
&& type && TYPE_ALIGN (type) > 64)
return 128;
@@ -9878,8 +9888,9 @@ rs6000_gimplify_va_arg (tree valist, tree type, gimple_seq *pre_p,
We don't need to check for pass-by-reference because of the test above.
We can return a simplifed answer, since we know there's no offset to add. */
- if (TARGET_MACHO
- && rs6000_darwin64_abi
+ if (((TARGET_MACHO
+ && rs6000_darwin64_abi)
+ || (DEFAULT_ABI == ABI_AIX && !rs6000_compat_align_parm))
&& integer_zerop (TYPE_SIZE (type)))
{
unsigned HOST_WIDE_INT align, boundary;
@@ -11133,9 +11144,6 @@ htm_expand_builtin (tree exp, rtx target, bool * expandedp)
switch (nopnds)
{
- case 0:
- pat = GEN_FCN (icode) (NULL_RTX);
- break;
case 1:
pat = GEN_FCN (icode) (op[0]);
break;
@@ -21401,8 +21409,7 @@ rs6000_emit_prologue (void)
HOST_WIDE_INT offset;
if (!(strategy & SAVE_INLINE_GPRS))
- ool_adjust = 8 * (info->first_gp_reg_save
- - (FIRST_SAVRES_REGISTER + 1));
+ ool_adjust = 8 * (info->first_gp_reg_save - FIRST_SAVED_GP_REGNO);
offset = info->spe_gp_save_offset + frame_off - ool_adjust;
spe_save_area_ptr = gen_rtx_REG (Pmode, 11);
save_off = frame_off - offset;
@@ -22644,8 +22651,7 @@ rs6000_emit_epilogue (int sibcall)
anew to every function. */
if (!restoring_GPRs_inline)
- ool_adjust = 8 * (info->first_gp_reg_save
- - (FIRST_SAVRES_REGISTER + 1));
+ ool_adjust = 8 * (info->first_gp_reg_save - FIRST_SAVED_GP_REGNO);
frame_reg_rtx = gen_rtx_REG (Pmode, 11);
emit_insn (gen_addsi3 (frame_reg_rtx, old_frame_reg_rtx,
GEN_INT (info->spe_gp_save_offset
@@ -28127,7 +28133,7 @@ rs6000_emit_swdiv (rtx dst, rtx n, rtx d, bool note_p)
passes++;
enum insn_code code = optab_handler (smul_optab, mode);
- gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
+ insn_gen_fn gen_mul = GEN_FCN (code);
gcc_assert (code != CODE_FOR_nothing);
@@ -28205,7 +28211,7 @@ rs6000_emit_swrsqrt (rtx dst, rtx src)
int i;
rtx halfthree;
enum insn_code code = optab_handler (smul_optab, mode);
- gen_2arg_fn_t gen_mul = (gen_2arg_fn_t) GEN_FCN (code);
+ insn_gen_fn gen_mul = GEN_FCN (code);
gcc_assert (code != CODE_FOR_nothing);
@@ -30419,6 +30425,382 @@ rs6000_split_logical (rtx operands[3],
}
+/* Return true if the peephole2 can combine a load involving a combination of
+ an addis instruction and a load with an offset that can be fused together on
+ a power8.
+
+ The operands are:
+ operands[0] register set with addis
+ operands[1] value set via addis
+ operands[2] target register being loaded
+ operands[3] D-form memory reference using operands[0].
+
+ In addition, we are passed a boolean that is true if this is a peephole2,
+ and we can use see if the addis_reg is dead after the insn and can be
+ replaced by the target register. */
+
+bool
+fusion_gpr_load_p (rtx *operands, bool peep2_p)
+{
+ rtx addis_reg = operands[0];
+ rtx addis_value = operands[1];
+ rtx target = operands[2];
+ rtx mem = operands[3];
+ rtx addr;
+ rtx base_reg;
+
+ /* Validate arguments. */
+ if (!base_reg_operand (addis_reg, GET_MODE (addis_reg)))
+ return false;
+
+ if (!base_reg_operand (target, GET_MODE (target)))
+ return false;
+
+ if (!fusion_gpr_addis (addis_value, GET_MODE (addis_value)))
+ return false;
+
+ if (!fusion_gpr_mem_load (mem, GET_MODE (mem)))
+ return false;
+
+ /* Allow sign/zero extension. */
+ if (GET_CODE (mem) == ZERO_EXTEND
+ || (GET_CODE (mem) == SIGN_EXTEND && TARGET_P8_FUSION_SIGN))
+ mem = XEXP (mem, 0);
+
+ if (!MEM_P (mem))
+ return false;
+
+ addr = XEXP (mem, 0); /* either PLUS or LO_SUM. */
+ if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
+ return false;
+
+ /* Validate that the register used to load the high value is either the
+ register being loaded, or we can safely replace its use in a peephole2.
+
+ If this is a peephole2, we assume that there are 2 instructions in the
+ peephole (addis and load), so we want to check if the target register was
+ not used in the memory address and the register to hold the addis result
+ is dead after the peephole. */
+ if (REGNO (addis_reg) != REGNO (target))
+ {
+ if (!peep2_p)
+ return false;
+
+ if (reg_mentioned_p (target, mem))
+ return false;
+
+ if (!peep2_reg_dead_p (2, addis_reg))
+ return false;
+ }
+
+ base_reg = XEXP (addr, 0);
+ return REGNO (addis_reg) == REGNO (base_reg);
+}
+
+/* During the peephole2 pass, adjust and expand the insns for a load fusion
+ sequence. We adjust the addis register to use the target register. If the
+ load sign extends, we adjust the code to do the zero extending load, and an
+ explicit sign extension later since the fusion only covers zero extending
+ loads.
+
+ The operands are:
+ operands[0] register set with addis (to be replaced with target)
+ operands[1] value set via addis
+ operands[2] target register being loaded
+ operands[3] D-form memory reference using operands[0]. */
+
+void
+expand_fusion_gpr_load (rtx *operands)
+{
+ rtx addis_value = operands[1];
+ rtx target = operands[2];
+ rtx orig_mem = operands[3];
+ rtx new_addr, new_mem, orig_addr, offset;
+ enum rtx_code plus_or_lo_sum;
+ enum machine_mode target_mode = GET_MODE (target);
+ enum machine_mode extend_mode = target_mode;
+ enum machine_mode ptr_mode = Pmode;
+ enum rtx_code extend = UNKNOWN;
+ rtx addis_reg = ((ptr_mode == target_mode)
+ ? target
+ : simplify_subreg (ptr_mode, target, target_mode, 0));
+
+ if (GET_CODE (orig_mem) == ZERO_EXTEND
+ || (TARGET_P8_FUSION_SIGN && GET_CODE (orig_mem) == SIGN_EXTEND))
+ {
+ extend = GET_CODE (orig_mem);
+ orig_mem = XEXP (orig_mem, 0);
+ target_mode = GET_MODE (orig_mem);
+ }
+
+ gcc_assert (MEM_P (orig_mem));
+
+ orig_addr = XEXP (orig_mem, 0);
+ plus_or_lo_sum = GET_CODE (orig_addr);
+ gcc_assert (plus_or_lo_sum == PLUS || plus_or_lo_sum == LO_SUM);
+
+ offset = XEXP (orig_addr, 1);
+ new_addr = gen_rtx_fmt_ee (plus_or_lo_sum, ptr_mode, addis_reg, offset);
+ new_mem = change_address (orig_mem, target_mode, new_addr);
+
+ if (extend != UNKNOWN)
+ new_mem = gen_rtx_fmt_e (ZERO_EXTEND, extend_mode, new_mem);
+
+ emit_insn (gen_rtx_SET (VOIDmode, addis_reg, addis_value));
+ emit_insn (gen_rtx_SET (VOIDmode, target, new_mem));
+
+ if (extend == SIGN_EXTEND)
+ {
+ int sub_off = ((BYTES_BIG_ENDIAN)
+ ? GET_MODE_SIZE (extend_mode) - GET_MODE_SIZE (target_mode)
+ : 0);
+ rtx sign_reg
+ = simplify_subreg (target_mode, target, extend_mode, sub_off);
+
+ emit_insn (gen_rtx_SET (VOIDmode, target,
+ gen_rtx_SIGN_EXTEND (extend_mode, sign_reg)));
+ }
+
+ return;
+}
+
+/* Return a string to fuse an addis instruction with a gpr load to the same
+ register that we loaded up the addis instruction. The code is complicated,
+ so we call output_asm_insn directly, and just return "".
+
+ The operands are:
+ operands[0] register set with addis (must be same reg as target).
+ operands[1] value set via addis
+ operands[2] target register being loaded
+ operands[3] D-form memory reference using operands[0]. */
+
+const char *
+emit_fusion_gpr_load (rtx *operands)
+{
+ rtx addis_reg = operands[0];
+ rtx addis_value = operands[1];
+ rtx target = operands[2];
+ rtx mem = operands[3];
+ rtx fuse_ops[10];
+ rtx addr;
+ rtx load_offset;
+ const char *addis_str = NULL;
+ const char *load_str = NULL;
+ const char *extend_insn = NULL;
+ const char *mode_name = NULL;
+ char insn_template[80];
+ enum machine_mode mode;
+ const char *comment_str = ASM_COMMENT_START;
+ bool sign_p = false;
+
+ gcc_assert (REG_P (addis_reg) && REG_P (target));
+ gcc_assert (REGNO (addis_reg) == REGNO (target));
+
+ if (*comment_str == ' ')
+ comment_str++;
+
+ /* Allow sign/zero extension. */
+ if (GET_CODE (mem) == ZERO_EXTEND)
+ mem = XEXP (mem, 0);
+
+ else if (GET_CODE (mem) == SIGN_EXTEND && TARGET_P8_FUSION_SIGN)
+ {
+ sign_p = true;
+ mem = XEXP (mem, 0);
+ }
+
+ gcc_assert (MEM_P (mem));
+ addr = XEXP (mem, 0);
+ if (GET_CODE (addr) != PLUS && GET_CODE (addr) != LO_SUM)
+ gcc_unreachable ();
+
+ load_offset = XEXP (addr, 1);
+
+ /* Now emit the load instruction to the same register. */
+ mode = GET_MODE (mem);
+ switch (mode)
+ {
+ case QImode:
+ mode_name = "char";
+ load_str = "lbz";
+ extend_insn = "extsb %0,%0";
+ break;
+
+ case HImode:
+ mode_name = "short";
+ load_str = "lhz";
+ extend_insn = "extsh %0,%0";
+ break;
+
+ case SImode:
+ mode_name = "int";
+ load_str = "lwz";
+ extend_insn = "extsw %0,%0";
+ break;
+
+ case DImode:
+ if (TARGET_POWERPC64)
+ {
+ mode_name = "long";
+ load_str = "ld";
+ }
+ else
+ gcc_unreachable ();
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+
+ /* Emit the addis instruction. */
+ fuse_ops[0] = target;
+ if (satisfies_constraint_L (addis_value))
+ {
+ fuse_ops[1] = addis_value;
+ addis_str = "lis %0,%v1";
+ }
+
+ else if (GET_CODE (addis_value) == PLUS)
+ {
+ rtx op0 = XEXP (addis_value, 0);
+ rtx op1 = XEXP (addis_value, 1);
+
+ if (REG_P (op0) && CONST_INT_P (op1)
+ && satisfies_constraint_L (op1))
+ {
+ fuse_ops[1] = op0;
+ fuse_ops[2] = op1;
+ addis_str = "addis %0,%1,%v2";
+ }
+ }
+
+ else if (GET_CODE (addis_value) == HIGH)
+ {
+ rtx value = XEXP (addis_value, 0);
+ if (GET_CODE (value) == UNSPEC && XINT (value, 1) == UNSPEC_TOCREL)
+ {
+ fuse_ops[1] = XVECEXP (value, 0, 0); /* symbol ref. */
+ fuse_ops[2] = XVECEXP (value, 0, 1); /* TOC register. */
+ if (TARGET_ELF)
+ addis_str = "addis %0,%2,%1@toc@ha";
+
+ else if (TARGET_XCOFF)
+ addis_str = "addis %0,%1@u(%2)";
+
+ else
+ gcc_unreachable ();
+ }
+
+ else if (GET_CODE (value) == PLUS)
+ {
+ rtx op0 = XEXP (value, 0);
+ rtx op1 = XEXP (value, 1);
+
+ if (GET_CODE (op0) == UNSPEC
+ && XINT (op0, 1) == UNSPEC_TOCREL
+ && CONST_INT_P (op1))
+ {
+ fuse_ops[1] = XVECEXP (op0, 0, 0); /* symbol ref. */
+ fuse_ops[2] = XVECEXP (op0, 0, 1); /* TOC register. */
+ fuse_ops[3] = op1;
+ if (TARGET_ELF)
+ addis_str = "addis %0,%2,%1+%3@toc@ha";
+
+ else if (TARGET_XCOFF)
+ addis_str = "addis %0,%1+%3@u(%2)";
+
+ else
+ gcc_unreachable ();
+ }
+ }
+
+ else if (satisfies_constraint_L (value))
+ {
+ fuse_ops[1] = value;
+ addis_str = "lis %0,%v1";
+ }
+
+ else if (TARGET_ELF && !TARGET_POWERPC64 && CONSTANT_P (value))
+ {
+ fuse_ops[1] = value;
+ addis_str = "lis %0,%1@ha";
+ }
+ }
+
+ if (!addis_str)
+ fatal_insn ("Could not generate addis value for fusion", addis_value);
+
+ sprintf (insn_template, "%s\t\t%s gpr load fusion, type %s", addis_str,
+ comment_str, mode_name);
+ output_asm_insn (insn_template, fuse_ops);
+
+ /* Emit the D-form load instruction. */
+ if (CONST_INT_P (load_offset) && satisfies_constraint_I (load_offset))
+ {
+ sprintf (insn_template, "%s %%0,%%1(%%0)", load_str);
+ fuse_ops[1] = load_offset;
+ output_asm_insn (insn_template, fuse_ops);
+ }
+
+ else if (GET_CODE (load_offset) == UNSPEC
+ && XINT (load_offset, 1) == UNSPEC_TOCREL)
+ {
+ if (TARGET_ELF)
+ sprintf (insn_template, "%s %%0,%%1@toc@l(%%0)", load_str);
+
+ else if (TARGET_XCOFF)
+ sprintf (insn_template, "%s %%0,%%1@l(%%0)", load_str);
+
+ else
+ gcc_unreachable ();
+
+ fuse_ops[1] = XVECEXP (load_offset, 0, 0);
+ output_asm_insn (insn_template, fuse_ops);
+ }
+
+ else if (GET_CODE (load_offset) == PLUS
+ && GET_CODE (XEXP (load_offset, 0)) == UNSPEC
+ && XINT (XEXP (load_offset, 0), 1) == UNSPEC_TOCREL
+ && CONST_INT_P (XEXP (load_offset, 1)))
+ {
+ rtx tocrel_unspec = XEXP (load_offset, 0);
+ if (TARGET_ELF)
+ sprintf (insn_template, "%s %%0,%%1+%%2@toc@l(%%0)", load_str);
+
+ else if (TARGET_XCOFF)
+ sprintf (insn_template, "%s %%0,%%1+%%2@l(%%0)", load_str);
+
+ else
+ gcc_unreachable ();
+
+ fuse_ops[1] = XVECEXP (tocrel_unspec, 0, 0);
+ fuse_ops[2] = XEXP (load_offset, 1);
+ output_asm_insn (insn_template, fuse_ops);
+ }
+
+ else if (TARGET_ELF && !TARGET_POWERPC64 && CONSTANT_P (load_offset))
+ {
+ sprintf (insn_template, "%s %%0,%%1@l(%%0)", load_str);
+
+ fuse_ops[1] = load_offset;
+ output_asm_insn (insn_template, fuse_ops);
+ }
+
+ else
+ fatal_insn ("Unable to generate load offset for fusion", load_offset);
+
+ /* Handle sign extension. The peephole2 pass generates this as a separate
+ insn, but we handle it just in case it got reattached. */
+ if (sign_p)
+ {
+ gcc_assert (extend_insn != NULL);
+ output_asm_insn (extend_insn, fuse_ops);
+ }
+
+ return "";
+}
+
+
struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-rs6000.h"
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index e5a6abd6d0d..a5a7a859426 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -1498,7 +1498,8 @@ extern enum reg_class rs6000_constraints[RS6000_CONSTRAINT_MAX];
On the RS/6000, we grow upwards, from the area after the outgoing
arguments. */
-#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0 || flag_asan != 0)
+#define FRAME_GROWS_DOWNWARD (flag_stack_protect != 0 \
+ || (flag_sanitize & SANITIZE_ADDRESS) != 0)
/* Size of the outgoing register save area */
#define RS6000_REG_SAVE ((DEFAULT_ABI == ABI_AIX \
@@ -2138,9 +2139,15 @@ extern int toc_initialized;
} \
else if (TARGET_XCOFF) \
{ \
- fputs ("\t.lglobl\t.", FILE); \
- RS6000_OUTPUT_BASENAME (FILE, alias); \
- putc ('\n', FILE); \
+ if (!RS6000_WEAK || !DECL_WEAK (DECL)) \
+ { \
+ fputs ("\t.lglobl\t.", FILE); \
+ RS6000_OUTPUT_BASENAME (FILE, alias); \
+ putc ('\n', FILE); \
+ fputs ("\t.lglobl\t", FILE); \
+ RS6000_OUTPUT_BASENAME (FILE, alias); \
+ putc ('\n', FILE); \
+ } \
} \
fputs ("\t.set\t.", FILE); \
RS6000_OUTPUT_BASENAME (FILE, alias); \
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index 064a51da608..3880f9175a2 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -136,7 +136,6 @@
UNSPEC_P8V_MTVSRD
UNSPEC_P8V_XXPERMDI
UNSPEC_P8V_RELOAD_FROM_VSX
- UNSPEC_FUSION_GPR
])
;;
@@ -15757,7 +15756,8 @@
"cmpw %2,%L0,%1\;"
"bne- %2,$-16";
}
-})
+}
+ [(set_attr "length" "20")])
(define_insn "rs6000_mftb_<mode>"
[(set (match_operand:P 0 "gpc_reg_operand" "=r")
@@ -15771,6 +15771,43 @@
})
+;; Power8 fusion support for fusing an addis instruction with a D-form load of
+;; a GPR. The addis instruction must be adjacent to the load, and use the same
+;; register that is being loaded. The fused ops must be physically adjacent.
+
+;; We use define_peephole for the actual addis/load, and the register used to
+;; hold the addis value must be the same as the register being loaded. We use
+;; define_peephole2 to change the register used for addis to be the register
+;; being loaded, since we can look at whether it is dead after the load insn.
+
+(define_peephole
+ [(set (match_operand:P 0 "base_reg_operand" "")
+ (match_operand:P 1 "fusion_gpr_addis" ""))
+ (set (match_operand:INT1 2 "base_reg_operand" "")
+ (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
+ "TARGET_P8_FUSION && fusion_gpr_load_p (operands, false)"
+{
+ return emit_fusion_gpr_load (operands);
+}
+ [(set_attr "type" "load")
+ (set_attr "length" "8")])
+
+(define_peephole2
+ [(set (match_operand:P 0 "base_reg_operand" "")
+ (match_operand:P 1 "fusion_gpr_addis" ""))
+ (set (match_operand:INT1 2 "base_reg_operand" "")
+ (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
+ "TARGET_P8_FUSION
+ && (REGNO (operands[0]) != REGNO (operands[2])
+ || GET_CODE (operands[3]) == SIGN_EXTEND)
+ && fusion_gpr_load_p (operands, true)"
+ [(const_int 0)]
+{
+ expand_fusion_gpr_load (operands);
+ DONE;
+})
+
+
(include "sync.md")
(include "vector.md")
diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt
index f36e4758031..cd83cb2d206 100644
--- a/gcc/config/rs6000/rs6000.opt
+++ b/gcc/config/rs6000/rs6000.opt
@@ -546,3 +546,7 @@ Use ISA 2.07 transactional memory (HTM) instructions
mquad-memory
Target Report Mask(QUAD_MEMORY) Var(rs6000_isa_flags)
Generate the quad word memory instructions (lq/stq/lqarx/stqcx).
+
+mcompat-align-parm
+Target Report Var(rs6000_compat_align_parm) Init(0) Save
+Generate aggregate parameter passing code with at most 64-bit alignment.
diff --git a/gcc/config/rs6000/rtems.h b/gcc/config/rs6000/rtems.h
index b910b5ec5a2..fb22be1e8bb 100644
--- a/gcc/config/rs6000/rtems.h
+++ b/gcc/config/rs6000/rtems.h
@@ -34,6 +34,9 @@
} \
while (0)
+#undef TARGET_LIBGCC_SDATA_SECTION
+#define TARGET_LIBGCC_SDATA_SECTION ".sdata"
+
#undef CPP_OS_DEFAULT_SPEC
#define CPP_OS_DEFAULT_SPEC "%(cpp_os_rtems)"
diff --git a/gcc/config/rs6000/t-linux64 b/gcc/config/rs6000/t-linux64
index 9175de2ffe3..70e928dd7cd 100644
--- a/gcc/config/rs6000/t-linux64
+++ b/gcc/config/rs6000/t-linux64
@@ -25,8 +25,8 @@
# it doesn't tell anything about the 32bit libraries on those systems. Set
# MULTILIB_OSDIRNAMES according to what is found on the target.
-MULTILIB_OPTIONS = m64/m32
-MULTILIB_DIRNAMES = 64 32
-MULTILIB_EXTRA_OPTS = fPIC
-MULTILIB_OSDIRNAMES = ../lib64$(call if_multiarch,:powerpc64-linux-gnu)
-MULTILIB_OSDIRNAMES += $(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
+MULTILIB_OPTIONS := m64/m32
+MULTILIB_DIRNAMES := 64 32
+MULTILIB_EXTRA_OPTS :=
+MULTILIB_OSDIRNAMES := m64=../lib64$(call if_multiarch,:powerpc64-linux-gnu)
+MULTILIB_OSDIRNAMES += m32=$(if $(wildcard $(shell echo $(SYSTEM_HEADER_DIR))/../../usr/lib32),../lib32,../lib)$(call if_multiarch,:powerpc-linux-gnu)
diff --git a/gcc/config/rs6000/t-linux64bele b/gcc/config/rs6000/t-linux64bele
new file mode 100644
index 00000000000..97c1ee6fb4d
--- /dev/null
+++ b/gcc/config/rs6000/t-linux64bele
@@ -0,0 +1,7 @@
+#rs6000/t-linux64end
+
+MULTILIB_OPTIONS += mlittle
+MULTILIB_DIRNAMES += le
+MULTILIB_OSDIRNAMES += $(subst =,.mlittle=,$(subst lible32,lib32le,$(subst lible64,lib64le,$(subst lib,lible,$(subst -linux,le-linux,$(MULTILIB_OSDIRNAMES))))))
+MULTILIB_OSDIRNAMES += $(subst $(if $(findstring 64,$(target)),m64,m32).,,$(filter $(if $(findstring 64,$(target)),m64,m32).mlittle%,$(MULTILIB_OSDIRNAMES)))
+MULTILIB_MATCHES := ${MULTILIB_MATCHES_ENDIAN}
diff --git a/gcc/config/rs6000/t-linux64le b/gcc/config/rs6000/t-linux64le
new file mode 100644
index 00000000000..0cf38e1523a
--- /dev/null
+++ b/gcc/config/rs6000/t-linux64le
@@ -0,0 +1,3 @@
+#rs6000/t-linux64le
+
+MULTILIB_OSDIRNAMES := $(subst -linux,le-linux,$(MULTILIB_OSDIRNAMES))
diff --git a/gcc/config/rs6000/t-linux64lebe b/gcc/config/rs6000/t-linux64lebe
new file mode 100644
index 00000000000..2e63bdb9fc9
--- /dev/null
+++ b/gcc/config/rs6000/t-linux64lebe
@@ -0,0 +1,7 @@
+#rs6000/t-linux64leend
+
+MULTILIB_OPTIONS += mbig
+MULTILIB_DIRNAMES += be
+MULTILIB_OSDIRNAMES += $(subst =,.mbig=,$(subst libbe32,lib32be,$(subst libbe64,lib64be,$(subst lib,libbe,$(subst le-linux,-linux,$(MULTILIB_OSDIRNAMES))))))
+MULTILIB_OSDIRNAMES += $(subst $(if $(findstring 64,$(target)),m64,m32).,,$(filter $(if $(findstring 64,$(target)),m64,m32).mbig%,$(MULTILIB_OSDIRNAMES)))
+MULTILIB_MATCHES := ${MULTILIB_MATCHES_ENDIAN}
diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md
index 5e6f397031c..11d6b8bb4d0 100644
--- a/gcc/config/rs6000/vsx.md
+++ b/gcc/config/rs6000/vsx.md
@@ -40,6 +40,14 @@
;; it to use gprs as well as vsx registers.
(define_mode_iterator VSX_M [V16QI V8HI V4SI V2DI V4SF V2DF])
+(define_mode_iterator VSX_M2 [V16QI
+ V8HI
+ V4SI
+ V2DI
+ V4SF
+ V2DF
+ (TI "TARGET_VSX_TIMODE")])
+
;; Map into the appropriate load/store name based on the type
(define_mode_attr VSm [(V16QI "vw4")
(V8HI "vw4")
@@ -1446,3 +1454,27 @@
}"
[(set_attr "length" "20")
(set_attr "type" "veccomplex")])
+
+
+;; Power8 Vector fusion. The fused ops must be physically adjacent.
+(define_peephole
+ [(set (match_operand:P 0 "base_reg_operand" "")
+ (match_operand:P 1 "short_cint_operand" ""))
+ (set (match_operand:VSX_M2 2 "vsx_register_operand" "")
+ (mem:VSX_M2 (plus:P (match_dup 0)
+ (match_operand:P 3 "int_reg_operand" ""))))]
+ "TARGET_P8_FUSION"
+ "li %0,%1\t\t\t# vector load fusion\;lx<VSX_M2:VSm>x %x2,%0,%3"
+ [(set_attr "length" "8")
+ (set_attr "type" "vecload")])
+
+(define_peephole
+ [(set (match_operand:P 0 "base_reg_operand" "")
+ (match_operand:P 1 "short_cint_operand" ""))
+ (set (match_operand:VSX_M2 2 "vsx_register_operand" "")
+ (mem:VSX_M2 (plus:P (match_operand:P 3 "int_reg_operand" "")
+ (match_dup 0))))]
+ "TARGET_P8_FUSION"
+ "li %0,%1\t\t\t# vector load fusion\;lx<VSX_M2:VSm>x %x2,%0,%3"
+ [(set_attr "length" "8")
+ (set_attr "type" "vecload")])
diff --git a/gcc/config/rx/rx.c b/gcc/config/rx/rx.c
index b163a593721..603e49de3ab 100644
--- a/gcc/config/rx/rx.c
+++ b/gcc/config/rx/rx.c
@@ -1021,9 +1021,9 @@ rx_gen_move_template (rtx * operands, bool is_movu)
gcc_assert (! is_movu);
if (REG_P (src) && REG_P (dest) && (REGNO (dest) == REGNO (src) + 1))
- sprintf (out_template, "mov.L\t%H1, %H0 | mov.L\t%1, %0");
+ sprintf (out_template, "mov.L\t%%H1, %%H0 ! mov.L\t%%1, %%0");
else
- sprintf (out_template, "mov.L\t%1, %0 | mov.L\t%H1, %H0");
+ sprintf (out_template, "mov.L\t%%1, %%0 ! mov.L\t%%H1, %%H0");
}
else
sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
@@ -3270,7 +3270,7 @@ rx_ok_to_inline (tree caller, tree callee)
static bool
rx_enable_lra (void)
{
- return TARGET_ENABLE_LRA || 1;
+ return TARGET_ENABLE_LRA;
}
diff --git a/gcc/config/rx/rx.h b/gcc/config/rx/rx.h
index 72aee2fe214..ec2770be161 100644
--- a/gcc/config/rx/rx.h
+++ b/gcc/config/rx/rx.h
@@ -99,6 +99,7 @@
%{mpid} \
%{mint-register=*} \
%{mgcc-abi:-mgcc-abi} %{!mgcc-abi:-mrx-abi} \
+%{mcpu=*} \
"
#undef LIB_SPEC
diff --git a/gcc/config/s390/2827.md b/gcc/config/s390/2827.md
index f21d8f8ce25..5be7cfaabfb 100644
--- a/gcc/config/s390/2827.md
+++ b/gcc/config/s390/2827.md
@@ -32,12 +32,12 @@
(const_int 0)))
(define_attr "ooo_groupalone" ""
- (cond [(eq_attr "mnemonic" "lnxbr,madb,ltxtr,clc,axtr,msebr,slbgr,xc,alcr,lpxbr,slbr,maebr,mlg,mfy,lxdtr,maeb,lxeb,nc,mxtr,sxtr,dxbr,alc,msdbr,ltxbr,lxdb,madbr,lxdbr,lxebr,mvc,m,mseb,mlr,mlgr,slb,tcxb,msdb,sqxbr,alcgr,oc,flogr,alcg,mxbr,dxtr,axbr,mr,sxbr,slbg,ml,lcxbr") (const_int 1)]
+ (cond [(eq_attr "mnemonic" "lnxbr,madb,ltxtr,clc,axtr,msebr,slbgr,xc,alcr,lpxbr,slbr,maebr,mlg,mfy,lxdtr,maeb,lxeb,nc,mxtr,sxtr,dxbr,alc,msdbr,ltxbr,lxdb,madbr,lxdbr,lxebr,mvc,m,mseb,mlr,mlgr,slb,tcxb,msdb,sqxbr,alcgr,oc,flogr,alcg,mxbr,dxtr,axbr,mr,sxbr,slbg,ml,lcxbr,bcr_flush") (const_int 1)]
(const_int 0)))
(define_insn_reservation "zEC12_simple" 1
(and (eq_attr "cpu" "zEC12")
- (eq_attr "mnemonic" "ltg,ogrk,lr,lnebr,lghrl,sdbr,x,asi,lhr,sebr,madb,ar,lhrl,clfxtr,llgfr,clghrl,cgr,cli,agrk,ic,adbr,aebr,lrv,clg,cy,cghi,sy,celfbr,seb,clgfr,al,tm,lang,clfebr,lghr,cdb,lpebr,laa,ark,lh,or,icy,xi,msebr,n,llihl,afi,cs,nrk,sth,lgr,l,lcr,stey,xg,crt,slgfr,ny,ld,j,llihh,slgr,clfhsi,slg,lb,lgrl,lrl,llihf,lndbr,llcr,laxg,mvghi,rllg,sdb,xrk,laag,alhsik,algfi,algr,aly,agfi,lrvr,d,crl,llgc,tmhl,algsi,lgh,icmh,clhrl,xgrk,icm,iilf,ork,lbr,cg,ldgr,lgf,iihf,llghr,sg,clfdbr,llgtr,stam,cebr,tmhh,tceb,slgf,basr,lgbr,maebr,lgb,cgfi,aeb,ltebr,lax,clfit,lrvgr,nihl,ni,clfdtr,srdl,mdb,srk,xihf,stgrl,sthrl,algf,ltr,cdlgbr,cgit,ng,lat,llghrl,ltgr,nihh,clgfrl,srlk,maeb,agr,cxlftr,ler,bcr,stcy,cds,clfi,nihf,ly,clt,lgat,alg,lhy,lgfrl,clghsi,clrt,tmll,srlg,tcdb,ay,sty,clr,lgfi,lan,lpdbr,clgt,adb,ahik,sra,algrk,cdfbr,lcebr,clfxbr,msdbr,ceb,clgr,tmy,tmlh,alghsik,lcgr,mvi,cdbr,ltgf,xr,larl,ldr,llgcr,clgrt,clrl,cghsi,cliy,madbr,oy,ogr,llgt,meebr,slr,clgxbr,chi,s,icmy,llc,ngr,clhhsi,ltgfr,llill,lhi,o,meeb,clgdtr,sll,clgrl,clgf,ledbr,cegbr,mviy,algfr,rll,cdlftr,sldl,cdlgtr,lg,niy,st,sgr,ag,le,xgr,cr,stg,llilh,sr,lzer,cdsg,sllk,mdbr,stoc,csg,clgit,chhsi,strl,llilf,lndfr,ngrk,clgebr,clgfi,llgh,mseb,ltdbr,oill,la,llhrl,stc,lghi,oihl,xiy,sllg,llgf,cgrt,ldeb,cl,sl,cdlfbr,oi,oilh,nr,srak,oihh,ear,slgrk,og,c,slgfi,sthy,oilf,oiy,msdb,oihf,a,cfi,lzxr,lzdr,srag,cdgbr,brasl,alr,cgrl,llgfrl,cit,clgxtr,ley,exrl,lcdfr,lay,xilf,lcdbr,alsi,mvhhi,srl,chsi,lgfr,lrvg,cly,sgrk,ahi,celgbr,nill,clgdbr,jg,slrk,lxr,sar,slfi,cpsdr,lcgfr,aghik,nilh,mvhi,lpdfr,xy,alrk,lao,agsi,ldy,nilf,llhr,alfi,laog,sly,aghi,ldebr,bras,srda,cefbr,lt")) "nothing")
+ (eq_attr "mnemonic" "ltg,ogrk,lr,lnebr,lghrl,sdbr,x,asi,lhr,sebr,madb,ar,lhrl,clfxtr,llgfr,clghrl,cgr,cli,agrk,ic,adbr,aebr,lrv,clg,cy,cghi,sy,celfbr,seb,clgfr,al,tm,lang,clfebr,lghr,cdb,lpebr,laa,ark,lh,or,icy,xi,msebr,n,llihl,afi,cs,nrk,sth,lgr,l,lcr,stey,xg,crt,slgfr,ny,ld,j,llihh,slgr,clfhsi,slg,lb,lgrl,lrl,llihf,lndbr,llcr,laxg,mvghi,rllg,sdb,xrk,laag,alhsik,algfi,algr,aly,agfi,lrvr,d,crl,llgc,tmhl,algsi,lgh,icmh,clhrl,xgrk,icm,iilf,ork,lbr,cg,ldgr,lgf,iihf,llghr,sg,clfdbr,llgtr,stam,cebr,tmhh,tceb,slgf,basr,lgbr,maebr,lgb,cgfi,aeb,ltebr,lax,clfit,lrvgr,nihl,ni,clfdtr,srdl,mdb,srk,xihf,stgrl,sthrl,algf,ltr,cdlgbr,cgit,ng,lat,llghrl,ltgr,nihh,clgfrl,srlk,maeb,agr,cxlftr,ler,bcr_flush,stcy,cds,clfi,nihf,ly,clt,lgat,alg,lhy,lgfrl,clghsi,clrt,tmll,srlg,tcdb,ay,sty,clr,lgfi,lan,lpdbr,clgt,adb,ahik,sra,algrk,cdfbr,lcebr,clfxbr,msdbr,ceb,clgr,tmy,tmlh,alghsik,lcgr,mvi,cdbr,ltgf,xr,larl,ldr,llgcr,clgrt,clrl,cghsi,cliy,madbr,oy,ogr,llgt,meebr,slr,clgxbr,chi,s,icmy,llc,ngr,clhhsi,ltgfr,llill,lhi,o,meeb,clgdtr,sll,clgrl,clgf,ledbr,cegbr,mviy,algfr,rll,cdlftr,sldl,cdlgtr,lg,niy,st,sgr,ag,le,xgr,cr,stg,llilh,sr,lzer,cdsg,sllk,mdbr,stoc,csg,clgit,chhsi,strl,llilf,lndfr,ngrk,clgebr,clgfi,llgh,mseb,ltdbr,oill,la,llhrl,stc,lghi,oihl,xiy,sllg,llgf,cgrt,ldeb,cl,sl,cdlfbr,oi,oilh,nr,srak,oihh,ear,slgrk,og,c,slgfi,sthy,oilf,oiy,msdb,oihf,a,cfi,lzxr,lzdr,srag,cdgbr,brasl,alr,cgrl,llgfrl,cit,clgxtr,ley,exrl,lcdfr,lay,xilf,lcdbr,alsi,mvhhi,srl,chsi,lgfr,lrvg,cly,sgrk,ahi,celgbr,nill,clgdbr,jg,slrk,lxr,sar,slfi,cpsdr,lcgfr,aghik,nilh,mvhi,lpdfr,xy,alrk,lao,agsi,ldy,nilf,llhr,alfi,laog,sly,aghi,ldebr,bras,srda,cefbr,lt,fiebra,fidbra,fixbra,fidtr,fixtr")) "nothing")
(define_insn_reservation "zEC12_cgdbr" 2
(and (eq_attr "cpu" "zEC12")
@@ -603,3 +603,22 @@
(and (eq_attr "cpu" "zEC12")
(eq_attr "mnemonic" "mh")) "nothing")
+(define_insn_reservation "zEC12_fiebra" 6
+ (and (eq_attr "cpu" "zEC12")
+ (eq_attr "mnemonic" "fiebra")) "nothing")
+
+(define_insn_reservation "zEC12_fidbra" 6
+ (and (eq_attr "cpu" "zEC12")
+ (eq_attr "mnemonic" "fidbra")) "nothing")
+
+(define_insn_reservation "zEC12_fixbra" 10
+ (and (eq_attr "cpu" "zEC12")
+ (eq_attr "mnemonic" "fixbra")) "nothing")
+
+(define_insn_reservation "zEC12_fidtr" 6
+ (and (eq_attr "cpu" "zEC12")
+ (eq_attr "mnemonic" "fidtr")) "nothing")
+
+(define_insn_reservation "zEC12_fixtr" 10
+ (and (eq_attr "cpu" "zEC12")
+ (eq_attr "mnemonic" "fixtr")) "nothing")
diff --git a/gcc/config/s390/linux.h b/gcc/config/s390/linux.h
index 3b4966a91ff..699b5dfb7e2 100644
--- a/gcc/config/s390/linux.h
+++ b/gcc/config/s390/linux.h
@@ -87,4 +87,7 @@ along with GCC; see the file COPYING3. If not see
/* Define if long doubles should be mangled as 'g'. */
#define TARGET_ALTERNATE_LONG_DOUBLE_MANGLING
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
+
#endif
diff --git a/gcc/config/s390/s390.md b/gcc/config/s390/s390.md
index 95ded7c78e6..cf9ef774675 100644
--- a/gcc/config/s390/s390.md
+++ b/gcc/config/s390/s390.md
@@ -117,6 +117,14 @@
; Population Count
UNSPEC_POPCNT
UNSPEC_COPYSIGN
+
+ ; Load FP Integer
+ UNSPEC_FPINT_FLOOR
+ UNSPEC_FPINT_BTRUNC
+ UNSPEC_FPINT_ROUND
+ UNSPEC_FPINT_CEIL
+ UNSPEC_FPINT_NEARBYINT
+ UNSPEC_FPINT_RINT
])
;;
@@ -291,7 +299,7 @@
z196_cracked"
(const_string "none"))
-(define_attr "mnemonic" "unknown" (const_string "unknown"))
+(define_attr "mnemonic" "bcr_flush,unknown" (const_string "unknown"))
;; Length in bytes.
@@ -429,9 +437,25 @@
;; the same template.
(define_code_iterator SHIFT [ashift lshiftrt])
-;; This iterator allow r[ox]sbg to be defined with the same template
+;; This iterator allows r[ox]sbg to be defined with the same template
(define_code_iterator IXOR [ior xor])
+;; This iterator is used to expand the patterns for the nearest
+;; integer functions.
+(define_int_iterator FPINT [UNSPEC_FPINT_FLOOR UNSPEC_FPINT_BTRUNC
+ UNSPEC_FPINT_ROUND UNSPEC_FPINT_CEIL
+ UNSPEC_FPINT_NEARBYINT])
+(define_int_attr fpint_name [(UNSPEC_FPINT_FLOOR "floor")
+ (UNSPEC_FPINT_BTRUNC "btrunc")
+ (UNSPEC_FPINT_ROUND "round")
+ (UNSPEC_FPINT_CEIL "ceil")
+ (UNSPEC_FPINT_NEARBYINT "nearbyint")])
+(define_int_attr fpint_roundingmode [(UNSPEC_FPINT_FLOOR "7")
+ (UNSPEC_FPINT_BTRUNC "5")
+ (UNSPEC_FPINT_ROUND "1")
+ (UNSPEC_FPINT_CEIL "6")
+ (UNSPEC_FPINT_NEARBYINT "0")])
+
;; This iterator and attribute allow to combine most atomic operations.
(define_code_iterator ATOMIC [and ior xor plus minus mult])
(define_code_iterator ATOMIC_Z196 [and ior xor plus])
@@ -2289,13 +2313,13 @@
lr\t%0,%1
tmh\t%1,12288
ipm\t%0
- st\t%0,%1
- sty\t%0,%1
- l\t%1,%0
- ly\t%1,%0"
+ l\t%0,%1
+ ly\t%0,%1
+ st\t%1,%0
+ sty\t%1,%0"
[(set_attr "op_type" "RR,RI,RRE,RX,RXY,RX,RXY")
- (set_attr "type" "lr,*,*,store,store,load,load")
- (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_rec,z10_rec,z10_fwd_A3,z10_fwd_A3")
+ (set_attr "type" "lr,*,*,load,load,store,store")
+ (set_attr "z10prop" "z10_fr_E1,z10_super,*,z10_fwd_A3,z10_fwd_A3,z10_rec,z10_rec")
(set_attr "z196prop" "*,*,z196_ends,*,*,*,*")])
;
@@ -4414,6 +4438,58 @@
[(set_attr "op_type" "RRF")
(set_attr "type" "fsimptf")])
+; Binary Floating Point - load fp integer
+
+; Expanders for: floor, btrunc, round, ceil, and nearbyint
+; For all of them the inexact exceptions are suppressed.
+
+; fiebra, fidbra, fixbra
+(define_insn "<FPINT:fpint_name><BFP:mode>2"
+ [(set (match_operand:BFP 0 "register_operand" "=f")
+ (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
+ FPINT))]
+ "TARGET_Z196"
+ "fi<BFP:xde>bra\t%0,<FPINT:fpint_roundingmode>,%1,4"
+ [(set_attr "op_type" "RRF")
+ (set_attr "type" "fsimp<BFP:mode>")])
+
+; rint is supposed to raise an inexact exception so we can use the
+; older instructions.
+
+; fiebr, fidbr, fixbr
+(define_insn "rint<BFP:mode>2"
+ [(set (match_operand:BFP 0 "register_operand" "=f")
+ (unspec:BFP [(match_operand:BFP 1 "register_operand" "f")]
+ UNSPEC_FPINT_RINT))]
+ ""
+ "fi<BFP:xde>br\t%0,0,%1"
+ [(set_attr "op_type" "RRF")
+ (set_attr "type" "fsimp<BFP:mode>")])
+
+
+; Decimal Floating Point - load fp integer
+
+; fidtr, fixtr
+(define_insn "<FPINT:fpint_name><DFP:mode>2"
+ [(set (match_operand:DFP 0 "register_operand" "=f")
+ (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
+ FPINT))]
+ "TARGET_HARD_DFP"
+ "fi<DFP:xde>tr\t%0,<FPINT:fpint_roundingmode>,%1,4"
+ [(set_attr "op_type" "RRF")
+ (set_attr "type" "fsimp<DFP:mode>")])
+
+; fidtr, fixtr
+(define_insn "rint<DFP:mode>2"
+ [(set (match_operand:DFP 0 "register_operand" "=f")
+ (unspec:DFP [(match_operand:DFP 1 "register_operand" "f")]
+ UNSPEC_FPINT_RINT))]
+ "TARGET_HARD_DFP"
+ "fi<DFP:xde>tr\t%0,0,%1,0"
+ [(set_attr "op_type" "RRF")
+ (set_attr "type" "fsimp<DFP:mode>")])
+
+;
; Binary <-> Decimal floating point trunc patterns
;
@@ -9007,12 +9083,22 @@
; Although bcr is superscalar on Z10, this variant will never
; become part of an execution group.
+; With z196 we can make use of the fast-BCR-serialization facility.
+; This allows for a slightly faster sync which is sufficient for our
+; purposes.
(define_insn "mem_thread_fence_1"
[(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0)] UNSPEC_MB))]
""
- "bcr\t15,0"
- [(set_attr "op_type" "RR")])
+{
+ if (TARGET_Z196)
+ return "bcr\t14,0";
+ else
+ return "bcr\t15,0";
+}
+ [(set_attr "op_type" "RR")
+ (set_attr "mnemonic" "bcr_flush")
+ (set_attr "z196prop" "z196_alone")])
;
; atomic load/store operations
diff --git a/gcc/config/s390/tpf.h b/gcc/config/s390/tpf.h
index a2bde82ca79..a1af01b07b6 100644
--- a/gcc/config/s390/tpf.h
+++ b/gcc/config/s390/tpf.h
@@ -94,9 +94,6 @@ along with GCC; see the file COPYING3. If not see
#define ASM_SPEC "%{m31&m64}%{mesa&mzarch}%{march=*} \
-alshd=%b.lst"
-#undef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 1
-
#define ENTRY_SPEC "%{mmain:-entry=_start} \
%{!mmain:-entry=0}"
@@ -114,4 +111,8 @@ along with GCC; see the file COPYING3. If not see
/* IBM copies these libraries over with these names. */
#define MATH_LIBRARY "CLBM"
#define LIBSTDCXX "CPP2"
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION gnu_libc_has_function
+
#endif /* ! _TPF_H */
diff --git a/gcc/config/sol2-10.h b/gcc/config/sol2-10.h
index 81d0f51e144..9df5548e4c1 100644
--- a/gcc/config/sol2-10.h
+++ b/gcc/config/sol2-10.h
@@ -18,5 +18,7 @@ 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/>. */
-/* Solaris 10 has the float and long double forms of math functions. */
-#define TARGET_C99_FUNCTIONS 1
+/* Solaris 10 has the float and long double forms of math functions.
+ We redefine this hook so the version from elfos.h header won't be used. */
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION default_libc_has_function
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index 4c9b334e7a7..b606595dfe9 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -285,6 +285,9 @@ along with GCC; see the file COPYING3. If not see
#define TARGET_POSIX_IO
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
extern GTY(()) tree solaris_pending_aligns;
extern GTY(()) tree solaris_pending_inits;
extern GTY(()) tree solaris_pending_finis;
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 48c25dcd5cd..e5b4662512d 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see
#include "df.h"
#include "opts.h"
#include "tree-pass.h"
+#include "context.h"
/* Processor costs */
@@ -1000,34 +1001,44 @@ sparc_do_work_around_errata (void)
return 0;
}
-struct rtl_opt_pass pass_work_around_errata =
-{
- {
- RTL_PASS,
- "errata", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- sparc_gate_work_around_errata, /* gate */
- sparc_do_work_around_errata, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_MACH_DEP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
-};
+namespace {
-struct register_pass_info insert_pass_work_around_errata =
+const pass_data pass_data_work_around_errata =
{
- &pass_work_around_errata.pass, /* pass */
- "dbr", /* reference_pass_name */
- 1, /* ref_pass_instance_number */
- PASS_POS_INSERT_AFTER /* po_op */
+ RTL_PASS, /* type */
+ "errata", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_MACH_DEP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_work_around_errata : public rtl_opt_pass
+{
+public:
+ pass_work_around_errata(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_work_around_errata, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return sparc_gate_work_around_errata (); }
+ unsigned int execute () { return sparc_do_work_around_errata (); }
+
+}; // class pass_work_around_errata
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_work_around_errata (gcc::context *ctxt)
+{
+ return new pass_work_around_errata (ctxt);
+}
+
/* Helpers for TARGET_DEBUG_OPTIONS. */
static void
dump_target_flag_bits (const int flags)
@@ -1140,9 +1151,8 @@ sparc_option_override (void)
/* TI TMS390Z55 supersparc */
{ "supersparc", MASK_ISA, MASK_V8 },
{ "hypersparc", MASK_ISA, MASK_V8|MASK_FPU },
- /* LEON */
- { "leon", MASK_ISA, MASK_V8|MASK_FPU },
- { "leon3", MASK_ISA, MASK_V8|MASK_FPU },
+ { "leon", MASK_ISA, MASK_V8|MASK_LEON|MASK_FPU },
+ { "leon3", MASK_ISA, MASK_V8|MASK_LEON3|MASK_FPU },
{ "sparclite", MASK_ISA, MASK_SPARCLITE },
/* The Fujitsu MB86930 is the original sparclite chip, with no FPU. */
{ "f930", MASK_ISA|MASK_FPU, MASK_SPARCLITE },
@@ -1302,6 +1312,9 @@ sparc_option_override (void)
#ifndef HAVE_AS_SPARC4
& ~MASK_CBCOND
#endif
+#ifndef HAVE_AS_LEON
+ & ~(MASK_LEON | MASK_LEON3)
+#endif
);
/* If -mfpu or -mno-fpu was explicitly used, don't override with
@@ -1430,6 +1443,10 @@ sparc_option_override (void)
/* Choose the most relaxed model for the processor. */
else if (TARGET_V9)
sparc_memory_model = SMM_RMO;
+ else if (TARGET_LEON3)
+ sparc_memory_model = SMM_TSO;
+ else if (TARGET_LEON)
+ sparc_memory_model = SMM_SC;
else if (TARGET_V8)
sparc_memory_model = SMM_PSO;
else
@@ -1477,6 +1494,14 @@ sparc_option_override (void)
(essentially) final form of the insn stream to work on.
Registering the pass must be done at start up. It's convenient to
do it here. */
+ opt_pass *errata_pass = make_pass_work_around_errata (g);
+ struct register_pass_info insert_pass_work_around_errata =
+ {
+ errata_pass, /* pass */
+ "dbr", /* reference_pass_name */
+ 1, /* ref_pass_instance_number */
+ PASS_POS_INSERT_AFTER /* po_op */
+ };
register_pass (&insert_pass_work_around_errata);
}
@@ -11318,6 +11343,11 @@ sparc_emit_membar_for_model (enum memmodel model,
/* Total Store Ordering: all memory transactions with store semantics
are followed by an implied StoreStore. */
implied |= StoreStore;
+
+ /* If we're not looking for a raw barrer (before+after), then atomic
+ operations get the benefit of being both load and store. */
+ if (load_store == 3 && before_after == 1)
+ implied |= StoreLoad;
/* FALLTHRU */
case SMM_PSO:
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 202d23c0162..d96c1b6b422 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -236,7 +236,7 @@ extern enum cmodel sparc_cmodel;
#if TARGET_CPU_DEFAULT == TARGET_CPU_leon \
|| TARGET_CPU_DEFAULT == TARGET_CPU_leon3
#define CPP_CPU32_DEFAULT_SPEC "-D__leon__ -D__sparc_v8__"
-#define ASM_CPU32_DEFAULT_SPEC ""
+#define ASM_CPU32_DEFAULT_SPEC AS_LEON_FLAG
#endif
#endif
@@ -332,8 +332,8 @@ extern enum cmodel sparc_cmodel;
%{mcpu=v8:-Av8} \
%{mcpu=supersparc:-Av8} \
%{mcpu=hypersparc:-Av8} \
-%{mcpu=leon:-Av8} \
-%{mcpu=leon3:-Av8} \
+%{mcpu=leon:" AS_LEON_FLAG "} \
+%{mcpu=leon3:" AS_LEON_FLAG "} \
%{mv8plus:-Av8plus} \
%{mcpu=v9:-Av9} \
%{mcpu=ultrasparc:%{!mv8plus:-Av9a}} \
@@ -1758,6 +1758,12 @@ extern int sparc_indent_opcode;
#define AS_NIAGARA4_FLAG "-Av9" AS_NIAGARA3_FLAG
#endif
+#ifdef HAVE_AS_LEON
+#define AS_LEON_FLAG "-Aleon"
+#else
+#define AS_LEON_FLAG "-Av8"
+#endif
+
/* We use gcc _mcount for profiling. */
#define NO_PROFILE_COUNTERS 0
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index 016e6997422..3ccd54fa463 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -211,6 +211,12 @@ Enable workarounds for the errata of the UT699 processor
Mask(LONG_DOUBLE_128)
;; Use 128-bit long double
+Mask(LEON)
+;; Generate code for LEON
+
+Mask(LEON3)
+;; Generate code for LEON3
+
Mask(SPARCLITE)
;; Generate code for SPARClite
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index 2f21f812dc9..130f5219194 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -161,7 +161,8 @@
(match_operand:SI 5 "const_int_operand" "") ;; is_weak
(match_operand:SI 6 "const_int_operand" "") ;; mod_s
(match_operand:SI 7 "const_int_operand" "")] ;; mod_f
- "TARGET_V9 && (<MODE>mode != DImode || TARGET_ARCH64 || TARGET_V8PLUS)"
+ "(TARGET_V9 || TARGET_LEON3)
+ && (<MODE>mode != DImode || TARGET_ARCH64 || TARGET_V8PLUS)"
{
sparc_expand_compare_and_swap (operands);
DONE;
@@ -176,7 +177,7 @@
[(match_operand:I48MODE 2 "register_operand" "")
(match_operand:I48MODE 3 "register_operand" "")]
UNSPECV_CAS))])]
- "TARGET_V9"
+ "TARGET_V9 || TARGET_LEON3"
"")
(define_insn "*atomic_compare_and_swap<mode>_1"
@@ -187,7 +188,7 @@
[(match_operand:I48MODE 2 "register_operand" "r")
(match_operand:I48MODE 3 "register_operand" "0")]
UNSPECV_CAS))]
- "TARGET_V9 && (<MODE>mode == SImode || TARGET_ARCH64)"
+ "(TARGET_V9 || TARGET_LEON3) && (<MODE>mode != DImode || TARGET_ARCH64)"
"cas<modesuffix>\t%1, %2, %0"
[(set_attr "type" "multi")])
diff --git a/gcc/config/sparc/t-sparc b/gcc/config/sparc/t-sparc
index 664f4a42418..62ad3f77934 100644
--- a/gcc/config/sparc/t-sparc
+++ b/gcc/config/sparc/t-sparc
@@ -24,7 +24,7 @@ sparc.o: $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(FUNCTION_H) $(EXCEPT_H) $(EXPR_H) $(OPTABS_H) $(RECOG_H) \
$(DIAGNOSTIC_CORE_H) $(GGC_H) $(TM_P_H) debug.h $(TARGET_H) \
$(TARGET_DEF_H) $(COMMON_TARGET_H) $(GIMPLE_H) $(TREE_PASS_H) \
- langhooks.h reload.h $(PARAMS_H) $(DF_H) $(OPTS_H) \
+ langhooks.h reload.h $(PARAMS_H) $(DF_H) $(OPTS_H) $(CONTEXT_H) \
gt-sparc.h
sparc-c.o: $(srcdir)/config/sparc/sparc-c.c \
diff --git a/gcc/config/vms/vms.h b/gcc/config/vms/vms.h
index b7689bfa674..5d0a5c6515c 100644
--- a/gcc/config/vms/vms.h
+++ b/gcc/config/vms/vms.h
@@ -87,3 +87,6 @@ extern void vms_c_register_includes (const char *, const char *, int);
/* Special VMS debugger symbol to record the entry point. */
#define VMS_DEBUG_MAIN_POINTER "TRANSFER$BREAK$GO"
+
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
diff --git a/gcc/config/vxworks.h b/gcc/config/vxworks.h
index d91a8b103ac..72f344b6f01 100644
--- a/gcc/config/vxworks.h
+++ b/gcc/config/vxworks.h
@@ -114,6 +114,9 @@ extern void vxworks_asm_out_destructor (rtx symbol, int priority);
#undef SIZE_TYPE
#define SIZE_TYPE "unsigned int"
+#undef TARGET_LIBC_HAS_FUNCTION
+#define TARGET_LIBC_HAS_FUNCTION no_c99_libc_has_function
+
/* Both kernels and RTPs have the facilities required by this macro. */
#define TARGET_POSIX_IO
diff --git a/gcc/configure b/gcc/configure
index e36a6086c44..c6bc3a69d84 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -24332,6 +24332,43 @@ if test $gcc_cv_as_sparc_sparc4 = yes; then
$as_echo "#define HAVE_AS_SPARC4 1" >>confdefs.h
fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for LEON instructions" >&5
+$as_echo_n "checking assembler for LEON instructions... " >&6; }
+if test "${gcc_cv_as_sparc_leon+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_sparc_leon=no
+ if test x$gcc_cv_as != x; then
+ $as_echo '.text
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .align 4
+ smac %g2, %g3, %g1
+ umac %g2, %g3, %g1
+ cas [%g2], %g3, %g1' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -Aleon -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_sparc_leon=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_sparc_leon" >&5
+$as_echo "$gcc_cv_as_sparc_leon" >&6; }
+if test $gcc_cv_as_sparc_leon = yes; then
+
+$as_echo "#define HAVE_AS_LEON 1" >>confdefs.h
+
+fi
;;
i[34567]86-*-* | x86_64-*-*)
@@ -26019,6 +26056,41 @@ $as_echo "$gcc_cv_ld_mips_personality_relaxation" >&6; }
$as_echo "#define HAVE_LD_PERSONALITY_RELAXATION 1" >>confdefs.h
fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for -mnan= support" >&5
+$as_echo_n "checking assembler for -mnan= support... " >&6; }
+if test "${gcc_cv_as_mips_nan+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ gcc_cv_as_mips_nan=no
+ if test x$gcc_cv_as != x; then
+ $as_echo '' > conftest.s
+ if { ac_try='$gcc_cv_as $gcc_cv_as_flags -mnan=2008 -o conftest.o conftest.s >&5'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ then
+ gcc_cv_as_mips_nan=yes
+ else
+ echo "configure: failed program was" >&5
+ cat conftest.s >&5
+ fi
+ rm -f conftest.o conftest.s
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_mips_nan" >&5
+$as_echo "$gcc_cv_as_mips_nan" >&6; }
+if test $gcc_cv_as_mips_nan = yes; then
+
+$as_echo "#define HAVE_AS_NAN 1" >>confdefs.h
+
+fi
+ if test x$gcc_cv_as_mips_nan = xno \
+ && test x$with_nan != x; then
+ as_fn_error "Requesting --with-nan= requires assembler support for -mnan=" "$LINENO" 5
+ fi
;;
esac
@@ -26046,8 +26118,9 @@ esac
# ??? Once 2.11 is released, probably need to add first known working
# version to the per-target configury.
case "$cpu_type" in
- alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \
- | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 | xtensa)
+ aarch64 | alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze \
+ | mips | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 \
+ | xtensa)
insn="nop"
;;
ia64 | s390)
@@ -27324,6 +27397,7 @@ if test "x$subdirs" != x; then
done
fi
echo "source ${srcdir}/gdbinit.in" >> .gdbinit
+echo "python import sys; sys.path.append('${srcdir}'); import gdbhooks" >> .gdbinit
gcc_tooldir='$(libsubdir)/$(libsubdir_to_prefix)$(target_noncanonical)'
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 9dfd389bd98..5d3e5ad5823 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -3613,6 +3613,19 @@ foo:
kasumi_fi_xor %f46, %f48, %f50, %f52],,
[AC_DEFINE(HAVE_AS_SPARC4, 1,
[Define if your assembler supports SPARC4 instructions.])])
+
+ gcc_GAS_CHECK_FEATURE([LEON instructions],
+ gcc_cv_as_sparc_leon,,
+ [-Aleon],
+ [.text
+ .register %g2, #scratch
+ .register %g3, #scratch
+ .align 4
+ smac %g2, %g3, %g1
+ umac %g2, %g3, %g1
+ cas [[%g2]], %g3, %g1],,
+ [AC_DEFINE(HAVE_AS_LEON, 1,
+ [Define if your assembler supports LEON instructions.])])
;;
changequote(,)dnl
@@ -4168,6 +4181,17 @@ EOF
[Define if your linker can relax absolute .eh_frame personality
pointers into PC-relative form.])
fi
+
+ gcc_GAS_CHECK_FEATURE([-mnan= support],
+ gcc_cv_as_mips_nan,,
+ [-mnan=2008],,,
+ [AC_DEFINE(HAVE_AS_NAN, 1,
+ [Define if the assembler understands -mnan=.])])
+ if test x$gcc_cv_as_mips_nan = xno \
+ && test x$with_nan != x; then
+ AC_MSG_ERROR(
+ [Requesting --with-nan= requires assembler support for -mnan=])
+ fi
;;
esac
@@ -4195,8 +4219,9 @@ esac
# ??? Once 2.11 is released, probably need to add first known working
# version to the per-target configury.
case "$cpu_type" in
- alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze | mips \
- | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 | xtensa)
+ aarch64 | alpha | arm | avr | bfin | cris | i386 | m32c | m68k | microblaze \
+ | mips | pa | rs6000 | score | sparc | spu | tilegx | tilepro | xstormy16 \
+ | xtensa)
insn="nop"
;;
ia64 | s390)
@@ -5156,6 +5181,7 @@ if test "x$subdirs" != x; then
done
fi
echo "source ${srcdir}/gdbinit.in" >> .gdbinit
+echo "python import sys; sys.path.append('${srcdir}'); import gdbhooks" >> .gdbinit
gcc_tooldir='$(libsubdir)/$(libsubdir_to_prefix)$(target_noncanonical)'
AC_SUBST(gcc_tooldir)
diff --git a/gcc/context.c b/gcc/context.c
index 76e0dde9c0f..b5152419a97 100644
--- a/gcc/context.c
+++ b/gcc/context.c
@@ -22,6 +22,12 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "ggc.h"
#include "context.h"
+#include "pass_manager.h"
/* The singleton holder of global state: */
gcc::context *g;
+
+gcc::context::context()
+{
+ passes_ = new gcc::pass_manager (this);
+}
diff --git a/gcc/context.h b/gcc/context.h
index 3caf02fed31..66260cd279a 100644
--- a/gcc/context.h
+++ b/gcc/context.h
@@ -22,14 +22,23 @@ along with GCC; see the file COPYING3. If not see
namespace gcc {
+class pass_manager;
+
/* GCC's internal state can be divided into zero or more
"parallel universe" of state; an instance of this class is one such
context of state. */
class context
{
public:
+ context();
+
+ /* Pass-management. */
+
+ pass_manager *get_passes () { gcc_assert (passes_); return passes_; }
- /* Currently empty. */
+private:
+ /* Pass-management. */
+ pass_manager *passes_;
}; // class context
diff --git a/gcc/convert.c b/gcc/convert.c
index 9ecef4247ba..b07f0efe820 100644
--- a/gcc/convert.c
+++ b/gcc/convert.c
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "convert.h"
#include "diagnostic-core.h"
+#include "target.h"
#include "langhooks.h"
/* Convert EXPR to some pointer or reference type TYPE.
@@ -386,7 +387,7 @@ convert_to_integer (tree type, tree expr)
{
CASE_FLT_FN (BUILT_IN_CEIL):
/* Only convert in ISO C99 mode. */
- if (!TARGET_C99_FUNCTIONS)
+ if (!targetm.libc_has_function (function_c99_misc))
break;
if (outprec < TYPE_PRECISION (integer_type_node)
|| (outprec == TYPE_PRECISION (integer_type_node)
@@ -402,7 +403,7 @@ convert_to_integer (tree type, tree expr)
CASE_FLT_FN (BUILT_IN_FLOOR):
/* Only convert in ISO C99 mode. */
- if (!TARGET_C99_FUNCTIONS)
+ if (!targetm.libc_has_function (function_c99_misc))
break;
if (outprec < TYPE_PRECISION (integer_type_node)
|| (outprec == TYPE_PRECISION (integer_type_node)
@@ -418,7 +419,7 @@ convert_to_integer (tree type, tree expr)
CASE_FLT_FN (BUILT_IN_ROUND):
/* Only convert in ISO C99 mode. */
- if (!TARGET_C99_FUNCTIONS)
+ if (!targetm.libc_has_function (function_c99_misc))
break;
if (outprec < TYPE_PRECISION (integer_type_node)
|| (outprec == TYPE_PRECISION (integer_type_node)
@@ -439,7 +440,7 @@ convert_to_integer (tree type, tree expr)
/* ... Fall through ... */
CASE_FLT_FN (BUILT_IN_RINT):
/* Only convert in ISO C99 mode. */
- if (!TARGET_C99_FUNCTIONS)
+ if (!targetm.libc_has_function (function_c99_misc))
break;
if (outprec < TYPE_PRECISION (integer_type_node)
|| (outprec == TYPE_PRECISION (integer_type_node)
diff --git a/gcc/coretypes.h b/gcc/coretypes.h
index edb9c8c8477..bff8f5c62d5 100644
--- a/gcc/coretypes.h
+++ b/gcc/coretypes.h
@@ -73,9 +73,7 @@ struct cl_option;
struct cl_decoded_option;
struct cl_option_handlers;
struct diagnostic_context;
-typedef struct diagnostic_context diagnostic_context;
-struct pretty_print_info;
-typedef struct pretty_print_info pretty_printer;
+struct pretty_printer;
/* Address space number for named address space support. */
typedef unsigned char addr_space_t;
@@ -169,6 +167,12 @@ typedef const struct basic_block_def *const_basic_block;
in target.h. */
typedef int reg_class_t;
+class rtl_opt_pass;
+
+namespace gcc {
+ class context;
+}
+
#else
struct _dont_use_rtx_here_;
@@ -183,6 +187,15 @@ union _dont_use_tree_here_;
#endif
+/* Classes of functions that compiler needs to check
+ whether they are present at the runtime or not. */
+enum function_class {
+ function_c94,
+ function_c99_misc,
+ function_c99_math_complex,
+ function_sincos
+};
+
/* Memory model types for the __atomic* builtins.
This must match the order in libstdc++-v3/include/bits/atomic_base.h. */
enum memmodel
diff --git a/gcc/coverage.c b/gcc/coverage.c
index 7c395f4750b..d662e8d0946 100644
--- a/gcc/coverage.c
+++ b/gcc/coverage.c
@@ -43,6 +43,9 @@ along with GCC; see the file COPYING3. If not see
#include "langhooks.h"
#include "hash-table.h"
#include "tree-iterator.h"
+#include "context.h"
+#include "pass_manager.h"
+#include "tree-pass.h"
#include "cgraph.h"
#include "dumpfile.h"
#include "diagnostic-core.h"
@@ -341,11 +344,13 @@ get_coverage_counts (unsigned counter, unsigned expected,
{
static int warned = 0;
- if (!warned++)
- inform (input_location, (flag_guess_branch_prob
- ? "file %s not found, execution counts estimated"
- : "file %s not found, execution counts assumed to be zero"),
- da_file_name);
+ if (!warned++ && dump_enabled_p ())
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ (flag_guess_branch_prob
+ ? "file %s not found, execution counts estimated"
+ : "file %s not found, execution counts assumed to "
+ "be zero"),
+ da_file_name);
return NULL;
}
@@ -369,21 +374,25 @@ get_coverage_counts (unsigned counter, unsigned expected,
warning_at (input_location, OPT_Wcoverage_mismatch,
"the control flow of function %qE does not match "
"its profile data (counter %qs)", id, ctr_names[counter]);
- if (warning_printed)
+ if (warning_printed && dump_enabled_p ())
{
- inform (input_location, "use -Wno-error=coverage-mismatch to tolerate "
- "the mismatch but performance may drop if the function is hot");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ "use -Wno-error=coverage-mismatch to tolerate "
+ "the mismatch but performance may drop if the "
+ "function is hot");
if (!seen_error ()
&& !warned++)
{
- inform (input_location, "coverage mismatch ignored");
- inform (input_location, flag_guess_branch_prob
- ? G_("execution counts estimated")
- : G_("execution counts assumed to be zero"));
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ "coverage mismatch ignored");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ flag_guess_branch_prob
+ ? G_("execution counts estimated")
+ : G_("execution counts assumed to be zero"));
if (!flag_guess_branch_prob)
- inform (input_location,
- "this can result in poorly optimized code");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, input_location,
+ "this can result in poorly optimized code");
}
}
@@ -539,6 +548,28 @@ coverage_compute_lineno_checksum (void)
return chksum;
}
+/* Compute profile ID. This is better to be unique in whole program. */
+
+unsigned
+coverage_compute_profile_id (struct cgraph_node *n)
+{
+ expanded_location xloc
+ = expand_location (DECL_SOURCE_LOCATION (n->symbol.decl));
+ unsigned chksum = xloc.line;
+
+ chksum = coverage_checksum_string (chksum, xloc.file);
+ chksum = coverage_checksum_string
+ (chksum, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (n->symbol.decl)));
+ if (first_global_object_name)
+ chksum = coverage_checksum_string
+ (chksum, first_global_object_name);
+ chksum = coverage_checksum_string
+ (chksum, aux_base_name);
+
+ /* Non-negative integers are hopefully small enough to fit in all targets. */
+ return chksum & 0x7fffffff;
+}
+
/* Compute cfg checksum for the current function.
The checksum is calculated carefully so that
source code changes that doesn't affect the control flow graph
@@ -1103,6 +1134,11 @@ coverage_init (const char *filename)
int len = strlen (filename);
int prefix_len = 0;
+ /* Since coverage_init is invoked very early, before the pass
+ manager, we need to set up the dumping explicitly. This is
+ similar to the handling in finish_optimization_passes. */
+ dump_start (g->get_passes ()->get_pass_profile ()->static_pass_number, NULL);
+
if (!profile_data_prefix && !IS_ABSOLUTE_PATH (filename))
profile_data_prefix = getpwd ();
@@ -1145,6 +1181,8 @@ coverage_init (const char *filename)
gcov_write_unsigned (bbg_file_stamp);
}
}
+
+ dump_finish (g->get_passes ()->get_pass_profile ()->static_pass_number);
}
/* Performs file-level cleanup. Close notes file, generate coverage
diff --git a/gcc/coverage.h b/gcc/coverage.h
index 21afe7298ff..342d73e1653 100644
--- a/gcc/coverage.h
+++ b/gcc/coverage.h
@@ -35,6 +35,9 @@ extern void coverage_end_function (unsigned, unsigned);
/* Compute the control flow checksum for the current function. */
extern unsigned coverage_compute_cfg_checksum (void);
+/* Compute the profile id of function N. */
+extern unsigned coverage_compute_profile_id (struct cgraph_node *n);
+
/* Compute the line number checksum for the current function. */
extern unsigned coverage_compute_lineno_checksum (void);
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 2669375b7f5..9ba17c8bc31 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,616 @@
+2013-09-08 Caroline Tice <cmtice@google.com>
+
+ PR c++/58300
+ * vtable-class-hierarchy.c (vtv_generate_init_routine): In
+ preinit case, move call to assemble_vtv_preinit_initializer to
+ after call to cgraph_process_new_functions.
+
+2013-09-08 Tom de Vries <tom@codesourcery.com>
+
+ PR c++/58282
+ * except.c (build_must_not_throw_expr): Handle
+ flag_exceptions.
+
+2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * typeck.c (cp_build_binary_op): Use vector_types_compatible_elements_p.
+
+2013-09-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/24926
+ * class.c (finish_struct_anon_r): New.
+ (finish_struct_anon): Use it.
+
+2013-09-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::simple_type_specifier):
+ Declare as overrider.
+ * cxx-pretty-print.c (cxx_pretty_printer::simple_type_specifier):
+ Rename from pp_cxx_simple_type_specifier.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ simple_type_specifier.
+
+2013-09-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58305
+ * typeck2.c (build_functional_cast): Maybe warn_deprecated_use.
+
+2013-09-03 Mike Stump <mikestump@comcast.net>
+
+ * Make-lang.in (cp/lambda.o): Add dependencies.
+
+2013-09-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::type_id): Declare as
+ overrider.
+ * cxx-pretty-print.c (pp_cxx_storage_class_specifier): Remove.
+ (pp_cxx_userdef_literal): Tidy.
+ (pp_cxx_template_argument_list): Likewise.
+ (pp_cxx_typeid_expression): Likewise.
+ (pp_cxx_offsetof_expression_1): Likewise.
+ (cxx_pretty_printer::postfix_expression): Likewise.
+ (cxx_pretty_printer::unary_expression): Likewise.
+ (cxx_pretty_printer::statement): Likewise.
+ (cxx_pretty_printer::type_id): Rename from pp_cxx_type_id.
+ (c_pretty_printer::cxx_pretty_printer): Do not assign to type_id.
+ * error.c (dump_decl): Tidy.
+ (dump_expr): Likewise.
+
+2013-09-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/21682, implement DR 565
+ * name-lookup.c (compparms_for_decl_and_using_decl): New.
+ (push_overloaded_decl_1, do_nonmember_using_decl): Use it.
+
+2013-08-30 Marek Polacek <polacek@redhat.com>
+
+ * typeck.c (cp_build_binary_op): Add division by zero and shift
+ instrumentation.
+ * error.c (dump_expr): Special-case ubsan builtins.
+
+2013-08-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51424
+ * cp-tree.h (LOOKUP_DELEGATING_CONS): Add.
+ * init.c (perform_target_ctor): Use it.
+ * call.c (build_special_member_call): Diagnose self-delegating
+ constructors.
+
+2013-08-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::declaration): Declare as
+ overrider.
+ (cxx_pretty_printer::declaration_specifiers): Likewise.
+ (cxx_pretty_printer::function_specifier): Likewise.
+ (cxx_pretty_printer::declarator): Likewise.
+ (cxx_pretty_printer::direct_declarator): Likewise.
+ (cxx_pretty_printer::abstract_declarator): Likewise.
+ (cxx_pretty_printer::direct_abstract_declarator): Likewise.
+ (pp_cxx_declaration): Remove.
+ * cxx-pretty-print.c (cxx_pretty_printer::function_specifier):
+ Rename from pp_cxx_function_specifier. Adjust.
+ (cxx_pretty_printer::declaration_specifiers): Rename from
+ pp_cxx_decl_specifier_seq. Adjust.
+ (cxx_pretty_printer::direct_declarator): Rename from
+ pp_cxx_direct_declarator. Adjust.
+ (cxx_pretty_printer::declarator): Rename from pp_cxx_declarator.
+ Adjust.
+ (cxx_pretty_printer::abstract_declarator): Rename from
+ pp_cxx_abstract_declarator. Adjust.
+ (cxx_pretty_printer::direct_abstract_declarator): Rename from
+ pp_cxx_direct_abstract_declarator. Adjust.
+ (cxx_pretty_printer::declaration): Rename from
+ pp_cxx_declaration. Adjust.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ declaration, declaration_specifiers, function_specifier,
+ declarator, direct_declarator, abstract_declarator,
+ direct_abstract_declarator.
+ * error.c (dump_decl): Adjust.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ Correct previous patch to not mark terminate as LEAF.
+ * class.c (build_vtbl_initializer): Drop LEAF
+ * decl.c (cxx_init_decl_processing): Likewise.
+ (push_throw_library_fn): Likewise.
+ * except.c (init_exception_processing): Likewise.
+ (do_begin_catch): Likewise.
+ (do_end_catch): Likewise.
+ (do_allocate_exception): Likewise.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * class.c (build_vtbl_initializer): Make __cxa_deleted_virtual
+ ECF_NORETURN | ECF_LEAF
+ * cp-tree.h (build_library_fn_ptr, build_cp_library_fn_ptr,
+ push_library_fn, push_void_library_fn): Update prototype.
+ * decl.c (build_library_fn_1): Remove.
+ (push_cp_library_fn, build_cp_library_fn): Update to take ECF flags.
+ (cxx_init_decl_processing): Update; global_delete_fndecl is ECF_NOTROW;
+ __cxa_pure_virtual is ECF_NORETURN | ECF_NORETURN | ECF_LEAF.
+ (build_library_fn_1): Add ecf_flags argument; rename to ...
+ (build_library_fn): ... this one.
+ (build_cp_library_fn): Take ecf_flags; do not copy NOTHROW flag.
+ (build_library_fn_ptr): Take ecf_flags.
+ (build_cp_library_fn_ptr): Likewise.
+ (push_library_fn): Likewise.
+ (push_cp_library_fn): Likewise.
+ (push_void_library_fn): Likewise.
+ (push_throw_library_fn): All throws are ECF_NORETURN.
+ (__cxa_atexit, __cxa_thread_atexit): Add ECF_LEAF | ECF_NOTHROW attributes.
+ (expand_static_init): __cxa_guard_acquire, __cxa_guard_release,
+ __cxa_guard_abort are ECF_NOTHROW | ECF_LEAF.
+ * except.c (init_exception_processing): terminate is
+ ECF_NOTHROW | ECF_NORETURN | ECF_LEAF.
+ (declare_nothrow_library_fn): Add ecf_flags parameter.
+ (__cxa_get_exception_ptr): Is ECF_NOTHROW | ECF_PURE | ECF_LEAF |
+ ECF_TM_PURE.
+ (do_begin_catch): cxa_begin_catch and _ITM_cxa_begin_catch
+ are ECF_NOTHROW | ECF_LEAF.
+ (do_end_catch): __cxa_end_catch and _ITM_cxa_end_catch is
+ ECF_LEAF.
+ (do_allocate_exception): _cxa_allocate_exception
+ and _ITM_cxa_allocate_exception are ECF_NOTHROW | ECF_MALLOC
+ | ECF_LEAF
+ (do_free_exception): __cxa_free_exception is
+ ECF_NOTHROW | ECF_LEAF.
+ * rtti.c (build_dynamic_cast_1): __dynamic_cast
+ is ECF_LEAF | ECF_PURE | ECF_NOTHROW.
+
+2013-08-29 Adam Butcher <adam@jessamine.co.uk>
+
+ * error.c (dump_lambda_function): New function, dependent on ...
+ (dump_substitution): ... this new function, factored out of ...
+ (subst_to_string): ... here and ...
+ (dump_function_decl): ... here. Updated to early-out with call to
+ dump_lambda_function after determining template bindings.
+
+2013-08-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58255
+ * init.c (build_aggr_init): When init == void_type_node do not
+ set LOOKUP_ONLYCONVERTING.
+
+2013-08-27 Caroline Tice <cmtice@google.com>
+
+ * vtable-class-hierarchy.c: Remove unnecessary include statements.
+ (MAX_SET_SIZE): Remove unnecessary constant.
+ (register_construction_vtables): Make vtable_ptr_array parameter
+ into a vector; remove num_args parameter. Change array accesses to
+ vector accesses.
+ (register_other_binfo_vtables): Ditto.
+ (insert_call_to_register_set): Ditto.
+ (insert_call_to_register_pair): Ditto.
+ (output_set_info): Ditto. Also change warning calls to warning_at
+ calls, and fix format of warning messages.
+ (register_all_pairs): Change vtbl_ptr_array from an array into a
+ vector. Remove num_vtable_args (replace with calls to vector length).
+ Change array stores & accesses to vector functions. Change calls to
+ register_construction_vtables, register_other_binfo_vtables,
+ insert_call_to_register_set, insert_call_to_register_pair and
+ output_set_info to match their new signatures. Change warning to
+ warning_at and fix the format of the warning message.
+
+2013-08-27 Jakub Jelinek <jakub@redhat.com>
+ Aldy Hernandez <aldyh@redhat.com>
+
+ * cp-tree.h (CP_OMP_CLAUSE_INFO): Adjust range for new clauses.
+
+2013-08-27 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (grokfndecl): Remove old bison hack.
+
+2013-08-26 Jan Hubicka <jh@suse.cz>
+
+ * cp-tree.h (DECL_CONSTRUCTOR_P, DECL_DESTRUCTOR_P): Use
+ middle-end flag.
+
+2013-08-26 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::unary_expression):
+ Declare as overrider.
+ (cxx_pretty_printer::multiplicative_expression): Likewise.
+ (cxx_pretty_printer::conditional_expression): Likewise.
+ (cxx_pretty_printer::assignment_expression): Likewise.
+ (cxx_pretty_printer::expression): Likewise.
+ * cxx-pretty-print.c (cxx_pretty_printer::unary_expression):
+ Rename from pp_cxx_unary_expression. Adjust.
+ (cxx_pretty_printer::multiplicative_expression): Rename from
+ pp_cxx_multiplicative_expression. Adjust.
+ (cxx_pretty_printer::conditional_expression): Rename from
+ pp_cxx_conditional_expression. Adjust.
+ (cxx_pretty_printer::assignment_expression): Rename from
+ pp_cxx_assignment_expression. Adjust.
+ (cxx_pretty_printer::expression): Rename from pp_cxx_expression.
+ Adjust.
+ (cxx_pretty_printer::cxx_pretty_printer): Dot not assign to
+ unary_expression, multiplicative_expression,
+ conditional_expression, assignment_expression, expression.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::postfix_expression):
+ Declare as overrider.
+ * cxx-pretty-print.c (cxx_pretty_printer::postfix_expression):
+ Rename from pp_cxx_postfix_expression. Adjust.
+ (pp_cxx_expression): Use pp_postfix_expression.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ postfix_expression.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::primary_expression): Now
+ an overrider of c_pretty_printer::primary_expression.
+ * cxx-pretty-print.c (cxx_pretty_printer::primary_expression):
+ Rename from pp_cxx_primary_expression. Adjust.
+ (pp_cxx_postfix_expression): Use pp_primary_expression.
+ (pp_cxx_ctor_initializer): Likewise.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ primary_expression.
+
+2013-08-23 Jan Hubicka <jh@suse.cz>
+
+ * cp-tree.h (struct lang_type_class): Free is_final bit.
+ (CLASSTYPE_FINAL): Define using TYPE_FINAL_P.
+ (DECL_FINAL_P): Remove.
+ * pt.c (instantiate_class_template_1): Guard that CLASSTYPE_FINAL
+ is called on CLASS_TYPE_P.
+
+2013-08-25 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.c (M_): Remove.
+ (pp_cxx_unqualified_id): Use translate_string instead of M_.
+ (pp_cxx_canonical_template_parameter): Likewise.
+
+2013-08-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::id_expression): Declare.
+ * cxx-pretty-print.c (cxx_pretty_printer::id_expression): Rename
+ from pp_cxx_id_expression. Adjust.
+ (pp_cxx_userdef_literal): Use pp_id_expression.
+ (pp_cxx_primary_expression): Likewise.
+ (pp_cxx_direct_declarator): Likewise.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to
+ id_expression.
+
+2013-08-24 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (cxx_pretty_printer::constant): Now a member
+ function, overriding c_pretty_printer::constant.
+ * cxx-pretty-print.c (cxx_pretty_printer::constant): Rename from
+ pp_cxx_constant. Adjust.
+ (cxx_pretty_printer::cxx_pretty_printer): Do not assign to constant.
+
+2013-08-23 Gabriel Dos Reis <gdr@integrable-solutiobs.net>
+
+ * cp-objcp-common.c (cxx_initialize_diagnostics): Call a
+ destructor for the early printer.
+ * error.c (type_to_string): Use pp_buffer.
+
+2013-08-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56380
+ * class.c (check_field_decls): Check for const mutable and const
+ reference data members.
+
+2013-08-22 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (init_error): Remove calls to pp_construct and
+ pp_cxx_pretty_printer_init. Initialize cxx_pp with placement-new.
+ * cxx-pretty-print.h (cxx_pretty_printer::cxx_pretty_printer): Declare.
+ (cxx_pretty_printer_init): Remove.
+ * cxx-pretty-print.c (cxx_pretty_printer::cxx_pretty_printer):
+ Rename from cxx_pretty_printer_init. Adjust.
+ * cp-objcp-common.c (cxx_initialize_diagnostics): Simplify
+ initialization of C++ diagnostics pretty printer.
+
+2013-08-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * call.c (build_new_method_call_1): Use INDIRECT_REF_P.
+ * cp-tree.h (REFERENCE_REF_P): Likewise.
+ * semantics.c (finish_offsetof): Likewise.
+
+2013-08-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56130
+ * semantics.c (finish_id_expression): Handle deprecated references.
+
+2013-08-20 Jason Merrill <jason@redhat.com>
+
+ PR c++/58119
+ * cvt.c (build_expr_type_conversion): Don't complain about a
+ template that can't match the desired type category.
+
+2013-08-20 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (pp_ggc_formatted_text): New.
+ (type_as_string): Use it in lieu of pp_formatted_text.
+ (type_as_string_translate): Likewise.
+ (expr_as_string): Likewise.
+ (decl_as_string): Likewise.
+ (decl_as_string_translate): Likewise.
+ (lang_decl_name): Likewise.
+ (decl_to_string): Likewise.
+ (expr_to_string): Likewise.
+ (fndecl_to_string): Likewise.
+ (parm_to_string): Likewise.
+ (type_to_string): Likewise.
+ (args_to_string): Likewise.
+ (subst_to_string): Likewise.
+
+2013-08-19 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c/57490
+ * cp-array-notation.c (cp_expand_cond_array_notations): Added a
+ check for truth values.
+ (expand_array_notation_exprs): Added truth values case. Removed an
+ unwanted else. Added for-loop to walk through subtrees in default
+ case.
+ * call.c (build_cxx_call): Inherited the type of the array notation for
+ certain built-in array notation functions.
+
+2013-08-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (cp_parser_lambda_introducer, cp_parser_decltype_expr):
+ Use cp_parser_lookup_name_simple.
+
+2013-08-19 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * name-lookup.h (pop_bindings_and_leave_scope): Declare.
+ * name-lookup.c (pop_bindings_and_leave_scope): Define.
+ * parser.c (cp_parser_lambda_declarator_opt,
+ cp_parser_direct_declarator, cp_parser_cache_defarg): Use it.
+
+2013-08-17 Jason Merrill <jason@redhat.com>
+
+ PR c++/58083
+ * name-lookup.c (push_class_level_binding_1): It's OK to push a
+ lambda type after the enclosing type is complete.
+
+2013-08-17 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_scope): Add a cxx_pretty_printer parameter.
+ Adjust callers.
+ (dump_template_argument): Likewise.
+ (dump_template_argument_list): Likewise.
+ (dump_template_parameter): Likewise.
+ (dump_template_bindings): Likewise.
+ (dump_alias_template_specialization): Likewise.
+ (dump_type): Likewise.
+ (dump_typename): Likewise.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_simple_decl): Likewise.
+ (dump_decl): Likewise.
+ (dump_template_decl): Likewise.
+ (dump_function_decl): Likewise.
+ (dump_parameters): Likewise.
+ (dump_ref_qualifier): Likewise.
+ (dump_exception_spec): Likewise.
+ (dump_function_name): Likewise.
+ (dump_template_parms): Likewise.
+ (dump_call_expr_args): Likewise.
+ (dump_aggr_init_expr_args): Likewise.
+ (dump_expr_list): Likewise.
+ (dump_expr_init_vec): Likewise.
+ (dump_expr): Likewise.
+ (dump_binary_op): Likewise.
+ (dump_unary_op): Likewise.
+
+2013-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51912
+ * cp-tree.h (LOOKUP_NO_NON_INTEGRAL): Add.
+ * decl.c (case_conversion): Use it.
+ * call.c (standard_conversion): Likewise.
+ (implicit_conversion): Adjust.
+
+2013-08-13 Adam Butcher <adam@jessamine.co.uk>
+
+ * pt.c: Grammar fix in comments ("it's" to "its").
+
+2013-08-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * decl.c (warn_extern_redeclared_static, duplicate_decls,
+ check_elaborated_type_specifier): Use error + inform.
+ * friend.c (make_friend_class): Likewise.
+ * semantics.c (finish_id_expression): Likewise.
+
+2013-08-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ Revert:
+ 2013-08-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46206
+ * name-lookup.c (lookup_name_real_1): Handle iter->type before
+ iter->value.
+
+2013-08-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46206
+ * name-lookup.c (lookup_name_real_1): Handle iter->type before
+ iter->value.
+
+2013-08-06 Caroline Tice <cmtice@google.com>
+
+ * Make-lang.in (*CXX_AND_OBJCXX_OBJS): Add vtable-class-hierarchy.o to
+ list.
+ (vtable-class-hierarchy.o): Add build rule.
+ * cp-tree.h (vtv_start_verification_constructor_init_function): New
+ extern function decl.
+ (vtv_finish_verification_constructor_init_function): New extern
+ function decl.
+ (build_vtbl_address): New extern function decl.
+ (get_mangled_vtable_map_var_name): New extern function decl.
+ (vtv_compute_class_hierarchy_transitive_closure): New extern function
+ decl.
+ (vtv_generate_init_routine): New extern function decl.
+ (vtv_save_class_info): New extern function decl.
+ (vtv_recover_class_info): New extern function decl.
+ (vtv_build_vtable_verify_fndecl): New extern function decl.
+ * class.c (finish_struct_1): Add call to vtv_save_class_info if
+ flag_vtable_verify is true.
+ * config-lang.in: Add vtable-class-hierarchy.c to gtfiles list.
+ * vtable-class-hierarchy.c: New file.
+ * mangle.c (get_mangled_vtable_map_var_name): New function.
+ * decl2.c (start_objects): Update function comment.
+ (cp_write_global_declarations): Call vtv_recover_class_info,
+ vtv_compute_class_hierarchy_transitive_closure and
+ vtv_build_vtable_verify_fndecl, before calling
+ finalize_compilation_unit, and call vtv_generate_init_rount after, IFF
+ flag_vtable_verify is true.
+ (vtv_start_verification_constructor_init_function): New function.
+ (vtv_finish_verification_constructor_init_function): New function.
+ * init.c (build_vtbl_address): Remove static qualifier from function.
+
+2013-08-06 Jason Merrill <jason@redhat.com>
+
+ PR c++/57825
+ * tree.c (strip_typedefs) [METHOD_TYPE]: Preserve ref-qualifier.
+
+2013-08-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58080
+ * typeck.c (cp_pointer_int_sum): Add tsubst_flags_t parameter.
+ (cp_build_binary_op): Adjust.
+
+2013-08-04 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * cxx-pretty-print.h (pp_c_base): Remove.
+ (cxx_pretty_printer): Derive from c_pretty_printer.
+ Adjust macros using pp_c_base.
+ * cp-objcp-common.c (cxx_initialize_diagnostics): Do not call pp_base.
+ * cxx-pretty-print.c (pp_cxx_nonconsecutive_character): Likewise.
+ (pp_cxx_colon_colon): Likewise.
+ (pp_cxx_separate_with): Likewise.
+ (pp_cxx_storage_class_specifier): Do not call pp_c_base.
+ (pp_cxx_expression_list): Likewise.
+ (pp_cxx_space_for_pointer_operator): Likewise.
+ (pp_cxx_init_declarator): Likewise.
+ (pp_cxx_call_argument_list): Likewise.
+ (pp_cxx_constant): Likewise.
+ (pp_cxx_postfix_expression): Likewise.
+ (pp_cxx_new_expression): Likewise.
+ (pp_cxx_unary_expression): Likewise.
+ (pp_cxx_cast_expression): Likewise.
+ (pp_cxx_conditional_expression): Likewise.
+ (pp_cxx_assignment_expression): Likewise.
+ (pp_cxx_expression): Likewise.
+ (pp_cxx_function_specifier): Likewise.
+ (pp_cxx_decl_specifier_seq): Likewise.
+ (pp_cxx_simple_type_specifier): Likewise.
+ (pp_cxx_type_specifier_seq): Likewise.
+ (pp_cxx_ptr_operator): Likewise.
+ (pp_cxx_parameter_declaration_clause): Likewise.
+ (pp_cxx_direct_declarator): Likewise.
+ (pp_cxx_direct_abstract_declarator): Likewise.
+ (pp_cxx_type_id): Likewise.
+ (pp_cxx_statement): Likewise.
+ (pp_cxx_pretty_printer_init): Tidy.
+ * error.c (init_error): Do not use pp_base.
+ (dump_aggr_type): Likewise.
+ (dump_type_prefix): Likewise.
+ (dump_type_suffix): Likewise.
+ (dump_global_iord): Likewise.
+ (dump_decl): Likewise.
+ (dump_function_decl): Likewise.
+ (dump_ref_qualifier): Likewise.
+ (reinit_cxx_pp): Likewise.
+ (decl_as_dwarf_string): Likewise.
+ (lang_decl_dwarf_name): Likewise.
+ (type_to_string): Likewise.
+ (cv_to_string): Likewise.
+ (cxx_print_error_function): Likewise.
+ (cp_diagnostic_starter): Likewise.
+ (cp_diagnostic_finalizer): Likewise.
+ (cp_print_error_function): Likewise.
+ (print_instantiation_context): Likewise.
+ (cp_printer): Likewise.
+
+2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_type_prefix): Use specialized pretty printer
+ functions instead of pp_string or operators and punctuators.
+ (dump_decl): Likewise.
+ (dump_expr): Likewise.
+
+2013-08-03 Jason Merrill <jason@redhat.com>
+
+ DR 1286
+ * pt.c (get_underlying_template): New.
+ (convert_template_argument, lookup_template_class_1): Use it.
+
+ DR 1430
+ PR c++/51239
+ * pt.c (pack_expansion_args_count): Rename from
+ any_pack_expanson_args_p.
+ (coerce_template_parms): Reject pack expansion to
+ non-pack template parameter of alias template.
+
+2013-08-03 Gabriel Dos Reis <gdr@integrable-solutions.net>
+
+ * error.c (dump_aggr_type): Use specialized pretty printer
+ functions instead of pp_character.
+ (dump_type_prefix): Likewise.
+ (dump_simple_decl): Likewise.
+ (type_to_string): Likewise.
+
+2013-08-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * cp-tree.h (finish_stmt): Do not declare.
+ * decl.c (finish_stmt): Do not define.
+ * parser.c (cp_parser_expression_statement,
+ cp_parser_declaration_statement,
+ cp_parser_transaction_cancel): Don't call finish_stmt.
+ * semantics.c (finish_expr_stmt, finish_if_stmt,
+ finish_while_stmt, finish_do_stmt, finish_return_stmt,
+ finish_for_stmt, finish_switch_stmt, finish_compound_stmt,
+ finish_transaction_stmt): Likewise.
+
+2013-08-01 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/54537
+ * cp-tree.h: Check OVL_USED with OVERLOAD_CHECK.
+ * name-lookup.c (do_nonmember_using_decl): Make sure we have an
+ OVERLOAD before calling OVL_USED. Call diagnose_name_conflict
+ instead of issuing an error without mentioning the conflicting
+ declaration.
+
+2013-07-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * parser.c (cp_parser_sizeof_pack): Check cp_parser_identifier
+ return value for error_mark_node.
+
+2013-07-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57673
+ * parser.c (cp_parser_cache_defarg): In an NSDMI don't stop when
+ token->type == CPP_ELLIPSIS.
+
+2013-07-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57947
+ * call.c (is_std_init_list): Return false if cxx_dialect == cxx98.
+
+2013-07-29 Jason Merrill <jason@redhat.com>
+
+ PR c++/57901
+ * semantics.c (build_data_member_initialization, constexpr_fn_retval):
+ Use break_out_target_exprs instead of unshare_expr.
+
+2013-07-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57948
+ * call.c (initialize_reference): Don't crash when reference_binding
+ returns a conv with conv->kind == ck_ambig.
+
+2013-07-29 Jason Merrill <jason@redhat.com>
+
+ * mangle.c (write_name): Check for null context.
+ (write_unscoped_name): Allow PARM_DECL context.
+
2013-07-25 Paolo Carlini <paolo.carlini@oracle.com>
PR c++/57981
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 2cb919a2172..65dfe081e0b 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -80,7 +80,8 @@ CXX_AND_OBJCXX_OBJS = cp/call.o cp/decl.o cp/expr.o cp/pt.o cp/typeck2.o \
cp/typeck.o cp/cvt.o cp/except.o cp/friend.o cp/init.o cp/method.o \
cp/search.o cp/semantics.o cp/tree.o cp/repo.o cp/dump.o cp/optimize.o \
cp/mangle.o cp/cp-objcp-common.o cp/name-lookup.o cp/cxx-pretty-print.o \
- cp/cp-gimplify.o cp/cp-array-notation.o cp/lambda.o $(CXX_C_OBJS)
+ cp/cp-gimplify.o cp/cp-array-notation.o cp/lambda.o \
+ cp/vtable-class-hierarchy.o $(CXX_C_OBJS)
# Language-specific object files for C++.
CXX_OBJS = cp/cp-lang.o c-family/stub-objc.o $(CXX_AND_OBJCXX_OBJS)
@@ -341,10 +342,16 @@ cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \
c-family/c-objc.h tree-pretty-print.h $(CXX_PARSER_H) $(TIMEVAR_H)
cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) $(C_COMMON_H) \
$(TM_H) coretypes.h pointer-set.h tree-iterator.h $(SPLAY_TREE_H)
-
+cp/vtable-class-hierarchy.o: cp/vtable-class-hierarchy.c \
+ $(TM_H) $(TIMEVAR_H) $(CXX_TREE_H) intl.h $(CXX_PARSER_H) cp/decl.h \
+ $(FLAGS_H) $(DIAGNOSTIC_CORE_H) output.h $(CGRAPH_H) c-family/c-common.h \
+ c-family/c-objc.h $(PLUGIN_H) \
+ tree-iterator.h vtable-verify.h $(GIMPLE_H) \
+ gt-cp-vtable-class-hierarchy.h
cp/name-lookup.o: cp/name-lookup.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(CXX_TREE_H) $(TIMEVAR_H) gt-cp-name-lookup.h $(PARAMS_H) \
$(DIAGNOSTIC_CORE_H) $(FLAGS_H) debug.h pointer-set.h
+cp/lambda.o: cp/lambda.c $(CXX_TREE_H) $(CGRAPH_H) $(VEC_H) $(SYSTEM_H) coretypes.h
cp/cxx-pretty-print.o: cp/cxx-pretty-print.c $(CXX_PRETTY_PRINT_H) \
$(CONFIG_H) $(SYSTEM_H) $(TM_H) coretypes.h $(CXX_TREE_H) tree-pretty-print.h
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index e8d526075a7..3ed73b80374 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1314,7 +1314,8 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
/* As an extension, allow conversion to complex type. */
else if (ARITHMETIC_TYPE_P (to))
{
- if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE)
+ if (! (INTEGRAL_CODE_P (fcode)
+ || (fcode == REAL_TYPE && !(flags & LOOKUP_NO_NON_INTEGRAL)))
|| SCOPED_ENUM_P (from))
return NULL;
conv = build_conv (ck_std, to, conv);
@@ -1681,7 +1682,7 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p,
resolution, or after we've chosen one. */
flags &= (LOOKUP_ONLYCONVERTING|LOOKUP_NO_CONVERSION|LOOKUP_COPY_PARM
|LOOKUP_NO_TEMP_BIND|LOOKUP_NO_RVAL_BIND|LOOKUP_PREFER_RVALUE
- |LOOKUP_NO_NARROWING|LOOKUP_PROTECT);
+ |LOOKUP_NO_NARROWING|LOOKUP_PROTECT|LOOKUP_NO_NON_INTEGRAL);
/* FIXME: actually we don't want warnings either, but we can't just
have 'complain &= ~(tf_warning|tf_error)' because it would cause
@@ -7176,6 +7177,33 @@ build_cxx_call (tree fn, int nargs, tree *argarray,
&& !check_builtin_function_arguments (fndecl, nargs, argarray))
return error_mark_node;
+ /* If it is a built-in array notation function, then the return type of
+ the function is the element type of the array passed in as array
+ notation (i.e. the first parameter of the function). */
+ if (flag_enable_cilkplus && TREE_CODE (fn) == CALL_EXPR)
+ {
+ enum built_in_function bif =
+ is_cilkplus_reduce_builtin (CALL_EXPR_FN (fn));
+ if (bif == BUILT_IN_CILKPLUS_SEC_REDUCE_ADD
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MUL
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MAX
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MIN
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE
+ || bif == BUILT_IN_CILKPLUS_SEC_REDUCE_MUTATING)
+ {
+ /* for bif == BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_ZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_ZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ANY_NONZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_ALL_NONZERO or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_MIN_IND or
+ BUILT_IN_CILKPLUS_SEC_REDUCE_MAX_IND
+ The pre-defined return-type is the correct one. */
+ tree array_ntn = CALL_EXPR_ARG (fn, 0);
+ TREE_TYPE (fn) = TREE_TYPE (array_ntn);
+ return fn;
+ }
+ }
+
/* Some built-in function calls will be evaluated at compile-time in
fold (). Set optimize to 1 when folding __builtin_constant_p inside
a constexpr function so that fold_builtin_1 doesn't fold it to 0. */
@@ -7414,6 +7442,14 @@ build_special_member_call (tree instance, tree name, vec<tree, va_gc> **args,
if (allocated != NULL)
release_tree_vector (allocated);
+ if ((complain & tf_error)
+ && (flags & LOOKUP_DELEGATING_CONS)
+ && name == complete_ctor_identifier
+ && TREE_CODE (ret) == CALL_EXPR
+ && (DECL_ABSTRACT_ORIGIN (TREE_OPERAND (CALL_EXPR_FN (ret), 0))
+ == current_function_decl))
+ error ("constructor delegates to itself");
+
return ret;
}
@@ -7640,7 +7676,7 @@ build_new_method_call_1 (tree instance, tree fns, vec<tree, va_gc> **args,
if (init)
{
- if (TREE_CODE (instance) == INDIRECT_REF
+ if (INDIRECT_REF_P (instance)
&& integer_zerop (TREE_OPERAND (instance, 0)))
return get_target_expr_sfinae (init, complain);
init = build2 (INIT_EXPR, TREE_TYPE (instance), instance, init);
@@ -9282,10 +9318,14 @@ initialize_reference (tree type, tree expr,
return error_mark_node;
}
- gcc_assert (conv->kind == ck_ref_bind);
-
- /* Perform the conversion. */
- expr = convert_like (conv, expr, complain);
+ if (conv->kind == ck_ref_bind)
+ /* Perform the conversion. */
+ expr = convert_like (conv, expr, complain);
+ else if (conv->kind == ck_ambig)
+ /* We gave an error in build_user_type_conversion_1. */
+ expr = error_mark_node;
+ else
+ gcc_unreachable ();
/* Free all the conversions we allocated. */
obstack_free (&conversion_obstack, p);
@@ -9392,6 +9432,8 @@ is_std_init_list (tree type)
/* Look through typedefs. */
if (!TYPE_P (type))
return false;
+ if (cxx_dialect == cxx98)
+ return false;
type = TYPE_MAIN_VARIANT (type);
return (CLASS_TYPE_P (type)
&& CP_TYPE_CONTEXT (type) == std_node
diff --git a/gcc/cp/class.c b/gcc/cp/class.c
index f0c515269e2..3d34b92cfb1 100644
--- a/gcc/cp/class.c
+++ b/gcc/cp/class.c
@@ -2773,15 +2773,93 @@ warn_hidden (tree t)
}
}
+/* Recursive helper for finish_struct_anon. */
+
+static void
+finish_struct_anon_r (tree field, bool complain)
+{
+ bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
+ tree elt = TYPE_FIELDS (TREE_TYPE (field));
+ for (; elt; elt = DECL_CHAIN (elt))
+ {
+ /* We're generally only interested in entities the user
+ declared, but we also find nested classes by noticing
+ the TYPE_DECL that we create implicitly. You're
+ allowed to put one anonymous union inside another,
+ though, so we explicitly tolerate that. We use
+ TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that
+ we also allow unnamed types used for defining fields. */
+ if (DECL_ARTIFICIAL (elt)
+ && (!DECL_IMPLICIT_TYPEDEF_P (elt)
+ || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
+ continue;
+
+ if (TREE_CODE (elt) != FIELD_DECL)
+ {
+ if (complain)
+ {
+ if (is_union)
+ permerror (input_location,
+ "%q+#D invalid; an anonymous union can "
+ "only have non-static data members", elt);
+ else
+ permerror (input_location,
+ "%q+#D invalid; an anonymous struct can "
+ "only have non-static data members", elt);
+ }
+ continue;
+ }
+
+ if (complain)
+ {
+ if (TREE_PRIVATE (elt))
+ {
+ if (is_union)
+ permerror (input_location,
+ "private member %q+#D in anonymous union", elt);
+ else
+ permerror (input_location,
+ "private member %q+#D in anonymous struct", elt);
+ }
+ else if (TREE_PROTECTED (elt))
+ {
+ if (is_union)
+ permerror (input_location,
+ "protected member %q+#D in anonymous union", elt);
+ else
+ permerror (input_location,
+ "protected member %q+#D in anonymous struct", elt);
+ }
+ }
+
+ TREE_PRIVATE (elt) = TREE_PRIVATE (field);
+ TREE_PROTECTED (elt) = TREE_PROTECTED (field);
+
+ /* Recurse into the anonymous aggregates to handle correctly
+ access control (c++/24926):
+
+ class A {
+ union {
+ union {
+ int i;
+ };
+ };
+ };
+
+ int j=A().i; */
+ if (DECL_NAME (elt) == NULL_TREE
+ && ANON_AGGR_TYPE_P (TREE_TYPE (elt)))
+ finish_struct_anon_r (elt, /*complain=*/false);
+ }
+}
+
/* Check for things that are invalid. There are probably plenty of other
things we should check for also. */
static void
finish_struct_anon (tree t)
{
- tree field;
-
- for (field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
+ for (tree field = TYPE_FIELDS (t); field; field = DECL_CHAIN (field))
{
if (TREE_STATIC (field))
continue;
@@ -2790,53 +2868,7 @@ finish_struct_anon (tree t)
if (DECL_NAME (field) == NULL_TREE
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
- {
- bool is_union = TREE_CODE (TREE_TYPE (field)) == UNION_TYPE;
- tree elt = TYPE_FIELDS (TREE_TYPE (field));
- for (; elt; elt = DECL_CHAIN (elt))
- {
- /* We're generally only interested in entities the user
- declared, but we also find nested classes by noticing
- the TYPE_DECL that we create implicitly. You're
- allowed to put one anonymous union inside another,
- though, so we explicitly tolerate that. We use
- TYPE_ANONYMOUS_P rather than ANON_AGGR_TYPE_P so that
- we also allow unnamed types used for defining fields. */
- if (DECL_ARTIFICIAL (elt)
- && (!DECL_IMPLICIT_TYPEDEF_P (elt)
- || TYPE_ANONYMOUS_P (TREE_TYPE (elt))))
- continue;
-
- if (TREE_CODE (elt) != FIELD_DECL)
- {
- if (is_union)
- permerror (input_location, "%q+#D invalid; an anonymous union can "
- "only have non-static data members", elt);
- else
- permerror (input_location, "%q+#D invalid; an anonymous struct can "
- "only have non-static data members", elt);
- continue;
- }
-
- if (TREE_PRIVATE (elt))
- {
- if (is_union)
- permerror (input_location, "private member %q+#D in anonymous union", elt);
- else
- permerror (input_location, "private member %q+#D in anonymous struct", elt);
- }
- else if (TREE_PROTECTED (elt))
- {
- if (is_union)
- permerror (input_location, "protected member %q+#D in anonymous union", elt);
- else
- permerror (input_location, "protected member %q+#D in anonymous struct", elt);
- }
-
- TREE_PRIVATE (elt) = TREE_PRIVATE (field);
- TREE_PROTECTED (elt) = TREE_PROTECTED (field);
- }
- }
+ finish_struct_anon_r (field, /*complain=*/true);
}
}
@@ -3500,6 +3532,22 @@ check_field_decls (tree t, tree *access_decls,
if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (type))
CLASSTYPE_HAS_MUTABLE (t) = 1;
+ if (DECL_MUTABLE_P (x))
+ {
+ if (CP_TYPE_CONST_P (type))
+ {
+ error ("member %q+D cannot be declared both %<const%> "
+ "and %<mutable%>", x);
+ continue;
+ }
+ if (TREE_CODE (type) == REFERENCE_TYPE)
+ {
+ error ("member %q+D cannot be declared as a %<mutable%> "
+ "reference", x);
+ continue;
+ }
+ }
+
if (! layout_pod_type_p (type))
/* DR 148 now allows pointers to members (which are POD themselves),
to be allowed in POD structs. */
@@ -6485,6 +6533,9 @@ finish_struct_1 (tree t)
maybe_suppress_debug_info (t);
+ if (flag_vtable_verify)
+ vtv_save_class_info (t);
+
dump_class_hierarchy (t);
/* Finish debugging output for this type. */
@@ -8854,7 +8905,7 @@ build_vtbl_initializer (tree binfo,
if (!get_global_value_if_present (fn, &fn))
fn = push_library_fn (fn, (build_function_type_list
(void_type_node, NULL_TREE)),
- NULL_TREE);
+ NULL_TREE, ECF_NORETURN);
if (!TARGET_VTABLE_USES_DESCRIPTORS)
init = fold_convert (vfunc_ptr_type_node,
build_fold_addr_expr (fn));
diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in
index 1597bf97017..4ea9b4d9a2b 100644
--- a/gcc/cp/config-lang.in
+++ b/gcc/cp/config-lang.in
@@ -29,4 +29,4 @@ compilers="cc1plus\$(exeext)"
target_libs="target-libstdc++-v3"
-gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.h \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c \$(srcdir)/cp/except.c"
+gtfiles="\$(srcdir)/cp/rtti.c \$(srcdir)/cp/mangle.c \$(srcdir)/cp/name-lookup.h \$(srcdir)/cp/name-lookup.c \$(srcdir)/cp/cp-tree.h \$(srcdir)/cp/decl.h \$(srcdir)/cp/call.c \$(srcdir)/cp/decl.c \$(srcdir)/cp/decl2.c \$(srcdir)/cp/pt.c \$(srcdir)/cp/repo.c \$(srcdir)/cp/semantics.c \$(srcdir)/cp/tree.c \$(srcdir)/cp/parser.h \$(srcdir)/cp/parser.c \$(srcdir)/cp/method.c \$(srcdir)/cp/typeck2.c \$(srcdir)/c-family/c-common.c \$(srcdir)/c-family/c-common.h \$(srcdir)/c-family/c-objc.h \$(srcdir)/c-family/c-lex.c \$(srcdir)/c-family/c-pragma.h \$(srcdir)/c-family/c-pragma.c \$(srcdir)/cp/class.c \$(srcdir)/cp/cp-objcp-common.c \$(srcdir)/cp/cp-lang.c \$(srcdir)/cp/except.c \$(srcdir)/cp/vtable-class-hierarchy.c"
diff --git a/gcc/cp/cp-array-notation.c b/gcc/cp/cp-array-notation.c
index eb6a70d835c..f4581f01e57 100644
--- a/gcc/cp/cp-array-notation.c
+++ b/gcc/cp/cp-array-notation.c
@@ -857,6 +857,19 @@ cp_expand_cond_array_notations (tree orig_stmt)
return error_mark_node;
}
}
+ else if (truth_value_p (TREE_CODE (orig_stmt)))
+ {
+ size_t left_rank = 0, right_rank = 0;
+ tree left_expr = TREE_OPERAND (orig_stmt, 0);
+ tree right_expr = TREE_OPERAND (orig_stmt, 1);
+ if (!find_rank (EXPR_LOCATION (left_expr), left_expr, left_expr, true,
+ &left_rank)
+ || !find_rank (EXPR_LOCATION (right_expr), right_expr, right_expr,
+ true, &right_rank))
+ return error_mark_node;
+ if (right_rank == 0 && left_rank == 0)
+ return orig_stmt;
+ }
if (!find_rank (EXPR_LOCATION (orig_stmt), orig_stmt, orig_stmt, true,
&rank))
@@ -1213,6 +1226,12 @@ expand_array_notation_exprs (tree t)
if (TREE_OPERAND (t, 0) == error_mark_node)
return TREE_OPERAND (t, 0);
return t;
+ case TRUTH_ANDIF_EXPR:
+ case TRUTH_ORIF_EXPR:
+ case TRUTH_AND_EXPR:
+ case TRUTH_OR_EXPR:
+ case TRUTH_XOR_EXPR:
+ case TRUTH_NOT_EXPR:
case COND_EXPR:
t = cp_expand_cond_array_notations (t);
if (TREE_CODE (t) == COND_EXPR)
@@ -1222,8 +1241,6 @@ expand_array_notation_exprs (tree t)
COND_EXPR_ELSE (t) =
expand_array_notation_exprs (COND_EXPR_ELSE (t));
}
- else
- t = expand_array_notation_exprs (t);
return t;
case FOR_STMT:
if (contains_array_notation_expr (FOR_COND (t)))
diff --git a/gcc/cp/cp-objcp-common.c b/gcc/cp/cp-objcp-common.c
index 82f684a1c7b..d70766f3a06 100644
--- a/gcc/cp/cp-objcp-common.c
+++ b/gcc/cp/cp-objcp-common.c
@@ -32,6 +32,8 @@ along with GCC; see the file COPYING3. If not see
#include "cxx-pretty-print.h"
#include "cp-objcp-common.h"
+#include <new> // For placement new.
+
/* Special routine to get the alias set for C++. */
alias_set_type
@@ -131,19 +133,15 @@ cp_var_mod_type_p (tree type, tree fn)
void
cxx_initialize_diagnostics (diagnostic_context *context)
{
- pretty_printer *base;
- cxx_pretty_printer *pp;
-
c_common_initialize_diagnostics (context);
- base = context->printer;
- pp = XNEW (cxx_pretty_printer);
- memcpy (pp_base (pp), base, sizeof (pretty_printer));
- pp_cxx_pretty_printer_init (pp);
- context->printer = (pretty_printer *) pp;
+ pretty_printer *base = context->printer;
+ cxx_pretty_printer *pp = XNEW (cxx_pretty_printer);
+ context->printer = new (pp) cxx_pretty_printer ();
- /* It is safe to free this object because it was previously malloc()'d. */
- free (base);
+ /* It is safe to free this object because it was previously XNEW()'d. */
+ base->~pretty_printer ();
+ XDELETE (base);
}
/* This compares two types for equivalence ("compatible" in C-based languages).
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 200e78ad715..3e4f188b93f 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -346,7 +346,7 @@ typedef struct ptrmem_cst * ptrmem_cst_t;
/* If set, this was imported in a using declaration.
This is not to confuse with being used somewhere, which
is not important for this node. */
-#define OVL_USED(NODE) TREE_USED (NODE)
+#define OVL_USED(NODE) TREE_USED (OVERLOAD_CHECK (NODE))
/* If set, this OVERLOAD was created for argument-dependent lookup
and can be freed afterward. */
#define OVL_ARG_DEPENDENT(NODE) TREE_LANG_FLAG_0 (OVERLOAD_CHECK (NODE))
@@ -1416,7 +1416,6 @@ struct GTY(()) lang_type_class {
unsigned has_complex_move_ctor : 1;
unsigned has_complex_move_assign : 1;
unsigned has_constexpr_ctor : 1;
- unsigned is_final : 1;
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If
@@ -1425,7 +1424,7 @@ struct GTY(()) lang_type_class {
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
- unsigned dummy : 2;
+ unsigned dummy : 3;
tree primary_base;
vec<tree_pair_s, va_gc> *vcall_indices;
@@ -1535,7 +1534,7 @@ struct GTY((variable_size)) lang_type {
/* Nonzero means that NODE (a class type) is final */
#define CLASSTYPE_FINAL(NODE) \
- (LANG_TYPE_CLASS_CHECK (NODE)->is_final)
+ TYPE_FINAL_P (NODE)
/* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */
@@ -2122,9 +2121,10 @@ struct GTY((variable_size)) lang_decl {
#define SET_DECL_LANGUAGE(NODE, LANGUAGE) \
(DECL_LANG_SPECIFIC (NODE)->u.base.language = (LANGUAGE))
-/* For FUNCTION_DECLs: nonzero means that this function is a constructor. */
+/* For FUNCTION_DECLs and TEMPLATE_DECLs: nonzero means that this function
+ is a constructor. */
#define DECL_CONSTRUCTOR_P(NODE) \
- (LANG_DECL_FN_CHECK (NODE)->constructor_attr)
+ DECL_CXX_CONSTRUCTOR_P (STRIP_TEMPLATE (NODE))
/* Nonzero if NODE (a FUNCTION_DECL) is a constructor for a complete
object. */
@@ -2153,9 +2153,10 @@ struct GTY((variable_size)) lang_decl {
#define DECL_MOVE_CONSTRUCTOR_P(NODE) \
(DECL_CONSTRUCTOR_P (NODE) && move_fn_p (NODE))
-/* Nonzero if NODE is a destructor. */
+/* Nonzero if NODE (a FUNCTION_DECL or TEMPLATE_DECL)
+ is a destructor. */
#define DECL_DESTRUCTOR_P(NODE) \
- (LANG_DECL_FN_CHECK (NODE)->destructor_attr)
+ DECL_CXX_DESTRUCTOR_P (STRIP_TEMPLATE (NODE))
/* Nonzero if NODE (a FUNCTION_DECL) is a destructor, but not the
specialized in-charge constructor, in-charge deleting constructor,
@@ -2400,10 +2401,6 @@ struct GTY((variable_size)) lang_decl {
an override virt-specifier */
#define DECL_OVERRIDE_P(NODE) (TREE_LANG_FLAG_0 (NODE))
-/* True (in a FUNCTION_DECL) if NODE is a function declared with
- a final virt-specifier */
-#define DECL_FINAL_P(NODE) (TREE_LANG_FLAG_1 (NODE))
-
/* The thunks associated with NODE, a FUNCTION_DECL. */
#define DECL_THUNKS(NODE) \
(DECL_VIRTUAL_P (NODE) ? LANG_DECL_FN_CHECK (NODE)->context : NULL_TREE)
@@ -2975,7 +2972,7 @@ extern void decl_shadowed_for_var_insert (tree, tree);
/* True if NODE is an implicit INDIRECT_EXPR from convert_from_reference. */
#define REFERENCE_REF_P(NODE) \
- (TREE_CODE (NODE) == INDIRECT_REF \
+ (INDIRECT_REF_P (NODE) \
&& TREE_TYPE (TREE_OPERAND (NODE, 0)) \
&& (TREE_CODE (TREE_TYPE (TREE_OPERAND ((NODE), 0))) \
== REFERENCE_TYPE))
@@ -4023,7 +4020,7 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter)
See semantics.c for details. */
#define CP_OMP_CLAUSE_INFO(NODE) \
TREE_TYPE (OMP_CLAUSE_RANGE_CHECK (NODE, OMP_CLAUSE_PRIVATE, \
- OMP_CLAUSE_COPYPRIVATE))
+ OMP_CLAUSE_LINEAR))
/* Nonzero if this transaction expression's body contains statements. */
#define TRANSACTION_EXPR_IS_STMT(NODE) \
@@ -4510,6 +4507,10 @@ enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, TYPENAME_FLAG };
#define LOOKUP_EXPLICIT_TMPL_ARGS (LOOKUP_ALREADY_DIGESTED << 1)
/* Like LOOKUP_NO_TEMP_BIND, but also prevent binding to xvalues. */
#define LOOKUP_NO_RVAL_BIND (LOOKUP_EXPLICIT_TMPL_ARGS << 1)
+/* Used by case_conversion to disregard non-integral conversions. */
+#define LOOKUP_NO_NON_INTEGRAL (LOOKUP_NO_RVAL_BIND << 1)
+/* Used for delegating constructors in order to diagnose self-delegation. */
+#define LOOKUP_DELEGATING_CONS (LOOKUP_NO_NON_INTEGRAL << 1)
#define LOOKUP_NAMESPACES_ONLY(F) \
(((F) & LOOKUP_PREFER_NAMESPACES) && !((F) & LOOKUP_PREFER_TYPES))
@@ -5171,10 +5172,10 @@ extern void check_goto (tree);
extern bool check_omp_return (void);
extern tree make_typename_type (tree, tree, enum tag_types, tsubst_flags_t);
extern tree make_unbound_class_template (tree, tree, tree, tsubst_flags_t);
-extern tree build_library_fn_ptr (const char *, tree);
-extern tree build_cp_library_fn_ptr (const char *, tree);
-extern tree push_library_fn (tree, tree, tree);
-extern tree push_void_library_fn (tree, tree);
+extern tree build_library_fn_ptr (const char *, tree, int);
+extern tree build_cp_library_fn_ptr (const char *, tree, int);
+extern tree push_library_fn (tree, tree, tree, int);
+extern tree push_void_library_fn (tree, tree, int);
extern tree push_throw_library_fn (tree, tree);
extern void warn_misplaced_attr_for_class_type (source_location location,
tree class_type);
@@ -5217,7 +5218,6 @@ extern tree grokmethod (cp_decl_specifier_seq *, const cp_declarator *, tree)
extern void maybe_register_incomplete_var (tree);
extern void maybe_commonize_var (tree);
extern void complete_vars (tree);
-extern void finish_stmt (void);
extern tree static_fn_type (tree);
extern void revert_static_member_fn (tree);
extern void fixup_anonymous_aggr (tree);
@@ -5299,6 +5299,8 @@ extern void note_vague_linkage_fn (tree);
extern tree build_artificial_parm (tree, tree);
extern bool possibly_inlined_p (tree);
extern int parm_index (tree);
+extern tree vtv_start_verification_constructor_init_function (void);
+extern tree vtv_finish_verification_constructor_init_function (tree);
/* in error.c */
extern void init_error (void);
@@ -5389,6 +5391,7 @@ extern tree build_java_class_ref (tree);
extern tree integral_constant_value (tree);
extern tree decl_constant_value_safe (tree);
extern int diagnose_uninitialized_cst_or_ref_member (tree, bool, bool);
+extern tree build_vtbl_address (tree);
/* in lex.c */
extern void cxx_dup_lang_specific_decl (tree);
@@ -5618,7 +5621,6 @@ extern tree copied_binfo (tree, tree);
extern tree original_binfo (tree, tree);
extern int shared_member_p (tree);
-
/* The representation of a deferred access check. */
typedef struct GTY(()) deferred_access_check {
@@ -6113,6 +6115,7 @@ extern tree mangle_tls_init_fn (tree);
extern tree mangle_tls_wrapper_fn (tree);
extern bool decl_tls_wrapper_p (tree);
extern tree mangle_ref_init_variable (tree);
+extern char * get_mangled_vtable_map_var_name (tree);
/* in dump.c */
extern bool cp_dump_tree (void *, tree);
@@ -6145,6 +6148,13 @@ extern bool cxx_omp_privatize_by_reference (const_tree);
extern void suggest_alternatives_for (location_t, tree);
extern tree strip_using_decl (tree);
+/* in vtable-class-hierarchy.c */
+extern void vtv_compute_class_hierarchy_transitive_closure (void);
+extern void vtv_generate_init_routine (void);
+extern void vtv_save_class_info (tree);
+extern void vtv_recover_class_info (void);
+extern void vtv_build_vtable_verify_fndecl (void);
+
/* In cp/cp-array-notations.c */
extern tree expand_array_notation_exprs (tree);
bool cilkplus_an_triplet_types_ok_p (location_t, tree, tree, tree,
diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c
index 532e8fd9d6b..08c026da178 100644
--- a/gcc/cp/cvt.c
+++ b/gcc/cp/cvt.c
@@ -1590,17 +1590,6 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
if (DECL_NONCONVERTING_P (cand))
continue;
- if (TREE_CODE (cand) == TEMPLATE_DECL)
- {
- if (complain)
- {
- error ("ambiguous default type conversion from %qT",
- basetype);
- error (" candidate conversions include %qD", cand);
- }
- return error_mark_node;
- }
-
candidate = non_reference (TREE_TYPE (TREE_TYPE (cand)));
switch (TREE_CODE (candidate))
@@ -1634,11 +1623,23 @@ build_expr_type_conversion (int desires, tree expr, bool complain)
break;
default:
+ /* A wildcard could be instantiated to match any desired
+ type, but we can't deduce the template argument. */
+ if (WILDCARD_TYPE_P (candidate))
+ win = true;
break;
}
if (win)
{
+ if (TREE_CODE (cand) == TEMPLATE_DECL)
+ {
+ if (complain)
+ error ("default type conversion can't deduce template"
+ " argument for %qD", cand);
+ return error_mark_node;
+ }
+
if (winner)
{
tree winner_type
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index ef8df706758..4578a5b0b05 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -27,24 +27,13 @@ along with GCC; see the file COPYING3. If not see
#include "cxx-pretty-print.h"
#include "tree-pretty-print.h"
-/* Translate if being used for diagnostics, but not for dump files or
- __PRETTY_FUNCTION. */
-#define M_(msgid) (pp_translate_identifiers (pp) ? _(msgid) : (msgid))
-
static void pp_cxx_unqualified_id (cxx_pretty_printer *, tree);
static void pp_cxx_nested_name_specifier (cxx_pretty_printer *, tree);
static void pp_cxx_qualified_id (cxx_pretty_printer *, tree);
-static void pp_cxx_assignment_expression (cxx_pretty_printer *, tree);
-static void pp_cxx_expression (cxx_pretty_printer *, tree);
static void pp_cxx_template_argument_list (cxx_pretty_printer *, tree);
static void pp_cxx_type_specifier_seq (cxx_pretty_printer *, tree);
static void pp_cxx_ptr_operator (cxx_pretty_printer *, tree);
-static void pp_cxx_type_id (cxx_pretty_printer *, tree);
-static void pp_cxx_direct_abstract_declarator (cxx_pretty_printer *, tree);
-static void pp_cxx_declarator (cxx_pretty_printer *, tree);
static void pp_cxx_parameter_declaration_clause (cxx_pretty_printer *, tree);
-static void pp_cxx_abstract_declarator (cxx_pretty_printer *, tree);
-static void pp_cxx_statement (cxx_pretty_printer *, tree);
static void pp_cxx_template_parameter (cxx_pretty_printer *, tree);
static void pp_cxx_cast_expression (cxx_pretty_printer *, tree);
static void pp_cxx_typeid_expression (cxx_pretty_printer *, tree);
@@ -58,25 +47,23 @@ pp_cxx_nonconsecutive_character (cxx_pretty_printer *pp, int c)
if (p != NULL && *p == c)
pp_cxx_whitespace (pp);
pp_character (pp, c);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
-#define pp_cxx_storage_class_specifier(PP, T) \
- pp_c_storage_class_specifier (pp_c_base (PP), T)
#define pp_cxx_expression_list(PP, T) \
- pp_c_expression_list (pp_c_base (PP), T)
+ pp_c_expression_list (PP, T)
#define pp_cxx_space_for_pointer_operator(PP, T) \
- pp_c_space_for_pointer_operator (pp_c_base (PP), T)
+ pp_c_space_for_pointer_operator (PP, T)
#define pp_cxx_init_declarator(PP, T) \
- pp_c_init_declarator (pp_c_base (PP), T)
+ pp_c_init_declarator (PP, T)
#define pp_cxx_call_argument_list(PP, T) \
- pp_c_call_argument_list (pp_c_base (PP), T)
+ pp_c_call_argument_list (PP, T)
void
pp_cxx_colon_colon (cxx_pretty_printer *pp)
{
pp_colon_colon (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
void
@@ -95,7 +82,7 @@ void
pp_cxx_separate_with (cxx_pretty_printer *pp, int c)
{
pp_separate_with (pp, c);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
/* Expressions. */
@@ -149,7 +136,7 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
switch (code)
{
case RESULT_DECL:
- pp_cxx_ws_string (pp, M_("<return-value>"));
+ pp->translate_string ("<return-value>");
break;
case OVERLOAD:
@@ -168,7 +155,7 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
case IDENTIFIER_NODE:
if (t == NULL)
- pp_cxx_ws_string (pp, M_("<unnamed>"));
+ pp->translate_string ("<unnamed>");
else if (IDENTIFIER_TYPENAME_P (t))
pp_cxx_conversion_function_id (pp, t);
else
@@ -321,8 +308,8 @@ pp_cxx_qualified_id (cxx_pretty_printer *pp, tree t)
}
-static void
-pp_cxx_constant (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::constant (tree t)
{
switch (TREE_CODE (t))
{
@@ -330,23 +317,23 @@ pp_cxx_constant (cxx_pretty_printer *pp, tree t)
{
const bool in_parens = PAREN_STRING_LITERAL_P (t);
if (in_parens)
- pp_cxx_left_paren (pp);
- pp_c_constant (pp_c_base (pp), t);
+ pp_cxx_left_paren (this);
+ c_pretty_printer::constant (t);
if (in_parens)
- pp_cxx_right_paren (pp);
+ pp_cxx_right_paren (this);
}
break;
case INTEGER_CST:
if (NULLPTR_TYPE_P (TREE_TYPE (t)))
{
- pp_string (pp, "nullptr");
+ pp_string (this, "nullptr");
break;
}
/* else fall through. */
default:
- pp_c_constant (pp_c_base (pp), t);
+ c_pretty_printer::constant (t);
break;
}
}
@@ -355,15 +342,15 @@ pp_cxx_constant (cxx_pretty_printer *pp, tree t)
unqualified-id
qualified-id */
-static inline void
-pp_cxx_id_expression (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::id_expression (tree t)
{
if (TREE_CODE (t) == OVERLOAD)
t = OVL_CURRENT (t);
if (DECL_P (t) && DECL_CONTEXT (t))
- pp_cxx_qualified_id (pp, t);
+ pp_cxx_qualified_id (this, t);
else
- pp_cxx_unqualified_id (pp, t);
+ pp_cxx_unqualified_id (this, t);
}
/* user-defined literal:
@@ -372,8 +359,8 @@ pp_cxx_id_expression (cxx_pretty_printer *pp, tree t)
void
pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
{
- pp_cxx_constant (pp, USERDEF_LITERAL_VALUE (t));
- pp_cxx_id_expression (pp, USERDEF_LITERAL_SUFFIX_ID (t));
+ pp->constant (USERDEF_LITERAL_VALUE (t));
+ pp->id_expression (USERDEF_LITERAL_SUFFIX_ID (t));
}
@@ -411,8 +398,8 @@ pp_cxx_userdef_literal (cxx_pretty_printer *pp, tree t)
__is_trivial ( type-id )
__is_union ( type-id ) */
-static void
-pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::primary_expression (tree t)
{
switch (TREE_CODE (t))
{
@@ -420,11 +407,11 @@ pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
case REAL_CST:
case COMPLEX_CST:
case STRING_CST:
- pp_cxx_constant (pp, t);
+ constant (t);
break;
case USERDEF_LITERAL:
- pp_cxx_userdef_literal (pp, t);
+ pp_cxx_userdef_literal (this, t);
break;
case BASELINK:
@@ -436,36 +423,36 @@ pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
case OVERLOAD:
case CONST_DECL:
case TEMPLATE_DECL:
- pp_cxx_id_expression (pp, t);
+ id_expression (t);
break;
case RESULT_DECL:
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case TEMPLATE_PARM_INDEX:
- pp_cxx_unqualified_id (pp, t);
+ pp_cxx_unqualified_id (this, t);
break;
case STMT_EXPR:
- pp_cxx_left_paren (pp);
- pp_cxx_statement (pp, STMT_EXPR_STMT (t));
- pp_cxx_right_paren (pp);
+ pp_cxx_left_paren (this);
+ statement (STMT_EXPR_STMT (t));
+ pp_cxx_right_paren (this);
break;
case TRAIT_EXPR:
- pp_cxx_trait_expression (pp, t);
+ pp_cxx_trait_expression (this, t);
break;
case VA_ARG_EXPR:
- pp_cxx_va_arg_expression (pp, t);
+ pp_cxx_va_arg_expression (this, t);
break;
case OFFSETOF_EXPR:
- pp_cxx_offsetof_expression (pp, t);
+ pp_cxx_offsetof_expression (this, t);
break;
default:
- pp_c_primary_expression (pp_c_base (pp), t);
+ c_pretty_printer::primary_expression (t);
break;
}
}
@@ -491,8 +478,8 @@ pp_cxx_primary_expression (cxx_pretty_printer *pp, tree t)
typeid ( expression )
typeid ( type-id ) */
-static void
-pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::postfix_expression (tree t)
{
enum tree_code code = TREE_CODE (t);
@@ -503,7 +490,7 @@ pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
{
tree fun = (code == AGGR_INIT_EXPR ? AGGR_INIT_EXPR_FN (t)
: CALL_EXPR_FN (t));
- tree saved_scope = pp->enclosing_scope;
+ tree saved_scope = enclosing_scope;
bool skipfirst = false;
tree arg;
@@ -532,21 +519,21 @@ pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
if (!TYPE_PTR_P (TREE_TYPE (object)))
{
- pp_cxx_postfix_expression (pp, object);
- pp_cxx_dot (pp);
+ postfix_expression (object);
+ pp_cxx_dot (this);
}
else
{
- pp_cxx_postfix_expression (pp, object);
- pp_cxx_arrow (pp);
+ postfix_expression (object);
+ pp_cxx_arrow (this);
}
skipfirst = true;
- pp->enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
+ enclosing_scope = strip_pointer_operator (TREE_TYPE (object));
}
- pp_cxx_postfix_expression (pp, fun);
- pp->enclosing_scope = saved_scope;
- pp_cxx_left_paren (pp);
+ postfix_expression (fun);
+ enclosing_scope = saved_scope;
+ pp_cxx_left_paren (this);
if (code == AGGR_INIT_EXPR)
{
aggr_init_expr_arg_iterator iter;
@@ -556,9 +543,9 @@ pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
skipfirst = false;
else
{
- pp_cxx_expression (pp, arg);
+ expression (arg);
if (more_aggr_init_expr_args_p (&iter))
- pp_cxx_separate_with (pp, ',');
+ pp_cxx_separate_with (this, ',');
}
}
}
@@ -571,18 +558,18 @@ pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
skipfirst = false;
else
{
- pp_cxx_expression (pp, arg);
+ expression (arg);
if (more_call_expr_args_p (&iter))
- pp_cxx_separate_with (pp, ',');
+ pp_cxx_separate_with (this, ',');
}
}
}
- pp_cxx_right_paren (pp);
+ pp_cxx_right_paren (this);
}
if (code == AGGR_INIT_EXPR && AGGR_INIT_VIA_CTOR_P (t))
{
- pp_cxx_separate_with (pp, ',');
- pp_cxx_postfix_expression (pp, AGGR_INIT_EXPR_SLOT (t));
+ pp_cxx_separate_with (this, ',');
+ postfix_expression (AGGR_INIT_EXPR_SLOT (t));
}
break;
@@ -595,7 +582,7 @@ pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
case CONST_DECL:
case TEMPLATE_DECL:
case RESULT_DECL:
- pp_cxx_primary_expression (pp, t);
+ primary_expression (t);
break;
case DYNAMIC_CAST_EXPR:
@@ -603,47 +590,47 @@ pp_cxx_postfix_expression (cxx_pretty_printer *pp, tree t)
case REINTERPRET_CAST_EXPR:
case CONST_CAST_EXPR:
if (code == DYNAMIC_CAST_EXPR)
- pp_cxx_ws_string (pp, "dynamic_cast");
+ pp_cxx_ws_string (this, "dynamic_cast");
else if (code == STATIC_CAST_EXPR)
- pp_cxx_ws_string (pp, "static_cast");
+ pp_cxx_ws_string (this, "static_cast");
else if (code == REINTERPRET_CAST_EXPR)
- pp_cxx_ws_string (pp, "reinterpret_cast");
+ pp_cxx_ws_string (this, "reinterpret_cast");
else
- pp_cxx_ws_string (pp, "const_cast");
- pp_cxx_begin_template_argument_list (pp);
- pp_cxx_type_id (pp, TREE_TYPE (t));
- pp_cxx_end_template_argument_list (pp);
- pp_left_paren (pp);
- pp_cxx_expression (pp, TREE_OPERAND (t, 0));
- pp_right_paren (pp);
+ pp_cxx_ws_string (this, "const_cast");
+ pp_cxx_begin_template_argument_list (this);
+ type_id (TREE_TYPE (t));
+ pp_cxx_end_template_argument_list (this);
+ pp_left_paren (this);
+ expression (TREE_OPERAND (t, 0));
+ pp_right_paren (this);
break;
case EMPTY_CLASS_EXPR:
- pp_cxx_type_id (pp, TREE_TYPE (t));
- pp_left_paren (pp);
- pp_right_paren (pp);
+ type_id (TREE_TYPE (t));
+ pp_left_paren (this);
+ pp_right_paren (this);
break;
case TYPEID_EXPR:
- pp_cxx_typeid_expression (pp, t);
+ pp_cxx_typeid_expression (this, t);
break;
case PSEUDO_DTOR_EXPR:
- pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
- pp_cxx_dot (pp);
- pp_cxx_qualified_id (pp, TREE_OPERAND (t, 1));
- pp_cxx_colon_colon (pp);
- pp_complement (pp);
- pp_cxx_unqualified_id (pp, TREE_OPERAND (t, 2));
+ postfix_expression (TREE_OPERAND (t, 0));
+ pp_cxx_dot (this);
+ pp_cxx_qualified_id (this, TREE_OPERAND (t, 1));
+ pp_cxx_colon_colon (this);
+ pp_complement (this);
+ pp_cxx_unqualified_id (this, TREE_OPERAND (t, 2));
break;
case ARROW_EXPR:
- pp_cxx_postfix_expression (pp, TREE_OPERAND (t, 0));
- pp_cxx_arrow (pp);
+ postfix_expression (TREE_OPERAND (t, 0));
+ pp_cxx_arrow (this);
break;
default:
- pp_c_postfix_expression (pp_c_base (pp), t);
+ c_pretty_printer::postfix_expression (t);
break;
}
}
@@ -694,16 +681,16 @@ pp_cxx_new_expression (cxx_pretty_printer *pp, tree t)
MINUS_EXPR, integer_type_node,
TREE_OPERAND (type, 1),
integer_one_node)));
- pp_cxx_type_id (pp, type);
+ pp->type_id (type);
if (init)
{
pp_left_paren (pp);
if (TREE_CODE (init) == TREE_LIST)
- pp_c_expression_list (pp_c_base (pp), init);
+ pp_c_expression_list (pp, init);
else if (init == void_zero_node)
; /* OK, empty initializer list. */
else
- pp_cxx_expression (pp, init);
+ pp->expression (init);
pp_right_paren (pp);
}
break;
@@ -736,7 +723,7 @@ pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
pp_right_bracket (pp);
pp_space (pp);
}
- pp_c_cast_expression (pp_c_base (pp), TREE_OPERAND (t, 0));
+ pp_c_cast_expression (pp, TREE_OPERAND (t, 0));
break;
default:
@@ -762,80 +749,80 @@ pp_cxx_delete_expression (cxx_pretty_printer *pp, tree t)
__alignof__ unary-expression
__alignof__ ( type-id ) */
-static void
-pp_cxx_unary_expression (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::unary_expression (tree t)
{
enum tree_code code = TREE_CODE (t);
switch (code)
{
case NEW_EXPR:
case VEC_NEW_EXPR:
- pp_cxx_new_expression (pp, t);
+ pp_cxx_new_expression (this, t);
break;
case DELETE_EXPR:
case VEC_DELETE_EXPR:
- pp_cxx_delete_expression (pp, t);
+ pp_cxx_delete_expression (this, t);
break;
case SIZEOF_EXPR:
if (PACK_EXPANSION_P (TREE_OPERAND (t, 0)))
{
- pp_cxx_ws_string (pp, "sizeof");
- pp_cxx_ws_string (pp, "...");
- pp_cxx_whitespace (pp);
- pp_cxx_left_paren (pp);
+ pp_cxx_ws_string (this, "sizeof");
+ pp_cxx_ws_string (this, "...");
+ pp_cxx_whitespace (this);
+ pp_cxx_left_paren (this);
if (TYPE_P (TREE_OPERAND (t, 0)))
- pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
+ type_id (TREE_OPERAND (t, 0));
else
- pp_unary_expression (pp, TREE_OPERAND (t, 0));
- pp_cxx_right_paren (pp);
+ unary_expression (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
break;
}
/* Fall through */
case ALIGNOF_EXPR:
- pp_cxx_ws_string (pp, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
- pp_cxx_whitespace (pp);
+ pp_cxx_ws_string (this, code == SIZEOF_EXPR ? "sizeof" : "__alignof__");
+ pp_cxx_whitespace (this);
if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
{
- pp_cxx_left_paren (pp);
- pp_cxx_type_id (pp, TREE_TYPE (TREE_OPERAND (t, 0)));
- pp_cxx_right_paren (pp);
+ pp_cxx_left_paren (this);
+ type_id (TREE_TYPE (TREE_OPERAND (t, 0)));
+ pp_cxx_right_paren (this);
}
else if (TYPE_P (TREE_OPERAND (t, 0)))
{
- pp_cxx_left_paren (pp);
- pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
- pp_cxx_right_paren (pp);
+ pp_cxx_left_paren (this);
+ type_id (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
}
else
- pp_unary_expression (pp, TREE_OPERAND (t, 0));
+ unary_expression (TREE_OPERAND (t, 0));
break;
case AT_ENCODE_EXPR:
- pp_cxx_ws_string (pp, "@encode");
- pp_cxx_whitespace (pp);
- pp_cxx_left_paren (pp);
- pp_cxx_type_id (pp, TREE_OPERAND (t, 0));
- pp_cxx_right_paren (pp);
+ pp_cxx_ws_string (this, "@encode");
+ pp_cxx_whitespace (this);
+ pp_cxx_left_paren (this);
+ type_id (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
break;
case NOEXCEPT_EXPR:
- pp_cxx_ws_string (pp, "noexcept");
- pp_cxx_whitespace (pp);
- pp_cxx_left_paren (pp);
- pp_cxx_expression (pp, TREE_OPERAND (t, 0));
- pp_cxx_right_paren (pp);
+ pp_cxx_ws_string (this, "noexcept");
+ pp_cxx_whitespace (this);
+ pp_cxx_left_paren (this);
+ expression (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
break;
case UNARY_PLUS_EXPR:
- pp_plus (pp);
- pp_cxx_cast_expression (pp, TREE_OPERAND (t, 0));
+ pp_plus (this);
+ pp_cxx_cast_expression (this, TREE_OPERAND (t, 0));
break;
default:
- pp_c_unary_expression (pp_c_base (pp), t);
+ c_pretty_printer::unary_expression (t);
break;
}
}
@@ -851,12 +838,12 @@ pp_cxx_cast_expression (cxx_pretty_printer *pp, tree t)
{
case CAST_EXPR:
case IMPLICIT_CONV_EXPR:
- pp_cxx_type_id (pp, TREE_TYPE (t));
+ pp->type_id (TREE_TYPE (t));
pp_cxx_call_argument_list (pp, TREE_OPERAND (t, 0));
break;
default:
- pp_c_cast_expression (pp_c_base (pp), t);
+ pp_c_cast_expression (pp, t);
break;
}
}
@@ -903,8 +890,8 @@ pp_cxx_pm_expression (cxx_pretty_printer *pp, tree t)
multiplicative-expression / pm-expression
multiplicative-expression % pm-expression */
-static void
-pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
+void
+cxx_pretty_printer::multiplicative_expression (tree e)
{
enum tree_code code = TREE_CODE (e);
switch (code)
@@ -912,20 +899,20 @@ pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
- pp_cxx_multiplicative_expression (pp, TREE_OPERAND (e, 0));
- pp_space (pp);
+ multiplicative_expression (TREE_OPERAND (e, 0));
+ pp_space (this);
if (code == MULT_EXPR)
- pp_star (pp);
+ pp_star (this);
else if (code == TRUNC_DIV_EXPR)
- pp_slash (pp);
+ pp_slash (this);
else
- pp_modulo (pp);
- pp_space (pp);
- pp_cxx_pm_expression (pp, TREE_OPERAND (e, 1));
+ pp_modulo (this);
+ pp_space (this);
+ pp_cxx_pm_expression (this, TREE_OPERAND (e, 1));
break;
default:
- pp_cxx_pm_expression (pp, e);
+ pp_cxx_pm_expression (this, e);
break;
}
}
@@ -934,21 +921,21 @@ pp_cxx_multiplicative_expression (cxx_pretty_printer *pp, tree e)
logical-or-expression
logical-or-expression ? expression : assignment-expression */
-static void
-pp_cxx_conditional_expression (cxx_pretty_printer *pp, tree e)
+void
+cxx_pretty_printer::conditional_expression (tree e)
{
if (TREE_CODE (e) == COND_EXPR)
{
- pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
- pp_space (pp);
- pp_question (pp);
- pp_space (pp);
- pp_cxx_expression (pp, TREE_OPERAND (e, 1));
- pp_space (pp);
- pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
+ pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
+ pp_space (this);
+ pp_question (this);
+ pp_space (this);
+ expression (TREE_OPERAND (e, 1));
+ pp_space (this);
+ assignment_expression (TREE_OPERAND (e, 2));
}
else
- pp_c_logical_or_expression (pp_c_base (pp), e);
+ pp_c_logical_or_expression (this, e);
}
/* Pretty-print a compound assignment operator token as indicated by T. */
@@ -1000,40 +987,40 @@ pp_cxx_assignment_operator (cxx_pretty_printer *pp, tree t)
assignment-operator: one of
= *= /= %= += -= >>= <<= &= ^= |= */
-static void
-pp_cxx_assignment_expression (cxx_pretty_printer *pp, tree e)
+void
+cxx_pretty_printer::assignment_expression (tree e)
{
switch (TREE_CODE (e))
{
case MODIFY_EXPR:
case INIT_EXPR:
- pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
- pp_space (pp);
- pp_equal (pp);
- pp_space (pp);
- pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 1));
+ pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
+ pp_space (this);
+ pp_equal (this);
+ pp_space (this);
+ assignment_expression (TREE_OPERAND (e, 1));
break;
case THROW_EXPR:
- pp_cxx_ws_string (pp, "throw");
+ pp_cxx_ws_string (this, "throw");
if (TREE_OPERAND (e, 0))
- pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 0));
+ assignment_expression (TREE_OPERAND (e, 0));
break;
case MODOP_EXPR:
- pp_c_logical_or_expression (pp_c_base (pp), TREE_OPERAND (e, 0));
- pp_cxx_assignment_operator (pp, TREE_OPERAND (e, 1));
- pp_cxx_assignment_expression (pp, TREE_OPERAND (e, 2));
+ pp_c_logical_or_expression (this, TREE_OPERAND (e, 0));
+ pp_cxx_assignment_operator (this, TREE_OPERAND (e, 1));
+ assignment_expression (TREE_OPERAND (e, 2));
break;
default:
- pp_cxx_conditional_expression (pp, e);
+ conditional_expression (e);
break;
}
}
-static void
-pp_cxx_expression (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::expression (tree t)
{
switch (TREE_CODE (t))
{
@@ -1041,15 +1028,15 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t)
case INTEGER_CST:
case REAL_CST:
case COMPLEX_CST:
- pp_cxx_constant (pp, t);
+ constant (t);
break;
case USERDEF_LITERAL:
- pp_cxx_userdef_literal (pp, t);
+ pp_cxx_userdef_literal (this, t);
break;
case RESULT_DECL:
- pp_cxx_unqualified_id (pp, t);
+ pp_cxx_unqualified_id (this, t);
break;
#if 0
@@ -1057,7 +1044,7 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t)
#endif
case SCOPE_REF:
case PTRMEM_CST:
- pp_cxx_qualified_id (pp, t);
+ pp_cxx_qualified_id (this, t);
break;
case OVERLOAD:
@@ -1073,7 +1060,7 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t)
case TEMPLATE_PARM_INDEX:
case TEMPLATE_TEMPLATE_PARM:
case STMT_EXPR:
- pp_cxx_primary_expression (pp, t);
+ primary_expression (t);
break;
case CALL_EXPR:
@@ -1089,65 +1076,65 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t)
case PSEUDO_DTOR_EXPR:
case AGGR_INIT_EXPR:
case ARROW_EXPR:
- pp_cxx_postfix_expression (pp, t);
+ postfix_expression (t);
break;
case NEW_EXPR:
case VEC_NEW_EXPR:
- pp_cxx_new_expression (pp, t);
+ pp_cxx_new_expression (this, t);
break;
case DELETE_EXPR:
case VEC_DELETE_EXPR:
- pp_cxx_delete_expression (pp, t);
+ pp_cxx_delete_expression (this, t);
break;
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
case NOEXCEPT_EXPR:
- pp_cxx_unary_expression (pp, t);
+ unary_expression (t);
break;
case CAST_EXPR:
case IMPLICIT_CONV_EXPR:
- pp_cxx_cast_expression (pp, t);
+ pp_cxx_cast_expression (this, t);
break;
case OFFSET_REF:
case MEMBER_REF:
case DOTSTAR_EXPR:
- pp_cxx_pm_expression (pp, t);
+ pp_cxx_pm_expression (this, t);
break;
case MULT_EXPR:
case TRUNC_DIV_EXPR:
case TRUNC_MOD_EXPR:
- pp_cxx_multiplicative_expression (pp, t);
+ multiplicative_expression (t);
break;
case COND_EXPR:
- pp_cxx_conditional_expression (pp, t);
+ conditional_expression (t);
break;
case MODIFY_EXPR:
case INIT_EXPR:
case THROW_EXPR:
case MODOP_EXPR:
- pp_cxx_assignment_expression (pp, t);
+ assignment_expression (t);
break;
case NON_DEPENDENT_EXPR:
case MUST_NOT_THROW_EXPR:
- pp_cxx_expression (pp, TREE_OPERAND (t, 0));
+ expression (TREE_OPERAND (t, 0));
break;
case EXPR_PACK_EXPANSION:
- pp_cxx_expression (pp, PACK_EXPANSION_PATTERN (t));
- pp_cxx_ws_string (pp, "...");
+ expression (PACK_EXPANSION_PATTERN (t));
+ pp_cxx_ws_string (this, "...");
break;
case TEMPLATE_ID_EXPR:
- pp_cxx_template_id (pp, t);
+ pp_cxx_template_id (this, t);
break;
case NONTYPE_ARGUMENT_PACK:
@@ -1157,24 +1144,24 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t)
for (i = 0; i < len; ++i)
{
if (i > 0)
- pp_cxx_separate_with (pp, ',');
- pp_cxx_expression (pp, TREE_VEC_ELT (args, i));
+ pp_cxx_separate_with (this, ',');
+ expression (TREE_VEC_ELT (args, i));
}
}
break;
case LAMBDA_EXPR:
- pp_cxx_ws_string (pp, "<lambda>");
+ pp_cxx_ws_string (this, "<lambda>");
break;
case PAREN_EXPR:
- pp_cxx_left_paren (pp);
- pp_cxx_expression (pp, TREE_OPERAND (t, 0));
- pp_cxx_right_paren (pp);
+ pp_cxx_left_paren (this);
+ expression (TREE_OPERAND (t, 0));
+ pp_cxx_right_paren (this);
break;
default:
- pp_c_expression (pp_c_base (pp), t);
+ c_pretty_printer::expression (t);
break;
}
}
@@ -1187,18 +1174,18 @@ pp_cxx_expression (cxx_pretty_printer *pp, tree t)
virtual
explicit */
-static void
-pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::function_specifier (tree t)
{
switch (TREE_CODE (t))
{
case FUNCTION_DECL:
if (DECL_VIRTUAL_P (t))
- pp_cxx_ws_string (pp, "virtual");
+ pp_cxx_ws_string (this, "virtual");
else if (DECL_CONSTRUCTOR_P (t) && DECL_NONCONVERTING_P (t))
- pp_cxx_ws_string (pp, "explicit");
+ pp_cxx_ws_string (this, "explicit");
else
- pp_c_function_specifier (pp_c_base (pp), t);
+ c_pretty_printer::function_specifier (t);
default:
break;
@@ -1215,8 +1202,8 @@ pp_cxx_function_specifier (cxx_pretty_printer *pp, tree t)
friend
typedef */
-static void
-pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::declaration_specifiers (tree t)
{
switch (TREE_CODE (t))
{
@@ -1224,25 +1211,25 @@ pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
case PARM_DECL:
case CONST_DECL:
case FIELD_DECL:
- pp_cxx_storage_class_specifier (pp, t);
- pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
+ storage_class_specifier (t);
+ declaration_specifiers (TREE_TYPE (t));
break;
case TYPE_DECL:
- pp_cxx_ws_string (pp, "typedef");
- pp_cxx_decl_specifier_seq (pp, TREE_TYPE (t));
+ pp_cxx_ws_string (this, "typedef");
+ declaration_specifiers (TREE_TYPE (t));
break;
case FUNCTION_DECL:
/* Constructors don't have return types. And conversion functions
do not have a type-specifier in their return types. */
if (DECL_CONSTRUCTOR_P (t) || DECL_CONV_FN_P (t))
- pp_cxx_function_specifier (pp, t);
+ function_specifier (t);
else if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
- pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (t)));
+ declaration_specifiers (TREE_TYPE (TREE_TYPE (t)));
else
default:
- pp_c_declaration_specifiers (pp_c_base (pp), t);
+ c_pretty_printer::declaration_specifiers (t);
break;
}
}
@@ -1262,32 +1249,32 @@ pp_cxx_decl_specifier_seq (cxx_pretty_printer *pp, tree t)
double
void */
-static void
-pp_cxx_simple_type_specifier (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::simple_type_specifier (tree t)
{
switch (TREE_CODE (t))
{
case RECORD_TYPE:
case UNION_TYPE:
case ENUMERAL_TYPE:
- pp_cxx_qualified_id (pp, t);
+ pp_cxx_qualified_id (this, t);
break;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case TEMPLATE_PARM_INDEX:
case BOUND_TEMPLATE_TEMPLATE_PARM:
- pp_cxx_unqualified_id (pp, t);
+ pp_cxx_unqualified_id (this, t);
break;
case TYPENAME_TYPE:
- pp_cxx_ws_string (pp, "typename");
- pp_cxx_nested_name_specifier (pp, TYPE_CONTEXT (t));
- pp_cxx_unqualified_id (pp, TYPE_NAME (t));
+ pp_cxx_ws_string (this, "typename");
+ pp_cxx_nested_name_specifier (this, TYPE_CONTEXT (t));
+ pp_cxx_unqualified_id (this, TYPE_NAME (t));
break;
default:
- pp_c_type_specifier (pp_c_base (pp), t);
+ c_pretty_printer::simple_type_specifier (t);
break;
}
}
@@ -1313,7 +1300,7 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
case TYPE_DECL:
case BOUND_TEMPLATE_TEMPLATE_PARM:
pp_cxx_cv_qualifier_seq (pp, t);
- pp_cxx_simple_type_specifier (pp, t);
+ pp->simple_type_specifier (t);
break;
case METHOD_TYPE:
@@ -1325,7 +1312,7 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
case DECLTYPE_TYPE:
pp_cxx_ws_string (pp, "decltype");
pp_cxx_left_paren (pp);
- pp_cxx_expression (pp, DECLTYPE_TYPE_EXPR (t));
+ pp->expression (DECLTYPE_TYPE_EXPR (t));
pp_cxx_right_paren (pp);
break;
@@ -1333,7 +1320,7 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
if (TYPE_PTRMEMFUNC_P (t))
{
tree pfm = TYPE_PTRMEMFUNC_FN_TYPE (t);
- pp_cxx_decl_specifier_seq (pp, TREE_TYPE (TREE_TYPE (pfm)));
+ pp->declaration_specifiers (TREE_TYPE (TREE_TYPE (pfm)));
pp_cxx_whitespace (pp);
pp_cxx_ptr_operator (pp, t);
break;
@@ -1342,7 +1329,7 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
default:
if (!(TREE_CODE (t) == FUNCTION_DECL && DECL_CONSTRUCTOR_P (t)))
- pp_c_specifier_qualifier_list (pp_c_base (pp), t);
+ pp_c_specifier_qualifier_list (pp, t);
}
}
@@ -1362,8 +1349,7 @@ pp_cxx_ptr_operator (cxx_pretty_printer *pp, tree t)
case POINTER_TYPE:
if (TYPE_PTR_OR_PTRMEM_P (TREE_TYPE (t)))
pp_cxx_ptr_operator (pp, TREE_TYPE (t));
- pp_c_attributes_display (pp_c_base (pp),
- TYPE_ATTRIBUTES (TREE_TYPE (t)));
+ pp_c_attributes_display (pp, TYPE_ATTRIBUTES (TREE_TYPE (t)));
if (TYPE_PTR_P (t))
{
pp_star (pp);
@@ -1415,11 +1401,11 @@ pp_cxx_implicit_parameter_type (tree mf)
static inline void
pp_cxx_parameter_declaration (cxx_pretty_printer *pp, tree t)
{
- pp_cxx_decl_specifier_seq (pp, t);
+ pp->declaration_specifiers (t);
if (TYPE_P (t))
- pp_cxx_abstract_declarator (pp, t);
+ pp->abstract_declarator (t);
else
- pp_cxx_declarator (pp, t);
+ pp->declarator (t);
}
/* parameter-declaration-clause:
@@ -1436,8 +1422,7 @@ pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
tree args = TYPE_P (t) ? NULL : FUNCTION_FIRST_USER_PARM (t);
tree types =
TYPE_P (t) ? TYPE_ARG_TYPES (t) : FUNCTION_FIRST_USER_PARMTYPE (t);
- const bool abstract = args == NULL
- || pp_c_base (pp)->flags & pp_c_flag_abstract;
+ const bool abstract = args == NULL || pp->flags & pp_c_flag_abstract;
bool first = true;
/* Skip artificial parameter for nonstatic member functions. */
@@ -1451,12 +1436,12 @@ pp_cxx_parameter_declaration_clause (cxx_pretty_printer *pp, tree t)
pp_cxx_separate_with (pp, ',');
first = false;
pp_cxx_parameter_declaration (pp, abstract ? TREE_VALUE (types) : args);
- if (!abstract && pp_c_base (pp)->flags & pp_cxx_flag_default_argument)
+ if (!abstract && pp->flags & pp_cxx_flag_default_argument)
{
pp_cxx_whitespace (pp);
pp_equal (pp);
pp_cxx_whitespace (pp);
- pp_cxx_assignment_expression (pp, TREE_PURPOSE (types));
+ pp->assignment_expression (TREE_PURPOSE (types));
}
}
pp_cxx_right_paren (pp);
@@ -1485,7 +1470,7 @@ pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
if (DEFERRED_NOEXCEPT_SPEC_P (ex_spec))
pp_cxx_ws_string (pp, "<uninstantiated>");
else
- pp_cxx_expression (pp, TREE_PURPOSE (ex_spec));
+ pp->expression (TREE_PURPOSE (ex_spec));
pp_cxx_right_paren (pp);
return;
}
@@ -1513,7 +1498,7 @@ pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
else
need_comma = true;
- pp_cxx_type_id (pp, type);
+ pp->type_id (type);
}
}
pp_cxx_right_paren (pp);
@@ -1526,8 +1511,8 @@ pp_cxx_exception_specification (cxx_pretty_printer *pp, tree t)
direct-declaration [ constant-expression(opt) ]
( declarator ) */
-static void
-pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::direct_declarator (tree t)
{
switch (TREE_CODE (t))
{
@@ -1537,31 +1522,31 @@ pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
case FIELD_DECL:
if (DECL_NAME (t))
{
- pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (t));
+ pp_cxx_space_for_pointer_operator (this, TREE_TYPE (t));
if ((TREE_CODE (t) == PARM_DECL && FUNCTION_PARAMETER_PACK_P (t))
|| template_parameter_pack_p (t))
/* A function parameter pack or non-type template
parameter pack. */
- pp_cxx_ws_string (pp, "...");
+ pp_cxx_ws_string (this, "...");
- pp_cxx_id_expression (pp, DECL_NAME (t));
+ id_expression (DECL_NAME (t));
}
- pp_cxx_abstract_declarator (pp, TREE_TYPE (t));
+ abstract_declarator (TREE_TYPE (t));
break;
case FUNCTION_DECL:
- pp_cxx_space_for_pointer_operator (pp, TREE_TYPE (TREE_TYPE (t)));
- pp_cxx_id_expression (pp, t);
- pp_cxx_parameter_declaration_clause (pp, t);
+ pp_cxx_space_for_pointer_operator (this, TREE_TYPE (TREE_TYPE (t)));
+ expression (t);
+ pp_cxx_parameter_declaration_clause (this, t);
if (DECL_NONSTATIC_MEMBER_FUNCTION_P (t))
{
- pp_base (pp)->padding = pp_before;
- pp_cxx_cv_qualifier_seq (pp, pp_cxx_implicit_parameter_type (t));
+ padding = pp_before;
+ pp_cxx_cv_qualifier_seq (this, pp_cxx_implicit_parameter_type (t));
}
- pp_cxx_exception_specification (pp, TREE_TYPE (t));
+ pp_cxx_exception_specification (this, TREE_TYPE (t));
break;
case TYPENAME_TYPE:
@@ -1572,7 +1557,7 @@ pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
break;
default:
- pp_c_direct_declarator (pp_c_base (pp), t);
+ c_pretty_printer::direct_declarator (t);
break;
}
}
@@ -1581,10 +1566,10 @@ pp_cxx_direct_declarator (cxx_pretty_printer *pp, tree t)
direct-declarator
ptr-operator declarator */
-static void
-pp_cxx_declarator (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::declarator (tree t)
{
- pp_cxx_direct_declarator (pp, t);
+ direct_declarator (t);
}
/* ctor-initializer:
@@ -1614,9 +1599,9 @@ pp_cxx_ctor_initializer (cxx_pretty_printer *pp, tree t)
bool is_pack = PACK_EXPANSION_P (purpose);
if (is_pack)
- pp_cxx_primary_expression (pp, PACK_EXPANSION_PATTERN (purpose));
+ pp->primary_expression (PACK_EXPANSION_PATTERN (purpose));
else
- pp_cxx_primary_expression (pp, purpose);
+ pp->primary_expression (purpose);
pp_cxx_call_argument_list (pp, TREE_VALUE (t));
if (is_pack)
pp_cxx_ws_string (pp, "...");
@@ -1633,12 +1618,12 @@ static void
pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
{
tree saved_scope = pp->enclosing_scope;
- pp_cxx_decl_specifier_seq (pp, t);
- pp_cxx_declarator (pp, t);
+ pp->declaration_specifiers (t);
+ pp->declarator (t);
pp_needs_newline (pp) = true;
pp->enclosing_scope = DECL_CONTEXT (t);
if (DECL_SAVED_TREE (t))
- pp_cxx_statement (pp, DECL_SAVED_TREE (t));
+ pp->statement (DECL_SAVED_TREE (t));
else
pp_cxx_semicolon (pp);
pp_newline_and_flush (pp);
@@ -1649,19 +1634,19 @@ pp_cxx_function_definition (cxx_pretty_printer *pp, tree t)
ptr-operator abstract-declarator(opt)
direct-abstract-declarator */
-static void
-pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::abstract_declarator (tree t)
{
if (TYPE_PTRMEM_P (t))
- pp_cxx_right_paren (pp);
+ pp_cxx_right_paren (this);
else if (POINTER_TYPE_P (t))
{
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
- pp_cxx_right_paren (pp);
+ pp_cxx_right_paren (this);
t = TREE_TYPE (t);
}
- pp_cxx_direct_abstract_declarator (pp, t);
+ direct_abstract_declarator (t);
}
/* direct-abstract-declarator:
@@ -1670,30 +1655,30 @@ pp_cxx_abstract_declarator (cxx_pretty_printer *pp, tree t)
direct-abstract-declarator(opt) [ constant-expression(opt) ]
( abstract-declarator ) */
-static void
-pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::direct_abstract_declarator (tree t)
{
switch (TREE_CODE (t))
{
case REFERENCE_TYPE:
- pp_cxx_abstract_declarator (pp, t);
+ abstract_declarator (t);
break;
case RECORD_TYPE:
if (TYPE_PTRMEMFUNC_P (t))
- pp_cxx_direct_abstract_declarator (pp, TYPE_PTRMEMFUNC_FN_TYPE (t));
+ direct_abstract_declarator (TYPE_PTRMEMFUNC_FN_TYPE (t));
break;
case METHOD_TYPE:
case FUNCTION_TYPE:
- pp_cxx_parameter_declaration_clause (pp, t);
- pp_cxx_direct_abstract_declarator (pp, TREE_TYPE (t));
+ pp_cxx_parameter_declaration_clause (this, t);
+ direct_abstract_declarator (TREE_TYPE (t));
if (TREE_CODE (t) == METHOD_TYPE)
{
- pp_base (pp)->padding = pp_before;
- pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (t));
+ padding = pp_before;
+ pp_cxx_cv_qualifier_seq (this, class_of_this_parm (t));
}
- pp_cxx_exception_specification (pp, t);
+ pp_cxx_exception_specification (this, t);
break;
case TYPENAME_TYPE:
@@ -1704,7 +1689,7 @@ pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
break;
default:
- pp_c_direct_abstract_declarator (pp_c_base (pp), t);
+ c_pretty_printer::direct_abstract_declarator (t);
break;
}
}
@@ -1712,11 +1697,11 @@ pp_cxx_direct_abstract_declarator (cxx_pretty_printer *pp, tree t)
/* type-id:
type-specifier-seq abstract-declarator(opt) */
-static void
-pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::type_id (tree t)
{
- pp_flags saved_flags = pp_c_base (pp)->flags;
- pp_c_base (pp)->flags |= pp_c_flag_abstract;
+ pp_flags saved_flags = flags;
+ flags |= pp_c_flag_abstract;
switch (TREE_CODE (t))
{
@@ -1735,20 +1720,20 @@ pp_cxx_type_id (cxx_pretty_printer *pp, tree t)
case UNDERLYING_TYPE:
case DECLTYPE_TYPE:
case TEMPLATE_ID_EXPR:
- pp_cxx_type_specifier_seq (pp, t);
+ pp_cxx_type_specifier_seq (this, t);
break;
case TYPE_PACK_EXPANSION:
- pp_cxx_type_id (pp, PACK_EXPANSION_PATTERN (t));
- pp_cxx_ws_string (pp, "...");
+ type_id (PACK_EXPANSION_PATTERN (t));
+ pp_cxx_ws_string (this, "...");
break;
default:
- pp_c_type_id (pp_c_base (pp), t);
+ c_pretty_printer::type_id (t);
break;
}
- pp_c_base (pp)->flags = saved_flags;
+ flags = saved_flags;
}
/* template-argument-list:
@@ -1792,9 +1777,9 @@ pp_cxx_template_argument_list (cxx_pretty_printer *pp, tree t)
if (TYPE_P (arg) || (TREE_CODE (arg) == TEMPLATE_DECL
&& TYPE_P (DECL_TEMPLATE_RESULT (arg))))
- pp_cxx_type_id (pp, arg);
+ pp->type_id (arg);
else
- pp_cxx_expression (pp, arg);
+ pp->expression (arg);
}
}
}
@@ -1806,34 +1791,34 @@ pp_cxx_exception_declaration (cxx_pretty_printer *pp, tree t)
t = DECL_EXPR_DECL (t);
pp_cxx_type_specifier_seq (pp, t);
if (TYPE_P (t))
- pp_cxx_abstract_declarator (pp, t);
+ pp->abstract_declarator (t);
else
- pp_cxx_declarator (pp, t);
+ pp->declarator (t);
}
/* Statements. */
-static void
-pp_cxx_statement (cxx_pretty_printer *pp, tree t)
+void
+cxx_pretty_printer::statement (tree t)
{
switch (TREE_CODE (t))
{
case CTOR_INITIALIZER:
- pp_cxx_ctor_initializer (pp, t);
+ pp_cxx_ctor_initializer (this, t);
break;
case USING_STMT:
- pp_cxx_ws_string (pp, "using");
- pp_cxx_ws_string (pp, "namespace");
+ pp_cxx_ws_string (this, "using");
+ pp_cxx_ws_string (this, "namespace");
if (DECL_CONTEXT (t))
- pp_cxx_nested_name_specifier (pp, DECL_CONTEXT (t));
- pp_cxx_qualified_id (pp, USING_STMT_NAMESPACE (t));
+ pp_cxx_nested_name_specifier (this, DECL_CONTEXT (t));
+ pp_cxx_qualified_id (this, USING_STMT_NAMESPACE (t));
break;
case USING_DECL:
- pp_cxx_ws_string (pp, "using");
- pp_cxx_nested_name_specifier (pp, USING_DECL_SCOPE (t));
- pp_cxx_unqualified_id (pp, DECL_NAME (t));
+ pp_cxx_ws_string (this, "using");
+ pp_cxx_nested_name_specifier (this, USING_DECL_SCOPE (t));
+ pp_cxx_unqualified_id (this, DECL_NAME (t));
break;
case EH_SPEC_BLOCK:
@@ -1842,15 +1827,15 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t)
/* try-block:
try compound-statement handler-seq */
case TRY_BLOCK:
- pp_maybe_newline_and_indent (pp, 0);
- pp_cxx_ws_string (pp, "try");
- pp_newline_and_indent (pp, 3);
- pp_cxx_statement (pp, TRY_STMTS (t));
- pp_newline_and_indent (pp, -3);
+ pp_maybe_newline_and_indent (this, 0);
+ pp_cxx_ws_string (this, "try");
+ pp_newline_and_indent (this, 3);
+ statement (TRY_STMTS (t));
+ pp_newline_and_indent (this, -3);
if (CLEANUP_P (t))
;
else
- pp_cxx_statement (pp, TRY_HANDLERS (t));
+ statement (TRY_HANDLERS (t));
break;
/*
@@ -1865,53 +1850,53 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t)
type-specifier-seq abstract-declarator
... */
case HANDLER:
- pp_cxx_ws_string (pp, "catch");
- pp_cxx_left_paren (pp);
- pp_cxx_exception_declaration (pp, HANDLER_PARMS (t));
- pp_cxx_right_paren (pp);
- pp_indentation (pp) += 3;
- pp_needs_newline (pp) = true;
- pp_cxx_statement (pp, HANDLER_BODY (t));
- pp_indentation (pp) -= 3;
- pp_needs_newline (pp) = true;
+ pp_cxx_ws_string (this, "catch");
+ pp_cxx_left_paren (this);
+ pp_cxx_exception_declaration (this, HANDLER_PARMS (t));
+ pp_cxx_right_paren (this);
+ pp_indentation (this) += 3;
+ pp_needs_newline (this) = true;
+ statement (HANDLER_BODY (t));
+ pp_indentation (this) -= 3;
+ pp_needs_newline (this) = true;
break;
/* selection-statement:
if ( expression ) statement
if ( expression ) statement else statement */
case IF_STMT:
- pp_cxx_ws_string (pp, "if");
- pp_cxx_whitespace (pp);
- pp_cxx_left_paren (pp);
- pp_cxx_expression (pp, IF_COND (t));
- pp_cxx_right_paren (pp);
- pp_newline_and_indent (pp, 2);
- pp_cxx_statement (pp, THEN_CLAUSE (t));
- pp_newline_and_indent (pp, -2);
+ pp_cxx_ws_string (this, "if");
+ pp_cxx_whitespace (this);
+ pp_cxx_left_paren (this);
+ expression (IF_COND (t));
+ pp_cxx_right_paren (this);
+ pp_newline_and_indent (this, 2);
+ statement (THEN_CLAUSE (t));
+ pp_newline_and_indent (this, -2);
if (ELSE_CLAUSE (t))
{
tree else_clause = ELSE_CLAUSE (t);
- pp_cxx_ws_string (pp, "else");
+ pp_cxx_ws_string (this, "else");
if (TREE_CODE (else_clause) == IF_STMT)
- pp_cxx_whitespace (pp);
+ pp_cxx_whitespace (this);
else
- pp_newline_and_indent (pp, 2);
- pp_cxx_statement (pp, else_clause);
+ pp_newline_and_indent (this, 2);
+ statement (else_clause);
if (TREE_CODE (else_clause) != IF_STMT)
- pp_newline_and_indent (pp, -2);
+ pp_newline_and_indent (this, -2);
}
break;
case SWITCH_STMT:
- pp_cxx_ws_string (pp, "switch");
- pp_space (pp);
- pp_cxx_left_paren (pp);
- pp_cxx_expression (pp, SWITCH_STMT_COND (t));
- pp_cxx_right_paren (pp);
- pp_indentation (pp) += 3;
- pp_needs_newline (pp) = true;
- pp_cxx_statement (pp, SWITCH_STMT_BODY (t));
- pp_newline_and_indent (pp, -3);
+ pp_cxx_ws_string (this, "switch");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ expression (SWITCH_STMT_COND (t));
+ pp_cxx_right_paren (this);
+ pp_indentation (this) += 3;
+ pp_needs_newline (this) = true;
+ statement (SWITCH_STMT_BODY (t));
+ pp_newline_and_indent (this, -3);
break;
/* iteration-statement:
@@ -1920,70 +1905,70 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t)
for ( expression(opt) ; expression(opt) ; expression(opt) ) statement
for ( declaration expression(opt) ; expression(opt) ) statement */
case WHILE_STMT:
- pp_cxx_ws_string (pp, "while");
- pp_space (pp);
- pp_cxx_left_paren (pp);
- pp_cxx_expression (pp, WHILE_COND (t));
- pp_cxx_right_paren (pp);
- pp_newline_and_indent (pp, 3);
- pp_cxx_statement (pp, WHILE_BODY (t));
- pp_indentation (pp) -= 3;
- pp_needs_newline (pp) = true;
+ pp_cxx_ws_string (this, "while");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ expression (WHILE_COND (t));
+ pp_cxx_right_paren (this);
+ pp_newline_and_indent (this, 3);
+ statement (WHILE_BODY (t));
+ pp_indentation (this) -= 3;
+ pp_needs_newline (this) = true;
break;
case DO_STMT:
- pp_cxx_ws_string (pp, "do");
- pp_newline_and_indent (pp, 3);
- pp_cxx_statement (pp, DO_BODY (t));
- pp_newline_and_indent (pp, -3);
- pp_cxx_ws_string (pp, "while");
- pp_space (pp);
- pp_cxx_left_paren (pp);
- pp_cxx_expression (pp, DO_COND (t));
- pp_cxx_right_paren (pp);
- pp_cxx_semicolon (pp);
- pp_needs_newline (pp) = true;
+ pp_cxx_ws_string (this, "do");
+ pp_newline_and_indent (this, 3);
+ statement (DO_BODY (t));
+ pp_newline_and_indent (this, -3);
+ pp_cxx_ws_string (this, "while");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ expression (DO_COND (t));
+ pp_cxx_right_paren (this);
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = true;
break;
case FOR_STMT:
- pp_cxx_ws_string (pp, "for");
- pp_space (pp);
- pp_cxx_left_paren (pp);
+ pp_cxx_ws_string (this, "for");
+ pp_space (this);
+ pp_cxx_left_paren (this);
if (FOR_INIT_STMT (t))
- pp_cxx_statement (pp, FOR_INIT_STMT (t));
+ statement (FOR_INIT_STMT (t));
else
- pp_cxx_semicolon (pp);
- pp_needs_newline (pp) = false;
- pp_cxx_whitespace (pp);
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = false;
+ pp_cxx_whitespace (this);
if (FOR_COND (t))
- pp_cxx_expression (pp, FOR_COND (t));
- pp_cxx_semicolon (pp);
- pp_needs_newline (pp) = false;
- pp_cxx_whitespace (pp);
+ expression (FOR_COND (t));
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = false;
+ pp_cxx_whitespace (this);
if (FOR_EXPR (t))
- pp_cxx_expression (pp, FOR_EXPR (t));
- pp_cxx_right_paren (pp);
- pp_newline_and_indent (pp, 3);
- pp_cxx_statement (pp, FOR_BODY (t));
- pp_indentation (pp) -= 3;
- pp_needs_newline (pp) = true;
+ expression (FOR_EXPR (t));
+ pp_cxx_right_paren (this);
+ pp_newline_and_indent (this, 3);
+ statement (FOR_BODY (t));
+ pp_indentation (this) -= 3;
+ pp_needs_newline (this) = true;
break;
case RANGE_FOR_STMT:
- pp_cxx_ws_string (pp, "for");
- pp_space (pp);
- pp_cxx_left_paren (pp);
- pp_cxx_statement (pp, RANGE_FOR_DECL (t));
- pp_space (pp);
- pp_needs_newline (pp) = false;
- pp_colon (pp);
- pp_space (pp);
- pp_cxx_statement (pp, RANGE_FOR_EXPR (t));
- pp_cxx_right_paren (pp);
- pp_newline_and_indent (pp, 3);
- pp_cxx_statement (pp, FOR_BODY (t));
- pp_indentation (pp) -= 3;
- pp_needs_newline (pp) = true;
+ pp_cxx_ws_string (this, "for");
+ pp_space (this);
+ pp_cxx_left_paren (this);
+ statement (RANGE_FOR_DECL (t));
+ pp_space (this);
+ pp_needs_newline (this) = false;
+ pp_colon (this);
+ pp_space (this);
+ statement (RANGE_FOR_EXPR (t));
+ pp_cxx_right_paren (this);
+ pp_newline_and_indent (this, 3);
+ statement (FOR_BODY (t));
+ pp_indentation (this) -= 3;
+ pp_needs_newline (this) = true;
break;
/* jump-statement:
@@ -1992,36 +1977,36 @@ pp_cxx_statement (cxx_pretty_printer *pp, tree t)
return expression(opt) ; */
case BREAK_STMT:
case CONTINUE_STMT:
- pp_string (pp, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
- pp_cxx_semicolon (pp);
- pp_needs_newline (pp) = true;
+ pp_string (this, TREE_CODE (t) == BREAK_STMT ? "break" : "continue");
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = true;
break;
/* expression-statement:
expression(opt) ; */
case EXPR_STMT:
- pp_cxx_expression (pp, EXPR_STMT_EXPR (t));
- pp_cxx_semicolon (pp);
- pp_needs_newline (pp) = true;
+ expression (EXPR_STMT_EXPR (t));
+ pp_cxx_semicolon (this);
+ pp_needs_newline (this) = true;
break;
case CLEANUP_STMT:
- pp_cxx_ws_string (pp, "try");
- pp_newline_and_indent (pp, 2);
- pp_cxx_statement (pp, CLEANUP_BODY (t));
- pp_newline_and_indent (pp, -2);
- pp_cxx_ws_string (pp, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
- pp_newline_and_indent (pp, 2);
- pp_cxx_statement (pp, CLEANUP_EXPR (t));
- pp_newline_and_indent (pp, -2);
+ pp_cxx_ws_string (this, "try");
+ pp_newline_and_indent (this, 2);
+ statement (CLEANUP_BODY (t));
+ pp_newline_and_indent (this, -2);
+ pp_cxx_ws_string (this, CLEANUP_EH_ONLY (t) ? "catch" : "finally");
+ pp_newline_and_indent (this, 2);
+ statement (CLEANUP_EXPR (t));
+ pp_newline_and_indent (this, -2);
break;
case STATIC_ASSERT:
- pp_cxx_declaration (pp, t);
+ declaration (t);
break;
default:
- pp_c_statement (pp_c_base (pp), t);
+ c_pretty_printer::statement (t);
break;
}
}
@@ -2078,7 +2063,7 @@ pp_cxx_namespace_alias_definition (cxx_pretty_printer *pp, tree t)
static void
pp_cxx_simple_declaration (cxx_pretty_printer *pp, tree t)
{
- pp_cxx_decl_specifier_seq (pp, t);
+ pp->declaration_specifiers (t);
pp_cxx_init_declarator (pp, t);
pp_cxx_semicolon (pp);
pp_needs_newline (pp) = true;
@@ -2156,7 +2141,7 @@ pp_cxx_canonical_template_parameter (cxx_pretty_printer *pp, tree parm)
parm = TEMPLATE_TYPE_PARM_INDEX (parm);
pp_cxx_begin_template_argument_list (pp);
- pp_cxx_ws_string (pp, M_("template-parameter-"));
+ pp->translate_string ("template-parameter-");
pp_wide_integer (pp, TEMPLATE_PARM_LEVEL (parm));
pp_minus (pp);
pp_wide_integer (pp, TEMPLATE_PARM_IDX (parm) + 1);
@@ -2218,32 +2203,32 @@ pp_cxx_explicit_instantiation (cxx_pretty_printer *pp, tree t)
using-directive
static_assert-declaration */
void
-pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
+cxx_pretty_printer::declaration (tree t)
{
if (TREE_CODE (t) == STATIC_ASSERT)
{
- pp_cxx_ws_string (pp, "static_assert");
- pp_cxx_left_paren (pp);
- pp_cxx_expression (pp, STATIC_ASSERT_CONDITION (t));
- pp_cxx_separate_with (pp, ',');
- pp_cxx_expression (pp, STATIC_ASSERT_MESSAGE (t));
- pp_cxx_right_paren (pp);
+ pp_cxx_ws_string (this, "static_assert");
+ pp_cxx_left_paren (this);
+ expression (STATIC_ASSERT_CONDITION (t));
+ pp_cxx_separate_with (this, ',');
+ expression (STATIC_ASSERT_MESSAGE (t));
+ pp_cxx_right_paren (this);
}
else if (!DECL_LANG_SPECIFIC (t))
- pp_cxx_simple_declaration (pp, t);
+ pp_cxx_simple_declaration (this, t);
else if (DECL_USE_TEMPLATE (t))
switch (DECL_USE_TEMPLATE (t))
{
case 1:
- pp_cxx_template_declaration (pp, t);
+ pp_cxx_template_declaration (this, t);
break;
case 2:
- pp_cxx_explicit_specialization (pp, t);
+ pp_cxx_explicit_specialization (this, t);
break;
case 3:
- pp_cxx_explicit_instantiation (pp, t);
+ pp_cxx_explicit_instantiation (this, t);
break;
default:
@@ -2253,25 +2238,25 @@ pp_cxx_declaration (cxx_pretty_printer *pp, tree t)
{
case VAR_DECL:
case TYPE_DECL:
- pp_cxx_simple_declaration (pp, t);
+ pp_cxx_simple_declaration (this, t);
break;
case FUNCTION_DECL:
if (DECL_SAVED_TREE (t))
- pp_cxx_function_definition (pp, t);
+ pp_cxx_function_definition (this, t);
else
- pp_cxx_simple_declaration (pp, t);
+ pp_cxx_simple_declaration (this, t);
break;
case NAMESPACE_DECL:
if (DECL_NAMESPACE_ALIAS (t))
- pp_cxx_namespace_alias_definition (pp, t);
+ pp_cxx_namespace_alias_definition (this, t);
else
- pp_cxx_original_namespace_definition (pp, t);
+ pp_cxx_original_namespace_definition (this, t);
break;
default:
- pp_unsupported_tree (pp, t);
+ pp_unsupported_tree (this, t);
break;
}
}
@@ -2283,9 +2268,9 @@ pp_cxx_typeid_expression (cxx_pretty_printer *pp, tree t)
pp_cxx_ws_string (pp, "typeid");
pp_cxx_left_paren (pp);
if (TYPE_P (t))
- pp_cxx_type_id (pp, t);
+ pp->type_id (t);
else
- pp_cxx_expression (pp, t);
+ pp->expression (t);
pp_cxx_right_paren (pp);
}
@@ -2294,9 +2279,9 @@ pp_cxx_va_arg_expression (cxx_pretty_printer *pp, tree t)
{
pp_cxx_ws_string (pp, "va_arg");
pp_cxx_left_paren (pp);
- pp_cxx_assignment_expression (pp, TREE_OPERAND (t, 0));
+ pp->assignment_expression (TREE_OPERAND (t, 0));
pp_cxx_separate_with (pp, ',');
- pp_cxx_type_id (pp, TREE_TYPE (t));
+ pp->type_id (TREE_TYPE (t));
pp_cxx_right_paren (pp);
}
@@ -2309,7 +2294,7 @@ pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
if (TREE_CODE (TREE_OPERAND (t, 0)) == STATIC_CAST_EXPR
&& POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (t, 0))))
{
- pp_cxx_type_id (pp, TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
+ pp->type_id (TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))));
pp_cxx_separate_with (pp, ',');
return true;
}
@@ -2319,13 +2304,13 @@ pp_cxx_offsetof_expression_1 (cxx_pretty_printer *pp, tree t)
return false;
if (TREE_CODE (TREE_OPERAND (t, 0)) != ARROW_EXPR)
pp_cxx_dot (pp);
- pp_cxx_expression (pp, TREE_OPERAND (t, 1));
+ pp->expression (TREE_OPERAND (t, 1));
return true;
case ARRAY_REF:
if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
return false;
pp_left_bracket (pp);
- pp_cxx_expression (pp, TREE_OPERAND (t, 1));
+ pp->expression (TREE_OPERAND (t, 1));
pp_right_bracket (pp);
return true;
default:
@@ -2339,7 +2324,7 @@ pp_cxx_offsetof_expression (cxx_pretty_printer *pp, tree t)
pp_cxx_ws_string (pp, "offsetof");
pp_cxx_left_paren (pp);
if (!pp_cxx_offsetof_expression_1 (pp, TREE_OPERAND (t, 0)))
- pp_cxx_expression (pp, TREE_OPERAND (t, 0));
+ pp->expression (TREE_OPERAND (t, 0));
pp_cxx_right_paren (pp);
}
@@ -2419,12 +2404,12 @@ pp_cxx_trait_expression (cxx_pretty_printer *pp, tree t)
}
pp_cxx_left_paren (pp);
- pp_cxx_type_id (pp, TRAIT_EXPR_TYPE1 (t));
+ pp->type_id (TRAIT_EXPR_TYPE1 (t));
if (kind == CPTK_IS_BASE_OF || kind == CPTK_IS_CONVERTIBLE_TO)
{
pp_cxx_separate_with (pp, ',');
- pp_cxx_type_id (pp, TRAIT_EXPR_TYPE2 (t));
+ pp->type_id (TRAIT_EXPR_TYPE2 (t));
}
pp_cxx_right_paren (pp);
@@ -2434,35 +2419,12 @@ typedef c_pretty_print_fn pp_fun;
/* Initialization of a C++ pretty-printer object. */
-void
-pp_cxx_pretty_printer_init (cxx_pretty_printer *pp)
+cxx_pretty_printer::cxx_pretty_printer ()
+ : c_pretty_printer (),
+ enclosing_scope (global_namespace)
{
- pp_c_pretty_printer_init (pp_c_base (pp));
- pp_set_line_maximum_length (pp, 0);
-
- pp->c_base.declaration = (pp_fun) pp_cxx_declaration;
- pp->c_base.declaration_specifiers = (pp_fun) pp_cxx_decl_specifier_seq;
- pp->c_base.function_specifier = (pp_fun) pp_cxx_function_specifier;
- pp->c_base.type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
- pp->c_base.declarator = (pp_fun) pp_cxx_declarator;
- pp->c_base.direct_declarator = (pp_fun) pp_cxx_direct_declarator;
- pp->c_base.parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
- pp->c_base.type_id = (pp_fun) pp_cxx_type_id;
- pp->c_base.abstract_declarator = (pp_fun) pp_cxx_abstract_declarator;
- pp->c_base.direct_abstract_declarator =
- (pp_fun) pp_cxx_direct_abstract_declarator;
- pp->c_base.simple_type_specifier = (pp_fun)pp_cxx_simple_type_specifier;
-
- /* pp->c_base.statement = (pp_fun) pp_cxx_statement; */
-
- pp->c_base.constant = (pp_fun) pp_cxx_constant;
- pp->c_base.id_expression = (pp_fun) pp_cxx_id_expression;
- pp->c_base.primary_expression = (pp_fun) pp_cxx_primary_expression;
- pp->c_base.postfix_expression = (pp_fun) pp_cxx_postfix_expression;
- pp->c_base.unary_expression = (pp_fun) pp_cxx_unary_expression;
- pp->c_base.multiplicative_expression = (pp_fun) pp_cxx_multiplicative_expression;
- pp->c_base.conditional_expression = (pp_fun) pp_cxx_conditional_expression;
- pp->c_base.assignment_expression = (pp_fun) pp_cxx_assignment_expression;
- pp->c_base.expression = (pp_fun) pp_cxx_expression;
- pp->enclosing_scope = global_namespace;
+ pp_set_line_maximum_length (this, 0);
+
+ type_specifier_seq = (pp_fun) pp_cxx_type_specifier_seq;
+ parameter_list = (pp_fun) pp_cxx_parameter_declaration_clause;
}
diff --git a/gcc/cp/cxx-pretty-print.h b/gcc/cp/cxx-pretty-print.h
index 0f7dc4a8174..819bbacae75 100644
--- a/gcc/cp/cxx-pretty-print.h
+++ b/gcc/cp/cxx-pretty-print.h
@@ -23,54 +23,69 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-pretty-print.h"
-#undef pp_c_base
-#define pp_c_base(PP) (&(PP)->c_base)
-
-typedef enum
+enum cxx_pretty_printer_flags
{
/* Ask for a qualified-id. */
pp_cxx_flag_default_argument = 1 << pp_c_flag_last_bit
+};
-} cxx_pretty_printer_flags;
-
-typedef struct
+struct cxx_pretty_printer : c_pretty_printer
{
- c_pretty_printer c_base;
+ cxx_pretty_printer ();
+
+ void constant (tree);
+ void id_expression (tree);
+ void primary_expression (tree);
+ void postfix_expression (tree);
+ void unary_expression (tree);
+ void multiplicative_expression (tree);
+ void conditional_expression (tree);
+ void assignment_expression (tree);
+ void expression (tree);
+ void type_id (tree);
+ void statement (tree);
+ void declaration (tree);
+ void declaration_specifiers (tree);
+ void simple_type_specifier (tree);
+ void function_specifier (tree);
+ void declarator (tree);
+ void direct_declarator (tree);
+ void abstract_declarator (tree);
+ void direct_abstract_declarator (tree);
+
/* This is the enclosing scope of the entity being pretty-printed. */
tree enclosing_scope;
-} cxx_pretty_printer;
+};
#define pp_cxx_cv_qualifier_seq(PP, T) \
- pp_c_type_qualifier_list (pp_c_base (PP), T)
+ pp_c_type_qualifier_list (PP, T)
#define pp_cxx_cv_qualifiers(PP, CV) \
- pp_c_cv_qualifiers (pp_c_base (PP), CV, false)
-
-#define pp_cxx_whitespace(PP) pp_c_whitespace (pp_c_base (PP))
-#define pp_cxx_left_paren(PP) pp_c_left_paren (pp_c_base (PP))
-#define pp_cxx_right_paren(PP) pp_c_right_paren (pp_c_base (PP))
-#define pp_cxx_left_brace(PP) pp_c_left_brace (pp_c_base (PP))
-#define pp_cxx_right_brace(PP) pp_c_right_brace (pp_c_base (PP))
-#define pp_cxx_left_bracket(PP) pp_c_left_bracket (pp_c_base (PP))
-#define pp_cxx_right_bracket(PP) pp_c_right_bracket (pp_c_base (PP))
-#define pp_cxx_dot(PP) pp_c_dot (pp_c_base (PP))
-#define pp_cxx_ampersand(PP) pp_c_ampersand (pp_c_base (PP))
-#define pp_cxx_star(PP) pp_c_star (pp_c_base (PP))
-#define pp_cxx_arrow(PP) pp_c_arrow (pp_c_base (PP))
-#define pp_cxx_semicolon(PP) pp_c_semicolon (pp_c_base (PP))
-#define pp_cxx_complement(PP) pp_c_complement (pp_c_base (PP))
-
-#define pp_cxx_ws_string(PP, I) pp_c_ws_string (pp_c_base (PP), I)
-#define pp_cxx_identifier(PP, I) pp_c_identifier (pp_c_base (PP), I)
+ pp_c_cv_qualifiers (PP, CV, false)
+
+#define pp_cxx_whitespace(PP) pp_c_whitespace (PP)
+#define pp_cxx_left_paren(PP) pp_c_left_paren (PP)
+#define pp_cxx_right_paren(PP) pp_c_right_paren (PP)
+#define pp_cxx_left_brace(PP) pp_c_left_brace (PP)
+#define pp_cxx_right_brace(PP) pp_c_right_brace (PP)
+#define pp_cxx_left_bracket(PP) pp_c_left_bracket (PP)
+#define pp_cxx_right_bracket(PP) pp_c_right_bracket (PP)
+#define pp_cxx_dot(PP) pp_c_dot (PP)
+#define pp_cxx_ampersand(PP) pp_c_ampersand (PP)
+#define pp_cxx_star(PP) pp_c_star (PP)
+#define pp_cxx_arrow(PP) pp_c_arrow (PP)
+#define pp_cxx_semicolon(PP) pp_c_semicolon (PP)
+#define pp_cxx_complement(PP) pp_c_complement (PP)
+
+#define pp_cxx_ws_string(PP, I) pp_c_ws_string (PP, I)
+#define pp_cxx_identifier(PP, I) pp_c_identifier (PP, I)
#define pp_cxx_tree_identifier(PP, T) \
- pp_c_tree_identifier (pp_c_base (PP), T)
+ pp_c_tree_identifier (PP, T)
-void pp_cxx_pretty_printer_init (cxx_pretty_printer *);
void pp_cxx_begin_template_argument_list (cxx_pretty_printer *);
void pp_cxx_end_template_argument_list (cxx_pretty_printer *);
void pp_cxx_colon_colon (cxx_pretty_printer *);
void pp_cxx_separate_with (cxx_pretty_printer *, int);
-void pp_cxx_declaration (cxx_pretty_printer *, tree);
void pp_cxx_canonical_template_parameter (cxx_pretty_printer *, tree);
void pp_cxx_trait_expression (cxx_pretty_printer *, tree);
void pp_cxx_va_arg_expression (cxx_pretty_printer *, tree);
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 7d6fe0de8c1..b4223aa5706 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -75,7 +75,6 @@ static tree grokvardecl (tree, tree, const cp_decl_specifier_seq *,
static int check_static_variable_definition (tree, tree);
static void record_unknown_type (tree, const char *);
static tree builtin_function_1 (tree, tree, bool);
-static tree build_library_fn_1 (tree, enum tree_code, tree);
static int member_function_or_else (tree, tree, enum overload_flags);
static void bad_specifiers (tree, enum bad_spec_place, int, int, int, int,
int);
@@ -107,8 +106,8 @@ static tree cp_make_fname_decl (location_t, tree, int);
static void initialize_predefined_identifiers (void);
static tree check_special_function_return_type
(special_function_kind, tree, tree);
-static tree push_cp_library_fn (enum tree_code, tree);
-static tree build_cp_library_fn (tree, enum tree_code, tree);
+static tree push_cp_library_fn (enum tree_code, tree, int);
+static tree build_cp_library_fn (tree, enum tree_code, tree, int);
static void store_parm_decls (tree);
static void initialize_local_var (tree, tree);
static void expand_static_init (tree, tree);
@@ -1146,8 +1145,9 @@ warn_extern_redeclared_static (tree newdecl, tree olddecl)
&& DECL_ARTIFICIAL (olddecl))
return;
- permerror (input_location, "%qD was declared %<extern%> and later %<static%>", newdecl);
- permerror (input_location, "previous declaration of %q+D", olddecl);
+ if (permerror (input_location,
+ "%qD was declared %<extern%> and later %<static%>", newdecl))
+ inform (input_location, "previous declaration of %q+D", olddecl);
}
/* NEW_DECL is a redeclaration of OLD_DECL; both are functions or
@@ -1287,19 +1287,19 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
&& DECL_UNINLINABLE (olddecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
{
- warning (OPT_Wattributes, "function %q+D redeclared as inline",
- newdecl);
- warning (OPT_Wattributes, "previous declaration of %q+D "
- "with attribute noinline", olddecl);
+ if (warning (OPT_Wattributes, "function %q+D redeclared as inline",
+ newdecl))
+ inform (input_location, "previous declaration of %q+D "
+ "with attribute noinline", olddecl);
}
else if (DECL_DECLARED_INLINE_P (olddecl)
&& DECL_UNINLINABLE (newdecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
{
- warning (OPT_Wattributes, "function %q+D redeclared with "
- "attribute noinline", newdecl);
- warning (OPT_Wattributes, "previous declaration of %q+D was inline",
- olddecl);
+ if (warning (OPT_Wattributes, "function %q+D redeclared with "
+ "attribute noinline", newdecl))
+ inform (input_location, "previous declaration of %q+D was inline",
+ olddecl);
}
}
@@ -1485,7 +1485,7 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
error ("%q#D redeclared as different kind of symbol", newdecl);
if (TREE_CODE (olddecl) == TREE_LIST)
olddecl = TREE_VALUE (olddecl);
- error ("previous declaration of %q+#D", olddecl);
+ inform (input_location, "previous declaration of %q+#D", olddecl);
return error_mark_node;
}
@@ -1550,7 +1550,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
else
{
error ("conflicting declaration %q#D", newdecl);
- error ("%q+D has a previous declaration as %q#D", olddecl, olddecl);
+ inform (input_location,
+ "%q+D has a previous declaration as %q#D", olddecl, olddecl);
return error_mark_node;
}
}
@@ -1613,9 +1614,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
{
error_at (DECL_SOURCE_LOCATION (newdecl), errmsg, newdecl);
if (DECL_NAME (olddecl) != NULL_TREE)
- error ((DECL_INITIAL (olddecl) && namespace_bindings_p ())
- ? G_("%q+#D previously defined here")
- : G_("%q+#D previously declared here"), olddecl);
+ inform (input_location,
+ (DECL_INITIAL (olddecl) && namespace_bindings_p ())
+ ? G_("%q+#D previously defined here")
+ : G_("%q+#D previously declared here"), olddecl);
return error_mark_node;
}
else if (TREE_CODE (olddecl) == FUNCTION_DECL
@@ -1759,8 +1761,10 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend)
&& (! DECL_TEMPLATE_SPECIALIZATION (newdecl)
|| DECL_TEMPLATE_SPECIALIZATION (olddecl)))
{
- warning (OPT_Wredundant_decls, "redundant redeclaration of %qD in same scope", newdecl);
- warning (OPT_Wredundant_decls, "previous declaration of %q+D", olddecl);
+ if (warning (OPT_Wredundant_decls,
+ "redundant redeclaration of %qD in same scope",
+ newdecl))
+ inform (input_location, "previous declaration of %q+D", olddecl);
}
if (!(DECL_TEMPLATE_INSTANTIATION (olddecl)
@@ -3098,7 +3102,9 @@ case_conversion (tree type, tree value)
{
if (INTEGRAL_OR_UNSCOPED_ENUMERATION_TYPE_P (type))
type = type_promotes_to (type);
- value = perform_implicit_conversion (type, value, tf_warning_or_error);
+ value = (perform_implicit_conversion_flags
+ (type, value, tf_warning_or_error,
+ LOOKUP_IMPLICIT | LOOKUP_NO_NON_INTEGRAL));
}
return cxx_constant_value (value);
}
@@ -3793,10 +3799,10 @@ cxx_init_decl_processing (void)
newtype = build_exception_variant (newtype, new_eh_spec);
deltype = cp_build_type_attribute_variant (void_ftype_ptr, extvisattr);
deltype = build_exception_variant (deltype, empty_except_spec);
- push_cp_library_fn (NEW_EXPR, newtype);
- push_cp_library_fn (VEC_NEW_EXPR, newtype);
- global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype);
- push_cp_library_fn (VEC_DELETE_EXPR, deltype);
+ push_cp_library_fn (NEW_EXPR, newtype, 0);
+ push_cp_library_fn (VEC_NEW_EXPR, newtype, 0);
+ global_delete_fndecl = push_cp_library_fn (DELETE_EXPR, deltype, ECF_NOTHROW);
+ push_cp_library_fn (VEC_DELETE_EXPR, deltype, ECF_NOTHROW);
nullptr_type_node = make_node (NULLPTR_TYPE);
TYPE_SIZE (nullptr_type_node) = bitsize_int (GET_MODE_BITSIZE (ptr_mode));
@@ -3809,7 +3815,8 @@ cxx_init_decl_processing (void)
}
abort_fndecl
- = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype);
+ = build_library_fn_ptr ("__cxa_pure_virtual", void_ftype,
+ ECF_NORETURN | ECF_NOTHROW);
/* Perform other language dependent initializations. */
init_class_processing ();
@@ -4000,7 +4007,8 @@ cxx_builtin_function_ext_scope (tree decl)
function. Not called directly. */
static tree
-build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
+build_library_fn (tree name, enum tree_code operator_code, tree type,
+ int ecf_flags)
{
tree fn = build_lang_decl (FUNCTION_DECL, name, type);
DECL_EXTERNAL (fn) = 1;
@@ -4012,28 +4020,17 @@ build_library_fn_1 (tree name, enum tree_code operator_code, tree type)
external shared object. */
DECL_VISIBILITY (fn) = VISIBILITY_DEFAULT;
DECL_VISIBILITY_SPECIFIED (fn) = 1;
- return fn;
-}
-
-/* Returns the _DECL for a library function with C linkage.
- We assume that such functions never throw; if this is incorrect,
- callers should unset TREE_NOTHROW. */
-
-static tree
-build_library_fn (tree name, tree type)
-{
- tree fn = build_library_fn_1 (name, ERROR_MARK, type);
- TREE_NOTHROW (fn) = 1;
+ set_call_expr_flags (fn, ecf_flags);
return fn;
}
/* Returns the _DECL for a library function with C++ linkage. */
static tree
-build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
+build_cp_library_fn (tree name, enum tree_code operator_code, tree type,
+ int ecf_flags)
{
- tree fn = build_library_fn_1 (name, operator_code, type);
- TREE_NOTHROW (fn) = TYPE_NOTHROW_P (type);
+ tree fn = build_library_fn (name, operator_code, type, ecf_flags);
DECL_CONTEXT (fn) = FROB_CONTEXT (current_namespace);
SET_DECL_LANGUAGE (fn, lang_cplusplus);
return fn;
@@ -4043,18 +4040,19 @@ build_cp_library_fn (tree name, enum tree_code operator_code, tree type)
IDENTIFIER_NODE. */
tree
-build_library_fn_ptr (const char* name, tree type)
+build_library_fn_ptr (const char* name, tree type, int ecf_flags)
{
- return build_library_fn (get_identifier (name), type);
+ return build_library_fn (get_identifier (name), ERROR_MARK, type, ecf_flags);
}
/* Like build_cp_library_fn, but takes a C string instead of an
IDENTIFIER_NODE. */
tree
-build_cp_library_fn_ptr (const char* name, tree type)
+build_cp_library_fn_ptr (const char* name, tree type, int ecf_flags)
{
- return build_cp_library_fn (get_identifier (name), ERROR_MARK, type);
+ return build_cp_library_fn (get_identifier (name), ERROR_MARK, type,
+ ecf_flags);
}
/* Like build_library_fn, but also pushes the function so that we will
@@ -4062,14 +4060,14 @@ build_cp_library_fn_ptr (const char* name, tree type)
may throw exceptions listed in RAISES. */
tree
-push_library_fn (tree name, tree type, tree raises)
+push_library_fn (tree name, tree type, tree raises, int ecf_flags)
{
tree fn;
if (raises)
type = build_exception_variant (type, raises);
- fn = build_library_fn (name, type);
+ fn = build_library_fn (name, ERROR_MARK, type, ecf_flags);
pushdecl_top_level (fn);
return fn;
}
@@ -4078,11 +4076,12 @@ push_library_fn (tree name, tree type, tree raises)
will be found by normal lookup. */
static tree
-push_cp_library_fn (enum tree_code operator_code, tree type)
+push_cp_library_fn (enum tree_code operator_code, tree type,
+ int ecf_flags)
{
tree fn = build_cp_library_fn (ansi_opname (operator_code),
operator_code,
- type);
+ type, ecf_flags);
pushdecl (fn);
if (flag_tm)
apply_tm_attr (fn, get_identifier ("transaction_safe"));
@@ -4093,10 +4092,10 @@ push_cp_library_fn (enum tree_code operator_code, tree type)
a FUNCTION_TYPE. */
tree
-push_void_library_fn (tree name, tree parmtypes)
+push_void_library_fn (tree name, tree parmtypes, int ecf_flags)
{
tree type = build_function_type (void_type_node, parmtypes);
- return push_library_fn (name, type, NULL_TREE);
+ return push_library_fn (name, type, NULL_TREE, ecf_flags);
}
/* Like push_library_fn, but also note that this function throws
@@ -4105,9 +4104,7 @@ push_void_library_fn (tree name, tree parmtypes)
tree
push_throw_library_fn (tree name, tree type)
{
- tree fn = push_library_fn (name, type, NULL_TREE);
- TREE_THIS_VOLATILE (fn) = 1;
- TREE_NOTHROW (fn) = 0;
+ tree fn = push_library_fn (name, type, NULL_TREE, ECF_NORETURN);
return fn;
}
@@ -6637,7 +6634,7 @@ get_atexit_node (void)
/* Now, build the function declaration. */
push_lang_context (lang_name_c);
- atexit_fndecl = build_library_fn_ptr (name, fn_type);
+ atexit_fndecl = build_library_fn_ptr (name, fn_type, ECF_LEAF | ECF_NOTHROW);
mark_used (atexit_fndecl);
pop_lang_context ();
atexit_node = decay_conversion (atexit_fndecl, tf_warning_or_error);
@@ -6659,7 +6656,8 @@ get_thread_atexit_node (void)
NULL_TREE);
/* Now, build the function declaration. */
- tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type);
+ tree atexit_fndecl = build_library_fn_ptr ("__cxa_thread_atexit", fn_type,
+ ECF_LEAF | ECF_NOTHROW);
return decay_conversion (atexit_fndecl, tf_warning_or_error);
}
@@ -6985,15 +6983,17 @@ expand_static_init (tree decl, tree init)
(acquire_name, build_function_type_list (integer_type_node,
TREE_TYPE (guard_addr),
NULL_TREE),
- NULL_TREE);
+ NULL_TREE, ECF_NOTHROW | ECF_LEAF);
if (!release_fn || !abort_fn)
vfntype = build_function_type_list (void_type_node,
TREE_TYPE (guard_addr),
NULL_TREE);
if (!release_fn)
- release_fn = push_library_fn (release_name, vfntype, NULL_TREE);
+ release_fn = push_library_fn (release_name, vfntype, NULL_TREE,
+ ECF_NOTHROW | ECF_LEAF);
if (!abort_fn)
- abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE);
+ abort_fn = push_library_fn (abort_name, vfntype, NULL_TREE,
+ ECF_NOTHROW | ECF_LEAF);
inner_if_stmt = begin_if_stmt ();
finish_if_stmt_cond (build_call_n (acquire_fn, 1, guard_addr),
@@ -7420,17 +7420,6 @@ grokfndecl (tree ctype,
the information in the TEMPLATE_ID_EXPR. */
SET_DECL_IMPLICIT_INSTANTIATION (decl);
- if (TREE_CODE (fns) == COMPONENT_REF)
- {
- /* Due to bison parser ickiness, we will have already looked
- up an operator_name or PFUNCNAME within the current class
- (see template_id in parse.y). If the current class contains
- such a name, we'll get a COMPONENT_REF here. Undo that. */
-
- gcc_assert (TREE_TYPE (TREE_OPERAND (fns, 0))
- == current_class_type);
- fns = TREE_OPERAND (fns, 1);
- }
gcc_assert (identifier_p (fns) || TREE_CODE (fns) == OVERLOAD);
DECL_TEMPLATE_INFO (decl) = build_template_info (fns, args);
@@ -11836,14 +11825,14 @@ check_elaborated_type_specifier (enum tag_types tag_code,
&& tag_code != typename_type)
{
error ("%qT referred to as %qs", type, tag_name (tag_code));
- error ("%q+T has a previous declaration here", type);
+ inform (input_location, "%q+T has a previous declaration here", type);
return error_mark_node;
}
else if (TREE_CODE (type) != ENUMERAL_TYPE
&& tag_code == enum_type)
{
error ("%qT referred to as enum", type);
- error ("%q+T has a previous declaration here", type);
+ inform (input_location, "%q+T has a previous declaration here", type);
return error_mark_node;
}
else if (!allow_template_p
@@ -14266,13 +14255,6 @@ cxx_maybe_build_cleanup (tree decl, tsubst_flags_t complain)
}
-/* When a stmt has been parsed, this function is called. */
-
-void
-finish_stmt (void)
-{
-}
-
/* Return the FUNCTION_TYPE that corresponds to MEMFNTYPE, which can be a
FUNCTION_DECL, METHOD_TYPE, FUNCTION_TYPE, pointer or reference to
METHOD_TYPE or FUNCTION_TYPE, or pointer to member function. */
diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c
index 1573cede899..d5d29127cfd 100644
--- a/gcc/cp/decl2.c
+++ b/gcc/cp/decl2.c
@@ -3039,7 +3039,8 @@ generate_tls_wrapper (tree fn)
}
/* Start the process of running a particular set of global constructors
- or destructors. Subroutine of do_[cd]tors. */
+ or destructors. Subroutine of do_[cd]tors. Also called from
+ vtv_start_verification_constructor_init_function. */
static tree
start_objects (int method_type, int initp)
@@ -4353,8 +4354,25 @@ cp_write_global_declarations (void)
timevar_stop (TV_PHASE_DEFERRED);
timevar_start (TV_PHASE_OPT_GEN);
+ if (flag_vtable_verify)
+ {
+ vtv_recover_class_info ();
+ vtv_compute_class_hierarchy_transitive_closure ();
+ vtv_build_vtable_verify_fndecl ();
+ }
+
finalize_compilation_unit ();
+ if (flag_vtable_verify)
+ {
+ /* Generate the special constructor initialization function that
+ calls __VLTRegisterPairs, and give it a very high
+ initialization priority. This must be done after
+ finalize_compilation_unit so that we have accurate
+ information about which vtable will actually be emitted. */
+ vtv_generate_init_routine ();
+ }
+
timevar_stop (TV_PHASE_OPT_GEN);
timevar_start (TV_PHASE_CHECK_DBGINFO);
@@ -4731,4 +4749,23 @@ mark_used (tree decl)
return mark_used (decl, tf_warning_or_error);
}
+tree
+vtv_start_verification_constructor_init_function (void)
+{
+ return start_objects ('I', MAX_RESERVED_INIT_PRIORITY - 1);
+}
+
+tree
+vtv_finish_verification_constructor_init_function (tree function_body)
+{
+ tree fn;
+
+ finish_compound_stmt (function_body);
+ fn = finish_function (0);
+ DECL_STATIC_CONSTRUCTOR (fn) = 1;
+ decl_init_priority_insert (fn, MAX_RESERVED_INIT_PRIORITY - 1);
+
+ return fn;
+}
+
#include "gt-cp-decl2.h"
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index a8f52cda0ae..78c74b65e67 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -32,6 +32,9 @@ along with GCC; see the file COPYING3. If not see
#include "tree-pretty-print.h"
#include "pointer-set.h"
#include "c-family/c-objc.h"
+#include "ubsan.h"
+
+#include <new> // For placement-new.
#define pp_separate_with_comma(PP) pp_cxx_separate_with (PP, ',')
#define pp_separate_with_semicolon(PP) pp_cxx_separate_with (PP, ';')
@@ -59,33 +62,34 @@ static const char *op_to_string (enum tree_code);
static const char *parm_to_string (int);
static const char *type_to_string (tree, int);
-static void dump_alias_template_specialization (tree, int);
-static void dump_type (tree, int);
-static void dump_typename (tree, int);
-static void dump_simple_decl (tree, tree, int);
-static void dump_decl (tree, int);
-static void dump_template_decl (tree, int);
-static void dump_function_decl (tree, int);
-static void dump_expr (tree, int);
-static void dump_unary_op (const char *, tree, int);
-static void dump_binary_op (const char *, tree, int);
-static void dump_aggr_type (tree, int);
-static void dump_type_prefix (tree, int);
-static void dump_type_suffix (tree, int);
-static void dump_function_name (tree, int);
-static void dump_call_expr_args (tree, int, bool);
-static void dump_aggr_init_expr_args (tree, int, bool);
-static void dump_expr_list (tree, int);
-static void dump_global_iord (tree);
-static void dump_parameters (tree, int);
-static void dump_ref_qualifier (tree, int);
-static void dump_exception_spec (tree, int);
-static void dump_template_argument (tree, int);
-static void dump_template_argument_list (tree, int);
-static void dump_template_parameter (tree, int);
-static void dump_template_bindings (tree, tree, vec<tree, va_gc> *);
-static void dump_scope (tree, int);
-static void dump_template_parms (tree, int, int);
+static void dump_alias_template_specialization (cxx_pretty_printer *, tree, int);
+static void dump_type (cxx_pretty_printer *, tree, int);
+static void dump_typename (cxx_pretty_printer *, tree, int);
+static void dump_simple_decl (cxx_pretty_printer *, tree, tree, int);
+static void dump_decl (cxx_pretty_printer *, tree, int);
+static void dump_template_decl (cxx_pretty_printer *, tree, int);
+static void dump_function_decl (cxx_pretty_printer *, tree, int);
+static void dump_expr (cxx_pretty_printer *, tree, int);
+static void dump_unary_op (cxx_pretty_printer *, const char *, tree, int);
+static void dump_binary_op (cxx_pretty_printer *, const char *, tree, int);
+static void dump_aggr_type (cxx_pretty_printer *, tree, int);
+static void dump_type_prefix (cxx_pretty_printer *, tree, int);
+static void dump_type_suffix (cxx_pretty_printer *, tree, int);
+static void dump_function_name (cxx_pretty_printer *, tree, int);
+static void dump_call_expr_args (cxx_pretty_printer *, tree, int, bool);
+static void dump_aggr_init_expr_args (cxx_pretty_printer *, tree, int, bool);
+static void dump_expr_list (cxx_pretty_printer *, tree, int);
+static void dump_global_iord (cxx_pretty_printer *, tree);
+static void dump_parameters (cxx_pretty_printer *, tree, int);
+static void dump_ref_qualifier (cxx_pretty_printer *, tree, int);
+static void dump_exception_spec (cxx_pretty_printer *, tree, int);
+static void dump_template_argument (cxx_pretty_printer *, tree, int);
+static void dump_template_argument_list (cxx_pretty_printer *, tree, int);
+static void dump_template_parameter (cxx_pretty_printer *, tree, int);
+static void dump_template_bindings (cxx_pretty_printer *, tree, tree,
+ vec<tree, va_gc> *);
+static void dump_scope (cxx_pretty_printer *, tree, int);
+static void dump_template_parms (cxx_pretty_printer *, tree, int, int);
static int get_non_default_template_args_count (tree, int);
static const char *function_category (tree);
static void maybe_print_constexpr_context (diagnostic_context *);
@@ -108,14 +112,13 @@ init_error (void)
diagnostic_finalizer (global_dc) = cp_diagnostic_finalizer;
diagnostic_format_decoder (global_dc) = cp_printer;
- pp_construct (pp_base (cxx_pp), NULL, 0);
- pp_cxx_pretty_printer_init (cxx_pp);
+ new (cxx_pp) cxx_pretty_printer ();
}
/* Dump a scope, if deemed necessary. */
static void
-dump_scope (tree scope, int flags)
+dump_scope (cxx_pretty_printer *pp, tree scope, int flags)
{
int f = flags & (TFF_SCOPE | TFF_CHASE_TYPEDEF);
@@ -126,39 +129,39 @@ dump_scope (tree scope, int flags)
{
if (scope != global_namespace)
{
- dump_decl (scope, f);
- pp_cxx_colon_colon (cxx_pp);
+ dump_decl (pp, scope, f);
+ pp_cxx_colon_colon (pp);
}
}
else if (AGGREGATE_TYPE_P (scope))
{
- dump_type (scope, f);
- pp_cxx_colon_colon (cxx_pp);
+ dump_type (pp, scope, f);
+ pp_cxx_colon_colon (pp);
}
else if ((flags & TFF_SCOPE) && TREE_CODE (scope) == FUNCTION_DECL)
{
- dump_function_decl (scope, f);
- pp_cxx_colon_colon (cxx_pp);
+ dump_function_decl (pp, scope, f);
+ pp_cxx_colon_colon (pp);
}
}
/* Dump the template ARGument under control of FLAGS. */
static void
-dump_template_argument (tree arg, int flags)
+dump_template_argument (cxx_pretty_printer *pp, tree arg, int flags)
{
if (ARGUMENT_PACK_P (arg))
- dump_template_argument_list (ARGUMENT_PACK_ARGS (arg),
+ dump_template_argument_list (pp, ARGUMENT_PACK_ARGS (arg),
/* No default args in argument packs. */
flags|TFF_NO_OMIT_DEFAULT_TEMPLATE_ARGUMENTS);
else if (TYPE_P (arg) || TREE_CODE (arg) == TEMPLATE_DECL)
- dump_type (arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
+ dump_type (pp, arg, flags & ~TFF_CLASS_KEY_OR_ENUM);
else
{
if (TREE_CODE (arg) == TREE_LIST)
arg = TREE_VALUE (arg);
- dump_expr (arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
+ dump_expr (pp, arg, (flags | TFF_EXPR_IN_PARENS) & ~TFF_CLASS_KEY_OR_ENUM);
}
}
@@ -186,7 +189,7 @@ get_non_default_template_args_count (tree args, int flags)
of FLAGS. */
static void
-dump_template_argument_list (tree args, int flags)
+dump_template_argument_list (cxx_pretty_printer *pp, tree args, int flags)
{
int n = get_non_default_template_args_count (args, flags);
int need_comma = 0;
@@ -202,9 +205,9 @@ dump_template_argument_list (tree args, int flags)
if (need_comma
&& (!ARGUMENT_PACK_P (arg)
|| TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
- dump_template_argument (arg, flags);
+ dump_template_argument (pp, arg, flags);
need_comma = 1;
}
}
@@ -212,7 +215,7 @@ dump_template_argument_list (tree args, int flags)
/* Dump a template parameter PARM (a TREE_LIST) under control of FLAGS. */
static void
-dump_template_parameter (tree parm, int flags)
+dump_template_parameter (cxx_pretty_printer *pp, tree parm, int flags)
{
tree p;
tree a;
@@ -227,29 +230,29 @@ dump_template_parameter (tree parm, int flags)
{
if (flags & TFF_DECL_SPECIFIERS)
{
- pp_cxx_ws_string (cxx_pp, "class");
+ pp_cxx_ws_string (pp, "class");
if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (p)))
- pp_cxx_ws_string (cxx_pp, "...");
+ pp_cxx_ws_string (pp, "...");
if (DECL_NAME (p))
- pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p));
+ pp_cxx_tree_identifier (pp, DECL_NAME (p));
}
else if (DECL_NAME (p))
- pp_cxx_tree_identifier (cxx_pp, DECL_NAME (p));
+ pp_cxx_tree_identifier (pp, DECL_NAME (p));
else
- pp_cxx_canonical_template_parameter (cxx_pp, TREE_TYPE (p));
+ pp_cxx_canonical_template_parameter (pp, TREE_TYPE (p));
}
else
- dump_decl (p, flags | TFF_DECL_SPECIFIERS);
+ dump_decl (pp, p, flags | TFF_DECL_SPECIFIERS);
if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && a != NULL_TREE)
{
- pp_cxx_whitespace (cxx_pp);
- pp_equal (cxx_pp);
- pp_cxx_whitespace (cxx_pp);
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
if (TREE_CODE (p) == TYPE_DECL || TREE_CODE (p) == TEMPLATE_DECL)
- dump_type (a, flags & ~TFF_CHASE_TYPEDEF);
+ dump_type (pp, a, flags & ~TFF_CHASE_TYPEDEF);
else
- dump_expr (a, flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, a, flags | TFF_EXPR_IN_PARENS);
}
}
@@ -258,7 +261,8 @@ dump_template_parameter (tree parm, int flags)
TREE_VEC. */
static void
-dump_template_bindings (tree parms, tree args, vec<tree, va_gc> *typenames)
+dump_template_bindings (cxx_pretty_printer *pp, tree parms, tree args,
+ vec<tree, va_gc> *typenames)
{
bool need_semicolon = false;
int i;
@@ -285,21 +289,22 @@ dump_template_bindings (tree parms, tree args, vec<tree, va_gc> *typenames)
arg = TREE_VEC_ELT (lvl_args, arg_idx);
if (need_semicolon)
- pp_separate_with_semicolon (cxx_pp);
- dump_template_parameter (TREE_VEC_ELT (p, i), TFF_PLAIN_IDENTIFIER);
- pp_cxx_whitespace (cxx_pp);
- pp_equal (cxx_pp);
- pp_cxx_whitespace (cxx_pp);
+ pp_separate_with_semicolon (pp);
+ dump_template_parameter (pp, TREE_VEC_ELT (p, i),
+ TFF_PLAIN_IDENTIFIER);
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
if (arg)
{
if (ARGUMENT_PACK_P (arg))
- pp_cxx_left_brace (cxx_pp);
- dump_template_argument (arg, TFF_PLAIN_IDENTIFIER);
+ pp_cxx_left_brace (pp);
+ dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
if (ARGUMENT_PACK_P (arg))
- pp_cxx_right_brace (cxx_pp);
+ pp_cxx_right_brace (pp);
}
else
- pp_string (cxx_pp, M_("<missing>"));
+ pp_string (pp, M_("<missing>"));
++arg_idx;
need_semicolon = true;
@@ -315,18 +320,18 @@ dump_template_bindings (tree parms, tree args, vec<tree, va_gc> *typenames)
FOR_EACH_VEC_SAFE_ELT (typenames, i, t)
{
if (need_semicolon)
- pp_separate_with_semicolon (cxx_pp);
- dump_type (t, TFF_PLAIN_IDENTIFIER);
- pp_cxx_whitespace (cxx_pp);
- pp_equal (cxx_pp);
- pp_cxx_whitespace (cxx_pp);
+ pp_separate_with_semicolon (pp);
+ dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
push_deferring_access_checks (dk_no_check);
t = tsubst (t, args, tf_none, NULL_TREE);
pop_deferring_access_checks ();
/* Strip typedefs. We can't just use TFF_CHASE_TYPEDEF because
pp_simple_type_specifier doesn't know about it. */
t = strip_typedefs (t);
- dump_type (t, TFF_PLAIN_IDENTIFIER);
+ dump_type (pp, t, TFF_PLAIN_IDENTIFIER);
}
}
@@ -334,17 +339,17 @@ dump_template_bindings (tree parms, tree args, vec<tree, va_gc> *typenames)
specialization of T. */
static void
-dump_alias_template_specialization (tree t, int flags)
+dump_alias_template_specialization (cxx_pretty_printer *pp, tree t, int flags)
{
tree name;
gcc_assert (alias_template_specialization_p (t));
if (!(flags & TFF_UNQUALIFIED_NAME))
- dump_scope (CP_DECL_CONTEXT (TYPE_NAME (t)), flags);
+ dump_scope (pp, CP_DECL_CONTEXT (TYPE_NAME (t)), flags);
name = TYPE_IDENTIFIER (t);
- pp_cxx_tree_identifier (cxx_pp, name);
- dump_template_parms (TYPE_TEMPLATE_INFO (t),
+ pp_cxx_tree_identifier (pp, name);
+ dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
/*primary=*/false,
flags & ~TFF_TEMPLATE_HEADER);
}
@@ -353,7 +358,7 @@ dump_alias_template_specialization (tree t, int flags)
format. */
static void
-dump_type (tree t, int flags)
+dump_type (cxx_pretty_printer *pp, tree t, int flags)
{
if (t == NULL_TREE)
return;
@@ -369,15 +374,15 @@ dump_type (tree t, int flags)
t = strip_typedefs (t);
else if (alias_template_specialization_p (t))
{
- dump_alias_template_specialization (t, flags);
+ dump_alias_template_specialization (pp, t, flags);
return;
}
else if (same_type_p (t, TREE_TYPE (decl)))
t = decl;
else
{
- pp_cxx_cv_qualifier_seq (cxx_pp, t);
- pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
return;
}
}
@@ -389,39 +394,39 @@ dump_type (tree t, int flags)
{
case LANG_TYPE:
if (t == init_list_type_node)
- pp_string (cxx_pp, M_("<brace-enclosed initializer list>"));
+ pp_string (pp, M_("<brace-enclosed initializer list>"));
else if (t == unknown_type_node)
- pp_string (cxx_pp, M_("<unresolved overloaded function type>"));
+ pp_string (pp, M_("<unresolved overloaded function type>"));
else
{
- pp_cxx_cv_qualifier_seq (cxx_pp, t);
- pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
}
break;
case TREE_LIST:
/* A list of function parms. */
- dump_parameters (t, flags);
+ dump_parameters (pp, t, flags);
break;
case IDENTIFIER_NODE:
- pp_cxx_tree_identifier (cxx_pp, t);
+ pp_cxx_tree_identifier (pp, t);
break;
case TREE_BINFO:
- dump_type (BINFO_TYPE (t), flags);
+ dump_type (pp, BINFO_TYPE (t), flags);
break;
case RECORD_TYPE:
case UNION_TYPE:
case ENUMERAL_TYPE:
- dump_aggr_type (t, flags);
+ dump_aggr_type (pp, t, flags);
break;
case TYPE_DECL:
if (flags & TFF_CHASE_TYPEDEF)
{
- dump_type (DECL_ORIGINAL_TYPE (t)
+ dump_type (pp, DECL_ORIGINAL_TYPE (t)
? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), flags);
break;
}
@@ -429,7 +434,7 @@ dump_type (tree t, int flags)
case TEMPLATE_DECL:
case NAMESPACE_DECL:
- dump_decl (t, flags & ~TFF_DECL_SPECIFIERS);
+ dump_decl (pp, t, flags & ~TFF_DECL_SPECIFIERS);
break;
case INTEGER_TYPE:
@@ -439,35 +444,35 @@ dump_type (tree t, int flags)
case COMPLEX_TYPE:
case VECTOR_TYPE:
case FIXED_POINT_TYPE:
- pp_type_specifier_seq (cxx_pp, t);
+ pp_type_specifier_seq (pp, t);
break;
case TEMPLATE_TEMPLATE_PARM:
/* For parameters inside template signature. */
if (TYPE_IDENTIFIER (t))
- pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
else
- pp_cxx_canonical_template_parameter (cxx_pp, t);
+ pp_cxx_canonical_template_parameter (pp, t);
break;
case BOUND_TEMPLATE_TEMPLATE_PARM:
{
tree args = TYPE_TI_ARGS (t);
- pp_cxx_cv_qualifier_seq (cxx_pp, t);
- pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
- pp_cxx_begin_template_argument_list (cxx_pp);
- dump_template_argument_list (args, flags);
- pp_cxx_end_template_argument_list (cxx_pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
+ pp_cxx_begin_template_argument_list (pp);
+ dump_template_argument_list (pp, args, flags);
+ pp_cxx_end_template_argument_list (pp);
}
break;
case TEMPLATE_TYPE_PARM:
- pp_cxx_cv_qualifier_seq (cxx_pp, t);
+ pp_cxx_cv_qualifier_seq (pp, t);
if (TYPE_IDENTIFIER (t))
- pp_cxx_tree_identifier (cxx_pp, TYPE_IDENTIFIER (t));
+ pp_cxx_tree_identifier (pp, TYPE_IDENTIFIER (t));
else
pp_cxx_canonical_template_parameter
- (cxx_pp, TEMPLATE_TYPE_PARM_INDEX (t));
+ (pp, TEMPLATE_TYPE_PARM_INDEX (t));
break;
/* This is not always necessary for pointers and such, but doing this
@@ -480,78 +485,78 @@ dump_type (tree t, int flags)
case FUNCTION_TYPE:
case METHOD_TYPE:
{
- dump_type_prefix (t, flags);
- dump_type_suffix (t, flags);
+ dump_type_prefix (pp, t, flags);
+ dump_type_suffix (pp, t, flags);
break;
}
case TYPENAME_TYPE:
if (! (flags & TFF_CHASE_TYPEDEF)
&& DECL_ORIGINAL_TYPE (TYPE_NAME (t)))
{
- dump_decl (TYPE_NAME (t), TFF_PLAIN_IDENTIFIER);
+ dump_decl (pp, TYPE_NAME (t), TFF_PLAIN_IDENTIFIER);
break;
}
- pp_cxx_cv_qualifier_seq (cxx_pp, t);
- pp_cxx_ws_string (cxx_pp,
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp_cxx_ws_string (pp,
TYPENAME_IS_ENUM_P (t) ? "enum"
: TYPENAME_IS_CLASS_P (t) ? "class"
: "typename");
- dump_typename (t, flags);
+ dump_typename (pp, t, flags);
break;
case UNBOUND_CLASS_TEMPLATE:
if (! (flags & TFF_UNQUALIFIED_NAME))
{
- dump_type (TYPE_CONTEXT (t), flags);
- pp_cxx_colon_colon (cxx_pp);
+ dump_type (pp, TYPE_CONTEXT (t), flags);
+ pp_cxx_colon_colon (pp);
}
- pp_cxx_ws_string (cxx_pp, "template");
- dump_type (DECL_NAME (TYPE_NAME (t)), flags);
+ pp_cxx_ws_string (pp, "template");
+ dump_type (pp, DECL_NAME (TYPE_NAME (t)), flags);
break;
case TYPEOF_TYPE:
- pp_cxx_ws_string (cxx_pp, "__typeof__");
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_expr (TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_ws_string (pp, "__typeof__");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TYPEOF_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
break;
case UNDERLYING_TYPE:
- pp_cxx_ws_string (cxx_pp, "__underlying_type");
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_expr (UNDERLYING_TYPE_TYPE (t), flags & ~TFF_EXPR_IN_PARENS);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_ws_string (pp, "__underlying_type");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, UNDERLYING_TYPE_TYPE (t), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
break;
case TYPE_PACK_EXPANSION:
- dump_type (PACK_EXPANSION_PATTERN (t), flags);
- pp_cxx_ws_string (cxx_pp, "...");
+ dump_type (pp, PACK_EXPANSION_PATTERN (t), flags);
+ pp_cxx_ws_string (pp, "...");
break;
case TYPE_ARGUMENT_PACK:
- dump_template_argument (t, flags);
+ dump_template_argument (pp, t, flags);
break;
case DECLTYPE_TYPE:
- pp_cxx_ws_string (cxx_pp, "decltype");
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_expr (DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_ws_string (pp, "decltype");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, DECLTYPE_TYPE_EXPR (t), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
break;
case NULLPTR_TYPE:
- pp_string (cxx_pp, "std::nullptr_t");
+ pp_string (pp, "std::nullptr_t");
break;
default:
- pp_unsupported_tree (cxx_pp, t);
+ pp_unsupported_tree (pp, t);
/* Fall through to error. */
case ERROR_MARK:
- pp_string (cxx_pp, M_("<type error>"));
+ pp_string (pp, M_("<type error>"));
break;
}
}
@@ -560,16 +565,16 @@ dump_type (tree t, int flags)
a TYPENAME_TYPE. */
static void
-dump_typename (tree t, int flags)
+dump_typename (cxx_pretty_printer *pp, tree t, int flags)
{
tree ctx = TYPE_CONTEXT (t);
if (TREE_CODE (ctx) == TYPENAME_TYPE)
- dump_typename (ctx, flags);
+ dump_typename (pp, ctx, flags);
else
- dump_type (ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
- pp_cxx_colon_colon (cxx_pp);
- dump_decl (TYPENAME_TYPE_FULLNAME (t), flags);
+ dump_type (pp, ctx, flags & ~TFF_CLASS_KEY_OR_ENUM);
+ pp_cxx_colon_colon (pp);
+ dump_decl (pp, TYPENAME_TYPE_FULLNAME (t), flags);
}
/* Return the name of the supplied aggregate, or enumeral type. */
@@ -596,17 +601,17 @@ class_key_or_enum_as_string (tree t)
in the form `class foo'. */
static void
-dump_aggr_type (tree t, int flags)
+dump_aggr_type (cxx_pretty_printer *pp, tree t, int flags)
{
tree name;
const char *variety = class_key_or_enum_as_string (t);
int typdef = 0;
int tmplate = 0;
- pp_cxx_cv_qualifier_seq (cxx_pp, t);
+ pp_cxx_cv_qualifier_seq (pp, t);
if (flags & TFF_CLASS_KEY_OR_ENUM)
- pp_cxx_ws_string (cxx_pp, variety);
+ pp_cxx_ws_string (pp, variety);
name = TYPE_NAME (t);
@@ -634,7 +639,7 @@ dump_aggr_type (tree t, int flags)
|| PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (t)));
if (! (flags & TFF_UNQUALIFIED_NAME))
- dump_scope (CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
+ dump_scope (pp, CP_DECL_CONTEXT (name), flags | TFF_SCOPE);
flags &= ~TFF_UNQUALIFIED_NAME;
if (tmplate)
{
@@ -652,23 +657,24 @@ dump_aggr_type (tree t, int flags)
if (name == 0 || ANON_AGGRNAME_P (name))
{
if (flags & TFF_CLASS_KEY_OR_ENUM)
- pp_string (cxx_pp, M_("<anonymous>"));
+ pp_string (pp, M_("<anonymous>"));
else
- pp_printf (pp_base (cxx_pp), M_("<anonymous %s>"), variety);
+ pp_printf (pp, M_("<anonymous %s>"), variety);
}
else if (LAMBDA_TYPE_P (t))
{
/* A lambda's "type" is essentially its signature. */
- pp_string (cxx_pp, M_("<lambda"));
+ pp_string (pp, M_("<lambda"));
if (lambda_function (t))
- dump_parameters (FUNCTION_FIRST_USER_PARMTYPE (lambda_function (t)),
+ dump_parameters (pp,
+ FUNCTION_FIRST_USER_PARMTYPE (lambda_function (t)),
flags);
- pp_character(cxx_pp, '>');
+ pp_greater (pp);
}
else
- pp_cxx_tree_identifier (cxx_pp, name);
+ pp_cxx_tree_identifier (pp, name);
if (tmplate)
- dump_template_parms (TYPE_TEMPLATE_INFO (t),
+ dump_template_parms (pp, TYPE_TEMPLATE_INFO (t),
!CLASSTYPE_USE_TEMPLATE (t),
flags & ~TFF_TEMPLATE_HEADER);
}
@@ -685,7 +691,7 @@ dump_aggr_type (tree t, int flags)
int *[]&. */
static void
-dump_type_prefix (tree t, int flags)
+dump_type_prefix (cxx_pretty_printer *pp, tree t, int flags)
{
if (TYPE_PTRMEMFUNC_P (t))
{
@@ -700,61 +706,60 @@ dump_type_prefix (tree t, int flags)
{
tree sub = TREE_TYPE (t);
- dump_type_prefix (sub, flags);
+ dump_type_prefix (pp, sub, flags);
if (TREE_CODE (sub) == ARRAY_TYPE
|| TREE_CODE (sub) == FUNCTION_TYPE)
{
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- pp_c_attributes_display (pp_c_base (cxx_pp),
- TYPE_ATTRIBUTES (sub));
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ pp_c_attributes_display (pp, TYPE_ATTRIBUTES (sub));
}
if (TYPE_PTR_P (t))
- pp_character(cxx_pp, '*');
+ pp_star (pp);
else if (TREE_CODE (t) == REFERENCE_TYPE)
{
if (TYPE_REF_IS_RVALUE (t))
- pp_string (cxx_pp, "&&");
+ pp_ampersand_ampersand (pp);
else
- pp_character (cxx_pp, '&');
+ pp_ampersand (pp);
}
- pp_base (cxx_pp)->padding = pp_before;
- pp_cxx_cv_qualifier_seq (cxx_pp, t);
+ pp->padding = pp_before;
+ pp_cxx_cv_qualifier_seq (pp, t);
}
break;
case OFFSET_TYPE:
offset_type:
- dump_type_prefix (TREE_TYPE (t), flags);
+ dump_type_prefix (pp, TREE_TYPE (t), flags);
if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */
{
- pp_maybe_space (cxx_pp);
+ pp_maybe_space (pp);
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE)
- pp_cxx_left_paren (cxx_pp);
- dump_type (TYPE_OFFSET_BASETYPE (t), flags);
- pp_cxx_colon_colon (cxx_pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TYPE_OFFSET_BASETYPE (t), flags);
+ pp_cxx_colon_colon (pp);
}
- pp_cxx_star (cxx_pp);
- pp_cxx_cv_qualifier_seq (cxx_pp, t);
- pp_base (cxx_pp)->padding = pp_before;
+ pp_cxx_star (pp);
+ pp_cxx_cv_qualifier_seq (pp, t);
+ pp->padding = pp_before;
break;
/* This can be reached without a pointer when dealing with
templates, e.g. std::is_function. */
case FUNCTION_TYPE:
- dump_type_prefix (TREE_TYPE (t), flags);
+ dump_type_prefix (pp, TREE_TYPE (t), flags);
break;
case METHOD_TYPE:
- dump_type_prefix (TREE_TYPE (t), flags);
- pp_maybe_space (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_aggr_type (TYPE_METHOD_BASETYPE (t), flags);
- pp_cxx_colon_colon (cxx_pp);
+ dump_type_prefix (pp, TREE_TYPE (t), flags);
+ pp_maybe_space (pp);
+ pp_cxx_left_paren (pp);
+ dump_aggr_type (pp, TYPE_METHOD_BASETYPE (t), flags);
+ pp_cxx_colon_colon (pp);
break;
case ARRAY_TYPE:
- dump_type_prefix (TREE_TYPE (t), flags);
+ dump_type_prefix (pp, TREE_TYPE (t), flags);
break;
case ENUMERAL_TYPE:
@@ -781,15 +786,15 @@ dump_type_prefix (tree t, int flags)
case TYPE_PACK_EXPANSION:
case FIXED_POINT_TYPE:
case NULLPTR_TYPE:
- dump_type (t, flags);
- pp_base (cxx_pp)->padding = pp_before;
+ dump_type (pp, t, flags);
+ pp->padding = pp_before;
break;
default:
- pp_unsupported_tree (cxx_pp, t);
+ pp_unsupported_tree (pp, t);
/* fall through. */
case ERROR_MARK:
- pp_string (cxx_pp, M_("<typeprefixerror>"));
+ pp_string (pp, M_("<typeprefixerror>"));
break;
}
}
@@ -798,7 +803,7 @@ dump_type_prefix (tree t, int flags)
which appears after the identifier (or function parms). */
static void
-dump_type_suffix (tree t, int flags)
+dump_type_suffix (cxx_pretty_printer *pp, tree t, int flags)
{
if (TYPE_PTRMEMFUNC_P (t))
t = TYPE_PTRMEMFUNC_FN_TYPE (t);
@@ -810,8 +815,8 @@ dump_type_suffix (tree t, int flags)
case OFFSET_TYPE:
if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE
|| TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE)
- pp_cxx_right_paren (cxx_pp);
- dump_type_suffix (TREE_TYPE (t), flags);
+ pp_cxx_right_paren (pp);
+ dump_type_suffix (pp, TREE_TYPE (t), flags);
break;
case FUNCTION_TYPE:
@@ -820,34 +825,34 @@ dump_type_suffix (tree t, int flags)
tree arg;
if (TREE_CODE (t) == METHOD_TYPE)
/* Can only be reached through a pointer. */
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
arg = TYPE_ARG_TYPES (t);
if (TREE_CODE (t) == METHOD_TYPE)
arg = TREE_CHAIN (arg);
/* Function pointers don't have default args. Not in standard C++,
anyway; they may in g++, but we'll just pretend otherwise. */
- dump_parameters (arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
+ dump_parameters (pp, arg, flags & ~TFF_FUNCTION_DEFAULT_ARGUMENTS);
- pp_base (cxx_pp)->padding = pp_before;
- pp_cxx_cv_qualifiers (cxx_pp, type_memfn_quals (t));
- dump_ref_qualifier (t, flags);
- dump_exception_spec (TYPE_RAISES_EXCEPTIONS (t), flags);
- dump_type_suffix (TREE_TYPE (t), flags);
+ pp->padding = pp_before;
+ pp_cxx_cv_qualifiers (pp, type_memfn_quals (t));
+ dump_ref_qualifier (pp, t, flags);
+ dump_exception_spec (pp, TYPE_RAISES_EXCEPTIONS (t), flags);
+ dump_type_suffix (pp, TREE_TYPE (t), flags);
break;
}
case ARRAY_TYPE:
- pp_maybe_space (cxx_pp);
- pp_cxx_left_bracket (cxx_pp);
+ pp_maybe_space (pp);
+ pp_cxx_left_bracket (pp);
if (TYPE_DOMAIN (t))
{
tree dtype = TYPE_DOMAIN (t);
tree max = TYPE_MAX_VALUE (dtype);
if (integer_all_onesp (max))
- pp_character (cxx_pp, '0');
+ pp_character (pp, '0');
else if (host_integerp (max, 0))
- pp_wide_integer (cxx_pp, tree_low_cst (max, 0) + 1);
+ pp_wide_integer (pp, tree_low_cst (max, 0) + 1);
else
{
STRIP_NOPS (max);
@@ -864,11 +869,11 @@ dump_type_suffix (tree t, int flags)
max = fold_build2_loc (input_location,
PLUS_EXPR, dtype, max,
build_int_cst (dtype, 1));
- dump_expr (max, flags & ~TFF_EXPR_IN_PARENS);
+ dump_expr (pp, max, flags & ~TFF_EXPR_IN_PARENS);
}
}
- pp_cxx_right_bracket (cxx_pp);
- dump_type_suffix (TREE_TYPE (t), flags);
+ pp_cxx_right_bracket (pp);
+ dump_type_suffix (pp, TREE_TYPE (t), flags);
break;
case ENUMERAL_TYPE:
@@ -898,7 +903,7 @@ dump_type_suffix (tree t, int flags)
break;
default:
- pp_unsupported_tree (cxx_pp, t);
+ pp_unsupported_tree (pp, t);
case ERROR_MARK:
/* Don't mark it here, we should have already done in
dump_type_prefix. */
@@ -907,7 +912,7 @@ dump_type_suffix (tree t, int flags)
}
static void
-dump_global_iord (tree t)
+dump_global_iord (cxx_pretty_printer *pp, tree t)
{
const char *p = NULL;
@@ -918,51 +923,51 @@ dump_global_iord (tree t)
else
gcc_unreachable ();
- pp_printf (pp_base (cxx_pp), p, input_filename);
+ pp_printf (pp, p, input_filename);
}
static void
-dump_simple_decl (tree t, tree type, int flags)
+dump_simple_decl (cxx_pretty_printer *pp, tree t, tree type, int flags)
{
if (flags & TFF_DECL_SPECIFIERS)
{
if (VAR_P (t)
&& DECL_DECLARED_CONSTEXPR_P (t))
- pp_cxx_ws_string (cxx_pp, "constexpr");
- dump_type_prefix (type, flags & ~TFF_UNQUALIFIED_NAME);
- pp_maybe_space (cxx_pp);
+ pp_cxx_ws_string (pp, "constexpr");
+ dump_type_prefix (pp, type, flags & ~TFF_UNQUALIFIED_NAME);
+ pp_maybe_space (pp);
}
if (! (flags & TFF_UNQUALIFIED_NAME)
&& TREE_CODE (t) != PARM_DECL
&& (!DECL_INITIAL (t)
|| TREE_CODE (DECL_INITIAL (t)) != TEMPLATE_PARM_INDEX))
- dump_scope (CP_DECL_CONTEXT (t), flags);
+ dump_scope (pp, CP_DECL_CONTEXT (t), flags);
flags &= ~TFF_UNQUALIFIED_NAME;
if ((flags & TFF_DECL_SPECIFIERS)
&& DECL_TEMPLATE_PARM_P (t)
&& TEMPLATE_PARM_PARAMETER_PACK (DECL_INITIAL (t)))
- pp_string (cxx_pp, "...");
+ pp_string (pp, "...");
if (DECL_NAME (t))
{
if (TREE_CODE (t) == FIELD_DECL && DECL_NORMAL_CAPTURE_P (t))
{
- pp_character (cxx_pp, '<');
- pp_string (cxx_pp, IDENTIFIER_POINTER (DECL_NAME (t)) + 2);
- pp_string (cxx_pp, " capture>");
+ pp_less (pp);
+ pp_string (pp, IDENTIFIER_POINTER (DECL_NAME (t)) + 2);
+ pp_string (pp, " capture>");
}
else
- dump_decl (DECL_NAME (t), flags);
+ dump_decl (pp, DECL_NAME (t), flags);
}
else
- pp_string (cxx_pp, M_("<anonymous>"));
+ pp_string (pp, M_("<anonymous>"));
if (flags & TFF_DECL_SPECIFIERS)
- dump_type_suffix (type, flags);
+ dump_type_suffix (pp, type, flags);
}
/* Dump a human readable string for the decl T under control of FLAGS. */
static void
-dump_decl (tree t, int flags)
+dump_decl (cxx_pretty_printer *pp, tree t, int flags)
{
if (t == NULL_TREE)
return;
@@ -974,7 +979,7 @@ dump_decl (tree t, int flags)
const char *demangled = objc_maybe_printable_name (t, flags);
if (demangled)
{
- pp_string (cxx_pp, demangled);
+ pp_string (pp, demangled);
return;
}
}
@@ -989,32 +994,32 @@ dump_decl (tree t, int flags)
&& TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM)
{
/* Say `class T' not just `T'. */
- pp_cxx_ws_string (cxx_pp, "class");
+ pp_cxx_ws_string (pp, "class");
/* Emit the `...' for a parameter pack. */
if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
- pp_cxx_ws_string (cxx_pp, "...");
+ pp_cxx_ws_string (pp, "...");
}
- dump_type (TREE_TYPE (t), flags);
+ dump_type (pp, TREE_TYPE (t), flags);
break;
}
if (TYPE_DECL_ALIAS_P (t)
&& (flags & TFF_DECL_SPECIFIERS
|| flags & TFF_CLASS_KEY_OR_ENUM))
{
- pp_cxx_ws_string (cxx_pp, "using");
- dump_decl (DECL_NAME (t), flags);
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_ws_string (cxx_pp, "=");
- pp_cxx_whitespace (cxx_pp);
- dump_type (DECL_ORIGINAL_TYPE (t), flags);
+ pp_cxx_ws_string (pp, "using");
+ dump_decl (pp, DECL_NAME (t), flags);
+ pp_cxx_whitespace (pp);
+ pp_cxx_ws_string (pp, "=");
+ pp_cxx_whitespace (pp);
+ dump_type (pp, DECL_ORIGINAL_TYPE (t), flags);
break;
}
if ((flags & TFF_DECL_SPECIFIERS)
&& !DECL_SELF_REFERENCE_P (t))
- pp_cxx_ws_string (cxx_pp, "typedef");
- dump_simple_decl (t, DECL_ORIGINAL_TYPE (t)
+ pp_cxx_ws_string (pp, "typedef");
+ dump_simple_decl (pp, t, DECL_ORIGINAL_TYPE (t)
? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t),
flags);
break;
@@ -1022,78 +1027,78 @@ dump_decl (tree t, int flags)
case VAR_DECL:
if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t)))
{
- pp_string (cxx_pp, M_("vtable for "));
+ pp_string (pp, M_("vtable for "));
gcc_assert (TYPE_P (DECL_CONTEXT (t)));
- dump_type (DECL_CONTEXT (t), flags);
+ dump_type (pp, DECL_CONTEXT (t), flags);
break;
}
/* Else fall through. */
case FIELD_DECL:
case PARM_DECL:
- dump_simple_decl (t, TREE_TYPE (t), flags);
+ dump_simple_decl (pp, t, TREE_TYPE (t), flags);
break;
case RESULT_DECL:
- pp_string (cxx_pp, M_("<return value> "));
- dump_simple_decl (t, TREE_TYPE (t), flags);
+ pp_string (pp, M_("<return value> "));
+ dump_simple_decl (pp, t, TREE_TYPE (t), flags);
break;
case NAMESPACE_DECL:
if (flags & TFF_DECL_SPECIFIERS)
- pp_cxx_declaration (cxx_pp, t);
+ pp->declaration (t);
else
{
if (! (flags & TFF_UNQUALIFIED_NAME))
- dump_scope (CP_DECL_CONTEXT (t), flags);
+ dump_scope (pp, CP_DECL_CONTEXT (t), flags);
flags &= ~TFF_UNQUALIFIED_NAME;
if (DECL_NAME (t) == NULL_TREE)
{
- if (!(pp_c_base (cxx_pp)->flags & pp_c_flag_gnu_v3))
- pp_cxx_ws_string (cxx_pp, M_("{anonymous}"));
+ if (!(pp->flags & pp_c_flag_gnu_v3))
+ pp_cxx_ws_string (pp, M_("{anonymous}"));
else
- pp_cxx_ws_string (cxx_pp, M_("(anonymous namespace)"));
+ pp_cxx_ws_string (pp, M_("(anonymous namespace)"));
}
else
- pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
+ pp_cxx_tree_identifier (pp, DECL_NAME (t));
}
break;
case SCOPE_REF:
- dump_type (TREE_OPERAND (t, 0), flags);
- pp_string (cxx_pp, "::");
- dump_decl (TREE_OPERAND (t, 1), TFF_UNQUALIFIED_NAME);
+ dump_type (pp, TREE_OPERAND (t, 0), flags);
+ pp_colon_colon (pp);
+ dump_decl (pp, TREE_OPERAND (t, 1), TFF_UNQUALIFIED_NAME);
break;
case ARRAY_REF:
- dump_decl (TREE_OPERAND (t, 0), flags);
- pp_cxx_left_bracket (cxx_pp);
- dump_decl (TREE_OPERAND (t, 1), flags);
- pp_cxx_right_bracket (cxx_pp);
+ dump_decl (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_left_bracket (pp);
+ dump_decl (pp, TREE_OPERAND (t, 1), flags);
+ pp_cxx_right_bracket (pp);
break;
case ARRAY_NOTATION_REF:
- dump_decl (ARRAY_NOTATION_ARRAY (t), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_left_bracket (cxx_pp);
- dump_decl (ARRAY_NOTATION_START (t), flags | TFF_EXPR_IN_PARENS);
- pp_string (cxx_pp, ":");
- dump_decl (ARRAY_NOTATION_LENGTH (t), flags | TFF_EXPR_IN_PARENS);
- pp_string (cxx_pp, ":");
- dump_decl (ARRAY_NOTATION_STRIDE (t), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_right_bracket (cxx_pp);
+ dump_decl (pp, ARRAY_NOTATION_ARRAY (t), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_left_bracket (pp);
+ dump_decl (pp, ARRAY_NOTATION_START (t), flags | TFF_EXPR_IN_PARENS);
+ pp_colon (pp);
+ dump_decl (pp, ARRAY_NOTATION_LENGTH (t), flags | TFF_EXPR_IN_PARENS);
+ pp_colon (pp);
+ dump_decl (pp, ARRAY_NOTATION_STRIDE (t), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_bracket (pp);
break;
/* So that we can do dump_decl on an aggr type. */
case RECORD_TYPE:
case UNION_TYPE:
case ENUMERAL_TYPE:
- dump_type (t, flags);
+ dump_type (pp, t, flags);
break;
case BIT_NOT_EXPR:
/* This is a pseudo destructor call which has not been folded into
a PSEUDO_DTOR_EXPR yet. */
- pp_cxx_complement (cxx_pp);
- dump_type (TREE_OPERAND (t, 0), flags);
+ pp_cxx_complement (pp);
+ dump_type (pp, TREE_OPERAND (t, 0), flags);
break;
case TYPE_EXPR:
@@ -1105,13 +1110,13 @@ dump_decl (tree t, int flags)
case IDENTIFIER_NODE:
if (IDENTIFIER_TYPENAME_P (t))
{
- pp_cxx_ws_string (cxx_pp, "operator");
+ pp_cxx_ws_string (pp, "operator");
/* Not exactly IDENTIFIER_TYPE_VALUE. */
- dump_type (TREE_TYPE (t), flags);
+ dump_type (pp, TREE_TYPE (t), flags);
break;
}
else
- pp_cxx_tree_identifier (cxx_pp, t);
+ pp_cxx_tree_identifier (pp, t);
break;
case OVERLOAD:
@@ -1120,15 +1125,15 @@ dump_decl (tree t, int flags)
t = OVL_CURRENT (t);
if (DECL_CLASS_SCOPE_P (t))
{
- dump_type (DECL_CONTEXT (t), flags);
- pp_cxx_colon_colon (cxx_pp);
+ dump_type (pp, DECL_CONTEXT (t), flags);
+ pp_cxx_colon_colon (pp);
}
else if (!DECL_FILE_SCOPE_P (t))
{
- dump_decl (DECL_CONTEXT (t), flags);
- pp_cxx_colon_colon (cxx_pp);
+ dump_decl (pp, DECL_CONTEXT (t), flags);
+ pp_cxx_colon_colon (pp);
}
- dump_decl (DECL_NAME (t), flags);
+ dump_decl (pp, DECL_NAME (t), flags);
break;
}
@@ -1139,15 +1144,15 @@ dump_decl (tree t, int flags)
case FUNCTION_DECL:
if (! DECL_LANG_SPECIFIC (t))
- pp_string (cxx_pp, M_("<built-in>"));
+ pp_string (pp, M_("<built-in>"));
else if (DECL_GLOBAL_CTOR_P (t) || DECL_GLOBAL_DTOR_P (t))
- dump_global_iord (t);
+ dump_global_iord (pp, t);
else
- dump_function_decl (t, flags);
+ dump_function_decl (pp, t, flags);
break;
case TEMPLATE_DECL:
- dump_template_decl (t, flags);
+ dump_template_decl (pp, t, flags);
break;
case TEMPLATE_ID_EXPR:
@@ -1157,71 +1162,71 @@ dump_decl (tree t, int flags)
if (is_overloaded_fn (name))
name = DECL_NAME (get_first_fn (name));
- dump_decl (name, flags);
- pp_cxx_begin_template_argument_list (cxx_pp);
+ dump_decl (pp, name, flags);
+ pp_cxx_begin_template_argument_list (pp);
if (args == error_mark_node)
- pp_string (cxx_pp, M_("<template arguments error>"));
+ pp_string (pp, M_("<template arguments error>"));
else if (args)
- dump_template_argument_list (args, flags);
- pp_cxx_end_template_argument_list (cxx_pp);
+ dump_template_argument_list (pp, args, flags);
+ pp_cxx_end_template_argument_list (pp);
}
break;
case LABEL_DECL:
- pp_cxx_tree_identifier (cxx_pp, DECL_NAME (t));
+ pp_cxx_tree_identifier (pp, DECL_NAME (t));
break;
case CONST_DECL:
if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE)
|| (DECL_INITIAL (t) &&
TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX))
- dump_simple_decl (t, TREE_TYPE (t), flags);
+ dump_simple_decl (pp, t, TREE_TYPE (t), flags);
else if (DECL_NAME (t))
- dump_decl (DECL_NAME (t), flags);
+ dump_decl (pp, DECL_NAME (t), flags);
else if (DECL_INITIAL (t))
- dump_expr (DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, DECL_INITIAL (t), flags | TFF_EXPR_IN_PARENS);
else
- pp_string (cxx_pp, M_("<enumerator>"));
+ pp_string (pp, M_("<enumerator>"));
break;
case USING_DECL:
- pp_cxx_ws_string (cxx_pp, "using");
- dump_type (USING_DECL_SCOPE (t), flags);
- pp_cxx_colon_colon (cxx_pp);
- dump_decl (DECL_NAME (t), flags);
+ pp_cxx_ws_string (pp, "using");
+ dump_type (pp, USING_DECL_SCOPE (t), flags);
+ pp_cxx_colon_colon (pp);
+ dump_decl (pp, DECL_NAME (t), flags);
break;
case STATIC_ASSERT:
- pp_cxx_declaration (cxx_pp, t);
+ pp->declaration (t);
break;
case BASELINK:
- dump_decl (BASELINK_FUNCTIONS (t), flags);
+ dump_decl (pp, BASELINK_FUNCTIONS (t), flags);
break;
case NON_DEPENDENT_EXPR:
- dump_expr (t, flags);
+ dump_expr (pp, t, flags);
break;
case TEMPLATE_TYPE_PARM:
if (flags & TFF_DECL_SPECIFIERS)
- pp_cxx_declaration (cxx_pp, t);
+ pp->declaration (t);
else
- pp_type_id (cxx_pp, t);
+ pp->type_id (t);
break;
case UNBOUND_CLASS_TEMPLATE:
case TYPE_PACK_EXPANSION:
case TREE_BINFO:
- dump_type (t, flags);
+ dump_type (pp, t, flags);
break;
default:
- pp_unsupported_tree (cxx_pp, t);
+ pp_unsupported_tree (pp, t);
/* Fall through to error. */
case ERROR_MARK:
- pp_string (cxx_pp, M_("<declaration error>"));
+ pp_string (pp, M_("<declaration error>"));
break;
}
}
@@ -1230,7 +1235,7 @@ dump_decl (tree t, int flags)
'template <...> leaders plus the 'class X' or 'void fn(...)' part. */
static void
-dump_template_decl (tree t, int flags)
+dump_template_decl (cxx_pretty_printer *pp, tree t, int flags)
{
tree orig_parms = DECL_TEMPLATE_PARMS (t);
tree parms;
@@ -1245,8 +1250,8 @@ dump_template_decl (tree t, int flags)
tree inner_parms = INNERMOST_TEMPLATE_PARMS (parms);
int len = TREE_VEC_LENGTH (inner_parms);
- pp_cxx_ws_string (cxx_pp, "template");
- pp_cxx_begin_template_argument_list (cxx_pp);
+ pp_cxx_ws_string (pp, "template");
+ pp_cxx_begin_template_argument_list (pp);
/* If we've shown the template prefix, we'd better show the
parameters' and decl's type too. */
@@ -1255,34 +1260,35 @@ dump_template_decl (tree t, int flags)
for (i = 0; i < len; i++)
{
if (i)
- pp_separate_with_comma (cxx_pp);
- dump_template_parameter (TREE_VEC_ELT (inner_parms, i), flags);
+ pp_separate_with_comma (pp);
+ dump_template_parameter (pp, TREE_VEC_ELT (inner_parms, i),
+ flags);
}
- pp_cxx_end_template_argument_list (cxx_pp);
- pp_cxx_whitespace (cxx_pp);
+ pp_cxx_end_template_argument_list (pp);
+ pp_cxx_whitespace (pp);
}
nreverse(orig_parms);
if (DECL_TEMPLATE_TEMPLATE_PARM_P (t))
{
/* Say `template<arg> class TT' not just `template<arg> TT'. */
- pp_cxx_ws_string (cxx_pp, "class");
+ pp_cxx_ws_string (pp, "class");
/* If this is a parameter pack, print the ellipsis. */
if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t)))
- pp_cxx_ws_string (cxx_pp, "...");
+ pp_cxx_ws_string (pp, "...");
}
}
if (DECL_CLASS_TEMPLATE_P (t))
- dump_type (TREE_TYPE (t),
+ dump_type (pp, TREE_TYPE (t),
((flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
| (flags & TFF_DECL_SPECIFIERS ? TFF_CLASS_KEY_OR_ENUM : 0)));
else if (DECL_TEMPLATE_RESULT (t)
&& (VAR_P (DECL_TEMPLATE_RESULT (t))
/* Alias template. */
|| DECL_TYPE_TEMPLATE_P (t)))
- dump_decl (DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
+ dump_decl (pp, DECL_TEMPLATE_RESULT (t), flags | TFF_TEMPLATE_NAME);
else
{
gcc_assert (TREE_TYPE (t));
@@ -1290,11 +1296,11 @@ dump_template_decl (tree t, int flags)
{
case METHOD_TYPE:
case FUNCTION_TYPE:
- dump_function_decl (t, flags | TFF_TEMPLATE_NAME);
+ dump_function_decl (pp, t, flags | TFF_TEMPLATE_NAME);
break;
default:
/* This case can occur with some invalid code. */
- dump_type (TREE_TYPE (t),
+ dump_type (pp, TREE_TYPE (t),
(flags & ~TFF_CLASS_KEY_OR_ENUM) | TFF_TEMPLATE_NAME
| (flags & TFF_DECL_SPECIFIERS
? TFF_CLASS_KEY_OR_ENUM : 0));
@@ -1358,13 +1364,54 @@ find_typenames (tree t)
return ft.typenames;
}
+/* Output the "[with ...]" clause for a template instantiation T iff
+ TEMPLATE_PARMS, TEMPLATE_ARGS and FLAGS are suitable. T may be NULL if
+ formatting a deduction/substitution diagnostic rather than an
+ instantiation. */
+
+static void
+dump_substitution (cxx_pretty_printer *pp,
+ tree t, tree template_parms, tree template_args,
+ int flags)
+{
+ if (template_parms != NULL_TREE && template_args != NULL_TREE
+ && !(flags & TFF_NO_TEMPLATE_BINDINGS))
+ {
+ vec<tree, va_gc> *typenames = t ? find_typenames (t) : NULL;
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_bracket (pp);
+ pp->translate_string ("with");
+ pp_cxx_whitespace (pp);
+ dump_template_bindings (pp, template_parms, template_args, typenames);
+ pp_cxx_right_bracket (pp);
+ }
+}
+
+/* Dump the lambda function FN including its 'mutable' qualifier and any
+ template bindings. */
+
+static void
+dump_lambda_function (cxx_pretty_printer *pp,
+ tree fn, tree template_parms, tree template_args,
+ int flags)
+{
+ /* A lambda's signature is essentially its "type". */
+ dump_type (pp, DECL_CONTEXT (fn), flags);
+ if (!(TYPE_QUALS (class_of_this_parm (TREE_TYPE (fn))) & TYPE_QUAL_CONST))
+ {
+ pp->padding = pp_before;
+ pp_c_ws_string (pp, "mutable");
+ }
+ dump_substitution (pp, fn, template_parms, template_args, flags);
+}
+
/* Pretty print a function decl. There are several ways we want to print a
function declaration. The TFF_ bits in FLAGS tells us how to behave.
As error can only apply the '#' flag once to give 0 and 1 for V, there
is %D which doesn't print the throw specs, and %F which does. */
static void
-dump_function_decl (tree t, int flags)
+dump_function_decl (cxx_pretty_printer *pp, tree t, int flags)
{
tree fntype;
tree parmtypes;
@@ -1374,15 +1421,6 @@ dump_function_decl (tree t, int flags)
int show_return = flags & TFF_RETURN_TYPE || flags & TFF_DECL_SPECIFIERS;
int do_outer_scope = ! (flags & TFF_UNQUALIFIED_NAME);
tree exceptions;
- vec<tree, va_gc> *typenames = NULL;
-
- if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
- {
- /* A lambda's signature is essentially its "type", so defer. */
- gcc_assert (LAMBDA_TYPE_P (DECL_CONTEXT (t)));
- dump_type (DECL_CONTEXT (t), flags);
- return;
- }
flags &= ~(TFF_UNQUALIFIED_NAME | TFF_TEMPLATE_NAME);
if (TREE_CODE (t) == TEMPLATE_DECL)
@@ -1404,10 +1442,12 @@ dump_function_decl (tree t, int flags)
{
template_parms = DECL_TEMPLATE_PARMS (tmpl);
t = tmpl;
- typenames = find_typenames (t);
}
}
+ if (DECL_NAME (t) && LAMBDA_FUNCTION_P (t))
+ return dump_lambda_function (pp, t, template_parms, template_args, flags);
+
fntype = TREE_TYPE (t);
parmtypes = FUNCTION_FIRST_USER_PARMTYPE (t);
@@ -1420,12 +1460,12 @@ dump_function_decl (tree t, int flags)
if (flags & TFF_DECL_SPECIFIERS)
{
if (DECL_STATIC_FUNCTION_P (t))
- pp_cxx_ws_string (cxx_pp, "static");
+ pp_cxx_ws_string (pp, "static");
else if (DECL_VIRTUAL_P (t))
- pp_cxx_ws_string (cxx_pp, "virtual");
+ pp_cxx_ws_string (pp, "virtual");
if (DECL_DECLARED_CONSTEXPR_P (STRIP_TEMPLATE (t)))
- pp_cxx_ws_string (cxx_pp, "constexpr");
+ pp_cxx_ws_string (pp, "constexpr");
}
/* Print the return type? */
@@ -1435,7 +1475,7 @@ dump_function_decl (tree t, int flags)
if (show_return)
{
tree ret = fndecl_declared_return_type (t);
- dump_type_prefix (ret, flags);
+ dump_type_prefix (pp, ret, flags);
}
/* Print the function name. */
@@ -1443,65 +1483,55 @@ dump_function_decl (tree t, int flags)
/* Nothing. */;
else if (cname)
{
- dump_type (cname, flags);
- pp_cxx_colon_colon (cxx_pp);
+ dump_type (pp, cname, flags);
+ pp_cxx_colon_colon (pp);
}
else
- dump_scope (CP_DECL_CONTEXT (t), flags);
+ dump_scope (pp, CP_DECL_CONTEXT (t), flags);
- dump_function_name (t, flags);
+ dump_function_name (pp, t, flags);
if (!(flags & TFF_NO_FUNCTION_ARGUMENTS))
{
- dump_parameters (parmtypes, flags);
+ dump_parameters (pp, parmtypes, flags);
if (TREE_CODE (fntype) == METHOD_TYPE)
{
- pp_base (cxx_pp)->padding = pp_before;
- pp_cxx_cv_qualifier_seq (cxx_pp, class_of_this_parm (fntype));
- dump_ref_qualifier (fntype, flags);
+ pp->padding = pp_before;
+ pp_cxx_cv_qualifier_seq (pp, class_of_this_parm (fntype));
+ dump_ref_qualifier (pp, fntype, flags);
}
if (flags & TFF_EXCEPTION_SPECIFICATION)
{
- pp_base (cxx_pp)->padding = pp_before;
- dump_exception_spec (exceptions, flags);
+ pp->padding = pp_before;
+ dump_exception_spec (pp, exceptions, flags);
}
if (show_return)
- dump_type_suffix (TREE_TYPE (fntype), flags);
+ dump_type_suffix (pp, TREE_TYPE (fntype), flags);
- /* If T is a template instantiation, dump the parameter binding. */
- if (template_parms != NULL_TREE && template_args != NULL_TREE
- && !(flags & TFF_NO_TEMPLATE_BINDINGS))
- {
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_bracket (cxx_pp);
- pp_cxx_ws_string (cxx_pp, M_("with"));
- pp_cxx_whitespace (cxx_pp);
- dump_template_bindings (template_parms, template_args, typenames);
- pp_cxx_right_bracket (cxx_pp);
- }
+ dump_substitution (pp, t, template_parms, template_args, flags);
}
else if (template_args)
{
bool need_comma = false;
int i;
- pp_cxx_begin_template_argument_list (cxx_pp);
+ pp_cxx_begin_template_argument_list (pp);
template_args = INNERMOST_TEMPLATE_ARGS (template_args);
for (i = 0; i < TREE_VEC_LENGTH (template_args); ++i)
{
tree arg = TREE_VEC_ELT (template_args, i);
if (need_comma)
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
if (ARGUMENT_PACK_P (arg))
- pp_cxx_left_brace (cxx_pp);
- dump_template_argument (arg, TFF_PLAIN_IDENTIFIER);
+ pp_cxx_left_brace (pp);
+ dump_template_argument (pp, arg, TFF_PLAIN_IDENTIFIER);
if (ARGUMENT_PACK_P (arg))
- pp_cxx_right_brace (cxx_pp);
+ pp_cxx_right_brace (pp);
need_comma = true;
}
- pp_cxx_end_template_argument_list (cxx_pp);
+ pp_cxx_end_template_argument_list (pp);
}
}
@@ -1510,84 +1540,84 @@ dump_function_decl (tree t, int flags)
already been removed. */
static void
-dump_parameters (tree parmtypes, int flags)
+dump_parameters (cxx_pretty_printer *pp, tree parmtypes, int flags)
{
int first = 1;
flags &= ~TFF_SCOPE;
- pp_cxx_left_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
for (first = 1; parmtypes != void_list_node;
parmtypes = TREE_CHAIN (parmtypes))
{
if (!first)
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
first = 0;
if (!parmtypes)
{
- pp_cxx_ws_string (cxx_pp, "...");
+ pp_cxx_ws_string (pp, "...");
break;
}
- dump_type (TREE_VALUE (parmtypes), flags);
+ dump_type (pp, TREE_VALUE (parmtypes), flags);
if ((flags & TFF_FUNCTION_DEFAULT_ARGUMENTS) && TREE_PURPOSE (parmtypes))
{
- pp_cxx_whitespace (cxx_pp);
- pp_equal (cxx_pp);
- pp_cxx_whitespace (cxx_pp);
- dump_expr (TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_whitespace (pp);
+ pp_equal (pp);
+ pp_cxx_whitespace (pp);
+ dump_expr (pp, TREE_PURPOSE (parmtypes), flags | TFF_EXPR_IN_PARENS);
}
}
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
}
/* Print ref-qualifier of a FUNCTION_TYPE or METHOD_TYPE. FLAGS are ignored. */
static void
-dump_ref_qualifier (tree t, int flags ATTRIBUTE_UNUSED)
+dump_ref_qualifier (cxx_pretty_printer *pp, tree t, int flags ATTRIBUTE_UNUSED)
{
if (FUNCTION_REF_QUALIFIED (t))
{
- pp_base (cxx_pp)->padding = pp_before;
+ pp->padding = pp_before;
if (FUNCTION_RVALUE_QUALIFIED (t))
- pp_cxx_ws_string (cxx_pp, "&&");
+ pp_cxx_ws_string (pp, "&&");
else
- pp_cxx_ws_string (cxx_pp, "&");
+ pp_cxx_ws_string (pp, "&");
}
}
/* Print an exception specification. T is the exception specification. */
static void
-dump_exception_spec (tree t, int flags)
+dump_exception_spec (cxx_pretty_printer *pp, tree t, int flags)
{
if (t && TREE_PURPOSE (t))
{
- pp_cxx_ws_string (cxx_pp, "noexcept");
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
+ pp_cxx_ws_string (pp, "noexcept");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
if (DEFERRED_NOEXCEPT_SPEC_P (t))
- pp_cxx_ws_string (cxx_pp, "<uninstantiated>");
+ pp_cxx_ws_string (pp, "<uninstantiated>");
else
- dump_expr (TREE_PURPOSE (t), flags);
- pp_cxx_right_paren (cxx_pp);
+ dump_expr (pp, TREE_PURPOSE (t), flags);
+ pp_cxx_right_paren (pp);
}
else if (t)
{
- pp_cxx_ws_string (cxx_pp, "throw");
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
+ pp_cxx_ws_string (pp, "throw");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
if (TREE_VALUE (t) != NULL_TREE)
while (1)
{
- dump_type (TREE_VALUE (t), flags);
+ dump_type (pp, TREE_VALUE (t), flags);
t = TREE_CHAIN (t);
if (!t)
break;
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
}
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
}
}
@@ -1595,7 +1625,7 @@ dump_exception_spec (tree t, int flags)
and destructors properly. */
static void
-dump_function_name (tree t, int flags)
+dump_function_name (cxx_pretty_printer *pp, tree t, int flags)
{
tree name = DECL_NAME (t);
@@ -1606,7 +1636,7 @@ dump_function_name (tree t, int flags)
literal name. */
if (!DECL_LANG_SPECIFIC (t))
{
- pp_cxx_tree_identifier (cxx_pp, name);
+ pp_cxx_tree_identifier (pp, name);
return;
}
@@ -1627,8 +1657,8 @@ dump_function_name (tree t, int flags)
if (DECL_DESTRUCTOR_P (t))
{
- pp_cxx_complement (cxx_pp);
- dump_decl (name, TFF_PLAIN_IDENTIFIER);
+ pp_cxx_complement (pp);
+ dump_decl (pp, name, TFF_PLAIN_IDENTIFIER);
}
else if (DECL_CONV_FN_P (t))
{
@@ -1638,21 +1668,22 @@ dump_function_name (tree t, int flags)
declarations, both will have the same name, yet
the types will be different, hence the TREE_TYPE field
of the first name will be clobbered by the second. */
- pp_cxx_ws_string (cxx_pp, "operator");
- dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
+ pp_cxx_ws_string (pp, "operator");
+ dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
}
else if (name && IDENTIFIER_OPNAME_P (name))
- pp_cxx_tree_identifier (cxx_pp, name);
+ pp_cxx_tree_identifier (pp, name);
else if (name && UDLIT_OPER_P (name))
- pp_cxx_tree_identifier (cxx_pp, name);
+ pp_cxx_tree_identifier (pp, name);
else
- dump_decl (name, flags);
+ dump_decl (pp, name, flags);
if (DECL_TEMPLATE_INFO (t)
&& !DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (t)
&& (TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL
|| PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t))))
- dump_template_parms (DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t), flags);
+ dump_template_parms (pp, DECL_TEMPLATE_INFO (t), !DECL_USE_TEMPLATE (t),
+ flags);
}
/* Dump the template parameters from the template info INFO under control of
@@ -1662,14 +1693,15 @@ dump_function_name (tree t, int flags)
decoration. */
static void
-dump_template_parms (tree info, int primary, int flags)
+dump_template_parms (cxx_pretty_printer *pp, tree info,
+ int primary, int flags)
{
tree args = info ? TI_ARGS (info) : NULL_TREE;
if (primary && flags & TFF_TEMPLATE_NAME)
return;
flags &= ~(TFF_CLASS_KEY_OR_ENUM | TFF_TEMPLATE_NAME);
- pp_cxx_begin_template_argument_list (cxx_pp);
+ pp_cxx_begin_template_argument_list (pp);
/* Be careful only to print things when we have them, so as not
to crash producing error messages. */
@@ -1689,12 +1721,12 @@ dump_template_parms (tree info, int primary, int flags)
if (ix
&& (!ARGUMENT_PACK_P (arg)
|| TREE_VEC_LENGTH (ARGUMENT_PACK_ARGS (arg)) > 0))
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
if (!arg)
- pp_string (cxx_pp, M_("<template parameter error>"));
+ pp_string (pp, M_("<template parameter error>"));
else
- dump_template_argument (arg, flags);
+ dump_template_argument (pp, arg, flags);
}
}
else if (primary)
@@ -1712,43 +1744,43 @@ dump_template_parms (tree info, int primary, int flags)
if (TREE_VEC_ELT (parms, ix) == error_mark_node)
{
- pp_string (cxx_pp, M_("<template parameter error>"));
+ pp_string (pp, M_("<template parameter error>"));
continue;
}
parm = TREE_VALUE (TREE_VEC_ELT (parms, ix));
if (ix)
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
- dump_decl (parm, flags & ~TFF_DECL_SPECIFIERS);
+ dump_decl (pp, parm, flags & ~TFF_DECL_SPECIFIERS);
}
}
- pp_cxx_end_template_argument_list (cxx_pp);
+ pp_cxx_end_template_argument_list (pp);
}
/* Print out the arguments of CALL_EXPR T as a parenthesized list using
flags FLAGS. Skip over the first argument if SKIPFIRST is true. */
static void
-dump_call_expr_args (tree t, int flags, bool skipfirst)
+dump_call_expr_args (cxx_pretty_printer *pp, tree t, int flags, bool skipfirst)
{
tree arg;
call_expr_arg_iterator iter;
- pp_cxx_left_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
FOR_EACH_CALL_EXPR_ARG (arg, iter, t)
{
if (skipfirst)
skipfirst = false;
else
{
- dump_expr (arg, flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
if (more_call_expr_args_p (&iter))
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
}
}
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
}
/* Print out the arguments of AGGR_INIT_EXPR T as a parenthesized list
@@ -1756,53 +1788,55 @@ dump_call_expr_args (tree t, int flags, bool skipfirst)
true. */
static void
-dump_aggr_init_expr_args (tree t, int flags, bool skipfirst)
+dump_aggr_init_expr_args (cxx_pretty_printer *pp, tree t, int flags,
+ bool skipfirst)
{
tree arg;
aggr_init_expr_arg_iterator iter;
- pp_cxx_left_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
FOR_EACH_AGGR_INIT_EXPR_ARG (arg, iter, t)
{
if (skipfirst)
skipfirst = false;
else
{
- dump_expr (arg, flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, arg, flags | TFF_EXPR_IN_PARENS);
if (more_aggr_init_expr_args_p (&iter))
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
}
}
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
}
/* Print out a list of initializers (subr of dump_expr). */
static void
-dump_expr_list (tree l, int flags)
+dump_expr_list (cxx_pretty_printer *pp, tree l, int flags)
{
while (l)
{
- dump_expr (TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, TREE_VALUE (l), flags | TFF_EXPR_IN_PARENS);
l = TREE_CHAIN (l);
if (l)
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
}
}
/* Print out a vector of initializers (subr of dump_expr). */
static void
-dump_expr_init_vec (vec<constructor_elt, va_gc> *v, int flags)
+dump_expr_init_vec (cxx_pretty_printer *pp, vec<constructor_elt, va_gc> *v,
+ int flags)
{
unsigned HOST_WIDE_INT idx;
tree value;
FOR_EACH_CONSTRUCTOR_VALUE (v, idx, value)
{
- dump_expr (value, flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, value, flags | TFF_EXPR_IN_PARENS);
if (idx != v->length () - 1)
- pp_separate_with_comma (cxx_pp);
+ pp_separate_with_comma (pp);
}
}
@@ -1831,7 +1865,7 @@ resolve_virtual_fun_from_obj_type_ref (tree ref)
/* Print out an expression E under control of FLAGS. */
static void
-dump_expr (tree t, int flags)
+dump_expr (cxx_pretty_printer *pp, tree t, int flags)
{
tree op;
@@ -1840,7 +1874,7 @@ dump_expr (tree t, int flags)
if (STATEMENT_CLASS_P (t))
{
- pp_cxx_ws_string (cxx_pp, M_("<statement>"));
+ pp_cxx_ws_string (pp, M_("<statement>"));
return;
}
@@ -1857,70 +1891,70 @@ dump_expr (tree t, int flags)
case OVERLOAD:
case TYPE_DECL:
case IDENTIFIER_NODE:
- dump_decl (t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
- |TFF_TEMPLATE_HEADER))
- | TFF_NO_FUNCTION_ARGUMENTS));
+ dump_decl (pp, t, ((flags & ~(TFF_DECL_SPECIFIERS|TFF_RETURN_TYPE
+ |TFF_TEMPLATE_HEADER))
+ | TFF_NO_FUNCTION_ARGUMENTS));
break;
case SSA_NAME:
if (SSA_NAME_VAR (t)
&& !DECL_ARTIFICIAL (SSA_NAME_VAR (t)))
- dump_expr (SSA_NAME_VAR (t), flags);
+ dump_expr (pp, SSA_NAME_VAR (t), flags);
else
- pp_cxx_ws_string (cxx_pp, M_("<unknown>"));
+ pp_cxx_ws_string (pp, M_("<unknown>"));
break;
case INTEGER_CST:
case REAL_CST:
case STRING_CST:
case COMPLEX_CST:
- pp_constant (cxx_pp, t);
+ pp->constant (t);
break;
case USERDEF_LITERAL:
- pp_cxx_userdef_literal (cxx_pp, t);
+ pp_cxx_userdef_literal (pp, t);
break;
case THROW_EXPR:
/* While waiting for caret diagnostics, avoid printing
__cxa_allocate_exception, __cxa_throw, and the like. */
- pp_cxx_ws_string (cxx_pp, M_("<throw-expression>"));
+ pp_cxx_ws_string (pp, M_("<throw-expression>"));
break;
case PTRMEM_CST:
- pp_ampersand (cxx_pp);
- dump_type (PTRMEM_CST_CLASS (t), flags);
- pp_cxx_colon_colon (cxx_pp);
- pp_cxx_tree_identifier (cxx_pp, DECL_NAME (PTRMEM_CST_MEMBER (t)));
+ pp_ampersand (pp);
+ dump_type (pp, PTRMEM_CST_CLASS (t), flags);
+ pp_cxx_colon_colon (pp);
+ pp_cxx_tree_identifier (pp, DECL_NAME (PTRMEM_CST_MEMBER (t)));
break;
case COMPOUND_EXPR:
- pp_cxx_left_paren (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- pp_separate_with_comma (cxx_pp);
- dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_separate_with_comma (pp);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
break;
case COND_EXPR:
- pp_cxx_left_paren (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- pp_string (cxx_pp, " ? ");
- dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
- pp_string (cxx_pp, " : ");
- dump_expr (TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_string (pp, " ? ");
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ pp_string (pp, " : ");
+ dump_expr (pp, TREE_OPERAND (t, 2), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
break;
case SAVE_EXPR:
if (TREE_HAS_CONSTRUCTOR (t))
{
- pp_cxx_ws_string (cxx_pp, "new");
- pp_cxx_whitespace (cxx_pp);
- dump_type (TREE_TYPE (TREE_TYPE (t)), flags);
+ pp_cxx_ws_string (pp, "new");
+ pp_cxx_whitespace (pp);
+ dump_type (pp, TREE_TYPE (TREE_TYPE (t)), flags);
}
else
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
break;
case AGGR_INIT_EXPR:
@@ -1933,14 +1967,14 @@ dump_expr (tree t, int flags)
if (fn && TREE_CODE (fn) == FUNCTION_DECL)
{
if (DECL_CONSTRUCTOR_P (fn))
- dump_type (DECL_CONTEXT (fn), flags);
+ dump_type (pp, DECL_CONTEXT (fn), flags);
else
- dump_decl (fn, 0);
+ dump_decl (pp, fn, 0);
}
else
- dump_expr (AGGR_INIT_EXPR_FN (t), 0);
+ dump_expr (pp, AGGR_INIT_EXPR_FN (t), 0);
}
- dump_aggr_init_expr_args (t, flags, true);
+ dump_aggr_init_expr_args (pp, t, flags, true);
break;
case CALL_EXPR:
@@ -1962,19 +1996,26 @@ dump_expr (tree t, int flags)
tree ob = CALL_EXPR_ARG (t, 0);
if (TREE_CODE (ob) == ADDR_EXPR)
{
- dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_dot (cxx_pp);
+ dump_expr (pp, TREE_OPERAND (ob, 0),
+ flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_dot (pp);
}
else if (TREE_CODE (ob) != PARM_DECL
|| strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
{
- dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
- pp_cxx_arrow (cxx_pp);
+ dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_arrow (pp);
}
skipfirst = true;
}
- dump_expr (fn, flags | TFF_EXPR_IN_PARENS);
- dump_call_expr_args (t, flags, skipfirst);
+ if (flag_sanitize & SANITIZE_UNDEFINED
+ && is_ubsan_builtin_p (fn))
+ {
+ pp_string (cxx_pp, M_("<ubsan routine call>"));
+ break;
+ }
+ dump_expr (pp, fn, flags | TFF_EXPR_IN_PARENS);
+ dump_call_expr_args (pp, t, flags, skipfirst);
}
break;
@@ -1985,16 +2026,16 @@ dump_expr (tree t, int flags)
default argument. Note we may have cleared out the first
operand in expand_expr, so don't go killing ourselves. */
if (TREE_OPERAND (t, 1))
- dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
break;
case POINTER_PLUS_EXPR:
- dump_binary_op ("+", t, flags);
+ dump_binary_op (pp, "+", t, flags);
break;
case INIT_EXPR:
case MODIFY_EXPR:
- dump_binary_op (assignment_operator_name_info[(int)NOP_EXPR].name,
+ dump_binary_op (pp, assignment_operator_name_info[NOP_EXPR].name,
t, flags);
break;
@@ -2019,20 +2060,20 @@ dump_expr (tree t, int flags)
case EQ_EXPR:
case NE_EXPR:
case EXACT_DIV_EXPR:
- dump_binary_op (operator_name_info[(int) TREE_CODE (t)].name, t, flags);
+ dump_binary_op (pp, operator_name_info[TREE_CODE (t)].name, t, flags);
break;
case CEIL_DIV_EXPR:
case FLOOR_DIV_EXPR:
case ROUND_DIV_EXPR:
case RDIV_EXPR:
- dump_binary_op ("/", t, flags);
+ dump_binary_op (pp, "/", t, flags);
break;
case CEIL_MOD_EXPR:
case FLOOR_MOD_EXPR:
case ROUND_MOD_EXPR:
- dump_binary_op ("%", t, flags);
+ dump_binary_op (pp, "%", t, flags);
break;
case COMPONENT_REF:
@@ -2045,42 +2086,42 @@ dump_expr (tree t, int flags)
|| (DECL_NAME (ob)
&& strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")))
{
- dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
if (TREE_CODE (TREE_TYPE (ob)) == REFERENCE_TYPE)
- pp_cxx_dot (cxx_pp);
+ pp_cxx_dot (pp);
else
- pp_cxx_arrow (cxx_pp);
+ pp_cxx_arrow (pp);
}
}
else
{
- dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
- pp_cxx_dot (cxx_pp);
+ dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_dot (pp);
}
- dump_expr (TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags & ~TFF_EXPR_IN_PARENS);
}
break;
case ARRAY_REF:
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_left_bracket (cxx_pp);
- dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_right_bracket (cxx_pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_left_bracket (pp);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_bracket (pp);
break;
case ARRAY_NOTATION_REF:
- dump_expr (ARRAY_NOTATION_ARRAY (t), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_left_bracket (cxx_pp);
- dump_expr (ARRAY_NOTATION_START (t), flags | TFF_EXPR_IN_PARENS);
- pp_string (cxx_pp, ":");
- dump_expr (ARRAY_NOTATION_LENGTH (t), flags | TFF_EXPR_IN_PARENS);
- pp_string (cxx_pp, ":");
- dump_expr (ARRAY_NOTATION_STRIDE (t), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_right_bracket (cxx_pp);
+ dump_expr (pp, ARRAY_NOTATION_ARRAY (t), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_left_bracket (pp);
+ dump_expr (pp, ARRAY_NOTATION_START (t), flags | TFF_EXPR_IN_PARENS);
+ pp_colon (pp);
+ dump_expr (pp, ARRAY_NOTATION_LENGTH (t), flags | TFF_EXPR_IN_PARENS);
+ pp_colon (pp);
+ dump_expr (pp, ARRAY_NOTATION_STRIDE (t), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_bracket (pp);
break;
case UNARY_PLUS_EXPR:
- dump_unary_op ("+", t, flags);
+ dump_unary_op (pp, "+", t, flags);
break;
case ADDR_EXPR:
@@ -2091,11 +2132,11 @@ dump_expr (tree t, int flags)
that the expression has pointer type. */
|| (TREE_TYPE (t)
&& TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE))
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
else if (TREE_CODE (TREE_OPERAND (t, 0)) == LABEL_DECL)
- dump_unary_op ("&&", t, flags);
+ dump_unary_op (pp, "&&", t, flags);
else
- dump_unary_op ("&", t, flags);
+ dump_unary_op (pp, "&", t, flags);
break;
case INDIRECT_REF:
@@ -2103,44 +2144,45 @@ dump_expr (tree t, int flags)
{
t = TREE_OPERAND (t, 0);
gcc_assert (TREE_CODE (t) == CALL_EXPR);
- dump_expr (CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
- dump_call_expr_args (t, flags, true);
+ dump_expr (pp, CALL_EXPR_FN (t), flags | TFF_EXPR_IN_PARENS);
+ dump_call_expr_args (pp, t, flags, true);
}
else
{
if (TREE_OPERAND (t,0) != NULL_TREE
&& TREE_TYPE (TREE_OPERAND (t, 0))
&& NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE)
- dump_expr (TREE_OPERAND (t, 0), flags);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
else
- dump_unary_op ("*", t, flags);
+ dump_unary_op (pp, "*", t, flags);
}
break;
case MEM_REF:
if (TREE_CODE (TREE_OPERAND (t, 0)) == ADDR_EXPR
&& integer_zerop (TREE_OPERAND (t, 1)))
- dump_expr (TREE_OPERAND (TREE_OPERAND (t, 0), 0), flags);
+ dump_expr (pp, TREE_OPERAND (TREE_OPERAND (t, 0), 0), flags);
else
{
- pp_cxx_star (cxx_pp);
+ pp_cxx_star (pp);
if (!integer_zerop (TREE_OPERAND (t, 1)))
{
- pp_cxx_left_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
if (!integer_onep (TYPE_SIZE_UNIT
(TREE_TYPE (TREE_TYPE (TREE_OPERAND (t, 0))))))
{
- pp_cxx_left_paren (cxx_pp);
- dump_type (ptr_type_node, flags);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, ptr_type_node, flags);
+ pp_cxx_right_paren (pp);
}
}
- dump_expr (TREE_OPERAND (t, 0), flags);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
if (!integer_zerop (TREE_OPERAND (t, 1)))
{
- pp_cxx_ws_string (cxx_pp, "+");
- dump_expr (fold_convert (ssizetype, TREE_OPERAND (t, 1)), flags);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_ws_string (pp, "+");
+ dump_expr (pp, fold_convert (ssizetype, TREE_OPERAND (t, 1)),
+ flags);
+ pp_cxx_right_paren (pp);
}
}
break;
@@ -2150,15 +2192,15 @@ dump_expr (tree t, int flags)
case TRUTH_NOT_EXPR:
case PREDECREMENT_EXPR:
case PREINCREMENT_EXPR:
- dump_unary_op (operator_name_info [(int)TREE_CODE (t)].name, t, flags);
+ dump_unary_op (pp, operator_name_info [TREE_CODE (t)].name, t, flags);
break;
case POSTDECREMENT_EXPR:
case POSTINCREMENT_EXPR:
- pp_cxx_left_paren (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_ws_string (cxx_pp, operator_name_info[(int)TREE_CODE (t)].name);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_ws_string (pp, operator_name_info[TREE_CODE (t)].name);
+ pp_cxx_right_paren (pp);
break;
case NON_LVALUE_EXPR:
@@ -2175,16 +2217,16 @@ dump_expr (tree t, int flags)
if (TREE_CODE (next) == FUNCTION_TYPE)
{
if (flags & TFF_EXPR_IN_PARENS)
- pp_cxx_left_paren (cxx_pp);
- pp_cxx_star (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_left_paren (pp);
+ pp_cxx_star (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
if (flags & TFF_EXPR_IN_PARENS)
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
break;
}
/* Else fall through. */
}
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
break;
CASE_CONVERT:
@@ -2202,25 +2244,25 @@ dump_expr (tree t, int flags)
TREE_TYPE (ttype)))
{
if (TREE_CODE (ttype) == REFERENCE_TYPE)
- dump_unary_op ("*", t, flags);
+ dump_unary_op (pp, "*", t, flags);
else
- dump_unary_op ("&", t, flags);
+ dump_unary_op (pp, "&", t, flags);
}
else if (!same_type_p (TREE_TYPE (op), TREE_TYPE (t)))
{
/* It is a cast, but we cannot tell whether it is a
reinterpret or static cast. Use the C style notation. */
if (flags & TFF_EXPR_IN_PARENS)
- pp_cxx_left_paren (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_type (TREE_TYPE (t), flags);
- pp_cxx_right_paren (cxx_pp);
- dump_expr (op, flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_left_paren (pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_right_paren (pp);
+ dump_expr (pp, op, flags | TFF_EXPR_IN_PARENS);
if (flags & TFF_EXPR_IN_PARENS)
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
}
else
- dump_expr (op, flags);
+ dump_expr (pp, op, flags);
break;
}
@@ -2232,12 +2274,12 @@ dump_expr (tree t, int flags)
if (integer_zerop (idx))
{
/* A NULL pointer-to-member constant. */
- pp_cxx_left_paren (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_type (TREE_TYPE (t), flags);
- pp_cxx_right_paren (cxx_pp);
- pp_character (cxx_pp, '0');
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_right_paren (pp);
+ pp_character (pp, '0');
+ pp_cxx_right_paren (pp);
break;
}
else if (host_integerp (idx, 0))
@@ -2262,27 +2304,27 @@ dump_expr (tree t, int flags)
}
if (virtuals)
{
- dump_expr (BV_FN (virtuals),
+ dump_expr (pp, BV_FN (virtuals),
flags | TFF_EXPR_IN_PARENS);
break;
}
}
}
if (TREE_TYPE (t) && LAMBDA_TYPE_P (TREE_TYPE (t)))
- pp_string (cxx_pp, "<lambda closure object>");
+ pp_string (pp, "<lambda closure object>");
if (TREE_TYPE (t) && EMPTY_CONSTRUCTOR_P (t))
{
- dump_type (TREE_TYPE (t), 0);
- pp_cxx_left_paren (cxx_pp);
- pp_cxx_right_paren (cxx_pp);
+ dump_type (pp, TREE_TYPE (t), 0);
+ pp_cxx_left_paren (pp);
+ pp_cxx_right_paren (pp);
}
else
{
if (!BRACE_ENCLOSED_INITIALIZER_P (t))
- dump_type (TREE_TYPE (t), 0);
- pp_cxx_left_brace (cxx_pp);
- dump_expr_init_vec (CONSTRUCTOR_ELTS (t), flags);
- pp_cxx_right_brace (cxx_pp);
+ dump_type (pp, TREE_TYPE (t), 0);
+ pp_cxx_left_brace (pp);
+ dump_expr_init_vec (pp, CONSTRUCTOR_ELTS (t), flags);
+ pp_cxx_right_brace (pp);
}
break;
@@ -2295,151 +2337,151 @@ dump_expr (tree t, int flags)
t = TREE_OPERAND (t, 1);
if (TREE_CODE (t) == FUNCTION_DECL)
/* A::f */
- dump_expr (t, flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, t, flags | TFF_EXPR_IN_PARENS);
else if (BASELINK_P (t))
- dump_expr (OVL_CURRENT (BASELINK_FUNCTIONS (t)),
+ dump_expr (pp, OVL_CURRENT (BASELINK_FUNCTIONS (t)),
flags | TFF_EXPR_IN_PARENS);
else
- dump_decl (t, flags);
+ dump_decl (pp, t, flags);
}
else
{
if (INDIRECT_REF_P (ob))
{
- dump_expr (TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_arrow (cxx_pp);
- pp_cxx_star (cxx_pp);
+ dump_expr (pp, TREE_OPERAND (ob, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_arrow (pp);
+ pp_cxx_star (pp);
}
else
{
- dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
- pp_cxx_dot (cxx_pp);
- pp_cxx_star (cxx_pp);
+ dump_expr (pp, ob, flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_dot (pp);
+ pp_cxx_star (pp);
}
- dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
}
break;
}
case TEMPLATE_PARM_INDEX:
- dump_decl (TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
+ dump_decl (pp, TEMPLATE_PARM_DECL (t), flags & ~TFF_DECL_SPECIFIERS);
break;
case CAST_EXPR:
if (TREE_OPERAND (t, 0) == NULL_TREE
|| TREE_CHAIN (TREE_OPERAND (t, 0)))
{
- dump_type (TREE_TYPE (t), flags);
- pp_cxx_left_paren (cxx_pp);
- dump_expr_list (TREE_OPERAND (t, 0), flags);
- pp_cxx_right_paren (cxx_pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_left_paren (pp);
+ dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
}
else
{
- pp_cxx_left_paren (cxx_pp);
- dump_type (TREE_TYPE (t), flags);
- pp_cxx_right_paren (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_expr_list (TREE_OPERAND (t, 0), flags);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_right_paren (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr_list (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
}
break;
case STATIC_CAST_EXPR:
- pp_cxx_ws_string (cxx_pp, "static_cast");
+ pp_cxx_ws_string (pp, "static_cast");
goto cast;
case REINTERPRET_CAST_EXPR:
- pp_cxx_ws_string (cxx_pp, "reinterpret_cast");
+ pp_cxx_ws_string (pp, "reinterpret_cast");
goto cast;
case CONST_CAST_EXPR:
- pp_cxx_ws_string (cxx_pp, "const_cast");
+ pp_cxx_ws_string (pp, "const_cast");
goto cast;
case DYNAMIC_CAST_EXPR:
- pp_cxx_ws_string (cxx_pp, "dynamic_cast");
+ pp_cxx_ws_string (pp, "dynamic_cast");
cast:
- pp_cxx_begin_template_argument_list (cxx_pp);
- dump_type (TREE_TYPE (t), flags);
- pp_cxx_end_template_argument_list (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_begin_template_argument_list (pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_end_template_argument_list (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
break;
case ARROW_EXPR:
- dump_expr (TREE_OPERAND (t, 0), flags);
- pp_cxx_arrow (cxx_pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_arrow (pp);
break;
case SIZEOF_EXPR:
case ALIGNOF_EXPR:
if (TREE_CODE (t) == SIZEOF_EXPR)
- pp_cxx_ws_string (cxx_pp, "sizeof");
+ pp_cxx_ws_string (pp, "sizeof");
else
{
gcc_assert (TREE_CODE (t) == ALIGNOF_EXPR);
- pp_cxx_ws_string (cxx_pp, "__alignof__");
+ pp_cxx_ws_string (pp, "__alignof__");
}
op = TREE_OPERAND (t, 0);
if (PACK_EXPANSION_P (op))
{
- pp_string (cxx_pp, "...");
+ pp_string (pp, "...");
op = PACK_EXPANSION_PATTERN (op);
}
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
if (TREE_CODE (t) == SIZEOF_EXPR && SIZEOF_EXPR_TYPE_P (t))
- dump_type (TREE_TYPE (op), flags);
+ dump_type (pp, TREE_TYPE (op), flags);
else if (TYPE_P (TREE_OPERAND (t, 0)))
- dump_type (op, flags);
+ dump_type (pp, op, flags);
else
- dump_expr (op, flags);
- pp_cxx_right_paren (cxx_pp);
+ dump_expr (pp, op, flags);
+ pp_cxx_right_paren (pp);
break;
case AT_ENCODE_EXPR:
- pp_cxx_ws_string (cxx_pp, "@encode");
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_type (TREE_OPERAND (t, 0), flags);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_ws_string (pp, "@encode");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_type (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
break;
case NOEXCEPT_EXPR:
- pp_cxx_ws_string (cxx_pp, "noexcept");
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_paren (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_ws_string (pp, "noexcept");
+ pp_cxx_whitespace (pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_right_paren (pp);
break;
case REALPART_EXPR:
case IMAGPART_EXPR:
- pp_cxx_ws_string (cxx_pp, operator_name_info[TREE_CODE (t)].name);
- pp_cxx_whitespace (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags);
+ pp_cxx_ws_string (pp, operator_name_info[TREE_CODE (t)].name);
+ pp_cxx_whitespace (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
break;
case DEFAULT_ARG:
- pp_string (cxx_pp, M_("<unparsed>"));
+ pp_string (pp, M_("<unparsed>"));
break;
case TRY_CATCH_EXPR:
case WITH_CLEANUP_EXPR:
case CLEANUP_POINT_EXPR:
- dump_expr (TREE_OPERAND (t, 0), flags);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
break;
case PSEUDO_DTOR_EXPR:
- dump_expr (TREE_OPERAND (t, 2), flags);
- pp_cxx_dot (cxx_pp);
- dump_type (TREE_OPERAND (t, 0), flags);
- pp_cxx_colon_colon (cxx_pp);
- pp_cxx_complement (cxx_pp);
- dump_type (TREE_OPERAND (t, 1), flags);
+ dump_expr (pp, TREE_OPERAND (t, 2), flags);
+ pp_cxx_dot (pp);
+ dump_type (pp, TREE_OPERAND (t, 0), flags);
+ pp_cxx_colon_colon (pp);
+ pp_cxx_complement (pp);
+ dump_type (pp, TREE_OPERAND (t, 1), flags);
break;
case TEMPLATE_ID_EXPR:
- dump_decl (t, flags);
+ dump_decl (pp, t, flags);
break;
case BIND_EXPR:
@@ -2448,37 +2490,37 @@ dump_expr (tree t, int flags)
case STATEMENT_LIST:
/* We don't yet have a way of dumping statements in a
human-readable format. */
- pp_string (cxx_pp, "({...})");
+ pp_string (pp, "({...})");
break;
case LOOP_EXPR:
- pp_string (cxx_pp, "while (1) { ");
- dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
- pp_cxx_right_brace (cxx_pp);
+ pp_string (pp, "while (1) { ");
+ dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_right_brace (pp);
break;
case EXIT_EXPR:
- pp_string (cxx_pp, "if (");
- dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
- pp_string (cxx_pp, ") break; ");
+ pp_string (pp, "if (");
+ dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ pp_string (pp, ") break; ");
break;
case BASELINK:
- dump_expr (BASELINK_FUNCTIONS (t), flags & ~TFF_EXPR_IN_PARENS);
+ dump_expr (pp, BASELINK_FUNCTIONS (t), flags & ~TFF_EXPR_IN_PARENS);
break;
case EMPTY_CLASS_EXPR:
- dump_type (TREE_TYPE (t), flags);
- pp_cxx_left_paren (cxx_pp);
- pp_cxx_right_paren (cxx_pp);
+ dump_type (pp, TREE_TYPE (t), flags);
+ pp_cxx_left_paren (pp);
+ pp_cxx_right_paren (pp);
break;
case NON_DEPENDENT_EXPR:
- dump_expr (TREE_OPERAND (t, 0), flags);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags);
break;
case ARGUMENT_PACK_SELECT:
- dump_template_argument (ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
+ dump_template_argument (pp, ARGUMENT_PACK_SELECT_FROM_PACK (t), flags);
break;
case RECORD_TYPE:
@@ -2490,35 +2532,35 @@ dump_expr (tree t, int flags)
case INTEGER_TYPE:
case COMPLEX_TYPE:
case VECTOR_TYPE:
- pp_type_specifier_seq (cxx_pp, t);
+ pp_type_specifier_seq (pp, t);
break;
case TYPENAME_TYPE:
/* We get here when we want to print a dependent type as an
id-expression, without any disambiguator decoration. */
- pp_id_expression (cxx_pp, t);
+ pp->id_expression (t);
break;
case TEMPLATE_TYPE_PARM:
case TEMPLATE_TEMPLATE_PARM:
case BOUND_TEMPLATE_TEMPLATE_PARM:
- dump_type (t, flags);
+ dump_type (pp, t, flags);
break;
case TRAIT_EXPR:
- pp_cxx_trait_expression (cxx_pp, t);
+ pp_cxx_trait_expression (pp, t);
break;
case VA_ARG_EXPR:
- pp_cxx_va_arg_expression (cxx_pp, t);
+ pp_cxx_va_arg_expression (pp, t);
break;
case OFFSETOF_EXPR:
- pp_cxx_offsetof_expression (cxx_pp, t);
+ pp_cxx_offsetof_expression (pp, t);
break;
case SCOPE_REF:
- dump_decl (t, flags);
+ dump_decl (pp, t, flags);
break;
case EXPR_PACK_EXPANSION:
@@ -2546,81 +2588,90 @@ dump_expr (tree t, int flags)
case BIT_FIELD_REF:
case FIX_TRUNC_EXPR:
case FLOAT_EXPR:
- pp_expression (cxx_pp, t);
+ pp->expression (t);
break;
case TRUTH_AND_EXPR:
case TRUTH_OR_EXPR:
case TRUTH_XOR_EXPR:
if (flags & TFF_EXPR_IN_PARENS)
- pp_cxx_left_paren (cxx_pp);
- pp_expression (cxx_pp, t);
+ pp_cxx_left_paren (pp);
+ pp->expression (t);
if (flags & TFF_EXPR_IN_PARENS)
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
break;
case OBJ_TYPE_REF:
- dump_expr (resolve_virtual_fun_from_obj_type_ref (t), flags);
+ dump_expr (pp, resolve_virtual_fun_from_obj_type_ref (t), flags);
break;
case LAMBDA_EXPR:
- pp_string (cxx_pp, M_("<lambda>"));
+ pp_string (pp, M_("<lambda>"));
break;
case PAREN_EXPR:
- pp_cxx_left_paren (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
break;
/* This list is incomplete, but should suffice for now.
It is very important that `sorry' does not call
`report_error_function'. That could cause an infinite loop. */
default:
- pp_unsupported_tree (cxx_pp, t);
+ pp_unsupported_tree (pp, t);
/* fall through to ERROR_MARK... */
case ERROR_MARK:
- pp_string (cxx_pp, M_("<expression error>"));
+ pp_string (pp, M_("<expression error>"));
break;
}
}
static void
-dump_binary_op (const char *opstring, tree t, int flags)
+dump_binary_op (cxx_pretty_printer *pp, const char *opstring, tree t,
+ int flags)
{
- pp_cxx_left_paren (cxx_pp);
- dump_expr (TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_whitespace (cxx_pp);
+ pp_cxx_left_paren (pp);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_whitespace (pp);
if (opstring)
- pp_cxx_ws_string (cxx_pp, opstring);
+ pp_cxx_ws_string (pp, opstring);
else
- pp_string (cxx_pp, M_("<unknown operator>"));
- pp_cxx_whitespace (cxx_pp);
- dump_expr (TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
- pp_cxx_right_paren (cxx_pp);
+ pp_string (pp, M_("<unknown operator>"));
+ pp_cxx_whitespace (pp);
+ dump_expr (pp, TREE_OPERAND (t, 1), flags | TFF_EXPR_IN_PARENS);
+ pp_cxx_right_paren (pp);
}
static void
-dump_unary_op (const char *opstring, tree t, int flags)
+dump_unary_op (cxx_pretty_printer *pp, const char *opstring, tree t, int flags)
{
if (flags & TFF_EXPR_IN_PARENS)
- pp_cxx_left_paren (cxx_pp);
- pp_cxx_ws_string (cxx_pp, opstring);
- dump_expr (TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
+ pp_cxx_left_paren (pp);
+ pp_cxx_ws_string (pp, opstring);
+ dump_expr (pp, TREE_OPERAND (t, 0), flags & ~TFF_EXPR_IN_PARENS);
if (flags & TFF_EXPR_IN_PARENS)
- pp_cxx_right_paren (cxx_pp);
+ pp_cxx_right_paren (pp);
}
static void
reinit_cxx_pp (void)
{
pp_clear_output_area (cxx_pp);
- pp_base (cxx_pp)->padding = pp_none;
+ cxx_pp->padding = pp_none;
pp_indentation (cxx_pp) = 0;
pp_needs_newline (cxx_pp) = false;
cxx_pp->enclosing_scope = current_function_decl;
}
+/* Same as pp_formatted_text, except the return string is a separate
+ copy and has a GGC storage duration, e.g. an indefinite lifetime. */
+
+inline const char *
+pp_ggc_formatted_text (pretty_printer *pp)
+{
+ return ggc_strdup (pp_formatted_text (pp));
+}
/* Exported interface to stringifying types, exprs and decls under TFF_*
control. */
@@ -2630,16 +2681,16 @@ type_as_string (tree typ, int flags)
{
reinit_cxx_pp ();
pp_translate_identifiers (cxx_pp) = false;
- dump_type (typ, flags);
- return pp_formatted_text (cxx_pp);
+ dump_type (cxx_pp, typ, flags);
+ return pp_ggc_formatted_text (cxx_pp);
}
const char *
type_as_string_translate (tree typ, int flags)
{
reinit_cxx_pp ();
- dump_type (typ, flags);
- return pp_formatted_text (cxx_pp);
+ dump_type (cxx_pp, typ, flags);
+ return pp_ggc_formatted_text (cxx_pp);
}
const char *
@@ -2647,8 +2698,8 @@ expr_as_string (tree decl, int flags)
{
reinit_cxx_pp ();
pp_translate_identifiers (cxx_pp) = false;
- dump_expr (decl, flags);
- return pp_formatted_text (cxx_pp);
+ dump_expr (cxx_pp, decl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
}
/* Wrap decl_as_string with options appropriate for dwarf. */
@@ -2659,10 +2710,10 @@ decl_as_dwarf_string (tree decl, int flags)
const char *name;
/* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
here will be adequate to get the desired behaviour. */
- pp_c_base (cxx_pp)->flags |= pp_c_flag_gnu_v3;
+ cxx_pp->flags |= pp_c_flag_gnu_v3;
name = decl_as_string (decl, flags);
/* Subsequent calls to the pretty printer shouldn't use this style. */
- pp_c_base (cxx_pp)->flags &= ~pp_c_flag_gnu_v3;
+ cxx_pp->flags &= ~pp_c_flag_gnu_v3;
return name;
}
@@ -2671,16 +2722,16 @@ decl_as_string (tree decl, int flags)
{
reinit_cxx_pp ();
pp_translate_identifiers (cxx_pp) = false;
- dump_decl (decl, flags);
- return pp_formatted_text (cxx_pp);
+ dump_decl (cxx_pp, decl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
}
const char *
decl_as_string_translate (tree decl, int flags)
{
reinit_cxx_pp ();
- dump_decl (decl, flags);
- return pp_formatted_text (cxx_pp);
+ dump_decl (cxx_pp, decl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
}
/* Wrap lang_decl_name with options appropriate for dwarf. */
@@ -2691,10 +2742,10 @@ lang_decl_dwarf_name (tree decl, int v, bool translate)
const char *name;
/* Curiously, reinit_cxx_pp doesn't reset the flags field, so setting the flag
here will be adequate to get the desired behaviour. */
- pp_c_base (cxx_pp)->flags |= pp_c_flag_gnu_v3;
+ cxx_pp->flags |= pp_c_flag_gnu_v3;
name = lang_decl_name (decl, v, translate);
/* Subsequent calls to the pretty printer shouldn't use this style. */
- pp_c_base (cxx_pp)->flags &= ~pp_c_flag_gnu_v3;
+ cxx_pp->flags &= ~pp_c_flag_gnu_v3;
return name;
}
@@ -2715,19 +2766,19 @@ lang_decl_name (tree decl, int v, bool translate)
|| (DECL_NAMESPACE_SCOPE_P (decl)
&& CP_DECL_CONTEXT (decl) != global_namespace)))
{
- dump_type (CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
+ dump_type (cxx_pp, CP_DECL_CONTEXT (decl), TFF_PLAIN_IDENTIFIER);
pp_cxx_colon_colon (cxx_pp);
}
if (TREE_CODE (decl) == FUNCTION_DECL)
- dump_function_name (decl, TFF_PLAIN_IDENTIFIER);
+ dump_function_name (cxx_pp, decl, TFF_PLAIN_IDENTIFIER);
else if ((DECL_NAME (decl) == NULL_TREE)
&& TREE_CODE (decl) == NAMESPACE_DECL)
- dump_decl (decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME);
+ dump_decl (cxx_pp, decl, TFF_PLAIN_IDENTIFIER | TFF_UNQUALIFIED_NAME);
else
- dump_decl (DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
+ dump_decl (cxx_pp, DECL_NAME (decl), TFF_PLAIN_IDENTIFIER);
- return pp_formatted_text (cxx_pp);
+ return pp_ggc_formatted_text (cxx_pp);
}
/* Return the location of a tree passed to %+ formats. */
@@ -2770,16 +2821,16 @@ decl_to_string (tree decl, int verbose)
flags |= TFF_TEMPLATE_HEADER;
reinit_cxx_pp ();
- dump_decl (decl, flags);
- return pp_formatted_text (cxx_pp);
+ dump_decl (cxx_pp, decl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
}
static const char *
expr_to_string (tree decl)
{
reinit_cxx_pp ();
- dump_expr (decl, 0);
- return pp_formatted_text (cxx_pp);
+ dump_expr (cxx_pp, decl, 0);
+ return pp_ggc_formatted_text (cxx_pp);
}
static const char *
@@ -2792,8 +2843,8 @@ fndecl_to_string (tree fndecl, int verbose)
if (verbose)
flags |= TFF_FUNCTION_DEFAULT_ARGUMENTS;
reinit_cxx_pp ();
- dump_decl (fndecl, flags);
- return pp_formatted_text (cxx_pp);
+ dump_decl (cxx_pp, fndecl, flags);
+ return pp_ggc_formatted_text (cxx_pp);
}
@@ -2833,13 +2884,13 @@ parm_to_string (int p)
pp_string (cxx_pp, "'this'");
else
pp_decimal_int (cxx_pp, p + 1);
- return pp_formatted_text (cxx_pp);
+ return pp_ggc_formatted_text (cxx_pp);
}
static const char *
op_to_string (enum tree_code p)
{
- tree id = operator_name_info[(int) p].identifier;
+ tree id = operator_name_info[p].identifier;
return id ? IDENTIFIER_POINTER (id) : M_("<unknown>");
}
@@ -2852,7 +2903,7 @@ type_to_string (tree typ, int verbose)
flags |= TFF_TEMPLATE_HEADER;
reinit_cxx_pp ();
- dump_type (typ, flags);
+ dump_type (cxx_pp, typ, flags);
/* If we're printing a type that involves typedefs, also print the
stripped version. But sometimes the stripped version looks
exactly the same, so we don't want it after all. To avoid printing
@@ -2861,7 +2912,7 @@ type_to_string (tree typ, int verbose)
&& !uses_template_parms (typ))
{
int aka_start; char *p;
- struct obstack *ob = pp_base (cxx_pp)->buffer->obstack;
+ struct obstack *ob = pp_buffer (cxx_pp)->obstack;
/* Remember the end of the initial dump. */
int len = obstack_object_size (ob);
tree aka = strip_typedefs (typ);
@@ -2869,14 +2920,14 @@ type_to_string (tree typ, int verbose)
pp_cxx_whitespace (cxx_pp);
/* And remember the start of the aka dump. */
aka_start = obstack_object_size (ob);
- dump_type (aka, flags);
- pp_character (cxx_pp, '}');
+ dump_type (cxx_pp, aka, flags);
+ pp_right_brace (cxx_pp);
p = (char*)obstack_base (ob);
/* If they are identical, cut off the aka with a NUL. */
if (memcmp (p, p+aka_start, len) == 0)
p[len] = '\0';
}
- return pp_formatted_text (cxx_pp);
+ return pp_ggc_formatted_text (cxx_pp);
}
static const char *
@@ -2905,11 +2956,11 @@ args_to_string (tree p, int verbose)
if (TREE_VALUE (p) == null_node)
pp_cxx_ws_string (cxx_pp, "NULL");
else
- dump_type (error_type (TREE_VALUE (p)), flags);
+ dump_type (cxx_pp, error_type (TREE_VALUE (p)), flags);
if (TREE_CHAIN (p))
pp_separate_with_comma (cxx_pp);
}
- return pp_formatted_text (cxx_pp);
+ return pp_ggc_formatted_text (cxx_pp);
}
/* Pretty-print a deduction substitution (from deduction_tsubst_fntype). P
@@ -2929,23 +2980,18 @@ subst_to_string (tree p)
return "";
reinit_cxx_pp ();
- dump_template_decl (TREE_PURPOSE (p), flags);
- pp_cxx_whitespace (cxx_pp);
- pp_cxx_left_bracket (cxx_pp);
- pp_cxx_ws_string (cxx_pp, M_("with"));
- pp_cxx_whitespace (cxx_pp);
- dump_template_bindings (tparms, targs, NULL);
- pp_cxx_right_bracket (cxx_pp);
- return pp_formatted_text (cxx_pp);
+ dump_template_decl (cxx_pp, TREE_PURPOSE (p), flags);
+ dump_substitution (cxx_pp, NULL, tparms, targs, /*flags=*/0);
+ return pp_ggc_formatted_text (cxx_pp);
}
static const char *
cv_to_string (tree p, int v)
{
reinit_cxx_pp ();
- pp_base (cxx_pp)->padding = v ? pp_before : pp_none;
+ cxx_pp->padding = v ? pp_before : pp_none;
pp_cxx_cv_qualifier_seq (cxx_pp, p);
- return pp_formatted_text (cxx_pp);
+ return pp_ggc_formatted_text (cxx_pp);
}
/* Langhook for print_error_function. */
@@ -2954,7 +3000,7 @@ cxx_print_error_function (diagnostic_context *context, const char *file,
diagnostic_info *diagnostic)
{
lhd_print_error_function (context, file, diagnostic);
- pp_base_set_prefix (context->printer, file);
+ pp_set_prefix (context->printer, file);
maybe_print_instantiation_context (context);
}
@@ -2966,7 +3012,7 @@ cp_diagnostic_starter (diagnostic_context *context,
cp_print_error_function (context, diagnostic);
maybe_print_instantiation_context (context);
maybe_print_constexpr_context (context);
- pp_base_set_prefix (context->printer, diagnostic_build_prefix (context,
+ pp_set_prefix (context->printer, diagnostic_build_prefix (context,
diagnostic));
}
@@ -2975,7 +3021,7 @@ cp_diagnostic_finalizer (diagnostic_context *context,
diagnostic_info *diagnostic)
{
virt_loc_aware_diagnostic_finalizer (context, diagnostic);
- pp_base_destroy_prefix (context->printer);
+ pp_destroy_prefix (context->printer);
}
/* Print current function onto BUFFER, in the process of reporting
@@ -2996,10 +3042,10 @@ cp_print_error_function (diagnostic_context *context,
char *new_prefix = (file && abstract_origin == NULL)
? file_name_as_prefix (context, file) : NULL;
- pp_base_set_prefix (context->printer, new_prefix);
+ pp_set_prefix (context->printer, new_prefix);
if (current_function_decl == NULL)
- pp_base_string (context->printer, _("At global scope:"));
+ pp_string (context->printer, _("At global scope:"));
else
{
tree fndecl, ao;
@@ -3062,8 +3108,8 @@ cp_print_error_function (diagnostic_context *context,
if (fndecl)
{
expanded_location s = expand_location (*locus);
- pp_base_character (context->printer, ',');
- pp_base_newline (context->printer);
+ pp_character (context->printer, ',');
+ pp_newline (context->printer);
if (s.file != NULL)
{
if (context->show_column && s.column != 0)
@@ -3083,12 +3129,12 @@ cp_print_error_function (diagnostic_context *context,
cxx_printable_name_translate (fndecl, 2));
}
}
- pp_base_character (context->printer, ':');
+ pp_character (context->printer, ':');
}
- pp_base_newline (context->printer);
+ pp_newline (context->printer);
diagnostic_set_last_function (context, diagnostic);
- pp_base_destroy_prefix (context->printer);
+ pp_destroy_prefix (context->printer);
context->printer->prefix = old_prefix;
}
}
@@ -3267,7 +3313,7 @@ print_instantiation_partial_context (diagnostic_context *context,
}
print_instantiation_partial_context_line (context, NULL, loc,
/*recursive_p=*/false);
- pp_base_newline (context->printer);
+ pp_newline (context->printer);
}
/* Called from cp_thing to print the template context for an error. */
@@ -3287,7 +3333,7 @@ print_instantiation_context (void)
{
print_instantiation_partial_context
(global_dc, current_instantiation (), input_location);
- pp_base_newline (global_dc->printer);
+ pp_newline (global_dc->printer);
diagnostic_flush_buffer (global_dc);
}
@@ -3312,7 +3358,7 @@ maybe_print_constexpr_context (diagnostic_context *context)
pp_verbatim (context->printer,
_("%r%s:%d:%R in constexpr expansion of %qs"),
"locus", xloc.file, xloc.line, s);
- pp_base_newline (context->printer);
+ pp_newline (context->printer);
}
}
@@ -3384,7 +3430,7 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
return false;
}
- pp_base_string (pp, result);
+ pp_string (pp, result);
if (set_locus && t != NULL)
*text->locus = location_of (t);
return true;
diff --git a/gcc/cp/except.c b/gcc/cp/except.c
index be003d2994b..c76d9440aa9 100644
--- a/gcc/cp/except.c
+++ b/gcc/cp/except.c
@@ -57,7 +57,8 @@ init_exception_processing (void)
/* void std::terminate (); */
push_namespace (std_identifier);
tmp = build_function_type_list (void_type_node, NULL_TREE);
- terminate_node = build_cp_library_fn_ptr ("terminate", tmp);
+ terminate_node = build_cp_library_fn_ptr ("terminate", tmp,
+ ECF_NOTHROW | ECF_NORETURN);
TREE_THIS_VOLATILE (terminate_node) = 1;
TREE_NOTHROW (terminate_node) = 1;
pop_namespace ();
@@ -149,12 +150,13 @@ build_exc_ptr (void)
are consistent with the actual implementations in libsupc++. */
static tree
-declare_nothrow_library_fn (tree name, tree return_type, tree parm_type)
+declare_library_fn (tree name, tree return_type, tree parm_type, int ecf_flags)
{
return push_library_fn (name, build_function_type_list (return_type,
parm_type,
NULL_TREE),
- empty_except_spec);
+ empty_except_spec,
+ ecf_flags);
}
/* Build up a call to __cxa_get_exception_ptr so that we can build a
@@ -169,10 +171,8 @@ do_get_exception_ptr (void)
if (!get_global_value_if_present (fn, &fn))
{
/* Declare void* __cxa_get_exception_ptr (void *) throw(). */
- fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
-
- if (flag_tm)
- apply_tm_attr (fn, get_identifier ("transaction_pure"));
+ fn = declare_library_fn (fn, ptr_type_node, ptr_type_node,
+ ECF_NOTHROW | ECF_PURE | ECF_LEAF | ECF_TM_PURE);
}
return cp_build_function_call_nary (fn, tf_warning_or_error,
@@ -191,16 +191,15 @@ do_begin_catch (void)
if (!get_global_value_if_present (fn, &fn))
{
/* Declare void* __cxa_begin_catch (void *) throw(). */
- fn = declare_nothrow_library_fn (fn, ptr_type_node, ptr_type_node);
+ fn = declare_library_fn (fn, ptr_type_node, ptr_type_node, ECF_NOTHROW);
/* Create its transactional-memory equivalent. */
if (flag_tm)
{
tree fn2 = get_identifier ("_ITM_cxa_begin_catch");
if (!get_global_value_if_present (fn2, &fn2))
- fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
- ptr_type_node);
- apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+ fn2 = declare_library_fn (fn2, ptr_type_node,
+ ptr_type_node, ECF_NOTHROW | ECF_TM_PURE);
record_tm_replacement (fn, fn2);
}
}
@@ -238,21 +237,16 @@ do_end_catch (tree type)
fn = get_identifier ("__cxa_end_catch");
if (!get_global_value_if_present (fn, &fn))
{
- /* Declare void __cxa_end_catch (). */
- fn = push_void_library_fn (fn, void_list_node);
- /* This can throw if the destructor for the exception throws. */
- TREE_NOTHROW (fn) = 0;
+ /* Declare void __cxa_end_catch ().
+ This can throw if the destructor for the exception throws. */
+ fn = push_void_library_fn (fn, void_list_node, 0);
/* Create its transactional-memory equivalent. */
if (flag_tm)
{
tree fn2 = get_identifier ("_ITM_cxa_end_catch");
if (!get_global_value_if_present (fn2, &fn2))
- {
- fn2 = push_void_library_fn (fn2, void_list_node);
- TREE_NOTHROW (fn2) = 0;
- }
- apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+ fn2 = push_void_library_fn (fn2, void_list_node, ECF_TM_PURE);
record_tm_replacement (fn, fn2);
}
}
@@ -380,6 +374,9 @@ build_must_not_throw_expr (tree body, tree cond)
{
tree type = body ? TREE_TYPE (body) : void_type_node;
+ if (!flag_exceptions)
+ return body;
+
if (cond && !value_dependent_expression_p (cond))
{
cond = cxx_constant_value (cond);
@@ -631,15 +628,16 @@ do_allocate_exception (tree type)
if (!get_global_value_if_present (fn, &fn))
{
/* Declare void *__cxa_allocate_exception(size_t) throw(). */
- fn = declare_nothrow_library_fn (fn, ptr_type_node, size_type_node);
+ fn = declare_library_fn (fn, ptr_type_node, size_type_node,
+ ECF_NOTHROW | ECF_MALLOC);
if (flag_tm)
{
tree fn2 = get_identifier ("_ITM_cxa_allocate_exception");
if (!get_global_value_if_present (fn2, &fn2))
- fn2 = declare_nothrow_library_fn (fn2, ptr_type_node,
- size_type_node);
- apply_tm_attr (fn2, get_identifier ("transaction_pure"));
+ fn2 = declare_library_fn (fn2, ptr_type_node,
+ size_type_node,
+ ECF_NOTHROW | ECF_MALLOC | ECF_TM_PURE);
record_tm_replacement (fn, fn2);
}
}
@@ -660,7 +658,8 @@ do_free_exception (tree ptr)
if (!get_global_value_if_present (fn, &fn))
{
/* Declare void __cxa_free_exception (void *) throw(). */
- fn = declare_nothrow_library_fn (fn, void_type_node, ptr_type_node);
+ fn = declare_library_fn (fn, void_type_node, ptr_type_node,
+ ECF_NOTHROW | ECF_LEAF);
}
return cp_build_function_call_nary (fn, tf_warning_or_error, ptr, NULL_TREE);
diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c
index 3e018e8e84c..779dac905d6 100644
--- a/gcc/cp/friend.c
+++ b/gcc/cp/friend.c
@@ -327,7 +327,7 @@ make_friend_class (tree type, tree friend_type, bool complain)
{
error ("%qT is not a member class template of %qT",
name, ctype);
- error ("%q+D declared here", decl);
+ inform (input_location, "%q+D declared here", decl);
return;
}
if (!template_member_p && (TREE_CODE (decl) != TYPE_DECL
@@ -335,7 +335,7 @@ make_friend_class (tree type, tree friend_type, bool complain)
{
error ("%qT is not a nested class of %qT",
name, ctype);
- error ("%q+D declared here", decl);
+ inform (input_location, "%q+D declared here", decl);
return;
}
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index f346d2fbff5..f261f99b82b 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -43,7 +43,6 @@ static tree initializing_context (tree);
static void expand_cleanup_for_base (tree, tree);
static tree dfs_initialize_vtbl_ptrs (tree, void *);
static tree build_field_list (tree, tree, int *);
-static tree build_vtbl_address (tree);
static int diagnose_uninitialized_cst_or_ref_member_1 (tree, tree, bool, bool);
/* We are about to generate some complex initialization code.
@@ -501,8 +500,9 @@ perform_target_ctor (tree init)
tree decl = current_class_ref;
tree type = current_class_type;
- finish_expr_stmt (build_aggr_init (decl, init, LOOKUP_NORMAL,
- tf_warning_or_error));
+ finish_expr_stmt (build_aggr_init (decl, init,
+ LOOKUP_NORMAL|LOOKUP_DELEGATING_CONS,
+ tf_warning_or_error));
if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type))
{
tree expr = build_delete (type, decl, sfk_complete_destructor,
@@ -1098,7 +1098,7 @@ emit_mem_initializers (tree mem_inits)
/* Returns the address of the vtable (i.e., the value that should be
assigned to the vptr) for BINFO. */
-static tree
+tree
build_vtbl_address (tree binfo)
{
tree binfo_for = binfo;
@@ -1465,7 +1465,8 @@ build_aggr_init (tree exp, tree init, int flags, tsubst_flags_t complain)
TREE_READONLY (exp) = 0;
TREE_THIS_VOLATILE (exp) = 0;
- if (init && TREE_CODE (init) != TREE_LIST
+ if (init && init != void_type_node
+ && TREE_CODE (init) != TREE_LIST
&& !(TREE_CODE (init) == TARGET_EXPR
&& TARGET_EXPR_DIRECT_INIT_P (init))
&& !(BRACE_ENCLOSED_INITIALIZER_P (init)
diff --git a/gcc/cp/mangle.c b/gcc/cp/mangle.c
index 68b956bbbd1..8c11ba8d394 100644
--- a/gcc/cp/mangle.c
+++ b/gcc/cp/mangle.c
@@ -798,13 +798,14 @@ write_name (tree decl, const int ignore_local_scope)
context = decl_mangling_context (decl);
+ gcc_assert (context != NULL_TREE);
+
/* A decl in :: or ::std scope is treated specially. The former is
mangled using <unscoped-name> or <unscoped-template-name>, the
latter with a special substitution. Also, a name that is
directly in a local function scope is also mangled with
<unscoped-name> rather than a full <nested-name>. */
- if (context == NULL
- || context == global_namespace
+ if (context == global_namespace
|| DECL_NAMESPACE_STD_P (context)
|| (ignore_local_scope
&& (TREE_CODE (context) == FUNCTION_DECL
@@ -837,10 +838,10 @@ write_name (tree decl, const int ignore_local_scope)
directly in that function's scope, either decl or one of
its enclosing scopes. */
tree local_entity = decl;
- while (context != NULL && context != global_namespace)
+ while (context != global_namespace)
{
/* Make sure we're always dealing with decls. */
- if (context != NULL && TYPE_P (context))
+ if (TYPE_P (context))
context = TYPE_NAME (context);
/* Is this a function? */
if (TREE_CODE (context) == FUNCTION_DECL
@@ -883,9 +884,10 @@ write_unscoped_name (const tree decl)
else
{
/* If not, it should be either in the global namespace, or directly
- in a local function scope. */
+ in a local function scope. A lambda can also be mangled in the
+ scope of a default argument. */
gcc_assert (context == global_namespace
- || context != NULL
+ || TREE_CODE (context) == PARM_DECL
|| TREE_CODE (context) == FUNCTION_DECL);
write_unqualified_name (decl);
@@ -3886,4 +3888,34 @@ write_java_integer_type_codes (const tree type)
gcc_unreachable ();
}
+/* Given a CLASS_TYPE, such as a record for std::bad_exception this
+ function generates a mangled name for the vtable map variable of
+ the class type. For example, if the class type is
+ "std::bad_exception", the mangled name for the class is
+ "St13bad_exception". This function would generate the name
+ "_ZN4_VTVISt13bad_exceptionE12__vtable_mapE", which unmangles as:
+ "_VTV<std::bad_exception>::__vtable_map". */
+
+
+char *
+get_mangled_vtable_map_var_name (tree class_type)
+{
+ char *var_name = NULL;
+ const char *prefix = "_ZN4_VTVI";
+ const char *postfix = "E12__vtable_mapE";
+
+ gcc_assert (TREE_CODE (class_type) == RECORD_TYPE);
+
+ tree class_id = DECL_ASSEMBLER_NAME (TYPE_NAME (class_type));
+ unsigned int len = strlen (IDENTIFIER_POINTER (class_id)) +
+ strlen (prefix) +
+ strlen (postfix) + 1;
+
+ var_name = (char *) xmalloc (len);
+
+ sprintf (var_name, "%s%s%s", prefix, IDENTIFIER_POINTER (class_id), postfix);
+
+ return var_name;
+}
+
#include "gt-cp-mangle.h"
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index 2b1f9fbf318..025a03cd9fa 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -392,6 +392,17 @@ pop_binding (tree id, tree decl)
}
}
+/* Remove the bindings for the decls of the current level and leave
+ the current scope. */
+
+void
+pop_bindings_and_leave_scope (void)
+{
+ for (tree t = getdecls (); t; t = DECL_CHAIN (t))
+ pop_binding (DECL_NAME (t), t);
+ leave_scope ();
+}
+
/* Strip non dependent using declarations. */
tree
@@ -2256,6 +2267,27 @@ pushdecl_with_scope (tree x, cp_binding_level *level, bool is_friend)
return ret;
}
+/* Helper function for push_overloaded_decl_1 and do_nonmember_using_decl.
+ Compares the parameter-type-lists of DECL1 and DECL2 and returns false
+ if they are different. If the DECLs are template functions, the return
+ types and the template parameter lists are compared too (DR 565). */
+
+static bool
+compparms_for_decl_and_using_decl (tree decl1, tree decl2)
+{
+ if (!compparms (TYPE_ARG_TYPES (TREE_TYPE (decl1)),
+ TYPE_ARG_TYPES (TREE_TYPE (decl2))))
+ return false;
+
+ if (! DECL_FUNCTION_TEMPLATE_P (decl1)
+ || ! DECL_FUNCTION_TEMPLATE_P (decl2))
+ return true;
+
+ return (comp_template_parms (DECL_TEMPLATE_PARMS (decl1),
+ DECL_TEMPLATE_PARMS (decl2))
+ && same_type_p (TREE_TYPE (TREE_TYPE (decl1)),
+ TREE_TYPE (TREE_TYPE (decl2))));
+}
/* DECL is a FUNCTION_DECL for a non-member function, which may have
other definitions already in place. We get around this by making
@@ -2313,11 +2345,9 @@ push_overloaded_decl_1 (tree decl, int flags, bool is_friend)
if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp)
&& !(flags & PUSH_USING)
- && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)),
- TYPE_ARG_TYPES (TREE_TYPE (decl)))
+ && compparms_for_decl_and_using_decl (fn, decl)
&& ! decls_match (fn, decl))
- error ("%q#D conflicts with previous using declaration %q#D",
- decl, fn);
+ diagnose_name_conflict (decl, fn);
dup = duplicate_decls (decl, fn, is_friend);
/* If DECL was a redeclaration of FN -- even an invalid
@@ -2549,10 +2579,9 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
if (new_fn == old_fn)
/* The function already exists in the current namespace. */
break;
- else if (OVL_USED (tmp1))
+ else if (TREE_CODE (tmp1) == OVERLOAD && OVL_USED (tmp1))
continue; /* this is a using decl */
- else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)),
- TYPE_ARG_TYPES (TREE_TYPE (old_fn))))
+ else if (compparms_for_decl_and_using_decl (new_fn, old_fn))
{
gcc_assert (!DECL_ANTICIPATED (old_fn)
|| DECL_HIDDEN_FRIEND_P (old_fn));
@@ -2564,7 +2593,7 @@ do_nonmember_using_decl (tree scope, tree name, tree oldval, tree oldtype,
break;
else
{
- error ("%qD is already declared in this scope", name);
+ diagnose_name_conflict (new_fn, old_fn);
break;
}
}
@@ -3063,8 +3092,10 @@ push_class_level_binding_1 (tree name, tree x)
if (name == error_mark_node)
return false;
- /* Check for invalid member names. */
- gcc_assert (TYPE_BEING_DEFINED (current_class_type));
+ /* Check for invalid member names. But don't worry about a default
+ argument-scope lambda being pushed after the class is complete. */
+ gcc_assert (TYPE_BEING_DEFINED (current_class_type)
+ || LAMBDA_TYPE_P (TREE_TYPE (decl)));
/* Check that we're pushing into the right binding level. */
gcc_assert (current_class_type == class_binding_level->this_entity);
diff --git a/gcc/cp/name-lookup.h b/gcc/cp/name-lookup.h
index 11cdd1f09e8..57641a19902 100644
--- a/gcc/cp/name-lookup.h
+++ b/gcc/cp/name-lookup.h
@@ -89,6 +89,7 @@ typedef struct GTY(()) cxx_saved_binding {
extern tree identifier_type_value (tree);
extern void set_identifier_type_value (tree, tree);
extern void pop_binding (tree, tree);
+extern void pop_bindings_and_leave_scope (void);
extern tree constructor_name (tree);
extern bool constructor_name_p (tree, tree);
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 56a017fdb7e..923277b6daa 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -8710,15 +8710,8 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
/* Turn the identifier into an id-expression. */
capture_init_expr
- = cp_parser_lookup_name
- (parser,
- capture_id,
- none_type,
- /*is_template=*/false,
- /*is_namespace=*/false,
- /*check_dependency=*/true,
- /*ambiguous_decls=*/NULL,
- capture_token->location);
+ = cp_parser_lookup_name_simple (parser, capture_id,
+ capture_token->location);
if (capture_init_expr == error_mark_node)
{
@@ -8809,7 +8802,6 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
tree param_list = void_list_node;
tree attributes = NULL_TREE;
tree exception_spec = NULL_TREE;
- tree t;
/* The lambda-declarator is optional, but must begin with an opening
parenthesis if present. */
@@ -8824,7 +8816,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
/* Default arguments shall not be specified in the
parameter-declaration-clause of a lambda-declarator. */
- for (t = param_list; t; t = TREE_CHAIN (t))
+ for (tree t = param_list; t; t = TREE_CHAIN (t))
if (TREE_PURPOSE (t))
pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)), OPT_Wpedantic,
"default argument specified for lambda parameter");
@@ -8853,10 +8845,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
/* The function parameters must be in scope all the way until after the
trailing-return-type in case of decltype. */
- for (t = current_binding_level->names; t; t = DECL_CHAIN (t))
- pop_binding (DECL_NAME (t), t);
-
- leave_scope ();
+ pop_bindings_and_leave_scope ();
}
/* Create the function call operator.
@@ -9419,8 +9408,6 @@ cp_parser_expression_statement (cp_parser* parser, tree in_statement_expr)
statement = finish_stmt_expr_expr (statement, in_statement_expr);
else if (statement)
statement = finish_expr_stmt (statement);
- else
- finish_stmt ();
return statement;
}
@@ -10472,9 +10459,6 @@ cp_parser_declaration_statement (cp_parser* parser)
/* Free any declarators allocated. */
obstack_free (&declarator_obstack, p);
-
- /* Finish off the statement. */
- finish_stmt ();
}
/* Some dependent statements (like `if (cond) statement'), are
@@ -11588,13 +11572,8 @@ cp_parser_decltype_expr (cp_parser *parser,
if (identifier_p (expr))
/* Lookup the name we got back from the id-expression. */
- expr = cp_parser_lookup_name (parser, expr,
- none_type,
- /*is_template=*/false,
- /*is_namespace=*/false,
- /*check_dependency=*/true,
- /*ambiguous_decls=*/NULL,
- id_expr_start_token->location);
+ expr = cp_parser_lookup_name_simple (parser, expr,
+ id_expr_start_token->location);
if (expr
&& expr != error_mark_node
@@ -16746,7 +16725,6 @@ cp_parser_direct_declarator (cp_parser* parser,
tree params;
unsigned saved_num_template_parameter_lists;
bool is_declarator = false;
- tree t;
/* In a member-declarator, the only valid interpretation
of a parenthesis is the start of a
@@ -16835,9 +16813,7 @@ cp_parser_direct_declarator (cp_parser* parser,
}
/* Remove the function parms from scope. */
- for (t = current_binding_level->names; t; t = DECL_CHAIN (t))
- pop_binding (DECL_NAME (t), t);
- leave_scope();
+ pop_bindings_and_leave_scope ();
if (is_declarator)
/* Repeat the main loop. */
@@ -23140,6 +23116,8 @@ cp_parser_sizeof_pack (cp_parser *parser)
cp_token *token = cp_lexer_peek_token (parser->lexer);
tree name = cp_parser_identifier (parser);
+ if (name == error_mark_node)
+ return error_mark_node;
/* The name is not qualified. */
parser->scope = NULL_TREE;
parser->qualifying_scope = NULL_TREE;
@@ -24104,7 +24082,6 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
the default argument; otherwise the default
argument continues. */
bool error = false;
- tree t;
/* Set ITALP so cp_parser_parameter_declaration_list
doesn't decide to commit to this parse. */
@@ -24126,9 +24103,7 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
{
begin_scope (sk_function_parms, NULL_TREE);
cp_parser_parameter_declaration_list (parser, &error);
- for (t = current_binding_level->names; t; t = DECL_CHAIN (t))
- pop_binding (DECL_NAME (t), t);
- leave_scope ();
+ pop_bindings_and_leave_scope ();
}
if (!cp_parser_error_occurred (parser) && !error)
done = true;
@@ -24145,7 +24120,9 @@ cp_parser_cache_defarg (cp_parser *parser, bool nsdmi)
case CPP_SEMICOLON:
case CPP_CLOSE_BRACE:
case CPP_CLOSE_SQUARE:
- if (depth == 0)
+ if (depth == 0
+ /* Handle correctly int n = sizeof ... ( p ); */
+ && !(nsdmi && token->type == CPP_ELLIPSIS))
done = true;
/* Update DEPTH, if necessary. */
else if (token->type == CPP_CLOSE_PAREN
@@ -28605,7 +28582,6 @@ cp_parser_transaction_cancel (cp_parser *parser)
stmt = build_tm_abort_call (token->location, is_outer);
add_stmt (stmt);
- finish_stmt ();
return stmt;
}
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 82c72dd96df..e937318d227 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -1986,7 +1986,7 @@ determine_specialization (tree template_id,
tree decl_arg_types;
/* This is an ordinary member function. However, since
- we're here, we can assume it's enclosing class is a
+ we're here, we can assume its enclosing class is a
template class. For example,
template <typename T> struct S { void f(); };
@@ -4337,7 +4337,7 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
|| DECL_INITIALIZED_IN_CLASS_P (decl)))
/* We already checked these parameters when the template was
declared, so there's no need to do it again now. This function
- was defined in class scope, but we're processing it's body now
+ was defined in class scope, but we're processing its body now
that the class is complete. */
return true;
@@ -5111,6 +5111,34 @@ alias_template_specialization_p (const_tree t)
&& DECL_ALIAS_TEMPLATE_P (TYPE_TI_TEMPLATE (t)));
}
+/* Return either TMPL or another template that it is equivalent to under DR
+ 1286: An alias that just changes the name of a template is equivalent to
+ the other template. */
+
+static tree
+get_underlying_template (tree tmpl)
+{
+ gcc_assert (TREE_CODE (tmpl) == TEMPLATE_DECL);
+ while (DECL_ALIAS_TEMPLATE_P (tmpl))
+ {
+ tree result = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl));
+ if (TYPE_TEMPLATE_INFO (result))
+ {
+ tree sub = TYPE_TI_TEMPLATE (result);
+ if (PRIMARY_TEMPLATE_P (sub)
+ && same_type_p (result, TREE_TYPE (sub)))
+ {
+ /* The alias type is equivalent to the pattern of the
+ underlying template, so strip the alias. */
+ tmpl = sub;
+ continue;
+ }
+ }
+ break;
+ }
+ return tmpl;
+}
+
/* Subroutine of convert_nontype_argument. Converts EXPR to TYPE, which
must be a function or a pointer-to-function type, as specified
in [temp.arg.nontype]: disambiguate EXPR if it is an overload set,
@@ -6319,6 +6347,9 @@ convert_template_argument (tree parm,
tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm);
tree argparm;
+ /* Strip alias templates that are equivalent to another
+ template. */
+ arg = get_underlying_template (arg);
argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg);
if (coerce_template_template_parms (parmparm, argparm,
@@ -6542,18 +6573,22 @@ coerce_template_parameter_pack (tree parms,
return argument_pack;
}
-/* Returns true if the template argument vector ARGS contains
- any pack expansions, false otherwise. */
+/* Returns the number of pack expansions in the template argument vector
+ ARGS. */
-static bool
-any_pack_expanson_args_p (tree args)
+static int
+pack_expansion_args_count (tree args)
{
int i;
+ int count = 0;
if (args)
for (i = 0; i < TREE_VEC_LENGTH (args); ++i)
- if (PACK_EXPANSION_P (TREE_VEC_ELT (args, i)))
- return true;
- return false;
+ {
+ tree elt = TREE_VEC_ELT (args, i);
+ if (elt && PACK_EXPANSION_P (elt))
+ ++count;
+ }
+ return count;
}
/* Convert all template arguments to their appropriate types, and
@@ -6588,6 +6623,7 @@ coerce_template_parms (tree parms,
subtract it from nparms to get the number of non-variadic
parameters. */
int variadic_p = 0;
+ int variadic_args_p = 0;
int post_variadic_parms = 0;
if (args == error_mark_node)
@@ -6617,11 +6653,14 @@ coerce_template_parms (tree parms,
if (!post_variadic_parms)
inner_args = expand_template_argument_pack (inner_args);
+ /* Count any pack expansion args. */
+ variadic_args_p = pack_expansion_args_count (inner_args);
+
nargs = inner_args ? NUM_TMPL_ARGS (inner_args) : 0;
if ((nargs > nparms && !variadic_p)
|| (nargs < nparms - variadic_p
&& require_all_args
- && !any_pack_expanson_args_p (inner_args)
+ && !variadic_args_p
&& (!use_default_args
|| (TREE_VEC_ELT (parms, nargs) != error_mark_node
&& !TREE_PURPOSE (TREE_VEC_ELT (parms, nargs))))))
@@ -6644,6 +6683,33 @@ coerce_template_parms (tree parms,
return error_mark_node;
}
+ /* We can't pass a pack expansion to a non-pack parameter of an alias
+ template (DR 1430). */
+ else if (in_decl && DECL_ALIAS_TEMPLATE_P (in_decl)
+ && variadic_args_p
+ && nargs - variadic_args_p < nparms - variadic_p)
+ {
+ if (complain & tf_error)
+ {
+ for (int i = 0; i < TREE_VEC_LENGTH (inner_args); ++i)
+ {
+ tree arg = TREE_VEC_ELT (inner_args, i);
+ tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i));
+
+ if (PACK_EXPANSION_P (arg)
+ && !template_parameter_pack_p (parm))
+ {
+ error ("pack expansion argument for non-pack parameter "
+ "%qD of alias template %qD", parm, in_decl);
+ inform (DECL_SOURCE_LOCATION (parm), "declared here");
+ goto found;
+ }
+ }
+ gcc_unreachable ();
+ found:;
+ }
+ return error_mark_node;
+ }
/* We need to evaluate the template arguments, even though this
template-id may be nested within a "sizeof". */
@@ -7142,6 +7208,13 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
complain &= ~tf_user;
+ /* An alias that just changes the name of a template is equivalent to the
+ other template, so if any of the arguments are pack expansions, strip
+ the alias to avoid problems with a pack expansion passed to a non-pack
+ alias template parameter (DR 1430). */
+ if (pack_expansion_args_count (INNERMOST_TEMPLATE_ARGS (arglist)))
+ templ = get_underlying_template (templ);
+
if (DECL_TEMPLATE_TEMPLATE_PARM_P (templ))
{
/* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store
@@ -7482,7 +7555,7 @@ lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context,
the one of #0.
When we encounter #1, we want to store the partial instantiation
- of M (template<class T> S<int>::M<T>) in it's CLASSTYPE_TI_TEMPLATE.
+ of M (template<class T> S<int>::M<T>) in its CLASSTYPE_TI_TEMPLATE.
For all cases other than this "explicit specialization of member of a
class template", we just want to store the most general template into
@@ -8657,7 +8730,8 @@ instantiate_class_template_1 (tree type)
/* Adjust visibility for template arguments. */
determine_visibility (TYPE_MAIN_DECL (type));
}
- CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern);
+ if (CLASS_TYPE_P (type))
+ CLASSTYPE_FINAL (type) = CLASSTYPE_FINAL (pattern);
pbinfo = TYPE_BINFO (pattern);
diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c
index f3094981dfb..5827540c9b2 100644
--- a/gcc/cp/rtti.c
+++ b/gcc/cp/rtti.c
@@ -739,8 +739,8 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain)
const_ptr_type_node,
tinfo_ptr, tinfo_ptr,
ptrdiff_type_node, NULL_TREE);
- dcast_fn = build_library_fn_ptr (name, tmp);
- DECL_PURE_P (dcast_fn) = 1;
+ dcast_fn = build_library_fn_ptr (name, tmp,
+ ECF_LEAF | ECF_PURE | ECF_NOTHROW);
pop_abi_namespace ();
dynamic_cast_node = dcast_fn;
}
diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c
index f68d3863ab1..ee3503cdd77 100644
--- a/gcc/cp/semantics.c
+++ b/gcc/cp/semantics.c
@@ -641,8 +641,6 @@ finish_expr_stmt (tree expr)
r = add_stmt (expr);
}
- finish_stmt ();
-
return r;
}
@@ -707,7 +705,6 @@ finish_if_stmt (tree if_stmt)
tree scope = IF_SCOPE (if_stmt);
IF_SCOPE (if_stmt) = NULL;
add_stmt (do_poplevel (scope));
- finish_stmt ();
}
/* Begin a while-statement. Returns a newly created WHILE_STMT if
@@ -740,7 +737,6 @@ void
finish_while_stmt (tree while_stmt)
{
WHILE_BODY (while_stmt) = do_poplevel (WHILE_BODY (while_stmt));
- finish_stmt ();
}
/* Begin a do-statement. Returns a newly created DO_STMT if
@@ -778,7 +774,6 @@ finish_do_stmt (tree cond, tree do_stmt)
{
cond = maybe_convert_cond (cond);
DO_COND (do_stmt) = cond;
- finish_stmt ();
}
/* Finish a return-statement. The EXPRESSION returned, if any, is as
@@ -815,7 +810,6 @@ finish_return_stmt (tree expr)
TREE_NO_WARNING (r) |= no_warning;
r = maybe_cleanup_point_expr_void (r);
r = add_stmt (r);
- finish_stmt ();
return r;
}
@@ -941,8 +935,6 @@ finish_for_stmt (tree for_stmt)
*scope_ptr = NULL;
add_stmt (do_poplevel (scope));
}
-
- finish_stmt ();
}
/* Begin a range-for-statement. Returns a new RANGE_FOR_STMT.
@@ -1076,7 +1068,6 @@ finish_switch_stmt (tree switch_stmt)
SWITCH_STMT_BODY (switch_stmt) =
pop_stmt_list (SWITCH_STMT_BODY (switch_stmt));
pop_switch ();
- finish_stmt ();
scope = SWITCH_STMT_SCOPE (switch_stmt);
SWITCH_STMT_SCOPE (switch_stmt) = NULL;
@@ -1298,7 +1289,6 @@ finish_compound_stmt (tree stmt)
/* ??? See c_end_compound_stmt wrt statement expressions. */
add_stmt (stmt);
- finish_stmt ();
}
/* Finish an asm-statement, whose components are a STRING, some
@@ -3141,7 +3131,7 @@ finish_id_expression (tree id_expression,
error (VAR_P (decl)
? G_("use of local variable with automatic storage from containing function")
: G_("use of parameter from containing function"));
- error (" %q+#D declared here", decl);
+ inform (input_location, "%q+#D declared here", decl);
return error_mark_node;
}
}
@@ -3467,8 +3457,10 @@ finish_id_expression (tree id_expression,
}
}
- if (TREE_DEPRECATED (decl))
- warn_deprecated_use (decl, NULL_TREE);
+ /* Handle references (c++/56130). */
+ tree t = REFERENCE_REF_P (decl) ? TREE_OPERAND (decl, 0) : decl;
+ if (TREE_DEPRECATED (t))
+ warn_deprecated_use (t, NULL_TREE);
return decl;
}
@@ -3701,7 +3693,7 @@ finish_offsetof (tree expr)
|| TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE
|| TREE_TYPE (expr) == unknown_type_node)
{
- if (TREE_CODE (expr) == INDIRECT_REF)
+ if (INDIRECT_REF_P (expr))
error ("second operand of %<offsetof%> is neither a single "
"identifier nor a sequence of member accesses and "
"array references");
@@ -5208,7 +5200,6 @@ finish_transaction_stmt (tree stmt, tree compound_stmt, int flags, tree noex)
if (compound_stmt)
finish_compound_stmt (compound_stmt);
- finish_stmt ();
}
/* Build a __transaction_atomic or __transaction_relaxed expression. If
@@ -6016,7 +6007,7 @@ build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
|| TREE_CODE (t) == MODIFY_EXPR)
{
member = TREE_OPERAND (t, 0);
- init = unshare_expr (TREE_OPERAND (t, 1));
+ init = break_out_target_exprs (TREE_OPERAND (t, 1));
}
else if (TREE_CODE (t) == CALL_EXPR)
{
@@ -6024,7 +6015,7 @@ build_data_member_initialization (tree t, vec<constructor_elt, va_gc> **vec)
/* We don't use build_cplus_new here because it complains about
abstract bases. Leaving the call unwrapped means that it has the
wrong type, but cxx_eval_constant_expression doesn't care. */
- init = unshare_expr (t);
+ init = break_out_target_exprs (t);
}
else if (TREE_CODE (t) == DECL_EXPR)
/* Declaring a temporary, don't add it to the CONSTRUCTOR. */
@@ -6261,7 +6252,7 @@ constexpr_fn_retval (tree body)
}
case RETURN_EXPR:
- return unshare_expr (TREE_OPERAND (body, 0));
+ return break_out_target_exprs (TREE_OPERAND (body, 0));
case DECL_EXPR:
if (TREE_CODE (DECL_EXPR_DECL (body)) == USING_DECL)
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index f8b4bbce822..63ec7fa7266 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1236,6 +1236,8 @@ strip_typedefs (tree t)
result =
build_method_type_directly (class_type, type,
TREE_CHAIN (arg_types));
+ result
+ = build_ref_qualified_type (result, type_memfn_rqual (t));
}
else
{
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 6f330559adf..6c48f242dd7 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -37,13 +37,14 @@ along with GCC; see the file COPYING3. If not see
#include "convert.h"
#include "c-family/c-common.h"
#include "c-family/c-objc.h"
+#include "c-family/c-ubsan.h"
#include "params.h"
static tree pfn_from_ptrmemfunc (tree);
static tree delta_from_ptrmemfunc (tree);
static tree convert_for_assignment (tree, tree, impl_conv_rhs, tree, int,
tsubst_flags_t, int);
-static tree cp_pointer_int_sum (enum tree_code, tree, tree);
+static tree cp_pointer_int_sum (enum tree_code, tree, tree, tsubst_flags_t);
static tree rationalize_conditional_expr (enum tree_code, tree,
tsubst_flags_t);
static int comp_ptr_ttypes_real (tree, tree, int);
@@ -3882,6 +3883,7 @@ cp_build_binary_op (location_t location,
tree final_type = 0;
tree result;
+ tree orig_type = NULL;
/* Nonzero if this is an operation like MIN or MAX which can
safely be computed in short if both args are promoted shorts.
@@ -3906,6 +3908,15 @@ cp_build_binary_op (location_t location,
op0 = orig_op0;
op1 = orig_op1;
+ /* Remember whether we're doing / or %. */
+ bool doing_div_or_mod = false;
+
+ /* Remember whether we're doing << or >>. */
+ bool doing_shift = false;
+
+ /* Tree holding instrumentation expression. */
+ tree instrument_expr = NULL;
+
if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR
|| code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR
|| code == TRUTH_XOR_EXPR)
@@ -4064,7 +4075,8 @@ cp_build_binary_op (location_t location,
}
return cp_pointer_int_sum (code,
ptr_operand,
- int_operand);
+ int_operand,
+ complain);
}
common = 1;
break;
@@ -4085,8 +4097,12 @@ cp_build_binary_op (location_t location,
{
enum tree_code tcode0 = code0, tcode1 = code1;
tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+ cop1 = maybe_constant_value (cop1);
- warn_for_div_by_zero (location, maybe_constant_value (cop1));
+ if (tcode0 == INTEGER_TYPE)
+ doing_div_or_mod = true;
+
+ warn_for_div_by_zero (location, cop1);
if (tcode0 == COMPLEX_TYPE || tcode0 == VECTOR_TYPE)
tcode0 = TREE_CODE (TREE_TYPE (TREE_TYPE (op0)));
@@ -4124,8 +4140,11 @@ cp_build_binary_op (location_t location,
case FLOOR_MOD_EXPR:
{
tree cop1 = fold_non_dependent_expr_sfinae (op1, tf_none);
+ cop1 = maybe_constant_value (cop1);
- warn_for_div_by_zero (location, maybe_constant_value (cop1));
+ if (code0 == INTEGER_TYPE)
+ doing_div_or_mod = true;
+ warn_for_div_by_zero (location, cop1);
}
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE
@@ -4179,6 +4198,7 @@ cp_build_binary_op (location_t location,
if (TREE_CODE (const_op1) != INTEGER_CST)
const_op1 = op1;
result_type = type0;
+ doing_shift = true;
if (TREE_CODE (const_op1) == INTEGER_CST)
{
if (tree_int_cst_lt (const_op1, integer_zero_node))
@@ -4226,6 +4246,7 @@ cp_build_binary_op (location_t location,
if (TREE_CODE (const_op1) != INTEGER_CST)
const_op1 = op1;
result_type = type0;
+ doing_shift = true;
if (TREE_CODE (const_op1) == INTEGER_CST)
{
if (tree_int_cst_lt (const_op1, integer_zero_node))
@@ -4533,7 +4554,8 @@ cp_build_binary_op (location_t location,
vector_compare:
tree intt;
if (!same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (type0),
- TREE_TYPE (type1)))
+ TREE_TYPE (type1))
+ && !vector_types_compatible_elements_p (type0, type1))
{
if (complain & tf_error)
{
@@ -4649,8 +4671,7 @@ cp_build_binary_op (location_t location,
if (code0 == VECTOR_TYPE && code1 == VECTOR_TYPE)
{
if (!tree_int_cst_equal (TYPE_SIZE (type0), TYPE_SIZE (type1))
- || !same_scalar_type_ignoring_signedness (TREE_TYPE (type0),
- TREE_TYPE (type1)))
+ || !vector_types_compatible_elements_p (type0, type1))
{
if (complain & tf_error)
binary_op_error (location, code, type0, type1);
@@ -4795,8 +4816,9 @@ cp_build_binary_op (location_t location,
if (shorten && none_complex)
{
+ orig_type = result_type;
final_type = result_type;
- result_type = shorten_binary_op (result_type, op0, op1,
+ result_type = shorten_binary_op (result_type, op0, op1,
shorten == -1);
}
@@ -4862,6 +4884,36 @@ cp_build_binary_op (location_t location,
if (build_type == NULL_TREE)
build_type = result_type;
+ if ((flag_sanitize & SANITIZE_UNDEFINED)
+ && !processing_template_decl
+ && current_function_decl != 0
+ && (doing_div_or_mod || doing_shift))
+ {
+ /* OP0 and/or OP1 might have side-effects. */
+ op0 = cp_save_expr (op0);
+ op1 = cp_save_expr (op1);
+ op0 = maybe_constant_value (fold_non_dependent_expr_sfinae (op0,
+ tf_none));
+ op1 = maybe_constant_value (fold_non_dependent_expr_sfinae (op1,
+ tf_none));
+ if (doing_div_or_mod)
+ {
+ /* For diagnostics we want to use the promoted types without
+ shorten_binary_op. So convert the arguments to the
+ original result_type. */
+ tree cop0 = op0;
+ tree cop1 = op1;
+ if (orig_type != NULL && result_type != orig_type)
+ {
+ cop0 = cp_convert (orig_type, op0, complain);
+ cop1 = cp_convert (orig_type, op1, complain);
+ }
+ instrument_expr = ubsan_instrument_division (location, cop0, cop1);
+ }
+ else if (doing_shift)
+ instrument_expr = ubsan_instrument_shift (location, code, op0, op1);
+ }
+
result = build2 (resultcode, build_type, op0, op1);
result = fold_if_not_in_template (result);
if (final_type != 0)
@@ -4872,6 +4924,10 @@ cp_build_binary_op (location_t location,
&& !TREE_OVERFLOW_P (op1))
overflow_warning (location, result);
+ if ((flag_sanitize & SANITIZE_UNDEFINED) && instrument_expr != NULL)
+ result = fold_build2 (COMPOUND_EXPR, TREE_TYPE (result),
+ instrument_expr, result);
+
return result;
}
@@ -4894,7 +4950,8 @@ build_x_vec_perm_expr (location_t loc,
of pointer PTROP and integer INTOP. */
static tree
-cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
+cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop,
+ tsubst_flags_t complain)
{
tree res_type = TREE_TYPE (ptrop);
@@ -4906,7 +4963,8 @@ cp_pointer_int_sum (enum tree_code resultcode, tree ptrop, tree intop)
complete_type (TREE_TYPE (res_type));
return pointer_int_sum (input_location, resultcode, ptrop,
- fold_if_not_in_template (intop));
+ fold_if_not_in_template (intop),
+ complain & tf_warning_or_error);
}
/* Return a tree for the difference of pointers OP0 and OP1.
diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c
index 79329397a8b..8882816666c 100644
--- a/gcc/cp/typeck2.c
+++ b/gcc/cp/typeck2.c
@@ -1761,7 +1761,14 @@ build_functional_cast (tree exp, tree parms, tsubst_flags_t complain)
return error_mark_node;
if (TREE_CODE (exp) == TYPE_DECL)
- type = TREE_TYPE (exp);
+ {
+ type = TREE_TYPE (exp);
+
+ if (complain & tf_warning
+ && TREE_DEPRECATED (type)
+ && DECL_ARTIFICIAL (exp))
+ warn_deprecated_use (type, NULL_TREE);
+ }
else
type = exp;
diff --git a/gcc/cp/vtable-class-hierarchy.c b/gcc/cp/vtable-class-hierarchy.c
new file mode 100644
index 00000000000..78611a83264
--- /dev/null
+++ b/gcc/cp/vtable-class-hierarchy.c
@@ -0,0 +1,1342 @@
+/* Copyright (C) 2012-2013 Free Software Foundation, Inc.
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Virtual Table Pointer Security Pass - Detect corruption of vtable pointers
+ before using them for virtual method dispatches. */
+
+/* This file is part of the vtable security feature implementation.
+ The vtable security feature is designed to detect when a virtual
+ call is about to be made through an invalid vtable pointer
+ (possibly due to data corruption or malicious attacks). The
+ compiler finds every virtual call, and inserts a verification call
+ before the virtual call. The verification call takes the actual
+ vtable pointer value in the object through which the virtual call
+ is being made, and compares the vtable pointer against a set of all
+ valid vtable pointers that the object could contain (this set is
+ based on the declared type of the object). If the pointer is in
+ the valid set, execution is allowed to continue; otherwise the
+ program is halted.
+
+ There are several pieces needed in order to make this work: 1. For
+ every virtual class in the program (i.e. a class that contains
+ virtual methods), we need to build the set of all possible valid
+ vtables that an object of that class could point to. This includes
+ vtables for any class(es) that inherit from the class under
+ consideration. 2. For every such data set we build up, we need a
+ way to find and reference the data set. This is complicated by the
+ fact that the real vtable addresses are not known until runtime,
+ when the program is loaded into memory, but we need to reference the
+ sets at compile time when we are inserting verification calls into
+ the program. 3. We need to find every virtual call in the program,
+ and insert the verification call (with the appropriate arguments)
+ before the virtual call. 4. We need some runtime library pieces:
+ the code to build up the data sets at runtime; the code to actually
+ perform the verification using the data sets; and some code to set
+ protections on the data sets, so they themselves do not become
+ hacker targets.
+
+ To find and reference the set of valid vtable pointers for any given
+ virtual class, we create a special global varible for each virtual
+ class. We refer to this as the "vtable map variable" for that
+ class. The vtable map variable has the type "void *", and is
+ initialized by the compiler to NULL. At runtime when the set of
+ valid vtable pointers for a virtual class, e.g. class Foo, is built,
+ the vtable map variable for class Foo is made to point to the set.
+ During compile time, when the compiler is inserting verification
+ calls into the program, it passes the vtable map variable for the
+ appropriate class to the verification call, so that at runtime the
+ verification call can find the appropriate data set.
+
+ The actual set of valid vtable pointers for a virtual class,
+ e.g. class Foo, cannot be built until runtime, when the vtables get
+ loaded into memory and their addresses are known. But the knowledge
+ about which vtables belong in which class' hierarchy is only known
+ at compile time. Therefore at compile time we collect class
+ hierarchy and vtable information about every virtual class, and we
+ generate calls to build up the data sets at runtime. To build the
+ data sets, we call one of the functions we add to the runtime
+ library, __VLTRegisterPair. __VLTRegisterPair takes two arguments,
+ a vtable map variable and the address of a vtable. If the vtable
+ map variable is currently NULL, it creates a new data set (hash
+ table), makes the vtable map variable point to the new data set, and
+ inserts the vtable address into the data set. If the vtable map
+ variable is not NULL, it just inserts the vtable address into the
+ data set. In order to make sure that our data sets are built before
+ any verification calls happen, we create a special constructor
+ initialization function for each compilation unit, give it a very
+ high initialization priority, and insert all of our calls to
+ __VLTRegisterPair into our special constructor initialization
+ function.
+
+ The vtable verification feature is controlled by the flag
+ '-fvtable-verify='. There are three flavors of this:
+ '-fvtable-verify=std', '-fvtable-verify=preinit', and
+ '-fvtable-verify=none'. If the option '-fvtable-verfy=preinit' is
+ used, then our constructor initialization function gets put into the
+ preinit array. This is necessary if there are data sets that need
+ to be built very early in execution. If the constructor
+ initialization function gets put into the preinit array, the we also
+ add calls to __VLTChangePermission at the beginning and end of the
+ function. The call at the beginning sets the permissions on the
+ data sets and vtable map variables to read/write, and the one at the
+ end makes them read-only. If the '-fvtable-verify=std' option is
+ used, the constructor initialization functions are executed at their
+ normal time, and the __VLTChangePermission calls are handled
+ differently (see the comments in libstdc++-v3/libsupc++/vtv_rts.cc).
+ The option '-fvtable-verify=none' turns off vtable verification.
+
+ This file contains code to find and record the class hierarchies for
+ the virtual classes in a program, and all the vtables associated
+ with each such class; to generate the vtable map variables; and to
+ generate the constructor initialization function (with the calls to
+ __VLTRegisterPair, and __VLTChangePermission). The main data
+ structures used for collecting the class hierarchy data and
+ building/maintaining the vtable map variable data are defined in
+ gcc/vtable-verify.h, because they are used both here and in
+ gcc/vtable-verify.c. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "cp-tree.h"
+#include "output.h"
+#include "cgraph.h"
+#include "tree-iterator.h"
+#include "vtable-verify.h"
+#include "gimple.h"
+
+static int num_calls_to_regset = 0;
+static int num_calls_to_regpair = 0;
+static int current_set_size;
+
+/* Mark these specially since they need to be stored in precompiled
+ header IR. */
+static GTY (()) vec<tree, va_gc> *vlt_saved_class_info;
+static GTY (()) tree vlt_register_pairs_fndecl = NULL_TREE;
+static GTY (()) tree vlt_register_set_fndecl = NULL_TREE;
+
+struct work_node {
+ struct vtv_graph_node *node;
+ struct work_node *next;
+};
+
+struct vtbl_map_node *vtable_find_or_create_map_decl (tree);
+
+/* As part of vtable verification the compiler generates and inserts
+ calls to __VLTVerifyVtablePointer, which is in libstdc++. This
+ function builds and initializes the function decl that is used
+ in generating those function calls.
+
+ In addition to __VLTVerifyVtablePointer there is also
+ __VLTVerifyVtablePointerDebug which can be used in place of
+ __VLTVerifyVtablePointer, and which takes extra parameters and
+ outputs extra information, to help debug problems. The debug
+ version of this function is generated and used if flag_vtv_debug is
+ true.
+
+ The signatures for these functions are:
+
+ void * __VLTVerifyVtablePointer (void **, void*);
+ void * __VLTVerifyVtablePointerDebug (void**, void *, char *, char *);
+*/
+
+void
+vtv_build_vtable_verify_fndecl (void)
+{
+ tree func_type = NULL_TREE;
+
+ if (verify_vtbl_ptr_fndecl != NULL_TREE
+ && TREE_CODE (verify_vtbl_ptr_fndecl) != ERROR_MARK)
+ return;
+
+ if (flag_vtv_debug)
+ {
+ func_type = build_function_type_list (const_ptr_type_node,
+ build_pointer_type (ptr_type_node),
+ const_ptr_type_node,
+ const_string_type_node,
+ const_string_type_node,
+ NULL_TREE);
+ verify_vtbl_ptr_fndecl =
+ build_lang_decl (FUNCTION_DECL,
+ get_identifier ("__VLTVerifyVtablePointerDebug"),
+ func_type);
+ }
+ else
+ {
+ func_type = build_function_type_list (const_ptr_type_node,
+ build_pointer_type (ptr_type_node),
+ const_ptr_type_node,
+ NULL_TREE);
+ verify_vtbl_ptr_fndecl =
+ build_lang_decl (FUNCTION_DECL,
+ get_identifier ("__VLTVerifyVtablePointer"),
+ func_type);
+ }
+
+ TREE_NOTHROW (verify_vtbl_ptr_fndecl) = 1;
+ DECL_ATTRIBUTES (verify_vtbl_ptr_fndecl)
+ = tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (verify_vtbl_ptr_fndecl));
+ DECL_PURE_P (verify_vtbl_ptr_fndecl) = 1;
+ TREE_PUBLIC (verify_vtbl_ptr_fndecl) = 1;
+ DECL_PRESERVE_P (verify_vtbl_ptr_fndecl) = 1;
+}
+
+/* As part of vtable verification the compiler generates and inserts
+ calls to __VLTRegisterSet and __VLTRegisterPair, which are in
+ libsupc++. This function builds and initializes the function decls
+ that are used in generating those function calls.
+
+ The signatures for these functions are:
+
+ void __VLTRegisterSetDebug (void **, const void *, std::size_t,
+ size_t, void **);
+
+ void __VLTRegisterSet (void **, const void *, std::size_t,
+ size_t, void **);
+
+ void __VLTRegisterPairDebug (void **, const void *, size_t,
+ const void *, const char *, const char *);
+
+ void __VLTRegisterPair (void **, const void *, size_t, const void *);
+*/
+
+static void
+init_functions (void)
+{
+ tree register_set_type;
+ tree register_pairs_type;
+
+ if (vlt_register_set_fndecl != NULL_TREE)
+ return;
+
+ gcc_assert (vlt_register_pairs_fndecl == NULL_TREE);
+ gcc_assert (vlt_register_set_fndecl == NULL_TREE);
+
+ /* Build function decl for __VLTRegisterSet*. */
+
+ register_set_type = build_function_type_list
+ (void_type_node,
+ build_pointer_type (ptr_type_node),
+ const_ptr_type_node,
+ size_type_node,
+ size_type_node,
+ build_pointer_type (ptr_type_node),
+ NULL_TREE);
+
+ if (flag_vtv_debug)
+ vlt_register_set_fndecl = build_lang_decl
+ (FUNCTION_DECL,
+ get_identifier ("__VLTRegisterSetDebug"),
+ register_set_type);
+ else
+ vlt_register_set_fndecl = build_lang_decl
+ (FUNCTION_DECL,
+ get_identifier ("__VLTRegisterSet"),
+ register_set_type);
+
+
+ TREE_NOTHROW (vlt_register_set_fndecl) = 1;
+ DECL_ATTRIBUTES (vlt_register_set_fndecl) =
+ tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (vlt_register_set_fndecl));
+ TREE_PUBLIC (vlt_register_set_fndecl) = 1;
+ DECL_PRESERVE_P (vlt_register_set_fndecl) = 1;
+ SET_DECL_LANGUAGE (vlt_register_set_fndecl, lang_cplusplus);
+
+ /* Build function decl for __VLTRegisterPair*. */
+
+ if (flag_vtv_debug)
+ {
+ register_pairs_type = build_function_type_list (void_type_node,
+ build_pointer_type
+ (ptr_type_node),
+ const_ptr_type_node,
+ size_type_node,
+ const_ptr_type_node,
+ const_string_type_node,
+ const_string_type_node,
+ NULL_TREE);
+
+ vlt_register_pairs_fndecl = build_lang_decl
+ (FUNCTION_DECL,
+ get_identifier ("__VLTRegisterPairDebug"),
+ register_pairs_type);
+ }
+ else
+ {
+ register_pairs_type = build_function_type_list (void_type_node,
+ build_pointer_type
+ (ptr_type_node),
+ const_ptr_type_node,
+ size_type_node,
+ const_ptr_type_node,
+ NULL_TREE);
+
+ vlt_register_pairs_fndecl = build_lang_decl
+ (FUNCTION_DECL,
+ get_identifier ("__VLTRegisterPair"),
+ register_pairs_type);
+ }
+
+ TREE_NOTHROW (vlt_register_pairs_fndecl) = 1;
+ DECL_ATTRIBUTES (vlt_register_pairs_fndecl) =
+ tree_cons (get_identifier ("leaf"), NULL,
+ DECL_ATTRIBUTES (vlt_register_pairs_fndecl));
+ TREE_PUBLIC (vlt_register_pairs_fndecl) = 1;
+ DECL_PRESERVE_P (vlt_register_pairs_fndecl) = 1;
+ SET_DECL_LANGUAGE (vlt_register_pairs_fndecl, lang_cplusplus);
+
+}
+
+/* This is a helper function for
+ vtv_compute_class_hierarchy_transitive_closure. It adds a
+ vtv_graph_node to the WORKLIST, which is a linked list of
+ seen-but-not-yet-processed nodes. INSERTED is a bitmap, one bit
+ per node, to help make sure that we don't insert a node into the
+ worklist more than once. Each node represents a class somewhere in
+ our class hierarchy information. Every node in the graph gets added
+ to the worklist exactly once and removed from the worklist exactly
+ once (when all of its children have been processed). */
+
+static void
+add_to_worklist (struct work_node **worklist, struct vtv_graph_node *node,
+ sbitmap inserted)
+{
+ struct work_node *new_work_node;
+
+ if (bitmap_bit_p (inserted, node->class_uid))
+ return;
+
+ new_work_node = XNEW (struct work_node);
+ new_work_node->next = *worklist;
+ new_work_node->node = node;
+ *worklist = new_work_node;
+
+ bitmap_set_bit (inserted, node->class_uid);
+}
+
+/* This is a helper function for
+ vtv_compute_class_hierarchy_transitive_closure. It goes through
+ the WORKLIST of class hierarchy nodes looking for a "leaf" node,
+ i.e. a node whose children in the hierarchy have all been
+ processed. When it finds the next leaf node, it removes it from
+ the linked list (WORKLIST) and returns the node. */
+
+static struct vtv_graph_node *
+find_and_remove_next_leaf_node (struct work_node **worklist)
+{
+ struct work_node *prev, *cur;
+ struct vtv_graph_node *ret_val = NULL;
+
+ for (prev = NULL, cur = *worklist; cur; prev = cur, cur = cur->next)
+ {
+ if ((cur->node->children).length() == cur->node->num_processed_children)
+ {
+ if (prev == NULL)
+ (*worklist) = cur->next;
+ else
+ prev->next = cur->next;
+
+ cur->next = NULL;
+ ret_val = cur->node;
+ free (cur);
+ return ret_val;
+ }
+ }
+
+ return NULL;
+}
+
+/* In our class hierarchy graph, each class node contains a bitmap,
+ with one bit for each class in the hierarchy. The bits are set for
+ classes that are descendants in the graph of the current node.
+ Initially the descendants bitmap is only set for immediate
+ descendants. This function traverses the class hierarchy graph,
+ bottom up, filling in the transitive closures for the descendants
+ as we rise up the graph. */
+
+void
+vtv_compute_class_hierarchy_transitive_closure (void)
+{
+ struct work_node *worklist = NULL;
+ sbitmap inserted = sbitmap_alloc (num_vtable_map_nodes);
+ unsigned i;
+ unsigned j;
+
+ /* Note: Every node in the graph gets added to the worklist exactly
+ once and removed from the worklist exactly once (when all of its
+ children have been processed). Each node's children edges are
+ followed exactly once, and each node's parent edges are followed
+ exactly once. So this algorithm is roughly O(V + 2E), i.e.
+ O(E + V). */
+
+ /* Set-up: */
+ /* Find all the "leaf" nodes in the graph, and add them to the worklist. */
+ bitmap_clear (inserted);
+ for (j = 0; j < num_vtable_map_nodes; ++j)
+ {
+ struct vtbl_map_node *cur = vtbl_map_nodes_vec[j];
+ if (cur->class_info
+ && ((cur->class_info->children).length() == 0)
+ && ! (bitmap_bit_p (inserted, cur->class_info->class_uid)))
+ add_to_worklist (&worklist, cur->class_info, inserted);
+ }
+
+ /* Main work: pull next leaf node off work list, process it, add its
+ parents to the worklist, where a 'leaf' node is one that has no
+ children, or all of its children have been processed. */
+ while (worklist)
+ {
+ struct vtv_graph_node *temp_node =
+ find_and_remove_next_leaf_node (&worklist);
+
+ gcc_assert (temp_node != NULL);
+ temp_node->descendants = sbitmap_alloc (num_vtable_map_nodes);
+ bitmap_clear (temp_node->descendants);
+ bitmap_set_bit (temp_node->descendants, temp_node->class_uid);
+ for (i = 0; i < (temp_node->children).length(); ++i)
+ bitmap_ior (temp_node->descendants, temp_node->descendants,
+ temp_node->children[i]->descendants);
+ for (i = 0; i < (temp_node->parents).length(); ++i)
+ {
+ temp_node->parents[i]->num_processed_children =
+ temp_node->parents[i]->num_processed_children + 1;
+ if (!bitmap_bit_p (inserted, temp_node->parents[i]->class_uid))
+ add_to_worklist (&worklist, temp_node->parents[i], inserted);
+ }
+ }
+}
+
+/* Keep track of which pairs we have already created __VLTRegisterPair
+ calls for, to prevent creating duplicate calls within the same
+ compilation unit. VTABLE_DECL is the var decl for the vtable of
+ the (descendant) class that we are adding to our class hierarchy
+ data. VPTR_ADDRESS is an expression for calculating the correct
+ offset into the vtable (VTABLE_DECL). It is the actual vtable
+ pointer address that will be stored in our list of valid vtable
+ pointers for BASE_CLASS. BASE_CLASS is the record_type node for
+ the base class to whose hiearchy we want to add
+ VPTR_ADDRESS. (VTABLE_DECL should be the vtable for BASE_CLASS or
+ one of BASE_CLASS' descendents. */
+
+static bool
+check_and_record_registered_pairs (tree vtable_decl, tree vptr_address,
+ tree base_class)
+{
+ unsigned offset;
+ struct vtbl_map_node *base_vtable_map_node;
+ bool inserted_something = false;
+
+
+ if (TREE_CODE (vptr_address) == ADDR_EXPR
+ && TREE_CODE (TREE_OPERAND (vptr_address, 0)) == MEM_REF)
+ vptr_address = TREE_OPERAND (vptr_address, 0);
+
+ if (TREE_OPERAND_LENGTH (vptr_address) > 1)
+ offset = TREE_INT_CST_LOW (TREE_OPERAND (vptr_address, 1));
+ else
+ offset = 0;
+
+ base_vtable_map_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (base_class));
+
+ inserted_something = vtbl_map_node_registration_insert
+ (base_vtable_map_node,
+ vtable_decl,
+ offset);
+ return !inserted_something;
+}
+
+/* Given an IDENTIFIER_NODE, build and return a string literal based on it. */
+
+static tree
+build_string_from_id (tree identifier)
+{
+ int len;
+
+ gcc_assert (TREE_CODE (identifier) == IDENTIFIER_NODE);
+
+ len = IDENTIFIER_LENGTH (identifier);
+ return build_string_literal (len + 1, IDENTIFIER_POINTER (identifier));
+}
+
+/* A class may contain secondary vtables in it, for various reasons.
+ This function goes through the decl chain of a class record looking
+ for any fields that point to secondary vtables, and adding calls to
+ __VLTRegisterPair for the secondary vtable pointers.
+
+ BASE_CLASS_DECL_ARG is an expression for the address of the vtable
+ map variable for the BASE_CLASS (whose hierarchy we are currently
+ updating). BASE_CLASS is the record_type node for the base class.
+ RECORD_TYPE is the record_type node for the descendant class that
+ we are possibly adding to BASE_CLASS's hierarchy. BODY is the
+ function body for the constructor init function to which we are
+ adding our calls to __VLTRegisterPair. */
+
+static void
+register_construction_vtables (tree base_class, tree record_type,
+ vec<tree> *vtable_ptr_array)
+{
+ tree vtbl_var_decl;
+
+ if (TREE_CODE (record_type) != RECORD_TYPE)
+ return;
+
+ vtbl_var_decl = CLASSTYPE_VTABLES (record_type);
+
+ if (CLASSTYPE_VBASECLASSES (record_type))
+ {
+ tree vtt_decl;
+ bool already_registered = false;
+ tree val_vtbl_decl = NULL_TREE;
+
+ vtt_decl = DECL_CHAIN (vtbl_var_decl);
+
+ /* Check to see if we have found a VTT. Add its data if appropriate. */
+ if (vtt_decl)
+ {
+ tree values = DECL_INITIAL (vtt_decl);
+ if (TREE_ASM_WRITTEN (vtt_decl)
+ && values != NULL_TREE
+ && TREE_CODE (values) == CONSTRUCTOR
+ && TREE_CODE (TREE_TYPE (values)) == ARRAY_TYPE)
+ {
+ unsigned HOST_WIDE_INT cnt;
+ constructor_elt *ce;
+
+ /* Loop through the initialization values for this
+ vtable to get all the correct vtable pointer
+ addresses that we need to add to our set of valid
+ vtable pointers for the current base class. This may
+ result in adding more than just the element assigned
+ to the primary vptr of the class, so we may end up
+ with more vtable pointers than are strictly
+ necessary. */
+
+ for (cnt = 0;
+ vec_safe_iterate (CONSTRUCTOR_ELTS (values),
+ cnt, &ce);
+ cnt++)
+ {
+ tree value = ce->value;
+
+ /* Search for the ADDR_EXPR operand within the value. */
+
+ while (value
+ && TREE_OPERAND (value, 0)
+ && TREE_CODE (TREE_OPERAND (value, 0)) == ADDR_EXPR)
+ value = TREE_OPERAND (value, 0);
+
+ /* The VAR_DECL for the vtable should be the first
+ argument of the ADDR_EXPR, which is the first
+ argument of value.*/
+
+ if (TREE_OPERAND (value, 0))
+ val_vtbl_decl = TREE_OPERAND (value, 0);
+
+ while (TREE_CODE (val_vtbl_decl) != VAR_DECL
+ && TREE_OPERAND (val_vtbl_decl, 0))
+ val_vtbl_decl = TREE_OPERAND (val_vtbl_decl, 0);
+
+ gcc_assert (TREE_CODE (val_vtbl_decl) == VAR_DECL);
+
+ /* Check to see if we already have this vtable pointer in
+ our valid set for this base class. */
+
+ already_registered = check_and_record_registered_pairs
+ (val_vtbl_decl,
+ value,
+ base_class);
+
+ if (already_registered)
+ continue;
+
+ /* Add this vtable pointer to our set of valid
+ pointers for the base class. */
+
+ vtable_ptr_array->safe_push (value);
+ current_set_size++;
+ }
+ }
+ }
+ }
+}
+
+/* This function iterates through all the vtables it can find from the
+ BINFO of a class, to make sure we have found ALL of the vtables
+ that an object of that class could point to. Generate calls to
+ __VLTRegisterPair for those vtable pointers that we find.
+
+ BINFO is the tree_binfo node for the BASE_CLASS. BODY is the
+ function body for the constructor init function to which we are
+ adding calls to __VLTRegisterPair. ARG1 is an expression for the
+ address of the vtable map variable (for the BASE_CLASS), that will
+ point to the updated data set. BASE_CLASS is the record_type node
+ for the base class whose set of valid vtable pointers we are
+ updating. STR1 and STR2 are all debugging information, to be passed
+ as parameters to __VLTRegisterPairDebug. STR1 represents the name
+ of the vtable map variable to be updated by the call. Similarly,
+ STR2 represents the name of the class whose vtable pointer is being
+ added to the hierarchy. */
+
+static void
+register_other_binfo_vtables (tree binfo, tree base_class,
+ vec<tree> *vtable_ptr_array)
+{
+ unsigned ix;
+ tree base_binfo;
+ tree vtable_decl;
+ bool already_registered;
+
+ if (binfo == NULL_TREE)
+ return;
+
+ for (ix = 0; BINFO_BASE_ITERATE (binfo, ix, base_binfo); ix++)
+ {
+ if ((!BINFO_PRIMARY_P (base_binfo)
+ || BINFO_VIRTUAL_P (base_binfo))
+ && (vtable_decl = get_vtbl_decl_for_binfo (base_binfo)))
+ {
+ tree vtable_address = build_vtbl_address (base_binfo);
+
+ already_registered = check_and_record_registered_pairs
+ (vtable_decl,
+ vtable_address,
+ base_class);
+ if (!already_registered)
+ {
+ vtable_ptr_array->safe_push (vtable_address);
+ current_set_size++;
+ }
+ }
+
+ register_other_binfo_vtables (base_binfo, base_class, vtable_ptr_array);
+ }
+}
+
+/* The set of valid vtable pointers for any given class are stored in
+ a hash table. For reasons of efficiency, that hash table size is
+ always a power of two. In order to try to prevent re-sizing the
+ hash tables very often, we pass __VLTRegisterPair an initial guess
+ as to the number of entries the hashtable will eventually need
+ (rounded up to the nearest power of two). This function takes the
+ class information we have collected for a particular class,
+ CLASS_NODE, and calculates the hash table size guess. */
+
+static int
+guess_num_vtable_pointers (struct vtv_graph_node *class_node)
+{
+ tree vtbl;
+ int total_num_vtbls = 0;
+ int num_vtbls_power_of_two = 1;
+ unsigned i;
+
+ for (i = 0; i < num_vtable_map_nodes; ++i)
+ if (bitmap_bit_p (class_node->descendants, i))
+ {
+ tree class_type = vtbl_map_nodes_vec[i]->class_info->class_type;
+ for (vtbl = CLASSTYPE_VTABLES (class_type); vtbl;
+ vtbl = DECL_CHAIN (vtbl))
+ {
+ total_num_vtbls++;
+ if (total_num_vtbls > num_vtbls_power_of_two)
+ num_vtbls_power_of_two <<= 1;
+ }
+ }
+ return num_vtbls_power_of_two;
+}
+
+/* A simple hash function on strings */
+/* Be careful about changing this routine. The values generated will
+ be stored in the calls to InitSet. So, changing this routine may
+ cause a binary incompatibility. */
+
+static uint32_t
+vtv_string_hash (const char *in)
+{
+ const char *s = in;
+ uint32_t h = 0;
+
+ gcc_assert (in != NULL);
+ for ( ; *s; ++s)
+ h = 5 * h + *s;
+ return h;
+}
+
+static char *
+get_log_file_name (const char *fname)
+{
+ const char *tmp_dir = concat (dump_dir_name, NULL);
+ char *full_name;
+ int dir_len;
+ int fname_len;
+
+ dir_len = strlen (tmp_dir);
+ fname_len = strlen (fname);
+
+ full_name = XNEWVEC (char, dir_len + fname_len + 1);
+ strcpy (full_name, tmp_dir);
+ strcpy (full_name + dir_len, fname);
+
+ return full_name;
+}
+
+static void
+write_out_current_set_data (tree base_class, int set_size)
+{
+ static int class_data_log_fd = -1;
+ char buffer[1024];
+ int bytes_written __attribute__ ((unused));
+ char *file_name = get_log_file_name ("vtv_class_set_sizes.log");
+
+ if (class_data_log_fd == -1)
+ class_data_log_fd = open (file_name,
+ O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
+
+ if (class_data_log_fd == -1)
+ {
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_class_set_sizes.log%>: %m");
+ return;
+ }
+
+ snprintf (buffer, sizeof (buffer), "%s %d\n",
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (base_class))),
+ set_size);
+ bytes_written = write (class_data_log_fd, buffer, strlen (buffer));
+}
+
+static tree
+build_key_buffer_arg (tree base_ptr_var_decl)
+{
+ const int key_type_fixed_size = 8;
+ uint32_t len1 = IDENTIFIER_LENGTH (DECL_NAME (base_ptr_var_decl));
+ uint32_t hash_value = vtv_string_hash (IDENTIFIER_POINTER
+ (DECL_NAME (base_ptr_var_decl)));
+ void *key_buffer = xmalloc (len1 + key_type_fixed_size);
+ uint32_t *value_ptr = (uint32_t *) key_buffer;
+ tree ret_value;
+
+ /* Set the len and hash for the string. */
+ *value_ptr = len1;
+ value_ptr++;
+ *value_ptr = hash_value;
+
+ /* Now copy the string representation of the vtbl map name... */
+ memcpy ((char *) key_buffer + key_type_fixed_size,
+ IDENTIFIER_POINTER (DECL_NAME (base_ptr_var_decl)),
+ len1);
+
+ /* ... and build a string literal from it. This will make a copy
+ so the key_bufffer is not needed anymore after this. */
+ ret_value = build_string_literal (len1 + key_type_fixed_size,
+ (char *) key_buffer);
+ free (key_buffer);
+ return ret_value;
+}
+
+static void
+insert_call_to_register_set (tree class_name,
+ vec<tree> *vtbl_ptr_array, tree body, tree arg1,
+ tree arg2, tree size_hint_arg)
+{
+ tree call_expr;
+ int num_args = vtbl_ptr_array->length();
+ char *array_arg_name = ACONCAT (("__vptr_array_",
+ IDENTIFIER_POINTER (class_name), NULL));
+ tree array_arg_type = build_array_type_nelts (build_pointer_type
+ (build_pointer_type
+ (void_type_node)),
+ num_args);
+ tree array_arg = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ get_identifier (array_arg_name),
+ array_arg_type);
+ int k;
+
+ vec<constructor_elt, va_gc> *array_elements;
+ vec_alloc (array_elements, num_args);
+
+ tree initial = NULL_TREE;
+ tree arg3 = NULL_TREE;
+
+ TREE_PUBLIC (array_arg) = 0;
+ DECL_EXTERNAL (array_arg) = 0;
+ TREE_STATIC (array_arg) = 1;
+ DECL_ARTIFICIAL (array_arg) = 0;
+ TREE_READONLY (array_arg) = 1;
+ DECL_IGNORED_P (array_arg) = 0;
+ DECL_PRESERVE_P (array_arg) = 0;
+ DECL_VISIBILITY (array_arg) = VISIBILITY_HIDDEN;
+
+ for (k = 0; k < num_args; ++k)
+ {
+ CONSTRUCTOR_APPEND_ELT (array_elements, NULL_TREE, (*vtbl_ptr_array)[k]);
+ }
+
+ initial = build_constructor (TREE_TYPE (array_arg), array_elements);
+
+ TREE_CONSTANT (initial) = 1;
+ TREE_STATIC (initial) = 1;
+ DECL_INITIAL (array_arg) = initial;
+ relayout_decl (array_arg);
+ varpool_finalize_decl (array_arg);
+
+ arg3 = build1 (ADDR_EXPR, TYPE_POINTER_TO (TREE_TYPE (array_arg)), array_arg);
+
+ TREE_TYPE (arg3) = build_pointer_type (TREE_TYPE (array_arg));
+
+ call_expr = build_call_expr (vlt_register_set_fndecl, 5, arg1,
+ arg2, /* set_symbol_key */
+ size_hint_arg, build_int_cst (size_type_node,
+ num_args),
+ arg3);
+ append_to_statement_list (call_expr, &body);
+ num_calls_to_regset++;
+}
+
+static void
+insert_call_to_register_pair (vec<tree> *vtbl_ptr_array, tree arg1,
+ tree arg2, tree size_hint_arg, tree str1,
+ tree str2, tree body)
+{
+ tree call_expr;
+ int num_args = vtbl_ptr_array->length();
+ tree vtable_address = NULL_TREE;
+
+ if (num_args == 0)
+ vtable_address = build_int_cst (build_pointer_type (void_type_node), 0);
+ else
+ vtable_address = (*vtbl_ptr_array)[0];
+
+ if (flag_vtv_debug)
+ call_expr = build_call_expr (vlt_register_pairs_fndecl, 6, arg1, arg2,
+ size_hint_arg, vtable_address, str1, str2);
+ else
+ call_expr = build_call_expr (vlt_register_pairs_fndecl, 4, arg1, arg2,
+ size_hint_arg, vtable_address);
+
+ append_to_statement_list (call_expr, &body);
+ num_calls_to_regpair++;
+}
+
+static void
+output_set_info (tree record_type, vec<tree> vtbl_ptr_array)
+{
+ static int vtv_debug_log_fd = -1;
+ char buffer[1024];
+ int bytes_written __attribute__ ((unused));
+ int array_len = vtbl_ptr_array.length();
+ const char *class_name =
+ IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (record_type)));
+ char *file_name = get_log_file_name ("vtv_set_ptr_data.log");
+
+ if (vtv_debug_log_fd == -1)
+ vtv_debug_log_fd = open (file_name,
+ O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
+ if (vtv_debug_log_fd == -1)
+ {
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_set_ptr_data.log%>: %m");
+ return;
+ }
+
+ for (int i = 0; i < array_len; ++i)
+ {
+ const char *vptr_name = "unknown";
+ int vptr_offset = 0;
+
+ if (TREE_CODE (vtbl_ptr_array[i]) == POINTER_PLUS_EXPR)
+ {
+ tree arg0 = TREE_OPERAND (vtbl_ptr_array[i], 0);
+ tree arg1 = TREE_OPERAND (vtbl_ptr_array[i], 1);
+
+ if (TREE_CODE (arg0) == ADDR_EXPR)
+ arg0 = TREE_OPERAND (arg0, 0);
+
+ if (TREE_CODE (arg0) == VAR_DECL)
+ vptr_name = IDENTIFIER_POINTER (DECL_NAME (arg0));
+
+ if (TREE_CODE (arg1) == INTEGER_CST)
+ vptr_offset = TREE_INT_CST_LOW (arg1);
+ }
+
+ snprintf (buffer, sizeof (buffer), "%s %s %s + %d\n",
+ main_input_filename, class_name, vptr_name, vptr_offset);
+ bytes_written = write (vtv_debug_log_fd, buffer, strlen(buffer));
+ }
+
+}
+
+/* This function goes through our internal class hierarchy & vtable
+ pointer data structure and outputs calls to __VLTRegisterPair for
+ every class-vptr pair (for those classes whose vtable would be
+ output in the current compilation unit). These calls get put into
+ our constructor initialization function. BODY is the function
+ body, so far, of our constructor initialization function, to which we
+ add the calls. */
+
+static bool
+register_all_pairs (tree body)
+{
+ bool registered_at_least_one = false;
+ vec<tree> *vtbl_ptr_array = NULL;
+ unsigned j;
+
+ for (j = 0; j < num_vtable_map_nodes; ++j)
+ {
+ struct vtbl_map_node *current = vtbl_map_nodes_vec[j];
+ unsigned i = 0;
+ tree base_class = current->class_info->class_type;
+ tree base_ptr_var_decl = current->vtbl_map_decl;
+ tree arg1;
+ tree arg2;
+ tree new_type;
+ tree str1 = NULL_TREE;
+ tree str2 = NULL_TREE;
+ size_t size_hint;
+ tree size_hint_arg;
+
+ gcc_assert (current->class_info != NULL);
+
+
+ if (flag_vtv_debug)
+ str1 = build_string_from_id (DECL_NAME (base_ptr_var_decl));
+
+ new_type = build_pointer_type (TREE_TYPE (base_ptr_var_decl));
+ arg1 = build1 (ADDR_EXPR, new_type, base_ptr_var_decl);
+
+ /* We need a fresh vector for each iteration. */
+ if (vtbl_ptr_array)
+ vec_free (vtbl_ptr_array);
+
+ vec_alloc (vtbl_ptr_array, 10);
+
+ for (i = 0; i < num_vtable_map_nodes; ++i)
+ if (bitmap_bit_p (current->class_info->descendants, i))
+ {
+ struct vtbl_map_node *vtbl_class_node = vtbl_map_nodes_vec[i];
+ tree class_type = vtbl_class_node->class_info->class_type;
+
+ if (class_type
+ && (TREE_CODE (class_type) == RECORD_TYPE))
+ {
+ bool already_registered;
+
+ tree binfo = TYPE_BINFO (class_type);
+ tree vtable_decl;
+ bool vtable_should_be_output = false;
+
+ vtable_decl = CLASSTYPE_VTABLES (class_type);
+
+ /* Handle main vtable for this class. */
+
+ if (vtable_decl)
+ {
+ vtable_should_be_output = TREE_ASM_WRITTEN (vtable_decl);
+ str2 = build_string_from_id (DECL_NAME (vtable_decl));
+ }
+
+ if (vtable_decl && vtable_should_be_output)
+ {
+ tree vtable_address = build_vtbl_address (binfo);
+
+ already_registered = check_and_record_registered_pairs
+ (vtable_decl,
+ vtable_address,
+ base_class);
+
+
+ if (!already_registered)
+ {
+ vtbl_ptr_array->safe_push (vtable_address);
+
+ /* Find and handle any 'extra' vtables associated
+ with this class, via virtual inheritance. */
+ register_construction_vtables (base_class, class_type,
+ vtbl_ptr_array);
+
+ /* Find and handle any 'extra' vtables associated
+ with this class, via multiple inheritance. */
+ register_other_binfo_vtables (binfo, base_class,
+ vtbl_ptr_array);
+ }
+ }
+ }
+ }
+ current_set_size = vtbl_ptr_array->length();
+
+ /* Sometimes we need to initialize the set symbol even if we are
+ not adding any vtable pointers to the set in the current
+ compilation unit. In that case, we need to initialize the
+ set to our best guess as to what the eventual size of the set
+ hash table will be (to prevent having to re-size the hash
+ table later). */
+
+ size_hint = guess_num_vtable_pointers (current->class_info);
+
+ /* If we have added vtable pointers to the set in this
+ compilation unit, adjust the size hint for the set's hash
+ table appropriately. */
+ if (vtbl_ptr_array->length() > 0)
+ {
+ unsigned len = vtbl_ptr_array->length();
+ while ((size_t) len > size_hint)
+ size_hint <<= 1;
+ }
+ size_hint_arg = build_int_cst (size_type_node, size_hint);
+
+ /* Get the key-buffer argument. */
+ arg2 = build_key_buffer_arg (base_ptr_var_decl);
+
+ if (str2 == NULL_TREE)
+ str2 = build_string_literal (strlen ("unknown") + 1,
+ "unknown");
+
+ if (flag_vtv_debug)
+ output_set_info (current->class_info->class_type,
+ *vtbl_ptr_array);
+
+ if (vtbl_ptr_array->length() > 1)
+ {
+ insert_call_to_register_set (current->class_name,
+ vtbl_ptr_array, body, arg1, arg2,
+ size_hint_arg);
+ registered_at_least_one = true;
+ }
+ else
+ {
+
+ if (vtbl_ptr_array->length() > 0
+ || (current->is_used
+ || (current->registered.size() > 0)))
+ {
+ insert_call_to_register_pair (vtbl_ptr_array,
+ arg1, arg2, size_hint_arg, str1,
+ str2, body);
+ registered_at_least_one = true;
+ }
+ }
+
+ if (flag_vtv_counts && current_set_size > 0)
+ write_out_current_set_data (base_class, current_set_size);
+
+ }
+
+ return registered_at_least_one;
+}
+
+/* Given a tree containing a class type (CLASS_TYPE), this function
+ finds and returns the class hierarchy node for that class in our
+ data structure. */
+
+static struct vtv_graph_node *
+find_graph_node (tree class_type)
+{
+ struct vtbl_map_node *vtbl_node;
+
+ vtbl_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (class_type));
+ if (vtbl_node)
+ return vtbl_node->class_info;
+
+ return NULL;
+}
+
+/* Add base class/derived class pair to our internal class hierarchy
+ data structure. BASE_NODE is our vtv_graph_node that corresponds
+ to a base class. DERIVED_NODE is our vtv_graph_node that
+ corresponds to a class that is a descendant of the base class
+ (possibly the base class itself). */
+
+static void
+add_hierarchy_pair (struct vtv_graph_node *base_node,
+ struct vtv_graph_node *derived_node)
+{
+ (base_node->children).safe_push (derived_node);
+ (derived_node->parents).safe_push (base_node);
+}
+
+/* This functions adds a new base class/derived class relationship to
+ our class hierarchy data structure. Both parameters are trees
+ representing the class types, i.e. RECORD_TYPE trees.
+ DERIVED_CLASS can be the same as BASE_CLASS. */
+
+static void
+update_class_hierarchy_information (tree base_class,
+ tree derived_class)
+{
+ struct vtv_graph_node *base_node = find_graph_node (base_class);
+ struct vtv_graph_node *derived_node = find_graph_node (derived_class);
+
+ add_hierarchy_pair (base_node, derived_node);
+}
+
+
+static void
+write_out_vtv_count_data (void)
+{
+ static int vtv_count_log_fd = -1;
+ char buffer[1024];
+ int unused_vtbl_map_vars = 0;
+ int bytes_written __attribute__ ((unused));
+ char *file_name = get_log_file_name ("vtv_count_data.log");
+
+ if (vtv_count_log_fd == -1)
+ vtv_count_log_fd = open (file_name,
+ O_WRONLY | O_APPEND | O_CREAT, S_IRWXU);
+ if (vtv_count_log_fd == -1)
+ {
+ warning_at (UNKNOWN_LOCATION, 0,
+ "unable to open log file %<vtv_count_data.log%>: %m");
+ return;
+ }
+
+ for (unsigned i = 0; i < num_vtable_map_nodes; ++i)
+ {
+ struct vtbl_map_node *current = vtbl_map_nodes_vec[i];
+ if (!current->is_used
+ && current->registered.size() == 0)
+ unused_vtbl_map_vars++;
+ }
+
+ snprintf (buffer, sizeof (buffer), "%s %d %d %d %d %d\n",
+ main_input_filename, total_num_virtual_calls,
+ total_num_verified_vcalls, num_calls_to_regset,
+ num_calls_to_regpair, unused_vtbl_map_vars);
+
+ bytes_written = write (vtv_count_log_fd, buffer, strlen (buffer));
+}
+
+/* This function calls register_all_pairs, which actually generates
+ all the calls to __VLTRegisterPair (in the verification constructor
+ init function). It also generates the calls to
+ __VLTChangePermission, if the verification constructor init
+ function is going into the preinit array. INIT_ROUTINE_BODY is
+ the body of our constructior initialization function, to which we
+ add our function calls.*/
+
+bool
+vtv_register_class_hierarchy_information (tree init_routine_body)
+{
+ bool registered_something = false;
+
+ init_functions ();
+
+ if (num_vtable_map_nodes == 0)
+ return false;
+
+ /* Add class hierarchy pairs to the vtable map data structure. */
+ registered_something = register_all_pairs (init_routine_body);
+
+ if (flag_vtv_counts)
+ write_out_vtv_count_data ();
+
+ return registered_something;
+}
+
+
+/* Generate the special constructor function that calls
+ __VLTChangePermission and __VLTRegisterPairs, and give it a very
+ high initialization priority. */
+
+void
+vtv_generate_init_routine (void)
+{
+ tree init_routine_body;
+ bool vtable_classes_found = false;
+
+ push_lang_context (lang_name_c);
+
+ /* The priority for this init function (constructor) is carefully
+ chosen so that it will happen after the calls to unprotect the
+ memory used for vtable verification and before the memory is
+ protected again. */
+ init_routine_body = vtv_start_verification_constructor_init_function ();
+
+ vtable_classes_found =
+ vtv_register_class_hierarchy_information (init_routine_body);
+
+ if (vtable_classes_found)
+ {
+ tree vtv_fndecl =
+ vtv_finish_verification_constructor_init_function (init_routine_body);
+ TREE_STATIC (vtv_fndecl) = 1;
+ TREE_USED (vtv_fndecl) = 1;
+ DECL_PRESERVE_P (vtv_fndecl) = 1;
+ if (flag_vtable_verify == VTV_PREINIT_PRIORITY)
+ DECL_STATIC_CONSTRUCTOR (vtv_fndecl) = 0;
+
+ gimplify_function_tree (vtv_fndecl);
+ cgraph_add_new_function (vtv_fndecl, false);
+
+ cgraph_process_new_functions ();
+
+ if (flag_vtable_verify == VTV_PREINIT_PRIORITY)
+ assemble_vtv_preinit_initializer (vtv_fndecl);
+
+ }
+ pop_lang_context ();
+}
+
+/* This funtion takes a tree containing a class type (BASE_TYPE), and
+ it either finds the existing vtbl_map_node for that class in our
+ data structure, or it creates a new node and adds it to the data
+ structure if there is not one for the class already. As part of
+ this process it also creates the global vtable map variable for the
+ class. */
+
+struct vtbl_map_node *
+vtable_find_or_create_map_decl (tree base_type)
+{
+ char *var_name = NULL;
+ struct vtbl_map_node *vtable_map_node = NULL;
+
+ /* Verify the type has an associated vtable. */
+ if (!TYPE_BINFO (base_type) || !BINFO_VTABLE (TYPE_BINFO (base_type)))
+ return NULL;
+
+ /* Create map lookup symbol for base class */
+ var_name = get_mangled_vtable_map_var_name (base_type);
+
+ /* We've already created the variable; just look it. */
+ vtable_map_node = vtbl_map_get_node (TYPE_MAIN_VARIANT (base_type));
+
+ if (!vtable_map_node || (vtable_map_node->vtbl_map_decl == NULL_TREE))
+ {
+ /* If we haven't already created the *__vtable_map global
+ variable for this class, do so now, and add it to the
+ varpool, to make sure it gets saved and written out. */
+
+ tree var_decl = NULL;
+ tree var_type = build_pointer_type (void_type_node);
+ tree initial_value = integer_zero_node;
+
+ var_decl = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ get_identifier (var_name), var_type);
+
+ DECL_EXTERNAL (var_decl) = 0;
+ TREE_STATIC (var_decl) = 1;
+ DECL_VISIBILITY (var_decl) = VISIBILITY_HIDDEN;
+ SET_DECL_ASSEMBLER_NAME (var_decl, get_identifier (var_name));
+ DECL_ARTIFICIAL (var_decl) = 1;
+ /* We cannot mark this variable as read-only because we want to be
+ able to write to it at runtime. */
+ TREE_READONLY (var_decl) = 0;
+ DECL_IGNORED_P (var_decl) = 1;
+ DECL_PRESERVE_P (var_decl) = 1;
+
+ /* Put these mmap variables in thr .vtable_map_vars section, so
+ we can find and protect them. */
+
+ DECL_SECTION_NAME (var_decl) = build_string (strlen (".vtable_map_vars"),
+ ".vtable_map_vars");
+ DECL_HAS_IMPLICIT_SECTION_NAME_P (var_decl) = true;
+ DECL_INITIAL (var_decl) = initial_value;
+
+ comdat_linkage (var_decl);
+
+ varpool_finalize_decl (var_decl);
+ if (!vtable_map_node)
+ vtable_map_node =
+ find_or_create_vtbl_map_node (TYPE_MAIN_VARIANT (base_type));
+ if (vtable_map_node->vtbl_map_decl == NULL_TREE)
+ vtable_map_node->vtbl_map_decl = var_decl;
+ }
+
+ gcc_assert (vtable_map_node);
+ return vtable_map_node;
+}
+
+/* This function is used to build up our class hierarchy data for a
+ particular class. TYPE is the record_type tree node for the
+ class. */
+
+static void
+vtv_insert_single_class_info (tree type)
+{
+ if (flag_vtable_verify)
+ {
+ tree binfo = TYPE_BINFO (type);
+ tree base_binfo;
+ struct vtbl_map_node *own_map;
+ int i;
+
+ /* First make sure to create the map for this record type. */
+ own_map = vtable_find_or_create_map_decl (type);
+ if (own_map == NULL)
+ return;
+
+ /* Go through the list of all base classes for the current
+ (derived) type, make sure the *__vtable_map global variable
+ for the base class exists, and add the base class/derived
+ class pair to the class hierarchy information we are
+ accumulating (for vtable pointer verification). */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ {
+ tree tree_val = BINFO_TYPE (base_binfo);
+ struct vtbl_map_node *vtable_map_node = NULL;
+
+ vtable_map_node = vtable_find_or_create_map_decl (tree_val);
+
+ if (vtable_map_node != NULL)
+ update_class_hierarchy_information (tree_val, type);
+ }
+ }
+}
+
+/* This function adds classes we are interested in to a list of
+ classes. RECORD is the record_type node for the class we are
+ adding to the list. */
+
+void
+vtv_save_class_info (tree record)
+{
+ if (!flag_vtable_verify || TREE_CODE (record) == UNION_TYPE)
+ return;
+
+ if (!vlt_saved_class_info)
+ vec_alloc (vlt_saved_class_info, 10);
+
+ gcc_assert (TREE_CODE (record) == RECORD_TYPE);
+
+ vec_safe_push (vlt_saved_class_info, record);
+}
+
+
+/* This function goes through the list of classes we saved and calls
+ vtv_insert_single_class_info on each one, to build up our class
+ hierarchy data structure. */
+
+void
+vtv_recover_class_info (void)
+{
+ tree current_class;
+ unsigned i;
+
+ if (vlt_saved_class_info)
+ {
+ for (i = 0; i < vlt_saved_class_info->length(); ++i)
+ {
+ current_class = (*vlt_saved_class_info)[i];
+ gcc_assert (TREE_CODE (current_class) == RECORD_TYPE);
+ vtv_insert_single_class_info (current_class);
+ }
+ }
+}
+
+#include "gt-cp-vtable-class-hierarchy.h"
diff --git a/gcc/cppbuiltin.c b/gcc/cppbuiltin.c
index 7ce01cb6934..2ceccdcce2b 100644
--- a/gcc/cppbuiltin.c
+++ b/gcc/cppbuiltin.c
@@ -90,7 +90,7 @@ define_builtin_macros_for_compilation_flags (cpp_reader *pfile)
cpp_define_formatted (pfile, "__PIE__=%d", flag_pie);
}
- if (flag_asan)
+ if (flag_sanitize & SANITIZE_ADDRESS)
cpp_define (pfile, "__SANITIZE_ADDRESS__");
if (optimize_size)
diff --git a/gcc/cprop.c b/gcc/cprop.c
index 6a6b5f1fd10..3518fd839ce 100644
--- a/gcc/cprop.c
+++ b/gcc/cprop.c
@@ -1913,23 +1913,42 @@ execute_rtl_cprop (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_cprop =
+namespace {
+
+const pass_data pass_data_rtl_cprop =
{
- {
- RTL_PASS,
- "cprop", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_rtl_cprop, /* gate */
- execute_rtl_cprop, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CPROP, /* tv_id */
- PROP_cfglayout, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "cprop", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_CPROP, /* tv_id */
+ PROP_cfglayout, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_rtl_cprop : public rtl_opt_pass
+{
+public:
+ pass_rtl_cprop(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_cprop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_rtl_cprop (ctxt_); }
+ bool gate () { return gate_rtl_cprop (); }
+ unsigned int execute () { return execute_rtl_cprop (); }
+
+}; // class pass_rtl_cprop
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_cprop (gcc::context *ctxt)
+{
+ return new pass_rtl_cprop (ctxt);
+}
diff --git a/gcc/cse.c b/gcc/cse.c
index 31a1cd03f66..b96af19f9e4 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -5381,7 +5381,7 @@ cse_insn (rtx insn)
&& CONST_INT_P (width)
&& INTVAL (width) < HOST_BITS_PER_WIDE_INT
&& ! (INTVAL (src_const)
- & ((HOST_WIDE_INT) (-1) << INTVAL (width))))
+ & (HOST_WIDE_INT_M1U << INTVAL (width))))
/* Exception: if the value is constant,
and it won't be truncated, record it. */
;
@@ -7449,27 +7449,45 @@ rest_of_handle_cse (void)
return 0;
}
-struct rtl_opt_pass pass_cse =
+namespace {
+
+const pass_data pass_data_cse =
{
- {
- RTL_PASS,
- "cse1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_cse, /* gate */
- rest_of_handle_cse, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CSE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "cse1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_CSE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+class pass_cse : public rtl_opt_pass
+{
+public:
+ pass_cse(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_cse, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_cse (); }
+ unsigned int execute () { return rest_of_handle_cse (); }
+
+}; // class pass_cse
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_cse (gcc::context *ctxt)
+{
+ return new pass_cse (ctxt);
+}
+
static bool
gate_handle_cse2 (void)
@@ -7511,27 +7529,45 @@ rest_of_handle_cse2 (void)
}
-struct rtl_opt_pass pass_cse2 =
+namespace {
+
+const pass_data pass_data_cse2 =
{
- {
- RTL_PASS,
- "cse2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_cse2, /* gate */
- rest_of_handle_cse2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CSE2, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "cse2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_CSE2, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+class pass_cse2 : public rtl_opt_pass
+{
+public:
+ pass_cse2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_cse2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_cse2 (); }
+ unsigned int execute () { return rest_of_handle_cse2 (); }
+
+}; // class pass_cse2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_cse2 (gcc::context *ctxt)
+{
+ return new pass_cse2 (ctxt);
+}
+
static bool
gate_handle_cse_after_global_opts (void)
{
@@ -7571,23 +7607,43 @@ rest_of_handle_cse_after_global_opts (void)
return 0;
}
-struct rtl_opt_pass pass_cse_after_global_opts =
+namespace {
+
+const pass_data pass_data_cse_after_global_opts =
{
- {
- RTL_PASS,
- "cse_local", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_cse_after_global_opts, /* gate */
- rest_of_handle_cse_after_global_opts, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CSE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "cse_local", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_CSE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_cse_after_global_opts : public rtl_opt_pass
+{
+public:
+ pass_cse_after_global_opts(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_cse_after_global_opts, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_cse_after_global_opts (); }
+ unsigned int execute () {
+ return rest_of_handle_cse_after_global_opts ();
+ }
+
+}; // class pass_cse_after_global_opts
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_cse_after_global_opts (gcc::context *ctxt)
+{
+ return new pass_cse_after_global_opts (ctxt);
+}
diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def
index 04d69ed9c3c..45b8eed85af 100644
--- a/gcc/dbgcnt.def
+++ b/gcc/dbgcnt.def
@@ -172,6 +172,8 @@ DEBUG_COUNTER (pre_insn)
DEBUG_COUNTER (treepre_insert)
DEBUG_COUNTER (tree_sra)
DEBUG_COUNTER (eipa_sra)
+DEBUG_COUNTER (vect_loop)
+DEBUG_COUNTER (vect_slp)
DEBUG_COUNTER (sched2_func)
DEBUG_COUNTER (sched_block)
DEBUG_COUNTER (sched_func)
diff --git a/gcc/dce.c b/gcc/dce.c
index 64ed81e35e8..fa22316b5cc 100644
--- a/gcc/dce.c
+++ b/gcc/dce.c
@@ -786,26 +786,44 @@ gate_ud_dce (void)
&& dbg_cnt (dce_ud);
}
-struct rtl_opt_pass pass_ud_rtl_dce =
+namespace {
+
+const pass_data pass_data_ud_rtl_dce =
{
- {
- RTL_PASS,
- "ud_dce", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_ud_dce, /* gate */
- rest_of_handle_ud_dce, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_DCE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "ud_dce", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_DCE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+class pass_ud_rtl_dce : public rtl_opt_pass
+{
+public:
+ pass_ud_rtl_dce(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_ud_rtl_dce, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_ud_dce (); }
+ unsigned int execute () { return rest_of_handle_ud_dce (); }
+
+}; // class pass_ud_rtl_dce
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_ud_rtl_dce (gcc::context *ctxt)
+{
+ return new pass_ud_rtl_dce (ctxt);
+}
+
/* -------------------------------------------------------------------------
Fast DCE functions
@@ -1201,22 +1219,40 @@ gate_fast_dce (void)
&& dbg_cnt (dce_fast);
}
-struct rtl_opt_pass pass_fast_rtl_dce =
+namespace {
+
+const pass_data pass_data_fast_rtl_dce =
{
- {
- RTL_PASS,
- "rtl_dce", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_fast_dce, /* gate */
- rest_of_handle_fast_dce, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_DCE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "rtl_dce", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_DCE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_fast_rtl_dce : public rtl_opt_pass
+{
+public:
+ pass_fast_rtl_dce(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_fast_rtl_dce, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_fast_dce (); }
+ unsigned int execute () { return rest_of_handle_fast_dce (); }
+
+}; // class pass_fast_rtl_dce
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_fast_rtl_dce (gcc::context *ctxt)
+{
+ return new pass_fast_rtl_dce (ctxt);
+}
diff --git a/gcc/defaults.h b/gcc/defaults.h
index 4f43f6f0067..3fa105d113d 100644
--- a/gcc/defaults.h
+++ b/gcc/defaults.h
@@ -1040,18 +1040,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#endif /* old constraint mechanism in use */
-/* Determine whether the entire c99 runtime
- is present in the runtime library. */
-#ifndef TARGET_C99_FUNCTIONS
-#define TARGET_C99_FUNCTIONS 0
-#endif
-
-/* Determine whether the target runtime library has
- a sincos implementation following the GNU extension. */
-#ifndef TARGET_HAS_SINCOS
-#define TARGET_HAS_SINCOS 0
-#endif
-
/* Determin whether the target runtime library is Bionic */
#ifndef TARGET_HAS_BIONIC
#define TARGET_HAS_BIONIC 0
diff --git a/gcc/df-core.c b/gcc/df-core.c
index d0e316c5c0f..95df1c1b056 100644
--- a/gcc/df-core.c
+++ b/gcc/df-core.c
@@ -746,26 +746,44 @@ gate_opt (void)
}
-struct rtl_opt_pass pass_df_initialize_opt =
-{
- {
- RTL_PASS,
- "dfinit", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_opt, /* gate */
- rest_of_handle_df_initialize, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_DF_SCAN, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_df_initialize_opt =
+{
+ RTL_PASS, /* type */
+ "dfinit", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_DF_SCAN, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_df_initialize_opt : public rtl_opt_pass
+{
+public:
+ pass_df_initialize_opt(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_df_initialize_opt, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_opt (); }
+ unsigned int execute () { return rest_of_handle_df_initialize (); }
+
+}; // class pass_df_initialize_opt
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_df_initialize_opt (gcc::context *ctxt)
+{
+ return new pass_df_initialize_opt (ctxt);
+}
+
static bool
gate_no_opt (void)
@@ -774,26 +792,44 @@ gate_no_opt (void)
}
-struct rtl_opt_pass pass_df_initialize_no_opt =
-{
- {
- RTL_PASS,
- "no-opt dfinit", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_no_opt, /* gate */
- rest_of_handle_df_initialize, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_DF_SCAN, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_df_initialize_no_opt =
+{
+ RTL_PASS, /* type */
+ "no-opt dfinit", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_DF_SCAN, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_df_initialize_no_opt : public rtl_opt_pass
+{
+public:
+ pass_df_initialize_no_opt(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_df_initialize_no_opt, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_no_opt (); }
+ unsigned int execute () { return rest_of_handle_df_initialize (); }
+
+}; // class pass_df_initialize_no_opt
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_df_initialize_no_opt (gcc::context *ctxt)
+{
+ return new pass_df_initialize_no_opt (ctxt);
+}
+
/* Free all the dataflow info and the DF structure. This should be
called from the df_finish macro which also NULLs the parm. */
@@ -822,26 +858,43 @@ rest_of_handle_df_finish (void)
}
-struct rtl_opt_pass pass_df_finish =
-{
- {
- RTL_PASS,
- "dfinish", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_df_finish, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_df_finish =
+{
+ RTL_PASS, /* type */
+ "dfinish", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_df_finish : public rtl_opt_pass
+{
+public:
+ pass_df_finish(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_df_finish, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_df_finish (); }
+
+}; // class pass_df_finish
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_df_finish (gcc::context *ctxt)
+{
+ return new pass_df_finish (ctxt);
+}
+
diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c
index 2ec96201459..295bbb6e045 100644
--- a/gcc/diagnostic.c
+++ b/gcc/diagnostic.c
@@ -33,6 +33,8 @@ along with GCC; see the file COPYING3. If not see
#include "diagnostic.h"
#include "diagnostic-color.h"
+#include <new> // For placement new.
+
#define pedantic_warning_kind(DC) \
((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
#define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
@@ -102,7 +104,7 @@ diagnostic_set_caret_max_width (diagnostic_context *context, int value)
{
/* One minus to account for the leading empty space. */
value = value ? value - 1
- : (isatty (fileno (context->printer->buffer->stream))
+ : (isatty (fileno (pp_buffer (context->printer)->stream))
? getenv_columns () - 1: INT_MAX);
if (value <= 0)
@@ -120,11 +122,7 @@ diagnostic_initialize (diagnostic_context *context, int n_opts)
/* Allocate a basic pretty-printer. Clients will replace this a
much more elaborated pretty-printer if they wish. */
context->printer = XNEW (pretty_printer);
- pp_construct (context->printer, NULL, 0);
- /* By default, diagnostics are sent to stderr. */
- context->printer->buffer->stream = stderr;
- /* By default, we emit prefixes once per message. */
- context->printer->wrapping.rule = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+ new (context->printer) pretty_printer ();
memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
context->some_warnings_are_errors = false;
@@ -247,6 +245,9 @@ diagnostic_build_prefix (diagnostic_context *context,
(s.file == NULL
? build_message_string ("%s%s:%s %s%s%s", locus_cs, progname, locus_ce,
text_cs, text, text_ce)
+ : !strcmp (s.file, N_("<built-in>"))
+ ? build_message_string ("%s%s:%s %s%s%s", locus_cs, s.file, locus_ce,
+ text_cs, text, text_ce)
: context->show_column
? build_message_string ("%s%s:%d:%d:%s %s%s%s", locus_cs, s.file, s.line,
s.column, locus_ce, text_cs, text, text_ce)
@@ -306,7 +307,7 @@ diagnostic_show_locus (diagnostic_context * context,
pp_newline (context->printer);
saved_prefix = pp_get_prefix (context->printer);
pp_set_prefix (context->printer, NULL);
- pp_character (context->printer, ' ');
+ pp_space (context->printer);
while (max_width > 0 && *line != '\0')
{
char c = *line == '\t' ? ' ' : *line;
@@ -554,7 +555,8 @@ default_diagnostic_finalizer (diagnostic_context *context ATTRIBUTE_UNUSED,
/* Interface to specify diagnostic kind overrides. Returns the
previous setting, or DK_UNSPECIFIED if the parameters are out of
- range. */
+ range. If OPTION_INDEX is zero, the new setting is for all the
+ diagnostics. */
diagnostic_t
diagnostic_classify_diagnostic (diagnostic_context *context,
int option_index,
@@ -563,7 +565,7 @@ diagnostic_classify_diagnostic (diagnostic_context *context,
{
diagnostic_t old_kind;
- if (option_index <= 0
+ if (option_index < 0
|| option_index >= context->n_opts
|| new_kind >= DK_LAST_DIAGNOSTIC_KIND)
return DK_UNSPECIFIED;
@@ -695,9 +697,8 @@ diagnostic_report_diagnostic (diagnostic_context *context,
/* This tests for #pragma diagnostic changes. */
if (context->n_classification_history > 0)
{
- int i;
/* FIXME: Stupid search. Optimize later. */
- for (i = context->n_classification_history - 1; i >= 0; i --)
+ for (int i = context->n_classification_history - 1; i >= 0; i --)
{
if (linemap_location_before_p
(line_table,
@@ -709,7 +710,9 @@ diagnostic_report_diagnostic (diagnostic_context *context,
i = context->classification_history[i].option;
continue;
}
- if (context->classification_history[i].option == diagnostic->option_index)
+ int option = context->classification_history[i].option;
+ /* The option 0 is for all the diagnostics. */
+ if (option == 0 || option == diagnostic->option_index)
{
diag_class = context->classification_history[i].kind;
if (diag_class != DK_UNSPECIFIED)
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index ae6d2b22aa1..cb38d370cee 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -211,7 +211,7 @@ diagnostic_inhibit_notes (diagnostic_context * context)
Zero means don't wrap lines. */
#define diagnostic_line_cutoff(DC) ((DC)->printer->wrapping.line_cutoff)
-#define diagnostic_flush_buffer(DC) pp_base_flush ((DC)->printer)
+#define diagnostic_flush_buffer(DC) pp_flush ((DC)->printer)
/* True if the last module or file in which a diagnostic was reported is
different from the current one. */
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 68d9426533f..151b7e9d56a 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -8618,8 +8618,9 @@ type is @code{long double}.
@end deftypefn
@deftypefn {Built-in Function} int __builtin_isinf_sign (...)
-Similar to @code{isinf}, except the return value is negative for
-an argument of @code{-Inf}. Note while the parameter list is an
+Similar to @code{isinf}, except the return value is -1 for
+an argument of @code{-Inf} and 1 for an argument of @code{+Inf}.
+Note while the parameter list is an
ellipsis, this function only accepts exactly one floating-point
argument. GCC treats this parameter as type-generic, which means it
does not do default promotion from float to double.
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index e05cbed9fea..82306251177 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -426,7 +426,11 @@ Necessary when modifying @command{gperf} input files, e.g.@:
@itemx Expect
@itemx Tcl
-Necessary to run the GCC testsuite; see the section on testing for details.
+Necessary to run the GCC testsuite; see the section on testing for
+details. Tcl 8.6 has a known regression in RE pattern handling that
+make parts of the testsuite fail. See
+@uref{http://core.tcl.tk/tcl/tktview/267b7e2334ee2e9de34c4b00d6e72e2f1997085f}
+for more information.
@item autogen version 5.5.4 (or later) and
@itemx guile version 1.4.1 (or later)
@@ -1032,6 +1036,18 @@ and for cross builds configured with @option{--with-sysroot}, and without
More documentation about multiarch can be found at
@uref{http://wiki.debian.org/Multiarch}.
+@item --enable-vtable-verify
+Specify whether to enable or disable the vtable verification feature.
+Enabling this feature causes libstdc++ to be built with its virtual calls
+in verifiable mode. This means that, when linked with libvtv, every
+virtual call in libstdc++ will verify the vtable pointer through which the
+call will be made before actually making the call. If not linked with libvtv,
+the verifier will call stub functions (in libstdc++ itself) and do nothing.
+If vtable verification is disabled, then libstdc++ is not built with its
+virtual calls in verifiable mode at all. However the libvtv library will
+still be built (see @option{--disable-libvtv} to turn off building libvtv).
+@option{--disable-vtable-verify} is the default.
+
@item --disable-multilib
Specify that multiple target
libraries to support different target variants, calling
@@ -1221,6 +1237,24 @@ ISA for floating-point arithmetics. You can select either @samp{sse} which
enables @option{-msse2} or @samp{avx} which enables @option{-mavx} by default.
This option is only supported on i386 and x86-64 targets.
+@item --with-nan=@var{encoding}
+On MIPS targets, set the default encoding convention to use for the
+special not-a-number (NaN) IEEE 754 floating-point data. The
+possibilities for @var{encoding} are:
+@table @code
+@item legacy
+Use the legacy encoding, as with the @option{-mnan=legacy} command-line
+option.
+@item 2008
+Use the 754-2008 encoding, as with the @option{-mnan=2008} command-line
+option.
+@end table
+To use this configuration option you must have an assembler version
+installed that supports the @option{-mnan=} command-line option too.
+In the absence of this configuration option the default convention is
+the legacy encoding, as when neither of the @option{-mnan=2008} and
+@option{-mnan=legacy} command-line options has been used.
+
@item --with-divide=@var{type}
Specify how the compiler should generate code for checking for
division by zero. This option is only supported on the MIPS target.
@@ -1400,6 +1434,10 @@ support for @code{libquadmath} on systems supporting it.
@item --disable-libgomp
Specify that the run-time libraries used by GOMP should not be built.
+@item --disable-libvtv
+Specify that the run-time libraries used by vtable verification
+should not be built.
+
@item --with-dwarf2
Specify that the compiler should
use DWARF 2 debugging information as the default.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c166c3a3f10..4b4181d3036 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -191,6 +191,8 @@ in the following sections.
-ftemplate-depth=@var{n} @gol
-fno-threadsafe-statics -fuse-cxa-atexit -fno-weak -nostdinc++ @gol
-fno-default-inline -fvisibility-inlines-hidden @gol
+-fvtable-verify=@var{std|preinit|none} @gol
+-fvtv-counts -fvtv-debug @gol
-fvisibility-ms-compat @gol
-fext-numeric-literals @gol
-Wabi -Wconversion-null -Wctor-dtor-privacy @gol
@@ -318,6 +320,7 @@ Objective-C and Objective-C++ Dialects}.
-fdump-tree-sra@r{[}-@var{n}@r{]} @gol
-fdump-tree-forwprop@r{[}-@var{n}@r{]} @gol
-fdump-tree-fre@r{[}-@var{n}@r{]} @gol
+-fdump-tree-vtable-verify @gol
-fdump-tree-vrp@r{[}-@var{n}@r{]} @gol
-ftree-vectorizer-verbose=@var{n} @gol
-fdump-tree-storeccp@r{[}-@var{n}@r{]} @gol
@@ -362,7 +365,7 @@ Objective-C and Objective-C++ Dialects}.
-fcse-follow-jumps -fcse-skip-blocks -fcx-fortran-rules @gol
-fcx-limited-range @gol
-fdata-sections -fdce -fdelayed-branch @gol
--fdelete-null-pointer-checks -fdevirtualize -fdse @gol
+-fdelete-null-pointer-checks -fdevirtualize -fdevirtualize-speculatively -fdse @gol
-fearly-inlining -fipa-sra -fexpensive-optimizations -ffat-lto-objects @gol
-ffast-math -ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol
-fforward-propagate -ffp-contract=@var{style} -ffunction-sections @gol
@@ -452,7 +455,7 @@ Objective-C and Objective-C++ Dialects}.
@gccoptlist{@var{object-file-name} -l@var{library} @gol
-nostartfiles -nodefaultlibs -nostdlib -pie -rdynamic @gol
-s -static -static-libgcc -static-libstdc++ @gol
--static-libasan -static-libtsan @gol
+-static-libasan -static-libtsan -static-libubsan @gol
-shared -shared-libgcc -symbolic @gol
-T @var{script} -Wl,@var{option} -Xlinker @var{option} @gol
-u @var{symbol}}
@@ -634,6 +637,7 @@ Objective-C and Objective-C++ Dialects}.
@emph{i386 and x86-64 Options}
@gccoptlist{-mtune=@var{cpu-type} -march=@var{cpu-type} @gol
+-mtune-ctrl=@var{feature-list} -mdump-tune-features -mno-default @gol
-mfpmath=@var{unit} @gol
-masm=@var{dialect} -mno-fancy-math-387 @gol
-mno-fp-ret-in-387 -msoft-float @gol
@@ -644,11 +648,13 @@ Objective-C and Objective-C++ Dialects}.
-mrecip -mrecip=@var{opt} @gol
-mvzeroupper -mprefer-avx128 @gol
-mmmx -msse -msse2 -msse3 -mssse3 -msse4.1 -msse4.2 -msse4 -mavx @gol
--mavx2 -maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma @gol
+-mavx2 -mavx512f -mavx512pf -mavx512er -mavx512cd @gol
+-maes -mpclmul -mfsgsbase -mrdrnd -mf16c -mfma @gol
-msse4a -m3dnow -mpopcnt -mabm -mbmi -mtbm -mfma4 -mxop -mlzcnt @gol
-mbmi2 -mrtm -mlwp -mthreads @gol
-mno-align-stringops -minline-all-stringops @gol
-minline-stringops-dynamically -mstringop-strategy=@var{alg} @gol
+-mmemcpy-strategy=@var{strategy} -mmemset-strategy=@var{strategy}
-mpush-args -maccumulate-outgoing-args -m128bit-long-double @gol
-m96bit-long-double -mlong-double-64 -mlong-double-80 @gol
-mregparm=@var{num} -msseregparm @gol
@@ -750,7 +756,8 @@ Objective-C and Objective-C++ Dialects}.
-mabi=@var{abi} -mabicalls -mno-abicalls @gol
-mshared -mno-shared -mplt -mno-plt -mxgot -mno-xgot @gol
-mgp32 -mgp64 -mfp32 -mfp64 -mhard-float -msoft-float @gol
--mno-float -msingle-float -mdouble-float @gol
+-mno-float -msingle-float -mdouble-float @gol
+-mabs=@var{mode} -mnan=@var{encoding} @gol
-mdsp -mno-dsp -mdspr2 -mno-dspr2 @gol
-mmcu -mmno-mcu @gol
-meva -mno-eva @gol
@@ -865,7 +872,8 @@ See RS/6000 and PowerPC Options.
-msave-toc-indirect -mno-save-toc-indirect @gol
-mpower8-fusion -mno-mpower8-fusion -mpower8-vector -mno-power8-vector @gol
-mcrypto -mno-crypto -mdirect-move -mno-direct-move @gol
--mquad-memory -mno-quad-memory}
+-mquad-memory -mno-quad-memory @gol
+-mcompat-align-parm -mno-compat-align-parm}
@emph{RX Options}
@gccoptlist{-m64bit-doubles -m32bit-doubles -fpu -nofpu@gol
@@ -1804,13 +1812,15 @@ have support for @option{-pthread}.
@item -fcilkplus
@opindex fcilkplus
@cindex Enable Cilk Plus
-Enable the usage of Cilk Language extension features for C/C++. When the flag
-@option{-fcilkplus} is specified, all the Cilk Plus components are converted
-to the appropriate C/C++ code. The present implementation follows ABI version
-0.9. There are four major parts to Cilk Plus language
-extension: Array Notations, Cilk Keywords, SIMD annotations and elemental
-functions. Detailed information about Cilk Plus can be found at
-@w{@uref{http://www.cilkplus.org}}.
+Enable the usage of Cilk Plus language extension features for C/C++.
+When the option @option{-fcilkplus} is specified, enable the usage of
+the Cilk Plus Language extension features for C/C++. The present
+implementation follows ABI version 0.9. This is an experimental
+feature that is only partially complete, and whose interface may
+change in future versions of GCC as the official specification
+changes. Currently only the array notation feature of the language
+specification has been implemented. More features will be implemented
+in subsequent release cycles.
@item -fgnu-tm
@opindex fgnu-tm
@@ -2301,6 +2311,56 @@ and that pointers to function members defined in different shared
objects may not compare equal. When this flag is given, it is a
violation of the ODR to define types with the same name differently.
+@item -fvtable-verify=@var{std|preinit|none}
+@opindex fvtable-verify
+Turn on (or off, if using @option{-fvtable-verify=none}) the security
+feature that verifies at runtime, for every virtual call that is made, that
+the vtable pointer through which the call is made is valid for the type of
+the object, and has not been corrupted or overwritten. If an invalid vtable
+pointer is detected (at runtime), an error is reported and execution of the
+program is immediately halted.
+
+This option causes runtime data structures to be built, at program start up,
+for verifying the vtable pointers. The options @code{std} and @code{preinit}
+control the timing of when these data structures are built. In both cases the
+data structures are built before execution reaches 'main'. The
+@option{-fvtable-verify=std} causes these data structure to be built after the
+shared libraries have been loaded and initialized.
+@option{-fvtable-verify=preinit} causes them to be built before the shared
+libraries have been loaded and initialized.
+
+If this option appears multiple times in the compiler line, with different
+values specified, 'none' will take highest priority over both 'std' and
+'preinit'; 'preinit' will take priority over 'std'.
+
+@item -fvtv-debug
+@opindex (fvtv-debug)
+Causes debug versions of the runtime functions for the vtable verification
+feature to be called. This assumes the @option{-fvtable-verify=std} or
+@option{-fvtable-verify=preinit} has been used. This flag will also cause the
+compiler to keep track of which vtable pointers it found for each class, and
+record that information in the file ``vtv_set_ptr_data.log'', in the dump
+file directory on the user's machine.
+
+Note: This feature APPENDS data to the log file. If you want a fresh log
+file, be sure to delete any existing one.
+
+@item -fvtv-counts
+@opindex (fvtv-counts)
+This is a debugging flag. When used in conjunction with
+@option{-fvtable-verify=std} or @option{-fvtable-verify=preinit}, this
+causes the compiler to keep track of the total number of virtual calls
+it encountered and the number of verifications it inserted. It also
+counts the number of calls to certain runtime library functions
+that it inserts. This information, for each compilation unit, is written
+to a file named ``vtv_count_data.log'', in the dump_file directory on
+the user's machine. It also counts the size of the vtable pointer sets
+for each class, and writes this information to ``vtv_class_set_sizes.log''
+in the same directory.
+
+Note: This feature APPENDS data to the log files. To get a fresh log
+files, be sure to delete any existing ones.
+
@item -fno-weak
@opindex fno-weak
Do not use weak symbol support, even if it is provided by the linker.
@@ -5152,6 +5212,14 @@ Memory access instructions will be instrumented to detect
data race bugs.
See @uref{http://code.google.com/p/data-race-test/wiki/ThreadSanitizer} for more details.
+@item -fsanitize=undefined
+Enable UndefinedBehaviorSanitizer, a fast undefined behavior detector
+Various computations will be instrumented to detect undefined behavior
+at runtime, e.g.@: division by zero or various overflows.
+While @option{-ftrapv} causes traps for signed overflows to be emitted,
+@option{-fsanitize=undefined} gives a diagnostic message.
+This currently works only for the C family of languages.
+
@item -fdump-final-insns@r{[}=@var{file}@r{]}
@opindex fdump-final-insns
Dump the final internal representation (RTL) to @var{file}. If the
@@ -6238,6 +6306,9 @@ Enable dumps from all loop optimizations.
Enable dumps from all inlining optimizations.
@item vec
Enable dumps from all vectorization optimizations.
+@item optall
+Enable dumps from all optimizations. This is a superset of
+the optimization groups listed above.
@end table
For example,
@@ -6646,7 +6717,7 @@ also turns on the following optimization flags:
-fcrossjumping @gol
-fcse-follow-jumps -fcse-skip-blocks @gol
-fdelete-null-pointer-checks @gol
--fdevirtualize @gol
+-fdevirtualize -fdevirtualize-speculatively @gol
-fexpensive-optimizations @gol
-fgcse -fgcse-lm @gol
-fhoist-adjacent-loads @gol
@@ -7191,6 +7262,15 @@ indirect inlining (@code{-findirect-inlining}) and interprocedural constant
propagation (@option{-fipa-cp}).
Enabled at levels @option{-O2}, @option{-O3}, @option{-Os}.
+@item -fdevirtualize-speculatively
+@opindex fdevirtualize-speculatively
+Attempt to convert calls to virtual functions to speculative direct calls.
+Based on the analysis of the type inheritance graph, determine for a given call
+the set of likely targets. If the set is small, preferably of size 1, change
+the call into an conditional deciding on direct and indirect call. The
+speculative calls enable more optimizations, such as inlining. When they seem
+useless after further optimization, they are converted back into original form.
+
@item -fexpensive-optimizations
@opindex fexpensive-optimizations
Perform a number of minor optimizations that are relatively expensive.
@@ -10102,6 +10182,15 @@ option is not used, then this links against the shared version of
driver to link @file{libtsan} statically, without necessarily linking
other libraries statically.
+@item -static-libubsan
+When the @option{-fsanitize=undefined} option is used to link a program,
+the GCC driver automatically links against @option{libubsan}. If
+@file{libubsan} is available as a shared library, and the @option{-static}
+option is not used, then this links against the shared version of
+@file{libubsan}. The @option{-static-libubsan} option directs the GCC
+driver to link @file{libubsan} statically, without necessarily linking
+other libraries statically.
+
@item -static-libstdc++
When the @command{g++} program is used to link a C++ program, it
normally automatically links against @option{libstdc++}. If
@@ -11089,6 +11178,8 @@ Feature modifiers used with @option{-march} and @option{-mcpu} can be one
the following:
@table @samp
+@item crc
+Enable CRC extension.
@item crypto
Enable Crypto extension. This implies Advanced SIMD is enabled.
@item fp
@@ -14314,11 +14405,20 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@itemx -mno-avx
@itemx -mavx2
@itemx -mno-avx2
+@itemx -mavx512f
+@itemx -mno-avx512f
+@need 800
+@itemx -mavx512pf
+@itemx -mno-avx512pf
+@itemx -mavx512er
+@itemx -mno-avx512er
+@itemx -mavx512cd
+@itemx -mno-avx512cd
@itemx -maes
@itemx -mno-aes
@itemx -mpclmul
-@need 800
@itemx -mno-pclmul
+@need 800
@itemx -mfsgsbase
@itemx -mno-fsgsbase
@itemx -mrdrnd
@@ -14330,8 +14430,8 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@itemx -msse4a
@itemx -mno-sse4a
@itemx -mfma4
-@need 800
@itemx -mno-fma4
+@need 800
@itemx -mxop
@itemx -mno-xop
@itemx -mlwp
@@ -14358,8 +14458,9 @@ preferred alignment to @option{-mpreferred-stack-boundary=2}.
@opindex m3dnow
@opindex mno-3dnow
These switches enable or disable the use of instructions in the MMX, SSE,
-SSE2, SSE3, SSSE3, SSE4.1, AVX, AVX2, AES, PCLMUL, FSGSBASE, RDRND, F16C,
-FMA, SSE4A, FMA4, XOP, LWP, ABM, BMI, BMI2, LZCNT, RTM or 3DNow!@:
+SSE2, SSE3, SSSE3, SSE4.1, AVX, AVX2, AVX512F, AVX512PF, AVX512ER, AVX512CD,
+AES, PCLMUL, FSGSBASE, RDRND, F16C, FMA, SSE4A, FMA4, XOP, LWP, ABM, BMI, BMI2,
+LZCNT, RTM or 3DNow!@:
extended instruction sets.
These extensions are also available as built-in functions: see
@ref{X86 Built-in Functions}, for details of the functions enabled and
@@ -14379,6 +14480,27 @@ supported architecture, using the appropriate flags. In particular,
the file containing the CPU detection code should be compiled without
these options.
+@item -mdump-tune-features
+@opindex mdump-tune-features
+This option instructs GCC to dump the names of the x86 performance
+tuning features and default settings. The names can be used in
+@option{-mtune-ctrl=@var{feature-list}}.
+
+@item -mtune-ctrl=@var{feature-list}
+@opindex mtune-ctrl=@var{feature-list}
+This option is used to do fine grain control of x86 code generation features.
+@var{feature-list} is a comma separated list of @var{feature} names. See also
+@option{-mdump-tune-features}. When specified, the @var{feature} will be turned
+on if it is not preceded with @code{^}, otherwise, it will be turned off.
+@option{-mtune-ctrl=@var{feature-list}} is intended to be used by GCC
+developers. Using it may lead to code paths not covered by testing and can
+potentially result in compiler ICEs or runtime errors.
+
+@item -mno-default
+@opindex mno-default
+This option instructs GCC to turn off all tunable features. See also
+@option{-mtune-ctrl=@var{feature-list}} and @option{-mdump-tune-features}.
+
@item -mcld
@opindex mcld
This option instructs GCC to emit a @code{cld} instruction in the prologue
@@ -14602,6 +14724,24 @@ Expand into an inline loop.
Always use a library call.
@end table
+@item -mmemcpy-strategy=@var{strategy}
+@opindex mmemcpy-strategy=@var{strategy}
+Override the internal decision heuristic to decide if @code{__builtin_memcpy}
+should be inlined and what inline algorithm to use when the expected size
+of the copy operation is known. @var{strategy}
+is a comma-separated list of @var{alg}:@var{max_size}:@var{dest_align} triplets.
+@var{alg} is specified in @option{-mstringop-strategy}, @var{max_size} specifies
+the max byte size with which inline algorithm @var{alg} is allowed. For the last
+triplet, the @var{max_size} must be @code{-1}. The @var{max_size} of the triplets
+in the list must be specified in increasing order. The minimal byte size for
+@var{alg} is @code{0} for the first triplet and @code{@var{max_size} + 1} of the
+preceding range.
+
+@item -mmemset-strategy=@var{strategy}
+@opindex mmemset-strategy=@var{strategy}
+The option is similar to @option{-mmemcpy-strategy=} except that it is to control
+@code{__builtin_memset} expansion.
+
@item -momit-leaf-frame-pointer
@opindex momit-leaf-frame-pointer
Don't keep the frame pointer in a register for leaf functions. This
@@ -16329,6 +16469,48 @@ operations.
Assume that the floating-point coprocessor supports double-precision
operations. This is the default.
+@item -mabs=2008
+@itemx -mabs=legacy
+@opindex mabs=2008
+@opindex mabs=legacy
+These options control the treatment of the special not-a-number (NaN)
+IEEE 754 floating-point data with the @code{abs.@i{fmt}} and
+@code{neg.@i{fmt}} machine instructions.
+
+By default or when the @option{-mabs=legacy} is used the legacy
+treatment is selected. In this case these instructions are considered
+arithmetic and avoided where correct operation is required and the
+input operand might be a NaN. A longer sequence of instructions that
+manipulate the sign bit of floating-point datum manually is used
+instead unless the @option{-ffinite-math-only} option has also been
+specified.
+
+The @option{-mabs=2008} option selects the IEEE 754-2008 treatment. In
+this case these instructions are considered non-arithmetic and therefore
+operating correctly in all cases, including in particular where the
+input operand is a NaN. These instructions are therefore always used
+for the respective operations.
+
+@item -mnan=2008
+@itemx -mnan=legacy
+@opindex mnan=2008
+@opindex mnan=legacy
+These options control the encoding of the special not-a-number (NaN)
+IEEE 754 floating-point data.
+
+The @option{-mnan=legacy} option selects the legacy encoding. In this
+case quiet NaNs (qNaNs) are denoted by the first bit of their trailing
+significand field being 0, whereas signalling NaNs (sNaNs) are denoted
+by the first bit of their trailing significand field being 1.
+
+The @option{-mnan=2008} option selects the IEEE 754-2008 encoding. In
+this case qNaNs are denoted by the first bit of their trailing
+significand field being 1, whereas sNaNs are denoted by the first bit of
+their trailing significand field being 0.
+
+The default is @option{-mnan=legacy} unless GCC has been configured with
+@option{--with-nan=2008}.
+
@item -mllsc
@itemx -mno-llsc
@opindex mllsc
@@ -18285,6 +18467,22 @@ stack location in the function prologue if the function calls through
a pointer on AIX and 64-bit Linux systems. If the TOC value is not
saved in the prologue, it is saved just before the call through the
pointer. The @option{-mno-save-toc-indirect} option is the default.
+
+@item -mcompat-align-parm
+@itemx -mno-compat-align-parm
+@opindex mcompat-align-parm
+Generate (do not generate) code to pass structure parameters with a
+maximum alignment of 64 bits, for compatibility with older versions
+of GCC.
+
+Older versions of GCC (prior to 4.9.0) incorrectly did not align a
+structure parameter on a 128-bit boundary when that structure contained
+a member requiring 128-bit alignment. This is corrected in more
+recent versions of GCC. This option may be used to generate code
+that is compatible with functions compiled with older versions of
+GCC.
+
+The @option{-mno-compat-align-parm} option is the default.
@end table
@node RX Options
@@ -20819,6 +21017,9 @@ Not all targets provide complete support for this switch.
Alter the thread-local storage model to be used (@pxref{Thread-Local}).
The @var{model} argument should be one of @code{global-dynamic},
@code{local-dynamic}, @code{initial-exec} or @code{local-exec}.
+Note that the choice is subject to optimization: the compiler may use
+a more efficient model for symbols not visible outside of the translation
+unit, or if @option{-fpic} is not given on the command line.
The default without @option{-fpic} is @code{initial-exec}; with
@option{-fpic} the default is @code{global-dynamic}.
diff --git a/gcc/doc/md.texi b/gcc/doc/md.texi
index c6664fa8e39..04f76fe901e 100644
--- a/gcc/doc/md.texi
+++ b/gcc/doc/md.texi
@@ -9651,7 +9651,7 @@ Here's an example of int iterators in action, taken from the ARM port:
QABSNEG))]
"TARGET_NEON"
"vq<absneg>.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_vqneg_vqabs")]
+ [(set_attr "type" "neon_vqneg_vqabs")]
)
@end smallexample
@@ -9666,7 +9666,7 @@ This is equivalent to:
UNSPEC_VQABS))]
"TARGET_NEON"
"vqabs.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_vqneg_vqabs")]
+ [(set_attr "type" "neon_vqneg_vqabs")]
)
(define_insn "neon_vqneg<mode>"
@@ -9676,7 +9676,7 @@ This is equivalent to:
UNSPEC_VQNEG))]
"TARGET_NEON"
"vqneg.<V_s_elem>\t%<V_reg>0, %<V_reg>1"
- [(set_attr "neon_type" "neon_vqneg_vqabs")]
+ [(set_attr "type" "neon_vqneg_vqabs")]
)
@end smallexample
diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi
index f14e11f6166..1d6222382b8 100644
--- a/gcc/doc/rtl.texi
+++ b/gcc/doc/rtl.texi
@@ -1097,6 +1097,10 @@ this is the right mode to use for certain pointers.
@item OImode
``Octa Integer'' (?) mode represents a thirty-two-byte integer.
+@findex XImode
+@item XImode
+``Hexadeca Integer'' (?) mode represents a sixty-four-byte integer.
+
@findex QFmode
@item QFmode
``Quarter-Floating'' mode represents a quarter-precision (single byte)
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 69e7e03cf68..d15f53ce5ae 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -1267,7 +1267,7 @@ This target hook should return @code{true} if accesses to volatile bitfields
should use the narrowest mode possible. It should return @code{false} if
these accesses should use the bitfield container type.
-The default is @code{!TARGET_STRICT_ALIGN}.
+The default is @code{false}.
@end deftypefn
@deftypefn {Target Hook} bool TARGET_MEMBER_TYPE_FORCES_BLK (const_tree @var{field}, enum machine_mode @var{mode})
@@ -5358,26 +5358,10 @@ refers to the global ``variable'' @code{errno}. (On certain systems,
macro, a reasonable default is used.
@end defmac
-@cindex C99 math functions, implicit usage
-@defmac TARGET_C99_FUNCTIONS
-When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
-@code{sinf} and similarly for other functions defined by C99 standard. The
-default is zero because a number of existing systems lack support for these
-functions in their runtime so this macro needs to be redefined to one on
-systems that do support the C99 runtime.
-@end defmac
-
-@cindex sincos math function, implicit usage
-@defmac TARGET_HAS_SINCOS
-When this macro is nonzero, GCC will implicitly optimize calls to @code{sin}
-and @code{cos} with the same argument to a call to @code{sincos}. The
-default is zero. The target has to provide the following functions:
-@smallexample
-void sincos(double x, double *sin, double *cos);
-void sincosf(float x, float *sin, float *cos);
-void sincosl(long double x, long double *sin, long double *cos);
-@end smallexample
-@end defmac
+@deftypefn {Target Hook} bool TARGET_LIBC_HAS_FUNCTION (enum function_class @var{fn_class})
+This hook determines whether a function from a class of functions
+@var{fn_class} is present at the runtime.
+@end deftypefn
@defmac NEXT_OBJC_RUNTIME
Set this macro to 1 to use the "NeXT" Objective-C message sending conventions
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index fad6d1044ea..b51d7b38800 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -4221,26 +4221,7 @@ refers to the global ``variable'' @code{errno}. (On certain systems,
macro, a reasonable default is used.
@end defmac
-@cindex C99 math functions, implicit usage
-@defmac TARGET_C99_FUNCTIONS
-When this macro is nonzero, GCC will implicitly optimize @code{sin} calls into
-@code{sinf} and similarly for other functions defined by C99 standard. The
-default is zero because a number of existing systems lack support for these
-functions in their runtime so this macro needs to be redefined to one on
-systems that do support the C99 runtime.
-@end defmac
-
-@cindex sincos math function, implicit usage
-@defmac TARGET_HAS_SINCOS
-When this macro is nonzero, GCC will implicitly optimize calls to @code{sin}
-and @code{cos} with the same argument to a call to @code{sincos}. The
-default is zero. The target has to provide the following functions:
-@smallexample
-void sincos(double x, double *sin, double *cos);
-void sincosf(float x, float *sin, float *cos);
-void sincosl(long double x, long double *sin, long double *cos);
-@end smallexample
-@end defmac
+@hook TARGET_LIBC_HAS_FUNCTION
@defmac NEXT_OBJC_RUNTIME
Set this macro to 1 to use the "NeXT" Objective-C message sending conventions
diff --git a/gcc/double-int.c b/gcc/double-int.c
index fe3c096619a..7eaad659279 100644
--- a/gcc/double-int.c
+++ b/gcc/double-int.c
@@ -271,13 +271,13 @@ rshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
;
else if ((prec - count) >= HOST_BITS_PER_WIDE_INT)
{
- *hv &= ~((HOST_WIDE_INT) (-1) << (prec - count - HOST_BITS_PER_WIDE_INT));
+ *hv &= ~(HOST_WIDE_INT_M1U << (prec - count - HOST_BITS_PER_WIDE_INT));
*hv |= signmask << (prec - count - HOST_BITS_PER_WIDE_INT);
}
else
{
*hv = signmask;
- *lv &= ~((unsigned HOST_WIDE_INT) (-1) << (prec - count));
+ *lv &= ~(HOST_WIDE_INT_M1U << (prec - count));
*lv |= signmask << (prec - count);
}
}
@@ -328,13 +328,13 @@ lshift_double (unsigned HOST_WIDE_INT l1, HOST_WIDE_INT h1,
;
else if (prec >= HOST_BITS_PER_WIDE_INT)
{
- *hv &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+ *hv &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT));
*hv |= signmask << (prec - HOST_BITS_PER_WIDE_INT);
}
else
{
*hv = signmask;
- *lv &= ~((unsigned HOST_WIDE_INT) (-1) << prec);
+ *lv &= ~(HOST_WIDE_INT_M1U << prec);
*lv |= signmask << prec;
}
}
diff --git a/gcc/dse.c b/gcc/dse.c
index d643cb0b4fa..8b132eb2c91 100644
--- a/gcc/dse.c
+++ b/gcc/dse.c
@@ -3729,42 +3729,78 @@ gate_dse2 (void)
&& dbg_cnt (dse2);
}
-struct rtl_opt_pass pass_rtl_dse1 =
-{
- {
- RTL_PASS,
- "dse1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dse1, /* gate */
- rest_of_handle_dse, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_DSE1, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_rtl_dse1 =
+{
+ RTL_PASS, /* type */
+ "dse1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_DSE1, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
-struct rtl_opt_pass pass_rtl_dse2 =
-{
- {
- RTL_PASS,
- "dse2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dse2, /* gate */
- rest_of_handle_dse, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_DSE2, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+class pass_rtl_dse1 : public rtl_opt_pass
+{
+public:
+ pass_rtl_dse1(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_dse1, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_dse1 (); }
+ unsigned int execute () { return rest_of_handle_dse (); }
+
+}; // class pass_rtl_dse1
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_dse1 (gcc::context *ctxt)
+{
+ return new pass_rtl_dse1 (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_rtl_dse2 =
+{
+ RTL_PASS, /* type */
+ "dse2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_DSE2, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_rtl_dse2 : public rtl_opt_pass
+{
+public:
+ pass_rtl_dse2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_dse2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_dse2 (); }
+ unsigned int execute () { return rest_of_handle_dse (); }
+
+}; // class pass_rtl_dse2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_dse2 (gcc::context *ctxt)
+{
+ return new pass_rtl_dse2 (ctxt);
+}
diff --git a/gcc/dumpfile.c b/gcc/dumpfile.c
index 55ad80451d6..6ac15ddf6f3 100644
--- a/gcc/dumpfile.c
+++ b/gcc/dumpfile.c
@@ -52,6 +52,8 @@ static struct dump_file_info dump_files[TDI_end] =
{NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, 0},
{".cgraph", "ipa-cgraph", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
0, 0, 0, 0, 0},
+ {".type-inheritance", "ipa-type-inheritance", NULL, NULL, NULL, NULL, NULL, TDF_IPA,
+ 0, 0, 0, 0, 0},
{".tu", "translation-unit", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
0, 0, 0, 0, 1},
{".class", "class-hierarchy", NULL, NULL, NULL, NULL, NULL, TDF_TREE,
@@ -257,16 +259,16 @@ dump_open_alternate_stream (struct dump_file_info *dfi)
void
dump_loc (int dump_kind, FILE *dfile, source_location loc)
{
- /* Currently vectorization passes print location information. */
if (dump_kind)
{
if (LOCATION_LOCUS (loc) > BUILTINS_LOCATION)
- fprintf (dfile, "\n%s:%d: note: ", LOCATION_FILE (loc),
- LOCATION_LINE (loc));
+ fprintf (dfile, "\n%s:%d:%d: note: ", LOCATION_FILE (loc),
+ LOCATION_LINE (loc), LOCATION_COLUMN (loc));
else if (current_function_decl)
- fprintf (dfile, "\n%s:%d: note: ",
+ fprintf (dfile, "\n%s:%d:%d: note: ",
DECL_SOURCE_FILE (current_function_decl),
- DECL_SOURCE_LINE (current_function_decl));
+ DECL_SOURCE_LINE (current_function_decl),
+ DECL_SOURCE_COLUMN (current_function_decl));
}
}
@@ -448,7 +450,9 @@ dump_finish (int phase)
if (phase < 0)
return;
dfi = get_dump_file_info (phase);
- if (dfi->pstream)
+ if (dfi->pstream && (!dfi->pfilename
+ || (strcmp("stderr", dfi->pfilename) != 0
+ && strcmp("stdout", dfi->pfilename) != 0)))
fclose (dfi->pstream);
if (dfi->alt_stream && strcmp("stderr", dfi->alt_filename) != 0
diff --git a/gcc/dumpfile.h b/gcc/dumpfile.h
index 77f5de68c4d..ddc770ab947 100644
--- a/gcc/dumpfile.h
+++ b/gcc/dumpfile.h
@@ -29,6 +29,7 @@ enum tree_dump_index
{
TDI_none, /* No dump */
TDI_cgraph, /* dump function call graph. */
+ TDI_inheritance, /* dump type inheritance graph. */
TDI_tu, /* dump the whole translation unit. */
TDI_class, /* dump class hierarchy. */
TDI_original, /* dump each function before optimizing it */
@@ -97,8 +98,9 @@ enum tree_dump_index
#define OPTGROUP_LOOP (1 << 2) /* Loop optimization passes */
#define OPTGROUP_INLINE (1 << 3) /* Inlining passes */
#define OPTGROUP_VEC (1 << 4) /* Vectorization passes */
+#define OPTGROUP_OTHER (1 << 5) /* All other passes */
#define OPTGROUP_ALL (OPTGROUP_IPA | OPTGROUP_LOOP | OPTGROUP_INLINE \
- | OPTGROUP_VEC)
+ | OPTGROUP_VEC | OPTGROUP_OTHER)
/* Define a tree dump switch. */
struct dump_file_info
diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c
index 29779d6ad6a..ee8d42c9b28 100644
--- a/gcc/dwarf2cfi.c
+++ b/gcc/dwarf2cfi.c
@@ -3370,24 +3370,42 @@ gate_dwarf2_frame (void)
return dwarf2out_do_frame ();
}
-struct rtl_opt_pass pass_dwarf2_frame =
-{
- {
- RTL_PASS,
- "dwarf2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dwarf2_frame, /* gate */
- execute_dwarf2_frame, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_FINAL, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_dwarf2_frame =
+{
+ RTL_PASS, /* type */
+ "dwarf2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_FINAL, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_dwarf2_frame : public rtl_opt_pass
+{
+public:
+ pass_dwarf2_frame(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_dwarf2_frame, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_dwarf2_frame (); }
+ unsigned int execute () { return execute_dwarf2_frame (); }
+
+}; // class pass_dwarf2_frame
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_dwarf2_frame (gcc::context *ctxt)
+{
+ return new pass_dwarf2_frame (ctxt);
+}
+
#include "gt-dwarf2cfi.h"
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 66cbfb032e0..fc1c3f21565 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -5432,6 +5432,7 @@ pop_compile_unit (dw_die_ref old_unit)
}
#define CHECKSUM(FOO) md5_process_bytes (&(FOO), sizeof (FOO), ctx)
+#define CHECKSUM_BLOCK(FOO, SIZE) md5_process_bytes ((FOO), (SIZE), ctx)
#define CHECKSUM_STRING(FOO) md5_process_bytes ((FOO), strlen (FOO), ctx)
/* Calculate the checksum of a location expression. */
@@ -5475,7 +5476,9 @@ attr_checksum (dw_attr_ref at, struct md5_ctx *ctx, int *mark)
CHECKSUM (at->dw_attr_val.v.val_double);
break;
case dw_val_class_vec:
- CHECKSUM (at->dw_attr_val.v.val_vec);
+ CHECKSUM_BLOCK (at->dw_attr_val.v.val_vec.array,
+ (at->dw_attr_val.v.val_vec.length
+ * at->dw_attr_val.v.val_vec.elt_size));
break;
case dw_val_class_flag:
CHECKSUM (at->dw_attr_val.v.val_flag);
@@ -5550,10 +5553,12 @@ die_checksum (dw_die_ref die, struct md5_ctx *ctx, int *mark)
}
#undef CHECKSUM
+#undef CHECKSUM_BLOCK
#undef CHECKSUM_STRING
/* For DWARF-4 types, include the trailing NULL when checksumming strings. */
#define CHECKSUM(FOO) md5_process_bytes (&(FOO), sizeof (FOO), ctx)
+#define CHECKSUM_BLOCK(FOO, SIZE) md5_process_bytes ((FOO), (SIZE), ctx)
#define CHECKSUM_STRING(FOO) md5_process_bytes ((FOO), strlen (FOO) + 1, ctx)
#define CHECKSUM_SLEB128(FOO) checksum_sleb128 ((FOO), ctx)
#define CHECKSUM_ULEB128(FOO) checksum_uleb128 ((FOO), ctx)
@@ -5749,8 +5754,11 @@ attr_checksum_ordered (enum dwarf_tag tag, dw_attr_ref at,
case dw_val_class_vec:
CHECKSUM_ULEB128 (DW_FORM_block);
- CHECKSUM_ULEB128 (sizeof (at->dw_attr_val.v.val_vec));
- CHECKSUM (at->dw_attr_val.v.val_vec);
+ CHECKSUM_ULEB128 (at->dw_attr_val.v.val_vec.length
+ * at->dw_attr_val.v.val_vec.elt_size);
+ CHECKSUM_BLOCK (at->dw_attr_val.v.val_vec.array,
+ (at->dw_attr_val.v.val_vec.length
+ * at->dw_attr_val.v.val_vec.elt_size));
break;
case dw_val_class_flag:
diff --git a/gcc/except.c b/gcc/except.c
index b25207b4c87..2d41d7b332d 100644
--- a/gcc/except.c
+++ b/gcc/except.c
@@ -2001,26 +2001,43 @@ set_nothrow_function_flags (void)
return 0;
}
-struct rtl_opt_pass pass_set_nothrow_function_flags =
-{
- {
- RTL_PASS,
- "nothrow", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- set_nothrow_function_flags, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_set_nothrow_function_flags =
+{
+ RTL_PASS, /* type */
+ "nothrow", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_set_nothrow_function_flags : public rtl_opt_pass
+{
+public:
+ pass_set_nothrow_function_flags(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_set_nothrow_function_flags, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return set_nothrow_function_flags (); }
+
+}; // class pass_set_nothrow_function_flags
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_set_nothrow_function_flags (gcc::context *ctxt)
+{
+ return new pass_set_nothrow_function_flags (ctxt);
+}
+
/* Various hooks for unwind library. */
@@ -2615,25 +2632,43 @@ gate_convert_to_eh_region_ranges (void)
return true;
}
-struct rtl_opt_pass pass_convert_to_eh_region_ranges =
-{
- {
- RTL_PASS,
- "eh_ranges", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_convert_to_eh_region_ranges, /* gate */
- convert_to_eh_region_ranges, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_convert_to_eh_region_ranges =
+{
+ RTL_PASS, /* type */
+ "eh_ranges", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_convert_to_eh_region_ranges : public rtl_opt_pass
+{
+public:
+ pass_convert_to_eh_region_ranges(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_convert_to_eh_region_ranges, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_convert_to_eh_region_ranges (); }
+ unsigned int execute () { return convert_to_eh_region_ranges (); }
+
+}; // class pass_convert_to_eh_region_ranges
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_convert_to_eh_region_ranges (gcc::context *ctxt)
+{
+ return new pass_convert_to_eh_region_ranges (ctxt);
+}
static void
push_uleb128 (vec<uchar, va_gc> **data_area, unsigned int value)
diff --git a/gcc/expmed.c b/gcc/expmed.c
index 79f3424961d..d18f09f4889 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -3697,11 +3697,11 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
masklow = ((HOST_WIDE_INT) 1 << logd) - 1;
if (GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
{
- masklow |= (HOST_WIDE_INT) -1 << (GET_MODE_BITSIZE (mode) - 1);
+ masklow |= HOST_WIDE_INT_M1U << (GET_MODE_BITSIZE (mode) - 1);
maskhigh = -1;
}
else
- maskhigh = (HOST_WIDE_INT) -1
+ maskhigh = HOST_WIDE_INT_M1U
<< (GET_MODE_BITSIZE (mode) - HOST_BITS_PER_WIDE_INT - 1);
temp = expand_binop (mode, and_optab, op0,
@@ -3715,7 +3715,7 @@ expand_smod_pow2 (enum machine_mode mode, rtx op0, HOST_WIDE_INT d)
temp = expand_binop (mode, sub_optab, result, const1_rtx, result,
0, OPTAB_LIB_WIDEN);
- masklow = (HOST_WIDE_INT) -1 << logd;
+ masklow = HOST_WIDE_INT_M1U << logd;
maskhigh = -1;
temp = expand_binop (mode, ior_optab, temp,
immed_double_const (masklow, maskhigh, mode),
diff --git a/gcc/expr.c b/gcc/expr.c
index 923f59bffda..167d4f5d5ce 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -119,7 +119,7 @@ struct store_by_pieces_d
int reverse;
};
-static void move_by_pieces_1 (rtx (*) (rtx, ...), enum machine_mode,
+static void move_by_pieces_1 (insn_gen_fn, machine_mode,
struct move_by_pieces_d *);
static bool block_move_libcall_safe_for_call_parm (void);
static bool emit_block_move_via_movmem (rtx, rtx, rtx, unsigned, unsigned, HOST_WIDE_INT);
@@ -128,7 +128,7 @@ static void emit_block_move_via_loop (rtx, rtx, rtx, unsigned);
static rtx clear_by_pieces_1 (void *, HOST_WIDE_INT, enum machine_mode);
static void clear_by_pieces (rtx, unsigned HOST_WIDE_INT, unsigned int);
static void store_by_pieces_1 (struct store_by_pieces_d *, unsigned int);
-static void store_by_pieces_2 (rtx (*) (rtx, ...), enum machine_mode,
+static void store_by_pieces_2 (insn_gen_fn, machine_mode,
struct store_by_pieces_d *);
static tree clear_storage_libcall_fn (int);
static rtx compress_float_constant (rtx, rtx);
@@ -1043,7 +1043,7 @@ move_by_pieces_ninsns (unsigned HOST_WIDE_INT l, unsigned int align,
to make a move insn for that mode. DATA has all the other info. */
static void
-move_by_pieces_1 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
+move_by_pieces_1 (insn_gen_fn genfun, machine_mode mode,
struct move_by_pieces_d *data)
{
unsigned int size = GET_MODE_SIZE (mode);
@@ -2657,7 +2657,7 @@ store_by_pieces_1 (struct store_by_pieces_d *data ATTRIBUTE_UNUSED,
to make a move insn for that mode. DATA has all the other info. */
static void
-store_by_pieces_2 (rtx (*genfun) (rtx, ...), enum machine_mode mode,
+store_by_pieces_2 (insn_gen_fn genfun, machine_mode mode,
struct store_by_pieces_d *data)
{
unsigned int size = GET_MODE_SIZE (mode);
@@ -3232,11 +3232,16 @@ emit_move_complex (enum machine_mode mode, rtx x, rtx y)
if (push_operand (x, mode))
return emit_move_complex_push (mode, x, y);
- /* See if we can coerce the target into moving both values at once. */
-
- /* Move floating point as parts. */
+ /* See if we can coerce the target into moving both values at once, except
+ for floating point where we favor moving as parts if this is easy. */
if (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
- && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing)
+ && optab_handler (mov_optab, GET_MODE_INNER (mode)) != CODE_FOR_nothing
+ && !(REG_P (x)
+ && HARD_REGISTER_P (x)
+ && hard_regno_nregs[REGNO(x)][mode] == 1)
+ && !(REG_P (y)
+ && HARD_REGISTER_P (y)
+ && hard_regno_nregs[REGNO(y)][mode] == 1))
try_int = false;
/* Not possible if the values are inherently not adjacent. */
else if (GET_CODE (x) == CONCAT || GET_CODE (y) == CONCAT)
diff --git a/gcc/final.c b/gcc/final.c
index d9b4408aadf..d1c8d7c77fb 100644
--- a/gcc/final.c
+++ b/gcc/final.c
@@ -795,26 +795,90 @@ compute_alignments (void)
return 0;
}
-struct rtl_opt_pass pass_compute_alignments =
+/* Grow the LABEL_ALIGN array after new labels are created. */
+
+static void
+grow_label_align (void)
+{
+ int old = max_labelno;
+ int n_labels;
+ int n_old_labels;
+
+ max_labelno = max_label_num ();
+
+ n_labels = max_labelno - min_labelno + 1;
+ n_old_labels = old - min_labelno + 1;
+
+ label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels);
+
+ /* Range of labels grows monotonically in the function. Failing here
+ means that the initialization of array got lost. */
+ gcc_assert (n_old_labels <= n_labels);
+
+ memset (label_align + n_old_labels, 0,
+ (n_labels - n_old_labels) * sizeof (struct label_alignment));
+}
+
+/* Update the already computed alignment information. LABEL_PAIRS is a vector
+ made up of pairs of labels for which the alignment information of the first
+ element will be copied from that of the second element. */
+
+void
+update_alignments (vec<rtx> &label_pairs)
{
- {
- RTL_PASS,
- "alignments", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- compute_alignments, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ unsigned int i = 0;
+ rtx iter, label;
+
+ if (max_labelno != max_label_num ())
+ grow_label_align ();
+
+ FOR_EACH_VEC_ELT (label_pairs, i, iter)
+ if (i & 1)
+ {
+ LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter);
+ LABEL_TO_MAX_SKIP (label) = LABEL_TO_MAX_SKIP (iter);
+ }
+ else
+ label = iter;
+}
+
+namespace {
+
+const pass_data pass_data_compute_alignments =
+{
+ RTL_PASS, /* type */
+ "alignments", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_compute_alignments : public rtl_opt_pass
+{
+public:
+ pass_compute_alignments(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_compute_alignments, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return compute_alignments (); }
+
+}; // class pass_compute_alignments
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_compute_alignments (gcc::context *ctxt)
+{
+ return new pass_compute_alignments (ctxt);
+}
+
/* Make a pass over all insns and compute their actual lengths by shortening
any branches of variable length if possible. */
@@ -852,25 +916,7 @@ shorten_branches (rtx first)
uid_shuid = XNEWVEC (int, max_uid);
if (max_labelno != max_label_num ())
- {
- int old = max_labelno;
- int n_labels;
- int n_old_labels;
-
- max_labelno = max_label_num ();
-
- n_labels = max_labelno - min_labelno + 1;
- n_old_labels = old - min_labelno + 1;
-
- label_align = XRESIZEVEC (struct label_alignment, label_align, n_labels);
-
- /* Range of labels grows monotonically in the function. Failing here
- means that the initialization of array got lost. */
- gcc_assert (n_old_labels <= n_labels);
-
- memset (label_align + n_old_labels, 0,
- (n_labels - n_old_labels) * sizeof (struct label_alignment));
- }
+ grow_label_align ();
/* Initialize label_align and set up uid_shuid to be strictly
monotonically rising with insn order. */
@@ -1604,12 +1650,26 @@ reemit_insn_block_notes (void)
rtx insn, note;
insn = get_insns ();
- if (!active_insn_p (insn))
- insn = next_active_insn (insn);
- for (; insn; insn = next_active_insn (insn))
+ for (; insn; insn = NEXT_INSN (insn))
{
tree this_block;
+ /* Prevent lexical blocks from straddling section boundaries. */
+ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
+ {
+ for (tree s = cur_block; s != DECL_INITIAL (cfun->decl);
+ s = BLOCK_SUPERCONTEXT (s))
+ {
+ rtx note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
+ NOTE_BLOCK (note) = s;
+ note = emit_note_after (NOTE_INSN_BLOCK_BEG, insn);
+ NOTE_BLOCK (note) = s;
+ }
+ }
+
+ if (!active_insn_p (insn))
+ continue;
+
/* Avoid putting scope notes between jump table and its label. */
if (JUMP_TABLE_DATA_P (insn))
continue;
@@ -4409,26 +4469,43 @@ rest_of_handle_final (void)
return 0;
}
-struct rtl_opt_pass pass_final =
+namespace {
+
+const pass_data pass_data_final =
{
- {
- RTL_PASS,
- "final", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_final, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_FINAL, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "final", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_FINAL, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_final : public rtl_opt_pass
+{
+public:
+ pass_final(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_final, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_final (); }
+
+}; // class pass_final
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_final (gcc::context *ctxt)
+{
+ return new pass_final (ctxt);
+}
+
static unsigned int
rest_of_handle_shorten_branches (void)
@@ -4438,26 +4515,43 @@ rest_of_handle_shorten_branches (void)
return 0;
}
-struct rtl_opt_pass pass_shorten_branches =
+namespace {
+
+const pass_data pass_data_shorten_branches =
{
- {
- RTL_PASS,
- "shorten", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_shorten_branches, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_SHORTEN_BRANCH, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "shorten", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_SHORTEN_BRANCH, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_shorten_branches : public rtl_opt_pass
+{
+public:
+ pass_shorten_branches(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_shorten_branches, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_shorten_branches (); }
+
+}; // class pass_shorten_branches
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_shorten_branches (gcc::context *ctxt)
+{
+ return new pass_shorten_branches (ctxt);
+}
+
static unsigned int
rest_of_clean_state (void)
@@ -4585,22 +4679,39 @@ rest_of_clean_state (void)
return 0;
}
-struct rtl_opt_pass pass_clean_state =
+namespace {
+
+const pass_data pass_data_clean_state =
{
- {
- RTL_PASS,
- "*clean_state", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_clean_state, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_FINAL, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- PROP_rtl, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "*clean_state", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_FINAL, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ PROP_rtl, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_clean_state : public rtl_opt_pass
+{
+public:
+ pass_clean_state(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_clean_state, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_clean_state (); }
+
+}; // class pass_clean_state
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_clean_state (gcc::context *ctxt)
+{
+ return new pass_clean_state (ctxt);
+}
diff --git a/gcc/flag-types.h b/gcc/flag-types.h
index 4fc5d33348e..45616bc74f5 100644
--- a/gcc/flag-types.h
+++ b/gcc/flag-types.h
@@ -191,4 +191,23 @@ enum fp_contract_mode {
FP_CONTRACT_FAST = 2
};
+/* Different instrumentation modes. */
+enum sanitize_code {
+ /* AddressSanitizer. */
+ SANITIZE_ADDRESS = 1 << 0,
+ /* ThreadSanitizer. */
+ SANITIZE_THREAD = 1 << 1,
+ /* UndefinedBehaviorSanitizer. */
+ SANITIZE_SHIFT = 1 << 2,
+ SANITIZE_DIVIDE = 1 << 3,
+ SANITIZE_UNREACHABLE = 1 << 4,
+ SANITIZE_UNDEFINED = SANITIZE_SHIFT | SANITIZE_DIVIDE | SANITIZE_UNREACHABLE
+};
+
+/* flag_vtable_verify initialization levels. */
+enum vtv_priority {
+ VTV_NO_PRIORITY = 0, /* i.E. Do NOT do vtable verification. */
+ VTV_STANDARD_PRIORITY = 1,
+ VTV_PREINIT_PRIORITY = 2
+};
#endif /* ! GCC_FLAG_TYPES_H */
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 6506ae7bbfb..9956b2c9f07 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -483,11 +483,24 @@ negate_expr_p (tree t)
and actually traps on some architectures. But if overflow is
undefined, we can negate, because - (INT_MIN / 1) is an
overflow. */
- if (INTEGRAL_TYPE_P (TREE_TYPE (t))
- && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)))
- break;
- return negate_expr_p (TREE_OPERAND (t, 1))
- || negate_expr_p (TREE_OPERAND (t, 0));
+ if (INTEGRAL_TYPE_P (TREE_TYPE (t)))
+ {
+ if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (t)))
+ break;
+ /* If overflow is undefined then we have to be careful because
+ we ask whether it's ok to associate the negate with the
+ division which is not ok for example for
+ -((a - b) / c) where (-(a - b)) / c may invoke undefined
+ overflow because of negating INT_MIN. So do not use
+ negate_expr_p here but open-code the two important cases. */
+ if (TREE_CODE (TREE_OPERAND (t, 0)) == NEGATE_EXPR
+ || (TREE_CODE (TREE_OPERAND (t, 0)) == INTEGER_CST
+ && may_negate_without_overflow_p (TREE_OPERAND (t, 0))))
+ return true;
+ }
+ else if (negate_expr_p (TREE_OPERAND (t, 0)))
+ return true;
+ return negate_expr_p (TREE_OPERAND (t, 1));
case NOP_EXPR:
/* Negate -((double)float) as (double)(-float). */
@@ -682,16 +695,20 @@ fold_negate_expr (location_t loc, tree t)
return fold_build2_loc (loc, TREE_CODE (t), type,
TREE_OPERAND (t, 0), negate_expr (tem));
}
+ /* If overflow is undefined then we have to be careful because
+ we ask whether it's ok to associate the negate with the
+ division which is not ok for example for
+ -((a - b) / c) where (-(a - b)) / c may invoke undefined
+ overflow because of negating INT_MIN. So do not use
+ negate_expr_p here but open-code the two important cases. */
tem = TREE_OPERAND (t, 0);
- if (negate_expr_p (tem))
- {
- if (INTEGRAL_TYPE_P (type)
- && (TREE_CODE (tem) != INTEGER_CST
- || tree_int_cst_equal (tem, TYPE_MIN_VALUE (type))))
- fold_overflow_warning (warnmsg, WARN_STRICT_OVERFLOW_MISC);
- return fold_build2_loc (loc, TREE_CODE (t), type,
- negate_expr (tem), TREE_OPERAND (t, 1));
- }
+ if ((INTEGRAL_TYPE_P (type)
+ && (TREE_CODE (tem) == NEGATE_EXPR
+ || (TREE_CODE (tem) == INTEGER_CST
+ && may_negate_without_overflow_p (tem))))
+ || !INTEGRAL_TYPE_P (type))
+ return fold_build2_loc (loc, TREE_CODE (t), type,
+ negate_expr (tem), TREE_OPERAND (t, 1));
}
break;
@@ -3740,8 +3757,7 @@ sign_bit_p (tree exp, const_tree val)
hi = (unsigned HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT - 1);
lo = 0;
- mask_hi = ((unsigned HOST_WIDE_INT) -1
- >> (HOST_BITS_PER_DOUBLE_INT - width));
+ mask_hi = (HOST_WIDE_INT_M1U >> (HOST_BITS_PER_DOUBLE_INT - width));
mask_lo = -1;
}
else
@@ -3750,8 +3766,7 @@ sign_bit_p (tree exp, const_tree val)
lo = (unsigned HOST_WIDE_INT) 1 << (width - 1);
mask_hi = 0;
- mask_lo = ((unsigned HOST_WIDE_INT) -1
- >> (HOST_BITS_PER_WIDE_INT - width));
+ mask_lo = (HOST_WIDE_INT_M1U >> (HOST_BITS_PER_WIDE_INT - width));
}
/* We mask off those bits beyond TREE_TYPE (exp) so that we can
@@ -4325,7 +4340,7 @@ build_range_check (location_t loc, tree type, tree exp, int in_p,
else
{
hi = ((HOST_WIDE_INT) 1 << (prec - HOST_BITS_PER_WIDE_INT - 1)) - 1;
- lo = (unsigned HOST_WIDE_INT) -1;
+ lo = HOST_WIDE_INT_M1U;
}
if (TREE_INT_CST_HIGH (high) == hi && TREE_INT_CST_LOW (high) == lo)
@@ -6636,10 +6651,10 @@ fold_single_bit_test (location_t loc, enum tree_code code,
not overflow, adjust BITNUM and INNER. */
if (TREE_CODE (inner) == RSHIFT_EXPR
&& TREE_CODE (TREE_OPERAND (inner, 1)) == INTEGER_CST
- && TREE_INT_CST_HIGH (TREE_OPERAND (inner, 1)) == 0
+ && host_integerp (TREE_OPERAND (inner, 1), 1)
&& bitnum < TYPE_PRECISION (type)
- && 0 > compare_tree_int (TREE_OPERAND (inner, 1),
- bitnum - TYPE_PRECISION (type)))
+ && (TREE_INT_CST_LOW (TREE_OPERAND (inner, 1))
+ < (unsigned) (TYPE_PRECISION (type) - bitnum)))
{
bitnum += TREE_INT_CST_LOW (TREE_OPERAND (inner, 1));
inner = TREE_OPERAND (inner, 0);
@@ -8096,7 +8111,7 @@ fold_unary_loc (location_t loc, enum tree_code code, tree type, tree op0)
unsigned HOST_WIDE_INT cst;
cst = tree_low_cst (and1, 1);
- cst &= (HOST_WIDE_INT) -1
+ cst &= HOST_WIDE_INT_M1U
<< (TYPE_PRECISION (TREE_TYPE (and1)) - 1);
change = (cst == 0);
#ifdef LOAD_EXTEND_OP
@@ -11277,7 +11292,7 @@ fold_binary_loc (location_t loc,
w <<= 1)
{
unsigned HOST_WIDE_INT mask
- = (unsigned HOST_WIDE_INT) -1 >> (HOST_BITS_PER_WIDE_INT - w);
+ = HOST_WIDE_INT_M1U >> (HOST_BITS_PER_WIDE_INT - w);
if (((c1.low | c2.low) & mask) == mask
&& (c1.low & ~mask) == 0 && c1.high == 0)
{
@@ -12297,7 +12312,7 @@ fold_binary_loc (location_t loc,
/* X / -1 is -X. */
if (!TYPE_UNSIGNED (type)
&& TREE_CODE (arg1) == INTEGER_CST
- && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
+ && TREE_INT_CST_LOW (arg1) == HOST_WIDE_INT_M1U
&& TREE_INT_CST_HIGH (arg1) == -1)
return fold_convert_loc (loc, type, negate_expr (arg0));
@@ -12380,7 +12395,7 @@ fold_binary_loc (location_t loc,
/* X % -1 is zero. */
if (!TYPE_UNSIGNED (type)
&& TREE_CODE (arg1) == INTEGER_CST
- && TREE_INT_CST_LOW (arg1) == (unsigned HOST_WIDE_INT) -1
+ && TREE_INT_CST_LOW (arg1) == HOST_WIDE_INT_M1U
&& TREE_INT_CST_HIGH (arg1) == -1)
return omit_one_operand_loc (loc, type, integer_zero_node, arg0);
@@ -13535,7 +13550,7 @@ fold_binary_loc (location_t loc,
else
{
max_lo = signed_max_lo;
- min_lo = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
+ min_lo = (HOST_WIDE_INT_M1U << (width - 1));
min_hi = -1;
}
}
@@ -13556,7 +13571,7 @@ fold_binary_loc (location_t loc,
else
{
max_hi = signed_max_hi;
- min_hi = ((unsigned HOST_WIDE_INT) -1 << (width - 1));
+ min_hi = (HOST_WIDE_INT_M1U << (width - 1));
}
}
@@ -14175,24 +14190,24 @@ fold_ternary_loc (location_t loc, enum tree_code code, tree type,
if (outer_width > HOST_BITS_PER_WIDE_INT)
{
- mask_hi = ((unsigned HOST_WIDE_INT) -1
+ mask_hi = (HOST_WIDE_INT_M1U
>> (HOST_BITS_PER_DOUBLE_INT - outer_width));
mask_lo = -1;
}
else
{
mask_hi = 0;
- mask_lo = ((unsigned HOST_WIDE_INT) -1
+ mask_lo = (HOST_WIDE_INT_M1U
>> (HOST_BITS_PER_WIDE_INT - outer_width));
}
if (inner_width > HOST_BITS_PER_WIDE_INT)
{
- mask_hi &= ~((unsigned HOST_WIDE_INT) -1
+ mask_hi &= ~(HOST_WIDE_INT_M1U
>> (HOST_BITS_PER_WIDE_INT - inner_width));
mask_lo = 0;
}
else
- mask_lo &= ~((unsigned HOST_WIDE_INT) -1
+ mask_lo &= ~(HOST_WIDE_INT_M1U
>> (HOST_BITS_PER_WIDE_INT - inner_width));
if ((TREE_INT_CST_HIGH (arg1) & mask_hi) == mask_hi
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 8ec11b6e453..2b34517741d 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,153 @@
+2013-09-02 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/PR56519
+ * gfortran.h: Declare gfc_do_concurrent_flag as extern.
+ * resolve.c: Rename do_concurrent_flag to gfc_do_concurrent_flag
+ and make non-static.
+ (resolve_function): Use gfc_do_concurrent_flag instead of
+ do_concurrent_flag.
+ (pure_subroutine): Likewise.
+ (resolve_code): Likewise.
+ (resolve_types): Likewise.
+ * intrinsic.c (gfc_intrinsic_sub_interface): Raise error for
+ non-pure intrinsic subroutines within DO CONCURRENT.
+
+2013-08-29 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/52243
+ * trans-expr.c (is_runtime_conformable): New function.
+ * gfc_trans_assignment_1: Use it.
+
+2013-08-26 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/58146
+ * array.c (gfc_ref_dimen_size): If possible, use
+ gfc_dep_difference to calculate array refrence
+ sizes. Fall back to integer code otherwise.
+ * dependency.c (discard_nops). Move up.
+ Also discarde widening integer conversions.
+ (gfc_dep_compare_expr): Use discard_nops.
+
+2013-08-23 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/57798
+ * trans-array.c (gfc_conv_ss_startstride, set_loop_bounds,
+ gfc_set_delta): Generate preliminary code before the outermost loop.
+
+2013-08-23 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/57843
+ * interface.c (gfc_extend_assign): Look for type-bound assignment
+ procedures before non-typebound.
+
+2013-08-23 Mikael Morin <mikael@gcc.gnu.org>
+
+ * trans-array.c (gfc_conv_section_startstride): Move &loop->pre access
+ to the callers.
+ (gfc_conv_ss_startstride, gfc_conv_expr_descriptor): Update callers.
+
+2013-08-22 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58185
+ * match.c (copy_ts_from_selector_to_associate): Only build class
+ container for polymorphic selector. Some cleanup.
+
+2013-08-20 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/53655
+ * trans-decl.c (generate_local_decl): Check if type has any components.
+
+2013-08-19 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/46271
+ * openmp.c (resolve_omp_clauses): Bugfix for procedure pointers.
+
+2013-08-12 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/56666
+ * gfortran.h (gfc_option_t): Add warn_zerotrip.
+ * invoke.texi (-Wzerotrip): Document option.
+ * lang.opt (Wzerotrip): Add.
+ * options.c (gfc_init_options): Initialize warn_zerotrip.
+ (set_Wall): Add handling of warn_zerotrip.
+ (gfc_handle_option): Handle OPT_Wzerotrip.
+ * resolve.c (gfc_resolve_iterator): Honor
+ gfc_option.warn_zerotrip; update error message to show
+ how to suppress the warning.
+
+2013-08-09 Janus Weil <janus@gcc.gnu.org>
+
+ * gfortran.h (gfc_get_code): Modified prototype.
+ * class.c (finalize_component, finalization_scalarizer,
+ finalization_get_offset, finalizer_insert_packed_call,
+ generate_finalization_wrapper, gfc_find_derived_vtab,
+ gfc_find_intrinsic_vtab): Use 'gfc_get_code'.
+ * io.c (match_io_iterator, match_io_element, terminate_io, get_io_list,
+ gfc_match_inquire): Call 'gfc_get_code' with argument.
+ * match.c (match_simple_forall, gfc_match_forall, gfc_match_goto,
+ gfc_match_nullify, gfc_match_call, match_simple_where, gfc_match_where):
+ Ditto.
+ * parse.c (new_level): Ditto.
+ (add_statement): Use XCNEW.
+ * resolve.c (resolve_entries, resolve_allocate_expr,
+ resolve_select_type, build_assignment, build_init_assign): Call
+ 'gfc_get_code' with argument.
+ * st.c (gfc_get_code): Add argument 'op'.
+ * trans-expr.c (gfc_trans_class_array_init_assign): Call 'gfc_get_code'
+ with argument.
+ * trans-stmt.c (gfc_trans_allocate): Ditto.
+
+2013-08-09 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58058
+ * trans-intrinsic.c (gfc_conv_intrinsic_transfer): Free the temporary
+ string, if necessary.
+
+2013-08-06 Martin Jambor <mjambor@suse.cz>
+
+ PR fortran/57987
+ * trans-decl.c (gfc_generate_function_code): Never call
+ cgraph_finalize_function on nested functions.
+
+2013-08-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/57306
+ * class.c (gfc_class_null_initializer): Rename to
+ 'gfc_class_initializer'. Treat non-NULL init-exprs.
+ * gfortran.h (gfc_class_null_initializer): Update prototype.
+ * trans-decl.c (gfc_get_symbol_decl): Treat class variables.
+ * trans-expr.c (gfc_conv_initializer): Ditto.
+ (gfc_trans_subcomponent_assign): Renamed gfc_class_null_initializer.
+
+2013-07-30 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57530
+ * symbol.c (gfc_type_compatible): A type is type compatible with
+ a class if both have the same declared type.
+ * interface.c (compare_type): Reject CLASS/TYPE even if they
+ are type compatible.
+
+2013-07-30 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57530
+ * trans-expr.c (gfc_trans_class_assign): Handle CLASS array
+ functions.
+ (gfc_trans_pointer_assign): Ditto and support pointer assignment of
+ a polymorphic var to a nonpolymorphic var.
+
+2013-07-22 Po Chang <pchang9@cs.wisc.edu>
+
+ * match.c (gfc_match_call): Exit loop after setting i.
+
+ * resolve.c (resolve_variable): Exit loop after setting seen.
+
+ * expr.c (gfc_check_pointer_assign): Exit loop after setting warn.
+
+ * trans-array.c (set_loop_bounds): Exit loop after setting
+ nonoptional_arr.
+
+ * trans-io.c (gfc_trans_transfer): Exit loop after setting seen_vector.
+
2013-07-28 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/58009
diff --git a/gcc/fortran/array.c b/gcc/fortran/array.c
index f07bc64dbca..687ae3d2f0d 100644
--- a/gcc/fortran/array.c
+++ b/gcc/fortran/array.c
@@ -2112,6 +2112,7 @@ bool
gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result, mpz_t *end)
{
mpz_t upper, lower, stride;
+ mpz_t diff;
bool t;
if (dimen < 0 || ar == NULL || dimen > ar->dimen - 1)
@@ -2130,9 +2131,63 @@ gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result, mpz_t *end)
break;
case DIMEN_RANGE:
+
+ mpz_init (stride);
+
+ if (ar->stride[dimen] == NULL)
+ mpz_set_ui (stride, 1);
+ else
+ {
+ if (ar->stride[dimen]->expr_type != EXPR_CONSTANT)
+ {
+ mpz_clear (stride);
+ return false;
+ }
+ mpz_set (stride, ar->stride[dimen]->value.integer);
+ }
+
+ /* Calculate the number of elements via gfc_dep_differce, but only if
+ start and end are both supplied in the reference or the array spec.
+ This is to guard against strange but valid code like
+
+ subroutine foo(a,n)
+ real a(1:n)
+ n = 3
+ print *,size(a(n-1:))
+
+ where the user changes the value of a variable. If we have to
+ determine end as well, we cannot do this using gfc_dep_difference.
+ Fall back to the constants-only code then. */
+
+ if (end == NULL)
+ {
+ bool use_dep;
+
+ use_dep = gfc_dep_difference (ar->end[dimen], ar->start[dimen],
+ &diff);
+ if (!use_dep && ar->end[dimen] == NULL && ar->start[dimen] == NULL)
+ use_dep = gfc_dep_difference (ar->as->upper[dimen],
+ ar->as->lower[dimen], &diff);
+
+ if (use_dep)
+ {
+ mpz_init (*result);
+ mpz_add (*result, diff, stride);
+ mpz_div (*result, *result, stride);
+ if (mpz_cmp_ui (*result, 0) < 0)
+ mpz_set_ui (*result, 0);
+
+ mpz_clear (stride);
+ mpz_clear (diff);
+ return true;
+ }
+
+ }
+
+ /* Constant-only code here, which covers more cases
+ like a(:4) etc. */
mpz_init (upper);
mpz_init (lower);
- mpz_init (stride);
t = false;
if (ar->start[dimen] == NULL)
@@ -2163,15 +2218,6 @@ gfc_ref_dimen_size (gfc_array_ref *ar, int dimen, mpz_t *result, mpz_t *end)
mpz_set (upper, ar->end[dimen]->value.integer);
}
- if (ar->stride[dimen] == NULL)
- mpz_set_ui (stride, 1);
- else
- {
- if (ar->stride[dimen]->expr_type != EXPR_CONSTANT)
- goto cleanup;
- mpz_set (stride, ar->stride[dimen]->value.integer);
- }
-
mpz_init (*result);
mpz_sub (*result, upper, lower);
mpz_add (*result, *result, stride);
diff --git a/gcc/fortran/class.c b/gcc/fortran/class.c
index 51bfd5685ea..629b052fb32 100644
--- a/gcc/fortran/class.c
+++ b/gcc/fortran/class.c
@@ -412,12 +412,12 @@ gfc_is_class_container_ref (gfc_expr *e)
}
-/* Build a NULL initializer for CLASS pointers,
- initializing the _data component to NULL and
- the _vptr component to the declared type. */
+/* Build an initializer for CLASS pointers,
+ initializing the _data component to the init_expr (or NULL) and the _vptr
+ component to the corresponding type (or the declared type, given by ts). */
gfc_expr *
-gfc_class_null_initializer (gfc_typespec *ts, gfc_expr *init_expr)
+gfc_class_initializer (gfc_typespec *ts, gfc_expr *init_expr)
{
gfc_expr *init;
gfc_component *comp;
@@ -430,6 +430,8 @@ gfc_class_null_initializer (gfc_typespec *ts, gfc_expr *init_expr)
if (is_unlimited_polymorphic && init_expr)
vtab = gfc_find_intrinsic_vtab (&ts->u.derived->components->ts);
+ else if (init_expr && init_expr->expr_type != EXPR_NULL)
+ vtab = gfc_find_derived_vtab (init_expr->ts.u.derived);
else
vtab = gfc_find_derived_vtab (ts->u.derived);
@@ -442,6 +444,8 @@ gfc_class_null_initializer (gfc_typespec *ts, gfc_expr *init_expr)
gfc_constructor *ctor = gfc_constructor_get();
if (strcmp (comp->name, "_vptr") == 0 && vtab)
ctor->expr = gfc_lval_expr_from_sym (vtab);
+ else if (init_expr && init_expr->expr_type != EXPR_NULL)
+ ctor->expr = gfc_copy_expr (init_expr);
else
ctor->expr = gfc_get_null_expr (NULL);
gfc_constructor_append (&init->value.constructor, ctor);
@@ -859,7 +863,7 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
|| (comp->ts.type == BT_CLASS && CLASS_DATA (comp)
&& CLASS_DATA (comp)->attr.allocatable))
{
- block = XCNEW (gfc_code);
+ block = gfc_get_code (EXEC_IF);
if (*code)
{
(*code)->next = block;
@@ -868,19 +872,12 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
else
(*code) = block;
- block->loc = gfc_current_locus;
- block->op = EXEC_IF;
-
- block->block = XCNEW (gfc_code);
+ block->block = gfc_get_code (EXEC_IF);
block = block->block;
- block->loc = gfc_current_locus;
- block->op = EXEC_IF;
block->expr1 = gfc_lval_expr_from_sym (fini_coarray);
}
- dealloc = XCNEW (gfc_code);
- dealloc->op = EXEC_DEALLOCATE;
- dealloc->loc = gfc_current_locus;
+ dealloc = gfc_get_code (EXEC_DEALLOCATE);
dealloc->ext.alloc.list = gfc_get_alloc ();
dealloc->ext.alloc.list->expr = e;
@@ -911,10 +908,7 @@ finalize_component (gfc_expr *expr, gfc_symbol *derived, gfc_component *comp,
break;
gcc_assert (c);
- final_wrap = XCNEW (gfc_code);
- final_wrap->op = EXEC_CALL;
- final_wrap->loc = gfc_current_locus;
- final_wrap->loc = gfc_current_locus;
+ final_wrap = gfc_get_code (EXEC_CALL);
final_wrap->symtree = c->initializer->symtree;
final_wrap->resolved_sym = c->initializer->symtree->n.sym;
final_wrap->ext.actual = gfc_get_actual_arglist ();
@@ -951,9 +945,7 @@ finalization_scalarizer (gfc_symbol *array, gfc_symbol *ptr,
gfc_expr *expr, *expr2;
/* C_F_POINTER(). */
- block = XCNEW (gfc_code);
- block->op = EXEC_CALL;
- block->loc = gfc_current_locus;
+ block = gfc_get_code (EXEC_CALL);
gfc_get_sym_tree ("c_f_pointer", sub_ns, &block->symtree, true);
block->resolved_sym = block->symtree->n.sym;
block->resolved_sym->attr.flavor = FL_PROCEDURE;
@@ -1033,10 +1025,8 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
gfc_expr *expr, *expr2;
/* offset = 0. */
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_ASSIGN);
block = block->next;
- block->op = EXEC_ASSIGN;
- block->loc = gfc_current_locus;
block->expr1 = gfc_lval_expr_from_sym (offset);
block->expr2 = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
@@ -1046,13 +1036,10 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
iter->end = gfc_copy_expr (rank);
iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_DO);
block = block->next;
- block->op = EXEC_DO;
- block->loc = gfc_current_locus;
block->ext.iterator = iter;
- block->block = gfc_get_code ();
- block->block->op = EXEC_DO;
+ block->block = gfc_get_code (EXEC_DO);
/* Loop body: offset = offset + mod (idx, sizes(idx2)) / sizes(idx2-1)
* strides(idx2). */
@@ -1111,9 +1098,7 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
expr->ts = idx->ts;
/* offset = offset + ... */
- block->block->next = XCNEW (gfc_code);
- block->block->next->op = EXEC_ASSIGN;
- block->block->next->loc = gfc_current_locus;
+ block->block->next = gfc_get_code (EXEC_ASSIGN);
block->block->next->expr1 = gfc_lval_expr_from_sym (offset);
block->block->next->expr2 = gfc_get_expr ();
block->block->next->expr2->expr_type = EXPR_OP;
@@ -1123,10 +1108,8 @@ finalization_get_offset (gfc_symbol *idx, gfc_symbol *idx2, gfc_symbol *offset,
block->block->next->expr2->ts = idx->ts;
/* After the loop: offset = offset * byte_stride. */
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_ASSIGN);
block = block->next;
- block->op = EXEC_ASSIGN;
- block->loc = gfc_current_locus;
block->expr1 = gfc_lval_expr_from_sym (offset);
block->expr2 = gfc_get_expr ();
block->expr2->expr_type = EXPR_OP;
@@ -1185,15 +1168,11 @@ finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
gfc_code *block2;
int i;
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_IF);
block = block->next;
- block->loc = gfc_current_locus;
- block->op = EXEC_IF;
- block->block = XCNEW (gfc_code);
+ block->block = gfc_get_code (EXEC_IF);
block = block->block;
- block->loc = gfc_current_locus;
- block->op = EXEC_IF;
/* size_expr = STORAGE_SIZE (...) / NUMERIC_STORAGE_SIZE. */
size_expr = gfc_get_expr ();
@@ -1270,9 +1249,7 @@ finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
block->expr1->value.op.op2->value.op.op2 = gfc_copy_expr (size_expr);
/* IF body: call final subroutine. */
- block->next = XCNEW (gfc_code);
- block->next->op = EXEC_CALL;
- block->next->loc = gfc_current_locus;
+ block->next = gfc_get_code (EXEC_CALL);
block->next->symtree = fini->proc_tree;
block->next->resolved_sym = fini->proc_tree->n.sym;
block->next->ext.actual = gfc_get_actual_arglist ();
@@ -1280,17 +1257,13 @@ finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
/* ELSE. */
- block->block = XCNEW (gfc_code);
+ block->block = gfc_get_code (EXEC_IF);
block = block->block;
- block->loc = gfc_current_locus;
- block->op = EXEC_IF;
- block->next = XCNEW (gfc_code);
+ /* BLOCK ... END BLOCK. */
+ block->next = gfc_get_code (EXEC_BLOCK);
block = block->next;
- /* BLOCK ... END BLOCK. */
- block->op = EXEC_BLOCK;
- block->loc = gfc_current_locus;
ns = gfc_build_block_ns (sub_ns);
block->ext.block.ns = ns;
block->ext.block.assoc = NULL;
@@ -1343,13 +1316,10 @@ finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
iter->end = gfc_lval_expr_from_sym (nelem);
iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
- block = XCNEW (gfc_code);
+ block = gfc_get_code (EXEC_DO);
ns->code = block;
- block->op = EXEC_DO;
- block->loc = gfc_current_locus;
block->ext.iterator = iter;
- block->block = gfc_get_code ();
- block->block->op = EXEC_DO;
+ block->block = gfc_get_code (EXEC_DO);
/* Offset calculation for the new array: idx * size of type (in bytes). */
offset2 = gfc_get_expr ();
@@ -1374,18 +1344,14 @@ finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
block2 = block2->next;
/* ptr2 = ptr. */
- block2->next = XCNEW (gfc_code);
+ block2->next = gfc_get_code (EXEC_ASSIGN);
block2 = block2->next;
- block2->op = EXEC_ASSIGN;
- block2->loc = gfc_current_locus;
block2->expr1 = gfc_lval_expr_from_sym (ptr2);
block2->expr2 = gfc_lval_expr_from_sym (ptr);
/* Call now the user's final subroutine. */
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_CALL);
block = block->next;
- block->op = EXEC_CALL;
- block->loc = gfc_current_locus;
block->symtree = fini->proc_tree;
block->resolved_sym = fini->proc_tree->n.sym;
block->ext.actual = gfc_get_actual_arglist ();
@@ -1403,13 +1369,10 @@ finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
iter->end = gfc_lval_expr_from_sym (nelem);
iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_DO);
block = block->next;
- block->op = EXEC_DO;
- block->loc = gfc_current_locus;
block->ext.iterator = iter;
- block->block = gfc_get_code ();
- block->block->op = EXEC_DO;
+ block->block = gfc_get_code (EXEC_DO);
/* Offset calculation of "array". */
block2 = finalization_get_offset (idx, idx2, offset, strides, sizes,
@@ -1427,9 +1390,7 @@ finalizer_insert_packed_call (gfc_code *block, gfc_finalizer *fini,
block2 = block2->next;
/* ptr = ptr2. */
- block2->next = XCNEW (gfc_code);
- block2->next->op = EXEC_ASSIGN;
- block2->next->loc = gfc_current_locus;
+ block2->next = gfc_get_code (EXEC_ASSIGN);
block2->next->expr1 = gfc_lval_expr_from_sym (ptr);
block2->next->expr2 = gfc_lval_expr_from_sym (ptr2);
}
@@ -1691,27 +1652,21 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
/* Set return value to 0. */
- last_code = XCNEW (gfc_code);
- last_code->op = EXEC_ASSIGN;
- last_code->loc = gfc_current_locus;
+ last_code = gfc_get_code (EXEC_ASSIGN);
last_code->expr1 = gfc_lval_expr_from_sym (final);
last_code->expr2 = gfc_get_int_expr (4, NULL, 0);
sub_ns->code = last_code;
/* Set: is_contiguous = .true. */
- last_code->next = XCNEW (gfc_code);
+ last_code->next = gfc_get_code (EXEC_ASSIGN);
last_code = last_code->next;
- last_code->op = EXEC_ASSIGN;
- last_code->loc = gfc_current_locus;
last_code->expr1 = gfc_lval_expr_from_sym (is_contiguous);
last_code->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
&gfc_current_locus, true);
/* Set: sizes(0) = 1. */
- last_code->next = XCNEW (gfc_code);
+ last_code->next = gfc_get_code (EXEC_ASSIGN);
last_code = last_code->next;
- last_code->op = EXEC_ASSIGN;
- last_code->loc = gfc_current_locus;
last_code->expr1 = gfc_lval_expr_from_sym (sizes);
last_code->expr1->ref = gfc_get_ref ();
last_code->expr1->ref->type = REF_ARRAY;
@@ -1736,19 +1691,14 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
iter->end = gfc_copy_expr (rank);
iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
- last_code->next = XCNEW (gfc_code);
+ last_code->next = gfc_get_code (EXEC_DO);
last_code = last_code->next;
- last_code->op = EXEC_DO;
- last_code->loc = gfc_current_locus;
last_code->ext.iterator = iter;
- last_code->block = gfc_get_code ();
- last_code->block->op = EXEC_DO;
+ last_code->block = gfc_get_code (EXEC_DO);
/* strides(idx) = _F._stride(array,dim=idx). */
- last_code->block->next = XCNEW (gfc_code);
+ last_code->block->next = gfc_get_code (EXEC_ASSIGN);
block = last_code->block->next;
- block->op = EXEC_ASSIGN;
- block->loc = gfc_current_locus;
block->expr1 = gfc_lval_expr_from_sym (strides);
block->expr1->ref = gfc_get_ref ();
@@ -1765,10 +1715,8 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
gfc_lval_expr_from_sym (idx));
/* sizes(idx) = sizes(idx-1) * size(array,dim=idx, kind=index_kind). */
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_ASSIGN);
block = block->next;
- block->op = EXEC_ASSIGN;
- block->loc = gfc_current_locus;
/* sizes(idx) = ... */
block->expr1 = gfc_lval_expr_from_sym (sizes);
@@ -1815,15 +1763,11 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
block->expr2->ts = idx->ts;
/* if (strides (idx) /= sizes(idx-1)) is_contiguous = .false. */
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_IF);
block = block->next;
- block->loc = gfc_current_locus;
- block->op = EXEC_IF;
- block->block = XCNEW (gfc_code);
+ block->block = gfc_get_code (EXEC_IF);
block = block->block;
- block->loc = gfc_current_locus;
- block->op = EXEC_IF;
/* if condition: strides(idx) /= sizes(idx-1). */
block->expr1 = gfc_get_expr ();
@@ -1860,10 +1804,8 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
= block->expr1->value.op.op2->ref->u.ar.start[0]->value.op.op1->ts;
/* if body: is_contiguous = .false. */
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_ASSIGN);
block = block->next;
- block->op = EXEC_ASSIGN;
- block->loc = gfc_current_locus;
block->expr1 = gfc_lval_expr_from_sym (is_contiguous);
block->expr2 = gfc_get_logical_expr (gfc_default_logical_kind,
&gfc_current_locus, false);
@@ -1879,10 +1821,8 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
gfc_commit_symbol (nelem);
/* nelem = sizes (rank) - 1. */
- last_code->next = XCNEW (gfc_code);
+ last_code->next = gfc_get_code (EXEC_ASSIGN);
last_code = last_code->next;
- last_code->op = EXEC_ASSIGN;
- last_code->loc = gfc_current_locus;
last_code->expr1 = gfc_lval_expr_from_sym (nelem);
@@ -1934,10 +1874,8 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
gfc_commit_symbol (ptr);
/* SELECT CASE (RANK (array)). */
- last_code->next = XCNEW (gfc_code);
+ last_code->next = gfc_get_code (EXEC_SELECT);
last_code = last_code->next;
- last_code->op = EXEC_SELECT;
- last_code->loc = gfc_current_locus;
last_code->expr1 = gfc_copy_expr (rank);
block = NULL;
@@ -1952,16 +1890,14 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
/* CASE (fini_rank). */
if (block)
{
- block->block = XCNEW (gfc_code);
+ block->block = gfc_get_code (EXEC_SELECT);
block = block->block;
}
else
{
- block = XCNEW (gfc_code);
+ block = gfc_get_code (EXEC_SELECT);
last_code->block = block;
}
- block->loc = gfc_current_locus;
- block->op = EXEC_SELECT;
block->ext.block.case_list = gfc_get_case ();
block->ext.block.case_list->where = gfc_current_locus;
if (fini->proc_tree->n.sym->formal->sym->attr.dimension)
@@ -1982,9 +1918,7 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
rank, sub_ns);
else
{
- block->next = XCNEW (gfc_code);
- block->next->op = EXEC_CALL;
- block->next->loc = gfc_current_locus;
+ block->next = gfc_get_code (EXEC_CALL);
block->next->symtree = fini->proc_tree;
block->next->resolved_sym = fini->proc_tree->n.sym;
block->next->ext.actual = gfc_get_actual_arglist ();
@@ -1998,16 +1932,14 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
/* CASE DEFAULT. */
if (block)
{
- block->block = XCNEW (gfc_code);
+ block->block = gfc_get_code (EXEC_SELECT);
block = block->block;
}
else
{
- block = XCNEW (gfc_code);
+ block = gfc_get_code (EXEC_SELECT);
last_code->block = block;
}
- block->loc = gfc_current_locus;
- block->op = EXEC_SELECT;
block->ext.block.case_list = gfc_get_case ();
/* Create loop. */
@@ -2016,13 +1948,10 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
iter->end = gfc_lval_expr_from_sym (nelem);
iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_DO);
block = block->next;
- block->op = EXEC_DO;
- block->loc = gfc_current_locus;
block->ext.iterator = iter;
- block->block = gfc_get_code ();
- block->block->op = EXEC_DO;
+ block->block = gfc_get_code (EXEC_DO);
/* Offset calculation. */
block = finalization_get_offset (idx, idx2, offset, strides, sizes,
@@ -2039,10 +1968,8 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
block = block->next;
/* CALL final_elemental (array). */
- block->next = XCNEW (gfc_code);
+ block->next = gfc_get_code (EXEC_CALL);
block = block->next;
- block->op = EXEC_CALL;
- block->loc = gfc_current_locus;
block->symtree = fini_elem->proc_tree;
block->resolved_sym = fini_elem->proc_sym;
block->ext.actual = gfc_get_actual_arglist ();
@@ -2084,13 +2011,10 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
iter->start = gfc_get_int_expr (gfc_index_integer_kind, NULL, 0);
iter->end = gfc_lval_expr_from_sym (nelem);
iter->step = gfc_get_int_expr (gfc_index_integer_kind, NULL, 1);
- last_code->next = XCNEW (gfc_code);
+ last_code->next = gfc_get_code (EXEC_DO);
last_code = last_code->next;
- last_code->op = EXEC_DO;
- last_code->loc = gfc_current_locus;
last_code->ext.iterator = iter;
- last_code->block = gfc_get_code ();
- last_code->block->op = EXEC_DO;
+ last_code->block = gfc_get_code (EXEC_DO);
/* Offset calculation. */
block = finalization_get_offset (idx, idx2, offset, strides, sizes,
@@ -2122,10 +2046,8 @@ generate_finalization_wrapper (gfc_symbol *derived, gfc_namespace *ns,
/* Call the finalizer of the ancestor. */
if (ancestor_wrapper && ancestor_wrapper->expr_type != EXPR_NULL)
{
- last_code->next = XCNEW (gfc_code);
+ last_code->next = gfc_get_code (EXEC_CALL);
last_code = last_code->next;
- last_code->op = EXEC_CALL;
- last_code->loc = gfc_current_locus;
last_code->symtree = ancestor_wrapper->symtree;
last_code->resolved_sym = ancestor_wrapper->symtree->n.sym;
@@ -2371,8 +2293,7 @@ gfc_find_derived_vtab (gfc_symbol *derived)
copy->formal->next = gfc_get_formal_arglist ();
copy->formal->next->sym = dst;
/* Set up code. */
- sub_ns->code = gfc_get_code ();
- sub_ns->code->op = EXEC_INIT_ASSIGN;
+ sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
/* Set initializer. */
@@ -2655,8 +2576,7 @@ gfc_find_intrinsic_vtab (gfc_typespec *ts)
copy->formal->next = gfc_get_formal_arglist ();
copy->formal->next->sym = dst;
/* Set up code. */
- sub_ns->code = gfc_get_code ();
- sub_ns->code->op = EXEC_INIT_ASSIGN;
+ sub_ns->code = gfc_get_code (EXEC_INIT_ASSIGN);
sub_ns->code->expr1 = gfc_lval_expr_from_sym (dst);
sub_ns->code->expr2 = gfc_lval_expr_from_sym (src);
got_char_copy:
diff --git a/gcc/fortran/dependency.c b/gcc/fortran/dependency.c
index 350c7bd07a2..d85905cb6b8 100644
--- a/gcc/fortran/dependency.c
+++ b/gcc/fortran/dependency.c
@@ -240,6 +240,46 @@ gfc_dep_compare_functions (gfc_expr *e1, gfc_expr *e2, bool impure_ok)
return -2;
}
+/* Helper function to look through parens, unary plus and widening
+ integer conversions. */
+
+static gfc_expr*
+discard_nops (gfc_expr *e)
+{
+ gfc_actual_arglist *arglist;
+
+ if (e == NULL)
+ return NULL;
+
+ while (true)
+ {
+ if (e->expr_type == EXPR_OP
+ && (e->value.op.op == INTRINSIC_UPLUS
+ || e->value.op.op == INTRINSIC_PARENTHESES))
+ {
+ e = e->value.op.op1;
+ continue;
+ }
+
+ if (e->expr_type == EXPR_FUNCTION && e->value.function.isym
+ && e->value.function.isym->id == GFC_ISYM_CONVERSION
+ && e->ts.type == BT_INTEGER)
+ {
+ arglist = e->value.function.actual;
+ if (arglist->expr->ts.type == BT_INTEGER
+ && e->ts.kind > arglist->expr->ts.kind)
+ {
+ e = arglist->expr;
+ continue;
+ }
+ }
+ break;
+ }
+
+ return e;
+}
+
+
/* Compare two expressions. Return values:
* +1 if e1 > e2
* 0 if e1 == e2
@@ -252,59 +292,13 @@ gfc_dep_compare_functions (gfc_expr *e1, gfc_expr *e2, bool impure_ok)
int
gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
{
- gfc_actual_arglist *args1;
- gfc_actual_arglist *args2;
int i;
- gfc_expr *n1, *n2;
-
- n1 = NULL;
- n2 = NULL;
if (e1 == NULL && e2 == NULL)
return 0;
- /* Remove any integer conversion functions to larger types. */
- if (e1->expr_type == EXPR_FUNCTION && e1->value.function.isym
- && e1->value.function.isym->id == GFC_ISYM_CONVERSION
- && e1->ts.type == BT_INTEGER)
- {
- args1 = e1->value.function.actual;
- if (args1->expr->ts.type == BT_INTEGER
- && e1->ts.kind > args1->expr->ts.kind)
- n1 = args1->expr;
- }
-
- if (e2->expr_type == EXPR_FUNCTION && e2->value.function.isym
- && e2->value.function.isym->id == GFC_ISYM_CONVERSION
- && e2->ts.type == BT_INTEGER)
- {
- args2 = e2->value.function.actual;
- if (args2->expr->ts.type == BT_INTEGER
- && e2->ts.kind > args2->expr->ts.kind)
- n2 = args2->expr;
- }
-
- if (n1 != NULL)
- {
- if (n2 != NULL)
- return gfc_dep_compare_expr (n1, n2);
- else
- return gfc_dep_compare_expr (n1, e2);
- }
- else
- {
- if (n2 != NULL)
- return gfc_dep_compare_expr (e1, n2);
- }
-
- if (e1->expr_type == EXPR_OP
- && (e1->value.op.op == INTRINSIC_UPLUS
- || e1->value.op.op == INTRINSIC_PARENTHESES))
- return gfc_dep_compare_expr (e1->value.op.op1, e2);
- if (e2->expr_type == EXPR_OP
- && (e2->value.op.op == INTRINSIC_UPLUS
- || e2->value.op.op == INTRINSIC_PARENTHESES))
- return gfc_dep_compare_expr (e1, e2->value.op.op1);
+ e1 = discard_nops (e1);
+ e2 = discard_nops (e2);
if (e1->expr_type == EXPR_OP && e1->value.op.op == INTRINSIC_PLUS)
{
@@ -501,21 +495,6 @@ gfc_dep_compare_expr (gfc_expr *e1, gfc_expr *e2)
}
-/* Helper function to look through parens and unary plus. */
-
-static gfc_expr*
-discard_nops (gfc_expr *e)
-{
-
- while (e && e->expr_type == EXPR_OP
- && (e->value.op.op == INTRINSIC_UPLUS
- || e->value.op.op == INTRINSIC_PARENTHESES))
- e = e->value.op.op1;
-
- return e;
-}
-
-
/* Return the difference between two expressions. Integer expressions of
the form
diff --git a/gcc/fortran/expr.c b/gcc/fortran/expr.c
index c00fbc5493f..61f0f8275cc 100644
--- a/gcc/fortran/expr.c
+++ b/gcc/fortran/expr.c
@@ -3764,7 +3764,10 @@ gfc_check_pointer_assign (gfc_expr *lvalue, gfc_expr *rvalue)
ns && ns->proc_name && ns->proc_name->attr.flavor != FL_PROCEDURE;
ns = ns->parent)
if (ns->parent == lvalue->symtree->n.sym->ns)
- warn = true;
+ {
+ warn = true;
+ break;
+ }
if (warn)
gfc_warning ("Pointer at %L in pointer assignment might outlive the "
diff --git a/gcc/fortran/f95-lang.c b/gcc/fortran/f95-lang.c
index 30cbfe59476..7bb2913552c 100644
--- a/gcc/fortran/f95-lang.c
+++ b/gcc/fortran/f95-lang.c
@@ -826,7 +826,7 @@ gfc_init_builtin_functions (void)
BUILT_IN_POWIF, "powif", ATTR_CONST_NOTHROW_LEAF_LIST);
- if (TARGET_C99_FUNCTIONS)
+ if (targetm.libc_has_function (function_c99_math_complex))
{
gfc_define_builtin ("__builtin_cbrtl", mfunc_longdouble[0],
BUILT_IN_CBRTL, "cbrtl",
@@ -848,7 +848,7 @@ gfc_init_builtin_functions (void)
ATTR_CONST_NOTHROW_LEAF_LIST);
}
- if (TARGET_HAS_SINCOS)
+ if (targetm.libc_has_function (function_sincos))
{
gfc_define_builtin ("__builtin_sincosl",
func_longdouble_longdoublep_longdoublep,
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index c11ffdda8b9..b28edd80002 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -2252,6 +2252,7 @@ typedef struct
int warn_align_commons;
int warn_real_q_constant;
int warn_unused_dummy_argument;
+ int warn_zerotrip;
int warn_realloc_lhs;
int warn_realloc_lhs_all;
int warn_compare_reals;
@@ -2820,7 +2821,7 @@ bool gfc_check_vardef_context (gfc_expr*, bool, bool, bool, const char*);
extern gfc_code new_st;
void gfc_clear_new_st (void);
-gfc_code *gfc_get_code (void);
+gfc_code *gfc_get_code (gfc_exec_op);
gfc_code *gfc_append_code (gfc_code *, gfc_code *);
void gfc_free_statement (gfc_code *);
void gfc_free_statements (gfc_code *);
@@ -2845,6 +2846,7 @@ gfc_expr *gfc_expr_to_initialize (gfc_expr *);
bool gfc_type_is_extensible (gfc_symbol *);
bool gfc_resolve_intrinsic (gfc_symbol *, locus *);
bool gfc_explicit_interface_required (gfc_symbol *, char *, int);
+extern int gfc_do_concurrent_flag;
/* array.c */
@@ -2983,7 +2985,7 @@ void gfc_add_class_array_ref (gfc_expr *);
bool gfc_is_class_array_ref (gfc_expr *, bool *);
bool gfc_is_class_scalar_expr (gfc_expr *);
bool gfc_is_class_container_ref (gfc_expr *e);
-gfc_expr *gfc_class_null_initializer (gfc_typespec *, gfc_expr *);
+gfc_expr *gfc_class_initializer (gfc_typespec *, gfc_expr *);
unsigned int gfc_hash_value (gfc_symbol *);
bool gfc_build_class_symbol (gfc_typespec *, symbol_attribute *,
gfc_array_spec **, bool);
diff --git a/gcc/fortran/interface.c b/gcc/fortran/interface.c
index 339dd243c12..aa88b3c3fa6 100644
--- a/gcc/fortran/interface.c
+++ b/gcc/fortran/interface.c
@@ -514,6 +514,12 @@ compare_type (gfc_symbol *s1, gfc_symbol *s2)
if (s2->attr.ext_attr & (1 << EXT_ATTR_NO_ARG_CHECK))
return 1;
+ /* TYPE and CLASS of the same declared type are type compatible,
+ but have different characteristics. */
+ if ((s1->ts.type == BT_CLASS && s2->ts.type == BT_DERIVED)
+ || (s1->ts.type == BT_DERIVED && s2->ts.type == BT_CLASS))
+ return 0;
+
return gfc_compare_types (&s1->ts, &s2->ts) || s2->ts.type == BT_ASSUMED;
}
@@ -3748,20 +3754,18 @@ gfc_extend_expr (gfc_expr *e)
}
-/* Tries to replace an assignment code node with a subroutine call to
- the subroutine associated with the assignment operator. Return
- true if the node was replaced. On false, no error is
- generated. */
+/* Tries to replace an assignment code node with a subroutine call to the
+ subroutine associated with the assignment operator. Return true if the node
+ was replaced. On false, no error is generated. */
bool
gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
{
gfc_actual_arglist *actual;
- gfc_expr *lhs, *rhs;
- gfc_symbol *sym;
- const char *gname;
-
- gname = NULL;
+ gfc_expr *lhs, *rhs, *tb_base;
+ gfc_symbol *sym = NULL;
+ const char *gname = NULL;
+ gfc_typebound_proc* tbo;
lhs = c->expr1;
rhs = c->expr2;
@@ -3779,8 +3783,26 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
actual->next = gfc_get_actual_arglist ();
actual->next->expr = rhs;
- sym = NULL;
+ /* TODO: Ambiguity-check, see above for gfc_extend_expr. */
+
+ /* See if we find a matching type-bound assignment. */
+ tbo = matching_typebound_op (&tb_base, actual, INTRINSIC_ASSIGN,
+ NULL, &gname);
+ if (tbo)
+ {
+ /* Success: Replace the expression with a type-bound call. */
+ gcc_assert (tb_base);
+ c->expr1 = gfc_get_expr ();
+ build_compcall_for_operator (c->expr1, actual, tb_base, tbo, gname);
+ c->expr1->value.compcall.assign = 1;
+ c->expr1->where = c->loc;
+ c->expr2 = NULL;
+ c->op = EXEC_COMPCALL;
+ return true;
+ }
+
+ /* See if we find an 'ordinary' (non-typebound) assignment procedure. */
for (; ns; ns = ns->parent)
{
sym = gfc_search_interface (ns->op[INTRINSIC_ASSIGN], 1, &actual);
@@ -3788,47 +3810,21 @@ gfc_extend_assign (gfc_code *c, gfc_namespace *ns)
break;
}
- /* TODO: Ambiguity-check, see above for gfc_extend_expr. */
-
- if (sym == NULL)
+ if (sym)
{
- gfc_typebound_proc* tbo;
- gfc_expr* tb_base;
-
- /* See if we find a matching type-bound assignment. */
- tbo = matching_typebound_op (&tb_base, actual,
- INTRINSIC_ASSIGN, NULL, &gname);
-
- /* If there is one, replace the expression with a call to it and
- succeed. */
- if (tbo)
- {
- gcc_assert (tb_base);
- c->expr1 = gfc_get_expr ();
- build_compcall_for_operator (c->expr1, actual, tb_base, tbo, gname);
- c->expr1->value.compcall.assign = 1;
- c->expr1->where = c->loc;
- c->expr2 = NULL;
- c->op = EXEC_COMPCALL;
-
- /* c is resolved from the caller, so no need to do it here. */
-
- return true;
- }
-
- free (actual->next);
- free (actual);
- return false;
+ /* Success: Replace the assignment with the call. */
+ c->op = EXEC_ASSIGN_CALL;
+ c->symtree = gfc_find_sym_in_symtree (sym);
+ c->expr1 = NULL;
+ c->expr2 = NULL;
+ c->ext.actual = actual;
+ return true;
}
- /* Replace the assignment with the call. */
- c->op = EXEC_ASSIGN_CALL;
- c->symtree = gfc_find_sym_in_symtree (sym);
- c->expr1 = NULL;
- c->expr2 = NULL;
- c->ext.actual = actual;
-
- return true;
+ /* Failure: No assignment procedure found. */
+ free (actual->next);
+ free (actual);
+ return false;
}
diff --git a/gcc/fortran/intrinsic.c b/gcc/fortran/intrinsic.c
index c2e1525a268..3da3c5365a0 100644
--- a/gcc/fortran/intrinsic.c
+++ b/gcc/fortran/intrinsic.c
@@ -4397,6 +4397,13 @@ gfc_intrinsic_sub_interface (gfc_code *c, int error_flag)
c->resolved_sym->attr.elemental = isym->elemental;
}
+ if (gfc_do_concurrent_flag && !isym->pure)
+ {
+ gfc_error ("Subroutine call to intrinsic '%s' in DO CONCURRENT "
+ "block at %L is not PURE", name, &c->loc);
+ return MATCH_ERROR;
+ }
+
if (gfc_pure (NULL) && !isym->pure)
{
gfc_error ("Subroutine call to intrinsic '%s' at %L is not PURE", name,
diff --git a/gcc/fortran/invoke.texi b/gcc/fortran/invoke.texi
index 3af57a300f8..69bec275de9 100644
--- a/gcc/fortran/invoke.texi
+++ b/gcc/fortran/invoke.texi
@@ -954,6 +954,11 @@ This option is implied by @option{-Wextra}.
Warn if the pointer in a pointer assignment might be longer than the its
target. This option is implied by @option{-Wall}.
+@item -Wzerotrip
+@opindex @code{Wzerotrip}
+Warn if a @code{DO} loop is known to execute zero times at compile
+time. This option is implied by @option{-Wall}.
+
@item -Werror
@opindex @code{Werror}
@cindex warnings, to errors
diff --git a/gcc/fortran/io.c b/gcc/fortran/io.c
index 678bc5d844e..cc5ce12781e 100644
--- a/gcc/fortran/io.c
+++ b/gcc/fortran/io.c
@@ -3055,12 +3055,10 @@ match_io_iterator (io_kind k, gfc_code **result)
if (gfc_match_char (')') != MATCH_YES)
goto syntax;
- new_code = gfc_get_code ();
- new_code->op = EXEC_DO;
+ new_code = gfc_get_code (EXEC_DO);
new_code->ext.iterator = iter;
- new_code->block = gfc_get_code ();
- new_code->block->op = EXEC_DO;
+ new_code->block = gfc_get_code (EXEC_DO);
new_code->block->next = head;
*result = new_code;
@@ -3117,8 +3115,7 @@ match_io_element (io_kind k, gfc_code **cpp)
return MATCH_ERROR;
}
- cp = gfc_get_code ();
- cp->op = EXEC_TRANSFER;
+ cp = gfc_get_code (EXEC_TRANSFER);
cp->expr1 = expr;
if (k != M_INQUIRE)
cp->ext.dt = current_dt;
@@ -3180,8 +3177,7 @@ terminate_io (gfc_code *io_code)
if (io_code == NULL)
io_code = new_st.block;
- c = gfc_get_code ();
- c->op = EXEC_DT_END;
+ c = gfc_get_code (EXEC_DT_END);
/* Point to structure that is already there */
c->ext.dt = new_st.ext.dt;
@@ -3751,8 +3747,7 @@ get_io_list:
new_st.op = (k == M_READ) ? EXEC_READ : EXEC_WRITE;
new_st.ext.dt = dt;
- new_st.block = gfc_get_code ();
- new_st.block->op = new_st.op;
+ new_st.block = gfc_get_code (new_st.op);
new_st.block->next = io_code;
terminate_io (io_code);
@@ -3961,8 +3956,7 @@ gfc_match_inquire (void)
if (gfc_implicit_pure (NULL))
gfc_current_ns->proc_name->attr.implicit_pure = 0;
- new_st.block = gfc_get_code ();
- new_st.block->op = EXEC_IOLENGTH;
+ new_st.block = gfc_get_code (EXEC_IOLENGTH);
terminate_io (code);
new_st.block->next = code;
return MATCH_YES;
diff --git a/gcc/fortran/lang.opt b/gcc/fortran/lang.opt
index 61f77b4fc5f..4f7993433d4 100644
--- a/gcc/fortran/lang.opt
+++ b/gcc/fortran/lang.opt
@@ -293,6 +293,10 @@ Wunused-dummy-argument
Fortran Warning
Warn about unused dummy arguments.
+Wzerotrip
+Fortran Warning
+Warn about zero-trip DO loops
+
cpp
Fortran Negative(nocpp)
Enable preprocessing
diff --git a/gcc/fortran/match.c b/gcc/fortran/match.c
index 7f30156624d..71e3862189a 100644
--- a/gcc/fortran/match.c
+++ b/gcc/fortran/match.c
@@ -1608,13 +1608,12 @@ got_match:
is in new_st. Rearrange things so that the IF statement appears
in new_st. */
- p = gfc_get_code ();
- p->next = gfc_get_code ();
+ p = gfc_get_code (EXEC_IF);
+ p->next = XCNEW (gfc_code);
*p->next = new_st;
p->next->loc = gfc_current_locus;
p->expr1 = expr;
- p->op = EXEC_IF;
gfc_clear_new_st ();
@@ -2224,7 +2223,7 @@ match_simple_forall (void)
goto syntax;
}
- c = gfc_get_code ();
+ c = XCNEW (gfc_code);
*c = new_st;
c->loc = gfc_current_locus;
@@ -2235,9 +2234,7 @@ match_simple_forall (void)
new_st.op = EXEC_FORALL;
new_st.expr1 = mask;
new_st.ext.forall_iterator = head;
- new_st.block = gfc_get_code ();
-
- new_st.block->op = EXEC_FORALL;
+ new_st.block = gfc_get_code (EXEC_FORALL);
new_st.block->next = c;
return MATCH_YES;
@@ -2302,7 +2299,7 @@ gfc_match_forall (gfc_statement *st)
goto syntax;
}
- c = gfc_get_code ();
+ c = XCNEW (gfc_code);
*c = new_st;
c->loc = gfc_current_locus;
@@ -2310,8 +2307,7 @@ gfc_match_forall (gfc_statement *st)
new_st.op = EXEC_FORALL;
new_st.expr1 = mask;
new_st.ext.forall_iterator = head;
- new_st.block = gfc_get_code ();
- new_st.block->op = EXEC_FORALL;
+ new_st.block = gfc_get_code (EXEC_FORALL);
new_st.block->next = c;
*st = ST_FORALL;
@@ -3283,15 +3279,14 @@ gfc_match_goto (void)
goto cleanup;
if (head == NULL)
- head = tail = gfc_get_code ();
+ head = tail = gfc_get_code (EXEC_GOTO);
else
{
- tail->block = gfc_get_code ();
+ tail->block = gfc_get_code (EXEC_GOTO);
tail = tail->block;
}
tail->label1 = label;
- tail->op = EXEC_GOTO;
}
while (gfc_match_char (',') == MATCH_YES);
@@ -3328,10 +3323,10 @@ gfc_match_goto (void)
goto cleanup;
if (head == NULL)
- head = tail = gfc_get_code ();
+ head = tail = gfc_get_code (EXEC_SELECT);
else
{
- tail->block = gfc_get_code ();
+ tail->block = gfc_get_code (EXEC_SELECT);
tail = tail->block;
}
@@ -3339,11 +3334,9 @@ gfc_match_goto (void)
cp->low = cp->high = gfc_get_int_expr (gfc_default_integer_kind,
NULL, i++);
- tail->op = EXEC_SELECT;
tail->ext.block.case_list = cp;
- tail->next = gfc_get_code ();
- tail->next->op = EXEC_GOTO;
+ tail->next = gfc_get_code (EXEC_GOTO);
tail->next->label1 = label;
}
while (gfc_match_char (',') == MATCH_YES);
@@ -3800,14 +3793,16 @@ gfc_match_nullify (void)
/* Chain to list. */
if (tail == NULL)
- tail = &new_st;
+ {
+ tail = &new_st;
+ tail->op = EXEC_POINTER_ASSIGN;
+ }
else
{
- tail->next = gfc_get_code ();
+ tail->next = gfc_get_code (EXEC_POINTER_ASSIGN);
tail = tail->next;
}
- tail->op = EXEC_POINTER_ASSIGN;
tail->expr1 = p;
tail->expr2 = e;
@@ -4188,7 +4183,10 @@ gfc_match_call (void)
i = 0;
for (a = arglist; a; a = a->next)
if (a->expr == NULL)
- i = 1;
+ {
+ i = 1;
+ break;
+ }
if (i)
{
@@ -4196,8 +4194,7 @@ gfc_match_call (void)
gfc_symbol *select_sym;
char name[GFC_MAX_SYMBOL_LEN + 1];
- new_st.next = c = gfc_get_code ();
- c->op = EXEC_SELECT;
+ new_st.next = c = gfc_get_code (EXEC_SELECT);
sprintf (name, "_result_%s", sym->name);
gfc_get_ha_sym_tree (name, &select_st); /* Can't fail. */
@@ -4222,17 +4219,15 @@ gfc_match_call (void)
i++;
- c->block = gfc_get_code ();
+ c->block = gfc_get_code (EXEC_SELECT);
c = c->block;
- c->op = EXEC_SELECT;
new_case = gfc_get_case ();
new_case->high = gfc_get_int_expr (gfc_default_integer_kind, NULL, i);
new_case->low = new_case->high;
c->ext.block.case_list = new_case;
- c->next = gfc_get_code ();
- c->next->op = EXEC_GOTO;
+ c->next = gfc_get_code (EXEC_GOTO);
c->next->label1 = a->label;
}
}
@@ -5098,7 +5093,6 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
{
gfc_ref *ref;
gfc_symbol *assoc_sym;
- int i;
assoc_sym = associate->symtree->n.sym;
@@ -5109,9 +5103,8 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
while (ref && ref->next)
ref = ref->next;
- if (selector->ts.type == BT_CLASS
- && CLASS_DATA (selector)->as
- && ref && ref->type == REF_ARRAY)
+ if (selector->ts.type == BT_CLASS && CLASS_DATA (selector)->as
+ && ref && ref->type == REF_ARRAY)
{
/* Ensure that the array reference type is set. We cannot use
gfc_resolve_expr at this point, so the usable parts of
@@ -5119,7 +5112,7 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
if (ref->u.ar.type == AR_UNKNOWN)
{
ref->u.ar.type = AR_ELEMENT;
- for (i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
+ for (int i = 0; i < ref->u.ar.dimen + ref->u.ar.codimen; i++)
if (ref->u.ar.dimen_type[i] == DIMEN_RANGE
|| ref->u.ar.dimen_type[i] == DIMEN_VECTOR
|| (ref->u.ar.dimen_type[i] == DIMEN_UNKNOWN
@@ -5138,37 +5131,19 @@ copy_ts_from_selector_to_associate (gfc_expr *associate, gfc_expr *selector)
selector->rank = 0;
}
- if (selector->ts.type != BT_CLASS)
+ if (selector->rank)
{
- /* The correct class container has to be available. */
- if (selector->rank)
- {
- assoc_sym->attr.dimension = 1;
- assoc_sym->as = gfc_get_array_spec ();
- assoc_sym->as->rank = selector->rank;
- assoc_sym->as->type = AS_DEFERRED;
- }
- else
- assoc_sym->as = NULL;
-
- assoc_sym->ts.type = BT_CLASS;
- assoc_sym->ts.u.derived = selector->ts.u.derived;
- assoc_sym->attr.pointer = 1;
- gfc_build_class_symbol (&assoc_sym->ts, &assoc_sym->attr,
- &assoc_sym->as, false);
+ assoc_sym->attr.dimension = 1;
+ assoc_sym->as = gfc_get_array_spec ();
+ assoc_sym->as->rank = selector->rank;
+ assoc_sym->as->type = AS_DEFERRED;
}
else
+ assoc_sym->as = NULL;
+
+ if (selector->ts.type == BT_CLASS)
{
/* The correct class container has to be available. */
- if (selector->rank)
- {
- assoc_sym->attr.dimension = 1;
- assoc_sym->as = gfc_get_array_spec ();
- assoc_sym->as->rank = selector->rank;
- assoc_sym->as->type = AS_DEFERRED;
- }
- else
- assoc_sym->as = NULL;
assoc_sym->ts.type = BT_CLASS;
assoc_sym->ts.u.derived = CLASS_DATA (selector)->ts.u.derived;
assoc_sym->attr.pointer = 1;
@@ -5636,12 +5611,10 @@ match_simple_where (void)
if (gfc_match_eos () != MATCH_YES)
goto syntax;
- c = gfc_get_code ();
-
- c->op = EXEC_WHERE;
+ c = gfc_get_code (EXEC_WHERE);
c->expr1 = expr;
- c->next = gfc_get_code ();
+ c->next = XCNEW (gfc_code);
*c->next = new_st;
gfc_clear_new_st ();
@@ -5696,12 +5669,10 @@ gfc_match_where (gfc_statement *st)
/* We've got a simple WHERE statement. */
*st = ST_WHERE;
- c = gfc_get_code ();
-
- c->op = EXEC_WHERE;
+ c = gfc_get_code (EXEC_WHERE);
c->expr1 = expr;
- c->next = gfc_get_code ();
+ c->next = XCNEW (gfc_code);
*c->next = new_st;
gfc_clear_new_st ();
diff --git a/gcc/fortran/openmp.c b/gcc/fortran/openmp.c
index 865f8365cfc..6c4dccbed10 100644
--- a/gcc/fortran/openmp.c
+++ b/gcc/fortran/openmp.c
@@ -847,7 +847,7 @@ resolve_omp_clauses (gfc_code *code)
for (n = omp_clauses->lists[list]; n; n = n->next)
{
n->sym->mark = 0;
- if (n->sym->attr.flavor == FL_VARIABLE)
+ if (n->sym->attr.flavor == FL_VARIABLE || n->sym->attr.proc_pointer)
continue;
if (n->sym->attr.flavor == FL_PROCEDURE
&& n->sym->result == n->sym
@@ -876,8 +876,6 @@ resolve_omp_clauses (gfc_code *code)
if (el)
continue;
}
- if (n->sym->attr.proc_pointer)
- continue;
}
gfc_error ("Object '%s' is not a variable at %L", n->sym->name,
&code->loc);
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index 908b47e68bb..3a9c508dc27 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -109,6 +109,7 @@ gfc_init_options (unsigned int decoded_options_count,
gfc_option.warn_align_commons = 1;
gfc_option.warn_real_q_constant = 0;
gfc_option.warn_unused_dummy_argument = 0;
+ gfc_option.warn_zerotrip = 0;
gfc_option.warn_realloc_lhs = 0;
gfc_option.warn_realloc_lhs_all = 0;
gfc_option.warn_compare_reals = 0;
@@ -466,6 +467,7 @@ set_Wall (int setting)
gfc_option.warn_real_q_constant = setting;
gfc_option.warn_unused_dummy_argument = setting;
gfc_option.warn_target_lifetime = setting;
+ gfc_option.warn_zerotrip = setting;
warn_return_type = setting;
warn_uninitialized = setting;
@@ -747,6 +749,10 @@ gfc_handle_option (size_t scode, const char *arg, int value,
gfc_option.warn_unused_dummy_argument = value;
break;
+ case OPT_Wzerotrip:
+ gfc_option.warn_zerotrip = value;
+ break;
+
case OPT_fall_intrinsics:
gfc_option.flag_all_intrinsics = 1;
break;
diff --git a/gcc/fortran/parse.c b/gcc/fortran/parse.c
index 737f3d61889..512babfd450 100644
--- a/gcc/fortran/parse.c
+++ b/gcc/fortran/parse.c
@@ -1095,7 +1095,7 @@ new_level (gfc_code *q)
{
gfc_code *p;
- p = q->block = gfc_get_code ();
+ p = q->block = gfc_get_code (EXEC_NOP);
gfc_state_stack->head = gfc_state_stack->tail = p;
@@ -1111,7 +1111,7 @@ add_statement (void)
{
gfc_code *p;
- p = gfc_get_code ();
+ p = XCNEW (gfc_code);
*p = new_st;
p->loc = gfc_current_locus;
diff --git a/gcc/fortran/resolve.c b/gcc/fortran/resolve.c
index c3487881631..2929679aecc 100644
--- a/gcc/fortran/resolve.c
+++ b/gcc/fortran/resolve.c
@@ -60,7 +60,7 @@ static code_stack *cs_base = NULL;
/* Nonzero if we're inside a FORALL or DO CONCURRENT block. */
static int forall_flag;
-static int do_concurrent_flag;
+int gfc_do_concurrent_flag;
/* True when we are resolving an expression that is an actual argument to
a procedure. */
@@ -723,8 +723,7 @@ resolve_entries (gfc_namespace *ns)
el = ns->entries;
/* Add an entry statement for it. */
- c = gfc_get_code ();
- c->op = EXEC_ENTRY;
+ c = gfc_get_code (EXEC_ENTRY);
c->ext.entry = el;
c->next = ns->code;
ns->code = c;
@@ -2987,11 +2986,11 @@ resolve_function (gfc_expr *expr)
forall_flag == 2 ? "mask" : "block");
t = false;
}
- else if (do_concurrent_flag)
+ else if (gfc_do_concurrent_flag)
{
gfc_error ("Reference to non-PURE function '%s' at %L inside a "
"DO CONCURRENT %s", name, &expr->where,
- do_concurrent_flag == 2 ? "mask" : "block");
+ gfc_do_concurrent_flag == 2 ? "mask" : "block");
t = false;
}
else if (gfc_pure (NULL))
@@ -3060,7 +3059,7 @@ pure_subroutine (gfc_code *c, gfc_symbol *sym)
if (forall_flag)
gfc_error ("Subroutine call to '%s' in FORALL block at %L is not PURE",
sym->name, &c->loc);
- else if (do_concurrent_flag)
+ else if (gfc_do_concurrent_flag)
gfc_error ("Subroutine call to '%s' in DO CONCURRENT block at %L is not "
"PURE", sym->name, &c->loc);
else if (gfc_pure (NULL))
@@ -4908,7 +4907,10 @@ resolve_variable (gfc_expr *e)
for (formal = entry->sym->formal; formal; formal = formal->next)
{
if (formal->sym && sym->name == formal->sym->name)
- seen = true;
+ {
+ seen = true;
+ break;
+ }
}
/* If it has not been seen as a dummy, this is an error. */
@@ -6279,8 +6281,10 @@ gfc_resolve_iterator (gfc_iterator *iter, bool real_ok, bool own_scope)
sgn = mpfr_sgn (iter->step->value.real);
cmp = mpfr_cmp (iter->end->value.real, iter->start->value.real);
}
- if ((sgn > 0 && cmp < 0) || (sgn < 0 && cmp > 0))
- gfc_warning ("DO loop at %L will be executed zero times",
+ if (gfc_option.warn_zerotrip &&
+ ((sgn > 0 && cmp < 0) || (sgn < 0 && cmp > 0)))
+ gfc_warning ("DO loop at %L will be executed zero times"
+ " (use -Wno-zerotrip to suppress)",
&iter->step->where);
}
@@ -6877,9 +6881,8 @@ resolve_allocate_expr (gfc_expr *e, gfc_code *code)
if (ts.type == BT_DERIVED && (init_e = gfc_default_initializer (&ts)))
{
- gfc_code *init_st = gfc_get_code ();
+ gfc_code *init_st = gfc_get_code (EXEC_INIT_ASSIGN);
init_st->loc = code->loc;
- init_st->op = EXEC_INIT_ASSIGN;
init_st->expr1 = gfc_expr_to_initialize (e);
init_st->expr2 = init_e;
init_st->next = code->next;
@@ -8017,8 +8020,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
code->ext.block.assoc = NULL;
/* Add EXEC_SELECT to switch on type. */
- new_st = gfc_get_code ();
- new_st->op = code->op;
+ new_st = gfc_get_code (code->op);
new_st->expr1 = code->expr1;
new_st->expr2 = code->expr2;
new_st->block = code->block;
@@ -8084,8 +8086,7 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
if (c->ts.type != BT_CLASS && c->ts.type != BT_UNKNOWN)
gfc_add_data_component (st->n.sym->assoc->target);
- new_st = gfc_get_code ();
- new_st->op = EXEC_BLOCK;
+ new_st = gfc_get_code (EXEC_BLOCK);
new_st->ext.block.ns = gfc_build_block_ns (ns);
new_st->ext.block.ns->code = body->next;
body->next = new_st;
@@ -8136,9 +8137,8 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
{
/* Add a default case to hold the CLASS IS cases. */
for (tail = code; tail->block; tail = tail->block) ;
- tail->block = gfc_get_code ();
+ tail->block = gfc_get_code (EXEC_SELECT_TYPE);
tail = tail->block;
- tail->op = EXEC_SELECT_TYPE;
tail->ext.block.case_list = gfc_get_case ();
tail->ext.block.case_list->ts.type = BT_UNKNOWN;
tail->next = NULL;
@@ -8181,14 +8181,12 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
}
/* Generate IF chain. */
- if_st = gfc_get_code ();
- if_st->op = EXEC_IF;
+ if_st = gfc_get_code (EXEC_IF);
new_st = if_st;
for (body = class_is; body; body = body->block)
{
- new_st->block = gfc_get_code ();
+ new_st->block = gfc_get_code (EXEC_IF);
new_st = new_st->block;
- new_st->op = EXEC_IF;
/* Set up IF condition: Call _gfortran_is_extension_of. */
new_st->expr1 = gfc_get_expr ();
new_st->expr1->expr_type = EXPR_FUNCTION;
@@ -8210,9 +8208,8 @@ resolve_select_type (gfc_code *code, gfc_namespace *old_ns)
}
if (default_case->next)
{
- new_st->block = gfc_get_code ();
+ new_st->block = gfc_get_code (EXEC_IF);
new_st = new_st->block;
- new_st->op = EXEC_IF;
new_st->next = default_case->next;
}
@@ -9238,8 +9235,7 @@ build_assignment (gfc_exec_op op, gfc_expr *expr1, gfc_expr *expr2,
{
gfc_code *this_code;
- this_code = gfc_get_code ();
- this_code->op = op;
+ this_code = gfc_get_code (op);
this_code->next = NULL;
this_code->expr1 = gfc_copy_expr (expr1);
this_code->expr2 = gfc_copy_expr (expr2);
@@ -9633,7 +9629,7 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
{
frame.current = code;
forall_save = forall_flag;
- do_concurrent_save = do_concurrent_flag;
+ do_concurrent_save = gfc_do_concurrent_flag;
if (code->op == EXEC_FORALL)
{
@@ -9667,9 +9663,9 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
to transform the SELECT TYPE into ASSOCIATE first. */
break;
case EXEC_DO_CONCURRENT:
- do_concurrent_flag = 1;
+ gfc_do_concurrent_flag = 1;
gfc_resolve_blocks (code->block, ns);
- do_concurrent_flag = 2;
+ gfc_do_concurrent_flag = 2;
break;
case EXEC_OMP_WORKSHARE:
omp_workshare_save = omp_workshare_flag;
@@ -9688,7 +9684,7 @@ resolve_code (gfc_code *code, gfc_namespace *ns)
if (code->op != EXEC_COMPCALL && code->op != EXEC_CALL_PPC)
t = gfc_resolve_expr (code->expr1);
forall_flag = forall_save;
- do_concurrent_flag = do_concurrent_save;
+ gfc_do_concurrent_flag = do_concurrent_save;
if (!gfc_resolve_expr (code->expr2))
t = false;
@@ -10278,13 +10274,12 @@ build_init_assign (gfc_symbol *sym, gfc_expr *init)
lval = gfc_lval_expr_from_sym (sym);
/* Add the code at scope entry. */
- init_st = gfc_get_code ();
+ init_st = gfc_get_code (EXEC_INIT_ASSIGN);
init_st->next = ns->code;
ns->code = init_st;
/* Assign the default initializer to the l-value. */
init_st->loc = sym->declared_at;
- init_st->op = EXEC_INIT_ASSIGN;
init_st->expr1 = lval;
init_st->expr2 = init;
}
@@ -14409,7 +14404,7 @@ resolve_types (gfc_namespace *ns)
}
forall_flag = 0;
- do_concurrent_flag = 0;
+ gfc_do_concurrent_flag = 0;
gfc_check_interfaces (ns);
gfc_traverse_ns (ns, resolve_values);
diff --git a/gcc/fortran/st.c b/gcc/fortran/st.c
index 836dac790a2..f8b341c0b6c 100644
--- a/gcc/fortran/st.c
+++ b/gcc/fortran/st.c
@@ -41,14 +41,16 @@ gfc_clear_new_st (void)
}
-/* Get a gfc_code structure. */
+/* Get a gfc_code structure, initialized with the current locus
+ and a statement code 'op'. */
gfc_code *
-gfc_get_code (void)
+gfc_get_code (gfc_exec_op op)
{
gfc_code *c;
c = XCNEW (gfc_code);
+ c->op = op;
c->loc = gfc_current_locus;
return c;
}
diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c
index c72974dc003..9d23e8b48a3 100644
--- a/gcc/fortran/symbol.c
+++ b/gcc/fortran/symbol.c
@@ -4489,6 +4489,9 @@ gfc_type_compatible (gfc_typespec *ts1, gfc_typespec *ts2)
if (is_derived1 && is_derived2)
return gfc_compare_derived_types (ts1->u.derived, ts2->u.derived);
+ if (is_derived1 && is_class2)
+ return gfc_compare_derived_types (ts1->u.derived,
+ ts2->u.derived->components->ts.u.derived);
if (is_class1 && is_derived2)
return gfc_type_is_extension_of (ts1->u.derived->components->ts.u.derived,
ts2->u.derived);
diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c
index c269ea8bbf1..5a3cf80f9f6 100644
--- a/gcc/fortran/trans-array.c
+++ b/gcc/fortran/trans-array.c
@@ -3715,7 +3715,7 @@ evaluate_bound (stmtblock_t *block, tree *bounds, gfc_expr ** values,
/* Calculate the lower bound of an array section. */
static void
-gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim)
+gfc_conv_section_startstride (stmtblock_t * block, gfc_ss * ss, int dim)
{
gfc_expr *stride = NULL;
tree desc;
@@ -3744,12 +3744,12 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim)
/* Calculate the start of the range. For vector subscripts this will
be the range of the vector. */
- evaluate_bound (&loop->pre, info->start, ar->start, desc, dim, true);
+ evaluate_bound (block, info->start, ar->start, desc, dim, true);
/* Similarly calculate the end. Although this is not used in the
scalarizer, it is needed when checking bounds and where the end
is an expression with side-effects. */
- evaluate_bound (&loop->pre, info->end, ar->end, desc, dim, false);
+ evaluate_bound (block, info->end, ar->end, desc, dim, false);
/* Calculate the stride. */
if (stride == NULL)
@@ -3758,8 +3758,8 @@ gfc_conv_section_startstride (gfc_loopinfo * loop, gfc_ss * ss, int dim)
{
gfc_init_se (&se, NULL);
gfc_conv_expr_type (&se, stride, gfc_array_index_type);
- gfc_add_block_to_block (&loop->pre, &se.pre);
- info->stride[dim] = gfc_evaluate_now (se.expr, &loop->pre);
+ gfc_add_block_to_block (block, &se.pre);
+ info->stride[dim] = gfc_evaluate_now (se.expr, block);
}
}
@@ -3776,6 +3776,8 @@ gfc_conv_ss_startstride (gfc_loopinfo * loop)
gfc_ss *ss;
tree desc;
+ gfc_loopinfo * const outer_loop = outermost_loop (loop);
+
loop->dimen = 0;
/* Determine the rank of the loop. */
for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
@@ -3835,10 +3837,11 @@ done:
/* Get the descriptor for the array. If it is a cross loops array,
we got the descriptor already in the outermost loop. */
if (ss->parent == NULL)
- gfc_conv_ss_descriptor (&loop->pre, ss, !loop->array_parameter);
+ gfc_conv_ss_descriptor (&outer_loop->pre, ss,
+ !loop->array_parameter);
for (n = 0; n < ss->dimen; n++)
- gfc_conv_section_startstride (loop, ss, ss->dim[n]);
+ gfc_conv_section_startstride (&outer_loop->pre, ss, ss->dim[n]);
break;
case GFC_SS_INTRINSIC:
@@ -3874,7 +3877,7 @@ done:
fold_convert (gfc_array_index_type,
rank),
gfc_index_one_node);
- info->end[0] = gfc_evaluate_now (tmp, &loop->pre);
+ info->end[0] = gfc_evaluate_now (tmp, &outer_loop->pre);
info->start[0] = gfc_index_zero_node;
info->stride[0] = gfc_index_one_node;
continue;
@@ -4156,7 +4159,7 @@ done:
}
tmp = gfc_finish_block (&block);
- gfc_add_expr_to_block (&loop->pre, tmp);
+ gfc_add_expr_to_block (&outer_loop->pre, tmp);
}
for (loop = loop->nested; loop; loop = loop->next)
@@ -4439,6 +4442,8 @@ set_loop_bounds (gfc_loopinfo *loop)
mpz_t i;
bool nonoptional_arr;
+ gfc_loopinfo * const outer_loop = outermost_loop (loop);
+
loopspec = loop->specloop;
mpz_init (i);
@@ -4456,7 +4461,10 @@ set_loop_bounds (gfc_loopinfo *loop)
for (ss = loop->ss; ss != gfc_ss_terminator; ss = ss->loop_chain)
if (ss->info->type != GFC_SS_SCALAR && ss->info->type != GFC_SS_TEMP
&& ss->info->type != GFC_SS_REFERENCE && !ss->info->can_be_null_ref)
- nonoptional_arr = true;
+ {
+ nonoptional_arr = true;
+ break;
+ }
/* We use one SS term, and use that to determine the bounds of the
loop for this dimension. We try to pick the simplest term. */
@@ -4624,7 +4632,7 @@ set_loop_bounds (gfc_loopinfo *loop)
else
{
/* Set the delta for this section. */
- info->delta[dim] = gfc_evaluate_now (loop->from[n], &loop->pre);
+ info->delta[dim] = gfc_evaluate_now (loop->from[n], &outer_loop->pre);
/* Number of iterations is (end - start + step) / step.
with start = 0, this simplifies to
last = end / step;
@@ -4636,7 +4644,7 @@ set_loop_bounds (gfc_loopinfo *loop)
gfc_array_index_type, tmp, info->stride[dim]);
tmp = fold_build2_loc (input_location, MAX_EXPR, gfc_array_index_type,
tmp, build_int_cst (gfc_array_index_type, -1));
- loop->to[n] = gfc_evaluate_now (tmp, &loop->pre);
+ loop->to[n] = gfc_evaluate_now (tmp, &outer_loop->pre);
/* Make the loop variable start at 0. */
loop->from[n] = gfc_index_zero_node;
}
@@ -4712,6 +4720,8 @@ gfc_set_delta (gfc_loopinfo *loop)
tree tmp;
int n, dim;
+ gfc_loopinfo * const outer_loop = outermost_loop (loop);
+
loopspec = loop->specloop;
/* Calculate the translation from loop variables to array indices. */
@@ -4747,7 +4757,7 @@ gfc_set_delta (gfc_loopinfo *loop)
gfc_array_index_type,
info->start[dim], tmp);
- info->delta[dim] = gfc_evaluate_now (tmp, &loop->pre);
+ info->delta[dim] = gfc_evaluate_now (tmp, &outer_loop->pre);
}
}
}
@@ -6724,10 +6734,10 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr)
gcc_assert (ar->dimen_type[n + ndim] == DIMEN_THIS_IMAGE);
/* Make sure the call to gfc_conv_section_startstride won't
- generate unnecessary code to calculate stride. */
+ generate unnecessary code to calculate stride. */
gcc_assert (ar->stride[n + ndim] == NULL);
- gfc_conv_section_startstride (&loop, ss, n + ndim);
+ gfc_conv_section_startstride (&loop.pre, ss, n + ndim);
loop.from[n + loop.dimen] = info->start[n + ndim];
loop.to[n + loop.dimen] = info->end[n + ndim];
}
diff --git a/gcc/fortran/trans-decl.c b/gcc/fortran/trans-decl.c
index 2916b4cc52e..c2c736e1c66 100644
--- a/gcc/fortran/trans-decl.c
+++ b/gcc/fortran/trans-decl.c
@@ -1491,14 +1491,14 @@ gfc_get_symbol_decl (gfc_symbol * sym)
SAVE is specified otherwise they need to be reinitialized
every time the procedure is entered. The TREE_STATIC is
in this case due to -fmax-stack-var-size=. */
+
DECL_INITIAL (decl) = gfc_conv_initializer (sym->value, &sym->ts,
- TREE_TYPE (decl),
- sym->attr.dimension
- || (sym->attr.codimension
- && sym->attr.allocatable),
- sym->attr.pointer
- || sym->attr.allocatable,
- sym->attr.proc_pointer);
+ TREE_TYPE (decl), sym->attr.dimension
+ || (sym->attr.codimension
+ && sym->attr.allocatable),
+ sym->attr.pointer || sym->attr.allocatable
+ || sym->ts.type == BT_CLASS,
+ sym->attr.proc_pointer);
}
if (!TREE_STATIC (decl)
@@ -4745,7 +4745,8 @@ generate_local_decl (gfc_symbol * sym)
gfc_warning ("Dummy argument '%s' at %L was declared "
"INTENT(OUT) but was not set", sym->name,
&sym->declared_at);
- else if (!gfc_has_default_initializer (sym->ts.u.derived))
+ else if (!gfc_has_default_initializer (sym->ts.u.derived)
+ && !sym->ts.u.derived->attr.zero_comp)
gfc_warning ("Derived-type dummy argument '%s' at %L was "
"declared INTENT(OUT) but was not set and "
"does not have a default initializer",
@@ -5643,14 +5644,16 @@ gfc_generate_function_code (gfc_namespace * ns)
}
current_function_decl = old_context;
- if (decl_function_context (fndecl) && gfc_option.coarray != GFC_FCOARRAY_LIB
- && has_coarray_vars)
- /* Register this function with cgraph just far enough to get it
- added to our parent's nested function list.
- If there are static coarrays in this function, the nested _caf_init
- function has already called cgraph_create_node, which also created
- the cgraph node for this function. */
- (void) cgraph_create_node (fndecl);
+ if (decl_function_context (fndecl))
+ {
+ /* Register this function with cgraph just far enough to get it
+ added to our parent's nested function list.
+ If there are static coarrays in this function, the nested _caf_init
+ function has already called cgraph_create_node, which also created
+ the cgraph node for this function. */
+ if (!has_coarray_vars || gfc_option.coarray != GFC_FCOARRAY_LIB)
+ (void) cgraph_create_node (fndecl);
+ }
else
cgraph_finalize_function (fndecl, true);
diff --git a/gcc/fortran/trans-expr.c b/gcc/fortran/trans-expr.c
index e0cdd49dfa2..0ecfdfce469 100644
--- a/gcc/fortran/trans-expr.c
+++ b/gcc/fortran/trans-expr.c
@@ -895,14 +895,13 @@ gfc_trans_class_array_init_assign (gfc_expr *rhs, gfc_expr *lhs, gfc_expr *obj)
ppc = gfc_copy_expr (obj);
gfc_add_vptr_component (ppc);
gfc_add_component_ref (ppc, "_copy");
- ppc_code = gfc_get_code ();
+ ppc_code = gfc_get_code (EXEC_CALL);
ppc_code->resolved_sym = ppc->symtree->n.sym;
/* Although '_copy' is set to be elemental in class.c, it is
not staying that way. Find out why, sometime.... */
ppc_code->resolved_sym->attr.elemental = 1;
ppc_code->ext.actual = actual;
ppc_code->expr1 = ppc;
- ppc_code->op = EXEC_CALL;
/* Since '_copy' is elemental, the scalarizer will take care
of arrays in gfc_trans_call. */
res = gfc_trans_call (ppc_code, false, NULL, NULL, false);
@@ -1043,7 +1042,7 @@ assign_vptr:
gfc_add_data_component (expr2);
goto assign;
}
- else if (CLASS_DATA (expr2)->attr.dimension)
+ else if (CLASS_DATA (expr2)->attr.dimension && expr2->expr_type != EXPR_FUNCTION)
{
/* Insert an additional assignment which sets the '_vptr' field. */
lhs = gfc_copy_expr (expr1);
@@ -1061,9 +1060,10 @@ assign_vptr:
/* Do the actual CLASS assignment. */
if (expr2->ts.type == BT_CLASS
- && !CLASS_DATA (expr2)->attr.dimension)
+ && !CLASS_DATA (expr2)->attr.dimension)
op = EXEC_ASSIGN;
- else
+ else if (expr2->expr_type != EXPR_FUNCTION || expr2->ts.type != BT_CLASS
+ || !CLASS_DATA (expr2)->attr.dimension)
gfc_add_data_component (expr1);
assign:
@@ -5663,7 +5663,15 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
}
else if (pointer || procptr)
{
- if (!expr || expr->expr_type == EXPR_NULL)
+ if (ts->type == BT_CLASS && !procptr)
+ {
+ gfc_init_se (&se, NULL);
+ gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
+ gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
+ TREE_STATIC (se.expr) = 1;
+ return se.expr;
+ }
+ else if (!expr || expr->expr_type == EXPR_NULL)
return fold_convert (type, null_pointer_node);
else
{
@@ -5682,7 +5690,7 @@ gfc_conv_initializer (gfc_expr * expr, gfc_typespec * ts, tree type,
case BT_CLASS:
gfc_init_se (&se, NULL);
if (ts->type == BT_CLASS && expr->expr_type == EXPR_NULL)
- gfc_conv_structure (&se, gfc_class_null_initializer(ts, expr), 1);
+ gfc_conv_structure (&se, gfc_class_initializer (ts, expr), 1);
else
gfc_conv_structure (&se, expr, 1);
gcc_assert (TREE_CODE (se.expr) == CONSTRUCTOR);
@@ -5992,7 +6000,7 @@ gfc_trans_subcomponent_assign (tree dest, gfc_component * cm, gfc_expr * expr)
{
/* NULL initialization for CLASS components. */
tmp = gfc_trans_structure_assign (dest,
- gfc_class_null_initializer (&cm->ts, expr));
+ gfc_class_initializer (&cm->ts, expr));
gfc_add_expr_to_block (&block, tmp);
}
else if (cm->attr.dimension && !cm->attr.proc_pointer)
@@ -6417,6 +6425,7 @@ gfc_trans_pointer_assign (gfc_code * code)
tree
gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
{
+ gfc_expr *expr1_vptr = NULL;
gfc_se lse;
gfc_se rse;
stmtblock_t block;
@@ -6437,6 +6446,15 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
if (!scalar)
gfc_free_ss_chain (ss);
+ if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS
+ && expr2->expr_type != EXPR_FUNCTION)
+ {
+ gfc_add_data_component (expr2);
+ /* The following is required as gfc_add_data_component doesn't
+ update ts.type if there is a tailing REF_ARRAY. */
+ expr2->ts.type = BT_DERIVED;
+ }
+
if (scalar)
{
/* Scalar pointers. */
@@ -6485,8 +6503,11 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
build_int_cst (gfc_charlen_type_node, 0));
}
+ if (expr1->ts.type == BT_DERIVED && expr2->ts.type == BT_CLASS)
+ rse.expr = gfc_class_data_get (rse.expr);
+
gfc_add_modify (&block, lse.expr,
- fold_convert (TREE_TYPE (lse.expr), rse.expr));
+ fold_convert (TREE_TYPE (lse.expr), rse.expr));
gfc_add_block_to_block (&block, &rse.post);
gfc_add_block_to_block (&block, &lse.post);
@@ -6508,8 +6529,12 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
break;
rank_remap = (remap && remap->u.ar.end[0]);
+ gfc_init_se (&lse, NULL);
if (remap)
lse.descriptor_only = 1;
+ if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS
+ && expr1->ts.type == BT_CLASS)
+ expr1_vptr = gfc_copy_expr (expr1);
gfc_conv_expr_descriptor (&lse, expr1);
strlen_lhs = lse.string_length;
desc = lse.expr;
@@ -6526,8 +6551,51 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
gfc_init_se (&rse, NULL);
rse.direct_byref = 1;
rse.byref_noassign = 1;
- gfc_conv_expr_descriptor (&rse, expr2);
- strlen_rhs = rse.string_length;
+
+ if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
+ {
+ gfc_conv_function_expr (&rse, expr2);
+
+ if (expr1->ts.type != BT_CLASS)
+ rse.expr = gfc_class_data_get (rse.expr);
+ else
+ {
+ tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
+ gfc_add_modify (&lse.pre, tmp, rse.expr);
+
+ gfc_add_vptr_component (expr1_vptr);
+ gfc_init_se (&rse, NULL);
+ rse.want_pointer = 1;
+ gfc_conv_expr (&rse, expr1_vptr);
+ gfc_add_modify (&lse.pre, rse.expr,
+ fold_convert (TREE_TYPE (rse.expr),
+ gfc_class_vptr_get (tmp)));
+ rse.expr = gfc_class_data_get (tmp);
+ }
+ }
+ else if (expr2->expr_type == EXPR_FUNCTION)
+ {
+ tree bound[GFC_MAX_DIMENSIONS];
+ int i;
+
+ for (i = 0; i < expr2->rank; i++)
+ bound[i] = NULL_TREE;
+ tmp = gfc_typenode_for_spec (&expr2->ts);
+ tmp = gfc_get_array_type_bounds (tmp, expr2->rank, 0,
+ bound, bound, 0,
+ GFC_ARRAY_POINTER_CONT, false);
+ tmp = gfc_create_var (tmp, "ptrtemp");
+ lse.expr = tmp;
+ lse.direct_byref = 1;
+ gfc_conv_expr_descriptor (&lse, expr2);
+ strlen_rhs = lse.string_length;
+ rse.expr = tmp;
+ }
+ else
+ {
+ gfc_conv_expr_descriptor (&rse, expr2);
+ strlen_rhs = rse.string_length;
+ }
}
else if (expr2->expr_type == EXPR_VARIABLE)
{
@@ -6551,12 +6619,37 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
gfc_add_modify (&lse.post, GFC_DECL_SPAN(decl), tmp);
}
}
+ else if (expr2->expr_type == EXPR_FUNCTION && expr2->ts.type == BT_CLASS)
+ {
+ gfc_init_se (&rse, NULL);
+ rse.want_pointer = 1;
+ gfc_conv_function_expr (&rse, expr2);
+ if (expr1->ts.type != BT_CLASS)
+ {
+ rse.expr = gfc_class_data_get (rse.expr);
+ gfc_add_modify (&lse.pre, desc, rse.expr);
+ }
+ else
+ {
+ tmp = gfc_create_var (TREE_TYPE (rse.expr), "ptrtemp");
+ gfc_add_modify (&lse.pre, tmp, rse.expr);
+
+ gfc_add_vptr_component (expr1_vptr);
+ gfc_init_se (&rse, NULL);
+ rse.want_pointer = 1;
+ gfc_conv_expr (&rse, expr1_vptr);
+ gfc_add_modify (&lse.pre, rse.expr,
+ fold_convert (TREE_TYPE (rse.expr),
+ gfc_class_vptr_get (tmp)));
+ rse.expr = gfc_class_data_get (tmp);
+ gfc_add_modify (&lse.pre, desc, rse.expr);
+ }
+ }
else
{
/* Assign to a temporary descriptor and then copy that
temporary to the pointer. */
tmp = gfc_create_var (TREE_TYPE (desc), "ptrtemp");
-
lse.expr = tmp;
lse.direct_byref = 1;
gfc_conv_expr_descriptor (&lse, expr2);
@@ -6564,6 +6657,9 @@ gfc_trans_pointer_assignment (gfc_expr * expr1, gfc_expr * expr2)
gfc_add_modify (&lse.pre, desc, tmp);
}
+ if (expr1_vptr)
+ gfc_free_expr (expr1_vptr);
+
gfc_add_block_to_block (&block, &lse.pre);
if (rank_remap)
gfc_add_block_to_block (&block, &rse.pre);
@@ -7642,6 +7738,105 @@ alloc_scalar_allocatable_for_assignment (stmtblock_t *block,
}
}
+/* Check for assignments of the type
+
+ a = a + 4
+
+ to make sure we do not check for reallocation unneccessarily. */
+
+
+static bool
+is_runtime_conformable (gfc_expr *expr1, gfc_expr *expr2)
+{
+ gfc_actual_arglist *a;
+ gfc_expr *e1, *e2;
+
+ switch (expr2->expr_type)
+ {
+ case EXPR_VARIABLE:
+ return gfc_dep_compare_expr (expr1, expr2) == 0;
+
+ case EXPR_FUNCTION:
+ if (expr2->value.function.esym
+ && expr2->value.function.esym->attr.elemental)
+ {
+ for (a = expr2->value.function.actual; a != NULL; a = a->next)
+ {
+ e1 = a->expr;
+ if (e1->rank > 0 && !is_runtime_conformable (expr1, e1))
+ return false;
+ }
+ return true;
+ }
+ else if (expr2->value.function.isym
+ && expr2->value.function.isym->elemental)
+ {
+ for (a = expr2->value.function.actual; a != NULL; a = a->next)
+ {
+ e1 = a->expr;
+ if (e1->rank > 0 && !is_runtime_conformable (expr1, e1))
+ return false;
+ }
+ return true;
+ }
+
+ break;
+
+ case EXPR_OP:
+ switch (expr2->value.op.op)
+ {
+ case INTRINSIC_NOT:
+ case INTRINSIC_UPLUS:
+ case INTRINSIC_UMINUS:
+ case INTRINSIC_PARENTHESES:
+ return is_runtime_conformable (expr1, expr2->value.op.op1);
+
+ case INTRINSIC_PLUS:
+ case INTRINSIC_MINUS:
+ case INTRINSIC_TIMES:
+ case INTRINSIC_DIVIDE:
+ case INTRINSIC_POWER:
+ case INTRINSIC_AND:
+ case INTRINSIC_OR:
+ case INTRINSIC_EQV:
+ case INTRINSIC_NEQV:
+ case INTRINSIC_EQ:
+ case INTRINSIC_NE:
+ case INTRINSIC_GT:
+ case INTRINSIC_GE:
+ case INTRINSIC_LT:
+ case INTRINSIC_LE:
+ case INTRINSIC_EQ_OS:
+ case INTRINSIC_NE_OS:
+ case INTRINSIC_GT_OS:
+ case INTRINSIC_GE_OS:
+ case INTRINSIC_LT_OS:
+ case INTRINSIC_LE_OS:
+
+ e1 = expr2->value.op.op1;
+ e2 = expr2->value.op.op2;
+
+ if (e1->rank == 0 && e2->rank > 0)
+ return is_runtime_conformable (expr1, e2);
+ else if (e1->rank > 0 && e2->rank == 0)
+ return is_runtime_conformable (expr1, e1);
+ else if (e1->rank > 0 && e2->rank > 0)
+ return is_runtime_conformable (expr1, e1)
+ && is_runtime_conformable (expr1, e2);
+ break;
+
+ default:
+ break;
+
+ }
+
+ break;
+
+ default:
+ break;
+ }
+ return false;
+}
/* Subroutine of gfc_trans_assignment that actually scalarizes the
assignment. EXPR1 is the destination/LHS and EXPR2 is the source/RHS.
@@ -7839,7 +8034,8 @@ gfc_trans_assignment_1 (gfc_expr * expr1, gfc_expr * expr2, bool init_flag,
&& gfc_is_reallocatable_lhs (expr1)
&& !gfc_expr_attr (expr1).codimension
&& !gfc_is_coindexed (expr1)
- && expr2->rank)
+ && expr2->rank
+ && !is_runtime_conformable (expr1, expr2))
{
realloc_lhs_warning (expr1->ts.type, true, &expr1->where);
ompws_flags &= ~OMPWS_SCALARIZER_WS;
diff --git a/gcc/fortran/trans-intrinsic.c b/gcc/fortran/trans-intrinsic.c
index 3fbf193d03c..6b85b5b78db 100644
--- a/gcc/fortran/trans-intrinsic.c
+++ b/gcc/fortran/trans-intrinsic.c
@@ -5652,8 +5652,7 @@ scalar_transfer:
if (expr->ts.type == BT_CHARACTER)
{
- tree direct;
- tree indirect;
+ tree direct, indirect, free;
ptr = convert (gfc_get_pchar_type (expr->ts.kind), source);
tmpdecl = gfc_create_var (gfc_get_pchar_type (expr->ts.kind),
@@ -5686,6 +5685,13 @@ scalar_transfer:
tmp = build3_v (COND_EXPR, tmp, direct, indirect);
gfc_add_expr_to_block (&se->pre, tmp);
+ /* Free the temporary string, if necessary. */
+ free = gfc_call_free (tmpdecl);
+ tmp = fold_build2_loc (input_location, GT_EXPR, boolean_type_node,
+ dest_word_len, source_bytes);
+ tmp = build3_v (COND_EXPR, tmp, free, build_empty_stmt (input_location));
+ gfc_add_expr_to_block (&se->post, tmp);
+
se->expr = tmpdecl;
se->string_length = fold_convert (gfc_charlen_type_node, dest_word_len);
}
diff --git a/gcc/fortran/trans-io.c b/gcc/fortran/trans-io.c
index d60d15faf28..ec17dc97c21 100644
--- a/gcc/fortran/trans-io.c
+++ b/gcc/fortran/trans-io.c
@@ -2260,7 +2260,10 @@ gfc_trans_transfer (gfc_code * code)
{
for (n = 0; n < ref->u.ar.dimen; n++)
if (ref->u.ar.dimen_type[n] == DIMEN_VECTOR)
- seen_vector = true;
+ {
+ seen_vector = true;
+ break;
+ }
}
if (seen_vector && last_dt == READ)
diff --git a/gcc/fortran/trans-stmt.c b/gcc/fortran/trans-stmt.c
index e2d0110ba96..edd2dacf579 100644
--- a/gcc/fortran/trans-stmt.c
+++ b/gcc/fortran/trans-stmt.c
@@ -5232,14 +5232,13 @@ gfc_trans_allocate (gfc_code * code)
(gfc_find_intrinsic_vtab (&rhs->ts));
gfc_add_component_ref (ppc, "_copy");
- ppc_code = gfc_get_code ();
+ ppc_code = gfc_get_code (EXEC_CALL);
ppc_code->resolved_sym = ppc->symtree->n.sym;
/* Although '_copy' is set to be elemental in class.c, it is
not staying that way. Find out why, sometime.... */
ppc_code->resolved_sym->attr.elemental = 1;
ppc_code->ext.actual = actual;
ppc_code->expr1 = ppc;
- ppc_code->op = EXEC_CALL;
/* Since '_copy' is elemental, the scalarizer will take care
of arrays in gfc_trans_call. */
tmp = gfc_trans_call (ppc_code, true, NULL, NULL, false);
diff --git a/gcc/function.c b/gcc/function.c
index 3e33fc70632..08731e84502 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -1948,26 +1948,43 @@ instantiate_virtual_regs (void)
return 0;
}
-struct rtl_opt_pass pass_instantiate_virtual_regs =
-{
- {
- RTL_PASS,
- "vregs", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- instantiate_virtual_regs, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_instantiate_virtual_regs =
+{
+ RTL_PASS, /* type */
+ "vregs", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_instantiate_virtual_regs : public rtl_opt_pass
+{
+public:
+ pass_instantiate_virtual_regs(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_instantiate_virtual_regs, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return instantiate_virtual_regs (); }
+
+}; // class pass_instantiate_virtual_regs
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_instantiate_virtual_regs (gcc::context *ctxt)
+{
+ return new pass_instantiate_virtual_regs (ctxt);
+}
+
/* Return 1 if EXP is an aggregate type (or a value with aggregate type).
This means a type for which function calls must pass an address to the
@@ -2369,7 +2386,7 @@ assign_parm_find_data_types (struct assign_parm_data_all *all, tree parm,
{
passed_type = nominal_type = build_pointer_type (passed_type);
data->passed_pointer = true;
- passed_mode = nominal_mode = Pmode;
+ passed_mode = nominal_mode = TYPE_MODE (nominal_type);
}
/* Find mode as it is passed by the ABI. */
@@ -3084,17 +3101,27 @@ assign_parm_setup_reg (struct assign_parm_data_all *all, tree parm,
emit_move_insn (parmreg, validated_mem);
/* If we were passed a pointer but the actual value can safely live
- in a register, put it in one. */
- if (data->passed_pointer
- && TYPE_MODE (TREE_TYPE (parm)) != BLKmode
- /* If by-reference argument was promoted, demote it. */
- && (TYPE_MODE (TREE_TYPE (parm)) != GET_MODE (DECL_RTL (parm))
- || use_register_for_decl (parm)))
+ in a register, retrieve it and use it directly. */
+ if (data->passed_pointer && TYPE_MODE (TREE_TYPE (parm)) != BLKmode)
{
/* We can't use nominal_mode, because it will have been set to
Pmode above. We must use the actual mode of the parm. */
- parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
- mark_user_reg (parmreg);
+ if (use_register_for_decl (parm))
+ {
+ parmreg = gen_reg_rtx (TYPE_MODE (TREE_TYPE (parm)));
+ mark_user_reg (parmreg);
+ }
+ else
+ {
+ int align = STACK_SLOT_ALIGNMENT (TREE_TYPE (parm),
+ TYPE_MODE (TREE_TYPE (parm)),
+ TYPE_ALIGN (TREE_TYPE (parm)));
+ parmreg
+ = assign_stack_local (TYPE_MODE (TREE_TYPE (parm)),
+ GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (parm))),
+ align);
+ set_mem_attributes (parmreg, parm, 1);
+ }
if (GET_MODE (parmreg) != GET_MODE (DECL_RTL (parm)))
{
@@ -5506,22 +5533,45 @@ move_insn_for_shrink_wrap (basic_block bb, rtx insn,
except for any part that overlaps SRC (next loop). */
bb_uses = &DF_LR_BB_INFO (bb)->use;
bb_defs = &DF_LR_BB_INFO (bb)->def;
- for (i = dregno; i < end_dregno; i++)
+ if (df_live)
{
- if (REGNO_REG_SET_P (bb_uses, i) || REGNO_REG_SET_P (bb_defs, i))
- next_block = NULL;
- CLEAR_REGNO_REG_SET (live_out, i);
- CLEAR_REGNO_REG_SET (live_in, i);
- }
+ for (i = dregno; i < end_dregno; i++)
+ {
+ if (REGNO_REG_SET_P (bb_uses, i) || REGNO_REG_SET_P (bb_defs, i)
+ || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i))
+ next_block = NULL;
+ CLEAR_REGNO_REG_SET (live_out, i);
+ CLEAR_REGNO_REG_SET (live_in, i);
+ }
- /* Check whether BB clobbers SRC. We need to add INSN to BB if so.
- Either way, SRC is now live on entry. */
- for (i = sregno; i < end_sregno; i++)
+ /* Check whether BB clobbers SRC. We need to add INSN to BB if so.
+ Either way, SRC is now live on entry. */
+ for (i = sregno; i < end_sregno; i++)
+ {
+ if (REGNO_REG_SET_P (bb_defs, i)
+ || REGNO_REG_SET_P (&DF_LIVE_BB_INFO (bb)->gen, i))
+ next_block = NULL;
+ SET_REGNO_REG_SET (live_out, i);
+ SET_REGNO_REG_SET (live_in, i);
+ }
+ }
+ else
{
- if (REGNO_REG_SET_P (bb_defs, i))
- next_block = NULL;
- SET_REGNO_REG_SET (live_out, i);
- SET_REGNO_REG_SET (live_in, i);
+ /* DF_LR_BB_INFO (bb)->def does not comprise the DF_REF_PARTIAL and
+ DF_REF_CONDITIONAL defs. So if DF_LIVE doesn't exist, i.e.
+ at -O1, just give up searching NEXT_BLOCK. */
+ next_block = NULL;
+ for (i = dregno; i < end_dregno; i++)
+ {
+ CLEAR_REGNO_REG_SET (live_out, i);
+ CLEAR_REGNO_REG_SET (live_in, i);
+ }
+
+ for (i = sregno; i < end_sregno; i++)
+ {
+ SET_REGNO_REG_SET (live_out, i);
+ SET_REGNO_REG_SET (live_in, i);
+ }
}
/* If we don't need to add the move to BB, look for a single
@@ -6950,26 +7000,43 @@ types_used_by_var_decl_insert (tree type, tree var_decl)
}
}
-struct rtl_opt_pass pass_leaf_regs =
-{
- {
- RTL_PASS,
- "*leaf_regs", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_check_leaf_regs, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_leaf_regs =
+{
+ RTL_PASS, /* type */
+ "*leaf_regs", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_leaf_regs : public rtl_opt_pass
+{
+public:
+ pass_leaf_regs(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_leaf_regs, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_check_leaf_regs (); }
+
+}; // class pass_leaf_regs
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_leaf_regs (gcc::context *ctxt)
+{
+ return new pass_leaf_regs (ctxt);
+}
+
static unsigned int
rest_of_handle_thread_prologue_and_epilogue (void)
{
@@ -6989,26 +7056,45 @@ rest_of_handle_thread_prologue_and_epilogue (void)
return 0;
}
-struct rtl_opt_pass pass_thread_prologue_and_epilogue =
-{
- {
- RTL_PASS,
- "pro_and_epilogue", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_thread_prologue_and_epilogue, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_THREAD_PROLOGUE_AND_EPILOGUE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- TODO_verify_flow, /* todo_flags_start */
- TODO_df_verify | TODO_df_finish
- | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_thread_prologue_and_epilogue =
+{
+ RTL_PASS, /* type */
+ "pro_and_epilogue", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_THREAD_PROLOGUE_AND_EPILOGUE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ TODO_verify_flow, /* todo_flags_start */
+ ( TODO_df_verify | TODO_df_finish
+ | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_thread_prologue_and_epilogue : public rtl_opt_pass
+{
+public:
+ pass_thread_prologue_and_epilogue(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_thread_prologue_and_epilogue, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () {
+ return rest_of_handle_thread_prologue_and_epilogue ();
+ }
+
+}; // class pass_thread_prologue_and_epilogue
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_thread_prologue_and_epilogue (gcc::context *ctxt)
+{
+ return new pass_thread_prologue_and_epilogue (ctxt);
+}
/* This mini-pass fixes fall-out from SSA in asm statements that have
@@ -7190,25 +7276,42 @@ rest_of_match_asm_constraints (void)
return TODO_df_finish;
}
-struct rtl_opt_pass pass_match_asm_constraints =
-{
- {
- RTL_PASS,
- "asmcons", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_match_asm_constraints, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_match_asm_constraints =
+{
+ RTL_PASS, /* type */
+ "asmcons", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_match_asm_constraints : public rtl_opt_pass
+{
+public:
+ pass_match_asm_constraints(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_match_asm_constraints, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_match_asm_constraints (); }
+
+}; // class pass_match_asm_constraints
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_match_asm_constraints (gcc::context *ctxt)
+{
+ return new pass_match_asm_constraints (ctxt);
+}
+
#include "gt-function.h"
diff --git a/gcc/function.h b/gcc/function.h
index c651f5037f8..d1f4ffc1fd4 100644
--- a/gcc/function.h
+++ b/gcc/function.h
@@ -650,6 +650,14 @@ struct GTY(()) function {
adjusts one of its arguments and forwards to another
function. */
unsigned int is_thunk : 1;
+
+ /* Nonzero if the current function contains any loops with
+ loop->force_vect set. */
+ unsigned int has_force_vect_loops : 1;
+
+ /* Nonzero if the current function contains any loops with
+ nonzero value in loop->simduid. */
+ unsigned int has_simduid_loops : 1;
};
/* Add the decl D to the local_decls list of FUN. */
diff --git a/gcc/fwprop.c b/gcc/fwprop.c
index 17cc62aa2e4..8fe02ac2a43 100644
--- a/gcc/fwprop.c
+++ b/gcc/fwprop.c
@@ -1485,28 +1485,45 @@ fwprop (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_fwprop =
+namespace {
+
+const pass_data pass_data_rtl_fwprop =
{
- {
- RTL_PASS,
- "fwprop1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_fwprop, /* gate */
- fwprop, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_FWPROP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish
- | TODO_verify_flow
- | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "fwprop1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_FWPROP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_flow
+ | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+class pass_rtl_fwprop : public rtl_opt_pass
+{
+public:
+ pass_rtl_fwprop(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_fwprop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_fwprop (); }
+ unsigned int execute () { return fwprop (); }
+
+}; // class pass_rtl_fwprop
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_fwprop (gcc::context *ctxt)
+{
+ return new pass_rtl_fwprop (ctxt);
+}
+
static unsigned int
fwprop_addr (void)
{
@@ -1535,22 +1552,40 @@ fwprop_addr (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_fwprop_addr =
+namespace {
+
+const pass_data pass_data_rtl_fwprop_addr =
{
- {
- RTL_PASS,
- "fwprop2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_fwprop, /* gate */
- fwprop_addr, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_FWPROP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "fwprop2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_FWPROP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_rtl_fwprop_addr : public rtl_opt_pass
+{
+public:
+ pass_rtl_fwprop_addr(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_fwprop_addr, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_fwprop (); }
+ unsigned int execute () { return fwprop_addr (); }
+
+}; // class pass_rtl_fwprop_addr
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_fwprop_addr (gcc::context *ctxt)
+{
+ return new pass_rtl_fwprop_addr (ctxt);
+}
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 6ef4e8a1b77..d48c4db118b 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -215,7 +215,7 @@ static inline void process_marked_switches (void);
static const char *process_brace_body (const char *, const char *, const char *, int, int);
static const struct spec_function *lookup_spec_function (const char *);
static const char *eval_spec_function (const char *, const char *);
-static const char *handle_spec_function (const char *);
+static const char *handle_spec_function (const char *, bool *);
static char *save_string (const char *, int);
static void set_collect_gcc_options (void);
static int do_spec_1 (const char *, int, const char *);
@@ -253,6 +253,7 @@ static const char *convert_filename (const char *, int, int);
static const char *getenv_spec_function (int, const char **);
static const char *if_exists_spec_function (int, const char **);
static const char *if_exists_else_spec_function (int, const char **);
+static const char *sanitize_spec_function (int, const char **);
static const char *replace_outfile_spec_function (int, const char **);
static const char *remove_outfile_spec_function (int, const char **);
static const char *version_compare_spec_function (int, const char **);
@@ -432,6 +433,10 @@ or with constant text in a single argument.
than the OR.
If %* appears in X, all of the alternatives must be starred, and
only the first matching alternative is substituted.
+ %{%:function(args):X}
+ Call function named FUNCTION with args ARGS. If the function
+ returns non-NULL, then X is substituted, if it returns
+ NULL, it isn't substituted.
%{S:X; if S was given to GCC, substitutes X;
T:Y; else if T was given to GCC, substitutes Y;
:D} else substitutes D. There can be as many clauses as you need.
@@ -586,6 +591,28 @@ proper position among the other output files. */
#define LIBTSAN_EARLY_SPEC ""
#endif
+#ifndef LIBUBSAN_SPEC
+#ifdef STATIC_LIBUBSAN_LIBS
+#define ADD_STATIC_LIBUBSAN_LIBS \
+ " %{static-libubsan:" STATIC_LIBUBSAN_LIBS "}"
+#else
+#define ADD_STATIC_LIBUBSAN_LIBS
+#endif
+#ifdef LIBUBSAN_EARLY_SPEC
+#define LIBUBSAN_SPEC ADD_STATIC_LIBUBSAN_LIBS
+#elif defined(HAVE_LD_STATIC_DYNAMIC)
+#define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \
+ "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \
+ ADD_STATIC_LIBUBSAN_LIBS
+#else
+#define LIBUBSAN_SPEC "-lubsan" ADD_STATIC_LIBUBSAN_LIBS
+#endif
+#endif
+
+#ifndef LIBUBSAN_EARLY_SPEC
+#define LIBUBSAN_EARLY_SPEC ""
+#endif
+
/* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
included. */
#ifndef LIBGCC_SPEC
@@ -708,18 +735,30 @@ proper position among the other output files. */
/* Linker command line options for -fsanitize= early on the command line. */
#ifndef SANITIZER_EARLY_SPEC
#define SANITIZER_EARLY_SPEC "\
-%{!nostdlib:%{!nodefaultlibs:%{fsanitize=address:" LIBASAN_EARLY_SPEC "} \
- %{fsanitize=thread:" LIBTSAN_EARLY_SPEC "}}}"
+%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_EARLY_SPEC "} \
+ %{%:sanitize(thread):" LIBTSAN_EARLY_SPEC "} \
+ %{%:sanitize(undefined):" LIBUBSAN_EARLY_SPEC "}}}"
#endif
/* Linker command line options for -fsanitize= late on the command line. */
#ifndef SANITIZER_SPEC
#define SANITIZER_SPEC "\
-%{!nostdlib:%{!nodefaultlibs:%{fsanitize=address:" LIBASAN_SPEC "\
+%{!nostdlib:%{!nodefaultlibs:%{%:sanitize(address):" LIBASAN_SPEC "\
%{static:%ecannot specify -static with -fsanitize=address}\
- %{fsanitize=thread:%e-fsanitize=address is incompatible with -fsanitize=thread}}\
- %{fsanitize=thread:" LIBTSAN_SPEC "\
- %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}}}"
+ %{%:sanitize(thread):%e-fsanitize=address is incompatible with -fsanitize=thread}}\
+ %{%:sanitize(thread):" LIBTSAN_SPEC "\
+ %{!pie:%{!shared:%e-fsanitize=thread linking must be done with -pie or -shared}}}\
+ %{%:sanitize(undefined):" LIBUBSAN_SPEC "}}}"
+#endif
+
+/* This is the spec to use, once the code for creating the vtable
+ verification runtime library, libvtv.so, has been created. Currently
+ the vtable verification runtime functions are in libstdc++, so we use
+ the spec just below this one. */
+#ifndef VTABLE_VERIFICATION_SPEC
+#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}}"
#endif
/* -u* was put back because both BSD and SysV seem to support it. */
@@ -740,7 +779,7 @@ proper position among the other output files. */
%{flto} %{flto=*} %l " LINK_PIE_SPEC \
"%{fuse-ld=*:-fuse-ld=%*}\
%X %{o*} %{e*} %{N} %{n} %{r}\
- %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
+ %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}} " VTABLE_VERIFICATION_SPEC " \
%{static:} %{L*} %(mfwrap) %(link_libgcc) " SANITIZER_EARLY_SPEC " %o\
%{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
%{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
@@ -1323,6 +1362,7 @@ static const struct spec_function static_spec_functions[] =
{ "getenv", getenv_spec_function },
{ "if-exists", if_exists_spec_function },
{ "if-exists-else", if_exists_else_spec_function },
+ { "sanitize", sanitize_spec_function },
{ "replace-outfile", replace_outfile_spec_function },
{ "remove-outfile", remove_outfile_spec_function },
{ "version-compare", version_compare_spec_function },
@@ -5273,7 +5313,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
break;
case ':':
- p = handle_spec_function (p);
+ p = handle_spec_function (p, NULL);
if (p == 0)
return -1;
break;
@@ -5509,10 +5549,13 @@ eval_spec_function (const char *func, const char *args)
ARGS is processed as a spec in a separate context and split into an
argument vector in the normal fashion. The function returns a string
containing a spec which we then process in the caller's context, or
- NULL if no processing is required. */
+ NULL if no processing is required.
+
+ If RETVAL_NONNULL is not NULL, then store a bool whether function
+ returned non-NULL. */
static const char *
-handle_spec_function (const char *p)
+handle_spec_function (const char *p, bool *retval_nonnull)
{
char *func, *args;
const char *endp, *funcval;
@@ -5558,6 +5601,8 @@ handle_spec_function (const char *p)
funcval = eval_spec_function (func, args);
if (funcval != NULL && do_spec_1 (funcval, 0, NULL) < 0)
p = NULL;
+ if (retval_nonnull)
+ *retval_nonnull = funcval != NULL;
free (func);
free (args);
@@ -5701,19 +5746,28 @@ handle_braces (const char *p)
p++, a_is_negated = true;
SKIP_WHITE();
- if (*p == '.')
- p++, a_is_suffix = true;
- else if (*p == ',')
- p++, a_is_spectype = true;
-
- atom = p;
- while (ISIDNUM(*p) || *p == '-' || *p == '+' || *p == '='
- || *p == ',' || *p == '.' || *p == '@')
- p++;
- end_atom = p;
+ if (*p == '%' && p[1] == ':')
+ {
+ atom = NULL;
+ end_atom = NULL;
+ p = handle_spec_function (p + 2, &a_matched);
+ }
+ else
+ {
+ if (*p == '.')
+ p++, a_is_suffix = true;
+ else if (*p == ',')
+ p++, a_is_spectype = true;
+
+ atom = p;
+ while (ISIDNUM(*p) || *p == '-' || *p == '+' || *p == '='
+ || *p == ',' || *p == '.' || *p == '@')
+ p++;
+ end_atom = p;
- if (*p == '*')
- p++, a_is_starred = 1;
+ if (*p == '*')
+ p++, a_is_starred = 1;
+ }
SKIP_WHITE();
switch (*p)
@@ -5738,7 +5792,7 @@ handle_braces (const char *p)
if (ordered_set)
goto invalid;
- if (atom == end_atom)
+ if (atom && atom == end_atom)
{
if (!n_way_choice || disj_matched || *p == '|'
|| a_is_negated || a_is_suffix || a_is_spectype
@@ -5763,7 +5817,9 @@ handle_braces (const char *p)
match. */
if (!disj_matched && !n_way_matched)
{
- if (a_is_suffix)
+ if (atom == NULL)
+ /* a_matched is already set by handle_spec_function. */;
+ else if (a_is_suffix)
a_matched = input_suffix_matches (atom, end_atom);
else if (a_is_spectype)
a_matched = input_spec_matches (atom, end_atom);
@@ -8060,6 +8116,27 @@ if_exists_else_spec_function (int argc, const char **argv)
return argv[1];
}
+/* sanitize built-in spec function.
+
+ This returns non-NULL, if sanitizing address, thread or
+ any of the undefined behavior sanitizers. */
+
+static const char *
+sanitize_spec_function (int argc, const char **argv)
+{
+ if (argc != 1)
+ return NULL;
+
+ if (strcmp (argv[0], "address") == 0)
+ return (flag_sanitize & SANITIZE_ADDRESS) ? "" : NULL;
+ if (strcmp (argv[0], "thread") == 0)
+ return (flag_sanitize & SANITIZE_THREAD) ? "" : NULL;
+ if (strcmp (argv[0], "undefined") == 0)
+ return (flag_sanitize & SANITIZE_UNDEFINED) ? "" : NULL;
+
+ return NULL;
+}
+
/* replace-outfile built-in spec function.
This looks for the first argument in the outfiles array's name and
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 08fe7b9240a..db1a6bf4c30 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -515,7 +515,7 @@ extern void __gcov_merge_ior (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;
extern void __gcov_interval_profiler (gcov_type *, gcov_type, int, unsigned);
extern void __gcov_pow2_profiler (gcov_type *, gcov_type);
extern void __gcov_one_value_profiler (gcov_type *, gcov_type);
-extern void __gcov_indirect_call_profiler (gcov_type *, gcov_type, void *, void *);
+extern void __gcov_indirect_call_profiler_v2 (gcov_type, void *);
extern void __gcov_average_profiler (gcov_type *, gcov_type);
extern void __gcov_ior_profiler (gcov_type *, gcov_type);
diff --git a/gcc/gcse.c b/gcc/gcse.c
index ec80e8bde47..422d6f060eb 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -4148,46 +4148,82 @@ execute_rtl_hoist (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_pre =
+namespace {
+
+const pass_data pass_data_rtl_pre =
{
- {
- RTL_PASS,
- "rtl pre", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_rtl_pre, /* gate */
- execute_rtl_pre, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_PRE, /* tv_id */
- PROP_cfglayout, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "rtl pre", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_PRE, /* tv_id */
+ PROP_cfglayout, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
-struct rtl_opt_pass pass_rtl_hoist =
+class pass_rtl_pre : public rtl_opt_pass
+{
+public:
+ pass_rtl_pre(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_pre, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_rtl_pre (); }
+ unsigned int execute () { return execute_rtl_pre (); }
+
+}; // class pass_rtl_pre
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_pre (gcc::context *ctxt)
+{
+ return new pass_rtl_pre (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_rtl_hoist =
{
- {
- RTL_PASS,
- "hoist", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_rtl_hoist, /* gate */
- execute_rtl_hoist, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_HOIST, /* tv_id */
- PROP_cfglayout, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "hoist", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_HOIST, /* tv_id */
+ PROP_cfglayout, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+class pass_rtl_hoist : public rtl_opt_pass
+{
+public:
+ pass_rtl_hoist(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_hoist, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_rtl_hoist (); }
+ unsigned int execute () { return execute_rtl_hoist (); }
+
+}; // class pass_rtl_hoist
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_hoist (gcc::context *ctxt)
+{
+ return new pass_rtl_hoist (ctxt);
+}
+
#include "gt-gcse.h"
diff --git a/gcc/gdbhooks.py b/gcc/gdbhooks.py
new file mode 100644
index 00000000000..3d69b11bfe9
--- /dev/null
+++ b/gcc/gdbhooks.py
@@ -0,0 +1,397 @@
+# Python hooks for gdb for debugging GCC
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# Contributed by David Malcolm <dmalcolm@redhat.com>
+
+# This file is part of GCC.
+
+# GCC is free software; you can redistribute it and/or modify it under
+# the terms of the GNU General Public License as published by the Free
+# Software Foundation; either version 3, or (at your option) any later
+# version.
+
+# GCC is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+# for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+"""
+Enabling the debugging hooks
+----------------------------
+gcc/configure (from configure.ac) generates a .gdbinit within the "gcc"
+subdirectory of the build directory, and when run by gdb, this imports
+gcc/gdbhooks.py from the source directory, injecting useful Python code
+into gdb.
+
+You may see a message from gdb of the form:
+ "path-to-build/gcc/.gdbinit" auto-loading has been declined by your `auto-load safe-path'
+as a protection against untrustworthy python scripts. See
+ http://sourceware.org/gdb/onlinedocs/gdb/Auto_002dloading-safe-path.html
+
+The fix is to mark the paths of the build/gcc directory as trustworthy.
+An easy way to do so is by adding the following to your ~/.gdbinit script:
+ add-auto-load-safe-path /absolute/path/to/build/gcc
+for the build directories for your various checkouts of gcc.
+
+If it's working, you should see the message:
+ Successfully loaded GDB hooks for GCC
+as gdb starts up.
+
+During development, I've been manually invoking the code in this way, as a
+precanned way of printing a variety of different kinds of value:
+
+ gdb \
+ -ex "break expand_gimple_stmt" \
+ -ex "run" \
+ -ex "bt" \
+ --args \
+ ./cc1 foo.c -O3
+
+Examples of output using the pretty-printers
+--------------------------------------------
+Pointer values are generally shown in the form:
+ <type address extra_info>
+
+For example, an opt_pass* might appear as:
+ (gdb) p pass
+ $2 = <opt_pass* 0x188b600 "expand"(170)>
+
+The name of the pass is given ("expand"), together with the
+static_pass_number.
+
+Note that you can dereference the pointer in the normal way:
+ (gdb) p *pass
+ $4 = {type = RTL_PASS, name = 0x120a312 "expand",
+ [etc, ...snipped...]
+
+and you can suppress pretty-printers using /r (for "raw"):
+ (gdb) p /r pass
+ $3 = (opt_pass *) 0x188b600
+
+Basic blocks are shown with their index in parentheses, apart from the
+CFG's entry and exit blocks, which are given as "ENTRY" and "EXIT":
+ (gdb) p bb
+ $9 = <basic_block 0x7ffff041f1a0 (2)>
+ (gdb) p cfun->cfg->x_entry_block_ptr
+ $10 = <basic_block 0x7ffff041f0d0 (ENTRY)>
+ (gdb) p cfun->cfg->x_exit_block_ptr
+ $11 = <basic_block 0x7ffff041f138 (EXIT)>
+
+CFG edges are shown with the src and dest blocks given in parentheses:
+ (gdb) p e
+ $1 = <edge 0x7ffff043f118 (ENTRY -> 6)>
+
+Tree nodes are printed using Python code that emulates print_node_brief,
+running in gdb, rather than in the inferior:
+ (gdb) p cfun->decl
+ $1 = <function_decl 0x7ffff0420b00 foo>
+For usability, the type is printed first (e.g. "function_decl"), rather
+than just "tree".
+
+RTL expressions use a kludge: they are pretty-printed by injecting
+calls into print-rtl.c into the inferior:
+ Value returned is $1 = (note 9 8 10 [bb 3] NOTE_INSN_BASIC_BLOCK)
+ (gdb) p $1
+ $2 = (note 9 8 10 [bb 3] NOTE_INSN_BASIC_BLOCK)
+ (gdb) p /r $1
+ $3 = (rtx_def *) 0x7ffff043e140
+This won't work for coredumps, and probably in other circumstances, but
+it's a quick way of getting lots of debuggability quickly.
+
+Callgraph nodes are printed with the name of the function decl, if
+available:
+ (gdb) frame 5
+ #5 0x00000000006c288a in expand_function (node=<cgraph_node* 0x7ffff0312720 "foo">) at ../../src/gcc/cgraphunit.c:1594
+ 1594 execute_pass_list (g->get_passes ()->all_passes);
+ (gdb) p node
+ $1 = <cgraph_node* 0x7ffff0312720 "foo">
+"""
+import re
+
+import gdb
+import gdb.printing
+import gdb.types
+
+# Convert "enum tree_code" (tree.def and tree.h) to a dict:
+tree_code_dict = gdb.types.make_enum_dict(gdb.lookup_type('enum tree_code'))
+
+# ...and look up specific values for use later:
+IDENTIFIER_NODE = tree_code_dict['IDENTIFIER_NODE']
+TYPE_DECL = tree_code_dict['TYPE_DECL']
+
+# Similarly for "enum tree_code_class" (tree.h):
+tree_code_class_dict = gdb.types.make_enum_dict(gdb.lookup_type('enum tree_code_class'))
+tcc_type = tree_code_class_dict['tcc_type']
+tcc_declaration = tree_code_class_dict['tcc_declaration']
+
+class Tree:
+ """
+ Wrapper around a gdb.Value for a tree, with various methods
+ corresponding to macros in gcc/tree.h
+ """
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def is_nonnull(self):
+ return long(self.gdbval)
+
+ def TREE_CODE(self):
+ """
+ Get gdb.Value corresponding to TREE_CODE (self)
+ as per:
+ #define TREE_CODE(NODE) ((enum tree_code) (NODE)->base.code)
+ """
+ return self.gdbval['base']['code']
+
+ def DECL_NAME(self):
+ """
+ Get Tree instance corresponding to DECL_NAME (self)
+ """
+ return Tree(self.gdbval['decl_minimal']['name'])
+
+ def TYPE_NAME(self):
+ """
+ Get Tree instance corresponding to result of TYPE_NAME (self)
+ """
+ return Tree(self.gdbval['type_common']['name'])
+
+ def IDENTIFIER_POINTER(self):
+ """
+ Get str correspoinding to result of IDENTIFIER_NODE (self)
+ """
+ return self.gdbval['identifier']['id']['str'].string()
+
+class TreePrinter:
+ "Prints a tree"
+
+ def __init__ (self, gdbval):
+ self.gdbval = gdbval
+ self.node = Tree(gdbval)
+
+ def to_string (self):
+ # like gcc/print-tree.c:print_node_brief
+ # #define TREE_CODE(NODE) ((enum tree_code) (NODE)->base.code)
+ # tree_code_name[(int) TREE_CODE (node)])
+ if long(self.gdbval) == 0:
+ return '<tree 0x0>'
+
+ val_TREE_CODE = self.node.TREE_CODE()
+
+ # extern const enum tree_code_class tree_code_type[];
+ # #define TREE_CODE_CLASS(CODE) tree_code_type[(int) (CODE)]
+
+ val_tree_code_type = gdb.parse_and_eval('tree_code_type')
+ val_tclass = val_tree_code_type[val_TREE_CODE]
+
+ val_tree_code_name = gdb.parse_and_eval('tree_code_name')
+ val_code_name = val_tree_code_name[long(val_TREE_CODE)]
+ #print val_code_name.string()
+
+ result = '<%s 0x%x' % (val_code_name.string(), long(self.gdbval))
+ if long(val_tclass) == tcc_declaration:
+ tree_DECL_NAME = self.node.DECL_NAME()
+ if tree_DECL_NAME.is_nonnull():
+ result += ' %s' % tree_DECL_NAME.IDENTIFIER_POINTER()
+ else:
+ pass # TODO: labels etc
+ elif long(val_tclass) == tcc_type:
+ tree_TYPE_NAME = Tree(self.gdbval['type_common']['name'])
+ if tree_TYPE_NAME.is_nonnull():
+ if tree_TYPE_NAME.TREE_CODE() == IDENTIFIER_NODE:
+ result += ' %s' % tree_TYPE_NAME.IDENTIFIER_POINTER()
+ elif tree_TYPE_NAME.TREE_CODE() == TYPE_DECL:
+ if tree_TYPE_NAME.DECL_NAME().is_nonnull():
+ result += ' %s' % tree_TYPE_NAME.DECL_NAME().IDENTIFIER_POINTER()
+ if self.node.TREE_CODE() == IDENTIFIER_NODE:
+ result += ' %s' % self.node.IDENTIFIER_POINTER()
+ # etc
+ result += '>'
+ return result
+
+######################################################################
+# Callgraph pretty-printers
+######################################################################
+
+class CGraphNodePrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ result = '<cgraph_node* 0x%x' % long(self.gdbval)
+ if long(self.gdbval):
+ # symtab_node_name calls lang_hooks.decl_printable_name
+ # default implementation (lhd_decl_printable_name) is:
+ # return IDENTIFIER_POINTER (DECL_NAME (decl));
+ symbol = self.gdbval['symbol']
+ tree_decl = Tree(symbol['decl'])
+ result += ' "%s"' % tree_decl.DECL_NAME().IDENTIFIER_POINTER()
+ result += '>'
+ return result
+
+######################################################################
+
+class GimplePrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ if long(self.gdbval) == 0:
+ return '<gimple 0x0>'
+ val_gimple_code = self.gdbval['gsbase']['code']
+ val_gimple_code_name = gdb.parse_and_eval('gimple_code_name')
+ val_code_name = val_gimple_code_name[long(val_gimple_code)]
+ result = '<%s 0x%x' % (val_code_name.string(),
+ long(self.gdbval))
+ result += '>'
+ return result
+
+######################################################################
+# CFG pretty-printers
+######################################################################
+
+def bb_index_to_str(index):
+ if index == 0:
+ return 'ENTRY'
+ elif index == 1:
+ return 'EXIT'
+ else:
+ return '%i' % index
+
+class BasicBlockPrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ result = '<basic_block 0x%x' % long(self.gdbval)
+ if long(self.gdbval):
+ result += ' (%s)' % bb_index_to_str(long(self.gdbval['index']))
+ result += '>'
+ return result
+
+class CfgEdgePrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ result = '<edge 0x%x' % long(self.gdbval)
+ if long(self.gdbval):
+ src = bb_index_to_str(long(self.gdbval['src']['index']))
+ dest = bb_index_to_str(long(self.gdbval['dest']['index']))
+ result += ' (%s -> %s)' % (src, dest)
+ result += '>'
+ return result
+
+######################################################################
+
+class Rtx:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def GET_CODE(self):
+ return self.gdbval['code']
+
+def GET_RTX_LENGTH(code):
+ val_rtx_length = gdb.parse_and_eval('rtx_length')
+ return long(val_rtx_length[code])
+
+def GET_RTX_NAME(code):
+ val_rtx_name = gdb.parse_and_eval('rtx_name')
+ return val_rtx_name[code].string()
+
+def GET_RTX_FORMAT(code):
+ val_rtx_format = gdb.parse_and_eval('rtx_format')
+ return val_rtx_format[code].string()
+
+class RtxPrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+ self.rtx = Rtx(gdbval)
+
+ def to_string (self):
+ """
+ For now, a cheap kludge: invoke the inferior's print
+ function to get a string to use the user, and return an empty
+ string for gdb
+ """
+ # We use print_inline_rtx to avoid a trailing newline
+ gdb.execute('call print_inline_rtx (stderr, (const_rtx) %s, 0)'
+ % long(self.gdbval))
+ return ''
+
+ # or by hand; based on gcc/print-rtl.c:print_rtx
+ result = ('<rtx_def 0x%x'
+ % (long(self.gdbval)))
+ code = self.rtx.GET_CODE()
+ result += ' (%s' % GET_RTX_NAME(code)
+ format_ = GET_RTX_FORMAT(code)
+ for i in range(GET_RTX_LENGTH(code)):
+ print format_[i]
+ result += ')>'
+ return result
+
+######################################################################
+
+class PassPrinter:
+ def __init__(self, gdbval):
+ self.gdbval = gdbval
+
+ def to_string (self):
+ result = '<opt_pass* 0x%x' % long(self.gdbval)
+ if long(self.gdbval):
+ result += (' "%s"(%i)'
+ % (self.gdbval['name'].string(),
+ long(self.gdbval['static_pass_number'])))
+ result += '>'
+ return result
+
+######################################################################
+
+# TODO:
+# * vec
+# * hashtab
+# * location_t
+
+class GdbSubprinter(gdb.printing.SubPrettyPrinter):
+ def __init__(self, name, str_type_, class_):
+ super(GdbSubprinter, self).__init__(name)
+ self.str_type_ = str_type_
+ self.class_ = class_
+
+class GdbPrettyPrinters(gdb.printing.PrettyPrinter):
+ def __init__(self, name):
+ super(GdbPrettyPrinters, self).__init__(name, [])
+
+ def add_printer(self, name, exp, class_):
+ self.subprinters.append(GdbSubprinter(name, exp, class_))
+
+ def __call__(self, gdbval):
+ type_ = gdbval.type.unqualified()
+ str_type_ = str(type_)
+ for printer in self.subprinters:
+ if printer.enabled and str_type_ == printer.str_type_:
+ return printer.class_(gdbval)
+
+ # Couldn't find a pretty printer (or it was disabled):
+ return None
+
+
+def build_pretty_printer():
+ pp = GdbPrettyPrinters('gcc')
+ pp.add_printer('tree', 'tree', TreePrinter)
+ pp.add_printer('cgraph_node', 'cgraph_node *', CGraphNodePrinter)
+ pp.add_printer('gimple', 'gimple', GimplePrinter)
+ pp.add_printer('basic_block', 'basic_block', BasicBlockPrinter)
+ pp.add_printer('edge', 'edge', CfgEdgePrinter)
+ pp.add_printer('rtx_def', 'rtx_def *', RtxPrinter)
+ pp.add_printer('opt_pass', 'opt_pass *', PassPrinter)
+ return pp
+
+gdb.printing.register_pretty_printer(
+ gdb.current_objfile(),
+ build_pretty_printer())
+
+print('Successfully loaded GDB hooks for GCC')
diff --git a/gcc/gen-pass-instances.awk b/gcc/gen-pass-instances.awk
new file mode 100644
index 00000000000..a7367aeae5e
--- /dev/null
+++ b/gcc/gen-pass-instances.awk
@@ -0,0 +1,66 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation; either version 3, or (at your option) any
+# later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# This Awk script takes passes.def and writes pass-instances.def,
+# counting the instances of each kind of pass, adding an instance number
+# to everywhere that NEXT_PASS is used.
+#
+# For example, the single-instanced pass:
+# NEXT_PASS (pass_warn_unused_result);
+# becomes this in the output:
+# NEXT_PASS (pass_warn_unused_result, 1);
+#
+# The various instances of
+# NEXT_PASS (pass_copy_prop);
+# become:
+# NEXT_PASS (pass_copy_prop, 1);
+# through:
+# NEXT_PASS (pass_copy_prop, 8);
+# (currently there are 8 instances of that pass)
+
+# Usage: awk -f gen-pass-instances.awk passes.def
+
+BEGIN {
+ print "/* This file is auto-generated by gen-pass-instances.awk";
+ print " from passes.def. */";
+}
+
+function handle_line()
+{
+ line = $0;
+ where = match(line, /NEXT_PASS \((.+)\)/)
+ if (where != 0)
+ {
+ len_of_start = length("NEXT_PASS (")
+ len_of_end = length(")")
+ len_of_pass_name = RLENGTH - (len_of_start + len_of_end)
+ line_length = length(line)
+ pass_starts_at = where + len_of_start
+ pass_name = substr(line, pass_starts_at, len_of_pass_name)
+ if (pass_name in pass_counts)
+ pass_counts[pass_name]++;
+ else
+ pass_counts[pass_name] = 1;
+ printf "%s, %s%s\n",
+ substr(line, 1, pass_starts_at + len_of_pass_name - 1),
+ pass_counts[pass_name],
+ substr(line, pass_starts_at + len_of_pass_name);
+ } else {
+ print line;
+ }
+}
+
+{ handle_line() }
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 8ea16dcdc31..fb1c85eec0d 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -559,6 +559,12 @@ type_p
create_user_defined_type (const char *type_name, struct fileloc *pos)
{
type_p ty = find_structure (type_name, TYPE_USER_STRUCT);
+
+ /* We might have already seen an incomplete decl of the given type,
+ in which case we won't have yet seen a GTY((user)), and the type will
+ only have kind "TYPE_STRUCT". Mark it as a user struct. */
+ ty->kind = TYPE_USER_STRUCT;
+
ty->u.s.line = *pos;
ty->u.s.bitmap = get_lang_bitmap (pos->file);
do_typedef (type_name, ty, pos);
@@ -604,6 +610,16 @@ static type_p
type_for_name (const char *s)
{
pair_p p;
+
+ /* Special-case support for types within a "gcc::" namespace. Rather
+ than fully-supporting namespaces, simply strip off the "gcc::" prefix
+ where present. This allows us to have GTY roots of this form:
+ extern GTY(()) gcc::some_type *some_ptr;
+ where the autogenerated functions will refer to simply "some_type",
+ where they can be resolved into their namespace. */
+ if (0 == strncmp(s, "gcc::", 5))
+ s += 5;
+
for (p = typedefs; p != NULL; p = p->next)
if (strcmp (p->name, s) == 0)
return p->type;
@@ -1740,6 +1756,13 @@ open_base_files (void)
/* Make sure we handle "cfun" specially. */
oprintf (gtype_desc_c, "\n/* See definition in function.h. */\n");
oprintf (gtype_desc_c, "#undef cfun\n");
+
+ oprintf (gtype_desc_c,
+ "\n"
+ "/* Types with a \"gcc::\" namespace have it stripped\n"
+ " during gengtype parsing. Provide a \"using\" directive\n"
+ " to ensure that the fully-qualified types are found. */\n"
+ "using namespace gcc;\n");
}
}
diff --git a/gcc/genoutput.c b/gcc/genoutput.c
index 995c5c55f11..59afaa452aa 100644
--- a/gcc/genoutput.c
+++ b/gcc/genoutput.c
@@ -404,9 +404,9 @@ output_insn_data (void)
}
if (d->name && d->name[0] != '*')
- printf (" (insn_gen_fn) gen_%s,\n", d->name);
+ printf (" { (insn_gen_fn::stored_funcptr) gen_%s },\n", d->name);
else
- printf (" 0,\n");
+ printf (" { 0 },\n");
printf (" &operand_data[%d],\n", d->operand_number);
printf (" %d,\n", d->n_generator_args);
diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c
index 62c71b6843e..e6baabfa03d 100644
--- a/gcc/gimple-fold.c
+++ b/gcc/gimple-fold.c
@@ -1007,13 +1007,14 @@ gimple_fold_builtin (gimple stmt)
represented by a declaration (i.e. a global or automatically allocated one)
or NULL if it cannot be found or is not safe. CST is expected to be an
ADDR_EXPR of such object or the function will return NULL. Currently it is
- safe to use such binfo only if it has no base binfo (i.e. no ancestors). */
+ safe to use such binfo only if it has no base binfo (i.e. no ancestors)
+ EXPECTED_TYPE is type of the class virtual belongs to. */
tree
-gimple_extract_devirt_binfo_from_cst (tree cst)
+gimple_extract_devirt_binfo_from_cst (tree cst, tree expected_type)
{
HOST_WIDE_INT offset, size, max_size;
- tree base, type, expected_type, binfo;
+ tree base, type, binfo;
bool last_artificial = false;
if (!flag_devirtualize
@@ -1022,7 +1023,6 @@ gimple_extract_devirt_binfo_from_cst (tree cst)
return NULL_TREE;
cst = TREE_OPERAND (cst, 0);
- expected_type = TREE_TYPE (cst);
base = get_ref_base_and_extent (cst, &offset, &size, &max_size);
type = TREE_TYPE (base);
if (!DECL_P (base)
@@ -1105,10 +1105,11 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
changed = true;
}
- else
+ else if (virtual_method_call_p (callee))
{
tree obj = OBJ_TYPE_REF_OBJECT (callee);
- tree binfo = gimple_extract_devirt_binfo_from_cst (obj);
+ tree binfo = gimple_extract_devirt_binfo_from_cst
+ (obj, obj_type_ref_class (callee));
if (binfo)
{
HOST_WIDE_INT token
@@ -3096,7 +3097,7 @@ tree
gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo)
{
unsigned HOST_WIDE_INT offset, size;
- tree v, fn, vtable;
+ tree v, fn, vtable, init;
vtable = v = BINFO_VTABLE (known_binfo);
/* If there is no virtual methods table, leave the OBJ_TYPE_REF alone. */
@@ -3116,14 +3117,24 @@ gimple_get_virt_method_for_binfo (HOST_WIDE_INT token, tree known_binfo)
v = TREE_OPERAND (v, 0);
if (TREE_CODE (v) != VAR_DECL
- || !DECL_VIRTUAL_P (v)
- || !DECL_INITIAL (v)
- || DECL_INITIAL (v) == error_mark_node)
+ || !DECL_VIRTUAL_P (v))
return NULL_TREE;
+ init = ctor_for_folding (v);
+
+ /* The virtual tables should always be born with constructors.
+ and we always should assume that they are avaialble for
+ folding. At the moment we do not stream them in all cases,
+ but it should never happen that ctor seem unreachable. */
+ gcc_assert (init);
+ if (init == error_mark_node)
+ {
+ gcc_assert (in_lto_p);
+ return NULL_TREE;
+ }
gcc_checking_assert (TREE_CODE (TREE_TYPE (v)) == ARRAY_TYPE);
size = tree_low_cst (TYPE_SIZE (TREE_TYPE (TREE_TYPE (v))), 1);
offset += token * size;
- fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), DECL_INITIAL (v),
+ fn = fold_ctor_reference (TREE_TYPE (TREE_TYPE (v)), init,
offset, size, vtable);
if (!fn || integer_zerop (fn))
return NULL_TREE;
diff --git a/gcc/gimple-low.c b/gcc/gimple-low.c
index 64cc031785d..2884b6ff6fb 100644
--- a/gcc/gimple-low.c
+++ b/gcc/gimple-low.c
@@ -177,26 +177,43 @@ lower_function_body (void)
return 0;
}
-struct gimple_opt_pass pass_lower_cf =
+namespace {
+
+const pass_data pass_data_lower_cf =
{
- {
- GIMPLE_PASS,
- "lower", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- lower_function_body, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_gimple_any, /* properties_required */
- PROP_gimple_lcf, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "lower", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ PROP_gimple_lcf, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_lower_cf : public gimple_opt_pass
+{
+public:
+ pass_lower_cf(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_cf, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return lower_function_body (); }
+
+}; // class pass_lower_cf
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_cf (gcc::context *ctxt)
+{
+ return new pass_lower_cf (ctxt);
+}
+
/* Verify if the type of the argument matches that of the function
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index ddb086c5715..3ab558cae38 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -36,9 +36,6 @@ along with GCC; see the file COPYING3. If not see
#define INDENT(SPACE) \
do { int i; for (i = 0; i < SPACE; i++) pp_space (buffer); } while (0)
-static pretty_printer buffer;
-static bool initialized = false;
-
#define GIMPLE_NIY do_niy (buffer,gs)
/* Try to print on BUFFER a default message for the unrecognized
@@ -52,22 +49,6 @@ do_niy (pretty_printer *buffer, gimple gs)
}
-/* Initialize the pretty printer on FILE if needed. */
-
-static void
-maybe_init_pretty_print (FILE *file)
-{
- if (!initialized)
- {
- pp_construct (&buffer, NULL, 0);
- pp_needs_newline (&buffer) = true;
- initialized = true;
- }
-
- buffer.buffer->stream = file;
-}
-
-
/* Emit a newline and SPC indentation spaces to BUFFER. */
static void
@@ -93,7 +74,9 @@ debug_gimple_stmt (gimple gs)
void
print_gimple_stmt (FILE *file, gimple g, int spc, int flags)
{
- maybe_init_pretty_print (file);
+ pretty_printer buffer;
+ pp_needs_newline (&buffer) = true;
+ buffer.buffer->stream = file;
pp_gimple_stmt_1 (&buffer, g, spc, flags);
pp_newline_and_flush (&buffer);
}
@@ -122,7 +105,9 @@ void
print_gimple_expr (FILE *file, gimple g, int spc, int flags)
{
flags |= TDF_RHS_ONLY;
- maybe_init_pretty_print (file);
+ pretty_printer buffer;
+ pp_needs_newline (&buffer) = true;
+ buffer.buffer->stream = file;
pp_gimple_stmt_1 (&buffer, g, spc, flags);
pp_flush (&buffer);
}
@@ -155,7 +140,9 @@ dump_gimple_seq (pretty_printer *buffer, gimple_seq seq, int spc, int flags)
void
print_gimple_seq (FILE *file, gimple_seq seq, int spc, int flags)
{
- maybe_init_pretty_print (file);
+ pretty_printer buffer;
+ pp_needs_newline (&buffer) = true;
+ buffer.buffer->stream = file;
dump_gimple_seq (&buffer, seq, spc, flags);
pp_newline_and_flush (&buffer);
}
@@ -280,14 +267,14 @@ dump_unary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
case FIX_TRUNC_EXPR:
case FLOAT_EXPR:
CASE_CONVERT:
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, TREE_TYPE (lhs), spc, flags, false);
pp_string (buffer, ") ");
if (op_prio (rhs) < op_code_prio (rhs_code))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, rhs, spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
else
dump_generic_node (buffer, rhs, spc, flags, false);
@@ -302,7 +289,7 @@ dump_unary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
case ABS_EXPR:
pp_string (buffer, "ABS_EXPR <");
dump_generic_node (buffer, rhs, spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
default:
@@ -317,23 +304,23 @@ dump_unary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
break;
}
else if (rhs_code == BIT_NOT_EXPR)
- pp_character (buffer, '~');
+ pp_complement (buffer);
else if (rhs_code == TRUTH_NOT_EXPR)
- pp_character (buffer, '!');
+ pp_exclamation (buffer);
else if (rhs_code == NEGATE_EXPR)
- pp_character (buffer, '-');
+ pp_minus (buffer);
else
{
- pp_character (buffer, '[');
+ pp_left_bracket (buffer);
pp_string (buffer, tree_code_name [rhs_code]);
pp_string (buffer, "] ");
}
if (op_prio (rhs) < op_code_prio (rhs_code))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, rhs, spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
else
dump_generic_node (buffer, rhs, spc, flags, false);
@@ -370,16 +357,16 @@ dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
default:
if (op_prio (gimple_assign_rhs1 (gs)) <= op_code_prio (code))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags,
false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
else
dump_generic_node (buffer, gimple_assign_rhs1 (gs), spc, flags, false);
@@ -388,10 +375,10 @@ dump_binary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_space (buffer);
if (op_prio (gimple_assign_rhs2 (gs)) <= op_code_prio (code))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags,
false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
else
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
@@ -418,7 +405,7 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
case FMA_EXPR:
@@ -436,7 +423,7 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case VEC_PERM_EXPR:
@@ -446,7 +433,7 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case REALIGN_LOAD_EXPR:
@@ -456,7 +443,7 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case COND_EXPR:
@@ -474,7 +461,7 @@ dump_ternary_rhs (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_generic_node (buffer, gimple_assign_rhs2 (gs), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, gimple_assign_rhs3 (gs), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
default:
@@ -517,7 +504,7 @@ dump_gimple_assign (pretty_printer *buffer, gimple gs, int spc, int flags)
{
dump_generic_node (buffer, gimple_assign_lhs (gs), spc, flags, false);
pp_space (buffer);
- pp_character (buffer, '=');
+ pp_equal (buffer);
if (gimple_assign_nontemporal_move_p (gs))
pp_string (buffer, "{nt}");
@@ -585,7 +572,7 @@ dump_gimple_call_args (pretty_printer *buffer, gimple gs, int flags)
{
if (gimple_call_num_args (gs) > 0)
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
@@ -621,9 +608,9 @@ pp_points_to_solution (pretty_printer *buffer, struct pt_solution *pt)
{
pp_string (buffer, "D.");
pp_decimal_int (buffer, i);
- pp_character (buffer, ' ');
+ pp_space (buffer);
}
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
if (pt->vars_contains_global)
pp_string (buffer, " (glob)");
}
@@ -669,7 +656,7 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_string (buffer, ", ");
dump_gimple_call_args (buffer, gs, flags);
}
- pp_character (buffer, '>');
+ pp_greater (buffer);
}
else
{
@@ -689,7 +676,7 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
print_call_name (buffer, fn, flags);
pp_string (buffer, " (");
dump_gimple_call_args (buffer, gs, flags);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
if (!(flags & TDF_RHS_ONLY))
pp_semicolon (buffer);
}
@@ -698,7 +685,7 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
{
pp_string (buffer, " [static-chain: ");
dump_generic_node (buffer, gimple_call_chain (gs), spc, flags, false);
- pp_character (buffer, ']');
+ pp_right_bracket (buffer);
}
if (gimple_call_return_slot_opt_p (gs))
@@ -757,7 +744,7 @@ dump_gimple_call (pretty_printer *buffer, gimple gs, int spc, int flags)
if (props & PR_READONLY)
pp_string (buffer, "readOnly ");
- pp_string (buffer, "]");
+ pp_right_bracket (buffer);
}
}
@@ -786,12 +773,12 @@ dump_gimple_switch (pretty_printer *buffer, gimple gs, int spc, int flags)
tree case_label = gimple_switch_label (gs, i);
gcc_checking_assert (case_label != NULL_TREE);
dump_generic_node (buffer, case_label, spc, flags, false);
- pp_character (buffer, ' ');
+ pp_space (buffer);
dump_generic_node (buffer, CASE_LABEL (case_label), spc, flags, false);
if (i < gimple_switch_num_labels (gs) - 1)
pp_string (buffer, ", ");
}
- pp_character (buffer, '>');
+ pp_greater (buffer);
}
@@ -817,7 +804,7 @@ dump_gimple_cond (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_generic_node (buffer, gimple_cond_rhs (gs), spc, flags, false);
if (!(flags & TDF_RHS_ONLY))
{
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
if (gimple_cond_true_label (gs))
{
@@ -851,7 +838,7 @@ dump_gimple_label (pretty_printer *buffer, gimple gs, int spc, int flags)
else
{
dump_generic_node (buffer, label, spc, flags, false);
- pp_character (buffer, ':');
+ pp_colon (buffer);
}
if (DECL_NONLOCAL (label))
pp_string (buffer, " [non-local]");
@@ -884,7 +871,7 @@ dump_gimple_bind (pretty_printer *buffer, gimple gs, int spc, int flags)
if (flags & TDF_RAW)
dump_gimple_fmt (buffer, spc, flags, "%G <", gs);
else
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
if (!(flags & TDF_SLIM))
{
tree var;
@@ -901,9 +888,9 @@ dump_gimple_bind (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_gimple_seq (buffer, gimple_bind_body (gs), spc + 2, flags);
newline_and_indent (buffer, spc);
if (flags & TDF_RAW)
- pp_character (buffer, '>');
+ pp_greater (buffer);
else
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
@@ -931,26 +918,26 @@ dump_gimple_try (pretty_printer *buffer, gimple gs, int spc, int flags)
{
pp_string (buffer, "try");
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_try_eval (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
if (gimple_try_kind (gs) == GIMPLE_TRY_CATCH)
{
newline_and_indent (buffer, spc);
pp_string (buffer, "catch");
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
}
else if (gimple_try_kind (gs) == GIMPLE_TRY_FINALLY)
{
newline_and_indent (buffer, spc);
pp_string (buffer, "finally");
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
}
else
pp_string (buffer, " <UNKNOWN GIMPLE_TRY> {");
@@ -958,7 +945,7 @@ dump_gimple_try (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_try_cleanup (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
@@ -1101,8 +1088,20 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
if (flags & TDF_RAW)
{
- dump_gimple_fmt (buffer, spc, flags, "%G <%+BODY <%S>%nCLAUSES <", gs,
- gimple_omp_body (gs));
+ const char *kind;
+ switch (gimple_omp_for_kind (gs))
+ {
+ case GF_OMP_FOR_KIND_FOR:
+ kind = "";
+ break;
+ case GF_OMP_FOR_KIND_SIMD:
+ kind = " simd";
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ dump_gimple_fmt (buffer, spc, flags, "%G%s <%+BODY <%S>%nCLAUSES <", gs,
+ kind, gimple_omp_body (gs));
dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
dump_gimple_fmt (buffer, spc, flags, " >,");
for (i = 0; i < gimple_omp_for_collapse (gs); i++)
@@ -1118,7 +1117,17 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
}
else
{
- pp_string (buffer, "#pragma omp for");
+ switch (gimple_omp_for_kind (gs))
+ {
+ case GF_OMP_FOR_KIND_FOR:
+ pp_string (buffer, "#pragma omp for");
+ break;
+ case GF_OMP_FOR_KIND_SIMD:
+ pp_string (buffer, "#pragma omp simd");
+ break;
+ default:
+ gcc_unreachable ();
+ }
dump_omp_clauses (buffer, gimple_omp_for_clauses (gs), spc, flags);
for (i = 0; i < gimple_omp_for_collapse (gs); i++)
{
@@ -1139,16 +1148,16 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
switch (gimple_omp_for_cond (gs, i))
{
case LT_EXPR:
- pp_character (buffer, '<');
+ pp_less (buffer);
break;
case GT_EXPR:
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
case LE_EXPR:
- pp_string (buffer, "<=");
+ pp_less_equal (buffer);
break;
case GE_EXPR:
- pp_string (buffer, ">=");
+ pp_greater_equal (buffer);
break;
default:
gcc_unreachable ();
@@ -1163,17 +1172,17 @@ dump_gimple_omp_for (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_string (buffer, " = ");
dump_generic_node (buffer, gimple_omp_for_incr (gs, i), spc,
flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
}
@@ -1194,11 +1203,11 @@ dump_gimple_omp_continue (pretty_printer *buffer, gimple gs, int spc, int flags)
pp_string (buffer, "#pragma omp continue (");
dump_generic_node (buffer, gimple_omp_continue_control_def (gs),
spc, flags, false);
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
dump_generic_node (buffer, gimple_omp_continue_control_use (gs),
spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
}
@@ -1221,11 +1230,11 @@ dump_gimple_omp_single (pretty_printer *buffer, gimple gs, int spc, int flags)
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
}
@@ -1251,17 +1260,17 @@ dump_gimple_omp_sections (pretty_printer *buffer, gimple gs, int spc,
pp_string (buffer, " <");
dump_generic_node (buffer, gimple_omp_sections_control (gs), spc,
flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
}
dump_omp_clauses (buffer, gimple_omp_sections_clauses (gs), spc, flags);
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
}
@@ -1294,11 +1303,11 @@ dump_gimple_omp_block (pretty_printer *buffer, gimple gs, int spc, int flags)
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
}
@@ -1320,16 +1329,16 @@ dump_gimple_omp_critical (pretty_printer *buffer, gimple gs, int spc,
pp_string (buffer, " (");
dump_generic_node (buffer, gimple_omp_critical_name (gs), spc,
flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
if (!gimple_seq_empty_p (gimple_omp_body (gs)))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_omp_body (gs), spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
}
@@ -1420,19 +1429,19 @@ dump_gimple_transaction (pretty_printer *buffer, gimple gs, int spc, int flags)
}
if (subcode)
pp_printf (buffer, "0x%x ", subcode);
- pp_string (buffer, "]");
+ pp_right_bracket (buffer);
}
}
if (!gimple_seq_empty_p (gimple_transaction_body (gs)))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, gimple_transaction_body (gs),
spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
}
@@ -1508,7 +1517,7 @@ dump_gimple_asm (pretty_printer *buffer, gimple gs, int spc, int flags)
}
newline_and_indent (buffer, spc);
- pp_character (buffer, '>');
+ pp_greater (buffer);
}
else
{
@@ -1634,26 +1643,26 @@ dump_gimple_phi (pretty_printer *buffer, gimple phi, int spc, int flags)
expanded_location xloc;
xloc = expand_location (gimple_phi_arg_location (phi, i));
- pp_character (buffer, '[');
+ pp_left_bracket (buffer);
if (xloc.file)
{
pp_string (buffer, xloc.file);
pp_string (buffer, " : ");
}
pp_decimal_int (buffer, xloc.line);
- pp_string (buffer, ":");
+ pp_colon (buffer);
pp_decimal_int (buffer, xloc.column);
pp_string (buffer, "] ");
}
dump_generic_node (buffer, gimple_phi_arg_def (phi, i), spc, flags,
false);
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
pp_decimal_int (buffer, gimple_phi_arg_edge (phi, i)->src->index);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
if (i < gimple_phi_num_args (phi) - 1)
pp_string (buffer, ", ");
}
- pp_character (buffer, '>');
+ pp_greater (buffer);
}
@@ -1696,11 +1705,11 @@ dump_gimple_omp_parallel (pretty_printer *buffer, gimple gs, int spc,
if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, body, spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
else if (body)
{
@@ -1753,11 +1762,11 @@ dump_gimple_omp_task (pretty_printer *buffer, gimple gs, int spc,
if (body && gimple_code (gimple_seq_first_stmt (body)) != GIMPLE_BIND)
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
dump_gimple_seq (buffer, body, spc + 4, flags);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
else if (body)
{
@@ -1791,9 +1800,9 @@ dump_gimple_omp_atomic_load (pretty_printer *buffer, gimple gs, int spc,
dump_generic_node (buffer, gimple_omp_atomic_load_lhs (gs),
spc, flags, false);
pp_space (buffer);
- pp_character (buffer, '=');
+ pp_equal (buffer);
pp_space (buffer);
- pp_character (buffer, '*');
+ pp_star (buffer);
dump_generic_node (buffer, gimple_omp_atomic_load_rhs (gs),
spc, flags, false);
}
@@ -1817,10 +1826,10 @@ dump_gimple_omp_atomic_store (pretty_printer *buffer, gimple gs, int spc,
pp_string (buffer, "#pragma omp atomic_store ");
if (gimple_omp_atomic_need_value_p (gs))
pp_string (buffer, "[needed] ");
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, gimple_omp_atomic_store_val (gs),
spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
}
@@ -1844,14 +1853,14 @@ dump_gimple_mem_ops (pretty_printer *buffer, gimple gs, int spc, int flags)
dump_generic_node (buffer, vdef, spc + 2, flags, false);
pp_string (buffer, " = VDEF <");
dump_generic_node (buffer, vuse, spc + 2, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
newline_and_indent (buffer, spc);
}
else if (vuse != NULL_TREE)
{
pp_string (buffer, "# VUSE <");
dump_generic_node (buffer, vuse, spc + 2, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
newline_and_indent (buffer, spc);
}
}
@@ -1874,14 +1883,14 @@ pp_gimple_stmt_1 (pretty_printer *buffer, gimple gs, int spc, int flags)
if ((flags & TDF_LINENO) && gimple_has_location (gs))
{
expanded_location xloc = expand_location (gimple_location (gs));
- pp_character (buffer, '[');
+ pp_left_bracket (buffer);
if (xloc.file)
{
pp_string (buffer, xloc.file);
pp_string (buffer, " : ");
}
pp_decimal_int (buffer, xloc.line);
- pp_string (buffer, ":");
+ pp_colon (buffer);
pp_decimal_int (buffer, xloc.column);
pp_string (buffer, "] ");
}
@@ -2155,12 +2164,12 @@ pp_cfg_jump (pretty_printer *buffer, basic_block bb)
pp_string (buffer, "goto <bb ");
pp_decimal_int (buffer, bb->index);
- pp_character (buffer, '>');
+ pp_greater (buffer);
if (stmt && gimple_code (stmt) == GIMPLE_LABEL)
{
pp_string (buffer, " (");
dump_generic_node (buffer, gimple_label_label (stmt), 0, 0, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
pp_semicolon (buffer);
}
else
@@ -2215,7 +2224,7 @@ dump_implicit_edges (pretty_printer *buffer, basic_block bb, int indent,
{
expanded_location goto_xloc;
goto_xloc = expand_location (e->goto_locus);
- pp_character (buffer, '[');
+ pp_left_bracket (buffer);
if (goto_xloc.file)
{
pp_string (buffer, goto_xloc.file);
@@ -2262,7 +2271,7 @@ gimple_dump_bb_buff (pretty_printer *buffer, basic_block bb, int indent,
pp_newline_and_flush (buffer);
gcc_checking_assert (DECL_STRUCT_FUNCTION (current_function_decl));
dump_histograms_for_stmt (DECL_STRUCT_FUNCTION (current_function_decl),
- buffer->buffer->stream, stmt);
+ pp_buffer(buffer)->stream, stmt);
}
dump_implicit_edges (buffer, bb, indent, flags);
@@ -2279,7 +2288,9 @@ gimple_dump_bb (FILE *file, basic_block bb, int indent, int flags)
dump_gimple_bb_header (file, bb, indent, flags);
if (bb->index >= NUM_FIXED_BLOCKS)
{
- maybe_init_pretty_print (file);
+ pretty_printer buffer;
+ pp_needs_newline (&buffer) = true;
+ buffer.buffer->stream = file;
gimple_dump_bb_buff (&buffer, bb, indent, flags);
}
dump_gimple_bb_footer (file, bb, indent, flags);
@@ -2304,7 +2315,7 @@ gimple_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
if (!virtual_operand_p (gimple_phi_result (phi))
|| (dump_flags & TDF_VOPS))
{
- pp_character (pp, '|');
+ pp_bar (pp);
pp_write_text_to_stream (pp);
pp_string (pp, "# ");
pp_gimple_stmt_1 (pp, phi, 0, dump_flags);
@@ -2316,7 +2327,7 @@ gimple_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
- pp_character (pp, '|');
+ pp_bar (pp);
pp_write_text_to_stream (pp);
pp_gimple_stmt_1 (pp, stmt, 0, dump_flags);
pp_newline (pp);
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index 9a53bf7c339..e85e6293db4 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -1728,11 +1728,23 @@ dump_incr_vec (void)
static void
replace_ref (tree *expr, slsr_cand_t c)
{
- tree add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr),
- c->base_expr, c->stride);
- tree mem_ref = fold_build2 (MEM_REF, TREE_TYPE (*expr), add_expr,
- double_int_to_tree (c->cand_type, c->index));
-
+ tree add_expr, mem_ref, acc_type = TREE_TYPE (*expr);
+ unsigned HOST_WIDE_INT misalign;
+ unsigned align;
+
+ /* Ensure the memory reference carries the minimum alignment
+ requirement for the data type. See PR58041. */
+ get_object_alignment_1 (*expr, &align, &misalign);
+ if (misalign != 0)
+ align = (misalign & -misalign);
+ if (align < TYPE_ALIGN (acc_type))
+ acc_type = build_aligned_type (acc_type, align);
+
+ add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr),
+ c->base_expr, c->stride);
+ mem_ref = fold_build2 (MEM_REF, acc_type, add_expr,
+ double_int_to_tree (c->cand_type, c->index));
+
/* Gimplify the base addressing expression for the new MEM_REF tree. */
gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
TREE_OPERAND (mem_ref, 0)
@@ -1882,6 +1894,7 @@ replace_mult_candidate (slsr_cand_t c, tree basis_name, double_int bump)
gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
gsi_replace (&gsi, copy_stmt, false);
+ c->cand_stmt = copy_stmt;
if (dump_file && (dump_flags & TDF_DETAILS))
stmt_to_print = copy_stmt;
}
@@ -1910,6 +1923,7 @@ replace_mult_candidate (slsr_cand_t c, tree basis_name, double_int bump)
gimple_assign_set_rhs_with_ops (&gsi, code,
basis_name, bump_tree);
update_stmt (gsi_stmt (gsi));
+ c->cand_stmt = gsi_stmt (gsi);
if (dump_file && (dump_flags & TDF_DETAILS))
stmt_to_print = gsi_stmt (gsi);
}
@@ -2179,6 +2193,18 @@ phi_add_costs (gimple phi, slsr_cand_t c, int one_add_cost)
int cost = 0;
slsr_cand_t phi_cand = base_cand_from_table (gimple_phi_result (phi));
+ /* If we work our way back to a phi that isn't dominated by the hidden
+ basis, this isn't a candidate for replacement. Indicate this by
+ returning an unreasonably high cost. It's not easy to detect
+ these situations when determining the basis, so we defer the
+ decision until now. */
+ basic_block phi_bb = gimple_bb (phi);
+ slsr_cand_t basis = lookup_cand (c->basis);
+ basic_block basis_bb = gimple_bb (basis->cand_stmt);
+
+ if (phi_bb == basis_bb || !dominated_by_p (CDI_DOMINATORS, phi_bb, basis_bb))
+ return COST_INFINITE;
+
for (i = 0; i < gimple_phi_num_args (phi); i++)
{
tree arg = gimple_phi_arg_def (phi, i);
@@ -3101,6 +3127,7 @@ replace_rhs_if_not_dup (enum tree_code new_code, tree new_rhs1, tree new_rhs2,
gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
gimple_assign_set_rhs_with_ops (&gsi, new_code, new_rhs1, new_rhs2);
update_stmt (gsi_stmt (gsi));
+ c->cand_stmt = gsi_stmt (gsi);
if (dump_file && (dump_flags & TDF_DETAILS))
return gsi_stmt (gsi);
@@ -3206,6 +3233,7 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
gimple_assign_set_rhs_with_ops (&gsi, MINUS_EXPR, basis_name, rhs2);
update_stmt (gsi_stmt (gsi));
+ c->cand_stmt = gsi_stmt (gsi);
if (dump_file && (dump_flags & TDF_DETAILS))
stmt_to_print = gsi_stmt (gsi);
@@ -3226,6 +3254,7 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
gimple_stmt_iterator gsi = gsi_for_stmt (c->cand_stmt);
gimple_set_location (copy_stmt, gimple_location (c->cand_stmt));
gsi_replace (&gsi, copy_stmt, false);
+ c->cand_stmt = copy_stmt;
if (dump_file && (dump_flags & TDF_DETAILS))
stmt_to_print = copy_stmt;
@@ -3238,6 +3267,7 @@ replace_one_candidate (slsr_cand_t c, unsigned i, tree basis_name)
NULL_TREE);
gimple_set_location (cast_stmt, gimple_location (c->cand_stmt));
gsi_replace (&gsi, cast_stmt, false);
+ c->cand_stmt = cast_stmt;
if (dump_file && (dump_flags & TDF_DETAILS))
stmt_to_print = cast_stmt;
@@ -3460,22 +3490,40 @@ gate_strength_reduction (void)
return flag_tree_slsr;
}
-struct gimple_opt_pass pass_strength_reduction =
-{
- {
- GIMPLE_PASS,
- "slsr", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_strength_reduction, /* gate */
- execute_strength_reduction, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_GIMPLE_SLSR, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_strength_reduction =
+{
+ GIMPLE_PASS, /* type */
+ "slsr", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_GIMPLE_SLSR, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_strength_reduction : public gimple_opt_pass
+{
+public:
+ pass_strength_reduction(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_strength_reduction, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_strength_reduction (); }
+ unsigned int execute () { return execute_strength_reduction (); }
+
+}; // class pass_strength_reduction
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_strength_reduction (gcc::context *ctxt)
+{
+ return new pass_strength_reduction (ctxt);
+}
diff --git a/gcc/gimple-streamer-in.c b/gcc/gimple-streamer-in.c
index 03fbe91bbe2..29e8bd04c83 100644
--- a/gcc/gimple-streamer-in.c
+++ b/gcc/gimple-streamer-in.c
@@ -80,7 +80,7 @@ input_phi (struct lto_input_block *ib, basic_block bb, struct data_in *data_in,
static gimple
input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
- struct function *fn, enum LTO_tags tag)
+ enum LTO_tags tag)
{
gimple stmt;
enum gimple_code code;
@@ -282,9 +282,6 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
if (lhs && TREE_CODE (lhs) == SSA_NAME)
SSA_NAME_DEF_STMT (lhs) = stmt;
}
- else if (code == GIMPLE_LABEL)
- gcc_assert (emit_label_in_global_context_p (gimple_label_label (stmt))
- || DECL_CONTEXT (gimple_label_label (stmt)) == fn->decl);
else if (code == GIMPLE_ASM)
{
unsigned i;
@@ -342,7 +339,7 @@ input_bb (struct lto_input_block *ib, enum LTO_tags tag,
tag = streamer_read_record_start (ib);
while (tag)
{
- gimple stmt = input_gimple_stmt (ib, data_in, fn, tag);
+ gimple stmt = input_gimple_stmt (ib, data_in, tag);
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
/* After the statement, expect a 0 delimiter or the EH region
diff --git a/gcc/gimple.c b/gcc/gimple.c
index f5074199381..4dbcdda31b9 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -902,19 +902,21 @@ gimple_build_omp_critical (gimple_seq body, tree name)
/* Build a GIMPLE_OMP_FOR statement.
BODY is sequence of statements inside the for loop.
+ KIND is the `for' variant.
CLAUSES, are any of the OMP loop construct's clauses: private, firstprivate,
lastprivate, reductions, ordered, schedule, and nowait.
COLLAPSE is the collapse count.
PRE_BODY is the sequence of statements that are loop invariant. */
gimple
-gimple_build_omp_for (gimple_seq body, tree clauses, size_t collapse,
+gimple_build_omp_for (gimple_seq body, int kind, tree clauses, size_t collapse,
gimple_seq pre_body)
{
gimple p = gimple_alloc (GIMPLE_OMP_FOR, 0);
if (body)
gimple_omp_set_body (p, body);
gimple_omp_for_set_clauses (p, clauses);
+ gimple_omp_for_set_kind (p, kind);
p->gimple_omp_for.collapse = collapse;
p->gimple_omp_for.iter
= ggc_alloc_cleared_vec_gimple_omp_for_iter (collapse);
@@ -4049,6 +4051,13 @@ walk_stmt_load_store_addr_ops (gimple stmt, void *data,
ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
}
}
+ else if (visit_addr
+ && gimple_code (stmt) == GIMPLE_GOTO)
+ {
+ tree op = gimple_goto_dest (stmt);
+ if (TREE_CODE (op) == ADDR_EXPR)
+ ret |= visit_addr (stmt, TREE_OPERAND (op, 0), data);
+ }
return ret;
}
diff --git a/gcc/gimple.def b/gcc/gimple.def
index acad572e353..f3652f4e78f 100644
--- a/gcc/gimple.def
+++ b/gcc/gimple.def
@@ -287,7 +287,7 @@ DEFGSCODE(GIMPLE_OMP_ORDERED, "gimple_omp_ordered", GSS_OMP)
BODY is a the sequence of statements to be executed by all threads.
- CLAUSES is a TREE_LIST node with all the clauses.
+ CLAUSES is an OMP_CLAUSE chain with all the clauses.
CHILD_FN is set when outlining the body of the parallel region.
All the statements in BODY are moved into this newly created
@@ -306,7 +306,7 @@ DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", GSS_OMP_PARALLEL)
BODY is a the sequence of statements to be executed by all threads.
- CLAUSES is a TREE_LIST node with all the clauses.
+ CLAUSES is an OMP_CLAUSE chain with all the clauses.
CHILD_FN is set when outlining the body of the explicit task region.
All the statements in BODY are moved into this newly created
@@ -334,7 +334,7 @@ DEFGSCODE(GIMPLE_OMP_SECTION, "gimple_omp_section", GSS_OMP)
/* OMP_SECTIONS <BODY, CLAUSES, CONTROL> represents #pragma omp sections.
BODY is the sequence of statements in the sections body.
- CLAUSES is a TREE_LIST node holding the list of associated clauses.
+ CLAUSES is an OMP_CLAUSE chain holding the list of associated clauses.
CONTROL is a VAR_DECL used for deciding which of the sections
to execute. */
DEFGSCODE(GIMPLE_OMP_SECTIONS, "gimple_omp_sections", GSS_OMP_SECTIONS)
@@ -346,7 +346,7 @@ DEFGSCODE(GIMPLE_OMP_SECTIONS_SWITCH, "gimple_omp_sections_switch", GSS_BASE)
/* GIMPLE_OMP_SINGLE <BODY, CLAUSES> represents #pragma omp single
BODY is the sequence of statements inside the single section.
- CLAUSES is a TREE_LIST node holding the associated clauses. */
+ CLAUSES is an OMP_CLAUSE chain holding the associated clauses. */
DEFGSCODE(GIMPLE_OMP_SINGLE, "gimple_omp_single", GSS_OMP_SINGLE)
/* GIMPLE_PREDICT <PREDICT, OUTCOME> specifies a hint for branch prediction.
diff --git a/gcc/gimple.h b/gcc/gimple.h
index 8ae07c9ba5d..9f29561eb37 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -110,6 +110,9 @@ enum gf_mask {
GF_CALL_ALLOCA_FOR_VAR = 1 << 5,
GF_CALL_INTERNAL = 1 << 6,
GF_OMP_PARALLEL_COMBINED = 1 << 0,
+ GF_OMP_FOR_KIND_MASK = 3 << 0,
+ GF_OMP_FOR_KIND_FOR = 0 << 0,
+ GF_OMP_FOR_KIND_SIMD = 1 << 0,
/* True on an GIMPLE_OMP_RETURN statement if the return does not require
a thread synchronization via some sort of barrier. The exact barrier
@@ -799,7 +802,7 @@ gimple gimple_build_switch_nlabels (unsigned, tree, tree);
gimple gimple_build_switch (tree, tree, vec<tree> );
gimple gimple_build_omp_parallel (gimple_seq, tree, tree, tree);
gimple gimple_build_omp_task (gimple_seq, tree, tree, tree, tree, tree, tree);
-gimple gimple_build_omp_for (gimple_seq, tree, size_t, gimple_seq);
+gimple gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq);
gimple gimple_build_omp_critical (gimple_seq, tree);
gimple gimple_build_omp_section (gimple_seq);
gimple gimple_build_omp_continue (tree, tree);
@@ -854,7 +857,7 @@ unsigned get_gimple_rhs_num_ops (enum tree_code);
gimple gimple_alloc_stat (enum gimple_code, unsigned MEM_STAT_DECL);
const char *gimple_decl_printable_name (tree, int);
tree gimple_get_virt_method_for_binfo (HOST_WIDE_INT, tree);
-tree gimple_extract_devirt_binfo_from_cst (tree);
+tree gimple_extract_devirt_binfo_from_cst (tree, tree);
/* Returns true iff T is a scalar register variable. */
extern bool is_gimple_reg (tree);
@@ -3948,6 +3951,27 @@ gimple_omp_critical_set_name (gimple gs, tree name)
}
+/* Return the kind of OMP for statemement. */
+
+static inline int
+gimple_omp_for_kind (const_gimple g)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_FOR);
+ return (gimple_omp_subcode (g) & GF_OMP_FOR_KIND_MASK);
+}
+
+
+/* Set the OMP for kind. */
+
+static inline void
+gimple_omp_for_set_kind (gimple g, int kind)
+{
+ GIMPLE_CHECK (g, GIMPLE_OMP_FOR);
+ g->gsbase.subcode = (g->gsbase.subcode & ~GF_OMP_FOR_KIND_MASK)
+ | (kind & GF_OMP_FOR_KIND_MASK);
+}
+
+
/* Return the clauses associated with OMP_FOR GS. */
static inline tree
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index 4d39d539f2d..3b3adb34317 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -58,14 +58,17 @@ enum gimplify_omp_var_data
GOVD_LOCAL = 128,
GOVD_DEBUG_PRIVATE = 256,
GOVD_PRIVATE_OUTER_REF = 512,
+ GOVD_LINEAR = 2048,
GOVD_DATA_SHARE_CLASS = (GOVD_SHARED | GOVD_PRIVATE | GOVD_FIRSTPRIVATE
- | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LOCAL)
+ | GOVD_LASTPRIVATE | GOVD_REDUCTION | GOVD_LINEAR
+ | GOVD_LOCAL)
};
enum omp_region_type
{
ORT_WORKSHARE = 0,
+ ORT_SIMD = 1,
ORT_PARALLEL = 2,
ORT_COMBINED_PARALLEL = 3,
ORT_TASK = 4,
@@ -710,7 +713,9 @@ gimple_add_tmp_var (tree tmp)
if (gimplify_omp_ctxp)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
- while (ctx && ctx->region_type == ORT_WORKSHARE)
+ while (ctx
+ && (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD))
ctx = ctx->outer_context;
if (ctx)
omp_add_variable (ctx, tmp, GOVD_LOCAL | GOVD_SEEN);
@@ -2061,7 +2066,9 @@ gimplify_var_or_parm_decl (tree *expr_p)
&& decl_function_context (decl) != current_function_decl)
{
struct gimplify_omp_ctx *ctx = gimplify_omp_ctxp;
- while (ctx && ctx->region_type == ORT_WORKSHARE)
+ while (ctx
+ && (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD))
ctx = ctx->outer_context;
if (!ctx && !pointer_set_insert (nonlocal_vlas, decl))
{
@@ -4702,6 +4709,7 @@ is_gimple_stmt (tree t)
case STATEMENT_LIST:
case OMP_PARALLEL:
case OMP_FOR:
+ case OMP_SIMD:
case OMP_SECTIONS:
case OMP_SECTION:
case OMP_SINGLE:
@@ -5714,7 +5722,8 @@ omp_firstprivatize_variable (struct gimplify_omp_ctx *ctx, tree decl)
else
return;
}
- else if (ctx->region_type != ORT_WORKSHARE)
+ else if (ctx->region_type != ORT_WORKSHARE
+ && ctx->region_type != ORT_SIMD)
omp_add_variable (ctx, decl, GOVD_FIRSTPRIVATE);
ctx = ctx->outer_context;
@@ -5806,7 +5815,8 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
FIRSTPRIVATE and LASTPRIVATE. */
nflags = n->value | flags;
gcc_assert ((nflags & GOVD_DATA_SHARE_CLASS)
- == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE));
+ == (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE)
+ || (flags & GOVD_DATA_SHARE_CLASS) == 0);
n->value = nflags;
return;
}
@@ -5870,7 +5880,10 @@ omp_add_variable (struct gimplify_omp_ctx *ctx, tree decl, unsigned int flags)
}
}
- splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
+ if (n != NULL)
+ n->value |= flags;
+ else
+ splay_tree_insert (ctx->variables, (splay_tree_key)decl, flags);
}
/* Notice a threadprivate variable DECL used in OpenMP context CTX.
@@ -5936,7 +5949,8 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
enum omp_clause_default_kind default_kind, kind;
struct gimplify_omp_ctx *octx;
- if (ctx->region_type == ORT_WORKSHARE)
+ if (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD)
goto do_outer;
/* ??? Some compiler-generated variables (like SAVE_EXPRs) could be
@@ -6049,7 +6063,7 @@ omp_notice_variable (struct gimplify_omp_ctx *ctx, tree decl, bool in_code)
to the contrary in the innermost scope, generate an error. */
static bool
-omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
+omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, bool simd)
{
splay_tree_node n;
@@ -6060,8 +6074,12 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
{
if (ctx == gimplify_omp_ctxp)
{
- error ("iteration variable %qE should be private",
- DECL_NAME (decl));
+ if (simd)
+ error ("iteration variable %qE is predetermined linear",
+ DECL_NAME (decl));
+ else
+ error ("iteration variable %qE should be private",
+ DECL_NAME (decl));
n->value = GOVD_PRIVATE;
return true;
}
@@ -6079,16 +6097,26 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl)
else if ((n->value & GOVD_REDUCTION) != 0)
error ("iteration variable %qE should not be reduction",
DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_LASTPRIVATE) != 0)
+ error ("iteration variable %qE should not be lastprivate",
+ DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_PRIVATE) != 0)
+ error ("iteration variable %qE should not be private",
+ DECL_NAME (decl));
+ else if (simd && (n->value & GOVD_LINEAR) != 0)
+ error ("iteration variable %qE is predetermined linear",
+ DECL_NAME (decl));
}
return (ctx == gimplify_omp_ctxp
|| (ctx->region_type == ORT_COMBINED_PARALLEL
&& gimplify_omp_ctxp->outer_context == ctx));
}
- if (ctx->region_type != ORT_WORKSHARE)
+ if (ctx->region_type != ORT_WORKSHARE
+ && ctx->region_type != ORT_SIMD)
return false;
else if (ctx->outer_context)
- return omp_is_private (ctx->outer_context, decl);
+ return omp_is_private (ctx->outer_context, decl, simd);
return false;
}
@@ -6113,7 +6141,8 @@ omp_check_private (struct gimplify_omp_ctx *ctx, tree decl)
if (n != NULL)
return (n->value & GOVD_SHARED) == 0;
}
- while (ctx->region_type == ORT_WORKSHARE);
+ while (ctx->region_type == ORT_WORKSHARE
+ || ctx->region_type == ORT_SIMD);
return false;
}
@@ -6166,6 +6195,15 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
flags = GOVD_REDUCTION | GOVD_SEEN | GOVD_EXPLICIT;
check_non_private = "reduction";
goto do_add;
+ case OMP_CLAUSE_LINEAR:
+ if (gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c), pre_p, NULL,
+ is_gimple_val, fb_rvalue) == GS_ERROR)
+ {
+ remove = true;
+ break;
+ }
+ flags = GOVD_LINEAR | GOVD_EXPLICIT;
+ goto do_add;
do_add:
decl = OMP_CLAUSE_DECL (c);
@@ -6264,6 +6302,7 @@ gimplify_scan_omp_clauses (tree *list_p, gimple_seq *pre_p,
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
case OMP_CLAUSE_DEFAULT:
@@ -6321,7 +6360,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
splay_tree_node on
= splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
if (on && (on->value & (GOVD_FIRSTPRIVATE | GOVD_LASTPRIVATE
- | GOVD_PRIVATE | GOVD_REDUCTION)) != 0)
+ | GOVD_PRIVATE | GOVD_REDUCTION
+ | GOVD_LINEAR)) != 0)
break;
ctx = ctx->outer_context;
}
@@ -6334,6 +6374,8 @@ gimplify_adjust_omp_clauses_1 (splay_tree_node n, void *data)
code = OMP_CLAUSE_PRIVATE;
else if (flags & GOVD_FIRSTPRIVATE)
code = OMP_CLAUSE_FIRSTPRIVATE;
+ else if (flags & GOVD_LASTPRIVATE)
+ code = OMP_CLAUSE_LASTPRIVATE;
else
gcc_unreachable ();
@@ -6366,6 +6408,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_SHARED:
case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LINEAR:
decl = OMP_CLAUSE_DECL (c);
n = splay_tree_lookup (ctx->variables, (splay_tree_key) decl);
remove = !(n->value & GOVD_SEEN);
@@ -6381,6 +6424,31 @@ gimplify_adjust_omp_clauses (tree *list_p)
OMP_CLAUSE_SET_CODE (c, OMP_CLAUSE_PRIVATE);
OMP_CLAUSE_PRIVATE_DEBUG (c) = 1;
}
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && ctx->outer_context
+ && !(OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+ && OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+ && !is_global_var (decl))
+ {
+ if (ctx->outer_context->region_type == ORT_COMBINED_PARALLEL)
+ {
+ n = splay_tree_lookup (ctx->outer_context->variables,
+ (splay_tree_key) decl);
+ if (n == NULL
+ || (n->value & GOVD_DATA_SHARE_CLASS) == 0)
+ {
+ int flags = OMP_CLAUSE_LINEAR_NO_COPYIN (c)
+ ? GOVD_LASTPRIVATE : GOVD_SHARED;
+ if (n == NULL)
+ omp_add_variable (ctx->outer_context, decl,
+ flags | GOVD_SEEN);
+ else
+ n->value |= flags | GOVD_SEEN;
+ }
+ }
+ else
+ omp_notice_variable (ctx->outer_context, decl, true);
+ }
}
break;
@@ -6406,6 +6474,7 @@ gimplify_adjust_omp_clauses (tree *list_p)
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
default:
@@ -6509,14 +6578,40 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gimple gfor;
gimple_seq for_body, for_pre_body;
int i;
+ bool simd;
+ bitmap has_decl_expr = NULL;
for_stmt = *expr_p;
+ simd = TREE_CODE (for_stmt) == OMP_SIMD;
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
- ORT_WORKSHARE);
+ simd ? ORT_SIMD : ORT_WORKSHARE);
/* Handle OMP_FOR_INIT. */
for_pre_body = NULL;
+ if (simd && OMP_FOR_PRE_BODY (for_stmt))
+ {
+ has_decl_expr = BITMAP_ALLOC (NULL);
+ if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (OMP_FOR_PRE_BODY (for_stmt)))
+ == VAR_DECL)
+ {
+ t = OMP_FOR_PRE_BODY (for_stmt);
+ bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
+ }
+ else if (TREE_CODE (OMP_FOR_PRE_BODY (for_stmt)) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator si;
+ for (si = tsi_start (OMP_FOR_PRE_BODY (for_stmt)); !tsi_end_p (si);
+ tsi_next (&si))
+ {
+ t = tsi_stmt (si);
+ if (TREE_CODE (t) == DECL_EXPR
+ && TREE_CODE (DECL_EXPR_DECL (t)) == VAR_DECL)
+ bitmap_set_bit (has_decl_expr, DECL_UID (DECL_EXPR_DECL (t)));
+ }
+ }
+ }
gimplify_and_add (OMP_FOR_PRE_BODY (for_stmt), &for_pre_body);
OMP_FOR_PRE_BODY (for_stmt) = NULL_TREE;
@@ -6535,7 +6630,44 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
|| POINTER_TYPE_P (TREE_TYPE (decl)));
/* Make sure the iteration variable is private. */
- if (omp_is_private (gimplify_omp_ctxp, decl))
+ tree c = NULL_TREE;
+ if (simd)
+ {
+ splay_tree_node n = splay_tree_lookup (gimplify_omp_ctxp->variables,
+ (splay_tree_key)decl);
+ omp_is_private (gimplify_omp_ctxp, decl, simd);
+ if (n != NULL && (n->value & GOVD_DATA_SHARE_CLASS) != 0)
+ omp_notice_variable (gimplify_omp_ctxp, decl, true);
+ else if (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
+ {
+ c = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
+ OMP_CLAUSE_LINEAR_NO_COPYIN (c) = 1;
+ if (has_decl_expr
+ && bitmap_bit_p (has_decl_expr, DECL_UID (decl)))
+ OMP_CLAUSE_LINEAR_NO_COPYOUT (c) = 1;
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
+ OMP_FOR_CLAUSES (for_stmt) = c;
+ omp_add_variable (gimplify_omp_ctxp, decl,
+ GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
+ }
+ else
+ {
+ bool lastprivate
+ = (!has_decl_expr
+ || !bitmap_bit_p (has_decl_expr, DECL_UID (decl)));
+ c = build_omp_clause (input_location,
+ lastprivate ? OMP_CLAUSE_LASTPRIVATE
+ : OMP_CLAUSE_PRIVATE);
+ OMP_CLAUSE_DECL (c) = decl;
+ OMP_CLAUSE_CHAIN (c) = OMP_FOR_CLAUSES (for_stmt);
+ omp_add_variable (gimplify_omp_ctxp, decl,
+ (lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
+ | GOVD_SEEN);
+ c = NULL_TREE;
+ }
+ }
+ else if (omp_is_private (gimplify_omp_ctxp, decl, simd))
omp_notice_variable (gimplify_omp_ctxp, decl, true);
else
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
@@ -6577,6 +6709,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case PREINCREMENT_EXPR:
case POSTINCREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), 1);
+ if (c)
+ OMP_CLAUSE_LINEAR_STEP (c) = t;
t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
@@ -6585,6 +6719,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
case PREDECREMENT_EXPR:
case POSTDECREMENT_EXPR:
t = build_int_cst (TREE_TYPE (decl), -1);
+ if (c)
+ OMP_CLAUSE_LINEAR_STEP (c) = t;
t = build2 (PLUS_EXPR, TREE_TYPE (decl), var, t);
t = build2 (MODIFY_EXPR, TREE_TYPE (var), var, t);
TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i) = t;
@@ -6618,6 +6754,20 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
tret = gimplify_expr (&TREE_OPERAND (t, 1), &for_pre_body, NULL,
is_gimple_val, fb_rvalue);
ret = MIN (ret, tret);
+ if (c)
+ {
+ OMP_CLAUSE_LINEAR_STEP (c) = TREE_OPERAND (t, 1);
+ if (TREE_CODE (t) == MINUS_EXPR)
+ {
+ t = TREE_OPERAND (t, 1);
+ OMP_CLAUSE_LINEAR_STEP (c)
+ = fold_build1 (NEGATE_EXPR, TREE_TYPE (t), t);
+ tret = gimplify_expr (&OMP_CLAUSE_LINEAR_STEP (c),
+ &for_pre_body, NULL,
+ is_gimple_val, fb_rvalue);
+ ret = MIN (ret, tret);
+ }
+ }
break;
default:
@@ -6648,11 +6798,21 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
}
+ BITMAP_FREE (has_decl_expr);
+
gimplify_and_add (OMP_FOR_BODY (for_stmt), &for_body);
gimplify_adjust_omp_clauses (&OMP_FOR_CLAUSES (for_stmt));
- gfor = gimple_build_omp_for (for_body, OMP_FOR_CLAUSES (for_stmt),
+ int kind;
+ switch (TREE_CODE (for_stmt))
+ {
+ case OMP_FOR: kind = GF_OMP_FOR_KIND_FOR; break;
+ case OMP_SIMD: kind = GF_OMP_FOR_KIND_SIMD; break;
+ default:
+ gcc_unreachable ();
+ }
+ gfor = gimple_build_omp_for (for_body, kind, OMP_FOR_CLAUSES (for_stmt),
TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)),
for_pre_body);
@@ -6669,7 +6829,10 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
}
gimplify_seq_add_stmt (pre_p, gfor);
- return ret == GS_ALL_DONE ? GS_ALL_DONE : GS_ERROR;
+ if (ret != GS_ALL_DONE)
+ return GS_ERROR;
+ *expr_p = NULL_TREE;
+ return GS_ALL_DONE;
}
/* Gimplify the gross structure of other OpenMP worksharing constructs.
@@ -7587,6 +7750,7 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
break;
case OMP_FOR:
+ case OMP_SIMD:
ret = gimplify_omp_for (expr_p, pre_p);
break;
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index db9d4443ac9..c730ecaa183 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,19 @@
+2013-08-28 Ian Lance Taylor <iant@google.com>
+
+ * go-gcc.cc (Gcc_backend::immutable_struct): Set TREE_PUBLIC if
+ the struct is not hidden.
+ (Gcc_backend::immutable_struct_set_init): Don't set TREE_PUBLIC.
+
+2013-08-06 Ian Lance Taylor <iant@google.com>
+
+ * go-gcc.cc (Gcc_backend::immutable_struct_set_init): Use
+ compute_reloc_for_constant.
+
+2013-08-02 Ian Lance Taylor <iant@google.com>
+
+ * go-gcc.cc (immutable_struct_set_init): Always call
+ resolve_unique_section.
+
2013-07-24 Ian Lance Taylor <iant@google.com>
* go-gcc.cc (Gcc_backend::non_zero_size_type): If a struct has a
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 27c756e5496..025bb2bdca0 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -1475,8 +1475,8 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
// Create a named immutable initialized data structure.
Bvariable*
-Gcc_backend::immutable_struct(const std::string& name, bool, bool,
- Btype* btype, Location location)
+Gcc_backend::immutable_struct(const std::string& name, bool is_hidden,
+ bool, Btype* btype, Location location)
{
tree type_tree = btype->get_tree();
if (type_tree == error_mark_node)
@@ -1490,6 +1490,8 @@ Gcc_backend::immutable_struct(const std::string& name, bool, bool,
TREE_CONSTANT(decl) = 1;
TREE_USED(decl) = 1;
DECL_ARTIFICIAL(decl) = 1;
+ if (!is_hidden)
+ TREE_PUBLIC(decl) = 1;
// We don't call rest_of_decl_compilation until we have the
// initializer.
@@ -1503,8 +1505,7 @@ Gcc_backend::immutable_struct(const std::string& name, bool, bool,
void
Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
- bool is_hidden, bool is_common, Btype*,
- Location,
+ bool, bool is_common, Btype*, Location,
Bexpression* initializer)
{
tree decl = var->get_tree();
@@ -1515,16 +1516,14 @@ Gcc_backend::immutable_struct_set_init(Bvariable* var, const std::string&,
DECL_INITIAL(decl) = init_tree;
// We can't call make_decl_one_only until we set DECL_INITIAL.
- if (!is_common)
- {
- if (!is_hidden)
- TREE_PUBLIC(decl) = 1;
- }
- else
- {
- make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
- resolve_unique_section(decl, 1, 0);
- }
+ if (is_common)
+ make_decl_one_only(decl, DECL_ASSEMBLER_NAME(decl));
+
+ // These variables are often unneeded in the final program, so put
+ // them in their own section so that linker GC can discard them.
+ resolve_unique_section(decl,
+ compute_reloc_for_constant (init_tree),
+ 1);
rest_of_decl_compilation(decl, 1, 0);
}
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 2b60d90a5dc..0b010334229 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -1382,7 +1382,7 @@ Expression::make_func_reference(Named_object* function, Expression* closure,
Func_descriptor_expression::Func_descriptor_expression(Named_object* fn)
: Expression(EXPRESSION_FUNC_DESCRIPTOR, fn->location()),
- fn_(fn), dfn_(NULL), dvar_(NULL)
+ fn_(fn), dvar_(NULL)
{
go_assert(!fn->is_function() || !fn->func_value()->needs_closure());
}
@@ -1417,18 +1417,6 @@ Func_descriptor_expression::do_type()
return Func_descriptor_expression::descriptor_type;
}
-// Copy a Func_descriptor_expression;
-
-Expression*
-Func_descriptor_expression::do_copy()
-{
- Func_descriptor_expression* fde =
- Expression::make_func_descriptor(this->fn_);
- if (this->dfn_ != NULL)
- fde->set_descriptor_wrapper(this->dfn_);
- return fde;
-}
-
// The tree for a function descriptor.
tree
@@ -1455,11 +1443,8 @@ Func_descriptor_expression::do_get_tree(Translate_context* context)
Bvariable* bvar;
if (no->package() != NULL
|| Linemap::is_predeclared_location(no->location()))
- {
- bvar = context->backend()->immutable_struct_reference(var_name, btype,
- loc);
- go_assert(this->dfn_ == NULL);
- }
+ bvar = context->backend()->immutable_struct_reference(var_name, btype,
+ loc);
else
{
Location bloc = Linemap::predeclared_location();
@@ -1469,8 +1454,7 @@ Func_descriptor_expression::do_get_tree(Translate_context* context)
bvar = context->backend()->immutable_struct(var_name, is_hidden, false,
btype, bloc);
Expression_list* vals = new Expression_list();
- go_assert(this->dfn_ != NULL);
- vals->push_back(Expression::make_func_code_reference(this->dfn_, bloc));
+ vals->push_back(Expression::make_func_code_reference(this->fn_, bloc));
Expression* init =
Expression::make_struct_composite_literal(this->type(), vals, bloc);
Translate_context bcontext(gogo, NULL, NULL, NULL);
@@ -6792,8 +6776,8 @@ Bound_method_expression::create_thunk(Gogo* gogo, const Method* method,
}
Struct_field_list* sfl = new Struct_field_list();
- // The type here is wrong--it should be new_fntype. But we don't
- // have new_fntype yet, and it doesn't really matter.
+ // The type here is wrong--it should be the C function type. But it
+ // doesn't really matter.
Type* vt = Type::make_pointer_type(Type::make_void_type());
sfl->push_back(Struct_field(Typed_identifier("fn.0", vt, loc)));
sfl->push_back(Struct_field(Typed_identifier("val.1",
@@ -6802,17 +6786,17 @@ Bound_method_expression::create_thunk(Gogo* gogo, const Method* method,
Type* closure_type = Type::make_struct_type(sfl, loc);
closure_type = Type::make_pointer_type(closure_type);
- Function_type* new_fntype = orig_fntype->copy_with_closure(closure_type);
+ Function_type* new_fntype = orig_fntype->copy_with_names();
Named_object* new_no = gogo->start_function(Gogo::thunk_name(), new_fntype,
false, loc);
- gogo->start_block(loc);
+ Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
+ cvar->set_is_used();
+ Named_object* cp = Named_object::make_variable("$closure", NULL, cvar);
+ new_no->func_value()->set_closure_var(cp);
- Named_object* cp = gogo->lookup("closure.0", NULL);
- go_assert(cp != NULL
- && cp->is_variable()
- && cp->var_value()->is_parameter());
+ gogo->start_block(loc);
// Field 0 of the closure is the function code pointer, field 1 is
// the value on which to invoke the method.
@@ -6831,7 +6815,7 @@ Bound_method_expression::create_thunk(Gogo* gogo, const Method* method,
const Typed_identifier_list* new_params = new_fntype->parameters();
args = new Expression_list();
for (Typed_identifier_list::const_iterator p = new_params->begin();
- p + 1 != new_params->end();
+ p != new_params->end();
++p)
{
Named_object* p_no = gogo->lookup(p->name(), NULL);
@@ -9154,35 +9138,27 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function,
// Because do_type will return an error type and thus prevent future
// errors, check for that case now to ensure that the error gets
// reported.
- if (this->get_function_type() == NULL)
+ Function_type* fntype = this->get_function_type();
+ if (fntype == NULL)
{
if (!this->fn_->type()->is_error())
this->report_error(_("expected function"));
return Expression::make_error(loc);
}
- // Recognize a call to a builtin function.
- Func_expression* fne = this->fn_->func_expression();
- if (fne != NULL
- && fne->named_object()->is_function_declaration()
- && fne->named_object()->func_declaration_value()->type()->is_builtin())
- return new Builtin_call_expression(gogo, this->fn_, this->args_,
- this->is_varargs_, loc);
-
// Handle an argument which is a call to a function which returns
// multiple results.
if (this->args_ != NULL
&& this->args_->size() == 1
- && this->args_->front()->call_expression() != NULL
- && this->fn_->type()->function_type() != NULL)
+ && this->args_->front()->call_expression() != NULL)
{
- Function_type* fntype = this->fn_->type()->function_type();
size_t rc = this->args_->front()->call_expression()->result_count();
if (rc > 1
- && fntype->parameters() != NULL
- && (fntype->parameters()->size() == rc
- || (fntype->is_varargs()
- && fntype->parameters()->size() - 1 <= rc)))
+ && ((fntype->parameters() != NULL
+ && (fntype->parameters()->size() == rc
+ || (fntype->is_varargs()
+ && fntype->parameters()->size() - 1 <= rc)))
+ || fntype->is_builtin()))
{
Call_expression* call = this->args_->front()->call_expression();
Expression_list* args = new Expression_list;
@@ -9196,6 +9172,11 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function,
}
}
+ // Recognize a call to a builtin function.
+ if (fntype->is_builtin())
+ return new Builtin_call_expression(gogo, this->fn_, this->args_,
+ this->is_varargs_, loc);
+
// If this call returns multiple results, create a temporary
// variable for each result.
size_t rc = this->result_count();
@@ -9204,8 +9185,7 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function,
std::vector<Temporary_statement*>* temps =
new std::vector<Temporary_statement*>;
temps->reserve(rc);
- const Typed_identifier_list* results =
- this->fn_->type()->function_type()->results();
+ const Typed_identifier_list* results = fntype->results();
for (Typed_identifier_list::const_iterator p = results->begin();
p != results->end();
++p)
@@ -9220,10 +9200,8 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function,
// Handle a call to a varargs function by packaging up the extra
// parameters.
- if (this->fn_->type()->function_type() != NULL
- && this->fn_->type()->function_type()->is_varargs())
+ if (fntype->is_varargs())
{
- Function_type* fntype = this->fn_->type()->function_type();
const Typed_identifier_list* parameters = fntype->parameters();
go_assert(parameters != NULL && !parameters->empty());
Type* varargs_type = parameters->back().type();
@@ -9729,21 +9707,21 @@ Call_expression::do_get_tree(Translate_context* context)
const bool has_closure = func != NULL && func->closure() != NULL;
const bool is_interface_method = interface_method != NULL;
- int closure_arg;
+ bool has_closure_arg;
if (has_closure)
- closure_arg = 1;
+ has_closure_arg = true;
else if (func != NULL)
- closure_arg = 0;
+ has_closure_arg = false;
else if (is_interface_method)
- closure_arg = 0;
+ has_closure_arg = false;
else
- closure_arg = 1;
+ has_closure_arg = true;
int nargs;
tree* args;
if (this->args_ == NULL || this->args_->empty())
{
- nargs = (is_interface_method ? 1 : 0) + closure_arg;
+ nargs = is_interface_method ? 1 : 0;
args = nargs == 0 ? NULL : new tree[nargs];
}
else if (fntype->parameters() == NULL || fntype->parameters()->empty())
@@ -9752,7 +9730,7 @@ Call_expression::do_get_tree(Translate_context* context)
go_assert(!is_interface_method
&& fntype->is_method()
&& this->args_->size() == 1);
- nargs = 1 + closure_arg;
+ nargs = 1;
args = new tree[nargs];
args[0] = this->args_->front()->get_tree(context);
}
@@ -9763,7 +9741,6 @@ Call_expression::do_get_tree(Translate_context* context)
nargs = this->args_->size();
int i = is_interface_method ? 1 : 0;
nargs += i;
- nargs += closure_arg;
args = new tree[nargs];
Typed_identifier_list::const_iterator pp = params->begin();
@@ -9787,7 +9764,7 @@ Call_expression::do_get_tree(Translate_context* context)
return error_mark_node;
}
go_assert(pp == params->end());
- go_assert(i + closure_arg == nargs);
+ go_assert(i == nargs);
}
tree fntype_tree = type_to_tree(fntype->get_backend(gogo));
@@ -9806,21 +9783,23 @@ Call_expression::do_get_tree(Translate_context* context)
return error_mark_node;
tree fn;
+ tree closure_tree;
if (func != NULL)
{
Named_object* no = func->named_object();
- go_assert(!no->is_function()
- || !no->func_value()->is_descriptor_wrapper());
fn = Func_expression::get_code_pointer(gogo, no, location);
- if (has_closure)
+ if (!has_closure)
+ closure_tree = NULL_TREE;
+ else
{
- go_assert(closure_arg == 1 && nargs > 0);
- args[nargs - 1] = func->closure()->get_tree(context);
+ closure_tree = func->closure()->get_tree(context);
+ if (closure_tree == error_mark_node)
+ return error_mark_node;
}
}
else if (!is_interface_method)
{
- tree closure_tree = this->fn_->get_tree(context);
+ closure_tree = this->fn_->get_tree(context);
if (closure_tree == error_mark_node)
return error_mark_node;
tree fnc = fold_convert_loc(location.gcc_location(), fntype_tree,
@@ -9834,8 +9813,6 @@ Call_expression::do_get_tree(Translate_context* context)
build_fold_indirect_ref_loc(location.gcc_location(),
fnc),
field, NULL_TREE);
- go_assert(closure_arg == 1 && nargs > 0);
- args[nargs - 1] = closure_tree;
}
else
{
@@ -9843,7 +9820,7 @@ Call_expression::do_get_tree(Translate_context* context)
&args[0]);
if (fn == error_mark_node)
return error_mark_node;
- go_assert(closure_arg == 0);
+ closure_tree = NULL_TREE;
}
if (fn == error_mark_node || TREE_TYPE(fn) == error_mark_node)
@@ -9894,6 +9871,32 @@ Call_expression::do_get_tree(Translate_context* context)
if (func == NULL)
fn = save_expr(fn);
+ if (!has_closure_arg)
+ go_assert(closure_tree == NULL_TREE);
+ else
+ {
+ // Pass the closure argument by calling the function function
+ // __go_set_closure. In the order_evaluations pass we have
+ // ensured that if any parameters contain call expressions, they
+ // will have been moved out to temporary variables.
+
+ go_assert(closure_tree != NULL_TREE);
+ closure_tree = fold_convert_loc(location.gcc_location(), ptr_type_node,
+ closure_tree);
+ static tree set_closure_fndecl;
+ tree set_closure = Gogo::call_builtin(&set_closure_fndecl,
+ location,
+ "__go_set_closure",
+ 1,
+ void_type_node,
+ ptr_type_node,
+ closure_tree);
+ if (set_closure == error_mark_node)
+ return error_mark_node;
+ fn = build2_loc(location.gcc_location(), COMPOUND_EXPR,
+ TREE_TYPE(fn), set_closure, fn);
+ }
+
tree ret = build_call_array(excess_type != NULL_TREE ? excess_type : rettype,
fn, nargs, args);
delete[] args;
@@ -11609,25 +11612,25 @@ Interface_field_reference_expression::create_thunk(Gogo* gogo,
return Named_object::make_erroneous_name(Gogo::thunk_name());
Struct_field_list* sfl = new Struct_field_list();
- // The type here is wrong--it should be new_fntype. But we don't
- // have new_fntype yet, and it doesn't really matter.
+ // The type here is wrong--it should be the C function type. But it
+ // doesn't really matter.
Type* vt = Type::make_pointer_type(Type::make_void_type());
sfl->push_back(Struct_field(Typed_identifier("fn.0", vt, loc)));
sfl->push_back(Struct_field(Typed_identifier("val.1", type, loc)));
Type* closure_type = Type::make_struct_type(sfl, loc);
closure_type = Type::make_pointer_type(closure_type);
- Function_type* new_fntype = orig_fntype->copy_with_closure(closure_type);
+ Function_type* new_fntype = orig_fntype->copy_with_names();
Named_object* new_no = gogo->start_function(Gogo::thunk_name(), new_fntype,
false, loc);
- gogo->start_block(loc);
+ Variable* cvar = new Variable(closure_type, NULL, false, false, false, loc);
+ cvar->set_is_used();
+ Named_object* cp = Named_object::make_variable("$closure", NULL, cvar);
+ new_no->func_value()->set_closure_var(cp);
- Named_object* cp = gogo->lookup("closure.0", NULL);
- go_assert(cp != NULL
- && cp->is_variable()
- && cp->var_value()->is_parameter());
+ gogo->start_block(loc);
// Field 0 of the closure is the function code pointer, field 1 is
// the value on which to invoke the method.
@@ -11647,7 +11650,7 @@ Interface_field_reference_expression::create_thunk(Gogo* gogo,
const Typed_identifier_list* new_params = new_fntype->parameters();
args = new Expression_list();
for (Typed_identifier_list::const_iterator p = new_params->begin();
- p + 1 != new_params->end();
+ p != new_params->end();
++p)
{
Named_object* p_no = gogo->lookup(p->name(), NULL);
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 67a4bb985e6..95584f2748b 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -1570,14 +1570,6 @@ class Func_descriptor_expression : public Expression
public:
Func_descriptor_expression(Named_object* fn);
- // Set the descriptor wrapper.
- void
- set_descriptor_wrapper(Named_object* dfn)
- {
- go_assert(this->dfn_ == NULL);
- this->dfn_ = dfn;
- }
-
// Make the function descriptor type, so that it can be converted.
static void
make_func_descriptor_type();
@@ -1594,7 +1586,8 @@ class Func_descriptor_expression : public Expression
{ }
Expression*
- do_copy();
+ do_copy()
+ { return Expression::make_func_descriptor(this->fn_); }
bool
do_is_addressable() const
@@ -1612,8 +1605,6 @@ class Func_descriptor_expression : public Expression
// The function for which this is the descriptor.
Named_object* fn_;
- // The descriptor function.
- Named_object* dfn_;
// The descriptor variable.
Bvariable* dvar_;
};
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index a1fe5fec7ca..69797f93342 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -1289,30 +1289,6 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
functype = TREE_TYPE(TYPE_FIELDS(TREE_TYPE(functype)));
go_assert(FUNCTION_POINTER_TYPE_P(functype));
functype = TREE_TYPE(functype);
-
- // In the struct, the function type always has a trailing
- // closure argument. For the function body, we only use
- // that trailing arg if this is a function literal or if it
- // is a wrapper created to store in a descriptor. Remove it
- // in that case.
- if (this->enclosing_ == NULL && !this->is_descriptor_wrapper_)
- {
- tree old_params = TYPE_ARG_TYPES(functype);
- go_assert(old_params != NULL_TREE
- && old_params != void_list_node);
- tree new_params = NULL_TREE;
- tree *pp = &new_params;
- while (TREE_CHAIN (old_params) != void_list_node)
- {
- tree p = TREE_VALUE(old_params);
- go_assert(TYPE_P(p));
- *pp = tree_cons(NULL_TREE, p, NULL_TREE);
- pp = &TREE_CHAIN(*pp);
- old_params = TREE_CHAIN (old_params);
- }
- *pp = void_list_node;
- functype = build_function_type(TREE_TYPE(functype), new_params);
- }
}
if (functype == error_mark_node)
@@ -1423,26 +1399,6 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no, tree id)
functype = TREE_TYPE(TYPE_FIELDS(TREE_TYPE(functype)));
go_assert(FUNCTION_POINTER_TYPE_P(functype));
functype = TREE_TYPE(functype);
-
- // In the struct, the function type always has a trailing
- // closure argument. Here we are referring to the function
- // code directly, and we know it is not a function literal,
- // and we know it is not a wrapper created to store in a
- // descriptor. Remove that trailing argument.
- tree old_params = TYPE_ARG_TYPES(functype);
- go_assert(old_params != NULL_TREE && old_params != void_list_node);
- tree new_params = NULL_TREE;
- tree *pp = &new_params;
- while (TREE_CHAIN (old_params) != void_list_node)
- {
- tree p = TREE_VALUE(old_params);
- go_assert(TYPE_P(p));
- *pp = tree_cons(NULL_TREE, p, NULL_TREE);
- pp = &TREE_CHAIN(*pp);
- old_params = TREE_CHAIN (old_params);
- }
- *pp = void_list_node;
- functype = build_function_type(TREE_TYPE(functype), new_params);
}
tree decl;
@@ -1659,8 +1615,13 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
}
}
- // The closure variable is passed last, if this is a function
- // literal or a descriptor wrapper.
+ *pp = NULL_TREE;
+
+ DECL_ARGUMENTS(fndecl) = params;
+
+ // If we need a closure variable, fetch it by calling a runtime
+ // function. The caller will have called __go_set_closure before
+ // the function call.
if (this->closure_var_ != NULL)
{
Bvariable* bvar =
@@ -1668,25 +1629,25 @@ Function::build_tree(Gogo* gogo, Named_object* named_function)
tree var_decl = var_to_tree(bvar);
if (var_decl != error_mark_node)
{
- go_assert(TREE_CODE(var_decl) == PARM_DECL);
- *pp = var_decl;
- pp = &DECL_CHAIN(*pp);
+ go_assert(TREE_CODE(var_decl) == VAR_DECL);
+ static tree get_closure_fndecl;
+ tree get_closure = Gogo::call_builtin(&get_closure_fndecl,
+ this->location_,
+ "__go_get_closure",
+ 0,
+ ptr_type_node);
+
+ // Mark the __go_get_closure function as pure, since it
+ // depends only on the global variable g.
+ DECL_PURE_P(get_closure_fndecl) = 1;
+
+ get_closure = fold_convert_loc(this->location_.gcc_location(),
+ TREE_TYPE(var_decl), get_closure);
+ DECL_INITIAL(var_decl) = get_closure;
+ DECL_CHAIN(var_decl) = declare_vars;
+ declare_vars = var_decl;
}
}
- else if (this->enclosing_ != NULL || this->is_descriptor_wrapper_)
- {
- tree parm_decl = build_decl(this->location_.gcc_location(), PARM_DECL,
- get_identifier("$closure"),
- const_ptr_type_node);
- DECL_CONTEXT(parm_decl) = current_function_decl;
- DECL_ARG_TYPE(parm_decl) = const_ptr_type_node;
- *pp = parm_decl;
- pp = &DECL_CHAIN(*pp);
- }
-
- *pp = NULL_TREE;
-
- DECL_ARGUMENTS(fndecl) = params;
if (this->block_ != NULL)
{
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index 6ae72b6a1c9..be8ec5939f3 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -1770,8 +1770,8 @@ Create_function_descriptors::function(Named_object* no)
if (no->is_function()
&& no->func_value()->enclosing() == NULL
&& !no->func_value()->is_method()
- && !no->func_value()->is_descriptor_wrapper()
- && !Gogo::is_hidden_name(no->name()))
+ && !Gogo::is_hidden_name(no->name())
+ && !Gogo::is_thunk(no))
no->func_value()->descriptor(this->gogo_, no);
return TRAVERSE_CONTINUE;
@@ -2541,13 +2541,38 @@ Order_eval::statement(Block* block, size_t* pindex, Statement* s)
return TRAVERSE_CONTINUE;
// If there is only one expression with a side-effect, we can
- // usually leave it in place. However, for an assignment statement,
- // we need to evaluate an expression on the right hand side before
- // we evaluate any index expression on the left hand side, so for
- // that case we always move the expression. Otherwise we mishandle
- // m[0] = len(m) where m is a map.
- if (c == 1 && s->classification() != Statement::STATEMENT_ASSIGNMENT)
- return TRAVERSE_CONTINUE;
+ // usually leave it in place.
+ if (c == 1)
+ {
+ switch (s->classification())
+ {
+ case Statement::STATEMENT_ASSIGNMENT:
+ // For an assignment statement, we need to evaluate an
+ // expression on the right hand side before we evaluate any
+ // index expression on the left hand side, so for that case
+ // we always move the expression. Otherwise we mishandle
+ // m[0] = len(m) where m is a map.
+ break;
+
+ case Statement::STATEMENT_EXPRESSION:
+ {
+ // If this is a call statement that doesn't return any
+ // values, it will not have been counted as a value to
+ // move. We need to move any subexpressions in case they
+ // are themselves call statements that require passing a
+ // closure.
+ Expression* expr = s->expression_statement()->expr();
+ if (expr->call_expression() != NULL
+ && expr->call_expression()->result_count() == 0)
+ break;
+ return TRAVERSE_CONTINUE;
+ }
+
+ default:
+ // We can leave the expression in place.
+ return TRAVERSE_CONTINUE;
+ }
+ }
bool is_thunk = s->thunk_statement() != NULL;
for (Find_eval_ordering::const_iterator p = find_eval_ordering.begin();
@@ -2803,7 +2828,7 @@ Build_recover_thunks::function(Named_object* orig_no)
Named_object* orig_closure_no = orig_func->closure_var();
Variable* orig_closure_var = orig_closure_no->var_value();
Variable* new_var = new Variable(orig_closure_var->type(), NULL, false,
- true, false, location);
+ false, false, location);
snprintf(buf, sizeof buf, "closure.%u", count);
++count;
Named_object* new_closure_no = Named_object::make_variable(buf, NULL,
@@ -3133,7 +3158,8 @@ Check_return_statements_traverse::function(Named_object* no)
return TRAVERSE_CONTINUE;
if (func->block()->may_fall_through())
- error_at(func->location(), "control reaches end of non-void function");
+ error_at(func->block()->end_location(),
+ "missing return at end of function");
return TRAVERSE_CONTINUE;
}
@@ -3274,7 +3300,7 @@ Function::Function(Function_type* type, Function* enclosing, Block* block,
local_type_count_(0), descriptor_(NULL), fndecl_(NULL), defer_stack_(NULL),
is_sink_(false), results_are_named_(false), nointerface_(false),
calls_recover_(false), is_recover_thunk_(false), has_recover_thunk_(false),
- in_unique_section_(false), is_descriptor_wrapper_(false)
+ in_unique_section_(false)
{
}
@@ -3356,9 +3382,9 @@ Function::closure_var()
Struct_field_list* sfl = new Struct_field_list;
Type* struct_type = Type::make_struct_type(sfl, loc);
Variable* var = new Variable(Type::make_pointer_type(struct_type),
- NULL, false, true, false, loc);
+ NULL, false, false, false, loc);
var->set_is_used();
- this->closure_var_ = Named_object::make_variable("closure", NULL, var);
+ this->closure_var_ = Named_object::make_variable("$closure", NULL, var);
// Note that the new variable is not in any binding contour.
}
return this->closure_var_;
@@ -3561,93 +3587,16 @@ Function::determine_types()
this->block_->determine_types();
}
-// Build a wrapper function for a function descriptor. A function
-// descriptor refers to a function that takes a closure as its last
-// argument. In this case there will be no closure, but an indirect
-// call will pass nil as the last argument. We need to build a
-// wrapper function that accepts and discards that last argument, so
-// that cases like -mrtd will work correctly. In most cases the
-// wrapper function will simply be a jump.
-
-Named_object*
-Function::make_descriptor_wrapper(Gogo* gogo, Named_object* no,
- Function_type* orig_fntype)
-{
- Location loc = no->location();
-
- Type* vt = Type::make_pointer_type(Type::make_void_type());
- Function_type* new_fntype = orig_fntype->copy_with_closure(vt);
-
- std::string name = no->name() + "$descriptorfn";
- Named_object* dno = gogo->start_function(name, new_fntype, false, loc);
- dno->func_value()->is_descriptor_wrapper_ = true;
-
- gogo->start_block(loc);
-
- Expression* fn = Expression::make_func_reference(no, NULL, loc);
-
- // Call the function begin wrapped, passing all of the arguments
- // except for the last one (the last argument is the ignored
- // closure).
- const Typed_identifier_list* orig_params = orig_fntype->parameters();
- Expression_list* args;
- if (orig_params == NULL || orig_params->empty())
- args = NULL;
- else
- {
- const Typed_identifier_list* new_params = new_fntype->parameters();
- args = new Expression_list();
- for (Typed_identifier_list::const_iterator p = new_params->begin();
- p + 1 != new_params->end();
- ++p)
- {
- Named_object* p_no = gogo->lookup(p->name(), NULL);
- go_assert(p_no != NULL
- && p_no->is_variable()
- && p_no->var_value()->is_parameter());
- args->push_back(Expression::make_var_reference(p_no, loc));
- }
- }
-
- Call_expression* call = Expression::make_call(fn, args,
- orig_fntype->is_varargs(),
- loc);
- call->set_varargs_are_lowered();
-
- Statement* s = Statement::make_return_from_call(call, loc);
- gogo->add_statement(s);
- Block* b = gogo->finish_block(loc);
- gogo->add_block(b, loc);
- gogo->lower_block(dno, b);
- gogo->finish_function(loc);
-
- return dno;
-}
-
// Return the function descriptor, the value you get when you refer to
// the function in Go code without calling it.
Expression*
-Function::descriptor(Gogo* gogo, Named_object* no)
+Function::descriptor(Gogo*, Named_object* no)
{
go_assert(!this->is_method());
go_assert(this->closure_var_ == NULL);
- go_assert(!this->is_descriptor_wrapper_);
if (this->descriptor_ == NULL)
- {
- // Make and record the descriptor first, so that when we lower
- // the descriptor wrapper we don't try to make it again.
- Func_descriptor_expression* descriptor =
- Expression::make_func_descriptor(no);
- this->descriptor_ = descriptor;
- if (no->package() == NULL
- && !Linemap::is_predeclared_location(no->location()))
- {
- Named_object* dno = Function::make_descriptor_wrapper(gogo, no,
- this->type_);
- descriptor->set_descriptor_wrapper(dno);
- }
- }
+ this->descriptor_ = Expression::make_func_descriptor(no);
return this->descriptor_;
}
@@ -4186,24 +4135,11 @@ Bindings_snapshot::check_goto_defs(Location loc, const Block* block,
// Return the function descriptor.
Expression*
-Function_declaration::descriptor(Gogo* gogo, Named_object* no)
+Function_declaration::descriptor(Gogo*, Named_object* no)
{
go_assert(!this->fntype_->is_method());
if (this->descriptor_ == NULL)
- {
- // Make and record the descriptor first, so that when we lower
- // the descriptor wrapper we don't try to make it again.
- Func_descriptor_expression* descriptor =
- Expression::make_func_descriptor(no);
- this->descriptor_ = descriptor;
- if (no->package() == NULL
- && !Linemap::is_predeclared_location(no->location()))
- {
- Named_object* dno = Function::make_descriptor_wrapper(gogo, no,
- this->fntype_);
- descriptor->set_descriptor_wrapper(dno);
- }
- }
+ this->descriptor_ = Expression::make_func_descriptor(no);
return this->descriptor_;
}
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index b6e9e45a1cb..6a87f2d562c 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -1050,12 +1050,6 @@ class Function
set_in_unique_section()
{ this->in_unique_section_ = true; }
- // Whether this function was created as a descriptor wrapper for
- // another function.
- bool
- is_descriptor_wrapper() const
- { return this->is_descriptor_wrapper_; }
-
// Swap with another function. Used only for the thunk which calls
// recover.
void
@@ -1085,10 +1079,6 @@ class Function
this->descriptor_ = descriptor;
}
- // Build a descriptor wrapper function.
- static Named_object*
- make_descriptor_wrapper(Gogo*, Named_object*, Function_type*);
-
// Return the function's decl given an identifier.
tree
get_or_make_decl(Gogo*, Named_object*, tree id);
@@ -1190,9 +1180,6 @@ class Function
// True if this function should be put in a unique section. This is
// turned on for field tracking.
bool in_unique_section_ : 1;
- // True if this is a function wrapper created to put in a function
- // descriptor.
- bool is_descriptor_wrapper_ : 1;
};
// A snapshot of the current binding state.
diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc
index 429d91bafe2..9d112850fee 100644
--- a/gcc/go/gofrontend/parse.cc
+++ b/gcc/go/gofrontend/parse.cc
@@ -5266,7 +5266,8 @@ Parse::range_clause_decl(const Typed_identifier_list* til,
no->var_value()->set_type_from_range_value();
if (is_new)
any_new = true;
- p_range_clause->value = Expression::make_var_reference(no, location);
+ if (!Gogo::is_sink_name(pti->name()))
+ p_range_clause->value = Expression::make_var_reference(no, location);
}
if (!any_new)
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index ca1ad07af6c..0261f9d4882 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -1658,46 +1658,23 @@ Statement::make_tuple_type_guard_assignment(Expression* val, Expression* ok,
location);
}
-// An expression statement.
+// Class Expression_statement.
-class Expression_statement : public Statement
-{
- public:
- Expression_statement(Expression* expr, bool is_ignored)
- : Statement(STATEMENT_EXPRESSION, expr->location()),
- expr_(expr), is_ignored_(is_ignored)
- { }
-
- Expression*
- expr()
- { return this->expr_; }
-
- protected:
- int
- do_traverse(Traverse* traverse)
- { return this->traverse_expression(traverse, &this->expr_); }
-
- void
- do_determine_types()
- { this->expr_->determine_type_no_context(); }
-
- void
- do_check_types(Gogo*);
-
- bool
- do_may_fall_through() const;
+// Constructor.
- Bstatement*
- do_get_backend(Translate_context* context);
+Expression_statement::Expression_statement(Expression* expr, bool is_ignored)
+ : Statement(STATEMENT_EXPRESSION, expr->location()),
+ expr_(expr), is_ignored_(is_ignored)
+{
+}
- void
- do_dump_statement(Ast_dump_context*) const;
+// Determine types.
- private:
- Expression* expr_;
- // Whether the value of this expression is being explicitly ignored.
- bool is_ignored_;
-};
+void
+Expression_statement::do_determine_types()
+{
+ this->expr_->determine_type_no_context();
+}
// Check the types of an expression statement. The only check we do
// is to possibly give an error about discarding the value of the
@@ -4093,6 +4070,16 @@ Type_case_clauses::Type_case_clause::lower(Type* switch_val_type,
bool
Type_case_clauses::Type_case_clause::may_fall_through() const
{
+ if (this->is_fallthrough_)
+ {
+ // This case means that we automatically fall through to the
+ // next case (it's used for T1 in case T1, T2:). It does not
+ // mean that we fall through to the end of the type switch as a
+ // whole. There is sure to be a next case and that next case
+ // will determine whether we fall through to the statements
+ // after the type switch.
+ return false;
+ }
if (this->statements_ == NULL)
return true;
return this->statements_->may_fall_through();
diff --git a/gcc/go/gofrontend/statements.h b/gcc/go/gofrontend/statements.h
index fb2ae334293..b128fa0a8eb 100644
--- a/gcc/go/gofrontend/statements.h
+++ b/gcc/go/gofrontend/statements.h
@@ -17,6 +17,7 @@ class Function;
class Unnamed_label;
class Temporary_statement;
class Variable_declaration_statement;
+class Expression_statement;
class Return_statement;
class Thunk_statement;
class Label_statement;
@@ -329,6 +330,14 @@ class Statement
STATEMENT_VARIABLE_DECLARATION>();
}
+ // If this is an expression statement, return it. Otherwise return
+ // NULL.
+ Expression_statement*
+ expression_statement()
+ {
+ return this->convert<Expression_statement, STATEMENT_EXPRESSION>();
+ }
+
// If this is a return statement, return it. Otherwise return NULL.
Return_statement*
return_statement()
@@ -636,6 +645,43 @@ class Return_statement : public Statement
bool is_lowered_;
};
+// An expression statement.
+
+class Expression_statement : public Statement
+{
+ public:
+ Expression_statement(Expression* expr, bool is_ignored);
+
+ Expression*
+ expr()
+ { return this->expr_; }
+
+ protected:
+ int
+ do_traverse(Traverse* traverse)
+ { return this->traverse_expression(traverse, &this->expr_); }
+
+ void
+ do_determine_types();
+
+ void
+ do_check_types(Gogo*);
+
+ bool
+ do_may_fall_through() const;
+
+ Bstatement*
+ do_get_backend(Translate_context* context);
+
+ void
+ do_dump_statement(Ast_dump_context*) const;
+
+ private:
+ Expression* expr_;
+ // Whether the value of this expression is being explicitly ignored.
+ bool is_ignored_;
+};
+
// A send statement.
class Send_statement : public Statement
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index 0a86d472062..9ce329d5503 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -3390,10 +3390,7 @@ Function_type::do_get_backend(Gogo* gogo)
// When we do anything with a function value other than call it, it
// is represented as a pointer to a struct whose first field is the
// actual function. So that is what we return as the type of a Go
- // function. The function stored in the first field always that
- // takes one additional trailing argument: the closure pointer. For
- // a top-level function, this additional argument will only be
- // passed when invoking the function indirectly, via the struct.
+ // function.
Location loc = this->location();
Btype* struct_type =
@@ -3415,15 +3412,9 @@ Function_type::do_get_backend(Gogo* gogo)
}
std::vector<Backend::Btyped_identifier> bparameters;
- size_t last;
- if (this->parameters_ == NULL)
- {
- bparameters.resize(1);
- last = 0;
- }
- else
+ if (this->parameters_ != NULL)
{
- bparameters.resize(this->parameters_->size() + 1);
+ bparameters.resize(this->parameters_->size());
size_t i = 0;
for (Typed_identifier_list::const_iterator p = this->parameters_->begin();
p != this->parameters_->end();
@@ -3433,12 +3424,8 @@ Function_type::do_get_backend(Gogo* gogo)
bparameters[i].btype = p->type()->get_backend(gogo);
bparameters[i].location = p->location();
}
- last = i;
+ go_assert(i == bparameters.size());
}
- go_assert(last + 1 == bparameters.size());
- bparameters[last].name = "$closure";
- bparameters[last].btype = ptr_struct_type;
- bparameters[last].location = loc;
std::vector<Backend::Btyped_identifier> bresults;
if (this->results_ != NULL)
@@ -3840,7 +3827,7 @@ Function_type::copy_with_receiver(Type* receiver_type) const
// closure parameter.
Function_type*
-Function_type::copy_with_closure(Type* closure_type) const
+Function_type::copy_with_names() const
{
Typed_identifier_list* new_params = new Typed_identifier_list();
const Typed_identifier_list* orig_params = this->parameters_;
@@ -3858,8 +3845,6 @@ Function_type::copy_with_closure(Type* closure_type) const
p->location()));
}
}
- new_params->push_back(Typed_identifier("closure.0", closure_type,
- this->location_));
const Typed_identifier_list* orig_results = this->results_;
Typed_identifier_list* new_results;
@@ -4221,6 +4206,22 @@ Struct_field::is_field_name(const std::string& name) const
}
}
+// Return whether this field is an embedded built-in type.
+
+bool
+Struct_field::is_embedded_builtin(Gogo* gogo) const
+{
+ const std::string& name(this->field_name());
+ // We know that a field is an embedded type if it is anonymous.
+ // We can decide if it is a built-in type by checking to see if it is
+ // registered globally under the field's name.
+ // This allows us to distinguish between embedded built-in types and
+ // embedded types that are aliases to built-in types.
+ return (this->is_anonymous()
+ && !Gogo::is_hidden_name(name)
+ && gogo->lookup_global(name.c_str()) != NULL);
+}
+
// Class Struct_type.
// A hash table used to find identical unnamed structs so that they
@@ -4835,11 +4836,16 @@ Struct_type::do_type_descriptor(Gogo* gogo, Named_type* name)
++q;
go_assert(q->is_field_name("pkgPath"));
- if (!Gogo::is_hidden_name(pf->field_name()))
- fvals->push_back(Expression::make_nil(bloc));
+ bool is_embedded_builtin = pf->is_embedded_builtin(gogo);
+ if (!Gogo::is_hidden_name(pf->field_name()) && !is_embedded_builtin)
+ fvals->push_back(Expression::make_nil(bloc));
else
{
- std::string n = Gogo::hidden_name_pkgpath(pf->field_name());
+ std::string n;
+ if (is_embedded_builtin)
+ n = gogo->package_name();
+ else
+ n = Gogo::hidden_name_pkgpath(pf->field_name());
Expression* s = Expression::make_string(n, bloc);
fvals->push_back(Expression::make_unary(OPERATOR_AND, s, bloc));
}
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 56626f1960e..d207fe5a375 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -1789,11 +1789,11 @@ class Function_type : public Type
Function_type*
copy_with_receiver(Type*) const;
- // Return a copy of this type ignoring any receiver and adding a
- // final closure parameter of type CLOSURE_TYPE. This is used when
- // creating descriptors.
+ // Return a copy of this type ignoring any receiver and using dummy
+ // names for all parameters. This is used for thunks for method
+ // values.
Function_type*
- copy_with_closure(Type* closure_type) const;
+ copy_with_names() const;
static Type*
make_function_type_descriptor_type();
@@ -1926,6 +1926,10 @@ class Struct_field
bool
is_field_name(const std::string& name) const;
+ // Return whether this struct field is an embedded built-in type.
+ bool
+ is_embedded_builtin(Gogo*) const;
+
// The field type.
Type*
type() const
diff --git a/gcc/graph.c b/gcc/graph.c
index 97930d0fabe..0ec279d86a9 100644
--- a/gcc/graph.c
+++ b/gcc/graph.c
@@ -56,26 +56,6 @@ open_graph_file (const char *base, const char *mode)
return fp;
}
-/* Return a pretty-print buffer for output to file FP. */
-
-static pretty_printer *
-init_graph_slim_pretty_print (FILE *fp)
-{
- static bool initialized = false;
- static pretty_printer graph_slim_pp;
-
- if (! initialized)
- {
- pp_construct (&graph_slim_pp, /*prefix=*/NULL, /*linewidth=*/0);
- initialized = true;
- }
- else
- gcc_assert (! pp_last_position_in_text (&graph_slim_pp));
-
- graph_slim_pp.buffer->stream = fp;
- return &graph_slim_pp;
-}
-
/* Draw a basic block BB belonging to the function with FUNCDEF_NO
as its unique number. */
static void
@@ -109,10 +89,10 @@ draw_cfg_node (pretty_printer *pp, int funcdef_no, basic_block bb)
pp_string (pp, "EXIT");
else
{
- pp_character (pp, '{');
+ pp_left_brace (pp);
pp_write_text_to_stream (pp);
dump_bb_for_graph (pp, bb);
- pp_character (pp, '}');
+ pp_right_brace (pp);
}
pp_string (pp, "\"];\n\n");
@@ -297,7 +277,9 @@ print_graph_cfg (const char *base, struct function *fun)
{
const char *funcname = function_name (fun);
FILE *fp = open_graph_file (base, "a");
- pretty_printer *pp = init_graph_slim_pretty_print (fp);
+ pretty_printer graph_slim_pp;
+ graph_slim_pp.buffer->stream = fp;
+ pretty_printer *const pp = &graph_slim_pp;
pp_printf (pp, "subgraph \"%s\" {\n"
"\tcolor=\"black\";\n"
"\tlabel=\"%s\";\n",
@@ -313,7 +295,9 @@ print_graph_cfg (const char *base, struct function *fun)
static void
start_graph_dump (FILE *fp, const char *base)
{
- pretty_printer *pp = init_graph_slim_pretty_print (fp);
+ pretty_printer graph_slim_pp;
+ graph_slim_pp.buffer->stream = fp;
+ pretty_printer *const pp = &graph_slim_pp;
pp_string (pp, "digraph \"");
pp_write_text_to_stream (pp);
pp_string (pp, base);
diff --git a/gcc/gtm-builtins.def b/gcc/gtm-builtins.def
index 171019ef7d0..e2bc081b054 100644
--- a/gcc/gtm-builtins.def
+++ b/gcc/gtm-builtins.def
@@ -28,7 +28,7 @@ DEF_TM_BUILTIN (BUILT_IN_TM_MALLOC, "_ITM_malloc",
DEF_TM_BUILTIN (BUILT_IN_TM_CALLOC, "_ITM_calloc",
BT_FN_PTR_SIZE_SIZE, ATTR_TMPURE_MALLOC_NOTHROW_LIST)
DEF_TM_BUILTIN (BUILT_IN_TM_FREE, "_ITM_free",
- BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LIST)
+ BT_FN_VOID_PTR, ATTR_TMPURE_NOTHROW_LEAF_LIST)
/* Logging builtins. */
DEF_TM_BUILTIN (BUILT_IN_TM_LOG_1, "_ITM_LU1",
diff --git a/gcc/hwint.h b/gcc/hwint.h
index dbf023975cb..9930baac100 100644
--- a/gcc/hwint.h
+++ b/gcc/hwint.h
@@ -110,7 +110,11 @@ extern char sizeof_long_long_must_be_8[sizeof(long long) == 8 ? 1 : -1];
#endif
+#define HOST_WIDE_INT_UC(X) HOST_WIDE_INT_C(X ## U)
#define HOST_WIDE_INT_1 HOST_WIDE_INT_C(1)
+#define HOST_WIDE_INT_1U HOST_WIDE_INT_UC(1)
+#define HOST_WIDE_INT_M1 HOST_WIDE_INT_C(-1)
+#define HOST_WIDE_INT_M1U HOST_WIDE_INT_UC(-1)
/* This is a magic identifier which allows GCC to figure out the type
of HOST_WIDE_INT for %wd specifier checks. You must issue this
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index b149d54c793..5698b4f5e72 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -4480,27 +4480,44 @@ rest_of_handle_if_conversion (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_ifcvt =
+namespace {
+
+const pass_data pass_data_rtl_ifcvt =
{
- {
- RTL_PASS,
- "ce1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_if_conversion, /* gate */
- rest_of_handle_if_conversion, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IFCVT, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "ce1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IFCVT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */
};
+class pass_rtl_ifcvt : public rtl_opt_pass
+{
+public:
+ pass_rtl_ifcvt(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_ifcvt, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_if_conversion (); }
+ unsigned int execute () { return rest_of_handle_if_conversion (); }
+
+}; // class pass_rtl_ifcvt
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_ifcvt (gcc::context *ctxt)
+{
+ return new pass_rtl_ifcvt (ctxt);
+}
+
static bool
gate_handle_if_after_combine (void)
{
@@ -4518,26 +4535,44 @@ rest_of_handle_if_after_combine (void)
return 0;
}
-struct rtl_opt_pass pass_if_after_combine =
+namespace {
+
+const pass_data pass_data_if_after_combine =
{
- {
- RTL_PASS,
- "ce2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_if_after_combine, /* gate */
- rest_of_handle_if_after_combine, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IFCVT, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "ce2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IFCVT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+class pass_if_after_combine : public rtl_opt_pass
+{
+public:
+ pass_if_after_combine(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_if_after_combine, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_if_after_combine (); }
+ unsigned int execute () { return rest_of_handle_if_after_combine (); }
+
+}; // class pass_if_after_combine
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_if_after_combine (gcc::context *ctxt)
+{
+ return new pass_if_after_combine (ctxt);
+}
+
static bool
gate_handle_if_after_reload (void)
@@ -4554,22 +4589,40 @@ rest_of_handle_if_after_reload (void)
}
-struct rtl_opt_pass pass_if_after_reload =
+namespace {
+
+const pass_data pass_data_if_after_reload =
{
- {
- RTL_PASS,
- "ce3", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_if_after_reload, /* gate */
- rest_of_handle_if_after_reload, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IFCVT2, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "ce3", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IFCVT2, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_if_after_reload : public rtl_opt_pass
+{
+public:
+ pass_if_after_reload(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_if_after_reload, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_if_after_reload (); }
+ unsigned int execute () { return rest_of_handle_if_after_reload (); }
+
+}; // class pass_if_after_reload
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_if_after_reload (gcc::context *ctxt)
+{
+ return new pass_if_after_reload (ctxt);
+}
diff --git a/gcc/init-regs.c b/gcc/init-regs.c
index 270d39b1628..ddb0b3792ba 100644
--- a/gcc/init-regs.c
+++ b/gcc/init-regs.c
@@ -138,22 +138,40 @@ rest_of_handle_initialize_regs (void)
return 0;
}
-struct rtl_opt_pass pass_initialize_regs =
+namespace {
+
+const pass_data pass_data_initialize_regs =
{
- {
- RTL_PASS,
- "init-regs", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_initialize_regs, /* gate */
- rest_of_handle_initialize_regs, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "init-regs", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_df_finish, /* todo_flags_finish */
};
+
+class pass_initialize_regs : public rtl_opt_pass
+{
+public:
+ pass_initialize_regs(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_initialize_regs, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_initialize_regs (); }
+ unsigned int execute () { return rest_of_handle_initialize_regs (); }
+
+}; // class pass_initialize_regs
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_initialize_regs (gcc::context *ctxt)
+{
+ return new pass_initialize_regs (ctxt);
+}
diff --git a/gcc/internal-fn.c b/gcc/internal-fn.c
index b841abd328e..983efeb751b 100644
--- a/gcc/internal-fn.c
+++ b/gcc/internal-fn.c
@@ -109,6 +109,30 @@ expand_STORE_LANES (gimple stmt)
expand_insn (get_multi_vector_move (type, vec_store_lanes_optab), 2, ops);
}
+/* This should get expanded in adjust_simduid_builtins. */
+
+static void
+expand_GOMP_SIMD_LANE (gimple stmt ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+}
+
+/* This should get expanded in adjust_simduid_builtins. */
+
+static void
+expand_GOMP_SIMD_VF (gimple stmt ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+}
+
+/* This should get expanded in adjust_simduid_builtins. */
+
+static void
+expand_GOMP_SIMD_LAST_LANE (gimple stmt ATTRIBUTE_UNUSED)
+{
+ gcc_unreachable ();
+}
+
/* Routines to expand each internal function, indexed by function number.
Each routine has the prototype:
diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def
index 8900d90dc22..5427664b8e3 100644
--- a/gcc/internal-fn.def
+++ b/gcc/internal-fn.def
@@ -40,3 +40,6 @@ along with GCC; see the file COPYING3. If not see
DEF_INTERNAL_FN (LOAD_LANES, ECF_CONST | ECF_LEAF)
DEF_INTERNAL_FN (STORE_LANES, ECF_CONST | ECF_LEAF)
+DEF_INTERNAL_FN (GOMP_SIMD_LANE, ECF_NOVOPS | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (GOMP_SIMD_VF, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
+DEF_INTERNAL_FN (GOMP_SIMD_LAST_LANE, ECF_CONST | ECF_LEAF | ECF_NOTHROW)
diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c
index 73f9d6ed4aa..78dee15aad8 100644
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -734,7 +734,8 @@ initialize_node_lattices (struct cgraph_node *node)
}
for (ie = node->indirect_calls; ie; ie = ie->next_callee)
- if (ie->indirect_info->polymorphic)
+ if (ie->indirect_info->polymorphic
+ && ie->indirect_info->param_index >= 0)
{
gcc_checking_assert (ie->indirect_info->param_index >= 0);
ipa_get_parm_lattices (info,
@@ -744,17 +745,26 @@ initialize_node_lattices (struct cgraph_node *node)
/* Return the result of a (possibly arithmetic) pass through jump function
JFUNC on the constant value INPUT. Return NULL_TREE if that cannot be
- determined or itself is considered an interprocedural invariant. */
+ determined or be considered an interprocedural invariant. */
static tree
ipa_get_jf_pass_through_result (struct ipa_jump_func *jfunc, tree input)
{
tree restype, res;
+ if (TREE_CODE (input) == TREE_BINFO)
+ {
+ if (ipa_get_jf_pass_through_type_preserved (jfunc))
+ {
+ gcc_checking_assert (ipa_get_jf_pass_through_operation (jfunc)
+ == NOP_EXPR);
+ return input;
+ }
+ return NULL_TREE;
+ }
+
if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
return input;
- else if (TREE_CODE (input) == TREE_BINFO)
- return NULL_TREE;
gcc_checking_assert (is_gimple_ip_invariant (input));
if (TREE_CODE_CLASS (ipa_get_jf_pass_through_operation (jfunc))
@@ -778,9 +788,13 @@ static tree
ipa_get_jf_ancestor_result (struct ipa_jump_func *jfunc, tree input)
{
if (TREE_CODE (input) == TREE_BINFO)
- return get_binfo_at_offset (input,
- ipa_get_jf_ancestor_offset (jfunc),
- ipa_get_jf_ancestor_type (jfunc));
+ {
+ if (!ipa_get_jf_ancestor_type_preserved (jfunc))
+ return NULL;
+ return get_binfo_at_offset (input,
+ ipa_get_jf_ancestor_offset (jfunc),
+ ipa_get_jf_ancestor_type (jfunc));
+ }
else if (TREE_CODE (input) == ADDR_EXPR)
{
tree t = TREE_OPERAND (input, 0);
@@ -1012,26 +1026,16 @@ propagate_vals_accross_pass_through (struct cgraph_edge *cs,
struct ipcp_value *src_val;
bool ret = false;
- if (ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
- for (src_val = src_lat->values; src_val; src_val = src_val->next)
- ret |= add_scalar_value_to_lattice (dest_lat, src_val->value, cs,
- src_val, src_idx);
/* Do not create new values when propagating within an SCC because if there
are arithmetic functions with circular dependencies, there is infinite
number of them and we would just make lattices bottom. */
- else if (edge_within_scc (cs))
+ if ((ipa_get_jf_pass_through_operation (jfunc) != NOP_EXPR)
+ and edge_within_scc (cs))
ret = set_lattice_contains_variable (dest_lat);
else
for (src_val = src_lat->values; src_val; src_val = src_val->next)
{
- tree cstval = src_val->value;
-
- if (TREE_CODE (cstval) == TREE_BINFO)
- {
- ret |= set_lattice_contains_variable (dest_lat);
- continue;
- }
- cstval = ipa_get_jf_pass_through_result (jfunc, cstval);
+ tree cstval = ipa_get_jf_pass_through_result (jfunc, src_val->value);
if (cstval)
ret |= add_scalar_value_to_lattice (dest_lat, cstval, cs, src_val,
@@ -1541,7 +1545,8 @@ ipa_get_indirect_edge_target_1 (struct cgraph_edge *ie,
if (TREE_CODE (t) != TREE_BINFO)
{
tree binfo;
- binfo = gimple_extract_devirt_binfo_from_cst (t);
+ binfo = gimple_extract_devirt_binfo_from_cst
+ (t, ie->indirect_info->otr_type);
if (!binfo)
return NULL_TREE;
binfo = get_binfo_at_offset (binfo, anc_offset, otr_type);
@@ -1758,13 +1763,12 @@ gather_context_independent_values (struct ipa_node_params *info,
}
else if (removable_params_cost
&& !ipa_is_param_used (info, i))
- *removable_params_cost
- += estimate_move_cost (TREE_TYPE (ipa_get_param (info, i)));
+ *removable_params_cost += ipa_get_param_move_cost (info, i);
}
else if (removable_params_cost
&& !ipa_is_param_used (info, i))
*removable_params_cost
- += estimate_move_cost (TREE_TYPE (ipa_get_param (info, i)));
+ += ipa_get_param_move_cost (info, i);
if (known_aggs)
{
@@ -1933,8 +1937,8 @@ estimate_local_effects (struct cgraph_node *node)
{
fprintf (dump_file, " - estimates for value ");
print_ipcp_constant_value (dump_file, val->value);
- fprintf (dump_file, " for parameter ");
- print_generic_expr (dump_file, ipa_get_param (info, i), 0);
+ fprintf (dump_file, " for ");
+ ipa_dump_param (dump_file, info, i);
fprintf (dump_file, ": time_benefit: %i, size: %i\n",
time_benefit, size);
}
@@ -1990,8 +1994,8 @@ estimate_local_effects (struct cgraph_node *node)
{
fprintf (dump_file, " - estimates for value ");
print_ipcp_constant_value (dump_file, val->value);
- fprintf (dump_file, " for parameter ");
- print_generic_expr (dump_file, ipa_get_param (info, i), 0);
+ fprintf (dump_file, " for ");
+ ipa_dump_param (dump_file, info, i);
fprintf (dump_file, "[%soffset: " HOST_WIDE_INT_PRINT_DEC
"]: time_benefit: %i, size: %i\n",
plats->aggs_by_ref ? "ref " : "",
@@ -2279,14 +2283,15 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
aggvals);
if (target)
{
+ bool agg_contents = ie->indirect_info->agg_contents;
+ bool polymorphic = ie->indirect_info->polymorphic;
+ bool param_index = ie->indirect_info->param_index;
struct cgraph_edge *cs = ipa_make_edge_direct_to_target (ie, target);
found = true;
- if (cs && !ie->indirect_info->agg_contents
- && !ie->indirect_info->polymorphic)
+ if (cs && !agg_contents && !polymorphic)
{
struct ipa_node_params *info = IPA_NODE_REF (node);
- int param_index = ie->indirect_info->param_index;
int c = ipa_get_controlled_uses (info, param_index);
if (c != IPA_UNDESCRIBED_USE)
{
@@ -2300,7 +2305,7 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node,
if (c == 0
&& (to_del = ipa_find_reference ((symtab_node) node,
(symtab_node) cs->callee,
- NULL)))
+ NULL, 0)))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " and even removing its "
@@ -2480,36 +2485,17 @@ gather_edges_for_value (struct ipcp_value *val, int caller_count)
Return it or NULL if for some reason it cannot be created. */
static struct ipa_replace_map *
-get_replacement_map (tree value, tree parm, int parm_num)
+get_replacement_map (struct ipa_node_params *info, tree value, int parm_num)
{
- tree req_type = TREE_TYPE (parm);
struct ipa_replace_map *replace_map;
- if (!useless_type_conversion_p (req_type, TREE_TYPE (value)))
- {
- if (fold_convertible_p (req_type, value))
- value = fold_build1 (NOP_EXPR, req_type, value);
- else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (value)))
- value = fold_build1 (VIEW_CONVERT_EXPR, req_type, value);
- else
- {
- if (dump_file)
- {
- fprintf (dump_file, " const ");
- print_generic_expr (dump_file, value, 0);
- fprintf (dump_file, " can't be converted to param ");
- print_generic_expr (dump_file, parm, 0);
- fprintf (dump_file, "\n");
- }
- return NULL;
- }
- }
replace_map = ggc_alloc_ipa_replace_map ();
if (dump_file)
{
- fprintf (dump_file, " replacing param ");
- print_generic_expr (dump_file, parm, 0);
+ fprintf (dump_file, " replacing ");
+ ipa_dump_param (dump_file, info, parm_num);
+
fprintf (dump_file, " with const ");
print_generic_expr (dump_file, value, 0);
fprintf (dump_file, "\n");
@@ -2697,7 +2683,7 @@ create_specialized_node (struct cgraph_node *node,
{
struct ipa_replace_map *replace_map;
- replace_map = get_replacement_map (t, ipa_get_param (info, i), i);
+ replace_map = get_replacement_map (info, t, i);
if (replace_map)
vec_safe_push (replace_trees, replace_map);
}
@@ -2781,8 +2767,8 @@ find_more_scalar_values_for_callers_subset (struct cgraph_node *node,
{
fprintf (dump_file, " adding an extra known scalar value ");
print_ipcp_constant_value (dump_file, newval);
- fprintf (dump_file, " for parameter ");
- print_generic_expr (dump_file, ipa_get_param (info, i), 0);
+ fprintf (dump_file, " for ");
+ ipa_dump_param (dump_file, info, i);
fprintf (dump_file, "\n");
}
@@ -3352,9 +3338,8 @@ decide_about_value (struct cgraph_node *node, int index, HOST_WIDE_INT offset,
{
fprintf (dump_file, " - considering value ");
print_ipcp_constant_value (dump_file, val->value);
- fprintf (dump_file, " for parameter ");
- print_generic_expr (dump_file, ipa_get_param (IPA_NODE_REF (node),
- index), 0);
+ fprintf (dump_file, " for ");
+ ipa_dump_param (dump_file, IPA_NODE_REF (node), index);
if (offset != -1)
fprintf (dump_file, ", offset: " HOST_WIDE_INT_PRINT_DEC, offset);
fprintf (dump_file, " (caller_count: %i)\n", caller_count);
@@ -3673,32 +3658,51 @@ cgraph_gate_cp (void)
return flag_ipa_cp && optimize;
}
-struct ipa_opt_pass_d pass_ipa_cp =
-{
- {
- IPA_PASS,
- "cp", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- cgraph_gate_cp, /* gate */
- ipcp_driver, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_CONSTANT_PROP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_dump_symtab |
- TODO_remove_functions /* todo_flags_finish */
- },
- ipcp_generate_summary, /* generate_summary */
- ipcp_write_summary, /* write_summary */
- ipcp_read_summary, /* read_summary */
- ipa_prop_write_all_agg_replacement, /* write_optimization_summary */
- ipa_prop_read_all_agg_replacement, /* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- ipcp_transform_function, /* function_transform */
- NULL, /* variable_transform */
+namespace {
+
+const pass_data pass_data_ipa_cp =
+{
+ IPA_PASS, /* type */
+ "cp", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_CONSTANT_PROP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_dump_symtab | TODO_remove_functions ), /* todo_flags_finish */
};
+
+class pass_ipa_cp : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_cp(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_cp, ctxt,
+ ipcp_generate_summary, /* generate_summary */
+ ipcp_write_summary, /* write_summary */
+ ipcp_read_summary, /* read_summary */
+ ipa_prop_write_all_agg_replacement, /*
+ write_optimization_summary */
+ ipa_prop_read_all_agg_replacement, /*
+ read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ ipcp_transform_function, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return cgraph_gate_cp (); }
+ unsigned int execute () { return ipcp_driver (); }
+
+}; // class pass_ipa_cp
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_cp (gcc::context *ctxt)
+{
+ return new pass_ipa_cp (ctxt);
+}
diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c
new file mode 100644
index 00000000000..96622b25b1b
--- /dev/null
+++ b/gcc/ipa-devirt.c
@@ -0,0 +1,1181 @@
+/* Basic IPA utilities for type inheritance graph construction and
+ devirtualization.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Jan Hubicka
+
+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/>. */
+
+/* Brief vocalburary:
+ ODR = One Definition Rule
+ In short, the ODR states that:
+ 1 In any translation unit, a template, type, function, or object can
+ have no more than one definition. Some of these can have any number
+ of declarations. A definition provides an instance.
+ 2 In the entire program, an object or non-inline function cannot have
+ more than one definition; if an object or function is used, it must
+ have exactly one definition. You can declare an object or function
+ that is never used, in which case you don't have to provide
+ a definition. In no event can there be more than one definition.
+ 3 Some things, like types, templates, and extern inline functions, can
+ be defined in more than one translation unit. For a given entity,
+ each definition must be the same. Non-extern objects and functions
+ in different translation units are different entities, even if their
+ names and types are the same.
+
+ OTR = OBJ_TYPE_REF
+ This is the Gimple representation of type information of a polymorphic call.
+ It contains two parameters:
+ otr_type is a type of class whose method is called.
+ otr_token is the index into virtual table where address is taken.
+
+ BINFO
+ This is the type inheritance information attached to each tree
+ RECORD_TYPE by the C++ frotend. It provides information about base
+ types and virtual tables.
+
+ BINFO is linked to the RECORD_TYPE by TYPE_BINFO.
+ BINFO also links to its type by BINFO_TYPE and to the virtual table by
+ BINFO_VTABLE.
+
+ Base types of a given type are enumerated by BINFO_BASE_BINFO
+ vector. Members of this vectors are not BINFOs associated
+ with a base type. Rather they are new copies of BINFOs
+ (base BINFOs). Their virtual tables may differ from
+ virtual table of the base type. Also BINFO_OFFSET specifies
+ offset of the base within the type.
+
+ In the case of single inheritance, the virtual table is shared
+ and BINFO_VTABLE of base BINFO is NULL. In the case of multiple
+ inheritance the individual virtual tables are pointer to by
+ BINFO_VTABLE of base binfos (that differs of BINFO_VTABLE of
+ binfo associated to the base type).
+
+ BINFO lookup for a given base type and offset can be done by
+ get_binfo_at_offset. It returns proper BINFO whose virtual table
+ can be used for lookup of virtual methods associated with the
+ base type.
+
+ token
+ This is an index of virtual method in virtual table associated
+ to the type defining it. Token can be looked up from OBJ_TYPE_REF
+ or from DECL_VINDEX of a given virtual table.
+
+ polymorphic (indirect) call
+ This is callgraph represention of virtual method call. Every
+ polymorphic call contains otr_type and otr_token taken from
+ original OBJ_TYPE_REF at callgraph construction time.
+
+ What we do here:
+
+ build_type_inheritance_graph triggers a construction of the type inheritance
+ graph.
+
+ We reconstruct it based on types of methods we see in the unit.
+ This means that the graph is not complete. Types with no methods are not
+ inserted into the graph. Also types without virtual methods are not
+ represented at all, though it may be easy to add this.
+
+ The inheritance graph is represented as follows:
+
+ Vertices are structures odr_type. Every odr_type may correspond
+ to one or more tree type nodes that are equivalent by ODR rule.
+ (the multiple type nodes appear only with linktime optimization)
+
+ Edges are represented by odr_type->base and odr_type->derived_types.
+ At the moment we do not track offsets of types for multiple inheritance.
+ Adding this is easy.
+
+ possible_polymorphic_call_targets returns, given an parameters found in
+ indirect polymorphic edge all possible polymorphic call targets of the call.
+
+ pass_ipa_devirt performs simple speculative devirtualization.
+*/
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "cgraph.h"
+#include "tree-pass.h"
+#include "ggc.h"
+#include "pointer-set.h"
+#include "target.h"
+#include "hash-table.h"
+#include "tree-pretty-print.h"
+#include "ipa-utils.h"
+#include "gimple.h"
+#include "ipa-inline.h"
+#include "diagnostic.h"
+
+/* Pointer set of all call targets appearing in the cache. */
+static pointer_set_t *cached_polymorphic_call_targets;
+
+/* The node of type inheritance graph. For each type unique in
+ One Defintion Rule (ODR) sense, we produce one node linking all
+ main variants of types equivalent to it, bases and derived types. */
+
+struct GTY(()) odr_type_d
+{
+ /* leader type. */
+ tree type;
+ /* All bases. */
+ vec<odr_type> GTY((skip)) bases;
+ /* All derrived types with virtual methods seen in unit. */
+ vec<odr_type> GTY((skip)) derived_types;
+
+ /* All equivalent types, if more than one. */
+ vec<tree, va_gc> *types;
+ /* Set of all equivalent types, if NON-NULL. */
+ pointer_set_t * GTY((skip)) types_set;
+
+ /* Unique ID indexing the type in odr_types array. */
+ int id;
+ /* Is it in anonymous namespace? */
+ bool anonymous_namespace;
+};
+
+
+/* Return true if BINFO corresponds to a type with virtual methods.
+
+ Every type has several BINFOs. One is the BINFO associated by the type
+ while other represents bases of derived types. The BINFOs representing
+ bases do not have BINFO_VTABLE pointer set when this is the single
+ inheritance (because vtables are shared). Look up the BINFO of type
+ and check presence of its vtable. */
+
+static inline bool
+polymorphic_type_binfo_p (tree binfo)
+{
+ /* See if BINFO's type has an virtual table associtated with it. */
+ return BINFO_VTABLE (TYPE_BINFO (BINFO_TYPE (binfo)));
+}
+
+/* One Definition Rule hashtable helpers. */
+
+struct odr_hasher
+{
+ typedef odr_type_d value_type;
+ typedef union tree_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+/* Produce hash based on type name. */
+
+hashval_t
+hash_type_name (tree t)
+{
+ gcc_checking_assert (TYPE_MAIN_VARIANT (t) == t);
+
+ /* If not in LTO, all main variants are unique, so we can do
+ pointer hash. */
+ if (!in_lto_p)
+ return htab_hash_pointer (t);
+
+ /* Anonymous types are unique. */
+ if (type_in_anonymous_namespace_p (t))
+ return htab_hash_pointer (t);
+
+ /* For polymorphic types, we can simply hash the virtual table. */
+ if (TYPE_BINFO (t) && BINFO_VTABLE (TYPE_BINFO (t)))
+ {
+ tree v = BINFO_VTABLE (TYPE_BINFO (t));
+ hashval_t hash = 0;
+
+ if (TREE_CODE (v) == POINTER_PLUS_EXPR)
+ {
+ hash = TREE_INT_CST_LOW (TREE_OPERAND (v, 1));
+ v = TREE_OPERAND (TREE_OPERAND (v, 0), 0);
+ }
+
+ v = DECL_ASSEMBLER_NAME (v);
+ hash = iterative_hash_hashval_t (hash, htab_hash_pointer (v));
+ return hash;
+ }
+
+ /* Rest is not implemented yet. */
+ gcc_unreachable ();
+}
+
+/* Return the computed hashcode for ODR_TYPE. */
+
+inline hashval_t
+odr_hasher::hash (const value_type *odr_type)
+{
+ return hash_type_name (odr_type->type);
+}
+
+/* Compare types T1 and T2 and return true if they are
+ equivalent. */
+
+inline bool
+odr_hasher::equal (const value_type *t1, const compare_type *ct2)
+{
+ tree t2 = const_cast <tree> (ct2);
+
+ gcc_checking_assert (TYPE_MAIN_VARIANT (ct2) == ct2);
+ if (t1->type == t2)
+ return true;
+ if (!in_lto_p)
+ return false;
+ return types_same_for_odr (t1->type, t2);
+}
+
+/* Free ODR type V. */
+
+inline void
+odr_hasher::remove (value_type *v)
+{
+ v->bases.release ();
+ v->derived_types.release ();
+ if (v->types_set)
+ pointer_set_destroy (v->types_set);
+ ggc_free (v);
+}
+
+/* ODR type hash used to lookup ODR type based on tree type node. */
+
+typedef hash_table <odr_hasher> odr_hash_type;
+static odr_hash_type odr_hash;
+
+/* ODR types are also stored into ODR_TYPE vector to allow consistent
+ walking. Bases appear before derived types. Vector is garbage collected
+ so we won't end up visiting empty types. */
+
+static GTY(()) vec <odr_type, va_gc> *odr_types_ptr;
+#define odr_types (*odr_types_ptr)
+
+/* TYPE is equivalent to VAL by ODR, but its tree representation differs
+ from VAL->type. This may happen in LTO where tree merging did not merge
+ all variants of the same type. It may or may not mean the ODR violation.
+ Add it to the list of duplicates and warn on some violations. */
+
+static void
+add_type_duplicate (odr_type val, tree type)
+{
+ if (!val->types_set)
+ val->types_set = pointer_set_create ();
+
+ /* See if this duplicate is new. */
+ if (!pointer_set_insert (val->types_set, type))
+ {
+ bool merge = true;
+ bool base_mismatch = false;
+ gcc_assert (in_lto_p);
+ vec_safe_push (val->types, type);
+ unsigned int i,j;
+
+ /* First we compare memory layout. */
+ if (!types_compatible_p (val->type, type))
+ {
+ merge = false;
+ if (BINFO_VTABLE (TYPE_BINFO (val->type))
+ && warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (type)), 0,
+ "type %qD violates one definition rule ",
+ type))
+ inform (DECL_SOURCE_LOCATION (TYPE_NAME (val->type)),
+ "a type with the same name but different layout is "
+ "defined in another translation unit");
+ debug_tree (BINFO_VTABLE (TYPE_BINFO (type)));
+ debug_tree (BINFO_VTABLE (TYPE_BINFO (val->type)));
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "ODR violation or merging or ODR type bug?\n");
+
+ print_node (cgraph_dump_file, "", val->type, 0);
+ putc ('\n',cgraph_dump_file);
+ print_node (cgraph_dump_file, "", type, 0);
+ putc ('\n',cgraph_dump_file);
+ }
+ }
+
+ /* Next sanity check that bases are the same. If not, we will end
+ up producing wrong answers. */
+ for (j = 0, i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++)
+ if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (TYPE_BINFO (type), i)))
+ {
+ odr_type base = get_odr_type
+ (BINFO_TYPE
+ (BINFO_BASE_BINFO (TYPE_BINFO (type),
+ i)),
+ true);
+ if (val->bases.length () <= j || val->bases[j] != base)
+ base_mismatch = true;
+ j++;
+ }
+ if (base_mismatch)
+ {
+ merge = false;
+
+ if (warning_at (DECL_SOURCE_LOCATION (TYPE_NAME (type)), 0,
+ "type %qD violates one definition rule ",
+ type))
+ inform (DECL_SOURCE_LOCATION (TYPE_NAME (val->type)),
+ "a type with the same name but different bases is "
+ "defined in another translation unit");
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "ODR bse violation or merging bug?\n");
+
+ print_node (cgraph_dump_file, "", val->type, 0);
+ putc ('\n',cgraph_dump_file);
+ print_node (cgraph_dump_file, "", type, 0);
+ putc ('\n',cgraph_dump_file);
+ }
+ }
+
+ /* Regularize things a little. During LTO same types may come with
+ different BINFOs. Either because their virtual table was
+ not merged by tree merging and only later at decl merging or
+ because one type comes with external vtable, while other
+ with internal. We want to merge equivalent binfos to conserve
+ memory and streaming overhead.
+
+ The external vtables are more harmful: they contain references
+ to external declarations of methods that may be defined in the
+ merged LTO unit. For this reason we absolutely need to remove
+ them and replace by internal variants. Not doing so will lead
+ to incomplete answers from possible_polymorphic_call_targets. */
+ if (!flag_ltrans && merge)
+ {
+ tree master_binfo = TYPE_BINFO (val->type);
+ tree v1 = BINFO_VTABLE (master_binfo);
+ tree v2 = BINFO_VTABLE (TYPE_BINFO (type));
+
+ if (TREE_CODE (v1) == POINTER_PLUS_EXPR)
+ {
+ gcc_assert (TREE_CODE (v2) == POINTER_PLUS_EXPR
+ && operand_equal_p (TREE_OPERAND (v1, 1),
+ TREE_OPERAND (v2, 1), 0));
+ v1 = TREE_OPERAND (TREE_OPERAND (v1, 0), 0);
+ v2 = TREE_OPERAND (TREE_OPERAND (v2, 0), 0);
+ }
+ gcc_assert (DECL_ASSEMBLER_NAME (v1)
+ == DECL_ASSEMBLER_NAME (v2));
+
+ if (DECL_EXTERNAL (v1) && !DECL_EXTERNAL (v2))
+ {
+ unsigned int i;
+
+ TYPE_BINFO (val->type) = TYPE_BINFO (type);
+ for (i = 0; i < val->types->length(); i++)
+ {
+ if (TYPE_BINFO ((*val->types)[i])
+ == master_binfo)
+ TYPE_BINFO ((*val->types)[i]) = TYPE_BINFO (type);
+ }
+ }
+ else
+ TYPE_BINFO (type) = master_binfo;
+ }
+ }
+}
+
+/* Get ODR type hash entry for TYPE. If INSERT is true, create
+ possibly new entry. */
+
+odr_type
+get_odr_type (tree type, bool insert)
+{
+ odr_type_d **slot;
+ odr_type val;
+ hashval_t hash;
+
+ type = TYPE_MAIN_VARIANT (type);
+ gcc_checking_assert (TYPE_MAIN_VARIANT (type) == type);
+ hash = hash_type_name (type);
+ slot = odr_hash.find_slot_with_hash (type, hash, insert ? INSERT : NO_INSERT);
+ if (!slot)
+ return NULL;
+
+ /* See if we already have entry for type. */
+ if (*slot)
+ {
+ val = *slot;
+
+ /* With LTO we need to support multiple tree representation of
+ the same ODR type. */
+ if (val->type != type)
+ add_type_duplicate (val, type);
+ }
+ else
+ {
+ tree binfo = TYPE_BINFO (type);
+ unsigned int i;
+
+ val = ggc_alloc_cleared_odr_type_d ();
+ val->type = type;
+ val->bases = vNULL;
+ val->derived_types = vNULL;
+ val->anonymous_namespace = type_in_anonymous_namespace_p (type);
+ *slot = val;
+ for (i = 0; i < BINFO_N_BASE_BINFOS (binfo); i++)
+ /* For now record only polymorphic types. other are
+ pointless for devirtualization and we can not precisely
+ determine ODR equivalency of these during LTO. */
+ if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (binfo, i)))
+ {
+ odr_type base = get_odr_type (BINFO_TYPE (BINFO_BASE_BINFO (binfo,
+ i)),
+ true);
+ base->derived_types.safe_push (val);
+ val->bases.safe_push (base);
+ }
+ /* First record bases, then add into array so ids are increasing. */
+ if (odr_types_ptr)
+ val->id = odr_types.length();
+ vec_safe_push (odr_types_ptr, val);
+ }
+ return val;
+}
+
+/* Dump ODR type T and all its derrived type. INDENT specify indentation for
+ recusive printing. */
+
+static void
+dump_odr_type (FILE *f, odr_type t, int indent=0)
+{
+ unsigned int i;
+ fprintf (f, "%*s type %i: ", indent * 2, "", t->id);
+ print_generic_expr (f, t->type, TDF_SLIM);
+ fprintf (f, "%s\n", t->anonymous_namespace ? " (anonymous namespace)":"");
+ if (TYPE_NAME (t->type))
+ {
+ fprintf (f, "%*s defined at: %s:%i\n", indent * 2, "",
+ DECL_SOURCE_FILE (TYPE_NAME (t->type)),
+ DECL_SOURCE_LINE (TYPE_NAME (t->type)));
+ }
+ if (t->bases.length())
+ {
+ fprintf (f, "%*s base odr type ids: ", indent * 2, "");
+ for (i = 0; i < t->bases.length(); i++)
+ fprintf (f, " %i", t->bases[i]->id);
+ fprintf (f, "\n");
+ }
+ if (t->derived_types.length())
+ {
+ fprintf (f, "%*s derived types:\n", indent * 2, "");
+ for (i = 0; i < t->derived_types.length(); i++)
+ dump_odr_type (f, t->derived_types[i], indent + 1);
+ }
+ fprintf (f, "\n");
+}
+
+/* Dump the type inheritance graph. */
+
+static void
+dump_type_inheritance_graph (FILE *f)
+{
+ unsigned int i;
+ if (!odr_types_ptr)
+ return;
+ fprintf (f, "\n\nType inheritance graph:\n");
+ for (i = 0; i < odr_types.length(); i++)
+ {
+ if (odr_types[i]->bases.length() == 0)
+ dump_odr_type (f, odr_types[i]);
+ }
+ for (i = 0; i < odr_types.length(); i++)
+ {
+ if (odr_types[i]->types && odr_types[i]->types->length())
+ {
+ unsigned int j;
+ fprintf (f, "Duplicate tree types for odr type %i\n", i);
+ print_node (f, "", odr_types[i]->type, 0);
+ for (j = 0; j < odr_types[i]->types->length(); j++)
+ {
+ tree t;
+ fprintf (f, "duplicate #%i\n", j);
+ print_node (f, "", (*odr_types[i]->types)[j], 0);
+ t = (*odr_types[i]->types)[j];
+ while (TYPE_P (t) && TYPE_CONTEXT (t))
+ {
+ t = TYPE_CONTEXT (t);
+ print_node (f, "", t, 0);
+ }
+ putc ('\n',f);
+ }
+ }
+ }
+}
+
+/* Given method type T, return type of class it belongs to.
+ Lookup this pointer and get its type. */
+
+tree
+method_class_type (tree t)
+{
+ tree first_parm_type = TREE_VALUE (TYPE_ARG_TYPES (t));
+
+ return TREE_TYPE (first_parm_type);
+}
+
+/* Initialize IPA devirt and build inheritance tree graph. */
+
+void
+build_type_inheritance_graph (void)
+{
+ struct cgraph_node *n;
+ FILE *inheritance_dump_file;
+ int flags;
+
+ if (odr_hash.is_created ())
+ return;
+ timevar_push (TV_IPA_INHERITANCE);
+ inheritance_dump_file = dump_begin (TDI_inheritance, &flags);
+ odr_hash.create (23);
+
+ /* We reconstruct the graph starting of types of all methods seen in the
+ the unit. */
+ FOR_EACH_FUNCTION (n)
+ if (DECL_VIRTUAL_P (n->symbol.decl)
+ && symtab_real_symbol_p ((symtab_node)n))
+ get_odr_type (method_class_type (TREE_TYPE (n->symbol.decl)), true);
+ if (inheritance_dump_file)
+ {
+ dump_type_inheritance_graph (inheritance_dump_file);
+ dump_end (TDI_inheritance, inheritance_dump_file);
+ }
+ timevar_pop (TV_IPA_INHERITANCE);
+}
+
+/* If TARGET has associated node, record it in the NODES array. */
+
+static void
+maybe_record_node (vec <cgraph_node *> &nodes,
+ tree target, pointer_set_t *inserted)
+{
+ struct cgraph_node *target_node;
+ enum built_in_function fcode;
+
+ if (target
+ /* Those are used to mark impossible scenarios. */
+ && (fcode = DECL_FUNCTION_CODE (target))
+ != BUILT_IN_UNREACHABLE
+ && fcode != BUILT_IN_TRAP
+ && !pointer_set_insert (inserted, target)
+ && (target_node = cgraph_get_node (target)) != NULL
+ && (TREE_PUBLIC (target)
+ || target_node->symbol.definition)
+ && symtab_real_symbol_p ((symtab_node)target_node))
+ {
+ pointer_set_insert (cached_polymorphic_call_targets,
+ target_node);
+ nodes.safe_push (target_node);
+ }
+}
+
+/* See if BINFO's type match OTR_TYPE. If so, lookup method
+ in vtable of TYPE_BINFO and insert method to NODES array.
+ Otherwise recurse to base BINFOs.
+ This match what get_binfo_at_offset does, but with offset
+ being unknown.
+
+ TYPE_BINFO is binfo holding an virtual table matching
+ BINFO's type. In the case of single inheritance, this
+ is binfo of BINFO's type ancestor (vtable is shared),
+ otherwise it is binfo of BINFO's type.
+
+ MATCHED_VTABLES tracks virtual tables we already did lookup
+ for virtual function in.
+
+ ANONYMOUS is true if BINFO is part of anonymous namespace.
+ */
+
+static void
+record_binfo (vec <cgraph_node *> &nodes,
+ tree binfo,
+ tree otr_type,
+ tree type_binfo,
+ HOST_WIDE_INT otr_token,
+ pointer_set_t *inserted,
+ pointer_set_t *matched_vtables,
+ bool anonymous)
+{
+ tree type = BINFO_TYPE (binfo);
+ int i;
+ tree base_binfo;
+
+ gcc_checking_assert (BINFO_VTABLE (type_binfo));
+
+ if (types_same_for_odr (type, otr_type)
+ && !pointer_set_insert (matched_vtables, BINFO_VTABLE (type_binfo)))
+ {
+ /* For types in anonymous namespace first check if the respective vtable
+ is alive. If not, we know the type can't be called. */
+ if (!flag_ltrans && anonymous)
+ {
+ tree vtable = BINFO_VTABLE (type_binfo);
+ struct varpool_node *vnode;
+
+ if (TREE_CODE (vtable) == POINTER_PLUS_EXPR)
+ vtable = TREE_OPERAND (TREE_OPERAND (vtable, 0), 0);
+ vnode = varpool_get_node (vtable);
+ if (!vnode || !vnode->symbol.definition)
+ return;
+ }
+ tree target = gimple_get_virt_method_for_binfo (otr_token, type_binfo);
+ if (target)
+ maybe_record_node (nodes, target, inserted);
+ return;
+ }
+
+ /* Walk bases. */
+ for (i = 0; BINFO_BASE_ITERATE (binfo, i, base_binfo); i++)
+ /* Walking bases that have no virtual method is pointless excercise. */
+ if (polymorphic_type_binfo_p (base_binfo))
+ record_binfo (nodes, base_binfo, otr_type,
+ /* In the case of single inheritance, the virtual table
+ is shared with the outer type. */
+ BINFO_VTABLE (base_binfo) ? base_binfo : type_binfo,
+ otr_token, inserted,
+ matched_vtables, anonymous);
+}
+
+/* Lookup virtual methods matching OTR_TYPE (with OFFSET and OTR_TOKEN)
+ of TYPE, insert them to NODES, recurse into derived nodes.
+ INSERTED is used to avoid duplicate insertions of methods into NODES.
+ MATCHED_VTABLES are used to avoid duplicate walking vtables. */
+
+static void
+possible_polymorphic_call_targets_1 (vec <cgraph_node *> &nodes,
+ pointer_set_t *inserted,
+ pointer_set_t *matched_vtables,
+ tree otr_type,
+ odr_type type,
+ HOST_WIDE_INT otr_token)
+{
+ tree binfo = TYPE_BINFO (type->type);
+ unsigned int i;
+
+ record_binfo (nodes, binfo, otr_type, binfo, otr_token, inserted,
+ matched_vtables, type->anonymous_namespace);
+ for (i = 0; i < type->derived_types.length(); i++)
+ possible_polymorphic_call_targets_1 (nodes, inserted,
+ matched_vtables,
+ otr_type,
+ type->derived_types[i],
+ otr_token);
+}
+
+/* Cache of queries for polymorphic call targets.
+
+ Enumerating all call targets may get expensive when there are many
+ polymorphic calls in the program, so we memoize all the previous
+ queries and avoid duplicated work. */
+
+struct polymorphic_call_target_d
+{
+ odr_type type;
+ HOST_WIDE_INT otr_token;
+ vec <cgraph_node *> targets;
+};
+
+/* Polymorphic call target cache helpers. */
+
+struct polymorphic_call_target_hasher
+{
+ typedef polymorphic_call_target_d value_type;
+ typedef polymorphic_call_target_d compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+ static inline void remove (value_type *);
+};
+
+/* Return the computed hashcode for ODR_QUERY. */
+
+inline hashval_t
+polymorphic_call_target_hasher::hash (const value_type *odr_query)
+{
+ return iterative_hash_hashval_t (odr_query->type->id,
+ odr_query->otr_token);
+}
+
+/* Compare cache entries T1 and T2. */
+
+inline bool
+polymorphic_call_target_hasher::equal (const value_type *t1,
+ const compare_type *t2)
+{
+ return t1->type == t2->type && t1->otr_token == t2->otr_token;
+}
+
+/* Remove entry in polymorphic call target cache hash. */
+
+inline void
+polymorphic_call_target_hasher::remove (value_type *v)
+{
+ v->targets.release ();
+ free (v);
+}
+
+/* Polymorphic call target query cache. */
+
+typedef hash_table <polymorphic_call_target_hasher>
+ polymorphic_call_target_hash_type;
+static polymorphic_call_target_hash_type polymorphic_call_target_hash;
+
+/* Destroy polymorphic call target query cache. */
+
+static void
+free_polymorphic_call_targets_hash ()
+{
+ if (cached_polymorphic_call_targets)
+ {
+ polymorphic_call_target_hash.dispose ();
+ pointer_set_destroy (cached_polymorphic_call_targets);
+ cached_polymorphic_call_targets = NULL;
+ }
+}
+
+/* When virtual function is removed, we may need to flush the cache. */
+
+static void
+devirt_node_removal_hook (struct cgraph_node *n, void *d ATTRIBUTE_UNUSED)
+{
+ if (cached_polymorphic_call_targets
+ && pointer_set_contains (cached_polymorphic_call_targets, n))
+ free_polymorphic_call_targets_hash ();
+}
+
+/* When virtual table is removed, we may need to flush the cache. */
+
+static void
+devirt_variable_node_removal_hook (struct varpool_node *n,
+ void *d ATTRIBUTE_UNUSED)
+{
+ if (cached_polymorphic_call_targets
+ && DECL_VIRTUAL_P (n->symbol.decl)
+ && type_in_anonymous_namespace_p (DECL_CONTEXT (n->symbol.decl)))
+ free_polymorphic_call_targets_hash ();
+}
+
+/* Return vector containing possible targets of polymorphic call of type
+ OTR_TYPE caling method OTR_TOKEN with OFFSET. If FINALp is non-NULL,
+ store true if the list is complette.
+ CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry
+ in the target cache. If user needs to visit every target list
+ just once, it can memoize them.
+
+ Returned vector is placed into cache. It is NOT caller's responsibility
+ to free it. The vector can be freed on cgraph_remove_node call if
+ the particular node is a virtual function present in the cache. */
+
+vec <cgraph_node *>
+possible_polymorphic_call_targets (tree otr_type,
+ HOST_WIDE_INT otr_token,
+ bool *finalp,
+ void **cache_token)
+{
+ static struct cgraph_node_hook_list *node_removal_hook_holder;
+ pointer_set_t *inserted;
+ pointer_set_t *matched_vtables;
+ vec <cgraph_node *> nodes=vNULL;
+ odr_type type;
+ polymorphic_call_target_d key;
+ polymorphic_call_target_d **slot;
+ unsigned int i;
+ tree binfo, target;
+
+ if (finalp)
+ *finalp = false;
+
+ type = get_odr_type (otr_type, false);
+ /* If we do not have type in our hash it means we never seen any method
+ in it. */
+ if (!type)
+ return nodes;
+
+ /* For anonymous namespace types we can attempt to build full type.
+ All derivations must be in this unit. */
+ if (type->anonymous_namespace && finalp && !flag_ltrans)
+ *finalp = true;
+
+ /* Initialize query cache. */
+ if (!cached_polymorphic_call_targets)
+ {
+ cached_polymorphic_call_targets = pointer_set_create ();
+ polymorphic_call_target_hash.create (23);
+ if (!node_removal_hook_holder)
+ {
+ node_removal_hook_holder =
+ cgraph_add_node_removal_hook (&devirt_node_removal_hook, NULL);
+ varpool_add_node_removal_hook (&devirt_variable_node_removal_hook,
+ NULL);
+ }
+ }
+
+ /* Lookup cached answer. */
+ key.type = type;
+ key.otr_token = otr_token;
+ slot = polymorphic_call_target_hash.find_slot (&key, INSERT);
+ if (cache_token)
+ *cache_token = (void *)*slot;
+ if (*slot)
+ return (*slot)->targets;
+
+ /* Do actual search. */
+ timevar_push (TV_IPA_VIRTUAL_CALL);
+ *slot = XCNEW (polymorphic_call_target_d);
+ if (cache_token)
+ *cache_token = (void *)*slot;
+ (*slot)->type = type;
+ (*slot)->otr_token = otr_token;
+
+ inserted = pointer_set_create ();
+ matched_vtables = pointer_set_create ();
+
+ /* First see virtual method of type itself. */
+
+ binfo = TYPE_BINFO (type->type);
+ target = gimple_get_virt_method_for_binfo (otr_token, binfo);
+ if (target)
+ maybe_record_node (nodes, target, inserted);
+ pointer_set_insert (matched_vtables, BINFO_VTABLE (binfo));
+
+ /* TODO: If method is final, we can stop here and signaize that
+ list is final. We need C++ FE to pass our info about final
+ methods and classes. */
+
+ /* Walk recursively all derived types. Here we need to lookup proper basetype
+ via their BINFO walk that is done by record_binfo */
+ for (i = 0; i < type->derived_types.length(); i++)
+ possible_polymorphic_call_targets_1 (nodes, inserted,
+ matched_vtables,
+ otr_type, type->derived_types[i],
+ otr_token);
+ (*slot)->targets = nodes;
+
+ pointer_set_destroy (inserted);
+ pointer_set_destroy (matched_vtables);
+ timevar_pop (TV_IPA_VIRTUAL_CALL);
+ return nodes;
+}
+
+/* Dump all possible targets of a polymorphic call. */
+
+void
+dump_possible_polymorphic_call_targets (FILE *f,
+ tree otr_type,
+ HOST_WIDE_INT otr_token)
+{
+ vec <cgraph_node *> targets;
+ bool final;
+ odr_type type = get_odr_type (otr_type, false);
+ unsigned int i;
+
+ if (!type)
+ return;
+ targets = possible_polymorphic_call_targets (otr_type, otr_token,
+ &final);
+ fprintf (f, "Targets of polymorphic call of type %i ", type->id);
+ print_generic_expr (f, type->type, TDF_SLIM);
+ fprintf (f, " token %i%s:",
+ (int)otr_token,
+ final ? " (full list)" : " (partial list, may call to other unit)");
+ for (i = 0; i < targets.length (); i++)
+ fprintf (f, " %s/%i", cgraph_node_name (targets[i]),
+ targets[i]->symbol.order);
+ fprintf (f, "\n");
+}
+
+
+/* Return true if N can be possibly target of a polymorphic call of
+ OTR_TYPE/OTR_TOKEN. */
+
+bool
+possible_polymorphic_call_target_p (tree otr_type,
+ HOST_WIDE_INT otr_token,
+ struct cgraph_node *n)
+{
+ vec <cgraph_node *> targets;
+ unsigned int i;
+
+ if (!odr_hash.is_created ())
+ return true;
+ targets = possible_polymorphic_call_targets (otr_type, otr_token);
+ for (i = 0; i < targets.length (); i++)
+ if (n == targets[i])
+ return true;
+ return false;
+}
+
+
+/* After callgraph construction new external nodes may appear.
+ Add them into the graph. */
+
+void
+update_type_inheritance_graph (void)
+{
+ struct cgraph_node *n;
+
+ if (!odr_hash.is_created ())
+ return;
+ free_polymorphic_call_targets_hash ();
+ timevar_push (TV_IPA_INHERITANCE);
+ /* We reconstruct the graph starting of types of all methods seen in the
+ the unit. */
+ FOR_EACH_FUNCTION (n)
+ if (DECL_VIRTUAL_P (n->symbol.decl)
+ && !n->symbol.definition
+ && symtab_real_symbol_p ((symtab_node)n))
+ get_odr_type (method_class_type (TREE_TYPE (n->symbol.decl)), true);
+ timevar_pop (TV_IPA_INHERITANCE);
+}
+
+
+/* Return true if N looks like likely target of a polymorphic call.
+ Rule out cxa_pure_virtual, noreturns, function declared cold and
+ other obvious cases. */
+
+bool
+likely_target_p (struct cgraph_node *n)
+{
+ int flags;
+ /* cxa_pure_virtual and similar things are not likely. */
+ if (TREE_CODE (TREE_TYPE (n->symbol.decl)) != METHOD_TYPE)
+ return false;
+ flags = flags_from_decl_or_type (n->symbol.decl);
+ if (flags & ECF_NORETURN)
+ return false;
+ if (lookup_attribute ("cold",
+ DECL_ATTRIBUTES (n->symbol.decl)))
+ return false;
+ if (n->frequency < NODE_FREQUENCY_NORMAL)
+ return false;
+ return true;
+}
+
+/* The ipa-devirt pass.
+ When polymorphic call has only one likely target in the unit,
+ turn it into speculative call. */
+
+static unsigned int
+ipa_devirt (void)
+{
+ struct cgraph_node *n;
+ struct pointer_set_t *bad_call_targets = pointer_set_create ();
+ struct cgraph_edge *e;
+
+ int npolymorphic = 0, nspeculated = 0, nconverted = 0, ncold = 0;
+ int nmultiple = 0, noverwritable = 0, ndevirtualized = 0, nnotdefined = 0;
+ int nwrong = 0, nok = 0, nexternal = 0;;
+
+ FOR_EACH_DEFINED_FUNCTION (n)
+ {
+ bool update = false;
+ if (dump_file && n->indirect_calls)
+ fprintf (dump_file, "\n\nProcesing function %s/%i\n",
+ cgraph_node_name (n), n->symbol.order);
+ for (e = n->indirect_calls; e; e = e->next_callee)
+ if (e->indirect_info->polymorphic)
+ {
+ struct cgraph_node *likely_target = NULL;
+ void *cache_token;
+ bool final;
+ vec <cgraph_node *>targets
+ = possible_polymorphic_call_targets
+ (e, &final, &cache_token);
+ unsigned int i;
+
+ if (dump_file)
+ dump_possible_polymorphic_call_targets
+ (dump_file, e);
+
+ npolymorphic++;
+
+ if (!cgraph_maybe_hot_edge_p (e))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Call is cold\n");
+ ncold++;
+ continue;
+ }
+ if (e->speculative)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Call is aready speculated\n");
+ nspeculated++;
+
+ /* When dumping see if we agree with speculation. */
+ if (!dump_file)
+ continue;
+ }
+ if (pointer_set_contains (bad_call_targets,
+ cache_token))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Target list is known to be useless\n");
+ nmultiple++;
+ continue;
+ }
+ for (i = 0; i < targets.length(); i++)
+ if (likely_target_p (targets[i]))
+ {
+ if (likely_target)
+ {
+ likely_target = NULL;
+ if (dump_file)
+ fprintf (dump_file, "More than one likely target\n");
+ nmultiple++;
+ break;
+ }
+ likely_target = targets[i];
+ }
+ if (!likely_target)
+ {
+ pointer_set_insert (bad_call_targets, cache_token);
+ continue;
+ }
+ /* This is reached only when dumping; check if we agree or disagree
+ with the speculation. */
+ if (e->speculative)
+ {
+ struct cgraph_edge *e2;
+ struct ipa_ref *ref;
+ cgraph_speculative_call_info (e, e2, e, ref);
+ if (cgraph_function_or_thunk_node (e2->callee, NULL)
+ == cgraph_function_or_thunk_node (likely_target, NULL))
+ {
+ fprintf (dump_file, "We agree with speculation\n");
+ nok++;
+ }
+ else
+ {
+ fprintf (dump_file, "We disagree with speculation\n");
+ nwrong++;
+ }
+ continue;
+ }
+ if (!likely_target->symbol.definition)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Target is not an definition\n");
+ nnotdefined++;
+ continue;
+ }
+ /* Do not introduce new references to external symbols. While we
+ can handle these just well, it is common for programs to
+ incorrectly with headers defining methods they are linked
+ with. */
+ if (DECL_EXTERNAL (likely_target->symbol.decl))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Target is external\n");
+ nexternal++;
+ continue;
+ }
+ if (cgraph_function_body_availability (likely_target)
+ <= AVAIL_OVERWRITABLE
+ && symtab_can_be_discarded ((symtab_node) likely_target))
+ {
+ if (dump_file)
+ fprintf (dump_file, "Target is overwritable\n");
+ noverwritable++;
+ continue;
+ }
+ else
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Speculatively devirtualizing call in %s/%i to %s/%i\n",
+ cgraph_node_name (n), n->symbol.order,
+ cgraph_node_name (likely_target),
+ likely_target->symbol.order);
+ if (!symtab_can_be_discarded ((symtab_node) likely_target))
+ likely_target = cgraph (symtab_nonoverwritable_alias ((symtab_node)likely_target));
+ nconverted++;
+ update = true;
+ cgraph_turn_edge_to_speculative
+ (e, likely_target, e->count * 8 / 10, e->frequency * 8 / 10);
+ }
+ }
+ if (update)
+ inline_update_overall_summary (n);
+ }
+ pointer_set_destroy (bad_call_targets);
+
+ if (dump_file)
+ fprintf (dump_file,
+ "%i polymorphic calls, %i devirtualized,"
+ " %i speculatively devirtualized, %i cold\n"
+ "%i have multiple targets, %i overwritable,"
+ " %i already speculated (%i agree, %i disagree),"
+ " %i external, %i not defined\n",
+ npolymorphic, ndevirtualized, nconverted, ncold,
+ nmultiple, noverwritable, nspeculated, nok, nwrong,
+ nexternal, nnotdefined);
+ return ndevirtualized ? TODO_remove_functions : 0;
+}
+
+/* Gate for IPCP optimization. */
+
+static bool
+gate_ipa_devirt (void)
+{
+ return flag_devirtualize_speculatively && !in_lto_p && optimize;
+}
+
+namespace {
+
+const pass_data pass_data_ipa_devirt =
+{
+ IPA_PASS, /* type */
+ "devirt", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_DEVIRT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_dump_symtab ), /* todo_flags_finish */
+};
+
+class pass_ipa_devirt : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_devirt(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_devirt, ctxt,
+ NULL, /* generate_summary */
+ NULL, /* write_summary */
+ NULL, /* read_summary */
+ NULL, /* write_optimization_summary */
+ NULL, /* read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ NULL, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_ipa_devirt (); }
+ unsigned int execute () { return ipa_devirt (); }
+
+}; // class pass_ipa_devirt
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_devirt (gcc::context *ctxt)
+{
+ return new pass_ipa_devirt (ctxt);
+}
+
+#include "gt-ipa-devirt.h"
diff --git a/gcc/ipa-inline-analysis.c b/gcc/ipa-inline-analysis.c
index 9a3629285fb..fb0c8382020 100644
--- a/gcc/ipa-inline-analysis.c
+++ b/gcc/ipa-inline-analysis.c
@@ -87,8 +87,8 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-inline.h"
#include "alloc-pool.h"
#include "cfgloop.h"
-#include "cfgloop.h"
#include "tree-scalar-evolution.h"
+#include "ipa-utils.h"
/* Estimate runtime of function can easilly run into huge numbers with many
nested loops. Be sure we can compute time * INLINE_SIZE_SCALE * 2 in an
@@ -337,7 +337,7 @@ add_clause (conditions conditions, struct predicate *p, clause_t clause)
and thus there is no point for looking for them. */
if (cc1->code == CHANGED || cc1->code == IS_NOT_CONSTANT)
continue;
- for (c2 = c1 + 1; c2 <= NUM_CONDITIONS; c2++)
+ for (c2 = c1 + 1; c2 < NUM_CONDITIONS; c2++)
if (clause & (1 << c2))
{
condition *cc1 =
@@ -1101,12 +1101,13 @@ inline_node_duplication_hook (struct cgraph_node *src,
known_vals.safe_grow_cleared (count);
for (i = 0; i < count; i++)
{
- tree t = ipa_get_param (parms_info, i);
struct ipa_replace_map *r;
for (j = 0; vec_safe_iterate (dst->clone.tree_map, j, &r); j++)
{
- if (r->old_tree == t && r->replace_p && !r->ref_p)
+ if (((!r->old_tree && r->parm_num == i)
+ || (r->old_tree && r->old_tree == ipa_get_param (parms_info, i)))
+ && r->replace_p && !r->ref_p)
{
known_vals[i] = r->new_tree;
break;
@@ -2714,26 +2715,46 @@ compute_inline_parameters_for_current (void)
return 0;
}
-struct gimple_opt_pass pass_inline_parameters =
-{
- {
- GIMPLE_PASS,
- "inline_param", /* name */
- OPTGROUP_INLINE, /* optinfo_flags */
- NULL, /* gate */
- compute_inline_parameters_for_current, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_INLINE_PARAMETERS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_inline_parameters =
+{
+ GIMPLE_PASS, /* type */
+ "inline_param", /* name */
+ OPTGROUP_INLINE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_INLINE_PARAMETERS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_inline_parameters : public gimple_opt_pass
+{
+public:
+ pass_inline_parameters(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_inline_parameters, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_inline_parameters (ctxt_); }
+ unsigned int execute () {
+ return compute_inline_parameters_for_current ();
+ }
+
+}; // class pass_inline_parameters
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_inline_parameters (gcc::context *ctxt)
+{
+ return new pass_inline_parameters (ctxt);
+}
+
/* Estimate benefit devirtualizing indirect edge IE, provided KNOWN_VALS and
KNOWN_BINFOS. */
@@ -3081,7 +3102,7 @@ inline_update_callee_summaries (struct cgraph_node *node, int depth)
+ callee_info->estimated_self_stack_size;
if (inline_summary (node->global.inlined_to)->estimated_stack_size < peak)
inline_summary (node->global.inlined_to)->estimated_stack_size = peak;
- cgraph_propagate_frequency (node);
+ ipa_propagate_frequency (node);
for (e = node->callees; e; e = e->next_callee)
{
if (!e->inline_failed)
@@ -3677,6 +3698,11 @@ inline_generate_summary (void)
{
struct cgraph_node *node;
+ /* When not optimizing, do not bother to analyze. Inlining is still done
+ because edge redirection needs to happen there. */
+ if (!optimize && !flag_lto && !flag_wpa)
+ return;
+
function_insertion_hook_holder =
cgraph_add_function_insertion_hook (&add_new_function, NULL);
diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c
index d421c87c222..2bada90bc8a 100644
--- a/gcc/ipa-inline-transform.c
+++ b/gcc/ipa-inline-transform.c
@@ -46,6 +46,7 @@ along with GCC; see the file COPYING3. If not see
int ncalls_inlined;
int nfunctions_inlined;
+bool speculation_removed;
/* Scale frequency of NODE edges by FREQ_SCALE. */
@@ -87,6 +88,7 @@ can_remove_node_now_p_1 (struct cgraph_node *node)
the callgraph so references can point to it. */
return (!node->symbol.address_taken
&& !ipa_ref_has_aliases_p (&node->symbol.ref_list)
+ && !node->used_as_abstract_origin
&& cgraph_can_remove_if_no_direct_calls_p (node)
/* Inlining might enable more devirtualizing, so we want to remove
those only after all devirtualizable virtual calls are processed.
@@ -133,6 +135,7 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
bool update_original, int *overall_size)
{
struct cgraph_node *inlining_into;
+ struct cgraph_edge *next;
if (e->caller->global.inlined_to)
inlining_into = e->caller->global.inlined_to;
@@ -185,9 +188,17 @@ clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
e->callee->global.inlined_to = inlining_into;
/* Recursively clone all bodies. */
- for (e = e->callee->callees; e; e = e->next_callee)
- if (!e->inline_failed)
- clone_inlined_nodes (e, duplicate, update_original, overall_size);
+ for (e = e->callee->callees; e; e = next)
+ {
+ next = e->next_callee;
+ if (!e->inline_failed)
+ clone_inlined_nodes (e, duplicate, update_original, overall_size);
+ if (e->speculative && !speculation_useful_p (e, true))
+ {
+ cgraph_resolve_speculation (e, NULL);
+ speculation_removed = true;
+ }
+ }
}
@@ -217,6 +228,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
bool predicated = inline_edge_summary (e)->predicate != NULL;
#endif
+ speculation_removed = false;
/* Don't inline inlined edges. */
gcc_assert (e->inline_failed);
/* Don't even think of inlining inline clone. */
@@ -266,6 +278,7 @@ inline_call (struct cgraph_edge *e, bool update_original,
error due to INLINE_SIZE_SCALE roudoff errors. */
gcc_assert (!update_overall_summary || !overall_size || new_edges_found
|| abs (estimated_growth - (new_size - old_size)) <= 1
+ || speculation_removed
/* FIXME: a hack. Edges with false predicate are accounted
wrong, we should remove them from callgraph. */
|| predicated);
@@ -399,7 +412,7 @@ unsigned int
inline_transform (struct cgraph_node *node)
{
unsigned int todo = 0;
- struct cgraph_edge *e;
+ struct cgraph_edge *e, *next;
/* FIXME: Currently the pass manager is adding inline transform more than
once to some clones. This needs revisiting after WPA cleanups. */
@@ -411,11 +424,15 @@ inline_transform (struct cgraph_node *node)
if (preserve_function_body_p (node))
save_inline_function_body (node);
- for (e = node->callees; e; e = e->next_callee)
- cgraph_redirect_edge_call_stmt_to_callee (e);
+ for (e = node->callees; e; e = next)
+ {
+ next = e->next_callee;
+ cgraph_redirect_edge_call_stmt_to_callee (e);
+ }
+ ipa_remove_all_references (&node->symbol.ref_list);
timevar_push (TV_INTEGRATION);
- if (node->callees)
+ if (node->callees && optimize)
todo = optimize_inline_calls (current_function_decl);
timevar_pop (TV_INTEGRATION);
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 6eede0d35fc..1e22d6eb87b 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -113,10 +113,12 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "ipa-inline.h"
#include "ipa-utils.h"
+#include "sreal.h"
/* Statistics we collect about inlining algorithm. */
static int overall_size;
static gcov_type max_count;
+static sreal max_count_real, max_relbenefit_real, half_int_min_real;
/* Return false when inlining edge E would lead to violating
limits on function unit growth or stack usage growth.
@@ -229,10 +231,13 @@ report_inline_failed_reason (struct cgraph_edge *e)
We check whether inlining is possible at all and whether
caller growth limits allow doing so.
- if REPORT is true, output reason to the dump file. */
+ if REPORT is true, output reason to the dump file.
+
+ if DISREGARD_LIMITES is true, ignore size limits.*/
static bool
-can_inline_edge_p (struct cgraph_edge *e, bool report)
+can_inline_edge_p (struct cgraph_edge *e, bool report,
+ bool disregard_limits = false)
{
bool inlinable = true;
enum availability avail;
@@ -309,6 +314,7 @@ can_inline_edge_p (struct cgraph_edge *e, bool report)
}
/* Check if caller growth allows the inlining. */
else if (!DECL_DISREGARD_INLINE_LIMITS (callee->symbol.decl)
+ && !disregard_limits
&& !lookup_attribute ("flatten",
DECL_ATTRIBUTES
(e->caller->global.inlined_to
@@ -744,6 +750,15 @@ check_caller_edge (struct cgraph_node *node, void *edge)
&& node->callers != edge);
}
+/* If NODE has a caller, return true. */
+
+static bool
+has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+{
+ if (node->callers)
+ return true;
+ return false;
+}
/* Decide if inlining NODE would reduce unit size by eliminating
the offline copy of function.
@@ -757,7 +772,7 @@ want_inline_function_to_all_callers_p (struct cgraph_node *node, bool cold)
bool has_hot_call = false;
/* Does it have callers? */
- if (!node->callers)
+ if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true))
return false;
/* Already inlined? */
if (function->global.inlined_to)
@@ -887,12 +902,26 @@ edge_badness (struct cgraph_edge *edge, bool dump)
else if (max_count)
{
+ sreal tmp, relbenefit_real, growth_real;
int relbenefit = relative_time_benefit (callee_info, edge, edge_time);
- badness =
- ((int)
- ((double) edge->count * INT_MIN / 2 / max_count / RELATIVE_TIME_BENEFIT_RANGE) *
- relbenefit) / growth;
-
+
+ sreal_init(&relbenefit_real, relbenefit, 0);
+ sreal_init(&growth_real, growth, 0);
+
+ /* relative_edge_count. */
+ sreal_init (&tmp, edge->count, 0);
+ sreal_div (&tmp, &tmp, &max_count_real);
+
+ /* relative_time_benefit. */
+ sreal_mul (&tmp, &tmp, &relbenefit_real);
+ sreal_div (&tmp, &tmp, &max_relbenefit_real);
+
+ /* growth_f_caller. */
+ sreal_mul (&tmp, &tmp, &half_int_min_real);
+ sreal_div (&tmp, &tmp, &growth_real);
+
+ badness = -1 * sreal_to_int (&tmp);
+
/* Be sure that insanity of the profile won't lead to increasing counts
in the scalling and thus to overflow in the computation above. */
gcc_assert (max_count >= edge->count);
@@ -1388,6 +1417,92 @@ add_new_edges_to_heap (fibheap_t heap, vec<cgraph_edge_p> new_edges)
}
}
+/* Remove EDGE from the fibheap. */
+
+static void
+heap_edge_removal_hook (struct cgraph_edge *e, void *data)
+{
+ if (e->callee)
+ reset_node_growth_cache (e->callee);
+ if (e->aux)
+ {
+ fibheap_delete_node ((fibheap_t)data, (fibnode_t)e->aux);
+ e->aux = NULL;
+ }
+}
+
+/* Return true if speculation of edge E seems useful.
+ If ANTICIPATE_INLINING is true, be conservative and hope that E
+ may get inlined. */
+
+bool
+speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining)
+{
+ enum availability avail;
+ struct cgraph_node *target = cgraph_function_or_thunk_node (e->callee, &avail);
+ struct cgraph_edge *direct, *indirect;
+ struct ipa_ref *ref;
+
+ gcc_assert (e->speculative && !e->indirect_unknown_callee);
+
+ if (!cgraph_maybe_hot_edge_p (e))
+ return false;
+
+ /* See if IP optimizations found something potentially useful about the
+ function. For now we look only for CONST/PURE flags. Almost everything
+ else we propagate is useless. */
+ if (avail >= AVAIL_AVAILABLE)
+ {
+ int ecf_flags = flags_from_decl_or_type (target->symbol.decl);
+ if (ecf_flags & ECF_CONST)
+ {
+ cgraph_speculative_call_info (e, direct, indirect, ref);
+ if (!(indirect->indirect_info->ecf_flags & ECF_CONST))
+ return true;
+ }
+ else if (ecf_flags & ECF_PURE)
+ {
+ cgraph_speculative_call_info (e, direct, indirect, ref);
+ if (!(indirect->indirect_info->ecf_flags & ECF_PURE))
+ return true;
+ }
+ }
+ /* If we did not managed to inline the function nor redirect
+ to an ipa-cp clone (that are seen by having local flag set),
+ it is probably pointless to inline it unless hardware is missing
+ indirect call predictor. */
+ if (!anticipate_inlining && e->inline_failed && !target->local.local)
+ return false;
+ /* For overwritable targets there is not much to do. */
+ if (e->inline_failed && !can_inline_edge_p (e, false, true))
+ return false;
+ /* OK, speculation seems interesting. */
+ return true;
+}
+
+/* We know that EDGE is not going to be inlined.
+ See if we can remove speculation. */
+
+static void
+resolve_noninline_speculation (fibheap_t edge_heap, struct cgraph_edge *edge)
+{
+ if (edge->speculative && !speculation_useful_p (edge, false))
+ {
+ struct cgraph_node *node = edge->caller;
+ struct cgraph_node *where = node->global.inlined_to
+ ? node->global.inlined_to : node;
+ bitmap updated_nodes = BITMAP_ALLOC (NULL);
+
+ cgraph_resolve_speculation (edge, NULL);
+ reset_edge_caches (where);
+ inline_update_overall_summary (where);
+ update_caller_keys (edge_heap, where,
+ updated_nodes, NULL);
+ update_callee_keys (edge_heap, where,
+ updated_nodes);
+ BITMAP_FREE (updated_nodes);
+ }
+}
/* We use greedy algorithm for inlining of small functions:
All inline candidates are put into prioritized heap ordered in
@@ -1406,10 +1521,14 @@ inline_small_functions (void)
vec<cgraph_edge_p> new_indirect_edges = vNULL;
int initial_size = 0;
struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+ struct cgraph_edge_hook_list *edge_removal_hook_holder;
if (flag_indirect_inlining)
new_indirect_edges.create (8);
+ edge_removal_hook_holder
+ = cgraph_add_edge_removal_hook (&heap_edge_removal_hook, edge_heap);
+
/* Compute overall unit size and other global parameters used by badness
metrics. */
@@ -1448,6 +1567,9 @@ inline_small_functions (void)
if (max_count < edge->count)
max_count = edge->count;
}
+ sreal_init (&max_count_real, max_count, 0);
+ sreal_init (&max_relbenefit_real, RELATIVE_TIME_BENEFIT_RANGE, 0);
+ sreal_init (&half_int_min_real, INT_MAX / 2, 0);
ipa_free_postorder_info ();
initialize_growth_caches ();
@@ -1463,14 +1585,19 @@ inline_small_functions (void)
/* Populate the heeap with all edges we might inline. */
FOR_EACH_DEFINED_FUNCTION (node)
- if (!node->global.inlined_to)
- {
- if (dump_file)
- fprintf (dump_file, "Enqueueing calls of %s/%i.\n",
- cgraph_node_name (node), node->symbol.order);
+ {
+ bool update = false;
+ struct cgraph_edge *next;
- for (edge = node->callers; edge; edge = edge->next_caller)
+ if (dump_file)
+ fprintf (dump_file, "Enqueueing calls in %s/%i.\n",
+ cgraph_node_name (node), node->symbol.order);
+
+ for (edge = node->callees; edge; edge = next)
+ {
+ next = edge->next_callee;
if (edge->inline_failed
+ && !edge->aux
&& can_inline_edge_p (edge, true)
&& want_inline_small_function_p (edge, true)
&& edge->inline_failed)
@@ -1478,7 +1605,24 @@ inline_small_functions (void)
gcc_assert (!edge->aux);
update_edge_key (edge_heap, edge);
}
- }
+ if (edge->speculative && !speculation_useful_p (edge, edge->aux != NULL))
+ {
+ cgraph_resolve_speculation (edge, NULL);
+ update = true;
+ }
+ }
+ if (update)
+ {
+ struct cgraph_node *where = node->global.inlined_to
+ ? node->global.inlined_to : node;
+ inline_update_overall_summary (where);
+ reset_node_growth_cache (where);
+ reset_edge_caches (where);
+ update_caller_keys (edge_heap, where,
+ updated_nodes, NULL);
+ bitmap_clear (updated_nodes);
+ }
+ }
gcc_assert (in_lto_p
|| !max_count
@@ -1519,7 +1663,10 @@ inline_small_functions (void)
}
if (!can_inline_edge_p (edge, true))
- continue;
+ {
+ resolve_noninline_speculation (edge_heap, edge);
+ continue;
+ }
callee = cgraph_function_or_thunk_node (edge->callee, NULL);
growth = estimate_edge_growth (edge);
@@ -1553,11 +1700,15 @@ inline_small_functions (void)
{
edge->inline_failed = CIF_INLINE_UNIT_GROWTH_LIMIT;
report_inline_failed_reason (edge);
+ resolve_noninline_speculation (edge_heap, edge);
continue;
}
if (!want_inline_small_function_p (edge, true))
- continue;
+ {
+ resolve_noninline_speculation (edge_heap, edge);
+ continue;
+ }
/* Heuristics for inlining small functions works poorly for
recursive calls where we do efect similar to loop unrolling.
@@ -1573,6 +1724,7 @@ inline_small_functions (void)
? &new_indirect_edges : NULL))
{
edge->inline_failed = CIF_RECURSIVE_INLINING;
+ resolve_noninline_speculation (edge_heap, edge);
continue;
}
reset_edge_caches (where);
@@ -1581,6 +1733,7 @@ inline_small_functions (void)
if (flag_indirect_inlining)
add_new_edges_to_heap (edge_heap, new_indirect_edges);
update_callee_keys (edge_heap, where, updated_nodes);
+ bitmap_clear (updated_nodes);
}
else
{
@@ -1606,6 +1759,7 @@ inline_small_functions (void)
edge->inline_failed
= (DECL_DISREGARD_INLINE_LIMITS (edge->callee->symbol.decl)
? CIF_RECURSIVE_INLINING : CIF_UNSPECIFIED);
+ resolve_noninline_speculation (edge_heap, edge);
continue;
}
else if (depth && dump_file)
@@ -1663,6 +1817,7 @@ inline_small_functions (void)
initial_size, overall_size,
initial_size ? overall_size * 100 / (initial_size) - 100: 0);
BITMAP_FREE (updated_nodes);
+ cgraph_remove_edge_removal_hook (edge_removal_hook_holder);
}
/* Flatten NODE. Performed both during early inlining and
@@ -1746,6 +1901,60 @@ flatten_function (struct cgraph_node *node, bool early)
inline_update_overall_summary (node);
}
+/* Count number of callers of NODE and store it into DATA (that
+ points to int. Worker for cgraph_for_node_and_aliases. */
+
+static bool
+sum_callers (struct cgraph_node *node, void *data)
+{
+ struct cgraph_edge *e;
+ int *num_calls = (int *)data;
+
+ for (e = node->callers; e; e = e->next_caller)
+ (*num_calls)++;
+ return false;
+}
+
+/* Inline NODE to all callers. Worker for cgraph_for_node_and_aliases.
+ DATA points to number of calls originally found so we avoid infinite
+ recursion. */
+
+static bool
+inline_to_all_callers (struct cgraph_node *node, void *data)
+{
+ int *num_calls = (int *)data;
+ while (node->callers && !node->global.inlined_to)
+ {
+ struct cgraph_node *caller = node->callers->caller;
+
+ if (dump_file)
+ {
+ fprintf (dump_file,
+ "\nInlining %s size %i.\n",
+ cgraph_node_name (node),
+ inline_summary (node)->size);
+ fprintf (dump_file,
+ " Called once from %s %i insns.\n",
+ cgraph_node_name (node->callers->caller),
+ inline_summary (node->callers->caller)->size);
+ }
+
+ inline_call (node->callers, true, NULL, NULL, true);
+ if (dump_file)
+ fprintf (dump_file,
+ " Inlined into %s which now has %i size\n",
+ cgraph_node_name (caller),
+ inline_summary (caller)->size);
+ if (!(*num_calls)--)
+ {
+ if (dump_file)
+ fprintf (dump_file, "New calls found; giving up.\n");
+ break;
+ }
+ }
+ return false;
+}
+
/* Decide on the inlining. We do so in the topological order to avoid
expenses on updating data structures. */
@@ -1757,6 +1966,11 @@ ipa_inline (void)
struct cgraph_node **order =
XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
int i;
+ int cold;
+ bool remove_functions = false;
+
+ if (!optimize)
+ return 0;
if (in_lto_p && optimize)
ipa_update_after_lto_read ();
@@ -1804,69 +2018,60 @@ ipa_inline (void)
code size will shrink because the out-of-line copy is eliminated.
We do this regardless on the callee size as long as function growth limits
are met. */
- if (flag_inline_functions_called_once)
+ if (dump_file)
+ fprintf (dump_file,
+ "\nDeciding on functions to be inlined into all callers and removing useless speculations:\n");
+
+ /* Inlining one function called once has good chance of preventing
+ inlining other function into the same callee. Ideally we should
+ work in priority order, but probably inlining hot functions first
+ is good cut without the extra pain of maintaining the queue.
+
+ ??? this is not really fitting the bill perfectly: inlining function
+ into callee often leads to better optimization of callee due to
+ increased context for optimization.
+ For example if main() function calls a function that outputs help
+ and then function that does the main optmization, we should inline
+ the second with priority even if both calls are cold by themselves.
+
+ We probably want to implement new predicate replacing our use of
+ maybe_hot_edge interpreted as maybe_hot_edge || callee is known
+ to be hot. */
+ for (cold = 0; cold <= 1; cold ++)
{
- int cold;
- if (dump_file)
- fprintf (dump_file,
- "\nDeciding on functions to be inlined into all callers:\n");
-
- /* Inlining one function called once has good chance of preventing
- inlining other function into the same callee. Ideally we should
- work in priority order, but probably inlining hot functions first
- is good cut without the extra pain of maintaining the queue.
-
- ??? this is not really fitting the bill perfectly: inlining function
- into callee often leads to better optimization of callee due to
- increased context for optimization.
- For example if main() function calls a function that outputs help
- and then function that does the main optmization, we should inline
- the second with priority even if both calls are cold by themselves.
-
- We probably want to implement new predicate replacing our use of
- maybe_hot_edge interpreted as maybe_hot_edge || callee is known
- to be hot. */
- for (cold = 0; cold <= 1; cold ++)
+ FOR_EACH_DEFINED_FUNCTION (node)
{
- FOR_EACH_DEFINED_FUNCTION (node)
+ struct cgraph_edge *edge, *next;
+ bool update=false;
+
+ for (edge = node->callees; edge; edge = next)
{
- if (want_inline_function_to_all_callers_p (node, cold))
+ next = edge->next_callee;
+ if (edge->speculative && !speculation_useful_p (edge, false))
{
- int num_calls = 0;
- struct cgraph_edge *e;
- for (e = node->callers; e; e = e->next_caller)
- num_calls++;
- while (node->callers && !node->global.inlined_to)
- {
- struct cgraph_node *caller = node->callers->caller;
-
- if (dump_file)
- {
- fprintf (dump_file,
- "\nInlining %s size %i.\n",
- cgraph_node_name (node),
- inline_summary (node)->size);
- fprintf (dump_file,
- " Called once from %s %i insns.\n",
- cgraph_node_name (node->callers->caller),
- inline_summary (node->callers->caller)->size);
- }
-
- inline_call (node->callers, true, NULL, NULL, true);
- if (dump_file)
- fprintf (dump_file,
- " Inlined into %s which now has %i size\n",
- cgraph_node_name (caller),
- inline_summary (caller)->size);
- if (!num_calls--)
- {
- if (dump_file)
- fprintf (dump_file, "New calls found; giving up.\n");
- break;
- }
- }
+ cgraph_resolve_speculation (edge, NULL);
+ update = true;
+ remove_functions = true;
}
}
+ if (update)
+ {
+ struct cgraph_node *where = node->global.inlined_to
+ ? node->global.inlined_to : node;
+ reset_node_growth_cache (where);
+ reset_edge_caches (where);
+ inline_update_overall_summary (where);
+ }
+ if (flag_inline_functions_called_once
+ && want_inline_function_to_all_callers_p (node, cold))
+ {
+ int num_calls = 0;
+ cgraph_for_node_and_aliases (node, sum_callers,
+ &num_calls, true);
+ cgraph_for_node_and_aliases (node, inline_to_all_callers,
+ &num_calls, true);
+ remove_functions = true;
+ }
}
}
@@ -1884,7 +2089,7 @@ ipa_inline (void)
/* In WPA we use inline summaries for partitioning process. */
if (!flag_wpa)
inline_free_summary ();
- return 0;
+ return remove_functions ? TODO_remove_functions : 0;
}
/* Inline always-inline function calls in NODE. */
@@ -2011,6 +2216,7 @@ early_inliner (void)
#ifdef ENABLE_CHECKING
verify_cgraph_node (node);
#endif
+ ipa_remove_all_references (&node->symbol.ref_list);
/* Even when not optimizing or not inlining inline always-inline
functions. */
@@ -2086,65 +2292,99 @@ early_inliner (void)
return todo;
}
-struct gimple_opt_pass pass_early_inline =
+namespace {
+
+const pass_data pass_data_early_inline =
{
- {
- GIMPLE_PASS,
- "einline", /* name */
- OPTGROUP_INLINE, /* optinfo_flags */
- NULL, /* gate */
- early_inliner, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_EARLY_INLINING, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "einline", /* name */
+ OPTGROUP_INLINE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_EARLY_INLINING, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_early_inline : public gimple_opt_pass
+{
+public:
+ pass_early_inline(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_early_inline, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return early_inliner (); }
+
+}; // class pass_early_inline
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_early_inline (gcc::context *ctxt)
+{
+ return new pass_early_inline (ctxt);
+}
+
/* When to run IPA inlining. Inlining of always-inline functions
happens during early inlining.
- Enable inlining unconditoinally at -flto. We need size estimates to
- drive partitioning. */
+ Enable inlining unconditoinally, because callgraph redirection
+ happens here. */
static bool
gate_ipa_inline (void)
{
- return optimize || flag_lto || flag_wpa;
+ return true;
}
-struct ipa_opt_pass_d pass_ipa_inline =
+namespace {
+
+const pass_data pass_data_ipa_inline =
{
- {
- IPA_PASS,
- "inline", /* name */
- OPTGROUP_INLINE, /* optinfo_flags */
- gate_ipa_inline, /* gate */
- ipa_inline, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_INLINING, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- TODO_remove_functions, /* todo_flags_finish */
- TODO_dump_symtab
- | TODO_remove_functions /* todo_flags_finish */
- },
- inline_generate_summary, /* generate_summary */
- inline_write_summary, /* write_summary */
- inline_read_summary, /* read_summary */
- NULL, /* write_optimization_summary */
- NULL, /* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- inline_transform, /* function_transform */
- NULL, /* variable_transform */
+ IPA_PASS, /* type */
+ "inline", /* name */
+ OPTGROUP_INLINE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_INLINING, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ TODO_remove_functions, /* todo_flags_start */
+ ( TODO_dump_symtab ), /* todo_flags_finish */
};
+
+class pass_ipa_inline : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_inline(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_inline, ctxt,
+ inline_generate_summary, /* generate_summary */
+ inline_write_summary, /* write_summary */
+ inline_read_summary, /* read_summary */
+ NULL, /* write_optimization_summary */
+ NULL, /* read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ inline_transform, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_ipa_inline (); }
+ unsigned int execute () { return ipa_inline (); }
+
+}; // class pass_ipa_inline
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_inline (gcc::context *ctxt)
+{
+ return new pass_ipa_inline (ctxt);
+}
diff --git a/gcc/ipa-inline.h b/gcc/ipa-inline.h
index b34cb526bad..000d1abc968 100644
--- a/gcc/ipa-inline.h
+++ b/gcc/ipa-inline.h
@@ -226,6 +226,7 @@ inline_hints do_estimate_edge_hints (struct cgraph_edge *edge);
void initialize_growth_caches (void);
void free_growth_caches (void);
void compute_inline_parameters (struct cgraph_node *, bool);
+bool speculation_useful_p (struct cgraph_edge *e, bool anticipate_inlining);
/* In ipa-inline-transform.c */
bool inline_call (struct cgraph_edge *, bool, vec<cgraph_edge_p> *, int *, bool);
diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c
new file mode 100644
index 00000000000..2b22333d1b9
--- /dev/null
+++ b/gcc/ipa-profile.c
@@ -0,0 +1,754 @@
+/* Basic IPA optimizations based on profile.
+ Copyright (C) 2003-2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* ipa-profile pass implements the following analysis propagating profille
+ inter-procedurally.
+
+ - Count histogram construction. This is a histogram analyzing how much
+ time is spent executing statements with a given execution count read
+ from profile feedback. This histogram is complette only with LTO,
+ otherwise it contains information only about the current unit.
+
+ Similar histogram is also estimated by coverage runtime. This histogram
+ is not dependent on LTO, but it suffers from various defects; first
+ gcov runtime is not weighting individual basic block by estimated execution
+ time and second the merging of multiple runs makes assumption that the
+ histogram distribution did not change. Consequentely histogram constructed
+ here may be more precise.
+
+ The information is used to set hot/cold thresholds.
+ - Next speculative indirect call resolution is performed: the local
+ profile pass assigns profile-id to each function and provide us with a
+ histogram specifying the most common target. We look up the callgraph
+ node corresponding to the target and produce a speculative call.
+
+ This call may or may not survive through IPA optimization based on decision
+ of inliner.
+ - Finally we propagate the following flags: unlikely executed, executed
+ once, executed at startup and executed at exit. These flags are used to
+ control code size/performance threshold and and code placement (by producing
+ .text.unlikely/.text.hot/.text.startup/.text.exit subsections). */
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "cgraph.h"
+#include "tree-pass.h"
+#include "gimple.h"
+#include "ggc.h"
+#include "flags.h"
+#include "target.h"
+#include "tree-iterator.h"
+#include "ipa-utils.h"
+#include "hash-table.h"
+#include "profile.h"
+#include "params.h"
+#include "value-prof.h"
+#include "alloc-pool.h"
+#include "tree-inline.h"
+#include "lto-streamer.h"
+#include "data-streamer.h"
+#include "ipa-inline.h"
+
+/* Entry in the histogram. */
+
+struct histogram_entry
+{
+ gcov_type count;
+ int time;
+ int size;
+};
+
+/* Histogram of profile values.
+ The histogram is represented as an ordered vector of entries allocated via
+ histogram_pool. During construction a separate hashtable is kept to lookup
+ duplicate entries. */
+
+vec<histogram_entry *> histogram;
+static alloc_pool histogram_pool;
+
+/* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */
+
+struct histogram_hash : typed_noop_remove <histogram_entry>
+{
+ typedef histogram_entry value_type;
+ typedef histogram_entry compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline int equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+histogram_hash::hash (const histogram_entry *val)
+{
+ return val->count;
+}
+
+inline int
+histogram_hash::equal (const histogram_entry *val, const histogram_entry *val2)
+{
+ return val->count == val2->count;
+}
+
+/* Account TIME and SIZE executed COUNT times into HISTOGRAM.
+ HASHTABLE is the on-side hash kept to avoid duplicates. */
+
+static void
+account_time_size (hash_table <histogram_hash> hashtable,
+ vec<histogram_entry *> &histogram,
+ gcov_type count, int time, int size)
+{
+ histogram_entry key = {count, 0, 0};
+ histogram_entry **val = hashtable.find_slot (&key, INSERT);
+
+ if (!*val)
+ {
+ *val = (histogram_entry *) pool_alloc (histogram_pool);
+ **val = key;
+ histogram.safe_push (*val);
+ }
+ (*val)->time += time;
+ (*val)->size += size;
+}
+
+int
+cmp_counts (const void *v1, const void *v2)
+{
+ const histogram_entry *h1 = *(const histogram_entry * const *)v1;
+ const histogram_entry *h2 = *(const histogram_entry * const *)v2;
+ if (h1->count < h2->count)
+ return 1;
+ if (h1->count > h2->count)
+ return -1;
+ return 0;
+}
+
+/* Dump HISTOGRAM to FILE. */
+
+static void
+dump_histogram (FILE *file, vec<histogram_entry *> histogram)
+{
+ unsigned int i;
+ gcov_type overall_time = 0, cumulated_time = 0, cumulated_size = 0, overall_size = 0;
+
+ fprintf (dump_file, "Histogram:\n");
+ for (i = 0; i < histogram.length (); i++)
+ {
+ overall_time += histogram[i]->count * histogram[i]->time;
+ overall_size += histogram[i]->size;
+ }
+ if (!overall_time)
+ overall_time = 1;
+ if (!overall_size)
+ overall_size = 1;
+ for (i = 0; i < histogram.length (); i++)
+ {
+ cumulated_time += histogram[i]->count * histogram[i]->time;
+ cumulated_size += histogram[i]->size;
+ fprintf (file, " "HOST_WIDEST_INT_PRINT_DEC": time:%i (%2.2f) size:%i (%2.2f)\n",
+ (HOST_WIDEST_INT) histogram[i]->count,
+ histogram[i]->time,
+ cumulated_time * 100.0 / overall_time,
+ histogram[i]->size,
+ cumulated_size * 100.0 / overall_size);
+ }
+}
+
+/* Collect histogram from CFG profiles. */
+
+static void
+ipa_profile_generate_summary (void)
+{
+ struct cgraph_node *node;
+ gimple_stmt_iterator gsi;
+ hash_table <histogram_hash> hashtable;
+ basic_block bb;
+
+ hashtable.create (10);
+ histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
+ 10);
+
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
+ FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->symbol.decl))
+ {
+ int time = 0;
+ int size = 0;
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (gimple_code (stmt) == GIMPLE_CALL
+ && !gimple_call_fndecl (stmt))
+ {
+ histogram_value h;
+ h = gimple_histogram_value_of_type
+ (DECL_STRUCT_FUNCTION (node->symbol.decl),
+ stmt, HIST_TYPE_INDIR_CALL);
+ /* No need to do sanity check: gimple_ic_transform already
+ takes away bad histograms. */
+ if (h)
+ {
+ /* counter 0 is target, counter 1 is number of execution we called target,
+ counter 2 is total number of executions. */
+ if (h->hvalue.counters[2])
+ {
+ struct cgraph_edge * e = cgraph_edge (node, stmt);
+ e->indirect_info->common_target_id
+ = h->hvalue.counters [0];
+ e->indirect_info->common_target_probability
+ = GCOV_COMPUTE_SCALE (h->hvalue.counters [1], h->hvalue.counters [2]);
+ if (e->indirect_info->common_target_probability > REG_BR_PROB_BASE)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Probability capped to 1\n");
+ e->indirect_info->common_target_probability = REG_BR_PROB_BASE;
+ }
+ }
+ gimple_remove_histogram_value (DECL_STRUCT_FUNCTION (node->symbol.decl),
+ stmt, h);
+ }
+ }
+ time += estimate_num_insns (stmt, &eni_time_weights);
+ size += estimate_num_insns (stmt, &eni_size_weights);
+ }
+ account_time_size (hashtable, histogram, bb->count, time, size);
+ }
+ hashtable.dispose ();
+ histogram.qsort (cmp_counts);
+}
+
+/* Serialize the ipa info for lto. */
+
+static void
+ipa_profile_write_summary (void)
+{
+ struct lto_simple_output_block *ob
+ = lto_create_simple_output_block (LTO_section_ipa_profile);
+ unsigned int i;
+
+ streamer_write_uhwi_stream (ob->main_stream, histogram.length());
+ for (i = 0; i < histogram.length (); i++)
+ {
+ streamer_write_gcov_count_stream (ob->main_stream, histogram[i]->count);
+ streamer_write_uhwi_stream (ob->main_stream, histogram[i]->time);
+ streamer_write_uhwi_stream (ob->main_stream, histogram[i]->size);
+ }
+ lto_destroy_simple_output_block (ob);
+}
+
+/* Deserialize the ipa info for lto. */
+
+static void
+ipa_profile_read_summary (void)
+{
+ struct lto_file_decl_data ** file_data_vec
+ = lto_get_file_decl_data ();
+ struct lto_file_decl_data * file_data;
+ hash_table <histogram_hash> hashtable;
+ int j = 0;
+
+ hashtable.create (10);
+ histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
+ 10);
+
+ while ((file_data = file_data_vec[j++]))
+ {
+ const char *data;
+ size_t len;
+ struct lto_input_block *ib
+ = lto_create_simple_input_block (file_data,
+ LTO_section_ipa_profile,
+ &data, &len);
+ if (ib)
+ {
+ unsigned int num = streamer_read_uhwi (ib);
+ unsigned int n;
+ for (n = 0; n < num; n++)
+ {
+ gcov_type count = streamer_read_gcov_count (ib);
+ int time = streamer_read_uhwi (ib);
+ int size = streamer_read_uhwi (ib);
+ account_time_size (hashtable, histogram,
+ count, time, size);
+ }
+ lto_destroy_simple_input_block (file_data,
+ LTO_section_ipa_profile,
+ ib, data, len);
+ }
+ }
+ hashtable.dispose ();
+ histogram.qsort (cmp_counts);
+}
+
+/* Data used by ipa_propagate_frequency. */
+
+struct ipa_propagate_frequency_data
+{
+ bool maybe_unlikely_executed;
+ bool maybe_executed_once;
+ bool only_called_at_startup;
+ bool only_called_at_exit;
+};
+
+/* Worker for ipa_propagate_frequency_1. */
+
+static bool
+ipa_propagate_frequency_1 (struct cgraph_node *node, void *data)
+{
+ struct ipa_propagate_frequency_data *d;
+ struct cgraph_edge *edge;
+
+ d = (struct ipa_propagate_frequency_data *)data;
+ for (edge = node->callers;
+ edge && (d->maybe_unlikely_executed || d->maybe_executed_once
+ || d->only_called_at_startup || d->only_called_at_exit);
+ edge = edge->next_caller)
+ {
+ if (edge->caller != node)
+ {
+ d->only_called_at_startup &= edge->caller->only_called_at_startup;
+ /* It makes sense to put main() together with the static constructors.
+ It will be executed for sure, but rest of functions called from
+ main are definitely not at startup only. */
+ if (MAIN_NAME_P (DECL_NAME (edge->caller->symbol.decl)))
+ d->only_called_at_startup = 0;
+ d->only_called_at_exit &= edge->caller->only_called_at_exit;
+ }
+
+ /* When profile feedback is available, do not try to propagate too hard;
+ counts are already good guide on function frequencies and roundoff
+ errors can make us to push function into unlikely section even when
+ it is executed by the train run. Transfer the function only if all
+ callers are unlikely executed. */
+ if (profile_info && flag_branch_probabilities
+ && (edge->caller->frequency != NODE_FREQUENCY_UNLIKELY_EXECUTED
+ || (edge->caller->global.inlined_to
+ && edge->caller->global.inlined_to->frequency
+ != NODE_FREQUENCY_UNLIKELY_EXECUTED)))
+ d->maybe_unlikely_executed = false;
+ if (!edge->frequency)
+ continue;
+ switch (edge->caller->frequency)
+ {
+ case NODE_FREQUENCY_UNLIKELY_EXECUTED:
+ break;
+ case NODE_FREQUENCY_EXECUTED_ONCE:
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Called by %s that is executed once\n",
+ cgraph_node_name (edge->caller));
+ d->maybe_unlikely_executed = false;
+ if (inline_edge_summary (edge)->loop_depth)
+ {
+ d->maybe_executed_once = false;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Called in loop\n");
+ }
+ break;
+ case NODE_FREQUENCY_HOT:
+ case NODE_FREQUENCY_NORMAL:
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, " Called by %s that is normal or hot\n",
+ cgraph_node_name (edge->caller));
+ d->maybe_unlikely_executed = false;
+ d->maybe_executed_once = false;
+ break;
+ }
+ }
+ return edge != NULL;
+}
+
+/* Return ture if NODE contains hot calls. */
+
+bool
+contains_hot_call_p (struct cgraph_node *node)
+{
+ struct cgraph_edge *e;
+ for (e = node->callees; e; e = e->next_callee)
+ if (cgraph_maybe_hot_edge_p (e))
+ return true;
+ else if (!e->inline_failed
+ && contains_hot_call_p (e->callee))
+ return true;
+ for (e = node->indirect_calls; e; e = e->next_callee)
+ if (cgraph_maybe_hot_edge_p (e))
+ return true;
+ return false;
+}
+
+/* See if the frequency of NODE can be updated based on frequencies of its
+ callers. */
+bool
+ipa_propagate_frequency (struct cgraph_node *node)
+{
+ struct ipa_propagate_frequency_data d = {true, true, true, true};
+ bool changed = false;
+
+ /* We can not propagate anything useful about externally visible functions
+ nor about virtuals. */
+ if (!node->local.local
+ || node->symbol.alias
+ || (flag_devirtualize && DECL_VIRTUAL_P (node->symbol.decl)))
+ return false;
+ gcc_assert (node->symbol.analyzed);
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Processing frequency %s\n", cgraph_node_name (node));
+
+ cgraph_for_node_and_aliases (node, ipa_propagate_frequency_1, &d, true);
+
+ if ((d.only_called_at_startup && !d.only_called_at_exit)
+ && !node->only_called_at_startup)
+ {
+ node->only_called_at_startup = true;
+ if (dump_file)
+ fprintf (dump_file, "Node %s promoted to only called at startup.\n",
+ cgraph_node_name (node));
+ changed = true;
+ }
+ if ((d.only_called_at_exit && !d.only_called_at_startup)
+ && !node->only_called_at_exit)
+ {
+ node->only_called_at_exit = true;
+ if (dump_file)
+ fprintf (dump_file, "Node %s promoted to only called at exit.\n",
+ cgraph_node_name (node));
+ changed = true;
+ }
+
+ /* With profile we can decide on hot/normal based on count. */
+ if (node->count)
+ {
+ bool hot = false;
+ if (node->count >= get_hot_bb_threshold ())
+ hot = true;
+ if (!hot)
+ hot |= contains_hot_call_p (node);
+ if (hot)
+ {
+ if (node->frequency != NODE_FREQUENCY_HOT)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Node %s promoted to hot.\n",
+ cgraph_node_name (node));
+ node->frequency = NODE_FREQUENCY_HOT;
+ return true;
+ }
+ return false;
+ }
+ else if (node->frequency == NODE_FREQUENCY_HOT)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Node %s reduced to normal.\n",
+ cgraph_node_name (node));
+ node->frequency = NODE_FREQUENCY_NORMAL;
+ changed = true;
+ }
+ }
+ /* These come either from profile or user hints; never update them. */
+ if (node->frequency == NODE_FREQUENCY_HOT
+ || node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
+ return changed;
+ if (d.maybe_unlikely_executed)
+ {
+ node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
+ if (dump_file)
+ fprintf (dump_file, "Node %s promoted to unlikely executed.\n",
+ cgraph_node_name (node));
+ changed = true;
+ }
+ else if (d.maybe_executed_once && node->frequency != NODE_FREQUENCY_EXECUTED_ONCE)
+ {
+ node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
+ if (dump_file)
+ fprintf (dump_file, "Node %s promoted to executed once.\n",
+ cgraph_node_name (node));
+ changed = true;
+ }
+ return changed;
+}
+
+/* Simple ipa profile pass propagating frequencies across the callgraph. */
+
+static unsigned int
+ipa_profile (void)
+{
+ struct cgraph_node **order;
+ struct cgraph_edge *e;
+ int order_pos;
+ bool something_changed = false;
+ int i;
+ gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0;
+ struct cgraph_node *n,*n2;
+ int nindirect = 0, ncommon = 0, nunknown = 0, nuseless = 0, nconverted = 0;
+ bool node_map_initialized = false;
+
+ if (dump_file)
+ dump_histogram (dump_file, histogram);
+ for (i = 0; i < (int)histogram.length (); i++)
+ {
+ overall_time += histogram[i]->count * histogram[i]->time;
+ overall_size += histogram[i]->size;
+ }
+ if (overall_time)
+ {
+ gcov_type threshold;
+
+ gcc_assert (overall_size);
+ if (dump_file)
+ {
+ gcov_type min, cumulated_time = 0, cumulated_size = 0;
+
+ fprintf (dump_file, "Overall time: "HOST_WIDEST_INT_PRINT_DEC"\n",
+ (HOST_WIDEST_INT)overall_time);
+ min = get_hot_bb_threshold ();
+ for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min;
+ i++)
+ {
+ cumulated_time += histogram[i]->count * histogram[i]->time;
+ cumulated_size += histogram[i]->size;
+ }
+ fprintf (dump_file, "GCOV min count: "HOST_WIDEST_INT_PRINT_DEC
+ " Time:%3.2f%% Size:%3.2f%%\n",
+ (HOST_WIDEST_INT)min,
+ cumulated_time * 100.0 / overall_time,
+ cumulated_size * 100.0 / overall_size);
+ }
+ cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
+ threshold = 0;
+ for (i = 0; cumulated < cutoff; i++)
+ {
+ cumulated += histogram[i]->count * histogram[i]->time;
+ threshold = histogram[i]->count;
+ }
+ if (!threshold)
+ threshold = 1;
+ if (dump_file)
+ {
+ gcov_type cumulated_time = 0, cumulated_size = 0;
+
+ for (i = 0;
+ i < (int)histogram.length () && histogram[i]->count >= threshold;
+ i++)
+ {
+ cumulated_time += histogram[i]->count * histogram[i]->time;
+ cumulated_size += histogram[i]->size;
+ }
+ fprintf (dump_file, "Determined min count: "HOST_WIDEST_INT_PRINT_DEC
+ " Time:%3.2f%% Size:%3.2f%%\n",
+ (HOST_WIDEST_INT)threshold,
+ cumulated_time * 100.0 / overall_time,
+ cumulated_size * 100.0 / overall_size);
+ }
+ if (threshold > get_hot_bb_threshold ()
+ || in_lto_p)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Threshold updated.\n");
+ set_hot_bb_threshold (threshold);
+ }
+ }
+ histogram.release();
+ free_alloc_pool (histogram_pool);
+
+ /* Produce speculative calls: we saved common traget from porfiling into
+ e->common_target_id. Now, at link time, we can look up corresponding
+ function node and produce speculative call. */
+
+ FOR_EACH_DEFINED_FUNCTION (n)
+ {
+ bool update = false;
+
+ for (e = n->indirect_calls; e; e = e->next_callee)
+ {
+ if (n->count)
+ nindirect++;
+ if (e->indirect_info->common_target_id)
+ {
+ if (!node_map_initialized)
+ init_node_map (false);
+ node_map_initialized = true;
+ ncommon++;
+ n2 = find_func_by_profile_id (e->indirect_info->common_target_id);
+ if (n2)
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "Indirect call -> direct call from"
+ " other module %s/%i => %s/%i, prob %3.2f\n",
+ xstrdup (cgraph_node_name (n)), n->symbol.order,
+ xstrdup (cgraph_node_name (n2)), n2->symbol.order,
+ e->indirect_info->common_target_probability
+ / (float)REG_BR_PROB_BASE);
+ }
+ if (e->indirect_info->common_target_probability
+ < REG_BR_PROB_BASE / 2)
+ {
+ nuseless++;
+ if (dump_file)
+ fprintf (dump_file,
+ "Not speculating: probability is too low.\n");
+ }
+ else if (!cgraph_maybe_hot_edge_p (e))
+ {
+ nuseless++;
+ if (dump_file)
+ fprintf (dump_file,
+ "Not speculating: call is cold.\n");
+ }
+ else if (cgraph_function_body_availability (n2)
+ <= AVAIL_OVERWRITABLE
+ && symtab_can_be_discarded ((symtab_node) n2))
+ {
+ nuseless++;
+ if (dump_file)
+ fprintf (dump_file,
+ "Not speculating: target is overwritable "
+ "and can be discarded.\n");
+ }
+ else
+ {
+ /* Target may be overwritable, but profile says that
+ control flow goes to this particular implementation
+ of N2. Speculate on the local alias to allow inlining.
+ */
+ if (!symtab_can_be_discarded ((symtab_node) n2))
+ n2 = cgraph (symtab_nonoverwritable_alias ((symtab_node)n2));
+ nconverted++;
+ cgraph_turn_edge_to_speculative
+ (e, n2,
+ apply_scale (e->count,
+ e->indirect_info->common_target_probability),
+ apply_scale (e->frequency,
+ e->indirect_info->common_target_probability));
+ update = true;
+ }
+ }
+ else
+ {
+ if (dump_file)
+ fprintf (dump_file, "Function with profile-id %i not found.\n",
+ e->indirect_info->common_target_id);
+ nunknown++;
+ }
+ }
+ }
+ if (update)
+ inline_update_overall_summary (n);
+ }
+ if (node_map_initialized)
+ del_node_map ();
+ if (dump_file && nindirect)
+ fprintf (dump_file,
+ "%i indirect calls trained.\n"
+ "%i (%3.2f%%) have common target.\n"
+ "%i (%3.2f%%) targets was not found.\n"
+ "%i (%3.2f%%) speculations seems useless.\n"
+ "%i (%3.2f%%) speculations produced.\n",
+ nindirect,
+ ncommon, ncommon * 100.0 / nindirect,
+ nunknown, nunknown * 100.0 / nindirect,
+ nuseless, nuseless * 100.0 / nindirect,
+ nconverted, nconverted * 100.0 / nindirect);
+
+ order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
+ order_pos = ipa_reverse_postorder (order);
+ for (i = order_pos - 1; i >= 0; i--)
+ {
+ if (order[i]->local.local && ipa_propagate_frequency (order[i]))
+ {
+ for (e = order[i]->callees; e; e = e->next_callee)
+ if (e->callee->local.local && !e->callee->symbol.aux)
+ {
+ something_changed = true;
+ e->callee->symbol.aux = (void *)1;
+ }
+ }
+ order[i]->symbol.aux = NULL;
+ }
+
+ while (something_changed)
+ {
+ something_changed = false;
+ for (i = order_pos - 1; i >= 0; i--)
+ {
+ if (order[i]->symbol.aux && ipa_propagate_frequency (order[i]))
+ {
+ for (e = order[i]->callees; e; e = e->next_callee)
+ if (e->callee->local.local && !e->callee->symbol.aux)
+ {
+ something_changed = true;
+ e->callee->symbol.aux = (void *)1;
+ }
+ }
+ order[i]->symbol.aux = NULL;
+ }
+ }
+ free (order);
+ return 0;
+}
+
+static bool
+gate_ipa_profile (void)
+{
+ return flag_ipa_profile;
+}
+
+namespace {
+
+const pass_data pass_data_ipa_profile =
+{
+ IPA_PASS, /* type */
+ "profile_estimate", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_PROFILE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class pass_ipa_profile : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_profile(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_profile, ctxt,
+ ipa_profile_generate_summary, /* generate_summary */
+ ipa_profile_write_summary, /* write_summary */
+ ipa_profile_read_summary, /* read_summary */
+ NULL, /* write_optimization_summary */
+ NULL, /* read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ NULL, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_ipa_profile (); }
+ unsigned int execute () { return ipa_profile (); }
+
+}; // class pass_ipa_profile
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_profile (gcc::context *ctxt)
+{
+ return new pass_ipa_profile (ctxt);
+}
diff --git a/gcc/ipa-prop.c b/gcc/ipa-prop.c
index bf9e903ca80..67811bbdcfb 100644
--- a/gcc/ipa-prop.c
+++ b/gcc/ipa-prop.c
@@ -130,16 +130,14 @@ ipa_populate_param_decls (struct cgraph_node *node,
tree parm;
int param_num;
- /* We do not copy DECL_ARGUMENTS to virtual clones. */
- while (node->clone_of)
- node = node->clone_of;
-
fndecl = node->symbol.decl;
+ gcc_assert (gimple_has_body_p (fndecl));
fnargs = DECL_ARGUMENTS (fndecl);
param_num = 0;
for (parm = fnargs; parm; parm = DECL_CHAIN (parm))
{
descriptors[param_num].decl = parm;
+ descriptors[param_num].move_cost = estimate_move_cost (TREE_TYPE (parm));
param_num++;
}
}
@@ -151,6 +149,7 @@ count_formal_params (tree fndecl)
{
tree parm;
int count = 0;
+ gcc_assert (gimple_has_body_p (fndecl));
for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
count++;
@@ -158,6 +157,33 @@ count_formal_params (tree fndecl)
return count;
}
+/* Return the declaration of Ith formal parameter of the function corresponding
+ to INFO. Note there is no setter function as this array is built just once
+ using ipa_initialize_node_params. */
+
+void
+ipa_dump_param (FILE *file, struct ipa_node_params *info, int i)
+{
+ fprintf (file, "param #%i", i);
+ if (info->descriptors[i].decl)
+ {
+ fprintf (file, " ");
+ print_generic_expr (file, info->descriptors[i].decl, 0);
+ }
+}
+
+/* Initialize the ipa_node_params structure associated with NODE
+ to hold PARAM_COUNT parameters. */
+
+void
+ipa_alloc_node_params (struct cgraph_node *node, int param_count)
+{
+ struct ipa_node_params *info = IPA_NODE_REF (node);
+
+ if (!info->descriptors.exists () && param_count)
+ info->descriptors.safe_grow_cleared (param_count);
+}
+
/* Initialize the ipa_node_params structure associated with NODE by counting
the function parameters, creating the descriptors and populating their
param_decls. */
@@ -169,15 +195,8 @@ ipa_initialize_node_params (struct cgraph_node *node)
if (!info->descriptors.exists ())
{
- int param_count;
- gcc_assert (!node->clone_of);
-
- param_count = count_formal_params (node->symbol.decl);
- if (param_count)
- {
- info->descriptors.safe_grow_cleared (param_count);
- ipa_populate_param_decls (node, info->descriptors);
- }
+ ipa_alloc_node_params (node, count_formal_params (node->symbol.decl));
+ ipa_populate_param_decls (node, info->descriptors);
}
}
@@ -238,6 +257,8 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
}
if (jump_func->value.pass_through.agg_preserved)
fprintf (f, ", agg_preserved");
+ if (jump_func->value.pass_through.type_preserved)
+ fprintf (f, ", type_preserved");
fprintf (f, "\n");
}
else if (type == IPA_JF_ANCESTOR)
@@ -249,6 +270,8 @@ ipa_print_node_jump_functions_for_edge (FILE *f, struct cgraph_edge *cs)
print_generic_expr (f, jump_func->value.ancestor.type, 0);
if (jump_func->value.ancestor.agg_preserved)
fprintf (f, ", agg_preserved");
+ if (jump_func->value.ancestor.type_preserved)
+ fprintf (f, ", type_preserved");
fprintf (f, "\n");
}
@@ -348,12 +371,27 @@ static void
ipa_set_jf_known_type (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
tree base_type, tree component_type)
{
+ gcc_assert (TREE_CODE (component_type) == RECORD_TYPE
+ && TYPE_BINFO (component_type));
jfunc->type = IPA_JF_KNOWN_TYPE;
jfunc->value.known_type.offset = offset,
jfunc->value.known_type.base_type = base_type;
jfunc->value.known_type.component_type = component_type;
}
+/* Set JFUNC to be a copy of another jmp (to be used by jump function
+ combination code). The two functions will share their rdesc. */
+
+static void
+ipa_set_jf_cst_copy (struct ipa_jump_func *dst,
+ struct ipa_jump_func *src)
+
+{
+ gcc_checking_assert (src->type == IPA_JF_CONST);
+ dst->type = IPA_JF_CONST;
+ dst->value.constant = src->value.constant;
+}
+
/* Set JFUNC to be a constant jmp function. */
static void
@@ -387,13 +425,14 @@ ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant,
/* Set JFUNC to be a simple pass-through jump function. */
static void
ipa_set_jf_simple_pass_through (struct ipa_jump_func *jfunc, int formal_id,
- bool agg_preserved)
+ bool agg_preserved, bool type_preserved)
{
jfunc->type = IPA_JF_PASS_THROUGH;
jfunc->value.pass_through.operand = NULL_TREE;
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = NOP_EXPR;
jfunc->value.pass_through.agg_preserved = agg_preserved;
+ jfunc->value.pass_through.type_preserved = type_preserved;
}
/* Set JFUNC to be an arithmetic pass through jump function. */
@@ -407,19 +446,22 @@ ipa_set_jf_arith_pass_through (struct ipa_jump_func *jfunc, int formal_id,
jfunc->value.pass_through.formal_id = formal_id;
jfunc->value.pass_through.operation = operation;
jfunc->value.pass_through.agg_preserved = false;
+ jfunc->value.pass_through.type_preserved = false;
}
/* Set JFUNC to be an ancestor jump function. */
static void
ipa_set_ancestor_jf (struct ipa_jump_func *jfunc, HOST_WIDE_INT offset,
- tree type, int formal_id, bool agg_preserved)
+ tree type, int formal_id, bool agg_preserved,
+ bool type_preserved)
{
jfunc->type = IPA_JF_ANCESTOR;
jfunc->value.ancestor.formal_id = formal_id;
jfunc->value.ancestor.offset = offset;
jfunc->value.ancestor.type = type;
jfunc->value.ancestor.agg_preserved = agg_preserved;
+ jfunc->value.ancestor.type_preserved = type_preserved;
}
/* Extract the acual BINFO being described by JFUNC which must be a known type
@@ -593,13 +635,16 @@ check_stmt_for_type_change (ao_ref *ao ATTRIBUTE_UNUSED, tree vdef, void *data)
-/* Like detect_type_change but with extra argument COMP_TYPE which will become
- the component type part of new JFUNC of dynamic type change is detected and
- the new base type is identified. */
+/* Detect whether the dynamic type of ARG of COMP_TYPE has changed (before
+ callsite CALL) by looking for assignments to its virtual table pointer. If
+ it is, return true and fill in the jump function JFUNC with relevant type
+ information or set it to unknown. ARG is the object itself (not a pointer
+ to it, unless dereferenced). BASE is the base of the memory access as
+ returned by get_ref_base_and_extent, as is the offset. */
static bool
-detect_type_change_1 (tree arg, tree base, tree comp_type, gimple call,
- struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
+detect_type_change (tree arg, tree base, tree comp_type, gimple call,
+ struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
{
struct type_change_info tci;
ao_ref ao;
@@ -609,7 +654,12 @@ detect_type_change_1 (tree arg, tree base, tree comp_type, gimple call,
|| handled_component_p (arg));
/* Const calls cannot call virtual methods through VMT and so type changes do
not matter. */
- if (!flag_devirtualize || !gimple_vuse (call))
+ if (!flag_devirtualize || !gimple_vuse (call)
+ /* Be sure expected_type is polymorphic. */
+ || !comp_type
+ || TREE_CODE (comp_type) != RECORD_TYPE
+ || !TYPE_BINFO (comp_type)
+ || !BINFO_VTABLE (TYPE_BINFO (comp_type)))
return false;
ao_ref_init (&ao, arg);
@@ -639,40 +689,23 @@ detect_type_change_1 (tree arg, tree base, tree comp_type, gimple call,
return true;
}
-/* Detect whether the dynamic type of ARG has changed (before callsite CALL) by
- looking for assignments to its virtual table pointer. If it is, return true
- and fill in the jump function JFUNC with relevant type information or set it
- to unknown. ARG is the object itself (not a pointer to it, unless
- dereferenced). BASE is the base of the memory access as returned by
- get_ref_base_and_extent, as is the offset. */
-
-static bool
-detect_type_change (tree arg, tree base, gimple call,
- struct ipa_jump_func *jfunc, HOST_WIDE_INT offset)
-{
- return detect_type_change_1 (arg, base, TREE_TYPE (arg), call, jfunc, offset);
-}
-
/* Like detect_type_change but ARG is supposed to be a non-dereferenced pointer
SSA name (its dereference will become the base and the offset is assumed to
be zero). */
static bool
-detect_type_change_ssa (tree arg, gimple call, struct ipa_jump_func *jfunc)
+detect_type_change_ssa (tree arg, tree comp_type,
+ gimple call, struct ipa_jump_func *jfunc)
{
- tree comp_type;
-
gcc_checking_assert (TREE_CODE (arg) == SSA_NAME);
if (!flag_devirtualize
- || !POINTER_TYPE_P (TREE_TYPE (arg))
- || TREE_CODE (TREE_TYPE (TREE_TYPE (arg))) != RECORD_TYPE)
+ || !POINTER_TYPE_P (TREE_TYPE (arg)))
return false;
- comp_type = TREE_TYPE (TREE_TYPE (arg));
arg = build2 (MEM_REF, ptr_type_node, arg,
build_int_cst (ptr_type_node, 0));
- return detect_type_change_1 (arg, arg, comp_type, call, jfunc, 0);
+ return detect_type_change (arg, arg, comp_type, call, jfunc, 0);
}
/* Callback of walk_aliased_vdefs. Flags that it has been invoked to the
@@ -948,7 +981,8 @@ static void
compute_complex_assign_jump_func (struct ipa_node_params *info,
struct param_analysis_info *parms_ainfo,
struct ipa_jump_func *jfunc,
- gimple call, gimple stmt, tree name)
+ gimple call, gimple stmt, tree name,
+ tree param_type)
{
HOST_WIDE_INT offset, size, max_size;
tree op1, tc_ssa, base, ssa;
@@ -986,12 +1020,17 @@ compute_complex_assign_jump_func (struct ipa_node_params *info,
ipa_set_jf_arith_pass_through (jfunc, index, op2,
gimple_assign_rhs_code (stmt));
}
- else if (gimple_assign_single_p (stmt)
- && !detect_type_change_ssa (tc_ssa, call, jfunc))
+ else if (gimple_assign_single_p (stmt))
{
bool agg_p = parm_ref_data_pass_through_p (&parms_ainfo[index],
call, tc_ssa);
- ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
+ bool type_p = false;
+
+ if (param_type && POINTER_TYPE_P (param_type))
+ type_p = !detect_type_change_ssa (tc_ssa, TREE_TYPE (param_type),
+ call, jfunc);
+ if (type_p || jfunc->type == IPA_JF_UNKNOWN)
+ ipa_set_jf_simple_pass_through (jfunc, index, agg_p, type_p);
}
return;
}
@@ -1014,13 +1053,17 @@ compute_complex_assign_jump_func (struct ipa_node_params *info,
|| offset < 0)
return;
- /* Dynamic types are changed only in constructors and destructors and */
+ /* Dynamic types are changed in constructors and destructors. */
index = ipa_get_param_decl_index (info, SSA_NAME_VAR (ssa));
- if (index >= 0
- && !detect_type_change (op1, base, call, jfunc, offset))
- ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (op1), index,
- parm_ref_data_pass_through_p (&parms_ainfo[index],
- call, ssa));
+ if (index >= 0 && param_type && POINTER_TYPE_P (param_type))
+ {
+ bool type_p = !detect_type_change (op1, base, TREE_TYPE (param_type),
+ call, jfunc, offset);
+ if (type_p || jfunc->type == IPA_JF_UNKNOWN)
+ ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (op1), index,
+ parm_ref_data_pass_through_p (&parms_ainfo[index],
+ call, ssa), type_p);
+ }
}
/* Extract the base, offset and MEM_REF expression from a statement ASSIGN if
@@ -1093,7 +1136,7 @@ static void
compute_complex_ancestor_jump_func (struct ipa_node_params *info,
struct param_analysis_info *parms_ainfo,
struct ipa_jump_func *jfunc,
- gimple call, gimple phi)
+ gimple call, gimple phi, tree param_type)
{
HOST_WIDE_INT offset;
gimple assign, cond;
@@ -1144,26 +1187,36 @@ compute_complex_ancestor_jump_func (struct ipa_node_params *info,
return;
}
- if (!detect_type_change (obj, expr, call, jfunc, offset))
+ bool type_p = false;
+ if (param_type && POINTER_TYPE_P (param_type))
+ type_p = !detect_type_change (obj, expr, TREE_TYPE (param_type),
+ call, jfunc, offset);
+ if (type_p || jfunc->type == IPA_JF_UNKNOWN)
ipa_set_ancestor_jf (jfunc, offset, TREE_TYPE (obj), index,
parm_ref_data_pass_through_p (&parms_ainfo[index],
- call, parm));
+ call, parm), type_p);
}
/* Given OP which is passed as an actual argument to a called function,
determine if it is possible to construct a KNOWN_TYPE jump function for it
- and if so, create one and store it to JFUNC. */
+ and if so, create one and store it to JFUNC.
+ EXPECTED_TYPE represents a type the argument should be in */
static void
compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
- gimple call)
+ gimple call, tree expected_type)
{
HOST_WIDE_INT offset, size, max_size;
tree base;
if (!flag_devirtualize
|| TREE_CODE (op) != ADDR_EXPR
- || TREE_CODE (TREE_TYPE (TREE_TYPE (op))) != RECORD_TYPE)
+ || TREE_CODE (TREE_TYPE (TREE_TYPE (op))) != RECORD_TYPE
+ /* Be sure expected_type is polymorphic. */
+ || !expected_type
+ || TREE_CODE (expected_type) != RECORD_TYPE
+ || !TYPE_BINFO (expected_type)
+ || !BINFO_VTABLE (TYPE_BINFO (expected_type)))
return;
op = TREE_OPERAND (op, 0);
@@ -1175,11 +1228,11 @@ compute_known_type_jump_func (tree op, struct ipa_jump_func *jfunc,
|| is_global_var (base))
return;
- if (!TYPE_BINFO (TREE_TYPE (base))
- || detect_type_change (op, base, call, jfunc, offset))
+ if (detect_type_change (op, base, expected_type, call, jfunc, offset))
return;
- ipa_set_jf_known_type (jfunc, offset, TREE_TYPE (base), TREE_TYPE (op));
+ ipa_set_jf_known_type (jfunc, offset, TREE_TYPE (base),
+ expected_type);
}
/* Inspect the given TYPE and return true iff it has the same structure (the
@@ -1450,6 +1503,37 @@ determine_known_aggregate_parts (gimple call, tree arg,
}
}
+static tree
+ipa_get_callee_param_type (struct cgraph_edge *e, int i)
+{
+ int n;
+ tree type = (e->callee
+ ? TREE_TYPE (e->callee->symbol.decl)
+ : gimple_call_fntype (e->call_stmt));
+ tree t = TYPE_ARG_TYPES (type);
+
+ for (n = 0; n < i; n++)
+ {
+ if (!t)
+ break;
+ t = TREE_CHAIN (t);
+ }
+ if (t)
+ return TREE_VALUE (t);
+ if (!e->callee)
+ return NULL;
+ t = DECL_ARGUMENTS (e->callee->symbol.decl);
+ for (n = 0; n < i; n++)
+ {
+ if (!t)
+ return NULL;
+ t = TREE_CHAIN (t);
+ }
+ if (t)
+ return TREE_TYPE (t);
+ return NULL;
+}
+
/* Compute jump function for all arguments of callsite CS and insert the
information in the jump_functions array in the ipa_edge_args corresponding
to this callsite. */
@@ -1474,6 +1558,7 @@ ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo,
{
struct ipa_jump_func *jfunc = ipa_get_ith_jump_func (args, n);
tree arg = gimple_call_arg (call, n);
+ tree param_type = ipa_get_callee_param_type (cs, n);
if (is_gimple_ip_invariant (arg))
ipa_set_jf_constant (jfunc, arg, cs);
@@ -1488,7 +1573,7 @@ ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo,
for cycle. */
if (parm_preserved_before_stmt_p (&parms_ainfo[index], call, arg))
{
- ipa_set_jf_simple_pass_through (jfunc, index, false);
+ ipa_set_jf_simple_pass_through (jfunc, index, false, false);
continue;
}
}
@@ -1497,13 +1582,19 @@ ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo,
if (SSA_NAME_IS_DEFAULT_DEF (arg))
{
int index = ipa_get_param_decl_index (info, SSA_NAME_VAR (arg));
- if (index >= 0
- && !detect_type_change_ssa (arg, call, jfunc))
+ if (index >= 0)
{
- bool agg_p;
+ bool agg_p, type_p;
agg_p = parm_ref_data_pass_through_p (&parms_ainfo[index],
call, arg);
- ipa_set_jf_simple_pass_through (jfunc, index, agg_p);
+ if (param_type && POINTER_TYPE_P (param_type))
+ type_p = !detect_type_change_ssa (arg, TREE_TYPE (param_type),
+ call, jfunc);
+ else
+ type_p = false;
+ if (type_p || jfunc->type == IPA_JF_UNKNOWN)
+ ipa_set_jf_simple_pass_through (jfunc, index, agg_p,
+ type_p);
}
}
else
@@ -1511,14 +1602,18 @@ ipa_compute_jump_functions_for_edge (struct param_analysis_info *parms_ainfo,
gimple stmt = SSA_NAME_DEF_STMT (arg);
if (is_gimple_assign (stmt))
compute_complex_assign_jump_func (info, parms_ainfo, jfunc,
- call, stmt, arg);
+ call, stmt, arg, param_type);
else if (gimple_code (stmt) == GIMPLE_PHI)
compute_complex_ancestor_jump_func (info, parms_ainfo, jfunc,
- call, stmt);
+ call, stmt, param_type);
}
}
else
- compute_known_type_jump_func (arg, jfunc, call);
+ compute_known_type_jump_func (arg, jfunc, call,
+ param_type
+ && POINTER_TYPE_P (param_type)
+ ? TREE_TYPE (param_type)
+ : NULL);
if ((jfunc->type != IPA_JF_PASS_THROUGH
|| !ipa_get_jf_pass_through_agg_preserved (jfunc))
@@ -1862,7 +1957,8 @@ ipa_analyze_virtual_call_uses (struct cgraph_node *node,
anc_offset = 0;
index = ipa_get_param_decl_index (info, SSA_NAME_VAR (obj));
gcc_assert (index >= 0);
- if (detect_type_change_ssa (obj, call, &jfunc))
+ if (detect_type_change_ssa (obj, obj_type_ref_class (target),
+ call, &jfunc))
return;
}
else
@@ -1876,7 +1972,8 @@ ipa_analyze_virtual_call_uses (struct cgraph_node *node,
index = ipa_get_param_decl_index (info,
SSA_NAME_VAR (TREE_OPERAND (expr, 0)));
gcc_assert (index >= 0);
- if (detect_type_change (obj, expr, call, &jfunc, anc_offset))
+ if (detect_type_change (obj, expr, obj_type_ref_class (target),
+ call, &jfunc, anc_offset))
return;
}
@@ -1884,7 +1981,7 @@ ipa_analyze_virtual_call_uses (struct cgraph_node *node,
ii = cs->indirect_info;
ii->offset = anc_offset;
ii->otr_token = tree_low_cst (OBJ_TYPE_REF_TOKEN (target), 1);
- ii->otr_type = TREE_TYPE (TREE_TYPE (OBJ_TYPE_REF_OBJECT (target)));
+ ii->otr_type = obj_type_ref_class (target);
ii->polymorphic = 1;
}
@@ -1903,7 +2000,7 @@ ipa_analyze_call_uses (struct cgraph_node *node,
return;
if (TREE_CODE (target) == SSA_NAME)
ipa_analyze_indirect_call_uses (node, info, parms_ainfo, call, target);
- else if (TREE_CODE (target) == OBJ_TYPE_REF)
+ else if (virtual_method_call_p (target))
ipa_analyze_virtual_call_uses (node, info, call, target);
}
@@ -2088,7 +2185,7 @@ ipa_intraprocedural_devirtualization (gimple call)
jfunc.type = IPA_JF_UNKNOWN;
compute_known_type_jump_func (OBJ_TYPE_REF_OBJECT (otr), &jfunc,
- call);
+ call, obj_type_ref_class (otr));
if (jfunc.type != IPA_JF_KNOWN_TYPE)
return NULL_TREE;
binfo = ipa_binfo_from_known_type_jfunc (&jfunc);
@@ -2111,6 +2208,12 @@ combine_known_type_and_ancestor_jfs (struct ipa_jump_func *src,
HOST_WIDE_INT combined_offset;
tree combined_type;
+ if (!ipa_get_jf_ancestor_type_preserved (dst))
+ {
+ dst->type = IPA_JF_UNKNOWN;
+ return;
+ }
+
combined_offset = ipa_get_jf_known_type_offset (src)
+ ipa_get_jf_ancestor_offset (dst);
combined_type = ipa_get_jf_ancestor_type (dst);
@@ -2177,6 +2280,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
dst->value.ancestor.formal_id = src->value.pass_through.formal_id;
dst->value.ancestor.agg_preserved &=
src->value.pass_through.agg_preserved;
+ dst->value.ancestor.type_preserved &=
+ src->value.pass_through.type_preserved;
}
else if (src->type == IPA_JF_ANCESTOR)
{
@@ -2184,6 +2289,8 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
dst->value.ancestor.offset += src->value.ancestor.offset;
dst->value.ancestor.agg_preserved &=
src->value.ancestor.agg_preserved;
+ dst->value.ancestor.type_preserved &=
+ src->value.ancestor.type_preserved;
}
else
dst->type = IPA_JF_UNKNOWN;
@@ -2197,16 +2304,69 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
&& (dst->value.pass_through.formal_id
< ipa_get_cs_argument_count (top)))
{
- bool agg_p;
int dst_fid = dst->value.pass_through.formal_id;
src = ipa_get_ith_jump_func (top, dst_fid);
- agg_p = dst->value.pass_through.agg_preserved;
+ bool dst_agg_p = ipa_get_jf_pass_through_agg_preserved (dst);
- dst->type = src->type;
- dst->value = src->value;
+ switch (src->type)
+ {
+ case IPA_JF_UNKNOWN:
+ dst->type = IPA_JF_UNKNOWN;
+ break;
+ case IPA_JF_KNOWN_TYPE:
+ ipa_set_jf_known_type (dst,
+ ipa_get_jf_known_type_offset (src),
+ ipa_get_jf_known_type_base_type (src),
+ ipa_get_jf_known_type_base_type (src));
+ break;
+ case IPA_JF_CONST:
+ ipa_set_jf_cst_copy (dst, src);
+ break;
+
+ case IPA_JF_PASS_THROUGH:
+ {
+ int formal_id = ipa_get_jf_pass_through_formal_id (src);
+ enum tree_code operation;
+ operation = ipa_get_jf_pass_through_operation (src);
+
+ if (operation == NOP_EXPR)
+ {
+ bool agg_p, type_p;
+ agg_p = dst_agg_p
+ && ipa_get_jf_pass_through_agg_preserved (src);
+ type_p = ipa_get_jf_pass_through_type_preserved (src)
+ && ipa_get_jf_pass_through_type_preserved (dst);
+ ipa_set_jf_simple_pass_through (dst, formal_id,
+ agg_p, type_p);
+ }
+ else
+ {
+ tree operand = ipa_get_jf_pass_through_operand (src);
+ ipa_set_jf_arith_pass_through (dst, formal_id, operand,
+ operation);
+ }
+ break;
+ }
+ case IPA_JF_ANCESTOR:
+ {
+ bool agg_p, type_p;
+ agg_p = dst_agg_p
+ && ipa_get_jf_ancestor_agg_preserved (src);
+ type_p = ipa_get_jf_ancestor_type_preserved (src)
+ && ipa_get_jf_pass_through_type_preserved (dst);
+ ipa_set_ancestor_jf (dst,
+ ipa_get_jf_ancestor_offset (src),
+ ipa_get_jf_ancestor_type (src),
+ ipa_get_jf_ancestor_formal_id (src),
+ agg_p, type_p);
+ break;
+ }
+ default:
+ gcc_unreachable ();
+ }
if (src->agg.items
- && (agg_p || !src->agg.by_ref))
+ && (dst_agg_p || !src->agg.by_ref))
{
/* Currently we do not produce clobber aggregate jump
functions, replace with merging when we do. */
@@ -2215,14 +2375,6 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs,
dst->agg.by_ref = src->agg.by_ref;
dst->agg.items = vec_safe_copy (src->agg.items);
}
-
- if (!agg_p)
- {
- if (dst->type == IPA_JF_PASS_THROUGH)
- dst->value.pass_through.agg_preserved = false;
- else if (dst->type == IPA_JF_ANCESTOR)
- dst->value.ancestor.agg_preserved = false;
- }
}
else
dst->type = IPA_JF_UNKNOWN;
@@ -2294,12 +2446,6 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
the cgraph node too early. */
gcc_assert (!callee->global.inlined_to);
- cgraph_make_edge_direct (ie, callee);
- es = inline_edge_summary (ie);
- es->call_stmt_size -= (eni_size_weights.indirect_call_cost
- - eni_size_weights.call_cost);
- es->call_stmt_time -= (eni_time_weights.indirect_call_cost
- - eni_time_weights.call_cost);
if (dump_file && !unreachable)
{
fprintf (dump_file, "ipa-prop: Discovered %s call to a known target "
@@ -2307,14 +2453,19 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target)
ie->indirect_info->polymorphic ? "a virtual" : "an indirect",
xstrdup (cgraph_node_name (ie->caller)),
ie->caller->symbol.order,
- xstrdup (cgraph_node_name (ie->callee)),
- ie->callee->symbol.order);
+ xstrdup (cgraph_node_name (callee)),
+ callee->symbol.order);
if (ie->call_stmt)
print_gimple_stmt (dump_file, ie->call_stmt, 2, TDF_SLIM);
else
fprintf (dump_file, "with uid %i\n", ie->lto_stmt_uid);
- }
- callee = cgraph_function_or_thunk_node (callee, NULL);
+ }
+ ie = cgraph_make_edge_direct (ie, callee);
+ es = inline_edge_summary (ie);
+ es->call_stmt_size -= (eni_size_weights.indirect_call_cost
+ - eni_size_weights.call_cost);
+ es->call_stmt_time -= (eni_time_weights.indirect_call_cost
+ - eni_time_weights.call_cost);
return ie;
}
@@ -2345,9 +2496,10 @@ ipa_find_agg_cst_for_param (struct ipa_agg_jump_function *agg,
}
/* Remove a reference to SYMBOL from the list of references of a node given by
- reference description RDESC. */
+ reference description RDESC. Return true if the reference has been
+ successfully found and removed. */
-static void
+static bool
remove_described_reference (symtab_node symbol, struct ipa_cst_ref_desc *rdesc)
{
struct ipa_ref *to_del;
@@ -2355,13 +2507,16 @@ remove_described_reference (symtab_node symbol, struct ipa_cst_ref_desc *rdesc)
origin = rdesc->cs;
to_del = ipa_find_reference ((symtab_node) origin->caller, symbol,
- origin->call_stmt);
- gcc_assert (to_del);
+ origin->call_stmt, origin->lto_stmt_uid);
+ if (!to_del)
+ return false;
+
ipa_remove_reference (to_del);
if (dump_file)
fprintf (dump_file, "ipa-prop: Removed a reference from %s/%i to %s.\n",
xstrdup (cgraph_node_name (origin->caller)),
origin->caller->symbol.order, xstrdup (symtab_node_name (symbol)));
+ return true;
}
/* If JFUNC has a reference description with refcount different from
@@ -2378,6 +2533,45 @@ jfunc_rdesc_usable (struct ipa_jump_func *jfunc)
return NULL;
}
+/* If the value of constant jump function JFUNC is an address of a function
+ declaration, return the associated call graph node. Otherwise return
+ NULL. */
+
+static cgraph_node *
+cgraph_node_for_jfunc (struct ipa_jump_func *jfunc)
+{
+ gcc_checking_assert (jfunc->type == IPA_JF_CONST);
+ tree cst = ipa_get_jf_constant (jfunc);
+ if (TREE_CODE (cst) != ADDR_EXPR
+ || TREE_CODE (TREE_OPERAND (cst, 0)) != FUNCTION_DECL)
+ return NULL;
+
+ return cgraph_get_node (TREE_OPERAND (cst, 0));
+}
+
+
+/* If JFUNC is a constant jump function with a usable rdesc, decrement its
+ refcount and if it hits zero, remove reference to SYMBOL from the caller of
+ the edge specified in the rdesc. Return false if either the symbol or the
+ reference could not be found, otherwise return true. */
+
+static bool
+try_decrement_rdesc_refcount (struct ipa_jump_func *jfunc)
+{
+ struct ipa_cst_ref_desc *rdesc;
+ if (jfunc->type == IPA_JF_CONST
+ && (rdesc = jfunc_rdesc_usable (jfunc))
+ && --rdesc->refcount == 0)
+ {
+ symtab_node symbol = (symtab_node) cgraph_node_for_jfunc (jfunc);
+ if (!symbol)
+ return false;
+
+ return remove_described_reference (symbol, rdesc);
+ }
+ return true;
+}
+
/* Try to find a destination for indirect edge IE that corresponds to a simple
call or a call of a member function pointer and where the destination is a
pointer formal parameter described by jump function JFUNC. If it can be
@@ -2389,9 +2583,9 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
struct ipa_jump_func *jfunc,
struct ipa_node_params *new_root_info)
{
- struct ipa_cst_ref_desc *rdesc;
struct cgraph_edge *cs;
tree target;
+ bool agg_contents = ie->indirect_info->agg_contents;
if (ie->indirect_info->agg_contents)
target = ipa_find_agg_cst_for_param (&jfunc->agg,
@@ -2403,11 +2597,16 @@ try_make_edge_direct_simple_call (struct cgraph_edge *ie,
return NULL;
cs = ipa_make_edge_direct_to_target (ie, target);
- if (cs && !ie->indirect_info->agg_contents
- && jfunc->type == IPA_JF_CONST
- && (rdesc = jfunc_rdesc_usable (jfunc))
- && --rdesc->refcount == 0)
- remove_described_reference ((symtab_node) cs->callee, rdesc);
+ if (cs && !agg_contents)
+ {
+ bool ok;
+ gcc_checking_assert (cs->callee
+ && (jfunc->type != IPA_JF_CONST
+ || !cgraph_node_for_jfunc (jfunc)
+ || cs->callee == cgraph_node_for_jfunc (jfunc)));
+ ok = try_decrement_rdesc_refcount (jfunc);
+ gcc_checking_assert (ok);
+ }
return cs;
}
@@ -2432,7 +2631,8 @@ try_make_edge_direct_virtual_call (struct cgraph_edge *ie,
if (TREE_CODE (binfo) != TREE_BINFO)
{
- binfo = gimple_extract_devirt_binfo_from_cst (binfo);
+ binfo = gimple_extract_devirt_binfo_from_cst
+ (binfo, ie->indirect_info->otr_type);
if (!binfo)
return NULL;
}
@@ -2502,7 +2702,14 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
else
new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc,
new_root_info);
- if (new_direct_edge)
+ /* If speculation was removed, then we need to do nothing. */
+ if (new_direct_edge && new_direct_edge != ie)
+ {
+ new_direct_edge->indirect_inlining_edge = 1;
+ top = IPA_EDGE_REF (cs);
+ res = true;
+ }
+ else if (new_direct_edge)
{
new_direct_edge->indirect_inlining_edge = 1;
if (new_direct_edge->call_stmt)
@@ -2513,9 +2720,9 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
if (new_edges)
{
new_edges->safe_push (new_direct_edge);
- top = IPA_EDGE_REF (cs);
res = true;
}
+ top = IPA_EDGE_REF (cs);
}
else if (jfunc->type == IPA_JF_PASS_THROUGH
&& ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR)
@@ -2626,7 +2833,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
&& TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
&& (n = cgraph_get_node (TREE_OPERAND (t, 0)))
&& (ref = ipa_find_reference ((symtab_node) new_root,
- (symtab_node) n, NULL)))
+ (symtab_node) n, NULL, 0)))
{
if (dump_file)
fprintf (dump_file, "ipa-prop: Removing cloning-created "
@@ -2655,7 +2862,9 @@ propagate_controlled_uses (struct cgraph_edge *cs)
if (n)
{
struct cgraph_node *clone;
- remove_described_reference ((symtab_node) n, rdesc);
+ bool ok;
+ ok = remove_described_reference ((symtab_node) n, rdesc);
+ gcc_checking_assert (ok);
clone = cs->caller;
while (clone->global.inlined_to
@@ -2664,7 +2873,7 @@ propagate_controlled_uses (struct cgraph_edge *cs)
{
struct ipa_ref *ref;
ref = ipa_find_reference ((symtab_node) clone,
- (symtab_node) n, NULL);
+ (symtab_node) n, NULL, 0);
if (ref)
{
if (dump_file)
@@ -2798,9 +3007,21 @@ ipa_set_node_agg_value_chain (struct cgraph_node *node,
static void
ipa_edge_removal_hook (struct cgraph_edge *cs, void *data ATTRIBUTE_UNUSED)
{
- /* During IPA-CP updating we can be called on not-yet analyze clones. */
+ struct ipa_edge_args *args;
+
+ /* During IPA-CP updating we can be called on not-yet analyzed clones. */
if (vec_safe_length (ipa_edge_args_vector) <= (unsigned)cs->uid)
return;
+
+ args = IPA_EDGE_REF (cs);
+ if (args->jump_functions)
+ {
+ struct ipa_jump_func *jf;
+ int i;
+ FOR_EACH_VEC_ELT (*args->jump_functions, i, jf)
+ try_decrement_rdesc_refcount (jf);
+ }
+
ipa_free_edge_args_substructures (IPA_EDGE_REF (cs));
}
@@ -2845,6 +3066,24 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
if (!src_rdesc)
dst_jf->value.constant.rdesc = NULL;
+ else if (src->caller == dst->caller)
+ {
+ struct ipa_ref *ref;
+ symtab_node n = (symtab_node) cgraph_node_for_jfunc (src_jf);
+ gcc_checking_assert (n);
+ ref = ipa_find_reference ((symtab_node) src->caller, n,
+ src->call_stmt, src->lto_stmt_uid);
+ gcc_checking_assert (ref);
+ ipa_clone_ref (ref, (symtab_node) dst->caller, ref->stmt);
+
+ gcc_checking_assert (ipa_refdesc_pool);
+ struct ipa_cst_ref_desc *dst_rdesc
+ = (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
+ dst_rdesc->cs = dst;
+ dst_rdesc->refcount = src_rdesc->refcount;
+ dst_rdesc->next_duplicate = NULL;
+ dst_jf->value.constant.rdesc = dst_rdesc;
+ }
else if (src_rdesc->cs == src)
{
struct ipa_cst_ref_desc *dst_rdesc;
@@ -2853,11 +3092,8 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
= (struct ipa_cst_ref_desc *) pool_alloc (ipa_refdesc_pool);
dst_rdesc->cs = dst;
dst_rdesc->refcount = src_rdesc->refcount;
- if (dst->caller->global.inlined_to)
- {
- dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
- src_rdesc->next_duplicate = dst_rdesc;
- }
+ dst_rdesc->next_duplicate = src_rdesc->next_duplicate;
+ src_rdesc->next_duplicate = dst_rdesc;
dst_jf->value.constant.rdesc = dst_rdesc;
}
else
@@ -2872,9 +3108,14 @@ ipa_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst,
for (dst_rdesc = src_rdesc->next_duplicate;
dst_rdesc;
dst_rdesc = dst_rdesc->next_duplicate)
- if (dst_rdesc->cs->caller->global.inlined_to
- == dst->caller->global.inlined_to)
- break;
+ {
+ struct cgraph_node *top;
+ top = dst_rdesc->cs->caller->global.inlined_to
+ ? dst_rdesc->cs->caller->global.inlined_to
+ : dst_rdesc->cs->caller;
+ if (dst->caller->global.inlined_to == top)
+ break;
+ }
gcc_assert (dst_rdesc);
dst_jf->value.constant.rdesc = dst_rdesc;
}
@@ -3012,7 +3253,6 @@ void
ipa_print_node_params (FILE *f, struct cgraph_node *node)
{
int i, count;
- tree temp;
struct ipa_node_params *info;
if (!node->symbol.definition)
@@ -3025,12 +3265,7 @@ ipa_print_node_params (FILE *f, struct cgraph_node *node)
{
int c;
- temp = ipa_get_param (info, i);
- if (TREE_CODE (temp) == PARM_DECL)
- fprintf (f, " param %d : %s", i,
- (DECL_NAME (temp)
- ? (*lang_hooks.decl_printable_name) (temp, 2)
- : "(unnamed)"));
+ ipa_dump_param (f, info, i);
if (ipa_is_param_used (info, i))
fprintf (f, " used");
c = ipa_get_controlled_uses (info, i);
@@ -3064,6 +3299,7 @@ ipa_get_vector_of_formal_parms (tree fndecl)
int count;
tree parm;
+ gcc_assert (!flag_wpa);
count = count_formal_params (fndecl);
args.create (count);
for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
@@ -3679,6 +3915,7 @@ ipa_write_jump_function (struct output_block *ob,
streamer_write_uhwi (ob, jump_func->value.pass_through.formal_id);
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, jump_func->value.pass_through.agg_preserved, 1);
+ bp_pack_value (&bp, jump_func->value.pass_through.type_preserved, 1);
streamer_write_bitpack (&bp);
}
else
@@ -3693,6 +3930,7 @@ ipa_write_jump_function (struct output_block *ob,
streamer_write_uhwi (ob, jump_func->value.ancestor.formal_id);
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, jump_func->value.ancestor.agg_preserved, 1);
+ bp_pack_value (&bp, jump_func->value.ancestor.type_preserved, 1);
streamer_write_bitpack (&bp);
break;
}
@@ -3750,7 +3988,9 @@ ipa_read_jump_function (struct lto_input_block *ib,
int formal_id = streamer_read_uhwi (ib);
struct bitpack_d bp = streamer_read_bitpack (ib);
bool agg_preserved = bp_unpack_value (&bp, 1);
- ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved);
+ bool type_preserved = bp_unpack_value (&bp, 1);
+ ipa_set_jf_simple_pass_through (jump_func, formal_id, agg_preserved,
+ type_preserved);
}
else
{
@@ -3767,8 +4007,10 @@ ipa_read_jump_function (struct lto_input_block *ib,
int formal_id = streamer_read_uhwi (ib);
struct bitpack_d bp = streamer_read_bitpack (ib);
bool agg_preserved = bp_unpack_value (&bp, 1);
+ bool type_preserved = bp_unpack_value (&bp, 1);
- ipa_set_ancestor_jf (jump_func, offset, type, formal_id, agg_preserved);
+ ipa_set_ancestor_jf (jump_func, offset, type, formal_id, agg_preserved,
+ type_preserved);
break;
}
}
@@ -3856,6 +4098,9 @@ ipa_write_node_info (struct output_block *ob, struct cgraph_node *node)
node_ref = lto_symtab_encoder_encode (encoder, (symtab_node) node);
streamer_write_uhwi (ob, node_ref);
+ streamer_write_uhwi (ob, ipa_get_param_count (info));
+ for (j = 0; j < ipa_get_param_count (info); j++)
+ streamer_write_uhwi (ob, ipa_get_param_move_cost (info, j));
bp = bitpack_create (ob->main_stream);
gcc_assert (info->uses_analysis_done
|| ipa_get_param_count (info) == 0);
@@ -3896,8 +4141,11 @@ ipa_read_node_info (struct lto_input_block *ib, struct cgraph_node *node,
struct cgraph_edge *e;
struct bitpack_d bp;
- ipa_initialize_node_params (node);
+ ipa_alloc_node_params (node, streamer_read_uhwi (ib));
+ for (k = 0; k < ipa_get_param_count (info); k++)
+ info->descriptors[k].move_cost = streamer_read_uhwi (ib);
+
bp = streamer_read_bitpack (ib);
if (ipa_get_param_count (info) != 0)
info->uses_analysis_done = true;
@@ -4049,13 +4297,8 @@ ipa_prop_read_jump_functions (void)
void
ipa_update_after_lto_read (void)
{
- struct cgraph_node *node;
-
ipa_check_create_node_params ();
ipa_check_create_edge_args ();
-
- FOR_EACH_DEFINED_FUNCTION (node)
- ipa_initialize_node_params (node);
}
void
diff --git a/gcc/ipa-prop.h b/gcc/ipa-prop.h
index e3836e0d09a..48634d2e172 100644
--- a/gcc/ipa-prop.h
+++ b/gcc/ipa-prop.h
@@ -117,7 +117,12 @@ struct GTY(()) ipa_pass_through_data
aggregate part of the jump function (see description of
ipa_agg_jump_function). The flag is used only when the operation is
NOP_EXPR. */
- bool agg_preserved;
+ unsigned agg_preserved : 1;
+
+ /* When set to true, we guarantee that, if there is a C++ object pointed to
+ by this object, it does not undergo dynamic type change in the course of
+ functions decribed by this jump function. */
+ unsigned type_preserved : 1;
};
/* Structure holding data required to describe an ancestor pass-through
@@ -132,7 +137,11 @@ struct GTY(()) ipa_ancestor_jf_data
/* Number of the caller's formal parameter being passed. */
int formal_id;
/* Flag with the same meaning like agg_preserve in ipa_pass_through_data. */
- bool agg_preserved;
+ unsigned agg_preserved : 1;
+ /* When set to true, we guarantee that, if there is a C++ object pointed to
+ by this object, it does not undergo dynamic type change in the course of
+ functions decribed by this jump function. */
+ unsigned type_preserved : 1;
};
/* An element in an aggegate part of a jump function describing a known value
@@ -264,7 +273,7 @@ ipa_get_jf_pass_through_operation (struct ipa_jump_func *jfunc)
return jfunc->value.pass_through.operation;
}
-/* Return the agg_preserved flag of a pass through jump functin JFUNC. */
+/* Return the agg_preserved flag of a pass through jump function JFUNC. */
static inline bool
ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
@@ -273,6 +282,15 @@ ipa_get_jf_pass_through_agg_preserved (struct ipa_jump_func *jfunc)
return jfunc->value.pass_through.agg_preserved;
}
+/* Return the type_preserved flag of a pass through jump function JFUNC. */
+
+static inline bool
+ipa_get_jf_pass_through_type_preserved (struct ipa_jump_func *jfunc)
+{
+ gcc_checking_assert (jfunc->type == IPA_JF_PASS_THROUGH);
+ return jfunc->value.pass_through.type_preserved;
+}
+
/* Return the offset of an ancestor jump function JFUNC. */
static inline HOST_WIDE_INT
@@ -301,7 +319,7 @@ ipa_get_jf_ancestor_formal_id (struct ipa_jump_func *jfunc)
return jfunc->value.ancestor.formal_id;
}
-/* Return the agg_preserved flag of an ancestor jump functin JFUNC. */
+/* Return the agg_preserved flag of an ancestor jump function JFUNC. */
static inline bool
ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
@@ -310,6 +328,15 @@ ipa_get_jf_ancestor_agg_preserved (struct ipa_jump_func *jfunc)
return jfunc->value.ancestor.agg_preserved;
}
+/* Return the type_preserved flag of an ancestor jump function JFUNC. */
+
+static inline bool
+ipa_get_jf_ancestor_type_preserved (struct ipa_jump_func *jfunc)
+{
+ gcc_checking_assert (jfunc->type == IPA_JF_ANCESTOR);
+ return jfunc->value.ancestor.type_preserved;
+}
+
/* Summary describing a single formal parameter. */
struct ipa_param_descriptor
@@ -320,6 +347,7 @@ struct ipa_param_descriptor
says how many there are. If any use could not be described by means of
ipa-prop structures, this is IPA_UNDESCRIBED_USE. */
int controlled_uses;
+ unsigned int move_cost : 31;
/* The parameter is used. */
unsigned used : 1;
};
@@ -377,9 +405,19 @@ ipa_get_param_count (struct ipa_node_params *info)
static inline tree
ipa_get_param (struct ipa_node_params *info, int i)
{
+ gcc_checking_assert (!flag_wpa);
return info->descriptors[i].decl;
}
+/* Return the move cost of Ith formal parameter of the function corresponding
+ to INFO. */
+
+static inline int
+ipa_get_param_move_cost (struct ipa_node_params *info, int i)
+{
+ return info->descriptors[i].move_cost;
+}
+
/* Set the used flag corresponding to the Ith formal parameter of the function
associated with INFO to VAL. */
@@ -653,6 +691,7 @@ int ipa_get_param_decl_index (struct ipa_node_params *, tree);
tree ipa_value_from_jfunc (struct ipa_node_params *info,
struct ipa_jump_func *jfunc);
unsigned int ipcp_transform_function (struct cgraph_node *node);
+void ipa_dump_param (FILE *, struct ipa_node_params *info, int i);
/* From tree-sra.c: */
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index b00ae2374a3..ed4deae64fe 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -541,7 +541,8 @@ check_call (funct_state local, gimple call, bool ipa)
}
/* When not in IPA mode, we can still handle self recursion. */
- if (!ipa && callee_t == current_function_decl)
+ if (!ipa && callee_t
+ && recursive_call_p (current_function_decl, callee_t))
{
if (dump_file)
fprintf (dump_file, " Recursive call can loop.\n");
@@ -1079,8 +1080,9 @@ ignore_edge (struct cgraph_edge *e)
}
/* Return true if NODE is self recursive function.
- ??? self recursive and indirectly recursive funcions should
- be the same, so this function seems unnecessary. */
+ Indirectly recursive functions appears as non-trivial strongly
+ connected components, so we need to care about self recursion
+ only. */
static bool
self_recursive_p (struct cgraph_node *node)
@@ -1498,35 +1500,53 @@ gate_pure_const (void)
&& !seen_error ());
}
-struct ipa_opt_pass_d pass_ipa_pure_const =
+namespace {
+
+const pass_data pass_data_ipa_pure_const =
{
- {
- IPA_PASS,
- "pure-const", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_pure_const, /* gate */
- propagate, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_PURE_CONST, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- },
- pure_const_generate_summary, /* generate_summary */
- pure_const_write_summary, /* write_summary */
- pure_const_read_summary, /* read_summary */
- NULL, /* write_optimization_summary */
- NULL, /* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- NULL, /* function_transform */
- NULL /* variable_transform */
+ IPA_PASS, /* type */
+ "pure-const", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_PURE_CONST, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_ipa_pure_const : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_pure_const(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_pure_const, ctxt,
+ pure_const_generate_summary, /* generate_summary */
+ pure_const_write_summary, /* write_summary */
+ pure_const_read_summary, /* read_summary */
+ NULL, /* write_optimization_summary */
+ NULL, /* read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ NULL, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_pure_const (); }
+ unsigned int execute () { return propagate (); }
+
+}; // class pass_ipa_pure_const
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_pure_const (gcc::context *ctxt)
+{
+ return new pass_ipa_pure_const (ctxt);
+}
+
/* Return true if function should be skipped for local pure const analysis. */
static bool
@@ -1664,22 +1684,41 @@ local_pure_const (void)
return 0;
}
-struct gimple_opt_pass pass_local_pure_const =
+namespace {
+
+const pass_data pass_data_local_pure_const =
{
- {
- GIMPLE_PASS,
- "local-pure-const", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_pure_const, /* gate */
- local_pure_const, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_PURE_CONST, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "local-pure-const", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_PURE_CONST, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_local_pure_const : public gimple_opt_pass
+{
+public:
+ pass_local_pure_const(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_local_pure_const, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_local_pure_const (ctxt_); }
+ bool gate () { return gate_pure_const (); }
+ unsigned int execute () { return local_pure_const (); }
+
+}; // class pass_local_pure_const
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_local_pure_const (gcc::context *ctxt)
+{
+ return new pass_local_pure_const (ctxt);
+}
diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c
index a6ffdf3e5bb..a7c3b40b0cf 100644
--- a/gcc/ipa-ref.c
+++ b/gcc/ipa-ref.c
@@ -38,7 +38,7 @@ ipa_record_reference (symtab_node referring_node,
symtab_node referred_node,
enum ipa_ref_use use_type, gimple stmt)
{
- struct ipa_ref *ref;
+ struct ipa_ref *ref, *ref2;
struct ipa_ref_list *list, *list2;
ipa_ref_t *old_references;
@@ -56,14 +56,16 @@ ipa_record_reference (symtab_node referring_node,
ref->referring = referring_node;
ref->referred = referred_node;
ref->stmt = stmt;
+ ref->lto_stmt_uid = 0;
ref->use = use_type;
+ ref->speculative = 0;
/* If vector was moved in memory, update pointers. */
if (old_references != list->references->address ())
{
int i;
- for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
- ipa_ref_referred_ref_list (ref)->referring[ref->referred_index] = ref;
+ for (i = 0; ipa_ref_list_reference_iterate (list, i, ref2); i++)
+ ipa_ref_referred_ref_list (ref2)->referring[ref2->referred_index] = ref2;
}
return ref;
}
@@ -155,6 +157,8 @@ ipa_dump_references (FILE * file, struct ipa_ref_list *list)
symtab_node_asm_name (ref->referred),
ref->referred->symbol.order,
ipa_ref_use_name [ref->use]);
+ if (ref->speculative)
+ fprintf (file, " (speculative)");
}
fprintf (file, "\n");
}
@@ -172,22 +176,50 @@ ipa_dump_referring (FILE * file, struct ipa_ref_list *list)
symtab_node_asm_name (ref->referring),
ref->referring->symbol.order,
ipa_ref_use_name [ref->use]);
+ if (ref->speculative)
+ fprintf (file, " (speculative)");
}
fprintf (file, "\n");
}
+/* Clone reference REF to DEST_NODE and set its stmt to STMT. */
+
+struct ipa_ref *
+ipa_clone_ref (struct ipa_ref *ref,
+ symtab_node dest_node,
+ gimple stmt)
+{
+ bool speculative = ref->speculative;
+ unsigned int stmt_uid = ref->lto_stmt_uid;
+ struct ipa_ref *ref2;
+
+ ref2 = ipa_record_reference (dest_node,
+ ref->referred,
+ ref->use, stmt);
+ ref2->speculative = speculative;
+ ref2->lto_stmt_uid = stmt_uid;
+ return ref2;
+}
+
/* Clone all references from SRC to DEST_NODE or DEST_VARPOOL_NODE. */
void
ipa_clone_references (symtab_node dest_node,
struct ipa_ref_list *src)
{
- struct ipa_ref *ref;
+ struct ipa_ref *ref, *ref2;
int i;
for (i = 0; ipa_ref_list_reference_iterate (src, i, ref); i++)
- ipa_record_reference (dest_node,
- ref->referred,
- ref->use, ref->stmt);
+ {
+ bool speculative = ref->speculative;
+ unsigned int stmt_uid = ref->lto_stmt_uid;
+
+ ref2 = ipa_record_reference (dest_node,
+ ref->referred,
+ ref->use, ref->stmt);
+ ref2->speculative = speculative;
+ ref2->lto_stmt_uid = stmt_uid;
+ }
}
/* Clone all referring from SRC to DEST_NODE or DEST_VARPOOL_NODE. */
@@ -196,12 +228,19 @@ void
ipa_clone_referring (symtab_node dest_node,
struct ipa_ref_list *src)
{
- struct ipa_ref *ref;
+ struct ipa_ref *ref, *ref2;
int i;
for (i = 0; ipa_ref_list_referring_iterate (src, i, ref); i++)
- ipa_record_reference (ref->referring,
- dest_node,
- ref->use, ref->stmt);
+ {
+ bool speculative = ref->speculative;
+ unsigned int stmt_uid = ref->lto_stmt_uid;
+
+ ref2 = ipa_record_reference (ref->referring,
+ dest_node,
+ ref->use, ref->stmt);
+ ref2->speculative = speculative;
+ ref2->lto_stmt_uid = stmt_uid;
+ }
}
/* Return true when execution of REF can lead to return from
@@ -218,6 +257,7 @@ ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list)
{
struct ipa_ref *ref;
int i;
+
for (i = 0; ipa_ref_list_referring_iterate (ref_list, i, ref); i++)
if (ref->use == IPA_REF_ALIAS)
return true;
@@ -229,14 +269,17 @@ ipa_ref_has_aliases_p (struct ipa_ref_list *ref_list)
struct ipa_ref *
ipa_find_reference (symtab_node referring_node, symtab_node referred_node,
- gimple stmt)
+ gimple stmt, unsigned int lto_stmt_uid)
{
struct ipa_ref *r = NULL;
int i;
- FOR_EACH_VEC_SAFE_ELT (referring_node->symbol.ref_list.references, i, r)
+ for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
if (r->referred == referred_node
- && (in_lto_p || r->stmt == stmt))
+ && !r->speculative
+ && ((stmt && r->stmt == stmt)
+ || (lto_stmt_uid && r->lto_stmt_uid == lto_stmt_uid)
+ || (!stmt && !lto_stmt_uid && !r->stmt && !r->lto_stmt_uid)))
return r;
return NULL;
}
@@ -250,7 +293,26 @@ ipa_remove_stmt_references (symtab_node referring_node, gimple stmt)
struct ipa_ref *r = NULL;
int i;
- FOR_EACH_VEC_SAFE_ELT (referring_node->symbol.ref_list.references, i, r)
+ for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
if (r->stmt == stmt)
ipa_remove_reference (r);
}
+
+/* Remove all stmt references in non-speculative references.
+ Those are not maintained during inlining & clonning.
+ The exception are speculative references that are updated along
+ with callgraph edges associated with them. */
+
+void
+ipa_clear_stmts_in_references (symtab_node referring_node)
+{
+ struct ipa_ref *r = NULL;
+ int i;
+
+ for (i = 0; ipa_ref_list_reference_iterate (&referring_node->symbol.ref_list, i, r); i++)
+ if (!r->speculative)
+ {
+ r->stmt = NULL;
+ r->lto_stmt_uid = 0;
+ }
+}
diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h
index c25e4e46f9d..e0553bb6609 100644
--- a/gcc/ipa-ref.h
+++ b/gcc/ipa-ref.h
@@ -40,8 +40,10 @@ struct GTY(()) ipa_ref
symtab_node referring;
symtab_node referred;
gimple stmt;
+ unsigned int lto_stmt_uid;
unsigned int referred_index;
ENUM_BITFIELD (ipa_ref_use) use:2;
+ unsigned int speculative:1;
};
typedef struct ipa_ref ipa_ref_t;
@@ -71,7 +73,9 @@ void ipa_dump_references (FILE *, struct ipa_ref_list *);
void ipa_dump_referring (FILE *, struct ipa_ref_list *);
void ipa_clone_references (symtab_node, struct ipa_ref_list *);
void ipa_clone_referring (symtab_node, struct ipa_ref_list *);
+struct ipa_ref * ipa_clone_ref (struct ipa_ref *, symtab_node, gimple);
bool ipa_ref_cannot_lead_to_return (struct ipa_ref *);
bool ipa_ref_has_aliases_p (struct ipa_ref_list *);
-struct ipa_ref * ipa_find_reference (symtab_node, symtab_node, gimple);
+struct ipa_ref * ipa_find_reference (symtab_node, symtab_node, gimple, unsigned int);
void ipa_remove_stmt_references (symtab_node, gimple);
+void ipa_clear_stmts_in_references (symtab_node);
diff --git a/gcc/ipa-reference.c b/gcc/ipa-reference.c
index 9c56b7f5518..3742474ed65 100644
--- a/gcc/ipa-reference.c
+++ b/gcc/ipa-reference.c
@@ -1155,31 +1155,51 @@ gate_reference (void)
&& !seen_error ());
}
-struct ipa_opt_pass_d pass_ipa_reference =
+namespace {
+
+const pass_data pass_data_ipa_reference =
{
- {
- IPA_PASS,
- "static-var", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_reference, /* gate */
- propagate, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_REFERENCE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- },
- NULL, /* generate_summary */
- NULL, /* write_summary */
- NULL, /* read_summary */
- ipa_reference_write_optimization_summary,/* write_optimization_summary */
- ipa_reference_read_optimization_summary,/* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- NULL, /* function_transform */
- NULL /* variable_transform */
+ IPA_PASS, /* type */
+ "static-var", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_REFERENCE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_ipa_reference : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_reference(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_reference, ctxt,
+ NULL, /* generate_summary */
+ NULL, /* write_summary */
+ NULL, /* read_summary */
+ ipa_reference_write_optimization_summary, /*
+ write_optimization_summary */
+ ipa_reference_read_optimization_summary, /*
+ read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ NULL, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_reference (); }
+ unsigned int execute () { return propagate (); }
+
+}; // class pass_ipa_reference
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_reference (gcc::context *ctxt)
+{
+ return new pass_ipa_reference (ctxt);
+}
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index e786478981e..5df14ecb703 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -1222,7 +1222,11 @@ split_function (struct split_point *split_point)
DECL_BUILT_IN_CLASS (node->symbol.decl) = NOT_BUILT_IN;
DECL_FUNCTION_CODE (node->symbol.decl) = (enum built_in_function) 0;
}
+ /* If the original function is declared inline, there is no point in issuing
+ a warning for the non-inlinable part. */
+ DECL_NO_INLINE_WARNING_P (node->symbol.decl) = 1;
cgraph_node_remove_callees (cur_node);
+ ipa_remove_all_references (&cur_node->symbol.ref_list);
if (!split_part_return_p)
TREE_THIS_VOLATILE (node->symbol.decl) = 1;
if (dump_file)
@@ -1536,7 +1540,9 @@ execute_split_functions (void)
Note that we are not completely conservative about disqualifying functions
called once. It is possible that the caller is called more then once and
then inlining would still benefit. */
- if ((!node->callers || !node->callers->next_caller)
+ if ((!node->callers
+ /* Local functions called once will be completely inlined most of time. */
+ || (!node->callers->next_caller && node->local.local))
&& !node->symbol.address_taken
&& (!flag_lto || !node->symbol.externally_visible))
{
@@ -1624,26 +1630,44 @@ gate_split_functions (void)
&& !profile_arc_flag && !flag_branch_probabilities);
}
-struct gimple_opt_pass pass_split_functions =
+namespace {
+
+const pass_data pass_data_split_functions =
{
- {
- GIMPLE_PASS,
- "fnsplit", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_split_functions, /* gate */
- execute_split_functions, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_FNSPLIT, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_all /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "fnsplit", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_FNSPLIT, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_all, /* todo_flags_finish */
};
+class pass_split_functions : public gimple_opt_pass
+{
+public:
+ pass_split_functions(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_split_functions, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_split_functions (); }
+ unsigned int execute () { return execute_split_functions (); }
+
+}; // class pass_split_functions
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_split_functions (gcc::context *ctxt)
+{
+ return new pass_split_functions (ctxt);
+}
+
/* Gate feedback driven function splitting pass.
We don't need to split when profiling at all, we are producing
lousy code anyway. */
@@ -1666,22 +1690,40 @@ execute_feedback_split_functions (void)
return retval;
}
-struct gimple_opt_pass pass_feedback_split_functions =
+namespace {
+
+const pass_data pass_data_feedback_split_functions =
{
- {
- GIMPLE_PASS,
- "feedback_fnsplit", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_feedback_split_functions, /* gate */
- execute_feedback_split_functions, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_FNSPLIT, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_all /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "feedback_fnsplit", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_FNSPLIT, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_all, /* todo_flags_finish */
};
+
+class pass_feedback_split_functions : public gimple_opt_pass
+{
+public:
+ pass_feedback_split_functions(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_feedback_split_functions, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_feedback_split_functions (); }
+ unsigned int execute () { return execute_feedback_split_functions (); }
+
+}; // class pass_feedback_split_functions
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_feedback_split_functions (gcc::context *ctxt)
+{
+ return new pass_feedback_split_functions (ctxt);
+}
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index 00e65285c54..e2e169043bc 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -37,6 +37,8 @@ along with GCC; see the file COPYING3. If not see
#include "flags.h"
#include "diagnostic.h"
#include "langhooks.h"
+#include "lto-streamer.h"
+#include "ipa-inline.h"
/* Debugging function for postorder and inorder code. NOTE is a string
that is printed before the nodes are printed. ORDER is an array of
@@ -618,3 +620,185 @@ debug_varpool_node_set (varpool_node_set set)
{
dump_varpool_node_set (stderr, set);
}
+
+
+/* SRC and DST are going to be merged. Take SRC's profile and merge it into
+ DST so it is not going to be lost. Destroy SRC's body on the way. */
+
+void
+ipa_merge_profiles (struct cgraph_node *dst,
+ struct cgraph_node *src)
+{
+ tree oldsrcdecl = src->symbol.decl;
+ struct function *srccfun, *dstcfun;
+ bool match = true;
+
+ if (!src->symbol.definition
+ || !dst->symbol.definition)
+ return;
+ if (src->frequency < dst->frequency)
+ src->frequency = dst->frequency;
+ if (!dst->count)
+ return;
+ if (cgraph_dump_file)
+ {
+ fprintf (cgraph_dump_file, "Merging profiles of %s/%i to %s/%i\n",
+ xstrdup (cgraph_node_name (src)), src->symbol.order,
+ xstrdup (cgraph_node_name (dst)), dst->symbol.order);
+ }
+ dst->count += src->count;
+
+ /* This is ugly. We need to get both function bodies into memory.
+ If declaration is merged, we need to duplicate it to be able
+ to load body that is being replaced. This makes symbol table
+ temporarily inconsistent. */
+ if (src->symbol.decl == dst->symbol.decl)
+ {
+ void **slot;
+ struct lto_in_decl_state temp;
+ struct lto_in_decl_state *state;
+
+ /* We are going to move the decl, we want to remove its file decl data.
+ and link these with the new decl. */
+ temp.fn_decl = src->symbol.decl;
+ slot = htab_find_slot (src->symbol.lto_file_data->function_decl_states,
+ &temp, NO_INSERT);
+ state = (lto_in_decl_state *)*slot;
+ htab_clear_slot (src->symbol.lto_file_data->function_decl_states, slot);
+ gcc_assert (state);
+
+ /* Duplicate the decl and be sure it does not link into body of DST. */
+ src->symbol.decl = copy_node (src->symbol.decl);
+ DECL_STRUCT_FUNCTION (src->symbol.decl) = NULL;
+ DECL_ARGUMENTS (src->symbol.decl) = NULL;
+ DECL_INITIAL (src->symbol.decl) = NULL;
+ DECL_RESULT (src->symbol.decl) = NULL;
+
+ /* Associate the decl state with new declaration, so LTO streamer
+ can look it up. */
+ state->fn_decl = src->symbol.decl;
+ slot = htab_find_slot (src->symbol.lto_file_data->function_decl_states,
+ state, INSERT);
+ gcc_assert (!*slot);
+ *slot = state;
+ }
+ cgraph_get_body (src);
+ cgraph_get_body (dst);
+ srccfun = DECL_STRUCT_FUNCTION (src->symbol.decl);
+ dstcfun = DECL_STRUCT_FUNCTION (dst->symbol.decl);
+ if (n_basic_blocks_for_function (srccfun)
+ != n_basic_blocks_for_function (dstcfun))
+ {
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "Giving up; number of basic block mismatch.\n");
+ match = false;
+ }
+ else if (last_basic_block_for_function (srccfun)
+ != last_basic_block_for_function (dstcfun))
+ {
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "Giving up; last block mismatch.\n");
+ match = false;
+ }
+ else
+ {
+ basic_block srcbb, dstbb;
+
+ FOR_ALL_BB_FN (srcbb, srccfun)
+ {
+ unsigned int i;
+
+ dstbb = BASIC_BLOCK_FOR_FUNCTION (dstcfun, srcbb->index);
+ if (dstbb == NULL)
+ {
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "No matching block for bb %i.\n",
+ srcbb->index);
+ match = false;
+ break;
+ }
+ if (EDGE_COUNT (srcbb->succs) != EDGE_COUNT (dstbb->succs))
+ {
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "Edge count mistmatch for bb %i.\n",
+ srcbb->index);
+ match = false;
+ break;
+ }
+ for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
+ {
+ edge srce = EDGE_SUCC (srcbb, i);
+ edge dste = EDGE_SUCC (dstbb, i);
+ if (srce->dest->index != dste->dest->index)
+ {
+ if (cgraph_dump_file)
+ fprintf (cgraph_dump_file,
+ "Succ edge mistmatch for bb %i.\n",
+ srce->dest->index);
+ match = false;
+ break;
+ }
+ }
+ }
+ }
+ if (match)
+ {
+ struct cgraph_edge *e;
+ basic_block srcbb, dstbb;
+
+ /* TODO: merge also statement histograms. */
+ FOR_ALL_BB_FN (srcbb, srccfun)
+ {
+ unsigned int i;
+
+ dstbb = BASIC_BLOCK_FOR_FUNCTION (dstcfun, srcbb->index);
+ dstbb->count += srcbb->count;
+ for (i = 0; i < EDGE_COUNT (srcbb->succs); i++)
+ {
+ edge srce = EDGE_SUCC (srcbb, i);
+ edge dste = EDGE_SUCC (dstbb, i);
+ dste->count += srce->count;
+ }
+ }
+ push_cfun (dstcfun);
+ counts_to_freqs ();
+ compute_function_frequency ();
+ pop_cfun ();
+ for (e = dst->callees; e; e = e->next_callee)
+ {
+ gcc_assert (!e->speculative);
+ e->count = gimple_bb (e->call_stmt)->count;
+ e->frequency = compute_call_stmt_bb_frequency
+ (dst->symbol.decl,
+ gimple_bb (e->call_stmt));
+ }
+ for (e = dst->indirect_calls; e; e = e->next_callee)
+ {
+ gcc_assert (!e->speculative);
+ e->count = gimple_bb (e->call_stmt)->count;
+ e->frequency = compute_call_stmt_bb_frequency
+ (dst->symbol.decl,
+ gimple_bb (e->call_stmt));
+ }
+ cgraph_release_function_body (src);
+ inline_update_overall_summary (dst);
+ }
+ /* TODO: if there is no match, we can scale up. */
+ src->symbol.decl = oldsrcdecl;
+}
+
+/* Return true if call to DEST is known to be self-recusive call withing FUNC. */
+
+bool
+recursive_call_p (tree func, tree dest)
+{
+ struct cgraph_node *dest_node = cgraph_get_create_node (dest);
+ struct cgraph_node *cnode = cgraph_get_create_node (func);
+
+ return symtab_semantically_equivalent_p ((symtab_node)dest_node,
+ (symtab_node)cnode);
+}
diff --git a/gcc/ipa-utils.h b/gcc/ipa-utils.h
index f388598eafb..d6f390daf15 100644
--- a/gcc/ipa-utils.h
+++ b/gcc/ipa-utils.h
@@ -36,7 +36,6 @@ struct ipa_dfs_info {
};
-
/* In ipa-utils.c */
void ipa_print_order (FILE*, const char *, struct cgraph_node**, int);
int ipa_reduced_postorder (struct cgraph_node **, bool, bool,
@@ -45,8 +44,70 @@ void ipa_free_postorder_info (void);
vec<cgraph_node_ptr> ipa_get_nodes_in_cycle (struct cgraph_node *);
int ipa_reverse_postorder (struct cgraph_node **);
tree get_base_var (tree);
+void ipa_merge_profiles (struct cgraph_node *dst,
+ struct cgraph_node *src);
+bool recursive_call_p (tree, tree);
+
+/* In ipa-profile.c */
+bool ipa_propagate_frequency (struct cgraph_node *node);
+
+/* In ipa-devirt.c */
+
+struct odr_type_d;
+typedef odr_type_d *odr_type;
+void build_type_inheritance_graph (void);
+void update_type_inheritance_graph (void);
+vec <cgraph_node *>
+possible_polymorphic_call_targets (tree, HOST_WIDE_INT,
+ bool *final = NULL,
+ void **cache_token = NULL);
+odr_type get_odr_type (tree, bool insert = false);
+void dump_possible_polymorphic_call_targets (FILE *, tree, HOST_WIDE_INT);
+bool possible_polymorphic_call_target_p (tree, HOST_WIDE_INT,
+ struct cgraph_node *n);
+tree method_class_type (tree);
+
+/* Return vector containing possible targets of polymorphic call E.
+ If FINALP is non-NULL, store true if the list is complette.
+ CACHE_TOKEN (if non-NULL) will get stored to an unique ID of entry
+ in the target cache. If user needs to visit every target list
+ just once, it can memoize them.
+
+ Returned vector is placed into cache. It is NOT caller's responsibility
+ to free it. The vector can be freed on cgraph_remove_node call if
+ the particular node is a virtual function present in the cache. */
+
+inline vec <cgraph_node *>
+possible_polymorphic_call_targets (struct cgraph_edge *e,
+ bool *final = NULL,
+ void **cache_token = NULL)
+{
+ gcc_checking_assert (e->indirect_info->polymorphic);
+ return possible_polymorphic_call_targets (e->indirect_info->otr_type,
+ e->indirect_info->otr_token,
+ final, cache_token);
+}
+
+/* Dump possible targets of a polymorphic call E into F. */
+
+inline void
+dump_possible_polymorphic_call_targets (FILE *f, struct cgraph_edge *e)
+{
+ gcc_checking_assert (e->indirect_info->polymorphic);
+ dump_possible_polymorphic_call_targets (f, e->indirect_info->otr_type,
+ e->indirect_info->otr_token);
+}
+/* Return true if N can be possibly target of a polymorphic call of
+ E. */
+inline bool
+possible_polymorphic_call_target_p (struct cgraph_edge *e,
+ struct cgraph_node *n)
+{
+ return possible_polymorphic_call_target_p (e->indirect_info->otr_type,
+ e->indirect_info->otr_token, n);
+}
#endif /* GCC_IPA_UTILS_H */
diff --git a/gcc/ipa.c b/gcc/ipa.c
index e20e561a2a0..91d63eb9f85 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -30,14 +30,10 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "tree-iterator.h"
#include "ipa-utils.h"
-#include "pointer-set.h"
#include "ipa-inline.h"
-#include "hash-table.h"
#include "tree-inline.h"
#include "profile.h"
#include "params.h"
-#include "lto-streamer.h"
-#include "data-streamer.h"
/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
@@ -153,6 +149,84 @@ process_references (struct ipa_ref_list *list,
}
}
+/* EDGE is an polymorphic call. If BEFORE_INLINING_P is set, mark
+ all its potential targets as reachable to permit later inlining if
+ devirtualization happens. After inlining still keep their declarations
+ around, so we can devirtualize to a direct call.
+
+ Also try to make trivial devirutalization when no or only one target is
+ possible. */
+
+static void
+walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
+ struct cgraph_edge *edge,
+ symtab_node *first,
+ pointer_set_t *reachable, bool before_inlining_p)
+{
+ unsigned int i;
+ void *cache_token;
+ bool final;
+ vec <cgraph_node *>targets
+ = possible_polymorphic_call_targets
+ (edge, &final, &cache_token);
+
+ if (!pointer_set_insert (reachable_call_targets,
+ cache_token))
+ {
+ for (i = 0; i < targets.length(); i++)
+ {
+ struct cgraph_node *n = targets[i];
+
+ /* Do not bother to mark virtual methods in anonymous namespace;
+ either we will find use of virtual table defining it, or it is
+ unused. */
+ if (TREE_CODE (TREE_TYPE (n->symbol.decl)) == METHOD_TYPE
+ && type_in_anonymous_namespace_p
+ (method_class_type (TREE_TYPE (n->symbol.decl))))
+ continue;
+
+ /* Prior inlining, keep alive bodies of possible targets for
+ devirtualization. */
+ if (n->symbol.definition
+ && before_inlining_p)
+ pointer_set_insert (reachable, n);
+
+ /* Even after inlining we want to keep the possible targets in the
+ boundary, so late passes can still produce direct call even if
+ the chance for inlining is lost. */
+ enqueue_node ((symtab_node) n, first, reachable);
+ }
+ }
+
+ /* Very trivial devirtualization; when the type is
+ final or anonymous (so we know all its derivation)
+ and there is only one possible virtual call target,
+ make the edge direct. */
+ if (final)
+ {
+ if (targets.length() <= 1)
+ {
+ cgraph_node *target, *node = edge->caller;
+ if (targets.length () == 1)
+ target = targets[0];
+ else
+ target = cgraph_get_create_node
+ (builtin_decl_implicit (BUILT_IN_UNREACHABLE));
+
+ if (dump_file)
+ fprintf (dump_file,
+ "Devirtualizing call in %s/%i to %s/%i\n",
+ cgraph_node_name (edge->caller),
+ edge->caller->symbol.order,
+ cgraph_node_name (target), target->symbol.order);
+ edge = cgraph_make_edge_direct (edge, target);
+ if (!inline_summary_vec && edge->call_stmt)
+ cgraph_redirect_edge_call_stmt_to_callee (edge);
+ else
+ inline_update_overall_summary (node);
+ }
+ }
+}
/* Perform reachability analysis and reclaim all unreachable nodes.
@@ -218,10 +292,14 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
bool changed = false;
struct pointer_set_t *reachable = pointer_set_create ();
struct pointer_set_t *body_needed_for_clonning = pointer_set_create ();
+ struct pointer_set_t *reachable_call_targets = pointer_set_create ();
+ timevar_push (TV_IPA_UNREACHABLE);
#ifdef ENABLE_CHECKING
verify_symtab ();
#endif
+ if (optimize && flag_devirtualize)
+ build_type_inheritance_graph ();
if (file)
fprintf (file, "\nReclaiming functions:");
#ifdef ENABLE_CHECKING
@@ -234,20 +312,21 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
This is mostly when they can be referenced externally. Inline clones
are special since their declarations are shared with master clone and thus
cgraph_can_remove_if_no_direct_calls_and_refs_p should not be called on them. */
- FOR_EACH_DEFINED_FUNCTION (node)
- if (!node->global.inlined_to
- && !node->symbol.in_other_partition
- && (!cgraph_can_remove_if_no_direct_calls_and_refs_p (node)
- /* Keep around virtual functions for possible devirtualization. */
- || (before_inlining_p
- && DECL_VIRTUAL_P (node->symbol.decl))))
- {
- gcc_assert (!node->global.inlined_to);
- pointer_set_insert (reachable, node);
- enqueue_node ((symtab_node)node, &first, reachable);
- }
- else
- gcc_assert (!node->symbol.aux);
+ FOR_EACH_FUNCTION (node)
+ {
+ node->used_as_abstract_origin = false;
+ if (node->symbol.definition
+ && !node->global.inlined_to
+ && !node->symbol.in_other_partition
+ && !cgraph_can_remove_if_no_direct_calls_and_refs_p (node))
+ {
+ gcc_assert (!node->global.inlined_to);
+ pointer_set_insert (reachable, node);
+ enqueue_node ((symtab_node)node, &first, reachable);
+ }
+ else
+ gcc_assert (!node->symbol.aux);
+ }
/* Mark variables that are obviously needed. */
FOR_EACH_DEFINED_VARIABLE (vnode)
@@ -272,6 +351,13 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
node->symbol.aux = (void *)2;
else
{
+ if (DECL_ABSTRACT_ORIGIN (node->symbol.decl))
+ {
+ struct cgraph_node *origin_node
+ = cgraph_get_create_real_symbol_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
+ origin_node->used_as_abstract_origin = true;
+ enqueue_node ((symtab_node) origin_node, &first, reachable);
+ }
/* If any symbol in a comdat group is reachable, force
all other in the same comdat group to be also reachable. */
if (node->symbol.same_comdat_group)
@@ -295,6 +381,19 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
if (!in_boundary_p)
{
struct cgraph_edge *e;
+ /* Keep alive possible targets for devirtualization. */
+ if (optimize && flag_devirtualize)
+ {
+ struct cgraph_edge *next;
+ for (e = cnode->indirect_calls; e; e = next)
+ {
+ next = e->next_callee;
+ if (e->indirect_info->polymorphic)
+ walk_polymorphic_call_targets (reachable_call_targets,
+ e, &first, reachable,
+ before_inlining_p);
+ }
+ }
for (e = cnode->callees; e; e = e->next_callee)
{
if (e->callee->symbol.definition
@@ -360,18 +459,26 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl))
cgraph_release_function_body (node);
else if (!node->clone_of)
- gcc_assert (DECL_RESULT (node->symbol.decl));
+ gcc_assert (in_lto_p || DECL_RESULT (node->symbol.decl));
if (node->symbol.definition)
{
if (file)
fprintf (file, " %s", cgraph_node_name (node));
- cgraph_reset_node (node);
+ node->symbol.analyzed = false;
+ node->symbol.definition = false;
+ node->symbol.cpp_implicit_alias = false;
+ node->symbol.alias = false;
+ node->symbol.weakref = false;
+ if (!node->symbol.in_other_partition)
+ node->local.local = false;
+ cgraph_node_remove_callees (node);
+ ipa_remove_all_references (&node->symbol.ref_list);
changed = true;
}
}
else
gcc_assert (node->clone_of || !cgraph_function_with_gimple_body_p (node)
- || DECL_RESULT (node->symbol.decl));
+ || in_lto_p || DECL_RESULT (node->symbol.decl));
}
/* Inline clones might be kept around so their materializing allows further
@@ -432,6 +539,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
pointer_set_destroy (reachable);
pointer_set_destroy (body_needed_for_clonning);
+ pointer_set_destroy (reachable_call_targets);
/* Now update address_taken flags and try to promote functions to be local. */
if (file)
@@ -464,8 +572,9 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
/* If we removed something, perhaps profile could be improved. */
if (changed && optimize && inline_edge_summary_vec.exists ())
FOR_EACH_DEFINED_FUNCTION (node)
- cgraph_propagate_frequency (node);
+ ipa_propagate_frequency (node);
+ timevar_pop (TV_IPA_UNREACHABLE);
return changed;
}
@@ -554,9 +663,13 @@ static bool
comdat_can_be_unshared_p_1 (symtab_node node)
{
/* When address is taken, we don't know if equality comparison won't
- break eventually. Exception are virutal functions and vtables,
- where this is not possible by language standard. */
+ break eventually. Exception are virutal functions, C++
+ constructors/destructors and vtables, where this is not possible by
+ language standard. */
if (!DECL_VIRTUAL_P (node->symbol.decl)
+ && (TREE_CODE (node->symbol.decl) != FUNCTION_DECL
+ || (!DECL_CXX_CONSTRUCTOR_P (node->symbol.decl)
+ && !DECL_CXX_DESTRUCTOR_P (node->symbol.decl)))
&& address_taken_from_non_vtable_p (node))
return false;
@@ -740,6 +853,17 @@ varpool_externally_visible_p (struct varpool_node *vnode)
return false;
}
+/* Return true if reference to NODE can be replaced by a local alias.
+ Local aliases save dynamic linking overhead and enable more optimizations.
+ */
+
+bool
+can_replace_by_local_alias (symtab_node node)
+{
+ return (symtab_node_availability (node) > AVAIL_OVERWRITABLE
+ && !symtab_can_be_discarded (node));
+}
+
/* Mark visibility of all functions.
A local function is one whose calls can occur only in the current
@@ -861,7 +985,36 @@ function_and_variable_visibility (bool whole_program)
}
}
FOR_EACH_DEFINED_FUNCTION (node)
- node->local.local = cgraph_local_node_p (node);
+ {
+ node->local.local |= cgraph_local_node_p (node);
+
+ /* If we know that function can not be overwritten by a different semantics
+ and moreover its section can not be discarded, replace all direct calls
+ by calls to an nonoverwritable alias. This make dynamic linking
+ cheaper and enable more optimization.
+
+ TODO: We can also update virtual tables. */
+ if (node->callers && can_replace_by_local_alias ((symtab_node)node))
+ {
+ struct cgraph_node *alias = cgraph (symtab_nonoverwritable_alias ((symtab_node) node));
+
+ if (alias != node)
+ {
+ while (node->callers)
+ {
+ struct cgraph_edge *e = node->callers;
+
+ cgraph_redirect_edge_callee (e, alias);
+ if (gimple_has_body_p (e->caller->symbol.decl))
+ {
+ push_cfun (DECL_STRUCT_FUNCTION (e->caller->symbol.decl));
+ cgraph_redirect_edge_call_stmt_to_callee (e);
+ pop_cfun ();
+ }
+ }
+ }
+ }
+ }
FOR_EACH_VARIABLE (vnode)
{
/* weak flag makes no sense on local variables. */
@@ -908,10 +1061,10 @@ function_and_variable_visibility (bool whole_program)
&& !vnode->symbol.weakref)
{
gcc_assert (in_lto_p || whole_program || !TREE_PUBLIC (vnode->symbol.decl));
- symtab_make_decl_local (vnode->symbol.decl);
vnode->symbol.unique_name = ((vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
|| vnode->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
&& TREE_PUBLIC (vnode->symbol.decl));
+ symtab_make_decl_local (vnode->symbol.decl);
if (vnode->symbol.same_comdat_group)
symtab_dissolve_same_comdat_group_list ((symtab_node) vnode);
vnode->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
@@ -949,450 +1102,161 @@ local_function_and_variable_visibility (void)
return function_and_variable_visibility (flag_whole_program && !flag_lto);
}
-struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
+namespace {
+
+const pass_data pass_data_ipa_function_and_variable_visibility =
{
- {
- SIMPLE_IPA_PASS,
- "visibility", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- local_function_and_variable_visibility,/* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CGRAPHOPT, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_remove_functions | TODO_dump_symtab /* todo_flags_finish */
- }
+ SIMPLE_IPA_PASS, /* type */
+ "visibility", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_CGRAPHOPT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
};
-/* Free inline summary. */
-
-static unsigned
-free_inline_summary (void)
+class pass_ipa_function_and_variable_visibility : public simple_ipa_opt_pass
{
- inline_free_summary ();
- return 0;
-}
+public:
+ pass_ipa_function_and_variable_visibility(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_ipa_function_and_variable_visibility, ctxt)
+ {}
-struct simple_ipa_opt_pass pass_ipa_free_inline_summary =
-{
- {
- SIMPLE_IPA_PASS,
- "*free_inline_summary", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- free_inline_summary, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
-};
+ /* opt_pass methods: */
+ unsigned int execute () {
+ return local_function_and_variable_visibility ();
+ }
-/* Do not re-run on ltrans stage. */
+}; // class pass_ipa_function_and_variable_visibility
-static bool
-gate_whole_program_function_and_variable_visibility (void)
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt)
{
- return !flag_ltrans;
+ return new pass_ipa_function_and_variable_visibility (ctxt);
}
-/* Bring functionss local at LTO time with -fwhole-program. */
+/* Free inline summary. */
-static unsigned int
-whole_program_function_and_variable_visibility (void)
+static unsigned
+free_inline_summary (void)
{
- function_and_variable_visibility (flag_whole_program);
- if (optimize)
- ipa_discover_readonly_nonaddressable_vars ();
+ inline_free_summary ();
return 0;
}
-struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
-{
- {
- IPA_PASS,
- "whole-program", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_whole_program_function_and_variable_visibility,/* gate */
- whole_program_function_and_variable_visibility,/* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CGRAPHOPT, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_remove_functions | TODO_dump_symtab /* todo_flags_finish */
- },
- NULL, /* generate_summary */
- NULL, /* write_summary */
- NULL, /* read_summary */
- NULL, /* write_optimization_summary */
- NULL, /* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- NULL, /* function_transform */
- NULL, /* variable_transform */
-};
-
-/* Entry in the histogram. */
-
-struct histogram_entry
-{
- gcov_type count;
- int time;
- int size;
-};
-
-/* Histogram of profile values.
- The histogram is represented as an ordered vector of entries allocated via
- histogram_pool. During construction a separate hashtable is kept to lookup
- duplicate entries. */
+namespace {
-vec<histogram_entry *> histogram;
-static alloc_pool histogram_pool;
-
-/* Hashtable support for storing SSA names hashed by their SSA_NAME_VAR. */
-
-struct histogram_hash : typed_noop_remove <histogram_entry>
+const pass_data pass_data_ipa_free_inline_summary =
{
- typedef histogram_entry value_type;
- typedef histogram_entry compare_type;
- static inline hashval_t hash (const value_type *);
- static inline int equal (const value_type *, const compare_type *);
+ SIMPLE_IPA_PASS, /* type */
+ "*free_inline_summary", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_FREE_INLINE_SUMMARY, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
-inline hashval_t
-histogram_hash::hash (const histogram_entry *val)
-{
- return val->count;
-}
-
-inline int
-histogram_hash::equal (const histogram_entry *val, const histogram_entry *val2)
-{
- return val->count == val2->count;
-}
-
-/* Account TIME and SIZE executed COUNT times into HISTOGRAM.
- HASHTABLE is the on-side hash kept to avoid duplicates. */
-
-static void
-account_time_size (hash_table <histogram_hash> hashtable,
- vec<histogram_entry *> &histogram,
- gcov_type count, int time, int size)
+class pass_ipa_free_inline_summary : public simple_ipa_opt_pass
{
- histogram_entry key = {count, 0, 0};
- histogram_entry **val = hashtable.find_slot (&key, INSERT);
+public:
+ pass_ipa_free_inline_summary(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_ipa_free_inline_summary, ctxt)
+ {}
- if (!*val)
- {
- *val = (histogram_entry *) pool_alloc (histogram_pool);
- **val = key;
- histogram.safe_push (*val);
- }
- (*val)->time += time;
- (*val)->size += size;
-}
+ /* opt_pass methods: */
+ unsigned int execute () { return free_inline_summary (); }
-int
-cmp_counts (const void *v1, const void *v2)
-{
- const histogram_entry *h1 = *(const histogram_entry * const *)v1;
- const histogram_entry *h2 = *(const histogram_entry * const *)v2;
- if (h1->count < h2->count)
- return 1;
- if (h1->count > h2->count)
- return -1;
- return 0;
-}
+}; // class pass_ipa_free_inline_summary
-/* Dump HISTOGRAM to FILE. */
+} // anon namespace
-static void
-dump_histogram (FILE *file, vec<histogram_entry *> histogram)
+simple_ipa_opt_pass *
+make_pass_ipa_free_inline_summary (gcc::context *ctxt)
{
- unsigned int i;
- gcov_type overall_time = 0, cumulated_time = 0, cumulated_size = 0, overall_size = 0;
-
- fprintf (dump_file, "Histogram:\n");
- for (i = 0; i < histogram.length (); i++)
- {
- overall_time += histogram[i]->count * histogram[i]->time;
- overall_size += histogram[i]->size;
- }
- if (!overall_time)
- overall_time = 1;
- if (!overall_size)
- overall_size = 1;
- for (i = 0; i < histogram.length (); i++)
- {
- cumulated_time += histogram[i]->count * histogram[i]->time;
- cumulated_size += histogram[i]->size;
- fprintf (file, " "HOST_WIDEST_INT_PRINT_DEC": time:%i (%2.2f) size:%i (%2.2f)\n",
- (HOST_WIDEST_INT) histogram[i]->count,
- histogram[i]->time,
- cumulated_time * 100.0 / overall_time,
- histogram[i]->size,
- cumulated_size * 100.0 / overall_size);
- }
+ return new pass_ipa_free_inline_summary (ctxt);
}
-/* Collect histogram from CFG profiles. */
+/* Do not re-run on ltrans stage. */
-static void
-ipa_profile_generate_summary (void)
+static bool
+gate_whole_program_function_and_variable_visibility (void)
{
- struct cgraph_node *node;
- gimple_stmt_iterator gsi;
- hash_table <histogram_hash> hashtable;
- basic_block bb;
-
- hashtable.create (10);
- histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
- 10);
-
- FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
- FOR_EACH_BB_FN (bb, DECL_STRUCT_FUNCTION (node->symbol.decl))
- {
- int time = 0;
- int size = 0;
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
- {
- time += estimate_num_insns (gsi_stmt (gsi), &eni_time_weights);
- size += estimate_num_insns (gsi_stmt (gsi), &eni_size_weights);
- }
- account_time_size (hashtable, histogram, bb->count, time, size);
- }
- hashtable.dispose ();
- histogram.qsort (cmp_counts);
+ return !flag_ltrans;
}
-/* Serialize the ipa info for lto. */
+/* Bring functionss local at LTO time with -fwhole-program. */
-static void
-ipa_profile_write_summary (void)
+static unsigned int
+whole_program_function_and_variable_visibility (void)
{
- struct lto_simple_output_block *ob
- = lto_create_simple_output_block (LTO_section_ipa_profile);
- unsigned int i;
-
- streamer_write_uhwi_stream (ob->main_stream, histogram.length());
- for (i = 0; i < histogram.length (); i++)
- {
- streamer_write_gcov_count_stream (ob->main_stream, histogram[i]->count);
- streamer_write_uhwi_stream (ob->main_stream, histogram[i]->time);
- streamer_write_uhwi_stream (ob->main_stream, histogram[i]->size);
- }
- lto_destroy_simple_output_block (ob);
+ function_and_variable_visibility (flag_whole_program);
+ if (optimize)
+ ipa_discover_readonly_nonaddressable_vars ();
+ return 0;
}
-/* Deserialize the ipa info for lto. */
+namespace {
-static void
-ipa_profile_read_summary (void)
+const pass_data pass_data_ipa_whole_program_visibility =
{
- struct lto_file_decl_data ** file_data_vec
- = lto_get_file_decl_data ();
- struct lto_file_decl_data * file_data;
- hash_table <histogram_hash> hashtable;
- int j = 0;
-
- hashtable.create (10);
- histogram_pool = create_alloc_pool ("IPA histogram", sizeof (struct histogram_entry),
- 10);
-
- while ((file_data = file_data_vec[j++]))
- {
- const char *data;
- size_t len;
- struct lto_input_block *ib
- = lto_create_simple_input_block (file_data,
- LTO_section_ipa_profile,
- &data, &len);
- if (ib)
- {
- unsigned int num = streamer_read_uhwi (ib);
- unsigned int n;
- for (n = 0; n < num; n++)
- {
- gcov_type count = streamer_read_gcov_count (ib);
- int time = streamer_read_uhwi (ib);
- int size = streamer_read_uhwi (ib);
- account_time_size (hashtable, histogram,
- count, time, size);
- }
- lto_destroy_simple_input_block (file_data,
- LTO_section_ipa_profile,
- ib, data, len);
- }
- }
- hashtable.dispose ();
- histogram.qsort (cmp_counts);
-}
-
-/* Simple ipa profile pass propagating frequencies across the callgraph. */
+ IPA_PASS, /* type */
+ "whole-program", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_CGRAPHOPT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_remove_functions | TODO_dump_symtab ), /* todo_flags_finish */
+};
-static unsigned int
-ipa_profile (void)
+class pass_ipa_whole_program_visibility : public ipa_opt_pass_d
{
- struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
- struct cgraph_edge *e;
- int order_pos;
- bool something_changed = false;
- int i;
- gcov_type overall_time = 0, cutoff = 0, cumulated = 0, overall_size = 0;
-
- if (dump_file)
- dump_histogram (dump_file, histogram);
- for (i = 0; i < (int)histogram.length (); i++)
- {
- overall_time += histogram[i]->count * histogram[i]->time;
- overall_size += histogram[i]->size;
- }
- if (overall_time)
- {
- gcov_type threshold;
-
- gcc_assert (overall_size);
- if (dump_file)
- {
- gcov_type min, cumulated_time = 0, cumulated_size = 0;
-
- fprintf (dump_file, "Overall time: "HOST_WIDEST_INT_PRINT_DEC"\n",
- (HOST_WIDEST_INT)overall_time);
- min = get_hot_bb_threshold ();
- for (i = 0; i < (int)histogram.length () && histogram[i]->count >= min;
- i++)
- {
- cumulated_time += histogram[i]->count * histogram[i]->time;
- cumulated_size += histogram[i]->size;
- }
- fprintf (dump_file, "GCOV min count: "HOST_WIDEST_INT_PRINT_DEC
- " Time:%3.2f%% Size:%3.2f%%\n",
- (HOST_WIDEST_INT)min,
- cumulated_time * 100.0 / overall_time,
- cumulated_size * 100.0 / overall_size);
- }
- cutoff = (overall_time * PARAM_VALUE (HOT_BB_COUNT_WS_PERMILLE) + 500) / 1000;
- threshold = 0;
- for (i = 0; cumulated < cutoff; i++)
- {
- cumulated += histogram[i]->count * histogram[i]->time;
- threshold = histogram[i]->count;
- }
- if (!threshold)
- threshold = 1;
- if (dump_file)
- {
- gcov_type cumulated_time = 0, cumulated_size = 0;
-
- for (i = 0;
- i < (int)histogram.length () && histogram[i]->count >= threshold;
- i++)
- {
- cumulated_time += histogram[i]->count * histogram[i]->time;
- cumulated_size += histogram[i]->size;
- }
- fprintf (dump_file, "Determined min count: "HOST_WIDEST_INT_PRINT_DEC
- " Time:%3.2f%% Size:%3.2f%%\n",
- (HOST_WIDEST_INT)threshold,
- cumulated_time * 100.0 / overall_time,
- cumulated_size * 100.0 / overall_size);
- }
- if (threshold > get_hot_bb_threshold ()
- || in_lto_p)
- {
- if (dump_file)
- fprintf (dump_file, "Threshold updated.\n");
- set_hot_bb_threshold (threshold);
- }
- }
- histogram.release();
- free_alloc_pool (histogram_pool);
-
- order_pos = ipa_reverse_postorder (order);
- for (i = order_pos - 1; i >= 0; i--)
- {
- if (order[i]->local.local && cgraph_propagate_frequency (order[i]))
- {
- for (e = order[i]->callees; e; e = e->next_callee)
- if (e->callee->local.local && !e->callee->symbol.aux)
- {
- something_changed = true;
- e->callee->symbol.aux = (void *)1;
- }
- }
- order[i]->symbol.aux = NULL;
- }
-
- while (something_changed)
- {
- something_changed = false;
- for (i = order_pos - 1; i >= 0; i--)
- {
- if (order[i]->symbol.aux && cgraph_propagate_frequency (order[i]))
- {
- for (e = order[i]->callees; e; e = e->next_callee)
- if (e->callee->local.local && !e->callee->symbol.aux)
- {
- something_changed = true;
- e->callee->symbol.aux = (void *)1;
- }
- }
- order[i]->symbol.aux = NULL;
- }
- }
- free (order);
- return 0;
-}
-
-static bool
-gate_ipa_profile (void)
+public:
+ pass_ipa_whole_program_visibility(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_whole_program_visibility, ctxt,
+ NULL, /* generate_summary */
+ NULL, /* write_summary */
+ NULL, /* read_summary */
+ NULL, /* write_optimization_summary */
+ NULL, /* read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ NULL, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () {
+ return gate_whole_program_function_and_variable_visibility ();
+ }
+ unsigned int execute () {
+ return whole_program_function_and_variable_visibility ();
+ }
+
+}; // class pass_ipa_whole_program_visibility
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_whole_program_visibility (gcc::context *ctxt)
{
- return flag_ipa_profile;
+ return new pass_ipa_whole_program_visibility (ctxt);
}
-struct ipa_opt_pass_d pass_ipa_profile =
-{
- {
- IPA_PASS,
- "profile_estimate", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_ipa_profile, /* gate */
- ipa_profile, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_PROFILE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- },
- ipa_profile_generate_summary, /* generate_summary */
- ipa_profile_write_summary, /* write_summary */
- ipa_profile_read_summary, /* read_summary */
- NULL, /* write_optimization_summary */
- NULL, /* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- NULL, /* function_transform */
- NULL /* variable_transform */
-};
-
/* Generate and emit a static constructor or destructor. WHICH must
be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
@@ -1675,31 +1539,49 @@ gate_ipa_cdtor_merge (void)
return !targetm.have_ctors_dtors || (optimize && in_lto_p);
}
-struct ipa_opt_pass_d pass_ipa_cdtor_merge =
+namespace {
+
+const pass_data pass_data_ipa_cdtor_merge =
{
- {
- IPA_PASS,
- "cdtor", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_ipa_cdtor_merge, /* gate */
- ipa_cdtor_merge, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CGRAPHOPT, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- },
- NULL, /* generate_summary */
- NULL, /* write_summary */
- NULL, /* read_summary */
- NULL, /* write_optimization_summary */
- NULL, /* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- NULL, /* function_transform */
- NULL /* variable_transform */
+ IPA_PASS, /* type */
+ "cdtor", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_CGRAPHOPT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_ipa_cdtor_merge : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_cdtor_merge(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_cdtor_merge, ctxt,
+ NULL, /* generate_summary */
+ NULL, /* write_summary */
+ NULL, /* read_summary */
+ NULL, /* write_optimization_summary */
+ NULL, /* read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ NULL, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_ipa_cdtor_merge (); }
+ unsigned int execute () { return ipa_cdtor_merge (); }
+
+}; // class pass_ipa_cdtor_merge
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_cdtor_merge (gcc::context *ctxt)
+{
+ return new pass_ipa_cdtor_merge (ctxt);
+}
diff --git a/gcc/ira.c b/gcc/ira.c
index ee0c5e80d99..44fa0bc2835 100644
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -1111,8 +1111,8 @@ setup_class_translate_array (enum reg_class *class_translate,
min_cost = INT_MAX;
for (mode = 0; mode < MAX_MACHINE_MODE; mode++)
{
- cost = (ira_memory_move_cost[mode][cl][0]
- + ira_memory_move_cost[mode][cl][1]);
+ cost = (ira_memory_move_cost[mode][aclass][0]
+ + ira_memory_move_cost[mode][aclass][1]);
if (min_cost > cost)
min_cost = cost;
}
@@ -2944,11 +2944,8 @@ update_equiv_regs (void)
prevent access beyond allocated memory for paradoxical memory subreg. */
FOR_EACH_BB (bb)
FOR_BB_INSNS (bb, insn)
- {
- if (! INSN_P (insn))
- continue;
- for_each_rtx (&insn, set_paradoxical_subreg, (void *)pdx_subregs);
- }
+ if (NONDEBUG_INSN_P (insn))
+ for_each_rtx (&insn, set_paradoxical_subreg, (void *) pdx_subregs);
/* Scan the insns and find which registers have equivalences. Do this
in a separate scan of the insns because (due to -fcse-follow-jumps)
@@ -4775,26 +4772,43 @@ rest_of_handle_ira (void)
return 0;
}
-struct rtl_opt_pass pass_ira =
+namespace {
+
+const pass_data pass_data_ira =
{
- {
- RTL_PASS,
- "ira", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_ira, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IRA, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_do_not_ggc_collect /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "ira", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_IRA, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_do_not_ggc_collect, /* todo_flags_finish */
};
+class pass_ira : public rtl_opt_pass
+{
+public:
+ pass_ira(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_ira, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_ira (); }
+
+}; // class pass_ira
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_ira (gcc::context *ctxt)
+{
+ return new pass_ira (ctxt);
+}
+
static unsigned int
rest_of_handle_reload (void)
{
@@ -4802,22 +4816,39 @@ rest_of_handle_reload (void)
return 0;
}
-struct rtl_opt_pass pass_reload =
+namespace {
+
+const pass_data pass_data_reload =
{
- {
- RTL_PASS,
- "reload", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_reload, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_RELOAD, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "reload", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_RELOAD, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_reload : public rtl_opt_pass
+{
+public:
+ pass_reload(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_reload, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_reload (); }
+
+}; // class pass_reload
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_reload (gcc::context *ctxt)
+{
+ return new pass_reload (ctxt);
+}
diff --git a/gcc/jump.c b/gcc/jump.c
index 4fb1e6e6bef..6f7bcb72d1c 100644
--- a/gcc/jump.c
+++ b/gcc/jump.c
@@ -139,26 +139,43 @@ cleanup_barriers (void)
return 0;
}
-struct rtl_opt_pass pass_cleanup_barriers =
+namespace {
+
+const pass_data pass_data_cleanup_barriers =
{
- {
- RTL_PASS,
- "barriers", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- cleanup_barriers, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "barriers", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_cleanup_barriers : public rtl_opt_pass
+{
+public:
+ pass_cleanup_barriers(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_cleanup_barriers, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return cleanup_barriers (); }
+
+}; // class pass_cleanup_barriers
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_cleanup_barriers (gcc::context *ctxt)
+{
+ return new pass_cleanup_barriers (ctxt);
+}
+
/* Initialize LABEL_NUSES and JUMP_LABEL fields, add REG_LABEL_TARGET
for remaining targets for JUMP_P. Delete any REG_LABEL_OPERAND
diff --git a/gcc/langhooks.c b/gcc/langhooks.c
index 901f9b4a300..fbf545b466a 100644
--- a/gcc/langhooks.c
+++ b/gcc/langhooks.c
@@ -446,7 +446,7 @@ lhd_print_error_function (diagnostic_context *context, const char *file,
if (fndecl)
{
expanded_location s = expand_location (*locus);
- pp_character (context->printer, ',');
+ pp_comma (context->printer);
pp_newline (context->printer);
if (s.file != NULL)
{
@@ -467,7 +467,7 @@ lhd_print_error_function (diagnostic_context *context, const char *file,
identifier_to_locale (lang_hooks.decl_printable_name (fndecl, 2)));
}
}
- pp_character (context->printer, ':');
+ pp_colon (context->printer);
}
diagnostic_set_last_function (context, diagnostic);
diff --git a/gcc/loop-init.c b/gcc/loop-init.c
index 65f9c6c9d4a..80c31ef70cd 100644
--- a/gcc/loop-init.c
+++ b/gcc/loop-init.c
@@ -316,26 +316,43 @@ gate_handle_loop2 (void)
}
}
-struct rtl_opt_pass pass_loop2 =
-{
- {
- RTL_PASS,
- "loop2", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_handle_loop2, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOOP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_loop2 =
+{
+ RTL_PASS, /* type */
+ "loop2", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_LOOP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_loop2 : public rtl_opt_pass
+{
+public:
+ pass_loop2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_loop2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_loop2 (); }
+
+}; // class pass_loop2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_loop2 (gcc::context *ctxt)
+{
+ return new pass_loop2 (ctxt);
+}
+
/* Initialization of the RTL loop passes. */
static unsigned int
@@ -353,26 +370,43 @@ rtl_loop_init (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_loop_init =
-{
- {
- RTL_PASS,
- "loop2_init", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- NULL, /* gate */
- rtl_loop_init, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOOP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_rtl_loop_init =
+{
+ RTL_PASS, /* type */
+ "loop2_init", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_LOOP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_rtl_loop_init : public rtl_opt_pass
+{
+public:
+ pass_rtl_loop_init(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_loop_init, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rtl_loop_init (); }
+
+}; // class pass_rtl_loop_init
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_loop_init (gcc::context *ctxt)
+{
+ return new pass_rtl_loop_init (ctxt);
+}
+
/* Finalization of the RTL loop passes. */
@@ -394,27 +428,43 @@ rtl_loop_done (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_loop_done =
-{
- {
- RTL_PASS,
- "loop2_done", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- NULL, /* gate */
- rtl_loop_done, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOOP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- PROP_loops, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow
- | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_rtl_loop_done =
+{
+ RTL_PASS, /* type */
+ "loop2_done", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_LOOP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ PROP_loops, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_flow | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+class pass_rtl_loop_done : public rtl_opt_pass
+{
+public:
+ pass_rtl_loop_done(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_loop_done, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rtl_loop_done (); }
+
+}; // class pass_rtl_loop_done
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_loop_done (gcc::context *ctxt)
+{
+ return new pass_rtl_loop_done (ctxt);
+}
+
/* Loop invariant code motion. */
static bool
@@ -431,27 +481,45 @@ rtl_move_loop_invariants (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_move_loop_invariants =
-{
- {
- RTL_PASS,
- "loop2_invariant", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_rtl_move_loop_invariants, /* gate */
- rtl_move_loop_invariants, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOOP_MOVE_INVARIANTS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_verify |
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_rtl_move_loop_invariants =
+{
+ RTL_PASS, /* type */
+ "loop2_invariant", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_LOOP_MOVE_INVARIANTS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_verify | TODO_df_finish
+ | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+class pass_rtl_move_loop_invariants : public rtl_opt_pass
+{
+public:
+ pass_rtl_move_loop_invariants(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_move_loop_invariants, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_rtl_move_loop_invariants (); }
+ unsigned int execute () { return rtl_move_loop_invariants (); }
+
+}; // class pass_rtl_move_loop_invariants
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_move_loop_invariants (gcc::context *ctxt)
+{
+ return new pass_rtl_move_loop_invariants (ctxt);
+}
+
/* Loop unswitching for RTL. */
static bool
@@ -468,26 +536,44 @@ rtl_unswitch (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_unswitch =
-{
- {
- RTL_PASS,
- "loop2_unswitch", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_rtl_unswitch, /* gate */
- rtl_unswitch, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOOP_UNSWITCH, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_rtl_unswitch =
+{
+ RTL_PASS, /* type */
+ "loop2_unswitch", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_LOOP_UNSWITCH, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_rtl_unswitch : public rtl_opt_pass
+{
+public:
+ pass_rtl_unswitch(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_unswitch, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_rtl_unswitch (); }
+ unsigned int execute () { return rtl_unswitch (); }
+
+}; // class pass_rtl_unswitch
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_unswitch (gcc::context *ctxt)
+{
+ return new pass_rtl_unswitch (ctxt);
+}
+
/* Loop unswitching for RTL. */
static bool
@@ -517,26 +603,44 @@ rtl_unroll_and_peel_loops (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_unroll_and_peel_loops =
-{
- {
- RTL_PASS,
- "loop2_unroll", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_rtl_unroll_and_peel_loops, /* gate */
- rtl_unroll_and_peel_loops, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOOP_UNROLL, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_rtl_unroll_and_peel_loops =
+{
+ RTL_PASS, /* type */
+ "loop2_unroll", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_LOOP_UNROLL, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_rtl_unroll_and_peel_loops : public rtl_opt_pass
+{
+public:
+ pass_rtl_unroll_and_peel_loops(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_unroll_and_peel_loops, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_rtl_unroll_and_peel_loops (); }
+ unsigned int execute () { return rtl_unroll_and_peel_loops (); }
+
+}; // class pass_rtl_unroll_and_peel_loops
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_unroll_and_peel_loops (gcc::context *ctxt)
+{
+ return new pass_rtl_unroll_and_peel_loops (ctxt);
+}
+
/* The doloop optimization. */
static bool
@@ -559,22 +663,40 @@ rtl_doloop (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_doloop =
-{
- {
- RTL_PASS,
- "loop2_doloop", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_rtl_doloop, /* gate */
- rtl_doloop, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOOP_DOLOOP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_rtl_doloop =
+{
+ RTL_PASS, /* type */
+ "loop2_doloop", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_LOOP_DOLOOP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+
+class pass_rtl_doloop : public rtl_opt_pass
+{
+public:
+ pass_rtl_doloop(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_doloop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_rtl_doloop (); }
+ unsigned int execute () { return rtl_doloop (); }
+
+}; // class pass_rtl_doloop
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_doloop (gcc::context *ctxt)
+{
+ return new pass_rtl_doloop (ctxt);
+}
diff --git a/gcc/loop-unroll.c b/gcc/loop-unroll.c
index fa0260175d8..ad26f3da174 100644
--- a/gcc/loop-unroll.c
+++ b/gcc/loop-unroll.c
@@ -225,7 +225,7 @@ report_unroll_peel (struct loop *loop, location_t locus)
&& !loop->lpt_decision.times)
{
dump_printf_loc (report_flags, locus,
- "Turned loop into non-loop; it never loops.\n");
+ "loop turned into non-loop; it never loops.\n");
return;
}
@@ -236,13 +236,16 @@ report_unroll_peel (struct loop *loop, location_t locus)
else if (loop->header->count)
niters = expected_loop_iterations (loop);
- dump_printf_loc (report_flags, locus,
- "%s loop %d times",
- (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY
- ? "Completely unroll"
- : (loop->lpt_decision.decision == LPT_PEEL_SIMPLE
- ? "Peel" : "Unroll")),
- loop->lpt_decision.times);
+ if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
+ dump_printf_loc (report_flags, locus,
+ "loop with %d iterations completely unrolled",
+ loop->lpt_decision.times + 1);
+ else
+ dump_printf_loc (report_flags, locus,
+ "loop %s %d times",
+ (loop->lpt_decision.decision == LPT_PEEL_SIMPLE
+ ? "peeled" : "unrolled"),
+ loop->lpt_decision.times);
if (profile_info)
dump_printf (report_flags,
" (header execution count %d",
diff --git a/gcc/lower-subreg.c b/gcc/lower-subreg.c
index eb22d8c87f5..ac67398a2db 100644
--- a/gcc/lower-subreg.c
+++ b/gcc/lower-subreg.c
@@ -1689,43 +1689,79 @@ rest_of_handle_lower_subreg2 (void)
return 0;
}
-struct rtl_opt_pass pass_lower_subreg =
+namespace {
+
+const pass_data pass_data_lower_subreg =
{
- {
- RTL_PASS,
- "subreg1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_lower_subreg, /* gate */
- rest_of_handle_lower_subreg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOWER_SUBREG, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "subreg1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_LOWER_SUBREG, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_flow, /* todo_flags_finish */
};
-struct rtl_opt_pass pass_lower_subreg2 =
+class pass_lower_subreg : public rtl_opt_pass
+{
+public:
+ pass_lower_subreg(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_lower_subreg, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_lower_subreg (); }
+ unsigned int execute () { return rest_of_handle_lower_subreg (); }
+
+}; // class pass_lower_subreg
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_lower_subreg (gcc::context *ctxt)
+{
+ return new pass_lower_subreg (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_lower_subreg2 =
{
- {
- RTL_PASS,
- "subreg2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_lower_subreg, /* gate */
- rest_of_handle_lower_subreg2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LOWER_SUBREG, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "subreg2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_LOWER_SUBREG, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_lower_subreg2 : public rtl_opt_pass
+{
+public:
+ pass_lower_subreg2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_lower_subreg2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_lower_subreg (); }
+ unsigned int execute () { return rest_of_handle_lower_subreg2 (); }
+
+}; // class pass_lower_subreg2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_lower_subreg2 (gcc::context *ctxt)
+{
+ return new pass_lower_subreg2 (ctxt);
+}
diff --git a/gcc/lra-constraints.c b/gcc/lra-constraints.c
index 29cf7dbe852..ee72f7f0985 100644
--- a/gcc/lra-constraints.c
+++ b/gcc/lra-constraints.c
@@ -859,8 +859,9 @@ emit_spill_move (bool to_p, rtx mem_pseudo, rtx val)
{
if (GET_MODE (mem_pseudo) != GET_MODE (val))
{
- lra_assert (GET_MODE_SIZE (GET_MODE (mem_pseudo))
- >= GET_MODE_SIZE (GET_MODE (val)));
+ /* Usually size of mem_pseudo is greater than val size but in
+ rare cases it can be less as it can be defined by target
+ dependent macro HARD_REGNO_CALLER_SAVE_MODE. */
if (! MEM_P (val))
{
val = gen_rtx_SUBREG (GET_MODE (mem_pseudo),
@@ -1423,8 +1424,14 @@ process_alt_operands (int only_alternative)
overall = losers = reject = reload_nregs = reload_sum = 0;
for (nop = 0; nop < n_operands; nop++)
- reject += (curr_static_id
- ->operand_alternative[nalt * n_operands + nop].reject);
+ {
+ int inc = (curr_static_id
+ ->operand_alternative[nalt * n_operands + nop].reject);
+ if (lra_dump_file != NULL && inc != 0)
+ fprintf (lra_dump_file,
+ " Staticly defined alt reject+=%d\n", inc);
+ reject += inc;
+ }
early_clobbered_regs_num = 0;
for (nop = 0; nop < n_operands; nop++)
@@ -1598,7 +1605,14 @@ process_alt_operands (int only_alternative)
|| (find_regno_note (curr_insn, REG_DEAD,
REGNO (operand_reg[nop]))
== NULL_RTX))
- reject += 2;
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Matching alt: reject+=2\n",
+ nop);
+ reject += 2;
+ }
}
/* If we have to reload this operand and some
previous operand also had to match the same
@@ -1854,16 +1868,35 @@ process_alt_operands (int only_alternative)
{
if (in_hard_reg_set_p (this_costly_alternative_set,
mode, hard_regno[nop]))
- reject++;
+ {
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " %d Costly set: reject++\n",
+ nop);
+ reject++;
+ }
}
else
{
/* Prefer won reg to spilled pseudo under other equal
conditions. */
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Non pseudo reload: reject++\n",
+ nop);
reject++;
if (in_class_p (operand_reg[nop],
this_costly_alternative, NULL))
- reject++;
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Non pseudo costly reload:"
+ " reject++\n",
+ nop);
+ reject++;
+ }
}
/* We simulate the behaviour of old reload here.
Although scratches need hard registers and it
@@ -1872,7 +1905,13 @@ process_alt_operands (int only_alternative)
might cost something but probably less than old
reload pass believes. */
if (lra_former_scratch_p (REGNO (operand_reg[nop])))
- reject += LRA_LOSER_COST_FACTOR;
+ {
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " %d Scratch win: reject+=3\n",
+ nop);
+ reject += 3;
+ }
}
}
else if (did_match)
@@ -1892,7 +1931,7 @@ process_alt_operands (int only_alternative)
/* For asms, verify that the class for this alternative is possible
for the mode that is specified. */
- if (!no_regs_p && REG_P (op) && INSN_CODE (curr_insn) < 0)
+ if (!no_regs_p && INSN_CODE (curr_insn) < 0)
{
int i;
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
@@ -1914,7 +1953,12 @@ process_alt_operands (int only_alternative)
this_alternative_offmemok = offmemok;
if (this_costly_alternative != NO_REGS)
- reject++;
+ {
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " %d Costly loser: reject++\n", nop);
+ reject++;
+ }
/* If the operand is dying, has a matching constraint,
and satisfies constraints of the matched operand
which failed to satisfy the own constraints, we do
@@ -1996,7 +2040,13 @@ process_alt_operands (int only_alternative)
|| (curr_static_id->operand[nop].type == OP_OUT
&& (targetm.preferred_output_reload_class
(op, this_alternative) == NO_REGS))))
- reject += LRA_MAX_REJECT;
+ {
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " %d Non-prefered reload: reject+=%d\n",
+ nop, LRA_MAX_REJECT);
+ reject += LRA_MAX_REJECT;
+ }
if (! (MEM_P (op) && offmemok)
&& ! (const_to_mem && constmemok))
@@ -2009,22 +2059,43 @@ process_alt_operands (int only_alternative)
we don't want to have a different alternative
match then. */
if (! (REG_P (op) && REGNO (op) >= FIRST_PSEUDO_REGISTER))
- reject += 2;
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Non-pseudo reload: reject+=2\n",
+ nop);
+ reject += 2;
+ }
if (! no_regs_p)
reload_nregs
+= ira_reg_class_max_nregs[this_alternative][mode];
if (SMALL_REGISTER_CLASS_P (this_alternative))
- reject += LRA_LOSER_COST_FACTOR / 2;
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Small class reload: reject+=%d\n",
+ nop, LRA_LOSER_COST_FACTOR / 2);
+ reject += LRA_LOSER_COST_FACTOR / 2;
+ }
}
/* We are trying to spill pseudo into memory. It is
usually more costly than moving to a hard register
although it might takes the same number of
reloads. */
- if (no_regs_p && REG_P (op))
- reject += 2;
+ if (no_regs_p && REG_P (op) && hard_regno[nop] >= 0)
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Spill pseudo in memory: reject+=3\n",
+ nop);
+ reject += 3;
+ }
#ifdef SECONDARY_MEMORY_NEEDED
/* If reload requires moving value through secondary
@@ -2043,12 +2114,23 @@ process_alt_operands (int only_alternative)
reloads can be removed, so penalize output
reloads. */
if (!REG_P (op) || curr_static_id->operand[nop].type != OP_IN)
- reject++;
-
+ {
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Non input pseudo reload: reject++\n",
+ nop);
+ reject++;
+ }
}
if (early_clobber_p)
- reject++;
+ {
+ if (lra_dump_file != NULL)
+ fprintf (lra_dump_file,
+ " %d Early clobber: reject++\n", nop);
+ reject++;
+ }
/* ??? We check early clobbers after processing all operands
(see loop below) and there we update the costs more.
Should we update the cost (may be approximately) here
@@ -2059,7 +2141,7 @@ process_alt_operands (int only_alternative)
{
if (lra_dump_file != NULL)
fprintf (lra_dump_file,
- " alt=%d,overall=%d,losers=%d -- reject\n",
+ " alt=%d,overall=%d,losers=%d -- refuse\n",
nalt, overall, losers);
goto fail;
}
@@ -2102,10 +2184,12 @@ process_alt_operands (int only_alternative)
insn we can transform it into an add still by
using this alternative. */
&& GET_CODE (no_subreg_reg_operand[1]) != PLUS)))
- /* We have a move insn and a new reload insn will be similar
- to the current insn. We should avoid such situation as it
- results in LRA cycling. */
- overall += LRA_MAX_REJECT;
+ {
+ /* We have a move insn and a new reload insn will be similar
+ to the current insn. We should avoid such situation as it
+ results in LRA cycling. */
+ overall += LRA_MAX_REJECT;
+ }
ok_p = true;
curr_alt_dont_inherit_ops_num = 0;
for (nop = 0; nop < early_clobbered_regs_num; nop++)
@@ -2159,6 +2243,11 @@ process_alt_operands (int only_alternative)
losers++;
/* Early clobber was already reflected in REJECT. */
lra_assert (reject > 0);
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Conflict early clobber reload: reject--\n",
+ i);
reject--;
overall += LRA_LOSER_COST_FACTOR - 1;
}
@@ -2186,6 +2275,12 @@ process_alt_operands (int only_alternative)
losers++;
/* Early clobber was already reflected in REJECT. */
lra_assert (reject > 0);
+ if (lra_dump_file != NULL)
+ fprintf
+ (lra_dump_file,
+ " %d Matched conflict early clobber reloads:"
+ "reject--\n",
+ i);
reject--;
overall += LRA_LOSER_COST_FACTOR - 1;
}
@@ -3600,6 +3695,40 @@ init_insn_rhs_dead_pseudo_p (int regno)
return false;
}
+/* Return TRUE if REGNO has a reverse equivalence. The equivalence is
+ reverse only if we have one init insn with given REGNO as a
+ source. */
+static bool
+reverse_equiv_p (int regno)
+{
+ rtx insns, set;
+
+ if ((insns = ira_reg_equiv[regno].init_insns) == NULL_RTX)
+ return false;
+ if (! INSN_P (XEXP (insns, 0))
+ || XEXP (insns, 1) != NULL_RTX)
+ return false;
+ if ((set = single_set (XEXP (insns, 0))) == NULL_RTX)
+ return false;
+ return REG_P (SET_SRC (set)) && (int) REGNO (SET_SRC (set)) == regno;
+}
+
+/* Return TRUE if REGNO was reloaded in an equivalence init insn. We
+ call this function only for non-reverse equivalence. */
+static bool
+contains_reloaded_insn_p (int regno)
+{
+ rtx set;
+ rtx list = ira_reg_equiv[regno].init_insns;
+
+ for (; list != NULL_RTX; list = XEXP (list, 1))
+ if ((set = single_set (XEXP (list, 0))) == NULL_RTX
+ || ! REG_P (SET_DEST (set))
+ || (int) REGNO (SET_DEST (set)) != regno)
+ return true;
+ return false;
+}
+
/* Entry function of LRA constraint pass. Return true if the
constraint pass did change the code. */
bool
@@ -3643,7 +3772,6 @@ lra_constraints (bool first_p)
else if ((x = get_equiv_substitution (reg)) != reg)
{
bool pseudo_p = contains_reg_p (x, false, false);
- rtx set, insns;
/* After RTL transformation, we can not guarantee that
pseudo in the substitution was not reloaded which might
@@ -3675,13 +3803,13 @@ lra_constraints (bool first_p)
removed the insn. When the equiv can be a
constant, the right hand side of the init insn can
be a pseudo. */
- || (! ((insns = ira_reg_equiv[i].init_insns) != NULL_RTX
- && INSN_P (XEXP (insns, 0))
- && XEXP (insns, 1) == NULL_RTX
- && (set = single_set (XEXP (insns, 0))) != NULL_RTX
- && REG_P (SET_SRC (set))
- && (int) REGNO (SET_SRC (set)) == i)
- && init_insn_rhs_dead_pseudo_p (i))
+ || (! reverse_equiv_p (i)
+ && (init_insn_rhs_dead_pseudo_p (i)
+ /* If we reloaded the pseudo in an equivalence
+ init insn, we can not remove the equiv init
+ insns and the init insns might write into
+ const memory in this case. */
+ || contains_reloaded_insn_p (i)))
/* Prevent access beyond equivalent memory for
paradoxical subregs. */
|| (MEM_P (x)
@@ -4353,15 +4481,12 @@ split_reg (bool before_p, int original_regno, rtx insn, rtx next_usage_insns)
" ((((((((((((((((((((((((((((((((((((((((((((((((\n");
if (call_save_p)
{
- enum machine_mode sec_mode;
+ enum machine_mode mode = GET_MODE (original_reg);
-#ifdef SECONDARY_MEMORY_NEEDED_MODE
- sec_mode = SECONDARY_MEMORY_NEEDED_MODE (GET_MODE (original_reg));
-#else
- sec_mode = GET_MODE (original_reg);
-#endif
- new_reg = lra_create_new_reg (sec_mode, NULL_RTX,
- NO_REGS, "save");
+ mode = HARD_REGNO_CALLER_SAVE_MODE (hard_regno,
+ hard_regno_nregs[hard_regno][mode],
+ mode);
+ new_reg = lra_create_new_reg (mode, NULL_RTX, NO_REGS, "save");
}
else
{
diff --git a/gcc/lra.c b/gcc/lra.c
index 30b7c0a3dd5..ef69526b0ec 100644
--- a/gcc/lra.c
+++ b/gcc/lra.c
@@ -480,13 +480,13 @@ init_insn_regs (void)
= create_alloc_pool ("insn regs", sizeof (struct lra_insn_reg), 100);
}
-/* Create LRA insn related info about referenced REGNO with TYPE
- (in/out/inout), biggest reference mode MODE, flag that it is
+/* Create LRA insn related info about a reference to REGNO in INSN with
+ TYPE (in/out/inout), biggest reference mode MODE, flag that it is
reference through subreg (SUBREG_P), flag that is early clobbered
in the insn (EARLY_CLOBBER), and reference to the next insn reg
info (NEXT). */
static struct lra_insn_reg *
-new_insn_reg (int regno, enum op_type type, enum machine_mode mode,
+new_insn_reg (rtx insn, int regno, enum op_type type, enum machine_mode mode,
bool subreg_p, bool early_clobber, struct lra_insn_reg *next)
{
struct lra_insn_reg *ir;
@@ -494,7 +494,8 @@ new_insn_reg (int regno, enum op_type type, enum machine_mode mode,
ir = (struct lra_insn_reg *) pool_alloc (insn_reg_pool);
ir->type = type;
ir->biggest_mode = mode;
- if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode))
+ if (GET_MODE_SIZE (mode) > GET_MODE_SIZE (lra_reg_info[regno].biggest_mode)
+ && NONDEBUG_INSN_P (insn))
lra_reg_info[regno].biggest_mode = mode;
ir->subreg_p = subreg_p;
ir->early_clobber = early_clobber;
@@ -976,7 +977,7 @@ collect_non_operand_hard_regs (rtx *x, lra_insn_recog_data_t data,
&& ! (FIRST_STACK_REG <= regno
&& regno <= LAST_STACK_REG));
#endif
- list = new_insn_reg (regno, type, mode, subreg_p,
+ list = new_insn_reg (data->insn, regno, type, mode, subreg_p,
early_clobber, list);
}
}
@@ -1575,7 +1576,7 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
expand_reg_info ();
if (bitmap_set_bit (&lra_reg_info[regno].insn_bitmap, uid))
{
- data->regs = new_insn_reg (regno, type, mode, subreg_p,
+ data->regs = new_insn_reg (data->insn, regno, type, mode, subreg_p,
early_clobber, data->regs);
return;
}
@@ -1587,8 +1588,9 @@ add_regs_to_insn_regno_info (lra_insn_recog_data_t data, rtx x, int uid,
if (curr->subreg_p != subreg_p || curr->biggest_mode != mode)
/* The info can not be integrated into the found
structure. */
- data->regs = new_insn_reg (regno, type, mode, subreg_p,
- early_clobber, data->regs);
+ data->regs = new_insn_reg (data->insn, regno, type, mode,
+ subreg_p, early_clobber,
+ data->regs);
else
{
if (curr->type != type)
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index d60213a5cb5..fcba1b92acd 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. If not see
#include "gcov-io.h"
#include "tree-pass.h"
#include "profile.h"
+#include "context.h"
+#include "pass_manager.h"
static void output_cgraph_opt_summary (void);
static void input_cgraph_opt_summary (vec<symtab_node> nodes);
@@ -271,12 +273,13 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
bp = bitpack_create (ob->main_stream);
uid = (!gimple_has_body_p (edge->caller->symbol.decl)
- ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt));
+ ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt) + 1);
bp_pack_enum (&bp, cgraph_inline_failed_enum,
CIF_N_REASONS, edge->inline_failed);
bp_pack_var_len_unsigned (&bp, uid);
bp_pack_var_len_unsigned (&bp, edge->frequency);
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);
bp_pack_value (&bp, edge->can_throw_external, 1);
if (edge->indirect_unknown_callee)
@@ -296,6 +299,14 @@ lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
| ECF_NOVOPS)));
}
streamer_write_bitpack (&bp);
+ if (edge->indirect_unknown_callee)
+ {
+ streamer_write_hwi_stream (ob->main_stream,
+ edge->indirect_info->common_target_id);
+ if (edge->indirect_info->common_target_id)
+ streamer_write_hwi_stream
+ (ob->main_stream, edge->indirect_info->common_target_probability);
+ }
}
/* Return if LIST contain references from other partitions. */
@@ -374,7 +385,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bool boundary_p;
intptr_t ref;
bool in_other_partition = false;
- struct cgraph_node *clone_of;
+ struct cgraph_node *clone_of, *ultimate_clone_of;
struct ipa_opt_pass_d *pass;
int i;
bool alias_p;
@@ -421,7 +432,16 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
else
clone_of = clone_of->clone_of;
- if (LTO_symtab_analyzed_node)
+ /* See if body of the master function is output. If not, we are seeing only
+ an declaration and we do not need to pass down clone tree. */
+ ultimate_clone_of = clone_of;
+ while (ultimate_clone_of && ultimate_clone_of->clone_of)
+ ultimate_clone_of = ultimate_clone_of->clone_of;
+
+ if (clone_of && !lto_symtab_encoder_encode_body_p (encoder, ultimate_clone_of))
+ clone_of = NULL;
+
+ if (tag == LTO_symtab_analyzed_node)
gcc_assert (clone_of || !node->clone_of);
if (!clone_of)
streamer_write_hwi_stream (ob->main_stream, LCC_NOT_FOUND);
@@ -436,7 +456,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
streamer_write_hwi_stream (ob->main_stream,
node->ipa_transforms_to_apply.length ());
FOR_EACH_VEC_ELT (node->ipa_transforms_to_apply, i, pass)
- streamer_write_hwi_stream (ob->main_stream, pass->pass.static_pass_number);
+ streamer_write_hwi_stream (ob->main_stream, pass->static_pass_number);
if (tag == LTO_symtab_analyzed_node)
{
@@ -472,7 +492,6 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bp_pack_value (&bp, node->symbol.forced_by_abi, 1);
bp_pack_value (&bp, node->symbol.unique_name, 1);
bp_pack_value (&bp, node->symbol.address_taken, 1);
- bp_pack_value (&bp, node->abstract_and_needed, 1);
bp_pack_value (&bp, tag == LTO_symtab_analyzed_node
&& !DECL_EXTERNAL (node->symbol.decl)
&& !DECL_COMDAT (node->symbol.decl)
@@ -508,6 +527,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
}
+ streamer_write_hwi_stream (ob->main_stream, node->profile_id);
}
/* Output the varpool NODE to OB.
@@ -579,13 +599,24 @@ lto_output_ref (struct lto_simple_output_block *ob, struct ipa_ref *ref,
{
struct bitpack_d bp;
int nref;
+ int uid = ref->lto_stmt_uid;
+ struct cgraph_node *node;
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, ref->use, 2);
+ bp_pack_value (&bp, ref->speculative, 1);
streamer_write_bitpack (&bp);
nref = lto_symtab_encoder_lookup (encoder, ref->referred);
gcc_assert (nref != LCC_NOT_FOUND);
streamer_write_hwi_stream (ob->main_stream, nref);
+
+ node = dyn_cast <cgraph_node> (ref->referring);
+ if (node)
+ {
+ if (ref->stmt)
+ uid = gimple_uid (ref->stmt) + 1;
+ streamer_write_hwi_stream (ob->main_stream, uid);
+ }
}
/* Stream out profile_summary to OB. */
@@ -748,6 +779,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
add_node_to (encoder, node, true);
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
add_references (encoder, &node->symbol.ref_list);
+ /* For proper debug info, we need to ship the origins, too. */
+ if (DECL_ABSTRACT_ORIGIN (node->symbol.decl))
+ {
+ struct cgraph_node *origin_node
+ = cgraph_get_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
+ add_node_to (encoder, origin_node, true);
+ }
}
for (lsei = lsei_start_variable_in_partition (in_encoder);
!lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
@@ -757,6 +795,13 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
lto_set_symtab_encoder_encode_initializer (encoder, vnode);
add_references (encoder, &vnode->symbol.ref_list);
+ /* For proper debug info, we need to ship the origins, too. */
+ if (DECL_ABSTRACT_ORIGIN (vnode->symbol.decl))
+ {
+ struct varpool_node *origin_node
+ = varpool_get_node (DECL_ABSTRACT_ORIGIN (node->symbol.decl));
+ lto_set_symtab_encoder_in_partition (encoder, (symtab_node)origin_node);
+ }
}
/* Pickle in also the initializer of all referenced readonly variables
to help folding. Constant pool variables are not shared, so we must
@@ -887,7 +932,6 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
node->symbol.forced_by_abi = bp_unpack_value (bp, 1);
node->symbol.unique_name = bp_unpack_value (bp, 1);
node->symbol.address_taken = bp_unpack_value (bp, 1);
- node->abstract_and_needed = bp_unpack_value (bp, 1);
node->symbol.used_from_other_partition = bp_unpack_value (bp, 1);
node->lowered = bp_unpack_value (bp, 1);
node->symbol.analyzed = tag == LTO_symtab_analyzed_node;
@@ -936,6 +980,7 @@ input_node (struct lto_file_decl_data *file_data,
enum LTO_symtab_tags tag,
vec<symtab_node> nodes)
{
+ gcc::pass_manager *passes = g->get_passes ();
tree fn_decl;
struct cgraph_node *node;
struct bitpack_d bp;
@@ -981,8 +1026,8 @@ input_node (struct lto_file_decl_data *file_data,
struct opt_pass *pass;
int pid = streamer_read_hwi (ib);
- gcc_assert (pid < passes_by_id_size);
- pass = passes_by_id[pid];
+ gcc_assert (pid < passes->passes_by_id_size);
+ pass = passes->passes_by_id[pid];
node->ipa_transforms_to_apply.safe_push ((struct ipa_opt_pass_d *) pass);
}
@@ -1021,6 +1066,7 @@ input_node (struct lto_file_decl_data *file_data,
}
if (node->symbol.alias && !node->symbol.analyzed && node->symbol.weakref)
node->symbol.alias_target = get_alias_symbol (node->symbol.decl);
+ node->profile_id = streamer_read_hwi (ib);
return node;
}
@@ -1092,11 +1138,17 @@ input_ref (struct lto_input_block *ib,
symtab_node node = NULL;
struct bitpack_d bp;
enum ipa_ref_use use;
+ bool speculative;
+ struct ipa_ref *ref;
bp = streamer_read_bitpack (ib);
use = (enum ipa_ref_use) bp_unpack_value (&bp, 2);
+ speculative = (enum ipa_ref_use) bp_unpack_value (&bp, 1);
node = nodes[streamer_read_hwi (ib)];
- ipa_record_reference (referring_node, node, use, NULL);
+ ref = ipa_record_reference (referring_node, node, use, NULL);
+ ref->speculative = speculative;
+ if (is_a <cgraph_node> (referring_node))
+ ref->lto_stmt_uid = streamer_read_hwi (ib);
}
/* Read an edge from IB. NODES points to a vector of previously read nodes for
@@ -1143,6 +1195,7 @@ input_edge (struct lto_input_block *ib, vec<symtab_node> nodes,
edge = cgraph_create_edge (caller, callee, NULL, count, freq);
edge->indirect_inlining_edge = bp_unpack_value (&bp, 1);
+ edge->speculative = bp_unpack_value (&bp, 1);
edge->lto_stmt_uid = stmt_id;
edge->inline_failed = inline_failed;
edge->call_stmt_cannot_inline_p = bp_unpack_value (&bp, 1);
@@ -1162,6 +1215,9 @@ input_edge (struct lto_input_block *ib, vec<symtab_node> nodes,
if (bp_unpack_value (&bp, 1))
ecf_flags |= ECF_RETURNS_TWICE;
edge->indirect_info->ecf_flags = ecf_flags;
+ edge->indirect_info->common_target_id = streamer_read_hwi (ib);
+ if (edge->indirect_info->common_target_id)
+ edge->indirect_info->common_target_probability = streamer_read_hwi (ib);
}
}
diff --git a/gcc/lto-section-in.c b/gcc/lto-section-in.c
index 0ef421f6167..5821030d4cf 100644
--- a/gcc/lto-section-in.c
+++ b/gcc/lto-section-in.c
@@ -414,6 +414,41 @@ lto_get_function_in_decl_state (struct lto_file_decl_data *file_data,
return slot? ((struct lto_in_decl_state*) *slot) : NULL;
}
+/* Free decl_states. */
+
+void
+lto_free_function_in_decl_state (struct lto_in_decl_state *state)
+{
+ int i;
+ for (i = 0; i < LTO_N_DECL_STREAMS; i++)
+ ggc_free (state->streams[i].trees);
+ ggc_free (state);
+}
+
+/* Free decl_states associated with NODE. This makes it possible to furhter
+ release trees needed by the NODE's body. */
+
+void
+lto_free_function_in_decl_state_for_node (symtab_node node)
+{
+ struct lto_in_decl_state temp;
+ void **slot;
+
+ if (!node->symbol.lto_file_data)
+ return;
+
+ temp.fn_decl = node->symbol.decl;
+ slot = htab_find_slot (node->symbol.lto_file_data->function_decl_states,
+ &temp, NO_INSERT);
+ if (slot && *slot)
+ {
+ lto_free_function_in_decl_state ((struct lto_in_decl_state*) *slot);
+ htab_clear_slot (node->symbol.lto_file_data->function_decl_states,
+ slot);
+ }
+ node->symbol.lto_file_data = NULL;
+}
+
/* Report read pass end of the section. */
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index fe7ab7c5067..7fa5bb34e58 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -755,30 +755,60 @@ input_ssa_names (struct lto_input_block *ib, struct data_in *data_in,
so they point to STMTS. */
static void
-fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts)
+fixup_call_stmt_edges_1 (struct cgraph_node *node, gimple *stmts,
+ struct function *fn)
{
struct cgraph_edge *cedge;
+ struct ipa_ref *ref;
+ unsigned int i;
+
for (cedge = node->callees; cedge; cedge = cedge->next_callee)
- cedge->call_stmt = stmts[cedge->lto_stmt_uid];
+ {
+ if (gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid)
+ fatal_error ("Cgraph edge statement index out of range");
+ cedge->call_stmt = stmts[cedge->lto_stmt_uid - 1];
+ if (!cedge->call_stmt)
+ fatal_error ("Cgraph edge statement index not found");
+ }
for (cedge = node->indirect_calls; cedge; cedge = cedge->next_callee)
- cedge->call_stmt = stmts[cedge->lto_stmt_uid];
+ {
+ if (gimple_stmt_max_uid (fn) < cedge->lto_stmt_uid)
+ fatal_error ("Cgraph edge statement index out of range");
+ cedge->call_stmt = stmts[cedge->lto_stmt_uid - 1];
+ if (!cedge->call_stmt)
+ fatal_error ("Cgraph edge statement index not found");
+ }
+ for (i = 0;
+ ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref);
+ i++)
+ if (ref->lto_stmt_uid)
+ {
+ if (gimple_stmt_max_uid (fn) < ref->lto_stmt_uid)
+ fatal_error ("Reference statement index out of range");
+ ref->stmt = stmts[ref->lto_stmt_uid - 1];
+ if (!ref->stmt)
+ fatal_error ("Reference statement index not found");
+ }
}
+
/* Fixup call_stmt pointers in NODE and all clones. */
static void
fixup_call_stmt_edges (struct cgraph_node *orig, gimple *stmts)
{
struct cgraph_node *node;
+ struct function *fn;
while (orig->clone_of)
orig = orig->clone_of;
+ fn = DECL_STRUCT_FUNCTION (orig->symbol.decl);
- fixup_call_stmt_edges_1 (orig, stmts);
+ fixup_call_stmt_edges_1 (orig, stmts, fn);
if (orig->clones)
for (node = orig->clones; node != orig;)
{
- fixup_call_stmt_edges_1 (node, stmts);
+ fixup_call_stmt_edges_1 (node, stmts, fn);
if (node->clones)
node = node->clones;
else if (node->next_sibling_clone)
@@ -851,7 +881,7 @@ input_struct_function_base (struct function *fn, struct data_in *data_in,
static void
input_function (tree fn_decl, struct data_in *data_in,
- struct lto_input_block *ib)
+ struct lto_input_block *ib, struct lto_input_block *ib_cfg)
{
struct function *fn;
enum LTO_tags tag;
@@ -859,13 +889,30 @@ input_function (tree fn_decl, struct data_in *data_in,
basic_block bb;
struct cgraph_node *node;
- fn = DECL_STRUCT_FUNCTION (fn_decl);
tag = streamer_read_record_start (ib);
+ lto_tag_check (tag, LTO_function);
+
+ /* Read decls for parameters and args. */
+ DECL_RESULT (fn_decl) = stream_read_tree (ib, data_in);
+ DECL_ARGUMENTS (fn_decl) = streamer_read_chain (ib, data_in);
+
+ /* Read the tree of lexical scopes for the function. */
+ DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
+
+ if (!streamer_read_uhwi (ib))
+ return;
+
+ push_struct_function (fn_decl);
+ fn = DECL_STRUCT_FUNCTION (fn_decl);
+ init_tree_ssa (fn);
+ /* We input IL in SSA form. */
+ cfun->gimple_df->in_ssa_p = true;
gimple_register_cfg_hooks ();
- lto_tag_check (tag, LTO_function);
+ node = cgraph_get_create_node (fn_decl);
input_struct_function_base (fn, data_in, ib);
+ input_cfg (ib_cfg, fn, node->count_materialization_scale);
/* Read all the SSA names. */
input_ssa_names (ib, data_in, fn);
@@ -873,11 +920,8 @@ input_function (tree fn_decl, struct data_in *data_in,
/* Read the exception handling regions in the function. */
input_eh_regions (ib, data_in, fn);
- /* Read the tree of lexical scopes for the function. */
- DECL_INITIAL (fn_decl) = stream_read_tree (ib, data_in);
gcc_assert (DECL_INITIAL (fn_decl));
DECL_SAVED_TREE (fn_decl) = NULL_TREE;
- node = cgraph_get_create_node (fn_decl);
/* Read all the basic blocks. */
tag = streamer_read_record_start (ib);
@@ -894,6 +938,11 @@ input_function (tree fn_decl, struct data_in *data_in,
FOR_ALL_BB (bb)
{
gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+ }
for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
@@ -903,7 +952,14 @@ input_function (tree fn_decl, struct data_in *data_in,
stmts = (gimple *) xcalloc (gimple_stmt_max_uid (fn), sizeof (gimple));
FOR_ALL_BB (bb)
{
- gimple_stmt_iterator bsi = gsi_start_bb (bb);
+ gimple_stmt_iterator bsi = gsi_start_phis (bb);
+ while (!gsi_end_p (bsi))
+ {
+ gimple stmt = gsi_stmt (bsi);
+ gsi_next (&bsi);
+ stmts[gimple_uid (stmt)] = stmt;
+ }
+ bsi = gsi_start_bb (bb);
while (!gsi_end_p (bsi))
{
gimple stmt = gsi_stmt (bsi);
@@ -942,17 +998,18 @@ input_function (tree fn_decl, struct data_in *data_in,
free_dominance_info (CDI_DOMINATORS);
free_dominance_info (CDI_POST_DOMINATORS);
free (stmts);
+ pop_cfun ();
}
-/* Read the body from DATA for function FN_DECL and fill it in.
+/* Read the body from DATA for function NODE and fill it in.
FILE_DATA are the global decls and types. SECTION_TYPE is either
LTO_section_function_body or LTO_section_static_initializer. If
section type is LTO_section_function_body, FN must be the decl for
that function. */
static void
-lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
+lto_read_body (struct lto_file_decl_data *file_data, struct cgraph_node *node,
const char *data, enum lto_section_type section_type)
{
const struct lto_function_header *header;
@@ -962,6 +1019,7 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
int string_offset;
struct lto_input_block ib_cfg;
struct lto_input_block ib_main;
+ tree fn_decl = node->symbol.decl;
header = (const struct lto_function_header *) data;
cfg_offset = sizeof (struct lto_function_header);
@@ -987,28 +1045,20 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
if (section_type == LTO_section_function_body)
{
- struct function *fn = DECL_STRUCT_FUNCTION (fn_decl);
struct lto_in_decl_state *decl_state;
- struct cgraph_node *node = cgraph_get_node (fn_decl);
unsigned from;
gcc_checking_assert (node);
- push_cfun (fn);
- init_tree_ssa (fn);
-
- /* We input IL in SSA form. */
- cfun->gimple_df->in_ssa_p = true;
/* Use the function's decl state. */
decl_state = lto_get_function_in_decl_state (file_data, fn_decl);
gcc_assert (decl_state);
file_data->current_decl_state = decl_state;
- input_cfg (&ib_cfg, fn, node->count_materialization_scale);
/* Set up the struct function. */
from = data_in->reader_cache->nodes.length ();
- input_function (fn_decl, data_in, &ib_main);
+ input_function (fn_decl, data_in, &ib_main, &ib_cfg);
/* And fixup types we streamed locally. */
{
struct streamer_tree_cache_d *cache = data_in->reader_cache;
@@ -1037,22 +1087,20 @@ lto_read_body (struct lto_file_decl_data *file_data, tree fn_decl,
/* Restore decl state */
file_data->current_decl_state = file_data->global_decl_state;
-
- pop_cfun ();
}
lto_data_in_delete (data_in);
}
-/* Read the body of FN_DECL using DATA. FILE_DATA holds the global
+/* Read the body of NODE using DATA. FILE_DATA holds the global
decls and types. */
void
lto_input_function_body (struct lto_file_decl_data *file_data,
- tree fn_decl, const char *data)
+ struct cgraph_node *node, const char *data)
{
- lto_read_body (file_data, fn_decl, data, LTO_section_function_body);
+ lto_read_body (file_data, node, data, LTO_section_function_body);
}
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index a962e9c5003..c46f71032af 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -124,8 +124,11 @@ output_type_ref (struct output_block *ob, tree node)
static bool
tree_is_indexable (tree t)
{
- if (TREE_CODE (t) == PARM_DECL)
- return true;
+ /* Parameters and return values of functions of variably modified types
+ must go to global stream, because they may be used in the type
+ definition. */
+ if (TREE_CODE (t) == PARM_DECL || TREE_CODE (t) == RESULT_DECL)
+ return variably_modified_type_p (TREE_TYPE (DECL_CONTEXT (t)), NULL_TREE);
else if (TREE_CODE (t) == VAR_DECL && decl_function_context (t)
&& !TREE_STATIC (t))
return false;
@@ -506,13 +509,7 @@ DFS_write_tree_body (struct output_block *ob,
if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
{
- if (TREE_CODE (expr) == FUNCTION_DECL)
- {
- for (tree t = DECL_ARGUMENTS (expr); t; t = TREE_CHAIN (t))
- DFS_follow_tree_edge (t);
- DFS_follow_tree_edge (DECL_RESULT (expr));
- }
- else if (TREE_CODE (expr) == TYPE_DECL)
+ if (TREE_CODE (expr) == TYPE_DECL)
DFS_follow_tree_edge (DECL_ORIGINAL_TYPE (expr));
DFS_follow_tree_edge (DECL_VINDEX (expr));
}
@@ -648,9 +645,8 @@ DFS_write_tree_body (struct output_block *ob,
FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (expr), i, t)
DFS_follow_tree_edge (t);
- DFS_follow_tree_edge (BINFO_INHERITANCE_CHAIN (expr));
- DFS_follow_tree_edge (BINFO_SUBVTT_INDEX (expr));
- DFS_follow_tree_edge (BINFO_VPTR_INDEX (expr));
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
@@ -754,7 +750,6 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
v = iterative_hash_host_wide_int (DECL_ALIGN (t), v);
if (code == LABEL_DECL)
{
- v = iterative_hash_host_wide_int (DECL_ERROR_ISSUED (t), v);
v = iterative_hash_host_wide_int (EH_LANDING_PAD_NR (t), v);
v = iterative_hash_host_wide_int (LABEL_DECL_UID (t), v);
}
@@ -787,23 +782,27 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
{
- v = iterative_hash_host_wide_int (DECL_DEFER_OUTPUT (t)
- | (DECL_COMMON (t) << 1)
- | (DECL_DLLIMPORT_P (t) << 2)
- | (DECL_WEAK (t) << 3)
- | (DECL_SEEN_IN_BIND_EXPR_P (t) << 4)
- | (DECL_COMDAT (t) << 5)
+ v = iterative_hash_host_wide_int ((DECL_COMMON (t))
+ | (DECL_DLLIMPORT_P (t) << 1)
+ | (DECL_WEAK (t) << 2)
+ | (DECL_SEEN_IN_BIND_EXPR_P (t) << 3)
+ | (DECL_COMDAT (t) << 4)
| (DECL_VISIBILITY_SPECIFIED (t) << 6),
v);
v = iterative_hash_host_wide_int (DECL_VISIBILITY (t), v);
if (code == VAR_DECL)
{
+ /* DECL_IN_TEXT_SECTION is set during final asm output only. */
v = iterative_hash_host_wide_int (DECL_HARD_REGISTER (t)
- | (DECL_IN_TEXT_SECTION (t) << 1)
- | (DECL_IN_CONSTANT_POOL (t) << 2),
+ | (DECL_IN_CONSTANT_POOL (t) << 1),
v);
v = iterative_hash_host_wide_int (DECL_TLS_MODEL (t), v);
}
+ if (TREE_CODE (t) == FUNCTION_DECL)
+ v = iterative_hash_host_wide_int (DECL_FINAL_P (t)
+ | (DECL_CXX_CONSTRUCTOR_P (t) << 1)
+ | (DECL_CXX_DESTRUCTOR_P (t) << 2),
+ v);
if (VAR_OR_FUNCTION_DECL_P (t))
v = iterative_hash_host_wide_int (DECL_INIT_PRIORITY (t), v);
}
@@ -844,7 +843,10 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
| (TYPE_USER_ALIGN (t) << 5)
| (TYPE_READONLY (t) << 6), v);
if (RECORD_OR_UNION_TYPE_P (t))
- v = iterative_hash_host_wide_int (TYPE_TRANSPARENT_AGGR (t), v);
+ {
+ v = iterative_hash_host_wide_int (TYPE_TRANSPARENT_AGGR (t)
+ | (TYPE_FINAL_P (t) << 1), v);
+ }
else if (code == ARRAY_TYPE)
v = iterative_hash_host_wide_int (TYPE_NONALIASED_COMPONENT (t), v);
v = iterative_hash_host_wide_int (TYPE_PRECISION (t), v);
@@ -936,13 +938,7 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
{
- if (code == FUNCTION_DECL)
- {
- for (tree a = DECL_ARGUMENTS (t); a; a = DECL_CHAIN (a))
- visit (a);
- visit (DECL_RESULT (t));
- }
- else if (code == TYPE_DECL)
+ if (code == TYPE_DECL)
visit (DECL_ORIGINAL_TYPE (t));
visit (DECL_VINDEX (t));
}
@@ -1033,9 +1029,8 @@ hash_tree (struct streamer_tree_cache_d *cache, tree t)
visit (BINFO_VPTR_FIELD (t));
FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (t), i, b)
visit (b);
- visit (BINFO_INHERITANCE_CHAIN (t));
- visit (BINFO_SUBVTT_INDEX (t));
- visit (BINFO_VPTR_INDEX (t));
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
@@ -1772,50 +1767,83 @@ output_function (struct cgraph_node *node)
streamer_write_record_start (ob, LTO_function);
- output_struct_function_base (ob, fn);
-
- /* Output all the SSA names used in the function. */
- output_ssa_names (ob, fn);
-
- /* Output any exception handling regions. */
- output_eh_regions (ob, fn);
+ /* Output decls for parameters and args. */
+ stream_write_tree (ob, DECL_RESULT (function), true);
+ streamer_write_chain (ob, DECL_ARGUMENTS (function), true);
/* Output DECL_INITIAL for the function, which contains the tree of
lexical scopes. */
stream_write_tree (ob, DECL_INITIAL (function), true);
- /* We will renumber the statements. The code that does this uses
- the same ordering that we use for serializing them so we can use
- the same code on the other end and not have to write out the
- statement numbers. We do not assign UIDs to PHIs here because
- virtual PHIs get re-computed on-the-fly which would make numbers
- inconsistent. */
- set_gimple_stmt_max_uid (cfun, 0);
- FOR_ALL_BB (bb)
- {
- gimple_stmt_iterator gsi;
- for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ /* We also stream abstract functions where we stream only stuff needed for
+ debug info. */
+ if (gimple_has_body_p (function))
+ {
+ streamer_write_uhwi (ob, 1);
+ output_struct_function_base (ob, fn);
+
+ /* Output all the SSA names used in the function. */
+ output_ssa_names (ob, fn);
+
+ /* Output any exception handling regions. */
+ output_eh_regions (ob, fn);
+
+
+ /* We will renumber the statements. The code that does this uses
+ the same ordering that we use for serializing them so we can use
+ the same code on the other end and not have to write out the
+ statement numbers. We do not assign UIDs to PHIs here because
+ virtual PHIs get re-computed on-the-fly which would make numbers
+ inconsistent. */
+ set_gimple_stmt_max_uid (cfun, 0);
+ FOR_ALL_BB (bb)
{
- gimple stmt = gsi_stmt (gsi);
- gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+
+ /* Virtual PHIs are not going to be streamed. */
+ if (!virtual_operand_p (gimple_phi_result (stmt)))
+ gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+ }
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+ }
+ }
+ /* To avoid keeping duplicate gimple IDs in the statements, renumber
+ virtual phis now. */
+ FOR_ALL_BB (bb)
+ {
+ gimple_stmt_iterator gsi;
+ for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (virtual_operand_p (gimple_phi_result (stmt)))
+ gimple_set_uid (stmt, inc_gimple_stmt_max_uid (cfun));
+ }
}
- }
- /* Output the code for the function. */
- FOR_ALL_BB_FN (bb, fn)
- output_bb (ob, bb, fn);
+ /* Output the code for the function. */
+ FOR_ALL_BB_FN (bb, fn)
+ output_bb (ob, bb, fn);
- /* The terminator for this function. */
- streamer_write_record_start (ob, LTO_null);
+ /* The terminator for this function. */
+ streamer_write_record_start (ob, LTO_null);
- output_cfg (ob, fn);
+ output_cfg (ob, fn);
+
+ pop_cfun ();
+ }
+ else
+ streamer_write_uhwi (ob, 0);
/* Create a section to hold the pickled output of this function. */
produce_asm (ob, function);
destroy_output_block (ob);
-
- pop_cfun ();
}
@@ -1957,8 +1985,7 @@ lto_output (void)
cgraph_node *node = dyn_cast <cgraph_node> (snode);
if (node
&& lto_symtab_encoder_encode_body_p (encoder, node)
- && !node->symbol.alias
- && !node->thunk.thunk_p)
+ && !node->symbol.alias)
{
#ifdef ENABLE_CHECKING
gcc_assert (!bitmap_bit_p (output, DECL_UID (node->symbol.decl)));
@@ -1966,7 +1993,7 @@ lto_output (void)
#endif
decl_state = lto_new_out_decl_state ();
lto_push_out_decl_state (decl_state);
- if (gimple_has_body_p (node->symbol.decl))
+ if (gimple_has_body_p (node->symbol.decl) || !flag_wpa)
output_function (node);
else
copy_function (node);
@@ -1987,35 +2014,52 @@ lto_output (void)
#endif
}
-struct ipa_opt_pass_d pass_ipa_lto_gimple_out =
+namespace {
+
+const pass_data pass_data_ipa_lto_gimple_out =
{
- {
- IPA_PASS,
- "lto_gimple_out", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_lto_out, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_LTO_GIMPLE_OUT, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- },
- NULL, /* generate_summary */
- lto_output, /* write_summary */
- NULL, /* read_summary */
- lto_output, /* write_optimization_summary */
- NULL, /* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- NULL, /* function_transform */
- NULL /* variable_transform */
+ IPA_PASS, /* type */
+ "lto_gimple_out", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_IPA_LTO_GIMPLE_OUT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_ipa_lto_gimple_out : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_lto_gimple_out(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_lto_gimple_out, ctxt,
+ NULL, /* generate_summary */
+ lto_output, /* write_summary */
+ NULL, /* read_summary */
+ lto_output, /* write_optimization_summary */
+ NULL, /* read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ NULL, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_lto_out (); }
+
+}; // class pass_ipa_lto_gimple_out
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_lto_gimple_out (gcc::context *ctxt)
+{
+ return new pass_ipa_lto_gimple_out (ctxt);
+}
+
/* Write each node in encoded by ENCODER to OB, as well as those reachable
from it and required for correct representation of its semantics.
@@ -2149,9 +2193,9 @@ write_symbol (struct streamer_tree_cache_d *cache,
if (!TREE_PUBLIC (t)
|| is_builtin_fn (t)
|| DECL_ABSTRACT (t)
- || TREE_CODE (t) == RESULT_DECL
|| (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t)))
return;
+ gcc_assert (TREE_CODE (t) != RESULT_DECL);
gcc_assert (TREE_CODE (t) == VAR_DECL
|| TREE_CODE (t) == FUNCTION_DECL);
@@ -2254,7 +2298,7 @@ output_symbol_p (symtab_node node)
and devirtualization. We do not want to see them in symbol table as
references unless they are really used. */
cnode = dyn_cast <cgraph_node> (node);
- if (cnode && DECL_EXTERNAL (cnode->symbol.decl)
+ if (cnode && (!node->symbol.definition || DECL_EXTERNAL (cnode->symbol.decl))
&& cnode->callers)
return true;
@@ -2262,7 +2306,7 @@ output_symbol_p (symtab_node node)
part of the compilation unit until they are used by folding. Some symbols,
like references to external construction vtables can not be referred to at all.
We decide this at can_refer_decl_in_current_unit_p. */
- if (DECL_EXTERNAL (node->symbol.decl))
+ if (!node->symbol.definition || DECL_EXTERNAL (node->symbol.decl))
{
int i;
struct ipa_ref *ref;
@@ -2442,31 +2486,48 @@ produce_asm_for_decls (void)
}
-struct ipa_opt_pass_d pass_ipa_lto_finish_out =
+namespace {
+
+const pass_data pass_data_ipa_lto_finish_out =
{
- {
- IPA_PASS,
- "lto_decls_out", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_lto_out, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_LTO_DECL_OUT, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- },
- NULL, /* generate_summary */
- produce_asm_for_decls, /* write_summary */
- NULL, /* read_summary */
- produce_asm_for_decls, /* write_optimization_summary */
- NULL, /* read_optimization_summary */
- NULL, /* stmt_fixup */
- 0, /* TODOs */
- NULL, /* function_transform */
- NULL /* variable_transform */
+ IPA_PASS, /* type */
+ "lto_decls_out", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_IPA_LTO_DECL_OUT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_ipa_lto_finish_out : public ipa_opt_pass_d
+{
+public:
+ pass_ipa_lto_finish_out(gcc::context *ctxt)
+ : ipa_opt_pass_d(pass_data_ipa_lto_finish_out, ctxt,
+ NULL, /* generate_summary */
+ produce_asm_for_decls, /* write_summary */
+ NULL, /* read_summary */
+ produce_asm_for_decls, /* write_optimization_summary */
+ NULL, /* read_optimization_summary */
+ NULL, /* stmt_fixup */
+ 0, /* function_transform_todo_flags_start */
+ NULL, /* function_transform */
+ NULL) /* variable_transform */
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_lto_out (); }
+
+}; // class pass_ipa_lto_finish_out
+
+} // anon namespace
+
+ipa_opt_pass_d *
+make_pass_ipa_lto_finish_out (gcc::context *ctxt)
+{
+ return new pass_ipa_lto_finish_out (ctxt);
+}
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index e7c89f16162..13a9593a866 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -774,6 +774,8 @@ extern hashval_t lto_hash_in_decl_state (const void *);
extern int lto_eq_in_decl_state (const void *, const void *);
extern struct lto_in_decl_state *lto_get_function_in_decl_state (
struct lto_file_decl_data *, tree);
+extern void lto_free_function_in_decl_state (struct lto_in_decl_state *);
+extern void lto_free_function_in_decl_state_for_node (symtab_node);
extern void lto_section_overrun (struct lto_input_block *) ATTRIBUTE_NORETURN;
extern void lto_value_range_error (const char *,
HOST_WIDE_INT, HOST_WIDE_INT,
@@ -832,7 +834,8 @@ extern void lto_streamer_hooks_init (void);
/* In lto-streamer-in.c */
extern void lto_input_cgraph (struct lto_file_decl_data *, const char *);
extern void lto_reader_init (void);
-extern void lto_input_function_body (struct lto_file_decl_data *, tree,
+extern void lto_input_function_body (struct lto_file_decl_data *,
+ struct cgraph_node *,
const char *);
extern void lto_input_constructors_and_inits (struct lto_file_decl_data *,
const char *);
@@ -900,7 +903,6 @@ lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
extern void lto_symtab_merge_decls (void);
extern void lto_symtab_merge_symbols (void);
extern tree lto_symtab_prevailing_decl (tree decl);
-extern GTY(()) vec<tree, va_gc> *lto_global_var_decls;
/* In lto-opts.c. */
@@ -1028,14 +1030,6 @@ lto_tree_ref_encoder_get_tree (struct lto_tree_ref_encoder *encoder,
return encoder->trees[idx];
}
-
-/* Return true if LABEL should be emitted in the global context. */
-static inline bool
-emit_label_in_global_context_p (tree label)
-{
- return DECL_NONLOCAL (label) || FORCED_LABEL (label);
-}
-
/* Return number of encoded nodes in ENCODER. */
static inline int
lto_symtab_encoder_size (lto_symtab_encoder_t encoder)
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index d6559750f92..8ac0f8d60a4 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,100 @@
+2013-09-06 Richard Biener <rguenther@suse.de>
+
+ * lto-symtab.c: Move from gcc/
+ * lto.h: Include vec.h.
+ (lto_global_var_decls): Declare.
+ * lto.c (lto_global_var_decls): Move definition here.
+ * Make-lang.in (LTO_OBJS): Add lto-symtab.o.
+ (lto-symtab.o): Add.
+ * config-lang.in (gtfiles): Add lto.h.
+
+2013-08-31 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (mentions_vars_p_field_decl, lto_fixup_prevailing_decls):
+ DECL_FIELD_OFFSET can contain an reference to variable.
+
+2013-08-31 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (tree_with_vars): Turn into vector.
+ (MAYBE_REMEMBER_WITH_VARS): Change to...
+ (CHECK_VAR): ... this one.
+ (CHECK_NO_VAR): New macro.
+ (maybe_remember_with_vars_typed): Turn to ...
+ (mentions_vars_p_typed): ... this one.
+ (maybe_remember_with_vars_common): Turn to ...
+ (mentions_vars_p_comon): ... this one.
+ (maybe_remember_with_vars_decl_minimal): Turn to ...
+ (mentions_vars_p_decl_minmal): ... this one.
+ (maybe_remember_with_vars_decl_common): Turn to ...
+ (mentions_vars_p_decl_common): ... this one.
+ (maybe_remember_with_vars_decl_with_vis): Turn to ...
+ (mentions_vars_p_decl_with_vis): ... this one.
+ (maybe_remember_with_vars_decl_non_common): Turn to ...
+ (mentions_vars_p_decl_non_common): ... this one.
+ (maybe_remember_with_vars_function): Turn to ...
+ (mentions_vars_p_function): ... this one.
+ (maybe_remember_with_vars_field_decl): Turn to ...
+ (mentions_vars_p_field_decl): ... this one.
+ (maybe_remember_with_vars_type): Turn to ...
+ (mentions_vars_p_type): ... this one.
+ (maybe_remember_with_vars_binfo): Turn to ...
+ (mentions_vars_p_binfo): ... this one.
+ (maybe_remember_with_vars_constructor): Turn to ...
+ (mentions_vars_p_constructor): ... this one.
+ (maybe_remember_with_vars_expr): Turn to ...
+ (mentions_vars_p_expr): ... this one.
+ (maybe_remember_with_vars): Turn to ...
+ (mentions_vars_p): ... this one.
+ (lto_read_decls): Update.
+ (LTO_SET_PREVAIL): Do not call function for internal decls.
+ (lto_fixup_prevailing_decls): Update to match mentions_vars_p;
+ check that something was updated.
+ (lto_fixup_state): Do not care about internal decls.
+ (lto_fixup_decls): Update.
+ (read_cgraph_and_symbols): Update.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (read_cgraph_and_symbols): Free decl states.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (compare_tree_sccs_1): Compare DECL_FINAL_P,
+ DECL_CXX_CONSTRUCTOR_P, DECL_CXX_DESTRUCTOR_P and
+ TYPE_FINAL_P.
+
+2013-08-28 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (compare_tree_sccs_1): Drop DECL_ERROR_ISSUED,
+ DECL_DEFER_OUTPUT and DECL_IN_TEXT_SECTION.
+ (unify_scc): Do checking assert.
+
+2013-08-06 Jan Hubicka <jh@suse.cz>
+ Martin Liska <marxin.liska@gmail.com>
+
+ * lto-partition.c (lto_balanced_map): Always base order on
+ source file order.
+
+2013-08-06 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (lto_materialize_function): Do not read body anymore.
+
+2013-08-02 Jan Hubicka <jh@suse.cz>
+
+ * lto.c (lto_materialize_function): Do not push struct function.
+ * lto-partition.c (get_symbol_class): Handle abstracts correctly.
+ (may_need_named_section_p): Even abstract origins may need
+ named section.
+
+2013-07-30 David Malcolm <dmalcolm@redhat.com>
+
+ * Make-lang.in (lto/lto.o:): Depend on CONTEXT_H and
+ PASS_MANAGER_H.
+
+ * lto.c (do_whole_program_analysis): Update for move of
+ all_regular_ipa_passes from a global to a field of class
+ pass_manager.
+
2013-07-21 Ondřej Bílka <neleai@seznam.cz>
* lto-partition.c: Fix typos.
diff --git a/gcc/lto/Make-lang.in b/gcc/lto/Make-lang.in
index 5f2f475879a..c67c58e7f83 100644
--- a/gcc/lto/Make-lang.in
+++ b/gcc/lto/Make-lang.in
@@ -22,7 +22,7 @@
# The name of the LTO compiler.
LTO_EXE = lto1$(exeext)
# The LTO-specific object files inclued in $(LTO_EXE).
-LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-object.o attribs.o lto/lto-partition.o
+LTO_OBJS = lto/lto-lang.o lto/lto.o lto/lto-object.o attribs.o lto/lto-partition.o lto/lto-symtab.o
LTO_H = lto/lto.h $(HASHTAB_H)
LINKER_PLUGIN_API_H = $(srcdir)/../include/plugin-api.h
LTO_TREE_H = lto/lto-tree.h $(LINKER_PLUGIN_API_H)
@@ -85,7 +85,8 @@ lto/lto.o: lto/lto.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(OPTS_H) \
langhooks.h $(VEC_H) $(BITMAP_H) pointer-set.h $(IPA_PROP_H) \
$(COMMON_H) debug.h $(GIMPLE_H) $(LTO_H) $(LTO_TREE_H) \
$(LTO_TAGS_H) $(LTO_STREAMER_H) $(SPLAY_TREE_H) gt-lto-lto.h \
- $(TREE_STREAMER_H) $(DATA_STREAMER_H) lto/lto-partition.h
+ $(TREE_STREAMER_H) $(DATA_STREAMER_H) lto/lto-partition.h \
+ $(CONTEXT_H) $(PIPELINE_H)
lto/lto-partition.o: lto/lto-partition.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
toplev.h $(TREE_H) $(TM_H) \
$(CGRAPH_H) $(TIMEVAR_H) \
@@ -94,6 +95,9 @@ lto/lto-partition.o: lto/lto-partition.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
lto/lto-object.o: lto/lto-object.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(DIAGNOSTIC_CORE_H) $(LTO_H) $(TM_H) $(LTO_STREAMER_H) \
../include/simple-object.h
+lto/lto-symtab.o: lto/lto-symtab.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
+ $(TREE_H) $(GIMPLE_H) $(GGC_H) $(HASHTAB_H) \
+ $(LTO_STREAMER_H) $(LINKER_PLUGIN_API_H)
# LTO testing is done as part of C/C++/Fortran etc. testing.
check-lto:
diff --git a/gcc/lto/config-lang.in b/gcc/lto/config-lang.in
index 266446de6d2..9217c5dfbaa 100644
--- a/gcc/lto/config-lang.in
+++ b/gcc/lto/config-lang.in
@@ -21,7 +21,7 @@ language="lto"
compilers="lto1\$(exeext)"
stagestuff="lto1\$(exeext)"
-gtfiles="\$(srcdir)/lto/lto-tree.h \$(srcdir)/lto/lto-lang.c \$(srcdir)/lto/lto.c"
+gtfiles="\$(srcdir)/lto/lto-tree.h \$(srcdir)/lto/lto-lang.c \$(srcdir)/lto/lto.c \$(srcdir)/lto/lto.h"
# LTO is a special front end. From a user's perspective it is not
# really a language, but a middle end feature. However, the GIMPLE
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 63e6ab96901..e05f805fea4 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -56,6 +56,10 @@ get_symbol_class (symtab_node node)
/* Inline clones are always duplicated.
This include external delcarations. */
cgraph_node *cnode = dyn_cast <cgraph_node> (node);
+
+ if (DECL_ABSTRACT (node->symbol.decl))
+ return SYMBOL_EXTERNAL;
+
if (cnode && cnode->global.inlined_to)
return SYMBOL_DUPLICATE;
@@ -445,11 +449,9 @@ lto_balanced_map (void)
{
int n_nodes = 0;
int n_varpool_nodes = 0, varpool_pos = 0, best_varpool_pos = 0;
- struct cgraph_node **postorder =
- XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
struct cgraph_node **order = XNEWVEC (struct cgraph_node *, cgraph_max_uid);
struct varpool_node **varpool_order = NULL;
- int i, postorder_len;
+ int i;
struct cgraph_node *node;
int total_size = 0, best_total_size = 0;
int partition_size;
@@ -464,24 +466,20 @@ lto_balanced_map (void)
FOR_EACH_VARIABLE (vnode)
gcc_assert (!vnode->symbol.aux);
- /* Until we have better ordering facility, use toplogical order.
- Include only nodes we will partition and compute estimate of program
- size. Note that since nodes that are not partitioned might be put into
- multiple partitions, this is just an estimate of real size. This is why
- we keep partition_size updated after every partition is finalized. */
- postorder_len = ipa_reverse_postorder (postorder);
- for (i = 0; i < postorder_len; i++)
- {
- node = postorder[i];
- if (get_symbol_class ((symtab_node) node) == SYMBOL_PARTITION)
- {
- order[n_nodes++] = node;
- total_size += inline_summary (node)->size;
- }
- }
- free (postorder);
+ FOR_EACH_DEFINED_FUNCTION (node)
+ if (get_symbol_class ((symtab_node) node) == SYMBOL_PARTITION)
+ {
+ order[n_nodes++] = node;
+ total_size += inline_summary (node)->size;
+ }
+ /* Streaming works best when the source units do not cross partition
+ boundaries much. This is because importing function from a source
+ unit tends to import a lot of global trees defined there. We should
+ get better about minimizing the function bounday, but until that
+ things works smoother if we order in source order. */
+ qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp);
if (!flag_toplevel_reorder)
{
qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp);
@@ -840,8 +838,6 @@ may_need_named_section_p (lto_symtab_encoder_t encoder, symtab_node node)
return false;
if (symtab_real_symbol_p (node))
return false;
- if (!cnode->global.inlined_to && !cnode->clones)
- return false;
return (!encoder
|| (lto_symtab_encoder_lookup (encoder, node) != LCC_NOT_FOUND
&& lto_symtab_encoder_encode_body_p (encoder,
diff --git a/gcc/lto-symtab.c b/gcc/lto/lto-symtab.c
index f9bf37c7005..b1b7731c830 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -28,9 +28,7 @@ along with GCC; see the file COPYING3. If not see
#include "hashtab.h"
#include "plugin-api.h"
#include "lto-streamer.h"
-
-/* Vector to keep track of external variables we've seen so far. */
-vec<tree, va_gc> *lto_global_var_decls;
+#include "ipa-utils.h"
/* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
all edges and removing the old node. */
@@ -80,6 +78,9 @@ lto_cgraph_replace_node (struct cgraph_node *node,
/* Redirect incomming references. */
ipa_clone_referring ((symtab_node)prevailing_node, &node->symbol.ref_list);
+ ipa_merge_profiles (prevailing_node, node);
+ lto_free_function_in_decl_state_for_node ((symtab_node)node);
+
if (node->symbol.decl != prevailing_node->symbol.decl)
cgraph_release_function_body (node);
@@ -582,6 +583,9 @@ lto_symtab_merge_symbols (void)
FOR_EACH_SYMBOL (node)
{
cgraph_node *cnode, *cnode2;
+ varpool_node *vnode;
+ symtab_node node2;
+
if (!node->symbol.analyzed && node->symbol.alias_target)
{
symtab_node tgt = symtab_node_for_asm (node->symbol.alias_target);
@@ -590,15 +594,37 @@ lto_symtab_merge_symbols (void)
symtab_resolve_alias (node, tgt);
}
node->symbol.aux = NULL;
-
+
if (!(cnode = dyn_cast <cgraph_node> (node))
|| !cnode->clone_of
|| cnode->clone_of->symbol.decl != cnode->symbol.decl)
{
+ /* Builtins are not merged via decl merging. It is however
+ possible that tree merging unified the declaration. We
+ do not want duplicate entries in symbol table. */
if (cnode && DECL_BUILT_IN (node->symbol.decl)
&& (cnode2 = cgraph_get_node (node->symbol.decl))
&& cnode2 != cnode)
lto_cgraph_replace_node (cnode2, cnode);
+
+ /* The user defined assembler variables are also not unified by their
+ symbol name (since it is irrelevant), but we need to unify symbol
+ nodes if tree merging occured. */
+ if ((vnode = dyn_cast <varpool_node> (node))
+ && DECL_HARD_REGISTER (vnode->symbol.decl)
+ && (node2 = symtab_get_node (vnode->symbol.decl))
+ && node2 != node)
+ lto_varpool_replace_node (dyn_cast <varpool_node> (node2),
+ vnode);
+
+
+ /* Abstract functions may have duplicated cgraph nodes attached;
+ remove them. */
+ else if (cnode && DECL_ABSTRACT (cnode->symbol.decl)
+ && (cnode2 = cgraph_get_node (node->symbol.decl))
+ && cnode2 != cnode)
+ cgraph_remove_node (cnode2);
+
symtab_insert_node_to_hashtable ((symtab_node)node);
}
}
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index c0f9328b726..470f3c1d7a7 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -46,6 +46,11 @@ along with GCC; see the file COPYING3. If not see
#include "splay-tree.h"
#include "lto-partition.h"
#include "data-streamer.h"
+#include "context.h"
+#include "pass_manager.h"
+
+/* Vector to keep track of external variables we've seen so far. */
+vec<tree, va_gc> *lto_global_var_decls;
static GTY(()) tree first_personality_decl;
@@ -190,50 +195,19 @@ static void
lto_materialize_function (struct cgraph_node *node)
{
tree decl;
- struct lto_file_decl_data *file_data;
- const char *data, *name;
- size_t len;
decl = node->symbol.decl;
/* Read in functions with body (analyzed nodes)
and also functions that are needed to produce virtual clones. */
if ((cgraph_function_with_gimple_body_p (node) && node->symbol.analyzed)
+ || node->used_as_abstract_origin
|| has_analyzed_clone_p (node))
{
/* Clones don't need to be read. */
if (node->clone_of)
return;
-
- /* Load the function body only if not operating in WPA mode. In
- WPA mode, the body of the function is not needed. */
- if (!flag_wpa)
- {
- file_data = node->symbol.lto_file_data;
- name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
-
- /* We may have renamed the declaration, e.g., a static function. */
- name = lto_get_decl_name_mapping (file_data, name);
-
- data = lto_get_section_data (file_data, LTO_section_function_body,
- name, &len);
- if (!data)
- fatal_error ("%s: section %s is missing",
- file_data->file_name,
- name);
-
- gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL);
-
- push_struct_function (decl);
- announce_function (decl);
- lto_input_function_body (file_data, decl, data);
- if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
- first_personality_decl = DECL_FUNCTION_PERSONALITY (decl);
- lto_stats.num_function_bodies++;
- lto_free_section_data (file_data, LTO_section_function_body, name,
- data, len);
- pop_cfun ();
- ggc_collect ();
- }
+ if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl)
+ first_personality_decl = DECL_FUNCTION_PERSONALITY (decl);
}
/* Let the middle end know about the function. */
@@ -1312,197 +1286,206 @@ gimple_register_type (tree t)
/* End of old merging code. */
+/* Remember trees that contains references to declarations. */
+static GTY(()) vec <tree, va_gc> *tree_with_vars;
-
-/* A hashtable of trees that potentially refer to variables or functions
- that must be replaced with their prevailing variant. */
-static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node))) htab_t
- tree_with_vars;
-
-/* Remember that T is a tree that (potentially) refers to a variable
- or function decl that may be replaced with its prevailing variant. */
-static void
-remember_with_vars (tree t)
-{
- *(tree *) htab_find_slot (tree_with_vars, t, INSERT) = t;
-}
-
-#define MAYBE_REMEMBER_WITH_VARS(tt) \
+#define CHECK_VAR(tt) \
do \
{ \
- if (tt) \
- { \
- if (VAR_OR_FUNCTION_DECL_P (tt) && TREE_PUBLIC (tt)) \
- remember_with_vars (t); \
- } \
+ if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
+ && (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
+ return true; \
} while (0)
-/* Fix up fields of a tree_typed T. */
+#define CHECK_NO_VAR(tt) \
+ gcc_checking_assert (!(tt) || !VAR_OR_FUNCTION_DECL_P (tt))
-static void
-maybe_remember_with_vars_typed (tree t)
+/* Check presence of pointers to decls in fields of a tree_typed T. */
+
+static inline bool
+mentions_vars_p_typed (tree t)
{
- MAYBE_REMEMBER_WITH_VARS (TREE_TYPE (t));
+ CHECK_NO_VAR (TREE_TYPE (t));
+ return false;
}
-/* Fix up fields of a tree_common T. */
+/* Check presence of pointers to decls in fields of a tree_common T. */
-static void
-maybe_remember_with_vars_common (tree t)
+static inline bool
+mentions_vars_p_common (tree t)
{
- maybe_remember_with_vars_typed (t);
- MAYBE_REMEMBER_WITH_VARS (TREE_CHAIN (t));
+ if (mentions_vars_p_typed (t))
+ return true;
+ CHECK_NO_VAR (TREE_CHAIN (t));
+ return false;
}
-/* Fix up fields of a decl_minimal T. */
+/* Check presence of pointers to decls in fields of a decl_minimal T. */
-static void
-maybe_remember_with_vars_decl_minimal (tree t)
+static inline bool
+mentions_vars_p_decl_minimal (tree t)
{
- maybe_remember_with_vars_common (t);
- MAYBE_REMEMBER_WITH_VARS (DECL_NAME (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_CONTEXT (t));
+ if (mentions_vars_p_common (t))
+ return true;
+ CHECK_NO_VAR (DECL_NAME (t));
+ CHECK_VAR (DECL_CONTEXT (t));
+ return false;
}
-/* Fix up fields of a decl_common T. */
+/* Check presence of pointers to decls in fields of a decl_common T. */
-static void
-maybe_remember_with_vars_decl_common (tree t)
+static inline bool
+mentions_vars_p_decl_common (tree t)
{
- maybe_remember_with_vars_decl_minimal (t);
- MAYBE_REMEMBER_WITH_VARS (DECL_SIZE (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_SIZE_UNIT (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_INITIAL (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_ATTRIBUTES (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_ABSTRACT_ORIGIN (t));
+ if (mentions_vars_p_decl_minimal (t))
+ return true;
+ CHECK_VAR (DECL_SIZE (t));
+ CHECK_VAR (DECL_SIZE_UNIT (t));
+ CHECK_VAR (DECL_INITIAL (t));
+ CHECK_NO_VAR (DECL_ATTRIBUTES (t));
+ CHECK_VAR (DECL_ABSTRACT_ORIGIN (t));
+ return false;
}
-/* Fix up fields of a decl_with_vis T. */
+/* Check presence of pointers to decls in fields of a decl_with_vis T. */
-static void
-maybe_remember_with_vars_decl_with_vis (tree t)
+static inline bool
+mentions_vars_p_decl_with_vis (tree t)
{
- maybe_remember_with_vars_decl_common (t);
+ if (mentions_vars_p_decl_common (t))
+ return true;
/* Accessor macro has side-effects, use field-name here. */
- MAYBE_REMEMBER_WITH_VARS (t->decl_with_vis.assembler_name);
- MAYBE_REMEMBER_WITH_VARS (DECL_SECTION_NAME (t));
+ CHECK_NO_VAR (t->decl_with_vis.assembler_name);
+ CHECK_NO_VAR (DECL_SECTION_NAME (t));
+ return false;
}
-/* Fix up fields of a decl_non_common T. */
+/* Check presence of pointers to decls in fields of a decl_non_common T. */
-static void
-maybe_remember_with_vars_decl_non_common (tree t)
+static inline bool
+mentions_vars_p_decl_non_common (tree t)
{
- maybe_remember_with_vars_decl_with_vis (t);
- MAYBE_REMEMBER_WITH_VARS (DECL_ARGUMENT_FLD (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_RESULT_FLD (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_VINDEX (t));
+ if (mentions_vars_p_decl_with_vis (t))
+ return true;
+ CHECK_NO_VAR (DECL_ARGUMENT_FLD (t));
+ CHECK_NO_VAR (DECL_RESULT_FLD (t));
+ CHECK_NO_VAR (DECL_VINDEX (t));
+ return false;
}
-/* Fix up fields of a decl_non_common T. */
+/* Check presence of pointers to decls in fields of a decl_non_common T. */
-static void
-maybe_remember_with_vars_function (tree t)
+static bool
+mentions_vars_p_function (tree t)
{
- maybe_remember_with_vars_decl_non_common (t);
- MAYBE_REMEMBER_WITH_VARS (DECL_FUNCTION_PERSONALITY (t));
+ if (mentions_vars_p_decl_non_common (t))
+ return true;
+ CHECK_VAR (DECL_FUNCTION_PERSONALITY (t));
+ return false;
}
-/* Fix up fields of a field_decl T. */
+/* Check presence of pointers to decls in fields of a field_decl T. */
-static void
-maybe_remember_with_vars_field_decl (tree t)
+static bool
+mentions_vars_p_field_decl (tree t)
{
- maybe_remember_with_vars_decl_common (t);
- MAYBE_REMEMBER_WITH_VARS (DECL_FIELD_OFFSET (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_BIT_FIELD_TYPE (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_QUALIFIER (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_FIELD_BIT_OFFSET (t));
- MAYBE_REMEMBER_WITH_VARS (DECL_FCONTEXT (t));
+ if (mentions_vars_p_decl_common (t))
+ return true;
+ CHECK_VAR (DECL_FIELD_OFFSET (t));
+ CHECK_NO_VAR (DECL_BIT_FIELD_TYPE (t));
+ CHECK_NO_VAR (DECL_QUALIFIER (t));
+ CHECK_NO_VAR (DECL_FIELD_BIT_OFFSET (t));
+ CHECK_NO_VAR (DECL_FCONTEXT (t));
+ return false;
}
-/* Fix up fields of a type T. */
+/* Check presence of pointers to decls in fields of a type T. */
-static void
-maybe_remember_with_vars_type (tree t)
+static bool
+mentions_vars_p_type (tree t)
{
- maybe_remember_with_vars_common (t);
- MAYBE_REMEMBER_WITH_VARS (TYPE_CACHED_VALUES (t));
- MAYBE_REMEMBER_WITH_VARS (TYPE_SIZE (t));
- MAYBE_REMEMBER_WITH_VARS (TYPE_SIZE_UNIT (t));
- MAYBE_REMEMBER_WITH_VARS (TYPE_ATTRIBUTES (t));
- MAYBE_REMEMBER_WITH_VARS (TYPE_NAME (t));
+ if (mentions_vars_p_common (t))
+ return true;
+ CHECK_NO_VAR (TYPE_CACHED_VALUES (t));
+ CHECK_VAR (TYPE_SIZE (t));
+ CHECK_VAR (TYPE_SIZE_UNIT (t));
+ CHECK_NO_VAR (TYPE_ATTRIBUTES (t));
+ CHECK_NO_VAR (TYPE_NAME (t));
- /* Accessors are for derived node types only. */
- if (!POINTER_TYPE_P (t))
- MAYBE_REMEMBER_WITH_VARS (TYPE_MINVAL (t));
- MAYBE_REMEMBER_WITH_VARS (TYPE_MAXVAL (t));
+ CHECK_VAR (TYPE_MINVAL (t));
+ CHECK_VAR (TYPE_MAXVAL (t));
/* Accessor is for derived node types only. */
- MAYBE_REMEMBER_WITH_VARS (t->type_non_common.binfo);
+ CHECK_NO_VAR (t->type_non_common.binfo);
- MAYBE_REMEMBER_WITH_VARS (TYPE_CONTEXT (t));
+ CHECK_VAR (TYPE_CONTEXT (t));
+ CHECK_NO_VAR (TYPE_CANONICAL (t));
+ CHECK_NO_VAR (TYPE_MAIN_VARIANT (t));
+ CHECK_NO_VAR (TYPE_NEXT_VARIANT (t));
+ return false;
}
-/* Fix up fields of a BINFO T. */
+/* Check presence of pointers to decls in fields of a BINFO T. */
-static void
-maybe_remember_with_vars_binfo (tree t)
+static bool
+mentions_vars_p_binfo (tree t)
{
unsigned HOST_WIDE_INT i, n;
- maybe_remember_with_vars_common (t);
- MAYBE_REMEMBER_WITH_VARS (BINFO_VTABLE (t));
- MAYBE_REMEMBER_WITH_VARS (BINFO_OFFSET (t));
- MAYBE_REMEMBER_WITH_VARS (BINFO_VIRTUALS (t));
- MAYBE_REMEMBER_WITH_VARS (BINFO_VPTR_FIELD (t));
+ if (mentions_vars_p_common (t))
+ return true;
+ CHECK_VAR (BINFO_VTABLE (t));
+ CHECK_NO_VAR (BINFO_OFFSET (t));
+ CHECK_NO_VAR (BINFO_VIRTUALS (t));
+ CHECK_NO_VAR (BINFO_VPTR_FIELD (t));
n = vec_safe_length (BINFO_BASE_ACCESSES (t));
for (i = 0; i < n; i++)
- MAYBE_REMEMBER_WITH_VARS (BINFO_BASE_ACCESS (t, i));
- MAYBE_REMEMBER_WITH_VARS (BINFO_INHERITANCE_CHAIN (t));
- MAYBE_REMEMBER_WITH_VARS (BINFO_SUBVTT_INDEX (t));
- MAYBE_REMEMBER_WITH_VARS (BINFO_VPTR_INDEX (t));
+ CHECK_NO_VAR (BINFO_BASE_ACCESS (t, i));
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
n = BINFO_N_BASE_BINFOS (t);
for (i = 0; i < n; i++)
- MAYBE_REMEMBER_WITH_VARS (BINFO_BASE_BINFO (t, i));
+ CHECK_NO_VAR (BINFO_BASE_BINFO (t, i));
+ return false;
}
-/* Fix up fields of a CONSTRUCTOR T. */
+/* Check presence of pointers to decls in fields of a CONSTRUCTOR T. */
-static void
-maybe_remember_with_vars_constructor (tree t)
+static bool
+mentions_vars_p_constructor (tree t)
{
unsigned HOST_WIDE_INT idx;
constructor_elt *ce;
- maybe_remember_with_vars_typed (t);
+ if (mentions_vars_p_typed (t))
+ return true;
for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce); idx++)
{
- MAYBE_REMEMBER_WITH_VARS (ce->index);
- MAYBE_REMEMBER_WITH_VARS (ce->value);
+ CHECK_NO_VAR (ce->index);
+ CHECK_VAR (ce->value);
}
+ return false;
}
-/* Fix up fields of an expression tree T. */
+/* Check presence of pointers to decls in fields of an expression tree T. */
-static void
-maybe_remember_with_vars_expr (tree t)
+static bool
+mentions_vars_p_expr (tree t)
{
int i;
- maybe_remember_with_vars_typed (t);
+ if (mentions_vars_p_typed (t))
+ return true;
for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
- MAYBE_REMEMBER_WITH_VARS (TREE_OPERAND (t, i));
+ CHECK_VAR (TREE_OPERAND (t, i));
+ return false;
}
-/* Given a tree T fixup fields of T by replacing types with their merged
- variant and other entities by an equal entity from an earlier compilation
- unit, or an entity being canonical in a different way. This includes
- for instance integer or string constants. */
+/* Check presence of pointers to decls that needs later fixup in T. */
-static void
-maybe_remember_with_vars (tree t)
+static bool
+mentions_vars_p (tree t)
{
switch (TREE_CODE (t))
{
@@ -1510,13 +1493,13 @@ maybe_remember_with_vars (tree t)
break;
case TREE_LIST:
- MAYBE_REMEMBER_WITH_VARS (TREE_VALUE (t));
- MAYBE_REMEMBER_WITH_VARS (TREE_PURPOSE (t));
- MAYBE_REMEMBER_WITH_VARS (TREE_CHAIN (t));
+ CHECK_VAR (TREE_VALUE (t));
+ CHECK_VAR (TREE_PURPOSE (t));
+ CHECK_NO_VAR (TREE_CHAIN (t));
break;
case FIELD_DECL:
- maybe_remember_with_vars_field_decl (t);
+ return mentions_vars_p_field_decl (t);
break;
case LABEL_DECL:
@@ -1524,27 +1507,28 @@ maybe_remember_with_vars (tree t)
case PARM_DECL:
case RESULT_DECL:
case IMPORTED_DECL:
- maybe_remember_with_vars_decl_common (t);
+ case NAMESPACE_DECL:
+ return mentions_vars_p_decl_common (t);
break;
case VAR_DECL:
- maybe_remember_with_vars_decl_with_vis (t);
+ return mentions_vars_p_decl_with_vis (t);
break;
case TYPE_DECL:
- maybe_remember_with_vars_decl_non_common (t);
+ return mentions_vars_p_decl_non_common (t);
break;
case FUNCTION_DECL:
- maybe_remember_with_vars_function (t);
+ return mentions_vars_p_function (t);
break;
case TREE_BINFO:
- maybe_remember_with_vars_binfo (t);
+ return mentions_vars_p_binfo (t);
break;
case PLACEHOLDER_EXPR:
- maybe_remember_with_vars_common (t);
+ return mentions_vars_p_common (t);
break;
case BLOCK:
@@ -1554,19 +1538,26 @@ maybe_remember_with_vars (tree t)
break;
case CONSTRUCTOR:
- maybe_remember_with_vars_constructor (t);
+ return mentions_vars_p_constructor (t);
break;
default:
if (TYPE_P (t))
- maybe_remember_with_vars_type (t);
- else if (CONSTANT_CLASS_P (t))
- MAYBE_REMEMBER_WITH_VARS (TREE_TYPE (t));
+ {
+ if (mentions_vars_p_type (t))
+ return true;
+ }
else if (EXPR_P (t))
- maybe_remember_with_vars_expr (t);
+ {
+ if (mentions_vars_p_expr (t))
+ return true;
+ }
+ else if (CONSTANT_CLASS_P (t))
+ CHECK_NO_VAR (TREE_TYPE (t));
else
- remember_with_vars (t);
+ gcc_unreachable ();
}
+ return false;
}
@@ -1852,7 +1843,6 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (DECL_ALIGN);
if (code == LABEL_DECL)
{
- compare_values (DECL_ERROR_ISSUED);
compare_values (EH_LANDING_PAD_NR);
compare_values (LABEL_DECL_UID);
}
@@ -1883,7 +1873,6 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
{
- compare_values (DECL_DEFER_OUTPUT);
compare_values (DECL_COMMON);
compare_values (DECL_DLLIMPORT_P);
compare_values (DECL_WEAK);
@@ -1894,7 +1883,7 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
if (code == VAR_DECL)
{
compare_values (DECL_HARD_REGISTER);
- compare_values (DECL_IN_TEXT_SECTION);
+ /* DECL_IN_TEXT_SECTION is set during final asm output only. */
compare_values (DECL_IN_CONSTANT_POOL);
compare_values (DECL_TLS_MODEL);
}
@@ -1921,6 +1910,9 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (DECL_DISREGARD_INLINE_LIMITS);
compare_values (DECL_PURE_P);
compare_values (DECL_LOOPING_CONST_OR_PURE_P);
+ compare_values (DECL_FINAL_P);
+ compare_values (DECL_CXX_CONSTRUCTOR_P);
+ compare_values (DECL_CXX_DESTRUCTOR_P);
if (DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN)
compare_values (DECL_FUNCTION_CODE);
if (DECL_STATIC_DESTRUCTOR (t1))
@@ -1934,7 +1926,10 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_values (TYPE_NO_FORCE_BLK);
compare_values (TYPE_NEEDS_CONSTRUCTING);
if (RECORD_OR_UNION_TYPE_P (t1))
- compare_values (TYPE_TRANSPARENT_AGGR);
+ {
+ compare_values (TYPE_TRANSPARENT_AGGR);
+ compare_values (TYPE_FINAL_P);
+ }
else if (code == ARRAY_TYPE)
compare_values (TYPE_NONALIASED_COMPONENT);
compare_values (TYPE_PACKED);
@@ -2196,12 +2191,8 @@ compare_tree_sccs_1 (tree t1, tree t2, tree **map)
compare_tree_edges (BINFO_OFFSET (t1), BINFO_OFFSET (t2));
compare_tree_edges (BINFO_VTABLE (t1), BINFO_VTABLE (t2));
compare_tree_edges (BINFO_VPTR_FIELD (t1), BINFO_VPTR_FIELD (t2));
- compare_tree_edges (BINFO_INHERITANCE_CHAIN (t1),
- BINFO_INHERITANCE_CHAIN (t2));
- compare_tree_edges (BINFO_SUBVTT_INDEX (t1),
- BINFO_SUBVTT_INDEX (t2));
- compare_tree_edges (BINFO_VPTR_INDEX (t1),
- BINFO_VPTR_INDEX (t2));
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
@@ -2313,7 +2304,7 @@ unify_scc (struct streamer_tree_cache_d *cache, unsigned from,
for (unsigned i = 0; i < scc->len; ++i)
{
TREE_VISITED (scc->entries[i]) = 1;
- gcc_assert (!TREE_ASM_WRITTEN (scc->entries[i]));
+ gcc_checking_assert (!TREE_ASM_WRITTEN (scc->entries[i]));
}
tree *map = XALLOCAVEC (tree, 2 * len);
@@ -2522,7 +2513,8 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
lto_register_function_decl_in_symtab (data_in, t, from + i);
/* Scan the tree for references to global functions or
variables and record those for later fixup. */
- maybe_remember_with_vars (t);
+ if (mentions_vars_p (t))
+ vec_safe_push (tree_with_vars, t);
}
}
if (not_merged_type_same_scc)
@@ -3167,8 +3159,12 @@ lto_wpa_write_files (void)
prevailing variant. */
#define LTO_SET_PREVAIL(tt) \
do {\
- if ((tt) && VAR_OR_FUNCTION_DECL_P (tt)) \
- tt = lto_symtab_prevailing_decl (tt); \
+ if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
+ && (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
+ { \
+ tt = lto_symtab_prevailing_decl (tt); \
+ fixed = true; \
+ } \
} while (0)
/* Ensure that TT isn't a replacable var of function decl. */
@@ -3181,6 +3177,9 @@ static void
lto_fixup_prevailing_decls (tree t)
{
enum tree_code code = TREE_CODE (t);
+ bool fixed = false;
+
+ gcc_checking_assert (code != CONSTRUCTOR && code != TREE_BINFO);
LTO_NO_PREVAIL (TREE_TYPE (t));
if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
LTO_NO_PREVAIL (TREE_CHAIN (t));
@@ -3211,7 +3210,7 @@ lto_fixup_prevailing_decls (tree t)
LTO_SET_PREVAIL (DECL_FUNCTION_PERSONALITY (t));
if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
{
- LTO_NO_PREVAIL (DECL_FIELD_OFFSET (t));
+ LTO_SET_PREVAIL (DECL_FIELD_OFFSET (t));
LTO_NO_PREVAIL (DECL_BIT_FIELD_TYPE (t));
LTO_NO_PREVAIL (DECL_QUALIFIER (t));
LTO_NO_PREVAIL (DECL_FIELD_BIT_OFFSET (t));
@@ -3228,7 +3227,7 @@ lto_fixup_prevailing_decls (tree t)
LTO_SET_PREVAIL (TYPE_MINVAL (t));
LTO_SET_PREVAIL (TYPE_MAXVAL (t));
- LTO_SET_PREVAIL (t->type_non_common.binfo);
+ LTO_NO_PREVAIL (t->type_non_common.binfo);
LTO_SET_PREVAIL (TYPE_CONTEXT (t));
@@ -3249,11 +3248,15 @@ lto_fixup_prevailing_decls (tree t)
case TREE_LIST:
LTO_SET_PREVAIL (TREE_VALUE (t));
LTO_SET_PREVAIL (TREE_PURPOSE (t));
+ LTO_NO_PREVAIL (TREE_PURPOSE (t));
break;
default:
gcc_unreachable ();
}
}
+ /* If we fixed nothing, then we missed something seen by
+ mentions_vars_p. */
+ gcc_checking_assert (fixed);
}
#undef LTO_SET_PREVAIL
#undef LTO_NO_PREVAIL
@@ -3276,7 +3279,8 @@ lto_fixup_state (struct lto_in_decl_state *state)
for (i = 0; i < table->size; i++)
{
tree *tp = table->trees + i;
- if (VAR_OR_FUNCTION_DECL_P (*tp))
+ if (VAR_OR_FUNCTION_DECL_P (*tp)
+ && (TREE_PUBLIC (*tp) || DECL_EXTERNAL (*tp)))
*tp = lto_symtab_prevailing_decl (*tp);
}
}
@@ -3300,11 +3304,11 @@ static void
lto_fixup_decls (struct lto_file_decl_data **files)
{
unsigned int i;
- htab_iterator hi;
tree t;
- FOR_EACH_HTAB_ELEMENT (tree_with_vars, t, tree, hi)
- lto_fixup_prevailing_decls (t);
+ if (tree_with_vars)
+ FOR_EACH_VEC_ELT ((*tree_with_vars), i, t)
+ lto_fixup_prevailing_decls (t);
for (i = 0; files[i]; i++)
{
@@ -3394,8 +3398,6 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
}
cgraph_state = CGRAPH_LTO_STREAMING;
- tree_with_vars = htab_create_ggc (101, htab_hash_pointer, htab_eq_pointer,
- NULL);
type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
tree_int_map_eq, NULL);
type_pair_cache = XCNEWVEC (struct type_pair_d, GIMPLE_TYPE_PAIR_SIZE);
@@ -3511,7 +3513,8 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
/* Fixup all decls. */
lto_fixup_decls (all_file_decl_data);
}
- htab_delete (tree_with_vars);
+ if (tree_with_vars)
+ ggc_free (tree_with_vars);
tree_with_vars = NULL;
ggc_collect ();
@@ -3532,6 +3535,9 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
gcc_assert (all_file_decl_data[i]->symtab_node_encoder);
lto_symtab_encoder_delete (all_file_decl_data[i]->symtab_node_encoder);
all_file_decl_data[i]->symtab_node_encoder = NULL;
+ lto_free_function_in_decl_state (all_file_decl_data[i]->global_decl_state);
+ all_file_decl_data[i]->global_decl_state = NULL;
+ all_file_decl_data[i]->current_decl_state = NULL;
}
/* Finally merge the cgraph according to the decl merging decisions. */
@@ -3694,7 +3700,7 @@ do_whole_program_analysis (void)
bitmap_obstack_initialize (NULL);
cgraph_state = CGRAPH_STATE_IPA_SSA;
- execute_ipa_pass_list (all_regular_ipa_passes);
+ execute_ipa_pass_list (g->get_passes ()->all_regular_ipa_passes);
symtab_remove_unreachable_nodes (false, dump_file);
if (cgraph_dump_file)
diff --git a/gcc/lto/lto.h b/gcc/lto/lto.h
index 2699459dc18..1734fe5def1 100644
--- a/gcc/lto/lto.h
+++ b/gcc/lto/lto.h
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#define LTO_H
#include "hashtab.h"
+#include "vec.h"
/* A file. */
typedef struct lto_file_struct
@@ -40,6 +41,9 @@ extern tree lto_eh_personality (void);
extern void lto_main (void);
extern void lto_read_all_file_options (void);
+/* In lto-symtab.c */
+extern GTY(()) vec<tree, va_gc> *lto_global_var_decls;
+
/* In lto-elf.c or lto-coff.c */
extern lto_file *lto_obj_file_open (const char *filename, bool writable);
extern void lto_obj_file_close (lto_file *file);
diff --git a/gcc/melt-run.proto.h b/gcc/melt-run.proto.h
index 032a85b028e..e5491100200 100644
--- a/gcc/melt-run.proto.h
+++ b/gcc/melt-run.proto.h
@@ -69,6 +69,11 @@ along with GCC; see the file COPYING3. If not see
#include "c-family/c-pretty-print.h"
#include "diagnostic.h"
+
+#if MELT_GCC_VERSION >= 4009
+#include "context.h"
+#endif /* GCC 4.9 */
+
#include "flags.h"
#include "toplev.h"
#include "options.h"
diff --git a/gcc/melt/xtramelt-ana-base.melt b/gcc/melt/xtramelt-ana-base.melt
index c3d921671cd..e1347735d2f 100644
--- a/gcc/melt/xtramelt-ana-base.melt
+++ b/gcc/melt/xtramelt-ana-base.melt
@@ -55,6 +55,19 @@ MELT_EXTERN bool melthk_simple_ipa_gate(void) MELT_MODULE_VISIBILITY;
MELT_EXTERN unsigned int melthk_simple_ipa_execute(void) MELT_MODULE_VISIBILITY;
MELT_EXTERN bool melthk_rtl_gate(void) MELT_MODULE_VISIBILITY;
MELT_EXTERN unsigned int melthk_rtl_execute(void) MELT_MODULE_VISIBILITY;
+
+#if GCCPLUGIN_VERSION >= 4009 || MELT_GCC_VERSION >= 4009 /* GCC 4.9 and later have classes for passes */
+class melt_gimple_pass : public gimple_opt_pass {
+public:
+ melt_gimple_pass (const pass_data& passdata, gcc::context*ctxt)
+ : gimple_opt_pass (passdata, ctxt) {};
+
+ bool gate () { return melthk_gimple_gate(); };
+ unsigned execute () { return melthk_gimple_execute(); };
+ opt_pass* clone () { return new melt_gimple_pass(*this); };
+}; // end of melt_gimple_pass
+#endif /* GCC 4.9 or newer */
+
}#)
(cimplement
@@ -159,6 +172,7 @@ unsigned int melthk_rtl_execute(void)
(code_chunk
gimplepass_chk
#{ /* start install_melt_gcc_pass $GIMPLEPASS_CHK */
+#if GCCPLUGIN_VERSION <= 4008 && MELT_GCC_VERSION <= 4008 /* GCC 4.7 or 4.8 */
struct gimple_opt_pass* gimpass = NULL;
struct register_pass_info rpassinfo;
memset (&rpassinfo, 0, sizeof(rpassinfo));
@@ -177,11 +191,40 @@ unsigned int melthk_rtl_execute(void)
gimpass->pass.todo_flags_finish = melt_val2passflag ((melt_ptr_t) $TODOFINISHV);
rpassinfo.pass = (struct opt_pass*) gimpass;
rpassinfo.reference_pass_name =
+ melt_intern_cstring (melt_string_str((melt_ptr_t) $REFPASSNAME));
+ rpassinfo.ref_pass_instance_number = $REFPASSNUM;
+ rpassinfo.pos_op = (enum pass_positioning_ops)$POSOPL;
+ register_callback (melt_plugin_name, PLUGIN_PASS_MANAGER_SETUP,
+ NULL, &rpassinfo);
+#else /* GCC 4.9 or newer has C++ passes */
+ struct register_pass_info rpassinfo;
+ memset (&rpassinfo, 0, sizeof(rpassinfo));
+ struct pass_data rpassdata;
+ memset (&rpassdata, 0, sizeof(rpassdata));
+ rpassdata.type = GIMPLE_PASS;
+ rpassdata.name = melt_intern_cstring (melt_string_str((melt_ptr_t) $PASSNAME));
+ rpassdata.optinfo_flags = OPTGROUP_NONE;
+ rpassdata.has_gate = ($GATEFUN != NULL);
+ rpassdata.has_execute = true;
+ rpassdata.tv_id = TV_PLUGIN_RUN;
+ rpassdata.properties_required = melt_val2passflag ((melt_ptr_t) $PROPREQV);
+ rpassdata.properties_provided = melt_val2passflag ((melt_ptr_t) $PROPPROV);
+ rpassdata.properties_destroyed = melt_val2passflag ((melt_ptr_t) $PROPDESTRV);
+ rpassdata.todo_flags_start = melt_val2passflag ((melt_ptr_t) $TODOSTARTV);
+ rpassdata.todo_flags_finish = melt_val2passflag ((melt_ptr_t) $TODOFINISHV);
+ rpassinfo.pass = new melt_gimple_pass (rpassdata, g); // the g is from context.h
+ rpassinfo.reference_pass_name =
+ melt_intern_cstring (melt_string_str((melt_ptr_t) $REFPASSNAME));
melt_intern_cstring (melt_string_str((melt_ptr_t) $REFPASSNAME));
rpassinfo.ref_pass_instance_number = $REFPASSNUM;
rpassinfo.pos_op = (enum pass_positioning_ops)$POSOPL;
register_callback (melt_plugin_name, PLUGIN_PASS_MANAGER_SETUP,
NULL, &rpassinfo);
+ rpassinfo.ref_pass_instance_number = $REFPASSNUM;
+ rpassinfo.pos_op = (enum pass_positioning_ops)$POSOPL;
+ register_callback (melt_plugin_name, PLUGIN_PASS_MANAGER_SETUP,
+ NULL, &rpassinfo);
+#endif /* GCC 4.9 */
/* end install_melt_gcc_pass $GIMPLEPASS_CHK */
}#)
(mapstring_putstr passdict passname pass)
@@ -192,6 +235,7 @@ unsigned int melthk_rtl_execute(void)
(code_chunk
simipapass_chk
#{ /* start install_melt_gcc_pass $SIMIPAPASS_CHK */
+#if GCCPLUGIN_VERSION <= 4008 && MELT_GCC_VERSION <= 4008 /* GCC 4.7 or 4.8 */
struct simple_ipa_opt_pass* simipass = NULL;
struct register_pass_info rpassinfo;
memset (&rpassinfo, 0, sizeof(rpassinfo));
@@ -215,6 +259,11 @@ unsigned int melthk_rtl_execute(void)
rpassinfo.pos_op = (enum pass_positioning_ops)$POSOPL;
register_callback (melt_plugin_name, PLUGIN_PASS_MANAGER_SETUP,
NULL, &rpassinfo);
+#else /* GCC >= 4.9 */
+#warning install_melt_gcc_pass $SIMIPAPASS_CHK not implemented for class_gcc_simple_ipa_pass
+ melt_fatal_error ("install_melt_gcc_pass unimplemented for MELT pass %s (simple_ipa)",
+ melt_string_str((melt_ptr_t) $PASSNAME));
+#endif /* GCC 4.9 or better */
/* end install_melt_gcc_pass $SIMIPAPASS_CHK */
}#)
(debug "install_melt_pass_in_gcc installed simple ipa pass=" pass)
@@ -225,6 +274,7 @@ unsigned int melthk_rtl_execute(void)
(code_chunk
rtlpass_chk
#{ /* start install_melt_gcc_pass $RTLPASS_CHK */
+#if GCCPLUGIN_VERSION <= 4008 && MELT_GCC_VERSION <= 4008 /* GCC 4.7 or 4.8 */
struct rtl_opt_pass* rtlpass = NULL;
struct register_pass_info rpassinfo;
memset (&rpassinfo, 0, sizeof(rpassinfo));
@@ -248,6 +298,11 @@ unsigned int melthk_rtl_execute(void)
rpassinfo.pos_op = (enum pass_positioning_ops)$POSOPL;
register_callback (melt_plugin_name, PLUGIN_PASS_MANAGER_SETUP,
NULL, &rpassinfo);
+#else /* GCC >= 4.9 */
+#warning install_melt_gcc_pass $RTLPASS_CHK not implemented for class_gcc_rtl_pass
+ melt_fatal_error ("install_melt_gcc_pass unimplemented for MELT pass %s (RTL)",
+ melt_string_str((melt_ptr_t) $PASSNAME));
+#endif /* GCC 4.9 or better */
/* end install_melt_gcc_pass $RTLPASS_CHK */
}#)
(debug "install_melt_pass_in_gcc installed simple ipa pass=" pass)
diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index 8ea8ca35d3c..56c4d0fef9a 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -420,7 +420,7 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
|| (GET_MODE_CLASS (GET_MODE (ret_reg)) != MODE_INT
&& nregs != 1));
- if (INSN_P (last_insn))
+ if (!NOTE_INSN_BASIC_BLOCK_P (last_insn))
{
before_return_copy
= emit_note_before (NOTE_INSN_DELETED, last_insn);
@@ -428,9 +428,8 @@ create_pre_exit (int n_entities, int *entity_map, const int *num_modes)
require a different mode than MODE_EXIT, so if we might
have such instructions, keep them in a separate block
from pre_exit. */
- if (last_insn != BB_HEAD (src_bb))
- src_bb = split_block (src_bb,
- PREV_INSN (before_return_copy))->dest;
+ src_bb = split_block (src_bb,
+ PREV_INSN (before_return_copy))->dest;
}
else
before_return_copy = last_insn;
@@ -785,23 +784,43 @@ rest_of_handle_mode_switching (void)
}
-struct rtl_opt_pass pass_mode_switching =
+namespace {
+
+const pass_data pass_data_mode_switching =
{
- {
- RTL_PASS,
- "mode_sw", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_mode_switching, /* gate */
- rest_of_handle_mode_switching, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_MODE_SWITCH, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "mode_sw", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_MODE_SWITCH, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */
};
+
+class pass_mode_switching : public rtl_opt_pass
+{
+public:
+ pass_mode_switching(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_mode_switching, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ /* The epiphany backend creates a second instance of this pass, so we need
+ a clone method. */
+ opt_pass * clone () { return new pass_mode_switching (ctxt_); }
+ bool gate () { return gate_mode_switching (); }
+ unsigned int execute () { return rest_of_handle_mode_switching (); }
+
+}; // class pass_mode_switching
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_mode_switching (gcc::context *ctxt)
+{
+ return new pass_mode_switching (ctxt);
+}
diff --git a/gcc/modulo-sched.c b/gcc/modulo-sched.c
index 1e9b16c6fcb..0df5fb61a25 100644
--- a/gcc/modulo-sched.c
+++ b/gcc/modulo-sched.c
@@ -3351,24 +3351,41 @@ rest_of_handle_sms (void)
return 0;
}
-struct rtl_opt_pass pass_sms =
-{
- {
- RTL_PASS,
- "sms", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_sms, /* gate */
- rest_of_handle_sms, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_SMS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish
- | TODO_verify_flow
- | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_sms =
+{
+ RTL_PASS, /* type */
+ "sms", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_SMS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_flow
+ | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_sms : public rtl_opt_pass
+{
+public:
+ pass_sms(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_sms, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_sms (); }
+ unsigned int execute () { return rest_of_handle_sms (); }
+
+}; // class pass_sms
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_sms (gcc::context *ctxt)
+{
+ return new pass_sms (ctxt);
+}
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index e07c21a4e6c..6da219e6869 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3. If not see
#include "splay-tree.h"
#include "optabs.h"
#include "cfgloop.h"
+#include "target.h"
/* Lowering of OpenMP parallel and workshare constructs proceeds in two
@@ -222,6 +223,7 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
int i;
struct omp_for_data_loop dummy_loop;
location_t loc = gimple_location (for_stmt);
+ bool simd = gimple_omp_for_kind (for_stmt) == GF_OMP_FOR_KIND_SIMD;
fd->for_stmt = for_stmt;
fd->pre = NULL;
@@ -349,7 +351,18 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
gcc_unreachable ();
}
- if (iter_type != long_long_unsigned_type_node)
+ if (simd)
+ {
+ if (fd->collapse == 1)
+ iter_type = TREE_TYPE (loop->v);
+ else if (i == 0
+ || TYPE_PRECISION (iter_type)
+ < TYPE_PRECISION (TREE_TYPE (loop->v)))
+ iter_type
+ = build_nonstandard_integer_type
+ (TYPE_PRECISION (TREE_TYPE (loop->v)), 1);
+ }
+ else if (iter_type != long_long_unsigned_type_node)
{
if (POINTER_TYPE_P (TREE_TYPE (loop->v)))
iter_type = long_long_unsigned_type_node;
@@ -445,7 +458,8 @@ extract_omp_for_data (gimple for_stmt, struct omp_for_data *fd,
}
}
- if (count)
+ if (count
+ && !simd)
{
if (!tree_int_cst_lt (count, TYPE_MAX_VALUE (long_integer_type_node)))
iter_type = long_long_unsigned_type_node;
@@ -836,6 +850,7 @@ copy_var_decl (tree var, tree name, tree type)
DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (var);
DECL_IGNORED_P (copy) = DECL_IGNORED_P (var);
DECL_CONTEXT (copy) = DECL_CONTEXT (var);
+ TREE_NO_WARNING (copy) = TREE_NO_WARNING (var);
TREE_USED (copy) = 1;
DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
@@ -918,6 +933,19 @@ build_outer_var_ref (tree var, omp_context *ctx)
bool by_ref = use_pointer_for_field (var, NULL);
x = build_receiver_ref (var, by_ref, ctx);
}
+ else if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ {
+ /* #pragma omp simd isn't a worksharing construct, and can reference even
+ private vars in its linear etc. clauses. */
+ x = NULL_TREE;
+ if (ctx->outer && is_taskreg_ctx (ctx))
+ x = lookup_decl (var, ctx->outer);
+ else if (ctx->outer)
+ x = maybe_lookup_decl (var, ctx->outer);
+ if (x == NULL_TREE)
+ x = var;
+ }
else if (ctx->outer)
x = lookup_decl (var, ctx->outer);
else if (is_reference (var))
@@ -1423,6 +1451,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_LINEAR:
decl = OMP_CLAUSE_DECL (c);
do_private:
if (is_variable_sized (decl))
@@ -1474,6 +1503,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_COLLAPSE:
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
default:
@@ -1497,6 +1527,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_REDUCTION:
+ case OMP_CLAUSE_LINEAR:
decl = OMP_CLAUSE_DECL (c);
if (is_variable_sized (decl))
install_var_local (decl, ctx);
@@ -1526,6 +1557,7 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
case OMP_CLAUSE_UNTIED:
case OMP_CLAUSE_FINAL:
case OMP_CLAUSE_MERGEABLE:
+ case OMP_CLAUSE_SAFELEN:
break;
default:
@@ -1631,7 +1663,6 @@ create_omp_child_function (omp_context *ctx, bool task_copy)
pop_cfun ();
}
-
/* Scan an OpenMP parallel directive. */
static void
@@ -1831,9 +1862,22 @@ scan_omp_single (gimple stmt, omp_context *outer_ctx)
static bool
check_omp_nesting_restrictions (gimple stmt, omp_context *ctx)
{
+ if (ctx != NULL)
+ {
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ {
+ error_at (gimple_location (stmt),
+ "OpenMP constructs may not be nested inside simd region");
+ return false;
+ }
+ }
switch (gimple_code (stmt))
{
case GIMPLE_OMP_FOR:
+ if (gimple_omp_for_kind (stmt) == GF_OMP_FOR_KIND_SIMD)
+ return true;
+ /* FALLTHRU */
case GIMPLE_OMP_SECTIONS:
case GIMPLE_OMP_SINGLE:
case GIMPLE_CALL:
@@ -2254,6 +2298,73 @@ omp_reduction_init (tree clause, tree type)
}
}
+/* Return maximum possible vectorization factor for the target. */
+
+static int
+omp_max_vf (void)
+{
+ if (!optimize
+ || optimize_debug
+ || (!flag_tree_vectorize
+ && global_options_set.x_flag_tree_vectorize))
+ return 1;
+
+ int vs = targetm.vectorize.autovectorize_vector_sizes ();
+ if (vs)
+ {
+ vs = 1 << floor_log2 (vs);
+ return vs;
+ }
+ enum machine_mode vqimode = targetm.vectorize.preferred_simd_mode (QImode);
+ if (GET_MODE_CLASS (vqimode) == MODE_VECTOR_INT)
+ return GET_MODE_NUNITS (vqimode);
+ return 1;
+}
+
+/* Helper function of lower_rec_input_clauses, used for #pragma omp simd
+ privatization. */
+
+static bool
+lower_rec_simd_input_clauses (tree new_var, omp_context *ctx, int &max_vf,
+ tree &idx, tree &lane, tree &ivar, tree &lvar)
+{
+ if (max_vf == 0)
+ {
+ max_vf = omp_max_vf ();
+ if (max_vf > 1)
+ {
+ tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
+ OMP_CLAUSE_SAFELEN);
+ if (c
+ && compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c), max_vf) == -1)
+ max_vf = tree_low_cst (OMP_CLAUSE_SAFELEN_EXPR (c), 0);
+ }
+ if (max_vf > 1)
+ {
+ idx = create_tmp_var (unsigned_type_node, NULL);
+ lane = create_tmp_var (unsigned_type_node, NULL);
+ }
+ }
+ if (max_vf == 1)
+ return false;
+
+ tree atype = build_array_type_nelts (TREE_TYPE (new_var), max_vf);
+ tree avar = create_tmp_var_raw (atype, NULL);
+ if (TREE_ADDRESSABLE (new_var))
+ TREE_ADDRESSABLE (avar) = 1;
+ DECL_ATTRIBUTES (avar)
+ = tree_cons (get_identifier ("omp simd array"), NULL,
+ DECL_ATTRIBUTES (avar));
+ gimple_add_tmp_var (avar);
+ ivar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, idx,
+ NULL_TREE, NULL_TREE);
+ lvar = build4 (ARRAY_REF, TREE_TYPE (new_var), avar, lane,
+ NULL_TREE, NULL_TREE);
+ SET_DECL_VALUE_EXPR (new_var, lvar);
+ DECL_HAS_VALUE_EXPR_P (new_var) = 1;
+ return true;
+}
+
/* Generate code to implement the input clauses, FIRSTPRIVATE and COPYIN,
from the receiver (aka child) side and initializers for REFERENCE_TYPE
private variables. Initialization statements go in ILIST, while calls
@@ -2267,9 +2378,38 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
bool copyin_by_ref = false;
bool lastprivate_firstprivate = false;
int pass;
+ bool is_simd = (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD);
+ int max_vf = 0;
+ tree lane = NULL_TREE, idx = NULL_TREE;
+ tree ivar = NULL_TREE, lvar = NULL_TREE;
+ gimple_seq llist[2] = { NULL, NULL };
copyin_seq = NULL;
+ /* Set max_vf=1 (which will later enforce safelen=1) in simd loops
+ with data sharing clauses referencing variable sized vars. That
+ is unnecessarily hard to support and very unlikely to result in
+ vectorized code anyway. */
+ if (is_simd)
+ for (c = clauses; c ; c = OMP_CLAUSE_CHAIN (c))
+ switch (OMP_CLAUSE_CODE (c))
+ {
+ case OMP_CLAUSE_REDUCTION:
+ if (OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
+ max_vf = 1;
+ /* FALLTHRU */
+ case OMP_CLAUSE_PRIVATE:
+ case OMP_CLAUSE_FIRSTPRIVATE:
+ case OMP_CLAUSE_LASTPRIVATE:
+ case OMP_CLAUSE_LINEAR:
+ if (is_variable_sized (OMP_CLAUSE_DECL (c)))
+ max_vf = 1;
+ break;
+ default:
+ continue;
+ }
+
/* Do all the fixed sized types in the first pass, and the variable sized
types in the second pass. This makes sure that the scalar arguments to
the variable sized types are processed before we use them in the
@@ -2299,6 +2439,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
case OMP_CLAUSE_COPYIN:
case OMP_CLAUSE_REDUCTION:
break;
+ case OMP_CLAUSE_LINEAR:
+ break;
case OMP_CLAUSE_LASTPRIVATE:
if (OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE (c))
{
@@ -2443,7 +2585,36 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
else
x = NULL;
+ do_private:
x = lang_hooks.decls.omp_clause_default_ctor (c, new_var, x);
+ if (is_simd)
+ {
+ tree y = lang_hooks.decls.omp_clause_dtor (c, new_var);
+ if ((TREE_ADDRESSABLE (new_var) || x || y
+ || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+ && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
+ idx, lane, ivar, lvar))
+ {
+ if (x)
+ x = lang_hooks.decls.omp_clause_default_ctor
+ (c, unshare_expr (ivar), x);
+ if (x)
+ gimplify_and_add (x, &llist[0]);
+ if (y)
+ {
+ y = lang_hooks.decls.omp_clause_dtor (c, ivar);
+ if (y)
+ {
+ gimple_seq tseq = NULL;
+
+ dtor = y;
+ gimplify_stmt (&dtor, &tseq);
+ gimple_seq_add_seq (&llist[1], tseq);
+ }
+ }
+ break;
+ }
+ }
if (x)
gimplify_and_add (x, ilist);
/* FALLTHRU */
@@ -2460,6 +2631,15 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
break;
+ case OMP_CLAUSE_LINEAR:
+ if (!OMP_CLAUSE_LINEAR_NO_COPYIN (c))
+ goto do_firstprivate;
+ if (OMP_CLAUSE_LINEAR_NO_COPYOUT (c))
+ x = NULL;
+ else
+ x = build_outer_var_ref (var, ctx);
+ goto do_private;
+
case OMP_CLAUSE_FIRSTPRIVATE:
if (is_task_ctx (ctx))
{
@@ -2475,11 +2655,56 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
goto do_dtor;
}
}
+ do_firstprivate:
x = build_outer_var_ref (var, ctx);
+ if (is_simd)
+ {
+ if ((OMP_CLAUSE_CODE (c) != OMP_CLAUSE_LINEAR
+ || TREE_ADDRESSABLE (new_var))
+ && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
+ idx, lane, ivar, lvar))
+ {
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR)
+ {
+ tree iv = create_tmp_var (TREE_TYPE (new_var), NULL);
+ x = lang_hooks.decls.omp_clause_copy_ctor (c, iv, x);
+ gimplify_and_add (x, ilist);
+ gimple_stmt_iterator gsi
+ = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
+ gimple g
+ = gimple_build_assign (unshare_expr (lvar), iv);
+ gsi_insert_before_without_update (&gsi, g,
+ GSI_SAME_STMT);
+ tree stept = POINTER_TYPE_P (TREE_TYPE (x))
+ ? sizetype : TREE_TYPE (x);
+ tree t = fold_convert (stept,
+ OMP_CLAUSE_LINEAR_STEP (c));
+ enum tree_code code = PLUS_EXPR;
+ if (POINTER_TYPE_P (TREE_TYPE (new_var)))
+ code = POINTER_PLUS_EXPR;
+ g = gimple_build_assign_with_ops (code, iv, iv, t);
+ gsi_insert_before_without_update (&gsi, g,
+ GSI_SAME_STMT);
+ break;
+ }
+ x = lang_hooks.decls.omp_clause_copy_ctor
+ (c, unshare_expr (ivar), x);
+ gimplify_and_add (x, &llist[0]);
+ x = lang_hooks.decls.omp_clause_dtor (c, ivar);
+ if (x)
+ {
+ gimple_seq tseq = NULL;
+
+ dtor = x;
+ gimplify_stmt (&dtor, &tseq);
+ gimple_seq_add_seq (&llist[1], tseq);
+ }
+ break;
+ }
+ }
x = lang_hooks.decls.omp_clause_copy_ctor (c, new_var, x);
gimplify_and_add (x, ilist);
goto do_dtor;
- break;
case OMP_CLAUSE_COPYIN:
by_ref = use_pointer_for_field (var, NULL);
@@ -2495,6 +2720,8 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
tree placeholder = OMP_CLAUSE_REDUCTION_PLACEHOLDER (c);
x = build_outer_var_ref (var, ctx);
+ /* FIXME: Not handled yet. */
+ gcc_assert (!is_simd);
if (is_reference (var))
x = build_fold_addr_expr_loc (clause_loc, x);
SET_DECL_VALUE_EXPR (placeholder, x);
@@ -2509,7 +2736,31 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
{
x = omp_reduction_init (c, TREE_TYPE (new_var));
gcc_assert (TREE_CODE (TREE_TYPE (new_var)) != ARRAY_TYPE);
- gimplify_assign (new_var, x, ilist);
+ if (is_simd
+ && lower_rec_simd_input_clauses (new_var, ctx, max_vf,
+ idx, lane, ivar, lvar))
+ {
+ enum tree_code code = OMP_CLAUSE_REDUCTION_CODE (c);
+ tree ref = build_outer_var_ref (var, ctx);
+
+ gimplify_assign (unshare_expr (ivar), x, &llist[0]);
+
+ /* reduction(-:var) sums up the partial results, so it
+ acts identically to reduction(+:var). */
+ if (code == MINUS_EXPR)
+ code = PLUS_EXPR;
+
+ x = build2 (code, TREE_TYPE (ref), ref, ivar);
+ ref = build_outer_var_ref (var, ctx);
+ gimplify_assign (ref, x, &llist[1]);
+ }
+ else
+ {
+ gimplify_assign (new_var, x, ilist);
+ if (is_simd)
+ gimplify_assign (build_outer_var_ref (var, ctx),
+ new_var, dlist);
+ }
}
break;
@@ -2519,6 +2770,49 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
}
}
+ if (lane)
+ {
+ tree uid = create_tmp_var (ptr_type_node, "simduid");
+ gimple g
+ = gimple_build_call_internal (IFN_GOMP_SIMD_LANE, 1, uid);
+ gimple_call_set_lhs (g, lane);
+ gimple_stmt_iterator gsi = gsi_start_1 (gimple_omp_body_ptr (ctx->stmt));
+ gsi_insert_before_without_update (&gsi, g, GSI_SAME_STMT);
+ c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE__SIMDUID_);
+ OMP_CLAUSE__SIMDUID__DECL (c) = uid;
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
+ gimple_omp_for_set_clauses (ctx->stmt, c);
+ g = gimple_build_assign_with_ops (INTEGER_CST, lane,
+ build_int_cst (unsigned_type_node, 0),
+ NULL_TREE);
+ gimple_seq_add_stmt (ilist, g);
+ for (int i = 0; i < 2; i++)
+ if (llist[i])
+ {
+ tree vf = create_tmp_var (unsigned_type_node, NULL);
+ g = gimple_build_call_internal (IFN_GOMP_SIMD_VF, 1, uid);
+ gimple_call_set_lhs (g, vf);
+ gimple_seq *seq = i == 0 ? ilist : dlist;
+ gimple_seq_add_stmt (seq, g);
+ tree t = build_int_cst (unsigned_type_node, 0);
+ g = gimple_build_assign_with_ops (INTEGER_CST, idx, t, NULL_TREE);
+ gimple_seq_add_stmt (seq, g);
+ tree body = create_artificial_label (UNKNOWN_LOCATION);
+ tree header = create_artificial_label (UNKNOWN_LOCATION);
+ tree end = create_artificial_label (UNKNOWN_LOCATION);
+ gimple_seq_add_stmt (seq, gimple_build_goto (header));
+ gimple_seq_add_stmt (seq, gimple_build_label (body));
+ gimple_seq_add_seq (seq, llist[i]);
+ t = build_int_cst (unsigned_type_node, 1);
+ g = gimple_build_assign_with_ops (PLUS_EXPR, idx, idx, t);
+ gimple_seq_add_stmt (seq, g);
+ gimple_seq_add_stmt (seq, gimple_build_label (header));
+ g = gimple_build_cond (LT_EXPR, idx, vf, body, end);
+ gimple_seq_add_stmt (seq, g);
+ gimple_seq_add_stmt (seq, gimple_build_label (end));
+ }
+ }
+
/* The copyin sequence is not to be executed by the main thread, since
that would result in self-copies. Perhaps not visible to scalars,
but it certainly is to C++ operator=. */
@@ -2538,7 +2832,31 @@ lower_rec_input_clauses (tree clauses, gimple_seq *ilist, gimple_seq *dlist,
lastprivate clauses we need to ensure the lastprivate copying
happens after firstprivate copying in all threads. */
if (copyin_by_ref || lastprivate_firstprivate)
- gimplify_and_add (build_omp_barrier (), ilist);
+ {
+ /* Don't add any barrier for #pragma omp simd or
+ #pragma omp distribute. */
+ if (gimple_code (ctx->stmt) != GIMPLE_OMP_FOR
+ || gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_FOR)
+ gimplify_and_add (build_omp_barrier (), ilist);
+ }
+
+ /* If max_vf is non-zero, then we can use only a vectorization factor
+ up to the max_vf we chose. So stick it into the safelen clause. */
+ if (max_vf)
+ {
+ tree c = find_omp_clause (gimple_omp_for_clauses (ctx->stmt),
+ OMP_CLAUSE_SAFELEN);
+ if (c == NULL_TREE
+ || compare_tree_int (OMP_CLAUSE_SAFELEN_EXPR (c),
+ max_vf) == 1)
+ {
+ c = build_omp_clause (UNKNOWN_LOCATION, OMP_CLAUSE_SAFELEN);
+ OMP_CLAUSE_SAFELEN_EXPR (c) = build_int_cst (integer_type_node,
+ max_vf);
+ OMP_CLAUSE_CHAIN (c) = gimple_omp_for_clauses (ctx->stmt);
+ gimple_omp_for_set_clauses (ctx->stmt, c);
+ }
+ }
}
@@ -2550,11 +2868,16 @@ static void
lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
omp_context *ctx)
{
- tree x, c, label = NULL;
+ tree x, c, label = NULL, orig_clauses = clauses;
bool par_clauses = false;
+ tree simduid = NULL, lastlane = NULL;
- /* Early exit if there are no lastprivate clauses. */
- clauses = find_omp_clause (clauses, OMP_CLAUSE_LASTPRIVATE);
+ /* Early exit if there are no lastprivate or linear clauses. */
+ for (; clauses ; clauses = OMP_CLAUSE_CHAIN (clauses))
+ if (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LASTPRIVATE
+ || (OMP_CLAUSE_CODE (clauses) == OMP_CLAUSE_LINEAR
+ && !OMP_CLAUSE_LINEAR_NO_COPYOUT (clauses)))
+ break;
if (clauses == NULL)
{
/* If this was a workshare clause, see if it had been combined
@@ -2591,23 +2914,59 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
gimple_seq_add_stmt (stmt_list, gimple_build_label (label_true));
}
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ {
+ simduid = find_omp_clause (orig_clauses, OMP_CLAUSE__SIMDUID_);
+ if (simduid)
+ simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
+ }
+
for (c = clauses; c ;)
{
tree var, new_var;
location_t clause_loc = OMP_CLAUSE_LOCATION (c);
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)))
{
var = OMP_CLAUSE_DECL (c);
new_var = lookup_decl (var, ctx);
- if (OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
+ if (simduid && DECL_HAS_VALUE_EXPR_P (new_var))
+ {
+ tree val = DECL_VALUE_EXPR (new_var);
+ if (TREE_CODE (val) == ARRAY_REF
+ && VAR_P (TREE_OPERAND (val, 0))
+ && lookup_attribute ("omp simd array",
+ DECL_ATTRIBUTES (TREE_OPERAND (val,
+ 0))))
+ {
+ if (lastlane == NULL)
+ {
+ lastlane = create_tmp_var (unsigned_type_node, NULL);
+ gimple g
+ = gimple_build_call_internal (IFN_GOMP_SIMD_LAST_LANE,
+ 2, simduid,
+ TREE_OPERAND (val, 1));
+ gimple_call_set_lhs (g, lastlane);
+ gimple_seq_add_stmt (stmt_list, g);
+ }
+ new_var = build4 (ARRAY_REF, TREE_TYPE (val),
+ TREE_OPERAND (val, 0), lastlane,
+ NULL_TREE, NULL_TREE);
+ }
+ }
+
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
{
lower_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
gimple_seq_add_seq (stmt_list,
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
+ OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
}
- OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
x = build_outer_var_ref (var, ctx);
if (is_reference (var))
@@ -2649,6 +3008,11 @@ lower_reduction_clauses (tree clauses, gimple_seq *stmt_seqp, omp_context *ctx)
tree x, c;
int count = 0;
+ /* SIMD reductions are handled in lower_rec_input_clauses. */
+ if (gimple_code (ctx->stmt) == GIMPLE_OMP_FOR
+ && gimple_omp_for_kind (ctx->stmt) == GF_OMP_FOR_KIND_SIMD)
+ return;
+
/* First see if there is exactly one reduction clause. Use OMP_ATOMIC
update in that case, otherwise use a lock. */
for (c = clauses; c && count < 2; c = OMP_CLAUSE_CHAIN (c))
@@ -3411,6 +3775,24 @@ expand_omp_regimplify_p (tree *tp, int *walk_subtrees, void *)
return NULL_TREE;
}
+/* Prepend TO = FROM assignment before *GSI_P. */
+
+static void
+expand_omp_build_assign (gimple_stmt_iterator *gsi_p, tree to, tree from)
+{
+ bool simple_p = DECL_P (to) && TREE_ADDRESSABLE (to);
+ from = force_gimple_operand_gsi (gsi_p, from, simple_p, NULL_TREE,
+ true, GSI_SAME_STMT);
+ gimple stmt = gimple_build_assign (to, from);
+ gsi_insert_before (gsi_p, stmt, GSI_SAME_STMT);
+ if (walk_tree (&from, expand_omp_regimplify_p, NULL, NULL)
+ || walk_tree (&to, expand_omp_regimplify_p, NULL, NULL))
+ {
+ gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &gsi);
+ }
+}
+
/* Expand the OpenMP parallel or task directive starting at REGION. */
static void
@@ -3654,6 +4036,311 @@ expand_omp_taskreg (struct omp_region *region)
}
+/* Helper function for expand_omp_{for_*,simd}. If this is the outermost
+ of the combined collapse > 1 loop constructs, generate code like:
+ if (__builtin_expect (N32 cond3 N31, 0)) goto ZERO_ITER_BB;
+ if (cond3 is <)
+ adj = STEP3 - 1;
+ else
+ adj = STEP3 + 1;
+ count3 = (adj + N32 - N31) / STEP3;
+ if (__builtin_expect (N22 cond2 N21, 0)) goto ZERO_ITER_BB;
+ if (cond2 is <)
+ adj = STEP2 - 1;
+ else
+ adj = STEP2 + 1;
+ count2 = (adj + N22 - N21) / STEP2;
+ if (__builtin_expect (N12 cond1 N11, 0)) goto ZERO_ITER_BB;
+ if (cond1 is <)
+ adj = STEP1 - 1;
+ else
+ adj = STEP1 + 1;
+ count1 = (adj + N12 - N11) / STEP1;
+ count = count1 * count2 * count3;
+ Furthermore, if ZERO_ITER_BB is NULL, create a BB which does:
+ count = 0;
+ and set ZERO_ITER_BB to that bb. */
+
+/* NOTE: It *could* be better to moosh all of the BBs together,
+ creating one larger BB with all the computation and the unexpected
+ jump at the end. I.e.
+
+ bool zero3, zero2, zero1, zero;
+
+ zero3 = N32 c3 N31;
+ count3 = (N32 - N31) /[cl] STEP3;
+ zero2 = N22 c2 N21;
+ count2 = (N22 - N21) /[cl] STEP2;
+ zero1 = N12 c1 N11;
+ count1 = (N12 - N11) /[cl] STEP1;
+ zero = zero3 || zero2 || zero1;
+ count = count1 * count2 * count3;
+ if (__builtin_expect(zero, false)) goto zero_iter_bb;
+
+ After all, we expect the zero=false, and thus we expect to have to
+ evaluate all of the comparison expressions, so short-circuiting
+ oughtn't be a win. Since the condition isn't protecting a
+ denominator, we're not concerned about divide-by-zero, so we can
+ fully evaluate count even if a numerator turned out to be wrong.
+
+ It seems like putting this all together would create much better
+ scheduling opportunities, and less pressure on the chip's branch
+ predictor. */
+
+static void
+expand_omp_for_init_counts (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
+ basic_block &entry_bb, tree *counts,
+ basic_block &zero_iter_bb, int &first_zero_iter,
+ basic_block &l2_dom_bb)
+{
+ tree t, type = TREE_TYPE (fd->loop.v);
+ gimple stmt;
+ edge e, ne;
+ int i;
+
+ /* Collapsed loops need work for expansion into SSA form. */
+ gcc_assert (!gimple_in_ssa_p (cfun));
+
+ for (i = 0; i < fd->collapse; i++)
+ {
+ tree itype = TREE_TYPE (fd->loops[i].v);
+
+ if (SSA_VAR_P (fd->loop.n2)
+ && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
+ fold_convert (itype, fd->loops[i].n1),
+ fold_convert (itype, fd->loops[i].n2)))
+ == NULL_TREE || !integer_onep (t)))
+ {
+ tree n1, n2;
+ n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
+ n1 = force_gimple_operand_gsi (gsi, n1, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
+ n2 = force_gimple_operand_gsi (gsi, n2, true, NULL_TREE,
+ true, GSI_SAME_STMT);
+ stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
+ NULL_TREE, NULL_TREE);
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ if (walk_tree (gimple_cond_lhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt),
+ expand_omp_regimplify_p, NULL, NULL))
+ {
+ *gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, gsi);
+ }
+ e = split_block (entry_bb, stmt);
+ if (zero_iter_bb == NULL)
+ {
+ first_zero_iter = i;
+ zero_iter_bb = create_empty_bb (entry_bb);
+ if (current_loops)
+ add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
+ *gsi = gsi_after_labels (zero_iter_bb);
+ stmt = gimple_build_assign (fd->loop.n2,
+ build_zero_cst (type));
+ gsi_insert_before (gsi, stmt, GSI_SAME_STMT);
+ set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
+ entry_bb);
+ }
+ ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
+ ne->probability = REG_BR_PROB_BASE / 2000 - 1;
+ e->flags = EDGE_TRUE_VALUE;
+ e->probability = REG_BR_PROB_BASE - ne->probability;
+ if (l2_dom_bb == NULL)
+ l2_dom_bb = entry_bb;
+ entry_bb = e->dest;
+ *gsi = gsi_last_bb (entry_bb);
+ }
+
+ if (POINTER_TYPE_P (itype))
+ itype = signed_type_for (itype);
+ t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
+ ? -1 : 1));
+ t = fold_build2 (PLUS_EXPR, itype,
+ fold_convert (itype, fd->loops[i].step), t);
+ t = fold_build2 (PLUS_EXPR, itype, t,
+ fold_convert (itype, fd->loops[i].n2));
+ t = fold_build2 (MINUS_EXPR, itype, t,
+ fold_convert (itype, fd->loops[i].n1));
+ /* ?? We could probably use CEIL_DIV_EXPR instead of
+ TRUNC_DIV_EXPR and adjusting by hand. Unless we can't
+ generate the same code in the end because generically we
+ don't know that the values involved must be negative for
+ GT?? */
+ if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
+ t = fold_build2 (TRUNC_DIV_EXPR, itype,
+ fold_build1 (NEGATE_EXPR, itype, t),
+ fold_build1 (NEGATE_EXPR, itype,
+ fold_convert (itype,
+ fd->loops[i].step)));
+ else
+ t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
+ fold_convert (itype, fd->loops[i].step));
+ t = fold_convert (type, t);
+ if (TREE_CODE (t) == INTEGER_CST)
+ counts[i] = t;
+ else
+ {
+ counts[i] = create_tmp_reg (type, ".count");
+ expand_omp_build_assign (gsi, counts[i], t);
+ }
+ if (SSA_VAR_P (fd->loop.n2))
+ {
+ if (i == 0)
+ t = counts[0];
+ else
+ t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
+ expand_omp_build_assign (gsi, fd->loop.n2, t);
+ }
+ }
+}
+
+
+/* Helper function for expand_omp_{for_*,simd}. Generate code like:
+ T = V;
+ V3 = N31 + (T % count3) * STEP3;
+ T = T / count3;
+ V2 = N21 + (T % count2) * STEP2;
+ T = T / count2;
+ V1 = N11 + T * STEP1;
+ if this loop doesn't have an inner loop construct combined with it. */
+
+static void
+expand_omp_for_init_vars (struct omp_for_data *fd, gimple_stmt_iterator *gsi,
+ tree *counts, tree startvar)
+{
+ int i;
+ tree type = TREE_TYPE (fd->loop.v);
+ tree tem = create_tmp_reg (type, ".tem");
+ gimple stmt = gimple_build_assign (tem, startvar);
+ gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
+
+ for (i = fd->collapse - 1; i >= 0; i--)
+ {
+ tree vtype = TREE_TYPE (fd->loops[i].v), itype, t;
+ itype = vtype;
+ if (POINTER_TYPE_P (vtype))
+ itype = signed_type_for (vtype);
+ if (i != 0)
+ t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
+ else
+ t = tem;
+ t = fold_convert (itype, t);
+ t = fold_build2 (MULT_EXPR, itype, t,
+ fold_convert (itype, fd->loops[i].step));
+ if (POINTER_TYPE_P (vtype))
+ t = fold_build_pointer_plus (fd->loops[i].n1, t);
+ else
+ t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
+ t = force_gimple_operand_gsi (gsi, t,
+ DECL_P (fd->loops[i].v)
+ && TREE_ADDRESSABLE (fd->loops[i].v),
+ NULL_TREE, false,
+ GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i].v, t);
+ gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
+ if (i != 0)
+ {
+ t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
+ t = force_gimple_operand_gsi (gsi, t, false, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (tem, t);
+ gsi_insert_after (gsi, stmt, GSI_CONTINUE_LINKING);
+ }
+ }
+}
+
+
+/* Helper function for expand_omp_for_*. Generate code like:
+ L10:
+ V3 += STEP3;
+ if (V3 cond3 N32) goto BODY_BB; else goto L11;
+ L11:
+ V3 = N31;
+ V2 += STEP2;
+ if (V2 cond2 N22) goto BODY_BB; else goto L12;
+ L12:
+ V2 = N21;
+ V1 += STEP1;
+ goto BODY_BB; */
+
+static basic_block
+extract_omp_for_update_vars (struct omp_for_data *fd, basic_block cont_bb,
+ basic_block body_bb)
+{
+ basic_block last_bb, bb, collapse_bb = NULL;
+ int i;
+ gimple_stmt_iterator gsi;
+ edge e;
+ tree t;
+ gimple stmt;
+
+ last_bb = cont_bb;
+ for (i = fd->collapse - 1; i >= 0; i--)
+ {
+ tree vtype = TREE_TYPE (fd->loops[i].v);
+
+ bb = create_empty_bb (last_bb);
+ if (current_loops)
+ add_bb_to_loop (bb, last_bb->loop_father);
+ gsi = gsi_start_bb (bb);
+
+ if (i < fd->collapse - 1)
+ {
+ e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
+ e->probability = REG_BR_PROB_BASE / 8;
+
+ t = fd->loops[i + 1].n1;
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loops[i + 1].v)
+ && TREE_ADDRESSABLE (fd->loops[i
+ + 1].v),
+ NULL_TREE, false,
+ GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i + 1].v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+ }
+ else
+ collapse_bb = bb;
+
+ set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
+
+ if (POINTER_TYPE_P (vtype))
+ t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
+ else
+ t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v, fd->loops[i].step);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (fd->loops[i].v)
+ && TREE_ADDRESSABLE (fd->loops[i].v),
+ NULL_TREE, false, GSI_CONTINUE_LINKING);
+ stmt = gimple_build_assign (fd->loops[i].v, t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+
+ if (i > 0)
+ {
+ t = fd->loops[i].n2;
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ tree v = fd->loops[i].v;
+ if (DECL_P (v) && TREE_ADDRESSABLE (v))
+ v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ t = fold_build2 (fd->loops[i].cond_code, boolean_type_node, v, t);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+ e = make_edge (bb, body_bb, EDGE_TRUE_VALUE);
+ e->probability = REG_BR_PROB_BASE * 7 / 8;
+ }
+ else
+ make_edge (bb, body_bb, EDGE_FALLTHRU);
+ last_bb = bb;
+ }
+
+ return collapse_bb;
+}
+
+
/* A subroutine of expand_omp_for. Generate code for a parallel
loop with any schedule. Given parameters:
@@ -3816,105 +4503,14 @@ expand_omp_for_generic (struct omp_region *region,
gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
if (fd->collapse > 1)
{
- basic_block zero_iter_bb = NULL;
int first_zero_iter = -1;
+ basic_block zero_iter_bb = NULL, l2_dom_bb = NULL;
- /* collapsed loops need work for expansion in SSA form. */
- gcc_assert (!gimple_in_ssa_p (cfun));
- counts = (tree *) alloca (fd->collapse * sizeof (tree));
- for (i = 0; i < fd->collapse; i++)
- {
- tree itype = TREE_TYPE (fd->loops[i].v);
+ counts = XALLOCAVEC (tree, fd->collapse);
+ expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
+ zero_iter_bb, first_zero_iter,
+ l2_dom_bb);
- if (SSA_VAR_P (fd->loop.n2)
- && ((t = fold_binary (fd->loops[i].cond_code, boolean_type_node,
- fold_convert (itype, fd->loops[i].n1),
- fold_convert (itype, fd->loops[i].n2)))
- == NULL_TREE || !integer_onep (t)))
- {
- tree n1, n2;
- n1 = fold_convert (itype, unshare_expr (fd->loops[i].n1));
- n1 = force_gimple_operand_gsi (&gsi, n1, true, NULL_TREE,
- true, GSI_SAME_STMT);
- n2 = fold_convert (itype, unshare_expr (fd->loops[i].n2));
- n2 = force_gimple_operand_gsi (&gsi, n2, true, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_cond (fd->loops[i].cond_code, n1, n2,
- NULL_TREE, NULL_TREE);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- if (walk_tree (gimple_cond_lhs_ptr (stmt),
- expand_omp_regimplify_p, NULL, NULL)
- || walk_tree (gimple_cond_rhs_ptr (stmt),
- expand_omp_regimplify_p, NULL, NULL))
- {
- gsi = gsi_for_stmt (stmt);
- gimple_regimplify_operands (stmt, &gsi);
- }
- e = split_block (entry_bb, stmt);
- if (zero_iter_bb == NULL)
- {
- first_zero_iter = i;
- zero_iter_bb = create_empty_bb (entry_bb);
- if (current_loops)
- add_bb_to_loop (zero_iter_bb, entry_bb->loop_father);
- gsi = gsi_after_labels (zero_iter_bb);
- stmt = gimple_build_assign (fd->loop.n2,
- build_zero_cst (type));
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- set_immediate_dominator (CDI_DOMINATORS, zero_iter_bb,
- entry_bb);
- }
- ne = make_edge (entry_bb, zero_iter_bb, EDGE_FALSE_VALUE);
- ne->probability = REG_BR_PROB_BASE / 2000 - 1;
- e->flags = EDGE_TRUE_VALUE;
- e->probability = REG_BR_PROB_BASE - ne->probability;
- entry_bb = e->dest;
- gsi = gsi_last_bb (entry_bb);
- }
- if (POINTER_TYPE_P (itype))
- itype = signed_type_for (itype);
- t = build_int_cst (itype, (fd->loops[i].cond_code == LT_EXPR
- ? -1 : 1));
- t = fold_build2 (PLUS_EXPR, itype,
- fold_convert (itype, fd->loops[i].step), t);
- t = fold_build2 (PLUS_EXPR, itype, t,
- fold_convert (itype, fd->loops[i].n2));
- t = fold_build2 (MINUS_EXPR, itype, t,
- fold_convert (itype, fd->loops[i].n1));
- if (TYPE_UNSIGNED (itype) && fd->loops[i].cond_code == GT_EXPR)
- t = fold_build2 (TRUNC_DIV_EXPR, itype,
- fold_build1 (NEGATE_EXPR, itype, t),
- fold_build1 (NEGATE_EXPR, itype,
- fold_convert (itype,
- fd->loops[i].step)));
- else
- t = fold_build2 (TRUNC_DIV_EXPR, itype, t,
- fold_convert (itype, fd->loops[i].step));
- t = fold_convert (type, t);
- if (TREE_CODE (t) == INTEGER_CST)
- counts[i] = t;
- else
- {
- counts[i] = create_tmp_reg (type, ".count");
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- stmt = gimple_build_assign (counts[i], t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- }
- if (SSA_VAR_P (fd->loop.n2))
- {
- if (i == 0)
- t = counts[0];
- else
- {
- t = fold_build2 (MULT_EXPR, type, fd->loop.n2, counts[i]);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- true, GSI_SAME_STMT);
- }
- stmt = gimple_build_assign (fd->loop.n2, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
- }
- }
if (zero_iter_bb)
{
/* Some counts[i] vars might be uninitialized if
@@ -3949,18 +4545,21 @@ expand_omp_for_generic (struct omp_region *region,
t4 = build_fold_addr_expr (iend0);
t3 = build_fold_addr_expr (istart0);
t2 = fold_convert (fd->iter_type, fd->loop.step);
- if (POINTER_TYPE_P (type)
- && TYPE_PRECISION (type) != TYPE_PRECISION (fd->iter_type))
+ t1 = fd->loop.n2;
+ t0 = fd->loop.n1;
+ if (POINTER_TYPE_P (TREE_TYPE (t0))
+ && TYPE_PRECISION (TREE_TYPE (t0))
+ != TYPE_PRECISION (fd->iter_type))
{
/* Avoid casting pointers to integer of a different size. */
tree itype = signed_type_for (type);
- t1 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n2));
- t0 = fold_convert (fd->iter_type, fold_convert (itype, fd->loop.n1));
+ t1 = fold_convert (fd->iter_type, fold_convert (itype, t1));
+ t0 = fold_convert (fd->iter_type, fold_convert (itype, t0));
}
else
{
- t1 = fold_convert (fd->iter_type, fd->loop.n2);
- t0 = fold_convert (fd->iter_type, fd->loop.n1);
+ t1 = fold_convert (fd->iter_type, t1);
+ t0 = fold_convert (fd->iter_type, t0);
}
if (bias)
{
@@ -4015,64 +4614,38 @@ expand_omp_for_generic (struct omp_region *region,
gsi_remove (&gsi, true);
/* Iteration setup for sequential loop goes in L0_BB. */
+ tree startvar = fd->loop.v;
+ tree endvar = NULL_TREE;
+
gsi = gsi_start_bb (l0_bb);
t = istart0;
if (bias)
t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
- if (POINTER_TYPE_P (type))
- t = fold_convert (signed_type_for (type), t);
- t = fold_convert (type, t);
+ if (POINTER_TYPE_P (TREE_TYPE (startvar)))
+ t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
+ t = fold_convert (TREE_TYPE (startvar), t);
t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (fd->loop.v)
- && TREE_ADDRESSABLE (fd->loop.v),
+ DECL_P (startvar)
+ && TREE_ADDRESSABLE (startvar),
NULL_TREE, false, GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (fd->loop.v, t);
+ stmt = gimple_build_assign (startvar, t);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
t = iend0;
if (bias)
t = fold_build2 (MINUS_EXPR, fd->iter_type, t, bias);
- if (POINTER_TYPE_P (type))
- t = fold_convert (signed_type_for (type), t);
- t = fold_convert (type, t);
+ if (POINTER_TYPE_P (TREE_TYPE (startvar)))
+ t = fold_convert (signed_type_for (TREE_TYPE (startvar)), t);
+ t = fold_convert (TREE_TYPE (startvar), t);
iend = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
false, GSI_CONTINUE_LINKING);
- if (fd->collapse > 1)
+ if (endvar)
{
- tree tem = create_tmp_reg (type, ".tem");
- stmt = gimple_build_assign (tem, fd->loop.v);
+ stmt = gimple_build_assign (endvar, iend);
gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- for (i = fd->collapse - 1; i >= 0; i--)
- {
- tree vtype = TREE_TYPE (fd->loops[i].v), itype;
- itype = vtype;
- if (POINTER_TYPE_P (vtype))
- itype = signed_type_for (vtype);
- t = fold_build2 (TRUNC_MOD_EXPR, type, tem, counts[i]);
- t = fold_convert (itype, t);
- t = fold_build2 (MULT_EXPR, itype, t,
- fold_convert (itype, fd->loops[i].step));
- if (POINTER_TYPE_P (vtype))
- t = fold_build_pointer_plus (fd->loops[i].n1, t);
- else
- t = fold_build2 (PLUS_EXPR, itype, fd->loops[i].n1, t);
- t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (fd->loops[i].v)
- && TREE_ADDRESSABLE (fd->loops[i].v),
- NULL_TREE, false,
- GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (fd->loops[i].v, t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- if (i != 0)
- {
- t = fold_build2 (TRUNC_DIV_EXPR, type, tem, counts[i]);
- t = force_gimple_operand_gsi (&gsi, t, false, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (tem, t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- }
- }
}
+ if (fd->collapse > 1)
+ expand_omp_for_init_vars (fd, &gsi, counts, startvar);
if (!broken_loop)
{
@@ -4084,93 +4657,32 @@ expand_omp_for_generic (struct omp_region *region,
vmain = gimple_omp_continue_control_use (stmt);
vback = gimple_omp_continue_control_def (stmt);
- if (POINTER_TYPE_P (type))
- t = fold_build_pointer_plus (vmain, fd->loop.step);
- else
- t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
- t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (vback) && TREE_ADDRESSABLE (vback),
- NULL_TREE, true, GSI_SAME_STMT);
- stmt = gimple_build_assign (vback, t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
-
- t = build2 (fd->loop.cond_code, boolean_type_node,
- DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
- iend);
- stmt = gimple_build_cond_empty (t);
- gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ /* OMP4 placeholder: if (!gimple_omp_for_combined_p (fd->for_stmt)). */
+ if (1)
+ {
+ if (POINTER_TYPE_P (type))
+ t = fold_build_pointer_plus (vmain, fd->loop.step);
+ else
+ t = fold_build2 (PLUS_EXPR, type, vmain, fd->loop.step);
+ t = force_gimple_operand_gsi (&gsi, t,
+ DECL_P (vback)
+ && TREE_ADDRESSABLE (vback),
+ NULL_TREE, true, GSI_SAME_STMT);
+ stmt = gimple_build_assign (vback, t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+
+ t = build2 (fd->loop.cond_code, boolean_type_node,
+ DECL_P (vback) && TREE_ADDRESSABLE (vback) ? t : vback,
+ iend);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_before (&gsi, stmt, GSI_SAME_STMT);
+ }
/* Remove GIMPLE_OMP_CONTINUE. */
gsi_remove (&gsi, true);
if (fd->collapse > 1)
- {
- basic_block last_bb, bb;
-
- last_bb = cont_bb;
- for (i = fd->collapse - 1; i >= 0; i--)
- {
- tree vtype = TREE_TYPE (fd->loops[i].v);
-
- bb = create_empty_bb (last_bb);
- if (current_loops)
- add_bb_to_loop (bb, last_bb->loop_father);
- gsi = gsi_start_bb (bb);
-
- if (i < fd->collapse - 1)
- {
- e = make_edge (last_bb, bb, EDGE_FALSE_VALUE);
- e->probability = REG_BR_PROB_BASE / 8;
-
- t = fd->loops[i + 1].n1;
- t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (fd->loops[i + 1].v)
- && TREE_ADDRESSABLE
- (fd->loops[i + 1].v),
- NULL_TREE, false,
- GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (fd->loops[i + 1].v, t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- }
- else
- collapse_bb = bb;
-
- set_immediate_dominator (CDI_DOMINATORS, bb, last_bb);
-
- if (POINTER_TYPE_P (vtype))
- t = fold_build_pointer_plus (fd->loops[i].v, fd->loops[i].step);
- else
- t = fold_build2 (PLUS_EXPR, vtype, fd->loops[i].v,
- fd->loops[i].step);
- t = force_gimple_operand_gsi (&gsi, t,
- DECL_P (fd->loops[i].v)
- && TREE_ADDRESSABLE (fd->loops[i].v),
- NULL_TREE, false,
- GSI_CONTINUE_LINKING);
- stmt = gimple_build_assign (fd->loops[i].v, t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
-
- if (i > 0)
- {
- t = fd->loops[i].n2;
- t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
- tree v = fd->loops[i].v;
- if (DECL_P (v) && TREE_ADDRESSABLE (v))
- v = force_gimple_operand_gsi (&gsi, v, true, NULL_TREE,
- false, GSI_CONTINUE_LINKING);
- t = fold_build2 (fd->loops[i].cond_code, boolean_type_node,
- v, t);
- stmt = gimple_build_cond_empty (t);
- gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
- e = make_edge (bb, l1_bb, EDGE_TRUE_VALUE);
- e->probability = REG_BR_PROB_BASE * 7 / 8;
- }
- else
- make_edge (bb, l1_bb, EDGE_FALLTHRU);
- last_bb = bb;
- }
- }
+ collapse_bb = extract_omp_for_update_vars (fd, cont_bb, l1_bb);
/* Emit code to get the next parallel iteration in L2_BB. */
gsi = gsi_start_bb (l2_bb);
@@ -4220,19 +4732,27 @@ expand_omp_for_generic (struct omp_region *region,
make_edge (cont_bb, l2_bb, EDGE_FALSE_VALUE);
if (current_loops)
add_bb_to_loop (l2_bb, cont_bb->loop_father);
- if (fd->collapse > 1)
+ e = find_edge (cont_bb, l1_bb);
+ /* OMP4 placeholder for gimple_omp_for_combined_p (fd->for_stmt). */
+ if (0)
+ ;
+ else if (fd->collapse > 1)
{
- e = find_edge (cont_bb, l1_bb);
remove_edge (e);
e = make_edge (cont_bb, collapse_bb, EDGE_TRUE_VALUE);
}
else
+ e->flags = EDGE_TRUE_VALUE;
+ if (e)
{
- e = find_edge (cont_bb, l1_bb);
- e->flags = EDGE_TRUE_VALUE;
+ e->probability = REG_BR_PROB_BASE * 7 / 8;
+ find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
+ }
+ else
+ {
+ e = find_edge (cont_bb, l2_bb);
+ e->flags = EDGE_FALLTHRU;
}
- e->probability = REG_BR_PROB_BASE * 7 / 8;
- find_edge (cont_bb, l2_bb)->probability = REG_BR_PROB_BASE / 8;
make_edge (l2_bb, l0_bb, EDGE_TRUE_VALUE);
set_immediate_dominator (CDI_DOMINATORS, l2_bb,
@@ -4249,10 +4769,14 @@ expand_omp_for_generic (struct omp_region *region,
outer_loop->latch = l2_bb;
add_loop (outer_loop, l0_bb->loop_father);
- struct loop *loop = alloc_loop ();
- loop->header = l1_bb;
- /* The loop may have multiple latches. */
- add_loop (loop, outer_loop);
+ /* OMP4 placeholder: if (!gimple_omp_for_combined_p (fd->for_stmt)). */
+ if (1)
+ {
+ struct loop *loop = alloc_loop ();
+ loop->header = l1_bb;
+ /* The loop may have multiple latches. */
+ add_loop (loop, outer_loop);
+ }
}
}
@@ -4883,6 +5407,295 @@ expand_omp_for_static_chunk (struct omp_region *region, struct omp_for_data *fd)
add_loop (loop, trip_loop);
}
+/* A subroutine of expand_omp_for. Generate code for a simd non-worksharing
+ loop. Given parameters:
+
+ for (V = N1; V cond N2; V += STEP) BODY;
+
+ where COND is "<" or ">", we generate pseudocode
+
+ V = N1;
+ goto L1;
+ L0:
+ BODY;
+ V += STEP;
+ L1:
+ if (V cond N2) goto L0; else goto L2;
+ L2:
+
+ For collapsed loops, given parameters:
+ collapse(3)
+ for (V1 = N11; V1 cond1 N12; V1 += STEP1)
+ for (V2 = N21; V2 cond2 N22; V2 += STEP2)
+ for (V3 = N31; V3 cond3 N32; V3 += STEP3)
+ BODY;
+
+ we generate pseudocode
+
+ if (cond3 is <)
+ adj = STEP3 - 1;
+ else
+ adj = STEP3 + 1;
+ count3 = (adj + N32 - N31) / STEP3;
+ if (cond2 is <)
+ adj = STEP2 - 1;
+ else
+ adj = STEP2 + 1;
+ count2 = (adj + N22 - N21) / STEP2;
+ if (cond1 is <)
+ adj = STEP1 - 1;
+ else
+ adj = STEP1 + 1;
+ count1 = (adj + N12 - N11) / STEP1;
+ count = count1 * count2 * count3;
+ V = 0;
+ V1 = N11;
+ V2 = N21;
+ V3 = N31;
+ goto L1;
+ L0:
+ BODY;
+ V += 1;
+ V3 += STEP3;
+ V2 += (V3 cond3 N32) ? 0 : STEP2;
+ V3 = (V3 cond3 N32) ? V3 : N31;
+ V1 += (V2 cond2 N22) ? 0 : STEP1;
+ V2 = (V2 cond2 N22) ? V2 : N21;
+ L1:
+ if (V < count) goto L0; else goto L2;
+ L2:
+
+ */
+
+static void
+expand_omp_simd (struct omp_region *region, struct omp_for_data *fd)
+{
+ tree type, t;
+ basic_block entry_bb, cont_bb, exit_bb, l0_bb, l1_bb, l2_bb, l2_dom_bb;
+ gimple_stmt_iterator gsi;
+ gimple stmt;
+ bool broken_loop = region->cont == NULL;
+ edge e, ne;
+ tree *counts = NULL;
+ int i;
+ tree safelen = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
+ OMP_CLAUSE_SAFELEN);
+ tree simduid = find_omp_clause (gimple_omp_for_clauses (fd->for_stmt),
+ OMP_CLAUSE__SIMDUID_);
+ tree n2;
+
+ type = TREE_TYPE (fd->loop.v);
+ entry_bb = region->entry;
+ cont_bb = region->cont;
+ gcc_assert (EDGE_COUNT (entry_bb->succs) == 2);
+ gcc_assert (broken_loop
+ || BRANCH_EDGE (entry_bb)->dest == FALLTHRU_EDGE (cont_bb)->dest);
+ l0_bb = FALLTHRU_EDGE (entry_bb)->dest;
+ if (!broken_loop)
+ {
+ gcc_assert (BRANCH_EDGE (cont_bb)->dest == l0_bb);
+ gcc_assert (EDGE_COUNT (cont_bb->succs) == 2);
+ l1_bb = split_block (cont_bb, last_stmt (cont_bb))->dest;
+ l2_bb = BRANCH_EDGE (entry_bb)->dest;
+ }
+ else
+ {
+ BRANCH_EDGE (entry_bb)->flags &= ~EDGE_ABNORMAL;
+ l1_bb = split_edge (BRANCH_EDGE (entry_bb));
+ l2_bb = single_succ (l1_bb);
+ }
+ exit_bb = region->exit;
+ l2_dom_bb = NULL;
+
+ gsi = gsi_last_bb (entry_bb);
+
+ gcc_assert (gimple_code (gsi_stmt (gsi)) == GIMPLE_OMP_FOR);
+ /* Not needed in SSA form right now. */
+ gcc_assert (!gimple_in_ssa_p (cfun));
+ if (fd->collapse > 1)
+ {
+ int first_zero_iter = -1;
+ basic_block zero_iter_bb = l2_bb;
+
+ counts = XALLOCAVEC (tree, fd->collapse);
+ expand_omp_for_init_counts (fd, &gsi, entry_bb, counts,
+ zero_iter_bb, first_zero_iter,
+ l2_dom_bb);
+ }
+ if (l2_dom_bb == NULL)
+ l2_dom_bb = l1_bb;
+
+ n2 = fd->loop.n2;
+ if (0)
+ /* Place holder for gimple_omp_for_combined_into_p() in
+ the upcoming gomp-4_0-branch merge. */;
+ else
+ {
+ expand_omp_build_assign (&gsi, fd->loop.v,
+ fold_convert (type, fd->loop.n1));
+ if (fd->collapse > 1)
+ for (i = 0; i < fd->collapse; i++)
+ {
+ tree itype = TREE_TYPE (fd->loops[i].v);
+ if (POINTER_TYPE_P (itype))
+ itype = signed_type_for (itype);
+ t = fold_convert (TREE_TYPE (fd->loops[i].v), fd->loops[i].n1);
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
+ }
+ }
+
+ /* Remove the GIMPLE_OMP_FOR statement. */
+ gsi_remove (&gsi, true);
+
+ if (!broken_loop)
+ {
+ /* Code to control the increment goes in the CONT_BB. */
+ gsi = gsi_last_bb (cont_bb);
+ stmt = gsi_stmt (gsi);
+ gcc_assert (gimple_code (stmt) == GIMPLE_OMP_CONTINUE);
+
+ if (POINTER_TYPE_P (type))
+ t = fold_build_pointer_plus (fd->loop.v, fd->loop.step);
+ else
+ t = fold_build2 (PLUS_EXPR, type, fd->loop.v, fd->loop.step);
+ expand_omp_build_assign (&gsi, fd->loop.v, t);
+
+ if (fd->collapse > 1)
+ {
+ i = fd->collapse - 1;
+ if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i].v)))
+ {
+ t = fold_convert (sizetype, fd->loops[i].step);
+ t = fold_build_pointer_plus (fd->loops[i].v, t);
+ }
+ else
+ {
+ t = fold_convert (TREE_TYPE (fd->loops[i].v),
+ fd->loops[i].step);
+ t = fold_build2 (PLUS_EXPR, TREE_TYPE (fd->loops[i].v),
+ fd->loops[i].v, t);
+ }
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
+
+ for (i = fd->collapse - 1; i > 0; i--)
+ {
+ tree itype = TREE_TYPE (fd->loops[i].v);
+ tree itype2 = TREE_TYPE (fd->loops[i - 1].v);
+ if (POINTER_TYPE_P (itype2))
+ itype2 = signed_type_for (itype2);
+ t = build3 (COND_EXPR, itype2,
+ build2 (fd->loops[i].cond_code, boolean_type_node,
+ fd->loops[i].v,
+ fold_convert (itype, fd->loops[i].n2)),
+ build_int_cst (itype2, 0),
+ fold_convert (itype2, fd->loops[i - 1].step));
+ if (POINTER_TYPE_P (TREE_TYPE (fd->loops[i - 1].v)))
+ t = fold_build_pointer_plus (fd->loops[i - 1].v, t);
+ else
+ t = fold_build2 (PLUS_EXPR, itype2, fd->loops[i - 1].v, t);
+ expand_omp_build_assign (&gsi, fd->loops[i - 1].v, t);
+
+ t = build3 (COND_EXPR, itype,
+ build2 (fd->loops[i].cond_code, boolean_type_node,
+ fd->loops[i].v,
+ fold_convert (itype, fd->loops[i].n2)),
+ fd->loops[i].v,
+ fold_convert (itype, fd->loops[i].n1));
+ expand_omp_build_assign (&gsi, fd->loops[i].v, t);
+ }
+ }
+
+ /* Remove GIMPLE_OMP_CONTINUE. */
+ gsi_remove (&gsi, true);
+ }
+
+ /* Emit the condition in L1_BB. */
+ gsi = gsi_start_bb (l1_bb);
+
+ t = fold_convert (type, n2);
+ t = force_gimple_operand_gsi (&gsi, t, true, NULL_TREE,
+ false, GSI_CONTINUE_LINKING);
+ t = build2 (fd->loop.cond_code, boolean_type_node, fd->loop.v, t);
+ stmt = gimple_build_cond_empty (t);
+ gsi_insert_after (&gsi, stmt, GSI_CONTINUE_LINKING);
+ if (walk_tree (gimple_cond_lhs_ptr (stmt), expand_omp_regimplify_p,
+ NULL, NULL)
+ || walk_tree (gimple_cond_rhs_ptr (stmt), expand_omp_regimplify_p,
+ NULL, NULL))
+ {
+ gsi = gsi_for_stmt (stmt);
+ gimple_regimplify_operands (stmt, &gsi);
+ }
+
+ /* Remove GIMPLE_OMP_RETURN. */
+ gsi = gsi_last_bb (exit_bb);
+ gsi_remove (&gsi, true);
+
+ /* Connect the new blocks. */
+ remove_edge (FALLTHRU_EDGE (entry_bb));
+
+ if (!broken_loop)
+ {
+ remove_edge (BRANCH_EDGE (entry_bb));
+ make_edge (entry_bb, l1_bb, EDGE_FALLTHRU);
+
+ e = BRANCH_EDGE (l1_bb);
+ ne = FALLTHRU_EDGE (l1_bb);
+ e->flags = EDGE_TRUE_VALUE;
+ }
+ else
+ {
+ single_succ_edge (entry_bb)->flags = EDGE_FALLTHRU;
+
+ ne = single_succ_edge (l1_bb);
+ e = make_edge (l1_bb, l0_bb, EDGE_TRUE_VALUE);
+
+ }
+ ne->flags = EDGE_FALSE_VALUE;
+ e->probability = REG_BR_PROB_BASE * 7 / 8;
+ ne->probability = REG_BR_PROB_BASE / 8;
+
+ set_immediate_dominator (CDI_DOMINATORS, l1_bb, entry_bb);
+ set_immediate_dominator (CDI_DOMINATORS, l2_bb, l2_dom_bb);
+ set_immediate_dominator (CDI_DOMINATORS, l0_bb, l1_bb);
+
+ if (!broken_loop)
+ {
+ struct loop *loop = alloc_loop ();
+ loop->header = l1_bb;
+ loop->latch = e->dest;
+ add_loop (loop, l1_bb->loop_father);
+ if (safelen == NULL_TREE)
+ loop->safelen = INT_MAX;
+ else
+ {
+ safelen = OMP_CLAUSE_SAFELEN_EXPR (safelen);
+ if (!host_integerp (safelen, 1)
+ || (unsigned HOST_WIDE_INT) tree_low_cst (safelen, 1)
+ > INT_MAX)
+ loop->safelen = INT_MAX;
+ else
+ loop->safelen = tree_low_cst (safelen, 1);
+ if (loop->safelen == 1)
+ loop->safelen = 0;
+ }
+ if (simduid)
+ {
+ loop->simduid = OMP_CLAUSE__SIMDUID__DECL (simduid);
+ cfun->has_simduid_loops = true;
+ }
+ /* If not -fno-tree-vectorize, hint that we want to vectorize
+ the loop. */
+ if ((flag_tree_vectorize
+ || !global_options_set.x_flag_tree_vectorize)
+ && loop->safelen > 1)
+ {
+ loop->force_vect = true;
+ cfun->has_force_vect_loops = true;
+ }
+ }
+}
+
/* Expand the OpenMP loop defined by REGION. */
@@ -4914,7 +5727,9 @@ expand_omp_for (struct omp_region *region)
original loops from being detected. Fix that up. */
loops_state_set (LOOPS_NEED_FIXUP);
- if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
+ if (gimple_omp_for_kind (fd.for_stmt) == GF_OMP_FOR_KIND_SIMD)
+ expand_omp_simd (region, &fd);
+ else if (fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC
&& !fd.have_ordered
&& fd.collapse == 1
&& region->cont != NULL)
@@ -4928,6 +5743,8 @@ expand_omp_for (struct omp_region *region)
{
int fn_index, start_ix, next_ix;
+ gcc_assert (gimple_omp_for_kind (fd.for_stmt)
+ == GF_OMP_FOR_KIND_FOR);
if (fd.chunk_size == NULL
&& fd.sched_kind == OMP_CLAUSE_SCHEDULE_STATIC)
fd.chunk_size = integer_zero_node;
@@ -6018,25 +6835,43 @@ gate_expand_omp (void)
return (flag_openmp != 0 && !seen_error ());
}
-struct gimple_opt_pass pass_expand_omp =
-{
- {
- GIMPLE_PASS,
- "ompexp", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_expand_omp, /* gate */
- execute_expand_omp, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_gimple_any, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_expand_omp =
+{
+ GIMPLE_PASS, /* type */
+ "ompexp", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_expand_omp : public gimple_opt_pass
+{
+public:
+ pass_expand_omp(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_expand_omp, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_expand_omp (); }
+ unsigned int execute () { return execute_expand_omp (); }
+
+}; // class pass_expand_omp
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_expand_omp (gcc::context *ctxt)
+{
+ return new pass_expand_omp (ctxt);
+}
/* Routines to lower OpenMP directives into OMP-GIMPLE. */
@@ -6516,6 +7351,8 @@ lower_omp_for_lastprivate (struct omp_for_data *fd, gimple_seq *body_p,
&& host_integerp (fd->loop.n2, 0)
&& ! integer_zerop (fd->loop.n2))
vinit = build_int_cst (TREE_TYPE (fd->loop.v), 0);
+ else
+ vinit = unshare_expr (vinit);
/* Initialize the iterator variable, so that threads that don't execute
any iterations don't execute the lastprivate clauses by accident. */
@@ -6539,7 +7376,6 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
push_gimplify_context (&gctx);
lower_omp (gimple_omp_for_pre_body_ptr (stmt), ctx);
- lower_omp (gimple_omp_body_ptr (stmt), ctx);
block = make_node (BLOCK);
new_stmt = gimple_build_bind (NULL, NULL, block);
@@ -6564,6 +7400,8 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx)
lower_rec_input_clauses (gimple_omp_for_clauses (stmt), &body, &dlist, ctx);
gimple_seq_add_seq (&body, gimple_omp_for_pre_body (stmt));
+ lower_omp (gimple_omp_body_ptr (stmt), ctx);
+
/* Lower the header expressions. At this point, we can assume that
the header is of the form:
@@ -7193,25 +8031,42 @@ execute_lower_omp (void)
return 0;
}
-struct gimple_opt_pass pass_lower_omp =
-{
- {
- GIMPLE_PASS,
- "omplower", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_lower_omp, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_gimple_any, /* properties_required */
- PROP_gimple_lomp, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_lower_omp =
+{
+ GIMPLE_PASS, /* type */
+ "omplower", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ PROP_gimple_lomp, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_lower_omp : public gimple_opt_pass
+{
+public:
+ pass_lower_omp(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_omp, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_lower_omp (); }
+
+}; // class pass_lower_omp
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_omp (gcc::context *ctxt)
+{
+ return new pass_lower_omp (ctxt);
+}
/* The following is a utility to diagnose OpenMP structured block violations.
It is not part of the "omplower" pass, as that's invoked too late. It
@@ -7457,24 +8312,44 @@ gate_diagnose_omp_blocks (void)
return flag_openmp != 0;
}
-struct gimple_opt_pass pass_diagnose_omp_blocks =
-{
- {
- GIMPLE_PASS,
- "*diagnose_omp_blocks", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_diagnose_omp_blocks, /* gate */
- diagnose_omp_structured_block_errors, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_gimple_any, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_diagnose_omp_blocks =
+{
+ GIMPLE_PASS, /* type */
+ "*diagnose_omp_blocks", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_diagnose_omp_blocks : public gimple_opt_pass
+{
+public:
+ pass_diagnose_omp_blocks(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_diagnose_omp_blocks, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_diagnose_omp_blocks (); }
+ unsigned int execute () {
+ return diagnose_omp_structured_block_errors ();
+ }
+
+}; // class pass_diagnose_omp_blocks
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_diagnose_omp_blocks (gcc::context *ctxt)
+{
+ return new pass_diagnose_omp_blocks (ctxt);
+}
+
#include "gt-omp-low.h"
diff --git a/gcc/opts.c b/gcc/opts.c
index 6856c3c8090..6b6652d89ca 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -479,6 +479,7 @@ static const struct default_options default_options_table[] =
{ OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
+ { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
{ OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
@@ -1405,6 +1406,70 @@ common_handle_option (struct gcc_options *opts,
opts->x_exit_after_options = true;
break;
+ case OPT_fsanitize_:
+ {
+ const char *p = arg;
+ while (*p != 0)
+ {
+ static const struct
+ {
+ const char *const name;
+ unsigned int flag;
+ size_t len;
+ } spec[] =
+ {
+ { "address", SANITIZE_ADDRESS, sizeof "address" - 1 },
+ { "thread", SANITIZE_THREAD, sizeof "thread" - 1 },
+ { "shift", SANITIZE_SHIFT, sizeof "shift" - 1 },
+ { "integer-divide-by-zero", SANITIZE_DIVIDE,
+ sizeof "integer-divide-by-zero" - 1 },
+ { "undefined", SANITIZE_UNDEFINED, sizeof "undefined" - 1 },
+ { "unreachable", SANITIZE_UNREACHABLE,
+ sizeof "unreachable" - 1 },
+ { NULL, 0, 0 }
+ };
+ const char *comma;
+ size_t len, i;
+ bool found = false;
+
+ comma = strchr (p, ',');
+ if (comma == NULL)
+ len = strlen (p);
+ else
+ len = comma - p;
+ if (len == 0)
+ {
+ p = comma + 1;
+ continue;
+ }
+
+ /* Check to see if the string matches an option class name. */
+ for (i = 0; spec[i].name != NULL; ++i)
+ if (len == spec[i].len
+ && memcmp (p, spec[i].name, len) == 0)
+ {
+ /* Handle both -fsanitize and -fno-sanitize cases. */
+ if (value)
+ flag_sanitize |= spec[i].flag;
+ else
+ flag_sanitize &= ~spec[i].flag;
+ found = true;
+ break;
+ }
+
+ if (! found)
+ warning_at (loc, 0,
+ "unrecognized argument to -fsanitize= option: %q.*s",
+ (int) len, p);
+
+ if (comma == NULL)
+ break;
+ p = comma + 1;
+ }
+
+ break;
+ }
+
case OPT_O:
case OPT_Os:
case OPT_Ofast:
@@ -1601,6 +1666,11 @@ common_handle_option (struct gcc_options *opts,
opts->x_flag_vect_cost_model = value;
if (!opts_set->x_flag_tree_loop_distribute_patterns)
opts->x_flag_tree_loop_distribute_patterns = value;
+ /* Indirect call profiling should do all useful transformations
+ speculative devirutalization does. */
+ if (!opts_set->x_flag_devirtualize_speculatively
+ && opts->x_flag_value_profile_transformations)
+ opts->x_flag_devirtualize_speculatively = false;
break;
case OPT_fprofile_generate_:
diff --git a/gcc/output.h b/gcc/output.h
index cc48dfbed50..7b262566c2f 100644
--- a/gcc/output.h
+++ b/gcc/output.h
@@ -197,6 +197,10 @@ extern void assemble_end_function (tree, const char *);
initial value (that will be done by the caller). */
extern void assemble_variable (tree, int, int, int);
+/* Put the vtable verification constructor initialization function
+ into the preinit array. */
+extern void assemble_vtv_preinit_initializer (tree);
+
/* Compute the alignment of variable specified by DECL.
DONT_OUTPUT_DATA is from assemble_variable. */
extern void align_variable (tree decl, bool dont_output_data);
diff --git a/gcc/pass_manager.h b/gcc/pass_manager.h
new file mode 100644
index 00000000000..04c6237d791
--- /dev/null
+++ b/gcc/pass_manager.h
@@ -0,0 +1,138 @@
+/* pass_manager.h - The pipeline of optimization passes
+ Copyright (C) 2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_PASS_MANAGER_H
+#define GCC_PASS_MANAGER_H
+
+class opt_pass;
+struct register_pass_info;
+
+/* Define a list of pass lists so that both passes.c and plugins can easily
+ find all the pass lists. */
+#define GCC_PASS_LISTS \
+ DEF_PASS_LIST (all_lowering_passes) \
+ DEF_PASS_LIST (all_small_ipa_passes) \
+ DEF_PASS_LIST (all_regular_ipa_passes) \
+ DEF_PASS_LIST (all_lto_gen_passes) \
+ DEF_PASS_LIST (all_passes)
+
+#define DEF_PASS_LIST(LIST) PASS_LIST_NO_##LIST,
+enum pass_list
+{
+ GCC_PASS_LISTS
+ PASS_LIST_NUM
+};
+#undef DEF_PASS_LIST
+
+namespace gcc {
+
+class context;
+
+class pass_manager
+{
+public:
+ void *operator new (size_t sz);
+
+ pass_manager(context *ctxt);
+
+ void register_pass (struct register_pass_info *pass_info);
+ void register_one_dump_file (struct opt_pass *pass);
+
+ opt_pass *get_pass_for_id (int id) const;
+
+ void dump_passes () const;
+
+ void dump_profile_report () const;
+
+ void finish_optimization_passes ();
+
+ /* Access to specific passes, so that the majority can be private. */
+ void execute_early_local_passes ();
+ unsigned int execute_pass_mode_switching ();
+
+ /* Various passes are manually cloned by epiphany. */
+ opt_pass *get_pass_split_all_insns () const {
+ return pass_split_all_insns_1;
+ }
+ opt_pass *get_pass_mode_switching () const {
+ return pass_mode_switching_1;
+ }
+ opt_pass *get_pass_peephole2 () const { return pass_peephole2_1; }
+ opt_pass *get_pass_profile () const { return pass_profile_1; }
+
+public:
+ /* The root of the compilation pass tree, once constructed. */
+ opt_pass *all_passes;
+ opt_pass *all_small_ipa_passes;
+ opt_pass *all_lowering_passes;
+ opt_pass *all_regular_ipa_passes;
+ opt_pass *all_lto_gen_passes;
+ opt_pass *all_late_ipa_passes;
+
+ /* A map from static pass id to optimization pass. */
+ opt_pass **passes_by_id;
+ int passes_by_id_size;
+
+ opt_pass **pass_lists[PASS_LIST_NUM];
+
+private:
+ void set_pass_for_id (int id, opt_pass *pass);
+ int register_dump_files_1 (struct opt_pass *pass, int properties);
+ void register_dump_files (struct opt_pass *pass, int properties);
+
+private:
+ context *ctxt_;
+
+ /* References to all of the individual passes.
+ These fields are generated via macro expansion.
+
+ For example:
+ NEXT_PASS (pass_build_cfg, 1);
+ within pass-instances.def means that there is a field:
+ opt_pass *pass_build_cfg_1;
+
+ Similarly, the various:
+ NEXT_PASS (pass_copy_prop, 1);
+ ...
+ NEXT_PASS (pass_copy_prop, 8);
+ in pass-instances.def lead to fields:
+ opt_pass *pass_copy_prop_1;
+ ...
+ opt_pass *pass_copy_prop_8; */
+
+#define INSERT_PASSES_AFTER(PASS)
+#define PUSH_INSERT_PASSES_WITHIN(PASS)
+#define POP_INSERT_PASSES()
+#define NEXT_PASS(PASS, NUM) opt_pass *PASS ## _ ## NUM
+#define TERMINATE_PASS_LIST()
+
+#include "pass-instances.def"
+
+#undef INSERT_PASSES_AFTER
+#undef PUSH_INSERT_PASSES_WITHIN
+#undef POP_INSERT_PASSES
+#undef NEXT_PASS
+#undef TERMINATE_PASS_LIST
+
+}; // class pass_manager
+
+} // namespace gcc
+
+#endif /* ! GCC_PASS_MANAGER_H */
+
diff --git a/gcc/passes.c b/gcc/passes.c
index 73e93d61edd..7f5ad640a3c 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -70,6 +70,10 @@ along with GCC; see the file COPYING3. If not see
#include "plugin.h"
#include "ipa-utils.h"
#include "tree-pretty-print.h" /* for dump_function_header */
+#include "context.h"
+#include "pass_manager.h"
+
+using namespace gcc;
/* This is used for debugging. It allows the current pass to printed
from anywhere in compilation.
@@ -78,6 +82,54 @@ struct opt_pass *current_pass;
static void register_pass_name (struct 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.
+
+ Handle this by providing a default implemenation, but make it a fatal
+ error to call it. */
+
+opt_pass *
+opt_pass::clone ()
+{
+ internal_error ("pass %s does not support cloning", name);
+}
+
+bool
+opt_pass::gate ()
+{
+ return true;
+}
+
+unsigned int
+opt_pass::execute ()
+{
+ return 0;
+}
+
+opt_pass::opt_pass(const pass_data &data, context *ctxt)
+ : pass_data(data),
+ sub(NULL),
+ next(NULL),
+ static_pass_number(0),
+ ctxt_(ctxt)
+{
+}
+
+
+void
+pass_manager::execute_early_local_passes ()
+{
+ execute_pass_list (pass_early_local_passes_1->sub);
+}
+
+unsigned int
+pass_manager::execute_pass_mode_switching ()
+{
+ return pass_mode_switching_1->execute ();
+}
+
+
/* Call from anywhere to find out what pass this is. Useful for
printing out debugging information deep inside an service
routine. */
@@ -220,6 +272,7 @@ rest_of_type_compilation (tree type, int toplev)
void
+pass_manager::
finish_optimization_passes (void)
{
int i;
@@ -229,16 +282,16 @@ finish_optimization_passes (void)
timevar_push (TV_DUMP);
if (profile_arc_flag || flag_test_coverage || flag_branch_probabilities)
{
- dump_start (pass_profile.pass.static_pass_number, NULL);
+ dump_start (pass_profile_1->static_pass_number, NULL);
end_branch_prob ();
- dump_finish (pass_profile.pass.static_pass_number);
+ dump_finish (pass_profile_1->static_pass_number);
}
if (optimize > 0)
{
- dump_start (pass_profile.pass.static_pass_number, NULL);
+ dump_start (pass_profile_1->static_pass_number, NULL);
print_combine_total_stats ();
- dump_finish (pass_profile.pass.static_pass_number);
+ dump_finish (pass_profile_1->static_pass_number);
}
/* Do whatever is necessary to finish printing the graphs. */
@@ -277,26 +330,44 @@ gate_all_early_local_passes (void)
return (!seen_error () && !in_lto_p);
}
-struct simple_ipa_opt_pass pass_early_local_passes =
-{
- {
- SIMPLE_IPA_PASS,
- "early_local_cleanups", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_all_early_local_passes, /* gate */
- execute_all_early_local_passes, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_EARLY_LOCAL, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_remove_functions /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_early_local_passes =
+{
+ SIMPLE_IPA_PASS, /* type */
+ "early_local_cleanups", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_EARLY_LOCAL, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_remove_functions, /* todo_flags_finish */
};
+class pass_early_local_passes : public simple_ipa_opt_pass
+{
+public:
+ pass_early_local_passes(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_early_local_passes, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_all_early_local_passes (); }
+ unsigned int execute () { return execute_all_early_local_passes (); }
+
+}; // class pass_early_local_passes
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_early_local_passes (gcc::context *ctxt)
+{
+ return new pass_early_local_passes (ctxt);
+}
+
/* Gate: execute, or not, all of the non-trivial optimizations. */
static bool
@@ -307,26 +378,43 @@ gate_all_early_optimizations (void)
&& !seen_error ());
}
-static struct gimple_opt_pass pass_all_early_optimizations =
-{
- {
- GIMPLE_PASS,
- "early_optimizations", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_all_early_optimizations, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_all_early_optimizations =
+{
+ GIMPLE_PASS, /* type */
+ "early_optimizations", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_all_early_optimizations : public gimple_opt_pass
+{
+public:
+ pass_all_early_optimizations(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_all_early_optimizations, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_all_early_optimizations (); }
+
+}; // class pass_all_early_optimizations
+
+} // anon namespace
+
+static gimple_opt_pass *
+make_pass_all_early_optimizations (gcc::context *ctxt)
+{
+ return new pass_all_early_optimizations (ctxt);
+}
+
/* Gate: execute, or not, all of the non-trivial optimizations. */
static bool
@@ -335,26 +423,43 @@ gate_all_optimizations (void)
return optimize >= 1 && !optimize_debug;
}
-static struct gimple_opt_pass pass_all_optimizations =
-{
- {
- GIMPLE_PASS,
- "*all_optimizations", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_all_optimizations, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_OPTIMIZE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_all_optimizations =
+{
+ GIMPLE_PASS, /* type */
+ "*all_optimizations", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_OPTIMIZE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_all_optimizations : public gimple_opt_pass
+{
+public:
+ pass_all_optimizations(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_all_optimizations, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_all_optimizations (); }
+
+}; // class pass_all_optimizations
+
+} // anon namespace
+
+static gimple_opt_pass *
+make_pass_all_optimizations (gcc::context *ctxt)
+{
+ return new pass_all_optimizations (ctxt);
+}
+
/* Gate: execute, or not, all of the non-trivial optimizations. */
static bool
@@ -363,26 +468,43 @@ gate_all_optimizations_g (void)
return optimize >= 1 && optimize_debug;
}
-static struct gimple_opt_pass pass_all_optimizations_g =
-{
- {
- GIMPLE_PASS,
- "*all_optimizations_g", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_all_optimizations_g, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_OPTIMIZE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_all_optimizations_g =
+{
+ GIMPLE_PASS, /* type */
+ "*all_optimizations_g", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_OPTIMIZE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_all_optimizations_g : public gimple_opt_pass
+{
+public:
+ pass_all_optimizations_g(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_all_optimizations_g, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_all_optimizations_g (); }
+
+}; // class pass_all_optimizations_g
+
+} // anon namespace
+
+static gimple_opt_pass *
+make_pass_all_optimizations_g (gcc::context *ctxt)
+{
+ return new pass_all_optimizations_g (ctxt);
+}
+
static bool
gate_rest_of_compilation (void)
{
@@ -391,71 +513,93 @@ gate_rest_of_compilation (void)
return !(rtl_dump_and_exit || flag_syntax_only || seen_error ());
}
-static struct rtl_opt_pass pass_rest_of_compilation =
-{
- {
- RTL_PASS,
- "*rest_of_compilation", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_rest_of_compilation, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_REST_OF_COMPILATION, /* tv_id */
- PROP_rtl, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_rest_of_compilation =
+{
+ RTL_PASS, /* type */
+ "*rest_of_compilation", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_REST_OF_COMPILATION, /* tv_id */
+ PROP_rtl, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_rest_of_compilation : public rtl_opt_pass
+{
+public:
+ pass_rest_of_compilation(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rest_of_compilation, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_rest_of_compilation (); }
+
+}; // class pass_rest_of_compilation
+
+} // anon namespace
+
+static rtl_opt_pass *
+make_pass_rest_of_compilation (gcc::context *ctxt)
+{
+ return new pass_rest_of_compilation (ctxt);
+}
+
static bool
gate_postreload (void)
{
return reload_completed;
}
-static struct rtl_opt_pass pass_postreload =
-{
- {
- RTL_PASS,
- "*all-postreload", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_postreload, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_POSTRELOAD, /* tv_id */
- PROP_rtl, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_postreload =
+{
+ RTL_PASS, /* type */
+ "*all-postreload", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_POSTRELOAD, /* tv_id */
+ PROP_rtl, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+class pass_postreload : public rtl_opt_pass
+{
+public:
+ pass_postreload(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_postreload, ctxt)
+ {}
+ /* opt_pass methods: */
+ bool gate () { return gate_postreload (); }
-/* The root of the compilation pass tree, once constructed. */
-struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes,
- *all_regular_ipa_passes, *all_late_ipa_passes, *all_lto_gen_passes;
+}; // class pass_postreload
+
+} // anon namespace
+
+static rtl_opt_pass *
+make_pass_postreload (gcc::context *ctxt)
+{
+ return new pass_postreload (ctxt);
+}
-/* This is used by plugins, and should also be used in register_pass. */
-#define DEF_PASS_LIST(LIST) &LIST,
-struct opt_pass **gcc_pass_lists[] = { GCC_PASS_LISTS NULL };
-#undef DEF_PASS_LIST
-/* A map from static pass id to optimization pass. */
-struct opt_pass **passes_by_id;
-int passes_by_id_size;
/* Set the static pass number of pass PASS to ID and record that
in the mapping from static pass number to pass. */
-static void
+void
+pass_manager::
set_pass_for_id (int id, struct opt_pass *pass)
{
pass->static_pass_number = id;
@@ -472,7 +616,7 @@ set_pass_for_id (int id, struct opt_pass *pass)
/* Return the pass with the static pass number ID. */
struct opt_pass *
-get_pass_for_id (int id)
+pass_manager::get_pass_for_id (int id) const
{
if (id >= passes_by_id_size)
return NULL;
@@ -486,6 +630,12 @@ get_pass_for_id (int id)
void
register_one_dump_file (struct opt_pass *pass)
{
+ g->get_passes ()->register_one_dump_file (pass);
+}
+
+void
+pass_manager::register_one_dump_file (struct opt_pass *pass)
+{
char *dot_name, *flag_name, *glob_name;
const char *name, *full_name, *prefix;
char num[10];
@@ -526,6 +676,11 @@ register_one_dump_file (struct opt_pass *pass)
flag_name = concat (prefix, name, num, NULL);
glob_name = concat (prefix, name, NULL);
optgroup_flags |= pass->optinfo_flags;
+ /* For any passes that do not have an optgroup set, and which are not
+ IPA passes setup above, set the optgroup to OPTGROUP_OTHER so that
+ any dump messages are emitted properly under -fopt-info(-optall). */
+ if (optgroup_flags == OPTGROUP_NONE)
+ optgroup_flags = OPTGROUP_OTHER;
id = dump_register (dot_name, flag_name, glob_name, flags, optgroup_flags);
set_pass_for_id (id, pass);
full_name = concat (prefix, pass->name, num, NULL);
@@ -535,7 +690,8 @@ register_one_dump_file (struct opt_pass *pass)
/* Recursive worker function for register_dump_files. */
-static int
+int
+pass_manager::
register_dump_files_1 (struct opt_pass *pass, int properties)
{
do
@@ -551,7 +707,7 @@ register_dump_files_1 (struct opt_pass *pass, int properties)
/* If we have a gate, combine the properties that we could have with
and without the pass being examined. */
- if (pass->gate)
+ if (pass->has_gate)
properties &= new_properties;
else
properties = new_properties;
@@ -563,11 +719,12 @@ register_dump_files_1 (struct opt_pass *pass, int properties)
return properties;
}
-/* Register the dump files for the pipeline starting at PASS.
+/* Register the dump files for the pass_manager starting at PASS.
PROPERTIES reflects the properties that are guaranteed to be available at
the beginning of the pipeline. */
-static void
+void
+pass_manager::
register_dump_files (struct opt_pass *pass,int properties)
{
pass->properties_required |= properties;
@@ -663,7 +820,7 @@ create_pass_tab (void)
if (!flag_dump_passes)
return;
- pass_tab.safe_grow_cleared (passes_by_id_size + 1);
+ pass_tab.safe_grow_cleared (g->get_passes ()->passes_by_id_size + 1);
name_to_pass_map.traverse <void *, passes_pass_traverse> (NULL);
}
@@ -679,7 +836,7 @@ dump_one_pass (struct opt_pass *pass, int pass_indent)
const char *pn;
bool is_on, is_really_on;
- is_on = (pass->gate == NULL) ? true : pass->gate();
+ is_on = pass->has_gate ? pass->gate() : true;
is_really_on = override_gate_status (pass, current_function_decl, is_on);
if (pass->static_pass_number <= 0)
@@ -714,6 +871,12 @@ dump_pass_list (struct opt_pass *pass, int indent)
void
dump_passes (void)
{
+ g->get_passes ()->dump_passes ();
+}
+
+void
+pass_manager::dump_passes () const
+{
struct cgraph_node *n, *node = NULL;
create_pass_tab();
@@ -1009,68 +1172,77 @@ is_pass_explicitly_enabled_or_disabled (struct opt_pass *pass,
return false;
}
-/* Look at the static_pass_number and duplicate the pass
- if it is already added to a list. */
-static struct opt_pass *
-make_pass_instance (struct opt_pass *pass, bool track_duplicates)
-{
- /* A nonzero static_pass_number indicates that the
- pass is already in the list. */
- if (pass->static_pass_number)
- {
- struct opt_pass *new_pass;
+/* Update static_pass_number for passes (and the flag
+ TODO_mark_first_instance).
- if (pass->type == GIMPLE_PASS
- || pass->type == RTL_PASS
- || pass->type == SIMPLE_IPA_PASS)
- {
- new_pass = XNEW (struct opt_pass);
- memcpy (new_pass, pass, sizeof (struct opt_pass));
- }
- else if (pass->type == IPA_PASS)
- {
- new_pass = (struct opt_pass *)XNEW (struct ipa_opt_pass_d);
- memcpy (new_pass, pass, sizeof (struct ipa_opt_pass_d));
- }
- else
- gcc_unreachable ();
+ Passes are constructed with static_pass_number preinitialized to 0
+
+ This field is used in two different ways: initially as instance numbers
+ of their kind, and then as ids within the entire pass manager.
+
+ Within pass_manager::pass_manager:
+
+ * In add_pass_instance(), as called by next_pass_1 in
+ NEXT_PASS in init_optimization_passes
+
+ * When the initial instance of a pass within a pass manager is seen,
+ it is flagged, and its static_pass_number is set to -1
- new_pass->next = NULL;
+ * On subsequent times that it is seen, the static pass number
+ is decremented each time, so that if there are e.g. 4 dups,
+ they have static_pass_number -4, 2, 3, 4 respectively (note
+ how the initial one is negative and gives the count); these
+ can be thought of as instance numbers of the specific pass
+ * Within the register_dump_files () traversal, set_pass_for_id()
+ is called on each pass, using these instance numbers to create
+ dumpfile switches, and then overwriting them with a pass id,
+ which are global to the whole pass manager (based on
+ (TDI_end + current value of extra_dump_files_in_use) ) */
+
+static void
+add_pass_instance (struct opt_pass *new_pass, bool track_duplicates,
+ opt_pass *initial_pass)
+{
+ /* Are we dealing with the first pass of its kind, or a clone? */
+ if (new_pass != initial_pass)
+ {
+ /* We're dealing with a clone. */
new_pass->todo_flags_start &= ~TODO_mark_first_instance;
/* Indicate to register_dump_files that this pass has duplicates,
and so it should rename the dump file. The first instance will
be -1, and be number of duplicates = -static_pass_number - 1.
Subsequent instances will be > 0 and just the duplicate number. */
- if ((pass->name && pass->name[0] != '*') || track_duplicates)
+ if ((new_pass->name && new_pass->name[0] != '*') || track_duplicates)
{
- pass->static_pass_number -= 1;
- new_pass->static_pass_number = -pass->static_pass_number;
+ initial_pass->static_pass_number -= 1;
+ new_pass->static_pass_number = -initial_pass->static_pass_number;
}
- return new_pass;
}
else
{
- pass->todo_flags_start |= TODO_mark_first_instance;
- pass->static_pass_number = -1;
+ /* We're dealing with the first pass of its kind. */
+ new_pass->todo_flags_start |= TODO_mark_first_instance;
+ new_pass->static_pass_number = -1;
- invoke_plugin_callbacks (PLUGIN_NEW_PASS, pass);
+ invoke_plugin_callbacks (PLUGIN_NEW_PASS, new_pass);
}
- return pass;
}
/* Add a pass to the pass list. Duplicate the pass if it's already
in the list. */
static struct opt_pass **
-next_pass_1 (struct opt_pass **list, struct opt_pass *pass)
+next_pass_1 (struct opt_pass **list, struct opt_pass *pass,
+ struct opt_pass *initial_pass)
{
/* Every pass should have a name so that plugins can refer to them. */
gcc_assert (pass->name != NULL);
- *list = make_pass_instance (pass, false);
+ add_pass_instance (pass, false, initial_pass);
+ *list = pass;
return &(*list)->next;
}
@@ -1120,7 +1292,16 @@ position_pass (struct register_pass_info *new_pass_info,
struct opt_pass *new_pass;
struct pass_list_node *new_pass_node;
- new_pass = make_pass_instance (new_pass_info->pass, true);
+ if (new_pass_info->ref_pass_instance_number == 0)
+ {
+ new_pass = new_pass_info->pass->clone ();
+ add_pass_instance (new_pass, true, new_pass_info->pass);
+ }
+ else
+ {
+ new_pass = new_pass_info->pass;
+ add_pass_instance (new_pass, true, new_pass);
+ }
/* Insert the new pass instance based on the positioning op. */
switch (new_pass_info->pos_op)
@@ -1188,6 +1369,25 @@ position_pass (struct register_pass_info *new_pass_info,
void
register_pass (struct register_pass_info *pass_info)
{
+ g->get_passes ()->register_pass (pass_info);
+}
+
+void
+register_pass (opt_pass* pass, pass_positioning_ops pos,
+ const char* ref_pass_name, int ref_pass_inst_number)
+{
+ register_pass_info i;
+ i.pass = pass;
+ i.reference_pass_name = ref_pass_name;
+ i.ref_pass_instance_number = ref_pass_inst_number;
+ i.pos_op = pos;
+
+ g->get_passes ()->register_pass (&i);
+}
+
+void
+pass_manager::register_pass (struct register_pass_info *pass_info)
+{
bool all_instances, success;
/* The checks below could fail in buggy plugins. Existing GCC
@@ -1277,27 +1477,55 @@ register_pass (struct register_pass_info *pass_info)
-> all_passes
*/
-void
-init_optimization_passes (void)
+void *
+pass_manager::operator new (size_t sz)
+{
+ /* Ensure that all fields of the pass manager are zero-initialized. */
+ return xcalloc (1, sz);
+}
+
+pass_manager::pass_manager (context *ctxt)
+: all_passes(NULL), all_small_ipa_passes(NULL), all_lowering_passes(NULL),
+ all_regular_ipa_passes(NULL), all_lto_gen_passes(NULL),
+ all_late_ipa_passes(NULL), passes_by_id(NULL), passes_by_id_size(0),
+ ctxt_(ctxt)
{
struct opt_pass **p;
+ /* Initialize the pass_lists array. */
+#define DEF_PASS_LIST(LIST) pass_lists[PASS_LIST_NO_##LIST] = &LIST;
+ GCC_PASS_LISTS
+#undef DEF_PASS_LIST
+
+ /* Build the tree of passes. */
+
#define INSERT_PASSES_AFTER(PASS) \
p = &(PASS);
#define PUSH_INSERT_PASSES_WITHIN(PASS) \
{ \
- struct opt_pass **p = &(PASS).pass.sub;
+ struct opt_pass **p = &(PASS ## _1)->sub;
#define POP_INSERT_PASSES() \
}
-#define NEXT_PASS(PASS) (p = next_pass_1 (p, &((PASS).pass)))
+#define NEXT_PASS(PASS, NUM) \
+ do { \
+ gcc_assert (NULL == PASS ## _ ## NUM); \
+ if ((NUM) == 1) \
+ PASS ## _1 = make_##PASS (ctxt_); \
+ else \
+ { \
+ gcc_assert (PASS ## _1); \
+ PASS ## _ ## NUM = PASS ## _1->clone (); \
+ } \
+ p = next_pass_1 (p, PASS ## _ ## NUM, PASS ## _1); \
+ } while (0)
#define TERMINATE_PASS_LIST() \
*p = NULL;
-#include "passes.def"
+#include "pass-instances.def"
#undef INSERT_PASSES_AFTER
#undef PUSH_INSERT_PASSES_WITHIN
@@ -1386,6 +1614,7 @@ do_per_function_toporder (void (*callback) (void *data), void *data)
node->process = 0;
if (cgraph_function_with_gimple_body_p (node))
{
+ cgraph_get_body (node);
push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl));
callback (data);
free_dominance_info (CDI_DOMINATORS);
@@ -1432,12 +1661,13 @@ static struct profile_record *profile_record;
static void
check_profile_consistency (int index, int subpass, bool run)
{
+ pass_manager *passes = g->get_passes ();
if (index == -1)
return;
if (!profile_record)
profile_record = XCNEWVEC (struct profile_record,
- passes_by_id_size);
- gcc_assert (index < passes_by_id_size && index >= 0);
+ passes->passes_by_id_size);
+ gcc_assert (index < passes->passes_by_id_size && index >= 0);
gcc_assert (subpass < 2);
profile_record[index].run |= run;
account_profile_record (&profile_record[index], subpass);
@@ -1448,6 +1678,12 @@ check_profile_consistency (int index, int subpass, bool run)
void
dump_profile_report (void)
{
+ g->get_passes ()->dump_profile_report ();
+}
+
+void
+pass_manager::dump_profile_report () const
+{
int i, j;
int last_freq_in = 0, last_count_in = 0, last_freq_out = 0, last_count_out = 0;
gcov_type last_time = 0, last_size = 0;
@@ -1511,7 +1747,7 @@ dump_profile_report (void)
fprintf (stderr, " ");
/* Size/time units change across gimple and RTL. */
- if (i == pass_expand.pass.static_pass_number)
+ if (i == pass_expand_1->static_pass_number)
fprintf (stderr, "|----------");
else
{
@@ -1748,11 +1984,11 @@ execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
{
while (ipa_pass)
{
- struct opt_pass *pass = &ipa_pass->pass;
+ struct opt_pass *pass = ipa_pass;
/* Execute all of the IPA_PASSes in the list. */
- if (ipa_pass->pass.type == IPA_PASS
- && (!pass->gate || pass->gate ())
+ if (ipa_pass->type == IPA_PASS
+ && ((!pass->has_gate) || pass->gate ())
&& ipa_pass->generate_summary)
{
pass_init_dump_file (pass);
@@ -1769,7 +2005,7 @@ execute_ipa_summary_passes (struct ipa_opt_pass_d *ipa_pass)
pass_fini_dump_file (pass);
}
- ipa_pass = (struct ipa_opt_pass_d *)ipa_pass->pass.next;
+ ipa_pass = (struct ipa_opt_pass_d *)ipa_pass->next;
}
}
@@ -1779,7 +2015,7 @@ static void
execute_one_ipa_transform_pass (struct cgraph_node *node,
struct ipa_opt_pass_d *ipa_pass)
{
- struct opt_pass *pass = &ipa_pass->pass;
+ struct opt_pass *pass = ipa_pass;
unsigned int todo_after = 0;
current_pass = pass;
@@ -1903,7 +2139,7 @@ execute_one_pass (struct opt_pass *pass)
/* Check whether gate check should be avoided.
User controls the value of the gate through the parameter "gate_status". */
- gate_status = (pass->gate == NULL) ? true : pass->gate();
+ gate_status = pass->has_gate ? pass->gate() : true;
gate_status = override_gate_status (pass, current_function_decl, gate_status);
/* Override gate with plugin. */
@@ -1964,7 +2200,7 @@ execute_one_pass (struct opt_pass *pass)
timevar_push (pass->tv_id);
/* Do it! */
- if (pass->execute)
+ if (pass->has_execute)
{
todo_after = pass->execute ();
do_per_function (clear_last_verified, NULL);
@@ -2040,7 +2276,7 @@ ipa_write_summaries_2 (struct opt_pass *pass, struct lto_out_decl_state *state)
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
if (pass->type == IPA_PASS
&& ipa_pass->write_summary
- && (!pass->gate || pass->gate ()))
+ && ((!pass->has_gate) || pass->gate ()))
{
/* If a timevar is present, start it. */
if (pass->tv_id)
@@ -2071,14 +2307,15 @@ ipa_write_summaries_2 (struct opt_pass *pass, struct lto_out_decl_state *state)
static void
ipa_write_summaries_1 (lto_symtab_encoder_t encoder)
{
+ pass_manager *passes = g->get_passes ();
struct lto_out_decl_state *state = lto_new_out_decl_state ();
state->symtab_node_encoder = encoder;
lto_push_out_decl_state (state);
gcc_assert (!flag_wpa);
- ipa_write_summaries_2 (all_regular_ipa_passes, state);
- ipa_write_summaries_2 (all_lto_gen_passes, state);
+ ipa_write_summaries_2 (passes->all_regular_ipa_passes, state);
+ ipa_write_summaries_2 (passes->all_lto_gen_passes, state);
gcc_assert (lto_get_out_decl_state () == state);
lto_pop_out_decl_state ();
@@ -2155,7 +2392,7 @@ ipa_write_optimization_summaries_1 (struct opt_pass *pass, struct lto_out_decl_s
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
if (pass->type == IPA_PASS
&& ipa_pass->write_optimization_summary
- && (!pass->gate || pass->gate ()))
+ && ((!pass->has_gate) || pass->gate ()))
{
/* If a timevar is present, start it. */
if (pass->tv_id)
@@ -2209,8 +2446,9 @@ ipa_write_optimization_summaries (lto_symtab_encoder_t encoder)
}
gcc_assert (flag_wpa);
- ipa_write_optimization_summaries_1 (all_regular_ipa_passes, state);
- ipa_write_optimization_summaries_1 (all_lto_gen_passes, state);
+ pass_manager *passes = g->get_passes ();
+ ipa_write_optimization_summaries_1 (passes->all_regular_ipa_passes, state);
+ ipa_write_optimization_summaries_1 (passes->all_lto_gen_passes, state);
gcc_assert (lto_get_out_decl_state () == state);
lto_pop_out_decl_state ();
@@ -2231,7 +2469,7 @@ ipa_read_summaries_1 (struct opt_pass *pass)
gcc_assert (!cfun);
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
- if (pass->gate == NULL || pass->gate ())
+ if ((!pass->has_gate) || pass->gate ())
{
if (pass->type == IPA_PASS && ipa_pass->read_summary)
{
@@ -2263,8 +2501,9 @@ ipa_read_summaries_1 (struct opt_pass *pass)
void
ipa_read_summaries (void)
{
- ipa_read_summaries_1 (all_regular_ipa_passes);
- ipa_read_summaries_1 (all_lto_gen_passes);
+ pass_manager *passes = g->get_passes ();
+ ipa_read_summaries_1 (passes->all_regular_ipa_passes);
+ ipa_read_summaries_1 (passes->all_lto_gen_passes);
}
/* Same as execute_pass_list but assume that subpasses of IPA passes
@@ -2281,7 +2520,7 @@ ipa_read_optimization_summaries_1 (struct opt_pass *pass)
gcc_assert (!cfun);
gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
- if (pass->gate == NULL || pass->gate ())
+ if ((!pass->has_gate) || pass->gate ())
{
if (pass->type == IPA_PASS && ipa_pass->read_optimization_summary)
{
@@ -2312,8 +2551,9 @@ ipa_read_optimization_summaries_1 (struct opt_pass *pass)
void
ipa_read_optimization_summaries (void)
{
- ipa_read_optimization_summaries_1 (all_regular_ipa_passes);
- ipa_read_optimization_summaries_1 (all_lto_gen_passes);
+ pass_manager *passes = g->get_passes ();
+ ipa_read_optimization_summaries_1 (passes->all_regular_ipa_passes);
+ ipa_read_optimization_summaries_1 (passes->all_lto_gen_passes);
}
/* Same as execute_pass_list but assume that subpasses of IPA passes
@@ -2358,7 +2598,7 @@ execute_ipa_stmt_fixups (struct opt_pass *pass,
{
/* Execute all of the IPA_PASSes in the list. */
if (pass->type == IPA_PASS
- && (!pass->gate || pass->gate ()))
+ && ((!pass->has_gate) || pass->gate ()))
{
struct ipa_opt_pass_d *ipa_pass = (struct ipa_opt_pass_d *) pass;
@@ -2388,7 +2628,8 @@ execute_ipa_stmt_fixups (struct opt_pass *pass,
void
execute_all_ipa_stmt_fixups (struct cgraph_node *node, gimple *stmts)
{
- execute_ipa_stmt_fixups (all_regular_ipa_passes, node, stmts);
+ pass_manager *passes = g->get_passes ();
+ execute_ipa_stmt_fixups (passes->all_regular_ipa_passes, node, stmts);
}
diff --git a/gcc/passes.def b/gcc/passes.def
index 61cfd9e7e95..736a28b64dc 100644
--- a/gcc/passes.def
+++ b/gcc/passes.def
@@ -104,6 +104,7 @@ along with GCC; see the file COPYING3. If not see
INSERT_PASSES_AFTER (all_regular_ipa_passes)
NEXT_PASS (pass_ipa_whole_program_visibility);
NEXT_PASS (pass_ipa_profile);
+ NEXT_PASS (pass_ipa_devirt);
NEXT_PASS (pass_ipa_cp);
NEXT_PASS (pass_ipa_cdtor_merge);
NEXT_PASS (pass_ipa_inline);
@@ -126,7 +127,6 @@ along with GCC; see the file COPYING3. If not see
/* These passes are run after IPA passes on every function that is being
output to the assembler file. */
INSERT_PASSES_AFTER (all_passes)
- NEXT_PASS (pass_fixup_cfg);
NEXT_PASS (pass_lower_eh_dispatch);
NEXT_PASS (pass_all_optimizations);
PUSH_INSERT_PASSES_WITHIN (pass_all_optimizations)
@@ -292,6 +292,7 @@ along with GCC; see the file COPYING3. If not see
NEXT_PASS (pass_tm_memopt);
NEXT_PASS (pass_tm_edges);
POP_INSERT_PASSES ()
+ NEXT_PASS (pass_vtable_verify);
NEXT_PASS (pass_lower_vector);
NEXT_PASS (pass_lower_complex_O0);
NEXT_PASS (pass_asan_O0);
diff --git a/gcc/postreload-gcse.c b/gcc/postreload-gcse.c
index aeffc14435e..0f3ed7acda6 100644
--- a/gcc/postreload-gcse.c
+++ b/gcc/postreload-gcse.c
@@ -1324,23 +1324,40 @@ rest_of_handle_gcse2 (void)
return 0;
}
-struct rtl_opt_pass pass_gcse2 =
+namespace {
+
+const pass_data pass_data_gcse2 =
{
- {
- RTL_PASS,
- "gcse2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_gcse2, /* gate */
- rest_of_handle_gcse2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_GCSE_AFTER_RELOAD, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing
- | TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "gcse2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_GCSE_AFTER_RELOAD, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_rtl_sharing | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_gcse2 : public rtl_opt_pass
+{
+public:
+ pass_gcse2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_gcse2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_gcse2 (); }
+ unsigned int execute () { return rest_of_handle_gcse2 (); }
+
+}; // class pass_gcse2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_gcse2 (gcc::context *ctxt)
+{
+ return new pass_gcse2 (ctxt);
+}
diff --git a/gcc/postreload.c b/gcc/postreload.c
index f340503f69c..97d7e5d0332 100644
--- a/gcc/postreload.c
+++ b/gcc/postreload.c
@@ -2339,23 +2339,40 @@ rest_of_handle_postreload (void)
return 0;
}
-struct rtl_opt_pass pass_postreload_cse =
+namespace {
+
+const pass_data pass_data_postreload_cse =
{
- {
- RTL_PASS,
- "postreload", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_postreload, /* gate */
- rest_of_handle_postreload, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_RELOAD_CSE_REGS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "postreload", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_RELOAD_CSE_REGS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */
};
+
+class pass_postreload_cse : public rtl_opt_pass
+{
+public:
+ pass_postreload_cse(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_postreload_cse, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_postreload (); }
+ unsigned int execute () { return rest_of_handle_postreload (); }
+
+}; // class pass_postreload_cse
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_postreload_cse (gcc::context *ctxt)
+{
+ return new pass_postreload_cse (ctxt);
+}
diff --git a/gcc/predict.c b/gcc/predict.c
index 9a15c87dac9..affed79ae9d 100644
--- a/gcc/predict.c
+++ b/gcc/predict.c
@@ -232,8 +232,38 @@ bool
probably_never_executed_bb_p (struct function *fun, const_basic_block bb)
{
gcc_checking_assert (fun);
+ if (profile_status_for_function (fun) == PROFILE_READ)
+ {
+ if ((bb->count * 4 + profile_info->runs / 2) / profile_info->runs > 0)
+ return false;
+ if (!bb->frequency)
+ return true;
+ if (!ENTRY_BLOCK_PTR->frequency)
+ return false;
+ if (ENTRY_BLOCK_PTR->count && ENTRY_BLOCK_PTR->count < REG_BR_PROB_BASE)
+ {
+ return (RDIV (bb->frequency * ENTRY_BLOCK_PTR->count,
+ ENTRY_BLOCK_PTR->frequency)
+ < REG_BR_PROB_BASE / 4);
+ }
+ return true;
+ }
+ if ((!profile_info || !flag_branch_probabilities)
+ && (cgraph_get_node (fun->decl)->frequency
+ == NODE_FREQUENCY_UNLIKELY_EXECUTED))
+ return true;
+ return false;
+}
+
+
+/* Return true in case edge E is probably never executed. */
+
+bool
+probably_never_executed_edge_p (struct function *fun, edge e)
+{
+ gcc_checking_assert (fun);
if (profile_info && flag_branch_probabilities)
- return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0;
+ return ((e->count + profile_info->runs / 2) / profile_info->runs) == 0;
if ((!profile_info || !flag_branch_probabilities)
&& (cgraph_get_node (fun->decl)->frequency
== NODE_FREQUENCY_UNLIKELY_EXECUTED))
@@ -2841,13 +2871,14 @@ compute_function_frequency (void)
{
basic_block bb;
struct cgraph_node *node = cgraph_get_node (current_function_decl);
+
if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
|| MAIN_NAME_P (DECL_NAME (current_function_decl)))
node->only_called_at_startup = true;
if (DECL_STATIC_DESTRUCTOR (current_function_decl))
node->only_called_at_exit = true;
- if (!profile_info || !flag_branch_probabilities)
+ if (profile_status != PROFILE_READ)
{
int flags = flags_from_decl_or_type (current_function_decl);
if (lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl))
@@ -2865,7 +2896,13 @@ compute_function_frequency (void)
node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
return;
}
- node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
+
+ /* Only first time try to drop function into unlikely executed.
+ After inlining the roundoff errors may confuse us.
+ Ipa-profile pass will drop functions only called from unlikely
+ functions to unlikely and that is most of what we care about. */
+ if (!cfun->after_inlining)
+ node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
FOR_EACH_BB (bb)
{
if (maybe_hot_bb_p (cfun, bb))
@@ -2900,46 +2937,82 @@ predictor_name (enum br_predictor predictor)
return predictor_info[predictor].name;
}
-struct gimple_opt_pass pass_profile =
-{
- {
- GIMPLE_PASS,
- "profile_estimate", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_estimate_probability, /* gate */
- tree_estimate_probability_driver, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_BRANCH_PROB, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_profile =
+{
+ GIMPLE_PASS, /* type */
+ "profile_estimate", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_BRANCH_PROB, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
-struct gimple_opt_pass pass_strip_predict_hints =
-{
- {
- GIMPLE_PASS,
- "*strip_predict_hints", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- strip_predict_hints, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_BRANCH_PROB, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+class pass_profile : public gimple_opt_pass
+{
+public:
+ pass_profile(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_profile, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_estimate_probability (); }
+ unsigned int execute () { return tree_estimate_probability_driver (); }
+
+}; // class pass_profile
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_profile (gcc::context *ctxt)
+{
+ return new pass_profile (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_strip_predict_hints =
+{
+ GIMPLE_PASS, /* type */
+ "*strip_predict_hints", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_BRANCH_PROB, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+class pass_strip_predict_hints : public gimple_opt_pass
+{
+public:
+ pass_strip_predict_hints(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_strip_predict_hints, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_strip_predict_hints (ctxt_); }
+ unsigned int execute () { return strip_predict_hints (); }
+
+}; // class pass_strip_predict_hints
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_strip_predict_hints (gcc::context *ctxt)
+{
+ return new pass_strip_predict_hints (ctxt);
+}
+
/* Rebuild function frequencies. Passes are in general expected to
maintain profile by hand, however in some cases this is not possible:
for example when inlining several functions with loops freuqencies might run
diff --git a/gcc/pretty-print.c b/gcc/pretty-print.c
index fe46464538e..05f345ca2a8 100644
--- a/gcc/pretty-print.c
+++ b/gcc/pretty-print.c
@@ -25,13 +25,38 @@ along with GCC; see the file COPYING3. If not see
#include "pretty-print.h"
#include "diagnostic-color.h"
+#include <new> // For placement-new.
+
#if HAVE_ICONV
#include <iconv.h>
#endif
+// Default construct an output buffer.
+
+output_buffer::output_buffer ()
+ : formatted_obstack (),
+ chunk_obstack (),
+ obstack (&formatted_obstack),
+ cur_chunk_array (),
+ stream (stderr),
+ line_length (),
+ digit_buffer ()
+{
+ obstack_init (&formatted_obstack);
+ obstack_init (&chunk_obstack);
+}
+
+// Release resources owned by an output buffer at the end of lifetime.
+
+output_buffer::~output_buffer ()
+{
+ obstack_free (&chunk_obstack, obstack_finish (&chunk_obstack));
+ obstack_free (&formatted_obstack, obstack_finish (&formatted_obstack));
+}
+
/* A pointer to the formatted diagnostic message. */
#define pp_formatted_text_data(PP) \
- ((const char *) obstack_base (pp_base (PP)->buffer->obstack))
+ ((const char *) obstack_base (pp_buffer (PP)->obstack))
/* Format an integer given by va_arg (ARG, type-specifier T) where
type-specifier is a precision modifier as indicated by PREC. F is
@@ -95,7 +120,7 @@ void
pp_write_text_to_stream (pretty_printer *pp)
{
const char *text = pp_formatted_text (pp);
- fputs (text, pp->buffer->stream);
+ fputs (text, pp_buffer (pp)->stream);
pp_clear_output_area (pp);
}
@@ -113,7 +138,7 @@ pp_write_text_as_dot_label_to_stream (pretty_printer *pp, bool for_record)
{
const char *text = pp_formatted_text (pp);
const char *p = text;
- FILE *fp = pp->buffer->stream;
+ FILE *fp = pp_buffer (pp)->stream;
while (*p)
{
@@ -199,15 +224,15 @@ pp_maybe_wrap_text (pretty_printer *pp, const char *start, const char *end)
static inline void
pp_append_r (pretty_printer *pp, const char *start, int length)
{
- obstack_grow (pp->buffer->obstack, start, length);
- pp->buffer->line_length += length;
+ obstack_grow (pp_buffer (pp)->obstack, start, length);
+ pp_buffer (pp)->line_length += length;
}
/* Insert enough spaces into the output area of PRETTY-PRINTER to bring
the column position to the current indentation level, assuming that a
newline has just been written to the buffer. */
void
-pp_base_indent (pretty_printer *pp)
+pp_indent (pretty_printer *pp)
{
int n = pp_indentation (pp);
int i;
@@ -251,13 +276,13 @@ pp_base_indent (pretty_printer *pp)
A format string can have at most 30 arguments. */
/* Formatting phases 1 and 2: render TEXT->format_spec plus
- TEXT->args_ptr into a series of chunks in PP->buffer->args[].
- Phase 3 is in pp_base_format_text. */
+ TEXT->args_ptr into a series of chunks in pp_buffer (PP)->args[].
+ Phase 3 is in pp_format_text. */
void
-pp_base_format (pretty_printer *pp, text_info *text)
+pp_format (pretty_printer *pp, text_info *text)
{
- output_buffer *buffer = pp->buffer;
+ output_buffer *buffer = pp_buffer (pp);
const char *p;
const char **args;
struct chunk_info *new_chunk_array;
@@ -274,7 +299,7 @@ pp_base_format (pretty_printer *pp, text_info *text)
args = new_chunk_array->args;
/* Formatting phase 1: split up TEXT->format_spec into chunks in
- PP->buffer->args[]. Even-numbered chunks are to be output
+ pp_buffer (PP)->args[]. Even-numbered chunks are to be output
verbatim, odd-numbered chunks are format specifiers.
%m, %%, %<, %>, and %' are replaced with the appropriate text at
this point. */
@@ -617,7 +642,7 @@ pp_base_format (pretty_printer *pp, text_info *text)
/* Format of a message pointed to by TEXT. */
void
-pp_base_output_formatted_text (pretty_printer *pp)
+pp_output_formatted_text (pretty_printer *pp)
{
unsigned int chunk;
output_buffer *buffer = pp_buffer (pp);
@@ -627,7 +652,7 @@ pp_base_output_formatted_text (pretty_printer *pp)
gcc_assert (buffer->obstack == &buffer->formatted_obstack);
gcc_assert (buffer->line_length == 0);
- /* This is a third phase, first 2 phases done in pp_base_format_args.
+ /* This is a third phase, first 2 phases done in pp_format_args.
Now we actually print it. */
for (chunk = 0; args[chunk]; chunk++)
pp_string (pp, args[chunk]);
@@ -641,7 +666,7 @@ pp_base_output_formatted_text (pretty_printer *pp)
/* Helper subroutine of output_verbatim and verbatim. Do the appropriate
settings needed by BUFFER for a verbatim formatting. */
void
-pp_base_format_verbatim (pretty_printer *pp, text_info *text)
+pp_format_verbatim (pretty_printer *pp, text_info *text)
{
/* Set verbatim mode. */
pp_wrapping_mode_t oldmode = pp_set_verbatim_wrapping (pp);
@@ -656,18 +681,18 @@ pp_base_format_verbatim (pretty_printer *pp, text_info *text)
/* Flush the content of BUFFER onto the attached stream. */
void
-pp_base_flush (pretty_printer *pp)
+pp_flush (pretty_printer *pp)
{
pp_write_text_to_stream (pp);
pp_clear_state (pp);
- fflush (pp->buffer->stream);
+ fflush (pp_buffer (pp)->stream);
}
/* Sets the number of maximum characters per line PRETTY-PRINTER can
output in line-wrapping mode. A LENGTH value 0 suppresses
line-wrapping. */
void
-pp_base_set_line_maximum_length (pretty_printer *pp, int length)
+pp_set_line_maximum_length (pretty_printer *pp, int length)
{
pp_line_cutoff (pp) = length;
pp_set_real_maximum_length (pp);
@@ -675,15 +700,16 @@ pp_base_set_line_maximum_length (pretty_printer *pp, int length)
/* Clear PRETTY-PRINTER output area text info. */
void
-pp_base_clear_output_area (pretty_printer *pp)
+pp_clear_output_area (pretty_printer *pp)
{
- obstack_free (pp->buffer->obstack, obstack_base (pp->buffer->obstack));
- pp->buffer->line_length = 0;
+ obstack_free (pp_buffer (pp)->obstack,
+ obstack_base (pp_buffer (pp)->obstack));
+ pp_buffer (pp)->line_length = 0;
}
/* Set PREFIX for PRETTY-PRINTER. */
void
-pp_base_set_prefix (pretty_printer *pp, const char *prefix)
+pp_set_prefix (pretty_printer *pp, const char *prefix)
{
pp->prefix = prefix;
pp_set_real_maximum_length (pp);
@@ -693,7 +719,7 @@ pp_base_set_prefix (pretty_printer *pp, const char *prefix)
/* Free PRETTY-PRINTER's prefix, a previously malloc()'d string. */
void
-pp_base_destroy_prefix (pretty_printer *pp)
+pp_destroy_prefix (pretty_printer *pp)
{
if (pp->prefix != NULL)
{
@@ -704,7 +730,7 @@ pp_base_destroy_prefix (pretty_printer *pp)
/* Write out PRETTY-PRINTER's prefix. */
void
-pp_base_emit_prefix (pretty_printer *pp)
+pp_emit_prefix (pretty_printer *pp)
{
if (pp->prefix != NULL)
{
@@ -717,7 +743,7 @@ pp_base_emit_prefix (pretty_printer *pp)
case DIAGNOSTICS_SHOW_PREFIX_ONCE:
if (pp->emitted_prefix)
{
- pp_base_indent (pp);
+ pp_indent (pp);
break;
}
pp_indentation (pp) += 3;
@@ -736,19 +762,30 @@ pp_base_emit_prefix (pretty_printer *pp)
/* Construct a PRETTY-PRINTER with PREFIX and of MAXIMUM_LENGTH
characters per line. */
-void
-pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
+
+pretty_printer::pretty_printer (const char *p, int l)
+ : buffer (new (XCNEW (output_buffer)) output_buffer ()),
+ prefix (),
+ padding (pp_none),
+ maximum_length (),
+ indent_skip (),
+ wrapping (),
+ format_decoder (),
+ emitted_prefix (),
+ need_newline (),
+ translate_identifiers(true),
+ show_color ()
+{
+ pp_line_cutoff (this) = l;
+ /* By default, we emit prefixes once per message. */
+ pp_prefixing_rule (this) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
+ pp_set_prefix (this, p);
+}
+
+pretty_printer::~pretty_printer ()
{
- memset (pp, 0, sizeof (pretty_printer));
- pp->buffer = XCNEW (output_buffer);
- obstack_init (&pp->buffer->chunk_obstack);
- obstack_init (&pp->buffer->formatted_obstack);
- pp->buffer->obstack = &pp->buffer->formatted_obstack;
- pp->buffer->stream = stderr;
- pp_line_cutoff (pp) = maximum_length;
- pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
- pp_set_prefix (pp, prefix);
- pp_translate_identifiers (pp) = true;
+ buffer->~output_buffer ();
+ XDELETE (buffer);
}
/* Append a string delimited by START and END to the output area of
@@ -757,10 +794,10 @@ pp_construct (pretty_printer *pp, const char *prefix, int maximum_length)
whitespace if appropriate. The caller must ensure that it is
safe to do so. */
void
-pp_base_append_text (pretty_printer *pp, const char *start, const char *end)
+pp_append_text (pretty_printer *pp, const char *start, const char *end)
{
/* Emit prefix and skip whitespace if we're starting a new line. */
- if (pp->buffer->line_length == 0)
+ if (pp_buffer (pp)->line_length == 0)
{
pp_emit_prefix (pp);
if (pp_is_wrapping_line (pp))
@@ -773,19 +810,19 @@ pp_base_append_text (pretty_printer *pp, const char *start, const char *end)
/* Finishes constructing a NULL-terminated character string representing
the PRETTY-PRINTED text. */
const char *
-pp_base_formatted_text (pretty_printer *pp)
+pp_formatted_text (pretty_printer *pp)
{
- obstack_1grow (pp->buffer->obstack, '\0');
+ obstack_1grow (pp_buffer (pp)->obstack, '\0');
return pp_formatted_text_data (pp);
}
/* Return a pointer to the last character emitted in PRETTY-PRINTER's
output area. A NULL pointer means no character available. */
const char *
-pp_base_last_position_in_text (const pretty_printer *pp)
+pp_last_position_in_text (const pretty_printer *pp)
{
const char *p = NULL;
- struct obstack *text = pp->buffer->obstack;
+ struct obstack *text = pp_buffer (pp)->obstack;
if (obstack_base (text) != obstack_next_free (text))
p = ((const char *) obstack_next_free (text)) - 1;
@@ -795,9 +832,9 @@ pp_base_last_position_in_text (const pretty_printer *pp)
/* Return the amount of characters PRETTY-PRINTER can accept to
make a full line. Meaningful only in line-wrapping mode. */
int
-pp_base_remaining_character_count_for_line (pretty_printer *pp)
+pp_remaining_character_count_for_line (pretty_printer *pp)
{
- return pp->maximum_length - pp->buffer->line_length;
+ return pp->maximum_length - pp_buffer (pp)->line_length;
}
@@ -839,16 +876,16 @@ pp_verbatim (pretty_printer *pp, const char *msg, ...)
/* Have PRETTY-PRINTER start a new line. */
void
-pp_base_newline (pretty_printer *pp)
+pp_newline (pretty_printer *pp)
{
- obstack_1grow (pp->buffer->obstack, '\n');
+ obstack_1grow (pp_buffer (pp)->obstack, '\n');
pp_needs_newline (pp) = false;
- pp->buffer->line_length = 0;
+ pp_buffer (pp)->line_length = 0;
}
/* Have PRETTY-PRINTER add a CHARACTER. */
void
-pp_base_character (pretty_printer *pp, int c)
+pp_character (pretty_printer *pp, int c)
{
if (pp_is_wrapping_line (pp)
&& pp_remaining_character_count_for_line (pp) <= 0)
@@ -857,14 +894,14 @@ pp_base_character (pretty_printer *pp, int c)
if (ISSPACE (c))
return;
}
- obstack_1grow (pp->buffer->obstack, c);
- ++pp->buffer->line_length;
+ obstack_1grow (pp_buffer (pp)->obstack, c);
+ ++pp_buffer (pp)->line_length;
}
/* Append a STRING to the output area of PRETTY-PRINTER; the STRING may
be line-wrapped if in appropriate mode. */
void
-pp_base_string (pretty_printer *pp, const char *str)
+pp_string (pretty_printer *pp, const char *str)
{
pp_maybe_wrap_text (pp, str, str + (str ? strlen (str) : 0));
}
@@ -872,14 +909,45 @@ pp_base_string (pretty_printer *pp, const char *str)
/* Maybe print out a whitespace if needed. */
void
-pp_base_maybe_space (pretty_printer *pp)
+pp_maybe_space (pretty_printer *pp)
{
- if (pp_base (pp)->padding != pp_none)
+ if (pp->padding != pp_none)
{
pp_space (pp);
- pp_base (pp)->padding = pp_none;
+ pp->padding = pp_none;
}
}
+
+// Add a newline to the pretty printer PP and flush formatted text.
+
+void
+pp_newline_and_flush (pretty_printer *pp)
+{
+ pp_newline (pp);
+ pp_flush (pp);
+ pp_needs_newline (pp) = false;
+}
+
+// Add a newline to the pretty printer PP, followed by indentation.
+
+void
+pp_newline_and_indent (pretty_printer *pp, int n)
+{
+ pp_indentation (pp) += n;
+ pp_newline (pp);
+ pp_indent (pp);
+ pp_needs_newline (pp) = false;
+}
+
+// Add separator C, followed by a single whitespace.
+
+void
+pp_separate_with (pretty_printer *pp, char c)
+{
+ pp_character (pp, c);
+ pp_space (pp);
+}
+
/* The string starting at P has LEN (at least 1) bytes left; if they
start with a valid UTF-8 sequence, return the length of that
diff --git a/gcc/pretty-print.h b/gcc/pretty-print.h
index 13bb2dede90..a60be3285ea 100644
--- a/gcc/pretty-print.h
+++ b/gcc/pretty-print.h
@@ -29,30 +29,30 @@ along with GCC; see the file COPYING3. If not see
/* The type of a text to be formatted according a format specification
along with a list of things. */
-typedef struct
+struct text_info
{
const char *format_spec;
va_list *args_ptr;
int err_no; /* for %m */
location_t *locus;
void **x_data;
-} text_info;
+};
/* How often diagnostics are prefixed by their locations:
o DIAGNOSTICS_SHOW_PREFIX_NEVER: never - not yet supported;
o DIAGNOSTICS_SHOW_PREFIX_ONCE: emit only once;
o DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE: emit each time a physical
line is started. */
-typedef enum
+enum diagnostic_prefixing_rule_t
{
DIAGNOSTICS_SHOW_PREFIX_ONCE = 0x0,
DIAGNOSTICS_SHOW_PREFIX_NEVER = 0x1,
DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE = 0x2
-} diagnostic_prefixing_rule_t;
+};
/* The chunk_info data structure forms a stack of the results from the
- first phase of formatting (pp_base_format) which have not yet been
- output (pp_base_output_formatted_text). A stack is necessary because
+ first phase of formatting (pp_format) which have not yet been
+ output (pp_output_formatted_text). A stack is necessary because
the diagnostic starter may decide to generate its own output by way
of the formatter. */
struct chunk_info
@@ -71,8 +71,11 @@ struct chunk_info
/* The output buffer datatype. This is best seen as an abstract datatype
whose fields should not be accessed directly by clients. */
-typedef struct
+struct output_buffer
{
+ output_buffer ();
+ ~output_buffer ();
+
/* Obstack where the text is built up. */
struct obstack formatted_obstack;
@@ -96,19 +99,19 @@ typedef struct
/* This must be large enough to hold any printed integer or
floating-point value. */
char digit_buffer[128];
-} output_buffer;
+};
/* The type of pretty-printer flags passed to clients. */
typedef unsigned int pp_flags;
-typedef enum
+enum pp_padding
{
pp_none, pp_before, pp_after
-} pp_padding;
+};
/* Structure for switching in and out of verbatim mode in a convenient
manner. */
-typedef struct
+struct pp_wrapping_mode_t
{
/* Current prefixing rule. */
diagnostic_prefixing_rule_t rule;
@@ -116,17 +119,17 @@ typedef struct
/* The ideal upper bound of number of characters per line, as suggested
by front-end. */
int line_cutoff;
-} pp_wrapping_mode_t;
+};
/* Maximum characters per line in automatic line wrapping mode.
Zero means don't wrap lines. */
-#define pp_line_cutoff(PP) pp_base (PP)->wrapping.line_cutoff
+#define pp_line_cutoff(PP) (PP)->wrapping.line_cutoff
/* Prefixing rule used in formatting a diagnostic message. */
-#define pp_prefixing_rule(PP) pp_base (PP)->wrapping.rule
+#define pp_prefixing_rule(PP) (PP)->wrapping.rule
/* Get or set the wrapping mode as a single entity. */
-#define pp_wrapping_mode(PP) pp_base (PP)->wrapping
+#define pp_wrapping_mode(PP) (PP)->wrapping
/* The type of a hook that formats client-specific data onto a pretty_pinter.
A client-supplied formatter returns true if everything goes well,
@@ -135,30 +138,36 @@ typedef bool (*printer_fn) (pretty_printer *, text_info *, const char *,
int, bool, bool, bool);
/* Client supplied function used to decode formats. */
-#define pp_format_decoder(PP) pp_base (PP)->format_decoder
+#define pp_format_decoder(PP) (PP)->format_decoder
/* TRUE if a newline character needs to be added before further
formatting. */
-#define pp_needs_newline(PP) pp_base (PP)->need_newline
+#define pp_needs_newline(PP) (PP)->need_newline
/* True if PRETTY-PRINTER is in line-wrapping mode. */
#define pp_is_wrapping_line(PP) (pp_line_cutoff (PP) > 0)
/* The amount of whitespace to be emitted when starting a new line. */
-#define pp_indentation(PP) pp_base (PP)->indent_skip
+#define pp_indentation(PP) (PP)->indent_skip
/* True if identifiers are translated to the locale character set on
output. */
-#define pp_translate_identifiers(PP) pp_base (PP)->translate_identifiers
+#define pp_translate_identifiers(PP) (PP)->translate_identifiers
/* True if colors should be shown. */
-#define pp_show_color(PP) pp_base (PP)->show_color
+#define pp_show_color(PP) (PP)->show_color
/* The data structure that contains the bare minimum required to do
proper pretty-printing. Clients may derived from this structure
and add additional fields they need. */
-struct pretty_print_info
+struct pretty_printer
{
+ // Default construct a pretty printer with specified prefix
+ // and a maximum line length cut off limit.
+ explicit pretty_printer (const char* = NULL, int = 0);
+
+ virtual ~pretty_printer ();
+
/* Where we print external representation of ENTITY. */
output_buffer *buffer;
@@ -202,33 +211,8 @@ struct pretty_print_info
bool show_color;
};
-#define pp_set_line_maximum_length(PP, L) \
- pp_base_set_line_maximum_length (pp_base (PP), L)
-#define pp_set_prefix(PP, P) pp_base_set_prefix (pp_base (PP), P)
-#define pp_get_prefix(PP) pp_base_get_prefix (pp_base (PP))
static inline const char *
-pp_base_get_prefix (const pretty_printer *pp) { return pp->prefix; }
-#define pp_destroy_prefix(PP) pp_base_destroy_prefix (pp_base (PP))
-#define pp_remaining_character_count_for_line(PP) \
- pp_base_remaining_character_count_for_line (pp_base (PP))
-#define pp_clear_output_area(PP) \
- pp_base_clear_output_area (pp_base (PP))
-#define pp_formatted_text(PP) pp_base_formatted_text (pp_base (PP))
-#define pp_last_position_in_text(PP) \
- pp_base_last_position_in_text (pp_base (PP))
-#define pp_emit_prefix(PP) pp_base_emit_prefix (pp_base (PP))
-#define pp_append_text(PP, B, E) \
- pp_base_append_text (pp_base (PP), B, E)
-#define pp_flush(PP) pp_base_flush (pp_base (PP))
-#define pp_format(PP, TI) pp_base_format (pp_base (PP), TI)
-#define pp_output_formatted_text(PP) \
- pp_base_output_formatted_text (pp_base (PP))
-#define pp_format_verbatim(PP, TI) \
- pp_base_format_verbatim (pp_base (PP), TI)
-
-#define pp_character(PP, C) pp_base_character (pp_base (PP), C)
-#define pp_string(PP, S) pp_base_string (pp_base (PP), S)
-#define pp_newline(PP) pp_base_newline (pp_base (PP))
+pp_get_prefix (const pretty_printer *pp) { return pp->prefix; }
#define pp_space(PP) pp_character (PP, ' ')
#define pp_left_paren(PP) pp_character (PP, '(')
@@ -238,7 +222,7 @@ pp_base_get_prefix (const pretty_printer *pp) { return pp->prefix; }
#define pp_left_brace(PP) pp_character (PP, '{')
#define pp_right_brace(PP) pp_character (PP, '}')
#define pp_semicolon(PP) pp_character (PP, ';')
-#define pp_comma(PP) pp_string (PP, ", ")
+#define pp_comma(PP) pp_character (PP, ',')
#define pp_dot(PP) pp_character (PP, '.')
#define pp_colon(PP) pp_character (PP, ':')
#define pp_colon_colon(PP) pp_string (PP, "::")
@@ -246,10 +230,14 @@ pp_base_get_prefix (const pretty_printer *pp) { return pp->prefix; }
#define pp_equal(PP) pp_character (PP, '=')
#define pp_question(PP) pp_character (PP, '?')
#define pp_bar(PP) pp_character (PP, '|')
+#define pp_bar_bar(PP) pp_string (PP, "||")
#define pp_carret(PP) pp_character (PP, '^')
#define pp_ampersand(PP) pp_character (PP, '&')
+#define pp_ampersand_ampersand(PP) pp_string (PP, "&&")
#define pp_less(PP) pp_character (PP, '<')
+#define pp_less_equal(PP) pp_string (PP, "<=")
#define pp_greater(PP) pp_character (PP, '>')
+#define pp_greater_equal(PP) pp_string (PP, ">=")
#define pp_plus(PP) pp_character (PP, '+')
#define pp_minus(PP) pp_character (PP, '-')
#define pp_star(PP) pp_character (PP, '*')
@@ -260,27 +248,9 @@ pp_base_get_prefix (const pretty_printer *pp) { return pp->prefix; }
#define pp_quote(PP) pp_character (PP, '\'')
#define pp_backquote(PP) pp_character (PP, '`')
#define pp_doublequote(PP) pp_character (PP, '"')
-#define pp_newline_and_flush(PP) \
- do { \
- pp_newline (PP); \
- pp_flush (PP); \
- pp_needs_newline (PP) = false; \
- } while (0)
-#define pp_newline_and_indent(PP, N) \
- do { \
- pp_indentation (PP) += N; \
- pp_newline (PP); \
- pp_base_indent (pp_base (PP)); \
- pp_needs_newline (PP) = false; \
- } while (0)
+#define pp_underscore(PP) pp_character (PP, '_')
#define pp_maybe_newline_and_indent(PP, N) \
if (pp_needs_newline (PP)) pp_newline_and_indent (PP, N)
-#define pp_maybe_space(PP) pp_base_maybe_space (pp_base (PP))
-#define pp_separate_with(PP, C) \
- do { \
- pp_character (PP, C); \
- pp_space (PP); \
- } while (0)
#define pp_scalar(PP, FORMAT, SCALAR) \
do \
{ \
@@ -302,21 +272,20 @@ pp_base_get_prefix (const pretty_printer *pp) { return pp->prefix; }
: (ID)))
-#define pp_buffer(PP) pp_base (PP)->buffer
-/* Clients that directly derive from pretty_printer need to override
- this macro to return a pointer to the base pretty_printer structure. */
-#define pp_base(PP) (PP)
+#define pp_buffer(PP) (PP)->buffer
-extern void pp_construct (pretty_printer *, const char *, int);
-extern void pp_base_set_line_maximum_length (pretty_printer *, int);
-extern void pp_base_set_prefix (pretty_printer *, const char *);
-extern void pp_base_destroy_prefix (pretty_printer *);
-extern int pp_base_remaining_character_count_for_line (pretty_printer *);
-extern void pp_base_clear_output_area (pretty_printer *);
-extern const char *pp_base_formatted_text (pretty_printer *);
-extern const char *pp_base_last_position_in_text (const pretty_printer *);
-extern void pp_base_emit_prefix (pretty_printer *);
-extern void pp_base_append_text (pretty_printer *, const char *, const char *);
+extern void pp_set_line_maximum_length (pretty_printer *, int);
+extern void pp_set_prefix (pretty_printer *, const char *);
+extern void pp_destroy_prefix (pretty_printer *);
+extern int pp_remaining_character_count_for_line (pretty_printer *);
+extern void pp_clear_output_area (pretty_printer *);
+extern const char *pp_formatted_text (pretty_printer *);
+extern const char *pp_last_position_in_text (const pretty_printer *);
+extern void pp_emit_prefix (pretty_printer *);
+extern void pp_append_text (pretty_printer *, const char *, const char *);
+extern void pp_newline_and_flush (pretty_printer *);
+extern void pp_newline_and_indent (pretty_printer *, int);
+extern void pp_separate_with (pretty_printer *, char);
/* If we haven't already defined a front-end-specific diagnostics
style, use the generic one. */
@@ -338,18 +307,18 @@ extern void pp_printf (pretty_printer *, const char *, ...)
extern void pp_verbatim (pretty_printer *, const char *, ...)
ATTRIBUTE_GCC_PPDIAG(2,3);
-extern void pp_base_flush (pretty_printer *);
-extern void pp_base_format (pretty_printer *, text_info *);
-extern void pp_base_output_formatted_text (pretty_printer *);
-extern void pp_base_format_verbatim (pretty_printer *, text_info *);
-
-extern void pp_base_indent (pretty_printer *);
-extern void pp_base_newline (pretty_printer *);
-extern void pp_base_character (pretty_printer *, int);
-extern void pp_base_string (pretty_printer *, const char *);
+extern void pp_flush (pretty_printer *);
+extern void pp_format (pretty_printer *, text_info *);
+extern void pp_output_formatted_text (pretty_printer *);
+extern void pp_format_verbatim (pretty_printer *, text_info *);
+
+extern void pp_indent (pretty_printer *);
+extern void pp_newline (pretty_printer *);
+extern void pp_character (pretty_printer *, int);
+extern void pp_string (pretty_printer *, const char *);
extern void pp_write_text_to_stream (pretty_printer *);
extern void pp_write_text_as_dot_label_to_stream (pretty_printer *, bool);
-extern void pp_base_maybe_space (pretty_printer *);
+extern void pp_maybe_space (pretty_printer *);
/* Switch into verbatim mode and return the old mode. */
static inline pp_wrapping_mode_t
@@ -360,7 +329,7 @@ pp_set_verbatim_wrapping_ (pretty_printer *pp)
pp_prefixing_rule (pp) = DIAGNOSTICS_SHOW_PREFIX_NEVER;
return oldmode;
}
-#define pp_set_verbatim_wrapping(PP) pp_set_verbatim_wrapping_ (pp_base (PP))
+#define pp_set_verbatim_wrapping(PP) pp_set_verbatim_wrapping_ (PP)
extern const char *identifier_to_locale (const char *);
extern void *(*identifier_to_locale_alloc) (size_t);
diff --git a/gcc/print-tree.c b/gcc/print-tree.c
index 029c3a25e6d..1ee27428714 100644
--- a/gcc/print-tree.c
+++ b/gcc/print-tree.c
@@ -409,8 +409,6 @@ print_node (FILE *file, const char *prefix, tree node, int indent)
if (code == FIELD_DECL && DECL_NONADDRESSABLE_P (node))
fputs (" nonaddressable", file);
- if (code == LABEL_DECL && DECL_ERROR_ISSUED (node))
- fputs (" error-issued", file);
if (code == LABEL_DECL && EH_LANDING_PAD_NR (node))
fprintf (file, " landing-pad:%d", EH_LANDING_PAD_NR (node));
diff --git a/gcc/profile.c b/gcc/profile.c
index b8333987e02..2abde8aec03 100644
--- a/gcc/profile.c
+++ b/gcc/profile.c
@@ -432,8 +432,8 @@ read_profile_edge_counts (gcov_type *exec_counts)
if (flag_profile_correction)
{
static bool informed = 0;
- if (!informed)
- inform (input_location,
+ if (dump_enabled_p () && !informed)
+ dump_printf_loc (MSG_NOTE, input_location,
"corrupted profile info: edge count exceeds maximal count");
informed = 1;
}
@@ -692,10 +692,11 @@ compute_branch_probabilities (unsigned cfg_checksum, unsigned lineno_checksum)
{
/* Inconsistency detected. Make it flow-consistent. */
static int informed = 0;
- if (informed == 0)
+ if (dump_enabled_p () && informed == 0)
{
informed = 1;
- inform (input_location, "correcting inconsistent profile data");
+ dump_printf_loc (MSG_NOTE, input_location,
+ "correcting inconsistent profile data");
}
correct_negative_edge_counts ();
/* Set bb counts to the sum of the outgoing edge counts */
@@ -885,12 +886,16 @@ compute_value_histograms (histogram_values values, unsigned cfg_checksum,
t = (int) hist->type;
aact_count = act_count[t];
- act_count[t] += hist->n_counters;
+ if (act_count[t])
+ act_count[t] += hist->n_counters;
gimple_add_histogram_value (cfun, stmt, hist);
hist->hvalue.counters = XNEWVEC (gcov_type, hist->n_counters);
for (j = 0; j < hist->n_counters; j++)
- hist->hvalue.counters[j] = aact_count[j];
+ if (aact_count)
+ hist->hvalue.counters[j] = aact_count[j];
+ else
+ hist->hvalue.counters[j] = 0;
}
for (t = 0; t < GCOV_N_VALUE_COUNTERS; t++)
diff --git a/gcc/profile.h b/gcc/profile.h
index d0b637de53b..b31cf7869b5 100644
--- a/gcc/profile.h
+++ b/gcc/profile.h
@@ -43,7 +43,7 @@ extern void mcf_smooth_cfg (void);
extern gcov_type sum_edge_counts (vec<edge, va_gc> *edges);
-extern void init_node_map (void);
+extern void init_node_map (bool);
extern void del_node_map (void);
extern void get_working_sets (void);
diff --git a/gcc/recog.c b/gcc/recog.c
index 6a607ba2a5a..690b20e4751 100644
--- a/gcc/recog.c
+++ b/gcc/recog.c
@@ -397,7 +397,10 @@ verify_changes (int num)
MEM_ADDR_SPACE (object)))
break;
}
- else if (REG_P (changes[i].old)
+ else if (/* changes[i].old might be zero, e.g. when putting a
+ REG_FRAME_RELATED_EXPR into a previously empty list. */
+ changes[i].old
+ && REG_P (changes[i].old)
&& asm_noperands (PATTERN (object)) > 0
&& REG_EXPR (changes[i].old) != NULL_TREE
&& DECL_ASSEMBLER_NAME_SET_P (REG_EXPR (changes[i].old))
@@ -3124,32 +3127,53 @@ peep2_find_free_register (int from, int to, const char *class_str,
regno = raw_regno;
#endif
- /* Don't allocate fixed registers. */
- if (fixed_regs[regno])
- continue;
- /* Don't allocate global registers. */
- if (global_regs[regno])
- continue;
- /* Make sure the register is of the right class. */
- if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno))
- continue;
- /* And can support the mode we need. */
+ /* Can it support the mode we need? */
if (! HARD_REGNO_MODE_OK (regno, mode))
continue;
- /* And that we don't create an extra save/restore. */
- if (! call_used_regs[regno] && ! df_regs_ever_live_p (regno))
- continue;
- if (! targetm.hard_regno_scratch_ok (regno))
- continue;
-
- /* And we don't clobber traceback for noreturn functions. */
- if ((regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM)
- && (! reload_completed || frame_pointer_needed))
- continue;
success = 1;
- for (j = hard_regno_nregs[regno][mode] - 1; j >= 0; j--)
+ for (j = 0; success && j < hard_regno_nregs[regno][mode]; j++)
{
+ /* Don't allocate fixed registers. */
+ if (fixed_regs[regno + j])
+ {
+ success = 0;
+ break;
+ }
+ /* Don't allocate global registers. */
+ if (global_regs[regno + j])
+ {
+ success = 0;
+ break;
+ }
+ /* Make sure the register is of the right class. */
+ if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j))
+ {
+ success = 0;
+ break;
+ }
+ /* And that we don't create an extra save/restore. */
+ if (! call_used_regs[regno + j] && ! df_regs_ever_live_p (regno + j))
+ {
+ success = 0;
+ break;
+ }
+
+ if (! targetm.hard_regno_scratch_ok (regno + j))
+ {
+ success = 0;
+ break;
+ }
+
+ /* And we don't clobber traceback for noreturn functions. */
+ if ((regno + j == FRAME_POINTER_REGNUM
+ || regno + j == HARD_FRAME_POINTER_REGNUM)
+ && (! reload_completed || frame_pointer_needed))
+ {
+ success = 0;
+ break;
+ }
+
if (TEST_HARD_REG_BIT (*reg_set, regno + j)
|| TEST_HARD_REG_BIT (live, regno + j))
{
@@ -3157,6 +3181,7 @@ peep2_find_free_register (int from, int to, const char *class_str,
break;
}
}
+
if (success)
{
add_to_hard_reg_set (reg_set, mode, regno);
@@ -3756,27 +3781,47 @@ rest_of_handle_peephole2 (void)
return 0;
}
-struct rtl_opt_pass pass_peephole2 =
-{
- {
- RTL_PASS,
- "peephole2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_peephole2, /* gate */
- rest_of_handle_peephole2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_PEEPHOLE2, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_peephole2 =
+{
+ RTL_PASS, /* type */
+ "peephole2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_PEEPHOLE2, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */
};
+class pass_peephole2 : public rtl_opt_pass
+{
+public:
+ pass_peephole2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_peephole2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ /* The epiphany backend creates a second instance of this pass, so we need
+ a clone method. */
+ opt_pass * clone () { return new pass_peephole2 (ctxt_); }
+ bool gate () { return gate_handle_peephole2 (); }
+ unsigned int execute () { return rest_of_handle_peephole2 (); }
+
+}; // class pass_peephole2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_peephole2 (gcc::context *ctxt)
+{
+ return new pass_peephole2 (ctxt);
+}
+
static unsigned int
rest_of_handle_split_all_insns (void)
{
@@ -3784,26 +3829,46 @@ rest_of_handle_split_all_insns (void)
return 0;
}
-struct rtl_opt_pass pass_split_all_insns =
-{
- {
- RTL_PASS,
- "split1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_split_all_insns, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_split_all_insns =
+{
+ RTL_PASS, /* type */
+ "split1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_split_all_insns : public rtl_opt_pass
+{
+public:
+ pass_split_all_insns(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_split_all_insns, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ /* The epiphany backend creates a second instance of this pass, so
+ we need a clone method. */
+ opt_pass * clone () { return new pass_split_all_insns (ctxt_); }
+ unsigned int execute () { return rest_of_handle_split_all_insns (); }
+
+}; // class pass_split_all_insns
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_split_all_insns (gcc::context *ctxt)
+{
+ return new pass_split_all_insns (ctxt);
+}
+
static unsigned int
rest_of_handle_split_after_reload (void)
{
@@ -3815,26 +3880,43 @@ rest_of_handle_split_after_reload (void)
return 0;
}
-struct rtl_opt_pass pass_split_after_reload =
-{
- {
- RTL_PASS,
- "split2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_split_after_reload, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_split_after_reload =
+{
+ RTL_PASS, /* type */
+ "split2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_split_after_reload : public rtl_opt_pass
+{
+public:
+ pass_split_after_reload(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_split_after_reload, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_split_after_reload (); }
+
+}; // class pass_split_after_reload
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_split_after_reload (gcc::context *ctxt)
+{
+ return new pass_split_after_reload (ctxt);
+}
+
static bool
gate_handle_split_before_regstack (void)
{
@@ -3860,26 +3942,46 @@ rest_of_handle_split_before_regstack (void)
return 0;
}
-struct rtl_opt_pass pass_split_before_regstack =
-{
- {
- RTL_PASS,
- "split3", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_split_before_regstack, /* gate */
- rest_of_handle_split_before_regstack, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_split_before_regstack =
+{
+ RTL_PASS, /* type */
+ "split3", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_split_before_regstack : public rtl_opt_pass
+{
+public:
+ pass_split_before_regstack(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_split_before_regstack, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_split_before_regstack (); }
+ unsigned int execute () {
+ return rest_of_handle_split_before_regstack ();
+ }
+
+}; // class pass_split_before_regstack
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_split_before_regstack (gcc::context *ctxt)
+{
+ return new pass_split_before_regstack (ctxt);
+}
+
static bool
gate_handle_split_before_sched2 (void)
{
@@ -3899,26 +4001,44 @@ rest_of_handle_split_before_sched2 (void)
return 0;
}
-struct rtl_opt_pass pass_split_before_sched2 =
-{
- {
- RTL_PASS,
- "split4", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_split_before_sched2, /* gate */
- rest_of_handle_split_before_sched2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_split_before_sched2 =
+{
+ RTL_PASS, /* type */
+ "split4", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_flow, /* todo_flags_finish */
};
+class pass_split_before_sched2 : public rtl_opt_pass
+{
+public:
+ pass_split_before_sched2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_split_before_sched2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_split_before_sched2 (); }
+ unsigned int execute () { return rest_of_handle_split_before_sched2 (); }
+
+}; // class pass_split_before_sched2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_split_before_sched2 (gcc::context *ctxt)
+{
+ return new pass_split_before_sched2 (ctxt);
+}
+
/* The placement of the splitting that we do for shorten_branches
depends on whether regstack is used by the target or not. */
static bool
@@ -3931,22 +4051,40 @@ gate_do_final_split (void)
#endif
}
-struct rtl_opt_pass pass_split_for_shorten_branches =
-{
- {
- RTL_PASS,
- "split5", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_do_final_split, /* gate */
- split_all_insns_noflow, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_split_for_shorten_branches =
+{
+ RTL_PASS, /* type */
+ "split5", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_rtl_sharing, /* todo_flags_finish */
};
+
+class pass_split_for_shorten_branches : public rtl_opt_pass
+{
+public:
+ pass_split_for_shorten_branches(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_split_for_shorten_branches, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_do_final_split (); }
+ unsigned int execute () { return split_all_insns_noflow (); }
+
+}; // class pass_split_for_shorten_branches
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_split_for_shorten_branches (gcc::context *ctxt)
+{
+ return new pass_split_for_shorten_branches (ctxt);
+}
diff --git a/gcc/recog.h b/gcc/recog.h
index 71e801edb2d..550a2174578 100644
--- a/gcc/recog.h
+++ b/gcc/recog.h
@@ -256,7 +256,57 @@ extern struct operand_alternative recog_op_alt[MAX_RECOG_OPERANDS][MAX_RECOG_ALT
typedef int (*insn_operand_predicate_fn) (rtx, enum machine_mode);
typedef const char * (*insn_output_fn) (rtx *, rtx);
-typedef rtx (*insn_gen_fn) (rtx, ...);
+
+struct insn_gen_fn
+{
+ typedef rtx (*f0) (void);
+ typedef rtx (*f1) (rtx);
+ typedef rtx (*f2) (rtx, rtx);
+ typedef rtx (*f3) (rtx, rtx, rtx);
+ typedef rtx (*f4) (rtx, rtx, rtx, rtx);
+ typedef rtx (*f5) (rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f6) (rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f7) (rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f8) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f9) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f10) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f11) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f12) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f13) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f14) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f15) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+ typedef rtx (*f16) (rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx, rtx);
+
+ typedef f0 stored_funcptr;
+
+ rtx operator () (void) const { return ((f0)func) (); }
+ rtx operator () (rtx a0) const { return ((f1)func) (a0); }
+ rtx operator () (rtx a0, rtx a1) const { return ((f2)func) (a0, a1); }
+ rtx operator () (rtx a0, rtx a1, rtx a2) const { return ((f3)func) (a0, a1, a2); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3) const { return ((f4)func) (a0, a1, a2, a3); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4) const { return ((f5)func) (a0, a1, a2, a3, a4); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5) const { return ((f6)func) (a0, a1, a2, a3, a4, a5); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6) const { return ((f7)func) (a0, a1, a2, a3, a4, a5, a6); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7) const { return ((f8)func) (a0, a1, a2, a3, a4, a5, a6, a7); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8) const { return ((f9)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9) const { return ((f10)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10) const { return ((f11)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11) const { return ((f12)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12) const { return ((f13)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13) const { return ((f14)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14) const { return ((f15)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
+ rtx operator () (rtx a0, rtx a1, rtx a2, rtx a3, rtx a4, rtx a5, rtx a6, rtx a7, rtx a8, rtx a9, rtx a10, rtx a11, rtx a12, rtx a13, rtx a14, rtx a15) const { return ((f16)func) (a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
+
+ // This is for compatibility of code that invokes functions like
+ // (*funcptr) (arg)
+ insn_gen_fn operator * (void) const { return *this; }
+
+ // The wrapped function pointer must be public and there must not be any
+ // constructors. Otherwise the insn_data_d struct initializers generated
+ // by genoutput.c will result in static initializer functions, which defeats
+ // the purpose of the generated insn_data_d array.
+ stored_funcptr func;
+};
struct insn_operand_data
{
diff --git a/gcc/ree.c b/gcc/ree.c
index c0d43c8f72a..4dab6e91995 100644
--- a/gcc/ree.c
+++ b/gcc/ree.c
@@ -940,23 +940,40 @@ gate_handle_ree (void)
return (optimize > 0 && flag_ree);
}
-struct rtl_opt_pass pass_ree =
+namespace {
+
+const pass_data pass_data_ree =
{
- {
- RTL_PASS,
- "ree", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_ree, /* gate */
- rest_of_handle_ree, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_REE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish
- | TODO_verify_rtl_sharing, /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "ree", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_REE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_ree : public rtl_opt_pass
+{
+public:
+ pass_ree(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_ree, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_ree (); }
+ unsigned int execute () { return rest_of_handle_ree (); }
+
+}; // class pass_ree
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_ree (gcc::context *ctxt)
+{
+ return new pass_ree (ctxt);
+}
diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c
index 2dd9289d118..b3574e66d17 100644
--- a/gcc/reg-stack.c
+++ b/gcc/reg-stack.c
@@ -3292,26 +3292,43 @@ gate_handle_stack_regs (void)
#endif
}
-struct rtl_opt_pass pass_stack_regs =
+namespace {
+
+const pass_data pass_data_stack_regs =
{
- {
- RTL_PASS,
- "*stack_regs", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_stack_regs, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_REG_STACK, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "*stack_regs", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_REG_STACK, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_stack_regs : public rtl_opt_pass
+{
+public:
+ pass_stack_regs(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_stack_regs, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_stack_regs (); }
+
+}; // class pass_stack_regs
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_stack_regs (gcc::context *ctxt)
+{
+ return new pass_stack_regs (ctxt);
+}
+
/* Convert register usage from flat register file usage to a stack
register file. */
static unsigned int
@@ -3324,22 +3341,39 @@ rest_of_handle_stack_regs (void)
return 0;
}
-struct rtl_opt_pass pass_stack_regs_run =
+namespace {
+
+const pass_data pass_data_stack_regs_run =
{
- {
- RTL_PASS,
- "stack", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_stack_regs, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_REG_STACK, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "stack", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_REG_STACK, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_stack_regs_run : public rtl_opt_pass
+{
+public:
+ pass_stack_regs_run(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_stack_regs_run, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_stack_regs (); }
+
+}; // class pass_stack_regs_run
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_stack_regs_run (gcc::context *ctxt)
+{
+ return new pass_stack_regs_run (ctxt);
+}
diff --git a/gcc/regcprop.c b/gcc/regcprop.c
index 896902f3012..19f33495170 100644
--- a/gcc/regcprop.c
+++ b/gcc/regcprop.c
@@ -1236,23 +1236,40 @@ gate_handle_cprop (void)
}
-struct rtl_opt_pass pass_cprop_hardreg =
+namespace {
+
+const pass_data pass_data_cprop_hardreg =
{
- {
- RTL_PASS,
- "cprop_hardreg", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_cprop, /* gate */
- copyprop_hardreg_forward, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CPROP_REGISTERS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish
- | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "cprop_hardreg", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_CPROP_REGISTERS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_cprop_hardreg : public rtl_opt_pass
+{
+public:
+ pass_cprop_hardreg(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_cprop_hardreg, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_cprop (); }
+ unsigned int execute () { return copyprop_hardreg_forward (); }
+
+}; // class pass_cprop_hardreg
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_cprop_hardreg (gcc::context *ctxt)
+{
+ return new pass_cprop_hardreg (ctxt);
+}
diff --git a/gcc/reginfo.c b/gcc/reginfo.c
index 0153cd9d8ec..49a7a5864e2 100644
--- a/gcc/reginfo.c
+++ b/gcc/reginfo.c
@@ -620,40 +620,35 @@ choose_hard_reg_mode (unsigned int regno ATTRIBUTE_UNUSED,
mode = GET_MODE_WIDER_MODE (mode))
if ((unsigned) hard_regno_nregs[regno][mode] == nregs
&& HARD_REGNO_MODE_OK (regno, mode)
- && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+ && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
found_mode = mode;
- if (found_mode != VOIDmode)
- return found_mode;
-
for (mode = GET_CLASS_NARROWEST_MODE (MODE_FLOAT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if ((unsigned) hard_regno_nregs[regno][mode] == nregs
&& HARD_REGNO_MODE_OK (regno, mode)
- && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+ && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
found_mode = mode;
- if (found_mode != VOIDmode)
- return found_mode;
-
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_FLOAT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if ((unsigned) hard_regno_nregs[regno][mode] == nregs
&& HARD_REGNO_MODE_OK (regno, mode)
- && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+ && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
found_mode = mode;
- if (found_mode != VOIDmode)
- return found_mode;
-
for (mode = GET_CLASS_NARROWEST_MODE (MODE_VECTOR_INT);
mode != VOIDmode;
mode = GET_MODE_WIDER_MODE (mode))
if ((unsigned) hard_regno_nregs[regno][mode] == nregs
&& HARD_REGNO_MODE_OK (regno, mode)
- && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)))
+ && (! call_saved || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode))
+ && GET_MODE_SIZE (mode) > GET_MODE_SIZE (found_mode))
found_mode = mode;
if (found_mode != VOIDmode)
@@ -965,26 +960,43 @@ reginfo_init (void)
return 1;
}
-struct rtl_opt_pass pass_reginfo_init =
+namespace {
+
+const pass_data pass_data_reginfo_init =
{
- {
- RTL_PASS,
- "reginfo", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- reginfo_init, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "reginfo", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_reginfo_init : public rtl_opt_pass
+{
+public:
+ pass_reginfo_init(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_reginfo_init, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return reginfo_init (); }
+
+}; // class pass_reginfo_init
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_reginfo_init (gcc::context *ctxt)
+{
+ return new pass_reginfo_init (ctxt);
+}
+
/* Set up preferred, alternate, and allocno classes for REGNO as
diff --git a/gcc/regmove.c b/gcc/regmove.c
index 1ce8a7ed285..da7fac9844e 100644
--- a/gcc/regmove.c
+++ b/gcc/regmove.c
@@ -1361,22 +1361,40 @@ gate_handle_regmove (void)
}
-struct rtl_opt_pass pass_regmove =
+namespace {
+
+const pass_data pass_data_regmove =
{
- {
- RTL_PASS,
- "regmove", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_regmove, /* gate */
- regmove_optimize, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_REGMOVE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "regmove", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_REGMOVE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_regmove : public rtl_opt_pass
+{
+public:
+ pass_regmove(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_regmove, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_regmove (); }
+ unsigned int execute () { return regmove_optimize (); }
+
+}; // class pass_regmove
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_regmove (gcc::context *ctxt)
+{
+ return new pass_regmove (ctxt);
+}
diff --git a/gcc/regrename.c b/gcc/regrename.c
index 20e2ae9f792..6830bd8389a 100644
--- a/gcc/regrename.c
+++ b/gcc/regrename.c
@@ -1842,23 +1842,40 @@ gate_handle_regrename (void)
return (optimize > 0 && (flag_rename_registers));
}
-struct rtl_opt_pass pass_regrename =
+namespace {
+
+const pass_data pass_data_regrename =
{
- {
- RTL_PASS,
- "rnreg", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_regrename, /* gate */
- regrename_optimize, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_RENAME_REGISTERS, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "rnreg", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_RENAME_REGISTERS, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing | 0 ), /* todo_flags_finish */
};
+
+class pass_regrename : public rtl_opt_pass
+{
+public:
+ pass_regrename(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_regrename, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_regrename (); }
+ unsigned int execute () { return regrename_optimize (); }
+
+}; // class pass_regrename
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_regrename (gcc::context *ctxt)
+{
+ return new pass_regrename (ctxt);
+}
diff --git a/gcc/reload.c b/gcc/reload.c
index b15f3b20eb7..b69660d16af 100644
--- a/gcc/reload.c
+++ b/gcc/reload.c
@@ -680,8 +680,8 @@ find_valid_class (enum machine_mode outer ATTRIBUTE_UNUSED,
if (HARD_REGNO_MODE_OK (regno, inner))
{
good = 1;
- if (! TEST_HARD_REG_BIT (reg_class_contents[rclass], regno + n)
- || ! HARD_REGNO_MODE_OK (regno + n, outer))
+ if (TEST_HARD_REG_BIT (reg_class_contents[rclass], regno + n)
+ && ! HARD_REGNO_MODE_OK (regno + n, outer))
bad = 1;
}
}
diff --git a/gcc/reload.h b/gcc/reload.h
index 7a13ad30e82..f68c345482a 100644
--- a/gcc/reload.h
+++ b/gcc/reload.h
@@ -203,7 +203,7 @@ extern struct target_reload *this_target_reload;
(this_target_reload->x_caller_save_initialized_p)
/* Register equivalences. Indexed by register number. */
-typedef struct reg_equivs
+typedef struct reg_equivs_s
{
/* The constant value to which pseudo reg N is equivalent,
or zero if pseudo reg N is not equivalent to a constant.
diff --git a/gcc/reorg.c b/gcc/reorg.c
index e601818a0d0..d39cc7d8a4a 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -1856,10 +1856,15 @@ update_reg_unused_notes (rtx insn, rtx redundant_insn)
}
}
-/* Return the label before INSN, or put a new label there. */
+static vec <rtx> sibling_labels;
+
+/* Return the label before INSN, or put a new label there. If SIBLING is
+ non-zero, it is another label associated with the new label (if any),
+ typically the former target of the jump that will be redirected to
+ the new label. */
static rtx
-get_label_before (rtx insn)
+get_label_before (rtx insn, rtx sibling)
{
rtx label;
@@ -1874,6 +1879,11 @@ get_label_before (rtx insn)
label = gen_label_rtx ();
emit_label_after (label, prev);
LABEL_NUSES (label) = 0;
+ if (sibling)
+ {
+ sibling_labels.safe_push (label);
+ sibling_labels.safe_push (sibling);
+ }
}
return label;
}
@@ -2219,7 +2229,7 @@ fill_simple_delay_slots (int non_jumps_p)
rtx new_label = next_real_insn (next_trial);
if (new_label != 0)
- new_label = get_label_before (new_label);
+ new_label = get_label_before (new_label, JUMP_LABEL (trial));
else
new_label = find_end_label (simple_return_rtx);
@@ -2770,7 +2780,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
else if (LABEL_P (new_thread))
label = new_thread;
else
- label = get_label_before (new_thread);
+ label = get_label_before (new_thread, JUMP_LABEL (insn));
if (label)
{
@@ -3321,7 +3331,7 @@ relax_delay_slots (rtx first)
/* Now emit a label before the special USE insn, and
redirect our jump to the new label. */
- target_label = get_label_before (PREV_INSN (tmp));
+ target_label = get_label_before (PREV_INSN (tmp), target_label);
reorg_redirect_jump (delay_insn, target_label);
next = insn;
continue;
@@ -3495,7 +3505,7 @@ make_return_insns (rtx first)
for (insn = first; insn; insn = NEXT_INSN (insn))
if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
{
- rtx t = get_label_before (insn);
+ rtx t = get_label_before (insn, NULL_RTX);
if (PATTERN (insn) == ret_rtx)
real_return_label = t;
else
@@ -3825,6 +3835,12 @@ dbr_schedule (rtx first)
fprintf (dump_file, "\n");
}
+ if (!sibling_labels.is_empty ())
+ {
+ update_alignments (sibling_labels);
+ sibling_labels.release ();
+ }
+
free_resource_info ();
free (uid_to_ruid);
crtl->dbr_scheduled_p = true;
@@ -3852,26 +3868,44 @@ rest_of_handle_delay_slots (void)
return 0;
}
-struct rtl_opt_pass pass_delay_slots =
+namespace {
+
+const pass_data pass_data_delay_slots =
{
- {
- RTL_PASS,
- "dbr", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_delay_slots, /* gate */
- rest_of_handle_delay_slots, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_DBR_SCHED, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "dbr", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_DBR_SCHED, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_delay_slots : public rtl_opt_pass
+{
+public:
+ pass_delay_slots(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_delay_slots, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_delay_slots (); }
+ unsigned int execute () { return rest_of_handle_delay_slots (); }
+
+}; // class pass_delay_slots
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_delay_slots (gcc::context *ctxt)
+{
+ return new pass_delay_slots (ctxt);
+}
+
/* Machine dependent reorg pass. */
static bool
gate_handle_machine_reorg (void)
@@ -3887,22 +3921,40 @@ rest_of_handle_machine_reorg (void)
return 0;
}
-struct rtl_opt_pass pass_machine_reorg =
+namespace {
+
+const pass_data pass_data_machine_reorg =
{
- {
- RTL_PASS,
- "mach", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_machine_reorg, /* gate */
- rest_of_handle_machine_reorg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_MACH_DEP, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "mach", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_MACH_DEP, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_machine_reorg : public rtl_opt_pass
+{
+public:
+ pass_machine_reorg(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_machine_reorg, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_machine_reorg (); }
+ unsigned int execute () { return rest_of_handle_machine_reorg (); }
+
+}; // class pass_machine_reorg
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_machine_reorg (gcc::context *ctxt)
+{
+ return new pass_machine_reorg (ctxt);
+}
diff --git a/gcc/resource.c b/gcc/resource.c
index a0fd2ec4e69..367181289df 100644
--- a/gcc/resource.c
+++ b/gcc/resource.c
@@ -374,6 +374,16 @@ mark_referenced_resources (rtx x, struct resources *res,
case INSN:
case JUMP_INSN:
+ if (GET_CODE (PATTERN (x)) == COND_EXEC)
+ /* In addition to the usual references, also consider all outputs
+ as referenced, to compensate for mark_set_resources treating
+ them as killed. This is similar to ZERO_EXTRACT / STRICT_LOW_PART
+ handling, execpt that we got a partial incidence instead of a partial
+ width. */
+ mark_set_resources (x, res, 0,
+ include_delayed_effects
+ ? MARK_SRC_DEST_CALL : MARK_SRC_DEST);
+
#ifdef INSN_REFERENCES_ARE_DELAYED
if (! include_delayed_effects
&& INSN_REFERENCES_ARE_DELAYED (x))
@@ -994,11 +1004,18 @@ mark_target_live_regs (rtx insns, rtx target, struct resources *res)
if (CALL_P (real_insn))
{
- /* CALL clobbers all call-used regs that aren't fixed except
- sp, ap, and fp. Do this before setting the result of the
- call live. */
- AND_COMPL_HARD_REG_SET (current_live_regs,
- regs_invalidated_by_call);
+ /* Values in call-clobbered registers survive a COND_EXEC CALL
+ if that is not executed; this matters for resoure use because
+ they may be used by a complementarily (or more strictly)
+ predicated instruction, or if the CALL is NORETURN. */
+ if (GET_CODE (PATTERN (real_insn)) != COND_EXEC)
+ {
+ /* CALL clobbers all call-used regs that aren't fixed except
+ sp, ap, and fp. Do this before setting the result of the
+ call live. */
+ AND_COMPL_HARD_REG_SET (current_live_regs,
+ regs_invalidated_by_call);
+ }
/* A CALL_INSN sets any global register live, since it may
have been modified by the call. */
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 0846aabbd29..b5bfdffebc1 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2749,6 +2749,7 @@ extern void simplify_using_condition (rtx, rtx *, bitmap);
/* In final.c */
extern unsigned int compute_alignments (void);
+extern void update_alignments (vec<rtx> &);
extern int asm_str_count (const char *templ);
struct rtl_hooks
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 95a314f0f3f..c15037e9645 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -4034,7 +4034,7 @@ nonzero_bits1 (const_rtx x, enum machine_mode mode, const_rtx known_x,
&& mode_width < BITS_PER_WORD
&& (UINTVAL (x) & ((unsigned HOST_WIDE_INT) 1 << (mode_width - 1)))
!= 0)
- return UINTVAL (x) | ((unsigned HOST_WIDE_INT) (-1) << mode_width);
+ return UINTVAL (x) | (HOST_WIDE_INT_M1U << mode_width);
#endif
return UINTVAL (x);
diff --git a/gcc/sanitizer.def b/gcc/sanitizer.def
index 99f87e5c84b..4c8a0377d8b 100644
--- a/gcc/sanitizer.def
+++ b/gcc/sanitizer.def
@@ -283,3 +283,17 @@ DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_ATOMIC_THREAD_FENCE,
DEF_SANITIZER_BUILTIN(BUILT_IN_TSAN_ATOMIC_SIGNAL_FENCE,
"__tsan_atomic_signal_fence",
BT_FN_VOID_INT, ATTR_NOTHROW_LEAF_LIST)
+
+/* Undefined Behavior Sanitizer */
+DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_DIVREM_OVERFLOW,
+ "__ubsan_handle_divrem_overflow",
+ BT_FN_VOID_PTR_PTR_PTR,
+ ATTR_COLD_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS,
+ "__ubsan_handle_shift_out_of_bounds",
+ BT_FN_VOID_PTR_PTR_PTR,
+ ATTR_COLD_NOTHROW_LEAF_LIST)
+DEF_SANITIZER_BUILTIN(BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE,
+ "__ubsan_handle_builtin_unreachable",
+ BT_FN_VOID_PTR,
+ ATTR_COLD_NORETURN_NOTHROW_LEAF_LIST)
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 2c971e2a999..e1a2dce16a2 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -3617,44 +3617,80 @@ rest_of_handle_sched2 (void)
return 0;
}
-struct rtl_opt_pass pass_sched =
-{
- {
- RTL_PASS,
- "sched1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_sched, /* gate */
- rest_of_handle_sched, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_SCHED, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_sched =
+{
+ RTL_PASS, /* type */
+ "sched1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_SCHED, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
-struct rtl_opt_pass pass_sched2 =
-{
- {
- RTL_PASS,
- "sched2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_sched2, /* gate */
- rest_of_handle_sched2, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_SCHED2, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+class pass_sched : public rtl_opt_pass
+{
+public:
+ pass_sched(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_sched, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_sched (); }
+ unsigned int execute () { return rest_of_handle_sched (); }
+
+}; // class pass_sched
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_sched (gcc::context *ctxt)
+{
+ return new pass_sched (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_sched2 =
+{
+ RTL_PASS, /* type */
+ "sched2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_SCHED2, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_sched2 : public rtl_opt_pass
+{
+public:
+ pass_sched2(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_sched2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_sched2 (); }
+ unsigned int execute () { return rest_of_handle_sched2 (); }
+
+}; // class pass_sched2
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_sched2 (gcc::context *ctxt)
+{
+ return new pass_sched2 (ctxt);
+}
diff --git a/gcc/sched-vis.c b/gcc/sched-vis.c
index 763230ccdb2..eb2410cbc4f 100644
--- a/gcc/sched-vis.c
+++ b/gcc/sched-vis.c
@@ -47,10 +47,6 @@ along with GCC; see the file COPYING3. If not see
It is also possible to obtain a string for a single pattern as a string
pointer, via str_pattern_slim, but this usage is discouraged. */
-/* A pretty-printer for slim rtl printing. */
-static bool rtl_slim_pp_initialized = false;
-static pretty_printer rtl_slim_pp;
-
/* For insns we print patterns, and for some patterns we print insns... */
static void print_insn_with_notes (pretty_printer *, const_rtx);
@@ -347,11 +343,11 @@ print_exp (pretty_printer *pp, const_rtx x, int verbose)
pp_string (pp, "unspec");
if (GET_CODE (x) == UNSPEC_VOLATILE)
pp_string (pp, "/v");
- pp_character (pp, '[');
+ pp_left_bracket (pp);
for (i = 0; i < XVECLEN (x, 0); i++)
{
if (i != 0)
- pp_character (pp, ',');
+ pp_comma (pp);
print_pattern (pp, XVECEXP (x, 0, i), verbose);
}
pp_string (pp, "] ");
@@ -393,7 +389,7 @@ print_exp (pretty_printer *pp, const_rtx x, int verbose)
if (fun)
{
pp_string (pp, fun);
- pp_character (pp, '(');
+ pp_left_paren (pp);
}
for (i = 0; i < 4; i++)
@@ -404,13 +400,13 @@ print_exp (pretty_printer *pp, const_rtx x, int verbose)
if (op[i])
{
if (fun && i != 0)
- pp_character (pp, ',');
+ pp_comma (pp);
print_value (pp, op[i], verbose);
}
}
if (fun)
- pp_character (pp, ')');
+ pp_right_paren (pp);
} /* print_exp */
/* Prints rtxes, I customarily classified as values. They're constants,
@@ -462,13 +458,13 @@ print_value (pretty_printer *pp, const_rtx x, int verbose)
case STRICT_LOW_PART:
pp_printf (pp, "%s(", GET_RTX_NAME (GET_CODE (x)));
print_value (pp, XEXP (x, 0), verbose);
- pp_character (pp, ')');
+ pp_right_paren (pp);
break;
case REG:
if (REGNO (x) < FIRST_PSEUDO_REGISTER)
{
if (ISDIGIT (reg_names[REGNO (x)][0]))
- pp_character (pp, '%');
+ pp_modulo (pp);
pp_string (pp, reg_names[REGNO (x)]);
}
else
@@ -486,9 +482,9 @@ print_value (pretty_printer *pp, const_rtx x, int verbose)
pp_string (pp, GET_RTX_NAME (GET_CODE (x)));
break;
case MEM:
- pp_character (pp, '[');
+ pp_left_bracket (pp);
print_value (pp, XEXP (x, 0), verbose);
- pp_character (pp, ']');
+ pp_right_bracket (pp);
break;
case DEBUG_EXPR:
pp_printf (pp, "D#%i", DEBUG_TEMP_UID (DEBUG_EXPR_TREE_DECL (x)));
@@ -514,7 +510,7 @@ print_pattern (pretty_printer *pp, const_rtx x, int verbose)
{
case SET:
print_value (pp, SET_DEST (x), verbose);
- pp_character (pp, '=');
+ pp_equal (pp);
print_value (pp, SET_SRC (x), verbose);
break;
case RETURN:
@@ -535,14 +531,14 @@ print_pattern (pretty_printer *pp, const_rtx x, int verbose)
print_value (pp, PAT_VAR_LOCATION_LOC (x), verbose);
break;
case COND_EXEC:
- pp_character (pp, '(');
+ pp_left_paren (pp);
if (GET_CODE (COND_EXEC_TEST (x)) == NE
&& XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
else if (GET_CODE (COND_EXEC_TEST (x)) == EQ
&& XEXP (COND_EXEC_TEST (x), 1) == const0_rtx)
{
- pp_character (pp, '!');
+ pp_exclamation (pp);
print_value (pp, XEXP (COND_EXEC_TEST (x), 0), verbose);
}
else
@@ -554,13 +550,13 @@ print_pattern (pretty_printer *pp, const_rtx x, int verbose)
{
int i;
- pp_character (pp, '{');
+ pp_left_brace (pp);
for (i = 0; i < XVECLEN (x, 0); i++)
{
print_pattern (pp, XVECEXP (x, 0, i), verbose);
- pp_character (pp, ';');
+ pp_semicolon (pp);
}
- pp_character (pp, '}');
+ pp_right_brace (pp);
}
break;
case SEQUENCE:
@@ -588,10 +584,10 @@ print_pattern (pretty_printer *pp, const_rtx x, int verbose)
for (int i = 0; i < XVECLEN (x, 0); i++)
{
print_pattern (pp, XVECEXP (x, 0, i), verbose);
- pp_character (pp, ';');
+ pp_semicolon (pp);
}
}
- pp_character (pp, '}');
+ pp_right_brace (pp);
}
break;
case ASM_INPUT:
@@ -690,7 +686,7 @@ print_insn (pretty_printer *pp, const_rtx x, int verbose)
case JUMP_TABLE_DATA:
pp_string (pp, "jump_table_data{\n");
print_pattern (pp, PATTERN (x), verbose);
- pp_string (pp, "}");
+ pp_right_brace (pp);
break;
case BARRIER:
pp_string (pp, "barrier");
@@ -726,9 +722,9 @@ print_insn (pretty_printer *pp, const_rtx x, int verbose)
case NOTE_INSN_VAR_LOCATION:
case NOTE_INSN_CALL_ARG_LOCATION:
- pp_character (pp, '{');
+ pp_left_brace (pp);
print_pattern (pp, NOTE_VAR_LOCATION (x), verbose);
- pp_character (pp, '}');
+ pp_right_brace (pp);
break;
default:
@@ -760,24 +756,6 @@ print_insn_with_notes (pretty_printer *pp, const_rtx x)
}
}
-/* Return a pretty-print buffer set up to print to file F. */
-
-static pretty_printer *
-init_rtl_slim_pretty_print (FILE *f)
-{
- if (! rtl_slim_pp_initialized)
- {
- pp_construct (&rtl_slim_pp, /*prefix=*/NULL, /*linewidth=*/0);
- rtl_slim_pp_initialized = true;
- }
- else
- /* Clean out any data that str_insn_slim may have left here. */
- pp_clear_output_area (&rtl_slim_pp);
-
- rtl_slim_pp.buffer->stream = f;
- return &rtl_slim_pp;
-}
-
/* Print X, an RTL value node, to file F in slim format. Include
additional information if VERBOSE is nonzero.
@@ -787,9 +765,10 @@ init_rtl_slim_pretty_print (FILE *f)
void
dump_value_slim (FILE *f, const_rtx x, int verbose)
{
- pretty_printer *pp = init_rtl_slim_pretty_print (f);
- print_value (pp, x, verbose);
- pp_flush (pp);
+ pretty_printer rtl_slim_pp;
+ rtl_slim_pp.buffer->stream = f;
+ print_value (&rtl_slim_pp, x, verbose);
+ pp_flush (&rtl_slim_pp);
}
/* Emit a slim dump of X (an insn) to the file F, including any register
@@ -797,9 +776,10 @@ dump_value_slim (FILE *f, const_rtx x, int verbose)
void
dump_insn_slim (FILE *f, const_rtx x)
{
- pretty_printer *pp = init_rtl_slim_pretty_print (f);
- print_insn_with_notes (pp, x);
- pp_flush (pp);
+ pretty_printer rtl_slim_pp;
+ rtl_slim_pp.buffer->stream = f;
+ print_insn_with_notes (&rtl_slim_pp, x);
+ pp_flush (&rtl_slim_pp);
}
/* Same as above, but stop at LAST or when COUNT == 0.
@@ -810,19 +790,20 @@ dump_rtl_slim (FILE *f, const_rtx first, const_rtx last,
int count, int flags ATTRIBUTE_UNUSED)
{
const_rtx insn, tail;
- pretty_printer *pp = init_rtl_slim_pretty_print (f);
+ pretty_printer rtl_slim_pp;
+ rtl_slim_pp.buffer->stream = f;
tail = last ? NEXT_INSN (last) : NULL_RTX;
for (insn = first;
(insn != NULL) && (insn != tail) && (count != 0);
insn = NEXT_INSN (insn))
{
- print_insn_with_notes (pp, insn);
+ print_insn_with_notes (&rtl_slim_pp, insn);
if (count > 0)
count--;
}
- pp_flush (pp);
+ pp_flush (&rtl_slim_pp);
}
/* Dumps basic block BB to pretty-printer PP in slim form and without and
@@ -839,7 +820,7 @@ rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
{
if (! first)
{
- pp_character (pp, '|');
+ pp_bar (pp);
pp_write_text_to_stream (pp);
}
first = false;
@@ -857,9 +838,9 @@ rtl_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
const char *
str_pattern_slim (const_rtx x)
{
- pretty_printer *pp = init_rtl_slim_pretty_print (NULL);
- print_pattern (pp, x, 0);
- return pp_base_formatted_text (pp);
+ pretty_printer rtl_slim_pp;
+ print_pattern (&rtl_slim_pp, x, 0);
+ return ggc_strdup (pp_formatted_text (&rtl_slim_pp));
}
/* Emit a slim dump of X (an insn) to stderr. */
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index fb9386f9690..46c66b4f3ed 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -6424,10 +6424,23 @@ code_motion_process_successors (insn_t insn, av_set_t orig_ops,
res = b;
/* We have simplified the control flow below this point. In this case,
- the iterator becomes invalid. We need to try again. */
+ the iterator becomes invalid. We need to try again.
+ If we have removed the insn itself, it could be only an
+ unconditional jump. Thus, do not rescan but break immediately --
+ we have already visited the only successor block. */
+ if (!BLOCK_FOR_INSN (insn))
+ {
+ if (sched_verbose >= 6)
+ sel_print ("Not doing rescan: already visited the only successor"
+ " of block %d\n", old_index);
+ break;
+ }
if (BLOCK_FOR_INSN (insn)->index != old_index
|| EDGE_COUNT (bb->succs) != old_succs)
{
+ if (sched_verbose >= 6)
+ sel_print ("Rescan: CFG was simplified below insn %d, block %d\n",
+ INSN_UID (insn), BLOCK_FOR_INSN (insn)->index);
insn = sel_bb_end (BLOCK_FOR_INSN (insn));
goto rescan;
}
diff --git a/gcc/simplify-rtx.c b/gcc/simplify-rtx.c
index 17a3d12e076..65a59062a48 100644
--- a/gcc/simplify-rtx.c
+++ b/gcc/simplify-rtx.c
@@ -2018,14 +2018,13 @@ simplify_const_unary_operation (enum rtx_code code, enum machine_mode mode,
/* Test against the signed lower bound. */
if (width > HOST_BITS_PER_WIDE_INT)
{
- th = (unsigned HOST_WIDE_INT) (-1)
- << (width - HOST_BITS_PER_WIDE_INT - 1);
+ th = HOST_WIDE_INT_M1U << (width - HOST_BITS_PER_WIDE_INT - 1);
tl = 0;
}
else
{
th = -1;
- tl = (unsigned HOST_WIDE_INT) (-1) << (width - 1);
+ tl = HOST_WIDE_INT_M1U << (width - 1);
}
real_from_integer (&t, VOIDmode, tl, th, 0);
if (REAL_VALUES_LESS (x, t))
@@ -4191,7 +4190,7 @@ simplify_const_binary_operation (enum rtx_code code, enum machine_mode mode,
/* Sign-extend the result for arithmetic right shifts. */
if (code == ASHIFTRT && arg0s < 0 && arg1 > 0)
- val |= ((unsigned HOST_WIDE_INT) (-1)) << (width - arg1);
+ val |= HOST_WIDE_INT_M1U << (width - arg1);
break;
case ROTATERT:
diff --git a/gcc/stack-ptr-mod.c b/gcc/stack-ptr-mod.c
index 739bcfc3ac5..737a07f5727 100644
--- a/gcc/stack-ptr-mod.c
+++ b/gcc/stack-ptr-mod.c
@@ -90,22 +90,39 @@ rest_of_handle_stack_ptr_mod (void)
return 0;
}
-struct rtl_opt_pass pass_stack_ptr_mod =
+namespace {
+
+const pass_data pass_data_stack_ptr_mod =
{
- {
- RTL_PASS,
- "*stack_ptr_mod", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rest_of_handle_stack_ptr_mod, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "*stack_ptr_mod", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_stack_ptr_mod : public rtl_opt_pass
+{
+public:
+ pass_stack_ptr_mod(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_stack_ptr_mod, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rest_of_handle_stack_ptr_mod (); }
+
+}; // class pass_stack_ptr_mod
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_stack_ptr_mod (gcc::context *ctxt)
+{
+ return new pass_stack_ptr_mod (ctxt);
+}
diff --git a/gcc/statistics.c b/gcc/statistics.c
index 3077cc0c36c..b198b3455fa 100644
--- a/gcc/statistics.c
+++ b/gcc/statistics.c
@@ -26,6 +26,8 @@ along with GCC; see the file COPYING3. If not see
#include "statistics.h"
#include "hash-table.h"
#include "function.h"
+#include "context.h"
+#include "pass_manager.h"
static int statistics_dump_nr;
static int statistics_dump_flags;
@@ -235,6 +237,7 @@ statistics_fini_1 (statistics_counter_t **slot, opt_pass *pass)
void
statistics_fini (void)
{
+ gcc::pass_manager *passes = g->get_passes ();
if (!statistics_dump_file)
return;
@@ -243,10 +246,10 @@ statistics_fini (void)
unsigned i;
for (i = 0; i < nr_statistics_hashes; ++i)
if (statistics_hashes[i].is_created ()
- && get_pass_for_id (i) != NULL)
+ && passes->get_pass_for_id (i) != NULL)
statistics_hashes[i]
.traverse_noresize <opt_pass *, statistics_fini_1>
- (get_pass_for_id (i));
+ (passes->get_pass_for_id (i));
}
dump_end (statistics_dump_nr, statistics_dump_file);
diff --git a/gcc/store-motion.c b/gcc/store-motion.c
index df756707408..e0b58477d4c 100644
--- a/gcc/store-motion.c
+++ b/gcc/store-motion.c
@@ -1235,23 +1235,41 @@ execute_rtl_store_motion (void)
return 0;
}
-struct rtl_opt_pass pass_rtl_store_motion =
+namespace {
+
+const pass_data pass_data_rtl_store_motion =
{
- {
- RTL_PASS,
- "store_motion", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_rtl_store_motion, /* gate */
- execute_rtl_store_motion, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LSM, /* tv_id */
- PROP_cfglayout, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing |
- TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "store_motion", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_LSM, /* tv_id */
+ PROP_cfglayout, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_rtl_store_motion : public rtl_opt_pass
+{
+public:
+ pass_rtl_store_motion(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_rtl_store_motion, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_rtl_store_motion (); }
+ unsigned int execute () { return execute_rtl_store_motion (); }
+
+}; // class pass_rtl_store_motion
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_rtl_store_motion (gcc::context *ctxt)
+{
+ return new pass_rtl_store_motion (ctxt);
+}
diff --git a/gcc/symtab.c b/gcc/symtab.c
index d15881b609a..8dc61d0c7af 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -283,7 +283,8 @@ symtab_unregister_node (symtab_node node)
else
*slot = replacement_node;
}
- unlink_from_assembler_name_hash (node, false);
+ if (!is_a <varpool_node> (node) || !DECL_HARD_REGISTER (node->symbol.decl))
+ unlink_from_assembler_name_hash (node, false);
}
/* Return symbol table node associated with DECL, if any,
@@ -390,6 +391,9 @@ change_decl_assembler_name (tree decl, tree name)
if (name == DECL_ASSEMBLER_NAME (decl))
return;
+ tree alias = (IDENTIFIER_TRANSPARENT_ALIAS (DECL_ASSEMBLER_NAME (decl))
+ ? TREE_CHAIN (DECL_ASSEMBLER_NAME (decl))
+ : NULL);
if (node)
unlink_from_assembler_name_hash (node, true);
if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))
@@ -397,6 +401,11 @@ change_decl_assembler_name (tree decl, tree name)
warning (0, "%D renamed after being referenced in assembly", decl);
SET_DECL_ASSEMBLER_NAME (decl, name);
+ if (alias)
+ {
+ IDENTIFIER_TRANSPARENT_ALIAS (name) = 1;
+ TREE_CHAIN (DECL_ASSEMBLER_NAME (name)) = alias;
+ }
if (node)
insert_to_assembler_name_hash (node, true);
}
@@ -1014,4 +1023,131 @@ symtab_resolve_alias (symtab_node node, symtab_node target)
symtab_alias_ultimate_target (target, NULL)->symbol.address_taken = true;
return true;
}
+
+/* Call calback on NODE and aliases associated to NODE.
+ When INCLUDE_OVERWRITABLE is false, overwritable aliases and thunks are
+ skipped. */
+
+bool
+symtab_for_node_and_aliases (symtab_node node,
+ bool (*callback) (symtab_node, void *),
+ void *data,
+ bool include_overwritable)
+{
+ int i;
+ struct ipa_ref *ref;
+
+ if (callback (node, data))
+ return true;
+ for (i = 0; ipa_ref_list_referring_iterate (&node->symbol.ref_list, i, ref); i++)
+ if (ref->use == IPA_REF_ALIAS)
+ {
+ symtab_node alias = ref->referring;
+ if (include_overwritable
+ || symtab_node_availability (alias) > AVAIL_OVERWRITABLE)
+ if (symtab_for_node_and_aliases (alias, callback, data,
+ include_overwritable))
+ return true;
+ }
+ return false;
+}
+
+/* Worker searching nonoverwritable alias. */
+
+static bool
+symtab_nonoverwritable_alias_1 (symtab_node node, void *data)
+{
+ if (decl_binds_to_current_def_p (node->symbol.decl))
+ {
+ *(symtab_node *)data = node;
+ return true;
+ }
+ return false;
+}
+
+/* If NODE can not be overwriten by static or dynamic linker to point to different
+ definition, return NODE. Otherwise look for alias with such property and if
+ none exists, introduce new one. */
+
+symtab_node
+symtab_nonoverwritable_alias (symtab_node node)
+{
+ tree new_decl;
+ symtab_node new_node = NULL;
+
+ /* First try to look up existing alias or base object
+ (if that is already non-overwritable). */
+ node = symtab_alias_ultimate_target (node, NULL);
+ gcc_assert (!node->symbol.alias && !node->symbol.weakref);
+ symtab_for_node_and_aliases (node, symtab_nonoverwritable_alias_1,
+ (void *)&new_node, true);
+ if (new_node)
+ return new_node;
+
+ /* Otherwise create a new one. */
+ new_decl = copy_node (node->symbol.decl);
+ DECL_NAME (new_decl) = clone_function_name (node->symbol.decl, "localalias");
+ if (TREE_CODE (new_decl) == FUNCTION_DECL)
+ DECL_STRUCT_FUNCTION (new_decl) = NULL;
+ DECL_INITIAL (new_decl) = NULL;
+ SET_DECL_ASSEMBLER_NAME (new_decl, DECL_NAME (new_decl));
+ SET_DECL_RTL (new_decl, NULL);
+
+ /* Update the properties. */
+ DECL_EXTERNAL (new_decl) = 0;
+ if (DECL_ONE_ONLY (node->symbol.decl))
+ DECL_SECTION_NAME (new_decl) = NULL;
+ DECL_COMDAT_GROUP (new_decl) = 0;
+ TREE_PUBLIC (new_decl) = 0;
+ DECL_COMDAT (new_decl) = 0;
+ DECL_WEAK (new_decl) = 0;
+ DECL_VIRTUAL_P (new_decl) = 0;
+ if (TREE_CODE (new_decl) == FUNCTION_DECL)
+ {
+ DECL_STATIC_CONSTRUCTOR (new_decl) = 0;
+ DECL_STATIC_DESTRUCTOR (new_decl) = 0;
+ new_node = (symtab_node) cgraph_create_function_alias
+ (new_decl, node->symbol.decl);
+ }
+ else
+ new_node = (symtab_node) varpool_create_variable_alias (new_decl,
+ node->symbol.decl);
+ symtab_resolve_alias (new_node, node);
+ gcc_assert (decl_binds_to_current_def_p (new_decl));
+ return new_node;
+}
+
+/* Return true if A and B represents semantically equivalent symbols. */
+
+bool
+symtab_semantically_equivalent_p (symtab_node a,
+ symtab_node b)
+{
+ enum availability avail;
+ symtab_node ba, bb;
+
+ /* Equivalent functions are equivalent. */
+ if (a->symbol.decl == b->symbol.decl)
+ return true;
+
+ /* If symbol is not overwritable by different implementation,
+ walk to the base object it defines. */
+ ba = symtab_alias_ultimate_target (a, &avail);
+ if (avail >= AVAIL_AVAILABLE)
+ {
+ if (ba == b)
+ return true;
+ }
+ else
+ ba = a;
+ bb = symtab_alias_ultimate_target (b, &avail);
+ if (avail >= AVAIL_AVAILABLE)
+ {
+ if (a == bb)
+ return true;
+ }
+ else
+ bb = b;
+ return bb == ba;
+}
#include "gt-symtab.h"
diff --git a/gcc/system.h b/gcc/system.h
index f10ba4a0e81..b735a96c10b 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -914,7 +914,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
USE_COMMON_FOR_ONE_ONLY IFCVT_EXTRA_FIELDS IFCVT_INIT_EXTRA_FIELDS \
CASE_USE_BIT_TESTS FIXUNS_TRUNC_LIKE_FIX_TRUNC \
GO_IF_MODE_DEPENDENT_ADDRESS DELAY_SLOTS_FOR_EPILOGUE \
- ELIGIBLE_FOR_EPILOGUE_DELAY
+ ELIGIBLE_FOR_EPILOGUE_DELAY TARGET_C99_FUNCTIONS TARGET_HAS_SINCOS
/* Hooks that are no longer used. */
#pragma GCC poison LANG_HOOKS_FUNCTION_MARK LANG_HOOKS_FUNCTION_FREE \
diff --git a/gcc/target.def b/gcc/target.def
index 561506f203e..6de513fdf9a 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1967,7 +1967,7 @@ DEFHOOK
should use the narrowest mode possible. It should return @code{false} if\n\
these accesses should use the bitfield container type.\n\
\n\
-The default is @code{!TARGET_STRICT_ALIGN}.",
+The default is @code{false}.",
bool, (void),
hook_bool_void_false)
@@ -2201,6 +2201,13 @@ set via @code{__attribute__}.",
unsigned int, (tree decl, const char *name, int reloc),
default_section_type_flags)
+DEFHOOK
+(libc_has_function,
+ "This hook determines whether a function from a class of functions\n\
+@var{fn_class} is present at the runtime.",
+ bool, (enum function_class fn_class),
+ default_libc_has_function)
+
/* True if new jumps cannot be created, to replace existing ones or
not, at the current point in the compilation. */
DEFHOOK
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index 2da6fb80631..aaddae93209 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -166,6 +166,10 @@ extern rtx default_addr_space_convert (rtx, tree, tree);
extern unsigned int default_case_values_threshold (void);
extern bool default_have_conditional_execution (void);
+extern bool default_libc_has_function (enum function_class);
+extern bool no_c99_libc_has_function (enum function_class);
+extern bool gnu_libc_has_function (enum function_class);
+
extern tree default_builtin_tm_load_store (tree);
extern int default_memory_move_cost (enum machine_mode, reg_class_t, bool);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 8082e4a159c..51cab1b35bf 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,1115 @@
+2013-09-09 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/58294
+ * g++.dg/torture/PR58294.C: New testcase.
+
+2013-09-08 Jeff Law <law@redhat.com>
+
+ * gcc.c-torture/compile/pr58340.c: New test.
+
+2013-09-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * g++.dg/debug/ra1.C: New test.
+
+2013-09-08 Jan Hubicka <jh@suse.cz>
+
+ * testsuite/g++.dg/ipa/devirt-11.C: Update template.
+ * testsuite/g++.dg/ipa/devirt-16.C: New testcase.
+ * testsuite/g++.dg/ipa/devirt-17.C: New testcase.
+ * testsuite/g++.dg/ipa/devirt-18.C: New testcase.
+
+2013-09-08 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/54941
+ * g++.dg/overload/new1.C: Adjust.
+
+2013-09-08 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * c-c++-common/opaque-vector.c: New test.
+
+2013-09-08 Tom de Vries <tom@codesourcery.com>
+
+ PR c++/58282
+ * g++.dg/tm/noexcept-6.C: New test.
+
+2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * gcc.target/arc/cond-set-use.c: New test.
+
+2013-09-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/stack_usage2.adb: New test.
+
+2013-09-06 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * gcc.target/aarch64/table-intrinsics.c
+ (qtbl_tests8_< ,2,3,4>): Fix control vector parameter type.
+ (qtb_tests8_< ,2,3,4>): Likewise.
+ (qtblq_tests8_< ,2,3,4>): Likewise.
+ (qtbxq_tests8_< ,2,3,4>): Likewise.
+
+2013-09-06 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/warn10.ad[sb]: New test.
+ * gnat.dg/warn10_pkg.ads: New helper.
+
+2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * gcc.dg/ipa/ipa-pta-14.c (scan-ipa-dump) [keeps_null_pointer_checks]:
+ Don't expect NULL in foo.result set.
+ * gcc.dg/tree-ssa/pta-escape-1.c (scan-tree-dump): Don't expect NULL
+ in ESCAPED set.
+ * gcc.dg/tree-ssa/pta-escape-2.c: Likewise.
+ * gcc.dg/tree-ssa/pta-escape-3.c: Likewise.
+
+2013-09-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * gcc.target/s390/nearestint-1.c: New testcase.
+
+2013-09-06 Joern Rennecke <joern.rennecke@embecosm.com>
+ Vineet Gupta <Vineet.Gupta@synopsys.com>
+
+ * gcc.c-torture/execute/20101011-1.c [__arc__] (DO_TEST): Define as 0.
+ * testsuite/gcc.target/arc: New directory.
+ * gcc.dg/torture/pr37868.c: Also skip for arc*-*-*.
+ * gcc.dg/stack-usage-1.c [__arc__] (SIZE): Define.
+ * testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
+ [__arc__] (STACK_ARGUMENTS_SIZE): Set to 0.
+ * testsuite/gcc.dg/builtin-apply2.c
+ [__arc__] (STACK_ARGUMENTS_SIZE): Set to 0.
+
+2013-09-04 Jan Hubicka <jh@suse.cz>
+
+ PR middle-end/58201
+ * g++.dg/torture/pr58201_0.C: New testcase.
+ * g++.dg/torture/pr58201_1.C: New testcase.
+ * g++.dg/torture/pr58201.h: New testcase.
+
+2013-09-05 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/autopar/pr49960.c: Disable partial inlining
+
+2013-09-05 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58137
+ * gcc.target/i386/pr58137.c: New testcase.
+
+2013-09-05 Martin Jambor <mjambor@suse.cz>
+
+ * g++.dg/ipa/remref-1.C: New test.
+ * g++.dg/ipa/remref-2.C: Likewise.
+
+2013-09-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/24926
+ * g++.dg/parse/access11.C: New.
+
+2013-09-04 David Edelsohn <dje.gcc@gmail.com>
+
+ * g++.dg/warn/weak1.C: Skip on AIX.
+
+2013-09-04 Easwaran Raman <eraman@google.com>
+
+ PR middle-end/57370
+ PR tree-optimization/58011
+ * gfortran.dg/reassoc_12.f90: New testcase.
+ * gcc.dg/tree-ssa/reassoc-31.c: New testcase.
+
+2013-09-04 David Edelsohn <dje.gcc@gmail.com>
+
+ * gcc.dg/attr-weakref-1.c: Skip on AIX.
+ * gcc.dg/torture/pr53922.c: Skip on AIX.
+ * lib/file-format.exp (gcc_target_object_format): AIX is COFF.
+
+2013-09-04 Teresa Johnson <tejohnson@google.com>
+
+ * gcc.dg/unroll_1.c: Test dumping to stderr.
+
+2013-09-04 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58305
+ * g++.dg/warn/deprecated-8.C: New.
+
+2013-09-03 Jeff Law <law@redhat.com>
+
+ * tree-ssa/ssa-dom-thread-3.c: Update due to changes in debug
+ dump output.
+
+2013-09-03 Meador Inge <meadori@codesourcery.com>
+
+ Revert:
+
+ 2013-08-30 Meador Inge <meadori@codesourcery.com>
+
+ * gcc.dg/Warray-bounds-11.c: New testcase.
+
+2013-09-03 David Edelsohn <dje.gcc@gmail.com>
+
+ * lib/target-supports.exp (check_weak_available): Return true for AIX.
+
+2013-09-03 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/ipa/devirt-15.C: Fix testcase.
+
+2013-09-03 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57656
+ * gcc.dg/torture/pr57656.c: New testcase.
+
+2013-09-03 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57287
+ * gcc.dg/pr57287-2.c: Use setjmp, not __sigsetjmp.
+
+2013-09-02 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/PR56519
+ * gfortran.dg/do_concurrent_3.f90: New test case.
+
+2013-09-02 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/fnsplit-1.c: New testcase.
+
+2013-09-02 Martin Jambor <mjambor@suse.cz>
+
+ PR ipa/58106
+ * gcc.dg/ipa/pr58106.c: New test.
+
+2013-09-02 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * gcc.target/aarch64/scalar_intrinsics.c
+ (vdup<bhsd>_lane<su><8,16,32,64>): Force values to SIMD registers.
+
+2013-09-02 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57511
+ * gcc.dg/tree-ssa/sccp-1.c: New testcase.
+
+2013-09-02 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/loop-4.c: Adjust scan looking for one memory
+ reference.
+
+2013-09-02 Bin Cheng <bin.cheng@arm.com>
+
+ * gcc.target/arm/ivopts-orig_biv-inc.c: New testcase.
+
+2013-09-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/21682, implement DR 565
+ * g++.dg/template/using24.C: New.
+ * g++.dg/template/using25.C: Likewise.
+ * g++.dg/template/using26.C: Likewise.
+
+2013-09-01 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/ipa/devirt-15.C: New testcase.
+
+2013-09-01 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/linker_alias.ads: Skip on Darwin.
+
+2013-08-31 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/ipa/devirt-11.C: Use -fno-devirtualize-speuclatively
+ * g++.dg/tree-ssa/pr45453.C: Likewise.
+
+2013-08-31 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/fork-instrumentation.c: New testcase.
+
+2013-08-30 Uros Bizjak <ubizjak@gmail.com>
+
+ * g++.dg/abi/mangle33.C (dg-final): Use match count in scan RE.
+
+2013-08-30 Meador Inge <meadori@codesourcery.com>
+
+ * gcc.dg/Warray-bounds-11.c: New testcase.
+
+2013-08-30 Marek Polacek <polacek@redhat.com>
+
+ * g++.dg/ubsan/div-by-zero-1.C: New test.
+ * c-c++-common/ubsan/save-expr-1.c: New test.
+ * c-c++-common/ubsan/save-expr-2.c: New test.
+ * c-c++-common/ubsan/save-expr-3.c: New test.
+ * c-c++-common/ubsan/save-expr-4.c: New test.
+ * c-c++-common/ubsan/typedef-1.c: New test.
+ * c-c++-common/ubsan/const-char-1.c: New test.
+ * c-c++-common/ubsan/const-expr.c: New test.
+ * c-c++-common/ubsan/div-by-zero-1.c: Likewise.
+ * c-c++-common/ubsan/shift-1.c: Likewise.
+ * c-c++-common/ubsan/shift-2.c: Likewise.
+ * c-c++-common/ubsan/div-by-zero-2.c: Likewise.
+ * lib/ubsan-dg.exp: New file.
+ * g++.dg/dg.exp: Add ubsan tests.
+ * g++.dg/ubsan/ubsan.exp: New file.
+ * gcc.dg/ubsan/ubsan.exp: New file.
+ * g++.dg/ubsan/cxx11-shift-1.C: New test.
+ * g++.dg/ubsan/cxx11-shift-2.C: New test.
+ * c-c++-common/ubsan/div-by-zero-3.c: New test.
+ * c-c++-common/ubsan/div-by-zero-1.c: New test.
+ * c-c++-common/ubsan/div-by-zero-4.c: New test.
+ * c-c++-common/ubsan/shift-3.c: New test.
+ * c-c++-common/ubsan/unreachable-1.c: New test.
+ * c-c++-common/ubsan/shift-1.c: New test.
+ * c-c++-common/ubsan/shift-2.c: New test.
+ * c-c++-common/ubsan/div-by-zero-2.c: New test.
+ * gcc.dg/ubsan/c99-shift-2.c: New test.
+ * gcc.dg/ubsan/c99-shift-1.c: New test.
+
+2013-08-29 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/attr-alias.c: Rename test3 to test1
+ to match template and comment.
+
+2013-08-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51424
+ * g++.dg/cpp0x/dc8.C: New.
+ * g++.dg/template/meminit1.C: Adjust.
+
+2013-08-30 Teresa Johnson <tejohnson@google.com>
+
+ * gcc.dg/inline-dump.c: Delete inadvertant commit.
+
+2013-08-30 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58277
+ * gcc.c-torture/execute/pr58277-1.c: New test.
+ * gcc.c-torture/execute/pr58277-2.c: New test.
+
+2013-08-30 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/guality/param-1.c: New test.
+ * gcc.dg/guality/param-2.c: Likewise.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58228
+ * gcc.dg/torture/pr58228.c: New testcase.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58223
+ * gcc.dg/torture/pr58223.c: New testcase.
+ * gcc.dg/tree-ssa/ldist-16.c: Flip expected behavior.
+
+2013-08-30 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58010
+ * gcc.dg/pr58010.c: New testcase.
+
+2013-08-29 Xinliang DavidLi <davidxl@google.com>
+
+ * gcc.dg/unroll_3.c: Message change.
+ * gcc.dg/unroll_4.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-1.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-2.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-3.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-4.c: Likewise.
+ * gcc.dg/tree-ssa/cunroll-5.c: Likewise.
+ * gcc.dg/tree-ssa/loop-23.c: Likewise.
+ * gcc.dg/tree-ssa/loop-1.c: Likewise.
+ * gcc.dg/unroll_1.c: Likewise.
+ * gcc.dg/vect/bb-slp-31.c: Likewise.
+ * gcc.dg/vect/bb-slp-14.c: Likewise.
+ * gcc.dg/vect/bb-slp-8.c: Likewise.
+ * gcc.dg/vect/bb-slp-23.c: Likewise.
+ * gcc.dg/vect/bb-slp-15.c: Likewise.
+ * gcc.dg/vect/bb-slp-9.c: Likewise.
+ * gcc.dg/vect/bb-slp-24.c: Likewise.
+ * gcc.dg/vect/bb-slp-16.c: Likewise.
+ * gcc.dg/vect/bb-slp-25.c: Likewise.
+ * gcc.dg/vect/bb-slp-17.c: Likewise.
+ * gcc.dg/vect/bb-slp-26.c: Likewise.
+ * gcc.dg/vect/bb-slp-18.c: Likewise.
+ * gcc.dg/vect/no-tree-reassoc-bb-slp-12.c: Likewise.
+ * gcc.dg/vect/bb-slp-27.c: Likewise.
+ * gcc.dg/vect/bb-slp-19.c: Likewise.
+ * gcc.dg/vect/bb-slp-28.c: Likewise.
+ * gcc.dg/vect/bb-slp-cond-1.c: Likewise.
+ * gcc.dg/vect/bb-slp-29.c: Likewise.
+ * gcc.dg/vect/bb-slp-8a.c: Likewise.
+ * gcc.dg/vect/bb-slp-pattern-2.c: Likewise.
+ * gcc.dg/vect/bb-slp-1.c: Likewise.
+ * gcc.dg/vect/bb-slp-8b.c: Likewise.
+ * gcc.dg/vect/bb-slp-2.c: Likewise.
+ * gcc.dg/vect/bb-slp-3.c: Likewise.
+ * gcc.dg/vect/bb-slp-10.c: Likewise.
+ * gcc.dg/vect/fast-math-bb-slp-call-1.c: Likewise.
+ * gcc.dg/vect/bb-slp-4.c: Likewise.
+ * gcc.dg/vect/bb-slp-11.c: Likewise.
+ * gcc.dg/vect/fast-math-bb-slp-call-2.c: Likewise.
+ * gcc.dg/vect/bb-slp-5.c: Likewise.
+ * gcc.dg/vect/bb-slp-20.c: Likewise.
+ * gcc.dg/vect/bb-slp-6.c: Likewise.
+ * gcc.dg/vect/bb-slp-21.c: Likewise.
+ * gcc.dg/vect/bb-slp-30.c: Likewise.
+ * gcc.dg/vect/bb-slp-13.c: Likewise.
+ * gcc.dg/vect/bb-slp-7.c: Likewise.
+ * gcc.dg/vect/bb-slp-22.c: Likewise.
+ * gcc.dg/unroll_2.c: Likewise.
+ * g++.dg/vect/slp-pr50413.cc: Likewise.
+ * g++.dg/vect/slp-pr56812.cc: Likewise.
+ * g++.dg/vect/slp-pr50819.cc: Likewise.
+
+2013-08-29 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.dg/tree-ssa/ipa-cp-1.c: Adjust regexp.
+
+2013-08-29 Teresa Johnson <tejohnson@google.com>
+
+ * gcc.dg/pr40209.c: Use -fopt-info.
+ * gcc.dg/pr26570.c: Ditto.
+ * gcc.dg/pr32773.c: Ditto.
+ * g++.dg/tree-ssa/dom-invalid.C: Ditto.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/58246
+ * gcc.dg/torture/pr58246.c: New testcase.
+
+2013-08-29 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/52243
+ * gfortran.dg/realloc_on_assign_14.f90: Remove warning made
+ obsolete by patch.
+ * gfortran.dg/realloc_on_assign_19.f90: New test.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/57287
+ * gcc.dg/pr57287-2.c: New testcase.
+
+2013-08-29 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57685
+ * gcc.dg/torture/pr57685.c: New testcase.
+
+2013-08-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58255
+ * g++.dg/cpp0x/dc7.C: New.
+
+2013-08-28 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/58257
+ * c-c++-common/gomp/pr58257.c: New test.
+
+2013-08-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/56933
+ * gcc.dg/vect/pr56933.c: Properly guard runtime with check_vect ().
+
+2013-08-27 Vidya Praveen <vidyapraveen@arm.com>
+
+ * gcc.target/aarch64/scalar_shift_1.c: New.
+
+2013-08-27 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/57521
+ * gcc.dg/torture/pr57521.c: New testcase.
+
+2013-08-27 Jakub Jelinek <jakub@redhat.com>
+
+ PR rtl-optimization/57860
+ PR rtl-optimization/57861
+ PR rtl-optimization/57875
+ PR rtl-optimization/57876
+ PR rtl-optimization/57877
+ * gcc.c-torture/execute/pr57860.c: New test.
+ * gcc.c-torture/execute/pr57861.c: New test.
+ * gcc.c-torture/execute/pr57875.c: New test.
+ * gcc.c-torture/execute/pr57876.c: New test.
+ * gcc.c-torture/execute/pr57877.c: New test.
+
+2013-08-26 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/58146
+ * gfortran.dg/bounds_check_18.f90: New test.
+
+2013-08-23 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/ipa/devirt-14.C: Fix typo.
+
+2013-08-23 Mikael Morin <mikael@gcc.gnu.org>
+
+ PR fortran/57798
+ * gfortran.dg/inline_sum_5.f90: New.
+
+2013-08-23 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/57843
+ * gfortran.dg/typebound_assignment_7.f90: New.
+
+2013-08-23 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/ipa/devirt-13.C: New testcase.
+ * g++.dg/ipa/devirt-14.C: New testcase.
+
+2013-08-23 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/58218
+ * gcc.target/i386/pr58218.c: New test.
+
+ PR tree-optimization/58209
+ * gcc.c-torture/execute/pr58209.c: New test.
+
+2013-08-22 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/pr57744.c: Declare abort.
+
+2013-08-22 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56380
+ * g++.dg/template/error54.C: New.
+
+2013-08-22 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58185
+ * gfortran.dg/select_type_34.f90: New.
+
+2013-08-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56130
+ * g++.dg/warn/deprecated-7.C: New.
+
+2013-08-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/tree-prof/pr57451.C: Remove spurious dg-do directive.
+
+2013-08-21 Jeff Law <law@redhat.com>
+
+ * gcc.dg/tree-ssa/ssa-vrp-thread-1.c: New test.
+
+2013-08-21 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/56134
+ * g++.dg/ext/attr-alias-3.C: New.
+
+2013-08-20 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/53655
+ * gfortran.dg/intent_out_8.f90: New.
+
+2013-08-20 Teresa Johnson <tejohnson@google.com>
+
+ PR rtl-optimizations/57451
+ * g++.dg/tree-prof/pr57451.C: New test.
+
+2013-08-20 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58190
+ * g++.dg/pr57878.C: Use __SIZE_TYPE__.
+
+2013-08-19 Balaji V. Iyer <balaji.v.iyer@intel.com>
+
+ PR c/57490
+ * c-c++-common/cilk-plus/AN/pr57490.c: New test.
+
+2013-08-19 Peter Bergner <bergner@vnet.ibm.com>
+
+ * gcc.target/powerpc/dfp-dd-2.c: New test.
+ * gcc.target/powerpc/dfp-td-2.c: Likewise.
+ * gcc.target/powerpc/dfp-td-3.c: Likewise.
+
+2013-08-19 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.target/mips/mulsize-1.c: Check for SLL as well as SUBU.
+ * gcc.target/mips/mulsize-2.c: Check for ADDU rather than SUBU.
+ Check for SLL too.
+
+2013-08-19 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * gcc.target/avr/progmem-error-1.cpp: Update linenumber of error.
+
+ * gcc.dg/tree-ssa/ssa-dom-thread-4.c [avr-*-*]: Expect 6 times
+ "Threaded".
+
+ * gcc.dg/tree-ssa/vrp55.c: Use keeps_null_pointer_checks to determine
+ correct test response.
+
+ PR testsuite/52641
+ * gcc.dg/tree-ssa/pr31261.c [int16]: Change expected unsigned type.
+ * gcc.dg/tree-ssa/ssa-pre-21.c [! size32plus]: Mark as xfail.
+ * gcc.dg/tree-ssa/vector-4.c (SItype): New typedef.
+ (v4si): Use it.
+ * gcc.dg/tree-ssa/ssa-pre-30.c: Test requires int32.
+ * gcc.dg/tree-ssa/vrp58.c: Adjust scan expression for int16.
+
+ * gcc.dg/tree-ssa/vrp87.c [avr-*-*] (dg-additional-options): New.
+
+2013-08-18 Jan Hubicka <jh@suse.cz>
+
+ * g++.dg/ipa/type-inheritance-1.C: New testcase.
+
+2013-08-19 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/46271
+ * gfortran.dg/gomp/proc_ptr_1.f90: New.
+
+2013-08-18 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58006
+ * g++.dg/opt/pr58006.C: New test.
+
+2013-08-18 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/specs/linker_alias.ads: New test.
+
+2013-08-16 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58164
+ * gcc.c-torture/compile/pr58164.c: New test.
+
+ PR tree-optimization/58165
+ * g++.dg/opt/pr58165.C: New test.
+
+2013-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/51912
+ * g++.dg/cpp0x/enum28.C: New.
+ * g++.dg/cpp0x/enum15.C: Adjust.
+
+2013-08-14 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR target/57949
+ * gcc.target/powerpc/pr57949-1.c: New.
+ * gcc.target/powerpc/pr57949-2.c: New.
+
+2013-08-14 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/58145
+ * gcc.dg/pr58145-1.c: New test.
+ * gcc.dg/pr58145-2.c: New test.
+
+2013-08-14 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * gcc.dg/debug/dwarf2/dwarf2.exp: Replace -gdwarf-2 with -gdwarf.
+ * gcc.dg/debug/dwarf2/dwarf-die7.c: Likewise.
+ * gcc.dg/debug/dwarf2/static1.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-dfp.c: Likewise.
+ * gcc.dg/debug/dwarf2/fesd-any.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-uninit.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-die1.c: Likewise.
+ * gcc.dg/debug/dwarf2/var1.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr29609-2.c: Likewise.
+ * gcc.dg/debug/dwarf2/aranges-fnsec-1.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-die3.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-merge.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-char1.c: Likewise.
+ * gcc.dg/debug/dwarf2/discriminator.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-char2.c: Likewise.
+ * gcc.dg/debug/dwarf2/fesd-baseonly.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr36690-3.c: Likewise.
+ * gcc.dg/debug/dwarf2/const-2.c: Likewise.
+ * gcc.dg/debug/dwarf2/ipa-cp1.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-char3.c: Likewise.
+ * gcc.dg/debug/dwarf2/var2.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr36690-2.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr31230.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-float.c: Likewise.
+ * gcc.dg/debug/dwarf2/short-circuit.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr36690-1.c: Likewise.
+ * gcc.dg/debug/dwarf2/fesd-reduced.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr37616.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-die2.c: Likewise.
+ * gcc.dg/debug/dwarf2/inline1.c: Likewise.
+ * gcc.dg/debug/dwarf2/fesd-sys.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr29609-1.c: Likewise.
+ * gcc.dg/debug/dwarf2/asm-line1.c: Likewise.
+ * gcc.dg/debug/dwarf2/c99-typedef1.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf2-macro.c: Likewise.
+ * gcc.dg/debug/dwarf2/fesd-none.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr51410.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-file1.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-die6.c: Likewise.
+ * gcc.dg/debug/dwarf2/const-2b.c: Likewise.
+ * gcc.dg/debug/dwarf2/dwarf-die5.c: Likewise.
+
+ PR testsuite/52641
+ * gcc.c-torture/execute/pr56799.x: New file.
+
+ * gcc.dg/c99-stdint-1.c [avr-*-*]: Update line number for dg-bogus.
+
+ * gcc.dg/torture/stackalign/builtin-apply-2.c: Also skip for avr.
+
+ * gcc.dg/pr44214-1.c (v2df): Define size using sizeof (double).
+ * gcc.dg/pr44214-3.c (v2df): Likewise.
+
+ * gcc.dg/pr46647.c: xfail for avr-*-*.
+
+ * gcc.dg/strlenopt-10.c [avr-*-*]: Reduce number of expected
+ memcpy by one.
+ * gcc.dg/strlenopt-11.c [avr-*-*]: Likewise.
+ Expect l to be optimized away.
+ * gcc.dg/strlenopt-13.c [avr-*-*]: Likewise.
+
+ PR testsuite/52641
+ * c-c++-common/scal-to-vec1.c: Add !int16 and large_double conditions
+ to tests that assume int/double are larger than short/float.
+
+ PR testsuite/52641
+ * c-c++-common/simulate-thread/bitfields-2.c: Run test only for
+ target { ! int16 }.
+ * gcc.dg/tree-ssa/pr54245.c: Do slsr scan only for target { ! int16 }.
+ * gcc.dg/tree-ssa/slsr-1.c: Adjust multiplicators to scan for for
+ target { int16 }. Restrict existing tests to target { int32 }
+ where appropriate.
+ * gcc.dg/tree-ssa/slsr-2.c, gcc.dg/tree-ssa/slsr-27.c: Likewise.
+ * gcc.dg/tree-ssa/slsr-28.c, gcc.dg/tree-ssa/slsr-29.c: Likewise.
+ * gcc.dg/tree-ssa/slsr-3.c, gcc.dg/tree-ssa/ssa-ccp-23.c: Likewise.
+ * lib/target-supports.exp (check_effective_target_int32): New proc.
+
+ * gcc.dg/tree-ssa/pr42585.c: Add avr-*-* to list of targets to
+ exclude from scan test.
+
+ * gcc.dg/debug/dwarf2/global-used-types.c: Request dwarf output.
+ * gcc.dg/debug/dwarf2/inline2.c: Likewise.
+ * gcc.dg/debug/dwarf2/inline3.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr37726.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr41445-1.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr41445-2.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr41445-3.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr41445-4.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr41445-5.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr41445-6.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr41543.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr41695.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr43237.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr47939-1.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr47939-2.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr47939-3.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr47939-4.c: Likewise.
+ * gcc.dg/debug/dwarf2/pr53948.c: Likewise.
+ * gcc.dg/debug/dwarf2/struct-loc1.c: Likewise.
+
+2013-08-14 Janis Johnson <janisjo@codesourcery.com>
+
+ * gcc.target/arm/pr19599.c: Skip for -mthumb.
+
+ * gcc.target/arm/atomic-comp-swap-release-acquire.c: Move dg-do
+ to be the first test directive.
+ * gcc.target/arm/atomic-op-acq_rel.c: Likewise.
+ * gcc.target/arm/atomic-op-acquire.c: Likewise.
+ * gcc.target/arm/atomic-op-char.c: Likewise.
+ * gcc.target/arm/atomic-op-consume.c: Likewise.
+ * gcc.target/arm/atomic-op-int.c: Likewise.
+ * gcc.target/arm/atomic-op-relaxed.c: Likewise.
+ * gcc.target/arm/atomic-op-release.c: Likewise.
+ * gcc.target/arm/atomic-op-seq_cst.c: Likewise.
+ * gcc.target/arm/atomic-op-short.c: Likewise.
+
+2013-08-14 Andrey Belevantsev <abel@ispras.ru>
+
+ PR rtl-optimization/57662
+ * gcc.dg/pr57662.c: New test.
+
+2013-08-13 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * gcc.target/mips/nan-legacy.c: Accept 4294967295 as an
+ alternative to -1.
+ * gcc.target/mips/nans-legacy.c: Likewise.
+
+2013-08-13 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * gcc.target/mips/fabs-2008.c: Correct scan-assembler pattern
+ escapes.
+ * gcc.target/mips/fabs-legacy.c: Likewise.
+ * gcc.target/mips/fabsf-2008.c: Likewise.
+ * gcc.target/mips/fabsf-legacy.c: Likewise.
+ * gcc.target/mips/fneg-2008.c: Likewise.
+ * gcc.target/mips/fneg-legacy.c: Likewise.
+ * gcc.target/mips/fnegf-2008.c: Likewise.
+ * gcc.target/mips/fnegf-legacy.c: Likewise.
+ * gcc.target/mips/nan-2008.c: Likewise.
+ * gcc.target/mips/nan-legacy.c: Likewise.
+ * gcc.target/mips/nanf-2008.c: Likewise.
+ * gcc.target/mips/nanf-legacy.c: Likewise.
+ * gcc.target/mips/nans-2008.c: Likewise.
+ * gcc.target/mips/nans-legacy.c: Likewise.
+ * gcc.target/mips/nansf-2008.c: Likewise.
+ * gcc.target/mips/nansf-legacy.c: Likewise.
+
+2013-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/valued_proc.adb: New test.
+ * gnat.dg/valued_proc_pkg.ads: New helper.
+
+2013-08-13 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/57661
+ * g++.dg/opt/pr57661.C: New test.
+
+ PR sanitizer/56417
+ * gcc.dg/asan/pr56417.c: New test.
+
+2013-08-13 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/loop_optimization16.adb: New test.
+ * gnat.dg/loop_optimization16_pkg.ad[sb]: New helper.
+
+2013-08-13 Marek Polacek <polacek@redhat.com>
+
+ * gcc.dg/pr57980.c: Use vector of two elements, not just one.
+
+2013-08-13 David Malcolm <dmalcolm@redhat.com>
+
+ Example of converting global state to per-pass state.
+
+ * gcc.dg/plugin/one_time_plugin.c (one_pass::execute): Convert
+ global state "static int counter" to...
+ (one_pass::counter): ...this instance data.
+
+2013-08-13 David Malcolm <dmalcolm@redhat.com>
+
+ * gcc.dg/plugin/one_time_plugin.c: (one_pass_gate): Convert
+ to member function...
+ (one_pass::gate): ...this.
+ (one_pass_exec): Convert to member function...
+ (one_pass::impl_execute): ...this.
+
+2013-08-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57416
+ * g++.dg/cpp0x/pr57416.C: New.
+
+2013-08-12 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * g++.dg/cpp0x/constexpr-function2.C: Adjust for error -> inform
+ changes.
+ * g++.dg/cpp0x/constexpr-neg1.C: Likewise.
+ * g++.dg/cpp0x/defaulted2.C: Likewise.
+ * g++.dg/cpp0x/defaulted31.C: Likewise.
+ * g++.dg/cpp0x/error6.C: Likewise.
+ * g++.dg/cpp0x/gen-attrs-32.C: Likewise.
+ * g++.dg/cpp0x/override2.C: Likewise.
+ * g++.dg/cpp0x/parse1.C: Likewise.
+ * g++.dg/cpp0x/scoped_enum.C: Likewise.
+ * g++.dg/cpp0x/temp_default4.C: Likewise.
+ * g++.dg/ext/attrib32.C: Likewise.
+ * g++.dg/ext/gnu-inline-global-reject.C: Likewise.
+ * g++.dg/ext/mv13.C: Likewise.
+ * g++.dg/ext/mv7.C: Likewise.
+ * g++.dg/ext/mv9.C: Likewise.
+ * g++.dg/ext/pr57362.C: Likewise.
+ * g++.dg/ext/typeof10.C: Likewise.
+ * g++.dg/lookup/anon6.C: Likewise.
+ * g++.dg/lookup/crash6.C: Likewise.
+ * g++.dg/lookup/name-clash5.C: Likewise.
+ * g++.dg/lookup/name-clash6.C: Likewise.
+ * g++.dg/other/anon4.C: Likewise.
+ * g++.dg/other/error15.C: Likewise.
+ * g++.dg/other/error8.C: Likewise.
+ * g++.dg/other/redecl2.C: Likewise.
+ * g++.dg/parse/crash16.C: Likewise.
+ * g++.dg/parse/crash21.C: Likewise.
+ * g++.dg/parse/crash38.C: Likewise.
+ * g++.dg/parse/redef2.C: Likewise.
+ * g++.dg/parse/struct-as-enum1.C: Likewise.
+ * g++.dg/template/crash39.C: Likewise.
+ * g++.dg/template/redecl3.C: Likewise.
+ * g++.dg/tls/diag-3.C: Likewise.
+ * g++.dg/warn/Wredundant-decls-spec.C: Likewise.
+ * g++.old-deja/g++.benjamin/typedef01.C: Likewise.
+ * g++.old-deja/g++.benjamin/warn02.C: Likewise.
+ * g++.old-deja/g++.brendan/crash16.C: Likewise.
+ * g++.old-deja/g++.brendan/crash18.C: Likewise.
+ * g++.old-deja/g++.brendan/err-msg4.C: Likewise.
+ * g++.old-deja/g++.brendan/redecl1.C: Likewise.
+ * g++.old-deja/g++.brendan/static3.C: Likewise.
+ * g++.old-deja/g++.bugs/900127_02.C: Likewise.
+ * g++.old-deja/g++.jason/binding.C: Likewise.
+ * g++.old-deja/g++.jason/crash4.C: Likewise.
+ * g++.old-deja/g++.jason/crash7.C: Likewise.
+ * g++.old-deja/g++.jason/lineno.C: Likewise.
+ * g++.old-deja/g++.jason/scoping7.C: Likewise.
+ * g++.old-deja/g++.mike/misc3.C: Likewise.
+ * g++.old-deja/g++.mike/net44.C: Likewise.
+ * g++.old-deja/g++.mike/ns3.C: Likewise.
+ * g++.old-deja/g++.ns/alias4.C: Likewise.
+ * g++.old-deja/g++.ns/ns11.C: Likewise.
+ * g++.old-deja/g++.other/crash23.C: Likewise.
+ * g++.old-deja/g++.other/decl8.C: Likewise.
+ * g++.old-deja/g++.other/linkage3.C: Likewise.
+ * g++.old-deja/g++.other/typeck1.C: Likewise.
+ * g++.old-deja/g++.other/typedef5.C: Likewise.
+ * g++.old-deja/g++.pt/explicit34.C: Likewise.
+ * g++.old-deja/g++.pt/friend36.C: Likewise.
+ * obj-c++.dg/method-8.mm: Likewise.
+ * obj-c++.dg/tls/diag-3.mm: Likewise.
+
+2013-08-12 Perez Read <netfirewall@gmail.com>
+
+ PR target/58132
+ * gcc.target/i386/movabs-1.c: New test.
+
+2013-08-12 Marek Polacek <polacek@redhat.com>
+
+ PR tree-optimization/57980
+ * gcc.dg/pr57980.c: New test.
+
+2013-08-12 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/56666
+ * gfortran.dg/do_check_10.f90: New test.
+ * gfortran.dg/array_constructor_11.f90: Add -Wzerotrip to dg-options.
+ * gfortran.dg/array_constructor_18.f90: Likewise.
+ * gfortran.dg/array_constructor_22.f90: Likewise.
+ * gfortran.dg/coarray_15.f90: Likewise.
+ * gfortran.dg/do_1.f90: Add -Wall to dg-options.
+ * gfortran.dg/do_3.F90: Add -Wzerotrip to dg-options.
+ * gfortran.dg/do_check_5.f90: Add -Wall to gd-options.
+
+2013-08-11 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/53349
+ * g++.dg/cpp0x/constexpr-ice8.C: New.
+
+2013-08-09 Xinliang David Li <davidxl@google.com>
+
+ * gcc.target/i386/memcpy-strategy-1.c: New test.
+ * gcc.target/i386/memcpy-strategy-2.c: Ditto.
+ * gcc.target/i386/memset-strategy-1.c: Ditto.
+ * gcc.target/i386/memcpy-strategy-3.c: Ditto.
+
+2013-08-09 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-prof/crossmodule-indircall-1.c: New testcase.
+ * gcc.dg/tree-prof/crossmodule-indircall-1a.c: New testcase.
+
+2013-08-09 Yufeng Zhang <yufeng.zhang@arm.com>
+
+ * gcc.dg/lower-subreg-1.c: Skip aarch64*-*-*.
+
+2013-08-09 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/58058
+ * gfortran.dg/transfer_intrinsic_6.f90: New.
+
+2013-08-09 Paolo Carlini <paolo.carlini@oracle.com>
+
+ Revert:
+ 2013-08-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46206
+ * g++.dg/lookup/typedef2.C: New.
+
+2013-08-09 James Greenhalgh <james.greenhalgh@arm.com>
+
+ * gcc.target/aarch64/scalar_intrinsics.c: Update expected
+ output of vdup intrinsics.
+
+2013-08-09 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ * gcc.target/arm/lp1189445.c: New testcase.
+
+2013-08-08 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.dg/torture/pr58079.c: New test.
+
+2013-08-07 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnat.dg/warn9.adb: New test.
+
+2013-08-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/46206
+ * g++.dg/lookup/typedef2.C: New.
+
+2013-08-07 David Malcolm <dmalcolm@redhat.com>
+
+ * lib/plugin-support.exp (plugin-test-execute): Add -fno-rtti
+ to optstr when building plugins on darwin.
+
+2013-08-06 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/57539
+ * gcc.dg/ipa/pr57539.c: New test.
+
+2013-08-06 Martin Jambor <mjambor@suse.cz>
+ Bernd Edlinger <bernd.edlinger@hotmail.de>
+
+ * gcc.dg/torture/pr58041.c (foo): Accept z by reference.
+ (a): Fix constructor.
+
+2013-08-06 Martin Jambor <mjambor@suse.cz>
+
+ PR fortran/57987
+ * gfortran.dg/pr57987.f90: New test.
+
+2013-08-06 Martin Jambor <mjambor@suse.cz>
+
+ PR middle-end/58041
+ * gcc.dg/torture/pr58041.c: New test.
+ * gcc.target/arm/pr58041.c: Likewise.
+
+2013-08-06 Janus Weil <janus@gcc.gnu.org>
+
+ PR fortran/57306
+ * gfortran.dg/pointer_init_8.f90: New.
+
+2013-08-05 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/58080
+ * g++.dg/cpp0x/pr58080.C: New.
+
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ * lib/plugin-support.exp (plugin-test-execute): Add -fno-rtti
+ to optstr when building plugins.
+
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ Patch autogenerated by refactor_passes.py from
+ https://github.com/davidmalcolm/gcc-refactoring-scripts
+ revision 03fe39476a4c4ea450b49e087cfa817b5f92021e
+
+ * gcc.dg/plugin/one_time_plugin.c (one_pass): Convert from a global
+ struct to a subclass of gimple_opt_pass along with...
+ (pass_data_one_pass): ...new pass_data instance and...
+ (make_one_pass): ...new function.
+ * gcc.dg/plugin/selfassign.c (pass_warn_self_assign): Convert from a
+ global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_warn_self_assign): ...new pass_data instance and...
+ (make_pass_warn_self_assign): ...new function.
+ * g++.dg/plugin/dumb_plugin.c (pass_dumb_plugin_example): Convert from
+ a global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_dumb_plugin_example): ...new pass_data instance and...
+ (make_pass_dumb_plugin_example): ...new function.
+ * g++.dg/plugin/selfassign.c (pass_warn_self_assign): Convert from a
+ global struct to a subclass of gimple_opt_pass along with...
+ (pass_data_warn_self_assign): ...new pass_data instance and...
+ (make_pass_warn_self_assign): ...new function.
+
+2013-08-05 David Malcolm <dmalcolm@redhat.com>
+
+ * g++.dg/plugin/dumb_plugin.c (plugin_init): Rework how the pass
+ is created and added to the pass_manager to reflect
+ autogenerated changes.
+ * g++.dg/plugin/selfassign.c (plugin_init): Likewise.
+ * gcc.dg/plugin/one_time_plugin.c (plugin_init): Likewise.
+ * gcc.dg/plugin/selfassign.c (plugin_init): Likewise.
+
+2013-08-04 Ed Smith-Rowland <3dw4rd@verizon.net>
+
+ PR c++/58072
+ * g++.dg/cpp0x/pr58072.C: New.
+
+2013-08-03 Bill Schmidt <wschmidt@vnet.linux.ibm.com>
+
+ * gcc.dg/torture/pr57993-2.cpp: New.
+
+2013-08-02 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/ipa/ipa-1.c: Update.
+ * gcc.dg/ipa/ipa-2.c: Update.
+ * gcc.dg/ipa/ipa-3.c: Update.
+ * gcc.dg/ipa/ipa-4.c: Update.
+ * gcc.dg/ipa/ipa-5.c: Update.
+ * gcc.dg/ipa/ipa-7.c: Update.
+ * gcc.dg/ipa/ipa-8.c: Update.
+ * gcc.dg/ipa/ipcp-1.c: Update.
+ * gcc.dg/ipa/ipcp-2.c: Update.
+
+2013-08-02 Vladimir Makarov <vmakarov@redhat.com>
+
+ PR rtl-optimization/58048
+ * gcc.target/i386/pr58048.c: New.
+
+2013-08-02 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/arm/neon-for-64bits-2.c: Delete.
+
+2013-08-01 Fabien Chêne <fabien@gcc.gnu.org>
+ Peter Bergner <bergner@vnet.ibm.com>
+
+ PR c++/54537
+ * g++.dg/overload/using3.C: New.
+ * g++.dg/overload/using2.C: Adjust.
+ * g++.dg/lookup/using9.C: Likewise.
+
+2013-08-01 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * gcc.target/arm/pr46972-2.c: New test.
+
+2013-08-01 Vidya Praveen <vidyapraveen@arm.com>
+
+ * gcc.dg/vect/vect-iv-5.c: Make xfail conditional with !arm_neon_ok.
+
+2013-07-31 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/fusion.c: New file, test power8 fusion support.
+
+2013-07-31 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * gcc.target/mips/mips.exp (mips-dg-options): Test for mabicalls
+ rather than addressing!=absolute when deciding how to handle MIPS16
+ when the test forces an ABI.
+
+2013-07-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57673
+ * g++.dg/cpp0x/nsdmi-sizeof.C: New.
+
+2013-07-30 Steve Ellcey <sellcey@mips.com>
+
+ * gcc.target/mips/code-readable-1.c: Increase switch size.
+ * gcc.target/mips/code-readable-2.c: Ditto.
+ * gcc.target/mips/code-readable-3.c: Ditto.
+ * gcc.target/mips/code-readable-4.c: Ditto.
+
+2013-07-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57947
+ * g++.dg/parse/crash63.C: New.
+
+2013-07-30 Tobias Burnus <burnus@net-b.de>
+
+ PR fortran/57530
+ * gfortran.dg/pointer_assign_8.f90: New.
+ * gfortran.dg/pointer_assign_9.f90: New.
+ * gfortran.dg/pointer_assign_10.f90: New.
+ * gfortran.dg/pointer_assign_11.f90: New.
+
+2013-07-30 Zhenqiang Chen <zhenqiang.chen@linaro.org>
+
+ * gcc.target/arm/pr57637.c: New testcase.
+
+2013-07-29 Bill Schmidt <wschmidt@vnet.linux.ibm.com>
+
+ PR tree-optimization/57993
+ * gcc.dg/torture/pr57993.c: New test.
+
+2013-07-29 Joern Rennecke <joern.rennecke@embecosm.com>
+
+ * gcc.dg/tree-ssa/pr44258.c: Disable scan test for Epiphany.
+
+2013-07-29 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/57948
+ * g++.dg/conversion/ambig2.C: New.
+
+2013-07-29 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * gcc.target/mips/fabs-2008.c: New test case.
+ * gcc.target/mips/fabs-legacy.c: New test case.
+ * gcc.target/mips/fabsf-2008.c: New test case.
+ * gcc.target/mips/fabsf-legacy.c: New test case.
+ * gcc.target/mips/fneg-2008.c: New test case.
+ * gcc.target/mips/fneg-legacy.c: New test case.
+ * gcc.target/mips/fneg-2008.c: New test case.
+ * gcc.target/mips/fneg-legacy.c: New test case.
+ * gcc.target/mips/nan-2008.c: New test case.
+ * gcc.target/mips/nan-legacy.c: New test case.
+ * gcc.target/mips/nanf-2008.c: New test case.
+ * gcc.target/mips/nanf-legacy.c: New test case.
+ * gcc.target/mips/nans-2008.c: New test case.
+ * gcc.target/mips/nans-legacy.c: New test case.
+ * gcc.target/mips/nansf-2008.c: New test case.
+ * gcc.target/mips/nansf-legacy.c: New test case.
+ * gcc.target/mips/mips.exp: Handle `-mabs=' and `-mnan='.
+
2013-07-29 Alexander Ivchenko <alexander.ivchenko@intel.com>
Maxim Kuvyrkov <maxim@kugelworks.com>
@@ -65,7 +1177,7 @@
* gcc.c-torture/execute/builtins/stpcpy-chk.x: Likewise.
* gcc.dg/pr27095.c: For Epiphany, add -mshort-calls.
- * gcc.dg/tree-ssa/loop-1.c: Likewise.
+ * gcc.dg/tree-ssa/loop-1.c: Likewise.
* gcc.dg/torture/pr37868.c: Disable for epiphany.
* gcc.dg/sibcall-6.c: Enable for epiphany.
@@ -127,8 +1239,7 @@
2013-07-23 Michael Meissner <meissner@linux.vnet.ibm.com>
* gcc.target/powerpc/bool2.h: New file, test the code generation
- of logical operations for power5, altivec, power7, and power8
- systems.
+ of logical operations for power5, altivec, power7, and power8 systems.
* gcc.target/powerpc/bool2-p5.c: Likewise.
* gcc.target/powerpc/bool2-av.c: Likewise.
* gcc.target/powerpc/bool2-p7.c: Likewise.
@@ -281,7 +1392,7 @@
* gcc.target/aarch64/vabs_intrinsic_1.c: New file.
-2013-07-20 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-07-20 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.dg/pr57154.c: Add dg-require-effective-target scheduling.
@@ -337,14 +1448,13 @@
PR middle-end/57698
* gcc.c-torture/compile/pr57698.c: New test.
- * gcc.c-torture/compile/pr43791.c: Remove prune output
- directive.
+ * gcc.c-torture/compile/pr43791.c: Remove prune output directive.
* gcc.c-torture/compile/pr44043.c: Ditto.
2013-07-18 Wei Mi <wmi@google.com>
PR rtl-optimization/57878
- * g++.dg/pr57518.C: New test.
+ * g++.dg/pr57878.C: New test.
2013-07-18 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
@@ -586,7 +1696,7 @@
PR c++/14263
* g++.dg/inherit/virtual10.C: New.
-2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
PR c/57821
* gcc.dg/large-size-array-6.c: New test.
@@ -596,7 +1706,7 @@
PR c++/38634
* g++.dg/template/crash116.C: New.
-2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-07-04 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.dg/tree-ssa/vrp66.c: Make conditional on { target { ! int16 } } .
* gcc.dg/tree-ssa/vrp66-int16-sw.c: New test.
@@ -803,7 +1913,7 @@
* g++.dg/cpp0x/sfinae47.C: New.
-2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
+2013-06-23 Oleg Endo <olegendo@gcc.gnu.org>
PR target/52483
* gcc.target/sh/pr52483-1.c: New.
@@ -995,7 +2105,7 @@
* c-c++-common/cilk-plus/AN/if_test.c (main2): Fixed a bug of
accidentally placing minus sign for length instead of stride.
-2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-06-16 Joern Rennecke <joern.rennecke@embecosm.com>
PR rtl-optimization/57425
PR rtl-optimization/57569
@@ -1039,7 +2149,7 @@
PR c++/51413
* g++.dg/ext/builtin-offsetof1.C: New.
-2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
+2013-06-14 Vidya Praveen <vidyapraveen@arm.com>
* gcc.target/aarch64/vect_smlal_1.c: New file.
@@ -1078,8 +2188,8 @@
* gcc.dg/tree-ssa/forwprop-27.c: New testcase.
2013-06-12 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/atomic-p7.c: New file, add tests for atomic
load/store instructions on power7, power8.
@@ -1154,8 +2264,8 @@
in how we check __sec_reduce_mutating function's result.
2013-06-10 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/direct-move-vint1.c: New tests for power8
direct move instructions.
@@ -1336,8 +2446,8 @@
* g++.dg/cpp0x/alias-decl-36.C: New.
2013-06-06 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/p8vector-builtin-1.c: New test to test
power8 builtin functions.
@@ -1938,7 +3048,7 @@
PR debug/57351
* gcc.dg/debug/pr57351.c: New test
-2013-05-23 Vidya Praveen <vidyapraveen@arm.com>
+2013-05-23 Vidya Praveen <vidyapraveen@arm.com>
* gcc.target/aarch64/vect-clz.c: New file.
@@ -1976,8 +3086,8 @@
* g++.dg/parse/crash62.C: New.
2013-05-22 Michael Meissner <meissner@linux.vnet.ibm.com>
- Pat Haugen <pthaugen@us.ibm.com>
- Peter Bergner <bergner@vnet.ibm.com>
+ Pat Haugen <pthaugen@us.ibm.com>
+ Peter Bergner <bergner@vnet.ibm.com>
* gcc.target/powerpc/crypto-builtin-1.c: New file, test for power8
crypto builtins.
@@ -2267,7 +3377,7 @@
(alloca): Remove declaration.
(foo9): Replace alloca by __builtin_alloca.
-2013-05-14 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-05-14 Joern Rennecke <joern.rennecke@embecosm.com>
* gcc.c-torture/compile/limits-externdecl.c [target avr-*-*]:
Expect "size of array is too large" error.
@@ -2564,7 +3674,7 @@
* gcc.target/i386/sse2-init-v2di-2.c: Update scan assembler string.
-2013-05-03 Vidya Praveen <vidyapraveen@arm.com>
+2013-05-03 Vidya Praveen <vidyapraveen@arm.com>
* gcc.target/aarch64/fabd.c: New file.
@@ -3261,12 +4371,12 @@
* gcc.dg/vect/slp-39.c: New testcase.
-2013-04-10 Joern Rennecke <joern.rennecke@embecosm.com>
+2013-04-10 Joern Rennecke <joern.rennecke@embecosm.com>
PR tree-optimization/55524
* gcc.target/epiphany/fnma-1.c: New test.
-2013-04-10 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
+2013-04-10 Zhouyi Zhou <yizhouzhou@ict.ac.cn>
* gcc.dg/tree-ssa/inline-11.c: New test
@@ -3949,7 +5059,7 @@
* gcc.dg/pr56355-1.c: New file.
2013-03-20 Catherine Moore <clm@codesourcery.com>
- Richard Sandiford <rdsandiford@googlemail.com>
+ Richard Sandiford <rdsandiford@googlemail.com>
* gcc.target/mips/mips.exp: Add microMIPS support.
* gcc.target/mips/umips-movep-2.c: New test.
diff --git a/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57490.c b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57490.c
new file mode 100644
index 00000000000..db38b30b5f3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cilk-plus/AN/pr57490.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-fcilkplus" } */
+
+const int n = 8;
+float x[8], y[8], z[8];
+int main() {
+ int i = 0;
+ float x_sum =0;
+ for(i=1; i<=5; i+=4 ) {
+ x[0:n] = 3;
+ y[0:n] = i;
+ z[0:n] = 0;
+ (void)((__sec_reduce_add(x[0:n])==3*n) || (__builtin_abort (), 0));
+ (void)((__sec_reduce_add(y[0:n])==i*n) || (__builtin_abort (), 0));
+ (void)((__sec_reduce_add(z[0:n])==0) || (__builtin_abort (), 0));
+
+ if (x[0:n] >= y[0:n]) {
+ z[0:n] = x[0:n] - y[0:n];
+ } else {
+ z[0:n] = x[0:n] + y[0:n];
+ }
+ (void)((__sec_reduce_add(x[0:n])==3*n) || (__builtin_abort (), 0));
+ (void)((__sec_reduce_add(y[0:n])==i*n) || (__builtin_abort (), 0));
+ (void)((__sec_reduce_add(z[0:n])==(3>=i?3-i:3+i)*n)
+ || (__builtin_abort (), 0));
+ }
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/gomp/pr58257.c b/gcc/testsuite/c-c++-common/gomp/pr58257.c
new file mode 100644
index 00000000000..8f8d24a998a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/gomp/pr58257.c
@@ -0,0 +1,15 @@
+/* PR middle-end/58257 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fopenmp -Wall" } */
+
+int
+foo (int n)
+{
+ int a[10][10];
+ int x, y;
+#pragma omp parallel for collapse(2) /* { dg-bogus "may be used uninitialized in this function" } */
+ for (x = 0; x < n; x++) /* { dg-bogus "may be used uninitialized in this function" } */
+ for (y = 0; y < n; y++)
+ a[x][y] = x + y * y;
+ return a[0][0];
+}
diff --git a/gcc/testsuite/c-c++-common/opaque-vector.c b/gcc/testsuite/c-c++-common/opaque-vector.c
new file mode 100644
index 00000000000..cad266e893b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/opaque-vector.c
@@ -0,0 +1,22 @@
+#define B_TEST(TYPE) { TYPE v __attribute__((vector_size(16))); (void)((v < v) < v); }
+#ifdef __cplusplus
+#define T_TEST(TYPE) { TYPE s; TYPE v __attribute__((vector_size(16))); __typeof((v<v)[0]) iv __attribute__((vector_size(16))); (void)((iv ? s : s) < v); }
+#else
+#define T_TEST(TYPE)
+#endif
+#define T(TYPE) B_TEST(TYPE) T_TEST(TYPE)
+
+void f ()
+{
+ T(short)
+ T(int)
+ T(long)
+ T(long long)
+
+ T_TEST(float)
+ T_TEST(double)
+ /* Avoid trouble with non-power-of-two sizes. */
+#if !defined(__i386__) && !defined(__x86_64__) && !defined(__m68k__) && !defined(__ia64__)
+ T_TEST(long double)
+#endif
+}
diff --git a/gcc/testsuite/c-c++-common/scal-to-vec1.c b/gcc/testsuite/c-c++-common/scal-to-vec1.c
index beb450db624..52cc2e39af7 100644
--- a/gcc/testsuite/c-c++-common/scal-to-vec1.c
+++ b/gcc/testsuite/c-c++-common/scal-to-vec1.c
@@ -26,13 +26,13 @@ int main (int argc, char *argv[]) {
int i = 12;
double d = 3.;
- v1 = i + v0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */
+ v1 = i + v0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" "scalar to vector" { target { ! int16 } } } */
v1 = 99999 + v0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */
- f1 = d + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */
- f1 = 1.3 + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */
+ f1 = d + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" "scalar to vector" { target { large_double } } } */
+ f1 = 1.3 + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" "scalar to vector" { target { large_double } } } */
f1 = sll + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */
- f1 = ((int)998769576) + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" } */
+ f1 = ((int)998769576) + f0; /* { dg-error "conversion of scalar \[^\\n\]* to vector" "scalar to vector" { target { ! int16 } } } */
/* convert.c should take care of this. */
i1 = sfl + i0; /* { dg-error "can't convert value to a vector|invalid operands" } */
diff --git a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c
index 392f779bad5..0b29ffb68d4 100644
--- a/gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c
+++ b/gcc/testsuite/c-c++-common/simulate-thread/bitfields-2.c
@@ -1,4 +1,4 @@
-/* { dg-do link } */
+/* { dg-do link { target { ! int16 } } } */
/* { dg-options "--param allow-store-data-races=0" } */
/* { dg-final { simulate-thread } } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/const-char-1.c b/gcc/testsuite/c-c++-common/ubsan/const-char-1.c
new file mode 100644
index 00000000000..6c2c3f8c3aa
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/const-char-1.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift" } */
+
+void
+foo (void)
+{
+ int y = 1 << 2;
+ __builtin_printf ("%d\n", y);
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c b/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c
new file mode 100644
index 00000000000..f474ec64ef5
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/const-expr-1.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -w" } */
+
+enum e { A = 1 << 1, B, };
+const int arr[] = {
+ 1 << 2,
+ 1 << 3,
+};
+
+int
+bar (int a, int b)
+{
+ return a >> b;
+}
+
+int
+foo (void)
+{
+ int i = 1;
+ int vla[B << 3];
+ return bar (A, (i <<= 6, i + 2));
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c
new file mode 100644
index 00000000000..4e2a2b92749
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-1.c
@@ -0,0 +1,24 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-div-by-zero" } */
+
+int
+main (void)
+{
+ volatile int a = 0;
+ volatile long long int b = 0;
+ volatile unsigned int c = 1;
+
+ a / b;
+ 0 / 0;
+ a / 0;
+ 0 / b;
+ 2 / --c;
+
+ return 0;
+}
+
+/* { dg-output "division by zero(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c
new file mode 100644
index 00000000000..ee9673800d3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-2.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-div-by-zero" } */
+
+int
+main (void)
+{
+ volatile const unsigned long int o = 1UL;
+ int zero = 0;
+
+ o / 0;
+ 1UL / 0;
+ 1UL / zero;
+ o / zero;
+ o / (++zero - 1);
+
+ return 0;
+}
+
+/* { dg-output "division by zero(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division by zero(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c
new file mode 100644
index 00000000000..719e6c98634
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-3.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-overflow" } */
+
+#include <limits.h>
+
+int
+main (void)
+{
+ volatile int min = INT_MIN;
+ volatile int zero = 0;
+
+ INT_MIN / -1;
+ min / -1;
+ min / (10 * zero - (2 - 1));
+
+ return 0;
+}
+
+/* { dg-output "division of -2147483648 by -1 cannot be represented in type int(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type int(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*division of -2147483648 by -1 cannot be represented in type int(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/div-by-zero-4.c b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-4.c
new file mode 100644
index 00000000000..295f624dc34
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/div-by-zero-4.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=integer-divide-by-zero -Wno-overflow" } */
+
+#include <limits.h>
+
+int
+main (void)
+{
+ /* This should not fail. */
+ return (unsigned int) INT_MIN / -1;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/save-expr-1.c b/gcc/testsuite/c-c++-common/ubsan/save-expr-1.c
new file mode 100644
index 00000000000..24532e80761
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/save-expr-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
+
+static int x;
+int
+main (void)
+{
+ int o = 1;
+ int y = x << o;
+ return y;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/save-expr-2.c b/gcc/testsuite/c-c++-common/ubsan/save-expr-2.c
new file mode 100644
index 00000000000..14ac17def9c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/save-expr-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
+
+int
+foo (int i, unsigned int u)
+{
+ return u / i;
+}
+
+int
+bar (int i, unsigned int u)
+{
+ return u % i;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/save-expr-3.c b/gcc/testsuite/c-c++-common/ubsan/save-expr-3.c
new file mode 100644
index 00000000000..dd2903bd682
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/save-expr-3.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
+
+int x;
+
+int
+foo (int i, int u)
+{
+ return (i << u) << x;
+}
+
+int
+bar (int i, int u)
+{
+ return (i >> u) >> x;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/save-expr-4.c b/gcc/testsuite/c-c++-common/ubsan/save-expr-4.c
new file mode 100644
index 00000000000..aa34a70ede7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/save-expr-4.c
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -Wall -Werror -O" } */
+
+int x;
+
+int
+foo (int i, unsigned int u)
+{
+ return (i % u) << (x / u);
+}
+
+int
+bar (int i, unsigned int u)
+{
+ return (((x % u) << (u / i)) >> x);
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-1.c b/gcc/testsuite/c-c++-common/ubsan/shift-1.c
new file mode 100644
index 00000000000..48cf3cd7bff
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/shift-1.c
@@ -0,0 +1,31 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -w" } */
+
+typedef const unsigned long long int CULLI;
+typedef volatile int VI;
+struct s { signed long int a; };
+
+int
+main (void)
+{
+ int a = 1;
+ struct s s = { .a = 400 };
+ CULLI culli = 42;
+ VI vi = 370;
+ volatile int shiftcount = 153;
+
+ a <<= 152;
+ 1 << shiftcount;
+ 1 << 154;
+ culli << 524;
+ 1 << vi++;
+ (long) 1 << (s.a + 2);
+
+ return 0;
+}
+/* { dg-output "shift exponent 152 is too large for \[^\n\r]*-bit type int(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent 153 is too large for \[^\n\r]*-bit type int(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent 154 is too large for \[^\n\r]*-bit type int(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent 524 is too large for \[^\n\r]*-bit type long long unsigned int(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent 370 is too large for \[^\n\r]*-bit type int(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent 402 is too large for \[^\n\r]*-bit type long int(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-2.c b/gcc/testsuite/c-c++-common/ubsan/shift-2.c
new file mode 100644
index 00000000000..68a7d136f43
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/shift-2.c
@@ -0,0 +1,23 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -w" } */
+
+int
+main (void)
+{
+ int a = 1;
+ volatile int b = -5;
+ long long int c = -6;
+
+ a << -3;
+ 1 << -4;
+ 1 << b;
+ a << c;
+ a << (b + c);
+
+ return 0;
+}
+/* { dg-output "shift exponent -3 is negative(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent -4 is negative(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent -5 is negative(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent -6 is negative(\n|\r\n|\r)" } */
+/* { dg-output "\[^\n\r]*shift exponent -11 is negative(\n|\r\n|\r)" } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/shift-3.c b/gcc/testsuite/c-c++-common/ubsan/shift-3.c
new file mode 100644
index 00000000000..c639d171184
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/shift-3.c
@@ -0,0 +1,11 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -w" } */
+
+int
+main (void)
+{
+ unsigned int a = 1;
+ a <<= 31;
+ a <<= 1;
+ return 0;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/typedef-1.c b/gcc/testsuite/c-c++-common/ubsan/typedef-1.c
new file mode 100644
index 00000000000..8dcf451c348
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/typedef-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=undefined" } */
+
+typedef int V;
+int
+foo (void)
+{
+ V v = 9;
+ int a = 3;
+ v += v % a;
+ return v / 3;
+}
diff --git a/gcc/testsuite/c-c++-common/ubsan/unreachable-1.c b/gcc/testsuite/c-c++-common/ubsan/unreachable-1.c
new file mode 100644
index 00000000000..336240c96cb
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/unreachable-1.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=unreachable" } */
+/* { dg-shouldfail "ubsan" } */
+
+int
+main (void)
+{
+ __builtin_unreachable ();
+}
+ /* { dg-output "execution reached a __builtin_unreachable\\(\\) call" } */
diff --git a/gcc/testsuite/g++.dg/abi/mangle33.C b/gcc/testsuite/g++.dg/abi/mangle33.C
index f0a4e5012d3..8c77f1f0d09 100644
--- a/gcc/testsuite/g++.dg/abi/mangle33.C
+++ b/gcc/testsuite/g++.dg/abi/mangle33.C
@@ -15,5 +15,5 @@ namespace N {
int j;
}
-// { dg-final { scan-assembler "_ZN4043abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklm1iE" } }
-// { dg-final { scan-assembler "_ZN4041abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijk1jE" } }
+// { dg-final { scan-assembler "_ZN4043(abcdefghijklmnopqrstuvwxyz){155}abcdefghijklm1iE" } }
+// { dg-final { scan-assembler "_ZN4041(abcdefghijklmnopqrstuvwxyz){155}abcdefghijk1jE" } }
diff --git a/gcc/testsuite/g++.dg/conversion/ambig2.C b/gcc/testsuite/g++.dg/conversion/ambig2.C
new file mode 100644
index 00000000000..a9d9d699cf0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/conversion/ambig2.C
@@ -0,0 +1,18 @@
+// PR c++/57948
+
+struct Base { };
+struct Derived : Base
+{
+ struct Derived2 : Base
+ {
+ struct ConvertibleToBothDerivedRef
+ {
+ operator Derived&();
+ operator Derived2&();
+ void bind_lvalue_to_conv_lvalue_ambig(ConvertibleToBothDerivedRef both)
+ {
+ Base &br1 = both; // { dg-error "ambiguous" }
+ }
+ };
+ };
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-0.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-0.C
index c5760cfe537..f38f9932b44 100644
--- a/gcc/testsuite/g++.dg/cpp0x/alias-decl-0.C
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-0.C
@@ -10,14 +10,13 @@ void g(X<Z>);
void
foo()
{
- // Below x and y don't have the same type, because Y and Z don't
- // designate the same template ...
+ // Below x and y have the same type (DR 1286)
X<Y> y;
X<Z> z;
- // ... So these must fail to compile.
- f(z); // { dg-error "" }
- g(y); // { dg-error "" }
+ // ... So these must compile.
+ f(z); // { dg-bogus "" }
+ g(y); // { dg-bogus "" }
}
template<class> struct A0 {};
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C
new file mode 100644
index 00000000000..25781a484e0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-33.C
@@ -0,0 +1,14 @@
+// PR c++/51239
+// { dg-require-effective-target c++11 }
+
+template<class... x>
+class list{};
+template<class a, class... b>
+using tail=list<b...>;
+template <class...T>
+void f(tail<T...>); // { dg-error "alias" }
+
+int main()
+{
+ f<int,int>({});
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-33a.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-33a.C
new file mode 100644
index 00000000000..a1c442eabeb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-33a.C
@@ -0,0 +1,15 @@
+// PR c++/51239
+// { dg-require-effective-target c++11 }
+// This variant should work because tail is equivalent to list.
+
+template<class y, class... x>
+class list{};
+template<class a, class... b>
+using tail=list<a, b...>;
+template <class...T>
+void f(tail<T...>);
+
+int main()
+{
+ f<int,int>({});
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C
new file mode 100644
index 00000000000..d6a3e12cea2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-37.C
@@ -0,0 +1,21 @@
+// PR c++/57138
+// { dg-do compile { target c++11 } }
+
+template <template <typename ... X> class T, typename ... Y>
+struct D
+{
+ template <typename ... Z>
+ using type = T <Y..., Z...>; // { dg-error "pack expansion" }
+};
+template <typename T>
+class A {};
+template <typename X, typename Y>
+struct B;
+template <typename T>
+struct B <int, T>
+{
+ typedef A <T> type;
+};
+template <typename X, typename Y>
+using C = typename B <X, Y>::type;
+struct E : public D <C> {};
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286.C
new file mode 100644
index 00000000000..0c545c735f0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286.C
@@ -0,0 +1,13 @@
+// DR 1286: An alias template can be equivalent to an underlying template.
+// { dg-do compile { target c++11 } }
+
+template <class T, class U> struct same;
+template <class T> struct same<T,T> {};
+
+template <class T> struct A {};
+template <class T> using B = A<T>;
+
+template <template <class> class T> class C {};
+
+void f(C<B>) { } // { dg-final { scan-assembler "_Z1f1CI1AE" } }
+same<C<A>, C<B> > s;
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C
new file mode 100644
index 00000000000..1780c9a47b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-dr1286a.C
@@ -0,0 +1,60 @@
+// DR 1286
+// { dg-do compile { target c++11 } }
+
+template <class,class> struct same;
+template <class T> struct same<T,T> {};
+
+template <class,class> struct different {};
+template <class T> struct different<T,T>;
+
+template<typename T, typename U = T> struct A;
+template<template <class...> class> struct X;
+
+// equivalent to A
+template<typename V, typename W>
+using B = A<V, W>;
+
+same<X<A>,X<B>> s1;
+
+// not equivalent to A: not all parameters used
+template<typename V, typename W>
+using C = A<V>;
+
+different<X<A>,X<C>> d1;
+
+// not equivalent to A: different number of parameters
+template<typename V>
+using D = A<V>;
+
+different<X<A>,X<D>> d2;
+
+// not equivalent to A: template-arguments in wrong order
+template<typename V, typename W>
+using E = A<W, V>;
+
+different<X<A>,X<E>> d3;
+
+// equivalent to A: default arguments not considered
+template<typename V, typename W = int>
+using F = A<V, W>;
+
+same<X<A>,X<F>> s2;
+
+// equivalent to A and B
+template<typename V, typename W>
+using G = A<V, W>;
+
+same<X<A>,X<G>> s3;
+same<X<B>,X<G>> s3b;
+
+// equivalent to E
+template<typename V, typename W>
+using H = E<V, W>;
+
+same<X<E>,X<H>> s4;
+
+// not equivalent to A: argument not identifier
+template<typename V, typename W>
+using I = A<V, typename W::type>;
+
+different<X<A>,X<I>> d4;
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C
index 5a2ec76e3a7..6403ea16e87 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-function2.C
@@ -38,7 +38,7 @@ constexpr int g(int x, int n) // error: body not just ‘‘return expr’’
} // { dg-error "not a return-statement" }
constexpr int
-bar(int x, int y) { return x + y + x * y; } // { dg-error "previously" }
+bar(int x, int y) { return x + y + x * y; } // { dg-message "previously" }
int bar(int x, int y) // { dg-error "redefinition" }
{ return x * 2 + 3 * y; }
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-ice8.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice8.C
new file mode 100644
index 00000000000..84bfae00077
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-ice8.C
@@ -0,0 +1,17 @@
+// PR c++/53349
+// { dg-do compile { target c++11 } }
+
+template <int N>
+struct Foo {
+ constexpr Foo(const Foo<N-1> a) : m_a(a) {}
+ constexpr Foo(const Foo<N> &a) : m_a(a.m_a) {}
+
+ Foo<N-1> m_a;
+};
+
+template <> struct Foo<0> {};
+
+constexpr Foo<1> catty1(Foo<1> x) { return x; }
+constexpr Foo<2> catty2(Foo<1> x) { return Foo<2>(catty1(x)); }
+
+constexpr auto res = catty2(Foo<1>(Foo<0>()));
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C
index 8294afa9837..c27615f05ad 100644
--- a/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-neg1.C
@@ -50,7 +50,7 @@ private:
bool flag;
};
// OK
-constexpr int bar(int x, int y) // { dg-error "previously defined here" }
+constexpr int bar(int x, int y) // { dg-message "previously defined here" }
{ return x + y + x*y; }
// ...
// error: redefinition of bar
diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C
new file mode 100644
index 00000000000..1fc3738554e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-value4.C
@@ -0,0 +1,16 @@
+// PR c++/57901
+// { dg-require-effective-target c++11 }
+
+struct Z {
+ Z() = default;
+ Z(Z const&) = default;
+ constexpr Z(Z&&) {} /* non-trivial (constexpr) move ctor */
+};
+
+template<typename T>
+constexpr int fn0(T v) { return 0; }
+template<typename T>
+constexpr int fn (T v) { return fn0(v); }
+
+constexpr auto t0 = fn0(Z()); // OK!
+constexpr auto t = fn (Z()); // error! (GCC 4.8.1)
diff --git a/gcc/testsuite/g++.dg/cpp0x/dc7.C b/gcc/testsuite/g++.dg/cpp0x/dc7.C
new file mode 100644
index 00000000000..e48741e0713
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/dc7.C
@@ -0,0 +1,7 @@
+// PR c++/58255
+// { dg-do compile { target c++11 } }
+
+struct A {
+ explicit A() { }
+ A(int x) : A() { }
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/dc8.C b/gcc/testsuite/g++.dg/cpp0x/dc8.C
new file mode 100644
index 00000000000..e483f3e4eeb
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/dc8.C
@@ -0,0 +1,66 @@
+// PR c++/51424
+// { dg-do compile { target c++11 } }
+
+template <class T >
+struct S
+{
+ S() : S() {} // { dg-error "delegates to itself" }
+ S(int x) : S(x) {} // { dg-error "delegates to itself" }
+};
+
+struct B1
+{
+ B1() : B1() {} // { dg-error "delegates to itself" }
+ B1(int y) : B1(y) {} // { dg-error "delegates to itself" }
+};
+
+struct V1 : virtual B1
+{
+ V1() : B1() {}
+ V1(int x) : B1(x) {}
+};
+
+struct B2
+{
+ B2() : B2() {} // { dg-error "delegates to itself" }
+ B2(int y) : B2(y) {} // { dg-error "delegates to itself" }
+};
+
+struct V2 : virtual B2
+{
+ V2() : V2() {} // { dg-error "delegates to itself" }
+ V2(int x) : V2(x) {} // { dg-error "delegates to itself" }
+};
+
+struct B3
+{
+ B3() {}
+ B3(int y) {}
+};
+
+struct V3 : virtual B3
+{
+ V3() : V3() {} // { dg-error "delegates to itself" }
+ V3(int x) : V3(x) {} // { dg-error "delegates to itself" }
+};
+
+struct CE1
+{
+ constexpr CE1() : CE1() {} // { dg-error "delegates to itself" }
+ constexpr CE1(int x) : CE1(x) {} // { dg-error "delegates to itself" }
+};
+
+struct CEB2
+{
+ constexpr CEB2() : CEB2() {} // { dg-error "delegates to itself" }
+ constexpr CEB2(int x) : CEB2(x) {} // { dg-error "delegates to itself" }
+};
+
+struct CE2 : CEB2
+{
+ constexpr CE2() : CEB2() {}
+ constexpr CE2(int x) : CEB2(x) {}
+};
+
+S<int> s1;
+S<int> s2(1);
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
index ce551a3fee2..57f74e8e714 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted2.C
@@ -6,13 +6,13 @@ void f() = delete; // { dg-error "deleted" }
struct A
{
- A() { } // { dg-error "previous" }
+ A() { } // { dg-message "previous" }
void f() = default; // { dg-error "default" }
};
A::A() = default; // { dg-error "redefinition" }
-void g() {} // { dg-error "previous" }
+void g() {} // { dg-message "previous" }
void g() = delete; // { dg-error "redefinition" }
struct B // { dg-message "user-provided default constructor" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/defaulted31.C b/gcc/testsuite/g++.dg/cpp0x/defaulted31.C
index de6a29854a5..c76a0f2bd69 100644
--- a/gcc/testsuite/g++.dg/cpp0x/defaulted31.C
+++ b/gcc/testsuite/g++.dg/cpp0x/defaulted31.C
@@ -3,7 +3,7 @@
struct A
{
- A() { } // { dg-error "defined" }
+ A() { } // { dg-message "defined" }
~A() = default; // { dg-error "defaulted" }
};
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum15.C b/gcc/testsuite/g++.dg/cpp0x/enum15.C
index d653216498e..1d33f90290f 100644
--- a/gcc/testsuite/g++.dg/cpp0x/enum15.C
+++ b/gcc/testsuite/g++.dg/cpp0x/enum15.C
@@ -15,6 +15,6 @@ void foo (A a, int i)
{
case A::Val0: break; // { dg-error "" }
case 1: break;
- case 2.0: break;
+ case 2.0: break; // { dg-error "" }
}
}
diff --git a/gcc/testsuite/g++.dg/cpp0x/enum28.C b/gcc/testsuite/g++.dg/cpp0x/enum28.C
new file mode 100644
index 00000000000..3967699dd03
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/enum28.C
@@ -0,0 +1,17 @@
+// PR c++/51912
+// { dg-do compile { target c++11 } }
+
+constexpr double g() { return 2.0; }
+
+void f(int i)
+{
+ switch (i)
+ {
+ case 1.0:; // { dg-error "could not convert" }
+ }
+
+ switch (i)
+ {
+ case g():; // { dg-error "could not convert" }
+ }
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/error6.C b/gcc/testsuite/g++.dg/cpp0x/error6.C
index 35156520b8e..3b457952d38 100644
--- a/gcc/testsuite/g++.dg/cpp0x/error6.C
+++ b/gcc/testsuite/g++.dg/cpp0x/error6.C
@@ -2,7 +2,7 @@
// { dg-options -std=c++0x }
template<typename C>
-auto g(C& c) -> decltype (c.f()) { return c.f(); } // { dg-error "decltype .c\\.f" }
+auto g(C& c) -> decltype (c.f()) { return c.f(); } // { dg-message "decltype .c\\.f" }
template<typename C>
auto g(C& c) -> decltype (c.f()) { return c.f(); } // { dg-error "decltype .c\\.f" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-32.C b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-32.C
index f3446611748..6a1b235d7f3 100644
--- a/gcc/testsuite/g++.dg/cpp0x/gen-attrs-32.C
+++ b/gcc/testsuite/g++.dg/cpp0x/gen-attrs-32.C
@@ -13,7 +13,7 @@ void bar()
typedef union U1 { int i; } U2 [[gnu::transparent_union]]; // { dg-warning "ignored" }
-static void foo2(U1) {} // { dg-error "previously defined" }
+static void foo2(U1) {} // { dg-message "previously defined" }
static void foo2(U2) {} // { dg-error "redefinition" }
void bar2(U1 u1, U2 u2)
diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C
new file mode 100644
index 00000000000..d85918dd07b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-defarg5.C
@@ -0,0 +1,30 @@
+// PR c++/58083
+// { dg-do compile { target c++11 } }
+
+namespace details {
+struct iterator_concept_checker
+{
+ typedef char yes_type;
+ typedef char (&no_type)[2];
+
+ template <typename T>
+ static no_type test(...);
+
+ template <typename T>
+ static yes_type test(
+ int*
+ , void (*)(T) = [](T it)
+ {
+ auto copy = T{it}; // copy constructible
+ copy = it; // copy assignable
+ copy.~T(); // destroyable
+ ++it; // incrementable
+ }
+ );
+};
+}
+
+int main()
+{
+ details::iterator_concept_checker::test<int>(0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/nsdmi-sizeof.C b/gcc/testsuite/g++.dg/cpp0x/nsdmi-sizeof.C
new file mode 100644
index 00000000000..fac979b668d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/nsdmi-sizeof.C
@@ -0,0 +1,7 @@
+// PR c++/57673
+// { dg-do compile { target c++11 } }
+
+template< int ... p >
+struct d {
+ int n = sizeof ... ( p );
+};
diff --git a/gcc/testsuite/g++.dg/cpp0x/override2.C b/gcc/testsuite/g++.dg/cpp0x/override2.C
index 4d5a412baf5..1a7a36e1ae0 100644
--- a/gcc/testsuite/g++.dg/cpp0x/override2.C
+++ b/gcc/testsuite/g++.dg/cpp0x/override2.C
@@ -44,7 +44,7 @@ int main()
B2 final2 = final;
struct B2 {}; // { dg-error "redefinition" }
struct B2 final; // { dg-error "redeclaration" }
- struct B2 override; // { dg-error "previously declared here" }
+ struct B2 override; // { dg-message "previously declared here" }
struct B2 final {}; // { dg-error "redefinition" }
struct B2 override {}; // { dg-error "cannot specify 'override' for a class" }
B2 override{}; // { dg-error "redeclaration" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/parse1.C b/gcc/testsuite/g++.dg/cpp0x/parse1.C
index 41811853cd7..4fa7461cb22 100644
--- a/gcc/testsuite/g++.dg/cpp0x/parse1.C
+++ b/gcc/testsuite/g++.dg/cpp0x/parse1.C
@@ -1,5 +1,5 @@
// PR c++/43509
// { dg-options "-std=c++0x" }
-typedef int B; // { dg-error "" }
+typedef int B; // { dg-message "" }
B::B() {} // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr57416.C b/gcc/testsuite/g++.dg/cpp0x/pr57416.C
new file mode 100644
index 00000000000..104f1a7acb6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr57416.C
@@ -0,0 +1,45 @@
+// PR c++/57416
+// { dg-do compile { target c++11 } }
+
+struct Nothing
+{
+};
+
+template <class PARENTDATA>
+void func3 (PARENTDATA & p_parent_data)
+{
+ struct Data
+ {
+ PARENTDATA & parent_data = p_parent_data; // { dg-error "parameter" }
+ } data;
+}
+
+template <class PARENTDATA>
+void func2 (PARENTDATA & p_parent_data)
+{
+ struct Data
+ {
+ PARENTDATA & parent_data = p_parent_data; // { dg-error "parameter" }
+ } data;
+
+ data.parent_data.x = 5;
+ func3(data);
+}
+
+template <class PARENTDATA>
+void func1 (PARENTDATA & p_parent_data)
+{
+ struct Data
+ {
+ PARENTDATA & parent_data = p_parent_data; // { dg-error "parameter" }
+ int x = 1;
+ } data;
+
+ func2(data);
+}
+
+int main()
+{
+ Nothing nothing;
+ func1(nothing);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr58072.C b/gcc/testsuite/g++.dg/cpp0x/pr58072.C
new file mode 100644
index 00000000000..941d7c7499c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr58072.C
@@ -0,0 +1,18 @@
+// { dg-do compile }
+// { dg-options "-std=c++11" }
+
+// PR c++/58072
+
+extern 'c'void*blah(void*); // { dg-error "expected unqualified-id before user-defined character literal" }
+extern L'c'void*Lblah(void*); // { dg-error "expected unqualified-id before user-defined character literal" }
+extern u'c'void*ublah(void*); // { dg-error "expected unqualified-id before user-defined character literal" }
+extern U'c'void*Ublah(void*); // { dg-error "expected unqualified-id before user-defined character literal" }
+
+extern "c"void*strblah(void*); // { dg-error "expected unqualified-id before user-defined string literal" }
+extern L"c"void*Lstrblah(void*); // { dg-error "expected unqualified-id before user-defined string literal" }
+extern u"c"void*ustrblah(void*); // { dg-error "expected unqualified-id before user-defined string literal" }
+extern U"c"void*Ustrblah(void*); // { dg-error "expected unqualified-id before user-defined string literal" }
+extern u8"c"void*u8strblah(void*); // { dg-error "expected unqualified-id before user-defined string literal" }
+
+extern 123void*ULLblah(void*); // { dg-error "expected unqualified-id before numeric constant" }
+extern 123.456void*Ldblblah(void*); // { dg-error "expected unqualified-id before numeric constant" }
diff --git a/gcc/testsuite/g++.dg/cpp0x/pr58080.C b/gcc/testsuite/g++.dg/cpp0x/pr58080.C
new file mode 100644
index 00000000000..82f200df044
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/pr58080.C
@@ -0,0 +1,14 @@
+// PR c++/58080
+// { dg-do compile { target c++11 } }
+
+template<class A, class B>
+struct Eval
+{
+ void foo(A a, B b) { bar(a,b, 0); }
+ auto bar(A a, B b, decltype(a+b)* _) -> decltype(a+b) { return a+b; } // { dg-error "pointer" }
+};
+
+int main()
+{
+ Eval<int,void*> eiv; eiv.foo(0,0);
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual14.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual14.C
new file mode 100644
index 00000000000..8e55551aeb2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual14.C
@@ -0,0 +1,18 @@
+// PR c++/57825
+// { dg-do compile { target c++11 } }
+
+template<typename T>
+struct target_class
+{};
+
+template<typename Class, typename Ret, typename... Args>
+struct target_class<Ret (Class::*)(Args...)>
+{};
+
+template<typename Class, typename Ret, typename... Args>
+struct target_class<Ret (Class::*)(Args...) &>
+{};
+
+template<typename Class, typename Ret, typename... Args>
+struct target_class<Ret (Class::*)(Args...) &&>
+{};
diff --git a/gcc/testsuite/g++.dg/cpp0x/scoped_enum.C b/gcc/testsuite/g++.dg/cpp0x/scoped_enum.C
index 4b0317cfbe0..20391eb407b 100644
--- a/gcc/testsuite/g++.dg/cpp0x/scoped_enum.C
+++ b/gcc/testsuite/g++.dg/cpp0x/scoped_enum.C
@@ -6,7 +6,7 @@ enum class Color1 {
};
enum struct Color2 {
- Red, // { dg-error "previously declared here" }
+ Red, // { dg-message "previously declared here" }
Orange,
Yellow,
Green,
diff --git a/gcc/testsuite/g++.dg/cpp0x/temp_default4.C b/gcc/testsuite/g++.dg/cpp0x/temp_default4.C
index f1e254c40a1..aa2ad58e01e 100644
--- a/gcc/testsuite/g++.dg/cpp0x/temp_default4.C
+++ b/gcc/testsuite/g++.dg/cpp0x/temp_default4.C
@@ -2,7 +2,7 @@
class X {
template<typename T = int> friend void f(X) { }
- template<typename T> friend void g(X); // { dg-error "previously declared here" }
+ template<typename T> friend void g(X); // { dg-message "previously declared here" }
template<typename T = int> friend void h(X); // { dg-error "function template friend" }
};
diff --git a/gcc/testsuite/g++.dg/debug/ra1.C b/gcc/testsuite/g++.dg/debug/ra1.C
new file mode 100644
index 00000000000..b6f7bfc588d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/ra1.C
@@ -0,0 +1,77 @@
+/* { dg-options "-fcompare-debug" } */
+
+enum signop { SIGNED, UNSIGNED };
+enum tree_code { FOO, BAR };
+enum tree_code_class { tcc_type, tcc_other };
+extern enum tree_code_class tree_code_type[];
+
+struct tree_base {
+ enum tree_code code : 16;
+ unsigned unsigned_flag : 1;
+};
+
+struct tree_def {
+ tree_base base;
+ struct {
+ int precision;
+ } type_common;
+};
+
+typedef tree_def *tree;
+
+struct storage_ref
+{
+ storage_ref (const long *, unsigned int, unsigned int);
+
+ const long *val;
+ unsigned int len;
+ unsigned int precision;
+};
+
+inline storage_ref::storage_ref (const long *val_in,
+ unsigned int len_in,
+ unsigned int precision_in)
+ : val (val_in), len (len_in), precision (precision_in)
+{
+}
+
+struct hwi_with_prec
+{
+ long val;
+ unsigned int precision;
+ signop sgn;
+};
+
+inline storage_ref
+decompose (long *scratch, unsigned int precision,
+ const hwi_with_prec &x)
+{
+ scratch[0] = x.val;
+ if (x.sgn == SIGNED || x.val >= 0 || precision <= sizeof (long) * 8)
+ return storage_ref (scratch, 1, precision);
+ scratch[1] = 0;
+ return storage_ref (scratch, 2, precision);
+}
+
+extern void tree_class_check_failed (int) __attribute__ ((__noreturn__));
+
+inline tree
+tree_class_check (tree t, const enum tree_code_class cls, int x)
+{
+ if (tree_code_type[t->base.code] != cls)
+ tree_class_check_failed (x);
+ return t;
+}
+
+tree wide_int_to_tree (tree, const storage_ref &);
+
+tree
+build_int_cstu (tree type, unsigned long val)
+{
+ hwi_with_prec x;
+ x.val = val;
+ x.precision = tree_class_check (type, tcc_type, 1)->type_common.precision;
+ x.sgn = (signop) tree_class_check (type, tcc_type, 2)->base.unsigned_flag;
+ long scratch[2];
+ return wide_int_to_tree (type, decompose (scratch, x.precision, x));
+}
diff --git a/gcc/testsuite/g++.dg/dg.exp b/gcc/testsuite/g++.dg/dg.exp
index 710218e67c5..0528538cee7 100644
--- a/gcc/testsuite/g++.dg/dg.exp
+++ b/gcc/testsuite/g++.dg/dg.exp
@@ -52,6 +52,7 @@ set tests [prune $tests $srcdir/$subdir/tm/*]
set tests [prune $tests $srcdir/$subdir/guality/*]
set tests [prune $tests $srcdir/$subdir/simulate-thread/*]
set tests [prune $tests $srcdir/$subdir/asan/*]
+set tests [prune $tests $srcdir/$subdir/ubsan/*]
# Main loop.
g++-dg-runtest $tests $DEFAULT_CXXFLAGS
diff --git a/gcc/testsuite/g++.dg/ext/attr-alias-3.C b/gcc/testsuite/g++.dg/ext/attr-alias-3.C
new file mode 100644
index 00000000000..7f6aa2cbc38
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ext/attr-alias-3.C
@@ -0,0 +1,8 @@
+// PR c++/56134
+// { dg-require-alias "" }
+
+char a;
+class Q
+{
+ static char q __attribute__ ((alias ("a")));
+};
diff --git a/gcc/testsuite/g++.dg/ext/attrib32.C b/gcc/testsuite/g++.dg/ext/attrib32.C
index e4dfe4e9f67..31a92b8f45c 100644
--- a/gcc/testsuite/g++.dg/ext/attrib32.C
+++ b/gcc/testsuite/g++.dg/ext/attrib32.C
@@ -12,7 +12,7 @@ void bar()
typedef union U1 { int i; } U2 __attribute__((transparent_union)); // { dg-warning "ignored" }
-static void foo2(U1) {} // { dg-error "previously defined" }
+static void foo2(U1) {} // { dg-message "previously defined" }
static void foo2(U2) {} // { dg-error "redefinition" }
void bar2(U1 u1, U2 u2)
diff --git a/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C b/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C
index fc7385d809a..7e84fa773eb 100644
--- a/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C
+++ b/gcc/testsuite/g++.dg/ext/gnu-inline-global-reject.C
@@ -10,47 +10,47 @@
#undef fn
#define fn pfx(func_decl_inline_before)
-decl(inline, fn) // { dg-error "previous" "" }
+decl(inline, fn) // { dg-message "previous" "" }
gnuindef(fn, 0) // { dg-error "redeclared" "" }
#undef fn
#define fn pfx(func_decl_inline_after)
-gnuindef(fn, 0) // { dg-error "previous" "" }
+gnuindef(fn, 0) // { dg-message "previous" "" }
decl(inline, fn) // { dg-error "redeclared" "" }
#undef fn
#define fn pfx(func_def_gnuin_redef)
-gnuindef(fn, 0) // { dg-error "previous" "" }
+gnuindef(fn, 0) // { dg-message "previous" "" }
gnuindef(fn, 1) // { dg-error "redefinition" "" }
#undef fn
#define fn pfx(func_def_inline_redef)
-def(inline, fn, 0) // { dg-error "previous" "" }
+def(inline, fn, 0) // { dg-message "previous" "" }
def(inline, fn, 1) // { dg-error "redefinition" "" }
#undef fn
#define fn pfx(func_def_inline_after)
-gnuindef(fn, 0) // { dg-error "previous" "" }
+gnuindef(fn, 0) // { dg-message "previous" "" }
def(inline, fn, 1) // { dg-error "redeclare" "" }
#undef fn
#define fn pfx(func_def_inline_before)
-def(inline, fn, 0) // { dg-error "previous" "" }
+def(inline, fn, 0) // { dg-message "previous" "" }
gnuindef(fn, 1) // { dg-error "redefinition" "" }
#undef fn
#define fn pfx(func_def_before)
-def(, fn, 0) // { dg-error "previous" "" }
+def(, fn, 0) // { dg-message "previous" "" }
gnuindef(fn, 1) // { dg-error "redefinition" "" }
#undef fn
#define fn pfx(func_decl_static_inline_before)
-decl(static inline, fn) // { dg-error "previous" "" }
+decl(static inline, fn) // { dg-message "previous" "" }
gnuindef(fn, 0) // { dg-error "redeclared" "" }
#undef fn
#define fn pfx(func_def_static_inline_after)
decl(static, fn)
-gnuindef(fn, 0) // { dg-error "previous" "" }
+gnuindef(fn, 0) // { dg-message "previous" "" }
decl(static, fn)
def(static inline, fn, 1) // { dg-error "redeclare" "" }
diff --git a/gcc/testsuite/g++.dg/ext/mv13.C b/gcc/testsuite/g++.dg/ext/mv13.C
index 9554993130c..5674d19c974 100644
--- a/gcc/testsuite/g++.dg/ext/mv13.C
+++ b/gcc/testsuite/g++.dg/ext/mv13.C
@@ -5,7 +5,7 @@
extern "C"
__attribute__ ((target ("default")))
-int foo () // { dg-error "previously defined here" }
+int foo () // { dg-message "previously defined here" }
{
return 0;
}
diff --git a/gcc/testsuite/g++.dg/ext/mv7.C b/gcc/testsuite/g++.dg/ext/mv7.C
index d378402e779..64c04fac60f 100644
--- a/gcc/testsuite/g++.dg/ext/mv7.C
+++ b/gcc/testsuite/g++.dg/ext/mv7.C
@@ -2,7 +2,7 @@
// { dg-options "" }
__attribute__((target ("default")))
-void foo (void) // { dg-error "previously defined here" }
+void foo (void) // { dg-message "previously defined here" }
{
}
diff --git a/gcc/testsuite/g++.dg/ext/mv9.C b/gcc/testsuite/g++.dg/ext/mv9.C
index 53ee995027a..c59651e102a 100644
--- a/gcc/testsuite/g++.dg/ext/mv9.C
+++ b/gcc/testsuite/g++.dg/ext/mv9.C
@@ -3,7 +3,7 @@
void foo ();
void foo () __attribute__((target ("sse4")));
-void foo () __attribute__((target ("default"))); // { dg-error "previous declaration" }
+void foo () __attribute__((target ("default"))); // { dg-message "previous declaration" }
void foo () // { dg-error "attribute for multi-versioned" }
{
}
diff --git a/gcc/testsuite/g++.dg/ext/pr57362.C b/gcc/testsuite/g++.dg/ext/pr57362.C
index 67f96857e8d..71c53d37618 100644
--- a/gcc/testsuite/g++.dg/ext/pr57362.C
+++ b/gcc/testsuite/g++.dg/ext/pr57362.C
@@ -193,7 +193,6 @@ int foo(void) { return 1; }
}
/* { dg-prune-output "attribute.* is unknown" } */
-/* { dg-prune-output "redefinition of int foo" } */
-/* { dg-prune-output "previous declaration of int foo" } */
-/* { dg-prune-output "int foo.* previously defined here" } */
+/* { dg-prune-output "missing 'target' attribute*" } */
+/* { dg-prune-output "redefinition of 'int foo" } */
/* { dg-prune-output "No dispatcher found for" } */
diff --git a/gcc/testsuite/g++.dg/ext/typeof10.C b/gcc/testsuite/g++.dg/ext/typeof10.C
index 1b357ad9d7b..614538527a7 100644
--- a/gcc/testsuite/g++.dg/ext/typeof10.C
+++ b/gcc/testsuite/g++.dg/ext/typeof10.C
@@ -5,7 +5,7 @@ template<int> struct A
{
void foo()
{
- typedef int T; // { dg-error "previous" }
+ typedef int T; // { dg-message "previous" }
typedef __typeof__(*this) T; // { dg-error "conflicting" }
}
};
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-11.C b/gcc/testsuite/g++.dg/ipa/devirt-11.C
index c139f8f9633..d30d56cff24 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-11.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-11.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-ipa-inline" } */
+/* { dg-options "-O2 -fdump-ipa-inline -fno-devirtualize-speculatively" } */
int baz ();
struct A
{
@@ -46,5 +46,4 @@ bar ()
and two to fn3. While doing so the new symbol for fn2 needs to be
introduced. */
/* { dg-final { scan-ipa-dump-times "Discovered a virtual call to a known target" 3 "inline" } } */
-/* { dg-final { scan-ipa-dump-times "and turned into root of the clone tree" 1 "inline" } } */
/* { dg-final { cleanup-ipa-dump "inline" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-13.C b/gcc/testsuite/g++.dg/ipa/devirt-13.C
new file mode 100644
index 00000000000..13fbaeea9c8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-13.C
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+/* Call to foo should be devirtualized because there are no derived types of A. */
+/* { dg-options "-O2 -fdump-ipa-cgraph -fdump-tree-ssa" } */
+namespace {
+class A {
+public:
+ virtual int foo(void)
+{
+ return 0;
+}
+};
+}
+class A a, *b=&a;
+main()
+{
+ return b->foo();
+}
+
+/* { dg-final { scan-ipa-dump "Devirtualizing call" "cgraph" } } */
+/* { dg-final { scan-tree-dump-times "OBJ_TYPE_REF" 0 "ssa"} } */
+/* { dg-final { cleanup-ipa-dump "cgraph" } } */
+/* { dg-final { cleanup-tree-dump "ssa" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-14.C b/gcc/testsuite/g++.dg/ipa/devirt-14.C
new file mode 100644
index 00000000000..456d44f84bd
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-14.C
@@ -0,0 +1,34 @@
+/* No devirtualization happens here, but A::foo should not end up as reachable
+ because the constructor of A is unreachable and therefore the virtual
+ method table referring to A::foo is optimized out. */
+/* { dg-do run } */
+/* { dg-options "-O2 -fdump-tree-ssa" } */
+class B {
+public:
+ virtual int foo(void)
+{
+ return 0;
+}
+};
+namespace {
+class A : public B {
+public:
+ virtual int foo(void)
+{
+ return 1;
+}
+};
+}
+class B a, *b=&a;
+main()
+{
+ if (0)
+ {
+ class A a;
+ a.foo();
+ }
+ return b->foo();
+}
+
+/* { dg-final { scan-tree-dump-not "A::foo" "ssa"} } */
+/* { dg-final { cleanup-tree-dump "ssa" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-15.C b/gcc/testsuite/g++.dg/ipa/devirt-15.C
new file mode 100644
index 00000000000..2ea85f487f4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-15.C
@@ -0,0 +1,40 @@
+/* Check that we speculatively devirutalize call to FOO to B::foo becuase
+ A is noreturn. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-devirt -fdump-tree-optimized" } */
+class A {
+public:
+ virtual int foo(void)
+ {
+ throw (1);
+ return 0;
+ }
+};
+
+
+class B : public A {
+public:
+ virtual int foo(void);
+};
+
+int
+B::foo(void)
+{
+ return 1;
+}
+class A a, *b=&a;
+void
+m(void)
+{
+ b->foo();
+}
+main()
+{
+ m();
+}
+
+/* { dg-final { scan-ipa-dump "Speculatively devirtualizing call" "devirt"} } */
+/* { dg-final { cleanup-ipa-dump "devirt" } } */
+/* Match if (PROF_6 == foo) to verify that the speculation survived. */
+/* { dg-final { scan-tree-dump "== foo" "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-16.C b/gcc/testsuite/g++.dg/ipa/devirt-16.C
new file mode 100644
index 00000000000..85567867ff1
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-16.C
@@ -0,0 +1,39 @@
+/* We shall devirtualize to unreachable. No anonymous type method should surivve
+ reachability. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-whole-program" } */
+namespace {
+class B {
+public:
+ virtual int foo(void)
+{
+ return 0;
+}
+};
+class A : public B {
+public:
+ virtual int foo(void)
+{
+ return 1;
+}
+};
+}
+class B *b;
+main()
+{
+ int c;
+ if (c)
+ {
+ class A a;
+ a.foo();
+ class B b;
+ b.foo();
+ }
+ return b->foo();
+}
+
+/* { dg-final { scan-ipa-dump "Devirtualizing" "whole-program"} } */
+/* { dg-final { scan-ipa-dump "builtin_unreachable" "whole-program"} } */
+/* { dg-final { scan-ipa-dump-not "A::foo" "whole-program"} } */
+/* { dg-final { scan-ipa-dump-not "A::foo" "whole-program"} } */
+/* { dg-final { cleanup-ipa-dump "whole-program" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-17.C b/gcc/testsuite/g++.dg/ipa/devirt-17.C
new file mode 100644
index 00000000000..9edfd73af56
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-17.C
@@ -0,0 +1,44 @@
+/* We shall devirtualize to B::foo since it is the only live candidate of an
+ anonymous type. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-whole-program" } */
+namespace {
+class B {
+public:
+ virtual int foo(void)
+{
+ return 0;
+}
+};
+class A : public B {
+public:
+ virtual int foo(void)
+{
+ return 1;
+}
+};
+}
+class B *b;
+void get_me_lost (void *);
+main()
+{
+ int c;
+ if (c)
+ {
+ class A a;
+ a.foo();
+ }
+ else
+ {
+ b = new (class B);
+ b->foo();
+ get_me_lost ((void *)&b);
+ }
+ return b->foo();
+}
+
+/* { dg-final { scan-ipa-dump "Devirtualizing" "whole-program"} } */
+/* { dg-final { scan-ipa-dump-not "builtin_unreachable" "whole-program"} } */
+/* { dg-final { scan-ipa-dump "B::foo" "whole-program"} } */
+/* { dg-final { scan-ipa-dump-not "A::foo" "whole-program"} } */
+/* { dg-final { cleanup-ipa-dump "whole-program" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-18.C b/gcc/testsuite/g++.dg/ipa/devirt-18.C
new file mode 100644
index 00000000000..dbbe597c92c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/devirt-18.C
@@ -0,0 +1,37 @@
+/* We shall devirtualize to unreachable. No anonymous type method should surivve
+ reachability. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ssa" } */
+namespace {
+class B {
+public:
+ virtual int foo(void)
+{
+ return 0;
+}
+};
+class A : public B {
+public:
+ virtual int foo(void)
+{
+ return 1;
+}
+};
+}
+class B *b;
+main()
+{
+ if (0)
+ {
+ class A a;
+ a.foo();
+ class B b;
+ b.foo();
+ }
+ return b->foo();
+}
+
+/* { dg-final { scan-tree-dump-not "A::foo" "ssa"} } */
+/* { dg-final { scan-tree-dump-not "B::foo" "ssa"} } */
+/* { dg-final { scan-tree-dump "builtin_unreachable" "ssa"} } */
+/* { dg-final { cleanup-tree-dump "ssa" } } */
diff --git a/gcc/testsuite/g++.dg/ipa/remref-1.C b/gcc/testsuite/g++.dg/ipa/remref-1.C
new file mode 100644
index 00000000000..c25c425e9b7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/remref-1.C
@@ -0,0 +1,36 @@
+/* Verify that indirect-inlining induced removal of referenes will not remove
+ too many references in presence of speculative devirtualization. */
+/* { dg-do link } */
+/* { dg-options "-O3 -fno-early-inlining" } */
+
+class A
+{
+ public:
+ virtual void foo(void (*)(void));
+};
+
+static
+void b(void)
+{
+}
+
+void
+A::foo(void (*back)(void))
+{
+ back();
+}
+
+class A *a;
+
+void __attribute__ ((noinline, noclone))
+allocate_a ()
+{
+ a = new A();
+}
+
+main()
+{
+ allocate_a();
+ for (int i=0; i<10000;i++)
+ a->foo(b);
+}
diff --git a/gcc/testsuite/g++.dg/ipa/remref-2.C b/gcc/testsuite/g++.dg/ipa/remref-2.C
new file mode 100644
index 00000000000..06bc71a5b00
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/remref-2.C
@@ -0,0 +1,37 @@
+/* Verify that we survive creation and deletion of references to facilitate
+ reference removal while also doing (unsuccessful) speculative
+ devirtualization. */
+/* { dg-do link } */
+/* { dg-options "-O3 -fno-early-inlining" } */
+
+class A
+{
+ public:
+ virtual void __attribute__ ((noinline)) foo(void (*)(void));
+};
+
+static
+void b(void)
+{
+}
+
+void __attribute__ ((noinline))
+A::foo(void (*back)(void))
+{
+ back();
+}
+
+class A *a;
+
+void __attribute__ ((noinline, noclone))
+allocate_a ()
+{
+ a = new A();
+}
+
+main()
+{
+ allocate_a();
+ for (int i=0; i<10000;i++)
+ a->foo(b);
+}
diff --git a/gcc/testsuite/g++.dg/ipa/type-inheritance-1.C b/gcc/testsuite/g++.dg/ipa/type-inheritance-1.C
new file mode 100644
index 00000000000..818002ec1d5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ipa/type-inheritance-1.C
@@ -0,0 +1,28 @@
+/* Verify that callgraph construction keeps FOO for possible devirtualization
+ and removes BAR. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-visibility" } */
+
+extern "C" void abort (void);
+
+class A
+{
+public:
+ virtual int foo (void)
+ {
+ return 4;
+ }
+ virtual int bar (void)
+ {
+ return 5;
+ }
+};
+
+
+int t(class A *a)
+{
+ return a->foo();
+}
+/* { dg-final { scan-ipa-dump "A::foo" "visibility" } } */
+/* { dg-final { scan-ipa-dump-not "A::bar" "visibility" } } */
+/* { dg-final { cleanup-ipa-dump "visibility" } } */
diff --git a/gcc/testsuite/g++.dg/lookup/anon6.C b/gcc/testsuite/g++.dg/lookup/anon6.C
index 09fa7f8f3b6..7c5a96848cc 100644
--- a/gcc/testsuite/g++.dg/lookup/anon6.C
+++ b/gcc/testsuite/g++.dg/lookup/anon6.C
@@ -1,11 +1,11 @@
-extern int v1; // { dg-error "declared" }
+extern int v1; // { dg-message "declared" }
static union { int v1; }; // { dg-error "redeclaration" }
-static union { int v2; }; // { dg-error "declared" }
+static union { int v2; }; // { dg-message "declared" }
extern int v2; // { dg-error "redeclaration" }
-int v3; // { dg-error "declared" }
+int v3; // { dg-message "declared" }
static union { int v3; }; // { dg-error "redeclaration" }
-static union { int v4; }; // { dg-error "declared" }
+static union { int v4; }; // { dg-message "declared" }
static union { int v4; }; // { dg-error "redeclaration" }
diff --git a/gcc/testsuite/g++.dg/lookup/crash6.C b/gcc/testsuite/g++.dg/lookup/crash6.C
index 0e49324bf27..b8481be4d34 100644
--- a/gcc/testsuite/g++.dg/lookup/crash6.C
+++ b/gcc/testsuite/g++.dg/lookup/crash6.C
@@ -4,5 +4,5 @@
// PR c++/18652: ICE redeclaring variable as template.
-int A; // { dg-error "previous declaration" }
+int A; // { dg-message "previous declaration" }
template<int> struct A; // { dg-error "different kind of symbol" }
diff --git a/gcc/testsuite/g++.dg/lookup/name-clash5.C b/gcc/testsuite/g++.dg/lookup/name-clash5.C
index 7f220d8877f..74595c26871 100644
--- a/gcc/testsuite/g++.dg/lookup/name-clash5.C
+++ b/gcc/testsuite/g++.dg/lookup/name-clash5.C
@@ -7,7 +7,7 @@
// declarative region (7.3.2, clause 14). ]"
namespace N
-{ // { dg-error "previous declaration" }
+{ // { dg-message "previous declaration" }
}
class N; // { dg-error "redeclared" }
diff --git a/gcc/testsuite/g++.dg/lookup/name-clash6.C b/gcc/testsuite/g++.dg/lookup/name-clash6.C
index 63a0b15bf5e..6918142f222 100644
--- a/gcc/testsuite/g++.dg/lookup/name-clash6.C
+++ b/gcc/testsuite/g++.dg/lookup/name-clash6.C
@@ -6,7 +6,7 @@
// "[Note: a namespace name or a class template name must be unique in its
// declarative region (7.3.2, clause 14). ]"
-class N; // { dg-error "previous declaration" }
+class N; // { dg-message "previous declaration" }
namespace N
{ // { dg-error "redeclared" }
diff --git a/gcc/testsuite/g++.dg/lookup/using9.C b/gcc/testsuite/g++.dg/lookup/using9.C
index 32abb5371f2..fd3e788638e 100644
--- a/gcc/testsuite/g++.dg/lookup/using9.C
+++ b/gcc/testsuite/g++.dg/lookup/using9.C
@@ -21,11 +21,11 @@ void h()
f('h');
f(1); // { dg-error "ambiguous" }
// { dg-message "candidate" "candidate note" { target *-*-* } 22 }
- void f(int); // { dg-error "previous using declaration" }
+ void f(int); // { dg-error "previous declaration" }
}
void m()
{
void f(int);
- using B::f; // { dg-error "already declared" }
+ using B::f; // { dg-error "previous declaration" }
}
diff --git a/gcc/testsuite/g++.dg/opt/pr57661.C b/gcc/testsuite/g++.dg/opt/pr57661.C
new file mode 100644
index 00000000000..8be9f09b633
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr57661.C
@@ -0,0 +1,76 @@
+// PR tree-optimization/57661
+// { dg-do compile }
+// { dg-options "-O2 -fno-tree-forwprop -std=gnu++11" }
+
+template <typename>
+struct A
+{
+ ~A () {}
+};
+template <typename _Tp>
+using B = A <_Tp>;
+template <typename _Tp>
+class C : B <_Tp> {};
+namespace N { enum D { d }; }
+template <class>
+struct E
+{
+ ~E ();
+};
+template <class, class V>
+struct F : V {};
+template <class U, class V>
+struct G : F <U, V>
+{
+ N::D g1;
+ void g2 ();
+ void g3 ();
+ void g4 () { g3 (); }
+ static void g5 (G *__t) { __t->g4 (); }
+};
+template <class U, class V>
+struct H : G <U, V>
+{
+ E <U> *h1;
+ bool h2;
+ ~H () throw ()
+ {
+ this->g2 ();
+ if (h2)
+ delete h1;
+ }
+};
+template <class U, class V>
+struct I : H <U, V>, E <U>
+{
+ G <U, V> *i;
+ ~I () throw ()
+ {
+ i->g4 ();
+ }
+};
+struct J
+{
+ typedef C <char> j1;
+ typedef G <char, C <char>> j2;
+ J ();
+ j2 *j3;
+};
+struct K : J
+{
+ typedef G <char, C <char>> j2;
+ K () { j2::g5 (this->j3); }
+};
+template <class U, class V>
+void G <U, V>::g3 ()
+{
+ switch (g1)
+ {
+ case N::d:
+ {
+ I <U, V> *q = (I <U, V> *) this;
+ q->I <U, V>::~I ();
+ }
+ }
+}
+K r;
diff --git a/gcc/testsuite/g++.dg/opt/pr58006.C b/gcc/testsuite/g++.dg/opt/pr58006.C
new file mode 100644
index 00000000000..fd3b7bebd8a
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr58006.C
@@ -0,0 +1,22 @@
+// PR tree-optimization/58006
+// { dg-do compile }
+// { dg-require-effective-target pthread }
+// { dg-options "-Ofast -ftree-parallelize-loops=2" }
+
+extern "C" float sqrtf (float);
+
+struct S
+{
+ float i, j;
+ float foo () const { return sqrtf (i * i + j * j); }
+ S () : i (1), j (1) {}
+};
+
+void
+bar (int a, int b)
+{
+ int i;
+ float f;
+ for (i = a; i < b; i++)
+ f = S ().foo ();
+}
diff --git a/gcc/testsuite/g++.dg/opt/pr58165.C b/gcc/testsuite/g++.dg/opt/pr58165.C
new file mode 100644
index 00000000000..d758e370050
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr58165.C
@@ -0,0 +1,14 @@
+// PR tree-optimization/58165
+// { dg-do compile }
+// { dg-options "-O2" }
+
+extern "C" float sqrtf (float);
+
+struct A { A (); ~A (); };
+
+void
+foo (double d)
+{
+ A a;
+ sqrtf (d);
+}
diff --git a/gcc/testsuite/g++.dg/other/anon4.C b/gcc/testsuite/g++.dg/other/anon4.C
index 571f4ae65fb..37df228da9b 100644
--- a/gcc/testsuite/g++.dg/other/anon4.C
+++ b/gcc/testsuite/g++.dg/other/anon4.C
@@ -3,6 +3,6 @@
void foo()
{
- int i; // { dg-error "previously" }
+ int i; // { dg-message "previously" }
union { int i; }; // { dg-error "redeclaration" }
}
diff --git a/gcc/testsuite/g++.dg/other/error15.C b/gcc/testsuite/g++.dg/other/error15.C
index 3601852322a..d218c13bbb2 100644
--- a/gcc/testsuite/g++.dg/other/error15.C
+++ b/gcc/testsuite/g++.dg/other/error15.C
@@ -3,39 +3,39 @@
extern void g0 (int a, int b);
extern void g1 (int a, float b);
-extern void f0 (int a, // { dg-error "previous" }
+extern void f0 (int a, // { dg-message "previous" }
int a); // { dg-error "redefinition" }
-extern void f1 (int a, // { dg-error "previous" }
+extern void f1 (int a, // { dg-message "previous" }
float a); // { dg-error "conflicting" }
-extern void f3 (int a, int b, int c, // { dg-error "previous" }
+extern void f3 (int a, int b, int c, // { dg-message "previous" }
int a); // { dg-error "redefinition" }
-extern void f4 (int a, int b, int c, // { dg-error "previous" }
+extern void f4 (int a, int b, int c, // { dg-message "previous" }
int a, // { dg-error "redefinition" }
int a); // { dg-error "redefinition" }
-extern void f5 (int a, int b, int c, int d, int e, int f, int g, int h, // { dg-error "previous" }
+extern void f5 (int a, int b, int c, int d, int e, int f, int g, int h, // { dg-message "previous" }
int a, // { dg-error "redefinition" }
int i, int j, int k, int l, int m, int n, int o, int p,
int q, int r, int s, int t, int u, int v, int w, int x, int y,
int z);
-extern void f6 (int a, int, int, int, int, int, int, int, int, int, int, // { dg-error "previous" }
+extern void f6 (int a, int, int, int, int, int, int, int, int, int, int, // { dg-message "previous" }
int a, // { dg-error "redefinition" }
int, int, int, int, int, int, int, int, int, int, int,
float, float, float, float, float, float, float, float,
int);
-extern void f7 (void (*a)(int), // { dg-error "previous" }
+extern void f7 (void (*a)(int), // { dg-message "previous" }
void (*a)(int)); // { dg-error "redefinition" }
-extern void f8 (float (*a)(int), // { dg-error "previous" }
+extern void f8 (float (*a)(int), // { dg-message "previous" }
int (*a)(float)); // { dg-error "conflicting" }
-extern void f9 (int a, // { dg-error "previous" }
+extern void f9 (int a, // { dg-message "previous" }
int a, // { dg-error "redefinition" }
int a); // { dg-error "redefinition" }
-extern void f10 (int a, // { dg-error "previous" }
- int b, // { dg-error "previous" }
- int c, // { dg-error "previous" }
+extern void f10 (int a, // { dg-message "previous" }
+ int b, // { dg-message "previous" }
+ int c, // { dg-message "previous" }
int c, // { dg-error "redefinition" }
int b, // { dg-error "redefinition" }
int a); // { dg-error "redefinition" }
@@ -43,7 +43,7 @@ extern void f10 (int a, // { dg-error "previous" }
class C1 {
public:
void C1_g0 (int a, int b);
- void C1_f0 (int a, // { dg-error "previous" }
+ void C1_f0 (int a, // { dg-message "previous" }
int a); // { dg-error "redefinition" }
};
@@ -51,6 +51,6 @@ template <class T>
class C2 {
public:
void C2_g0 (T a, T b);
- void C2_f0 (T a, // { dg-error "previous" }
+ void C2_f0 (T a, // { dg-message "previous" }
T a); // { dg-error "redefinition" }
};
diff --git a/gcc/testsuite/g++.dg/other/error8.C b/gcc/testsuite/g++.dg/other/error8.C
index 9246c2afa56..116a6846c70 100644
--- a/gcc/testsuite/g++.dg/other/error8.C
+++ b/gcc/testsuite/g++.dg/other/error8.C
@@ -5,7 +5,7 @@
void foo(void)
{
- union { int alpha; int beta; }; // { dg-error "previous declaration" }
+ union { int alpha; int beta; }; // { dg-message "previous declaration" }
double alpha; // { dg-error "conflicting declaration" }
}
diff --git a/gcc/testsuite/g++.dg/other/redecl2.C b/gcc/testsuite/g++.dg/other/redecl2.C
index 591c258b891..6c8913c1f09 100644
--- a/gcc/testsuite/g++.dg/other/redecl2.C
+++ b/gcc/testsuite/g++.dg/other/redecl2.C
@@ -7,5 +7,5 @@ struct S {
virtual int foo() = 0;
};
-int S::foo() { return 0; } // { dg-error "defined here" }
+int S::foo() { return 0; } // { dg-message "defined here" }
int S::foo() { return 0; } // { dg-error "redefinition" }
diff --git a/gcc/testsuite/g++.dg/overload/new1.C b/gcc/testsuite/g++.dg/overload/new1.C
index 9adb4c07245..f1b7328366f 100644
--- a/gcc/testsuite/g++.dg/overload/new1.C
+++ b/gcc/testsuite/g++.dg/overload/new1.C
@@ -17,6 +17,5 @@ void f(X *x = new (3) X(6)); // { dg-error "" }
void f(X *x = new (2) X[10]); // { dg-error "" }
// { dg-message "candidate" "candidate note" { target *-*-* } 18 }
-// { dg-message "operator new|candidate expects" "match candidate text" { target *-*-* } 00 }
void f(X *x = new X[10][5]); // { dg-error "" }
diff --git a/gcc/testsuite/g++.dg/overload/using2.C b/gcc/testsuite/g++.dg/overload/using2.C
index 514d83f34d8..d1824548ad5 100644
--- a/gcc/testsuite/g++.dg/overload/using2.C
+++ b/gcc/testsuite/g++.dg/overload/using2.C
@@ -45,7 +45,7 @@ using std::C1;
extern "C" void exit (int) throw ();
extern "C" void *malloc (__SIZE_TYPE__) throw () __attribute__((malloc));
- void abort (void) throw ();
+ void abort (void) throw (); // { dg-message "previous" }
void _exit (int) throw (); // { dg-error "conflicts" "conflicts" }
// { dg-message "void _exit" "_exit" { target *-*-* } 49 }
@@ -54,14 +54,14 @@ using std::C1;
// { dg-message "void C1" "C1" { target *-*-* } 53 }
extern "C" void c2 (void) throw ();
- void C2 (void) throw ();
+ void C2 (void) throw (); // { dg-message "previous" }
int C3 (int) throw ();
using std::malloc;
-using std::abort; // { dg-error "already declared" }
+using std::abort; // { dg-error "conflicts" }
using std::c2;
-using std::C2; // { dg-error "already declared" }
+using std::C2; // { dg-error "conflicts" }
using std::c3; using other::c3;
using std::C3; using other::C3;
diff --git a/gcc/testsuite/g++.dg/overload/using3.C b/gcc/testsuite/g++.dg/overload/using3.C
new file mode 100644
index 00000000000..38344e48a9d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/overload/using3.C
@@ -0,0 +1,16 @@
+// { dg-do compile }
+
+namespace a
+{
+ void f(int);
+}
+
+namespace b
+{
+ void f(int); // { dg-message "previous" }
+ void g()
+ {
+ f (3);
+ }
+ using a::f; // { dg-error "conflicts" }
+}
diff --git a/gcc/testsuite/g++.dg/parse/access11.C b/gcc/testsuite/g++.dg/parse/access11.C
new file mode 100644
index 00000000000..7004fa76401
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/access11.C
@@ -0,0 +1,35 @@
+// PR c++/24926
+
+class A {
+ union {
+ int i; // { dg-error "private" }
+ };
+ union {
+ int j; // { dg-error "private" }
+ };
+ union {
+ union {
+ int k; // { dg-error "private" }
+ };
+ union {
+ union {
+ int l; // { dg-error "private" }
+ };
+ union {
+ int m; // { dg-error "private" }
+ union {
+ int n; // { dg-error "private" }
+ int o; // { dg-error "private" }
+ };
+ };
+ };
+ };
+};
+
+int a1 = A().i; // { dg-error "context" }
+int a2 = A().j; // { dg-error "context" }
+int a3 = A().k; // { dg-error "context" }
+int a4 = A().l; // { dg-error "context" }
+int a5 = A().m; // { dg-error "context" }
+int a6 = A().n; // { dg-error "context" }
+int a7 = A().o; // { dg-error "context" }
diff --git a/gcc/testsuite/g++.dg/parse/crash16.C b/gcc/testsuite/g++.dg/parse/crash16.C
index dc8f7a608d2..c7da3eb7025 100644
--- a/gcc/testsuite/g++.dg/parse/crash16.C
+++ b/gcc/testsuite/g++.dg/parse/crash16.C
@@ -1,7 +1,7 @@
// PR c++/16971
namespace N {
- int i; // { dg-error "" }
+ int i; // { dg-message "" }
// By checking for an explicit keyword on the next line we avoid
// matching an ICE message.
int i; // { dg-error "redefinition" }
diff --git a/gcc/testsuite/g++.dg/parse/crash21.C b/gcc/testsuite/g++.dg/parse/crash21.C
index 283f6b4d583..623bbec81c9 100644
--- a/gcc/testsuite/g++.dg/parse/crash21.C
+++ b/gcc/testsuite/g++.dg/parse/crash21.C
@@ -1,6 +1,6 @@
namespace N
{
- struct A; // { dg-error "previous declaration" "" }
+ struct A; // { dg-message "previous declaration" "" }
}
template<int I>
diff --git a/gcc/testsuite/g++.dg/parse/crash38.C b/gcc/testsuite/g++.dg/parse/crash38.C
index 724f9b80a12..7a0c2655681 100644
--- a/gcc/testsuite/g++.dg/parse/crash38.C
+++ b/gcc/testsuite/g++.dg/parse/crash38.C
@@ -1,11 +1,11 @@
/* PR c++/33207 */
/* This would not ICE. */
-namespace M { } /* { dg-error "previous declaration" } */
+namespace M { } /* { dg-message "previous declaration" } */
struct M; /* { dg-error "redeclared as different kind of symbol" } */
M *p; /* { dg-error "does not name a type" } */
/* This would ICE when processing 'p'. */
-namespace N { } /* { dg-error "previous declaration" } */
+namespace N { } /* { dg-message "previous declaration" } */
struct N; /* { dg-error "redeclared as different kind of symbol" } */
struct N* p; /* { dg-error "redeclared as different kind of symbol|invalid type" } */
diff --git a/gcc/testsuite/g++.dg/parse/crash63.C b/gcc/testsuite/g++.dg/parse/crash63.C
new file mode 100644
index 00000000000..c7189c2c17e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/crash63.C
@@ -0,0 +1,10 @@
+// PR c++/57947
+// { dg-options "-std=c++98" }
+
+namespace std
+{
+ template <class E> class initializer_list {};
+ template <int N> struct D { D(initializer_list<int>) {} };
+ D<0> d {1, 2, 3}; // { dg-error "constructor|no matching" }
+ // { dg-warning "initializer list" "" { target *-*-* } 8 }
+}
diff --git a/gcc/testsuite/g++.dg/parse/redef2.C b/gcc/testsuite/g++.dg/parse/redef2.C
index 2435672d146..3ab3667d82d 100644
--- a/gcc/testsuite/g++.dg/parse/redef2.C
+++ b/gcc/testsuite/g++.dg/parse/redef2.C
@@ -1,6 +1,6 @@
// { dg-do compile }
-char * d [10]; // { dg-error "8: 'd' has a previous declaration as" }
+char * d [10]; // { dg-message "8: 'd' has a previous declaration as" }
char e [15][10];
int (*f)();
diff --git a/gcc/testsuite/g++.dg/parse/struct-as-enum1.C b/gcc/testsuite/g++.dg/parse/struct-as-enum1.C
index f58c7388195..a6cb6b592d6 100644
--- a/gcc/testsuite/g++.dg/parse/struct-as-enum1.C
+++ b/gcc/testsuite/g++.dg/parse/struct-as-enum1.C
@@ -4,7 +4,7 @@
namespace N
{
- struct A {}; // { dg-error "previous declaration" }
+ struct A {}; // { dg-message "previous declaration" }
}
typedef enum N::A B; // { dg-error "enum|invalid type" }
diff --git a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
index 0f15140068c..e197d667251 100644
--- a/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
+++ b/gcc/testsuite/g++.dg/plugin/dumb_plugin.c
@@ -11,6 +11,7 @@
#include "intl.h"
#include "toplev.h"
#include "diagnostic.h"
+#include "context.h"
int plugin_is_GPL_compatible;
@@ -57,26 +58,44 @@ gate_dumb_plugin_example (void)
return true;
}
-static struct gimple_opt_pass pass_dumb_plugin_example =
+namespace {
+
+const pass_data pass_data_dumb_plugin_example =
{
- {
- GIMPLE_PASS,
- "dumb_plugin_example", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dumb_plugin_example, /* gate */
- execute_dumb_plugin_example, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "dumb_plugin_example", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_dumb_plugin_example : public gimple_opt_pass
+{
+public:
+ pass_dumb_plugin_example(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_dumb_plugin_example, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_dumb_plugin_example (); }
+ unsigned int execute () { return execute_dumb_plugin_example (); }
+
+}; // class pass_dumb_plugin_example
+
+} // anon namespace
+
+static gimple_opt_pass *
+make_pass_dumb_plugin_example (gcc::context *ctxt)
+{
+ return new pass_dumb_plugin_example (ctxt);
+}
+
/* Initialization function that GCC calls. This plugin takes an argument
that specifies the name of the reference pass and an instance number,
both of which determine where the plugin pass should be inserted. */
@@ -124,7 +143,7 @@ plugin_init (struct plugin_name_args *plugin_info,
return 1;
}
- pass_info.pass = &pass_dumb_plugin_example.pass;
+ pass_info.pass = make_pass_dumb_plugin_example (g);
pass_info.reference_pass_name = ref_pass_name;
pass_info.ref_pass_instance_number = ref_instance_number;
pass_info.pos_op = PASS_POS_INSERT_AFTER;
diff --git a/gcc/testsuite/g++.dg/plugin/selfassign.c b/gcc/testsuite/g++.dg/plugin/selfassign.c
index 37a0a979cb7..7235089c7d3 100644
--- a/gcc/testsuite/g++.dg/plugin/selfassign.c
+++ b/gcc/testsuite/g++.dg/plugin/selfassign.c
@@ -15,6 +15,7 @@
#include "intl.h"
#include "plugin-version.h"
#include "diagnostic.h"
+#include "context.h"
int plugin_is_GPL_compatible;
@@ -263,26 +264,44 @@ gate_warn_self_assign (void)
return true;
}
-static struct gimple_opt_pass pass_warn_self_assign =
+namespace {
+
+const pass_data pass_data_warn_self_assign =
{
- {
- GIMPLE_PASS,
- "warn_self_assign", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_warn_self_assign, /* gate */
- execute_warn_self_assign, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "warn_self_assign", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_warn_self_assign : public gimple_opt_pass
+{
+public:
+ pass_warn_self_assign(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_warn_self_assign, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_warn_self_assign (); }
+ unsigned int execute () { return execute_warn_self_assign (); }
+
+}; // class pass_warn_self_assign
+
+} // anon namespace
+
+static gimple_opt_pass *
+make_pass_warn_self_assign (gcc::context *ctxt)
+{
+ return new pass_warn_self_assign (ctxt);
+}
+
/* The initialization routine exposed to and called by GCC. The spec of this
function is defined in gcc/gcc-plugin.h.
@@ -309,7 +328,7 @@ plugin_init (struct plugin_name_args *plugin_info,
return 1;
/* Self-assign detection should happen after SSA is constructed. */
- pass_info.pass = &pass_warn_self_assign.pass;
+ pass_info.pass = make_pass_warn_self_assign (g);
pass_info.reference_pass_name = "ssa";
pass_info.ref_pass_instance_number = 1;
pass_info.pos_op = PASS_POS_INSERT_AFTER;
diff --git a/gcc/testsuite/g++.dg/pr57878.C b/gcc/testsuite/g++.dg/pr57878.C
index d4e7d862d2c..0a21ef53b10 100644
--- a/gcc/testsuite/g++.dg/pr57878.C
+++ b/gcc/testsuite/g++.dg/pr57878.C
@@ -6,7 +6,7 @@ typedef long long int64;
typedef unsigned int uint32;
typedef unsigned long long uint64;
namespace std {
- typedef unsigned int size_t;
+ typedef __SIZE_TYPE__ size_t;
template<class _CharT>
struct char_traits;
template<typename _Tp>
@@ -22,7 +22,7 @@ namespace std {
return static_cast<_Tp&&>(__t);
}
}
-typedef unsigned int size_t;
+typedef __SIZE_TYPE__ size_t;
extern "C++" {
inline void* operator new(std::size_t, void* __p) noexcept {
return __p;
diff --git a/gcc/testsuite/g++.dg/template/abstract1.C b/gcc/testsuite/g++.dg/template/abstract1.C
new file mode 100644
index 00000000000..20bbf5a911f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/abstract1.C
@@ -0,0 +1,12 @@
+// PR c++/58022
+
+template <class T> struct A { };
+template <class T> A<T> & operator<< (A<T>&, T);
+template <class T> class foo;
+template <class T> A<char> & operator<<(A<char>& o, const foo<T>& l);
+template <class T> class foo {
+ friend A<char>& operator<< <T> (A<char>& o, const foo<T>& l);
+};
+class bar;
+foo<bar> fb;
+class bar { virtual void baz()=0; };
diff --git a/gcc/testsuite/g++.dg/template/crash39.C b/gcc/testsuite/g++.dg/template/crash39.C
index ddecc173c45..840255cbea9 100644
--- a/gcc/testsuite/g++.dg/template/crash39.C
+++ b/gcc/testsuite/g++.dg/template/crash39.C
@@ -1,6 +1,6 @@
// PR c++/22405
-template <typename T> void foo(T &arg) { // { dg-error "declared" }
+template <typename T> void foo(T &arg) { // { dg-message "declared" }
arg+=1;
}
diff --git a/gcc/testsuite/g++.dg/template/delete2.C b/gcc/testsuite/g++.dg/template/delete2.C
new file mode 100644
index 00000000000..b6ab380c9f9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/delete2.C
@@ -0,0 +1,26 @@
+// PR c++/58119
+
+template <class T>
+struct A
+{
+ operator T*();
+ template <class U>
+ operator A<U>();
+};
+
+template <class T>
+struct B
+{
+ operator T*();
+ template <class U>
+ operator A<U>*();
+};
+
+int main()
+{
+ A<int> a;
+ delete a;
+
+ B<int> b;
+ delete b; // { dg-error "template|delete" }
+}
diff --git a/gcc/testsuite/g++.dg/template/error54.C b/gcc/testsuite/g++.dg/template/error54.C
new file mode 100644
index 00000000000..2933bb5aea5
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/error54.C
@@ -0,0 +1,10 @@
+// PR c++/56380
+
+template <typename T>
+struct X {
+ X();
+ mutable T x; // { dg-error "cannot be declared" }
+};
+
+X<const int> a; // { dg-message "required from here" }
+X<int&> b; // { dg-message "required from here" }
diff --git a/gcc/testsuite/g++.dg/template/meminit1.C b/gcc/testsuite/g++.dg/template/meminit1.C
index 19a1e546d52..1dc96c472ad 100644
--- a/gcc/testsuite/g++.dg/template/meminit1.C
+++ b/gcc/testsuite/g++.dg/template/meminit1.C
@@ -3,6 +3,6 @@ template <class T >
struct S
{
S() : S() {} // { dg-message "delegating constructors" }
-};
+}; // { dg-error "delegates to itself" "" { target *-*-* } 5 }
S<int> s;
diff --git a/gcc/testsuite/g++.dg/template/redecl3.C b/gcc/testsuite/g++.dg/template/redecl3.C
index 029f9e69a5f..faa29bf453d 100644
--- a/gcc/testsuite/g++.dg/template/redecl3.C
+++ b/gcc/testsuite/g++.dg/template/redecl3.C
@@ -3,5 +3,5 @@
// { dg-do compile }
-int foo; // { dg-error "previous declaration" }
+int foo; // { dg-message "previous declaration" }
template<int> void foo() {} // { dg-error "redeclared" }
diff --git a/gcc/testsuite/g++.dg/template/using24.C b/gcc/testsuite/g++.dg/template/using24.C
new file mode 100644
index 00000000000..c3cdf93ec9b
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using24.C
@@ -0,0 +1,30 @@
+// PR c++/21682
+
+template <class T>
+struct t
+{
+ typedef typename T::type type;
+};
+template<> class t<int>{};
+
+template <class T> struct t1{ };
+template<> struct t1<int>
+{
+ typedef int type;
+};
+
+namespace name1
+{
+ template <class S> typename t<S>::type begin(S const& s);
+ namespace name2
+ {
+ template <class S> typename t1<S>::type begin(S const& s);
+ }
+ using name2::begin;
+}
+
+/* Test calling the function. */
+int f(int a) { return name1::begin(a); }
+
+struct aa { typedef double type; };
+double g(aa t) { return name1::begin(t); }
diff --git a/gcc/testsuite/g++.dg/template/using25.C b/gcc/testsuite/g++.dg/template/using25.C
new file mode 100644
index 00000000000..6f4a7def7ab
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using25.C
@@ -0,0 +1,17 @@
+// PR c++/21682
+
+namespace one {
+ template<typename T> void fun(T);
+}
+
+using one::fun;
+
+template<typename T> void fun(T); // { dg-error "conflicts" }
+
+template<typename T> void funr(T);
+
+namespace oner {
+ template<typename T> void funr(T);
+}
+
+using oner::funr; // { dg-error "conflicts" }
diff --git a/gcc/testsuite/g++.dg/template/using26.C b/gcc/testsuite/g++.dg/template/using26.C
new file mode 100644
index 00000000000..ca21857aad4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/using26.C
@@ -0,0 +1,49 @@
+// PR c++/21682
+
+namespace one {
+ template<typename T> int bar1(T);
+}
+
+using one::bar1;
+
+template<typename T> void bar1(T);
+
+template<typename T> void bar1r(T);
+
+namespace oner {
+ template<typename T> int bar1r(T);
+}
+
+using oner::bar1r;
+
+namespace two {
+ template<typename T, typename U> void bar2(T);
+}
+
+using two::bar2;
+
+template<typename T> void bar2(T);
+
+template<typename T> void bar2r(T);
+
+namespace twor {
+ template<typename T, typename U> void bar2r(T);
+}
+
+using twor::bar2r;
+
+namespace three {
+ template<int i> void bar3();
+}
+
+using three::bar3;
+
+template<typename T> void bar3();
+
+template<typename T> void bar3r();
+
+namespace threer {
+ template<int i> void bar3r();
+}
+
+using threer::bar3r;
diff --git a/gcc/testsuite/g++.dg/tls/diag-3.C b/gcc/testsuite/g++.dg/tls/diag-3.C
index ea5158b898f..06046170b0b 100644
--- a/gcc/testsuite/g++.dg/tls/diag-3.C
+++ b/gcc/testsuite/g++.dg/tls/diag-3.C
@@ -1,10 +1,10 @@
// Report invalid extern and __thread combinations.
// { dg-require-effective-target tls }
-extern int j; // { dg-error "previously declared here" }
+extern int j; // { dg-message "previously declared here" }
__thread int j; // { dg-error "follows non-thread-local" }
-extern __thread int i; // { dg-error "previously declared here" }
+extern __thread int i; // { dg-message "previously declared here" }
int i; // { dg-error "follows thread-local" }
extern __thread int k; // This is fine.
diff --git a/gcc/testsuite/g++.dg/tm/noexcept-6.C b/gcc/testsuite/g++.dg/tm/noexcept-6.C
new file mode 100644
index 00000000000..4391159e235
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tm/noexcept-6.C
@@ -0,0 +1,23 @@
+// { dg-do compile }
+// { dg-options "-fno-exceptions -fgnu-tm -O -std=c++0x -fdump-tree-tmlower" }
+
+struct TrueFalse
+{
+ static constexpr bool v() { return true; }
+};
+
+int global;
+
+template<typename T> int foo()
+{
+ return __transaction_atomic noexcept(T::v()) (global + 1);
+}
+
+int f1()
+{
+ return foo<TrueFalse>();
+}
+
+/* { dg-final { scan-tree-dump-times "eh_must_not_throw" 0 "tmlower" } } */
+/* { dg-final { scan-tree-dump-times "__transaction_atomic" 1 "tmlower" } } */
+/* { dg-final { cleanup-tree-dump "tmlower" } } */
diff --git a/gcc/testsuite/g++.dg/torture/PR58294.C b/gcc/testsuite/g++.dg/torture/PR58294.C
new file mode 100644
index 00000000000..e1fb95ae23d
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/PR58294.C
@@ -0,0 +1,20 @@
+// { dg-do compile }
+struct A {
+ virtual ~A();
+ virtual void m_fn1() { delete this; }
+ void m_fn2() { m_fn1(); }
+};
+
+struct B {
+ A *pi_;
+ B() { pi_->m_fn2(); }
+};
+struct C {
+ B pn;
+};
+void _setjmp();
+int png_decode() {
+ _setjmp();
+ C a;
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr58201.h b/gcc/testsuite/g++.dg/torture/pr58201.h
new file mode 100644
index 00000000000..6071ccdf877
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr58201.h
@@ -0,0 +1,24 @@
+class A
+{
+ protected:
+ A();
+ virtual ~A();
+};
+
+class B : virtual public A
+{
+ public:
+ B();
+ virtual ~B();
+};
+
+class C
+{
+ private:
+ class C2 : public B
+ {
+ public:
+ C2();
+ virtual ~C2();
+ };
+};
diff --git a/gcc/testsuite/g++.dg/torture/pr58201_0.C b/gcc/testsuite/g++.dg/torture/pr58201_0.C
new file mode 100644
index 00000000000..f8fa7173c11
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr58201_0.C
@@ -0,0 +1,9 @@
+#include "pr58201.h"
+
+C::C2::C2(){ }
+C::C2::~C2() { }
+
+int main ()
+{
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/torture/pr58201_1.C b/gcc/testsuite/g++.dg/torture/pr58201_1.C
new file mode 100644
index 00000000000..132cd5a43b8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/torture/pr58201_1.C
@@ -0,0 +1,10 @@
+/* { dg-do link } */
+/* { dg-options "-O2" } */
+/* { dg-additional-sources "pr58201_0.C" } */
+#include "pr58201.h"
+
+A::A() { }
+A::~A() { }
+B::B() { }
+B::~B() { }
+
diff --git a/gcc/testsuite/g++.dg/tree-prof/pr57451.C b/gcc/testsuite/g++.dg/tree-prof/pr57451.C
new file mode 100644
index 00000000000..db0fcc1e8ef
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-prof/pr57451.C
@@ -0,0 +1,26 @@
+// { dg-require-effective-target freorder }
+// { dg-options "-O2 -freorder-blocks-and-partition -g" }
+
+extern "C" void abort (void);
+struct MyException {};
+struct Data {
+ int nr;
+ Data() : nr(66) {}
+};
+Data __attribute__((noinline,noclone)) getData(int i)
+{
+ if (i) throw MyException();
+ Data data;
+ data.nr = i;
+ return data;
+}
+int main(int, char **)
+{
+ Data data;
+ try {
+ data = getData(1);
+ } catch (MyException& e) {
+ if (data.nr != 66)
+ abort ();
+ }
+}
diff --git a/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C b/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C
index 5513d3650c6..91f43ae8c0b 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/dom-invalid.C
@@ -1,7 +1,7 @@
// PR tree-optimization/39557
// invalid post-dom info leads to infinite loop
// { dg-do run }
-// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fno-rtti" }
+// { dg-options "-Wall -fno-exceptions -O2 -fprofile-use -fopt-info -fno-rtti" }
struct C
{
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr45453.C b/gcc/testsuite/g++.dg/tree-ssa/pr45453.C
index 78c6460f727..c8ef8955f0e 100644
--- a/gcc/testsuite/g++.dg/tree-ssa/pr45453.C
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr45453.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-tree-optimized" } */
+/* { dg-options "-O2 -fdump-tree-optimized -fno-devirtualize-speculatively" } */
struct S
{
S();
diff --git a/gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C b/gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C
new file mode 100644
index 00000000000..a5c0e330ab3
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/cxx11-shift-1.C
@@ -0,0 +1,9 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -w -std=c++11" } */
+
+int
+main (void)
+{
+ int a = 1;
+ a <<= 31;
+}
diff --git a/gcc/testsuite/g++.dg/ubsan/cxx11-shift-2.C b/gcc/testsuite/g++.dg/ubsan/cxx11-shift-2.C
new file mode 100644
index 00000000000..fbc16dfd3d8
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/cxx11-shift-2.C
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -w -std=c++11" } */
+
+int
+main (void)
+{
+ int a = -42;
+ a <<= 1;
+}
+/* { dg-output "left shift of negative value -42" } */
diff --git a/gcc/testsuite/g++.dg/ubsan/div-by-zero-1.C b/gcc/testsuite/g++.dg/ubsan/div-by-zero-1.C
new file mode 100644
index 00000000000..d7d2c8f1565
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/div-by-zero-1.C
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-fsanitize=shift -w" } */
+
+void
+foo (int i)
+{
+ switch (i)
+ case 0 * (1 / 0): /* { dg-error "is not a constant expression" } */
+ ;
+}
diff --git a/gcc/testsuite/g++.dg/ubsan/ubsan.exp b/gcc/testsuite/g++.dg/ubsan/ubsan.exp
new file mode 100644
index 00000000000..b2651a36a43
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/ubsan.exp
@@ -0,0 +1,34 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# Load support procs.
+load_lib g++-dg.exp
+load_lib ubsan-dg.exp
+
+# Initialize `dg'.
+dg-init
+if [ubsan_init] {
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.C $srcdir/c-c++-common/ubsan/*.c]] ""
+
+}
+
+# All done.
+ubsan_finish
+dg-finish
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr50413.cc b/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
index c47caf10747..6e69f11b382 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr50413.cc
@@ -160,6 +160,6 @@ void shift(unsigned char t)
V.bitmap.b96 = t;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr50819.cc b/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
index 96f82c30218..515d774a228 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr50819.cc
@@ -49,5 +49,5 @@ const & v2) {
res = res + s*(v1+v2);
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/g++.dg/vect/slp-pr56812.cc b/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
index 9570fb31e86..e98abc89df0 100644
--- a/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
+++ b/gcc/testsuite/g++.dg/vect/slp-pr56812.cc
@@ -17,5 +17,5 @@ void mydata::Set (float x)
data[i] = x;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/g++.dg/warn/Wredundant-decls-spec.C b/gcc/testsuite/g++.dg/warn/Wredundant-decls-spec.C
index b5c790f474b..3a9b019b675 100644
--- a/gcc/testsuite/g++.dg/warn/Wredundant-decls-spec.C
+++ b/gcc/testsuite/g++.dg/warn/Wredundant-decls-spec.C
@@ -8,5 +8,5 @@ template <typename T> struct S
template<> void S<int>::foo();
-template<> void S<double>::foo(); // { dg-warning "previous declaration" }
+template<> void S<double>::foo(); // { dg-message "previous declaration" }
template<> void S<double>::foo(); // { dg-warning "redundant redeclaration" }
diff --git a/gcc/testsuite/g++.dg/warn/deprecated-7.C b/gcc/testsuite/g++.dg/warn/deprecated-7.C
new file mode 100644
index 00000000000..f564a1bb0a9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/deprecated-7.C
@@ -0,0 +1,17 @@
+// PR c++/56130
+
+int g_nn;
+int& g_n __attribute__((deprecated)) = g_nn;
+
+void f()
+{
+ int f_nn;
+ int& f_n __attribute__((deprecated)) = f_nn;
+ f_n = 1; // { dg-warning "'f_n' is deprecated" }
+}
+
+int main()
+{
+ g_n = 1; // { dg-warning "'g_n' is deprecated" }
+ f();
+}
diff --git a/gcc/testsuite/g++.dg/warn/deprecated-8.C b/gcc/testsuite/g++.dg/warn/deprecated-8.C
new file mode 100644
index 00000000000..801811029a2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/warn/deprecated-8.C
@@ -0,0 +1,15 @@
+// PR c++/58305
+
+class ToBeDeprecated {
+} __attribute__ ((deprecated ("deprecated!")));
+
+typedef ToBeDeprecated NotToBeDeprecated; // { dg-warning "'ToBeDeprecated' is deprecated" }
+
+int main() {
+
+ ToBeDeprecated(); // { dg-warning "'ToBeDeprecated' is deprecated" }
+ ToBeDeprecated x; // { dg-warning "'ToBeDeprecated' is deprecated" }
+
+ NotToBeDeprecated();
+ NotToBeDeprecated y;
+}
diff --git a/gcc/testsuite/g++.dg/warn/weak1.C b/gcc/testsuite/g++.dg/warn/weak1.C
index efce90a2bcf..456e6f34c53 100644
--- a/gcc/testsuite/g++.dg/warn/weak1.C
+++ b/gcc/testsuite/g++.dg/warn/weak1.C
@@ -2,6 +2,7 @@
// { dg-require-weak "" }
// The PA HP-UX dynamic loader doesn't support unsatisfied weak symbols.
// { dg-skip-if "No unsat" { hppa*-*-hpux* } { "*" } { "" } }
+// { dg-skip-if "No weak unsat" { *-*-aix* } { "*" } { "" } }
// The darwin loader does, but they do need to exist at link time.
// { dg-skip-if "No link unsat" { *-*-darwin* } { "*" } { "" } }
// For kernel modules and static RTPs, the loader treats undefined weak
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C b/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
index d5ed39af364..af65162cf13 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/typedef01.C
@@ -16,7 +16,7 @@ typedef int I;
typedef I I;
//p3--cannot redefine to a different type in a given scope
-class complex2 { /* ... */ };// { dg-error "" } .*
+class complex2 { /* ... */ };// { dg-message "" } .*
typedef int complex2;// { dg-error "" } .*
typedef int complex3;// { dg-message "" } .*
class complex3 { /* ... */ };// { dg-error "" } .*
diff --git a/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C b/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C
index 248e1ed9ff1..a3d23747b48 100644
--- a/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C
+++ b/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C
@@ -44,11 +44,5 @@ public:
int b;
};
+extern int foo3(const char *); // { dg-message "" }
extern int foo3(const char *); // { dg-warning "" }
-extern int foo3(const char *); // { dg-warning "" }
-
-
-
-
-
-
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
index 674fc4fa679..5e6acc8c61c 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash16.C
@@ -5,7 +5,7 @@
class Graph { // { dg-error "1:new types|1: note: \\(perhaps" }
public:
unsigned char N;
- Graph(void) {} // { dg-error "7:'Graph" }
+ Graph(void) {} // { dg-message "7:'Graph" }
}
Graph::Graph(void) // { dg-error "18:return type|1: error: redefinition" }
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/crash18.C b/gcc/testsuite/g++.old-deja/g++.brendan/crash18.C
index 119ba460538..3119f02ede2 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/crash18.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/crash18.C
@@ -7,7 +7,7 @@ public:
Pix(const Pix&);
// Friend functions so that v == x works as does x == v works
- friend int operator==(void *v, const Pix& x) // { dg-error "previously" }
+ friend int operator==(void *v, const Pix& x) // { dg-message "previously" }
{ return v == index; } // { dg-error "from this location" }
// ??? should be operator!=
friend int operator==(void *v, const Pix& x) // { dg-error "redefinition" }
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/err-msg4.C b/gcc/testsuite/g++.old-deja/g++.brendan/err-msg4.C
index 2f4bc4210a3..d1d84448f38 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/err-msg4.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/err-msg4.C
@@ -2,8 +2,8 @@
// GROUPS passed error-messages
class X {
public:
- static int x;// { dg-error "" } previous.*
- static int y;// { dg-error "" } previous.*
+ static int x;// { dg-message "" } previous.*
+ static int y;// { dg-message "" } previous.*
};
unsigned X::x;// { dg-error "" } conflict.*
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/redecl1.C b/gcc/testsuite/g++.old-deja/g++.brendan/redecl1.C
index 0e01f2b4789..1edd548b668 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/redecl1.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/redecl1.C
@@ -1,5 +1,5 @@
// { dg-do assemble }
// GROUPS passed redeclaration
-inline int min(int x, int y) {return x < y ? x : y;} /* 235 */// { dg-error "" } .*
+inline int min(int x, int y) {return x < y ? x : y;} /* 235 */// { dg-message "" } .*
int min(int a, int b);
inline int min(int a, int b) {return (a < b)?a:b;}// { dg-error "" } .*
diff --git a/gcc/testsuite/g++.old-deja/g++.brendan/static3.C b/gcc/testsuite/g++.old-deja/g++.brendan/static3.C
index c0ee011787f..7c432310279 100644
--- a/gcc/testsuite/g++.old-deja/g++.brendan/static3.C
+++ b/gcc/testsuite/g++.old-deja/g++.brendan/static3.C
@@ -3,7 +3,7 @@
class foo{
public:
static void bar( int i ){ value = i; }
- static int value;// { dg-error "" } .*
+ static int value;// { dg-message "" } .*
};
const int foo::value = 0; // should be an error.// { dg-error "" } .*
diff --git a/gcc/testsuite/g++.old-deja/g++.bugs/900127_02.C b/gcc/testsuite/g++.old-deja/g++.bugs/900127_02.C
index 12ae64a36a0..c74baa9406a 100644
--- a/gcc/testsuite/g++.old-deja/g++.bugs/900127_02.C
+++ b/gcc/testsuite/g++.old-deja/g++.bugs/900127_02.C
@@ -16,10 +16,10 @@
// keywords: name spaces, overloading
-int global0; // { dg-error "" }
+int global0; // { dg-message "" }
int global0 (); // { dg-error "" }
-int global1 (); // { dg-error "" } xref for below
+int global1 (); // { dg-message "" } xref for below
int global1; // { dg-error "" } caught
struct struct_0 {
@@ -34,13 +34,13 @@ struct struct_1 {
void function_0 ()
{
- int function_0_local; // { dg-error "" }
+ int function_0_local; // { dg-message "" }
extern int function_0_local (); // { dg-error "" }
}
void function_1 ()
{
- int function_1_local (); // { dg-error "" }
+ int function_1_local (); // { dg-message "" }
extern int function_1_local; // { dg-error "" }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/binding.C b/gcc/testsuite/g++.old-deja/g++.jason/binding.C
index 1f297b76d6c..3321cece23a 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/binding.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/binding.C
@@ -6,7 +6,7 @@ struct T { ~T(); };
int main()
{
foo:
- T t; // { dg-error "" } redeclared
+ T t; // { dg-message "" } redeclared
bar:
T t; // { dg-error "" } redeclaration
}
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/crash4.C b/gcc/testsuite/g++.old-deja/g++.jason/crash4.C
index 00ba0cc0644..30c563b9d83 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/crash4.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/crash4.C
@@ -16,7 +16,7 @@ public:
};
template <class T>
-const ccObjectInfo& cc_Array<T>::repInvariant(int) const // { dg-error "previously declared" }
+const ccObjectInfo& cc_Array<T>::repInvariant(int) const // { dg-message "previously declared" }
{ return *this /* *this is required here */; }
template <class T>
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/crash7.C b/gcc/testsuite/g++.old-deja/g++.jason/crash7.C
index 95c7c2fb5a0..f17c402976f 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/crash7.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/crash7.C
@@ -1,6 +1,6 @@
// { dg-do assemble }
// Bug: g++ can't deal.
-typedef unsigned size_t; // { dg-error "" } previous declaration
+typedef unsigned size_t; // { dg-message "" } previous declaration
typedef unsigned long size_t; // { dg-error "" } redefining size_t
void f (size_t); // causes compiler segfault -
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/lineno.C b/gcc/testsuite/g++.old-deja/g++.jason/lineno.C
index bd5a393e50e..4ef9208ea34 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/lineno.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/lineno.C
@@ -1,6 +1,6 @@
// { dg-do assemble }
// Bug; g++ binds a function definition to the line number of a later decl.
-void foo () { } // { dg-error "" } redeclared
+void foo () { } // { dg-message "" } redeclared
void foo (); // { dg-bogus "" } invalid binding
void foo () { } // { dg-error "" } redeclared
diff --git a/gcc/testsuite/g++.old-deja/g++.jason/scoping7.C b/gcc/testsuite/g++.old-deja/g++.jason/scoping7.C
index 41859aa3981..245c8fa073e 100644
--- a/gcc/testsuite/g++.old-deja/g++.jason/scoping7.C
+++ b/gcc/testsuite/g++.old-deja/g++.jason/scoping7.C
@@ -2,5 +2,5 @@
// Bug: g++ doesn't flag name collisions between types and non-types as
// errors. It shouldn't for class names, but it should for typedefs.
-int bar; // { dg-error "" }
+int bar; // { dg-message "" }
typedef int bar; // { dg-error "" }
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/misc3.C b/gcc/testsuite/g++.old-deja/g++.mike/misc3.C
index 560f0c13efc..f633873f854 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/misc3.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/misc3.C
@@ -1,4 +1,4 @@
// { dg-do assemble }
// GROUPS uncaught
-int a;// { dg-error "" } .*
+int a;// { dg-message "" } .*
int a;// { dg-error "" } .*
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/net44.C b/gcc/testsuite/g++.old-deja/g++.mike/net44.C
index bc45b487888..226df2d9e7a 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/net44.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/net44.C
@@ -1,7 +1,7 @@
// { dg-do assemble }
// Make sure we don't dump core
-enum request { q, w, e}; // { dg-error "" }
+enum request { q, w, e}; // { dg-message "" }
class request { // { dg-error "" }
public:
diff --git a/gcc/testsuite/g++.old-deja/g++.mike/ns3.C b/gcc/testsuite/g++.old-deja/g++.mike/ns3.C
index eb40fe4aea7..b39a1d78452 100644
--- a/gcc/testsuite/g++.old-deja/g++.mike/ns3.C
+++ b/gcc/testsuite/g++.old-deja/g++.mike/ns3.C
@@ -1,5 +1,5 @@
// { dg-do assemble }
-int i; // { dg-error "" }
+int i; // { dg-message "" }
namespace i { // { dg-error "" }
}
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/alias4.C b/gcc/testsuite/g++.old-deja/g++.ns/alias4.C
index 5bff439fcee..2d9dd4a4c57 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/alias4.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/alias4.C
@@ -7,7 +7,7 @@ namespace D { // { dg-error "" } reopening namespace with alias
void f();
}
-void C::f(){} // { dg-error "" } previous definition
+void C::f(){} // { dg-message "" } previous definition
void D::f(){} // { dg-error "" } redefinition
diff --git a/gcc/testsuite/g++.old-deja/g++.ns/ns11.C b/gcc/testsuite/g++.old-deja/g++.ns/ns11.C
index 2dc0344f399..3067bdfb7c3 100644
--- a/gcc/testsuite/g++.old-deja/g++.ns/ns11.C
+++ b/gcc/testsuite/g++.old-deja/g++.ns/ns11.C
@@ -5,7 +5,7 @@
namespace A{
void f(int);
void f(int,int);
- int i; // { dg-error "" } .*
+ int i; // { dg-message "" } .*
}
void A::f(){} // { dg-error "" } should have been declared before
diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash23.C b/gcc/testsuite/g++.old-deja/g++.other/crash23.C
index 13249020fe9..72f94cb1a01 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/crash23.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/crash23.C
@@ -2,6 +2,6 @@
// Origin: Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at>
class T;
-inline void operator<(T&, T&) { } // { dg-error "" } previous definition
+inline void operator<(T&, T&) { } // { dg-message "" } previous definition
inline void operator<(T&, T&) { } // { dg-error "" } duplicate definition
diff --git a/gcc/testsuite/g++.old-deja/g++.other/decl8.C b/gcc/testsuite/g++.old-deja/g++.other/decl8.C
index 705fc6c5df8..ebcc064404f 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/decl8.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/decl8.C
@@ -3,7 +3,7 @@
void foo(void)
{
- extern int i; // { dg-error "" } previous declaration
+ extern int i; // { dg-message "" } previous declaration
extern double i; // { dg-error "" } conflicting type
extern int j;
extern int j;
diff --git a/gcc/testsuite/g++.old-deja/g++.other/linkage3.C b/gcc/testsuite/g++.old-deja/g++.other/linkage3.C
index 8ddff82f50d..5e01c1d1f90 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/linkage3.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/linkage3.C
@@ -1,5 +1,5 @@
// { dg-do assemble }
// Origin: Mark Mitchell <mark@codesourcery.com>
-extern "C" void f (); // { dg-error "" } previous declaration
+extern "C" void f (); // { dg-message "" } previous declaration
static void f () {} // { dg-error "" } extern redeclared static
diff --git a/gcc/testsuite/g++.old-deja/g++.other/typeck1.C b/gcc/testsuite/g++.old-deja/g++.other/typeck1.C
index 574fd7e2836..1dce27397ae 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/typeck1.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/typeck1.C
@@ -4,7 +4,7 @@ extern int a[][]; // { dg-error "" } invalid multidimensional array
extern int b[7][]; // { dg-error "" } invalid multidimensional array
extern int c[][7]; // OK
-extern int (*i)[]; // { dg-error "" } previous declaration
+extern int (*i)[]; // { dg-message "" } previous declaration
extern int (*i)[7]; // { dg-error "" } conflicting types for `i'
extern int m[];
diff --git a/gcc/testsuite/g++.old-deja/g++.other/typedef5.C b/gcc/testsuite/g++.old-deja/g++.other/typedef5.C
index f9e71479c7f..09845509028 100644
--- a/gcc/testsuite/g++.old-deja/g++.other/typedef5.C
+++ b/gcc/testsuite/g++.old-deja/g++.other/typedef5.C
@@ -10,7 +10,7 @@ typedef int t;
typedef t* u;
typedef u v;
typedef v* (*w)(t const); // this is ok
-typedef v* (*w)(t); // { dg-error "" } covers message `previously declared here'
+typedef v* (*w)(t); // { dg-message "" } covers message `previously declared here'
typedef v* (*const w)(t); // { dg-error "" } invalid redeclaration
typedef v const* (*w)(t); // { dg-error "" } invalid redeclaration
typedef v* const (*w)(t); // { dg-error "" } invalid redeclaration
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/explicit34.C b/gcc/testsuite/g++.old-deja/g++.pt/explicit34.C
index ea32cf6ea9e..54029eb8544 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/explicit34.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/explicit34.C
@@ -5,7 +5,7 @@ template <class T>
void foo(T t);
template <>
-void foo(int) {}; // { dg-error "6:previously declared here" }
+void foo(int) {}; // { dg-message "6:previously declared here" }
template <>
void foo<int>(int) {} // { dg-error "6:redefinition" }
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/friend36.C b/gcc/testsuite/g++.old-deja/g++.pt/friend36.C
index f5cb8d40a06..f6f261ba07f 100644
--- a/gcc/testsuite/g++.old-deja/g++.pt/friend36.C
+++ b/gcc/testsuite/g++.old-deja/g++.pt/friend36.C
@@ -1,7 +1,7 @@
// { dg-do assemble }
template <class T>
-void f(T) {} // { dg-error "previously" }
+void f(T) {} // { dg-message "previously" }
template <class U>
struct S {
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58164.c b/gcc/testsuite/gcc.c-torture/compile/pr58164.c
new file mode 100644
index 00000000000..7fe24fa439f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr58164.c
@@ -0,0 +1,8 @@
+/* PR tree-optimization/58164 */
+
+int
+foo (void)
+{
+ int x = 0;
+ goto *&x;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr58340.c b/gcc/testsuite/gcc.c-torture/compile/pr58340.c
new file mode 100644
index 00000000000..ca3ccda0a47
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr58340.c
@@ -0,0 +1,16 @@
+int a, b, c, d;
+
+int foo (int x, int y)
+{
+ return y == 0 ? x : 1 % y;
+}
+
+int main ()
+{
+ c = 0 || a;
+
+ for (;;)
+ b = foo (d, c) && 1;
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c
index 8d821839b1a..bd54318a263 100644
--- a/gcc/testsuite/gcc.c-torture/execute/20101011-1.c
+++ b/gcc/testsuite/gcc.c-torture/execute/20101011-1.c
@@ -43,6 +43,9 @@
#elif defined (__CRIS__)
/* No SIGFPE for CRIS integer division. */
# define DO_TEST 0
+#elif defined (__arc__)
+ /* No SIGFPE for ARC integer division. */
+# define DO_TEST 0
#elif defined (__arm__) && defined (__ARM_EABI__)
# ifdef __ARM_ARCH_EXT_IDIV__
/* Hardware division instructions may not trap, and handle trapping
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr56799.x b/gcc/testsuite/gcc.c-torture/execute/pr56799.x
new file mode 100644
index 00000000000..4efed4c325f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr56799.x
@@ -0,0 +1,7 @@
+load_lib target-supports.exp
+
+if { [check_effective_target_int32plus] } {
+ return 0
+}
+
+return 1;
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57860.c b/gcc/testsuite/gcc.c-torture/execute/pr57860.c
new file mode 100644
index 00000000000..6cef63e7077
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr57860.c
@@ -0,0 +1,25 @@
+/* PR rtl-optimization/57860 */
+
+extern void abort (void);
+int a, *b = &a, c, d, e, *f = &e, g, *h = &d, k[1] = { 1 };
+
+int
+foo (int p)
+{
+ for (;; g++)
+ {
+ for (; c; c--);
+ *f = *h = p > ((0x1FFFFFFFFLL ^ a) & *b);
+ if (k[g])
+ return 0;
+ }
+}
+
+int
+main ()
+{
+ foo (1);
+ if (d != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57861.c b/gcc/testsuite/gcc.c-torture/execute/pr57861.c
new file mode 100644
index 00000000000..138eb617e5b
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr57861.c
@@ -0,0 +1,33 @@
+/* PR rtl-optimization/57861 */
+
+extern void abort (void);
+short a = 1, f;
+int b, c, d, *g = &b, h, i, j;
+unsigned int e;
+
+static int
+foo (char p)
+{
+ int k;
+ for (c = 0; c < 2; c++)
+ {
+ i = (j = 0) || p;
+ k = i * p;
+ if (e < k)
+ {
+ short *l = &f;
+ a = d && h;
+ *l = 0;
+ }
+ }
+ return 0;
+}
+
+int
+main ()
+{
+ *g = foo (a);
+ if (a != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57875.c b/gcc/testsuite/gcc.c-torture/execute/pr57875.c
new file mode 100644
index 00000000000..c3ae51b441f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr57875.c
@@ -0,0 +1,21 @@
+/* PR rtl-optimization/57875 */
+
+extern void abort (void);
+int a[1], b, c, d, f, i;
+char e[1];
+
+int
+main ()
+{
+ for (; i < 1; i++)
+ if (!d)
+ {
+ if (!c)
+ f = 2;
+ e[0] &= f ^= 0;
+ }
+ b = a[e[0] >> 1 & 1];
+ if (b != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57876.c b/gcc/testsuite/gcc.c-torture/execute/pr57876.c
new file mode 100644
index 00000000000..bcf69127286
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr57876.c
@@ -0,0 +1,27 @@
+/* PR rtl-optimization/57876 */
+
+extern void abort (void);
+int a, b = 1, c, *d = &c, f, *g, h, j;
+static int e;
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 2; i++)
+ {
+ long long k = b;
+ int l;
+ for (f = 0; f < 8; f++)
+ {
+ int *m = &e;
+ j = *d;
+ h = a * j - 1;
+ *m = (h == 0) < k;
+ g = &l;
+ }
+ }
+ if (e != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr57877.c b/gcc/testsuite/gcc.c-torture/execute/pr57877.c
new file mode 100644
index 00000000000..2d6ce447a31
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr57877.c
@@ -0,0 +1,28 @@
+/* PR rtl-optimization/57877 */
+
+extern void abort (void);
+int a, b, *c = &b, e, f = 6, g, h;
+short d;
+
+static unsigned char
+foo (unsigned long long p1, int *p2)
+{
+ for (; g <= 0; g++)
+ {
+ short *i = &d;
+ int *j = &e;
+ h = *c;
+ *i = h;
+ *j = (*i == *p2) < p1;
+ }
+ return 0;
+}
+
+int
+main ()
+{
+ foo (f, &a);
+ if (e != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58209.c b/gcc/testsuite/gcc.c-torture/execute/pr58209.c
new file mode 100644
index 00000000000..78743bfb959
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr58209.c
@@ -0,0 +1,32 @@
+/* PR tree-optimization/58209 */
+
+extern void abort (void);
+typedef __INTPTR_TYPE__ T;
+T buf[1024];
+
+T *
+foo (T n)
+{
+ if (n == 0)
+ return (T *) buf;
+ T s = (T) foo (n - 1);
+ return (T *) (s + sizeof (T));
+}
+
+T *
+bar (T n)
+{
+ if (n == 0)
+ return buf;
+ return foo (n - 1) + 1;
+}
+
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 27; i++)
+ if (foo (i) != buf + i || bar (i) != buf + i)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58277-1.c b/gcc/testsuite/gcc.c-torture/execute/pr58277-1.c
new file mode 100644
index 00000000000..811988f4371
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr58277-1.c
@@ -0,0 +1,102 @@
+/* PR tree-optimization/58277 */
+
+extern void abort (void);
+static int a[2];
+int b, c, d, *e, f, g, h, **i = &e, k, l = 1, n, o, p;
+static int **volatile j = &e;
+const int m;
+char u;
+
+int
+bar ()
+{
+ u = 0;
+ return m;
+}
+
+__attribute__((noinline, noclone)) void
+baz ()
+{
+ asm ("");
+}
+
+static int
+foo ()
+{
+ int t1;
+ g = bar ();
+ if (l)
+ ;
+ else
+ for (;; h++)
+ {
+ *i = 0;
+ o = *e = 0;
+ if (p)
+ {
+ f = 0;
+ return 0;
+ }
+ for (;; k++)
+ {
+ int *t2 = 0;
+ int *const *t3[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, &t2, &t2, &t2,
+ &t2, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, &t2,
+ &t2, &t2, &t2, 0, 0, 0, 0, 0, 0, 0, &t2, 0, 0, 0,
+ &t2, 0, 0, 0, &t2, 0, &t2, 0, 0, &t2, 0, 0, 0, 0,
+ 0, &t2, 0, 0, 0, 0, &t2, &t2, 0, 0, 0, 0, &t2, 0,
+ 0, 0, 0, 0, 0, 0, &t2, 0, 0, 0, 0, 0, &t2, 0, 0, 0,
+ &t2, &t2
+ };
+ int *const **t4[] = {&t3[0]};
+ **i = 0;
+ if (**j)
+ break;
+ u = 0;
+ }
+ *i = *j;
+ t1 = 0;
+ for (; t1 < 5; t1++)
+ *i = *j;
+ }
+ *j = 0;
+ return 1;
+}
+
+int
+main ()
+{
+ int t5;
+ a[0] = 1;
+ {
+ int *t6[6] = {&d, &d};
+ for (n = 1; n; n--)
+ if (foo())
+ {
+ int *t7[] = {0};
+ d = 0;
+ for (; u < 1; u++)
+ *i = *j;
+ *i = 0;
+ *i = 0;
+ int t8[5] = {0};
+ *i = &t8[0];
+ int *const *t9 = &t6[0];
+ int *const **t10 = &t9;
+ *t10 = &t7[0];
+ }
+ }
+ u = 0;
+ for (; b; b++)
+ for (t5 = 0; t5 < 10; t5++)
+ c = a[a[a[a[a[a[a[a[c]]]]]]]];
+
+ baz ();
+
+ if (!a[a[a[a[a[a[a[a[a[a[a[a[a[a[a[u]]]]]]]]]]]]]]])
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr58277-2.c b/gcc/testsuite/gcc.c-torture/execute/pr58277-2.c
new file mode 100644
index 00000000000..d919c2f3f80
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr58277-2.c
@@ -0,0 +1,98 @@
+/* PR tree-optimization/58277 */
+
+extern void abort (void);
+static int a[1], b, c, e, i, j, k, m, q[] = { 1, 1 }, t;
+int volatile d;
+int **r;
+static int ***volatile s = &r;
+int f, g, o, x;
+static int *volatile h = &f, *p;
+char n;
+
+static void
+fn1 ()
+{
+ b = a[a[a[a[a[a[a[a[b]]]]]]]];
+ b = a[a[a[a[a[a[a[a[b]]]]]]]];
+ b = a[a[b]];
+ b = a[a[a[a[a[a[a[a[b]]]]]]]];
+ b = a[a[a[a[a[a[a[a[b]]]]]]]];
+}
+
+static int
+fn2 ()
+{
+ n = 0;
+ for (; g; t++)
+ {
+ for (;; m++)
+ {
+ d;
+ int *u;
+ int **v[] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, &u, 0, 0, 0, 0, &u, &u, &u, &u, &u, &u, &u, 0,
+ &u, 0, &u, &u, &u, 0, &u, &u, 0, &u, &u, &u, &u, 0, &u, &u, &u,
+ &u, &u, 0, &u, &u, 0, &u, 0, &u, &u, 0, &u, &u, &u, &u, &u, 0,
+ &u, 0, 0, 0, &u, &u, &u, 0, 0, &u, &u, &u, 0, &u, 0, &u, &u
+ };
+ int ***w[] = { &v[0] };
+ if (*p)
+ break;
+ return 0;
+ }
+ *h = 0;
+ }
+ return 1;
+}
+
+static void
+fn3 ()
+{
+ int *y[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ for (; i; i++)
+ x = 0;
+ if (fn2 ())
+ {
+ int *z[6] = { };
+ for (; n < 1; n++)
+ *h = 0;
+ int t1[7];
+ for (; c; c++)
+ o = t1[0];
+ for (; e; e--)
+ {
+ int **t2 = &y[0];
+ int ***t3 = &t2;
+ *t3 = &z[0];
+ }
+ }
+ *s = 0;
+ for (n = 0;; n = 0)
+ {
+ int t4 = 0;
+ if (q[n])
+ break;
+ *r = &t4;
+ }
+}
+
+int
+main ()
+{
+ for (; j; j--)
+ a[0] = 0;
+ fn3 ();
+ for (; k; k++)
+ fn1 ();
+ fn1 ();
+
+ if (n)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/asan/pr56417.c b/gcc/testsuite/gcc.dg/asan/pr56417.c
new file mode 100644
index 00000000000..b7eabf125aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/asan/pr56417.c
@@ -0,0 +1,9 @@
+/* PR sanitizer/56417 */
+/* { dg-do compile } */
+/* { dg-options "-w" } */
+
+int
+foo (void)
+{
+ return __builtin_strlen (&foo);
+}
diff --git a/gcc/testsuite/gcc.dg/attr-weakref-1.c b/gcc/testsuite/gcc.dg/attr-weakref-1.c
index 898bc4169a0..ee900fcdec5 100644
--- a/gcc/testsuite/gcc.dg/attr-weakref-1.c
+++ b/gcc/testsuite/gcc.dg/attr-weakref-1.c
@@ -4,7 +4,7 @@
// This test requires support for undefined weak symbols. This support
// is not available on hppa*-*-hpux*. The test is skipped rather than
// xfailed to suppress the warning that would otherwise arise.
-// { dg-skip-if "" { "*-*-darwin*" "hppa*-*-hpux*" } "*" { "" } }
+// { dg-skip-if "" { "*-*-darwin*" "hppa*-*-hpux*" "*-*-aix*" } "*" { "" } }
// For kernel modules and static RTPs, the loader treats undefined weak
// symbols in the same way as undefined strong symbols. The test
// therefore fails to load, so skip it.
diff --git a/gcc/testsuite/gcc.dg/autopar/pr49960.c b/gcc/testsuite/gcc.dg/autopar/pr49960.c
index b34a5207755..5dacb8de84a 100644
--- a/gcc/testsuite/gcc.dg/autopar/pr49960.c
+++ b/gcc/testsuite/gcc.dg/autopar/pr49960.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized" } */
+/* { dg-options "-O2 -ftree-parallelize-loops=4 -fdump-tree-parloops-details -fdump-tree-optimized -fno-partial-inlining" } */
#include <stdio.h>
#define MB 100
@@ -12,7 +12,9 @@ void MRTRBR(int MA_1, int NA_1, int MB_1)
int i,j, t,k;
/* At the moment we are not able to hoist the loop headers out of the loop
- nest. */
+ nest.
+ Partial inlining needs to be disabled so we do not optimize this out
+ of the function body. */
if (MA_1 < 4 || NA_1 < 4 || MB_1 < 4)
return;
diff --git a/gcc/testsuite/gcc.dg/builtin-apply2.c b/gcc/testsuite/gcc.dg/builtin-apply2.c
index 9b731470e6c..daaef477894 100644
--- a/gcc/testsuite/gcc.dg/builtin-apply2.c
+++ b/gcc/testsuite/gcc.dg/builtin-apply2.c
@@ -17,7 +17,7 @@
E, F and G are passed on stack. So the size of the stack argument
data is 20. */
#define STACK_ARGUMENTS_SIZE 20
-#elif defined __MMIX__
+#elif defined __MMIX__ || defined __arc__
/* No parameters on stack for bar. */
#define STACK_ARGUMENTS_SIZE 0
#else
diff --git a/gcc/testsuite/gcc.dg/c99-stdint-1.c b/gcc/testsuite/gcc.dg/c99-stdint-1.c
index 37e1203f0ae..89bdec809f8 100644
--- a/gcc/testsuite/gcc.dg/c99-stdint-1.c
+++ b/gcc/testsuite/gcc.dg/c99-stdint-1.c
@@ -214,7 +214,7 @@ test_max (void)
void
test_misc_limits (void)
{
-/* { dg-bogus "size" "ptrdiff is 16bits" { xfail avr-*-* } 218 } */
+/* { dg-bogus "size" "ptrdiff is 16bits" { xfail avr-*-* } 56 } */
CHECK_SIGNED_LIMITS_2(__PTRDIFF_TYPE__, PTRDIFF_MIN, PTRDIFF_MAX, -65535L, 65535L);
#ifndef SIGNAL_SUPPRESS
CHECK_LIMITS_2(sig_atomic_t, SIG_ATOMIC_MIN, SIG_ATOMIC_MAX, -127, 127, 255);
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/aranges-fnsec-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/aranges-fnsec-1.c
index 8a97e4dc2ac..4e40aea4ea7 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/aranges-fnsec-1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/aranges-fnsec-1.c
@@ -3,7 +3,7 @@
/* Origin: Joseph Myers <joseph@codesourcery.com> */
/* { dg-do compile } */
/* { dg-require-effective-target function_sections } */
-/* { dg-options "-gdwarf-2 -ffunction-sections -w -dA" } */
+/* { dg-options "-gdwarf -ffunction-sections -w -dA" } */
/* { dg-final { scan-assembler-not "\\.Letext0-\\.Ltext0" } } */
/* { dg-final { scan-assembler-not "\\.Ltext0\[^\n\r\]*Offset 0x0" } } */
/* { dg-final { scan-assembler "DW_AT_ranges" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/asm-line1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/asm-line1.c
index f94dfce93ea..3773e1c83c3 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/asm-line1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/asm-line1.c
@@ -1,6 +1,6 @@
/* PR debug/50983 */
/* { dg-do compile { target *-*-gnu* } } */
-/* { dg-options "-O0 -gdwarf-2" } */
+/* { dg-options "-O0 -gdwarf" } */
/* { dg-final { scan-assembler "is_stmt 1" } } */
int i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/c99-typedef1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/c99-typedef1.c
index b7bd66a6023..c1ca1ebb6a2 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/c99-typedef1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/c99-typedef1.c
@@ -1,4 +1,4 @@
-// { dg-options "-std=iso9899:1999 -gdwarf-2" }
+// { dg-options "-std=iso9899:1999 -gdwarf" }
void f() {
int n = 3;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/const-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/const-2.c
index 16e1d8bd140..b139122fdeb 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/const-2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/const-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target powerpc_altivec_ok } } */
-/* { dg-options "-O -gdwarf-2 -dA -maltivec" } */
+/* { dg-options "-O -gdwarf -dA -maltivec" } */
/* { dg-final { scan-assembler "DW_AT_const_value" } } */
typedef float FloatVect __attribute__((__vector_size__(16)));
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/const-2b.c b/gcc/testsuite/gcc.dg/debug/dwarf2/const-2b.c
index 6cbdc85b3d5..e7d199d1c4e 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/const-2b.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/const-2b.c
@@ -1,5 +1,5 @@
/* { dg-do compile { target i386*-*-* } } */
-/* { dg-options "-O -gdwarf-2 -dA -msse" } */
+/* { dg-options "-O -gdwarf -dA -msse" } */
/* { dg-require-effective-target sse } */
/* { dg-final { scan-assembler "DW_AT_const_value" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c b/gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c
index 5eef4ab95fe..b77f7b1bfff 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/discriminator.c
@@ -1,7 +1,7 @@
/* HAVE_AS_DWARF2_DEBUG_LINE macro needs to be defined to pass the unittest.
However, dg cannot access it, so we restrict to GNU targets. */
/* { dg-do compile { target *-*-gnu* } } */
-/* { dg-options "-O0 -gdwarf-2" } */
+/* { dg-options "-O0 -gdwarf" } */
/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])?\n" } } */
/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])? discriminator 2\n" } } */
/* { dg-final { scan-assembler "loc \[0-9] 11 \[0-9]( is_stmt \[0-9])? discriminator 1\n" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char1.c
index ed32349b4de..23f9596732f 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char1.c
@@ -1,6 +1,6 @@
/* PR debug/7241 */
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */
/* { dg-final { scan-assembler "0x\[68\]\[ \t\]+\[#@;!/|\]+\[ \t\]+DW_AT_encoding" } } */
/* { dg-final { scan-assembler-not "0x\[57\]\[ \t\]+\[#@;!/|\]+\[ \t\]+DW_AT_encoding" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char2.c
index dc145852fcd..4a4bd438ce7 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char2.c
@@ -1,6 +1,6 @@
/* PR debug/7241 */
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */
/* { dg-final { scan-assembler "0x\[68\]\[ \t\]+\[#@;!/|\]+\[ \t\]+DW_AT_encoding" } } */
/* { dg-final { scan-assembler-not "0x\[57\]\[ \t\]+\[#@;!/|\]+\[ \t\]+DW_AT_encoding" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char3.c
index edc1d83ed4f..4ff201f1345 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char3.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-char3.c
@@ -1,6 +1,6 @@
/* PR debug/7241 */
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
/* { dg-skip-if "Unmatchable assembly" { mmix-*-* } { "*" } { "" } } */
/* { dg-final { scan-assembler "0x\[68\]\[ \t\]+\[#@;!/|\]+\[ \t\]+DW_AT_encoding" } } */
/* { dg-final { scan-assembler-not "0x\[57\]\[ \t\]+\[#@;!/|\]+\[ \t\]+DW_AT_encoding" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-dfp.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-dfp.c
index ddb602250ce..951380f125f 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-dfp.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-dfp.c
@@ -2,7 +2,7 @@
/* { dg-do compile */
/* { dg-require-effective-target dfp } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
/* { dg-final { scan-assembler "0x10.*DW_AT_encoding" } } */
/* { dg-final { scan-assembler "0x4.*DW_AT_byte_size" } } */
/* { dg-final { scan-assembler "0x8.*DW_AT_byte_size" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die1.c
index fdfbf83215e..9ca84e757b0 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die1.c
@@ -1,6 +1,6 @@
/* Verify that inline function never actually inlined has no abstract DIE. */
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
/* { dg-final { scan-assembler-not "DW_AT_inline" } } */
inline int t()
{
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die2.c
index ac897ab78c1..746ab031b83 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die2.c
@@ -1,6 +1,6 @@
/* Verify that inline function never actually emit has no DIE. */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
/* { dg-final { scan-assembler-not "CIE Version" } } */
static inline int t()
{
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die3.c
index 04b2f36c3b3..2b071fc9ed0 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die3.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die3.c
@@ -1,6 +1,6 @@
/* Verify that extern inline function never actually inlined has no abstract DIE. */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
/* { dg-final { scan-assembler-not "DW_AT_inline" } } */
extern inline int t()
{
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die5.c
index 3fefd41ef94..68985b71fab 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die5.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die5.c
@@ -1,6 +1,6 @@
/* Inlined inline function must have abstract DIE */
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA -fpreprocessed" } */
+/* { dg-options "-O2 -gdwarf -dA -fpreprocessed" } */
/* { dg-final { scan-assembler "3.*DW_AT_inline" } } */
#1 "test.h"
inline int t()
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die6.c
index d8f477f54e8..ff0d6798df2 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die6.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die6.c
@@ -1,6 +1,6 @@
/* not inline inline function must not have abstract DIE */
/* { dg-do compile } */
-/* { dg-options "-O2 -fno-inline -gdwarf-2 -dA -fpreprocessed" } */
+/* { dg-options "-O2 -fno-inline -gdwarf -dA -fpreprocessed" } */
/* { dg-final { scan-assembler-not "DW_AT_inline" } } */
#1 "test.h"
inline int t()
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die7.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die7.c
index b747076bac6..88d78e23358 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die7.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-die7.c
@@ -1,6 +1,6 @@
/* Inlined non-inline function must have abstract DIE */
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA -fpreprocessed" } */
+/* { dg-options "-O2 -gdwarf -dA -fpreprocessed" } */
/* { dg-final { scan-assembler "1.*DW_AT_inline" } } */
#1 "test.h"
void f(void);
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-file1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-file1.c
index c68dfe436e3..b75395557bf 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-file1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-file1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
/* { dg-final { scan-assembler "File Entry:|.file" } } */
/* Verify that a file entry is output for this file. Only systems that
do not define HAVE_AS_DWARF2_DEBUG_LINE will put out "File Entry:",
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-float.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-float.c
index 84d605fcd03..a028d1484af 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-float.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-float.c
@@ -1,7 +1,7 @@
/* Verify the DWARF encoding of C99 floating point types. */
/* { dg-do compile */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
/* { dg-final { scan-assembler "0x4.*DW_AT_encoding" } } */
/* { dg-final { scan-assembler "0x4.*DW_AT_byte_size" } } */
/* { dg-final { scan-assembler "0x8.*DW_AT_byte_size" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-merge.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-merge.c
index 767d38b173b..15e09b116cc 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-merge.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-merge.c
@@ -1,7 +1,7 @@
/* Verify that mergeable strings are used in the CU DIE. */
/* { dg-do compile } */
/* { dg-require-effective-target string_merging } */
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
/* { dg-final { scan-assembler "DW_AT_producer: \"GNU C" } } */
/* { dg-final { scan-assembler-not "GNU C\[^\\n\\r\]*DW_AT_producer" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-uninit.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-uninit.c
index 7bcebe355e5..d871bab0c2e 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-uninit.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf-uninit.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
/* { dg-final { scan-assembler "DW_TAG_variable" } } */
/* PR debug/21828 */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c
index 4efb25e8c22..fd61296b2f1 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2-macro.c
@@ -1,6 +1,6 @@
/* Test to make sure the mcaro info includes a start file command for the main source */
/* { dg-do compile } */
-/* { dg-options "-g3 -gdwarf-2 -dA -fverbose-asm" } */
+/* { dg-options "-g3 -gdwarf -dA -fverbose-asm" } */
/* { dg-final { scan-assembler "Start new file" } } */
#define ADD(x) (M + x)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2.exp b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2.exp
index 829840c2052..824d9947f09 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2.exp
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/dwarf2.exp
@@ -22,7 +22,7 @@ load_lib gcc-dg.exp
# If a testcase doesn't have special options, use these.
global DEFAULT_CFLAGS
if ![info exists DEFAULT_CFLAGS] then {
- set DEFAULT_CFLAGS " -ansi -pedantic-errors -gdwarf-2"
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors -gdwarf"
}
# Initialize `dg'.
@@ -31,7 +31,7 @@ dg-init
# Main loop.
set comp_output [gcc_target_compile \
"$srcdir/$subdir/../trivial.c" "trivial.S" assembly \
- "additional_flags=-gdwarf-2"]
+ "additional_flags=-gdwarf"]
if { ! [string match "*: target system does not support the * debug format*" \
$comp_output] } {
remove-build-file "trivial.S"
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-any.c b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-any.c
index fc510903c2c..810788ae6e3 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-any.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-any.c
@@ -1,5 +1,5 @@
// { dg-do compile }
-// { dg-options "-gdwarf-2 -dA -femit-struct-debug-detailed=any" }
+// { dg-options "-gdwarf -dA -femit-struct-debug-detailed=any" }
// { dg-final { scan-assembler "timespec.*DW_AT_name" } }
// { dg-final { scan-assembler "tv_sec.*DW_AT_name" } }
// { dg-final { scan-assembler "tv_nsec.*DW_AT_name" } }
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-baseonly.c b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-baseonly.c
index a32abb5a2e2..aefcb871509 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-baseonly.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-baseonly.c
@@ -1,5 +1,5 @@
// { dg-do compile }
-// { dg-options "-gdwarf-2 -dA -femit-struct-debug-baseonly" }
+// { dg-options "-gdwarf -dA -femit-struct-debug-baseonly" }
// { dg-final { scan-assembler "timespec.*DW_AT_name" } }
// { dg-final { scan-assembler-not "tv_sec.*DW_AT_name" } }
// { dg-final { scan-assembler-not "tv_nsec.*DW_AT_name" } }
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-none.c b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-none.c
index bd218f82615..193c05d6155 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-none.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-none.c
@@ -1,5 +1,5 @@
// { dg-do compile }
-// { dg-options "-gdwarf-2 -dA -femit-struct-debug-detailed=none" }
+// { dg-options "-gdwarf -dA -femit-struct-debug-detailed=none" }
// { dg-final { scan-assembler "timespec.*DW_AT_name" } }
// { dg-final { scan-assembler-not "tv_sec.*DW_AT_name" } }
// { dg-final { scan-assembler-not "tv_nsec.*DW_AT_name" } }
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-reduced.c b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-reduced.c
index ac599f43fbf..ebbfc36672b 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-reduced.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-reduced.c
@@ -1,5 +1,5 @@
// { dg-do compile }
-// { dg-options "-gdwarf-2 -dA -femit-struct-debug-reduced" }
+// { dg-options "-gdwarf -dA -femit-struct-debug-reduced" }
// { dg-final { scan-assembler "timespec.*DW_AT_name" } }
// { dg-final { scan-assembler "tv_sec.*DW_AT_name" } }
// { dg-final { scan-assembler "tv_nsec.*DW_AT_name" } }
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-sys.c b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-sys.c
index 3a5c0bf1463..ad0a44a95b3 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-sys.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/fesd-sys.c
@@ -1,5 +1,5 @@
// { dg-do compile }
-// { dg-options "-gdwarf-2 -dA -femit-struct-debug-detailed=sys" }
+// { dg-options "-gdwarf -dA -femit-struct-debug-detailed=sys" }
// { dg-final { scan-assembler "timespec.*DW_AT_name" } }
// { dg-final { scan-assembler "tv_sec.*DW_AT_name" } }
// { dg-final { scan-assembler "tv_nsec.*DW_AT_name" } }
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/global-used-types.c b/gcc/testsuite/gcc.dg/debug/dwarf2/global-used-types.c
index 54fa58ae3f2..431b429dea5 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/global-used-types.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/global-used-types.c
@@ -1,6 +1,6 @@
/*
Contributed by Dodji Seketeli <dodji@redhat.com>
- { dg-options "-g -dA -fno-merge-debug-strings" }
+ { dg-options "-gdwarf -dA -fno-merge-debug-strings" }
{ dg-do compile }
{ dg-final { scan-assembler-times "DIE \\(0x\[^\n\]*\\) DW_TAG_enumeration_type" 1 } }
{ dg-final { scan-assembler-times "DIE \\(0x\[^\n\]*\\) DW_TAG_enumerator" 2 } }
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline1.c
index 11c8fad7841..bd7f7b986b3 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/inline1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
void e(int);
__attribute__ ((always_inline)) inline int
t(int function_parameter)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
index 20edb588ea8..b1947699e70 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline2.c
@@ -14,7 +14,7 @@
properly nested DW_TAG_inlined_subroutine DIEs for third, second and first.
*/
-/* { dg-options "-O -g3 -dA" } */
+/* { dg-options "-O -g3 -gdwarf -dA" } */
/* { dg-do compile } */
/* There are 6 inlined subroutines:
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/inline3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/inline3.c
index d2d3e0fd8a8..baa2f66e8a1 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/inline3.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/inline3.c
@@ -1,7 +1,7 @@
/* Verify that only one DW_AT_const_value is emitted for baz,
not for baz abstract DIE and again inside of
DW_TAG_inlined_subroutine. */
-/* { dg-options "-O2 -g -dA -fmerge-all-constants" } */
+/* { dg-options "-O2 -gdwarf -dA -fmerge-all-constants" } */
/* { dg-do compile } */
/* { dg-final { scan-assembler-times " DW_AT_const_value" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/ipa-cp1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/ipa-cp1.c
index 7442dab19f9..395c5441859 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/ipa-cp1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/ipa-cp1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
void q(int p);
static void
t(int constant_propagated_par)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c
index 5476aac0afd..e818263a51d 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-1.c
@@ -1,7 +1,7 @@
/* PR debug/29609 */
/* Verify that breakpoint on the break is hit. */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
void abort (void);
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c
index 43bc54524a9..463d3cc588f 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr29609-2.c
@@ -1,7 +1,7 @@
/* PR debug/29609 */
/* Verify that breakpoint on both goto failure; stmts is hit. */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
extern void abort (void);
int x;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr31230.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr31230.c
index ce26ec639c3..36d55bf30fd 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr31230.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr31230.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-gdwarf-2 -dA --param ggc-min-expand=0 --param ggc-min-heapsize=0" } */
+/* { dg-options "-gdwarf -dA --param ggc-min-expand=0 --param ggc-min-heapsize=0" } */
/* { dg-final { scan-assembler-times "DIE.*DW_TAG_array_type" 1 } } */
/* { dg-final { scan-assembler-times "DIE.*DW_TAG_subrange_type" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c
index de90acb81bf..d84ce26cae9 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-1.c
@@ -1,7 +1,7 @@
/* PR debug/36690 */
/* Verify that break func is hit. */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
int i;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c
index 2330f53858e..0927e7465b3 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-2.c
@@ -3,7 +3,7 @@
varz at that spot is defined and contains 5. Nowhere else
in the function should be varz in the scope. */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
int cnt;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c
index 234ad1263b2..bc492f2c14a 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr36690-3.c
@@ -1,6 +1,6 @@
/* PR debug/36690 */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
int cnt;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c
index badff447a8b..016dbc94806 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr37616.c
@@ -2,7 +2,7 @@
/* Test that one can put breakpoints onto continue, exitlab and break
and actually see program reaching those breakpoints. */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
extern void abort (void);
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr37726.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr37726.c
index 60fb8396169..622fbcf6401 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr37726.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr37726.c
@@ -1,6 +1,6 @@
/* PR debug/37726 */
/* { dg-do compile } */
-/* { dg-options "-g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf -O0 -dA -fno-merge-debug-strings" } */
int foo (int parm)
{
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-1.c
index 452c0f6808f..4e856ec0946 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-1.c
@@ -2,7 +2,7 @@
/* Test that token after multi-line function-like macro use
gets correct locus even when preprocessing separately. */
/* { dg-do compile } */
-/* { dg-options "-save-temps -g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-save-temps -gdwarf -O0 -dA -fno-merge-debug-strings" } */
#define A(a,b)
int varh;A(1,
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-2.c
index d2ee408ac9d..e416b0f90b4 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-2.c
@@ -1,6 +1,6 @@
/* PR preprocessor/41445 */
/* { dg-do compile } */
-/* { dg-options "-g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf -O0 -dA -fno-merge-debug-strings" } */
#include "pr41445-1.c"
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-3.c
index 2a74dc5e3d4..46f57e6708f 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-3.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-3.c
@@ -2,7 +2,7 @@
/* Test that token after multi-line function-like macro use
gets correct locus even when preprocessing separately. */
/* { dg-do compile } */
-/* { dg-options "-save-temps -g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-save-temps -gdwarf -O0 -dA -fno-merge-debug-strings" } */
#define A(a,b)
int varh;/*
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-4.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-4.c
index 8aa92de5dd4..409f79f8505 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-4.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-4.c
@@ -1,6 +1,6 @@
/* PR preprocessor/41445 */
/* { dg-do compile } */
-/* { dg-options "-g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf -O0 -dA -fno-merge-debug-strings" } */
#include "pr41445-3.c"
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
index d21acd5aba9..de5a1cc13dc 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-5.c
@@ -2,7 +2,7 @@
/* Test that token after multi-line function-like macro use
gets correct locus even when preprocessing separately. */
/* { dg-do compile } */
-/* { dg-options "-save-temps -g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-save-temps -gdwarf -O0 -dA -fno-merge-debug-strings" } */
#define A(x) vari x
#define vari(x)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
index d6d79ccc469..340cb383530 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41445-6.c
@@ -1,6 +1,6 @@
/* PR preprocessor/41445 */
/* { dg-do compile } */
-/* { dg-options "-g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf -O0 -dA -fno-merge-debug-strings" } */
#include "pr41445-5.c"
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41543.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41543.c
index 02683960bdb..872ed7da618 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41543.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41543.c
@@ -1,6 +1,6 @@
/* PR preprocessor/41543 */
/* { dg-do compile } */
-/* { dg-options "-save-temps -g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-save-temps -gdwarf -O0 -dA -fno-merge-debug-strings" } */
#include <stdarg.h>
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41695.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41695.c
index d61b5a293f5..90ae5cd888f 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr41695.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr41695.c
@@ -1,6 +1,6 @@
/* PR debug/41695 */
/* { dg-do compile } */
-/* { dg-options "-g -O2 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf -O2 -dA -fno-merge-debug-strings" } */
int bar (int);
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr43237.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr43237.c
index 21262c3b210..8db2543927e 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr43237.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr43237.c
@@ -1,6 +1,6 @@
/* PR debug/43237 */
/* { dg-do compile } */
-/* { dg-options "-g -O2 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf -O2 -dA -fno-merge-debug-strings" } */
struct S
{
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c
index 2e4c3cda86c..a859ac91a5d 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-save-temps -g -dA" } */
+/* { dg-options "-save-temps -gdwarf -dA" } */
typedef struct _Harry { int dummy; } Harry_t;
Harry_t harry;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c
index 13856d7aa0d..dfbfa2fed1d 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-2.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-save-temps -g -dA" } */
+/* { dg-options "-save-temps -gdwarf -dA" } */
typedef const struct _Harry { int dummy; } Harry_t;
Harry_t harry;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c
index f1e463e45dc..c8039ef6d41 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-3.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-save-temps -g -dA" } */
+/* { dg-options "-save-temps -gdwarf -dA" } */
typedef struct _Harry { int dummy; } Harry_t;
const Harry_t harry[5];
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c
index cf0a2af6ced..bd2351bd907 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr47939-4.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-save-temps -g -dA" } */
+/* { dg-options "-save-temps -gdwarf -dA" } */
typedef const struct _Harry { int dummy; } Harry_t;
Harry_t harry[10];
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr51410.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr51410.c
index 957c152b4a0..62b389ee935 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr51410.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr51410.c
@@ -1,6 +1,6 @@
/* PR debug/51410 */
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-O0 -gdwarf -dA -fno-merge-debug-strings" } */
int x;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/pr53948.c b/gcc/testsuite/gcc.dg/debug/dwarf2/pr53948.c
index d2d44ea77b7..0ec3e84d704 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/pr53948.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/pr53948.c
@@ -1,6 +1,6 @@
/* Test that we have line information for the line
with local variable initializations. */
-/* { dg-options "-O0 -g -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
/* { dg-final { scan-assembler ".loc 1 8 0|\[#/!\]\[ \t\]+line 8" } } */
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c b/gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c
index 7e745ff19d2..4fa199c0c18 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/short-circuit.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O0 -gdwarf-2 -dA" } */
+/* { dg-options "-O0 -gdwarf -dA" } */
#define True 1
#define False 0
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/static1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/static1.c
index b9b5d0b3743..bdc118ddcec 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/static1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/static1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -gdwarf-2" } */
+/* { dg-options "-O2 -gdwarf" } */
void
main(void)
{
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/struct-loc1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/struct-loc1.c
index 216a498e1ab..bf893ee8654 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/struct-loc1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/struct-loc1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-g -O0 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf -O0 -dA -fno-merge-debug-strings" } */
struct foo;
struct foo *obj;
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/var1.c b/gcc/testsuite/gcc.dg/debug/dwarf2/var1.c
index 04dd1297694..297d244e2cc 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/var1.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/var1.c
@@ -1,6 +1,6 @@
/* PR 23190 */
/* { dg-do compile }
-/* { dg-options "-gdwarf-2 -dA -fno-merge-debug-strings" } */
+/* { dg-options "-gdwarf -dA -fno-merge-debug-strings" } */
/* { dg-final { scan-assembler "xyzzy\[^\\n\\r\]+DW_AT_name" } } */
void f(void)
diff --git a/gcc/testsuite/gcc.dg/debug/dwarf2/var2.c b/gcc/testsuite/gcc.dg/debug/dwarf2/var2.c
index 8ef2a74388c..72aef418098 100644
--- a/gcc/testsuite/gcc.dg/debug/dwarf2/var2.c
+++ b/gcc/testsuite/gcc.dg/debug/dwarf2/var2.c
@@ -1,6 +1,6 @@
/* PR 23190 */
/* { dg-do compile }
-/* { dg-options "-O2 -gdwarf-2 -dA" } */
+/* { dg-options "-O2 -gdwarf -dA" } */
/* { dg-final { scan-assembler "DW_OP_addr\[\\n\\r\]+\[^\\n\\r\]+foo" } } */
/* { dg-final { scan-assembler "DW_OP_addr\[\\n\\r\]+\[^\\n\\r\]+bar" } } */
diff --git a/gcc/testsuite/gcc.dg/fork-instrumentation.c b/gcc/testsuite/gcc.dg/fork-instrumentation.c
new file mode 100644
index 00000000000..bd9bf41cd2f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/fork-instrumentation.c
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-O0 -fprofile-generate" } */
+int fork(void);
+t()
+{
+ fork ();
+}
+/* { dg-final { scan-assembler "gcov_fork" } } */
diff --git a/gcc/testsuite/gcc.dg/guality/param-1.c b/gcc/testsuite/gcc.dg/guality/param-1.c
new file mode 100644
index 00000000000..480ad3c13b6
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/param-1.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-g" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" } } */
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+__attribute__((noinline, noclone)) int
+sub (int a, int b)
+{
+ return a - b;
+}
+
+typedef struct { uintptr_t pa; uintptr_t pb; } fatp_t
+ __attribute__ ((aligned (2 * __alignof__ (uintptr_t))));
+
+__attribute__((noinline, noclone)) void
+foo (fatp_t str, int a, int b)
+{
+ int i = sub (a, b);
+ if (i == 0) /* BREAK */
+ i = sub (b, a);
+}
+
+int
+main (void)
+{
+ fatp_t ptr = { 31415927, 27182818 };
+ foo (ptr, 1, 2);
+ return 0;
+}
+
+/* { dg-final { gdb-test 20 "str.pa" "31415927" } } */
+/* { dg-final { gdb-test 20 "str.pb" "27182818" } } */
diff --git a/gcc/testsuite/gcc.dg/guality/param-2.c b/gcc/testsuite/gcc.dg/guality/param-2.c
new file mode 100644
index 00000000000..64678bd5699
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/guality/param-2.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+/* { dg-options "-g -fno-var-tracking-assignments" } */
+/* { dg-skip-if "" { *-*-* } { "*" } { "-O0" "-O1" } } */
+
+typedef __UINTPTR_TYPE__ uintptr_t;
+
+__attribute__((noinline, noclone)) int
+sub (int a, int b)
+{
+ return a - b;
+}
+
+typedef struct { uintptr_t pa; uintptr_t pb; } fatp_t
+ __attribute__ ((aligned (2 * __alignof__ (uintptr_t))));
+
+__attribute__((noinline, noclone)) void
+foo (fatp_t str, int a, int b)
+{
+ int i = sub (a, b);
+ if (i == 0) /* BREAK */
+ foo (str, a - 1, b);
+}
+
+int
+main (void)
+{
+ fatp_t ptr = { 31415927, 27182818 };
+ foo (ptr, 1, 2);
+ return 0;
+}
+
+/* { dg-final { gdb-test 20 "str.pa" "31415927" } } */
+/* { dg-final { gdb-test 20 "str.pb" "27182818" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-1.c b/gcc/testsuite/gcc.dg/ipa/ipa-1.c
index 3517b035f1c..3cc32da1c98 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-1.c
@@ -25,7 +25,7 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-2.c b/gcc/testsuite/gcc.dg/ipa/ipa-2.c
index 122a4a0181a..7f14d42a03a 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-2.c
@@ -23,5 +23,5 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-3.c b/gcc/testsuite/gcc.dg/ipa/ipa-3.c
index e15f084b400..36fd5067892 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-3.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-3.c
@@ -29,8 +29,8 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { scan-ipa-dump "Creating a specialized node of g" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param b with const 7" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param c with const 3" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 b with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .1 c with const 3" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-4.c b/gcc/testsuite/gcc.dg/ipa/ipa-4.c
index 88716dd8f4c..566b3297136 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-4.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-4.c
@@ -26,5 +26,5 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
-/* { dg-final { scan-ipa-dump-times "replacing param a with const 7" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "replacing param .0 a with const 7" 1 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-5.c b/gcc/testsuite/gcc.dg/ipa/ipa-5.c
index d599d3187fe..daa64fada6f 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-5.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-5.c
@@ -28,6 +28,6 @@ int main ()
}
/* { dg-final { scan-ipa-dump-times "Creating a specialized node" 3 "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param c with const 3" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .1 c with const 3" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-7.c b/gcc/testsuite/gcc.dg/ipa/ipa-7.c
index c8b510046a1..271a34a3d60 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-7.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-7.c
@@ -27,7 +27,7 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
-/* { dg-final { scan-ipa-dump-times "replacing param . with const 7" 1 "cp" } } */
+/* { dg-final { scan-ipa-dump-times "replacing param .. . with const 7" 1 "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-8.c b/gcc/testsuite/gcc.dg/ipa/ipa-8.c
index dcbed13a0ed..d138cf26330 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-8.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-8.c
@@ -23,9 +23,9 @@ int main ()
/* { dg-final { scan-ipa-dump "Creating a specialized node of f" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { scan-ipa-dump "Creating a specialized node of g" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param b with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 b with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
index e8abc3244a0..ed59cbfda00 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipa-pta-14.c
@@ -22,7 +22,8 @@ int main()
a.p = (void *)&c;
p = foo(&a, &a);
/* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* c\[^ \]* }" "pta" { xfail *-*-* } } } */
- /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* a\[^ \]* c\[^ \]* }" "pta" } } */
+ /* { dg-final { scan-ipa-dump "foo.result = { NULL a\[^ \]* a\[^ \]* c\[^ \]* }" "pta" { target { ! keeps_null_pointer_checks } } } } */
+ /* { dg-final { scan-ipa-dump "foo.result = { NONLOCAL a\[^ \]* a\[^ \]* c\[^ \]* }" "pta" { target { keeps_null_pointer_checks } } } } */
((struct X *)p)->p = (void *)0;
if (a.p != (void *)0)
abort ();
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-1.c b/gcc/testsuite/gcc.dg/ipa/ipcp-1.c
index 0f50ff9276a..a2ffd420203 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipcp-1.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-1.c
@@ -46,7 +46,7 @@ main (int argc, char *argv[])
/* { dg-final { scan-ipa-dump "Creating a specialized node of f.*for all known contexts" "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param a with const 7" "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 a with const 7" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-2.c b/gcc/testsuite/gcc.dg/ipa/ipcp-2.c
index c6dcdf0af52..62f564f216a 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipcp-2.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-2.c
@@ -94,6 +94,6 @@ top2 (int q)
}
/* { dg-final { scan-ipa-dump-times "Creating a specialized node of foo" 1 "cp" } } */
-/* { dg-final { scan-ipa-dump-times "replacing param p with const 0" 3 "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param s with const 4" "cp" } } */
+/* { dg-final { scan-ipa-dump-times "replacing param .. p with const 0" 3 "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 s with const 4" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/ipcp-4.c b/gcc/testsuite/gcc.dg/ipa/ipcp-4.c
index 59018ca6b1e..462cade498e 100644
--- a/gcc/testsuite/gcc.dg/ipa/ipcp-4.c
+++ b/gcc/testsuite/gcc.dg/ipa/ipcp-4.c
@@ -61,8 +61,8 @@ main (int argc, char *argv[])
/* { dg-final { scan-ipa-dump "Creating a specialized node of g1.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump "Creating a specialized node of g2.*for all known contexts" "cp" } } */
/* { dg-final { scan-ipa-dump-not "Creating a specialized node of h.*for all known contexts" "cp" } } */
-/* { dg-final { scan-ipa-dump-times "replacing param a with const 7" 2 "cp" } } */
-/* { dg-final { scan-ipa-dump "replacing param a with const 11" "cp" } } */
+/* { dg-final { scan-ipa-dump-times "replacing param .0 a with const 7" 2 "cp" } } */
+/* { dg-final { scan-ipa-dump "replacing param .0 a with const 11" "cp" } } */
/* { dg-final { cleanup-ipa-dump "cp" } } */
diff --git a/gcc/testsuite/gcc.dg/ipa/pr57539.c b/gcc/testsuite/gcc.dg/ipa/pr57539.c
new file mode 100644
index 00000000000..e02018eb872
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr57539.c
@@ -0,0 +1,218 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef long unsigned int size_t;
+typedef struct
+{
+}
+box;
+typedef struct
+{
+}
+textpara_t;
+typedef struct _dtlink_s Dtlink_t;
+typedef struct _dtdisc_s Dtdisc_t;
+typedef struct _dtmethod_s Dtmethod_t;
+typedef struct _dt_s Dt_t;
+typedef void *(*Dtmemory_f) (Dt_t *, void *, size_t, Dtdisc_t *);
+typedef void *(*Dtsearch_f) (Dt_t *, void *, int);
+typedef void *(*Dtmake_f) (Dt_t *, void *, Dtdisc_t *);
+typedef void (*Dtfree_f) (Dt_t *, void *, Dtdisc_t *);
+typedef int (*Dtcompar_f) (Dt_t *, void *, void *, Dtdisc_t *);
+typedef unsigned int (*Dthash_f) (Dt_t *, void *, Dtdisc_t *);
+typedef int (*Dtevent_f) (Dt_t *, int, void *, Dtdisc_t *);
+struct _dtlink_s
+{
+ Dtlink_t *right;
+};
+struct _dtdisc_s
+{
+ int key;
+ int size;
+ int link;
+ Dtmake_f makef;
+ Dtfree_f freef;
+ Dtcompar_f comparf;
+ Dthash_f hashf;
+ Dtmemory_f memoryf;
+ Dtevent_f eventf;
+};
+struct _dt_s
+{
+ Dtsearch_f searchf;
+};
+extern Dtmethod_t *Dtobag;
+extern Dt_t *dtopen (Dtdisc_t *, Dtmethod_t *);
+extern Dtlink_t *dtflatten (Dt_t *);
+typedef struct Agobj_s Agobj_t;
+typedef struct Agraph_s Agraph_t;
+typedef struct Agnode_s Agnode_t;
+typedef struct Agedge_s Agedge_t;
+typedef struct Agdesc_s Agdesc_t;
+typedef struct Agdisc_s Agdisc_t;
+typedef struct Agrec_s Agrec_t;
+struct Agobj_s
+{
+ Agrec_t *data;
+};
+struct Agdesc_s
+{
+};
+extern Agraph_t *agopen (char *name, Agdesc_t desc, Agdisc_t * disc);
+extern Agnode_t *agfstnode (Agraph_t * g);
+extern Agnode_t *agnxtnode (Agraph_t * g, Agnode_t * n);
+extern Agedge_t *agedge (Agraph_t * g, Agnode_t * t, Agnode_t * h, char *name,
+ int createflag);
+extern Agedge_t *agfstout (Agraph_t * g, Agnode_t * n);
+extern Agedge_t *agnxtout (Agraph_t * g, Agedge_t * e);
+extern Agdesc_t Agdirected, Agstrictdirected, Agundirected,
+ Agstrictundirected;
+typedef struct Agraph_s graph_t;
+typedef struct Agnode_s node_t;
+typedef struct Agedge_s edge_t;
+typedef union inside_t
+{
+ unsigned short minlen;
+}
+Agedgeinfo_t;
+extern void *gmalloc (size_t);
+typedef enum
+{ AM_NONE, AM_VOR, AM_SCALE, AM_NSCALE, AM_SCALEXY, AM_PUSH, AM_PUSHPULL,
+ AM_ORTHO, AM_ORTHO_YX, AM_ORTHOXY, AM_ORTHOYX, AM_PORTHO, AM_PORTHO_YX,
+ AM_PORTHOXY, AM_PORTHOYX, AM_COMPRESS, AM_VPSC, AM_IPSEP, AM_PRISM }
+adjust_mode;
+typedef struct nitem
+{
+ Dtlink_t link;
+ int val;
+ node_t *cnode;
+ box bb;
+}
+nitem;
+typedef int (*distfn) (box *, box *);
+typedef int (*intersectfn) (nitem *, nitem *);
+static int
+cmpitem (Dt_t * d, int *p1, int *p2, Dtdisc_t * disc)
+{
+}
+static Dtdisc_t constr =
+ { __builtin_offsetof (nitem, val), sizeof (int), __builtin_offsetof (nitem,
+ link),
+((Dtmake_f) 0), ((Dtfree_f) 0), (Dtcompar_f) cmpitem, ((Dthash_f) 0), ((Dtmemory_f) 0),
+((Dtevent_f) 0) };
+static int
+distX (box * b1, box * b2)
+{
+}
+
+static int
+intersectY0 (nitem * p, nitem * q)
+{
+}
+
+static int
+intersectY (nitem * p, nitem * q)
+{
+}
+
+static void
+mapGraphs (graph_t * g, graph_t * cg, distfn dist)
+{
+ node_t *n;
+ edge_t *e;
+ edge_t *ce;
+ node_t *t;
+ node_t *h;
+ nitem *tp;
+ nitem *hp;
+ int delta;
+ for (n = agfstnode (g); n; n = agnxtnode (g, n))
+ {
+ for (e = agfstout (g, n); e; e = agnxtout (g, e))
+ {
+ delta = dist (&tp->bb, &hp->bb);
+ ce = agedge (cg, t, h, ((void *) 0), 1);
+ if ((((Agedgeinfo_t *) (((Agobj_t *) (ce))->data))->minlen) < delta)
+ {
+ if ((((Agedgeinfo_t *) (((Agobj_t *) (ce))->data))->minlen) ==
+ 0.0)
+ {
+ }
+ }
+ }
+ }
+}
+
+static graph_t *
+mkNConstraintG (graph_t * g, Dt_t * list, intersectfn intersect, distfn dist)
+{
+ nitem *p;
+ nitem *nxp;
+ edge_t *e;
+ graph_t *cg = agopen ("cg", Agstrictdirected, ((Agdisc_t *) 0));
+ for (p = (nitem *) dtflatten (list); p;
+ p = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right))
+ {
+ for (nxp = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right); nxp;
+ nxp = (nitem *) (((Dtlink_t *) ((Dtlink_t *) nxp))->right))
+ {
+ if (intersect (p, nxp))
+ {
+ e = agedge (cg, p->cnode, nxp->cnode, ((void *) 0), 1);
+ }
+ }} for (p = (nitem *) dtflatten (list); p;
+ p = (nitem *) (((Dtlink_t *) ((Dtlink_t *) p))->right))
+ {
+ }
+}
+
+static graph_t *
+mkConstraintG (graph_t * g, Dt_t * list, intersectfn intersect, distfn dist)
+{
+ graph_t *vg;
+ graph_t *cg = agopen ("cg", Agstrictdirected, ((Agdisc_t *) 0));
+ mapGraphs (vg, cg, dist);
+}
+
+static void
+constrainX (graph_t * g, nitem * nlist, int nnodes, intersectfn ifn,
+ int ortho)
+{
+ Dt_t *list = dtopen (&constr, Dtobag);
+ nitem *p = nlist;
+ graph_t *cg;
+ int i;
+ for (i = 0; i < nnodes; i++)
+ {
+ (*(((Dt_t *) (list))->searchf)) ((list), (void *) (p), 0000001);
+ p++;
+ } if (ortho)
+ cg = mkConstraintG (g, list, ifn, distX);
+ else
+ cg = mkNConstraintG (g, list, ifn, distX);
+}
+
+int
+cAdjust (graph_t * g, int mode)
+{
+ int ret, i, nnodes = agnnodes (g);
+ nitem *nlist = (nitem *) gmalloc ((nnodes) * sizeof (nitem));
+ node_t *n;
+ for (n = agfstnode (g); n; n = agnxtnode (g, n))
+ {
+ }
+ if (overlaps (nlist, nnodes))
+ {
+ switch ((adjust_mode) mode)
+ {
+ case AM_ORTHOXY:
+ constrainX (g, nlist, nnodes, intersectY, 1);
+ case AM_ORTHO:
+ constrainX (g, nlist, nnodes, intersectY0, 1);
+ constrainX (g, nlist, nnodes, intersectY, 1);
+ case AM_PORTHO:
+ default:
+ constrainX (g, nlist, nnodes, intersectY0, 0);
+ }
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/ipa/pr58106.c b/gcc/testsuite/gcc.dg/ipa/pr58106.c
new file mode 100644
index 00000000000..b83353c4e9a
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ipa/pr58106.c
@@ -0,0 +1,50 @@
+/* PR 58106 testcase. Verify that rdesc chain creating and lookup works with
+ recursive inlining and master clone creation. */
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+typedef struct rtx_def *rtx;
+enum rtx_code {
+ LAST_AND_UNUSED_RTX_CODE};
+extern const char * const rtx_format[((int) LAST_AND_UNUSED_RTX_CODE)];
+struct rtx_def {
+ enum rtx_code code;
+};
+typedef int (*rtx_function) (rtx *, void *);
+extern int for_each_rtx (rtx *, rtx_function, void *);
+int
+replace_label (rtx *x, void *data)
+{
+ rtx l = *x;
+ if (l == (rtx) 0)
+ {
+ {
+ rtx new_c, new_l;
+ for_each_rtx (&new_c, replace_label, data);
+ }
+ }
+}
+static int
+for_each_rtx_1 (rtx exp, int n, rtx_function f, void *data)
+{
+ int result, i, j;
+ const char *format = (rtx_format[(int) (((enum rtx_code) (exp)->code))]);
+ rtx *x;
+ for (; format[n] != '\0'; n++)
+ {
+ switch (format[n])
+ {
+ case 'e':
+ result = (*f) (x, data);
+ {
+ result = for_each_rtx_1 (*x, i, f, data);
+ }
+ }
+ }
+}
+int
+for_each_rtx (rtx *x, rtx_function f, void *data)
+{
+ int i;
+ return for_each_rtx_1 (*x, i, f, data);
+}
diff --git a/gcc/testsuite/gcc.dg/lower-subreg-1.c b/gcc/testsuite/gcc.dg/lower-subreg-1.c
index f5827e1db1f..102ba22b431 100644
--- a/gcc/testsuite/gcc.dg/lower-subreg-1.c
+++ b/gcc/testsuite/gcc.dg/lower-subreg-1.c
@@ -1,4 +1,4 @@
-/* { dg-do compile { target { ! { mips64 || { arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */
+/* { dg-do compile { target { ! { mips64 || { aarch64*-*-* arm*-*-* ia64-*-* sparc*-*-* spu-*-* tilegx-*-* } } } } } */
/* { dg-options "-O -fdump-rtl-subreg1" } */
/* { dg-skip-if "" { { i?86-*-* x86_64-*-* } && x32 } { "*" } { "" } } */
/* { dg-require-effective-target ilp32 } */
diff --git a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
index 45e6257c070..c4dace5ab27 100644
--- a/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
+++ b/gcc/testsuite/gcc.dg/plugin/one_time_plugin.c
@@ -8,18 +8,52 @@
#include "gimple.h"
#include "tree-pass.h"
#include "intl.h"
+#include "context.h"
int plugin_is_GPL_compatible;
-static bool one_pass_gate (void)
+namespace {
+
+const pass_data pass_data_one_pass =
+{
+ GIMPLE_PASS, /* type */
+ "cfg", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
+};
+
+class one_pass : public gimple_opt_pass
+{
+public:
+ one_pass(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_one_pass, ctxt),
+ counter(0)
+ {}
+
+ /* opt_pass methods: */
+ bool gate ();
+ unsigned int execute ();
+
+private:
+ int counter;
+}; // class one_pass
+
+} // anon namespace
+
+bool one_pass::gate (void)
{
return true;
}
-static unsigned int one_pass_exec (void)
+unsigned int one_pass::execute ()
{
- static int counter = 0;
-
if (counter > 0) {
printf ("Executed more than once \n");
}
@@ -27,25 +61,11 @@ static unsigned int one_pass_exec (void)
return 0;
}
-struct gimple_opt_pass one_pass =
+gimple_opt_pass *
+make_one_pass (gcc::context *ctxt)
{
- {
- GIMPLE_PASS,
- "cfg", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- one_pass_gate, /* gate */
- one_pass_exec, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_gimple_any, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
-};
+ return new one_pass (ctxt);
+}
int plugin_init (struct plugin_name_args *plugin_info,
@@ -53,7 +73,7 @@ int plugin_init (struct plugin_name_args *plugin_info,
{
struct register_pass_info p;
- p.pass = &one_pass.pass;
+ p.pass = make_one_pass (g);
p.reference_pass_name = "cfg";
p.ref_pass_instance_number = 1;
p.pos_op = PASS_POS_INSERT_AFTER;
diff --git a/gcc/testsuite/gcc.dg/plugin/selfassign.c b/gcc/testsuite/gcc.dg/plugin/selfassign.c
index 37a0a979cb7..7235089c7d3 100644
--- a/gcc/testsuite/gcc.dg/plugin/selfassign.c
+++ b/gcc/testsuite/gcc.dg/plugin/selfassign.c
@@ -15,6 +15,7 @@
#include "intl.h"
#include "plugin-version.h"
#include "diagnostic.h"
+#include "context.h"
int plugin_is_GPL_compatible;
@@ -263,26 +264,44 @@ gate_warn_self_assign (void)
return true;
}
-static struct gimple_opt_pass pass_warn_self_assign =
+namespace {
+
+const pass_data pass_data_warn_self_assign =
{
- {
- GIMPLE_PASS,
- "warn_self_assign", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_warn_self_assign, /* gate */
- execute_warn_self_assign, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "warn_self_assign", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_warn_self_assign : public gimple_opt_pass
+{
+public:
+ pass_warn_self_assign(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_warn_self_assign, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_warn_self_assign (); }
+ unsigned int execute () { return execute_warn_self_assign (); }
+
+}; // class pass_warn_self_assign
+
+} // anon namespace
+
+static gimple_opt_pass *
+make_pass_warn_self_assign (gcc::context *ctxt)
+{
+ return new pass_warn_self_assign (ctxt);
+}
+
/* The initialization routine exposed to and called by GCC. The spec of this
function is defined in gcc/gcc-plugin.h.
@@ -309,7 +328,7 @@ plugin_init (struct plugin_name_args *plugin_info,
return 1;
/* Self-assign detection should happen after SSA is constructed. */
- pass_info.pass = &pass_warn_self_assign.pass;
+ pass_info.pass = make_pass_warn_self_assign (g);
pass_info.reference_pass_name = "ssa";
pass_info.ref_pass_instance_number = 1;
pass_info.pos_op = PASS_POS_INSERT_AFTER;
diff --git a/gcc/testsuite/gcc.dg/pr26570.c b/gcc/testsuite/gcc.dg/pr26570.c
index 5768d32cc12..71c16f20744 100644
--- a/gcc/testsuite/gcc.dg/pr26570.c
+++ b/gcc/testsuite/gcc.dg/pr26570.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fprofile-generate -fprofile-use" } */
+/* { dg-options "-O2 -fprofile-generate -fprofile-use -fopt-info" } */
unsigned test (unsigned a, unsigned b)
{
diff --git a/gcc/testsuite/gcc.dg/pr32773.c b/gcc/testsuite/gcc.dg/pr32773.c
index e9cdd4c377e..19a90195ad3 100644
--- a/gcc/testsuite/gcc.dg/pr32773.c
+++ b/gcc/testsuite/gcc.dg/pr32773.c
@@ -1,6 +1,6 @@
/* { dg-do compile } */
-/* { dg-options "-O -fprofile-use" } */
-/* { dg-options "-O -m4 -fprofile-use" { target sh-*-* } } */
+/* { dg-options "-O -fprofile-use -fopt-info" } */
+/* { dg-options "-O -m4 -fprofile-use -fopt-info" { target sh-*-* } } */
void foo (int *p)
{
diff --git a/gcc/testsuite/gcc.dg/pr40209.c b/gcc/testsuite/gcc.dg/pr40209.c
index f367f7c2472..afe131fc5eb 100644
--- a/gcc/testsuite/gcc.dg/pr40209.c
+++ b/gcc/testsuite/gcc.dg/pr40209.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fprofile-use" } */
+/* { dg-options "-O2 -fprofile-use -fopt-info" } */
void process(const char *s);
diff --git a/gcc/testsuite/gcc.dg/pr44214-1.c b/gcc/testsuite/gcc.dg/pr44214-1.c
index 292ce57c30e..28194e48fc4 100644
--- a/gcc/testsuite/gcc.dg/pr44214-1.c
+++ b/gcc/testsuite/gcc.dg/pr44214-1.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -freciprocal-math -fdump-tree-ccp1" } */
-typedef double v2df __attribute__ ((vector_size (16)));
+typedef double v2df __attribute__ ((vector_size (2 * sizeof (double))));
void do_div (v2df *a, v2df *b)
{
diff --git a/gcc/testsuite/gcc.dg/pr44214-3.c b/gcc/testsuite/gcc.dg/pr44214-3.c
index 46d5ee8c78e..a0eb35b1ca6 100644
--- a/gcc/testsuite/gcc.dg/pr44214-3.c
+++ b/gcc/testsuite/gcc.dg/pr44214-3.c
@@ -1,7 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-ccp1" } */
-typedef double v2df __attribute__ ((vector_size (16)));
+typedef double v2df __attribute__ ((vector_size (2 * sizeof (double))));
void do_div (v2df *a, v2df *b)
{
diff --git a/gcc/testsuite/gcc.dg/pr46647.c b/gcc/testsuite/gcc.dg/pr46647.c
index 961bd327d1d..4510d695b1f 100644
--- a/gcc/testsuite/gcc.dg/pr46647.c
+++ b/gcc/testsuite/gcc.dg/pr46647.c
@@ -25,6 +25,6 @@ func3 (void)
return 0;
}
-/* The xfail for cris-* and crisv32-* is due to PR53535. */
-/* { dg-final { scan-tree-dump-not "memset" "optimized" { xfail cris-*-* crisv32-*-* } } } */
+/* The xfail for avr, cris-* and crisv32-* is due to PR53535. */
+/* { dg-final { scan-tree-dump-not "memset" "optimized" { xfail avr-*-* cris-*-* crisv32-*-* } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr57287-2.c b/gcc/testsuite/gcc.dg/pr57287-2.c
new file mode 100644
index 00000000000..1ddf76c6461
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr57287-2.c
@@ -0,0 +1,35 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -Wall" } */
+
+#include <setjmp.h>
+
+struct node
+{
+ struct node *next;
+ char *name;
+} *list;
+
+struct node *list;
+struct node *head (void);
+
+jmp_buf *bar (void);
+
+int baz (void)
+{
+ struct node *n;
+ int varseen = 0;
+
+ list = head ();
+ for (n = list; n; n = n->next)
+ {
+ if (!varseen)
+ varseen = 1;
+
+ jmp_buf *buf = bar (); /* { dg-bogus "may be used uninitialized" "" } */
+ setjmp (*buf);
+ }
+
+ if (!varseen)
+ return 0;
+ return 1;
+}
diff --git a/gcc/testsuite/gcc.dg/pr57662.c b/gcc/testsuite/gcc.dg/pr57662.c
new file mode 100644
index 00000000000..7af845532b8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr57662.c
@@ -0,0 +1,47 @@
+/* { dg-do compile { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+/* { dg-options " -O -fno-guess-branch-probability -fpeel-loops -freorder-blocks-and-partition -fschedule-insns2 -fsel-sched-pipelining -fselective-scheduling2 -ftree-pre" } */
+
+struct intC
+{
+ short x;
+ short y;
+};
+
+void Get(void);
+
+int size_x;
+
+struct
+{
+ int *depot_table;
+ struct intC *ti;
+ int size;
+} dummy;
+
+static inline int
+GetRotatedTileFromOffset (int *a, struct intC tidc)
+{
+ if (!*a)
+ Get ();
+ switch (*a)
+ {
+ case 0:
+ return (tidc.y << size_x) + tidc.x;
+ case 1:
+ return tidc.y + (dummy.size - tidc.x) * size_x;
+ case 2:
+ return tidc.x + (dummy.size - tidc.y) * size_x;
+ case 3:
+ return (dummy.size - tidc.x);
+ }
+ return 0;
+}
+
+int
+GetHangarNum (int *a, int i)
+{
+ while (dummy.size)
+ if (GetRotatedTileFromOffset (a, dummy.ti[i]))
+ return *dummy.depot_table;
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr57980.c b/gcc/testsuite/gcc.dg/pr57980.c
new file mode 100644
index 00000000000..be83536c5f7
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr57980.c
@@ -0,0 +1,19 @@
+/* PR tree-optimization/57980 */
+/* { dg-do compile } */
+/* { dg-options "-O -foptimize-sibling-calls -w" } */
+
+typedef int V __attribute__ ((vector_size (2 * sizeof (int))));
+extern V f (void);
+
+V
+bar (void)
+{
+ return -f ();
+}
+
+V
+foo (void)
+{
+ V v = { };
+ return v - f ();
+}
diff --git a/gcc/testsuite/gcc.dg/pr58010.c b/gcc/testsuite/gcc.dg/pr58010.c
new file mode 100644
index 00000000000..a0fbd31f495
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr58010.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -funswitch-loops -ftree-vectorize" } */
+
+short a, b, c, d;
+
+void f(void)
+{
+ short e;
+
+ for(; e; e++)
+ for(; b; b++);
+
+ for(d = 0; d < 4; d++)
+ a ^= (e ^= 1) || c ? : e;
+}
diff --git a/gcc/testsuite/gcc.dg/pr58145-1.c b/gcc/testsuite/gcc.dg/pr58145-1.c
new file mode 100644
index 00000000000..0e236c0456d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr58145-1.c
@@ -0,0 +1,37 @@
+/* PR tree-optimization/58145 */
+/* { dg-do compile { target { int32plus } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+struct S { unsigned int data : 32; };
+struct T { unsigned int data; };
+volatile struct S s2;
+
+void
+f1 (int val)
+{
+ struct S s = { .data = val };
+ *(volatile struct S *) 0x880000UL = s;
+}
+
+void
+f2 (int val)
+{
+ struct T t = { .data = val };
+ *(volatile struct T *) 0x880000UL = t;
+}
+
+void
+f3 (int val)
+{
+ *(volatile unsigned int *) 0x880000UL = val;
+}
+
+void
+f4 (int val)
+{
+ struct S s = { .data = val };
+ s2 = s;
+}
+
+/* { dg-final { scan-tree-dump-times " ={v} " 4 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/pr58145-2.c b/gcc/testsuite/gcc.dg/pr58145-2.c
new file mode 100644
index 00000000000..840e9828972
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr58145-2.c
@@ -0,0 +1,51 @@
+/* PR tree-optimization/58145 */
+/* { dg-do compile { target { int32plus } } } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+struct S { unsigned int data : 32; };
+struct T { unsigned int data; };
+volatile struct S s2;
+
+static inline void
+f1 (int val)
+{
+ struct S s = { .data = val };
+ *(volatile struct S *) 0x880000UL = s;
+}
+
+static inline void
+f2 (int val)
+{
+ struct T t = { .data = val };
+ *(volatile struct T *) 0x880000UL = t;
+}
+
+static inline void
+f3 (int val)
+{
+ *(volatile unsigned int *) 0x880000UL = val;
+}
+
+static inline void
+f4 (int val)
+{
+ struct S s = { .data = val };
+ s2 = s;
+}
+
+void
+f5 (void)
+{
+ int i;
+ for (i = 0; i < 100; i++)
+ f1 (0);
+ for (i = 0; i < 100; i++)
+ f2 (0);
+ for (i = 0; i < 100; i++)
+ f3 (0);
+ for (i = 0; i < 100; i++)
+ f4 (0);
+}
+
+/* { dg-final { scan-tree-dump-times " ={v} " 4 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/stack-usage-1.c b/gcc/testsuite/gcc.dg/stack-usage-1.c
index fa299c4385a..ff9709ad4a2 100644
--- a/gcc/testsuite/gcc.dg/stack-usage-1.c
+++ b/gcc/testsuite/gcc.dg/stack-usage-1.c
@@ -9,6 +9,8 @@
#if defined(__aarch64__)
# define SIZE 256 /* No frame pointer for leaf functions (default) */
+#elif defined(__arc__)
+# define SIZE (256-4)
#elif defined(__i386__)
# define SIZE 248
#elif defined(__x86_64__)
diff --git a/gcc/testsuite/gcc.dg/strlenopt-10.c b/gcc/testsuite/gcc.dg/strlenopt-10.c
index a18c06ae069..b044496352d 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-10.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-10.c
@@ -70,7 +70,10 @@ main ()
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 2 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen" } } */
+/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
+ to expand the memcpy call at the end of fn2. */
+/* { dg-final { scan-tree-dump-times "memcpy \\(" 8 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-11.c b/gcc/testsuite/gcc.dg/strlenopt-11.c
index 888eeb20cdc..0fb327ced02 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-11.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-11.c
@@ -59,12 +59,18 @@ main ()
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 3 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" } } */
+/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
+ to expand the memcpy call at the end of fn1. */
+/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
-/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" } } */
-/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" } } */
-/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen" } } */
+/* Where the memcpy is expanded, the assignemts to elements of l are
+ propagated. */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.9. = " 1 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 3 "strlen" { target { avr-*-* } } } } */
/* { dg-final { cleanup-tree-dump "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/strlenopt-13.c b/gcc/testsuite/gcc.dg/strlenopt-13.c
index 9413cb53e2f..f9ab561110d 100644
--- a/gcc/testsuite/gcc.dg/strlenopt-13.c
+++ b/gcc/testsuite/gcc.dg/strlenopt-13.c
@@ -56,13 +56,19 @@ main ()
}
/* { dg-final { scan-tree-dump-times "strlen \\(" 4 "strlen" } } */
-/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" } } */
+/* avr has BIGGEST_ALIGNMENT 8, allowing fold_builtin_memory_op
+ to expand the memcpy call at the end of fn1. */
+/* { dg-final { scan-tree-dump-times "memcpy \\(" 7 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times "memcpy \\(" 6 "strlen" { target { avr-*-* } } } } */
/* { dg-final { scan-tree-dump-times "strcpy \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strcat \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "strchr \\(" 0 "strlen" } } */
/* { dg-final { scan-tree-dump-times "stpcpy \\(" 0 "strlen" } } */
-/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" } } */
-/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen" } } */
-/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen" } } */
-/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" } } */
+/* Where the memcpy is expanded, the assignemts to elements of l are
+ propagated. */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.0. = " 1 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.1. = " 1 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.5. = " 1 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;\[\n\r\]* l.6. = " 1 "strlen" { target { ! avr-*-* } } } } */
+/* { dg-final { scan-tree-dump-times " _\[0-9\]* = strlen \\(\[^\n\r\]*;" 4 "strlen" { target { avr-*-* } } } } */
/* { dg-final { cleanup-tree-dump "strlen" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr37868.c b/gcc/testsuite/gcc.dg/torture/pr37868.c
index 2b245ebf49b..cc9c24f49bb 100644
--- a/gcc/testsuite/gcc.dg/torture/pr37868.c
+++ b/gcc/testsuite/gcc.dg/torture/pr37868.c
@@ -1,6 +1,6 @@
/* { dg-do run } */
/* { dg-options "-fno-strict-aliasing" } */
-/* { dg-skip-if "unaligned access" { epiphany-*-* sparc*-*-* sh*-*-* tic6x-*-* } "*" "" } */
+/* { dg-skip-if "unaligned access" { arc*-*-* epiphany-*-* sparc*-*-* sh*-*-* tic6x-*-* } "*" "" } */
extern void abort (void);
#if (__SIZEOF_INT__ <= 2)
diff --git a/gcc/testsuite/gcc.dg/torture/pr53922.c b/gcc/testsuite/gcc.dg/torture/pr53922.c
index e4136014326..d385587e391 100644
--- a/gcc/testsuite/gcc.dg/torture/pr53922.c
+++ b/gcc/testsuite/gcc.dg/torture/pr53922.c
@@ -1,6 +1,7 @@
/* { dg-do run } */
/* { dg-require-weak "" } */
/* { dg-skip-if "No undefined" { *-*-mingw* } { "*" } { "" } } */
+/* { dg-skip-if "No undefined weak" { *-*-aix* } { "*" } { "" } } */
/* { dg-skip-if "No undefined weak" { hppa*-*-hpux* && { ! lp64 } } { "*" } { "" } } */
/* { dg-options "-Wl,-undefined,dynamic_lookup" { target *-*-darwin* } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr57521.c b/gcc/testsuite/gcc.dg/torture/pr57521.c
new file mode 100644
index 00000000000..e7832cb00e8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57521.c
@@ -0,0 +1,51 @@
+/* { dg-do run } */
+/* { dg-options "-ftree-loop-if-convert" } */
+
+void abort (void);
+
+int a, b, c, d, o = 1, p;
+short e;
+
+int
+fn1 (int * p1)
+{
+ int f, g, h, j = 0, k = 0, l = 0;
+ unsigned int i;
+ int *m[1] = { &l };
+ for (; b >= 0; b--)
+ {
+ if (*p1)
+ if (j >= 0)
+ {
+ int n = 1;
+ e = 1;
+ h = a ? a : 1 % n;
+ g = h > 0 ? 0 : h + 1;
+ k = c + g;
+ }
+ else
+ continue;
+ else
+ {
+
+ f = d > 0 ? 0 : d + 1;
+ i = f;
+ j = 1 + i;
+ }
+ l++;
+ }
+ return k;
+}
+
+int
+main ()
+{
+ for (;; p++)
+ {
+ fn1 (&o);
+ break;
+ }
+ if (e != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57656.c b/gcc/testsuite/gcc.dg/torture/pr57656.c
new file mode 100644
index 00000000000..4f3645e4693
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57656.c
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-options "-fstrict-overflow" } */
+
+int main (void)
+{
+ int a = -1;
+ int b = __INT_MAX__;
+ int c = 2;
+ int t = 1 - ((a - b) / c); // t = 1 - ( __INT_MIN__ / 2 )
+ if (t != (1 - (-1 - __INT_MAX__) / 2))
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57685.c b/gcc/testsuite/gcc.dg/torture/pr57685.c
new file mode 100644
index 00000000000..75973f2a493
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57685.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+
+unsigned f(void)
+{
+ unsigned a;
+ int b, c, d, e;
+
+ for(c = 27; c < 40; c++)
+ b |= d |= b;
+
+ if(b)
+ a = e;
+
+ return a;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57993-2.cpp b/gcc/testsuite/gcc.dg/torture/pr57993-2.cpp
new file mode 100644
index 00000000000..d8fd371b096
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57993-2.cpp
@@ -0,0 +1,213 @@
+/* This ICEd due to an incomplete fix for PR57993. */
+/* { dg-compile } */
+
+extern "C"
+{
+ extern double sqrt (double __x) throw ();
+ typedef long unsigned int size_t;
+ typedef struct
+ {
+ }
+ __mbstate_t;
+ void *pov_malloc (size_t size, const char *file, int line, const char *msg);
+ typedef struct Object_Struct OBJECT;
+ typedef struct Ray_Struct RAY;
+ typedef struct istack_struct ISTACK;
+ typedef struct istk_entry INTERSECTION;
+ typedef double UV_VECT[2];
+ typedef double VECTOR[3];
+ typedef struct Transform_Struct TRANSFORM;
+ typedef struct Method_Struct METHODS;
+ typedef int (*ALL_INTERSECTIONS_METHOD) (OBJECT *, RAY *, ISTACK *);
+ typedef int (*INSIDE_METHOD) (VECTOR, OBJECT *);
+ typedef void (*NORMAL_METHOD) (VECTOR, OBJECT *, INTERSECTION *);
+ typedef void (*UVCOORD_METHOD) (UV_VECT, OBJECT *, INTERSECTION *);
+ typedef void *(*COPY_METHOD) (OBJECT *);
+ typedef void (*TRANSLATE_METHOD) (OBJECT *, VECTOR, TRANSFORM *);
+ typedef void (*ROTATE_METHOD) (OBJECT *, VECTOR, TRANSFORM *);
+ typedef void (*SCALE_METHOD) (OBJECT *, VECTOR, TRANSFORM *);
+ typedef void (*TRANSFORM_METHOD) (OBJECT *, TRANSFORM *);
+ typedef void (*INVERT_METHOD) (OBJECT *);
+ typedef void (*DESTROY_METHOD) (OBJECT *);
+ struct Method_Struct
+ {
+ ALL_INTERSECTIONS_METHOD All_Intersections_Method;
+ INSIDE_METHOD Inside_Method;
+ NORMAL_METHOD Normal_Method;
+ UVCOORD_METHOD UVCoord_Method;
+ COPY_METHOD Copy_Method;
+ TRANSLATE_METHOD Translate_Method;
+ ROTATE_METHOD Rotate_Method;
+ SCALE_METHOD Scale_Method;
+ TRANSFORM_METHOD Transform_Method;
+ INVERT_METHOD Invert_Method;
+ DESTROY_METHOD Destroy_Method;
+ };
+ typedef struct Bicubic_Patch_Struct BICUBIC_PATCH;
+ typedef struct Bezier_Node_Struct BEZIER_NODE;
+ struct Bezier_Node_Struct
+ {
+ int Node_Type;
+ int Count;
+ };
+ struct Bicubic_Patch_Struct
+ {
+ METHODS *Methods;
+ int Patch_Type, U_Steps, V_Steps;
+ VECTOR Control_Points[4][4];
+ BEZIER_NODE *Node_Tree;
+ };
+ typedef enum
+ {
+ CSV, SYS, PPM, TARGA, PNG, NONE
+ }
+ SHELLDATA;
+ typedef enum STATS
+ {
+ Number_Of_Pixels =
+ 0, Number_Of_Pixels_Supersampled, Number_Of_Samples, Number_Of_Rays,
+ Calls_To_DNoise, Calls_To_Noise, ADC_Saves, Istack_overflows,
+ Ray_RBezier_Tests, Ray_RBezier_Tests_Succeeded, Ray_Bicubic_Tests,
+ Ray_Bicubic_Tests_Succeeded, Ray_Blob_Tests, Ray_Blob_Tests_Succeeded,
+ Blob_Element_Tests, Blob_Element_Tests_Succeeded, Blob_Bound_Tests,
+ Blob_Bound_Tests_Succeeded, Ray_Box_Tests, Ray_Box_Tests_Succeeded,
+ Ray_Cone_Tests, Ray_Cone_Tests_Succeeded, Ray_CSG_Intersection_Tests,
+ Ray_CSG_Intersection_Tests_Succeeded, Ray_CSG_Merge_Tests,
+ Ray_CSG_Merge_Tests_Succeeded, Ray_CSG_Union_Tests,
+ Ray_CSG_Union_Tests_Succeeded, Ray_Disc_Tests, Ray_Disc_Tests_Succeeded,
+ Ray_Fractal_Tests, Ray_Fractal_Tests_Succeeded, Ray_HField_Tests,
+ Ray_HField_Tests_Succeeded, Ray_HField_Box_Tests,
+ Ray_HField_Box_Tests_Succeeded, Ray_HField_Triangle_Tests,
+ Ray_HField_Triangle_Tests_Succeeded, Ray_HField_Block_Tests,
+ Ray_HField_Block_Tests_Succeeded, Ray_HField_Cell_Tests,
+ Ray_HField_Cell_Tests_Succeeded, Ray_IsoSurface_Tests,
+ Ray_IsoSurface_Tests_Succeeded, Ray_IsoSurface_Bound_Tests,
+ Ray_IsoSurface_Bound_Tests_Succeeded, Ray_IsoSurface_Cache,
+ Ray_IsoSurface_Cache_Succeeded, Ray_Lathe_Tests,
+ Ray_Lathe_Tests_Succeeded, Lathe_Bound_Tests,
+ Lathe_Bound_Tests_Succeeded, Ray_Mesh_Tests, Ray_Mesh_Tests_Succeeded,
+ Ray_Plane_Tests, Ray_Plane_Tests_Succeeded, Ray_Polygon_Tests,
+ Ray_Polygon_Tests_Succeeded, Ray_Prism_Tests, Ray_Prism_Tests_Succeeded,
+ Prism_Bound_Tests, Prism_Bound_Tests_Succeeded, Ray_Parametric_Tests,
+ Ray_Parametric_Tests_Succeeded, Ray_Par_Bound_Tests,
+ Ray_Par_Bound_Tests_Succeeded, Ray_Quadric_Tests,
+ Ray_Quadric_Tests_Succeeded, Ray_Poly_Tests, Ray_Poly_Tests_Succeeded,
+ Ray_Sphere_Tests, Ray_Sphere_Tests_Succeeded, Ray_Sphere_Sweep_Tests,
+ Ray_Sphere_Sweep_Tests_Succeeded, Ray_Superellipsoid_Tests,
+ Ray_Superellipsoid_Tests_Succeeded, Ray_Sor_Tests,
+ Ray_Sor_Tests_Succeeded, Sor_Bound_Tests, Sor_Bound_Tests_Succeeded,
+ Ray_Torus_Tests, Ray_Torus_Tests_Succeeded, Torus_Bound_Tests,
+ Torus_Bound_Tests_Succeeded, Ray_Triangle_Tests,
+ Ray_Triangle_Tests_Succeeded, Ray_TTF_Tests, Ray_TTF_Tests_Succeeded,
+ Bounding_Region_Tests, Bounding_Region_Tests_Succeeded,
+ Clipping_Region_Tests, Clipping_Region_Tests_Succeeded,
+ Ray_IsoSurface_Find_Root, Ray_Function_VM_Calls,
+ Ray_Function_VM_Instruction_Est, VBuffer_Tests, VBuffer_Tests_Succeeded,
+ LBuffer_Tests, LBuffer_Tests_Succeeded, Media_Samples, Media_Intervals,
+ Reflected_Rays_Traced, Refracted_Rays_Traced, Transmitted_Rays_Traced,
+ Internal_Reflected_Rays_Traced, Shadow_Cache_Hits,
+ Shadow_Rays_Succeeded, Shadow_Ray_Tests, nChecked, nEnqueued,
+ totalQueues, totalQueueResets, totalQueueResizes, Polynomials_Tested,
+ Roots_Eliminated, MemStat_Smallest_Alloc, MemStat_Largest_Alloc,
+ MemStat_Largest_Mem_Usage, Number_Of_Photons_Shot,
+ Number_Of_Photons_Stored, Number_Of_Global_Photons_Stored,
+ Number_Of_Media_Photons_Stored, Priority_Queue_Add,
+ Priority_Queue_Remove, Gather_Performed_Count, Gather_Expanded_Count,
+ MaxStat
+ }
+ Stats;
+ static int All_Bicubic_Patch_Intersections (OBJECT * Object, RAY * Ray,
+ ISTACK * Depth_Stack);
+ static int Inside_Bicubic_Patch (VECTOR IPoint, OBJECT * Object);
+ static void Bicubic_Patch_Normal (VECTOR Result, OBJECT * Object,
+ INTERSECTION * Inter);
+ static void Bicubic_Patch_UVCoord (UV_VECT Result, OBJECT * Object,
+ INTERSECTION * Inter);
+ static BICUBIC_PATCH *Copy_Bicubic_Patch (OBJECT * Object);
+ static void Translate_Bicubic_Patch (OBJECT * Object, VECTOR Vector,
+ TRANSFORM * Trans);
+ static void Rotate_Bicubic_Patch (OBJECT * Object, VECTOR Vector,
+ TRANSFORM * Trans);
+ static void Scale_Bicubic_Patch (OBJECT * Object, VECTOR Vector,
+ TRANSFORM * Trans);
+ static void Transform_Bicubic_Patch (OBJECT * Object, TRANSFORM * Trans);
+ static void Invert_Bicubic_Patch (OBJECT * Object);
+ static void Destroy_Bicubic_Patch (OBJECT * Object);
+ static METHODS Bicubic_Patch_Methods = {
+ All_Bicubic_Patch_Intersections, Inside_Bicubic_Patch,
+ Bicubic_Patch_Normal, Bicubic_Patch_UVCoord,
+ (COPY_METHOD) Copy_Bicubic_Patch, Translate_Bicubic_Patch,
+ Rotate_Bicubic_Patch, Scale_Bicubic_Patch, Transform_Bicubic_Patch,
+ Invert_Bicubic_Patch, Destroy_Bicubic_Patch
+ };
+ static void bezier_value (VECTOR (*Control_Points)[4][4], double u0,
+ double v0, VECTOR P, VECTOR N)
+ {
+ int i, j;
+ double c, t, ut, vt;
+ double u[4], uu[4], v[4], vv[4];
+ double du[4], duu[4], dv[4], dvv[4];
+ for (i = 1; i < 4; i++)
+ {
+ vv[i] = vv[i - 1] * (1.0 - v0);
+ dvv[i] = -i * vv[i - 1];
+ }
+ for (i = 0; i < 4; i++)
+ {
+ for (j = 0; j < 4; j++)
+ {
+ t = c * ut * (dv[j] * vv[3 - j] + v[j] * dvv[3 - j]);
+ }
+ t = 1.0 / sqrt (t);
+ }
+ }
+ static int intersect_subpatch (BICUBIC_PATCH * Shape, RAY * ray,
+ VECTOR V1[3], double uu[3], double vv[3],
+ double *Depth, VECTOR P, VECTOR N, double *u,
+ double *v)
+ {
+ VECTOR Q, T1;
+ VECTOR B[3], IB[3], NN[3];
+ bezier_value ((VECTOR (*)[4][4]) & Shape->Control_Points, uu[1], vv[1],
+ T1, NN[1]);
+ }
+ static int bezier_tree_walker (RAY * Ray, BICUBIC_PATCH * Shape,
+ BEZIER_NODE * Node, ISTACK * Depth_Stack)
+ {
+ int i, cnt = 0;
+ double Depth, u, v;
+ double uu[3], vv[3];
+ VECTOR N, P;
+ VECTOR V1[3];
+ if (Node->Node_Type == 0)
+ {
+ for (i = 0; i < Node->Count; i++)
+ {
+ }
+ if (intersect_subpatch (Shape, Ray, V1, uu, vv, &Depth, P, N, &u, &v))
+ {
+ }
+ }
+ }
+ static int All_Bicubic_Patch_Intersections (OBJECT * Object, RAY * Ray,
+ ISTACK * Depth_Stack)
+ {
+ int Found, cnt = 0;
+ switch (((BICUBIC_PATCH *) Object)->Patch_Type)
+ {
+ case 1:
+ cnt =
+ bezier_tree_walker (Ray, (BICUBIC_PATCH *) Object,
+ ((BICUBIC_PATCH *) Object)->Node_Tree,
+ Depth_Stack);
+ }
+ }
+ BICUBIC_PATCH *Create_Bicubic_Patch ()
+ {
+ BICUBIC_PATCH *New;
+ New =
+ (BICUBIC_PATCH *) pov_malloc ((sizeof (BICUBIC_PATCH)), "bezier.cpp",
+ 2079, ("bicubic patch"));
+ New->Methods = &Bicubic_Patch_Methods;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr57993.c b/gcc/testsuite/gcc.dg/torture/pr57993.c
new file mode 100644
index 00000000000..e73b73f4fa3
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr57993.c
@@ -0,0 +1,30 @@
+/* This ICEd prior to fixing PR57993. */
+/* { dg-do compile } */
+
+int a, b, c, d;
+char e;
+unsigned g;
+
+void f(void)
+{
+ int h;
+
+ for(; d; d++)
+ if(d)
+lbl:
+ g + a || (d = 0);
+
+ b && (a = e);
+
+ for(h = 0; h < 1; ++h)
+ {
+ h = c ? : (d = 0);
+ g = a = (e | 0);
+ }
+
+ if(a)
+ goto lbl;
+
+ a = e = 0;
+ goto lbl;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr58041.c b/gcc/testsuite/gcc.dg/torture/pr58041.c
new file mode 100644
index 00000000000..169a71ae7e4
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58041.c
@@ -0,0 +1,33 @@
+/* { dg-do run } */
+
+typedef long long V
+ __attribute__ ((vector_size (2 * sizeof (long long)), may_alias));
+
+struct s
+{
+ char u;
+ V v[2];
+} __attribute__((packed,aligned(1)));
+
+__attribute__((noinline, noclone))
+long long foo(struct s *x, int y, V *z)
+{
+ V a = x->v[y];
+ x->v[y] = *z;
+ return a[1];
+}
+
+struct s a = {0,{{0,0},{0,0}}};
+int main()
+{
+ V v1 = {0,1};
+ V v2 = {0,2};
+
+ if (foo(&a,0,&v1) != 0)
+ __builtin_abort();
+ if (foo(&a,0,&v2) != 1)
+ __builtin_abort();
+ if (foo(&a,1,&v1) != 0)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr58079.c b/gcc/testsuite/gcc.dg/torture/pr58079.c
new file mode 100644
index 00000000000..99a30181f1e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58079.c
@@ -0,0 +1,107 @@
+/* { dg-options "-mlong-calls" { target mips*-*-* } } */
+
+typedef unsigned char u8;
+typedef unsigned short u16;
+typedef unsigned int __kernel_size_t;
+typedef __kernel_size_t size_t;
+struct list_head {
+ struct list_head *next;
+};
+
+struct dmx_ts_feed {
+ int is_filtering;
+};
+struct dmx_section_feed {
+ u16 secbufp;
+ u16 seclen;
+ u16 tsfeedp;
+};
+
+typedef int (*dmx_ts_cb) (
+ const u8 * buffer1,
+ size_t buffer1_length,
+ const u8 * buffer2,
+ size_t buffer2_length
+);
+
+struct dvb_demux_feed {
+ union {
+ struct dmx_ts_feed ts;
+ struct dmx_section_feed sec;
+ } feed;
+ union {
+ dmx_ts_cb ts;
+ } cb;
+ int type;
+ u16 pid;
+ int ts_type;
+ struct list_head list_head;
+};
+
+struct dvb_demux {
+ int (*stop_feed)(struct dvb_demux_feed *feed);
+ struct list_head feed_list;
+};
+
+
+static
+inline
+__attribute__((always_inline))
+u8
+payload(const u8 *tsp)
+{
+ if (tsp[3] & 0x20) {
+ return 184 - 1 - tsp[4];
+ }
+ return 184;
+}
+
+static
+inline
+__attribute__((always_inline))
+int
+dvb_dmx_swfilter_payload(struct dvb_demux_feed *feed, const u8 *buf)
+{
+ int count = payload(buf);
+ int p;
+ if (count == 0)
+ return -1;
+ return feed->cb.ts(&buf[p], count, ((void *)0), 0);
+}
+
+static
+inline
+__attribute__((always_inline))
+void
+dvb_dmx_swfilter_packet_type(struct dvb_demux_feed *feed, const u8 *buf)
+{
+ switch (feed->type) {
+ case 0:
+ if (feed->ts_type & 1) {
+ dvb_dmx_swfilter_payload(feed, buf);
+ }
+ if (dvb_dmx_swfilter_section_packet(feed, buf) < 0)
+ feed->feed.sec.seclen = feed->feed.sec.secbufp = 0;
+ }
+}
+
+static
+void
+dvb_dmx_swfilter_packet(struct dvb_demux *demux, const u8 *buf)
+{
+ struct dvb_demux_feed *feed;
+ int dvr_done = 0;
+
+ for (feed = ({ const typeof( ((typeof(*feed) *)0)->list_head ) *__mptr = ((&demux->feed_list)->next); (typeof(*feed) *)( (char *)__mptr - __builtin_offsetof(typeof(*feed),list_head) );}); __builtin_prefetch(feed->list_head.next), &feed->list_head != (&demux->feed_list); feed = ({ const typeof( ((typeof(*feed) *)0)->list_head ) *__mptr = (feed->list_head.next); (typeof(*feed) *)( (char *)__mptr - __builtin_offsetof(typeof(*feed),list_head) );})) {
+ if (((((feed)->type == 0) && ((feed)->feed.ts.is_filtering) && (((feed)->ts_type & (1 | 8)) == 1))) && (dvr_done++))
+ dvb_dmx_swfilter_packet_type(feed, buf);
+ else if (feed->pid == 0x2000)
+ feed->cb.ts(buf, 188, ((void *)0), 0);
+ }
+}
+void dvb_dmx_swfilter_packets(struct dvb_demux *demux, const u8 *buf, size_t count)
+{
+ while (count--) {
+ dvb_dmx_swfilter_packet(demux, buf);
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr58223.c b/gcc/testsuite/gcc.dg/torture/pr58223.c
new file mode 100644
index 00000000000..978084ad0dc
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58223.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int a[2], b;
+
+int main ()
+{
+ for (b = 0; b < 2; b++)
+ {
+ a[0] = 1;
+ a[b] = 0;
+ }
+ if (a[0] != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr58228.c b/gcc/testsuite/gcc.dg/torture/pr58228.c
new file mode 100644
index 00000000000..d12303a008d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58228.c
@@ -0,0 +1,15 @@
+/* { dg-do run } */
+
+extern void abort (void);
+int a[8][8] = {{1}};
+int b, c, d, e;
+
+int main ()
+{
+ for (c = 0; c < 8; c++)
+ for (b = 0; b < 2; b++)
+ a[b + 4][c] = a[c][0];
+ if (a[4][4] != 1)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr58246.c b/gcc/testsuite/gcc.dg/torture/pr58246.c
new file mode 100644
index 00000000000..5417abf913d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr58246.c
@@ -0,0 +1,21 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+int a, b;
+
+int main ()
+{
+ int t[2] = {1,1};
+
+ for (a = 0; a < 2; a++)
+ {
+ b ^= t[a];
+ t[a] = t[1] = 0;
+ }
+
+ if (b != 1)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
index 7982210a616..ed81e808309 100644
--- a/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
+++ b/gcc/testsuite/gcc.dg/torture/stackalign/builtin-apply-2.c
@@ -6,7 +6,10 @@
/* { dg-do run } */
-/* { dg-skip-if "Variadic funcs use Base AAPCS. Normal funcs use VFP variant." { arm_hf_eabi } } */
+/* arm_hf_eabi: Variadic funcs use Base AAPCS. Normal funcs use VFP variant.
+ avr: Variadic funcs don't pass arguments in registers, while normal funcs
+ do. */
+/* { dg-skip-if "Variadic funcs use different argument passing from normal funcs" { arm_hf_eabi || { avr-*-* } } "*" "" } */
#define INTEGER_ARG 5
@@ -16,7 +19,7 @@
E, F and G are passed on stack. So the size of the stack argument
data is 20. */
#define STACK_ARGUMENTS_SIZE 20
-#elif defined __aarch64__ || defined __MMIX__
+#elif defined __aarch64__ || defined __arc__ || defined __MMIX__
/* No parameters on stack for bar. */
#define STACK_ARGUMENTS_SIZE 0
#else
diff --git a/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indircall-1.c b/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indircall-1.c
new file mode 100644
index 00000000000..3021425893f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indircall-1.c
@@ -0,0 +1,19 @@
+/* { dg-require-effective-target lto } */
+/* { dg-additional-sources "crossmodule-indircall-1a.c" } */
+/* { dg-options "-O3 -flto -DDOJOB=1" } */
+
+int a;
+extern void (*p[2])(int n);
+void abort (void);
+main()
+{ int i;
+
+ /* This call shall be converted. */
+ for (i = 0;i<1000;i++)
+ p[0](1);
+ /* This call shall not be converted. */
+ for (i = 0;i<1000;i++)
+ p[i%2](2);
+ if (a != 1000)
+ abort ();
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indircall-1a.c b/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indircall-1a.c
new file mode 100644
index 00000000000..a94195cd95f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-prof/crossmodule-indircall-1a.c
@@ -0,0 +1,40 @@
+/* It seems there is no way to avoid the other source of mulitple
+ source testcase from being compiled independently. Just avoid
+ error. */
+#ifdef DOJOB
+extern int a;
+void abort (void);
+
+#ifdef _PROFILE_USE
+__attribute__ ((externally_visible))
+int constval=1,constval2=2;
+#else
+__attribute__ ((externally_visible))
+int constval=3,constval2=2;
+#endif
+
+
+void
+add(int i)
+{
+ /* Verify that inlining happens for first case. */
+ if (i==constval && !__builtin_constant_p (i))
+ abort ();
+ /* Second case has no dominating target; it should not inline. */
+ if (i==constval2 && __builtin_constant_p (i))
+ abort ();
+ a += i;
+}
+void
+sub(int i)
+{
+ a -= i;
+}
+__attribute__ ((externally_visible))
+void (*p[2])(int)={add, sub};
+#else
+main()
+{
+ return 0;
+}
+#endif
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c b/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c
index 96c0dc24bed..fe4084d2131 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/attr-alias.c
@@ -8,7 +8,7 @@ int test()
return 0;
}
static int test2() __attribute__ ((alias("test")));
-static int test3() __attribute__ ((weakref)) __attribute__ ((alias("test2")));
+static int test1() __attribute__ ((weakref)) __attribute__ ((alias("test2")));
static int test4() __attribute__ ((weakref)) __attribute__ ((alias("test")));
main()
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
index 6220640459d..0bea9a9f00b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-1.c
@@ -8,6 +8,6 @@ test(int c)
a[i]=5;
}
/* Array bounds says the loop will not roll much. */
-/* { dg-final { scan-tree-dump "Completely unroll loop 2 times" "cunrolli"} } */
+/* { dg-final { scan-tree-dump "loop with 3 iterations completely unrolled" "cunrolli"} } */
/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunrolli"} } */
/* { dg-final { cleanup-tree-dump "cunrolli" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c
index 10f6645cf25..e16d0086fab 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-2.c
@@ -12,5 +12,5 @@ test(int c)
}
}
/* We are not able to get rid of the final conditional because the loop has two exits. */
-/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunroll"} } */
+/* { dg-final { scan-tree-dump "loop with 2 iterations completely unrolled" "cunroll"} } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c
index 44de9606e9c..dd6ce506744 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-3.c
@@ -11,5 +11,5 @@ test(int c)
}
/* If we start duplicating headers prior curoll, this loop will have 0 iterations. */
-/* { dg-final { scan-tree-dump "Completely unroll loop 1 times" "cunrolli"} } */
+/* { dg-final { scan-tree-dump "loop with 2 iterations completely unrolled" "cunrolli"} } */
/* { dg-final { cleanup-tree-dump "cunrolli" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c
index 9b70e95949f..86e12bbb419 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-4.c
@@ -16,6 +16,6 @@ test(int c)
/* We should do this as part of cunrolli, but our cost model do not take into account early exit
from the last iteration. */
-/* { dg-final { scan-tree-dump "Turned loop into non-loop; it never loops." "ivcanon"} } */
+/* { dg-final { scan-tree-dump "loop turned into non-loop; it never loops." "ivcanon"} } */
/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "ivcanon"} } */
/* { dg-final { cleanup-tree-dump "ivcanon" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c
index f74e6b5093b..1e9b8bfbab0 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/cunroll-5.c
@@ -8,7 +8,7 @@ test(int c)
a[i]=5;
}
/* Basic testcase for complette unrolling. */
-/* { dg-final { scan-tree-dump "Completely unroll loop 5 times" "cunroll"} } */
+/* { dg-final { scan-tree-dump "loop with 6 iterations completely unrolled" "cunroll"} } */
/* { dg-final { scan-tree-dump "Exit condition of peeled iterations was eliminated." "cunroll"} } */
/* { dg-final { scan-tree-dump "Last iteration exit edge was proved true." "cunroll"} } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c
new file mode 100644
index 00000000000..0c81d92bfa9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/fnsplit-1.c
@@ -0,0 +1,23 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-fnsplit" } */
+#include <stdio.h>
+int a[1000];
+
+void
+t(int a)
+{
+ if (a)
+ printf ("I Am Completely Operational,"),
+ printf ("And All My Circuits Are Functioning Perfectly\n");
+}
+int
+main(void)
+{
+ int i;
+ for (i = 0; i < 1000; i++)
+ t(a[i]);
+ return 0;
+}
+/* { dg-final { scan-tree-dump-times "Splitting function at:" 1 "fnsplit"} } */
+
+/* { dg-final { cleanup-tree-dump "fnsplit" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
index 5d087aa45dd..ec628b777a9 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
@@ -16,5 +16,5 @@ blah ()
very_long_function (1);
}
/* One appearance for dump, one self recursive call and one call from main. */
-/* { dg-final { scan-tree-dump-times "very_long_function.constprop.0 \\(\\)" 3 "optimized"} } */
+/* { dg-final { scan-tree-dump-times "very_long_function.constprop \\(\\)" 3 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c
index a26999e8905..53a9fa4f9e3 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ldist-16.c
@@ -14,8 +14,8 @@ void foo (int n)
}
}
-/* We should apply loop distribution and generate a memset (0). */
+/* We should not apply loop distribution and not generate a memset (0). */
-/* { dg-final { scan-tree-dump "distributed: split to 2" "ldist" } } */
-/* { dg-final { scan-tree-dump-times "generated memset zero" 1 "ldist" } } */
+/* { dg-final { scan-tree-dump "Loop 1 is the same" "ldist" } } */
+/* { dg-final { scan-tree-dump-times "generated memset zero" 0 "ldist" } } */
/* { dg-final { cleanup-tree-dump "ldist" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
index b4e4f2ac798..dd52c50faf4 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-1.c
@@ -35,7 +35,7 @@ int xxx(void)
/* { dg-final { scan-tree-dump-times "Added canonical iv to loop 1, 4 iterations" 1 "ivcanon"} } */
/* { dg-final { cleanup-tree-dump "ivcanon" } } */
-/* { dg-final { scan-tree-dump-times "Completely unroll loop 4 times" 1 "cunroll"} } */
+/* { dg-final { scan-tree-dump-times "loop with 5 iterations completely unrolled" 1 "cunroll"} } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
/* { dg-final { scan-tree-dump-times "foo" 5 "optimized"} } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
index 4f42491dad2..5bdc35fbd4c 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-23.c
@@ -24,6 +24,6 @@ int foo(void)
return sum;
}
-/* { dg-final { scan-tree-dump-times "Completely unroll loop 3 times" 1 "cunroll" } } */
+/* { dg-final { scan-tree-dump-times "loop with 4 iterations completely unrolled" 1 "cunroll" } } */
/* { dg-final { cleanup-tree-dump "cunroll" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/loop-4.c b/gcc/testsuite/gcc.dg/tree-ssa/loop-4.c
index a6c8c8fd34a..4313fca50e7 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/loop-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/loop-4.c
@@ -37,7 +37,7 @@ void xxx(void)
/* { dg-final { scan-tree-dump-times " \\* \[^\\n\\r\]*=" 0 "optimized" } } */
/* { dg-final { scan-tree-dump-times "\[^\\n\\r\]*= \\* " 0 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "MEM" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times " MEM" 1 "optimized" } } */
/* And the original induction variable should be eliminated. */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr31261.c b/gcc/testsuite/gcc.dg/tree-ssa/pr31261.c
index 42bd2a21ef3..54f677ba8ca 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr31261.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr31261.c
@@ -35,6 +35,7 @@ f5 (int e)
/* { dg-final { scan-tree-dump-times "return -a \& 7;" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "return b \& 7;" 1 "original" } } */
/* { dg-final { scan-tree-dump-times "return \\(char\\) -\\(unsigned char\\) c \& 31;" 1 "original" } } */
-/* { dg-final { scan-tree-dump-times "return \\(int\\) \\(12 - \\(unsigned int\\) d\\) \& 7;" 1 "original" } } */
+/* { dg-final { scan-tree-dump-times "return \\(int\\) \\(12 - \\(unsigned int\\) d\\) \& 7;" 1 "original" { target { ! int16 } } } } */
+/* { dg-final { scan-tree-dump-times "return \\(int\\) \\(12 - \\(unsigned short\\) d\\) \& 7;" 1 "original" { target { int16 } } } } */
/* { dg-final { scan-tree-dump-times "return 12 - \\(e \& 7\\) \& 15;" 1 "original" } } */
/* { dg-final { cleanup-tree-dump "original" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c b/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c
index f3d8459cc7d..bea55496aeb 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr42585.c
@@ -35,6 +35,6 @@ Cyc_string_ungetc (int ignore, struct _fat_ptr *sptr)
/* Whether the structs are totally scalarized or not depends on the
MOVE_RATIO macro definition in the back end. The scalarization will
not take place when using small values for MOVE_RATIO. */
-/* { dg-final { scan-tree-dump-times "struct _fat_ptr _ans" 0 "optimized" { target { ! "arm*-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
-/* { dg-final { scan-tree-dump-times "struct _fat_ptr _T2" 0 "optimized" { target { ! "arm*-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "struct _fat_ptr _ans" 0 "optimized" { target { ! "arm*-*-* avr-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
+/* { dg-final { scan-tree-dump-times "struct _fat_ptr _T2" 0 "optimized" { target { ! "arm*-*-* avr-*-* powerpc*-*-* s390*-*-* sh*-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr44258.c b/gcc/testsuite/gcc.dg/tree-ssa/pr44258.c
index a98d3ceccbf..6dc233b3231 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr44258.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr44258.c
@@ -39,5 +39,7 @@ int foo (int b)
*e_u = u;
}
-/* { dg-final { scan-tree-dump-times "Created a replacement" 0 "esra"} } */
+/* Epiphany has struct alignment/padding that avoids the overlap of
+ str.b1 and val.b2. */
+/* { dg-final { scan-tree-dump-times "Created a replacement" 0 "esra" { target { ! "epiphany-*-*" } } } } */
/* { dg-final { cleanup-tree-dump "esra" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr54245.c b/gcc/testsuite/gcc.dg/tree-ssa/pr54245.c
index 0e11d06ed85..daca0423a1d 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pr54245.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr54245.c
@@ -45,5 +45,5 @@ int main(void)
/* For now, disable inserting an initializer when the multiplication will
take place in a smaller type than originally. This test may be deleted
in future when this case is handled more precisely. */
-/* { dg-final { scan-tree-dump-times "Inserting initializer" 0 "slsr" } } */
+/* { dg-final { scan-tree-dump-times "Inserting initializer" 0 "slsr" { target { ! int16 } } } } */
/* { dg-final { cleanup-tree-dump "slsr" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c
index a4244171305..dcfae5dd957 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-1.c
@@ -33,5 +33,6 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" { target { ! keeps_null_pointer_checks } } } } */
+/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL x }" "alias" { target { keeps_null_pointer_checks } } } } */
/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c
index 8580382fca6..e6139591ec8 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-2.c
@@ -34,5 +34,6 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" { target { ! keeps_null_pointer_checks } } } } */
+/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL x }" "alias" { target { keeps_null_pointer_checks } } } } */
/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c
index 5a121a0d9a7..870dcf6b19a 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pta-escape-3.c
@@ -38,5 +38,6 @@ int main()
return 0;
}
-/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" } } */
+/* { dg-final { scan-tree-dump "ESCAPED = { NULL ESCAPED NONLOCAL x }" "alias" { target { ! keeps_null_pointer_checks } } } } */
+/* { dg-final { scan-tree-dump "ESCAPED = { ESCAPED NONLOCAL x }" "alias" { target { keeps_null_pointer_checks } } } } */
/* { dg-final { cleanup-tree-dump "alias" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/reassoc-31.c b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-31.c
new file mode 100644
index 00000000000..1c1527f1350
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/reassoc-31.c
@@ -0,0 +1,17 @@
+/* PR tree-optimization/58011 */
+/* { dg-do compile } */
+/* { dg-options "-O1" } */
+int a, b;
+
+void f(unsigned p)
+{
+ unsigned *pp = &p;
+
+ if(!a)
+ p = 0;
+
+ for(b = 0; b < 1; b++)
+ if(3 * p + 5 * *pp)
+ a = 0;
+}
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/sccp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/sccp-1.c
new file mode 100644
index 00000000000..633a37a35fe
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/sccp-1.c
@@ -0,0 +1,15 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-optimized" } */
+
+int main(int argc, char* argv[])
+{
+ int i, a = 0;
+ for (i=0; i < 10; i++)
+ a += i + 0xff00ff;
+ return a;
+}
+
+/* There should be no loop left. */
+
+/* { dg-final { scan-tree-dump-times "goto" 0 "optimized" } } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-1.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-1.c
index 38da1791512..e8c0ff02133 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-1.c
@@ -14,7 +14,9 @@ f (int *p, unsigned int n)
foo (*(p + 48 + n * 4));
}
-/* { dg-final { scan-tree-dump-times "\\+ 128|\\, 128>" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\+ 128|\\, 128>" 1 "optimized" { target { int32plus } } } } */
/* { dg-final { scan-tree-dump-times "\\+ 64|\\, 64>" 1 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "\\+ 192|\\, 192>" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\+ 32|\\, 32>" 1 "optimized" { target { int16 } } } } */
+/* { dg-final { scan-tree-dump-times "\\+ 192|\\, 192>" 1 "optimized" { target { int32 } } } } */
+/* { dg-final { scan-tree-dump-times "\\+ 96|\\, 96>" 1 "optimized" { target { int16 } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-2.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-2.c
index c6bb3e030e9..56697ff7f88 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-2.c
@@ -11,6 +11,8 @@ f (int *p, int n)
foo (*(p + 16 + n * 4));
}
-/* { dg-final { scan-tree-dump-times "\\+ 144|\\, 144>" 1 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "\\+ 96|\\, 96>" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\+ 144|\\, 144>" 1 "optimized" { target { int32 } } } } */
+/* { dg-final { scan-tree-dump-times "\\+ 72|\\, 72>" 1 "optimized" { target { int16 } } } } */
+/* { dg-final { scan-tree-dump-times "\\+ 96|\\, 96>" 1 "optimized" { target { int32 } } } } */
+/* { dg-final { scan-tree-dump-times "\\+ 48|\\, 48>" 1 "optimized" { target { int16 } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c
index eb5734ae543..c6642627d1f 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-27.c
@@ -16,7 +16,8 @@ f (struct x *p, unsigned int n)
foo (p->a[n], p->c[n], p->b[n]);
}
-/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" } } */
+/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" { target { int32 } } } } */
+/* { dg-final { scan-tree-dump-times "\\* 2;" 1 "dom2" { target { int16 } } } } */
/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+;" 1 "dom2" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 3 "dom2" } } */
/* { dg-final { cleanup-tree-dump "dom2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c
index 7e7c7516e6a..c4dbf54db86 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-28.c
@@ -20,7 +20,8 @@ f (struct x *p, unsigned int n)
foo (p->b[n], p->a[n], p->c[n]);
}
-/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" } } */
+/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" { target { int32 } } } } */
+/* { dg-final { scan-tree-dump-times "\\* 2;" 1 "dom2" { target { int16 } } } } */
/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+" 1 "dom2" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom2" } } */
/* { dg-final { cleanup-tree-dump "dom2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c
index 2a8fe0e6d6c..c8e7a5e137b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-29.c
@@ -22,7 +22,8 @@ f (struct x *p, unsigned int n)
}
}
-/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" } } */
+/* { dg-final { scan-tree-dump-times "\\* 4;" 1 "dom2" { target { int32 } } } } */
+/* { dg-final { scan-tree-dump-times "\\* 2;" 1 "dom2" { target { int16 } } } } */
/* { dg-final { scan-tree-dump-times "p_\\d\+\\(D\\) \\+ \[^\r\n\]*_\\d\+" 1 "dom2" } } */
/* { dg-final { scan-tree-dump-times "MEM\\\[\\(struct x \\*\\)\[^\r\n\]*_\\d\+" 9 "dom2" } } */
/* { dg-final { cleanup-tree-dump "dom2" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/slsr-3.c b/gcc/testsuite/gcc.dg/tree-ssa/slsr-3.c
index 32edf2b77b3..89d1d2e73fd 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/slsr-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/slsr-3.c
@@ -15,8 +15,11 @@ foo (int a[], int b[], int i)
return i;
}
-/* { dg-final { scan-tree-dump-times "\\* 4" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\* 4" 1 "optimized" { target { int32 } } } } */
+/* { dg-final { scan-tree-dump-times "\\* 2" 1 "optimized" { target { int16 } } } } */
+/* { dg-final { scan-tree-dump-times "\\+ 2|\\, 2>" 5 "optimized" { target { int16 } } } } */
/* { dg-final { scan-tree-dump-times "\\+ 4|\\, 4>" 2 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "\\+ 8|\\, 8>" 1 "optimized" } } */
-/* { dg-final { scan-tree-dump-times "\\+ 12|\\, 12>" 1 "optimized" } } */
+/* { dg-final { scan-tree-dump-times "\\+ 8|\\, 8>" 1 "optimized" { target { int32plus } } } } */
+/* { dg-final { scan-tree-dump-times "\\+ 6|\\, 6>" 1 "optimized" { target { int16 } } } } */
+/* { dg-final { scan-tree-dump-times "\\+ 12|\\, 12>" 1 "optimized" { target { int32 } } } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-23.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-23.c
index fb4af2d484d..8b95b0c3438 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-23.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-ccp-23.c
@@ -15,5 +15,6 @@ int foo (void)
return *x;
}
-/* { dg-final { scan-tree-dump "MEM\\\[\\\(int \\\*\\\)&a \\\+ 4B\\\]" "ccp1" } } */
+/* { dg-final { scan-tree-dump "MEM\\\[\\\(int \\\*\\\)&a \\\+ 2B\\\]" "ccp1" { target { int16 } } } } */
+/* { dg-final { scan-tree-dump "MEM\\\[\\\(int \\\*\\\)&a \\\+ 4B\\\]" "ccp1" { target { int32 } } } } */
/* { dg-final { cleanup-tree-dump "ccp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c
index d67f8692862..c2efd15eb33 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-3.c
@@ -43,6 +43,5 @@ expand_one_var (tree var, unsigned char toplevel, unsigned char really_expand)
}
/* We should thread the jump, through an intermediate block. */
/* { dg-final { scan-tree-dump-times "Threaded" 1 "dom1"} } */
-/* { dg-final { scan-tree-dump-times "one or more intermediate" 1 "dom1"} } */
-/* { dg-final { cleanup-tree-dump "dom1" } } */
+/* { dg-final { scan-tree-dump-times "Registering jump thread .through joiner block.: \\(.*\\); \\(.*\\); \\(.*\\);" 1 "dom1"} } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
index 44b05f07a6c..e97719f9c13 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-4.c
@@ -61,7 +61,7 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
zero. */
/* ARM Cortex-M0 defined LOGICAL_OP_NON_SHORT_CIRCUIT to false,
so skip below test. */
-/* { dg-final { scan-tree-dump-times "Threaded" 3 "dom1" { target { ! { mips*-*-* || { arm_cortex_m && arm_thumb1 } } } } } } */
+/* { dg-final { scan-tree-dump-times "Threaded" 3 "dom1" { target { ! { { mips*-*-* avr-*-* } || { arm_cortex_m && arm_thumb1 } } } } } } */
/* MIPS defines LOGICAL_OP_NON_SHORT_CIRCUIT to 0, so we split both
"a_elt || b_elt" and "b_elt && kill_elt" into two conditions each,
rather than using "(var1 != 0) op (var2 != 0)". Also, as on other targets,
@@ -81,6 +81,8 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b,
-> "kill_elt->indx == b_elt->indx" in the second condition,
skipping the known-true "b_elt && kill_elt" in the second
condition. */
-/* { dg-final { scan-tree-dump-times "Threaded" 6 "dom1" { target mips*-*-* } } } */
+/* For avr, BRANCH_COST is by default 0, so the default
+ LOGICAL_OP_NON_SHORT_CIRCUIT definition also computes as 0. */
+/* { dg-final { scan-tree-dump-times "Threaded" 6 "dom1" { target mips*-*-* avr-*-* } } } */
/* { dg-final { cleanup-tree-dump "dom1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c
index e4c9772f61f..40bb421f535 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-21.c
@@ -11,5 +11,5 @@ NumSift (long *array, unsigned long k)
/* There should be only two loads left. */
-/* { dg-final { scan-tree-dump-times "= \\\*\[^\n;\]*;" 2 "pre" } } */
+/* { dg-final { scan-tree-dump-times "= \\\*\[^\n;\]*;" 2 "pre" { xfail { ! size32plus } } } } */ /* xfail: PR tree-optimization/58169 */
/* { dg-final { cleanup-tree-dump "pre" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
index 68a7a7f826e..91e0e89363e 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-30.c
@@ -1,4 +1,5 @@
/* { dg-do compile } */
+/* { dg-require-effective-target int32 } */
/* { dg-options "-O2 -fdump-tree-pre-details" } */
int f;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c
new file mode 100644
index 00000000000..9d9473e7f31
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-vrp-thread-1.c
@@ -0,0 +1,31 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-vrp1-details" } */
+
+
+struct basic_block_def;
+typedef struct basic_block_def *basic_block;
+enum gimple_code
+{
+ LAST_AND_UNUSED_GIMPLE_CODE
+};
+struct omp_region
+{
+ struct omp_region *outer;
+ basic_block cont;
+};
+void
+build_omp_regions_1 (basic_block bb, struct omp_region *parent,
+ unsigned char single_tree, enum gimple_code code)
+{
+ if (code == 25)
+ parent = parent->outer;
+ else if (code == 42)
+ parent->cont = bb;
+ if (single_tree && !parent)
+ return;
+ oof ();
+}
+
+/* { dg-final { scan-tree-dump-times "Threaded" 1 "vrp1" } } */
+/* { dg-final { cleanup-tree-dump "vrp1" } } */
+
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c b/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
index 10aebc47b45..018b8cbe3ad 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vector-4.c
@@ -1,7 +1,8 @@
/* { dg-do compile } */
/* { dg-options "-w -O1 -fdump-tree-gimple" } */
-typedef int v4si __attribute__ ((vector_size (16)));
+typedef int SItype __attribute__ ((mode (SI)));
+typedef SItype v4si __attribute__ ((vector_size (16)));
v4si vs (v4si a, v4si b)
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp55.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp55.c
index 7adfe62052d..7a3e726b206 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp55.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp55.c
@@ -9,6 +9,7 @@ fu (char *p, int x)
arf ();
}
-/* { dg-final { scan-tree-dump-times "Threaded jump" 1 "vrp1" } } */
+/* { dg-final { scan-tree-dump-times "Threaded jump" 1 "vrp1" { target { ! keeps_null_pointer_checks } } } } */
+/* { dg-final { scan-tree-dump-times "Threaded jump" 0 "vrp1" { target { keeps_null_pointer_checks } } } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c
index 7da3896b5b2..aa10af24960 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp58.c
@@ -8,5 +8,6 @@ foo (long long a, signed char b, signed char c)
return a + (short)bc;
}
-/* { dg-final { scan-tree-dump "Folded into" "vrp1" } } */
+/* { dg-final { scan-tree-dump "Folded into" "vrp1" { target int32plus } } } */
+/* { dg-final { scan-tree-dump "Folding statement: _\[0-9\]\* = \\(long long int\\) bc_\[0-9\]\*;" "vrp1" { target int16 } } } */
/* { dg-final { cleanup-tree-dump "vrp1" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
index 0b9029f60b7..7339823f480 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp87.c
@@ -1,6 +1,7 @@
/* { dg-do compile { target { ! "m68k*-*-* mmix*-*-* mep*-*-* bfin*-*-* v850*-*-* picochip*-*-* moxie*-*-* cris*-*-* m32c*-*-* fr30*-*-* mcore*-*-* powerpc*-*-* xtensa*-*-*"} } } */
/* { dg-options "-O2 -fdump-tree-vrp2-details -fdump-tree-cddce2-details" } */
+/* { dg-additional-options "-mbranch-cost=2" { target avr-*-* } } */
struct bitmap_head_def;
typedef struct bitmap_head_def *bitmap;
diff --git a/gcc/testsuite/gcc.dg/ubsan/c99-shift-1.c b/gcc/testsuite/gcc.dg/ubsan/c99-shift-1.c
new file mode 100644
index 00000000000..ff6776bf3c1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/c99-shift-1.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -w -std=c99" } */
+
+int
+main (void)
+{
+ int a = -42;
+ a << 1;
+}
+/* { dg-output "left shift of negative value -42" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c b/gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c
new file mode 100644
index 00000000000..7dceb585739
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/c99-shift-2.c
@@ -0,0 +1,10 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=shift -w -std=c99" } */
+
+int
+main (void)
+{
+ int a = 1;
+ a <<= 31;
+}
+/* { dg-output "left shift of 1 by 31 places cannot be represented in type int" } */
diff --git a/gcc/testsuite/gcc.dg/ubsan/ubsan.exp b/gcc/testsuite/gcc.dg/ubsan/ubsan.exp
new file mode 100644
index 00000000000..d077d1da8e2
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/ubsan/ubsan.exp
@@ -0,0 +1,36 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Load support procs.
+load_lib gcc-dg.exp
+load_lib ubsan-dg.exp
+
+# Initialize `dg'.
+dg-init
+if [ubsan_init] {
+
+# Main loop.
+gcc-dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.c $srcdir/c-c++-common/ubsan/*.c]] ""
+
+}
+
+# All done.
+ubsan_finish
+dg-finish
diff --git a/gcc/testsuite/gcc.dg/unroll_1.c b/gcc/testsuite/gcc.dg/unroll_1.c
index 5818635cea9..154c78e4bf9 100644
--- a/gcc/testsuite/gcc.dg/unroll_1.c
+++ b/gcc/testsuite/gcc.dg/unroll_1.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O2 -fdump-rtl-loop2_unroll -fno-peel-loops -fdisable-tree-cunroll -fdisable-tree-cunrolli -fenable-rtl-loop2_unroll" } */
+/* { dg-options "-O2 -fdump-rtl-loop2_unroll=stderr -fno-peel-loops -fdisable-tree-cunroll -fdisable-tree-cunrolli -fenable-rtl-loop2_unroll" } */
unsigned a[100], b[100];
inline void bar()
@@ -11,7 +11,7 @@ int foo(void)
{
int i;
bar();
- for (i = 0; i < 2; i++)
+ for (i = 0; i < 2; i++) /* { dg-message "note: loop turned into non-loop; it never loops" } */
{
a[i]= b[i] + 1;
}
@@ -21,12 +21,10 @@ int foo(void)
int foo2(void)
{
int i;
- for (i = 0; i < 2; i++)
+ for (i = 0; i < 2; i++) /* { dg-message "note: loop turned into non-loop; it never loops" } */
{
a[i]= b[i] + 1;
}
return 1;
}
-
-/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 2 "loop2_unroll" } } */
-/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
+/* { dg-prune-output ".*" } */
diff --git a/gcc/testsuite/gcc.dg/unroll_2.c b/gcc/testsuite/gcc.dg/unroll_2.c
index 1156b2cc88d..601b38705c1 100644
--- a/gcc/testsuite/gcc.dg/unroll_2.c
+++ b/gcc/testsuite/gcc.dg/unroll_2.c
@@ -28,5 +28,5 @@ int foo2(void)
return 1;
}
-/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "loop turned into non-loop; it never loops" 1 "loop2_unroll" } } */
/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/unroll_3.c b/gcc/testsuite/gcc.dg/unroll_3.c
index 13e815f18be..1f4216b6068 100644
--- a/gcc/testsuite/gcc.dg/unroll_3.c
+++ b/gcc/testsuite/gcc.dg/unroll_3.c
@@ -28,5 +28,5 @@ int foo2(void)
return 1;
}
-/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "loop turned into non-loop; it never loops" 1 "loop2_unroll" } } */
/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/unroll_4.c b/gcc/testsuite/gcc.dg/unroll_4.c
index 59f75edf3db..33d6edee2cc 100644
--- a/gcc/testsuite/gcc.dg/unroll_4.c
+++ b/gcc/testsuite/gcc.dg/unroll_4.c
@@ -28,5 +28,5 @@ int foo2(void)
return 1;
}
-/* { dg-final { scan-rtl-dump-times "Turned loop into non-loop; it never loops" 1 "loop2_unroll" } } */
+/* { dg-final { scan-rtl-dump-times "loop turned into non-loop; it never loops" 1 "loop2_unroll" } } */
/* { dg-final { cleanup-rtl-dump "loop2_unroll" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
index 11882ec5d4a..1caa3cf5c60 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-1.c
@@ -56,6 +56,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
index 6eb8f5465f8..658bf03ca56 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-10.c
@@ -50,6 +50,6 @@ int main (void)
}
/* { dg-final { scan-tree-dump-times "unsupported alignment in basic block." 1 "slp" { xfail vect_element_align } } } */
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
index 9844788ea0d..3c350a7ab22 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-11.c
@@ -48,6 +48,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect64 } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect64 } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
index f312ea64fc1..88838cea9bc 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-13.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
index 9a36033ca7b..d46deadd0dc 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-14.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
index 842699ecb0a..fd065e6ce35 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-15.c
@@ -51,6 +51,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
index 609dc7b6a3e..0cbec65b773 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-16.c
@@ -65,6 +65,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
index 5a917b8b3f7..3f14ff487a5 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-17.c
@@ -57,6 +57,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
index 98501ccf6a6..7d73dbd8b23 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-18.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
index 2f726121c94..576bbc16921 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-19.c
@@ -53,6 +53,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { xfail *-*-* } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
index da228f7c33c..accc472f791 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-2.c
@@ -53,6 +53,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
index caaecb9bafb..a7978a70d7a 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-20.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
index eba9d08c951..8ad71454afe 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-21.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 1 "slp" { target { ! {vect_int_mult } } } } } */
/* { dg-final { scan-tree-dump-times "vectorizing stmts using SLP" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
index 30bc57a6bbb..e425dc9ade1 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-22.c
@@ -63,7 +63,7 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { ! {vect_int_mult } } } } } */
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { ! {vect_int_mult } } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
index a736c385c81..35f5186fd74 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-23.c
@@ -51,6 +51,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
index 10d8e406647..d0c1d69d1fa 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-24.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
index b92535df00c..737b3b06c04 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-25.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-26.c b/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
index f40c12402b6..881f3204f40 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-26.c
@@ -55,6 +55,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect64 } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect64 } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
index e9b386f4921..7fcc1e61041 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-27.c
@@ -44,6 +44,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_int_mult && { vect_unpack && vect_pack_trunc } } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
index 3dc1a0d8a7c..650c50eb938 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-28.c
@@ -66,6 +66,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && { vect_pack_trunc && vect_unpack } } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_int_mult && { vect_pack_trunc && vect_unpack } } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
index c2bc391885d..c5b31343a44 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-29.c
@@ -54,6 +54,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_int_mult && vect_element_align } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_int_mult && vect_element_align } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
index 98cbc5b80ea..093389faf9f 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-3.c
@@ -42,6 +42,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-30.c b/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
index a587780364f..86da55a47cc 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-30.c
@@ -43,5 +43,5 @@ test1(void)
int main() { test1(); return a[21]; }
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-31.c b/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
index e2704dc721f..bbddb0ac28c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-31.c
@@ -9,4 +9,4 @@ void f(){
a[1]=1+2*a[1]*a[1];
}
-/* { dg-final { scan-tree-dump "Vectorized basic-block" "slp" } } */
+/* { dg-final { scan-tree-dump "basic block vectorized" "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
index 5b983c7e63e..2c4b62dc4ac 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-4.c
@@ -38,6 +38,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
index cd1679e981d..ca093e795fc 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-5.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
index 39d8c04cc9a..c233a9d5010 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-6.c
@@ -45,6 +45,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
index c0ca017d0d8..b7b90f0b95b 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-7.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
index 1cb3ddd65e6..303fe3e4336 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8.c
@@ -48,6 +48,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
index 9db6747985e..55a6a81d38c 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8a.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 0 "slp" } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 0 "slp" } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
index dc6353999f3..8c5c5ab9182 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-8b.c
@@ -49,6 +49,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_hw_misalign } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_hw_misalign } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
index 3b950897249..9f1a5877a29 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-9.c
@@ -46,6 +46,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { xfail vect_no_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { xfail vect_no_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c b/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
index 38c18a71fc7..86376b44641 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-cond-1.c
@@ -41,6 +41,6 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_element_align } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_element_align } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
index 0d4d54fe0c2..545c08d86e9 100644
--- a/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
+++ b/gcc/testsuite/gcc.dg/vect/bb-slp-pattern-2.c
@@ -48,5 +48,5 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_element_align && vect_pack_trunc } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_element_align && vect_pack_trunc } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
index d842658c679..c138a78b328 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-1.c
@@ -45,5 +45,5 @@ main ()
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target { vect_call_copysignf && vect_call_sqrtf } } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
index d6fb6a2b6f9..c126c1c0085 100644
--- a/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
+++ b/gcc/testsuite/gcc.dg/vect/fast-math-bb-slp-call-2.c
@@ -63,5 +63,5 @@ main ()
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 2 "slp" { target vect_call_lrint } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 2 "slp" { target vect_call_lrint } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
index b4154835a11..49274f88f57 100644
--- a/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
+++ b/gcc/testsuite/gcc.dg/vect/no-tree-reassoc-bb-slp-12.c
@@ -47,6 +47,6 @@ int main (void)
return 0;
}
-/* { dg-final { scan-tree-dump-times "Vectorized basic-block" 1 "slp" { target vect_int_mult } } } */
+/* { dg-final { scan-tree-dump-times "basic block vectorized" 1 "slp" { target vect_int_mult } } } */
/* { dg-final { cleanup-tree-dump "slp" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr56933.c b/gcc/testsuite/gcc.dg/vect/pr56933.c
index 93a7da2ee8d..b5e56fbddc9 100644
--- a/gcc/testsuite/gcc.dg/vect/pr56933.c
+++ b/gcc/testsuite/gcc.dg/vect/pr56933.c
@@ -1,4 +1,7 @@
/* { dg-do run } */
+/* { dg-require-effective-target vect_double } */
+
+#include "tree-vect.h"
extern void abort (void);
void __attribute__((noinline,noclone))
@@ -17,6 +20,9 @@ int main()
{
double b[1024], d[2*1024], f[1024];
int i;
+
+ check_vect ();
+
for (i = 0; i < 2*1024; i++)
d[i] = 1.;
foo (b, d, f);
diff --git a/gcc/testsuite/gcc.dg/vect/vect-iv-5.c b/gcc/testsuite/gcc.dg/vect/vect-iv-5.c
index 1766ae6a33a..88610950055 100644
--- a/gcc/testsuite/gcc.dg/vect/vect-iv-5.c
+++ b/gcc/testsuite/gcc.dg/vect/vect-iv-5.c
@@ -36,5 +36,5 @@ int main (void)
return main1 ();
}
-/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail *-*-* } } } */
+/* { dg-final { scan-tree-dump-times "vectorized 1 loops" 1 "vect" { xfail {! arm_neon_ok } } } } */
/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c b/gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c
index 3d902f6342d..aa041cc2c20 100644
--- a/gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c
+++ b/gcc/testsuite/gcc.target/aarch64/scalar_intrinsics.c
@@ -193,60 +193,92 @@ test_vcltzd_s64 (int64x1_t a)
return res;
}
-/* { dg-final { scan-assembler-times "aarch64_dup_lane_scalarv16qi" 2 } } */
+/* { dg-final { scan-assembler-times "aarch64_get_lanev16qi" 2 } } */
int8x1_t
test_vdupb_lane_s8 (int8x16_t a)
{
- return vdupb_lane_s8 (a, 2);
+ int8x1_t res;
+ force_simd (a);
+ res = vdupb_laneq_s8 (a, 2);
+ force_simd (res);
+ return res;
}
uint8x1_t
test_vdupb_lane_u8 (uint8x16_t a)
{
- return vdupb_lane_u8 (a, 2);
+ uint8x1_t res;
+ force_simd (a);
+ res = vdupb_laneq_u8 (a, 2);
+ force_simd (res);
+ return res;
}
-/* { dg-final { scan-assembler-times "aarch64_dup_lane_scalarv8hi" 2 } } */
+/* { dg-final { scan-assembler-times "aarch64_get_lanev8hi" 2 } } */
int16x1_t
test_vduph_lane_s16 (int16x8_t a)
{
- return vduph_lane_s16 (a, 2);
+ int16x1_t res;
+ force_simd (a);
+ res = vduph_laneq_s16 (a, 2);
+ force_simd (res);
+ return res;
}
uint16x1_t
test_vduph_lane_u16 (uint16x8_t a)
{
- return vduph_lane_u16 (a, 2);
+ uint16x1_t res;
+ force_simd (a);
+ res = vduph_laneq_u16 (a, 2);
+ force_simd (res);
+ return res;
}
-/* { dg-final { scan-assembler-times "aarch64_dup_lane_scalarv4si" 2 } } */
+/* { dg-final { scan-assembler-times "aarch64_get_lanev4si" 2 } } */
int32x1_t
test_vdups_lane_s32 (int32x4_t a)
{
- return vdups_lane_s32 (a, 2);
+ int32x1_t res;
+ force_simd (a);
+ res = vdups_laneq_s32 (a, 2);
+ force_simd (res);
+ return res;
}
uint32x1_t
test_vdups_lane_u32 (uint32x4_t a)
{
- return vdups_lane_u32 (a, 2);
+ uint32x1_t res;
+ force_simd (a);
+ res = vdups_laneq_u32 (a, 2);
+ force_simd (res);
+ return res;
}
-/* { dg-final { scan-assembler-times "aarch64_dup_lane_scalarv2di" 2 } } */
+/* { dg-final { scan-assembler-times "aarch64_get_lanev2di" 2 } } */
int64x1_t
test_vdupd_lane_s64 (int64x2_t a)
{
- return vdupd_lane_s64 (a, 1);
+ int64x1_t res;
+ force_simd (a);
+ res = vdupd_laneq_s64 (a, 1);
+ force_simd (res);
+ return res;
}
uint64x1_t
test_vdupd_lane_u64 (uint64x2_t a)
{
- return vdupd_lane_u64 (a, 1);
+ uint64x1_t res;
+ force_simd (a);
+ res = vdupd_laneq_u64 (a, 1);
+ force_simd (res);
+ return res;
}
/* { dg-final { scan-assembler-times "\\tcmtst\\td\[0-9\]+, d\[0-9\]+, d\[0-9\]+" 2 } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/scalar_shift_1.c b/gcc/testsuite/gcc.target/aarch64/scalar_shift_1.c
new file mode 100644
index 00000000000..7cb17f89c51
--- /dev/null
+++ b/gcc/testsuite/gcc.target/aarch64/scalar_shift_1.c
@@ -0,0 +1,263 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-inline -save-temps" } */
+
+extern void abort ();
+
+#define force_simd_di(v) asm volatile ("mov %d0, %1.d[0]" :"=w" (v) :"w" (v) :)
+#define force_simd_si(v) asm volatile ("mov %s0, %1.s[0]" :"=w" (v) :"w" (v) :)
+
+typedef unsigned long long int UInt64x1;
+typedef long long int Int64x1;
+typedef unsigned int UInt32x1;
+typedef int Int32x1;
+
+UInt64x1
+test_lshift_left_sisd_di (UInt64x1 b, UInt64x1 c)
+{
+ UInt64x1 a;
+
+ force_simd_di (b);
+ force_simd_di (c);
+ a = b << 8;
+ a = a << c;
+ force_simd_di (a);
+ return a;
+}
+/* { dg-final { scan-assembler "shl\td\[0-9\]+,\ d\[0-9\]+,\ 8" } } */
+/* { dg-final { scan-assembler "ushl\td\[0-9\]+,\ d\[0-9\]+,\ d\[0-9\]+" } } */
+
+UInt32x1
+test_lshift_left_sisd_si (UInt32x1 b, UInt32x1 c)
+{
+ UInt32x1 a;
+
+ force_simd_si (b);
+ force_simd_si (c);
+ a = b << 4;
+ a = a << c;
+ force_simd_si (a);
+ return a;
+}
+/* { dg-final { scan-assembler "shl\tv\[0-9\]+\.2s,\ v\[0-9\]+\.2s,\ 4" } } */
+/* "ushl\tv\[0-9\]+\.2s,\ v\[0-9\]+\.2s,\ v\[0-9\]+\.2s" (counted later) */
+
+UInt64x1
+test_lshift_right_sisd_di (UInt64x1 b, UInt64x1 c)
+{
+ UInt64x1 a;
+
+ force_simd_di (b);
+ force_simd_di (c);
+ a = b >> 8;
+ a = a >> c;
+ force_simd_di (a);
+ return a;
+}
+/* { dg-final { scan-assembler "ushr\td\[0-9\]+,\ d\[0-9\]+,\ 8" } } */
+/* "neg\td\[0-9\]+,\ d\[0-9\]+" (counted later) */
+/* { dg-final { scan-assembler "ushl\td\[0-9\]+,\ d\[0-9\]+,\ d\[0-9\]+" } } */
+
+UInt64x1
+test_lshift_right_sisd_si (UInt32x1 b, UInt32x1 c)
+{
+ UInt32x1 a;
+
+ force_simd_si (b);
+ force_simd_si (c);
+ a = b >> 4;
+ a = a >> c;
+ force_simd_si (a);
+ return a;
+}
+/* { dg-final { scan-assembler "ushr\tv\[0-9\]+\.2s,\ v\[0-9\]+\.2s,\ 4" } } */
+/* "neg\td\[0-9\]+,\ d\[0-9\]+" (counted later) */
+/* { dg-final { scan-assembler-times "ushl\tv\[0-9\]+\.2s,\ v\[0-9\]+\.2s,\ v\[0-9\]+\.2s" 2 } } */
+
+Int64x1
+test_ashift_right_sisd_di (Int64x1 b, Int64x1 c)
+{
+ Int64x1 a;
+
+ force_simd_di (b);
+ force_simd_di (c);
+ a = b >> 8;
+ a = a >> c;
+ force_simd_di (a);
+ return a;
+}
+/* { dg-final { scan-assembler "sshr\td\[0-9\]+,\ d\[0-9\]+,\ 8" } } */
+/* "neg\td\[0-9\]+,\ d\[0-9\]+" (counted later) */
+/* { dg-final { scan-assembler "sshl\td\[0-9\]+,\ d\[0-9\]+,\ d\[0-9\]+" } } */
+
+Int32x1
+test_ashift_right_sisd_si (Int32x1 b, Int32x1 c)
+{
+ Int32x1 a;
+
+ force_simd_si (b);
+ force_simd_si (c);
+ a = b >> 4;
+ a = a >> c;
+ force_simd_si (a);
+ return a;
+}
+/* { dg-final { scan-assembler "sshr\tv\[0-9\]+\.2s,\ v\[0-9\]+\.2s,\ 4" } } */
+/* { dg-final { scan-assembler-times "neg\td\[0-9\]+,\ d\[0-9\]+" 4 } } */
+/* { dg-final { scan-assembler "sshl\tv\[0-9\]+\.2s,\ v\[0-9\]+\.2s,\ v\[0-9\]+\.2s" } } */
+
+
+/* The following are to make sure if the integer instructions lsl/lsr/asr are
+ generated in non-vector scenarios */
+
+UInt64x1
+test_lshift_left_int_di (UInt64x1 b, UInt64x1 c)
+{
+ UInt64x1 a;
+
+ a = b << 8;
+ a = a << c;
+ return a;
+}
+/* { dg-final { scan-assembler "lsl\tx\[0-9\]+,\ x\[0-9\]+,\ 8" } } */
+/* { dg-final { scan-assembler "lsl\tx\[0-9\]+,\ x\[0-9\]+,\ x\[0-9\]+" } } */
+
+UInt32x1
+test_lshift_left_int_si (UInt32x1 b, UInt32x1 c)
+{
+ UInt32x1 a;
+
+ a = b << 4;
+ a = a << c;
+ return a;
+}
+/* { dg-final { scan-assembler "lsl\tw\[0-9\]+,\ w\[0-9\]+,\ 4" } } */
+/* { dg-final { scan-assembler "lsl\tw\[0-9\]+,\ w\[0-9\]+,\ w\[0-9\]+" } } */
+
+UInt64x1
+test_lshift_right_int_di (UInt64x1 b, UInt64x1 c)
+{
+ UInt64x1 a;
+
+ a = b >> 8;
+ a = a >> c;
+ return a;
+}
+/* { dg-final { scan-assembler "lsr\tx\[0-9\]+,\ x\[0-9\]+,\ 8" } } */
+/* { dg-final { scan-assembler "lsr\tx\[0-9\]+,\ x\[0-9\]+,\ x\[0-9\]+" } } */
+
+UInt32x1
+test_lshift_right_int_si (UInt32x1 b, UInt32x1 c)
+{
+ UInt32x1 a;
+
+ a = b >> 4;
+ a = a >> c;
+ return a;
+}
+/* { dg-final { scan-assembler "lsr\tw\[0-9\]+,\ w\[0-9\]+,\ 4" } } */
+/* { dg-final { scan-assembler "lsr\tw\[0-9\]+,\ w\[0-9\]+,\ w\[0-9\]+" } } */
+
+Int64x1
+test_ashift_right_int_di (Int64x1 b, Int64x1 c)
+{
+ Int64x1 a;
+
+ a = b >> 8;
+ a = a >> c;
+ return a;
+}
+/* { dg-final { scan-assembler "asr\tx\[0-9\]+,\ x\[0-9\]+,\ 8" } } */
+/* { dg-final { scan-assembler "asr\tx\[0-9\]+,\ x\[0-9\]+,\ x\[0-9\]+" } } */
+
+Int32x1
+test_ashift_right_int_si (Int32x1 b, Int32x1 c)
+{
+ Int32x1 a;
+
+ a = b >> 4;
+ a = a >> c;
+ return a;
+}
+/* { dg-final { scan-assembler "asr\tw\[0-9\]+,\ w\[0-9\]+,\ 4" } } */
+/* { dg-final { scan-assembler "asr\tw\[0-9\]+,\ w\[0-9\]+,\ w\[0-9\]+" } } */
+
+Int64x1
+test_corners_sisd_di (Int64x1 b)
+{
+ force_simd_di (b);
+ b = b >> 63;
+ b = b >> 0;
+ b += b >> 65; /* { dg-warning "right shift count >= width of type" } */
+ force_simd_di (b);
+
+ return b;
+}
+/* { dg-final { scan-assembler "sshr\td\[0-9\]+,\ d\[0-9\]+,\ 63" } } */
+/* { dg-final { scan-assembler "shl\td\[0-9\]+,\ d\[0-9\]+,\ 1" } } */
+
+Int32x1
+test_corners_sisd_si (Int32x1 b)
+{
+ force_simd_si (b);
+ b = b >> 31;
+ b = b >> 0;
+ b += b >> 33; /* { dg-warning "right shift count >= width of type" } */
+ force_simd_si (b);
+
+ return b;
+}
+/* { dg-final { scan-assembler "sshr\tv\[0-9\]+\.2s,\ v\[0-9\]+\.2s,\ 31" } } */
+/* { dg-final { scan-assembler "shl\tv\[0-9\]+\.2s,\ v\[0-9\]+\.2s,\ 1" } } */
+
+
+
+#define CHECK(var,val) \
+do \
+ { \
+ if (var != val) \
+ abort(); \
+ } \
+while(0)
+
+UInt64x1 x = 0xC01dDeadBeefFaceull;
+UInt32x1 y = 0xDeadBeef;
+
+int
+main ()
+{
+ x = test_lshift_left_sisd_di (x, 8);
+ CHECK (x, 0xdeadbeefface0000ull);
+ x = test_lshift_right_int_di (x, 8);
+ CHECK (x, 0x0000deadbeeffaceull);
+ x = test_lshift_right_sisd_di (x, 8);
+ CHECK (x, 0x00000000deadbeefull);
+ x = test_lshift_left_int_di (x, 8);
+ CHECK (x, 0x0000deadbeef0000ull);
+ x = ~x;
+ x = test_ashift_right_int_di (x, 8);
+ CHECK (x, 0xffffffff21524110ull);
+ x = test_ashift_right_sisd_di (x, 8);
+ CHECK (x, 0xffffffffffff2152ull);
+ x = test_corners_sisd_di (x);
+ CHECK (x, 0xfffffffffffffffeull);
+
+ y = test_lshift_left_sisd_si (y, 4);
+ CHECK (y, 0xadbeef00);
+ y = test_lshift_right_int_si (y, 4);
+ CHECK (y, 0x00adbeef);
+ y = test_lshift_right_sisd_si (y, 4);
+ CHECK (y, 0x0000adbe);
+ y = test_lshift_left_int_si (y, 4);
+ CHECK (y, 0x00adbe00);
+ y = ~y;
+ y = test_ashift_right_int_si (y, 4);
+ CHECK (y, 0xffff5241);
+ y = test_ashift_right_sisd_si (y, 4);
+ CHECK (y, 0xffffff52);
+ y = test_corners_sisd_si (y);
+ CHECK (y, 0xfffffffe);
+
+ return 0;
+}
+
+/* { dg-final { cleanup-saved-temps } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/table-intrinsics.c b/gcc/testsuite/gcc.target/aarch64/table-intrinsics.c
index 5d53abe8d10..6281cdae74e 100644
--- a/gcc/testsuite/gcc.target/aarch64/table-intrinsics.c
+++ b/gcc/testsuite/gcc.target/aarch64/table-intrinsics.c
@@ -148,7 +148,7 @@ tb_testp8_4 (poly8x8_t r, poly8x8x4_t tab, uint8x8_t idx)
}
int8x8_t
-qtbl_tests8_ (int8x16_t tab, int8x8_t idx)
+qtbl_tests8_ (int8x16_t tab, uint8x8_t idx)
{
return vqtbl1_s8 (tab, idx);
}
@@ -166,7 +166,7 @@ qtbl_testp8_ (poly8x16_t tab, uint8x8_t idx)
}
int8x8_t
-qtbl_tests8_2 (int8x16x2_t tab, int8x8_t idx)
+qtbl_tests8_2 (int8x16x2_t tab, uint8x8_t idx)
{
return vqtbl2_s8 (tab, idx);
}
@@ -184,7 +184,7 @@ qtbl_testp8_2 (poly8x16x2_t tab, uint8x8_t idx)
}
int8x8_t
-qtbl_tests8_3 (int8x16x3_t tab, int8x8_t idx)
+qtbl_tests8_3 (int8x16x3_t tab, uint8x8_t idx)
{
return vqtbl3_s8 (tab, idx);
}
@@ -202,7 +202,7 @@ qtbl_testp8_3 (poly8x16x3_t tab, uint8x8_t idx)
}
int8x8_t
-qtbl_tests8_4 (int8x16x4_t tab, int8x8_t idx)
+qtbl_tests8_4 (int8x16x4_t tab, uint8x8_t idx)
{
return vqtbl4_s8 (tab, idx);
}
@@ -220,7 +220,7 @@ qtbl_testp8_4 (poly8x16x4_t tab, uint8x8_t idx)
}
int8x8_t
-qtb_tests8_ (int8x8_t r, int8x16_t tab, int8x8_t idx)
+qtb_tests8_ (int8x8_t r, int8x16_t tab, uint8x8_t idx)
{
return vqtbx1_s8 (r, tab, idx);
}
@@ -238,7 +238,7 @@ qtb_testp8_ (poly8x8_t r, poly8x16_t tab, uint8x8_t idx)
}
int8x8_t
-qtb_tests8_2 (int8x8_t r, int8x16x2_t tab, int8x8_t idx)
+qtb_tests8_2 (int8x8_t r, int8x16x2_t tab, uint8x8_t idx)
{
return vqtbx2_s8 (r, tab, idx);
}
@@ -256,7 +256,7 @@ qtb_testp8_2 (poly8x8_t r, poly8x16x2_t tab, uint8x8_t idx)
}
int8x8_t
-qtb_tests8_3 (int8x8_t r, int8x16x3_t tab, int8x8_t idx)
+qtb_tests8_3 (int8x8_t r, int8x16x3_t tab, uint8x8_t idx)
{
return vqtbx3_s8 (r, tab, idx);
}
@@ -274,7 +274,7 @@ qtb_testp8_3 (poly8x8_t r, poly8x16x3_t tab, uint8x8_t idx)
}
int8x8_t
-qtb_tests8_4 (int8x8_t r, int8x16x4_t tab, int8x8_t idx)
+qtb_tests8_4 (int8x8_t r, int8x16x4_t tab, uint8x8_t idx)
{
return vqtbx4_s8 (r, tab, idx);
}
@@ -292,7 +292,7 @@ qtb_testp8_4 (poly8x8_t r, poly8x16x4_t tab, uint8x8_t idx)
}
int8x16_t
-qtblq_tests8_ (int8x16_t tab, int8x16_t idx)
+qtblq_tests8_ (int8x16_t tab, uint8x16_t idx)
{
return vqtbl1q_s8 (tab, idx);
}
@@ -310,7 +310,7 @@ qtblq_testp8_ (poly8x16_t tab, uint8x16_t idx)
}
int8x16_t
-qtblq_tests8_2 (int8x16x2_t tab, int8x16_t idx)
+qtblq_tests8_2 (int8x16x2_t tab, uint8x16_t idx)
{
return vqtbl2q_s8 (tab, idx);
}
@@ -328,7 +328,7 @@ qtblq_testp8_2 (poly8x16x2_t tab, uint8x16_t idx)
}
int8x16_t
-qtblq_tests8_3 (int8x16x3_t tab, int8x16_t idx)
+qtblq_tests8_3 (int8x16x3_t tab, uint8x16_t idx)
{
return vqtbl3q_s8 (tab, idx);
}
@@ -346,7 +346,7 @@ qtblq_testp8_3 (poly8x16x3_t tab, uint8x16_t idx)
}
int8x16_t
-qtblq_tests8_4 (int8x16x4_t tab, int8x16_t idx)
+qtblq_tests8_4 (int8x16x4_t tab, uint8x16_t idx)
{
return vqtbl4q_s8 (tab, idx);
}
@@ -364,7 +364,7 @@ qtblq_testp8_4 (poly8x16x4_t tab, uint8x16_t idx)
}
int8x16_t
-qtbxq_tests8_ (int8x16_t r, int8x16_t tab, int8x16_t idx)
+qtbxq_tests8_ (int8x16_t r, int8x16_t tab, uint8x16_t idx)
{
return vqtbx1q_s8 (r, tab, idx);
}
@@ -382,7 +382,7 @@ qtbxq_testp8_ (poly8x16_t r, poly8x16_t tab, uint8x16_t idx)
}
int8x16_t
-qtbxq_tests8_2 (int8x16_t r, int8x16x2_t tab, int8x16_t idx)
+qtbxq_tests8_2 (int8x16_t r, int8x16x2_t tab, uint8x16_t idx)
{
return vqtbx2q_s8 (r, tab, idx);
}
@@ -400,7 +400,7 @@ qtbxq_testp8_2 (poly8x16_t r, poly8x16x2_t tab, uint8x16_t idx)
}
int8x16_t
-qtbxq_tests8_3 (int8x16_t r, int8x16x3_t tab, int8x16_t idx)
+qtbxq_tests8_3 (int8x16_t r, int8x16x3_t tab, uint8x16_t idx)
{
return vqtbx3q_s8 (r, tab, idx);
}
@@ -418,7 +418,7 @@ qtbxq_testp8_3 (poly8x16_t r, poly8x16x3_t tab, uint8x16_t idx)
}
int8x16_t
-qtbxq_tests8_4 (int8x16_t r, int8x16x4_t tab, int8x16_t idx)
+qtbxq_tests8_4 (int8x16_t r, int8x16x4_t tab, uint8x16_t idx)
{
return vqtbx4q_s8 (r, tab, idx);
}
diff --git a/gcc/testsuite/gcc.target/arc/arc.exp b/gcc/testsuite/gcc.target/arc/arc.exp
new file mode 100644
index 00000000000..83e2762e64a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/arc.exp
@@ -0,0 +1,41 @@
+# Copyright (C) 2007, 2011, 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+# GCC testsuite that uses the `dg.exp' driver.
+
+# Exit immediately if this isn't an arc target.
+if ![istarget arc*-*-*] then {
+ return
+}
+
+# Load support procs.
+load_lib gcc-dg.exp
+
+# If a testcase doesn't have special options, use these.
+global DEFAULT_CFLAGS
+if ![info exists DEFAULT_CFLAGS] then {
+ set DEFAULT_CFLAGS " -ansi -pedantic-errors"
+}
+
+# Initialize `dg'.
+dg-init
+
+# Main loop.
+dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.\[cS\]]] \
+ "" $DEFAULT_CFLAGS
+
+# All done.
+dg-finish
diff --git a/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-1.c b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-1.c
new file mode 100644
index 00000000000..b1990c628e9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-1.c
@@ -0,0 +1,16 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+extern void abort (void);
+
+/* In macros like optimized memset, we want to be able to decide what
+ alignment a passed pointer has. */
+#define f(p) __builtin_arc_aligned (p, 4)
+
+int main (void)
+{
+ int i;
+ if (f (&i) == 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-2.c b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-2.c
new file mode 100644
index 00000000000..d48a915b8bd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-2.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+extern void abort (void);
+
+typedef struct {
+ short x;
+} mytype_t;
+
+mytype_t *__attribute__ ((noinline,weak))
+some_func (void)
+{
+ static mytype_t s;
+ return &s;
+};
+
+int main (void)
+{
+ int y, y2;
+ mytype_t *shorter = some_func();
+ y = __builtin_arc_aligned (shorter, 2);
+ if (!y)
+ abort ();
+ y2 = __builtin_arc_aligned (shorter, 4);
+ if (y2)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-3.c b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-3.c
new file mode 100644
index 00000000000..23d80edd478
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/builtin_arc_aligned-3.c
@@ -0,0 +1,67 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+extern void abort (void);
+
+typedef struct {
+ int b, c;
+}
+__attribute__((aligned(32))) inner_t; // data type is 32 byte aligned
+
+typedef struct {
+ inner_t *inner;
+ int a;
+} outer_t;
+
+void __attribute__ ((noinline,weak))
+somefunc (int a, int b, int c)
+{
+ if (!a || !b || c)
+ abort ();
+};
+
+__attribute__ ((noinline,weak))
+outer_t *
+some_alloc_1 ()
+{
+ static outer_t x;
+ return &x;
+}
+
+__attribute__ ((noinline,weak))
+inner_t *
+some_alloc_2 ()
+{
+ static inner_t x;
+ return &x;
+}
+
+int main (void)
+{
+ int y, y2, y3;
+ // @p_out is pointing to instance of outer_t, naturally aligned to 4+4 = 8
+ // and not gauranteed be 32 byte aligned.
+ outer_t *p_out = some_alloc_1( ); // returns 8 byte aligned ptr
+
+ // @ptr is pointing to instance of inner_t which is naturally aligned to 32.
+ // It is assigned to p_out->inner which is of type inner_t thus 32 byte
+ // aligned as well
+ // Note that gcc can deduce p_out->inner is 32b aligned, not at runtime,
+ // because it was assigned @ptr, but even at compile time, because it's data
+ // type is naturally 32 byte aligned.
+ inner_t *ptr = some_alloc_2(); // returns 32 byte aligned ptr
+ p_out->inner = ptr; // this ptr will also be 32 byte aligned
+
+ y = __builtin_arc_aligned(ptr, 32); // this shd return 1
+ y2 = __builtin_arc_aligned(p_out->inner, 32); // this also shd return 1
+ // Although p_out->inner ptr is 32 byte aligned,
+ // it's container &(p_out->inner) need not be.
+ // That is because the hoister has no relation to contents.
+ // p_out is not gauranteed to be 32 byte
+ // aligned, so it's member @inner in p_out need not be.
+ y3 = __builtin_arc_aligned(&(p_out->inner), 32);
+ // compiler not sure, so must return 0
+
+ somefunc(y, y2, y3);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arc/cond-set-use.c b/gcc/testsuite/gcc.target/arc/cond-set-use.c
new file mode 100644
index 00000000000..aee27251a5c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/cond-set-use.c
@@ -0,0 +1,128 @@
+/* { dg-do run } */
+/* { dg-options "-Os" } */
+
+/* Based on gethostbyname_r,
+ * Copyright (C) 2000-2006 Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB
+ *
+ * Extraction / wrapping as test by
+ * Joern Rennecke <joern.rennecke@embecosm.com>
+ * Copyright (C) 2013 Free Software Foundation, Inc.
+ */
+
+typedef unsigned size_t;
+typedef int ssize_t;
+typedef unsigned uint32_t;
+struct resolv_answer {
+ char *dotted;
+ int atype;
+ int aclass;
+ int ttl;
+ int rdlength;
+ const unsigned char *rdata;
+ int rdoffset;
+ char* buf;
+ size_t buflen;
+ size_t add_count;
+};
+struct hostent
+{
+ char *h_name;
+ char **h_aliases;
+ int h_addrtype;
+ int h_length;
+ char **h_addr_list;
+};
+
+int *__attribute__ ((noinline,weak)) nop (void * p) { return p; };
+void __attribute__ ((noinline,weak)) seta (struct resolv_answer * p)
+{ p->atype = 1;}
+
+int ghostbyname_r(
+ struct hostent *result_buf,
+ char *buf,
+ size_t buflen,
+ struct hostent **result,
+ int *h_errnop)
+{
+ char **addr_list;
+ char **alias;
+ char *alias0;
+ int i0;
+ struct resolv_answer a;
+ int i;
+
+ *result = ((void *)0);
+
+ *h_errnop = -1;
+
+ if ((ssize_t)buflen <= 5)
+ return 34;
+
+ alias = (char **)buf;
+ addr_list = (char **)buf;
+
+ /* This got turned into branch with conditional move in delay slot. */
+ if ((ssize_t)buflen < 256)
+ return 34;
+
+
+ {
+ if (!nop(&i0)) {
+ result_buf->h_aliases = alias;
+ result_buf->h_addrtype = 2;
+ result_buf->h_length = 4;
+ result_buf->h_addr_list = addr_list;
+ *result = result_buf;
+ *h_errnop = 0;
+ return 0;
+ }
+ }
+
+
+ seta (&a);
+
+ if (a.atype == 1) {
+
+ int need_bytes = sizeof(addr_list[0]) * (a.add_count + 1 + 1);
+
+ int ips_len = a.add_count * a.rdlength;
+
+ buflen -= (need_bytes + ips_len);
+ if ((ssize_t)buflen < 0) {
+ i = 34;
+ goto free_and_ret;
+ }
+
+ result_buf->h_addrtype = 2;
+ *result = result_buf;
+ *h_errnop = 0;
+ i = 0;
+ goto free_and_ret;
+ }
+
+ /* For cse, the 1 was is loaded into a call-saved register;
+ the load was hoisted into a delay slot before the conditional load,
+ clobbering result_buf, which (conditionally) lived in the same
+ call-saved register, because mark_referenced_resources considered the
+ destination of the COND_EXEC only clobbered, but not used. */
+ *h_errnop = 1;
+ *nop(&i0) = 1;
+ i = 2;
+
+ free_and_ret:
+ nop (&i0);
+ return i;
+}
+
+int
+main ()
+{
+ struct hostent buf, *res;
+ int i;
+ char c;
+ ghostbyname_r (&buf, &c, 1024, &res, &i);
+ ghostbyname_r (&buf, 0, 1024, &res, &i);
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-1.c b/gcc/testsuite/gcc.target/arc/interrupt-1.c
new file mode 100644
index 00000000000..70514572ea5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/interrupt-1.c
@@ -0,0 +1,5 @@
+void __attribute__ ((interrupt("ilink1")))
+handler1 (void)
+{
+}
+/* { dg-final { scan-assembler-times "j.*\[ilink1\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-2.c b/gcc/testsuite/gcc.target/arc/interrupt-2.c
new file mode 100644
index 00000000000..ee8593b3039
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/interrupt-2.c
@@ -0,0 +1,5 @@
+void __attribute__ ((interrupt("ilink2")))
+handler1 (void)
+{
+}
+/* { dg-final { scan-assembler-times "j.*\[ilink2\]" 1 } } */
diff --git a/gcc/testsuite/gcc.target/arc/interrupt-3.c b/gcc/testsuite/gcc.target/arc/interrupt-3.c
new file mode 100644
index 00000000000..fa598d67e6b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/interrupt-3.c
@@ -0,0 +1,14 @@
+void __attribute__ ((interrupt))
+handler0 (void)
+{ /* { dg-error "wrong number of arguments specified" } */
+}
+
+void __attribute__ ((interrupt("you load too")))
+handler1 (void)
+{ /* { dg-warning "is not \"ilink1\" or \"ilink2\"" } */
+}
+
+void __attribute__ ((interrupt(42)))
+hander2 (void)
+{ /* { dg-warning "is not a string constant" } */
+}
diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
new file mode 100644
index 00000000000..398ecfe948e
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-1.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mARC700 --save-temps" } */
+
+#include <stdlib.h>
+
+/* Hide value propagation from the optimizers. */
+static int
+id (int i)
+{
+ asm ("": "+Xr" (i));
+ return i;
+}
+
+static int
+mulhigh (unsigned a, unsigned b)
+{
+ return (unsigned long long) a * b >> 32;
+}
+
+int
+main (void)
+{
+ if (mulhigh (id (0x12345678), id (0x90abcdef)) != 0xa49a83e)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler "mpyhu\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
new file mode 100644
index 00000000000..ccc74e7b1ad
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/mulsi3_highpart-2.c
@@ -0,0 +1,30 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -mARC700 --save-temps -mno-mpy" } */
+
+#include <stdlib.h>
+
+/* Hide value propagation from the optimizers. */
+static int
+id (int i)
+{
+ asm ("": "+Xr" (i));
+ return i;
+}
+
+static int
+mulhigh (unsigned a, unsigned b)
+{
+ return (unsigned long long) a * b >> 32;
+}
+
+int
+main (void)
+{
+ if (mulhigh (id (0x12345678), id (0x90abcdef)) != 0xa49a83e)
+ abort ();
+ return 0;
+}
+
+/* { dg-final { scan-assembler-not "mpyhu\[ \t\]" } } */
+/* { dg-final { scan-assembler-not "@__muldi3" } } */
+/* { dg-final { scan-assembler "@__umulsi3_highpart" } } */
diff --git a/gcc/testsuite/gcc.target/arc/nv-cache.c b/gcc/testsuite/gcc.target/arc/nv-cache.c
new file mode 100644
index 00000000000..9687195981c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/nv-cache.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-volatile-cache" } */
+
+volatile int i;
+void f (void)
+{
+ i = 0;
+}
+/* { dg-final { scan-assembler "st\.di" } } */
diff --git a/gcc/testsuite/gcc.target/arc/sdata-1.c b/gcc/testsuite/gcc.target/arc/sdata-1.c
new file mode 100644
index 00000000000..3d8366c1564
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/sdata-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msdata" } */
+
+int i;
+
+int f (void)
+{
+ return i;
+}
+/* { dg-final { scan-assembler "@sda" } } */
diff --git a/gcc/testsuite/gcc.target/arc/sdata-2.c b/gcc/testsuite/gcc.target/arc/sdata-2.c
new file mode 100644
index 00000000000..ebaa25e7267
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/sdata-2.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-sdata" } */
+
+int i;
+
+int f (void)
+{
+ return i;
+}
+/* { dg-final { scan-assembler-not "@sda" } } */
diff --git a/gcc/testsuite/gcc.target/arc/v-cache.c b/gcc/testsuite/gcc.target/arc/v-cache.c
new file mode 100644
index 00000000000..7722c433581
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/v-cache.c
@@ -0,0 +1,9 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mvolatile-cache" } */
+
+volatile int i;
+void f (void)
+{
+ i = 0;
+}
+/* { dg-final { scan-assembler-not "st\.di" } } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c b/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c
index 1c1028ce147..1eabb26ef4d 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-comp-swap-release-acquire.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c b/gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c
index 2f091f29057..ccfa31c34e3 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-acq_rel.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-acquire.c b/gcc/testsuite/gcc.target/arm/atomic-op-acquire.c
index 977c2fab97c..52bcf99e83c 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-acquire.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-acquire.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-char.c b/gcc/testsuite/gcc.target/arm/atomic-op-char.c
index 63e34c1d3e8..0c30922dbaa 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-char.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-char.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-consume.c b/gcc/testsuite/gcc.target/arm/atomic-op-consume.c
index 8e1779e2381..0354717cb70 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-consume.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-consume.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-int.c b/gcc/testsuite/gcc.target/arm/atomic-op-int.c
index 1476c52607a..7716994f0d0 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-int.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-int.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c b/gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c
index cae83230bd9..4b72fd95bc3 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-relaxed.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-release.c b/gcc/testsuite/gcc.target/arm/atomic-op-release.c
index ed90aab2edd..8582e4f1d97 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-release.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-release.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c b/gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c
index c7b93eb6d61..70b5b9ebb6c 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-seq_cst.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/atomic-op-short.c b/gcc/testsuite/gcc.target/arm/atomic-op-short.c
index f4d6262e005..a6f5a6df617 100644
--- a/gcc/testsuite/gcc.target/arm/atomic-op-short.c
+++ b/gcc/testsuite/gcc.target/arm/atomic-op-short.c
@@ -1,5 +1,5 @@
-/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-do compile } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* { dg-options "-O2" } */
/* { dg-add-options arm_arch_v8a } */
diff --git a/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c b/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c
new file mode 100644
index 00000000000..f466ff35f89
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/ivopts-orig_biv-inc.c
@@ -0,0 +1,19 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-ivopts-details" } */
+/* { dg-skip-if "" { arm_thumb1 } } */
+
+extern char *__ctype_ptr__;
+
+unsigned char * foo(unsigned char *ReadPtr)
+{
+
+ unsigned char c;
+
+ while (!(((__ctype_ptr__+sizeof(""[*ReadPtr]))[(int)(*ReadPtr)])&04) == (!(0)))
+ ReadPtr++;
+
+ return ReadPtr;
+}
+
+/* { dg-final { scan-tree-dump-times "original biv" 2 "ivopts"} } */
+/* { dg-final { cleanup-tree-dump "ivopts" } } */
diff --git a/gcc/testsuite/gcc.target/arm/lp1189445.c b/gcc/testsuite/gcc.target/arm/lp1189445.c
new file mode 100644
index 00000000000..766748e5509
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/lp1189445.c
@@ -0,0 +1,18 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon } */
+/* { dg-add-options arm_neon } */
+/* { dg-options "-O3" } */
+
+int id;
+int
+test (const long int *data)
+{
+ int i, retval;
+ retval = id;
+ for (i = 0; i < id; i++)
+ {
+ retval &= (data[i] <= 0);
+ }
+
+ return (retval);
+}
diff --git a/gcc/testsuite/gcc.target/arm/neon-for-64bits-2.c b/gcc/testsuite/gcc.target/arm/neon-for-64bits-2.c
deleted file mode 100644
index 035bfb77a37..00000000000
--- a/gcc/testsuite/gcc.target/arm/neon-for-64bits-2.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Check that Neon is used to handle 64-bits scalar operations. */
-
-/* { dg-do compile } */
-/* { dg-require-effective-target arm_neon_ok } */
-/* { dg-options "-O2 -mneon-for-64bits" } */
-/* { dg-add-options arm_neon } */
-
-typedef long long i64;
-typedef unsigned long long u64;
-typedef unsigned int u32;
-typedef int i32;
-
-/* Unary operators */
-#define UNARY_OP(name, op) \
- void unary_##name(u64 *a, u64 *b) { *a = op (*b + 0x1234567812345678ULL) ; }
-
-/* Binary operators */
-#define BINARY_OP(name, op) \
- void binary_##name(u64 *a, u64 *b, u64 *c) { *a = *b op *c ; }
-
-/* Unsigned shift */
-#define SHIFT_U(name, op, amount) \
- void ushift_##name(u64 *a, u64 *b, int c) { *a = *b op amount; }
-
-/* Signed shift */
-#define SHIFT_S(name, op, amount) \
- void sshift_##name(i64 *a, i64 *b, int c) { *a = *b op amount; }
-
-UNARY_OP(not, ~)
-
-BINARY_OP(add, +)
-BINARY_OP(sub, -)
-BINARY_OP(and, &)
-BINARY_OP(or, |)
-BINARY_OP(xor, ^)
-
-SHIFT_U(right1, >>, 1)
-SHIFT_U(right2, >>, 2)
-SHIFT_U(right5, >>, 5)
-SHIFT_U(rightn, >>, c)
-
-SHIFT_S(right1, >>, 1)
-SHIFT_S(right2, >>, 2)
-SHIFT_S(right5, >>, 5)
-SHIFT_S(rightn, >>, c)
-
-/* { dg-final {scan-assembler-times "vmvn" 1} } */
-/* Two vadd: 1 in unary_not, 1 in binary_add */
-/* { dg-final {scan-assembler-times "vadd" 2} } */
-/* { dg-final {scan-assembler-times "vsub" 1} } */
-/* { dg-final {scan-assembler-times "vand" 1} } */
-/* { dg-final {scan-assembler-times "vorr" 1} } */
-/* { dg-final {scan-assembler-times "veor" 1} } */
-/* 6 vshr for right shifts by constant, and variable right shift uses
- vshl with a negative amount in register. */
-/* { dg-final {scan-assembler-times "vshr" 6} } */
-/* { dg-final {scan-assembler-times "vshl" 2} } */
diff --git a/gcc/testsuite/gcc.target/arm/pr19599.c b/gcc/testsuite/gcc.target/arm/pr19599.c
index e3e066cf820..c3ee22017e6 100644
--- a/gcc/testsuite/gcc.target/arm/pr19599.c
+++ b/gcc/testsuite/gcc.target/arm/pr19599.c
@@ -1,4 +1,4 @@
-/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" } { "" } } */
+/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" "-mthumb" } { "" } } */
/* { dg-options "-O2 -march=armv5te -marm" } */
/* { dg-final { scan-assembler "bx" } } */
diff --git a/gcc/testsuite/gcc.target/arm/pr46975-2.c b/gcc/testsuite/gcc.target/arm/pr46975-2.c
new file mode 100644
index 00000000000..f4017e3f78d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr46975-2.c
@@ -0,0 +1,10 @@
+/* { dg-options "-mthumb -O2" } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-final { scan-assembler "sub" } } */
+/* { dg-final { scan-assembler "clz" } } */
+/* { dg-final { scan-assembler "lsr.*#5" } } */
+
+int foo (int s)
+{
+ return s == 1;
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr57637.c b/gcc/testsuite/gcc.target/arm/pr57637.c
new file mode 100644
index 00000000000..2b9bfdded7f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr57637.c
@@ -0,0 +1,206 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -fno-inline" } */
+
+typedef struct _GtkCssStyleProperty GtkCssStyleProperty;
+
+struct _GtkCssStyleProperty
+{
+ int *initial_value;
+ unsigned int id;
+ unsigned int inherit :1;
+ unsigned int animated :1;
+ unsigned int affects_size :1;
+ unsigned int affects_font :1;
+
+ int * parse_value;
+ int * query_value;
+ int * assign_value;
+};
+
+void
+g_assertion_message_expr (const char *domain,
+ const char *file,
+ int line,
+ const char *func,
+ const char *expr) __attribute__((__noreturn__));
+
+void
+g_assertion_message_expr (const char *domain,
+ const char *file,
+ int line,
+ const char *func,
+ const char *expr)
+{
+ __builtin_abort ();
+}
+int
+get_id (GtkCssStyleProperty *property)
+{
+ return 1;
+}
+int
+_gtk_css_style_property_get_type ()
+{
+ return 1;
+}
+
+GtkCssStyleProperty *
+g_object_new (int object_type,
+ const char *first_property_name,
+ ...)
+{
+ return (GtkCssStyleProperty *) __builtin_malloc (sizeof (GtkCssStyleProperty));
+}
+
+typedef enum {
+ INHERIT = (1 << 0),
+ ANIMATED = (1 << 1),
+ RESIZE = (1 << 2),
+ FONT = (1 << 3)
+} GtkStylePropertyFlags;
+
+int t = 0;
+void
+gtk_css_style_property_register (const char * name,
+ int expected_id,
+ int value_type,
+ int flags,
+ int *parse_value,
+ int *query_value,
+ int *assign_value,
+ int *initial_value)
+{
+ GtkCssStyleProperty *node;
+
+ do
+ {
+ if (__builtin_expect (__extension__ (
+ {
+ int _g_boolean_var_;
+ if (initial_value != ((void *)0))
+ _g_boolean_var_ = 1;
+ else
+ _g_boolean_var_ = 0;
+ _g_boolean_var_;
+ }),
+ 1))
+ ;
+ else
+ g_assertion_message_expr ("Gtk",
+ "gtkcssstylepropertyimpl.c",
+ 85,
+ ((const char*) (__PRETTY_FUNCTION__)),
+ "initial_value != NULL");
+ } while (0);
+
+ do
+ {
+ if (__builtin_expect (__extension__ (
+ {
+ int _g_boolean_var_;
+ if (parse_value != ((void *)0))
+ _g_boolean_var_ = 1;
+ else
+ _g_boolean_var_ = 0;
+ _g_boolean_var_;
+ }),
+ 1))
+ ;
+ else
+ g_assertion_message_expr ("Gtk",
+ "gtkcssstylepropertyimpl.c",
+ 86,
+ ((const char*) (__PRETTY_FUNCTION__)),
+ "parse_value != NULL");
+ } while (0);
+
+ do
+ {
+ if (__builtin_expect (__extension__ (
+ {
+ int _g_boolean_var_;
+ if (value_type == ((int) ((1) << (2)))
+ || query_value != ((void *)0))
+ _g_boolean_var_ = 1;
+ else
+ _g_boolean_var_ = 0;
+ _g_boolean_var_;
+ }),
+ 1))
+ ;
+ else
+ g_assertion_message_expr ("Gtk",
+ "gtkcssstylepropertyimpl.c",
+ 87, ((const char*) (__PRETTY_FUNCTION__)),
+ "value_type == NONE || query_value != NULL");
+ } while (0);
+
+ /* FLAGS is changed in a cond_exec instruction with pr57637. */
+ if (flags == 15)
+ t = 15;
+
+ do
+ {
+ if (__builtin_expect (__extension__ (
+ {
+ int _g_boolean_var_;
+ if (value_type == ((1) << (2))
+ || assign_value != ((void *)0))
+ _g_boolean_var_ = 1;
+ else
+ _g_boolean_var_ = 0;
+ _g_boolean_var_;
+ }),
+ 1))
+ ;
+ else
+ g_assertion_message_expr ("Gtk",
+ "gtkcssstylepropertyimpl.c",
+ 88, ((const char*) (__PRETTY_FUNCTION__)),
+ "value_type == NONE || assign_value != NULL");
+ } while (0);
+
+ node = g_object_new ((_gtk_css_style_property_get_type ()),
+ "value-type", value_type,
+ "affects-size", (flags & RESIZE) ? (0) : (!(0)),
+ "affects-font", (flags & FONT) ? (!(0)) : (0),
+ "animated", (flags & ANIMATED) ? (!(0)) : (0),
+ "inherit", (flags & INHERIT) ? (!(0)) : (0),
+ "initial-value", initial_value,
+ "name", name,
+ ((void *)0));
+
+ node->parse_value = parse_value;
+ node->query_value = query_value;
+ node->assign_value = assign_value;
+
+ do
+ {
+ if (__builtin_expect (__extension__ (
+ {
+ int _g_boolean_var_;
+ if (get_id (node) == expected_id)
+ _g_boolean_var_ = 1;
+ else
+ _g_boolean_var_ = 0;
+ _g_boolean_var_;
+ }),
+ 1))
+ ;
+ else
+ g_assertion_message_expr ("Gtk",
+ "gtkcssstylepropertyimpl.c",
+ 106,
+ ((const char*) (__PRETTY_FUNCTION__)),
+ "get_id (node) == expected_id");
+ } while (0);
+}
+
+int main ()
+{
+ gtk_css_style_property_register ("test", 1, 4, 15, &t, &t, &t, &t);
+
+ if (t != 15)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/arm/pr58041.c b/gcc/testsuite/gcc.target/arm/pr58041.c
new file mode 100644
index 00000000000..481a72b81c7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr58041.c
@@ -0,0 +1,30 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -mno-unaligned-access" } */
+/* { dg-final { scan-assembler "ldrb" } } */
+/* { dg-final { scan-assembler "strb" } } */
+
+struct s
+{
+ char u;
+ long long v[2];
+} __attribute__((packed,aligned(1)));
+
+__attribute__((noinline, noclone))
+long long foo(struct s *x, int y, long long z)
+{
+ long long a = x->v[y];
+ x->v[y] = z;
+ return a;
+}
+
+struct s a = {0,{0,0}};
+int main()
+{
+ if (foo(&a,0,1) != 0)
+ __builtin_abort();
+ if (foo(&a,0,2) != 1)
+ __builtin_abort();
+ if (foo(&a,1,1) != 0)
+ __builtin_abort();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/avr/progmem-error-1.cpp b/gcc/testsuite/gcc.target/avr/progmem-error-1.cpp
index cf53cc8e92b..934b93c15a0 100644
--- a/gcc/testsuite/gcc.target/avr/progmem-error-1.cpp
+++ b/gcc/testsuite/gcc.target/avr/progmem-error-1.cpp
@@ -2,4 +2,4 @@
#include "progmem.h"
-char str[] PROGMEM = "Hallo"; /* { dg-error "must be const" } */
+char str[] PROGMEM = "Hallo"; /* { dg-error "must be const" "" { target avr-*-* } 1 } */
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c
new file mode 100644
index 00000000000..a2b66d966d0
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:-1:align" } */
+/* { dg-final { scan-assembler-times "movdqa" 8 { target { ! { ia32 } } } } } */
+/* { dg-final { scan-assembler-times "movdqa" 4 { target { ia32 } } } } */
+
+char a[2048];
+char b[2048];
+void t (void)
+{
+ __builtin_memcpy (a, b, 2048);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c
new file mode 100644
index 00000000000..c2f49f0cc5f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-2.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:3000:align,libcall:-1:align" } */
+/* { dg-final { scan-assembler-times "movdqa" 8 { target { ! { ia32 } } } } } */
+/* { dg-final { scan-assembler-times "movdqa" 4 { target { ia32 } } } } */
+
+char a[2048];
+char b[2048];
+void t (void)
+{
+ __builtin_memcpy (a, b, 2048);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/memcpy-strategy-3.c b/gcc/testsuite/gcc.target/i386/memcpy-strategy-3.c
new file mode 100644
index 00000000000..ddd1ef7c0b2
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memcpy-strategy-3.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=atom -mmemcpy-strategy=vector_loop:2000:align,libcall:-1:align" } */
+/* { dg-final { scan-assembler-times "memcpy" 2 } } */
+
+char a[2048];
+char b[2048];
+void t (void)
+{
+ __builtin_memcpy (a, b, 2048);
+}
diff --git a/gcc/testsuite/gcc.target/i386/memset-strategy-1.c b/gcc/testsuite/gcc.target/i386/memset-strategy-1.c
new file mode 100644
index 00000000000..d1b97c5df10
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/memset-strategy-1.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -march=atom -mmemset-strategy=libcall:-1:align" } */
+/* { dg-final { scan-assembler-times "memset" 2 } } */
+
+char a[2048];
+void t (void)
+{
+ __builtin_memset (a, 1, 2048);
+}
+
diff --git a/gcc/testsuite/gcc.target/i386/movabs-1.c b/gcc/testsuite/gcc.target/i386/movabs-1.c
new file mode 100644
index 00000000000..75ef8d2a6cb
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/movabs-1.c
@@ -0,0 +1,10 @@
+/* { dg-do assemble } */
+/* { dg-options "-O2 -masm=intel" } */
+/* { dg-require-effective-target lp64 } */
+/* { dg-require-effective-target masm_intel } */
+
+void
+foo (void)
+{
+ *(volatile long*)0xFFFF800000000000 = -1;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr58048.c b/gcc/testsuite/gcc.target/i386/pr58048.c
new file mode 100644
index 00000000000..a7249d0a910
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr58048.c
@@ -0,0 +1,11 @@
+/* PR target/58048 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+void
+div3 (void)
+{
+ double tmp1;
+
+ asm volatile ("fscale":"=t" (tmp1):"0" (0), "u" (0)); /* { dg-error "inconsistent operand constraints in an 'asm'" } */
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr58137.c b/gcc/testsuite/gcc.target/i386/pr58137.c
new file mode 100644
index 00000000000..0a7daf83cd5
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr58137.c
@@ -0,0 +1,33 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -mavx2" } */
+
+typedef unsigned int U32;
+
+struct sv {
+ void* sv_any;
+ U32 sv_refcnt;
+ U32 sv_flags;
+};
+typedef struct sv SV;
+
+struct xrv {
+ SV * xrv_rv;
+};
+typedef struct xrv XRV;
+
+extern XRV * PL_xrv_root;
+
+void
+more_xrv (void)
+{
+ register XRV* xrv;
+ register XRV* xrvend;
+ xrv = PL_xrv_root;
+ xrvend = &xrv[200 / sizeof (XRV) - 1];
+ while (xrv < xrvend)
+ {
+ xrv->xrv_rv = (SV*)(xrv + 1);
+ xrv++;
+ }
+ xrv->xrv_rv = 0;
+}
diff --git a/gcc/testsuite/gcc.target/i386/pr58218.c b/gcc/testsuite/gcc.target/i386/pr58218.c
new file mode 100644
index 00000000000..4145242059f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr58218.c
@@ -0,0 +1,5 @@
+/* PR target/58218 */
+/* { dg-do assemble { target lp64 } } */
+/* { dg-options "-mcmodel=medium" } */
+
+struct { float x[16385]; } a = { { 0.f, } };
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-1.c b/gcc/testsuite/gcc.target/mips/code-readable-1.c
index 34c2c0a770a..b3e864df6fb 100644
--- a/gcc/testsuite/gcc.target/mips/code-readable-1.c
+++ b/gcc/testsuite/gcc.target/mips/code-readable-1.c
@@ -8,6 +8,10 @@ volatile int x4;
volatile int x5;
volatile int x6;
volatile int x7;
+volatile int x8;
+volatile int x9;
+volatile int x10;
+volatile int x11;
MIPS16 int
foo (int i, volatile *x)
@@ -21,6 +25,10 @@ foo (int i, volatile *x)
case 5: return x5 + x[4];
case 6: return x6 + x[5];
case 7: return x7 + x[6];
+ case 8: return x8 + x[7];
+ case 9: return x9 + x[8];
+ case 10: return x10 + x[9];
+ case 11: return x11 + x[10];
default: return 0;
}
}
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-2.c b/gcc/testsuite/gcc.target/mips/code-readable-2.c
index 71aeb132c0c..3d325049d59 100644
--- a/gcc/testsuite/gcc.target/mips/code-readable-2.c
+++ b/gcc/testsuite/gcc.target/mips/code-readable-2.c
@@ -7,6 +7,10 @@ volatile int x4;
volatile int x5;
volatile int x6;
volatile int x7;
+volatile int x8;
+volatile int x9;
+volatile int x10;
+volatile int x11;
MIPS16 int
foo (int i, volatile *x)
@@ -20,6 +24,10 @@ foo (int i, volatile *x)
case 5: return x5 + x[4];
case 6: return x6 + x[5];
case 7: return x7 + x[6];
+ case 8: return x8 + x[7];
+ case 9: return x9 + x[8];
+ case 10: return x10 + x[9];
+ case 11: return x11 + x[10];
default: return 0;
}
}
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-3.c b/gcc/testsuite/gcc.target/mips/code-readable-3.c
index fc785055196..aaf18749374 100644
--- a/gcc/testsuite/gcc.target/mips/code-readable-3.c
+++ b/gcc/testsuite/gcc.target/mips/code-readable-3.c
@@ -7,6 +7,10 @@ volatile int x4;
volatile int x5;
volatile int x6;
volatile int x7;
+volatile int x8;
+volatile int x9;
+volatile int x10;
+volatile int x11;
MIPS16 int
foo (int i, volatile *x)
@@ -20,6 +24,10 @@ foo (int i, volatile *x)
case 5: return x5 + x[4];
case 6: return x6 + x[5];
case 7: return x7 + x[6];
+ case 8: return x8 + x[7];
+ case 9: return x9 + x[8];
+ case 10: return x10 + x[9];
+ case 11: return x11 + x[10];
default: return 0;
}
}
diff --git a/gcc/testsuite/gcc.target/mips/code-readable-4.c b/gcc/testsuite/gcc.target/mips/code-readable-4.c
index ae8ff8a1a66..4db89f87466 100644
--- a/gcc/testsuite/gcc.target/mips/code-readable-4.c
+++ b/gcc/testsuite/gcc.target/mips/code-readable-4.c
@@ -8,6 +8,10 @@ volatile int x4;
volatile int x5;
volatile int x6;
volatile int x7;
+volatile int x8;
+volatile int x9;
+volatile int x10;
+volatile int x11;
MIPS16 int
foo (int i, volatile *x)
@@ -21,6 +25,10 @@ foo (int i, volatile *x)
case 5: return x5 + x[4];
case 6: return x6 + x[5];
case 7: return x7 + x[6];
+ case 8: return x8 + x[7];
+ case 9: return x9 + x[8];
+ case 10: return x10 + x[9];
+ case 11: return x11 + x[10];
default: return 0;
}
}
diff --git a/gcc/testsuite/gcc.target/mips/fabs-2008.c b/gcc/testsuite/gcc.target/mips/fabs-2008.c
new file mode 100644
index 00000000000..211d561d478
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fabs-2008.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=2008" } */
+
+NOMIPS16 double
+fabs_2008 (double d)
+{
+ return __builtin_fabs (d);
+}
+
+/* { dg-final { scan-assembler "\tabs\\.d\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fabs-legacy.c b/gcc/testsuite/gcc.target/mips/fabs-legacy.c
new file mode 100644
index 00000000000..dabc9d09c17
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fabs-legacy.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=legacy" } */
+
+NOMIPS16 double
+fabs_legacy (double d)
+{
+ return __builtin_fabs (d);
+}
+
+/* { dg-final { scan-assembler-not "\tabs\\.d\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fabsf-2008.c b/gcc/testsuite/gcc.target/mips/fabsf-2008.c
new file mode 100644
index 00000000000..2b0363abc69
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fabsf-2008.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=2008" } */
+
+NOMIPS16 float
+fabsf_2008 (float f)
+{
+ return __builtin_fabsf (f);
+}
+
+/* { dg-final { scan-assembler "\tabs\\.s\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fabsf-legacy.c b/gcc/testsuite/gcc.target/mips/fabsf-legacy.c
new file mode 100644
index 00000000000..7278f7d7738
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fabsf-legacy.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=legacy" } */
+
+NOMIPS16 float
+fabsf_legacy (float f)
+{
+ return __builtin_fabsf (f);
+}
+
+/* { dg-final { scan-assembler-not "\tabs\\.s\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fneg-2008.c b/gcc/testsuite/gcc.target/mips/fneg-2008.c
new file mode 100644
index 00000000000..899268af737
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fneg-2008.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=2008" } */
+
+NOMIPS16 double
+fneg_2008 (double d)
+{
+ return -d;
+}
+
+/* { dg-final { scan-assembler "\tneg\\.d\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fneg-legacy.c b/gcc/testsuite/gcc.target/mips/fneg-legacy.c
new file mode 100644
index 00000000000..38f810cf952
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fneg-legacy.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=legacy" } */
+
+NOMIPS16 double
+fneg_legacy (double d)
+{
+ return -d;
+}
+
+/* { dg-final { scan-assembler-not "\tneg\\.d\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fnegf-2008.c b/gcc/testsuite/gcc.target/mips/fnegf-2008.c
new file mode 100644
index 00000000000..a64a6e6937c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fnegf-2008.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=2008" } */
+
+NOMIPS16 float
+fnegf_2008 (float f)
+{
+ return -f;
+}
+
+/* { dg-final { scan-assembler "\tneg\\.s\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/fnegf-legacy.c b/gcc/testsuite/gcc.target/mips/fnegf-legacy.c
new file mode 100644
index 00000000000..e628c2bd006
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/fnegf-legacy.c
@@ -0,0 +1,10 @@
+/* { dg-do compile } */
+/* { dg-options "-mabs=legacy" } */
+
+NOMIPS16 float
+fnegf_legacy (float f)
+{
+ return -f;
+}
+
+/* { dg-final { scan-assembler-not "\tneg\\.s\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/mips.exp b/gcc/testsuite/gcc.target/mips/mips.exp
index 54c97db2481..1f0d0d6223f 100644
--- a/gcc/testsuite/gcc.target/mips/mips.exp
+++ b/gcc/testsuite/gcc.target/mips/mips.exp
@@ -276,8 +276,10 @@ foreach option {
# Add -mfoo= options to mips_option_groups.
foreach option {
+ abs
branch-cost
code-readable
+ nan
r10k-cache-barrier
tune
} {
@@ -705,6 +707,18 @@ proc mips-dg-init {} {
"-msoft-float",
#endif
+ #ifdef __mips_abs2008
+ "-mabs=2008",
+ #else
+ "-mabs=legacy",
+ #endif
+
+ #ifdef __mips_nan2008
+ "-mnan=2008",
+ #else
+ "-mnan=legacy",
+ #endif
+
#if __mips_fpr == 64
"-mfp64",
#else
@@ -826,6 +840,8 @@ proc mips-dg-finish {} {
# | |
# -mfp64 -mfp32
# | |
+# -mabs=2008/-mabs=legacy <no option>
+# | |
# -mhard-float -msoft-float
# | |
# -mno-sym32 -msym32
@@ -913,6 +929,8 @@ proc mips-dg-options { args } {
mips_option_dependency options "-mips3d" "-mpaired-single"
mips_option_dependency options "-mpaired-single" "-mfp64"
mips_option_dependency options "-mfp64" "-mhard-float"
+ mips_option_dependency options "-mabs=2008" "-mhard-float"
+ mips_option_dependency options "-mabs=legacy" "-mhard-float"
mips_option_dependency options "-mrelax-pic-calls" "-mno-plt"
mips_option_dependency options "-mrelax-pic-calls" "-mabicalls"
mips_option_dependency options "-mrelax-pic-calls" "-mexplicit-relocs"
@@ -1146,7 +1164,7 @@ proc mips-dg-options { args } {
if { [mips_using_mips16_p options]
&& ![mips_same_option_p $abi "-mabi=32"]
&& ![mips_same_option_p $abi "-mabi=o64"]
- && (![mips_have_option_p options "addressing=absolute"]
+ && ([mips_have_option_p options "-mabicalls"]
|| [mips_have_option_p options "-mhard-float"]) } {
if { [mips_test_option_p options mips16] } {
mips_make_test_option options "addressing=absolute"
diff --git a/gcc/testsuite/gcc.target/mips/mulsize-1.c b/gcc/testsuite/gcc.target/mips/mulsize-1.c
index 4dd5a19a985..0997fd93458 100644
--- a/gcc/testsuite/gcc.target/mips/mulsize-1.c
+++ b/gcc/testsuite/gcc.target/mips/mulsize-1.c
@@ -1,4 +1,5 @@
/* { dg-final { scan-assembler "\t.globl\tf7" } } */
+/* { dg-final { scan-assembler "\tsll\t" } } */
/* { dg-final { scan-assembler "\tsubu\t" } } */
/* { dg-final { scan-assembler-not "\tli\t" } } */
/* { dg-final { scan-assembler-not "\tmul\t" } } */
diff --git a/gcc/testsuite/gcc.target/mips/mulsize-2.c b/gcc/testsuite/gcc.target/mips/mulsize-2.c
index c427bfa78f1..4cc2224dff9 100644
--- a/gcc/testsuite/gcc.target/mips/mulsize-2.c
+++ b/gcc/testsuite/gcc.target/mips/mulsize-2.c
@@ -1,5 +1,6 @@
/* { dg-final { scan-assembler "\t.globl\tf9" } } */
-/* { dg-final { scan-assembler "\tsubu\t" } } */
+/* { dg-final { scan-assembler "\tsll\t" } } */
+/* { dg-final { scan-assembler "\taddu\t" } } */
/* { dg-final { scan-assembler-not "\tli\t" } } */
/* { dg-final { scan-assembler-not "\tmul\t" } } */
int
diff --git a/gcc/testsuite/gcc.target/mips/nan-2008.c b/gcc/testsuite/gcc.target/mips/nan-2008.c
new file mode 100644
index 00000000000..fc776e5fea8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/nan-2008.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=2008 -EB" } */
+
+double d = __builtin_nan ("");
+
+/* { dg-final { scan-assembler "\t\\.nan\t2008\n" } } */
+/* { dg-final { scan-assembler "\t\\.word\t2146959360\n\t\\.word\t0\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/nan-legacy.c b/gcc/testsuite/gcc.target/mips/nan-legacy.c
new file mode 100644
index 00000000000..359ca221edd
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/nan-legacy.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=legacy -EB" } */
+
+double d = __builtin_nan ("");
+
+/* { dg-final { scan-assembler "\t\\.nan\tlegacy\n" } } */
+/* { dg-final { scan-assembler "\t\\.word\t2146959359\n\t\\.word\t(?:-1|4294967295)\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/nanf-2008.c b/gcc/testsuite/gcc.target/mips/nanf-2008.c
new file mode 100644
index 00000000000..fb5e2858814
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/nanf-2008.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=2008 -EB" } */
+
+float f = __builtin_nanf ("");
+
+/* { dg-final { scan-assembler "\t\\.nan\t2008\n" } } */
+/* { dg-final { scan-assembler "\t\\.word\t2143289344\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/nanf-legacy.c b/gcc/testsuite/gcc.target/mips/nanf-legacy.c
new file mode 100644
index 00000000000..6db278ef182
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/nanf-legacy.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=legacy -EB" } */
+
+float f = __builtin_nanf ("");
+
+/* { dg-final { scan-assembler "\t\\.nan\tlegacy\n" } } */
+/* { dg-final { scan-assembler "\t\\.word\t2143289343\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/nans-2008.c b/gcc/testsuite/gcc.target/mips/nans-2008.c
new file mode 100644
index 00000000000..2da0c2df470
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/nans-2008.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=2008 -EB" } */
+
+double ds = __builtin_nans ("");
+
+/* { dg-final { scan-assembler "\t\\.nan\t2008\n" } } */
+/* { dg-final { scan-assembler "\t\\.word\t2146697216\n\t\\.word\t0\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/nans-legacy.c b/gcc/testsuite/gcc.target/mips/nans-legacy.c
new file mode 100644
index 00000000000..0ce4226b162
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/nans-legacy.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=legacy -EB" } */
+
+double ds = __builtin_nans ("");
+
+/* { dg-final { scan-assembler "\t\\.nan\tlegacy\n" } } */
+/* { dg-final { scan-assembler "\t\\.word\t2147483647\n\t\\.word\t(?:-1|4294967295)\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/nansf-2008.c b/gcc/testsuite/gcc.target/mips/nansf-2008.c
new file mode 100644
index 00000000000..d368add1909
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/nansf-2008.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=2008 -EB" } */
+
+float fs = __builtin_nansf ("");
+
+/* { dg-final { scan-assembler "\t\\.nan\t2008\n" } } */
+/* { dg-final { scan-assembler "\t\\.word\t2141192192\n" } } */
diff --git a/gcc/testsuite/gcc.target/mips/nansf-legacy.c b/gcc/testsuite/gcc.target/mips/nansf-legacy.c
new file mode 100644
index 00000000000..8a518670c94
--- /dev/null
+++ b/gcc/testsuite/gcc.target/mips/nansf-legacy.c
@@ -0,0 +1,7 @@
+/* { dg-do compile } */
+/* { dg-options "-mnan=legacy -EB" } */
+
+float fs = __builtin_nansf ("");
+
+/* { dg-final { scan-assembler "\t\\.nan\tlegacy\n" } } */
+/* { dg-final { scan-assembler "\t\\.word\t2147483647\n" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c b/gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c
new file mode 100644
index 00000000000..fcb72bdff2b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dfp-dd-2.c
@@ -0,0 +1,26 @@
+/* Test generation of DFP instructions for POWER6. */
+/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */
+/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */
+
+/* { dg-final { scan-assembler-times "fneg" 1 } } */
+/* { dg-final { scan-assembler-times "fabs" 1 } } */
+/* { dg-final { scan-assembler-times "fnabs" 1 } } */
+/* { dg-final { scan-assembler-times "fmr" 0 } } */
+
+_Decimal64
+func1 (_Decimal64 a, _Decimal64 b)
+{
+ return -b;
+}
+
+_Decimal64
+func2 (_Decimal64 a, _Decimal64 b)
+{
+ return __builtin_fabsd64 (b);
+}
+
+_Decimal64
+func3 (_Decimal64 a, _Decimal64 b)
+{
+ return - __builtin_fabsd64 (b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-td-2.c b/gcc/testsuite/gcc.target/powerpc/dfp-td-2.c
new file mode 100644
index 00000000000..a078cc46980
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dfp-td-2.c
@@ -0,0 +1,29 @@
+/* Test generation of DFP instructions for POWER6. */
+/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */
+/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */
+
+/* { dg-final { scan-assembler-times "fneg" 1 } } */
+/* { dg-final { scan-assembler-times "fabs" 1 } } */
+/* { dg-final { scan-assembler-times "fnabs" 1 } } */
+/* { dg-final { scan-assembler-times "fmr" 0 } } */
+
+/* These tests verify we only generate fneg, fabs and fnabs
+ instructions and no fmr's since these are done in place. */
+
+_Decimal128
+func1 (_Decimal128 a)
+{
+ return -a;
+}
+
+_Decimal128
+func2 (_Decimal128 a)
+{
+ return __builtin_fabsd128 (a);
+}
+
+_Decimal128
+func3 (_Decimal128 a)
+{
+ return - __builtin_fabsd128 (a);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-td-3.c b/gcc/testsuite/gcc.target/powerpc/dfp-td-3.c
new file mode 100644
index 00000000000..e825e5cad28
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dfp-td-3.c
@@ -0,0 +1,29 @@
+/* Test generation of DFP instructions for POWER6. */
+/* { dg-do compile { target { powerpc*-*-linux* && powerpc_fprs } } } */
+/* { dg-options "-std=gnu99 -O1 -mcpu=power6" } */
+
+/* { dg-final { scan-assembler-times "fneg" 1 } } */
+/* { dg-final { scan-assembler-times "fabs" 1 } } */
+/* { dg-final { scan-assembler-times "fnabs" 1 } } */
+/* { dg-final { scan-assembler-times "fmr" 3 } } */
+
+/* These tests verify we generate fneg, fabs and fnabs and
+ associated fmr's since these are not done in place. */
+
+_Decimal128
+func1 (_Decimal128 a, _Decimal128 b)
+{
+ return -b;
+}
+
+_Decimal128
+func2 (_Decimal128 a, _Decimal128 b)
+{
+ return __builtin_fabsd128 (b);
+}
+
+_Decimal128
+func3 (_Decimal128 a, _Decimal128 b)
+{
+ return - __builtin_fabsd128 (b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/fusion.c b/gcc/testsuite/gcc.target/powerpc/fusion.c
new file mode 100644
index 00000000000..3bea1c9f5a8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/fusion.c
@@ -0,0 +1,23 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power7 -mtune=power8 -O3" } */
+
+#define LARGE 0x12345
+
+int fusion_uchar (unsigned char *p){ return p[LARGE]; }
+int fusion_schar (signed char *p){ return p[LARGE]; }
+int fusion_ushort (unsigned short *p){ return p[LARGE]; }
+int fusion_short (short *p){ return p[LARGE]; }
+int fusion_int (int *p){ return p[LARGE]; }
+unsigned fusion_uns (unsigned *p){ return p[LARGE]; }
+
+vector double fusion_vector (vector double *p) { return p[2]; }
+
+/* { dg-final { scan-assembler-times "gpr load fusion" 6 } } */
+/* { dg-final { scan-assembler-times "vector load fusion" 1 } } */
+/* { dg-final { scan-assembler-times "lbz" 2 } } */
+/* { dg-final { scan-assembler-times "extsb" 1 } } */
+/* { dg-final { scan-assembler-times "lhz" 2 } } */
+/* { dg-final { scan-assembler-times "extsh" 1 } } */
+/* { dg-final { scan-assembler-times "lwz" 2 } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr57744.c b/gcc/testsuite/gcc.target/powerpc/pr57744.c
index 69bf42a1194..222fd6abd4f 100644
--- a/gcc/testsuite/gcc.target/powerpc/pr57744.c
+++ b/gcc/testsuite/gcc.target/powerpc/pr57744.c
@@ -3,6 +3,8 @@
/* { dg-require-effective-target powerpc_p8vector_ok } */
/* { dg-options "-mcpu=power8 -O3" } */
+void abort (void);
+
typedef unsigned U_16 __attribute__((mode(TI)));
extern int libat_compare_exchange_16 (U_16 *, U_16 *, U_16, int, int)
diff --git a/gcc/testsuite/gcc.target/powerpc/pr57949-1.c b/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
new file mode 100644
index 00000000000..253b2d89083
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr57949-1.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-options "-O2 -mcpu=power7" } */
+
+/* Verify that vs is 16-byte aligned in the absence of -mcompat-align-parm. */
+
+typedef float v4sf __attribute__ ((vector_size (16)));
+struct s { long m; v4sf v; };
+long n;
+v4sf ve;
+
+void pr57949 (long d1, long d2, long d3, long d4, long d5, long d6,
+ long d7, long d8, long d9, struct s vs) {
+ n = vs.m;
+ ve = vs.v;
+}
+
+/* { dg-final { scan-assembler "li \.\*,144" } } */
+/* { dg-final { scan-assembler "ld \.\*,128\\(1\\)" } } */
diff --git a/gcc/testsuite/gcc.target/powerpc/pr57949-2.c b/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
new file mode 100644
index 00000000000..aa6a0d9631a
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pr57949-2.c
@@ -0,0 +1,19 @@
+/* { dg-do compile { target { powerpc64*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-options "-O2 -mcpu=power7 -mcompat-align-parm" } */
+
+/* Verify that vs is not 16-byte aligned with -mcompat-align-parm. */
+
+typedef float v4sf __attribute__ ((vector_size (16)));
+struct s { long m; v4sf v; };
+long n;
+v4sf ve;
+
+void pr57949 (long d1, long d2, long d3, long d4, long d5, long d6,
+ long d7, long d8, long d9, struct s vs) {
+ n = vs.m;
+ ve = vs.v;
+}
+
+/* { dg-final { scan-assembler "ld .\*,136\\(1\\)" } } */
+/* { dg-final { scan-assembler "ld .\*,120\\(1\\)" } } */
diff --git a/gcc/testsuite/gcc.target/s390/nearestint-1.c b/gcc/testsuite/gcc.target/s390/nearestint-1.c
new file mode 100644
index 00000000000..1d9a753b3e4
--- /dev/null
+++ b/gcc/testsuite/gcc.target/s390/nearestint-1.c
@@ -0,0 +1,48 @@
+/* Since z196 the nearest integer functions can be expanded to single
+ instructions. */
+
+/* { dg-do compile } */
+/* { dg-options "-O3 -march=z196 -mzarch" } */
+
+extern float ceilf (float x);
+extern double ceil (double x);
+extern long double ceill (long double x);
+extern float floorf (float x);
+extern double floor (double x);
+extern long double floorl (long double x);
+extern float truncf (float x);
+extern double trunc (double x);
+extern long double truncl (long double x);
+extern float nearbyintf (float x);
+extern double nearbyint (double x);
+extern long double nearbyintl (long double x);
+extern float rintf (float x);
+extern double rint (double x);
+extern long double rintl (long double x);
+
+float my_ceilf (float x) { return ceilf (x); }
+double my_ceil (double x) { return ceil (x); }
+long double my_ceill (long double x) { return ceill (x); }
+
+float my_floorf (float x) { return floorf (x); }
+double my_floor (double x) { return floor (x); }
+long double my_floorl (long double x) { return floorl (x); }
+
+float my_truncf (float x) { return truncf (x); }
+double my_trunc (double x) { return trunc (x); }
+long double my_truncl (long double x) { return truncl (x); }
+
+float my_nearbyintf (float x) { return nearbyintf (x); }
+double my_nearbyint (double x) { return nearbyint (x); }
+long double my_nearbyintl (long double x) { return nearbyintl (x); }
+
+float my_rintf (float x) { return rintf (x); }
+double my_rint (double x) { return rint (x); }
+long double my_rintl (long double x) { return rintl (x); }
+
+/* { dg-final { scan-assembler-times "fiebr\t" 1 } } */
+/* { dg-final { scan-assembler-times "fidbr\t" 1 } } */
+/* { dg-final { scan-assembler-times "fixbr\t" 1 } } */
+/* { dg-final { scan-assembler-times "fiebra\t" 4 } } */
+/* { dg-final { scan-assembler-times "fidbra\t" 4 } } */
+/* { dg-final { scan-assembler-times "fixbra\t" 4 } } */
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_11.f90 b/gcc/testsuite/gfortran.dg/array_constructor_11.f90
index bb9f0dddb11..410fbcb7ddf 100644
--- a/gcc/testsuite/gfortran.dg/array_constructor_11.f90
+++ b/gcc/testsuite/gfortran.dg/array_constructor_11.f90
@@ -1,6 +1,7 @@
! Like array_constructor_6.f90, but check iterators with non-default stride,
! including combinations which lead to zero-length vectors.
! { dg-do run }
+! { dg-options "-Wzerotrip" }
program main
implicit none
call build (77)
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_18.f90 b/gcc/testsuite/gfortran.dg/array_constructor_18.f90
index c78976839d0..6853c069633 100644
--- a/gcc/testsuite/gfortran.dg/array_constructor_18.f90
+++ b/gcc/testsuite/gfortran.dg/array_constructor_18.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options "-Wzerotrip" }
! Tests the fix for PR32875, in which the character length for the
! array constructor would get lost in simplification and would lead
! the error 'Not Implemented: complex character array constructor'.
diff --git a/gcc/testsuite/gfortran.dg/array_constructor_22.f90 b/gcc/testsuite/gfortran.dg/array_constructor_22.f90
index 0dcdaea68c1..f7cdb27423c 100644
--- a/gcc/testsuite/gfortran.dg/array_constructor_22.f90
+++ b/gcc/testsuite/gfortran.dg/array_constructor_22.f90
@@ -1,4 +1,5 @@
! { dg-do compile }
+! { dg-options "-Wzerotrip" }
! PR34990 ICE in gfc_typenode_for_spec, at fortran/trans-types.c:842
! Test case that of the reporters.
module test
diff --git a/gcc/testsuite/gfortran.dg/bounds_check_18.f90 b/gcc/testsuite/gfortran.dg/bounds_check_18.f90
new file mode 100644
index 00000000000..afd0503ef10
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/bounds_check_18.f90
@@ -0,0 +1,9 @@
+! { dg-do compile }
+program main
+ implicit none
+ integer :: n
+ real, dimension(10) :: a
+ n = 0
+ call random_number(a)
+ if (any(a(n+1:n+5) > [1.0, 2.0, 3.0])) print *,"Hello!" ! { dg-error "not conformable" }
+end program main
diff --git a/gcc/testsuite/gfortran.dg/coarray_15.f90 b/gcc/testsuite/gfortran.dg/coarray_15.f90
index 0aecb2f4e11..ee01e61ccc1 100644
--- a/gcc/testsuite/gfortran.dg/coarray_15.f90
+++ b/gcc/testsuite/gfortran.dg/coarray_15.f90
@@ -1,5 +1,5 @@
! { dg-do run }
-! { dg-options "-fcoarray=single" }
+! { dg-options "-fcoarray=single -Wzerotrip" }
!
! PR fortran/18918
!
diff --git a/gcc/testsuite/gfortran.dg/do_1.f90 b/gcc/testsuite/gfortran.dg/do_1.f90
index 171275af3f2..b041279f6d9 100644
--- a/gcc/testsuite/gfortran.dg/do_1.f90
+++ b/gcc/testsuite/gfortran.dg/do_1.f90
@@ -1,4 +1,5 @@
! { dg-do run }
+! { dg-options "-Wall" }
! Program to check corner cases for DO statements.
program do_1
implicit none
diff --git a/gcc/testsuite/gfortran.dg/do_3.F90 b/gcc/testsuite/gfortran.dg/do_3.F90
index 67723a508f4..eb4751d6b06 100644
--- a/gcc/testsuite/gfortran.dg/do_3.F90
+++ b/gcc/testsuite/gfortran.dg/do_3.F90
@@ -1,5 +1,5 @@
! { dg-do run }
-! { dg-options "-std=legacy -ffree-line-length-none -fno-range-check -fwrapv" }
+! { dg-options "-std=legacy -ffree-line-length-none -fno-range-check -fwrapv -Wzerotrip" }
program test
integer :: count
integer :: i
diff --git a/gcc/testsuite/gfortran.dg/do_check_10.f90 b/gcc/testsuite/gfortran.dg/do_check_10.f90
new file mode 100644
index 00000000000..016dab7ade9
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_check_10.f90
@@ -0,0 +1,7 @@
+! { dg-do compile }
+! { dg-options "-Wall -Wno-zerotrip" }
+program main
+ do i=1,0
+ print *,i
+ end do
+end program main
diff --git a/gcc/testsuite/gfortran.dg/do_check_5.f90 b/gcc/testsuite/gfortran.dg/do_check_5.f90
index 3df7b14f0eb..57930fd61ad 100644
--- a/gcc/testsuite/gfortran.dg/do_check_5.f90
+++ b/gcc/testsuite/gfortran.dg/do_check_5.f90
@@ -1,5 +1,5 @@
! { dg-do compile }
-!
+! { dg-options "-Wall" }
! PR/fortran 38432
! DO-loop compile-time checks
!
diff --git a/gcc/testsuite/gfortran.dg/do_concurrent_3.f90 b/gcc/testsuite/gfortran.dg/do_concurrent_3.f90
new file mode 100644
index 00000000000..09bb0cce722
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/do_concurrent_3.f90
@@ -0,0 +1,13 @@
+! { dg-do compile }
+! PR 56519 - flag impure intrinsic subroutine calls
+! within DO CONCURRENT
+program main
+ implicit none
+ integer :: i
+ real :: array(123), val
+
+ do concurrent (i = 1:123)
+ call random_number (val) ! { dg-error "is not PURE" }
+ array(i) = val
+ end do
+end program main
diff --git a/gcc/testsuite/gfortran.dg/gomp/proc_ptr_1.f90 b/gcc/testsuite/gfortran.dg/gomp/proc_ptr_1.f90
new file mode 100644
index 00000000000..952c31491ed
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/gomp/proc_ptr_1.f90
@@ -0,0 +1,28 @@
+! { dg-do compile }
+!
+! PR 46271: [F03] OpenMP default(none) and procedure pointers
+!
+! Contributed by Marco Restelli <mrestelli@gmail.com>
+
+program test
+ implicit none
+ integer :: i
+ real :: s(1000)
+ procedure(f), pointer :: pf
+
+ pf => f
+
+ !$omp parallel do schedule(static) private(i) shared(s,pf) default(none)
+ do i=1,1000
+ call pf(real(i),s(i))
+ enddo
+ !$omp end parallel do
+
+ write(*,*) 'Sum ',sum(s)
+contains
+ pure subroutine f(x,y)
+ real, intent(in) :: x
+ real, intent(out) :: y
+ y = sin(x)*cos(x)
+ end subroutine
+end
diff --git a/gcc/testsuite/gfortran.dg/inline_sum_5.f90 b/gcc/testsuite/gfortran.dg/inline_sum_5.f90
new file mode 100644
index 00000000000..bda73fd99a3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/inline_sum_5.f90
@@ -0,0 +1,33 @@
+! { dg-do run }
+!
+! PR fortran/57798
+! The call to sum used to be inlined into a loop with an uninitialized bound
+!
+! Original testcase by Stephan Kramer <stephan.kramer@imperial.ac.uk>
+
+program test
+ implicit none
+
+ call sub(2, 11)
+
+ contains
+
+ function func(m, n)
+ integer, intent(in):: m,n
+ real, dimension(m, n):: func
+
+ func = 1.0
+
+ end function func
+
+ subroutine sub(m, n)
+ integer, intent(in):: m, n
+ real, dimension(m,n):: y
+
+ y = 1.0
+ if (any(sum(y*func(m,n), dim=1) /= m)) call abort
+
+ end subroutine sub
+
+end program test
+
diff --git a/gcc/testsuite/gfortran.dg/intent_out_8.f90 b/gcc/testsuite/gfortran.dg/intent_out_8.f90
new file mode 100644
index 00000000000..674d8338bfa
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/intent_out_8.f90
@@ -0,0 +1,17 @@
+! { dg-do compile }
+! { dg-options "-Wall" }
+!
+! PR 53655: [F03] "default initializer" warnings
+!
+! Contributed by Tobias Burnus <burnus@gcc.gnu.org>
+
+type t
+end type t
+
+contains
+
+ subroutine foo(x)
+ type(t), intent(out) :: x
+ end subroutine
+
+end
diff --git a/gcc/testsuite/gfortran.dg/pointer_assign_10.f90 b/gcc/testsuite/gfortran.dg/pointer_assign_10.f90
new file mode 100644
index 00000000000..756e530209c
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_assign_10.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+!
+! PR fortran/57530
+!
+!
+! TYPE => TYPE pointer assignment for functions
+!
+module m
+ implicit none
+ type t
+ integer :: ii = 55
+ end type t
+contains
+ function f1()
+ type(t), pointer :: f1
+ allocate (f1)
+ f1%ii = 123
+ end function f1
+ function f2()
+ type(t), pointer :: f2(:)
+ allocate (f2(3))
+ f2(:)%ii = [-11,-22,-33]
+ end function f2
+end module m
+
+program test
+ use m
+ implicit none
+ type(t), pointer :: p1, p2(:), p3(:,:)
+ p1 => f1()
+ if (p1%ii /= 123) call abort ()
+ p2 => f2()
+ if (any (p2%ii /= [-11,-22,-33])) call abort ()
+ p3(2:2,1:3) => f2()
+ if (any (p3(2,:)%ii /= [-11,-22,-33])) call abort ()
+end program test
diff --git a/gcc/testsuite/gfortran.dg/pointer_assign_11.f90 b/gcc/testsuite/gfortran.dg/pointer_assign_11.f90
new file mode 100644
index 00000000000..f32c5315711
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_assign_11.f90
@@ -0,0 +1,51 @@
+! { dg-do run }
+!
+! PR fortran/57530
+!
+!
+! CLASS => CLASS pointer assignment for function results
+!
+module m
+ implicit none
+ type t
+ integer :: ii = 55
+ end type t
+ type, extends(t) :: t2
+ end type t2
+contains
+ function f1()
+ class(t), pointer :: f1
+ allocate (f1)
+ f1%ii = 123
+ end function f1
+ function f2()
+ class(t), pointer :: f2(:)
+ allocate (f2(3))
+ f2(:)%ii = [-11,-22,-33]
+ end function f2
+end module m
+
+program test
+ use m
+ implicit none
+ class(t), pointer :: p1, p2(:), p3(:,:)
+ type(t) :: my_t
+ type(t2) :: my_t2
+
+ allocate (t2 :: p1, p2(1), p3(1,1))
+ if (.not. same_type_as (p1, my_t2)) call abort()
+ if (.not. same_type_as (p2, my_t2)) call abort()
+ if (.not. same_type_as (p3, my_t2)) call abort()
+
+ p1 => f1()
+ if (p1%ii /= 123) call abort ()
+ if (.not. same_type_as (p1, my_t)) call abort()
+
+ p2 => f2()
+ if (any (p2%ii /= [-11,-22,-33])) call abort ()
+ if (.not. same_type_as (p2, my_t)) call abort()
+
+ p3(2:2,1:3) => f2()
+ if (any (p3(2,:)%ii /= [-11,-22,-33])) call abort ()
+ if (.not. same_type_as (p3, my_t)) call abort()
+end program test
diff --git a/gcc/testsuite/gfortran.dg/pointer_assign_8.f90 b/gcc/testsuite/gfortran.dg/pointer_assign_8.f90
new file mode 100644
index 00000000000..e8fb2c3a6b2
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_assign_8.f90
@@ -0,0 +1,46 @@
+! { dg-do run }
+!
+! PR fortran/57530
+!
+!
+! TYPE => CLASS pointer assignment for variables
+!
+module m
+ implicit none
+ type t
+ integer :: ii = 55
+ end type t
+contains
+ subroutine sub (tgt, tgt2)
+ class(t), target :: tgt, tgt2(:)
+ type(t), pointer :: ptr, ptr2(:), ptr3(:,:)
+
+ if (tgt%ii /= 43) call abort()
+ if (size (tgt2) /= 3) call abort()
+ if (any (tgt2(:)%ii /= [11,22,33])) call abort()
+
+ ptr => tgt ! TYPE => CLASS
+ ptr2 => tgt2 ! TYPE => CLASS
+ ptr3(-3:-3,1:3) => tgt2 ! TYPE => CLASS
+
+ if (.not. associated(ptr)) call abort()
+ if (.not. associated(ptr2)) call abort()
+ if (.not. associated(ptr3)) call abort()
+ if (.not. associated(ptr,tgt)) call abort()
+ if (.not. associated(ptr2,tgt2)) call abort()
+ if (ptr%ii /= 43) call abort()
+ if (size (ptr2) /= 3) call abort()
+ if (size (ptr3) /= 3) call abort()
+ if (any (ptr2(:)%ii /= [11,22,33])) call abort()
+ if (any (shape (ptr3) /= [1,3])) call abort()
+ if (any (ptr3(-3,:)%ii /= [11,22,33])) call abort()
+ end subroutine sub
+end module m
+
+use m
+type(t), target :: x
+type(t), target :: y(3)
+x%ii = 43
+y(:)%ii = [11,22,33]
+call sub(x,y)
+end
diff --git a/gcc/testsuite/gfortran.dg/pointer_assign_9.f90 b/gcc/testsuite/gfortran.dg/pointer_assign_9.f90
new file mode 100644
index 00000000000..7f8152aae6b
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_assign_9.f90
@@ -0,0 +1,36 @@
+! { dg-do run }
+!
+! PR fortran/57530
+!
+!
+! TYPE => CLASS pointer assignment for functions
+!
+module m
+ implicit none
+ type t
+ integer :: ii = 55
+ end type t
+contains
+ function f1()
+ class(t), pointer :: f1
+ allocate (f1)
+ f1%ii = 123
+ end function f1
+ function f2()
+ class(t), pointer :: f2(:)
+ allocate (f2(3))
+ f2(:)%ii = [-11,-22,-33]
+ end function f2
+end module m
+
+program test
+ use m
+ implicit none
+ type(t), pointer :: p1, p2(:),p3(:,:)
+ p1 => f1()
+ if (p1%ii /= 123) call abort ()
+ p2 => f2()
+ if (any (p2%ii /= [-11,-22,-33])) call abort ()
+ p3(2:2,1:3) => f2()
+ if (any (p3(2,:)%ii /= [-11,-22,-33])) call abort ()
+end program test
diff --git a/gcc/testsuite/gfortran.dg/pointer_init_8.f90 b/gcc/testsuite/gfortran.dg/pointer_init_8.f90
new file mode 100644
index 00000000000..aacd9a8e16e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pointer_init_8.f90
@@ -0,0 +1,26 @@
+! { dg-do run }
+!
+! PR 57306: [OOP] ICE on valid with class pointer initialization
+!
+! Contributed by Andrew Benson <abensonca@gmail.com>
+
+module m
+ type :: c
+ end type c
+ type, extends(c) :: d
+ end type d
+ type(c), target :: x
+ type(d), target :: y
+end module m
+
+ use m
+ class(c), pointer :: px => x
+ class(c), pointer :: py => y
+
+ if (.not. associated(px, x)) call abort()
+ if (.not. same_type_as(px, x)) call abort()
+ if (.not. associated(py, y)) call abort()
+ if (.not. same_type_as(py, y)) call abort()
+end
+
+! { dg-final { cleanup-modules "m" } }
diff --git a/gcc/testsuite/gfortran.dg/pr57987.f90 b/gcc/testsuite/gfortran.dg/pr57987.f90
new file mode 100644
index 00000000000..c881e6d64a3
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/pr57987.f90
@@ -0,0 +1,24 @@
+! { dg-do compile }
+! { dg-options "-O3 -fno-ipa-cp -fdump-ipa-inline" }
+
+program test
+ call test2 ()
+contains
+ subroutine test2 ()
+ type t
+ integer, allocatable :: x
+ end type t
+
+ type t2
+ class(t), allocatable :: a
+ end type t2
+
+ type(t2) :: one, two
+
+ allocate (two%a)
+ one = two
+ end subroutine test2
+end program test
+
+! { dg-final { scan-ipa-dump-not "redefined extern inline functions are not considered for inlining" "inline" } }
+! { dg-final { cleanup-ipa-dump "inline" } }
diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_14.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_14.f90
index 8474d18622d..b8b669f640d 100644
--- a/gcc/testsuite/gfortran.dg/realloc_on_assign_14.f90
+++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_14.f90
@@ -23,7 +23,7 @@ str = 'abc' ! { dg-warning "Code for reallocating the allocatable variable" }
astr = 'abc' ! no realloc
astr = ['abc'] ! { dg-warning "Code for reallocating the allocatable array" }
a = reshape(a,shape(a)) ! { dg-warning "Code for reallocating the allocatable array" }
-r = sin(r) ! { dg-warning "Code for reallocating the allocatable array" }
+r = sin(r)
r = sin(r(1)) ! no realloc
b = sin(r(1)) ! { dg-warning "Code for reallocating the allocatable variable" }
diff --git a/gcc/testsuite/gfortran.dg/realloc_on_assign_19.f90 b/gcc/testsuite/gfortran.dg/realloc_on_assign_19.f90
new file mode 100644
index 00000000000..c54a35f40da
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/realloc_on_assign_19.f90
@@ -0,0 +1,21 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+! PR 52243 - avoid check for reallocation when doing simple
+! assignments with the same variable on both sides.
+module foo
+contains
+ elemental function ele(a)
+ real, intent(in) :: a
+ real :: ele
+ ele = 1./(2+a)
+ end function ele
+
+ subroutine bar(a)
+ real, dimension(:), allocatable :: a
+ a = a * 2.0
+ a = sin(a-0.3)
+ a = ele(a)
+ end subroutine bar
+end module foo
+! { dg-final { scan-tree-dump-times "alloc" 0 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/reassoc_12.f90 b/gcc/testsuite/gfortran.dg/reassoc_12.f90
new file mode 100644
index 00000000000..7f4d70e31ca
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/reassoc_12.f90
@@ -0,0 +1,74 @@
+! { dg-do compile }
+! { dg-options "-O2 -ffast-math" }
+! PR middle-end/57370
+
+ SUBROUTINE xb88_lr_adiabatic_lda_calc(e_ndrho_ndrho_ndrho, &
+ grad_deriv,npoints, sx)
+ IMPLICIT REAL*8 (t)
+ INTEGER, PARAMETER :: dp=8
+ REAL(kind=dp), DIMENSION(1:npoints) :: e_ndrho_ndrho_ndrho, &
+ e_ndrho_ndrho_rho
+ DO ii=1,npoints
+ IF( grad_deriv >= 2 .OR. grad_deriv == -2 ) THEN
+ t1425 = t233 * t557
+ t1429 = beta * t225
+ t1622 = t327 * t1621
+ t1626 = t327 * t1625
+ t1632 = t327 * t1631
+ t1685 = t105 * t1684
+ t2057 = t1636 + t8 * (t2635 + t3288)
+ END IF
+ IF( grad_deriv >= 3 .OR. grad_deriv == -3 ) THEN
+ t5469 = t5440 - t5443 - t5446 - t5449 - &
+ t5451 - t5454 - t5456 + t5459 - &
+ t5462 + t5466 - t5468
+ t5478 = 0.240e2_dp * t1616 * t973 * t645 * t1425
+ t5489 = 0.1600000000e2_dp * t1429 * t1658
+ t5531 = 0.160e2_dp * t112 * t1626
+ t5533 = 0.160e2_dp * t112 * t1632
+ t5537 = 0.160e2_dp * t112 * t1622
+ t5541 = t5472 - t5478 - t5523 + t5525 + &
+ t5531 + t5533 + t5535 + t5537 + &
+ t5540
+ t5565 = t112 * t1685
+ t5575 = t5545 - t5548 + t5551 + t5553 - &
+ t5558 + t5560 - t5562 + t5564 - &
+ 0.80e1_dp * t5565 + t5568 + t5572 + &
+ t5574
+ t5611 = t5579 - t5585 + t5590 - t5595 + &
+ t5597 - t5602 + t5604 + t5607 + &
+ t5610
+ t5613 = t5469 + t5541 + t5575 + t5611
+ t6223 = t6189 - &
+ 0.3333333336e0_dp * t83 * t84 * t5613 + &
+ t6222
+ t6227 = - t8 * (t5305 + t6223)
+ e_ndrho_ndrho_rho(ii) = e_ndrho_ndrho_rho(ii) + &
+ t6227 * sx
+ t6352 = t5440 - t5443 - t5446 - t5449 - &
+ t5451 - t5454 + &
+ 0.40e1_dp * t102 * t327 * t2057 * t557 - &
+ t5456 + t5459 - t5462 + t5466 - &
+ t5468
+ t6363 = t5480 - t5489 + &
+ 0.9600000000e2_dp * t1054 * t640 * t3679
+ t6367 = t5472 - t5474 - t5478 - t5523 + &
+ t5525 + t5531 + t5533 + t5535 + &
+ t5537 - 0.20e1_dp * t102 * t105 * t6363 + &
+ t5540
+ t6370 = t5545 - t5548 + t5551 + t5553 - &
+ t5558 + t5560 - t5562 + t5564 - &
+ 0.40e1_dp * t5565 + &
+ t5568 + t5572 + t5574
+ t6373 = t5579 - t5585 + t5590 - t5595 + &
+ t5597 - t5602 + t5604 + t5607 + &
+ t5610
+ t6375 = t6352 + t6367 + t6370 + t6373
+ t6380 = - 0.3333333336e0_dp * t83 * t84 * t6375 + t5701
+ t6669 = -t4704 - t8 * (t6344 + t6380 + t6665)
+ e_ndrho_ndrho_ndrho(ii) = e_ndrho_ndrho_ndrho(ii) + &
+ t6669 * sx
+ END IF
+ END DO
+ END SUBROUTINE xb88_lr_adiabatic_lda_calc
+
diff --git a/gcc/testsuite/gfortran.dg/select_type_34.f90 b/gcc/testsuite/gfortran.dg/select_type_34.f90
new file mode 100644
index 00000000000..e75a7abd56e
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/select_type_34.f90
@@ -0,0 +1,10 @@
+! { dg-do compile }
+!
+! PR 58185: [4.8/4.9 Regression] [OOP] ICE when selector in SELECT TYPE is non-polymorphic
+!
+! Contributed by John <jwmwalrus@gmail.com>
+
+ integer :: array
+ select type (a => array) ! { dg-error "Selector shall be polymorphic" }
+ end select
+end
diff --git a/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90 b/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90
new file mode 100644
index 00000000000..e76bc49aeda
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/transfer_intrinsic_6.f90
@@ -0,0 +1,20 @@
+! { dg-do compile }
+! { dg-options "-fdump-tree-original" }
+!
+! PR 58058: [4.7/4.8/4.9 Regression] Memory leak with transfer function
+!
+! Contributed by Thomas Jourdan <thomas.jourdan@orange.fr>
+
+ implicit none
+
+ integer, dimension(3) :: t1
+ character(len=64) :: str
+
+ t1 = (/1,2,3/)
+
+ str = transfer(t1,str)
+
+end
+
+! { dg-final { scan-tree-dump-times "__builtin_free" 1 "original" } }
+! { dg-final { cleanup-tree-dump "original" } }
diff --git a/gcc/testsuite/gfortran.dg/typebound_assignment_7.f90 b/gcc/testsuite/gfortran.dg/typebound_assignment_7.f90
new file mode 100644
index 00000000000..2c5b837d670
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/typebound_assignment_7.f90
@@ -0,0 +1,66 @@
+! { dg-do run }
+!
+! PR 57843: [OOP] Type-bound assignment is resolved to non-polymorphic procedure call
+!
+! Contributed by John <jwmwalrus@gmail.com>
+
+module mod1
+ implicit none
+ type :: itemType
+ contains
+ procedure :: the_assignment => assign_itemType
+ generic :: assignment(=) => the_assignment
+ end type
+contains
+ subroutine assign_itemType(left, right)
+ class(itemType), intent(OUT) :: left
+ class(itemType), intent(IN) :: right
+ end subroutine
+end module
+
+module mod2
+ use mod1
+ implicit none
+ type, extends(itemType) :: myItem
+ character(3) :: name = ''
+ contains
+ procedure :: the_assignment => assign_myItem
+ end type
+contains
+ subroutine assign_myItem(left, right)
+ class(myItem), intent(OUT) :: left
+ class(itemType), intent(IN) :: right
+ select type (right)
+ type is (myItem)
+ left%name = right%name
+ end select
+ end subroutine
+end module
+
+
+program test_assign
+
+ use mod2
+ implicit none
+
+ class(itemType), allocatable :: item1, item2
+
+ allocate (myItem :: item1)
+ select type (item1)
+ type is (myItem)
+ item1%name = 'abc'
+ end select
+
+ allocate (myItem :: item2)
+ item2 = item1
+
+ select type (item2)
+ type is (myItem)
+ if (item2%name /= 'abc') call abort()
+ class default
+ call abort()
+ end select
+
+end
+
+! { dg-final { cleanup-modules "mod1 mod2" } }
diff --git a/gcc/testsuite/gnat.dg/loop_optimization16.adb b/gcc/testsuite/gnat.dg/loop_optimization16.adb
new file mode 100644
index 00000000000..b9f2b70bb45
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization16.adb
@@ -0,0 +1,24 @@
+-- { dg-do run }
+
+with Loop_Optimization16_Pkg; use Loop_Optimization16_Pkg;
+
+procedure Loop_Optimization16 is
+
+ Counter : Natural := 0;
+
+ C : constant Natural := F;
+
+ subtype Index_T is Index_Base range 1 .. Index_Base (C);
+
+begin
+
+ for I in Index_T'First .. Index_T'Last loop
+ Counter := Counter + 1;
+ exit when Counter > 200;
+ end loop;
+
+ if Counter > 200 then
+ raise Program_Error;
+ end if;
+
+end Loop_Optimization16;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization16_pkg.adb b/gcc/testsuite/gnat.dg/loop_optimization16_pkg.adb
new file mode 100644
index 00000000000..e4142f6e6a1
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization16_pkg.adb
@@ -0,0 +1,8 @@
+package body Loop_Optimization16_Pkg is
+
+ function F return Natural is
+ begin
+ return Natural (Index_Base'Last);
+ end;
+
+end Loop_Optimization16_Pkg;
diff --git a/gcc/testsuite/gnat.dg/loop_optimization16_pkg.ads b/gcc/testsuite/gnat.dg/loop_optimization16_pkg.ads
new file mode 100644
index 00000000000..abeecfb646f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/loop_optimization16_pkg.ads
@@ -0,0 +1,7 @@
+package Loop_Optimization16_Pkg is
+
+ type Index_Base is range 0 .. 127;
+
+ function F return Natural;
+
+end Loop_Optimization16_Pkg;
diff --git a/gcc/testsuite/gnat.dg/specs/linker_alias.ads b/gcc/testsuite/gnat.dg/specs/linker_alias.ads
new file mode 100644
index 00000000000..0f7980eb54f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/specs/linker_alias.ads
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+-- { dg-skip-if "missing alias support" { *-*-darwin* } }
+
+package Linker_Alias is
+
+ Var : Integer; -- { dg-error "aliased to undefined symbol" }
+ pragma Export (C, Var, "my_var");
+ pragma Linker_Alias (Var, "var2");
+
+end Linker_Alias;
diff --git a/gcc/testsuite/gnat.dg/stack_usage2.adb b/gcc/testsuite/gnat.dg/stack_usage2.adb
new file mode 100644
index 00000000000..d458a929037
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/stack_usage2.adb
@@ -0,0 +1,26 @@
+-- { dg-do compile }
+-- { dg-options "-O2 -fstack-usage" }
+
+with System;
+
+procedure Stack_Usage2 is
+
+ Sink : System.Address;
+ pragma Import (Ada, Sink);
+
+ procedure Transmit_Data (Branch : Integer) is
+ pragma No_Inline (Transmit_Data);
+ X : Integer;
+ begin
+ case Branch is
+ when 1 => Sink := X'Address;
+ when others => null;
+ end case;
+ end;
+
+begin
+ Transmit_Data (Branch => 1);
+end;
+
+-- { dg-final { scan-stack-usage-not ":Constprop" } }
+-- { dg-final { cleanup-stack-usage } }
diff --git a/gcc/testsuite/gnat.dg/valued_proc.adb b/gcc/testsuite/gnat.dg/valued_proc.adb
new file mode 100644
index 00000000000..7030b43c45f
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/valued_proc.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+-- { dg-options "-gnatdm -gnatws" }
+
+with Valued_Proc_Pkg; use Valued_Proc_Pkg;
+with System; use System;
+
+procedure Valued_Proc is
+ Status : UNSIGNED_LONGWORD;
+ Length : POSITIVE;
+begin
+ GetMsg (Status, UNSIGNED_WORD(Length));
+end;
diff --git a/gcc/testsuite/gnat.dg/valued_proc_pkg.ads b/gcc/testsuite/gnat.dg/valued_proc_pkg.ads
new file mode 100644
index 00000000000..d5197abf4d4
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/valued_proc_pkg.ads
@@ -0,0 +1,15 @@
+pragma Extend_System (Aux_DEC);
+with System; use System;
+
+package Valued_Proc_Pkg is
+
+ procedure GETMSG (STATUS : out UNSIGNED_LONGWORD;
+ MSGLEN : out UNSIGNED_WORD);
+
+ pragma Interface (EXTERNAL, GETMSG);
+
+ pragma IMPORT_VALUED_PROCEDURE (GETMSG, "SYS$GETMSG",
+ (UNSIGNED_LONGWORD, UNSIGNED_WORD),
+ (VALUE, REFERENCE));
+
+end Valued_Proc_Pkg;
diff --git a/gcc/testsuite/gnat.dg/warn10.adb b/gcc/testsuite/gnat.dg/warn10.adb
new file mode 100644
index 00000000000..29b140d7598
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn10.adb
@@ -0,0 +1,12 @@
+-- { dg-do compile }
+-- { dg-options "-O3 -gnatn -Winline" }
+
+package body Warn10 is
+
+ procedure Do_Something(Driver : My_Driver) is
+ X : Float;
+ begin
+ X := Get_Input_Value( Driver, 1, 1);
+ end;
+
+end Warn10;
diff --git a/gcc/testsuite/gnat.dg/warn10.ads b/gcc/testsuite/gnat.dg/warn10.ads
new file mode 100644
index 00000000000..01aa1e4b58a
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn10.ads
@@ -0,0 +1,11 @@
+with Warn10_Pkg; use Warn10_Pkg;
+
+package Warn10 is
+
+ type My_Driver is new Root with record
+ Extra : Natural;
+ end record;
+
+ procedure Do_Something(Driver : My_Driver);
+
+end Warn10;
diff --git a/gcc/testsuite/gnat.dg/warn10_pkg.ads b/gcc/testsuite/gnat.dg/warn10_pkg.ads
new file mode 100644
index 00000000000..ac5b676777d
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn10_pkg.ads
@@ -0,0 +1,12 @@
+package Warn10_Pkg is
+
+ Size : constant Natural := 100;
+ type My_Array is array(1..Size, 1..Size) of Float;
+
+ type Root is tagged record
+ Input_Values : My_Array;
+ end record;
+
+ function Get_Input_Value( Driver : Root; I, J : Natural) return Float;
+
+end Warn10_Pkg;
diff --git a/gcc/testsuite/gnat.dg/warn9.adb b/gcc/testsuite/gnat.dg/warn9.adb
new file mode 100644
index 00000000000..38f9d71e410
--- /dev/null
+++ b/gcc/testsuite/gnat.dg/warn9.adb
@@ -0,0 +1,10 @@
+-- { dg-do compile }
+-- { dg-options "-Wuninitialized" }
+
+pragma Warnings (Off);
+
+function Warn9 return Integer is
+ I : Integer;
+begin
+ return I;
+end;
diff --git a/gcc/testsuite/go.test/test/fixedbugs/bug086.go b/gcc/testsuite/go.test/test/fixedbugs/bug086.go
index fc69e0e3fc7..40d23620669 100644
--- a/gcc/testsuite/go.test/test/fixedbugs/bug086.go
+++ b/gcc/testsuite/go.test/test/fixedbugs/bug086.go
@@ -6,12 +6,12 @@
package main
-func f() int { // ERROR "return|control"
+func f() int {
if false {
return 0;
}
// we should not be able to return successfully w/o a return statement
-}
+} // ERROR "return"
func main() {
print(f(), "\n");
diff --git a/gcc/testsuite/lib/file-format.exp b/gcc/testsuite/lib/file-format.exp
index eb96b085c31..7d74d63f7ea 100644
--- a/gcc/testsuite/lib/file-format.exp
+++ b/gcc/testsuite/lib/file-format.exp
@@ -38,6 +38,9 @@ proc gcc_target_object_format { } {
} else {
set gcc_target_object_format_saved som
}
+ } elseif { [istarget *-*-aix*] } {
+ # AIX doesn't necessarily have objdump, so hand-code it.
+ set gcc_target_object_format_saved coff
} else {
set objdump_name [find_binutils_prog objdump]
set open_file [open objfmtst.c w]
diff --git a/gcc/testsuite/lib/plugin-support.exp b/gcc/testsuite/lib/plugin-support.exp
index 88033b3286a..54c51fe686e 100644
--- a/gcc/testsuite/lib/plugin-support.exp
+++ b/gcc/testsuite/lib/plugin-support.exp
@@ -101,10 +101,10 @@ proc plugin-test-execute { plugin_src plugin_tests } {
set optstr [concat $optstr " $op"]
}
}
- set optstr [concat $optstr "-DIN_GCC -fPIC -shared -undefined dynamic_lookup"]
+ set optstr [concat $optstr "-DIN_GCC -fPIC -shared -fno-rtti -undefined dynamic_lookup"]
} else {
set plug_cflags $PLUGINCFLAGS
- set optstr "$includes $extra_flags -DIN_GCC -fPIC -shared"
+ set optstr "$includes $extra_flags -DIN_GCC -fPIC -shared -fno-rtti"
}
# Temporarily switch to the environment for the plugin compiler.
diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp
index 0fb135c5298..0905821587b 100644
--- a/gcc/testsuite/lib/target-supports.exp
+++ b/gcc/testsuite/lib/target-supports.exp
@@ -226,6 +226,12 @@ proc check_weak_available { } {
return 1
}
+ # All AIX targets should support it
+
+ if { [istarget *-*-aix*] } {
+ return 1
+ }
+
# All solaris2 targets should support it
if { [istarget *-*-solaris2*] } {
@@ -1723,6 +1729,15 @@ proc check_effective_target_x32 { } {
}]
}
+# Return 1 if we're generating 32-bit integers using default
+# options, 0 otherwise.
+
+proc check_effective_target_int32 { } {
+ return [check_no_compiler_messages int32 object {
+ int dummy[sizeof (int) == 4 ? 1 : -1];
+ }]
+}
+
# Return 1 if we're generating 32-bit or larger integers using default
# options, 0 otherwise.
diff --git a/gcc/testsuite/lib/ubsan-dg.exp b/gcc/testsuite/lib/ubsan-dg.exp
new file mode 100644
index 00000000000..4ec5fdfad67
--- /dev/null
+++ b/gcc/testsuite/lib/ubsan-dg.exp
@@ -0,0 +1,104 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+#
+# ubsan_link_flags -- compute library path and flags to find libubsan.
+# (originally from g++.exp)
+#
+
+proc ubsan_link_flags { paths } {
+ global srcdir
+ global ld_library_path
+ global shlib_ext
+
+ set gccpath ${paths}
+ set flags ""
+
+ set shlib_ext [get_shlib_extension]
+
+ if { $gccpath != "" } {
+ if { [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.a"]
+ || [file exists "${gccpath}/libsanitizer/ubsan/.libs/libubsan.${shlib_ext}"] } {
+ append flags " -B${gccpath}/libsanitizer/ubsan/ "
+ append flags " -L${gccpath}/libsanitizer/ubsan/.libs"
+ append ld_library_path ":${gccpath}/libsanitizer/ubsan/.libs"
+ }
+ } else {
+ global tool_root_dir
+
+ set libubsan [lookfor_file ${tool_root_dir} libubsan]
+ if { $libubsan != "" } {
+ append flags "-L${libubsan} "
+ append ld_library_path ":${libubsan}"
+ }
+ }
+
+ set_ld_library_path_env_vars
+
+ return "$flags"
+}
+
+#
+# ubsan_init -- called at the start of each subdir of tests
+#
+
+proc ubsan_init { args } {
+ global TEST_ALWAYS_FLAGS
+ global ALWAYS_CXXFLAGS
+ global TOOL_OPTIONS
+ global ubsan_saved_TEST_ALWAYS_FLAGS
+
+ set link_flags ""
+ if ![is_remote host] {
+ if [info exists TOOL_OPTIONS] {
+ set link_flags "[ubsan_link_flags [get_multilibs ${TOOL_OPTIONS}]]"
+ } else {
+ set link_flags "[ubsan_link_flags [get_multilibs]]"
+ }
+ }
+
+ if [info exists TEST_ALWAYS_FLAGS] {
+ set ubsan_saved_TEST_ALWAYS_FLAGS $TEST_ALWAYS_FLAGS
+ }
+ if [info exists ALWAYS_CXXFLAGS] {
+ set ALWAYS_CXXFLAGS [concat "{ldflags=$link_flags}" $ALWAYS_CXXFLAGS]
+ } else {
+ if [info exists TEST_ALWAYS_FLAGS] {
+ set TEST_ALWAYS_FLAGS "$link_flags $TEST_ALWAYS_FLAGS"
+ } else {
+ set TEST_ALWAYS_FLAGS "$link_flags"
+ }
+ }
+ if { $link_flags != "" } {
+ return 1
+ }
+ return 0
+}
+
+#
+# ubsan_finish -- called at the end of each subdir of tests
+#
+
+proc ubsan_finish { args } {
+ global TEST_ALWAYS_FLAGS
+ global ubsan_saved_TEST_ALWAYS_FLAGS
+
+ if [info exists ubsan_saved_TEST_ALWAYS_FLAGS] {
+ set TEST_ALWAYS_FLAGS $ubsan_saved_TEST_ALWAYS_FLAGS
+ } else {
+ unset TEST_ALWAYS_FLAGS
+ }
+}
diff --git a/gcc/testsuite/obj-c++.dg/method-8.mm b/gcc/testsuite/obj-c++.dg/method-8.mm
index 9857c63ffe0..cde1bc27469 100644
--- a/gcc/testsuite/obj-c++.dg/method-8.mm
+++ b/gcc/testsuite/obj-c++.dg/method-8.mm
@@ -16,7 +16,7 @@
@end
@implementation class3
-- (int) meth1 { return 0; } /* { dg-error "previously defined here" } */
+- (int) meth1 { return 0; } /* { dg-message "previously defined here" } */
- (int) meth1 { return 0; } /* { dg-error "redefinition of" } */
@end
@@ -25,6 +25,6 @@
@end
@implementation class4
-+ (void) meth1 {} /* { dg-error "previously defined here" } */
++ (void) meth1 {} /* { dg-message "previously defined here" } */
+ (void) meth1 {} /* { dg-error "redefinition of" } */
@end
diff --git a/gcc/testsuite/obj-c++.dg/tls/diag-3.mm b/gcc/testsuite/obj-c++.dg/tls/diag-3.mm
index 0a597b20f8d..22c2395ab97 100644
--- a/gcc/testsuite/obj-c++.dg/tls/diag-3.mm
+++ b/gcc/testsuite/obj-c++.dg/tls/diag-3.mm
@@ -1,10 +1,10 @@
/* Report invalid extern and __thread combinations. */
/* { dg-require-effective-target tls } */
-extern int j; /* { dg-error "previously declared here" } */
+extern int j; /* { dg-message "previously declared here" } */
__thread int j; /* { dg-error "follows non-thread-local" } */
-extern __thread int i; /* { dg-error "previously declared here" } */
+extern __thread int i; /* { dg-message "previously declared here" } */
int i; /* { dg-error "follows thread-local" } */
extern __thread int k; /* This is fine. */
diff --git a/gcc/timevar.c b/gcc/timevar.c
index 3e0ccb27104..23b71186670 100644
--- a/gcc/timevar.c
+++ b/gcc/timevar.c
@@ -430,7 +430,7 @@ validate_phases (FILE *fp)
double phase_user = 0.0;
double phase_sys = 0.0;
double phase_wall = 0.0;
- unsigned phase_ggc_mem = 0;
+ size_t phase_ggc_mem = 0;
static char phase_prefix[] = "phase ";
const double tolerance = 1.000001; /* One part in a million. */
@@ -465,7 +465,8 @@ validate_phases (FILE *fp)
if (phase_wall > total->wall)
fprintf (fp, "wall %24.18e > %24.18e\n", phase_wall, total->wall);
if (phase_ggc_mem > total->ggc_mem)
- fprintf (fp, "ggc_mem %24u > %24u\n", phase_ggc_mem, total->ggc_mem);
+ fprintf (fp, "ggc_mem %24lu > %24lu\n", (unsigned long)phase_ggc_mem,
+ (unsigned long)total->ggc_mem);
gcc_unreachable ();
}
}
diff --git a/gcc/timevar.def b/gcc/timevar.def
index 44f0eac52c7..5a880a8a364 100644
--- a/gcc/timevar.def
+++ b/gcc/timevar.def
@@ -64,6 +64,10 @@ DEFTIMEVAR (TV_PCH_CPP_RESTORE , "PCH preprocessor state restore")
DEFTIMEVAR (TV_CGRAPH , "callgraph construction")
DEFTIMEVAR (TV_CGRAPHOPT , "callgraph optimization")
+DEFTIMEVAR (TV_IPA_UNREACHABLE , "ipa dead code removal")
+DEFTIMEVAR (TV_IPA_INHERITANCE , "ipa inheritance graph")
+DEFTIMEVAR (TV_IPA_VIRTUAL_CALL , "ipa virtual call target")
+DEFTIMEVAR (TV_IPA_DEVIRT , "ipa devirtualization")
DEFTIMEVAR (TV_IPA_CONSTANT_PROP , "ipa cp")
DEFTIMEVAR (TV_IPA_INLINING , "ipa inlining heuristics")
DEFTIMEVAR (TV_IPA_FNSPLIT , "ipa function splitting")
@@ -255,6 +259,7 @@ DEFTIMEVAR (TV_TREE_UNINIT , "uninit var analysis")
DEFTIMEVAR (TV_PLUGIN_INIT , "plugin initialization")
DEFTIMEVAR (TV_PLUGIN_RUN , "plugin execution")
DEFTIMEVAR (TV_GIMPLE_SLSR , "straight-line strength reduction")
+DEFTIMEVAR (TV_VTABLE_VERIFICATION , "vtable verification")
/* Everything else in rest_of_compilation not included above. */
DEFTIMEVAR (TV_EARLY_LOCAL , "early local passes")
diff --git a/gcc/timevar.h b/gcc/timevar.h
index 20deb6d7418..dc2a8bc7f99 100644
--- a/gcc/timevar.h
+++ b/gcc/timevar.h
@@ -62,7 +62,7 @@ struct timevar_time_def
double wall;
/* Garbage collector memory. */
- unsigned ggc_mem;
+ size_t ggc_mem;
};
/* An enumeration of timing variable identifiers. Constructed from
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 4921cff929a..9b421c874b0 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -76,6 +76,7 @@ along with GCC; see the file COPYING3. If not see
#include "plugin.h"
#include "diagnostic-color.h"
#include "context.h"
+#include "pass_manager.h"
#if defined(DBX_DEBUGGING_INFO) || defined(XCOFF_DEBUGGING_INFO)
#include "dbxout.h"
@@ -584,10 +585,10 @@ compile_file (void)
mudflap_finish_file ();
/* File-scope initialization for AddressSanitizer. */
- if (flag_asan)
+ if (flag_sanitize & SANITIZE_ADDRESS)
asan_finish_file ();
- if (flag_tsan)
+ if (flag_sanitize & SANITIZE_THREAD)
tsan_finish_file ();
output_shared_constant_pool ();
@@ -1033,22 +1034,35 @@ output_stack_usage (void)
{
expanded_location loc
= expand_location (DECL_SOURCE_LOCATION (current_function_decl));
- const char *raw_id, *id;
-
- /* Strip the scope prefix if any. */
- raw_id = lang_hooks.decl_printable_name (current_function_decl, 2);
- id = strrchr (raw_id, '.');
- if (id)
- id++;
+ /* We don't want to print the full qualified name because it can be long,
+ so we strip the scope prefix, but we may need to deal with the suffix
+ created by the compiler. */
+ const char *suffix
+ = strchr (IDENTIFIER_POINTER (DECL_NAME (current_function_decl)), '.');
+ const char *name
+ = lang_hooks.decl_printable_name (current_function_decl, 2);
+ if (suffix)
+ {
+ const char *dot = strchr (name, '.');
+ while (dot && strcasecmp (dot, suffix) != 0)
+ {
+ name = dot + 1;
+ dot = strchr (name, '.');
+ }
+ }
else
- id = raw_id;
+ {
+ const char *dot = strrchr (name, '.');
+ if (dot)
+ name = dot + 1;
+ }
fprintf (stack_usage_file,
"%s:%d:%d:%s\t"HOST_WIDE_INT_PRINT_DEC"\t%s\n",
lbasename (loc.file),
loc.line,
loc.column,
- id,
+ name,
stack_usage,
stack_usage_kind_str[stack_usage_kind]);
}
@@ -1188,10 +1202,10 @@ general_init (const char *argv0)
processing. */
init_ggc_heuristics();
- /* Create the singleton holder for global state. */
+ /* Create the singleton holder for global state.
+ Doing so also creates the pass manager and with it the passes. */
g = new gcc::context();
- init_optimization_passes ();
statistics_early_init ();
finish_params ();
}
@@ -1571,12 +1585,12 @@ process_options (void)
warn_stack_protect = 0;
/* Address Sanitizer needs porting to each target architecture. */
- if (flag_asan
+ if ((flag_sanitize & SANITIZE_ADDRESS)
&& (targetm.asan_shadow_offset == NULL
|| !FRAME_GROWS_DOWNWARD))
{
warning (0, "-fsanitize=address not supported for this target");
- flag_asan = 0;
+ flag_sanitize &= ~SANITIZE_ADDRESS;
}
/* Enable -Werror=coverage-mismatch when -Werror and -Wno-error
@@ -1848,7 +1862,7 @@ finalize (bool no_backend)
{
statistics_fini ();
- finish_optimization_passes ();
+ g->get_passes ()->finish_optimization_passes ();
ira_finish_once ();
}
diff --git a/gcc/toplev.h b/gcc/toplev.h
index 707b960c2be..afc56bdf759 100644
--- a/gcc/toplev.h
+++ b/gcc/toplev.h
@@ -28,7 +28,6 @@ extern int toplev_main (int, char **);
extern void rest_of_decl_compilation (tree, int, int);
extern void rest_of_type_compilation (tree, int);
extern void init_optimization_passes (void);
-extern void finish_optimization_passes (void);
extern bool enable_rtl_dump_file (void);
/* In except.c. Initialize exception handling. This is used by the Ada
diff --git a/gcc/tracer.c b/gcc/tracer.c
index 975cadb9285..0139669aa16 100644
--- a/gcc/tracer.c
+++ b/gcc/tracer.c
@@ -397,23 +397,40 @@ gate_tracer (void)
return (optimize > 0 && flag_tracer && flag_reorder_blocks);
}
-struct gimple_opt_pass pass_tracer =
+namespace {
+
+const pass_data pass_data_tracer =
{
- {
- GIMPLE_PASS,
- "tracer", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tracer, /* gate */
- tracer, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TRACER, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "tracer", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TRACER, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
};
+
+class pass_tracer : public gimple_opt_pass
+{
+public:
+ pass_tracer(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tracer, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tracer (); }
+ unsigned int execute () { return tracer (); }
+
+}; // class pass_tracer
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tracer (gcc::context *ctxt)
+{
+ return new pass_tracer (ctxt);
+}
diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c
index 6289ea46a89..220ded277b5 100644
--- a/gcc/trans-mem.c
+++ b/gcc/trans-mem.c
@@ -801,25 +801,43 @@ diagnose_tm_blocks (void)
return 0;
}
-struct gimple_opt_pass pass_diagnose_tm_blocks =
-{
- {
- GIMPLE_PASS,
- "*diagnose_tm_blocks", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tm, /* gate */
- diagnose_tm_blocks, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TRANS_MEM, /* tv_id */
- PROP_gimple_any, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_diagnose_tm_blocks =
+{
+ GIMPLE_PASS, /* type */
+ "*diagnose_tm_blocks", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TRANS_MEM, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_diagnose_tm_blocks : public gimple_opt_pass
+{
+public:
+ pass_diagnose_tm_blocks(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_diagnose_tm_blocks, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tm (); }
+ unsigned int execute () { return diagnose_tm_blocks (); }
+
+}; // class pass_diagnose_tm_blocks
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_diagnose_tm_blocks (gcc::context *ctxt)
+{
+ return new pass_diagnose_tm_blocks (ctxt);
+}
/* Instead of instrumenting thread private memory, we save the
addresses in a log which we later use to save/restore the addresses
@@ -1706,25 +1724,43 @@ execute_lower_tm (void)
return 0;
}
-struct gimple_opt_pass pass_lower_tm =
-{
- {
- GIMPLE_PASS,
- "tmlower", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tm, /* gate */
- execute_lower_tm, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TRANS_MEM, /* tv_id */
- PROP_gimple_lcf, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_lower_tm =
+{
+ GIMPLE_PASS, /* type */
+ "tmlower", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TRANS_MEM, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_lower_tm : public gimple_opt_pass
+{
+public:
+ pass_lower_tm(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_tm, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tm (); }
+ unsigned int execute () { return execute_lower_tm (); }
+
+}; // class pass_lower_tm
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_tm (gcc::context *ctxt)
+{
+ return new pass_lower_tm (ctxt);
+}
/* Collect region information for each transaction. */
@@ -1968,25 +2004,42 @@ gate_tm_init (void)
return true;
}
-struct gimple_opt_pass pass_tm_init =
-{
- {
- GIMPLE_PASS,
- "*tminit", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tm_init, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TRANS_MEM, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_tm_init =
+{
+ GIMPLE_PASS, /* type */
+ "*tminit", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_TRANS_MEM, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_tm_init : public gimple_opt_pass
+{
+public:
+ pass_tm_init(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tm_init, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tm_init (); }
+
+}; // class pass_tm_init
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tm_init (gcc::context *ctxt)
+{
+ return new pass_tm_init (ctxt);
+}
/* Add FLAGS to the GIMPLE_TRANSACTION subcode for the transaction region
represented by STATE. */
@@ -2927,26 +2980,42 @@ execute_tm_mark (void)
return 0;
}
-struct gimple_opt_pass pass_tm_mark =
-{
- {
- GIMPLE_PASS,
- "tmmark", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_tm_mark, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TRANS_MEM, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_tm_mark =
+{
+ GIMPLE_PASS, /* type */
+ "tmmark", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TRANS_MEM, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
};
+
+class pass_tm_mark : public gimple_opt_pass
+{
+public:
+ pass_tm_mark(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tm_mark, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_tm_mark (); }
+
+}; // class pass_tm_mark
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tm_mark (gcc::context *ctxt)
+{
+ return new pass_tm_mark (ctxt);
+}
/* Create an abnormal edge from STMT at iter, splitting the block
@@ -3094,26 +3163,42 @@ execute_tm_edges (void)
return 0;
}
-struct gimple_opt_pass pass_tm_edges =
-{
- {
- GIMPLE_PASS,
- "tmedge", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_tm_edges, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TRANS_MEM, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_tm_edges =
+{
+ GIMPLE_PASS, /* type */
+ "tmedge", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TRANS_MEM, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
};
+
+class pass_tm_edges : public gimple_opt_pass
+{
+public:
+ pass_tm_edges(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tm_edges, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_tm_edges (); }
+
+}; // class pass_tm_edges
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tm_edges (gcc::context *ctxt)
+{
+ return new pass_tm_edges (ctxt);
+}
/* Helper function for expand_regions. Expand REGION and recurse to
the inner region. Call CALLBACK on each region. CALLBACK returns
@@ -3818,26 +3903,44 @@ gate_tm_memopt (void)
return flag_tm && optimize > 0;
}
-struct gimple_opt_pass pass_tm_memopt =
-{
- {
- GIMPLE_PASS,
- "tmmemopt", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tm_memopt, /* gate */
- execute_tm_memopt, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TRANS_MEM, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_tm_memopt =
+{
+ GIMPLE_PASS, /* type */
+ "tmmemopt", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TRANS_MEM, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_tm_memopt : public gimple_opt_pass
+{
+public:
+ pass_tm_memopt(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tm_memopt, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tm_memopt (); }
+ unsigned int execute () { return execute_tm_memopt (); }
+
+}; // class pass_tm_memopt
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tm_memopt (gcc::context *ctxt)
+{
+ return new pass_tm_memopt (ctxt);
+}
+
/* Interprocedual analysis for the creation of transactional clones.
The aim of this pass is to find which functions are referenced in
@@ -4774,6 +4877,7 @@ ipa_tm_create_version (struct cgraph_node *old_node)
DECL_COMDAT_GROUP (new_decl) = tm_mangle (DECL_COMDAT_GROUP (old_decl));
new_node = cgraph_copy_node_for_versioning (old_node, new_decl, vNULL, NULL);
+ new_node->local.local = false;
new_node->symbol.externally_visible = old_node->symbol.externally_visible;
new_node->lowered = true;
new_node->tm_clone = 1;
@@ -5434,24 +5538,42 @@ ipa_tm_execute (void)
return 0;
}
-struct simple_ipa_opt_pass pass_ipa_tm =
-{
- {
- SIMPLE_IPA_PASS,
- "tmipa", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tm, /* gate */
- ipa_tm_execute, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TRANS_MEM, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- },
+namespace {
+
+const pass_data pass_data_ipa_tm =
+{
+ SIMPLE_IPA_PASS, /* type */
+ "tmipa", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TRANS_MEM, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_ipa_tm : public simple_ipa_opt_pass
+{
+public:
+ pass_ipa_tm(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_ipa_tm, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tm (); }
+ unsigned int execute () { return ipa_tm_execute (); }
+
+}; // class pass_ipa_tm
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_tm (gcc::context *ctxt)
+{
+ return new pass_ipa_tm (ctxt);
+}
+
#include "gt-trans-mem.h"
diff --git a/gcc/tree-affine.c b/gcc/tree-affine.c
index 46a183a07b4..81da521277f 100644
--- a/gcc/tree-affine.c
+++ b/gcc/tree-affine.c
@@ -377,35 +377,53 @@ add_elt_to_tree (tree expr, tree type, tree elt, double_int scale,
type1 = sizetype;
scale = double_int_ext_for_comb (scale, comb);
- elt = fold_convert (type1, elt);
+
+ if (scale.is_minus_one ()
+ && POINTER_TYPE_P (TREE_TYPE (elt)))
+ {
+ elt = convert_to_ptrofftype (elt);
+ elt = fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt);
+ scale = double_int_one;
+ }
if (scale.is_one ())
{
if (!expr)
- return fold_convert (type, elt);
+ {
+ if (POINTER_TYPE_P (TREE_TYPE (elt)))
+ return elt;
+ else
+ return fold_convert (type1, elt);
+ }
- if (POINTER_TYPE_P (type))
- return fold_build_pointer_plus (expr, elt);
- return fold_build2 (PLUS_EXPR, type, expr, elt);
+ if (POINTER_TYPE_P (TREE_TYPE (expr)))
+ return fold_build_pointer_plus (expr, elt);
+ if (POINTER_TYPE_P (TREE_TYPE (elt)))
+ return fold_build_pointer_plus (elt, expr);
+ return fold_build2 (PLUS_EXPR, type1,
+ expr, fold_convert (type1, elt));
}
if (scale.is_minus_one ())
{
if (!expr)
- return fold_convert (type, fold_build1 (NEGATE_EXPR, type1, elt));
+ return fold_build1 (NEGATE_EXPR, type1,
+ fold_convert (type1, elt));
- if (POINTER_TYPE_P (type))
+ if (POINTER_TYPE_P (TREE_TYPE (expr)))
{
- elt = fold_build1 (NEGATE_EXPR, type1, elt);
+ elt = convert_to_ptrofftype (elt);
+ elt = fold_build1 (NEGATE_EXPR, TREE_TYPE (elt), elt);
return fold_build_pointer_plus (expr, elt);
}
- return fold_build2 (MINUS_EXPR, type, expr, elt);
+ return fold_build2 (MINUS_EXPR, type1,
+ expr, fold_convert (type1, elt));
}
+ elt = fold_convert (type1, elt);
if (!expr)
- return fold_convert (type,
- fold_build2 (MULT_EXPR, type1, elt,
- double_int_to_tree (type1, scale)));
+ return fold_build2 (MULT_EXPR, type1, elt,
+ double_int_to_tree (type1, scale));
if (scale.is_negative ())
{
@@ -417,13 +435,13 @@ add_elt_to_tree (tree expr, tree type, tree elt, double_int scale,
elt = fold_build2 (MULT_EXPR, type1, elt,
double_int_to_tree (type1, scale));
- if (POINTER_TYPE_P (type))
+ if (POINTER_TYPE_P (TREE_TYPE (expr)))
{
if (code == MINUS_EXPR)
elt = fold_build1 (NEGATE_EXPR, type1, elt);
return fold_build_pointer_plus (expr, elt);
}
- return fold_build2 (code, type, expr, elt);
+ return fold_build2 (code, type1, expr, elt);
}
/* Makes tree from the affine combination COMB. */
diff --git a/gcc/tree-call-cdce.c b/gcc/tree-call-cdce.c
index 9b6186e3393..1396388676b 100644
--- a/gcc/tree-call-cdce.c
+++ b/gcc/tree-call-cdce.c
@@ -726,15 +726,28 @@ shrink_wrap_one_built_in_call (gimple bi_call)
return false and do not do any transformation for
the call. */
if (nconds == 0)
- return false;
+ {
+ conds.release ();
+ return false;
+ }
bi_call_bb = gimple_bb (bi_call);
- /* Now find the join target bb -- split
- bi_call_bb if needed. */
- bi_call_bsi = gsi_for_stmt (bi_call);
+ /* Now find the join target bb -- split bi_call_bb if needed. */
+ if (stmt_ends_bb_p (bi_call))
+ {
+ /* If the call must be the last in the bb, don't split the block,
+ it could e.g. have EH edges. */
+ join_tgt_in_edge_from_call = find_fallthru_edge (bi_call_bb->succs);
+ if (join_tgt_in_edge_from_call == NULL)
+ {
+ conds.release ();
+ return false;
+ }
+ }
+ else
+ join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call);
- join_tgt_in_edge_from_call = split_block (bi_call_bb, bi_call);
bi_call_bsi = gsi_for_stmt (bi_call);
join_tgt_bb = join_tgt_in_edge_from_call->dest;
@@ -913,22 +926,40 @@ gate_call_cdce (void)
return flag_tree_builtin_call_dce != 0 && optimize_function_for_speed_p (cfun);
}
-struct gimple_opt_pass pass_call_cdce =
+namespace {
+
+const pass_data pass_data_call_cdce =
{
- {
- GIMPLE_PASS,
- "cdce", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_call_cdce, /* gate */
- tree_call_cdce, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_CALL_CDCE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "cdce", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_CALL_CDCE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_call_cdce : public gimple_opt_pass
+{
+public:
+ pass_call_cdce(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_call_cdce, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_call_cdce (); }
+ unsigned int execute () { return tree_call_cdce (); }
+
+}; // class pass_call_cdce
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_call_cdce (gcc::context *ctxt)
+{
+ return new pass_call_cdce (ctxt);
+}
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 4b91a35f17d..c74b9885933 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -253,26 +253,43 @@ execute_build_cfg (void)
return 0;
}
-struct gimple_opt_pass pass_build_cfg =
-{
- {
- GIMPLE_PASS,
- "cfg", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_build_cfg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_CFG, /* tv_id */
- PROP_gimple_leh, /* properties_required */
- PROP_cfg | PROP_loops, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_stmts /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_build_cfg =
+{
+ GIMPLE_PASS, /* type */
+ "cfg", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_CFG, /* tv_id */
+ PROP_gimple_leh, /* properties_required */
+ ( PROP_cfg | PROP_loops ), /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_stmts, /* todo_flags_finish */
};
+class pass_build_cfg : public gimple_opt_pass
+{
+public:
+ pass_build_cfg(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_build_cfg, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_build_cfg (); }
+
+}; // class pass_build_cfg
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_build_cfg (gcc::context *ctxt)
+{
+ return new pass_build_cfg (ctxt);
+}
+
/* Return true if T is a computed goto. */
@@ -3554,11 +3571,10 @@ verify_gimple_assign_binary (gimple stmt)
case PLUS_EXPR:
case MINUS_EXPR:
{
- /* We use regular PLUS_EXPR and MINUS_EXPR for vectors.
- ??? This just makes the checker happy and may not be what is
- intended. */
- if (TREE_CODE (lhs_type) == VECTOR_TYPE
- && POINTER_TYPE_P (TREE_TYPE (lhs_type)))
+ tree lhs_etype = lhs_type;
+ tree rhs1_etype = rhs1_type;
+ tree rhs2_etype = rhs2_type;
+ if (TREE_CODE (lhs_type) == VECTOR_TYPE)
{
if (TREE_CODE (rhs1_type) != VECTOR_TYPE
|| TREE_CODE (rhs2_type) != VECTOR_TYPE)
@@ -3566,22 +3582,13 @@ verify_gimple_assign_binary (gimple stmt)
error ("invalid non-vector operands to vector valued plus");
return true;
}
- lhs_type = TREE_TYPE (lhs_type);
- rhs1_type = TREE_TYPE (rhs1_type);
- rhs2_type = TREE_TYPE (rhs2_type);
- /* PLUS_EXPR is commutative, so we might end up canonicalizing
- the pointer to 2nd place. */
- if (POINTER_TYPE_P (rhs2_type))
- {
- tree tem = rhs1_type;
- rhs1_type = rhs2_type;
- rhs2_type = tem;
- }
- goto do_pointer_plus_expr_check;
+ lhs_etype = TREE_TYPE (lhs_type);
+ rhs1_etype = TREE_TYPE (rhs1_type);
+ rhs2_etype = TREE_TYPE (rhs2_type);
}
- if (POINTER_TYPE_P (lhs_type)
- || POINTER_TYPE_P (rhs1_type)
- || POINTER_TYPE_P (rhs2_type))
+ if (POINTER_TYPE_P (lhs_etype)
+ || POINTER_TYPE_P (rhs1_etype)
+ || POINTER_TYPE_P (rhs2_etype))
{
error ("invalid (pointer) operands to plus/minus");
return true;
@@ -3593,7 +3600,6 @@ verify_gimple_assign_binary (gimple stmt)
case POINTER_PLUS_EXPR:
{
-do_pointer_plus_expr_check:
if (!POINTER_TYPE_P (rhs1_type)
|| !useless_type_conversion_p (lhs_type, rhs1_type)
|| !ptrofftype_p (rhs2_type))
@@ -4235,6 +4241,12 @@ verify_gimple_label (gimple stmt)
if (TREE_CODE (decl) != LABEL_DECL)
return true;
+ if (!DECL_NONLOCAL (decl) && !FORCED_LABEL (decl)
+ && DECL_CONTEXT (decl) != current_function_decl)
+ {
+ error ("label's context is not the current function decl");
+ err |= true;
+ }
uid = LABEL_DECL_UID (decl);
if (cfun->cfg
@@ -7890,26 +7902,43 @@ split_critical_edges (void)
return 0;
}
-struct gimple_opt_pass pass_split_crit_edges =
-{
- {
- GIMPLE_PASS,
- "crited", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- split_critical_edges, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SPLIT_EDGES, /* tv_id */
- PROP_cfg, /* properties required */
- PROP_no_crit_edges, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_split_crit_edges =
+{
+ GIMPLE_PASS, /* type */
+ "crited", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SPLIT_EDGES, /* tv_id */
+ PROP_cfg, /* properties_required */
+ PROP_no_crit_edges, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_flow, /* todo_flags_finish */
};
+class pass_split_crit_edges : public gimple_opt_pass
+{
+public:
+ pass_split_crit_edges(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_split_crit_edges, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return split_critical_edges (); }
+
+}; // class pass_split_crit_edges
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_split_crit_edges (gcc::context *ctxt)
+{
+ return new pass_split_crit_edges (ctxt);
+}
+
/* Build a ternary operation and gimplify it. Emit code before GSI.
Return the gimple_val holding the result. */
@@ -8044,26 +8073,43 @@ extract_true_false_edges_from_block (basic_block b,
}
}
-struct gimple_opt_pass pass_warn_function_return =
-{
- {
- GIMPLE_PASS,
- "*warn_function_return", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_warn_function_return, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_warn_function_return =
+{
+ GIMPLE_PASS, /* type */
+ "*warn_function_return", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_warn_function_return : public gimple_opt_pass
+{
+public:
+ pass_warn_function_return(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_warn_function_return, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_warn_function_return (); }
+
+}; // class pass_warn_function_return
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_warn_function_return (gcc::context *ctxt)
+{
+ return new pass_warn_function_return (ctxt);
+}
+
/* Emit noreturn warnings. */
static unsigned int
@@ -8081,26 +8127,44 @@ gate_warn_function_noreturn (void)
return warn_suggest_attribute_noreturn;
}
-struct gimple_opt_pass pass_warn_function_noreturn =
-{
- {
- GIMPLE_PASS,
- "*warn_function_noreturn", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_warn_function_noreturn, /* gate */
- execute_warn_function_noreturn, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_warn_function_noreturn =
+{
+ GIMPLE_PASS, /* type */
+ "*warn_function_noreturn", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_warn_function_noreturn : public gimple_opt_pass
+{
+public:
+ pass_warn_function_noreturn(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_warn_function_noreturn, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_warn_function_noreturn (); }
+ unsigned int execute () { return execute_warn_function_noreturn (); }
+
+}; // class pass_warn_function_noreturn
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_warn_function_noreturn (gcc::context *ctxt)
+{
+ return new pass_warn_function_noreturn (ctxt);
+}
+
/* Walk a gimplified function and warn for functions whose return value is
ignored and attribute((warn_unused_result)) is set. This is done before
@@ -8180,26 +8244,44 @@ gate_warn_unused_result (void)
return flag_warn_unused_result;
}
-struct gimple_opt_pass pass_warn_unused_result =
-{
- {
- GIMPLE_PASS,
- "*warn_unused_result", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_warn_unused_result, /* gate */
- run_warn_unused_result, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_gimple_any, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_warn_unused_result =
+{
+ GIMPLE_PASS, /* type */
+ "*warn_unused_result", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_warn_unused_result : public gimple_opt_pass
+{
+public:
+ pass_warn_unused_result(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_warn_unused_result, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_warn_unused_result (); }
+ unsigned int execute () { return run_warn_unused_result (); }
+
+}; // class pass_warn_unused_result
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_warn_unused_result (gcc::context *ctxt)
+{
+ return new pass_warn_unused_result (ctxt);
+}
+
/* Garbage collection support for edge_def. */
diff --git a/gcc/tree-cfgcleanup.c b/gcc/tree-cfgcleanup.c
index 9b314f73ea6..8917f855705 100644
--- a/gcc/tree-cfgcleanup.c
+++ b/gcc/tree-cfgcleanup.c
@@ -989,22 +989,41 @@ gate_merge_phi (void)
return 1;
}
-struct gimple_opt_pass pass_merge_phi =
+namespace {
+
+const pass_data pass_data_merge_phi =
{
- {
- GIMPLE_PASS,
- "mergephi", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_merge_phi, /* gate */
- merge_phi_nodes, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_MERGE_PHI, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "mergephi", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_MERGE_PHI, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_merge_phi : public gimple_opt_pass
+{
+public:
+ pass_merge_phi(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_merge_phi, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_merge_phi (ctxt_); }
+ bool gate () { return gate_merge_phi (); }
+ unsigned int execute () { return merge_phi_nodes (); }
+
+}; // class pass_merge_phi
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_merge_phi (gcc::context *ctxt)
+{
+ return new pass_merge_phi (ctxt);
+}
diff --git a/gcc/tree-complex.c b/gcc/tree-complex.c
index 5caba01cde4..225728fdaeb 100644
--- a/gcc/tree-complex.c
+++ b/gcc/tree-complex.c
@@ -1637,27 +1637,44 @@ tree_lower_complex (void)
return 0;
}
-struct gimple_opt_pass pass_lower_complex =
+namespace {
+
+const pass_data pass_data_lower_complex =
{
- {
- GIMPLE_PASS,
- "cplxlower", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- 0, /* gate */
- tree_lower_complex, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- PROP_gimple_lcx, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_stmts /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "cplxlower", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ PROP_gimple_lcx, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_stmts ), /* todo_flags_finish */
};
+class pass_lower_complex : public gimple_opt_pass
+{
+public:
+ pass_lower_complex(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_complex, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_lower_complex (ctxt_); }
+ unsigned int execute () { return tree_lower_complex (); }
+
+}; // class pass_lower_complex
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_complex (gcc::context *ctxt)
+{
+ return new pass_lower_complex (ctxt);
+}
+
static bool
gate_no_optimization (void)
@@ -1667,23 +1684,40 @@ gate_no_optimization (void)
return !(cfun->curr_properties & PROP_gimple_lcx);
}
-struct gimple_opt_pass pass_lower_complex_O0 =
+namespace {
+
+const pass_data pass_data_lower_complex_O0 =
{
- {
- GIMPLE_PASS,
- "cplxlower0", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_no_optimization, /* gate */
- tree_lower_complex, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- PROP_gimple_lcx, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_stmts /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "cplxlower0", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ PROP_gimple_lcx, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_stmts ), /* todo_flags_finish */
};
+
+class pass_lower_complex_O0 : public gimple_opt_pass
+{
+public:
+ pass_lower_complex_O0(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_complex_O0, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_no_optimization (); }
+ unsigned int execute () { return tree_lower_complex (); }
+
+}; // class pass_lower_complex_O0
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_complex_O0 (gcc::context *ctxt)
+{
+ return new pass_lower_complex_O0 (ctxt);
+}
diff --git a/gcc/tree-core.h b/gcc/tree-core.h
new file mode 100644
index 00000000000..b1bc56ae29f
--- /dev/null
+++ b/gcc/tree-core.h
@@ -0,0 +1,1693 @@
+/* Core data structures for the 'tree' type.
+ Copyright (C) 1989-2013 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_TREE_CORE_H
+#define GCC_TREE_CORE_H
+
+#include "hashtab.h"
+#include "machmode.h"
+#include "input.h"
+#include "statistics.h"
+#include "vec.h"
+#include "double-int.h"
+#include "real.h"
+#include "fixed-value.h"
+#include "alias.h"
+#include "flags.h"
+#include "symtab.h"
+
+/* This file contains all the data structures that define the 'tree' type.
+ There are no accessor macros nor functions in this file. Only the
+ basic data structures, extern declarations and type definitions. */
+
+/*---------------------------------------------------------------------------
+ Forward type declarations. Mostly to avoid including unnecessary headers
+---------------------------------------------------------------------------*/
+struct function;
+struct real_value;
+struct fixed_value;
+struct ptr_info_def;
+struct die_struct;
+struct pointer_set_t;
+
+
+/*---------------------------------------------------------------------------
+ #defined constants
+---------------------------------------------------------------------------*/
+/* Nonzero if this is a call to a function whose return value depends
+ solely on its arguments, has no side effects, and does not read
+ global memory. This corresponds to TREE_READONLY for function
+ decls. */
+#define ECF_CONST (1 << 0)
+
+/* Nonzero if this is a call to "pure" function (like const function,
+ but may read memory. This corresponds to DECL_PURE_P for function
+ decls. */
+#define ECF_PURE (1 << 1)
+
+/* Nonzero if this is ECF_CONST or ECF_PURE but cannot be proven to no
+ infinite loop. This corresponds to DECL_LOOPING_CONST_OR_PURE_P
+ for function decls.*/
+#define ECF_LOOPING_CONST_OR_PURE (1 << 2)
+
+/* Nonzero if this call will never return. */
+#define ECF_NORETURN (1 << 3)
+
+/* Nonzero if this is a call to malloc or a related function. */
+#define ECF_MALLOC (1 << 4)
+
+/* Nonzero if it is plausible that this is a call to alloca. */
+#define ECF_MAY_BE_ALLOCA (1 << 5)
+
+/* Nonzero if this is a call to a function that won't throw an exception. */
+#define ECF_NOTHROW (1 << 6)
+
+/* Nonzero if this is a call to setjmp or a related function. */
+#define ECF_RETURNS_TWICE (1 << 7)
+
+/* Nonzero if this call replaces the current stack frame. */
+#define ECF_SIBCALL (1 << 8)
+
+/* Function does not read or write memory (but may have side effects, so
+ it does not necessarily fit ECF_CONST). */
+#define ECF_NOVOPS (1 << 9)
+
+/* The function does not lead to calls within current function unit. */
+#define ECF_LEAF (1 << 10)
+
+/* Nonzero if this call does not affect transactions. */
+#define ECF_TM_PURE (1 << 11)
+
+/* Nonzero if this call is into the transaction runtime library. */
+#define ECF_TM_BUILTIN (1 << 12)
+
+/* Call argument flags. */
+/* Nonzero if the argument is not dereferenced recursively, thus only
+ directly reachable memory is read or written. */
+#define EAF_DIRECT (1 << 0)
+
+/* Nonzero if memory reached by the argument is not clobbered. */
+#define EAF_NOCLOBBER (1 << 1)
+
+/* Nonzero if the argument does not escape. */
+#define EAF_NOESCAPE (1 << 2)
+
+/* Nonzero if the argument is not used by the function. */
+#define EAF_UNUSED (1 << 3)
+
+/* Call return flags. */
+/* Mask for the argument number that is returned. Lower two bits of
+ the return flags, encodes argument slots zero to three. */
+#define ERF_RETURN_ARG_MASK (3)
+
+/* Nonzero if the return value is equal to the argument number
+ flags & ERF_RETURN_ARG_MASK. */
+#define ERF_RETURNS_ARG (1 << 2)
+
+/* Nonzero if the return value does not alias with anything. Functions
+ with the malloc attribute have this set on their return value. */
+#define ERF_NOALIAS (1 << 3)
+
+
+/*---------------------------------------------------------------------------
+ Enumerations
+---------------------------------------------------------------------------*/
+/* Codes of tree nodes. */
+#define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM,
+#define END_OF_BASE_TREE_CODES LAST_AND_UNUSED_TREE_CODE,
+
+enum tree_code {
+#include "all-tree.def"
+MAX_TREE_CODES
+};
+
+#undef DEFTREECODE
+#undef END_OF_BASE_TREE_CODES
+
+/* Number of language-independent tree codes. */
+#define NUM_TREE_CODES \
+ ((int) LAST_AND_UNUSED_TREE_CODE)
+
+#define CODE_CONTAINS_STRUCT(CODE, STRUCT) \
+ (tree_contains_struct[(CODE)][(STRUCT)])
+
+
+/* Classify which part of the compiler has defined a given builtin function.
+ Note that we assume below that this is no more than two bits. */
+enum built_in_class {
+ NOT_BUILT_IN = 0,
+ BUILT_IN_FRONTEND,
+ BUILT_IN_MD,
+ BUILT_IN_NORMAL
+};
+
+/* Last marker used for LTO stremaing of built_in_class. We can not add it
+ to the enum since we need the enumb to fit in 2 bits. */
+#define BUILT_IN_LAST (BUILT_IN_NORMAL + 1)
+
+/* Codes that identify the various built in functions
+ so that expand_call can identify them quickly. */
+#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM,
+enum built_in_function {
+#include "builtins.def"
+
+ /* Complex division routines in libgcc. These are done via builtins
+ because emit_library_call_value can't handle complex values. */
+ BUILT_IN_COMPLEX_MUL_MIN,
+ BUILT_IN_COMPLEX_MUL_MAX
+ = BUILT_IN_COMPLEX_MUL_MIN
+ + MAX_MODE_COMPLEX_FLOAT
+ - MIN_MODE_COMPLEX_FLOAT,
+
+ BUILT_IN_COMPLEX_DIV_MIN,
+ BUILT_IN_COMPLEX_DIV_MAX
+ = BUILT_IN_COMPLEX_DIV_MIN
+ + MAX_MODE_COMPLEX_FLOAT
+ - MIN_MODE_COMPLEX_FLOAT,
+
+ /* Upper bound on non-language-specific builtins. */
+ END_BUILTINS
+};
+#undef DEF_BUILTIN
+
+/* Tree code classes. Each tree_code has an associated code class
+ represented by a TREE_CODE_CLASS. */
+enum tree_code_class {
+ tcc_exceptional, /* An exceptional code (fits no category). */
+ tcc_constant, /* A constant. */
+ /* Order of tcc_type and tcc_declaration is important. */
+ tcc_type, /* A type object code. */
+ tcc_declaration, /* A declaration (also serving as variable refs). */
+ tcc_reference, /* A reference to storage. */
+ tcc_comparison, /* A comparison expression. */
+ tcc_unary, /* A unary arithmetic expression. */
+ tcc_binary, /* A binary arithmetic expression. */
+ tcc_statement, /* A statement expression, which have side effects
+ but usually no interesting value. */
+ tcc_vl_exp, /* A function call or other expression with a
+ variable-length operand vector. */
+ tcc_expression /* Any other expression. */
+};
+
+/* OMP_CLAUSE codes. Do not reorder, as this is used to index into
+ the tables omp_clause_num_ops and omp_clause_code_name. */
+enum omp_clause_code {
+ /* Clause zero is special-cased inside the parser
+ (c_parser_omp_variable_list). */
+ OMP_CLAUSE_ERROR = 0,
+
+ /* OpenMP clause: private (variable_list). */
+ OMP_CLAUSE_PRIVATE,
+
+ /* OpenMP clause: shared (variable_list). */
+ OMP_CLAUSE_SHARED,
+
+ /* OpenMP clause: firstprivate (variable_list). */
+ OMP_CLAUSE_FIRSTPRIVATE,
+
+ /* OpenMP clause: lastprivate (variable_list). */
+ OMP_CLAUSE_LASTPRIVATE,
+
+ /* OpenMP clause: reduction (operator:variable_list).
+ OMP_CLAUSE_REDUCTION_CODE: The tree_code of the operator.
+ Operand 1: OMP_CLAUSE_REDUCTION_INIT: Stmt-list to initialize the var.
+ Operand 2: OMP_CLAUSE_REDUCTION_MERGE: Stmt-list to merge private var
+ into the shared one.
+ Operand 3: OMP_CLAUSE_REDUCTION_PLACEHOLDER: A dummy VAR_DECL
+ placeholder used in OMP_CLAUSE_REDUCTION_{INIT,MERGE}. */
+ OMP_CLAUSE_REDUCTION,
+
+ /* OpenMP clause: copyin (variable_list). */
+ OMP_CLAUSE_COPYIN,
+
+ /* OpenMP clause: copyprivate (variable_list). */
+ OMP_CLAUSE_COPYPRIVATE,
+
+ /* OpenMP clause: linear (variable-list[:linear-step]). */
+ OMP_CLAUSE_LINEAR,
+
+ /* OpenMP clause: uniform (argument-list). */
+ OMP_CLAUSE_UNIFORM,
+
+ /* OpenMP clause: if (scalar-expression). */
+ OMP_CLAUSE_IF,
+
+ /* OpenMP clause: num_threads (integer-expression). */
+ OMP_CLAUSE_NUM_THREADS,
+
+ /* OpenMP clause: schedule. */
+ OMP_CLAUSE_SCHEDULE,
+
+ /* OpenMP clause: nowait. */
+ OMP_CLAUSE_NOWAIT,
+
+ /* OpenMP clause: ordered. */
+ OMP_CLAUSE_ORDERED,
+
+ /* OpenMP clause: default. */
+ OMP_CLAUSE_DEFAULT,
+
+ /* OpenMP clause: collapse (constant-integer-expression). */
+ OMP_CLAUSE_COLLAPSE,
+
+ /* OpenMP clause: untied. */
+ OMP_CLAUSE_UNTIED,
+
+ /* OpenMP clause: final (scalar-expression). */
+ OMP_CLAUSE_FINAL,
+
+ /* OpenMP clause: mergeable. */
+ OMP_CLAUSE_MERGEABLE,
+
+ /* OpenMP clause: safelen (constant-integer-expression). */
+ OMP_CLAUSE_SAFELEN,
+
+ /* Internally used only clause, holding SIMD uid. */
+ OMP_CLAUSE__SIMDUID_
+};
+
+#undef DEFTREESTRUCT
+#define DEFTREESTRUCT(ENUM, NAME) ENUM,
+enum tree_node_structure_enum {
+#include "treestruct.def"
+ LAST_TS_ENUM
+};
+#undef DEFTREESTRUCT
+
+enum omp_clause_schedule_kind {
+ OMP_CLAUSE_SCHEDULE_STATIC,
+ OMP_CLAUSE_SCHEDULE_DYNAMIC,
+ OMP_CLAUSE_SCHEDULE_GUIDED,
+ OMP_CLAUSE_SCHEDULE_AUTO,
+ OMP_CLAUSE_SCHEDULE_RUNTIME
+};
+
+enum omp_clause_default_kind {
+ OMP_CLAUSE_DEFAULT_UNSPECIFIED,
+ OMP_CLAUSE_DEFAULT_SHARED,
+ OMP_CLAUSE_DEFAULT_NONE,
+ OMP_CLAUSE_DEFAULT_PRIVATE,
+ OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
+};
+
+/* There is a TYPE_QUAL value for each type qualifier. They can be
+ combined by bitwise-or to form the complete set of qualifiers for a
+ type. */
+enum cv_qualifier {
+ TYPE_UNQUALIFIED = 0x0,
+ TYPE_QUAL_CONST = 0x1,
+ TYPE_QUAL_VOLATILE = 0x2,
+ TYPE_QUAL_RESTRICT = 0x4
+};
+
+/* Enumerate visibility settings. */
+#ifndef SYMBOL_VISIBILITY_DEFINED
+#define SYMBOL_VISIBILITY_DEFINED
+enum symbol_visibility {
+ VISIBILITY_DEFAULT,
+ VISIBILITY_PROTECTED,
+ VISIBILITY_HIDDEN,
+ VISIBILITY_INTERNAL
+};
+#endif // SYMBOL_VISIBILITY_DEFINED
+
+/* Standard named or nameless data types of the C compiler. */
+enum tree_index {
+ TI_ERROR_MARK,
+ TI_INTQI_TYPE,
+ TI_INTHI_TYPE,
+ TI_INTSI_TYPE,
+ TI_INTDI_TYPE,
+ TI_INTTI_TYPE,
+
+ TI_UINTQI_TYPE,
+ TI_UINTHI_TYPE,
+ TI_UINTSI_TYPE,
+ TI_UINTDI_TYPE,
+ TI_UINTTI_TYPE,
+
+ TI_UINT16_TYPE,
+ TI_UINT32_TYPE,
+ TI_UINT64_TYPE,
+
+ TI_INTEGER_ZERO,
+ TI_INTEGER_ONE,
+ TI_INTEGER_THREE,
+ TI_INTEGER_MINUS_ONE,
+ TI_NULL_POINTER,
+
+ TI_SIZE_ZERO,
+ TI_SIZE_ONE,
+
+ TI_BITSIZE_ZERO,
+ TI_BITSIZE_ONE,
+ TI_BITSIZE_UNIT,
+
+ TI_PUBLIC,
+ TI_PROTECTED,
+ TI_PRIVATE,
+
+ TI_BOOLEAN_FALSE,
+ TI_BOOLEAN_TRUE,
+
+ TI_COMPLEX_INTEGER_TYPE,
+ TI_COMPLEX_FLOAT_TYPE,
+ TI_COMPLEX_DOUBLE_TYPE,
+ TI_COMPLEX_LONG_DOUBLE_TYPE,
+
+ TI_FLOAT_TYPE,
+ TI_DOUBLE_TYPE,
+ TI_LONG_DOUBLE_TYPE,
+
+ TI_FLOAT_PTR_TYPE,
+ TI_DOUBLE_PTR_TYPE,
+ TI_LONG_DOUBLE_PTR_TYPE,
+ TI_INTEGER_PTR_TYPE,
+
+ TI_VOID_TYPE,
+ TI_PTR_TYPE,
+ TI_CONST_PTR_TYPE,
+ TI_SIZE_TYPE,
+ TI_PID_TYPE,
+ TI_PTRDIFF_TYPE,
+ TI_VA_LIST_TYPE,
+ TI_VA_LIST_GPR_COUNTER_FIELD,
+ TI_VA_LIST_FPR_COUNTER_FIELD,
+ TI_BOOLEAN_TYPE,
+ TI_FILEPTR_TYPE,
+ TI_POINTER_SIZED_TYPE,
+
+ TI_DFLOAT32_TYPE,
+ TI_DFLOAT64_TYPE,
+ TI_DFLOAT128_TYPE,
+ TI_DFLOAT32_PTR_TYPE,
+ TI_DFLOAT64_PTR_TYPE,
+ TI_DFLOAT128_PTR_TYPE,
+
+ TI_VOID_LIST_NODE,
+
+ TI_MAIN_IDENTIFIER,
+
+ TI_SAT_SFRACT_TYPE,
+ TI_SAT_FRACT_TYPE,
+ TI_SAT_LFRACT_TYPE,
+ TI_SAT_LLFRACT_TYPE,
+ TI_SAT_USFRACT_TYPE,
+ TI_SAT_UFRACT_TYPE,
+ TI_SAT_ULFRACT_TYPE,
+ TI_SAT_ULLFRACT_TYPE,
+ TI_SFRACT_TYPE,
+ TI_FRACT_TYPE,
+ TI_LFRACT_TYPE,
+ TI_LLFRACT_TYPE,
+ TI_USFRACT_TYPE,
+ TI_UFRACT_TYPE,
+ TI_ULFRACT_TYPE,
+ TI_ULLFRACT_TYPE,
+ TI_SAT_SACCUM_TYPE,
+ TI_SAT_ACCUM_TYPE,
+ TI_SAT_LACCUM_TYPE,
+ TI_SAT_LLACCUM_TYPE,
+ TI_SAT_USACCUM_TYPE,
+ TI_SAT_UACCUM_TYPE,
+ TI_SAT_ULACCUM_TYPE,
+ TI_SAT_ULLACCUM_TYPE,
+ TI_SACCUM_TYPE,
+ TI_ACCUM_TYPE,
+ TI_LACCUM_TYPE,
+ TI_LLACCUM_TYPE,
+ TI_USACCUM_TYPE,
+ TI_UACCUM_TYPE,
+ TI_ULACCUM_TYPE,
+ TI_ULLACCUM_TYPE,
+ TI_QQ_TYPE,
+ TI_HQ_TYPE,
+ TI_SQ_TYPE,
+ TI_DQ_TYPE,
+ TI_TQ_TYPE,
+ TI_UQQ_TYPE,
+ TI_UHQ_TYPE,
+ TI_USQ_TYPE,
+ TI_UDQ_TYPE,
+ TI_UTQ_TYPE,
+ TI_SAT_QQ_TYPE,
+ TI_SAT_HQ_TYPE,
+ TI_SAT_SQ_TYPE,
+ TI_SAT_DQ_TYPE,
+ TI_SAT_TQ_TYPE,
+ TI_SAT_UQQ_TYPE,
+ TI_SAT_UHQ_TYPE,
+ TI_SAT_USQ_TYPE,
+ TI_SAT_UDQ_TYPE,
+ TI_SAT_UTQ_TYPE,
+ TI_HA_TYPE,
+ TI_SA_TYPE,
+ TI_DA_TYPE,
+ TI_TA_TYPE,
+ TI_UHA_TYPE,
+ TI_USA_TYPE,
+ TI_UDA_TYPE,
+ TI_UTA_TYPE,
+ TI_SAT_HA_TYPE,
+ TI_SAT_SA_TYPE,
+ TI_SAT_DA_TYPE,
+ TI_SAT_TA_TYPE,
+ TI_SAT_UHA_TYPE,
+ TI_SAT_USA_TYPE,
+ TI_SAT_UDA_TYPE,
+ TI_SAT_UTA_TYPE,
+
+ TI_OPTIMIZATION_DEFAULT,
+ TI_OPTIMIZATION_CURRENT,
+ TI_TARGET_OPTION_DEFAULT,
+ TI_TARGET_OPTION_CURRENT,
+ TI_CURRENT_TARGET_PRAGMA,
+ TI_CURRENT_OPTIMIZE_PRAGMA,
+
+ TI_MAX
+};
+
+/* An enumeration of the standard C integer types. These must be
+ ordered so that shorter types appear before longer ones, and so
+ that signed types appear before unsigned ones, for the correct
+ functioning of interpret_integer() in c-lex.c. */
+enum integer_type_kind {
+ itk_char,
+ itk_signed_char,
+ itk_unsigned_char,
+ itk_short,
+ itk_unsigned_short,
+ itk_int,
+ itk_unsigned_int,
+ itk_long,
+ itk_unsigned_long,
+ itk_long_long,
+ itk_unsigned_long_long,
+ itk_int128,
+ itk_unsigned_int128,
+ itk_none
+};
+
+/* A pointer-to-function member type looks like:
+
+ struct {
+ __P __pfn;
+ ptrdiff_t __delta;
+ };
+
+ If __pfn is NULL, it is a NULL pointer-to-member-function.
+
+ (Because the vtable is always the first thing in the object, we
+ don't need its offset.) If the function is virtual, then PFN is
+ one plus twice the index into the vtable; otherwise, it is just a
+ pointer to the function.
+
+ Unfortunately, using the lowest bit of PFN doesn't work in
+ architectures that don't impose alignment requirements on function
+ addresses, or that use the lowest bit to tell one ISA from another,
+ for example. For such architectures, we use the lowest bit of
+ DELTA instead of the lowest bit of the PFN, and DELTA will be
+ multiplied by 2. */
+enum ptrmemfunc_vbit_where_t {
+ ptrmemfunc_vbit_in_pfn,
+ ptrmemfunc_vbit_in_delta
+};
+
+/* Flags that may be passed in the third argument of decl_attributes, and
+ to handler functions for attributes. */
+enum attribute_flags {
+ /* The type passed in is the type of a DECL, and any attributes that
+ should be passed in again to be applied to the DECL rather than the
+ type should be returned. */
+ ATTR_FLAG_DECL_NEXT = 1,
+ /* The type passed in is a function return type, and any attributes that
+ should be passed in again to be applied to the function type rather
+ than the return type should be returned. */
+ ATTR_FLAG_FUNCTION_NEXT = 2,
+ /* The type passed in is an array element type, and any attributes that
+ should be passed in again to be applied to the array type rather
+ than the element type should be returned. */
+ ATTR_FLAG_ARRAY_NEXT = 4,
+ /* The type passed in is a structure, union or enumeration type being
+ created, and should be modified in place. */
+ ATTR_FLAG_TYPE_IN_PLACE = 8,
+ /* The attributes are being applied by default to a library function whose
+ name indicates known behavior, and should be silently ignored if they
+ are not in fact compatible with the function type. */
+ ATTR_FLAG_BUILT_IN = 16,
+ /* A given attribute has been parsed as a C++-11 attribute. */
+ ATTR_FLAG_CXX11 = 32
+};
+
+/* Types used to represent sizes. */
+enum size_type_kind {
+ stk_sizetype, /* Normal representation of sizes in bytes. */
+ stk_ssizetype, /* Signed representation of sizes in bytes. */
+ stk_bitsizetype, /* Normal representation of sizes in bits. */
+ stk_sbitsizetype, /* Signed representation of sizes in bits. */
+ stk_type_kind_last
+};
+
+enum operand_equal_flag {
+ OEP_ONLY_CONST = 1,
+ OEP_PURE_SAME = 2,
+ OEP_CONSTANT_ADDRESS_OF = 4
+};
+
+/* Enum and arrays used for tree allocation stats.
+ Keep in sync with tree.c:tree_node_kind_names. */
+enum tree_node_kind {
+ d_kind,
+ t_kind,
+ b_kind,
+ s_kind,
+ r_kind,
+ e_kind,
+ c_kind,
+ id_kind,
+ vec_kind,
+ binfo_kind,
+ ssa_name_kind,
+ constr_kind,
+ x_kind,
+ lang_decl,
+ lang_type,
+ omp_clause_kind,
+ all_kinds
+};
+
+
+/*---------------------------------------------------------------------------
+ Type definitions
+---------------------------------------------------------------------------*/
+/* When processing aliases at the symbol table level, we need the
+ declaration of target. For this reason we need to queue aliases and
+ process them after all declarations has been produced. */
+typedef struct GTY(()) alias_pair {
+ tree decl;
+ tree target;
+} alias_pair;
+
+/* An initialization priority. */
+typedef unsigned short priority_type;
+
+/* The type of a callback function for walking over tree structure. */
+typedef tree (*walk_tree_fn) (tree *, int *, void *);
+
+/* The type of a callback function that represents a custom walk_tree. */
+typedef tree (*walk_tree_lh) (tree *, int *, tree (*) (tree *, int *, void *),
+ void *, struct pointer_set_t*);
+
+
+/*---------------------------------------------------------------------------
+ Main data structures
+---------------------------------------------------------------------------*/
+/* A tree node can represent a data type, a variable, an expression
+ or a statement. Each node has a TREE_CODE which says what kind of
+ thing it represents. Some common codes are:
+ INTEGER_TYPE -- represents a type of integers.
+ ARRAY_TYPE -- represents a type of pointer.
+ VAR_DECL -- represents a declared variable.
+ INTEGER_CST -- represents a constant integer value.
+ PLUS_EXPR -- represents a sum (an expression).
+
+ As for the contents of a tree node: there are some fields
+ that all nodes share. Each TREE_CODE has various special-purpose
+ fields as well. The fields of a node are never accessed directly,
+ always through accessor macros. */
+
+/* Every kind of tree node starts with this structure,
+ so all nodes have these fields.
+
+ See the accessor macros, defined below, for documentation of the
+ fields, and the table below which connects the fields and the
+ accessor macros. */
+
+struct GTY(()) tree_base {
+ ENUM_BITFIELD(tree_code) code : 16;
+
+ unsigned side_effects_flag : 1;
+ unsigned constant_flag : 1;
+ unsigned addressable_flag : 1;
+ unsigned volatile_flag : 1;
+ unsigned readonly_flag : 1;
+ unsigned asm_written_flag: 1;
+ unsigned nowarning_flag : 1;
+ unsigned visited : 1;
+
+ unsigned used_flag : 1;
+ unsigned nothrow_flag : 1;
+ unsigned static_flag : 1;
+ unsigned public_flag : 1;
+ unsigned private_flag : 1;
+ unsigned protected_flag : 1;
+ unsigned deprecated_flag : 1;
+ unsigned default_def_flag : 1;
+
+ union {
+ /* The bits in the following structure should only be used with
+ accessor macros that constrain inputs with tree checking. */
+ struct {
+ unsigned lang_flag_0 : 1;
+ unsigned lang_flag_1 : 1;
+ unsigned lang_flag_2 : 1;
+ unsigned lang_flag_3 : 1;
+ unsigned lang_flag_4 : 1;
+ unsigned lang_flag_5 : 1;
+ unsigned lang_flag_6 : 1;
+ unsigned saturating_flag : 1;
+
+ unsigned unsigned_flag : 1;
+ unsigned packed_flag : 1;
+ unsigned user_align : 1;
+ unsigned nameless_flag : 1;
+ unsigned spare0 : 4;
+
+ unsigned spare1 : 8;
+
+ /* This field is only used with TREE_TYPE nodes; the only reason it is
+ present in tree_base instead of tree_type is to save space. The size
+ of the field must be large enough to hold addr_space_t values. */
+ unsigned address_space : 8;
+ } bits;
+ /* The following fields are present in tree_base to save space. The
+ nodes using them do not require any of the flags above and so can
+ make better use of the 4-byte sized word. */
+ /* VEC length. This field is only used with TREE_VEC. */
+ int length;
+ /* SSA version number. This field is only used with SSA_NAME. */
+ unsigned int version;
+ } GTY((skip(""))) u;
+};
+
+/* The following table lists the uses of each of the above flags and
+ for which types of nodes they are defined.
+
+ addressable_flag:
+
+ TREE_ADDRESSABLE in
+ VAR_DECL, PARM_DECL, RESULT_DECL, FUNCTION_DECL, LABEL_DECL
+ SSA_NAME
+ all types
+ CONSTRUCTOR, IDENTIFIER_NODE
+ STMT_EXPR
+
+ CALL_EXPR_TAILCALL in
+ CALL_EXPR
+
+ CASE_LOW_SEEN in
+ CASE_LABEL_EXPR
+
+ PREDICT_EXPR_OUTCOME in
+ PREDICT_EXPR
+
+ static_flag:
+
+ TREE_STATIC in
+ VAR_DECL, FUNCTION_DECL
+ CONSTRUCTOR
+
+ TREE_NO_TRAMPOLINE in
+ ADDR_EXPR
+
+ BINFO_VIRTUAL_P in
+ TREE_BINFO
+
+ TREE_SYMBOL_REFERENCED in
+ IDENTIFIER_NODE
+
+ CLEANUP_EH_ONLY in
+ TARGET_EXPR, WITH_CLEANUP_EXPR
+
+ TRY_CATCH_IS_CLEANUP in
+ TRY_CATCH_EXPR
+
+ ASM_INPUT_P in
+ ASM_EXPR
+
+ TYPE_REF_CAN_ALIAS_ALL in
+ POINTER_TYPE, REFERENCE_TYPE
+
+ CASE_HIGH_SEEN in
+ CASE_LABEL_EXPR
+
+ ENUM_IS_SCOPED in
+ ENUMERAL_TYPE
+
+ TRANSACTION_EXPR_OUTER in
+ TRANSACTION_EXPR
+
+ public_flag:
+
+ TREE_OVERFLOW in
+ INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
+
+ TREE_PUBLIC in
+ VAR_DECL, FUNCTION_DECL
+ IDENTIFIER_NODE
+
+ ASM_VOLATILE_P in
+ ASM_EXPR
+
+ CALL_EXPR_VA_ARG_PACK in
+ CALL_EXPR
+
+ TYPE_CACHED_VALUES_P in
+ all types
+
+ SAVE_EXPR_RESOLVED_P in
+ SAVE_EXPR
+
+ OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE in
+ OMP_CLAUSE_LASTPRIVATE
+
+ OMP_CLAUSE_PRIVATE_DEBUG in
+ OMP_CLAUSE_PRIVATE
+
+ TRANSACTION_EXPR_RELAXED in
+ TRANSACTION_EXPR
+
+ private_flag:
+
+ TREE_PRIVATE in
+ all decls
+
+ CALL_EXPR_RETURN_SLOT_OPT in
+ CALL_EXPR
+
+ OMP_SECTION_LAST in
+ OMP_SECTION
+
+ OMP_PARALLEL_COMBINED in
+ OMP_PARALLEL
+
+ OMP_CLAUSE_PRIVATE_OUTER_REF in
+ OMP_CLAUSE_PRIVATE
+
+ TYPE_REF_IS_RVALUE in
+ REFERENCE_TYPE
+
+ ENUM_IS_OPAQUE in
+ ENUMERAL_TYPE
+
+ protected_flag:
+
+ TREE_PROTECTED in
+ BLOCK
+ all decls
+
+ CALL_FROM_THUNK_P and
+ CALL_ALLOCA_FOR_VAR_P in
+ CALL_EXPR
+
+ side_effects_flag:
+
+ TREE_SIDE_EFFECTS in
+ all expressions
+ all decls
+ all constants
+
+ FORCED_LABEL in
+ LABEL_DECL
+
+ volatile_flag:
+
+ TREE_THIS_VOLATILE in
+ all expressions
+ all decls
+
+ TYPE_VOLATILE in
+ all types
+
+ readonly_flag:
+
+ TREE_READONLY in
+ all expressions
+ all decls
+
+ TYPE_READONLY in
+ all types
+
+ constant_flag:
+
+ TREE_CONSTANT in
+ all expressions
+ all decls
+ all constants
+
+ TYPE_SIZES_GIMPLIFIED in
+ all types
+
+ unsigned_flag:
+
+ TYPE_UNSIGNED in
+ all types
+
+ DECL_UNSIGNED in
+ all decls
+
+ asm_written_flag:
+
+ TREE_ASM_WRITTEN in
+ VAR_DECL, FUNCTION_DECL, TYPE_DECL
+ RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE
+ BLOCK, STRING_CST
+
+ SSA_NAME_OCCURS_IN_ABNORMAL_PHI in
+ SSA_NAME
+
+ used_flag:
+
+ TREE_USED in
+ all expressions
+ all decls
+ IDENTIFIER_NODE
+
+ nothrow_flag:
+
+ TREE_NOTHROW in
+ CALL_EXPR
+ FUNCTION_DECL
+
+ TYPE_ALIGN_OK in
+ all types
+
+ TREE_THIS_NOTRAP in
+ INDIRECT_REF, MEM_REF, TARGET_MEM_REF, ARRAY_REF, ARRAY_RANGE_REF
+
+ SSA_NAME_IN_FREELIST in
+ SSA_NAME
+
+ deprecated_flag:
+
+ TREE_DEPRECATED in
+ all decls
+ all types
+
+ IDENTIFIER_TRANSPARENT_ALIAS in
+ IDENTIFIER_NODE
+
+ visited:
+
+ TREE_VISITED in
+ all trees (used liberally by many passes)
+
+ saturating_flag:
+
+ TYPE_SATURATING in
+ all types
+
+ VAR_DECL_IS_VIRTUAL_OPERAND in
+ VAR_DECL
+
+ nowarning_flag:
+
+ TREE_NO_WARNING in
+ all expressions
+ all decls
+
+ TYPE_ARTIFICIAL in
+ all types
+
+ default_def_flag:
+
+ TYPE_VECTOR_OPAQUE in
+ VECTOR_TYPE
+
+ SSA_NAME_IS_DEFAULT_DEF in
+ SSA_NAME
+
+ DECL_NONLOCAL_FRAME in
+ VAR_DECL
+*/
+
+struct GTY(()) tree_typed {
+ struct tree_base base;
+ tree type;
+};
+
+struct GTY(()) tree_common {
+ struct tree_typed typed;
+ tree chain;
+};
+
+struct GTY(()) tree_int_cst {
+ struct tree_typed typed;
+ double_int int_cst;
+};
+
+
+struct GTY(()) tree_real_cst {
+ struct tree_typed typed;
+ struct real_value * real_cst_ptr;
+};
+
+struct GTY(()) tree_fixed_cst {
+ struct tree_typed typed;
+ struct fixed_value * fixed_cst_ptr;
+};
+
+struct GTY(()) tree_string {
+ struct tree_typed typed;
+ int length;
+ char str[1];
+};
+
+struct GTY(()) tree_complex {
+ struct tree_typed typed;
+ tree real;
+ tree imag;
+};
+
+struct GTY(()) tree_vector {
+ struct tree_typed typed;
+ tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1];
+};
+
+struct GTY(()) tree_identifier {
+ struct tree_common common;
+ struct ht_identifier id;
+};
+
+struct GTY(()) tree_list {
+ struct tree_common common;
+ tree purpose;
+ tree value;
+};
+
+struct GTY(()) tree_vec {
+ struct tree_common common;
+ tree GTY ((length ("TREE_VEC_LENGTH ((tree)&%h)"))) a[1];
+};
+
+/* A single element of a CONSTRUCTOR. VALUE holds the actual value of the
+ element. INDEX can optionally design the position of VALUE: in arrays,
+ it is the index where VALUE has to be placed; in structures, it is the
+ FIELD_DECL of the member. */
+typedef struct GTY(()) constructor_elt_d {
+ tree index;
+ tree value;
+} constructor_elt;
+
+struct GTY(()) tree_constructor {
+ struct tree_typed typed;
+ vec<constructor_elt, va_gc> *elts;
+};
+
+struct GTY(()) tree_exp {
+ struct tree_typed typed;
+ location_t locus;
+ tree GTY ((special ("tree_exp"),
+ desc ("TREE_CODE ((tree) &%0)")))
+ operands[1];
+};
+
+/* Immediate use linking structure. This structure is used for maintaining
+ a doubly linked list of uses of an SSA_NAME. */
+typedef struct GTY(()) ssa_use_operand_d {
+ struct ssa_use_operand_d* GTY((skip(""))) prev;
+ struct ssa_use_operand_d* GTY((skip(""))) next;
+ /* Immediate uses for a given SSA name are maintained as a cyclic
+ list. To recognize the root of this list, the location field
+ needs to point to the original SSA name. Since statements and
+ SSA names are of different data types, we need this union. See
+ the explanation in struct immediate_use_iterator_d. */
+ union { gimple stmt; tree ssa_name; } GTY((skip(""))) loc;
+ tree *GTY((skip(""))) use;
+} ssa_use_operand_t;
+
+struct GTY(()) tree_ssa_name {
+ struct tree_typed typed;
+
+ /* _DECL wrapped by this SSA name. */
+ tree var;
+
+ /* Statement that defines this SSA name. */
+ gimple def_stmt;
+
+ /* Pointer attributes used for alias analysis. */
+ struct ptr_info_def *ptr_info;
+
+ /* Immediate uses list for this SSA_NAME. */
+ struct ssa_use_operand_d imm_uses;
+};
+
+struct GTY(()) phi_arg_d {
+ /* imm_use MUST be the first element in struct because we do some
+ pointer arithmetic with it. See phi_arg_index_from_use. */
+ struct ssa_use_operand_d imm_use;
+ tree def;
+ location_t locus;
+};
+
+struct GTY(()) tree_omp_clause {
+ struct tree_common common;
+ location_t locus;
+ enum omp_clause_code code;
+ union omp_clause_subcode {
+ enum omp_clause_default_kind default_kind;
+ enum omp_clause_schedule_kind schedule_kind;
+ enum tree_code reduction_code;
+ } GTY ((skip)) subcode;
+
+ /* The gimplification of OMP_CLAUSE_REDUCTION_{INIT,MERGE} for omp-low's
+ usage. */
+ gimple_seq gimple_reduction_init;
+ gimple_seq gimple_reduction_merge;
+
+ tree GTY ((length ("omp_clause_num_ops[OMP_CLAUSE_CODE ((tree)&%h)]")))
+ ops[1];
+};
+
+struct GTY(()) tree_block {
+ struct tree_base base;
+ tree chain;
+
+ unsigned abstract_flag : 1;
+ unsigned block_num : 31;
+
+ location_t locus;
+
+ tree vars;
+ vec<tree, va_gc> *nonlocalized_vars;
+
+ tree subblocks;
+ tree supercontext;
+ tree abstract_origin;
+ tree fragment_origin;
+ tree fragment_chain;
+};
+
+struct GTY(()) tree_type_common {
+ struct tree_common common;
+ tree size;
+ tree size_unit;
+ tree attributes;
+ unsigned int uid;
+
+ unsigned int precision : 10;
+ unsigned no_force_blk_flag : 1;
+ unsigned needs_constructing_flag : 1;
+ unsigned transparent_aggr_flag : 1;
+ unsigned restrict_flag : 1;
+ unsigned contains_placeholder_bits : 2;
+
+ ENUM_BITFIELD(machine_mode) mode : 8;
+
+ unsigned string_flag : 1;
+ unsigned lang_flag_0 : 1;
+ unsigned lang_flag_1 : 1;
+ unsigned lang_flag_2 : 1;
+ unsigned lang_flag_3 : 1;
+ unsigned lang_flag_4 : 1;
+ unsigned lang_flag_5 : 1;
+ unsigned lang_flag_6 : 1;
+
+ unsigned int align;
+ alias_set_type alias_set;
+ tree pointer_to;
+ tree reference_to;
+ union tree_type_symtab {
+ int GTY ((tag ("TYPE_SYMTAB_IS_ADDRESS"))) address;
+ const char * GTY ((tag ("TYPE_SYMTAB_IS_POINTER"))) pointer;
+ struct die_struct * GTY ((tag ("TYPE_SYMTAB_IS_DIE"))) die;
+ } GTY ((desc ("debug_hooks->tree_type_symtab_field"))) symtab;
+ tree name;
+ tree next_variant;
+ tree main_variant;
+ tree context;
+ tree canonical;
+};
+
+struct GTY(()) tree_type_with_lang_specific {
+ struct tree_type_common common;
+ /* Points to a structure whose details depend on the language in use. */
+ struct lang_type *lang_specific;
+};
+
+struct GTY(()) tree_type_non_common {
+ struct tree_type_with_lang_specific with_lang_specific;
+ tree values;
+ tree minval;
+ tree maxval;
+ tree binfo;
+};
+
+struct GTY (()) tree_binfo {
+ struct tree_common common;
+
+ tree offset;
+ tree vtable;
+ tree virtuals;
+ tree vptr_field;
+ vec<tree, va_gc> *base_accesses;
+ tree inheritance;
+
+ tree vtt_subvtt;
+ tree vtt_vptr;
+
+ vec<tree, va_gc> base_binfos;
+};
+
+struct GTY(()) tree_decl_minimal {
+ struct tree_common common;
+ location_t locus;
+ unsigned int uid;
+ tree name;
+ tree context;
+};
+
+struct GTY(()) tree_decl_common {
+ struct tree_decl_minimal common;
+ tree size;
+
+ ENUM_BITFIELD(machine_mode) mode : 8;
+
+ unsigned nonlocal_flag : 1;
+ unsigned virtual_flag : 1;
+ unsigned ignored_flag : 1;
+ unsigned abstract_flag : 1;
+ unsigned artificial_flag : 1;
+ unsigned preserve_flag: 1;
+ unsigned debug_expr_is_from : 1;
+
+ unsigned lang_flag_0 : 1;
+ unsigned lang_flag_1 : 1;
+ unsigned lang_flag_2 : 1;
+ unsigned lang_flag_3 : 1;
+ unsigned lang_flag_4 : 1;
+ unsigned lang_flag_5 : 1;
+ unsigned lang_flag_6 : 1;
+ unsigned lang_flag_7 : 1;
+ unsigned lang_flag_8 : 1;
+
+ /* In LABEL_DECL, this is DECL_ERROR_ISSUED.
+ In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */
+ unsigned decl_flag_0 : 1;
+ /* In FIELD_DECL, this is DECL_BIT_FIELD
+ In VAR_DECL and FUNCTION_DECL, this is DECL_EXTERNAL.
+ In TYPE_DECL, this is TYPE_DECL_SUPPRESS_DEBUG. */
+ unsigned decl_flag_1 : 1;
+ /* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
+ In VAR_DECL, PARM_DECL and RESULT_DECL, this is
+ DECL_HAS_VALUE_EXPR_P. */
+ unsigned decl_flag_2 : 1;
+ /* 1 bit unused. */
+ unsigned decl_flag_3 : 1;
+ /* Logically, these two would go in a theoretical base shared by var and
+ parm decl. */
+ unsigned gimple_reg_flag : 1;
+ /* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_BY_REFERENCE. */
+ unsigned decl_by_reference_flag : 1;
+ /* In a VAR_DECL and PARM_DECL, this is DECL_READ_P. */
+ unsigned decl_read_flag : 1;
+ /* In a VAR_DECL or RESULT_DECL, this is DECL_NONSHAREABLE. */
+ unsigned decl_nonshareable_flag : 1;
+
+ /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */
+ unsigned int off_align : 8;
+
+ /* 24 bits unused. */
+
+ /* DECL_ALIGN. It should have the same size as TYPE_ALIGN. */
+ unsigned int align;
+
+ /* UID for points-to sets, stable over copying from inlining. */
+ unsigned int pt_uid;
+
+ tree size_unit;
+ tree initial;
+ tree attributes;
+ tree abstract_origin;
+
+ /* Points to a structure whose details depend on the language in use. */
+ struct lang_decl *lang_specific;
+};
+
+struct GTY(()) tree_decl_with_rtl {
+ struct tree_decl_common common;
+ rtx rtl;
+};
+
+struct GTY(()) tree_field_decl {
+ struct tree_decl_common common;
+
+ tree offset;
+ tree bit_field_type;
+ tree qualifier;
+ tree bit_offset;
+ tree fcontext;
+};
+
+struct GTY(()) tree_label_decl {
+ struct tree_decl_with_rtl common;
+ int label_decl_uid;
+ int eh_landing_pad_nr;
+};
+
+struct GTY(()) tree_result_decl {
+ struct tree_decl_with_rtl common;
+};
+
+struct GTY(()) tree_const_decl {
+ struct tree_decl_common common;
+};
+
+struct GTY(()) tree_parm_decl {
+ struct tree_decl_with_rtl common;
+ rtx incoming_rtl;
+};
+
+struct GTY(()) tree_decl_with_vis {
+ struct tree_decl_with_rtl common;
+ tree assembler_name;
+ tree section_name;
+ tree comdat_group;
+
+ /* Belong to VAR_DECL exclusively. */
+ unsigned defer_output : 1;
+ unsigned hard_register : 1;
+ unsigned common_flag : 1;
+ unsigned in_text_section : 1;
+ unsigned in_constant_pool : 1;
+ unsigned dllimport_flag : 1;
+ /* Don't belong to VAR_DECL exclusively. */
+ unsigned weak_flag : 1;
+ /* When SECTION_NAME is implied by -ffunction-section. */
+ unsigned implicit_section_name_p : 1;
+
+ unsigned seen_in_bind_expr : 1;
+ unsigned comdat_flag : 1;
+ ENUM_BITFIELD(symbol_visibility) visibility : 2;
+ unsigned visibility_specified : 1;
+ /* Belongs to VAR_DECL exclusively. */
+ ENUM_BITFIELD(tls_model) tls_model : 3;
+
+ /* Belong to FUNCTION_DECL exclusively. */
+ unsigned init_priority_p : 1;
+ /* Used by C++ only. Might become a generic decl flag. */
+ unsigned shadowed_for_var_p : 1;
+ /* Belong to FUNCTION_DECL exclusively. */
+ unsigned cxx_constructor : 1;
+ /* Belong to FUNCTION_DECL exclusively. */
+ unsigned cxx_destructor : 1;
+ /* Belong to FUNCTION_DECL exclusively. */
+ unsigned final : 1;
+ /* 11 unused bits. */
+};
+
+struct GTY(()) tree_var_decl {
+ struct tree_decl_with_vis common;
+};
+
+struct GTY(()) tree_decl_non_common {
+ struct tree_decl_with_vis common;
+ /* C++ uses this in namespaces. */
+ tree saved_tree;
+ /* C++ uses this in templates. */
+ tree arguments;
+ /* Almost all FE's use this. */
+ tree result;
+ /* C++ uses this in namespaces and function_decls. */
+ tree vindex;
+};
+
+/* FUNCTION_DECL inherits from DECL_NON_COMMON because of the use of the
+ arguments/result/saved_tree fields by front ends. It was either inherit
+ FUNCTION_DECL from non_common, or inherit non_common from FUNCTION_DECL,
+ which seemed a bit strange. */
+
+struct GTY(()) tree_function_decl {
+ struct tree_decl_non_common common;
+
+ struct function *f;
+
+ /* The personality function. Used for stack unwinding. */
+ tree personality;
+
+ /* Function specific options that are used by this function. */
+ tree function_specific_target; /* target options */
+ tree function_specific_optimization; /* optimization options */
+
+ /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
+ DECL_FUNCTION_CODE. Otherwise unused.
+ ??? The bitfield needs to be able to hold all target function
+ codes as well. */
+ ENUM_BITFIELD(built_in_function) function_code : 11;
+ ENUM_BITFIELD(built_in_class) built_in_class : 2;
+
+ unsigned static_ctor_flag : 1;
+ unsigned static_dtor_flag : 1;
+ unsigned uninlinable : 1;
+
+ unsigned possibly_inlined : 1;
+ unsigned novops_flag : 1;
+ unsigned returns_twice_flag : 1;
+ unsigned malloc_flag : 1;
+ unsigned operator_new_flag : 1;
+ unsigned declared_inline_flag : 1;
+ unsigned regdecl_flag : 1;
+ unsigned no_inline_warning_flag : 1;
+
+ unsigned no_instrument_function_entry_exit : 1;
+ unsigned no_limit_stack : 1;
+ unsigned disregard_inline_limits : 1;
+ unsigned pure_flag : 1;
+ unsigned looping_const_or_pure_flag : 1;
+ unsigned has_debug_args_flag : 1;
+ unsigned tm_clone_flag : 1;
+ unsigned versioned_function : 1;
+ /* No bits left. */
+};
+
+struct GTY(()) tree_translation_unit_decl {
+ struct tree_decl_common common;
+ /* Source language of this translation unit. Used for DWARF output. */
+ const char * GTY((skip(""))) language;
+ /* TODO: Non-optimization used to build this translation unit. */
+ /* TODO: Root of a partial DWARF tree for global types and decls. */
+};
+
+struct GTY(()) tree_type_decl {
+ struct tree_decl_non_common common;
+
+};
+
+struct GTY ((chain_next ("%h.next"), chain_prev ("%h.prev"))) tree_statement_list_node
+ {
+ struct tree_statement_list_node *prev;
+ struct tree_statement_list_node *next;
+ tree stmt;
+};
+
+struct GTY(()) tree_statement_list
+ {
+ struct tree_typed typed;
+ struct tree_statement_list_node *head;
+ struct tree_statement_list_node *tail;
+};
+
+struct GTY(()) tree_optimization_option {
+ struct tree_common common;
+
+ /* The optimization options used by the user. */
+ struct cl_optimization opts;
+
+ /* Target optabs for this set of optimization options. This is of
+ type `struct target_optabs *'. */
+ unsigned char *GTY ((atomic)) optabs;
+
+ /* The value of this_target_optabs against which the optabs above were
+ generated. */
+ struct target_optabs *GTY ((skip)) base_optabs;
+};
+
+struct GTY(()) tree_target_option {
+ struct tree_common common;
+
+ /* The optimization options used by the user. */
+ struct cl_target_option opts;
+};
+
+/* Define the overall contents of a tree node.
+ It may be any of the structures declared above
+ for various types of node. */
+union GTY ((ptr_alias (union lang_tree_node),
+ desc ("tree_node_structure (&%h)"), variable_size)) tree_node {
+ struct tree_base GTY ((tag ("TS_BASE"))) base;
+ struct tree_typed GTY ((tag ("TS_TYPED"))) typed;
+ struct tree_common GTY ((tag ("TS_COMMON"))) common;
+ struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;
+ struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst;
+ struct tree_fixed_cst GTY ((tag ("TS_FIXED_CST"))) fixed_cst;
+ struct tree_vector GTY ((tag ("TS_VECTOR"))) vector;
+ struct tree_string GTY ((tag ("TS_STRING"))) string;
+ struct tree_complex GTY ((tag ("TS_COMPLEX"))) complex;
+ struct tree_identifier GTY ((tag ("TS_IDENTIFIER"))) identifier;
+ struct tree_decl_minimal GTY((tag ("TS_DECL_MINIMAL"))) decl_minimal;
+ struct tree_decl_common GTY ((tag ("TS_DECL_COMMON"))) decl_common;
+ struct tree_decl_with_rtl GTY ((tag ("TS_DECL_WRTL"))) decl_with_rtl;
+ struct tree_decl_non_common GTY ((tag ("TS_DECL_NON_COMMON")))
+ decl_non_common;
+ struct tree_parm_decl GTY ((tag ("TS_PARM_DECL"))) parm_decl;
+ struct tree_decl_with_vis GTY ((tag ("TS_DECL_WITH_VIS"))) decl_with_vis;
+ struct tree_var_decl GTY ((tag ("TS_VAR_DECL"))) var_decl;
+ struct tree_field_decl GTY ((tag ("TS_FIELD_DECL"))) field_decl;
+ struct tree_label_decl GTY ((tag ("TS_LABEL_DECL"))) label_decl;
+ struct tree_result_decl GTY ((tag ("TS_RESULT_DECL"))) result_decl;
+ struct tree_const_decl GTY ((tag ("TS_CONST_DECL"))) const_decl;
+ struct tree_type_decl GTY ((tag ("TS_TYPE_DECL"))) type_decl;
+ struct tree_function_decl GTY ((tag ("TS_FUNCTION_DECL"))) function_decl;
+ struct tree_translation_unit_decl GTY ((tag ("TS_TRANSLATION_UNIT_DECL")))
+ translation_unit_decl;
+ struct tree_type_common GTY ((tag ("TS_TYPE_COMMON"))) type_common;
+ struct tree_type_with_lang_specific GTY ((tag ("TS_TYPE_WITH_LANG_SPECIFIC")))
+ type_with_lang_specific;
+ struct tree_type_non_common GTY ((tag ("TS_TYPE_NON_COMMON")))
+ type_non_common;
+ struct tree_list GTY ((tag ("TS_LIST"))) list;
+ struct tree_vec GTY ((tag ("TS_VEC"))) vec;
+ struct tree_exp GTY ((tag ("TS_EXP"))) exp;
+ struct tree_ssa_name GTY ((tag ("TS_SSA_NAME"))) ssa_name;
+ struct tree_block GTY ((tag ("TS_BLOCK"))) block;
+ struct tree_binfo GTY ((tag ("TS_BINFO"))) binfo;
+ struct tree_statement_list GTY ((tag ("TS_STATEMENT_LIST"))) stmt_list;
+ struct tree_constructor GTY ((tag ("TS_CONSTRUCTOR"))) constructor;
+ struct tree_omp_clause GTY ((tag ("TS_OMP_CLAUSE"))) omp_clause;
+ struct tree_optimization_option GTY ((tag ("TS_OPTIMIZATION"))) optimization;
+ struct tree_target_option GTY ((tag ("TS_TARGET_OPTION"))) target_option;
+};
+
+/* Structure describing an attribute and a function to handle it. */
+struct attribute_spec {
+ /* The name of the attribute (without any leading or trailing __),
+ or NULL to mark the end of a table of attributes. */
+ const char *name;
+ /* The minimum length of the list of arguments of the attribute. */
+ int min_length;
+ /* The maximum length of the list of arguments of the attribute
+ (-1 for no maximum). */
+ int max_length;
+ /* Whether this attribute requires a DECL. If it does, it will be passed
+ from types of DECLs, function return types and array element types to
+ the DECLs, function types and array types respectively; but when
+ applied to a type in any other circumstances, it will be ignored with
+ a warning. (If greater control is desired for a given attribute,
+ this should be false, and the flags argument to the handler may be
+ used to gain greater control in that case.) */
+ bool decl_required;
+ /* Whether this attribute requires a type. If it does, it will be passed
+ from a DECL to the type of that DECL. */
+ bool type_required;
+ /* Whether this attribute requires a function (or method) type. If it does,
+ it will be passed from a function pointer type to the target type,
+ and from a function return type (which is not itself a function
+ pointer type) to the function type. */
+ bool function_type_required;
+ /* Function to handle this attribute. NODE points to the node to which
+ the attribute is to be applied. If a DECL, it should be modified in
+ place; if a TYPE, a copy should be created. NAME is the name of the
+ attribute (possibly with leading or trailing __). ARGS is the TREE_LIST
+ of the arguments (which may be NULL). FLAGS gives further information
+ about the context of the attribute. Afterwards, the attributes will
+ be added to the DECL_ATTRIBUTES or TYPE_ATTRIBUTES, as appropriate,
+ unless *NO_ADD_ATTRS is set to true (which should be done on error,
+ as well as in any other cases when the attributes should not be added
+ to the DECL or TYPE). Depending on FLAGS, any attributes to be
+ applied to another type or DECL later may be returned;
+ otherwise the return value should be NULL_TREE. This pointer may be
+ NULL if no special handling is required beyond the checks implied
+ by the rest of this structure. */
+ tree (*handler) (tree *node, tree name, tree args,
+ int flags, bool *no_add_attrs);
+ /* Specifies if attribute affects type's identity. */
+ bool affects_type_identity;
+};
+
+/* These functions allow a front-end to perform a manual layout of a
+ RECORD_TYPE. (For instance, if the placement of subsequent fields
+ depends on the placement of fields so far.) Begin by calling
+ start_record_layout. Then, call place_field for each of the
+ fields. Then, call finish_record_layout. See layout_type for the
+ default way in which these functions are used. */
+typedef struct record_layout_info_s {
+ /* The RECORD_TYPE that we are laying out. */
+ tree t;
+ /* The offset into the record so far, in bytes, not including bits in
+ BITPOS. */
+ tree offset;
+ /* The last known alignment of SIZE. */
+ unsigned int offset_align;
+ /* The bit position within the last OFFSET_ALIGN bits, in bits. */
+ tree bitpos;
+ /* The alignment of the record so far, in bits. */
+ unsigned int record_align;
+ /* The alignment of the record so far, ignoring #pragma pack and
+ __attribute__ ((packed)), in bits. */
+ unsigned int unpacked_align;
+ /* The previous field laid out. */
+ tree prev_field;
+ /* The static variables (i.e., class variables, as opposed to
+ instance variables) encountered in T. */
+ vec<tree, va_gc> *pending_statics;
+ /* Bits remaining in the current alignment group */
+ int remaining_in_alignment;
+ /* True if we've seen a packed field that didn't have normal
+ alignment anyway. */
+ int packed_maybe_necessary;
+} *record_layout_info;
+
+/* Iterator for going through the function arguments. */
+struct function_args_iterator {
+ tree next; /* TREE_LIST pointing to the next argument */
+};
+
+/* Structures to map from a tree to another tree. */
+struct GTY(()) tree_map_base {
+ tree from;
+};
+
+struct GTY(()) tree_map {
+ struct tree_map_base base;
+ unsigned int hash;
+ tree to;
+};
+
+/* Map from a decl tree to another tree. */
+struct GTY(()) tree_decl_map {
+ struct tree_map_base base;
+ tree to;
+};
+
+/* Map from a tree to an int. */
+struct GTY(()) tree_int_map {
+ struct tree_map_base base;
+ unsigned int to;
+};
+
+/* Map from a tree to initialization/finalization priorities. */
+struct GTY(()) tree_priority_map {
+ struct tree_map_base base;
+ priority_type init;
+ priority_type fini;
+};
+
+/* Map from a decl tree to a tree vector. */
+struct GTY(()) tree_vec_map {
+ struct tree_map_base base;
+ vec<tree, va_gc> *to;
+};
+
+/* Abstract iterators for CALL_EXPRs. These static inline definitions
+ have to go towards the end of tree.h so that union tree_node is fully
+ defined by this point. */
+
+/* Structure containing iterator state. */
+struct call_expr_arg_iterator {
+ tree t; /* the call_expr */
+ int n; /* argument count */
+ int i; /* next argument index */
+};
+
+struct const_call_expr_arg_iterator {
+ const_tree t; /* the call_expr */
+ int n; /* argument count */
+ int i; /* next argument index */
+};
+
+/* The builtin_info structure holds the FUNCTION_DECL of the standard builtin
+ function, and a flag that says if the function is available implicitly, or
+ whether the user has to code explicit calls to __builtin_<xxx>. */
+struct GTY(()) builtin_info_type {
+ tree decl[(int)END_BUILTINS];
+ bool implicit_p[(int)END_BUILTINS];
+};
+
+
+/*---------------------------------------------------------------------------
+ Global variables
+---------------------------------------------------------------------------*/
+/* Matrix describing the structures contained in a given tree code. */
+extern unsigned char tree_contains_struct[MAX_TREE_CODES][64];
+
+/* Class of tree given its code. */
+extern const enum tree_code_class tree_code_type[];
+
+/* Each tree code class has an associated string representation.
+ These must correspond to the tree_code_class entries. */
+extern const char *const tree_code_class_strings[];
+
+/* Number of argument-words in each kind of tree-node. */
+extern const unsigned char tree_code_length[];
+
+/* Names of tree components. */
+extern const char *const tree_code_name[];
+
+/* Vector of all alias pairs for global symbols. */
+extern GTY(()) vec<alias_pair, va_gc> *alias_pairs;
+
+/* Names of all the built_in classes. */
+extern const char *const built_in_class_names[BUILT_IN_LAST];
+
+/* Names of all the built_in functions. */
+extern const char * built_in_names[(int) END_BUILTINS];
+
+/* Number of operands and names for each OMP_CLAUSE node. */
+extern unsigned const char omp_clause_num_ops[];
+extern const char * const omp_clause_code_name[];
+
+/* A vector of all translation-units. */
+extern GTY (()) vec<tree, va_gc> *all_translation_units;
+
+/* Vector of standard trees used by the C compiler. */
+extern GTY(()) tree global_trees[TI_MAX];
+
+/* The standard C integer types. Use integer_type_kind to index into
+ this array. */
+extern GTY(()) tree integer_types[itk_none];
+
+/* Types used to represent sizes. */
+extern GTY(()) tree sizetype_tab[(int) stk_type_kind_last];
+
+/* Arrays for keeping track of tree node statistics. */
+extern int tree_node_counts[];
+extern int tree_node_sizes[];
+
+/* True if we are in gimple form and the actions of the folders need to
+ be restricted. False if we are not in gimple form and folding is not
+ restricted to creating gimple expressions. */
+extern bool in_gimple_form;
+
+/* Functional interface to the builtin functions. */
+extern GTY(()) builtin_info_type builtin_info;
+
+/* If nonzero, an upper limit on alignment of structure fields, in bits, */
+extern unsigned int maximum_field_alignment;
+
+/* Nonzero means lvalues are limited to those valid in pedantic ANSI C.
+ Zero means allow extended lvalues. */
+extern int pedantic_lvalues;
+
+/* Points to the FUNCTION_DECL of the function whose body we are reading. */
+extern GTY(()) tree current_function_decl;
+
+/* Nonzero means a FUNC_BEGIN label was emitted. */
+extern GTY(()) const char * current_function_func_begin_label;
+
+#endif // GCC_TREE_CORE_H
diff --git a/gcc/tree-data-ref.c b/gcc/tree-data-ref.c
index 10431c09237..5bd7719516b 100644
--- a/gcc/tree-data-ref.c
+++ b/gcc/tree-data-ref.c
@@ -4331,10 +4331,25 @@ get_references_in_stmt (gimple stmt, vec<data_ref_loc, va_stack> *references)
/* ASM_EXPR and CALL_EXPR may embed arbitrary side effects.
As we cannot model data-references to not spelled out
accesses give up if they may occur. */
- if ((stmt_code == GIMPLE_CALL
- && !(gimple_call_flags (stmt) & ECF_CONST))
- || (stmt_code == GIMPLE_ASM
- && (gimple_asm_volatile_p (stmt) || gimple_vuse (stmt))))
+ if (stmt_code == GIMPLE_CALL
+ && !(gimple_call_flags (stmt) & ECF_CONST))
+ {
+ /* Allow IFN_GOMP_SIMD_LANE in their own loops. */
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
+ {
+ struct loop *loop = gimple_bb (stmt)->loop_father;
+ tree uid = gimple_call_arg (stmt, 0);
+ gcc_assert (TREE_CODE (uid) == SSA_NAME);
+ if (loop == NULL
+ || loop->simduid != SSA_NAME_VAR (uid))
+ clobbers_memory = true;
+ }
+ else
+ clobbers_memory = true;
+ }
+ else if (stmt_code == GIMPLE_ASM
+ && (gimple_asm_volatile_p (stmt) || gimple_vuse (stmt)))
clobbers_memory = true;
if (!gimple_vuse (stmt))
diff --git a/gcc/tree-eh.c b/gcc/tree-eh.c
index 0850bd53cf1..6ffbd266711 100644
--- a/gcc/tree-eh.c
+++ b/gcc/tree-eh.c
@@ -2157,25 +2157,42 @@ lower_eh_constructs (void)
return 0;
}
-struct gimple_opt_pass pass_lower_eh =
+namespace {
+
+const pass_data pass_data_lower_eh =
{
- {
- GIMPLE_PASS,
- "eh", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- lower_eh_constructs, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_EH, /* tv_id */
- PROP_gimple_lcf, /* properties_required */
- PROP_gimple_leh, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "eh", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_EH, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ PROP_gimple_leh, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_lower_eh : public gimple_opt_pass
+{
+public:
+ pass_lower_eh(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_eh, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return lower_eh_constructs (); }
+
+}; // class pass_lower_eh
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_eh (gcc::context *ctxt)
+{
+ return new pass_lower_eh (ctxt);
+}
/* Create the multiple edges from an EH_DISPATCH statement to all of
the possible handlers for its EH region. Return true if there's
@@ -3017,25 +3034,43 @@ gate_refactor_eh (void)
return flag_exceptions != 0;
}
-struct gimple_opt_pass pass_refactor_eh =
+namespace {
+
+const pass_data pass_data_refactor_eh =
{
- {
- GIMPLE_PASS,
- "ehopt", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_refactor_eh, /* gate */
- refactor_eh, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_EH, /* tv_id */
- PROP_gimple_lcf, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "ehopt", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_EH, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_refactor_eh : public gimple_opt_pass
+{
+public:
+ pass_refactor_eh(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_refactor_eh, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_refactor_eh (); }
+ unsigned int execute () { return refactor_eh (); }
+
+}; // class pass_refactor_eh
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_refactor_eh (gcc::context *ctxt)
+{
+ return new pass_refactor_eh (ctxt);
+}
/* At the end of gimple optimization, we can lower RESX. */
@@ -3226,26 +3261,44 @@ gate_lower_resx (void)
return flag_exceptions != 0;
}
-struct gimple_opt_pass pass_lower_resx =
+namespace {
+
+const pass_data pass_data_lower_resx =
{
- {
- GIMPLE_PASS,
- "resx", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_lower_resx, /* gate */
- execute_lower_resx, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_EH, /* tv_id */
- PROP_gimple_lcf, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "resx", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_EH, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_flow, /* todo_flags_finish */
};
+class pass_lower_resx : public gimple_opt_pass
+{
+public:
+ pass_lower_resx(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_resx, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_lower_resx (); }
+ unsigned int execute () { return execute_lower_resx (); }
+
+}; // class pass_lower_resx
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_resx (gcc::context *ctxt)
+{
+ return new pass_lower_resx (ctxt);
+}
+
/* Try to optimize var = {v} {CLOBBER} stmts followed just by
external throw. */
@@ -3619,25 +3672,43 @@ gate_lower_eh_dispatch (void)
return cfun->eh->region_tree != NULL;
}
-struct gimple_opt_pass pass_lower_eh_dispatch =
+namespace {
+
+const pass_data pass_data_lower_eh_dispatch =
{
- {
- GIMPLE_PASS,
- "ehdisp", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_lower_eh_dispatch, /* gate */
- execute_lower_eh_dispatch, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_EH, /* tv_id */
- PROP_gimple_lcf, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "ehdisp", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_EH, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_flow, /* todo_flags_finish */
};
+
+class pass_lower_eh_dispatch : public gimple_opt_pass
+{
+public:
+ pass_lower_eh_dispatch(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_eh_dispatch, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_lower_eh_dispatch (); }
+ unsigned int execute () { return execute_lower_eh_dispatch (); }
+
+}; // class pass_lower_eh_dispatch
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_eh_dispatch (gcc::context *ctxt)
+{
+ return new pass_lower_eh_dispatch (ctxt);
+}
/* Walk statements, see what regions and, optionally, landing pads
are really referenced.
@@ -4445,24 +4516,44 @@ gate_cleanup_eh (void)
return cfun->eh != NULL && cfun->eh->region_tree != NULL;
}
-struct gimple_opt_pass pass_cleanup_eh = {
- {
- GIMPLE_PASS,
- "ehcleanup", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_cleanup_eh, /* gate */
- execute_cleanup_eh, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_EH, /* tv_id */
- PROP_gimple_lcf, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_cleanup_eh =
+{
+ GIMPLE_PASS, /* type */
+ "ehcleanup", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_EH, /* tv_id */
+ PROP_gimple_lcf, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_cleanup_eh : public gimple_opt_pass
+{
+public:
+ pass_cleanup_eh(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_cleanup_eh, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_cleanup_eh (ctxt_); }
+ bool gate () { return gate_cleanup_eh (); }
+ unsigned int execute () { return execute_cleanup_eh (); }
+
+}; // class pass_cleanup_eh
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_cleanup_eh (gcc::context *ctxt)
+{
+ return new pass_cleanup_eh (ctxt);
+}
/* Verify that BB containing STMT as the last statement, has precisely the
edge that make_eh_edges would create. */
diff --git a/gcc/tree-emutls.c b/gcc/tree-emutls.c
index 6329fdd5015..ed8edc3569c 100644
--- a/gcc/tree-emutls.c
+++ b/gcc/tree-emutls.c
@@ -811,22 +811,40 @@ gate_emutls (void)
return !targetm.have_tls;
}
-struct simple_ipa_opt_pass pass_ipa_lower_emutls =
+namespace {
+
+const pass_data pass_data_ipa_lower_emutls =
{
- {
- SIMPLE_IPA_PASS,
- "emutls", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_emutls, /* gate */
- ipa_lower_emutls, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_OPT, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- }
+ SIMPLE_IPA_PASS, /* type */
+ "emutls", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_OPT, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_ipa_lower_emutls : public simple_ipa_opt_pass
+{
+public:
+ pass_ipa_lower_emutls(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_ipa_lower_emutls, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_emutls (); }
+ unsigned int execute () { return ipa_lower_emutls (); }
+
+}; // class pass_ipa_lower_emutls
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_lower_emutls (gcc::context *ctxt)
+{
+ return new pass_ipa_lower_emutls (ctxt);
+}
diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h
index caa8d7457fb..333e1687e5d 100644
--- a/gcc/tree-flow.h
+++ b/gcc/tree-flow.h
@@ -344,7 +344,6 @@ extern struct omp_region *new_omp_region (basic_block, enum gimple_code,
struct omp_region *);
extern void free_omp_regions (void);
void omp_expand_local (basic_block);
-extern tree find_omp_clause (tree, enum omp_clause_code);
tree copy_var_decl (tree, tree, tree);
/*---------------------------------------------------------------------------
@@ -750,7 +749,7 @@ bool may_be_nonaddressable_p (tree expr);
/* In tree-ssa-threadupdate.c. */
extern bool thread_through_all_blocks (bool);
-extern void register_jump_thread (edge, edge, edge);
+extern void register_jump_thread (vec<edge>, bool);
/* In gimplify.c */
tree force_gimple_operand_1 (tree, gimple_seq *, gimple_predicate, tree);
diff --git a/gcc/tree-if-conv.c b/gcc/tree-if-conv.c
index 0ebb8c36cea..3ef356a0ac7 100644
--- a/gcc/tree-if-conv.c
+++ b/gcc/tree-if-conv.c
@@ -797,20 +797,6 @@ if_convertible_stmt_p (gimple stmt, vec<data_reference_p> refs)
return true;
}
-/* Return true when BB post-dominates all its predecessors. */
-
-static bool
-bb_postdominates_preds (basic_block bb)
-{
- unsigned i;
-
- for (i = 0; i < EDGE_COUNT (bb->preds); i++)
- if (!dominated_by_p (CDI_POST_DOMINATORS, EDGE_PRED (bb, i)->src, bb))
- return false;
-
- return true;
-}
-
/* Return true when BB is if-convertible. This routine does not check
basic block's statements and phis.
@@ -868,10 +854,23 @@ if_convertible_bb_p (struct loop *loop, basic_block bb, basic_block exit_bb)
return false;
}
- if (EDGE_COUNT (bb->preds) == 2
- && bb != loop->header
- && !bb_postdominates_preds (bb))
- return false;
+ /* At least one incoming edge has to be non-critical as otherwise edge
+ predicates are not equal to basic-block predicates of the edge
+ source. */
+ if (EDGE_COUNT (bb->preds) > 1
+ && bb != loop->header)
+ {
+ bool found = false;
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (EDGE_COUNT (e->src->succs) == 1)
+ found = true;
+ if (!found)
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "only critical predecessors\n");
+ return false;
+ }
+ }
return true;
}
@@ -1084,7 +1083,6 @@ if_convertible_loop_p_1 (struct loop *loop,
return false;
calculate_dominance_info (CDI_DOMINATORS);
- calculate_dominance_info (CDI_POST_DOMINATORS);
/* Allow statements that can be handled during if-conversion. */
ifc_bbs = get_loop_body_in_if_conv_order (loop);
@@ -1220,8 +1218,7 @@ if_convertible_loop_p (struct loop *loop)
if-conversion. */
static basic_block
-find_phi_replacement_condition (struct loop *loop,
- basic_block bb, tree *cond,
+find_phi_replacement_condition (basic_block bb, tree *cond,
gimple_stmt_iterator *gsi)
{
edge first_edge, second_edge;
@@ -1231,34 +1228,10 @@ find_phi_replacement_condition (struct loop *loop,
first_edge = EDGE_PRED (bb, 0);
second_edge = EDGE_PRED (bb, 1);
- /* Use condition based on following criteria:
- 1)
- S1: x = !c ? a : b;
-
- S2: x = c ? b : a;
-
- S2 is preferred over S1. Make 'b' first_bb and use its condition.
-
- 2) Do not make loop header first_bb.
-
- 3)
- S1: x = !(c == d)? a : b;
-
- S21: t1 = c == d;
- S22: x = t1 ? b : a;
-
- S3: x = (c == d) ? b : a;
-
- S3 is preferred over S1 and S2*, Make 'b' first_bb and use
- its condition.
-
- 4) If pred B is dominated by pred A then use pred B's condition.
- See PR23115. */
-
- /* Select condition that is not TRUTH_NOT_EXPR. */
+ /* Prefer an edge with a not negated predicate.
+ ??? That's a very weak cost model. */
tmp_cond = bb_predicate (first_edge->src);
gcc_assert (tmp_cond);
-
if (TREE_CODE (tmp_cond) == TRUTH_NOT_EXPR)
{
edge tmp_edge;
@@ -1268,11 +1241,9 @@ find_phi_replacement_condition (struct loop *loop,
second_edge = tmp_edge;
}
- /* Check if FIRST_BB is loop header or not and make sure that
- FIRST_BB does not dominate SECOND_BB. */
- if (first_edge->src == loop->header
- || dominated_by_p (CDI_DOMINATORS,
- second_edge->src, first_edge->src))
+ /* Check if the edge we take the condition from is not critical.
+ We know that at least one non-critical edge exists. */
+ if (EDGE_COUNT (first_edge->src->succs) > 1)
{
*cond = bb_predicate (second_edge->src);
@@ -1347,9 +1318,6 @@ predicate_scalar_phi (gimple phi, tree cond,
arg_1 = gimple_phi_arg_def (phi, 1);
}
- gcc_checking_assert (bb == bb->loop_father->header
- || bb_postdominates_preds (bb));
-
/* Build new RHS using selected condition and arguments. */
rhs = fold_build_cond_expr (TREE_TYPE (res), unshare_expr (cond),
arg_0, arg_1);
@@ -1395,7 +1363,7 @@ predicate_all_scalar_phis (struct loop *loop)
/* BB has two predecessors. Using predecessor's aux field, set
appropriate condition for the PHI node replacement. */
gsi = gsi_after_labels (bb);
- true_bb = find_phi_replacement_condition (loop, bb, &cond, &gsi);
+ true_bb = find_phi_replacement_condition (bb, &cond, &gsi);
while (!gsi_end_p (phi_gsi))
{
@@ -1765,9 +1733,6 @@ combine_blocks (struct loop *loop)
free (ifc_bbs);
ifc_bbs = NULL;
-
- /* Post-dominators are corrupt now. */
- free_dominance_info (CDI_POST_DOMINATORS);
}
/* If-convert LOOP when it is legal. For the moment this pass has no
@@ -1822,6 +1787,10 @@ main_tree_if_conversion (void)
return 0;
FOR_EACH_LOOP (li, loop, 0)
+ if (flag_tree_loop_if_convert == 1
+ || flag_tree_loop_if_convert_stores == 1
+ || flag_tree_vectorize
+ || loop->force_vect)
changed |= tree_if_conversion (loop);
if (changed)
@@ -1830,8 +1799,6 @@ main_tree_if_conversion (void)
if (changed && flag_tree_loop_if_convert_stores)
todo |= TODO_update_ssa_only_virtuals;
- free_dominance_info (CDI_POST_DOMINATORS);
-
#ifdef ENABLE_CHECKING
{
basic_block bb;
@@ -1848,28 +1815,47 @@ main_tree_if_conversion (void)
static bool
gate_tree_if_conversion (void)
{
- return ((flag_tree_vectorize && flag_tree_loop_if_convert != 0)
+ return (((flag_tree_vectorize || cfun->has_force_vect_loops)
+ && flag_tree_loop_if_convert != 0)
|| flag_tree_loop_if_convert == 1
|| flag_tree_loop_if_convert_stores == 1);
}
-struct gimple_opt_pass pass_if_conversion =
+namespace {
+
+const pass_data pass_data_if_conversion =
{
- {
- GIMPLE_PASS,
- "ifcvt", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tree_if_conversion, /* gate */
- main_tree_if_conversion, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_stmts | TODO_verify_flow
- /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "ifcvt", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_stmts | TODO_verify_flow
+ | TODO_verify_ssa ), /* todo_flags_finish */
};
+
+class pass_if_conversion : public gimple_opt_pass
+{
+public:
+ pass_if_conversion(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_if_conversion, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_if_conversion (); }
+ unsigned int execute () { return main_tree_if_conversion (); }
+
+}; // class pass_if_conversion
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_if_conversion (gcc::context *ctxt)
+{
+ return new pass_if_conversion (ctxt);
+}
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 9b2c815de21..40eb3807119 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1298,7 +1298,8 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
case GIMPLE_OMP_FOR:
s1 = remap_gimple_seq (gimple_omp_body (stmt), id);
s2 = remap_gimple_seq (gimple_omp_for_pre_body (stmt), id);
- copy = gimple_build_omp_for (s1, gimple_omp_for_clauses (stmt),
+ copy = gimple_build_omp_for (s1, gimple_omp_for_kind (stmt),
+ gimple_omp_for_clauses (stmt),
gimple_omp_for_collapse (stmt), s2);
{
size_t i;
@@ -1387,6 +1388,23 @@ remap_gimple_stmt (gimple stmt, copy_body_data *id)
}
}
+ /* For *ptr_N ={v} {CLOBBER}, if ptr_N is SSA_NAME defined
+ in a block that we aren't copying during tree_function_versioning,
+ just drop the clobber stmt. */
+ if (id->blocks_to_copy && gimple_clobber_p (stmt))
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ if (TREE_CODE (lhs) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (lhs, 0)) == SSA_NAME)
+ {
+ gimple def_stmt = SSA_NAME_DEF_STMT (TREE_OPERAND (lhs, 0));
+ if (gimple_bb (def_stmt)
+ && !bitmap_bit_p (id->blocks_to_copy,
+ gimple_bb (def_stmt)->index))
+ return gimple_build_nop ();
+ }
+ }
+
if (gimple_debug_bind_p (stmt))
{
copy = gimple_build_debug_bind (gimple_debug_bind_get_var (stmt),
@@ -1676,6 +1694,8 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
if (edge)
{
int edge_freq = edge->frequency;
+ int new_freq;
+ struct cgraph_edge *old_edge = edge;
edge = cgraph_clone_edge (edge, id->dst_node, stmt,
gimple_uid (stmt),
REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
@@ -1683,25 +1703,52 @@ copy_bb (copy_body_data *id, basic_block bb, int frequency_scale,
/* We could also just rescale the frequency, but
doing so would introduce roundoff errors and make
verifier unhappy. */
- edge->frequency
- = compute_call_stmt_bb_frequency (id->dst_node->symbol.decl,
- copy_basic_block);
- if (dump_file
- && profile_status_for_function (cfun) != PROFILE_ABSENT
- && (edge_freq > edge->frequency + 10
- || edge_freq < edge->frequency - 10))
+ new_freq = compute_call_stmt_bb_frequency (id->dst_node->symbol.decl,
+ copy_basic_block);
+
+ /* Speculative calls consist of two edges - direct and indirect.
+ Duplicate the whole thing and distribute frequencies accordingly. */
+ if (edge->speculative)
{
- fprintf (dump_file, "Edge frequency estimated by "
- "cgraph %i diverge from inliner's estimate %i\n",
- edge_freq,
- edge->frequency);
- fprintf (dump_file,
- "Orig bb: %i, orig bb freq %i, new bb freq %i\n",
- bb->index,
- bb->frequency,
- copy_basic_block->frequency);
+ struct cgraph_edge *direct, *indirect;
+ struct ipa_ref *ref;
+
+ gcc_assert (!edge->indirect_unknown_callee);
+ cgraph_speculative_call_info (old_edge, direct, indirect, ref);
+ indirect = cgraph_clone_edge (indirect, id->dst_node, stmt,
+ gimple_uid (stmt),
+ REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
+ true);
+ if (old_edge->frequency + indirect->frequency)
+ {
+ edge->frequency = MIN (RDIV ((gcov_type)new_freq * old_edge->frequency,
+ (old_edge->frequency + indirect->frequency)),
+ CGRAPH_FREQ_MAX);
+ indirect->frequency = MIN (RDIV ((gcov_type)new_freq * indirect->frequency,
+ (old_edge->frequency + indirect->frequency)),
+ CGRAPH_FREQ_MAX);
+ }
+ ipa_clone_ref (ref, (symtab_node)id->dst_node, stmt);
+ }
+ else
+ {
+ edge->frequency = new_freq;
+ if (dump_file
+ && profile_status_for_function (cfun) != PROFILE_ABSENT
+ && (edge_freq > edge->frequency + 10
+ || edge_freq < edge->frequency - 10))
+ {
+ fprintf (dump_file, "Edge frequency estimated by "
+ "cgraph %i diverge from inliner's estimate %i\n",
+ edge_freq,
+ edge->frequency);
+ fprintf (dump_file,
+ "Orig bb: %i, orig bb freq %i, new bb freq %i\n",
+ bb->index,
+ bb->frequency,
+ copy_basic_block->frequency);
+ }
}
- stmt = cgraph_redirect_edge_call_stmt_to_callee (edge);
}
break;
@@ -2232,6 +2279,23 @@ copy_loops (bitmap blocks_to_copy,
}
}
+/* Call cgraph_redirect_edge_call_stmt_to_callee on all calls in BB */
+
+void
+redirect_all_calls (copy_body_data * id, basic_block bb)
+{
+ gimple_stmt_iterator si;
+ for (si = gsi_start_bb (bb); !gsi_end_p (si); gsi_next (&si))
+ {
+ if (is_gimple_call (gsi_stmt (si)))
+ {
+ struct cgraph_edge *edge = cgraph_edge (id->dst_node, gsi_stmt (si));
+ if (edge)
+ cgraph_redirect_edge_call_stmt_to_callee (edge);
+ }
+ }
+}
+
/* Make a copy of the body of FN so that it can be inserted inline in
another function. Walks FN via CFG, returns new fndecl. */
@@ -2336,6 +2400,8 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
get_loop (src_cfun, 0));
/* Defer to cfgcleanup to update loop-father fields of basic-blocks. */
loops_state_set (LOOPS_NEED_FIXUP);
+ cfun->has_force_vect_loops |= src_cfun->has_force_vect_loops;
+ cfun->has_simduid_loops |= src_cfun->has_simduid_loops;
}
/* If the loop tree in the source function needed fixup, mark the
@@ -2356,6 +2422,10 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
&& bb->index != ENTRY_BLOCK
&& bb->index != EXIT_BLOCK)
maybe_move_debug_stmts_to_successors (id, (basic_block) bb->aux);
+ /* Update call edge destinations. This can not be done before loop
+ info is updated, because we may split basic blocks. */
+ if (id->transform_call_graph_edges == CB_CGE_DUPLICATE)
+ redirect_all_calls (id, (basic_block)bb->aux);
((basic_block)bb->aux)->aux = NULL;
bb->aux = NULL;
}
@@ -2367,6 +2437,10 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
if (need_debug_cleanup)
maybe_move_debug_stmts_to_successors (id, BASIC_BLOCK (last));
BASIC_BLOCK (last)->aux = NULL;
+ /* Update call edge destinations. This can not be done before loop
+ info is updated, because we may split basic blocks. */
+ if (id->transform_call_graph_edges == CB_CGE_DUPLICATE)
+ redirect_all_calls (id, BASIC_BLOCK (last));
}
entry_block_map->aux = NULL;
exit_block_map->aux = NULL;
@@ -3670,7 +3744,14 @@ estimate_num_insns (gimple stmt, eni_weights *weights)
return 0;
case GIMPLE_ASM:
- return asm_str_count (gimple_asm_string (stmt));
+ {
+ int count = asm_str_count (gimple_asm_string (stmt));
+ /* 1000 means infinity. This avoids overflows later
+ with very long asm statements. */
+ if (count > 1000)
+ count = 1000;
+ return count;
+ }
case GIMPLE_RESX:
/* This is either going to be an external function call with one
@@ -3939,6 +4020,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
goto egress;
}
fn = cg_edge->callee->symbol.decl;
+ cgraph_get_body (cg_edge->callee);
#ifdef ENABLE_CHECKING
if (cg_edge->callee->symbol.decl != id->dst_node->symbol.decl)
@@ -4940,43 +5022,47 @@ delete_unreachable_blocks_update_callgraph (copy_body_data *id)
gimple_stmt_iterator bsi;
for (bsi = gsi_start_bb (b); !gsi_end_p (bsi); gsi_next (&bsi))
- if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL)
- {
- struct cgraph_edge *e;
- struct cgraph_node *node;
+ {
+ struct cgraph_edge *e;
+ struct cgraph_node *node;
- if ((e = cgraph_edge (id->dst_node, gsi_stmt (bsi))) != NULL)
+ ipa_remove_stmt_references ((symtab_node)id->dst_node, gsi_stmt (bsi));
+
+ if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL
+ &&(e = cgraph_edge (id->dst_node, gsi_stmt (bsi))) != NULL)
+ {
+ if (!e->inline_failed)
+ cgraph_remove_node_and_inline_clones (e->callee, id->dst_node);
+ else
+ cgraph_remove_edge (e);
+ }
+ if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES
+ && id->dst_node->clones)
+ for (node = id->dst_node->clones; node != id->dst_node;)
{
- if (!e->inline_failed)
- cgraph_remove_node_and_inline_clones (e->callee, id->dst_node);
+ ipa_remove_stmt_references ((symtab_node)node, gsi_stmt (bsi));
+ if (gimple_code (gsi_stmt (bsi)) == GIMPLE_CALL
+ && (e = cgraph_edge (node, gsi_stmt (bsi))) != NULL)
+ {
+ if (!e->inline_failed)
+ cgraph_remove_node_and_inline_clones (e->callee, id->dst_node);
+ else
+ cgraph_remove_edge (e);
+ }
+
+ if (node->clones)
+ node = node->clones;
+ else if (node->next_sibling_clone)
+ node = node->next_sibling_clone;
else
- cgraph_remove_edge (e);
+ {
+ while (node != id->dst_node && !node->next_sibling_clone)
+ node = node->clone_of;
+ if (node != id->dst_node)
+ node = node->next_sibling_clone;
+ }
}
- if (id->transform_call_graph_edges == CB_CGE_MOVE_CLONES
- && id->dst_node->clones)
- for (node = id->dst_node->clones; node != id->dst_node;)
- {
- if ((e = cgraph_edge (node, gsi_stmt (bsi))) != NULL)
- {
- if (!e->inline_failed)
- cgraph_remove_node_and_inline_clones (e->callee, id->dst_node);
- else
- cgraph_remove_edge (e);
- }
-
- if (node->clones)
- node = node->clones;
- else if (node->next_sibling_clone)
- node = node->next_sibling_clone;
- else
- {
- while (node != id->dst_node && !node->next_sibling_clone)
- node = node->clone_of;
- if (node != id->dst_node)
- node = node->next_sibling_clone;
- }
- }
- }
+ }
delete_basic_block (b);
changed = true;
}
@@ -5085,6 +5171,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
DECL_ARTIFICIAL (new_decl) = 1;
DECL_ABSTRACT_ORIGIN (new_decl) = DECL_ORIGIN (old_decl);
+ if (DECL_ORIGIN (old_decl) == old_decl)
+ old_version_node->used_as_abstract_origin = true;
DECL_FUNCTION_PERSONALITY (new_decl) = DECL_FUNCTION_PERSONALITY (old_decl);
/* Prepare the data structures for the tree copy. */
@@ -5100,6 +5188,7 @@ tree_function_versioning (tree old_decl, tree new_decl,
id.src_node = old_version_node;
id.dst_node = new_version_node;
id.src_cfun = DECL_STRUCT_FUNCTION (old_decl);
+ id.blocks_to_copy = blocks_to_copy;
if (id.src_node->ipa_transforms_to_apply.exists ())
{
vec<ipa_opt_pass> old_transforms_to_apply
@@ -5122,6 +5211,8 @@ tree_function_versioning (tree old_decl, tree new_decl,
old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION
(DECL_STRUCT_FUNCTION (old_decl));
+ DECL_RESULT (new_decl) = DECL_RESULT (old_decl);
+ DECL_ARGUMENTS (new_decl) = DECL_ARGUMENTS (old_decl);
initialize_cfun (new_decl, old_decl,
old_entry_block->count);
DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta
@@ -5146,17 +5237,43 @@ tree_function_versioning (tree old_decl, tree new_decl,
{
int i = replace_info->parm_num;
tree parm;
+ tree req_type;
+
for (parm = DECL_ARGUMENTS (old_decl); i; parm = DECL_CHAIN (parm))
i --;
replace_info->old_tree = parm;
+ req_type = TREE_TYPE (parm);
+ if (!useless_type_conversion_p (req_type, TREE_TYPE (replace_info->new_tree)))
+ {
+ if (fold_convertible_p (req_type, replace_info->new_tree))
+ replace_info->new_tree = fold_build1 (NOP_EXPR, req_type, replace_info->new_tree);
+ else if (TYPE_SIZE (req_type) == TYPE_SIZE (TREE_TYPE (replace_info->new_tree)))
+ replace_info->new_tree = fold_build1 (VIEW_CONVERT_EXPR, req_type, replace_info->new_tree);
+ else
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, " const ");
+ print_generic_expr (dump_file, replace_info->new_tree, 0);
+ fprintf (dump_file, " can't be converted to param ");
+ print_generic_expr (dump_file, parm, 0);
+ fprintf (dump_file, "\n");
+ }
+ replace_info->old_tree = NULL;
+ }
+ }
+ }
+ else
+ gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL);
+ if (replace_info->old_tree)
+ {
+ init = setup_one_parameter (&id, replace_info->old_tree,
+ replace_info->new_tree, id.src_fn,
+ NULL,
+ &vars);
+ if (init)
+ init_stmts.safe_push (init);
}
- gcc_assert (TREE_CODE (replace_info->old_tree) == PARM_DECL);
- init = setup_one_parameter (&id, replace_info->old_tree,
- replace_info->new_tree, id.src_fn,
- NULL,
- &vars);
- if (init)
- init_stmts.safe_push (init);
}
}
/* Copy the function's arguments. */
diff --git a/gcc/tree-inline.h b/gcc/tree-inline.h
index b65dee9350b..620ec977768 100644
--- a/gcc/tree-inline.h
+++ b/gcc/tree-inline.h
@@ -115,6 +115,10 @@ typedef struct copy_body_data
/* Entry basic block to currently copied body. */
basic_block entry_bb;
+ /* For partial function versioning, bitmap of bbs to be copied,
+ otherwise NULL. */
+ bitmap blocks_to_copy;
+
/* Debug statements that need processing. */
vec<gimple> debug_stmts;
diff --git a/gcc/tree-into-ssa.c b/gcc/tree-into-ssa.c
index 4c630a3130e..33d4ba8c623 100644
--- a/gcc/tree-into-ssa.c
+++ b/gcc/tree-into-ssa.c
@@ -2410,27 +2410,43 @@ rewrite_into_ssa (void)
}
-struct gimple_opt_pass pass_build_ssa =
-{
- {
- GIMPLE_PASS,
- "ssa", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- rewrite_into_ssa, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SSA_OTHER, /* tv_id */
- PROP_cfg, /* properties_required */
- PROP_ssa, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_remove_unused_locals /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_build_ssa =
+{
+ GIMPLE_PASS, /* type */
+ "ssa", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SSA_OTHER, /* tv_id */
+ PROP_cfg, /* properties_required */
+ PROP_ssa, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa | TODO_remove_unused_locals ), /* todo_flags_finish */
};
+class pass_build_ssa : public gimple_opt_pass
+{
+public:
+ pass_build_ssa(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_build_ssa, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return rewrite_into_ssa (); }
+
+}; // class pass_build_ssa
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_build_ssa (gcc::context *ctxt)
+{
+ return new pass_build_ssa (ctxt);
+}
+
/* Mark the definition of VAR at STMT and BB as interesting for the
renamer. BLOCKS is the set of blocks that need updating. */
diff --git a/gcc/tree-loop-distribution.c b/gcc/tree-loop-distribution.c
index 13b78cc37d2..95c4d5f753a 100644
--- a/gcc/tree-loop-distribution.c
+++ b/gcc/tree-loop-distribution.c
@@ -542,17 +542,19 @@ already_processed_vertex_p (bitmap processed, int v)
|| !bitmap_bit_p (remaining_stmts, v));
}
-/* Returns NULL when there is no anti-dependence among the successors
- of vertex V, otherwise returns the edge with the anti-dep. */
+/* Returns NULL when there is no anti-dependence or output-dependence
+ among the successors of vertex V, otherwise returns the edge with the
+ dependency. */
static struct graph_edge *
-has_anti_dependence (struct vertex *v)
+has_anti_or_output_dependence (struct vertex *v)
{
struct graph_edge *e;
if (v->succ)
for (e = v->succ; e; e = e->succ_next)
- if (RDGE_TYPE (e) == anti_dd)
+ if (RDGE_TYPE (e) == anti_dd
+ || RDGE_TYPE (e) == output_dd)
return e;
return NULL;
@@ -604,11 +606,10 @@ mark_nodes_having_upstream_mem_writes (struct graph *rdg)
|| predecessor_has_mem_write (rdg, &(rdg->vertices[x]))
/* In anti dependences the read should occur before
the write, this is why both the read and the write
- should be placed in the same partition. */
- || has_anti_dependence (&(rdg->vertices[x])))
- {
- bitmap_set_bit (upstream_mem_writes, x);
- }
+ should be placed in the same partition. In output
+ dependences the writes order need to be preserved. */
+ || has_anti_or_output_dependence (&(rdg->vertices[x])))
+ bitmap_set_bit (upstream_mem_writes, x);
}
nodes.release ();
@@ -637,7 +638,7 @@ rdg_flag_uses (struct graph *rdg, int u, partition_t partition, bitmap loops,
use_operand_p use_p;
struct vertex *x = &(rdg->vertices[u]);
gimple stmt = RDGV_STMT (x);
- struct graph_edge *anti_dep = has_anti_dependence (x);
+ struct graph_edge *anti_dep = has_anti_or_output_dependence (x);
/* Keep in the same partition the destination of an antidependence,
because this is a store to the exact same location. Putting this
@@ -1589,22 +1590,40 @@ gate_tree_loop_distribution (void)
|| flag_tree_loop_distribute_patterns;
}
-struct gimple_opt_pass pass_loop_distribution =
+namespace {
+
+const pass_data pass_data_loop_distribution =
{
- {
- GIMPLE_PASS,
- "ldist", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_loop_distribution, /* gate */
- tree_loop_distribution, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_LOOP_DISTRIBUTION, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "ldist", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_LOOP_DISTRIBUTION, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_loop_distribution : public gimple_opt_pass
+{
+public:
+ pass_loop_distribution(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_loop_distribution, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_loop_distribution (); }
+ unsigned int execute () { return tree_loop_distribution (); }
+
+}; // class pass_loop_distribution
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_loop_distribution (gcc::context *ctxt)
+{
+ return new pass_loop_distribution (ctxt);
+}
diff --git a/gcc/tree-mudflap.c b/gcc/tree-mudflap.c
index b250bfefadb..87431e7237c 100644
--- a/gcc/tree-mudflap.c
+++ b/gcc/tree-mudflap.c
@@ -106,20 +106,12 @@ mf_build_string (const char *string)
static tree
mf_varname_tree (tree decl)
{
- static pretty_printer buf_rec;
- static int initialized = 0;
- pretty_printer *buf = & buf_rec;
const char *buf_contents;
tree result;
gcc_assert (decl);
- if (!initialized)
- {
- pp_construct (buf, /* prefix */ NULL, /* line-width */ 0);
- initialized = 1;
- }
- pp_clear_output_area (buf);
+ pretty_printer buf;
/* Add FILENAME[:LINENUMBER[:COLUMNNUMBER]]. */
{
@@ -134,17 +126,17 @@ mf_varname_tree (tree decl)
if (sourcefile == NULL)
sourcefile = "<unknown file>";
- pp_string (buf, sourcefile);
+ pp_string (&buf, sourcefile);
if (sourceline != 0)
{
- pp_string (buf, ":");
- pp_decimal_int (buf, sourceline);
+ pp_colon (&buf);
+ pp_decimal_int (&buf, sourceline);
if (sourcecolumn != 0)
{
- pp_string (buf, ":");
- pp_decimal_int (buf, sourcecolumn);
+ pp_colon (&buf);
+ pp_decimal_int (&buf, sourcecolumn);
}
}
}
@@ -152,7 +144,7 @@ mf_varname_tree (tree decl)
if (current_function_decl != NULL_TREE)
{
/* Add (FUNCTION) */
- pp_string (buf, " (");
+ pp_string (&buf, " (");
{
const char *funcname = NULL;
if (DECL_NAME (current_function_decl))
@@ -160,12 +152,12 @@ mf_varname_tree (tree decl)
if (funcname == NULL)
funcname = "anonymous fn";
- pp_string (buf, funcname);
+ pp_string (&buf, funcname);
}
- pp_string (buf, ") ");
+ pp_string (&buf, ") ");
}
else
- pp_string (buf, " ");
+ pp_space (&buf);
/* Add <variable-declaration>, possibly demangled. */
{
@@ -186,13 +178,13 @@ mf_varname_tree (tree decl)
if (declname == NULL)
declname = "<unnamed variable>";
- pp_string (buf, declname);
+ pp_string (&buf, declname);
}
/* Return the lot as a new STRING_CST. */
- buf_contents = pp_base_formatted_text (buf);
+ buf_contents = ggc_strdup (pp_formatted_text (&buf));
result = mf_build_string (buf_contents);
- pp_clear_output_area (buf);
+ pp_clear_output_area (&buf);
return result;
}
@@ -1378,45 +1370,81 @@ gate_mudflap (void)
return flag_mudflap != 0;
}
-struct gimple_opt_pass pass_mudflap_1 =
+namespace {
+
+const pass_data pass_data_mudflap_1 =
{
- {
- GIMPLE_PASS,
- "mudflap1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_mudflap, /* gate */
- execute_mudflap_function_decls, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_gimple_any, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "mudflap1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_gimple_any, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
-struct gimple_opt_pass pass_mudflap_2 =
+class pass_mudflap_1 : public gimple_opt_pass
+{
+public:
+ pass_mudflap_1(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_mudflap_1, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_mudflap (); }
+ unsigned int execute () { return execute_mudflap_function_decls (); }
+
+}; // class pass_mudflap_1
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_mudflap_1 (gcc::context *ctxt)
+{
+ return new pass_mudflap_1 (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_mudflap_2 =
{
- {
- GIMPLE_PASS,
- "mudflap2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_mudflap, /* gate */
- execute_mudflap_function_ops, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa | PROP_cfg | PROP_gimple_leh,/* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow | TODO_verify_stmts
- | TODO_update_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "mudflap2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_ssa | PROP_cfg | PROP_gimple_leh ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_flow | TODO_verify_stmts
+ | TODO_update_ssa ), /* todo_flags_finish */
};
+class pass_mudflap_2 : public gimple_opt_pass
+{
+public:
+ pass_mudflap_2(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_mudflap_2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_mudflap (); }
+ unsigned int execute () { return execute_mudflap_function_ops (); }
+
+}; // class pass_mudflap_2
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_mudflap_2 (gcc::context *ctxt)
+{
+ return new pass_mudflap_2 (ctxt);
+}
+
#include "gt-tree-mudflap.h"
diff --git a/gcc/tree-nomudflap.c b/gcc/tree-nomudflap.c
index 657c82dad53..6659f05f5b1 100644
--- a/gcc/tree-nomudflap.c
+++ b/gcc/tree-nomudflap.c
@@ -85,46 +85,80 @@ gate_mudflap (void)
return flag_mudflap != 0;
}
-struct gimple_opt_pass pass_mudflap_1 =
+namespace {
+
+const pass_data pass_data_mudflap_1 =
{
- {
- GIMPLE_PASS,
- "mudflap1", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_mudflap, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "mudflap1", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
-struct gimple_opt_pass pass_mudflap_2 =
+class pass_mudflap_1 : public gimple_opt_pass
+{
+public:
+ pass_mudflap_1(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_mudflap_1, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_mudflap (); }
+
+}; // class pass_mudflap_1
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_mudflap_1 (gcc::context *ctxt)
+{
+ return new pass_mudflap_1 (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_mudflap_2 =
{
- {
- GIMPLE_PASS,
- "mudflap2", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_mudflap, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "mudflap2", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_mudflap_2 : public gimple_opt_pass
+{
+public:
+ pass_mudflap_2(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_mudflap_2, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_mudflap (); }
+
+}; // class pass_mudflap_2
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_mudflap_2 (gcc::context *ctxt)
+{
+ return new pass_mudflap_2 (ctxt);
+}
+
/* Instead of:
#include "gt-tree-mudflap.h"
We prepare a little dummy struct here.
diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c
index 51bc7cd90cd..2acb2ebaa34 100644
--- a/gcc/tree-nrv.c
+++ b/gcc/tree-nrv.c
@@ -269,26 +269,44 @@ gate_pass_return_slot (void)
return optimize > 0;
}
-struct gimple_opt_pass pass_nrv =
+namespace {
+
+const pass_data pass_data_nrv =
{
- {
- GIMPLE_PASS,
- "nrv", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_pass_return_slot, /* gate */
- tree_nrv, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_NRV, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "nrv", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_NRV, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_nrv : public gimple_opt_pass
+{
+public:
+ pass_nrv(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_nrv, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_pass_return_slot (); }
+ unsigned int execute () { return tree_nrv (); }
+
+}; // class pass_nrv
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_nrv (gcc::context *ctxt)
+{
+ return new pass_nrv (ctxt);
+}
+
/* Determine (pessimistically) whether DEST is available for NRV
optimization, where DEST is expected to be the LHS of a modify
expression where the RHS is a function returning an aggregate.
@@ -355,22 +373,39 @@ execute_return_slot_opt (void)
return 0;
}
-struct gimple_opt_pass pass_return_slot =
+namespace {
+
+const pass_data pass_data_return_slot =
{
- {
- GIMPLE_PASS,
- "retslot", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_return_slot_opt, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "retslot", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_return_slot : public gimple_opt_pass
+{
+public:
+ pass_return_slot(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_return_slot, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_return_slot_opt (); }
+
+}; // class pass_return_slot
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_return_slot (gcc::context *ctxt)
+{
+ return new pass_return_slot (ctxt);
+}
diff --git a/gcc/tree-object-size.c b/gcc/tree-object-size.c
index 16345713505..1a52a416a63 100644
--- a/gcc/tree-object-size.c
+++ b/gcc/tree-object-size.c
@@ -1262,22 +1262,40 @@ compute_object_sizes (void)
return 0;
}
-struct gimple_opt_pass pass_object_sizes =
+namespace {
+
+const pass_data pass_data_object_sizes =
{
- {
- GIMPLE_PASS,
- "objsz", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- compute_object_sizes, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "objsz", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_object_sizes : public gimple_opt_pass
+{
+public:
+ pass_object_sizes(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_object_sizes, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_object_sizes (ctxt_); }
+ unsigned int execute () { return compute_object_sizes (); }
+
+}; // class pass_object_sizes
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_object_sizes (gcc::context *ctxt)
+{
+ return new pass_object_sizes (ctxt);
+}
diff --git a/gcc/tree-optimize.c b/gcc/tree-optimize.c
index 0948d2e6977..9c99ec23a2e 100644
--- a/gcc/tree-optimize.c
+++ b/gcc/tree-optimize.c
@@ -88,26 +88,45 @@ execute_cleanup_cfg_post_optimizing (void)
return todo;
}
-struct gimple_opt_pass pass_cleanup_cfg_post_optimizing =
+namespace {
+
+const pass_data pass_data_cleanup_cfg_post_optimizing =
{
- {
- GIMPLE_PASS,
- "optimized", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_cleanup_cfg_post_optimizing, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_CLEANUP_CFG, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_remove_unused_locals /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "optimized", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_CLEANUP_CFG, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_remove_unused_locals, /* todo_flags_finish */
};
+class pass_cleanup_cfg_post_optimizing : public gimple_opt_pass
+{
+public:
+ pass_cleanup_cfg_post_optimizing(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_cleanup_cfg_post_optimizing, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () {
+ return execute_cleanup_cfg_post_optimizing ();
+ }
+
+}; // class pass_cleanup_cfg_post_optimizing
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_cleanup_cfg_post_optimizing (gcc::context *ctxt)
+{
+ return new pass_cleanup_cfg_post_optimizing (ctxt);
+}
+
/* IPA passes, compilation of earlier functions or inlining
might have changed some properties, such as marked functions nothrow,
pure, const or noreturn.
@@ -211,22 +230,40 @@ execute_fixup_cfg (void)
return todo;
}
-struct gimple_opt_pass pass_fixup_cfg =
+namespace {
+
+const pass_data pass_data_fixup_cfg =
{
- {
- GIMPLE_PASS,
- "*free_cfg_annotations", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_fixup_cfg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "*free_cfg_annotations", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_fixup_cfg : public gimple_opt_pass
+{
+public:
+ pass_fixup_cfg(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_fixup_cfg, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_fixup_cfg (ctxt_); }
+ unsigned int execute () { return execute_fixup_cfg (); }
+
+}; // class pass_fixup_cfg
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_fixup_cfg (gcc::context *ctxt)
+{
+ return new pass_fixup_cfg (ctxt);
+}
diff --git a/gcc/tree-parloops.c b/gcc/tree-parloops.c
index cea6f030c0a..9d413c7fb42 100644
--- a/gcc/tree-parloops.c
+++ b/gcc/tree-parloops.c
@@ -494,9 +494,12 @@ take_address_of (tree obj, tree type, edge entry,
if (gsi == NULL)
return NULL;
addr = TREE_OPERAND (*var_p, 0);
- name = make_temp_ssa_name (TREE_TYPE (addr), NULL,
- get_name (TREE_OPERAND
- (TREE_OPERAND (*var_p, 0), 0)));
+ const char *obj_name
+ = get_name (TREE_OPERAND (TREE_OPERAND (*var_p, 0), 0));
+ if (obj_name)
+ name = make_temp_ssa_name (TREE_TYPE (addr), NULL, obj_name);
+ else
+ name = make_ssa_name (TREE_TYPE (addr), NULL);
stmt = gimple_build_assign (name, addr);
gsi_insert_on_edge_immediate (entry, stmt);
@@ -694,6 +697,12 @@ eliminate_local_variables_stmt (edge entry, gimple_stmt_iterator *gsi,
dta.changed = true;
}
}
+ else if (gimple_clobber_p (stmt))
+ {
+ stmt = gimple_build_nop ();
+ gsi_replace (gsi, stmt, false);
+ dta.changed = true;
+ }
else
{
dta.gsi = gsi;
@@ -1686,7 +1695,7 @@ create_parallel_loop (struct loop *loop, tree loop_fn, tree data,
t = build_omp_clause (loc, OMP_CLAUSE_SCHEDULE);
OMP_CLAUSE_SCHEDULE_KIND (t) = OMP_CLAUSE_SCHEDULE_STATIC;
- for_stmt = gimple_build_omp_for (NULL, t, 1, NULL);
+ for_stmt = gimple_build_omp_for (NULL, GF_OMP_FOR_KIND_FOR, t, 1, NULL);
gimple_set_location (for_stmt, loc);
gimple_omp_for_set_index (for_stmt, 0, initvar);
gimple_omp_for_set_initial (for_stmt, 0, cvar_init);
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 547f355851d..ea1a62f4368 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -34,9 +34,8 @@ enum opt_pass_type
IPA_PASS
};
-/* Describe one pass; this is the common part shared across different pass
- types. */
-struct opt_pass
+/* Metadata for a pass, non-varying across all instances of a pass. */
+struct pass_data
{
/* Optimization pass type. */
enum opt_pass_type type;
@@ -48,23 +47,13 @@ struct opt_pass
/* The -fopt-info optimization group flags as defined in dumpfile.h. */
unsigned int optinfo_flags;
- /* If non-null, this pass and all sub-passes are executed only if
- the function returns true. */
- bool (*gate) (void);
+ /* If true, this pass has its own implementation of the opt_pass::gate
+ method. */
+ bool has_gate;
- /* This is the code to run. If null, then there should be sub-passes
- otherwise this pass does nothing. The return value contains
- TODOs to execute in addition to those in TODO_flags_finish. */
- unsigned int (*execute) (void);
-
- /* A list of sub-passes to run, dependent on gate predicate. */
- struct opt_pass *sub;
-
- /* Next in the list of passes to run, independent of gate predicate. */
- struct opt_pass *next;
-
- /* Static pass number, used as a fragment of the dump file name. */
- int static_pass_number;
+ /* If true, this pass has its own implementation of the opt_pass::execute
+ method. */
+ bool has_execute;
/* The timevar id associated with this pass. */
/* ??? Ideally would be dynamically assigned. */
@@ -80,16 +69,73 @@ struct opt_pass
unsigned int todo_flags_finish;
};
+namespace gcc
+{
+ class context;
+} // namespace gcc
+
+/* An instance of a pass. This is also "pass_data" to minimize the
+ changes in existing code. */
+class opt_pass : public pass_data
+{
+public:
+ virtual ~opt_pass () { }
+
+ /* Create a copy of this pass.
+
+ Passes that can have multiple instances must provide their own
+ implementation of this, to ensure that any sharing of state between
+ this instance and the copy is "wired up" correctly.
+
+ The default implementation prints an error message and aborts. */
+ virtual opt_pass *clone ();
+
+ /* If has_gate is set, this pass and all sub-passes are executed only if
+ the function returns true.
+ The default implementation returns true. */
+ virtual bool gate ();
+
+ /* This is the code to run. If has_execute is false, then there should
+ be sub-passes otherwise this pass does nothing.
+ The return value contains TODOs to execute in addition to those in
+ TODO_flags_finish. */
+ virtual unsigned int execute ();
+
+protected:
+ opt_pass(const pass_data&, gcc::context *);
+
+public:
+ /* A list of sub-passes to run, dependent on gate predicate. */
+ struct opt_pass *sub;
+
+ /* Next in the list of passes to run, independent of gate predicate. */
+ struct opt_pass *next;
+
+ /* Static pass number, used as a fragment of the dump file name. */
+ int static_pass_number;
+
+protected:
+ gcc::context *ctxt_;
+};
+
/* Description of GIMPLE pass. */
-struct gimple_opt_pass
+class gimple_opt_pass : public opt_pass
{
- struct opt_pass pass;
+protected:
+ gimple_opt_pass(const pass_data& data, gcc::context *ctxt)
+ : opt_pass(data, ctxt)
+ {
+ }
};
/* Description of RTL pass. */
-struct rtl_opt_pass
+class rtl_opt_pass : public opt_pass
{
- struct opt_pass pass;
+protected:
+ rtl_opt_pass(const pass_data& data, gcc::context *ctxt)
+ : opt_pass(data, ctxt)
+ {
+ }
};
struct varpool_node;
@@ -98,10 +144,9 @@ struct lto_symtab_encoder_d;
/* Description of IPA pass with generate summary, write, execute, read and
transform stages. */
-struct ipa_opt_pass_d
+class ipa_opt_pass_d : public opt_pass
{
- struct opt_pass pass;
-
+public:
/* IPA passes can analyze function body and variable initializers
using this hook and produce summary. */
void (*generate_summary) (void);
@@ -127,13 +172,42 @@ struct ipa_opt_pass_d
unsigned int function_transform_todo_flags_start;
unsigned int (*function_transform) (struct cgraph_node *);
void (*variable_transform) (struct varpool_node *);
+
+protected:
+ ipa_opt_pass_d(const pass_data& data, gcc::context *ctxt,
+ void (*generate_summary) (void),
+ void (*write_summary) (void),
+ void (*read_summary) (void),
+ void (*write_optimization_summary) (void),
+ void (*read_optimization_summary) (void),
+ void (*stmt_fixup) (struct cgraph_node *, gimple *),
+ unsigned int function_transform_todo_flags_start,
+ unsigned int (*function_transform) (struct cgraph_node *),
+ void (*variable_transform) (struct varpool_node *))
+ : opt_pass(data, ctxt),
+ generate_summary(generate_summary),
+ write_summary(write_summary),
+ read_summary(read_summary),
+ write_optimization_summary(write_optimization_summary),
+ read_optimization_summary(read_optimization_summary),
+ stmt_fixup(stmt_fixup),
+ function_transform_todo_flags_start(
+ function_transform_todo_flags_start),
+ function_transform(function_transform),
+ variable_transform(variable_transform)
+ {
+ }
};
/* Description of simple IPA pass. Simple IPA passes have just one execute
hook. */
-struct simple_ipa_opt_pass
+class simple_ipa_opt_pass : public opt_pass
{
- struct opt_pass pass;
+protected:
+ simple_ipa_opt_pass(const pass_data& data, gcc::context *ctxt)
+ : opt_pass(data, ctxt)
+ {
+ }
};
/* Pass properties. */
@@ -257,267 +331,261 @@ struct register_pass_info
enum pass_positioning_ops pos_op; /* how to insert the new pass. */
};
-extern struct gimple_opt_pass pass_mudflap_1;
-extern struct gimple_opt_pass pass_mudflap_2;
-extern struct gimple_opt_pass pass_asan;
-extern struct gimple_opt_pass pass_asan_O0;
-extern struct gimple_opt_pass pass_tsan;
-extern struct gimple_opt_pass pass_tsan_O0;
-extern struct gimple_opt_pass pass_lower_cf;
-extern struct gimple_opt_pass pass_refactor_eh;
-extern struct gimple_opt_pass pass_lower_eh;
-extern struct gimple_opt_pass pass_lower_eh_dispatch;
-extern struct gimple_opt_pass pass_lower_resx;
-extern struct gimple_opt_pass pass_build_cfg;
-extern struct gimple_opt_pass pass_early_tree_profile;
-extern struct gimple_opt_pass pass_cleanup_eh;
-extern struct gimple_opt_pass pass_sra;
-extern struct gimple_opt_pass pass_sra_early;
-extern struct gimple_opt_pass pass_early_ipa_sra;
-extern struct gimple_opt_pass pass_tail_recursion;
-extern struct gimple_opt_pass pass_tail_calls;
-extern struct gimple_opt_pass pass_tree_loop;
-extern struct gimple_opt_pass pass_tree_loop_init;
-extern struct gimple_opt_pass pass_lim;
-extern struct gimple_opt_pass pass_tree_unswitch;
-extern struct gimple_opt_pass pass_predcom;
-extern struct gimple_opt_pass pass_iv_canon;
-extern struct gimple_opt_pass pass_scev_cprop;
-extern struct gimple_opt_pass pass_empty_loop;
-extern struct gimple_opt_pass pass_record_bounds;
-extern struct gimple_opt_pass pass_graphite;
-extern struct gimple_opt_pass pass_graphite_transforms;
-extern struct gimple_opt_pass pass_if_conversion;
-extern struct gimple_opt_pass pass_loop_distribution;
-extern struct gimple_opt_pass pass_vectorize;
-extern struct gimple_opt_pass pass_slp_vectorize;
-extern struct gimple_opt_pass pass_complete_unroll;
-extern struct gimple_opt_pass pass_complete_unrolli;
-extern struct gimple_opt_pass pass_parallelize_loops;
-extern struct gimple_opt_pass pass_loop_prefetch;
-extern struct gimple_opt_pass pass_iv_optimize;
-extern struct gimple_opt_pass pass_tree_loop_done;
-extern struct gimple_opt_pass pass_ch;
-extern struct gimple_opt_pass pass_ccp;
-extern struct gimple_opt_pass pass_phi_only_cprop;
-extern struct gimple_opt_pass pass_build_ssa;
-extern struct gimple_opt_pass pass_build_alias;
-extern struct gimple_opt_pass pass_build_ealias;
-extern struct gimple_opt_pass pass_dominator;
-extern struct gimple_opt_pass pass_dce;
-extern struct gimple_opt_pass pass_dce_loop;
-extern struct gimple_opt_pass pass_cd_dce;
-extern struct gimple_opt_pass pass_call_cdce;
-extern struct gimple_opt_pass pass_merge_phi;
-extern struct gimple_opt_pass pass_split_crit_edges;
-extern struct gimple_opt_pass pass_pre;
+/* Registers a new pass. Either fill out the register_pass_info or specify
+ the individual parameters. The pass object is expected to have been
+ allocated using operator new and the pass manager takes the ownership of
+ the pass object. */
+extern void register_pass (register_pass_info *);
+extern void register_pass (opt_pass* pass, pass_positioning_ops pos,
+ const char* ref_pass_name, int ref_pass_inst_number);
+
+extern gimple_opt_pass *make_pass_mudflap_1 (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_mudflap_2 (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_asan (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_asan_O0 (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tsan (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tsan_O0 (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_cf (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_refactor_eh (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_eh (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_eh_dispatch (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_resx (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_build_cfg (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_early_tree_profile (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_cleanup_eh (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_sra (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_sra_early (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_early_ipa_sra (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tail_recursion (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tail_calls (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tree_loop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tree_loop_init (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lim (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tree_unswitch (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_predcom (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_iv_canon (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_scev_cprop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_empty_loop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_record_bounds (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_graphite (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_graphite_transforms (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_if_conversion (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_loop_distribution (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_vectorize (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_slp_vectorize (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_complete_unroll (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_complete_unrolli (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_parallelize_loops (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_loop_prefetch (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_iv_optimize (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tree_loop_done (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_ch (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_ccp (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_phi_only_cprop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_build_ssa (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_build_alias (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_build_ealias (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_dominator (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_dce (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_dce_loop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_cd_dce (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_call_cdce (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_merge_phi (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_split_crit_edges (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_pre (gcc::context *ctxt);
extern unsigned int tail_merge_optimize (unsigned int);
-extern struct gimple_opt_pass pass_profile;
-extern struct gimple_opt_pass pass_strip_predict_hints;
-extern struct gimple_opt_pass pass_lower_complex_O0;
-extern struct gimple_opt_pass pass_lower_complex;
-extern struct gimple_opt_pass pass_lower_vector;
-extern struct gimple_opt_pass pass_lower_vector_ssa;
-extern struct gimple_opt_pass pass_lower_omp;
-extern struct gimple_opt_pass pass_diagnose_omp_blocks;
-extern struct gimple_opt_pass pass_expand_omp;
-extern struct gimple_opt_pass pass_expand_omp_ssa;
-extern struct gimple_opt_pass pass_object_sizes;
-extern struct gimple_opt_pass pass_strlen;
-extern struct gimple_opt_pass pass_fold_builtins;
-extern struct gimple_opt_pass pass_stdarg;
-extern struct gimple_opt_pass pass_early_warn_uninitialized;
-extern struct gimple_opt_pass pass_late_warn_uninitialized;
-extern struct gimple_opt_pass pass_cse_reciprocals;
-extern struct gimple_opt_pass pass_cse_sincos;
-extern struct gimple_opt_pass pass_optimize_bswap;
-extern struct gimple_opt_pass pass_optimize_widening_mul;
-extern struct gimple_opt_pass pass_warn_function_return;
-extern struct gimple_opt_pass pass_warn_function_noreturn;
-extern struct gimple_opt_pass pass_cselim;
-extern struct gimple_opt_pass pass_phiopt;
-extern struct gimple_opt_pass pass_forwprop;
-extern struct gimple_opt_pass pass_phiprop;
-extern struct gimple_opt_pass pass_tree_ifcombine;
-extern struct gimple_opt_pass pass_dse;
-extern struct gimple_opt_pass pass_nrv;
-extern struct gimple_opt_pass pass_rename_ssa_copies;
-extern struct gimple_opt_pass pass_sink_code;
-extern struct gimple_opt_pass pass_fre;
-extern struct gimple_opt_pass pass_check_data_deps;
-extern struct gimple_opt_pass pass_copy_prop;
-extern struct gimple_opt_pass pass_vrp;
-extern struct gimple_opt_pass pass_uncprop;
-extern struct gimple_opt_pass pass_return_slot;
-extern struct gimple_opt_pass pass_reassoc;
-extern struct gimple_opt_pass pass_rebuild_cgraph_edges;
-extern struct gimple_opt_pass pass_remove_cgraph_callee_edges;
-extern struct gimple_opt_pass pass_build_cgraph_edges;
-extern struct gimple_opt_pass pass_local_pure_const;
-extern struct gimple_opt_pass pass_tracer;
-extern struct gimple_opt_pass pass_warn_unused_result;
-extern struct gimple_opt_pass pass_diagnose_tm_blocks;
-extern struct gimple_opt_pass pass_lower_tm;
-extern struct gimple_opt_pass pass_tm_init;
-extern struct gimple_opt_pass pass_tm_mark;
-extern struct gimple_opt_pass pass_tm_memopt;
-extern struct gimple_opt_pass pass_tm_edges;
-extern struct gimple_opt_pass pass_split_functions;
-extern struct gimple_opt_pass pass_feedback_split_functions;
-extern struct gimple_opt_pass pass_strength_reduction;
+extern gimple_opt_pass *make_pass_profile (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_strip_predict_hints (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_complex_O0 (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_complex (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_vector (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_vector_ssa (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_omp (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_diagnose_omp_blocks (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_expand_omp (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_expand_omp_ssa (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_object_sizes (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_strlen (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_fold_builtins (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_stdarg (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_early_warn_uninitialized (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_late_warn_uninitialized (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_cse_reciprocals (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_cse_sincos (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_optimize_bswap (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_optimize_widening_mul (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_warn_function_return (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_warn_function_noreturn (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_cselim (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_phiopt (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_forwprop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_phiprop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tree_ifcombine (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_dse (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_nrv (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_rename_ssa_copies (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_sink_code (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_fre (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_check_data_deps (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_copy_prop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_vrp (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_uncprop (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_return_slot (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_reassoc (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_rebuild_cgraph_edges (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_remove_cgraph_callee_edges (gcc::context
+ *ctxt);
+extern gimple_opt_pass *make_pass_build_cgraph_edges (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_local_pure_const (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tracer (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_warn_unused_result (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_diagnose_tm_blocks (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_lower_tm (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tm_init (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tm_mark (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tm_memopt (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_tm_edges (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_split_functions (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_feedback_split_functions (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_strength_reduction (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_vtable_verify (gcc::context *ctxt);
/* IPA Passes */
-extern struct simple_ipa_opt_pass pass_ipa_lower_emutls;
-extern struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility;
-extern struct simple_ipa_opt_pass pass_ipa_tree_profile;
-
-extern struct simple_ipa_opt_pass pass_early_local_passes;
-
-extern struct ipa_opt_pass_d pass_ipa_whole_program_visibility;
-extern struct ipa_opt_pass_d pass_ipa_lto_gimple_out;
-extern struct simple_ipa_opt_pass pass_ipa_increase_alignment;
-extern struct ipa_opt_pass_d pass_ipa_inline;
-extern struct simple_ipa_opt_pass pass_ipa_free_lang_data;
-extern struct simple_ipa_opt_pass pass_ipa_free_inline_summary;
-extern struct ipa_opt_pass_d pass_ipa_cp;
-extern struct ipa_opt_pass_d pass_ipa_reference;
-extern struct ipa_opt_pass_d pass_ipa_pure_const;
-extern struct simple_ipa_opt_pass pass_ipa_pta;
-extern struct ipa_opt_pass_d pass_ipa_lto_finish_out;
-extern struct simple_ipa_opt_pass pass_ipa_tm;
-extern struct ipa_opt_pass_d pass_ipa_profile;
-extern struct ipa_opt_pass_d pass_ipa_cdtor_merge;
-
-extern struct gimple_opt_pass pass_cleanup_cfg_post_optimizing;
-extern struct gimple_opt_pass pass_init_datastructures;
-extern struct gimple_opt_pass pass_fixup_cfg;
-
-extern struct rtl_opt_pass pass_expand;
-extern struct rtl_opt_pass pass_instantiate_virtual_regs;
-extern struct rtl_opt_pass pass_rtl_fwprop;
-extern struct rtl_opt_pass pass_rtl_fwprop_addr;
-extern struct rtl_opt_pass pass_jump;
-extern struct rtl_opt_pass pass_jump2;
-extern struct rtl_opt_pass pass_lower_subreg;
-extern struct rtl_opt_pass pass_cse;
-extern struct rtl_opt_pass pass_fast_rtl_dce;
-extern struct rtl_opt_pass pass_ud_rtl_dce;
-extern struct rtl_opt_pass pass_rtl_dce;
-extern struct rtl_opt_pass pass_rtl_dse1;
-extern struct rtl_opt_pass pass_rtl_dse2;
-extern struct rtl_opt_pass pass_rtl_dse3;
-extern struct rtl_opt_pass pass_rtl_cprop;
-extern struct rtl_opt_pass pass_rtl_pre;
-extern struct rtl_opt_pass pass_rtl_hoist;
-extern struct rtl_opt_pass pass_rtl_store_motion;
-extern struct rtl_opt_pass pass_cse_after_global_opts;
-extern struct rtl_opt_pass pass_rtl_ifcvt;
-
-extern struct rtl_opt_pass pass_into_cfg_layout_mode;
-extern struct rtl_opt_pass pass_outof_cfg_layout_mode;
-
-extern struct rtl_opt_pass pass_loop2;
-extern struct rtl_opt_pass pass_rtl_loop_init;
-extern struct rtl_opt_pass pass_rtl_move_loop_invariants;
-extern struct rtl_opt_pass pass_rtl_unswitch;
-extern struct rtl_opt_pass pass_rtl_unroll_and_peel_loops;
-extern struct rtl_opt_pass pass_rtl_doloop;
-extern struct rtl_opt_pass pass_rtl_loop_done;
-
-extern struct rtl_opt_pass pass_web;
-extern struct rtl_opt_pass pass_cse2;
-extern struct rtl_opt_pass pass_df_initialize_opt;
-extern struct rtl_opt_pass pass_df_initialize_no_opt;
-extern struct rtl_opt_pass pass_reginfo_init;
-extern struct rtl_opt_pass pass_inc_dec;
-extern struct rtl_opt_pass pass_stack_ptr_mod;
-extern struct rtl_opt_pass pass_initialize_regs;
-extern struct rtl_opt_pass pass_combine;
-extern struct rtl_opt_pass pass_if_after_combine;
-extern struct rtl_opt_pass pass_ree;
-extern struct rtl_opt_pass pass_partition_blocks;
-extern struct rtl_opt_pass pass_match_asm_constraints;
-extern struct rtl_opt_pass pass_regmove;
-extern struct rtl_opt_pass pass_split_all_insns;
-extern struct rtl_opt_pass pass_fast_rtl_byte_dce;
-extern struct rtl_opt_pass pass_lower_subreg2;
-extern struct rtl_opt_pass pass_mode_switching;
-extern struct rtl_opt_pass pass_sms;
-extern struct rtl_opt_pass pass_sched;
-extern struct rtl_opt_pass pass_ira;
-extern struct rtl_opt_pass pass_reload;
-extern struct rtl_opt_pass pass_clean_state;
-extern struct rtl_opt_pass pass_branch_prob;
-extern struct rtl_opt_pass pass_value_profile_transformations;
-extern struct rtl_opt_pass pass_postreload_cse;
-extern struct rtl_opt_pass pass_gcse2;
-extern struct rtl_opt_pass pass_split_after_reload;
-extern struct rtl_opt_pass pass_branch_target_load_optimize1;
-extern struct rtl_opt_pass pass_thread_prologue_and_epilogue;
-extern struct rtl_opt_pass pass_stack_adjustments;
-extern struct rtl_opt_pass pass_peephole2;
-extern struct rtl_opt_pass pass_if_after_reload;
-extern struct rtl_opt_pass pass_regrename;
-extern struct rtl_opt_pass pass_cprop_hardreg;
-extern struct rtl_opt_pass pass_reorder_blocks;
-extern struct rtl_opt_pass pass_branch_target_load_optimize2;
-extern struct rtl_opt_pass pass_leaf_regs;
-extern struct rtl_opt_pass pass_split_before_sched2;
-extern struct rtl_opt_pass pass_compare_elim_after_reload;
-extern struct rtl_opt_pass pass_sched2;
-extern struct rtl_opt_pass pass_stack_regs;
-extern struct rtl_opt_pass pass_stack_regs_run;
-extern struct rtl_opt_pass pass_df_finish;
-extern struct rtl_opt_pass pass_compute_alignments;
-extern struct rtl_opt_pass pass_duplicate_computed_gotos;
-extern struct rtl_opt_pass pass_variable_tracking;
-extern struct rtl_opt_pass pass_free_cfg;
-extern struct rtl_opt_pass pass_machine_reorg;
-extern struct rtl_opt_pass pass_cleanup_barriers;
-extern struct rtl_opt_pass pass_delay_slots;
-extern struct rtl_opt_pass pass_split_for_shorten_branches;
-extern struct rtl_opt_pass pass_split_before_regstack;
-extern struct rtl_opt_pass pass_convert_to_eh_region_ranges;
-extern struct rtl_opt_pass pass_shorten_branches;
-extern struct rtl_opt_pass pass_set_nothrow_function_flags;
-extern struct rtl_opt_pass pass_dwarf2_frame;
-extern struct rtl_opt_pass pass_final;
-extern struct rtl_opt_pass pass_rtl_seqabstr;
-extern struct gimple_opt_pass pass_release_ssa_names;
-extern struct gimple_opt_pass pass_early_inline;
-extern struct gimple_opt_pass pass_inline_parameters;
-extern struct gimple_opt_pass pass_update_address_taken;
-extern struct gimple_opt_pass pass_convert_switch;
-
-/* The root of the compilation pass tree, once constructed. */
-extern struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes,
- *all_regular_ipa_passes, *all_lto_gen_passes, *all_late_ipa_passes;
-
-/* Define a list of pass lists so that both passes.c and plugins can easily
- find all the pass lists. */
-#define GCC_PASS_LISTS \
- DEF_PASS_LIST (all_lowering_passes) \
- DEF_PASS_LIST (all_small_ipa_passes) \
- DEF_PASS_LIST (all_regular_ipa_passes) \
- DEF_PASS_LIST (all_lto_gen_passes) \
- DEF_PASS_LIST (all_passes)
-
-#define DEF_PASS_LIST(LIST) PASS_LIST_NO_##LIST,
-enum
-{
- GCC_PASS_LISTS
- PASS_LIST_NUM
-};
-#undef DEF_PASS_LIST
-
-/* This is used by plugins, and should also be used in
- passes.c:register_pass. */
-extern struct opt_pass **gcc_pass_lists[];
+extern simple_ipa_opt_pass *make_pass_ipa_lower_emutls (gcc::context *ctxt);
+extern simple_ipa_opt_pass
+ *make_pass_ipa_function_and_variable_visibility (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_tree_profile (gcc::context *ctxt);
+
+extern simple_ipa_opt_pass *make_pass_early_local_passes (gcc::context *ctxt);
+
+extern ipa_opt_pass_d *make_pass_ipa_whole_program_visibility (gcc::context
+ *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_lto_gimple_out (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_increase_alignment (gcc::context
+ *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_inline (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_free_lang_data (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_free_inline_summary (gcc::context
+ *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_cp (gcc::context *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_devirt (gcc::context *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_reference (gcc::context *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_pure_const (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_pta (gcc::context *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_lto_finish_out (gcc::context *ctxt);
+extern simple_ipa_opt_pass *make_pass_ipa_tm (gcc::context *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_profile (gcc::context *ctxt);
+extern ipa_opt_pass_d *make_pass_ipa_cdtor_merge (gcc::context *ctxt);
+
+extern gimple_opt_pass *make_pass_cleanup_cfg_post_optimizing (gcc::context
+ *ctxt);
+extern gimple_opt_pass *make_pass_init_datastructures (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_fixup_cfg (gcc::context *ctxt);
+
+extern rtl_opt_pass *make_pass_expand (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_instantiate_virtual_regs (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_fwprop (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_fwprop_addr (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_jump (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_jump2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_lower_subreg (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_cse (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_fast_rtl_dce (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_ud_rtl_dce (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_dce (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_dse1 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_dse2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_dse3 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_cprop (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_pre (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_hoist (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_store_motion (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_cse_after_global_opts (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_ifcvt (gcc::context *ctxt);
+
+extern rtl_opt_pass *make_pass_into_cfg_layout_mode (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_outof_cfg_layout_mode (gcc::context *ctxt);
+
+extern rtl_opt_pass *make_pass_loop2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_loop_init (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_move_loop_invariants (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_unswitch (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_unroll_and_peel_loops (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_doloop (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_loop_done (gcc::context *ctxt);
+
+extern rtl_opt_pass *make_pass_web (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_cse2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_df_initialize_opt (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_df_initialize_no_opt (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_reginfo_init (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_inc_dec (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_stack_ptr_mod (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_initialize_regs (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_combine (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_if_after_combine (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_ree (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_partition_blocks (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_match_asm_constraints (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_regmove (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_split_all_insns (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_fast_rtl_byte_dce (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_lower_subreg2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_mode_switching (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_sms (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_sched (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_ira (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_reload (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_clean_state (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_branch_prob (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_value_profile_transformations (gcc::context
+ *ctxt);
+extern rtl_opt_pass *make_pass_postreload_cse (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_gcse2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_split_after_reload (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_branch_target_load_optimize1 (gcc::context
+ *ctxt);
+extern rtl_opt_pass *make_pass_thread_prologue_and_epilogue (gcc::context
+ *ctxt);
+extern rtl_opt_pass *make_pass_stack_adjustments (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_peephole2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_if_after_reload (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_regrename (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_cprop_hardreg (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_reorder_blocks (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_branch_target_load_optimize2 (gcc::context
+ *ctxt);
+extern rtl_opt_pass *make_pass_leaf_regs (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_split_before_sched2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_compare_elim_after_reload (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_sched2 (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_stack_regs (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_stack_regs_run (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_df_finish (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_compute_alignments (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_duplicate_computed_gotos (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_variable_tracking (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_free_cfg (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_machine_reorg (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_cleanup_barriers (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_delay_slots (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_split_for_shorten_branches (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_split_before_regstack (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_convert_to_eh_region_ranges (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_shorten_branches (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_set_nothrow_function_flags (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_dwarf2_frame (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_final (gcc::context *ctxt);
+extern rtl_opt_pass *make_pass_rtl_seqabstr (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_release_ssa_names (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_early_inline (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_inline_parameters (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_update_address_taken (gcc::context *ctxt);
+extern gimple_opt_pass *make_pass_convert_switch (gcc::context *ctxt);
/* Current optimization pass. */
extern struct opt_pass *current_pass;
-extern struct opt_pass * get_pass_for_id (int);
extern bool execute_one_pass (struct opt_pass *);
extern void execute_pass_list (struct opt_pass *);
extern void execute_ipa_pass_list (struct opt_pass *);
@@ -536,7 +604,6 @@ extern void ipa_read_summaries (void);
extern void ipa_read_optimization_summaries (void);
extern void register_one_dump_file (struct opt_pass *);
extern bool function_called_by_processed_nodes_p (void);
-extern void register_pass (struct register_pass_info *);
/* Set to true if the pass is called the first time during compilation of the
current function. Note that using this information in the optimization
@@ -547,9 +614,6 @@ extern void register_pass (struct register_pass_info *);
directly in jump threading, and avoid peeling them next time. */
extern bool first_pass_instance;
-extern struct opt_pass **passes_by_id;
-extern int passes_by_id_size;
-
/* Declare for plugins. */
extern void do_per_function_toporder (void (*) (void *), void *);
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 7745f73210b..69e40060727 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -33,6 +33,8 @@ along with GCC; see the file COPYING3. If not see
#include "value-prof.h"
#include "predict.h"
+#include <new> // For placement-new.
+
/* Local functions, macros and variables. */
static const char *op_symbol (const_tree);
static void pretty_print_string (pretty_printer *, const char*);
@@ -229,7 +231,7 @@ dump_function_declaration (pretty_printer *buffer, tree node,
tree arg;
pp_space (buffer);
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
/* Print the argument types. */
arg = TYPE_ARG_TYPES (node);
@@ -237,7 +239,7 @@ dump_function_declaration (pretty_printer *buffer, tree node,
{
if (wrote_arg)
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
wrote_arg = true;
@@ -253,7 +255,7 @@ dump_function_declaration (pretty_printer *buffer, tree node,
pp_string (buffer, ", ...");
/* Avoid printing any arg for unprototyped functions. */
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
/* Dump the domain associated with an array. */
@@ -261,7 +263,7 @@ dump_function_declaration (pretty_printer *buffer, tree node,
static void
dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
{
- pp_character (buffer, '[');
+ pp_left_bracket (buffer);
if (domain)
{
tree min = TYPE_MIN_VALUE (domain);
@@ -275,14 +277,14 @@ dump_array_domain (pretty_printer *buffer, tree domain, int spc, int flags)
{
if (min)
dump_generic_node (buffer, min, spc, flags, false);
- pp_character (buffer, ':');
+ pp_colon (buffer);
if (max)
dump_generic_node (buffer, max, spc, flags, false);
}
}
else
pp_string (buffer, "<unknown>");
- pp_character (buffer, ']');
+ pp_right_bracket (buffer);
}
@@ -314,35 +316,38 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
case OMP_CLAUSE_COPYPRIVATE:
name = "copyprivate";
goto print_remap;
+ case OMP_CLAUSE_UNIFORM:
+ name = "uniform";
+ goto print_remap;
print_remap:
pp_string (buffer, name);
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
- spc, flags, false);
- pp_character (buffer, ')');
+ spc, flags, false);
+ pp_right_paren (buffer);
break;
case OMP_CLAUSE_REDUCTION:
pp_string (buffer, "reduction(");
pp_string (buffer, op_symbol_code (OMP_CLAUSE_REDUCTION_CODE (clause)));
- pp_character (buffer, ':');
+ pp_colon (buffer);
dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case OMP_CLAUSE_IF:
pp_string (buffer, "if(");
dump_generic_node (buffer, OMP_CLAUSE_IF_EXPR (clause),
spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case OMP_CLAUSE_NUM_THREADS:
pp_string (buffer, "num_threads(");
dump_generic_node (buffer, OMP_CLAUSE_NUM_THREADS_EXPR (clause),
spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case OMP_CLAUSE_NOWAIT:
@@ -373,7 +378,7 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
default:
gcc_unreachable ();
}
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case OMP_CLAUSE_SCHEDULE:
@@ -400,12 +405,12 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
}
if (OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause))
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
dump_generic_node (buffer,
OMP_CLAUSE_SCHEDULE_CHUNK_EXPR (clause),
spc, flags, false);
}
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case OMP_CLAUSE_UNTIED:
@@ -417,20 +422,44 @@ dump_omp_clause (pretty_printer *buffer, tree clause, int spc, int flags)
dump_generic_node (buffer,
OMP_CLAUSE_COLLAPSE_EXPR (clause),
spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case OMP_CLAUSE_FINAL:
pp_string (buffer, "final(");
dump_generic_node (buffer, OMP_CLAUSE_FINAL_EXPR (clause),
spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case OMP_CLAUSE_MERGEABLE:
pp_string (buffer, "mergeable");
break;
+ case OMP_CLAUSE_LINEAR:
+ pp_string (buffer, "linear(");
+ dump_generic_node (buffer, OMP_CLAUSE_DECL (clause),
+ spc, flags, false);
+ pp_character (buffer, ':');
+ dump_generic_node (buffer, OMP_CLAUSE_LINEAR_STEP (clause),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
+ case OMP_CLAUSE_SAFELEN:
+ pp_string (buffer, "safelen(");
+ dump_generic_node (buffer, OMP_CLAUSE_SAFELEN_EXPR (clause),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
+ case OMP_CLAUSE__SIMDUID_:
+ pp_string (buffer, "_simduid_(");
+ dump_generic_node (buffer, OMP_CLAUSE__SIMDUID__DECL (clause),
+ spc, flags, false);
+ pp_character (buffer, ')');
+ break;
+
default:
/* Should never happen. */
dump_generic_node (buffer, clause, spc, flags, false);
@@ -467,7 +496,7 @@ dump_location (pretty_printer *buffer, location_t loc)
{
expanded_location xloc = expand_location (loc);
- pp_character (buffer, '[');
+ pp_left_bracket (buffer);
if (xloc.file)
{
pp_string (buffer, xloc.file);
@@ -519,7 +548,7 @@ dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
for (t = BLOCK_SUBBLOCKS (block); t; t = BLOCK_CHAIN (t))
{
dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
- pp_string (buffer, " ");
+ pp_space (buffer);
}
newline_and_indent (buffer, spc + 2);
}
@@ -530,7 +559,7 @@ dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
for (t = BLOCK_CHAIN (block); t; t = BLOCK_CHAIN (t))
{
dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
- pp_string (buffer, " ");
+ pp_space (buffer);
}
newline_and_indent (buffer, spc + 2);
}
@@ -541,7 +570,7 @@ dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
for (t = BLOCK_VARS (block); t; t = TREE_CHAIN (t))
{
dump_generic_node (buffer, t, 0, flags, false);
- pp_string (buffer, " ");
+ pp_space (buffer);
}
newline_and_indent (buffer, spc + 2);
}
@@ -555,7 +584,7 @@ dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
FOR_EACH_VEC_ELT (*nlv, i, t)
{
dump_generic_node (buffer, t, 0, flags, false);
- pp_string (buffer, " ");
+ pp_space (buffer);
}
newline_and_indent (buffer, spc + 2);
}
@@ -582,7 +611,7 @@ dump_block_node (pretty_printer *buffer, tree block, int spc, int flags)
for (t = BLOCK_FRAGMENT_CHAIN (block); t; t = BLOCK_FRAGMENT_CHAIN (t))
{
dump_generic_node (buffer, t, 0, flags | TDF_SLIM, false);
- pp_string (buffer, " ");
+ pp_space (buffer);
}
newline_and_indent (buffer, spc + 2);
}
@@ -638,7 +667,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
node = TREE_CHAIN (node);
if (node && TREE_CODE (node) == TREE_LIST)
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
}
@@ -658,7 +687,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
dump_generic_node (buffer, TREE_VEC_ELT (node, i), spc, flags,
false);
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
dump_generic_node (buffer, TREE_VEC_ELT (node, len - 1), spc,
@@ -717,7 +746,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
else if (TREE_CODE (node) == VECTOR_TYPE)
{
pp_string (buffer, "vector");
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
pp_wide_integer (buffer, TYPE_VECTOR_SUBPARTS (node));
pp_string (buffer, ") ");
dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
@@ -757,7 +786,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
? "<unnamed-unsigned:"
: "<unnamed-signed:"));
pp_decimal_int (buffer, TYPE_PRECISION (node));
- pp_string (buffer, ">");
+ pp_greater (buffer);
}
}
else if (TREE_CODE (node) == COMPLEX_TYPE)
@@ -769,14 +798,14 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
pp_string (buffer, "<float:");
pp_decimal_int (buffer, TYPE_PRECISION (node));
- pp_string (buffer, ">");
+ pp_greater (buffer);
}
else if (TREE_CODE (node) == FIXED_POINT_TYPE)
{
pp_string (buffer, "<fixed-point-");
pp_string (buffer, TYPE_SATURATING (node) ? "sat:" : "nonsat:");
pp_decimal_int (buffer, TYPE_PRECISION (node));
- pp_string (buffer, ">");
+ pp_greater (buffer);
}
else if (TREE_CODE (node) == VOID_TYPE)
pp_string (buffer, "void");
@@ -801,7 +830,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_TYPE (fnode), spc, flags, false);
pp_space (buffer);
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
pp_string (buffer, str);
if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
dump_decl_name (buffer, TYPE_NAME (node), flags);
@@ -810,7 +839,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
else
pp_printf (buffer, "<T%x>", TYPE_UID (node));
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
dump_function_declaration (buffer, fnode, spc, flags);
}
else
@@ -832,7 +861,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
pp_string (buffer, " <address-space-");
pp_decimal_int (buffer, TYPE_ADDR_SPACE (node));
- pp_string (buffer, ">");
+ pp_greater (buffer);
}
if (TYPE_REF_CAN_ALIAS_ALL (node))
@@ -868,7 +897,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
if (TREE_CODE (TREE_OPERAND (node, 0)) != ADDR_EXPR)
{
- pp_string (buffer, "*");
+ pp_star (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 0),
spc, flags, false);
}
@@ -882,11 +911,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
tree ptype;
pp_string (buffer, "MEM[");
- pp_string (buffer, "(");
+ pp_left_paren (buffer);
ptype = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (node, 1)));
dump_generic_node (buffer, ptype,
spc, flags | TDF_SLIM, false);
- pp_string (buffer, ")");
+ pp_right_paren (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 0),
spc, flags, false);
if (!integer_zerop (TREE_OPERAND (node, 1)))
@@ -895,7 +924,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 1),
spc, flags, false);
}
- pp_string (buffer, "]");
+ pp_right_bracket (buffer);
}
break;
}
@@ -954,7 +983,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_string (buffer, "offset: ");
dump_generic_node (buffer, tmp, spc, flags, false);
}
- pp_string (buffer, "]");
+ pp_right_bracket (buffer);
}
break;
@@ -1045,7 +1074,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (tree_int_cst_sgn (val) < 0)
{
- pp_character (buffer, '-');
+ pp_minus (buffer);
high = ~high + !low;
low = -low;
}
@@ -1102,7 +1131,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_REALPART (node), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, TREE_IMAGPART (node), spc, flags, false);
- pp_string (buffer, ")");
+ pp_right_paren (buffer);
break;
case STRING_CST:
@@ -1137,7 +1166,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
flags);
else
pp_string (buffer, "<null method basetype>");
- pp_string (buffer, "::");
+ pp_colon_colon (buffer);
}
if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
dump_decl_name (buffer, TYPE_NAME (node), flags);
@@ -1241,10 +1270,10 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
str = "->";
}
if (op_prio (op0) < op_prio (node))
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, op0, spc, flags, false);
if (op_prio (op0) < op_prio (node))
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
pp_string (buffer, str);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
op0 = component_ref_field_offset (node);
@@ -1252,7 +1281,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
pp_string (buffer, "{off: ");
dump_generic_node (buffer, op0, spc, flags, false);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
break;
@@ -1263,22 +1292,22 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case ARRAY_REF:
case ARRAY_RANGE_REF:
op0 = TREE_OPERAND (node, 0);
if (op_prio (op0) < op_prio (node))
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, op0, spc, flags, false);
if (op_prio (op0) < op_prio (node))
- pp_character (buffer, ')');
- pp_character (buffer, '[');
+ pp_right_paren (buffer);
+ pp_left_bracket (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
if (TREE_CODE (node) == ARRAY_RANGE_REF)
pp_string (buffer, " ...");
- pp_character (buffer, ']');
+ pp_right_bracket (buffer);
op0 = array_ref_low_bound (node);
op1 = array_ref_element_size (node);
@@ -1291,7 +1320,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, op0, spc, flags, false);
pp_string (buffer, " sz: ");
dump_generic_node (buffer, op1, spc, flags, false);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
break;
@@ -1302,7 +1331,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
bool is_struct_init = false;
bool is_array_init = false;
double_int curidx = double_int_zero;
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
if (TREE_CLOBBER_P (node))
pp_string (buffer, "CLOBBER");
else if (TREE_CODE (TREE_TYPE (node)) == RECORD_TYPE
@@ -1324,15 +1353,15 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
if (is_struct_init)
{
- pp_character (buffer, '.');
+ pp_dot (buffer);
dump_generic_node (buffer, field, spc, flags, false);
- pp_character (buffer, '=');
+ pp_equal (buffer);
}
else if (is_array_init
&& (TREE_CODE (field) != INTEGER_CST
|| tree_to_double_int (field) != curidx))
{
- pp_character (buffer, '[');
+ pp_left_bracket (buffer);
if (TREE_CODE (field) == RANGE_EXPR)
{
dump_generic_node (buffer, TREE_OPERAND (field, 0), spc,
@@ -1361,11 +1390,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, val, spc, flags, false);
if (ix != vec_safe_length (CONSTRUCTOR_ELTS (node)) - 1)
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
}
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
break;
@@ -1384,7 +1413,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
newline_and_indent (buffer, spc);
else
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
@@ -1398,7 +1427,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
newline_and_indent (buffer, spc);
else
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
}
@@ -1434,7 +1463,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags,
false);
pp_space (buffer);
- pp_character (buffer, '=');
+ pp_equal (buffer);
pp_space (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags,
false);
@@ -1443,10 +1472,10 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case TARGET_EXPR:
pp_string (buffer, "TARGET_EXPR <");
dump_generic_node (buffer, TARGET_EXPR_SLOT (node), spc, flags, false);
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
dump_generic_node (buffer, TARGET_EXPR_INITIAL (node), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
case DECL_EXPR:
@@ -1459,7 +1488,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
pp_string (buffer, "if (");
dump_generic_node (buffer, COND_EXPR_COND (node), spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
/* The lowered cond_exprs should always be printed in full. */
if (COND_EXPR_THEN (node)
&& (IS_EMPTY_STMT (COND_EXPR_THEN (node))
@@ -1484,12 +1513,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (COND_EXPR_THEN (node))
{
newline_and_indent (buffer, spc+2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc+4);
dump_generic_node (buffer, COND_EXPR_THEN (node), spc+4,
flags, true);
newline_and_indent (buffer, spc+2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
/* Output COND_EXPR_ELSE. */
@@ -1499,12 +1528,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
newline_and_indent (buffer, spc);
pp_string (buffer, "else");
newline_and_indent (buffer, spc+2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc+4);
dump_generic_node (buffer, COND_EXPR_ELSE (node), spc+4,
flags, true);
newline_and_indent (buffer, spc+2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
is_expr = false;
@@ -1513,18 +1542,18 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
pp_space (buffer);
- pp_character (buffer, '?');
+ pp_question (buffer);
pp_space (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
pp_space (buffer);
- pp_character (buffer, ':');
+ pp_colon (buffer);
pp_space (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
}
break;
case BIND_EXPR:
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
if (!(flags & TDF_SLIM))
{
if (BIND_EXPR_VARS (node))
@@ -1541,7 +1570,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
newline_and_indent (buffer, spc+2);
dump_generic_node (buffer, BIND_EXPR_BODY (node), spc+2, flags, true);
newline_and_indent (buffer, spc);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
is_expr = false;
break;
@@ -1551,7 +1580,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
/* Print parameters. */
pp_space (buffer);
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
{
tree arg;
call_expr_arg_iterator iter;
@@ -1560,7 +1589,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, arg, spc, flags, false);
if (more_call_expr_args_p (&iter))
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
}
@@ -1569,19 +1598,19 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
{
if (call_expr_nargs (node) > 0)
{
- pp_character (buffer, ',');
+ pp_comma (buffer);
pp_space (buffer);
}
pp_string (buffer, "__builtin_va_arg_pack ()");
}
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
op1 = CALL_EXPR_STATIC_CHAIN (node);
if (op1)
{
pp_string (buffer, " [static-chain: ");
dump_generic_node (buffer, op1, spc, flags, false);
- pp_character (buffer, ']');
+ pp_right_bracket (buffer);
}
if (CALL_EXPR_RETURN_SLOT_OPT (node))
@@ -1603,7 +1632,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case PLACEHOLDER_EXPR:
pp_string (buffer, "<PLACEHOLDER_EXPR ");
dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
/* Binary arithmetic and logic expressions. */
@@ -1662,9 +1691,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
keep semantics of the tree representation. */
if (op_prio (op0) <= op_prio (node))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, op0, spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
else
dump_generic_node (buffer, op0, spc, flags, false);
@@ -1677,9 +1706,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
keep semantics of the tree representation. */
if (op_prio (op1) <= op_prio (node))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, op1, spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
else
dump_generic_node (buffer, op1, spc, flags, false);
@@ -1703,9 +1732,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
else
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
@@ -1715,9 +1744,9 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case POSTINCREMENT_EXPR:
if (op_prio (TREE_OPERAND (node, 0)) < op_prio (node))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
else
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
@@ -1729,7 +1758,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
case MAX_EXPR:
@@ -1737,13 +1766,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
case ABS_EXPR:
pp_string (buffer, "ABS_EXPR <");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
case RANGE_EXPR:
@@ -1759,15 +1788,15 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
op0 = TREE_OPERAND (node, 0);
if (type != TREE_TYPE (op0))
{
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, type, spc, flags, false);
pp_string (buffer, ") ");
}
if (op_prio (op0) < op_prio (node))
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, op0, spc, flags, false);
if (op_prio (op0) < op_prio (node))
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case VIEW_CONVERT_EXPR:
@@ -1775,7 +1804,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_TYPE (node), spc, flags, false);
pp_string (buffer, ">(");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case PAREN_EXPR:
@@ -1787,13 +1816,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case NON_LVALUE_EXPR:
pp_string (buffer, "NON_LVALUE_EXPR <");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
case SAVE_EXPR:
pp_string (buffer, "SAVE_EXPR <");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_character (buffer, '>');
+ pp_greater (buffer);
break;
case COMPLEX_EXPR:
@@ -1801,64 +1830,64 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case CONJ_EXPR:
pp_string (buffer, "CONJ_EXPR <");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case REALPART_EXPR:
pp_string (buffer, "REALPART_EXPR <");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case IMAGPART_EXPR:
pp_string (buffer, "IMAGPART_EXPR <");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case VA_ARG_EXPR:
pp_string (buffer, "VA_ARG_EXPR <");
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case TRY_FINALLY_EXPR:
case TRY_CATCH_EXPR:
pp_string (buffer, "try");
newline_and_indent (buffer, spc+2);
- pp_string (buffer, "{");
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc+4);
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc+4, flags, true);
newline_and_indent (buffer, spc+2);
- pp_string (buffer, "}");
+ pp_right_brace (buffer);
newline_and_indent (buffer, spc);
pp_string (buffer,
(TREE_CODE (node) == TRY_CATCH_EXPR) ? "catch" : "finally");
newline_and_indent (buffer, spc+2);
- pp_string (buffer, "{");
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc+4);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc+4, flags, true);
newline_and_indent (buffer, spc+2);
- pp_string (buffer, "}");
+ pp_right_brace (buffer);
is_expr = false;
break;
case CATCH_EXPR:
pp_string (buffer, "catch (");
dump_generic_node (buffer, CATCH_TYPES (node), spc+2, flags, false);
- pp_string (buffer, ")");
+ pp_right_paren (buffer);
newline_and_indent (buffer, spc+2);
- pp_string (buffer, "{");
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc+4);
dump_generic_node (buffer, CATCH_BODY (node), spc+4, flags, true);
newline_and_indent (buffer, spc+2);
- pp_string (buffer, "}");
+ pp_right_brace (buffer);
is_expr = false;
break;
@@ -1867,11 +1896,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, EH_FILTER_TYPES (node), spc+2, flags, false);
pp_string (buffer, ")>>>");
newline_and_indent (buffer, spc+2);
- pp_string (buffer, "{");
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc+4);
dump_generic_node (buffer, EH_FILTER_FAILURE (node), spc+4, flags, true);
newline_and_indent (buffer, spc+2);
- pp_string (buffer, "}");
+ pp_right_brace (buffer);
is_expr = false;
break;
@@ -1886,7 +1915,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
break;
}
dump_generic_node (buffer, op0, spc, flags, false);
- pp_character (buffer, ':');
+ pp_colon (buffer);
if (DECL_NONLOCAL (op0))
pp_string (buffer, " [non-local]");
break;
@@ -1896,11 +1925,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (!(flags & TDF_SLIM))
{
newline_and_indent (buffer, spc+2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc+4);
dump_generic_node (buffer, LOOP_EXPR_BODY (node), spc+4, flags, true);
newline_and_indent (buffer, spc+2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
is_expr = false;
break;
@@ -1938,11 +1967,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case SWITCH_EXPR:
pp_string (buffer, "switch (");
dump_generic_node (buffer, SWITCH_COND (node), spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
if (!(flags & TDF_SLIM))
{
newline_and_indent (buffer, spc+2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
if (SWITCH_BODY (node))
{
newline_and_indent (buffer, spc+4);
@@ -1970,7 +1999,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
}
}
newline_and_indent (buffer, spc+2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
is_expr = false;
break;
@@ -1995,18 +2024,18 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_string (buffer, "__asm__");
if (ASM_VOLATILE_P (node))
pp_string (buffer, " __volatile__");
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, ASM_STRING (node), spc, flags, false);
- pp_character (buffer, ':');
+ pp_colon (buffer);
dump_generic_node (buffer, ASM_OUTPUTS (node), spc, flags, false);
- pp_character (buffer, ':');
+ pp_colon (buffer);
dump_generic_node (buffer, ASM_INPUTS (node), spc, flags, false);
if (ASM_CLOBBERS (node))
{
- pp_character (buffer, ':');
+ pp_colon (buffer);
dump_generic_node (buffer, ASM_CLOBBERS (node), spc, flags, false);
}
- pp_string (buffer, ")");
+ pp_right_paren (buffer);
break;
case CASE_LABEL_EXPR:
@@ -2024,25 +2053,24 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
}
else
pp_string (buffer, "default");
- pp_character (buffer, ':');
+ pp_colon (buffer);
break;
case OBJ_TYPE_REF:
pp_string (buffer, "OBJ_TYPE_REF(");
dump_generic_node (buffer, OBJ_TYPE_REF_EXPR (node), spc, flags, false);
- pp_character (buffer, ';');
+ pp_semicolon (buffer);
dump_generic_node (buffer, OBJ_TYPE_REF_OBJECT (node), spc, flags, false);
- pp_character (buffer, '-');
- pp_character (buffer, '>');
+ pp_arrow (buffer);
dump_generic_node (buffer, OBJ_TYPE_REF_TOKEN (node), spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
break;
case SSA_NAME:
if (SSA_NAME_IDENTIFIER (node))
dump_generic_node (buffer, SSA_NAME_IDENTIFIER (node),
spc, flags, false);
- pp_string (buffer, "_");
+ pp_underscore (buffer);
pp_decimal_int (buffer, SSA_NAME_VERSION (node));
if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (node))
pp_string (buffer, "(ab)");
@@ -2055,7 +2083,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case ASSERT_EXPR:
@@ -2063,7 +2091,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, ASSERT_EXPR_VAR (node), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, ASSERT_EXPR_COND (node), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case SCEV_KNOWN:
@@ -2075,7 +2103,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
break;
case POLYNOMIAL_CHREC:
- pp_string (buffer, "{");
+ pp_left_brace (buffer);
dump_generic_node (buffer, CHREC_LEFT (node), spc, flags, false);
pp_string (buffer, ", +, ");
dump_generic_node (buffer, CHREC_RIGHT (node), spc, flags, false);
@@ -2091,7 +2119,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
pp_string (buffer, ", ");
dump_generic_node (buffer, TREE_OPERAND (node, 2), spc, flags, false);
- pp_string (buffer, ">");
+ pp_greater (buffer);
break;
case VEC_COND_EXPR:
@@ -2162,11 +2190,11 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (!(flags & TDF_SLIM) && OMP_BODY (node))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc + 4);
dump_generic_node (buffer, OMP_BODY (node), spc + 4, flags, false);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
is_expr = false;
break;
@@ -2178,6 +2206,13 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case OMP_FOR:
pp_string (buffer, "#pragma omp for");
+ goto dump_omp_loop;
+
+ case OMP_SIMD:
+ pp_string (buffer, "#pragma omp simd");
+ goto dump_omp_loop;
+
+ dump_omp_loop:
dump_omp_clauses (buffer, OMP_FOR_CLAUSES (node), spc, flags);
if (!(flags & TDF_SLIM))
@@ -2187,7 +2222,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (OMP_FOR_PRE_BODY (node))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
spc += 4;
newline_and_indent (buffer, spc);
dump_generic_node (buffer, OMP_FOR_PRE_BODY (node),
@@ -2207,24 +2242,24 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
pp_string (buffer, "; ");
dump_generic_node (buffer, TREE_VEC_ELT (OMP_FOR_INCR (node), i),
spc, flags, false);
- pp_string (buffer, ")");
+ pp_right_paren (buffer);
}
if (OMP_FOR_BODY (node))
{
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc + 4);
dump_generic_node (buffer, OMP_FOR_BODY (node), spc + 4, flags,
false);
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
spc -= 2 * TREE_VEC_LENGTH (OMP_FOR_INIT (node)) - 2;
if (OMP_FOR_PRE_BODY (node))
{
spc -= 4;
newline_and_indent (buffer, spc + 2);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
}
is_expr = false;
@@ -2252,10 +2287,10 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (OMP_CRITICAL_NAME (node))
{
pp_space (buffer);
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, OMP_CRITICAL_NAME (node), spc,
flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
goto dump_omp_body;
@@ -2264,7 +2299,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
newline_and_indent (buffer, spc + 2);
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
pp_space (buffer);
- pp_character (buffer, '=');
+ pp_equal (buffer);
pp_space (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
break;
@@ -2282,7 +2317,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
newline_and_indent (buffer, spc + 2);
dump_generic_node (buffer, TREE_OPERAND (node, 0), spc, flags, false);
pp_space (buffer);
- pp_character (buffer, '=');
+ pp_equal (buffer);
pp_space (buffer);
dump_generic_node (buffer, TREE_OPERAND (node, 1), spc, flags, false);
break;
@@ -2307,12 +2342,12 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
if (!(flags & TDF_SLIM) && TRANSACTION_EXPR_BODY (node))
{
newline_and_indent (buffer, spc);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
newline_and_indent (buffer, spc + 2);
dump_generic_node (buffer, TRANSACTION_EXPR_BODY (node),
spc + 2, flags, false);
newline_and_indent (buffer, spc);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
is_expr = false;
break;
@@ -2341,7 +2376,7 @@ dump_generic_node (pretty_printer *buffer, tree node, int spc, int flags,
case VEC_WIDEN_MULT_ODD_EXPR:
case VEC_WIDEN_LSHIFT_HI_EXPR:
case VEC_WIDEN_LSHIFT_LO_EXPR:
- pp_character (buffer, ' ');
+ pp_space (buffer);
for (str = tree_code_name [code]; *str; str++)
pp_character (buffer, TOUPPER (*str));
pp_string (buffer, " < ");
@@ -2474,9 +2509,9 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
{
pp_string (buffer, " __asm__ ");
- pp_character (buffer, '(');
+ pp_left_paren (buffer);
dump_generic_node (buffer, DECL_ASSEMBLER_NAME (t), spc, flags, false);
- pp_character (buffer, ')');
+ pp_right_paren (buffer);
}
/* The initial value of a function serves to determine whether the function
@@ -2488,7 +2523,7 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
if (DECL_INITIAL (t))
{
pp_space (buffer);
- pp_character (buffer, '=');
+ pp_equal (buffer);
pp_space (buffer);
dump_generic_node (buffer, DECL_INITIAL (t), spc, flags, false);
}
@@ -2498,10 +2533,10 @@ print_declaration (pretty_printer *buffer, tree t, int spc, int flags)
{
pp_string (buffer, " [value-expr: ");
dump_generic_node (buffer, DECL_VALUE_EXPR (t), spc, flags, false);
- pp_character (buffer, ']');
+ pp_right_bracket (buffer);
}
- pp_character (buffer, ';');
+ pp_semicolon (buffer);
}
@@ -2527,7 +2562,7 @@ print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
/* Print the contents of the structure. */
pp_newline (buffer);
INDENT (spc);
- pp_character (buffer, '{');
+ pp_left_brace (buffer);
pp_newline (buffer);
/* Print the fields of the structure. */
@@ -2552,7 +2587,7 @@ print_struct_decl (pretty_printer *buffer, const_tree node, int spc, int flags)
}
}
INDENT (spc);
- pp_character (buffer, '}');
+ pp_right_brace (buffer);
}
/* Return the priority of the operator CODE.
@@ -2936,7 +2971,7 @@ print_call_name (pretty_printer *buffer, tree node, int flags)
goto again;
case COND_EXPR:
- pp_string (buffer, "(");
+ pp_left_paren (buffer);
dump_generic_node (buffer, TREE_OPERAND (op0, 0), 0, flags, false);
pp_string (buffer, ") ? ");
dump_generic_node (buffer, TREE_OPERAND (op0, 1), 0, flags, false);
@@ -3060,7 +3095,7 @@ maybe_init_pretty_print (FILE *file)
{
if (!initialized)
{
- pp_construct (&buffer, /* prefix */NULL, /* line-width */0);
+ new (&buffer) pretty_printer ();
pp_needs_newline (&buffer) = true;
pp_translate_identifiers (&buffer) = false;
initialized = 1;
@@ -3113,7 +3148,7 @@ percent_K_format (text_info *text)
/* Print the identifier ID to PRETTY-PRINTER. */
void
-pp_base_tree_identifier (pretty_printer *pp, tree id)
+pp_tree_identifier (pretty_printer *pp, tree id)
{
if (pp_translate_identifiers (pp))
{
diff --git a/gcc/tree-pretty-print.h b/gcc/tree-pretty-print.h
index a868db4e5dd..7da8000d5b8 100644
--- a/gcc/tree-pretty-print.h
+++ b/gcc/tree-pretty-print.h
@@ -24,16 +24,13 @@ along with GCC; see the file COPYING3. If not see
#include "pretty-print.h"
-#define pp_tree_identifier(PP, T) \
- pp_base_tree_identifier (pp_base (PP), T)
-
#define pp_unsupported_tree(PP, T) \
- pp_verbatim (pp_base (PP), "#%qs not supported by %s#", \
+ pp_verbatim (PP, "#%qs not supported by %s#", \
tree_code_name[(int) TREE_CODE (T)], __FUNCTION__)
#define pp_ti_abstract_origin(TI) ((tree *) (TI)->x_data)
-extern void pp_base_tree_identifier (pretty_printer *, tree);
+extern void pp_tree_identifier (pretty_printer *, tree);
/* In tree-pretty-print.c */
extern void print_declaration (pretty_printer *, tree, int, int);
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index 9985b40a2a8..dd164b53a74 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -57,8 +57,8 @@ static GTY(()) tree ptr_void;
/* Do initialization work for the edge profiler. */
/* Add code:
- static gcov* __gcov_indirect_call_counters; // pointer to actual counter
- static void* __gcov_indirect_call_callee; // actual callee address
+ __thread gcov* __gcov_indirect_call_counters; // pointer to actual counter
+ __thread void* __gcov_indirect_call_callee; // actual callee address
*/
static void
init_ic_make_global_vars (void)
@@ -67,12 +67,28 @@ init_ic_make_global_vars (void)
ptr_void = build_pointer_type (void_type_node);
- ic_void_ptr_var
- = build_decl (UNKNOWN_LOCATION, VAR_DECL,
- get_identifier ("__gcov_indirect_call_callee"),
- ptr_void);
+ /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
+ if (flag_lto)
+ {
+ ic_void_ptr_var
+ = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ get_identifier ("__gcov_indirect_call_callee_ltopriv"),
+ ptr_void);
+ TREE_PUBLIC (ic_void_ptr_var) = 1;
+ DECL_COMMON (ic_void_ptr_var) = 1;
+ DECL_VISIBILITY (ic_void_ptr_var) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (ic_void_ptr_var) = true;
+ }
+ else
+ {
+ ic_void_ptr_var
+ = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ get_identifier ("__gcov_indirect_call_callee"),
+ ptr_void);
+ TREE_PUBLIC (ic_void_ptr_var) = 1;
+ DECL_EXTERNAL (ic_void_ptr_var) = 1;
+ }
TREE_STATIC (ic_void_ptr_var) = 1;
- TREE_PUBLIC (ic_void_ptr_var) = 0;
DECL_ARTIFICIAL (ic_void_ptr_var) = 1;
DECL_INITIAL (ic_void_ptr_var) = NULL;
if (targetm.have_tls)
@@ -82,12 +98,28 @@ init_ic_make_global_vars (void)
varpool_finalize_decl (ic_void_ptr_var);
gcov_type_ptr = build_pointer_type (get_gcov_type ());
- ic_gcov_type_ptr_var
- = build_decl (UNKNOWN_LOCATION, VAR_DECL,
- get_identifier ("__gcov_indirect_call_counters"),
- gcov_type_ptr);
+ /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
+ if (flag_lto)
+ {
+ ic_gcov_type_ptr_var
+ = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ get_identifier ("__gcov_indirect_call_counters_ltopriv"),
+ gcov_type_ptr);
+ TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
+ DECL_COMMON (ic_gcov_type_ptr_var) = 1;
+ DECL_VISIBILITY (ic_gcov_type_ptr_var) = VISIBILITY_HIDDEN;
+ DECL_VISIBILITY_SPECIFIED (ic_gcov_type_ptr_var) = true;
+ }
+ else
+ {
+ ic_gcov_type_ptr_var
+ = build_decl (UNKNOWN_LOCATION, VAR_DECL,
+ get_identifier ("__gcov_indirect_call_counters"),
+ gcov_type_ptr);
+ TREE_PUBLIC (ic_gcov_type_ptr_var) = 1;
+ DECL_EXTERNAL (ic_gcov_type_ptr_var) = 1;
+ }
TREE_STATIC (ic_gcov_type_ptr_var) = 1;
- TREE_PUBLIC (ic_gcov_type_ptr_var) = 0;
DECL_ARTIFICIAL (ic_gcov_type_ptr_var) = 1;
DECL_INITIAL (ic_gcov_type_ptr_var) = NULL;
if (targetm.have_tls)
@@ -155,15 +187,31 @@ gimple_init_edge_profiler (void)
init_ic_make_global_vars ();
- /* void (*) (gcov_type *, gcov_type, void *, void *) */
- ic_profiler_fn_type
- = build_function_type_list (void_type_node,
- gcov_type_ptr, gcov_type_node,
- ptr_void,
- ptr_void, NULL_TREE);
- tree_indirect_call_profiler_fn
- = build_fn_decl ("__gcov_indirect_call_profiler",
- ic_profiler_fn_type);
+ /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
+ if (flag_lto)
+ {
+ /* void (*) (gcov_type, void *) */
+ ic_profiler_fn_type
+ = build_function_type_list (void_type_node,
+ gcov_type_ptr, gcov_type_node,
+ ptr_void, ptr_void,
+ NULL_TREE);
+ tree_indirect_call_profiler_fn
+ = build_fn_decl ("__gcov_indirect_call_profiler",
+ ic_profiler_fn_type);
+ }
+ else
+ {
+ /* void (*) (gcov_type, void *) */
+ ic_profiler_fn_type
+ = build_function_type_list (void_type_node,
+ gcov_type_node,
+ ptr_void,
+ NULL_TREE);
+ tree_indirect_call_profiler_fn
+ = build_fn_decl ("__gcov_indirect_call_profiler_v2",
+ ic_profiler_fn_type);
+ }
TREE_NOTHROW (tree_indirect_call_profiler_fn) = 1;
DECL_ATTRIBUTES (tree_indirect_call_profiler_fn)
= tree_cons (get_identifier ("leaf"), NULL,
@@ -352,7 +400,7 @@ gimple_gen_ic_func_profiler (void)
struct cgraph_node * c_node = cgraph_get_node (current_function_decl);
gimple_stmt_iterator gsi;
gimple stmt1, stmt2;
- tree tree_uid, cur_func, counter_ptr, ptr_var, void0;
+ tree tree_uid, cur_func, void0;
if (cgraph_only_called_directly_p (c_node))
return;
@@ -361,27 +409,37 @@ gimple_gen_ic_func_profiler (void)
/* Insert code:
- stmt1: __gcov_indirect_call_profiler (__gcov_indirect_call_counters,
- current_function_funcdef_no,
- &current_function_decl,
- __gcov_indirect_call_callee);
+ stmt1: __gcov_indirect_call_profiler_v2 (profile_id,
+ &current_function_decl)
*/
- gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
+ gsi = gsi_after_labels (split_edge (single_succ_edge (ENTRY_BLOCK_PTR)));
cur_func = force_gimple_operand_gsi (&gsi,
build_addr (current_function_decl,
current_function_decl),
true, NULL_TREE,
true, GSI_SAME_STMT);
- counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
+ tree_uid = build_int_cst
+ (gcov_type_node, cgraph_get_node (current_function_decl)->profile_id);
+ /* Workaround for binutils bug 14342. Once it is fixed, remove lto path. */
+ if (flag_lto)
+ {
+ tree counter_ptr, ptr_var;
+ counter_ptr = force_gimple_operand_gsi (&gsi, ic_gcov_type_ptr_var,
+ true, NULL_TREE, true,
+ GSI_SAME_STMT);
+ ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
true, NULL_TREE, true,
GSI_SAME_STMT);
- ptr_var = force_gimple_operand_gsi (&gsi, ic_void_ptr_var,
- true, NULL_TREE, true,
- GSI_SAME_STMT);
- tree_uid = build_int_cst (gcov_type_node, current_function_funcdef_no);
- stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
- counter_ptr, tree_uid, cur_func, ptr_var);
+
+ stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 4,
+ counter_ptr, tree_uid, cur_func, ptr_var);
+ }
+ else
+ {
+ stmt1 = gimple_build_call (tree_indirect_call_profiler_fn, 2,
+ tree_uid, cur_func);
+ }
gsi_insert_before (&gsi, stmt1, GSI_SAME_STMT);
/* Set __gcov_indirect_call_callee to 0,
@@ -461,7 +519,7 @@ tree_profiling (void)
cgraphunit.c:ipa_passes(). */
gcc_assert (cgraph_state == CGRAPH_STATE_IPA_SSA);
- init_node_map();
+ init_node_map (true);
FOR_EACH_DEFINED_FUNCTION (node)
{
@@ -540,6 +598,8 @@ tree_profiling (void)
}
}
+ /* re-merge split blocks. */
+ cleanup_tree_cfg ();
update_ssa (TODO_update_ssa);
rebuild_cgraph_edges ();
@@ -561,24 +621,42 @@ gate_tree_profile_ipa (void)
|| profile_arc_flag));
}
-struct simple_ipa_opt_pass pass_ipa_tree_profile =
+namespace {
+
+const pass_data pass_data_ipa_tree_profile =
{
- {
- SIMPLE_IPA_PASS,
- "profile", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tree_profile_ipa, /* gate */
- tree_profiling, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_PROFILE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ SIMPLE_IPA_PASS, /* type */
+ "profile", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_PROFILE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_ipa_tree_profile : public simple_ipa_opt_pass
+{
+public:
+ pass_ipa_tree_profile(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_ipa_tree_profile, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_profile_ipa (); }
+ unsigned int execute () { return tree_profiling (); }
+
+}; // class pass_ipa_tree_profile
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_tree_profile (gcc::context *ctxt)
+{
+ return new pass_ipa_tree_profile (ctxt);
+}
+
#include "gt-tree-profile.h"
diff --git a/gcc/tree-scalar-evolution.c b/gcc/tree-scalar-evolution.c
index c7e9d4b46cd..bed621fe052 100644
--- a/gcc/tree-scalar-evolution.c
+++ b/gcc/tree-scalar-evolution.c
@@ -2252,6 +2252,7 @@ instantiate_scev_name (basic_block instantiate_below,
else if (res != chrec_dont_know)
{
if (inner_loop
+ && def_bb->loop_father != inner_loop
&& !flow_loop_nested_p (def_bb->loop_father, inner_loop))
/* ??? We could try to compute the overall effect of the loop here. */
res = chrec_dont_know;
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 7e950aeecdf..7ed166857e5 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -91,6 +91,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree-inline.h"
#include "gimple-pretty-print.h"
#include "ipa-inline.h"
+#include "ipa-utils.h"
/* Enumeration of all aggregate reductions we can do. */
enum sra_mode { SRA_MODE_EARLY_IPA, /* early call regularization */
@@ -1256,8 +1257,7 @@ scan_function (void)
if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL
&& DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS)
encountered_apply_args = true;
- if (cgraph_get_node (dest)
- == cgraph_get_node (current_function_decl))
+ if (recursive_call_p (current_function_decl, dest))
{
encountered_recursive_call = true;
if (!callsite_has_enough_arguments_p (stmt))
@@ -1466,6 +1466,7 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
{
tree prev_base = base;
tree off;
+ tree mem_ref;
HOST_WIDE_INT base_offset;
unsigned HOST_WIDE_INT misalign;
unsigned int align;
@@ -1516,7 +1517,12 @@ build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset,
if (align < TYPE_ALIGN (exp_type))
exp_type = build_aligned_type (exp_type, align);
- return fold_build2_loc (loc, MEM_REF, exp_type, base, off);
+ mem_ref = fold_build2_loc (loc, MEM_REF, exp_type, base, off);
+ if (TREE_THIS_VOLATILE (prev_base))
+ TREE_THIS_VOLATILE (mem_ref) = 1;
+ if (TREE_SIDE_EFFECTS (prev_base))
+ TREE_SIDE_EFFECTS (mem_ref) = 1;
+ return mem_ref;
}
/* Construct a memory reference to a part of an aggregate BASE at the given
@@ -3442,48 +3448,82 @@ gate_intra_sra (void)
}
-struct gimple_opt_pass pass_sra_early =
+namespace {
+
+const pass_data pass_data_sra_early =
{
- {
- GIMPLE_PASS,
- "esra", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_intra_sra, /* gate */
- early_intra_sra, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SRA, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "esra", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SRA, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
};
-struct gimple_opt_pass pass_sra =
+class pass_sra_early : public gimple_opt_pass
{
- {
- GIMPLE_PASS,
- "sra", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_intra_sra, /* gate */
- late_intra_sra, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SRA, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- TODO_update_address_taken, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa /* todo_flags_finish */
- }
+public:
+ pass_sra_early(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_sra_early, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_intra_sra (); }
+ unsigned int execute () { return early_intra_sra (); }
+
+}; // class pass_sra_early
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_sra_early (gcc::context *ctxt)
+{
+ return new pass_sra_early (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_sra =
+{
+ GIMPLE_PASS, /* type */
+ "sra", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SRA, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ TODO_update_address_taken, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
};
+class pass_sra : public gimple_opt_pass
+{
+public:
+ pass_sra(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_sra, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_intra_sra (); }
+ unsigned int execute () { return late_intra_sra (); }
+
+}; // class pass_sra
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_sra (gcc::context *ctxt)
+{
+ return new pass_sra (ctxt);
+}
+
/* Return true iff PARM (which must be a parm_decl) is an unused scalar
parameter. */
@@ -4866,6 +4906,16 @@ modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
return cfg_changed;
}
+/* If NODE has a caller, return true. */
+
+static bool
+has_caller_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
+{
+ if (node->callers)
+ return true;
+ return false;
+}
+
/* Return false the function is apparently unsuitable for IPA-SRA based on it's
attributes, return true otherwise. NODE is the cgraph node of the current
function. */
@@ -4909,7 +4959,7 @@ ipa_sra_preliminary_function_checks (struct cgraph_node *node)
return false;
}
- if (!node->callers)
+ if (!cgraph_for_node_and_aliases (node, has_caller_p, NULL, true))
{
if (dump_file)
fprintf (dump_file,
@@ -5018,22 +5068,40 @@ ipa_early_sra_gate (void)
return flag_ipa_sra && dbg_cnt (eipa_sra);
}
-struct gimple_opt_pass pass_early_ipa_sra =
+namespace {
+
+const pass_data pass_data_early_ipa_sra =
{
- {
- GIMPLE_PASS,
- "eipa_sra", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- ipa_early_sra_gate, /* gate */
- ipa_early_sra, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_SRA, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_dump_symtab /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "eipa_sra", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_SRA, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_dump_symtab, /* todo_flags_finish */
};
+
+class pass_early_ipa_sra : public gimple_opt_pass
+{
+public:
+ pass_early_ipa_sra(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_early_ipa_sra, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return ipa_early_sra_gate (); }
+ unsigned int execute () { return ipa_early_sra (); }
+
+}; // class pass_early_ipa_sra
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_early_ipa_sra (gcc::context *ctxt)
+{
+ return new pass_early_ipa_sra (ctxt);
+}
diff --git a/gcc/tree-ssa-ccp.c b/gcc/tree-ssa-ccp.c
index 1bc4c2fb7b5..3ba321d6181 100644
--- a/gcc/tree-ssa-ccp.c
+++ b/gcc/tree-ssa-ccp.c
@@ -258,12 +258,7 @@ get_default_value (tree var)
val.mask = double_int_minus_one;
}
}
- else if (is_gimple_assign (stmt)
- /* Value-returning GIMPLE_CALL statements assign to
- a variable, and are treated similarly to GIMPLE_ASSIGN. */
- || (is_gimple_call (stmt)
- && gimple_call_lhs (stmt) != NULL_TREE)
- || gimple_code (stmt) == GIMPLE_PHI)
+ else if (is_gimple_assign (stmt))
{
tree cst;
if (gimple_assign_single_p (stmt)
@@ -274,9 +269,19 @@ get_default_value (tree var)
val.value = cst;
}
else
- /* Any other variable defined by an assignment or a PHI node
- is considered UNDEFINED. */
- val.lattice_val = UNDEFINED;
+ {
+ /* Any other variable defined by an assignment is considered
+ UNDEFINED. */
+ val.lattice_val = UNDEFINED;
+ }
+ }
+ else if ((is_gimple_call (stmt)
+ && gimple_call_lhs (stmt) != NULL_TREE)
+ || gimple_code (stmt) == GIMPLE_PHI)
+ {
+ /* A variable defined by a call or a PHI node is considered
+ UNDEFINED. */
+ val.lattice_val = UNDEFINED;
}
else
{
@@ -626,6 +631,22 @@ likely_value (gimple stmt)
if (has_constant_operand)
all_undefined_operands = false;
+ if (has_undefined_operand
+ && code == GIMPLE_CALL
+ && gimple_call_internal_p (stmt))
+ switch (gimple_call_internal_fn (stmt))
+ {
+ /* These 3 builtins use the first argument just as a magic
+ way how to find out a decl uid. */
+ case IFN_GOMP_SIMD_LANE:
+ case IFN_GOMP_SIMD_VF:
+ case IFN_GOMP_SIMD_LAST_LANE:
+ has_undefined_operand = false;
+ break;
+ default:
+ break;
+ }
+
/* If the operation combines operands like COMPLEX_EXPR make sure to
not mark the result UNDEFINED if only one part of the result is
undefined. */
@@ -2121,28 +2142,46 @@ gate_ccp (void)
}
-struct gimple_opt_pass pass_ccp =
+namespace {
+
+const pass_data pass_data_ccp =
{
- {
- GIMPLE_PASS,
- "ccp", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_ccp, /* gate */
- do_ssa_ccp, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_CCP, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_update_address_taken
- | TODO_verify_stmts /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "ccp", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_CCP, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa | TODO_update_address_taken
+ | TODO_verify_stmts ), /* todo_flags_finish */
};
+class pass_ccp : public gimple_opt_pass
+{
+public:
+ pass_ccp(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_ccp, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_ccp (ctxt_); }
+ bool gate () { return gate_ccp (); }
+ unsigned int execute () { return do_ssa_ccp (); }
+
+}; // class pass_ccp
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_ccp (gcc::context *ctxt)
+{
+ return new pass_ccp (ctxt);
+}
+
/* Try to optimize out __builtin_stack_restore. Optimize it out
@@ -2521,23 +2560,40 @@ execute_fold_all_builtins (void)
}
-struct gimple_opt_pass pass_fold_builtins =
+namespace {
+
+const pass_data pass_data_fold_builtins =
{
- {
- GIMPLE_PASS,
- "fab", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_fold_all_builtins, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_update_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "fab", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa | TODO_update_ssa ), /* todo_flags_finish */
};
+
+class pass_fold_builtins : public gimple_opt_pass
+{
+public:
+ pass_fold_builtins(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_fold_builtins, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_fold_builtins (ctxt_); }
+ unsigned int execute () { return execute_fold_all_builtins (); }
+
+}; // class pass_fold_builtins
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_fold_builtins (gcc::context *ctxt)
+{
+ return new pass_fold_builtins (ctxt);
+}
diff --git a/gcc/tree-ssa-copy.c b/gcc/tree-ssa-copy.c
index 625f46e1942..9bc455c61a7 100644
--- a/gcc/tree-ssa-copy.c
+++ b/gcc/tree-ssa-copy.c
@@ -60,7 +60,13 @@ may_propagate_copy (tree dest, tree orig)
/* If ORIG flows in from an abnormal edge, it cannot be propagated. */
if (TREE_CODE (orig) == SSA_NAME
- && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig))
+ && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (orig)
+ /* If it is the default definition and an automatic variable then
+ we can though and it is important that we do to avoid
+ uninitialized regular copies. */
+ && !(SSA_NAME_IS_DEFAULT_DEF (orig)
+ && (SSA_NAME_VAR (orig) == NULL_TREE
+ || TREE_CODE (SSA_NAME_VAR (orig)) == VAR_DECL)))
return false;
/* If DEST is an SSA_NAME that flows from an abnormal edge, then it
@@ -823,24 +829,42 @@ gate_copy_prop (void)
return flag_tree_copy_prop != 0;
}
-struct gimple_opt_pass pass_copy_prop =
+namespace {
+
+const pass_data pass_data_copy_prop =
{
- {
- GIMPLE_PASS,
- "copyprop", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_copy_prop, /* gate */
- execute_copy_prop, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_COPY_PROP, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_cleanup_cfg
- | TODO_verify_ssa
- | TODO_update_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "copyprop", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_COPY_PROP, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_cleanup_cfg | TODO_verify_ssa
+ | TODO_update_ssa ), /* todo_flags_finish */
};
+
+class pass_copy_prop : public gimple_opt_pass
+{
+public:
+ pass_copy_prop(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_copy_prop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_copy_prop (ctxt_); }
+ bool gate () { return gate_copy_prop (); }
+ unsigned int execute () { return execute_copy_prop (); }
+
+}; // class pass_copy_prop
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_copy_prop (gcc::context *ctxt)
+{
+ return new pass_copy_prop (ctxt);
+}
diff --git a/gcc/tree-ssa-copyrename.c b/gcc/tree-ssa-copyrename.c
index 6f49b7ecf5a..990598ef29b 100644
--- a/gcc/tree-ssa-copyrename.c
+++ b/gcc/tree-ssa-copyrename.c
@@ -435,22 +435,41 @@ gate_copyrename (void)
return flag_tree_copyrename != 0;
}
-struct gimple_opt_pass pass_rename_ssa_copies =
+namespace {
+
+const pass_data pass_data_rename_ssa_copies =
{
- {
- GIMPLE_PASS,
- "copyrename", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_copyrename, /* gate */
- rename_ssa_copies, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_COPY_RENAME, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "copyrename", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_COPY_RENAME, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_rename_ssa_copies : public gimple_opt_pass
+{
+public:
+ pass_rename_ssa_copies(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_rename_ssa_copies, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_rename_ssa_copies (ctxt_); }
+ bool gate () { return gate_copyrename (); }
+ unsigned int execute () { return rename_ssa_copies (); }
+
+}; // class pass_rename_ssa_copies
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_rename_ssa_copies (gcc::context *ctxt)
+{
+ return new pass_rename_ssa_copies (ctxt);
+}
diff --git a/gcc/tree-ssa-dce.c b/gcc/tree-ssa-dce.c
index fd1bc69be56..ecc8c6f2264 100644
--- a/gcc/tree-ssa-dce.c
+++ b/gcc/tree-ssa-dce.c
@@ -87,7 +87,7 @@ static sbitmap bb_contains_live_stmts;
use a bitmap for each block recording its edges. An array holds the
bitmap. The Ith bit in the bitmap is set if that block is dependent
on the Ith edge. */
-static bitmap *control_dependence_map;
+static control_dependences *cd;
/* Vector indicating that a basic block has already had all the edges
processed that it is control dependent on. */
@@ -100,96 +100,6 @@ static sbitmap visited_control_parents;
to be recomputed. */
static bool cfg_altered;
-/* Execute code that follows the macro for each edge (given number
- EDGE_NUMBER within the CODE) for which the block with index N is
- control dependent. */
-#define EXECUTE_IF_CONTROL_DEPENDENT(BI, N, EDGE_NUMBER) \
- EXECUTE_IF_SET_IN_BITMAP (control_dependence_map[(N)], 0, \
- (EDGE_NUMBER), (BI))
-
-
-/* Indicate block BB is control dependent on an edge with index EDGE_INDEX. */
-static inline void
-set_control_dependence_map_bit (basic_block bb, int edge_index)
-{
- if (bb == ENTRY_BLOCK_PTR)
- return;
- gcc_assert (bb != EXIT_BLOCK_PTR);
- bitmap_set_bit (control_dependence_map[bb->index], edge_index);
-}
-
-/* Clear all control dependences for block BB. */
-static inline void
-clear_control_dependence_bitmap (basic_block bb)
-{
- bitmap_clear (control_dependence_map[bb->index]);
-}
-
-
-/* Find the immediate postdominator PDOM of the specified basic block BLOCK.
- This function is necessary because some blocks have negative numbers. */
-
-static inline basic_block
-find_pdom (basic_block block)
-{
- gcc_assert (block != ENTRY_BLOCK_PTR);
-
- if (block == EXIT_BLOCK_PTR)
- return EXIT_BLOCK_PTR;
- else
- {
- basic_block bb = get_immediate_dominator (CDI_POST_DOMINATORS, block);
- if (! bb)
- return EXIT_BLOCK_PTR;
- return bb;
- }
-}
-
-
-/* Determine all blocks' control dependences on the given edge with edge_list
- EL index EDGE_INDEX, ala Morgan, Section 3.6. */
-
-static void
-find_control_dependence (struct edge_list *el, int edge_index)
-{
- basic_block current_block;
- basic_block ending_block;
-
- gcc_assert (INDEX_EDGE_PRED_BB (el, edge_index) != EXIT_BLOCK_PTR);
-
- if (INDEX_EDGE_PRED_BB (el, edge_index) == ENTRY_BLOCK_PTR)
- ending_block = single_succ (ENTRY_BLOCK_PTR);
- else
- ending_block = find_pdom (INDEX_EDGE_PRED_BB (el, edge_index));
-
- for (current_block = INDEX_EDGE_SUCC_BB (el, edge_index);
- current_block != ending_block && current_block != EXIT_BLOCK_PTR;
- current_block = find_pdom (current_block))
- {
- edge e = INDEX_EDGE (el, edge_index);
-
- /* For abnormal edges, we don't make current_block control
- dependent because instructions that throw are always necessary
- anyway. */
- if (e->flags & EDGE_ABNORMAL)
- continue;
-
- set_control_dependence_map_bit (current_block, edge_index);
- }
-}
-
-
-/* Record all blocks' control dependences on all edges in the edge
- list EL, ala Morgan, Section 3.6. */
-
-static void
-find_all_control_dependences (struct edge_list *el)
-{
- int i;
-
- for (i = 0; i < NUM_EDGES (el); ++i)
- find_control_dependence (el, i);
-}
/* If STMT is not already marked necessary, mark it, and add it to the
worklist if ADD_TO_WORKLIST is true. */
@@ -400,8 +310,7 @@ mark_last_stmt_necessary (basic_block bb)
When IGNORE_SELF is true, ignore BB in the list of control dependences. */
static void
-mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el,
- bool ignore_self)
+mark_control_dependent_edges_necessary (basic_block bb, bool ignore_self)
{
bitmap_iterator bi;
unsigned edge_number;
@@ -412,9 +321,10 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el,
if (bb == ENTRY_BLOCK_PTR)
return;
- EXECUTE_IF_CONTROL_DEPENDENT (bi, bb->index, edge_number)
+ EXECUTE_IF_SET_IN_BITMAP (cd->get_edges_dependent_on (bb->index),
+ 0, edge_number, bi)
{
- basic_block cd_bb = INDEX_EDGE_PRED_BB (el, edge_number);
+ basic_block cd_bb = cd->get_edge (edge_number)->src;
if (ignore_self && cd_bb == bb)
{
@@ -439,7 +349,7 @@ mark_control_dependent_edges_necessary (basic_block bb, struct edge_list *el,
dependence analysis. */
static void
-find_obviously_necessary_stmts (struct edge_list *el)
+find_obviously_necessary_stmts (bool aggressive)
{
basic_block bb;
gimple_stmt_iterator gsi;
@@ -461,7 +371,7 @@ find_obviously_necessary_stmts (struct edge_list *el)
{
stmt = gsi_stmt (gsi);
gimple_set_plf (stmt, STMT_NECESSARY, false);
- mark_stmt_if_obviously_necessary (stmt, el != NULL);
+ mark_stmt_if_obviously_necessary (stmt, aggressive);
}
}
@@ -472,7 +382,7 @@ find_obviously_necessary_stmts (struct edge_list *el)
return;
/* Prevent the empty possibly infinite loops from being removed. */
- if (el)
+ if (aggressive)
{
loop_iterator li;
struct loop *loop;
@@ -488,7 +398,7 @@ find_obviously_necessary_stmts (struct edge_list *el)
if (dump_file)
fprintf (dump_file, "Marking back edge of irreducible loop %i->%i\n",
e->src->index, e->dest->index);
- mark_control_dependent_edges_necessary (e->dest, el, false);
+ mark_control_dependent_edges_necessary (e->dest, false);
}
}
@@ -497,7 +407,7 @@ find_obviously_necessary_stmts (struct edge_list *el)
{
if (dump_file)
fprintf (dump_file, "can not prove finiteness of loop %i\n", loop->num);
- mark_control_dependent_edges_necessary (loop->latch, el, false);
+ mark_control_dependent_edges_necessary (loop->latch, false);
}
scev_finalize ();
}
@@ -574,6 +484,11 @@ mark_aliased_reaching_defs_necessary_1 (ao_ref *ref, tree vdef, void *data)
in the references (gcc.c-torture/execute/pr42142.c).
The simplest way is to check if the kill dominates
the use. */
+ /* But when both are in the same block we cannot
+ easily tell whether we came from a backedge
+ unless we decide to compute stmt UIDs
+ (see PR58246). */
+ && (basic_block) data != gimple_bb (def_stmt)
&& dominated_by_p (CDI_DOMINATORS, (basic_block) data,
gimple_bb (def_stmt))
&& operand_equal_p (ref->ref, lhs, 0))
@@ -685,10 +600,9 @@ degenerate_phi_p (gimple phi)
In conservative mode, EL is NULL. */
static void
-propagate_necessity (struct edge_list *el)
+propagate_necessity (bool aggressive)
{
gimple stmt;
- bool aggressive = (el ? true : false);
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, "\nProcessing worklist:\n");
@@ -713,7 +627,7 @@ propagate_necessity (struct edge_list *el)
basic_block bb = gimple_bb (stmt);
if (bb != ENTRY_BLOCK_PTR
&& !bitmap_bit_p (visited_control_parents, bb->index))
- mark_control_dependent_edges_necessary (bb, el, false);
+ mark_control_dependent_edges_necessary (bb, false);
}
if (gimple_code (stmt) == GIMPLE_PHI
@@ -820,7 +734,7 @@ propagate_necessity (struct edge_list *el)
else if (arg_bb != ENTRY_BLOCK_PTR
&& !bitmap_bit_p (visited_control_parents,
arg_bb->index))
- mark_control_dependent_edges_necessary (arg_bb, el, true);
+ mark_control_dependent_edges_necessary (arg_bb, true);
}
}
}
@@ -1481,12 +1395,6 @@ tree_dce_init (bool aggressive)
if (aggressive)
{
- int i;
-
- control_dependence_map = XNEWVEC (bitmap, last_basic_block);
- for (i = 0; i < last_basic_block; ++i)
- control_dependence_map[i] = BITMAP_ALLOC (NULL);
-
last_stmt_necessary = sbitmap_alloc (last_basic_block);
bitmap_clear (last_stmt_necessary);
bb_contains_live_stmts = sbitmap_alloc (last_basic_block);
@@ -1507,12 +1415,7 @@ tree_dce_done (bool aggressive)
{
if (aggressive)
{
- int i;
-
- for (i = 0; i < last_basic_block; ++i)
- BITMAP_FREE (control_dependence_map[i]);
- free (control_dependence_map);
-
+ delete cd;
sbitmap_free (visited_control_parents);
sbitmap_free (last_stmt_necessary);
sbitmap_free (bb_contains_live_stmts);
@@ -1541,7 +1444,6 @@ tree_dce_done (bool aggressive)
static unsigned int
perform_tree_ssa_dce (bool aggressive)
{
- struct edge_list *el = NULL;
bool something_changed = 0;
calculate_dominance_info (CDI_DOMINATORS);
@@ -1558,11 +1460,8 @@ perform_tree_ssa_dce (bool aggressive)
if (aggressive)
{
/* Compute control dependence. */
- timevar_push (TV_CONTROL_DEPENDENCES);
calculate_dominance_info (CDI_POST_DOMINATORS);
- el = create_edge_list ();
- find_all_control_dependences (el);
- timevar_pop (TV_CONTROL_DEPENDENCES);
+ cd = new control_dependences (create_edge_list ());
visited_control_parents = sbitmap_alloc (last_basic_block);
bitmap_clear (visited_control_parents);
@@ -1570,7 +1469,7 @@ perform_tree_ssa_dce (bool aggressive)
mark_dfs_back_edges ();
}
- find_obviously_necessary_stmts (el);
+ find_obviously_necessary_stmts (aggressive);
if (aggressive)
loop_optimizer_finalize ();
@@ -1580,7 +1479,7 @@ perform_tree_ssa_dce (bool aggressive)
nr_walks = 0;
chain_ovfl = false;
visited = BITMAP_ALLOC (NULL);
- propagate_necessity (el);
+ propagate_necessity (aggressive);
BITMAP_FREE (visited);
something_changed |= eliminate_unnecessary_stmts ();
@@ -1604,8 +1503,6 @@ perform_tree_ssa_dce (bool aggressive)
tree_dce_done (aggressive);
- free_edge_list (el);
-
if (something_changed)
return TODO_update_ssa | TODO_cleanup_cfg;
return 0;
@@ -1643,63 +1540,119 @@ gate_dce (void)
return flag_tree_dce != 0;
}
-struct gimple_opt_pass pass_dce =
+namespace {
+
+const pass_data pass_data_dce =
{
- {
- GIMPLE_PASS,
- "dce", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dce, /* gate */
- tree_ssa_dce, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_DCE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "dce", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_DCE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
-struct gimple_opt_pass pass_dce_loop =
+class pass_dce : public gimple_opt_pass
{
- {
- GIMPLE_PASS,
- "dceloop", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dce, /* gate */
- tree_ssa_dce_loop, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_DCE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+public:
+ pass_dce(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_dce, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_dce (ctxt_); }
+ bool gate () { return gate_dce (); }
+ unsigned int execute () { return tree_ssa_dce (); }
+
+}; // class pass_dce
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_dce (gcc::context *ctxt)
+{
+ return new pass_dce (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_dce_loop =
+{
+ GIMPLE_PASS, /* type */
+ "dceloop", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_DCE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
-struct gimple_opt_pass pass_cd_dce =
+class pass_dce_loop : public gimple_opt_pass
+{
+public:
+ pass_dce_loop(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_dce_loop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_dce_loop (ctxt_); }
+ bool gate () { return gate_dce (); }
+ unsigned int execute () { return tree_ssa_dce_loop (); }
+
+}; // class pass_dce_loop
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_dce_loop (gcc::context *ctxt)
+{
+ return new pass_dce_loop (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_cd_dce =
{
- {
- GIMPLE_PASS,
- "cddce", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dce, /* gate */
- tree_ssa_cd_dce, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_CD_DCE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_verify_flow /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "cddce", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_CD_DCE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_cd_dce : public gimple_opt_pass
+{
+public:
+ pass_cd_dce(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_cd_dce, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_cd_dce (ctxt_); }
+ bool gate () { return gate_dce (); }
+ unsigned int execute () { return tree_ssa_cd_dce (); }
+
+}; // class pass_cd_dce
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_cd_dce (gcc::context *ctxt)
+{
+ return new pass_cd_dce (ctxt);
+}
diff --git a/gcc/tree-ssa-dom.c b/gcc/tree-ssa-dom.c
index 83ca27a0bf4..f999a648e26 100644
--- a/gcc/tree-ssa-dom.c
+++ b/gcc/tree-ssa-dom.c
@@ -919,29 +919,47 @@ gate_dominator (void)
return flag_tree_dom != 0;
}
-struct gimple_opt_pass pass_dominator =
-{
- {
- GIMPLE_PASS,
- "dom", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dominator, /* gate */
- tree_ssa_dominator_optimize, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_cleanup_cfg
- | TODO_update_ssa
+namespace {
+
+const pass_data pass_data_dominator =
+{
+ GIMPLE_PASS, /* type */
+ "dom", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SSA_DOMINATOR_OPTS, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_cleanup_cfg | TODO_update_ssa
| TODO_verify_ssa
- | TODO_verify_flow /* todo_flags_finish */
- }
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+class pass_dominator : public gimple_opt_pass
+{
+public:
+ pass_dominator(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_dominator, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_dominator (ctxt_); }
+ bool gate () { return gate_dominator (); }
+ unsigned int execute () { return tree_ssa_dominator_optimize (); }
+
+}; // class pass_dominator
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_dominator (gcc::context *ctxt)
+{
+ return new pass_dominator (ctxt);
+}
+
/* Given a conditional statement CONDSTMT, convert the
condition to a canonical form. */
@@ -1624,6 +1642,28 @@ cprop_into_successor_phis (basic_block bb)
if (gsi_end_p (gsi))
continue;
+ /* We may have an equivalence associated with this edge. While
+ we can not propagate it into non-dominated blocks, we can
+ propagate them into PHIs in non-dominated blocks. */
+
+ /* Push the unwind marker so we can reset the const and copies
+ table back to its original state after processing this edge. */
+ const_and_copies_stack.safe_push (NULL_TREE);
+
+ /* Extract and record any simple NAME = VALUE equivalences.
+
+ Don't bother with [01] = COND equivalences, they're not useful
+ here. */
+ struct edge_info *edge_info = (struct edge_info *) e->aux;
+ if (edge_info)
+ {
+ tree lhs = edge_info->lhs;
+ tree rhs = edge_info->rhs;
+
+ if (lhs && TREE_CODE (lhs) == SSA_NAME)
+ record_const_or_copy (lhs, rhs);
+ }
+
indx = e->dest_idx;
for ( ; !gsi_end_p (gsi); gsi_next (&gsi))
{
@@ -1649,6 +1689,8 @@ cprop_into_successor_phis (basic_block bb)
&& may_propagate_copy (orig_val, new_val))
propagate_value (orig_p, new_val);
}
+
+ restore_vars_to_original_value ();
}
}
@@ -3094,25 +3136,43 @@ eliminate_degenerate_phis (void)
return 0;
}
-struct gimple_opt_pass pass_phi_only_cprop =
-{
- {
- GIMPLE_PASS,
- "phicprop", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dominator, /* gate */
- eliminate_degenerate_phis, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_PHI_CPROP, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_cleanup_cfg
- | TODO_verify_ssa
+namespace {
+
+const pass_data pass_data_phi_only_cprop =
+{
+ GIMPLE_PASS, /* type */
+ "phicprop", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_PHI_CPROP, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_cleanup_cfg | TODO_verify_ssa
| TODO_verify_stmts
- | TODO_update_ssa /* todo_flags_finish */
- }
+ | TODO_update_ssa ), /* todo_flags_finish */
};
+
+class pass_phi_only_cprop : public gimple_opt_pass
+{
+public:
+ pass_phi_only_cprop(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_phi_only_cprop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_phi_only_cprop (ctxt_); }
+ bool gate () { return gate_dominator (); }
+ unsigned int execute () { return eliminate_degenerate_phis (); }
+
+}; // class pass_phi_only_cprop
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_phi_only_cprop (gcc::context *ctxt)
+{
+ return new pass_phi_only_cprop (ctxt);
+}
diff --git a/gcc/tree-ssa-dse.c b/gcc/tree-ssa-dse.c
index 39f47abd83b..65787582a28 100644
--- a/gcc/tree-ssa-dse.c
+++ b/gcc/tree-ssa-dse.c
@@ -366,22 +366,41 @@ gate_dse (void)
return flag_tree_dse != 0;
}
-struct gimple_opt_pass pass_dse =
+namespace {
+
+const pass_data pass_data_dse =
{
- {
- GIMPLE_PASS,
- "dse", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_dse, /* gate */
- tree_ssa_dse, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_DSE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "dse", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_DSE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_dse : public gimple_opt_pass
+{
+public:
+ pass_dse(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_dse, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_dse (ctxt_); }
+ bool gate () { return gate_dse (); }
+ unsigned int execute () { return tree_ssa_dse (); }
+
+}; // class pass_dse
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_dse (gcc::context *ctxt)
+{
+ return new pass_dse (ctxt);
+}
diff --git a/gcc/tree-ssa-forwprop.c b/gcc/tree-ssa-forwprop.c
index df192952a1d..c3e0fac0775 100644
--- a/gcc/tree-ssa-forwprop.c
+++ b/gcc/tree-ssa-forwprop.c
@@ -3548,23 +3548,41 @@ gate_forwprop (void)
return flag_tree_forwprop;
}
-struct gimple_opt_pass pass_forwprop =
+namespace {
+
+const pass_data pass_data_forwprop =
{
- {
- GIMPLE_PASS,
- "forwprop", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_forwprop, /* gate */
- ssa_forward_propagate_and_combine, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_FORWPROP, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "forwprop", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_FORWPROP, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
};
+
+class pass_forwprop : public gimple_opt_pass
+{
+public:
+ pass_forwprop(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_forwprop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_forwprop (ctxt_); }
+ bool gate () { return gate_forwprop (); }
+ unsigned int execute () { return ssa_forward_propagate_and_combine (); }
+
+}; // class pass_forwprop
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_forwprop (gcc::context *ctxt)
+{
+ return new pass_forwprop (ctxt);
+}
diff --git a/gcc/tree-ssa-ifcombine.c b/gcc/tree-ssa-ifcombine.c
index 9598eb81a45..984a7634ef6 100644
--- a/gcc/tree-ssa-ifcombine.c
+++ b/gcc/tree-ssa-ifcombine.c
@@ -648,23 +648,40 @@ gate_ifcombine (void)
return 1;
}
-struct gimple_opt_pass pass_tree_ifcombine =
+namespace {
+
+const pass_data pass_data_tree_ifcombine =
{
- {
- GIMPLE_PASS,
- "ifcombine", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_ifcombine, /* gate */
- tree_ssa_ifcombine, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_IFCOMBINE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "ifcombine", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_IFCOMBINE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
};
+
+class pass_tree_ifcombine : public gimple_opt_pass
+{
+public:
+ pass_tree_ifcombine(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tree_ifcombine, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_ifcombine (); }
+ unsigned int execute () { return tree_ssa_ifcombine (); }
+
+}; // class pass_tree_ifcombine
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tree_ifcombine (gcc::context *ctxt)
+{
+ return new pass_tree_ifcombine (ctxt);
+}
diff --git a/gcc/tree-ssa-loop-ch.c b/gcc/tree-ssa-loop-ch.c
index ff17c7e78fb..f500761c9c2 100644
--- a/gcc/tree-ssa-loop-ch.c
+++ b/gcc/tree-ssa-loop-ch.c
@@ -256,24 +256,41 @@ gate_ch (void)
return flag_tree_ch != 0;
}
-struct gimple_opt_pass pass_ch =
+namespace {
+
+const pass_data pass_data_ch =
{
- {
- GIMPLE_PASS,
- "ch", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_ch, /* gate */
- copy_loop_headers, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_CH, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_cleanup_cfg
- | TODO_verify_ssa
- | TODO_verify_flow /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "ch", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_CH, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_cleanup_cfg | TODO_verify_ssa
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_ch : public gimple_opt_pass
+{
+public:
+ pass_ch(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_ch, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_ch (); }
+ unsigned int execute () { return copy_loop_headers (); }
+
+}; // class pass_ch
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_ch (gcc::context *ctxt)
+{
+ return new pass_ch (ctxt);
+}
diff --git a/gcc/tree-ssa-loop-ivcanon.c b/gcc/tree-ssa-loop-ivcanon.c
index 735403a0284..f2acc4c15f1 100644
--- a/gcc/tree-ssa-loop-ivcanon.c
+++ b/gcc/tree-ssa-loop-ivcanon.c
@@ -870,11 +870,12 @@ try_unroll_loop_completely (struct loop *loop,
{
if (!n_unroll)
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
- "Turned loop into non-loop; it never loops.\n");
+ "loop turned into non-loop; it never loops\n");
else
{
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS, locus,
- "Completely unroll loop %d times", (int)n_unroll);
+ "loop with %d iterations completely unrolled",
+ (int) (n_unroll + 1));
if (profile_info)
dump_printf (MSG_OPTIMIZED_LOCATIONS | TDF_DETAILS,
" (header execution count %d)",
@@ -1125,6 +1126,11 @@ tree_unroll_loops_completely_1 (bool may_increase_size, bool unroll_outer,
if (changed)
return true;
+ /* Don't unroll #pragma omp simd loops until the vectorizer
+ attempts to vectorize those. */
+ if (loop->force_vect)
+ return false;
+
/* Try to unroll this loop. */
loop_father = loop_outer (loop);
if (!loop_father)
diff --git a/gcc/tree-ssa-loop-ivopts.c b/gcc/tree-ssa-loop-ivopts.c
index 7cfe80d9213..c45f3167f2f 100644
--- a/gcc/tree-ssa-loop-ivopts.c
+++ b/gcc/tree-ssa-loop-ivopts.c
@@ -4876,22 +4876,36 @@ set_autoinc_for_original_candidates (struct ivopts_data *data)
for (i = 0; i < n_iv_cands (data); i++)
{
struct iv_cand *cand = iv_cand (data, i);
- struct iv_use *closest = NULL;
+ struct iv_use *closest_before = NULL;
+ struct iv_use *closest_after = NULL;
if (cand->pos != IP_ORIGINAL)
continue;
+
for (j = 0; j < n_iv_uses (data); j++)
{
struct iv_use *use = iv_use (data, j);
unsigned uid = gimple_uid (use->stmt);
- if (gimple_bb (use->stmt) != gimple_bb (cand->incremented_at)
- || uid > gimple_uid (cand->incremented_at))
+
+ if (gimple_bb (use->stmt) != gimple_bb (cand->incremented_at))
continue;
- if (closest == NULL || uid > gimple_uid (closest->stmt))
- closest = use;
+
+ if (uid < gimple_uid (cand->incremented_at)
+ && (closest_before == NULL
+ || uid > gimple_uid (closest_before->stmt)))
+ closest_before = use;
+
+ if (uid > gimple_uid (cand->incremented_at)
+ && (closest_after == NULL
+ || uid < gimple_uid (closest_after->stmt)))
+ closest_after = use;
}
- if (closest == NULL || !autoinc_possible_for_pair (data, closest, cand))
- continue;
- cand->ainc_use = closest;
+
+ if (closest_before != NULL
+ && autoinc_possible_for_pair (data, closest_before, cand))
+ cand->ainc_use = closest_before;
+ else if (closest_after != NULL
+ && autoinc_possible_for_pair (data, closest_after, cand))
+ cand->ainc_use = closest_after;
}
}
diff --git a/gcc/tree-ssa-loop.c b/gcc/tree-ssa-loop.c
index 99e27a1359a..8bcfd060e60 100644
--- a/gcc/tree-ssa-loop.c
+++ b/gcc/tree-ssa-loop.c
@@ -41,26 +41,43 @@ gate_tree_loop (void)
return flag_tree_loop_optimize != 0;
}
-struct gimple_opt_pass pass_tree_loop =
-{
- {
- GIMPLE_PASS,
- "loop", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_loop, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_LOOP, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_tree_loop =
+{
+ GIMPLE_PASS, /* type */
+ "loop", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_TREE_LOOP, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+class pass_tree_loop : public gimple_opt_pass
+{
+public:
+ pass_tree_loop(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tree_loop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_loop (); }
+
+}; // class pass_tree_loop
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tree_loop (gcc::context *ctxt)
+{
+ return new pass_tree_loop (ctxt);
+}
+
/* Loop optimizer initialization. */
static unsigned int
@@ -80,26 +97,43 @@ tree_ssa_loop_init (void)
return 0;
}
-struct gimple_opt_pass pass_tree_loop_init =
-{
- {
- GIMPLE_PASS,
- "loopinit", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- NULL, /* gate */
- tree_ssa_loop_init, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_tree_loop_init =
+{
+ GIMPLE_PASS, /* type */
+ "loopinit", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_tree_loop_init : public gimple_opt_pass
+{
+public:
+ pass_tree_loop_init(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tree_loop_init, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return tree_ssa_loop_init (); }
+
+}; // class pass_tree_loop_init
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tree_loop_init (gcc::context *ctxt)
+{
+ return new pass_tree_loop_init (ctxt);
+}
+
/* Loop invariant motion pass. */
static unsigned int
@@ -117,26 +151,45 @@ gate_tree_ssa_loop_im (void)
return flag_tree_loop_im != 0;
}
-struct gimple_opt_pass pass_lim =
-{
- {
- GIMPLE_PASS,
- "lim", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_ssa_loop_im, /* gate */
- tree_ssa_loop_im, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_LIM, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_lim =
+{
+ GIMPLE_PASS, /* type */
+ "lim", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_LIM, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_lim : public gimple_opt_pass
+{
+public:
+ pass_lim(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lim, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_lim (ctxt_); }
+ bool gate () { return gate_tree_ssa_loop_im (); }
+ unsigned int execute () { return tree_ssa_loop_im (); }
+
+}; // class pass_lim
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lim (gcc::context *ctxt)
+{
+ return new pass_lim (ctxt);
+}
+
/* Loop unswitching pass. */
static unsigned int
@@ -154,26 +207,44 @@ gate_tree_ssa_loop_unswitch (void)
return flag_unswitch_loops != 0;
}
-struct gimple_opt_pass pass_tree_unswitch =
-{
- {
- GIMPLE_PASS,
- "unswitch", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_ssa_loop_unswitch, /* gate */
- tree_ssa_loop_unswitch, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_LOOP_UNSWITCH, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_tree_unswitch =
+{
+ GIMPLE_PASS, /* type */
+ "unswitch", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_LOOP_UNSWITCH, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_tree_unswitch : public gimple_opt_pass
+{
+public:
+ pass_tree_unswitch(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tree_unswitch, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_ssa_loop_unswitch (); }
+ unsigned int execute () { return tree_ssa_loop_unswitch (); }
+
+}; // class pass_tree_unswitch
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tree_unswitch (gcc::context *ctxt)
+{
+ return new pass_tree_unswitch (ctxt);
+}
+
/* Predictive commoning. */
static unsigned
@@ -191,26 +262,44 @@ gate_tree_predictive_commoning (void)
return flag_predictive_commoning != 0;
}
-struct gimple_opt_pass pass_predcom =
-{
- {
- GIMPLE_PASS,
- "pcom", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_predictive_commoning, /* gate */
- run_tree_predictive_commoning, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_PREDCOM, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa_only_virtuals /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_predcom =
+{
+ GIMPLE_PASS, /* type */
+ "pcom", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_PREDCOM, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_update_ssa_only_virtuals, /* todo_flags_finish */
};
+class pass_predcom : public gimple_opt_pass
+{
+public:
+ pass_predcom(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_predcom, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_predictive_commoning (); }
+ unsigned int execute () { return run_tree_predictive_commoning (); }
+
+}; // class pass_predcom
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_predcom (gcc::context *ctxt)
+{
+ return new pass_predcom (ctxt);
+}
+
/* Loop autovectorization. */
static unsigned int
@@ -225,30 +314,47 @@ tree_vectorize (void)
static bool
gate_tree_vectorize (void)
{
- return flag_tree_vectorize;
-}
-
-struct gimple_opt_pass pass_vectorize =
-{
- {
- GIMPLE_PASS,
- "vect", /* name */
- OPTGROUP_LOOP
- | OPTGROUP_VEC, /* optinfo_flags */
- gate_tree_vectorize, /* gate */
- tree_vectorize, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_VECTORIZATION, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ return flag_tree_vectorize || cfun->has_force_vect_loops;
+}
+
+namespace {
+
+const pass_data pass_data_vectorize =
+{
+ GIMPLE_PASS, /* type */
+ "vect", /* name */
+ OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_VECTORIZATION, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_vectorize : public gimple_opt_pass
+{
+public:
+ pass_vectorize(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_vectorize, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_vectorize (); }
+ unsigned int execute () { return tree_vectorize (); }
+
+}; // class pass_vectorize
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_vectorize (gcc::context *ctxt)
+{
+ return new pass_vectorize (ctxt);
+}
+
/* GRAPHITE optimizations. */
static unsigned int
@@ -278,46 +384,81 @@ gate_graphite_transforms (void)
return flag_graphite != 0;
}
-struct gimple_opt_pass pass_graphite =
-{
- {
- GIMPLE_PASS,
- "graphite0", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_graphite_transforms, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_GRAPHITE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_graphite =
+{
+ GIMPLE_PASS, /* type */
+ "graphite0", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_GRAPHITE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
-struct gimple_opt_pass pass_graphite_transforms =
-{
- {
- GIMPLE_PASS,
- "graphite", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_graphite_transforms, /* gate */
- graphite_transforms, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_GRAPHITE_TRANSFORMS, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+class pass_graphite : public gimple_opt_pass
+{
+public:
+ pass_graphite(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_graphite, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_graphite_transforms (); }
+
+}; // class pass_graphite
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_graphite (gcc::context *ctxt)
+{
+ return new pass_graphite (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_graphite_transforms =
+{
+ GIMPLE_PASS, /* type */
+ "graphite", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_GRAPHITE_TRANSFORMS, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_graphite_transforms : public gimple_opt_pass
+{
+public:
+ pass_graphite_transforms(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_graphite_transforms, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_graphite_transforms (); }
+ unsigned int execute () { return graphite_transforms (); }
+
+}; // class pass_graphite_transforms
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_graphite_transforms (gcc::context *ctxt)
+{
+ return new pass_graphite_transforms (ctxt);
+}
+
/* Check the correctness of the data dependence analyzers. */
static unsigned int
@@ -336,26 +477,44 @@ gate_check_data_deps (void)
return flag_check_data_deps != 0;
}
-struct gimple_opt_pass pass_check_data_deps =
-{
- {
- GIMPLE_PASS,
- "ckdd", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_check_data_deps, /* gate */
- check_data_deps, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_CHECK_DATA_DEPS, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_check_data_deps =
+{
+ GIMPLE_PASS, /* type */
+ "ckdd", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_CHECK_DATA_DEPS, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_check_data_deps : public gimple_opt_pass
+{
+public:
+ pass_check_data_deps(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_check_data_deps, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_check_data_deps (); }
+ unsigned int execute () { return check_data_deps (); }
+
+}; // class pass_check_data_deps
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_check_data_deps (gcc::context *ctxt)
+{
+ return new pass_check_data_deps (ctxt);
+}
+
/* Canonical induction variable creation pass. */
static unsigned int
@@ -373,26 +532,44 @@ gate_tree_ssa_loop_ivcanon (void)
return flag_tree_loop_ivcanon != 0;
}
-struct gimple_opt_pass pass_iv_canon =
-{
- {
- GIMPLE_PASS,
- "ivcanon", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_ssa_loop_ivcanon, /* gate */
- tree_ssa_loop_ivcanon, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_LOOP_IVCANON, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_iv_canon =
+{
+ GIMPLE_PASS, /* type */
+ "ivcanon", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_LOOP_IVCANON, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_iv_canon : public gimple_opt_pass
+{
+public:
+ pass_iv_canon(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_iv_canon, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_ssa_loop_ivcanon (); }
+ unsigned int execute () { return tree_ssa_loop_ivcanon (); }
+
+}; // class pass_iv_canon
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_iv_canon (gcc::context *ctxt)
+{
+ return new pass_iv_canon (ctxt);
+}
+
/* Propagation of constants using scev. */
static bool
@@ -401,28 +578,45 @@ gate_scev_const_prop (void)
return flag_tree_scev_cprop;
}
-struct gimple_opt_pass pass_scev_cprop =
-{
- {
- GIMPLE_PASS,
- "sccp", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_scev_const_prop, /* gate */
- scev_const_prop, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_SCEV_CONST, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_cleanup_cfg
- | TODO_update_ssa_only_virtuals
- /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_scev_cprop =
+{
+ GIMPLE_PASS, /* type */
+ "sccp", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_SCEV_CONST, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_cleanup_cfg
+ | TODO_update_ssa_only_virtuals ), /* todo_flags_finish */
};
+class pass_scev_cprop : public gimple_opt_pass
+{
+public:
+ pass_scev_cprop(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_scev_cprop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_scev_const_prop (); }
+ unsigned int execute () { return scev_const_prop (); }
+
+}; // class pass_scev_cprop
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_scev_cprop (gcc::context *ctxt)
+{
+ return new pass_scev_cprop (ctxt);
+}
+
/* Record bounds on numbers of iterations of loops. */
static unsigned int
@@ -436,26 +630,43 @@ tree_ssa_loop_bounds (void)
return 0;
}
-struct gimple_opt_pass pass_record_bounds =
-{
- {
- GIMPLE_PASS,
- "*record_bounds", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- tree_ssa_loop_bounds, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_LOOP_BOUNDS, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_record_bounds =
+{
+ GIMPLE_PASS, /* type */
+ "*record_bounds", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_LOOP_BOUNDS, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_record_bounds : public gimple_opt_pass
+{
+public:
+ pass_record_bounds(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_record_bounds, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return tree_ssa_loop_bounds (); }
+
+}; // class pass_record_bounds
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_record_bounds (gcc::context *ctxt)
+{
+ return new pass_record_bounds (ctxt);
+}
+
/* Complete unrolling of loops. */
static unsigned int
@@ -475,26 +686,44 @@ gate_tree_complete_unroll (void)
return true;
}
-struct gimple_opt_pass pass_complete_unroll =
-{
- {
- GIMPLE_PASS,
- "cunroll", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_complete_unroll, /* gate */
- tree_complete_unroll, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_COMPLETE_UNROLL, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_complete_unroll =
+{
+ GIMPLE_PASS, /* type */
+ "cunroll", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_COMPLETE_UNROLL, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_complete_unroll : public gimple_opt_pass
+{
+public:
+ pass_complete_unroll(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_complete_unroll, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_complete_unroll (); }
+ unsigned int execute () { return tree_complete_unroll (); }
+
+}; // class pass_complete_unroll
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_complete_unroll (gcc::context *ctxt)
+{
+ return new pass_complete_unroll (ctxt);
+}
+
/* Complete unrolling of inner loops. */
static unsigned int
@@ -522,26 +751,44 @@ gate_tree_complete_unroll_inner (void)
return optimize >= 2;
}
-struct gimple_opt_pass pass_complete_unrolli =
-{
- {
- GIMPLE_PASS,
- "cunrolli", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_complete_unroll_inner, /* gate */
- tree_complete_unroll_inner, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_COMPLETE_UNROLL, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_complete_unrolli =
+{
+ GIMPLE_PASS, /* type */
+ "cunrolli", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_COMPLETE_UNROLL, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_flow, /* todo_flags_finish */
};
+class pass_complete_unrolli : public gimple_opt_pass
+{
+public:
+ pass_complete_unrolli(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_complete_unrolli, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_complete_unroll_inner (); }
+ unsigned int execute () { return tree_complete_unroll_inner (); }
+
+}; // class pass_complete_unrolli
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_complete_unrolli (gcc::context *ctxt)
+{
+ return new pass_complete_unrolli (ctxt);
+}
+
/* Parallelization. */
static bool
@@ -561,26 +808,44 @@ tree_parallelize_loops (void)
return 0;
}
-struct gimple_opt_pass pass_parallelize_loops =
-{
- {
- GIMPLE_PASS,
- "parloops", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_parallelize_loops, /* gate */
- tree_parallelize_loops, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_PARALLELIZE_LOOPS, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_flow /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_parallelize_loops =
+{
+ GIMPLE_PASS, /* type */
+ "parloops", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_PARALLELIZE_LOOPS, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_flow, /* todo_flags_finish */
};
+class pass_parallelize_loops : public gimple_opt_pass
+{
+public:
+ pass_parallelize_loops(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_parallelize_loops, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_parallelize_loops (); }
+ unsigned int execute () { return tree_parallelize_loops (); }
+
+}; // class pass_parallelize_loops
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_parallelize_loops (gcc::context *ctxt)
+{
+ return new pass_parallelize_loops (ctxt);
+}
+
/* Prefetching. */
static unsigned int
@@ -598,26 +863,44 @@ gate_tree_ssa_loop_prefetch (void)
return flag_prefetch_loop_arrays > 0;
}
-struct gimple_opt_pass pass_loop_prefetch =
-{
- {
- GIMPLE_PASS,
- "aprefetch", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_ssa_loop_prefetch, /* gate */
- tree_ssa_loop_prefetch, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_PREFETCH, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_loop_prefetch =
+{
+ GIMPLE_PASS, /* type */
+ "aprefetch", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_PREFETCH, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_loop_prefetch : public gimple_opt_pass
+{
+public:
+ pass_loop_prefetch(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_loop_prefetch, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_ssa_loop_prefetch (); }
+ unsigned int execute () { return tree_ssa_loop_prefetch (); }
+
+}; // class pass_loop_prefetch
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_loop_prefetch (gcc::context *ctxt)
+{
+ return new pass_loop_prefetch (ctxt);
+}
+
/* Induction variable optimizations. */
static unsigned int
@@ -636,26 +919,44 @@ gate_tree_ssa_loop_ivopts (void)
return flag_ivopts != 0;
}
-struct gimple_opt_pass pass_iv_optimize =
-{
- {
- GIMPLE_PASS,
- "ivopts", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- gate_tree_ssa_loop_ivopts, /* gate */
- tree_ssa_loop_ivopts, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_LOOP_IVOPTS, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_iv_optimize =
+{
+ GIMPLE_PASS, /* type */
+ "ivopts", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_LOOP_IVOPTS, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_update_ssa, /* todo_flags_finish */
};
+class pass_iv_optimize : public gimple_opt_pass
+{
+public:
+ pass_iv_optimize(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_iv_optimize, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_ssa_loop_ivopts (); }
+ unsigned int execute () { return tree_ssa_loop_ivopts (); }
+
+}; // class pass_iv_optimize
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_iv_optimize (gcc::context *ctxt)
+{
+ return new pass_iv_optimize (ctxt);
+}
+
/* Loop optimizer finalization. */
static unsigned int
@@ -667,23 +968,39 @@ tree_ssa_loop_done (void)
return 0;
}
-struct gimple_opt_pass pass_tree_loop_done =
-{
- {
- GIMPLE_PASS,
- "loopdone", /* name */
- OPTGROUP_LOOP, /* optinfo_flags */
- NULL, /* gate */
- tree_ssa_loop_done, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_cleanup_cfg
- | TODO_verify_flow /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_tree_loop_done =
+{
+ GIMPLE_PASS, /* type */
+ "loopdone", /* name */
+ OPTGROUP_LOOP, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_cleanup_cfg | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_tree_loop_done : public gimple_opt_pass
+{
+public:
+ pass_tree_loop_done(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tree_loop_done, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return tree_ssa_loop_done (); }
+
+}; // class pass_tree_loop_done
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tree_loop_done (gcc::context *ctxt)
+{
+ return new pass_tree_loop_done (ctxt);
+}
diff --git a/gcc/tree-ssa-math-opts.c b/gcc/tree-ssa-math-opts.c
index e9c32b3c8be..f871e928a19 100644
--- a/gcc/tree-ssa-math-opts.c
+++ b/gcc/tree-ssa-math-opts.c
@@ -636,27 +636,45 @@ execute_cse_reciprocals (void)
return 0;
}
-struct gimple_opt_pass pass_cse_reciprocals =
+namespace {
+
+const pass_data pass_data_cse_reciprocals =
{
- {
- GIMPLE_PASS,
- "recip", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_cse_reciprocals, /* gate */
- execute_cse_reciprocals, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa | TODO_verify_ssa
- | TODO_verify_stmts /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "recip", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa
+ | TODO_verify_stmts ), /* todo_flags_finish */
};
+class pass_cse_reciprocals : public gimple_opt_pass
+{
+public:
+ pass_cse_reciprocals(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_cse_reciprocals, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_cse_reciprocals (); }
+ unsigned int execute () { return execute_cse_reciprocals (); }
+
+}; // class pass_cse_reciprocals
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_cse_reciprocals (gcc::context *ctxt)
+{
+ return new pass_cse_reciprocals (ctxt);
+}
+
/* Records an occurrence at statement USE_STMT in the vector of trees
STMTS if it is dominated by *TOP_BB or dominates it or this basic block
is not yet initialized. Returns true if the occurrence was pushed on
@@ -1414,7 +1432,8 @@ execute_cse_sincos (void)
CASE_FLT_FN (BUILT_IN_SIN):
CASE_FLT_FN (BUILT_IN_CEXPI):
/* Make sure we have either sincos or cexp. */
- if (!TARGET_HAS_SINCOS && !TARGET_C99_FUNCTIONS)
+ if (!targetm.libc_has_function (function_c99_math_complex)
+ && !targetm.libc_has_function (function_sincos))
break;
arg = gimple_call_arg (stmt, 0);
@@ -1535,27 +1554,45 @@ gate_cse_sincos (void)
return optimize;
}
-struct gimple_opt_pass pass_cse_sincos =
+namespace {
+
+const pass_data pass_data_cse_sincos =
{
- {
- GIMPLE_PASS,
- "sincos", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_cse_sincos, /* gate */
- execute_cse_sincos, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa | TODO_verify_ssa
- | TODO_verify_stmts /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "sincos", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa
+ | TODO_verify_stmts ), /* todo_flags_finish */
};
+class pass_cse_sincos : public gimple_opt_pass
+{
+public:
+ pass_cse_sincos(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_cse_sincos, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_cse_sincos (); }
+ unsigned int execute () { return execute_cse_sincos (); }
+
+}; // class pass_cse_sincos
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_cse_sincos (gcc::context *ctxt)
+{
+ return new pass_cse_sincos (ctxt);
+}
+
/* A symbolic number is used to detect byte permutation and selection
patterns. Therefore the field N contains an artificial number
consisting of byte size markers:
@@ -2008,26 +2045,44 @@ gate_optimize_bswap (void)
return flag_expensive_optimizations && optimize;
}
-struct gimple_opt_pass pass_optimize_bswap =
+namespace {
+
+const pass_data pass_data_optimize_bswap =
{
- {
- GIMPLE_PASS,
- "bswap", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_optimize_bswap, /* gate */
- execute_optimize_bswap, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "bswap", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_optimize_bswap : public gimple_opt_pass
+{
+public:
+ pass_optimize_bswap(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_optimize_bswap, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_optimize_bswap (); }
+ unsigned int execute () { return execute_optimize_bswap (); }
+
+}; // class pass_optimize_bswap
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_optimize_bswap (gcc::context *ctxt)
+{
+ return new pass_optimize_bswap (ctxt);
+}
+
/* Return true if stmt is a type conversion operation that can be stripped
when used in a widening multiply operation. */
static bool
@@ -2795,24 +2850,41 @@ gate_optimize_widening_mul (void)
return flag_expensive_optimizations && optimize;
}
-struct gimple_opt_pass pass_optimize_widening_mul =
+namespace {
+
+const pass_data pass_data_optimize_widening_mul =
{
- {
- GIMPLE_PASS,
- "widening_mul", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_optimize_widening_mul, /* gate */
- execute_optimize_widening_mul, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_verify_stmts
- | TODO_update_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "widening_mul", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa | TODO_verify_stmts
+ | TODO_update_ssa ), /* todo_flags_finish */
};
+
+class pass_optimize_widening_mul : public gimple_opt_pass
+{
+public:
+ pass_optimize_widening_mul(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_optimize_widening_mul, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_optimize_widening_mul (); }
+ unsigned int execute () { return execute_optimize_widening_mul (); }
+
+}; // class pass_optimize_widening_mul
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_optimize_widening_mul (gcc::context *ctxt)
+{
+ return new pass_optimize_widening_mul (ctxt);
+}
diff --git a/gcc/tree-ssa-phiopt.c b/gcc/tree-ssa-phiopt.c
index 5e99678ac01..ddcd040ba7c 100644
--- a/gcc/tree-ssa-phiopt.c
+++ b/gcc/tree-ssa-phiopt.c
@@ -2015,52 +2015,87 @@ gate_phiopt (void)
return 1;
}
-struct gimple_opt_pass pass_phiopt =
+namespace {
+
+const pass_data pass_data_phiopt =
{
- {
- GIMPLE_PASS,
- "phiopt", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_phiopt, /* gate */
- tree_ssa_phiopt, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_PHIOPT, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_verify_flow
- | TODO_verify_stmts /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "phiopt", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_PHIOPT, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa | TODO_verify_flow
+ | TODO_verify_stmts ), /* todo_flags_finish */
};
+class pass_phiopt : public gimple_opt_pass
+{
+public:
+ pass_phiopt(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_phiopt, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_phiopt (ctxt_); }
+ bool gate () { return gate_phiopt (); }
+ unsigned int execute () { return tree_ssa_phiopt (); }
+
+}; // class pass_phiopt
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_phiopt (gcc::context *ctxt)
+{
+ return new pass_phiopt (ctxt);
+}
+
static bool
gate_cselim (void)
{
return flag_tree_cselim;
}
-struct gimple_opt_pass pass_cselim =
+namespace {
+
+const pass_data pass_data_cselim =
{
- {
- GIMPLE_PASS,
- "cselim", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_cselim, /* gate */
- tree_ssa_cs_elim, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_PHIOPT, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_verify_flow
- | TODO_verify_stmts /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "cselim", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_PHIOPT, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa | TODO_verify_flow
+ | TODO_verify_stmts ), /* todo_flags_finish */
};
+
+class pass_cselim : public gimple_opt_pass
+{
+public:
+ pass_cselim(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_cselim, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_cselim (); }
+ unsigned int execute () { return tree_ssa_cs_elim (); }
+
+}; // class pass_cselim
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_cselim (gcc::context *ctxt)
+{
+ return new pass_cselim (ctxt);
+}
diff --git a/gcc/tree-ssa-phiprop.c b/gcc/tree-ssa-phiprop.c
index 96d7ba6a935..1257334f51b 100644
--- a/gcc/tree-ssa-phiprop.c
+++ b/gcc/tree-ssa-phiprop.c
@@ -394,23 +394,40 @@ gate_phiprop (void)
return flag_tree_phiprop;
}
-struct gimple_opt_pass pass_phiprop =
+namespace {
+
+const pass_data pass_data_phiprop =
{
- {
- GIMPLE_PASS,
- "phiprop", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_phiprop, /* gate */
- tree_ssa_phiprop, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_PHIPROP, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "phiprop", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_PHIPROP, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa ), /* todo_flags_finish */
};
+
+class pass_phiprop : public gimple_opt_pass
+{
+public:
+ pass_phiprop(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_phiprop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_phiprop (); }
+ unsigned int execute () { return tree_ssa_phiprop (); }
+
+}; // class pass_phiprop
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_phiprop (gcc::context *ctxt)
+{
+ return new pass_phiprop (ctxt);
+}
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index 642a343afe8..56b05734e16 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -3341,7 +3341,11 @@ do_regular_insertion (basic_block block, basic_block dom)
if (bitmap_set_contains_value (AVAIL_OUT (dom), val))
{
if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file, "Found fully redundant value\n");
+ {
+ fprintf (dump_file, "Found fully redundant value: ");
+ print_pre_expr (dump_file, expr);
+ fprintf (dump_file, "\n");
+ }
continue;
}
@@ -4786,27 +4790,44 @@ gate_pre (void)
return flag_tree_pre != 0;
}
-struct gimple_opt_pass pass_pre =
+namespace {
+
+const pass_data pass_data_pre =
{
- {
- GIMPLE_PASS,
- "pre", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_pre, /* gate */
- do_pre, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_PRE, /* tv_id */
- PROP_no_crit_edges | PROP_cfg
- | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- TODO_rebuild_alias, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "pre", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_PRE, /* tv_id */
+ ( PROP_no_crit_edges | PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ TODO_rebuild_alias, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+class pass_pre : public gimple_opt_pass
+{
+public:
+ pass_pre(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_pre, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_pre (); }
+ unsigned int execute () { return do_pre (); }
+
+}; // class pass_pre
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_pre (gcc::context *ctxt)
+{
+ return new pass_pre (ctxt);
+}
+
/* Gate and execute functions for FRE. */
@@ -4839,22 +4860,41 @@ gate_fre (void)
return flag_tree_fre != 0;
}
-struct gimple_opt_pass pass_fre =
+namespace {
+
+const pass_data pass_data_fre =
{
- {
- GIMPLE_PASS,
- "fre", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_fre, /* gate */
- execute_fre, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_FRE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "fre", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_FRE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_fre : public gimple_opt_pass
+{
+public:
+ pass_fre(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_fre, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_fre (ctxt_); }
+ bool gate () { return gate_fre (); }
+ unsigned int execute () { return execute_fre (); }
+
+}; // class pass_fre
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_fre (gcc::context *ctxt)
+{
+ return new pass_fre (ctxt);
+}
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 1a2619d607c..03c6c5dbfa4 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -1141,6 +1141,14 @@ zero_one_operation (tree *def, enum tree_code opcode, tree op)
while (1);
}
+/* Returns the UID of STMT if it is non-NULL. Otherwise return 1. */
+
+static inline unsigned
+get_stmt_uid_with_default (gimple stmt)
+{
+ return stmt ? gimple_uid (stmt) : 1;
+}
+
/* Builds one statement performing OP1 OPCODE OP2 using TMPVAR for
the result. Places the statement after the definition of either
OP1 or OP2. Returns the new statement. */
@@ -1165,12 +1173,8 @@ build_and_add_sum (tree type, tree op1, tree op2, enum tree_code opcode)
if ((!op1def || gimple_nop_p (op1def))
&& (!op2def || gimple_nop_p (op2def)))
{
- gimple first_stmt;
- unsigned uid;
gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
- first_stmt = gsi_stmt (gsi);
- uid = first_stmt ? gimple_uid (first_stmt) : 1;
- gimple_set_uid (sum, uid);
+ gimple_set_uid (sum, get_stmt_uid_with_default (gsi_stmt (gsi)));
gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
}
else if ((!op1def || gimple_nop_p (op1def))
@@ -1180,7 +1184,7 @@ build_and_add_sum (tree type, tree op1, tree op2, enum tree_code opcode)
if (gimple_code (op2def) == GIMPLE_PHI)
{
gsi = gsi_after_labels (gimple_bb (op2def));
- gimple_set_uid (sum, gimple_uid (gsi_stmt (gsi)));
+ gimple_set_uid (sum, get_stmt_uid_with_default (gsi_stmt (gsi)));
gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
}
else
@@ -1207,7 +1211,7 @@ build_and_add_sum (tree type, tree op1, tree op2, enum tree_code opcode)
if (gimple_code (op1def) == GIMPLE_PHI)
{
gsi = gsi_after_labels (gimple_bb (op1def));
- gimple_set_uid (sum, gimple_uid (op1def));
+ gimple_set_uid (sum, get_stmt_uid_with_default (gsi_stmt (gsi)));
gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
}
else
@@ -2860,7 +2864,7 @@ not_dominated_by (gimple a, gimple b)
basic_block bb_a, bb_b;
bb_a = gimple_bb (a);
bb_b = gimple_bb (b);
- return ((bb_a == bb_b && gimple_uid (a) < gimple_uid (b))
+ return ((bb_a == bb_b && gimple_uid (a) < gimple_uid (b))
|| (bb_a != bb_b
&& !dominated_by_p (CDI_DOMINATORS, bb_a, bb_b)));
@@ -2874,10 +2878,7 @@ appears_later_in_bb (gimple stmt1, gimple stmt2)
{
unsigned uid = gimple_uid (stmt1);
gimple_stmt_iterator gsi = gsi_for_stmt (stmt1);
- gsi_next (&gsi);
- if (gsi_end_p (gsi))
- return stmt1;
- for (; !gsi_end_p (gsi); gsi_next (&gsi))
+ for (gsi_next (&gsi); !gsi_end_p (gsi); gsi_next (&gsi))
{
gimple stmt = gsi_stmt (gsi);
@@ -4450,24 +4451,43 @@ gate_tree_ssa_reassoc (void)
return flag_tree_reassoc != 0;
}
-struct gimple_opt_pass pass_reassoc =
+namespace {
+
+const pass_data pass_data_reassoc =
{
- {
- GIMPLE_PASS,
- "reassoc", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tree_ssa_reassoc, /* gate */
- execute_reassoc, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_REASSOC, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_update_ssa_only_virtuals
- | TODO_verify_flow /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "reassoc", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_REASSOC, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa
+ | TODO_update_ssa_only_virtuals
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_reassoc : public gimple_opt_pass
+{
+public:
+ pass_reassoc(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_reassoc, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_reassoc (ctxt_); }
+ bool gate () { return gate_tree_ssa_reassoc (); }
+ unsigned int execute () { return execute_reassoc (); }
+
+}; // class pass_reassoc
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_reassoc (gcc::context *ctxt)
+{
+ return new pass_reassoc (ctxt);
+}
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c
index 87a0a599110..e8540e80534 100644
--- a/gcc/tree-ssa-sink.c
+++ b/gcc/tree-ssa-sink.c
@@ -586,25 +586,41 @@ gate_sink (void)
return flag_tree_sink != 0;
}
-struct gimple_opt_pass pass_sink_code =
+namespace {
+
+const pass_data pass_data_sink_code =
{
- {
- GIMPLE_PASS,
- "sink", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_sink, /* gate */
- do_sink, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SINK, /* tv_id */
- PROP_no_crit_edges | PROP_cfg
- | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa
- | TODO_verify_flow /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "sink", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SINK, /* tv_id */
+ ( PROP_no_crit_edges | PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_sink_code : public gimple_opt_pass
+{
+public:
+ pass_sink_code(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_sink_code, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_sink (); }
+ unsigned int execute () { return do_sink (); }
+
+}; // class pass_sink_code
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_sink_code (gcc::context *ctxt)
+{
+ return new pass_sink_code (ctxt);
+}
diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c
index c0f9ccd5642..5c21b92ec68 100644
--- a/gcc/tree-ssa-strlen.c
+++ b/gcc/tree-ssa-strlen.c
@@ -1952,6 +1952,28 @@ strlen_enter_block (struct dom_walk_data *walk_data ATTRIBUTE_UNUSED,
int count_vdef = 100;
do_invalidate (dombb, phi, visited, &count_vdef);
BITMAP_FREE (visited);
+ if (count_vdef == 0)
+ {
+ /* If there were too many vdefs in between immediate
+ dominator and current bb, invalidate everything.
+ If stridx_to_strinfo has been unshared, we need
+ to free it, otherwise just set it to NULL. */
+ if (!strinfo_shared ())
+ {
+ unsigned int i;
+ strinfo si;
+
+ for (i = 1;
+ vec_safe_iterate (stridx_to_strinfo, i, &si);
+ ++i)
+ {
+ free_strinfo (si);
+ (*stridx_to_strinfo)[i] = NULL;
+ }
+ }
+ else
+ stridx_to_strinfo = NULL;
+ }
break;
}
}
@@ -2065,22 +2087,40 @@ gate_strlen (void)
return flag_optimize_strlen != 0;
}
-struct gimple_opt_pass pass_strlen =
+namespace {
+
+const pass_data pass_data_strlen =
{
- {
- GIMPLE_PASS,
- "strlen", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_strlen, /* gate */
- tree_ssa_strlen, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_STRLEN, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "strlen", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_STRLEN, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_strlen : public gimple_opt_pass
+{
+public:
+ pass_strlen(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_strlen, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_strlen (); }
+ unsigned int execute () { return tree_ssa_strlen (); }
+
+}; // class pass_strlen
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_strlen (gcc::context *ctxt)
+{
+ return new pass_strlen (ctxt);
+}
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index d46cbb34b88..991a6b5800e 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -482,7 +482,7 @@ struct constraint_expr
};
/* Use 0x8000... as special unknown offset. */
-#define UNKNOWN_OFFSET ((HOST_WIDE_INT)-1 << (HOST_BITS_PER_WIDE_INT-1))
+#define UNKNOWN_OFFSET HOST_WIDE_INT_MIN
typedef struct constraint_expr ce_s;
static void get_constraint_for_1 (tree, vec<ce_s> *, bool, bool);
@@ -6960,49 +6960,83 @@ gate_tree_pta (void)
/* A dummy pass to cause points-to information to be computed via
TODO_rebuild_alias. */
-struct gimple_opt_pass pass_build_alias =
-{
- {
- GIMPLE_PASS,
- "alias", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tree_pta, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_rebuild_alias /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_build_alias =
+{
+ GIMPLE_PASS, /* type */
+ "alias", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_rebuild_alias, /* todo_flags_finish */
};
+class pass_build_alias : public gimple_opt_pass
+{
+public:
+ pass_build_alias(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_build_alias, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_pta (); }
+
+}; // class pass_build_alias
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_build_alias (gcc::context *ctxt)
+{
+ return new pass_build_alias (ctxt);
+}
+
/* A dummy pass to cause points-to information to be computed via
TODO_rebuild_alias. */
-struct gimple_opt_pass pass_build_ealias =
-{
- {
- GIMPLE_PASS,
- "ealias", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tree_pta, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_rebuild_alias /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_build_ealias =
+{
+ GIMPLE_PASS, /* type */
+ "ealias", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ false, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_rebuild_alias, /* todo_flags_finish */
};
+class pass_build_ealias : public gimple_opt_pass
+{
+public:
+ pass_build_ealias(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_build_ealias, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_pta (); }
+
+}; // class pass_build_ealias
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_build_ealias (gcc::context *ctxt)
+{
+ return new pass_build_ealias (ctxt);
+}
+
/* Return true if we should execute IPA PTA. */
static bool
@@ -7054,8 +7088,9 @@ ipa_pta_execute (void)
/* Nodes without a body are not interesting. Especially do not
visit clones at this point for now - we get duplicate decls
there for inline clones at least. */
- if (!cgraph_function_with_gimple_body_p (node))
+ if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
continue;
+ cgraph_get_body (node);
gcc_assert (!node->clone_of);
@@ -7088,7 +7123,7 @@ ipa_pta_execute (void)
basic_block bb;
/* Nodes without a body are not interesting. */
- if (!cgraph_function_with_gimple_body_p (node))
+ if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
continue;
if (dump_file)
@@ -7197,7 +7232,7 @@ ipa_pta_execute (void)
struct cgraph_edge *e;
/* Nodes without a body are not interesting. */
- if (!cgraph_function_with_gimple_body_p (node))
+ if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
continue;
fn = DECL_STRUCT_FUNCTION (node->symbol.decl);
@@ -7359,22 +7394,40 @@ ipa_pta_execute (void)
return 0;
}
-struct simple_ipa_opt_pass pass_ipa_pta =
-{
- {
- SIMPLE_IPA_PASS,
- "pta", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_ipa_pta, /* gate */
- ipa_pta_execute, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_PTA, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_ipa_pta =
+{
+ SIMPLE_IPA_PASS, /* type */
+ "pta", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_PTA, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_update_ssa, /* todo_flags_finish */
};
+
+class pass_ipa_pta : public simple_ipa_opt_pass
+{
+public:
+ pass_ipa_pta(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_ipa_pta, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_ipa_pta (); }
+ unsigned int execute () { return ipa_pta_execute (); }
+
+}; // class pass_ipa_pta
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_pta (gcc::context *ctxt)
+{
+ return new pass_ipa_pta (ctxt);
+}
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 357b6712a75..f2051d7e7d0 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -738,54 +738,68 @@ propagate_threaded_block_debug_into (basic_block dest, basic_block src)
fewvars.release ();
}
-/* TAKEN_EDGE represents the an edge taken as a result of jump threading.
- See if we can thread around TAKEN_EDGE->dest as well. If so, return
- the edge out of TAKEN_EDGE->dest that we can statically compute will be
- traversed.
-
- We are much more restrictive as to the contents of TAKEN_EDGE->dest
- as the path isolation code in tree-ssa-threadupdate.c isn't prepared
- to handle copying intermediate blocks on a threaded path.
-
- Long term a more consistent and structured approach to path isolation
- would be a huge help. */
-static edge
-thread_around_empty_block (edge taken_edge,
- gimple dummy_cond,
- bool handle_dominating_asserts,
- tree (*simplify) (gimple, gimple),
- bitmap visited)
+/* See if TAKEN_EDGE->dest is a threadable block with no side effecs (ie, it
+ need not be duplicated as part of the CFG/SSA updating process).
+
+ If it is threadable, add it to PATH and VISITED and recurse, ultimately
+ returning TRUE from the toplevel call. Otherwise do nothing and
+ return false.
+
+ DUMMY_COND, HANDLE_DOMINATING_ASSERTS and SIMPLIFY are used to
+ try and simplify the condition at the end of TAKEN_EDGE->dest. */
+static bool
+thread_around_empty_blocks (edge taken_edge,
+ gimple dummy_cond,
+ bool handle_dominating_asserts,
+ tree (*simplify) (gimple, gimple),
+ bitmap visited,
+ vec<edge> *path)
{
basic_block bb = taken_edge->dest;
gimple_stmt_iterator gsi;
gimple stmt;
tree cond;
- /* This block must have a single predecessor (E->dest). */
- if (!single_pred_p (bb))
- return NULL;
-
- /* This block must have more than one successor. */
- if (single_succ_p (bb))
- return NULL;
-
- /* This block can have no PHI nodes. This is overly conservative. */
+ /* The key property of these blocks is that they need not be duplicated
+ when threading. Thus they can not have visible side effects such
+ as PHI nodes. */
if (!gsi_end_p (gsi_start_phis (bb)))
return NULL;
/* Skip over DEBUG statements at the start of the block. */
gsi = gsi_start_nondebug_bb (bb);
+ /* If the block has no statements, but does have a single successor, then
+ it's just a forwarding block and we can thread through it trivially. */
if (gsi_end_p (gsi))
- return NULL;
+ {
+ if (single_succ_p (bb))
+ {
+ taken_edge = single_succ_edge (bb);
+ if ((taken_edge->flags & EDGE_DFS_BACK) == 0
+ && !bitmap_bit_p (visited, taken_edge->dest->index))
+ {
+ bitmap_set_bit (visited, taken_edge->dest->index);
+ path->safe_push (taken_edge);
+ thread_around_empty_blocks (taken_edge,
+ dummy_cond,
+ handle_dominating_asserts,
+ simplify,
+ visited,
+ path);
+ return true;
+ }
+ }
+ return false;
+ }
- /* This block can have no statements other than its control altering
- statement. This is overly conservative. */
+ /* The only real statements this block can have are a control
+ flow altering statement. Anything else stops the thread. */
stmt = gsi_stmt (gsi);
if (gimple_code (stmt) != GIMPLE_COND
&& gimple_code (stmt) != GIMPLE_GOTO
&& gimple_code (stmt) != GIMPLE_SWITCH)
- return NULL;
+ return false;
/* Extract and simplify the condition. */
cond = simplify_control_stmt_condition (taken_edge, stmt, dummy_cond,
@@ -796,15 +810,22 @@ thread_around_empty_block (edge taken_edge,
path. */
if (cond && is_gimple_min_invariant (cond))
{
- edge taken_edge = find_taken_edge (bb, cond);
+ taken_edge = find_taken_edge (bb, cond);
if (bitmap_bit_p (visited, taken_edge->dest->index))
- return NULL;
+ return false;
bitmap_set_bit (visited, taken_edge->dest->index);
- return taken_edge;
+ path->safe_push (taken_edge);
+ thread_around_empty_blocks (taken_edge,
+ dummy_cond,
+ handle_dominating_asserts,
+ simplify,
+ visited,
+ path);
+ return true;
}
- return NULL;
+ return false;
}
/* E1 and E2 are edges into the same basic block. Return TRUE if the
@@ -904,43 +925,41 @@ thread_across_edge (gimple dummy_cond,
edge taken_edge = find_taken_edge (e->dest, cond);
basic_block dest = (taken_edge ? taken_edge->dest : NULL);
bitmap visited;
- edge e2;
- if (dest == e->dest)
+ /* DEST could be NULL for a computed jump to an absolute
+ address. */
+ if (dest == NULL || dest == e->dest)
goto fail;
- /* DEST could be null for a computed jump to an absolute
- address. If DEST is not null, then see if we can thread
- through it as well, this helps capture secondary effects
- of threading without having to re-run DOM or VRP. */
- if (dest
- && ((e->flags & EDGE_DFS_BACK) == 0
- || ! cond_arg_set_in_bb (taken_edge, e->dest)))
+ vec<edge> path = vNULL;
+ path.safe_push (e);
+ path.safe_push (taken_edge);
+
+ /* See if we can thread through DEST as well, this helps capture
+ secondary effects of threading without having to re-run DOM or
+ VRP. */
+ if ((e->flags & EDGE_DFS_BACK) == 0
+ || ! cond_arg_set_in_bb (taken_edge, e->dest))
{
/* We don't want to thread back to a block we have already
visited. This may be overly conservative. */
visited = BITMAP_ALLOC (NULL);
bitmap_set_bit (visited, dest->index);
bitmap_set_bit (visited, e->dest->index);
- do
- {
- e2 = thread_around_empty_block (taken_edge,
- dummy_cond,
- handle_dominating_asserts,
- simplify,
- visited);
- if (e2)
- taken_edge = e2;
- }
- while (e2);
+ thread_around_empty_blocks (taken_edge,
+ dummy_cond,
+ handle_dominating_asserts,
+ simplify,
+ visited,
+ &path);
BITMAP_FREE (visited);
}
remove_temporary_equivalences (stack);
- if (!taken_edge)
- return;
- propagate_threaded_block_debug_into (taken_edge->dest, e->dest);
- register_jump_thread (e, taken_edge, NULL);
+ propagate_threaded_block_debug_into (path[path.length () - 1]->dest,
+ e->dest);
+ register_jump_thread (path, false);
+ path.release ();
return;
}
}
@@ -957,9 +976,9 @@ thread_across_edge (gimple dummy_cond,
This is a stopgap until we have a more structured approach to path
isolation. */
{
- edge e2, e3, taken_edge;
+ edge taken_edge;
edge_iterator ei;
- bool found = false;
+ bool found;
bitmap visited = BITMAP_ALLOC (NULL);
/* Look at each successor of E->dest to see if we can thread through it. */
@@ -969,30 +988,21 @@ thread_across_edge (gimple dummy_cond,
bitmap_clear (visited);
bitmap_set_bit (visited, taken_edge->dest->index);
bitmap_set_bit (visited, e->dest->index);
+ vec<edge> path = vNULL;
/* Record whether or not we were able to thread through a successor
of E->dest. */
+ path.safe_push (e);
+ path.safe_push (taken_edge);
found = false;
- e3 = taken_edge;
- do
- {
- if ((e->flags & EDGE_DFS_BACK) == 0
- || ! cond_arg_set_in_bb (e3, e->dest))
- e2 = thread_around_empty_block (e3,
+ if ((e->flags & EDGE_DFS_BACK) == 0
+ || ! cond_arg_set_in_bb (path[path.length () - 1], e->dest))
+ found = thread_around_empty_blocks (taken_edge,
dummy_cond,
handle_dominating_asserts,
simplify,
- visited);
- else
- e2 = NULL;
-
- if (e2)
- {
- e3 = e2;
- found = true;
- }
- }
- while (e2);
+ visited,
+ &path);
/* If we were able to thread through a successor of E->dest, then
record the jump threading opportunity. */
@@ -1003,15 +1013,16 @@ thread_across_edge (gimple dummy_cond,
(E2->src) to the final target (E3->dest), then make sure that
the PHI args associated with the edges E2 and E3 are the
same. */
- tmp = find_edge (taken_edge->src, e3->dest);
- if (!tmp || phi_args_equal_on_edges (tmp, e3))
+ tmp = find_edge (taken_edge->src, path[path.length () - 1]->dest);
+ if (!tmp || phi_args_equal_on_edges (tmp, path[path.length () - 1]))
{
- propagate_threaded_block_debug_into (e3->dest,
+ propagate_threaded_block_debug_into (path[path.length () - 1]->dest,
taken_edge->dest);
- register_jump_thread (e, taken_edge, e3);
+ register_jump_thread (path, true);
}
}
+ path.release();
}
BITMAP_FREE (visited);
}
diff --git a/gcc/tree-ssa-threadupdate.c b/gcc/tree-ssa-threadupdate.c
index 0e4cbc98ced..8e40f6668cf 100644
--- a/gcc/tree-ssa-threadupdate.c
+++ b/gcc/tree-ssa-threadupdate.c
@@ -1146,17 +1146,56 @@ mark_threaded_blocks (bitmap threaded_blocks)
edge e;
edge_iterator ei;
+ /* It is possible to have jump threads in which one is a subpath
+ of the other. ie, (A, B), (B, C), (C, D) where B is a joiner
+ block and (B, C), (C, D) where no joiner block exists.
+
+ When this occurs ignore the jump thread request with the joiner
+ block. It's totally subsumed by the simpler jump thread request.
+
+ This results in less block copying, simpler CFGs. More improtantly,
+ when we duplicate the joiner block, B, in this case we will create
+ a new threading opportunity that we wouldn't be able to optimize
+ until the next jump threading iteration.
+
+ So first convert the jump thread requests which do not require a
+ joiner block. */
for (i = 0; i < threaded_edges.length (); i += 3)
{
edge e = threaded_edges[i];
- edge *x = XNEWVEC (edge, 2);
- e->aux = x;
- THREAD_TARGET (e) = threaded_edges[i + 1];
- THREAD_TARGET2 (e) = threaded_edges[i + 2];
- bitmap_set_bit (tmp, e->dest->index);
+ if (threaded_edges[i + 2] == NULL)
+ {
+ edge *x = XNEWVEC (edge, 2);
+
+ e->aux = x;
+ THREAD_TARGET (e) = threaded_edges[i + 1];
+ THREAD_TARGET2 (e) = NULL;
+ bitmap_set_bit (tmp, e->dest->index);
+ }
}
+
+ /* Now iterate again, converting cases where we threaded through
+ a joiner block, but ignoring those where we have already
+ threaded through the joiner block. */
+ for (i = 0; i < threaded_edges.length (); i += 3)
+ {
+ edge e = threaded_edges[i];
+
+ if (threaded_edges[i + 2] != NULL
+ && threaded_edges[i + 1]->aux == NULL)
+ {
+ edge *x = XNEWVEC (edge, 2);
+
+ e->aux = x;
+ THREAD_TARGET (e) = threaded_edges[i + 1];
+ THREAD_TARGET2 (e) = threaded_edges[i + 2];
+ bitmap_set_bit (tmp, e->dest->index);
+ }
+ }
+
+
/* If optimizing for size, only thread through block if we don't have
to duplicate it or it's an otherwise empty redirection block. */
if (optimize_function_for_size_p (cfun))
@@ -1264,21 +1303,42 @@ thread_through_all_blocks (bool may_peel_loop_headers)
after fixing the SSA graph. */
void
-register_jump_thread (edge e, edge e2, edge e3)
+register_jump_thread (vec<edge> path, bool through_joiner)
{
+ /* Convert PATH into 3 edge representation we've been using. This
+ is temporary until we convert this file to use a path representation
+ throughout. */
+ edge e = path[0];
+ edge e2 = path[1];
+ edge e3;
+
+ if (!through_joiner)
+ e3 = NULL;
+ else
+ e3 = path[path.length () - 1];
+
/* This can occur if we're jumping to a constant address or
or something similar. Just get out now. */
if (e2 == NULL)
return;
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ {
+ unsigned int i;
+
+ fprintf (dump_file,
+ " Registering jump thread %s:",
+ through_joiner ? "(through joiner block)" : "");
+
+ for (i = 0; i < path.length (); i++)
+ fprintf (dump_file, " (%d, %d); ",
+ path[i]->src->index, path[i]->dest->index);
+ fputc ('\n', dump_file);
+ }
+
if (!threaded_edges.exists ())
threaded_edges.create (15);
- if (dump_file && (dump_flags & TDF_DETAILS)
- && e->dest != e2->src)
- fprintf (dump_file,
- " Registering jump thread around one or more intermediate blocks\n");
-
threaded_edges.safe_push (e);
threaded_edges.safe_push (e2);
threaded_edges.safe_push (e3);
diff --git a/gcc/tree-ssa-uncprop.c b/gcc/tree-ssa-uncprop.c
index 555485a07c3..837c4eaf066 100644
--- a/gcc/tree-ssa-uncprop.c
+++ b/gcc/tree-ssa-uncprop.c
@@ -585,22 +585,41 @@ gate_uncprop (void)
return flag_tree_dom != 0;
}
-struct gimple_opt_pass pass_uncprop =
+namespace {
+
+const pass_data pass_data_uncprop =
{
- {
- GIMPLE_PASS,
- "uncprop", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_uncprop, /* gate */
- tree_ssa_uncprop, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SSA_UNCPROP, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "uncprop", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SSA_UNCPROP, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_uncprop : public gimple_opt_pass
+{
+public:
+ pass_uncprop(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_uncprop, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_uncprop (ctxt_); }
+ bool gate () { return gate_uncprop (); }
+ unsigned int execute () { return tree_ssa_uncprop (); }
+
+}; // class pass_uncprop
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_uncprop (gcc::context *ctxt)
+{
+ return new pass_uncprop (ctxt);
+}
diff --git a/gcc/tree-ssa-uninit.c b/gcc/tree-ssa-uninit.c
index 9a726f115a9..6d2d768a243 100644
--- a/gcc/tree-ssa-uninit.c
+++ b/gcc/tree-ssa-uninit.c
@@ -2046,22 +2046,41 @@ gate_warn_uninitialized (void)
return warn_uninitialized != 0;
}
-struct gimple_opt_pass pass_late_warn_uninitialized =
+namespace {
+
+const pass_data pass_data_late_warn_uninitialized =
{
- {
- GIMPLE_PASS,
- "uninit", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_warn_uninitialized, /* gate */
- execute_late_warn_uninitialized, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "uninit", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_late_warn_uninitialized : public gimple_opt_pass
+{
+public:
+ pass_late_warn_uninitialized(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_late_warn_uninitialized, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_late_warn_uninitialized (ctxt_); }
+ bool gate () { return gate_warn_uninitialized (); }
+ unsigned int execute () { return execute_late_warn_uninitialized (); }
+
+}; // class pass_late_warn_uninitialized
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_late_warn_uninitialized (gcc::context *ctxt)
+{
+ return new pass_late_warn_uninitialized (ctxt);
+}
diff --git a/gcc/tree-ssa.c b/gcc/tree-ssa.c
index 215206743e8..83a265c43ac 100644
--- a/gcc/tree-ssa.c
+++ b/gcc/tree-ssa.c
@@ -1088,26 +1088,43 @@ execute_init_datastructures (void)
return 0;
}
-struct gimple_opt_pass pass_init_datastructures =
+namespace {
+
+const pass_data pass_data_init_datastructures =
{
- {
- GIMPLE_PASS,
- "*init_datastructures", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- execute_init_datastructures, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "*init_datastructures", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_init_datastructures : public gimple_opt_pass
+{
+public:
+ pass_init_datastructures(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_init_datastructures, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return execute_init_datastructures (); }
+
+}; // class pass_init_datastructures
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_init_datastructures (gcc::context *ctxt)
+{
+ return new pass_init_datastructures (ctxt);
+}
+
/* Deallocate memory associated with SSA data structures for FNDECL. */
void
@@ -1698,26 +1715,44 @@ gate_warn_uninitialized (void)
return warn_uninitialized != 0;
}
-struct gimple_opt_pass pass_early_warn_uninitialized =
+namespace {
+
+const pass_data pass_data_early_warn_uninitialized =
{
- {
- GIMPLE_PASS,
- "*early_warn_uninitialized", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_warn_uninitialized, /* gate */
- execute_early_warn_uninitialized, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_UNINIT, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "*early_warn_uninitialized", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_UNINIT, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_early_warn_uninitialized : public gimple_opt_pass
+{
+public:
+ pass_early_warn_uninitialized(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_early_warn_uninitialized, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_warn_uninitialized (); }
+ unsigned int execute () { return execute_early_warn_uninitialized (); }
+
+}; // class pass_early_warn_uninitialized
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_early_warn_uninitialized (gcc::context *ctxt)
+{
+ return new pass_early_warn_uninitialized (ctxt);
+}
+
/* If necessary, rewrite the base of the reference tree *TP from
a MEM_REF to a plain or converted symbol. */
@@ -2130,22 +2165,38 @@ execute_update_addresses_taken (void)
timevar_pop (TV_ADDRESS_TAKEN);
}
-struct gimple_opt_pass pass_update_address_taken =
+namespace {
+
+const pass_data pass_data_update_address_taken =
{
- {
- GIMPLE_PASS,
- "addressables", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- NULL, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_ADDRESS_TAKEN, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_address_taken /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "addressables", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ false, /* has_execute */
+ TV_ADDRESS_TAKEN, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_update_address_taken, /* todo_flags_finish */
};
+
+class pass_update_address_taken : public gimple_opt_pass
+{
+public:
+ pass_update_address_taken(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_update_address_taken, ctxt)
+ {}
+
+ /* opt_pass methods: */
+
+}; // class pass_update_address_taken
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_update_address_taken (gcc::context *ctxt)
+{
+ return new pass_update_address_taken (ctxt);
+}
diff --git a/gcc/tree-ssanames.c b/gcc/tree-ssanames.c
index 0a405ce2a30..a6af3da192c 100644
--- a/gcc/tree-ssanames.c
+++ b/gcc/tree-ssanames.c
@@ -440,22 +440,39 @@ release_dead_ssa_names (void)
return 0;
}
-struct gimple_opt_pass pass_release_ssa_names =
+namespace {
+
+const pass_data pass_data_release_ssa_names =
{
- {
- GIMPLE_PASS,
- "release_ssa", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- release_dead_ssa_names, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SSA_OTHER, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- TODO_remove_unused_locals, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "release_ssa", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SSA_OTHER, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ TODO_remove_unused_locals, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_release_ssa_names : public gimple_opt_pass
+{
+public:
+ pass_release_ssa_names(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_release_ssa_names, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return release_dead_ssa_names (); }
+
+}; // class pass_release_ssa_names
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_release_ssa_names (gcc::context *ctxt)
+{
+ return new pass_release_ssa_names (ctxt);
+}
diff --git a/gcc/tree-stdarg.c b/gcc/tree-stdarg.c
index 8ad9fc2d22e..e4eb60ae042 100644
--- a/gcc/tree-stdarg.c
+++ b/gcc/tree-stdarg.c
@@ -105,7 +105,7 @@ reachable_at_most_once (basic_block va_arg_bb, basic_block va_start_bb)
/* For statement COUNTER = RHS, if RHS is COUNTER + constant,
- return constant, otherwise return (unsigned HOST_WIDE_INT) -1.
+ return constant, otherwise return HOST_WIDE_INT_M1U.
GPR_P is true if this is GPR counter. */
static unsigned HOST_WIDE_INT
@@ -149,7 +149,7 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
stmt = SSA_NAME_DEF_STMT (lhs);
if (!is_gimple_assign (stmt) || gimple_assign_lhs (stmt) != lhs)
- return (unsigned HOST_WIDE_INT) -1;
+ return HOST_WIDE_INT_M1U;
rhs_code = gimple_assign_rhs_code (stmt);
rhs1 = gimple_assign_rhs1 (stmt);
@@ -182,21 +182,21 @@ va_list_counter_bump (struct stdarg_info *si, tree counter, tree rhs,
}
if (get_gimple_rhs_class (rhs_code) != GIMPLE_SINGLE_RHS)
- return (unsigned HOST_WIDE_INT) -1;
+ return HOST_WIDE_INT_M1U;
rhs = gimple_assign_rhs1 (stmt);
if (TREE_CODE (counter) != TREE_CODE (rhs))
- return (unsigned HOST_WIDE_INT) -1;
+ return HOST_WIDE_INT_M1U;
if (TREE_CODE (counter) == COMPONENT_REF)
{
if (get_base_address (counter) != get_base_address (rhs)
|| TREE_CODE (TREE_OPERAND (rhs, 1)) != FIELD_DECL
|| TREE_OPERAND (counter, 1) != TREE_OPERAND (rhs, 1))
- return (unsigned HOST_WIDE_INT) -1;
+ return HOST_WIDE_INT_M1U;
}
else if (counter != rhs)
- return (unsigned HOST_WIDE_INT) -1;
+ return HOST_WIDE_INT_M1U;
lhs = NULL;
}
@@ -401,7 +401,7 @@ va_list_ptr_read (struct stdarg_info *si, tree ap, tree tem)
if (! si->compute_sizes)
return false;
- if (va_list_counter_bump (si, ap, tem, true) == (unsigned HOST_WIDE_INT) -1)
+ if (va_list_counter_bump (si, ap, tem, true) == HOST_WIDE_INT_M1U)
return false;
/* Note the temporary, as we need to track whether it doesn't escape
@@ -504,7 +504,7 @@ check_va_list_escapes (struct stdarg_info *si, tree lhs, tree rhs)
}
if (va_list_counter_bump (si, si->va_start_ap, lhs, true)
- == (unsigned HOST_WIDE_INT) -1)
+ == HOST_WIDE_INT_M1U)
{
si->va_list_escapes = true;
return;
@@ -985,22 +985,40 @@ finish:
}
-struct gimple_opt_pass pass_stdarg =
+namespace {
+
+const pass_data pass_data_stdarg =
{
- {
- GIMPLE_PASS,
- "stdarg", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_optimize_stdarg, /* gate */
- execute_optimize_stdarg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "stdarg", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_stdarg : public gimple_opt_pass
+{
+public:
+ pass_stdarg(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_stdarg, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_optimize_stdarg (); }
+ unsigned int execute () { return execute_optimize_stdarg (); }
+
+}; // class pass_stdarg
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_stdarg (gcc::context *ctxt)
+{
+ return new pass_stdarg (ctxt);
+}
diff --git a/gcc/tree-streamer-in.c b/gcc/tree-streamer-in.c
index 00f78a13df3..a86bcd87c1a 100644
--- a/gcc/tree-streamer-in.c
+++ b/gcc/tree-streamer-in.c
@@ -209,7 +209,6 @@ unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
if (TREE_CODE (expr) == LABEL_DECL)
{
- DECL_ERROR_ISSUED (expr) = (unsigned) bp_unpack_value (bp, 1);
EH_LANDING_PAD_NR (expr) = (int) bp_unpack_var_len_unsigned (bp);
/* Always assume an initial value of -1 for LABEL_DECL_UID to
@@ -258,7 +257,6 @@ unpack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
static void
unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
{
- DECL_DEFER_OUTPUT (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_COMMON (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_DLLIMPORT_P (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_WEAK (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -270,11 +268,16 @@ unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
if (TREE_CODE (expr) == VAR_DECL)
{
DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1);
- DECL_IN_TEXT_SECTION (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1);
DECL_TLS_MODEL (expr) = (enum tls_model) bp_unpack_value (bp, 3);
}
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ {
+ DECL_FINAL_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ DECL_CXX_CONSTRUCTOR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ DECL_CXX_DESTRUCTOR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ }
if (VAR_OR_FUNCTION_DECL_P (expr))
{
priority_type p;
@@ -346,7 +349,10 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_NEEDS_CONSTRUCTING (expr) = (unsigned) bp_unpack_value (bp, 1);
if (RECORD_OR_UNION_TYPE_P (expr))
- TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
+ {
+ TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
+ TYPE_FINAL_P (expr) = (unsigned) bp_unpack_value (bp, 1);
+ }
else if (TREE_CODE (expr) == ARRAY_TYPE)
TYPE_NONALIASED_COMPONENT (expr) = (unsigned) bp_unpack_value (bp, 1);
TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -678,12 +684,7 @@ static void
lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *ib,
struct data_in *data_in, tree expr)
{
- if (TREE_CODE (expr) == FUNCTION_DECL)
- {
- DECL_ARGUMENTS (expr) = streamer_read_chain (ib, data_in);
- DECL_RESULT (expr) = stream_read_tree (ib, data_in);
- }
- else if (TREE_CODE (expr) == TYPE_DECL)
+ if (TREE_CODE (expr) == TYPE_DECL)
DECL_ORIGINAL_TYPE (expr) = stream_read_tree (ib, data_in);
DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
}
@@ -928,10 +929,8 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
tree a = stream_read_tree (ib, data_in);
(*BINFO_BASE_ACCESSES (expr))[i] = a;
}
-
- BINFO_INHERITANCE_CHAIN (expr) = stream_read_tree (ib, data_in);
- BINFO_SUBVTT_INDEX (expr) = stream_read_tree (ib, data_in);
- BINFO_VPTR_INDEX (expr) = stream_read_tree (ib, data_in);
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
diff --git a/gcc/tree-streamer-out.c b/gcc/tree-streamer-out.c
index fa50ef5b7ad..942ba1ee44f 100644
--- a/gcc/tree-streamer-out.c
+++ b/gcc/tree-streamer-out.c
@@ -22,6 +22,7 @@ along with GCC; see the file COPYING3. If not see
#include "config.h"
#include "system.h"
#include "coretypes.h"
+#include "tm.h"
#include "diagnostic.h"
#include "tree.h"
#include "tree-streamer.h"
@@ -180,7 +181,6 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
/* Note that we do not write LABEL_DECL_UID. The reader will
always assume an initial value of -1 so that the
label_to_block_map is recreated by gimple_set_bb. */
- bp_pack_value (bp, DECL_ERROR_ISSUED (expr), 1);
bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr));
}
@@ -225,7 +225,6 @@ pack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
static void
pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
{
- bp_pack_value (bp, DECL_DEFER_OUTPUT (expr), 1);
bp_pack_value (bp, DECL_COMMON (expr), 1);
bp_pack_value (bp, DECL_DLLIMPORT_P (expr), 1);
bp_pack_value (bp, DECL_WEAK (expr), 1);
@@ -237,11 +236,17 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
if (TREE_CODE (expr) == VAR_DECL)
{
bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
- bp_pack_value (bp, DECL_IN_TEXT_SECTION (expr), 1);
+ /* DECL_IN_TEXT_SECTION is set during final asm output only. */
bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
bp_pack_value (bp, DECL_TLS_MODEL (expr), 3);
}
+ if (TREE_CODE (expr) == FUNCTION_DECL)
+ {
+ bp_pack_value (bp, DECL_FINAL_P (expr), 1);
+ bp_pack_value (bp, DECL_CXX_CONSTRUCTOR_P (expr), 1);
+ bp_pack_value (bp, DECL_CXX_DESTRUCTOR_P (expr), 1);
+ }
if (VAR_OR_FUNCTION_DECL_P (expr))
bp_pack_var_len_unsigned (bp, DECL_INIT_PRIORITY (expr));
}
@@ -293,7 +298,10 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1);
bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1);
if (RECORD_OR_UNION_TYPE_P (expr))
- bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
+ {
+ bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
+ bp_pack_value (bp, TYPE_FINAL_P (expr), 1);
+ }
else if (TREE_CODE (expr) == ARRAY_TYPE)
bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
bp_pack_value (bp, TYPE_PACKED (expr), 1);
@@ -606,12 +614,7 @@ static void
write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr,
bool ref_p)
{
- if (TREE_CODE (expr) == FUNCTION_DECL)
- {
- streamer_write_chain (ob, DECL_ARGUMENTS (expr), ref_p);
- stream_write_tree (ob, DECL_RESULT (expr), ref_p);
- }
- else if (TREE_CODE (expr) == TYPE_DECL)
+ if (TREE_CODE (expr) == TYPE_DECL)
stream_write_tree (ob, DECL_ORIGINAL_TYPE (expr), ref_p);
stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
}
@@ -820,9 +823,8 @@ write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (expr), i, t)
stream_write_tree (ob, t, ref_p);
- stream_write_tree (ob, BINFO_INHERITANCE_CHAIN (expr), ref_p);
- stream_write_tree (ob, BINFO_SUBVTT_INDEX (expr), ref_p);
- stream_write_tree (ob, BINFO_VPTR_INDEX (expr), ref_p);
+ /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
+ and BINFO_VPTR_INDEX; these are used by C++ FE only. */
}
diff --git a/gcc/tree-switch-conversion.c b/gcc/tree-switch-conversion.c
index 9ad7daf0689..0d128981e38 100644
--- a/gcc/tree-switch-conversion.c
+++ b/gcc/tree-switch-conversion.c
@@ -1463,25 +1463,42 @@ switchconv_gate (void)
return flag_tree_switch_conversion != 0;
}
-struct gimple_opt_pass pass_convert_switch =
+namespace {
+
+const pass_data pass_data_convert_switch =
{
- {
- GIMPLE_PASS,
- "switchconv", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- switchconv_gate, /* gate */
- do_switchconv, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SWITCH_CONVERSION, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa
- | TODO_verify_ssa
- | TODO_verify_stmts
- | TODO_verify_flow /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "switchconv", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SWITCH_CONVERSION, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa
+ | TODO_verify_stmts
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_convert_switch : public gimple_opt_pass
+{
+public:
+ pass_convert_switch(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_convert_switch, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return switchconv_gate (); }
+ unsigned int execute () { return do_switchconv (); }
+
+}; // class pass_convert_switch
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_convert_switch (gcc::context *ctxt)
+{
+ return new pass_convert_switch (ctxt);
+}
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c
index c6581dcedcd..289b75a09bc 100644
--- a/gcc/tree-tailcall.c
+++ b/gcc/tree-tailcall.c
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "target.h"
#include "cfgloop.h"
#include "common/common-target.h"
+#include "ipa-utils.h"
/* The file implements the tail recursion elimination. It is also used to
analyze the tail calls in general, passing the results to the rtl level
@@ -305,7 +306,7 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
if (rhs_class == GIMPLE_UNARY_RHS)
;
else if (op0 == *ass_var
- && (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
+ && (non_ass_var = independent_of_stmt_p (op1, stmt, call)))
;
else if (op1 == *ass_var
&& (non_ass_var = independent_of_stmt_p (op0, stmt, call)))
@@ -320,17 +321,20 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
*ass_var = dest;
return true;
+ case POINTER_PLUS_EXPR:
+ if (op0 != *ass_var)
+ return false;
+ *a = non_ass_var;
+ *ass_var = dest;
+ return true;
+
case MULT_EXPR:
*m = non_ass_var;
*ass_var = dest;
return true;
case NEGATE_EXPR:
- if (FLOAT_TYPE_P (TREE_TYPE (op0)))
- *m = build_real (TREE_TYPE (op0), dconstm1);
- else
- *m = build_int_cst (TREE_TYPE (op0), -1);
-
+ *m = build_minus_one_cst (TREE_TYPE (op0));
*ass_var = dest;
return true;
@@ -339,11 +343,7 @@ process_assignment (gimple stmt, gimple_stmt_iterator call, tree *m,
*a = fold_build1 (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var);
else
{
- if (FLOAT_TYPE_P (TREE_TYPE (non_ass_var)))
- *m = build_real (TREE_TYPE (non_ass_var), dconstm1);
- else
- *m = build_int_cst (TREE_TYPE (non_ass_var), -1);
-
+ *m = build_minus_one_cst (TREE_TYPE (non_ass_var));
*a = fold_build1 (NEGATE_EXPR, TREE_TYPE (non_ass_var), non_ass_var);
}
@@ -446,7 +446,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
/* We found the call, check whether it is suitable. */
tail_recursion = false;
func = gimple_call_fndecl (call);
- if (func == current_function_decl)
+ if (func && recursive_call_p (current_function_decl, func))
{
tree arg;
@@ -570,6 +570,10 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
if (!tail_recursion && (m || a))
return;
+ /* For pointers only allow additions. */
+ if (m && POINTER_TYPE_P (TREE_TYPE (DECL_RESULT (current_function_decl))))
+ return;
+
nw = XNEW (struct tailcall);
nw->call_gsi = gsi;
@@ -612,15 +616,23 @@ adjust_return_value_with_ops (enum tree_code code, const char *label,
tree result = make_temp_ssa_name (ret_type, NULL, label);
gimple stmt;
- if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1)))
+ if (POINTER_TYPE_P (ret_type))
+ {
+ gcc_assert (code == PLUS_EXPR && TREE_TYPE (acc) == sizetype);
+ code = POINTER_PLUS_EXPR;
+ }
+ if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1))
+ && code != POINTER_PLUS_EXPR)
stmt = gimple_build_assign_with_ops (code, result, acc, op1);
else
{
- tree rhs = fold_convert (TREE_TYPE (acc),
- fold_build2 (code,
- TREE_TYPE (op1),
- fold_convert (TREE_TYPE (op1), acc),
- op1));
+ tree tem;
+ if (code == POINTER_PLUS_EXPR)
+ tem = fold_build2 (code, TREE_TYPE (op1), op1, acc);
+ else
+ tem = fold_build2 (code, TREE_TYPE (op1),
+ fold_convert (TREE_TYPE (op1), acc), op1);
+ tree rhs = fold_convert (ret_type, tem);
rhs = force_gimple_operand_gsi (&gsi, rhs,
false, NULL, true, GSI_SAME_STMT);
stmt = gimple_build_assign (result, rhs);
@@ -900,6 +912,9 @@ static tree
create_tailcall_accumulator (const char *label, basic_block bb, tree init)
{
tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
+ if (POINTER_TYPE_P (ret_type))
+ ret_type = sizetype;
+
tree tmp = make_temp_ssa_name (ret_type, NULL, label);
gimple phi;
@@ -1048,42 +1063,79 @@ execute_tail_calls (void)
return tree_optimize_tail_calls_1 (true);
}
-struct gimple_opt_pass pass_tail_recursion =
+namespace {
+
+const pass_data pass_data_tail_recursion =
{
- {
- GIMPLE_PASS,
- "tailr", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tail_calls, /* gate */
- execute_tail_recursion, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "tailr", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
-struct gimple_opt_pass pass_tail_calls =
+class pass_tail_recursion : public gimple_opt_pass
+{
+public:
+ pass_tail_recursion(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tail_recursion, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_tail_recursion (ctxt_); }
+ bool gate () { return gate_tail_calls (); }
+ unsigned int execute () { return execute_tail_recursion (); }
+
+}; // class pass_tail_recursion
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tail_recursion (gcc::context *ctxt)
{
- {
- GIMPLE_PASS,
- "tailc", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_tail_calls, /* gate */
- execute_tail_calls, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg | PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa /* todo_flags_finish */
- }
+ return new pass_tail_recursion (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_tail_calls =
+{
+ GIMPLE_PASS, /* type */
+ "tailc", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_verify_ssa, /* todo_flags_finish */
};
+
+class pass_tail_calls : public gimple_opt_pass
+{
+public:
+ pass_tail_calls(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tail_calls, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tail_calls (); }
+ unsigned int execute () { return execute_tail_calls (); }
+
+}; // class pass_tail_calls
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tail_calls (gcc::context *ctxt)
+{
+ return new pass_tail_calls (ctxt);
+}
diff --git a/gcc/tree-vect-data-refs.c b/gcc/tree-vect-data-refs.c
index 4e99747b73c..230e302acf6 100644
--- a/gcc/tree-vect-data-refs.c
+++ b/gcc/tree-vect-data-refs.c
@@ -37,7 +37,6 @@ along with GCC; see the file COPYING3. If not see
#include "tree-scalar-evolution.h"
#include "tree-vectorizer.h"
#include "diagnostic-core.h"
-
/* Need to include rtl.h, expr.h, etc. for optabs. */
#include "expr.h"
#include "optabs.h"
@@ -255,6 +254,15 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
/* Unknown data dependence. */
if (DDR_ARE_DEPENDENT (ddr) == chrec_dont_know)
{
+ /* If user asserted safelen consecutive iterations can be
+ executed concurrently, assume independence. */
+ if (loop->safelen >= 2)
+ {
+ if (loop->safelen < *max_vf)
+ *max_vf = loop->safelen;
+ return false;
+ }
+
if (STMT_VINFO_GATHER_P (stmtinfo_a)
|| STMT_VINFO_GATHER_P (stmtinfo_b))
{
@@ -291,6 +299,15 @@ vect_analyze_data_ref_dependence (struct data_dependence_relation *ddr,
/* Known data dependence. */
if (DDR_NUM_DIST_VECTS (ddr) == 0)
{
+ /* If user asserted safelen consecutive iterations can be
+ executed concurrently, assume independence. */
+ if (loop->safelen >= 2)
+ {
+ if (loop->safelen < *max_vf)
+ *max_vf = loop->safelen;
+ return false;
+ }
+
if (STMT_VINFO_GATHER_P (stmtinfo_a)
|| STMT_VINFO_GATHER_P (stmtinfo_b))
{
@@ -746,15 +763,10 @@ vect_compute_data_ref_alignment (struct data_reference *dr)
dump_generic_expr (MSG_NOTE, TDF_SLIM, ref);
}
- DECL_ALIGN (base) = TYPE_ALIGN (vectype);
- DECL_USER_ALIGN (base) = 1;
+ ((dataref_aux *)dr->aux)->base_decl = base;
+ ((dataref_aux *)dr->aux)->base_misaligned = true;
}
- /* At this point we assume that the base is aligned. */
- gcc_assert (base_aligned
- || (TREE_CODE (base) == VAR_DECL
- && DECL_ALIGN (base) >= TYPE_ALIGN (vectype)));
-
/* If this is a backward running DR then first access in the larger
vectype actually is N-1 elements before the address in the DR.
Adjust misalign accordingly. */
@@ -2254,10 +2266,17 @@ vect_analyze_data_ref_access (struct data_reference *dr)
return false;
}
- /* Allow invariant loads in loops. */
+ /* Allow invariant loads in not nested loops. */
if (loop_vinfo && integer_zerop (step))
{
GROUP_FIRST_ELEMENT (vinfo_for_stmt (stmt)) = NULL;
+ if (nested_in_vect_loop_p (loop, stmt))
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_NOTE, vect_location,
+ "zero step in inner loop of nest");
+ return false;
+ }
return DR_IS_READ (dr);
}
@@ -2930,6 +2949,7 @@ vect_analyze_data_refs (loop_vec_info loop_vinfo,
stmt_vec_info stmt_info;
tree base, offset, init;
bool gather = false;
+ bool simd_lane_access = false;
int vf;
again:
@@ -2961,12 +2981,17 @@ again:
if (!DR_BASE_ADDRESS (dr) || !DR_OFFSET (dr) || !DR_INIT (dr)
|| !DR_STEP (dr))
{
- /* If target supports vector gather loads, see if they can't
- be used. */
- if (loop_vinfo
- && DR_IS_READ (dr)
+ bool maybe_gather
+ = DR_IS_READ (dr)
&& !TREE_THIS_VOLATILE (DR_REF (dr))
- && targetm.vectorize.builtin_gather != NULL
+ && targetm.vectorize.builtin_gather != NULL;
+ bool maybe_simd_lane_access
+ = loop_vinfo && loop->simduid;
+
+ /* If target supports vector gather loads, or if this might be
+ a SIMD lane access, see if they can't be used. */
+ if (loop_vinfo
+ && (maybe_gather || maybe_simd_lane_access)
&& !nested_in_vect_loop_p (loop, stmt))
{
struct data_reference *newdr
@@ -2979,14 +3004,59 @@ again:
&& DR_STEP (newdr)
&& integer_zerop (DR_STEP (newdr)))
{
- dr = newdr;
- gather = true;
+ if (maybe_simd_lane_access)
+ {
+ tree off = DR_OFFSET (newdr);
+ STRIP_NOPS (off);
+ if (TREE_CODE (DR_INIT (newdr)) == INTEGER_CST
+ && TREE_CODE (off) == MULT_EXPR
+ && host_integerp (TREE_OPERAND (off, 1), 1))
+ {
+ tree step = TREE_OPERAND (off, 1);
+ off = TREE_OPERAND (off, 0);
+ STRIP_NOPS (off);
+ if (CONVERT_EXPR_P (off)
+ && TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (off,
+ 0)))
+ < TYPE_PRECISION (TREE_TYPE (off)))
+ off = TREE_OPERAND (off, 0);
+ if (TREE_CODE (off) == SSA_NAME)
+ {
+ gimple def = SSA_NAME_DEF_STMT (off);
+ tree reft = TREE_TYPE (DR_REF (newdr));
+ if (gimple_call_internal_p (def)
+ && gimple_call_internal_fn (def)
+ == IFN_GOMP_SIMD_LANE)
+ {
+ tree arg = gimple_call_arg (def, 0);
+ gcc_assert (TREE_CODE (arg) == SSA_NAME);
+ arg = SSA_NAME_VAR (arg);
+ if (arg == loop->simduid
+ /* For now. */
+ && tree_int_cst_equal
+ (TYPE_SIZE_UNIT (reft),
+ step))
+ {
+ DR_OFFSET (newdr) = ssize_int (0);
+ DR_STEP (newdr) = step;
+ dr = newdr;
+ simd_lane_access = true;
+ }
+ }
+ }
+ }
+ }
+ if (!simd_lane_access && maybe_gather)
+ {
+ dr = newdr;
+ gather = true;
+ }
}
- else
+ if (!gather && !simd_lane_access)
free_data_ref (newdr);
}
- if (!gather)
+ if (!gather && !simd_lane_access)
{
if (dump_enabled_p ())
{
@@ -3013,7 +3083,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
@@ -3046,7 +3116,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
@@ -3065,7 +3135,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
@@ -3086,7 +3156,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
@@ -3221,12 +3291,17 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
free_data_ref (dr);
return false;
}
STMT_VINFO_DATA_REF (stmt_info) = dr;
+ if (simd_lane_access)
+ {
+ STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info) = true;
+ datarefs[i] = dr;
+ }
/* Set vectype for STMT. */
scalar_type = TREE_TYPE (DR_REF (dr));
@@ -3247,7 +3322,7 @@ again:
if (bb_vinfo)
break;
- if (gather)
+ if (gather || simd_lane_access)
{
STMT_VINFO_DATA_REF (stmt_info) = NULL;
free_data_ref (dr);
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 516bd6f954c..b2a6944687c 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -1454,50 +1454,86 @@ expand_vector_operations (void)
return cfg_changed ? TODO_cleanup_cfg : 0;
}
-struct gimple_opt_pass pass_lower_vector =
+namespace {
+
+const pass_data pass_data_lower_vector =
{
- {
- GIMPLE_PASS,
- "veclower", /* name */
- OPTGROUP_VEC, /* optinfo_flags */
- gate_expand_vector_operations_ssa, /* gate */
- expand_vector_operations, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- PROP_gimple_lvec, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa /* todo_flags_finish */
- | TODO_verify_ssa
- | TODO_verify_stmts | TODO_verify_flow
- | TODO_cleanup_cfg
- }
+ GIMPLE_PASS, /* type */
+ "veclower", /* name */
+ OPTGROUP_VEC, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ PROP_gimple_lvec, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa
+ | TODO_verify_stmts
+ | TODO_verify_flow
+ | TODO_cleanup_cfg ), /* todo_flags_finish */
};
-struct gimple_opt_pass pass_lower_vector_ssa =
+class pass_lower_vector : public gimple_opt_pass
+{
+public:
+ pass_lower_vector(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_vector, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_expand_vector_operations_ssa (); }
+ unsigned int execute () { return expand_vector_operations (); }
+
+}; // class pass_lower_vector
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_vector (gcc::context *ctxt)
+{
+ return new pass_lower_vector (ctxt);
+}
+
+namespace {
+
+const pass_data pass_data_lower_vector_ssa =
{
- {
- GIMPLE_PASS,
- "veclower2", /* name */
- OPTGROUP_VEC, /* optinfo_flags */
- 0, /* gate */
- expand_vector_operations, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_cfg, /* properties_required */
- PROP_gimple_lvec, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_update_ssa /* todo_flags_finish */
- | TODO_verify_ssa
- | TODO_verify_stmts | TODO_verify_flow
- | TODO_cleanup_cfg
- }
+ GIMPLE_PASS, /* type */
+ "veclower2", /* name */
+ OPTGROUP_VEC, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ PROP_cfg, /* properties_required */
+ PROP_gimple_lvec, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_update_ssa | TODO_verify_ssa
+ | TODO_verify_stmts
+ | TODO_verify_flow
+ | TODO_cleanup_cfg ), /* todo_flags_finish */
};
+class pass_lower_vector_ssa : public gimple_opt_pass
+{
+public:
+ pass_lower_vector_ssa(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_lower_vector_ssa, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_lower_vector_ssa (ctxt_); }
+ unsigned int execute () { return expand_vector_operations (); }
+
+}; // class pass_lower_vector_ssa
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_lower_vector_ssa (gcc::context *ctxt)
+{
+ return new pass_lower_vector_ssa (ctxt);
+}
+
#include "gt-tree-vect-generic.h"
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index 12f70ee002a..2bebdeab34c 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -2021,8 +2021,9 @@ vect_do_peeling_for_alignment (loop_vec_info loop_vinfo,
int bound = 0;
if (dump_enabled_p ())
- dump_printf_loc (MSG_NOTE, vect_location,
- "=== vect_do_peeling_for_alignment ===");
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "loop peeled for vectorization to enhance"
+ " alignment\n");
initialize_original_copy_tables ();
@@ -2404,6 +2405,8 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
unsigned prob = 4 * REG_BR_PROB_BASE / 5;
gimple_seq gimplify_stmt_list = NULL;
tree scalar_loop_iters = LOOP_VINFO_NITERS (loop_vinfo);
+ bool version_align = LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo);
+ bool version_alias = LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo);
if (check_profitability)
{
@@ -2413,11 +2416,11 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
is_gimple_condexpr, NULL_TREE);
}
- if (LOOP_REQUIRES_VERSIONING_FOR_ALIGNMENT (loop_vinfo))
+ if (version_align)
vect_create_cond_for_align_checks (loop_vinfo, &cond_expr,
&cond_expr_stmt_list);
- if (LOOP_REQUIRES_VERSIONING_FOR_ALIAS (loop_vinfo))
+ if (version_alias)
vect_create_cond_for_alias_checks (loop_vinfo, &cond_expr);
cond_expr = force_gimple_operand_1 (cond_expr, &gimplify_stmt_list,
@@ -2427,6 +2430,20 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
initialize_original_copy_tables ();
loop_version (loop, cond_expr, &condition_bb,
prob, prob, REG_BR_PROB_BASE - prob, true);
+
+ if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC
+ && dump_enabled_p ())
+ {
+ if (version_alias)
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "loop versioned for vectorization because of "
+ "possible aliasing\n");
+ if (version_align)
+ dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
+ "loop versioned for vectorization to enhance "
+ "alignment\n");
+
+ }
free_original_copy_tables();
/* Loop versioning violates an assumption we try to maintain during
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 41eac972a97..9b4b1892984 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -957,7 +957,7 @@ destroy_loop_vec_info (loop_vec_info loop_vinfo, bool clean_stmts)
}
free (LOOP_VINFO_BBS (loop_vinfo));
- free_data_refs (LOOP_VINFO_DATAREFS (loop_vinfo));
+ vect_destroy_datarefs (loop_vinfo, NULL);
free_dependence_relations (LOOP_VINFO_DDRS (loop_vinfo));
LOOP_VINFO_LOOP_NEST (loop_vinfo).release ();
LOOP_VINFO_MAY_MISALIGN_STMTS (loop_vinfo).release ();
@@ -1384,7 +1384,7 @@ vect_analyze_loop_operations (loop_vec_info loop_vinfo, bool slp)
return false;
op_def_stmt = SSA_NAME_DEF_STMT (phi_op);
- if (!op_def_stmt
+ if (gimple_nop_p (op_def_stmt)
|| !flow_bb_inside_loop_p (loop, gimple_bb (op_def_stmt))
|| !vinfo_for_stmt (op_def_stmt))
return false;
@@ -3133,7 +3133,6 @@ get_initial_def_for_induction (gimple iv_phi)
stmt_vec_info stmt_vinfo = vinfo_for_stmt (iv_phi);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_vinfo);
struct loop *loop = LOOP_VINFO_LOOP (loop_vinfo);
- tree scalar_type;
tree vectype;
int nunits;
edge pe = loop_preheader_edge (loop);
@@ -3185,8 +3184,7 @@ get_initial_def_for_induction (gimple iv_phi)
gcc_assert (ok);
pe = loop_preheader_edge (iv_loop);
- scalar_type = TREE_TYPE (init_expr);
- vectype = get_vectype_for_scalar_type (scalar_type);
+ vectype = get_vectype_for_scalar_type (TREE_TYPE (init_expr));
resvectype = get_vectype_for_scalar_type (TREE_TYPE (PHI_RESULT (iv_phi)));
gcc_assert (vectype);
nunits = TYPE_VECTOR_SUBPARTS (vectype);
@@ -3229,8 +3227,11 @@ get_initial_def_for_induction (gimple iv_phi)
/* iv_loop is the loop to be vectorized. Create:
vec_init = [X, X+S, X+2*S, X+3*S] (S = step_expr, X = init_expr) */
- new_var = vect_get_new_vect_var (scalar_type, vect_scalar_var, "var_");
- new_name = force_gimple_operand (init_expr, &stmts, false, new_var);
+ new_var = vect_get_new_vect_var (TREE_TYPE (vectype),
+ vect_scalar_var, "var_");
+ new_name = force_gimple_operand (fold_convert (TREE_TYPE (vectype),
+ init_expr),
+ &stmts, false, new_var);
if (stmts)
{
new_bb = gsi_insert_seq_on_edge_immediate (pe, stmts);
@@ -3243,9 +3244,8 @@ get_initial_def_for_induction (gimple iv_phi)
for (i = 1; i < nunits; i++)
{
/* Create: new_name_i = new_name + step_expr */
- enum tree_code code = POINTER_TYPE_P (scalar_type)
- ? POINTER_PLUS_EXPR : PLUS_EXPR;
- new_name = fold_build2 (code, scalar_type, new_name, step_expr);
+ new_name = fold_build2 (PLUS_EXPR, TREE_TYPE (new_name),
+ new_name, step_expr);
if (!is_gimple_min_invariant (new_name))
{
init_stmt = gimple_build_assign (new_var, new_name);
@@ -4373,9 +4373,8 @@ vect_finalize_reduction:
if (!flow_bb_inside_loop_p (loop, gimple_bb (USE_STMT (use_p))))
phis.safe_push (USE_STMT (use_p));
- /* We expect to have found an exit_phi because of loop-closed-ssa
- form. */
- gcc_assert (!phis.is_empty ());
+ /* While we expect to have found an exit_phi because of loop-closed-ssa
+ form we can end up without one if the scalar cycle is dead. */
FOR_EACH_VEC_ELT (phis, i, exit_phi)
{
@@ -5378,7 +5377,7 @@ vectorizable_induction (gimple phi, gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
bool
vectorizable_live_operation (gimple stmt,
gimple_stmt_iterator *gsi ATTRIBUTE_UNUSED,
- gimple *vec_stmt ATTRIBUTE_UNUSED)
+ gimple *vec_stmt)
{
stmt_vec_info stmt_info = vinfo_for_stmt (stmt);
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
@@ -5398,7 +5397,41 @@ vectorizable_live_operation (gimple stmt,
return false;
if (!is_gimple_assign (stmt))
- return false;
+ {
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE
+ && gimple_call_lhs (stmt)
+ && loop->simduid
+ && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME
+ && loop->simduid
+ == SSA_NAME_VAR (gimple_call_arg (stmt, 0)))
+ {
+ edge e = single_exit (loop);
+ basic_block merge_bb = e->dest;
+ imm_use_iterator imm_iter;
+ use_operand_p use_p;
+ tree lhs = gimple_call_lhs (stmt);
+
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
+ {
+ gimple use_stmt = USE_STMT (use_p);
+ if (gimple_code (use_stmt) == GIMPLE_PHI
+ || gimple_bb (use_stmt) == merge_bb)
+ {
+ if (vec_stmt)
+ {
+ tree vfm1
+ = build_int_cst (unsigned_type_node,
+ loop_vinfo->vectorization_factor - 1);
+ SET_PHI_ARG_DEF (use_stmt, e->dest_idx, vfm1);
+ }
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
if (TREE_CODE (gimple_assign_lhs (stmt)) != SSA_NAME)
return false;
diff --git a/gcc/tree-vect-slp.c b/gcc/tree-vect-slp.c
index ea8c202d187..4217f2be54c 100644
--- a/gcc/tree-vect-slp.c
+++ b/gcc/tree-vect-slp.c
@@ -1825,7 +1825,7 @@ destroy_bb_vec_info (bb_vec_info bb_vinfo)
free_stmt_vec_info (stmt);
}
- free_data_refs (BB_VINFO_DATAREFS (bb_vinfo));
+ vect_destroy_datarefs (NULL, bb_vinfo);
free_dependence_relations (BB_VINFO_DDRS (bb_vinfo));
BB_VINFO_GROUPED_STORES (bb_vinfo).release ();
slp_instances = BB_VINFO_SLP_INSTANCES (bb_vinfo);
diff --git a/gcc/tree-vect-stmts.c b/gcc/tree-vect-stmts.c
index 0580f7dfadc..bc4ea1e3097 100644
--- a/gcc/tree-vect-stmts.c
+++ b/gcc/tree-vect-stmts.c
@@ -1755,6 +1755,14 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
if (nargs == 0 || nargs > 3)
return false;
+ /* Ignore the argument of IFN_GOMP_SIMD_LANE, it is magic. */
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
+ {
+ nargs = 0;
+ rhs_type = unsigned_type_node;
+ }
+
for (i = 0; i < nargs; i++)
{
tree opvectype;
@@ -1830,11 +1838,26 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
fndecl = vectorizable_function (stmt, vectype_out, vectype_in);
if (fndecl == NULL_TREE)
{
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "function is not vectorizable.");
-
- return false;
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE
+ && !slp_node
+ && loop_vinfo
+ && LOOP_VINFO_LOOP (loop_vinfo)->simduid
+ && TREE_CODE (gimple_call_arg (stmt, 0)) == SSA_NAME
+ && LOOP_VINFO_LOOP (loop_vinfo)->simduid
+ == SSA_NAME_VAR (gimple_call_arg (stmt, 0)))
+ {
+ /* We can handle IFN_GOMP_SIMD_LANE by returning a
+ { 0, 1, 2, ... vf - 1 } vector. */
+ gcc_assert (nargs == 0);
+ }
+ else
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "function is not vectorizable.");
+ return false;
+ }
}
gcc_assert (!gimple_vuse (stmt));
@@ -1932,9 +1955,30 @@ vectorizable_call (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
vargs.quick_push (vec_oprnd0);
}
- new_stmt = gimple_build_call_vec (fndecl, vargs);
- new_temp = make_ssa_name (vec_dest, new_stmt);
- gimple_call_set_lhs (new_stmt, new_temp);
+ if (gimple_call_internal_p (stmt)
+ && gimple_call_internal_fn (stmt) == IFN_GOMP_SIMD_LANE)
+ {
+ tree *v = XALLOCAVEC (tree, nunits_out);
+ int k;
+ for (k = 0; k < nunits_out; ++k)
+ v[k] = build_int_cst (unsigned_type_node, j * nunits_out + k);
+ tree cst = build_vector (vectype_out, v);
+ tree new_var
+ = vect_get_new_vect_var (vectype_out, vect_simple_var, "cst_");
+ gimple init_stmt = gimple_build_assign (new_var, cst);
+ new_temp = make_ssa_name (new_var, init_stmt);
+ gimple_assign_set_lhs (init_stmt, new_temp);
+ vect_init_vector_1 (stmt, init_stmt, NULL);
+ new_temp = make_ssa_name (vec_dest, NULL);
+ new_stmt = gimple_build_assign (new_temp,
+ gimple_assign_lhs (init_stmt));
+ }
+ else
+ {
+ new_stmt = gimple_build_call_vec (fndecl, vargs);
+ new_temp = make_ssa_name (vec_dest, new_stmt);
+ gimple_call_set_lhs (new_stmt, new_temp);
+ }
vect_finish_stmt_generation (stmt, new_stmt, gsi);
if (j == 0)
@@ -3765,6 +3809,26 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
return true;
}
+/* A helper function to ensure data reference DR's base alignment
+ for STMT_INFO. */
+
+static void
+ensure_base_align (stmt_vec_info stmt_info, struct data_reference *dr)
+{
+ if (!dr->aux)
+ return;
+
+ if (((dataref_aux *)dr->aux)->base_misaligned)
+ {
+ tree vectype = STMT_VINFO_VECTYPE (stmt_info);
+ tree base_decl = ((dataref_aux *)dr->aux)->base_decl;
+
+ DECL_ALIGN (base_decl) = TYPE_ALIGN (vectype);
+ DECL_USER_ALIGN (base_decl) = 1;
+ ((dataref_aux *)dr->aux)->base_misaligned = false;
+ }
+}
+
/* Function vectorizable_store.
@@ -3776,7 +3840,7 @@ vectorizable_operation (gimple stmt, gimple_stmt_iterator *gsi,
static bool
vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
- slp_tree slp_node)
+ slp_tree slp_node)
{
tree scalar_dest;
tree data_ref;
@@ -3796,6 +3860,7 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
enum vect_def_type dt;
stmt_vec_info prev_stmt_info = NULL;
tree dataref_ptr = NULL_TREE;
+ tree dataref_offset = NULL_TREE;
gimple ptr_incr = NULL;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies;
@@ -3937,6 +4002,8 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
/** Transform. **/
+ ensure_base_align (stmt_info, dr);
+
if (grouped_store)
{
first_dr = STMT_VINFO_DATA_REF (vinfo_for_stmt (first_stmt));
@@ -4085,9 +4152,26 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
/* We should have catched mismatched types earlier. */
gcc_assert (useless_type_conversion_p (vectype,
TREE_TYPE (vec_oprnd)));
- dataref_ptr = vect_create_data_ref_ptr (first_stmt, aggr_type, NULL,
- NULL_TREE, &dummy, gsi,
- &ptr_incr, false, &inv_p);
+ bool simd_lane_access_p
+ = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info);
+ if (simd_lane_access_p
+ && TREE_CODE (DR_BASE_ADDRESS (first_dr)) == ADDR_EXPR
+ && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr), 0))
+ && integer_zerop (DR_OFFSET (first_dr))
+ && integer_zerop (DR_INIT (first_dr))
+ && alias_sets_conflict_p (get_alias_set (aggr_type),
+ get_alias_set (DR_REF (first_dr))))
+ {
+ dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr));
+ dataref_offset = build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0);
+ }
+ else
+ dataref_ptr
+ = vect_create_data_ref_ptr (first_stmt, aggr_type,
+ simd_lane_access_p ? loop : NULL,
+ NULL_TREE, &dummy, gsi, &ptr_incr,
+ simd_lane_access_p, &inv_p);
gcc_assert (bb_vinfo || !inv_p);
}
else
@@ -4108,8 +4192,13 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
dr_chain[i] = vec_oprnd;
oprnds[i] = vec_oprnd;
}
- dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
- TYPE_SIZE_UNIT (aggr_type));
+ if (dataref_offset)
+ dataref_offset
+ = int_const_binop (PLUS_EXPR, dataref_offset,
+ TYPE_SIZE_UNIT (aggr_type));
+ else
+ dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
+ TYPE_SIZE_UNIT (aggr_type));
}
if (store_lanes_p)
@@ -4161,8 +4250,10 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
vec_oprnd = result_chain[i];
data_ref = build2 (MEM_REF, TREE_TYPE (vec_oprnd), dataref_ptr,
- build_int_cst (reference_alias_ptr_type
- (DR_REF (first_dr)), 0));
+ dataref_offset
+ ? dataref_offset
+ : build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
align = TYPE_ALIGN_UNIT (vectype);
if (aligned_access_p (first_dr))
misalign = 0;
@@ -4181,8 +4272,9 @@ vectorizable_store (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
TYPE_ALIGN (elem_type));
misalign = DR_MISALIGNMENT (first_dr);
}
- set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
- misalign);
+ if (dataref_offset == NULL_TREE)
+ set_ptr_info_alignment (get_ptr_info (dataref_ptr), align,
+ misalign);
/* Arguments are ready. Create the new vector stmt. */
new_stmt = gimple_build_assign (data_ref, vec_oprnd);
@@ -4294,7 +4386,7 @@ permute_vec_elements (tree x, tree y, tree mask_vec, gimple stmt,
static bool
vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
- slp_tree slp_node, slp_instance slp_node_instance)
+ slp_tree slp_node, slp_instance slp_node_instance)
{
tree scalar_dest;
tree vec_dest = NULL;
@@ -4305,7 +4397,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
struct loop *loop = NULL;
struct loop *containing_loop = (gimple_bb (stmt))->loop_father;
bool nested_in_vect_loop = false;
- struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr;
+ struct data_reference *dr = STMT_VINFO_DATA_REF (stmt_info), *first_dr = NULL;
tree vectype = STMT_VINFO_VECTYPE (stmt_info);
tree elem_type;
tree new_temp;
@@ -4314,6 +4406,7 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
tree dummy;
enum dr_alignment_support alignment_support_scheme;
tree dataref_ptr = NULL_TREE;
+ tree dataref_offset = NULL_TREE;
gimple ptr_incr = NULL;
int nunits = TYPE_VECTOR_SUBPARTS (vectype);
int ncopies;
@@ -4504,6 +4597,8 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
/** Transform. **/
+ ensure_base_align (stmt_info, dr);
+
if (STMT_VINFO_GATHER_P (stmt_info))
{
tree vec_oprnd0 = NULL_TREE, op;
@@ -4947,9 +5042,32 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
{
/* 1. Create the vector or array pointer update chain. */
if (j == 0)
- dataref_ptr = vect_create_data_ref_ptr (first_stmt, aggr_type, at_loop,
- offset, &dummy, gsi,
- &ptr_incr, false, &inv_p);
+ {
+ bool simd_lane_access_p
+ = STMT_VINFO_SIMD_LANE_ACCESS_P (stmt_info);
+ if (simd_lane_access_p
+ && TREE_CODE (DR_BASE_ADDRESS (first_dr)) == ADDR_EXPR
+ && VAR_P (TREE_OPERAND (DR_BASE_ADDRESS (first_dr), 0))
+ && integer_zerop (DR_OFFSET (first_dr))
+ && integer_zerop (DR_INIT (first_dr))
+ && alias_sets_conflict_p (get_alias_set (aggr_type),
+ get_alias_set (DR_REF (first_dr)))
+ && (alignment_support_scheme == dr_aligned
+ || alignment_support_scheme == dr_unaligned_supported))
+ {
+ dataref_ptr = unshare_expr (DR_BASE_ADDRESS (first_dr));
+ dataref_offset = build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0);
+ }
+ else
+ dataref_ptr
+ = vect_create_data_ref_ptr (first_stmt, aggr_type, at_loop,
+ offset, &dummy, gsi, &ptr_incr,
+ simd_lane_access_p, &inv_p);
+ }
+ else if (dataref_offset)
+ dataref_offset = int_const_binop (PLUS_EXPR, dataref_offset,
+ TYPE_SIZE_UNIT (aggr_type));
else
dataref_ptr = bump_vector_ptr (dataref_ptr, ptr_incr, gsi, stmt,
TYPE_SIZE_UNIT (aggr_type));
@@ -4999,8 +5117,10 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
data_ref
= build2 (MEM_REF, vectype, dataref_ptr,
- build_int_cst (reference_alias_ptr_type
- (DR_REF (first_dr)), 0));
+ dataref_offset
+ ? dataref_offset
+ : build_int_cst (reference_alias_ptr_type
+ (DR_REF (first_dr)), 0));
align = TYPE_ALIGN_UNIT (vectype);
if (alignment_support_scheme == dr_aligned)
{
@@ -5022,8 +5142,9 @@ vectorizable_load (gimple stmt, gimple_stmt_iterator *gsi, gimple *vec_stmt,
TYPE_ALIGN (elem_type));
misalign = DR_MISALIGNMENT (first_dr);
}
- set_ptr_info_alignment (get_ptr_info (dataref_ptr),
- align, misalign);
+ if (dataref_offset == NULL_TREE)
+ set_ptr_info_alignment (get_ptr_info (dataref_ptr),
+ align, misalign);
break;
}
case dr_explicit_realign:
@@ -6082,8 +6203,7 @@ get_vectype_for_scalar_type_and_size (tree scalar_type, unsigned size)
corresponding to that mode. The theory is that any use that
would cause problems with this will disable vectorization anyway. */
else if (!SCALAR_FLOAT_TYPE_P (scalar_type)
- && !INTEGRAL_TYPE_P (scalar_type)
- && !POINTER_TYPE_P (scalar_type))
+ && !INTEGRAL_TYPE_P (scalar_type))
scalar_type = lang_hooks.types.type_for_mode (inner_mode, 1);
/* We can't build a vector type of elements with alignment bigger than
diff --git a/gcc/tree-vectorizer.c b/gcc/tree-vectorizer.c
index 1ef31eefd1d..575cb756245 100644
--- a/gcc/tree-vectorizer.c
+++ b/gcc/tree-vectorizer.c
@@ -66,14 +66,245 @@ along with GCC; see the file COPYING3. If not see
#include "cfgloop.h"
#include "tree-vectorizer.h"
#include "tree-pass.h"
+#include "hash-table.h"
+#include "tree-ssa-propagate.h"
+#include "dbgcnt.h"
/* Loop or bb location. */
LOC vect_location;
/* Vector mapping GIMPLE stmt to stmt_vec_info. */
vec<vec_void_p> stmt_vec_info_vec;
+
+/* For mapping simduid to vectorization factor. */
+
+struct simduid_to_vf : typed_free_remove<simduid_to_vf>
+{
+ unsigned int simduid;
+ int vf;
+
+ /* hash_table support. */
+ typedef simduid_to_vf value_type;
+ typedef simduid_to_vf compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline int equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+simduid_to_vf::hash (const value_type *p)
+{
+ return p->simduid;
+}
+
+inline int
+simduid_to_vf::equal (const value_type *p1, const value_type *p2)
+{
+ return p1->simduid == p2->simduid;
+}
+
+/* This hash maps the OMP simd array to the corresponding simduid used
+ to index into it. Like thus,
+
+ _7 = GOMP_SIMD_LANE (simduid.0)
+ ...
+ ...
+ D.1737[_7] = stuff;
+
+
+ This hash maps from the simduid.0 to OMP simd array (D.1737[]). */
+
+struct simd_array_to_simduid : typed_free_remove<simd_array_to_simduid>
+{
+ tree decl;
+ unsigned int simduid;
+
+ /* hash_table support. */
+ typedef simd_array_to_simduid value_type;
+ typedef simd_array_to_simduid compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline int equal (const value_type *, const compare_type *);
+};
+
+inline hashval_t
+simd_array_to_simduid::hash (const value_type *p)
+{
+ return DECL_UID (p->decl);
+}
+
+inline int
+simd_array_to_simduid::equal (const value_type *p1, const value_type *p2)
+{
+ return p1->decl == p2->decl;
+}
+
+/* Fold IFN_GOMP_SIMD_LANE, IFN_GOMP_SIMD_VF and IFN_GOMP_SIMD_LAST_LANE
+ into their corresponding constants. */
+
+static void
+adjust_simduid_builtins (hash_table <simduid_to_vf> &htab)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ gimple_stmt_iterator i;
+
+ for (i = gsi_start_bb (bb); !gsi_end_p (i); gsi_next (&i))
+ {
+ unsigned int vf = 1;
+ enum internal_fn ifn;
+ gimple stmt = gsi_stmt (i);
+ tree t;
+ if (!is_gimple_call (stmt)
+ || !gimple_call_internal_p (stmt))
+ continue;
+ ifn = gimple_call_internal_fn (stmt);
+ switch (ifn)
+ {
+ case IFN_GOMP_SIMD_LANE:
+ case IFN_GOMP_SIMD_VF:
+ case IFN_GOMP_SIMD_LAST_LANE:
+ break;
+ default:
+ continue;
+ }
+ tree arg = gimple_call_arg (stmt, 0);
+ gcc_assert (arg != NULL_TREE);
+ gcc_assert (TREE_CODE (arg) == SSA_NAME);
+ simduid_to_vf *p = NULL, data;
+ data.simduid = DECL_UID (SSA_NAME_VAR (arg));
+ if (htab.is_created ())
+ p = htab.find (&data);
+ if (p)
+ vf = p->vf;
+ switch (ifn)
+ {
+ case IFN_GOMP_SIMD_VF:
+ t = build_int_cst (unsigned_type_node, vf);
+ break;
+ case IFN_GOMP_SIMD_LANE:
+ t = build_int_cst (unsigned_type_node, 0);
+ break;
+ case IFN_GOMP_SIMD_LAST_LANE:
+ t = gimple_call_arg (stmt, 1);
+ break;
+ default:
+ gcc_unreachable ();
+ }
+ update_call_from_tree (&i, t);
+ }
+ }
+}
+
+/* Helper structure for note_simd_array_uses. */
+
+struct note_simd_array_uses_struct
+{
+ hash_table <simd_array_to_simduid> *htab;
+ unsigned int simduid;
+};
+
+/* Callback for note_simd_array_uses, called through walk_gimple_op. */
+
+static tree
+note_simd_array_uses_cb (tree *tp, int *walk_subtrees, void *data)
+{
+ struct walk_stmt_info *wi = (struct walk_stmt_info *) data;
+ struct note_simd_array_uses_struct *ns
+ = (struct note_simd_array_uses_struct *) wi->info;
+
+ if (TYPE_P (*tp))
+ *walk_subtrees = 0;
+ else if (VAR_P (*tp)
+ && lookup_attribute ("omp simd array", DECL_ATTRIBUTES (*tp))
+ && DECL_CONTEXT (*tp) == current_function_decl)
+ {
+ simd_array_to_simduid data;
+ if (!ns->htab->is_created ())
+ ns->htab->create (15);
+ data.decl = *tp;
+ data.simduid = ns->simduid;
+ simd_array_to_simduid **slot = ns->htab->find_slot (&data, INSERT);
+ if (*slot == NULL)
+ {
+ simd_array_to_simduid *p = XNEW (simd_array_to_simduid);
+ *p = data;
+ *slot = p;
+ }
+ else if ((*slot)->simduid != ns->simduid)
+ (*slot)->simduid = -1U;
+ *walk_subtrees = 0;
+ }
+ return NULL_TREE;
+}
+
+/* Find "omp simd array" temporaries and map them to corresponding
+ simduid. */
+
+static void
+note_simd_array_uses (hash_table <simd_array_to_simduid> *htab)
+{
+ basic_block bb;
+ gimple_stmt_iterator gsi;
+ struct walk_stmt_info wi;
+ struct note_simd_array_uses_struct ns;
+ memset (&wi, 0, sizeof (wi));
+ wi.info = &ns;
+ ns.htab = htab;
+
+ FOR_EACH_BB (bb)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ gimple stmt = gsi_stmt (gsi);
+ if (!is_gimple_call (stmt) || !gimple_call_internal_p (stmt))
+ continue;
+ switch (gimple_call_internal_fn (stmt))
+ {
+ case IFN_GOMP_SIMD_LANE:
+ case IFN_GOMP_SIMD_VF:
+ case IFN_GOMP_SIMD_LAST_LANE:
+ break;
+ default:
+ continue;
+ }
+ tree lhs = gimple_call_lhs (stmt);
+ if (lhs == NULL_TREE)
+ continue;
+ imm_use_iterator use_iter;
+ gimple use_stmt;
+ ns.simduid = DECL_UID (SSA_NAME_VAR (gimple_call_arg (stmt, 0)));
+ FOR_EACH_IMM_USE_STMT (use_stmt, use_iter, lhs)
+ if (!is_gimple_debug (use_stmt))
+ walk_gimple_op (use_stmt, note_simd_array_uses_cb, &wi);
+ }
+}
+/* A helper function to free data refs. */
+
+void
+vect_destroy_datarefs (loop_vec_info loop_vinfo, bb_vec_info bb_vinfo)
+{
+ vec<data_reference_p> datarefs;
+ struct data_reference *dr;
+ unsigned int i;
+
+ if (loop_vinfo)
+ datarefs = LOOP_VINFO_DATAREFS (loop_vinfo);
+ else
+ datarefs = BB_VINFO_DATAREFS (bb_vinfo);
+
+ FOR_EACH_VEC_ELT (datarefs, i, dr)
+ if (dr->aux)
+ {
+ free (dr->aux);
+ dr->aux = NULL;
+ }
+
+ free_data_refs (datarefs);
+}
+
+
/* Function vectorize_loops.
Entry point to loop vectorization phase. */
@@ -86,12 +317,21 @@ vectorize_loops (void)
unsigned int vect_loops_num;
loop_iterator li;
struct loop *loop;
+ hash_table <simduid_to_vf> simduid_to_vf_htab;
+ hash_table <simd_array_to_simduid> simd_array_to_simduid_htab;
vect_loops_num = number_of_loops (cfun);
/* Bail out if there are no loops. */
if (vect_loops_num <= 1)
- return 0;
+ {
+ if (cfun->has_simduid_loops)
+ adjust_simduid_builtins (simduid_to_vf_htab);
+ return 0;
+ }
+
+ if (cfun->has_simduid_loops)
+ note_simd_array_uses (&simd_array_to_simduid_htab);
init_stmt_vec_info_vec ();
@@ -101,7 +341,8 @@ vectorize_loops (void)
than all previously defined loops. This fact allows us to run
only over initial loops skipping newly generated ones. */
FOR_EACH_LOOP (li, loop, 0)
- if (optimize_loop_nest_for_speed_p (loop))
+ if ((flag_tree_vectorize && optimize_loop_nest_for_speed_p (loop))
+ || loop->force_vect)
{
loop_vec_info loop_vinfo;
vect_location = find_loop_location (loop);
@@ -116,12 +357,29 @@ vectorize_loops (void)
if (!loop_vinfo || !LOOP_VINFO_VECTORIZABLE_P (loop_vinfo))
continue;
+ if (!dbg_cnt (vect_loop))
+ break;
+
if (LOCATION_LOCUS (vect_location) != UNKNOWN_LOC
&& dump_enabled_p ())
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
- "Vectorized loop\n");
+ "loop vectorized\n");
vect_transform_loop (loop_vinfo);
num_vectorized_loops++;
+ /* Now that the loop has been vectorized, allow it to be unrolled
+ etc. */
+ loop->force_vect = false;
+
+ if (loop->simduid)
+ {
+ simduid_to_vf *simduid_to_vf_data = XNEW (simduid_to_vf);
+ if (!simduid_to_vf_htab.is_created ())
+ simduid_to_vf_htab.create (15);
+ simduid_to_vf_data->simduid = DECL_UID (loop->simduid);
+ simduid_to_vf_data->vf = loop_vinfo->vectorization_factor;
+ *simduid_to_vf_htab.find_slot (simduid_to_vf_data, INSERT)
+ = simduid_to_vf_data;
+ }
}
vect_location = UNKNOWN_LOC;
@@ -149,6 +407,40 @@ vectorize_loops (void)
free_stmt_vec_info_vec ();
+ /* Fold IFN_GOMP_SIMD_{VF,LANE,LAST_LANE} builtins. */
+ if (cfun->has_simduid_loops)
+ adjust_simduid_builtins (simduid_to_vf_htab);
+
+ /* Shrink any "omp array simd" temporary arrays to the
+ actual vectorization factors. */
+ if (simd_array_to_simduid_htab.is_created ())
+ {
+ for (hash_table <simd_array_to_simduid>::iterator iter
+ = simd_array_to_simduid_htab.begin ();
+ iter != simd_array_to_simduid_htab.end (); ++iter)
+ if ((*iter).simduid != -1U)
+ {
+ tree decl = (*iter).decl;
+ int vf = 1;
+ if (simduid_to_vf_htab.is_created ())
+ {
+ simduid_to_vf *p = NULL, data;
+ data.simduid = (*iter).simduid;
+ p = simduid_to_vf_htab.find (&data);
+ if (p)
+ vf = p->vf;
+ }
+ tree atype
+ = build_array_type_nelts (TREE_TYPE (TREE_TYPE (decl)), vf);
+ TREE_TYPE (decl) = atype;
+ relayout_decl (decl);
+ }
+
+ simd_array_to_simduid_htab.dispose ();
+ }
+ if (simduid_to_vf_htab.is_created ())
+ simduid_to_vf_htab.dispose ();
+
if (num_vectorized_loops > 0)
{
/* If we vectorized any loop only virtual SSA form needs to be updated.
@@ -177,10 +469,13 @@ execute_vect_slp (void)
if (vect_slp_analyze_bb (bb))
{
+ if (!dbg_cnt (vect_slp))
+ break;
+
vect_slp_transform_bb (bb);
if (dump_enabled_p ())
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, vect_location,
- "Vectorized basic-block\n");
+ "basic block vectorized\n");
}
}
@@ -197,29 +492,45 @@ gate_vect_slp (void)
|| flag_tree_slp_vectorize == 1);
}
-struct gimple_opt_pass pass_slp_vectorize =
+namespace {
+
+const pass_data pass_data_slp_vectorize =
{
- {
- GIMPLE_PASS,
- "slp", /* name */
- OPTGROUP_LOOP
- | OPTGROUP_VEC, /* optinfo_flags */
- gate_vect_slp, /* gate */
- execute_vect_slp, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_SLP_VECTORIZATION, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_ssa
- | TODO_update_ssa
- | TODO_verify_stmts /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "slp", /* name */
+ OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_SLP_VECTORIZATION, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_ssa | TODO_update_ssa
+ | TODO_verify_stmts ), /* todo_flags_finish */
};
+class pass_slp_vectorize : public gimple_opt_pass
+{
+public:
+ pass_slp_vectorize(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_slp_vectorize, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_vect_slp (); }
+ unsigned int execute () { return execute_vect_slp (); }
+
+}; // class pass_slp_vectorize
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_slp_vectorize (gcc::context *ctxt)
+{
+ return new pass_slp_vectorize (ctxt);
+}
+
/* Increase alignment of global arrays to improve vectorization potential.
TODO:
@@ -272,23 +583,40 @@ gate_increase_alignment (void)
}
-struct simple_ipa_opt_pass pass_ipa_increase_alignment =
+namespace {
+
+const pass_data pass_data_ipa_increase_alignment =
{
- {
- SIMPLE_IPA_PASS,
- "increase_alignment", /* name */
- OPTGROUP_LOOP
- | OPTGROUP_VEC, /* optinfo_flags */
- gate_increase_alignment, /* gate */
- increase_alignment, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_OPT, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+ SIMPLE_IPA_PASS, /* type */
+ "increase_alignment", /* name */
+ OPTGROUP_LOOP | OPTGROUP_VEC, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_OPT, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+
+class pass_ipa_increase_alignment : public simple_ipa_opt_pass
+{
+public:
+ pass_ipa_increase_alignment(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_ipa_increase_alignment, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_increase_alignment (); }
+ unsigned int execute () { return increase_alignment (); }
+
+}; // class pass_ipa_increase_alignment
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_increase_alignment (gcc::context *ctxt)
+{
+ return new pass_ipa_increase_alignment (ctxt);
+}
diff --git a/gcc/tree-vectorizer.h b/gcc/tree-vectorizer.h
index 7c5dfe884df..9c7753e2eaf 100644
--- a/gcc/tree-vectorizer.h
+++ b/gcc/tree-vectorizer.h
@@ -576,6 +576,9 @@ typedef struct _stmt_vec_info {
/* For loads only, true if this is a gather load. */
bool gather_p;
bool stride_load_p;
+
+ /* For both loads and stores. */
+ bool simd_lane_access_p;
} *stmt_vec_info;
/* Access Functions. */
@@ -591,6 +594,7 @@ typedef struct _stmt_vec_info {
#define STMT_VINFO_DATA_REF(S) (S)->data_ref_info
#define STMT_VINFO_GATHER_P(S) (S)->gather_p
#define STMT_VINFO_STRIDE_LOAD_P(S) (S)->stride_load_p
+#define STMT_VINFO_SIMD_LANE_ACCESS_P(S) (S)->simd_lane_access_p
#define STMT_VINFO_DR_BASE_ADDRESS(S) (S)->dr_base_address
#define STMT_VINFO_DR_INIT(S) (S)->dr_init
@@ -625,6 +629,12 @@ typedef struct _stmt_vec_info {
#define PURE_SLP_STMT(S) ((S)->slp_type == pure_slp)
#define STMT_SLP_TYPE(S) (S)->slp_type
+struct dataref_aux {
+ tree base_decl;
+ bool base_misaligned;
+ int misalignment;
+};
+
#define VECT_MAX_COST 1000
/* The maximum number of intermediate steps required in multi-step type
@@ -827,11 +837,31 @@ destroy_cost_data (void *data)
/*-----------------------------------------------------------------*/
/* Info on data references alignment. */
/*-----------------------------------------------------------------*/
+inline void
+set_dr_misalignment (struct data_reference *dr, int val)
+{
+ dataref_aux *data_aux = (dataref_aux *) dr->aux;
+
+ if (!data_aux)
+ {
+ data_aux = XCNEW (dataref_aux);
+ dr->aux = data_aux;
+ }
+
+ data_aux->misalignment = val;
+}
+
+inline int
+dr_misalignment (struct data_reference *dr)
+{
+ gcc_assert (dr->aux);
+ return ((dataref_aux *) dr->aux)->misalignment;
+}
/* Reflects actual alignment of first access in the vectorized loop,
taking into account peeling/versioning if applied. */
-#define DR_MISALIGNMENT(DR) ((int) (size_t) (DR)->aux)
-#define SET_DR_MISALIGNMENT(DR, VAL) ((DR)->aux = (void *) (size_t) (VAL))
+#define DR_MISALIGNMENT(DR) dr_misalignment (DR)
+#define SET_DR_MISALIGNMENT(DR, VAL) set_dr_misalignment (DR, VAL)
/* Return TRUE if the data access is aligned, and FALSE otherwise. */
@@ -1010,5 +1040,6 @@ void vect_pattern_recog (loop_vec_info, bb_vec_info);
/* In tree-vectorizer.c. */
unsigned vectorize_loops (void);
+void vect_destroy_datarefs (loop_vec_info, bb_vec_info);
#endif /* GCC_TREE_VECTORIZER_H */
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index ca9d8bdb305..d5548ff55eb 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -5410,10 +5410,14 @@ register_edge_assert_for_1 (tree op, enum tree_code code,
&& gimple_assign_rhs_code (op_def) == BIT_IOR_EXPR))
{
/* Recurse on each operand. */
- retval |= register_edge_assert_for_1 (gimple_assign_rhs1 (op_def),
- code, e, bsi);
- retval |= register_edge_assert_for_1 (gimple_assign_rhs2 (op_def),
- code, e, bsi);
+ tree op0 = gimple_assign_rhs1 (op_def);
+ tree op1 = gimple_assign_rhs2 (op_def);
+ if (TREE_CODE (op0) == SSA_NAME
+ && has_single_use (op0))
+ retval |= register_edge_assert_for_1 (op0, code, e, bsi);
+ if (TREE_CODE (op1) == SSA_NAME
+ && has_single_use (op1))
+ retval |= register_edge_assert_for_1 (op1, code, e, bsi);
}
else if (gimple_assign_rhs_code (op_def) == BIT_NOT_EXPR
&& TYPE_PRECISION (TREE_TYPE (gimple_assign_lhs (op_def))) == 1)
@@ -9273,15 +9277,27 @@ static vec<tree> equiv_stack;
static tree
simplify_stmt_for_jump_threading (gimple stmt, gimple within_stmt)
{
- /* We only use VRP information to simplify conditionals. This is
- overly conservative, but it's unclear if doing more would be
- worth the compile time cost. */
- if (gimple_code (stmt) != GIMPLE_COND)
- return NULL;
+ if (gimple_code (stmt) == GIMPLE_COND)
+ return vrp_evaluate_conditional (gimple_cond_code (stmt),
+ gimple_cond_lhs (stmt),
+ gimple_cond_rhs (stmt), within_stmt);
- return vrp_evaluate_conditional (gimple_cond_code (stmt),
- gimple_cond_lhs (stmt),
- gimple_cond_rhs (stmt), within_stmt);
+ if (gimple_code (stmt) == GIMPLE_ASSIGN)
+ {
+ value_range_t new_vr = VR_INITIALIZER;
+ tree lhs = gimple_assign_lhs (stmt);
+
+ if (TREE_CODE (lhs) == SSA_NAME
+ && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
+ || POINTER_TYPE_P (TREE_TYPE (lhs))))
+ {
+ extract_range_from_assignment (&new_vr, stmt);
+ if (range_int_cst_singleton_p (&new_vr))
+ return new_vr.min;
+ }
+ }
+
+ return NULL_TREE;
}
/* Blocks which have more than one predecessor and more than
@@ -9584,25 +9600,43 @@ gate_vrp (void)
return flag_tree_vrp != 0;
}
-struct gimple_opt_pass pass_vrp =
-{
- {
- GIMPLE_PASS,
- "vrp", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_vrp, /* gate */
- execute_vrp, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_TREE_VRP, /* tv_id */
- PROP_ssa, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_cleanup_cfg
- | TODO_update_ssa
+namespace {
+
+const pass_data pass_data_vrp =
+{
+ GIMPLE_PASS, /* type */
+ "vrp", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_TREE_VRP, /* tv_id */
+ PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_cleanup_cfg | TODO_update_ssa
| TODO_verify_ssa
- | TODO_verify_flow /* todo_flags_finish */
- }
+ | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_vrp : public gimple_opt_pass
+{
+public:
+ pass_vrp(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_vrp, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_vrp (ctxt_); }
+ bool gate () { return gate_vrp (); }
+ unsigned int execute () { return execute_vrp (); }
+
+}; // class pass_vrp
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_vrp (gcc::context *ctxt)
+{
+ return new pass_vrp (ctxt);
+}
diff --git a/gcc/tree.c b/gcc/tree.c
index ab1173525c7..61815046fae 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -236,6 +236,8 @@ unsigned const char omp_clause_num_ops[] =
4, /* OMP_CLAUSE_REDUCTION */
1, /* OMP_CLAUSE_COPYIN */
1, /* OMP_CLAUSE_COPYPRIVATE */
+ 2, /* OMP_CLAUSE_LINEAR */
+ 1, /* OMP_CLAUSE_UNIFORM */
1, /* OMP_CLAUSE_IF */
1, /* OMP_CLAUSE_NUM_THREADS */
1, /* OMP_CLAUSE_SCHEDULE */
@@ -245,7 +247,9 @@ unsigned const char omp_clause_num_ops[] =
3, /* OMP_CLAUSE_COLLAPSE */
0, /* OMP_CLAUSE_UNTIED */
1, /* OMP_CLAUSE_FINAL */
- 0 /* OMP_CLAUSE_MERGEABLE */
+ 0, /* OMP_CLAUSE_MERGEABLE */
+ 1, /* OMP_CLAUSE_SAFELEN */
+ 1, /* OMP_CLAUSE__SIMDUID_ */
};
const char * const omp_clause_code_name[] =
@@ -258,6 +262,8 @@ const char * const omp_clause_code_name[] =
"reduction",
"copyin",
"copyprivate",
+ "linear",
+ "uniform",
"if",
"num_threads",
"schedule",
@@ -267,7 +273,9 @@ const char * const omp_clause_code_name[] =
"collapse",
"untied",
"final",
- "mergeable"
+ "mergeable",
+ "safelen",
+ "_simduid_"
};
@@ -2051,12 +2059,12 @@ integer_pow2p (const_tree expr)
if (prec == HOST_BITS_PER_DOUBLE_INT)
;
else if (prec > HOST_BITS_PER_WIDE_INT)
- high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+ high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT));
else
{
high = 0;
if (prec < HOST_BITS_PER_WIDE_INT)
- low &= ~((HOST_WIDE_INT) (-1) << prec);
+ low &= ~(HOST_WIDE_INT_M1U << prec);
}
if (high == 0 && low == 0)
@@ -2115,12 +2123,12 @@ tree_log2 (const_tree expr)
if (prec == HOST_BITS_PER_DOUBLE_INT)
;
else if (prec > HOST_BITS_PER_WIDE_INT)
- high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+ high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT));
else
{
high = 0;
if (prec < HOST_BITS_PER_WIDE_INT)
- low &= ~((HOST_WIDE_INT) (-1) << prec);
+ low &= ~(HOST_WIDE_INT_M1U << prec);
}
return (high != 0 ? HOST_BITS_PER_WIDE_INT + exact_log2 (high)
@@ -2152,12 +2160,12 @@ tree_floor_log2 (const_tree expr)
if (prec == HOST_BITS_PER_DOUBLE_INT || prec == 0)
;
else if (prec > HOST_BITS_PER_WIDE_INT)
- high &= ~((HOST_WIDE_INT) (-1) << (prec - HOST_BITS_PER_WIDE_INT));
+ high &= ~(HOST_WIDE_INT_M1U << (prec - HOST_BITS_PER_WIDE_INT));
else
{
high = 0;
if (prec < HOST_BITS_PER_WIDE_INT)
- low &= ~((HOST_WIDE_INT) (-1) << prec);
+ low &= ~(HOST_WIDE_INT_M1U << prec);
}
return (high != 0 ? HOST_BITS_PER_WIDE_INT + floor_log2 (high)
@@ -4886,6 +4894,20 @@ free_lang_data_in_decl (tree decl)
if (TREE_CODE (decl) == FUNCTION_DECL)
{
+ struct cgraph_node *node;
+ if (!(node = cgraph_get_node (decl))
+ || (!node->symbol.definition && !node->clones))
+ {
+ if (node)
+ cgraph_release_function_body (node);
+ else
+ {
+ release_function_body (decl);
+ DECL_ARGUMENTS (decl) = NULL;
+ DECL_RESULT (decl) = NULL;
+ DECL_INITIAL (decl) = error_mark_node;
+ }
+ }
if (gimple_has_body_p (decl))
{
tree t;
@@ -5491,26 +5513,43 @@ free_lang_data (void)
}
-struct simple_ipa_opt_pass pass_ipa_free_lang_data =
-{
- {
- SIMPLE_IPA_PASS,
- "*free_lang_data", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- NULL, /* gate */
- free_lang_data, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_IPA_FREE_LANG_DATA, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- 0 /* todo_flags_finish */
- }
+namespace {
+
+const pass_data pass_data_ipa_free_lang_data =
+{
+ SIMPLE_IPA_PASS, /* type */
+ "*free_lang_data", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ false, /* has_gate */
+ true, /* has_execute */
+ TV_IPA_FREE_LANG_DATA, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ 0, /* todo_flags_finish */
};
+class pass_ipa_free_lang_data : public simple_ipa_opt_pass
+{
+public:
+ pass_ipa_free_lang_data(gcc::context *ctxt)
+ : simple_ipa_opt_pass(pass_data_ipa_free_lang_data, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ unsigned int execute () { return free_lang_data (); }
+
+}; // class pass_ipa_free_lang_data
+
+} // anon namespace
+
+simple_ipa_opt_pass *
+make_pass_ipa_free_lang_data (gcc::context *ctxt)
+{
+ return new pass_ipa_free_lang_data (ctxt);
+}
+
/* The backbone of is_attribute_p(). ATTR_LEN is the string length of
ATTR_NAME. Also used internally by remove_attribute(). */
bool
@@ -9638,6 +9677,8 @@ build_common_tree_nodes (bool signed_char, bool short_double)
= build_pointer_type (build_type_variant (void_type_node, 1, 0));
fileptr_type_node = ptr_type_node;
+ pointer_sized_int_node = build_nonstandard_integer_type (POINTER_SIZE, 1);
+
float_type_node = make_node (REAL_TYPE);
TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE;
layout_type (float_type_node);
@@ -9755,7 +9796,10 @@ build_common_tree_nodes (bool signed_char, bool short_double)
}
}
-/* Modify DECL for given flags. */
+/* Modify DECL for given flags.
+ TM_PURE attribute is set only on types, so the function will modify
+ DECL's type when ECF_TM_PURE is used. */
+
void
set_call_expr_flags (tree decl, int flags)
{
@@ -9779,8 +9823,7 @@ set_call_expr_flags (tree decl, int flags)
DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"),
NULL, DECL_ATTRIBUTES (decl));
if ((flags & ECF_TM_PURE) && flag_tm)
- DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("transaction_pure"),
- NULL, DECL_ATTRIBUTES (decl));
+ apply_tm_attr (decl, get_identifier ("transaction_pure"));
/* Looping const or pure is implied by noreturn.
There is currently no way to declare looping const or looping pure alone. */
gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE)
@@ -11033,6 +11076,9 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
case OMP_CLAUSE_IF:
case OMP_CLAUSE_NUM_THREADS:
case OMP_CLAUSE_SCHEDULE:
+ case OMP_CLAUSE_UNIFORM:
+ case OMP_CLAUSE_SAFELEN:
+ case OMP_CLAUSE__SIMDUID_:
WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 0));
/* FALLTHRU */
@@ -11056,6 +11102,11 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data,
WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
}
+ case OMP_CLAUSE_LINEAR:
+ WALK_SUBTREE (OMP_CLAUSE_DECL (*tp));
+ WALK_SUBTREE (OMP_CLAUSE_OPERAND (*tp, 1));
+ WALK_SUBTREE_TAIL (OMP_CLAUSE_CHAIN (*tp));
+
case OMP_CLAUSE_REDUCTION:
{
int i;
@@ -11802,11 +11853,6 @@ types_same_for_odr (tree type1, tree type2)
if (type1 == type2)
return true;
- /* If types are not structuraly same, do not bother to contnue.
- Match in the remainder of code would mean ODR violation. */
- if (!types_compatible_p (type1, type2))
- return false;
-
#ifndef ENABLE_CHECKING
if (!in_lto_p)
return false;
@@ -11814,13 +11860,42 @@ types_same_for_odr (tree type1, tree type2)
/* Check for anonymous namespaces. Those have !TREE_PUBLIC
on the corresponding TYPE_STUB_DECL. */
- if (TYPE_STUB_DECL (type1) != TYPE_STUB_DECL (type2)
- && (!TYPE_STUB_DECL (type1)
- || !TYPE_STUB_DECL (type2)
- || !TREE_PUBLIC (TYPE_STUB_DECL (type1))
- || !TREE_PUBLIC (TYPE_STUB_DECL (type2))))
+ if (type_in_anonymous_namespace_p (type1)
+ || type_in_anonymous_namespace_p (type2))
return false;
+ /* When assembler name of virtual table is available, it is
+ easy to compare types for equivalence. */
+ if (TYPE_BINFO (type1) && TYPE_BINFO (type2)
+ && BINFO_VTABLE (TYPE_BINFO (type1))
+ && BINFO_VTABLE (TYPE_BINFO (type2)))
+ {
+ tree v1 = BINFO_VTABLE (TYPE_BINFO (type1));
+ tree v2 = BINFO_VTABLE (TYPE_BINFO (type2));
+ if (TREE_CODE (v1) == POINTER_PLUS_EXPR)
+ {
+ if (TREE_CODE (v2) != POINTER_PLUS_EXPR
+ || !operand_equal_p (TREE_OPERAND (v1, 1),
+ TREE_OPERAND (v2, 1), 0))
+ return false;
+ v1 = TREE_OPERAND (TREE_OPERAND (v1, 0), 0);
+ v2 = TREE_OPERAND (TREE_OPERAND (v2, 0), 0);
+ }
+ v1 = DECL_ASSEMBLER_NAME (v1);
+ v2 = DECL_ASSEMBLER_NAME (v2);
+ return (v1 == v2);
+ }
+
+ /* FIXME: the code comparing type names consider all instantiations of the
+ same template to have same name. This is because we have no access
+ to template parameters. For types with no virtual method tables
+ we thus can return false positives. At the moment we do not need
+ to compare types in other scenarios than devirtualization. */
+
+ /* If types are not structuraly same, do not bother to contnue.
+ Match in the remainder of code would mean ODR violation. */
+ if (!types_compatible_p (type1, type2))
+ return false;
if (!TYPE_NAME (type1))
return false;
if (!decls_same_for_odr (TYPE_NAME (type1), TYPE_NAME (type2)))
@@ -11833,6 +11908,54 @@ types_same_for_odr (tree type1, tree type2)
return true;
}
+/* TARGET is a call target of GIMPLE call statement
+ (obtained by gimple_call_fn). Return true if it is
+ OBJ_TYPE_REF representing an virtual call of C++ method.
+ (As opposed to OBJ_TYPE_REF representing objc calls
+ through a cast where middle-end devirtualization machinery
+ can't apply.) */
+
+bool
+virtual_method_call_p (tree target)
+{
+ if (TREE_CODE (target) != OBJ_TYPE_REF)
+ return false;
+ target = TREE_TYPE (target);
+ gcc_checking_assert (TREE_CODE (target) == POINTER_TYPE);
+ target = TREE_TYPE (target);
+ if (TREE_CODE (target) == FUNCTION_TYPE)
+ return false;
+ gcc_checking_assert (TREE_CODE (target) == METHOD_TYPE);
+ return true;
+}
+
+/* REF is OBJ_TYPE_REF, return the class the ref corresponds to. */
+
+tree
+obj_type_ref_class (tree ref)
+{
+ gcc_checking_assert (TREE_CODE (ref) == OBJ_TYPE_REF);
+ ref = TREE_TYPE (ref);
+ gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
+ ref = TREE_TYPE (ref);
+ /* We look for type THIS points to. ObjC also builds
+ OBJ_TYPE_REF with non-method calls, Their first parameter
+ ID however also corresponds to class type. */
+ gcc_checking_assert (TREE_CODE (ref) == METHOD_TYPE
+ || TREE_CODE (ref) == FUNCTION_TYPE);
+ ref = TREE_VALUE (TYPE_ARG_TYPES (ref));
+ gcc_checking_assert (TREE_CODE (ref) == POINTER_TYPE);
+ return TREE_TYPE (ref);
+}
+
+/* Return true if T is in anonymous namespace. */
+
+bool
+type_in_anonymous_namespace_p (tree t)
+{
+ return (TYPE_STUB_DECL (t) && !TREE_PUBLIC (TYPE_STUB_DECL (t)));
+}
+
/* Try to find a base info of BINFO that would have its field decl at offset
OFFSET within the BINFO type and which is of EXPECTED_TYPE. If it can be
found, return, otherwise return NULL_TREE. */
diff --git a/gcc/tree.def b/gcc/tree.def
index da30074b109..f825aad5355 100644
--- a/gcc/tree.def
+++ b/gcc/tree.def
@@ -1030,6 +1030,10 @@ DEFTREECODE (OMP_TASK, "omp_task", tcc_statement, 2)
unspecified by the standard. */
DEFTREECODE (OMP_FOR, "omp_for", tcc_statement, 6)
+/* OpenMP - #pragma omp simd [clause1 ... clauseN]
+ Operands like for OMP_FOR. */
+DEFTREECODE (OMP_SIMD, "omp_simd", tcc_statement, 6)
+
/* OpenMP - #pragma omp sections [clause1 ... clauseN]
Operand 0: OMP_SECTIONS_BODY: Sections body.
Operand 1: OMP_SECTIONS_CLAUSES: List of clauses. */
diff --git a/gcc/tree.h b/gcc/tree.h
index 0058a4b17bf..7c1f57b829b 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -20,32 +20,7 @@ along with GCC; see the file COPYING3. If not see
#ifndef GCC_TREE_H
#define GCC_TREE_H
-#include "hashtab.h"
-#include "machmode.h"
-#include "input.h"
-#include "statistics.h"
-#include "vec.h"
-#include "double-int.h"
-#include "real.h"
-#include "fixed-value.h"
-#include "alias.h"
-#include "flags.h"
-
-/* Codes of tree nodes */
-
-#define DEFTREECODE(SYM, STRING, TYPE, NARGS) SYM,
-#define END_OF_BASE_TREE_CODES LAST_AND_UNUSED_TREE_CODE,
-
-enum tree_code {
-#include "all-tree.def"
-MAX_TREE_CODES
-};
-
-#undef DEFTREECODE
-#undef END_OF_BASE_TREE_CODES
-
-extern unsigned char tree_contains_struct[MAX_TREE_CODES][64];
-#define CODE_CONTAINS_STRUCT(CODE, STRUCT) (tree_contains_struct[(CODE)][(STRUCT)])
+#include "tree-core.h"
/* Macros for initializing `tree_contains_struct'. */
#define MARK_TS_BASE(C) \
@@ -107,42 +82,12 @@ extern unsigned char tree_contains_struct[MAX_TREE_CODES][64];
tree_contains_struct[C][TS_DECL_NON_COMMON] = 1; \
} while (0)
-/* Number of language-independent tree codes. */
-#define NUM_TREE_CODES ((int) LAST_AND_UNUSED_TREE_CODE)
-
-/* Tree code classes. */
-
-/* Each tree_code has an associated code class represented by a
- TREE_CODE_CLASS. */
-
-enum tree_code_class {
- tcc_exceptional, /* An exceptional code (fits no category). */
- tcc_constant, /* A constant. */
- /* Order of tcc_type and tcc_declaration is important. */
- tcc_type, /* A type object code. */
- tcc_declaration, /* A declaration (also serving as variable refs). */
- tcc_reference, /* A reference to storage. */
- tcc_comparison, /* A comparison expression. */
- tcc_unary, /* A unary arithmetic expression. */
- tcc_binary, /* A binary arithmetic expression. */
- tcc_statement, /* A statement expression, which have side effects
- but usually no interesting value. */
- tcc_vl_exp, /* A function call or other expression with a
- variable-length operand vector. */
- tcc_expression /* Any other expression. */
-};
-
-/* Each tree code class has an associated string representation.
- These must correspond to the tree_code_class entries. */
-
-extern const char *const tree_code_class_strings[];
/* Returns the string representing CLASS. */
#define TREE_CODE_CLASS_STRING(CLASS)\
tree_code_class_strings[(int) (CLASS)]
-extern const enum tree_code_class tree_code_type[];
#define TREE_CODE_CLASS(CODE) tree_code_type[(int) (CODE)]
/* Nonzero if CODE represents an exceptional code. */
@@ -231,76 +176,8 @@ extern const enum tree_code_class tree_code_type[];
#define EXPR_P(NODE) IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (NODE)))
-/* Number of argument-words in each kind of tree-node. */
-
-extern const unsigned char tree_code_length[];
#define TREE_CODE_LENGTH(CODE) tree_code_length[(int) (CODE)]
-/* Names of tree components. */
-
-extern const char *const tree_code_name[];
-
-/* When procesing aliases on symtab level, we need the declaration of target.
- For this reason we need to queue aliases and process them after all declarations
- has been produced. */
-
-typedef struct GTY(()) alias_pair
-{
- tree decl;
- tree target;
-} alias_pair;
-
-/* Define gc'd vector type. */
-
-extern GTY(()) vec<alias_pair, va_gc> *alias_pairs;
-
-
-/* Classify which part of the compiler has defined a given builtin function.
- Note that we assume below that this is no more than two bits. */
-enum built_in_class
-{
- NOT_BUILT_IN = 0,
- BUILT_IN_FRONTEND,
- BUILT_IN_MD,
- BUILT_IN_NORMAL
-};
-
-/* Last marker used for LTO stremaing of built_in_class. We can not add it
- to the enum since we need the enumb to fit in 2 bits. */
-#define BUILT_IN_LAST (BUILT_IN_NORMAL + 1)
-
-/* Names for the above. */
-extern const char *const built_in_class_names[4];
-
-/* Codes that identify the various built in functions
- so that expand_call can identify them quickly. */
-
-#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM,
-enum built_in_function
-{
-#include "builtins.def"
-
- /* Complex division routines in libgcc. These are done via builtins
- because emit_library_call_value can't handle complex values. */
- BUILT_IN_COMPLEX_MUL_MIN,
- BUILT_IN_COMPLEX_MUL_MAX
- = BUILT_IN_COMPLEX_MUL_MIN
- + MAX_MODE_COMPLEX_FLOAT
- - MIN_MODE_COMPLEX_FLOAT,
-
- BUILT_IN_COMPLEX_DIV_MIN,
- BUILT_IN_COMPLEX_DIV_MAX
- = BUILT_IN_COMPLEX_DIV_MIN
- + MAX_MODE_COMPLEX_FLOAT
- - MIN_MODE_COMPLEX_FLOAT,
-
- /* Upper bound on non-language-specific builtins. */
- END_BUILTINS
-};
-#undef DEF_BUILTIN
-
-/* Names for the above. */
-extern const char * built_in_names[(int) END_BUILTINS];
/* Helper macros for math builtins. */
@@ -323,417 +200,6 @@ extern const char * built_in_names[(int) END_BUILTINS];
#define CASE_FLT_FN(FN) case FN: case FN##F: case FN##L
#define CASE_FLT_FN_REENT(FN) case FN##_R: case FN##F_R: case FN##L_R
#define CASE_INT_FN(FN) case FN: case FN##L: case FN##LL: case FN##IMAX
-
-/* In an OMP_CLAUSE node. */
-
-/* Number of operands and names for each clause. */
-extern unsigned const char omp_clause_num_ops[];
-extern const char * const omp_clause_code_name[];
-
-/* Clause codes. Do not reorder, as this is used to index into the tables
- omp_clause_num_ops and omp_clause_code_name. */
-enum omp_clause_code
-{
- /* Clause zero is special-cased inside the parser
- (c_parser_omp_variable_list). */
- OMP_CLAUSE_ERROR = 0,
-
- /* OpenMP clause: private (variable_list). */
- OMP_CLAUSE_PRIVATE,
-
- /* OpenMP clause: shared (variable_list). */
- OMP_CLAUSE_SHARED,
-
- /* OpenMP clause: firstprivate (variable_list). */
- OMP_CLAUSE_FIRSTPRIVATE,
-
- /* OpenMP clause: lastprivate (variable_list). */
- OMP_CLAUSE_LASTPRIVATE,
-
- /* OpenMP clause: reduction (operator:variable_list).
- OMP_CLAUSE_REDUCTION_CODE: The tree_code of the operator.
- Operand 1: OMP_CLAUSE_REDUCTION_INIT: Stmt-list to initialize the var.
- Operand 2: OMP_CLAUSE_REDUCTION_MERGE: Stmt-list to merge private var
- into the shared one.
- Operand 3: OMP_CLAUSE_REDUCTION_PLACEHOLDER: A dummy VAR_DECL
- placeholder used in OMP_CLAUSE_REDUCTION_{INIT,MERGE}. */
- OMP_CLAUSE_REDUCTION,
-
- /* OpenMP clause: copyin (variable_list). */
- OMP_CLAUSE_COPYIN,
-
- /* OpenMP clause: copyprivate (variable_list). */
- OMP_CLAUSE_COPYPRIVATE,
-
- /* OpenMP clause: if (scalar-expression). */
- OMP_CLAUSE_IF,
-
- /* OpenMP clause: num_threads (integer-expression). */
- OMP_CLAUSE_NUM_THREADS,
-
- /* OpenMP clause: schedule. */
- OMP_CLAUSE_SCHEDULE,
-
- /* OpenMP clause: nowait. */
- OMP_CLAUSE_NOWAIT,
-
- /* OpenMP clause: ordered. */
- OMP_CLAUSE_ORDERED,
-
- /* OpenMP clause: default. */
- OMP_CLAUSE_DEFAULT,
-
- /* OpenMP clause: collapse (constant-integer-expression). */
- OMP_CLAUSE_COLLAPSE,
-
- /* OpenMP clause: untied. */
- OMP_CLAUSE_UNTIED,
-
- /* OpenMP clause: final (scalar-expression). */
- OMP_CLAUSE_FINAL,
-
- /* OpenMP clause: mergeable. */
- OMP_CLAUSE_MERGEABLE
-};
-
-/* The definition of tree nodes fills the next several pages. */
-
-/* A tree node can represent a data type, a variable, an expression
- or a statement. Each node has a TREE_CODE which says what kind of
- thing it represents. Some common codes are:
- INTEGER_TYPE -- represents a type of integers.
- ARRAY_TYPE -- represents a type of pointer.
- VAR_DECL -- represents a declared variable.
- INTEGER_CST -- represents a constant integer value.
- PLUS_EXPR -- represents a sum (an expression).
-
- As for the contents of a tree node: there are some fields
- that all nodes share. Each TREE_CODE has various special-purpose
- fields as well. The fields of a node are never accessed directly,
- always through accessor macros. */
-
-/* Every kind of tree node starts with this structure,
- so all nodes have these fields.
-
- See the accessor macros, defined below, for documentation of the
- fields, and the table below which connects the fields and the
- accessor macros. */
-
-struct GTY(()) tree_base {
- ENUM_BITFIELD(tree_code) code : 16;
-
- unsigned side_effects_flag : 1;
- unsigned constant_flag : 1;
- unsigned addressable_flag : 1;
- unsigned volatile_flag : 1;
- unsigned readonly_flag : 1;
- unsigned asm_written_flag: 1;
- unsigned nowarning_flag : 1;
- unsigned visited : 1;
-
- unsigned used_flag : 1;
- unsigned nothrow_flag : 1;
- unsigned static_flag : 1;
- unsigned public_flag : 1;
- unsigned private_flag : 1;
- unsigned protected_flag : 1;
- unsigned deprecated_flag : 1;
- unsigned default_def_flag : 1;
-
- union {
- /* The bits in the following structure should only be used with
- accessor macros that constrain inputs with tree checking. */
- struct {
- unsigned lang_flag_0 : 1;
- unsigned lang_flag_1 : 1;
- unsigned lang_flag_2 : 1;
- unsigned lang_flag_3 : 1;
- unsigned lang_flag_4 : 1;
- unsigned lang_flag_5 : 1;
- unsigned lang_flag_6 : 1;
- unsigned saturating_flag : 1;
-
- unsigned unsigned_flag : 1;
- unsigned packed_flag : 1;
- unsigned user_align : 1;
- unsigned nameless_flag : 1;
- unsigned spare0 : 4;
-
- unsigned spare1 : 8;
-
- /* This field is only used with TREE_TYPE nodes; the only reason it is
- present in tree_base instead of tree_type is to save space. The size
- of the field must be large enough to hold addr_space_t values. */
- unsigned address_space : 8;
- } bits;
- /* The following fields are present in tree_base to save space. The
- nodes using them do not require any of the flags above and so can
- make better use of the 4-byte sized word. */
- /* VEC length. This field is only used with TREE_VEC. */
- int length;
- /* SSA version number. This field is only used with SSA_NAME. */
- unsigned int version;
- } GTY((skip(""))) u;
-};
-
-/* The following table lists the uses of each of the above flags and
- for which types of nodes they are defined.
-
- addressable_flag:
-
- TREE_ADDRESSABLE in
- VAR_DECL, PARM_DECL, RESULT_DECL, FUNCTION_DECL, LABEL_DECL
- SSA_NAME
- all types
- CONSTRUCTOR, IDENTIFIER_NODE
- STMT_EXPR
-
- CALL_EXPR_TAILCALL in
- CALL_EXPR
-
- CASE_LOW_SEEN in
- CASE_LABEL_EXPR
-
- PREDICT_EXPR_OUTCOME in
- PREDICT_EXPR
-
- static_flag:
-
- TREE_STATIC in
- VAR_DECL, FUNCTION_DECL
- CONSTRUCTOR
-
- TREE_NO_TRAMPOLINE in
- ADDR_EXPR
-
- BINFO_VIRTUAL_P in
- TREE_BINFO
-
- TREE_SYMBOL_REFERENCED in
- IDENTIFIER_NODE
-
- CLEANUP_EH_ONLY in
- TARGET_EXPR, WITH_CLEANUP_EXPR
-
- TRY_CATCH_IS_CLEANUP in
- TRY_CATCH_EXPR
-
- ASM_INPUT_P in
- ASM_EXPR
-
- TYPE_REF_CAN_ALIAS_ALL in
- POINTER_TYPE, REFERENCE_TYPE
-
- CASE_HIGH_SEEN in
- CASE_LABEL_EXPR
-
- ENUM_IS_SCOPED in
- ENUMERAL_TYPE
-
- TRANSACTION_EXPR_OUTER in
- TRANSACTION_EXPR
-
- public_flag:
-
- TREE_OVERFLOW in
- INTEGER_CST, REAL_CST, COMPLEX_CST, VECTOR_CST
-
- TREE_PUBLIC in
- VAR_DECL, FUNCTION_DECL
- IDENTIFIER_NODE
-
- ASM_VOLATILE_P in
- ASM_EXPR
-
- CALL_EXPR_VA_ARG_PACK in
- CALL_EXPR
-
- TYPE_CACHED_VALUES_P in
- all types
-
- SAVE_EXPR_RESOLVED_P in
- SAVE_EXPR
-
- OMP_CLAUSE_LASTPRIVATE_FIRSTPRIVATE in
- OMP_CLAUSE_LASTPRIVATE
-
- OMP_CLAUSE_PRIVATE_DEBUG in
- OMP_CLAUSE_PRIVATE
-
- TRANSACTION_EXPR_RELAXED in
- TRANSACTION_EXPR
-
- private_flag:
-
- TREE_PRIVATE in
- all decls
-
- CALL_EXPR_RETURN_SLOT_OPT in
- CALL_EXPR
-
- OMP_SECTION_LAST in
- OMP_SECTION
-
- OMP_PARALLEL_COMBINED in
- OMP_PARALLEL
-
- OMP_CLAUSE_PRIVATE_OUTER_REF in
- OMP_CLAUSE_PRIVATE
-
- TYPE_REF_IS_RVALUE in
- REFERENCE_TYPE
-
- ENUM_IS_OPAQUE in
- ENUMERAL_TYPE
-
- protected_flag:
-
- TREE_PROTECTED in
- BLOCK
- all decls
-
- CALL_FROM_THUNK_P and
- CALL_ALLOCA_FOR_VAR_P in
- CALL_EXPR
-
- side_effects_flag:
-
- TREE_SIDE_EFFECTS in
- all expressions
- all decls
- all constants
-
- FORCED_LABEL in
- LABEL_DECL
-
- volatile_flag:
-
- TREE_THIS_VOLATILE in
- all expressions
- all decls
-
- TYPE_VOLATILE in
- all types
-
- readonly_flag:
-
- TREE_READONLY in
- all expressions
- all decls
-
- TYPE_READONLY in
- all types
-
- constant_flag:
-
- TREE_CONSTANT in
- all expressions
- all decls
- all constants
-
- TYPE_SIZES_GIMPLIFIED in
- all types
-
- unsigned_flag:
-
- TYPE_UNSIGNED in
- all types
-
- DECL_UNSIGNED in
- all decls
-
- asm_written_flag:
-
- TREE_ASM_WRITTEN in
- VAR_DECL, FUNCTION_DECL, TYPE_DECL
- RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE
- BLOCK, STRING_CST
-
- SSA_NAME_OCCURS_IN_ABNORMAL_PHI in
- SSA_NAME
-
- used_flag:
-
- TREE_USED in
- all expressions
- all decls
- IDENTIFIER_NODE
-
- nothrow_flag:
-
- TREE_NOTHROW in
- CALL_EXPR
- FUNCTION_DECL
-
- TYPE_ALIGN_OK in
- all types
-
- TREE_THIS_NOTRAP in
- INDIRECT_REF, MEM_REF, TARGET_MEM_REF, ARRAY_REF, ARRAY_RANGE_REF
-
- SSA_NAME_IN_FREELIST in
- SSA_NAME
-
- deprecated_flag:
-
- TREE_DEPRECATED in
- all decls
- all types
-
- IDENTIFIER_TRANSPARENT_ALIAS in
- IDENTIFIER_NODE
-
- visited:
-
- TREE_VISITED in
- all trees (used liberally by many passes)
-
- saturating_flag:
-
- TYPE_SATURATING in
- all types
-
- VAR_DECL_IS_VIRTUAL_OPERAND in
- VAR_DECL
-
- nowarning_flag:
-
- TREE_NO_WARNING in
- all expressions
- all decls
-
- TYPE_ARTIFICIAL in
- all types
-
- default_def_flag:
-
- TYPE_VECTOR_OPAQUE in
- VECTOR_TYPE
-
- SSA_NAME_IS_DEFAULT_DEF in
- SSA_NAME
-
- DECL_NONLOCAL_FRAME in
- VAR_DECL
-*/
-
-struct GTY(()) tree_typed {
- struct tree_base base;
- tree type;
-};
-
-struct GTY(()) tree_common {
- struct tree_typed typed;
- tree chain;
-};
-
-#undef DEFTREESTRUCT
-#define DEFTREESTRUCT(ENUM, NAME) ENUM,
-enum tree_node_structure_enum {
-#include "treestruct.def"
- LAST_TS_ENUM
-};
-#undef DEFTREESTRUCT
/* Define accessors for the fields that all tree nodes have
(though some fields are not used for all kinds of nodes). */
@@ -1418,70 +884,28 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
== (unsigned HOST_WIDE_INT) TREE_INT_CST_HIGH (B)) \
&& TREE_INT_CST_LOW (A) < TREE_INT_CST_LOW (B)))
-struct GTY(()) tree_int_cst {
- struct tree_typed typed;
- double_int int_cst;
-};
-
-/* In a REAL_CST node. struct real_value is an opaque entity, with
- manipulators defined in real.h. We don't want tree.h depending on
- real.h and transitively on tm.h. */
-struct real_value;
-
#define TREE_REAL_CST_PTR(NODE) (REAL_CST_CHECK (NODE)->real_cst.real_cst_ptr)
#define TREE_REAL_CST(NODE) (*TREE_REAL_CST_PTR (NODE))
-struct GTY(()) tree_real_cst {
- struct tree_typed typed;
- struct real_value * real_cst_ptr;
-};
-
-/* In a FIXED_CST node. */
-struct fixed_value;
-
#define TREE_FIXED_CST_PTR(NODE) \
(FIXED_CST_CHECK (NODE)->fixed_cst.fixed_cst_ptr)
#define TREE_FIXED_CST(NODE) (*TREE_FIXED_CST_PTR (NODE))
-struct GTY(()) tree_fixed_cst {
- struct tree_typed typed;
- struct fixed_value * fixed_cst_ptr;
-};
-
/* In a STRING_CST */
/* In C terms, this is sizeof, not strlen. */
#define TREE_STRING_LENGTH(NODE) (STRING_CST_CHECK (NODE)->string.length)
#define TREE_STRING_POINTER(NODE) \
((const char *)(STRING_CST_CHECK (NODE)->string.str))
-struct GTY(()) tree_string {
- struct tree_typed typed;
- int length;
- char str[1];
-};
-
/* In a COMPLEX_CST node. */
#define TREE_REALPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.real)
#define TREE_IMAGPART(NODE) (COMPLEX_CST_CHECK (NODE)->complex.imag)
-struct GTY(()) tree_complex {
- struct tree_typed typed;
- tree real;
- tree imag;
-};
-
/* In a VECTOR_CST node. */
#define VECTOR_CST_NELTS(NODE) (TYPE_VECTOR_SUBPARTS (TREE_TYPE (NODE)))
#define VECTOR_CST_ELTS(NODE) (VECTOR_CST_CHECK (NODE)->vector.elts)
#define VECTOR_CST_ELT(NODE,IDX) (VECTOR_CST_CHECK (NODE)->vector.elts[IDX])
-struct GTY(()) tree_vector {
- struct tree_typed typed;
- tree GTY ((length ("TYPE_VECTOR_SUBPARTS (TREE_TYPE ((tree)&%h))"))) elts[1];
-};
-
-#include "symtab.h"
-
/* Define fields and accessors for some special-purpose tree nodes. */
#define IDENTIFIER_LENGTH(NODE) \
@@ -1498,21 +922,10 @@ struct GTY(()) tree_vector {
((tree) ((char *) (NODE) - sizeof (struct tree_common)))
#define GCC_IDENT_TO_HT_IDENT(NODE) (&((struct tree_identifier *) (NODE))->id)
-struct GTY(()) tree_identifier {
- struct tree_common common;
- struct ht_identifier id;
-};
-
/* In a TREE_LIST node. */
#define TREE_PURPOSE(NODE) (TREE_LIST_CHECK (NODE)->list.purpose)
#define TREE_VALUE(NODE) (TREE_LIST_CHECK (NODE)->list.value)
-struct GTY(()) tree_list {
- struct tree_common common;
- tree purpose;
- tree value;
-};
-
/* In a TREE_VEC node. */
#define TREE_VEC_LENGTH(NODE) (TREE_VEC_CHECK (NODE)->base.u.length)
#define TREE_VEC_END(NODE) \
@@ -1520,11 +933,6 @@ struct GTY(()) tree_list {
#define TREE_VEC_ELT(NODE,I) TREE_VEC_ELT_CHECK (NODE, I)
-struct GTY(()) tree_vec {
- struct tree_common common;
- tree GTY ((length ("TREE_VEC_LENGTH ((tree)&%h)"))) a[1];
-};
-
/* In a CONSTRUCTOR node. */
#define CONSTRUCTOR_ELTS(NODE) (CONSTRUCTOR_CHECK (NODE)->constructor.elts)
#define CONSTRUCTOR_ELT(NODE,IDX) \
@@ -1573,21 +981,6 @@ struct GTY(()) tree_vec {
#define TREE_CLOBBER_P(NODE) \
(TREE_CODE (NODE) == CONSTRUCTOR && TREE_THIS_VOLATILE (NODE))
-/* A single element of a CONSTRUCTOR. VALUE holds the actual value of the
- element. INDEX can optionally design the position of VALUE: in arrays,
- it is the index where VALUE has to be placed; in structures, it is the
- FIELD_DECL of the member. */
-typedef struct GTY(()) constructor_elt_d {
- tree index;
- tree value;
-} constructor_elt;
-
-
-struct GTY(()) tree_constructor {
- struct tree_typed typed;
- vec<constructor_elt, va_gc> *elts;
-};
-
/* Define fields and accessors for some nodes that represent expressions. */
/* Nonzero if NODE is an empty statement (NOP_EXPR <0>). */
@@ -1800,7 +1193,7 @@ extern void protected_set_expr_location (tree, location_t);
#define OMP_CLAUSE_DECL(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_RANGE_CHECK (OMP_CLAUSE_CHECK (NODE), \
OMP_CLAUSE_PRIVATE, \
- OMP_CLAUSE_COPYPRIVATE), 0)
+ OMP_CLAUSE_UNIFORM), 0)
#define OMP_CLAUSE_HAS_LOCATION(NODE) \
(LOCATION_LOCUS ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus) \
!= UNKNOWN_LOCATION)
@@ -1867,38 +1260,31 @@ extern void protected_set_expr_location (tree, location_t);
#define OMP_CLAUSE_REDUCTION_PLACEHOLDER(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_REDUCTION), 3)
-enum omp_clause_schedule_kind
-{
- OMP_CLAUSE_SCHEDULE_STATIC,
- OMP_CLAUSE_SCHEDULE_DYNAMIC,
- OMP_CLAUSE_SCHEDULE_GUIDED,
- OMP_CLAUSE_SCHEDULE_AUTO,
- OMP_CLAUSE_SCHEDULE_RUNTIME
-};
+/* True if a LINEAR clause doesn't need copy in. True for iterator vars which
+ are always initialized inside of the loop construct, false otherwise. */
+#define OMP_CLAUSE_LINEAR_NO_COPYIN(NODE) \
+ (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR)->base.public_flag)
+
+/* True if a LINEAR clause doesn't need copy out. True for iterator vars which
+ are declared inside of the simd construct. */
+#define OMP_CLAUSE_LINEAR_NO_COPYOUT(NODE) \
+ TREE_PRIVATE (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR))
+
+#define OMP_CLAUSE_LINEAR_STEP(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR), 1)
+
+#define OMP_CLAUSE_SAFELEN_EXPR(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SAFELEN), 0)
+
+#define OMP_CLAUSE__SIMDUID__DECL(NODE) \
+ OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE__SIMDUID_), 0)
#define OMP_CLAUSE_SCHEDULE_KIND(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_SCHEDULE)->omp_clause.subcode.schedule_kind)
-enum omp_clause_default_kind
-{
- OMP_CLAUSE_DEFAULT_UNSPECIFIED,
- OMP_CLAUSE_DEFAULT_SHARED,
- OMP_CLAUSE_DEFAULT_NONE,
- OMP_CLAUSE_DEFAULT_PRIVATE,
- OMP_CLAUSE_DEFAULT_FIRSTPRIVATE
-};
-
#define OMP_CLAUSE_DEFAULT_KIND(NODE) \
(OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_DEFAULT)->omp_clause.subcode.default_kind)
-struct GTY(()) tree_exp {
- struct tree_typed typed;
- location_t locus;
- tree GTY ((special ("tree_exp"),
- desc ("TREE_CODE ((tree) &%0)")))
- operands[1];
-};
-
/* SSA_NAME accessors. */
/* Returns the IDENTIFIER_NODE giving the SSA name a name or NULL_TREE
@@ -1952,51 +1338,9 @@ struct GTY(()) tree_exp {
#define SSA_NAME_PTR_INFO(N) \
SSA_NAME_CHECK (N)->ssa_name.ptr_info
-/* Defined in tree-flow.h. */
-struct ptr_info_def;
-
-/* Immediate use linking structure. This structure is used for maintaining
- a doubly linked list of uses of an SSA_NAME. */
-typedef struct GTY(()) ssa_use_operand_d {
- struct ssa_use_operand_d* GTY((skip(""))) prev;
- struct ssa_use_operand_d* GTY((skip(""))) next;
- /* Immediate uses for a given SSA name are maintained as a cyclic
- list. To recognize the root of this list, the location field
- needs to point to the original SSA name. Since statements and
- SSA names are of different data types, we need this union. See
- the explanation in struct immediate_use_iterator_d. */
- union { gimple stmt; tree ssa_name; } GTY((skip(""))) loc;
- tree *GTY((skip(""))) use;
-} ssa_use_operand_t;
-
/* Return the immediate_use information for an SSA_NAME. */
#define SSA_NAME_IMM_USE_NODE(NODE) SSA_NAME_CHECK (NODE)->ssa_name.imm_uses
-struct GTY(()) tree_ssa_name {
- struct tree_typed typed;
-
- /* _DECL wrapped by this SSA name. */
- tree var;
-
- /* Statement that defines this SSA name. */
- gimple def_stmt;
-
- /* Pointer attributes used for alias analysis. */
- struct ptr_info_def *ptr_info;
-
- /* Immediate uses list for this SSA_NAME. */
- struct ssa_use_operand_d imm_uses;
-};
-
-struct GTY(()) phi_arg_d {
- /* imm_use MUST be the first element in struct because we do some
- pointer arithmetic with it. See phi_arg_index_from_use. */
- struct ssa_use_operand_d imm_use;
- tree def;
- location_t locus;
-};
-
-
#define OMP_CLAUSE_CODE(NODE) \
(OMP_CLAUSE_CHECK (NODE))->omp_clause.code
@@ -2009,25 +1353,6 @@ struct GTY(()) phi_arg_d {
#define OMP_CLAUSE_OPERAND(NODE, I) \
OMP_CLAUSE_ELT_CHECK (NODE, I)
-struct GTY(()) tree_omp_clause {
- struct tree_common common;
- location_t locus;
- enum omp_clause_code code;
- union omp_clause_subcode {
- enum omp_clause_default_kind default_kind;
- enum omp_clause_schedule_kind schedule_kind;
- enum tree_code reduction_code;
- } GTY ((skip)) subcode;
-
- /* The gimplification of OMP_CLAUSE_REDUCTION_{INIT,MERGE} for omp-low's
- usage. */
- gimple_seq gimple_reduction_init;
- gimple_seq gimple_reduction_merge;
-
- tree GTY ((length ("omp_clause_num_ops[OMP_CLAUSE_CODE ((tree)&%h)]"))) ops[1];
-};
-
-
/* In a BLOCK node. */
#define BLOCK_VARS(NODE) (BLOCK_CHECK (NODE)->block.vars)
#define BLOCK_NONLOCALIZED_VARS(NODE) \
@@ -2080,25 +1405,6 @@ struct GTY(()) tree_omp_clause {
#define BLOCK_SOURCE_LOCATION(NODE) (BLOCK_CHECK (NODE)->block.locus)
-struct GTY(()) tree_block {
- struct tree_base base;
- tree chain;
-
- unsigned abstract_flag : 1;
- unsigned block_num : 31;
-
- location_t locus;
-
- tree vars;
- vec<tree, va_gc> *nonlocalized_vars;
-
- tree subblocks;
- tree supercontext;
- tree abstract_origin;
- tree fragment_origin;
- tree fragment_chain;
-};
-
/* Define fields and accessors for nodes representing data types. */
/* See tree.def for documentation of the use of these fields.
@@ -2218,17 +1524,6 @@ extern enum machine_mode vector_type_mode (const_tree);
/* The address space the type is in. */
#define TYPE_ADDR_SPACE(NODE) (TYPE_CHECK (NODE)->base.u.bits.address_space)
-/* There is a TYPE_QUAL value for each type qualifier. They can be
- combined by bitwise-or to form the complete set of qualifiers for a
- type. */
-enum cv_qualifier
- {
- TYPE_UNQUALIFIED = 0x0,
- TYPE_QUAL_CONST = 0x1,
- TYPE_QUAL_VOLATILE = 0x2,
- TYPE_QUAL_RESTRICT = 0x4
- };
-
/* Encode/decode the named memory support as part of the qualifier. If more
than 8 qualifiers are added, these macros need to be adjusted. */
#define ENCODE_QUAL_ADDR_SPACE(NUM) ((NUM & 0xFF) << 8)
@@ -2314,6 +1609,10 @@ enum cv_qualifier
#define TYPE_CONTAINS_PLACEHOLDER_INTERNAL(NODE) \
(TYPE_CHECK (NODE)->type_common.contains_placeholder_bits)
+/* Nonzero if RECORD_TYPE represents a final derivation of class. */
+#define TYPE_FINAL_P(NODE) \
+ (RECORD_OR_UNION_CHECK (NODE)->base.default_def_flag)
+
/* The debug output functions use the symtab union field to store
information specific to the debugging format. The different debug
output hooks store different types in the union field. These three
@@ -2344,58 +1643,9 @@ enum cv_qualifier
#define TYPE_SYMTAB_IS_POINTER (1)
#define TYPE_SYMTAB_IS_DIE (2)
-struct die_struct;
-
-struct GTY(()) tree_type_common {
- struct tree_common common;
- tree size;
- tree size_unit;
- tree attributes;
- unsigned int uid;
-
- unsigned int precision : 10;
- unsigned no_force_blk_flag : 1;
- unsigned needs_constructing_flag : 1;
- unsigned transparent_aggr_flag : 1;
- unsigned restrict_flag : 1;
- unsigned contains_placeholder_bits : 2;
-
- ENUM_BITFIELD(machine_mode) mode : 8;
-
- unsigned string_flag : 1;
- unsigned lang_flag_0 : 1;
- unsigned lang_flag_1 : 1;
- unsigned lang_flag_2 : 1;
- unsigned lang_flag_3 : 1;
- unsigned lang_flag_4 : 1;
- unsigned lang_flag_5 : 1;
- unsigned lang_flag_6 : 1;
-
- unsigned int align;
- alias_set_type alias_set;
- tree pointer_to;
- tree reference_to;
- union tree_type_symtab {
- int GTY ((tag ("TYPE_SYMTAB_IS_ADDRESS"))) address;
- const char * GTY ((tag ("TYPE_SYMTAB_IS_POINTER"))) pointer;
- struct die_struct * GTY ((tag ("TYPE_SYMTAB_IS_DIE"))) die;
- } GTY ((desc ("debug_hooks->tree_type_symtab_field"))) symtab;
- tree name;
- tree next_variant;
- tree main_variant;
- tree context;
- tree canonical;
-};
-
#define TYPE_LANG_SPECIFIC(NODE) \
(TYPE_CHECK (NODE)->type_with_lang_specific.lang_specific)
-struct GTY(()) tree_type_with_lang_specific {
- struct tree_type_common common;
- /* Points to a structure whose details depend on the language in use. */
- struct lang_type *lang_specific;
-};
-
#define TYPE_VALUES(NODE) (ENUMERAL_TYPE_CHECK (NODE)->type_non_common.values)
#define TYPE_DOMAIN(NODE) (ARRAY_TYPE_CHECK (NODE)->type_non_common.values)
#define TYPE_FIELDS(NODE) \
@@ -2438,14 +1688,6 @@ struct GTY(()) tree_type_with_lang_specific {
#define TYPE_LANG_SLOT_1(NODE) \
(NOT_RECORD_OR_UNION_CHECK(NODE)->type_non_common.binfo)
-struct GTY(()) tree_type_non_common {
- struct tree_type_with_lang_specific with_lang_specific;
- tree values;
- tree minval;
- tree maxval;
- tree binfo;
-};
-
/* Define accessor macros for information about type inheritance
and basetypes.
@@ -2549,23 +1791,7 @@ struct GTY(()) tree_type_non_common {
#define BINFO_INHERITANCE_CHAIN(NODE) \
(TREE_BINFO_CHECK(NODE)->binfo.inheritance)
-struct GTY (()) tree_binfo {
- struct tree_common common;
-
- tree offset;
- tree vtable;
- tree virtuals;
- tree vptr_field;
- vec<tree, va_gc> *base_accesses;
- tree inheritance;
-
- tree vtt_subvtt;
- tree vtt_vptr;
-
- vec<tree, va_gc> base_binfos;
-};
-
/* Define fields and accessors for nodes representing declared names. */
/* Nonzero if DECL represents an SSA name or a variable that can possibly
@@ -2577,21 +1803,6 @@ struct GTY (()) tree_binfo {
|| TREE_CODE (DECL) == SSA_NAME)
-
-/* Enumerate visibility settings. */
-#ifndef SYMBOL_VISIBILITY_DEFINED
-#define SYMBOL_VISIBILITY_DEFINED
-enum symbol_visibility
-{
- VISIBILITY_DEFAULT,
- VISIBILITY_PROTECTED,
- VISIBILITY_HIDDEN,
- VISIBILITY_INTERNAL
-};
-#endif
-
-struct function;
-
#define DECL_CHAIN(NODE) (TREE_CHAIN (DECL_MINIMAL_CHECK (NODE)))
/* This is the name of the object as written by the user.
@@ -2627,6 +1838,9 @@ struct function;
#define DECL_SOURCE_FILE(NODE) LOCATION_FILE (DECL_SOURCE_LOCATION (NODE))
#define DECL_SOURCE_LINE(NODE) LOCATION_LINE (DECL_SOURCE_LOCATION (NODE))
#define DECL_SOURCE_COLUMN(NODE) LOCATION_COLUMN (DECL_SOURCE_LOCATION (NODE))
+/* This accessor returns TRUE if the decl it operates on was created
+ by a front-end or back-end rather than by user code. In this case
+ builtin-ness is indicated by source location. */
#define DECL_IS_BUILTIN(DECL) \
(LOCATION_LOCUS (DECL_SOURCE_LOCATION (DECL)) <= BUILTINS_LOCATION)
@@ -2646,15 +1860,6 @@ struct function;
/* If nonzero, decl's name shouldn't be emitted into debug info. */
#define DECL_NAMELESS(NODE) (DECL_MINIMAL_CHECK (NODE)->base.u.bits.nameless_flag)
-struct GTY(()) tree_decl_minimal {
- struct tree_common common;
- location_t locus;
- unsigned int uid;
- tree name;
- tree context;
-};
-
-
/* For any sort of a ..._DECL node, this points to the original (abstract)
decl node which this decl is an inlined/cloned instance of, or else it
is NULL indicating that this decl is not an instance of some other decl.
@@ -2812,73 +2017,6 @@ struct GTY(()) tree_decl_minimal {
#define DECL_GIMPLE_REG_P(DECL) \
DECL_COMMON_CHECK (DECL)->decl_common.gimple_reg_flag
-struct GTY(()) tree_decl_common {
- struct tree_decl_minimal common;
- tree size;
-
- ENUM_BITFIELD(machine_mode) mode : 8;
-
- unsigned nonlocal_flag : 1;
- unsigned virtual_flag : 1;
- unsigned ignored_flag : 1;
- unsigned abstract_flag : 1;
- unsigned artificial_flag : 1;
- unsigned preserve_flag: 1;
- unsigned debug_expr_is_from : 1;
-
- unsigned lang_flag_0 : 1;
- unsigned lang_flag_1 : 1;
- unsigned lang_flag_2 : 1;
- unsigned lang_flag_3 : 1;
- unsigned lang_flag_4 : 1;
- unsigned lang_flag_5 : 1;
- unsigned lang_flag_6 : 1;
- unsigned lang_flag_7 : 1;
- unsigned lang_flag_8 : 1;
-
- /* In LABEL_DECL, this is DECL_ERROR_ISSUED.
- In VAR_DECL and PARM_DECL, this is DECL_REGISTER. */
- unsigned decl_flag_0 : 1;
- /* In FIELD_DECL, this is DECL_BIT_FIELD
- In VAR_DECL and FUNCTION_DECL, this is DECL_EXTERNAL.
- In TYPE_DECL, this is TYPE_DECL_SUPPRESS_DEBUG. */
- unsigned decl_flag_1 : 1;
- /* In FIELD_DECL, this is DECL_NONADDRESSABLE_P
- In VAR_DECL, PARM_DECL and RESULT_DECL, this is
- DECL_HAS_VALUE_EXPR_P. */
- unsigned decl_flag_2 : 1;
- /* 1 bit unused. */
- unsigned decl_flag_3 : 1;
- /* Logically, these two would go in a theoretical base shared by var and
- parm decl. */
- unsigned gimple_reg_flag : 1;
- /* In VAR_DECL, PARM_DECL and RESULT_DECL, this is DECL_BY_REFERENCE. */
- unsigned decl_by_reference_flag : 1;
- /* In a VAR_DECL and PARM_DECL, this is DECL_READ_P. */
- unsigned decl_read_flag : 1;
- /* In a VAR_DECL or RESULT_DECL, this is DECL_NONSHAREABLE. */
- unsigned decl_nonshareable_flag : 1;
-
- /* DECL_OFFSET_ALIGN, used only for FIELD_DECLs. */
- unsigned int off_align : 8;
-
- /* 24 bits unused. */
-
- /* DECL_ALIGN. It should have the same size as TYPE_ALIGN. */
- unsigned int align;
-
- /* UID for points-to sets, stable over copying from inlining. */
- unsigned int pt_uid;
-
- tree size_unit;
- tree initial;
- tree attributes;
- tree abstract_origin;
-
- /* Points to a structure whose details depend on the language in use. */
- struct lang_decl *lang_specific;
-};
-
extern tree decl_value_expr_lookup (tree);
extern void decl_value_expr_insert (tree, tree);
@@ -2935,11 +2073,6 @@ extern void decl_value_expr_insert (tree, tree);
/* In VAR_DECL and PARM_DECL nodes, nonzero means declared `register'. */
#define DECL_REGISTER(NODE) (DECL_WRTL_CHECK (NODE)->decl_common.decl_flag_0)
-struct GTY(()) tree_decl_with_rtl {
- struct tree_decl_common common;
- rtx rtl;
-};
-
/* In a FIELD_DECL, this is the field position, counting in bytes, of the
DECL_OFFSET_ALIGN-bit-sized word containing the bit closest to the beginning
of the structure. */
@@ -3008,16 +2141,6 @@ struct GTY(()) tree_decl_with_rtl {
#define DECL_NONADDRESSABLE_P(NODE) \
(FIELD_DECL_CHECK (NODE)->decl_common.decl_flag_2)
-struct GTY(()) tree_field_decl {
- struct tree_decl_common common;
-
- tree offset;
- tree bit_field_type;
- tree qualifier;
- tree bit_offset;
- tree fcontext;
-};
-
/* A numeric unique identifier for a LABEL_DECL. The UID allocation is
dense, unique within any one function, and may be used to index arrays.
If the value is -1, then no UID has been assigned. */
@@ -3029,25 +2152,6 @@ struct GTY(()) tree_field_decl {
#define EH_LANDING_PAD_NR(NODE) \
(LABEL_DECL_CHECK (NODE)->label_decl.eh_landing_pad_nr)
-/* In LABEL_DECL nodes, nonzero means that an error message about
- jumping into such a binding contour has been printed for this label. */
-#define DECL_ERROR_ISSUED(NODE) \
- (LABEL_DECL_CHECK (NODE)->decl_common.decl_flag_0)
-
-struct GTY(()) tree_label_decl {
- struct tree_decl_with_rtl common;
- int label_decl_uid;
- int eh_landing_pad_nr;
-};
-
-struct GTY(()) tree_result_decl {
- struct tree_decl_with_rtl common;
-};
-
-struct GTY(()) tree_const_decl {
- struct tree_decl_common common;
-};
-
/* For a PARM_DECL, records the data type used to pass the argument,
which may be different from the type seen in the program. */
#define DECL_ARG_TYPE(NODE) (PARM_DECL_CHECK (NODE)->decl_common.initial)
@@ -3057,12 +2161,6 @@ struct GTY(()) tree_const_decl {
#define DECL_INCOMING_RTL(NODE) \
(PARM_DECL_CHECK (NODE)->parm_decl.incoming_rtl)
-struct GTY(()) tree_parm_decl {
- struct tree_decl_with_rtl common;
- rtx incoming_rtl;
-};
-
-
/* Nonzero for a given ..._DECL node means that no warnings should be
generated just because this node is unused. */
#define DECL_IN_SYSTEM_HEADER(NODE) \
@@ -3195,40 +2293,9 @@ struct GTY(()) tree_parm_decl {
#define DECL_HAS_IMPLICIT_SECTION_NAME_P(NODE) \
(DECL_WITH_VIS_CHECK (NODE)->decl_with_vis.implicit_section_name_p)
-struct GTY(()) tree_decl_with_vis {
- struct tree_decl_with_rtl common;
- tree assembler_name;
- tree section_name;
- tree comdat_group;
-
- /* Belong to VAR_DECL exclusively. */
- unsigned defer_output : 1;
- unsigned hard_register : 1;
- unsigned common_flag : 1;
- unsigned in_text_section : 1;
- unsigned in_constant_pool : 1;
- unsigned dllimport_flag : 1;
- /* Don't belong to VAR_DECL exclusively. */
- unsigned weak_flag : 1;
- /* When SECTION_NAME is implied by -ffunction-section. */
- unsigned implicit_section_name_p : 1;
-
- unsigned seen_in_bind_expr : 1;
- unsigned comdat_flag : 1;
- ENUM_BITFIELD(symbol_visibility) visibility : 2;
- unsigned visibility_specified : 1;
- /* Belongs to VAR_DECL exclusively. */
- ENUM_BITFIELD(tls_model) tls_model : 3;
-
- /* Belong to FUNCTION_DECL exclusively. */
- unsigned init_priority_p : 1;
- /* Used by C++ only. Might become a generic decl flag. */
- unsigned shadowed_for_var_p : 1;
- /* 14 unused bits. */
-};
-
extern tree decl_debug_expr_lookup (tree);
extern void decl_debug_expr_insert (tree, tree);
+
/* For VAR_DECL, this is set to an expression that it was split from. */
#define DECL_HAS_DEBUG_EXPR_P(NODE) \
(VAR_DECL_CHECK (NODE)->decl_common.debug_expr_is_from)
@@ -3238,9 +2305,6 @@ extern void decl_debug_expr_insert (tree, tree);
#define SET_DECL_DEBUG_EXPR(NODE, VAL) \
(decl_debug_expr_insert (VAR_DECL_CHECK (NODE), VAL))
-/* An initialization priority. */
-typedef unsigned short priority_type;
-
extern priority_type decl_init_priority_lookup (tree);
extern priority_type decl_fini_priority_lookup (tree);
extern void decl_init_priority_insert (tree, priority_type);
@@ -3280,11 +2344,6 @@ extern void decl_fini_priority_insert (tree, priority_type);
#define DECL_NONLOCAL_FRAME(NODE) \
(VAR_DECL_CHECK (NODE)->base.default_def_flag)
-struct GTY(()) tree_var_decl {
- struct tree_decl_with_vis common;
-};
-
-
/* This field is used to reference anything in decl.result and is meant only
for use by the garbage collector. */
#define DECL_RESULT_FLD(NODE) \
@@ -3301,19 +2360,6 @@ struct GTY(()) tree_var_decl {
#define DECL_VINDEX(NODE) \
(DECL_NON_COMMON_CHECK (NODE)->decl_non_common.vindex)
-struct GTY(())
- tree_decl_non_common {
- struct tree_decl_with_vis common;
- /* C++ uses this in namespaces. */
- tree saved_tree;
- /* C++ uses this in templates. */
- tree arguments;
- /* Almost all FE's use this. */
- tree result;
- /* C++ uses this in namespaces and function_decls. */
- tree vindex;
-};
-
/* In FUNCTION_DECL, holds the decl for the return value. */
#define DECL_RESULT(NODE) (FUNCTION_DECL_CHECK (NODE)->decl_non_common.result)
@@ -3443,7 +2489,13 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
#define DECL_STRUCT_FUNCTION(NODE) \
(FUNCTION_DECL_CHECK (NODE)->function_decl.f)
-/* In a FUNCTION_DECL, nonzero means a built in function. */
+/* In a FUNCTION_DECL, nonzero means a built in function of a
+ standard library or more generally a built in function that is
+ recognized by optimizers and expanders.
+
+ Note that it is different from the DECL_IS_BUILTIN accessor. For
+ instance, user declared prototypes of C library functions are not
+ DECL_IS_BUILTIN but may be DECL_BUILT_IN. */
#define DECL_BUILT_IN(NODE) (DECL_BUILT_IN_CLASS (NODE) != NOT_BUILT_IN)
/* For a builtin function, identify which part of the compiler defined it. */
@@ -3474,53 +2526,22 @@ extern vec<tree, va_gc> **decl_debug_args_insert (tree);
#define DECL_FUNCTION_VERSIONED(NODE)\
(FUNCTION_DECL_CHECK (NODE)->function_decl.versioned_function)
-/* FUNCTION_DECL inherits from DECL_NON_COMMON because of the use of the
- arguments/result/saved_tree fields by front ends. It was either inherit
- FUNCTION_DECL from non_common, or inherit non_common from FUNCTION_DECL,
- which seemed a bit strange. */
-
-struct GTY(()) tree_function_decl {
- struct tree_decl_non_common common;
-
- struct function *f;
-
- /* The personality function. Used for stack unwinding. */
- tree personality;
-
- /* Function specific options that are used by this function. */
- tree function_specific_target; /* target options */
- tree function_specific_optimization; /* optimization options */
-
- /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
- DECL_FUNCTION_CODE. Otherwise unused.
- ??? The bitfield needs to be able to hold all target function
- codes as well. */
- ENUM_BITFIELD(built_in_function) function_code : 11;
- ENUM_BITFIELD(built_in_class) built_in_class : 2;
-
- unsigned static_ctor_flag : 1;
- unsigned static_dtor_flag : 1;
- unsigned uninlinable : 1;
-
- unsigned possibly_inlined : 1;
- unsigned novops_flag : 1;
- unsigned returns_twice_flag : 1;
- unsigned malloc_flag : 1;
- unsigned operator_new_flag : 1;
- unsigned declared_inline_flag : 1;
- unsigned regdecl_flag : 1;
- unsigned no_inline_warning_flag : 1;
-
- unsigned no_instrument_function_entry_exit : 1;
- unsigned no_limit_stack : 1;
- unsigned disregard_inline_limits : 1;
- unsigned pure_flag : 1;
- unsigned looping_const_or_pure_flag : 1;
- unsigned has_debug_args_flag : 1;
- unsigned tm_clone_flag : 1;
- unsigned versioned_function : 1;
- /* No bits left. */
-};
+/* In FUNCTION_DECL, this is set if this function is a C++ constructor.
+ Devirtualization machinery uses this knowledge for determing type of the
+ object constructed. Also we assume that constructor address is not
+ important. */
+#define DECL_CXX_CONSTRUCTOR_P(NODE)\
+ (FUNCTION_DECL_CHECK (NODE)->decl_with_vis.cxx_constructor)
+
+/* In FUNCTION_DECL, this is set if this function is a C++ destructor.
+ Devirtualization machinery uses this to track types in destruction. */
+#define DECL_CXX_DESTRUCTOR_P(NODE)\
+ (FUNCTION_DECL_CHECK (NODE)->decl_with_vis.cxx_destructor)
+
+/* In FUNCTION_DECL that represent an virtual method this is set when
+ the method is final. */
+#define DECL_FINAL_P(NODE)\
+ (FUNCTION_DECL_CHECK (NODE)->decl_with_vis.final)
/* The source language of the translation-unit. */
#define TRANSLATION_UNIT_LANGUAGE(NODE) \
@@ -3528,17 +2549,6 @@ struct GTY(()) tree_function_decl {
/* TRANSLATION_UNIT_DECL inherits from DECL_MINIMAL. */
-struct GTY(()) tree_translation_unit_decl {
- struct tree_decl_common common;
- /* Source language of this translation unit. Used for DWARF output. */
- const char * GTY((skip(""))) language;
- /* TODO: Non-optimization used to build this translation unit. */
- /* TODO: Root of a partial DWARF tree for global types and decls. */
-};
-
-/* A vector of all translation-units. */
-extern GTY (()) vec<tree, va_gc> *all_translation_units;
-
/* For a TYPE_DECL, holds the "original" type. (TREE_TYPE has the copy.) */
#define DECL_ORIGINAL_TYPE(NODE) \
(TYPE_DECL_CHECK (NODE)->decl_non_common.result)
@@ -3554,11 +2564,6 @@ extern GTY (()) vec<tree, va_gc> *all_translation_units;
#define IMPORTED_DECL_ASSOCIATED_DECL(NODE) \
(DECL_INITIAL (IMPORTED_DECL_CHECK (NODE)))
-struct GTY(()) tree_type_decl {
- struct tree_decl_non_common common;
-
-};
-
/* A STATEMENT_LIST chains statements together in GENERIC and GIMPLE.
To reduce overhead, the nodes containing the statements are not trees.
This avoids the overhead of tree_common on all linked list elements.
@@ -3570,38 +2575,6 @@ struct GTY(()) tree_type_decl {
#define STATEMENT_LIST_TAIL(NODE) \
(STATEMENT_LIST_CHECK (NODE)->stmt_list.tail)
-struct GTY ((chain_next ("%h.next"), chain_prev ("%h.prev"))) tree_statement_list_node
- {
- struct tree_statement_list_node *prev;
- struct tree_statement_list_node *next;
- tree stmt;
-};
-
-struct GTY(()) tree_statement_list
- {
- struct tree_typed typed;
- struct tree_statement_list_node *head;
- struct tree_statement_list_node *tail;
-};
-
-
-/* Optimization options used by a function. */
-
-struct GTY(()) tree_optimization_option {
- struct tree_common common;
-
- /* The optimization options used by the user. */
- struct cl_optimization opts;
-
- /* Target optabs for this set of optimization options. This is of
- type `struct target_optabs *'. */
- unsigned char *GTY ((atomic)) optabs;
-
- /* The value of this_target_optabs against which the optabs above were
- generated. */
- struct target_optabs *GTY ((skip)) base_optabs;
-};
-
#define TREE_OPTIMIZATION(NODE) \
(&OPTIMIZATION_NODE_CHECK (NODE)->optimization.opts)
@@ -3616,71 +2589,12 @@ extern tree build_optimization_node (void);
extern void init_tree_optimization_optabs (tree);
-/* Target options used by a function. */
-
-struct GTY(()) tree_target_option {
- struct tree_common common;
-
- /* The optimization options used by the user. */
- struct cl_target_option opts;
-};
-
#define TREE_TARGET_OPTION(NODE) \
(&TARGET_OPTION_NODE_CHECK (NODE)->target_option.opts)
/* Return a tree node that encapsulates the current target options. */
extern tree build_target_option_node (void);
-
-/* Define the overall contents of a tree node.
- It may be any of the structures declared above
- for various types of node. */
-
-union GTY ((ptr_alias (union lang_tree_node),
- desc ("tree_node_structure (&%h)"), variable_size)) tree_node {
- struct tree_base GTY ((tag ("TS_BASE"))) base;
- struct tree_typed GTY ((tag ("TS_TYPED"))) typed;
- struct tree_common GTY ((tag ("TS_COMMON"))) common;
- struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;
- struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst;
- struct tree_fixed_cst GTY ((tag ("TS_FIXED_CST"))) fixed_cst;
- struct tree_vector GTY ((tag ("TS_VECTOR"))) vector;
- struct tree_string GTY ((tag ("TS_STRING"))) string;
- struct tree_complex GTY ((tag ("TS_COMPLEX"))) complex;
- struct tree_identifier GTY ((tag ("TS_IDENTIFIER"))) identifier;
- struct tree_decl_minimal GTY((tag ("TS_DECL_MINIMAL"))) decl_minimal;
- struct tree_decl_common GTY ((tag ("TS_DECL_COMMON"))) decl_common;
- struct tree_decl_with_rtl GTY ((tag ("TS_DECL_WRTL"))) decl_with_rtl;
- struct tree_decl_non_common GTY ((tag ("TS_DECL_NON_COMMON"))) decl_non_common;
- struct tree_parm_decl GTY ((tag ("TS_PARM_DECL"))) parm_decl;
- struct tree_decl_with_vis GTY ((tag ("TS_DECL_WITH_VIS"))) decl_with_vis;
- struct tree_var_decl GTY ((tag ("TS_VAR_DECL"))) var_decl;
- struct tree_field_decl GTY ((tag ("TS_FIELD_DECL"))) field_decl;
- struct tree_label_decl GTY ((tag ("TS_LABEL_DECL"))) label_decl;
- struct tree_result_decl GTY ((tag ("TS_RESULT_DECL"))) result_decl;
- struct tree_const_decl GTY ((tag ("TS_CONST_DECL"))) const_decl;
- struct tree_type_decl GTY ((tag ("TS_TYPE_DECL"))) type_decl;
- struct tree_function_decl GTY ((tag ("TS_FUNCTION_DECL"))) function_decl;
- struct tree_translation_unit_decl GTY ((tag ("TS_TRANSLATION_UNIT_DECL")))
- translation_unit_decl;
- struct tree_type_common GTY ((tag ("TS_TYPE_COMMON"))) type_common;
- struct tree_type_with_lang_specific GTY ((tag ("TS_TYPE_WITH_LANG_SPECIFIC")))
- type_with_lang_specific;
- struct tree_type_non_common GTY ((tag ("TS_TYPE_NON_COMMON")))
- type_non_common;
- struct tree_list GTY ((tag ("TS_LIST"))) list;
- struct tree_vec GTY ((tag ("TS_VEC"))) vec;
- struct tree_exp GTY ((tag ("TS_EXP"))) exp;
- struct tree_ssa_name GTY ((tag ("TS_SSA_NAME"))) ssa_name;
- struct tree_block GTY ((tag ("TS_BLOCK"))) block;
- struct tree_binfo GTY ((tag ("TS_BINFO"))) binfo;
- struct tree_statement_list GTY ((tag ("TS_STATEMENT_LIST"))) stmt_list;
- struct tree_constructor GTY ((tag ("TS_CONSTRUCTOR"))) constructor;
- struct tree_omp_clause GTY ((tag ("TS_OMP_CLAUSE"))) omp_clause;
- struct tree_optimization_option GTY ((tag ("TS_OPTIMIZATION"))) optimization;
- struct tree_target_option GTY ((tag ("TS_TARGET_OPTION"))) target_option;
-};
-
#if defined ENABLE_TREE_CHECKING && (GCC_VERSION >= 2007)
inline tree
@@ -4160,166 +3074,6 @@ tree_operand_check_code (const_tree __t, enum tree_code __code, int __i,
#endif
-
-/* Standard named or nameless data types of the C compiler. */
-
-enum tree_index
-{
- TI_ERROR_MARK,
- TI_INTQI_TYPE,
- TI_INTHI_TYPE,
- TI_INTSI_TYPE,
- TI_INTDI_TYPE,
- TI_INTTI_TYPE,
-
- TI_UINTQI_TYPE,
- TI_UINTHI_TYPE,
- TI_UINTSI_TYPE,
- TI_UINTDI_TYPE,
- TI_UINTTI_TYPE,
-
- TI_UINT16_TYPE,
- TI_UINT32_TYPE,
- TI_UINT64_TYPE,
-
- TI_INTEGER_ZERO,
- TI_INTEGER_ONE,
- TI_INTEGER_THREE,
- TI_INTEGER_MINUS_ONE,
- TI_NULL_POINTER,
-
- TI_SIZE_ZERO,
- TI_SIZE_ONE,
-
- TI_BITSIZE_ZERO,
- TI_BITSIZE_ONE,
- TI_BITSIZE_UNIT,
-
- TI_PUBLIC,
- TI_PROTECTED,
- TI_PRIVATE,
-
- TI_BOOLEAN_FALSE,
- TI_BOOLEAN_TRUE,
-
- TI_COMPLEX_INTEGER_TYPE,
- TI_COMPLEX_FLOAT_TYPE,
- TI_COMPLEX_DOUBLE_TYPE,
- TI_COMPLEX_LONG_DOUBLE_TYPE,
-
- TI_FLOAT_TYPE,
- TI_DOUBLE_TYPE,
- TI_LONG_DOUBLE_TYPE,
-
- TI_FLOAT_PTR_TYPE,
- TI_DOUBLE_PTR_TYPE,
- TI_LONG_DOUBLE_PTR_TYPE,
- TI_INTEGER_PTR_TYPE,
-
- TI_VOID_TYPE,
- TI_PTR_TYPE,
- TI_CONST_PTR_TYPE,
- TI_SIZE_TYPE,
- TI_PID_TYPE,
- TI_PTRDIFF_TYPE,
- TI_VA_LIST_TYPE,
- TI_VA_LIST_GPR_COUNTER_FIELD,
- TI_VA_LIST_FPR_COUNTER_FIELD,
- TI_BOOLEAN_TYPE,
- TI_FILEPTR_TYPE,
-
- TI_DFLOAT32_TYPE,
- TI_DFLOAT64_TYPE,
- TI_DFLOAT128_TYPE,
- TI_DFLOAT32_PTR_TYPE,
- TI_DFLOAT64_PTR_TYPE,
- TI_DFLOAT128_PTR_TYPE,
-
- TI_VOID_LIST_NODE,
-
- TI_MAIN_IDENTIFIER,
-
- TI_SAT_SFRACT_TYPE,
- TI_SAT_FRACT_TYPE,
- TI_SAT_LFRACT_TYPE,
- TI_SAT_LLFRACT_TYPE,
- TI_SAT_USFRACT_TYPE,
- TI_SAT_UFRACT_TYPE,
- TI_SAT_ULFRACT_TYPE,
- TI_SAT_ULLFRACT_TYPE,
- TI_SFRACT_TYPE,
- TI_FRACT_TYPE,
- TI_LFRACT_TYPE,
- TI_LLFRACT_TYPE,
- TI_USFRACT_TYPE,
- TI_UFRACT_TYPE,
- TI_ULFRACT_TYPE,
- TI_ULLFRACT_TYPE,
- TI_SAT_SACCUM_TYPE,
- TI_SAT_ACCUM_TYPE,
- TI_SAT_LACCUM_TYPE,
- TI_SAT_LLACCUM_TYPE,
- TI_SAT_USACCUM_TYPE,
- TI_SAT_UACCUM_TYPE,
- TI_SAT_ULACCUM_TYPE,
- TI_SAT_ULLACCUM_TYPE,
- TI_SACCUM_TYPE,
- TI_ACCUM_TYPE,
- TI_LACCUM_TYPE,
- TI_LLACCUM_TYPE,
- TI_USACCUM_TYPE,
- TI_UACCUM_TYPE,
- TI_ULACCUM_TYPE,
- TI_ULLACCUM_TYPE,
- TI_QQ_TYPE,
- TI_HQ_TYPE,
- TI_SQ_TYPE,
- TI_DQ_TYPE,
- TI_TQ_TYPE,
- TI_UQQ_TYPE,
- TI_UHQ_TYPE,
- TI_USQ_TYPE,
- TI_UDQ_TYPE,
- TI_UTQ_TYPE,
- TI_SAT_QQ_TYPE,
- TI_SAT_HQ_TYPE,
- TI_SAT_SQ_TYPE,
- TI_SAT_DQ_TYPE,
- TI_SAT_TQ_TYPE,
- TI_SAT_UQQ_TYPE,
- TI_SAT_UHQ_TYPE,
- TI_SAT_USQ_TYPE,
- TI_SAT_UDQ_TYPE,
- TI_SAT_UTQ_TYPE,
- TI_HA_TYPE,
- TI_SA_TYPE,
- TI_DA_TYPE,
- TI_TA_TYPE,
- TI_UHA_TYPE,
- TI_USA_TYPE,
- TI_UDA_TYPE,
- TI_UTA_TYPE,
- TI_SAT_HA_TYPE,
- TI_SAT_SA_TYPE,
- TI_SAT_DA_TYPE,
- TI_SAT_TA_TYPE,
- TI_SAT_UHA_TYPE,
- TI_SAT_USA_TYPE,
- TI_SAT_UDA_TYPE,
- TI_SAT_UTA_TYPE,
-
- TI_OPTIMIZATION_DEFAULT,
- TI_OPTIMIZATION_CURRENT,
- TI_TARGET_OPTION_DEFAULT,
- TI_TARGET_OPTION_CURRENT,
- TI_CURRENT_TARGET_PRAGMA,
- TI_CURRENT_OPTIMIZE_PRAGMA,
-
- TI_MAX
-};
-
-extern GTY(()) tree global_trees[TI_MAX];
-
#define error_mark_node global_trees[TI_ERROR_MARK]
#define intQI_type_node global_trees[TI_INTQI_TYPE]
@@ -4383,6 +3137,7 @@ extern GTY(()) tree global_trees[TI_MAX];
#define va_list_fpr_counter_field global_trees[TI_VA_LIST_FPR_COUNTER_FIELD]
/* The C type `FILE *'. */
#define fileptr_type_node global_trees[TI_FILEPTR_TYPE]
+#define pointer_sized_int_node global_trees[TI_POINTER_SIZED_TYPE]
#define boolean_type_node global_trees[TI_BOOLEAN_TYPE]
#define boolean_false_node global_trees[TI_BOOLEAN_FALSE]
@@ -4499,34 +3254,6 @@ extern GTY(()) tree global_trees[TI_MAX];
#define current_target_pragma global_trees[TI_CURRENT_TARGET_PRAGMA]
#define current_optimize_pragma global_trees[TI_CURRENT_OPTIMIZE_PRAGMA]
-/* An enumeration of the standard C integer types. These must be
- ordered so that shorter types appear before longer ones, and so
- that signed types appear before unsigned ones, for the correct
- functioning of interpret_integer() in c-lex.c. */
-enum integer_type_kind
-{
- itk_char,
- itk_signed_char,
- itk_unsigned_char,
- itk_short,
- itk_unsigned_short,
- itk_int,
- itk_unsigned_int,
- itk_long,
- itk_unsigned_long,
- itk_long_long,
- itk_unsigned_long_long,
- itk_int128,
- itk_unsigned_int128,
- itk_none
-};
-
-typedef enum integer_type_kind integer_type_kind;
-
-/* The standard C integer types. Use integer_type_kind to index into
- this array. */
-extern GTY(()) tree integer_types[itk_none];
-
#define char_type_node integer_types[itk_char]
#define signed_char_type_node integer_types[itk_signed_char]
#define unsigned_char_type_node integer_types[itk_unsigned_char]
@@ -4540,34 +3267,7 @@ extern GTY(()) tree integer_types[itk_none];
#define long_long_unsigned_type_node integer_types[itk_unsigned_long_long]
#define int128_integer_type_node integer_types[itk_int128]
#define int128_unsigned_type_node integer_types[itk_unsigned_int128]
-
-/* A pointer-to-function member type looks like:
-
- struct {
- __P __pfn;
- ptrdiff_t __delta;
- };
- If __pfn is NULL, it is a NULL pointer-to-member-function.
-
- (Because the vtable is always the first thing in the object, we
- don't need its offset.) If the function is virtual, then PFN is
- one plus twice the index into the vtable; otherwise, it is just a
- pointer to the function.
-
- Unfortunately, using the lowest bit of PFN doesn't work in
- architectures that don't impose alignment requirements on function
- addresses, or that use the lowest bit to tell one ISA from another,
- for example. For such architectures, we use the lowest bit of
- DELTA instead of the lowest bit of the PFN, and DELTA will be
- multiplied by 2. */
-
-enum ptrmemfunc_vbit_where_t
-{
- ptrmemfunc_vbit_in_pfn,
- ptrmemfunc_vbit_in_delta
-};
-
#define NULL_TREE (tree) NULL
/* True if NODE is an erroneous expression. */
@@ -4783,6 +3483,7 @@ extern tree build_translation_unit_decl (tree);
extern tree build_block (tree, tree, tree, tree);
extern tree build_empty_stmt (location_t);
extern tree build_omp_clause (location_t, enum omp_clause_code);
+extern tree find_omp_clause (tree, enum omp_clause_code);
extern tree build_vl_exp_stat (enum tree_code, int MEM_STAT_DECL);
#define build_vl_exp(c,n) build_vl_exp_stat (c,n MEM_STAT_INFO)
@@ -4923,82 +3624,7 @@ extern tree build_type_attribute_qual_variant (tree, tree, int);
warning to be generated). */
extern int comp_type_attributes (const_tree, const_tree);
-/* Structure describing an attribute and a function to handle it. */
-struct attribute_spec
-{
- /* The name of the attribute (without any leading or trailing __),
- or NULL to mark the end of a table of attributes. */
- const char *name;
- /* The minimum length of the list of arguments of the attribute. */
- int min_length;
- /* The maximum length of the list of arguments of the attribute
- (-1 for no maximum). */
- int max_length;
- /* Whether this attribute requires a DECL. If it does, it will be passed
- from types of DECLs, function return types and array element types to
- the DECLs, function types and array types respectively; but when
- applied to a type in any other circumstances, it will be ignored with
- a warning. (If greater control is desired for a given attribute,
- this should be false, and the flags argument to the handler may be
- used to gain greater control in that case.) */
- bool decl_required;
- /* Whether this attribute requires a type. If it does, it will be passed
- from a DECL to the type of that DECL. */
- bool type_required;
- /* Whether this attribute requires a function (or method) type. If it does,
- it will be passed from a function pointer type to the target type,
- and from a function return type (which is not itself a function
- pointer type) to the function type. */
- bool function_type_required;
- /* Function to handle this attribute. NODE points to the node to which
- the attribute is to be applied. If a DECL, it should be modified in
- place; if a TYPE, a copy should be created. NAME is the name of the
- attribute (possibly with leading or trailing __). ARGS is the TREE_LIST
- of the arguments (which may be NULL). FLAGS gives further information
- about the context of the attribute. Afterwards, the attributes will
- be added to the DECL_ATTRIBUTES or TYPE_ATTRIBUTES, as appropriate,
- unless *NO_ADD_ATTRS is set to true (which should be done on error,
- as well as in any other cases when the attributes should not be added
- to the DECL or TYPE). Depending on FLAGS, any attributes to be
- applied to another type or DECL later may be returned;
- otherwise the return value should be NULL_TREE. This pointer may be
- NULL if no special handling is required beyond the checks implied
- by the rest of this structure. */
- tree (*handler) (tree *node, tree name, tree args,
- int flags, bool *no_add_attrs);
- /* Specifies if attribute affects type's identity. */
- bool affects_type_identity;
-};
-
-/* Flags that may be passed in the third argument of decl_attributes, and
- to handler functions for attributes. */
-enum attribute_flags
-{
- /* The type passed in is the type of a DECL, and any attributes that
- should be passed in again to be applied to the DECL rather than the
- type should be returned. */
- ATTR_FLAG_DECL_NEXT = 1,
- /* The type passed in is a function return type, and any attributes that
- should be passed in again to be applied to the function type rather
- than the return type should be returned. */
- ATTR_FLAG_FUNCTION_NEXT = 2,
- /* The type passed in is an array element type, and any attributes that
- should be passed in again to be applied to the array type rather
- than the element type should be returned. */
- ATTR_FLAG_ARRAY_NEXT = 4,
- /* The type passed in is a structure, union or enumeration type being
- created, and should be modified in place. */
- ATTR_FLAG_TYPE_IN_PLACE = 8,
- /* The attributes are being applied by default to a library function whose
- name indicates known behavior, and should be silently ignored if they
- are not in fact compatible with the function type. */
- ATTR_FLAG_BUILT_IN = 16,
- /* A given attribute has been parsed as a C++-11 attribute. */
- ATTR_FLAG_CXX11 = 32
-};
-
/* Default versions of target-overridable functions. */
-
extern tree merge_decl_attributes (tree, tree);
extern tree merge_type_attributes (tree, tree);
@@ -5113,41 +3739,6 @@ extern void finish_builtin_struct (tree, const char *,
extern void layout_type (tree);
-/* These functions allow a front-end to perform a manual layout of a
- RECORD_TYPE. (For instance, if the placement of subsequent fields
- depends on the placement of fields so far.) Begin by calling
- start_record_layout. Then, call place_field for each of the
- fields. Then, call finish_record_layout. See layout_type for the
- default way in which these functions are used. */
-
-typedef struct record_layout_info_s
-{
- /* The RECORD_TYPE that we are laying out. */
- tree t;
- /* The offset into the record so far, in bytes, not including bits in
- BITPOS. */
- tree offset;
- /* The last known alignment of SIZE. */
- unsigned int offset_align;
- /* The bit position within the last OFFSET_ALIGN bits, in bits. */
- tree bitpos;
- /* The alignment of the record so far, in bits. */
- unsigned int record_align;
- /* The alignment of the record so far, ignoring #pragma pack and
- __attribute__ ((packed)), in bits. */
- unsigned int unpacked_align;
- /* The previous field laid out. */
- tree prev_field;
- /* The static variables (i.e., class variables, as opposed to
- instance variables) encountered in T. */
- vec<tree, va_gc> *pending_statics;
- /* Bits remaining in the current alignment group */
- int remaining_in_alignment;
- /* True if we've seen a packed field that didn't have normal
- alignment anyway. */
- int packed_maybe_necessary;
-} *record_layout_info;
-
extern record_layout_info start_record_layout (tree);
extern tree bit_from_pos (tree, tree);
extern tree byte_from_pos (tree, tree);
@@ -5207,20 +3798,6 @@ extern HOST_WIDE_INT int_bit_position (const_tree);
extern tree byte_position (const_tree);
extern HOST_WIDE_INT int_byte_position (const_tree);
-/* Define data structures, macros, and functions for handling sizes
- and the various types used to represent sizes. */
-
-enum size_type_kind
-{
- stk_sizetype, /* Normal representation of sizes in bytes. */
- stk_ssizetype, /* Signed representation of sizes in bytes. */
- stk_bitsizetype, /* Normal representation of sizes in bits. */
- stk_sbitsizetype, /* Signed representation of sizes in bits. */
- stk_type_kind_last
-};
-
-extern GTY(()) tree sizetype_tab[(int) stk_type_kind_last];
-
#define sizetype sizetype_tab[(int) stk_sizetype]
#define bitsizetype sizetype_tab[(int) stk_bitsizetype]
#define ssizetype sizetype_tab[(int) stk_ssizetype]
@@ -5252,9 +3829,6 @@ extern void finalize_size_functions (void);
+ (BITS_PER_UNIT > 8) + (BITS_PER_UNIT > 16) + (BITS_PER_UNIT > 32) \
+ (BITS_PER_UNIT > 64) + (BITS_PER_UNIT > 128) + (BITS_PER_UNIT > 256))
-/* If nonzero, an upper limit on alignment of structure fields, in bits, */
-extern unsigned int maximum_field_alignment;
-
/* Concatenate two lists (chains of TREE_LIST nodes) X and Y
by making the last node in X point to Y.
Returns X, except if X is 0 returns Y. */
@@ -5529,25 +4103,6 @@ extern tree decl_type_context (const_tree);
/* Return 1 if EXPR is the real constant zero. */
extern int real_zerop (const_tree);
-
-/* Declare commonly used variables for tree structure. */
-
-/* Nonzero means lvalues are limited to those valid in pedantic ANSI C.
- Zero means allow extended lvalues. */
-
-extern int pedantic_lvalues;
-
-/* Points to the FUNCTION_DECL of the function whose body we are reading. */
-
-extern GTY(()) tree current_function_decl;
-
-/* Nonzero means a FUNC_BEGIN label was emitted. */
-extern GTY(()) const char * current_function_func_begin_label;
-
-/* Iterator for going through the function arguments. */
-typedef struct {
- tree next; /* TREE_LIST pointing to the next argument */
-} function_args_iterator;
/* Initialize the iterator I with arguments from function FNDECL */
@@ -5753,14 +4308,6 @@ extern void fold_undefer_overflow_warnings (bool, const_gimple, int);
extern void fold_undefer_and_ignore_overflow_warnings (void);
extern bool fold_deferring_overflow_warnings_p (void);
extern tree fold_fma (location_t, tree, tree, tree, tree);
-
-enum operand_equal_flag
-{
- OEP_ONLY_CONST = 1,
- OEP_PURE_SAME = 2,
- OEP_CONSTANT_ADDRESS_OF = 4
-};
-
extern int operand_equal_p (const_tree, const_tree, unsigned int);
extern int multiple_of_p (tree, const_tree, const_tree);
#define omit_one_operand(T1,T2,T3)\
@@ -5974,10 +4521,13 @@ extern location_t tree_nonartificial_location (tree);
extern tree block_ultimate_origin (const_tree);
extern tree get_binfo_at_offset (tree, HOST_WIDE_INT, tree);
+extern bool virtual_method_call_p (tree);
+extern tree obj_type_ref_class (tree ref);
extern bool types_same_for_odr (tree type1, tree type2);
extern tree get_ref_base_and_extent (tree, HOST_WIDE_INT *,
HOST_WIDE_INT *, HOST_WIDE_INT *);
extern bool contains_bitfld_component_ref_p (const_tree);
+extern bool type_in_anonymous_namespace_p (tree);
/* In tree-nested.c */
extern tree build_addr (tree, tree);
@@ -6042,70 +4592,10 @@ extern bool debug_find_tree (tree, tree);
extern tree build_duplicate_type (tree);
/* In calls.c */
-
-/* Nonzero if this is a call to a function whose return value depends
- solely on its arguments, has no side effects, and does not read
- global memory. This corresponds to TREE_READONLY for function
- decls. */
-#define ECF_CONST (1 << 0)
-/* Nonzero if this is a call to "pure" function (like const function,
- but may read memory. This corresponds to DECL_PURE_P for function
- decls. */
-#define ECF_PURE (1 << 1)
-/* Nonzero if this is ECF_CONST or ECF_PURE but cannot be proven to no
- infinite loop. This corresponds to DECL_LOOPING_CONST_OR_PURE_P
- for function decls.*/
-#define ECF_LOOPING_CONST_OR_PURE (1 << 2)
-/* Nonzero if this call will never return. */
-#define ECF_NORETURN (1 << 3)
-/* Nonzero if this is a call to malloc or a related function. */
-#define ECF_MALLOC (1 << 4)
-/* Nonzero if it is plausible that this is a call to alloca. */
-#define ECF_MAY_BE_ALLOCA (1 << 5)
-/* Nonzero if this is a call to a function that won't throw an exception. */
-#define ECF_NOTHROW (1 << 6)
-/* Nonzero if this is a call to setjmp or a related function. */
-#define ECF_RETURNS_TWICE (1 << 7)
-/* Nonzero if this call replaces the current stack frame. */
-#define ECF_SIBCALL (1 << 8)
-/* Function does not read or write memory (but may have side effects, so
- it does not necessarily fit ECF_CONST). */
-#define ECF_NOVOPS (1 << 9)
-/* The function does not lead to calls within current function unit. */
-#define ECF_LEAF (1 << 10)
-/* Nonzero if this call does not affect transactions. */
-#define ECF_TM_PURE (1 << 11)
-/* Nonzero if this call is into the transaction runtime library. */
-#define ECF_TM_BUILTIN (1 << 12)
-
extern int flags_from_decl_or_type (const_tree);
extern int call_expr_flags (const_tree);
extern void set_call_expr_flags (tree, int);
-/* Call argument flags. */
-
-/* Nonzero if the argument is not dereferenced recursively, thus only
- directly reachable memory is read or written. */
-#define EAF_DIRECT (1 << 0)
-/* Nonzero if memory reached by the argument is not clobbered. */
-#define EAF_NOCLOBBER (1 << 1)
-/* Nonzero if the argument does not escape. */
-#define EAF_NOESCAPE (1 << 2)
-/* Nonzero if the argument is not used by the function. */
-#define EAF_UNUSED (1 << 3)
-
-/* Call return flags. */
-
-/* Mask for the argument number that is returned. Lower two bits of
- the return flags, encodes argument slots zero to three. */
-#define ERF_RETURN_ARG_MASK (3)
-/* Nonzero if the return value is equal to the argument number
- flags & ERF_RETURN_ARG_MASK. */
-#define ERF_RETURNS_ARG (1 << 2)
-/* Nonzero if the return value does not alias with anything. Functions
- with the malloc attribute have this set on their return value. */
-#define ERF_NOALIAS (1 << 3)
-
extern int setjmp_call_p (const_tree);
extern bool gimple_alloca_call_p (const_gimple);
extern bool alloca_call_p (const_tree);
@@ -6206,19 +4696,6 @@ extern tree tree_overlaps_hard_reg_set (tree, HARD_REG_SET *);
/* In tree-inline.c */
-/* The type of a set of already-visited pointers. Functions for creating
- and manipulating it are declared in pointer-set.h */
-struct pointer_set_t;
-
-/* The type of a callback function for walking over tree structure. */
-
-typedef tree (*walk_tree_fn) (tree *, int *, void *);
-
-/* The type of a callback function that represents a custom walk_tree. */
-
-typedef tree (*walk_tree_lh) (tree *, int *, tree (*) (tree *, int *, void *),
- void *, struct pointer_set_t*);
-
extern tree walk_tree_1 (tree*, walk_tree_fn, void*, struct pointer_set_t*,
walk_tree_lh);
extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*,
@@ -6233,106 +4710,33 @@ extern tree walk_tree_without_duplicates_1 (tree*, walk_tree_fn, void*,
extern void set_decl_rtl (tree, rtx);
extern void set_decl_incoming_rtl (tree, rtx, bool);
-
-/* Enum and arrays used for tree allocation stats.
- Keep in sync with tree.c:tree_node_kind_names. */
-typedef enum
-{
- d_kind,
- t_kind,
- b_kind,
- s_kind,
- r_kind,
- e_kind,
- c_kind,
- id_kind,
- vec_kind,
- binfo_kind,
- ssa_name_kind,
- constr_kind,
- x_kind,
- lang_decl,
- lang_type,
- omp_clause_kind,
- all_kinds
-} tree_node_kind;
-
-extern int tree_node_counts[];
-extern int tree_node_sizes[];
-
-/* True if we are in gimple form and the actions of the folders need to
- be restricted. False if we are not in gimple form and folding is not
- restricted to creating gimple expressions. */
-extern bool in_gimple_form;
/* In gimple.c. */
extern tree get_base_address (tree t);
extern void mark_addressable (tree);
/* In tree.c. */
-
-struct GTY(()) tree_map_base {
- tree from;
-};
-
extern int tree_map_base_eq (const void *, const void *);
extern unsigned int tree_map_base_hash (const void *);
extern int tree_map_base_marked_p (const void *);
extern bool list_equal_p (const_tree, const_tree);
-/* Map from a tree to another tree. */
-
-struct GTY(()) tree_map {
- struct tree_map_base base;
- unsigned int hash;
- tree to;
-};
-
#define tree_map_eq tree_map_base_eq
extern unsigned int tree_map_hash (const void *);
#define tree_map_marked_p tree_map_base_marked_p
-/* Map from a decl tree to another tree. */
-
-struct GTY(()) tree_decl_map {
- struct tree_map_base base;
- tree to;
-};
-
#define tree_decl_map_eq tree_map_base_eq
extern unsigned int tree_decl_map_hash (const void *);
#define tree_decl_map_marked_p tree_map_base_marked_p
-/* Map from a tree to an int. */
-
-struct GTY(()) tree_int_map {
- struct tree_map_base base;
- unsigned int to;
-};
-
#define tree_int_map_eq tree_map_base_eq
#define tree_int_map_hash tree_map_base_hash
#define tree_int_map_marked_p tree_map_base_marked_p
-/* Map from a tree to initialization/finalization priorities. */
-
-struct GTY(()) tree_priority_map {
- struct tree_map_base base;
- priority_type init;
- priority_type fini;
-};
-
#define tree_priority_map_eq tree_map_base_eq
#define tree_priority_map_hash tree_map_base_hash
#define tree_priority_map_marked_p tree_map_base_marked_p
-/* Map from a decl tree to a tree vector. */
-
-struct GTY(()) tree_vec_map {
- struct tree_map_base base;
- vec<tree, va_gc> *to;
-};
-
#define tree_vec_map_eq tree_map_base_eq
#define tree_vec_map_hash tree_decl_map_hash
#define tree_vec_map_marked_p tree_map_base_marked_p
@@ -6385,23 +4789,6 @@ is_tm_safe_or_pure (const_tree x)
void init_inline_once (void);
-/* Abstract iterators for CALL_EXPRs. These static inline definitions
- have to go towards the end of tree.h so that union tree_node is fully
- defined by this point. */
-
-/* Structure containing iterator state. */
-typedef struct call_expr_arg_iterator_d {
- tree t; /* the call_expr */
- int n; /* argument count */
- int i; /* next argument index */
-} call_expr_arg_iterator;
-
-typedef struct const_call_expr_arg_iterator_d {
- const_tree t; /* the call_expr */
- int n; /* argument count */
- int i; /* next argument index */
-} const_call_expr_arg_iterator;
-
/* Initialize the abstract argument list iterator object ITER with the
arguments from CALL_EXPR node EXP. */
static inline void
@@ -6496,19 +4883,8 @@ is_lang_specific (tree t)
/* In gimple-low.c. */
extern bool block_may_fallthru (const_tree);
-
-/* Functional interface to the builtin functions. */
-
-/* The builtin_info structure holds the FUNCTION_DECL of the standard builtin
- function, and a flag that says if the function is available implicitly, or
- whether the user has to code explicit calls to __builtin_<xxx>. */
-
-typedef struct GTY(()) builtin_info_type_d {
- tree decl[(int)END_BUILTINS];
- bool implicit_p[(int)END_BUILTINS];
-} builtin_info_type;
-
-extern GTY(()) builtin_info_type builtin_info;
+/* In vtable-verify.c. */
+extern void save_vtable_map_decl (tree);
/* Valid builtin number. */
#define BUILTIN_VALID_P(FNCODE) \
@@ -6586,7 +4962,6 @@ builtin_decl_implicit_p (enum built_in_function fncode)
&& builtin_info.implicit_p[uns_fncode]);
}
-
/* For anonymous aggregate types, we need some sort of name to
hold on to. In practice, this should not appear, but it should
not be harmful if it does. */
diff --git a/gcc/tsan.c b/gcc/tsan.c
index d218eed5a1b..fb91129eb67 100644
--- a/gcc/tsan.c
+++ b/gcc/tsan.c
@@ -713,7 +713,7 @@ tsan_pass (void)
static bool
tsan_gate (void)
{
- return flag_tsan != 0;
+ return (flag_sanitize & SANITIZE_THREAD) != 0;
}
/* Inserts __tsan_init () into the list of CTORs. */
@@ -733,48 +733,85 @@ tsan_finish_file (void)
/* The pass descriptor. */
-struct gimple_opt_pass pass_tsan =
+namespace {
+
+const pass_data pass_data_tsan =
{
- {
- GIMPLE_PASS,
- "tsan", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- tsan_gate, /* gate */
- tsan_pass, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_all | TODO_update_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "tsan", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_all | TODO_update_ssa ), /* todo_flags_finish */
};
+class pass_tsan : public gimple_opt_pass
+{
+public:
+ pass_tsan(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tsan, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ opt_pass * clone () { return new pass_tsan (ctxt_); }
+ bool gate () { return tsan_gate (); }
+ unsigned int execute () { return tsan_pass (); }
+
+}; // class pass_tsan
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tsan (gcc::context *ctxt)
+{
+ return new pass_tsan (ctxt);
+}
+
static bool
tsan_gate_O0 (void)
{
- return flag_tsan != 0 && !optimize;
+ return (flag_sanitize & SANITIZE_THREAD) != 0 && !optimize;
}
-struct gimple_opt_pass pass_tsan_O0 =
+namespace {
+
+const pass_data pass_data_tsan_O0 =
{
- {
- GIMPLE_PASS,
- "tsan0", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- tsan_gate_O0, /* gate */
- tsan_pass, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- PROP_ssa | PROP_cfg, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_all | TODO_update_ssa /* todo_flags_finish */
- }
+ GIMPLE_PASS, /* type */
+ "tsan0", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_NONE, /* tv_id */
+ ( PROP_ssa | PROP_cfg ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_all | TODO_update_ssa ), /* todo_flags_finish */
};
+
+class pass_tsan_O0 : public gimple_opt_pass
+{
+public:
+ pass_tsan_O0(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_tsan_O0, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return tsan_gate_O0 (); }
+ unsigned int execute () { return tsan_pass (); }
+
+}; // class pass_tsan_O0
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_tsan_O0 (gcc::context *ctxt)
+{
+ return new pass_tsan_O0 (ctxt);
+}
diff --git a/gcc/ubsan.c b/gcc/ubsan.c
new file mode 100644
index 00000000000..b8d40d52128
--- /dev/null
+++ b/gcc/ubsan.c
@@ -0,0 +1,417 @@
+/* UndefinedBehaviorSanitizer, undefined behavior detector.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Marek Polacek <polacek@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "cgraph.h"
+#include "gimple.h"
+#include "hashtab.h"
+#include "pointer-set.h"
+#include "output.h"
+#include "tm_p.h"
+#include "toplev.h"
+#include "ubsan.h"
+#include "c-family/c-common.h"
+
+/* Map from a tree to a VAR_DECL tree. */
+
+struct GTY(()) tree_type_map {
+ struct tree_map_base type;
+ tree decl;
+};
+
+#define tree_type_map_eq tree_map_base_eq
+#define tree_type_map_hash tree_map_base_hash
+#define tree_type_map_marked_p tree_map_base_marked_p
+
+static GTY ((if_marked ("tree_type_map_marked_p"), param_is (struct tree_type_map)))
+ htab_t decl_tree_for_type;
+
+/* Lookup a VAR_DECL for TYPE, and return it if we find one. */
+
+static tree
+decl_for_type_lookup (tree type)
+{
+ /* If the hash table is not initialized yet, create it now. */
+ if (decl_tree_for_type == NULL)
+ {
+ decl_tree_for_type = htab_create_ggc (10, tree_type_map_hash,
+ tree_type_map_eq, 0);
+ /* That also means we don't have to bother with the lookup. */
+ return NULL_TREE;
+ }
+
+ struct tree_type_map *h, in;
+ in.type.from = type;
+
+ h = (struct tree_type_map *)
+ htab_find_with_hash (decl_tree_for_type, &in, TYPE_UID (type));
+ return h ? h->decl : NULL_TREE;
+}
+
+/* Insert a mapping TYPE->DECL in the VAR_DECL for type hashtable. */
+
+static void
+decl_for_type_insert (tree type, tree decl)
+{
+ struct tree_type_map *h;
+ void **slot;
+
+ h = ggc_alloc_tree_type_map ();
+ h->type.from = type;
+ h->decl = decl;
+ slot = htab_find_slot_with_hash (decl_tree_for_type, h, TYPE_UID (type),
+ INSERT);
+ *(struct tree_type_map **) slot = h;
+}
+
+/* Helper routine, which encodes a value in the pointer_sized_int_node.
+ Arguments with precision <= POINTER_SIZE are passed directly,
+ the rest is passed by reference. T is a value we are to encode. */
+
+tree
+ubsan_encode_value (tree t)
+{
+ tree type = TREE_TYPE (t);
+ switch (TREE_CODE (type))
+ {
+ case INTEGER_TYPE:
+ if (TYPE_PRECISION (type) <= POINTER_SIZE)
+ return fold_build1 (NOP_EXPR, pointer_sized_int_node, t);
+ else
+ return build_fold_addr_expr (t);
+ case REAL_TYPE:
+ {
+ unsigned int bitsize = GET_MODE_BITSIZE (TYPE_MODE (type));
+ if (bitsize <= POINTER_SIZE)
+ {
+ tree itype = build_nonstandard_integer_type (bitsize, true);
+ t = fold_build1 (VIEW_CONVERT_EXPR, itype, t);
+ return fold_convert (pointer_sized_int_node, t);
+ }
+ else
+ {
+ if (!TREE_ADDRESSABLE (t))
+ {
+ /* The reason for this is that we don't want to pessimize
+ code by making vars unnecessarily addressable. */
+ tree var = create_tmp_var (TREE_TYPE (t), NULL);
+ tree tem = build2 (MODIFY_EXPR, void_type_node, var, t);
+ t = build_fold_addr_expr (var);
+ return build2 (COMPOUND_EXPR, TREE_TYPE (t), tem, t);
+ }
+ else
+ return build_fold_addr_expr (t);
+ }
+ }
+ default:
+ gcc_unreachable ();
+ }
+}
+
+/* Build
+ struct __ubsan_type_descriptor
+ {
+ unsigned short __typekind;
+ unsigned short __typeinfo;
+ char __typename[];
+ }
+ type. */
+
+static tree
+ubsan_type_descriptor_type (void)
+{
+ static const char *field_names[3]
+ = { "__typekind", "__typeinfo", "__typename" };
+ tree fields[3], ret;
+ tree itype = build_range_type (sizetype, size_zero_node, NULL_TREE);
+ tree flex_arr_type = build_array_type (char_type_node, itype);
+
+ ret = make_node (RECORD_TYPE);
+ for (int i = 0; i < 3; i++)
+ {
+ fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
+ get_identifier (field_names[i]),
+ (i == 2) ? flex_arr_type
+ : short_unsigned_type_node);
+ DECL_CONTEXT (fields[i]) = ret;
+ if (i)
+ DECL_CHAIN (fields[i - 1]) = fields[i];
+ }
+ TYPE_FIELDS (ret) = fields[0];
+ TYPE_NAME (ret) = get_identifier ("__ubsan_type_descriptor");
+ layout_type (ret);
+ return ret;
+}
+
+/* Build
+ struct __ubsan_source_location
+ {
+ const char *__filename;
+ unsigned int __line;
+ unsigned int __column;
+ }
+ type. */
+
+static tree
+ubsan_source_location_type (void)
+{
+ static const char *field_names[3]
+ = { "__filename", "__line", "__column" };
+ tree fields[3], ret;
+ tree const_char_type = build_qualified_type (char_type_node,
+ TYPE_QUAL_CONST);
+
+ ret = make_node (RECORD_TYPE);
+ for (int i = 0; i < 3; i++)
+ {
+ fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL,
+ get_identifier (field_names[i]),
+ (i == 0) ? build_pointer_type (const_char_type)
+ : unsigned_type_node);
+ DECL_CONTEXT (fields[i]) = ret;
+ if (i)
+ DECL_CHAIN (fields[i - 1]) = fields[i];
+ }
+ TYPE_FIELDS (ret) = fields[0];
+ TYPE_NAME (ret) = get_identifier ("__ubsan_source_location");
+ layout_type (ret);
+ return ret;
+}
+
+/* Helper routine that returns a CONSTRUCTOR of __ubsan_source_location
+ type with its fields filled from a location_t LOC. */
+
+static tree
+ubsan_source_location (location_t loc)
+{
+ expanded_location xloc;
+ tree type = ubsan_source_location_type ();
+
+ xloc = expand_location (loc);
+
+ /* Fill in the values from LOC. */
+ size_t len = strlen (xloc.file);
+ tree str = build_string (len + 1, xloc.file);
+ TREE_TYPE (str) = build_array_type (char_type_node,
+ build_index_type (size_int (len)));
+ TREE_READONLY (str) = 1;
+ TREE_STATIC (str) = 1;
+ str = build_fold_addr_expr_loc (loc, str);
+ tree ctor = build_constructor_va (type, 3, NULL_TREE, str, NULL_TREE,
+ build_int_cst (unsigned_type_node,
+ xloc.line), NULL_TREE,
+ build_int_cst (unsigned_type_node,
+ xloc.column));
+ TREE_CONSTANT (ctor) = 1;
+ TREE_STATIC (ctor) = 1;
+
+ return ctor;
+}
+
+/* This routine returns a magic number for TYPE. */
+
+static unsigned short
+get_ubsan_type_info_for_type (tree type)
+{
+ int prec = exact_log2 (TYPE_PRECISION (type));
+ if (prec == -1)
+ error ("unexpected size of type %qT", type);
+
+ return (prec << 1) | !TYPE_UNSIGNED (type);
+}
+
+/* Helper routine that returns ADDR_EXPR of a VAR_DECL of a type
+ descriptor. It first looks into the pointer map; if not found,
+ create the VAR_DECL, put it into the pointer map and return the
+ ADDR_EXPR of it. TYPE describes a particular type. */
+
+tree
+ubsan_type_descriptor (tree type)
+{
+ /* See through any typedefs. */
+ type = TYPE_MAIN_VARIANT (type);
+
+ tree decl = decl_for_type_lookup (type);
+ if (decl != NULL_TREE)
+ return decl;
+
+ tree dtype = ubsan_type_descriptor_type ();
+ const char *tname;
+ unsigned short tkind, tinfo;
+
+ /* At least for INTEGER_TYPE/REAL_TYPE/COMPLEX_TYPE, this should work.
+ ??? For e.g. type_unsigned_for (type), the TYPE_NAME would be NULL. */
+ if (TYPE_NAME (type) != NULL)
+ tname = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
+ else
+ tname = "<unknown>";
+ if (TREE_CODE (type) == INTEGER_TYPE)
+ {
+ /* For INTEGER_TYPE, this is 0x0000. */
+ tkind = 0x000;
+ tinfo = get_ubsan_type_info_for_type (type);
+ }
+ else if (TREE_CODE (type) == REAL_TYPE)
+ /* We don't have float support yet. */
+ gcc_unreachable ();
+ else
+ gcc_unreachable ();
+
+ /* Create a new VAR_DECL of type descriptor. */
+ char tmp_name[32];
+ static unsigned int type_var_id_num;
+ ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_type", type_var_id_num++);
+ decl = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
+ dtype);
+ TREE_STATIC (decl) = 1;
+ TREE_PUBLIC (decl) = 0;
+ DECL_ARTIFICIAL (decl) = 1;
+ DECL_IGNORED_P (decl) = 1;
+ DECL_EXTERNAL (decl) = 0;
+
+ size_t len = strlen (tname);
+ tree str = build_string (len + 1, tname);
+ TREE_TYPE (str) = build_array_type (char_type_node,
+ build_index_type (size_int (len)));
+ TREE_READONLY (str) = 1;
+ TREE_STATIC (str) = 1;
+ tree ctor = build_constructor_va (dtype, 3, NULL_TREE,
+ build_int_cst (short_unsigned_type_node,
+ tkind), NULL_TREE,
+ build_int_cst (short_unsigned_type_node,
+ tinfo), NULL_TREE, str);
+ TREE_CONSTANT (ctor) = 1;
+ TREE_STATIC (ctor) = 1;
+ DECL_INITIAL (decl) = ctor;
+ rest_of_decl_compilation (decl, 1, 0);
+
+ /* Save the address of the VAR_DECL into the pointer map. */
+ decl = build_fold_addr_expr (decl);
+ decl_for_type_insert (type, decl);
+
+ return decl;
+}
+
+/* Create a structure for the ubsan library. NAME is a name of the new
+ structure. The arguments in ... are of __ubsan_type_descriptor type
+ and there are at most two of them. */
+
+tree
+ubsan_create_data (const char *name, location_t loc, ...)
+{
+ va_list args;
+ tree ret, t;
+ tree fields[3];
+ vec<tree, va_gc> *saved_args = NULL;
+ size_t i = 0;
+
+ /* Firstly, create a pointer to type descriptor type. */
+ tree td_type = ubsan_type_descriptor_type ();
+ TYPE_READONLY (td_type) = 1;
+ td_type = build_pointer_type (td_type);
+
+ /* Create the structure type. */
+ ret = make_node (RECORD_TYPE);
+ if (loc != UNKNOWN_LOCATION)
+ {
+ fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
+ ubsan_source_location_type ());
+ DECL_CONTEXT (fields[i]) = ret;
+ i++;
+ }
+
+ va_start (args, loc);
+ for (t = va_arg (args, tree); t != NULL_TREE;
+ i++, t = va_arg (args, tree))
+ {
+ gcc_checking_assert (i < 3);
+ /* Save the tree argument for later use. */
+ vec_safe_push (saved_args, t);
+ fields[i] = build_decl (UNKNOWN_LOCATION, FIELD_DECL, NULL_TREE,
+ td_type);
+ DECL_CONTEXT (fields[i]) = ret;
+ if (i)
+ DECL_CHAIN (fields[i - 1]) = fields[i];
+ }
+ TYPE_FIELDS (ret) = fields[0];
+ TYPE_NAME (ret) = get_identifier (name);
+ layout_type (ret);
+ va_end (args);
+
+ /* Now, fill in the type. */
+ char tmp_name[32];
+ static unsigned int ubsan_var_id_num;
+ ASM_GENERATE_INTERNAL_LABEL (tmp_name, "Lubsan_data", ubsan_var_id_num++);
+ tree var = build_decl (UNKNOWN_LOCATION, VAR_DECL, get_identifier (tmp_name),
+ ret);
+ TREE_STATIC (var) = 1;
+ TREE_PUBLIC (var) = 0;
+ DECL_ARTIFICIAL (var) = 1;
+ DECL_IGNORED_P (var) = 1;
+ DECL_EXTERNAL (var) = 0;
+
+ vec<constructor_elt, va_gc> *v;
+ vec_alloc (v, i);
+ tree ctor = build_constructor (ret, v);
+
+ /* If desirable, set the __ubsan_source_location element. */
+ if (loc != UNKNOWN_LOCATION)
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, ubsan_source_location (loc));
+
+ size_t nelts = vec_safe_length (saved_args);
+ for (i = 0; i < nelts; i++)
+ {
+ t = (*saved_args)[i];
+ CONSTRUCTOR_APPEND_ELT (v, NULL_TREE, t);
+ }
+
+ TREE_CONSTANT (ctor) = 1;
+ TREE_STATIC (ctor) = 1;
+ DECL_INITIAL (var) = ctor;
+ rest_of_decl_compilation (var, 1, 0);
+
+ return var;
+}
+
+/* Instrument the __builtin_unreachable call. We just call the libubsan
+ routine instead. */
+
+tree
+ubsan_instrument_unreachable (location_t loc)
+{
+ tree data = ubsan_create_data ("__ubsan_unreachable_data", loc, NULL_TREE);
+ tree t = builtin_decl_explicit (BUILT_IN_UBSAN_HANDLE_BUILTIN_UNREACHABLE);
+ return build_call_expr_loc (loc, t, 1, build_fold_addr_expr_loc (loc, data));
+}
+
+/* Return true if T is a call to a libubsan routine. */
+
+bool
+is_ubsan_builtin_p (tree t)
+{
+ gcc_checking_assert (TREE_CODE (t) == FUNCTION_DECL);
+ return strncmp (IDENTIFIER_POINTER (DECL_NAME (t)),
+ "__builtin___ubsan_", 18) == 0;
+}
+
+#include "gt-ubsan.h"
diff --git a/gcc/ubsan.h b/gcc/ubsan.h
new file mode 100644
index 00000000000..3553a6cfbc4
--- /dev/null
+++ b/gcc/ubsan.h
@@ -0,0 +1,31 @@
+/* UndefinedBehaviorSanitizer, undefined behavior detector.
+ Copyright (C) 2013 Free Software Foundation, Inc.
+ Contributed by Marek Polacek <polacek@redhat.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#ifndef GCC_UBSAN_H
+#define GCC_UBSAN_H
+
+extern tree ubsan_instrument_unreachable (location_t);
+extern tree ubsan_create_data (const char *, location_t, ...);
+extern tree ubsan_type_descriptor (tree);
+extern tree ubsan_encode_value (tree);
+extern bool is_ubsan_builtin_p (tree);
+
+#endif /* GCC_UBSAN_H */
+
diff --git a/gcc/value-prof.c b/gcc/value-prof.c
index 67bc2c8ea8e..498eb907e81 100644
--- a/gcc/value-prof.c
+++ b/gcc/value-prof.c
@@ -585,9 +585,11 @@ check_counter (gimple stmt, const char * name,
: DECL_SOURCE_LOCATION (current_function_decl);
if (flag_profile_correction)
{
- inform (locus, "correcting inconsistent value profile: "
- "%s profiler overall count (%d) does not match BB count "
- "(%d)", name, (int)*all, (int)bb_count);
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
+ "correcting inconsistent value profile: %s "
+ "profiler overall count (%d) does not match BB "
+ "count (%d)", name, (int)*all, (int)bb_count);
*all = bb_count;
if (*count > *all)
*count = *all;
@@ -1173,24 +1175,67 @@ gimple_mod_subtract_transform (gimple_stmt_iterator *si)
return true;
}
-static vec<cgraph_node_ptr> cgraph_node_map
- = vNULL;
+static pointer_map_t *cgraph_node_map;
-/* Initialize map from FUNCDEF_NO to CGRAPH_NODE. */
+/* Initialize map from PROFILE_ID to CGRAPH_NODE.
+ When LOCAL is true, the PROFILE_IDs are computed. when it is false we assume
+ that the PROFILE_IDs was already assigned. */
void
-init_node_map (void)
+init_node_map (bool local)
{
struct cgraph_node *n;
+ cgraph_node_map = pointer_map_create ();
- if (get_last_funcdef_no ())
- cgraph_node_map.safe_grow_cleared (get_last_funcdef_no ());
-
- FOR_EACH_FUNCTION (n)
- {
- if (DECL_STRUCT_FUNCTION (n->symbol.decl))
- cgraph_node_map[DECL_STRUCT_FUNCTION (n->symbol.decl)->funcdef_no] = n;
- }
+ FOR_EACH_DEFINED_FUNCTION (n)
+ if (cgraph_function_with_gimple_body_p (n)
+ && !cgraph_only_called_directly_p (n))
+ {
+ void **val;
+ if (local)
+ {
+ n->profile_id = coverage_compute_profile_id (n);
+ while ((val = pointer_map_contains (cgraph_node_map,
+ (void *)(size_t)n->profile_id))
+ || !n->profile_id)
+ {
+ if (dump_file)
+ fprintf (dump_file, "Local profile-id %i conflict"
+ " with nodes %s/%i %s/%i\n",
+ n->profile_id,
+ cgraph_node_name (n),
+ n->symbol.order,
+ symtab_node_name (*(symtab_node*)val),
+ (*(symtab_node *)val)->symbol.order);
+ n->profile_id = (n->profile_id + 1) & 0x7fffffff;
+ }
+ }
+ else if (!n->profile_id)
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Node %s/%i has no profile-id"
+ " (profile feedback missing?)\n",
+ cgraph_node_name (n),
+ n->symbol.order);
+ continue;
+ }
+ else if ((val = pointer_map_contains (cgraph_node_map,
+ (void *)(size_t)n->profile_id)))
+ {
+ if (dump_file)
+ fprintf (dump_file,
+ "Node %s/%i has IP profile-id %i conflict. "
+ "Giving up.\n",
+ cgraph_node_name (n),
+ n->symbol.order,
+ n->profile_id);
+ *val = NULL;
+ continue;
+ }
+ *pointer_map_insert (cgraph_node_map,
+ (void *)(size_t)n->profile_id) = (void *)n;
+ }
}
/* Delete the CGRAPH_NODE_MAP. */
@@ -1198,27 +1243,20 @@ init_node_map (void)
void
del_node_map (void)
{
- cgraph_node_map.release ();
+ pointer_map_destroy (cgraph_node_map);
}
/* Return cgraph node for function with pid */
-static inline struct cgraph_node*
-find_func_by_funcdef_no (int func_id)
+struct cgraph_node*
+find_func_by_profile_id (int profile_id)
{
- int max_id = get_last_funcdef_no ();
- if (func_id >= max_id || cgraph_node_map[func_id] == NULL)
- {
- if (flag_profile_correction)
- inform (DECL_SOURCE_LOCATION (current_function_decl),
- "Inconsistent profile: indirect call target (%d) does not exist", func_id);
- else
- error ("Inconsistent profile: indirect call target (%d) does not exist", func_id);
-
- return NULL;
- }
-
- return cgraph_node_map[func_id];
+ void **val = pointer_map_contains (cgraph_node_map,
+ (void *)(size_t)profile_id);
+ if (val)
+ return (struct cgraph_node *)*val;
+ else
+ return NULL;
}
/* Perform sanity check on the indirect call target. Due to race conditions,
@@ -1235,8 +1273,10 @@ check_ic_target (gimple call_stmt, struct cgraph_node *target)
return true;
locus = gimple_location (call_stmt);
- inform (locus, "Skipping target %s with mismatching types for icall ",
- cgraph_node_name (target));
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, locus,
+ "Skipping target %s with mismatching types for icall ",
+ cgraph_node_name (target));
return false;
}
@@ -1248,7 +1288,7 @@ check_ic_target (gimple call_stmt, struct cgraph_node *target)
old call
*/
-static gimple
+gimple
gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
int prob, gcov_type count, gcov_type all)
{
@@ -1259,6 +1299,9 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
edge e_cd, e_ci, e_di, e_dj = NULL, e_ij;
gimple_stmt_iterator gsi;
int lp_nr, dflags;
+ edge e_eh, e;
+ edge_iterator ei;
+ gimple_stmt_iterator psi;
cond_bb = gimple_bb (icall_stmt);
gsi = gsi_for_stmt (icall_stmt);
@@ -1359,27 +1402,23 @@ gimple_ic (gimple icall_stmt, struct cgraph_node *direct_call,
/* Build an EH edge for the direct call if necessary. */
lp_nr = lookup_stmt_eh_lp (icall_stmt);
- if (lp_nr != 0
- && stmt_could_throw_p (dcall_stmt))
+ if (lp_nr > 0 && stmt_could_throw_p (dcall_stmt))
{
- edge e_eh, e;
- edge_iterator ei;
- gimple_stmt_iterator psi;
-
add_stmt_to_eh_lp (dcall_stmt, lp_nr);
- FOR_EACH_EDGE (e_eh, ei, icall_bb->succs)
- if (e_eh->flags & EDGE_EH)
- break;
- e = make_edge (dcall_bb, e_eh->dest, EDGE_EH);
- for (psi = gsi_start_phis (e_eh->dest);
- !gsi_end_p (psi); gsi_next (&psi))
- {
- gimple phi = gsi_stmt (psi);
- SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
- PHI_ARG_DEF_FROM_EDGE (phi, e_eh));
- }
}
+ FOR_EACH_EDGE (e_eh, ei, icall_bb->succs)
+ if (e_eh->flags & (EDGE_EH | EDGE_ABNORMAL))
+ {
+ e = make_edge (dcall_bb, e_eh->dest, e_eh->flags);
+ for (psi = gsi_start_phis (e_eh->dest);
+ !gsi_end_p (psi); gsi_next (&psi))
+ {
+ gimple phi = gsi_stmt (psi);
+ SET_USE (PHI_ARG_DEF_PTR_FROM_EDGE (phi, e),
+ PHI_ARG_DEF_FROM_EDGE (phi, e_eh));
+ }
+ }
return dcall_stmt;
}
@@ -1395,8 +1434,6 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
gimple stmt = gsi_stmt (*gsi);
histogram_value histogram;
gcov_type val, count, all, bb_all;
- gcov_type prob;
- gimple modify;
struct cgraph_node *direct_call;
if (gimple_code (stmt) != GIMPLE_CALL)
@@ -1415,10 +1452,6 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
val = histogram->hvalue.counters [0];
count = histogram->hvalue.counters [1];
all = histogram->hvalue.counters [2];
- gimple_remove_histogram_value (cfun, stmt, histogram);
-
- if (4 * count <= 3 * all)
- return false;
bb_all = gimple_bb (stmt)->count;
/* The order of CHECK_COUNTER calls is important -
@@ -1426,21 +1459,44 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
and we want to make count <= all <= bb_all. */
if ( check_counter (stmt, "ic", &all, &bb_all, bb_all)
|| check_counter (stmt, "ic", &count, &all, all))
+ {
+ gimple_remove_histogram_value (cfun, stmt, histogram);
+ return false;
+ }
+
+ if (4 * count <= 3 * all)
return false;
- if (all > 0)
- prob = GCOV_COMPUTE_SCALE (count, all);
- else
- prob = 0;
- direct_call = find_func_by_funcdef_no ((int)val);
+ direct_call = find_func_by_profile_id ((int)val);
if (direct_call == NULL)
- return false;
+ {
+ if (val)
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "Indirect call -> direct call from other module");
+ print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
+ fprintf (dump_file, "=> %i (will resolve only with LTO)\n", (int)val);
+ }
+ }
+ return false;
+ }
if (!check_ic_target (stmt, direct_call))
- return false;
-
- modify = gimple_ic (stmt, direct_call, prob, count, all);
+ {
+ if (dump_file)
+ {
+ fprintf (dump_file, "Indirect call -> direct call ");
+ print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
+ fprintf (dump_file, "=> ");
+ print_generic_expr (dump_file, direct_call->symbol.decl, TDF_SLIM);
+ fprintf (dump_file, " transformation skipped because of type mismatch");
+ print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
+ }
+ gimple_remove_histogram_value (cfun, stmt, histogram);
+ return false;
+ }
if (dump_file)
{
@@ -1448,10 +1504,8 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
print_generic_expr (dump_file, gimple_call_fn (stmt), TDF_SLIM);
fprintf (dump_file, "=> ");
print_generic_expr (dump_file, direct_call->symbol.decl, TDF_SLIM);
- fprintf (dump_file, " transformation on insn ");
+ fprintf (dump_file, " transformation on insn postponned to ipa-profile");
print_gimple_stmt (dump_file, stmt, 0, TDF_SLIM);
- fprintf (dump_file, " to ");
- print_gimple_stmt (dump_file, modify, 0, TDF_SLIM);
fprintf (dump_file, "hist->count "HOST_WIDEST_INT_PRINT_DEC
" hist->all "HOST_WIDEST_INT_PRINT_DEC"\n", count, all);
}
diff --git a/gcc/value-prof.h b/gcc/value-prof.h
index 7030d90e988..57f249d56ef 100644
--- a/gcc/value-prof.h
+++ b/gcc/value-prof.h
@@ -86,6 +86,8 @@ void gimple_move_stmt_histograms (struct function *, gimple, gimple);
void verify_histograms (void);
void free_histograms (void);
void stringop_block_profile (gimple, unsigned int *, HOST_WIDE_INT *);
+gimple gimple_ic (gimple, struct cgraph_node *, int, gcov_type, gcov_type);
+
/* In tree-profile.c. */
extern void gimple_init_edge_profiler (void);
@@ -101,6 +103,8 @@ extern void gimple_gen_average_profiler (histogram_value, unsigned, unsigned);
extern void gimple_gen_ior_profiler (histogram_value, unsigned, unsigned);
extern void stream_out_histogram_value (struct output_block *, histogram_value);
extern void stream_in_histogram_value (struct lto_input_block *, gimple);
+extern struct cgraph_node* find_func_by_profile_id (int func_id);
+
/* In profile.c. */
extern void init_branch_prob (void);
diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c
index 8108413ea72..cf1f08bc252 100644
--- a/gcc/var-tracking.c
+++ b/gcc/var-tracking.c
@@ -5836,7 +5836,24 @@ add_stores (rtx loc, const_rtx expr, void *cuip)
{
rtx xexpr = gen_rtx_SET (VOIDmode, loc, src);
if (same_variable_part_p (src, REG_EXPR (loc), REG_OFFSET (loc)))
- mo.type = MO_COPY;
+ {
+ /* If this is an instruction copying (part of) a parameter
+ passed by invisible reference to its register location,
+ pretend it's a SET so that the initial memory location
+ is discarded, as the parameter register can be reused
+ for other purposes and we do not track locations based
+ on generic registers. */
+ if (MEM_P (src)
+ && REG_EXPR (loc)
+ && TREE_CODE (REG_EXPR (loc)) == PARM_DECL
+ && DECL_MODE (REG_EXPR (loc)) != BLKmode
+ && MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc)))
+ && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0)
+ != arg_pointer_rtx)
+ mo.type = MO_SET;
+ else
+ mo.type = MO_COPY;
+ }
else
mo.type = MO_SET;
mo.u.loc = xexpr;
@@ -9086,7 +9103,7 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set)
else
var_mem_set (set, loc, VAR_INIT_STATUS_UNINITIALIZED, NULL);
- emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN, set->vars);
+ emit_notes_for_changes (insn, EMIT_NOTE_BEFORE_INSN, set->vars);
}
break;
@@ -9533,12 +9550,11 @@ vt_add_function_parameter (tree parm)
if (!vt_get_decl_and_offset (incoming, &decl, &offset))
{
- if (REG_P (incoming) || MEM_P (incoming))
+ if (MEM_P (incoming))
{
/* This means argument is passed by invisible reference. */
offset = 0;
decl = parm;
- incoming = gen_rtx_MEM (GET_MODE (decl_rtl), incoming);
}
else
{
@@ -10218,23 +10234,40 @@ gate_handle_var_tracking (void)
-struct rtl_opt_pass pass_variable_tracking =
+namespace {
+
+const pass_data pass_data_variable_tracking =
{
- {
- RTL_PASS,
- "vartrack", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_var_tracking, /* gate */
- variable_tracking_main, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_VAR_TRACKING, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_verify_rtl_sharing
- | TODO_verify_flow /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "vartrack", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_VAR_TRACKING, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_verify_rtl_sharing | TODO_verify_flow ), /* todo_flags_finish */
};
+
+class pass_variable_tracking : public rtl_opt_pass
+{
+public:
+ pass_variable_tracking(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_variable_tracking, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_var_tracking (); }
+ unsigned int execute () { return variable_tracking_main (); }
+
+}; // class pass_variable_tracking
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_variable_tracking (gcc::context *ctxt)
+{
+ return new pass_variable_tracking (ctxt);
+}
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 8efd98e0020..0504eeb4f39 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -1102,7 +1102,8 @@ get_variable_section (tree decl, bool prefer_noswitch_p)
&& bss_initializer_p (decl))
{
if (!TREE_PUBLIC (decl)
- && !(flag_asan && asan_protect_global (decl)))
+ && !((flag_sanitize & SANITIZE_ADDRESS)
+ && asan_protect_global (decl)))
return lcomm_section;
if (bss_noswitch_section)
return bss_noswitch_section;
@@ -1904,7 +1905,7 @@ assemble_noswitch_variable (tree decl, const char *name, section *sect,
size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
rounded = size;
- if (flag_asan && asan_protect_global (decl))
+ if ((flag_sanitize & SANITIZE_ADDRESS) && asan_protect_global (decl))
size += asan_red_zone_size (size);
/* Don't allocate zero bytes of common,
@@ -2063,7 +2064,7 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
align_variable (decl, dont_output_data);
- if (flag_asan
+ if ((flag_sanitize & SANITIZE_ADDRESS)
&& asan_protect_global (decl))
{
asan_protected = true;
@@ -2107,7 +2108,31 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
assemble_noswitch_variable (decl, name, sect, align);
else
{
- switch_to_section (sect);
+ /* The following bit of code ensures that vtable_map
+ variables are not only in the comdat section, but that
+ each variable has its own unique comdat name. If this
+ code is removed, the variables end up in the same section
+ with a single comdat name.
+
+ FIXME: resolve_unique_section needs to deal better with
+ decls with both DECL_SECTION_NAME and DECL_ONE_ONLY. Once
+ that is fixed, this if-else statement can be replaced with
+ a single call to "switch_to_section (sect)". */
+ if (sect->named.name
+ && (strcmp (sect->named.name, ".vtable_map_vars") == 0))
+ {
+#if defined (OBJECT_FORMAT_ELF)
+ targetm.asm_out.named_section (sect->named.name,
+ sect->named.common.flags
+ | SECTION_LINKONCE,
+ DECL_NAME (decl));
+ in_section = sect;
+#else
+ switch_to_section (sect);
+#endif
+ }
+ else
+ switch_to_section (sect);
if (align > BITS_PER_UNIT)
ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT));
assemble_variable_contents (decl, name, dont_output_data);
@@ -2120,6 +2145,23 @@ assemble_variable (tree decl, int top_level ATTRIBUTE_UNUSED,
}
}
+
+/* Given a function declaration (FN_DECL), this function assembles the
+ function into the .preinit_array section. */
+
+void
+assemble_vtv_preinit_initializer (tree fn_decl)
+{
+ section *sect;
+ unsigned flags = SECTION_WRITE;
+ rtx symbol = XEXP (DECL_RTL (fn_decl), 0);
+
+ flags |= SECTION_NOTYPE;
+ sect = get_section (".preinit_array", flags, fn_decl);
+ switch_to_section (sect);
+ assemble_addr_to_section (symbol, sect);
+}
+
/* Return 1 if type TYPE contains any pointers. */
static int
@@ -3335,7 +3377,8 @@ output_constant_def_contents (rtx symbol)
/* We are no longer deferring this constant. */
TREE_ASM_WRITTEN (decl) = TREE_ASM_WRITTEN (exp) = 1;
- if (flag_asan && TREE_CODE (exp) == STRING_CST
+ if ((flag_sanitize & SANITIZE_ADDRESS)
+ && TREE_CODE (exp) == STRING_CST
&& asan_protect_global (exp))
{
asan_protected = true;
@@ -6046,6 +6089,9 @@ default_section_type_flags (tree decl, const char *name, int reloc)
if (decl && DECL_P (decl) && DECL_ONE_ONLY (decl))
flags |= SECTION_LINKONCE;
+ if (strcmp (name, ".vtable_map_vars") == 0)
+ flags |= SECTION_LINKONCE;
+
if (decl && TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
flags |= SECTION_TLS | SECTION_WRITE;
@@ -6247,7 +6293,8 @@ categorize_decl_for_section (const_tree decl, int reloc)
else if (TREE_CODE (decl) == STRING_CST)
{
if (flag_mudflap
- || (flag_asan && asan_protect_global (CONST_CAST_TREE (decl))))
+ || ((flag_sanitize & SANITIZE_ADDRESS)
+ && asan_protect_global (CONST_CAST_TREE (decl))))
/* or !flag_merge_constants */
return SECCAT_RODATA;
else
@@ -6273,7 +6320,8 @@ categorize_decl_for_section (const_tree decl, int reloc)
else if (reloc & targetm.asm_out.reloc_rw_mask ())
ret = reloc == 1 ? SECCAT_DATA_REL_RO_LOCAL : SECCAT_DATA_REL_RO;
else if (reloc || flag_merge_constants < 2 || flag_mudflap
- || (flag_asan && asan_protect_global (CONST_CAST_TREE (decl))))
+ || ((flag_sanitize & SANITIZE_ADDRESS)
+ && asan_protect_global (CONST_CAST_TREE (decl))))
/* C and C++ don't allow different variables to share the same
location. -fmerge-all-constants allows even that (at the
expense of not conforming). */
@@ -7031,7 +7079,7 @@ place_block_symbol (rtx symbol)
decl = SYMBOL_REF_DECL (symbol);
alignment = DECL_ALIGN (decl);
size = get_constant_size (DECL_INITIAL (decl));
- if (flag_asan
+ if ((flag_sanitize & SANITIZE_ADDRESS)
&& TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
&& asan_protect_global (DECL_INITIAL (decl)))
size += asan_red_zone_size (size);
@@ -7041,7 +7089,8 @@ place_block_symbol (rtx symbol)
decl = SYMBOL_REF_DECL (symbol);
alignment = get_variable_align (decl);
size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
- if (flag_asan && asan_protect_global (decl))
+ if ((flag_sanitize & SANITIZE_ADDRESS)
+ && asan_protect_global (decl))
{
size += asan_red_zone_size (size);
alignment = MAX (alignment,
@@ -7191,7 +7240,7 @@ output_object_block (struct object_block *block)
DECL_ALIGN (decl));
size = get_constant_size (DECL_INITIAL (decl));
offset += size;
- if (flag_asan
+ if ((flag_sanitize & SANITIZE_ADDRESS)
&& TREE_CODE (DECL_INITIAL (decl)) == STRING_CST
&& asan_protect_global (DECL_INITIAL (decl)))
{
@@ -7207,7 +7256,8 @@ output_object_block (struct object_block *block)
assemble_variable_contents (decl, XSTR (symbol, 0), false);
size = tree_low_cst (DECL_SIZE_UNIT (decl), 1);
offset += size;
- if (flag_asan && asan_protect_global (decl))
+ if ((flag_sanitize & SANITIZE_ADDRESS)
+ && asan_protect_global (decl))
{
size = asan_red_zone_size (size);
assemble_zeros (size);
diff --git a/gcc/varpool.c b/gcc/varpool.c
index b426757ec84..2e47d288536 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -36,6 +36,100 @@ along with GCC; see the file COPYING3. If not see
#include "tree-flow.h"
#include "flags.h"
+/* List of hooks triggered on varpool_node events. */
+struct varpool_node_hook_list {
+ varpool_node_hook hook;
+ void *data;
+ struct varpool_node_hook_list *next;
+};
+
+/* List of hooks triggered when a node is removed. */
+struct varpool_node_hook_list *first_varpool_node_removal_hook;
+/* List of hooks triggered when an variable is inserted. */
+struct varpool_node_hook_list *first_varpool_variable_insertion_hook;
+
+/* Register HOOK to be called with DATA on each removed node. */
+struct varpool_node_hook_list *
+varpool_add_node_removal_hook (varpool_node_hook hook, void *data)
+{
+ struct varpool_node_hook_list *entry;
+ struct varpool_node_hook_list **ptr = &first_varpool_node_removal_hook;
+
+ entry = (struct varpool_node_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on removing nodes. */
+void
+varpool_remove_node_removal_hook (struct varpool_node_hook_list *entry)
+{
+ struct varpool_node_hook_list **ptr = &first_varpool_node_removal_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+ free (entry);
+}
+
+/* Call all node removal hooks. */
+static void
+varpool_call_node_removal_hooks (struct varpool_node *node)
+{
+ struct varpool_node_hook_list *entry = first_varpool_node_removal_hook;
+ while (entry)
+ {
+ entry->hook (node, entry->data);
+ entry = entry->next;
+ }
+}
+
+/* Register HOOK to be called with DATA on each inserted node. */
+struct varpool_node_hook_list *
+varpool_add_variable_insertion_hook (varpool_node_hook hook, void *data)
+{
+ struct varpool_node_hook_list *entry;
+ struct varpool_node_hook_list **ptr = &first_varpool_variable_insertion_hook;
+
+ entry = (struct varpool_node_hook_list *) xmalloc (sizeof (*entry));
+ entry->hook = hook;
+ entry->data = data;
+ entry->next = NULL;
+ while (*ptr)
+ ptr = &(*ptr)->next;
+ *ptr = entry;
+ return entry;
+}
+
+/* Remove ENTRY from the list of hooks called on inserted nodes. */
+void
+varpool_remove_variable_insertion_hook (struct varpool_node_hook_list *entry)
+{
+ struct varpool_node_hook_list **ptr = &first_varpool_variable_insertion_hook;
+
+ while (*ptr != entry)
+ ptr = &(*ptr)->next;
+ *ptr = entry->next;
+ free (entry);
+}
+
+/* Call all node insertion hooks. */
+void
+varpool_call_variable_insertion_hooks (struct varpool_node *node)
+{
+ struct varpool_node_hook_list *entry = first_varpool_variable_insertion_hook;
+ while (entry)
+ {
+ entry->hook (node, entry->data);
+ entry = entry->next;
+ }
+}
+
/* Allocate new callgraph node and insert it into basic data structures. */
struct varpool_node *
@@ -65,8 +159,9 @@ varpool_node_for_decl (tree decl)
void
varpool_remove_node (struct varpool_node *node)
{
- symtab_unregister_node ((symtab_node)node);
tree init;
+ varpool_call_node_removal_hooks (node);
+ symtab_unregister_node ((symtab_node)node);
/* Because we remove references from external functions before final compilation,
we may end up removing useful constructors.
@@ -246,6 +341,7 @@ varpool_add_new_variable (tree decl)
struct varpool_node *node;
varpool_finalize_decl (decl);
node = varpool_node_for_decl (decl);
+ varpool_call_variable_insertion_hooks (node);
if (varpool_externally_visible_p (node))
node->symbol.externally_visible = true;
}
@@ -260,10 +356,22 @@ cgraph_variable_initializer_availability (struct varpool_node *node)
return AVAIL_NOT_AVAILABLE;
if (!TREE_PUBLIC (node->symbol.decl))
return AVAIL_AVAILABLE;
+ if (DECL_IN_CONSTANT_POOL (node->symbol.decl)
+ || DECL_VIRTUAL_P (node->symbol.decl))
+ return AVAIL_AVAILABLE;
+ if (node->symbol.alias && node->symbol.weakref)
+ {
+ enum availability avail;
+
+ cgraph_variable_initializer_availability
+ (varpool_variable_node (node, &avail));
+ return avail;
+ }
/* If the variable can be overwritten, return OVERWRITABLE. Takes
care of at least one notable extension - the COMDAT variables
used to share template instantiations in C++. */
- if (!decl_replaceable_p (node->symbol.decl))
+ if (decl_replaceable_p (node->symbol.decl)
+ || DECL_EXTERNAL (node->symbol.decl))
return AVAIL_OVERWRITABLE;
return AVAIL_AVAILABLE;
}
diff --git a/gcc/vtable-verify.c b/gcc/vtable-verify.c
new file mode 100644
index 00000000000..b6c5bc3bce4
--- /dev/null
+++ b/gcc/vtable-verify.c
@@ -0,0 +1,793 @@
+/* Copyright (C) 2013
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Virtual Table Pointer Security Pass - Detect corruption of vtable pointers
+ before using them for virtual method dispatches. */
+
+/* This file is part of the vtable security feature implementation.
+ The vtable security feature is designed to detect when a virtual
+ call is about to be made through an invalid vtable pointer
+ (possibly due to data corruption or malicious attacks). The
+ compiler finds every virtual call, and inserts a verification call
+ before the virtual call. The verification call takes the actual
+ vtable pointer value in the object through which the virtual call
+ is being made, and compares the vtable pointer against a set of all
+ valid vtable pointers that the object could contain (this set is
+ based on the declared type of the object). If the pointer is in
+ the valid set, execution is allowed to continue; otherwise the
+ program is halted.
+
+ There are several pieces needed in order to make this work: 1. For
+ every virtual class in the program (i.e. a class that contains
+ virtual methods), we need to build the set of all possible valid
+ vtables that an object of that class could point to. This includes
+ vtables for any class(es) that inherit from the class under
+ consideration. 2. For every such data set we build up, we need a
+ way to find and reference the data set. This is complicated by the
+ fact that the real vtable addresses are not known until runtime,
+ when the program is loaded into memory, but we need to reference the
+ sets at compile time when we are inserting verification calls into
+ the program. 3. We need to find every virtual call in the program,
+ and insert the verification call (with the appropriate arguments)
+ before the virtual call. 4. We need some runtime library pieces:
+ the code to build up the data sets at runtime; the code to actually
+ perform the verification using the data sets; and some code to set
+ protections on the data sets, so they themselves do not become
+ hacker targets.
+
+ To find and reference the set of valid vtable pointers for any given
+ virtual class, we create a special global variable for each virtual
+ class. We refer to this as the "vtable map variable" for that
+ class. The vtable map variable has the type "void *", and is
+ initialized by the compiler to NULL. At runtime when the set of
+ valid vtable pointers for a virtual class, e.g. class Foo, is built,
+ the vtable map variable for class Foo is made to point to the set.
+ During compile time, when the compiler is inserting verification
+ calls into the program, it passes the vtable map variable for the
+ appropriate class to the verification call, so that at runtime the
+ verification call can find the appropriate data set.
+
+ The actual set of valid vtable pointers for a virtual class,
+ e.g. class Foo, cannot be built until runtime, when the vtables get
+ loaded into memory and their addresses are known. But the knowledge
+ about which vtables belong in which class' hierarchy is only known
+ at compile time. Therefore at compile time we collect class
+ hierarchy and vtable information about every virtual class, and we
+ generate calls to build up the data sets at runtime. To build the
+ data sets, we call one of the functions we add to the runtime
+ library, __VLTRegisterPair. __VLTRegisterPair takes two arguments,
+ a vtable map variable and the address of a vtable. If the vtable
+ map variable is currently NULL, it creates a new data set (hash
+ table), makes the vtable map variable point to the new data set, and
+ inserts the vtable address into the data set. If the vtable map
+ variable is not NULL, it just inserts the vtable address into the
+ data set. In order to make sure that our data sets are built before
+ any verification calls happen, we create a special constructor
+ initialization function for each compilation unit, give it a very
+ high initialization priority, and insert all of our calls to
+ __VLTRegisterPair into our special constructor initialization
+ function.
+
+ The vtable verification feature is controlled by the flag
+ '-fvtable-verify='. There are three flavors of this:
+ '-fvtable-verify=std', '-fvtable-verify=preinit', and
+ '-fvtable-verify=none'. If the option '-fvtable-verfy=preinit' is
+ used, then our constructor initialization function gets put into the
+ preinit array. This is necessary if there are data sets that need
+ to be built very early in execution. If the constructor
+ initialization function gets put into the preinit array, the we also
+ add calls to __VLTChangePermission at the beginning and end of the
+ function. The call at the beginning sets the permissions on the
+ data sets and vtable map variables to read/write, and the one at the
+ end makes them read-only. If the '-fvtable-verify=std' option is
+ used, the constructor initialization functions are executed at their
+ normal time, and the __VLTChangePermission calls are handled
+ differently (see the comments in libstdc++-v3/libsupc++/vtv_rts.cc).
+ The option '-fvtable-verify=none' turns off vtable verification.
+
+ This file contains code for the tree pass that goes through all the
+ statements in each basic block, looking for virtual calls, and
+ inserting a call to __VLTVerifyVtablePointer (with appropriate
+ arguments) before each one. It also contains the hash table
+ functions for the data structures used for collecting the class
+ hierarchy data and building/maintaining the vtable map variable data
+ are defined in gcc/vtable-verify.h. These data structures are
+ shared with the code in the C++ front end that collects the class
+ hierarchy & vtable information and generates the vtable map
+ variables (see cp/vtable-class-hierarchy.c). This tree pass should
+ run just before the gimple is converted to RTL.
+
+ Some implementation details for this pass:
+
+ To find all of the virtual calls, we iterate through all the
+ gimple statements in each basic block, looking for any call
+ statement with the code "OBJ_TYPE_REF". Once we have found the
+ virtual call, we need to find the vtable pointer through which the
+ call is being made, and the type of the object containing the
+ pointer (to find the appropriate vtable map variable). We then use
+ these to build a call to __VLTVerifyVtablePointer, passing the
+ vtable map variable, and the vtable pointer. We insert the
+ verification call just after the gimple statement that gets the
+ vtable pointer out of the object, and we update the next
+ statement to depend on the result returned from
+ __VLTVerifyVtablePointer (the vtable pointer value), to ensure
+ subsequent compiler phases don't remove or reorder the call (it's no
+ good to have the verification occur after the virtual call, for
+ example). To find the vtable pointer being used (and the type of
+ the object) we search backwards through the def_stmts chain from the
+ virtual call (see verify_bb_vtables for more details). */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "basic-block.h"
+#include "tree-flow.h"
+#include "tree-pass.h"
+#include "cfgloop.h"
+
+#include "vtable-verify.h"
+
+unsigned num_vtable_map_nodes = 0;
+int total_num_virtual_calls = 0;
+int total_num_verified_vcalls = 0;
+
+extern GTY(()) tree verify_vtbl_ptr_fndecl;
+tree verify_vtbl_ptr_fndecl = NULL_TREE;
+
+/* Keep track of whether or not any virtual call were verified. */
+static bool any_verification_calls_generated = false;
+
+unsigned int vtable_verify_main (void);
+
+
+/* The following few functions are for the vtbl pointer hash table
+ in the 'registered' field of the struct vtable_map_node. The hash
+ table keeps track of which vtable pointers have been used in
+ calls to __VLTRegisterPair with that particular vtable map variable. */
+
+/* This function checks to see if a particular VTABLE_DECL and OFFSET are
+ already in the 'registered' hash table for NODE. */
+
+bool
+vtbl_map_node_registration_find (struct vtbl_map_node *node,
+ tree vtable_decl,
+ unsigned offset)
+{
+ struct vtable_registration key;
+ struct vtable_registration **slot;
+
+ gcc_assert (node && node->registered.is_created());
+
+ key.vtable_decl = vtable_decl;
+ slot = (struct vtable_registration **) node->registered.find_slot (&key,
+ NO_INSERT);
+
+ if (slot && (*slot))
+ {
+ unsigned i;
+ for (i = 0; i < ((*slot)->offsets).length(); ++i)
+ if ((*slot)->offsets[i] == offset)
+ return true;
+ }
+
+ return false;
+}
+
+/* This function inserts VTABLE_DECL and OFFSET into the 'registered'
+ hash table for NODE. It returns a boolean indicating whether or not
+ it actually inserted anything. */
+
+bool
+vtbl_map_node_registration_insert (struct vtbl_map_node *node,
+ tree vtable_decl,
+ unsigned offset)
+{
+ struct vtable_registration key;
+ struct vtable_registration **slot;
+ bool inserted_something = false;
+
+ if (!node || !node->registered.is_created())
+ return false;
+
+ key.vtable_decl = vtable_decl;
+ slot = (struct vtable_registration **) node->registered.find_slot (&key,
+ INSERT);
+
+ if (! *slot)
+ {
+ struct vtable_registration *node;
+ node = XNEW (struct vtable_registration);
+ node->vtable_decl = vtable_decl;
+
+ (node->offsets).create (10);
+ (node->offsets).safe_push (offset);
+ *slot = node;
+ inserted_something = true;
+ }
+ else
+ {
+ /* We found the vtable_decl slot; we need to see if it already
+ contains the offset. If not, we need to add the offset. */
+ unsigned i;
+ bool found = false;
+ for (i = 0; i < ((*slot)->offsets).length() && !found; ++i)
+ if ((*slot)->offsets[i] == offset)
+ found = true;
+
+ if (!found)
+ {
+ ((*slot)->offsets).safe_push (offset);
+ inserted_something = true;
+ }
+ }
+ return inserted_something;
+}
+
+/* Hashtable functions for vtable_registration hashtables. */
+
+inline hashval_t
+registration_hasher::hash (const value_type *p)
+{
+ const struct vtable_registration *n = (const struct vtable_registration *) p;
+ return (hashval_t) (DECL_UID (n->vtable_decl));
+}
+
+inline bool
+registration_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+ const struct vtable_registration *n1 =
+ (const struct vtable_registration *) p1;
+ const struct vtable_registration *n2 =
+ (const struct vtable_registration *) p2;
+ return (DECL_UID (n1->vtable_decl) == DECL_UID (n2->vtable_decl));
+}
+
+/* End of hashtable functions for "registered" hashtables. */
+
+
+
+/* Hashtable definition and functions for vtbl_map_hash. */
+
+struct vtbl_map_hasher : typed_noop_remove <struct vtbl_map_node>
+{
+ typedef struct vtbl_map_node value_type;
+ typedef struct vtbl_map_node compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+/* Returns a hash code for P. */
+
+inline hashval_t
+vtbl_map_hasher::hash (const value_type *p)
+{
+ const struct vtbl_map_node n = *((const struct vtbl_map_node *) p);
+ return (hashval_t) IDENTIFIER_HASH_VALUE (n.class_name);
+}
+
+/* Returns nonzero if P1 and P2 are equal. */
+
+inline bool
+vtbl_map_hasher::equal (const value_type *p1, const compare_type *p2)
+{
+ const struct vtbl_map_node n1 = *((const struct vtbl_map_node *) p1);
+ const struct vtbl_map_node n2 = *((const struct vtbl_map_node *) p2);
+ return (IDENTIFIER_HASH_VALUE (n1.class_name) ==
+ IDENTIFIER_HASH_VALUE (n2.class_name));
+}
+
+/* Here are the two structures into which we insert vtable map nodes.
+ We use two data structures because of the vastly different ways we need
+ to find the nodes for various tasks (see comments in vtable-verify.h
+ for more details. */
+
+typedef hash_table <vtbl_map_hasher> vtbl_map_table_type;
+typedef vtbl_map_table_type::iterator vtbl_map_iterator_type;
+
+/* Vtable map variable nodes stored in a hash table. */
+static vtbl_map_table_type vtbl_map_hash;
+
+/* Vtable map variable nodes stored in a vector. */
+vec<struct vtbl_map_node *> vtbl_map_nodes_vec;
+
+/* Return vtbl_map node for CLASS_NAME without creating a new one. */
+
+struct vtbl_map_node *
+vtbl_map_get_node (tree class_type)
+{
+ struct vtbl_map_node key;
+ struct vtbl_map_node **slot;
+
+ tree class_type_decl;
+ tree class_name;
+ unsigned int type_quals;
+
+ if (!vtbl_map_hash.is_created())
+ return NULL;
+
+ gcc_assert (TREE_CODE (class_type) == RECORD_TYPE);
+
+
+ /* Find the TYPE_DECL for the class. */
+ class_type_decl = TYPE_NAME (class_type);
+
+ /* Verify that there aren't any qualifiers on the type. */
+ type_quals = TYPE_QUALS (TREE_TYPE (class_type_decl));
+ gcc_assert (type_quals == TYPE_UNQUALIFIED);
+
+ /* Get the mangled name for the unqualified type. */
+ gcc_assert (HAS_DECL_ASSEMBLER_NAME_P (class_type_decl));
+ class_name = DECL_ASSEMBLER_NAME (class_type_decl);
+
+ key.class_name = class_name;
+ slot = (struct vtbl_map_node **) vtbl_map_hash.find_slot (&key,
+ NO_INSERT);
+ if (!slot)
+ return NULL;
+ return *slot;
+}
+
+/* Return vtbl_map node assigned to BASE_CLASS_TYPE. Create new one
+ when needed. */
+
+struct vtbl_map_node *
+find_or_create_vtbl_map_node (tree base_class_type)
+{
+ struct vtbl_map_node key;
+ struct vtbl_map_node *node;
+ struct vtbl_map_node **slot;
+ tree class_type_decl;
+ unsigned int type_quals;
+
+ if (!vtbl_map_hash.is_created())
+ vtbl_map_hash.create (10);
+
+ /* Find the TYPE_DECL for the class. */
+ class_type_decl = TYPE_NAME (base_class_type);
+
+ /* Verify that there aren't any type qualifiers on type. */
+ type_quals = TYPE_QUALS (TREE_TYPE (class_type_decl));
+ gcc_assert (type_quals == TYPE_UNQUALIFIED);
+
+ gcc_assert (HAS_DECL_ASSEMBLER_NAME_P (class_type_decl));
+ key.class_name = DECL_ASSEMBLER_NAME (class_type_decl);
+ slot = (struct vtbl_map_node **) vtbl_map_hash.find_slot (&key,
+ INSERT);
+
+ if (*slot)
+ return *slot;
+
+ node = XNEW (struct vtbl_map_node);
+ node->vtbl_map_decl = NULL_TREE;
+ node->class_name = key.class_name;
+ node->uid = num_vtable_map_nodes++;
+
+ node->class_info = XNEW (struct vtv_graph_node);
+ node->class_info->class_type = base_class_type;
+ node->class_info->class_uid = node->uid;
+ node->class_info->num_processed_children = 0;
+
+ (node->class_info->parents).create (4);
+ (node->class_info->children).create (4);
+
+ node->registered.create (16);
+
+ node->is_used = false;
+
+ vtbl_map_nodes_vec.safe_push (node);
+ gcc_assert (vtbl_map_nodes_vec[node->uid] == node);
+
+ *slot = node;
+ return node;
+}
+
+/* End of hashtable functions for vtable_map variables hash table. */
+
+/* Given a gimple STMT, this function checks to see if the statement
+ is an assignment, the rhs of which is getting the vtable pointer
+ value out of an object. (i.e. it's the value we need to verify
+ because its the vtable pointer that will be used for a virtual
+ call). */
+
+static bool
+is_vtable_assignment_stmt (gimple stmt)
+{
+
+ if (gimple_code (stmt) != GIMPLE_ASSIGN)
+ return false;
+ else
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ tree rhs = gimple_assign_rhs1 (stmt);
+
+ if (TREE_CODE (lhs) != SSA_NAME)
+ return false;
+
+ if (TREE_CODE (rhs) != COMPONENT_REF)
+ return false;
+
+ if (! (TREE_OPERAND (rhs, 1))
+ || (TREE_CODE (TREE_OPERAND (rhs, 1)) != FIELD_DECL))
+ return false;
+
+ if (! DECL_VIRTUAL_P (TREE_OPERAND (rhs, 1)))
+ return false;
+ }
+
+ return true;
+}
+
+/* This function attempts to recover the declared class of an object
+ that is used in making a virtual call. We try to get the type from
+ the type cast in the gimple assignment statement that extracts the
+ vtable pointer from the object (DEF_STMT). The gimple statement
+ usually looks something like this:
+
+ D.2201_4 = MEM[(struct Event *)this_1(D)]._vptr.Event */
+
+static tree
+extract_object_class_type (tree rhs)
+{
+ tree result = NULL_TREE;
+
+ /* Try to find and extract the type cast from that stmt. */
+ if (TREE_CODE (rhs) == COMPONENT_REF)
+ {
+ tree op0 = TREE_OPERAND (rhs, 0);
+ tree op1 = TREE_OPERAND (rhs, 1);
+
+ if (TREE_CODE (op1) == FIELD_DECL
+ && DECL_VIRTUAL_P (op1))
+ {
+ if (TREE_CODE (op0) == COMPONENT_REF
+ && TREE_CODE (TREE_OPERAND (op0, 0)) == MEM_REF
+ && TREE_CODE (TREE_TYPE (TREE_OPERAND (op0, 0)))== RECORD_TYPE)
+ result = TREE_TYPE (TREE_OPERAND (op0, 0));
+ else
+ result = TREE_TYPE (op0);
+ }
+ else if (TREE_CODE (op0) == COMPONENT_REF)
+ {
+ result = extract_object_class_type (op0);
+ if (result == NULL_TREE
+ && TREE_CODE (op1) == COMPONENT_REF)
+ result = extract_object_class_type (op1);
+ }
+ }
+
+ return result;
+}
+
+/* This function traces forward through the def-use chain of an SSA
+ variable to see if it ever gets used in a virtual function call. It
+ returns a boolean indicating whether or not it found a virtual call in
+ the use chain. */
+
+static bool
+var_is_used_for_virtual_call_p (tree lhs, int *mem_ref_depth)
+{
+ imm_use_iterator imm_iter;
+ bool found_vcall = false;
+ use_operand_p use_p;
+
+ if (TREE_CODE (lhs) != SSA_NAME)
+ return false;
+
+ if (*mem_ref_depth > 2)
+ return false;
+
+ /* Iterate through the immediate uses of the current variable. If
+ it's a virtual function call, we're done. Otherwise, if there's
+ an LHS for the use stmt, add the ssa var to the work list
+ (assuming it's not already in the list and is not a variable
+ we've already examined. */
+
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, lhs)
+ {
+ gimple stmt2 = USE_STMT (use_p);
+
+ if (gimple_code (stmt2) == GIMPLE_CALL)
+ {
+ tree fncall = gimple_call_fn (stmt2);
+ if (TREE_CODE (fncall) == OBJ_TYPE_REF)
+ found_vcall = true;
+ else
+ return false;
+ }
+ else if (gimple_code (stmt2) == GIMPLE_PHI)
+ {
+ found_vcall = var_is_used_for_virtual_call_p
+ (gimple_phi_result (stmt2),
+ mem_ref_depth);
+ }
+ else if (gimple_code (stmt2) == GIMPLE_ASSIGN)
+ {
+ tree rhs = gimple_assign_rhs1 (stmt2);
+ if (TREE_CODE (rhs) == ADDR_EXPR
+ || TREE_CODE (rhs) == MEM_REF)
+ *mem_ref_depth = *mem_ref_depth + 1;
+
+ if (TREE_CODE (rhs) == COMPONENT_REF)
+ {
+ while (TREE_CODE (TREE_OPERAND (rhs, 0)) == COMPONENT_REF)
+ rhs = TREE_OPERAND (rhs, 0);
+
+ if (TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR
+ || TREE_CODE (TREE_OPERAND (rhs, 0)) == MEM_REF)
+ *mem_ref_depth = *mem_ref_depth + 1;
+ }
+
+ if (*mem_ref_depth < 3)
+ found_vcall = var_is_used_for_virtual_call_p
+ (gimple_assign_lhs (stmt2),
+ mem_ref_depth);
+ }
+
+ else
+ break;
+
+ if (found_vcall)
+ return true;
+ }
+
+ return false;
+}
+
+/* Search through all the statements in a basic block (BB), searching
+ for virtual method calls. For each virtual method dispatch, find
+ the vptr value used, and the statically declared type of the
+ object; retrieve the vtable map variable for the type of the
+ object; generate a call to __VLTVerifyVtablePointer; and insert the
+ generated call into the basic block, after the point where the vptr
+ value is gotten out of the object and before the virtual method
+ dispatch. Make the virtual method dispatch depend on the return
+ value from the verification call, so that subsequent optimizations
+ cannot reorder the two calls. */
+
+static void
+verify_bb_vtables (basic_block bb)
+{
+ gimple_seq stmts;
+ gimple stmt = NULL;
+ gimple_stmt_iterator gsi_vtbl_assign;
+ gimple_stmt_iterator gsi_virtual_call;
+
+ stmts = bb_seq (bb);
+ gsi_virtual_call = gsi_start (stmts);
+ for (; !gsi_end_p (gsi_virtual_call); gsi_next (&gsi_virtual_call))
+ {
+ stmt = gsi_stmt (gsi_virtual_call);
+
+ /* Count virtual calls. */
+ if (gimple_code (stmt) == GIMPLE_CALL)
+ {
+ tree fncall = gimple_call_fn (stmt);
+ if (TREE_CODE (fncall) == OBJ_TYPE_REF)
+ total_num_virtual_calls++;
+ }
+
+ if (is_vtable_assignment_stmt (stmt))
+ {
+ tree lhs = gimple_assign_lhs (stmt);
+ tree vtbl_var_decl = NULL_TREE;
+ struct vtbl_map_node *vtable_map_node;
+ tree vtbl_decl = NULL_TREE;
+ gimple call_stmt;
+ const char *vtable_name = "<unknown>";
+ tree tmp0;
+ bool found;
+ int mem_ref_depth = 0;
+
+ /* Make sure this vptr field access is for a virtual call. */
+ if (!var_is_used_for_virtual_call_p (lhs, &mem_ref_depth))
+ continue;
+
+ /* Now we have found the virtual method dispatch and
+ the preceding access of the _vptr.* field... Next
+ we need to find the statically declared type of
+ the object, so we can find and use the right
+ vtable map variable in the verification call. */
+ tree class_type = extract_object_class_type
+ (gimple_assign_rhs1 (stmt));
+
+ gsi_vtbl_assign = gsi_for_stmt (stmt);
+
+ if (class_type
+ && (TREE_CODE (class_type) == RECORD_TYPE)
+ && TYPE_BINFO (class_type))
+ {
+ /* Get the vtable VAR_DECL for the type. */
+ vtbl_var_decl = BINFO_VTABLE (TYPE_BINFO (class_type));
+
+ if (TREE_CODE (vtbl_var_decl) == POINTER_PLUS_EXPR)
+ vtbl_var_decl = TREE_OPERAND (TREE_OPERAND (vtbl_var_decl, 0),
+ 0);
+
+ gcc_assert (vtbl_var_decl);
+
+ vtbl_decl = vtbl_var_decl;
+ vtable_map_node = vtbl_map_get_node
+ (TYPE_MAIN_VARIANT (class_type));
+
+ gcc_assert (verify_vtbl_ptr_fndecl);
+
+ /* Given the vtable pointer for the base class of the
+ object, build the call to __VLTVerifyVtablePointer to
+ verify that the object's vtable pointer (contained in
+ lhs) is in the set of valid vtable pointers for the
+ base class. */
+
+ if (vtable_map_node && vtable_map_node->vtbl_map_decl)
+ {
+ use_operand_p use_p;
+ ssa_op_iter iter;
+
+ vtable_map_node->is_used = true;
+ vtbl_var_decl = vtable_map_node->vtbl_map_decl;
+
+ if (TREE_CODE (vtbl_decl) == VAR_DECL)
+ vtable_name = IDENTIFIER_POINTER (DECL_NAME (vtbl_decl));
+
+ /* Call different routines if we are interested in
+ trace information to debug problems. */
+ if (flag_vtv_debug)
+ {
+ int len1 = IDENTIFIER_LENGTH
+ (DECL_NAME (vtbl_var_decl));
+ int len2 = strlen (vtable_name);
+
+ call_stmt = gimple_build_call
+ (verify_vtbl_ptr_fndecl, 4,
+ build1 (ADDR_EXPR,
+ TYPE_POINTER_TO
+ (TREE_TYPE (vtbl_var_decl)),
+ vtbl_var_decl),
+ lhs,
+ build_string_literal
+ (len1 + 1,
+ IDENTIFIER_POINTER
+ (DECL_NAME
+ (vtbl_var_decl))),
+ build_string_literal (len2 + 1,
+ vtable_name));
+ }
+ else
+ call_stmt = gimple_build_call
+ (verify_vtbl_ptr_fndecl, 2,
+ build1 (ADDR_EXPR,
+ TYPE_POINTER_TO
+ (TREE_TYPE (vtbl_var_decl)),
+ vtbl_var_decl),
+ lhs);
+
+
+ /* Create a new SSA_NAME var to hold the call's
+ return value, and make the call_stmt use the
+ variable for that purpose. */
+ tmp0 = make_temp_ssa_name (TREE_TYPE (lhs), NULL, "VTV");
+ gimple_call_set_lhs (call_stmt, tmp0);
+ update_stmt (call_stmt);
+
+ /* Find the next stmt, after the vptr assignment
+ statememt, which should use the result of the
+ vptr assignment statement value. */
+ gsi_next (&gsi_vtbl_assign);
+ gimple next_stmt = gsi_stmt (gsi_vtbl_assign);
+
+ if (!next_stmt)
+ return;
+
+ /* Find any/all uses of 'lhs' in next_stmt, and
+ replace them with 'tmp0'. */
+ found = false;
+ FOR_EACH_PHI_OR_STMT_USE (use_p, next_stmt, iter,
+ SSA_OP_ALL_USES)
+ {
+ tree op = USE_FROM_PTR (use_p);
+ if (op == lhs)
+ {
+ SET_USE (use_p, tmp0);
+ found = true;
+ }
+ }
+ update_stmt (next_stmt);
+ gcc_assert (found);
+
+ /* Insert the new verification call just after the
+ statement that gets the vtable pointer out of the
+ object. */
+ gsi_vtbl_assign = gsi_for_stmt (stmt);
+ gsi_insert_after (&gsi_vtbl_assign, call_stmt,
+ GSI_NEW_STMT);
+
+ any_verification_calls_generated = true;
+ total_num_verified_vcalls++;
+ }
+ }
+ }
+ }
+}
+
+/* Main function, called from pass->excute(). Loop through all the
+ basic blocks in the current function, passing them to
+ verify_bb_vtables, which searches for virtual calls, and inserts
+ calls to __VLTVerifyVtablePointer. */
+
+unsigned int
+vtable_verify_main (void)
+{
+ unsigned int ret = 1;
+ basic_block bb;
+
+ FOR_ALL_BB (bb)
+ verify_bb_vtables (bb);
+
+ return ret;
+}
+
+/* Gate function for the pass. */
+
+static bool
+gate_tree_vtable_verify (void)
+{
+ return (flag_vtable_verify);
+}
+
+/* Definition of this optimization pass. */
+
+namespace {
+
+const pass_data pass_data_vtable_verify =
+{
+ GIMPLE_PASS, /* type */
+ "vtable-verify", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_VTABLE_VERIFICATION, /* tv_id */
+ ( PROP_cfg | PROP_ssa ), /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_update_ssa, /* todo_flags_finish */
+};
+
+class pass_vtable_verify : public gimple_opt_pass
+{
+public:
+ pass_vtable_verify(gcc::context *ctxt)
+ : gimple_opt_pass(pass_data_vtable_verify, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_tree_vtable_verify (); }
+ unsigned int execute () { return vtable_verify_main (); }
+
+}; // class pass_vtable_verify
+
+} // anon namespace
+
+gimple_opt_pass *
+make_pass_vtable_verify (gcc::context *ctxt)
+{
+ return new pass_vtable_verify (ctxt);
+}
+
+#include "gt-vtable-verify.h"
diff --git a/gcc/vtable-verify.h b/gcc/vtable-verify.h
new file mode 100644
index 00000000000..7ac487bef52
--- /dev/null
+++ b/gcc/vtable-verify.h
@@ -0,0 +1,141 @@
+/* Copyright (C) 2013
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+/* Virtual Table Pointer Security. */
+
+#ifndef VTABLE_VERIFY_H
+#define VTABLE_VERIFY_H
+
+#include "sbitmap.h"
+#include "hash-table.h"
+
+/* The function decl used to create calls to __VLTVtableVerify. It must
+ be global because it needs to be initialized in the C++ front end, but
+ used in the middle end (in the vtable verification pass). */
+
+extern tree verify_vtbl_ptr_fndecl;
+
+/* Global variable keeping track of how many vtable map variables we
+ have created. */
+extern unsigned num_vtable_map_nodes;
+
+/* Keep track of how many virtual calls we are actually verifying. */
+extern int total_num_virtual_calls;
+extern int total_num_verified_vcalls;
+
+/* Each vtable map variable corresponds to a virtual class. Each
+ vtable map variable has a hash table associated with it, that keeps
+ track of the vtable pointers for which we have generated a call to
+ __VLTRegisterPair (with the current vtable map variable). This is
+ the hash table node that is used for each entry in this hash table
+ of vtable pointers.
+
+ Sometimes there are multiple valid vtable pointer entries that use
+ the same vtable pointer decl with different offsets. Therefore,
+ for each vtable pointer in the hash table, there is also an array
+ of offsets used with that vtable. */
+
+struct vtable_registration
+{
+ tree vtable_decl; /* The var decl of the vtable. */
+ vec<unsigned> offsets; /* The offsets array. */
+};
+
+struct registration_hasher : typed_noop_remove <struct vtable_registration>
+{
+ typedef struct vtable_registration value_type;
+ typedef struct vtable_registration compare_type;
+ static inline hashval_t hash (const value_type *);
+ static inline bool equal (const value_type *, const compare_type *);
+};
+
+typedef hash_table <registration_hasher> register_table_type;
+typedef register_table_type::iterator registration_iterator_type;
+
+/* This struct is used to represent the class hierarchy information
+ that we need. Each vtable map variable has an associated class
+ hierarchy node (struct vtv_graph_node). Note: In this struct,
+ 'children' means immediate descendants in the class hierarchy;
+ 'descendant' means any descendant however many levels deep. */
+
+struct vtv_graph_node {
+ tree class_type; /* The record_type of the class. */
+ unsigned class_uid; /* A unique, monotonically
+ ascending id for class node.
+ Each vtable map node also has
+ an id. The class uid is the
+ same as the vtable map node id
+ for nodes corresponding to the
+ same class. */
+ unsigned num_processed_children; /* # of children for whom we have
+ computed the class hierarchy
+ transitive closure. */
+ vec<struct vtv_graph_node *> parents; /* Vector of parents in the graph. */
+ vec<struct vtv_graph_node *> children; /* Vector of children in the graph.*/
+ sbitmap descendants; /* Bitmap representing all this node's
+ descendants in the graph. */
+};
+
+/* This is the node used for our hashtable of vtable map variable
+ information. When we create a vtable map variable (var decl) we
+ put it into one of these nodes; create a corresponding
+ vtv_graph_node for our class hierarchy info and store that in this
+ node; generate a unique (monotonically ascending) id for both the
+ vtbl_map_node and the vtv_graph_node; and insert the node into two
+ data structures (to make it easy to find in several different
+ ways): 1). A hash table ("vtbl_map_hash" in vtable-verify.c).
+ This gives us an easy way to check to see if we already have a node
+ for the vtable map variable or not; and 2). An array (vector) of
+ vtbl_map_nodes, where the array index corresponds to the unique id
+ of the vtbl_map_node, which gives us an easy way to use bitmaps to
+ represent and find the vtable map nodes. */
+
+struct vtbl_map_node {
+ tree vtbl_map_decl; /* The var decl for the vtable map
+ variable. */
+ tree class_name; /* The DECL_ASSEMBLER_NAME of the
+ class. */
+ struct vtv_graph_node *class_info; /* Our class hierarchy info for the
+ class. */
+ unsigned uid; /* The unique id for the vtable map
+ variable. */
+ struct vtbl_map_node *next, *prev; /* Pointers for the linked list
+ structure. */
+ register_table_type registered; /* Hashtable of vtable pointers for which
+ we have generated a _VLTRegisterPair
+ call with this vtable map variable. */
+ bool is_used; /* Boolean indicating if we used this vtable map
+ variable in a call to __VLTVerifyVtablePointer. */
+};
+
+/* Controls debugging for vtable verification. */
+extern bool vtv_debug;
+
+/* The global vector of vtbl_map_nodes. */
+extern vec<struct vtbl_map_node *> vtbl_map_nodes_vec;
+
+extern struct vtbl_map_node *vtbl_map_get_node (tree);
+extern struct vtbl_map_node *find_or_create_vtbl_map_node (tree);
+extern void vtbl_map_node_class_insert (struct vtbl_map_node *, unsigned);
+extern bool vtbl_map_node_registration_find (struct vtbl_map_node *,
+ tree, unsigned);
+extern bool vtbl_map_node_registration_insert (struct vtbl_map_node *,
+ tree, unsigned);
+
+#endif /* VTABLE_VERIFY_H */
diff --git a/gcc/web.c b/gcc/web.c
index 1f2e24fc105..6c3ab952188 100644
--- a/gcc/web.c
+++ b/gcc/web.c
@@ -453,22 +453,40 @@ web_main (void)
return 0;
}
-struct rtl_opt_pass pass_web =
+namespace {
+
+const pass_data pass_data_web =
{
- {
- RTL_PASS,
- "web", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_handle_web, /* gate */
- web_main, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_WEB, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish | TODO_verify_rtl_sharing /* todo_flags_finish */
- }
+ RTL_PASS, /* type */
+ "web", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ true, /* has_gate */
+ true, /* has_execute */
+ TV_WEB, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ ( TODO_df_finish | TODO_verify_rtl_sharing ), /* todo_flags_finish */
};
+
+class pass_web : public rtl_opt_pass
+{
+public:
+ pass_web(gcc::context *ctxt)
+ : rtl_opt_pass(pass_data_web, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ bool gate () { return gate_handle_web (); }
+ unsigned int execute () { return web_main (); }
+
+}; // class pass_web
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_web (gcc::context *ctxt)
+{
+ return new pass_web (ctxt);
+}
diff --git a/gnattools/ChangeLog b/gnattools/ChangeLog
index d7333c60b85..a1e7b9a32b8 100644
--- a/gnattools/ChangeLog
+++ b/gnattools/ChangeLog
@@ -1,3 +1,12 @@
+2013-09-01 Eric Botcazou <ebotcazou@adacore.com>
+ Iain Sandoe <iain@codesourcery.com>
+
+ PR ada/58239
+ * Makefile.in (CXX_LFLAGS): New.
+ (TOOLS_FLAGS_TO_PASS_NATIVE): Pass CXX and CXX_LFLAGS.
+ (TOOLS_FLAGS_TO_PASS_RE): Likewise.
+ (TOOLS_FLAGS_TO_PASS_CROSS): Pass CXX.
+
2012-03-14 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* configure.ac (mips-sgi-irix*): Remove.
diff --git a/gnattools/Makefile.in b/gnattools/Makefile.in
index 794d374e75e..fdd649194df 100644
--- a/gnattools/Makefile.in
+++ b/gnattools/Makefile.in
@@ -63,9 +63,16 @@ INCLUDES_FOR_SUBDIR = -I. -I.. -I../.. -I$(fsrcdir)/ada -I$(fsrcdir)/config \
-I$(fsrcdir)/../include -I$(fsrcdir)
ADA_INCLUDES_FOR_SUBDIR = -I. -I$(fsrcdir)/ada
+CXX_LFLAGS = \
+ -B../../../$(target_noncanonical)/libstdc++-v3/src/.libs \
+ -B../../../$(target_noncanonical)/libstdc++-v3/libsupc++/.libs \
+ -L../../../$(target_noncanonical)/libstdc++-v3/src/.libs \
+ -L../../../$(target_noncanonical)/libstdc++-v3/libsupc++/.libs
+
# Variables for gnattools, native
TOOLS_FLAGS_TO_PASS_NATIVE= \
"CC=../../xgcc -B../../" \
+ "CXX=../../xg++ -B../../ $(CXX_LFLAGS)" \
"CFLAGS=$(CFLAGS) $(WARN_CFLAGS)" \
"LDFLAGS=$(LDFLAGS)" \
"ADAFLAGS=$(ADAFLAGS)" \
@@ -83,6 +90,7 @@ TOOLS_FLAGS_TO_PASS_NATIVE= \
# Variables for regnattools
TOOLS_FLAGS_TO_PASS_RE= \
"CC=../../xgcc -B../../" \
+ "CXX=../../xg++ -B../../ $(CXX_LFLAGS)" \
"CFLAGS=$(CFLAGS)" \
"ADAFLAGS=$(ADAFLAGS)" \
"ADA_CFLAGS=$(ADA_CFLAGS)" \
@@ -99,6 +107,7 @@ TOOLS_FLAGS_TO_PASS_RE= \
# Variables for gnattools, cross
TOOLS_FLAGS_TO_PASS_CROSS= \
"CC=$(CC)" \
+ "CXX=$(CXX)" \
"CFLAGS=$(CFLAGS) $(WARN_CFLAGS)" \
"LDFLAGS=$(LDFLAGS)" \
"ADAFLAGS=$(ADAFLAGS)" \
diff --git a/include/ChangeLog b/include/ChangeLog
index 7fe2842b413..e41915461d6 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,17 @@
+2013-08-20 Alan Modra <amodra@gmail.com>
+
+ * floatformat.h (floatformat_ibm_long_double): Delete.
+ (floatformat_ibm_long_double_big): Declare.
+ (floatformat_ibm_long_double_little): Declare.
+
+2013-08-19 Dehao Chen <dehao@google.com>
+
+ * dwarf2.def (DW_AT_GNU_discriminator): New attribute.
+
+2013-08-02 Caroline Tice <cmtice@google.com>
+
+ * vtv-change-permission.h: New file.
+
2013-04-03 Jason Merrill <jason@redhat.com>
Demangle C++11 ref-qualifier.
diff --git a/include/dwarf2.def b/include/dwarf2.def
index 7fe2df126c5..71a37b30c9f 100644
--- a/include/dwarf2.def
+++ b/include/dwarf2.def
@@ -390,6 +390,9 @@ DW_AT (DW_AT_GNU_ranges_base, 0x2132)
DW_AT (DW_AT_GNU_addr_base, 0x2133)
DW_AT (DW_AT_GNU_pubnames, 0x2134)
DW_AT (DW_AT_GNU_pubtypes, 0x2135)
+/* Attribute for discriminator.
+ See http://gcc.gnu.org/wiki/Discriminator */
+DW_AT (DW_AT_GNU_discriminator, 0x2136)
/* VMS extensions. */
DW_AT (DW_AT_VMS_rtnbeg_pd_address, 0x2201)
/* GNAT extensions. */
diff --git a/include/floatformat.h b/include/floatformat.h
index b5951644ea5..04db61a2659 100644
--- a/include/floatformat.h
+++ b/include/floatformat.h
@@ -128,7 +128,8 @@ extern const struct floatformat floatformat_ia64_spill_little;
extern const struct floatformat floatformat_ia64_quad_big;
extern const struct floatformat floatformat_ia64_quad_little;
/* IBM long double (double+double). */
-extern const struct floatformat floatformat_ibm_long_double;
+extern const struct floatformat floatformat_ibm_long_double_big;
+extern const struct floatformat floatformat_ibm_long_double_little;
/* Convert from FMT to a double.
FROM is the address of the extended float.
diff --git a/include/vtv-change-permission.h b/include/vtv-change-permission.h
new file mode 100644
index 00000000000..1adcb974594
--- /dev/null
+++ b/include/vtv-change-permission.h
@@ -0,0 +1,55 @@
+/* Copyright (C) 2013
+ Free Software Foundation
+
+ This file is part of GCC.
+
+ modify it under the terms of the GNU Library General Public License
+ as published by the Free Software Foundation; either version 2, or
+ (at your option) any later version.
+
+ In addition to the permissions in the GNU Library General Public
+ License, the Free Software Foundation gives you unlimited
+ permission to link the compiled version of this file into
+ combinations with other programs, and to distribute those
+ combinations without any restriction coming from the use of this
+ file. (The Library Public License restrictions do apply in other
+ respects; for example, they cover modification of the file, and
+ distribution when not linked into a combined executable.)
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
+ 02110-1301, USA. */
+
+
+#ifndef __VTV_H__
+#define __VTV_H__
+
+/* We could have used an enumeration here but it just makes it more
+ difficult for the compiler to generate a call to this. These are
+ used as arguments to the function __VLTChangePermission, declared
+ below. */
+#define __VLTP_READ_ONLY 0
+#define __VLTP_READ_WRITE 1
+
+#ifdef __cplusplus
+extern "C" void __VLTChangePermission (int);
+#else
+extern void __VLTChangePermission (int);
+#endif
+
+#ifdef BIG_PAGE_SIZE
+/* TODO - Replace '4096' below with correct big page size. */
+#define VTV_PAGE_SIZE 4096
+#else
+#define VTV_PAGE_SIZE 4096
+#endif
+
+
+
+#endif /* __VTV_H__ */
diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog
index dd107aec089..862333e1422 100644
--- a/libcpp/ChangeLog
+++ b/libcpp/ChangeLog
@@ -1,3 +1,8 @@
+2013-08-07 Richard Earnshaw <rearnsha@arm.com>
+
+ * configure.ac: Set need_64bit_hwint for all arm targets.
+ * configure: Regenerated.
+
2013-07-20 Jakub Jelinek <jakub@redhat.com>
PR preprocessor/57620
diff --git a/libcpp/configure b/libcpp/configure
index 715818697b8..60ce2e569dd 100755
--- a/libcpp/configure
+++ b/libcpp/configure
@@ -7152,9 +7152,7 @@ fi
case $target in
aarch64*-*-* | \
alpha*-*-* | \
- arm*-*-*eabi* | \
- arm*-*-rtems* | \
- arm*-*-symbianelf* | \
+ arm*-*-* | \
x86_64-*-* | \
ia64-*-* | \
hppa*64*-*-* | \
diff --git a/libcpp/configure.ac b/libcpp/configure.ac
index 43ac9bade1b..799301f0722 100644
--- a/libcpp/configure.ac
+++ b/libcpp/configure.ac
@@ -184,9 +184,7 @@ m4_changequote(,)
case $target in
aarch64*-*-* | \
alpha*-*-* | \
- arm*-*-*eabi* | \
- arm*-*-rtems* | \
- arm*-*-symbianelf* | \
+ arm*-*-* | \
x86_64-*-* | \
ia64-*-* | \
hppa*64*-*-* | \
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index 78700d7a15c..2f415bfc80a 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,66 @@
+2013-08-18 Iain Sandoe <iain@codesourcery.com>
+
+ PR gcov-profile/58127
+ * libgcov.c (__gcov_indirect_call_callee): Don't make this a
+ __thread var for emulated TLS.
+ (__gcov_indirect_call_counters): Likewise.
+
+2013-08-16 Maciej W. Rozycki <macro@codesourcery.com>
+ Catherine Moore <clm@codesourcery.com>
+ Richard Sandiford <rdsandiford@googlemail.com>
+
+ * config/mips/mips16.S (CE_STARTFN, CE_ENDFN): New macros.
+ (RET_FUNCTION): Use them in place of STARTFN and ENDFN.
+ (CALL_STUB_NO_RET): Likewise.
+ (CALL_STUB_RET): Likewise.
+ * config/mips/libgcc-mips16.ver: Remove __mips16_call_stub and
+ __mips16_ret call/return stub symbols.
+ * config.host <mips*-*-linux>: For non-R5900 add t-slibgcc-libgcc
+ to tmake_file.
+
+2013-08-13 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config.host <mips*-*-linux*>: Remove a stray comment.
+
+2013-08-10 Jan Hubicka <jh@suse.cz>
+
+ Work around binutils PR14342
+ * Makefile.in: Add _gcov_indirect_call_profiler_v2 symbol.
+ * libgcov.c (L_gcov_indirect_call_profiler): Restore original API.
+ (L_gcov_indirect_call_profiler_v2): New.
+
+2013-08-06 Jan Hubicka <jh@suse.cz>
+
+ * libgcov.c (__gcov_indirect_call_callee,
+ __gcov_indirect_call_counters): New global vars.
+ (__gcov_indirect_call_profiler): replace by ...
+ (__gcov_indirect_call_profiler_v2) ... this one.
+
+2013-08-06 Caroline Tice <cmtice@google.com>
+
+ * config.host (extra_parts): Add vtv_start.o, vtv_end.o
+ vtv_start_preinit.o and vtv_end_preinit.o.
+ * configure.ac: Add code to check/set enable_vtable_verify.
+ * Makefile.in: Add rules to build vtv_*.o, if enable_vtable_verify is
+ true.
+ * vtv_start_preinit.c: New file.
+ * vtv_end_preinit.c: New file.
+ * vtv_start.c: New file.
+ * vtv_end.c: New file.
+ * configure: Regenerated.
+
+2013-08-01 Maxim Kuvyrkov <maxim@kugelworks.com>
+
+ * config/aarch64/sfp-machine.h, config/aarch64/sync-cache.c,
+ * config/i386/cpuinfo.c, config/ia64/unwind-ia64.h,
+ * config/mips/vr4120-div.S: Fix license from GPL-3.0+ to
+ GPL-3.0-with-GCC-exception.
+
+2013-07-30 Maciej W. Rozycki <macro@codesourcery.com>
+
+ * config/mips/mips16.S (DELAYf): Alias to DELAYt for the MIPS IV
+ ISA and up.
+
2013-07-23 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config/s390/linux-unwind.h: Use the proper dwarf to hard reg
diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 958be5ec86f..354fb72d984 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -39,6 +39,7 @@ enable_shared = @enable_shared@
double_type_size = @double_type_size@
long_double_type_size = @long_double_type_size@
decimal_float = @decimal_float@
+enable_vtable_verify = @enable_vtable_verify@
enable_decimal_float = @enable_decimal_float@
fixed_point = @fixed_point@
@@ -857,7 +858,7 @@ LIBGCOV = _gcov _gcov_merge_add _gcov_merge_single _gcov_merge_delta \
_gcov_execv _gcov_execvp _gcov_execve _gcov_reset _gcov_dump \
_gcov_interval_profiler _gcov_pow2_profiler _gcov_one_value_profiler \
_gcov_indirect_call_profiler _gcov_average_profiler _gcov_ior_profiler \
- _gcov_merge_ior
+ _gcov_merge_ior _gcov_indirect_call_profiler_v2
libgcov-objects = $(patsubst %,%$(objext),$(LIBGCOV))
@@ -971,6 +972,22 @@ crtendS$(objext): $(srcdir)/crtstuff.c
# This is a version of crtbegin for -static links.
crtbeginT$(objext): $(srcdir)/crtstuff.c
$(crt_compile) $(CRTSTUFF_T_CFLAGS) -c $< -DCRT_BEGIN -DCRTSTUFFT_O
+
+ifeq ($(enable_vtable_verify),yes)
+# These are used in vtable verification; see comments in source files for
+# more details.
+vtv_start$(objext): $(srcdir)/vtv_start.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $(srcdir)/vtv_start.c
+
+vtv_end$(objext): $(srcdir)/vtv_end.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $(srcdir)/vtv_end.c
+
+vtv_start_preinit$(objext): $(srcdir)/vtv_start_preinit.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $(srcdir)/vtv_start_preinit.c
+
+vtv_end_preinit$(objext): $(srcdir)/vtv_end_preinit.c
+ $(crt_compile) $(CRTSTUFF_T_CFLAGS_S) -c $(srcdir)/vtv_end_preinit.c
+endif
endif
ifeq ($(CUSTOM_CRTIN),)
diff --git a/libgcc/config.host b/libgcc/config.host
index 9c47e1b4233..187391e9a2e 100644
--- a/libgcc/config.host
+++ b/libgcc/config.host
@@ -197,7 +197,7 @@ case ${host} in
;;
*-*-linux* | frv-*-*linux* | *-*-kfreebsd*-gnu | *-*-knetbsd*-gnu | *-*-gnu* | *-*-kopensolaris*-gnu)
tmake_file="$tmake_file t-crtstuff-pic t-libgcc-pic t-eh-dw2-dip t-slibgcc t-slibgcc-gld t-slibgcc-elf-ver t-linux"
- extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o"
+ extra_parts="crtbegin.o crtbeginS.o crtbeginT.o crtend.o crtendS.o vtv_start.o vtv_end.o vtv_start_preinit.o vtv_end_preinit.o"
;;
*-*-lynxos*)
tmake_file="$tmake_file t-lynx $cpu_type/t-crtstuff t-crtstuff-pic t-libgcc-pic"
@@ -740,15 +740,14 @@ mips*-*-netbsd*) # NetBSD/mips, either endian.
mips*-*-linux*) # Linux MIPS, either endian.
extra_parts="$extra_parts crtfastmath.o"
tmake_file="${tmake_file} t-crtfm"
- # Check for MicroMIPS support.
case ${host} in
- mips64r5900* | mipsr5900*)
- # The MIPS16 support code uses floating point
- # instructions that are not supported on r5900.
- ;;
- *)
- tmake_file="${tmake_file} mips/t-mips16"
- ;;
+ mips64r5900* | mipsr5900*)
+ # The MIPS16 support code uses floating point
+ # instructions that are not supported on r5900.
+ ;;
+ *)
+ tmake_file="${tmake_file} mips/t-mips16 t-slibgcc-libgcc"
+ ;;
esac
md_unwind_header=mips/linux-unwind.h
if test "${ac_cv_sizeof_long_double}" = 16; then
diff --git a/libgcc/config/aarch64/sfp-machine.h b/libgcc/config/aarch64/sfp-machine.h
index 306da1749b3..fb7c5dab97c 100644
--- a/libgcc/config/aarch64/sfp-machine.h
+++ b/libgcc/config/aarch64/sfp-machine.h
@@ -2,21 +2,26 @@
Copyright (C) 2009-2013 Free Software Foundation, Inc.
Contributed by ARM 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.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
+This 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/>. */
#define _FP_W_TYPE_SIZE 64
#define _FP_W_TYPE unsigned long long
diff --git a/libgcc/config/aarch64/sync-cache.c b/libgcc/config/aarch64/sync-cache.c
index 3397e9d29b4..0899256ab9f 100644
--- a/libgcc/config/aarch64/sync-cache.c
+++ b/libgcc/config/aarch64/sync-cache.c
@@ -2,21 +2,26 @@
Copyright (C) 2012-2013 Free Software Foundation, Inc.
Contributed by ARM Ltd.
- This file is part of GCC.
+This file is part of GCC.
- GCC is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
- GCC is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
+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/>. */
void __aarch64_sync_cache_range (const void *, const void *);
diff --git a/libgcc/config/i386/cpuinfo.c b/libgcc/config/i386/cpuinfo.c
index b7e64c3d720..1c744f12344 100644
--- a/libgcc/config/i386/cpuinfo.c
+++ b/libgcc/config/i386/cpuinfo.c
@@ -14,9 +14,14 @@ 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/>. */
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
#include "cpuid.h"
#include "tsystem.h"
diff --git a/libgcc/config/ia64/unwind-ia64.h b/libgcc/config/ia64/unwind-ia64.h
index fb5a3c48fb0..644f81a2b2a 100644
--- a/libgcc/config/ia64/unwind-ia64.h
+++ b/libgcc/config/ia64/unwind-ia64.h
@@ -2,21 +2,26 @@
Contributed by Andrew MacLeod <amacleod@cygnus.com>
Andrew Haley <aph@cygnus.com>
- This file is part of GCC.
-
- GCC is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3, or (at your option)
- any later version.
-
- GCC is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
+This 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/>. */
#ifdef __VMS__
/* On VMS, long is a 32 bit type. */
diff --git a/libgcc/config/mips/libgcc-mips16.ver b/libgcc/config/mips/libgcc-mips16.ver
index d4e4777c817..ed949c3af59 100644
--- a/libgcc/config/mips/libgcc-mips16.ver
+++ b/libgcc/config/mips/libgcc-mips16.ver
@@ -45,42 +45,4 @@ GCC_4.4.0 {
__mips16_floatsidf
__mips16_floatunsidf
__mips16_fix_truncdfsi
- __mips16_ret_sf
- __mips16_ret_sc
- __mips16_ret_df
- __mips16_ret_dc
- __mips16_call_stub_1
- __mips16_call_stub_5
- __mips16_call_stub_2
- __mips16_call_stub_6
- __mips16_call_stub_9
- __mips16_call_stub_10
- __mips16_call_stub_sf_0
- __mips16_call_stub_sf_1
- __mips16_call_stub_sf_5
- __mips16_call_stub_sf_2
- __mips16_call_stub_sf_6
- __mips16_call_stub_sf_9
- __mips16_call_stub_sf_10
- __mips16_call_stub_sc_0
- __mips16_call_stub_sc_1
- __mips16_call_stub_sc_5
- __mips16_call_stub_sc_2
- __mips16_call_stub_sc_6
- __mips16_call_stub_sc_9
- __mips16_call_stub_sc_10
- __mips16_call_stub_df_0
- __mips16_call_stub_df_1
- __mips16_call_stub_df_5
- __mips16_call_stub_df_2
- __mips16_call_stub_df_6
- __mips16_call_stub_df_9
- __mips16_call_stub_df_10
- __mips16_call_stub_dc_0
- __mips16_call_stub_dc_1
- __mips16_call_stub_dc_5
- __mips16_call_stub_dc_2
- __mips16_call_stub_dc_6
- __mips16_call_stub_dc_9
- __mips16_call_stub_dc_10
}
diff --git a/libgcc/config/mips/mips16.S b/libgcc/config/mips/mips16.S
index 82675018002..d910758fe3a 100644
--- a/libgcc/config/mips/mips16.S
+++ b/libgcc/config/mips/mips16.S
@@ -89,8 +89,13 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
OPCODE, OP2; \
.set reorder
+#if __mips >= 4
+/* Coprocessor moves are interlocked from the MIPS IV ISA up. */
+#define DELAYf(T, OPCODE, OP2) DELAYt (T, OPCODE, OP2)
+#else
/* Use "OPCODE. OP2" and jump to T. */
#define DELAYf(T, OPCODE, OP2) OPCODE, OP2; jr T
+#endif
/* MOVE_SF_BYTE0(D)
Move the first single-precision floating-point argument between
@@ -474,13 +479,35 @@ STARTFN (__mips16_fix_truncdfsi)
#endif
#endif /* !__mips_single_float */
+/* We don't export stubs from libgcc_s.so and always require static
+ versions to be pulled from libgcc.a as needed because they use $2
+ and possibly $3 as arguments, diverging from the standard SysV ABI,
+ and as such would require severe pessimisation of MIPS16 PLT entries
+ just for this single special case.
+
+ For compatibility with old binaries that used safe standard MIPS PLT
+ entries and referred to these functions we still export them at
+ version GCC_4.4.0 for run-time loading only. */
+
+#ifdef SHARED
+#define CE_STARTFN(NAME) \
+STARTFN (NAME##_compat); \
+ .symver NAME##_compat, NAME@GCC_4.4.0
+#define CE_ENDFN(NAME) ENDFN (NAME##_compat)
+#else
+#define CE_STARTFN(NAME) \
+STARTFN (NAME); \
+ .hidden NAME
+#define CE_ENDFN(NAME) ENDFN (NAME)
+#endif
+
/* Define a function NAME that moves a return value of mode MODE from
FPRs to GPRs. */
#define RET_FUNCTION(NAME, MODE) \
-STARTFN (NAME); \
+CE_STARTFN (NAME); \
MOVE_##MODE##_RET (t, $31); \
- ENDFN (NAME)
+ CE_ENDFN (NAME)
#ifdef L_m16retsf
RET_FUNCTION (__mips16_ret_sf, SF)
@@ -521,13 +548,13 @@ RET_FUNCTION (__mips16_ret_dc, DC)
to FPRs and then call function $2. */
#define CALL_STUB_NO_RET(NAME, CODE) \
-STARTFN (NAME); \
+CE_STARTFN (NAME); \
STUB_ARGS_##CODE; \
.set noreorder; \
jr $2; \
move $25,$2; \
.set reorder; \
- ENDFN (NAME)
+ CE_ENDFN (NAME)
#ifdef L_m16stub1
CALL_STUB_NO_RET (__mips16_call_stub_1, 1)
@@ -570,7 +597,7 @@ CALL_STUB_NO_RET (__mips16_call_stub_10, 10)
however, it's faster to always do the copy. */
#define CALL_STUB_RET(NAME, CODE, MODE) \
-STARTFN (NAME); \
+CE_STARTFN (NAME); \
.cfi_startproc; \
/* Create a fake CFA 4 bytes below the stack pointer. */ \
.cfi_def_cfa 29,-4; \
@@ -586,7 +613,7 @@ STARTFN (NAME); \
.set reorder; \
MOVE_##MODE##_RET (f, $18); \
.cfi_endproc; \
- ENDFN (NAME)
+ CE_ENDFN (NAME)
/* First, instantiate the single-float set. */
diff --git a/libgcc/config/mips/vr4120-div.S b/libgcc/config/mips/vr4120-div.S
index 2b934624a87..6e9242a1e37 100644
--- a/libgcc/config/mips/vr4120-div.S
+++ b/libgcc/config/mips/vr4120-div.S
@@ -3,18 +3,23 @@
This file is part of GCC.
-GCC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 3, or (at your option)
-any later version.
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
-GCC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
-You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/* This file contains functions which implement divsi3 and modsi3 for
diff --git a/libgcc/configure b/libgcc/configure
index bb36889ae56..29fa46f597a 100644
--- a/libgcc/configure
+++ b/libgcc/configure
@@ -608,6 +608,7 @@ build_os
build_vendor
build_cpu
build
+enable_vtable_verify
enable_shared
libgcc_topdir
target_alias
@@ -655,6 +656,7 @@ with_target_subdir
with_cross_host
with_ld
enable_shared
+enable_vtable_verify
enable_version_specific_runtime_libs
with_slibdir
enable_maintainer_mode
@@ -1288,6 +1290,7 @@ Optional Features:
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-shared don't provide a shared libgcc
+ --enable-vtable-verify Enable vtable verification feature
--enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory
--enable-maintainer-mode
enable make rules and dependencies not useful (and
@@ -2140,6 +2143,19 @@ fi
+# Check whether --enable-vtable-verify was given.
+if test "${enable_vtable_verify+set}" = set; then :
+ enableval=$enable_vtable_verify; case "$enableval" in
+ yes) enable_vtable_verify=yes ;;
+ no) enable_vtable_verify=no ;;
+ *) enable_vtable_verify=no;;
+ esac
+else
+ enable_vtable_verify=no
+fi
+
+
+
# Make sure we can run config.sub.
$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
diff --git a/libgcc/configure.ac b/libgcc/configure.ac
index 8b7aba5823b..186cd6e9cd7 100644
--- a/libgcc/configure.ac
+++ b/libgcc/configure.ac
@@ -66,6 +66,16 @@ AC_ARG_ENABLE(shared,
], [enable_shared=yes])
AC_SUBST(enable_shared)
+AC_ARG_ENABLE(vtable-verify,
+[ --enable-vtable-verify Enable vtable verification feature ],
+[case "$enableval" in
+ yes) enable_vtable_verify=yes ;;
+ no) enable_vtable_verify=no ;;
+ *) enable_vtable_verify=no;;
+ esac],
+[enable_vtable_verify=no])
+AC_SUBST(enable_vtable_verify)
+
GCC_PICFLAG
AC_SUBST(PICFLAG)
diff --git a/libgcc/libgcov.c b/libgcc/libgcov.c
index a93eddbd4c2..3c39331e6ba 100644
--- a/libgcc/libgcov.c
+++ b/libgcc/libgcov.c
@@ -1120,6 +1120,8 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
#endif
#ifdef L_gcov_indirect_call_profiler
+/* This function exist only for workaround of binutils bug 14342.
+ Once this compatibility hack is obsolette, it can be removed. */
/* By default, the C++ compiler will use function addresses in the
vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
@@ -1141,18 +1143,64 @@ __gcov_one_value_profiler (gcov_type *counters, gcov_type value)
/* Tries to determine the most common value among its inputs. */
void
__gcov_indirect_call_profiler (gcov_type* counter, gcov_type value,
- void* cur_func, void* callee_func)
+ void* cur_func, void* callee_func)
{
/* If the C++ virtual tables contain function descriptors then one
function may have multiple descriptors and we need to dereference
the descriptors to see if they point to the same function. */
if (cur_func == callee_func
|| (VTABLE_USES_DESCRIPTORS && callee_func
- && *(void **) cur_func == *(void **) callee_func))
+ && *(void **) cur_func == *(void **) callee_func))
__gcov_one_value_profiler_body (counter, value);
}
+
+#endif
+#ifdef L_gcov_indirect_call_profiler_v2
+
+/* These two variables are used to actually track caller and callee. Keep
+ them in TLS memory so races are not common (they are written to often).
+ The variables are set directly by GCC instrumented code, so declaration
+ here must match one in tree-profile.c */
+
+#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
+__thread
+#endif
+void * __gcov_indirect_call_callee;
+#if defined(HAVE_CC_TLS) && !defined (USE_EMUTLS)
+__thread
+#endif
+gcov_type * __gcov_indirect_call_counters;
+
+/* By default, the C++ compiler will use function addresses in the
+ vtable entries. Setting TARGET_VTABLE_USES_DESCRIPTORS to nonzero
+ tells the compiler to use function descriptors instead. The value
+ of this macro says how many words wide the descriptor is (normally 2),
+ but it may be dependent on target flags. Since we do not have access
+ to the target flags here we just check to see if it is set and use
+ that to set VTABLE_USES_DESCRIPTORS to 0 or 1.
+
+ It is assumed that the address of a function descriptor may be treated
+ as a pointer to a function. */
+
+#ifdef TARGET_VTABLE_USES_DESCRIPTORS
+#define VTABLE_USES_DESCRIPTORS 1
+#else
+#define VTABLE_USES_DESCRIPTORS 0
#endif
+/* Tries to determine the most common value among its inputs. */
+void
+__gcov_indirect_call_profiler_v2 (gcov_type value, void* cur_func)
+{
+ /* If the C++ virtual tables contain function descriptors then one
+ function may have multiple descriptors and we need to dereference
+ the descriptors to see if they point to the same function. */
+ if (cur_func == __gcov_indirect_call_callee
+ || (VTABLE_USES_DESCRIPTORS && __gcov_indirect_call_callee
+ && *(void **) cur_func == *(void **) __gcov_indirect_call_callee))
+ __gcov_one_value_profiler_body (__gcov_indirect_call_counters, value);
+}
+#endif
#ifdef L_gcov_average_profiler
/* Increase corresponding COUNTER by VALUE. FIXME: Perhaps we want
diff --git a/libgcc/vtv_end.c b/libgcc/vtv_end.c
new file mode 100644
index 00000000000..83fa101c8e3
--- /dev/null
+++ b/libgcc/vtv_end.c
@@ -0,0 +1,66 @@
+/* Copyright (C) 2012, 2013
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* This file is part of the vtable verification feature (for a
+ detailed description of the feature, see comments in
+ vtable-verify.c). The vtable verification feature creates
+ certain global symbols that need to be read-write sometimes during
+ program execution, and read-only at others. It uses 'mprotect' to
+ change the memory protections of the pages on which these variables
+ are stored. In order to not affect the protections of other
+ program variables, these variables are put into a special named
+ section, ".vtable_map_vars", which is page-aligned at the start,
+ and which is padded with a page-sized amount of zeros at the end.
+ To make this section page aligned, we create a special symbol,
+ "_vtable_map_vars_start" which we make the very first thing that
+ goes into the section. That is defined in vtv_start.c (which
+ contains nothing else). vtv_start.c gest compiled into
+ vtv_start.o, and vtv_start.o gets inserted into the link line
+ immediately after crtbegin.o, if the program is compiled with
+ -fvtable.verify.
+
+ In order to pad the ".vtable_map_vars" section with a page-sized
+ amount of zeros at the end, there is a second symbol,
+ _vtable_map_vars_end. This file defines that symbol (and only this
+ symbol). This second symbol is a page-sized array of chars,
+ zero-filled, and is the very last thing to go into the section.
+ When the GCC driver inserts vtv_start.o into the link line (just
+ after crtbegin.o) it also inserts vtv_end.o into the link line,
+ just before crtend.o. This has the desired effect of making our
+ section page-aligned and page-size paded, ensuring that no other
+ program data lands on our pages. */
+
+
+#include "vtv-change-permission.h"
+
+__attribute__ ((constructor(100))) void
+__VLTprotect (void)
+{
+ __VLTChangePermission (__VLTP_READ_ONLY);
+}
+
+/* Page-sized variable to mark end of .vtable_map_vars section. */
+char _vtable_map_vars_end[VTV_PAGE_SIZE]
+ __attribute__ ((__visibility__ ("protected"), used,
+ section(".vtable_map_vars")));
diff --git a/libgcc/vtv_end_preinit.c b/libgcc/vtv_end_preinit.c
new file mode 100644
index 00000000000..53d12b07ea1
--- /dev/null
+++ b/libgcc/vtv_end_preinit.c
@@ -0,0 +1,71 @@
+/* Copyright (C) 2012, 2013
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* This file is part of the vtable verification feature (for a
+ detailed description of the feature, see comments in
+ vtable-verify.c). The vtable verification feature creates
+ certain global symbols that need to be read-write sometimes during
+ program execution, and read-only at others. It uses 'mprotect' to
+ change the memory protections of the pages on which these variables
+ are stored. In order to not affect the protections of other
+ program variables, these variables are put into a special named
+ section, ".vtable_map_vars", which is page-aligned at the start,
+ and which is padded with a page-sized amount of zeros at the end.
+ To make this section page aligned, we create a special symbol,
+ "_vtable_map_vars_start" which we make the very first thing that
+ goes into the section. That is defined in vtv_start.c (which
+ contains nothing else). vtv_start.c gest compiled into
+ vtv_start.o, and vtv_start.o gets inserted into the link line
+ immediately after crtbegin.o, if the program is compiled with
+ -fvtable.verify.
+
+ In order to pad the ".vtable_map_vars" section with a page-sized
+ amount of zeros at the end, there is a second symbol,
+ _vtable_map_vars_end. This file defines that symbol (and only this
+ symbol). This second symbol is a page-sized array of chars,
+ zero-filled, and is the very last thing to go into the section.
+ When the GCC driver inserts vtv_start.o into the link line (just
+ after crtbegin.o) it also inserts vtv_end.o into the link line,
+ just before crtend.o. This has the desired effect of making our
+ section page-aligned and page-size paded, ensuring that no other
+ program data lands on our pages. */
+
+#include "vtv-change-permission.h"
+
+void
+__VLTProtectPreinit (void)
+{
+ __VLTChangePermission (__VLTP_READ_ONLY);
+}
+
+/* Page-sized variable to mark end of .vtable_map_vars section. */
+char _vtable_map_vars_end[VTV_PAGE_SIZE]
+ __attribute__ ((__visibility__ ("protected"), used,
+ section(".vtable_map_vars")));
+
+/* Put the function __VLTProtectPreinit into the .preinit_array
+ section. */
+
+__attribute__ ((section (".preinit_array")))
+ typeof (__VLTProtectPreinit) *__preinit_end = __VLTProtectPreinit;
diff --git a/libgcc/vtv_start.c b/libgcc/vtv_start.c
new file mode 100644
index 00000000000..3efb63dfbb0
--- /dev/null
+++ b/libgcc/vtv_start.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 2012, 2013
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* This file is part of the vtable verification feature (for a
+ detailed description of the feature, see comments in
+ vtable-verify.c). The vtable verification feature creates
+ certain global symbols that need to be read-write sometimes during
+ program execution, and read-only at others. It uses 'mprotect' to
+ change the memory protections of the pages on which these variables
+ are stored. In order to not affect the protections of other
+ program variables, these variables are put into a special named
+ section, ".vtable_map_vars", which is page-aligned at the start,
+ and which is padded with a page-sized amount of zeros at the end.
+ To make this section page aligned, we create a special symbol,
+ "_vtable_map_vars_start" which we make the very first thing that
+ goes into the section. This file defines that symbol (and only
+ that symbol). GCC compiles this file into vtv_start.o, and
+ inserts vtv_start.o into the link line immediately after
+ crtbegin.o, if the program is compiled with -fvtable.verify.
+
+ In order to pad the ".vtable_map_vars" section with a page-sized
+ amount of zeros at the end, there is a second symbol,
+ _vtable_map_vars_end, which is defined in another file, vtv_end.c.
+ This second symbol is a page-sized array of chars, zero-filled, and
+ is the very last thing to go into the section. When the GCC driver
+ inserts vtv_start.o into the link line (just after crtbegin.o) it
+ also inserts vtv_end.o into the link line, just before crtend.o.
+ This has the desired effect of making our section page-aligned and
+ page-size paded, ensuring that no other program data lands on our
+ pages. */
+
+#include "vtv-change-permission.h"
+
+__attribute__ ((constructor(98))) void
+__VLTunprotect (void)
+{
+ __VLTChangePermission (__VLTP_READ_WRITE);
+}
+
+/* Page-aligned symbol to mark beginning of .vtable_map_vars section. */
+char _vtable_map_vars_start []
+__attribute__ ((__visibility__ ("protected"), used, aligned(VTV_PAGE_SIZE),
+ section(".vtable_map_vars")))
+ = { };
diff --git a/libgcc/vtv_start_preinit.c b/libgcc/vtv_start_preinit.c
new file mode 100644
index 00000000000..512c8581a28
--- /dev/null
+++ b/libgcc/vtv_start_preinit.c
@@ -0,0 +1,73 @@
+/* Copyright (C) 2012, 2013
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+/* This file is part of the vtable verification feature (for a
+ detailed description of the feature, see comments in
+ vtable-verify.c). The vtable verification feature creates
+ certain global symbols that need to be read-write sometimes during
+ program execution, and read-only at others. It uses 'mprotect' to
+ change the memory protections of the pages on which these variables
+ are stored. In order to not affect the protections of other
+ program variables, these variables are put into a special named
+ section, ".vtable_map_vars", which is page-aligned at the start,
+ and which is padded with a page-sized amount of zeros at the end.
+ To make this section page aligned, we create a special symbol,
+ "_vtable_map_vars_start" which we make the very first thing that
+ goes into the section. This file defines that symbol (and only
+ that symbol). GCC compiles this file into vtv_start.o, and
+ inserts vtv_start.o into the link line immediately after
+ crtbegin.o, if the program is compiled with -fvtable.verify.
+
+ In order to pad the ".vtable_map_vars" section with a page-sized
+ amount of zeros at the end, there is a second symbol,
+ _vtable_map_vars_end, which is defined in another file, vtv_end.c.
+ This second symbol is a page-sized array of chars, zero-filled, and
+ is the very last thing to go into the section. When the GCC driver
+ inserts vtv_start.o into the link line (just after crtbegin.o) it
+ also inserts vtv_end.o into the link line, just before crtend.o.
+ This has the desired effect of making our section page-aligned and
+ page-size paded, ensuring that no other program data lands on our
+ pages. */
+
+#include "vtv-change-permission.h"
+
+void
+__VLTUnprotectPreinit (void)
+{
+ __VLTChangePermission (__VLTP_READ_WRITE);
+}
+
+/* Page-aligned symbol to mark beginning of .vtable_map_vars section. */
+char _vtable_map_vars_start []
+__attribute__ ((__visibility__ ("protected"), used, aligned(VTV_PAGE_SIZE),
+ section(".vtable_map_vars")))
+ = { };
+
+
+/* Put the function __VLTUnprotectPreinit into the .preinit_array
+ section. */
+
+__attribute__ ((section (".preinit_array")))
+ typeof (__VLTUnprotectPreinit) *__preinit = __VLTUnprotectPreinit;
+
diff --git a/libgo/config/libtool.m4 b/libgo/config/libtool.m4
index 1a667d31a5a..a8321ede5a8 100644
--- a/libgo/config/libtool.m4
+++ b/libgo/config/libtool.m4
@@ -1225,7 +1225,7 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
@@ -1239,7 +1239,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_i386"
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -1258,7 +1261,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
diff --git a/libgo/configure b/libgo/configure
index 5c943ff5589..a1e045cb625 100755
--- a/libgo/configure
+++ b/libgo/configure
@@ -6501,7 +6501,7 @@ ia64-*-hpux*)
rm -rf conftest*
;;
-x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \
s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
# Find out which ABI we are using.
echo 'int i;' > conftest.$ac_ext
@@ -6519,7 +6519,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_i386"
;;
- ppc64-*linux*|powerpc64-*linux*)
+ powerpc64le-*)
+ LD="${LD-ld} -m elf32lppclinux"
+ ;;
+ powerpc64-*)
LD="${LD-ld} -m elf32ppclinux"
;;
s390x-*linux*)
@@ -6538,7 +6541,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
x86_64-*linux*)
LD="${LD-ld} -m elf_x86_64"
;;
- ppc*-*linux*|powerpc*-*linux*)
+ powerpcle-*)
+ LD="${LD-ld} -m elf64lppc"
+ ;;
+ powerpc-*)
LD="${LD-ld} -m elf64ppc"
;;
s390*-*linux*|s390*-*tpf*)
@@ -11105,7 +11111,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11108 "configure"
+#line 11114 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11211,7 +11217,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11214 "configure"
+#line 11220 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/libgo/go/net/cgo_unix.go b/libgo/go/net/cgo_unix.go
index a4d96a86d12..ce54d827c8e 100644
--- a/libgo/go/net/cgo_unix.go
+++ b/libgo/go/net/cgo_unix.go
@@ -103,6 +103,7 @@ func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err error, complet
var hints syscall.Addrinfo
hints.Ai_flags = int32(cgoAddrInfoFlags())
+ hints.Ai_socktype = syscall.SOCK_STREAM
h := syscall.StringBytePtr(name)
syscall.Entersyscall()
@@ -130,7 +131,7 @@ func cgoLookupIPCNAME(name string) (addrs []IP, cname string, err error, complet
}
}
for r := res; r != nil; r = r.Ai_next {
- // Everything comes back twice, once for UDP and once for TCP.
+ // We only asked for SOCK_STREAM, but check anyhow.
if r.Ai_socktype != syscall.SOCK_STREAM {
continue
}
diff --git a/libgo/go/reflect/value.go b/libgo/go/reflect/value.go
index 6bf66c8caf6..45a08587973 100644
--- a/libgo/go/reflect/value.go
+++ b/libgo/go/reflect/value.go
@@ -434,9 +434,6 @@ func (v Value) call(op string, in []Value) []Value {
nin++
}
firstPointer := len(in) > 0 && Kind(t.In(0).(*rtype).kind) != Ptr && v.flag&flagMethod == 0 && isMethod(v.typ)
- if v.flag&flagMethod == 0 && !firstPointer {
- nin++
- }
params := make([]unsafe.Pointer, nin)
off := 0
if v.flag&flagMethod != 0 {
@@ -464,10 +461,6 @@ func (v Value) call(op string, in []Value) []Value {
}
off++
}
- if v.flag&flagMethod == 0 && !firstPointer {
- // Closure argument.
- params[off] = unsafe.Pointer(&fn)
- }
ret := make([]Value, nout)
results := make([]unsafe.Pointer, nout)
diff --git a/libgo/go/syscall/mksyscall.awk b/libgo/go/syscall/mksyscall.awk
index 74f0e28af4d..daf6554a6cd 100644
--- a/libgo/go/syscall/mksyscall.awk
+++ b/libgo/go/syscall/mksyscall.awk
@@ -53,7 +53,7 @@ BEGIN {
}
# Sets a[1] = //sysnb, a[2] == function name.
- split(line, a, "[ (]*")
+ split(line, a, "[ (]+")
gofnname = a[2]
off = match(line, "\\([^()]*\\)")
@@ -78,7 +78,7 @@ BEGIN {
next
}
- split(line, a, "[ (]*")
+ split(line, a, "[ (]+")
cfnname = substr(a[1], 3, length(a[1]) - 2)
off = match(line, "\\([^()]*\\)")
diff --git a/libgo/runtime/go-reflect-call.c b/libgo/runtime/go-reflect-call.c
index 83b9eba0436..5cf370798bf 100644
--- a/libgo/runtime/go-reflect-call.c
+++ b/libgo/runtime/go-reflect-call.c
@@ -302,9 +302,7 @@ go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
in_types = ((const struct __go_type_descriptor **)
func->__in.__values);
- num_args = (num_params
- + (is_interface ? 1 : 0)
- + (!is_interface && !is_method ? 1 : 0));
+ num_args = num_params + (is_interface ? 1 : 0);
args = (ffi_type **) __go_alloc (num_args * sizeof (ffi_type *));
i = 0;
off = 0;
@@ -321,12 +319,6 @@ go_func_to_cif (const struct __go_func_type *func, _Bool is_interface,
for (; i < num_params; ++i)
args[i + off] = go_type_to_ffi (in_types[i]);
- if (!is_interface && !is_method)
- {
- // There is a closure argument, a pointer.
- args[i + off] = &ffi_type_pointer;
- }
-
rettype = go_func_return_ffi (func);
status = ffi_prep_cif (cif, FFI_DEFAULT_ABI, num_args, rettype, args);
@@ -511,9 +503,8 @@ go_set_results (const struct __go_func_type *func, unsigned char *call_result,
regardless of FUNC_TYPE, it is passed as a pointer.
If neither IS_INTERFACE nor IS_METHOD is true then we are calling a
- function indirectly, and the caller is responsible for passing a
- trailing closure argument, a pointer, which is not described in
- FUNC_TYPE. */
+ function indirectly, and we must pass a closure pointer via
+ __go_set_closure. The pointer to pass is simply FUNC_VAL. */
void
reflect_call (const struct __go_func_type *func_type, FuncVal *func_val,
@@ -528,6 +519,8 @@ reflect_call (const struct __go_func_type *func_type, FuncVal *func_val,
call_result = (unsigned char *) malloc (go_results_size (func_type));
+ if (!is_interface && !is_method)
+ __go_set_closure (func_val);
ffi_call (&cif, func_val->fn, call_result, params);
/* Some day we may need to free result values if RESULTS is
diff --git a/libgo/runtime/mgc0.c b/libgo/runtime/mgc0.c
index 36afd2b964d..c3b32111ca0 100644
--- a/libgo/runtime/mgc0.c
+++ b/libgo/runtime/mgc0.c
@@ -2263,12 +2263,11 @@ runfinq(void* dummy __attribute__ ((unused)))
for(; fb; fb=next) {
next = fb->next;
for(i=0; i<(uint32)fb->cnt; i++) {
- void *params[2];
+ void *param;
f = &fb->fin[i];
- params[0] = &f->arg;
- params[1] = f;
- reflect_call(f->ft, f->fn, 0, 0, params, nil);
+ param = &f->arg;
+ reflect_call(f->ft, f->fn, 0, 0, &param, nil);
f->fn = nil;
f->arg = nil;
}
diff --git a/libgo/runtime/proc.c b/libgo/runtime/proc.c
index d42ff3362ee..0e77a3e0603 100644
--- a/libgo/runtime/proc.c
+++ b/libgo/runtime/proc.c
@@ -2832,3 +2832,23 @@ runtime_proc_scan(void (*addroot)(Obj))
{
addroot((Obj){(byte*)&runtime_sched, sizeof runtime_sched, 0});
}
+
+// When a function calls a closure, it passes the closure value to
+// __go_set_closure immediately before the function call. When a
+// function uses a closure, it calls __go_get_closure immediately on
+// function entry. This is a hack, but it will work on any system.
+// It would be better to use the static chain register when there is
+// one. It is also worth considering expanding these functions
+// directly in the compiler.
+
+void
+__go_set_closure(void* v)
+{
+ g->closure = v;
+}
+
+void *
+__go_get_closure(void)
+{
+ return g->closure;
+}
diff --git a/libgo/runtime/runtime.h b/libgo/runtime/runtime.h
index 78fd388186a..d2e7d4c11bc 100644
--- a/libgo/runtime/runtime.h
+++ b/libgo/runtime/runtime.h
@@ -190,6 +190,7 @@ struct Location
struct G
{
+ void* closure; // Closure value.
Defer* defer;
Panic* panic;
void* exception; // current exception being thrown
@@ -759,3 +760,6 @@ extern void runtime_main(void*);
int32 getproccount(void);
#define PREFETCH(p) __builtin_prefetch(p)
+
+void __go_set_closure(void*);
+void* __go_get_closure(void);
diff --git a/libgo/runtime/time.goc b/libgo/runtime/time.goc
index e06b75ccb3d..8d12fe01080 100644
--- a/libgo/runtime/time.goc
+++ b/libgo/runtime/time.goc
@@ -46,10 +46,9 @@ static void siftdown(int32);
// Ready the goroutine e.data.
static void
-ready(int64 now, Eface e, void *closure)
+ready(int64 now, Eface e)
{
USED(now);
- USED(closure);
runtime_ready(e.__object);
}
@@ -166,7 +165,7 @@ timerproc(void* dummy __attribute__ ((unused)))
{
int64 delta, now;
Timer *t;
- void (*f)(int64, Eface, void *);
+ void (*f)(int64, Eface);
Eface arg;
for(;;) {
@@ -197,7 +196,8 @@ timerproc(void* dummy __attribute__ ((unused)))
runtime_unlock(&timers);
if(raceenabled)
runtime_raceacquire(t);
- f(now, arg, &t->fv);
+ __go_set_closure(t->fv);
+ f(now, arg);
runtime_lock(&timers);
}
if(delta < 0) {
diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog
index 73b5c299575..e4ce0b9a637 100644
--- a/libiberty/ChangeLog
+++ b/libiberty/ChangeLog
@@ -1,3 +1,9 @@
+2013-08-20 Alan Modra <amodra@gmail.com>
+
+ * floatformat.c (floatformat_ibm_long_double): Rename to..
+ (floatformat_ibm_long_double_big): ..this.
+ (floatformat_ibm_long_double_little): New.
+
2013-07-09 Tristan Gingold <gingold@adacore.com>
* makefile.vms (OBJS): Add dwarfnames.obj
diff --git a/libiberty/floatformat.c b/libiberty/floatformat.c
index c58ab01bce2..789fa05777d 100644
--- a/libiberty/floatformat.c
+++ b/libiberty/floatformat.c
@@ -371,14 +371,23 @@ floatformat_ibm_long_double_is_valid (const struct floatformat *fmt,
}
}
-const struct floatformat floatformat_ibm_long_double =
+const struct floatformat floatformat_ibm_long_double_big =
{
floatformat_big, 128, 0, 1, 11, 1023, 2047, 12, 52,
floatformat_intbit_no,
- "floatformat_ibm_long_double",
+ "floatformat_ibm_long_double_big",
floatformat_ibm_long_double_is_valid,
&floatformat_ieee_double_big
};
+
+const struct floatformat floatformat_ibm_long_double_little =
+{
+ floatformat_little, 128, 0, 1, 11, 1023, 2047, 12, 52,
+ floatformat_intbit_no,
+ "floatformat_ibm_long_double_little",
+ floatformat_ibm_long_double_is_valid,
+ &floatformat_ieee_double_little
+};
#ifndef min
diff --git a/libitm/ChangeLog b/libitm/ChangeLog
index 3e9a7067979..adf42308ef3 100644
--- a/libitm/ChangeLog
+++ b/libitm/ChangeLog
@@ -1,3 +1,40 @@
+2013-08-30 Torvald Riegel <triegel@redhat.com>
+
+ * config/posix/rwlock.cc: Fix initialization order.
+
+2013-08-30 Torvald Riegel <triegel@redhat.com>
+
+ * libitm_i.h (gtm_thread): Assign an asm name to serial_lock.
+ (htm_fastpath): Assign an asm name.
+ * libitm.h (_ITM_codeProperties): Add non-ABI flags used by custom
+ HTM fast paths.
+ (_ITM_actions): Likewise.
+ * config/x86/target.h (HTM_CUSTOM_FASTPATH): Enable custom fastpath on
+ x86_64.
+ * config/x86/sjlj.S (_ITM_beginTransaction): Add custom HTM fast path.
+ * config/posix/rwlock.h (gtm_rwlock): Update comments. Move summary
+ field to the start of the structure.
+ * config/linux/rwlock.h (gtm_rwlock): Update comments.
+ * beginend.cc (gtm_thread::begin_transaction): Add retry policy
+ handling for custom HTM fast paths.
+
+2013-08-14 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+ Revert:
+ 2013-08-02 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * configure.tgt: Add -msoft-float to XCFLAGS.
+
+2013-08-02 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * configure.tgt: Add -msoft-float to XCFLAGS.
+
+2013-07-29 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
+
+ * config/s390/target.h (htm_begin, htm_commit, htm_abort)
+ (htm_transaction_active): Enable zEC12 instructions in the
+ assembler.
+ * configure.tgt: Remove -Wa,-march=zEC12 from XCFLAGS.
+
2013-07-17 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* acinclude.m4: Add htm asm check for s390.
diff --git a/libitm/beginend.cc b/libitm/beginend.cc
index a3bf5492153..bd7b19ec844 100644
--- a/libitm/beginend.cc
+++ b/libitm/beginend.cc
@@ -165,7 +165,7 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb)
if (unlikely(prop & pr_undoLogCode))
GTM_fatal("pr_undoLogCode not supported");
-#if defined(USE_HTM_FASTPATH) && !defined(HTM_CUSTOM_FASTPATH)
+#ifdef USE_HTM_FASTPATH
// HTM fastpath. Only chosen in the absence of transaction_cancel to allow
// using an uninstrumented code path.
// The fastpath is enabled only by dispatch_htm's method group, which uses
@@ -187,6 +187,7 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb)
// indeed in serial mode, and HW transactions should never need serial mode
// for any internal changes (e.g., they never abort visibly to the STM code
// and thus do not trigger the standard retry handling).
+#ifndef HTM_CUSTOM_FASTPATH
if (likely(htm_fastpath && (prop & pr_hasNoAbort)))
{
for (uint32_t t = htm_fastpath; t; t--)
@@ -237,6 +238,49 @@ GTM::gtm_thread::begin_transaction (uint32_t prop, const gtm_jmpbuf *jb)
}
}
}
+#else
+ // If we have a custom HTM fastpath in ITM_beginTransaction, we implement
+ // just the retry policy here. We communicate with the custom fastpath
+ // through additional property bits and return codes, and either transfer
+ // control back to the custom fastpath or run the fallback mechanism. The
+ // fastpath synchronization algorithm itself is the same.
+ // pr_HTMRetryableAbort states that a HW transaction started by the custom
+ // HTM fastpath aborted, and that we thus have to decide whether to retry
+ // the fastpath (returning a_tryHTMFastPath) or just proceed with the
+ // fallback method.
+ if (likely(htm_fastpath && (prop & pr_HTMRetryableAbort)))
+ {
+ tx = gtm_thr();
+ if (unlikely(tx == NULL))
+ {
+ // See below.
+ tx = new gtm_thread();
+ set_gtm_thr(tx);
+ }
+ // If this is the first abort, reset the retry count. We abuse
+ // restart_total for the retry count, which is fine because our only
+ // other fallback will use serial transactions, which don't use
+ // restart_total but will reset it when committing.
+ if (!(prop & pr_HTMRetriedAfterAbort))
+ tx->restart_total = htm_fastpath;
+
+ if (--tx->restart_total > 0)
+ {
+ // Wait until any concurrent serial-mode transactions have finished.
+ // Essentially the same code as above.
+ if (serial_lock.is_write_locked())
+ {
+ if (tx->nesting > 0)
+ goto stop_custom_htm_fastpath;
+ serial_lock.read_lock(tx);
+ serial_lock.read_unlock(tx);
+ }
+ // Let ITM_beginTransaction retry the custom HTM fastpath.
+ return a_tryHTMFastPath;
+ }
+ }
+ stop_custom_htm_fastpath:
+#endif
#endif
tx = gtm_thr();
diff --git a/libitm/config/linux/rwlock.h b/libitm/config/linux/rwlock.h
index 428299f1be8..c761edf0c9c 100644
--- a/libitm/config/linux/rwlock.h
+++ b/libitm/config/linux/rwlock.h
@@ -39,6 +39,11 @@ struct gtm_thread;
//
// In this implementation, writers are given highest priority access but
// read-to-write upgrades do not have a higher priority than writers.
+//
+// Do not change the layout of this class; it must remain a POD type with
+// standard layout, and the WRITERS field must be first (i.e., so the
+// assembler code can assume that its address is equal to the address of the
+// respective instance of the class).
class gtm_rwlock
{
diff --git a/libitm/config/posix/rwlock.cc b/libitm/config/posix/rwlock.cc
index 488e9c2374c..61b6ad9cbd1 100644
--- a/libitm/config/posix/rwlock.cc
+++ b/libitm/config/posix/rwlock.cc
@@ -30,11 +30,11 @@ namespace GTM HIDDEN {
// ??? Move this back to the header file when constexpr is implemented.
gtm_rwlock::gtm_rwlock()
- : mutex (PTHREAD_MUTEX_INITIALIZER),
+ : summary (0),
+ mutex (PTHREAD_MUTEX_INITIALIZER),
c_readers (PTHREAD_COND_INITIALIZER),
c_writers (PTHREAD_COND_INITIALIZER),
c_confirmed_writers (PTHREAD_COND_INITIALIZER),
- summary (0),
a_readers (0),
w_readers (0),
w_writers (0)
diff --git a/libitm/config/posix/rwlock.h b/libitm/config/posix/rwlock.h
index 2e415286aeb..b2fd517b642 100644
--- a/libitm/config/posix/rwlock.h
+++ b/libitm/config/posix/rwlock.h
@@ -44,19 +44,25 @@ struct gtm_thread;
//
// In this implementation, writers are given highest priority access but
// read-to-write upgrades do not have a higher priority than writers.
+//
+// Do not change the layout of this class; it must remain a POD type with
+// standard layout, and the SUMMARY field must be first (i.e., so the
+// assembler code can assume that its address is equal to the address of the
+// respective instance of the class).
class gtm_rwlock
{
- pthread_mutex_t mutex; // Held if manipulating any field.
- pthread_cond_t c_readers; // Readers wait here
- pthread_cond_t c_writers; // Writers wait here for writers
- pthread_cond_t c_confirmed_writers; // Writers wait here for readers
-
static const unsigned a_writer = 1; // An active writer.
static const unsigned w_writer = 2; // The w_writers field != 0
static const unsigned w_reader = 4; // The w_readers field != 0
std::atomic<unsigned int> summary; // Bitmask of the above.
+
+ pthread_mutex_t mutex; // Held if manipulating any field.
+ pthread_cond_t c_readers; // Readers wait here
+ pthread_cond_t c_writers; // Writers wait here for writers
+ pthread_cond_t c_confirmed_writers; // Writers wait here for readers
+
unsigned int a_readers; // Nr active readers as observed by a writer
unsigned int w_readers; // Nr waiting readers
unsigned int w_writers; // Nr waiting writers
diff --git a/libitm/config/s390/target.h b/libitm/config/s390/target.h
index 17228f844dd..cec49cf7774 100644
--- a/libitm/config/s390/target.h
+++ b/libitm/config/s390/target.h
@@ -85,6 +85,7 @@ htm_init ()
static inline uint32_t
htm_begin ()
{
+ __asm volatile (".machine \"all\" \n\t");
return __builtin_tbegin_nofloat (NULL);
}
@@ -97,12 +98,14 @@ htm_begin_success (uint32_t begin_ret)
static inline void
htm_commit ()
{
+ __asm volatile (".machine \"all\" \n\t");
__builtin_tend ();
}
static inline void
htm_abort ()
{
+ __asm volatile (".machine \"all\" \n\t");
__builtin_tabort (_HTM_FIRST_USER_ABORT_CODE);
}
@@ -115,6 +118,7 @@ htm_abort_should_retry (uint32_t begin_ret)
static inline bool
htm_transaction_active ()
{
+ __asm volatile (".machine \"all\" \n\t");
return __builtin_tx_nesting_depth() != 0;
}
diff --git a/libitm/config/x86/sjlj.S b/libitm/config/x86/sjlj.S
index 993f698652c..437551bcd69 100644
--- a/libitm/config/x86/sjlj.S
+++ b/libitm/config/x86/sjlj.S
@@ -24,6 +24,7 @@
#include "asmcfi.h"
+#include "config.h"
#define CONCAT1(a, b) CONCAT2(a, b)
#define CONCAT2(a, b) a ## b
@@ -52,6 +53,19 @@
# endif
#endif
+/* These are duplicates of the canonical definitions in libitm.h. Note that
+ the code relies on pr_uninstrumentedCode == a_runUninstrumentedCode. */
+#define pr_uninstrumentedCode 0x02
+#define pr_hasNoAbort 0x08
+#define pr_HTMRetryableAbort 0x800000
+#define pr_HTMRetriedAfterAbort 0x1000000
+#define a_runInstrumentedCode 0x01
+#define a_runUninstrumentedCode 0x02
+#define a_tryHTMFastPath 0x20
+
+#define _XABORT_EXPLICIT (1 << 0)
+#define _XABORT_RETRY (1 << 1)
+
.text
.align 4
@@ -60,20 +74,83 @@
SYM(_ITM_beginTransaction):
cfi_startproc
#ifdef __x86_64__
+#ifdef HAVE_AS_RTM
+ /* Custom HTM fast path. We start the HW transaction here and let
+ gtm_thread::begin_transaction (aka GTM_begin_transaction) decide
+ how to proceed on aborts: We either retry the fast path, or fall
+ back to another execution method. RTM restores all registers after
+ a HW transaction abort, so we can do the SW setjmp after aborts,
+ and we have to because we might choose a SW fall back. However,
+ we have to explicitly save/restore the first argument (edi). */
+ cmpl $0, SYM(gtm_htm_fastpath)(%rip)
+ jz .Lno_htm
+ testl $pr_hasNoAbort, %edi
+ jz .Lno_htm
+.Lhtm_fastpath:
+ xbegin .Ltxn_abort
+ /* Monitor the serial lock (specifically, the 32b writer/summary field
+ at its start), and only continue if there is no serial-mode
+ transaction. Note that we might be just a nested transaction and
+ our outermost transaction might be in serial mode; we check for
+ this case in the retry policy implementation. */
+ cmpl $0, SYM(gtm_serial_lock)(%rip)
+ jnz 1f
+ /* Everything is good. Run the transaction, preferably using the
+ uninstrumented code path. Note that the following works because
+ pr_uninstrumentedCode == a_runUninstrumentedCode. */
+ andl $pr_uninstrumentedCode, %edi
+ mov $a_runInstrumentedCode, %eax
+ cmovnz %edi, %eax
+ ret
+ /* There is a serial-mode transaction, so abort (see htm_abort()
+ regarding the abort code). */
+1: xabort $0xff
+.Ltxn_abort:
+ /* If it might make sense to retry the HTM fast path, let the C++
+ code decide. */
+ testl $(_XABORT_RETRY|_XABORT_EXPLICIT), %eax
+ jz .Lno_htm
+ orl $pr_HTMRetryableAbort, %edi
+ /* Let the C++ code handle the retry policy. */
+.Lno_htm:
+#endif
leaq 8(%rsp), %rax
- subq $56, %rsp
- cfi_def_cfa_offset(64)
- movq %rax, (%rsp)
- movq %rbx, 8(%rsp)
- movq %rbp, 16(%rsp)
- movq %r12, 24(%rsp)
- movq %r13, 32(%rsp)
- movq %r14, 40(%rsp)
- movq %r15, 48(%rsp)
- movq %rsp, %rsi
+ subq $72, %rsp
+ cfi_adjust_cfa_offset(72)
+ /* Store edi for future HTM fast path retries. We use a stack slot
+ lower than the jmpbuf so that the jmpbuf's rip field will overlap
+ with the proper return address on the stack. */
+ movl %edi, 8(%rsp)
+ /* Save the jmpbuf for any non-HTM-fastpath execution method.
+ Because rsp-based addressing is 1 byte larger and we've got rax
+ handy, use it. */
+ movq %rax, -64(%rax)
+ movq %rbx, -56(%rax)
+ movq %rbp, -48(%rax)
+ movq %r12, -40(%rax)
+ movq %r13, -32(%rax)
+ movq %r14, -24(%rax)
+ movq %r15, -16(%rax)
+ leaq -64(%rax), %rsi
call SYM(GTM_begin_transaction)
- addq $56, %rsp
- cfi_def_cfa_offset(8)
+ movl 8(%rsp), %edi
+ addq $72, %rsp
+ cfi_adjust_cfa_offset(-72)
+#ifdef HAVE_AS_RTM
+ /* If a_tryHTMFastPath was returned, then we need to retry the
+ fast path. We also restore edi and set pr_HTMRetriedAfterAbort
+ to state that we have retried the fast path already (it's harmless
+ if this bit is set even if we don't retry the fast path because it
+ is checked iff pr_HTMRetryableAbort is set). We clear
+ pr_HTMRetryableAbort because it applies to a previous HW
+ transaction attempt. */
+ cmpl $a_tryHTMFastPath, %eax
+ jnz 2f
+ andl $(0xffffffff-pr_HTMRetryableAbort), %edi
+ orl $pr_HTMRetriedAfterAbort, %edi
+ jmp .Lhtm_fastpath
+2:
+#endif
#else
leal 4(%esp), %ecx
movl 4(%esp), %eax
diff --git a/libitm/config/x86/target.h b/libitm/config/x86/target.h
index 063c09ed974..65efb31324e 100644
--- a/libitm/config/x86/target.h
+++ b/libitm/config/x86/target.h
@@ -70,6 +70,10 @@ cpu_relax (void)
// See gtm_thread::begin_transaction for how these functions are used.
#ifdef HAVE_AS_RTM
#define USE_HTM_FASTPATH
+#ifdef __x86_64__
+// Use the custom fastpath in ITM_beginTransaction.
+#define HTM_CUSTOM_FASTPATH
+#endif
static inline bool
htm_available ()
diff --git a/libitm/configure.tgt b/libitm/configure.tgt
index 4dc2807cfe5..5078455975c 100644
--- a/libitm/configure.tgt
+++ b/libitm/configure.tgt
@@ -109,7 +109,7 @@ case "${target_cpu}" in
ARCH=x86
;;
s390|s390x)
- XCFLAGS="${XCFLAGS} -mzarch -mhtm -Wa,-march=zEC12"
+ XCFLAGS="${XCFLAGS} -mzarch -mhtm"
ARCH=s390
;;
diff --git a/libitm/libitm.h b/libitm/libitm.h
index 20ac59a4474..4bee0a2577e 100644
--- a/libitm/libitm.h
+++ b/libitm/libitm.h
@@ -72,7 +72,9 @@ typedef enum
inIrrevocableTransaction
} _ITM_howExecuting;
-/* Values to describe properties of code, passed in to beginTransaction */
+/* Values to describe properties of code, passed in to beginTransaction.
+ Some of these constants are duplicated in some of the ITM_beginTransaction
+ implementations, so update those too when applying any changes. */
typedef enum
{
pr_instrumentedCode = 0x0001,
@@ -95,10 +97,16 @@ typedef enum
pr_exceptionBlock = 0x1000,
pr_hasElse = 0x2000,
pr_readOnly = 0x4000,
- pr_hasNoSimpleReads = 0x400000
+ pr_hasNoSimpleReads = 0x400000,
+ /* These are not part of the ABI but used for custom HTM fast paths. See
+ ITM_beginTransaction and gtm_thread::begin_transaction. */
+ pr_HTMRetryableAbort = 0x800000,
+ pr_HTMRetriedAfterAbort = 0x1000000
} _ITM_codeProperties;
-/* Result from startTransaction that describes what actions to take. */
+/* Result from startTransaction that describes what actions to take.
+ Some of these constants are duplicated in some of the ITM_beginTransaction
+ implementations, so update those too when applying any changes. */
typedef enum
{
a_runInstrumentedCode = 0x01,
@@ -106,6 +114,7 @@ typedef enum
a_saveLiveVariables = 0x04,
a_restoreLiveVariables = 0x08,
a_abortTransaction = 0x10,
+ a_tryHTMFastPath = 0x20
} _ITM_actions;
typedef struct
diff --git a/libitm/libitm_i.h b/libitm/libitm_i.h
index 421b349cfe5..e965caf839c 100644
--- a/libitm/libitm_i.h
+++ b/libitm/libitm_i.h
@@ -87,6 +87,14 @@ enum gtm_restart_reason
#include "dispatch.h"
#include "containers.h"
+#ifdef __USER_LABEL_PREFIX__
+# define UPFX UPFX1(__USER_LABEL_PREFIX__)
+# define UPFX1(t) UPFX2(t)
+# define UPFX2(t) #t
+#else
+# define UPFX
+#endif
+
namespace GTM HIDDEN {
// This type is private to alloc.c, but needs to be defined so that
@@ -230,6 +238,7 @@ struct gtm_thread
// be used for the next iteration of the transaction.
// Only restart_total is reset to zero when the transaction commits, the
// other counters are total values for all previously executed transactions.
+ // restart_total is also used by the HTM fastpath in a different way.
uint32_t restart_reason[NUM_RESTARTS];
uint32_t restart_total;
@@ -247,7 +256,9 @@ struct gtm_thread
// The lock that provides access to serial mode. Non-serialized
// transactions acquire read locks; a serialized transaction aquires
// a write lock.
- static gtm_rwlock serial_lock;
+ // Accessed from assembly language, thus the "asm" specifier on
+ // the name, avoiding complex name mangling.
+ static gtm_rwlock serial_lock __asm__(UPFX "gtm_serial_lock");
// The head of the list of all threads' transactions.
static gtm_thread *list_of_threads;
@@ -277,15 +288,8 @@ struct gtm_thread
// Invoked from assembly language, thus the "asm" specifier on
// the name, avoiding complex name mangling.
-#ifdef __USER_LABEL_PREFIX__
-#define UPFX1(t) UPFX(t)
-#define UPFX(t) #t
- static uint32_t begin_transaction(uint32_t, const gtm_jmpbuf *)
- __asm__(UPFX1(__USER_LABEL_PREFIX__) "GTM_begin_transaction") ITM_REGPARM;
-#else
static uint32_t begin_transaction(uint32_t, const gtm_jmpbuf *)
- __asm__("GTM_begin_transaction") ITM_REGPARM;
-#endif
+ __asm__(UPFX "GTM_begin_transaction") ITM_REGPARM;
// In eh_cpp.cc
void revert_cpp_exceptions (gtm_transaction_cp *cp = 0);
@@ -338,7 +342,9 @@ extern gtm_cacheline_mask gtm_mask_stack(gtm_cacheline *, gtm_cacheline_mask);
// Control variable for the HTM fastpath that uses serial mode as fallback.
// Non-zero if the HTM fastpath is enabled. See gtm_thread::begin_transaction.
-extern uint32_t htm_fastpath;
+// Accessed from assembly language, thus the "asm" specifier on
+// the name, avoiding complex name mangling.
+extern uint32_t htm_fastpath __asm__(UPFX "gtm_htm_fastpath");
} // namespace GTM
diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog
index d2c80b35704..f5162c90250 100644
--- a/libsanitizer/ChangeLog
+++ b/libsanitizer/ChangeLog
@@ -1,3 +1,19 @@
+2013-09-01 Iain Sandoe <iain@codesourcery.com>
+
+ * ubsan/Makefile.am (libubsan_la_LIBADD): Revise to omit
+ libinterception.la for Darwin.
+ * ubsan/Makefile.in: Regenerate.
+
+2013-08-30 Jakub Jelinek <jakub@redhat.com>
+
+ * Makefile.am (SUBDIRS): Add ubsan.
+ * configure.ac (AC_CONFIG_FILES): Add ubsan/Makefile.
+ * merge.sh: Merge ubsan.
+ * sanitizer_common/sanitizer_report_decorator.h: Partial merge from trunk.
+ * sanitizer_common/sanitizer_printf.cc: Likewise.
+ * sanitizer_common/sanitizer_common.h: Likewise.
+ * ubsan: New directory. Import ubsan runtime from llvm.
+
2013-06-03 Christophe Lyon <christophe.lyon@linaro.org>
* sanitizer_common/sanitizer_linux.cc (MemoryMappingLayout::Next):
diff --git a/libsanitizer/Makefile.am b/libsanitizer/Makefile.am
index 308d438074a..739c33babbe 100644
--- a/libsanitizer/Makefile.am
+++ b/libsanitizer/Makefile.am
@@ -1,13 +1,13 @@
ACLOCAL_AMFLAGS = -I .. -I ../config
if TSAN_SUPPORTED
-SUBDIRS = interception sanitizer_common asan tsan
+SUBDIRS = interception sanitizer_common asan tsan ubsan
else
-SUBDIRS = interception sanitizer_common asan
+SUBDIRS = interception sanitizer_common asan ubsan
endif
if USING_MAC_INTERPOSE
-SUBDIRS = sanitizer_common asan
+SUBDIRS = sanitizer_common asan ubsan
endif
# Work around what appears to be a GNU make bug handling MAKEFLAGS
diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in
index 7ecfece39f9..fca1c4e0dc3 100644
--- a/libsanitizer/Makefile.in
+++ b/libsanitizer/Makefile.in
@@ -98,7 +98,7 @@ AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
$(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
ETAGS = etags
CTAGS = ctags
-DIST_SUBDIRS = interception sanitizer_common asan tsan
+DIST_SUBDIRS = interception sanitizer_common asan ubsan tsan
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AR = @AR@
@@ -231,9 +231,9 @@ top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
ACLOCAL_AMFLAGS = -I .. -I ../config
-@TSAN_SUPPORTED_FALSE@SUBDIRS = interception sanitizer_common asan
-@TSAN_SUPPORTED_TRUE@SUBDIRS = interception sanitizer_common asan tsan
-@USING_MAC_INTERPOSE_TRUE@SUBDIRS = sanitizer_common asan
+@TSAN_SUPPORTED_FALSE@SUBDIRS = interception sanitizer_common asan ubsan
+@TSAN_SUPPORTED_TRUE@SUBDIRS = interception sanitizer_common asan tsan ubsan
+@USING_MAC_INTERPOSE_TRUE@SUBDIRS = sanitizer_common asan ubsan
# Work around what appears to be a GNU make bug handling MAKEFLAGS
# values defined in terms of make variables, as is the case for CC and
diff --git a/libsanitizer/configure b/libsanitizer/configure
index 4bdef4fc18f..4080d7a1c95 100755
--- a/libsanitizer/configure
+++ b/libsanitizer/configure
@@ -14548,7 +14548,7 @@ fi
ac_config_files="$ac_config_files Makefile"
-ac_config_files="$ac_config_files interception/Makefile sanitizer_common/Makefile asan/Makefile"
+ac_config_files="$ac_config_files interception/Makefile sanitizer_common/Makefile asan/Makefile ubsan/Makefile"
if test "x$TSAN_SUPPORTED" = "xyes"; then
@@ -15679,6 +15679,7 @@ do
"interception/Makefile") CONFIG_FILES="$CONFIG_FILES interception/Makefile" ;;
"sanitizer_common/Makefile") CONFIG_FILES="$CONFIG_FILES sanitizer_common/Makefile" ;;
"asan/Makefile") CONFIG_FILES="$CONFIG_FILES asan/Makefile" ;;
+ "ubsan/Makefile") CONFIG_FILES="$CONFIG_FILES ubsan/Makefile" ;;
"tsan/Makefile") CONFIG_FILES="$CONFIG_FILES tsan/Makefile" ;;
*) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
@@ -17044,6 +17045,17 @@ _EOF
. ${multi_basedir}/config-ml.in
{ ml_norecursion=; unset ml_norecursion;}
;;
+ "ubsan/Makefile":F) cat > vpsed$$ << \_EOF
+s!`test -f '$<' || echo '$(srcdir)/'`!!
+_EOF
+ sed -f vpsed$$ $ac_file > tmp$$
+ mv tmp$$ $ac_file
+ rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
+ ;;
"tsan/Makefile":F) cat > vpsed$$ << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
diff --git a/libsanitizer/configure.ac b/libsanitizer/configure.ac
index 3cf161d12de..5919da61304 100644
--- a/libsanitizer/configure.ac
+++ b/libsanitizer/configure.ac
@@ -89,7 +89,7 @@ AM_CONDITIONAL(USING_MAC_INTERPOSE, $MAC_INTERPOSE)
AC_CONFIG_FILES([Makefile])
-AC_CONFIG_FILES(AC_FOREACH([DIR], [interception sanitizer_common asan], [DIR/Makefile ]),
+AC_CONFIG_FILES(AC_FOREACH([DIR], [interception sanitizer_common asan ubsan], [DIR/Makefile ]),
[cat > vpsed$$ << \_EOF
s!`test -f '$<' || echo '$(srcdir)/'`!!
_EOF
diff --git a/libsanitizer/merge.sh b/libsanitizer/merge.sh
index 9c29b319829..23748a701bb 100755
--- a/libsanitizer/merge.sh
+++ b/libsanitizer/merge.sh
@@ -69,6 +69,7 @@ merge lib/asan asan
merge lib/tsan/rtl tsan
merge lib/sanitizer_common sanitizer_common
merge lib/interception interception
+merge lib/ubsan ubsan
rm -rf upstream
diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h
index 302dc742769..d2782b6c9dc 100644
--- a/libsanitizer/sanitizer_common/sanitizer_common.h
+++ b/libsanitizer/sanitizer_common/sanitizer_common.h
@@ -15,6 +15,7 @@
#define SANITIZER_COMMON_H
#include "sanitizer_internal_defs.h"
+#include "sanitizer_mutex.h"
namespace __sanitizer {
struct StackTrace;
@@ -105,6 +106,8 @@ bool PrintsToTty();
void Printf(const char *format, ...);
void Report(const char *format, ...);
void SetPrintfAndReportCallback(void (*callback)(const char *));
+// Can be used to prevent mixing error reports from different sanitizers.
+extern StaticSpinMutex CommonSanitizerReportMutex;
fd_t OpenFile(const char *filename, bool write);
// Opens the file 'file_name" and reads up to 'max_len' bytes.
diff --git a/libsanitizer/sanitizer_common/sanitizer_printf.cc b/libsanitizer/sanitizer_common/sanitizer_printf.cc
index 7771e1d34a1..8298f12bd7b 100644
--- a/libsanitizer/sanitizer_common/sanitizer_printf.cc
+++ b/libsanitizer/sanitizer_common/sanitizer_printf.cc
@@ -21,6 +21,8 @@
namespace __sanitizer {
+StaticSpinMutex CommonSanitizerReportMutex;
+
static int AppendChar(char **buff, const char *buff_end, char c) {
if (*buff < buff_end) {
**buff = c;
diff --git a/libsanitizer/sanitizer_common/sanitizer_report_decorator.h b/libsanitizer/sanitizer_common/sanitizer_report_decorator.h
index 17f0b2edd2f..cabf08e6082 100644
--- a/libsanitizer/sanitizer_common/sanitizer_report_decorator.h
+++ b/libsanitizer/sanitizer_common/sanitizer_report_decorator.h
@@ -12,24 +12,26 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SANITIZER_ALLOCATOR_H
-#define SANITIZER_ALLOCATOR_H
+#ifndef SANITIZER_REPORT_DECORATOR_H
+#define SANITIZER_REPORT_DECORATOR_H
namespace __sanitizer {
class AnsiColorDecorator {
public:
explicit AnsiColorDecorator(bool use_ansi_colors) : ansi_(use_ansi_colors) { }
- const char *Black() { return ansi_ ? "\033[1m\033[30m" : ""; }
- const char *Red() { return ansi_ ? "\033[1m\033[31m" : ""; }
- const char *Green() { return ansi_ ? "\033[1m\033[32m" : ""; }
- const char *Yellow() { return ansi_ ? "\033[1m\033[33m" : ""; }
- const char *Blue() { return ansi_ ? "\033[1m\033[34m" : ""; }
- const char *Magenta() { return ansi_ ? "\033[1m\033[35m" : ""; }
- const char *Cyan() { return ansi_ ? "\033[1m\033[36m" : ""; }
- const char *White() { return ansi_ ? "\033[1m\033[37m" : ""; }
- const char *Default() { return ansi_ ? "\033[1m\033[0m" : ""; }
+ const char *Bold() const { return ansi_ ? "\033[1m" : ""; }
+ const char *Black() const { return ansi_ ? "\033[1m\033[30m" : ""; }
+ const char *Red() const { return ansi_ ? "\033[1m\033[31m" : ""; }
+ const char *Green() const { return ansi_ ? "\033[1m\033[32m" : ""; }
+ const char *Yellow() const { return ansi_ ? "\033[1m\033[33m" : ""; }
+ const char *Blue() const { return ansi_ ? "\033[1m\033[34m" : ""; }
+ const char *Magenta() const { return ansi_ ? "\033[1m\033[35m" : ""; }
+ const char *Cyan() const { return ansi_ ? "\033[1m\033[36m" : ""; }
+ const char *White() const { return ansi_ ? "\033[1m\033[37m" : ""; }
+ const char *Default() const { return ansi_ ? "\033[1m\033[0m" : ""; }
private:
bool ansi_;
};
} // namespace __sanitizer
-#endif // SANITIZER_ALLOCATOR_H
+
+#endif // SANITIZER_REPORT_DECORATOR_H
diff --git a/libsanitizer/ubsan/Makefile.am b/libsanitizer/ubsan/Makefile.am
new file mode 100644
index 00000000000..e98984a757b
--- /dev/null
+++ b/libsanitizer/ubsan/Makefile.am
@@ -0,0 +1,69 @@
+AM_CPPFLAGS = -I $(top_srcdir) -I $(top_srcdir)/include
+
+# May be used by toolexeclibdir.
+gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
+
+DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
+AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic -Wno-long-long -fPIC -fno-builtin -fno-exceptions -fomit-frame-pointer -funwind-tables -fvisibility=hidden -Wno-variadic-macros
+AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
+ACLOCAL_AMFLAGS = -I m4
+
+toolexeclib_LTLIBRARIES = libubsan.la
+
+ubsan_files = \
+ ubsan_diag.cc \
+ ubsan_handlers.cc \
+ ubsan_handlers_cxx.cc \
+ ubsan_type_hash.cc \
+ ubsan_value.cc
+
+libubsan_la_SOURCES = $(ubsan_files)
+libubsan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la
+if !USING_MAC_INTERPOSE
+libubsan_la_LIBADD += $(top_builddir)/interception/libinterception.la
+endif
+libubsan_la_LIBADD += $(LIBSTDCXX_RAW_CXX_LDFLAGS)
+libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "JC1FLAGS=$(JC1FLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "includedir=$(includedir)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES=
+
+## ################################################################
+
diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in
new file mode 100644
index 00000000000..68125387540
--- /dev/null
+++ b/libsanitizer/ubsan/Makefile.in
@@ -0,0 +1,580 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+@USING_MAC_INTERPOSE_FALSE@am__append_1 = $(top_builddir)/interception/libinterception.la
+subdir = ubsan
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/depstand.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/libstdc++-raw-cxx.m4 \
+ $(top_srcdir)/../config/multi.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(toolexeclibdir)"
+LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
+am__DEPENDENCIES_1 =
+libubsan_la_DEPENDENCIES = \
+ $(top_builddir)/sanitizer_common/libsanitizer_common.la \
+ $(am__append_1) $(am__DEPENDENCIES_1)
+am__objects_1 = ubsan_diag.lo ubsan_handlers.lo ubsan_handlers_cxx.lo \
+ ubsan_type_hash.lo ubsan_value.lo
+am_libubsan_la_OBJECTS = $(am__objects_1)
+libubsan_la_OBJECTS = $(am_libubsan_la_OBJECTS)
+libubsan_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
+ $(CXXFLAGS) $(libubsan_la_LDFLAGS) $(LDFLAGS) -o $@
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(libubsan_la_SOURCES)
+ETAGS = etags
+CTAGS = ctags
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASDEPMODE = @CCASDEPMODE@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX_RAW_CXX_CXXFLAGS = @LIBSTDCXX_RAW_CXX_CXXFLAGS@
+LIBSTDCXX_RAW_CXX_LDFLAGS = @LIBSTDCXX_RAW_CXX_LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+multi_basedir = @multi_basedir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_noncanonical = @target_noncanonical@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+AM_CPPFLAGS = -I $(top_srcdir) -I $(top_srcdir)/include
+
+# May be used by toolexeclibdir.
+gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
+AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \
+ -Wno-long-long -fPIC -fno-builtin -fno-exceptions \
+ -fomit-frame-pointer -funwind-tables -fvisibility=hidden \
+ -Wno-variadic-macros $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
+ACLOCAL_AMFLAGS = -I m4
+toolexeclib_LTLIBRARIES = libubsan.la
+ubsan_files = \
+ ubsan_diag.cc \
+ ubsan_handlers.cc \
+ ubsan_handlers_cxx.cc \
+ ubsan_type_hash.cc \
+ ubsan_value.cc
+
+libubsan_la_SOURCES = $(ubsan_files)
+libubsan_la_LIBADD = \
+ $(top_builddir)/sanitizer_common/libsanitizer_common.la \
+ $(am__append_1) $(LIBSTDCXX_RAW_CXX_LDFLAGS)
+libubsan_la_LDFLAGS = -version-info `grep -v '^\#' $(srcdir)/libtool-version` -lpthread -ldl
+
+# Work around what appears to be a GNU make bug handling MAKEFLAGS
+# values defined in terms of make variables, as is the case for CC and
+# friends when we are called from the top level Makefile.
+AM_MAKEFLAGS = \
+ "AR_FLAGS=$(AR_FLAGS)" \
+ "CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+ "CFLAGS=$(CFLAGS)" \
+ "CXXFLAGS=$(CXXFLAGS)" \
+ "CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+ "CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+ "INSTALL=$(INSTALL)" \
+ "INSTALL_DATA=$(INSTALL_DATA)" \
+ "INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+ "INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+ "JC1FLAGS=$(JC1FLAGS)" \
+ "LDFLAGS=$(LDFLAGS)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+ "MAKE=$(MAKE)" \
+ "MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+ "PICFLAG=$(PICFLAG)" \
+ "PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+ "SHELL=$(SHELL)" \
+ "RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+ "exec_prefix=$(exec_prefix)" \
+ "infodir=$(infodir)" \
+ "libdir=$(libdir)" \
+ "prefix=$(prefix)" \
+ "includedir=$(includedir)" \
+ "AR=$(AR)" \
+ "AS=$(AS)" \
+ "LD=$(LD)" \
+ "LIBCFLAGS=$(LIBCFLAGS)" \
+ "NM=$(NM)" \
+ "PICFLAG=$(PICFLAG)" \
+ "RANLIB=$(RANLIB)" \
+ "DESTDIR=$(DESTDIR)"
+
+MAKEOVERRIDES =
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .cc .lo .o .obj
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ubsan/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign ubsan/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
+ @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \
+ }
+
+uninstall-toolexeclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \
+ done
+
+clean-toolexeclibLTLIBRARIES:
+ -test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES)
+ @list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libubsan.la: $(libubsan_la_OBJECTS) $(libubsan_la_DEPENDENCIES)
+ $(libubsan_la_LINK) -rpath $(toolexeclibdir) $(libubsan_la_OBJECTS) $(libubsan_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_diag.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_handlers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_handlers_cxx.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_type_hash.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_value.Plo@am__quote@
+
+.cc.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+check-am: all-am
+check: check-am
+all-am: Makefile $(LTLIBRARIES)
+installdirs:
+ for dir in "$(DESTDIR)$(toolexeclibdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am: install-toolexeclibLTLIBRARIES
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-toolexeclibLTLIBRARIES
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
+ clean-libtool clean-toolexeclibLTLIBRARIES ctags distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-tags dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-toolexeclibLTLIBRARIES installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-toolexeclibLTLIBRARIES
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libsanitizer/ubsan/libtool-version b/libsanitizer/ubsan/libtool-version
new file mode 100644
index 00000000000..204fdd2d8e5
--- /dev/null
+++ b/libsanitizer/ubsan/libtool-version
@@ -0,0 +1,6 @@
+# This file is used to maintain libtool version info for libmudflap. See
+# the libtool manual to understand the meaning of the fields. This is
+# a separate file so that version updates don't involve re-running
+# automake.
+# CURRENT:REVISION:AGE
+0:0:0
diff --git a/libsanitizer/ubsan/ubsan_diag.cc b/libsanitizer/ubsan/ubsan_diag.cc
new file mode 100644
index 00000000000..d56ef849b6f
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_diag.cc
@@ -0,0 +1,261 @@
+//===-- ubsan_diag.cc -----------------------------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Diagnostic reporting for the UBSan runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ubsan_diag.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_libc.h"
+#include "sanitizer_common/sanitizer_report_decorator.h"
+#include "sanitizer_common/sanitizer_stacktrace.h"
+#include "sanitizer_common/sanitizer_symbolizer.h"
+#include <stdio.h>
+
+using namespace __ubsan;
+
+Location __ubsan::getCallerLocation(uptr CallerLoc) {
+ if (!CallerLoc)
+ return Location();
+
+ uptr Loc = StackTrace::GetPreviousInstructionPc(CallerLoc);
+
+ AddressInfo Info;
+ if (!SymbolizeCode(Loc, &Info, 1) || !Info.module || !*Info.module)
+ return Location(Loc);
+
+ if (!Info.file)
+ return ModuleLocation(Info.module, Info.module_offset);
+
+ return SourceLocation(Info.file, Info.line, Info.column);
+}
+
+Diag &Diag::operator<<(const TypeDescriptor &V) {
+ return AddArg(V.getTypeName());
+}
+
+Diag &Diag::operator<<(const Value &V) {
+ if (V.getType().isSignedIntegerTy())
+ AddArg(V.getSIntValue());
+ else if (V.getType().isUnsignedIntegerTy())
+ AddArg(V.getUIntValue());
+ else if (V.getType().isFloatTy())
+ AddArg(V.getFloatValue());
+ else
+ AddArg("<unknown>");
+ return *this;
+}
+
+/// Hexadecimal printing for numbers too large for Printf to handle directly.
+static void PrintHex(UIntMax Val) {
+#if HAVE_INT128_T
+ Printf("0x%08x%08x%08x%08x",
+ (unsigned int)(Val >> 96),
+ (unsigned int)(Val >> 64),
+ (unsigned int)(Val >> 32),
+ (unsigned int)(Val));
+#else
+ UNREACHABLE("long long smaller than 64 bits?");
+#endif
+}
+
+static void renderLocation(Location Loc) {
+ switch (Loc.getKind()) {
+ case Location::LK_Source: {
+ SourceLocation SLoc = Loc.getSourceLocation();
+ if (SLoc.isInvalid())
+ Printf("<unknown>:");
+ else {
+ Printf("%s:%d:", SLoc.getFilename(), SLoc.getLine());
+ if (SLoc.getColumn())
+ Printf("%d:", SLoc.getColumn());
+ }
+ break;
+ }
+ case Location::LK_Module:
+ Printf("%s:0x%zx:", Loc.getModuleLocation().getModuleName(),
+ Loc.getModuleLocation().getOffset());
+ break;
+ case Location::LK_Memory:
+ Printf("%p:", Loc.getMemoryLocation());
+ break;
+ case Location::LK_Null:
+ Printf("<unknown>:");
+ break;
+ }
+}
+
+static void renderText(const char *Message, const Diag::Arg *Args) {
+ for (const char *Msg = Message; *Msg; ++Msg) {
+ if (*Msg != '%') {
+ char Buffer[64];
+ unsigned I;
+ for (I = 0; Msg[I] && Msg[I] != '%' && I != 63; ++I)
+ Buffer[I] = Msg[I];
+ Buffer[I] = '\0';
+ Printf(Buffer);
+ Msg += I - 1;
+ } else {
+ const Diag::Arg &A = Args[*++Msg - '0'];
+ switch (A.Kind) {
+ case Diag::AK_String:
+ Printf("%s", A.String);
+ break;
+ case Diag::AK_Mangled: {
+ Printf("'%s'", Demangle(A.String));
+ break;
+ }
+ case Diag::AK_SInt:
+ // 'long long' is guaranteed to be at least 64 bits wide.
+ if (A.SInt >= INT64_MIN && A.SInt <= INT64_MAX)
+ Printf("%lld", (long long)A.SInt);
+ else
+ PrintHex(A.SInt);
+ break;
+ case Diag::AK_UInt:
+ if (A.UInt <= UINT64_MAX)
+ Printf("%llu", (unsigned long long)A.UInt);
+ else
+ PrintHex(A.UInt);
+ break;
+ case Diag::AK_Float: {
+ // FIXME: Support floating-point formatting in sanitizer_common's
+ // printf, and stop using snprintf here.
+ char Buffer[32];
+ snprintf(Buffer, sizeof(Buffer), "%Lg", (long double)A.Float);
+ Printf("%s", Buffer);
+ break;
+ }
+ case Diag::AK_Pointer:
+ Printf("%p", A.Pointer);
+ break;
+ }
+ }
+ }
+}
+
+/// Find the earliest-starting range in Ranges which ends after Loc.
+static Range *upperBound(MemoryLocation Loc, Range *Ranges,
+ unsigned NumRanges) {
+ Range *Best = 0;
+ for (unsigned I = 0; I != NumRanges; ++I)
+ if (Ranges[I].getEnd().getMemoryLocation() > Loc &&
+ (!Best ||
+ Best->getStart().getMemoryLocation() >
+ Ranges[I].getStart().getMemoryLocation()))
+ Best = &Ranges[I];
+ return Best;
+}
+
+/// Render a snippet of the address space near a location.
+static void renderMemorySnippet(const __sanitizer::AnsiColorDecorator &Decor,
+ MemoryLocation Loc,
+ Range *Ranges, unsigned NumRanges,
+ const Diag::Arg *Args) {
+ const unsigned BytesToShow = 32;
+ const unsigned MinBytesNearLoc = 4;
+
+ // Show at least the 8 bytes surrounding Loc.
+ MemoryLocation Min = Loc - MinBytesNearLoc, Max = Loc + MinBytesNearLoc;
+ for (unsigned I = 0; I < NumRanges; ++I) {
+ Min = __sanitizer::Min(Ranges[I].getStart().getMemoryLocation(), Min);
+ Max = __sanitizer::Max(Ranges[I].getEnd().getMemoryLocation(), Max);
+ }
+
+ // If we have too many interesting bytes, prefer to show bytes after Loc.
+ if (Max - Min > BytesToShow)
+ Min = __sanitizer::Min(Max - BytesToShow, Loc - MinBytesNearLoc);
+ Max = Min + BytesToShow;
+
+ // Emit data.
+ for (uptr P = Min; P != Max; ++P) {
+ // FIXME: Check that the address is readable before printing it.
+ unsigned char C = *reinterpret_cast<const unsigned char*>(P);
+ Printf("%s%02x", (P % 8 == 0) ? " " : " ", C);
+ }
+ Printf("\n");
+
+ // Emit highlights.
+ Printf(Decor.Green());
+ Range *InRange = upperBound(Min, Ranges, NumRanges);
+ for (uptr P = Min; P != Max; ++P) {
+ char Pad = ' ', Byte = ' ';
+ if (InRange && InRange->getEnd().getMemoryLocation() == P)
+ InRange = upperBound(P, Ranges, NumRanges);
+ if (!InRange && P > Loc)
+ break;
+ if (InRange && InRange->getStart().getMemoryLocation() < P)
+ Pad = '~';
+ if (InRange && InRange->getStart().getMemoryLocation() <= P)
+ Byte = '~';
+ char Buffer[] = { Pad, Pad, P == Loc ? '^' : Byte, Byte, 0 };
+ Printf((P % 8 == 0) ? Buffer : &Buffer[1]);
+ }
+ Printf("%s\n", Decor.Default());
+
+ // Go over the line again, and print names for the ranges.
+ InRange = 0;
+ unsigned Spaces = 0;
+ for (uptr P = Min; P != Max; ++P) {
+ if (!InRange || InRange->getEnd().getMemoryLocation() == P)
+ InRange = upperBound(P, Ranges, NumRanges);
+ if (!InRange)
+ break;
+
+ Spaces += (P % 8) == 0 ? 2 : 1;
+
+ if (InRange && InRange->getStart().getMemoryLocation() == P) {
+ while (Spaces--)
+ Printf(" ");
+ renderText(InRange->getText(), Args);
+ Printf("\n");
+ // FIXME: We only support naming one range for now!
+ break;
+ }
+
+ Spaces += 2;
+ }
+
+ // FIXME: Print names for anything we can identify within the line:
+ //
+ // * If we can identify the memory itself as belonging to a particular
+ // global, stack variable, or dynamic allocation, then do so.
+ //
+ // * If we have a pointer-size, pointer-aligned range highlighted,
+ // determine whether the value of that range is a pointer to an
+ // entity which we can name, and if so, print that name.
+ //
+ // This needs an external symbolizer, or (preferably) ASan instrumentation.
+}
+
+Diag::~Diag() {
+ __sanitizer::AnsiColorDecorator Decor(PrintsToTty());
+ SpinMutexLock l(&CommonSanitizerReportMutex);
+ Printf(Decor.Bold());
+
+ renderLocation(Loc);
+
+ switch (Level) {
+ case DL_Error:
+ Printf("%s runtime error: %s%s",
+ Decor.Red(), Decor.Default(), Decor.Bold());
+ break;
+
+ case DL_Note:
+ Printf("%s note: %s", Decor.Black(), Decor.Default());
+ break;
+ }
+
+ renderText(Message, Args);
+
+ Printf("%s\n", Decor.Default());
+
+ if (Loc.isMemoryLocation())
+ renderMemorySnippet(Decor, Loc.getMemoryLocation(), Ranges,
+ NumRanges, Args);
+}
diff --git a/libsanitizer/ubsan/ubsan_diag.h b/libsanitizer/ubsan/ubsan_diag.h
new file mode 100644
index 00000000000..969d51cb677
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_diag.h
@@ -0,0 +1,200 @@
+//===-- ubsan_diag.h --------------------------------------------*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Diagnostics emission for Clang's undefined behavior sanitizer.
+//
+//===----------------------------------------------------------------------===//
+#ifndef UBSAN_DIAG_H
+#define UBSAN_DIAG_H
+
+#include "ubsan_value.h"
+
+namespace __ubsan {
+
+/// \brief A location within a loaded module in the program. These are used when
+/// the location can't be resolved to a SourceLocation.
+class ModuleLocation {
+ const char *ModuleName;
+ uptr Offset;
+
+public:
+ ModuleLocation() : ModuleName(0), Offset(0) {}
+ ModuleLocation(const char *ModuleName, uptr Offset)
+ : ModuleName(ModuleName), Offset(Offset) {}
+ const char *getModuleName() const { return ModuleName; }
+ uptr getOffset() const { return Offset; }
+};
+
+/// A location of some data within the program's address space.
+typedef uptr MemoryLocation;
+
+/// \brief Location at which a diagnostic can be emitted. Either a
+/// SourceLocation, a ModuleLocation, or a MemoryLocation.
+class Location {
+public:
+ enum LocationKind { LK_Null, LK_Source, LK_Module, LK_Memory };
+
+private:
+ LocationKind Kind;
+ // FIXME: In C++11, wrap these in an anonymous union.
+ SourceLocation SourceLoc;
+ ModuleLocation ModuleLoc;
+ MemoryLocation MemoryLoc;
+
+public:
+ Location() : Kind(LK_Null) {}
+ Location(SourceLocation Loc) :
+ Kind(LK_Source), SourceLoc(Loc) {}
+ Location(ModuleLocation Loc) :
+ Kind(LK_Module), ModuleLoc(Loc) {}
+ Location(MemoryLocation Loc) :
+ Kind(LK_Memory), MemoryLoc(Loc) {}
+
+ LocationKind getKind() const { return Kind; }
+
+ bool isSourceLocation() const { return Kind == LK_Source; }
+ bool isModuleLocation() const { return Kind == LK_Module; }
+ bool isMemoryLocation() const { return Kind == LK_Memory; }
+
+ SourceLocation getSourceLocation() const {
+ CHECK(isSourceLocation());
+ return SourceLoc;
+ }
+ ModuleLocation getModuleLocation() const {
+ CHECK(isModuleLocation());
+ return ModuleLoc;
+ }
+ MemoryLocation getMemoryLocation() const {
+ CHECK(isMemoryLocation());
+ return MemoryLoc;
+ }
+};
+
+/// Try to obtain a location for the caller. This might fail, and produce either
+/// an invalid location or a module location for the caller.
+Location getCallerLocation(uptr CallerLoc = GET_CALLER_PC());
+
+/// A diagnostic severity level.
+enum DiagLevel {
+ DL_Error, ///< An error.
+ DL_Note ///< A note, attached to a prior diagnostic.
+};
+
+/// \brief Annotation for a range of locations in a diagnostic.
+class Range {
+ Location Start, End;
+ const char *Text;
+
+public:
+ Range() : Start(), End(), Text() {}
+ Range(MemoryLocation Start, MemoryLocation End, const char *Text)
+ : Start(Start), End(End), Text(Text) {}
+ Location getStart() const { return Start; }
+ Location getEnd() const { return End; }
+ const char *getText() const { return Text; }
+};
+
+/// \brief A mangled C++ name. Really just a strong typedef for 'const char*'.
+class MangledName {
+ const char *Name;
+public:
+ MangledName(const char *Name) : Name(Name) {}
+ const char *getName() const { return Name; }
+};
+
+/// \brief Representation of an in-flight diagnostic.
+///
+/// Temporary \c Diag instances are created by the handler routines to
+/// accumulate arguments for a diagnostic. The destructor emits the diagnostic
+/// message.
+class Diag {
+ /// The location at which the problem occurred.
+ Location Loc;
+
+ /// The diagnostic level.
+ DiagLevel Level;
+
+ /// The message which will be emitted, with %0, %1, ... placeholders for
+ /// arguments.
+ const char *Message;
+
+public:
+ /// Kinds of arguments, corresponding to members of \c Arg's union.
+ enum ArgKind {
+ AK_String, ///< A string argument, displayed as-is.
+ AK_Mangled,///< A C++ mangled name, demangled before display.
+ AK_UInt, ///< An unsigned integer argument.
+ AK_SInt, ///< A signed integer argument.
+ AK_Float, ///< A floating-point argument.
+ AK_Pointer ///< A pointer argument, displayed in hexadecimal.
+ };
+
+ /// An individual diagnostic message argument.
+ struct Arg {
+ Arg() {}
+ Arg(const char *String) : Kind(AK_String), String(String) {}
+ Arg(MangledName MN) : Kind(AK_Mangled), String(MN.getName()) {}
+ Arg(UIntMax UInt) : Kind(AK_UInt), UInt(UInt) {}
+ Arg(SIntMax SInt) : Kind(AK_SInt), SInt(SInt) {}
+ Arg(FloatMax Float) : Kind(AK_Float), Float(Float) {}
+ Arg(const void *Pointer) : Kind(AK_Pointer), Pointer(Pointer) {}
+
+ ArgKind Kind;
+ union {
+ const char *String;
+ UIntMax UInt;
+ SIntMax SInt;
+ FloatMax Float;
+ const void *Pointer;
+ };
+ };
+
+private:
+ static const unsigned MaxArgs = 5;
+ static const unsigned MaxRanges = 1;
+
+ /// The arguments which have been added to this diagnostic so far.
+ Arg Args[MaxArgs];
+ unsigned NumArgs;
+
+ /// The ranges which have been added to this diagnostic so far.
+ Range Ranges[MaxRanges];
+ unsigned NumRanges;
+
+ Diag &AddArg(Arg A) {
+ CHECK(NumArgs != MaxArgs);
+ Args[NumArgs++] = A;
+ return *this;
+ }
+
+ Diag &AddRange(Range A) {
+ CHECK(NumRanges != MaxRanges);
+ Ranges[NumRanges++] = A;
+ return *this;
+ }
+
+ /// \c Diag objects are not copyable.
+ Diag(const Diag &); // NOT IMPLEMENTED
+ Diag &operator=(const Diag &);
+
+public:
+ Diag(Location Loc, DiagLevel Level, const char *Message)
+ : Loc(Loc), Level(Level), Message(Message), NumArgs(0), NumRanges(0) {}
+ ~Diag();
+
+ Diag &operator<<(const char *Str) { return AddArg(Str); }
+ Diag &operator<<(MangledName MN) { return AddArg(MN); }
+ Diag &operator<<(unsigned long long V) { return AddArg(UIntMax(V)); }
+ Diag &operator<<(const void *V) { return AddArg(V); }
+ Diag &operator<<(const TypeDescriptor &V);
+ Diag &operator<<(const Value &V);
+ Diag &operator<<(const Range &R) { return AddRange(R); }
+};
+
+} // namespace __ubsan
+
+#endif // UBSAN_DIAG_H
diff --git a/libsanitizer/ubsan/ubsan_handlers.cc b/libsanitizer/ubsan/ubsan_handlers.cc
new file mode 100644
index 00000000000..5947c2a5101
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_handlers.cc
@@ -0,0 +1,258 @@
+//===-- ubsan_handlers.cc -------------------------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Error logging entry points for the UBSan runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ubsan_handlers.h"
+#include "ubsan_diag.h"
+
+#include "sanitizer_common/sanitizer_common.h"
+
+using namespace __sanitizer;
+using namespace __ubsan;
+
+namespace __ubsan {
+ const char *TypeCheckKinds[] = {
+ "load of", "store to", "reference binding to", "member access within",
+ "member call on", "constructor call on", "downcast of", "downcast of"
+ };
+}
+
+static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer,
+ Location FallbackLoc) {
+ Location Loc = Data->Loc.acquire();
+
+ // Use the SourceLocation from Data to track deduplication, even if 'invalid'
+ if (Loc.getSourceLocation().isDisabled())
+ return;
+ if (Data->Loc.isInvalid())
+ Loc = FallbackLoc;
+
+ if (!Pointer)
+ Diag(Loc, DL_Error, "%0 null pointer of type %1")
+ << TypeCheckKinds[Data->TypeCheckKind] << Data->Type;
+ else if (Data->Alignment && (Pointer & (Data->Alignment - 1)))
+ Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, "
+ "which requires %2 byte alignment")
+ << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer
+ << Data->Alignment << Data->Type;
+ else
+ Diag(Loc, DL_Error, "%0 address %1 with insufficient space "
+ "for an object of type %2")
+ << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
+ if (Pointer)
+ Diag(Pointer, DL_Note, "pointer points here");
+}
+void __ubsan::__ubsan_handle_type_mismatch(TypeMismatchData *Data,
+ ValueHandle Pointer) {
+ handleTypeMismatchImpl(Data, Pointer, getCallerLocation());
+}
+void __ubsan::__ubsan_handle_type_mismatch_abort(TypeMismatchData *Data,
+ ValueHandle Pointer) {
+ handleTypeMismatchImpl(Data, Pointer, getCallerLocation());
+ Die();
+}
+
+/// \brief Common diagnostic emission for various forms of integer overflow.
+template<typename T> static void HandleIntegerOverflow(OverflowData *Data,
+ ValueHandle LHS,
+ const char *Operator,
+ T RHS) {
+ SourceLocation Loc = Data->Loc.acquire();
+ if (Loc.isDisabled())
+ return;
+
+ Diag(Loc, DL_Error, "%0 integer overflow: "
+ "%1 %2 %3 cannot be represented in type %4")
+ << (Data->Type.isSignedIntegerTy() ? "signed" : "unsigned")
+ << Value(Data->Type, LHS) << Operator << RHS << Data->Type;
+}
+
+void __ubsan::__ubsan_handle_add_overflow(OverflowData *Data,
+ ValueHandle LHS, ValueHandle RHS) {
+ HandleIntegerOverflow(Data, LHS, "+", Value(Data->Type, RHS));
+}
+void __ubsan::__ubsan_handle_add_overflow_abort(OverflowData *Data,
+ ValueHandle LHS,
+ ValueHandle RHS) {
+ __ubsan_handle_add_overflow(Data, LHS, RHS);
+ Die();
+}
+
+void __ubsan::__ubsan_handle_sub_overflow(OverflowData *Data,
+ ValueHandle LHS, ValueHandle RHS) {
+ HandleIntegerOverflow(Data, LHS, "-", Value(Data->Type, RHS));
+}
+void __ubsan::__ubsan_handle_sub_overflow_abort(OverflowData *Data,
+ ValueHandle LHS,
+ ValueHandle RHS) {
+ __ubsan_handle_sub_overflow(Data, LHS, RHS);
+ Die();
+}
+
+void __ubsan::__ubsan_handle_mul_overflow(OverflowData *Data,
+ ValueHandle LHS, ValueHandle RHS) {
+ HandleIntegerOverflow(Data, LHS, "*", Value(Data->Type, RHS));
+}
+void __ubsan::__ubsan_handle_mul_overflow_abort(OverflowData *Data,
+ ValueHandle LHS,
+ ValueHandle RHS) {
+ __ubsan_handle_mul_overflow(Data, LHS, RHS);
+ Die();
+}
+
+void __ubsan::__ubsan_handle_negate_overflow(OverflowData *Data,
+ ValueHandle OldVal) {
+ SourceLocation Loc = Data->Loc.acquire();
+ if (Loc.isDisabled())
+ return;
+
+ if (Data->Type.isSignedIntegerTy())
+ Diag(Loc, DL_Error,
+ "negation of %0 cannot be represented in type %1; "
+ "cast to an unsigned type to negate this value to itself")
+ << Value(Data->Type, OldVal) << Data->Type;
+ else
+ Diag(Loc, DL_Error,
+ "negation of %0 cannot be represented in type %1")
+ << Value(Data->Type, OldVal) << Data->Type;
+}
+void __ubsan::__ubsan_handle_negate_overflow_abort(OverflowData *Data,
+ ValueHandle OldVal) {
+ __ubsan_handle_negate_overflow(Data, OldVal);
+ Die();
+}
+
+void __ubsan::__ubsan_handle_divrem_overflow(OverflowData *Data,
+ ValueHandle LHS, ValueHandle RHS) {
+ SourceLocation Loc = Data->Loc.acquire();
+ if (Loc.isDisabled())
+ return;
+
+ Value LHSVal(Data->Type, LHS);
+ Value RHSVal(Data->Type, RHS);
+ if (RHSVal.isMinusOne())
+ Diag(Loc, DL_Error,
+ "division of %0 by -1 cannot be represented in type %1")
+ << LHSVal << Data->Type;
+ else
+ Diag(Loc, DL_Error, "division by zero");
+}
+void __ubsan::__ubsan_handle_divrem_overflow_abort(OverflowData *Data,
+ ValueHandle LHS,
+ ValueHandle RHS) {
+ __ubsan_handle_divrem_overflow(Data, LHS, RHS);
+ Die();
+}
+
+void __ubsan::__ubsan_handle_shift_out_of_bounds(ShiftOutOfBoundsData *Data,
+ ValueHandle LHS,
+ ValueHandle RHS) {
+ SourceLocation Loc = Data->Loc.acquire();
+ if (Loc.isDisabled())
+ return;
+
+ Value LHSVal(Data->LHSType, LHS);
+ Value RHSVal(Data->RHSType, RHS);
+ if (RHSVal.isNegative())
+ Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal;
+ else if (RHSVal.getPositiveIntValue() >= Data->LHSType.getIntegerBitWidth())
+ Diag(Loc, DL_Error,
+ "shift exponent %0 is too large for %1-bit type %2")
+ << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType;
+ else if (LHSVal.isNegative())
+ Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal;
+ else
+ Diag(Loc, DL_Error,
+ "left shift of %0 by %1 places cannot be represented in type %2")
+ << LHSVal << RHSVal << Data->LHSType;
+}
+void __ubsan::__ubsan_handle_shift_out_of_bounds_abort(
+ ShiftOutOfBoundsData *Data,
+ ValueHandle LHS,
+ ValueHandle RHS) {
+ __ubsan_handle_shift_out_of_bounds(Data, LHS, RHS);
+ Die();
+}
+
+void __ubsan::__ubsan_handle_out_of_bounds(OutOfBoundsData *Data,
+ ValueHandle Index) {
+ SourceLocation Loc = Data->Loc.acquire();
+ if (Loc.isDisabled())
+ return;
+
+ Value IndexVal(Data->IndexType, Index);
+ Diag(Loc, DL_Error, "index %0 out of bounds for type %1")
+ << IndexVal << Data->ArrayType;
+}
+void __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data,
+ ValueHandle Index) {
+ __ubsan_handle_out_of_bounds(Data, Index);
+ Die();
+}
+
+void __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) {
+ Diag(Data->Loc, DL_Error, "execution reached a __builtin_unreachable() call");
+ Die();
+}
+
+void __ubsan::__ubsan_handle_missing_return(UnreachableData *Data) {
+ Diag(Data->Loc, DL_Error,
+ "execution reached the end of a value-returning function "
+ "without returning a value");
+ Die();
+}
+
+void __ubsan::__ubsan_handle_vla_bound_not_positive(VLABoundData *Data,
+ ValueHandle Bound) {
+ SourceLocation Loc = Data->Loc.acquire();
+ if (Loc.isDisabled())
+ return;
+
+ Diag(Loc, DL_Error, "variable length array bound evaluates to "
+ "non-positive value %0")
+ << Value(Data->Type, Bound);
+}
+void __ubsan::__ubsan_handle_vla_bound_not_positive_abort(VLABoundData *Data,
+ ValueHandle Bound) {
+ __ubsan_handle_vla_bound_not_positive(Data, Bound);
+ Die();
+}
+
+
+void __ubsan::__ubsan_handle_float_cast_overflow(FloatCastOverflowData *Data,
+ ValueHandle From) {
+ // TODO: Add deduplication once a SourceLocation is generated for this check.
+ Diag(getCallerLocation(), DL_Error,
+ "value %0 is outside the range of representable values of type %2")
+ << Value(Data->FromType, From) << Data->FromType << Data->ToType;
+}
+void __ubsan::__ubsan_handle_float_cast_overflow_abort(
+ FloatCastOverflowData *Data,
+ ValueHandle From) {
+ Diag(getCallerLocation(), DL_Error,
+ "value %0 is outside the range of representable values of type %2")
+ << Value(Data->FromType, From) << Data->FromType << Data->ToType;
+ Die();
+}
+
+void __ubsan::__ubsan_handle_load_invalid_value(InvalidValueData *Data,
+ ValueHandle Val) {
+ // TODO: Add deduplication once a SourceLocation is generated for this check.
+ Diag(getCallerLocation(), DL_Error,
+ "load of value %0, which is not a valid value for type %1")
+ << Value(Data->Type, Val) << Data->Type;
+}
+void __ubsan::__ubsan_handle_load_invalid_value_abort(InvalidValueData *Data,
+ ValueHandle Val) {
+ Diag(getCallerLocation(), DL_Error,
+ "load of value %0, which is not a valid value for type %1")
+ << Value(Data->Type, Val) << Data->Type;
+ Die();
+}
diff --git a/libsanitizer/ubsan/ubsan_handlers.h b/libsanitizer/ubsan/ubsan_handlers.h
new file mode 100644
index 00000000000..034edf59021
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_handlers.h
@@ -0,0 +1,115 @@
+//===-- ubsan_handlers.h ----------------------------------------*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Entry points to the runtime library for Clang's undefined behavior sanitizer.
+//
+//===----------------------------------------------------------------------===//
+#ifndef UBSAN_HANDLERS_H
+#define UBSAN_HANDLERS_H
+
+#include "ubsan_value.h"
+
+namespace __ubsan {
+
+struct TypeMismatchData {
+ SourceLocation Loc;
+ const TypeDescriptor &Type;
+ uptr Alignment;
+ unsigned char TypeCheckKind;
+};
+
+#define RECOVERABLE(checkname, ...) \
+ extern "C" SANITIZER_INTERFACE_ATTRIBUTE \
+ void __ubsan_handle_ ## checkname( __VA_ARGS__ ); \
+ extern "C" SANITIZER_INTERFACE_ATTRIBUTE \
+ void __ubsan_handle_ ## checkname ## _abort( __VA_ARGS__ );
+
+/// \brief Handle a runtime type check failure, caused by either a misaligned
+/// pointer, a null pointer, or a pointer to insufficient storage for the
+/// type.
+RECOVERABLE(type_mismatch, TypeMismatchData *Data, ValueHandle Pointer)
+
+struct OverflowData {
+ SourceLocation Loc;
+ const TypeDescriptor &Type;
+};
+
+/// \brief Handle an integer addition overflow.
+RECOVERABLE(add_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
+
+/// \brief Handle an integer subtraction overflow.
+RECOVERABLE(sub_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
+
+/// \brief Handle an integer multiplication overflow.
+RECOVERABLE(mul_overflow, OverflowData *Data, ValueHandle LHS, ValueHandle RHS)
+
+/// \brief Handle a signed integer overflow for a unary negate operator.
+RECOVERABLE(negate_overflow, OverflowData *Data, ValueHandle OldVal)
+
+/// \brief Handle an INT_MIN/-1 overflow or division by zero.
+RECOVERABLE(divrem_overflow, OverflowData *Data,
+ ValueHandle LHS, ValueHandle RHS)
+
+struct ShiftOutOfBoundsData {
+ SourceLocation Loc;
+ const TypeDescriptor &LHSType;
+ const TypeDescriptor &RHSType;
+};
+
+/// \brief Handle a shift where the RHS is out of bounds or a left shift where
+/// the LHS is negative or overflows.
+RECOVERABLE(shift_out_of_bounds, ShiftOutOfBoundsData *Data,
+ ValueHandle LHS, ValueHandle RHS)
+
+struct OutOfBoundsData {
+ SourceLocation Loc;
+ const TypeDescriptor &ArrayType;
+ const TypeDescriptor &IndexType;
+};
+
+/// \brief Handle an array index out of bounds error.
+RECOVERABLE(out_of_bounds, OutOfBoundsData *Data, ValueHandle Index)
+
+struct UnreachableData {
+ SourceLocation Loc;
+};
+
+/// \brief Handle a __builtin_unreachable which is reached.
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void __ubsan_handle_builtin_unreachable(UnreachableData *Data);
+/// \brief Handle reaching the end of a value-returning function.
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void __ubsan_handle_missing_return(UnreachableData *Data);
+
+struct VLABoundData {
+ SourceLocation Loc;
+ const TypeDescriptor &Type;
+};
+
+/// \brief Handle a VLA with a non-positive bound.
+RECOVERABLE(vla_bound_not_positive, VLABoundData *Data, ValueHandle Bound)
+
+struct FloatCastOverflowData {
+ // FIXME: SourceLocation Loc;
+ const TypeDescriptor &FromType;
+ const TypeDescriptor &ToType;
+};
+
+/// \brief Handle overflow in a conversion to or from a floating-point type.
+RECOVERABLE(float_cast_overflow, FloatCastOverflowData *Data, ValueHandle From)
+
+struct InvalidValueData {
+ // FIXME: SourceLocation Loc;
+ const TypeDescriptor &Type;
+};
+
+/// \brief Handle a load of an invalid value for the type.
+RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val)
+
+}
+
+#endif // UBSAN_HANDLERS_H
diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.cc b/libsanitizer/ubsan/ubsan_handlers_cxx.cc
new file mode 100644
index 00000000000..bb43cc75cfc
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_handlers_cxx.cc
@@ -0,0 +1,72 @@
+//===-- ubsan_handlers_cxx.cc ---------------------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Error logging entry points for the UBSan runtime, which are only used for C++
+// compilations. This file is permitted to use language features which require
+// linking against a C++ ABI library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ubsan_handlers_cxx.h"
+#include "ubsan_diag.h"
+#include "ubsan_type_hash.h"
+
+#include "sanitizer_common/sanitizer_common.h"
+
+using namespace __sanitizer;
+using namespace __ubsan;
+
+namespace __ubsan {
+ extern const char *TypeCheckKinds[];
+}
+
+static void HandleDynamicTypeCacheMiss(
+ DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash,
+ bool Abort) {
+ if (checkDynamicType((void*)Pointer, Data->TypeInfo, Hash))
+ // Just a cache miss. The type matches after all.
+ return;
+
+ SourceLocation Loc = Data->Loc.acquire();
+ if (Loc.isDisabled())
+ return;
+
+ Diag(Loc, DL_Error,
+ "%0 address %1 which does not point to an object of type %2")
+ << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type;
+
+ // If possible, say what type it actually points to.
+ DynamicTypeInfo DTI = getDynamicTypeInfo((void*)Pointer);
+ if (!DTI.isValid())
+ Diag(Pointer, DL_Note, "object has invalid vptr")
+ << MangledName(DTI.getMostDerivedTypeName())
+ << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr");
+ else if (!DTI.getOffset())
+ Diag(Pointer, DL_Note, "object is of type %0")
+ << MangledName(DTI.getMostDerivedTypeName())
+ << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0");
+ else
+ // FIXME: Find the type at the specified offset, and include that
+ // in the note.
+ Diag(Pointer - DTI.getOffset(), DL_Note,
+ "object is base class subobject at offset %0 within object of type %1")
+ << DTI.getOffset() << MangledName(DTI.getMostDerivedTypeName())
+ << MangledName(DTI.getSubobjectTypeName())
+ << Range(Pointer, Pointer + sizeof(uptr), "vptr for %2 base class of %1");
+
+ if (Abort)
+ Die();
+}
+
+void __ubsan::__ubsan_handle_dynamic_type_cache_miss(
+ DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
+ HandleDynamicTypeCacheMiss(Data, Pointer, Hash, false);
+}
+void __ubsan::__ubsan_handle_dynamic_type_cache_miss_abort(
+ DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash) {
+ HandleDynamicTypeCacheMiss(Data, Pointer, Hash, true);
+}
diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.h b/libsanitizer/ubsan/ubsan_handlers_cxx.h
new file mode 100644
index 00000000000..3419744e390
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_handlers_cxx.h
@@ -0,0 +1,38 @@
+//===-- ubsan_handlers_cxx.h ------------------------------------*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Entry points to the runtime library for Clang's undefined behavior sanitizer,
+// for C++-specific checks. This code is not linked into C binaries.
+//
+//===----------------------------------------------------------------------===//
+#ifndef UBSAN_HANDLERS_CXX_H
+#define UBSAN_HANDLERS_CXX_H
+
+#include "ubsan_value.h"
+
+namespace __ubsan {
+
+struct DynamicTypeCacheMissData {
+ SourceLocation Loc;
+ const TypeDescriptor &Type;
+ void *TypeInfo;
+ unsigned char TypeCheckKind;
+};
+
+/// \brief Handle a runtime type check failure, caused by an incorrect vptr.
+/// When this handler is called, all we know is that the type was not in the
+/// cache; this does not necessarily imply the existence of a bug.
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void __ubsan_handle_dynamic_type_cache_miss(
+ DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void __ubsan_handle_dynamic_type_cache_miss_abort(
+ DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash);
+
+}
+
+#endif // UBSAN_HANDLERS_H
diff --git a/libsanitizer/ubsan/ubsan_type_hash.cc b/libsanitizer/ubsan/ubsan_type_hash.cc
new file mode 100644
index 00000000000..440d3ad89c6
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_type_hash.cc
@@ -0,0 +1,246 @@
+//===-- ubsan_type_hash.cc ------------------------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implementation of a hash table for fast checking of inheritance
+// relationships. This file is only linked into C++ compilations, and is
+// permitted to use language features which require a C++ ABI library.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ubsan_type_hash.h"
+
+#include "sanitizer_common/sanitizer_common.h"
+
+// The following are intended to be binary compatible with the definitions
+// given in the Itanium ABI. We make no attempt to be ODR-compatible with
+// those definitions, since existing ABI implementations aren't.
+
+namespace std {
+ class type_info {
+ public:
+ virtual ~type_info();
+
+ const char *__type_name;
+ };
+}
+
+namespace __cxxabiv1 {
+
+/// Type info for classes with no bases, and base class for type info for
+/// classes with bases.
+class __class_type_info : public std::type_info {
+ virtual ~__class_type_info();
+};
+
+/// Type info for classes with simple single public inheritance.
+class __si_class_type_info : public __class_type_info {
+public:
+ virtual ~__si_class_type_info();
+
+ const __class_type_info *__base_type;
+};
+
+class __base_class_type_info {
+public:
+ const __class_type_info *__base_type;
+ long __offset_flags;
+
+ enum __offset_flags_masks {
+ __virtual_mask = 0x1,
+ __public_mask = 0x2,
+ __offset_shift = 8
+ };
+};
+
+/// Type info for classes with multiple, virtual, or non-public inheritance.
+class __vmi_class_type_info : public __class_type_info {
+public:
+ virtual ~__vmi_class_type_info();
+
+ unsigned int flags;
+ unsigned int base_count;
+ __base_class_type_info base_info[1];
+};
+
+}
+
+namespace abi = __cxxabiv1;
+
+// We implement a simple two-level cache for type-checking results. For each
+// (vptr,type) pair, a hash is computed. This hash is assumed to be globally
+// unique; if it collides, we will get false negatives, but:
+// * such a collision would have to occur on the *first* bad access,
+// * the probability of such a collision is low (and for a 64-bit target, is
+// negligible), and
+// * the vptr, and thus the hash, can be affected by ASLR, so multiple runs
+// give better coverage.
+//
+// The first caching layer is a small hash table with no chaining; buckets are
+// reused as needed. The second caching layer is a large hash table with open
+// chaining. We can freely evict from either layer since this is just a cache.
+//
+// FIXME: Make these hash table accesses thread-safe. The races here are benign
+// (worst-case, we could miss a bug or see a slowdown) but we should
+// avoid upsetting race detectors.
+
+/// Find a bucket to store the given hash value in.
+static __ubsan::HashValue *getTypeCacheHashTableBucket(__ubsan::HashValue V) {
+ static const unsigned HashTableSize = 65537;
+ static __ubsan::HashValue __ubsan_vptr_hash_set[HashTableSize] = { 1 };
+
+ unsigned Probe = V & 65535;
+ for (int Tries = 5; Tries; --Tries) {
+ if (!__ubsan_vptr_hash_set[Probe] || __ubsan_vptr_hash_set[Probe] == V)
+ return &__ubsan_vptr_hash_set[Probe];
+ Probe += ((V >> 16) & 65535) + 1;
+ if (Probe >= HashTableSize)
+ Probe -= HashTableSize;
+ }
+ // FIXME: Pick a random entry from the probe sequence to evict rather than
+ // just taking the first.
+ return &__ubsan_vptr_hash_set[V];
+}
+
+/// A cache of recently-checked hashes. Mini hash table with "random" evictions.
+__ubsan::HashValue
+__ubsan::__ubsan_vptr_type_cache[__ubsan::VptrTypeCacheSize] = { 1 };
+
+/// \brief Determine whether \p Derived has a \p Base base class subobject at
+/// offset \p Offset.
+static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived,
+ const abi::__class_type_info *Base,
+ sptr Offset) {
+ if (Derived->__type_name == Base->__type_name)
+ return Offset == 0;
+
+ if (const abi::__si_class_type_info *SI =
+ dynamic_cast<const abi::__si_class_type_info*>(Derived))
+ return isDerivedFromAtOffset(SI->__base_type, Base, Offset);
+
+ const abi::__vmi_class_type_info *VTI =
+ dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
+ if (!VTI)
+ // No base class subobjects.
+ return false;
+
+ // Look for a base class which is derived from \p Base at the right offset.
+ for (unsigned int base = 0; base != VTI->base_count; ++base) {
+ // FIXME: Curtail the recursion if this base can't possibly contain the
+ // given offset.
+ sptr OffsetHere = VTI->base_info[base].__offset_flags >>
+ abi::__base_class_type_info::__offset_shift;
+ if (VTI->base_info[base].__offset_flags &
+ abi::__base_class_type_info::__virtual_mask)
+ // For now, just punt on virtual bases and say 'yes'.
+ // FIXME: OffsetHere is the offset in the vtable of the virtual base
+ // offset. Read the vbase offset out of the vtable and use it.
+ return true;
+ if (isDerivedFromAtOffset(VTI->base_info[base].__base_type,
+ Base, Offset - OffsetHere))
+ return true;
+ }
+
+ return false;
+}
+
+/// \brief Find the derived-most dynamic base class of \p Derived at offset
+/// \p Offset.
+static const abi::__class_type_info *findBaseAtOffset(
+ const abi::__class_type_info *Derived, sptr Offset) {
+ if (!Offset)
+ return Derived;
+
+ if (const abi::__si_class_type_info *SI =
+ dynamic_cast<const abi::__si_class_type_info*>(Derived))
+ return findBaseAtOffset(SI->__base_type, Offset);
+
+ const abi::__vmi_class_type_info *VTI =
+ dynamic_cast<const abi::__vmi_class_type_info*>(Derived);
+ if (!VTI)
+ // No base class subobjects.
+ return 0;
+
+ for (unsigned int base = 0; base != VTI->base_count; ++base) {
+ sptr OffsetHere = VTI->base_info[base].__offset_flags >>
+ abi::__base_class_type_info::__offset_shift;
+ if (VTI->base_info[base].__offset_flags &
+ abi::__base_class_type_info::__virtual_mask)
+ // FIXME: Can't handle virtual bases yet.
+ continue;
+ if (const abi::__class_type_info *Base =
+ findBaseAtOffset(VTI->base_info[base].__base_type,
+ Offset - OffsetHere))
+ return Base;
+ }
+
+ return 0;
+}
+
+namespace {
+
+struct VtablePrefix {
+ /// The offset from the vptr to the start of the most-derived object.
+ /// This should never be greater than zero, and will usually be exactly
+ /// zero.
+ sptr Offset;
+ /// The type_info object describing the most-derived class type.
+ std::type_info *TypeInfo;
+};
+VtablePrefix *getVtablePrefix(void *Object) {
+ VtablePrefix **VptrPtr = reinterpret_cast<VtablePrefix**>(Object);
+ if (!*VptrPtr)
+ return 0;
+ VtablePrefix *Prefix = *VptrPtr - 1;
+ if (Prefix->Offset > 0 || !Prefix->TypeInfo)
+ // This can't possibly be a valid vtable.
+ return 0;
+ return Prefix;
+}
+
+}
+
+bool __ubsan::checkDynamicType(void *Object, void *Type, HashValue Hash) {
+ // A crash anywhere within this function probably means the vptr is corrupted.
+ // FIXME: Perform these checks more cautiously.
+
+ // Check whether this is something we've evicted from the cache.
+ HashValue *Bucket = getTypeCacheHashTableBucket(Hash);
+ if (*Bucket == Hash) {
+ __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
+ return true;
+ }
+
+ VtablePrefix *Vtable = getVtablePrefix(Object);
+ if (!Vtable)
+ return false;
+
+ // Check that this is actually a type_info object for a class type.
+ abi::__class_type_info *Derived =
+ dynamic_cast<abi::__class_type_info*>(Vtable->TypeInfo);
+ if (!Derived)
+ return false;
+
+ abi::__class_type_info *Base = (abi::__class_type_info*)Type;
+ if (!isDerivedFromAtOffset(Derived, Base, -Vtable->Offset))
+ return false;
+
+ // Success. Cache this result.
+ __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] = Hash;
+ *Bucket = Hash;
+ return true;
+}
+
+__ubsan::DynamicTypeInfo __ubsan::getDynamicTypeInfo(void *Object) {
+ VtablePrefix *Vtable = getVtablePrefix(Object);
+ if (!Vtable)
+ return DynamicTypeInfo(0, 0, 0);
+ const abi::__class_type_info *ObjectType = findBaseAtOffset(
+ static_cast<const abi::__class_type_info*>(Vtable->TypeInfo),
+ -Vtable->Offset);
+ return DynamicTypeInfo(Vtable->TypeInfo->__type_name, -Vtable->Offset,
+ ObjectType ? ObjectType->__type_name : "<unknown>");
+}
diff --git a/libsanitizer/ubsan/ubsan_type_hash.h b/libsanitizer/ubsan/ubsan_type_hash.h
new file mode 100644
index 00000000000..138559f204d
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_type_hash.h
@@ -0,0 +1,61 @@
+//===-- ubsan_type_hash.h ---------------------------------------*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Hashing of types for Clang's undefined behavior checker.
+//
+//===----------------------------------------------------------------------===//
+#ifndef UBSAN_TYPE_HASH_H
+#define UBSAN_TYPE_HASH_H
+
+#include "sanitizer_common/sanitizer_common.h"
+
+namespace __ubsan {
+
+typedef uptr HashValue;
+
+/// \brief Information about the dynamic type of an object (extracted from its
+/// vptr).
+class DynamicTypeInfo {
+ const char *MostDerivedTypeName;
+ sptr Offset;
+ const char *SubobjectTypeName;
+
+public:
+ DynamicTypeInfo(const char *MDTN, sptr Offset, const char *STN)
+ : MostDerivedTypeName(MDTN), Offset(Offset), SubobjectTypeName(STN) {}
+
+ /// Determine whether the object had a valid dynamic type.
+ bool isValid() const { return MostDerivedTypeName; }
+ /// Get the name of the most-derived type of the object.
+ const char *getMostDerivedTypeName() const { return MostDerivedTypeName; }
+ /// Get the offset from the most-derived type to this base class.
+ sptr getOffset() const { return Offset; }
+ /// Get the name of the most-derived type at the specified offset.
+ const char *getSubobjectTypeName() const { return SubobjectTypeName; }
+};
+
+/// \brief Get information about the dynamic type of an object.
+DynamicTypeInfo getDynamicTypeInfo(void *Object);
+
+/// \brief Check whether the dynamic type of \p Object has a \p Type subobject
+/// at offset 0.
+/// \return \c true if the type matches, \c false if not.
+bool checkDynamicType(void *Object, void *Type, HashValue Hash);
+
+const unsigned VptrTypeCacheSize = 128;
+
+/// \brief A cache of the results of checkDynamicType. \c checkDynamicType would
+/// return \c true (modulo hash collisions) if
+/// \code
+/// __ubsan_vptr_type_cache[Hash % VptrTypeCacheSize] == Hash
+/// \endcode
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+HashValue __ubsan_vptr_type_cache[VptrTypeCacheSize];
+
+} // namespace __ubsan
+
+#endif // UBSAN_TYPE_HASH_H
diff --git a/libsanitizer/ubsan/ubsan_value.cc b/libsanitizer/ubsan/ubsan_value.cc
new file mode 100644
index 00000000000..141e8b53504
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_value.cc
@@ -0,0 +1,99 @@
+//===-- ubsan_value.cc ----------------------------------------------------===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Representation of a runtime value, as marshaled from the generated code to
+// the ubsan runtime.
+//
+//===----------------------------------------------------------------------===//
+
+#include "ubsan_value.h"
+#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_libc.h"
+
+using namespace __ubsan;
+
+SIntMax Value::getSIntValue() const {
+ CHECK(getType().isSignedIntegerTy());
+ if (isInlineInt()) {
+ // Val was zero-extended to ValueHandle. Sign-extend from original width
+ // to SIntMax.
+ const unsigned ExtraBits =
+ sizeof(SIntMax) * 8 - getType().getIntegerBitWidth();
+ return SIntMax(Val) << ExtraBits >> ExtraBits;
+ }
+ if (getType().getIntegerBitWidth() == 64)
+ return *reinterpret_cast<s64*>(Val);
+#if HAVE_INT128_T
+ if (getType().getIntegerBitWidth() == 128)
+ return *reinterpret_cast<s128*>(Val);
+#else
+ if (getType().getIntegerBitWidth() == 128)
+ UNREACHABLE("libclang_rt.ubsan was built without __int128 support");
+#endif
+ UNREACHABLE("unexpected bit width");
+}
+
+UIntMax Value::getUIntValue() const {
+ CHECK(getType().isUnsignedIntegerTy());
+ if (isInlineInt())
+ return Val;
+ if (getType().getIntegerBitWidth() == 64)
+ return *reinterpret_cast<u64*>(Val);
+#if HAVE_INT128_T
+ if (getType().getIntegerBitWidth() == 128)
+ return *reinterpret_cast<u128*>(Val);
+#else
+ if (getType().getIntegerBitWidth() == 128)
+ UNREACHABLE("libclang_rt.ubsan was built without __int128 support");
+#endif
+ UNREACHABLE("unexpected bit width");
+}
+
+UIntMax Value::getPositiveIntValue() const {
+ if (getType().isUnsignedIntegerTy())
+ return getUIntValue();
+ SIntMax Val = getSIntValue();
+ CHECK(Val >= 0);
+ return Val;
+}
+
+/// Get the floating-point value of this object, extended to a long double.
+/// These are always passed by address (our calling convention doesn't allow
+/// them to be passed in floating-point registers, so this has little cost).
+FloatMax Value::getFloatValue() const {
+ CHECK(getType().isFloatTy());
+ if (isInlineFloat()) {
+ switch (getType().getFloatBitWidth()) {
+#if 0
+ // FIXME: OpenCL / NEON 'half' type. LLVM can't lower the conversion
+ // from '__fp16' to 'long double'.
+ case 16: {
+ __fp16 Value;
+ internal_memcpy(&Value, &Val, 4);
+ return Value;
+ }
+#endif
+ case 32: {
+ float Value;
+ internal_memcpy(&Value, &Val, 4);
+ return Value;
+ }
+ case 64: {
+ double Value;
+ internal_memcpy(&Value, &Val, 8);
+ return Value;
+ }
+ }
+ } else {
+ switch (getType().getFloatBitWidth()) {
+ case 64: return *reinterpret_cast<double*>(Val);
+ case 80: return *reinterpret_cast<long double*>(Val);
+ case 128: return *reinterpret_cast<long double*>(Val);
+ }
+ }
+ UNREACHABLE("unexpected floating point bit width");
+}
diff --git a/libsanitizer/ubsan/ubsan_value.h b/libsanitizer/ubsan/ubsan_value.h
new file mode 100644
index 00000000000..6ca0f56c99d
--- /dev/null
+++ b/libsanitizer/ubsan/ubsan_value.h
@@ -0,0 +1,202 @@
+//===-- ubsan_value.h -------------------------------------------*- C++ -*-===//
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Representation of data which is passed from the compiler-generated calls into
+// the ubsan runtime.
+//
+//===----------------------------------------------------------------------===//
+#ifndef UBSAN_VALUE_H
+#define UBSAN_VALUE_H
+
+// For now, only support linux and darwin. Other platforms should be easy to
+// add, and probably work as-is.
+#if !defined(__linux__) && !defined(__APPLE__)
+#error "UBSan not supported for this platform!"
+#endif
+
+#include "sanitizer_common/sanitizer_atomic.h"
+#include "sanitizer_common/sanitizer_common.h"
+
+// FIXME: Move this out to a config header.
+#if __SIZEOF_INT128__
+__extension__ typedef __int128 s128;
+__extension__ typedef unsigned __int128 u128;
+#define HAVE_INT128_T 1
+#else
+#define HAVE_INT128_T 0
+#endif
+
+
+namespace __ubsan {
+
+/// \brief Largest integer types we support.
+#if HAVE_INT128_T
+typedef s128 SIntMax;
+typedef u128 UIntMax;
+#else
+typedef s64 SIntMax;
+typedef u64 UIntMax;
+#endif
+
+/// \brief Largest floating-point type we support.
+typedef long double FloatMax;
+
+/// \brief A description of a source location. This corresponds to Clang's
+/// \c PresumedLoc type.
+class SourceLocation {
+ const char *Filename;
+ u32 Line;
+ u32 Column;
+
+public:
+ SourceLocation() : Filename(), Line(), Column() {}
+ SourceLocation(const char *Filename, unsigned Line, unsigned Column)
+ : Filename(Filename), Line(Line), Column(Column) {}
+
+ /// \brief Determine whether the source location is known.
+ bool isInvalid() const { return !Filename; }
+
+ /// \brief Atomically acquire a copy, disabling original in-place.
+ /// Exactly one call to acquire() returns a copy that isn't disabled.
+ SourceLocation acquire() {
+ u32 OldColumn = __sanitizer::atomic_exchange(
+ (__sanitizer::atomic_uint32_t *)&Column, ~u32(0),
+ __sanitizer::memory_order_relaxed);
+ return SourceLocation(Filename, Line, OldColumn);
+ }
+
+ /// \brief Determine if this Location has been disabled.
+ /// Disabled SourceLocations are invalid to use.
+ bool isDisabled() {
+ return Column == ~u32(0);
+ }
+
+ /// \brief Get the presumed filename for the source location.
+ const char *getFilename() const { return Filename; }
+ /// \brief Get the presumed line number.
+ unsigned getLine() const { return Line; }
+ /// \brief Get the column within the presumed line.
+ unsigned getColumn() const { return Column; }
+};
+
+
+/// \brief A description of a type.
+class TypeDescriptor {
+ /// A value from the \c Kind enumeration, specifying what flavor of type we
+ /// have.
+ u16 TypeKind;
+
+ /// A \c Type-specific value providing information which allows us to
+ /// interpret the meaning of a ValueHandle of this type.
+ u16 TypeInfo;
+
+ /// The name of the type follows, in a format suitable for including in
+ /// diagnostics.
+ char TypeName[1];
+
+public:
+ enum Kind {
+ /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned
+ /// value. Remaining bits are log_2(bit width). The value representation is
+ /// the integer itself if it fits into a ValueHandle, and a pointer to the
+ /// integer otherwise.
+ TK_Integer = 0x0000,
+ /// A floating-point type. Low 16 bits are bit width. The value
+ /// representation is that of bitcasting the floating-point value to an
+ /// integer type.
+ TK_Float = 0x0001,
+ /// Any other type. The value representation is unspecified.
+ TK_Unknown = 0xffff
+ };
+
+ const char *getTypeName() const { return TypeName; }
+
+ Kind getKind() const {
+ return static_cast<Kind>(TypeKind);
+ }
+
+ bool isIntegerTy() const { return getKind() == TK_Integer; }
+ bool isSignedIntegerTy() const {
+ return isIntegerTy() && (TypeInfo & 1);
+ }
+ bool isUnsignedIntegerTy() const {
+ return isIntegerTy() && !(TypeInfo & 1);
+ }
+ unsigned getIntegerBitWidth() const {
+ CHECK(isIntegerTy());
+ return 1 << (TypeInfo >> 1);
+ }
+
+ bool isFloatTy() const { return getKind() == TK_Float; }
+ unsigned getFloatBitWidth() const {
+ CHECK(isFloatTy());
+ return TypeInfo;
+ }
+};
+
+/// \brief An opaque handle to a value.
+typedef uptr ValueHandle;
+
+
+/// \brief Representation of an operand value provided by the instrumented code.
+///
+/// This is a combination of a TypeDescriptor (which is emitted as constant data
+/// as an operand to a handler function) and a ValueHandle (which is passed at
+/// runtime when a check failure occurs).
+class Value {
+ /// The type of the value.
+ const TypeDescriptor &Type;
+ /// The encoded value itself.
+ ValueHandle Val;
+
+ /// Is \c Val a (zero-extended) integer?
+ bool isInlineInt() const {
+ CHECK(getType().isIntegerTy());
+ const unsigned InlineBits = sizeof(ValueHandle) * 8;
+ const unsigned Bits = getType().getIntegerBitWidth();
+ return Bits <= InlineBits;
+ }
+
+ /// Is \c Val a (zero-extended) integer representation of a float?
+ bool isInlineFloat() const {
+ CHECK(getType().isFloatTy());
+ const unsigned InlineBits = sizeof(ValueHandle) * 8;
+ const unsigned Bits = getType().getFloatBitWidth();
+ return Bits <= InlineBits;
+ }
+
+public:
+ Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {}
+
+ const TypeDescriptor &getType() const { return Type; }
+
+ /// \brief Get this value as a signed integer.
+ SIntMax getSIntValue() const;
+
+ /// \brief Get this value as an unsigned integer.
+ UIntMax getUIntValue() const;
+
+ /// \brief Decode this value, which must be a positive or unsigned integer.
+ UIntMax getPositiveIntValue() const;
+
+ /// Is this an integer with value -1?
+ bool isMinusOne() const {
+ return getType().isSignedIntegerTy() && getSIntValue() == -1;
+ }
+
+ /// Is this a negative integer?
+ bool isNegative() const {
+ return getType().isSignedIntegerTy() && getSIntValue() < 0;
+ }
+
+ /// \brief Get this value as a floating-point quantity.
+ FloatMax getFloatValue() const;
+};
+
+} // namespace __ubsan
+
+#endif // UBSAN_VALUE_H
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index d0a494b467f..80e0139b483 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,498 @@
+2013-09-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/58341
+ * include/bits/stl_algobase.h (copy_backward): Fix documentation
+ per DR 1206.
+
+2013-09-05 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex_automaton.h: Add dummy node type. Rewrite
+ _StateSeq.
+ * include/bits/regex_automaton.tcc: Implement them.
+ * include/bits/regex_compiler.h: Rewrite _Compiler to use new
+ _StateSeq interfaces.
+ * include/bits/regex_compiler.tcc: Implement them.
+ * include/bits/regex_scanner.h: Add word boundry assertion token.
+ * include/bits/regex_scanner.tcc (_Scanner<>::_M_eat_escape_ecma):
+ Support word boundry.
+ * testsuite/28_regex/algorithms/regex_match/basic/
+ string_range_02_03.cc: Remove "xfail".
+ * testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc:
+ Likewise.
+ * testsuite/28_regex/algorithms/regex_match/extended/
+ string_range_02_03.cc: Likewise.
+ * testsuite/28_regex/algorithms/regex_match/extended/
+ cstring_questionmark.cc: Remove xfail and get correct length of
+ c-string.
+ * testsuite/28_regex/algorithms/regex_match/extended/
+ string_range_00_03.cc: Likewise.
+ * testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc:
+ New.
+ * testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc:
+ New.
+ * testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc: New.
+
+2013-09-03 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/58302
+ * include/bits/random.tcc (negative_binomial_distribution<>::
+ operator()(_UniformRandomNumberGenerator&, const param_type&)):
+ Fix typo in template argument.
+ * testsuite/26_numerics/random/negative_binomial_distribution/
+ operators/58302.cc: New.
+
+2013-09-02 Tim Shen <timshen91@gmail.com>
+
+ * regex_automaton.h: Rearrange _NFA's layout.
+ * include/bits/regex_compiler.h: Add _AnyMatcher and _CharMatcher.
+ Rearrange _BracketMatcher's layout.
+ (_BracketMatcher<>::_M_add_char): Use set instead of vector for
+ _M_char_set.
+ (_BracketMatcher<>::_M_add_collating_element): Likewise.
+ (_BracketMatcher<>::_M_make_range): Likewise.
+ * include/bits/regex_compiler.tcc (_Compiler<>::_M_atom): Use
+ apropriate constructors of matchers above.
+ * testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc:
+ New.
+ * testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc: New.
+ * testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc:
+ New.
+ * testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc:
+ New.
+ * testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc: New.
+ * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc:
+ New.
+ * testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc: New.
+
+2013-08-30 François Dumont <fdumont@gcc.gnu.org>
+
+ PR libstdc++/58148
+ * include/debug/functions.h (__foreign_iterator_aux4): Use
+ sequence const_pointer as common type to compare pointers. Add a
+ fallback overload in case pointers cannot be cast to sequence
+ const_pointer.
+ * testsuite/23_containers/vector/modifiers/insert/58148.cc: New.
+
+2013-08-30 François Dumont <fdumont@gcc.gnu.org>
+
+ PR libstdc++/58191
+ * include/debug/macros.h (__glibcxx_check_partitioned_lower): Add
+ __gnu_debug::__base calls on iterators passed to internal debug
+ check.
+ (__glibcxx_check_partitioned_lower_pred): Likewise.
+ (__glibcxx_check_partitioned_upper): Likewise.
+ (__glibcxx_check_partitioned_upper_pred): Likewise.
+ (__glibcxx_check_sorted): Likewise.
+ (__glibcxx_check_sorted_pred): Likewise.
+ (__glibcxx_check_sorted_set): Likewise.
+ (__glibcxx_check_sorted_set_pred): Likewise.
+ * include/debug/functions.h (__check_partitioned_lower):
+ Remove code to detect safe iterators.
+ (__check_partitioned_upper): Likewise.
+ (__check_sorted): Likewise.
+
+2013-08-29 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex.h (basic_regex<>::assign): Don't lose _M_traits.
+ (regex_iterator<>::regex_iterator): Return nullptr when regex_search
+ failed.
+ (regex_token_iterator<>::_M_end_of_seq): Should be defined true when
+ _M_result is(not isn't) nullptr.
+ * include/bits/regex_compiler.h: Store _Compiler::_M_traits by reference
+ instead of by value.
+ * include/bits/regex_executor.h (_DFSExecutor<>::_DFSExecutor): Add
+ _M_traits to _DFSExecutor.
+ * include/bits/regex_executor.tcc (__get_executor<>): Pass traits to
+ _DFSExecutor too.
+ * testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc:
+ New.
+ * testsuite/28_regex/iterators/regex_token_iterator/wchar_t/
+ wstring_02.cc: New.
+
+2013-08-26 Tim Shen <timshen91@gmail.com>
+
+ * include/Makefile.am: Add regex_scanner.{h,tcc}.
+ * include/Makefile.in: Regenerate.
+ * include/bits/regex.h (match_search): Handle the `__first == __last`
+ situation correctly.
+ * include/bits/regex_compiler.h: Move _Scanner...
+ * include/bits/regex_scanner.h: ...to here. New.
+ * include/bits/regex_compiler.tcc: Move _Scanner...
+ * include/bits/regex_scanner.tcc: ...to here, too. New.
+ * include/bits/regex_executor.tcc: Use value instead of reference for
+ submatch.
+ * include/std/regex: Add regex_scanner.h
+ * testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc: New.
+ * testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc: New.
+ * testsuite/28_regex/algorithms/regex_match/ecma/cstring_hex.cc: New.
+ * testsuite/28_regex/algorithms/regex_match/ecma/empty_range.cc: New.
+ * testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc: New.
+
+2013-08-22 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex.h: Replace 8 spaces in indentation with a tab.
+ * include/bits/regex_automaton.h: Same.
+ * include/bits/regex_automaton.tcc: Same.
+ * include/bits/regex_compiler.h: Same.
+ * include/bits/regex_compiler.tcc: Same.
+ * include/bits/regex_constants.h: Same.
+ * include/bits/regex_executor.h: Same.
+ * include/bits/regex_executor.tcc: Same.
+
+2013-08-22 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex.h: Executor caller.
+ * include/bits/regex_executor.h: Fix empty grouping problem.
+ * include/bits/regex_executor.tcc: Same.
+ * testsuite/28_regex/algorithms/regex_match/ecma/cstring_emptygroup.cc:
+ New.
+
+2013-08-20 Phil Muldoon <pmuldoon@redhat.com>
+
+ PR libstdc++/53477
+ http://sourceware.org/bugzilla/show_bug.cgi?id=15195
+
+ * python/libstdcxx/v6/printers.py (Printer.__call__): If a value
+ is a reference, fetch referenced value.
+ (RxPrinter.invoke): Ditto.
+ * testsuite/libstdc++-prettyprinters/cxx11.cc (main): Add -O0
+ flag. Add referenced value tests.
+
+2013-08-20 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex_constants.h: Add underlying `unsigned int` for
+ enum syntax_option_type.
+
+2013-08-18 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex_automaton.h: _S_opcode_backref.
+ * include/bits/regex_automaton.tcc: Backref automaton support.
+ * include/bits/regex_compiler.tcc: Parsing support.
+ * include/bits/regex_executor.h: Add _M_traits for _DFSExecutor.
+ * include/bits/regex_executor.tcc: Add _S_opcode_backref support.
+ * testsuite/28_regex/algorithms/regex_match/ecma/string_backref.cc: New.
+
+2013-08-16 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex.h (regex_traits<>::transform_primary):
+ Avoid past-the-end dereferences.
+
+2013-08-14 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/58163
+ * include/bits/basic_string.h (basic_string<>::operator[]): Fix
+ _GLIBCXX_DEBUG_PEDASSERT check vs C++11.
+ * include/ext/vstring.h: Likewise.
+ * testsuite/21_strings/basic_string/element_access/char/58163.cc:
+ New.
+ * testsuite/21_strings/basic_string/element_access/wchar_t/58163.cc:
+ Likewise.
+ * testsuite/ext/vstring/element_access/char/58163.cc: Likewise.
+ * testsuite/ext/vstring/element_access/wchar_t/58163.cc: Likewise.
+
+2013-08-14 Uros Bizjak <ubizjak@gmail.com>
+
+ * src/c++98/compatibility.cc (_ZTIe): Use
+ reinterpret_cast<const cast *> to avoid -Wcast-qual warnings.
+ (_ZTIPe): Ditto.
+ (ZTIPKe): Ditto.
+
+2013-08-09 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex_constants.h: Change syntax_option_type to enum
+ type.
+
+2013-08-08 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * include/bits/regex.h: Replace _A, _B, _C, _R by _Ap, _Bp, _Cp, _Rp.
+
+2013-08-08 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/bits/hashtable_policy.h (_Hashtable_alloc): New.
+ (_ReuseOrAllocNode, _AllocNode): Adapt to use latter rather than
+ _Hashtable.
+ (_Before_begin<>): Remove.
+ * include/bits/hashtable.h (_Hashtable): Inherit from
+ _Hashtable_alloc and adapt. Restore _M_before_begin field.
+ * src/c++11/hashtable_c++0x.cc: Add ext/alloc_traits.h include.
+ * python/libstdcxx/v6/printers.py (StdHashtableIterator): Adapt
+ access to hashtable before begin.
+ * testsuite/23_containers/unordered_set/
+ not_default_constructible_hash_neg.cc: Adapt dg-error line number.
+ * testsuite/23_containers/unordered_set/instantiation_neg.cc:
+ Likewise.
+
+2013-08-07 Tim Shen <timshen91@gmail.com>
+
+ * include/Makefile.am: Adjust to new files.
+ * include/Makefile.in: Regenerate.
+ * include/bits/regex.h: Adjust to new interfaces.
+ * include/bits/regex_automaton.h: New.
+ * include/bits/regex_automaton.tcc: New.
+ * include/bits/regex_compiler.h: Adjust to new files.
+ * include/bits/regex_compiler.tcc: New.
+ * include/bits/regex_constants.h: Tail spaces.
+ * include/bits/regex_error.h: Likewise.
+ * include/bits/regex_executor.h: New.
+ * include/bits/regex_executor.tcc: New.
+ * include/std/regex: Adjust to new files.
+ * testsuite/28_regex/algorithms/regex_match/extended/
+ string_dispatch_01.cc: Adjust to new interfaces.
+
+2013-08-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/ext/atomicity.h: Add #pragma GCC system_header.
+
+2013-08-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/58098
+ * include/bits/random.h (cauchy_distribution<>::min,
+ extreme_value_distribution<>::min, normal_distribution<>::min,
+ student_t_distribution<>::min): Fix.
+ * include/ext/random (normal_mv_distribution<>::min): Likewise.
+ * testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc:
+ Adjust.
+ testsuite/26_numerics/random/cauchy_distribution/cons/default.cc:
+ Likewise.
+ * testsuite/26_numerics/random/extreme_value_distribution/cons/
+ parms.cc: Likewise.
+ testsuite/26_numerics/random/extreme_value_distribution/cons/
+ default.cc: Likewise.
+ * testsuite/26_numerics/random/normal_distribution/cons/parms.cc:
+ Likewise.
+ * testsuite/26_numerics/random/normal_distribution/cons/default.cc:
+ Likewise.
+ * testsuite/26_numerics/random/student_t_distribution/cons/parms.cc:
+ Likewise.
+ * testsuite/26_numerics/random/student_t_distribution/cons/default.cc:
+ Likewise.
+ * testsuite/ext/random/normal_mv_distribution/cons/parms.cc: Likewise.
+ * testsuite/ext/random/normal_mv_distribution/cons/default.cc: Likewise.
+
+ * testsuite/26_numerics/random/exponential_distribution/cons/parms.cc:
+ Minor tweak.
+ * testsuite/26_numerics/random/exponential_distribution/cons/default.cc:
+ Likewise.
+
+ * testsuite/ext/von_mises_distribution/*: Move to...
+ * testsuite/ext/random/von_mises_distribution/*: ... here.
+ * testsuite/ext/triangular_distribution/*: Move to...
+ * testsuite/ext/random/triangular_distribution/*: ... here.
+
+2013-08-06 Caroline Tice <cmtice@google.com>
+
+ * fragment.am: Add XTEMPLATE_FLAGS.
+ * configure.ac: Add definitions for --enable-vtable-verify.
+ * acinclude.m4: Add --enable-vtable-verify and
+ --disable-vtable-verify; define --enable-vtable-verify; define
+ VTV_CXXFLAGS, VTV_PCH_CXXFLAGS and VTV_CXXLINKFLAGS.
+ * config/abi/pre/gnu.ver: Export symbols for vtable verification.
+ * libsupc++/Makefile.am: Define vtv_sources and add it to
+ libsupc___la_SOURCES and libsupc__convenience_la_SOURCES.
+ * libsupc++/vtv_stubs.cc: New file.
+ * include/Makefile.am: Add VTV_PCH_CXXFLAGS to PCHFLAGS.
+ * src/Makefile.am: Add VTV_CXXFLAGS to AM_CXXFLAGS; add
+ VTV_CXXLINKFLAGS to CXXLINK.
+ * src/c++98/Makefile.am: Comment out XTEMPLATE_FLAGS; add VTV_CXXFLAGS
+ to AM_CXXFLAGS; add VTV_CXXXLINKFLAGS to CXXLINK.
+ * src/C++11/Makefile.am: Ditto.
+ * doc/xml/manual/configure.xml: Add entry for --enable-vtable-verify.
+ * scripts/testsuite_flags.in: Add cxxvtvflags to Usage; cause
+ cxxvtvflags to use VTV_CXXFLAGS and VTV_CXXLINKFLAGS.
+ * testsuite/lib/libstdc++.exp: Add cxxvtvflags; add code to locate
+ libvtv if --enable-vtable-verify was used; set cxxvtvflags; add
+ cxxvtvflags to cxx_final.
+ * testsuite/18_support/bad_exception/23591_thread-1.c: Add
+ -fvtable-verify=none to compiler flags.
+ * testsuite/17_intro/freestanding.cc: Add -fvtable-verify=none
+ to compiler flags.
+ * configure: Regenerated.
+ * Makefile.in: Regenerated.
+ * python/Makefile.in: Regenerated.
+ * include/Makefile.in: Regenerated.
+ * libsupc++/Makefile.in: Regenerated.
+ * config.h.in: Regenerated.
+ * po/Makefile.in: Regenerated.
+ * src/Makefile.in: Regenerated.
+ * src/c++98/Makefile.in: Regenerated.
+ * src/c++11/Makefile.in: Regenerated.
+ * doc/Makefile.in: Regenerated.
+ * testsuite/Makefile.in: Regenerated.
+
+2013-08-06 Paolo Carlini <paolo.carlini@oracle.com>
+
+ Revert the last commit.
+
+2013-08-06 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/bits/hashtable_policy.h (_Hashtable_alloc): New.
+ (_ReuseOrAllocNode, _AllocNode): Adapt to use latter rather than
+ _Hashtable.
+ (_Before_begin<>): Remove.
+ * include/bits/hashtable.h (_Hashtable): Inherit from
+ _Hashtable_alloc and adapt. Restore _M_before_begin field.
+ * python/libstdcxx/v6/printers.py (StdHashtableIterator): Adapt
+ access to hashtable before begin.
+ * testsuite/23_containers/unordered_set/
+ not_default_constructible_hash_neg.cc: Adapt dg-error line number.
+ * testsuite/23_containers/unordered_set/instantiation_neg.cc:
+ Likewise.
+
+2013-08-03 Tim Shen <timshen91@gmail.com>
+
+ Implement bracket expression.
+ * include/bits/regex.h: Remove constexpr from "|=", etc.
+ * include/bits/regex_compiler.h: Parse bracket expression.
+ * include/bits/regex_nfa.h: _Comparator and _BracketMatcher(old
+ _RangeMatcher).
+ * include/bits/regex_nfa.tcc: Implement them.
+ * testsuite/28_regex/algorithms/regex_match/extended/53622.cc:
+ from regex_search to regex_match.
+ * testsuite/28_regex/algorithms/regex_match/extended/
+ cstring_bracket_01.cc: New.
+
+2013-08-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * include/debug/functions.h (__foreign_iterator_aux4):
+ Initialize __l and __ge.
+
+2013-08-02 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/58049
+ * include/debug/functions.h: Include <bits/move.h>; minor formatting
+ changes.
+ (__foreign_iterator_aux4): Declare __l and __ge constexpr.
+ * include/debug/safe_iterator.h (_Safe_iterator<>::operator->):
+ Use __addressof.
+ * include/debug/safe_local_iterator.h (_Safe_local_iterator<>::
+ operator->): Likewise.
+
+2013-08-01 François Dumont <fdumont@gcc.gnu.org>
+
+ PR libstdc++/57779
+ * include/debug/formatter.h (_Debug_msg_id): Add
+ __msg_insert_itself_range entry.
+ * include/debug/functions.h (_Insert_range_from_self_is_safe<>):
+ New, indicate container types supporting self range insertion in
+ GNU implementation.
+ (__foreign_iterator): New, check if an iterator points to a given
+ sequence.
+ * include/debug/macros.h (__glibcxx_check_insert_range): Add check
+ using __foreign_iterator.
+ (__gibcxx_check_insert_range_after): Likewise.
+ * include/debug/string (_Insert_range_from_self_is_safe<>):
+ Partially specialized to mark __gnu_debug::basic_string<> as
+ supporting self range insert.
+ * include/debug/list (_Insert_range_from_self_is_safe<>):
+ Partially specialized to mark std::list as supporting self range
+ insert if _GLIBCXX_DEBUG_PEDANTIC is not defined.
+ * include/debug/forward_list (_Insert_range_from_self_is_safe<>):
+ Likewise.
+ * src/c++11/debug.cc (_S_debug_messages): Add
+ __msg_insert_itself_range_entry message.
+ (_Error_formatter::_Parameter::_M_print_description): Display
+ iterator sequence address rather than sequence address when the
+ parameter type is an iterator.
+ (_Error_formatter::_M_print_word): Enhance behavior when
+ displaying a word with an appended '\n'.
+ * testsuite/util/debug/checks.h (check_insert4<>): New.
+ * testsuite/23_containers/deque/debug/insert5_neg.cc: New.
+ * testsuite/23_containers/vector/debug/insert5_neg.cc: Likewise.
+ * testsuite/23_containers/vector/debug/insert6_neg.cc: Likewise.
+ * testsuite/23_containers/vector/debug/57779_neg.cc: Likewise.
+ * testsuite/23_containers/list/debug/insert5_neg.cc: Likewise.
+ * testsuite/23_containers/forward_list/debug/insert_after4_neg.cc:
+ Likewise.
+
+2013-08-01 Fabien Chêne <fabien@gcc.gnu.org>
+
+ PR c++/54537
+ * include/tr1/cmath: Remove pow(double,double) overload, remove a
+ duplicated comment about DR 550. Add a comment to explain the
+ issue.
+ * testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc: New.
+
+2013-07-31 Tim Shen <timshen91@gmail.com>
+
+ Thompson matcher refactored. Fix grouping problem.
+ * include/bits/regex.h: Use a dispatcher _M_get_matcher().
+ * include/bits/regex_compiler.h: Tweak for auto switching.
+ * include/bits/regex_grep_matcher.h: Class structure.
+ * include/bits/regex_grep_matcher.tcc: _BFSMatcher(Thompson
+ matcher) refactoring.
+ * include/bits/regex_nfa.h: Change _Results's interfaces.
+ * include/std/regex: Includes <map> and <queue>.
+ * testsuite/28_regex/algorithms/regex_match/extended/53622.cc:
+ For both matchers.
+ * testsuite/28_regex/algorithms/regex_match/extended/57173.cc:
+ For both matchers.
+ * testsuite/28_regex/algorithms/regex_match/extended/
+ string_dispatch_01.cc: New.
+
+2013-07-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR libstdc++/56627
+ * include/bits/stl_bvector.h: Use friend struct hash intead of
+ friend class hash to work around useless warnings produced by
+ some compilers.
+ * include/std/bitset: Likewise.
+
+2013-07-31 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * src/c++11/functexcept.cc: Do not include the whole <regex>.
+ * src/c++11/regex.cc: Likewise.
+
+2013-07-31 Tim Shen <timshen91@gmail.com>
+
+ Revert last commit.
+
+2013-07-31 Tim Shen <timshen91@gmail.com>
+
+ Thompson matcher refactored. Fix grouping problem.
+ * include/bits/regex.h: Use a dispatcher _M_get_matcher().
+ * include/bits/regex_compiler.h: Tweak for auto switching.
+ * include/bits/regex_grep_matcher.h: Class structure.
+ * include/bits/regex_grep_matcher.tcc: _BFSMatcher(Thompson
+ matcher) refactoring.
+ * include/bits/regex_nfa.h: Change _Results's interfaces.
+ * include/std/regex: Includes <map> and <queue>.
+ * testsuite/28_regex/algorithms/regex_match/extended/53622.cc:
+ For both matchers.
+ * testsuite/28_regex/algorithms/regex_match/extended/57173.cc:
+ For both matchers.
+ * testsuite/28_regex/algorithms/regex_match/extended/
+ string_dispatch_01.cc: New.
+
+2013-07-30 Paolo Carlini <paolo.carlini@oracle.com>
+
+ Revert last commit.
+
+2013-07-30 Tim Shen <timshen91@gmail.com>
+
+ Thompson matcher refactored. Fix grouping problem.
+ * include/bits/regex.h: Use a dispatcher _M_get_matcher().
+ * include/bits/regex_compiler.h: Tweak for auto switching.
+ * include/bits/regex_grep_matcher.h: Class structure.
+ * include/bits/regex_grep_matcher.tcc: _BFSMatcher(Thompson
+ matcher) refactoring.
+ * include/bits/regex_nfa.h: Change _Results's interfaces.
+ * include/std/regex: Includes <map> and <queue>.
+ * testsuite/28_regex/algorithms/regex_match/extended/53622.cc:
+ For both matchers.
+ * testsuite/28_regex/algorithms/regex_match/extended/57173.cc:
+ For both matchers.
+ * testsuite/28_regex/algorithms/regex_match/extended/
+ string_dispatch_01.cc: New.
+
+2013-07-29 Nathan Froyd <froydnj@gcc.gnu.org>
+
+ * include/std/atomic (compare_exchange_weak, compare_exchange_strong):
+ Add call to __cmpexch_failure_order.
+ * testsuite/util/testsuite_common_types.h
+ (compare_exchange_order_lowering): New generator.
+ * testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc:
+ New test.
+
2013-07-25 Paolo Carlini <paolo.carlini@oracle.com>
* include/std/complex (pow(const complex<>&, int)): Enable in
diff --git a/libstdc++-v3/Makefile.in b/libstdc++-v3/Makefile.in
index e541f1e516e..2af823acd42 100644
--- a/libstdc++-v3/Makefile.in
+++ b/libstdc++-v3/Makefile.in
@@ -225,6 +225,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -321,6 +324,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
diff --git a/libstdc++-v3/acinclude.m4 b/libstdc++-v3/acinclude.m4
index d68768ed150..72b90a80252 100644
--- a/libstdc++-v3/acinclude.m4
+++ b/libstdc++-v3/acinclude.m4
@@ -2285,6 +2285,38 @@ AC_DEFUN([GLIBCXX_ENABLE_EXTERN_TEMPLATE], [
])
dnl
+dnl Use vtable verification.
+dnl
+dnl --enable-vtable-verify defines _GLIBCXX_VTABLE_VERIFY to 1
+dnl --disable-vtable-verify defines _GLIBCXX_VTABLE_VERIFY to 0
+
+dnl + Usage: GLIBCXX_ENABLE_VTABLE_VERIFY[(DEFAULT)]
+dnl Where DEFAULT is `yes' or `no'.
+dnl
+AC_DEFUN([GLIBCXX_ENABLE_VTABLE_VERIFY], [
+
+ GLIBCXX_ENABLE(vtable-verify,$1,,[enable vtable verify])
+
+ AC_MSG_CHECKING([for vtable verify support])
+ AC_MSG_RESULT([$enable_vtable_verify])
+
+ if test $enable_vtable_verify = yes; then
+ VTV_CXXFLAGS="-fvtable-verify=std -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end"
+ VTV_PCH_CXXFLAGS="-fvtable-verify=std"
+ VTV_CXXLINKFLAGS="-L${toplevel_builddir}/libvtv/.libs -Wl,--rpath -Wl,${toplevel_builddir}/libvtv/.libs"
+ else
+ VTV_CXXFLAGS=
+ VTV_PCH_CXXFLAGS=
+ VTV_CXXLINKFLAGS=
+ fi
+
+ AC_SUBST(VTV_CXXFLAGS)
+ AC_SUBST(VTV_PCH_CXXFLAGS)
+ AC_SUBST(VTV_CXXLINKFLAGS)
+ GLIBCXX_CONDITIONAL(ENABLE_VTABLE_VERIFY, test $enable_vtable_verify = yes)
+])
+
+dnl
dnl Check for parallel mode pre-requisites, including OpenMP support.
dnl
dnl + Usage: GLIBCXX_ENABLE_PARALLEL
diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 9e1f4da1589..8972fcfca88 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1572,6 +1572,16 @@ CXXABI_1.3.8 {
__cxa_throw_bad_array_length;
_Z*St16bad_array_length*;
+
+ # Virtual table verification stub functions.
+ _Z17__VLTRegisterPair*;
+ _Z22__VLTRegisterPairDebug*;
+ _Z16__VLTRegisterSet*;
+ _Z21__VLTRegisterSetDebug*;
+ _Z24__VLTVerifyVtablePointer*;
+ _Z29__VLTVerifyVtablePointerDebug*;
+ __VLTChangePermission;
+
} CXXABI_1.3.7;
# Symbols in the support library (libsupc++) supporting transactional memory.
diff --git a/libstdc++-v3/configure b/libstdc++-v3/configure
index 71ec2473e43..7459bcdf2ce 100755
--- a/libstdc++-v3/configure
+++ b/libstdc++-v3/configure
@@ -664,6 +664,11 @@ LIBICONV
OPT_LDFLAGS
SECTION_LDFLAGS
GLIBCXX_LIBS
+ENABLE_VTABLE_VERIFY_FALSE
+ENABLE_VTABLE_VERIFY_TRUE
+VTV_CXXLINKFLAGS
+VTV_PCH_CXXFLAGS
+VTV_CXXFLAGS
ENABLE_WERROR_FALSE
ENABLE_WERROR_TRUE
ENABLE_PYTHONDIR_FALSE
@@ -866,6 +871,7 @@ enable_fully_dynamic_string
enable_extern_template
with_python_dir
enable_werror
+enable_vtable_verify
enable_libstdcxx_time
enable_tls
enable_rpath
@@ -1558,6 +1564,7 @@ Optional Features:
--enable-extern-template
enable extern template [default=yes]
--enable-werror turns on -Werror [default=yes]
+ --enable-vtable-verify enable vtable verify [default=no]
--enable-libstdcxx-time[=KIND]
use KIND for check type [default=auto]
--enable-tls Use thread-local storage [default=yes]
@@ -11513,7 +11520,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11516 "configure"
+#line 11523 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -11619,7 +11626,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 11622 "configure"
+#line 11629 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -14906,6 +14913,12 @@ esac
+if test "$enable_vtable_verify" = yes; then
+ predep_objects_CXX="${predep_objects_CXX} ${glibcxx_builddir}/../libgcc/vtv_start.o"
+ postdep_objects_CXX="${postdep_objects_CXX} ${glibcxx_builddir}/../libgcc/vtv_end.o"
+fi
+
+
# libtool variables for C++ shared and position-independent compiles.
#
# Use glibcxx_lt_pic_flag to designate the automake variable
@@ -15033,7 +15046,7 @@ fi
#
# Fake what AC_TRY_COMPILE does. XXX Look at redoing this new-style.
cat > conftest.$ac_ext << EOF
-#line 15036 "configure"
+#line 15049 "configure"
struct S { ~S(); };
void bar();
void foo()
@@ -15383,7 +15396,7 @@ $as_echo "$glibcxx_cv_atomic_long_long" >&6; }
# Fake what AC_TRY_COMPILE does.
cat > conftest.$ac_ext << EOF
-#line 15386 "configure"
+#line 15399 "configure"
int main()
{
typedef bool atomic_type;
@@ -15418,7 +15431,7 @@ $as_echo "$glibcxx_cv_atomic_bool" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15421 "configure"
+#line 15434 "configure"
int main()
{
typedef short atomic_type;
@@ -15453,7 +15466,7 @@ $as_echo "$glibcxx_cv_atomic_short" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15456 "configure"
+#line 15469 "configure"
int main()
{
// NB: _Atomic_word not necessarily int.
@@ -15489,7 +15502,7 @@ $as_echo "$glibcxx_cv_atomic_int" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15492 "configure"
+#line 15505 "configure"
int main()
{
typedef long long atomic_type;
@@ -15568,7 +15581,7 @@ $as_echo "$as_me: WARNING: Performance of certain classes will degrade as a resu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 15571 "configure"
+#line 15584 "configure"
int main()
{
_Decimal32 d1;
@@ -15610,7 +15623,7 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
# unnecessary for this test.
cat > conftest.$ac_ext << EOF
-#line 15613 "configure"
+#line 15626 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -15644,7 +15657,7 @@ $as_echo "$enable_int128" >&6; }
rm -f conftest*
cat > conftest.$ac_ext << EOF
-#line 15647 "configure"
+#line 15660 "configure"
template<typename T1, typename T2>
struct same
{ typedef T2 type; };
@@ -17379,6 +17392,42 @@ $as_echo "$enable_werror" >&6; }
+
+ # Check whether --enable-vtable-verify was given.
+if test "${enable_vtable_verify+set}" = set; then :
+ enableval=$enable_vtable_verify;
+ case "$enableval" in
+ yes|no) ;;
+ *) as_fn_error "Argument to enable/disable vtable-verify must be yes or no" "$LINENO" 5 ;;
+ esac
+
+else
+ enable_vtable_verify=no
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for vtable verify support" >&5
+$as_echo_n "checking for vtable verify support... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_vtable_verify" >&5
+$as_echo "$enable_vtable_verify" >&6; }
+
+ if test $enable_vtable_verify = yes; then
+ VTV_CXXFLAGS="-fvtable-verify=std -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end"
+ VTV_PCH_CXXFLAGS="-fvtable-verify=std"
+ VTV_CXXLINKFLAGS="-L${toplevel_builddir}/libvtv/.libs -Wl,--rpath -Wl,${toplevel_builddir}/libvtv/.libs"
+ else
+ VTV_CXXFLAGS=
+ VTV_PCH_CXXFLAGS=
+ VTV_CXXLINKFLAGS=
+ fi
+
+
+
+
+
+
+
# Checks for operating systems support that doesn't require linking.
@@ -72960,6 +73009,15 @@ else
fi
+ if test $enable_vtable_verify = yes; then
+ ENABLE_VTABLE_VERIFY_TRUE=
+ ENABLE_VTABLE_VERIFY_FALSE='#'
+else
+ ENABLE_VTABLE_VERIFY_TRUE='#'
+ ENABLE_VTABLE_VERIFY_FALSE=
+fi
+
+
if test $enable_symvers != no; then
ENABLE_SYMVERS_TRUE=
ENABLE_SYMVERS_FALSE='#'
@@ -73403,6 +73461,10 @@ if test -z "${ENABLE_WERROR_TRUE}" && test -z "${ENABLE_WERROR_FALSE}"; then
as_fn_error "conditional \"ENABLE_WERROR\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${ENABLE_VTABLE_VERIFY_TRUE}" && test -z "${ENABLE_VTABLE_VERIFY_FALSE}"; then
+ as_fn_error "conditional \"ENABLE_VTABLE_VERIFY\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
if test -z "${ENABLE_SYMVERS_TRUE}" && test -z "${ENABLE_SYMVERS_FALSE}"; then
as_fn_error "conditional \"ENABLE_SYMVERS\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
diff --git a/libstdc++-v3/configure.ac b/libstdc++-v3/configure.ac
index f6ba176d2a8..dd13b011f97 100644
--- a/libstdc++-v3/configure.ac
+++ b/libstdc++-v3/configure.ac
@@ -97,6 +97,12 @@ ACX_LT_HOST_FLAGS
AC_SUBST(enable_shared)
AC_SUBST(enable_static)
+if test "$enable_vtable_verify" = yes; then
+ predep_objects_CXX="${predep_objects_CXX} ${glibcxx_builddir}/../libgcc/vtv_start.o"
+ postdep_objects_CXX="${postdep_objects_CXX} ${glibcxx_builddir}/../libgcc/vtv_end.o"
+fi
+
+
# libtool variables for C++ shared and position-independent compiles.
#
# Use glibcxx_lt_pic_flag to designate the automake variable
@@ -168,6 +174,7 @@ GLIBCXX_ENABLE_FULLY_DYNAMIC_STRING([no])
GLIBCXX_ENABLE_EXTERN_TEMPLATE([yes])
GLIBCXX_ENABLE_PYTHON
GLIBCXX_ENABLE_WERROR([yes])
+GLIBCXX_ENABLE_VTABLE_VERIFY([no])
# Checks for operating systems support that doesn't require linking.
GLIBCXX_CHECK_STDIO_PROTO
diff --git a/libstdc++-v3/doc/Makefile.in b/libstdc++-v3/doc/Makefile.in
index f2d3de857fc..ba7fd1bf8a2 100644
--- a/libstdc++-v3/doc/Makefile.in
+++ b/libstdc++-v3/doc/Makefile.in
@@ -197,6 +197,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
@@ -303,6 +306,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
diff --git a/libstdc++-v3/doc/xml/manual/configure.xml b/libstdc++-v3/doc/xml/manual/configure.xml
index 05f6ebabefa..cf0989720fa 100644
--- a/libstdc++-v3/doc/xml/manual/configure.xml
+++ b/libstdc++-v3/doc/xml/manual/configure.xml
@@ -382,6 +382,18 @@
</para>
</listitem></varlistentry>
+ <varlistentry><term><code>--enable-vtable-verify</code>[default]</term>
+ <listitem>
+ <para>Use <code>-fvtable-verify=std</code> to compile the C++
+ runtime with instrumentation for vtable verification. All virtual
+ functions in the standard library will be verified at runtime.
+ Types impacted include <classname>locale</classname> and
+ <classname>iostream</classname>, and others. Disabling means that
+ the C++ runtime is compiled without support for vtable
+ verification. By default, this option is off.
+ </para>
+ </listitem></varlistentry>
+
</variablelist>
</section>
diff --git a/libstdc++-v3/fragment.am b/libstdc++-v3/fragment.am
index 5b1d503a6d7..0036ae8004a 100644
--- a/libstdc++-v3/fragment.am
+++ b/libstdc++-v3/fragment.am
@@ -19,6 +19,12 @@ else
WERROR_FLAG=
endif
+if ENABLE_EXTERN_TEMPLATE
+XTEMPLATE_FLAGS = -fno-implicit-templates
+else
+XTEMPLATE_FLAGS =
+endif
+
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
CONFIG_CXXFLAGS = \
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 801a8858087..0bceb5776a5 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -126,14 +126,16 @@ bits_headers = \
${bits_srcdir}/random.tcc \
${bits_srcdir}/range_access.h \
${bits_srcdir}/regex.h \
- ${bits_srcdir}/regex_compiler.h \
${bits_srcdir}/regex_constants.h \
- ${bits_srcdir}/regex_cursor.h \
${bits_srcdir}/regex_error.h \
- ${bits_srcdir}/regex_grep_matcher.h \
- ${bits_srcdir}/regex_grep_matcher.tcc \
- ${bits_srcdir}/regex_nfa.h \
- ${bits_srcdir}/regex_nfa.tcc \
+ ${bits_srcdir}/regex_scanner.h \
+ ${bits_srcdir}/regex_scanner.tcc \
+ ${bits_srcdir}/regex_automaton.h \
+ ${bits_srcdir}/regex_automaton.tcc \
+ ${bits_srcdir}/regex_compiler.h \
+ ${bits_srcdir}/regex_compiler.tcc \
+ ${bits_srcdir}/regex_executor.h \
+ ${bits_srcdir}/regex_executor.tcc \
${bits_srcdir}/stream_iterator.h \
${bits_srcdir}/streambuf_iterator.h \
${bits_srcdir}/shared_ptr.h \
@@ -893,7 +895,7 @@ pch_output_dirs = \
${pch1_output_builddir} ${pch2_output_builddir} ${pch3_output_builddir}
pch_output_anchors = \
${pch1_output_anchor} ${pch2_output_anchor} ${pch3_output_anchor}
-PCHFLAGS=-x c++-header -nostdinc++ $(CXXFLAGS)
+PCHFLAGS=-x c++-header -nostdinc++ $(CXXFLAGS) $(VTV_PCH_CXXFLAGS)
if GLIBCXX_BUILD_PCH
pch_build = ${pch_output}
else
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 31aa0aa60b3..458b08c17fb 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -197,6 +197,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -293,6 +296,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
@@ -410,14 +415,16 @@ bits_headers = \
${bits_srcdir}/random.tcc \
${bits_srcdir}/range_access.h \
${bits_srcdir}/regex.h \
- ${bits_srcdir}/regex_compiler.h \
${bits_srcdir}/regex_constants.h \
- ${bits_srcdir}/regex_cursor.h \
${bits_srcdir}/regex_error.h \
- ${bits_srcdir}/regex_grep_matcher.h \
- ${bits_srcdir}/regex_grep_matcher.tcc \
- ${bits_srcdir}/regex_nfa.h \
- ${bits_srcdir}/regex_nfa.tcc \
+ ${bits_srcdir}/regex_scanner.h \
+ ${bits_srcdir}/regex_scanner.tcc \
+ ${bits_srcdir}/regex_automaton.h \
+ ${bits_srcdir}/regex_automaton.tcc \
+ ${bits_srcdir}/regex_compiler.h \
+ ${bits_srcdir}/regex_compiler.tcc \
+ ${bits_srcdir}/regex_executor.h \
+ ${bits_srcdir}/regex_executor.tcc \
${bits_srcdir}/stream_iterator.h \
${bits_srcdir}/streambuf_iterator.h \
${bits_srcdir}/shared_ptr.h \
@@ -1169,7 +1176,7 @@ pch_output_dirs = \
pch_output_anchors = \
${pch1_output_anchor} ${pch2_output_anchor} ${pch3_output_anchor}
-PCHFLAGS = -x c++-header -nostdinc++ $(CXXFLAGS)
+PCHFLAGS = -x c++-header -nostdinc++ $(CXXFLAGS) $(VTV_PCH_CXXFLAGS)
@GLIBCXX_BUILD_PCH_FALSE@pch_build =
@GLIBCXX_BUILD_PCH_TRUE@pch_build = ${pch_output}
diff --git a/libstdc++-v3/include/bits/basic_string.h b/libstdc++-v3/include/bits/basic_string.h
index cbea5664e71..c8723ededd9 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -842,10 +842,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reference
operator[](size_type __pos)
{
- // allow pos == size() as v3 extension:
+ // Allow pos == size() both in C++98 mode, as v3 extension,
+ // and in C++11 mode.
_GLIBCXX_DEBUG_ASSERT(__pos <= size());
- // but be strict in pedantic mode:
- _GLIBCXX_DEBUG_PEDASSERT(__pos < size());
+ // In pedantic mode be strict in C++98 mode.
+ _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L || __pos < size());
_M_leak();
return _M_data()[__pos];
}
diff --git a/libstdc++-v3/include/bits/hashtable.h b/libstdc++-v3/include/bits/hashtable.h
index 44ce3b30ef8..43c89b1ce51 100644
--- a/libstdc++-v3/include/bits/hashtable.h
+++ b/libstdc++-v3/include/bits/hashtable.h
@@ -103,7 +103,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* Each _Hashtable data structure has:
*
* - _Bucket[] _M_buckets
- * - _Hash_node_base _M_bbegin
+ * - _Hash_node_base _M_before_begin
* - size_type _M_bucket_count
* - size_type _M_element_count
*
@@ -181,12 +181,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
public __detail::_Rehash_base<_Key, _Value, _Alloc, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, _Traits>,
public __detail::_Equality<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>
+ _H1, _H2, _Hash, _RehashPolicy, _Traits>,
+ private __detail::_Hashtable_alloc<
+ typename __alloctr_rebind<_Alloc,
+ __detail::_Hash_node<_Value,
+ _Traits::__hash_cached::value> >::__type>
{
- typedef std::allocator_traits<_Alloc> _Alloc_traits;
- typedef typename _Alloc_traits::template rebind_alloc<_Value>
- _Value_alloc_type;
- typedef __gnu_cxx::__alloc_traits<_Value_alloc_type> _Value_alloc_traits;
+ using __traits_type = _Traits;
+ using __hash_cached = typename __traits_type::__hash_cached;
+ using __node_type = __detail::_Hash_node<_Value, __hash_cached::value>;
+ using __node_alloc_type =
+ typename __alloctr_rebind<_Alloc, __node_type>::__type;
+
+ using __hashtable_alloc = __detail::_Hashtable_alloc<__node_alloc_type>;
+
+ using __value_alloc_traits =
+ typename __hashtable_alloc::__value_alloc_traits;
+ using __node_alloc_traits =
+ typename __hashtable_alloc::__node_alloc_traits;
+ using __node_base = typename __hashtable_alloc::__node_base;
+ using __bucket_type = typename __hashtable_alloc::__bucket_type;
public:
typedef _Key key_type;
@@ -196,8 +210,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// mapped_type, if present, comes from _Map_base.
// hasher, if present, comes from _Hash_code_base/_Hashtable_base.
- typedef typename _Value_alloc_traits::pointer pointer;
- typedef typename _Value_alloc_traits::const_pointer const_pointer;
+ typedef typename __value_alloc_traits::pointer pointer;
+ typedef typename __value_alloc_traits::const_pointer const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
@@ -205,8 +219,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __rehash_type = _RehashPolicy;
using __rehash_state = typename __rehash_type::_State;
- using __traits_type = _Traits;
- using __hash_cached = typename __traits_type::__hash_cached;
using __constant_iterators = typename __traits_type::__constant_iterators;
using __unique_keys = typename __traits_type::__unique_keys;
@@ -221,9 +233,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __hash_code_base = typename __hashtable_base::__hash_code_base;
using __hash_code = typename __hashtable_base::__hash_code;
- using __node_type = typename __hashtable_base::__node_type;
- using __node_base = typename __hashtable_base::__node_base;
- using __bucket_type = typename __hashtable_base::__bucket_type;
using __ireturn_type = typename __hashtable_base::__ireturn_type;
using __map_base = __detail::_Map_base<_Key, _Value, _Alloc, _ExtractKey,
@@ -240,9 +249,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_RehashPolicy, _Traits>;
using __reuse_or_alloc_node_type =
- __detail::_ReuseOrAllocNode<_Key, _Value, _Alloc,
- _ExtractKey, _Equal, _H1, _H2, _Hash,
- _RehashPolicy, _Traits>;
+ __detail::_ReuseOrAllocNode<__node_alloc_type>;
// Metaprogramming for picking apart hash caching.
template<typename _Cond>
@@ -309,18 +316,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool _Constant_iteratorsa, bool _Unique_keysa>
friend struct __detail::_Insert;
- template<typename _Keya, typename _Valuea, typename _Alloca,
- typename _ExtractKeya, typename _Equala,
- typename _H1a, typename _H2a, typename _Hasha,
- typename _RehashPolicya, typename _Traitsa>
- friend struct __detail::_ReuseOrAllocNode;
-
- template<typename _Keya, typename _Valuea, typename _Alloca,
- typename _ExtractKeya, typename _Equala,
- typename _H1a, typename _H2a, typename _Hasha,
- typename _RehashPolicya, typename _Traitsa>
- friend struct __detail::_AllocNode;
-
public:
using size_type = typename __hashtable_base::size_type;
using difference_type = typename __hashtable_base::difference_type;
@@ -333,60 +328,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const_local_iterator;
private:
- typedef typename _Alloc_traits::template rebind_alloc<__node_type>
- _Node_alloc_type;
- // Use __gnu_cxx to benefit from _S_always_equal and al.
- typedef __gnu_cxx::__alloc_traits<_Node_alloc_type> _Node_alloc_traits;
-
- typedef
- typename _Alloc_traits::template rebind_alloc<__bucket_type>
- _Bucket_alloc_type;
- typedef std::allocator_traits<_Bucket_alloc_type> _Bucket_alloc_traits;
-
- using __before_begin = __detail::_Before_begin<_Node_alloc_type>;
-
__bucket_type* _M_buckets;
size_type _M_bucket_count;
- __before_begin _M_bbegin;
+ __node_base _M_before_begin;
size_type _M_element_count;
_RehashPolicy _M_rehash_policy;
- _Node_alloc_type&
- _M_node_allocator()
- { return _M_bbegin; }
-
- const _Node_alloc_type&
- _M_node_allocator() const
- { return _M_bbegin; }
-
- __node_base&
- _M_before_begin()
- { return _M_bbegin._M_node; }
-
- const __node_base&
- _M_before_begin() const
- { return _M_bbegin._M_node; }
+ __hashtable_alloc&
+ _M_base_alloc() { return *this; }
- template<typename... _Args>
- __node_type*
- _M_allocate_node(_Args&&... __args);
-
- void
- _M_deallocate_node(__node_type* __n);
-
- // Deallocate the linked list of nodes pointed to by __n
- void
- _M_deallocate_nodes(__node_type* __n);
-
- __bucket_type*
- _M_allocate_buckets(size_type __n);
-
- void
- _M_deallocate_buckets(__bucket_type*, size_type __n);
+ using __hashtable_alloc::_M_deallocate_buckets;
void
_M_deallocate_buckets()
- { _M_deallocate_buckets(_M_buckets, _M_bucket_count); }
+ { this->_M_deallocate_buckets(_M_buckets, _M_bucket_count); }
// Gets bucket begin, deals with the fact that non-empty buckets contain
// their before begin node.
@@ -395,7 +350,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__node_type*
_M_begin() const
- { return static_cast<__node_type*>(_M_before_begin()._M_nxt); }
+ { return static_cast<__node_type*>(_M_before_begin._M_nxt); }
template<typename _NodeGenerator>
void
@@ -477,11 +432,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Hashtable&
operator=(_Hashtable&& __ht)
- noexcept(_Node_alloc_traits::_S_nothrow_move())
+ noexcept(__node_alloc_traits::_S_nothrow_move())
{
constexpr bool __move_storage =
- _Node_alloc_traits::_S_propagate_on_move_assign()
- || _Node_alloc_traits::_S_always_equal();
+ __node_alloc_traits::_S_propagate_on_move_assign()
+ || __node_alloc_traits::_S_always_equal();
_M_move_assign(std::move(__ht),
integral_constant<bool, __move_storage>());
return *this;
@@ -491,7 +446,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator=(initializer_list<value_type> __l)
{
__reuse_or_alloc_node_type __roan(_M_begin(), *this);
- _M_before_begin()._M_nxt = nullptr;
+ _M_before_begin._M_nxt = nullptr;
clear();
this->_M_insert_range(__l.begin(), __l.end(), __roan);
return *this;
@@ -501,7 +456,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
swap(_Hashtable&)
- noexcept(_Node_alloc_traits::_S_nothrow_swap());
+ noexcept(__node_alloc_traits::_S_nothrow_swap());
// Basic container operations
iterator
@@ -538,11 +493,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
allocator_type
get_allocator() const noexcept
- { return allocator_type(_M_node_allocator()); }
+ { return allocator_type(this->_M_node_allocator()); }
size_type
max_size() const noexcept
- { return _Node_alloc_traits::max_size(_M_node_allocator()); }
+ { return __node_alloc_traits::max_size(this->_M_node_allocator()); }
// Observers
key_equal
@@ -807,101 +762,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Alloc, typename _ExtractKey, typename _Equal,
typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
typename _Traits>
- template<typename... _Args>
- typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>::__node_type*
- _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>::
- _M_allocate_node(_Args&&... __args)
- {
- auto __nptr = _Node_alloc_traits::allocate(_M_node_allocator(), 1);
- __node_type* __n = std::__addressof(*__nptr);
- __try
- {
- _Value_alloc_type __a(_M_node_allocator());
- ::new ((void*)__n) __node_type();
- _Value_alloc_traits::construct(__a, __n->_M_valptr(),
- std::forward<_Args>(__args)...);
- return __n;
- }
- __catch(...)
- {
- _Node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
- __throw_exception_again;
- }
- }
-
- template<typename _Key, typename _Value,
- typename _Alloc, typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
- typename _Traits>
- void
- _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>::
- _M_deallocate_node(__node_type* __n)
- {
- typedef typename _Node_alloc_traits::pointer _Ptr;
- auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n);
- _Value_alloc_type __a(_M_node_allocator());
- _Value_alloc_traits::destroy(__a, __n->_M_valptr());
- __n->~__node_type();
- _Node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
- }
-
- template<typename _Key, typename _Value,
- typename _Alloc, typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
- typename _Traits>
- void
- _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>::
- _M_deallocate_nodes(__node_type* __n)
- {
- while (__n)
- {
- __node_type* __tmp = __n;
- __n = __n->_M_next();
- _M_deallocate_node(__tmp);
- }
- }
-
- template<typename _Key, typename _Value,
- typename _Alloc, typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
- typename _Traits>
- typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>::__bucket_type*
- _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>::
- _M_allocate_buckets(size_type __n)
- {
- _Bucket_alloc_type __alloc(_M_node_allocator());
-
- auto __ptr = _Bucket_alloc_traits::allocate(__alloc, __n);
- __bucket_type* __p = std::__addressof(*__ptr);
- __builtin_memset(__p, 0, __n * sizeof(__bucket_type));
- return __p;
- }
-
- template<typename _Key, typename _Value,
- typename _Alloc, typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
- typename _Traits>
- void
- _Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
- _H1, _H2, _Hash, _RehashPolicy, _Traits>::
- _M_deallocate_buckets(__bucket_type* __bkts, size_type __n)
- {
- typedef typename _Bucket_alloc_traits::pointer _Ptr;
- auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__bkts);
- _Bucket_alloc_type __alloc(_M_node_allocator());
- _Bucket_alloc_traits::deallocate(__alloc, __ptr, __n);
- }
-
- template<typename _Key, typename _Value,
- typename _Alloc, typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash, typename _RehashPolicy,
- typename _Traits>
typename _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
_Equal, _H1, _H2, _Hash, _RehashPolicy,
_Traits>::__node_type*
@@ -926,12 +786,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: __hashtable_base(__exk, __h1, __h2, __h, __eq),
__map_base(),
__rehash_base(),
- _M_bbegin(__a),
+ __hashtable_alloc(__node_alloc_type(__a)),
_M_element_count(0),
_M_rehash_policy()
{
_M_bucket_count = _M_rehash_policy._M_next_bkt(__bucket_hint);
- _M_buckets = _M_allocate_buckets(_M_bucket_count);
+ _M_buckets = this->_M_allocate_buckets(_M_bucket_count);
}
template<typename _Key, typename _Value,
@@ -949,7 +809,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: __hashtable_base(__exk, __h1, __h2, __h, __eq),
__map_base(),
__rehash_base(),
- _M_bbegin(__a),
+ __hashtable_alloc(__node_alloc_type(__a)),
_M_element_count(0),
_M_rehash_policy()
{
@@ -959,7 +819,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::max(_M_rehash_policy._M_bkt_for_elements(__nb_elems),
__bucket_hint));
- _M_buckets = _M_allocate_buckets(_M_bucket_count);
+ _M_buckets = this->_M_allocate_buckets(_M_bucket_count);
__try
{
for (; __f != __l; ++__f)
@@ -987,15 +847,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (&__ht == this)
return *this;
- if (_Node_alloc_traits::_S_propagate_on_copy_assign())
+ if (__node_alloc_traits::_S_propagate_on_copy_assign())
{
auto& __this_alloc = this->_M_node_allocator();
auto& __that_alloc = __ht._M_node_allocator();
- if (!_Node_alloc_traits::_S_always_equal()
+ if (!__node_alloc_traits::_S_always_equal()
&& __this_alloc != __that_alloc)
{
// Replacement allocator cannot free existing storage.
- _M_deallocate_nodes(_M_begin());
+ this->_M_deallocate_nodes(_M_begin());
if (__builtin_expect(_M_bucket_count != 0, true))
_M_deallocate_buckets();
_M_reset();
@@ -1008,7 +868,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_M_assign(__ht,
[this](const __node_type* __n)
- { return _M_allocate_node(__n->_M_v()); });
+ { return this->_M_allocate_node(__n->_M_v()); });
}
__catch(...)
{
@@ -1030,7 +890,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (_M_bucket_count != __ht._M_bucket_count)
{
__former_buckets = _M_buckets;
- _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
+ _M_buckets = this->_M_allocate_buckets(__ht._M_bucket_count);
_M_bucket_count = __ht._M_bucket_count;
}
else
@@ -1043,12 +903,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_element_count = __ht._M_element_count;
_M_rehash_policy = __ht._M_rehash_policy;
__reuse_or_alloc_node_type __roan(_M_begin(), *this);
- _M_before_begin()._M_nxt = nullptr;
+ _M_before_begin._M_nxt = nullptr;
_M_assign(__ht,
[&__roan](const __node_type* __n)
{ return __roan(__n->_M_v()); });
if (__former_buckets)
- _M_deallocate_buckets(__former_buckets, __former_bucket_count);
+ this->_M_deallocate_buckets(__former_buckets,
+ __former_bucket_count);
}
__catch(...)
{
@@ -1079,11 +940,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
__bucket_type* __buckets = nullptr;
if (!_M_buckets)
- _M_buckets = __buckets = _M_allocate_buckets(_M_bucket_count);
+ _M_buckets = __buckets = this->_M_allocate_buckets(_M_bucket_count);
__try
{
- if (!__ht._M_before_begin()._M_nxt)
+ if (!__ht._M_before_begin._M_nxt)
return;
// First deal with the special first node pointed to by
@@ -1091,8 +952,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__node_type* __ht_n = __ht._M_begin();
__node_type* __this_n = __node_gen(__ht_n);
this->_M_copy_code(__this_n, __ht_n);
- _M_before_begin()._M_nxt = __this_n;
- _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin();
+ _M_before_begin._M_nxt = __this_n;
+ _M_buckets[_M_bucket_index(__this_n)] = &_M_before_begin;
// Then deal with other nodes.
__node_base* __prev_n = __this_n;
@@ -1128,7 +989,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_rehash_policy._M_reset();
_M_bucket_count = 0;
_M_buckets = nullptr;
- _M_before_begin()._M_nxt = nullptr;
+ _M_before_begin._M_nxt = nullptr;
_M_element_count = 0;
}
@@ -1141,7 +1002,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
_M_move_assign(_Hashtable&& __ht, std::true_type)
{
- _M_deallocate_nodes(_M_begin());
+ this->_M_deallocate_nodes(_M_begin());
if (__builtin_expect(_M_bucket_count != 0, true))
_M_deallocate_buckets();
@@ -1149,14 +1010,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_rehash_policy = __ht._M_rehash_policy;
_M_buckets = __ht._M_buckets;
_M_bucket_count = __ht._M_bucket_count;
- _M_before_begin()._M_nxt = __ht._M_before_begin()._M_nxt;
+ _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
_M_element_count = __ht._M_element_count;
- std::__alloc_on_move(_M_node_allocator(), __ht._M_node_allocator());
+ std::__alloc_on_move(this->_M_node_allocator(), __ht._M_node_allocator());
// Fix buckets containing the _M_before_begin pointers that can't be
// moved.
if (_M_begin())
- _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin();
+ _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
__ht._M_reset();
}
@@ -1169,7 +1030,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
_M_move_assign(_Hashtable&& __ht, std::false_type)
{
- if (__ht._M_node_allocator() == _M_node_allocator())
+ if (__ht._M_node_allocator() == this->_M_node_allocator())
_M_move_assign(std::move(__ht), std::true_type());
else
{
@@ -1181,7 +1042,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (_M_bucket_count != __ht._M_bucket_count)
{
__former_buckets = _M_buckets;
- _M_buckets = _M_allocate_buckets(__ht._M_bucket_count);
+ _M_buckets = this->_M_allocate_buckets(__ht._M_bucket_count);
_M_bucket_count = __ht._M_bucket_count;
}
else
@@ -1194,7 +1055,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_element_count = __ht._M_element_count;
_M_rehash_policy = __ht._M_rehash_policy;
__reuse_or_alloc_node_type __roan(_M_begin(), *this);
- _M_before_begin()._M_nxt = nullptr;
+ _M_before_begin._M_nxt = nullptr;
_M_assign(__ht,
[&__roan](__node_type* __n)
{ return __roan(std::move_if_noexcept(__n->_M_v())); });
@@ -1226,16 +1087,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: __hashtable_base(__ht),
__map_base(__ht),
__rehash_base(__ht),
+ __hashtable_alloc(
+ __node_alloc_traits::_S_select_on_copy(__ht._M_node_allocator())),
_M_buckets(),
_M_bucket_count(__ht._M_bucket_count),
- _M_bbegin(_Node_alloc_traits::_S_select_on_copy(
- __ht._M_node_allocator())),
_M_element_count(__ht._M_element_count),
_M_rehash_policy(__ht._M_rehash_policy)
{
_M_assign(__ht,
[this](const __node_type* __n)
- { return _M_allocate_node(__n->_M_v()); });
+ { return this->_M_allocate_node(__n->_M_v()); });
}
template<typename _Key, typename _Value,
@@ -1248,16 +1109,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: __hashtable_base(__ht),
__map_base(__ht),
__rehash_base(__ht),
+ __hashtable_alloc(std::move(__ht._M_base_alloc())),
_M_buckets(__ht._M_buckets),
_M_bucket_count(__ht._M_bucket_count),
- _M_bbegin(std::move(__ht._M_bbegin)),
+ _M_before_begin(__ht._M_before_begin._M_nxt),
_M_element_count(__ht._M_element_count),
_M_rehash_policy(__ht._M_rehash_policy)
{
// Update, if necessary, bucket pointing to before begin that hasn't
// moved.
if (_M_begin())
- _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin();
+ _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
__ht._M_reset();
}
@@ -1271,15 +1133,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: __hashtable_base(__ht),
__map_base(__ht),
__rehash_base(__ht),
+ __hashtable_alloc(__node_alloc_type(__a)),
_M_buckets(),
_M_bucket_count(__ht._M_bucket_count),
- _M_bbegin(_Node_alloc_type(__a)),
_M_element_count(__ht._M_element_count),
_M_rehash_policy(__ht._M_rehash_policy)
{
_M_assign(__ht,
[this](const __node_type* __n)
- { return _M_allocate_node(__n->_M_v()); });
+ { return this->_M_allocate_node(__n->_M_v()); });
}
template<typename _Key, typename _Value,
@@ -1292,20 +1154,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: __hashtable_base(__ht),
__map_base(__ht),
__rehash_base(__ht),
+ __hashtable_alloc(__node_alloc_type(__a)),
_M_buckets(),
_M_bucket_count(__ht._M_bucket_count),
- _M_bbegin(_Node_alloc_type(__a)),
_M_element_count(__ht._M_element_count),
_M_rehash_policy(__ht._M_rehash_policy)
{
- if (__ht._M_node_allocator() == _M_node_allocator())
+ if (__ht._M_node_allocator() == this->_M_node_allocator())
{
_M_buckets = __ht._M_buckets;
- _M_before_begin()._M_nxt = __ht._M_before_begin()._M_nxt;
+ _M_before_begin._M_nxt = __ht._M_before_begin._M_nxt;
// Update, if necessary, bucket pointing to before begin that hasn't
// moved.
if (_M_begin())
- _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin();
+ _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
__ht._M_reset();
}
else
@@ -1313,7 +1175,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_assign(__ht,
[this](__node_type* __n)
{
- return _M_allocate_node(
+ return this->_M_allocate_node(
std::move_if_noexcept(__n->_M_v()));
});
__ht.clear();
@@ -1341,27 +1203,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Hashtable<_Key, _Value, _Alloc, _ExtractKey, _Equal,
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
swap(_Hashtable& __x)
- noexcept(_Node_alloc_traits::_S_nothrow_swap())
+ noexcept(__node_alloc_traits::_S_nothrow_swap())
{
// The only base class with member variables is hash_code_base.
// We define _Hash_code_base::_M_swap because different
// specializations have different members.
this->_M_swap(__x);
- std::__alloc_on_swap(_M_node_allocator(), __x._M_node_allocator());
+ std::__alloc_on_swap(this->_M_node_allocator(), __x._M_node_allocator());
std::swap(_M_rehash_policy, __x._M_rehash_policy);
std::swap(_M_buckets, __x._M_buckets);
std::swap(_M_bucket_count, __x._M_bucket_count);
- std::swap(_M_before_begin()._M_nxt, __x._M_before_begin()._M_nxt);
+ std::swap(_M_before_begin._M_nxt, __x._M_before_begin._M_nxt);
std::swap(_M_element_count, __x._M_element_count);
// Fix buckets containing the _M_before_begin pointers that can't be
// swapped.
if (_M_begin())
- _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin();
+ _M_buckets[_M_bucket_index(_M_begin())] = &_M_before_begin;
if (__x._M_begin())
__x._M_buckets[__x._M_bucket_index(__x._M_begin())]
- = &(__x._M_before_begin());
+ = &__x._M_before_begin;
}
template<typename _Key, typename _Value,
@@ -1580,13 +1442,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// The bucket is empty, the new node is inserted at the
// beginning of the singly-linked list and the bucket will
// contain _M_before_begin pointer.
- __node->_M_nxt = _M_before_begin()._M_nxt;
- _M_before_begin()._M_nxt = __node;
+ __node->_M_nxt = _M_before_begin._M_nxt;
+ _M_before_begin._M_nxt = __node;
if (__node->_M_nxt)
// We must update former begin bucket that is pointing to
// _M_before_begin.
_M_buckets[_M_bucket_index(__node->_M_next())] = __node;
- _M_buckets[__bkt] = &_M_before_begin();
+ _M_buckets[__bkt] = &_M_before_begin;
}
}
@@ -1608,8 +1470,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_buckets[__next_bkt] = _M_buckets[__bkt];
// Second update before begin node if necessary
- if (&_M_before_begin() == _M_buckets[__bkt])
- _M_before_begin()._M_nxt = __next;
+ if (&_M_before_begin == _M_buckets[__bkt])
+ _M_before_begin._M_nxt = __next;
_M_buckets[__bkt] = nullptr;
}
}
@@ -1645,7 +1507,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_emplace(std::true_type, _Args&&... __args)
{
// First build the node to get access to the hash code
- __node_type* __node = _M_allocate_node(std::forward<_Args>(__args)...);
+ __node_type* __node = this->_M_allocate_node(std::forward<_Args>(__args)...);
const key_type& __k = this->_M_extract()(__node->_M_v());
__hash_code __code;
__try
@@ -1654,7 +1516,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
__catch(...)
{
- _M_deallocate_node(__node);
+ this->_M_deallocate_node(__node);
__throw_exception_again;
}
@@ -1662,7 +1524,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__node_type* __p = _M_find_node(__bkt, __k, __code))
{
// There is already an equivalent node, no insertion
- _M_deallocate_node(__node);
+ this->_M_deallocate_node(__node);
return std::make_pair(iterator(__p), false);
}
@@ -1684,7 +1546,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_emplace(const_iterator __hint, std::false_type, _Args&&... __args)
{
// First build the node to get its hash code.
- __node_type* __node = _M_allocate_node(std::forward<_Args>(__args)...);
+ __node_type* __node =
+ this->_M_allocate_node(std::forward<_Args>(__args)...);
__hash_code __code;
__try
@@ -1693,7 +1556,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
__catch(...)
{
- _M_deallocate_node(__node);
+ this->_M_deallocate_node(__node);
__throw_exception_again;
}
@@ -1733,7 +1596,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
__catch(...)
{
- _M_deallocate_node(__node);
+ this->_M_deallocate_node(__node);
__throw_exception_again;
}
}
@@ -1799,7 +1662,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
__catch(...)
{
- _M_deallocate_node(__node);
+ this->_M_deallocate_node(__node);
__throw_exception_again;
}
}
@@ -1899,7 +1762,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__prev_n->_M_nxt = __n->_M_nxt;
iterator __result(__n->_M_next());
- _M_deallocate_node(__n);
+ this->_M_deallocate_node(__n);
--_M_element_count;
return __result;
@@ -1972,7 +1835,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
do
{
__node_type* __p = __n->_M_next();
- _M_deallocate_node(__n);
+ this->_M_deallocate_node(__n);
__n = __p;
++__result;
--_M_element_count;
@@ -2014,7 +1877,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
__node_type* __tmp = __n;
__n = __n->_M_next();
- _M_deallocate_node(__tmp);
+ this->_M_deallocate_node(__tmp);
--_M_element_count;
if (!__n)
break;
@@ -2044,10 +1907,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
clear() noexcept
{
- _M_deallocate_nodes(_M_begin());
+ this->_M_deallocate_nodes(_M_begin());
__builtin_memset(_M_buckets, 0, _M_bucket_count * sizeof(__bucket_type));
_M_element_count = 0;
- _M_before_begin()._M_nxt = nullptr;
+ _M_before_begin._M_nxt = nullptr;
}
template<typename _Key, typename _Value,
@@ -2104,9 +1967,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
_M_rehash_aux(size_type __n, std::true_type)
{
- __bucket_type* __new_buckets = _M_allocate_buckets(__n);
+ __bucket_type* __new_buckets = this->_M_allocate_buckets(__n);
__node_type* __p = _M_begin();
- _M_before_begin()._M_nxt = nullptr;
+ _M_before_begin._M_nxt = nullptr;
std::size_t __bbegin_bkt = 0;
while (__p)
{
@@ -2114,9 +1977,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::size_t __bkt = __hash_code_base::_M_bucket_index(__p, __n);
if (!__new_buckets[__bkt])
{
- __p->_M_nxt = _M_before_begin()._M_nxt;
- _M_before_begin()._M_nxt = __p;
- __new_buckets[__bkt] = &_M_before_begin();
+ __p->_M_nxt = _M_before_begin._M_nxt;
+ _M_before_begin._M_nxt = __p;
+ __new_buckets[__bkt] = &_M_before_begin;
if (__p->_M_nxt)
__new_buckets[__bbegin_bkt] = __p;
__bbegin_bkt = __bkt;
@@ -2146,10 +2009,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_H1, _H2, _Hash, _RehashPolicy, _Traits>::
_M_rehash_aux(size_type __n, std::false_type)
{
- __bucket_type* __new_buckets = _M_allocate_buckets(__n);
+ __bucket_type* __new_buckets = this->_M_allocate_buckets(__n);
__node_type* __p = _M_begin();
- _M_before_begin()._M_nxt = nullptr;
+ _M_before_begin._M_nxt = nullptr;
std::size_t __bbegin_bkt = 0;
std::size_t __prev_bkt = 0;
__node_type* __prev_p = nullptr;
@@ -2194,9 +2057,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (!__new_buckets[__bkt])
{
- __p->_M_nxt = _M_before_begin()._M_nxt;
- _M_before_begin()._M_nxt = __p;
- __new_buckets[__bkt] = &_M_before_begin();
+ __p->_M_nxt = _M_before_begin._M_nxt;
+ _M_before_begin._M_nxt = __p;
+ __new_buckets[__bkt] = &_M_before_begin;
if (__p->_M_nxt)
__new_buckets[__bbegin_bkt] = __p;
__bbegin_bkt = __bkt;
diff --git a/libstdc++-v3/include/bits/hashtable_policy.h b/libstdc++-v3/include/bits/hashtable_policy.h
index a95b8d4f6a5..61b852f62df 100644
--- a/libstdc++-v3/include/bits/hashtable_policy.h
+++ b/libstdc++-v3/include/bits/hashtable_policy.h
@@ -102,25 +102,26 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return std::get<0>(std::forward<_Tp>(__x)); }
};
+ template<typename _NodeAlloc>
+ struct _Hashtable_alloc;
+
// Functor recycling a pool of nodes and using allocation once the pool is
// empty.
- template<typename _Key, typename _Value, typename _Alloc,
- typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash,
- typename _RehashPolicy, typename _Traits>
+ template<typename _NodeAlloc>
struct _ReuseOrAllocNode
{
private:
- using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
- _Equal, _H1, _H2, _Hash,
- _RehashPolicy, _Traits>;
- using __val_alloc_type = typename __hashtable::_Value_alloc_type;
- using __val_alloc_traits = typename __hashtable::_Value_alloc_traits;
- using __node_alloc_traits = typename __hashtable::_Node_alloc_traits;
- using __node_type = typename __hashtable::__node_type;
+ using __node_alloc_type = _NodeAlloc;
+ using __hashtable_alloc = _Hashtable_alloc<__node_alloc_type>;
+ using __value_alloc_type = typename __hashtable_alloc::__value_alloc_type;
+ using __value_alloc_traits =
+ typename __hashtable_alloc::__value_alloc_traits;
+ using __node_alloc_traits =
+ typename __hashtable_alloc::__node_alloc_traits;
+ using __node_type = typename __hashtable_alloc::__node_type;
public:
- _ReuseOrAllocNode(__node_type* __nodes, __hashtable& __h)
+ _ReuseOrAllocNode(__node_type* __nodes, __hashtable_alloc& __h)
: _M_nodes(__nodes), _M_h(__h) { }
_ReuseOrAllocNode(const _ReuseOrAllocNode&) = delete;
@@ -136,12 +137,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__node_type* __node = _M_nodes;
_M_nodes = _M_nodes->_M_next();
__node->_M_nxt = nullptr;
- __val_alloc_type __a(_M_h._M_node_allocator());
- __val_alloc_traits::destroy(__a, __node->_M_valptr());
+ __value_alloc_type __a(_M_h._M_node_allocator());
+ __value_alloc_traits::destroy(__a, __node->_M_valptr());
__try
{
- __val_alloc_traits::construct(__a, __node->_M_valptr(),
- std::forward<_Arg>(__arg));
+ __value_alloc_traits::construct(__a, __node->_M_valptr(),
+ std::forward<_Arg>(__arg));
}
__catch(...)
{
@@ -157,24 +158,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
mutable __node_type* _M_nodes;
- __hashtable& _M_h;
+ __hashtable_alloc& _M_h;
};
// Functor similar to the previous one but without any pool of node to recycle.
- template<typename _Key, typename _Value, typename _Alloc,
- typename _ExtractKey, typename _Equal,
- typename _H1, typename _H2, typename _Hash,
- typename _RehashPolicy, typename _Traits>
+ template<typename _NodeAlloc>
struct _AllocNode
{
private:
- using __hashtable = _Hashtable<_Key, _Value, _Alloc, _ExtractKey,
- _Equal, _H1, _H2, _Hash,
- _RehashPolicy, _Traits>;
- using __node_type = typename __hashtable::__node_type;
+ using __hashtable_alloc = _Hashtable_alloc<_NodeAlloc>;
+ using __node_type = typename __hashtable_alloc::__node_type;
public:
- _AllocNode(__hashtable& __h)
+ _AllocNode(__hashtable_alloc& __h)
: _M_h(__h) { }
template<typename _Arg>
@@ -183,7 +179,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return _M_h._M_allocate_node(std::forward<_Arg>(__arg)); }
private:
- __hashtable& _M_h;
+ __hashtable_alloc& _M_h;
};
// Auxiliary types used for all instantiations of _Hashtable nodes
@@ -247,6 +243,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Value>
struct _Hash_node_value_base : _Hash_node_base
{
+ typedef _Value value_type;
+
__gnu_cxx::__aligned_buffer<_Value> _M_storage;
_Value*
@@ -336,9 +334,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __node_type = typename __base_type::__node_type;
public:
- typedef _Value value_type;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ typedef _Value value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
using pointer = typename std::conditional<__constant_iterators,
const _Value*, _Value*>::type;
@@ -387,12 +385,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __node_type = typename __base_type::__node_type;
public:
- typedef _Value value_type;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ typedef _Value value_type;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
- typedef const _Value* pointer;
- typedef const _Value& reference;
+ typedef const _Value* pointer;
+ typedef const _Value& reference;
_Node_const_iterator()
: __base_type(0) { }
@@ -499,8 +497,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static const std::size_t _S_growth_factor = 2;
- float _M_max_load_factor;
- mutable std::size_t _M_next_resize;
+ float _M_max_load_factor;
+ mutable std::size_t _M_next_resize;
};
// Base classes for std::_Hashtable. We define these base classes
@@ -697,9 +695,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __unique_keys = typename __hashtable_base::__unique_keys;
using __ireturn_type = typename __hashtable_base::__ireturn_type;
- using __node_gen_type = _AllocNode<_Key, _Value, _Alloc, _ExtractKey,
- _Equal, _H1, _H2, _Hash,
- _RehashPolicy, _Traits>;
+ using __node_type = _Hash_node<_Value, _Traits::__hash_cached::value>;
+ using __node_alloc_type =
+ typename __alloctr_rebind<_Alloc, __node_type>::__type;
+ using __node_gen_type = _AllocNode<__node_alloc_type>;
__hashtable&
_M_conjure_hashtable()
@@ -979,8 +978,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_Hashtable_ebo_helper() = default;
- _Hashtable_ebo_helper(const _Tp& __tp) : _Tp(__tp)
- { }
+ template<typename _OtherTp>
+ _Hashtable_ebo_helper(_OtherTp&& __tp)
+ : _Tp(std::forward<_OtherTp>(__tp))
+ { }
static const _Tp&
_S_cget(const _Hashtable_ebo_helper& __eboh)
@@ -997,8 +998,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_Hashtable_ebo_helper() = default;
- _Hashtable_ebo_helper(const _Tp& __tp) : _M_tp(__tp)
- { }
+ template<typename _OtherTp>
+ _Hashtable_ebo_helper(_OtherTp&& __tp)
+ : _M_tp(std::forward<_OtherTp>(__tp))
+ { }
static const _Tp&
_S_cget(const _Hashtable_ebo_helper& __eboh)
@@ -1431,15 +1434,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_H1, _H2, _Hash, __cache>;
using __hash_code_base = typename __base_type::__hash_code_base;
public:
- typedef _Value value_type;
+ typedef _Value value_type;
typedef typename std::conditional<__constant_iterators,
const _Value*, _Value*>::type
pointer;
typedef typename std::conditional<__constant_iterators,
const _Value&, _Value&>::type
reference;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
_Local_iterator() = default;
@@ -1487,11 +1490,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
using __hash_code_base = typename __base_type::__hash_code_base;
public:
- typedef _Value value_type;
- typedef const _Value* pointer;
- typedef const _Value& reference;
- typedef std::ptrdiff_t difference_type;
- typedef std::forward_iterator_tag iterator_category;
+ typedef _Value value_type;
+ typedef const _Value* pointer;
+ typedef const _Value& reference;
+ typedef std::ptrdiff_t difference_type;
+ typedef std::forward_iterator_tag iterator_category;
_Local_const_iterator() = default;
@@ -1551,11 +1554,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private _Hashtable_ebo_helper<0, _Equal>
{
public:
- typedef _Key key_type;
- typedef _Value value_type;
- typedef _Equal key_equal;
- typedef std::size_t size_type;
- typedef std::ptrdiff_t difference_type;
+ typedef _Key key_type;
+ typedef _Value value_type;
+ typedef _Equal key_equal;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
using __traits_type = _Traits;
using __hash_cached = typename __traits_type::__hash_cached;
@@ -1597,9 +1600,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__hash_code, __hash_cached::value>;
protected:
- using __node_base = __detail::_Hash_node_base;
- using __bucket_type = __node_base*;
-
_Hashtable_base(const _ExtractKey& __ex, const _H1& __h1, const _H2& __h2,
const _Hash& __hash, const _Equal& __eq)
: __hash_code_base(__ex, __h1, __h2, __hash), _EqualEBO(__eq)
@@ -1787,23 +1787,136 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
/**
- * This type is to combine a _Hash_node_base instance with an allocator
- * instance through inheritance to benefit from EBO when possible.
+ * This type deals with all allocation and keeps an allocator instance through
+ * inheritance to benefit from EBO when possible.
*/
template<typename _NodeAlloc>
- struct _Before_begin : public _NodeAlloc
+ struct _Hashtable_alloc : private _Hashtable_ebo_helper<0, _NodeAlloc>
{
- _Hash_node_base _M_node;
+ private:
+ using __ebo_node_alloc = _Hashtable_ebo_helper<0, _NodeAlloc>;
+ public:
+ using __node_type = typename _NodeAlloc::value_type;
+ using __node_alloc_type = _NodeAlloc;
+ // Use __gnu_cxx to benefit from _S_always_equal and al.
+ using __node_alloc_traits = __gnu_cxx::__alloc_traits<__node_alloc_type>;
+
+ using __value_type = typename __node_type::value_type;
+ using __value_alloc_type =
+ typename __alloctr_rebind<__node_alloc_type, __value_type>::__type;
+ using __value_alloc_traits = std::allocator_traits<__value_alloc_type>;
- _Before_begin(const _Before_begin&) = default;
- _Before_begin(_Before_begin&&) = default;
+ using __node_base = __detail::_Hash_node_base;
+ using __bucket_type = __node_base*;
+ using __bucket_alloc_type =
+ typename __alloctr_rebind<__node_alloc_type, __bucket_type>::__type;
+ using __bucket_alloc_traits = std::allocator_traits<__bucket_alloc_type>;
+
+ _Hashtable_alloc(const _Hashtable_alloc&) = default;
+ _Hashtable_alloc(_Hashtable_alloc&&) = default;
template<typename _Alloc>
- _Before_begin(_Alloc&& __a)
- : _NodeAlloc(std::forward<_Alloc>(__a))
+ _Hashtable_alloc(_Alloc&& __a)
+ : __ebo_node_alloc(std::forward<_Alloc>(__a))
{ }
+
+ __node_alloc_type&
+ _M_node_allocator()
+ { return __ebo_node_alloc::_S_get(*this); }
+
+ const __node_alloc_type&
+ _M_node_allocator() const
+ { return __ebo_node_alloc::_S_cget(*this); }
+
+ template<typename... _Args>
+ __node_type*
+ _M_allocate_node(_Args&&... __args);
+
+ void
+ _M_deallocate_node(__node_type* __n);
+
+ // Deallocate the linked list of nodes pointed to by __n
+ void
+ _M_deallocate_nodes(__node_type* __n);
+
+ __bucket_type*
+ _M_allocate_buckets(std::size_t __n);
+
+ void
+ _M_deallocate_buckets(__bucket_type*, std::size_t __n);
};
+ // Definitions of class template _Hashtable_alloc's out-of-line member
+ // functions.
+ template<typename _NodeAlloc>
+ template<typename... _Args>
+ typename _Hashtable_alloc<_NodeAlloc>::__node_type*
+ _Hashtable_alloc<_NodeAlloc>::_M_allocate_node(_Args&&... __args)
+ {
+ auto __nptr = __node_alloc_traits::allocate(_M_node_allocator(), 1);
+ __node_type* __n = std::__addressof(*__nptr);
+ __try
+ {
+ __value_alloc_type __a(_M_node_allocator());
+ ::new ((void*)__n) __node_type();
+ __value_alloc_traits::construct(__a, __n->_M_valptr(),
+ std::forward<_Args>(__args)...);
+ return __n;
+ }
+ __catch(...)
+ {
+ __node_alloc_traits::deallocate(_M_node_allocator(), __nptr, 1);
+ __throw_exception_again;
+ }
+ }
+
+ template<typename _NodeAlloc>
+ void
+ _Hashtable_alloc<_NodeAlloc>::_M_deallocate_node(__node_type* __n)
+ {
+ typedef typename __node_alloc_traits::pointer _Ptr;
+ auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__n);
+ __value_alloc_type __a(_M_node_allocator());
+ __value_alloc_traits::destroy(__a, __n->_M_valptr());
+ __n->~__node_type();
+ __node_alloc_traits::deallocate(_M_node_allocator(), __ptr, 1);
+ }
+
+ template<typename _NodeAlloc>
+ void
+ _Hashtable_alloc<_NodeAlloc>::_M_deallocate_nodes(__node_type* __n)
+ {
+ while (__n)
+ {
+ __node_type* __tmp = __n;
+ __n = __n->_M_next();
+ _M_deallocate_node(__tmp);
+ }
+ }
+
+ template<typename _NodeAlloc>
+ typename _Hashtable_alloc<_NodeAlloc>::__bucket_type*
+ _Hashtable_alloc<_NodeAlloc>::_M_allocate_buckets(std::size_t __n)
+ {
+ __bucket_alloc_type __alloc(_M_node_allocator());
+
+ auto __ptr = __bucket_alloc_traits::allocate(__alloc, __n);
+ __bucket_type* __p = std::__addressof(*__ptr);
+ __builtin_memset(__p, 0, __n * sizeof(__bucket_type));
+ return __p;
+ }
+
+ template<typename _NodeAlloc>
+ void
+ _Hashtable_alloc<_NodeAlloc>::_M_deallocate_buckets(__bucket_type* __bkts,
+ std::size_t __n)
+ {
+ typedef typename __bucket_alloc_traits::pointer _Ptr;
+ auto __ptr = std::pointer_traits<_Ptr>::pointer_to(*__bkts);
+ __bucket_alloc_type __alloc(_M_node_allocator());
+ __bucket_alloc_traits::deallocate(__alloc, __ptr, __n);
+ }
+
//@} hashtable-detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __detail
diff --git a/libstdc++-v3/include/bits/random.h b/libstdc++-v3/include/bits/random.h
index bf7f32ff0f2..dde2dd45f9e 100644
--- a/libstdc++-v3/include/bits/random.h
+++ b/libstdc++-v3/include/bits/random.h
@@ -2178,7 +2178,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
result_type
min() const
- { return std::numeric_limits<result_type>::min(); }
+ { return std::numeric_limits<result_type>::lowest(); }
/**
* @brief Returns the least upper bound value of the distribution.
@@ -3011,7 +3011,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
result_type
min() const
- { return std::numeric_limits<result_type>::min(); }
+ { return std::numeric_limits<result_type>::lowest(); }
/**
* @brief Returns the least upper bound value of the distribution.
@@ -3428,7 +3428,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
result_type
min() const
- { return std::numeric_limits<result_type>::min(); }
+ { return std::numeric_limits<result_type>::lowest(); }
/**
* @brief Returns the least upper bound value of the distribution.
@@ -5136,7 +5136,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
result_type
min() const
- { return std::numeric_limits<result_type>::min(); }
+ { return std::numeric_limits<result_type>::lowest(); }
/**
* @brief Returns the least upper bound value of the distribution.
diff --git a/libstdc++-v3/include/bits/random.tcc b/libstdc++-v3/include/bits/random.tcc
index c6db5b40cb7..10c65506f81 100644
--- a/libstdc++-v3/include/bits/random.tcc
+++ b/libstdc++-v3/include/bits/random.tcc
@@ -1291,7 +1291,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator()(_UniformRandomNumberGenerator& __urng,
const param_type& __p)
{
- typedef typename std::gamma_distribution<result_type>::param_type
+ typedef typename std::gamma_distribution<double>::param_type
param_type;
const double __y =
diff --git a/libstdc++-v3/include/bits/regex.h b/libstdc++-v3/include/bits/regex.h
index 56928484785..412465adfa2 100644
--- a/libstdc++-v3/include/bits/regex.h
+++ b/libstdc++-v3/include/bits/regex.h
@@ -40,7 +40,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/**
* @brief Class regex_traits. Describes aspects of a regular expression.
*
- * A regular expression traits class that satisfies the requirements of
+ * A regular expression traits class that satisfies the requirements of
* section [28.7].
*
* The class %regex is parameterized around a set of related types and
@@ -56,70 +56,71 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef std::locale locale_type;
private:
struct _RegexMask
- {
- typedef typename std::ctype<char_type>::mask _BaseType;
- _BaseType _M_base;
- unsigned char _M_extended;
- static constexpr unsigned char _S_under = 1 << 0;
- // FIXME: _S_blank should be removed in the future, when locale's complete.
- static constexpr unsigned char _S_blank = 1 << 1;
- static constexpr unsigned char _S_valid_mask = 0x3;
-
- constexpr _RegexMask(_BaseType __base = 0,
- unsigned char __extended = 0)
- : _M_base(__base), _M_extended(__extended)
- { }
-
- constexpr _RegexMask
- operator&(_RegexMask __other) const
- {
- return _RegexMask(_M_base & __other._M_base,
- _M_extended & __other._M_extended);
- }
-
- constexpr _RegexMask
- operator|(_RegexMask __other) const
- {
- return _RegexMask(_M_base | __other._M_base,
- _M_extended | __other._M_extended);
- }
-
- constexpr _RegexMask
- operator^(_RegexMask __other) const
- {
- return _RegexMask(_M_base ^ __other._M_base,
- _M_extended ^ __other._M_extended);
- }
-
- constexpr _RegexMask
- operator~() const
- { return _RegexMask(~_M_base, ~_M_extended); }
-
- constexpr _RegexMask&
- operator&=(_RegexMask __other)
- { return *this = (*this) & __other; }
-
- constexpr _RegexMask&
- operator|=(_RegexMask __other)
- { return *this = (*this) | __other; }
-
- constexpr _RegexMask&
- operator^=(_RegexMask __other)
- { return *this = (*this) ^ __other; }
-
- constexpr bool
- operator==(_RegexMask __other) const
- {
- return (_M_extended & _S_valid_mask)
- == (__other._M_extended & _S_valid_mask)
- && _M_base == __other._M_base;
- }
-
- constexpr bool
- operator!=(_RegexMask __other) const
- { return !((*this) == __other); }
-
- };
+ {
+ typedef typename std::ctype<char_type>::mask _BaseType;
+ _BaseType _M_base;
+ unsigned char _M_extended;
+ static constexpr unsigned char _S_under = 1 << 0;
+ // FIXME: _S_blank should be removed in the future,
+ // when locale's complete.
+ static constexpr unsigned char _S_blank = 1 << 1;
+ static constexpr unsigned char _S_valid_mask = 0x3;
+
+ constexpr _RegexMask(_BaseType __base = 0,
+ unsigned char __extended = 0)
+ : _M_base(__base), _M_extended(__extended)
+ { }
+
+ constexpr _RegexMask
+ operator&(_RegexMask __other) const
+ {
+ return _RegexMask(_M_base & __other._M_base,
+ _M_extended & __other._M_extended);
+ }
+
+ constexpr _RegexMask
+ operator|(_RegexMask __other) const
+ {
+ return _RegexMask(_M_base | __other._M_base,
+ _M_extended | __other._M_extended);
+ }
+
+ constexpr _RegexMask
+ operator^(_RegexMask __other) const
+ {
+ return _RegexMask(_M_base ^ __other._M_base,
+ _M_extended ^ __other._M_extended);
+ }
+
+ constexpr _RegexMask
+ operator~() const
+ { return _RegexMask(~_M_base, ~_M_extended); }
+
+ _RegexMask&
+ operator&=(_RegexMask __other)
+ { return *this = (*this) & __other; }
+
+ _RegexMask&
+ operator|=(_RegexMask __other)
+ { return *this = (*this) | __other; }
+
+ _RegexMask&
+ operator^=(_RegexMask __other)
+ { return *this = (*this) ^ __other; }
+
+ constexpr bool
+ operator==(_RegexMask __other) const
+ {
+ return (_M_extended & _S_valid_mask)
+ == (__other._M_extended & _S_valid_mask)
+ && _M_base == __other._M_base;
+ }
+
+ constexpr bool
+ operator!=(_RegexMask __other) const
+ { return !((*this) == __other); }
+
+ };
public:
typedef _RegexMask char_class_type;
@@ -128,7 +129,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @brief Constructs a default traits object.
*/
regex_traits() { }
-
+
/**
* @brief Gives the length of a C-style string starting at @p __p.
*
@@ -153,7 +154,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
char_type
translate(char_type __c) const
{ return __c; }
-
+
/**
* @brief Translates a character into a case-insensitive equivalent.
*
@@ -165,12 +166,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
char_type
translate_nocase(char_type __c) const
- {
+ {
typedef std::ctype<char_type> __ctype_type;
const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
- return __fctyp.tolower(__c);
+ return __fctyp.tolower(__c);
}
-
+
/**
* @brief Gets a sort key for a character sequence.
*
@@ -192,9 +193,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* facet.
*/
template<typename _Fwd_iter>
- string_type
- transform(_Fwd_iter __first, _Fwd_iter __last) const
- {
+ string_type
+ transform(_Fwd_iter __first, _Fwd_iter __last) const
+ {
typedef std::collate<char_type> __collate_type;
const __collate_type& __fclt(use_facet<__collate_type>(_M_locale));
string_type __s(__first, __last);
@@ -209,45 +210,38 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* Effects: if typeid(use_facet<collate<_Ch_type> >) ==
* typeid(collate_byname<_Ch_type>) and the form of the sort key
- * returned by collate_byname<_Ch_type>::transform(__first, __last)
+ * returned by collate_byname<_Ch_type>::transform(__first, __last)
* is known and can be converted into a primary sort key
* then returns that key, otherwise returns an empty string.
*
* @todo Implement this function.
*/
template<typename _Fwd_iter>
- string_type
- transform_primary(_Fwd_iter __first, _Fwd_iter __last) const
- {
- __try
- {
- typedef std::ctype<char_type> __ctype_type;
- const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
- std::vector<char_type> __v(__first, __last);
- // FIXME : this is not entirely correct
- __fctyp.tolower(&*__v.begin(), &*__v.end());
- return this->transform(&*__v.begin(), &*__v.end());
- }
- __catch (...)
- {
- }
- return string_type();
- }
+ string_type
+ transform_primary(_Fwd_iter __first, _Fwd_iter __last) const
+ {
+ typedef std::ctype<char_type> __ctype_type;
+ const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
+ std::vector<char_type> __s(__first, __last);
+ // FIXME : this is not entirely correct
+ __fctyp.tolower(__s.data(), __s.data() + __s.size());
+ return this->transform(__s.data(), __s.data() + __s.size());
+ }
/**
* @brief Gets a collation element by name.
*
* @param __first beginning of the collation element name.
* @param __last one-past-the-end of the collation element name.
- *
+ *
* @returns a sequence of one or more characters that represents the
* collating element consisting of the character sequence designated by
* the iterator range [__first, __last). Returns an empty string if the
* character sequence is not a valid collating element.
*/
template<typename _Fwd_iter>
- string_type
- lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const;
+ string_type
+ lookup_collatename(_Fwd_iter __first, _Fwd_iter __last) const;
/**
* @brief Maps one or more characters to a named character
@@ -287,9 +281,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* - xdigit
*/
template<typename _Fwd_iter>
- char_class_type
- lookup_classname(_Fwd_iter __first, _Fwd_iter __last,
- bool __icase = false) const;
+ char_class_type
+ lookup_classname(_Fwd_iter __first, _Fwd_iter __last,
+ bool __icase = false) const;
/**
* @brief Determines if @p c is a member of an identified class.
@@ -312,13 +306,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __ch a character representing a digit.
* @param __radix the radix if the numeric conversion (limited to 8, 10,
* or 16).
- *
+ *
* @returns the value represented by the digit __ch in base radix if the
* character __ch is a valid digit in base radix; otherwise returns -1.
*/
int
value(_Ch_type __ch, int __radix) const;
-
+
/**
* @brief Imbues the regex_traits object with a copy of a new locale.
*
@@ -336,7 +330,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
std::swap(_M_locale, __loc);
return __loc;
}
-
+
/**
* @brief Gets a copy of the current locale in use by the regex_traits
* object.
@@ -344,7 +338,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
locale_type
getloc() const
{ return _M_locale; }
-
+
protected:
locale_type _M_locale;
};
@@ -359,183 +353,182 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
static const char* __collatenames[] =
- {
- "NUL",
- "SOH",
- "STX",
- "ETX",
- "EOT",
- "ENQ",
- "ACK",
- "alert",
- "backspace",
- "tab",
- "newline",
- "vertical-tab",
- "form-feed",
- "carriage-return",
- "SO",
- "SI",
- "DLE",
- "DC1",
- "DC2",
- "DC3",
- "DC4",
- "NAK",
- "SYN",
- "ETB",
- "CAN",
- "EM",
- "SUB",
- "ESC",
- "IS4",
- "IS3",
- "IS2",
- "IS1",
- "space",
- "exclamation-mark",
- "quotation-mark",
- "number-sign",
- "dollar-sign",
- "percent-sign",
- "ampersand",
- "apostrophe",
- "left-parenthesis",
- "right-parenthesis",
- "asterisk",
- "plus-sign",
- "comma",
- "hyphen",
- "period",
- "slash",
- "zero",
- "one",
- "two",
- "three",
- "four",
- "five",
- "six",
- "seven",
- "eight",
- "nine",
- "colon",
- "semicolon",
- "less-than-sign",
- "equals-sign",
- "greater-than-sign",
- "question-mark",
- "commercial-at",
- "A",
- "B",
- "C",
- "D",
- "E",
- "F",
- "G",
- "H",
- "I",
- "J",
- "K",
- "L",
- "M",
- "N",
- "O",
- "P",
- "Q",
- "R",
- "S",
- "T",
- "U",
- "V",
- "W",
- "X",
- "Y",
- "Z",
- "left-square-bracket",
- "backslash",
- "right-square-bracket",
- "circumflex",
- "underscore",
- "grave-accent",
- "a",
- "b",
- "c",
- "d",
- "e",
- "f",
- "g",
- "h",
- "i",
- "j",
- "k",
- "l",
- "m",
- "n",
- "o",
- "p",
- "q",
- "r",
- "s",
- "t",
- "u",
- "v",
- "w",
- "x",
- "y",
- "z",
- "left-curly-bracket",
- "vertical-line",
- "right-curly-bracket",
- "tilde",
- "DEL",
- ""
- };
+ {
+ "NUL",
+ "SOH",
+ "STX",
+ "ETX",
+ "EOT",
+ "ENQ",
+ "ACK",
+ "alert",
+ "backspace",
+ "tab",
+ "newline",
+ "vertical-tab",
+ "form-feed",
+ "carriage-return",
+ "SO",
+ "SI",
+ "DLE",
+ "DC1",
+ "DC2",
+ "DC3",
+ "DC4",
+ "NAK",
+ "SYN",
+ "ETB",
+ "CAN",
+ "EM",
+ "SUB",
+ "ESC",
+ "IS4",
+ "IS3",
+ "IS2",
+ "IS1",
+ "space",
+ "exclamation-mark",
+ "quotation-mark",
+ "number-sign",
+ "dollar-sign",
+ "percent-sign",
+ "ampersand",
+ "apostrophe",
+ "left-parenthesis",
+ "right-parenthesis",
+ "asterisk",
+ "plus-sign",
+ "comma",
+ "hyphen",
+ "period",
+ "slash",
+ "zero",
+ "one",
+ "two",
+ "three",
+ "four",
+ "five",
+ "six",
+ "seven",
+ "eight",
+ "nine",
+ "colon",
+ "semicolon",
+ "less-than-sign",
+ "equals-sign",
+ "greater-than-sign",
+ "question-mark",
+ "commercial-at",
+ "A",
+ "B",
+ "C",
+ "D",
+ "E",
+ "F",
+ "G",
+ "H",
+ "I",
+ "J",
+ "K",
+ "L",
+ "M",
+ "N",
+ "O",
+ "P",
+ "Q",
+ "R",
+ "S",
+ "T",
+ "U",
+ "V",
+ "W",
+ "X",
+ "Y",
+ "Z",
+ "left-square-bracket",
+ "backslash",
+ "right-square-bracket",
+ "circumflex",
+ "underscore",
+ "grave-accent",
+ "a",
+ "b",
+ "c",
+ "d",
+ "e",
+ "f",
+ "g",
+ "h",
+ "i",
+ "j",
+ "k",
+ "l",
+ "m",
+ "n",
+ "o",
+ "p",
+ "q",
+ "r",
+ "s",
+ "t",
+ "u",
+ "v",
+ "w",
+ "x",
+ "y",
+ "z",
+ "left-curly-bracket",
+ "vertical-line",
+ "right-curly-bracket",
+ "tilde",
+ "DEL",
+ ""
+ };
// same as boost
static const char* __digraphs[] =
- {
- "ae",
- "Ae",
- "AE",
- "ch",
- "Ch",
- "CH",
- "ll",
- "Ll",
- "LL",
- "ss",
- "Ss",
- "SS",
- "nj",
- "Nj",
- "NJ",
- "dz",
- "Dz",
- "DZ",
- "lj",
- "Lj",
- "LJ",
- ""
- };
+ {
+ "ae",
+ "Ae",
+ "AE",
+ "ch",
+ "Ch",
+ "CH",
+ "ll",
+ "Ll",
+ "LL",
+ "ss",
+ "Ss",
+ "SS",
+ "nj",
+ "Nj",
+ "NJ",
+ "dz",
+ "Dz",
+ "DZ",
+ "lj",
+ "Lj",
+ "LJ",
+ ""
+ };
std::string __s(__last - __first, '?');
- string_type a(__first, __last);
__fctyp.narrow(__first, __last, '?', &*__s.begin());
for (unsigned int __i = 0; *__collatenames[__i]; __i++)
- if (__s == __collatenames[__i])
- return string_type(1, __fctyp.widen((char)__i));
+ if (__s == __collatenames[__i])
+ return string_type(1, __fctyp.widen((char)__i));
for (unsigned int __i = 0; *__digraphs[__i]; __i++)
- {
- const char* __now = __digraphs[__i];
- if (__s == __now)
- {
- string_type ret(__s.size(), __fctyp.widen('?'));
- __fctyp.widen(__now, __now + 2/* ouch */, &*ret.begin());
- return ret;
- }
- }
+ {
+ const char* __now = __digraphs[__i];
+ if (__s == __now)
+ {
+ string_type ret(__s.size(), __fctyp.widen('?'));
+ __fctyp.widen(__now, __now + 2/* ouch */, &*ret.begin());
+ return ret;
+ }
+ }
return string_type();
}
@@ -553,38 +546,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
static _ClassnameEntry __classnames[] =
{
- {"d", ctype_base::digit},
- {"w", {ctype_base::alnum, _RegexMask::_S_under}},
- {"s", ctype_base::space},
- {"alnum", ctype_base::alnum},
- {"alpha", ctype_base::alpha},
- {"blank", {0, _RegexMask::_S_blank}},
- {"cntrl", ctype_base::cntrl},
- {"digit", ctype_base::digit},
- {"graph", ctype_base::graph},
- {"lower", ctype_base::lower},
- {"print", ctype_base::print},
- {"punct", ctype_base::punct},
- {"space", ctype_base::space},
- {"upper", ctype_base::upper},
- {"xdigit", ctype_base::xdigit},
+ {"d", ctype_base::digit},
+ {"w", {ctype_base::alnum, _RegexMask::_S_under}},
+ {"s", ctype_base::space},
+ {"alnum", ctype_base::alnum},
+ {"alpha", ctype_base::alpha},
+ {"blank", {0, _RegexMask::_S_blank}},
+ {"cntrl", ctype_base::cntrl},
+ {"digit", ctype_base::digit},
+ {"graph", ctype_base::graph},
+ {"lower", ctype_base::lower},
+ {"print", ctype_base::print},
+ {"punct", ctype_base::punct},
+ {"space", ctype_base::space},
+ {"upper", ctype_base::upper},
+ {"xdigit", ctype_base::xdigit},
};
std::string __s(__last - __first, '?');
__fctyp.narrow(__first, __last, '?', &__s[0]);
- __cctyp.tolower(&*__s.begin(), &*__s.end());
+ __cctyp.tolower(&*__s.begin(), &*__s.begin() + __s.size());
for (_ClassnameEntry* __it = __classnames;
- __it < *(&__classnames + 1);
- ++__it)
- {
- if (__s == __it->first)
- {
- if (__icase
- && ((__it->second & (ctype_base::lower | ctype_base::upper)) != 0))
- return ctype_base::alpha;
- return __it->second;
- }
- }
+ __it < *(&__classnames + 1);
+ ++__it)
+ {
+ if (__s == __it->first)
+ {
+ if (__icase
+ && ((__it->second
+ & (ctype_base::lower | ctype_base::upper)) != 0))
+ return ctype_base::alpha;
+ return __it->second;
+ }
+ }
return 0;
}
@@ -595,15 +589,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef std::ctype<char_type> __ctype_type;
const __ctype_type& __fctyp(use_facet<__ctype_type>(_M_locale));
-
+
return __fctyp.is(__f._M_base, __c)
- // [[:w:]]
- || ((__f._M_extended & _RegexMask::_S_under)
- && __c == __fctyp.widen('_'))
- // [[:blank:]]
- || ((__f._M_extended & _RegexMask::_S_blank)
- && (__c == __fctyp.widen(' ')
- || __c == __fctyp.widen('\t')));
+ // [[:w:]]
+ || ((__f._M_extended & _RegexMask::_S_under)
+ && __c == __fctyp.widen('_'))
+ // [[:blank:]]
+ || ((__f._M_extended & _RegexMask::_S_blank)
+ && (__c == __fctyp.widen(' ')
+ || __c == __fctyp.widen('\t')));
}
template<typename _Ch_type>
@@ -663,9 +657,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* character sequence.
*/
basic_regex()
- : _M_flags(ECMAScript),
- _M_automaton(__detail::__compile<const _Ch_type*, _Rx_traits>(0, 0,
- _M_traits, _M_flags))
+ : _M_flags(ECMAScript), _M_automaton(nullptr)
{ }
/**
@@ -681,9 +673,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
explicit
basic_regex(const _Ch_type* __p, flag_type __f = ECMAScript)
- : _M_flags(__f),
- _M_automaton(__detail::__compile(__p, __p + _Rx_traits::length(__p),
- _M_traits, _M_flags))
+ : basic_regex(__p, __p + _Rx_traits::length(__p), __f)
{ }
/**
@@ -698,9 +688,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* @throws regex_error if @p __p is not a valid regular expression.
*/
- basic_regex(const _Ch_type* __p, std::size_t __len, flag_type __f)
- : _M_flags(__f),
- _M_automaton(__detail::__compile(__p, __p + __len, _M_traits, _M_flags))
+ basic_regex(const _Ch_type* __p,
+ std::size_t __len, flag_type __f = ECMAScript)
+ : basic_regex(__p, __p + __len, __f)
{ }
/**
@@ -708,10 +698,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*
* @param __rhs A @p regex object.
*/
- basic_regex(const basic_regex& __rhs)
- : _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits),
- _M_automaton(__rhs._M_automaton)
- { }
+ basic_regex(const basic_regex& __rhs) = default;
/**
* @brief Move-constructs a basic regular expression.
@@ -720,7 +707,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
basic_regex(const basic_regex&& __rhs) noexcept
: _M_flags(__rhs._M_flags), _M_traits(__rhs._M_traits),
- _M_automaton(std::move(__rhs._M_automaton))
+ _M_automaton(std::move(__rhs._M_automaton))
{ }
/**
@@ -733,14 +720,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @throws regex_error if @p __s is not a valid regular expression.
*/
template<typename _Ch_traits, typename _Ch_alloc>
- explicit
- basic_regex(const std::basic_string<_Ch_type, _Ch_traits,
+ explicit
+ basic_regex(const std::basic_string<_Ch_type, _Ch_traits,
_Ch_alloc>& __s,
flag_type __f = ECMAScript)
- : _M_flags(__f),
- _M_automaton(__detail::__compile(__s.begin(), __s.end(),
- _M_traits, _M_flags))
- { }
+ : basic_regex(__s.begin(), __s.end(), __f)
+ { }
/**
* @brief Constructs a basic regular expression from the range
@@ -755,12 +740,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @throws regex_error if @p [__first, __last) is not a valid regular
* expression.
*/
- template<typename _InputIterator>
- basic_regex(_InputIterator __first, _InputIterator __last,
+ template<typename _FwdIter>
+ basic_regex(_FwdIter __first, _FwdIter __last,
flag_type __f = ECMAScript)
: _M_flags(__f),
- _M_automaton(__detail::__compile(__first, __last, _M_traits, _M_flags))
- { }
+ _M_automaton(__detail::_Compiler<_FwdIter, _Ch_type, _Rx_traits>
+ (__first, __last, _M_traits, _M_flags)._M_get_nfa())
+ { }
/**
* @brief Constructs a basic regular expression from an initializer list.
@@ -772,9 +758,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
basic_regex(initializer_list<_Ch_type> __l,
flag_type __f = ECMAScript)
- : _M_flags(__f),
- _M_automaton(__detail::__compile(__l.begin(), __l.end(),
- _M_traits, _M_flags))
+ : basic_regex(__l.begin(), __l.end(), __f)
{ }
/**
@@ -782,7 +766,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
~basic_regex()
{ }
-
+
/**
* @brief Assigns one regular expression to another.
*/
@@ -807,7 +791,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
basic_regex&
operator=(const _Ch_type* __p)
{ return this->assign(__p, flags()); }
-
+
/**
* @brief Replaces a regular expression with a new one constructed from
* a string.
@@ -815,9 +799,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __s A pointer to a string containing a regular expression.
*/
template<typename _Ch_typeraits, typename _Alloc>
- basic_regex&
- operator=(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s)
- { return this->assign(__s, flags()); }
+ basic_regex&
+ operator=(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s)
+ { return this->assign(__s, flags()); }
// [7.8.3] assign
/**
@@ -832,7 +816,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
this->swap(__tmp);
return *this;
}
-
+
/**
* @brief The move-assignment operator.
*
@@ -881,7 +865,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return this->assign(string_type(__p, __len), __flags); }
/**
- * @brief Assigns a new regular expression to a regex object from a
+ * @brief Assigns a new regular expression to a regex object from a
* string containing a regular expression pattern.
*
* @param __s A string containing a regular expression pattern.
@@ -892,12 +876,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* regex_error is thrown, *this remains unchanged.
*/
template<typename _Ch_typeraits, typename _Alloc>
- basic_regex&
- assign(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s,
+ basic_regex&
+ assign(const basic_string<_Ch_type, _Ch_typeraits, _Alloc>& __s,
flag_type __flags = ECMAScript)
- {
- basic_regex __tmp(__s, __flags);
- this->swap(__tmp);
+ {
+ _M_flags = __flags;
+ _M_automaton =
+ __detail::_Compiler<decltype(__s.begin()), _Ch_type, _Rx_traits>
+ (__s.begin(), __s.end(), _M_traits, _M_flags)._M_get_nfa();
return *this;
}
@@ -915,10 +901,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* regex_error is thrown, the object remains unchanged.
*/
template<typename _InputIterator>
- basic_regex&
- assign(_InputIterator __first, _InputIterator __last,
+ basic_regex&
+ assign(_InputIterator __first, _InputIterator __last,
flag_type __flags = ECMAScript)
- { return this->assign(string_type(__first, __last), __flags); }
+ { return this->assign(string_type(__first, __last), __flags); }
/**
* @brief Assigns a new regular expression to a regex object.
@@ -943,7 +929,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
unsigned int
mark_count() const
{ return _M_automaton->_M_sub_count() - 1; }
-
+
/**
* @brief Gets the flags used to construct the regular expression
* or in the last call to assign().
@@ -951,7 +937,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
flag_type
flags() const
{ return _M_flags; }
-
+
// [7.8.5] locale
/**
* @brief Imbues the regular expression object with the given locale.
@@ -961,7 +947,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
locale_type
imbue(locale_type __loc)
{ return _M_traits.imbue(__loc); }
-
+
/**
* @brief Gets the locale currently imbued in the regular expression
* object.
@@ -969,7 +955,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
locale_type
getloc() const
{ return _M_traits.getloc(); }
-
+
// [7.8.6] swap
/**
* @brief Swaps the contents of two regular expression objects.
@@ -989,17 +975,40 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_dot(std::ostream& __ostr)
{ _M_automaton->_M_dot(__ostr); }
#endif
-
- const __detail::_AutomatonPtr&
- _M_get_automaton() const
- { return _M_automaton; }
protected:
- flag_type _M_flags;
- _Rx_traits _M_traits;
- __detail::_AutomatonPtr _M_automaton;
+ typedef std::shared_ptr<__detail::_Automaton<_Ch_type, _Rx_traits>>
+ _AutomatonPtr;
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ friend std::unique_ptr<
+ __detail::_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+ __detail::__get_executor(_BiIter,
+ _BiIter,
+ match_results<_BiIter, _Alloc>&,
+ const basic_regex<_CharT, _TraitsT>&,
+ regex_constants::match_flag_type);
+
+ template<typename _Bp, typename _Ap, typename _Cp, typename _Rp>
+ friend bool
+ regex_match(_Bp, _Bp,
+ match_results<_Bp, _Ap>&,
+ const basic_regex<_Cp, _Rp>&,
+ regex_constants::match_flag_type);
+
+ template<typename _Bp, typename _Ap, typename _Cp, typename _Rp>
+ friend bool
+ regex_search(_Bp, _Bp,
+ match_results<_Bp, _Ap>&,
+ const basic_regex<_Cp, _Rp>&,
+ regex_constants::match_flag_type);
+
+ flag_type _M_flags;
+ _Rx_traits _M_traits;
+ _AutomatonPtr _M_automaton;
};
-
+
/** @brief Standard regular expressions. */
typedef basic_regex<char> regex;
@@ -1047,7 +1056,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef std::basic_string<value_type> string_type;
bool matched;
-
+
constexpr sub_match() : matched() { }
/**
@@ -1073,7 +1082,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
? string_type(this->first, this->second)
: string_type();
}
-
+
/**
* @brief Gets the matching sequence as a string.
*
@@ -1086,7 +1095,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
? string_type(this->first, this->second)
: string_type();
}
-
+
/**
* @brief Compares this and another matched sequence.
*
@@ -1112,7 +1121,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
int
compare(const string_type& __s) const
{ return this->str().compare(__s); }
-
+
/**
* @brief Compares this sub_match to a C-style string.
*
@@ -1126,8 +1135,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
compare(const value_type* __s) const
{ return this->str().compare(__s); }
};
-
-
+
+
/** @brief Standard regex submatch over a C-style null-terminated string. */
typedef sub_match<const char*> csub_match;
@@ -1143,7 +1152,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
#endif
// [7.9.2] sub_match non-member operators
-
+
/**
* @brief Tests the equivalence of two regular expression submatches.
* @param __lhs First regular expression submatch.
@@ -1213,8 +1222,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Alias for sub_match'd string.
template<typename _Bi_iter, typename _Ch_traits, typename _Ch_alloc>
using __sub_match_string = basic_string<
- typename iterator_traits<_Bi_iter>::value_type,
- _Ch_traits, _Ch_alloc>;
+ typename iterator_traits<_Bi_iter>::value_type,
+ _Ch_traits, _Ch_alloc>;
/**
* @brief Tests the equivalence of a string and a regular expression
@@ -1761,7 +1770,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef std::basic_string<char_type> string_type;
//@}
-
+
public:
/**
* @name 28.10.1 Construction, Copying, and Destruction
@@ -1816,7 +1825,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
~match_results()
{ }
-
+
//@}
// 28.10.2, state:
@@ -1847,7 +1856,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_type __size = _Base_type::size();
return (__size && _Base_type::operator[](0).matched) ? __size - 2 : 0;
}
-
+
size_type
max_size() const
{ return _Base_type::max_size(); }
@@ -1860,7 +1869,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
empty() const
{ return size() == 0; }
-
+
//@}
/**
@@ -1912,7 +1921,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
string_type
str(size_type __sub = 0) const
{ return (*this)[__sub].str(); }
-
+
/**
* @brief Gets a %sub_match reference for the match or submatch.
* @param __sub indicates the submatch.
@@ -1926,7 +1935,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
const_reference
operator[](size_type __sub) const
- {
+ {
_GLIBCXX_DEBUG_ASSERT( ready() );
return __sub < size()
? _Base_type::operator[](__sub)
@@ -1973,7 +1982,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const_iterator
begin() const
{ return _Base_type::begin(); }
-
+
/**
* @brief Gets an iterator to the start of the %sub_match collection.
*/
@@ -1987,7 +1996,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const_iterator
end() const
{ return !empty() ? _Base_type::end() - 2 : _Base_type::end(); }
-
+
/**
* @brief Gets an iterator to one-past-the-end of the collection.
*/
@@ -2012,36 +2021,36 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @todo Implement this function.
*/
template<typename _Out_iter>
- _Out_iter
- format(_Out_iter __out, const char_type* __fmt_first,
+ _Out_iter
+ format(_Out_iter __out, const char_type* __fmt_first,
const char_type* __fmt_last,
match_flag_type __flags = regex_constants::format_default) const
- { return __out; }
+ { return __out; }
/**
* @pre ready() == true
*/
template<typename _Out_iter, typename _St, typename _Sa>
- _Out_iter
- format(_Out_iter __out, const basic_string<char_type, _St, _Sa>& __fmt,
+ _Out_iter
+ format(_Out_iter __out, const basic_string<char_type, _St, _Sa>& __fmt,
match_flag_type __flags = regex_constants::format_default) const
- {
- return format(__out, __fmt.data(), __fmt.data() + __fmt.size(),
- __flags);
- }
+ {
+ return format(__out, __fmt.data(), __fmt.data() + __fmt.size(),
+ __flags);
+ }
/**
* @pre ready() == true
*/
template<typename _Out_iter, typename _St, typename _Sa>
- basic_string<char_type, _St, _Sa>
- format(const basic_string<char_type, _St, _Sa>& __fmt,
+ basic_string<char_type, _St, _Sa>
+ format(const basic_string<char_type, _St, _Sa>& __fmt,
match_flag_type __flags = regex_constants::format_default) const
- {
- basic_string<char_type, _St, _Sa> __result;
- format(std::back_inserter(__result), __fmt, __flags);
- return __result;
- }
+ {
+ basic_string<char_type, _St, _Sa> __result;
+ format(std::back_inserter(__result), __fmt, __flags);
+ return __result;
+ }
/**
* @pre ready() == true
@@ -2050,19 +2059,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
format(const char_type* __fmt,
match_flag_type __flags = regex_constants::format_default) const
{
- string_type __result;
- format(std::back_inserter(__result),
- __fmt + char_traits<char_type>::length(__fmt),
- __flags);
- return __result;
+ string_type __result;
+ format(std::back_inserter(__result),
+ __fmt,
+ __fmt + char_traits<char_type>::length(__fmt),
+ __flags);
+ return __result;
}
- //@}
+ //@}
/**
* @name 10.5 Allocator
*/
- //@{
+ //@{
/**
* @brief Gets a copy of the allocator.
@@ -2070,13 +2080,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
allocator_type
get_allocator() const
{ return _Base_type::get_allocator(); }
-
- //@}
+
+ //@}
/**
* @name 10.6 Swap
*/
- //@{
+ //@{
/**
* @brief Swaps the contents of two match_results.
@@ -2084,12 +2094,33 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
swap(match_results& __that)
{ _Base_type::swap(__that); }
- //@}
-
+ //@}
+
private:
- friend class __detail::_SpecializedResults<_Bi_iter, _Alloc>;
+ template<typename, typename, typename, typename>
+ friend class __detail::_Executor;
+
+ template<typename, typename, typename, typename>
+ friend class __detail::_DFSExecutor;
+
+ template<typename, typename, typename, typename>
+ friend class __detail::_BFSExecutor;
+
+ template<typename _Bp, typename _Ap, typename _Ch_type, typename _Rx_traits>
+ friend bool
+ regex_match(_Bp, _Bp, match_results<_Bp, _Ap>&,
+ const basic_regex<_Ch_type,
+ _Rx_traits>&,
+ regex_constants::match_flag_type);
+
+ template<typename _Bp, typename _Ap, typename _Ch_type, typename _Rx_traits>
+ friend bool
+ regex_search(_Bp, _Bp, match_results<_Bp, _Ap>&,
+ const basic_regex<_Ch_type,
+ _Rx_traits>&,
+ regex_constants::match_flag_type);
};
-
+
typedef match_results<const char*> cmatch;
typedef match_results<string::const_iterator> smatch;
#ifdef _GLIBCXX_USE_WCHAR_T
@@ -2109,17 +2140,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const match_results<_Bi_iter, _Alloc>& __m2)
{
if (__m1.ready() != __m2.ready())
- return false;
+ return false;
if (!__m1.ready()) // both are not ready
- return true;
+ return true;
if (__m1.empty() != __m2.empty())
- return false;
+ return false;
if (__m1.empty()) // both are empty
- return true;
+ return true;
return __m1.prefix() == __m2.prefix()
- && __m1.size() == __m2.size()
- && std::equal(__m1.begin(), __m1.end(), __m2.begin())
- && __m1.suffix() == __m2.suffix();
+ && __m1.size() == __m2.size()
+ && std::equal(__m1.begin(), __m1.end(), __m2.begin())
+ && __m1.suffix() == __m2.suffix();
}
/**
@@ -2174,18 +2205,29 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Ch_type, typename _Rx_traits>
bool
regex_match(_Bi_iter __s,
- _Bi_iter __e,
- match_results<_Bi_iter, _Alloc>& __m,
- const basic_regex<_Ch_type, _Rx_traits>& __re,
- regex_constants::match_flag_type __flags
- = regex_constants::match_default)
+ _Bi_iter __e,
+ match_results<_Bi_iter, _Alloc>& __m,
+ const basic_regex<_Ch_type, _Rx_traits>& __re,
+ regex_constants::match_flag_type __flags
+ = regex_constants::match_default)
{
- __detail::_AutomatonPtr __a = __re._M_get_automaton();
- __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
- __detail::_SpecializedCursor<_Bi_iter> __cs(__s, __e);
- __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
- __detail::_Grep_matcher __matcher(__cs, __r, __a, __flags);
- return __matcher._M_dfs_match();
+ if (__re._M_automaton == nullptr)
+ return false;
+ __detail::__get_executor(__s, __e, __m, __re, __flags)->_M_match();
+ if (__m.size() > 0 && __m[0].matched)
+ {
+ for (auto __it : __m)
+ if (!__it.matched)
+ __it.first = __it.second = __e;
+ __m.at(__m.size()).matched = false;
+ __m.at(__m.size()).first = __s;
+ __m.at(__m.size()).second = __s;
+ __m.at(__m.size()+1).matched = false;
+ __m.at(__m.size()+1).first = __e;
+ __m.at(__m.size()+1).second = __e;
+ return true;
+ }
+ return false;
}
/**
@@ -2208,7 +2250,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const basic_regex<_Ch_type, _Rx_traits>& __re,
regex_constants::match_flag_type __flags
= regex_constants::match_default)
- {
+ {
match_results<_Bi_iter> __what;
return regex_match(__first, __last, __what, __re, __flags);
}
@@ -2254,7 +2296,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Alloc, typename _Ch_type, typename _Rx_traits>
inline bool
regex_match(const basic_string<_Ch_type, _Ch_traits, _Ch_alloc>& __s,
- match_results<typename basic_string<_Ch_type,
+ match_results<typename basic_string<_Ch_type,
_Ch_traits, _Ch_alloc>::const_iterator, _Alloc>& __m,
const basic_regex<_Ch_type, _Rx_traits>& __re,
regex_constants::match_flag_type __flags
@@ -2324,38 +2366,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typename _Ch_type, typename _Rx_traits>
inline bool
regex_search(_Bi_iter __first, _Bi_iter __last,
- match_results<_Bi_iter, _Alloc>& __m,
- const basic_regex<_Ch_type, _Rx_traits>& __re,
- regex_constants::match_flag_type __flags
- = regex_constants::match_default)
+ match_results<_Bi_iter, _Alloc>& __m,
+ const basic_regex<_Ch_type, _Rx_traits>& __re,
+ regex_constants::match_flag_type __flags
+ = regex_constants::match_default)
{
- __detail::_AutomatonPtr __a = __re._M_get_automaton();
- __detail::_Automaton::_SizeT __sz = __a->_M_sub_count();
- __detail::_SpecializedCursor<_Bi_iter> __cs(__first, __last);
- __detail::_SpecializedResults<_Bi_iter, _Alloc> __r(__sz, __cs, __m);
- for (auto __cur = __first; __cur != __last; ++__cur) // Any KMP-like algo?
- {
- __detail::_SpecializedCursor<_Bi_iter> __curs(__cur, __last);
- __detail::_Grep_matcher __matcher(__curs, __r, __a, __flags);
- if (__matcher._M_dfs_search_from_first())
- {
- __r._M_set_range(__m.size(),
- __detail::_SpecializedCursor<_Bi_iter>
- {__first, __m[0].first});
- __r._M_set_range(__m.size()+1,
- __detail::_SpecializedCursor<_Bi_iter>
- {__m[0].second, __last});
- __r._M_set_matched(__m.size(),
- __m.prefix().first != __m.prefix().second);
- __r._M_set_matched(__m.size()+1,
- __m.suffix().first != __m.suffix().second);
- return true;
- }
- }
+ if (__re._M_automaton == nullptr)
+ return false;
+ auto __cur = __first;
+ // Continue when __cur == __last
+ do
+ {
+ __detail::__get_executor(__cur, __last, __m, __re, __flags)
+ ->_M_search_from_first();
+ if (__m.size() > 0 && __m[0].matched)
+ {
+ for (auto __it : __m)
+ if (!__it.matched)
+ __it.first = __it.second = __last;
+ __m.at(__m.size()).first = __first;
+ __m.at(__m.size()).second = __m[0].first;
+ __m.at(__m.size()+1).first = __m[0].second;
+ __m.at(__m.size()+1).second = __last;
+ __m.at(__m.size()).matched =
+ (__m.prefix().first != __m.prefix().second);
+ __m.at(__m.size()+1).matched =
+ (__m.suffix().first != __m.suffix().second);
+ return true;
+ }
+ }
+ while (__cur++ != __last);
return false;
}
-
/**
* Searches for a regular expression within a range.
* @param __first [IN] The start of the string to search.
@@ -2515,7 +2558,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// std [28.12] Class template regex_iterator
/**
- * An iterator adaptor that will provide repeated calls of regex_search over
+ * An iterator adaptor that will provide repeated calls of regex_search over
* a range until no more matches remain.
*/
template<typename _Bi_iter,
@@ -2538,7 +2581,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
regex_iterator()
: _M_match()
{ }
-
+
/**
* Constructs a %regex_iterator...
* @param __a [IN] The start of a text range to search.
@@ -2550,63 +2593,66 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
regex_constants::match_flag_type __m
= regex_constants::match_default)
: _M_begin(__a), _M_end(__b), _M_pregex(&__re), _M_flags(__m), _M_match()
- { regex_search(_M_begin, _M_end, _M_match, *_M_pregex, _M_flags); }
+ {
+ if (!regex_search(_M_begin, _M_end, _M_match, *_M_pregex, _M_flags))
+ *this = regex_iterator();
+ }
/**
* Copy constructs a %regex_iterator.
*/
regex_iterator(const regex_iterator& __rhs) = default;
-
+
/**
* @brief Assigns one %regex_iterator to another.
*/
regex_iterator&
operator=(const regex_iterator& __rhs) = default;
-
+
/**
* @brief Tests the equivalence of two regex iterators.
*/
bool
operator==(const regex_iterator& __rhs) const;
-
+
/**
* @brief Tests the inequivalence of two regex iterators.
*/
bool
operator!=(const regex_iterator& __rhs) const
{ return !(*this == __rhs); }
-
+
/**
* @brief Dereferences a %regex_iterator.
*/
const value_type&
operator*() const
{ return _M_match; }
-
+
/**
* @brief Selects a %regex_iterator member.
*/
const value_type*
operator->() const
{ return &_M_match; }
-
+
/**
* @brief Increments a %regex_iterator.
*/
regex_iterator&
operator++();
-
+
/**
* @brief Postincrements a %regex_iterator.
*/
regex_iterator
operator++(int)
{
- auto __tmp = *this;
- ++(*this);
- return __tmp;
+ auto __tmp = *this;
+ ++(*this);
+ return __tmp;
}
-
+
private:
_Bi_iter _M_begin;
_Bi_iter _M_end;
@@ -2623,11 +2669,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
operator==(const regex_iterator& __rhs) const
{
return (_M_match.empty() && __rhs._M_match.empty())
- || (_M_begin == __rhs._M_begin
- && _M_end == __rhs._M_end
- && _M_pregex == __rhs._M_pregex
- && _M_flags == __rhs._M_flags
- && _M_match[0] == __rhs._M_match[0]);
+ || (_M_begin == __rhs._M_begin
+ && _M_end == __rhs._M_end
+ && _M_pregex == __rhs._M_pregex
+ && _M_flags == __rhs._M_flags
+ && _M_match[0] == __rhs._M_match[0]);
}
template<typename _Bi_iter,
@@ -2644,30 +2690,30 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// match[i].position() shall return distance(begin, match[i].first).
// [28.12.1.4.5]
if (_M_match[0].matched)
- {
- auto __start = _M_match[0].second;
- if (_M_match[0].first == _M_match[0].second)
- if (__start == _M_end)
- {
- _M_match = value_type();
- return *this;
- }
- else
- {
- if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags
- | regex_constants::match_not_null
- | regex_constants::match_continuous))
- return *this;
- else
- ++__start;
- }
- _M_flags |= regex_constants::match_prev_avail;
- if (!regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags))
- _M_match = value_type();
- }
+ {
+ auto __start = _M_match[0].second;
+ if (_M_match[0].first == _M_match[0].second)
+ if (__start == _M_end)
+ {
+ _M_match = value_type();
+ return *this;
+ }
+ else
+ {
+ if (regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags
+ | regex_constants::match_not_null
+ | regex_constants::match_continuous))
+ return *this;
+ else
+ ++__start;
+ }
+ _M_flags |= regex_constants::match_prev_avail;
+ if (!regex_search(__start, _M_end, _M_match, *_M_pregex, _M_flags))
+ _M_match = value_type();
+ }
return *this;
}
-
+
typedef regex_iterator<const char*> cregex_iterator;
typedef regex_iterator<string::const_iterator> sregex_iterator;
#ifdef _GLIBCXX_USE_WCHAR_T
@@ -2684,8 +2730,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* value of an iterator of this class is a std::sub_match object.
*/
template<typename _Bi_iter,
- typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type,
- typename _Rx_traits = regex_traits<_Ch_type> >
+ typename _Ch_type = typename iterator_traits<_Bi_iter>::value_type,
+ typename _Rx_traits = regex_traits<_Ch_type> >
class regex_token_iterator
{
public:
@@ -2695,11 +2741,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
typedef const value_type* pointer;
typedef const value_type& reference;
typedef std::forward_iterator_tag iterator_category;
-
+
public:
/**
* @brief Default constructs a %regex_token_iterator.
- *
+ *
* A default-constructed %regex_token_iterator is a singular iterator
* that will compare equal to the one-past-the-end value for any
* iterator of the same type.
@@ -2707,7 +2753,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
regex_token_iterator()
: _M_position(), _M_result(nullptr), _M_suffix(), _M_n(0), _M_subs()
{ }
-
+
/**
* Constructs a %regex_token_iterator...
* @param __a [IN] The start of the text to search.
@@ -2760,7 +2806,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
*/
regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
const regex_type& __re,
- initializer_list<int> __submatches,
+ initializer_list<int> __submatches,
regex_constants::match_flag_type __m
= regex_constants::match_default)
: _M_position(__a, __b, __re, __m), _M_subs(__submatches), _M_n(0)
@@ -2776,7 +2822,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @param __m [IN] Policy flags for match rules.
*/
template<std::size_t _Nm>
- regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
+ regex_token_iterator(_Bi_iter __a, _Bi_iter __b,
const regex_type& __re,
const int (&__submatches)[_Nm],
regex_constants::match_flag_type __m
@@ -2794,8 +2840,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_result(__rhs.result), _M_suffix(__rhs.suffix),
_M_has_m1(__rhs._M_has_m1)
{
- if (__rhs._M_result == &__rhs._M_suffix)
- _M_result = &_M_suffix;
+ if (__rhs._M_result == &__rhs._M_suffix)
+ _M_result = &_M_suffix;
}
/**
@@ -2844,9 +2890,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
regex_token_iterator
operator++(int)
{
- auto __tmp = *this;
- ++(*this);
- return __tmp;
+ auto __tmp = *this;
+ ++(*this);
+ return __tmp;
}
private:
@@ -2858,15 +2904,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
const value_type&
_M_current_match() const
{
- if (_M_subs[_M_n] == -1)
- return (*_M_position).prefix();
- else
- return (*_M_position)[_M_subs[_M_n]];
+ if (_M_subs[_M_n] == -1)
+ return (*_M_position).prefix();
+ else
+ return (*_M_position)[_M_subs[_M_n]];
}
- bool
- _M_end_of_seq() const
- { return _M_result != nullptr; }
+ constexpr bool
+ _M_end_of_seq()
+ { return _M_result == nullptr; }
_Position _M_position;
const value_type* _M_result;
@@ -2879,8 +2925,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
};
template<typename _Bi_iter,
- typename _Ch_type,
- typename _Rx_traits>
+ typename _Ch_type,
+ typename _Rx_traits>
regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator=(const regex_token_iterator& __rhs)
@@ -2892,88 +2938,88 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_suffix = __rhs._M_suffix;
_M_has_m1 = __rhs._M_has_m1;
if (__rhs._M_result == &__rhs._M_suffix)
- _M_result = &_M_suffix;
+ _M_result = &_M_suffix;
}
template<typename _Bi_iter,
- typename _Ch_type,
- typename _Rx_traits>
+ typename _Ch_type,
+ typename _Rx_traits>
bool
regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator==(const regex_token_iterator& __rhs) const
{
if (_M_end_of_seq() && __rhs._M_end_of_seq())
- return true;
+ return true;
if (_M_suffix.matched && __rhs._M_suffix.matched
- && _M_suffix == __rhs._M_suffix)
- return true;
+ && _M_suffix == __rhs._M_suffix)
+ return true;
if (_M_end_of_seq() || _M_suffix.matched
- || __rhs._M_end_of_seq() || __rhs._M_suffix.matched)
- return false;
+ || __rhs._M_end_of_seq() || __rhs._M_suffix.matched)
+ return false;
return _M_position == __rhs._M_position
- && _M_n == __rhs._M_n
- && _M_subs == __rhs._M_subs;
+ && _M_n == __rhs._M_n
+ && _M_subs == __rhs._M_subs;
}
template<typename _Bi_iter,
- typename _Ch_type,
- typename _Rx_traits>
+ typename _Ch_type,
+ typename _Rx_traits>
regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>&
regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
operator++()
{
_Position __prev = _M_position;
if (_M_suffix.matched)
- *this = regex_token_iterator();
+ *this = regex_token_iterator();
else if (_M_n + 1 < _M_subs.size())
- {
- _M_n++;
- _M_result = &_M_current_match();
- }
+ {
+ _M_n++;
+ _M_result = &_M_current_match();
+ }
else
- {
- _M_n = 0;
- ++_M_position;
- if (_M_position != _Position())
- _M_result = &_M_current_match();
- else if (_M_has_m1 && __prev->suffix().length() != 0)
- {
- _M_suffix.matched = true;
- _M_suffix.first = __prev->suffix().first;
- _M_suffix.second = __prev->suffix().second;
- _M_result = &_M_suffix;
- }
- else
- *this = regex_token_iterator();
- }
+ {
+ _M_n = 0;
+ ++_M_position;
+ if (_M_position != _Position())
+ _M_result = &_M_current_match();
+ else if (_M_has_m1 && __prev->suffix().length() != 0)
+ {
+ _M_suffix.matched = true;
+ _M_suffix.first = __prev->suffix().first;
+ _M_suffix.second = __prev->suffix().second;
+ _M_result = &_M_suffix;
+ }
+ else
+ *this = regex_token_iterator();
+ }
return *this;
}
template<typename _Bi_iter,
- typename _Ch_type,
- typename _Rx_traits>
+ typename _Ch_type,
+ typename _Rx_traits>
void
regex_token_iterator<_Bi_iter, _Ch_type, _Rx_traits>::
_M_init(_Bi_iter __a, _Bi_iter __b)
{
_M_has_m1 = false;
for (auto __it : _M_subs)
- if (__it == -1)
- {
- _M_has_m1 = true;
- break;
- }
+ if (__it == -1)
+ {
+ _M_has_m1 = true;
+ break;
+ }
if (_M_position != _Position())
- _M_result = &_M_current_match();
+ _M_result = &_M_current_match();
else if (_M_has_m1)
- {
- _M_suffix.matched = true;
- _M_suffix.first = __a;
- _M_suffix.second = __b;
- _M_result = &_M_suffix;
- }
+ {
+ _M_suffix.matched = true;
+ _M_suffix.first = __a;
+ _M_suffix.second = __b;
+ _M_result = &_M_suffix;
+ }
else
- _M_result = nullptr;
+ _M_result = nullptr;
}
/** @brief Token iterator for C-style NULL-terminated strings. */
@@ -2989,7 +3035,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
/** @brief Token iterator for standard wide-character strings. */
typedef regex_token_iterator<wstring::const_iterator> wsregex_token_iterator;
#endif
-
+
//@} // group regex
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
diff --git a/libstdc++-v3/include/bits/regex_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h
new file mode 100644
index 00000000000..77551756f65
--- /dev/null
+++ b/libstdc++-v3/include/bits/regex_automaton.h
@@ -0,0 +1,285 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/**
+ * @file bits/regex_automaton.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @defgroup regex-detail Base and Implementation Classes
+ * @ingroup regex
+ * @{
+ */
+
+ typedef int _StateIdT;
+ typedef std::set<_StateIdT> _StateSet;
+ static const _StateIdT _S_invalid_state_id = -1;
+
+ template<typename _CharT>
+ using _Matcher = std::function<bool (_CharT)>;
+
+ /// Operation codes that define the type of transitions within the base NFA
+ /// that represents the regular expression.
+ enum _Opcode
+ {
+ _S_opcode_unknown = 0,
+ _S_opcode_alternative = 1,
+ _S_opcode_backref = 2,
+ _S_opcode_subexpr_begin = 4,
+ _S_opcode_subexpr_end = 5,
+ _S_opcode_dummy = 6,
+ _S_opcode_match = 100,
+ _S_opcode_accept = 255
+ };
+
+ template<typename _CharT, typename _TraitsT>
+ class _State
+ {
+ public:
+ typedef int _OpcodeT;
+ typedef _Matcher<_CharT> _MatcherT;
+
+ _OpcodeT _M_opcode; // type of outgoing transition
+ _StateIdT _M_next; // outgoing transition
+ union // Since they are mutually exclusive.
+ {
+ _StateIdT _M_alt; // for _S_opcode_alternative
+ unsigned int _M_subexpr; // for _S_opcode_subexpr_*
+ unsigned int _M_backref_index; // for _S_opcode_backref
+ };
+ _MatcherT _M_matches; // for _S_opcode_match
+
+ explicit _State(_OpcodeT __opcode)
+ : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
+ { }
+
+ _State(const _MatcherT& __m)
+ : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id),
+ _M_matches(__m)
+ { }
+
+ _State(_OpcodeT __opcode, unsigned __index)
+ : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
+ {
+ if (__opcode == _S_opcode_subexpr_begin
+ || __opcode == _S_opcode_subexpr_end)
+ _M_subexpr = __index;
+ else if (__opcode == _S_opcode_backref)
+ _M_backref_index = __index;
+ }
+
+ _State(_StateIdT __next, _StateIdT __alt)
+ : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt)
+ { }
+
+#ifdef _GLIBCXX_DEBUG
+ std::ostream&
+ _M_print(std::ostream& ostr) const;
+
+ // Prints graphviz dot commands for state.
+ std::ostream&
+ _M_dot(std::ostream& __ostr, _StateIdT __id) const;
+#endif
+ };
+
+ /// Base class for, um, automata. Could be an NFA or a DFA. Your choice.
+ template<typename _CharT, typename _TraitsT>
+ class _Automaton
+ {
+ public:
+ typedef unsigned int _SizeT;
+
+ public:
+ virtual _SizeT
+ _M_sub_count() const = 0;
+
+#ifdef _GLIBCXX_DEBUG
+ virtual std::ostream&
+ _M_dot(std::ostream& __ostr) const = 0;
+#endif
+ };
+
+ template<typename _CharT, typename _TraitsT>
+ class _NFA
+ : public _Automaton<_CharT, _TraitsT>,
+ public std::vector<_State<_CharT, _TraitsT>>
+ {
+ public:
+ typedef _State<_CharT, _TraitsT> _StateT;
+ typedef const _Matcher<_CharT>& _MatcherT;
+ typedef unsigned int _SizeT;
+ typedef regex_constants::syntax_option_type _FlagT;
+
+ _NFA(_FlagT __f)
+ : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0),
+ _M_has_backref(false)
+ { }
+
+ _FlagT
+ _M_options() const
+ { return _M_flags; }
+
+ _StateIdT
+ _M_start() const
+ { return _M_start_state; }
+
+ const _StateSet&
+ _M_final_states() const
+ { return _M_accepting_states; }
+
+ _SizeT
+ _M_sub_count() const
+ { return _M_subexpr_count; }
+
+ _StateIdT
+ _M_insert_accept()
+ {
+ this->push_back(_StateT(_S_opcode_accept));
+ _M_accepting_states.insert(this->size()-1);
+ return this->size()-1;
+ }
+
+ _StateIdT
+ _M_insert_alt(_StateIdT __next, _StateIdT __alt)
+ {
+ this->push_back(_StateT(__next, __alt));
+ return this->size()-1;
+ }
+
+ _StateIdT
+ _M_insert_matcher(_MatcherT __m)
+ {
+ this->push_back(_StateT(__m));
+ return this->size()-1;
+ }
+
+ _StateIdT
+ _M_insert_subexpr_begin()
+ {
+ auto __id = _M_subexpr_count++;
+ _M_paren_stack.push_back(__id);
+ this->push_back(_StateT(_S_opcode_subexpr_begin, __id));
+ return this->size()-1;
+ }
+
+ _StateIdT
+ _M_insert_subexpr_end()
+ {
+ this->push_back(_StateT(_S_opcode_subexpr_end, _M_paren_stack.back()));
+ _M_paren_stack.pop_back();
+ return this->size()-1;
+ }
+
+ _StateIdT
+ _M_insert_backref(unsigned int __index);
+
+ _StateIdT
+ _M_insert_dummy()
+ {
+ this->push_back(_StateT(_S_opcode_dummy));
+ return this->size()-1;
+ }
+
+ _StateIdT
+ _M_insert_state(_StateT __s)
+ {
+ this->push_back(__s);
+ return this->size()-1;
+ }
+
+ // Eliminate dummy node in this NFA to make it compact.
+ void
+ _M_eliminate_dummy();
+
+#ifdef _GLIBCXX_DEBUG
+ std::ostream&
+ _M_dot(std::ostream& __ostr) const;
+#endif
+
+ std::vector<unsigned int> _M_paren_stack;
+ _StateSet _M_accepting_states;
+ _FlagT _M_flags;
+ _StateIdT _M_start_state;
+ _SizeT _M_subexpr_count;
+ bool _M_has_backref;
+ };
+
+ /// Describes a sequence of one or more %_State, its current start
+ /// and end(s). This structure contains fragments of an NFA during
+ /// construction.
+ template<typename _CharT, typename _TraitsT>
+ class _StateSeq
+ {
+ public:
+ typedef _NFA<_CharT, _TraitsT> _RegexT;
+
+ public:
+ _StateSeq(_RegexT& __nfa, _StateIdT __s)
+ : _StateSeq(__nfa, __s, __s)
+ { }
+
+ _StateSeq(_RegexT& __nfa, _StateIdT __s, _StateIdT __end)
+ : _M_nfa(__nfa), _M_start(__s), _M_end(__end)
+ { }
+
+ // Append a state on *this and change *this to the new sequence.
+ void
+ _M_append(_StateIdT __id)
+ {
+ _M_nfa[_M_end]._M_next = __id;
+ _M_end = __id;
+ }
+
+ // Append a sequence on *this and change *this to the new sequence.
+ void
+ _M_append(const _StateSeq& __s)
+ {
+ _M_nfa[_M_end]._M_next = __s._M_start;
+ _M_end = __s._M_end;
+ }
+
+ // Clones an entire sequence.
+ _StateSeq
+ _M_clone();
+
+ public:
+ _RegexT& _M_nfa;
+ _StateIdT _M_start;
+ _StateIdT _M_end;
+ };
+
+ //@} regex-detail
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#include <bits/regex_automaton.tcc>
diff --git a/libstdc++-v3/include/bits/regex_automaton.tcc b/libstdc++-v3/include/bits/regex_automaton.tcc
new file mode 100644
index 00000000000..2d34b95cdba
--- /dev/null
+++ b/libstdc++-v3/include/bits/regex_automaton.tcc
@@ -0,0 +1,207 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/**
+ * @file bits/regex_automaton.tcc
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#ifdef _GLIBCXX_DEBUG
+ template<typename _CharT, typename _TraitsT>
+ std::ostream& _State<_CharT, _TraitsT>::
+ _M_print(std::ostream& ostr) const
+ {
+ switch (_M_opcode)
+ {
+ case _S_opcode_alternative:
+ ostr << "alt next=" << _M_next << " alt=" << _M_alt;
+ break;
+ case _S_opcode_subexpr_begin:
+ ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr;
+ break;
+ case _S_opcode_subexpr_end:
+ ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr;
+ break;
+ case _S_opcode_backref:
+ ostr << "backref next=" << _M_next << " index=" << _M_backref_index;
+ break;
+ case _S_opcode_match:
+ ostr << "match next=" << _M_next;
+ break;
+ case _S_opcode_accept:
+ ostr << "accept next=" << _M_next;
+ break;
+ default:
+ ostr << "unknown next=" << _M_next;
+ break;
+ }
+ return ostr;
+ }
+
+ // Prints graphviz dot commands for state.
+ template<typename _CharT, typename _TraitsT>
+ std::ostream& _State<_CharT, _TraitsT>::
+ _M_dot(std::ostream& __ostr, _StateIdT __id) const
+ {
+ switch (_M_opcode)
+ {
+ case _S_opcode_alternative:
+ __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n"
+ << __id << " -> " << _M_next
+ << " [label=\"epsilon\", tailport=\"s\"];\n"
+ << __id << " -> " << _M_alt
+ << " [label=\"epsilon\", tailport=\"n\"];\n";
+ break;
+ case _S_opcode_subexpr_begin:
+ __ostr << __id << " [label=\"" << __id << "\\nSBEGIN "
+ << _M_subexpr << "\"];\n"
+ << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
+ break;
+ case _S_opcode_subexpr_end:
+ __ostr << __id << " [label=\"" << __id << "\\nSEND "
+ << _M_subexpr << "\"];\n"
+ << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
+ break;
+ case _S_opcode_backref:
+ __ostr << __id << " [label=\"" << __id << "\\nBACKREF "
+ << _M_subexpr << "\"];\n"
+ << __id << " -> " << _M_next << " [label=\"<match>\"];\n";
+ break;
+ case _S_opcode_match:
+ __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n"
+ << __id << " -> " << _M_next << " [label=\"<match>\"];\n";
+ break;
+ case _S_opcode_accept:
+ __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ;
+ break;
+ case _S_opcode_dummy:
+ break;
+ default:
+ _GLIBCXX_DEBUG_ASSERT(false);
+ break;
+ }
+ return __ostr;
+ }
+
+ template<typename _CharT, typename _TraitsT>
+ std::ostream& _NFA<_CharT, _TraitsT>::
+ _M_dot(std::ostream& __ostr) const
+ {
+ __ostr << "digraph _Nfa {\n"
+ << " rankdir=LR;\n";
+ for (unsigned int __i = 0; __i < this->size(); ++__i)
+ { this->at(__i)._M_dot(__ostr, __i); }
+ __ostr << "}\n";
+ return __ostr;
+ }
+#endif
+
+ template<typename _CharT, typename _TraitsT>
+ _StateIdT _NFA<_CharT, _TraitsT>::
+ _M_insert_backref(unsigned int __index)
+ {
+ // To figure out whether a backref is valid, a stack is used to store
+ // unfinished sub-expressions. For example, when parsing
+ // "(a(b)(c\\1(d)))" at '\\1', _M_subexpr_count is 3, indicating that 3
+ // sub expressions are parsed or partially parsed(in the stack), aka,
+ // "(a..", "(b)" and "(c..").
+ // _M_paren_stack is {1, 3}, for incomplete "(a.." and "(c..". At this
+ // time, "\\2" is valid, but "\\1" and "\\3" are not.
+ if (__index >= _M_subexpr_count)
+ __throw_regex_error(regex_constants::error_backref);
+ for (auto __it : _M_paren_stack)
+ if (__index == __it)
+ __throw_regex_error(regex_constants::error_backref);
+ _M_has_backref = true;
+ this->push_back(_StateT(_S_opcode_backref, __index));
+ return this->size()-1;
+ }
+
+ template<typename _CharT, typename _TraitsT>
+ void _NFA<_CharT, _TraitsT>::
+ _M_eliminate_dummy()
+ {
+ for (auto& __it : *this)
+ {
+ while (__it._M_next >= 0 && (*this)[__it._M_next]._M_opcode
+ == _S_opcode_dummy)
+ __it._M_next = (*this)[__it._M_next]._M_next;
+ if (__it._M_opcode == _S_opcode_alternative)
+ while (__it._M_alt >= 0 && (*this)[__it._M_alt]._M_opcode
+ == _S_opcode_dummy)
+ __it._M_alt = (*this)[__it._M_alt]._M_next;
+ }
+ }
+
+ // Just apply DFS on the sequence and re-link their links.
+ template<typename _CharT, typename _TraitsT>
+ _StateSeq<_CharT, _TraitsT> _StateSeq<_CharT, _TraitsT>::
+ _M_clone()
+ {
+ std::map<_StateIdT, _StateIdT> __m;
+ std::stack<_StateIdT> __stack;
+ __stack.push(_M_start);
+ while (!__stack.empty())
+ {
+ auto __u = __stack.top();
+ __stack.pop();
+ auto __dup = _M_nfa[__u];
+ auto __id = _M_nfa._M_insert_state(__dup);
+ __m[__u] = __id;
+ if (__u == _M_end)
+ continue;
+ if (__m.count(__dup._M_next) == 0)
+ __stack.push(__dup._M_next);
+ if (__dup._M_opcode == _S_opcode_alternative)
+ if (__m.count(__dup._M_alt) == 0)
+ __stack.push(__dup._M_alt);
+ }
+ for (auto __it : __m)
+ {
+ auto& __ref = _M_nfa[__it.second];
+ if (__ref._M_next != -1)
+ {
+ _GLIBCXX_DEBUG_ASSERT(__m.count(__ref._M_next));
+ __ref._M_next = __m[__ref._M_next];
+ }
+ if (__ref._M_opcode == _S_opcode_alternative)
+ if (__ref._M_alt != -1)
+ {
+ _GLIBCXX_DEBUG_ASSERT(__m.count(__ref._M_alt));
+ __ref._M_alt = __m[__ref._M_alt];
+ }
+ }
+ return _StateSeq(_M_nfa, __m[_M_start], __m[_M_end]);
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h
index dae0948404c..96a0d294177 100644
--- a/libstdc++-v3/include/bits/regex_compiler.h
+++ b/libstdc++-v3/include/bits/regex_compiler.h
@@ -39,618 +39,32 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @{
*/
- /// Base class for scanner.
- struct _Scanner_base
- {
- typedef unsigned int _StateT;
-
- static constexpr _StateT _S_state_at_start = 1 << 0;
- static constexpr _StateT _S_state_in_brace = 1 << 2;
- static constexpr _StateT _S_state_in_bracket = 1 << 3;
-
- virtual ~_Scanner_base() { };
- };
-
- /**
- * @brief struct _Scanner. Scans an input range for regex tokens.
- *
- * The %_Scanner class interprets the regular expression pattern in
- * the input range passed to its constructor as a sequence of parse
- * tokens passed to the regular expression compiler. The sequence
- * of tokens provided depends on the flag settings passed to the
- * constructor: different regular expression grammars will interpret
- * the same input pattern in syntactically different ways.
- */
- template<typename _InputIterator>
- class _Scanner: public _Scanner_base
- {
- public:
- typedef _InputIterator _IteratorT;
- typedef typename std::iterator_traits<_IteratorT>::value_type _CharT;
- typedef std::basic_string<_CharT> _StringT;
- typedef regex_constants::syntax_option_type _FlagT;
- typedef const std::ctype<_CharT> _CtypeT;
-
- /// Token types returned from the scanner.
- enum _TokenT
- {
- _S_token_anychar,
- _S_token_backref,
- _S_token_bracket_begin,
- _S_token_bracket_end,
- _S_token_inverse_class,
- _S_token_char_class_name,
- _S_token_closure0,
- _S_token_closure1,
- _S_token_collelem_multi,
- _S_token_collelem_single,
- _S_token_collsymbol,
- _S_token_comma,
- _S_token_dash,
- _S_token_dup_count,
- _S_token_eof,
- _S_token_equiv_class_name,
- _S_token_interval_begin,
- _S_token_interval_end,
- _S_token_line_begin,
- _S_token_line_end,
- _S_token_opt,
- _S_token_or,
- _S_token_ord_char,
- _S_token_quoted_char,
- _S_token_subexpr_begin,
- _S_token_subexpr_end,
- _S_token_word_begin,
- _S_token_word_end,
- _S_token_unknown
- };
-
- _Scanner(_IteratorT __begin, _IteratorT __end, _FlagT __flags,
- std::locale __loc)
- : _M_current(__begin) , _M_end(__end) , _M_flags(__flags),
- _M_ctype(std::use_facet<_CtypeT>(__loc)), _M_state(_S_state_at_start)
- { _M_advance(); }
-
- void
- _M_advance();
-
- _TokenT
- _M_token() const
- { return _M_curToken; }
-
- const _StringT&
- _M_value() const
- { return _M_curValue; }
-
-#ifdef _GLIBCXX_DEBUG
- std::ostream&
- _M_print(std::ostream&);
-#endif
-
- private:
- void
- _M_eat_escape();
-
- void
- _M_scan_in_brace();
-
- void
- _M_scan_in_bracket();
-
- void
- _M_eat_charclass();
-
- void
- _M_eat_equivclass();
-
- void
- _M_eat_collsymbol();
-
- _IteratorT _M_current;
- _IteratorT _M_end;
- _FlagT _M_flags;
- _CtypeT& _M_ctype;
- _TokenT _M_curToken;
- _StringT _M_curValue;
- _StateT _M_state;
- };
-
- template<typename _InputIterator>
- void
- _Scanner<_InputIterator>::
- _M_advance()
- {
- if (_M_current == _M_end)
- {
- _M_curToken = _S_token_eof;
- return;
- }
-
- _CharT __c = *_M_current;
- if (_M_state & _S_state_in_bracket)
- {
- _M_scan_in_bracket();
- return;
- }
- if (_M_state & _S_state_in_brace)
- {
- _M_scan_in_brace();
- return;
- }
-#if 0
- // TODO: re-enable line anchors when _M_assertion is implemented.
- // See PR libstdc++/47724
- else if (_M_state & _S_state_at_start && __c == _M_ctype.widen('^'))
- {
- _M_curToken = _S_token_line_begin;
- ++_M_current;
- return;
- }
- else if (__c == _M_ctype.widen('$'))
- {
- _M_curToken = _S_token_line_end;
- ++_M_current;
- return;
- }
-#endif
- else if (__c == _M_ctype.widen('.'))
- {
- _M_curToken = _S_token_anychar;
- ++_M_current;
- return;
- }
- else if (__c == _M_ctype.widen('*'))
- {
- _M_curToken = _S_token_closure0;
- ++_M_current;
- return;
- }
- else if (__c == _M_ctype.widen('+'))
- {
- _M_curToken = _S_token_closure1;
- ++_M_current;
- return;
- }
- else if (__c == _M_ctype.widen('|'))
- {
- _M_curToken = _S_token_or;
- ++_M_current;
- return;
- }
- else if (__c == _M_ctype.widen('['))
- {
- _M_curToken = _S_token_bracket_begin;
- _M_state |= (_S_state_in_bracket | _S_state_at_start);
- ++_M_current;
- return;
- }
- else if (__c == _M_ctype.widen('\\'))
- {
- _M_eat_escape();
- return;
- }
- else if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
- {
- if (__c == _M_ctype.widen('('))
- {
- _M_curToken = _S_token_subexpr_begin;
- ++_M_current;
- return;
- }
- else if (__c == _M_ctype.widen(')'))
- {
- _M_curToken = _S_token_subexpr_end;
- ++_M_current;
- return;
- }
- else if (__c == _M_ctype.widen('{'))
- {
- _M_curToken = _S_token_interval_begin;
- _M_state |= _S_state_in_brace;
- ++_M_current;
- return;
- }
- }
-
- _M_curToken = _S_token_ord_char;
- _M_curValue.assign(1, __c);
- ++_M_current;
- }
-
-
- template<typename _InputIterator>
- void
- _Scanner<_InputIterator>::
- _M_scan_in_brace()
- {
- if (_M_ctype.is(_CtypeT::digit, *_M_current))
- {
- _M_curToken = _S_token_dup_count;
- _M_curValue.assign(1, *_M_current);
- ++_M_current;
- while (_M_current != _M_end
- && _M_ctype.is(_CtypeT::digit, *_M_current))
- {
- _M_curValue += *_M_current;
- ++_M_current;
- }
- return;
- }
- else if (*_M_current == _M_ctype.widen(','))
- {
- _M_curToken = _S_token_comma;
- ++_M_current;
- return;
- }
- if (_M_flags & (regex_constants::basic | regex_constants::grep))
- {
- if (*_M_current == _M_ctype.widen('\\'))
- _M_eat_escape();
- }
- else
- {
- if (*_M_current == _M_ctype.widen('}'))
- {
- _M_curToken = _S_token_interval_end;
- _M_state &= ~_S_state_in_brace;
- ++_M_current;
- return;
- }
- }
- }
-
- template<typename _InputIterator>
- void
- _Scanner<_InputIterator>::
- _M_scan_in_bracket()
- {
- if (_M_state & _S_state_at_start && *_M_current == _M_ctype.widen('^'))
- {
- _M_curToken = _S_token_inverse_class;
- _M_state &= ~_S_state_at_start;
- ++_M_current;
- return;
- }
- else if (*_M_current == _M_ctype.widen('['))
- {
- ++_M_current;
- if (_M_current == _M_end)
- {
- _M_curToken = _S_token_eof;
- return;
- }
-
- if (*_M_current == _M_ctype.widen('.'))
- {
- _M_curToken = _S_token_collsymbol;
- _M_eat_collsymbol();
- return;
- }
- else if (*_M_current == _M_ctype.widen(':'))
- {
- _M_curToken = _S_token_char_class_name;
- _M_eat_charclass();
- return;
- }
- else if (*_M_current == _M_ctype.widen('='))
- {
- _M_curToken = _S_token_equiv_class_name;
- _M_eat_equivclass();
- return;
- }
- }
- else if (*_M_current == _M_ctype.widen('-'))
- {
- _M_curToken = _S_token_dash;
- ++_M_current;
- return;
- }
- else if (*_M_current == _M_ctype.widen(']'))
- {
- if (!(_M_flags & regex_constants::ECMAScript)
- || !(_M_state & _S_state_at_start))
- {
- // special case: only if _not_ chr first after
- // '[' or '[^' and if not ECMAscript
- _M_curToken = _S_token_bracket_end;
- ++_M_current;
- return;
- }
- }
- _M_curToken = _S_token_collelem_single;
- _M_curValue.assign(1, *_M_current);
- ++_M_current;
- }
-
- template<typename _InputIterator>
- void
- _Scanner<_InputIterator>::
- _M_eat_escape()
- {
- ++_M_current;
- if (_M_current == _M_end)
- {
- _M_curToken = _S_token_eof;
- return;
- }
- _CharT __c = *_M_current;
- ++_M_current;
-
- if (__c == _M_ctype.widen('('))
- {
- if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
- {
- _M_curToken = _S_token_ord_char;
- _M_curValue.assign(1, __c);
- }
- else
- _M_curToken = _S_token_subexpr_begin;
- }
- else if (__c == _M_ctype.widen(')'))
- {
- if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
- {
- _M_curToken = _S_token_ord_char;
- _M_curValue.assign(1, __c);
- }
- else
- _M_curToken = _S_token_subexpr_end;
- }
- else if (__c == _M_ctype.widen('{'))
- {
- if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
- {
- _M_curToken = _S_token_ord_char;
- _M_curValue.assign(1, __c);
- }
- else
- {
- _M_curToken = _S_token_interval_begin;
- _M_state |= _S_state_in_brace;
- }
- }
- else if (__c == _M_ctype.widen('}'))
- {
- if (!(_M_flags & (regex_constants::basic | regex_constants::grep)))
- {
- _M_curToken = _S_token_ord_char;
- _M_curValue.assign(1, __c);
- }
- else
- {
- if (!(_M_state && _S_state_in_brace))
- __throw_regex_error(regex_constants::error_badbrace);
- _M_state &= ~_S_state_in_brace;
- _M_curToken = _S_token_interval_end;
- }
- }
- else if (__c == _M_ctype.widen('x'))
- {
- ++_M_current;
- if (_M_current == _M_end)
- {
- _M_curToken = _S_token_eof;
- return;
- }
- if (_M_ctype.is(_CtypeT::digit, *_M_current))
- {
- _M_curValue.assign(1, *_M_current);
- ++_M_current;
- if (_M_current == _M_end)
- {
- _M_curToken = _S_token_eof;
- return;
- }
- if (_M_ctype.is(_CtypeT::digit, *_M_current))
- {
- _M_curValue += *_M_current;
- ++_M_current;
- return;
- }
- }
- }
- else if (__c == _M_ctype.widen('^')
- || __c == _M_ctype.widen('.')
- || __c == _M_ctype.widen('*')
- || __c == _M_ctype.widen('$')
- || __c == _M_ctype.widen('\\'))
- {
- _M_curToken = _S_token_ord_char;
- _M_curValue.assign(1, __c);
- }
- else if (_M_ctype.is(_CtypeT::digit, __c))
- {
- _M_curToken = _S_token_backref;
- _M_curValue.assign(1, __c);
- }
- else
- __throw_regex_error(regex_constants::error_escape);
- }
-
-
- // Eats a character class or throwns an exception.
- // current point to ':' delimiter on entry, char after ']' on return
- template<typename _InputIterator>
- void
- _Scanner<_InputIterator>::
- _M_eat_charclass()
- {
- ++_M_current; // skip ':'
- if (_M_current == _M_end)
- __throw_regex_error(regex_constants::error_ctype);
- for (_M_curValue.clear();
- _M_current != _M_end && *_M_current != _M_ctype.widen(':');
- ++_M_current)
- _M_curValue += *_M_current;
- if (_M_current == _M_end)
- __throw_regex_error(regex_constants::error_ctype);
- ++_M_current; // skip ':'
- if (*_M_current != _M_ctype.widen(']'))
- __throw_regex_error(regex_constants::error_ctype);
- ++_M_current; // skip ']'
- }
-
-
- template<typename _InputIterator>
- void
- _Scanner<_InputIterator>::
- _M_eat_equivclass()
- {
- ++_M_current; // skip '='
- if (_M_current == _M_end)
- __throw_regex_error(regex_constants::error_collate);
- for (_M_curValue.clear();
- _M_current != _M_end && *_M_current != _M_ctype.widen('=');
- ++_M_current)
- _M_curValue += *_M_current;
- if (_M_current == _M_end)
- __throw_regex_error(regex_constants::error_collate);
- ++_M_current; // skip '='
- if (*_M_current != _M_ctype.widen(']'))
- __throw_regex_error(regex_constants::error_collate);
- ++_M_current; // skip ']'
- }
-
-
- template<typename _InputIterator>
- void
- _Scanner<_InputIterator>::
- _M_eat_collsymbol()
- {
- ++_M_current; // skip '.'
- if (_M_current == _M_end)
- __throw_regex_error(regex_constants::error_collate);
- for (_M_curValue.clear();
- _M_current != _M_end && *_M_current != _M_ctype.widen('.');
- ++_M_current)
- _M_curValue += *_M_current;
- if (_M_current == _M_end)
- __throw_regex_error(regex_constants::error_collate);
- ++_M_current; // skip '.'
- if (*_M_current != _M_ctype.widen(']'))
- __throw_regex_error(regex_constants::error_collate);
- ++_M_current; // skip ']'
- }
-
-#ifdef _GLIBCXX_DEBUG
- template<typename _InputIterator>
- std::ostream&
- _Scanner<_InputIterator>::
- _M_print(std::ostream& ostr)
- {
- switch (_M_curToken)
- {
- case _S_token_anychar:
- ostr << "any-character\n";
- break;
- case _S_token_backref:
- ostr << "backref\n";
- break;
- case _S_token_bracket_begin:
- ostr << "bracket-begin\n";
- break;
- case _S_token_bracket_end:
- ostr << "bracket-end\n";
- break;
- case _S_token_char_class_name:
- ostr << "char-class-name \"" << _M_curValue << "\"\n";
- break;
- case _S_token_closure0:
- ostr << "closure0\n";
- break;
- case _S_token_closure1:
- ostr << "closure1\n";
- break;
- case _S_token_collelem_multi:
- ostr << "coll-elem-multi \"" << _M_curValue << "\"\n";
- break;
- case _S_token_collelem_single:
- ostr << "coll-elem-single \"" << _M_curValue << "\"\n";
- break;
- case _S_token_collsymbol:
- ostr << "collsymbol \"" << _M_curValue << "\"\n";
- break;
- case _S_token_comma:
- ostr << "comma\n";
- break;
- case _S_token_dash:
- ostr << "dash\n";
- break;
- case _S_token_dup_count:
- ostr << "dup count: " << _M_curValue << "\n";
- break;
- case _S_token_eof:
- ostr << "EOF\n";
- break;
- case _S_token_equiv_class_name:
- ostr << "equiv-class-name \"" << _M_curValue << "\"\n";
- break;
- case _S_token_interval_begin:
- ostr << "interval begin\n";
- break;
- case _S_token_interval_end:
- ostr << "interval end\n";
- break;
- case _S_token_line_begin:
- ostr << "line begin\n";
- break;
- case _S_token_line_end:
- ostr << "line end\n";
- break;
- case _S_token_opt:
- ostr << "opt\n";
- break;
- case _S_token_or:
- ostr << "or\n";
- break;
- case _S_token_ord_char:
- ostr << "ordinary character: \"" << _M_value() << "\"\n";
- break;
- case _S_token_quoted_char:
- ostr << "quoted char\n";
- break;
- case _S_token_subexpr_begin:
- ostr << "subexpr begin\n";
- break;
- case _S_token_subexpr_end:
- ostr << "subexpr end\n";
- break;
- case _S_token_word_begin:
- ostr << "word begin\n";
- break;
- case _S_token_word_end:
- ostr << "word end\n";
- break;
- case _S_token_unknown:
- ostr << "-- unknown token --\n";
- break;
- }
- return ostr;
- }
-#endif
+ template<typename _CharT, typename _TraitsT>
+ struct _BracketMatcher;
/// Builds an NFA from an input iterator interval.
- template<typename _InIter, typename _TraitsT>
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
class _Compiler
{
public:
- typedef _InIter _IterT;
- typedef typename std::iterator_traits<_InIter>::value_type _CharT;
- typedef std::basic_string<_CharT> _StringT;
- typedef regex_constants::syntax_option_type _FlagT;
+ typedef typename _TraitsT::string_type _StringT;
+ typedef _NFA<_CharT, _TraitsT> _RegexT;
+ typedef regex_constants::syntax_option_type _FlagT;
- _Compiler(const _InIter& __b, const _InIter& __e,
- _TraitsT& __traits, _FlagT __flags);
+ _Compiler(_FwdIter __b, _FwdIter __e,
+ const _TraitsT& __traits, _FlagT __flags);
- const _Nfa&
- _M_nfa() const
- { return _M_state_store; }
+ std::shared_ptr<_RegexT>
+ _M_get_nfa() const
+ { return std::shared_ptr<_RegexT>(new _RegexT(_M_nfa)); }
private:
- typedef _Scanner<_InIter> _ScannerT;
- typedef typename _ScannerT::_TokenT _TokenT;
- typedef std::stack<_StateSeq, std::vector<_StateSeq> > _StackT;
- typedef _RangeMatcher<_InIter, _TraitsT> _RMatcherT;
+ typedef _Scanner<_FwdIter> _ScannerT;
+ typedef typename _ScannerT::_TokenT _TokenT;
+ typedef _StateSeq<_CharT, _TraitsT> _StateSeqT;
+ typedef std::stack<_StateSeqT, std::vector<_StateSeqT>> _StackT;
+ typedef _BracketMatcher<_CharT, _TraitsT> _BMatcherT;
+ typedef std::ctype<_CharT> _CtypeT;
// accepts a specific token or returns false.
bool
@@ -659,7 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_disjunction();
- bool
+ void
_M_alternative();
bool
@@ -668,7 +82,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
_M_assertion();
- bool
+ void
_M_quantifier();
bool
@@ -677,434 +91,186 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
_M_bracket_expression();
- bool
- _M_bracket_list(_RMatcherT& __matcher);
-
- bool
- _M_follow_list(_RMatcherT& __matcher);
-
- bool
- _M_follow_list2(_RMatcherT& __matcher);
-
- bool
- _M_expression_term(_RMatcherT& __matcher);
-
- bool
- _M_range_expression(_RMatcherT& __matcher);
+ void
+ _M_expression_term(_BMatcherT& __matcher);
bool
- _M_start_range(_RMatcherT& __matcher);
+ _M_range_expression(_BMatcherT& __matcher);
bool
- _M_collating_symbol(_RMatcherT& __matcher);
+ _M_collating_symbol(_BMatcherT& __matcher);
bool
- _M_equivalence_class(_RMatcherT& __matcher);
+ _M_equivalence_class(_BMatcherT& __matcher);
bool
- _M_character_class(_RMatcherT& __matcher);
+ _M_character_class(_BMatcherT& __matcher);
int
_M_cur_int_value(int __radix);
- _TraitsT& _M_traits;
- _ScannerT _M_scanner;
- _StringT _M_cur_value;
- _Nfa _M_state_store;
- _StackT _M_stack;
- };
-
- template<typename _InIter, typename _TraitsT>
- _Compiler<_InIter, _TraitsT>::
- _Compiler(const _InIter& __b, const _InIter& __e, _TraitsT& __traits,
- _Compiler<_InIter, _TraitsT>::_FlagT __flags)
- : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()),
- _M_state_store(__flags)
- {
- typedef _StartTagger<_InIter, _TraitsT> _Start;
- typedef _EndTagger<_InIter, _TraitsT> _End;
+ bool
+ _M_try_char();
- _StateSeq __r(_M_state_store,
- _M_state_store._M_insert_subexpr_begin(_Start(0)));
- _M_disjunction();
- if (!_M_stack.empty())
- {
- __r._M_append(_M_stack.top());
- _M_stack.pop();
- }
- __r._M_append(_M_state_store._M_insert_subexpr_end(0, _End(0)));
- __r._M_append(_M_state_store._M_insert_accept());
- }
+ _StateSeqT
+ _M_pop()
+ {
+ auto ret = _M_stack.top();
+ _M_stack.pop();
+ return ret;
+ }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_match_token(_Compiler<_InIter, _TraitsT>::_TokenT token)
- {
- if (token == _M_scanner._M_token())
- {
- _M_cur_value = _M_scanner._M_value();
- _M_scanner._M_advance();
- return true;
- }
- return false;
- }
+ const _TraitsT& _M_traits;
+ const _CtypeT& _M_ctype;
+ _ScannerT _M_scanner;
+ _RegexT _M_nfa;
+ _StringT _M_value;
+ _StackT _M_stack;
+ _FlagT _M_flags;
+ };
- template<typename _InIter, typename _TraitsT>
- void
- _Compiler<_InIter, _TraitsT>::
- _M_disjunction()
+ template<typename _CharT, typename _TraitsT>
+ struct _AnyMatcher
{
- this->_M_alternative();
- if (_M_match_token(_ScannerT::_S_token_or))
- {
- _StateSeq __alt1 = _M_stack.top(); _M_stack.pop();
- this->_M_disjunction();
- _StateSeq __alt2 = _M_stack.top(); _M_stack.pop();
- _M_stack.push(_StateSeq(__alt1, __alt2));
- }
- }
+ explicit
+ _AnyMatcher(const _TraitsT& __traits)
+ : _M_traits(__traits)
+ { }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_alternative()
- {
- if (this->_M_term())
- {
- _StateSeq __re = _M_stack.top(); _M_stack.pop();
- this->_M_alternative();
- if (!_M_stack.empty())
- {
- __re._M_append(_M_stack.top());
- _M_stack.pop();
- }
- _M_stack.push(__re);
- return true;
- }
- return false;
- }
+ bool
+ operator()(_CharT __ch) const
+ {
+ return _M_traits.translate(__ch) != '\n'
+ && _M_traits.translate(__ch) != '\r'
+ && _M_traits.translate(__ch) != u'\u2028'
+ && _M_traits.translate(__ch) != u'\u2029';
+ }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_term()
- {
- if (this->_M_assertion())
- return true;
- if (this->_M_atom())
- {
- this->_M_quantifier();
- return true;
- }
- return false;
- }
+ const _TraitsT& _M_traits;
+ };
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_assertion()
+ template<typename _CharT, typename _TraitsT>
+ struct _CharMatcher
{
- if (_M_match_token(_ScannerT::_S_token_line_begin))
- {
- // __m.push(_Matcher::_S_opcode_line_begin);
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_line_end))
- {
- // __m.push(_Matcher::_S_opcode_line_end);
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_word_begin))
- {
- // __m.push(_Matcher::_S_opcode_word_begin);
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_word_end))
- {
- // __m.push(_Matcher::_S_opcode_word_end);
- return true;
- }
- return false;
- }
+ typedef regex_constants::syntax_option_type _FlagT;
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_quantifier()
- {
- if (_M_match_token(_ScannerT::_S_token_closure0))
- {
- if (_M_stack.empty())
- __throw_regex_error(regex_constants::error_badrepeat);
- _StateSeq __r(_M_stack.top(), -1);
- __r._M_append(__r._M_front());
- _M_stack.pop();
- _M_stack.push(__r);
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_closure1))
- {
- if (_M_stack.empty())
- __throw_regex_error(regex_constants::error_badrepeat);
- _StateSeq __r(_M_state_store,
- _M_state_store.
- _M_insert_alt(_S_invalid_state_id,
- _M_stack.top()._M_front()));
- _M_stack.top()._M_append(__r);
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_opt))
- {
- if (_M_stack.empty())
- __throw_regex_error(regex_constants::error_badrepeat);
- _StateSeq __r(_M_stack.top(), -1);
- _M_stack.pop();
- _M_stack.push(__r);
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_interval_begin))
- {
- if (_M_stack.empty())
- __throw_regex_error(regex_constants::error_badrepeat);
- if (!_M_match_token(_ScannerT::_S_token_dup_count))
- __throw_regex_error(regex_constants::error_badbrace);
- _StateSeq __r(_M_stack.top());
- int __min_rep = _M_cur_int_value(10);
- for (int __i = 1; __i < __min_rep; ++__i)
- _M_stack.top()._M_append(__r._M_clone());
- if (_M_match_token(_ScannerT::_S_token_comma))
- if (_M_match_token(_ScannerT::_S_token_dup_count))
- {
- int __n = _M_cur_int_value(10) - __min_rep;
- if (__n < 0)
- __throw_regex_error(regex_constants::error_badbrace);
- for (int __i = 0; __i < __n; ++__i)
- {
- _StateSeq __r(_M_state_store,
- _M_state_store.
- _M_insert_alt(_S_invalid_state_id,
- _M_stack.top()._M_front()));
- _M_stack.top()._M_append(__r);
- }
- }
- else
- {
- _StateSeq __r(_M_stack.top(), -1);
- __r._M_push_back(__r._M_front());
- _M_stack.pop();
- _M_stack.push(__r);
- }
- if (!_M_match_token(_ScannerT::_S_token_interval_end))
- __throw_regex_error(regex_constants::error_brace);
- return true;
- }
- return false;
- }
+ explicit
+ _CharMatcher(_CharT __ch, const _TraitsT& __traits, _FlagT __flags)
+ : _M_ch(_M_translate(__ch)), _M_traits(__traits), _M_flags(__flags)
+ { }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_atom()
- {
- typedef _CharMatcher<_InIter, _TraitsT> _CMatcher;
- typedef _StartTagger<_InIter, _TraitsT> _Start;
- typedef _EndTagger<_InIter, _TraitsT> _End;
+ bool
+ operator()(_CharT __ch) const
+ { return _M_ch == _M_translate(__ch); }
- if (_M_match_token(_ScannerT::_S_token_anychar))
- {
- _M_stack.push(_StateSeq(_M_state_store,
- _M_state_store._M_insert_matcher
- (_AnyMatcher)));
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_ord_char))
- {
- _M_stack.push(_StateSeq(_M_state_store,
- _M_state_store._M_insert_matcher
- (_CMatcher(_M_cur_value[0], _M_traits))));
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_quoted_char))
- {
- // note that in the ECMA grammar, this case covers backrefs.
- _M_stack.push(_StateSeq(_M_state_store,
- _M_state_store._M_insert_matcher
- (_CMatcher(_M_cur_value[0], _M_traits))));
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_backref))
- {
- // __m.push(_Matcher::_S_opcode_ordchar, _M_cur_value);
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
- {
- int __mark = _M_state_store._M_sub_count();
- _StateSeq __r(_M_state_store,
- _M_state_store.
- _M_insert_subexpr_begin(_Start(__mark)));
- this->_M_disjunction();
- if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
- __throw_regex_error(regex_constants::error_paren);
- if (!_M_stack.empty())
- {
- __r._M_append(_M_stack.top());
- _M_stack.pop();
- }
- __r._M_append(_M_state_store._M_insert_subexpr_end
- (__mark, _End(__mark)));
- _M_stack.push(__r);
- return true;
- }
- return _M_bracket_expression();
- }
+ _CharT
+ _M_translate(_CharT __ch) const
+ {
+ if (_M_flags & regex_constants::icase)
+ return _M_traits.translate_nocase(__ch);
+ else
+ return _M_traits.translate(__ch);
+ }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_bracket_expression()
- {
- if (_M_match_token(_ScannerT::_S_token_bracket_begin))
- {
- _RMatcherT __matcher(_M_match_token(_ScannerT::_S_token_line_begin),
- _M_traits);
- if (!_M_bracket_list(__matcher)
- || !_M_match_token(_ScannerT::_S_token_bracket_end))
- __throw_regex_error(regex_constants::error_brack);
- _M_stack.push(_StateSeq(_M_state_store,
- _M_state_store._M_insert_matcher(__matcher)));
- return true;
- }
- return false;
- }
+ const _TraitsT& _M_traits;
+ _FlagT _M_flags;
+ _CharT _M_ch;
+ };
- // If the dash is the last character in the bracket expression, it is not
- // special.
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_bracket_list(_RMatcherT& __matcher)
+ /// Matches a character range (bracket expression)
+ template<typename _CharT, typename _TraitsT>
+ struct _BracketMatcher
{
- if (_M_follow_list(__matcher))
- {
- if (_M_match_token(_ScannerT::_S_token_dash))
- __matcher._M_add_char(_M_cur_value[0]);
- return true;
- }
- return false;
- }
+ typedef typename _TraitsT::char_class_type _CharClassT;
+ typedef typename _TraitsT::string_type _StringT;
+ typedef regex_constants::syntax_option_type _FlagT;
+
+ explicit
+ _BracketMatcher(bool __is_non_matching,
+ const _TraitsT& __traits,
+ _FlagT __flags)
+ : _M_is_non_matching(__is_non_matching), _M_traits(__traits),
+ _M_flags(__flags), _M_class_set(0)
+ { }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_follow_list(_RMatcherT& __matcher)
- { return _M_expression_term(__matcher) && _M_follow_list2(__matcher); }
+ bool
+ operator()(_CharT) const;
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_follow_list2(_RMatcherT& __matcher)
- {
- if (_M_expression_term(__matcher))
- return _M_follow_list2(__matcher);
- return true;
- }
+ void
+ _M_add_char(_CharT __c)
+ { _M_char_set.insert(_M_translate(__c)); }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_expression_term(_RMatcherT& __matcher)
- {
- return (_M_collating_symbol(__matcher)
- || _M_character_class(__matcher)
- || _M_equivalence_class(__matcher)
- || (_M_start_range(__matcher)
- && _M_range_expression(__matcher)));
- }
+ void
+ _M_add_collating_element(const _StringT& __s)
+ {
+ auto __st = _M_traits.lookup_collatename(__s.data(),
+ __s.data() + __s.size());
+ if (__st.empty())
+ __throw_regex_error(regex_constants::error_collate);
+ // TODO: digraph
+ _M_char_set.insert(_M_translate(__st[0]));
+ }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_range_expression(_RMatcherT& __matcher)
- {
- if (!_M_collating_symbol(__matcher))
- if (!_M_match_token(_ScannerT::_S_token_dash))
- __throw_regex_error(regex_constants::error_range);
- __matcher._M_make_range();
- return true;
- }
+ void
+ _M_add_equivalence_class(const _StringT& __s)
+ {
+ _M_add_character_class(
+ _M_traits.transform_primary(__s.data(),
+ __s.data() + __s.size()));
+ }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_start_range(_RMatcherT& __matcher)
- { return _M_match_token(_ScannerT::_S_token_dash); }
+ void
+ _M_add_character_class(const _StringT& __s)
+ {
+ auto __st = _M_traits.
+ lookup_classname(__s.data(), __s.data() + __s.size(), _M_is_icase());
+ if (__st == 0)
+ __throw_regex_error(regex_constants::error_ctype);
+ _M_class_set |= __st;
+ }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_collating_symbol(_RMatcherT& __matcher)
- {
- if (_M_match_token(_ScannerT::_S_token_collelem_single))
- {
- __matcher._M_add_char(_M_cur_value[0]);
- return true;
- }
- if (_M_match_token(_ScannerT::_S_token_collsymbol))
- {
- __matcher._M_add_collating_element(_M_cur_value);
- return true;
- }
- return false;
- }
+ void
+ _M_make_range(_CharT __l, _CharT __r)
+ {
+ if (_M_flags & regex_constants::collate)
+ _M_range_set.insert(
+ make_pair(_M_get_str(_M_translate(__l)),
+ _M_get_str(_M_translate(__r))));
+ else
+ _M_range_set.insert(make_pair(_M_get_str(__l), _M_get_str(__r)));
+ }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_equivalence_class(_RMatcherT& __matcher)
- {
- if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
- {
- __matcher._M_add_equivalence_class(_M_cur_value);
- return true;
- }
- return false;
- }
+ _CharT
+ _M_translate(_CharT __c) const
+ {
+ if (_M_is_icase())
+ return _M_traits.translate_nocase(__c);
+ else
+ return _M_traits.translate(__c);
+ }
- template<typename _InIter, typename _TraitsT>
- bool
- _Compiler<_InIter, _TraitsT>::
- _M_character_class(_RMatcherT& __matcher)
- {
- if (_M_match_token(_ScannerT::_S_token_char_class_name))
- {
- __matcher._M_add_character_class(_M_cur_value);
- return true;
- }
- return false;
- }
+ bool
+ _M_is_icase() const
+ { return _M_flags & regex_constants::icase; }
- template<typename _InIter, typename _TraitsT>
- int
- _Compiler<_InIter, _TraitsT>::
- _M_cur_int_value(int __radix)
- {
- int __v = 0;
- for (typename _StringT::size_type __i = 0;
- __i < _M_cur_value.length(); ++__i)
- __v =__v * __radix + _M_traits.value(_M_cur_value[__i], __radix);
- return __v;
- }
+ _StringT
+ _M_get_str(_CharT __c) const
+ {
+ _StringT __s(1, __c);
+ return _M_traits.transform(__s.begin(), __s.end());
+ }
- template<typename _InIter, typename _TraitsT>
- _AutomatonPtr
- __compile(const _InIter& __b, const _InIter& __e, _TraitsT& __t,
- regex_constants::syntax_option_type __f)
- { return _AutomatonPtr(new _Nfa(_Compiler<_InIter, _TraitsT>(__b, __e, __t,
- __f)._M_nfa())); }
+ std::set<_CharT> _M_char_set;
+ std::set<pair<_StringT, _StringT>> _M_range_set;
+ const _TraitsT& _M_traits;
+ _CharClassT _M_class_set;
+ _FlagT _M_flags;
+ bool _M_is_non_matching;
+ };
//@} regex-detail
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace __detail
} // namespace std
+
+#include <bits/regex_compiler.tcc>
diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc
new file mode 100644
index 00000000000..a574e8e5ddd
--- /dev/null
+++ b/libstdc++-v3/include/bits/regex_compiler.tcc
@@ -0,0 +1,415 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/**
+ * @file bits/regex_compiler.tcc
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{regex}
+ */
+
+// TODO make comments doxygen format.
+
+// This compiler refers to "Regular Expression Matching Can Be Simple And Fast"
+// (http://swtch.com/~rsc/regexp/regexp1.html"),
+// but doesn't strictly follow it.
+//
+// When compiling, states are *chained* instead of tree- or graph-constructed.
+// It's more like structured programs: there's if statement and loop statement.
+//
+// For alternative structure(say "a|b"), aka "if statement", two branchs should
+// be constructed. However, these two shall merge to an "end_tag" at the end of
+// this operator:
+//
+// branch1
+// / \
+// => begin_tag end_tag =>
+// \ /
+// branch2
+//
+// This is the difference between this implementation and that in Russ's
+// article.
+//
+// That's why we introduced dummy node here ------ "end_tag" is a dummy node.
+// All dummy node will be eliminated at the end of compiling process.
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _Compiler(_FwdIter __b, _FwdIter __e,
+ const _TraitsT& __traits, _FlagT __flags)
+ : _M_traits(__traits), _M_scanner(__b, __e, __flags, _M_traits.getloc()),
+ _M_ctype(std::use_facet<std::ctype<_CharT>>(_M_traits.getloc())),
+ _M_nfa(__flags), _M_flags(__flags)
+ {
+ _StateSeqT __r(_M_nfa, _M_nfa._M_start());
+ __r._M_append(_M_nfa._M_insert_subexpr_begin());
+ this->_M_disjunction();
+ if (!_M_match_token(_ScannerT::_S_token_eof))
+ __throw_regex_error(regex_constants::error_paren);
+ __r._M_append(_M_pop());
+ _GLIBCXX_DEBUG_ASSERT(_M_stack.empty());
+ __r._M_append(_M_nfa._M_insert_subexpr_end());
+ __r._M_append(_M_nfa._M_insert_accept());
+ _M_nfa._M_eliminate_dummy();
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ void
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_disjunction()
+ {
+ this->_M_alternative();
+ // TODO empty alternative like, um, "(|asdf)"
+ while (_M_match_token(_ScannerT::_S_token_or))
+ {
+ _StateSeqT __alt1 = _M_pop();
+ this->_M_alternative();
+ _StateSeqT __alt2 = _M_pop();
+ auto __end = _M_nfa._M_insert_dummy();
+ __alt1._M_append(__end);
+ __alt2._M_append(__end);
+ _M_stack.push(_StateSeqT(_M_nfa,
+ _M_nfa._M_insert_alt(__alt1._M_start,
+ __alt2._M_start),
+ __end));
+ }
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ void
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_alternative()
+ {
+ if (this->_M_term())
+ {
+ _StateSeqT __re = _M_pop();
+ this->_M_alternative();
+ __re._M_append(_M_pop());
+ _M_stack.push(__re);
+ }
+ else
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy()));
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ bool
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_term()
+ {
+ if (this->_M_assertion())
+ return true;
+ if (this->_M_atom())
+ {
+ this->_M_quantifier();
+ return true;
+ }
+ return false;
+ }
+
+ // TODO Implement it.
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ bool
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_assertion()
+ {
+ // temporary place holders.
+ if (_M_match_token(_ScannerT::_S_token_line_begin))
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy()));
+ else if (_M_match_token(_ScannerT::_S_token_line_end))
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy()));
+ else if (_M_match_token(_ScannerT::_S_token_word_bound))
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy()));
+ else if (_M_match_token(_ScannerT::_S_token_neg_word_bound))
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy()));
+ else if (_M_match_token(_ScannerT::_S_token_subexpr_lookahead_begin))
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy()));
+ else if (_M_match_token(_ScannerT::_S_token_subexpr_neg_lookahead_begin))
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_dummy()));
+ else
+ return false;
+ return true;
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ void
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_quantifier()
+ {
+ if (_M_match_token(_ScannerT::_S_token_closure0))
+ {
+ if (_M_stack.empty())
+ __throw_regex_error(regex_constants::error_badrepeat);
+ auto __e = _M_pop();
+ _StateSeqT __r(_M_nfa, _M_nfa._M_insert_alt(_S_invalid_state_id,
+ __e._M_start));
+ __e._M_append(__r);
+ _M_stack.push(__r);
+ }
+ else if (_M_match_token(_ScannerT::_S_token_closure1))
+ {
+ if (_M_stack.empty())
+ __throw_regex_error(regex_constants::error_badrepeat);
+ auto __e = _M_pop();
+ __e._M_append(_M_nfa._M_insert_alt(_S_invalid_state_id, __e._M_start));
+ _M_stack.push(__e);
+ }
+ else if (_M_match_token(_ScannerT::_S_token_opt))
+ {
+ if (_M_stack.empty())
+ __throw_regex_error(regex_constants::error_badrepeat);
+ auto __e = _M_pop();
+ auto __end = _M_nfa._M_insert_dummy();
+ _StateSeqT __r(_M_nfa, _M_nfa._M_insert_alt(_S_invalid_state_id,
+ __e._M_start));
+ __e._M_append(__end);
+ __r._M_append(__end);
+ _M_stack.push(__r);
+ }
+ else if (_M_match_token(_ScannerT::_S_token_interval_begin))
+ {
+ if (_M_stack.empty())
+ __throw_regex_error(regex_constants::error_badrepeat);
+ if (!_M_match_token(_ScannerT::_S_token_dup_count))
+ __throw_regex_error(regex_constants::error_badbrace);
+ _StateSeqT __r(_M_pop());
+ _StateSeqT __e(_M_nfa, _M_nfa._M_insert_dummy());
+ int __min_rep = _M_cur_int_value(10);
+ // {3
+ for (int __i = 0; __i < __min_rep; ++__i)
+ __e._M_append(__r._M_clone());
+ if (_M_match_token(_ScannerT::_S_token_comma))
+ if (_M_match_token(_ScannerT::_S_token_dup_count)) // {3,7}
+ {
+ int __n = _M_cur_int_value(10) - __min_rep;
+ if (__n < 0)
+ __throw_regex_error(regex_constants::error_badbrace);
+ auto __end = _M_nfa._M_insert_dummy();
+ for (int __i = 0; __i < __n; ++__i)
+ {
+ auto __tmp = __r._M_clone();
+ __e._M_append(_StateSeqT(_M_nfa, _M_nfa.
+ _M_insert_alt(__tmp._M_start, __end), __tmp._M_end));
+ }
+ __e._M_append(__end);
+ }
+ else // {3,}
+ {
+ auto __tmp = __r._M_clone();
+ _StateSeqT __s(_M_nfa, _M_nfa._M_insert_alt(_S_invalid_state_id,
+ __tmp._M_start));
+ __tmp._M_append(__s);
+ __e._M_append(__s);
+ }
+ if (!_M_match_token(_ScannerT::_S_token_interval_end))
+ __throw_regex_error(regex_constants::error_brace);
+ _M_stack.push(__e);
+ }
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ bool
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_atom()
+ {
+ if (_M_match_token(_ScannerT::_S_token_anychar))
+ _M_stack.push(_StateSeqT(_M_nfa,
+ _M_nfa._M_insert_matcher
+ (_AnyMatcher<_CharT, _TraitsT>(_M_traits))));
+ else if (_M_try_char())
+ _M_stack.push(_StateSeqT(_M_nfa,
+ _M_nfa._M_insert_matcher
+ (_CharMatcher<_CharT, _TraitsT>(_M_value[0],
+ _M_traits,
+ _M_flags))));
+ else if (_M_match_token(_ScannerT::_S_token_backref))
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa.
+ _M_insert_backref(_M_cur_int_value(10))));
+ else if (_M_match_token(_ScannerT::_S_token_quoted_class))
+ {
+ _GLIBCXX_DEBUG_ASSERT(_M_value.size() == 1);
+ _BMatcherT __matcher(_M_ctype.is(_CtypeT::upper, _M_value[0]),
+ _M_traits, _M_flags);
+ __matcher._M_add_character_class(_M_value);
+ _M_stack.push(_StateSeqT(_M_nfa,
+ _M_nfa._M_insert_matcher(__matcher)));
+ }
+ else if (_M_match_token(_ScannerT::_S_token_subexpr_no_group_begin))
+ {
+ _StateSeqT __r(_M_nfa, _M_nfa._M_insert_dummy());
+ this->_M_disjunction();
+ if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
+ __throw_regex_error(regex_constants::error_paren);
+ __r._M_append(_M_pop());
+ _M_stack.push(__r);
+ }
+ else if (_M_match_token(_ScannerT::_S_token_subexpr_begin))
+ {
+ int __mark = _M_nfa._M_sub_count();
+ _StateSeqT __r(_M_nfa, _M_nfa._M_insert_subexpr_begin());
+ this->_M_disjunction();
+ if (!_M_match_token(_ScannerT::_S_token_subexpr_end))
+ __throw_regex_error(regex_constants::error_paren);
+ __r._M_append(_M_pop());
+ __r._M_append(_M_nfa._M_insert_subexpr_end());
+ _M_stack.push(__r);
+ }
+ else if (!_M_bracket_expression())
+ return false;
+ return true;
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ bool
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_bracket_expression()
+ {
+ bool __neg =
+ _M_match_token(_ScannerT::_S_token_bracket_neg_begin);
+ if (!(__neg || _M_match_token(_ScannerT::_S_token_bracket_begin)))
+ return false;
+ _BMatcherT __matcher(__neg, _M_traits, _M_flags);
+ while (!_M_match_token(_ScannerT::_S_token_bracket_end))
+ _M_expression_term(__matcher);
+ _M_stack.push(_StateSeqT(_M_nfa, _M_nfa._M_insert_matcher(__matcher)));
+ return true;
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ void
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_expression_term(_BMatcherT& __matcher)
+ {
+ if (_M_match_token(_ScannerT::_S_token_collsymbol))
+ __matcher._M_add_collating_element(_M_value);
+ else if (_M_match_token(_ScannerT::_S_token_equiv_class_name))
+ __matcher._M_add_equivalence_class(_M_value);
+ else if (_M_match_token(_ScannerT::_S_token_char_class_name))
+ __matcher._M_add_character_class(_M_value);
+ else if (_M_try_char()) // [a
+ {
+ auto __ch = _M_value[0];
+ if (_M_try_char())
+ {
+ if (_M_value[0] == '-') // [a-
+ {
+ if (_M_try_char()) // [a-z]
+ {
+ __matcher._M_make_range(__ch, _M_value[0]);
+ return;
+ }
+ // If the dash is the last character in the bracket
+ // expression, it is not special.
+ if (_M_scanner._M_get_token()
+ != _ScannerT::_S_token_bracket_end)
+ __throw_regex_error(regex_constants::error_range);
+ }
+ __matcher._M_add_char(_M_value[0]);
+ }
+ __matcher._M_add_char(__ch);
+ }
+ else
+ __throw_regex_error(regex_constants::error_brack);
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ bool
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_try_char()
+ {
+ bool __is_char = false;
+ if (_M_match_token(_ScannerT::_S_token_oct_num))
+ {
+ __is_char = true;
+ _M_value.assign(1, _M_cur_int_value(8));
+ }
+ else if (_M_match_token(_ScannerT::_S_token_hex_num))
+ {
+ __is_char = true;
+ _M_value.assign(1, _M_cur_int_value(16));
+ }
+ else if (_M_match_token(_ScannerT::_S_token_ord_char))
+ __is_char = true;
+ return __is_char;
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ bool
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_match_token(_TokenT token)
+ {
+ if (token == _M_scanner._M_get_token())
+ {
+ _M_value = _M_scanner._M_get_value();
+ _M_scanner._M_advance();
+ return true;
+ }
+ return false;
+ }
+
+ template<typename _FwdIter, typename _CharT, typename _TraitsT>
+ int
+ _Compiler<_FwdIter, _CharT, _TraitsT>::
+ _M_cur_int_value(int __radix)
+ {
+ int __v = 0;
+ for (typename _StringT::size_type __i = 0;
+ __i < _M_value.length(); ++__i)
+ __v =__v * __radix + _M_traits.value(_M_value[__i], __radix);
+ return __v;
+ }
+
+ template<typename _CharT, typename _TraitsT>
+ bool _BracketMatcher<_CharT, _TraitsT>::
+ operator()(_CharT __ch) const
+ {
+ bool __ret = false;
+ if (_M_traits.isctype(__ch, _M_class_set))
+ __ret = true;
+ else if (_M_char_set.count(_M_translate(__ch)))
+ __ret = true;
+ else
+ {
+ _StringT __s = _M_get_str(_M_flags & regex_constants::collate
+ ? _M_translate(__ch) : __ch);
+ for (auto& __it : _M_range_set)
+ if (__it.first <= __s && __s <= __it.second)
+ {
+ __ret = true;
+ break;
+ }
+ }
+ if (_M_is_non_matching)
+ return !__ret;
+ else
+ return __ret;
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
diff --git a/libstdc++-v3/include/bits/regex_constants.h b/libstdc++-v3/include/bits/regex_constants.h
index aea2a5bb2c0..23174becdf9 100644
--- a/libstdc++-v3/include/bits/regex_constants.h
+++ b/libstdc++-v3/include/bits/regex_constants.h
@@ -77,87 +77,125 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* elements @c ECMAScript, @c basic, @c extended, @c awk, @c grep, @c egrep
* %set.
*/
- typedef unsigned int syntax_option_type;
-
- /**
- * Specifies that the matching of regular expressions against a character
- * sequence shall be performed without regard to case.
- */
- constexpr syntax_option_type icase = 1 << _S_icase;
-
- /**
- * Specifies that when a regular expression is matched against a character
- * container sequence, no sub-expression matches are to be stored in the
- * supplied match_results structure.
- */
- constexpr syntax_option_type nosubs = 1 << _S_nosubs;
-
- /**
- * Specifies that the regular expression engine should pay more attention to
- * the speed with which regular expressions are matched, and less to the
- * speed with which regular expression objects are constructed. Otherwise
- * it has no detectable effect on the program output.
- */
- constexpr syntax_option_type optimize = 1 << _S_optimize;
-
- /**
- * Specifies that character ranges of the form [a-b] should be locale
- * sensitive.
- */
- constexpr syntax_option_type collate = 1 << _S_collate;
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript
- * Language Specification, Standard Ecma-262, third edition, 1999], as
- * modified in section [28.13]. This grammar is similar to that defined
- * in the PERL scripting language but extended with elements found in the
- * POSIX regular expression grammar.
- */
- constexpr syntax_option_type ECMAScript = 1 << _S_ECMAScript;
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001,
- * Portable Operating System Interface (POSIX), Base Definitions and
- * Headers, Section 9, Regular Expressions [IEEE, Information Technology --
- * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
- */
- constexpr syntax_option_type basic = 1 << _S_basic;
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001,
- * Portable Operating System Interface (POSIX), Base Definitions and Headers,
- * Section 9, Regular Expressions.
- */
- constexpr syntax_option_type extended = 1 << _S_extended;
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is
- * identical to syntax_option_type extended, except that C-style escape
- * sequences are supported. These sequences are:
- * \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\&apos;, &apos;,
- * and \\ddd (where ddd is one, two, or three octal digits).
- */
- constexpr syntax_option_type awk = 1 << _S_awk;
-
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is
- * identical to syntax_option_type basic, except that newlines are treated
- * as whitespace.
- */
- constexpr syntax_option_type grep = 1 << _S_grep;
+ enum syntax_option_type : unsigned int
+ {
+ /**
+ * Specifies that the matching of regular expressions against a character
+ * sequence shall be performed without regard to case.
+ */
+ icase = 1 << _S_icase,
+
+ /**
+ * Specifies that when a regular expression is matched against a character
+ * container sequence, no sub-expression matches are to be stored in the
+ * supplied match_results structure.
+ */
+ nosubs = 1 << _S_nosubs,
+
+ /**
+ * Specifies that the regular expression engine should pay more attention to
+ * the speed with which regular expressions are matched, and less to the
+ * speed with which regular expression objects are constructed. Otherwise
+ * it has no detectable effect on the program output.
+ */
+ optimize = 1 << _S_optimize,
+
+ /**
+ * Specifies that character ranges of the form [a-b] should be locale
+ * sensitive.
+ */
+ collate = 1 << _S_collate,
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by ECMAScript in ECMA-262 [Ecma International, ECMAScript
+ * Language Specification, Standard Ecma-262, third edition, 1999], as
+ * modified in section [28.13]. This grammar is similar to that defined
+ * in the PERL scripting language but extended with elements found in the
+ * POSIX regular expression grammar.
+ */
+ ECMAScript = 1 << _S_ECMAScript,
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX basic regular expressions in IEEE Std 1003.1-2001,
+ * Portable Operating System Interface (POSIX), Base Definitions and
+ * Headers, Section 9, Regular Expressions [IEEE, Information Technology --
+ * Portable Operating System Interface (POSIX), IEEE Standard 1003.1-2001].
+ */
+ basic = 1 << _S_basic,
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX extended regular expressions in IEEE Std 1003.1-2001,
+ * Portable Operating System Interface (POSIX), Base Definitions and Headers,
+ * Section 9, Regular Expressions.
+ */
+ extended = 1 << _S_extended,
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX utility awk in IEEE Std 1003.1-2001. This option is
+ * identical to syntax_option_type extended, except that C-style escape
+ * sequences are supported. These sequences are:
+ * \\\\, \\a, \\b, \\f, \\n, \\r, \\t , \\v, \\&apos,, &apos,,
+ * and \\ddd (where ddd is one, two, or three octal digits).
+ */
+ awk = 1 << _S_awk,
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX utility grep in IEEE Std 1003.1-2001. This option is
+ * identical to syntax_option_type basic, except that newlines are treated
+ * as whitespace.
+ */
+ grep = 1 << _S_grep,
+
+ /**
+ * Specifies that the grammar recognized by the regular expression engine is
+ * that used by POSIX utility grep when given the -E option in
+ * IEEE Std 1003.1-2001. This option is identical to syntax_option_type
+ * extended, except that newlines are treated as whitespace.
+ */
+ egrep = 1 << _S_egrep,
+ };
- /**
- * Specifies that the grammar recognized by the regular expression engine is
- * that used by POSIX utility grep when given the -E option in
- * IEEE Std 1003.1-2001. This option is identical to syntax_option_type
- * extended, except that newlines are treated as whitespace.
- */
- constexpr syntax_option_type egrep = 1 << _S_egrep;
+ constexpr inline syntax_option_type
+ operator&(syntax_option_type __a, syntax_option_type __b)
+ {
+ return (syntax_option_type)(static_cast<unsigned int>(__a)
+ & static_cast<unsigned int>(__b));
+ }
+
+ constexpr inline syntax_option_type
+ operator|(syntax_option_type __a, syntax_option_type __b)
+ {
+ return (syntax_option_type)(static_cast<unsigned int>(__a)
+ | static_cast<unsigned int>(__b));
+ }
+
+ constexpr inline syntax_option_type
+ operator^(syntax_option_type __a, syntax_option_type __b)
+ {
+ return (syntax_option_type)(static_cast<unsigned int>(__a)
+ ^ static_cast<unsigned int>(__b));
+ }
+
+ constexpr inline syntax_option_type
+ operator~(syntax_option_type __a)
+ { return (syntax_option_type)(~static_cast<unsigned int>(__a)); }
+
+ inline syntax_option_type&
+ operator&=(syntax_option_type& __a, syntax_option_type __b)
+ { return __a = __a & __b; }
+
+ inline syntax_option_type&
+ operator|=(syntax_option_type& __a, syntax_option_type __b)
+ { return __a = __a | __b; }
+
+ inline syntax_option_type&
+ operator^=(syntax_option_type& __a, syntax_option_type __b)
+ { return __a = __a ^ __b; }
//@}
@@ -215,35 +253,35 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* expression shall not match [last, last).
*/
constexpr match_flag_type match_not_eol = 1 << _S_not_eol;
-
+
/**
* The expression \\b is not matched against the sub-sequence
* [first,first).
*/
constexpr match_flag_type match_not_bow = 1 << _S_not_bow;
-
+
/**
* The expression \\b should not be matched against the sub-sequence
* [last,last).
*/
constexpr match_flag_type match_not_eow = 1 << _S_not_eow;
-
+
/**
* If more than one match is possible then any match is an acceptable
* result.
*/
constexpr match_flag_type match_any = 1 << _S_any;
-
+
/**
* The expression does not match an empty sequence.
*/
constexpr match_flag_type match_not_null = 1 << _S_not_null;
-
+
/**
* The expression only matches a sub-sequence that begins at first .
*/
constexpr match_flag_type match_continuous = 1 << _S_continuous;
-
+
/**
* --first is a valid iterator position. When this flag is set then the
* flags match_not_bol and match_not_bow are ignored by the regular
@@ -260,7 +298,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* operations all non-overlapping occurrences of the regular expression
* are located and replaced, and sections of the input that did not match
* the expression are copied unchanged to the output string.
- *
+ *
* Format strings (from ECMA-262 [15.5.4.11]):
* @li $$ The dollar-sign itself ($)
* @li $& The matched substring.
diff --git a/libstdc++-v3/include/bits/regex_cursor.h b/libstdc++-v3/include/bits/regex_cursor.h
deleted file mode 100644
index 444d07ae263..00000000000
--- a/libstdc++-v3/include/bits/regex_cursor.h
+++ /dev/null
@@ -1,105 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-/**
- * @file bits/regex_cursor.h
- * This is an internal header file, included by other library headers.
- * Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- /**
- * @defgroup regex-detail Base and Implementation Classes
- * @ingroup regex
- * @{
- */
-
- /// ABC for pattern matching
- struct _PatternCursor
- {
- virtual ~_PatternCursor() { };
- virtual void _M_next() = 0;
- virtual void _M_prev() = 0;
- virtual bool _M_at_end() const = 0;
- };
-
- /// Provides a cursor into the specific target string.
- template<typename _FwdIterT>
- class _SpecializedCursor
- : public _PatternCursor
- {
- public:
- _SpecializedCursor(const _FwdIterT& __b, const _FwdIterT __e)
- : _M_b(__b), _M_c(__b), _M_e(__e)
- { }
-
- typename std::iterator_traits<_FwdIterT>::value_type
- _M_current() const
- { return *_M_c; }
-
- void
- _M_next()
- { ++_M_c; }
-
- void
- _M_prev()
- { --_M_c; }
-
- _FwdIterT
- _M_pos() const
- { return _M_c; }
-
- const _FwdIterT&
- _M_begin() const
- { return _M_b; }
-
- const _FwdIterT&
- _M_end() const
- { return _M_e; }
-
- bool
- _M_at_end() const
- { return _M_c == _M_e; }
-
- private:
- _FwdIterT _M_b;
- _FwdIterT _M_c;
- _FwdIterT _M_e;
- };
-
- // Helper function to create a cursor specialized for an iterator class.
- template<typename _FwdIterT>
- inline _SpecializedCursor<_FwdIterT>
- __cursor(const _FwdIterT& __b, const _FwdIterT __e)
- { return _SpecializedCursor<_FwdIterT>(__b, __e); }
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
diff --git a/libstdc++-v3/include/bits/regex_error.h b/libstdc++-v3/include/bits/regex_error.h
index 310b2026e60..7f06727bfae 100644
--- a/libstdc++-v3/include/bits/regex_error.h
+++ b/libstdc++-v3/include/bits/regex_error.h
@@ -45,7 +45,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* @name 5.3 Error Types
*/
//@{
-
+
enum error_type
{
_S_error_collate,
diff --git a/libstdc++-v3/include/bits/regex_executor.h b/libstdc++-v3/include/bits/regex_executor.h
new file mode 100644
index 00000000000..6d66d881584
--- /dev/null
+++ b/libstdc++-v3/include/bits/regex_executor.h
@@ -0,0 +1,225 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/**
+ * @file bits/regex_executor.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{regex}
+ */
+
+// TODO: convert comments to doxygen format.
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+ template<typename, typename>
+ class basic_regex;
+
+ template<typename>
+ class sub_match;
+
+ template<typename, typename>
+ class match_results;
+_GLIBCXX_END_NAMESPACE_VERSION
+
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @addtogroup regex-detail
+ * @{
+ */
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ class _Executor
+ {
+ public:
+ typedef match_results<_BiIter, _Alloc> _ResultsT;
+ typedef std::vector<sub_match<_BiIter>, _Alloc> _ResultsVec;
+ typedef regex_constants::match_flag_type _FlagT;
+
+ virtual
+ ~_Executor()
+ { }
+
+ // Set matched when string exactly match the pattern.
+ virtual void
+ _M_match() = 0;
+
+ // Set matched when some prefix of the string matches the pattern.
+ virtual void
+ _M_search_from_first() = 0;
+
+ protected:
+ typedef typename _NFA<_CharT, _TraitsT>::_SizeT _SizeT;
+ _Executor(_BiIter __begin,
+ _BiIter __end,
+ _ResultsT& __results,
+ _FlagT __flags,
+ _SizeT __size)
+ : _M_current(__begin), _M_end(__end), _M_results(__results),
+ _M_flags(__flags)
+ {
+ __size += 2;
+ _M_results.resize(__size);
+ for (auto __i = 0; __i < __size; __i++)
+ _M_results[__i].matched = false;
+ }
+
+ _BiIter _M_current;
+ _BiIter _M_end;
+ _ResultsVec& _M_results;
+ _FlagT _M_flags;
+ };
+
+ // A _DFSExecutor perform a DFS on given NFA and input string. At the very
+ // beginning the executor stands in the start state, then it try every
+ // possible state transition in current state recursively. Some state
+ // transitions consume input string, say, a single-char-matcher or a
+ // back-reference matcher; some not, like assertion or other anchor nodes.
+ // When the input is exhausted and the current state is an accepting state,
+ // the whole executor return true.
+ //
+ // TODO: This approach is exponentially slow for certain input.
+ // Try to compile the NFA to a DFA.
+ //
+ // Time complexity: exponential
+ // Space complexity: O(__end - __begin)
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ class _DFSExecutor
+ : public _Executor<_BiIter, _Alloc, _CharT, _TraitsT>
+ {
+ public:
+ typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT;
+ typedef _NFA<_CharT, _TraitsT> _RegexT;
+ typedef typename _BaseT::_ResultsT _ResultsT;
+ typedef typename _BaseT::_ResultsVec _ResultsVec;
+ typedef regex_constants::match_flag_type _FlagT;
+
+ _DFSExecutor(_BiIter __begin,
+ _BiIter __end,
+ _ResultsT& __results,
+ const _RegexT& __nfa,
+ const _TraitsT& __traits,
+ _FlagT __flags)
+ : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count()),
+ _M_traits(__traits), _M_nfa(__nfa), _M_results_ret(this->_M_results)
+ { }
+
+ void
+ _M_match()
+ { _M_dfs<true>(_M_nfa._M_start()); }
+
+ void
+ _M_search_from_first()
+ { _M_dfs<false>(_M_nfa._M_start()); }
+
+ private:
+ template<bool __match_mode>
+ bool
+ _M_dfs(_StateIdT __i);
+
+ _ResultsVec _M_results_ret;
+ const _TraitsT& _M_traits;
+ const _RegexT& _M_nfa;
+ };
+
+ // Like the DFS approach, it try every possible state transition; Unlike DFS,
+ // it uses a queue instead of a stack to store matching states. It's a BFS
+ // approach.
+ //
+ // Russ Cox's article(http://swtch.com/~rsc/regexp/regexp1.html) explained
+ // this algorithm clearly.
+ //
+ // Every entry of _M_covered saves the solution(grouping status) for every
+ // matching head. When states transit, solutions will be compared and
+ // deduplicated(based on which greedy mode we have).
+ //
+ // Time complexity: O((__end - __begin) * _M_nfa.size())
+ // Space complexity: O(_M_nfa.size() * _M_nfa.mark_count())
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ class _BFSExecutor
+ : public _Executor<_BiIter, _Alloc, _CharT, _TraitsT>
+ {
+ public:
+ typedef _Executor<_BiIter, _Alloc, _CharT, _TraitsT> _BaseT;
+ typedef _NFA<_CharT, _TraitsT> _RegexT;
+ typedef typename _BaseT::_ResultsT _ResultsT;
+ typedef typename _BaseT::_ResultsVec _ResultsVec;
+ typedef std::unique_ptr<_ResultsVec> _ResultsPtr;
+ typedef regex_constants::match_flag_type _FlagT;
+
+ _BFSExecutor(_BiIter __begin,
+ _BiIter __end,
+ _ResultsT& __results,
+ const _RegexT& __nfa,
+ _FlagT __flags)
+ : _BaseT(__begin, __end, __results, __flags, __nfa._M_sub_count()),
+ _M_nfa(__nfa)
+ {
+ if (_M_nfa._M_start() != _S_invalid_state_id)
+ _M_covered[_M_nfa._M_start()] =
+ _ResultsPtr(new _ResultsVec(this->_M_results));
+ _M_e_closure();
+ }
+
+ void
+ _M_match()
+ { _M_main_loop<true>(); }
+
+ void
+ _M_search_from_first()
+ { _M_main_loop<false>(); }
+
+ private:
+ template<bool __match_mode>
+ void
+ _M_main_loop();
+
+ void
+ _M_e_closure();
+
+ void
+ _M_move();
+
+ bool
+ _M_match_less_than(const _ResultsVec& __u, const _ResultsVec& __v) const;
+
+ bool
+ _M_includes_some() const;
+
+ std::map<_StateIdT, _ResultsPtr> _M_covered;
+ const _RegexT& _M_nfa;
+ };
+
+ //@} regex-detail
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#include <bits/regex_executor.tcc>
diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc
new file mode 100644
index 00000000000..788d65e54de
--- /dev/null
+++ b/libstdc++-v3/include/bits/regex_executor.tcc
@@ -0,0 +1,330 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/**
+ * @file bits/regex_executor.tcc
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ template<bool __match_mode>
+ bool _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+ _M_dfs(_StateIdT __i)
+ {
+ if (__i == _S_invalid_state_id)
+ // This is not that certain. Need deeper investigate.
+ return false;
+ auto& __current = this->_M_current;
+ auto& __end = this->_M_end;
+ auto& __results = _M_results_ret;
+ const auto& __state = _M_nfa[__i];
+ bool __ret = false;
+ switch (__state._M_opcode)
+ {
+ case _S_opcode_alternative:
+ // Greedy mode by default. For non-greedy mode,
+ // swap _M_alt and _M_next.
+ // TODO: Add greedy mode option.
+ __ret = _M_dfs<__match_mode>(__state._M_alt)
+ || _M_dfs<__match_mode>(__state._M_next);
+ break;
+ case _S_opcode_subexpr_begin:
+ // Here's the critical part: if there's nothing changed since last
+ // visit, do NOT continue. This prevents the executor from get into
+ // infinite loop when use "()*" to match "".
+ //
+ // Every change on __results will be roll back after the recursion
+ // step finished.
+ if (!__results[__state._M_subexpr].matched
+ || __results[__state._M_subexpr].first != __current)
+ {
+ auto __back = __current;
+ __results[__state._M_subexpr].first = __current;
+ __ret = _M_dfs<__match_mode>(__state._M_next);
+ __results[__state._M_subexpr].first = __back;
+ }
+ break;
+ case _S_opcode_subexpr_end:
+ if (__results[__state._M_subexpr].second != __current
+ || __results[__state._M_subexpr].matched != true)
+ {
+ auto __back = __results[__state._M_subexpr];
+ __results[__state._M_subexpr].second = __current;
+ __results[__state._M_subexpr].matched = true;
+ __ret = _M_dfs<__match_mode>(__state._M_next);
+ __results[__state._M_subexpr] = __back;
+ }
+ else
+ __ret = _M_dfs<__match_mode>(__state._M_next);
+ break;
+ case _S_opcode_match:
+ if (__current != __end && __state._M_matches(*__current))
+ {
+ ++__current;
+ __ret = _M_dfs<__match_mode>(__state._M_next);
+ --__current;
+ }
+ break;
+ // First fetch the matched result from __results as __submatch;
+ // then compare it with
+ // (__current, __current + (__submatch.second - __submatch.first))
+ // If matched, keep going; else just return to try another state.
+ case _S_opcode_backref:
+ {
+ auto& __submatch = __results[__state._M_backref_index];
+ if (!__submatch.matched)
+ break;
+ auto __last = __current;
+ for (auto __tmp = __submatch.first;
+ __last != __end && __tmp != __submatch.second;
+ ++__tmp)
+ ++__last;
+ if (_M_traits.transform(__submatch.first, __submatch.second)
+ == _M_traits.transform(__current, __last))
+ if (__last != __current)
+ {
+ auto __backup = __current;
+ __current = __last;
+ __ret = _M_dfs<__match_mode>(__state._M_next);
+ __current = __backup;
+ }
+ else
+ __ret = _M_dfs<__match_mode>(__state._M_next);
+ }
+ break;
+ case _S_opcode_accept:
+ if (__match_mode)
+ __ret = __current == __end;
+ else
+ __ret = true;
+ if (__ret)
+ this->_M_results = __results;
+ break;
+ default:
+ _GLIBCXX_DEBUG_ASSERT(false);
+ }
+ return __ret;
+ }
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ template<bool __match_mode>
+ void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+ _M_main_loop()
+ {
+ while (this->_M_current != this->_M_end)
+ {
+ if (!__match_mode)
+ if (_M_includes_some())
+ return;
+ _M_move();
+ ++this->_M_current;
+ _M_e_closure();
+ }
+ _M_includes_some();
+ }
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+ _M_e_closure()
+ {
+ auto& __current = this->_M_current;
+ std::queue<_StateIdT> __q;
+ std::vector<bool> __in_q(_M_nfa.size(), false);
+ for (auto& __it : _M_covered)
+ {
+ __in_q[__it.first] = true;
+ __q.push(__it.first);
+ }
+ while (!__q.empty())
+ {
+ auto __u = __q.front();
+ __q.pop();
+ __in_q[__u] = false;
+ const auto& __state = _M_nfa[__u];
+
+ // Can be implemented using method, but there're too much arguments.
+ // I would use macro function before C++11, but lambda is a better
+ // choice, since hopefully compiler can inline it.
+ auto __add_visited_state = [&](_StateIdT __v)
+ {
+ if (__v == _S_invalid_state_id)
+ return;
+ if (_M_covered.count(__u) != 0
+ && (_M_covered.count(__v) == 0
+ || _M_match_less_than(*_M_covered[__u], *_M_covered[__v])))
+ {
+ _M_covered[__v] = _ResultsPtr(new _ResultsVec(*_M_covered[__u]));
+ // if a state is updated, it's outgoing neighbors should be
+ // reconsidered too. Push them to the queue.
+ if (!__in_q[__v])
+ {
+ __in_q[__v] = true;
+ __q.push(__v);
+ }
+ }
+ };
+
+ switch (__state._M_opcode)
+ {
+ case _S_opcode_alternative:
+ __add_visited_state(__state._M_next);
+ __add_visited_state(__state._M_alt);
+ break;
+ case _S_opcode_subexpr_begin:
+ {
+ auto& __cu = *_M_covered[__u];
+ auto __back = __cu[__state._M_subexpr].first;
+ __cu[__state._M_subexpr].first = __current;
+ __add_visited_state(__state._M_next);
+ __cu[__state._M_subexpr].first = __back;
+ }
+ break;
+ case _S_opcode_subexpr_end:
+ {
+ auto& __cu = *_M_covered[__u];
+ auto __back = __cu[__state._M_subexpr];
+ __cu[__state._M_subexpr].second = __current;
+ __cu[__state._M_subexpr].matched = true;
+ __add_visited_state(__state._M_next);
+ __cu[__state._M_subexpr] = __back;
+ }
+ break;
+ case _S_opcode_match:
+ break;
+ case _S_opcode_accept:
+ __add_visited_state(__state._M_next);
+ break;
+ default:
+ _GLIBCXX_DEBUG_ASSERT(false);
+ }
+ }
+ }
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ void _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+ _M_move()
+ {
+ decltype(_M_covered) __next;
+ for (auto& __it : _M_covered)
+ {
+ const auto& __state = _M_nfa[__it.first];
+ if (__state._M_opcode == _S_opcode_match
+ && __state._M_matches(*this->_M_current))
+ if (__state._M_next != _S_invalid_state_id)
+ if (__next.count(__state._M_next) == 0
+ || _M_match_less_than(*__it.second, *__next[__state._M_next]))
+ __next[__state._M_next] = move(__it.second);
+ }
+ _M_covered = move(__next);
+ }
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+ _M_match_less_than(const _ResultsVec& __u, const _ResultsVec& __v) const
+ {
+ // TODO: Greedy and Non-greedy support
+ _GLIBCXX_DEBUG_ASSERT(__u.size() == __v.size());
+ auto __size = __u.size();
+ for (auto __i = 0; __i < __size; __i++)
+ {
+ auto __uit = __u[__i], __vit = __v[__i];
+ if (__uit.matched && !__vit.matched)
+ return true;
+ if (!__uit.matched && __vit.matched)
+ return false;
+ if (__uit.matched && __vit.matched)
+ {
+ // GREEDY
+ if (__uit.first != __vit.first)
+ return __uit.first < __vit.first;
+ if (__uit.second != __vit.second)
+ return __uit.second > __vit.second;
+ }
+ }
+ return false;
+ }
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ bool _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT>::
+ _M_includes_some() const
+ {
+ auto& __s = _M_nfa._M_final_states();
+ auto& __t = _M_covered;
+ if (__s.size() > 0 && __t.size() > 0)
+ {
+ auto __first = __s.begin();
+ auto __second = __t.begin();
+ while (__first != __s.end() && __second != __t.end())
+ {
+ if (*__first < __second->first)
+ ++__first;
+ else if (__second->first < *__first)
+ ++__second;
+ else
+ {
+ this->_M_results = *__second->second;
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ template<typename _BiIter, typename _Alloc,
+ typename _CharT, typename _TraitsT>
+ std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+ __get_executor(_BiIter __b,
+ _BiIter __e,
+ match_results<_BiIter, _Alloc>& __m,
+ const basic_regex<_CharT, _TraitsT>& __re,
+ regex_constants::match_flag_type __flags)
+ {
+ typedef std::unique_ptr<_Executor<_BiIter, _Alloc, _CharT, _TraitsT>>
+ _ExecutorPtr;
+ typedef _DFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _DFSExecutorT;
+ typedef _BFSExecutor<_BiIter, _Alloc, _CharT, _TraitsT> _BFSExecutorT;
+ auto __p = std::static_pointer_cast<_NFA<_CharT, _TraitsT>>
+ (__re._M_automaton);
+ if (__p->_M_has_backref)
+ return _ExecutorPtr(new _DFSExecutorT(__b, __e, __m, *__p,
+ __re._M_traits, __flags));
+ return _ExecutorPtr(new _BFSExecutorT(__b, __e, __m, *__p, __flags));
+ }
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
diff --git a/libstdc++-v3/include/bits/regex_grep_matcher.h b/libstdc++-v3/include/bits/regex_grep_matcher.h
deleted file mode 100644
index 8686cc933be..00000000000
--- a/libstdc++-v3/include/bits/regex_grep_matcher.h
+++ /dev/null
@@ -1,173 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-/**
- * @file bits/regex_grep_matcher.h
- * This is an internal header file, included by other library headers.
- * Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- template<typename _BiIter>
- class sub_match;
-
- template<typename _Bi_iter, typename _Allocator>
- class match_results;
-
-_GLIBCXX_END_NAMESPACE_VERSION
-
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- /**
- * @defgroup regex-detail Base and Implementation Classes
- * @ingroup regex
- * @{
- */
-
- /// A _Results facade specialized for wrapping a templated match_results.
- template<typename _FwdIterT, typename _Alloc>
- class _SpecializedResults
- : public _Results
- {
- public:
- _SpecializedResults(const _Automaton::_SizeT __size,
- const _SpecializedCursor<_FwdIterT>& __cursor,
- match_results<_FwdIterT, _Alloc>& __m);
-
- void
- _M_set_pos(int __i, int __j, const _PatternCursor& __pc);
-
- void
- _M_set_range(int __i, const _PatternCursor& __pc)
- {
- typedef const _SpecializedCursor<_FwdIterT>& _CursorT;
- _CursorT __c = static_cast<_CursorT>(__pc);
- _M_results.at(__i).first = __c._M_begin();
- _M_results.at(__i).second = __c._M_end();
- }
-
- void
- _M_set_matched(int __i, bool __is_matched)
- { _M_results.at(__i).matched = __is_matched; }
-
- private:
- match_results<_FwdIterT, _Alloc>& _M_results;
- };
-
- template<typename _FwdIterT, typename _Alloc>
- _SpecializedResults<_FwdIterT, _Alloc>::
- _SpecializedResults(const _Automaton::_SizeT __size,
- const _SpecializedCursor<_FwdIterT>& __cursor,
- match_results<_FwdIterT, _Alloc>& __m)
- : _M_results(__m)
- {
- _M_results.clear();
- _M_results.reserve(__size + 2);
- _M_results.resize(__size);
- typename match_results<_FwdIterT, _Alloc>::value_type __sm;
- __sm.first = __sm.second = __cursor._M_begin();
- _M_results.push_back(__sm);
- __sm.first = __sm.second = __cursor._M_end();
- _M_results.push_back(__sm);
- }
-
- template<typename _FwdIterT, typename _Alloc>
- void
- _SpecializedResults<_FwdIterT, _Alloc>::
- _M_set_pos(int __i, int __j, const _PatternCursor& __pc)
- {
- typedef const _SpecializedCursor<_FwdIterT>& _CursorT;
- _CursorT __c = static_cast<_CursorT>(__pc);
- if (__j == 0)
- _M_results.at(__i).first = __c._M_pos();
- else
- _M_results.at(__i).second = __c._M_pos();
- }
-
- /// A stack of states used in evaluating the NFA.
- typedef std::stack<_StateIdT, std::vector<_StateIdT> > _StateStack;
-
- /// Executes a regular expression NFA/DFA over a range using a
- /// variant of the parallel execution algorithm featured in the grep
- /// utility, modified to use Laurikari tags.
- class _Grep_matcher
- {
- public:
- _Grep_matcher(_PatternCursor& __p,
- _Results& __r,
- const _AutomatonPtr& __automaton,
- regex_constants::match_flag_type __flags)
- : _M_nfa(static_pointer_cast<_Nfa>(__automaton)),
- _M_pattern(__p), _M_results(__r)
- { }
-
- // Set matched when string exactly match the pattern.
- void
- _M_match();
-
- // Set matched when some prefix of the string matches the pattern.
- void
- _M_search_from_first();
-
- // TODO: in the future this function will be _M_match, in another class.
- bool
- _M_dfs_match()
- { return _M_dfs<true>(_M_nfa->_M_start()); }
-
- // TODO: in the future this function will be _M_search_from_first,
- // in another class.
- bool
- _M_dfs_search_from_first()
- { return _M_dfs<false>(_M_nfa->_M_start()); }
-
- private:
- _StateSet
- _M_e_closure(_StateIdT __i);
-
- _StateSet
- _M_e_closure(const _StateSet& __s);
-
- _StateSet
- _M_e_closure(_StateStack& __stack, const _StateSet& __s);
-
- template<bool __match_mode>
- bool
- _M_dfs(_StateIdT __i);
-
- const std::shared_ptr<_Nfa> _M_nfa;
- _PatternCursor& _M_pattern;
- _Results& _M_results;
- };
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace std
-
-#include <bits/regex_grep_matcher.tcc>
diff --git a/libstdc++-v3/include/bits/regex_grep_matcher.tcc b/libstdc++-v3/include/bits/regex_grep_matcher.tcc
deleted file mode 100644
index dccdfda0bc1..00000000000
--- a/libstdc++-v3/include/bits/regex_grep_matcher.tcc
+++ /dev/null
@@ -1,243 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-/**
- * @file bits/regex_grep_matcher.tcc
- * This is an internal header file, included by other library headers.
- * Do not attempt to use it directly. @headername{regex}
- */
-
-#include <regex>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace
-{
- // A stack of states used in evaluating the NFA.
- typedef std::stack<std::__detail::_StateIdT,
- std::vector<std::__detail::_StateIdT>
- > _StateStack;
-
- // Obtains the next state set given the current state set __s and the current
- // input character.
- inline std::__detail::_StateSet
- __move(const std::__detail::_PatternCursor& __p,
- const std::__detail::_Nfa& __nfa,
- const std::__detail::_StateSet& __s)
- {
- std::__detail::_StateSet __m;
- for (std::__detail::_StateSet::const_iterator __i = __s.begin();
- __i != __s.end(); ++__i)
- {
- if (*__i == std::__detail::_S_invalid_state_id)
- continue;
-
- const std::__detail::_State& __state = __nfa[*__i];
- if (__state._M_opcode == std::__detail::_S_opcode_match
- && __state._M_matches(__p))
- __m.insert(__state._M_next);
- }
- return __m;
- }
-
- // returns true if (__s intersect __t) is not empty
- inline bool
- __includes_some(const std::__detail::_StateSet& __s,
- const std::__detail::_StateSet& __t)
- {
- if (__s.size() > 0 && __t.size() > 0)
- {
- std::__detail::_StateSet::const_iterator __first = __s.begin();
- std::__detail::_StateSet::const_iterator __second = __t.begin();
- while (__first != __s.end() && __second != __t.end())
- {
- if (*__first < *__second)
- ++__first;
- else if (*__second < *__first)
- ++__second;
- else
- return true;
- }
- }
- return false;
- }
-
- // If an identified state __u is not already in the current state set __e,
- // insert it and push it on the current state stack __s.
- inline void
- __add_visited_state(const std::__detail::_StateIdT __u,
- _StateStack& __s,
- std::__detail::_StateSet& __e)
- {
- if (__e.count(__u) == 0)
- {
- __e.insert(__u);
- __s.push(__u);
- }
- }
-
-} // anonymous namespace
-
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- // _M_dfs() take a state, along with current string cursor(_M_pattern),
- // trying to match current state with current character.
- // Only _S_opcode_match will consume a character.
- // TODO: This is too slow. Try to compile the NFA to a DFA.
- template<bool __match_mode>
- bool _Grep_matcher::
- _M_dfs(_StateIdT __i)
- {
- if (__i == _S_invalid_state_id)
- // This is not that certain. Need deeper investigate.
- return false;
- const auto& __state = (*_M_nfa)[__i];
- bool __ret = false;
- switch (__state._M_opcode)
- {
- case _S_opcode_alternative:
- // Greedy mode by default. For non-greedy mode,
- // swap _M_alt and _M_next.
- // TODO: Add greedy mode option.
- __ret = _M_dfs<__match_mode>(__state._M_alt)
- || _M_dfs<__match_mode>(__state._M_next);
- break;
- case _S_opcode_subexpr_begin:
- __state._M_tagger(_M_pattern, _M_results);
- __ret = _M_dfs<__match_mode>(__state._M_next);
- break;
- case _S_opcode_subexpr_end:
- __state._M_tagger(_M_pattern, _M_results);
- __ret = _M_dfs<__match_mode>(__state._M_next);
- _M_results._M_set_matched(__state._M_subexpr, __ret);
- break;
- case _S_opcode_match:
- if (!_M_pattern._M_at_end() && __state._M_matches(_M_pattern))
- {
- _M_pattern._M_next();
- __ret = _M_dfs<__match_mode>(__state._M_next);
- _M_pattern._M_prev();
- }
- break;
- case _S_opcode_accept:
- if (__match_mode)
- __ret = _M_pattern._M_at_end();
- else
- __ret = true;
- break;
- default:
- _GLIBCXX_DEBUG_ASSERT( false );
- }
- return __ret;
- }
-
- inline void _Grep_matcher::
- _M_match()
- {
- __detail::_StateSet __t = this->_M_e_closure(_M_nfa->_M_start());
- for (; !_M_pattern._M_at_end(); _M_pattern._M_next())
- __t = this->_M_e_closure(__move(_M_pattern, *_M_nfa, __t));
-
- _M_results._M_set_matched(0,
- __includes_some(_M_nfa->_M_final_states(), __t));
- }
-
- inline void _Grep_matcher::
- _M_search_from_first()
- {
- __detail::_StateSet __t = this->_M_e_closure(_M_nfa->_M_start());
- for (; !_M_pattern._M_at_end(); _M_pattern._M_next())
- {
- if (__includes_some(_M_nfa->_M_final_states(), __t)) // KISS
- {
- _M_results._M_set_matched(0, true);
- return;
- }
- __t = this->_M_e_closure(__move(_M_pattern, *_M_nfa, __t));
- }
- _M_results._M_set_matched(0, false);
- }
-
- // Creates the e-closure set for the initial state __i.
- inline _StateSet _Grep_matcher::
- _M_e_closure(_StateIdT __i)
- {
- _StateSet __s;
- __s.insert(__i);
- _StateStack __stack;
- __stack.push(__i);
- return this->_M_e_closure(__stack, __s);
- }
-
- // Creates the e-closure set for an arbitrary state set __s.
- inline _StateSet _Grep_matcher::
- _M_e_closure(const _StateSet& __s)
- {
- _StateStack __stack;
- for (_StateSet::const_iterator __i = __s.begin(); __i != __s.end(); ++__i)
- __stack.push(*__i);
- return this->_M_e_closure(__stack, __s);
- }
-
- inline _StateSet _Grep_matcher::
- _M_e_closure(_StateStack& __stack, const _StateSet& __s)
- {
- _StateSet __e = __s;
- while (!__stack.empty())
- {
- _StateIdT __t = __stack.top(); __stack.pop();
- if (__t == _S_invalid_state_id)
- continue;
- // for each __u with edge from __t to __u labeled e do ...
- const _State& __state = _M_nfa->operator[](__t);
- switch (__state._M_opcode)
- {
- case _S_opcode_alternative:
- __add_visited_state(__state._M_next, __stack, __e);
- __add_visited_state(__state._M_alt, __stack, __e);
- break;
- case _S_opcode_subexpr_begin:
- __add_visited_state(__state._M_next, __stack, __e);
- __state._M_tagger(_M_pattern, _M_results);
- break;
- case _S_opcode_subexpr_end:
- __add_visited_state(__state._M_next, __stack, __e);
- __state._M_tagger(_M_pattern, _M_results);
- _M_results._M_set_matched(__state._M_subexpr, true);
- break;
- case _S_opcode_accept:
- __add_visited_state(__state._M_next, __stack, __e);
- break;
- default:
- break;
- }
- }
- return __e;
- }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
diff --git a/libstdc++-v3/include/bits/regex_nfa.h b/libstdc++-v3/include/bits/regex_nfa.h
deleted file mode 100644
index fc30237436a..00000000000
--- a/libstdc++-v3/include/bits/regex_nfa.h
+++ /dev/null
@@ -1,415 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-/**
- * @file bits/regex_nfa.h
- * This is an internal header file, included by other library headers.
- * Do not attempt to use it directly. @headername{regex}
- */
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
- /**
- * @addtogroup regex-detail
- * @{
- */
-
- /// Base class for, um, automata. Could be an NFA or a DFA. Your choice.
- class _Automaton
- {
- public:
- typedef unsigned int _SizeT;
-
- public:
- virtual
- ~_Automaton() { }
-
- virtual _SizeT
- _M_sub_count() const = 0;
-
-#ifdef _GLIBCXX_DEBUG
- virtual std::ostream&
- _M_dot(std::ostream& __ostr) const = 0;
-#endif
- };
-
- /// Generic shared pointer to an automaton.
- typedef std::shared_ptr<_Automaton> _AutomatonPtr;
-
- /// Operation codes that define the type of transitions within the base NFA
- /// that represents the regular expression.
- enum _Opcode
- {
- _S_opcode_unknown = 0,
- _S_opcode_alternative = 1,
- _S_opcode_subexpr_begin = 4,
- _S_opcode_subexpr_end = 5,
- _S_opcode_match = 100,
- _S_opcode_accept = 255
- };
-
- /// Provides a generic facade for a templated match_results.
- struct _Results
- {
- virtual void _M_set_pos(int __i, int __j, const _PatternCursor& __p) = 0;
- virtual void _M_set_matched(int __i, bool __is_matched) = 0;
- };
-
- /// Tags current state (for subexpr begin/end).
- typedef std::function<void (const _PatternCursor&, _Results&)> _Tagger;
-
- /// Start state tag.
- template<typename _FwdIterT, typename _TraitsT>
- struct _StartTagger
- {
- explicit
- _StartTagger(int __i)
- : _M_index(__i)
- { }
-
- void
- operator()(const _PatternCursor& __pc, _Results& __r)
- { __r._M_set_pos(_M_index, 0, __pc); }
-
- int _M_index;
- };
-
- /// End state tag.
- template<typename _FwdIterT, typename _TraitsT>
- struct _EndTagger
- {
- explicit
- _EndTagger(int __i)
- : _M_index(__i)
- { }
-
- void
- operator()(const _PatternCursor& __pc, _Results& __r)
- { __r._M_set_pos(_M_index, 1, __pc); }
-
- int _M_index;
- _FwdIterT _M_pos;
- };
-
- /// Indicates if current state matches cursor current.
- typedef std::function<bool (const _PatternCursor&)> _Matcher;
-
- /// Matches any character
- inline bool
- _AnyMatcher(const _PatternCursor&)
- { return true; }
-
- /// Matches a single character
- template<typename _InIterT, typename _TraitsT>
- struct _CharMatcher
- {
- typedef typename _TraitsT::char_type char_type;
-
- explicit
- _CharMatcher(char_type __c, const _TraitsT& __t = _TraitsT())
- : _M_traits(__t), _M_c(_M_traits.translate(__c))
- { }
-
- bool
- operator()(const _PatternCursor& __pc) const
- {
- typedef const _SpecializedCursor<_InIterT>& _CursorT;
- _CursorT __c = static_cast<_CursorT>(__pc);
- return _M_traits.translate(__c._M_current()) == _M_c;
- }
-
- const _TraitsT& _M_traits;
- char_type _M_c;
- };
-
- /// Matches a character range (bracket expression)
- template<typename _InIterT, typename _TraitsT>
- struct _RangeMatcher
- {
- typedef typename _TraitsT::char_type _CharT;
- typedef std::basic_string<_CharT> _StringT;
-
- explicit
- _RangeMatcher(bool __is_non_matching, const _TraitsT& __t = _TraitsT())
- : _M_traits(__t), _M_is_non_matching(__is_non_matching)
- { }
-
- bool
- operator()(const _PatternCursor& __pc) const
- {
- typedef const _SpecializedCursor<_InIterT>& _CursorT;
- _CursorT __c = static_cast<_CursorT>(__pc);
- return true;
- }
-
- void
- _M_add_char(_CharT __c)
- { }
-
- void
- _M_add_collating_element(const _StringT& __s)
- { }
-
- void
- _M_add_equivalence_class(const _StringT& __s)
- { }
-
- void
- _M_add_character_class(const _StringT& __s)
- { }
-
- void
- _M_make_range()
- { }
-
- const _TraitsT& _M_traits;
- bool _M_is_non_matching;
- };
-
- /// Identifies a state in the NFA.
- typedef int _StateIdT;
-
- /// The special case in which a state identifier is not an index.
- static const _StateIdT _S_invalid_state_id = -1;
-
-
- /**
- * @brief struct _State
- *
- * An individual state in an NFA
- *
- * In this case a "state" is an entry in the NFA definition coupled
- * with its outgoing transition(s). All states have a single outgoing
- * transition, except for accepting states (which have no outgoing
- * transitions) and alt states, which have two outgoing transitions.
- */
- struct _State
- {
- typedef int _OpcodeT;
-
- _OpcodeT _M_opcode; // type of outgoing transition
- _StateIdT _M_next; // outgoing transition
- _StateIdT _M_alt; // for _S_opcode_alternative
- unsigned int _M_subexpr; // for _S_opcode_subexpr_*
- _Tagger _M_tagger; // for _S_opcode_subexpr_*
- _Matcher _M_matches; // for _S_opcode_match
-
- explicit _State(_OpcodeT __opcode)
- : _M_opcode(__opcode), _M_next(_S_invalid_state_id)
- { }
-
- _State(const _Matcher& __m)
- : _M_opcode(_S_opcode_match), _M_next(_S_invalid_state_id), _M_matches(__m)
- { }
-
- _State(_OpcodeT __opcode, unsigned int __s, const _Tagger& __t)
- : _M_opcode(__opcode), _M_next(_S_invalid_state_id), _M_subexpr(__s),
- _M_tagger(__t)
- { }
-
- _State(_StateIdT __next, _StateIdT __alt)
- : _M_opcode(_S_opcode_alternative), _M_next(__next), _M_alt(__alt)
- { }
-
-#ifdef _GLIBCXX_DEBUG
- std::ostream&
- _M_print(std::ostream& ostr) const;
-
- // Prints graphviz dot commands for state.
- std::ostream&
- _M_dot(std::ostream& __ostr, _StateIdT __id) const;
-#endif
- };
-
-
- /// The Grep Matcher works on sets of states. Here are sets of states.
- typedef std::set<_StateIdT> _StateSet;
-
- /**
- * @brief struct _Nfa
- *
- * A collection of all states making up an NFA.
- *
- * An NFA is a 4-tuple M = (K, S, s, F), where
- * K is a finite set of states,
- * S is the alphabet of the NFA,
- * s is the initial state,
- * F is a set of final (accepting) states.
- *
- * This NFA class is templated on S, a type that will hold values of the
- * underlying alphabet (without regard to semantics of that alphabet). The
- * other elements of the tuple are generated during construction of the NFA
- * and are available through accessor member functions.
- */
- class _Nfa
- : public _Automaton, public std::vector<_State>
- {
- public:
- typedef _State _StateT;
- typedef unsigned int _SizeT;
- typedef regex_constants::syntax_option_type _FlagT;
-
- _Nfa(_FlagT __f)
- : _M_flags(__f), _M_start_state(0), _M_subexpr_count(0)
- { }
-
- ~_Nfa()
- { }
-
- _FlagT
- _M_options() const
- { return _M_flags; }
-
- _StateIdT
- _M_start() const
- { return _M_start_state; }
-
- const _StateSet&
- _M_final_states() const
- { return _M_accepting_states; }
-
- _SizeT
- _M_sub_count() const
- { return _M_subexpr_count; }
-
- _StateIdT
- _M_insert_accept()
- {
- this->push_back(_StateT(_S_opcode_accept));
- _M_accepting_states.insert(this->size()-1);
- return this->size()-1;
- }
-
- _StateIdT
- _M_insert_alt(_StateIdT __next, _StateIdT __alt)
- {
- this->push_back(_StateT(__next, __alt));
- return this->size()-1;
- }
-
- _StateIdT
- _M_insert_matcher(_Matcher __m)
- {
- this->push_back(_StateT(__m));
- return this->size()-1;
- }
-
- _StateIdT
- _M_insert_subexpr_begin(const _Tagger& __t)
- {
- this->push_back(_StateT(_S_opcode_subexpr_begin, _M_subexpr_count++,
- __t));
- return this->size()-1;
- }
-
- _StateIdT
- _M_insert_subexpr_end(unsigned int __i, const _Tagger& __t)
- {
- this->push_back(_StateT(_S_opcode_subexpr_end, __i, __t));
- return this->size()-1;
- }
-
-#ifdef _GLIBCXX_DEBUG
- std::ostream&
- _M_dot(std::ostream& __ostr) const;
-#endif
-
- private:
- _FlagT _M_flags;
- _StateIdT _M_start_state;
- _StateSet _M_accepting_states;
- _SizeT _M_subexpr_count;
- };
-
- /// Describes a sequence of one or more %_State, its current start
- /// and end(s). This structure contains fragments of an NFA during
- /// construction.
- class _StateSeq
- {
- public:
- // Constructs a single-node sequence
- _StateSeq(_Nfa& __ss, _StateIdT __s, _StateIdT __e = _S_invalid_state_id)
- : _M_nfa(__ss), _M_start(__s), _M_end1(__s), _M_end2(__e)
- { }
- // Constructs a split sequence from two other sequencces
- _StateSeq(const _StateSeq& __e1, const _StateSeq& __e2)
- : _M_nfa(__e1._M_nfa),
- _M_start(_M_nfa._M_insert_alt(__e1._M_start, __e2._M_start)),
- _M_end1(__e1._M_end1), _M_end2(__e2._M_end1)
- { }
-
- // Constructs a split sequence from a single sequence
- _StateSeq(const _StateSeq& __e, _StateIdT __id)
- : _M_nfa(__e._M_nfa),
- _M_start(_M_nfa._M_insert_alt(__id, __e._M_start)),
- _M_end1(__id), _M_end2(__e._M_end1)
- { }
-
- // Constructs a copy of a %_StateSeq
- _StateSeq(const _StateSeq& __rhs)
- : _M_nfa(__rhs._M_nfa), _M_start(__rhs._M_start),
- _M_end1(__rhs._M_end1), _M_end2(__rhs._M_end2)
- { }
-
-
- _StateSeq& operator=(const _StateSeq& __rhs);
-
- _StateIdT
- _M_front() const
- { return _M_start; }
-
- // Extends a sequence by one.
- void
- _M_push_back(_StateIdT __id);
-
- // Extends and maybe joins a sequence.
- void
- _M_append(_StateIdT __id);
-
- void
- _M_append(_StateSeq& __rhs);
-
- // Clones an entire sequence.
- _StateIdT
- _M_clone();
-
- private:
- _Nfa& _M_nfa;
- _StateIdT _M_start;
- _StateIdT _M_end1;
- _StateIdT _M_end2;
-
- };
-
- //@} regex-detail
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace std
-
-#include <bits/regex_nfa.tcc>
-
diff --git a/libstdc++-v3/include/bits/regex_nfa.tcc b/libstdc++-v3/include/bits/regex_nfa.tcc
deleted file mode 100644
index e8277f806a1..00000000000
--- a/libstdc++-v3/include/bits/regex_nfa.tcc
+++ /dev/null
@@ -1,174 +0,0 @@
-// class template regex -*- C++ -*-
-
-// Copyright (C) 2010-2013 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 3, or (at your option)
-// any later version.
-
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU General Public License for more details.
-
-// Under Section 7 of GPL version 3, you are granted additional
-// permissions described in the GCC Runtime Library Exception, version
-// 3.1, as published by the Free Software Foundation.
-
-// You should have received a copy of the GNU General Public License and
-// a copy of the GCC Runtime Library Exception along with this program;
-// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
-// <http://www.gnu.org/licenses/>.
-
-/**
- * @file bits/regex_nfa.tcc
- * This is an internal header file, included by other library headers.
- * Do not attempt to use it directly. @headername{regex}
- */
-#include <regex>
-
-namespace std _GLIBCXX_VISIBILITY(default)
-{
-namespace __detail
-{
-_GLIBCXX_BEGIN_NAMESPACE_VERSION
-
-#ifdef _GLIBCXX_DEBUG
-inline std::ostream& _State::
-_M_print(std::ostream& ostr) const
-{
- switch (_M_opcode)
- {
- case _S_opcode_alternative:
- ostr << "alt next=" << _M_next << " alt=" << _M_alt;
- break;
- case _S_opcode_subexpr_begin:
- ostr << "subexpr begin next=" << _M_next << " index=" << _M_subexpr;
- break;
- case _S_opcode_subexpr_end:
- ostr << "subexpr end next=" << _M_next << " index=" << _M_subexpr;
- break;
- case _S_opcode_match:
- ostr << "match next=" << _M_next;
- break;
- case _S_opcode_accept:
- ostr << "accept next=" << _M_next;
- break;
- default:
- ostr << "unknown next=" << _M_next;
- break;
- }
- return ostr;
-}
-
-// Prints graphviz dot commands for state.
-inline std::ostream& _State::
-_M_dot(std::ostream& __ostr, _StateIdT __id) const
-{
- switch (_M_opcode)
- {
- case _S_opcode_alternative:
- __ostr << __id << " [label=\"" << __id << "\\nALT\"];\n"
- << __id << " -> " << _M_next
- << " [label=\"epsilon\", tailport=\"s\"];\n"
- << __id << " -> " << _M_alt
- << " [label=\"epsilon\", tailport=\"n\"];\n";
- break;
- case _S_opcode_subexpr_begin:
- __ostr << __id << " [label=\"" << __id << "\\nSBEGIN "
- << _M_subexpr << "\"];\n"
- << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
- break;
- case _S_opcode_subexpr_end:
- __ostr << __id << " [label=\"" << __id << "\\nSEND "
- << _M_subexpr << "\"];\n"
- << __id << " -> " << _M_next << " [label=\"epsilon\"];\n";
- break;
- case _S_opcode_match:
- __ostr << __id << " [label=\"" << __id << "\\nMATCH\"];\n"
- << __id << " -> " << _M_next << " [label=\"<match>\"];\n";
- break;
- case _S_opcode_accept:
- __ostr << __id << " [label=\"" << __id << "\\nACC\"];\n" ;
- break;
- default:
- __ostr << __id << " [label=\"" << __id << "\\nUNK\"];\n"
- << __id << " -> " << _M_next << " [label=\"?\"];\n";
- break;
- }
- return __ostr;
-}
-
-inline std::ostream& _Nfa::
-_M_dot(std::ostream& __ostr) const
-{
- __ostr << "digraph _Nfa {\n"
- << " rankdir=LR;\n";
- for (unsigned int __i = 0; __i < this->size(); ++__i)
- { this->at(__i)._M_dot(__ostr, __i); }
- __ostr << "}\n";
- return __ostr;
-}
-#endif
-
-inline _StateSeq& _StateSeq::
-operator=(const _StateSeq& __rhs)
-{
- _M_start = __rhs._M_start;
- _M_end1 = __rhs._M_end1;
- _M_end2 = __rhs._M_end2;
- return *this;
-}
-
-inline void _StateSeq::
-_M_push_back(_StateIdT __id)
-{
- if (_M_end1 != _S_invalid_state_id)
- _M_nfa[_M_end1]._M_next = __id;
- _M_end1 = __id;
-}
-
-inline void _StateSeq::
-_M_append(_StateIdT __id)
-{
- if (_M_end2 != _S_invalid_state_id)
- {
- if (_M_end2 == _M_end1)
- _M_nfa[_M_end2]._M_alt = __id;
- else
- _M_nfa[_M_end2]._M_next = __id;
- _M_end2 = _S_invalid_state_id;
- }
- if (_M_end1 != _S_invalid_state_id)
- _M_nfa[_M_end1]._M_next = __id;
- _M_end1 = __id;
-}
-
-inline void _StateSeq::
-_M_append(_StateSeq& __rhs)
-{
- if (_M_end2 != _S_invalid_state_id)
- {
- if (_M_end2 == _M_end1)
- _M_nfa[_M_end2]._M_alt = __rhs._M_start;
- else
- _M_nfa[_M_end2]._M_next = __rhs._M_start;
- _M_end2 = _S_invalid_state_id;
- }
- if (__rhs._M_end2 != _S_invalid_state_id)
- _M_end2 = __rhs._M_end2;
- if (_M_end1 != _S_invalid_state_id)
- _M_nfa[_M_end1]._M_next = __rhs._M_start;
- _M_end1 = __rhs._M_end1;
-}
-
-// @todo implement this function.
-inline _StateIdT _StateSeq::
-_M_clone()
-{ return 0; }
-
-_GLIBCXX_END_NAMESPACE_VERSION
-} // namespace __detail
-} // namespace
diff --git a/libstdc++-v3/include/bits/regex_scanner.h b/libstdc++-v3/include/bits/regex_scanner.h
new file mode 100644
index 00000000000..064c1832796
--- /dev/null
+++ b/libstdc++-v3/include/bits/regex_scanner.h
@@ -0,0 +1,196 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/**
+ * @file bits/regex_scanner.h
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{regex}
+ */
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ /**
+ * @addtogroup regex-detail
+ * @{
+ */
+
+ /**
+ * @brief struct _Scanner. Scans an input range for regex tokens.
+ *
+ * The %_Scanner class interprets the regular expression pattern in
+ * the input range passed to its constructor as a sequence of parse
+ * tokens passed to the regular expression compiler. The sequence
+ * of tokens provided depends on the flag settings passed to the
+ * constructor: different regular expression grammars will interpret
+ * the same input pattern in syntactically different ways.
+ */
+ template<typename _FwdIter>
+ class _Scanner
+ {
+ public:
+ typedef typename std::iterator_traits<_FwdIter>::value_type _CharT;
+ typedef std::basic_string<_CharT> _StringT;
+ typedef regex_constants::syntax_option_type _FlagT;
+ typedef const std::ctype<_CharT> _CtypeT;
+
+ /// Token types returned from the scanner.
+ enum _TokenT
+ {
+ _S_token_anychar,
+ _S_token_ord_char,
+ _S_token_oct_num,
+ _S_token_hex_num,
+ _S_token_backref,
+ _S_token_subexpr_begin,
+ _S_token_subexpr_no_group_begin,
+ _S_token_subexpr_lookahead_begin,
+ _S_token_subexpr_neg_lookahead_begin,
+ _S_token_subexpr_end,
+ _S_token_bracket_begin,
+ _S_token_bracket_neg_begin,
+ _S_token_bracket_end,
+ _S_token_interval_begin,
+ _S_token_interval_end,
+ _S_token_quoted_class,
+ _S_token_char_class_name,
+ _S_token_collsymbol,
+ _S_token_equiv_class_name,
+ _S_token_opt,
+ _S_token_or,
+ _S_token_closure0,
+ _S_token_closure1,
+ _S_token_line_begin,
+ _S_token_line_end,
+ _S_token_word_bound,
+ _S_token_neg_word_bound,
+ _S_token_comma,
+ _S_token_dup_count,
+ _S_token_eof,
+ _S_token_unknown
+ };
+
+ _Scanner(_FwdIter __begin, _FwdIter __end,
+ _FlagT __flags, std::locale __loc);
+
+ void
+ _M_advance();
+
+ _TokenT
+ _M_get_token() const
+ { return _M_token; }
+
+ const _StringT&
+ _M_get_value() const
+ { return _M_value; }
+
+#ifdef _GLIBCXX_DEBUG
+ std::ostream&
+ _M_print(std::ostream&);
+#endif
+
+ private:
+ enum _StateT
+ {
+ _S_state_normal,
+ _S_state_in_brace,
+ _S_state_in_bracket,
+ };
+
+ void
+ _M_scan_normal();
+
+ void
+ _M_scan_in_bracket();
+
+ void
+ _M_scan_in_brace();
+
+ void
+ _M_eat_escape_ecma();
+
+ void
+ _M_eat_escape_posix();
+
+ void
+ _M_eat_escape_awk();
+
+ void
+ _M_eat_class(char);
+
+ constexpr bool
+ _M_is_ecma()
+ { return _M_flags & regex_constants::ECMAScript; }
+
+ constexpr bool
+ _M_is_basic()
+ { return _M_flags & (regex_constants::basic | regex_constants::grep); }
+
+ constexpr bool
+ _M_is_extended()
+ {
+ return _M_flags & (regex_constants::extended
+ | regex_constants::egrep
+ | regex_constants::awk);
+ }
+
+ constexpr bool
+ _M_is_grep()
+ { return _M_flags & (regex_constants::grep | regex_constants::egrep); }
+
+ constexpr bool
+ _M_is_awk()
+ { return _M_flags & regex_constants::awk; }
+
+ _StateT _M_state;
+ _FwdIter _M_current;
+ _FwdIter _M_end;
+ _FlagT _M_flags;
+ _CtypeT& _M_ctype;
+ _TokenT _M_token;
+ _StringT _M_value;
+ bool _M_at_bracket_start;
+ public:
+ // TODO: make them static when this file is stable.
+ const std::map<char, _TokenT> _M_token_map;
+ const std::map<char, char> _M_ecma_escape_map;
+ const std::map<char, char> _M_awk_escape_map;
+ const std::set<char> _M_ecma_spec_char;
+ const std::set<char> _M_basic_spec_char;
+ const std::set<char> _M_extended_spec_char;
+
+ const std::map<char, char>& _M_escape_map;
+ const std::set<char>& _M_spec_char;
+ void (_Scanner::* _M_eat_escape)();
+ };
+
+ //@} regex-detail
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace std
+
+#include <bits/regex_scanner.tcc>
diff --git a/libstdc++-v3/include/bits/regex_scanner.tcc b/libstdc++-v3/include/bits/regex_scanner.tcc
new file mode 100644
index 00000000000..3303aa56a38
--- /dev/null
+++ b/libstdc++-v3/include/bits/regex_scanner.tcc
@@ -0,0 +1,611 @@
+// class template regex -*- C++ -*-
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/**
+ * @file bits/regex_scanner.tcc
+ * This is an internal header file, included by other library headers.
+ * Do not attempt to use it directly. @headername{regex}
+ */
+
+// TODO make comments doxygen format.
+
+// N3376 specified 6 regex styles: ECMAScript, basic, extended, grep, egrep
+// and awk
+// 1) grep is basic except '\n' is treated as '|'
+// 2) egrep is extended except '\n' is treated as '|'
+// 3) awk is extended except special escaping rules, and there's no
+// back-reference.
+//
+// References:
+//
+// ECMAScript: ECMA-262 15.10
+//
+// basic, extended:
+// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap09.html
+//
+// awk: http://pubs.opengroup.org/onlinepubs/000095399/utilities/awk.html
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+namespace __detail
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+ template<typename _FwdIter>
+ _Scanner<_FwdIter>::
+ _Scanner(_FwdIter __begin, _FwdIter __end,
+ _FlagT __flags, std::locale __loc)
+ : _M_current(__begin) , _M_end(__end) , _M_flags(__flags),
+ _M_ctype(std::use_facet<_CtypeT>(__loc)), _M_state(_S_state_normal),
+ _M_at_bracket_start(false),
+ _M_token_map
+ {
+ {'^', _S_token_line_begin},
+ {'$', _S_token_line_end},
+ {'.', _S_token_anychar},
+ {'*', _S_token_closure0},
+ {'+', _S_token_closure1},
+ {'?', _S_token_opt},
+ {'|', _S_token_or},
+ // grep and egrep
+ {'\n', _S_token_or},
+ },
+ _M_ecma_escape_map
+ {
+ {'0', '\0'},
+ {'b', '\b'},
+ {'f', '\f'},
+ {'n', '\n'},
+ {'r', '\r'},
+ {'t', '\t'},
+ {'v', '\v'},
+ },
+ _M_awk_escape_map
+ {
+ {'"', '"'},
+ {'/', '/'},
+ {'\\', '\\'},
+ {'a', '\a'},
+ {'b', '\b'},
+ {'f', '\f'},
+ {'n', '\n'},
+ {'r', '\r'},
+ {'t', '\t'},
+ {'v', '\v'},
+ },
+ _M_escape_map(_M_is_ecma()
+ ? _M_ecma_escape_map
+ : _M_awk_escape_map),
+ _M_ecma_spec_char
+ {
+ '^',
+ '$',
+ '\\',
+ '.',
+ '*',
+ '+',
+ '?',
+ '(',
+ ')',
+ '[',
+ ']',
+ '{',
+ '}',
+ '|',
+ },
+ _M_basic_spec_char
+ {
+ '.',
+ '[',
+ '\\',
+ '*',
+ '^',
+ '$',
+ },
+ _M_extended_spec_char
+ {
+ '.',
+ '[',
+ '\\',
+ '(',
+ ')',
+ '*',
+ '+',
+ '?',
+ '{',
+ '|',
+ '^',
+ '$',
+ },
+ _M_eat_escape(_M_is_ecma()
+ ? &_Scanner::_M_eat_escape_ecma
+ : &_Scanner::_M_eat_escape_posix),
+ _M_spec_char(_M_is_ecma()
+ ? _M_ecma_spec_char
+ : _M_is_basic()
+ ? _M_basic_spec_char
+ : _M_extended_spec_char)
+ { _M_advance(); }
+
+ template<typename _FwdIter>
+ void
+ _Scanner<_FwdIter>::
+ _M_advance()
+ {
+ if (_M_current == _M_end)
+ {
+ _M_token = _S_token_eof;
+ return;
+ }
+
+ if (_M_state == _S_state_normal)
+ _M_scan_normal();
+ else if (_M_state == _S_state_in_bracket)
+ _M_scan_in_bracket();
+ else if (_M_state == _S_state_in_brace)
+ _M_scan_in_brace();
+ else
+ _GLIBCXX_DEBUG_ASSERT(false);
+ }
+
+ // Differences between styles:
+ // 1) "\(", "\)", "\{" in basic. It's not escaping.
+ // 2) "(?:", "(?=", "(?!" in ECMAScript.
+ template<typename _FwdIter>
+ void
+ _Scanner<_FwdIter>::
+ _M_scan_normal()
+ {
+ auto __c = *_M_current++;
+
+ if (__c == '\\')
+ {
+ if (_M_current == _M_end)
+ __throw_regex_error(regex_constants::error_escape);
+
+ if (!_M_is_basic()
+ || (*_M_current != '('
+ && *_M_current != ')'
+ && *_M_current != '{'))
+ {
+ (this->*_M_eat_escape)();
+ return;
+ }
+ __c = *_M_current++;
+ }
+ if (__c == '(')
+ {
+ if (_M_is_ecma() && *_M_current == '?')
+ {
+ if (++_M_current == _M_end)
+ __throw_regex_error(regex_constants::error_paren);
+
+ if (*_M_current == ':')
+ {
+ ++_M_current;
+ _M_token = _S_token_subexpr_no_group_begin;
+ }
+ else if (*_M_current == '=')
+ {
+ ++_M_current;
+ _M_token = _S_token_subexpr_lookahead_begin;
+ }
+ else if (*_M_current == '!')
+ {
+ ++_M_current;
+ _M_token = _S_token_subexpr_neg_lookahead_begin;
+ }
+ else
+ __throw_regex_error(regex_constants::error_paren);
+ }
+ else
+ _M_token = _S_token_subexpr_begin;
+ }
+ else if (__c == ')')
+ _M_token = _S_token_subexpr_end;
+ else if (__c == '[')
+ {
+ _M_state = _S_state_in_bracket;
+ _M_at_bracket_start = true;
+ if (_M_current != _M_end && *_M_current == '^')
+ {
+ _M_token = _S_token_bracket_neg_begin;
+ ++_M_current;
+ }
+ else
+ _M_token = _S_token_bracket_begin;
+ }
+ else if (__c == '{')
+ {
+ _M_state = _S_state_in_brace;
+ _M_token = _S_token_interval_begin;
+ }
+ else if (_M_spec_char.count(__c)
+ && __c != ']'
+ && __c != '}'
+ || (_M_is_grep() && __c == '\n'))
+ _M_token = _M_token_map.at(__c);
+ else
+ {
+ _M_token = _S_token_ord_char;
+ _M_value.assign(1, __c);
+ }
+ }
+
+ // Differences between styles:
+ // 1) different semantics of "[]" and "[^]".
+ // 2) Escaping in bracket expr.
+ template<typename _FwdIter>
+ void
+ _Scanner<_FwdIter>::
+ _M_scan_in_bracket()
+ {
+ if (_M_current == _M_end)
+ __throw_regex_error(regex_constants::error_brack);
+
+ auto __c = *_M_current++;
+
+ if (__c == '[')
+ {
+ if (_M_current == _M_end)
+ __throw_regex_error(regex_constants::error_brack);
+
+ if (*_M_current == '.')
+ {
+ _M_token = _S_token_collsymbol;
+ _M_eat_class(*_M_current++);
+ }
+ else if (*_M_current == ':')
+ {
+ _M_token = _S_token_char_class_name;
+ _M_eat_class(*_M_current++);
+ }
+ else if (*_M_current == '=')
+ {
+ _M_token = _S_token_equiv_class_name;
+ _M_eat_class(*_M_current++);
+ }
+ else
+ {
+ _M_token = _S_token_ord_char;
+ _M_value.assign(1, __c);
+ }
+ }
+ // In POSIX, when encountering "[]" or "[^]", the ']' is interpreted
+ // literally. So "[]]" or "[^]]" is valid regex. See the testcases
+ // `*/empty_range.cc`.
+ else if (__c == ']' && (_M_is_ecma() || !_M_at_bracket_start))
+ {
+ _M_token = _S_token_bracket_end;
+ _M_state = _S_state_normal;
+ }
+ // ECMAScirpt and awk permmits escaping in bracket.
+ else if (__c == '\\' && (_M_is_ecma() || _M_is_awk()))
+ (this->*_M_eat_escape)();
+ else
+ {
+ _M_token = _S_token_ord_char;
+ _M_value.assign(1, __c);
+ }
+ _M_at_bracket_start = false;
+ }
+
+ // Differences between styles:
+ // 1) "\}" in basic style.
+ template<typename _FwdIter>
+ void
+ _Scanner<_FwdIter>::
+ _M_scan_in_brace()
+ {
+ if (_M_current == _M_end)
+ __throw_regex_error(regex_constants::error_brace);
+
+ auto __c = *_M_current++;
+
+ if (_M_ctype.is(_CtypeT::digit, __c))
+ {
+ _M_token = _S_token_dup_count;
+ _M_value.assign(1, __c);
+ while (_M_current != _M_end
+ && _M_ctype.is(_CtypeT::digit, *_M_current))
+ _M_value += *_M_current++;
+ }
+ else if (__c == ',')
+ _M_token = _S_token_comma;
+ // basic use \}.
+ else if (_M_is_basic())
+ {
+ if (__c == '\\' && _M_current != _M_end && *_M_current == '}')
+ {
+ _M_state = _S_state_normal;
+ _M_token = _S_token_interval_end;
+ ++_M_current;
+ }
+ else
+ __throw_regex_error(regex_constants::error_brace);
+ }
+ else if (__c == '}')
+ {
+ _M_state = _S_state_normal;
+ _M_token = _S_token_interval_end;
+ }
+ else
+ __throw_regex_error(regex_constants::error_brace);
+ }
+
+ template<typename _FwdIter>
+ void
+ _Scanner<_FwdIter>::
+ _M_eat_escape_ecma()
+ {
+ if (_M_current == _M_end)
+ __throw_regex_error(regex_constants::error_escape);
+
+ auto __c = *_M_current++;
+
+ if (_M_escape_map.count(__c)
+ && (__c != 'b' || _M_state == _S_state_in_bracket))
+ {
+ _M_token = _S_token_ord_char;
+ _M_value.assign(1, _M_escape_map.at(__c));
+ }
+ else if (__c == 'b')
+ _M_token = _S_token_word_bound;
+ else if (__c == 'B')
+ _M_token = _S_token_neg_word_bound;
+ // N3376 28.13
+ else if (__c == 'd'
+ || __c == 'D'
+ || __c == 's'
+ || __c == 'S'
+ || __c == 'w'
+ || __c == 'W')
+ {
+ _M_token = _S_token_quoted_class;
+ _M_value.assign(1, __c);
+ }
+ else if (__c == 'c')
+ {
+ if (_M_current == _M_end)
+ __throw_regex_error(regex_constants::error_escape);
+ _M_token = _S_token_ord_char;
+ _M_value.assign(1, *_M_current++);
+ }
+ else if (__c == 'x' || __c == 'u')
+ {
+ _M_value.erase();
+ for (int i = 0; i < (__c == 'x' ? 2 : 4); i++)
+ {
+ if (_M_current == _M_end
+ || !_M_ctype.is(_CtypeT::xdigit, *_M_current))
+ __throw_regex_error(regex_constants::error_escape);
+ _M_value += *_M_current++;
+ }
+ _M_token = _S_token_hex_num;
+ }
+ // ECMAScript recongnizes multi-digit back-references.
+ else if (_M_ctype.is(_CtypeT::digit, __c))
+ {
+ _M_value.assign(1, __c);
+ while (_M_current != _M_end
+ && _M_ctype.is(_CtypeT::digit, *_M_current))
+ _M_value += *_M_current++;
+ _M_token = _S_token_backref;
+ }
+ else
+ {
+ _M_token = _S_token_ord_char;
+ _M_value.assign(1, __c);
+ }
+ }
+
+ template<typename _FwdIter>
+ void
+ _Scanner<_FwdIter>::
+ _M_eat_escape_posix()
+ {
+ if (_M_current == _M_end)
+ __throw_regex_error(regex_constants::error_escape);
+
+ auto __c = *_M_current;
+
+ if (_M_spec_char.count(__c))
+ {
+ _M_token = _S_token_ord_char;
+ _M_value.assign(1, __c);
+ }
+ // We MUST judge awk before handling backrefs. There's no backref in awk.
+ else if (_M_is_awk())
+ {
+ _M_eat_escape_awk();
+ return;
+ }
+ else if (_M_ctype.is(_CtypeT::digit, __c) && __c != '0')
+ {
+ _M_token = _S_token_backref;
+ _M_value.assign(1, __c);
+ }
+ else
+ __throw_regex_error(regex_constants::error_escape);
+ ++_M_current;
+ }
+
+ template<typename _FwdIter>
+ void
+ _Scanner<_FwdIter>::
+ _M_eat_escape_awk()
+ {
+ auto __c = *_M_current++;
+
+ if (_M_escape_map.count(__c))
+ {
+ _M_token = _S_token_ord_char;
+ _M_value.assign(1, _M_escape_map.at(__c));
+ }
+ // \ddd for oct representation
+ else if (_M_ctype.is(_CtypeT::digit, __c)
+ && __c != '8'
+ && __c != '9')
+ {
+ _M_value.assign(1, __c);
+ for (int __i = 0;
+ __i < 2
+ && _M_current != _M_end
+ && _M_ctype.is(_CtypeT::digit, *_M_current)
+ && *_M_current != '8'
+ && *_M_current != '9';
+ __i++)
+ _M_value += *_M_current++;
+ _M_token = _S_token_oct_num;
+ return;
+ }
+ else
+ __throw_regex_error(regex_constants::error_escape);
+ }
+
+ // Eats a character class or throwns an exception.
+ // __ch cound be ':', '.' or '=', _M_current is the char after ']' when
+ // returning.
+ template<typename _FwdIter>
+ void
+ _Scanner<_FwdIter>::
+ _M_eat_class(char __ch)
+ {
+ for (_M_value.clear(); _M_current != _M_end && *_M_current != __ch;)
+ _M_value += *_M_current++;
+ if (_M_current == _M_end
+ || *_M_current++ != __ch
+ || _M_current == _M_end // skip __ch
+ || *_M_current++ != ']') // skip ']'
+ if (__ch == ':')
+ __throw_regex_error(regex_constants::error_ctype);
+ else
+ __throw_regex_error(regex_constants::error_collate);
+ }
+
+#ifdef _GLIBCXX_DEBUG
+ template<typename _FwdIter>
+ std::ostream&
+ _Scanner<_FwdIter>::
+ _M_print(std::ostream& ostr)
+ {
+ switch (_M_token)
+ {
+ case _S_token_anychar:
+ ostr << "any-character\n";
+ break;
+ case _S_token_backref:
+ ostr << "backref\n";
+ break;
+ case _S_token_bracket_begin:
+ ostr << "bracket-begin\n";
+ break;
+ case _S_token_bracket_neg_begin:
+ ostr << "bracket-neg-begin\n";
+ break;
+ case _S_token_bracket_end:
+ ostr << "bracket-end\n";
+ break;
+ case _S_token_char_class_name:
+ ostr << "char-class-name \"" << _M_value << "\"\n";
+ break;
+ case _S_token_closure0:
+ ostr << "closure0\n";
+ break;
+ case _S_token_closure1:
+ ostr << "closure1\n";
+ break;
+ case _S_token_collsymbol:
+ ostr << "collsymbol \"" << _M_value << "\"\n";
+ break;
+ case _S_token_comma:
+ ostr << "comma\n";
+ break;
+ case _S_token_dup_count:
+ ostr << "dup count: " << _M_value << "\n";
+ break;
+ case _S_token_eof:
+ ostr << "EOF\n";
+ break;
+ case _S_token_equiv_class_name:
+ ostr << "equiv-class-name \"" << _M_value << "\"\n";
+ break;
+ case _S_token_interval_begin:
+ ostr << "interval begin\n";
+ break;
+ case _S_token_interval_end:
+ ostr << "interval end\n";
+ break;
+ case _S_token_line_begin:
+ ostr << "line begin\n";
+ break;
+ case _S_token_line_end:
+ ostr << "line end\n";
+ break;
+ case _S_token_opt:
+ ostr << "opt\n";
+ break;
+ case _S_token_or:
+ ostr << "or\n";
+ break;
+ case _S_token_ord_char:
+ ostr << "ordinary character: \"" << _M_value << "\"\n";
+ break;
+ case _S_token_subexpr_begin:
+ ostr << "subexpr begin\n";
+ break;
+ case _S_token_subexpr_no_group_begin:
+ ostr << "no grouping subexpr begin\n";
+ break;
+ case _S_token_subexpr_lookahead_begin:
+ ostr << "lookahead subexpr begin\n";
+ break;
+ case _S_token_subexpr_neg_lookahead_begin:
+ ostr << "neg lookahead subexpr begin\n";
+ break;
+ case _S_token_subexpr_end:
+ ostr << "subexpr end\n";
+ break;
+ case _S_token_unknown:
+ ostr << "-- unknown token --\n";
+ break;
+ case _S_token_oct_num:
+ ostr << "oct number " << _M_value << "\n";
+ break;
+ case _S_token_hex_num:
+ ostr << "hex number " << _M_value << "\n";
+ break;
+ case _S_token_quoted_class:
+ ostr << "quoted class " << "\\" << _M_value << "\n";
+ break;
+ default:
+ _GLIBCXX_DEBUG_ASSERT(false);
+ }
+ return ostr;
+ }
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace __detail
+} // namespace
diff --git a/libstdc++-v3/include/bits/stl_algobase.h b/libstdc++-v3/include/bits/stl_algobase.h
index e1daac2ddda..1c889356460 100644
--- a/libstdc++-v3/include/bits/stl_algobase.h
+++ b/libstdc++-v3/include/bits/stl_algobase.h
@@ -611,7 +611,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
* loop count will be known (and therefore a candidate for compiler
* optimizations such as unrolling).
*
- * Result may not be in the range [first,last). Use copy instead. Note
+ * Result may not be in the range (first,last]. Use copy instead. Note
* that the start of the output range may overlap [first,last).
*/
template<typename _BI1, typename _BI2>
diff --git a/libstdc++-v3/include/bits/stl_bvector.h b/libstdc++-v3/include/bits/stl_bvector.h
index 887ea16ae55..468fad0dbd0 100644
--- a/libstdc++-v3/include/bits/stl_bvector.h
+++ b/libstdc++-v3/include/bits/stl_bvector.h
@@ -528,7 +528,7 @@ template<typename _Alloc>
typedef _Bvector_base<_Alloc> _Base;
#if __cplusplus >= 201103L
- template<typename> friend class hash;
+ template<typename> friend struct hash;
#endif
public:
diff --git a/libstdc++-v3/include/debug/formatter.h b/libstdc++-v3/include/debug/formatter.h
index 4c65e1ac4da..15dd8d73797 100644
--- a/libstdc++-v3/include/debug/formatter.h
+++ b/libstdc++-v3/include/debug/formatter.h
@@ -114,7 +114,9 @@ namespace __gnu_debug
// unordered container buckets
__msg_bucket_index_oob,
__msg_valid_load_factor,
- __msg_equal_allocs
+ // others
+ __msg_equal_allocs,
+ __msg_insert_range_from_self
};
class _Error_formatter
diff --git a/libstdc++-v3/include/debug/forward_list b/libstdc++-v3/include/debug/forward_list
index 90a2e9c3e65..4c8ac371c94 100644
--- a/libstdc++-v3/include/debug/forward_list
+++ b/libstdc++-v3/include/debug/forward_list
@@ -796,6 +796,13 @@ namespace __gnu_debug
_S_Is_Beginnest(_BaseIt __it, const _Sequence* __seq)
{ return _S_Is(__it, __seq); }
};
+
+#ifndef _GLIBCXX_DEBUG_PEDANTIC
+ template<class _Tp, class _Alloc>
+ struct _Insert_range_from_self_is_safe<
+ std::__debug::forward_list<_Tp, _Alloc> >
+ { enum { __value = 1 }; };
+#endif
}
#endif
diff --git a/libstdc++-v3/include/debug/functions.h b/libstdc++-v3/include/debug/functions.h
index 3f16098185c..8e76b7f2ee5 100644
--- a/libstdc++-v3/include/debug/functions.h
+++ b/libstdc++-v3/include/debug/functions.h
@@ -32,7 +32,12 @@
#include <bits/c++config.h>
#include <bits/stl_iterator_base_types.h> // for iterator_traits, categories and
// _Iter_base
-#include <bits/cpp_type_traits.h> // for __is_integer
+#include <bits/cpp_type_traits.h> // for __is_integer
+#include <bits/move.h> // for __addressof and addressof
+#if __cplusplus >= 201103L
+# include <bits/stl_function.h> // for less and greater_equal
+# include <type_traits> // for is_lvalue_reference and __and_
+#endif
#include <debug/formatter.h>
namespace __gnu_debug
@@ -40,6 +45,10 @@ namespace __gnu_debug
template<typename _Iterator, typename _Sequence>
class _Safe_iterator;
+ template<typename _Sequence>
+ struct _Insert_range_from_self_is_safe
+ { enum { __value = 0 }; };
+
// An arbitrary iterator pointer is not singular.
inline bool
__check_singular_aux(const void*) { return false; }
@@ -118,8 +127,8 @@ namespace __gnu_debug
inline bool
__valid_range_aux(const _InputIterator& __first,
const _InputIterator& __last, std::__false_type)
- { return __valid_range_aux2(__first, __last,
- std::__iterator_category(__first)); }
+ { return __valid_range_aux2(__first, __last,
+ std::__iterator_category(__first)); }
/** Don't know what these iterators are, or if they are even
* iterators (we may get an integral type for InputIterator), so
@@ -162,6 +171,125 @@ namespace __gnu_debug
return __first;
}
+#if __cplusplus >= 201103L
+ // Default implementation.
+ template<typename _Iterator, typename _Sequence>
+ inline bool
+ __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ typename _Sequence::const_pointer __begin,
+ typename _Sequence::const_pointer __other)
+ {
+ typedef typename _Sequence::const_pointer _PointerType;
+ constexpr std::less<_PointerType> __l{};
+
+ return (__l(__other, __begin)
+ || __l(std::addressof(*(__it._M_get_sequence()->_M_base().end()
+ - 1)), __other));
+ }
+
+ // Fallback when address type cannot be implicitely casted to sequence
+ // const_pointer.
+ template<typename _Iterator, typename _Sequence,
+ typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux4(const _Safe_iterator<_Iterator, _Sequence>&,
+ _InputIterator, ...)
+ { return true; }
+
+ template<typename _Iterator, typename _Sequence, typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ std::true_type)
+ {
+ // Only containers with all elements in contiguous memory can have their
+ // elements passed through pointers.
+ // Arithmetics is here just to make sure we are not dereferencing
+ // past-the-end iterator.
+ if (__it._M_get_sequence()->_M_base().begin()
+ != __it._M_get_sequence()->_M_base().end())
+ if (std::addressof(*(__it._M_get_sequence()->_M_base().end() - 1))
+ - std::addressof(*(__it._M_get_sequence()->_M_base().begin()))
+ == __it._M_get_sequence()->size() - 1)
+ return (__foreign_iterator_aux4
+ (__it,
+ std::addressof(*(__it._M_get_sequence()->_M_base().begin())),
+ std::addressof(*__other)));
+ return true;
+ }
+
+ /* Fallback overload for which we can't say, assume it is valid. */
+ template<typename _Iterator, typename _Sequence, typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux3(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ std::false_type)
+ { return true; }
+#endif
+
+ /** Checks that iterators do not belong to the same sequence. */
+ template<typename _Iterator, typename _Sequence, typename _OtherIterator>
+ inline bool
+ __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ const _Safe_iterator<_OtherIterator, _Sequence>& __other,
+ std::input_iterator_tag)
+ { return __it._M_get_sequence() != __other._M_get_sequence(); }
+
+#if __cplusplus >= 201103L
+ /* This overload detects when passing pointers to the contained elements
+ rather than using iterators.
+ */
+ template<typename _Iterator, typename _Sequence, typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ std::random_access_iterator_tag)
+ {
+ typedef typename _Sequence::const_iterator _ItType;
+ typedef typename std::iterator_traits<_ItType>::reference _Ref;
+ return __foreign_iterator_aux3(__it, __other,
+ std::is_lvalue_reference<_Ref>());
+ }
+#endif
+
+ /* Fallback overload for which we can't say, assume it is valid. */
+ template<typename _Iterator, typename _Sequence, typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux2(const _Safe_iterator<_Iterator, _Sequence>&,
+ _InputIterator,
+ std::input_iterator_tag)
+ { return true; }
+
+ template<typename _Iterator, typename _Sequence,
+ typename _Integral>
+ inline bool
+ __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _Integral __other,
+ std::__true_type)
+ { return true; }
+
+ template<typename _Iterator, typename _Sequence,
+ typename _InputIterator>
+ inline bool
+ __foreign_iterator_aux(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other,
+ std::__false_type)
+ {
+ return (_Insert_range_from_self_is_safe<_Sequence>::__value
+ || __foreign_iterator_aux2(__it, __other,
+ std::__iterator_category(__it)));
+ }
+
+ template<typename _Iterator, typename _Sequence,
+ typename _InputIterator>
+ inline bool
+ __foreign_iterator(const _Safe_iterator<_Iterator, _Sequence>& __it,
+ _InputIterator __other)
+ {
+ typedef typename std::__is_integer<_InputIterator>::__type _Integral;
+ return __foreign_iterator_aux(__it, __other, _Integral());
+ }
+
/** Checks that __s is non-NULL or __n == 0, and then returns __s. */
template<typename _CharT, typename _Integer>
inline const _CharT*
@@ -211,15 +339,6 @@ namespace __gnu_debug
return true;
}
- // For performance reason, as the iterator range has been validated, check on
- // random access safe iterators is done using the base iterator.
- template<typename _Iterator, typename _Sequence>
- inline bool
- __check_sorted_aux(const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
- std::random_access_iterator_tag __tag)
- { return __check_sorted_aux(__first.base(), __last.base(), __tag); }
-
// Can't check if an input iterator sequence is sorted, because we can't step
// through the sequence.
template<typename _InputIterator, typename _Predicate>
@@ -246,17 +365,6 @@ namespace __gnu_debug
return true;
}
- // For performance reason, as the iterator range has been validated, check on
- // random access safe iterators is done using the base iterator.
- template<typename _Iterator, typename _Sequence,
- typename _Predicate>
- inline bool
- __check_sorted_aux(const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
- _Predicate __pred,
- std::random_access_iterator_tag __tag)
- { return __check_sorted_aux(__first.base(), __last.base(), __pred, __tag); }
-
// Determine if a sequence is sorted.
template<typename _InputIterator>
inline bool
@@ -345,11 +453,13 @@ namespace __gnu_debug
return __check_sorted_set_aux(__first, __last, __pred, _SameType());
}
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 270. Binary search requirements overly strict
+ // Determine if a sequence is partitioned w.r.t. this element.
template<typename _ForwardIterator, typename _Tp>
inline bool
- __check_partitioned_lower_aux(_ForwardIterator __first,
- _ForwardIterator __last, const _Tp& __value,
- std::forward_iterator_tag)
+ __check_partitioned_lower(_ForwardIterator __first,
+ _ForwardIterator __last, const _Tp& __value)
{
while (__first != __last && *__first < __value)
++__first;
@@ -362,38 +472,11 @@ namespace __gnu_debug
return __first == __last;
}
- // For performance reason, as the iterator range has been validated, check on
- // random access safe iterators is done using the base iterator.
- template<typename _Iterator, typename _Sequence, typename _Tp>
- inline bool
- __check_partitioned_lower_aux(
- const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
- const _Tp& __value,
- std::random_access_iterator_tag __tag)
- {
- return __check_partitioned_lower_aux(__first.base(), __last.base(),
- __value, __tag);
- }
-
- // _GLIBCXX_RESOLVE_LIB_DEFECTS
- // 270. Binary search requirements overly strict
- // Determine if a sequence is partitioned w.r.t. this element.
template<typename _ForwardIterator, typename _Tp>
inline bool
- __check_partitioned_lower(_ForwardIterator __first,
+ __check_partitioned_upper(_ForwardIterator __first,
_ForwardIterator __last, const _Tp& __value)
{
- return __check_partitioned_lower_aux(__first, __last, __value,
- std::__iterator_category(__first));
- }
-
- template<typename _ForwardIterator, typename _Tp>
- inline bool
- __check_partitioned_upper_aux(_ForwardIterator __first,
- _ForwardIterator __last, const _Tp& __value,
- std::forward_iterator_tag)
- {
while (__first != __last && !(__value < *__first))
++__first;
if (__first != __last)
@@ -405,35 +488,12 @@ namespace __gnu_debug
return __first == __last;
}
- // For performance reason, as the iterator range has been validated, check on
- // random access safe iterators is done using the base iterator.
- template<typename _Iterator, typename _Sequence, typename _Tp>
- inline bool
- __check_partitioned_upper_aux(
- const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
- const _Tp& __value,
- std::random_access_iterator_tag __tag)
- {
- return __check_partitioned_upper_aux(__first.base(), __last.base(),
- __value, __tag);
- }
-
- template<typename _ForwardIterator, typename _Tp>
- inline bool
- __check_partitioned_upper(_ForwardIterator __first,
- _ForwardIterator __last, const _Tp& __value)
- {
- return __check_partitioned_upper_aux(__first, __last, __value,
- std::__iterator_category(__first));
- }
-
+ // Determine if a sequence is partitioned w.r.t. this element.
template<typename _ForwardIterator, typename _Tp, typename _Pred>
inline bool
- __check_partitioned_lower_aux(_ForwardIterator __first,
- _ForwardIterator __last, const _Tp& __value,
- _Pred __pred,
- std::forward_iterator_tag)
+ __check_partitioned_lower(_ForwardIterator __first,
+ _ForwardIterator __last, const _Tp& __value,
+ _Pred __pred)
{
while (__first != __last && bool(__pred(*__first, __value)))
++__first;
@@ -446,39 +506,12 @@ namespace __gnu_debug
return __first == __last;
}
- // For performance reason, as the iterator range has been validated, check on
- // random access safe iterators is done using the base iterator.
- template<typename _Iterator, typename _Sequence,
- typename _Tp, typename _Pred>
- inline bool
- __check_partitioned_lower_aux(
- const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
- const _Tp& __value, _Pred __pred,
- std::random_access_iterator_tag __tag)
- {
- return __check_partitioned_lower_aux(__first.base(), __last.base(),
- __value, __pred, __tag);
- }
-
- // Determine if a sequence is partitioned w.r.t. this element.
template<typename _ForwardIterator, typename _Tp, typename _Pred>
inline bool
- __check_partitioned_lower(_ForwardIterator __first,
+ __check_partitioned_upper(_ForwardIterator __first,
_ForwardIterator __last, const _Tp& __value,
_Pred __pred)
{
- return __check_partitioned_lower_aux(__first, __last, __value, __pred,
- std::__iterator_category(__first));
- }
-
- template<typename _ForwardIterator, typename _Tp, typename _Pred>
- inline bool
- __check_partitioned_upper_aux(_ForwardIterator __first,
- _ForwardIterator __last, const _Tp& __value,
- _Pred __pred,
- std::forward_iterator_tag)
- {
while (__first != __last && !bool(__pred(__value, *__first)))
++__first;
if (__first != __last)
@@ -490,31 +523,6 @@ namespace __gnu_debug
return __first == __last;
}
- // For performance reason, as the iterator range has been validated, check on
- // random access safe iterators is done using the base iterator.
- template<typename _Iterator, typename _Sequence,
- typename _Tp, typename _Pred>
- inline bool
- __check_partitioned_upper_aux(
- const _Safe_iterator<_Iterator, _Sequence>& __first,
- const _Safe_iterator<_Iterator, _Sequence>& __last,
- const _Tp& __value, _Pred __pred,
- std::random_access_iterator_tag __tag)
- {
- return __check_partitioned_upper_aux(__first.base(), __last.base(),
- __value, __pred, __tag);
- }
-
- template<typename _ForwardIterator, typename _Tp, typename _Pred>
- inline bool
- __check_partitioned_upper(_ForwardIterator __first,
- _ForwardIterator __last, const _Tp& __value,
- _Pred __pred)
- {
- return __check_partitioned_upper_aux(__first, __last, __value, __pred,
- std::__iterator_category(__first));
- }
-
// Helper struct to detect random access safe iterators.
template<typename _Iterator>
struct __is_safe_random_iterator
diff --git a/libstdc++-v3/include/debug/list b/libstdc++-v3/include/debug/list
index 1ae8507ca86..fd00b0148a9 100644
--- a/libstdc++-v3/include/debug/list
+++ b/libstdc++-v3/include/debug/list
@@ -791,4 +791,13 @@ namespace __debug
} // namespace __debug
} // namespace std
+#ifndef _GLIBCXX_DEBUG_PEDANTIC
+namespace __gnu_debug
+{
+ template<class _Tp, class _Alloc>
+ struct _Insert_range_from_self_is_safe<std::__debug::list<_Tp, _Alloc> >
+ { enum { __value = 1 }; };
+}
+#endif
+
#endif
diff --git a/libstdc++-v3/include/debug/macros.h b/libstdc++-v3/include/debug/macros.h
index 26732c9e3e2..1e160c26c0f 100644
--- a/libstdc++-v3/include/debug/macros.h
+++ b/libstdc++-v3/include/debug/macros.h
@@ -72,11 +72,11 @@ _GLIBCXX_DEBUG_VERIFY(_First != _Last, \
*/
#define __glibcxx_check_insert(_Position) \
_GLIBCXX_DEBUG_VERIFY(!_Position._M_singular(), \
- _M_message(__gnu_debug::__msg_insert_singular) \
+ _M_message(__gnu_debug::__msg_insert_singular) \
._M_sequence(*this, "this") \
._M_iterator(_Position, #_Position)); \
_GLIBCXX_DEBUG_VERIFY(_Position._M_attached_to(this), \
- _M_message(__gnu_debug::__msg_insert_different) \
+ _M_message(__gnu_debug::__msg_insert_different) \
._M_sequence(*this, "this") \
._M_iterator(_Position, #_Position))
@@ -101,15 +101,16 @@ _GLIBCXX_DEBUG_VERIFY(!_Position._M_is_end(), \
* that it reference the sequence we are inserting into, and that the
* iterator range [_First, Last) is a valid (possibly empty)
* range. Note that this macro is only valid when the container is a
- * _Safe_sequence and the iterator is a _Safe_iterator.
- *
- * @todo We would like to be able to check for noninterference of
- * _Position and the range [_First, _Last), but that can't (in
- * general) be done.
+ * _Safe_sequence and the _Position iterator is a _Safe_iterator.
*/
#define __glibcxx_check_insert_range(_Position,_First,_Last) \
__glibcxx_check_valid_range(_First,_Last); \
-__glibcxx_check_insert(_Position)
+__glibcxx_check_insert(_Position); \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First),\
+ _M_message(__gnu_debug::__msg_insert_range_from_self)\
+ ._M_iterator(_First, #_First) \
+ ._M_iterator(_Last, #_Last) \
+ ._M_sequence(*this, "this"))
/** Verify that we can insert the values in the iterator range
* [_First, _Last) into *this after the iterator _Position. Insertion
@@ -126,7 +127,12 @@ __glibcxx_check_insert(_Position)
*/
#define __glibcxx_check_insert_range_after(_Position,_First,_Last) \
__glibcxx_check_valid_range(_First,_Last); \
-__glibcxx_check_insert_after(_Position)
+__glibcxx_check_insert_after(_Position); \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__foreign_iterator(_Position,_First),\
+ _M_message(__gnu_debug::__msg_insert_range_from_self)\
+ ._M_iterator(_First, #_First) \
+ ._M_iterator(_Last, #_Last) \
+ ._M_sequence(*this, "this"))
/** Verify that we can erase the element referenced by the iterator
* _Position. We can erase the element if the _Position iterator is
@@ -223,7 +229,9 @@ _GLIBCXX_DEBUG_VERIFY(! this->empty(), \
// Verify that the iterator range [_First, _Last) is sorted
#define __glibcxx_check_sorted(_First,_Last) \
__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last), \
+ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted( \
+ __gnu_debug::__base(_First), \
+ __gnu_debug::__base(_Last)), \
_M_message(__gnu_debug::__msg_unsorted) \
._M_iterator(_First, #_First) \
._M_iterator(_Last, #_Last))
@@ -232,7 +240,9 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last), \
predicate _Pred. */
#define __glibcxx_check_sorted_pred(_First,_Last,_Pred) \
__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last, _Pred), \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted( \
+ __gnu_debug::__base(_First), \
+ __gnu_debug::__base(_Last), _Pred), \
_M_message(__gnu_debug::__msg_unsorted_pred) \
._M_iterator(_First, #_First) \
._M_iterator(_Last, #_Last) \
@@ -242,7 +252,8 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_sorted(_First, _Last, _Pred), \
#define __glibcxx_check_sorted_set(_First1,_Last1,_First2) \
__glibcxx_check_valid_range(_First1,_Last1); \
_GLIBCXX_DEBUG_VERIFY( \
- __gnu_debug::__check_sorted_set(_First1, _Last1, _First2), \
+ __gnu_debug::__check_sorted_set(__gnu_debug::__base(_First1), \
+ __gnu_debug::__base(_Last1), _First2),\
_M_message(__gnu_debug::__msg_unsorted) \
._M_iterator(_First1, #_First1) \
._M_iterator(_Last1, #_Last1))
@@ -251,7 +262,9 @@ _GLIBCXX_DEBUG_VERIFY( \
#define __glibcxx_check_sorted_set_pred(_First1,_Last1,_First2,_Pred) \
__glibcxx_check_valid_range(_First1,_Last1); \
_GLIBCXX_DEBUG_VERIFY( \
- __gnu_debug::__check_sorted_set(_First1, _Last1, _First2, _Pred), \
+ __gnu_debug::__check_sorted_set(__gnu_debug::__base(_First1), \
+ __gnu_debug::__base(_Last1), \
+ _First2, _Pred), \
_M_message(__gnu_debug::__msg_unsorted_pred) \
._M_iterator(_First1, #_First1) \
._M_iterator(_Last1, #_Last1) \
@@ -261,8 +274,9 @@ _GLIBCXX_DEBUG_VERIFY( \
w.r.t. the value _Value. */
#define __glibcxx_check_partitioned_lower(_First,_Last,_Value) \
__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
- _Value), \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower( \
+ __gnu_debug::__base(_First), \
+ __gnu_debug::__base(_Last), _Value), \
_M_message(__gnu_debug::__msg_unpartitioned) \
._M_iterator(_First, #_First) \
._M_iterator(_Last, #_Last) \
@@ -270,8 +284,9 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
#define __glibcxx_check_partitioned_upper(_First,_Last,_Value) \
__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
- _Value), \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper( \
+ __gnu_debug::__base(_First), \
+ __gnu_debug::__base(_Last), _Value), \
_M_message(__gnu_debug::__msg_unpartitioned) \
._M_iterator(_First, #_First) \
._M_iterator(_Last, #_Last) \
@@ -281,8 +296,9 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
w.r.t. the value _Value and predicate _Pred. */
#define __glibcxx_check_partitioned_lower_pred(_First,_Last,_Value,_Pred) \
__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
- _Value, _Pred), \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower( \
+ __gnu_debug::__base(_First), \
+ __gnu_debug::__base(_Last), _Value, _Pred), \
_M_message(__gnu_debug::__msg_unpartitioned_pred) \
._M_iterator(_First, #_First) \
._M_iterator(_Last, #_Last) \
@@ -293,8 +309,9 @@ _GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_lower(_First, _Last, \
w.r.t. the value _Value and predicate _Pred. */
#define __glibcxx_check_partitioned_upper_pred(_First,_Last,_Value,_Pred) \
__glibcxx_check_valid_range(_First,_Last); \
-_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper(_First, _Last, \
- _Value, _Pred), \
+_GLIBCXX_DEBUG_VERIFY(__gnu_debug::__check_partitioned_upper( \
+ __gnu_debug::__base(_First), \
+ __gnu_debug::__base(_Last), _Value, _Pred), \
_M_message(__gnu_debug::__msg_unpartitioned_pred) \
._M_iterator(_First, #_First) \
._M_iterator(_Last, #_Last) \
@@ -332,7 +349,7 @@ _GLIBCXX_DEBUG_VERIFY(_F > 0.0f, \
_M_message(__gnu_debug::__msg_valid_load_factor) \
._M_sequence(*this, "this"))
-#define __glibcxx_check_equal_allocs(_Other) \
+#define __glibcxx_check_equal_allocs(_Other) \
_GLIBCXX_DEBUG_VERIFY(this->get_allocator() == _Other.get_allocator(), \
_M_message(__gnu_debug::__msg_equal_allocs) \
._M_sequence(*this, "this"))
diff --git a/libstdc++-v3/include/debug/safe_iterator.h b/libstdc++-v3/include/debug/safe_iterator.h
index b8a971b80e0..a1f7651b1bd 100644
--- a/libstdc++-v3/include/debug/safe_iterator.h
+++ b/libstdc++-v3/include/debug/safe_iterator.h
@@ -269,7 +269,6 @@ namespace __gnu_debug
* @brief Iterator dereference.
* @pre iterator is dereferenceable
* @todo Make this correct w.r.t. iterators that return proxies
- * @todo Use addressof() instead of & operator
*/
pointer
operator->() const
@@ -277,7 +276,7 @@ namespace __gnu_debug
_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
_M_message(__msg_bad_deref)
._M_iterator(*this, "this"));
- return &*_M_current;
+ return std::__addressof(*_M_current);
}
// ------ Input iterator requirements ------
diff --git a/libstdc++-v3/include/debug/safe_local_iterator.h b/libstdc++-v3/include/debug/safe_local_iterator.h
index 6426ed82afa..82975b70722 100644
--- a/libstdc++-v3/include/debug/safe_local_iterator.h
+++ b/libstdc++-v3/include/debug/safe_local_iterator.h
@@ -173,7 +173,6 @@ namespace __gnu_debug
* @brief Iterator dereference.
* @pre iterator is dereferenceable
* @todo Make this correct w.r.t. iterators that return proxies
- * @todo Use addressof() instead of & operator
*/
pointer
operator->() const
@@ -181,7 +180,7 @@ namespace __gnu_debug
_GLIBCXX_DEBUG_VERIFY(this->_M_dereferenceable(),
_M_message(__msg_bad_deref)
._M_iterator(*this, "this"));
- return &*_M_current;
+ return std::__addressof(*_M_current);
}
// ------ Input iterator requirements ------
diff --git a/libstdc++-v3/include/debug/string b/libstdc++-v3/include/debug/string
index 8a5bf9b0367..9e856c1ee8c 100644
--- a/libstdc++-v3/include/debug/string
+++ b/libstdc++-v3/include/debug/string
@@ -1156,6 +1156,11 @@ namespace __gnu_debug
typedef basic_string<wchar_t> wstring;
#endif
+ template<typename _CharT, typename _Traits, typename _Allocator>
+ struct _Insert_range_from_self_is_safe<
+ __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
+ { enum { __value = 1 }; };
+
} // namespace __gnu_debug
#endif
diff --git a/libstdc++-v3/include/ext/atomicity.h b/libstdc++-v3/include/ext/atomicity.h
index 6367026c0ed..a43962724a6 100644
--- a/libstdc++-v3/include/ext/atomicity.h
+++ b/libstdc++-v3/include/ext/atomicity.h
@@ -29,6 +29,8 @@
#ifndef _GLIBCXX_ATOMICITY_H
#define _GLIBCXX_ATOMICITY_H 1
+#pragma GCC system_header
+
#include <bits/c++config.h>
#include <bits/gthr.h>
#include <bits/atomic_word.h>
diff --git a/libstdc++-v3/include/ext/random b/libstdc++-v3/include/ext/random
index 5f365e65a33..347ebed449c 100644
--- a/libstdc++-v3/include/ext/random
+++ b/libstdc++-v3/include/ext/random
@@ -791,7 +791,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
result_type
min() const
{ result_type __res;
- __res.fill(std::numeric_limits<_RealType>::min());
+ __res.fill(std::numeric_limits<_RealType>::lowest());
return __res; }
/**
diff --git a/libstdc++-v3/include/ext/vstring.h b/libstdc++-v3/include/ext/vstring.h
index 43edb53b41c..85322130cf9 100644
--- a/libstdc++-v3/include/ext/vstring.h
+++ b/libstdc++-v3/include/ext/vstring.h
@@ -557,10 +557,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
reference
operator[](size_type __pos)
{
- // allow pos == size() as v3 extension:
+ // Allow pos == size() both in C++98 mode, as v3 extension,
+ // and in C++11 mode.
_GLIBCXX_DEBUG_ASSERT(__pos <= this->size());
- // but be strict in pedantic mode:
- _GLIBCXX_DEBUG_PEDASSERT(__pos < this->size());
+ // In pedantic mode be strict in C++98 mode.
+ _GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L
+ || __pos < this->size());
this->_M_leak();
return this->_M_data()[__pos];
}
diff --git a/libstdc++-v3/include/std/atomic b/libstdc++-v3/include/std/atomic
index 813f5741a10..2d66729629e 100644
--- a/libstdc++-v3/include/std/atomic
+++ b/libstdc++-v3/include/std/atomic
@@ -252,12 +252,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
compare_exchange_weak(_Tp& __e, _Tp __i,
memory_order __m = memory_order_seq_cst) noexcept
- { return compare_exchange_weak(__e, __i, __m, __m); }
+ { return compare_exchange_weak(__e, __i, __m,
+ __cmpexch_failure_order(__m)); }
bool
compare_exchange_weak(_Tp& __e, _Tp __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
- { return compare_exchange_weak(__e, __i, __m, __m); }
+ { return compare_exchange_weak(__e, __i, __m,
+ __cmpexch_failure_order(__m)); }
bool
compare_exchange_strong(_Tp& __e, _Tp __i, memory_order __s,
@@ -276,12 +278,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
bool
compare_exchange_strong(_Tp& __e, _Tp __i,
memory_order __m = memory_order_seq_cst) noexcept
- { return compare_exchange_strong(__e, __i, __m, __m); }
+ { return compare_exchange_strong(__e, __i, __m,
+ __cmpexch_failure_order(__m)); }
bool
compare_exchange_strong(_Tp& __e, _Tp __i,
memory_order __m = memory_order_seq_cst) volatile noexcept
- { return compare_exchange_strong(__e, __i, __m, __m); }
+ { return compare_exchange_strong(__e, __i, __m,
+ __cmpexch_failure_order(__m)); }
};
diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset
index 08ba2cd3857..1da6baf332f 100644
--- a/libstdc++-v3/include/std/bitset
+++ b/libstdc++-v3/include/std/bitset
@@ -760,7 +760,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
}
#if __cplusplus >= 201103L
- template<typename> friend class hash;
+ template<typename> friend struct hash;
#endif
public:
diff --git a/libstdc++-v3/include/std/regex b/libstdc++-v3/include/std/regex
index 907f5bb65d8..36dd0a97b8f 100644
--- a/libstdc++-v3/include/std/regex
+++ b/libstdc++-v3/include/std/regex
@@ -44,6 +44,8 @@
#include <iterator>
#include <locale>
#include <memory>
+#include <map>
+#include <queue>
#include <set>
#include <sstream>
#include <stack>
@@ -52,13 +54,12 @@
#include <utility>
#include <vector>
-#include <bits/range_access.h>
#include <bits/regex_constants.h>
#include <bits/regex_error.h>
-#include <bits/regex_cursor.h>
-#include <bits/regex_nfa.h>
+#include <bits/regex_scanner.h>
+#include <bits/regex_automaton.h>
#include <bits/regex_compiler.h>
-#include <bits/regex_grep_matcher.h>
+#include <bits/regex_executor.h>
#include <bits/regex.h>
#endif // C++11
diff --git a/libstdc++-v3/include/tr1/cmath b/libstdc++-v3/include/tr1/cmath
index 3658afb1d64..6e63e56b45e 100644
--- a/libstdc++-v3/include/tr1/cmath
+++ b/libstdc++-v3/include/tr1/cmath
@@ -846,10 +846,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
nexttoward(_Tp __x, long double __y)
{ return __builtin_nexttoward(__x, __y); }
- // DR 550. What should the return type of pow(float,int) be?
- // NB: C++0x and TR1 != C++03.
- // using std::pow;
-
inline float
remainder(float __x, float __y)
{ return __builtin_remainderf(__x, __y); }
@@ -985,9 +981,18 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// DR 550. What should the return type of pow(float,int) be?
// NB: C++0x and TR1 != C++03.
- inline double
- pow(double __x, double __y)
- { return std::pow(__x, __y); }
+
+ // The std::tr1::pow(double, double) overload cannot be provided
+ // here, because it would clash with ::pow(double,double) declared
+ // in <math.h>, if <tr1/math.h> is included at the same time (raised
+ // by the fix of PR c++/54537). It is not possible either to use the
+ // using-declaration 'using ::pow;' here, because if the user code
+ // has a 'using std::pow;', it would bring the pow(*,int) averloads
+ // in the tr1 namespace, which is undesirable. Consequently, the
+ // solution is to forward std::tr1::pow(double,double) to
+ // std::pow(double,double) via the templatized version below. See
+ // the discussion about this issue here:
+ // http://gcc.gnu.org/ml/gcc-patches/2012-09/msg01278.html
inline float
pow(float __x, float __y)
diff --git a/libstdc++-v3/libsupc++/Makefile.am b/libstdc++-v3/libsupc++/Makefile.am
index b4e86f53144..f0ab6026ca3 100644
--- a/libstdc++-v3/libsupc++/Makefile.am
+++ b/libstdc++-v3/libsupc++/Makefile.am
@@ -26,6 +26,7 @@ include $(top_srcdir)/fragment.am
# separately too.
# 1) separate libsupc++.la
toolexeclib_LTLIBRARIES = libsupc++.la
+
# 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a
noinst_LTLIBRARIES = libsupc++convenience.la
@@ -96,8 +97,13 @@ sources = \
vmi_class_type_info.cc \
vterminate.cc
-libsupc___la_SOURCES = $(sources) $(c_sources)
-libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
+if ENABLE_VTABLE_VERIFY
+ vtv_sources = \
+ vtv_stubs.cc
+endif
+
+libsupc___la_SOURCES = $(sources) $(c_sources) $(vtv_sources)
+libsupc__convenience_la_SOURCES = $(sources) $(c_sources) $(vtv_sources)
cp-demangle.c:
rm -f $@
@@ -282,3 +288,8 @@ uninstall-bitsHEADERS:
q=`echo $$p | sed -e 's,.*/,,'`; \
rm -f $(DESTDIR)$(bitsdir)/$$q; \
done
+
+
+# By adding these files here, automake will remove them for 'make clean'
+CLEANFILES = stamp-*
+
diff --git a/libstdc++-v3/libsupc++/Makefile.in b/libstdc++-v3/libsupc++/Makefile.in
index eb2d0bdba9f..ff5b67456dc 100644
--- a/libstdc++-v3/libsupc++/Makefile.in
+++ b/libstdc++-v3/libsupc++/Makefile.in
@@ -128,10 +128,13 @@ am__objects_1 = array_type_info.lo atexit_arm.lo atexit_thread.lo \
pointer_type_info.lo pure.lo si_class_type_info.lo tinfo.lo \
tinfo2.lo vec.lo vmi_class_type_info.lo vterminate.lo
@GLIBCXX_HOSTED_TRUE@am__objects_2 = cp-demangle.lo
-am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2)
+@ENABLE_VTABLE_VERIFY_TRUE@am__objects_3 = vtv_stubs.lo
+am_libsupc___la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3)
libsupc___la_OBJECTS = $(am_libsupc___la_OBJECTS)
libsupc__convenience_la_LIBADD =
-am_libsupc__convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2)
+am_libsupc__convenience_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
+ $(am__objects_3)
libsupc__convenience_la_OBJECTS = \
$(am_libsupc__convenience_la_OBJECTS)
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
@@ -263,6 +266,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -359,6 +365,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
@@ -376,6 +384,7 @@ AM_CPPFLAGS = $(GLIBCXX_INCLUDES)
# separately too.
# 1) separate libsupc++.la
toolexeclib_LTLIBRARIES = libsupc++.la
+
# 2) integrated libsupc++convenience.la that is to be a part of libstdc++.a
noinst_LTLIBRARIES = libsupc++convenience.la
std_HEADERS = \
@@ -442,8 +451,11 @@ sources = \
vmi_class_type_info.cc \
vterminate.cc
-libsupc___la_SOURCES = $(sources) $(c_sources)
-libsupc__convenience_la_SOURCES = $(sources) $(c_sources)
+@ENABLE_VTABLE_VERIFY_TRUE@vtv_sources = \
+@ENABLE_VTABLE_VERIFY_TRUE@ vtv_stubs.cc
+
+libsupc___la_SOURCES = $(sources) $(c_sources) $(vtv_sources)
+libsupc__convenience_la_SOURCES = $(sources) $(c_sources) $(vtv_sources)
# AM_CXXFLAGS needs to be in each subdirectory so that it can be
# modified in a per-library or per-sub-library way. Need to manually
@@ -527,6 +539,9 @@ CXXLINK = \
# prepending each of $(*_HEADERS) with VPATH below.
stddir = $(gxx_include_dir)
bitsdir = $(gxx_include_dir)/bits
+
+# By adding these files here, automake will remove them for 'make clean'
+CLEANFILES = stamp-*
all: all-am
.SUFFIXES:
@@ -718,6 +733,7 @@ install-strip:
mostlyclean-generic:
clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
diff --git a/libstdc++-v3/libsupc++/vtv_stubs.cc b/libstdc++-v3/libsupc++/vtv_stubs.cc
new file mode 100644
index 00000000000..a41d943f31f
--- /dev/null
+++ b/libstdc++-v3/libsupc++/vtv_stubs.cc
@@ -0,0 +1,100 @@
+// Copyright (C) 2012-2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+// <http://www.gnu.org/licenses/>.
+
+/* This is part of the vtable verification runtime library. For more
+ information about this feature, see the comments in libvtv/vtv_rts.cc. */
+
+/* The functions in this file are used to create the libvtv_stubs
+ library, as part of the vtable verification feature. When building
+ a binary without vtable verification, and linking it with a
+ (possibly pre-built third-party) library that was built with
+ verification, it is possible that vtable verification will fail due
+ to incomplete data (rather than due to corrupt vtable pointers). In
+ this case we need to give programmers a way of turning off the
+ vtable verification in their libraries. They can do so by linking
+ with the libvtv_stubs library, which (as you can see) will replace
+ the real verification functions with a set of functions that do
+ nothing (so no more verification failures/aborts). */
+
+#include <cstddef>
+
+// Declare as weak for libsupc++, strong definitions are in libvtv.
+#if __GXX_WEAK__
+extern "C"
+void
+__VLTChangePermission(int) __attribute__((weak));
+
+void
+__VLTRegisterSet(void**, const void*, std::size_t, std::size_t,
+ void**) __attribute__((weak));
+
+void
+__VLTRegisterPair(void**, const void*, std::size_t,
+ const void*) __attribute__((weak));
+
+const void*
+__VLTVerifyVtablePointer(void**, const void*) __attribute__((weak));
+
+void
+__VLTRegisterSetDebug(void**, const void*, std::size_t, std::size_t,
+ void**) __attribute__((weak));
+
+void
+__VLTRegisterPairDebug(void**, const void*, std::size_t, const void*,
+ const char*, const char*) __attribute__((weak));
+
+const void*
+__VLTVerifyVtablePointerDebug(void**, const void*, const char*,
+ const char*) __attribute__((weak));
+#endif
+
+// Stub definitions.
+extern "C"
+void
+__VLTChangePermission(int)
+{ }
+
+void
+__VLTRegisterSet(void**, const void*, std::size_t, std::size_t, void**)
+{ }
+
+void
+__VLTRegisterPair(void**, const void*, std::size_t, const void*)
+{ }
+
+const void*
+__VLTVerifyVtablePointer(void**, const void* vtable_ptr)
+{ return vtable_ptr; }
+
+void
+__VLTRegisterSetDebug(void**, const void*, std::size_t, std::size_t, void**)
+{ }
+
+void
+__VLTRegisterPairDebug(void**, const void*, std::size_t, const void*,
+ const char*, const char*)
+{ }
+
+const void*
+__VLTVerifyVtablePointerDebug(void**, const void* vtable_ptr, const char*,
+ const char*)
+{ return vtable_ptr; }
diff --git a/libstdc++-v3/po/Makefile.in b/libstdc++-v3/po/Makefile.in
index 7246f719fa8..e135bf8c310 100644
--- a/libstdc++-v3/po/Makefile.in
+++ b/libstdc++-v3/po/Makefile.in
@@ -197,6 +197,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -293,6 +296,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
diff --git a/libstdc++-v3/python/Makefile.in b/libstdc++-v3/python/Makefile.in
index 1915d663a23..73f3799da26 100644
--- a/libstdc++-v3/python/Makefile.in
+++ b/libstdc++-v3/python/Makefile.in
@@ -227,6 +227,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -323,6 +326,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
diff --git a/libstdc++-v3/python/libstdcxx/v6/printers.py b/libstdc++-v3/python/libstdcxx/v6/printers.py
index a3a8b1e2fd7..3465348fbe2 100644
--- a/libstdc++-v3/python/libstdcxx/v6/printers.py
+++ b/libstdc++-v3/python/libstdcxx/v6/printers.py
@@ -652,7 +652,7 @@ class Tr1HashtableIterator:
class StdHashtableIterator:
def __init__(self, hash):
- self.node = hash['_M_bbegin']['_M_node']['_M_nxt']
+ self.node = hash['_M_before_begin']['_M_nxt']
self.node_type = find_type(hash.type, '__node_type').pointer()
def __iter__(self):
@@ -786,6 +786,11 @@ class RxPrinter(object):
def invoke(self, value):
if not self.enabled:
return None
+
+ if value.type.code == gdb.TYPE_CODE_REF:
+ if hasattr(gdb.Value,"referenced_value"):
+ value = value.referenced_value()
+
return self.function(self.name, value)
# A pretty-printer that conforms to the "PrettyPrinter" protocol from
@@ -841,6 +846,11 @@ class Printer(object):
return None
basename = match.group(1)
+
+ if val.type.code == gdb.TYPE_CODE_REF:
+ if hasattr(gdb.Value,"referenced_value"):
+ val = val.referenced_value()
+
if basename in self.lookup:
return self.lookup[basename].invoke(val)
diff --git a/libstdc++-v3/scripts/testsuite_flags.in b/libstdc++-v3/scripts/testsuite_flags.in
index d7710ca70ec..cf692f8f059 100755
--- a/libstdc++-v3/scripts/testsuite_flags.in
+++ b/libstdc++-v3/scripts/testsuite_flags.in
@@ -18,8 +18,10 @@ Usage:
--build-cc
--install-cxx
--cxxflags
- --cxxpchflags
--cxxldflags
+ --cxxpchflags
+ --cxxvtvflags
+
EOF
}
@@ -56,7 +58,12 @@ case ${query} in
--cxxflags)
CXXFLAGS_default="-D_GLIBCXX_ASSERT -fmessage-length=0"
CXXFLAGS_config="@SECTION_FLAGS@ @CXXFLAGS@ @EXTRA_CXX_FLAGS@"
- echo ${CXXFLAGS_default} ${CXXFLAGS_config}
+ echo ${CXXFLAGS_default} ${CXXFLAGS_config}
+ ;;
+ --cxxvtvflags)
+ CXXFLAGS_vtv="@VTV_CXXFLAGS@"
+ LDFLAGS_vtv="@VTV_CXXLINKFLAGS@"
+ echo ${CXXFLAGS_vtv} ${LDFLAGS_vtv}
;;
--cxxparallelflags)
CXXFLAGS_parallel="-D_GLIBCXX_PARALLEL -fopenmp
diff --git a/libstdc++-v3/src/Makefile.am b/libstdc++-v3/src/Makefile.am
index 3e11aa39ba4..c3c6ab77e7a 100644
--- a/libstdc++-v3/src/Makefile.am
+++ b/libstdc++-v3/src/Makefile.am
@@ -73,7 +73,6 @@ libstdc___la_LDFLAGS = \
libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
-
# Use special rules for compatibility-ldbl.cc compilation, as we need to
# pass -mlong-double-64.
if GLIBCXX_LDBL_COMPAT
@@ -138,7 +137,7 @@ compatibility-condvar.o: compatibility-condvar.cc
# as the occasion calls for it.
AM_CXXFLAGS = \
$(glibcxx_compiler_pic_flag) \
- $(XTEMPLATE_FLAGS) \
+ $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
# Libtool notes
@@ -185,9 +184,9 @@ CXXLINK = \
$(LIBTOOL) --tag CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXX) \
+ $(VTV_CXXLINKFLAGS) \
$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
-
# Symbol versioning for shared libraries.
if ENABLE_SYMVERS
libstdc++-symbols.ver: ${glibcxx_srcdir}/$(SYMVER_FILE) \
diff --git a/libstdc++-v3/src/Makefile.in b/libstdc++-v3/src/Makefile.in
index a8c164fc37b..90db4544d04 100644
--- a/libstdc++-v3/src/Makefile.in
+++ b/libstdc++-v3/src/Makefile.in
@@ -254,6 +254,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -350,6 +353,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
@@ -431,7 +436,7 @@ libstdc___la_LINK = $(CXXLINK) $(libstdc___la_LDFLAGS)
# as the occasion calls for it.
AM_CXXFLAGS = \
$(glibcxx_compiler_pic_flag) \
- $(XTEMPLATE_FLAGS) \
+ $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
@@ -479,6 +484,7 @@ CXXLINK = \
$(LIBTOOL) --tag CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXX) \
+ $(VTV_CXXLINKFLAGS) \
$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
@ENABLE_SYMVERS_TRUE@CLEANFILES = libstdc++-symbols.ver $(version_dep)
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index e7b48acef46..58d3025f0e7 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -46,13 +46,13 @@ sources = \
thread.cc
if ENABLE_EXTERN_TEMPLATE
-XTEMPLATE_FLAGS = -fno-implicit-templates
+# XTEMPLATE_FLAGS = -fno-implicit-templates
inst_sources = \
fstream-inst.cc \
string-inst.cc \
wstring-inst.cc
else
-XTEMPLATE_FLAGS =
+# XTEMPLATE_FLAGS =
inst_sources =
endif
@@ -75,7 +75,7 @@ hashtable_c++0x.o: hashtable_c++0x.cc
AM_CXXFLAGS = \
-std=gnu++11 \
$(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
- $(XTEMPLATE_FLAGS) \
+ $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
@@ -125,4 +125,5 @@ CXXLINK = \
$(LIBTOOL) --tag CXX --tag disable-shared \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXX) \
+ $(VTV_CXXLINKFLAGS) \
$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index 4e3f5dc5535..37f96731435 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -214,6 +214,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -310,6 +313,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
@@ -344,9 +349,10 @@ sources = \
system_error.cc \
thread.cc
-@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
-@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
+# XTEMPLATE_FLAGS =
@ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources =
+
+# XTEMPLATE_FLAGS = -fno-implicit-templates
@ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
@ENABLE_EXTERN_TEMPLATE_TRUE@ fstream-inst.cc \
@ENABLE_EXTERN_TEMPLATE_TRUE@ string-inst.cc \
@@ -362,7 +368,7 @@ libc__11convenience_la_SOURCES = $(sources) $(inst_sources)
AM_CXXFLAGS = \
-std=gnu++11 \
$(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
- $(XTEMPLATE_FLAGS) \
+ $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
@@ -413,6 +419,7 @@ CXXLINK = \
$(LIBTOOL) --tag CXX --tag disable-shared \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXX) \
+ $(VTV_CXXLINKFLAGS) \
$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
all: all-am
diff --git a/libstdc++-v3/src/c++11/debug.cc b/libstdc++-v3/src/c++11/debug.cc
index 3655f392f7a..260009c1172 100644
--- a/libstdc++-v3/src/c++11/debug.cc
+++ b/libstdc++-v3/src/c++11/debug.cc
@@ -181,7 +181,8 @@ namespace __gnu_debug
"attempt to access container with out-of-bounds bucket index %2;,"
" container only holds %3; buckets",
"load factor shall be positive",
- "allocators must be equal"
+ "allocators must be equal",
+ "attempt to insert with an iterator range [%1.name;, %2.name;) from this container"
};
void
@@ -695,7 +696,7 @@ namespace __gnu_debug
}
__formatter->_M_format_word(__buf, __bufsize, "@ 0x%p\n",
- _M_variant._M_sequence._M_address);
+ _M_variant._M_iterator._M_sequence);
__formatter->_M_print_word(__buf);
}
__formatter->_M_print_word("}\n");
@@ -808,8 +809,11 @@ namespace __gnu_debug
if (__length == 0)
return;
- if ((_M_column + __length < _M_max_length)
- || (__length >= _M_max_length && _M_column == 1))
+ size_t __visual_length
+ = __word[__length - 1] == '\n' ? __length - 1 : __length;
+ if (__visual_length == 0
+ || (_M_column + __visual_length < _M_max_length)
+ || (__visual_length >= _M_max_length && _M_column == 1))
{
// If this isn't the first line, indent
if (_M_column == 1 && !_M_first_line)
@@ -823,17 +827,17 @@ namespace __gnu_debug
}
fprintf(stderr, "%s", __word);
- _M_column += __length;
if (__word[__length - 1] == '\n')
{
_M_first_line = false;
_M_column = 1;
}
+ else
+ _M_column += __length;
}
else
{
- _M_column = 1;
_M_print_word("\n");
_M_print_word(__word);
}
diff --git a/libstdc++-v3/src/c++11/functexcept.cc b/libstdc++-v3/src/c++11/functexcept.cc
index b74be7dce00..b0c1804ae04 100644
--- a/libstdc++-v3/src/c++11/functexcept.cc
+++ b/libstdc++-v3/src/c++11/functexcept.cc
@@ -30,7 +30,7 @@
#include <system_error>
#include <future>
#include <functional>
-#include <regex>
+#include <bits/regex_error.h>
#ifdef _GLIBCXX_USE_NLS
# include <libintl.h>
diff --git a/libstdc++-v3/src/c++11/hashtable_c++0x.cc b/libstdc++-v3/src/c++11/hashtable_c++0x.cc
index bddb7ff338b..e7e6b1643c2 100644
--- a/libstdc++-v3/src/c++11/hashtable_c++0x.cc
+++ b/libstdc++-v3/src/c++11/hashtable_c++0x.cc
@@ -29,6 +29,7 @@
#include <initializer_list>
#include <tuple>
#include <ext/aligned_buffer.h>
+#include <ext/alloc_traits.h>
#include <bits/hashtable_policy.h>
namespace std _GLIBCXX_VISIBILITY(default)
diff --git a/libstdc++-v3/src/c++11/regex.cc b/libstdc++-v3/src/c++11/regex.cc
index b18afe2081a..bf863009041 100644
--- a/libstdc++-v3/src/c++11/regex.cc
+++ b/libstdc++-v3/src/c++11/regex.cc
@@ -22,7 +22,8 @@
// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
// <http://www.gnu.org/licenses/>.
-#include <regex>
+#include <stdexcept>
+#include <bits/regex_error.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
diff --git a/libstdc++-v3/src/c++98/Makefile.am b/libstdc++-v3/src/c++98/Makefile.am
index 2f33b964af9..8ebff1aff23 100644
--- a/libstdc++-v3/src/c++98/Makefile.am
+++ b/libstdc++-v3/src/c++98/Makefile.am
@@ -82,7 +82,7 @@ basic_file.cc: ${glibcxx_srcdir}/$(BASIC_FILE_CC)
if ENABLE_EXTERN_TEMPLATE
-XTEMPLATE_FLAGS = -fno-implicit-templates
+# XTEMPLATE_FLAGS = -fno-implicit-templates
inst_sources = \
allocator-inst.cc \
concept-inst.cc \
@@ -97,7 +97,7 @@ inst_sources = \
streambuf-inst.cc \
wlocale-inst.cc
else
-XTEMPLATE_FLAGS =
+# XTEMPLATE_FLAGS =
inst_sources =
endif
@@ -172,7 +172,7 @@ parallel_settings.o: parallel_settings.cc
# as the occasion calls for it.
AM_CXXFLAGS = \
$(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
- $(XTEMPLATE_FLAGS) \
+ $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
@@ -222,4 +222,5 @@ CXXLINK = \
$(LIBTOOL) --tag CXX --tag disable-shared \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXX) \
+ $(VTV_CXXLINKFLAGS) \
$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
diff --git a/libstdc++-v3/src/c++98/Makefile.in b/libstdc++-v3/src/c++98/Makefile.in
index 42a08cd9eab..747bfa688ba 100644
--- a/libstdc++-v3/src/c++98/Makefile.in
+++ b/libstdc++-v3/src/c++98/Makefile.in
@@ -230,6 +230,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -326,6 +329,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
@@ -364,9 +369,10 @@ host_sources_extra = \
basic_file.cc c++locale.cc \
${inst_sources} ${parallel_sources}
-@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
-@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
+# XTEMPLATE_FLAGS =
@ENABLE_EXTERN_TEMPLATE_FALSE@inst_sources =
+
+# XTEMPLATE_FLAGS = -fno-implicit-templates
@ENABLE_EXTERN_TEMPLATE_TRUE@inst_sources = \
@ENABLE_EXTERN_TEMPLATE_TRUE@ allocator-inst.cc \
@ENABLE_EXTERN_TEMPLATE_TRUE@ concept-inst.cc \
@@ -434,7 +440,7 @@ PARALLEL_FLAGS = -D_GLIBCXX_PARALLEL
# as the occasion calls for it.
AM_CXXFLAGS = \
$(glibcxx_lt_pic_flag) $(glibcxx_compiler_shared_flag) \
- $(XTEMPLATE_FLAGS) \
+ $(XTEMPLATE_FLAGS) $(VTV_CXXFLAGS) \
$(WARN_CXXFLAGS) $(OPTIMIZE_CXXFLAGS) $(CONFIG_CXXFLAGS)
AM_MAKEFLAGS = \
@@ -485,6 +491,7 @@ CXXLINK = \
$(LIBTOOL) --tag CXX --tag disable-shared \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CXX) \
+ $(VTV_CXXLINKFLAGS) \
$(OPT_LDFLAGS) $(SECTION_LDFLAGS) $(AM_CXXFLAGS) $(LTLDFLAGS) -o $@
all: all-am
diff --git a/libstdc++-v3/src/c++98/compatibility.cc b/libstdc++-v3/src/c++98/compatibility.cc
index d964e89db4c..3f21c581ec1 100644
--- a/libstdc++-v3/src/c++98/compatibility.cc
+++ b/libstdc++-v3/src/c++98/compatibility.cc
@@ -517,14 +517,21 @@ extern __attribute__((used, weak)) const char _ZTSe[2] = "e";
extern __attribute__((used, weak)) const char _ZTSPe[3] = "Pe";
extern __attribute__((used, weak)) const char _ZTSPKe[4] = "PKe";
extern __attribute__((used, weak)) const void * const _ZTIe[2]
- = { (void *) &_ZTVN10__cxxabiv123__fundamental_type_infoE[2],
- (void *) _ZTSe };
+ = { reinterpret_cast<const void *>
+ (&_ZTVN10__cxxabiv123__fundamental_type_infoE[2]),
+ reinterpret_cast<const void *>(_ZTSe) };
extern __attribute__((used, weak)) const void * const _ZTIPe[4]
- = { (void *) &_ZTVN10__cxxabiv119__pointer_type_infoE[2],
- (void *) _ZTSPe, (void *) 0L, (void *) _ZTIe };
+ = { reinterpret_cast<const void *>
+ (&_ZTVN10__cxxabiv119__pointer_type_infoE[2]),
+ reinterpret_cast<const void *>(_ZTSPe),
+ reinterpret_cast<const void *>(0L),
+ reinterpret_cast<const void *>(_ZTIe) };
extern __attribute__((used, weak)) const void * const _ZTIPKe[4]
- = { (void *) &_ZTVN10__cxxabiv119__pointer_type_infoE[2],
- (void *) _ZTSPKe, (void *) 1L, (void *) _ZTIe };
+ = { reinterpret_cast<const void *>
+ (&_ZTVN10__cxxabiv119__pointer_type_infoE[2]),
+ reinterpret_cast<const void *>(_ZTSPKe),
+ reinterpret_cast<const void *>(1L),
+ reinterpret_cast<const void *>(_ZTIe) };
#endif // _GLIBCXX_LONG_DOUBLE_COMPAT
#ifdef _GLIBCXX_SYMVER_DARWIN
diff --git a/libstdc++-v3/testsuite/17_intro/freestanding.cc b/libstdc++-v3/testsuite/17_intro/freestanding.cc
index 4b5b4910629..6518af5b831 100644
--- a/libstdc++-v3/testsuite/17_intro/freestanding.cc
+++ b/libstdc++-v3/testsuite/17_intro/freestanding.cc
@@ -1,4 +1,4 @@
-// { dg-options "-x c -std=gnu++0x -lsupc++" }
+// { dg-options "-x c -std=gnu++0x -lsupc++ -fvtable-verify=none" }
// Copyright (C) 2010-2013 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c b/libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c
index e7cabc30bd2..0b8d1e26d3b 100644
--- a/libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c
+++ b/libstdc++-v3/testsuite/18_support/bad_exception/23591_thread-1.c
@@ -1,5 +1,5 @@
// { dg-require-sharedlib "" }
-// { dg-options "-g -O2 -pthread -ldl -x c" { target *-*-linux* *-*-gnu* } }
+// { dg-options "-g -O2 -pthread -ldl -x c -fvtable-verify=none" { target *-*-linux* *-*-gnu* } }
// Copyright (C) 2005-2013 Free Software Foundation, Inc.
//
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/58163.cc b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/58163.cc
new file mode 100644
index 00000000000..ea42027960b
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/char/58163.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11 -D_GLIBCXX_DEBUG_PEDANTIC" }
+
+#include <string>
+#include <testsuite_hooks.h>
+
+// PR c++/58163
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const std::string cs;
+ std::string s;
+
+ VERIFY( cs[0] == '\0' );
+ VERIFY( s[0] == '\0' );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/58163.cc b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/58163.cc
new file mode 100644
index 00000000000..a52390810e3
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/element_access/wchar_t/58163.cc
@@ -0,0 +1,39 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11 -D_GLIBCXX_DEBUG_PEDANTIC" }
+
+#include <string>
+#include <testsuite_hooks.h>
+
+// PR c++/58163
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const std::wstring cs;
+ std::wstring s;
+
+ VERIFY( cs[0] == L'\0' );
+ VERIFY( s[0] == L'\0' );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/deque/debug/insert5_neg.cc b/libstdc++-v3/testsuite/23_containers/deque/debug/insert5_neg.cc
new file mode 100644
index 00000000000..51d9fd3e7ab
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/deque/debug/insert5_neg.cc
@@ -0,0 +1,33 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-do run { xfail *-*-* } }
+
+#include <deque>
+#include <debug/checks.h>
+
+void test01()
+{
+ __gnu_test::check_insert4<std::deque<int> >();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/forward_list/debug/insert_after4_neg.cc b/libstdc++-v3/testsuite/23_containers/forward_list/debug/insert_after4_neg.cc
new file mode 100644
index 00000000000..f2e7847f607
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/forward_list/debug/insert_after4_neg.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-std=gnu++11 -D_GLIBCXX_DEBUG_PEDANTIC" }
+// { dg-do run { xfail *-*-* } }
+
+#include <forward_list>
+#include <iterator>
+
+void test01()
+{
+ std::forward_list<int> fl{ 1, 2, 3 };
+ fl.insert_after(fl.before_begin(), fl.begin(), std::next(fl.begin(), 2));
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/list/debug/insert5_neg.cc b/libstdc++-v3/testsuite/23_containers/list/debug/insert5_neg.cc
new file mode 100644
index 00000000000..7f748bbb8a6
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/list/debug/insert5_neg.cc
@@ -0,0 +1,34 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-options "-D_GLIBCXX_DEBUG_PEDANTIC" }
+// { dg-do run { xfail *-*-* } }
+
+#include <list>
+#include <debug/checks.h>
+
+void test01()
+{
+ __gnu_test::check_insert4<std::list<int> >();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
index ff0c832dd88..6aad5561392 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/instantiation_neg.cc
@@ -19,7 +19,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "with noexcept" "" { target *-*-* } 258 }
+// { dg-error "with noexcept" "" { target *-*-* } 265 }
#include <unordered_set>
diff --git a/libstdc++-v3/testsuite/23_containers/unordered_set/not_default_constructible_hash_neg.cc b/libstdc++-v3/testsuite/23_containers/unordered_set/not_default_constructible_hash_neg.cc
index be5b1201edd..3332cc593cd 100644
--- a/libstdc++-v3/testsuite/23_containers/unordered_set/not_default_constructible_hash_neg.cc
+++ b/libstdc++-v3/testsuite/23_containers/unordered_set/not_default_constructible_hash_neg.cc
@@ -19,7 +19,7 @@
// with this library; see the file COPYING3. If not see
// <http://www.gnu.org/licenses/>.
-// { dg-error "default constructible" "" { target *-*-* } 276 }
+// { dg-error "default constructible" "" { target *-*-* } 283 }
#include <unordered_set>
diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/57779_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/57779_neg.cc
new file mode 100644
index 00000000000..10ee76675f5
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/57779_neg.cc
@@ -0,0 +1,38 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-options "-std=gnu++11" }
+// { dg-require-debug-mode "" }
+// { dg-do run { xfail *-*-* } }
+
+#include <vector>
+#include <debug/checks.h>
+
+void test01()
+{
+ std::vector<int> v;
+ for (int i = 0; i != 10; ++i)
+ v.push_back(i);
+
+ v.insert(v.begin(), v.data() + 1, v.data() + 5); // Expected failure
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/insert5_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/insert5_neg.cc
new file mode 100644
index 00000000000..ccdafad76c0
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/insert5_neg.cc
@@ -0,0 +1,33 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-require-debug-mode "" }
+// { dg-do run { xfail *-*-* } }
+
+#include <vector>
+#include <debug/checks.h>
+
+void test01()
+{
+ __gnu_test::check_insert4<std::vector<int> >();
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/debug/insert6_neg.cc b/libstdc++-v3/testsuite/23_containers/vector/debug/insert6_neg.cc
new file mode 100644
index 00000000000..679df5bf84d
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/debug/insert6_neg.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+//
+// { dg-do run { xfail *-*-* } }
+
+#include <vector>
+#include <debug/vector>
+#include <debug/checks.h>
+
+void test01()
+{
+ std::vector<bool> v;
+ __gnu_debug::vector<bool> dv;
+ for (int i = 0; i != 10; ++i)
+ {
+ v.push_back((i % 2) != 0);
+ dv.push_back((i % 2) == 0);
+ }
+
+ dv.insert(dv.begin(), v.begin(), v.begin() + 5);
+ VERIFY( dv.size() == 15 );
+}
+
+void test02()
+{
+ __gnu_test::check_insert4<__gnu_debug::vector<bool> >();
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/58148.cc b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/58148.cc
new file mode 100644
index 00000000000..bfb2c0959c8
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/vector/modifiers/insert/58148.cc
@@ -0,0 +1,35 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+#include <vector>
+
+void
+test01()
+{
+ std::vector<wchar_t> v;
+ char c = 'a';
+ v.insert(v.begin(), &c, &c);
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc
index 37455cea5cb..2a3465b86d1 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/default.cc
@@ -35,7 +35,7 @@ test01()
VERIFY( u.a() == 0.0 );
VERIFY( u.b() == 1.0 );
typedef std::cauchy_distribution<>::result_type result_type;
- VERIFY( u.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( u.min() == std::numeric_limits<result_type>::lowest() );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc
index 2ac096b451f..67fb17172e5 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/cauchy_distribution/cons/parms.cc
@@ -35,7 +35,7 @@ test01()
VERIFY( u.a() == 5.0 );
VERIFY( u.b() == 2.0 );
typedef std::cauchy_distribution<>::result_type result_type;
- VERIFY( u.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( u.min() == std::numeric_limits<result_type>::lowest() );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc
index 486a1b2f2a7..f84b1307ed7 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/default.cc
@@ -34,7 +34,7 @@ test01()
std::exponential_distribution<> u;
VERIFY( u.lambda() == 1.0 );
typedef std::exponential_distribution<>::result_type result_type;
- VERIFY( u.min() == 0 );
+ VERIFY( u.min() == 0.0 );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc
index d1fc4dc5f13..ef2decfccd1 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/exponential_distribution/cons/parms.cc
@@ -34,7 +34,7 @@ test01()
std::exponential_distribution<> u(0.5);
VERIFY( u.lambda() == 0.5 );
typedef std::exponential_distribution<>::result_type result_type;
- VERIFY( u.min() == 0 );
+ VERIFY( u.min() == 0.0 );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc
index a8845e4d028..c14c49ce315 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/default.cc
@@ -35,7 +35,7 @@ test01()
VERIFY( u.a() == 0.0 );
VERIFY( u.b() == 1.0 );
typedef std::extreme_value_distribution<>::result_type result_type;
- VERIFY( u.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( u.min() == std::numeric_limits<result_type>::lowest() );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc
index daa20b5e384..786847f2fb0 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/extreme_value_distribution/cons/parms.cc
@@ -35,7 +35,7 @@ test01()
VERIFY( u.a() == 5.0 );
VERIFY( u.b() == 2.0 );
typedef std::extreme_value_distribution<>::result_type result_type;
- VERIFY( u.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( u.min() == std::numeric_limits<result_type>::lowest() );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/operators/58302.cc b/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/operators/58302.cc
new file mode 100644
index 00000000000..3ced018ed3c
--- /dev/null
+++ b/libstdc++-v3/testsuite/26_numerics/random/negative_binomial_distribution/operators/58302.cc
@@ -0,0 +1,34 @@
+// { dg-do compile }
+// { dg-options "-std=gnu++11" }
+// { dg-require-cstdint "" }
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <random>
+
+void test01()
+{
+ typedef std::negative_binomial_distribution<> dist_type;
+
+ std::default_random_engine engine;
+
+ dist_type dist;
+ dist_type::param_type param(3, 0.5);
+
+ dist(engine, param); // compile error!
+}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc
index 2ffa3305a81..8beb8bd2d2e 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/default.cc
@@ -35,7 +35,7 @@ test01()
VERIFY( u.mean() == 0.0 );
VERIFY( u.stddev() == 1.0 );
typedef std::normal_distribution<>::result_type result_type;
- VERIFY( u.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( u.min() == std::numeric_limits<result_type>::lowest() );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc
index 0c2b79905c7..ea87162c6c6 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/normal_distribution/cons/parms.cc
@@ -35,7 +35,7 @@ test01()
VERIFY( u.mean() == 5.0 );
VERIFY( u.stddev() == 2.0 );
typedef std::normal_distribution<>::result_type result_type;
- VERIFY( u.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( u.min() == std::numeric_limits<result_type>::lowest() );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc
index 8318b37a8b5..0b5b8fa301e 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/default.cc
@@ -34,7 +34,7 @@ test01()
std::student_t_distribution<> u;
VERIFY( u.n() == 1.0 );
typedef std::student_t_distribution<>::result_type result_type;
- VERIFY( u.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( u.min() == std::numeric_limits<result_type>::lowest() );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc
index fb3dc052837..1b9996212cf 100644
--- a/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc
+++ b/libstdc++-v3/testsuite/26_numerics/random/student_t_distribution/cons/parms.cc
@@ -34,7 +34,7 @@ test01()
std::student_t_distribution<> u(1.5);
VERIFY( u.n() == 1.5 );
typedef std::student_t_distribution<>::result_type result_type;
- VERIFY( u.min() == std::numeric_limits<result_type>::min() );
+ VERIFY( u.min() == std::numeric_limits<result_type>::lowest() );
VERIFY( u.max() == std::numeric_limits<result_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc
new file mode 100644
index 00000000000..d4edf123e97
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/awk/cstring_01.cc
@@ -0,0 +1,50 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-08-26 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests awk escaping.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ regex("\\[", regex_constants::awk);
+ VERIFY(regex_match("\"", regex("[\\\"]", regex_constants::awk)));
+ VERIFY(regex_match("/", regex("/", regex_constants::awk)));
+ VERIFY(regex_match("\a", regex("\\a", regex_constants::awk)));
+ VERIFY(regex_match("\"", regex("\\\"", regex_constants::awk)));
+ VERIFY(regex_match("5", regex("\\65", regex_constants::awk)));
+ VERIFY(regex_match("53", regex("\\0653", regex_constants::awk)));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc
new file mode 100644
index 00000000000..eb22569f337
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/empty_range.cc
@@ -0,0 +1,57 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-08-26 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript empty range.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+#define FAIL(s) \
+ try\
+ {\
+ regex re(s, regex_constants::basic);\
+ VERIFY(false);\
+ }\
+ catch (...)\
+ {\
+ VERIFY(true);\
+ }
+ FAIL("[]");
+ FAIL("[^]");
+ VERIFY(regex_match("]", regex("[]]", regex_constants::basic)));
+ VERIFY(!regex_match("]", regex("[^]]", regex_constants::basic)));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc
index 5d43d7c4354..91bc101392b 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/basic/string_range_02_03.cc
@@ -1,5 +1,4 @@
// { dg-options "-std=c++0x" }
-// { dg-do run { xfail *-*-* } }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc
new file mode 100644
index 00000000000..6e6095b8f24
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/anymatcher.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-02 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript "." against a std::string.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+#define TEST(res, s) \
+ {\
+ regex re(res);\
+ string st(s);\
+ VERIFY(!regex_match(st, re));\
+ }
+ TEST(".", "\0");
+ TEST(".", "\n");
+ TEST(".", "\r");
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc
new file mode 100644
index 00000000000..321ce35a038
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/backref.cc
@@ -0,0 +1,78 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-02 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript back-refernce against a std::string.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ regex re("([A-Z])\\1*");
+ smatch m;
+ {
+ string s = "AAAA";
+ regex_match(s, m, re);
+ VERIFY( m[0].matched );
+ VERIFY( m[1].matched );
+ VERIFY( std::string(m[0].first, m[0].second) == "AAAA" );
+ VERIFY( std::string(m[1].first, m[1].second) == "A" );
+ }
+ {
+ string s = "BBBB";
+ regex_match(s, m, re);
+ VERIFY( m[0].matched );
+ VERIFY( m[1].matched );
+ VERIFY( std::string(m[0].first, m[0].second) == "BBBB" );
+ VERIFY( std::string(m[1].first, m[1].second) == "B" );
+ }
+ {
+ string s = "BBBA";
+ regex_match(s, m, re);
+ VERIFY( !m[0].matched );
+ VERIFY( !m[1].matched );
+ }
+ {
+ try
+ {
+ regex re("(a(b)(c\\1(d)))");
+ VERIFY( false );
+ }
+ catch (...)
+ {
+ VERIFY( true );
+ }
+ }
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc
new file mode 100644
index 00000000000..3c48d3521a5
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/empty_range.cc
@@ -0,0 +1,47 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-02 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript empty range.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY(!regex_match("x", regex("[]")));
+ VERIFY(regex_match("x", regex("[^]")));
+ VERIFY(!regex_match("]", regex("[]]")));
+ VERIFY(!regex_match("]", regex("[^]]")));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc
new file mode 100644
index 00000000000..1dc8f63f789
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc
@@ -0,0 +1,58 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-02 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript empty-grouping against a C-string.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ {
+ regex re("()*\\1");
+ cmatch m;
+ const char s[] = "";
+ VERIFY( regex_match(s, m, re) );
+ VERIFY( m.size() == 2 );
+ VERIFY( m[0].matched );
+ VERIFY( m[1].matched );
+ }
+ {
+ regex re("()*");
+ cmatch m;
+ const char s[] = "";
+ VERIFY( regex_match(s, m, re) );
+ }
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc
new file mode 100644
index 00000000000..a73b742a5e4
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/hex.cc
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-02 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript \x and \u.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY(regex_match(":", regex("\\x3a")));
+ try
+ {
+ regex("\\u400x");
+ VERIFY(false);
+ }
+ catch (...)
+ {
+ VERIFY(true);
+ }
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc
new file mode 100644
index 00000000000..b54f5619a24
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/quoted_char.cc
@@ -0,0 +1,52 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-05 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript \d \D \s \S \w \W
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY(regex_match("01", regex("\\d*")));
+ VERIFY(regex_match("asdfjkl", regex("\\D*")));
+ VERIFY(!regex_match("asdfjkl0", regex("\\D*")));
+ VERIFY(regex_match("\r\t\v\f ", regex("\\s*")));
+ VERIFY(regex_match("asdfjkl", regex("\\S*")));
+ VERIFY(!regex_match("asdfjkl\r", regex("\\S*")));
+ VERIFY(regex_match("_az", regex("\\w*")));
+ VERIFY(regex_match("!@#$%", regex("\\W*")));
+ VERIFY(!regex_match("_01234", regex("\\W*")));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc
new file mode 100644
index 00000000000..c574908d6a9
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/anymatcher.cc
@@ -0,0 +1,51 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-02 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript "." against a std::string.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+#define TESTL(res, s) \
+ {\
+ wregex re(res);\
+ wstring st(s);\
+ VERIFY(!regex_match(st, re));\
+ }
+ TESTL(L".", L"\u2028");
+ TESTL(L".", L"\u2029");
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc
new file mode 100644
index 00000000000..f9561be70e2
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/wchar_t/hex.cc
@@ -0,0 +1,44 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-02 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests ECMAScript \x and \u.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY(regex_match(L"\u1234", wregex(L"\\u1234")));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/53622.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/53622.cc
index 383ed054a90..aee1dbe15dc 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/53622.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/53622.cc
@@ -32,16 +32,31 @@ test01()
{
bool test __attribute__((unused)) = true;
- std::regex re("zxcv/(one.*)abc", std::regex::extended);
- std::string target("zxcv/onetwoabc");
- std::smatch m;
-
- VERIFY( std::regex_search(target, m, re) );
- VERIFY( m.size() == 2 );
- VERIFY( m[0].matched == true );
- VERIFY( std::string(m[0].first, m[0].second) == "zxcv/onetwoabc" );
- VERIFY( m[1].matched == true );
- VERIFY( std::string(m[1].first, m[1].second) == "onetwo" );
+ {
+ std::regex re("zxcv/(one.*)abc", std::regex::extended);
+ std::string target("zxcv/onetwoabc");
+ std::smatch m;
+
+ VERIFY( std::regex_match(target, m, re) );
+ VERIFY( m.size() == 2 );
+ VERIFY( m[0].matched == true );
+ VERIFY( std::string(m[0].first, m[0].second) == "zxcv/onetwoabc" );
+ VERIFY( m[1].matched == true );
+ VERIFY( std::string(m[1].first, m[1].second) == "onetwo" );
+ }
+
+ {
+ std::regex re("zxcv/(one.*)abc()\\2", std::regex::extended);
+ std::string target("zxcv/onetwoabc");
+ std::smatch m;
+
+ VERIFY( std::regex_match(target, m, re) );
+ VERIFY( m.size() == 3 );
+ VERIFY( m[0].matched == true );
+ VERIFY( std::string(m[0].first, m[0].second) == "zxcv/onetwoabc" );
+ VERIFY( m[1].matched == true );
+ VERIFY( std::string(m[1].first, m[1].second) == "onetwo" );
+ }
}
int
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/57173.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/57173.cc
index 3031c43d188..cb3a54f4d88 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/57173.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/57173.cc
@@ -33,13 +33,24 @@ test01()
{
bool test __attribute__((unused)) = true;
- std::regex re("/asdf(/.*)", std::regex::extended);
- std::string target("/asdf/qwerty");
- std::smatch m;
+ {
+ std::regex re("/asdf(/.*)", std::regex::extended);
+ std::string target("/asdf/qwerty");
+ std::smatch m;
- VERIFY( std::regex_match(target, m, re) );
- VERIFY( m.size() == 2 );
- VERIFY( std::string(m[1].first, m[1].second) == "/qwerty");
+ VERIFY( std::regex_match(target, m, re) );
+ VERIFY( m.size() == 2 );
+ VERIFY( std::string(m[1].first, m[1].second) == "/qwerty");
+ }
+ {
+ std::regex re("/asdf(/.*)()\\2", std::regex::extended);
+ std::string target("/asdf/qwerty");
+ std::smatch m;
+
+ VERIFY( std::regex_match(target, m, re) );
+ VERIFY( m.size() == 3 );
+ VERIFY( std::string(m[1].first, m[1].second) == "/qwerty");
+ }
}
int
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc
new file mode 100644
index 00000000000..3a4ff31f104
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_bracket_01.cc
@@ -0,0 +1,66 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-08-01 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests Extended bracket expression against a C-string.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ {
+ std::regex re("pre/[za-x]", std::regex::extended);
+ VERIFY( std::regex_match("pre/z", re) );
+ VERIFY( std::regex_match("pre/a", re) );
+ VERIFY( !std::regex_match("pre/y", re) );
+ }
+ {
+ std::regex re("pre/[[:uPPer:]]", std::regex::extended);
+ VERIFY( std::regex_match("pre/Z", re) );
+ VERIFY( !std::regex_match("pre/_", re) );
+ VERIFY( !std::regex_match("pre/a", re) );
+ VERIFY( !std::regex_match("pre/0", re) );
+ }
+ {
+ std::regex re("pre/[[:lOWer:]]", std::regex::extended | std::regex::icase);
+ VERIFY( std::regex_match("pre/Z", re) );
+ VERIFY( std::regex_match("pre/a", re) );
+ }
+ {
+ std::regex re("pre/[[:w:][.tilde.]]", std::regex::extended);
+ VERIFY( std::regex_match("pre/~", re) );
+ VERIFY( std::regex_match("pre/_", re) );
+ VERIFY( std::regex_match("pre/a", re) );
+ VERIFY( std::regex_match("pre/0", re) );
+ }
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc
index 67bc1d8a5c2..375f34b8064 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_plus.cc
@@ -1,5 +1,4 @@
// { dg-options "-std=c++0x" }
-// { dg-do run { xfail *-*-* } }
//
// 2010-06-21 Stephen M. Webb <stephen.webb@bregmasoft.ca>
@@ -32,27 +31,31 @@ test01()
{
bool test __attribute__((unused)) = true;
- std::regex re("(a+)", std::regex::extended);
- const char target[] = "aa";
- std::cmatch m;
+ std::regex re("(a+)", std::regex::extended);
+ const char target[] = "aa";
+ std::cmatch m;
- VERIFY( std::regex_match(target, m, re) );
+ VERIFY( std::regex_match(target, m, re) );
- VERIFY( re.mark_count() == 1 );
- VERIFY( m.size() == re.mark_count()+1 );
- VERIFY( m.empty() == false );
- VERIFY( m.prefix().first == target );
- VERIFY( m.prefix().second == target );
- VERIFY( m.prefix().matched == false );
- VERIFY( m.suffix().first == target+sizeof(target) );
- VERIFY( m.suffix().second == target+sizeof(target) );
- VERIFY( m.suffix().matched == false );
- VERIFY( m[0].first == target );
- VERIFY( m[0].second == target+sizeof(target) );
- VERIFY( m[0].matched == true );
- VERIFY( m[1].first == target );
- VERIFY( m[1].second == target+sizeof(target) );
- VERIFY( m[1].matched == true );
+ VERIFY( re.mark_count() == 1 );
+ VERIFY( m.size() == re.mark_count()+1 );
+ VERIFY( m.empty() == false );
+ VERIFY( m.prefix().first == target );
+ VERIFY( m.prefix().second == target );
+ VERIFY( m.prefix().matched == false );
+ VERIFY( m.suffix().first == target+sizeof(target)-1 );
+ VERIFY( m.suffix().second == target+sizeof(target)-1 );
+ VERIFY( m.suffix().matched == false );
+ VERIFY( m[0].first == target );
+ VERIFY( m[0].second == target+sizeof(target)-1 );
+ VERIFY( m[0].matched == true );
+ VERIFY( m[1].first == target );
+ VERIFY( m[1].second == target+sizeof(target)-1 );
+ VERIFY( m[1].matched == true );
+
+ VERIFY(!std::regex_match("", std::regex("a+", std::regex::extended)));
+ VERIFY(std::regex_match("a", std::regex("a+", std::regex::extended)));
+ VERIFY(std::regex_match("aa", std::regex("a+", std::regex::extended)));
}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc
index c0c8b92965b..79b52a88c4f 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_questionmark.cc
@@ -1,5 +1,4 @@
// { dg-options "-std=c++0x" }
-// { dg-do run { xfail *-*-* } }
//
// 2010-06-21 Stephen M. Webb <stephen.webb@bregmasoft.ca>
@@ -32,27 +31,31 @@ test01()
{
bool test __attribute__((unused)) = true;
- std::regex re("(aa?)", std::regex::extended);
- char target[] = "a";
- std::cmatch m;
+ std::regex re("(aa?)", std::regex::extended);
+ char target[] = "a";
+ std::cmatch m;
- VERIFY( std::regex_match(target, m, re) );
+ VERIFY( std::regex_match(target, m, re) );
- VERIFY( re.mark_count() == 1 );
- VERIFY( m.size() == re.mark_count()+1 );
- VERIFY( m.empty() == false );
- VERIFY( m.prefix().first == target );
- VERIFY( m.prefix().second == target );
- VERIFY( m.prefix().matched == false );
- VERIFY( m.suffix().first == target+sizeof(target) );
- VERIFY( m.suffix().second == target+sizeof(target) );
- VERIFY( m.suffix().matched == false );
- VERIFY( m[0].first == target );
- VERIFY( m[0].second == target+sizeof(target) );
- VERIFY( m[0].matched == true );
- VERIFY( m[1].first == target );
- VERIFY( m[1].second == target+sizeof(target) );
- VERIFY( m[1].matched == true );
+ VERIFY( re.mark_count() == 1 );
+ VERIFY( m.size() == re.mark_count()+1 );
+ VERIFY( m.empty() == false );
+ VERIFY( m.prefix().first == target );
+ VERIFY( m.prefix().second == target );
+ VERIFY( m.prefix().matched == false );
+ VERIFY( m.suffix().first == target+sizeof(target)-1 );
+ VERIFY( m.suffix().second == target+sizeof(target)-1 );
+ VERIFY( m.suffix().matched == false );
+ VERIFY( m[0].first == target );
+ VERIFY( m[0].second == target+sizeof(target)-1 );
+ VERIFY( m[0].matched == true );
+ VERIFY( m[1].first == target );
+ VERIFY( m[1].second == target+sizeof(target)-1 );
+ VERIFY( m[1].matched == true );
+
+ VERIFY(std::regex_match("", std::regex("a?", std::regex::extended)));
+ VERIFY(std::regex_match("a", std::regex("a?", std::regex::extended)));
+ VERIFY(!std::regex_match("aa", std::regex("a?", std::regex::extended)));
}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc
new file mode 100644
index 00000000000..62f825a0fb9
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/cstring_range.cc
@@ -0,0 +1,68 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-09-05 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests Extended interval range.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ regex re;
+ re.assign("(ab){3}", std::regex::extended);
+ VERIFY(!regex_match("abab", re));
+ VERIFY(regex_match("ababab", re));
+ VERIFY(!regex_match("abababab", re));
+ re.assign("(ab){3,}", std::regex::extended);
+ VERIFY(!regex_match("abab", re));
+ VERIFY(regex_match("ababab", re));
+ VERIFY(regex_match("abababab", re));
+ VERIFY(regex_match("ababababab", re));
+ re.assign("(ab){0,3}", std::regex::extended);
+ VERIFY(regex_match("", re));
+ VERIFY(regex_match("ab", re));
+ VERIFY(regex_match("abab", re));
+ VERIFY(regex_match("ababab", re));
+ VERIFY(!regex_match("abababab", re));
+ re.assign("(a|b){0,2}", std::regex::extended);
+ VERIFY(regex_match("", re));
+ VERIFY(regex_match("a", re));
+ VERIFY(regex_match("b", re));
+ VERIFY(regex_match("aa", re));
+ VERIFY(regex_match("ab", re));
+ VERIFY(regex_match("ba", re));
+ VERIFY(regex_match("bb", re));
+ VERIFY(!regex_match("aaa", re));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc
new file mode 100644
index 00000000000..cb502eadfb4
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_dispatch_01.cc
@@ -0,0 +1,69 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-07-29 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests Extended automatic matcher dispatching against a std::string target.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+using namespace std;
+
+template<typename _Bi_iter, typename _Alloc,
+ typename _Ch_type, typename _Rx_traits>
+ void
+ fake_match(_Bi_iter __s,
+ _Bi_iter __e,
+ match_results<_Bi_iter, _Alloc>& __m,
+ const basic_regex<_Ch_type, _Rx_traits>& __re,
+ regex_constants::match_flag_type __flags
+ = regex_constants::match_default)
+ {
+ VERIFY( (dynamic_cast
+ <__detail::_DFSExecutor<_Bi_iter, _Alloc, _Ch_type, _Rx_traits>*>
+ (&*__detail::__get_executor(__s, __e, __m, __re, __flags))
+ != nullptr) );
+ }
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ regex re("()(one(.*))abc\\1"); // backref cause DFS
+ const string target("onetwoabc");
+ smatch m;
+ fake_match(target.begin(), target.end(), m, re);
+
+ regex_match(target, m, re);
+ VERIFY( m[2].matched );
+ VERIFY( m[3].matched );
+ VERIFY( std::string(m[2].first, m[2].second) == "onetwo" );
+ VERIFY( std::string(m[3].first, m[3].second) == "two" );
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc
index 180c35962e1..e10dba81ffa 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_00_03.cc
@@ -31,23 +31,23 @@ test01()
{
bool test __attribute__((unused)) = true;
- std::regex re("a{0,3}", std::regex::extended);
- std::string target("aa");
- std::smatch m;
-
- VERIFY( std::regex_match(target, m, re) );
-
- VERIFY( m.size() == re.mark_count()+1 );
- VERIFY( m.empty() == false );
- VERIFY( m.prefix().first == target.begin() );
- VERIFY( m.prefix().second == target.begin() );
- VERIFY( m.prefix().matched == false );
- VERIFY( m.suffix().first == target.end() );
- VERIFY( m.suffix().second == target.end() );
- VERIFY( m.suffix().matched == false );
- VERIFY( m[0].first == target.begin() );
- VERIFY( m[0].second == target.end() );
- VERIFY( m[0].matched == true );
+ std::regex re("a{0,3}", std::regex::extended);
+ std::string target("aa");
+ std::smatch m;
+
+ VERIFY( std::regex_match(target, m, re) );
+
+ VERIFY( m.size() == re.mark_count()+1 );
+ VERIFY( m.empty() == false );
+ VERIFY( m.prefix().first == target.begin() );
+ VERIFY( m.prefix().second == target.begin() );
+ VERIFY( m.prefix().matched == false );
+ VERIFY( m.suffix().first == target.end() );
+ VERIFY( m.suffix().second == target.end() );
+ VERIFY( m.suffix().matched == false );
+ VERIFY( m[0].first == target.begin() );
+ VERIFY( m[0].second == target.end() );
+ VERIFY( m[0].matched == true );
}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc
index 532869d1341..62793b4a199 100644
--- a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/string_range_02_03.cc
@@ -1,5 +1,4 @@
// { dg-options "-std=c++0x" }
-// { dg-do run { xfail *-*-* } }
//
// 2010-06-16 Stephen M. Webb <stephen.webb@bregmasoft.ca>
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc
new file mode 100644
index 00000000000..6ab48ca6baf
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_match/extended/wstring_locale.cc
@@ -0,0 +1,48 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-namedlocale "de_DE.UTF-8" }
+
+//
+// 2013-08-29 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.2 regex_match
+// Tests Extended localization against a wide-string.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::wstring str2 = L"ÜBER";
+ std::wregex re2;
+ re2.imbue(std::locale("de_DE.UTF-8"));
+ re2.assign(L"[[:upper:]]*", std::regex::extended);
+ std::wsmatch m2;
+ VERIFY(std::regex_match(str2, m2, re2));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc
new file mode 100644
index 00000000000..a2d290db283
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/algorithms/regex_search/ecma/string_01.cc
@@ -0,0 +1,42 @@
+// { dg-options "-std=gnu++11" }
+
+//
+// 2013-08-26 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.11.3 regex_search
+// Tests BRE against a std::string target.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ VERIFY(std::regex_search("", std::regex("")));
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc
new file mode 100644
index 00000000000..cd2c68e33ee
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_iterator/wchar_t/string_02.cc
@@ -0,0 +1,59 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-namedlocale "en_US.UTF-8" }
+// { dg-do run { xfail *-*-* } }
+
+//
+// 2013-09-05 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.12.1 regex_iterator
+// Tests regex_iterator class
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::setlocale(LC_ALL, "en_US.UTF-8");
+
+ std::wstring str2 = L"ä\u2009Ä\u2009ö\u2009Ö\u2009ü\u2009Ü";
+
+ std::wregex re2;
+ re2.imbue(std::locale("en_US.UTF-8"));
+
+ re2.assign(L"([[:lower:]]{0,1}[[:space:]]{0,1}[[:upper:]]{0,1})");
+
+ std::wsregex_iterator p(str2.begin(), str2.end(), re2);
+ auto a = p;
+ ++p;
+ VERIFY(a != p);
+ //for (std::wsregex_iterator p(str2.begin(), str2.end(), re2);
+ // p != std::wsregex_iterator{}; ++p)
+ // std::wcout << (*p)[1] << std::endl;
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc
new file mode 100644
index 00000000000..0306ee197b9
--- /dev/null
+++ b/libstdc++-v3/testsuite/28_regex/iterators/regex_token_iterator/wchar_t/wstring_02.cc
@@ -0,0 +1,53 @@
+// { dg-options "-std=gnu++11" }
+// { dg-require-namedlocale "en_US.UTF-8" }
+
+//
+// 2013-08-29 Tim Shen <timshen91@gmail.com>
+//
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// 28.12.2 regex_token_iterator
+// Tests regex_token_iterator class over a localized wstring.
+
+#include <regex>
+#include <testsuite_hooks.h>
+
+void
+test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ std::setlocale(LC_ALL, "en_US.UTF-8");
+
+ std::wstring str2 = L"öäü";
+ std::wregex re2;
+ re2.assign(L"([[:lower:]]+)");
+ std::wsmatch m2;
+
+ std::wsregex_token_iterator end {};
+ std::wsregex_token_iterator p{str2.begin(), str2.end(), re2, {1}};
+
+ VERIFY(p == end);
+}
+
+int
+main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc b/libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc
new file mode 100644
index 00000000000..7e5d58f418e
--- /dev/null
+++ b/libstdc++-v3/testsuite/29_atomics/atomic/requirements/compare_exchange_lowering.cc
@@ -0,0 +1,65 @@
+// { dg-options "-std=gnu++11" }
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <atomic>
+#include <testsuite_common_types.h>
+
+#define TEST_ALL_ORDERS() \
+ do { \
+ ORDER_TEST(std::memory_order_relaxed); \
+ ORDER_TEST(std::memory_order_consume); \
+ ORDER_TEST(std::memory_order_acquire); \
+ ORDER_TEST(std::memory_order_release); \
+ ORDER_TEST(std::memory_order_acq_rel); \
+ ORDER_TEST(std::memory_order_seq_cst); \
+ } while(0)
+
+void test01()
+{
+#define ORDER_TEST(ORDER) \
+ do { \
+ __gnu_test::compare_exchange_order_lowering<ORDER> test; \
+ __gnu_cxx::typelist::apply_generator(test, \
+ __gnu_test::integral_types::type()); \
+ } while (0);
+ TEST_ALL_ORDERS();
+#undef ORDER_TEST
+
+ enum e { a, b, c };
+#define ORDER_TEST(ORDER) \
+ do { \
+ std::atomic<e> x(a); \
+ e expected = a; \
+ x.compare_exchange_strong(expected, b, ORDER); \
+ x.compare_exchange_weak(expected, c, ORDER); \
+ } while (0);
+ TEST_ALL_ORDERS();
+#undef ORDER_TEST
+
+#define ORDER_TEST(ORDER) \
+ do { \
+ std::atomic<void*> x(nullptr); \
+ void* expected = nullptr; \
+ x.compare_exchange_strong(expected, nullptr, ORDER); \
+ x.compare_exchange_weak(expected, nullptr, ORDER); \
+ } while (0);
+ TEST_ALL_ORDERS();
+#undef ORDER_TEST
+}
diff --git a/libstdc++-v3/testsuite/Makefile.in b/libstdc++-v3/testsuite/Makefile.in
index 6d883a67c87..6c9d3b030b2 100644
--- a/libstdc++-v3/testsuite/Makefile.in
+++ b/libstdc++-v3/testsuite/Makefile.in
@@ -197,6 +197,9 @@ SYMVER_FILE = @SYMVER_FILE@
TOPLEVEL_INCLUDES = @TOPLEVEL_INCLUDES@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
+VTV_CXXFLAGS = @VTV_CXXFLAGS@
+VTV_CXXLINKFLAGS = @VTV_CXXLINKFLAGS@
+VTV_PCH_CXXFLAGS = @VTV_PCH_CXXFLAGS@
WARN_FLAGS = @WARN_FLAGS@
WERROR = @WERROR@
XMLLINT = @XMLLINT@
@@ -296,6 +299,8 @@ toolexecdir = $(glibcxx_toolexecdir)
toolexeclibdir = $(glibcxx_toolexeclibdir)
@ENABLE_WERROR_FALSE@WERROR_FLAG =
@ENABLE_WERROR_TRUE@WERROR_FLAG = $(WERROR)
+@ENABLE_EXTERN_TEMPLATE_FALSE@XTEMPLATE_FLAGS =
+@ENABLE_EXTERN_TEMPLATE_TRUE@XTEMPLATE_FLAGS = -fno-implicit-templates
# These bits are all figured out from configure. Look in acinclude.m4
# or configure.ac to see how they are set. See GLIBCXX_EXPORT_FLAGS.
diff --git a/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/default.cc b/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/default.cc
index db3db480a70..80ad819797c 100644
--- a/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/default.cc
+++ b/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/default.cc
@@ -36,9 +36,9 @@ test01()
VERIFY( u.varcov()[1] == 0.0 );
VERIFY( u.varcov()[2] == 1.0 );
typedef __gnu_cxx::normal_mv_distribution<2>::result_type result_type;
- VERIFY( u.min()[0] == std::numeric_limits<result_type::value_type>::min() );
+ VERIFY( u.min()[0] == std::numeric_limits<result_type::value_type>::lowest() );
VERIFY( u.max()[0] == std::numeric_limits<result_type::value_type>::max() );
- VERIFY( u.min()[1] == std::numeric_limits<result_type::value_type>::min() );
+ VERIFY( u.min()[1] == std::numeric_limits<result_type::value_type>::lowest() );
VERIFY( u.max()[1] == std::numeric_limits<result_type::value_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/parms.cc b/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/parms.cc
index b546d0793d4..3c51e7db20a 100644
--- a/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/parms.cc
+++ b/libstdc++-v3/testsuite/ext/random/normal_mv_distribution/cons/parms.cc
@@ -36,9 +36,9 @@ test01()
VERIFY( u.varcov()[1] == 0.0 );
VERIFY( u.varcov()[2] == 3.0 );
typedef __gnu_cxx::normal_mv_distribution<2>::result_type result_type;
- VERIFY( u.min()[0] == std::numeric_limits<result_type::value_type>::min() );
+ VERIFY( u.min()[0] == std::numeric_limits<result_type::value_type>::lowest() );
VERIFY( u.max()[0] == std::numeric_limits<result_type::value_type>::max() );
- VERIFY( u.min()[1] == std::numeric_limits<result_type::value_type>::min() );
+ VERIFY( u.min()[1] == std::numeric_limits<result_type::value_type>::lowest() );
VERIFY( u.max()[1] == std::numeric_limits<result_type::value_type>::max() );
}
diff --git a/libstdc++-v3/testsuite/ext/triangular_distribution/cons/default.cc b/libstdc++-v3/testsuite/ext/random/triangular_distribution/cons/default.cc
index 63303f81e6b..63303f81e6b 100644
--- a/libstdc++-v3/testsuite/ext/triangular_distribution/cons/default.cc
+++ b/libstdc++-v3/testsuite/ext/random/triangular_distribution/cons/default.cc
diff --git a/libstdc++-v3/testsuite/ext/triangular_distribution/cons/parms.cc b/libstdc++-v3/testsuite/ext/random/triangular_distribution/cons/parms.cc
index 8380965df46..8380965df46 100644
--- a/libstdc++-v3/testsuite/ext/triangular_distribution/cons/parms.cc
+++ b/libstdc++-v3/testsuite/ext/random/triangular_distribution/cons/parms.cc
diff --git a/libstdc++-v3/testsuite/ext/triangular_distribution/operators/equal.cc b/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/equal.cc
index c38ea4c58c4..c38ea4c58c4 100644
--- a/libstdc++-v3/testsuite/ext/triangular_distribution/operators/equal.cc
+++ b/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/equal.cc
diff --git a/libstdc++-v3/testsuite/ext/triangular_distribution/operators/inequal.cc b/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/inequal.cc
index c4a014ea2c8..c4a014ea2c8 100644
--- a/libstdc++-v3/testsuite/ext/triangular_distribution/operators/inequal.cc
+++ b/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/inequal.cc
diff --git a/libstdc++-v3/testsuite/ext/triangular_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/serialize.cc
index 7878376d93a..7878376d93a 100644
--- a/libstdc++-v3/testsuite/ext/triangular_distribution/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/ext/random/triangular_distribution/operators/serialize.cc
diff --git a/libstdc++-v3/testsuite/ext/triangular_distribution/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/ext/random/triangular_distribution/requirements/explicit_instantiation/1.cc
index 189bdaf80c1..189bdaf80c1 100644
--- a/libstdc++-v3/testsuite/ext/triangular_distribution/requirements/explicit_instantiation/1.cc
+++ b/libstdc++-v3/testsuite/ext/random/triangular_distribution/requirements/explicit_instantiation/1.cc
diff --git a/libstdc++-v3/testsuite/ext/triangular_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/ext/random/triangular_distribution/requirements/typedefs.cc
index 835e8e7e9c7..835e8e7e9c7 100644
--- a/libstdc++-v3/testsuite/ext/triangular_distribution/requirements/typedefs.cc
+++ b/libstdc++-v3/testsuite/ext/random/triangular_distribution/requirements/typedefs.cc
diff --git a/libstdc++-v3/testsuite/ext/von_mises_distribution/cons/default.cc b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/cons/default.cc
index 3183c85ed7e..3183c85ed7e 100644
--- a/libstdc++-v3/testsuite/ext/von_mises_distribution/cons/default.cc
+++ b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/cons/default.cc
diff --git a/libstdc++-v3/testsuite/ext/von_mises_distribution/cons/parms.cc b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/cons/parms.cc
index 6c1f8f73007..6c1f8f73007 100644
--- a/libstdc++-v3/testsuite/ext/von_mises_distribution/cons/parms.cc
+++ b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/cons/parms.cc
diff --git a/libstdc++-v3/testsuite/ext/von_mises_distribution/operators/equal.cc b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/equal.cc
index 569a9aae944..569a9aae944 100644
--- a/libstdc++-v3/testsuite/ext/von_mises_distribution/operators/equal.cc
+++ b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/equal.cc
diff --git a/libstdc++-v3/testsuite/ext/von_mises_distribution/operators/inequal.cc b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/inequal.cc
index a4d2d8ddfbd..a4d2d8ddfbd 100644
--- a/libstdc++-v3/testsuite/ext/von_mises_distribution/operators/inequal.cc
+++ b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/inequal.cc
diff --git a/libstdc++-v3/testsuite/ext/von_mises_distribution/operators/serialize.cc b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/serialize.cc
index 5437c136ae8..5437c136ae8 100644
--- a/libstdc++-v3/testsuite/ext/von_mises_distribution/operators/serialize.cc
+++ b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/operators/serialize.cc
diff --git a/libstdc++-v3/testsuite/ext/von_mises_distribution/requirements/explicit_instantiation/1.cc b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/requirements/explicit_instantiation/1.cc
index d93093f4d8f..d93093f4d8f 100644
--- a/libstdc++-v3/testsuite/ext/von_mises_distribution/requirements/explicit_instantiation/1.cc
+++ b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/requirements/explicit_instantiation/1.cc
diff --git a/libstdc++-v3/testsuite/ext/von_mises_distribution/requirements/typedefs.cc b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/requirements/typedefs.cc
index c8c34abd3e2..c8c34abd3e2 100644
--- a/libstdc++-v3/testsuite/ext/von_mises_distribution/requirements/typedefs.cc
+++ b/libstdc++-v3/testsuite/ext/random/von_mises_distribution/requirements/typedefs.cc
diff --git a/libstdc++-v3/testsuite/ext/vstring/element_access/char/58163.cc b/libstdc++-v3/testsuite/ext/vstring/element_access/char/58163.cc
new file mode 100644
index 00000000000..cd58be56378
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/vstring/element_access/char/58163.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11 -D_GLIBCXX_DEBUG_PEDANTIC" }
+// { dg-require-string-conversions "" }
+
+#include <ext/vstring.h>
+#include <testsuite_hooks.h>
+
+// PR c++/58163
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const __gnu_cxx::__vstring cs;
+ __gnu_cxx::__vstring s;
+
+ VERIFY( cs[0] == '\0' );
+ VERIFY( s[0] == '\0' );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/ext/vstring/element_access/wchar_t/58163.cc b/libstdc++-v3/testsuite/ext/vstring/element_access/wchar_t/58163.cc
new file mode 100644
index 00000000000..29ca38eea97
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/vstring/element_access/wchar_t/58163.cc
@@ -0,0 +1,40 @@
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-options "-std=gnu++11 -D_GLIBCXX_DEBUG_PEDANTIC" }
+// { dg-require-string-conversions "" }
+
+#include <ext/vstring.h>
+#include <testsuite_hooks.h>
+
+// PR c++/58163
+void test01()
+{
+ bool test __attribute__((unused)) = true;
+
+ const __gnu_cxx::__wvstring cs;
+ __gnu_cxx::__wvstring s;
+
+ VERIFY( cs[0] == L'\0' );
+ VERIFY( s[0] == L'\0' );
+}
+
+int main()
+{
+ test01();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/lib/libstdc++.exp b/libstdc++-v3/testsuite/lib/libstdc++.exp
index c339044a656..83a3862fbd0 100644
--- a/libstdc++-v3/testsuite/lib/libstdc++.exp
+++ b/libstdc++-v3/testsuite/lib/libstdc++.exp
@@ -84,7 +84,7 @@ proc libstdc++_init { testfile } {
global env
global v3-sharedlib v3-libgomp
global srcdir blddir objdir tool_root_dir
- global cc cxx cxxflags cxxpchflags cxxldflags
+ global cc cxx cxxflags cxxpchflags cxxldflags cxxvtvflags
global includes
global gluefile wrap_flags
global ld_library_path
@@ -157,6 +157,17 @@ proc libstdc++_init { testfile } {
}
v3track libgompdir 3
+ # Locate libvtv. This is only required for --enable-vtable-verify.
+ set v3-libvtv 0
+ set libvtvdir [lookfor_file $blddir/../libvtv .libs/libvtv.$shlib_ext]
+ if {$libvtvdir != ""} {
+ set v3-libvtv 1
+ set libvtvdir [file dirname $libvtvdir]
+ append ld_library_path_tmp ":${libvtvdir}"
+ verbose -log "libvtv support detected"
+ }
+ v3track libvtvdir 3
+
# Locate libstdc++ shared library. (ie libstdc++.so.)
set v3-sharedlib 0
set sharedlibdir [lookfor_file $blddir src/.libs/libstdc++.$shlib_ext]
@@ -214,6 +225,7 @@ proc libstdc++_init { testfile } {
set cxx [transform "g++"]
set cxxflags "-D_GLIBCXX_ASSERT -fmessage-length=0"
set cxxpchflags ""
+ set cxxvtvflags ""
set cxxldflags ""
set cc [transform "gcc"]
# Locate testsuite_hooks.h and other testsuite headers.
@@ -261,6 +273,7 @@ proc libstdc++_init { testfile } {
set cxx [exec sh $flags_file --build-cxx]
set cxxflags [exec sh $flags_file --cxxflags]
set cxxpchflags [exec sh $flags_file --cxxpchflags]
+ set cxxvtvflags [exec sh $flags_file --cxxvtvflags]
set cxxldflags [exec sh $flags_file --cxxldflags]
set cc [exec sh $flags_file --build-cc]
set includes [exec sh $flags_file --build-includes]
@@ -424,6 +437,7 @@ proc v3_target_compile { source dest type options } {
global wrap_flags
global cxx
global cxxflags
+ global cxxvtvflags
global cxxldflags
global includes
global STATIC_LIBCXXFLAGS
@@ -438,6 +452,7 @@ proc v3_target_compile { source dest type options } {
set cxx_final [concat $cxx_final $cxxlibglossflags]
set cxx_final [concat $cxx_final $STATIC_LIBCXXFLAGS]
set cxx_final [concat $cxx_final $cxxflags]
+ set cxx_final [concat $cxx_final $cxxvtvflags]
set cxx_final [concat $cxx_final $includes]
# Flag setting based on type argument.
diff --git a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
index 29e8ceafb05..6ca02aa4e1f 100644
--- a/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
+++ b/libstdc++-v3/testsuite/libstdc++-prettyprinters/cxx11.cc
@@ -1,5 +1,5 @@
// { dg-do run }
-// { dg-options "-std=gnu++11 -g" }
+// { dg-options "-std=gnu++11 -g -O0" }
// Copyright (C) 2011-2013 Free Software Foundation, Inc.
//
@@ -25,6 +25,8 @@
#include <memory>
#include <iostream>
+typedef std::tuple<int, int> ExTuple;
+
template<class T>
void
placeholder(const T &s)
@@ -63,43 +65,75 @@ main()
std::forward_list<int> efl;
// { dg-final { note-test efl "empty std::forward_list" } }
+ std::forward_list<int> &refl = efl;
+// { dg-final { note-test refl "empty std::forward_list" } }
+
std::forward_list<int> fl;
fl.push_front(2);
fl.push_front(1);
// { dg-final { note-test fl {std::forward_list = {[0] = 1, [1] = 2}} } }
+ std::forward_list<int> &rfl = fl;
+// { dg-final { note-test rfl {std::forward_list = {[0] = 1, [1] = 2}} } }
+
std::unordered_map<int, std::string> eum;
// { dg-final { note-test eum "std::unordered_map with 0 elements" } }
+ std::unordered_map<int, std::string> &reum = eum;
+// { dg-final { note-test reum "std::unordered_map with 0 elements" } }
+
std::unordered_multimap<int, std::string> eumm;
// { dg-final { note-test eumm "std::unordered_multimap with 0 elements" } }
+ std::unordered_multimap<int, std::string> &reumm = eumm;
+// { dg-final { note-test reumm "std::unordered_multimap with 0 elements" } }
+
std::unordered_set<int> eus;
// { dg-final { note-test eus "std::unordered_set with 0 elements" } }
+ std::unordered_set<int> &reus = eus;
+// { dg-final { note-test reus "std::unordered_set with 0 elements" } }
+
std::unordered_multiset<int> eums;
// { dg-final { note-test eums "std::unordered_multiset with 0 elements" } }
+ std::unordered_multiset<int> &reums = eums;
+// { dg-final { note-test reums "std::unordered_multiset with 0 elements" } }
std::unordered_map<int, std::string> uom;
uom[5] = "three";
uom[3] = "seven";
// { dg-final { note-test uom {std::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
+ std::unordered_map<int, std::string> &ruom = uom;
+// { dg-final { note-test ruom {std::unordered_map with 2 elements = {[3] = "seven", [5] = "three"}} } }
+
std::unordered_multimap<int, std::string> uomm;
uomm.insert(std::pair<int, std::string> (5, "three"));
uomm.insert(std::pair<int, std::string> (5, "seven"));
// { dg-final { note-test uomm {std::unordered_multimap with 2 elements = {[5] = "seven", [5] = "three"}} } }
+ std::unordered_multimap<int, std::string> &ruomm = uomm;
+// { dg-final { note-test ruomm {std::unordered_multimap with 2 elements = {[5] = "seven", [5] = "three"}} } }
std::unordered_set<int> uos;
uos.insert(5);
// { dg-final { note-test uos {std::unordered_set with 1 elements = {[0] = 5}} } }
+ std::unordered_set<int> &ruos = uos;
+// { dg-final { note-test ruos {std::unordered_set with 1 elements = {[0] = 5}} } }
std::unordered_multiset<int> uoms;
uoms.insert(5);
// { dg-final { note-test uoms {std::unordered_multiset with 1 elements = {[0] = 5}} } }
+ std::unordered_multiset<int> &ruoms = uoms;
+// { dg-final { note-test ruoms {std::unordered_multiset with 1 elements = {[0] = 5}} } }
std::unique_ptr<datum> uptr (new datum);
uptr->s = "hi bob";
uptr->i = 23;
// { dg-final { regexp-test uptr {std::unique_ptr.datum. containing 0x.*} } }
+ std::unique_ptr<datum> &ruptr = uptr;
+// { dg-final { regexp-test ruptr {std::unique_ptr.datum. containing 0x.*} } }
+ ExTuple tpl(6,7);
+// { dg-final { note-test tpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
+ ExTuple &rtpl = tpl;
+// { dg-final { note-test rtpl {std::tuple containing = {[1] = 6, [2] = 7}} } }
placeholder(""); // Mark SPOT
use(efl);
use(fl);
diff --git a/libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc b/libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc
new file mode 100644
index 00000000000..5775450925e
--- /dev/null
+++ b/libstdc++-v3/testsuite/tr1/8_c_compatibility/cmath/pow_cmath.cc
@@ -0,0 +1,33 @@
+// { dg-do compile }
+
+// Copyright (C) 2013 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+#include <cmath>
+using std::pow;
+#include <tr1/cmath>
+#include <testsuite_tr1.h>
+
+void
+test01()
+{
+ using namespace __gnu_test;
+
+ float x = 2080703.375F;
+ check_ret_type<float>(std::pow(x, 2));
+ check_ret_type<double>(std::tr1::pow(x, 2));
+}
diff --git a/libstdc++-v3/testsuite/util/debug/checks.h b/libstdc++-v3/testsuite/util/debug/checks.h
index 6ad39aded34..01c5beb5cd4 100644
--- a/libstdc++-v3/testsuite/util/debug/checks.h
+++ b/libstdc++-v3/testsuite/util/debug/checks.h
@@ -129,7 +129,7 @@ namespace __gnu_test
c2.assign(last, first); // Expected failure
}
- // Check that invalid range of debug !random debug iterators is detected
+ // Check that invalid range of debug not random iterators is detected
template<typename _Tp>
void
check_assign3()
@@ -377,6 +377,34 @@ namespace __gnu_test
}
template<typename _Tp>
+ void
+ check_insert4()
+ {
+ bool test __attribute__((unused)) = true;
+
+ typedef _Tp cont_type;
+ typedef typename cont_type::value_type cont_val_type;
+ typedef typename CopyableValueType<cont_val_type>::value_type val_type;
+ typedef std::list<val_type> list_type;
+
+ generate_unique<val_type> gu;
+
+ list_type l;
+ for (int i = 0; i != 5; ++i)
+ l.push_back(gu.build());
+ VERIFY(l.size() == 5);
+
+ typename list_type::iterator first = l.begin(); ++first;
+ typename list_type::iterator last = first; ++last; ++last;
+
+ cont_type c1;
+ InsertRangeHelper<cont_type>::Insert(c1, l.begin(), l.end());
+ VERIFY(c1.size() == 5);
+
+ c1.insert(c1.begin(), c1.begin(), c1.end()); // Expected failure.
+ }
+
+ template<typename _Tp>
void use_invalid_iterator()
{
bool test __attribute__((unused)) = true;
diff --git a/libstdc++-v3/testsuite/util/testsuite_common_types.h b/libstdc++-v3/testsuite/util/testsuite_common_types.h
index 54d6a753e36..12e3921aaf2 100644
--- a/libstdc++-v3/testsuite/util/testsuite_common_types.h
+++ b/libstdc++-v3/testsuite/util/testsuite_common_types.h
@@ -872,5 +872,22 @@ namespace __gnu_test
= &_Concept::__constraint;
}
};
+
+#if __cplusplus >= 201103L
+ // Generator to test lowering requirements for compare-and-exchange.
+ template<std::memory_order _Torder>
+ struct compare_exchange_order_lowering
+ {
+ template<typename _Tp>
+ void
+ operator()()
+ {
+ std::atomic<_Tp> __x;
+ _Tp __expected = 0;
+ __x.compare_exchange_strong(__expected, 1, _Torder);
+ __x.compare_exchange_weak(__expected, 1, _Torder);
+ }
+ };
+#endif
} // namespace __gnu_test
#endif
diff --git a/libvtv/ChangeLog b/libvtv/ChangeLog
new file mode 100644
index 00000000000..20092f4d0a3
--- /dev/null
+++ b/libvtv/ChangeLog
@@ -0,0 +1,193 @@
+2013-09-08 Caroline Tice <cmtice@google.com>
+
+ * testsuite/event-main.cc: Move to libvtv.cc subdirectory.
+ * testsuite/environment.cc: Ditto.
+ * testsuite/template-list2.cc: Ditto.
+ * testsuite/event.h: Ditto.
+ * testsuite/dataentry.cc: Ditto.
+ * testsuite/event-private.h: Ditto.
+ * testsuite/virtual_inheritance.cc: Ditto.
+ * testsuite/povray-derived.cc: Ditto.
+ * testsuite/nested_vcall_test.cc: Ditto.
+ * testsuite/template-list-iostream.cc: Ditto.
+ * testsuite/parts-test-extra-parts-views.h: Ditto.
+ * testsuite/virtfunc-test.cc: Ditto.
+ * testsuite/parts-test-extra-parts.h: Ditto.
+ * testsuite/const_vtable.cc: Ditto.
+ * testsuite/template-list.cc: Ditto.
+ * testsuite/dup_name.cc: Ditto.
+ * testsuite/thunk.cc: Ditto.
+ * testsuite/parts-test-main.h: Ditto.
+ * testsuite/mul_inh.cc: Ditto.
+ * testsuite/test1.cc: Ditto.
+ * testsuite/bb_tests.cc: Ditto.
+ * testsuite/v8-test-2.cc: Ditto.
+ * testsuite/thunk_vtable_map_attack.cc: Ditto.
+ * testsuite/xlan-test.cc: Ditto.
+ * testsuite/parts-test-main.cpp: Move to libvtv.cc subdirectory and
+ change file extension from .cc to .cpp.
+ * testsuite/event-definitions.cpp: Ditto.
+ * testsuite/event-main.cpp: Ditto.
+ * testsuite/derived-main.cpp: Ditto.
+ * testsuite/derived-lib.cpp: Ditto.
+ * testsuite/event-private.cpp: Ditto.
+ * testsuite/parts-test-extra-parts-views.cpp: Ditto.
+ * testsuite/parts-test-extra-parts.cpp: Ditto.
+ * testsuite/parts-test.list: Move to libvtv.cc subdirectory. Change
+ file extensions inside file from .cc to .cpp.
+ * testsuite/event.list: Ditto.
+ * testsuite/derived.list: Ditto.
+ * testsuite/register_pair.cc: Move to libvtv.cc; rename file to
+ register_set_pair.cc; include stdlib.h, stdio.h stdint.h string.h
+ (KEY_TYPE_FIXED_SIZE): New define.
+ (key_buffer, name_string, fake_names): New global variables.
+ (generate_names): New function.
+ (vtv_string_hans): New function.
+ (main): Add call to generate_names. Update middle for-loop to
+ initialize new parameters for __VLTRegisterPair... calls; move calls
+ to __VLTRegisterPair... to middle for-loop. Add calls to
+ __VLTRegisterSet...
+ * testsuite/register_pair_mt.cc: Ditto; renamed to
+ register_set_pair_mt.cc
+ * testsuite/libvtv.cc/vtv.exp: New file.
+ * testsuite/libvtv.mempool.cc/mempool.exp: New file.
+ * testsuite/libvtv.mt.cc/mt.exp: New file.
+ * testsuite/lib/libvtv.exp: New file.
+ * testsuite/lib/libvtv-dg.exp: New file.
+ * testsuite/config/default.exp: New file.
+ * testsuite/Makefile.am: New file. (Old file was moved to other-tests
+ subdirectory.)
+ * testsuite/Makefile.in: New file (generated).
+ * testsuite/mempool_negative.c: Change to C++ file; move to
+ libvtv.mempool.cc; include vtv-change-permission.h.
+ (main): Add call to __VLTChangePermission.
+ * testsuite/mempool_positive.c: Change to C++ file; move to
+ libvtv.mempool.cc; include vtv-change-permission.h.
+ (main): Add call to __VLTChangePermission.
+ * testsuite/temp_deriv3.cc: Move to other-tests subdirectory.
+ * testsuite/environment-fail-64.s: Ditto.
+ * testsutite/dlopen.cc: Ditto.
+ * testsuite/so.cc: Ditto.
+ * testsuite/temp_deriv2.cc: Ditto.
+ * testsuite/field-test.cc: Ditto.
+ * testsuite/dlopen_mt.cc: Ditto.
+ * testsuite/environment-fail-32.s: Ditto.
+ * testsuite/temp_deriv.cc: Ditto.
+ * testsuite/replace-fail.cc: Ditto.
+ * testsuite/other-tests/Makefile.am: New file. Copied from the
+ Makefile.am that used to be in testsuite directory.
+ * testsuite/other-tests/Makefile.in: Generated. (New file).
+ * testsuite/other-tests/README: New file.
+
+2013-09-07 Paolo Carlini <paolo.carlini@oracle.com>
+
+ * testsuite/Makefile.am: Remove #if ENABLE_VTABLE_VERIFY check around
+ definition of check-am:.
+ * testsuite/Makefile.in: Regenerate.
+
+2013-09-06 Caroline Tice <cmtice@google.com>
+
+ * Makefile.am: Remove #if ENABLE_VTABLE_VERIFY checks around
+ definitions of SUBDIRS, libvtv_la_SOURCES and libvtv_include_HEADERS.
+ * Makefile.in: Regenerate.
+ * configure.ac: Remove checks and tests for --enable-vtable-verify.
+ * configure: Regenerate.
+
+2013-08-20 Caroline Tice <cmtice@google.com>
+
+ * Makefile.am (DEFS): Add "@DEFS@", to inherit defintions.
+ * Makefile.in: Regenerate.
+ * configure.ac: Add check for __secure_getenv and secure_getenv.
+ * configure: Regenerate.
+ * vtv_utils.cc : Include stdlib.h
+ (HAVE_SECURE_GETENV): Add checks and definitions for secure_getenv.
+ (log_dirs): Remove file static constant.
+ (__vtv_open_log): Increase size of log file name. Add the user
+ and process ids to the file name. Do not put the log files in /tmp.
+ Instead try to get the directory name from an environment variable; if
+ that fails try to use stderr. Add O_NOFOLLOW to the flags
+ for 'open'. Update function comment.
+ * vtv_rts.cc (log_memory_protection_data): Remove %d from file name.
+
+2013-08-08 Benjamin Kosnik <bkoz@rehat.com>
+ Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * configure.tgt : Simplify, just use VTV_SUPPORTED.
+
+2013-08-07 Benjamin Kosnik <bkoz@rehat.com>
+
+ * Makefile.am (SUBDIRS): Protect with ENABLE_VTABLE_VERIFY.
+ * Makefile.in: Regenerate.
+ * acinclude.m4 (LIBVTV_CONFIGURE): Move parts to..
+ * configure.ac: ...here. Make configure more verbose, re-order.
+ * configure: Regenerate.
+
+2013-08-02 Caroline Tice <cmtice@google.com>
+ Benjamin Kosnik <bkoz@redhat.com>
+ Luis Lozano <llozano@google.com>
+ Geoff Pike <gpike@google.com>
+
+ Initial check-in of new vtable verification feature.
+ * configure.ac : New file.
+ * acinclude.m4 : New file.
+ * Makefile.am : New file.
+ * aclocal.m4 : New file.
+ * configure.tgt : New file.
+ * configure: New file (generated).
+ * Makefile.in: New file (generated).
+ * vtv_set.h : New file.
+ * vtv_utils.cc : New file.
+ * vtv_utils.h : New file.
+ * vtv_malloc.cc : New file.
+ * vtv_rts.cc : New file.
+ * vtv_malloc.h : New file.
+ * vtv_rts.h : New file.
+ * vtv_fail.cc : New file.
+ * vtv_fail.h : New file.
+ * vtv_map.h : New file.
+ * scripts/run-testsuite.sh : New file.
+ * scripts/sum-vtv-counts.c : New file.
+ * testsuite/parts-test-main.h : New file.
+ * testusite/dataentry.cc : New file.
+ * testsuite/temp_deriv.cc : New file.
+ * testsuite/register_pair.cc : New file.
+ * testsuite/virtual_inheritance.cc : New file.
+ * testsuite/field-test.cc : New file.
+ * testsuite/nested_vcall_test.cc : New file.
+ * testsuite/template-list-iostream.cc : New file.
+ * testsuite/register_pair_inserts.cc : New file.
+ * testsuite/register_pair_inserts_mt.cc : New file.
+ * testsuite/event.list : New file.
+ * testsuite/parts-test-extra-parts-views.cc : New file.
+ * testsuite/parts-test-extra-parts-views.h : New file.
+ * testsuite/environment-fail-32.s : New file.
+ * testsuite/parts-test-extra-parts.h : New file.
+ * testsuite/temp_deriv2.cc : New file.
+ * testsuite/dlopen_mt.cc : New file.
+ * testsuite/event.h : New file.
+ * testsuite/template-list.cc : New file.
+ * testsuite/replace-fail.cc : New file.
+ * testsuite/Makefile.am : New file.
+ * testsuite/Makefile.in: New file (generated).
+ * testsuite/mempool_negative.c : New file.
+ * testsuite/parts-test-main.cc : New file.
+ * testsuite/event-private.cc : New file.
+ * testsuite/thunk.cc : New file.
+ * testsuite/event-defintiions.cc : New file.
+ * testsuite/event-private.h : New file.
+ * testsuite/parts-test.list : New file.
+ * testusite/register_pair_mt.cc : New file.
+ * testsuite/povray-derived.cc : New file.
+ * testsuite/event-main.cc : New file.
+ * testsuite/environment.cc : New file.
+ * testsuite/template-list2.cc : New file.
+ * testsuite/thunk_vtable_map_attack.cc : New file.
+ * testsuite/parts-test-extra-parts.cc : New file.
+ * testsuite/environment-fail-64.s : New file.
+ * testsuite/dlopen.cc : New file.
+ * testsuite/so.cc : New file.
+ * testsuite/temp_deriv3.cc : New file.
+ * testsuite/const_vtable.cc : New file.
+ * testsuite/mempool_positive.c : New file.
+ * testsuite/dup_name.cc : New file.
+
diff --git a/libvtv/Makefile.am b/libvtv/Makefile.am
new file mode 100644
index 00000000000..c3983effb7d
--- /dev/null
+++ b/libvtv/Makefile.am
@@ -0,0 +1,78 @@
+## Makefile for the VTV library.
+##
+## Copyright (C) 2013 Free Software Foundation, Inc.
+##
+## Process this file with automake to produce Makefile.in.
+##
+## This file is part of the Vtable Verification (VTV) 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/>.
+
+SUBDIRS = testsuite
+
+ACLOCAL_AMFLAGS = -I .. -I ../config
+
+# May be used by toolexeclibdir.
+gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
+
+DEFS = @DEFS@
+AM_CPPFLAGS = -I$(top_srcdir)/../include
+AM_CFLAGS = $(XCFLAGS)
+AM_CCASFLAGS = $(XCFLAGS)
+AM_CXXFLAGS = $(XCFLAGS)
+AM_CXXFLAGS += $(LIBSTDCXX_RAW_CXX_CXXFLAGS)
+AM_CXXFLAGS += -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end
+
+toolexeclib_LTLIBRARIES = libvtv.la
+
+vtv_headers = \
+ vtv_map.h \
+ vtv_malloc.h \
+ vtv_fail.h \
+ vtv_set.h \
+ vtv_utils.h \
+ vtv_rts.h
+
+vtv_sources = \
+ vtv_start.c \
+ vtv_malloc.cc \
+ vtv_rts.cc \
+ vtv_utils.cc \
+ vtv_end.c
+
+libvtv_includedir = $(includedir)
+
+# Link in vtv_start and vtv_end.
+BUILT_SOURCES = vtv_start.c vtv_end.c
+vtv_start.c:
+ rm -f $@
+ $(LN_S) $(toplevel_srcdir)/libgcc/vtv_start.c $@
+
+vtv_end.c:
+ rm -f $@
+ $(LN_S) $(toplevel_srcdir)/libgcc/vtv_end.c $@
+
+libvtv_la_SOURCES = $(vtv_sources)
+libvtv_include_HEADERS = $(vtv_headers)
+
+# Least ordering for dependencies mean linking w/o libstdc++ for as
+# long as the development of libvtv does not absolutely require it.
+CXXVTV=$(CC_FOR_TARGET)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXXVTV) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXVTV) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
diff --git a/libvtv/Makefile.in b/libvtv/Makefile.in
new file mode 100644
index 00000000000..e021d42fd14
--- /dev/null
+++ b/libvtv/Makefile.in
@@ -0,0 +1,762 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = .
+DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/../mkinstalldirs $(srcdir)/../depcomp \
+ $(libvtv_include_HEADERS)
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/depstand.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/libstdc++-raw-cxx.m4 \
+ $(top_srcdir)/../config/multi.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno config.status.lineno
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
+am__install_max = 40
+am__nobase_strip_setup = \
+ srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
+am__nobase_strip = \
+ for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
+am__nobase_list = $(am__nobase_strip_setup); \
+ for p in $$list; do echo "$$p $$p"; done | \
+ sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
+ $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
+ if (++n[$$2] == $(am__install_max)) \
+ { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
+ END { for (dir in files) print dir, files[dir] }'
+am__base_list = \
+ sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
+ sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__installdirs = "$(DESTDIR)$(toolexeclibdir)" \
+ "$(DESTDIR)$(libvtv_includedir)"
+LTLIBRARIES = $(toolexeclib_LTLIBRARIES)
+libvtv_la_LIBADD =
+am__objects_1 = vtv_start.lo vtv_malloc.lo vtv_rts.lo vtv_utils.lo \
+ vtv_end.lo
+am_libvtv_la_OBJECTS = $(am__objects_1)
+libvtv_la_OBJECTS = $(am_libvtv_la_OBJECTS)
+DEFAULT_INCLUDES = -I.@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/../depcomp
+am__depfiles_maybe = depfiles
+am__mv = mv -f
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+CXXLD = $(CXX)
+SOURCES = $(libvtv_la_SOURCES)
+MULTISRCTOP =
+MULTIBUILDTOP =
+MULTIDIRS =
+MULTISUBDIR =
+MULTIDO = true
+MULTICLEAN = true
+RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
+ html-recursive info-recursive install-data-recursive \
+ install-dvi-recursive install-exec-recursive \
+ install-html-recursive install-info-recursive \
+ install-pdf-recursive install-ps-recursive install-recursive \
+ installcheck-recursive installdirs-recursive pdf-recursive \
+ ps-recursive uninstall-recursive
+HEADERS = $(libvtv_include_HEADERS)
+RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
+ distclean-recursive maintainer-clean-recursive
+AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
+ETAGS = etags
+CTAGS = ctags
+DIST_SUBDIRS = $(SUBDIRS)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX_RAW_CXX_CXXFLAGS = @LIBSTDCXX_RAW_CXX_CXXFLAGS@
+LIBSTDCXX_RAW_CXX_LDFLAGS = @LIBSTDCXX_RAW_CXX_LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XCFLAGS = @XCFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libtool_VERSION = @libtool_VERSION@
+libvtv_builddir = @libvtv_builddir@
+libvtv_srcdir = @libvtv_srcdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+multi_basedir = @multi_basedir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_noncanonical = @target_noncanonical@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+toplevel_builddir = @toplevel_builddir@
+toplevel_srcdir = @toplevel_srcdir@
+SUBDIRS = testsuite
+ACLOCAL_AMFLAGS = -I .. -I ../config
+
+# May be used by toolexeclibdir.
+gcc_version := $(shell cat $(top_srcdir)/../gcc/BASE-VER)
+AM_CPPFLAGS = -I$(top_srcdir)/../include
+AM_CFLAGS = $(XCFLAGS)
+AM_CCASFLAGS = $(XCFLAGS)
+AM_CXXFLAGS = $(XCFLAGS) $(LIBSTDCXX_RAW_CXX_CXXFLAGS) \
+ -Wl,-u_vtable_map_vars_start,-u_vtable_map_vars_end
+toolexeclib_LTLIBRARIES = libvtv.la
+vtv_headers = \
+ vtv_map.h \
+ vtv_malloc.h \
+ vtv_fail.h \
+ vtv_set.h \
+ vtv_utils.h \
+ vtv_rts.h
+
+vtv_sources = \
+ vtv_start.c \
+ vtv_malloc.cc \
+ vtv_rts.cc \
+ vtv_utils.cc \
+ vtv_end.c
+
+libvtv_includedir = $(includedir)
+
+# Link in vtv_start and vtv_end.
+BUILT_SOURCES = vtv_start.c vtv_end.c
+libvtv_la_SOURCES = $(vtv_sources)
+libvtv_include_HEADERS = $(vtv_headers)
+
+# Least ordering for dependencies mean linking w/o libstdc++ for as
+# long as the development of libvtv does not absolutely require it.
+CXXVTV = $(CC_FOR_TARGET)
+LTCXXCOMPILE = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CXXVTV) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
+
+CXXLINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CXXVTV) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+
+all: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) all-recursive
+
+.SUFFIXES:
+.SUFFIXES: .c .cc .lo .o .obj
+am--refresh:
+ @:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
+ $(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign ./Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign ./Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ echo ' $(SHELL) ./config.status'; \
+ $(SHELL) ./config.status;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ $(am__cd) $(srcdir) && $(AUTOCONF)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ $(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
+$(am__aclocal_m4_deps):
+install-toolexeclibLTLIBRARIES: $(toolexeclib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(toolexeclibdir)" || $(MKDIR_P) "$(DESTDIR)$(toolexeclibdir)"
+ @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(toolexeclibdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(toolexeclibdir)"; \
+ }
+
+uninstall-toolexeclibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(toolexeclib_LTLIBRARIES)'; test -n "$(toolexeclibdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(toolexeclibdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(toolexeclibdir)/$$f"; \
+ done
+
+clean-toolexeclibLTLIBRARIES:
+ -test -z "$(toolexeclib_LTLIBRARIES)" || rm -f $(toolexeclib_LTLIBRARIES)
+ @list='$(toolexeclib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+libvtv.la: $(libvtv_la_OBJECTS) $(libvtv_la_DEPENDENCIES)
+ $(CXXLINK) -rpath $(toolexeclibdir) $(libvtv_la_OBJECTS) $(libvtv_la_LIBADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_end.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_malloc.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_rts.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_start.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vtv_utils.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+.cc.o:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ $<
+
+.cc.obj:
+@am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.cc.lo:
+@am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCXX_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+ -rm -f libtool config.lt
+
+# GNU Make needs to see an explicit $(MAKE) variable in the command it
+# runs to enable its job server during parallel builds. Hence the
+# comments below.
+all-multi:
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=all multi-do # $(MAKE)
+install-multi:
+ $(MULTIDO) $(AM_MAKEFLAGS) DO=install multi-do # $(MAKE)
+
+mostlyclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=mostlyclean multi-clean # $(MAKE)
+clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=clean multi-clean # $(MAKE)
+distclean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=distclean multi-clean # $(MAKE)
+maintainer-clean-multi:
+ $(MULTICLEAN) $(AM_MAKEFLAGS) DO=maintainer-clean multi-clean # $(MAKE)
+install-libvtv_includeHEADERS: $(libvtv_include_HEADERS)
+ @$(NORMAL_INSTALL)
+ test -z "$(libvtv_includedir)" || $(MKDIR_P) "$(DESTDIR)$(libvtv_includedir)"
+ @list='$(libvtv_include_HEADERS)'; test -n "$(libvtv_includedir)" || list=; \
+ for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ echo "$$d$$p"; \
+ done | $(am__base_list) | \
+ while read files; do \
+ echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libvtv_includedir)'"; \
+ $(INSTALL_HEADER) $$files "$(DESTDIR)$(libvtv_includedir)" || exit $$?; \
+ done
+
+uninstall-libvtv_includeHEADERS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libvtv_include_HEADERS)'; test -n "$(libvtv_includedir)" || list=; \
+ files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
+ test -n "$$files" || exit 0; \
+ echo " ( cd '$(DESTDIR)$(libvtv_includedir)' && rm -f" $$files ")"; \
+ cd "$(DESTDIR)$(libvtv_includedir)" && rm -f $$files
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+$(RECURSIVE_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+$(RECURSIVE_CLEAN_TARGETS):
+ @fail= failcom='exit 1'; \
+ for f in x $$MAKEFLAGS; do \
+ case $$f in \
+ *=* | --[!k]*);; \
+ *k*) failcom='fail=yes';; \
+ esac; \
+ done; \
+ dot_seen=no; \
+ case "$@" in \
+ distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
+ *) list='$(SUBDIRS)' ;; \
+ esac; \
+ rev=''; for subdir in $$list; do \
+ if test "$$subdir" = "."; then :; else \
+ rev="$$subdir $$rev"; \
+ fi; \
+ done; \
+ rev="$$rev ."; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || eval $$failcom; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+ctags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ set x; \
+ here=`pwd`; \
+ if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
+ include_option=--etags-include; \
+ empty_fix=.; \
+ else \
+ include_option=--include; \
+ empty_fix=; \
+ fi; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test ! -f $$subdir/TAGS || \
+ set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ shift; \
+ if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ if test $$# -gt 0; then \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ "$$@" $$unique; \
+ else \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$unique; \
+ fi; \
+ fi
+ctags: CTAGS
+CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
+ END { if (nonempty) { for (i in files) print i; }; }'`; \
+ test -z "$(CTAGS_ARGS)$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && $(am__cd) $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) "$$here"
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+check-am: all-am
+check: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) check-recursive
+all-am: Makefile $(LTLIBRARIES) all-multi $(HEADERS)
+installdirs: installdirs-recursive
+installdirs-am:
+ for dir in "$(DESTDIR)$(toolexeclibdir)" "$(DESTDIR)$(libvtv_includedir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: $(BUILT_SOURCES)
+ $(MAKE) $(AM_MAKEFLAGS) install-recursive
+install-exec: install-exec-recursive
+install-data: install-data-recursive
+uninstall: uninstall-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+ -test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
+clean: clean-multi clean-recursive
+
+clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-multi distclean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-libtool distclean-tags
+
+dvi: dvi-recursive
+
+dvi-am:
+
+html: html-recursive
+
+html-am:
+
+info: info-recursive
+
+info-am:
+
+install-data-am: install-libvtv_includeHEADERS
+
+install-dvi: install-dvi-recursive
+
+install-dvi-am:
+
+install-exec-am: install-multi install-toolexeclibLTLIBRARIES
+
+install-html: install-html-recursive
+
+install-html-am:
+
+install-info: install-info-recursive
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-recursive
+
+install-pdf-am:
+
+install-ps: install-ps-recursive
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-multi maintainer-clean-recursive
+ -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+ -rm -rf $(top_srcdir)/autom4te.cache
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-multi mostlyclean-recursive
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-recursive
+
+pdf-am:
+
+ps: ps-recursive
+
+ps-am:
+
+uninstall-am: uninstall-libvtv_includeHEADERS \
+ uninstall-toolexeclibLTLIBRARIES
+
+.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) all all-multi \
+ check clean-multi ctags-recursive distclean-multi install \
+ install-am install-multi install-strip maintainer-clean-multi \
+ mostlyclean-multi tags-recursive
+
+.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
+ all all-am all-multi am--refresh check check-am clean \
+ clean-generic clean-libtool clean-multi \
+ clean-toolexeclibLTLIBRARIES ctags ctags-recursive distclean \
+ distclean-compile distclean-generic distclean-libtool \
+ distclean-multi distclean-tags dvi dvi-am html html-am info \
+ info-am install install-am install-data install-data-am \
+ install-dvi install-dvi-am install-exec install-exec-am \
+ install-html install-html-am install-info install-info-am \
+ install-libvtv_includeHEADERS install-man install-multi \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip install-toolexeclibLTLIBRARIES installcheck \
+ installcheck-am installdirs installdirs-am maintainer-clean \
+ maintainer-clean-generic maintainer-clean-multi mostlyclean \
+ mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+ mostlyclean-multi pdf pdf-am ps ps-am tags tags-recursive \
+ uninstall uninstall-am uninstall-libvtv_includeHEADERS \
+ uninstall-toolexeclibLTLIBRARIES
+
+vtv_start.c:
+ rm -f $@
+ $(LN_S) $(toplevel_srcdir)/libgcc/vtv_start.c $@
+
+vtv_end.c:
+ rm -f $@
+ $(LN_S) $(toplevel_srcdir)/libgcc/vtv_end.c $@
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libvtv/acinclude.m4 b/libvtv/acinclude.m4
new file mode 100644
index 00000000000..53e62d24c11
--- /dev/null
+++ b/libvtv/acinclude.m4
@@ -0,0 +1,47 @@
+dnl ----------------------------------------------------------------------
+dnl This whole bit snagged from libgfortran.
+
+sinclude(../libtool.m4)
+dnl The lines below arrange for aclocal not to bring an installed
+dnl libtool.m4 into aclocal.m4, while still arranging for automake to
+dnl add a definition of LIBTOOL to Makefile.in.
+ifelse(,,,[AC_SUBST(LIBTOOL)
+AC_DEFUN([AM_PROG_LIBTOOL])
+])
+
+
+
+dnl
+dnl Initialize the rest of the library configury. At this point we have
+dnl variables like $host.
+dnl
+dnl Substs:
+dnl libvtv_builddir (absolute path)
+dnl libvtv_srcdir (absolute path)
+dnl toplevel_builddir (absolute path)
+dnl toplevel_srcdir (absolute path)
+dnl with_cross_host
+dnl with_newlib
+dnl with_target_subdir
+dnl plus
+dnl - the variables in LIBVTV_CHECK_HOST / configure.host
+dnl - default settings for all AM_CONDITIONAL test variables
+dnl - lots of tools, like CC and CXX
+dnl
+AC_DEFUN([LIBVTV_CONFIGURE], [
+
+ # These need to be absolute paths, yet at the same time need to
+ # canonicalize only relative paths, because then amd will not unmount
+ # drives. Thus the use of PWDCMD: set it to 'pawd' or 'amq -w' if using amd.
+ libvtv_builddir=`${PWDCMD-pwd}`
+ case $srcdir in
+ [\\/$]* | ?:[\\/]*) libvtv_srcdir=${srcdir} ;;
+ *) libvtv_srcdir=`cd "$srcdir" && ${PWDCMD-pwd} || echo "$srcdir"` ;;
+ esac
+ toplevel_builddir=${libvtv_builddir}/..
+ toplevel_srcdir=${libvtv_srcdir}/..
+ AC_SUBST(libvtv_builddir)
+ AC_SUBST(libvtv_srcdir)
+ AC_SUBST(toplevel_builddir)
+ AC_SUBST(toplevel_srcdir)
+])
diff --git a/libvtv/aclocal.m4 b/libvtv/aclocal.m4
new file mode 100644
index 00000000000..5478f2b7df7
--- /dev/null
+++ b/libvtv/aclocal.m4
@@ -0,0 +1,1016 @@
+# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
+[m4_warning([this file was generated for autoconf 2.64.
+You have another version of autoconf. It may work, but is not guaranteed to.
+If you have problems, you may need to regenerate the build system entirely.
+To do so, use the procedure documented by the package, typically `autoreconf'.])])
+
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_AUTOMAKE_VERSION(VERSION)
+# ----------------------------
+# Automake X.Y traces this macro to ensure aclocal.m4 has been
+# generated from the m4 files accompanying Automake X.Y.
+# (This private macro should not be called outside this file.)
+AC_DEFUN([AM_AUTOMAKE_VERSION],
+[am__api_version='1.11'
+dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
+dnl require some minimum version. Point them to the right macro.
+m4_if([$1], [1.11.1], [],
+ [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
+])
+
+# _AM_AUTOCONF_VERSION(VERSION)
+# -----------------------------
+# aclocal traces this macro to find the Autoconf version.
+# This is a private macro too. Using m4_define simplifies
+# the logic in aclocal, which can simply ignore this definition.
+m4_define([_AM_AUTOCONF_VERSION], [])
+
+# AM_SET_CURRENT_AUTOMAKE_VERSION
+# -------------------------------
+# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
+# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
+AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
+[AM_AUTOMAKE_VERSION([1.11.1])dnl
+m4_ifndef([AC_AUTOCONF_VERSION],
+ [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
+_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
+
+# AM_AUX_DIR_EXPAND -*- Autoconf -*-
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
+# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
+# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
+#
+# Of course, Automake must honor this variable whenever it calls a
+# tool from the auxiliary directory. The problem is that $srcdir (and
+# therefore $ac_aux_dir as well) can be either absolute or relative,
+# depending on how configure is run. This is pretty annoying, since
+# it makes $ac_aux_dir quite unusable in subdirectories: in the top
+# source directory, any form will work fine, but in subdirectories a
+# relative path needs to be adjusted first.
+#
+# $ac_aux_dir/missing
+# fails when called from a subdirectory if $ac_aux_dir is relative
+# $top_srcdir/$ac_aux_dir/missing
+# fails if $ac_aux_dir is absolute,
+# fails when called from a subdirectory in a VPATH build with
+# a relative $ac_aux_dir
+#
+# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
+# are both prefixed by $srcdir. In an in-source build this is usually
+# harmless because $srcdir is `.', but things will broke when you
+# start a VPATH build or use an absolute $srcdir.
+#
+# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
+# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
+# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
+# and then we would define $MISSING as
+# MISSING="\${SHELL} $am_aux_dir/missing"
+# This will work as long as MISSING is not called from configure, because
+# unfortunately $(top_srcdir) has no meaning in configure.
+# However there are other variables, like CC, which are often used in
+# configure, and could therefore not use this "fixed" $ac_aux_dir.
+#
+# Another solution, used here, is to always expand $ac_aux_dir to an
+# absolute PATH. The drawback is that using absolute paths prevent a
+# configured tree to be moved without reconfiguration.
+
+AC_DEFUN([AM_AUX_DIR_EXPAND],
+[dnl Rely on autoconf to set up CDPATH properly.
+AC_PREREQ([2.50])dnl
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+])
+
+# AM_CONDITIONAL -*- Autoconf -*-
+
+# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 9
+
+# AM_CONDITIONAL(NAME, SHELL-CONDITION)
+# -------------------------------------
+# Define a conditional.
+AC_DEFUN([AM_CONDITIONAL],
+[AC_PREREQ(2.52)dnl
+ ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
+ [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
+AC_SUBST([$1_TRUE])dnl
+AC_SUBST([$1_FALSE])dnl
+_AM_SUBST_NOTMAKE([$1_TRUE])dnl
+_AM_SUBST_NOTMAKE([$1_FALSE])dnl
+m4_define([_AM_COND_VALUE_$1], [$2])dnl
+if $2; then
+ $1_TRUE=
+ $1_FALSE='#'
+else
+ $1_TRUE='#'
+ $1_FALSE=
+fi
+AC_CONFIG_COMMANDS_PRE(
+[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
+ AC_MSG_ERROR([[conditional "$1" was never defined.
+Usually this means the macro was only invoked conditionally.]])
+fi])])
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 10
+
+# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
+# written in clear, in which case automake, when reading aclocal.m4,
+# will think it sees a *use*, and therefore will trigger all it's
+# C support machinery. Also note that it means that autoscan, seeing
+# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
+
+
+# _AM_DEPENDENCIES(NAME)
+# ----------------------
+# See how the compiler implements dependency checking.
+# NAME is "CC", "CXX", "GCJ", or "OBJC".
+# We try a few techniques and use that to set a single cache variable.
+#
+# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
+# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
+# dependency, and given that the user is not expected to run this macro,
+# just rely on AC_PROG_CC.
+AC_DEFUN([_AM_DEPENDENCIES],
+[AC_REQUIRE([AM_SET_DEPDIR])dnl
+AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
+AC_REQUIRE([AM_MAKE_INCLUDE])dnl
+AC_REQUIRE([AM_DEP_TRACK])dnl
+
+ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
+ [$1], CXX, [depcc="$CXX" am_compiler_list=],
+ [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
+ [$1], UPC, [depcc="$UPC" am_compiler_list=],
+ [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
+ [depcc="$$1" am_compiler_list=])
+
+AC_CACHE_CHECK([dependency style of $depcc],
+ [am_cv_$1_dependencies_compiler_type],
+[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'.
+ 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_$1_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
+ m4_case([$1], [CC],
+ [case " $depcc " in #(
+ *\ -arch\ *\ -arch\ *) am__universal=true ;;
+ esac],
+ [CXX],
+ [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
+ ;;
+ 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_$1_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_$1_dependencies_compiler_type=none
+fi
+])
+AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
+AM_CONDITIONAL([am__fastdep$1], [
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
+])
+
+
+# AM_SET_DEPDIR
+# -------------
+# Choose a directory name for dependency files.
+# This macro is AC_REQUIREd in _AM_DEPENDENCIES
+AC_DEFUN([AM_SET_DEPDIR],
+[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
+])
+
+
+# AM_DEP_TRACK
+# ------------
+AC_DEFUN([AM_DEP_TRACK],
+[AC_ARG_ENABLE(dependency-tracking,
+[ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors])
+if test "x$enable_dependency_tracking" != xno; then
+ am_depcomp="$ac_aux_dir/depcomp"
+ AMDEPBACKSLASH='\'
+fi
+AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
+AC_SUBST([AMDEPBACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+])
+
+# Generate code to set up dependency tracking. -*- Autoconf -*-
+
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+#serial 5
+
+# _AM_OUTPUT_DEPENDENCY_COMMANDS
+# ------------------------------
+AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
+[{
+ # 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
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`AS_DIRNAME("$mf")`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`AS_DIRNAME(["$file"])`
+ AS_MKDIR_P([$dirpart/$fdir])
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+])# _AM_OUTPUT_DEPENDENCY_COMMANDS
+
+
+# AM_OUTPUT_DEPENDENCY_COMMANDS
+# -----------------------------
+# This macro should only be invoked once -- use via AC_REQUIRE.
+#
+# This code is only required when automatic dependency tracking
+# is enabled. FIXME. This creates each `.P' file that we will
+# need in order to bootstrap the dependency handling code.
+AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
+[AC_CONFIG_COMMANDS([depfiles],
+ [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
+ [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
+])
+
+# Do all the work for Automake. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
+# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 16
+
+# This macro actually does too much. Some checks are only needed if
+# your package does certain things. But this isn't really a big deal.
+
+# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
+# AM_INIT_AUTOMAKE([OPTIONS])
+# -----------------------------------------------
+# The call with PACKAGE and VERSION arguments is the old style
+# call (pre autoconf-2.50), which is being phased out. PACKAGE
+# and VERSION should now be passed to AC_INIT and removed from
+# the call to AM_INIT_AUTOMAKE.
+# We support both call styles for the transition. After
+# the next Automake release, Autoconf can make the AC_INIT
+# arguments mandatory, and then we can depend on a new Autoconf
+# release and drop the old call support.
+AC_DEFUN([AM_INIT_AUTOMAKE],
+[AC_PREREQ([2.62])dnl
+dnl Autoconf wants to disallow AM_ names. We explicitly allow
+dnl the ones we care about.
+m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
+AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
+AC_REQUIRE([AC_PROG_INSTALL])dnl
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+AC_SUBST([CYGPATH_W])
+
+# Define the identity of the package.
+dnl Distinguish between old-style and new-style calls.
+m4_ifval([$2],
+[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
+ AC_SUBST([PACKAGE], [$1])dnl
+ AC_SUBST([VERSION], [$2])],
+[_AM_SET_OPTIONS([$1])dnl
+dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
+m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
+ [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
+ AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
+ AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
+
+_AM_IF_OPTION([no-define],,
+[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+ AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
+
+# Some tools Automake needs.
+AC_REQUIRE([AM_SANITY_CHECK])dnl
+AC_REQUIRE([AC_ARG_PROGRAM])dnl
+AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
+AM_MISSING_PROG(AUTOCONF, autoconf)
+AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
+AM_MISSING_PROG(AUTOHEADER, autoheader)
+AM_MISSING_PROG(MAKEINFO, makeinfo)
+AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
+AC_REQUIRE([AM_PROG_MKDIR_P])dnl
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+AC_REQUIRE([AC_PROG_AWK])dnl
+AC_REQUIRE([AC_PROG_MAKE_SET])dnl
+AC_REQUIRE([AM_SET_LEADING_DOT])dnl
+_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
+ [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
+ [_AM_PROG_TAR([v7])])])
+_AM_IF_OPTION([no-dependencies],,
+[AC_PROVIDE_IFELSE([AC_PROG_CC],
+ [_AM_DEPENDENCIES(CC)],
+ [define([AC_PROG_CC],
+ defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_CXX],
+ [_AM_DEPENDENCIES(CXX)],
+ [define([AC_PROG_CXX],
+ defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
+AC_PROVIDE_IFELSE([AC_PROG_OBJC],
+ [_AM_DEPENDENCIES(OBJC)],
+ [define([AC_PROG_OBJC],
+ defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
+])
+_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
+dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
+dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
+dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
+AC_CONFIG_COMMANDS_PRE(dnl
+[m4_provide_if([_AM_COMPILER_EXEEXT],
+ [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
+])
+
+dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
+dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
+dnl mangled by Autoconf and run in a shell conditional statement.
+m4_define([_AC_COMPILER_EXEEXT],
+m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
+
+
+# When config.status generates a header, we must update the stamp-h file.
+# This file resides in the same directory as the config header
+# that is generated. The stamp files are numbered to have different names.
+
+# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
+# loop where config.status creates the headers, so we can generate
+# our stamp files there.
+AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
+[# Compute $1's index in $config_headers.
+_am_arg=$1
+_am_stamp_count=1
+for _am_header in $config_headers :; do
+ case $_am_header in
+ $_am_arg | $_am_arg:* )
+ break ;;
+ * )
+ _am_stamp_count=`expr $_am_stamp_count + 1` ;;
+ esac
+done
+echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
+
+# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_SH
+# ------------------
+# Define $install_sh.
+AC_DEFUN([AM_PROG_INSTALL_SH],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+AC_SUBST(install_sh)])
+
+# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_MAINTAINER_MODE([DEFAULT-MODE])
+# ----------------------------------
+# Control maintainer-specific portions of Makefiles.
+# Default is to disable them, unless `enable' is passed literally.
+# For symmetry, `disable' may be passed as well. Anyway, the user
+# can override the default with the --enable/--disable switch.
+AC_DEFUN([AM_MAINTAINER_MODE],
+[m4_case(m4_default([$1], [disable]),
+ [enable], [m4_define([am_maintainer_other], [disable])],
+ [disable], [m4_define([am_maintainer_other], [enable])],
+ [m4_define([am_maintainer_other], [enable])
+ m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
+AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+ dnl maintainer-mode's default is 'disable' unless 'enable' is passed
+ AC_ARG_ENABLE([maintainer-mode],
+[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer],
+ [USE_MAINTAINER_MODE=$enableval],
+ [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
+ AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+ AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
+ MAINT=$MAINTAINER_MODE_TRUE
+ AC_SUBST([MAINT])dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
+# Check to see how 'make' treats includes. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# AM_MAKE_INCLUDE()
+# -----------------
+# Check to see how make treats includes.
+AC_DEFUN([AM_MAKE_INCLUDE],
+[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.
+AC_MSG_CHECKING([for style of include used by $am_make])
+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
+AC_SUBST([am__include])
+AC_SUBST([am__quote])
+AC_MSG_RESULT([$_am_result])
+rm -f confinc confmf
+])
+
+# Copyright (C) 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_PROG_CC_C_O
+# --------------
+# Like AC_PROG_CC_C_O, but changed for automake.
+AC_DEFUN([AM_PROG_CC_C_O],
+[AC_REQUIRE([AC_PROG_CC_C_O])dnl
+AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([compile])dnl
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $[2] | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+dnl Make sure AC_PROG_CC is never called again, or it will override our
+dnl setting of CC.
+m4_define([AC_PROG_CC],
+ [m4_fatal([AC_PROG_CC cannot be called after AM_PROG_CC_C_O])])
+])
+
+# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
+
+# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 6
+
+# AM_MISSING_PROG(NAME, PROGRAM)
+# ------------------------------
+AC_DEFUN([AM_MISSING_PROG],
+[AC_REQUIRE([AM_MISSING_HAS_RUN])
+$1=${$1-"${am_missing_run}$2"}
+AC_SUBST($1)])
+
+
+# AM_MISSING_HAS_RUN
+# ------------------
+# Define MISSING if not defined so far and test if it supports --run.
+# If it does, set am_missing_run to use it, otherwise, to nothing.
+AC_DEFUN([AM_MISSING_HAS_RUN],
+[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
+AC_REQUIRE_AUX_FILE([missing])dnl
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ AC_MSG_WARN([`missing' script is too old or missing])
+fi
+])
+
+# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_MKDIR_P
+# ---------------
+# Check for `mkdir -p'.
+AC_DEFUN([AM_PROG_MKDIR_P],
+[AC_PREREQ([2.60])dnl
+AC_REQUIRE([AC_PROG_MKDIR_P])dnl
+dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
+dnl while keeping a definition of mkdir_p for backward compatibility.
+dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
+dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
+dnl Makefile.ins that do not define MKDIR_P, so we do our own
+dnl adjustment using top_builddir (which is defined more often than
+dnl MKDIR_P).
+AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
+case $mkdir_p in
+ [[\\/$]]* | ?:[[\\/]]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+])
+
+# Helper functions for option handling. -*- Autoconf -*-
+
+# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+# _AM_MANGLE_OPTION(NAME)
+# -----------------------
+AC_DEFUN([_AM_MANGLE_OPTION],
+[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
+
+# _AM_SET_OPTION(NAME)
+# ------------------------------
+# Set option NAME. Presently that only means defining a flag for this option.
+AC_DEFUN([_AM_SET_OPTION],
+[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
+
+# _AM_SET_OPTIONS(OPTIONS)
+# ----------------------------------
+# OPTIONS is a space-separated list of Automake options.
+AC_DEFUN([_AM_SET_OPTIONS],
+[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
+
+# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
+# -------------------------------------------
+# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
+AC_DEFUN([_AM_IF_OPTION],
+[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
+
+# Check to make sure that the build environment is sane. -*- Autoconf -*-
+
+# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 5
+
+# AM_SANITY_CHECK
+# ---------------
+AC_DEFUN([AM_SANITY_CHECK],
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[[\\\"\#\$\&\'\`$am_lf]]*)
+ AC_MSG_ERROR([unsafe absolute working directory name]);;
+esac
+case $srcdir in
+ *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
+ AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$[*]" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$[*]" != "X $srcdir/configure conftest.file" \
+ && test "$[*]" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "$[2]" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+AC_MSG_RESULT(yes)])
+
+# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# AM_PROG_INSTALL_STRIP
+# ---------------------
+# One issue with vendor `install' (even GNU) is that you can't
+# specify the program used to strip binaries. This is especially
+# annoying in cross-compiling environments, where the build's strip
+# is unlikely to handle the host's binaries.
+# Fortunately install-sh will honor a STRIPPROG variable, so we
+# always use install-sh in `make install-strip', and initialize
+# STRIPPROG with the value of the STRIP variable (set by the user).
+AC_DEFUN([AM_PROG_INSTALL_STRIP],
+[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
+if test "$cross_compiling" != no; then
+ AC_CHECK_TOOL([STRIP], [strip], :)
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+AC_SUBST([INSTALL_STRIP_PROGRAM])])
+
+# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
+# This macro is traced by Automake.
+AC_DEFUN([_AM_SUBST_NOTMAKE])
+
+# AM_SUBST_NOTMAKE(VARIABLE)
+# ---------------------------
+# Public sister of _AM_SUBST_NOTMAKE.
+AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
+
+# Check how to create a tarball. -*- Autoconf -*-
+
+# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 2
+
+# _AM_PROG_TAR(FORMAT)
+# --------------------
+# Check how to create a tarball in format FORMAT.
+# FORMAT should be one of `v7', `ustar', or `pax'.
+#
+# Substitute a variable $(am__tar) that is a command
+# writing to stdout a FORMAT-tarball containing the directory
+# $tardir.
+# tardir=directory && $(am__tar) > result.tar
+#
+# Substitute a variable $(am__untar) that extract such
+# a tarball read from stdin.
+# $(am__untar) < result.tar
+AC_DEFUN([_AM_PROG_TAR],
+[# Always define AMTAR for backward compatibility.
+AM_MISSING_PROG([AMTAR], [tar])
+m4_if([$1], [v7],
+ [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+ [m4_case([$1], [ustar],, [pax],,
+ [m4_fatal([Unknown tar format])])
+AC_MSG_CHECKING([how to create a $1 tar archive])
+# Loop over all known methods to create a tar archive until one works.
+_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
+_am_tools=${am_cv_prog_tar_$1-$_am_tools}
+# Do not fold the above two line into one, because Tru64 sh and
+# Solaris sh will not grok spaces in the rhs of `-'.
+for _am_tool in $_am_tools
+do
+ case $_am_tool in
+ gnutar)
+ for _am_tar in tar gnutar gtar;
+ do
+ AM_RUN_LOG([$_am_tar --version]) && break
+ done
+ am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
+ am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
+ am__untar="$_am_tar -xf -"
+ ;;
+ plaintar)
+ # Must skip GNU tar: if it does not support --format= it doesn't create
+ # ustar tarball either.
+ (tar --version) >/dev/null 2>&1 && continue
+ am__tar='tar chf - "$$tardir"'
+ am__tar_='tar chf - "$tardir"'
+ am__untar='tar xf -'
+ ;;
+ pax)
+ am__tar='pax -L -x $1 -w "$$tardir"'
+ am__tar_='pax -L -x $1 -w "$tardir"'
+ am__untar='pax -r'
+ ;;
+ cpio)
+ am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
+ am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
+ am__untar='cpio -i -H $1 -d'
+ ;;
+ none)
+ am__tar=false
+ am__tar_=false
+ am__untar=false
+ ;;
+ esac
+
+ # If the value was cached, stop now. We just wanted to have am__tar
+ # and am__untar set.
+ test -n "${am_cv_prog_tar_$1}" && break
+
+ # tar/untar a dummy directory, and stop if the command works
+ rm -rf conftest.dir
+ mkdir conftest.dir
+ echo GrepMe > conftest.dir/file
+ AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
+ rm -rf conftest.dir
+ if test -s conftest.tar; then
+ AM_RUN_LOG([$am__untar <conftest.tar])
+ grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
+ fi
+done
+rm -rf conftest.dir
+
+AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
+AC_MSG_RESULT([$am_cv_prog_tar_$1])])
+AC_SUBST([am__tar])
+AC_SUBST([am__untar])
+]) # _AM_PROG_TAR
+
+m4_include([../config/acx.m4])
+m4_include([../config/depstand.m4])
+m4_include([../config/lead-dot.m4])
+m4_include([../config/libstdc++-raw-cxx.m4])
+m4_include([../config/multi.m4])
+m4_include([../config/override.m4])
+m4_include([../ltoptions.m4])
+m4_include([../ltsugar.m4])
+m4_include([../ltversion.m4])
+m4_include([../lt~obsolete.m4])
+m4_include([acinclude.m4])
diff --git a/libvtv/configure b/libvtv/configure
new file mode 100755
index 00000000000..bb56cb0cb97
--- /dev/null
+++ b/libvtv/configure
@@ -0,0 +1,17982 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.64 for GNU Vtable Verification Runtime Library 1.0.
+#
+# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
+# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
+# Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1
+
+ test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+ ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+ PATH=/empty FPATH=/empty; export PATH FPATH
+ test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+ || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ # We cannot yet assume a decent shell, so we have to provide a
+ # neutralization value for shells without unset; and this also
+ # works around shells that cannot unset nonexistent variables.
+ BASH_ENV=/dev/null
+ ENV=/dev/null
+ (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+ export CONFIG_SHELL
+ exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
+ else
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
+ fi
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
+ sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
+ N
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
+ t loop
+ s/-\n.*//
+ ' >$as_me.lineno &&
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+
+ # Don't try to exec as it changes $[0], causing all sort of problems
+ # (the dirname of $[0] is not the place where we might find the
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
+ # Exit status is that of the last command.
+ exit
+}
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+
+exec 7<&0 </dev/null 6>&1
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_clean_files=
+ac_config_libobj_dir=.
+LIBOBJS=
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+
+# Identity of this package.
+PACKAGE_NAME='GNU Vtable Verification Runtime Library'
+PACKAGE_TARNAME='libvtv'
+PACKAGE_VERSION='1.0'
+PACKAGE_STRING='GNU Vtable Verification Runtime Library 1.0'
+PACKAGE_BUGREPORT=''
+PACKAGE_URL='http://www.gnu.org/software/libvtv/'
+
+ac_unique_file="vtv_rts.h"
+# Factoring default headers for most tests.
+ac_includes_default="\
+#include <stdio.h>
+#ifdef HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+#ifdef STDC_HEADERS
+# 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_STRINGS_H
+# include <strings.h>
+#endif
+#ifdef HAVE_INTTYPES_H
+# include <inttypes.h>
+#endif
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif"
+
+ac_subst_vars='am__EXEEXT_FALSE
+am__EXEEXT_TRUE
+LTLIBOBJS
+LIBOBJS
+XCFLAGS
+libtool_VERSION
+enable_static
+enable_shared
+CXXCPP
+OTOOL64
+OTOOL
+LIPO
+NMEDIT
+DSYMUTIL
+OBJDUMP
+LN_S
+NM
+ac_ct_DUMPBIN
+DUMPBIN
+LD
+FGREP
+SED
+LIBTOOL
+RANLIB
+AR
+AS
+CCASFLAGS
+CCAS
+am__fastdepCXX_FALSE
+am__fastdepCXX_TRUE
+CXXDEPMODE
+ac_ct_CXX
+CXXFLAGS
+CXX
+EGREP
+GREP
+CPP
+am__fastdepCC_FALSE
+am__fastdepCC_TRUE
+CCDEPMODE
+AMDEPBACKSLASH
+AMDEP_FALSE
+AMDEP_TRUE
+am__quote
+am__include
+DEPDIR
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+toolexeclibdir
+toolexecdir
+toplevel_srcdir
+toplevel_builddir
+libvtv_srcdir
+libvtv_builddir
+MAINT
+MAINTAINER_MODE_FALSE
+MAINTAINER_MODE_TRUE
+multi_basedir
+am__untar
+am__tar
+AMTAR
+am__leading_dot
+SET_MAKE
+AWK
+mkdir_p
+MKDIR_P
+INSTALL_STRIP_PROGRAM
+STRIP
+install_sh
+MAKEINFO
+AUTOHEADER
+AUTOMAKE
+AUTOCONF
+ACLOCAL
+VERSION
+PACKAGE
+CYGPATH_W
+am__isrc
+INSTALL_DATA
+INSTALL_SCRIPT
+INSTALL_PROGRAM
+LIBSTDCXX_RAW_CXX_LDFLAGS
+LIBSTDCXX_RAW_CXX_CXXFLAGS
+target_noncanonical
+target_os
+target_vendor
+target_cpu
+target
+host_os
+host_vendor
+host_cpu
+host
+build_os
+build_vendor
+build_cpu
+build
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
+ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_version_specific_runtime_libs
+enable_multilib
+enable_maintainer_mode
+enable_dependency_tracking
+enable_shared
+enable_static
+with_pic
+enable_fast_install
+with_gnu_ld
+enable_libtool_lock
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP
+CXXCPP'
+
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
+
+ac_prev=
+ac_dashdash=
+for ac_option
+do
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval $ac_prev=\$ac_option
+ ac_prev=
+ continue
+ fi
+
+ case $ac_option in
+ *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *) ac_optarg=yes ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir=$ac_optarg ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build_alias ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build_alias=$ac_optarg ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file=$ac_optarg ;;
+
+ --config-cache | -C)
+ cache_file=config.cache ;;
+
+ -datadir | --datadir | --datadi | --datad)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
+ datadir=$ac_optarg ;;
+
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
+ -disable-* | --disable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
+
+ -enable-* | --enable-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=\$ac_optarg ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix=$ac_optarg ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he | -h)
+ ac_init_help=long ;;
+ -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+ ac_init_help=recursive ;;
+ -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+ ac_init_help=short ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host_alias ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host_alias=$ac_optarg ;;
+
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir=$ac_optarg ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir=$ac_optarg ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir=$ac_optarg ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir=$ac_optarg ;;
+
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst | --locals)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
+ localstatedir=$ac_optarg ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir=$ac_optarg ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c | -n)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir=$ac_optarg ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix=$ac_optarg ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix=$ac_optarg ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix=$ac_optarg ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name=$ac_optarg ;;
+
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir=$ac_optarg ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir=$ac_optarg ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site=$ac_optarg ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir=$ac_optarg ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir=$ac_optarg ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target_alias ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target_alias=$ac_optarg ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers | -V)
+ ac_init_version=: ;;
+
+ -with-* | --with-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=\$ac_optarg ;;
+
+ -without-* | --without-*)
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ # Reject names that are not valid shell variable names.
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes=$ac_optarg ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries=$ac_optarg ;;
+
+ -*) as_fn_error "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information."
+ ;;
+
+ *=*)
+ ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+ # Reject names that are not valid shell variable names.
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
+ export $ac_envvar ;;
+
+ *)
+ # FIXME: should be removed in autoconf 3.0.
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+ as_fn_error "missing argument to $ac_option"
+fi
+
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
+ esac
+fi
+
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
+do
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
+ case $ac_val in
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
+ esac
+ as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+ if test "x$build_alias" = x; then
+ cross_compiling=maybe
+ $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+ If a cross compiler is detected then cross compile mode will be used." >&2
+ elif test "x$build_alias" != "x$host_alias"; then
+ cross_compiling=yes
+ fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error "pwd does not report name of working directory"
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ srcdir=$ac_confdir
+ if test ! -r "$srcdir/$ac_unique_file"; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat <<_ACEOF
+\`configure' configures GNU Vtable Verification Runtime Library 1.0 to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE. See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+ -h, --help display this help and exit
+ --help=short display options specific to this package
+ --help=recursive display the short help of all the included packages
+ -V, --version display version information and exit
+ -q, --quiet, --silent do not print \`checking...' messages
+ --cache-file=FILE cache test results in FILE [disabled]
+ -C, --config-cache alias for \`--cache-file=config.cache'
+ -n, --no-create do not create output files
+ --srcdir=DIR find the sources in DIR [configure dir or \`..']
+
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/libvtv]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+_ACEOF
+
+ cat <<\_ACEOF
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+
+System types:
+ --build=BUILD configure for building on BUILD [guessed]
+ --host=HOST cross-compile to build programs to run on HOST [BUILD]
+ --target=TARGET configure for building compilers for TARGET [HOST]
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+ case $ac_init_help in
+ short | recursive ) echo "Configuration of GNU Vtable Verification Runtime Library 1.0:";;
+ esac
+ cat <<\_ACEOF
+
+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]
+ --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory
+ --enable-multilib build many library versions (default)
+ --enable-maintainer-mode enable make rules and dependencies not useful
+ (and sometimes confusing) to the casual installer
+ --disable-dependency-tracking speeds up one-time build
+ --enable-dependency-tracking do not reject slow dependency extractors
+ --enable-shared[=PKGS] build shared libraries [default=yes]
+ --enable-static[=PKGS] build static libraries [default=yes]
+ --enable-fast-install[=PKGS]
+ optimize for fast installation [default=yes]
+ --disable-libtool-lock avoid locking (might break parallel builds)
+
+Optional Packages:
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --with-pic try to use only PIC/non-PIC objects [default=use
+ both]
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]
+
+Some influential environment variables:
+ CC C compiler command
+ CFLAGS C compiler flags
+ LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
+ nonstandard directory <lib dir>
+ 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
+ CXXCPP C++ preprocessor
+
+Use these variables to override the choices made by `configure' or to help
+it to find libraries and programs with nonstandard names/locations.
+
+Report bugs to the package provider.
+GNU Vtable Verification Runtime Library home page: <http://www.gnu.org/software/libvtv/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>.
+_ACEOF
+ac_status=$?
+fi
+
+if test "$ac_init_help" = "recursive"; then
+ # If there are subdirs, report their specific --help.
+ for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
+ else
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
+ done
+fi
+
+test -n "$ac_init_help" && exit $ac_status
+if $ac_init_version; then
+ cat <<\_ACEOF
+GNU Vtable Verification Runtime Library configure 1.0
+generated by GNU Autoconf 2.64
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+ exit
+fi
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ 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>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; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; 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_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;}
+ ;;
+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_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ 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>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; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ 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_link
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ 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. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext 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_func
+
+# ac_fn_cxx_try_compile LINENO
+# ----------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ 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>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; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; 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_cxx_try_compile
+
+# ac_fn_cxx_try_cpp LINENO
+# ------------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_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_cxx_preproc_warn_flag$ac_cxx_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_cxx_try_cpp
+
+# ac_fn_cxx_try_link LINENO
+# -------------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_cxx_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ 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>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; } && {
+ test -z "$ac_cxx_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ 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_cxx_try_link
+cat >config.log <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by GNU Vtable Verification Runtime Library $as_me 1.0, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ $ $0 $@
+
+_ACEOF
+exec 5>>config.log
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown`
+
+/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
+/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
+/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+ for ac_arg
+ do
+ case $ac_arg in
+ -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ continue ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ case $ac_pass in
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
+ 2)
+ as_fn_append ac_configure_args1 " '$ac_arg'"
+ if test $ac_must_keep_next = true; then
+ ac_must_keep_next=false # Got value, back to normal.
+ else
+ case $ac_arg in
+ *=* | --config-cache | -C | -disable-* | --disable-* \
+ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+ | -with-* | --with-* | -without-* | --without-* | --x)
+ case "$ac_configure_args0 " in
+ "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+ esac
+ ;;
+ -* ) ac_must_keep_next=true ;;
+ esac
+ fi
+ as_fn_append ac_configure_args " '$ac_arg'"
+ ;;
+ esac
+ done
+done
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log. We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
+trap 'exit_status=$?
+ # Save into config.log some information that might help in debugging.
+ {
+ echo
+
+ cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+ echo
+ # The following way of writing the cache mishandles newlines in values,
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+ (set) 2>&1 |
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ sed -n \
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
+ *)
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+)
+ echo
+
+ cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_vars
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+
+ if test -n "$ac_subst_files"; then
+ cat <<\_ASBOX
+## ------------------- ##
+## File substitutions. ##
+## ------------------- ##
+_ASBOX
+ echo
+ for ac_var in $ac_subst_files
+ do
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
+ done | sort
+ echo
+ fi
+
+ if test -s confdefs.h; then
+ cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+ echo
+ cat confdefs.h
+ echo
+ fi
+ test "$ac_signal" != 0 &&
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
+ } >&5
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
+ exit $exit_status
+' 0
+for ac_signal in 1 2 13 15; do
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ ac_site_file1=$CONFIG_SITE
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
+fi
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
+ sed 's/^/| /' "$ac_site_file" >&5
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ # Some versions of bash will fail to source /dev/null (special
+ # files actually), so we avoid doing that.
+ if test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
+ case $cache_file in
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
+ esac
+ fi
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
+ >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in $ac_precious_vars; do
+ eval ac_old_set=\$ac_cv_env_${ac_var}_set
+ eval ac_new_set=\$ac_env_${ac_var}_set
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
+ case $ac_old_set,$ac_new_set in
+ set,)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,set)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ ac_cache_corrupted=: ;;
+ ,);;
+ *)
+ if test "x$ac_old_val" != "x$ac_new_val"; then
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
+ fi;;
+ esac
+ # Pass precious variables to config.status.
+ if test "$ac_new_set" = set; then
+ case $ac_new_val in
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *) ac_arg=$ac_var=$ac_new_val ;;
+ esac
+ case " $ac_configure_args " in
+ *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
+ esac
+ fi
+done
+if $ac_cache_corrupted; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
+
+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_INIT(package-unused, version-unused, libvtv)
+
+
+# -------
+# Options
+# -------
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for --enable-version-specific-runtime-libs" >&5
+$as_echo_n "checking for --enable-version-specific-runtime-libs... " >&6; }
+# Check whether --enable-version-specific-runtime-libs was given.
+if test "${enable_version_specific_runtime_libs+set}" = set; then :
+ enableval=$enable_version_specific_runtime_libs; case "$enableval" in
+ yes) version_specific_libs=yes ;;
+ no) version_specific_libs=no ;;
+ *) as_fn_error "Unknown argument to enable/disable version-specific libs" "$LINENO" 5;;
+ esac
+else
+ version_specific_libs=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $version_specific_libs" >&5
+$as_echo "$version_specific_libs" >&6; }
+
+# See if supported.
+unset VTV_SUPPORTED
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for host support for vtable verification" >&5
+$as_echo_n "checking for host support for vtable verification... " >&6; }
+. ${srcdir}/configure.tgt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $VTV_SUPPORTED" >&5
+$as_echo "$VTV_SUPPORTED" >&6; }
+
+# Decide if it's usable.
+use_vtable_verify=no
+if test "x$VTV_SUPPORTED" = "xyes"; then
+ use_vtable_verify=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: using vtable verification" >&5
+$as_echo "$as_me: using vtable verification" >&6;}
+fi
+
+# Do not delete or change the following two lines. For why, see
+# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html
+ac_aux_dir=
+for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
+ for ac_t in install-sh install.sh shtool; do
+ if test -f "$ac_dir/$ac_t"; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/$ac_t -c"
+ break 2
+ fi
+ done
+done
+if test -z "$ac_aux_dir"; then
+ as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+fi
+
+# These three variables are undocumented and unsupported,
+# and are intended to be withdrawn in a future Autoconf release.
+# They can cause serious problems if a builder's source tree is in a directory
+# whose full name contains unusual characters.
+ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var.
+ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var.
+ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var.
+
+
+# Make sure we can run config.sub.
+$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
+ as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
+$as_echo_n "checking build system type... " >&6; }
+if test "${ac_cv_build+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_build_alias=$build_alias
+test "x$ac_build_alias" = x &&
+ ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
+test "x$ac_build_alias" = x &&
+ as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
+$as_echo "$ac_cv_build" >&6; }
+case $ac_cv_build in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+esac
+build=$ac_cv_build
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_build
+shift
+build_cpu=$1
+build_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+build_os=$*
+IFS=$ac_save_IFS
+case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
+$as_echo_n "checking host system type... " >&6; }
+if test "${ac_cv_host+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$host_alias" = x; then
+ ac_cv_host=$ac_cv_build
+else
+ ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5
+$as_echo "$ac_cv_host" >&6; }
+case $ac_cv_host in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+esac
+host=$ac_cv_host
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_host
+shift
+host_cpu=$1
+host_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+host_os=$*
+IFS=$ac_save_IFS
+case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking target system type" >&5
+$as_echo_n "checking target system type... " >&6; }
+if test "${ac_cv_target+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "x$target_alias" = x; then
+ ac_cv_target=$ac_cv_host
+else
+ ac_cv_target=`$SHELL "$ac_aux_dir/config.sub" $target_alias` ||
+ as_fn_error "$SHELL $ac_aux_dir/config.sub $target_alias failed" "$LINENO" 5
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_target" >&5
+$as_echo "$ac_cv_target" >&6; }
+case $ac_cv_target in
+*-*-*) ;;
+*) as_fn_error "invalid value of canonical target" "$LINENO" 5;;
+esac
+target=$ac_cv_target
+ac_save_IFS=$IFS; IFS='-'
+set x $ac_cv_target
+shift
+target_cpu=$1
+target_vendor=$2
+shift; shift
+# Remember, the first character of IFS is used to create $*,
+# except with old shells:
+target_os=$*
+IFS=$ac_save_IFS
+case $target_os in *\ *) target_os=`echo "$target_os" | sed 's/ /-/g'`;; esac
+
+
+# The aliases save the names the user supplied, while $host etc.
+# will get canonicalized.
+test -n "$target_alias" &&
+ test "$program_prefix$program_suffix$program_transform_name" = \
+ NONENONEs,x,x, &&
+ program_prefix=${target_alias}-
+
+target_alias=${target_alias-$host_alias}
+
+ case ${build_alias} in
+ "") build_noncanonical=${build} ;;
+ *) build_noncanonical=${build_alias} ;;
+esac
+
+ case ${host_alias} in
+ "") host_noncanonical=${build_noncanonical} ;;
+ *) host_noncanonical=${host_alias} ;;
+esac
+
+ case ${target_alias} in
+ "") target_noncanonical=${host_noncanonical} ;;
+ *) target_noncanonical=${target_alias} ;;
+esac
+
+
+
+
+
+ LIBSTDCXX_RAW_CXX_CXXFLAGS="\
+ -I\$(top_builddir)/../libstdc++-v3/include \
+ -I\$(top_builddir)/../libstdc++-v3/include/\$(target_noncanonical) \
+ -I\$(top_srcdir)/../libstdc++-v3/libsupc++"
+ LIBSTDCXX_RAW_CXX_LDFLAGS="\
+ \$(top_builddir)/../libstdc++-v3/src/libstdc++.la"
+
+
+
+
+am__api_version='1.11'
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AmigaOS /C/install, which installs bootblocks on floppy discs
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# OS/2's system install, which has a completely different semantic
+# ./install, which can be erroneously created by make from ./install.sh.
+# Reject install programs that cannot install multiple files.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
+$as_echo_n "checking for a BSD-compatible install... " >&6; }
+if test -z "$INSTALL"; then
+if test "${ac_cv_path_install+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ # Account for people who put trailing slashes in PATH elements.
+case $as_dir/ in #((
+ ./ | .// | /[cC]/* | \
+ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \
+ ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \
+ /usr/ucb/* ) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+ if test $ac_prog = install &&
+ grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ elif test $ac_prog = install &&
+ grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
+ # program-specific install script used by HP pwplus--don't use.
+ :
+ else
+ rm -rf conftest.one conftest.two conftest.dir
+ echo one > conftest.one
+ echo two > conftest.two
+ mkdir conftest.dir
+ if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" &&
+ test -s conftest.one && test -s conftest.two &&
+ test -s conftest.dir/conftest.one &&
+ test -s conftest.dir/conftest.two
+ then
+ ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c"
+ break 3
+ fi
+ fi
+ fi
+ done
+ done
+ ;;
+esac
+
+ done
+IFS=$as_save_IFS
+
+rm -rf conftest.one conftest.two conftest.dir
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL=$ac_cv_path_install
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ INSTALL=$ac_install_sh
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5
+$as_echo "$INSTALL" >&6; }
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether build environment is sane" >&5
+$as_echo_n "checking whether build environment is sane... " >&6; }
+# Just in case
+sleep 1
+echo timestamp > conftest.file
+# Reject unsafe characters in $srcdir or the absolute working directory
+# name. Accept space and tab only in the latter.
+am_lf='
+'
+case `pwd` in
+ *[\\\"\#\$\&\'\`$am_lf]*)
+ as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+esac
+case $srcdir in
+ *[\\\"\#\$\&\'\`$am_lf\ \ ]*)
+ as_fn_error "unsafe srcdir value: \`$srcdir'" "$LINENO" 5;;
+esac
+
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t "$srcdir/configure" conftest.file`
+ fi
+ rm -f conftest.file
+ if test "$*" != "X $srcdir/configure conftest.file" \
+ && test "$*" != "X conftest.file $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ as_fn_error "ls -t appears to fail. Make sure there is not a broken
+alias in your environment" "$LINENO" 5
+ fi
+
+ test "$2" = conftest.file
+ )
+then
+ # Ok.
+ :
+else
+ as_fn_error "newly created file is older than distributed files!
+Check your system clock" "$LINENO" 5
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+test "$program_prefix" != NONE &&
+ program_transform_name="s&^&$program_prefix&;$program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s&\$&$program_suffix&;$program_transform_name"
+# Double any \ or $.
+# By default was `s,x,x', remove it if useless.
+ac_script='s/[\\$]/&&/g;s/;s,x,x,$//'
+program_transform_name=`$as_echo "$program_transform_name" | sed "$ac_script"`
+
+# expand $ac_aux_dir to an absolute path
+am_aux_dir=`cd $ac_aux_dir && pwd`
+
+if test x"${MISSING+set}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
+ *)
+ MISSING="\${SHELL} $am_aux_dir/missing" ;;
+ esac
+fi
+# Use eval to expand $SHELL
+if eval "$MISSING --run true"; then
+ am_missing_run="$MISSING --run "
+else
+ am_missing_run=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`missing' script is too old or missing" >&5
+$as_echo "$as_me: WARNING: \`missing' script is too old or missing" >&2;}
+fi
+
+if test x"${install_sh}" != xset; then
+ case $am_aux_dir in
+ *\ * | *\ *)
+ install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
+ *)
+ install_sh="\${SHELL} $am_aux_dir/install-sh"
+ esac
+fi
+
+# Installed binaries are usually stripped using `strip' when the user
+# run `make install-strip'. However `strip' might not be the right
+# tool to use in cross-compilation environments, therefore Automake
+# will honor the `STRIP' environment variable to overrule this program.
+if test "$cross_compiling" != no; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; 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_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip"
+ $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
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; 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_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip"
+ $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_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ 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
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+fi
+INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
+$as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
+if test -z "$MKDIR_P"; then
+ if test "${ac_cv_path_mkdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/opt/sfw/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in mkdir gmkdir; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+ case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
+ 'mkdir (GNU coreutils) '* | \
+ 'mkdir (coreutils) '* | \
+ 'mkdir (fileutils) '4.1*)
+ ac_cv_path_mkdir=$as_dir/$ac_prog$ac_exec_ext
+ break 3;;
+ esac
+ done
+ done
+ done
+IFS=$as_save_IFS
+
+fi
+
+ if test "${ac_cv_path_mkdir+set}" = set; then
+ MKDIR_P="$ac_cv_path_mkdir -p"
+ else
+ # As a last resort, use the slow shell script. Don't cache a
+ # value for MKDIR_P within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the value is a relative name.
+ test -d ./--version && rmdir ./--version
+ MKDIR_P="$ac_install_sh -d"
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $MKDIR_P" >&5
+$as_echo "$MKDIR_P" >&6; }
+
+mkdir_p="$MKDIR_P"
+case $mkdir_p in
+ [\\/$]* | ?:[\\/]*) ;;
+ */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
+esac
+
+for ac_prog in gawk mawk nawk awk
+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_AWK+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # 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_AWK="$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
+AWK=$ac_cv_prog_AWK
+if test -n "$AWK"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AWK" >&5
+$as_echo "$AWK" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$AWK" && break
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} sets \$(MAKE)" >&5
+$as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
+set x ${MAKE-make}
+ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
+if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.make <<\_ACEOF
+SHELL = /bin/sh
+all:
+ @echo '@@@%%%=$(MAKE)=@@@%%%'
+_ACEOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+case `${MAKE-make} -f conftest.make 2>/dev/null` in
+ *@@@%%%=?*=@@@%%%*)
+ eval ac_cv_prog_make_${ac_make}_set=yes;;
+ *)
+ eval ac_cv_prog_make_${ac_make}_set=no;;
+esac
+rm -f conftest.make
+fi
+if eval test \$ac_cv_prog_make_${ac_make}_set = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ SET_MAKE=
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+rm -rf .tst 2>/dev/null
+mkdir .tst 2>/dev/null
+if test -d .tst; then
+ am__leading_dot=.
+else
+ am__leading_dot=_
+fi
+rmdir .tst 2>/dev/null
+
+if test "`cd $srcdir && pwd`" != "`pwd`"; then
+ # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
+ # is not polluted with repeated "-I."
+ am__isrc=' -I$(srcdir)'
+ # test to see if srcdir already configured
+ if test -f $srcdir/config.status; then
+ as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+ fi
+fi
+
+# test whether we have cygpath
+if test -z "$CYGPATH_W"; then
+ if (cygpath --version) >/dev/null 2>/dev/null; then
+ CYGPATH_W='cygpath -w'
+ else
+ CYGPATH_W=echo
+ fi
+fi
+
+
+# Define the identity of the package.
+ PACKAGE='libvtv'
+ VERSION='1.0'
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE "$PACKAGE"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define VERSION "$VERSION"
+_ACEOF
+
+# Some tools Automake needs.
+
+ACLOCAL=${ACLOCAL-"${am_missing_run}aclocal-${am__api_version}"}
+
+
+AUTOCONF=${AUTOCONF-"${am_missing_run}autoconf"}
+
+
+AUTOMAKE=${AUTOMAKE-"${am_missing_run}automake-${am__api_version}"}
+
+
+AUTOHEADER=${AUTOHEADER-"${am_missing_run}autoheader"}
+
+
+MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
+
+# We need awk for the "check" target. The system "awk" is bad on
+# some platforms.
+# Always define AMTAR for backward compatibility.
+
+AMTAR=${AMTAR-"${am_missing_run}tar"}
+
+am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+
+
+
+
+
+# Default to --enable-multilib
+# Check whether --enable-multilib was given.
+if test "${enable_multilib+set}" = set; then :
+ enableval=$enable_multilib; case "$enableval" in
+ yes) multilib=yes ;;
+ no) multilib=no ;;
+ *) as_fn_error "bad value $enableval for multilib option" "$LINENO" 5 ;;
+ esac
+else
+ multilib=yes
+fi
+
+
+# We may get other options which we leave undocumented:
+# --with-target-subdir, --with-multisrctop, --with-multisubdir
+# See config-ml.in if you want the gory details.
+
+if test "$srcdir" = "."; then
+ if test "$with_target_subdir" != "."; then
+ multi_basedir="$srcdir/$with_multisrctop../.."
+ else
+ multi_basedir="$srcdir/$with_multisrctop.."
+ fi
+else
+ multi_basedir="$srcdir/.."
+fi
+
+
+# Even if the default multilib is not a cross compilation,
+# it may be that some of the other multilibs are.
+if test $cross_compiling = no && test $multilib = yes \
+ && test "x${with_multisubdir}" != x ; then
+ cross_compiling=maybe
+fi
+
+ac_config_commands="$ac_config_commands default-1"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable maintainer-specific portions of Makefiles" >&5
+$as_echo_n "checking whether to enable maintainer-specific portions of Makefiles... " >&6; }
+ # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then :
+ enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+ USE_MAINTAINER_MODE=no
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_MAINTAINER_MODE" >&5
+$as_echo "$USE_MAINTAINER_MODE" >&6; }
+ if test $USE_MAINTAINER_MODE = yes; then
+ MAINTAINER_MODE_TRUE=
+ MAINTAINER_MODE_FALSE='#'
+else
+ MAINTAINER_MODE_TRUE='#'
+ MAINTAINER_MODE_FALSE=
+fi
+
+ MAINT=$MAINTAINER_MODE_TRUE
+
+
+
+
+
+ # These need to be absolute paths, yet at the same time need to
+ # canonicalize only relative paths, because then amd will not unmount
+ # drives. Thus the use of PWDCMD: set it to 'pawd' or 'amq -w' if using amd.
+ libvtv_builddir=`${PWDCMD-pwd}`
+ case $srcdir in
+ \\/$* | ?:\\/*) libvtv_srcdir=${srcdir} ;;
+ *) libvtv_srcdir=`cd "$srcdir" && ${PWDCMD-pwd} || echo "$srcdir"` ;;
+ esac
+ toplevel_builddir=${libvtv_builddir}/..
+ toplevel_srcdir=${libvtv_srcdir}/..
+
+
+
+
+
+
+# Calculate toolexeclibdir
+# Also toolexecdir, though it's only used in toolexeclibdir
+case ${version_specific_libs} in
+ yes)
+ # Need the gcc compiler version to know where to install libraries
+ # and header files if --enable-version-specific-runtime-libs option
+ # is selected.
+ toolexecdir='$(libdir)/gcc/$(target_alias)'
+ toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
+ ;;
+ no)
+ if test -n "$with_cross_host" &&
+ test x"$with_cross_host" != x"no"; then
+ # Install a library built with a cross compiler in tooldir, not libdir.
+ toolexecdir='$(exec_prefix)/$(target_alias)'
+ toolexeclibdir='$(toolexecdir)/lib'
+ else
+ toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+ toolexeclibdir='$(libdir)'
+ fi
+ multi_os_directory=`$CC -print-multi-os-directory`
+ case $multi_os_directory in
+ .) ;; # Avoid trailing /.
+ *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+ esac
+ ;;
+esac
+
+
+
+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='\'
+fi
+ if test "x$enable_dependency_tracking" != xno; then
+ AMDEP_TRUE=
+ AMDEP_FALSE='#'
+else
+ AMDEP_TRUE='#'
+ AMDEP_FALSE=
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+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
+
+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'.
+ 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
+ ;;
+ msvisualcpp | msvcmsys)
+ # This compiler won't grok `-c -o', but also, the minuso test has
+ # not run yet. These depmodes are late enough in the game, and
+ # so weak that their functioning should not be impacted.
+ am__obj=conftest.${OBJEXT-o}
+ am__minus_obj=
+ ;;
+ none) break ;;
+ esac
+ if depmode=$depmode \
+ source=sub/conftest.c object=$am__obj \
+ depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
+ $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
+ >/dev/null 2>conftest.err &&
+ grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
+ grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
+ ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
+ # icc doesn't choke on unknown options, it will just issue warnings
+ # or remarks (even with -Werror). So we grep stderr for any message
+ # that says an option was ignored or not supported.
+ # When given -MP, icc 7.0 and 7.1 complain thusly:
+ # icc: Command line warning: ignoring option '-M'; no argument required
+ # The diagnosis changed in icc 8.0:
+ # icc: Command line remark: option '-MP' not supported
+ if (grep 'ignoring option' conftest.err ||
+ grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
+ am_cv_CC_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CC_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CC_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CC_dependencies_compiler_type" >&6; }
+CCDEPMODE=depmode=$am_cv_CC_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CC_dependencies_compiler_type" = gcc3; then
+ am__fastdepCC_TRUE=
+ am__fastdepCC_FALSE='#'
+else
+ am__fastdepCC_TRUE='#'
+ am__fastdepCC_FALSE=
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether nonexistent headers
+ # can be detected and how.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ # Broken: success on invalid input.
+continue
+else
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
+else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." "$LINENO" 5; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if test "${ac_cv_path_GREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $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
+
+
+
+for ac_func in __secure_getenv
+do :
+ ac_fn_c_check_func "$LINENO" "__secure_getenv" "ac_cv_func___secure_getenv"
+if test "x$ac_cv_func___secure_getenv" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE___SECURE_GETENV 1
+_ACEOF
+
+fi
+done
+
+
+
+for ac_func in secure_getenv
+do :
+ ac_fn_c_check_func "$LINENO" "secure_getenv" "ac_cv_func_secure_getenv"
+if test "x$ac_cv_func_secure_getenv" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_SECURE_GETENV 1
+_ACEOF
+
+fi
+done
+
+
+# Check for programs.
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_CC"; then
+ ac_ct_CC=$CC
+ # Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="gcc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+else
+ CC="$ac_cv_prog_CC"
+fi
+
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+set dummy ${ac_tool_prefix}cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="${ac_tool_prefix}cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ fi
+fi
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ ac_prog_rejected=no
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# != 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@"
+ fi
+fi
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$CC"; then
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in cl.exe
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CC=$ac_cv_prog_CC
+if test -n "$CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CC" && break
+ done
+fi
+if test -z "$CC"; then
+ ac_ct_CC=$CC
+ for ac_prog in cl.exe
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CC"; then
+ ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_prog_ac_ct_CC="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CC=$ac_cv_prog_ac_ct_CC
+if test -n "$ac_ct_CC"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CC" && break
+done
+
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
+fi
+
+fi
+
+
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error "no acceptable C compiler found in \$PATH
+See \`config.log' for more details." "$LINENO" 5; }
+
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+#ifndef __GNUC__
+ choke me
+#endif
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_compiler_gnu=yes
+else
+ ac_compiler_gnu=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ac_cv_c_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+ac_test_CFLAGS=${CFLAGS+set}
+ac_save_CFLAGS=$CFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if test "${ac_cv_prog_cc_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+else
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS=$ac_save_CFLAGS
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if test "${ac_cv_prog_cc_c89+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_cv_prog_cc_c89=no
+ac_save_CC=$CC
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdarg.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
+struct buf { int x; };
+FILE * (*rcsopen) (struct buf *, struct stat *, int);
+static char *e (p, i)
+ char **p;
+ int i;
+{
+ return p[i];
+}
+static char *f (char * (*g) (char **, int), char **p, ...)
+{
+ char *s;
+ va_list v;
+ va_start (v,p);
+ s = g (p, va_arg (v,int));
+ va_end (v);
+ return s;
+}
+
+/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
+ function prototypes and stuff, but not '\xHH' hex character constants.
+ These don't provoke an error unfortunately, instead are silently treated
+ as 'x'. The following induces an error, until -std is added to get
+ proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
+ array size at least. It's necessary to write '\x00'==0 to get something
+ that's true only with -std. */
+int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
+int test (int i, double x);
+struct s1 {int (*f) (int a);};
+struct s2 {int (*f) (double a);};
+int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int);
+int argc;
+char **argv;
+int
+main ()
+{
+return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
+ ;
+ return 0;
+}
+_ACEOF
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+do
+ CC="$ac_save_CC $ac_arg"
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
+fi
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
+done
+rm -f conftest.$ac_ext
+CC=$ac_save_CC
+
+fi
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
+ *)
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
+esac
+if test "x$ac_cv_prog_cc_c89" != xno; then :
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CC" am_compiler_list=
+
+{ $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'.
+ 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
+ ;;
+ 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'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+if test -z "$CXX"; then
+ if test -n "$CCC"; then
+ CXX=$CCC
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+ 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_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # 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_CXX="$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
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC xlC_r xlC
+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_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # 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_CXX="$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_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX="g++"
+ 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
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+fi
+# Provide some information about the compiler.
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C++ compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ rm -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C++ compiler" >&5
+$as_echo_n "checking whether we are using the GNU C++ compiler... " >&6; }
+if test "${ac_cv_cxx_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_cxx_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_cxx_compiler_gnu=$ac_compiler_gnu
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cxx_compiler_gnu" >&5
+$as_echo "$ac_cv_cxx_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GXX=yes
+else
+ GXX=
+fi
+ac_test_CXXFLAGS=${CXXFLAGS+set}
+ac_save_CXXFLAGS=$CXXFLAGS
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CXX accepts -g" >&5
+$as_echo_n "checking whether $CXX accepts -g... " >&6; }
+if test "${ac_cv_prog_cxx_g+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_cxx_werror_flag=$ac_cxx_werror_flag
+ ac_cxx_werror_flag=yes
+ ac_cv_prog_cxx_g=no
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_g=yes
+else
+ CXXFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+
+else
+ ac_cxx_werror_flag=$ac_save_cxx_werror_flag
+ CXXFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ ac_cv_prog_cxx_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_cxx_werror_flag=$ac_save_cxx_werror_flag
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cxx_g" >&5
+$as_echo "$ac_cv_prog_cxx_g" >&6; }
+if test "$ac_test_CXXFLAGS" = set; then
+ CXXFLAGS=$ac_save_CXXFLAGS
+elif test $ac_cv_prog_cxx_g = yes; then
+ if test "$GXX" = yes; then
+ CXXFLAGS="-g -O2"
+ else
+ CXXFLAGS="-g"
+ fi
+else
+ if test "$GXX" = yes; then
+ CXXFLAGS="-O2"
+ else
+ CXXFLAGS=
+ fi
+fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+depcc="$CXX" 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_CXX_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'.
+ 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_CXX_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
+ ;;
+ 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_CXX_dependencies_compiler_type=$depmode
+ break
+ fi
+ fi
+ done
+
+ cd ..
+ rm -rf conftest.dir
+else
+ am_cv_CXX_dependencies_compiler_type=none
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_CXX_dependencies_compiler_type" >&5
+$as_echo "$am_cv_CXX_dependencies_compiler_type" >&6; }
+CXXDEPMODE=depmode=$am_cv_CXX_dependencies_compiler_type
+
+ if
+ test "x$enable_dependency_tracking" != xno \
+ && test "$am_cv_CXX_dependencies_compiler_type" = gcc3; then
+ am__fastdepCXX_TRUE=
+ am__fastdepCXX_FALSE='#'
+else
+ am__fastdepCXX_TRUE='#'
+ am__fastdepCXX_FALSE=
+fi
+
+
+
+
+if test "x$CC" != xcc; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC and cc understand -c and -o together" >&5
+$as_echo_n "checking whether $CC and cc understand -c and -o together... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether cc understands -c and -o together" >&5
+$as_echo_n "checking whether cc understands -c and -o together... " >&6; }
+fi
+set dummy $CC; ac_cc=`$as_echo "$2" |
+ sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+if { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+# Make sure it works both with $CC and with simple cc.
+# We do the test twice because some compilers refuse to overwrite an
+# existing .o file with -o, though they will create one.
+ac_try='$CC -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+rm -f conftest2.*
+if { { 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; } &&
+ test -f conftest2.$ac_objext && { { 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
+ eval ac_cv_prog_cc_${ac_cc}_c_o=yes
+ if test "x$CC" != xcc; then
+ # Test first that cc exists at all.
+ if { ac_try='cc -c conftest.$ac_ext >&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_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ ac_try='cc -c conftest.$ac_ext -o conftest2.$ac_objext >&5'
+ rm -f conftest2.*
+ if { { 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; } &&
+ test -f conftest2.$ac_objext && { { 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
+ # cc works too.
+ :
+ else
+ # cc exists but doesn't like -o.
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+ fi
+ fi
+ fi
+else
+ eval ac_cv_prog_cc_${ac_cc}_c_o=no
+fi
+rm -f core conftest*
+
+fi
+if eval test \$ac_cv_prog_cc_${ac_cc}_c_o = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+
+$as_echo "#define NO_MINUS_C_MINUS_O 1" >>confdefs.h
+
+fi
+
+# FIXME: we rely on the cache variable name because
+# there is no other way.
+set dummy $CC
+am_cc=`echo $2 | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
+eval am_t=\$ac_cv_prog_cc_${am_cc}_c_o
+if test "$am_t" != yes; then
+ # Losing compiler, so override with the script.
+ # FIXME: It is wrong to rewrite CC.
+ # But if we don't then we get into trouble of one sort or another.
+ # A longer-term fix would be to have automake use am__CC in this case,
+ # and then we could set am__CC="\$(top_srcdir)/compile \$(CC)"
+ CC="$am_aux_dir/compile $CC"
+fi
+
+
+
+
+
+
+# Newer automakes demand CCAS and CCASFLAGS.
+: ${CCAS='$(CC)'}
+: ${CCASFLAGS='$(CFLAGS)'}
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
+set dummy ${ac_tool_prefix}as; 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_AS+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AS"; then
+ ac_cv_prog_AS="$AS" # 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_AS="${ac_tool_prefix}as"
+ $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
+AS=$ac_cv_prog_AS
+if test -n "$AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AS" >&5
+$as_echo "$AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AS"; then
+ ac_ct_AS=$AS
+ # Extract the first word of "as", so it can be a program name with args.
+set dummy as; 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_AS+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AS"; then
+ ac_cv_prog_ac_ct_AS="$ac_ct_AS" # 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_AS="as"
+ $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_AS=$ac_cv_prog_ac_ct_AS
+if test -n "$ac_ct_AS"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AS" >&5
+$as_echo "$ac_ct_AS" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AS" = x; then
+ AS=""
+ 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
+ AS=$ac_ct_AS
+ fi
+else
+ AS="$ac_cv_prog_AS"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; 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_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # 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_AR="${ac_tool_prefix}ar"
+ $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
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; 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_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_AR="ar"
+ $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_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR=""
+ 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
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; 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_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # 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_RANLIB="${ac_tool_prefix}ranlib"
+ $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
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; 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_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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_RANLIB="ranlib"
+ $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_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ 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
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+
+# Configure libtool
+enable_dlopen=yes
+
+
+
+case `pwd` in
+ *\ * | *\ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5
+$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;;
+esac
+
+
+
+macro_version='2.2.7a'
+macro_revision='1.3134'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`print -r -- -n 2>/dev/null`" = X-n && \
+ test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+ ECHO='printf %s\n'
+else
+ # Use this function as a fallback that always works.
+ func_fallback_echo ()
+ {
+ eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+ }
+ ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+ $ECHO ""
+}
+
+case "$ECHO" in
+ printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+ print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+ *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if test "${ac_cv_path_SED+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+ for ac_i in 1 2 3 4 5 6 7; do
+ ac_script="$ac_script$as_nl$ac_script"
+ done
+ echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+ { ac_script=; unset ac_script;}
+ if test -z "$SED"; then
+ ac_path_SED_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
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in sed gsed; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+# Check for GNU ac_path_SED and select it if it is found.
+ # Check for GNU $ac_path_SED
+case `"$ac_path_SED" --version 2>&1` in
+*GNU*)
+ ac_cv_path_SED="$ac_path_SED" ac_path_SED_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 '' >> "conftest.nl"
+ "$ac_path_SED" -f conftest.sed < "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_SED_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_SED="$ac_path_SED"
+ ac_path_SED_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_SED_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_SED"; then
+ as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+ fi
+else
+ ac_cv_path_SED=$SED
+fi
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5
+$as_echo "$ac_cv_path_SED" >&6; }
+ SED="$ac_cv_path_SED"
+ rm -f conftest.sed
+
+test -z "$SED" && SED=sed
+Xsed="$SED -e 1s/^X//"
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
+$as_echo_n "checking for fgrep... " >&6; }
+if test "${ac_cv_path_FGREP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
+ then ac_cv_path_FGREP="$GREP -F"
+ else
+ if test -z "$FGREP"; then
+ ac_path_FGREP_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 fgrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
+ { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+# Check for GNU ac_path_FGREP and select it if it is found.
+ # Check for GNU $ac_path_FGREP
+case `"$ac_path_FGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_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 'FGREP' >> "conftest.nl"
+ "$ac_path_FGREP" FGREP < "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_FGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_FGREP="$ac_path_FGREP"
+ ac_path_FGREP_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_FGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_FGREP"; then
+ as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_FGREP=$FGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5
+$as_echo "$ac_cv_path_FGREP" >&6; }
+ FGREP="$ac_cv_path_FGREP"
+
+
+test -z "$GREP" && GREP=grep
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
+$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
+if test "${lt_cv_path_NM+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ lt_cv_path_NM="$NM"
+else
+ lt_nm_to_check="${ac_tool_prefix}nm"
+ if test -n "$ac_tool_prefix" && test "$build" = "$host"; then
+ lt_nm_to_check="$lt_nm_to_check nm"
+ fi
+ for lt_tmp_nm in $lt_nm_to_check; do
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ tmp_nm="$ac_dir/$lt_tmp_nm"
+ if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ # Tru64's nm complains that /dev/null is an invalid object file
+ case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in
+ */dev/null* | *'Invalid file or object type'*)
+ lt_cv_path_NM="$tmp_nm -B"
+ break
+ ;;
+ *)
+ case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in
+ */dev/null*)
+ lt_cv_path_NM="$tmp_nm -p"
+ break
+ ;;
+ *)
+ lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+ done
+ : ${lt_cv_path_NM=no}
+fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5
+$as_echo "$lt_cv_path_NM" >&6; }
+if test "$lt_cv_path_NM" != "no"; then
+ NM="$lt_cv_path_NM"
+else
+ # Didn't find any BSD compatible name lister, look for dumpbin.
+ if test -n "$DUMPBIN"; then :
+ # Let the user override the test.
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in dumpbin "link -dump"
+ 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_DUMPBIN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DUMPBIN"; then
+ ac_cv_prog_DUMPBIN="$DUMPBIN" # 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_DUMPBIN="$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
+DUMPBIN=$ac_cv_prog_DUMPBIN
+if test -n "$DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5
+$as_echo "$DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$DUMPBIN" && break
+ done
+fi
+if test -z "$DUMPBIN"; then
+ ac_ct_DUMPBIN=$DUMPBIN
+ for ac_prog in dumpbin "link -dump"
+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_DUMPBIN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DUMPBIN"; then
+ ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # 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_DUMPBIN="$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_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN
+if test -n "$ac_ct_DUMPBIN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5
+$as_echo "$ac_ct_DUMPBIN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_DUMPBIN" && break
+done
+
+ if test "x$ac_ct_DUMPBIN" = x; then
+ DUMPBIN=":"
+ 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
+ DUMPBIN=$ac_ct_DUMPBIN
+ fi
+fi
+
+ case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+ *COFF*)
+ DUMPBIN="$DUMPBIN -symbols"
+ ;;
+ *)
+ DUMPBIN=:
+ ;;
+ esac
+ fi
+
+ if test "$DUMPBIN" != ":"; then
+ NM="$DUMPBIN"
+ fi
+fi
+test -z "$NM" && NM=nm
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
+$as_echo_n "checking the name lister ($NM) interface... " >&6; }
+if test "${lt_cv_nm_interface+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_nm_interface="BSD nm"
+ echo "int some_variable = 0;" > conftest.$ac_ext
+ (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
+ (eval "$ac_compile" 2>conftest.err)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
+ cat conftest.err >&5
+ (eval echo "\"\$as_me:$LINENO: output\"" >&5)
+ cat conftest.out >&5
+ if $GREP 'External.*some_variable' conftest.out > /dev/null; then
+ lt_cv_nm_interface="MS dumpbin"
+ fi
+ rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5
+$as_echo "$lt_cv_nm_interface" >&6; }
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
+$as_echo_n "checking whether ln -s works... " >&6; }
+LN_S=$as_ln_s
+if test "$LN_S" = "ln -s"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5
+$as_echo "no, using $LN_S" >&6; }
+fi
+
+# find the maximum length of command line arguments
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
+$as_echo_n "checking the maximum length of command line arguments... " >&6; }
+if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ i=0
+ teststring="ABCD"
+
+ case $build_os in
+ msdosdjgpp*)
+ # On DJGPP, this test can blow up pretty badly due to problems in libc
+ # (any single argument exceeding 2000 bytes causes a buffer overrun
+ # during glob expansion). Even if it were fixed, the result of this
+ # check would be larger than it should be.
+ lt_cv_sys_max_cmd_len=12288; # 12K is about right
+ ;;
+
+ gnu*)
+ # Under GNU Hurd, this test is not required because there is
+ # no limit to the length of command line arguments.
+ # Libtool will interpret -1 as no limit whatsoever
+ lt_cv_sys_max_cmd_len=-1;
+ ;;
+
+ cygwin* | mingw* | cegcc*)
+ # On Win9x/ME, this test blows up -- it succeeds, but takes
+ # about 5 minutes as the teststring grows exponentially.
+ # Worse, since 9x/ME are not pre-emptively multitasking,
+ # you end up with a "frozen" computer, even though with patience
+ # the test eventually succeeds (with a max line length of 256k).
+ # Instead, let's just punt: use the minimum linelength reported by
+ # all of the supported platforms: 8192 (on NT/2K/XP).
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ mint*)
+ # On MiNT this can take a long time and run out of memory.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ amigaos*)
+ # On AmigaOS with pdksh, this test takes hours, literally.
+ # So we just punt and use a minimum line length of 8192.
+ lt_cv_sys_max_cmd_len=8192;
+ ;;
+
+ netbsd* | freebsd* | openbsd* | darwin* | dragonfly*)
+ # This has been around since 386BSD, at least. Likely further.
+ if test -x /sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax`
+ elif test -x /usr/sbin/sysctl; then
+ lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax`
+ else
+ lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs
+ fi
+ # And add a safety zone
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ ;;
+
+ interix*)
+ # We know the value 262144 and hardcode it with a safety zone (like BSD)
+ lt_cv_sys_max_cmd_len=196608
+ ;;
+
+ osf*)
+ # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
+ # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
+ # nice to cause kernel panics so lets avoid the loop below.
+ # First set a reasonable default.
+ lt_cv_sys_max_cmd_len=16384
+ #
+ if test -x /sbin/sysconfig; then
+ case `/sbin/sysconfig -q proc exec_disable_arg_limit` in
+ *1*) lt_cv_sys_max_cmd_len=-1 ;;
+ esac
+ fi
+ ;;
+ sco3.2v5*)
+ lt_cv_sys_max_cmd_len=102400
+ ;;
+ sysv5* | sco5v6* | sysv4.2uw2*)
+ kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null`
+ if test -n "$kargmax"; then
+ lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'`
+ else
+ lt_cv_sys_max_cmd_len=32768
+ fi
+ ;;
+ *)
+ lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null`
+ if test -n "$lt_cv_sys_max_cmd_len"; then
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4`
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3`
+ else
+ # Make teststring a little bigger before we do anything with it.
+ # a 1K string should be a reasonable start.
+ for i in 1 2 3 4 5 6 7 8 ; do
+ teststring=$teststring$teststring
+ done
+ SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}}
+ # If test is not a shell built-in, we'll probably end up computing a
+ # maximum length that is only half of the actual maximum length, but
+ # we can't tell.
+ while { test "X"`func_fallback_echo "$teststring$teststring" 2>/dev/null` \
+ = "X$teststring$teststring"; } >/dev/null 2>&1 &&
+ test $i != 17 # 1/2 MB should be enough
+ do
+ i=`expr $i + 1`
+ teststring=$teststring$teststring
+ done
+ # Only check the string length outside the loop.
+ lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1`
+ teststring=
+ # Add a significant safety factor because C++ compilers can tack on
+ # massive amounts of additional arguments before passing them to the
+ # linker. It appears as though 1/2 is a usable value.
+ lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2`
+ fi
+ ;;
+ esac
+
+fi
+
+if test -n $lt_cv_sys_max_cmd_len ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5
+$as_echo "$lt_cv_sys_max_cmd_len" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
+fi
+max_cmd_len=$lt_cv_sys_max_cmd_len
+
+
+
+
+
+
+: ${CP="cp -f"}
+: ${MV="mv -f"}
+: ${RM="rm -f"}
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5
+$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; }
+# Try some XSI features
+xsi_shell=no
+( _lt_dummy="a/b/c"
+ test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
+ = c,a/b,, \
+ && eval 'test $(( 1 + 1 )) -eq 2 \
+ && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
+ && xsi_shell=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5
+$as_echo "$xsi_shell" >&6; }
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5
+$as_echo_n "checking whether the shell understands \"+=\"... " >&6; }
+lt_shell_append=no
+( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \
+ >/dev/null 2>&1 \
+ && lt_shell_append=yes
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5
+$as_echo "$lt_shell_append" >&6; }
+
+
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+ lt_unset=unset
+else
+ lt_unset=false
+fi
+
+
+
+
+
+# test EBCDIC or ASCII
+case `echo X|tr X '\101'` in
+ A) # ASCII based system
+ # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr
+ lt_SP2NL='tr \040 \012'
+ lt_NL2SP='tr \015\012 \040\040'
+ ;;
+ *) # EBCDIC based system
+ lt_SP2NL='tr \100 \n'
+ lt_NL2SP='tr \r\n \100\100'
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
+$as_echo_n "checking for $LD option to reload object files... " >&6; }
+if test "${lt_cv_ld_reload_flag+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_reload_flag='-r'
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5
+$as_echo "$lt_cv_ld_reload_flag" >&6; }
+reload_flag=$lt_cv_ld_reload_flag
+case $reload_flag in
+"" | " "*) ;;
+*) reload_flag=" $reload_flag" ;;
+esac
+reload_cmds='$LD$reload_flag -o $output$reload_objs'
+case $host_os in
+ darwin*)
+ if test "$GCC" = yes; then
+ reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
+ else
+ reload_cmds='$LD$reload_flag -o $output$reload_objs'
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args.
+set dummy ${ac_tool_prefix}objdump; 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_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OBJDUMP"; then
+ ac_cv_prog_OBJDUMP="$OBJDUMP" # 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_OBJDUMP="${ac_tool_prefix}objdump"
+ $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
+OBJDUMP=$ac_cv_prog_OBJDUMP
+if test -n "$OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5
+$as_echo "$OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OBJDUMP"; then
+ ac_ct_OBJDUMP=$OBJDUMP
+ # Extract the first word of "objdump", so it can be a program name with args.
+set dummy objdump; 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_OBJDUMP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OBJDUMP"; then
+ ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # 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_OBJDUMP="objdump"
+ $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_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP
+if test -n "$ac_ct_OBJDUMP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5
+$as_echo "$ac_ct_OBJDUMP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OBJDUMP" = x; then
+ OBJDUMP="false"
+ 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
+ OBJDUMP=$ac_ct_OBJDUMP
+ fi
+else
+ OBJDUMP="$ac_cv_prog_OBJDUMP"
+fi
+
+test -z "$OBJDUMP" && OBJDUMP=objdump
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
+$as_echo_n "checking how to recognize dependent libraries... " >&6; }
+if test "${lt_cv_deplibs_check_method+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_file_magic_cmd='$MAGIC_CMD'
+lt_cv_file_magic_test_file=
+lt_cv_deplibs_check_method='unknown'
+# Need to set the preceding variable on all platforms that support
+# interlibrary dependencies.
+# 'none' -- dependencies not supported.
+# `unknown' -- same as none, but documents that we really don't know.
+# 'pass_all' -- all dependencies passed with no checks.
+# 'test_compile' -- check by making test program.
+# 'file_magic [[regex]]' -- check by looking for files in library path
+# which responds to the $file_magic_cmd with a given extended regex.
+# If you have `file' or equivalent on your system and you're not sure
+# whether `pass_all' will *always* work, you probably want this one.
+
+case $host_os in
+aix[4-9]*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+beos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+bsdi[45]*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)'
+ lt_cv_file_magic_cmd='/usr/bin/file -L'
+ lt_cv_file_magic_test_file=/shlib/libc.so
+ ;;
+
+cygwin*)
+ # func_win32_libid is a shell function defined in ltmain.sh
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ ;;
+
+mingw* | pw32*)
+ # Base MSYS/MinGW do not provide the 'file' command needed by
+ # func_win32_libid shell function, so use a weaker test based on 'objdump',
+ # unless we find 'file', for example because we are cross-compiling.
+ # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+ if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
+ lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
+ lt_cv_file_magic_cmd='func_win32_libid'
+ else
+ lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ fi
+ ;;
+
+cegcc*)
+ # use the weaker test based on 'objdump'. See mingw*.
+ lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
+ lt_cv_file_magic_cmd='$OBJDUMP -f'
+ ;;
+
+darwin* | rhapsody*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+freebsd* | dragonfly*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ case $host_cpu in
+ i*86 )
+ # Not sure whether the presence of OpenBSD here was a mistake.
+ # Let's accept both of them until this is cleared up.
+ lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*`
+ ;;
+ esac
+ else
+ lt_cv_deplibs_check_method=pass_all
+ fi
+ ;;
+
+gnu*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+haiku*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+hpux10.20* | hpux11*)
+ lt_cv_file_magic_cmd=/usr/bin/file
+ case $host_cpu in
+ ia64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64'
+ lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
+ ;;
+ hppa*64*)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
+ lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
+ ;;
+ *)
+ lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
+ lt_cv_file_magic_test_file=/usr/lib/libc.sl
+ ;;
+ esac
+ ;;
+
+interix[3-9]*)
+ # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$'
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $LD in
+ *-32|*"-32 ") libmagic=32-bit;;
+ *-n32|*"-n32 ") libmagic=N32;;
+ *-64|*"-64 ") libmagic=64-bit;;
+ *) libmagic=never-match;;
+ esac
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$'
+ fi
+ ;;
+
+newos6*)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)'
+ lt_cv_file_magic_cmd=/usr/bin/file
+ lt_cv_file_magic_test_file=/usr/lib/libnls.so
+ ;;
+
+*nto* | *qnx*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+openbsd*)
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$'
+ else
+ lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$'
+ fi
+ ;;
+
+osf3* | osf4* | osf5*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+rdos*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+solaris*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+
+sysv4 | sysv4.3*)
+ case $host_vendor in
+ motorola)
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]'
+ lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*`
+ ;;
+ ncr)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ sequent)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )'
+ ;;
+ sni)
+ lt_cv_file_magic_cmd='/bin/file'
+ lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib"
+ lt_cv_file_magic_test_file=/lib/libc.so
+ ;;
+ siemens)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ pc)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+ esac
+ ;;
+
+tpf*)
+ lt_cv_deplibs_check_method=pass_all
+ ;;
+esac
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
+$as_echo "$lt_cv_deplibs_check_method" >&6; }
+file_magic_cmd=$lt_cv_file_magic_cmd
+deplibs_check_method=$lt_cv_deplibs_check_method
+test -z "$deplibs_check_method" && deplibs_check_method=unknown
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ar; 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_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$AR"; then
+ ac_cv_prog_AR="$AR" # 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_AR="${ac_tool_prefix}ar"
+ $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
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_AR"; then
+ ac_ct_AR=$AR
+ # Extract the first word of "ar", so it can be a program name with args.
+set dummy ar; 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_AR+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_AR"; then
+ ac_cv_prog_ac_ct_AR="$ac_ct_AR" # 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_AR="ar"
+ $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_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_AR" = x; then
+ AR="false"
+ 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
+ AR=$ac_ct_AR
+ fi
+else
+ AR="$ac_cv_prog_AR"
+fi
+
+test -z "$AR" && AR=ar
+test -z "$AR_FLAGS" && AR_FLAGS=cru
+
+
+
+
+
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args.
+set dummy ${ac_tool_prefix}strip; 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_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$STRIP"; then
+ ac_cv_prog_STRIP="$STRIP" # 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_STRIP="${ac_tool_prefix}strip"
+ $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
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+ ac_ct_STRIP=$STRIP
+ # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; 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_STRIP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_STRIP"; then
+ ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # 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_STRIP="strip"
+ $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_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_STRIP" = x; then
+ STRIP=":"
+ 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
+ STRIP=$ac_ct_STRIP
+ fi
+else
+ STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; 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_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # 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_RANLIB="${ac_tool_prefix}ranlib"
+ $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
+RANLIB=$ac_cv_prog_RANLIB
+if test -n "$RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_RANLIB"; then
+ ac_ct_RANLIB=$RANLIB
+ # Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; 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_RANLIB+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_RANLIB"; then
+ ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # 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_RANLIB="ranlib"
+ $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_RANLIB=$ac_cv_prog_ac_ct_RANLIB
+if test -n "$ac_ct_RANLIB"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ 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
+ RANLIB=$ac_ct_RANLIB
+ fi
+else
+ RANLIB="$ac_cv_prog_RANLIB"
+fi
+
+test -z "$RANLIB" && RANLIB=:
+
+
+
+
+
+
+# Determine commands to create old-style static archives.
+old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs'
+old_postinstall_cmds='chmod 644 $oldlib'
+old_postuninstall_cmds=
+
+if test -n "$RANLIB"; then
+ case $host_os in
+ openbsd*)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+ ;;
+ *)
+ old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+ ;;
+ esac
+ old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+fi
+
+case $host_os in
+ darwin*)
+ lock_old_archive_extraction=yes ;;
+ *)
+ lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+# Check for command to grab the raw symbol name followed by C symbol from nm.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
+$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
+if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+
+# These are sane defaults that work on at least a few old systems.
+# [They come from Ultrix. What could be older than Ultrix?!! ;)]
+
+# Character class describing NM global symbol codes.
+symcode='[BCDEGRST]'
+
+# Regexp to match symbols that can be accessed directly from C.
+sympat='\([_A-Za-z][_A-Za-z0-9]*\)'
+
+# Define system-specific variables.
+case $host_os in
+aix*)
+ symcode='[BCDT]'
+ ;;
+cygwin* | mingw* | pw32* | cegcc*)
+ symcode='[ABCDGISTW]'
+ ;;
+hpux*)
+ if test "$host_cpu" = ia64; then
+ symcode='[ABCDEGRST]'
+ fi
+ ;;
+irix* | nonstopux*)
+ symcode='[BCDEGRST]'
+ ;;
+osf*)
+ symcode='[BCDEGQRST]'
+ ;;
+solaris*)
+ symcode='[BDRT]'
+ ;;
+sco3.2v5*)
+ symcode='[DT]'
+ ;;
+sysv4.2uw2*)
+ symcode='[DT]'
+ ;;
+sysv5* | sco5v6* | unixware* | OpenUNIX*)
+ symcode='[ABDT]'
+ ;;
+sysv4)
+ symcode='[DFNSTU]'
+ ;;
+esac
+
+# If we're using GNU nm, then use its standard symbol codes.
+case `$NM -V 2>&1` in
+*GNU* | *'with BFD'*)
+ symcode='[ABCDGIRSTW]' ;;
+esac
+
+# Transform an extracted symbol line into a proper C declaration.
+# Some systems (esp. on ia64) link data and code symbols differently,
+# so use this general approach.
+lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
+
+# Transform an extracted symbol line into symbol name and symbol address
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'"
+
+# Handle CRLF in mingw tool chain
+opt_cr=
+case $build_os in
+mingw*)
+ opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp
+ ;;
+esac
+
+# Try without a prefix underscore, then with it.
+for ac_symprfx in "" "_"; do
+
+ # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol.
+ symxfrm="\\1 $ac_symprfx\\2 \\2"
+
+ # Write the raw and C identifiers.
+ if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+ # Fake it for dumpbin and say T for any non-static function
+ # and D for any global variable.
+ # Also find C++ and __fastcall symbols from MSVC++,
+ # which start with @ or ?.
+ lt_cv_sys_global_symbol_pipe="$AWK '"\
+" {last_section=section; section=\$ 3};"\
+" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
+" \$ 0!~/External *\|/{next};"\
+" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
+" {if(hide[section]) next};"\
+" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\
+" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\
+" s[1]~/^[@?]/{print s[1], s[1]; next};"\
+" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\
+" ' prfx=^$ac_symprfx"
+ else
+ lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
+ fi
+
+ # Check to see that the pipe works correctly.
+ pipe_works=no
+
+ rm -f conftest*
+ cat > conftest.$ac_ext <<_LT_EOF
+#ifdef __cplusplus
+extern "C" {
+#endif
+char nm_test_var;
+void nm_test_func(void);
+void nm_test_func(void){}
+#ifdef __cplusplus
+}
+#endif
+int main(){nm_test_var='a';nm_test_func();return(0);}
+_LT_EOF
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Now try to grab the symbols.
+ nlist=conftest.nm
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+ (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s "$nlist"; then
+ # Try sorting and uniquifying the output.
+ if sort "$nlist" | uniq > "$nlist"T; then
+ mv -f "$nlist"T "$nlist"
+ else
+ rm -f "$nlist"T
+ fi
+
+ # Make sure that we snagged all the symbols we need.
+ if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
+ if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
+ cat <<_LT_EOF > conftest.$ac_ext
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+_LT_EOF
+ # Now generate the symbol file.
+ eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext'
+
+ cat <<_LT_EOF >> conftest.$ac_ext
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ void *address;
+}
+lt__PROGRAM__LTX_preloaded_symbols[] =
+{
+ { "@PROGRAM@", (void *) 0 },
+_LT_EOF
+ $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext
+ cat <<\_LT_EOF >> conftest.$ac_ext
+ {0, (void *) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt__PROGRAM__LTX_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+_LT_EOF
+ # Now try linking the two files.
+ mv conftest.$ac_objext conftstm.$ac_objext
+ lt_save_LIBS="$LIBS"
+ lt_save_CFLAGS="$CFLAGS"
+ LIBS="conftstm.$ac_objext"
+ CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext}; then
+ pipe_works=yes
+ fi
+ LIBS="$lt_save_LIBS"
+ CFLAGS="$lt_save_CFLAGS"
+ else
+ echo "cannot find nm_test_func in $nlist" >&5
+ fi
+ else
+ echo "cannot find nm_test_var in $nlist" >&5
+ fi
+ else
+ echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5
+ fi
+ else
+ echo "$progname: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ fi
+ rm -rf conftest* conftst*
+
+ # Do not use the global_symbol_pipe unless it works.
+ if test "$pipe_works" = yes; then
+ break
+ else
+ lt_cv_sys_global_symbol_pipe=
+ fi
+done
+
+fi
+
+if test -z "$lt_cv_sys_global_symbol_pipe"; then
+ lt_cv_sys_global_symbol_to_cdecl=
+fi
+if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5
+$as_echo "ok" >&6; }
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Check whether --enable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then :
+ enableval=$enable_libtool_lock;
+fi
+
+test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case $host in
+ia64-*-hpux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *ELF-32*)
+ HPUX_IA64_MODE="32"
+ ;;
+ *ELF-64*)
+ HPUX_IA64_MODE="64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line '$LINENO' "configure"' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -melf32bsmip"
+ ;;
+ *N32*)
+ LD="${LD-ld} -melf32bmipn32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -melf64bmip"
+ ;;
+ esac
+ else
+ case `/usr/bin/file conftest.$ac_objext` in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ fi
+ rm -rf conftest*
+ ;;
+
+x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \
+s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *32-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_i386_fbsd"
+ ;;
+ x86_64-*linux*)
+ case `/usr/bin/file conftest.o` in
+ *x86-64*)
+ LD="${LD-ld} -m elf32_x86_64"
+ ;;
+ *)
+ LD="${LD-ld} -m elf_i386"
+ ;;
+ esac
+ ;;
+ ppc64-*linux*|powerpc64-*linux*)
+ LD="${LD-ld} -m elf32ppclinux"
+ ;;
+ s390x-*linux*)
+ LD="${LD-ld} -m elf_s390"
+ ;;
+ sparc64-*linux*)
+ LD="${LD-ld} -m elf32_sparc"
+ ;;
+ esac
+ ;;
+ *64-bit*)
+ case $host in
+ x86_64-*kfreebsd*-gnu)
+ LD="${LD-ld} -m elf_x86_64_fbsd"
+ ;;
+ x86_64-*linux*)
+ LD="${LD-ld} -m elf_x86_64"
+ ;;
+ ppc*-*linux*|powerpc*-*linux*)
+ LD="${LD-ld} -m elf64ppc"
+ ;;
+ s390*-*linux*|s390*-*tpf*)
+ LD="${LD-ld} -m elf64_s390"
+ ;;
+ sparc*-*linux*)
+ LD="${LD-ld} -m elf64_sparc"
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
+$as_echo_n "checking whether the C compiler needs -belf... " >&6; }
+if test "${lt_cv_cc_needs_belf+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ 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
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_cc_needs_belf=yes
+else
+ lt_cv_cc_needs_belf=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ 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
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5
+$as_echo "$lt_cv_cc_needs_belf" >&6; }
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+sparc*-*solaris*)
+ # Find out which ABI we are using.
+ echo 'int i;' > conftest.$ac_ext
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ case `/usr/bin/file conftest.o` in
+ *64-bit*)
+ case $lt_cv_prog_gnu_ld in
+ yes*) LD="${LD-ld} -m elf64_sparc" ;;
+ *)
+ if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
+ LD="${LD-ld} -64"
+ fi
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+esac
+
+need_locks="$enable_libtool_lock"
+
+
+ case $host_os in
+ rhapsody* | darwin*)
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dsymutil; 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_DSYMUTIL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$DSYMUTIL"; then
+ ac_cv_prog_DSYMUTIL="$DSYMUTIL" # 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_DSYMUTIL="${ac_tool_prefix}dsymutil"
+ $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
+DSYMUTIL=$ac_cv_prog_DSYMUTIL
+if test -n "$DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5
+$as_echo "$DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_DSYMUTIL"; then
+ ac_ct_DSYMUTIL=$DSYMUTIL
+ # Extract the first word of "dsymutil", so it can be a program name with args.
+set dummy dsymutil; 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_DSYMUTIL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_DSYMUTIL"; then
+ ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # 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_DSYMUTIL="dsymutil"
+ $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_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL
+if test -n "$ac_ct_DSYMUTIL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5
+$as_echo "$ac_ct_DSYMUTIL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_DSYMUTIL" = x; then
+ DSYMUTIL=":"
+ 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
+ DSYMUTIL=$ac_ct_DSYMUTIL
+ fi
+else
+ DSYMUTIL="$ac_cv_prog_DSYMUTIL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args.
+set dummy ${ac_tool_prefix}nmedit; 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_NMEDIT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$NMEDIT"; then
+ ac_cv_prog_NMEDIT="$NMEDIT" # 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_NMEDIT="${ac_tool_prefix}nmedit"
+ $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
+NMEDIT=$ac_cv_prog_NMEDIT
+if test -n "$NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5
+$as_echo "$NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_NMEDIT"; then
+ ac_ct_NMEDIT=$NMEDIT
+ # Extract the first word of "nmedit", so it can be a program name with args.
+set dummy nmedit; 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_NMEDIT+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_NMEDIT"; then
+ ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # 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_NMEDIT="nmedit"
+ $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_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT
+if test -n "$ac_ct_NMEDIT"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5
+$as_echo "$ac_ct_NMEDIT" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_NMEDIT" = x; then
+ NMEDIT=":"
+ 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
+ NMEDIT=$ac_ct_NMEDIT
+ fi
+else
+ NMEDIT="$ac_cv_prog_NMEDIT"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args.
+set dummy ${ac_tool_prefix}lipo; 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_LIPO+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$LIPO"; then
+ ac_cv_prog_LIPO="$LIPO" # 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_LIPO="${ac_tool_prefix}lipo"
+ $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
+LIPO=$ac_cv_prog_LIPO
+if test -n "$LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5
+$as_echo "$LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_LIPO"; then
+ ac_ct_LIPO=$LIPO
+ # Extract the first word of "lipo", so it can be a program name with args.
+set dummy lipo; 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_LIPO+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_LIPO"; then
+ ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # 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_LIPO="lipo"
+ $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_LIPO=$ac_cv_prog_ac_ct_LIPO
+if test -n "$ac_ct_LIPO"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5
+$as_echo "$ac_ct_LIPO" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_LIPO" = x; then
+ LIPO=":"
+ 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
+ LIPO=$ac_ct_LIPO
+ fi
+else
+ LIPO="$ac_cv_prog_LIPO"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool; 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_OTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL"; then
+ ac_cv_prog_OTOOL="$OTOOL" # 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_OTOOL="${ac_tool_prefix}otool"
+ $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
+OTOOL=$ac_cv_prog_OTOOL
+if test -n "$OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5
+$as_echo "$OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL"; then
+ ac_ct_OTOOL=$OTOOL
+ # Extract the first word of "otool", so it can be a program name with args.
+set dummy otool; 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_OTOOL+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL"; then
+ ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # 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_OTOOL="otool"
+ $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_OTOOL=$ac_cv_prog_ac_ct_OTOOL
+if test -n "$ac_ct_OTOOL"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5
+$as_echo "$ac_ct_OTOOL" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL" = x; then
+ OTOOL=":"
+ 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
+ OTOOL=$ac_ct_OTOOL
+ fi
+else
+ OTOOL="$ac_cv_prog_OTOOL"
+fi
+
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args.
+set dummy ${ac_tool_prefix}otool64; 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_OTOOL64+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$OTOOL64"; then
+ ac_cv_prog_OTOOL64="$OTOOL64" # 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_OTOOL64="${ac_tool_prefix}otool64"
+ $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
+OTOOL64=$ac_cv_prog_OTOOL64
+if test -n "$OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5
+$as_echo "$OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_OTOOL64"; then
+ ac_ct_OTOOL64=$OTOOL64
+ # Extract the first word of "otool64", so it can be a program name with args.
+set dummy otool64; 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_OTOOL64+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_OTOOL64"; then
+ ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # 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_OTOOL64="otool64"
+ $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_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64
+if test -n "$ac_ct_OTOOL64"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5
+$as_echo "$ac_ct_OTOOL64" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+ if test "x$ac_ct_OTOOL64" = x; then
+ OTOOL64=":"
+ 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
+ OTOOL64=$ac_ct_OTOOL64
+ fi
+else
+ OTOOL64="$ac_cv_prog_OTOOL64"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
+$as_echo_n "checking for -single_module linker flag... " >&6; }
+if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_apple_cc_single_mod=no
+ if test -z "${LT_MULTI_MODULE}"; then
+ # By default we will add the -single_module flag. You can override
+ # by either setting the environment variable LT_MULTI_MODULE
+ # non-empty at configure time, or by adding -multi_module to the
+ # link flags.
+ rm -rf libconftest.dylib*
+ echo "int foo(void){return 1;}" > conftest.c
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+-dynamiclib -Wl,-single_module conftest.c" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
+ -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
+ _lt_result=$?
+ if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+ lt_cv_apple_cc_single_mod=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -rf libconftest.dylib*
+ rm -f conftest.*
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
+$as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
+$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
+if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_exported_symbols_list=no
+ save_LDFLAGS=$LDFLAGS
+ echo "_main" > conftest.sym
+ LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ lt_cv_ld_exported_symbols_list=yes
+else
+ lt_cv_ld_exported_symbols_list=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
+$as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if test "${lt_cv_ld_force_load+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_ld_force_load=no
+ cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+ $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+ echo "$AR cru libconftest.a conftest.o" >&5
+ $AR cru libconftest.a conftest.o 2>&5
+ cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+ echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+ $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+ _lt_result=$?
+ if test -f conftest && test ! -s conftest.err && test $_lt_result = 0 && $GREP forced_load conftest 2>&1 >/dev/null; then
+ lt_cv_ld_force_load=yes
+ else
+ cat conftest.err >&5
+ fi
+ rm -f conftest.err libconftest.a conftest conftest.c
+ rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
+ case $host_os in
+ rhapsody* | darwin1.[012])
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
+ darwin1.*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ darwin*) # darwin 5.x on
+ # if running on 10.5 or later, the deployment target defaults
+ # to the OS version, if on x86, and 10.4, the deployment
+ # target defaults to 10.4. Don't you love it?
+ case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in
+ 10.0,*86*-darwin8*|10.0,*-darwin[91]*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ 10.[012]*)
+ _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;;
+ 10.*)
+ _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;;
+ esac
+ ;;
+ esac
+ if test "$lt_cv_apple_cc_single_mod" = "yes"; then
+ _lt_dar_single_mod='$single_module'
+ fi
+ if test "$lt_cv_ld_exported_symbols_list" = "yes"; then
+ _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym'
+ else
+ _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
+ fi
+ if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
+ _lt_dsymutil='~$DSYMUTIL $lib || :'
+ else
+ _lt_dsymutil=
+ fi
+ ;;
+ esac
+
+for ac_header in dlfcn.h
+do :
+ ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
+"
+if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_DLFCN_H 1
+_ACEOF
+
+fi
+
+done
+
+
+
+
+
+
+# Set options
+
+
+
+
+ enable_win32_dll=no
+
+
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_shared=yes ;;
+ no) enable_shared=no ;;
+ *)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_shared=yes
+fi
+
+
+
+
+
+
+
+
+
+ # Check whether --enable-static was given.
+if test "${enable_static+set}" = set; then :
+ enableval=$enable_static; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_static=yes ;;
+ no) enable_static=no ;;
+ *)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_static=yes
+fi
+
+
+
+
+
+
+
+
+
+
+# Check whether --with-pic was given.
+if test "${with_pic+set}" = set; then :
+ withval=$with_pic; pic_mode="$withval"
+else
+ pic_mode=default
+fi
+
+
+test -z "$pic_mode" && pic_mode=default
+
+
+
+
+
+
+
+ # Check whether --enable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then :
+ enableval=$enable_fast_install; p=${PACKAGE-default}
+ case $enableval in
+ yes) enable_fast_install=yes ;;
+ no) enable_fast_install=no ;;
+ *)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+ for pkg in $enableval; do
+ IFS="$lt_save_ifs"
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$lt_save_ifs"
+ ;;
+ esac
+else
+ enable_fast_install=yes
+fi
+
+
+
+
+
+
+
+
+
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ltmain"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+test -z "$LN_S" && LN_S="ln -s"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
+$as_echo_n "checking for objdir... " >&6; }
+if test "${lt_cv_objdir+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ rm -f .libs 2>/dev/null
+mkdir .libs 2>/dev/null
+if test -d .libs; then
+ lt_cv_objdir=.libs
+else
+ # MS-DOS does not allow filenames that begin with a dot.
+ lt_cv_objdir=_libs
+fi
+rmdir .libs 2>/dev/null
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5
+$as_echo "$lt_cv_objdir" >&6; }
+objdir=$lt_cv_objdir
+
+
+
+
+
+cat >>confdefs.h <<_ACEOF
+#define LT_OBJDIR "$lt_cv_objdir/"
+_ACEOF
+
+
+
+
+case $host_os in
+aix3*)
+ # AIX sometimes has problems with the GCC collect2 program. For some
+ # reason, if we set the COLLECT_NAMES environment variable, the problems
+ # vanish in a puff of smoke.
+ if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+ fi
+ ;;
+esac
+
+# Global variables:
+ofile=libtool
+can_build_shared=yes
+
+# All known linkers require a `.a' archive for static linking (except MSVC,
+# which needs '.lib').
+libext=a
+
+with_gnu_ld="$lt_cv_prog_gnu_ld"
+
+old_CC="$CC"
+old_CFLAGS="$CFLAGS"
+
+# Set sane defaults for various variables
+test -z "$CC" && CC=cc
+test -z "$LTCC" && LTCC=$CC
+test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS
+test -z "$LD" && LD=ld
+test -z "$ac_objext" && ac_objext=o
+
+for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+# Only perform the check for file, if the check method requires it
+test -z "$MAGIC_CMD" && MAGIC_CMD=file
+case $deplibs_check_method in
+file_magic*)
+ if test "$file_magic_cmd" = '$MAGIC_CMD'; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
+$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/${ac_tool_prefix}file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+
+
+
+if test -z "$lt_cv_path_MAGIC_CMD"; then
+ if test -n "$ac_tool_prefix"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
+$as_echo_n "checking for file... " >&6; }
+if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $MAGIC_CMD in
+[\\/*] | ?:[\\/]*)
+ lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path.
+ ;;
+*)
+ lt_save_MAGIC_CMD="$MAGIC_CMD"
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ ac_dummy="/usr/bin$PATH_SEPARATOR$PATH"
+ for ac_dir in $ac_dummy; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/file; then
+ lt_cv_path_MAGIC_CMD="$ac_dir/file"
+ if test -n "$file_magic_test_file"; then
+ case $deplibs_check_method in
+ "file_magic "*)
+ file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"`
+ MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+ if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null |
+ $EGREP "$file_magic_regex" > /dev/null; then
+ :
+ else
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the command libtool uses to detect shared libraries,
+*** $file_magic_cmd, produces output that libtool cannot recognize.
+*** The result is that libtool may fail to recognize shared libraries
+*** as such. This will affect the creation of libtool libraries that
+*** depend on shared libraries, but programs linked with such libtool
+*** libraries will work regardless of this problem. Nevertheless, you
+*** may want to report the problem to your system manager and/or to
+*** bug-libtool@gnu.org
+
+_LT_EOF
+ fi ;;
+ esac
+ fi
+ break
+ fi
+ done
+ IFS="$lt_save_ifs"
+ MAGIC_CMD="$lt_save_MAGIC_CMD"
+ ;;
+esac
+fi
+
+MAGIC_CMD="$lt_cv_path_MAGIC_CMD"
+if test -n "$MAGIC_CMD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5
+$as_echo "$MAGIC_CMD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ else
+ MAGIC_CMD=:
+ fi
+fi
+
+ fi
+ ;;
+esac
+
+# Use C for the default configuration in the libtool script
+
+lt_save_CC="$CC"
+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
+
+
+# Source file extension for C test sources.
+ac_ext=c
+
+# Object file extension for compiled C test sources.
+objext=o
+objext=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="int some_variable = 0;"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='int main(){return(0);}'
+
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+# Save the default compiler, since it gets overwritten when the other
+# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP.
+compiler_DEFAULT=$CC
+
+# save warnings/boilerplate of simple test code
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+
+lt_prog_compiler_no_builtin_flag=
+
+if test "$GCC" = yes; then
+ case $cc_basename in
+ nvcc*)
+ lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+ *)
+ lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
+$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
+if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_rtti_exceptions=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="-fno-rtti -fno-exceptions"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_rtti_exceptions=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5
+$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; }
+
+if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then
+ lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions"
+else
+ :
+fi
+
+fi
+
+
+
+
+
+
+ lt_prog_compiler_wl=
+lt_prog_compiler_pic=
+lt_prog_compiler_static=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+ if test "$GCC" = yes; then
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_static='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic='-fno-common'
+ ;;
+
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static=
+ ;;
+
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+
+ msdosdjgpp*)
+ # Just because we use GCC doesn't mean we suddenly get shared libraries
+ # on systems that don't support them.
+ lt_prog_compiler_can_build_shared=no
+ enable_shared=no
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic=-Kconform_pic
+ fi
+ ;;
+
+ *)
+ lt_prog_compiler_pic='-fPIC'
+ ;;
+ esac
+
+ case $cc_basename in
+ nvcc*) # Cuda Compiler Driver 2.2
+ lt_prog_compiler_wl='-Xlinker '
+ lt_prog_compiler_pic='-Xcompiler -fPIC'
+ ;;
+ esac
+ else
+ # PORTME Check for flag to pass linker flags through the system compiler.
+ case $host_os in
+ aix*)
+ lt_prog_compiler_wl='-Wl,'
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static='-Bstatic'
+ else
+ lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+
+ mingw* | cygwin* | pw32* | os2* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ lt_prog_compiler_pic='-DDLL_EXPORT'
+ ;;
+
+ hpux9* | hpux10* | hpux11*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but
+ # not for PA HP-UX.
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic='+Z'
+ ;;
+ esac
+ # Is there a better lt_prog_compiler_static that works with the bundled CC?
+ lt_prog_compiler_static='${wl}-a ${wl}archive'
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ lt_prog_compiler_wl='-Wl,'
+ # PIC (with -KPIC) is the default.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ # old Intel for x86_64 which still supported -KPIC.
+ ecc*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # icc used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ icc* | ifort*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fPIC'
+ lt_prog_compiler_static='-static'
+ ;;
+ # Lahey Fortran 8.1.
+ lf95*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='--shared'
+ lt_prog_compiler_static='--static'
+ ;;
+ pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group compilers (*not* the Pentium gcc compiler,
+ # which looks to be a dead project)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-fpic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+ ccc*)
+ lt_prog_compiler_wl='-Wl,'
+ # All Alpha code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+ xl* | bgxl* | bgf* | mpixl*)
+ # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-qpic'
+ lt_prog_compiler_static='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ F* | *Sun*Fortran*)
+ # Sun Fortran 8.3 passes all unrecognized flags to the linker
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl=''
+ ;;
+ *Sun\ C*)
+ # Sun C 5.9
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ lt_prog_compiler_wl='-Wl,'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ newsos6)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *nto* | *qnx*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic='-fPIC -shared'
+ ;;
+
+ osf3* | osf4* | osf5*)
+ lt_prog_compiler_wl='-Wl,'
+ # All OSF/1 code is PIC.
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ rdos*)
+ lt_prog_compiler_static='-non_shared'
+ ;;
+
+ solaris*)
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ case $cc_basename in
+ f77* | f90* | f95*)
+ lt_prog_compiler_wl='-Qoption ld ';;
+ *)
+ lt_prog_compiler_wl='-Wl,';;
+ esac
+ ;;
+
+ sunos4*)
+ lt_prog_compiler_wl='-Qoption ld '
+ lt_prog_compiler_pic='-PIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4 | sysv4.2uw2* | sysv4.3*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec ;then
+ lt_prog_compiler_pic='-Kconform_pic'
+ lt_prog_compiler_static='-Bstatic'
+ fi
+ ;;
+
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_pic='-KPIC'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ unicos*)
+ lt_prog_compiler_wl='-Wl,'
+ lt_prog_compiler_can_build_shared=no
+ ;;
+
+ uts4*)
+ lt_prog_compiler_pic='-pic'
+ lt_prog_compiler_static='-Bstatic'
+ ;;
+
+ *)
+ lt_prog_compiler_can_build_shared=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic=
+ ;;
+ *)
+ lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
+$as_echo "$lt_prog_compiler_pic" >&6; }
+
+
+
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works" = xyes; then
+ case $lt_prog_compiler_pic in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;;
+ esac
+else
+ lt_prog_compiler_pic=
+ lt_prog_compiler_can_build_shared=no
+fi
+
+fi
+
+
+
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5
+$as_echo "$lt_cv_prog_compiler_static_works" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works" = xyes; then
+ :
+else
+ lt_prog_compiler_static=
+fi
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5
+$as_echo "$lt_cv_prog_compiler_c_o" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ runpath_var=
+ allow_undefined_flag=
+ always_export_symbols=no
+ archive_cmds=
+ archive_expsym_cmds=
+ compiler_needs_object=no
+ enable_shared_with_static_runtimes=no
+ export_dynamic_flag_spec=
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ hardcode_automatic=no
+ hardcode_direct=no
+ hardcode_direct_absolute=no
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld=
+ hardcode_libdir_separator=
+ hardcode_minus_L=no
+ hardcode_shlibpath_var=unsupported
+ inherit_rpath=no
+ link_all_deplibs=unknown
+ module_cmds=
+ module_expsym_cmds=
+ old_archive_from_new_cmds=
+ old_archive_from_expsyms_cmds=
+ thread_safe_flag_spec=
+ whole_archive_flag_spec=
+ # include_expsyms should be a list of space-separated symbols to be *always*
+ # included in the symbol list
+ include_expsyms=
+ # exclude_expsyms can be an extended regexp of symbols to exclude
+ # it will be wrapped by ` (' and `)$', so one must not match beginning or
+ # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc',
+ # as well as any symbol that contains `d'.
+ exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+ # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out
+ # platforms (ab)use it in PIC code, but their linkers get confused if
+ # the symbol is explicitly referenced. Since portable code cannot
+ # rely on this symbol name, it's probably fine to never include it in
+ # preloaded symbol tables.
+ # Exclude shared library initialization/finalization symbols.
+ extract_expsyms_cmds=
+
+ case $host_os in
+ cygwin* | mingw* | pw32* | cegcc*)
+ # FIXME: the MSVC++ port hasn't been tested in a loooong time
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ if test "$GCC" != yes; then
+ with_gnu_ld=no
+ fi
+ ;;
+ interix*)
+ # we just hope/assume this is gcc and not c89 (= MSVC++)
+ with_gnu_ld=yes
+ ;;
+ openbsd*)
+ with_gnu_ld=no
+ ;;
+ esac
+
+ ld_shlibs=yes
+
+ # On some targets, GNU ld is compatible enough with the native linker
+ # that we're better off using the native interface for both.
+ lt_use_gnu_ld_interface=no
+ if test "$with_gnu_ld" = yes; then
+ case $host_os in
+ aix*)
+ # The AIX port of GNU ld has always aspired to compatibility
+ # with the native linker. However, as the warning in the GNU ld
+ # block says, versions before 2.19.5* couldn't really create working
+ # shared libraries, regardless of the interface used.
+ case `$LD -v 2>&1` in
+ *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+ *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+ *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ ;;
+ *)
+ lt_use_gnu_ld_interface=yes
+ ;;
+ esac
+ fi
+
+ if test "$lt_use_gnu_ld_interface" = yes; then
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ wlarc='${wl}'
+
+ # Set some defaults for GNU ld with shared library support. These
+ # are reset later if shared libraries are not supported. Putting them
+ # here allows them to be overridden if necessary.
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec='${wl}--export-dynamic'
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec=
+ fi
+ supports_anon_versioning=no
+ case `$LD -v 2>&1` in
+ *GNU\ gold*) supports_anon_versioning=yes ;;
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
+ *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
+ *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
+ *\ 2.11.*) ;; # other 2.11 versions
+ *) supports_anon_versioning=yes ;;
+ esac
+
+ # See if GNU ld supports shared libraries.
+ case $host_os in
+ aix[3-9]*)
+ # On AIX/PPC, the GNU linker is very broken
+ if test "$host_cpu" != ia64; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: the GNU linker, at least up to release 2.19, is reported
+*** to be unable to reliably create shared libraries on AIX.
+*** Therefore, libtool is disabling shared libraries support. If you
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
+
+_LT_EOF
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec='-L$libdir'
+ export_dynamic_flag_spec='${wl}--export-all-symbols'
+ allow_undefined_flag=unsupported
+ always_export_symbols=no
+ enable_shared_with_static_runtimes=yes
+ export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ haiku*)
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs=yes
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+
+ gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
+ tmp_diet=no
+ if test "$host_os" = linux-dietlibc; then
+ case $cc_basename in
+ diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn)
+ esac
+ fi
+ if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
+ && test "$tmp_diet" = no
+ then
+ tmp_addflag=
+ tmp_sharedflag='-shared'
+ case $cc_basename,$host_cpu in
+ pgcc*) # Portland Group C compiler
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag'
+ ;;
+ pgf77* | pgf90* | pgf95* | pgfortran*)
+ # Portland Group f77 and f90 compilers
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ tmp_addflag=' $pic_flag -Mnomain' ;;
+ ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64
+ tmp_addflag=' -i_dynamic' ;;
+ efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64
+ tmp_addflag=' -i_dynamic -nofor_main' ;;
+ ifc* | ifort*) # Intel Fortran compiler
+ tmp_addflag=' -nofor_main' ;;
+ lf95*) # Lahey Fortran 8.1
+ whole_archive_flag_spec=
+ tmp_sharedflag='--shared' ;;
+ xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
+ tmp_sharedflag='-qmkshrobj'
+ tmp_addflag= ;;
+ nvcc*) # Cuda Compiler Driver 2.2
+ whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ ;;
+ esac
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*) # Sun C 5.9
+ whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object=yes
+ tmp_sharedflag='-G' ;;
+ *Sun\ F*) # Sun Fortran 8.3
+ tmp_sharedflag='-G' ;;
+ esac
+ archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+
+ case $cc_basename in
+ xlf* | bgf* | bgxlf* | mpixlf*)
+ # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
+ whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
+ hardcode_libdir_flag_spec=
+ hardcode_libdir_flag_spec_ld='-rpath $libdir'
+ archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ esac
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
+ wlarc=
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ fi
+ ;;
+
+ solaris*)
+ if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: The releases 2.8.* of the GNU linker cannot reliably
+*** create shared libraries on Solaris systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.9.1 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
+ case `$LD -v 2>&1` in
+ *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
+ ld_shlibs=no
+ cat <<_LT_EOF 1>&2
+
+*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not
+*** reliably create shared libraries on SCO systems. Therefore, libtool
+*** is disabling shared libraries support. We urge you to upgrade GNU
+*** binutils to release 2.16.91.0.3 or newer. Another option is to modify
+*** your PATH or compiler configuration so that the native linker is
+*** used, and then restart.
+
+_LT_EOF
+ ;;
+ *)
+ # For security reasons, it is highly recommended that you always
+ # use absolute paths for naming shared libraries, and exclude the
+ # DT_RUNPATH tag from executables and libraries. But doing so
+ # requires that you compile everything twice, which is a pain.
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+ ;;
+
+ sunos4*)
+ archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ wlarc=
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ else
+ ld_shlibs=no
+ fi
+ ;;
+ esac
+
+ if test "$ld_shlibs" = no; then
+ runpath_var=
+ hardcode_libdir_flag_spec=
+ export_dynamic_flag_spec=
+ whole_archive_flag_spec=
+ fi
+ else
+ # PORTME fill in a description of your system's linker (not GNU ld)
+ case $host_os in
+ aix3*)
+ allow_undefined_flag=unsupported
+ always_export_symbols=yes
+ archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname'
+ # Note: this linker hardcodes the directories in LIBPATH if there
+ # are no directories specified by -L.
+ hardcode_minus_L=yes
+ if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then
+ # Neither direct hardcoding nor static linking is supported with a
+ # broken collect2.
+ hardcode_direct=unsupported
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global
+ # defined symbols, whereas GNU nm marks them as "W".
+ 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'
+ fi
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
+ aix_use_runtimelinking=yes
+ break
+ fi
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds=''
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ file_list_spec='${wl}-f,'
+
+ if test "$GCC" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L=yes
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_libdir_separator=
+ fi
+ ;;
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to export.
+ always_export_symbols=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag='-berok'
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag="-z nodefs"
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag=' ${wl}-bernotok'
+ allow_undefined_flag=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec='$convenience'
+ fi
+ archive_cmds_need_lc=yes
+ # This is similar to how AIX traditionally builds its shared libraries.
+ archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds=''
+ ;;
+ m68k)
+ archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ ;;
+ esac
+ ;;
+
+ bsdi[45]*)
+ export_dynamic_flag_spec=-rdynamic
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # When not using gcc, we currently assume that we are using
+ # Microsoft Visual C++.
+ # hardcode_libdir_flag_spec is actually meaningless, as there is
+ # no search path for DLLs.
+ hardcode_libdir_flag_spec=' '
+ allow_undefined_flag=unsupported
+ # Tell ltmain to make .lib files, not .a files.
+ libext=lib
+ # Tell ltmain to make .dll files, not .so files.
+ shrext_cmds=".dll"
+ # FIXME: Setting linknames here is a bad hack.
+ archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+ # The linker will automatically build a .lib file if we build a DLL.
+ old_archive_from_new_cmds='true'
+ # FIXME: Should let the user specify the lib program.
+ old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+ fix_srcfile_path='`cygpath -w "$srcfile"`'
+ enable_shared_with_static_runtimes=yes
+ ;;
+
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc=no
+ hardcode_direct=no
+ hardcode_automatic=yes
+ hardcode_shlibpath_var=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ else
+ whole_archive_flag_spec=''
+ fi
+ link_all_deplibs=yes
+ allow_undefined_flag="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+
+ else
+ ld_shlibs=no
+ fi
+
+ ;;
+
+ dgux*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
+ # support. Future versions do this automatically, but an explicit c++rt0.o
+ # does not break anything, and helps significantly (at the cost of a little
+ # extra space).
+ freebsd2.2*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # Unfortunately, older versions of FreeBSD 2 do not have this feature.
+ freebsd2.*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
+ freebsd* | dragonfly*)
+ archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ hpux9*)
+ if test "$GCC" = yes; then
+ archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ fi
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ export_dynamic_flag_spec='${wl}-E'
+ ;;
+
+ hpux10*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_flag_spec_ld='+b $libdir'
+ hardcode_libdir_separator=:
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ fi
+ ;;
+
+ hpux11*)
+ if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ else
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+
+ # Older versions of the 11.00 compiler do not understand -b yet
+ # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if test "${lt_cv_prog_compiler__b+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler__b=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -b"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler__b=yes
+ fi
+ else
+ lt_cv_prog_compiler__b=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+ archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+ archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
+ ;;
+ esac
+ fi
+ if test "$with_gnu_ld" = no; then
+ hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct=no
+ hardcode_shlibpath_var=no
+ ;;
+ *)
+ hardcode_direct=yes
+ hardcode_direct_absolute=yes
+ export_dynamic_flag_spec='${wl}-E'
+
+ # hardcode_minus_L: Not really in the search PATH,
+ # but as the default location of the library.
+ hardcode_minus_L=yes
+ ;;
+ esac
+ fi
+ ;;
+
+ irix5* | irix6* | nonstopux*)
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ # Try to use the -exported_symbol ld option, if it does not
+ # work, assume that -exports_file does not work either and
+ # implicitly export all symbols.
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo(void) {}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS="$save_LDFLAGS"
+ else
+ archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ inherit_rpath=yes
+ link_all_deplibs=yes
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out
+ else
+ archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ newsos6)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ hardcode_shlibpath_var=no
+ ;;
+
+ *nto* | *qnx*)
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct=yes
+ hardcode_shlibpath_var=no
+ hardcode_direct_absolute=yes
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec='${wl}-E'
+ else
+ case $host_os in
+ openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
+ archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-R$libdir'
+ ;;
+ *)
+ archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
+ hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
+ ;;
+ esac
+ fi
+ else
+ ld_shlibs=no
+ fi
+ ;;
+
+ os2*)
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_minus_L=yes
+ allow_undefined_flag=unsupported
+ archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+ old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
+ ;;
+
+ osf3*)
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator=:
+ ;;
+
+ osf4* | osf5*) # as osf3* with the addition of -msym flag
+ if test "$GCC" = yes; then
+ allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+ else
+ allow_undefined_flag=' -expect_unresolved \*'
+ archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
+ $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+
+ # Both c and cxx compiler support -rpath directly
+ hardcode_libdir_flag_spec='-rpath $libdir'
+ fi
+ archive_cmds_need_lc='no'
+ hardcode_libdir_separator=:
+ ;;
+
+ solaris*)
+ no_undefined_flag=' -z defs'
+ if test "$GCC" = yes; then
+ wlarc='${wl}'
+ archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ else
+ case `$CC -V 2>&1` in
+ *"Compilers 5.0"*)
+ wlarc=''
+ archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp'
+ ;;
+ *)
+ wlarc='${wl}'
+ archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+ ;;
+ esac
+ fi
+ hardcode_libdir_flag_spec='-R$libdir'
+ hardcode_shlibpath_var=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'. GCC discards it without `$wl',
+ # but is careful enough not to reorder.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ if test "$GCC" = yes; then
+ whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ else
+ whole_archive_flag_spec='-z allextract$convenience -z defaultextract'
+ fi
+ ;;
+ esac
+ link_all_deplibs=yes
+ ;;
+
+ sunos4*)
+ if test "x$host_vendor" = xsequent; then
+ # Use $CC to link under sequent, because it throws in some extra .o
+ # files that make .init and .fini sections work.
+ archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags'
+ fi
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_direct=yes
+ hardcode_minus_L=yes
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4)
+ case $host_vendor in
+ sni)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=yes # is this really true???
+ ;;
+ siemens)
+ ## LD is ld it makes a PLAMLIB
+ ## CC just makes a GrossModule.
+ archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags'
+ reload_cmds='$CC -r -o $output$reload_objs'
+ hardcode_direct=no
+ ;;
+ motorola)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_direct=no #Motorola manual says yes, but my tests say they lie
+ ;;
+ esac
+ runpath_var='LD_RUN_PATH'
+ hardcode_shlibpath_var=no
+ ;;
+
+ sysv4.3*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ export_dynamic_flag_spec='-Bexport'
+ ;;
+
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_shlibpath_var=no
+ runpath_var=LD_RUN_PATH
+ hardcode_runpath_var=yes
+ ld_shlibs=yes
+ fi
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag='${wl}-z,text'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag='${wl}-z,text'
+ allow_undefined_flag='${wl}-z,nodefs'
+ archive_cmds_need_lc=no
+ hardcode_shlibpath_var=no
+ hardcode_libdir_flag_spec='${wl}-R,$libdir'
+ hardcode_libdir_separator=':'
+ link_all_deplibs=yes
+ export_dynamic_flag_spec='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ if test "$GCC" = yes; then
+ archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ else
+ archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ fi
+ ;;
+
+ uts4*)
+ archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags'
+ hardcode_libdir_flag_spec='-L$libdir'
+ hardcode_shlibpath_var=no
+ ;;
+
+ *)
+ ld_shlibs=no
+ ;;
+ esac
+
+ if test x$host_vendor = xsni; then
+ case $host in
+ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*)
+ export_dynamic_flag_spec='${wl}-Blargedynsym'
+ ;;
+ esac
+ fi
+ fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5
+$as_echo "$ld_shlibs" >&6; }
+test "$ld_shlibs" = no && can_build_shared=no
+
+with_gnu_ld=$with_gnu_ld
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if test "${lt_cv_archive_cmds_need_lc+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl
+ pic_flag=$lt_prog_compiler_pic
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag
+ allow_undefined_flag=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc=no
+ else
+ lt_cv_archive_cmds_need_lc=yes
+ fi
+ allow_undefined_flag=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+ archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+if test "$GCC" = yes; then
+ case $host_os in
+ darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
+ *) lt_awk_arg="/^libraries:/" ;;
+ esac
+ case $host_os in
+ mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+ *) lt_sed_strip_eq="s,=/,/,g" ;;
+ esac
+ lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+ case $lt_search_path_spec in
+ *\;*)
+ # if the path contains ";" then we assume it to be the separator
+ # otherwise default to the standard path separator (i.e. ":") - it is
+ # assumed that no part of a normal pathname contains ";" but that should
+ # okay in the real world where ";" in dirpaths is itself problematic.
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+ ;;
+ *)
+ lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+ ;;
+ esac
+ # Ok, now we have the path, separated by spaces, we can step through it
+ # and add multilib dir if necessary.
+ lt_tmp_lt_search_path_spec=
+ lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null`
+ for lt_sys_path in $lt_search_path_spec; do
+ if test -d "$lt_sys_path/$lt_multi_os_dir"; then
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir"
+ else
+ test -d "$lt_sys_path" && \
+ lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
+ fi
+ done
+ lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
+BEGIN {RS=" "; FS="/|\n";} {
+ lt_foo="";
+ lt_count=0;
+ for (lt_i = NF; lt_i > 0; lt_i--) {
+ if ($lt_i != "" && $lt_i != ".") {
+ if ($lt_i == "..") {
+ lt_count++;
+ } else {
+ if (lt_count == 0) {
+ lt_foo="/" $lt_i lt_foo;
+ } else {
+ lt_count--;
+ }
+ }
+ }
+ }
+ if (lt_foo != "") { lt_freq[lt_foo]++; }
+ if (lt_freq[lt_foo] == 1) { print lt_foo; }
+}'`
+ # AWK program above erroneously prepends '/' to C:/dos/paths
+ # for these hosts.
+ case $host_os in
+ mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+ $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+ esac
+ sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
+else
+ sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+fi
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action=
+if test -n "$hardcode_libdir_flag_spec" ||
+ test -n "$runpath_var" ||
+ test "X$hardcode_automatic" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no &&
+ test "$hardcode_minus_L" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5
+$as_echo "$hardcode_action" >&6; }
+
+if test "$hardcode_action" = relink ||
+ test "$inherit_rpath" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+ if test "x$enable_dlopen" != xyes; then
+ enable_dlopen=unknown
+ enable_dlopen_self=unknown
+ enable_dlopen_self_static=unknown
+else
+ lt_cv_dlopen=no
+ lt_cv_dlopen_libs=
+
+ case $host_os in
+ beos*)
+ lt_cv_dlopen="load_add_on"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+ ;;
+
+ mingw* | pw32* | cegcc*)
+ lt_cv_dlopen="LoadLibrary"
+ lt_cv_dlopen_libs=
+ ;;
+
+ cygwin*)
+ lt_cv_dlopen="dlopen"
+ lt_cv_dlopen_libs=
+ ;;
+
+ darwin*)
+ # if libdl is installed we need to link against it
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+
+ lt_cv_dlopen="dyld"
+ lt_cv_dlopen_libs=
+ lt_cv_dlopen_self=yes
+
+fi
+
+ ;;
+
+ *)
+ ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
+if test "x$ac_cv_func_shl_load" = x""yes; then :
+ lt_cv_dlopen="shl_load"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char shl_load ();
+int
+main ()
+{
+return shl_load ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_shl_load=yes
+else
+ ac_cv_lib_dld_shl_load=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+ lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
+else
+ ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
+if test "x$ac_cv_func_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dl_dlopen=yes
+else
+ ac_cv_lib_dl_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
+$as_echo_n "checking for dlopen in -lsvld... " >&6; }
+if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lsvld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dlopen ();
+int
+main ()
+{
+return dlopen ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_svld_dlopen=yes
+else
+ ac_cv_lib_svld_dlopen=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
+$as_echo "$ac_cv_lib_svld_dlopen" >&6; }
+if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+ lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
+$as_echo_n "checking for dld_link in -ldld... " >&6; }
+if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-ldld $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char dld_link ();
+int
+main ()
+{
+return dld_link ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_dld_dld_link=yes
+else
+ ac_cv_lib_dld_dld_link=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
+$as_echo "$ac_cv_lib_dld_dld_link" >&6; }
+if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+ lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+ ;;
+ esac
+
+ if test "x$lt_cv_dlopen" != xno; then
+ enable_dlopen=yes
+ else
+ enable_dlopen=no
+ fi
+
+ case $lt_cv_dlopen in
+ dlopen)
+ save_CPPFLAGS="$CPPFLAGS"
+ test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H"
+
+ save_LDFLAGS="$LDFLAGS"
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\"
+
+ save_LIBS="$LIBS"
+ LIBS="$lt_cv_dlopen_libs $LIBS"
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
+$as_echo_n "checking whether a program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 12093 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+void fnord () __attribute__((visibility("default")));
+#endif
+
+void fnord () { int i=42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5
+$as_echo "$lt_cv_dlopen_self" >&6; }
+
+ if test "x$lt_cv_dlopen_self" = xyes; then
+ wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
+$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
+if test "${lt_cv_dlopen_self_static+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test "$cross_compiling" = yes; then :
+ lt_cv_dlopen_self_static=cross
+else
+ lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
+ lt_status=$lt_dlunknown
+ cat > conftest.$ac_ext <<_LT_EOF
+#line 12199 "configure"
+#include "confdefs.h"
+
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+
+#include <stdio.h>
+
+#ifdef RTLD_GLOBAL
+# define LT_DLGLOBAL RTLD_GLOBAL
+#else
+# ifdef DL_GLOBAL
+# define LT_DLGLOBAL DL_GLOBAL
+# else
+# define LT_DLGLOBAL 0
+# endif
+#endif
+
+/* We may have to define LT_DLLAZY_OR_NOW in the command line if we
+ find out it does not work in some platform. */
+#ifndef LT_DLLAZY_OR_NOW
+# ifdef RTLD_LAZY
+# define LT_DLLAZY_OR_NOW RTLD_LAZY
+# else
+# ifdef DL_LAZY
+# define LT_DLLAZY_OR_NOW DL_LAZY
+# else
+# ifdef RTLD_NOW
+# define LT_DLLAZY_OR_NOW RTLD_NOW
+# else
+# ifdef DL_NOW
+# define LT_DLLAZY_OR_NOW DL_NOW
+# else
+# define LT_DLLAZY_OR_NOW 0
+# endif
+# endif
+# endif
+# endif
+#endif
+
+/* When -fvisbility=hidden is used, assume the code has been annotated
+ correspondingly for the symbols needed. */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+void fnord () __attribute__((visibility("default")));
+#endif
+
+void fnord () { int i=42; }
+int main ()
+{
+ void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
+ int status = $lt_dlunknown;
+
+ if (self)
+ {
+ if (dlsym (self,"fnord")) status = $lt_dlno_uscore;
+ else
+ {
+ if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+ else puts (dlerror ());
+ }
+ /* dlclose (self); */
+ }
+ else
+ puts (dlerror ());
+
+ return status;
+}
+_LT_EOF
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then
+ (./conftest; exit; ) >&5 2>/dev/null
+ lt_status=$?
+ case x$lt_status in
+ x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;;
+ x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;;
+ esac
+ else :
+ # compilation failed
+ lt_cv_dlopen_self_static=no
+ fi
+fi
+rm -fr conftest*
+
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5
+$as_echo "$lt_cv_dlopen_self_static" >&6; }
+ fi
+
+ CPPFLAGS="$save_CPPFLAGS"
+ LDFLAGS="$save_LDFLAGS"
+ LIBS="$save_LIBS"
+ ;;
+ esac
+
+ case $lt_cv_dlopen_self in
+ yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;;
+ *) enable_dlopen_self=unknown ;;
+ esac
+
+ case $lt_cv_dlopen_self_static in
+ yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;;
+ *) enable_dlopen_self_static=unknown ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+striplib=
+old_striplib=
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5
+$as_echo_n "checking whether stripping libraries is possible... " >&6; }
+if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then
+ test -z "$old_striplib" && old_striplib="$STRIP --strip-debug"
+ test -z "$striplib" && striplib="$STRIP --strip-unneeded"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+# FIXME - insert some real tests, host_os isn't really good enough
+ case $host_os in
+ darwin*)
+ if test -n "$STRIP" ; then
+ striplib="$STRIP -x"
+ old_striplib="$STRIP -S"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ fi
+ ;;
+ *)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ ;;
+ esac
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+ # Report which library types will actually be built
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5
+$as_echo_n "checking if libtool supports shared libraries... " >&6; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5
+$as_echo "$can_build_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5
+$as_echo_n "checking whether to build shared libraries... " >&6; }
+ test "$can_build_shared" = "no" && enable_shared=no
+
+ # On AIX, shared libraries and static libraries use the same namespace, and
+ # are all built from PIC.
+ case $host_os in
+ aix3*)
+ test "$enable_shared" = yes && enable_static=no
+ if test -n "$RANLIB"; then
+ archive_cmds="$archive_cmds~\$RANLIB \$lib"
+ postinstall_cmds='$RANLIB $lib'
+ fi
+ ;;
+
+ aix[4-9]*)
+ if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then
+ test "$enable_shared" = yes && enable_static=no
+ fi
+ ;;
+ esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5
+$as_echo "$enable_shared" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5
+$as_echo_n "checking whether to build static libraries... " >&6; }
+ # Make sure either enable_shared or enable_static is yes.
+ test "$enable_shared" = yes || enable_static=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5
+$as_echo "$enable_static" >&6; }
+
+
+
+
+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
+
+CC="$lt_save_CC"
+
+ if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+ ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+ (test "X$CXX" != "Xg++"))) ; then
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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; }
+if test -z "$CXXCPP"; then
+ if test "${ac_cv_prog_CXXCPP+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_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_cxx_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_cxx_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_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXXCPP" >&5
+$as_echo "$CXXCPP" >&6; }
+ac_preproc_ok=false
+for ac_cxx_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_cxx_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_cxx_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 \"$CXXCPP\" 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
+
+else
+ _lt_caught_CXX_error=yes
+fi
+
+ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+archive_cmds_need_lc_CXX=no
+allow_undefined_flag_CXX=
+always_export_symbols_CXX=no
+archive_expsym_cmds_CXX=
+compiler_needs_object_CXX=no
+export_dynamic_flag_spec_CXX=
+hardcode_direct_CXX=no
+hardcode_direct_absolute_CXX=no
+hardcode_libdir_flag_spec_CXX=
+hardcode_libdir_flag_spec_ld_CXX=
+hardcode_libdir_separator_CXX=
+hardcode_minus_L_CXX=no
+hardcode_shlibpath_var_CXX=unsupported
+hardcode_automatic_CXX=no
+inherit_rpath_CXX=no
+module_cmds_CXX=
+module_expsym_cmds_CXX=
+link_all_deplibs_CXX=unknown
+old_archive_cmds_CXX=$old_archive_cmds
+reload_flag_CXX=$reload_flag
+reload_cmds_CXX=$reload_cmds
+no_undefined_flag_CXX=
+whole_archive_flag_spec_CXX=
+enable_shared_with_static_runtimes_CXX=no
+
+# Source file extension for C++ test sources.
+ac_ext=cpp
+
+# Object file extension for compiled C++ test sources.
+objext=o
+objext_CXX=$objext
+
+# No sense in running all these tests if we already determined that
+# the CXX compiler isn't working. Some variables (like enable_shared)
+# are currently assumed to apply to all compilers on this platform,
+# and will be corrupted by setting them based on a non-working compiler.
+if test "$_lt_caught_CXX_error" != yes; then
+ # Code to be used in simple compile tests
+ lt_simple_compile_test_code="int some_variable = 0;"
+
+ # Code to be used in simple link tests
+ lt_simple_link_test_code='int main(int, char *[]) { return(0); }'
+
+ # ltmain only uses $CC for tagged configurations so make sure $CC is set.
+
+
+
+
+
+
+# If no C compiler was specified, use CC.
+LTCC=${LTCC-"$CC"}
+
+# If no C compiler flags were specified, use CFLAGS.
+LTCFLAGS=${LTCFLAGS-"$CFLAGS"}
+
+# Allow CC to be a program name with arguments.
+compiler=$CC
+
+
+ # save warnings/boilerplate of simple test code
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_compile_test_code" >conftest.$ac_ext
+eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_compiler_boilerplate=`cat conftest.err`
+$RM conftest*
+
+ ac_outfile=conftest.$ac_objext
+echo "$lt_simple_link_test_code" >conftest.$ac_ext
+eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err
+_lt_linker_boilerplate=`cat conftest.err`
+$RM -r conftest*
+
+
+ # Allow CC to be a program name with arguments.
+ lt_save_CC=$CC
+ lt_save_LD=$LD
+ lt_save_GCC=$GCC
+ GCC=$GXX
+ lt_save_with_gnu_ld=$with_gnu_ld
+ lt_save_path_LD=$lt_cv_path_LD
+ if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then
+ lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx
+ else
+ $as_unset lt_cv_prog_gnu_ld
+ fi
+ if test -n "${lt_cv_path_LDCXX+set}"; then
+ lt_cv_path_LD=$lt_cv_path_LDCXX
+ else
+ $as_unset lt_cv_path_LD
+ fi
+ test -z "${LDCXX+set}" || LD=$LDCXX
+ CC=${CXX-"c++"}
+ compiler=$CC
+ compiler_CXX=$CC
+ for cc_temp in $compiler""; do
+ case $cc_temp in
+ compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
+ distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
+ \-*) ;;
+ *) break;;
+ esac
+done
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
+
+
+ if test -n "$compiler"; then
+ # We don't want -fno-exception when compiling C++ code, so set the
+ # no_builtin_flag separately
+ if test "$GXX" = yes; then
+ lt_prog_compiler_no_builtin_flag_CXX=' -fno-builtin'
+ else
+ lt_prog_compiler_no_builtin_flag_CXX=
+ fi
+
+ if test "$GXX" = yes; then
+ # Set up default GNU C++ configuration
+
+
+
+# Check whether --with-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then :
+ withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$GCC" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5
+$as_echo_n "checking for ld used by $CC... " >&6; }
+ case $host in
+ *-*-mingw*)
+ # gcc leaves a trailing carriage return which upsets mingw
+ ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
+ *)
+ ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
+ esac
+ case $ac_prog in
+ # Accept absolute paths.
+ [\\/]* | ?:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the pathname of ld
+ ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'`
+ while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5
+$as_echo_n "checking for GNU ld... " >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
+$as_echo_n "checking for non-GNU ld... " >&6; }
+fi
+if test "${lt_cv_path_LD+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -z "$LD"; then
+ lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
+ for ac_dir in $PATH; do
+ IFS="$lt_save_ifs"
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ lt_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some variants of GNU ld only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ case `"$lt_cv_path_LD" -v 2>&1 </dev/null` in
+ *GNU* | *'with BFD'*)
+ test "$with_gnu_ld" != no && break
+ ;;
+ *)
+ test "$with_gnu_ld" != yes && break
+ ;;
+ esac
+ fi
+ done
+ IFS="$lt_save_ifs"
+else
+ lt_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$lt_cv_path_LD"
+if test -n "$LD"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LD" >&5
+$as_echo "$LD" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
+$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
+if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ # I'd rather use --version here, but apparently some GNU lds only accept -v.
+case `$LD -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+ lt_cv_prog_gnu_ld=yes
+ ;;
+*)
+ lt_cv_prog_gnu_ld=no
+ ;;
+esac
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_gnu_ld" >&5
+$as_echo "$lt_cv_prog_gnu_ld" >&6; }
+with_gnu_ld=$lt_cv_prog_gnu_ld
+
+
+
+
+
+
+
+ # Check if GNU C++ uses GNU ld as the underlying linker, since the
+ # archiving commands below assume that GNU ld is being used.
+ if test "$with_gnu_ld" = yes; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+ # If archive_cmds runs LD, not CC, wlarc should be empty
+ # XXX I think wlarc can be eliminated in ltcf-cxx, but I need to
+ # investigate it a little bit more. (MM)
+ wlarc='${wl}'
+
+ # ancient GNU ld didn't support --whole-archive et. al.
+ if eval "`$CC -print-prog-name=ld` --help 2>&1" |
+ $GREP 'no-whole-archive' > /dev/null; then
+ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ else
+ whole_archive_flag_spec_CXX=
+ fi
+ else
+ with_gnu_ld=no
+ wlarc=
+
+ # A generic and very simple default shared library creation
+ # command for GNU C++ for the case where it uses the native
+ # linker, instead of GNU ld. If possible, this setting should
+ # overridden to take advantage of the native linker features on
+ # the platform it is being used on.
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ fi
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ GXX=no
+ with_gnu_ld=no
+ wlarc=
+ fi
+
+ # PORTME: fill in a description of your system's C++ link characteristics
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+ ld_shlibs_CXX=yes
+ case $host_os in
+ aix3*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aix[4-9]*)
+ if test "$host_cpu" = ia64; then
+ # On IA64, the linker does run time linking by default, so we don't
+ # have to do anything special.
+ aix_use_runtimelinking=no
+ exp_sym_flag='-Bexport'
+ no_entry_flag=""
+ else
+ aix_use_runtimelinking=no
+
+ # Test if we are trying to use run time linking or normal
+ # AIX style linking. If -brtl is somewhere in LDFLAGS, we
+ # need to do runtime linking.
+ case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*)
+ for ld_flag in $LDFLAGS; do
+ case $ld_flag in
+ *-brtl*)
+ aix_use_runtimelinking=yes
+ break
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ exp_sym_flag='-bexport'
+ no_entry_flag='-bnoentry'
+ fi
+
+ # When large executables or shared objects are built, AIX ld can
+ # have problems creating the table of contents. If linking a library
+ # or program results in "error TOC overflow" add -mminimal-toc to
+ # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not
+ # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS.
+
+ archive_cmds_CXX=''
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ file_list_spec_CXX='${wl}-f,'
+
+ if test "$GXX" = yes; then
+ case $host_os in aix4.[012]|aix4.[012].*)
+ # We only want to do this on AIX 4.2 and lower, the check
+ # below for broken collect2 doesn't work under 4.3+
+ collect2name=`${CC} -print-prog-name=collect2`
+ if test -f "$collect2name" &&
+ strings "$collect2name" | $GREP resolve_lib_name >/dev/null
+ then
+ # We have reworked collect2
+ :
+ else
+ # We have old collect2
+ hardcode_direct_CXX=unsupported
+ # It fails to find uninstalled libraries when the uninstalled
+ # path is not listed in the libpath. Setting hardcode_minus_L
+ # to unsupported forces relinking
+ hardcode_minus_L_CXX=yes
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ hardcode_libdir_separator_CXX=
+ fi
+ esac
+ shared_flag='-shared'
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag="$shared_flag "'${wl}-G'
+ fi
+ else
+ # not using gcc
+ if test "$host_cpu" = ia64; then
+ # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release
+ # chokes on -Wl,-G. The following line is correct:
+ shared_flag='-G'
+ else
+ if test "$aix_use_runtimelinking" = yes; then
+ shared_flag='${wl}-G'
+ else
+ shared_flag='${wl}-bM:SRE'
+ fi
+ fi
+ fi
+
+ export_dynamic_flag_spec_CXX='${wl}-bexpall'
+ # It seems that -bexpall does not export symbols beginning with
+ # underscore (_), so it is better to generate a list of symbols to
+ # export.
+ always_export_symbols_CXX=yes
+ if test "$aix_use_runtimelinking" = yes; then
+ # Warning - without using the other runtime loading flags (-brtl),
+ # -berok will link without error, but may produce a broken library.
+ allow_undefined_flag_CXX='-berok'
+ # Determine the default libpath from the value encoded in an empty
+ # executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+
+ archive_expsym_cmds_CXX='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+ else
+ if test "$host_cpu" = ia64; then
+ hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib'
+ allow_undefined_flag_CXX="-z nodefs"
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols"
+ else
+ # Determine the default libpath from the value encoded in an
+ # empty executable.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+
+lt_aix_libpath_sed='
+ /Import File Strings/,/^$/ {
+ /^0/ {
+ s/^0 *\(.*\)$/\1/
+ p
+ }
+ }'
+aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+# Check for a 64-bit object if we didn't find anything.
+if test -z "$aix_libpath"; then
+ aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath"
+ # Warning - without using the other run time loading flags,
+ # -berok will link without error, but may produce a broken library.
+ no_undefined_flag_CXX=' ${wl}-bernotok'
+ allow_undefined_flag_CXX=' ${wl}-berok'
+ if test "$with_gnu_ld" = yes; then
+ # We only use this code for GNU lds that support --whole-archive.
+ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ else
+ # Exported symbols can be pulled into shared objects from archives
+ whole_archive_flag_spec_CXX='$convenience'
+ fi
+ archive_cmds_need_lc_CXX=yes
+ # This is similar to how AIX traditionally builds its shared
+ # libraries.
+ archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
+ fi
+ fi
+ ;;
+
+ beos*)
+ if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
+ allow_undefined_flag_CXX=unsupported
+ # Joseph Beckenbach <jrb3@best.com> says some releases of gcc
+ # support --undefined. This deserves some investigation. FIXME
+ archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ chorus*)
+ case $cc_basename in
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ cygwin* | mingw* | pw32* | cegcc*)
+ # _LT_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless,
+ # as there is no search path for DLLs.
+ hardcode_libdir_flag_spec_CXX='-L$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-all-symbols'
+ allow_undefined_flag_CXX=unsupported
+ always_export_symbols_CXX=no
+ enable_shared_with_static_runtimes_CXX=yes
+
+ if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ # If the export-symbols file already is a .def file (1st line
+ # is EXPORTS), use it as is; otherwise, prepend...
+ archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+ cp $export_symbols $output_objdir/$soname.def;
+ else
+ echo EXPORTS > $output_objdir/$soname.def;
+ cat $export_symbols >> $output_objdir/$soname.def;
+ fi~
+ $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ darwin* | rhapsody*)
+
+
+ archive_cmds_need_lc_CXX=no
+ hardcode_direct_CXX=no
+ hardcode_automatic_CXX=yes
+ hardcode_shlibpath_var_CXX=unsupported
+ if test "$lt_cv_ld_force_load" = "yes"; then
+ whole_archive_flag_spec_CXX='`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+ else
+ whole_archive_flag_spec_CXX=''
+ fi
+ link_all_deplibs_CXX=yes
+ allow_undefined_flag_CXX="$_lt_dar_allow_undefined"
+ case $cc_basename in
+ ifort*) _lt_dar_can_shared=yes ;;
+ *) _lt_dar_can_shared=$GCC ;;
+ esac
+ if test "$_lt_dar_can_shared" = "yes"; then
+ output_verbose_link_cmd=func_echo_all
+ archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
+ module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
+ module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}"
+ if test "$lt_cv_apple_cc_single_mod" != "yes"; then
+ archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}"
+ archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}"
+ fi
+
+ else
+ ld_shlibs_CXX=no
+ fi
+
+ ;;
+
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ freebsd2.*)
+ # C++ shared libraries reported to be fairly broken before
+ # switch to ELF
+ ld_shlibs_CXX=no
+ ;;
+
+ freebsd-elf*)
+ archive_cmds_need_lc_CXX=no
+ ;;
+
+ freebsd* | dragonfly*)
+ # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF
+ # conventions
+ ld_shlibs_CXX=yes
+ ;;
+
+ gnu*)
+ ;;
+
+ haiku*)
+ archive_cmds_CXX='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ link_all_deplibs_CXX=yes
+ ;;
+
+ hpux9*)
+ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ hardcode_direct_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -b ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ archive_cmds_CXX='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ hpux10*|hpux11*)
+ if test $with_gnu_ld = no; then
+ hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ case $host_cpu in
+ hppa*64*|ia64*)
+ ;;
+ *)
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ ;;
+ esac
+ fi
+ case $host_cpu in
+ hppa*64*|ia64*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ ;;
+ *)
+ hardcode_direct_CXX=yes
+ hardcode_direct_absolute_CXX=yes
+ hardcode_minus_L_CXX=yes # Not in the search PATH,
+ # but as the default
+ # location of the library.
+ ;;
+ esac
+
+ case $cc_basename in
+ CC*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ aCC*)
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test $with_gnu_ld = no; then
+ case $host_cpu in
+ hppa*64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ ia64*)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ ;;
+ esac
+ fi
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ interix[3-9]*)
+ hardcode_direct_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc.
+ # Instead, shared libraries are loaded at an image base (0x10000000 by
+ # default) and relocated if they conflict, which is a slow very memory
+ # consuming and fragmenting process. To avoid this, we pick a random,
+ # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link
+ # time. Moving up from 0x10000000 also allows more sbrk(2) space.
+ archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
+ ;;
+ irix5* | irix6*)
+ case $cc_basename in
+ CC*)
+ # SGI C++
+ archive_cmds_CXX='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+
+ # Archives containing C++ object files must be created using
+ # "CC -ar", where "CC" is the IRIX C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -ar -WR,-u -o $oldlib $oldobjs'
+ ;;
+ *)
+ if test "$GXX" = yes; then
+ if test "$with_gnu_ld" = no; then
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ else
+ archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
+ fi
+ fi
+ link_all_deplibs_CXX=yes
+ ;;
+ esac
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+ inherit_rpath_CXX=yes
+ ;;
+
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+ archive_expsym_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo $lib | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib ${wl}-retain-symbols-file,$export_symbols; mv \$templib $lib'
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+
+ # Archives containing C++ object files must be created using
+ # "CC -Bstatic", where "CC" is the KAI C++ compiler.
+ old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs'
+ ;;
+ icpc* | ecpc* )
+ # Intel C++
+ with_gnu_ld=yes
+ # version 8.0 and above of icpc choke on multiply defined symbols
+ # if we add $predep_objects and $postdep_objects, however 7.1 and
+ # earlier do not add the objects themselves.
+ case `$CC -V 2>&1` in
+ *"Version 7."*)
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ *) # Version 8.0 or newer
+ tmp_idyn=
+ case $host_cpu in
+ ia64*) tmp_idyn=' -i_dynamic';;
+ esac
+ archive_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared'"$tmp_idyn"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+ ;;
+ esac
+ archive_cmds_need_lc_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ case `$CC -V` in
+ *pgCC\ [1-5].* | *pgcpp\ [1-5].*)
+ prelink_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
+ compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+ old_archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
+ $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+ $RANLIB $oldlib'
+ archive_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ archive_expsym_cmds_CXX='tpldir=Template.dir~
+ rm -rf $tpldir~
+ $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
+ $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ *) # Version 6 and above use weak symbols
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ ;;
+ cxx*)
+ # Compaq C++
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib ${wl}-retain-symbols-file $wl$export_symbols'
+
+ runpath_var=LD_RUN_PATH
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
+ ;;
+ xl* | mpixl* | bgxl*)
+ # IBM XL 8.0 on PPC, with GNU ld
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ export_dynamic_flag_spec_CXX='${wl}--export-dynamic'
+ archive_cmds_CXX='$CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+ if test "x$supports_anon_versioning" = xyes; then
+ archive_expsym_cmds_CXX='echo "{ global:" > $output_objdir/$libname.ver~
+ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
+ echo "local: *; };" >> $output_objdir/$libname.ver~
+ $CC -qmkshrobj $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib'
+ fi
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+ compiler_needs_object_CXX=yes
+
+ # Not sure whether something based on
+ # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
+ # would be better.
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+
+ lynxos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ m88k*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ netbsd*)
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ archive_cmds_CXX='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags'
+ wlarc=
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ fi
+ # Workaround some broken pre-1.5 toolchains
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP conftest.$objext | $SED -e "s:-lgcc -lc -lgcc::"'
+ ;;
+
+ *nto* | *qnx*)
+ ld_shlibs_CXX=yes
+ ;;
+
+ openbsd2*)
+ # C++ shared libraries are fairly broken
+ ld_shlibs_CXX=no
+ ;;
+
+ openbsd*)
+ if test -f /usr/libexec/ld.so; then
+ hardcode_direct_CXX=yes
+ hardcode_shlibpath_var_CXX=no
+ hardcode_direct_absolute_CXX=yes
+ archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib'
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib'
+ export_dynamic_flag_spec_CXX='${wl}-E'
+ whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
+ fi
+ output_verbose_link_cmd=func_echo_all
+ else
+ ld_shlibs_CXX=no
+ fi
+ ;;
+
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ # Kuck and Associates, Inc. (KAI) C++ Compiler
+
+ # KCC will only create a shared library if the output file
+ # ends with ".so" (or ".sl" for HP-UX), so rename the library
+ # to its proper name (with version) after linking.
+ archive_cmds_CXX='tempext=`echo $shared_ext | $SED -e '\''s/\([^()0-9A-Za-z{}]\)/\\\\\1/g'\''`; templib=`echo "$lib" | $SED -e "s/\${tempext}\..*/.so/"`; $CC $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags --soname $soname -o \$templib; mv \$templib $lib'
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Archives containing C++ object files must be created using
+ # the KAI C++ compiler.
+ case $host in
+ osf3*) old_archive_cmds_CXX='$CC -Bstatic -o $oldlib $oldobjs' ;;
+ *) old_archive_cmds_CXX='$CC -o $oldlib $oldobjs' ;;
+ esac
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ cxx*)
+ case $host in
+ osf3*)
+ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ ;;
+ *)
+ allow_undefined_flag_CXX=' -expect_unresolved \*'
+ archive_cmds_CXX='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+ archive_expsym_cmds_CXX='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
+ echo "-hidden">> $lib.exp~
+ $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
+ $RM $lib.exp'
+ hardcode_libdir_flag_spec_CXX='-rpath $libdir'
+ ;;
+ esac
+
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ #
+ # There doesn't appear to be a way to prevent this compiler from
+ # explicitly linking system object files so we need to strip them
+ # from the output so that they don't get included in the library
+ # dependencies.
+ output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
+ ;;
+ *)
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ allow_undefined_flag_CXX=' ${wl}-expect_unresolved ${wl}\*'
+ case $host in
+ osf3*)
+ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+ ;;
+ esac
+
+ hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir'
+ hardcode_libdir_separator_CXX=:
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+
+ else
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ fi
+ ;;
+ esac
+ ;;
+
+ psos*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ lcc*)
+ # Lucid
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ archive_cmds_need_lc_CXX=yes
+ no_undefined_flag_CXX=' -zdefs'
+ archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ hardcode_libdir_flag_spec_CXX='-R$libdir'
+ hardcode_shlibpath_var_CXX=no
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ # The compiler driver will combine and reorder linker options,
+ # but understands `-z linker_flag'.
+ # Supported since Solaris 2.6 (maybe 2.5.1?)
+ whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract'
+ ;;
+ esac
+ link_all_deplibs_CXX=yes
+
+ output_verbose_link_cmd='func_echo_all'
+
+ # Archives containing C++ object files must be created using
+ # "CC -xar", where "CC" is the Sun C++ compiler. This is
+ # necessary to make sure instantiated templates are included
+ # in the archive.
+ old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs'
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ archive_cmds_CXX='$CC -shared $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+
+ # The C++ compiler must be used to create the archive.
+ old_archive_cmds_CXX='$CC $LDFLAGS -archive -o $oldlib $oldobjs'
+ ;;
+ *)
+ # GNU C++ compiler with Solaris linker
+ if test "$GXX" = yes && test "$with_gnu_ld" = no; then
+ no_undefined_flag_CXX=' ${wl}-z ${wl}defs'
+ if $CC --version | $GREP -v '^2\.7' > /dev/null; then
+ archive_cmds_CXX='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ else
+ # g++ 2.7 appears to require `-G' NOT `-shared' on this
+ # platform.
+ archive_cmds_CXX='$CC -G -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+ archive_expsym_cmds_CXX='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
+ $CC -G -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+
+ # Commands to make compiler produce verbose output that lists
+ # what "hidden" libraries, object files and flags are used when
+ # linking a shared library.
+ output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
+ fi
+
+ hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir'
+ case $host_os in
+ solaris2.[0-5] | solaris2.[0-5].*) ;;
+ *)
+ whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract'
+ ;;
+ esac
+ fi
+ ;;
+ esac
+ ;;
+
+ sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
+ no_undefined_flag_CXX='${wl}-z,text'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ sysv5* | sco3.2v5* | sco5v6*)
+ # Note: We can NOT use -z defs as we might desire, because we do not
+ # link with -lc, and that would cause any symbols used from libc to
+ # always be unresolved, which means just about no library would
+ # ever link correctly. If we're not using GNU ld we use -z text
+ # though, which does catch some bad symbols but isn't as heavy-handed
+ # as -z defs.
+ no_undefined_flag_CXX='${wl}-z,text'
+ allow_undefined_flag_CXX='${wl}-z,nodefs'
+ archive_cmds_need_lc_CXX=no
+ hardcode_shlibpath_var_CXX=no
+ hardcode_libdir_flag_spec_CXX='${wl}-R,$libdir'
+ hardcode_libdir_separator_CXX=':'
+ link_all_deplibs_CXX=yes
+ export_dynamic_flag_spec_CXX='${wl}-Bexport'
+ runpath_var='LD_RUN_PATH'
+
+ case $cc_basename in
+ CC*)
+ archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ old_archive_cmds_CXX='$CC -Tprelink_objects $oldobjs~
+ '"$old_archive_cmds_CXX"
+ reload_cmds_CXX='$CC -Tprelink_objects $reload_objs~
+ '"$reload_cmds_CXX"
+ ;;
+ *)
+ archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+ ;;
+ esac
+ ;;
+
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+ ;;
+
+ vxworks*)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+
+ *)
+ # FIXME: insert proper C++ library support
+ ld_shlibs_CXX=no
+ ;;
+ esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+ test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+ GCC_CXX="$GXX"
+ LD_CXX="$LD"
+
+ ## CAVEAT EMPTOR:
+ ## There is no encapsulation within the following macros, do not change
+ ## the running order or otherwise move them around unless you know exactly
+ ## what you are doing...
+ # Dependencies to place before and after the object being linked:
+predep_objects_CXX=
+postdep_objects_CXX=
+predeps_CXX=
+postdeps_CXX=
+compiler_lib_search_path_CXX=
+
+cat > conftest.$ac_ext <<_LT_EOF
+class Foo
+{
+public:
+ Foo (void) { a = 0; }
+private:
+ int a;
+};
+_LT_EOF
+
+if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then
+ # Parse the compiler output and extract the necessary
+ # objects, libraries and library flags.
+
+ # Sentinel used to keep track of whether or not we are before
+ # the conftest object file.
+ pre_test_object_deps_done=no
+
+ for p in `eval "$output_verbose_link_cmd"`; do
+ case $p in
+
+ -L* | -R* | -l*)
+ # Some compilers place space between "-{L,R}" and the path.
+ # Remove the space.
+ if test $p = "-L" ||
+ test $p = "-R"; then
+ prev=$p
+ continue
+ else
+ prev=
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ case $p in
+ -L* | -R*)
+ # Internal compiler library paths should come after those
+ # provided the user. The postdeps already come after the
+ # user supplied libs so there is no need to process them.
+ if test -z "$compiler_lib_search_path_CXX"; then
+ compiler_lib_search_path_CXX="${prev}${p}"
+ else
+ compiler_lib_search_path_CXX="${compiler_lib_search_path_CXX} ${prev}${p}"
+ fi
+ ;;
+ # The "-l" case would never come before the object being
+ # linked, so don't bother handling this case.
+ esac
+ else
+ if test -z "$postdeps_CXX"; then
+ postdeps_CXX="${prev}${p}"
+ else
+ postdeps_CXX="${postdeps_CXX} ${prev}${p}"
+ fi
+ fi
+ ;;
+
+ *.$objext)
+ # This assumes that the test object file only shows up
+ # once in the compiler output.
+ if test "$p" = "conftest.$objext"; then
+ pre_test_object_deps_done=yes
+ continue
+ fi
+
+ if test "$pre_test_object_deps_done" = no; then
+ if test -z "$predep_objects_CXX"; then
+ predep_objects_CXX="$p"
+ else
+ predep_objects_CXX="$predep_objects_CXX $p"
+ fi
+ else
+ if test -z "$postdep_objects_CXX"; then
+ postdep_objects_CXX="$p"
+ else
+ postdep_objects_CXX="$postdep_objects_CXX $p"
+ fi
+ fi
+ ;;
+
+ *) ;; # Ignore the rest.
+
+ esac
+ done
+
+ # Clean up.
+ rm -f a.out a.exe
+else
+ echo "libtool.m4: error: problem compiling CXX test program"
+fi
+
+$RM -f confest.$objext
+
+# PORTME: override above test on systems where it is broken
+case $host_os in
+interix[3-9]*)
+ # Interix 3.5 installs completely hosed .la files for C++, so rather than
+ # hack all around it, let's just trust "g++" to DTRT.
+ predep_objects_CXX=
+ postdep_objects_CXX=
+ postdeps_CXX=
+ ;;
+
+linux*)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ if test "$solaris_use_stlport4" != yes; then
+ postdeps_CXX='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+
+solaris*)
+ case $cc_basename in
+ CC*)
+ # The more standards-conforming stlport4 library is
+ # incompatible with the Cstd library. Avoid specifying
+ # it if it's in CXXFLAGS. Ignore libCrun as
+ # -library=stlport4 depends on it.
+ case " $CXX $CXXFLAGS " in
+ *" -library=stlport4 "*)
+ solaris_use_stlport4=yes
+ ;;
+ esac
+
+ # Adding this requires a known-good setup of shared libraries for
+ # Sun compiler versions before 5.6, else PIC objects from an old
+ # archive will be linked into the output, leading to subtle bugs.
+ if test "$solaris_use_stlport4" != yes; then
+ postdeps_CXX='-library=Cstd -library=Crun'
+ fi
+ ;;
+ esac
+ ;;
+esac
+
+
+case " $postdeps_CXX " in
+*" -lc "*) archive_cmds_need_lc_CXX=no ;;
+esac
+ compiler_lib_search_dirs_CXX=
+if test -n "${compiler_lib_search_path_CXX}"; then
+ compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'`
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ lt_prog_compiler_wl_CXX=
+lt_prog_compiler_pic_CXX=
+lt_prog_compiler_static_CXX=
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+
+ # C++ specific cases for pic, static, wl, etc.
+ if test "$GXX" = yes; then
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-static'
+
+ case $host_os in
+ aix*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ fi
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+
+ amigaos*)
+ case $host_cpu in
+ powerpc)
+ # see comment about AmigaOS4 .so support
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ m68k)
+ # FIXME: we need at least 68020 code to build shared libraries, but
+ # adding the `-m68020' flag to GCC prevents building anything better,
+ # like `-m68040'.
+ lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4'
+ ;;
+ esac
+ ;;
+
+ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*)
+ # PIC is the default for these OSes.
+ ;;
+ mingw* | cygwin* | os2* | pw32* | cegcc*)
+ # This hack is so that the source file can tell whether it is being
+ # built for inclusion in a dll (and should export symbols for example).
+ # Although the cygwin gcc ignores -fPIC, still need this for old-style
+ # (--disable-auto-import) libraries
+ lt_prog_compiler_pic_CXX='-DDLL_EXPORT'
+ ;;
+ darwin* | rhapsody*)
+ # PIC is the default on this platform
+ # Common symbols not allowed in MH_DYLIB files
+ lt_prog_compiler_pic_CXX='-fno-common'
+ ;;
+ *djgpp*)
+ # DJGPP does not support shared libraries at all
+ lt_prog_compiler_pic_CXX=
+ ;;
+ haiku*)
+ # PIC is the default for Haiku.
+ # The "-static" flag exists, but is broken.
+ lt_prog_compiler_static_CXX=
+ ;;
+ interix[3-9]*)
+ # Interix 3.x gcc -fpic/-fPIC options generate broken code.
+ # Instead, we relocate shared libraries at runtime.
+ ;;
+ sysv4*MP*)
+ if test -d /usr/nec; then
+ lt_prog_compiler_pic_CXX=-Kconform_pic
+ fi
+ ;;
+ hpux*)
+ # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
+ # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag
+ # sets the default TLS model and affects inlining.
+ case $host_cpu in
+ hppa*64*)
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ esac
+ else
+ case $host_os in
+ aix[4-9]*)
+ # All AIX code is PIC.
+ if test "$host_cpu" = ia64; then
+ # AIX 5 now supports IA64 processor
+ lt_prog_compiler_static_CXX='-Bstatic'
+ else
+ lt_prog_compiler_static_CXX='-bnso -bI:/lib/syscalls.exp'
+ fi
+ ;;
+ chorus*)
+ case $cc_basename in
+ cxch68*)
+ # Green Hills C++ Compiler
+ # _LT_TAGVAR(lt_prog_compiler_static, CXX)="--no_auto_instantiation -u __main -u __premain -u _abort -r $COOL_DIR/lib/libOrb.a $MVME_DIR/lib/CC/libC.a $MVME_DIR/lib/classix/libcx.s.a"
+ ;;
+ esac
+ ;;
+ dgux*)
+ case $cc_basename in
+ ec++*)
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ ghcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ freebsd* | dragonfly*)
+ # FreeBSD uses GNU C++
+ ;;
+ hpux9* | hpux10* | hpux11*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+ if test "$host_cpu" != ia64; then
+ lt_prog_compiler_pic_CXX='+Z'
+ fi
+ ;;
+ aCC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='${wl}-a ${wl}archive'
+ case $host_cpu in
+ hppa*64*|ia64*)
+ # +Z the default
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX='+Z'
+ ;;
+ esac
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ interix*)
+ # This is c89, which is MS Visual C++ (no shared libs)
+ # Anyone wants to do a port?
+ ;;
+ irix5* | irix6* | nonstopux*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_static_CXX='-non_shared'
+ # CC pic flag -KPIC is the default.
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ case $cc_basename in
+ KCC*)
+ # KAI C++ Compiler
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ ;;
+ ecpc* )
+ # old Intel C++ for x86_64 which still supported -KPIC.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ icpc* )
+ # Intel C++, used to be incompatible with GCC.
+ # ICC 10 doesn't accept -KPIC any more.
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fPIC'
+ lt_prog_compiler_static_CXX='-static'
+ ;;
+ pgCC* | pgcpp*)
+ # Portland Group C++ compiler
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-fpic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ cxx*)
+ # Compaq C++
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ xlc* | xlC* | bgxl[cC]* | mpixl[cC]*)
+ # IBM XL 8.0, 9.0 on PPC and BlueGene
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-qpic'
+ lt_prog_compiler_static_CXX='-qstaticlink'
+ ;;
+ *)
+ case `$CC -V 2>&1 | sed 5q` in
+ *Sun\ C*)
+ # Sun C++ 5.9
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ esac
+ ;;
+ esac
+ ;;
+ lynxos*)
+ ;;
+ m88k*)
+ ;;
+ mvs*)
+ case $cc_basename in
+ cxx*)
+ lt_prog_compiler_pic_CXX='-W c,exportall'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ netbsd*)
+ ;;
+ *qnx* | *nto*)
+ # QNX uses GNU C++, but need to define -shared option too, otherwise
+ # it will coredump.
+ lt_prog_compiler_pic_CXX='-fPIC -shared'
+ ;;
+ osf3* | osf4* | osf5*)
+ case $cc_basename in
+ KCC*)
+ lt_prog_compiler_wl_CXX='--backend -Wl,'
+ ;;
+ RCC*)
+ # Rational C++ 2.4.1
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ cxx*)
+ # Digital/Compaq C++
+ lt_prog_compiler_wl_CXX='-Wl,'
+ # Make sure the PIC flag is empty. It appears that all Alpha
+ # Linux and Compaq Tru64 Unix objects are PIC.
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_static_CXX='-non_shared'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ psos*)
+ ;;
+ solaris*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.2, 5.x and Centerline C++
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ lt_prog_compiler_wl_CXX='-Qoption ld '
+ ;;
+ gcx*)
+ # Green Hills C++ Compiler
+ lt_prog_compiler_pic_CXX='-PIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sunos4*)
+ case $cc_basename in
+ CC*)
+ # Sun C++ 4.x
+ lt_prog_compiler_pic_CXX='-pic'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ lcc*)
+ # Lucid
+ lt_prog_compiler_pic_CXX='-pic'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
+ case $cc_basename in
+ CC*)
+ lt_prog_compiler_wl_CXX='-Wl,'
+ lt_prog_compiler_pic_CXX='-KPIC'
+ lt_prog_compiler_static_CXX='-Bstatic'
+ ;;
+ esac
+ ;;
+ tandem*)
+ case $cc_basename in
+ NCC*)
+ # NonStop-UX NCC 3.20
+ lt_prog_compiler_pic_CXX='-KPIC'
+ ;;
+ *)
+ ;;
+ esac
+ ;;
+ vxworks*)
+ ;;
+ *)
+ lt_prog_compiler_can_build_shared_CXX=no
+ ;;
+ esac
+ fi
+
+case $host_os in
+ # For platforms which do not support PIC, -DPIC is meaningless:
+ *djgpp*)
+ lt_prog_compiler_pic_CXX=
+ ;;
+ *)
+ lt_prog_compiler_pic_CXX="$lt_prog_compiler_pic_CXX -DPIC"
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic_CXX" >&5
+$as_echo "$lt_prog_compiler_pic_CXX" >&6; }
+
+
+
+#
+# Check to make sure the PIC flag actually works.
+#
+if test -n "$lt_prog_compiler_pic_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5
+$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... " >&6; }
+if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_pic_works_CXX=no
+ ac_outfile=conftest.$ac_objext
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+ lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ # The option is referenced via a variable to avoid confusing sed.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>conftest.err)
+ ac_status=$?
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s "$ac_outfile"; then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings other than the usual output.
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_pic_works_CXX=yes
+ fi
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_pic_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then
+ case $lt_prog_compiler_pic_CXX in
+ "" | " "*) ;;
+ *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;;
+ esac
+else
+ lt_prog_compiler_pic_CXX=
+ lt_prog_compiler_can_build_shared_CXX=no
+fi
+
+fi
+
+
+
+#
+# Check to make sure the static flag actually works.
+#
+wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
+$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
+if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_static_works_CXX=no
+ save_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS $lt_tmp_static_flag"
+ echo "$lt_simple_link_test_code" > conftest.$ac_ext
+ if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+ # The linker can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ if test -s conftest.err; then
+ # Append any errors to the config.log.
+ cat conftest.err 1>&5
+ $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+ $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+ if diff conftest.exp conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ else
+ lt_cv_prog_compiler_static_works_CXX=yes
+ fi
+ fi
+ $RM -r conftest*
+ LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_static_works_CXX" >&6; }
+
+if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then
+ :
+else
+ lt_prog_compiler_static_CXX=
+fi
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
+$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
+if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_prog_compiler_c_o_CXX=no
+ $RM -r conftest 2>/dev/null
+ mkdir conftest
+ cd conftest
+ mkdir out
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ lt_compiler_flag="-o out/conftest2.$ac_objext"
+ # Insert the option either (1) after the last *FLAGS variable, or
+ # (2) before a word containing "conftest.", or (3) at the end.
+ # Note that $ac_compile itself does not contain backslashes and begins
+ # with a dollar sign (not a hyphen), so the echo should work correctly.
+ lt_compile=`echo "$ac_compile" | $SED \
+ -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
+ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
+ -e 's:$: $lt_compiler_flag:'`
+ (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
+ (eval "$lt_compile" 2>out/conftest.err)
+ ac_status=$?
+ cat out/conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ if (exit $ac_status) && test -s out/conftest2.$ac_objext
+ then
+ # The compiler can only warn and ignore the option if not recognized
+ # So say no if there are warnings
+ $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
+ $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
+ if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
+ lt_cv_prog_compiler_c_o_CXX=yes
+ fi
+ fi
+ chmod u+w . 2>&5
+ $RM conftest*
+ # SGI C++ compiler will create directory out/ii_files/ for
+ # template instantiation
+ test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files
+ $RM out/* && rmdir out
+ cd ..
+ $RM -r conftest
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o_CXX" >&5
+$as_echo "$lt_cv_prog_compiler_c_o_CXX" >&6; }
+
+
+
+
+hard_links="nottested"
+if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then
+ # do not overwrite the value of need_locks provided by the user
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5
+$as_echo_n "checking if we can lock with hard links... " >&6; }
+ hard_links=yes
+ $RM conftest*
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ touch conftest.a
+ ln conftest.a conftest.b 2>&5 || hard_links=no
+ ln conftest.a conftest.b 2>/dev/null && hard_links=no
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5
+$as_echo "$hard_links" >&6; }
+ if test "$hard_links" = no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5
+$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;}
+ need_locks=warn
+ fi
+else
+ need_locks=no
+fi
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5
+$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; }
+
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ case $host_os in
+ aix[4-9]*)
+ # If we're using GNU nm, then we don't want the "-C" option.
+ # -C means demangle to AIX nm, but means don't demangle with GNU nm
+ # Also, AIX nm treats weak defined symbols like other global defined
+ # symbols, whereas GNU nm marks them as "W".
+ 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'
+ fi
+ ;;
+ pw32*)
+ export_symbols_cmds_CXX="$ltdll_cmds"
+ ;;
+ cygwin* | mingw* | cegcc*)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ *)
+ export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+ ;;
+ esac
+ exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs_CXX" >&5
+$as_echo "$ld_shlibs_CXX" >&6; }
+test "$ld_shlibs_CXX" = no && can_build_shared=no
+
+with_gnu_ld_CXX=$with_gnu_ld
+
+
+
+
+
+
+#
+# Do we need to explicitly link libc?
+#
+case "x$archive_cmds_need_lc_CXX" in
+x|xyes)
+ # Assume -lc should be added
+ archive_cmds_need_lc_CXX=yes
+
+ if test "$enable_shared" = yes && test "$GCC" = yes; then
+ case $archive_cmds_CXX in
+ *'~'*)
+ # FIXME: we may have to deal with multi-command sequences.
+ ;;
+ '$CC '*)
+ # Test whether the compiler implicitly links with -lc since on some
+ # systems, -lgcc has to come before -lc. If gcc already passes -lc
+ # to ld, don't add -lc before -lgcc.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
+$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
+if test "${lt_cv_archive_cmds_need_lc_CXX+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ $RM conftest*
+ echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+ (eval $ac_compile) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } 2>conftest.err; then
+ soname=conftest
+ lib=conftest
+ libobjs=conftest.$ac_objext
+ deplibs=
+ wl=$lt_prog_compiler_wl_CXX
+ pic_flag=$lt_prog_compiler_pic_CXX
+ compiler_flags=-v
+ linker_flags=-v
+ verstring=
+ output_objdir=.
+ libname=conftest
+ lt_save_allow_undefined_flag=$allow_undefined_flag_CXX
+ allow_undefined_flag_CXX=
+ if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+ (eval $archive_cmds_CXX 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ then
+ lt_cv_archive_cmds_need_lc_CXX=no
+ else
+ lt_cv_archive_cmds_need_lc_CXX=yes
+ fi
+ allow_undefined_flag_CXX=$lt_save_allow_undefined_flag
+ else
+ cat conftest.err 1>&5
+ fi
+ $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc_CXX" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc_CXX" >&6; }
+ archive_cmds_need_lc_CXX=$lt_cv_archive_cmds_need_lc_CXX
+ ;;
+ esac
+ fi
+ ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
+$as_echo_n "checking dynamic linker characteristics... " >&6; }
+
+library_names_spec=
+libname_spec='lib$name'
+soname_spec=
+shrext_cmds=".so"
+postinstall_cmds=
+postuninstall_cmds=
+finish_cmds=
+finish_eval=
+shlibpath_var=
+shlibpath_overrides_runpath=unknown
+version_type=none
+dynamic_linker="$host_os ld.so"
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+need_lib_prefix=unknown
+hardcode_into_libs=no
+
+# when you set need_version to no, make sure it does not cause -set_version
+# flags to be left without arguments
+need_version=unknown
+
+case $host_os in
+aix3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
+ shlibpath_var=LIBPATH
+
+ # AIX 3 has no versioning support, so we append a major version to the name.
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+
+aix[4-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ hardcode_into_libs=yes
+ if test "$host_cpu" = ia64; then
+ # AIX 5 supports IA64
+ library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ else
+ # With GCC up to 2.95.x, collect2 would create an import file
+ # for dependence libraries. The import file would start with
+ # the line `#! .'. This would cause the generated library to
+ # depend on `.', always an invalid library. This was fixed in
+ # development snapshots of GCC prior to 3.0.
+ case $host_os in
+ aix4 | aix4.[01] | aix4.[01].*)
+ if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)'
+ echo ' yes '
+ echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then
+ :
+ else
+ can_build_shared=no
+ fi
+ ;;
+ esac
+ # AIX (on Power*) has no versioning support, so currently we can not hardcode correct
+ # soname into executable. Probably we can add versioning support to
+ # collect2, so additional links can be useful in future.
+ if test "$aix_use_runtimelinking" = yes; then
+ # If using run time linking (on AIX 4.2 or later) use lib<name>.so
+ # instead of lib<name>.a to let people know that these are not
+ # typical AIX shared libraries.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ else
+ # We preserve .a as extension for shared libraries through AIX4.2
+ # and later when we are not doing run time linking.
+ library_names_spec='${libname}${release}.a $libname.a'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ fi
+ shlibpath_var=LIBPATH
+ fi
+ ;;
+
+amigaos*)
+ case $host_cpu in
+ powerpc)
+ # Since July 2007 AmigaOS4 officially supports .so libraries.
+ # When compiling the executable, add -use-dynld -Lsobjs: to the compileline.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ ;;
+ m68k)
+ library_names_spec='$libname.ixlibrary $libname.a'
+ # Create ${libname}_ixlibrary.a entries in /sys/libs.
+ finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+ ;;
+ esac
+ ;;
+
+beos*)
+ library_names_spec='${libname}${shared_ext}'
+ dynamic_linker="$host_os ld.so"
+ shlibpath_var=LIBRARY_PATH
+ ;;
+
+bsdi[45]*)
+ version_type=linux
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib"
+ sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib"
+ # the default ld.so.conf also contains /usr/contrib/lib and
+ # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow
+ # libtool to hard-code these into programs
+ ;;
+
+cygwin* | mingw* | pw32* | cegcc*)
+ version_type=windows
+ shrext_cmds=".dll"
+ need_version=no
+ need_lib_prefix=no
+
+ case $GCC,$host_os in
+ yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+ library_names_spec='$libname.dll.a'
+ # DLL is installed to $(libdir)/../bin by postinstall_cmds
+ postinstall_cmds='base_file=`basename \${file}`~
+ dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+ dldir=$destdir/`dirname \$dlpath`~
+ test -d \$dldir || mkdir -p \$dldir~
+ $install_prog $dir/$dlname \$dldir/$dlname~
+ chmod a+x \$dldir/$dlname~
+ if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then
+ eval '\''$striplib \$dldir/$dlname'\'' || exit \$?;
+ fi'
+ postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+ dlpath=$dir/\$dldll~
+ $RM \$dlpath'
+ shlibpath_overrides_runpath=yes
+
+ case $host_os in
+ cygwin*)
+ # Cygwin DLLs use 'cyg' prefix rather than 'lib'
+ soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+
+ ;;
+ mingw* | cegcc*)
+ # MinGW DLLs use traditional 'lib' prefix
+ soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ pw32*)
+ # pw32 DLLs use 'pw' prefix rather than 'lib'
+ library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+ ;;
+ esac
+ ;;
+
+ *)
+ library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+ ;;
+ esac
+ dynamic_linker='Win32 ld.exe'
+ # FIXME: first we should search . and the directory the executable is in
+ shlibpath_var=PATH
+ ;;
+
+darwin* | rhapsody*)
+ dynamic_linker="$host_os dyld"
+ version_type=darwin
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext'
+ soname_spec='${libname}${release}${major}$shared_ext'
+ shlibpath_overrides_runpath=yes
+ shlibpath_var=DYLD_LIBRARY_PATH
+ shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`'
+
+ sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib'
+ ;;
+
+dgux*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+freebsd* | dragonfly*)
+ # DragonFly does not have aout. When/if they implement a new
+ # versioning mechanism, adjust this.
+ if test -x /usr/bin/objformat; then
+ objformat=`/usr/bin/objformat`
+ else
+ case $host_os in
+ freebsd[23].*) objformat=aout ;;
+ *) objformat=elf ;;
+ esac
+ fi
+ version_type=freebsd-$objformat
+ case $version_type in
+ freebsd-elf*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ need_version=no
+ need_lib_prefix=no
+ ;;
+ freebsd-*)
+ library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix'
+ need_version=yes
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_os in
+ freebsd2.*)
+ shlibpath_overrides_runpath=yes
+ ;;
+ freebsd3.[01]* | freebsdelf3.[01]*)
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ freebsd3.[2-9]* | freebsdelf3.[2-9]* | \
+ freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1)
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+ *) # from 4.6 on, and DragonFly
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+ esac
+ ;;
+
+gnu*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ hardcode_into_libs=yes
+ ;;
+
+haiku*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ dynamic_linker="$host_os runtime_loader"
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/beos/system/lib'
+ hardcode_into_libs=yes
+ ;;
+
+hpux9* | hpux10* | hpux11*)
+ # Give a soname corresponding to the major version so that dld.sl refuses to
+ # link against other versions.
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ case $host_cpu in
+ ia64*)
+ shrext_cmds='.so'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.so"
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ if test "X$HPUX_IA64_MODE" = X32; then
+ sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib"
+ else
+ sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64"
+ fi
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ hppa*64*)
+ shrext_cmds='.sl'
+ hardcode_into_libs=yes
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH
+ shlibpath_overrides_runpath=yes # Unless +noenvvar is specified.
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64"
+ sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec
+ ;;
+ *)
+ shrext_cmds='.sl'
+ dynamic_linker="$host_os dld.sl"
+ shlibpath_var=SHLIB_PATH
+ shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ ;;
+ esac
+ # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
+ postinstall_cmds='chmod 555 $lib'
+ # or fails outright, so override atomically:
+ install_override_mode=555
+ ;;
+
+interix[3-9]*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+irix5* | irix6* | nonstopux*)
+ case $host_os in
+ nonstopux*) version_type=nonstopux ;;
+ *)
+ if test "$lt_cv_prog_gnu_ld" = yes; then
+ version_type=linux
+ else
+ version_type=irix
+ fi ;;
+ esac
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}'
+ case $host_os in
+ irix5* | nonstopux*)
+ libsuff= shlibsuff=
+ ;;
+ *)
+ case $LD in # libtool.m4 will add one of these switches to LD
+ *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ")
+ libsuff= shlibsuff= libmagic=32-bit;;
+ *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ")
+ libsuff=32 shlibsuff=N32 libmagic=N32;;
+ *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ")
+ libsuff=64 shlibsuff=64 libmagic=64-bit;;
+ *) libsuff= shlibsuff= libmagic=never-match;;
+ esac
+ ;;
+ esac
+ shlibpath_var=LD_LIBRARY${shlibsuff}_PATH
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}"
+ sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}"
+ hardcode_into_libs=yes
+ ;;
+
+# No shared lib support for Linux oldld, aout, or coff.
+linux*oldld* | linux*aout* | linux*coff*)
+ dynamic_linker=no
+ ;;
+
+# This must be Linux ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+
+ # Some binutils ld are patched to set DT_RUNPATH
+ if test "${lt_cv_shlibpath_overrides_runpath+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ lt_cv_shlibpath_overrides_runpath=no
+ save_LDFLAGS=$LDFLAGS
+ save_libdir=$libdir
+ eval "libdir=/foo; wl=\"$lt_prog_compiler_wl_CXX\"; \
+ LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec_CXX\""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
+ lt_cv_shlibpath_overrides_runpath=yes
+fi
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ LDFLAGS=$save_LDFLAGS
+ libdir=$save_libdir
+
+fi
+
+ shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
+
+ # This implies no fast_install, which is unacceptable.
+ # Some rework will be needed to allow for fast_install
+ # before this can be enabled.
+ hardcode_into_libs=yes
+
+ # Append ld.so.conf contents to the search path
+ if test -f /etc/ld.so.conf; then
+ lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
+ sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+ fi
+
+ # We used to test for /lib/ld.so.1 and disable shared libraries on
+ # powerpc, because MkLinux only supported shared libraries with the
+ # GNU dynamic linker. Since this was broken with cross compilers,
+ # most powerpc-linux boxes support dynamic linking these days and
+ # people can always --disable-shared, the test was removed, and we
+ # assume the GNU/Linux dynamic linker is in use.
+ dynamic_linker='GNU/Linux ld.so'
+ ;;
+
+netbsd*)
+ version_type=sunos
+ need_lib_prefix=no
+ need_version=no
+ if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ dynamic_linker='NetBSD (a.out) ld.so'
+ else
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ dynamic_linker='NetBSD ld.elf_so'
+ fi
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ ;;
+
+newsos6)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ ;;
+
+*nto* | *qnx*)
+ version_type=qnx
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ dynamic_linker='ldqnx.so'
+ ;;
+
+openbsd*)
+ version_type=sunos
+ sys_lib_dlsearch_path_spec="/usr/lib"
+ need_lib_prefix=no
+ # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs.
+ case $host_os in
+ openbsd3.3 | openbsd3.3.*) need_version=yes ;;
+ *) need_version=no ;;
+ esac
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
+ case $host_os in
+ openbsd2.[89] | openbsd2.[89].*)
+ shlibpath_overrides_runpath=no
+ ;;
+ *)
+ shlibpath_overrides_runpath=yes
+ ;;
+ esac
+ else
+ shlibpath_overrides_runpath=yes
+ fi
+ ;;
+
+os2*)
+ libname_spec='$name'
+ shrext_cmds=".dll"
+ need_lib_prefix=no
+ library_names_spec='$libname${shared_ext} $libname.a'
+ dynamic_linker='OS/2 ld.exe'
+ shlibpath_var=LIBPATH
+ ;;
+
+osf3* | osf4* | osf5*)
+ version_type=osf
+ need_lib_prefix=no
+ need_version=no
+ soname_spec='${libname}${release}${shared_ext}$major'
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib"
+ sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec"
+ ;;
+
+rdos*)
+ dynamic_linker=no
+ ;;
+
+solaris*)
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ # ldd complains unless libraries are executable
+ postinstall_cmds='chmod +x $lib'
+ ;;
+
+sunos4*)
+ version_type=sunos
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix'
+ finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ if test "$with_gnu_ld" = yes; then
+ need_lib_prefix=no
+ fi
+ need_version=yes
+ ;;
+
+sysv4 | sysv4.3*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ case $host_vendor in
+ sni)
+ shlibpath_overrides_runpath=no
+ need_lib_prefix=no
+ runpath_var=LD_RUN_PATH
+ ;;
+ siemens)
+ need_lib_prefix=no
+ ;;
+ motorola)
+ need_lib_prefix=no
+ need_version=no
+ shlibpath_overrides_runpath=no
+ sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib'
+ ;;
+ esac
+ ;;
+
+sysv4*MP*)
+ if test -d /usr/nec ;then
+ version_type=linux
+ library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
+ soname_spec='$libname${shared_ext}.$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ fi
+ ;;
+
+sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
+ version_type=freebsd-elf
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=yes
+ hardcode_into_libs=yes
+ if test "$with_gnu_ld" = yes; then
+ sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib'
+ else
+ sys_lib_search_path_spec='/usr/ccs/lib /usr/lib'
+ case $host_os in
+ sco3.2v5*)
+ sys_lib_search_path_spec="$sys_lib_search_path_spec /lib"
+ ;;
+ esac
+ fi
+ sys_lib_dlsearch_path_spec='/usr/lib'
+ ;;
+
+tpf*)
+ # TPF is a cross-target only. Preferred cross-host = GNU/Linux.
+ version_type=linux
+ need_lib_prefix=no
+ need_version=no
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ shlibpath_var=LD_LIBRARY_PATH
+ shlibpath_overrides_runpath=no
+ hardcode_into_libs=yes
+ ;;
+
+uts4*)
+ version_type=linux
+ library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
+ soname_spec='${libname}${release}${shared_ext}$major'
+ shlibpath_var=LD_LIBRARY_PATH
+ ;;
+
+*)
+ dynamic_linker=no
+ ;;
+esac
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5
+$as_echo "$dynamic_linker" >&6; }
+test "$dynamic_linker" = no && can_build_shared=no
+
+variables_saved_for_relink="PATH $shlibpath_var $runpath_var"
+if test "$GCC" = yes; then
+ variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH"
+fi
+
+if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then
+ sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec"
+fi
+if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then
+ sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec"
+fi
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
+$as_echo_n "checking how to hardcode library paths into programs... " >&6; }
+hardcode_action_CXX=
+if test -n "$hardcode_libdir_flag_spec_CXX" ||
+ test -n "$runpath_var_CXX" ||
+ test "X$hardcode_automatic_CXX" = "Xyes" ; then
+
+ # We can hardcode non-existent directories.
+ if test "$hardcode_direct_CXX" != no &&
+ # If the only mechanism to avoid hardcoding is shlibpath_var, we
+ # have to relink, otherwise we might link with an installed library
+ # when we should be linking with a yet-to-be-installed one
+ ## test "$_LT_TAGVAR(hardcode_shlibpath_var, CXX)" != no &&
+ test "$hardcode_minus_L_CXX" != no; then
+ # Linking always hardcodes the temporary library directory.
+ hardcode_action_CXX=relink
+ else
+ # We can link without hardcoding, and we can hardcode nonexisting dirs.
+ hardcode_action_CXX=immediate
+ fi
+else
+ # We cannot hardcode anything, or else we can only hardcode existing
+ # directories.
+ hardcode_action_CXX=unsupported
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action_CXX" >&5
+$as_echo "$hardcode_action_CXX" >&6; }
+
+if test "$hardcode_action_CXX" = relink ||
+ test "$inherit_rpath_CXX" = yes; then
+ # Fast installation is not supported
+ enable_fast_install=no
+elif test "$shlibpath_overrides_runpath" = yes ||
+ test "$enable_shared" = no; then
+ # Fast installation is not necessary
+ enable_fast_install=needless
+fi
+
+
+
+
+
+
+
+ fi # test -n "$compiler"
+
+ CC=$lt_save_CC
+ LDCXX=$LD
+ LD=$lt_save_LD
+ GCC=$lt_save_GCC
+ with_gnu_ld=$lt_save_with_gnu_ld
+ lt_cv_path_LDCXX=$lt_cv_path_LD
+ lt_cv_path_LD=$lt_save_path_LD
+ lt_cv_prog_gnu_ldcxx=$lt_cv_prog_gnu_ld
+ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld
+fi # test "$_lt_caught_CXX_error" != yes
+
+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_config_commands="$ac_config_commands libtool"
+
+
+
+
+# Only expand once:
+
+
+
+
+
+# For libtool versioning info, format is CURRENT:REVISION:AGE
+libtool_VERSION=1:0:0
+
+
+XCFLAGS="-D_GNU_SOURCE -Wall -Wextra -fno-exceptions"
+
+
+if test "${multilib}" = "yes"; then
+ multilib_arg="--enable-multilib"
+else
+ multilib_arg=
+fi
+
+ac_config_files="$ac_config_files Makefile"
+
+
+if test "x$VTV_SUPPORTED" = "xyes"; then
+ ac_config_files="$ac_config_files ./Makefile testsuite/Makefile"
+
+fi
+
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems. If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, we kill variables containing newlines.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
+ (set) 2>&1 |
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
+ sed -n \
+ "s/'/'\\\\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+ ;; #(
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
+ ;;
+ esac |
+ sort
+) |
+ sed '
+ /^ac_cv_env_/b end
+ t clear
+ :clear
+ s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+ t end
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ test "x$cache_file" != "x/dev/null" &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ cat confcache >$cache_file
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
+ fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then branch to the quote section. Otherwise,
+# look for a macro that doesn't take arguments.
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
+t clear
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
+t quote
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+ # 1. Remove the extension, and $U if already installed.
+ ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
+ ac_i=`$as_echo "$ac_i" | sed "$ac_script"`
+ # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR
+ # will be set to the directory where LIBOBJS objects are built.
+ as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext"
+ as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+ if test -n "$EXEEXT"; then
+ am__EXEEXT_TRUE=
+ am__EXEEXT_FALSE='#'
+else
+ am__EXEEXT_TRUE='#'
+ am__EXEEXT_FALSE=
+fi
+
+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__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
+fi
+
+: ${CONFIG_STATUS=./config.status}
+ac_write_fail=0
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '${1+"$@"}'='"$@"'
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
+fi
+
+
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error ERROR [LINENO LOG_FD]
+# ---------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with status $?, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$?; test $as_status -eq 0 && as_status=1
+ if test "$3"; then
+ as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+ fi
+ $as_echo "$as_me: error: $1" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
+ as_expr=expr
+else
+ as_expr=false
+fi
+
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
+ as_basename=basename
+else
+ as_basename=false
+fi
+
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
+
+as_me=`$as_basename -- "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+ X"$0" : 'X\(//\)$' \| \
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
+esac
+
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
+else
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
+fi
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -p'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -p'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -p'
+ fi
+else
+ as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+if mkdir -p . 2>/dev/null; then
+ as_mkdir_p='mkdir -p "$as_dir"'
+else
+ test -d ./-p && rmdir ./-p
+ as_mkdir_p=false
+fi
+
+if test -x / >/dev/null 2>&1; then
+ as_test_x='test -x'
+else
+ if ls -dL / >/dev/null 2>&1; then
+ as_ls_L_option=L
+ else
+ as_ls_L_option=
+ fi
+ as_test_x='
+ eval sh -c '\''
+ if test -d "$1"; then
+ test -d "$1/.";
+ else
+ case $1 in #(
+ -*)set "./$1";;
+ esac;
+ case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
+ ???[sx]*):;;*)false;;esac;fi
+ '\'' sh
+ '
+fi
+as_executable_p=$as_test_x
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+exec 6>&1
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.
+ac_log="
+This file was extended by GNU Vtable Verification Runtime Library $as_me 1.0, which was
+generated by GNU Autoconf 2.64. Invocation command line was
+
+ CONFIG_FILES = $CONFIG_FILES
+ CONFIG_HEADERS = $CONFIG_HEADERS
+ CONFIG_LINKS = $CONFIG_LINKS
+ CONFIG_COMMANDS = $CONFIG_COMMANDS
+ $ $0 $@
+
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
+_ACEOF
+
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
+
+
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+ac_cs_usage="\
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
+
+Usage: $0 [OPTION]... [TAG]...
+
+ -h, --help print this help, then exit
+ -V, --version print version number and configuration settings, then exit
+ -q, --quiet, --silent
+ do not print progress messages
+ -d, --debug don't remove temporary files
+ --recheck update $as_me by reconfiguring in the same conditions
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Configuration commands:
+$config_commands
+
+Report bugs to the package provider.
+GNU Vtable Verification Runtime Library home page: <http://www.gnu.org/software/libvtv/>.
+General help using GNU software: <http://www.gnu.org/gethelp/>."
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_version="\\
+GNU Vtable Verification Runtime Library config.status 1.0
+configured by $0, generated by GNU Autoconf 2.64,
+ with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2009 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+INSTALL='$INSTALL'
+MKDIR_P='$MKDIR_P'
+AWK='$AWK'
+test -n "\$AWK" || AWK=awk
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
+ac_need_defaults=:
+while test $# != 0
+do
+ case $1 in
+ --*=*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
+ ac_shift=:
+ ;;
+ *)
+ ac_option=$1
+ ac_optarg=$2
+ ac_shift=shift
+ ;;
+ esac
+
+ case $ac_option in
+ # Handling of the options.
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ ac_cs_recheck=: ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
+ debug=: ;;
+ --file | --fil | --fi | --f )
+ $ac_shift
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
+ ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil | --si | --s)
+ ac_cs_silent=: ;;
+
+ # This is an error.
+ -*) as_fn_error "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
+
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
+
+ esac
+ shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+ exec 6>/dev/null
+ ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+if \$ac_cs_recheck; then
+ set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+#
+# INIT-COMMANDS
+#
+
+srcdir="$srcdir"
+host="$host"
+target="$target"
+with_multisubdir="$with_multisubdir"
+with_multisrctop="$with_multisrctop"
+with_target_subdir="$with_target_subdir"
+ac_configure_args="${multilib_arg} ${ac_configure_args}"
+multi_basedir="$multi_basedir"
+CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
+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
+# if CDPATH is set.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+sed_quote_subst='$sed_quote_subst'
+double_quote_subst='$double_quote_subst'
+delay_variable_subst='$delay_variable_subst'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld='`$ECHO "$hardcode_libdir_flag_spec_ld" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+fix_srcfile_path='`$ECHO "$fix_srcfile_path" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs='`$ECHO "$compiler_lib_search_dirs" | $SED "$delay_single_quote_subst"`'
+predep_objects='`$ECHO "$predep_objects" | $SED "$delay_single_quote_subst"`'
+postdep_objects='`$ECHO "$postdep_objects" | $SED "$delay_single_quote_subst"`'
+predeps='`$ECHO "$predeps" | $SED "$delay_single_quote_subst"`'
+postdeps='`$ECHO "$postdeps" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path='`$ECHO "$compiler_lib_search_path" | $SED "$delay_single_quote_subst"`'
+LD_CXX='`$ECHO "$LD_CXX" | $SED "$delay_single_quote_subst"`'
+reload_flag_CXX='`$ECHO "$reload_flag_CXX" | $SED "$delay_single_quote_subst"`'
+reload_cmds_CXX='`$ECHO "$reload_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_CXX='`$ECHO "$old_archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_CXX='`$ECHO "$compiler_CXX" | $SED "$delay_single_quote_subst"`'
+GCC_CXX='`$ECHO "$GCC_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_CXX='`$ECHO "$lt_prog_compiler_no_builtin_flag_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_CXX='`$ECHO "$lt_prog_compiler_wl_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_CXX='`$ECHO "$lt_prog_compiler_pic_CXX" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_CXX='`$ECHO "$lt_prog_compiler_static_CXX" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_CXX='`$ECHO "$lt_cv_prog_compiler_c_o_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_CXX='`$ECHO "$archive_cmds_need_lc_CXX" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_CXX='`$ECHO "$enable_shared_with_static_runtimes_CXX" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_CXX='`$ECHO "$export_dynamic_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_CXX='`$ECHO "$whole_archive_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_CXX='`$ECHO "$compiler_needs_object_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_CXX='`$ECHO "$old_archive_from_new_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_CXX='`$ECHO "$old_archive_from_expsyms_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_cmds_CXX='`$ECHO "$archive_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_CXX='`$ECHO "$archive_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_cmds_CXX='`$ECHO "$module_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_CXX='`$ECHO "$module_expsym_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_CXX='`$ECHO "$with_gnu_ld_CXX" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_CXX='`$ECHO "$allow_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_CXX='`$ECHO "$no_undefined_flag_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_CXX='`$ECHO "$hardcode_libdir_flag_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_ld_CXX='`$ECHO "$hardcode_libdir_flag_spec_ld_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_CXX='`$ECHO "$hardcode_libdir_separator_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_CXX='`$ECHO "$hardcode_direct_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_CXX='`$ECHO "$hardcode_direct_absolute_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_CXX='`$ECHO "$hardcode_minus_L_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_CXX='`$ECHO "$hardcode_shlibpath_var_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_CXX='`$ECHO "$hardcode_automatic_CXX" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_CXX='`$ECHO "$inherit_rpath_CXX" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_CXX='`$ECHO "$link_all_deplibs_CXX" | $SED "$delay_single_quote_subst"`'
+fix_srcfile_path_CXX='`$ECHO "$fix_srcfile_path_CXX" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_CXX='`$ECHO "$always_export_symbols_CXX" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_CXX='`$ECHO "$export_symbols_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_CXX='`$ECHO "$exclude_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+include_expsyms_CXX='`$ECHO "$include_expsyms_CXX" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_CXX='`$ECHO "$prelink_cmds_CXX" | $SED "$delay_single_quote_subst"`'
+file_list_spec_CXX='`$ECHO "$file_list_spec_CXX" | $SED "$delay_single_quote_subst"`'
+hardcode_action_CXX='`$ECHO "$hardcode_action_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_dirs_CXX='`$ECHO "$compiler_lib_search_dirs_CXX" | $SED "$delay_single_quote_subst"`'
+predep_objects_CXX='`$ECHO "$predep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+postdep_objects_CXX='`$ECHO "$postdep_objects_CXX" | $SED "$delay_single_quote_subst"`'
+predeps_CXX='`$ECHO "$predeps_CXX" | $SED "$delay_single_quote_subst"`'
+postdeps_CXX='`$ECHO "$postdeps_CXX" | $SED "$delay_single_quote_subst"`'
+compiler_lib_search_path_CXX='`$ECHO "$compiler_lib_search_path_CXX" | $SED "$delay_single_quote_subst"`'
+
+LTCC='$LTCC'
+LTCFLAGS='$LTCFLAGS'
+compiler='$compiler_DEFAULT'
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+ eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
+# Quote evaled strings.
+for var in SHELL \
+ECHO \
+SED \
+GREP \
+EGREP \
+FGREP \
+LD \
+NM \
+LN_S \
+lt_SP2NL \
+lt_NL2SP \
+reload_flag \
+OBJDUMP \
+deplibs_check_method \
+file_magic_cmd \
+AR \
+AR_FLAGS \
+STRIP \
+RANLIB \
+CC \
+CFLAGS \
+compiler \
+lt_cv_sys_global_symbol_pipe \
+lt_cv_sys_global_symbol_to_cdecl \
+lt_cv_sys_global_symbol_to_c_name_address \
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
+lt_prog_compiler_no_builtin_flag \
+lt_prog_compiler_wl \
+lt_prog_compiler_pic \
+lt_prog_compiler_static \
+lt_cv_prog_compiler_c_o \
+need_locks \
+DSYMUTIL \
+NMEDIT \
+LIPO \
+OTOOL \
+OTOOL64 \
+shrext_cmds \
+export_dynamic_flag_spec \
+whole_archive_flag_spec \
+compiler_needs_object \
+with_gnu_ld \
+allow_undefined_flag \
+no_undefined_flag \
+hardcode_libdir_flag_spec \
+hardcode_libdir_flag_spec_ld \
+hardcode_libdir_separator \
+fix_srcfile_path \
+exclude_expsyms \
+include_expsyms \
+file_list_spec \
+variables_saved_for_relink \
+libname_spec \
+library_names_spec \
+soname_spec \
+install_override_mode \
+finish_eval \
+old_striplib \
+striplib \
+compiler_lib_search_dirs \
+predep_objects \
+postdep_objects \
+predeps \
+postdeps \
+compiler_lib_search_path \
+LD_CXX \
+reload_flag_CXX \
+compiler_CXX \
+lt_prog_compiler_no_builtin_flag_CXX \
+lt_prog_compiler_wl_CXX \
+lt_prog_compiler_pic_CXX \
+lt_prog_compiler_static_CXX \
+lt_cv_prog_compiler_c_o_CXX \
+export_dynamic_flag_spec_CXX \
+whole_archive_flag_spec_CXX \
+compiler_needs_object_CXX \
+with_gnu_ld_CXX \
+allow_undefined_flag_CXX \
+no_undefined_flag_CXX \
+hardcode_libdir_flag_spec_CXX \
+hardcode_libdir_flag_spec_ld_CXX \
+hardcode_libdir_separator_CXX \
+fix_srcfile_path_CXX \
+exclude_expsyms_CXX \
+include_expsyms_CXX \
+file_list_spec_CXX \
+compiler_lib_search_dirs_CXX \
+predep_objects_CXX \
+postdep_objects_CXX \
+predeps_CXX \
+postdeps_CXX \
+compiler_lib_search_path_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+# Double-quote double-evaled strings.
+for var in reload_cmds \
+old_postinstall_cmds \
+old_postuninstall_cmds \
+old_archive_cmds \
+extract_expsyms_cmds \
+old_archive_from_new_cmds \
+old_archive_from_expsyms_cmds \
+archive_cmds \
+archive_expsym_cmds \
+module_cmds \
+module_expsym_cmds \
+export_symbols_cmds \
+prelink_cmds \
+postinstall_cmds \
+postuninstall_cmds \
+finish_cmds \
+sys_lib_search_path_spec \
+sys_lib_dlsearch_path_spec \
+reload_cmds_CXX \
+old_archive_cmds_CXX \
+old_archive_from_new_cmds_CXX \
+old_archive_from_expsyms_cmds_CXX \
+archive_cmds_CXX \
+archive_expsym_cmds_CXX \
+module_cmds_CXX \
+module_expsym_cmds_CXX \
+export_symbols_cmds_CXX \
+prelink_cmds_CXX; do
+ case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
+ *[\\\\\\\`\\"\\\$]*)
+ eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+ ;;
+ *)
+ eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
+ ;;
+ esac
+done
+
+ac_aux_dir='$ac_aux_dir'
+xsi_shell='$xsi_shell'
+lt_shell_append='$lt_shell_append'
+
+# See if we are running on zsh, and set the options which allow our
+# commands through without removal of \ escapes INIT.
+if test -n "\${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+fi
+
+
+ PACKAGE='$PACKAGE'
+ VERSION='$VERSION'
+ TIMESTAMP='$TIMESTAMP'
+ RM='$RM'
+ ofile='$ofile'
+
+
+
+
+
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+
+# Handling of arguments.
+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" ;;
+ "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+ "./Makefile") CONFIG_FILES="$CONFIG_FILES ./Makefile" ;;
+ "testsuite/Makefile") CONFIG_FILES="$CONFIG_FILES testsuite/Makefile" ;;
+
+ *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+ esac
+done
+
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used. Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+ test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+ test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands
+fi
+
+# Have a temporary directory for convenience. Make it in the build tree
+# simply because there is no reason against having it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
+$debug ||
+{
+ tmp=
+ trap 'exit_status=$?
+ { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
+}
+# Create a (secure) tmp directory for tmp files.
+
+{
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -n "$tmp" && test -d "$tmp"
+} ||
+{
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$tmp/subs1.awk" &&
+_ACEOF
+
+
+{
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\).*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\).*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
+}
+
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
+ || as_fn_error "could not setup config files machinery" "$LINENO" 5
+_ACEOF
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=/{
+s/:*\$(srcdir):*/:/
+s/:*\${srcdir}:*/:/
+s/:*@srcdir@:*/:/
+s/^\([^=]*=[ ]*\):*/\1/
+s/:*$//
+s/^[^=]*=[ ]*$//
+}'
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
+
+
+eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
+
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
+ fi
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
+
+ case $ac_tag in
+ *:-:* | *:-) cat >"$tmp/stdin" \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
+ esac
+
+ ac_dir=`$as_dirname -- "$ac_file" ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$ac_file" : 'X\(//\)[^/]' \| \
+ X"$ac_file" : 'X\(//\)$' \| \
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
+ ac_builddir=.
+
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
+
+case $srcdir in
+ .) # We are building in place.
+ ac_srcdir=.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
+ ac_srcdir=$srcdir$ac_dir_suffix;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
+esac
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+ case $INSTALL in
+ [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;;
+ *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;;
+ esac
+ ac_MKDIR_P=$MKDIR_P
+ case $MKDIR_P in
+ [\\/$]* | ?:[\\/]* ) ;;
+ */*) ac_MKDIR_P=$ac_top_build_prefix$MKDIR_P ;;
+ esac
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
+esac
+_ACEOF
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+s&@INSTALL@&$ac_INSTALL&;t t
+s&@MKDIR_P@&$ac_MKDIR_P&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined." >&2;}
+
+ rm -f "$tmp/stdin"
+ case $ac_file in
+ -) cat "$tmp/out" && rm -f "$tmp/out";;
+ *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error "could not create $ac_file" "$LINENO" 5
+ ;;
+
+
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
+
+
+ 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
+ # if we detect the quoting.
+ case $CONFIG_FILES in
+ *\'*) eval set x "$CONFIG_FILES" ;;
+ *) set x $CONFIG_FILES ;;
+ esac
+ shift
+ for mf
+ do
+ # Strip MF so we end up with the name of the file.
+ mf=`echo "$mf" | sed -e 's/:.*$//'`
+ # Check whether this is an Automake generated Makefile or not.
+ # We used to match only the files named `Makefile.in', but
+ # some people rename them; so instead we look at the file content.
+ # Grep'ing the first line is not enough: some people post-process
+ # each Makefile.in and add a new line on top of each file to say so.
+ # Grep'ing the whole file is not good either: AIX grep has a line
+ # limit of 2048, but all sed's we know have understand at least 4000.
+ if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
+ dirpart=`$as_dirname -- "$mf" ||
+$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$mf" : 'X\(//\)[^/]' \| \
+ X"$mf" : 'X\(//\)$' \| \
+ X"$mf" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$mf" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ else
+ continue
+ fi
+ # Extract the definition of DEPDIR, am__include, and am__quote
+ # from the Makefile without running `make'.
+ DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
+ test -z "$DEPDIR" && continue
+ am__include=`sed -n 's/^am__include = //p' < "$mf"`
+ test -z "am__include" && continue
+ am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
+ # When using ansi2knr, U may be empty or an underscore; expand it
+ U=`sed -n 's/^U = //p' < "$mf"`
+ # Find all dependency output files, they are included files with
+ # $(DEPDIR) in their names. We invoke sed twice because it is the
+ # simplest approach to changing $(DEPDIR) to its actual value in the
+ # expansion.
+ for file in `sed -n "
+ s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
+ sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
+ # Make sure the directory exists.
+ test -f "$dirpart/$file" && continue
+ fdir=`$as_dirname -- "$file" ||
+$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$file" : 'X\(//\)[^/]' \| \
+ X"$file" : 'X\(//\)$' \| \
+ X"$file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir=$dirpart/$fdir; as_fn_mkdir_p
+ # echo "creating $dirpart/$file"
+ echo '# dummy' > "$dirpart/$file"
+ done
+ done
+}
+ ;;
+ "libtool":C)
+
+ # See if we are running on zsh, and set the options which allow our
+ # commands through without removal of \ escapes.
+ if test -n "${ZSH_VERSION+set}" ; then
+ setopt NO_GLOB_SUBST
+ fi
+
+ cfgfile="${ofile}T"
+ trap "$RM \"$cfgfile\"; exit 1" 1 2 15
+ $RM "$cfgfile"
+
+ cat <<_LT_EOF >> "$cfgfile"
+#! $SHELL
+
+# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services.
+# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION
+# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+# NOTE: Changes made to this file will be lost: look at ltmain.sh.
+#
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
+# 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+# Written by Gordon Matzigkeit, 1996
+#
+# This file is part of GNU Libtool.
+#
+# GNU Libtool is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# As a special exception to the GNU General Public License,
+# if you distribute this file as part of a program or library that
+# is built using GNU Libtool, you may include this file under the
+# same distribution terms that you use for the rest of that program.
+#
+# GNU Libtool 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 GNU Libtool; see the file COPYING. If not, a copy
+# can be downloaded from http://www.gnu.org/licenses/gpl.html, or
+# obtained by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+# The names of the tagged configurations supported by this script.
+available_tags="CXX "
+
+# ### BEGIN LIBTOOL CONFIG
+
+# Which release of libtool.m4 was used?
+macro_version=$macro_version
+macro_revision=$macro_revision
+
+# Whether or not to build shared libraries.
+build_libtool_libs=$enable_shared
+
+# Whether or not to build static libraries.
+build_old_libs=$enable_static
+
+# What type of objects to build.
+pic_mode=$pic_mode
+
+# Whether or not to optimize for fast installation.
+fast_install=$enable_fast_install
+
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The host system.
+host_alias=$host_alias
+host=$host
+host_os=$host_os
+
+# The build system.
+build_alias=$build_alias
+build=$build
+build_os=$build_os
+
+# A sed program that does not truncate output.
+SED=$lt_SED
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="\$SED -e 1s/^X//"
+
+# A grep program that handles long lines.
+GREP=$lt_GREP
+
+# An ERE matcher.
+EGREP=$lt_EGREP
+
+# A literal string matcher.
+FGREP=$lt_FGREP
+
+# A BSD- or MS-compatible name lister.
+NM=$lt_NM
+
+# Whether we need soft or hard links.
+LN_S=$lt_LN_S
+
+# What is the maximum length of a command?
+max_cmd_len=$max_cmd_len
+
+# Object file suffix (normally "o").
+objext=$ac_objext
+
+# Executable file suffix (normally "").
+exeext=$exeext
+
+# whether the shell understands "unset".
+lt_unset=$lt_unset
+
+# turn spaces into newlines.
+SP2NL=$lt_lt_SP2NL
+
+# turn newlines into spaces.
+NL2SP=$lt_lt_NL2SP
+
+# An object symbol dumper.
+OBJDUMP=$lt_OBJDUMP
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method=$lt_deplibs_check_method
+
+# Command to use when deplibs_check_method == "file_magic".
+file_magic_cmd=$lt_file_magic_cmd
+
+# The archiver.
+AR=$lt_AR
+AR_FLAGS=$lt_AR_FLAGS
+
+# A symbol stripping program.
+STRIP=$lt_STRIP
+
+# Commands used to install an old-style archive.
+RANLIB=$lt_RANLIB
+old_postinstall_cmds=$lt_old_postinstall_cmds
+old_postuninstall_cmds=$lt_old_postuninstall_cmds
+
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
+# A C compiler.
+LTCC=$lt_CC
+
+# LTCC compiler flags.
+LTCFLAGS=$lt_CFLAGS
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe
+
+# Transform the output of nm in a proper C declaration.
+global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl
+
+# Transform the output of nm in a C name address pair.
+global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
+
+# Transform the output of nm in a C name address pair when lib prefix is needed.
+global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
+
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
+
+# Used to examine libraries when file_magic_cmd begins with "file".
+MAGIC_CMD=$MAGIC_CMD
+
+# Must we lock files when doing compilation?
+need_locks=$lt_need_locks
+
+# Tool to manipulate archived DWARF debug symbol files on Mac OS X.
+DSYMUTIL=$lt_DSYMUTIL
+
+# Tool to change global to local symbols on Mac OS X.
+NMEDIT=$lt_NMEDIT
+
+# Tool to manipulate fat objects and archives on Mac OS X.
+LIPO=$lt_LIPO
+
+# ldd/readelf like tool for Mach-O binaries on Mac OS X.
+OTOOL=$lt_OTOOL
+
+# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4.
+OTOOL64=$lt_OTOOL64
+
+# Old archive suffix (normally "a").
+libext=$libext
+
+# Shared library suffix (normally ".so").
+shrext_cmds=$lt_shrext_cmds
+
+# The commands to extract the exported symbol list from a shared archive.
+extract_expsyms_cmds=$lt_extract_expsyms_cmds
+
+# Variables whose values should be saved in libtool wrapper scripts and
+# restored at link time.
+variables_saved_for_relink=$lt_variables_saved_for_relink
+
+# Do we need the "lib" prefix for modules?
+need_lib_prefix=$need_lib_prefix
+
+# Do we need a version for libraries?
+need_version=$need_version
+
+# Library versioning type.
+version_type=$version_type
+
+# Shared library runtime path variable.
+runpath_var=$runpath_var
+
+# Shared library path variable.
+shlibpath_var=$shlibpath_var
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=$shlibpath_overrides_runpath
+
+# Format of library name prefix.
+libname_spec=$lt_libname_spec
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME
+library_names_spec=$lt_library_names_spec
+
+# The coded name of the library, if different from the real name.
+soname_spec=$lt_soname_spec
+
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
+# Command to use after installation of a shared archive.
+postinstall_cmds=$lt_postinstall_cmds
+
+# Command to use after uninstallation of a shared archive.
+postuninstall_cmds=$lt_postuninstall_cmds
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds=$lt_finish_cmds
+
+# As "finish_cmds", except a single script fragment to be evaled but
+# not shown.
+finish_eval=$lt_finish_eval
+
+# Whether we should hardcode library paths into libraries.
+hardcode_into_libs=$hardcode_into_libs
+
+# Compile-time system search path for libraries.
+sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+
+# Run-time system search path for libraries.
+sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
+
+# Whether dlopen is supported.
+dlopen_support=$enable_dlopen
+
+# Whether dlopen of programs is supported.
+dlopen_self=$enable_dlopen_self
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=$enable_dlopen_self_static
+
+# Commands to strip libraries.
+old_striplib=$lt_old_striplib
+striplib=$lt_striplib
+
+
+# The linker used to build libraries.
+LD=$lt_LD
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds
+
+# A language specific compiler.
+CC=$lt_compiler
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds
+archive_expsym_cmds=$lt_archive_expsym_cmds
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds
+module_expsym_cmds=$lt_module_expsym_cmds
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects
+postdep_objects=$lt_postdep_objects
+predeps=$lt_predeps
+postdeps=$lt_postdeps
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path
+
+# ### END LIBTOOL CONFIG
+
+_LT_EOF
+
+ case $host_os in
+ aix3*)
+ cat <<\_LT_EOF >> "$cfgfile"
+# AIX sometimes has problems with the GCC collect2 program. For some
+# reason, if we set the COLLECT_NAMES environment variable, the problems
+# vanish in a puff of smoke.
+if test "X${COLLECT_NAMES+set}" != Xset; then
+ COLLECT_NAMES=
+ export COLLECT_NAMES
+fi
+_LT_EOF
+ ;;
+ esac
+
+
+ltmain="$ac_aux_dir/ltmain.sh"
+
+
+ # We use sed instead of cat because bash on DJGPP gets confused if
+ # if finds mixed CR/LF and LF-only lines. Since sed operates in
+ # text mode, it properly converts lines to CR/LF. This bash problem
+ # is reportedly fixed, but why not run on old versions too?
+ sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ case $xsi_shell in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result="${1##*/}"
+}
+
+# func_dirname_and_basename file append nondir_replacement
+# perform func_basename and func_dirname in a single function
+# call:
+# dirname: Compute the dirname of FILE. If nonempty,
+# add APPEND to the result, otherwise set result
+# to NONDIR_REPLACEMENT.
+# value returned in "$func_dirname_result"
+# basename: Compute filename of FILE.
+# value retuned in "$func_basename_result"
+# Implementation must be kept synchronized with func_dirname
+# and func_basename. For efficiency, we do not delegate to
+# those functions but instead duplicate the functionality here.
+func_dirname_and_basename ()
+{
+ case ${1} in
+ */*) func_dirname_result="${1%/*}${2}" ;;
+ * ) func_dirname_result="${3}" ;;
+ esac
+ func_basename_result="${1##*/}"
+}
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+func_stripname ()
+{
+ # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+ # positional parameters, so assign one to ordinary parameter first.
+ func_stripname_result=${3}
+ func_stripname_result=${func_stripname_result#"${1}"}
+ func_stripname_result=${func_stripname_result%"${2}"}
+}
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=${1%%=*}
+ func_opt_split_arg=${1#*=}
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ case ${1} in
+ *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+ *) func_lo2o_result=${1} ;;
+ esac
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=${1%.*}.lo
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=$(( $* ))
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=${#1}
+}
+
+_LT_EOF
+ ;;
+ *) # Bourne compatible functions.
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE. If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+ # Extract subdirectory from the argument.
+ func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+ if test "X$func_dirname_result" = "X${1}"; then
+ func_dirname_result="${3}"
+ else
+ func_dirname_result="$func_dirname_result${2}"
+ fi
+}
+
+# func_basename file
+func_basename ()
+{
+ func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+}
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+ case ${2} in
+ .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+ *) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+ esac
+}
+
+# sed scripts:
+my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
+my_sed_long_arg='1s/^-[^=]*=//'
+
+# func_opt_split
+func_opt_split ()
+{
+ func_opt_split_opt=`$ECHO "${1}" | $SED "$my_sed_long_opt"`
+ func_opt_split_arg=`$ECHO "${1}" | $SED "$my_sed_long_arg"`
+}
+
+# func_lo2o object
+func_lo2o ()
+{
+ func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+}
+
+# func_xform libobj-or-source
+func_xform ()
+{
+ func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+}
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+ func_arith_result=`expr "$@"`
+}
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+ func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
+}
+
+_LT_EOF
+esac
+
+case $lt_shell_append in
+ yes)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1+=\$2"
+}
+_LT_EOF
+ ;;
+ *)
+ cat << \_LT_EOF >> "$cfgfile"
+
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+ eval "$1=\$$1\$2"
+}
+
+_LT_EOF
+ ;;
+ esac
+
+
+ sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
+ || (rm -f "$cfgfile"; exit 1)
+
+ mv -f "$cfgfile" "$ofile" ||
+ (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
+ chmod +x "$ofile"
+
+
+ cat <<_LT_EOF >> "$ofile"
+
+# ### BEGIN LIBTOOL TAG CONFIG: CXX
+
+# The linker used to build libraries.
+LD=$lt_LD_CXX
+
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_CXX
+reload_cmds=$lt_reload_cmds_CXX
+
+# Commands used to build an old-style archive.
+old_archive_cmds=$lt_old_archive_cmds_CXX
+
+# A language specific compiler.
+CC=$lt_compiler_CXX
+
+# Is the compiler the GNU compiler?
+with_gcc=$GCC_CXX
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_CXX
+
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_CXX
+
+# Additional compiler flags for building library objects.
+pic_flag=$lt_lt_prog_compiler_pic_CXX
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag=$lt_lt_prog_compiler_static_CXX
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o=$lt_lt_cv_prog_compiler_c_o_CXX
+
+# Whether or not to add -lc for building shared libraries.
+build_libtool_need_lc=$archive_cmds_need_lc_CXX
+
+# Whether or not to disallow shared libs when runtime libs are static.
+allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes_CXX
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec=$lt_export_dynamic_flag_spec_CXX
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec=$lt_whole_archive_flag_spec_CXX
+
+# Whether the compiler copes with passing no objects directly.
+compiler_needs_object=$lt_compiler_needs_object_CXX
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=$lt_old_archive_from_new_cmds_CXX
+
+# Create a temporary old-style archive to link instead of a shared archive.
+old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds_CXX
+
+# Commands used to build a shared archive.
+archive_cmds=$lt_archive_cmds_CXX
+archive_expsym_cmds=$lt_archive_expsym_cmds_CXX
+
+# Commands used to build a loadable module if different from building
+# a shared archive.
+module_cmds=$lt_module_cmds_CXX
+module_expsym_cmds=$lt_module_expsym_cmds_CXX
+
+# Whether we are building with GNU ld or not.
+with_gnu_ld=$lt_with_gnu_ld_CXX
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=$lt_allow_undefined_flag_CXX
+
+# Flag that enforces no undefined symbols.
+no_undefined_flag=$lt_no_undefined_flag_CXX
+
+# Flag to hardcode \$libdir into a binary during linking.
+# This must work even if \$libdir does not exist
+hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_CXX
+
+# If ld is used when linking, flag to hardcode \$libdir into a binary
+# during linking. This must work even if \$libdir does not exist.
+hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_CXX
+
+# Whether we need a single "-rpath" flag with a separated argument.
+hardcode_libdir_separator=$lt_hardcode_libdir_separator_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary.
+hardcode_direct=$hardcode_direct_CXX
+
+# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes
+# DIR into the resulting binary and the resulting library dependency is
+# "absolute",i.e impossible to change by setting \${shlibpath_var} if the
+# library is relocated.
+hardcode_direct_absolute=$hardcode_direct_absolute_CXX
+
+# Set to "yes" if using the -LDIR flag during linking hardcodes DIR
+# into the resulting binary.
+hardcode_minus_L=$hardcode_minus_L_CXX
+
+# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR
+# into the resulting binary.
+hardcode_shlibpath_var=$hardcode_shlibpath_var_CXX
+
+# Set to "yes" if building a shared library automatically hardcodes DIR
+# into the library and all subsequent libraries and executables linked
+# against it.
+hardcode_automatic=$hardcode_automatic_CXX
+
+# Set to yes if linker adds runtime paths of dependent libraries
+# to runtime path list.
+inherit_rpath=$inherit_rpath_CXX
+
+# Whether libtool must link a program against all its dependency libraries.
+link_all_deplibs=$link_all_deplibs_CXX
+
+# Fix the shell variable \$srcfile for the compiler.
+fix_srcfile_path=$lt_fix_srcfile_path_CXX
+
+# Set to "yes" if exported symbols are required.
+always_export_symbols=$always_export_symbols_CXX
+
+# The commands to list exported symbols.
+export_symbols_cmds=$lt_export_symbols_cmds_CXX
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms=$lt_exclude_expsyms_CXX
+
+# Symbols that must always be exported.
+include_expsyms=$lt_include_expsyms_CXX
+
+# Commands necessary for linking programs (against libraries) with templates.
+prelink_cmds=$lt_prelink_cmds_CXX
+
+# Specify filename containing input files.
+file_list_spec=$lt_file_list_spec_CXX
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=$hardcode_action_CXX
+
+# The directories searched by this compiler when creating a shared library.
+compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX
+
+# Dependencies to place before and after the objects being linked to
+# create a shared library.
+predep_objects=$lt_predep_objects_CXX
+postdep_objects=$lt_postdep_objects_CXX
+predeps=$lt_predeps_CXX
+postdeps=$lt_postdeps_CXX
+
+# The library search path used internally by the compiler when linking
+# a shared library.
+compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+
+# ### END LIBTOOL TAG CONFIG: CXX
+_LT_EOF
+
+ ;;
+ "./Makefile":F) cat > vpsed$$ << \_EOF
+s!`test -f '$<' || echo '$(srcdir)/'`!!
+_EOF
+ sed -f vpsed$$ $ac_file > tmp$$
+ mv tmp$$ $ac_file
+ rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
+ ;;
+ "testsuite/Makefile":F) cat > vpsed$$ << \_EOF
+s!`test -f '$<' || echo '$(srcdir)/'`!!
+_EOF
+ sed -f vpsed$$ $ac_file > tmp$$
+ mv tmp$$ $ac_file
+ rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ { ml_norecursion=; unset ml_norecursion;}
+ ;;
+
+ esac
+done # for ac_tag
+
+
+as_fn_exit 0
+_ACEOF
+ac_clean_files=$ac_clean_files_save
+
+test $ac_write_fail = 0 ||
+ as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded. So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status. When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+ ac_cs_success=:
+ ac_config_status_args=
+ test "$silent" = yes &&
+ ac_config_status_args="$ac_config_status_args --quiet"
+ exec 5>/dev/null
+ $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+ exec 5>>config.log
+ # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+ # would make configure fail if this is the last instruction.
+ $ac_cs_success || as_fn_exit $?
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
+fi
+
diff --git a/libvtv/configure.ac b/libvtv/configure.ac
new file mode 100644
index 00000000000..6db97dc60b8
--- /dev/null
+++ b/libvtv/configure.ac
@@ -0,0 +1,143 @@
+# -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_PREREQ([2.64])
+AC_INIT([GNU Vtable Verification Runtime Library], 1.0,,[libvtv])
+#AC_INIT(package-unused, version-unused, libvtv)
+AC_CONFIG_SRCDIR([vtv_rts.h])
+
+# -------
+# Options
+# -------
+AC_MSG_CHECKING([for --enable-version-specific-runtime-libs])
+AC_ARG_ENABLE(version-specific-runtime-libs,
+[ --enable-version-specific-runtime-libs Specify that runtime libraries should be installed in a compiler-specific directory ],
+[case "$enableval" in
+ yes) version_specific_libs=yes ;;
+ no) version_specific_libs=no ;;
+ *) AC_MSG_ERROR([Unknown argument to enable/disable version-specific libs]);;
+ esac],
+[version_specific_libs=no])
+AC_MSG_RESULT($version_specific_libs)
+
+# See if supported.
+unset VTV_SUPPORTED
+AC_MSG_CHECKING([for host support for vtable verification])
+. ${srcdir}/configure.tgt
+AC_MSG_RESULT($VTV_SUPPORTED)
+
+# Decide if it's usable.
+use_vtable_verify=no
+if test "x$VTV_SUPPORTED" = "xyes"; then
+ use_vtable_verify=yes
+ AC_MSG_NOTICE(using vtable verification)
+fi
+
+# Do not delete or change the following two lines. For why, see
+# http://gcc.gnu.org/ml/libstdc++/2003-07/msg00451.html
+AC_CANONICAL_SYSTEM
+target_alias=${target_alias-$host_alias}
+AC_SUBST(target_alias)
+GCC_LIBSTDCXX_RAW_CXX_FLAGS
+
+AM_INIT_AUTOMAKE(foreign no-dist)
+AM_ENABLE_MULTILIB(, ..)
+AM_MAINTAINER_MODE
+
+LIBVTV_CONFIGURE
+
+# Calculate toolexeclibdir
+# Also toolexecdir, though it's only used in toolexeclibdir
+case ${version_specific_libs} in
+ yes)
+ # Need the gcc compiler version to know where to install libraries
+ # and header files if --enable-version-specific-runtime-libs option
+ # is selected.
+ toolexecdir='$(libdir)/gcc/$(target_alias)'
+ toolexeclibdir='$(toolexecdir)/$(gcc_version)$(MULTISUBDIR)'
+ ;;
+ no)
+ if test -n "$with_cross_host" &&
+ test x"$with_cross_host" != x"no"; then
+ # Install a library built with a cross compiler in tooldir, not libdir.
+ toolexecdir='$(exec_prefix)/$(target_alias)'
+ toolexeclibdir='$(toolexecdir)/lib'
+ else
+ toolexecdir='$(libdir)/gcc-lib/$(target_alias)'
+ toolexeclibdir='$(libdir)'
+ fi
+ multi_os_directory=`$CC -print-multi-os-directory`
+ case $multi_os_directory in
+ .) ;; # Avoid trailing /.
+ *) toolexeclibdir=$toolexeclibdir/$multi_os_directory ;;
+ esac
+ ;;
+esac
+AC_SUBST(toolexecdir)
+AC_SUBST(toolexeclibdir)
+
+AC_GNU_SOURCE
+AC_CHECK_FUNCS([__secure_getenv])
+
+AC_GNU_SOURCE
+AC_CHECK_FUNCS([secure_getenv])
+
+# Check for programs.
+m4_rename([_AC_ARG_VAR_PRECIOUS],[real_PRECIOUS])
+m4_define([_AC_ARG_VAR_PRECIOUS],[])
+AC_PROG_CC
+AC_PROG_CXX
+m4_rename_force([real_PRECIOUS],[_AC_ARG_VAR_PRECIOUS])
+
+AM_PROG_CC_C_O
+
+AC_SUBST(CFLAGS)
+AC_SUBST(CXXFLAGS)
+
+# Newer automakes demand CCAS and CCASFLAGS.
+: ${CCAS='$(CC)'}
+: ${CCASFLAGS='$(CFLAGS)'}
+AC_SUBST(CCAS)
+AC_SUBST(CCASFLAGS)
+
+AC_CHECK_TOOL(AS, as)
+AC_CHECK_TOOL(AR, ar)
+AC_CHECK_TOOL(RANLIB, ranlib, :)
+
+# Configure libtool
+AC_LIBTOOL_DLOPEN
+AM_PROG_LIBTOOL
+AC_SUBST(enable_shared)
+AC_SUBST(enable_static)
+
+# For libtool versioning info, format is CURRENT:REVISION:AGE
+libtool_VERSION=1:0:0
+AC_SUBST(libtool_VERSION)
+
+XCFLAGS="-D_GNU_SOURCE -Wall -Wextra -fno-exceptions"
+AC_SUBST(XCFLAGS)
+
+if test "${multilib}" = "yes"; then
+ multilib_arg="--enable-multilib"
+else
+ multilib_arg=
+fi
+
+AC_CONFIG_FILES([Makefile])
+
+if test "x$VTV_SUPPORTED" = "xyes"; then
+ AC_CONFIG_FILES(AC_FOREACH([DIR], [. testsuite], [DIR/Makefile ]),
+ [cat > vpsed$$ << \_EOF
+s!`test -f '$<' || echo '$(srcdir)/'`!!
+_EOF
+ sed -f vpsed$$ $ac_file > tmp$$
+ mv tmp$$ $ac_file
+ rm vpsed$$
+ echo 'MULTISUBDIR =' >> $ac_file
+ ml_norecursion=yes
+ . ${multi_basedir}/config-ml.in
+ AS_UNSET([ml_norecursion])
+])
+fi
+
+AC_OUTPUT
diff --git a/libvtv/configure.tgt b/libvtv/configure.tgt
new file mode 100644
index 00000000000..801d2f09564
--- /dev/null
+++ b/libvtv/configure.tgt
@@ -0,0 +1,37 @@
+# -*- shell-script -*-
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not see <http://www.gnu.org/licenses/>.
+
+# This is the target specific configuration file. This is invoked by the
+# autoconf generated configure script. Putting it in a separate shell file
+# lets us skip running autoconf when modifying target specific information.
+
+# Filter out unsupported systems.
+VTV_SUPPORTED=no
+case "${target}" in
+ x86_64-*-linux* | i?86-*-linux*)
+ VTV_SUPPORTED=yes
+ ;;
+ powerpc*-*-linux*)
+ ;;
+ sparc*-*-linux*)
+ ;;
+ arm*-*-linux*)
+ ;;
+ x86_64-*-darwin[1]* | i?86-*-darwin[1]*)
+ ;;
+ *)
+ ;;
+esac
diff --git a/libvtv/scripts/run-testsuite.sh b/libvtv/scripts/run-testsuite.sh
new file mode 100644
index 00000000000..a02ce1562e6
--- /dev/null
+++ b/libvtv/scripts/run-testsuite.sh
@@ -0,0 +1,226 @@
+#!/usr/bin/env bash
+
+# Script to do testing.
+
+# Invocation
+# run-testsuite SRC_DIR BUILD_DIR
+
+# Pass in build/src directory as parameters.
+SRC_DIR=$1
+BUILD_DIR=$2
+
+# Now that we've successfully translated the numerical option into
+# a symbolic one, we can safely ignore it.
+shift
+
+# Use build compiler/library flags from libstdc++
+flags_script=$BUILD_DIR/../libstdc++-v3/scripts/testsuite_flags
+INCLUDES=`$flags_script --build-includes`
+COMPILER=`$flags_script --build-cxx`
+CXX="$COMPILER $INCLUDES -L$BUILD_DIR/.libs -Wl,--rpath -Wl,$BUILD_DIR/.libs"
+
+echo "compiler config is:"
+echo $CXX
+echo ""
+
+# Other constants.
+LOPT_LEVELS=${OPT_LEVELS:-"-O0 -O2"}
+#LDATA_MODELS=${DATA_MODELS:-"32 64"}
+LDATA_MODELS=${DATA_MODELS:-"64"}
+
+# Check if value of LGCC_LIB_PATH/$1 exists. If it does, save this path.
+# If it doesn't, use LGCC_LIB_PATH as the library path.
+# This allows us to check for paths that are of the form <x>/lib32 or <x>/lib64.
+get_lib_path()
+{
+ if [[ -e $LGCC_LIB_PATH$1 ]]; then
+ LLGCC_LIB_PATH=$LGCC_LIB_PATH$1
+ else
+ LLGCC_LIB_PATH=$LGCC_LIB_PATH
+ fi
+ return
+}
+
+LGCC_SRC=$SRC_DIR/testsuite
+
+TESTS="const_vtable.cc dataentry.cc dup_name.cc environment.cc template-list.cc template-list2.cc template-list-iostream.cc povray-derived.cc thunk.cc thunk_vtable_map_attack.cc virtual_inheritance.cc "
+
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for T in $TESTS; do
+ TSRC=${LGCC_SRC}/${T}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fvtable-verify=std -fpic -rdynamic -Wl,-z,relro ${TSRC} ${OL}"
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 ) && echo "PASS $T $OL") || echo "FAIL $T $OL"
+ done
+ done
+done
+
+TESTS_COMPOUND_parts="${LGCC_SRC}/parts-test-main.cc ${LGCC_SRC}/parts-test-extra-parts.cc ${LGCC_SRC}/parts-test-extra-parts-views.cc"
+TESTS_COMPOUND_events="${LGCC_SRC}/event-main.cc ${LGCC_SRC}/event-definitions.cc ${LGCC_SRC}/event-private.cc"
+
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fvtable-verify=std -fpic -rdynamic -Wl,-z,relro ${TESTS_COMPOUND_parts} ${OL}"
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 ) && echo "PASS $T $OL") || echo "FAIL $T $OL"
+ done
+done
+
+for M in $LDATA_MODELS; do
+ for (( TN = 0 ; TN < 100 ; TN++ )); do
+ SO_NAME=so$TN.so
+ if [ -f ./lib${M}/$SO_NAME ]; then
+ /bin/rm ./lib${M}/$SO_NAME
+ fi
+ CMD="${CXX} -m${M} -fvtable-verify=std -O0 -g -shared -fpic -rdynamic -Wl,-z,relro -DTPID=$TN -I${SRC_DIR} ${LGCC_SRC}/so.cc -o ./lib${M}/$SO_NAME"
+ echo ${CMD}
+ ${CMD} || exit 8
+ done
+done
+
+DLOPEN_TESTS="dlopen.cc dlopen_mt.cc"
+
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for T in $DLOPEN_TESTS; do
+ TSRC=${LGCC_SRC}/${T}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fvtable-verify=std -fpic -rdynamic -Wl,-z,relro -Wl,-R,./lib${M} -I${SRC_DIR} ${TSRC} ${OL} -ldl -lpthread"
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 ) && echo "PASS $T $OL") || echo "FAIL $T $OL"
+ done
+ done
+done
+
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for T in $TESTS; do
+ TSRC=${LGCC_SRC}/${T}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fvtable-verify=preinit -fpic -rdynamic -Wl,-z,relro ${TSRC} ${OL}"
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 ) && echo "PASS $T $OL") || echo "FAIL $T $OL"
+ done
+ done
+done
+
+for M in $LDATA_MODELS; do
+ if [ -f ./lib${M}/vtv_malloc.o ]; then
+ /bin/rm ./lib${M}/vtv_malloc.o;
+ fi
+ CMD="${CXX} -m${M} -O2 -g -c -fpic ${SRC_DIR}/vtv_malloc.cc -o ./lib${M}/vtv_malloc.o"
+ echo ${CMD}
+ ${CMD} || exit 3
+
+ if [ -f ./lib${M}/vtv_utils.o ]; then
+ /bin/rm ./lib${M}/vtv_utils.o;
+ fi
+ CMD="${CXX} -m${M} -O2 -g -c -fpic ${SRC_DIR}/vtv_utils.cc -o ./lib${M}/vtv_utils.o"
+ echo ${CMD}
+ ${CMD} || exit 4
+done
+
+MEMPOOL_TESTS="mempool_positive.c mempool_negative.c"
+
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for T in $MEMPOOL_TESTS; do
+ TSRC=${LGCC_SRC}/${T}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fpic -rdynamic -I${SRC_DIR} ${TSRC} ${OL} ./lib${M}/vtv_malloc.o ./lib${M}/vtv_utils.o"
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 ) && echo "PASS $T $OL") || echo "FAIL $T $OL"
+ done
+ done
+done
+
+# bkoz not working ATM signature mismatch
+#MT_TESTS="register_pair_mt.cc register_pair_inserts_mt.cc"
+MT_TESTS=
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for T in $MT_TESTS; do
+ TSRC=${LGCC_SRC}/${T}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fpic -rdynamic -I${SRC_DIR} ${TSRC} ${OL} -lpthread"
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 ) && echo "PASS $T $OL") || echo "FAIL $T $OL"
+ done
+ done
+done
+
+# These test cases were written for performance measurements, not for
+# correctness but lets run them here so that we dont loose track of
+# them
+# bkoz not working ATM signature mismatch
+#PERF_TESTS="register_pair.cc register_pair_inserts.cc"
+PERF_TESTS=
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for T in $PERF_TESTS; do
+ TSRC=${LGCC_SRC}/${T}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fpic -rdynamic -I${SRC_DIR} ${TSRC} ${OL} "
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 ) && echo "PASS $T $OL") || echo "FAIL $T $OL"
+ done
+ done
+done
+
+
+PASS_FAIL_TESTS="field-test.cc temp_deriv.cc temp_deriv2.cc temp_deriv3.cc"
+
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for T in $PASS_FAIL_TESTS; do
+ TSRC=${LGCC_SRC}/${T}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fvtable-verify=std -fpic -rdynamic ${TSRC} ${OL} -Wl,-z,relro -DTPID"
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 )) || (( grep "Pass first attack" $T.$OL.out ) && echo "PASS $T $OL - correctly passed then failed.") || echo "FAIL $T $OL"
+ done
+ done
+done
+
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for T in $PERF_TESTS; do
+ TSRC=${LGCC_SRC}/${T}
+ for OL in $LOPT_LEVELS; do
+ CMD="${CXX} -m${M} -fpic -rdynamic -I${SRC_DIR} ${TSRC} ${OL} "
+ echo $CMD
+ ($CMD && ( ./a.out > $T.$OL.out 2>&1 ) && echo "PASS $T $OL") || echo "FAIL $T $OL"
+ done
+ done
+done
+
+for M in $LDATA_MODELS; do
+ get_lib_path lib${M}
+ for OL in $LOPT_LEVELS; do
+
+ CMD="as --${M} -o environment-fail-${M}.o ${LGCC_SRC}/environment-fail-${M}.s"
+ echo $CMD
+ ${CMD} || exit 5
+
+ CMD="${CXX} -m${M} environment-fail-${M}.o -O0 -Wl,-z,relro -o environment-fail-${M}"
+ echo ${CMD}
+ # ${CMD} || exit 6
+ # (./environment-fail-${M}) || echo "PASS environment-fail-${M} (correctly failed), ${OL}"
+
+ CMD="${CXX} -fvtable-verify=std -m${M} environment-fail-${M}.o -O0 -Wl,-z,relro -o environment-fail-${M}"
+ echo ${CMD}
+ ($CMD && ( ./environment-fail-${M} > environment-fail-${M}-stubs.out 2>&1 ) && echo "PASS environment-fail-${M} with libvtv_stubs ${OL}" ) || echo "FAIL environment-fail-${M} with libvtv_stubs ${OL}"
+
+ CMD="${CXX} -m${M} ${LGCC_SRC}/replace-fail.cc -O0 -c -o replace-fail-${M}.o"
+ echo ${CMD}
+ ${CMD} || exit 7
+
+ CMD="${CXX} -fvtable-verify=std -m${M} environment-fail-${M}.o replace-fail-${M}.o -O0 -Wl,-z,relro -o environment-fail-${M}"
+ echo ${CMD}
+ ($CMD && ( ./environment-fail-${M} > environment-fail-${M}-stubs.out 2>&1 ) && echo "PASS environment-fail-${M} with replace-fail ${OL}" ) || echo "FAIL environment-fail-${M} with replace-fail ${OL}"
+ done
+done
+
diff --git a/libvtv/scripts/sum-vtv-counts.c b/libvtv/scripts/sum-vtv-counts.c
new file mode 100644
index 00000000000..fc99498e705
--- /dev/null
+++ b/libvtv/scripts/sum-vtv-counts.c
@@ -0,0 +1,150 @@
+/*
+This script sums up the counters for seeing how many virtual calls are
+actually being verified. The flag for generating the count data is
+"-fvtv-counts". This flag will generate two files in /tmp,
+"vtv_count_data.log" and "vtv_class_set_sizes.log". The first file is
+the one that contains the info I mentioned; the second one is one I
+generated because I was curious about how big the average set size was
+for the vtable verification work.
+
+After compiling the attached program, run it on the vtv_count_data.log
+file:
+
+$ sum-counters /tmp/vtv_count_data.log
+
+One can optionally pass a "--verbose" flag. This file generates an
+output file whose name is the same as the input file, with ".summary"
+appended to it, e.g. /tmp/vtv_count_data.log.summary . Without the
+verbose flag, it will just contain something like this:
+
+Total # virtual calls: 349123
+Total # verified calls: 348236
+Percent verified: 99 %
+
+Total calls to __VLTRegisterSet: 42236
+Total calls to __VLTRegisterPair: 84371
+Total # unused vtable map vars: 1536333
+
+With the --verbose flag it will also output one line for each
+compilation unit for which it verified less than 90% of the virtual
+calls (and there were more than 20 virtual calls in the file),
+something like this:
+
+Verified 1 out of 25 (4.00%) : foo.cc
+Verified 27 out of 43 (62.00%) : bar.cc
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+void
+usage (const char *error_text)
+{
+ fprintf (stderr, "%s", error_text);
+ fprintf (stderr, "Usage: \n");
+ fprintf (stderr, "sum-counters <input-file> [--verbose]\n");
+}
+
+int
+main (int argc, char **argv)
+{
+ FILE *fp_in = NULL;
+ FILE *fp_out = NULL;
+ int sum_vcalls = 0;
+ int sum_verified = 0;
+ int sum_regset = 0;
+ int sum_regpair = 0;
+ int sum_unused = 0;
+ char fname_in[1024];
+ char fname_out[1024];
+ int total;
+ int verified;
+ int regset;
+ int regpair;
+ int unused;
+ float pct;
+ char buffer[1024];
+ int verbose = 0;
+
+ if (argc < 2)
+ {
+ usage ("Error: Need an input file.\n");
+ return 1;
+ }
+
+ fp_in = fopen (argv[1], "r");
+ if (!fp_in)
+ {
+ snprintf (buffer, 1024, "Error: Unable to open input file '%s'.\n",
+ argv[1]);
+ usage (buffer);
+ return 1;
+ }
+
+ if (argc == 3)
+ {
+ if (strcmp (argv[2], "--verbose") == 0)
+ verbose = 1;
+ else
+ {
+ snprintf (buffer, 1024, "Error: Unrecognized option '%s'.\n",
+ argv[2]);
+ usage (buffer);
+ return 1;
+ }
+ }
+
+ snprintf (fname_out, 1024, "%s.summary", argv[1]);
+
+ fp_out = fopen (fname_out, "w");
+ if (!fp_out)
+ {
+ fprintf (stderr, "Error: Unable to open output file '%s'\n",
+ fname_out);
+ return 1;
+ }
+
+ while (fscanf (fp_in, "%s %d %d %d %d %d\n", fname_in, &total,
+ &verified, &regset, &regpair, &unused) != EOF)
+ {
+ sum_vcalls += total;
+ sum_verified += verified;
+ sum_regset += regset;
+ sum_regpair += regpair;
+ sum_unused += unused;
+
+ float tmp_pct = 0.0;
+
+ if (total > 0)
+ tmp_pct = (verified * 100) / total;
+
+ if (verbose && tmp_pct < 90 && total >= 20)
+ {
+ fprintf (fp_out, "Verified %d out of %d (%.2f%%) : %s\n",
+ verified, total, tmp_pct, fname_in);
+ }
+
+ }
+
+ fclose (fp_in);
+
+ fprintf (fp_out, "\n\n");
+ fprintf (fp_out, "Total # virtual calls: %d\n", sum_vcalls);
+ fprintf (fp_out, "Total # verified calls: %d\n", sum_verified);
+ if (sum_vcalls > 0)
+ fprintf (fp_out, "Percent verified: %d %%\n",
+ sum_verified * 100 / sum_vcalls);
+ else
+ fprintf (fp_out, "Percent verified: NA %%\n");
+
+ fprintf (fp_out, "\nTotal calls to __VLTRegisterSet: %d\n",
+ sum_regset);
+ fprintf (fp_out, "Total calls to __VLTRegisterPair: %d\n",
+ sum_regpair);
+ fprintf (fp_out, "Total # unused vtable map vars: %d\n", sum_unused);
+
+ fclose (fp_out);
+
+ return 0;
+}
diff --git a/libvtv/testsuite/Makefile.am b/libvtv/testsuite/Makefile.am
new file mode 100644
index 00000000000..a2c1e9f4ea3
--- /dev/null
+++ b/libvtv/testsuite/Makefile.am
@@ -0,0 +1,11 @@
+## Process this with automake to create Makefile.in
+
+AUTOMAKE_OPTIONS = foreign dejagnu
+
+EXPECT = `if [ -f ../../expect/expect ] ; then \
+ echo ../../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \
+ echo ${srcdir}/../../dejagnu/runtest ; \
+ else echo runtest ; fi`
diff --git a/libvtv/testsuite/Makefile.in b/libvtv/testsuite/Makefile.in
new file mode 100644
index 00000000000..ba28e744f95
--- /dev/null
+++ b/libvtv/testsuite/Makefile.in
@@ -0,0 +1,400 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = testsuite
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/depstand.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/libstdc++-raw-cxx.m4 \
+ $(top_srcdir)/../config/multi.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+DEJATOOL = $(PACKAGE)
+RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX_RAW_CXX_CXXFLAGS = @LIBSTDCXX_RAW_CXX_CXXFLAGS@
+LIBSTDCXX_RAW_CXX_LDFLAGS = @LIBSTDCXX_RAW_CXX_LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XCFLAGS = @XCFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libtool_VERSION = @libtool_VERSION@
+libvtv_builddir = @libvtv_builddir@
+libvtv_srcdir = @libvtv_srcdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+multi_basedir = @multi_basedir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_noncanonical = @target_noncanonical@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+toplevel_builddir = @toplevel_builddir@
+toplevel_srcdir = @toplevel_srcdir@
+AUTOMAKE_OPTIONS = foreign dejagnu
+EXPECT = `if [ -f ../../expect/expect ] ; then \
+ echo ../../expect/expect ; \
+ else echo expect ; fi`
+
+RUNTEST = `if [ -f ${srcdir}/../../dejagnu/runtest ] ; then \
+ echo ${srcdir}/../../dejagnu/runtest ; \
+ else echo runtest ; fi`
+
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign testsuite/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+
+check-DEJAGNU: site.exp
+ srcdir=`$(am__cd) $(srcdir) && pwd`; export srcdir; \
+ EXPECT=$(EXPECT); export EXPECT; \
+ runtest=$(RUNTEST); \
+ if $(SHELL) -c "$$runtest --version" > /dev/null 2>&1; then \
+ exit_status=0; l='$(DEJATOOL)'; for tool in $$l; do \
+ if $$runtest $(AM_RUNTESTFLAGS) $(RUNTESTDEFAULTFLAGS) $(RUNTESTFLAGS); \
+ then :; else exit_status=1; fi; \
+ done; \
+ else echo "WARNING: could not find \`runtest'" 1>&2; :;\
+ fi; \
+ exit $$exit_status
+site.exp: Makefile
+ @echo 'Making a new site.exp file...'
+ @echo '## these variables are automatically generated by make ##' >site.tmp
+ @echo '# Do not edit here. If you wish to override these values' >>site.tmp
+ @echo '# edit the last section' >>site.tmp
+ @echo 'set srcdir $(srcdir)' >>site.tmp
+ @echo "set objdir `pwd`" >>site.tmp
+ @echo 'set build_alias "$(build_alias)"' >>site.tmp
+ @echo 'set build_triplet $(build_triplet)' >>site.tmp
+ @echo 'set host_alias "$(host_alias)"' >>site.tmp
+ @echo 'set host_triplet $(host_triplet)' >>site.tmp
+ @echo 'set target_alias "$(target_alias)"' >>site.tmp
+ @echo 'set target_triplet $(target_triplet)' >>site.tmp
+ @echo '## All variables above are generated by configure. Do Not Edit ##' >>site.tmp
+ @test ! -f site.exp || \
+ sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp
+ @-rm -f site.bak
+ @test ! -f site.exp || mv site.exp site.bak
+ @mv site.tmp site.exp
+
+distclean-DEJAGNU:
+ -rm -f site.exp site.bak
+ -l='$(DEJATOOL)'; for tool in $$l; do \
+ rm -f $$tool.sum $$tool.log; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-DEJAGNU distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: check-am install-am install-strip
+
+.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \
+ clean-libtool distclean distclean-DEJAGNU distclean-generic \
+ distclean-libtool dvi dvi-am html html-am info info-am install \
+ install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am install-html \
+ install-html-am install-info install-info-am install-man \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-strip installcheck installcheck-am installdirs \
+ maintainer-clean maintainer-clean-generic mostlyclean \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ uninstall uninstall-am
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libvtv/testsuite/config/default.exp b/libvtv/testsuite/config/default.exp
new file mode 100644
index 00000000000..6d5eba84f10
--- /dev/null
+++ b/libvtv/testsuite/config/default.exp
@@ -0,0 +1,17 @@
+# Copyright (C) 2013 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+load_lib "standard.exp"
diff --git a/libvtv/testsuite/lib/libvtv-dg.exp b/libvtv/testsuite/lib/libvtv-dg.exp
new file mode 100644
index 00000000000..b140c194cdc
--- /dev/null
+++ b/libvtv/testsuite/lib/libvtv-dg.exp
@@ -0,0 +1,21 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+proc libvtv-dg-test { prog do_what extra_tool_flags } {
+ return [gcc-dg-test-1 libvtv_target_compile $prog $do_what $extra_tool_flags]
+}
+
+proc libvtv-dg-prune { system text } {
+ return [gcc-dg-prune $system $text]
+}
diff --git a/libvtv/testsuite/lib/libvtv.exp b/libvtv/testsuite/lib/libvtv.exp
new file mode 100644
index 00000000000..83674be29a2
--- /dev/null
+++ b/libvtv/testsuite/lib/libvtv.exp
@@ -0,0 +1,220 @@
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+# Damn dejagnu for not having proper library search paths for load_lib.
+# We have to explicitly load everything that gcc-dg.exp wants to load.
+
+proc load_gcc_lib { filename } {
+ global srcdir loaded_libs
+
+ load_file $srcdir/../../gcc/testsuite/lib/$filename
+ set loaded_libs($filename) ""
+}
+
+load_lib dg.exp
+load_gcc_lib file-format.exp
+load_gcc_lib target-supports.exp
+load_gcc_lib target-supports-dg.exp
+load_gcc_lib scanasm.exp
+load_gcc_lib scandump.exp
+load_gcc_lib scanrtl.exp
+load_gcc_lib scantree.exp
+load_gcc_lib scanipa.exp
+load_gcc_lib prune.exp
+load_gcc_lib target-libpath.exp
+load_gcc_lib wrapper.exp
+load_gcc_lib gcc-defs.exp
+load_gcc_lib torture-options.exp
+load_gcc_lib timeout.exp
+load_gcc_lib timeout-dg.exp
+load_gcc_lib fortran-modules.exp
+load_gcc_lib gcc-dg.exp
+
+set dg-do-what-default run
+
+#
+# GCC_UNDER_TEST is the compiler under test.
+#
+
+set libvtv_compile_options ""
+
+#
+# libvtv_init
+#
+
+if [info exists TOOL_OPTIONS] {
+ set multilibs [get_multilibs $TOOL_OPTIONS]
+} else {
+ set multilibs [get_multilibs]
+}
+
+proc libvtv_init { args } {
+ global srcdir blddir objdir tool_root_dir
+ global libvtv_initialized
+ global tmpdir
+ global blddir
+ global gluefile wrap_flags
+ global ALWAYS_CFLAGS
+ global CFLAGS
+ global TOOL_EXECUTABLE TOOL_OPTIONS
+ global GCC_UNDER_TEST
+ global TESTING_IN_BUILD_TREE
+ global target_triplet
+ global always_ld_library_path
+
+ set blddir [lookfor_file [get_multilibs] libvtv]
+
+ # We set LC_ALL and LANG to C so that we get the same error
+ # messages as expected.
+ setenv LC_ALL C
+ setenv LANG C
+
+ if ![info exists GCC_UNDER_TEST] then {
+ if [info exists TOOL_EXECUTABLE] {
+ set GCC_UNDER_TEST $TOOL_EXECUTABLE
+ } else {
+ set GCC_UNDER_TEST "[find_gcc]"
+ }
+ }
+
+ if ![info exists tmpdir] {
+ set tmpdir "/tmp"
+ }
+
+ if [info exists gluefile] {
+ unset gluefile
+ }
+
+ if {![info exists CFLAGS]} {
+ set CFLAGS ""
+ }
+
+ # Locate libgcc.a so we don't need to account for different values of
+ # SHLIB_EXT on different platforms
+ set gccdir [lookfor_file $tool_root_dir gcc/libgcc.a]
+ if {$gccdir != ""} {
+ set gccdir [file dirname $gccdir]
+ }
+
+ # Compute what needs to be put into LD_LIBRARY_PATH
+ set always_ld_library_path ".:${blddir}/.libs"
+
+ # Compute what needs to be added to the existing LD_LIBRARY_PATH.
+ if {$gccdir != ""} {
+ # Add AIX pthread directory first.
+ if { [llength [glob -nocomplain ${gccdir}/pthread/libgcc_s*.a]] >= 1 } {
+ append always_ld_library_path ":${gccdir}/pthread"
+ }
+ append always_ld_library_path ":${gccdir}"
+ set compiler [lindex $GCC_UNDER_TEST 0]
+
+ if { [is_remote host] == 0 && [which $compiler] != 0 } {
+ foreach i "[exec $compiler --print-multi-lib]" {
+ set mldir ""
+ regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
+ set mldir [string trimright $mldir "\;@"]
+ if { "$mldir" == "." } {
+ continue
+ }
+ if { [llength [glob -nocomplain ${gccdir}/${mldir}/libgcc_s*.so.*]] >= 1 } {
+ append always_ld_library_path ":${gccdir}/${mldir}"
+ }
+ }
+ }
+ }
+
+ set ALWAYS_CFLAGS ""
+ if { $blddir != "" } {
+ lappend ALWAYS_CFLAGS "additional_flags=-B${blddir}/"
+ lappend ALWAYS_CFLAGS "additional_flags=-I${blddir}"
+ lappend ALWAYS_CFLAGS "ldflags=-L${blddir}/.libs"
+ }
+ lappend ALWAYS_CFLAGS "additional_flags=-I${srcdir}/.."
+
+ if [istarget *-*-darwin*] {
+ lappend ALWAYS_CFLAGS "additional_flags=-shared-libgcc"
+ }
+
+ if [info exists TOOL_OPTIONS] {
+ lappend ALWAYS_CFLAGS "additional_flags=$TOOL_OPTIONS"
+ }
+
+ # Make sure that lines are not wrapped. That can confuse the
+ # error-message parsing machinery.
+ lappend ALWAYS_CFLAGS "additional_flags=-fmessage-length=0"
+
+ # Turn on vtable verification
+ lappend ALWAYS_CFLAGS "-fvtable-verify=std"
+ # lappend ALWAYS_CFLAGS "ldflags=-lvtv"
+}
+
+#
+# libvtv_target_compile -- compile a source file
+#
+
+proc libvtv_target_compile { source dest type options } {
+ global blddir
+ global libvtv_compile_options
+ global gluefile wrap_flags
+ global ALWAYS_CFLAGS
+ global GCC_UNDER_TEST
+ global lang_test_file
+ global lang_library_path
+ global lang_link_flags
+
+ if { [info exists lang_test_file] } {
+ if { $blddir != "" } {
+ lappend options "ldflags=-L${blddir}/${lang_library_path}"
+ }
+ lappend options "ldflags=${lang_link_flags}"
+ }
+
+ if { [target_info needs_status_wrapper] != "" && [info exists gluefile] } {
+ lappend options "libs=${gluefile}"
+ lappend options "ldflags=${wrap_flags}"
+ }
+
+ lappend options "additional_flags=[libio_include_flags]"
+ lappend options "timeout=[timeout_value]"
+ lappend options "compiler=$GCC_UNDER_TEST"
+
+ set options [concat $libvtv_compile_options $options]
+
+ if [info exists ALWAYS_CFLAGS] {
+ set options [concat "$ALWAYS_CFLAGS" $options]
+ }
+
+ set options [dg-additional-files-options $options $source]
+
+ set result [target_compile $source $dest $type $options]
+
+ return $result
+}
+
+proc libvtv_option_help { } {
+ send_user " --additional_options,OPTIONS\t\tUse OPTIONS to compile the testcase files. OPTIONS should be comma-separated.\n"
+}
+
+proc libvtv_option_proc { option } {
+ if [regexp "^--additional_options," $option] {
+ global libvtv_compile_options
+ regsub "--additional_options," $option "" option
+ foreach x [split $option ","] {
+ lappend libvtv_compile_options "additional_flags=$x"
+ }
+ return 1
+ } else {
+ return 0
+ }
+}
diff --git a/libvtv/testsuite/libvtv.cc/bb_tests.cc b/libvtv/testsuite/libvtv.cc/bb_tests.cc
new file mode 100644
index 00000000000..2a2447d02c8
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/bb_tests.cc
@@ -0,0 +1,53 @@
+// { dg-do run }
+struct base
+{
+ int total;
+ virtual void add (int i) { total += i; }
+ virtual void sub (int i) { total -= i; }
+ virtual void init (void) { total = 73; }
+};
+
+struct derived : public base
+{
+ int total;
+ virtual void add (int i) { total += 10 * i; }
+ virtual void sub (int i) { total -= 2 * i; }
+ virtual void init (void) { total = 0; }
+};
+
+bool
+get_cond_value (int x)
+{
+ if ((x % 3) > 0)
+ return true;
+ else
+ return false;
+
+ return false;
+}
+
+int
+main (int argc, char **argv)
+{
+ base *a;
+ bool cond_value = get_cond_value (10);
+ int x;
+
+ if (cond_value)
+ a = new base ();
+ else
+ a = new derived ();
+
+ cond_value = get_cond_value (47);
+ x = 0;
+ if (!cond_value)
+ x = 17;
+
+ a->init ();
+
+ for ( ; x < 10; ++x)
+ {
+ a->add(50);
+ a->sub(25);
+ }
+}
diff --git a/libvtv/testsuite/libvtv.cc/const_vtable.cc b/libvtv/testsuite/libvtv.cc/const_vtable.cc
new file mode 100644
index 00000000000..3229f008308
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/const_vtable.cc
@@ -0,0 +1,83 @@
+// { dg-do run }
+extern "C" int printf(const char *,...);
+struct V1 {
+ int v;
+ virtual int foo();
+ V1();
+ ~V1();
+};
+struct V2 : virtual V1 {
+ int v2;
+ virtual int foo();
+ V2();
+ ~V2();
+};
+struct C : virtual V1, virtual V2 {
+ int c;
+ virtual int foo();
+ C();
+ ~C();
+};
+
+struct B {
+ int b; };
+struct D : B, C {
+ int d;
+ virtual int bar();
+ D();
+ ~D();
+};
+extern "C" int printf(const char *,...);
+main()
+{
+ try {
+ D *d = new D;
+ delete d;
+ } catch (int) {
+ printf("Int caught\n");
+ }
+}
+
+int V1::foo() {
+ printf("V1::foo called\n"); return 1; }
+V1::V1() : v(5) {
+ printf("V1 called\n"); }
+V1::~V1() {
+ printf("~V1 called\n"); }
+
+int V2::foo() {
+ printf("V2::foo called\n"); return 1; }
+V2::V2() : v2(6) {
+ printf("V2 called\n"); }
+V2::~V2() {
+ printf("~V2 called\n"); }
+
+int C::foo() {
+ printf("C::foo called %d\n", c); return 1; }
+C::C() : c(7) {
+ printf("C called\n");
+ V1 *vv = this; vv->foo();
+ C *cp = dynamic_cast<C *>(vv);
+ if (this == cp) {
+ printf("PASSED this == cp\n");
+ } else {
+ printf("FAILED this != cp\n");
+ }
+}
+C::~C() {
+ printf("~C called\n");
+ V1 *vv = this; vv->foo();
+ C *cp = dynamic_cast<C *>(vv);
+ if (this == cp) {
+ printf("PASSED this == cp\n");
+ } else {
+ printf("FAILED this != cp\n");
+ }
+}
+
+int D::bar() {
+ printf("D::bar called\n"); return 1; }
+D::D() : d(8) {
+ printf("D called\n"); throw 5; }
+D::~D() {
+ printf("~D called\n"); }
diff --git a/libvtv/testsuite/libvtv.cc/dataentry.cc b/libvtv/testsuite/libvtv.cc/dataentry.cc
new file mode 100644
index 00000000000..6246136e521
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/dataentry.cc
@@ -0,0 +1,39 @@
+// { dg-do run }
+
+template<int patch_dim, int patch_space_dim>
+class DataOutInterface
+{
+ public:
+ virtual ~DataOutInterface() {}
+};
+
+template <int dof_handler_dim, int patch_dim, int patch_space_dim=patch_dim>
+class DataOut_DoFData : public DataOutInterface<patch_dim,patch_space_dim>
+{
+ public:
+ virtual ~DataOut_DoFData() {}
+
+class DataEntryBase {
+ public:
+ virtual ~DataEntryBase () {}
+};
+
+template <typename T>
+class DataEntry : public DataEntryBase
+{
+ public:
+ virtual ~DataEntry() {}
+};
+};
+
+template <typename T> void Destroy(T * p) __attribute__((noinline));
+template <typename T> void Destroy(T * p)
+{
+ delete p;
+}
+
+int main()
+{
+ DataOut_DoFData<3,3>::DataEntryBase * p = new DataOut_DoFData<3,3>::DataEntry<int>();
+ Destroy(p);
+}
diff --git a/libvtv/testsuite/libvtv.cc/derived-lib.cpp b/libvtv/testsuite/libvtv.cc/derived-lib.cpp
new file mode 100644
index 00000000000..375dbe41bde
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/derived-lib.cpp
@@ -0,0 +1,18 @@
+#include "lib.h"
+
+struct Derived_Private : public Base
+{
+ virtual ~Derived_Private()
+ { printf("in Derived_Private destructor\n"); }
+};
+
+Base * GetPrivate()
+{
+ return new Derived_Private();
+}
+
+void Destroy(Base * pb)
+{
+ delete pb; // Virtual call #1
+}
+
diff --git a/libvtv/testsuite/libvtv.cc/derived-main.cpp b/libvtv/testsuite/libvtv.cc/derived-main.cpp
new file mode 100644
index 00000000000..0933ff69621
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/derived-main.cpp
@@ -0,0 +1,18 @@
+// { dg-do run }
+
+#include "lib.h"
+
+struct Derived: public Base
+{
+ virtual ~Derived()
+ { printf("In Derived destructor\n"); }
+};
+
+int main()
+{
+ Derived * d = new Derived;
+ Destroy(d);
+ Base * pp = GetPrivate();
+ delete pp; // Virtual call #2
+}
+
diff --git a/libvtv/testsuite/libvtv.cc/derived.list b/libvtv/testsuite/libvtv.cc/derived.list
new file mode 100644
index 00000000000..6ea3b9cf603
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/derived.list
@@ -0,0 +1 @@
+derived-main.cpp derived-lib.cpp
diff --git a/libvtv/testsuite/libvtv.cc/dup_name.cc b/libvtv/testsuite/libvtv.cc/dup_name.cc
new file mode 100644
index 00000000000..d9d02512630
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/dup_name.cc
@@ -0,0 +1,62 @@
+// { dg-do run }
+
+#include <assert.h>
+
+extern "C" int printf(const char *, ...);
+
+class Subscriptor
+{
+ public:
+
+ Subscriptor()
+ { counter = 1;}
+
+ virtual ~Subscriptor()
+ {
+ counter--;
+ assert(counter == 0);
+ }
+
+ private:
+ static int counter;
+};
+
+int Subscriptor::counter;
+
+template <typename number>
+class Polynomial : public Subscriptor
+{
+};
+
+class LagrangeEquidistant: public Polynomial<double>
+{
+};
+
+template <int value>
+class A
+{
+ public:
+ class Nested: public LagrangeEquidistant
+ {
+ };
+ A() { n = new Nested; }
+ ~A() { delete n; }
+ Subscriptor * n;
+};
+
+template<typename _Tp>
+inline void
+_MyDestroy(_Tp* __pointer)
+ { __pointer->~_Tp(); }
+
+int main()
+{
+ Subscriptor * s1 = new LagrangeEquidistant;
+ _MyDestroy(s1);
+ A<1> * a1 = new A<1>;
+ _MyDestroy(a1);
+ A<2> * a2 = new A<2>;
+ _MyDestroy(a2);
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/environment.cc b/libvtv/testsuite/libvtv.cc/environment.cc
new file mode 100644
index 00000000000..af1a8775298
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/environment.cc
@@ -0,0 +1,38 @@
+// { dg-do run }
+
+extern "C" int printf(const char *, ...);
+
+class Environment {
+ public:
+ virtual ~Environment();
+
+ // Static factory method that returns the implementation that provide the
+ // appropriate platform-specific instance.
+ static Environment* Create();
+
+ // Gets an environment variable's value and stores it in |result|.
+ // Returns false if the key is unset.
+ virtual bool GetVar(const char* variable_name, char* result) = 0;
+};
+
+class EnvironmentImpl : public Environment {
+ public:
+ virtual bool GetVar(const char* variable_name, char* result) {
+ return true;
+ }
+};
+
+Environment::~Environment() {}
+
+// static
+Environment* Environment::Create() {
+ return new EnvironmentImpl();
+}
+
+int main()
+{
+ char * null = 0;
+ Environment * env = Environment::Create();
+ env->GetVar(0, null);
+ printf("%p\n", env);
+}
diff --git a/libvtv/testsuite/libvtv.cc/event-defintions.cpp b/libvtv/testsuite/libvtv.cc/event-defintions.cpp
new file mode 100644
index 00000000000..ba9efe11a4d
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/event-defintions.cpp
@@ -0,0 +1,10 @@
+#include "event.h"
+
+Event::Event()
+{
+}
+
+Event::~Event()
+{
+
+}
diff --git a/libvtv/testsuite/libvtv.cc/event-main.cpp b/libvtv/testsuite/libvtv.cc/event-main.cpp
new file mode 100644
index 00000000000..95c4640313a
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/event-main.cpp
@@ -0,0 +1,15 @@
+// { dg-do run }
+
+#include "event-private.h"
+
+template<typename T> void derefIfNotNull(T* ptr)
+{
+ if (ptr != 0)
+ ptr->deref();
+}
+
+int main()
+{
+ Event * ev = new Event;
+ derefIfNotNull(ev);
+}
diff --git a/libvtv/testsuite/libvtv.cc/event-private.cpp b/libvtv/testsuite/libvtv.cc/event-private.cpp
new file mode 100644
index 00000000000..a27f4697a25
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/event-private.cpp
@@ -0,0 +1,10 @@
+#include "event-private.h"
+
+PrivateEvent::PrivateEvent()
+{
+}
+
+PrivateEvent::~PrivateEvent()
+{
+
+}
diff --git a/libvtv/testsuite/libvtv.cc/event-private.h b/libvtv/testsuite/libvtv.cc/event-private.h
new file mode 100644
index 00000000000..678ab5f68af
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/event-private.h
@@ -0,0 +1,7 @@
+#include "event.h"
+
+class PrivateEvent: public Event {
+ public:
+ PrivateEvent();
+ ~PrivateEvent ();
+};
diff --git a/libvtv/testsuite/libvtv.cc/event.h b/libvtv/testsuite/libvtv.cc/event.h
new file mode 100644
index 00000000000..61e1d7c9172
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/event.h
@@ -0,0 +1,29 @@
+class RefCountedBase {
+protected:
+ bool derefBase()
+ {
+ return true;
+ }
+};
+
+template<typename T> class RefCounted : public RefCountedBase {
+public:
+ void deref()
+ {
+ if (derefBase())
+ delete static_cast<T*>(this);
+ }
+
+protected:
+ // RefCounted() { }
+ ~RefCounted()
+ {
+ }
+};
+
+
+class Event : public RefCounted<Event> {
+ public:
+ Event();
+ virtual ~Event();
+};
diff --git a/libvtv/testsuite/libvtv.cc/event.list b/libvtv/testsuite/libvtv.cc/event.list
new file mode 100644
index 00000000000..77606f8c122
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/event.list
@@ -0,0 +1 @@
+event-main.cpp event-definitions.cpp event-private.cpp \ No newline at end of file
diff --git a/libvtv/testsuite/libvtv.cc/mul_inh.cc b/libvtv/testsuite/libvtv.cc/mul_inh.cc
new file mode 100644
index 00000000000..b32b710c835
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/mul_inh.cc
@@ -0,0 +1,27 @@
+// { dg-do run }
+
+extern "C" int printf(const char *, ...);
+
+struct A {
+ virtual ~A() {}
+};
+
+struct B {
+ virtual ~B() {}
+};
+
+struct C: public A {
+ virtual ~C() {}
+};
+
+struct D: public C, B {
+ virtual ~D() {}
+};
+
+D d;
+
+int main()
+{
+ printf ("%p\n", &d);
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/nested_vcall_test.cc b/libvtv/testsuite/libvtv.cc/nested_vcall_test.cc
new file mode 100644
index 00000000000..9d1a9c692da
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/nested_vcall_test.cc
@@ -0,0 +1,77 @@
+// { dg-do run }
+
+class EtherCtrl {
+ protected:
+ int ssap;
+
+ public:
+ EtherCtrl(void);
+ ~EtherCtrl();
+ virtual int getSsap(void) const;
+ virtual void setSsap(int);
+};
+
+class EtherFrameWithLLC {
+ protected:
+ int ssap;
+
+ public:
+ EtherFrameWithLLC(const char *, int);
+ ~EtherFrameWithLLC();
+ virtual int getSsap(void) const;
+ virtual void setSsap(int);
+};
+
+
+EtherCtrl::EtherCtrl()
+{
+ this->ssap = 0;
+}
+
+EtherCtrl::~EtherCtrl()
+{
+}
+
+int EtherCtrl::getSsap() const
+{
+ return ssap;
+}
+
+void EtherCtrl::setSsap(int ssap)
+{
+ this->ssap = ssap;
+}
+
+EtherFrameWithLLC::EtherFrameWithLLC(const char *name, int kind)
+{
+ this->ssap = 0;
+}
+
+EtherFrameWithLLC::~EtherFrameWithLLC()
+{
+}
+
+int EtherFrameWithLLC::getSsap() const
+{
+ return ssap;
+}
+
+void EtherFrameWithLLC::setSsap(int ssap)
+{
+ this->ssap = ssap;
+}
+
+
+int
+main (int argc, char **argv)
+{
+ EtherCtrl *etherctrl = new EtherCtrl ();
+ EtherFrameWithLLC *frame = new EtherFrameWithLLC ("test", 10);
+ int my_value;
+
+ etherctrl->setSsap(43);
+ frame->setSsap(etherctrl->getSsap());
+ my_value = frame->getSsap();
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.cpp b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.cpp
new file mode 100644
index 00000000000..13d7fdc6e4f
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.cpp
@@ -0,0 +1,16 @@
+#include "parts-test-extra-parts-views.h"
+
+ExtraPartsViews::ExtraPartsViews ()
+ : ExtraParts () {
+}
+
+ExtraPartsViews::~ExtraPartsViews () {}
+
+void
+ExtraPartsViews::ToolkitInitialized ()
+{
+ /* Do something */
+ int sum = 0;
+ for (int i = 0; i < 10; ++i)
+ sum += i;
+}
diff --git a/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.h b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.h
new file mode 100644
index 00000000000..0784c0ecdaa
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts-views.h
@@ -0,0 +1,14 @@
+#ifndef _EXTRA_PARTS_VIEWS_H_
+#define _EXTRA_PARTS_VIEWS_H_
+
+#include "parts-test-extra-parts.h"
+
+class ExtraPartsViews : public ExtraParts {
+ public:
+ ExtraPartsViews ();
+ virtual ~ExtraPartsViews ();
+
+ virtual void ToolkitInitialized ();
+};
+
+#endif /* _EXTRA_PARTS_VIEWS_H_ */
diff --git a/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.cpp b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.cpp
new file mode 100644
index 00000000000..dbd3dbfd8f5
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.cpp
@@ -0,0 +1,15 @@
+#include "parts-test-extra-parts.h"
+
+ExtraParts::ExtraParts () {}
+
+ExtraParts::~ExtraParts () {}
+
+void
+ExtraParts::ToolkitInitialized ()
+{
+}
+
+void
+ExtraParts::PreEarlyInitialization ()
+{
+}
diff --git a/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.h b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.h
new file mode 100644
index 00000000000..4ed2a4ce1a0
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/parts-test-extra-parts.h
@@ -0,0 +1,13 @@
+#ifndef _EXTRA_PARTS_H_
+#define _EXTRA_PARTS_H_
+
+class ExtraParts {
+ public:
+ ExtraParts ();
+ virtual ~ExtraParts ();
+
+ virtual void PreEarlyInitialization ();
+ virtual void ToolkitInitialized ();
+};
+
+#endif /* _EXTRA_PARTS_H_ */
diff --git a/libvtv/testsuite/libvtv.cc/parts-test-main.cpp b/libvtv/testsuite/libvtv.cc/parts-test-main.cpp
new file mode 100644
index 00000000000..a0cc721abf5
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/parts-test-main.cpp
@@ -0,0 +1,39 @@
+// { dg-do run }
+
+#include "parts-test-main.h"
+#include "parts-test-extra-parts-views.h"
+
+MainParts::MainParts () {}
+
+MainParts::~MainParts ()
+{
+ for (int i = static_cast<int>(main_extra_parts_.size()) - 1; i >= 0; --i)
+ delete main_extra_parts_[i];
+ main_extra_parts_.clear();
+}
+
+void
+MainParts::AddParts (ExtraParts *parts)
+{
+ main_extra_parts_.push_back (parts);
+}
+
+
+void
+MainParts::PreEarlyInitialization (void)
+{
+ for (int i = 0; i < main_extra_parts_.size(); ++i)
+ main_extra_parts_[i]->PreEarlyInitialization ();
+}
+
+
+int
+main (int argc, char **argv)
+{
+ MainParts *main_parts = new MainParts ();
+
+ main_parts->AddParts (new ExtraPartsViews ());
+ main_parts->PreEarlyInitialization ();
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/parts-test-main.h b/libvtv/testsuite/libvtv.cc/parts-test-main.h
new file mode 100644
index 00000000000..fb631dec340
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/parts-test-main.h
@@ -0,0 +1,15 @@
+#include <vector>
+
+class ExtraParts;
+
+class MainParts {
+ public:
+ MainParts ();
+ virtual ~MainParts ();
+ virtual void AddParts (ExtraParts *parts);
+
+ virtual void PreEarlyInitialization ();
+
+ protected:
+ std::vector<ExtraParts *> main_extra_parts_;
+};
diff --git a/libvtv/testsuite/libvtv.cc/parts-test.list b/libvtv/testsuite/libvtv.cc/parts-test.list
new file mode 100644
index 00000000000..11a959a62d1
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/parts-test.list
@@ -0,0 +1 @@
+parts-test-main.cpp parts-test-extra-parts.cpp parts-test-extra-parts-views.cpp
diff --git a/libvtv/testsuite/libvtv.cc/povray-derived.cc b/libvtv/testsuite/libvtv.cc/povray-derived.cc
new file mode 100644
index 00000000000..9005826dff4
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/povray-derived.cc
@@ -0,0 +1,74 @@
+// { dg-do run }
+
+// Small test case from povray, see if it reproduces.
+
+#include <stdio.h>
+
+class POVMS_MessageReceiver
+{
+
+private:
+ int x;
+ class Handler
+ {
+ public:
+ virtual void print() = 0;
+ };
+protected:
+ template<class T> class MemberHandler : public Handler
+ {
+ public:
+ MemberHandler(T *xx)
+ {
+ x = xx;
+ }
+
+ ~MemberHandler() {}
+
+ void print()
+ {
+ printf("In print\n");
+ }
+ private:
+ T *x;
+ };
+
+private:
+ struct HandlerNode
+ {
+ Handler *handler;
+ };
+
+ HandlerNode *receiver;
+public:
+ POVMS_MessageReceiver(int xx) : x(xx) {}
+ ~POVMS_MessageReceiver() {}
+
+ void foo(int *xx);
+ void try_call();
+};
+
+void POVMS_MessageReceiver::foo(int *xx)
+{
+ receiver = new HandlerNode;
+
+ receiver->handler = new MemberHandler<int>(xx);
+}
+
+void POVMS_MessageReceiver::try_call()
+{
+ receiver->handler->print();
+}
+
+
+int main()
+{
+ int loc = 34;
+ POVMS_MessageReceiver a_test(100);
+
+ a_test.foo(&loc);
+ a_test.try_call();
+}
+
+
+
diff --git a/libvtv/testsuite/libvtv.cc/register_set_pair.cc b/libvtv/testsuite/libvtv.cc/register_set_pair.cc
new file mode 100644
index 00000000000..b7f08331d68
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/register_set_pair.cc
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "vtv_utils.h"
+#include "vtv_rts.h"
+
+/* This configuration will test mostly inserting of elements that are already inserted since
+ the number of repeats is 200 */
+
+#define NUM_MAPS 4000
+#define ELEMENTS_PER_MAP 100
+#define NUM_REPEATS 200
+
+#define KEY_TYPE_FIXED_SIZE 8
+void *key_buffer = malloc (17);
+typedef char * name_string;
+name_string fake_names[NUM_MAPS];
+
+/* This variable has to be put in rel.ro */
+void * maps[NUM_MAPS] VTV_PROTECTED_VAR;
+
+struct fake_vt {
+ void * fake_vfp [4];
+};
+void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP];
+
+void
+generate_names (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_MAPS; ++i)
+ {
+ fake_names[i] = (char *) malloc (9 * sizeof (char));
+ snprintf (fake_names[i], 9, "name%d", i);
+ }
+}
+
+static uint32_t
+vtv_string_hash(const char *in)
+{
+ const char *s = in;
+ uint32_t h = 0;
+
+ for ( ; *s; ++s)
+ h = 5 * h + *s;
+ return h;
+}
+
+int main()
+{
+ __VLTChangePermission(__VLTP_READ_WRITE);
+
+ generate_names ();
+
+ for (int k = 0; k < NUM_REPEATS; k++)
+ {
+ int curr_fake_vt = 0;
+ for (int i = 0; i < NUM_MAPS; i++)
+ {
+ uint32_t *value_ptr = (uint32_t *) key_buffer;
+ uint32_t len1 = strlen (fake_names[i]);
+ uint32_t hash_value = vtv_string_hash (fake_names[i]);
+ void *temp_array[ELEMENTS_PER_MAP];
+
+ *value_ptr = len1;
+ value_ptr++;
+ *value_ptr = hash_value;
+
+ memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i],
+ len1);
+
+
+#ifdef VTV_DEBUG
+ __VLTRegisterPairDebug (&maps[i], (char *) key_buffer, 128,
+ &fake_vts[curr_fake_vt], "", "");
+#else
+ __VLTRegisterPair (&maps[i], (char *) key_buffer, 128,
+ &fake_vts[curr_fake_vt]);
+#endif
+ for (int j = 0; j < ELEMENTS_PER_MAP; j++)
+ {
+ temp_array[j] = &fake_vts[curr_fake_vt];
+ curr_fake_vt++;
+ }
+#ifdef VTV_DEBUG
+ __VLTRegisterSetDebug (&maps[i], (char *) key_buffer, 128, 100,
+ (void **) &temp_array);
+#else
+ __VLTRegisterSet (&maps[i], (char *) key_buffer, 128, 100,
+ (void **) &temp_array);
+#endif
+ }
+ }
+
+ __VLTChangePermission(__VLTP_READ_ONLY);
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/register_set_pair_inserts.cc b/libvtv/testsuite/libvtv.cc/register_set_pair_inserts.cc
new file mode 100644
index 00000000000..297e8756797
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/register_set_pair_inserts.cc
@@ -0,0 +1,106 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "vtv_utils.h"
+#include "vtv_rts.h"
+
+/* This configuration will test mostly inserting of new elements since
+ the number of repeats is 1. It should also do a lot of rehashing */
+
+/* This test case may fail depending on the system configuration.
+ Check the value of /proc/sys/vm/max_map_count and fix by doing
+ Ex: sudo sh -c "echo 131060 > /proc/sys/vm/max_map_count" */
+
+#define NUM_MAPS 40000
+#define ELEMENTS_PER_MAP 100
+#define NUM_REPEATS 1
+
+#define KEY_TYPE_FIXED_SIZE 8
+void *key_buffer = malloc (17);
+typedef char * name_string;
+name_string fake_names[NUM_MAPS];
+
+/* This variable has to be put in rel.ro */
+void * maps[NUM_MAPS] VTV_PROTECTED_VAR;
+
+struct fake_vt {
+ void * fake_vfp [4];
+};
+void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP];
+
+
+void
+generate_names (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_MAPS; ++i)
+ {
+ fake_names[i] = (char *) malloc (9 * sizeof (char));
+ snprintf (fake_names[i], 9, "name%d", i);
+ }
+}
+
+static uint32_t
+vtv_string_hash(const char *in)
+{
+ const char *s = in;
+ uint32_t h = 0;
+
+ for ( ; *s; ++s)
+ h = 5 * h + *s;
+ return h;
+}
+
+int main()
+{
+ __VLTChangePermission(__VLTP_READ_WRITE);
+
+ generate_names();
+
+ for (int k = 0; k < NUM_REPEATS; k++)
+ {
+ int curr_fake_vt = 0;
+ for (int i = 0; i < NUM_MAPS; i++)
+ {
+ uint32_t *value_ptr = (uint32_t *) key_buffer;
+ uint32_t len1 = strlen (fake_names[i]);
+ uint32_t hash_value = vtv_string_hash (fake_names[i]);
+ void *temp_array[ELEMENTS_PER_MAP];
+
+ *value_ptr = len1;
+ value_ptr++;
+ *value_ptr = hash_value;
+
+ memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i],
+ len1);
+
+
+#ifdef VTV_DEBUG
+ __VLTRegisterPairDebug (&maps[i], (char *) key_buffer, 128,
+ &fake_vts[curr_fake_vt], "", "");
+#else
+ __VLTRegisterPair (&maps[i], (char *) key_buffer, 128,
+ &fake_vts[curr_fake_vt]);
+#endif
+ for (int j = 0; j < ELEMENTS_PER_MAP; j++)
+ {
+ temp_array[j] = &fake_vts[curr_fake_vt];
+ curr_fake_vt++;
+ }
+#ifdef VTV_DEBUG
+ __VLTRegisterSetDebug (&maps[i], (char *) key_buffer, 128, 100,
+ (void **) &temp_array);
+#else
+ __VLTRegisterSet (&maps[i], (char *) key_buffer, 128, 100,
+ (void **) &temp_array);
+#endif
+ }
+ }
+
+ __VLTChangePermission(__VLTP_READ_ONLY);
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/template-list-iostream.cc b/libvtv/testsuite/libvtv.cc/template-list-iostream.cc
new file mode 100644
index 00000000000..06ec3b01e10
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/template-list-iostream.cc
@@ -0,0 +1,120 @@
+// { dg-do run }
+
+#include <assert.h>
+#include <iostream>
+#include <fstream>
+
+using std::ofstream;
+using std::ifstream;
+using std::ios;
+
+extern "C" int printf(const char *, ...);
+
+class Subscriptor
+{
+ public:
+
+ Subscriptor() : counter(1) {}
+
+ virtual ~Subscriptor()
+ {
+ counter--;
+ assert(counter == 0);
+ }
+
+ private:
+ mutable int counter;
+};
+
+template <int dim> struct Function
+{
+ Function(int i): value(dim + i) {}
+ int value;
+};
+
+template <int dim> struct Triangulation
+{
+
+};
+
+template <int dim> struct Exercise_2_3
+{
+ enum { DIM = dim };
+};
+
+ template <int dim>
+ struct SetUpBase : public Subscriptor
+ {
+ virtual
+ const Function<dim> get_boundary_values () const = 0;
+
+ virtual
+ const Function<dim> get_right_hand_side () const = 0;
+
+ // virtual
+ // void create_coarse_grid (Triangulation<dim> &coarse_grid) const = 0;
+ };
+
+ template <class Traits, int dim>
+ struct SetUp : public SetUpBase<dim>
+ {
+ SetUp () {};
+
+ virtual
+ const Function<dim> get_boundary_values () const
+ { return Function<dim>(Traits::DIM); }
+
+ virtual
+ const Function<dim> get_right_hand_side () const
+ { return Function<dim>(Traits::DIM); }
+
+ // virtual
+ // void create_coarse_grid (Triangulation<dim> &coarse_grid) const;
+
+ // static const typename Traits::BoundaryValues boundary_values;
+ // static const typename Traits::RightHandSide right_hand_side;
+ };
+
+
+void myread(std::istream * in)
+{
+ char input_str[50] = "\0";
+ if (in->good())
+ (*in) >> input_str;
+ std::cout << input_str << std::endl;
+ delete in;
+}
+
+
+
+int main()
+{
+ /*
+
+ SetUp<Exercise_2_3<1000>, 2> s1a;
+ SetUp<Exercise_2_3<2000>, 1> s2;
+ SetUp<Exercise_2_3<2000>, 2> s2a;
+ return s1->get_boundary_values().value + s1a.get_boundary_values().value +
+ s2.get_boundary_values().value + s2a.get_boundary_values().value +
+ s1->get_right_hand_side().value + s1a.get_right_hand_side().value +
+ s2.get_right_hand_side().value + s2a.get_right_hand_side().value;
+ */
+
+ SetUp<Exercise_2_3<1000>, 1> * s1 = new SetUp<Exercise_2_3<1000>, 1>();
+
+ printf("%d\n", s1->get_boundary_values().value);
+
+ ifstream * infile = new ifstream("./template-list-iostream.cc");
+
+ myread(infile);
+
+ ofstream * outfile = new ofstream("/tmp/xxx.txt");
+
+ if (outfile->good())
+ (*outfile) << "hello there" << std::endl;
+ std::cerr << "Reached End" << std::endl;
+
+ delete outfile;
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/template-list.cc b/libvtv/testsuite/libvtv.cc/template-list.cc
new file mode 100644
index 00000000000..aeb2db9e526
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/template-list.cc
@@ -0,0 +1,94 @@
+// { dg-do run }
+
+#include <assert.h>
+
+extern "C" int printf(const char *, ...);
+
+class Subscriptor
+{
+ public:
+
+ Subscriptor() : counter(1) {}
+
+ virtual ~Subscriptor()
+ {
+ counter--;
+ assert(counter == 0);
+ }
+
+ private:
+ mutable int counter;
+};
+
+template <int dim> struct Function
+{
+ Function(int i): value(dim + i) {}
+ int value;
+};
+
+template <int dim> struct Triangulation
+{
+
+};
+
+template <int dim> struct Exercise_2_3
+{
+ enum { DIM = dim };
+};
+
+ template <int dim>
+ struct SetUpBase : public Subscriptor
+ {
+ virtual
+ const Function<dim> get_boundary_values () const = 0;
+
+ virtual
+ const Function<dim> get_right_hand_side () const = 0;
+
+ // virtual
+ // void create_coarse_grid (Triangulation<dim> &coarse_grid) const = 0;
+ };
+
+ template <class Traits, int dim>
+ struct SetUp : public SetUpBase<dim>
+ {
+ SetUp () {};
+
+ virtual
+ const Function<dim> get_boundary_values () const
+ { return Function<dim>(Traits::DIM); }
+
+ virtual
+ const Function<dim> get_right_hand_side () const
+ { return Function<dim>(Traits::DIM); }
+
+ // virtual
+ // void create_coarse_grid (Triangulation<dim> &coarse_grid) const;
+
+ // static const typename Traits::BoundaryValues boundary_values;
+ // static const typename Traits::RightHandSide right_hand_side;
+ };
+
+
+int main()
+{
+ /*
+
+ SetUp<Exercise_2_3<1000>, 2> s1a;
+ SetUp<Exercise_2_3<2000>, 1> s2;
+ SetUp<Exercise_2_3<2000>, 2> s2a;
+ return s1->get_boundary_values().value + s1a.get_boundary_values().value +
+ s2.get_boundary_values().value + s2a.get_boundary_values().value +
+ s1->get_right_hand_side().value + s1a.get_right_hand_side().value +
+ s2.get_right_hand_side().value + s2a.get_right_hand_side().value;
+ */
+#ifndef NFAIL
+ SetUp<Exercise_2_3<1000>, 1> * s1 = new SetUp<Exercise_2_3<1000>, 1>();
+ printf("%d\n", s1->get_boundary_values().value);
+ return 0;
+#else
+ SetUp<Exercise_2_3<1000>, 1> s1;
+ printf("%d\n", s1.get_boundary_values().value);
+ return 0;
+#endif
+}
diff --git a/libvtv/testsuite/libvtv.cc/template-list2.cc b/libvtv/testsuite/libvtv.cc/template-list2.cc
new file mode 100644
index 00000000000..3df8d372418
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/template-list2.cc
@@ -0,0 +1,46 @@
+// { dg-do run }
+
+#include <assert.h>
+
+extern "C" int printf(const char *, ...);
+
+class Subscriptor
+{
+ public:
+
+ Subscriptor()
+ { counter = 1;}
+
+ virtual ~Subscriptor()
+ {
+ counter--;
+ assert(counter == 0);
+ }
+
+ private:
+ static int counter;
+};
+
+int Subscriptor::counter;
+
+template <typename number>
+class Polynomial : public Subscriptor
+{
+};
+
+class LagrangeEquidistant: public Polynomial<double>
+{
+};
+
+template<typename _Tp>
+inline void
+_MyDestroy(_Tp* __pointer)
+ { __pointer->~_Tp(); }
+
+int main()
+{
+ LagrangeEquidistant * s1 = new LagrangeEquidistant;
+ _MyDestroy(s1);
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/test1.cc b/libvtv/testsuite/libvtv.cc/test1.cc
new file mode 100644
index 00000000000..9005826dff4
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/test1.cc
@@ -0,0 +1,74 @@
+// { dg-do run }
+
+// Small test case from povray, see if it reproduces.
+
+#include <stdio.h>
+
+class POVMS_MessageReceiver
+{
+
+private:
+ int x;
+ class Handler
+ {
+ public:
+ virtual void print() = 0;
+ };
+protected:
+ template<class T> class MemberHandler : public Handler
+ {
+ public:
+ MemberHandler(T *xx)
+ {
+ x = xx;
+ }
+
+ ~MemberHandler() {}
+
+ void print()
+ {
+ printf("In print\n");
+ }
+ private:
+ T *x;
+ };
+
+private:
+ struct HandlerNode
+ {
+ Handler *handler;
+ };
+
+ HandlerNode *receiver;
+public:
+ POVMS_MessageReceiver(int xx) : x(xx) {}
+ ~POVMS_MessageReceiver() {}
+
+ void foo(int *xx);
+ void try_call();
+};
+
+void POVMS_MessageReceiver::foo(int *xx)
+{
+ receiver = new HandlerNode;
+
+ receiver->handler = new MemberHandler<int>(xx);
+}
+
+void POVMS_MessageReceiver::try_call()
+{
+ receiver->handler->print();
+}
+
+
+int main()
+{
+ int loc = 34;
+ POVMS_MessageReceiver a_test(100);
+
+ a_test.foo(&loc);
+ a_test.try_call();
+}
+
+
+
diff --git a/libvtv/testsuite/libvtv.cc/thunk.cc b/libvtv/testsuite/libvtv.cc/thunk.cc
new file mode 100644
index 00000000000..bec1057f564
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/thunk.cc
@@ -0,0 +1,37 @@
+// { dg-do run }
+
+#include <assert.h>
+struct A {
+ A():value(123) {}
+ int value;
+ virtual int access() { return this->value; }
+};
+struct B {
+ B():value(456) {}
+ int value;
+ virtual int access() { return this->value; }
+};
+struct C : public A, public B {
+ C():better_value(789) {}
+ int better_value;
+ virtual int access() { return this->better_value; }
+};
+struct D: public C {
+ D():other_value(987) {}
+ int other_value;
+ virtual int access() { return this->other_value; }
+};
+
+int use(B *b)
+{
+ return b->access();
+}
+
+int main()
+{
+ C c;
+ assert(use(&c) == 789);
+ D d;
+ assert(use(&d) == 987);
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc b/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc
new file mode 100644
index 00000000000..51f974ee4e7
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/thunk_vtable_map_attack.cc
@@ -0,0 +1,113 @@
+// { dg-do run }
+
+#include <assert.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <stdio.h>
+
+#include <iostream>
+#include <fstream>
+
+using std::ofstream;
+using std::ifstream;
+using std::ios;
+
+struct A {
+ A():value(123) {}
+ int value;
+ virtual int access() { return this->value; }
+};
+struct B {
+ B():value(456) {}
+ int value;
+ virtual int access() { return this->value; }
+};
+struct C : public A, public B {
+ C():better_value(789) {}
+ int better_value;
+ virtual int access() { return this->better_value; }
+};
+struct D: public C {
+ D():other_value(987) {}
+ int other_value;
+ virtual int access() { return this->other_value; }
+};
+
+volatile static int signal_count = 0;
+
+sigjmp_buf before_segv;
+
+static void
+handler(int sig, siginfo_t *si, void *unused)
+{
+ /*
+ printf("Got SIGSEGV at address: 0x%lx\n",
+ (long) si->si_addr);
+ */
+
+ signal_count++;
+ /* You are not supposed to longjmp out of a signal handler but it seems
+ to work for this test case and it simplifies it */
+ siglongjmp(before_segv, 1);
+ /* exit(1); */
+}
+
+/* Access one of the vtable_map variables generated by this .o */
+extern void * _ZN4_VTVI1BE12__vtable_mapE;
+
+/* Access one of the vtable_map variables generated by libstdc++ */
+extern void * _ZN4_VTVISt8ios_baseE12__vtable_mapE;
+
+int use(B *b)
+{
+ int ret;
+
+ ret = sigsetjmp(before_segv, 1);
+ if (ret == 0)
+ {
+ /* This should generate a segmentation violation. ie: at this point it should
+ be protected */
+ _ZN4_VTVI1BE12__vtable_mapE = 0;
+ }
+ assert(ret == 1 && signal_count == 1);
+
+ ret = sigsetjmp(before_segv, 1);
+ if (ret == 0)
+ {
+ /* Try to modify one of the vtable_map variables in the stdc++ library.
+ This should generate a segmentation violation. ie: at this point it
+ should be protected */
+ _ZN4_VTVISt8ios_baseE12__vtable_mapE = 0;
+ }
+ assert(ret == 1 && signal_count == 2);
+
+ return b->access();
+}
+
+void myread(std::istream * in)
+{
+ char input_str[50] = "\0";
+ if (in->good())
+ (*in) >> input_str;
+ std::cout << input_str << std::endl;
+ delete in;
+}
+
+int main()
+{
+ ifstream * infile = new ifstream("./thunk_vtable_map_attack.cpp");
+ myread(infile);
+
+ /* Set up handler for SIGSEGV. */
+ struct sigaction sa;
+ sa.sa_flags = SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_sigaction = handler;
+ if (sigaction(SIGSEGV, &sa, NULL) == -1)
+ assert(0);
+
+ C c;
+ assert(use(&c) == 789);
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/v8-test-2.cc b/libvtv/testsuite/libvtv.cc/v8-test-2.cc
new file mode 100644
index 00000000000..6bfda56e8c6
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/v8-test-2.cc
@@ -0,0 +1,97 @@
+// { dg-do run }
+
+#include <stdlib.h>
+#include <string>
+
+class Literal;
+class CallRuntime;
+
+class AstNode {
+public:
+
+ enum Type {
+ kLiteral, kCallRuntime,
+ kInvalid = -1
+ };
+
+ AstNode() { }
+
+ virtual ~AstNode() { }
+
+ virtual Type node_type() const = 0;
+
+ bool
+ IsLiteral() { return node_type() == AstNode::kLiteral; }
+
+ Literal *
+ AsLiteral() { return IsLiteral() ? reinterpret_cast<Literal*>(this)
+ : NULL; }
+
+ bool
+ IsCallRuntime() { return node_type() == AstNode::kCallRuntime; }
+
+ CallRuntime *
+ AsCallRuntime() { return IsCallRuntime() ? reinterpret_cast<CallRuntime*>(this)
+ : NULL; }
+
+};
+
+class Expression: public AstNode {
+public:
+private:
+ int id_;
+};
+
+class Literal: public Expression {
+public:
+
+ virtual AstNode::Type node_type() const { return AstNode::kLiteral; }
+
+ private:
+ std::string ToString();
+
+};
+
+class CallRuntime: public Expression {
+public:
+
+ virtual AstNode::Type node_type() const { return AstNode::kCallRuntime; }
+
+ private:
+ std::string name_;
+};
+
+Expression *
+ExpressionCheck (bool *ok)
+{
+ if (*ok == true)
+ return new CallRuntime();
+ else
+ return new Literal ();
+
+ return NULL;
+}
+
+Expression *
+GetExpression (bool *ok)
+{
+ Expression *expression = ExpressionCheck (ok);
+ Expression *return_expr = NULL;
+
+ if (expression != NULL && expression->AsLiteral() != NULL)
+ return_expr = new Literal();
+ else if (expression != NULL && expression->AsCallRuntime() != NULL)
+ return_expr = expression;
+
+ return return_expr;
+}
+
+int
+main (int argc, char **argv)
+{
+ bool a_bool = true;
+
+ AstNode *node = GetExpression (&a_bool);
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/virtfunc-test.cc b/libvtv/testsuite/libvtv.cc/virtfunc-test.cc
new file mode 100644
index 00000000000..3ad12b896c1
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/virtfunc-test.cc
@@ -0,0 +1,222 @@
+// { dg-do run }
+
+/* This test script is part of GDB, the GNU debugger.
+
+ Copyright 1993, 1994, 1997, 1998, 1999, 2003, 2004,
+ Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Pls try the following program on virtual functions and try to do print on
+// most of the code in main(). Almost none of them works !
+
+//
+// The inheritance structure is:
+//
+// V : VA VB
+// A : (V)
+// B : A
+// D : AD (V)
+// C : (V)
+// E : B (V) D C
+//
+
+class VA
+{
+public:
+ int va;
+};
+
+class VB
+{
+public:
+ int vb;
+ int fvb();
+ virtual int vvb();
+};
+
+class V : public VA, public VB
+{
+public:
+ int f();
+ virtual int vv();
+ int w;
+};
+
+class A : virtual public V
+{
+public:
+ virtual int f();
+private:
+ int a;
+};
+
+class B : public A
+{
+public:
+ int f();
+private:
+ int b;
+};
+
+class C : public virtual V
+{
+public:
+ int c;
+};
+
+class AD
+{
+public:
+ virtual int vg() = 0;
+};
+
+class D : public AD, virtual public V
+{
+public:
+ static void s();
+ virtual int vg();
+ virtual int vd();
+ int fd();
+ int d;
+};
+
+class E : public B, virtual public V, public D, public C
+{
+public:
+ int f();
+ int vg();
+ int vv();
+ int e;
+};
+
+D dd;
+D* ppd = &dd;
+AD* pAd = &dd;
+
+A a;
+B b;
+C c;
+D d;
+E e;
+V v;
+VB vb;
+
+
+A* pAa = &a;
+A* pAe = &e;
+
+B* pBe = &e;
+
+D* pDd = &d;
+D* pDe = &e;
+
+V* pVa = &a;
+V* pVv = &v;
+V* pVe = &e;
+V* pVd = &d;
+
+AD* pADe = &e;
+
+E* pEe = &e;
+
+VB* pVB = &vb;
+
+void init()
+{
+ a.vb = 1;
+ b.vb = 2;
+ c.vb = 3;
+ d.vb = 4;
+ e.vb = 5;
+ v.vb = 6;
+ vb.vb = 7;
+
+ d.d = 1;
+ e.d = 2;
+}
+
+extern "C" int printf(const char *, ...);
+
+int all_count = 0;
+int failed_count = 0;
+
+#define TEST(EXPR, EXPECTED) \
+ ret = EXPR; \
+ if (ret != EXPECTED) {\
+ printf("Failed %s is %d, should be %d!\n", #EXPR, ret, EXPECTED); \
+ failed_count++; } \
+ all_count++;
+
+int ret;
+
+void test_calls()
+{
+ TEST(pAe->f(), 20);
+ TEST(pAa->f(), 1);
+
+ TEST(pDe->vg(), 202);
+ TEST(pADe->vg(), 202);
+ TEST(pDd->vg(), 101);
+
+ TEST(pEe->vvb(), 411);
+
+ TEST(pVB->vvb(), 407);
+
+ TEST(pBe->vvb(), 411);
+ TEST(pDe->vvb(), 411);
+
+ TEST(pEe->vd(), 282);
+ TEST(pEe->fvb(), 311);
+
+ TEST(pEe->D::vg(), 102);
+ printf("Did %d tests, of which %d failed.\n", all_count, failed_count);
+}
+#ifdef usestubs
+extern "C" {
+ void set_debug_traps();
+ void breakpoint();
+};
+#endif
+
+int main()
+{
+#ifdef usestubs
+ set_debug_traps();
+ breakpoint();
+#endif
+ init();
+
+ e.w = 7;
+ e.vb = 11;
+
+ test_calls();
+ return 0;
+
+}
+
+int A::f() {return 1;}
+int B::f() {return 2;}
+void D::s() {}
+int E::f() {return 20;}
+int D::vg() {return 100+d;}
+int E::vg() {return 200+d;}
+int V::f() {return 600+w;}
+int V::vv() {return 400+w;}
+int E::vv() {return 450+w;}
+int D::fd() {return 250+d;}
+int D::vd() {return 280+d;}
+int VB::fvb() {return 300+vb;}
+int VB::vvb() {return 400+vb;}
diff --git a/libvtv/testsuite/libvtv.cc/virtual_inheritance.cc b/libvtv/testsuite/libvtv.cc/virtual_inheritance.cc
new file mode 100644
index 00000000000..1c49c966453
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/virtual_inheritance.cc
@@ -0,0 +1,48 @@
+// { dg-do run }
+
+#include <assert.h>
+struct V {
+ V(): virtual_value(-123) {}
+ int virtual_value;
+ virtual int access_vv() { return virtual_value; }
+};
+
+struct A: virtual public V {
+ A():value(123) {}
+ int value;
+ virtual int access() { return value; }
+};
+struct B: virtual public V {
+ B():value(456) {}
+ int value;
+ virtual int access() { return value; }
+};
+struct C : public A, public B {
+ C():better_value(789) {}
+ int better_value;
+ virtual int access() { return better_value; }
+};
+struct D: public A, public B {
+ D():better_virtual_value(-345) {}
+ int better_virtual_value;
+ virtual int access_vv() { return better_virtual_value; }
+};
+
+int use(B *b)
+{
+ return b->access();
+}
+
+int v_use(V * v)
+{
+ return v->access_vv();
+}
+
+int main()
+{
+ C c;
+ assert(v_use(&c) == -123);
+ D d;
+ assert(v_use(&d) == -345);
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.cc/vtv.exp b/libvtv/testsuite/libvtv.cc/vtv.exp
new file mode 100644
index 00000000000..12ed77431a8
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/vtv.exp
@@ -0,0 +1,83 @@
+load_lib libvtv-dg.exp
+load_gcc_lib gcc-dg.exp
+
+global VTV_FLAGS
+set VTV_FLAGS [list {-O0} {-O2}]
+
+libvtv_init c++
+
+set shlib_ext [get_shlib_extension]
+set lang_link_flags "-shared-libgcc -lstdc++"
+set lang_test_file_found 0
+set lang_library_path "../libstdc++-v3/src/.libs"
+
+dg-init
+
+set blddir [lookfor_file [get_multilibs] libvtv]
+
+# Find the correct libstdc++ library to use.
+
+if { $blddir != "" } {
+ # Look for a static libstdc++ first.
+ if [file exists "${blddir}/${lang_library_path}/libstdc++.a"] {
+ set lang_test_file "${lang_library_path}/libstdc++.a"
+ set lang_test_file_found 1
+ # We may have a shared only build, so look for a shared libstdc++.
+ } elseif [file exists "${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"] {
+ set lang_test_file "${lang_library_path}/libstdc++.${shlib_ext}"
+ set lang_test_file_found 1
+ } else {
+ puts "looking for ${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"
+ puts "No libstdc++ library found, will not execute c++ tests"
+ }
+} elseif { [info exists GXX_UNDER_TEST] } {
+ set lang_test_file_found 1
+ # Needs to exist for libvtv.exp.
+ set lang_test_file ""
+} else {
+ puts "GXX_UNDER_TEST not defined, will not execute c++ tests"
+}
+
+
+global srcdir
+
+if { $lang_test_file_found } {
+ # Set the path for finding libstdc++.
+ if { $blddir != "" } {
+ set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
+ } else {
+ set ld_library_path "$always_ld_library_path"
+ }
+ append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
+ set_ld_library_path_env_vars
+
+ # Make sure we can find the libstdc++ header files.
+ set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags"
+ if { [file exists $flags_file] } {
+ set libstdcxx_includes [exec sh $flags_file --build-includes]
+ } else {
+ set libstdcxx_includes ""
+ }
+
+ # Run the tests with -fvtable-verify=std
+ foreach flags $VTV_FLAGS {
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.cc/*.cc]] {
+ dg-runtest $srcfile "$flags -fvtable-verify=std" $libstdcxx_includes
+ }
+
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.cc/@*.list]] {
+ dg-runtest $srcfile "$flags -fvtable-verify=std" $libstdcxx_includes
+ }
+ }
+
+ # Run the tests with -fvtable-verify=preinit
+ foreach flags $VTV_FLAGS {
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.cc/*.cc]] {
+ dg-runtest $srcfile "$flags -fvtable-verify=preinit" $libstdcxx_includes
+ }
+
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.cc/@*.list]] {
+ dg-runtest $srcfile "$flags -fvtable-verify=preinit" $libstdcxx_includes
+ }
+ }
+}
diff --git a/libvtv/testsuite/libvtv.cc/xlan-test.cc b/libvtv/testsuite/libvtv.cc/xlan-test.cc
new file mode 100644
index 00000000000..213ed613fbb
--- /dev/null
+++ b/libvtv/testsuite/libvtv.cc/xlan-test.cc
@@ -0,0 +1,185 @@
+// { dg-do run }
+
+#include <stdio.h>
+#include <stdlib.h>
+
+class XMemory
+{
+public:
+ void * operator new (size_t size);
+ void operator delete (void *p);
+
+protected:
+ XMemory () {}
+
+ virtual ~XMemory() {}
+};
+
+class XSerializable
+{
+public:
+ virtual ~XSerializable () {};
+
+ virtual bool isSerializable() const = 0;
+ virtual void serialize () = 0;
+
+protected:
+ XSerializable() {};
+
+};
+
+class Grammar: public XSerializable, public XMemory
+{
+public:
+ enum GrammarType {
+ DTDGrammarType,
+ SchemaGrammarType,
+ OtherGrammarType,
+ Unknown
+ };
+
+ virtual ~Grammar() {}
+
+ virtual GrammarType getGrammarType() const = 0;
+ virtual bool getValidated() const = 0;
+
+ virtual bool isSerializable() const;
+ virtual void serialize ();
+
+protected:
+ Grammar() {};
+
+};
+
+class SchemaGrammar : public Grammar
+{
+public:
+
+ SchemaGrammar () : Grammar(), elemID(10) { fValidated = true; }
+
+ virtual ~SchemaGrammar() {}
+
+ virtual Grammar::GrammarType getGrammarType() const;
+ virtual bool getValidated() const;
+
+ virtual bool isSerializable () const;
+ virtual void serialize ();
+
+private:
+ const unsigned int elemID;
+ bool fValidated;
+
+};
+
+class OtherGrammar : public Grammar
+{
+public:
+
+ OtherGrammar () : Grammar(), elemID(10) { fValidated = true; }
+
+ virtual ~OtherGrammar() {}
+
+ virtual Grammar::GrammarType getGrammarType() const;
+ virtual bool getValidated() const;
+
+ virtual bool isSerializable () const;
+ virtual void serialize ();
+
+private:
+ const unsigned int elemID;
+ bool fValidated;
+
+};
+
+void
+Grammar::serialize ()
+{
+ printf ("in Grammar::serialize\n");
+}
+
+bool
+Grammar::isSerializable () const
+{
+ return true;
+}
+
+bool
+SchemaGrammar::isSerializable () const
+{
+ return true;
+}
+
+void
+SchemaGrammar::serialize ()
+{
+ printf ("in SchemaGrammar::serialize\n");
+}
+
+Grammar::GrammarType
+SchemaGrammar::getGrammarType() const {
+ return Grammar::SchemaGrammarType;
+}
+
+bool
+SchemaGrammar::getValidated () const
+{
+ return fValidated;
+}
+
+void *
+XMemory::operator new (size_t size)
+{
+ return malloc (size);
+}
+
+void
+XMemory::operator delete (void *p)
+{
+}
+
+bool
+OtherGrammar::isSerializable () const
+{
+ return false;
+}
+
+void
+OtherGrammar::serialize ()
+{
+ printf ("in OtherGrammar::serialize\n");
+}
+
+Grammar::GrammarType
+OtherGrammar::getGrammarType() const {
+ return Grammar::OtherGrammarType;
+}
+
+bool
+OtherGrammar::getValidated () const
+{
+ return fValidated;
+}
+
+int
+main (int argc, char **argv)
+{
+ SchemaGrammar sPtr;
+ OtherGrammar oPtr;
+ Grammar &sGrammar = sPtr;
+
+ for (int i = 0; i < 2; ++i)
+ {
+ if (i == 0)
+ sGrammar = oPtr;
+ else
+ sGrammar = sPtr;
+
+ if (sGrammar.getGrammarType() != Grammar::SchemaGrammarType ||
+ sGrammar.getValidated ())
+ printf ("if condition was true.\n");
+ else
+ printf ("if condition was false.\n");
+ }
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.mempool.cc/mempool.exp b/libvtv/testsuite/libvtv.mempool.cc/mempool.exp
new file mode 100644
index 00000000000..9565eae711a
--- /dev/null
+++ b/libvtv/testsuite/libvtv.mempool.cc/mempool.exp
@@ -0,0 +1,68 @@
+load_lib libvtv-dg.exp
+load_gcc_lib gcc-dg.exp
+
+global VTV_FLAGS
+set VTV_FLAGS [list {-O0} {-O2}]
+
+libvtv_init c++
+
+set shlib_ext [get_shlib_extension]
+set lang_link_flags "-shared-libgcc -lstdc++"
+set lang_test_file_found 0
+set lang_library_path "../libstdc++-v3/src/.libs"
+
+dg-init
+
+set blddir [lookfor_file [get_multilibs] libvtv]
+
+# Find the correct libstdc++ library to use.
+
+if { $blddir != "" } {
+ # Look for a static libstdc++ first.
+ if [file exists "${blddir}/${lang_library_path}/libstdc++.a"] {
+ set lang_test_file "${lang_library_path}/libstdc++.a"
+ set lang_test_file_found 1
+ # We may have a shared only build, so look for a shared libstdc++.
+ } elseif [file exists "${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"] {
+ set lang_test_file "${lang_library_path}/libstdc++.${shlib_ext}"
+ set lang_test_file_found 1
+ } else {
+ puts "looking for ${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"
+ puts "No libstdc++ library found, will not execute c++ tests"
+ }
+} elseif { [info exists GXX_UNDER_TEST] } {
+ set lang_test_file_found 1
+ # Needs to exist for libvtv.exp.
+ set lang_test_file ""
+} else {
+ puts "GXX_UNDER_TEST not defined, will not execute c++ tests"
+}
+
+
+global srcdir
+
+if { $lang_test_file_found } {
+ # Set the path for finding libstdc++.
+ if { $blddir != "" } {
+ set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
+ } else {
+ set ld_library_path "$always_ld_library_path"
+ }
+ append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
+ set_ld_library_path_env_vars
+
+ # Make sure we can find the libstdc++ header files.
+ set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags"
+ if { [file exists $flags_file] } {
+ set libstdcxx_includes [exec sh $flags_file --build-includes]
+ } else {
+ set libstdcxx_includes ""
+ }
+
+ # Run the tests with -fvtable-verify=std
+ foreach flags $VTV_FLAGS {
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.mempool.cc/*.cc]] {
+ dg-runtest $srcfile "$flags -fvtable-verify=std" $libstdcxx_includes
+ }
+ }
+}
diff --git a/libvtv/testsuite/libvtv.mempool.cc/mempool_negative.cc b/libvtv/testsuite/libvtv.mempool.cc/mempool_negative.cc
new file mode 100644
index 00000000000..2d5e1d0b531
--- /dev/null
+++ b/libvtv/testsuite/libvtv.mempool.cc/mempool_negative.cc
@@ -0,0 +1,193 @@
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <setjmp.h>
+
+#include "vtv_malloc.h"
+#include "../../../include/vtv-change-permission.h"
+
+volatile static int signal_count = 0;
+
+sigjmp_buf before_segv;
+
+unsigned int vtv_debug = 0;
+
+static void
+handler(int sig, siginfo_t *si, void *unused)
+{
+ signal_count++;
+ /* You are not supposed to longjmp out of a signal handler but it seems
+ to work for this test case and it simplifies it */
+ siglongjmp(before_segv, 1);
+}
+
+/* Try to modify the memory pointed by "s" but dont actually change the values.
+ Assumes and verifies the memory to be modified is mprotected */
+void mempoke(void * s, size_t n)
+{
+ volatile char * p = (char *)s;
+ int ret;
+
+ signal_count = 0;
+ ret = sigsetjmp(before_segv, 1);
+ if (ret == 0)
+ p[0] = p[0];
+
+ assert(ret == 1 && signal_count == 1);
+
+ ret = sigsetjmp(before_segv, 1);
+ if (ret == 0)
+ p[n - 1] = p[n - 1];
+
+ assert(ret == 1 && signal_count == 2);
+}
+
+int main()
+{
+ char * ptr;
+ int size;
+
+ /* Set up handler for SIGSEGV. */
+ struct sigaction sa;
+ sa.sa_flags = SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_sigaction = handler;
+ if (sigaction(SIGSEGV, &sa, NULL) == -1)
+ assert(0);
+
+ /* Make the 'bookkeeping' vars read-write. */
+ __VLTChangePermission (__VLTP_READ_WRITE);
+ __vtv_malloc_init();
+
+ size = 10;
+
+ /* Verify not writable after unprotect */
+ __vtv_malloc_unprotect();
+ ptr = (char *)__vtv_malloc(size);
+ memset(ptr, 'a', size);
+ __vtv_malloc_protect();
+ mempoke(ptr, size);
+ __vtv_free(ptr);
+
+ /* verify not-writable after protect, unprotect */
+ __vtv_malloc_unprotect();
+ ptr = (char *)__vtv_malloc(size);
+ memset(ptr, 'a', size);
+ __vtv_malloc_protect();
+ __vtv_malloc_unprotect();
+ memset(ptr, 'a', size);
+ assert(ptr[size - 1] == 'a');
+ __vtv_malloc_protect();
+ assert(ptr[size - 1] == 'a');
+ mempoke(ptr,size);
+ __vtv_free(ptr);
+
+ /* Allocate a bunch of small objects.
+ Make sure the alignment is correct.
+ Verify data has not been corrupted.
+ Make sure the data cannot modified */
+ {
+ int s;
+ for (s = 3; s < 28; s += 3)
+ {
+ size = s;
+ {
+ int i;
+ #define ITERS 1000
+ char * ptrs[ITERS];
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS; i++)
+ {
+ ptr = (char *)__vtv_malloc(size);
+ assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
+ memset(ptr, (i & 127), size);
+ assert(ptr[size - 1] == (i & 127));
+ ptrs[i] = ptr;
+ }
+ __vtv_malloc_protect();
+
+ for (i = 0; i < ITERS; i++)
+ mempoke(ptrs[i], size);
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS; i++)
+ __vtv_free(ptrs[i]);
+ __vtv_malloc_protect();
+ }
+ }
+ }
+
+ /* Allocate a bunch of medium size objects.
+ Make sure the alignment is correct.
+ Verify data has not been corrupted.
+ Try to modify the data to verify everything gets unprotected */
+ {
+ int s;
+ for (s = 501; s < 2500; s += 91)
+ {
+ size = s;
+ {
+ int i;
+ #define ITERS2 100
+ char * ptrs[ITERS2];
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS2; i++)
+ {
+
+ ptr = (char *)__vtv_malloc(size);
+ assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
+ memset(ptr, i & 127, size);
+ assert(ptr[size - 1] == i & 127);
+ ptrs[i] = ptr;
+ }
+ __vtv_malloc_protect();
+
+ for (i = 0; i < ITERS2; i++)
+ mempoke(ptrs[i], size);
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS2; i++)
+ __vtv_free(ptrs[i]);
+ __vtv_malloc_protect();
+ }
+ }
+ }
+
+ /* Allocate a bunch of medium size objects. Make sure the alignment is correct */
+ {
+ int s;
+ for (s = 3001; s < 15000; s += 307)
+ {
+ size = s;
+ {
+ int i;
+ #define ITERS3 50
+ char * ptrs[ITERS3];
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS3; i++)
+ {
+ ptr = (char *)__vtv_malloc(size);
+ assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
+ memset(ptr, i & 127, size);
+ assert(ptr[size - 1] == i & 127);
+ ptrs[i] = ptr;
+ }
+ __vtv_malloc_protect();
+
+ for (i = 0; i < ITERS3; i++)
+ mempoke(ptrs[i], size);
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS3; i++)
+ __vtv_free(ptrs[i]);
+ __vtv_malloc_protect();
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.mempool.cc/mempool_positive.cc b/libvtv/testsuite/libvtv.mempool.cc/mempool_positive.cc
new file mode 100644
index 00000000000..5e60df9b686
--- /dev/null
+++ b/libvtv/testsuite/libvtv.mempool.cc/mempool_positive.cc
@@ -0,0 +1,199 @@
+#include <string.h>
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+
+#include "vtv_malloc.h"
+#include "../../../include/vtv-change-permission.h"
+
+unsigned int vtv_debug = 0;
+
+static void
+handler(int sig, siginfo_t *si, void *unused)
+{
+ printf("Got SIGSEGV at address: 0x%lx\n",
+ (long) si->si_addr);
+ exit(1);
+}
+
+int memchk(const void * s, int c, size_t n)
+{
+ const char * p = (const char *)s;
+ for (; p < ((char *)s + n); p++)
+ if (*p != c)
+ return 1;
+ return 0;
+}
+
+int main()
+{
+ char * ptr;
+ int size;
+
+ /* Set up handler for SIGSEGV. In this test case, we should never hit any SIGSEGV */
+ struct sigaction sa;
+ sa.sa_flags = SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_sigaction = handler;
+ if (sigaction(SIGSEGV, &sa, NULL) == -1)
+ assert(0);
+
+ /* Make the 'bookkeeping' vars read-write. */
+ __VLTChangePermission (__VLTP_READ_WRITE);
+ __vtv_malloc_init();
+
+ size = 10;
+
+ /* Verify simple allocation and deallocation */
+ __vtv_malloc_unprotect();
+ ptr = (char *)__vtv_malloc(size);
+ __vtv_malloc_protect();
+ __vtv_free(ptr);
+
+ /* Verify writable after unprotect */
+ __vtv_malloc_unprotect();
+ ptr = (char *)__vtv_malloc(size);
+ memset(ptr, 'a', size);
+ __vtv_malloc_protect();
+ __vtv_free(ptr);
+
+ /* verify readable after protect */
+ __vtv_malloc_unprotect();
+ ptr = (char *)__vtv_malloc(size);
+ memset(ptr, 'a', size);
+ __vtv_malloc_protect();
+ assert(ptr[size - 1] == 'a');
+ __vtv_free(ptr);
+
+ /* verify writable after protect, unprotect */
+ __vtv_malloc_unprotect();
+ ptr = (char *)__vtv_malloc(size);
+ memset(ptr, 'a', size);
+ __vtv_malloc_protect();
+ __vtv_malloc_unprotect();
+ memset(ptr, 'a', size);
+ assert(ptr[size - 1] == 'a');
+ __vtv_malloc_protect();
+ assert(ptr[size - 1] == 'a');
+ __vtv_free(ptr);
+
+ /* Allocate a bunch of small objects.
+ Make sure the alignment is correct.
+ Verify data has not been corrupted.
+ Try to modify the data to verify everything gets unprotected */
+ {
+ int s;
+ for (s = 3; s < 28; s += 3)
+ {
+ size = s;
+ {
+ int i;
+ #define ITERS 1000
+ char * ptrs[ITERS];
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS; i++)
+ {
+ ptr = (char *)__vtv_malloc(size);
+ assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
+ memset(ptr, (i & 127), size);
+ assert(ptr[size - 1] == (i & 127));
+ ptrs[i] = ptr;
+ }
+ __vtv_malloc_protect();
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS; i++)
+ {
+ if (memchk(ptrs[i], i & 127, size) != 0)
+ assert(0);
+ memset(ptrs[i], (i + 1) & 127, size);
+ if (memchk(ptrs[i], (i + 1) & 127, size) != 0)
+ assert(0);
+ __vtv_free(ptrs[i]);
+ }
+ __vtv_malloc_protect();
+ }
+ }
+ }
+
+ /* Allocate a bunch of medium size objects.
+ Make sure the alignment is correct.
+ Verify data has not been corrupted.
+ Try to modify the data to verify everything gets unprotected */
+ {
+ int s;
+ for (s = 501; s < 2500; s += 91)
+ {
+ size = s;
+ {
+ int i;
+ #define ITERS2 100
+ char * ptrs[ITERS2];
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS2; i++)
+ {
+
+ ptr = (char *)__vtv_malloc(size);
+ assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
+ memset(ptr, i & 127, size);
+ assert(ptr[size - 1] == i & 127);
+ ptrs[i] = ptr;
+ }
+ __vtv_malloc_protect();
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS2; i++)
+ {
+ if (memchk(ptrs[i], i & 127, size) != 0)
+ assert(0);
+ memset(ptrs[i], (i + 1) & 127, size);
+ if (memchk(ptrs[i], (i + 1) & 127, size) != 0)
+ assert(0);
+ __vtv_free(ptrs[i]);
+ }
+ __vtv_malloc_protect();
+ }
+ }
+ }
+
+ /* Allocate a bunch of medium size objects. Make sure the alignment is correct */
+ {
+ int s;
+ for (s = 3001; s < 15000; s += 307)
+ {
+ size = s;
+ {
+ int i;
+ #define ITERS3 50
+ char * ptrs[ITERS3];
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS3; i++)
+ {
+ ptr = (char *)__vtv_malloc(size);
+ assert(((long)ptr & VTV_ALIGNMENT_MASK) == 0);
+ memset(ptr, i & 127, size);
+ assert(ptr[size - 1] == i & 127);
+ ptrs[i] = ptr;
+ }
+ __vtv_malloc_protect();
+
+ __vtv_malloc_unprotect();
+ for (i = 0; i < ITERS3; i++)
+ {
+ if (memchk(ptrs[i], i & 127, size) != 0)
+ assert(0);
+ memset(ptrs[i], (i + 1) & 127, size);
+ if (memchk(ptrs[i], (i + 1) & 127, size) != 0)
+ assert(0);
+ __vtv_free(ptrs[i]);
+ }
+ __vtv_malloc_protect();
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.mt.cc/mt.exp b/libvtv/testsuite/libvtv.mt.cc/mt.exp
new file mode 100644
index 00000000000..e2ee43577a3
--- /dev/null
+++ b/libvtv/testsuite/libvtv.mt.cc/mt.exp
@@ -0,0 +1,68 @@
+load_lib libvtv-dg.exp
+load_gcc_lib gcc-dg.exp
+
+global VTV_FLAGS
+set VTV_FLAGS [list {-O0} {-O2}]
+
+libvtv_init c++
+
+set shlib_ext [get_shlib_extension]
+set lang_link_flags "-shared-libgcc -lstdc++"
+set lang_test_file_found 0
+set lang_library_path "../libstdc++-v3/src/.libs"
+
+dg-init
+
+set blddir [lookfor_file [get_multilibs] libvtv]
+
+# Find the correct libstdc++ library to use.
+
+if { $blddir != "" } {
+ # Look for a static libstdc++ first.
+ if [file exists "${blddir}/${lang_library_path}/libstdc++.a"] {
+ set lang_test_file "${lang_library_path}/libstdc++.a"
+ set lang_test_file_found 1
+ # We may have a shared only build, so look for a shared libstdc++.
+ } elseif [file exists "${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"] {
+ set lang_test_file "${lang_library_path}/libstdc++.${shlib_ext}"
+ set lang_test_file_found 1
+ } else {
+ puts "looking for ${blddir}/${lang_library_path}/libstdc++.${shlib_ext}"
+ puts "No libstdc++ library found, will not execute c++ tests"
+ }
+} elseif { [info exists GXX_UNDER_TEST] } {
+ set lang_test_file_found 1
+ # Needs to exist for libvtv.exp.
+ set lang_test_file ""
+} else {
+ puts "GXX_UNDER_TEST not defined, will not execute c++ tests"
+}
+
+
+global srcdir
+
+if { $lang_test_file_found } {
+ # Set the path for finding libstdc++.
+ if { $blddir != "" } {
+ set ld_library_path "$always_ld_library_path:${blddir}/${lang_library_path}"
+ } else {
+ set ld_library_path "$always_ld_library_path"
+ }
+ append ld_library_path [gcc-set-multilib-library-path $GCC_UNDER_TEST]
+ set_ld_library_path_env_vars
+
+ # Make sure we can find the libstdc++ header files.
+ set flags_file "${blddir}/../libstdc++-v3/scripts/testsuite_flags"
+ if { [file exists $flags_file] } {
+ set libstdcxx_includes [exec sh $flags_file --build-includes]
+ } else {
+ set libstdcxx_includes ""
+ }
+
+ # Run the tests with -fvtable-verify=std
+ foreach flags $VTV_FLAGS {
+ foreach srcfile [lsort [glob -nocomplain ${srcdir}/libvtv.mt.cc/*.cc]] {
+ dg-runtest $srcfile "$flags -fvtable-verify=std -lpthread" $libstdcxx_includes
+ }
+ }
+}
diff --git a/libvtv/testsuite/libvtv.mt.cc/register_set_pair_inserts_mt.cc b/libvtv/testsuite/libvtv.mt.cc/register_set_pair_inserts_mt.cc
new file mode 100644
index 00000000000..6df197343f7
--- /dev/null
+++ b/libvtv/testsuite/libvtv.mt.cc/register_set_pair_inserts_mt.cc
@@ -0,0 +1,156 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "vtv_utils.h"
+#include "vtv_rts.h"
+#include "pthread.h"
+
+
+/* Multi-threaded test for calls to RegisterPair */
+
+/* This configuration will test mostly inserting of new elements since
+ the number of repeats is 1. It should also do a lot of rehashing */
+
+/* This test case may fail depending on the system configuration.
+ Check the value of /proc/sys/vm/max_map_count and fix by doing
+ Ex: sudo sh -c "echo 131060 > /proc/sys/vm/max_map_count" */
+
+#define NUM_MAPS 2000
+#define ELEMENTS_PER_MAP 100
+#define NUM_REPEATS 1
+
+#define NUM_THREADS 9
+
+#define KEY_TYPE_FIXED_SIZE 8
+void *key_buffer = malloc (17);
+typedef char * name_string;
+name_string fake_names[NUM_MAPS];
+
+/* This variable has to be put in rel.ro */
+void * volatile maps[NUM_MAPS] VTV_PROTECTED_VAR;
+
+struct fake_vt {
+ void * fake_vfp [4];
+};
+void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP];
+
+volatile int current_map = -1;
+volatile int threads_completed_it = 0;
+
+void
+generate_names (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_MAPS; ++i)
+ {
+ fake_names[i] = (char *) malloc (9 * sizeof (char));
+ snprintf (fake_names[i], 9, "name%d", i);
+ }
+}
+
+static uint32_t
+vtv_string_hash(const char *in)
+{
+ const char *s = in;
+ uint32_t h = 0;
+
+ for ( ; *s; ++s)
+ h = 5 * h + *s;
+ return h;
+}
+
+void * do_register_pairs(void *)
+{
+ for (int k = 0; k < NUM_REPEATS; k++)
+ {
+ int curr_fake_vt = 0;
+ for (int i = 0; i < NUM_MAPS; i++)
+ {
+ uint32_t *value_ptr = (uint32_t *) key_buffer;
+ uint32_t len1 = strlen (fake_names[i]);
+ uint32_t hash_value = vtv_string_hash (fake_names[i]);
+ void *temp_array[ELEMENTS_PER_MAP];
+
+ while (current_map < (k*NUM_MAPS + i))
+ ;
+
+ __VLTChangePermission(__VLTP_READ_WRITE);
+
+ *value_ptr = len1;
+ value_ptr++;
+ *value_ptr = hash_value;
+
+ memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i],
+ len1);
+
+
+#ifdef VTV_DEBUG
+ __VLTRegisterPairDebug ((void **) &maps[i], (char *) key_buffer, 128,
+ &fake_vts[curr_fake_vt], "", "");
+#else
+ __VLTRegisterPair ((void **) &maps[i], (char *) key_buffer, 128,
+ &fake_vts[curr_fake_vt]);
+#endif
+ for (int j = 0; j < ELEMENTS_PER_MAP; j++)
+ {
+ temp_array[j] = &fake_vts[curr_fake_vt];
+ curr_fake_vt++;
+ }
+
+#ifdef VTV_DEBUG
+ __VLTRegisterSetDebug ((void **) &maps[i], (char *) key_buffer, 128, 100,
+ (void **) &temp_array);
+#else
+ __VLTRegisterSet ((void **) &maps[i], (char *) key_buffer, 128, 100,
+ (void **) &temp_array);
+#endif
+ __VLTChangePermission(__VLTP_READ_ONLY);
+
+ int old_value;
+ do {
+ old_value = threads_completed_it;
+ } while (!__sync_bool_compare_and_swap(&threads_completed_it, old_value, old_value + 1));
+
+ if (old_value == (NUM_THREADS - 1)) // Only one thread will do this.
+ {
+ threads_completed_it = 0;
+ printf("%c%d", 13, current_map + 1);
+ fflush(stdout);
+ current_map++;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+int main()
+{
+ pthread_t thread_ids[NUM_THREADS];
+
+ generate_names();
+
+ for (int t = 0; t < NUM_THREADS; t++ )
+ if (pthread_create(&thread_ids[t], NULL, do_register_pairs, NULL) != 0)
+ {
+ printf("failed pthread_create\n");
+ exit(1);
+ }
+
+ current_map = 0; // start the work on the other threads
+
+ for (int t = 0; t < NUM_THREADS; t++)
+ if (pthread_join(thread_ids[t], NULL) != 0)
+ {
+ printf("failed pthread_join\n");
+ exit(2);
+ }
+
+ printf("\n");
+
+ return 0;
+}
diff --git a/libvtv/testsuite/libvtv.mt.cc/register_set_pair_mt.cc b/libvtv/testsuite/libvtv.mt.cc/register_set_pair_mt.cc
new file mode 100644
index 00000000000..1d480a1e3b8
--- /dev/null
+++ b/libvtv/testsuite/libvtv.mt.cc/register_set_pair_mt.cc
@@ -0,0 +1,158 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "vtv_utils.h"
+#include "vtv_rts.h"
+#include "pthread.h"
+
+
+/* Multi-threaded test for calls to RegisterPair */
+
+/* This configuration will test mostly inserting of elements that are already inserted since
+ the number of repeats is 10 */
+
+/* This test case may fail depending on the system configuration.
+ Check the value of /proc/sys/vm/max_map_count and fix by doing
+ Ex: sudo sh -c "echo 131060 > /proc/sys/vm/max_map_count" */
+
+#define NUM_MAPS 200
+#define ELEMENTS_PER_MAP 100
+#define NUM_REPEATS 10
+
+#define NUM_THREADS 9
+
+#define KEY_TYPE_FIXED_SIZE 8
+void *key_buffer = malloc (17);
+typedef char * name_string;
+name_string fake_names[NUM_MAPS];
+
+/* This variable has to be put in rel.ro */
+void * volatile maps[NUM_MAPS] VTV_PROTECTED_VAR;
+
+struct fake_vt {
+ void * fake_vfp [4];
+};
+void * fake_vts [NUM_MAPS * ELEMENTS_PER_MAP];
+
+volatile int current_map = -1;
+volatile int threads_completed_it = 0;
+
+void
+generate_names (void)
+{
+ int i;
+
+ for (i = 0; i < NUM_MAPS; ++i)
+ {
+ fake_names[i] = (char *) malloc (9 * sizeof (char));
+ snprintf (fake_names[i], 9, "name%d", i);
+ }
+}
+
+static uint32_t
+vtv_string_hash(const char *in)
+{
+ const char *s = in;
+ uint32_t h = 0;
+
+ for ( ; *s; ++s)
+ h = 5 * h + *s;
+ return h;
+}
+
+void * do_register_pairs(void *)
+{
+ for (int k = 0; k < NUM_REPEATS; k++)
+ {
+ int curr_fake_vt = 0;
+ for (int i = 0; i < NUM_MAPS; i++)
+ {
+ uint32_t *value_ptr = (uint32_t *) key_buffer;
+ uint32_t len1 = strlen (fake_names[i]);
+ uint32_t hash_value = vtv_string_hash (fake_names[i]);
+ void *temp_array[ELEMENTS_PER_MAP];
+
+ while (current_map < (k*NUM_MAPS + i))
+ ;
+
+ __VLTChangePermission(__VLTP_READ_WRITE);
+
+ *value_ptr = len1;
+ value_ptr++;
+ *value_ptr = hash_value;
+
+ memcpy ((char *) key_buffer + KEY_TYPE_FIXED_SIZE, fake_names[i],
+ len1);
+
+
+#ifdef VTV_DEBUG
+ __VLTRegisterPairDebug ((void **) &maps[i], (char *) key_buffer, 128,
+ &fake_vts[curr_fake_vt], "", "");
+#else
+ __VLTRegisterPair ((void **) &maps[i], (char *) key_buffer, 128,
+ &fake_vts[curr_fake_vt]);
+#endif
+ for (int j = 0; j < ELEMENTS_PER_MAP; j++)
+ {
+ temp_array[j] = &fake_vts[curr_fake_vt];
+ curr_fake_vt++;
+ }
+
+#ifdef VTV_DEBUG
+ __VLTRegisterSetDebug ((void **) &maps[i], (char *) key_buffer, 128, 100,
+ (void **) &temp_array);
+#else
+ __VLTRegisterSet ((void **) &maps[i], (char *) key_buffer, 128, 100,
+ (void **) &temp_array);
+#endif
+ __VLTChangePermission(__VLTP_READ_ONLY);
+
+ int old_value;
+ do {
+ old_value = threads_completed_it;
+ } while (!__sync_bool_compare_and_swap(&threads_completed_it, old_value, old_value + 1));
+
+ if (old_value == (NUM_THREADS - 1)) // Only one thread will do this.
+ {
+ threads_completed_it = 0;
+ printf("%c%d", 13, current_map + 1);
+ fflush(stdout);
+ current_map++;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+int main()
+{
+ pthread_t thread_ids[NUM_THREADS];
+
+ generate_names ();
+
+ for (int t = 0; t < NUM_THREADS; t++ )
+ if (pthread_create(&thread_ids[t], NULL, do_register_pairs, NULL) != 0)
+ {
+ printf("failed pthread_create\n");
+ exit(1);
+ }
+
+ current_map = 0; // start the work on the other threads
+
+ for (int t = 0; t < NUM_THREADS; t++)
+ if (pthread_join(thread_ids[t], NULL) != 0)
+ {
+ printf("failed pthread_join\n");
+ exit(2);
+ }
+
+ printf("\n");
+
+
+
+ return 0;
+}
diff --git a/libvtv/testsuite/other-tests/Makefile.am b/libvtv/testsuite/other-tests/Makefile.am
new file mode 100644
index 00000000000..56f76a79f5b
--- /dev/null
+++ b/libvtv/testsuite/other-tests/Makefile.am
@@ -0,0 +1,52 @@
+## Makefile for the testsuite subdirectory of the VTV library.
+##
+## Copyright (C) 2013 Free Software Foundation, Inc.
+##
+## Process this file with automake to produce Makefile.in.
+##
+## This file is part of the Vtable Verification (VTV) 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/>.
+
+AUTOMAKE_OPTIONS = nostdinc
+
+# Runs the testsuite via a script.
+
+# Create subdirectories.
+stamp-subdir:
+ if test ! -d lib64; then \
+ mkdir -p lib64; \
+ fi; \
+ if test ! -d lib32; then \
+ mkdir -p lib32; \
+ fi; \
+ echo `date` > stamp-subdir;
+
+
+testing_script=${libvtv_srcdir}/scripts/run-testsuite.sh
+check-script: ${testing_script} stamp-subdir
+ -@(chmod +x ${testing_script}; \
+ ${testing_script} ${libvtv_srcdir} ${libvtv_builddir})
+
+check-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-script
+
+.PHONY: check-script
+
+# By adding these files here, automake will remove them for 'make clean'
+CLEANFILES = *.out environment-fail-* stamp-* replace-fail-*
+
+# To remove directories.
+clean-local:
+ rm -rf lib*
diff --git a/libvtv/testsuite/other-tests/Makefile.in b/libvtv/testsuite/other-tests/Makefile.in
new file mode 100644
index 00000000000..66a75e16ea6
--- /dev/null
+++ b/libvtv/testsuite/other-tests/Makefile.in
@@ -0,0 +1,379 @@
+# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
+# Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkglibexecdir = $(libexecdir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+target_triplet = @target@
+subdir = testsuite
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+ $(top_srcdir)/../config/depstand.m4 \
+ $(top_srcdir)/../config/lead-dot.m4 \
+ $(top_srcdir)/../config/libstdc++-raw-cxx.m4 \
+ $(top_srcdir)/../config/multi.m4 \
+ $(top_srcdir)/../config/override.m4 \
+ $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
+ $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+ $(top_srcdir)/acinclude.m4 $(top_srcdir)/../libtool.m4 \
+ $(top_srcdir)/configure.ac
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/../mkinstalldirs
+CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_VPATH_FILES =
+SOURCES =
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AS = @AS@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CC = @CC@
+CCAS = @CCAS@
+CCASFLAGS = @CCASFLAGS@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+DSYMUTIL = @DSYMUTIL@
+DUMPBIN = @DUMPBIN@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+FGREP = @FGREP@
+GREP = @GREP@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+LD = @LD@
+LDFLAGS = @LDFLAGS@
+LIBOBJS = @LIBOBJS@
+LIBS = @LIBS@
+LIBSTDCXX_RAW_CXX_CXXFLAGS = @LIBSTDCXX_RAW_CXX_CXXFLAGS@
+LIBSTDCXX_RAW_CXX_LDFLAGS = @LIBSTDCXX_RAW_CXX_LDFLAGS@
+LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NM = @NM@
+NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
+OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_URL = @PACKAGE_URL@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+RANLIB = @RANLIB@
+SED = @SED@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+XCFLAGS = @XCFLAGS@
+abs_builddir = @abs_builddir@
+abs_srcdir = @abs_srcdir@
+abs_top_builddir = @abs_top_builddir@
+abs_top_srcdir = @abs_top_srcdir@
+ac_ct_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+enable_shared = @enable_shared@
+enable_static = @enable_static@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libdir = @libdir@
+libexecdir = @libexecdir@
+libtool_VERSION = @libtool_VERSION@
+libvtv_builddir = @libvtv_builddir@
+libvtv_srcdir = @libvtv_srcdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+multi_basedir = @multi_basedir@
+oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target = @target@
+target_alias = @target_alias@
+target_cpu = @target_cpu@
+target_noncanonical = @target_noncanonical@
+target_os = @target_os@
+target_vendor = @target_vendor@
+toolexecdir = @toolexecdir@
+toolexeclibdir = @toolexeclibdir@
+top_build_prefix = @top_build_prefix@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+toplevel_builddir = @toplevel_builddir@
+toplevel_srcdir = @toplevel_srcdir@
+AUTOMAKE_OPTIONS = nostdinc
+testing_script = ${libvtv_srcdir}/scripts/run-testsuite.sh
+
+# By adding these files here, automake will remove them for 'make clean'
+CLEANFILES = *.out environment-fail-* stamp-* replace-fail-*
+all: all-am
+
+.SUFFIXES:
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
+ @for dep in $?; do \
+ case '$(am__configure_deps)' in \
+ *$$dep*) \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign testsuite/Makefile'; \
+ $(am__cd) $(top_srcdir) && \
+ $(AUTOMAKE) --foreign testsuite/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(am__aclocal_m4_deps):
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+tags: TAGS
+TAGS:
+
+ctags: CTAGS
+CTAGS:
+
+check-am: all-am
+check: check-am
+all-am: Makefile
+installdirs:
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+ -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-local mostlyclean-am
+
+distclean: distclean-am
+ -rm -f Makefile
+distclean-am: clean-am distclean-generic
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+html-am:
+
+info: info-am
+
+info-am:
+
+install-data-am:
+
+install-dvi: install-dvi-am
+
+install-dvi-am:
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-html-am:
+
+install-info: install-info-am
+
+install-info-am:
+
+install-man:
+
+install-pdf: install-pdf-am
+
+install-pdf-am:
+
+install-ps: install-ps-am
+
+install-ps-am:
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-generic mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am:
+
+.MAKE: install-am install-strip
+
+.PHONY: all all-am check check-am clean clean-generic clean-libtool \
+ clean-local distclean distclean-generic distclean-libtool dvi \
+ dvi-am html html-am info info-am install install-am \
+ install-data install-data-am install-dvi install-dvi-am \
+ install-exec install-exec-am install-html install-html-am \
+ install-info install-info-am install-man install-pdf \
+ install-pdf-am install-ps install-ps-am install-strip \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am uninstall uninstall-am
+
+
+# Runs the testsuite via a script.
+
+# Create subdirectories.
+stamp-subdir:
+ if test ! -d lib64; then \
+ mkdir -p lib64; \
+ fi; \
+ if test ! -d lib32; then \
+ mkdir -p lib32; \
+ fi; \
+ echo `date` > stamp-subdir;
+check-script: ${testing_script} stamp-subdir
+ -@(chmod +x ${testing_script}; \
+ ${testing_script} ${libvtv_srcdir} ${libvtv_builddir})
+
+check-am:
+ $(MAKE) $(AM_MAKEFLAGS) check-script
+
+.PHONY: check-script
+
+# To remove directories.
+clean-local:
+ rm -rf lib*
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/libvtv/testsuite/other-tests/README b/libvtv/testsuite/other-tests/README
new file mode 100644
index 00000000000..a64047460a6
--- /dev/null
+++ b/libvtv/testsuite/other-tests/README
@@ -0,0 +1,8 @@
+This directory contains tests that have not yet been converted to
+proper dejagnu tests. If you look at the run_testsuite script in
+libvtv/scripts, you should get a fair idea as to how to run these
+tests. The plan is to convert these tests into proper dejangnu tests
+sometime in the near future.
+
+
+Aug. 30, 2013 \ No newline at end of file
diff --git a/libvtv/testsuite/other-tests/dlopen.cc b/libvtv/testsuite/other-tests/dlopen.cc
new file mode 100644
index 00000000000..4ffbe83acf7
--- /dev/null
+++ b/libvtv/testsuite/other-tests/dlopen.cc
@@ -0,0 +1,38 @@
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
+
+
+typedef void (*voidfn)(void);
+
+int failures = 0;
+
+void
+__vtv_verify_fail (void **data_set_ptr, const void *vtbl_pointer)
+{
+ failures++;
+ return;
+}
+
+
+int main()
+{
+ char so_name[] = "so0.so";
+ void * dlhandle = dlopen(so_name, RTLD_NOW);
+ if (!dlhandle)
+ {
+ fprintf(stderr, "dlopen %s error: %s\n", so_name, dlerror());
+ exit(1);
+ }
+ voidfn so_entry = (voidfn)dlsym(dlhandle, "so_entry_0");
+ if (!so_entry)
+ {
+ fprintf(stderr, "dlopen %s dlsym error: %s\n", so_name, dlerror());
+ exit(2);
+ }
+
+ so_entry();
+
+ dlclose(dlhandle);
+}
diff --git a/libvtv/testsuite/other-tests/dlopen_mt.cc b/libvtv/testsuite/other-tests/dlopen_mt.cc
new file mode 100644
index 00000000000..772e8a733ed
--- /dev/null
+++ b/libvtv/testsuite/other-tests/dlopen_mt.cc
@@ -0,0 +1,112 @@
+#include <stdlib.h>
+#include <dlfcn.h>
+#include <stdio.h>
+
+#include "vtv_utils.h"
+#include "vtv_rts.h"
+#include "pthread.h"
+
+#define NUM_REPEATS 10
+#define NUM_THREADS 10
+#define NUM_SOS 100
+#define NUM_SOS_PER_THREAD (NUM_SOS/NUM_THREADS)
+
+typedef void (*voidfn)(void);
+
+int failures = 0;
+
+void
+__vtv_verify_fail (void **data_set_ptr, const void *vtbl_pointer)
+{
+ failures++;
+ return;
+}
+
+
+void do_dlopen(int so_num)
+{
+ char so_name [sizeof("soxxx.so")];
+ sprintf(so_name, "so%d.so", so_num);
+ // printf("dl-opening %s\n", so_name);
+ void * dlhandle = dlopen(so_name, RTLD_NOW);
+ if (!dlhandle)
+ {
+ fprintf(stderr, "dlopen so:%s error: %s\n", so_name, dlerror());
+ exit(1);
+ }
+ char so_entry [sizeof("so_entry_xxx")];
+ sprintf(so_entry, "so_entry_%d", so_num);
+ voidfn so_entry_fn = (voidfn)dlsym(dlhandle, so_entry);
+ if (!so_entry_fn)
+ {
+ fprintf(stderr, "so:%s dlsym error: %s\n", so_name, dlerror());
+ exit(2);
+ }
+
+ so_entry_fn();
+
+ dlclose(dlhandle);
+}
+
+volatile int threads_completed_it = 0;
+volatile int current_wave = -1;
+
+void * do_dlopens(void * ptid)
+{
+ for (int k = 0; k < NUM_REPEATS; k++)
+ {
+
+ for (int i = 0; i < NUM_SOS_PER_THREAD; i++)
+ {
+ while (current_wave < (k*NUM_SOS_PER_THREAD + i)) /* from 0 to 99 */
+ ;
+
+ do_dlopen((NUM_SOS_PER_THREAD * *(int *)ptid) + i);
+
+ int old_value;
+ do {
+ old_value = threads_completed_it;
+ } while (!__sync_bool_compare_and_swap(&threads_completed_it, old_value, old_value + 1));
+
+ if (old_value == (NUM_THREADS - 1)) // Only one thread will do this.
+ {
+ threads_completed_it = 0;
+ printf("%c%d", 13, current_wave + 1);
+ fflush(stdout);
+ current_wave++;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+int main()
+{
+ pthread_t thread_ids[NUM_THREADS];
+ int thread_nids[NUM_THREADS];
+
+ for (int t = 0; t < NUM_THREADS; t++ )
+ {
+ thread_nids[t] = t;
+ if (pthread_create(&thread_ids[t], NULL, do_dlopens, &thread_nids[t]) != 0)
+ {
+ printf("failed pthread_create\n");
+ exit(1);
+ }
+ }
+
+ current_wave = 0; // start the work on the other threads
+
+ for (int t = 0; t < NUM_THREADS; t++)
+ if (pthread_join(thread_ids[t], NULL) != 0)
+ {
+ printf("failed pthread_join\n");
+ exit(2);
+ }
+
+ printf("\n");
+
+ return 0;
+}
diff --git a/libvtv/testsuite/other-tests/environment-fail-32.s b/libvtv/testsuite/other-tests/environment-fail-32.s
new file mode 100644
index 00000000000..cac501652a7
--- /dev/null
+++ b/libvtv/testsuite/other-tests/environment-fail-32.s
@@ -0,0 +1,514 @@
+ .file "environment.cc"
+ .section .text._ZN15EnvironmentImpl6GetVarEPKcPc,"axG",@progbits,_ZN15EnvironmentImpl6GetVarEPKcPc,comdat
+ .align 2
+ .weak _ZN15EnvironmentImpl6GetVarEPKcPc
+ .type _ZN15EnvironmentImpl6GetVarEPKcPc, @function
+_ZN15EnvironmentImpl6GetVarEPKcPc:
+.LFB0:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ movl $1, %eax
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE0:
+ .size _ZN15EnvironmentImpl6GetVarEPKcPc, .-_ZN15EnvironmentImpl6GetVarEPKcPc
+ .text
+ .align 2
+ .globl _ZN11EnvironmentD2Ev
+ .type _ZN11EnvironmentD2Ev, @function
+_ZN11EnvironmentD2Ev:
+.LFB2:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ pushl %ebx
+ subl $20, %esp
+ .cfi_offset 3, -12
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl 8(%ebp), %eax
+ movl _ZTV11Environment@GOT(%ebx), %edx
+ leal 8(%edx), %edx
+ movl %edx, (%eax)
+ movl $0, %eax
+ testl %eax, %eax
+ je .L3
+ movl 8(%ebp), %eax
+ movl %eax, (%esp)
+ call _ZdlPv@PLT
+.L3:
+ addl $20, %esp
+ popl %ebx
+ .cfi_restore 3
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE2:
+ .size _ZN11EnvironmentD2Ev, .-_ZN11EnvironmentD2Ev
+ .globl _ZN11EnvironmentD1Ev
+ .set _ZN11EnvironmentD1Ev,_ZN11EnvironmentD2Ev
+ .align 2
+ .globl _ZN11EnvironmentD0Ev
+ .type _ZN11EnvironmentD0Ev, @function
+_ZN11EnvironmentD0Ev:
+.LFB4:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ pushl %ebx
+ subl $20, %esp
+ .cfi_offset 3, -12
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl 8(%ebp), %eax
+ movl %eax, (%esp)
+ call _ZN11EnvironmentD1Ev@PLT
+ movl 8(%ebp), %eax
+ movl %eax, (%esp)
+ call _ZdlPv@PLT
+ addl $20, %esp
+ popl %ebx
+ .cfi_restore 3
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE4:
+ .size _ZN11EnvironmentD0Ev, .-_ZN11EnvironmentD0Ev
+ .section .text._ZN11EnvironmentC2Ev,"axG",@progbits,_ZN11EnvironmentC5Ev,comdat
+ .align 2
+ .weak _ZN11EnvironmentC2Ev
+ .type _ZN11EnvironmentC2Ev, @function
+_ZN11EnvironmentC2Ev:
+.LFB8:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ call __x86.get_pc_thunk.cx
+ addl $_GLOBAL_OFFSET_TABLE_, %ecx
+ movl 8(%ebp), %eax
+ movl _ZTV11Environment@GOT(%ecx), %edx
+ leal 8(%edx), %edx
+ movl %edx, (%eax)
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE8:
+ .size _ZN11EnvironmentC2Ev, .-_ZN11EnvironmentC2Ev
+ .weak _ZN11EnvironmentC1Ev
+ .set _ZN11EnvironmentC1Ev,_ZN11EnvironmentC2Ev
+ .section .text._ZN15EnvironmentImplC2Ev,"axG",@progbits,_ZN15EnvironmentImplC5Ev,comdat
+ .align 2
+ .weak _ZN15EnvironmentImplC2Ev
+ .type _ZN15EnvironmentImplC2Ev, @function
+_ZN15EnvironmentImplC2Ev:
+.LFB10:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ pushl %ebx
+ subl $20, %esp
+ .cfi_offset 3, -12
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl 8(%ebp), %eax
+ movl %eax, (%esp)
+ call _ZN11EnvironmentC2Ev@PLT
+ movl 8(%ebp), %eax
+ movl _ZTV15EnvironmentImpl@GOT(%ebx), %edx
+ leal 8(%edx), %edx
+ movl %edx, (%eax)
+ addl $20, %esp
+ popl %ebx
+ .cfi_restore 3
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE10:
+ .size _ZN15EnvironmentImplC2Ev, .-_ZN15EnvironmentImplC2Ev
+ .weak _ZN15EnvironmentImplC1Ev
+ .set _ZN15EnvironmentImplC1Ev,_ZN15EnvironmentImplC2Ev
+ .text
+ .align 2
+ .globl _ZN11Environment6CreateEv
+ .type _ZN11Environment6CreateEv, @function
+_ZN11Environment6CreateEv:
+.LFB5:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ pushl %esi
+ pushl %ebx
+ subl $16, %esp
+ .cfi_offset 6, -12
+ .cfi_offset 3, -16
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl $4, (%esp)
+ call _Znwj@PLT
+ movl %eax, %esi
+ movl $0, (%esi)
+ movl %esi, (%esp)
+ call _ZN15EnvironmentImplC1Ev@PLT
+ movl %esi, %eax
+ addl $16, %esp
+ popl %ebx
+ .cfi_restore 3
+ popl %esi
+ .cfi_restore 6
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE5:
+ .size _ZN11Environment6CreateEv, .-_ZN11Environment6CreateEv
+ .section .rodata
+.LC0:
+ .string "%p\n"
+ .text
+ .globl main
+ .type main, @function
+main:
+.LFB12:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ pushl %ebx
+ andl $-16, %esp
+ subl $32, %esp
+ .cfi_offset 3, -12
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl $0, 28(%esp)
+ call _ZN11Environment6CreateEv@PLT
+ movl %eax, 24(%esp)
+ movl 24(%esp), %eax
+ movl (%eax), %eax
+ movl %eax, 4(%esp)
+ leal _ZN4_VTVI11EnvironmentE12__vtable_mapE@GOTOFF(%ebx), %eax
+ movl %eax, (%esp)
+ call _Z24__VLTVerifyVtablePointerPPvPKv@PLT
+ addl $8, %eax
+ movl (%eax), %eax
+ movl 28(%esp), %edx
+ movl %edx, 8(%esp)
+ movl $0, 4(%esp)
+ movl 24(%esp), %edx
+ movl %edx, (%esp)
+ call *%eax
+ movl 24(%esp), %eax
+ movl %eax, 4(%esp)
+ leal .LC0@GOTOFF(%ebx), %eax
+ movl %eax, (%esp)
+ call printf@PLT
+ movl $0, %eax
+ movl -4(%ebp), %ebx
+ leave
+ .cfi_restore 5
+ .cfi_restore 3
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE12:
+ .size main, .-main
+ .weak _ZTV11Environment
+ .section .data.rel.ro._ZTV11Environment,"awG",@progbits,_ZTV11Environment,comdat
+ .align 8
+ .type _ZTV11Environment, @object
+ .size _ZTV11Environment, 20
+_ZTV11Environment:
+ .long 0
+ .long _ZTI11Environment
+ .long _ZN11EnvironmentD1Ev
+ .long _ZN11EnvironmentD0Ev
+ .long __cxa_pure_virtual
+ .weak _ZTV15EnvironmentImpl
+ .section .data.rel.ro._ZTV15EnvironmentImpl,"awG",@progbits,_ZTV15EnvironmentImpl,comdat
+ .align 8
+ .type _ZTV15EnvironmentImpl, @object
+ .size _ZTV15EnvironmentImpl, 20
+_ZTV15EnvironmentImpl:
+ .long 0
+ .long _ZTI15EnvironmentImpl
+ .long _ZN15EnvironmentImplD1Ev
+ .long _ZN15EnvironmentImplD0Ev
+ .long _ZN15EnvironmentImpl6GetVarEPKcPc
+ .section .text._ZN15EnvironmentImplD2Ev,"axG",@progbits,_ZN15EnvironmentImplD5Ev,comdat
+ .align 2
+ .weak _ZN15EnvironmentImplD2Ev
+ .type _ZN15EnvironmentImplD2Ev, @function
+_ZN15EnvironmentImplD2Ev:
+.LFB14:
+ .cfi_startproc
+ .cfi_personality 0x9b,DW.ref.__gxx_personality_v0
+ .cfi_lsda 0x1b,.LLSDA14
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ pushl %ebx
+ subl $20, %esp
+ .cfi_offset 3, -12
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl 8(%ebp), %eax
+ movl _ZTV15EnvironmentImpl@GOT(%ebx), %edx
+ leal 8(%edx), %edx
+ movl %edx, (%eax)
+ movl 8(%ebp), %eax
+ movl %eax, (%esp)
+.LEHB0:
+ call _ZN11EnvironmentD2Ev@PLT
+.LEHE0:
+ movl $0, %eax
+ testl %eax, %eax
+ je .L19
+ movl 8(%ebp), %eax
+ movl %eax, (%esp)
+ call _ZdlPv@PLT
+ jmp .L19
+.L18:
+ movl %eax, (%esp)
+.LEHB1:
+ call _Unwind_Resume@PLT
+.LEHE1:
+.L19:
+ addl $20, %esp
+ popl %ebx
+ .cfi_restore 3
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE14:
+ .globl __gxx_personality_v0
+ .section .gcc_except_table._ZN15EnvironmentImplD2Ev,"aG",@progbits,_ZN15EnvironmentImplD5Ev,comdat
+.LLSDA14:
+ .byte 0xff
+ .byte 0xff
+ .byte 0x1
+ .uleb128 .LLSDACSE14-.LLSDACSB14
+.LLSDACSB14:
+ .uleb128 .LEHB0-.LFB14
+ .uleb128 .LEHE0-.LEHB0
+ .uleb128 .L18-.LFB14
+ .uleb128 0
+ .uleb128 .LEHB1-.LFB14
+ .uleb128 .LEHE1-.LEHB1
+ .uleb128 0
+ .uleb128 0
+.LLSDACSE14:
+ .section .text._ZN15EnvironmentImplD2Ev,"axG",@progbits,_ZN15EnvironmentImplD5Ev,comdat
+ .size _ZN15EnvironmentImplD2Ev, .-_ZN15EnvironmentImplD2Ev
+ .weak _ZN15EnvironmentImplD1Ev
+ .set _ZN15EnvironmentImplD1Ev,_ZN15EnvironmentImplD2Ev
+ .section .text._ZN15EnvironmentImplD0Ev,"axG",@progbits,_ZN15EnvironmentImplD0Ev,comdat
+ .align 2
+ .weak _ZN15EnvironmentImplD0Ev
+ .type _ZN15EnvironmentImplD0Ev, @function
+_ZN15EnvironmentImplD0Ev:
+.LFB16:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ pushl %ebx
+ subl $20, %esp
+ .cfi_offset 3, -12
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ movl 8(%ebp), %eax
+ movl %eax, (%esp)
+ call _ZN15EnvironmentImplD1Ev@PLT
+ movl 8(%ebp), %eax
+ movl %eax, (%esp)
+ call _ZdlPv@PLT
+ addl $20, %esp
+ popl %ebx
+ .cfi_restore 3
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE16:
+ .size _ZN15EnvironmentImplD0Ev, .-_ZN15EnvironmentImplD0Ev
+ .weak _ZTS15EnvironmentImpl
+ .section .rodata._ZTS15EnvironmentImpl,"aG",@progbits,_ZTS15EnvironmentImpl,comdat
+ .type _ZTS15EnvironmentImpl, @object
+ .size _ZTS15EnvironmentImpl, 18
+_ZTS15EnvironmentImpl:
+ .string "15EnvironmentImpl"
+ .weak _ZTI15EnvironmentImpl
+ .section .data.rel.ro._ZTI15EnvironmentImpl,"awG",@progbits,_ZTI15EnvironmentImpl,comdat
+ .align 4
+ .type _ZTI15EnvironmentImpl, @object
+ .size _ZTI15EnvironmentImpl, 12
+_ZTI15EnvironmentImpl:
+ .long _ZTVN10__cxxabiv120__si_class_type_infoE+8
+ .long _ZTS15EnvironmentImpl
+ .long _ZTI11Environment
+ .weak _ZTI11Environment
+ .section .data.rel.ro._ZTI11Environment,"awG",@progbits,_ZTI11Environment,comdat
+ .align 4
+ .type _ZTI11Environment, @object
+ .size _ZTI11Environment, 8
+_ZTI11Environment:
+ .long _ZTVN10__cxxabiv117__class_type_infoE+8
+ .long _ZTS11Environment
+ .weak _ZTS11Environment
+ .section .rodata._ZTS11Environment,"aG",@progbits,_ZTS11Environment,comdat
+ .type _ZTS11Environment, @object
+ .size _ZTS11Environment, 14
+_ZTS11Environment:
+ .string "11Environment"
+ .hidden _ZN4_VTVI11EnvironmentE12__vtable_mapE
+ .weak _ZN4_VTVI11EnvironmentE12__vtable_mapE
+ .section .vtable_map_vars,"awG",@progbits,_ZN4_VTVI11EnvironmentE12__vtable_mapE,comdat
+ .align 4
+ .type _ZN4_VTVI11EnvironmentE12__vtable_mapE, @gnu_unique_object
+ .size _ZN4_VTVI11EnvironmentE12__vtable_mapE, 4
+_ZN4_VTVI11EnvironmentE12__vtable_mapE:
+ .zero 4
+ .hidden _ZN4_VTVI15EnvironmentImplE12__vtable_mapE
+ .weak _ZN4_VTVI15EnvironmentImplE12__vtable_mapE
+ .section .vtable_map_vars,"awG",@progbits,_ZN4_VTVI15EnvironmentImplE12__vtable_mapE,comdat
+ .align 4
+ .type _ZN4_VTVI15EnvironmentImplE12__vtable_mapE, @gnu_unique_object
+ .size _ZN4_VTVI15EnvironmentImplE12__vtable_mapE, 4
+_ZN4_VTVI15EnvironmentImplE12__vtable_mapE:
+ .zero 4
+ .section .data.rel.ro,"aw",@progbits
+ .align 4
+ .type __vptr_array_11Environment, @object
+ .size __vptr_array_11Environment, 8
+__vptr_array_11Environment:
+ .long _ZTV11Environment+8
+ .long _ZTV15EnvironmentImpl+8
+ .section .rodata
+ .align 4
+.LC1:
+ .string "&"
+ .string ""
+ .string ""
+ .ascii "\224\tl\022_ZN4_VTVI11EnvironmentE12__vtable_mapE"
+ .align 4
+.LC2:
+ .string "*"
+ .string ""
+ .string ""
+ .ascii "N\225\r\334_ZN4_VTVI15EnvironmentImplE12__vtable_mapE"
+ .text
+ .type _GLOBAL__sub_I.00099_environment.cc, @function
+_GLOBAL__sub_I.00099_environment.cc:
+.LFB17:
+ .cfi_startproc
+ pushl %ebp
+ .cfi_def_cfa_offset 8
+ .cfi_offset 5, -8
+ movl %esp, %ebp
+ .cfi_def_cfa_register 5
+ pushl %ebx
+ subl $36, %esp
+ .cfi_offset 3, -12
+ call __x86.get_pc_thunk.bx
+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
+ leal __vptr_array_11Environment@GOTOFF(%ebx), %eax
+ movl %eax, 16(%esp)
+ movl $2, 12(%esp)
+ movl $2, 8(%esp)
+ leal .LC1@GOTOFF(%ebx), %eax
+ movl %eax, 4(%esp)
+ leal _ZN4_VTVI11EnvironmentE12__vtable_mapE@GOTOFF(%ebx), %eax
+ movl %eax, (%esp)
+ movl _ZTV15EnvironmentImpl@GOT(%ebx), %eax
+ leal 8(%eax), %eax
+ movl %eax, 12(%esp)
+ movl $1, 8(%esp)
+ leal .LC2@GOTOFF(%ebx), %eax
+ movl %eax, 4(%esp)
+ leal _ZN4_VTVI15EnvironmentImplE12__vtable_mapE@GOTOFF(%ebx), %eax
+ movl %eax, (%esp)
+ call _Z17__VLTRegisterPairPPvPKvjS2_@PLT
+ addl $36, %esp
+ popl %ebx
+ .cfi_restore 3
+ popl %ebp
+ .cfi_restore 5
+ .cfi_def_cfa 4, 4
+ ret
+ .cfi_endproc
+.LFE17:
+ .size _GLOBAL__sub_I.00099_environment.cc, .-_GLOBAL__sub_I.00099_environment.cc
+ .section .init_array.00099,"aw"
+ .align 4
+ .long _GLOBAL__sub_I.00099_environment.cc
+ .section .text.__x86.get_pc_thunk.cx,"axG",@progbits,__x86.get_pc_thunk.cx,comdat
+ .globl __x86.get_pc_thunk.cx
+ .hidden __x86.get_pc_thunk.cx
+ .type __x86.get_pc_thunk.cx, @function
+__x86.get_pc_thunk.cx:
+.LFB18:
+ .cfi_startproc
+ movl (%esp), %ecx
+ ret
+ .cfi_endproc
+.LFE18:
+ .section .text.__x86.get_pc_thunk.bx,"axG",@progbits,__x86.get_pc_thunk.bx,comdat
+ .globl __x86.get_pc_thunk.bx
+ .hidden __x86.get_pc_thunk.bx
+ .type __x86.get_pc_thunk.bx, @function
+__x86.get_pc_thunk.bx:
+.LFB19:
+ .cfi_startproc
+ movl (%esp), %ebx
+ ret
+ .cfi_endproc
+.LFE19:
+ .hidden DW.ref.__gxx_personality_v0
+ .weak DW.ref.__gxx_personality_v0
+ .section .data.DW.ref.__gxx_personality_v0,"awG",@progbits,DW.ref.__gxx_personality_v0,comdat
+ .align 4
+ .type DW.ref.__gxx_personality_v0, @object
+ .size DW.ref.__gxx_personality_v0, 4
+DW.ref.__gxx_personality_v0:
+ .long __gxx_personality_v0
+ .ident "GCC: (GNU) 4.9.0 20130616 (experimental)"
+ .section .note.GNU-stack,"",@progbits
diff --git a/libvtv/testsuite/other-tests/environment-fail-64.s b/libvtv/testsuite/other-tests/environment-fail-64.s
new file mode 100644
index 00000000000..d75db248b07
--- /dev/null
+++ b/libvtv/testsuite/other-tests/environment-fail-64.s
@@ -0,0 +1,425 @@
+ .file "environment.cc"
+ .section .text._ZN15EnvironmentImpl6GetVarEPKcPc,"axG",@progbits,_ZN15EnvironmentImpl6GetVarEPKcPc,comdat
+ .align 2
+ .weak _ZN15EnvironmentImpl6GetVarEPKcPc
+ .type _ZN15EnvironmentImpl6GetVarEPKcPc, @function
+_ZN15EnvironmentImpl6GetVarEPKcPc:
+.LFB0:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ movq %rdi, -8(%rbp)
+ movq %rsi, -16(%rbp)
+ movq %rdx, -24(%rbp)
+ movl $1, %eax
+ popq %rbp
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE0:
+ .size _ZN15EnvironmentImpl6GetVarEPKcPc, .-_ZN15EnvironmentImpl6GetVarEPKcPc
+ .text
+ .align 2
+ .globl _ZN11EnvironmentD2Ev
+ .type _ZN11EnvironmentD2Ev, @function
+_ZN11EnvironmentD2Ev:
+.LFB2:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ subq $16, %rsp
+ movq %rdi, -8(%rbp)
+ movq -8(%rbp), %rax
+ movq _ZTV11Environment@GOTPCREL(%rip), %rdx
+ leaq 16(%rdx), %rdx
+ movq %rdx, (%rax)
+ movl $0, %eax
+ testl %eax, %eax
+ je .L3
+ movq -8(%rbp), %rax
+ movq %rax, %rdi
+ call _ZdlPv@PLT
+.L3:
+ leave
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE2:
+ .size _ZN11EnvironmentD2Ev, .-_ZN11EnvironmentD2Ev
+ .globl _ZN11EnvironmentD1Ev
+ .set _ZN11EnvironmentD1Ev,_ZN11EnvironmentD2Ev
+ .align 2
+ .globl _ZN11EnvironmentD0Ev
+ .type _ZN11EnvironmentD0Ev, @function
+_ZN11EnvironmentD0Ev:
+.LFB4:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ subq $16, %rsp
+ movq %rdi, -8(%rbp)
+ movq -8(%rbp), %rax
+ movq %rax, %rdi
+ call _ZN11EnvironmentD1Ev@PLT
+ movq -8(%rbp), %rax
+ movq %rax, %rdi
+ call _ZdlPv@PLT
+ leave
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE4:
+ .size _ZN11EnvironmentD0Ev, .-_ZN11EnvironmentD0Ev
+ .section .text._ZN11EnvironmentC2Ev,"axG",@progbits,_ZN11EnvironmentC5Ev,comdat
+ .align 2
+ .weak _ZN11EnvironmentC2Ev
+ .type _ZN11EnvironmentC2Ev, @function
+_ZN11EnvironmentC2Ev:
+.LFB8:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ movq %rdi, -8(%rbp)
+ movq -8(%rbp), %rax
+ movq _ZTV11Environment@GOTPCREL(%rip), %rdx
+ leaq 16(%rdx), %rdx
+ movq %rdx, (%rax)
+ popq %rbp
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE8:
+ .size _ZN11EnvironmentC2Ev, .-_ZN11EnvironmentC2Ev
+ .weak _ZN11EnvironmentC1Ev
+ .set _ZN11EnvironmentC1Ev,_ZN11EnvironmentC2Ev
+ .section .text._ZN15EnvironmentImplC2Ev,"axG",@progbits,_ZN15EnvironmentImplC5Ev,comdat
+ .align 2
+ .weak _ZN15EnvironmentImplC2Ev
+ .type _ZN15EnvironmentImplC2Ev, @function
+_ZN15EnvironmentImplC2Ev:
+.LFB10:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ subq $16, %rsp
+ movq %rdi, -8(%rbp)
+ movq -8(%rbp), %rax
+ movq %rax, %rdi
+ call _ZN11EnvironmentC2Ev@PLT
+ movq -8(%rbp), %rax
+ movq _ZTV15EnvironmentImpl@GOTPCREL(%rip), %rdx
+ leaq 16(%rdx), %rdx
+ movq %rdx, (%rax)
+ leave
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE10:
+ .size _ZN15EnvironmentImplC2Ev, .-_ZN15EnvironmentImplC2Ev
+ .weak _ZN15EnvironmentImplC1Ev
+ .set _ZN15EnvironmentImplC1Ev,_ZN15EnvironmentImplC2Ev
+ .text
+ .align 2
+ .globl _ZN11Environment6CreateEv
+ .type _ZN11Environment6CreateEv, @function
+_ZN11Environment6CreateEv:
+.LFB5:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ pushq %rbx
+ subq $8, %rsp
+ .cfi_offset 3, -24
+ movl $8, %edi
+ call _Znwm@PLT
+ movq %rax, %rbx
+ movq $0, (%rbx)
+ movq %rbx, %rdi
+ call _ZN15EnvironmentImplC1Ev@PLT
+ movq %rbx, %rax
+ addq $8, %rsp
+ popq %rbx
+ popq %rbp
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE5:
+ .size _ZN11Environment6CreateEv, .-_ZN11Environment6CreateEv
+ .section .rodata
+.LC0:
+ .string "%p\n"
+ .text
+ .globl main
+ .type main, @function
+main:
+.LFB12:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ subq $16, %rsp
+ movq $0, -8(%rbp)
+ call _ZN11Environment6CreateEv@PLT
+ movq %rax, -16(%rbp)
+ movq -16(%rbp), %rax
+ movq (%rax), %rax
+ movq %rax, %rsi
+ leaq _ZN4_VTVI11EnvironmentE12__vtable_mapE(%rip), %rdi
+ call _Z24__VLTVerifyVtablePointerPPvPKv@PLT
+ addq $16, %rax
+ movq (%rax), %rax
+ movq -8(%rbp), %rdx
+ movq -16(%rbp), %rcx
+ movl $0, %esi
+ movq %rcx, %rdi
+ call *%rax
+ movq -16(%rbp), %rax
+ movq %rax, %rsi
+ leaq .LC0(%rip), %rdi
+ movl $0, %eax
+ call printf@PLT
+ movl $0, %eax
+ leave
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE12:
+ .size main, .-main
+ .weak _ZTV11Environment
+ .section .data.rel.ro._ZTV11Environment,"awG",@progbits,_ZTV11Environment,comdat
+ .align 32
+ .type _ZTV11Environment, @object
+ .size _ZTV11Environment, 40
+_ZTV11Environment:
+ .quad 0
+ .quad _ZTI11Environment
+ .quad _ZN11EnvironmentD1Ev
+ .quad _ZN11EnvironmentD0Ev
+ .quad __cxa_pure_virtual
+ .weak _ZTV15EnvironmentImpl
+ .section .data.rel.ro._ZTV15EnvironmentImpl,"awG",@progbits,_ZTV15EnvironmentImpl,comdat
+ .align 32
+ .type _ZTV15EnvironmentImpl, @object
+ .size _ZTV15EnvironmentImpl, 40
+_ZTV15EnvironmentImpl:
+ .quad 0
+ .quad _ZTI15EnvironmentImpl
+ .quad _ZN15EnvironmentImplD1Ev
+ .quad _ZN15EnvironmentImplD0Ev
+ .quad _ZN15EnvironmentImpl6GetVarEPKcPc
+ .section .text._ZN15EnvironmentImplD2Ev,"axG",@progbits,_ZN15EnvironmentImplD5Ev,comdat
+ .align 2
+ .weak _ZN15EnvironmentImplD2Ev
+ .type _ZN15EnvironmentImplD2Ev, @function
+_ZN15EnvironmentImplD2Ev:
+.LFB14:
+ .cfi_startproc
+ .cfi_personality 0x9b,DW.ref.__gxx_personality_v0
+ .cfi_lsda 0x1b,.LLSDA14
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ subq $16, %rsp
+ movq %rdi, -8(%rbp)
+ movq -8(%rbp), %rax
+ movq _ZTV15EnvironmentImpl@GOTPCREL(%rip), %rdx
+ leaq 16(%rdx), %rdx
+ movq %rdx, (%rax)
+ movq -8(%rbp), %rax
+ movq %rax, %rdi
+.LEHB0:
+ call _ZN11EnvironmentD2Ev@PLT
+.LEHE0:
+ movl $0, %eax
+ testl %eax, %eax
+ je .L19
+ movq -8(%rbp), %rax
+ movq %rax, %rdi
+ call _ZdlPv@PLT
+ jmp .L19
+.L18:
+ movq %rax, %rdi
+.LEHB1:
+ call _Unwind_Resume@PLT
+.LEHE1:
+.L19:
+ leave
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE14:
+ .globl __gxx_personality_v0
+ .section .gcc_except_table._ZN15EnvironmentImplD2Ev,"aG",@progbits,_ZN15EnvironmentImplD5Ev,comdat
+.LLSDA14:
+ .byte 0xff
+ .byte 0xff
+ .byte 0x1
+ .uleb128 .LLSDACSE14-.LLSDACSB14
+.LLSDACSB14:
+ .uleb128 .LEHB0-.LFB14
+ .uleb128 .LEHE0-.LEHB0
+ .uleb128 .L18-.LFB14
+ .uleb128 0
+ .uleb128 .LEHB1-.LFB14
+ .uleb128 .LEHE1-.LEHB1
+ .uleb128 0
+ .uleb128 0
+.LLSDACSE14:
+ .section .text._ZN15EnvironmentImplD2Ev,"axG",@progbits,_ZN15EnvironmentImplD5Ev,comdat
+ .size _ZN15EnvironmentImplD2Ev, .-_ZN15EnvironmentImplD2Ev
+ .weak _ZN15EnvironmentImplD1Ev
+ .set _ZN15EnvironmentImplD1Ev,_ZN15EnvironmentImplD2Ev
+ .section .text._ZN15EnvironmentImplD0Ev,"axG",@progbits,_ZN15EnvironmentImplD0Ev,comdat
+ .align 2
+ .weak _ZN15EnvironmentImplD0Ev
+ .type _ZN15EnvironmentImplD0Ev, @function
+_ZN15EnvironmentImplD0Ev:
+.LFB16:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ subq $16, %rsp
+ movq %rdi, -8(%rbp)
+ movq -8(%rbp), %rax
+ movq %rax, %rdi
+ call _ZN15EnvironmentImplD1Ev@PLT
+ movq -8(%rbp), %rax
+ movq %rax, %rdi
+ call _ZdlPv@PLT
+ leave
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE16:
+ .size _ZN15EnvironmentImplD0Ev, .-_ZN15EnvironmentImplD0Ev
+ .weak _ZTS15EnvironmentImpl
+ .section .rodata._ZTS15EnvironmentImpl,"aG",@progbits,_ZTS15EnvironmentImpl,comdat
+ .align 16
+ .type _ZTS15EnvironmentImpl, @object
+ .size _ZTS15EnvironmentImpl, 18
+_ZTS15EnvironmentImpl:
+ .string "15EnvironmentImpl"
+ .weak _ZTI15EnvironmentImpl
+ .section .data.rel.ro._ZTI15EnvironmentImpl,"awG",@progbits,_ZTI15EnvironmentImpl,comdat
+ .align 16
+ .type _ZTI15EnvironmentImpl, @object
+ .size _ZTI15EnvironmentImpl, 24
+_ZTI15EnvironmentImpl:
+ .quad _ZTVN10__cxxabiv120__si_class_type_infoE+16
+ .quad _ZTS15EnvironmentImpl
+ .quad _ZTI11Environment
+ .weak _ZTI11Environment
+ .section .data.rel.ro._ZTI11Environment,"awG",@progbits,_ZTI11Environment,comdat
+ .align 16
+ .type _ZTI11Environment, @object
+ .size _ZTI11Environment, 16
+_ZTI11Environment:
+ .quad _ZTVN10__cxxabiv117__class_type_infoE+16
+ .quad _ZTS11Environment
+ .weak _ZTS11Environment
+ .section .rodata._ZTS11Environment,"aG",@progbits,_ZTS11Environment,comdat
+ .type _ZTS11Environment, @object
+ .size _ZTS11Environment, 14
+_ZTS11Environment:
+ .string "11Environment"
+ .hidden _ZN4_VTVI11EnvironmentE12__vtable_mapE
+ .weak _ZN4_VTVI11EnvironmentE12__vtable_mapE
+ .section .vtable_map_vars,"awG",@progbits,_ZN4_VTVI11EnvironmentE12__vtable_mapE,comdat
+ .align 8
+ .type _ZN4_VTVI11EnvironmentE12__vtable_mapE, @gnu_unique_object
+ .size _ZN4_VTVI11EnvironmentE12__vtable_mapE, 8
+_ZN4_VTVI11EnvironmentE12__vtable_mapE:
+ .zero 8
+ .hidden _ZN4_VTVI15EnvironmentImplE12__vtable_mapE
+ .weak _ZN4_VTVI15EnvironmentImplE12__vtable_mapE
+ .section .vtable_map_vars,"awG",@progbits,_ZN4_VTVI15EnvironmentImplE12__vtable_mapE,comdat
+ .align 8
+ .type _ZN4_VTVI15EnvironmentImplE12__vtable_mapE, @gnu_unique_object
+ .size _ZN4_VTVI15EnvironmentImplE12__vtable_mapE, 8
+_ZN4_VTVI15EnvironmentImplE12__vtable_mapE:
+ .zero 8
+ .section .data.rel.ro,"aw",@progbits
+ .align 16
+ .type __vptr_array_11Environment, @object
+ .size __vptr_array_11Environment, 16
+__vptr_array_11Environment:
+ .quad _ZTV11Environment+16
+ .quad _ZTV15EnvironmentImpl+16
+ .section .rodata
+ .align 8
+.LC1:
+ .string "&"
+ .string ""
+ .string ""
+ .ascii "\224\tl\022_ZN4_VTVI11EnvironmentE12__vtable_mapE"
+ .align 8
+.LC2:
+ .string "*"
+ .string ""
+ .string ""
+ .ascii "N\225\r\334_ZN4_VTVI15EnvironmentImplE12__vtable_mapE"
+ .text
+ .type _GLOBAL__sub_I.00099_environment.cc, @function
+_GLOBAL__sub_I.00099_environment.cc:
+.LFB17:
+ .cfi_startproc
+ pushq %rbp
+ .cfi_def_cfa_offset 16
+ .cfi_offset 6, -16
+ movq %rsp, %rbp
+ .cfi_def_cfa_register 6
+ leaq __vptr_array_11Environment(%rip), %r8
+ movl $2, %ecx
+ movl $2, %edx
+ leaq .LC1(%rip), %rsi
+ leaq _ZN4_VTVI11EnvironmentE12__vtable_mapE(%rip), %rdi
+ movq _ZTV15EnvironmentImpl@GOTPCREL(%rip), %rax
+ leaq 16(%rax), %rcx
+ movl $1, %edx
+ leaq .LC2(%rip), %rsi
+ leaq _ZN4_VTVI15EnvironmentImplE12__vtable_mapE(%rip), %rdi
+ call _Z17__VLTRegisterPairPPvPKvmS2_@PLT
+ popq %rbp
+ .cfi_def_cfa 7, 8
+ ret
+ .cfi_endproc
+.LFE17:
+ .size _GLOBAL__sub_I.00099_environment.cc, .-_GLOBAL__sub_I.00099_environment.cc
+ .section .init_array.00099,"aw"
+ .align 8
+ .quad _GLOBAL__sub_I.00099_environment.cc
+ .hidden DW.ref.__gxx_personality_v0
+ .weak DW.ref.__gxx_personality_v0
+ .section .data.DW.ref.__gxx_personality_v0,"awG",@progbits,DW.ref.__gxx_personality_v0,comdat
+ .align 8
+ .type DW.ref.__gxx_personality_v0, @object
+ .size DW.ref.__gxx_personality_v0, 8
+DW.ref.__gxx_personality_v0:
+ .quad __gxx_personality_v0
+ .ident "GCC: (GNU) 4.9.0 20130616 (experimental)"
+ .section .note.GNU-stack,"",@progbits
diff --git a/libvtv/testsuite/other-tests/field-test.cc b/libvtv/testsuite/other-tests/field-test.cc
new file mode 100644
index 00000000000..b6f34bca02c
--- /dev/null
+++ b/libvtv/testsuite/other-tests/field-test.cc
@@ -0,0 +1,94 @@
+// Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g
+// Look at assembly with: objdump -drl a.out
+
+#include <dlfcn.h>
+#include <assert.h>
+#include <stdlib.h>
+
+extern "C" int printf(const char *, ...);
+
+static int counter = 0;
+
+int i = TPID;
+struct base
+{
+ virtual void inc() { counter += i; }
+};
+
+struct derived: public base
+{
+ virtual void inc() { counter += (10*i); }
+};
+
+// We don't use this class. It is just here so that the
+// compiler does not devirtualize calls to derived::inc()
+struct derived2: public derived
+{
+ virtual void inc() { counter += (20*i); }
+};
+
+/*
+static base * bp = new base();
+static derived * dp = new derived();
+static base * dbp = new derived();
+*/
+
+struct my_struct {
+ base *bp;
+ derived *dp;
+ base *dbp;
+};
+
+typedef void * vtptr;
+
+vtptr get_vtptr(void * object_ptr)
+{
+ vtptr * object_vtptr_ptr = (vtptr *)object_ptr;
+ return *object_vtptr_ptr;
+}
+
+void set_vptr(void * object_ptr, vtptr vtp)
+{
+ vtptr * object_vtptr_ptr = (vtptr *)object_ptr;
+ *object_vtptr_ptr = vtp;
+}
+
+// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable
+void exchange_vtptr(void * object1_ptr, void * object2_ptr)
+{
+ vtptr object1_vtptr = get_vtptr(object1_ptr);
+ vtptr object2_vtptr = get_vtptr(object2_ptr);
+ set_vptr(object1_ptr, object2_vtptr);
+ set_vptr(object2_ptr, object1_vtptr);
+}
+
+main()
+{
+ int prev_counter;
+
+ struct my_struct *my_obj = (struct my_struct *) malloc (sizeof (struct my_struct));
+
+ my_obj->bp = new base();
+ my_obj->dp = new derived ();
+ my_obj->dbp = new derived ();
+
+
+ counter = 0;
+ my_obj->bp->inc();
+ my_obj->dp->inc();
+ my_obj->dbp->inc();
+ assert(counter == (TPID + 10*TPID + 10*TPID));
+
+ prev_counter = counter;
+ printf("before ex bp vptr=%x dp vptr=%x\n", get_vtptr(my_obj->bp), get_vtptr(my_obj->dp));
+ exchange_vtptr(my_obj->bp, my_obj->dp);
+ printf("after ex bp vptr=%x dp vptr=%x\n", get_vtptr(my_obj->bp), get_vtptr(my_obj->dp));
+ my_obj->bp->inc(); // This one should not abort but it is calling the wrong member
+ assert(counter == (prev_counter + 10*TPID));
+ printf("Pass first attack! Expected!\n");
+ printf("TPDI=%d counter %d\n", TPID, counter);
+ my_obj->dp->inc();
+ printf("Pass second attack! SHOULD NOT BE HERE!\n");
+ printf("TPDI=%d counter %d\n", TPID, counter);
+ exit(1);
+}
diff --git a/libvtv/testsuite/other-tests/replace-fail.cc b/libvtv/testsuite/other-tests/replace-fail.cc
new file mode 100644
index 00000000000..2b4070eec77
--- /dev/null
+++ b/libvtv/testsuite/other-tests/replace-fail.cc
@@ -0,0 +1,11 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+
+void __vtv_verify_fail (void **, void*) __attribute__((visibility ("default")));
+
+void
+__vtv_verify_fail (void **hash_table, const void *vtbl_ptr)
+{
+ fprintf (stdout, "Executing alternative failure routine.\n");
+}
diff --git a/libvtv/testsuite/other-tests/so.cc b/libvtv/testsuite/other-tests/so.cc
new file mode 100644
index 00000000000..3f0a346f1e8
--- /dev/null
+++ b/libvtv/testsuite/other-tests/so.cc
@@ -0,0 +1,93 @@
+#include <dlfcn.h>
+#include <assert.h>
+#include <unistd.h>
+#include <vtv_fail.h>
+
+extern "C" int printf(const char *, ...);
+extern "C" int sprintf(char *, const char*, ...);
+
+static int counter = 0;
+extern int failures;
+
+template <int i> struct base
+{
+ virtual char * whoami() {
+ static char sl[100];
+ sprintf(sl, "I am base %d", i);
+ return sl;
+ }
+ virtual void inc() { counter += i; }
+};
+
+template <int i> struct derived: base<i>
+{
+ virtual char * whoami() {
+ static char sl[100];
+ sprintf(sl, "I am derived %d", i);
+ return sl;
+ }
+ virtual void inc() { counter += (10*i); }
+};
+
+// We don't use this class. It is just here so that the
+// compiler does not devirtualize calls to derived::inc()
+template <int i> struct derived2: derived<i>
+{
+ virtual void inc() { counter += (20*i); }
+};
+
+static base<TPID> * bp = new base<TPID>();
+static derived<TPID> * dp = new derived<TPID>();
+static base<TPID> * dbp = new derived<TPID>();
+
+
+// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable
+static void exchange_vtptr(void * object1_ptr, void * object2_ptr)
+{
+ void ** object1_vtptr_ptr = (void **)object1_ptr;
+ void ** object2_vtptr_ptr = (void **)object2_ptr;
+ void * object1_vtptr = *object1_vtptr_ptr;
+ void * object2_vtptr = *object2_vtptr_ptr;
+ *object1_vtptr_ptr = object2_vtptr;
+ *object2_vtptr_ptr = object1_vtptr;
+}
+
+#define BUILD_NAME(NAME,ID) NAME##ID
+#define EXPAND(NAME,X) BUILD_NAME(NAME,X)
+extern "C" void EXPAND(so_entry_,TPID)(void)
+{
+ int prev_counter;
+ int prev_failures;
+
+ counter = 0;
+ bp->inc();
+ dp->inc();
+ dbp->inc();
+ assert(counter == (TPID + 10*TPID + 10*TPID));
+
+ prev_counter = counter;
+ exchange_vtptr(bp, dp);
+ bp->inc(); // This one should succeed but it is calling the wrong member
+ if (counter != (prev_counter + 10*TPID))
+ {
+ printf("TPID=%d whoami=%s wrong counter value prev_counter=%d counter=%d\n", TPID, bp->whoami(), prev_counter, counter);
+ sleep(2);
+ }
+ assert(counter == (prev_counter + 10*TPID));
+ // printf("Pass first attack!\n");
+
+ // This one should fail verification!. So it should jump to __vtv_verify_fail above.
+ prev_failures = failures;
+ dp->inc();
+ // this code may be executed by multiple threads at the same time. So, just verify the number of failures has
+ // increased as opposed to check for increase by 1.
+ assert(failures > prev_failures);
+ assert(counter == (prev_counter + 10*TPID + TPID));
+ // printf("TPDI=%d counter %d\n", TPID, counter);
+ // printf("Pass second attack!\n");
+
+ // restore the vtable pointers to the original state.
+ // This is very important. For some reason the dlclose is not "really" closing the library so when we reopen it we are
+ // getting the old memory state.
+ exchange_vtptr(bp, dp);
+}
diff --git a/libvtv/testsuite/other-tests/temp_deriv.cc b/libvtv/testsuite/other-tests/temp_deriv.cc
new file mode 100644
index 00000000000..ca360c0bc91
--- /dev/null
+++ b/libvtv/testsuite/other-tests/temp_deriv.cc
@@ -0,0 +1,67 @@
+// Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g
+// Look at assembly with: objdump -drl a.out
+
+#include <dlfcn.h>
+#include <assert.h>
+
+extern "C" int printf(const char *, ...);
+
+static int counter = 0;
+
+template <int i> struct base
+{
+ virtual void inc() { counter += i; }
+};
+
+template <int i> struct derived: base<i>
+{
+ virtual void inc() { counter += (10*i); }
+};
+
+// We don't use this class. It is just here so that the
+// compiler does not devirtualize calls to derived::inc()
+template <int i> struct derived2: derived<i>
+{
+ virtual void inc() { counter += (20*i); }
+};
+
+static base<TPID> * bp = new base<TPID>();
+static derived<TPID> * dp = new derived<TPID>();
+static base<TPID> * dbp = new derived<TPID>();
+
+// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable
+void exchange_vtptr(void * object1_ptr, void * object2_ptr)
+{
+ void ** object1_vtptr_ptr = (void **)object1_ptr;
+ void ** object2_vtptr_ptr = (void **)object2_ptr;
+ void * object1_vtptr = *object1_vtptr_ptr;
+ void * object2_vtptr = *object2_vtptr_ptr;
+ *object1_vtptr_ptr = object2_vtptr;
+ *object2_vtptr_ptr = object1_vtptr;
+}
+
+main()
+{
+ int prev_counter;
+
+ exchange_vtptr(bp, dp);
+ exchange_vtptr(bp, dp);
+ exchange_vtptr(bp, dbp);
+ exchange_vtptr(bp, dbp);
+
+ counter = 0;
+ bp->inc();
+ dp->inc();
+ dbp->inc();
+ assert(counter == (TPID + 10*TPID + 10*TPID));
+
+ prev_counter = counter;
+ exchange_vtptr(bp, dp);
+ bp->inc(); // This one should succeed but it is calling the wrong member
+ assert(counter == (prev_counter + 10*TPID));
+ printf("Pass first attack!\n");
+ dp->inc();
+ printf("TPDI=%d counter %d\n", TPID, counter);
+ printf("Pass second attack!\n");
+
+}
diff --git a/libvtv/testsuite/other-tests/temp_deriv2.cc b/libvtv/testsuite/other-tests/temp_deriv2.cc
new file mode 100644
index 00000000000..78b43f8b08b
--- /dev/null
+++ b/libvtv/testsuite/other-tests/temp_deriv2.cc
@@ -0,0 +1,69 @@
+// Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g
+// Look at assembly with: objdump -drl a.out
+
+#include <dlfcn.h>
+#include <assert.h>
+
+extern "C" int printf(const char *, ...);
+
+static int counter = 0;
+
+int i = TPID;
+struct base
+{
+ virtual void inc() { counter += i; }
+};
+
+struct derived: public base
+{
+ virtual void inc() { counter += (10*i); }
+};
+
+// We don't use this class. It is just here so that the
+// compiler does not devirtualize calls to derived::inc()
+struct derived2: public derived
+{
+ virtual void inc() { counter += (20*i); }
+};
+
+static base * bp = new base();
+static derived * dp = new derived();
+static base * dbp = new derived();
+
+// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable
+void exchange_vtptr(void * object1_ptr, void * object2_ptr)
+{
+ typedef void * vtptr;
+ vtptr * object1_vtptr_ptr = (vtptr *)object1_ptr;
+ vtptr * object2_vtptr_ptr = (vtptr *)object2_ptr;
+ vtptr object1_vtptr = *object1_vtptr_ptr;
+ vtptr object2_vtptr = *object2_vtptr_ptr;
+ *object1_vtptr_ptr = object2_vtptr;
+ *object2_vtptr_ptr = object1_vtptr;
+}
+
+main()
+{
+ int prev_counter;
+
+ exchange_vtptr(bp, dp);
+ exchange_vtptr(bp, dp);
+ exchange_vtptr(bp, dbp);
+ exchange_vtptr(bp, dbp);
+
+ counter = 0;
+ bp->inc();
+ dp->inc();
+ dbp->inc();
+ assert(counter == (TPID + 10*TPID + 10*TPID));
+
+ prev_counter = counter;
+ exchange_vtptr(bp, dp);
+ bp->inc(); // This one should succeed but it is calling the wrong member
+ assert(counter == (prev_counter + 10*TPID));
+ printf("Pass first attack!\n");
+ dp->inc();
+ printf("TPDI=%d counter %d\n", TPID, counter);
+ printf("Pass second attack!\n");
+
+}
diff --git a/libvtv/testsuite/other-tests/temp_deriv3.cc b/libvtv/testsuite/other-tests/temp_deriv3.cc
new file mode 100644
index 00000000000..924c47e9628
--- /dev/null
+++ b/libvtv/testsuite/other-tests/temp_deriv3.cc
@@ -0,0 +1,79 @@
+// Compile with /home/llozano/local2/proj/vtable/gcc-root/usr/local/bin/g++ -m32 -fvtable-verify=std -fpic -rdynamic -Wl,-R,/home/llozano/local2/proj/vtable/gcc-root/usr/local/lib32:./lib32 -I/home/llozano/local2/proj/vtable/vt2/gcc-4_6-mobile-vtable-security//libstdc++-v3/libsupc++ temp_deriv.cc -O0 -ldl -lpthread -Wl,--whole-archive,-lvtv_init,--no-whole-archive,-z,relro -DTPID=0 -g
+// Look at assembly with: objdump -drl a.out
+
+#include <dlfcn.h>
+#include <assert.h>
+#include <stdlib.h>
+
+extern "C" int printf(const char *, ...);
+
+static int counter = 0;
+
+int i = TPID;
+struct base
+{
+ virtual void inc() { counter += i; }
+};
+
+struct derived: public base
+{
+ virtual void inc() { counter += (10*i); }
+};
+
+// We don't use this class. It is just here so that the
+// compiler does not devirtualize calls to derived::inc()
+struct derived2: public derived
+{
+ virtual void inc() { counter += (20*i); }
+};
+
+static base * bp = new base();
+static derived * dp = new derived();
+static base * dbp = new derived();
+
+typedef void * vtptr;
+
+vtptr get_vtptr(void * object_ptr)
+{
+ vtptr * object_vtptr_ptr = (vtptr *)object_ptr;
+ return *object_vtptr_ptr;
+}
+
+void set_vptr(void * object_ptr, vtptr vtp)
+{
+ vtptr * object_vtptr_ptr = (vtptr *)object_ptr;
+ *object_vtptr_ptr = vtp;
+}
+
+// Given 2 pointers to C++ objects (non PODs), exchange the pointers to vtable
+void exchange_vtptr(void * object1_ptr, void * object2_ptr)
+{
+ vtptr object1_vtptr = get_vtptr(object1_ptr);
+ vtptr object2_vtptr = get_vtptr(object2_ptr);
+ set_vptr(object1_ptr, object2_vtptr);
+ set_vptr(object2_ptr, object1_vtptr);
+}
+
+main()
+{
+ int prev_counter;
+
+ counter = 0;
+ bp->inc();
+ dp->inc();
+ dbp->inc();
+ assert(counter == (TPID + 10*TPID + 10*TPID));
+
+ prev_counter = counter;
+ printf("before ex bp vptr=%x dp vptr=%x\n", get_vtptr(bp), get_vtptr(dp));
+ exchange_vtptr(bp, dp);
+ printf("after ex bp vptr=%x dp vptr=%x\n", get_vtptr(bp), get_vtptr(dp));
+ bp->inc(); // This one should not abort but it is calling the wrong member
+ assert(counter == (prev_counter + 10*TPID));
+ printf("Pass first attack! Expected!\n");
+ printf("TPDI=%d counter %d\n", TPID, counter);
+ dp->inc();
+ printf("Pass second attack! SHOULD NOT BE HERE!\n");
+ printf("TPDI=%d counter %d\n", TPID, counter);
+ exit(1);
+}
diff --git a/libvtv/vtv_fail.cc b/libvtv/vtv_fail.cc
new file mode 100644
index 00000000000..4f183d8cac2
--- /dev/null
+++ b/libvtv/vtv_fail.cc
@@ -0,0 +1,233 @@
+/* Copyright (C) 2012-2013
+ Free Software Foundation
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file is part of the vtable security feature implementation.
+ The vtable security feature is designed to detect when a virtual
+ call is about to be made through an invalid vtable pointer
+ (possibly due to data corruption or malicious attacks).
+
+ This file also contains the failure functions that get called when
+ a vtable pointer is not found in the data set. Two particularly
+ important functions are __vtv_verify_fail and __vtv_really_fail.
+ They are both externally visible. __vtv_verify_fail is defined in
+ such a way that it can be replaced by a programmer, if desired. It
+ is the function that __VLTVerifyVtablePointer calls if it can't
+ find the pointer in the data set. Allowing the programmer to
+ overwrite this function means that he/she can do some alternate
+ verification, including NOT failing in certain specific cases, if
+ desired. This may be the case if the programmer has to deal wtih
+ unverified third party software, for example. __vtv_really_fail is
+ available for the programmer to call from his version of
+ __vtv_verify_fail, if he decides the failure is real.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <execinfo.h>
+#include <unistd.h>
+
+#include "vtv_utils.h"
+#include "vtv_fail.h"
+
+/* This is used to disable aborts for debugging purposes. */
+bool vtv_no_abort = false;
+
+
+extern "C" {
+
+ /* __fortify_fail is a function in glibc that calls __libc_message,
+ causing it to print out a program termination error message
+ (including the name of the binary being terminated), a stack
+ trace where the error occurred, and a memory map dump. Ideally
+ we would have called __libc_message directly, but that function
+ does not appear to be accessible to functions outside glibc,
+ whereas __fortify_fail is. We call __fortify_fail from
+ __vtv_really_fail. We looked at calling __libc_fatal, which is
+ externally accessible, but it does not do the back trace and
+ memory dump. */
+
+ extern void __fortify_fail (const char *) __attribute__((noreturn));
+
+} /* extern "C" */
+
+const unsigned long SET_HANDLE_HANDLE_BIT = 0x2;
+
+/* Instantiate the template classes (in vtv_set.h) for our particular
+ hash table needs. */
+typedef void * vtv_set_handle;
+typedef vtv_set_handle * vtv_set_handle_handle;
+
+static int vtv_failures_log_fd = -1;
+
+/* Open error logging file, if not already open, and write vtable
+ verification failure messages (LOG_MSG) to the log file. Also
+ generate a backtrace in the log file, if GENERATE_BACKTRACE is
+ set. */
+
+static void
+log_error_message (const char *log_msg, bool generate_backtrace)
+{
+ if (vtv_failures_log_fd == -1)
+ vtv_failures_log_fd = vtv_open_log ("vtable_verification_failures.log");
+
+ if (vtv_failures_log_fd == -1)
+ return;
+
+ vtv_add_to_log (vtv_failures_log_fd, "%s", log_msg);
+
+ if (generate_backtrace)
+ {
+#define STACK_DEPTH 20
+ void *callers[STACK_DEPTH];
+ int actual_depth = backtrace (callers, STACK_DEPTH);
+ backtrace_symbols_fd (callers, actual_depth, vtv_failures_log_fd);
+ }
+}
+
+/* In the case where a vtable map variable is the only instance of the
+ variable we have seen, it points directly to the set of valid
+ vtable pointers. All subsequent instances of the 'same' vtable map
+ variable point to the first vtable map variable. This function,
+ given a vtable map variable PTR, checks a bit to see whether it's
+ pointing directly to the data set or to the first vtable map
+ variable. */
+
+static inline bool
+is_set_handle_handle (void * ptr)
+{
+ return ((unsigned long) ptr & SET_HANDLE_HANDLE_BIT)
+ == SET_HANDLE_HANDLE_BIT;
+}
+
+/* Returns the actual pointer value of a vtable map variable, PTR (see
+ comments for is_set_handle_handle for more details). */
+
+static inline vtv_set_handle *
+ptr_from_set_handle_handle (void * ptr)
+{
+ return (vtv_set_handle *) ((unsigned long) ptr & ~SET_HANDLE_HANDLE_BIT);
+}
+
+/* Given a vtable map variable, PTR, this function sets the bit that
+ says this is the second (or later) instance of a vtable map
+ variable. */
+
+static inline vtv_set_handle_handle
+set_handle_handle (vtv_set_handle * ptr)
+{
+ return (vtv_set_handle_handle) ((unsigned long) ptr | SET_HANDLE_HANDLE_BIT);
+}
+
+/* This function is called from __VLTVerifyVtablePointerDebug; it
+ sends as much debugging information as it can to the error log
+ file, then calls __vtv_verify_fail. SET_HANDLE_PTR is the pointer
+ to the set of valid vtable pointers, VTBL_PTR is the pointer that
+ was not found in the set, and DEBUG_MSG is the message to be
+ written to the log file before failing. n */
+
+void
+__vtv_verify_fail_debug (void **set_handle_ptr, const void *vtbl_ptr,
+ const char *debug_msg)
+{
+ log_error_message (debug_msg, false);
+
+ /* Call the public interface in case it has been overwritten by
+ user. */
+ __vtv_verify_fail (set_handle_ptr, vtbl_ptr);
+
+ log_error_message ("Returned from __vtv_verify_fail."
+ " Secondary verification succeeded.\n", false);
+}
+
+/* This function calls __fortify_fail with a FAILURE_MSG and then
+ calls abort. */
+
+void
+__vtv_really_fail (const char *failure_msg)
+{
+ __fortify_fail (failure_msg);
+
+ /* We should never get this far; __fortify_fail calls __libc_message
+ which prints out a back trace and a memory dump and then is
+ supposed to call abort, but let's play it safe anyway and call abort
+ ourselves. */
+ abort ();
+}
+
+/* This function takes an error MSG, a vtable map variable
+ (DATA_SET_PTR) and a vtable pointer (VTBL_PTR). It is called when
+ an attempt to verify VTBL_PTR with the set pointed to by
+ DATA_SET_PTR failed. It outputs a failure message with the
+ addresses involved, and calls __vtv_really_fail. */
+
+static void
+vtv_fail (const char *msg, void **data_set_ptr, const void *vtbl_ptr)
+{
+ char buffer[128];
+ int buf_len;
+ const char *format_str =
+ "*** Unable to verify vtable pointer (%p) in set (%p) *** \n";
+
+ snprintf (buffer, sizeof (buffer), format_str, vtbl_ptr,
+ is_set_handle_handle(*data_set_ptr) ?
+ ptr_from_set_handle_handle (*data_set_ptr) :
+ *data_set_ptr);
+ buf_len = strlen (buffer);
+ /* Send this to to stderr. */
+ write (2, buffer, buf_len);
+
+ if (!vtv_no_abort)
+ __vtv_really_fail (msg);
+}
+
+/* Send information about what we were trying to do when verification
+ failed to the error log, then call vtv_fail. This function can be
+ overwritten/replaced by the user, to implement a secondary
+ verification function instead. DATA_SET_PTR is the vtable map
+ variable used for the failed verification, and VTBL_PTR is the
+ vtable pointer that was not found in the set. */
+
+void
+__vtv_verify_fail (void **data_set_ptr, const void *vtbl_ptr)
+{
+ char log_msg[256];
+ snprintf (log_msg, sizeof (log_msg), "Looking for vtable %p in set %p.\n",
+ vtbl_ptr,
+ is_set_handle_handle (*data_set_ptr) ?
+ ptr_from_set_handle_handle (*data_set_ptr) :
+ *data_set_ptr);
+ log_error_message (log_msg, false);
+
+ const char *format_str =
+ "*** Unable to verify vtable pointer (%p) in set (%p) *** \n";
+ snprintf (log_msg, sizeof (log_msg), format_str, vtbl_ptr, *data_set_ptr);
+ log_error_message (log_msg, false);
+ log_error_message (" Backtrace: \n", true);
+
+ const char *fail_msg = "Potential vtable pointer corruption detected!!\n";
+ vtv_fail (fail_msg, data_set_ptr, vtbl_ptr);
+}
+
diff --git a/libvtv/vtv_fail.h b/libvtv/vtv_fail.h
new file mode 100644
index 00000000000..30741616a46
--- /dev/null
+++ b/libvtv/vtv_fail.h
@@ -0,0 +1,59 @@
+// Copyright (C) 2012-2013
+// Free Software Foundation
+//
+// 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 _VTV_FAIL_H
+#define _VTV_FAIL_H 1
+
+/* __vtv_really_fail prints a backtrace and a memory dump, then calls
+ abort. It is here for programmers to call, presumably from
+ __vtv_verify_fail, if they choose to overwrite the standard
+ __vtv_verify_fail with one of their own. Programmers should NOT
+ attempt to rewrite __vtv_really_fail. */
+
+extern void
+__vtv_really_fail (const char *fail_msg)
+ __attribute__ ((visibility ("default"), noreturn, nothrow));
+
+/* __vtv_verify_fail is the function that gets called if the vtable
+ verification code discovers a vtable pointer that it cannot verify
+ as valid. Normally __vtv_verify_fail calls __vtv_really_fail.
+ However programmers can write and link in their own version of
+ __vtv_verify_fail, if they wish to do some kind of secondary
+ verification, for example. The main verification code assumes that
+ IF __vtv_verify_fail returns, then some kind of secondary
+ verification was done AND that the secondary verification succeeded,
+ i.e. that the vtable pointer is actually valid and ok to use. If
+ the secondary verification fails, then __vtv_verify_fail should not
+ return. */
+
+extern void
+__vtv_verify_fail (void **data_set_ptr, const void *vtbl_pointer)
+ __attribute__((visibility ("default"), nothrow));
+
+extern void
+__vtv_verify_fail_debug (void **data_set_ptr, const void *vtbl_pointer,
+ const char *debug_msg)
+ __attribute__((visibility ("default"), nothrow));
+
+#endif /* _VTV_FAIL_H */
diff --git a/libvtv/vtv_malloc.cc b/libvtv/vtv_malloc.cc
new file mode 100644
index 00000000000..8aaa636e0e3
--- /dev/null
+++ b/libvtv/vtv_malloc.cc
@@ -0,0 +1,267 @@
+/* Copyright (C) 2012-2013
+ Free Software Foundation
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file is part of the vtable verification runtime library. It
+ contains our memory allocation and deallocation routines, which we
+ use in order to keep track of the pages in memory in which our sets
+ of valid vtable pointes are stored. (We need to know the pages so
+ we can set the protections on them appropriately). For more
+ information about the vtable verification feature, see the comments
+ in vtv_rts.cc. We use the existing obstack implementation in our
+ memory allocation scheme. */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+#include "vtv_utils.h"
+#include "vtv_malloc.h"
+#include "obstack.h"
+
+/* The following variables are used only for debugging and performance tuning
+ purposes. Therefore they do not need to be "protected". They cannot be used
+ to attack the vtable verification system and if they become corrupted it will
+ not affect the correctness or security of any of the rest of the vtable
+ verification feature. */
+
+unsigned int num_calls_to_mprotect = 0;
+unsigned int num_pages_protected = 0;
+unsigned int long long mprotect_cycles = 0;
+
+/* Put the following variables in our ".vtable_map_vars" section so
+ that they are protected. They are explicitly unprotected and
+ protected again by calls to __vtv_unprotect and __vtv_protect */
+
+static struct obstack vtv_obstack VTV_PROTECTED_VAR;
+static void *current_chunk VTV_PROTECTED_VAR = 0;
+static size_t current_chunk_size VTV_PROTECTED_VAR = 0;
+static int malloc_initialized VTV_PROTECTED_VAR = 0;
+
+/* The function goes through and counts all the pages we have allocated
+ so far. It returns the page count. */
+
+int
+__vtv_count_mmapped_pages (void)
+{
+ int count = 0;
+ struct _obstack_chunk * ci = (struct _obstack_chunk *) current_chunk;
+ while (ci)
+ {
+ count++;
+ ci = ci->prev;
+ }
+
+ return count;
+}
+
+/* This function goes through all of the pages we have allocated so
+ far and calls mprotect to change the protections on the pages,
+ according to the value of PROTECTION_FLAG. */
+
+static void
+change_protections_on_data_chunks (int protection_flag)
+{
+ struct _obstack_chunk *ci;
+ ci = (struct _obstack_chunk *) current_chunk;
+
+ while (ci)
+ {
+ /* Initial set up for mprotect call.*/
+ struct _obstack_chunk *protect_start = ci;
+ size_t chunk_size;
+ size_t total_size;
+ unsigned int num_pages_in_chunk;
+ char *next_page;
+ unsigned long long start, end;
+ int result;
+
+
+ /* As long as the next 'chunk' is adjacent to the current one,
+ keep going down the list. */
+ do
+ {
+ chunk_size = (ci->limit - (char *) ci);
+ total_size = (ci->limit - (char *) protect_start);
+ num_pages_in_chunk = chunk_size / VTV_PAGE_SIZE;
+ if (chunk_size % VTV_PAGE_SIZE > 0)
+ num_pages_in_chunk++;
+ next_page = (char *) ci + (num_pages_in_chunk * VTV_PAGE_SIZE);
+ ci = ci->prev;
+ } while (ci && (char *) ci == next_page);
+
+ VTV_DEBUG_ASSERT (((unsigned long) protect_start & (VTV_PAGE_SIZE - 1))
+ == 0);
+
+ /* Protect the contiguous chunks so far. */
+ start = rdtsc ();
+ result = mprotect (protect_start, total_size, protection_flag);
+ end = rdtsc ();
+ mprotect_cycles += end - start;
+ if (result == -1)
+ VTV_error ();
+ num_calls_to_mprotect++;
+ num_pages_protected += (total_size + VTV_PAGE_SIZE - 1)/ VTV_PAGE_SIZE;
+ }
+
+#ifdef VTV_DEBUG
+ VTV_malloc_dump_stats ();
+#endif
+}
+
+/* This function makes all of our allocated pages read-only. */
+
+void
+__vtv_malloc_protect (void)
+{
+ change_protections_on_data_chunks (PROT_READ);
+}
+
+/* This function makes all of our allocated pages read-write. */
+
+void
+__vtv_malloc_unprotect (void)
+{
+ change_protections_on_data_chunks (PROT_READ | PROT_WRITE);
+}
+
+/* Allocates a SIZE-sized chunk of memory that is aligned to a page
+ boundary. The amount of memory requested (SIZE) must be a multiple
+ of the page size. Note: We must use mmap to allocate the memory;
+ using malloc here will cause problems. */
+
+static void *
+obstack_chunk_alloc (size_t size)
+{
+ /* Increase size to the next multiple of VTV_PAGE_SIZE. */
+ size = (size + (VTV_PAGE_SIZE - 1)) & (~(VTV_PAGE_SIZE - 1));
+ VTV_DEBUG_ASSERT ((size & (VTV_PAGE_SIZE - 1)) == 0);
+ void *allocated;
+
+ if ((allocated = mmap (NULL, size, PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) == 0)
+ VTV_error ();
+
+ VTV_DEBUG_ASSERT (((unsigned long) allocated & (VTV_PAGE_SIZE - 1)) == 0);
+
+ current_chunk = allocated;
+ current_chunk_size = size;
+ return allocated;
+}
+
+static void
+obstack_chunk_free (size_t)
+{
+ /* Do nothing. For our purposes there should be very little
+ de-allocation. */
+}
+
+/* This function sets up and initializes the obstack pieces for our
+ memory allocation scheme. */
+
+void
+__vtv_malloc_init (void)
+{
+ /* Make sure we only execute the main body of this function ONCE. */
+ if (malloc_initialized)
+ return;
+
+ if (VTV_PAGE_SIZE != sysconf (_SC_PAGE_SIZE))
+ VTV_error ();
+
+ obstack_chunk_size (&vtv_obstack) = VTV_PAGE_SIZE;
+ obstack_alignment_mask (&vtv_obstack) = sizeof (long) - 1;
+ /* We guarantee that the obstack alloc failed handler will never be
+ called because in case the allocation of the chunk fails, it will
+ never return */
+ obstack_alloc_failed_handler = NULL;
+
+ obstack_init (&vtv_obstack);
+ malloc_initialized = 1;
+}
+
+/* This is our external interface for the memory allocation. SIZE is
+ the requested number of bytes to be allocated/ */
+
+void *
+__vtv_malloc (size_t size)
+{
+ return obstack_alloc (&vtv_obstack, size);
+}
+
+
+/* This is our external interface for memory deallocation. */
+
+void
+__vtv_free (void *)
+{
+ /* Do nothing. We dont care about recovering unneded memory at this
+ time. */
+}
+
+
+/* This is a debugging function tat collects statistics about our
+ memory allocation. */
+void
+__vtv_malloc_stats (void)
+{
+ int count = 0;
+ struct _obstack_chunk * ci = (struct _obstack_chunk *) current_chunk;
+ while (ci)
+ {
+ count++;
+ ci = ci->prev;
+ }
+ fprintf (stderr,
+ "__vtv_malloc_stats:\n Page Size = %lu bytes\n "
+ "Number of pages = %d\n", static_cast<unsigned long>(VTV_PAGE_SIZE),
+ count);
+}
+
+/* This is a debugging function. It writes out our memory allocation
+ statistics to a log file. */
+
+void
+__vtv_malloc_dump_stats (void)
+{
+ static int fd = -1;
+
+ if (fd == -1)
+ fd = __vtv_open_log ("vtv_mem_protection.log");
+ if (fd == -1)
+ return;
+
+ int count = 0;
+ struct _obstack_chunk * ci = (struct _obstack_chunk *) current_chunk;
+ while (ci)
+ {
+ count++;
+ ci = ci->prev;
+ }
+
+ __vtv_add_to_log (fd, "__vtv_malloc_protect protected=%d pages\n", count);
+}
diff --git a/libvtv/vtv_malloc.h b/libvtv/vtv_malloc.h
new file mode 100644
index 00000000000..55f5fe8022b
--- /dev/null
+++ b/libvtv/vtv_malloc.h
@@ -0,0 +1,98 @@
+// Copyright (C) 2012-2013
+// Free Software Foundation
+//
+// 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 _VTV_MALLOC_H
+#define _VTV_MALLOC_H 1
+
+#include <stdlib.h>
+
+/* Alignment mask for any object returned by the VTV memory pool */
+#ifdef __LP64__
+#define VTV_ALIGNMENT_MASK (0x7)
+#else
+#define VTV_ALIGNMENT_MASK (0x3)
+#endif
+
+/* The following function is used to instrument the compiler and find
+ out how many cycles are being spent in various vtable verification
+ runtime library functions. */
+
+#ifdef __x86_64__
+static inline unsigned long
+rdtsc ()
+{
+ unsigned long long hi, lo;
+
+ asm volatile ("rdtsc" : "=a" (lo), "=d" (hi));
+ return hi << 32 | lo;
+}
+#elif defined (__i386__)
+static inline unsigned long long
+rdtsc ()
+{
+ unsigned long long var;
+
+ asm volatile ("rdtsc" : "=A" (var));
+
+ return var;
+}
+#else
+static inline unsigned long long
+rdtsc ()
+{
+ /* Create an empty function for unknown architectures, so that the
+ calls to this function in vtv_malloc.cc and vtv_rts.cc do not cause
+ compilation errors. */
+ return ((unsigned long long) 0);
+}
+#endif
+
+
+/* The following variables are used only for debugging and performance tuning
+ purposes. Therefore they do not need to be "protected". They cannot be used
+ to attack the vtable verification system and if they become corrupted it will
+ not affect the correctness or security of any of the rest of the vtable
+ verification feature. */
+
+extern unsigned int num_calls_to_mprotect;
+extern unsigned int num_pages_protected;
+extern unsigned int num_calls_to_regset;
+extern unsigned int num_calls_to_regpair;
+extern unsigned long long mprotect_cycles;
+extern unsigned long long regset_cycles;
+extern unsigned long long regpair_cycles;
+
+
+/* Function declarations. */
+
+extern void __vtv_malloc_init (void);
+extern void *__vtv_malloc (size_t size) __attribute__ ((malloc));
+extern void __vtv_free (void * ptr);
+extern void __vtv_malloc_protect (void);
+extern void __vtv_malloc_unprotect (void);
+extern void __vtv_malloc_stats (void);
+extern void __vtv_malloc_dump_stats (void);
+extern int __vtv_count_mmapped_pages (void);
+
+#endif /* vtv_malloc.h */
diff --git a/libvtv/vtv_map.h b/libvtv/vtv_map.h
new file mode 100644
index 00000000000..ec058f845f7
--- /dev/null
+++ b/libvtv/vtv_map.h
@@ -0,0 +1,311 @@
+/* Copyright (C) 2012-2013
+ Free Software Foundation
+
+ 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 _VTV_MAP_H
+#define _VTV_MAP_H 1
+
+#include <string.h>
+#include <vtv_utils.h>
+
+inline uint64_t
+load8bytes (const void *p)
+{
+ uint64_t result;
+ memcpy (&result, p, 8);
+ return result;
+}
+
+/* Insert_only_hash_map maps keys to values. The implementation is a
+ basic hash table with open addressing. The keys are not "owned" by
+ the table; it only stores pointers to keys. The key type is
+ specified below (see insert_only_hash_map::key_type) and is,
+ roughly speaking, a string of any length with the string length and
+ a hash code stored at the front. The code here does not compute
+ any hash codes, but rather uses what's given. */
+
+template<typename T, typename Alloc>
+class insert_only_hash_map
+ {
+ public:
+ typedef size_t size_type;
+ typedef T value_type;
+ typedef Alloc alloc_type;
+ enum { min_capacity = 4 };
+#if HASHMAP_STATS
+ enum { stats = true };
+#else
+ enum { stats = false };
+#endif
+
+ /* Keys are a byte string (up to 2^32 - 1 long) plus a uint32_t
+ that's used as a hash code. The latter can encode arbitrary
+ information at the client's discretion, so, e.g., multiple keys
+ that are the same string still "differ" if the hash codes differ.
+ Keys are equal if the first 8 bytes are equal and the next n
+ bytes are equal. */
+ struct key_type
+ {
+ uint32_t n;
+ uint32_t hash;
+ char bytes[0];
+
+ bool
+ equals (const key_type *k) const;
+ };
+
+ /* Create an empty map with a reasonable number of buckets for the
+ expected size. Returns NULL if the allocator fails. */
+
+ static insert_only_hash_map *
+ create (size_type expected_size);
+
+ /* The opposite of create(). Free the memory for the given map. */
+
+ static void
+ destroy (insert_only_hash_map *m)
+ { Alloc().dealloc (m, m->size_in_bytes_); }
+
+ /* Return a map identical to this except that *k is mapped to v.
+ Typcially it's done by modifying this in place, but if a resize
+ is necessary then this is deallocated and a new map is returned.
+ Requires k to be non-NULL. Does nothing and returns NULL if the
+ allocator fails. */
+
+ insert_only_hash_map*
+ put (const key_type *k, const value_type &v)
+ { return this->put_internal (k, v, false); }
+
+ /* If *k is a key in this then set *v to point to the corresponding
+ value. Otherwise, do the equivalent of insert(k, value_type())
+ and, if that succeeds, set *v to point to the inserted value.
+ Requires k to be non-NULL. Does nothing and returns NULL if the
+ allocator fails. Typically returns this, but will return a new
+ insert_only_hash_map if a resize occurs. If the return value is
+ non-NULL, *v is set and it's valid until a resize of the map that
+ is the return value. */
+
+ insert_only_hash_map *
+ find_or_add_key (const key_type *k, value_type **v);
+
+ /* Get the value corresponding to *k. Returns NULL if there is
+ none. Requires k to be non-NULL. The return value is valid
+ until any resize. */
+ const value_type *get (const key_type *k) const;
+
+ size_type
+ size () const
+ { return num_entries_; }
+
+ bool
+ empty () const
+ { return this->size () == 0; }
+
+ size_type
+ bucket_count () const
+ { return num_buckets_; }
+
+ private:
+ typedef std::pair <const key_type *, value_type> bucket_type;
+
+ insert_only_hash_map *put_internal (const key_type *, const value_type &,
+ bool);
+
+ /* This function determines when to resize the table. */
+ bool
+ is_too_full (size_type entries) const
+ { return entries > (this->bucket_count () * 0.7); }
+
+ /* Return a copy with double the number of buckets. Returns NULL if
+ the allocator fails. Otherwise, calls destroy (this). */
+ insert_only_hash_map *destructive_copy ();
+
+ /* Must be a power of 2 not less than min_capacity. */
+ size_type num_buckets_;
+ size_type num_entries_;
+ size_type size_in_bytes_;
+ bucket_type buckets[0]; /* Actual array size is num_buckets. */
+};
+
+template <typename T, typename Alloc>
+insert_only_hash_map <T, Alloc> *
+insert_only_hash_map <T, Alloc>::create (size_type expected_size)
+{
+ size_t cap = min_capacity;
+ while (expected_size >= cap)
+ {
+ cap *= 2;
+ }
+ size_t size_in_bytes = sizeof (insert_only_hash_map <T, Alloc>)
+ + cap * sizeof (bucket_type);
+ insert_only_hash_map <T, Alloc>* result =
+ static_cast <insert_only_hash_map <T, Alloc>*> (Alloc ()
+ .alloc (size_in_bytes));
+ if (result != NULL)
+ {
+ result->size_in_bytes_ = size_in_bytes;
+ result->num_buckets_ = cap;
+ result->num_entries_ = 0;
+ memset (result->buckets, 0, cap * sizeof (bucket_type));
+ }
+ return result;
+}
+
+template <typename T, typename Alloc>
+insert_only_hash_map <T, Alloc>*
+insert_only_hash_map <T, Alloc>::destructive_copy ()
+{
+ insert_only_hash_map* copy = create (this->bucket_count ());
+ if (copy == NULL)
+ return NULL;
+ VTV_DEBUG_ASSERT (copy->bucket_count () == 2 * this->bucket_count ());
+ for (size_type i = 0; i < this->bucket_count (); i++)
+ if (this->buckets[i].first != NULL)
+ copy->put_internal (this->buckets[i].first, this->buckets[i].second,
+ true);
+ VTV_DEBUG_ASSERT (copy->size () == this->size ());
+ destroy (this);
+ return copy;
+}
+
+template <typename T, typename Alloc>
+insert_only_hash_map <T, Alloc>*
+insert_only_hash_map <T, Alloc>::find_or_add_key (const key_type *k,
+ value_type **v)
+{
+ /* Table size is always a power of 2. */
+ const size_type mask = this->bucket_count () - 1;
+ size_type bucket_index = k->hash & mask;
+ size_type step = 1;
+ for (;;)
+ {
+ bucket_type &bucket = this->buckets[bucket_index];
+ if (bucket.first == NULL)
+ {
+ /* Key was not present. */
+ if (this->is_too_full (this->size () + 1))
+ {
+ insert_only_hash_map <T, Alloc>* result =
+ this->destructive_copy ();
+ return result == NULL
+ ? NULL
+ : result->find_or_add_key (k, v);
+ }
+ else
+ {
+ bucket.first = k;
+ bucket.second = T ();
+ this->num_entries_++;
+ *v = &bucket.second;
+ return this;
+ }
+ }
+ else if (bucket.first->equals (k))
+ {
+ /* Key was present. */
+ *v = &bucket.second;
+ return this;
+ }
+ else
+ bucket_index = (bucket_index + step++) & mask;
+ }
+}
+
+template <typename T, typename Alloc>
+insert_only_hash_map <T, Alloc>*
+insert_only_hash_map <T, Alloc>::put_internal (
+ const insert_only_hash_map::key_type *k,
+ const insert_only_hash_map::value_type &v,
+ bool unique_key_and_resize_not_needed)
+{
+ /* Table size is always a power of 2. */
+ const size_type mask = this->bucket_count () - 1;
+ size_type bucket_index = k->hash & mask;
+ size_type step = 1;
+ for (;;)
+ {
+ bucket_type &bucket = this->buckets[bucket_index];
+ if (bucket.first == NULL)
+ {
+ /* Key was not present. */
+ if (!unique_key_and_resize_not_needed
+ && this->is_too_full (this->size () + 1))
+ {
+ insert_only_hash_map <T, Alloc>* result =
+ this->destructive_copy ();
+ return result == NULL
+ ? NULL
+ : result->put_internal (k, v, true);
+ }
+ else
+ {
+ bucket.first = k;
+ bucket.second = v;
+ this->num_entries_++;
+ return this;
+ }
+ }
+ else if (!unique_key_and_resize_not_needed && bucket.first->equals (k))
+ {
+ /* Key was present. Just change the value. */
+ bucket.second = v;
+ return this;
+ }
+ else
+ bucket_index = (bucket_index + step++) & mask;
+ }
+}
+
+template <typename T, typename Alloc>
+inline const typename insert_only_hash_map <T, Alloc>::value_type*
+insert_only_hash_map <T, Alloc>::get (const insert_only_hash_map::key_type *k)
+ const
+{
+ /* Table size is always a power of 2. */
+ const size_type mask = this->bucket_count () - 1;
+ size_type bucket_index = k->hash & mask;
+ size_type step = 1;
+ for (;;)
+ {
+ const bucket_type &bucket = this->buckets[bucket_index];
+ if (bucket.first == NULL)
+ return NULL;
+ else if (bucket.first->equals (k))
+ return &bucket.second;
+ else
+ bucket_index = (bucket_index + step++) & mask;
+ }
+}
+
+template <typename T, typename Alloc>
+inline bool
+insert_only_hash_map <T, Alloc>::key_type::equals (
+ const typename insert_only_hash_map <T, Alloc>::key_type *k) const
+{
+ const char* x = reinterpret_cast <const char *> (k);
+ const char* y = reinterpret_cast <const char *> (this);
+ return (load8bytes (x) == load8bytes (y)
+ && memcmp (x + 8, y + 8, this->n) == 0);
+}
+
+#endif /* _VTV_MAP_H */
diff --git a/libvtv/vtv_rts.cc b/libvtv/vtv_rts.cc
new file mode 100644
index 00000000000..1af000d8eb5
--- /dev/null
+++ b/libvtv/vtv_rts.cc
@@ -0,0 +1,1523 @@
+/* Copyright (C) 2012-2013
+ Free Software Foundation
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file is part of the vtable security feature implementation.
+ The vtable security feature is designed to detect when a virtual
+ call is about to be made through an invalid vtable pointer
+ (possibly due to data corruption or malicious attacks). The
+ compiler finds every virtual call, and inserts a verification call
+ before the virtual call. The verification call takes the actual
+ vtable pointer value in the object through which the virtual call
+ is being made, and compares the vtable pointer against a set of all
+ valid vtable pointers that the object could contain (this set is
+ based on the declared type of the object). If the pointer is in
+ the valid set, execution is allowed to continue; otherwise the
+ program is halted.
+
+ There are several pieces needed in order to make this work: 1. For
+ every virtual class in the program (i.e. a class that contains
+ virtual methods), we need to build the set of all possible valid
+ vtables that an object of that class could point to. This includes
+ vtables for any class(es) that inherit from the class under
+ consideration. 2. For every such data set we build up, we need a
+ way to find and reference the data set. This is complicated by the
+ fact that the real vtable addresses are not known until runtime,
+ when the program is loaded into memory, but we need to reference the
+ sets at compile time when we are inserting verification calls into
+ the program. 3. We need to find every virtual call in the program,
+ and insert the verification call (with the appropriate arguments)
+ before the virtual call. 4. We need some runtime library pieces:
+ the code to build up the data sets at runtime; the code to actually
+ perform the verification using the data sets; and some code to set
+ protections on the data sets, so they themselves do not become
+ hacker targets.
+
+ To find and reference the set of valid vtable pointers for any given
+ virtual class, we create a special global varible for each virtual
+ class. We refer to this as the "vtable map variable" for that
+ class. The vtable map variable has the type "void *", and is
+ initialized by the compiler to NULL. At runtime when the set of
+ valid vtable pointers for a virtual class, e.g. class Foo, is built,
+ the vtable map variable for class Foo is made to point to the set.
+ During compile time, when the compiler is inserting verification
+ calls into the program, it passes the vtable map variable for the
+ appropriate class to the verification call, so that at runtime the
+ verification call can find the appropriate data set.
+
+ The actual set of valid vtable pointers for a polymorphic class,
+ e.g. class Foo, cannot be built until runtime, when the vtables get
+ loaded into memory and their addresses are known. But the knowledge
+ about which vtables belong in which class' hierarchy is only known
+ at compile time. Therefore at compile time we collect class
+ hierarchy and vtable information about every virtual class, and we
+ generate calls to build up the data sets at runtime. To build the
+ data sets, we call one of the functions we add to the runtime
+ library, __VLTRegisterPair. __VLTRegisterPair takes two arguments,
+ a vtable map variable and the address of a vtable. If the vtable
+ map variable is currently NULL, it creates a new data set (hash
+ table), makes the vtable map variable point to the new data set, and
+ inserts the vtable address into the data set. If the vtable map
+ variable is not NULL, it just inserts the vtable address into the
+ data set. In order to make sure that our data sets are built before
+ any verification calls happen, we create a special constructor
+ initialization function for each compilation unit, give it a very
+ high initialization priority, and insert all of our calls to
+ __VLTRegisterPair into our special constructor initialization
+ function. */
+
+/* This file contains the main externally visible runtime library
+ functions for vtable verification: __VLTChangePermission,
+ __VLTRegisterPair, and __VLTVerifyVtablePointer. It also contains
+ debug versions __VLTRegisterPairDebug and
+ __VLTVerifyVtablePointerDebug, which have extra parameters in order
+ to make it easier to debug verification failures.
+
+ The final piece of functionality implemented in this file is symbol
+ resolution for multiple instances of the same vtable map variable.
+ If the same virtual class is used in two different compilation
+ units, then each compilation unit will create a vtable map variable
+ for the class. We need all instances of the same vtable map
+ variable to point to the same (single) set of valid vtable
+ pointers for the class, so we wrote our own hashtable-based symbol
+ resolution for vtable map variables (with a tiny optimization in
+ the case where there is only one instance of the variable).
+
+ There are two other important pieces to the runtime for vtable
+ verification besides the main pieces that go into libstdc++.so: two
+ special tiny shared libraries, libvtv_init.so and libvtv_stubs.so.
+ libvtv_init.so is built from vtv_init.cc. It is designed to help
+ minimize the calls made to mprotect (see the comments in
+ vtv_init.cc for more details). Anything compiled with
+ "-fvtable-verify=std" must be linked with libvtv_init.so (the gcc
+ driver has been modified to do this). vtv_stubs.so is built from
+ vtv_stubs.cc. It replaces the main runtime functions
+ (__VLTChangePermissino, __VLTRegisterPair and
+ __VLTVerifyVtablePointer) with stub functions that do nothing. If
+ a programmer has a library that was built with verification, but
+ wishes to not have verification turned on, the programmer can link
+ in the vtv_stubs.so library. */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <execinfo.h>
+
+#include <unistd.h>
+#include <sys/mman.h>
+#include <errno.h>
+#include <link.h>
+#include <fcntl.h>
+#include <limits.h>
+
+/* For gthreads suppport */
+#include <bits/c++config.h>
+#include <ext/concurrence.h>
+
+#include "vtv_utils.h"
+#include "vtv_malloc.h"
+#include "vtv_set.h"
+#include "vtv_map.h"
+#include "vtv_rts.h"
+#include "vtv_fail.h"
+
+#include "vtv-change-permission.h"
+
+extern "C" {
+
+ /* __fortify_fail is a function in glibc that calls __libc_message,
+ causing it to print out a program termination error message
+ (including the name of the binary being terminated), a stack
+ trace where the error occurred, and a memory map dump. Ideally
+ we would have called __libc_message directly, but that function
+ does not appear to be accessible to functions outside glibc,
+ whereas __fortify_fail is. We call __fortify_fail from
+ __vtv_really_fail. We looked at calling __libc_fatal, which is
+ externally accessible, but it does not do the back trace and
+ memory dump. */
+
+ extern void __fortify_fail (const char *) __attribute__((noreturn));
+
+} /* extern "C" */
+
+/* The following variables are used only for debugging and performance
+ tuning purposes. Therefore they do not need to be "protected".
+ They cannot be used to attack the vtable verification system and if
+ they become corrupted it will not affect the correctness or
+ security of any of the rest of the vtable verification feature. */
+
+unsigned int num_calls_to_regset = 0;
+unsigned int num_calls_to_regpair = 0;
+unsigned int num_calls_to_verify_vtable = 0;
+unsigned long long regset_cycles = 0;
+unsigned long long regpair_cycles = 0;
+unsigned long long verify_vtable_cycles = 0;
+
+/* Be careful about initialization of statics in this file. Some of
+ the routines below are called before any runtime initialization for
+ statics in this file will be done. For example, dont try to
+ initialize any of these statics with a runtime call (for ex:
+ sysconf). The initialization will happen after calls to the routines
+ to protect/unprotec the vtabla_map variables */
+
+/* No need to mark the following variables with VTV_PROTECTED_VAR.
+ These are either const or are only used for debugging/tracing.
+ debugging/tracing will not be ON on production environments */
+
+static const bool debug_hash = HASHTABLE_STATS;
+static const int debug_functions = 0;
+static const int debug_init = 0;
+static const int debug_verify_vtable = 0;
+
+#ifdef VTV_DEBUG
+static const int debug_functions = 1;
+static const int debug_init = 1;
+static const int debug_verify_vtable = 1;
+#endif
+
+/* Global file descriptor variables for logging, tracing and debugging. */
+
+static int init_log_fd = -1;
+static int verify_vtable_log_fd = -1;
+
+/* This holds a formatted error logging message, to be written to the
+ vtable verify failures log. */
+static char debug_log_message[1024];
+
+
+#ifdef __GTHREAD_MUTEX_INIT
+static __gthread_mutex_t change_permissions_lock = __GTHREAD_MUTEX_INIT;
+#else
+static __gthread_mutex_t change_permissions_lock;
+#endif
+
+
+#ifndef VTV_STATS
+#define VTV_STATS 0
+#endif
+
+#if VTV_STATS
+
+static inline unsigned long long
+get_cycle_count (void)
+{
+ return rdtsc();
+}
+
+static inline void
+accumulate_cycle_count (unsigned long long *sum, unsigned long long start)
+{
+ unsigned long long end = rdtsc();
+ *sum = *sum + (end - start);
+}
+
+static inline void
+increment_num_calls (unsigned int *num_calls)
+{
+ *num_calls = *num_calls + 1;
+}
+
+#else
+
+static inline unsigned long long
+get_cycle_count (void)
+{
+ return (unsigned long long) 0;
+}
+
+static inline void
+accumulate_cycle_count (unsigned long long *sum __attribute__((__unused__)),
+ unsigned long long start __attribute__((__unused__)))
+{
+ /* Do nothing. */
+}
+
+static inline void
+increment_num_calls (unsigned int *num_calls __attribute__((__unused__)))
+{
+ /* Do nothing. */
+}
+
+#endif
+
+/* Types needed by insert_only_hash_sets. */
+typedef uintptr_t int_vptr;
+
+/* The set of valid vtable pointers for each virtual class is stored
+ in a hash table. This is the hashing function used for the hash
+ table. For more information on the implementation of the hash
+ table, see the class insert_only_hash_sets in vtv_set.h. */
+
+struct vptr_hash
+ {
+ /* Hash function, used to convert vtable pointer, V, (a memory
+ address) into an index into the hash table. */
+ size_t
+ operator() (int_vptr v) const
+ {
+ const uint32_t x = 0x7a35e4d9;
+ const int shift = (sizeof (v) == 8) ? 23 : 21;
+ v = x * v;
+ return v ^ (v >> shift);
+ }
+ };
+
+/* This is the memory allocator used to create the hash table data
+ sets of valid vtable pointers. We use VTV_malloc in order to keep
+ track of which pages have been allocated, so we can update the
+ protections on those pages appropriately. See the class
+ insert_only_hash_sets in vtv_set.h for more information. */
+
+struct vptr_set_alloc
+ {
+ /* Memory allocator operator. N is the number of bytes to be
+ allocated. */
+ void *
+ operator() (size_t n) const
+ {
+ return __vtv_malloc (n);
+ }
+ };
+
+/* Instantiate the template classes (in vtv_set.h) for our particular
+ hash table needs. */
+typedef insert_only_hash_sets<int_vptr, vptr_hash, vptr_set_alloc> vtv_sets;
+typedef vtv_sets::insert_only_hash_set vtv_set;
+typedef vtv_set * vtv_set_handle;
+typedef vtv_set_handle * vtv_set_handle_handle;
+
+/* Records for caching the section header information that we have
+ read out of the file(s) on disk (in dl_iterate_phdr_callback), to
+ avoid having to re-open and re-read the same file multiple
+ times. */
+
+struct sect_hdr_data
+{
+ ElfW (Addr) dlpi_addr; /* The header address in the INFO record,
+ passed in from dl_iterate_phdr. */
+ ElfW (Addr) mp_low; /* Start address of the .vtable_map_vars
+ section in memory. */
+ size_t mp_size; /* Size of the .vtable_map_vars section in
+ memory. */
+};
+
+/* Array for caching the section header information, read from file,
+ to avoid re-opening and re-reading the same file over-and-over
+ again. */
+
+#define MAX_ENTRIES 250
+static struct sect_hdr_data vtv_sect_info_cache[MAX_ENTRIES] VTV_PROTECTED_VAR;
+
+unsigned int num_cache_entries VTV_PROTECTED_VAR = 0;
+
+/* This function takes the LOAD_ADDR for an object opened by the
+ dynamic loader, and checks the array of cached file data to see if
+ there is an entry with the same addres. If it finds such an entry,
+ it returns the record for that entry; otherwise it returns
+ NULL. */
+
+struct sect_hdr_data *
+search_cached_file_data (ElfW (Addr) load_addr)
+{
+ unsigned int i;
+ for (i = 0; i < num_cache_entries; ++i)
+ {
+ if (vtv_sect_info_cache[i].dlpi_addr == load_addr)
+ return &(vtv_sect_info_cache[i]);
+ }
+
+ return NULL;
+}
+
+/* This function tries to read COUNT bytes out of the file referred to
+ by FD into the buffer BUF. It returns the actual number of bytes
+ it succeeded in reading. */
+
+static size_t
+ReadPersistent (int fd, void *buf, size_t count)
+{
+ char *buf0 = (char *) buf;
+ size_t num_bytes = 0;
+ while (num_bytes < count)
+ {
+ int len;
+ len = read (fd, buf0 + num_bytes, count - num_bytes);
+ if (len < 0)
+ return -1;
+ if (len == 0)
+ break;
+ num_bytes += len;
+ }
+
+ return num_bytes;
+}
+
+/* This function tries to read COUNT bytes, starting at OFFSET from
+ the file referred to by FD, and put them into BUF. It calls
+ ReadPersistent to help it do so. It returns the actual number of
+ bytes read, or -1 if it fails altogether. */
+
+static size_t
+ReadFromOffset (int fd, void *buf, const size_t count, const off_t offset)
+{
+ off_t off = lseek (fd, offset, SEEK_SET);
+ if (off != (off_t) -1)
+ return ReadPersistent (fd, buf, count);
+ return -1;
+}
+
+/* The function takes a MESSAGE and attempts to write it to the vtable
+ memory protection log (for debugging purposes). If the file is not
+ open, it attempts to open the file first. */
+
+static void
+log_memory_protection_data (char *message)
+{
+ static int log_fd = -1;
+
+ if (log_fd == -1)
+ log_fd = __vtv_open_log ("vtv_memory_protection_data.log");
+
+ __vtv_add_to_log (log_fd, "%s", message);
+}
+
+static void
+read_section_offset_and_length (struct dl_phdr_info *info,
+ const char *sect_name,
+ int mprotect_flags,
+ off_t *sect_offset,
+ ElfW (Word) *sect_len)
+{
+ char program_name[PATH_MAX];
+ char *cptr;
+ bool found = false;
+ struct sect_hdr_data *cached_data = NULL;
+ const ElfW (Phdr) *phdr_info = info->dlpi_phdr;
+ const ElfW (Ehdr) *ehdr_info =
+ (const ElfW (Ehdr) *) (info->dlpi_addr + info->dlpi_phdr[0].p_vaddr
+ - info->dlpi_phdr[0].p_offset);
+
+
+ /* Get the name of the main executable. This may or may not include
+ arguments passed to the program. Find the first space, assume it
+ is the start of the argument list, and change it to a '\0'. */
+ snprintf (program_name, sizeof (program_name), program_invocation_name);
+
+ /* Check to see if we already have the data for this file. */
+ cached_data = search_cached_file_data (info->dlpi_addr);
+
+ if (cached_data)
+ {
+ *sect_offset = cached_data->mp_low;
+ *sect_len = cached_data->mp_size;
+ return;
+ }
+
+ /* Find the first non-escaped space in the program name and make it
+ the end of the string. */
+ cptr = strchr (program_name, ' ');
+ if (cptr != NULL && cptr[-1] != '\\')
+ cptr[0] = '\0';
+
+ if ((phdr_info->p_type == PT_PHDR || phdr_info->p_type == PT_LOAD)
+ && (ehdr_info->e_shoff && ehdr_info->e_shnum))
+ {
+ int name_len = strlen (sect_name);
+ int fd = -1;
+
+ /* Attempt to open the binary file on disk. */
+ if (strlen (info->dlpi_name) == 0)
+ {
+ /* If the constructor initialization function was put into
+ the preinit array, then this function will get called
+ while handling preinit array stuff, in which case
+ program_invocation_name has not been initialized. In
+ that case we can get the filename of the executable from
+ "/proc/self/exe". */
+ if (strlen (program_name) > 0)
+ {
+ if (phdr_info->p_type == PT_PHDR)
+ fd = open (program_name, O_RDONLY);
+ }
+ else
+ fd = open ("/proc/self/exe", O_RDONLY);
+ }
+ else
+ fd = open (info->dlpi_name, O_RDONLY);
+
+ if (fd != -1)
+ {
+ /* Find the section header information in the file. */
+ ElfW (Half) strtab_idx = ehdr_info->e_shstrndx;
+ ElfW (Shdr) shstrtab;
+ off_t shstrtab_offset = ehdr_info->e_shoff +
+ (ehdr_info->e_shentsize * strtab_idx);
+ size_t bytes_read = ReadFromOffset (fd, &shstrtab, sizeof (shstrtab),
+ shstrtab_offset);
+ VTV_ASSERT (bytes_read == sizeof (shstrtab));
+
+ ElfW (Shdr) sect_hdr;
+
+ /* This code will be needed once we have crated libvtv.so. */
+ bool is_libvtv = false;
+
+ /*
+ if (strstr (info->dlpi_name, "libvtv.so"))
+ is_libvtv = true;
+ */
+
+ /* Loop through all the section headers, looking for one whose
+ name is ".vtable_map_vars". */
+
+ for (int i = 0; i < ehdr_info->e_shnum && !found; ++i)
+ {
+ off_t offset = ehdr_info->e_shoff + (ehdr_info->e_shentsize * i);
+
+ bytes_read = ReadFromOffset (fd, &sect_hdr, sizeof (sect_hdr),
+ offset);
+
+ VTV_ASSERT (bytes_read == sizeof (sect_hdr));
+
+ char header_name[64];
+ off_t name_offset = shstrtab.sh_offset + sect_hdr.sh_name;
+
+ bytes_read = ReadFromOffset (fd, &header_name, 64, name_offset);
+
+ VTV_ASSERT (bytes_read > 0);
+
+ if (memcmp (header_name, sect_name, name_len) == 0)
+ {
+ /* We found the section; get its load offset and
+ size. */
+ *sect_offset = sect_hdr.sh_addr;
+ if (!is_libvtv)
+ *sect_len = sect_hdr.sh_size - VTV_PAGE_SIZE;
+ else
+ *sect_len = sect_hdr.sh_size;
+ found = true;
+ }
+ }
+ close (fd);
+ }
+ }
+
+ if (*sect_offset != 0 && *sect_len != 0)
+ {
+ /* Calculate the page location in memory, making sure the
+ address is page-aligned. */
+ ElfW (Addr) start_addr = (const ElfW (Addr)) info->dlpi_addr
+ + *sect_offset;
+ *sect_offset = start_addr & ~(VTV_PAGE_SIZE - 1);
+ *sect_len = *sect_len - 1;
+
+ /* Since we got this far, we must not have found these pages in
+ the cache, so add them to it. NOTE: We could get here either
+ while making everything read-only or while making everything
+ read-write. We will only update the cache if we get here on
+ a read-write (to make absolutely sure the cache is writable
+ -- also the read-write pass should come before the read-only
+ pass). */
+ if ((mprotect_flags & PROT_WRITE)
+ && num_cache_entries < MAX_ENTRIES)
+ {
+ vtv_sect_info_cache[num_cache_entries].dlpi_addr = info->dlpi_addr;
+ vtv_sect_info_cache[num_cache_entries].mp_low = *sect_offset;
+ vtv_sect_info_cache[num_cache_entries].mp_size = *sect_len;
+ num_cache_entries++;
+ }
+ }
+}
+
+/* This is the callback function used by dl_iterate_phdr (which is
+ called from vtv_unprotect_vtable_vars and vtv_protect_vtable_vars).
+ It attempts to find the binary file on disk for the INFO record
+ that dl_iterate_phdr passes in; open the binary file, and read its
+ section header information. If the file contains a
+ ".vtable_map_vars" section, read the section offset and size. Use
+ the section offset and size, in conjunction with the data in INFO
+ to locate the pages in memory where the section is. Call
+ 'mprotect' on those pages, setting the protection either to
+ read-only or read-write, depending on what's in DATA. */
+
+static int
+dl_iterate_phdr_callback (struct dl_phdr_info *info, size_t, void *data)
+{
+ int * mprotect_flags = (int *) data;
+ off_t map_sect_offset = 0;
+ ElfW (Word) map_sect_len = 0;
+ char buffer[1024];
+ char program_name[1024];
+ const char *map_sect_name = VTV_PROTECTED_VARS_SECTION;
+
+ /* Check to see if this is the record for the Linux Virtual Dynamic
+ Shared Object (linux-vdso.so.1), which exists only in memory (and
+ therefore cannot be read from disk). */
+
+ if (strcmp (info->dlpi_name, "linux-vdso.so.1") == 0)
+ return 0;
+
+ if (strlen (info->dlpi_name) == 0
+ && info->dlpi_addr != 0)
+ return 0;
+
+ /* Get the name of the main executable. This may or may not include
+ arguments passed to the program. Find the first space, assume it
+ is the start of the argument list, and change it to a '\0'. */
+ snprintf (program_name, sizeof (program_name), program_invocation_name);
+
+ read_section_offset_and_length (info, map_sect_name, *mprotect_flags,
+ &map_sect_offset, &map_sect_len);
+
+ if (debug_functions)
+ {
+ snprintf (buffer, sizeof(buffer),
+ " Looking at load module %s to change permissions to %s\n",
+ ((strlen (info->dlpi_name) == 0) ? program_name
+ : info->dlpi_name),
+ (*mprotect_flags & PROT_WRITE) ? "READ/WRITE" : "READ-ONLY");
+ log_memory_protection_data (buffer);
+ }
+
+ /* See if we actually found the section. */
+ if (map_sect_offset && map_sect_len)
+ {
+ unsigned long long start;
+ int result;
+
+ if (debug_functions)
+ {
+ snprintf (buffer, sizeof (buffer),
+ " (%s): Protecting %p to %p\n",
+ ((strlen (info->dlpi_name) == 0) ? program_name
+ : info->dlpi_name),
+ (void *) map_sect_offset,
+ (void *) (map_sect_offset + map_sect_len));
+ log_memory_protection_data (buffer);
+ }
+
+ /* Change the protections on the pages for the section. */
+
+ start = get_cycle_count ();
+ result = mprotect ((void *) map_sect_offset, map_sect_len,
+ *mprotect_flags);
+ accumulate_cycle_count (&mprotect_cycles, start);
+ if (result == -1)
+ {
+ if (debug_functions)
+ {
+ snprintf (buffer, sizeof (buffer),
+ "Failed called to mprotect for %s error: ",
+ (*mprotect_flags & PROT_WRITE) ?
+ "READ/WRITE" : "READ-ONLY");
+ log_memory_protection_data (buffer);
+ perror(NULL);
+ }
+ VTV_error();
+ }
+ else
+ {
+ if (debug_functions)
+ {
+ snprintf (buffer, sizeof (buffer),
+ "mprotect'ed range [%p, %p]\n",
+ (void *) map_sect_offset,
+ (char *) map_sect_offset + map_sect_len);
+ log_memory_protection_data (buffer);
+ }
+ }
+ increment_num_calls (&num_calls_to_mprotect);
+ /* num_pages_protected += (map_sect_len + VTV_PAGE_SIZE - 1) / VTV_PAGE_SIZE; */
+ num_pages_protected += (map_sect_len + 4096 - 1) / 4096;
+ }
+
+ return 0;
+}
+
+/* This function explicitly changes the protection (read-only or read-write)
+ on the vtv_sect_info_cache, which is used for speeding up look ups in the
+ function dl_iterate_phdr_callback. This data structure needs to be
+ explicitly made read-write before any calls to dl_iterate_phdr_callback,
+ because otherwise it may still be read-only when dl_iterate_phdr_callback
+ attempts to write to it.
+
+ More detailed explanation: dl_iterate_phdr_callback finds all the
+ .vtable_map_vars sections in all loaded objects (including the main program)
+ and (depending on where it was called from) either makes all the pages in the
+ sections read-write or read-only. The vtv_sect_info_cache should be in the
+ .vtable_map_vars section for libstdc++.so, which means that normally it would
+ be read-only until libstdc++.so is processed by dl_iterate_phdr_callback
+ (on the read-write pass), after which it will be writable. But if any loaded
+ object gets processed before libstdc++.so, it will attempt to update the
+ data cache, which will still be read-only, and cause a seg fault. Hence
+ we need a special function, called before dl_iterate_phdr_callback, that
+ will make the data cache writable. */
+
+static void
+change_protections_on_phdr_cache (int protection_flag)
+{
+ char * low_address = (char *) &(vtv_sect_info_cache);
+ size_t cache_size = MAX_ENTRIES * sizeof (struct sect_hdr_data);
+
+ low_address = (char *) ((unsigned long) low_address & ~(VTV_PAGE_SIZE - 1));
+
+ if (mprotect ((void *) low_address, cache_size, protection_flag) == -1)
+ VTV_error ();
+}
+
+/* Unprotect all the vtable map vars and other side data that is used
+ to keep the core hash_map data. All of these data have been put
+ into relro sections */
+
+static void
+vtv_unprotect_vtable_vars (void)
+{
+ int mprotect_flags;
+
+ mprotect_flags = PROT_READ | PROT_WRITE;
+ change_protections_on_phdr_cache (mprotect_flags);
+ dl_iterate_phdr (dl_iterate_phdr_callback, (void *) &mprotect_flags);
+}
+
+/* Protect all the vtable map vars and other side data that is used
+ to keep the core hash_map data. All of these data have been put
+ into relro sections */
+
+static void
+vtv_protect_vtable_vars (void)
+{
+ int mprotect_flags;
+
+ mprotect_flags = PROT_READ;
+ dl_iterate_phdr (dl_iterate_phdr_callback, (void *) &mprotect_flags);
+ change_protections_on_phdr_cache (mprotect_flags);
+}
+
+#ifndef __GTHREAD_MUTEX_INIT
+static void
+initialize_change_permissions_mutexes ()
+{
+ __GTHREAD_MUTEX_INIT_FUNCTION (&change_permissions_lock);
+}
+#endif
+
+/* Variables needed for getting the statistics about the hashtable set. */
+#if HASHTABLE_STATS
+_AtomicStatCounter stat_contains = 0;
+_AtomicStatCounter stat_insert = 0;
+_AtomicStatCounter stat_resize = 0;
+_AtomicStatCounter stat_create = 0;
+_AtomicStatCounter stat_probes_in_non_trivial_set = 0;
+_AtomicStatCounter stat_contains_size0 = 0;
+_AtomicStatCounter stat_contains_size1 = 0;
+_AtomicStatCounter stat_contains_size2 = 0;
+_AtomicStatCounter stat_contains_size3 = 0;
+_AtomicStatCounter stat_contains_size4 = 0;
+_AtomicStatCounter stat_contains_size5 = 0;
+_AtomicStatCounter stat_contains_size6 = 0;
+_AtomicStatCounter stat_contains_size7 = 0;
+_AtomicStatCounter stat_contains_size8 = 0;
+_AtomicStatCounter stat_contains_size9 = 0;
+_AtomicStatCounter stat_contains_size10 = 0;
+_AtomicStatCounter stat_contains_size11 = 0;
+_AtomicStatCounter stat_contains_size12 = 0;
+_AtomicStatCounter stat_contains_size13_or_more = 0;
+_AtomicStatCounter stat_contains_sizes = 0;
+_AtomicStatCounter stat_grow_from_size0_to_1 = 0;
+_AtomicStatCounter stat_grow_from_size1_to_2 = 0;
+_AtomicStatCounter stat_double_the_number_of_buckets = 0;
+_AtomicStatCounter stat_insert_found_hash_collision = 0;
+_AtomicStatCounter stat_contains_in_non_trivial_set = 0;
+_AtomicStatCounter stat_insert_key_that_was_already_present = 0;
+#endif
+/* Record statistics about the hash table sets, for debugging. */
+
+static void
+log_set_stats (void)
+{
+#if HASHTABLE_STATS
+ if (set_log_fd == -1)
+ set_log_fd = __vtv_open_log ("vtv_set_stats.log");
+
+ __vtv_add_to_log (set_log_fd, "---\n%s\n",
+ insert_only_hash_tables_stats().c_str());
+#endif
+}
+
+/* Change the permissions on all the pages we have allocated for the
+ data sets and all the ".vtable_map_var" sections in memory (which
+ contain our vtable map variables). PERM indicates whether to make
+ the permissions read-only or read-write. */
+
+extern "C" /* This is only being applied to __VLTChangePermission*/
+void
+__VLTChangePermission (int perm)
+{
+ if (debug_functions)
+ {
+ if (perm == __VLTP_READ_WRITE)
+ fprintf (stdout, "Changing VLT permisisons to Read-Write.\n");
+ else if (perm == __VLTP_READ_ONLY)
+ fprintf (stdout, "Changing VLT permissions to Read-only.\n");
+
+ else
+ fprintf (stdout, "Unrecognized permissions value: %d\n", perm);
+ }
+
+#ifndef __GTHREAD_MUTEX_INIT
+ static __gthread_once_t mutex_once VTV_PROTECTED_VAR = __GTHREAD_ONCE_INIT;
+
+ __gthread_once (&mutex_once, initialize_change_permissions_mutexes);
+#endif
+
+ /* Ordering of these unprotect/protect calls is very important.
+ You first need to unprotect all the map vars and side
+ structures before you do anything with the core data
+ structures (hash_maps) */
+
+ if (perm == __VLTP_READ_WRITE)
+ {
+ /* TODO: Need to revisit this code for dlopen. It most probably
+ is not unlocking the protected vtable vars after for load
+ module that is not the first load module. */
+ __gthread_mutex_lock (&change_permissions_lock);
+
+ vtv_unprotect_vtable_vars ();
+ __vtv_malloc_init ();
+ __vtv_malloc_unprotect ();
+
+ }
+ else if (perm == __VLTP_READ_ONLY)
+ {
+ if (debug_hash)
+ log_set_stats();
+
+ __vtv_malloc_protect ();
+ vtv_protect_vtable_vars ();
+
+ __gthread_mutex_unlock (&change_permissions_lock);
+ }
+}
+
+/* This is the memory allocator used to create the hash table that
+ maps from vtable map variable name to the data set that vtable map
+ variable should point to. This is part of our vtable map variable
+ symbol resolution, which is necessary because the same vtable map
+ variable may be created by multiple compilation units and we need a
+ method to make sure that all vtable map variables for a particular
+ class point to the same data set at runtime. */
+
+struct insert_only_hash_map_allocator
+ {
+ /* N is the number of bytes to allocate. */
+ void *
+ alloc (size_t n) const
+ {
+ return __vtv_malloc (n);
+ }
+
+ /* P points to the memory to be deallocated; N is the number of
+ bytes to deallocate. */
+ void
+ dealloc (void *p, size_t) const
+ {
+ __vtv_free (p);
+ }
+ };
+
+/* Explicitly instantiate this class since this file is compiled with
+ -fno-implicit-templates. These are for the hash table that is used
+ to do vtable map variable symbol resolution. */
+template class insert_only_hash_map <vtv_set_handle *,
+ insert_only_hash_map_allocator >;
+typedef insert_only_hash_map <vtv_set_handle *,
+ insert_only_hash_map_allocator > s2s;
+typedef const s2s::key_type vtv_symbol_key;
+
+static s2s * vtv_symbol_unification_map VTV_PROTECTED_VAR = NULL;
+
+const unsigned long SET_HANDLE_HANDLE_BIT = 0x2;
+
+/* In the case where a vtable map variable is the only instance of the
+ variable we have seen, it points directly to the set of valid
+ vtable pointers. All subsequent instances of the 'same' vtable map
+ variable point to the first vtable map variable. This function,
+ given a vtable map variable PTR, checks a bit to see whether it's
+ pointing directly to the data set or to the first vtable map
+ variable. */
+
+static inline bool
+is_set_handle_handle (void * ptr)
+{
+ return ((unsigned long) ptr & SET_HANDLE_HANDLE_BIT)
+ == SET_HANDLE_HANDLE_BIT;
+}
+
+/* Returns the actual pointer value of a vtable map variable, PTR (see
+ comments for is_set_handle_handle for more details). */
+
+static inline vtv_set_handle *
+ptr_from_set_handle_handle (void * ptr)
+{
+ return (vtv_set_handle *) ((unsigned long) ptr & ~SET_HANDLE_HANDLE_BIT);
+}
+
+/* Given a vtable map variable, PTR, this function sets the bit that
+ says this is the second (or later) instance of a vtable map
+ variable. */
+
+static inline vtv_set_handle_handle
+set_handle_handle (vtv_set_handle * ptr)
+{
+ return (vtv_set_handle_handle) ((unsigned long) ptr | SET_HANDLE_HANDLE_BIT);
+}
+
+static inline void
+register_set_common (void **set_handle_ptr, size_t num_args,
+ void **vtable_ptr_array, bool debug)
+{
+ /* Now figure out what pointer to use for the set pointer, for the
+ inserts. */
+ vtv_set_handle *handle_ptr = (vtv_set_handle *) set_handle_ptr;
+
+ if (debug)
+ VTV_DEBUG_ASSERT (vtv_symbol_unification_map != NULL);
+
+ if (!is_set_handle_handle (*set_handle_ptr))
+ handle_ptr = (vtv_set_handle *) set_handle_ptr;
+ else
+ handle_ptr = ptr_from_set_handle_handle (*set_handle_ptr);
+
+ /* Now we've got the set and it's initialized, add the vtable
+ pointers. */
+ for (size_t index = 0; index < num_args; ++index)
+ {
+ int_vptr vtbl_ptr = (int_vptr) vtable_ptr_array[index];
+ vtv_sets::insert (vtbl_ptr, handle_ptr);
+ }
+}
+
+static inline void
+register_pair_common (void **set_handle_ptr, const void *vtable_ptr,
+ const char *set_symbol_name, const char *vtable_name,
+ bool debug)
+{
+ /* Now we've got the set and it's initialized, add the vtable
+ pointer (assuming that it's not NULL...It may be NULL, as we may
+ have called this function merely to initialize the set
+ pointer). */
+ int_vptr vtbl_ptr = (int_vptr) vtable_ptr;
+ if (vtbl_ptr)
+ {
+ vtv_set_handle *handle_ptr = (vtv_set_handle *) set_handle_ptr;
+ if (debug)
+ VTV_DEBUG_ASSERT (vtv_symbol_unification_map != NULL);
+ if (!is_set_handle_handle (*set_handle_ptr))
+ handle_ptr = (vtv_set_handle *) set_handle_ptr;
+ else
+ handle_ptr = ptr_from_set_handle_handle (*set_handle_ptr);
+
+ vtv_sets::insert (vtbl_ptr, handle_ptr);
+ }
+
+ if (debug && debug_init)
+ {
+ if (init_log_fd == -1)
+ init_log_fd = __vtv_open_log("vtv_init.log");
+
+ __vtv_add_to_log(init_log_fd,
+ "Registered %s : %s (%p) 2 level deref = %s\n",
+ set_symbol_name, vtable_name, vtbl_ptr,
+ is_set_handle_handle(*set_handle_ptr) ? "yes" : "no" );
+ }
+}
+
+/* This routine initializes a set handle to a vtable set. It makes
+ sure that there is only one set handle for a particular set by
+ using a map from set name to pointer to set handle. Since there
+ will be multiple copies of the pointer to the set handle (one per
+ compilation unit that uses it), it makes sure to initialize all the
+ pointers to the set handle so that the set handle is unique. To
+ make this a little more efficient and avoid a level of indirection
+ in some cases, the first pointer to handle for a particular handle
+ becomes the handle itself and the other pointers will point to the
+ set handle. This is the debug version of this function, so it
+ outputs extra debugging messages and logging. SET_HANDLE_PTR is
+ the address of the vtable map variable, SET_SYMBOL_KEY is the hash
+ table key (containing the name of the map variable and the hash
+ value) and SIZE_HINT is a guess for the best initial size for the
+ set of vtable pointers that SET_HANDLE_POINTER will point to. */
+
+static inline void
+init_set_symbol_debug (void **set_handle_ptr, const void *set_symbol_key,
+ size_t size_hint)
+{
+ VTV_DEBUG_ASSERT (set_handle_ptr);
+
+ if (vtv_symbol_unification_map == NULL)
+ {
+ /* TODO: For now we have chosen 1024, but we need to come up with a
+ better initial size for this. */
+ vtv_symbol_unification_map = s2s::create (1024);
+ VTV_DEBUG_ASSERT(vtv_symbol_unification_map);
+ }
+
+ vtv_set_handle *handle_ptr = (vtv_set_handle *) set_handle_ptr;
+ vtv_symbol_key *symbol_key_ptr = (vtv_symbol_key *) set_symbol_key;
+
+ const s2s::value_type * map_value_ptr =
+ vtv_symbol_unification_map->get (symbol_key_ptr);
+ char buffer[200];
+ if (map_value_ptr == NULL)
+ {
+ if (*handle_ptr != NULL)
+ {
+ snprintf (buffer, sizeof (buffer),
+ "*** Found non-NULL local set ptr %p missing for symbol"
+ " %.*s",
+ *handle_ptr, symbol_key_ptr->n, symbol_key_ptr->bytes);
+ __vtv_log_verification_failure (buffer, true);
+ VTV_DEBUG_ASSERT (0);
+ }
+ }
+ else if (*handle_ptr != NULL &&
+ (handle_ptr != *map_value_ptr &&
+ ptr_from_set_handle_handle (*handle_ptr) != *map_value_ptr))
+ {
+ VTV_DEBUG_ASSERT (*map_value_ptr != NULL);
+ snprintf (buffer, sizeof(buffer),
+ "*** Found diffence between local set ptr %p and set ptr %p"
+ "for symbol %.*s",
+ *handle_ptr, *map_value_ptr,
+ symbol_key_ptr->n, symbol_key_ptr->bytes);
+ __vtv_log_verification_failure (buffer, true);
+ VTV_DEBUG_ASSERT (0);
+ }
+ else if (*handle_ptr == NULL)
+ {
+ /* Execution should not reach this point. */
+ }
+
+ if (*handle_ptr != NULL)
+ {
+ if (!is_set_handle_handle (*set_handle_ptr))
+ handle_ptr = (vtv_set_handle *) set_handle_ptr;
+ else
+ handle_ptr = ptr_from_set_handle_handle (*set_handle_ptr);
+ vtv_sets::resize (size_hint, handle_ptr);
+ return;
+ }
+
+ VTV_DEBUG_ASSERT (*handle_ptr == NULL);
+ if (map_value_ptr != NULL)
+ {
+ if (*map_value_ptr == handle_ptr)
+ vtv_sets::resize (size_hint, *map_value_ptr);
+ else
+ {
+ /* The one level handle to the set already exists. So, we
+ are adding one level of indirection here and we will
+ store a pointer to the one level handle here. */
+
+ vtv_set_handle_handle * handle_handle_ptr =
+ (vtv_set_handle_handle *)handle_ptr;
+ *handle_handle_ptr = set_handle_handle(*map_value_ptr);
+ VTV_DEBUG_ASSERT(*handle_handle_ptr != NULL);
+
+ /* The handle can itself be NULL if the set has only
+ been initiazlied with size hint == 1. */
+ vtv_sets::resize (size_hint, *map_value_ptr);
+ }
+ }
+ else
+ {
+ /* We will create a new set. So, in this case handle_ptr is the
+ one level pointer to the set handle. Create copy of map name
+ in case the memory where this comes from gets unmapped by
+ dlclose. */
+ size_t map_key_len = symbol_key_ptr->n + sizeof (vtv_symbol_key);
+ void *map_key = __vtv_malloc (map_key_len);
+
+ memcpy (map_key, symbol_key_ptr, map_key_len);
+
+ s2s::value_type *value_ptr;
+ vtv_symbol_unification_map =
+ vtv_symbol_unification_map->find_or_add_key ((vtv_symbol_key *)map_key,
+ &value_ptr);
+ *value_ptr = handle_ptr;
+
+ /* TODO: We should verify the return value. */
+ vtv_sets::create (size_hint, handle_ptr);
+ VTV_DEBUG_ASSERT (size_hint <= 1 || *handle_ptr != NULL);
+ }
+
+ if (debug_init)
+ {
+ if (init_log_fd == -1)
+ init_log_fd = __vtv_open_log ("vtv_init.log");
+
+ __vtv_add_to_log (init_log_fd,
+ "Init handle:%p for symbol:%.*s hash:%u size_hint:%lu"
+ "number of symbols:%lu \n",
+ set_handle_ptr, symbol_key_ptr->n,
+ symbol_key_ptr->bytes, symbol_key_ptr->hash, size_hint,
+ vtv_symbol_unification_map->size ());
+ }
+}
+
+
+/* This routine initializes a set handle to a vtable set. It makes
+ sure that there is only one set handle for a particular set by
+ using a map from set name to pointer to set handle. Since there
+ will be multiple copies of the pointer to the set handle (one per
+ compilation unit that uses it), it makes sure to initialize all the
+ pointers to the set handle so that the set handle is unique. To
+ make this a little more efficient and avoid a level of indirection
+ in some cases, the first pointer to handle for a particular handle
+ becomes the handle itself and the other pointers will point to the
+ set handle. This is the debug version of this function, so it
+ outputs extra debugging messages and logging. SET_HANDLE_PTR is
+ the address of the vtable map variable, SET_SYMBOL_KEY is the hash
+ table key (containing the name of the map variable and the hash
+ value) and SIZE_HINT is a guess for the best initial size for the
+ set of vtable pointers that SET_HANDLE_POINTER will point to. */
+
+void
+__VLTRegisterSetDebug (void **set_handle_ptr, const void *set_symbol_key,
+ size_t size_hint, size_t num_args,
+ void **vtable_ptr_array)
+{
+ unsigned long long start = get_cycle_count ();
+ increment_num_calls (&num_calls_to_regset);
+
+ VTV_DEBUG_ASSERT(set_handle_ptr != NULL);
+ init_set_symbol_debug (set_handle_ptr, set_symbol_key, size_hint);
+
+ register_set_common (set_handle_ptr, num_args, vtable_ptr_array, true);
+
+ accumulate_cycle_count (&regset_cycles, start);
+}
+
+/* This function takes a the address of a vtable map variable
+ (SET_HANDLE_PTR), a VTABLE_PTR to add to the data set, the name of
+ the vtable map variable (SET_SYMBOL_NAME) and the name of the
+ vtable (VTABLE_NAME) being pointed to. If the vtable map variable
+ is NULL it creates a new data set and initializes the variable,
+ otherwise it uses our symbol unification to find the right data
+ set; in either case it then adds the vtable pointer to the set.
+ The other two parameters are used for debugging information. */
+
+void
+__VLTRegisterPairDebug (void **set_handle_ptr, const void *set_symbol_key,
+ size_t size_hint, const void *vtable_ptr,
+ const char *set_symbol_name, const char *vtable_name)
+{
+ unsigned long long start = get_cycle_count ();
+ increment_num_calls (&num_calls_to_regpair);
+
+ VTV_DEBUG_ASSERT(set_handle_ptr != NULL);
+ init_set_symbol_debug (set_handle_ptr, set_symbol_key, size_hint);
+
+ register_pair_common (set_handle_ptr, vtable_ptr, set_symbol_name, vtable_name,
+ true);
+
+ accumulate_cycle_count (&regpair_cycles, start);
+}
+
+
+/* This is the debug version of the verification function. It takes
+ the address of a vtable map variable (SET_HANDLE_PTR) and a
+ VTABLE_PTR to validate, as well as the name of the vtable map
+ variable (SET_SYMBOL_NAME) and VTABLE_NAME, which are used for
+ debugging messages. It checks to see if VTABLE_PTR is in the set
+ pointed to by SET_HANDLE_PTR. If so, it returns VTABLE_PTR,
+ otherwise it calls __vtv_verify_fail, which usually logs error
+ messages and calls abort. */
+
+const void *
+__VLTVerifyVtablePointerDebug (void **set_handle_ptr, const void *vtable_ptr,
+ const char *set_symbol_name,
+ const char *vtable_name)
+{
+ unsigned long long start = get_cycle_count ();
+ VTV_DEBUG_ASSERT (set_handle_ptr != NULL && *set_handle_ptr != NULL);
+ int_vptr vtbl_ptr = (int_vptr) vtable_ptr;
+
+ increment_num_calls (&num_calls_to_verify_vtable);
+ vtv_set_handle *handle_ptr;
+ if (!is_set_handle_handle (*set_handle_ptr))
+ handle_ptr = (vtv_set_handle *) set_handle_ptr;
+ else
+ handle_ptr = ptr_from_set_handle_handle (*set_handle_ptr);
+
+ if (vtv_sets::contains (vtbl_ptr, handle_ptr))
+ {
+ if (debug_verify_vtable)
+ {
+ if (verify_vtable_log_fd == -1)
+ __vtv_open_log ("vtv_verify_vtable.log");
+ __vtv_add_to_log (verify_vtable_log_fd,
+ "Verified %s %s value = %p\n",
+ set_symbol_name, vtable_name, vtable_ptr);
+ }
+ }
+ else
+ {
+ /* We failed to find the vtable pointer in the set of valid
+ pointers. Log the error data and call the failure
+ function. */
+ snprintf (debug_log_message, sizeof (debug_log_message),
+ "Looking for %s in %s\n", vtable_name, set_symbol_name);
+ __vtv_verify_fail_debug (set_handle_ptr, vtable_ptr, debug_log_message);
+
+ /* Normally __vtv_verify_fail_debug will call abort, so we won't
+ execute the return below. If we get this far, the assumption
+ is that the programmer has replaced __vtv_verify_fail_debug
+ with some kind of secondary verification AND this secondary
+ verification succeeded, so the vtable pointer is valid. */
+ }
+ accumulate_cycle_count (&verify_vtable_cycles, start);
+
+ return vtable_ptr;
+}
+
+/* This routine initializes a set handle to a vtable set. It makes
+ sure that there is only one set handle for a particular set by
+ using a map from set name to pointer to set handle. Since there
+ will be multiple copies of the pointer to the set handle (one per
+ compilation unit that uses it), it makes sure to initialize all the
+ pointers to the set handle so that the set handle is unique. To
+ make this a little more efficient and avoid a level of indirection
+ in some cases, the first pointer to handle for a particular handle
+ becomes the handle itself and the other pointers will point to the
+ set handle. SET_HANDLE_PTR is the address of the vtable map
+ variable, SET_SYMBOL_KEY is the hash table key (containing the name
+ of the map variable and the hash value) and SIZE_HINT is a guess
+ for the best initial size for the set of vtable pointers that
+ SET_HANDLE_POINTER will point to.*/
+
+static inline void
+init_set_symbol (void **set_handle_ptr, const void *set_symbol_key,
+ size_t size_hint)
+{
+ vtv_set_handle *handle_ptr = (vtv_set_handle *) set_handle_ptr;
+
+ if (*handle_ptr != NULL)
+ {
+ if (!is_set_handle_handle (*set_handle_ptr))
+ handle_ptr = (vtv_set_handle *) set_handle_ptr;
+ else
+ handle_ptr = ptr_from_set_handle_handle (*set_handle_ptr);
+ vtv_sets::resize (size_hint, handle_ptr);
+ return;
+ }
+
+ if (vtv_symbol_unification_map == NULL)
+ vtv_symbol_unification_map = s2s::create (1024);
+
+ vtv_symbol_key *symbol_key_ptr = (vtv_symbol_key *) set_symbol_key;
+ const s2s::value_type *map_value_ptr =
+ vtv_symbol_unification_map->get (symbol_key_ptr);
+
+ if (map_value_ptr != NULL)
+ {
+ if (*map_value_ptr == handle_ptr)
+ vtv_sets::resize (size_hint, *map_value_ptr);
+ else
+ {
+ /* The one level handle to the set already exists. So, we
+ are adding one level of indirection here and we will
+ store a pointer to the one level pointer here. */
+ vtv_set_handle_handle *handle_handle_ptr =
+ (vtv_set_handle_handle *) handle_ptr;
+ *handle_handle_ptr = set_handle_handle (*map_value_ptr);
+ vtv_sets::resize (size_hint, *map_value_ptr);
+ }
+ }
+ else
+ {
+ /* We will create a new set. So, in this case handle_ptr is the
+ one level pointer to the set handle. Create copy of map name
+ in case the memory where this comes from gets unmapped by
+ dlclose. */
+ size_t map_key_len = symbol_key_ptr->n + sizeof (vtv_symbol_key);
+ void * map_key = __vtv_malloc (map_key_len);
+ memcpy (map_key, symbol_key_ptr, map_key_len);
+
+ s2s::value_type * value_ptr;
+ vtv_symbol_unification_map =
+ vtv_symbol_unification_map->find_or_add_key ((vtv_symbol_key *)map_key,
+ &value_ptr);
+
+ *value_ptr = handle_ptr;
+
+ /* TODO: We should verify the return value. */
+ vtv_sets::create (size_hint, handle_ptr);
+ }
+}
+
+/* This routine initializes a set handle to a vtable set. It makes
+ sure that there is only one set handle for a particular set by
+ using a map from set name to pointer to set handle. Since there
+ will be multiple copies of the pointer to the set handle (one per
+ compilation unit that uses it), it makes sure to initialize all the
+ pointers to the set handle so that the set handle is unique. To
+ make this a little more efficient and avoid a level of indirection
+ in some cases, the first pointer to handle for a particular handle
+ becomes the handle itself and the other pointers will point to the
+ set handle. SET_HANDLE_PTR is the address of the vtable map
+ variable, SET_SYMBOL_KEY is the hash table key (containing the name
+ of the map variable and the hash value) and SIZE_HINT is a guess
+ for the best initial size for the set of vtable pointers that
+ SET_HANDLE_POINTER will point to.*/
+
+
+void
+__VLTRegisterSet (void **set_handle_ptr, const void *set_symbol_key,
+ size_t size_hint, size_t num_args, void **vtable_ptr_array)
+{
+ unsigned long long start = get_cycle_count ();
+ increment_num_calls (&num_calls_to_regset);
+
+ init_set_symbol (set_handle_ptr, set_symbol_key, size_hint);
+ register_set_common (set_handle_ptr, num_args, vtable_ptr_array, false);
+
+ accumulate_cycle_count (&regset_cycles, start);
+}
+
+
+
+/* This function takes a the address of a vtable map variable
+ (SET_HANDLE_PTR) and a VTABLE_PTR. If the vtable map variable is
+ NULL it creates a new data set and initializes the variable,
+ otherwise it uses our symbol unification to find the right data
+ set; in either case it then adds the vtable pointer to the set. */
+
+void
+__VLTRegisterPair (void **set_handle_ptr, const void *set_symbol_key,
+ size_t size_hint, const void *vtable_ptr)
+{
+ unsigned long long start = get_cycle_count ();
+ increment_num_calls (&num_calls_to_regpair);
+
+ init_set_symbol (set_handle_ptr, set_symbol_key, size_hint);
+ register_pair_common (set_handle_ptr, vtable_ptr, NULL, NULL, false);
+
+ accumulate_cycle_count (&regpair_cycles, start);
+}
+
+/* This is the main verification function. It takes the address of a
+ vtable map variable (SET_HANDLE_PTR) and a VTABLE_PTR to validate.
+ It checks to see if VTABLE_PTR is in the set pointed to by
+ SET_HANDLE_PTR. If so, it returns VTABLE_PTR, otherwise it calls
+ __vtv_verify_fail, which usually logs error messages and calls
+ abort. Since this function gets called VERY frequently, it is
+ important for it to be as efficient as possible. */
+
+const void *
+__VLTVerifyVtablePointer (void ** set_handle_ptr, const void * vtable_ptr)
+{
+ unsigned long long start = get_cycle_count ();
+ int_vptr vtbl_ptr = (int_vptr) vtable_ptr;
+
+ vtv_set_handle *handle_ptr;
+ increment_num_calls (&num_calls_to_verify_vtable);
+ if (!is_set_handle_handle (*set_handle_ptr))
+ handle_ptr = (vtv_set_handle *) set_handle_ptr;
+ else
+ handle_ptr = ptr_from_set_handle_handle (*set_handle_ptr);
+
+ if (!vtv_sets::contains (vtbl_ptr, handle_ptr))
+ {
+ __vtv_verify_fail ((void **) handle_ptr, vtable_ptr);
+ /* Normally __vtv_verify_fail will call abort, so we won't
+ execute the return below. If we get this far, the assumption
+ is that the programmer has replaced __vtv_verify_fail with
+ some kind of secondary verification AND this secondary
+ verification succeeded, so the vtable pointer is valid. */
+ }
+ accumulate_cycle_count (&verify_vtable_cycles, start);
+
+ return vtable_ptr;
+}
+
+static int page_count_2 = 0;
+
+static int
+dl_iterate_phdr_count_pages (struct dl_phdr_info *info,
+ size_t unused __attribute__ ((__unused__)),
+ void *data)
+{
+ int *mprotect_flags = (int *) data;
+ off_t map_sect_offset = 0;
+ ElfW (Word) map_sect_len = 0;
+ const char *map_sect_name = VTV_PROTECTED_VARS_SECTION;
+
+ /* Check to see if this is the record for the Linux Virtual Dynamic
+ Shared Object (linux-vdso.so.1), which exists only in memory (and
+ therefore cannot be read from disk). */
+
+ if (strcmp (info->dlpi_name, "linux-vdso.so.1") == 0)
+ return 0;
+
+ if (strlen (info->dlpi_name) == 0
+ && info->dlpi_addr != 0)
+ return 0;
+
+ read_section_offset_and_length (info, map_sect_name, *mprotect_flags,
+ &map_sect_offset, &map_sect_len);
+
+ /* See if we actually found the section. */
+ if (map_sect_len)
+ page_count_2 += (map_sect_len + VTV_PAGE_SIZE - 1) / VTV_PAGE_SIZE;
+
+ return 0;
+}
+
+static void
+count_all_pages (void)
+{
+ int mprotect_flags;
+
+ mprotect_flags = PROT_READ;
+ page_count_2 = 0;
+
+ dl_iterate_phdr (dl_iterate_phdr_count_pages, (void *) &mprotect_flags);
+ page_count_2 += __vtv_count_mmapped_pages ();
+}
+
+void
+__VLTDumpStats (void)
+{
+ int log_fd = __vtv_open_log ("vtv-runtime-stats.log");
+
+ if (log_fd != -1)
+ {
+ count_all_pages ();
+ __vtv_add_to_log (log_fd,
+ "Calls: mprotect (%d) regset (%d) regpair (%d)"
+ " verify_vtable (%d)\n",
+ num_calls_to_mprotect, num_calls_to_regset,
+ num_calls_to_regpair, num_calls_to_verify_vtable);
+ __vtv_add_to_log (log_fd,
+ "Cycles: mprotect (%lld) regset (%lld) "
+ "regpair (%lld) verify_vtable (%lld)\n",
+ mprotect_cycles, regset_cycles, regpair_cycles,
+ verify_vtable_cycles);
+ __vtv_add_to_log (log_fd,
+ "Pages protected (1): %d\n", num_pages_protected);
+ __vtv_add_to_log (log_fd, "Pages protected (2): %d\n", page_count_2);
+
+ close (log_fd);
+ }
+}
+
+/* This function is called from __VLTVerifyVtablePointerDebug; it
+ sends as much debugging information as it can to the error log
+ file, then calls __vtv_verify_fail. SET_HANDLE_PTR is the pointer
+ to the set of valid vtable pointers, VTBL_PTR is the pointer that
+ was not found in the set, and DEBUG_MSG is the message to be
+ written to the log file before failing. n */
+
+void
+__vtv_verify_fail_debug (void **set_handle_ptr, const void *vtbl_ptr,
+ const char *debug_msg)
+{
+ __vtv_log_verification_failure (debug_msg, false);
+
+ /* Call the public interface in case it has been overwritten by
+ user. */
+ __vtv_verify_fail (set_handle_ptr, vtbl_ptr);
+
+ __vtv_log_verification_failure ("Returned from __vtv_verify_fail."
+ " Secondary verification succeeded.\n", false);
+}
+
+/* This function calls __fortify_fail with a FAILURE_MSG and then
+ calls abort. */
+
+void
+__vtv_really_fail (const char *failure_msg)
+{
+ __fortify_fail (failure_msg);
+
+ /* We should never get this far; __fortify_fail calls __libc_message
+ which prints out a back trace and a memory dump and then is
+ supposed to call abort, but let's play it safe anyway and call abort
+ ourselves. */
+ abort ();
+}
+
+/* This function takes an error MSG, a vtable map variable
+ (DATA_SET_PTR) and a vtable pointer (VTBL_PTR). It is called when
+ an attempt to verify VTBL_PTR with the set pointed to by
+ DATA_SET_PTR failed. It outputs a failure message with the
+ addresses involved, and calls __vtv_really_fail. */
+
+static void
+vtv_fail (const char *msg, void **data_set_ptr, const void *vtbl_ptr)
+{
+ char buffer[128];
+ int buf_len;
+ const char *format_str =
+ "*** Unable to verify vtable pointer (%p) in set (%p) *** \n";
+
+ snprintf (buffer, sizeof (buffer), format_str, vtbl_ptr,
+ is_set_handle_handle(*data_set_ptr) ?
+ ptr_from_set_handle_handle (*data_set_ptr) :
+ *data_set_ptr);
+ buf_len = strlen (buffer);
+ /* Send this to to stderr. */
+ write (2, buffer, buf_len);
+
+#ifndef VTV_NO_ABORT
+ __vtv_really_fail (msg);
+#endif
+}
+
+/* Send information about what we were trying to do when verification
+ failed to the error log, then call vtv_fail. This function can be
+ overwritten/replaced by the user, to implement a secondary
+ verification function instead. DATA_SET_PTR is the vtable map
+ variable used for the failed verification, and VTBL_PTR is the
+ vtable pointer that was not found in the set. */
+
+void
+__vtv_verify_fail (void **data_set_ptr, const void *vtbl_ptr)
+{
+ char log_msg[256];
+ snprintf (log_msg, sizeof (log_msg), "Looking for vtable %p in set %p.\n",
+ vtbl_ptr,
+ is_set_handle_handle (*data_set_ptr) ?
+ ptr_from_set_handle_handle (*data_set_ptr) :
+ *data_set_ptr);
+ __vtv_log_verification_failure (log_msg, false);
+
+ const char *format_str =
+ "*** Unable to verify vtable pointer (%p) in set (%p) *** \n";
+ snprintf (log_msg, sizeof (log_msg), format_str, vtbl_ptr, *data_set_ptr);
+ __vtv_log_verification_failure (log_msg, false);
+ __vtv_log_verification_failure (" Backtrace: \n", true);
+
+ const char *fail_msg = "Potential vtable pointer corruption detected!!\n";
+ vtv_fail (fail_msg, data_set_ptr, vtbl_ptr);
+}
diff --git a/libvtv/vtv_rts.h b/libvtv/vtv_rts.h
new file mode 100644
index 00000000000..0e2763cb404
--- /dev/null
+++ b/libvtv/vtv_rts.h
@@ -0,0 +1,50 @@
+// Copyright (C) 2012-2013
+// Free Software Foundation
+//
+// 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 _VTV_RTS_H
+#define _VTV_RTS_H 1
+
+#include <cstdlib>
+
+// These prototypes needs to be kept in sync with the compiler-generated declarations in vtable-class-hierarchy.c
+extern void
+__VLTRegisterSet(void**, const void*, std::size_t, std::size_t, void**);
+
+extern void
+__VLTRegisterSetDebug(void**, const void*, std::size_t, std::size_t, void**);
+
+extern void
+__VLTRegisterPair(void**, const void*, size_t, const void*);
+
+extern void
+__VLTRegisterPairDebug(void**, const void*, size_t, const void*,
+ const char*, const char*);
+
+extern const void*
+__VLTVerifyVtablePointer(void**, const void*);
+
+extern const void*
+__VLTVerifyVtablePointerDebug(void**, const void*, const char*, const char*);
+
+#endif /* _VTV_RTS_H */
diff --git a/libvtv/vtv_set.h b/libvtv/vtv_set.h
new file mode 100644
index 00000000000..6d0e3c97f9b
--- /dev/null
+++ b/libvtv/vtv_set.h
@@ -0,0 +1,653 @@
+/* Copyright (C) 2012-2013
+ Free Software Foundation
+
+ 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 _VTV_SET_H
+#define _VTV_SET_H 1
+
+/* Code in this file manages a collection of insert-only sets. We
+ have only tested the case where Key is uintptr_t, though it
+ theoretically should work for some other cases. All odd keys are
+ reserved, and must not be inserted into any of the sets. This code
+ is intended primarily for sets of pointers, and the code is
+ optimized for small sets (including size 0 and 1), but regardless
+ of the set size, insert() and contains() have close to O(1) speed
+ in practice.
+
+ TODO(gpike): fix this comment.
+
+ Recommended multithreaded use of a set:
+
+ For speed, we want to use a lock-free test for set membership. The
+ code handles simultaneous reads and inserts, as long as at most one
+ insertion is in progress at a time. After an insert, other threads
+ may not immediately "see" the inserted key if they perform a
+ lock-free read, so we recommend retrying, as explained below.
+
+ Also, to make data corruption less likely, we recommend using a
+ "normal" RW page as well as one or pages that are typically RO
+ but that can be switched to RW and back as needed. The latter
+ pages should contain sets. The former should contain a lock, L,
+ and an int or similar, num_writers. Then, to insert, something
+ like this would be safe:
+ o Acquire L.
+ o Increment num_writers; if that made it 1, change pages to RW.
+ o Release L.
+ o while (there are insertions to do in some set, S) {
+ acquire L;
+ do some insertions in S;
+ release L;
+ }
+ o Acquire L.
+ o Decrement num_writers; if that made it 0, change pages to RO.
+ o Release L.
+
+ And to check if the set contains some key, one could use
+ set.contains(key) ||
+ ({ Acquire L; bool b = set.contains(key); Release L; b; })
+
+ In this scheme, the number of threads with reads in progress isn't
+ tracked, so old sets can never be deleted. In addition, on some
+ architectures the intentionally racy reads might cause contains()
+ to return true when it should have returned false. This should be
+ no problem on x86, and most other machines, where reading or
+ writing an aligned uintptr_t is atomic. E.g., on those machines,
+ if *p is 0 and one thread does *p = x while another reads *p, the
+ read will see either 0 or x.
+
+ To make the above easier, the insert_only_hash_sets class provides
+ an interface to manipulate any number of hash sets. One shouldn't
+ create objects of that class, as it has no member data and its
+ methods are static.
+
+ So the recommended model is to have a single lock, a single
+ num_writers variable, and some number of sets. If lock contention
+ becomes a problem then the sets can be divided into k groups, each
+ of which has a lock and a num_writers variable; or each set can be
+ represented as a set of values that equal 0 mod m, a set of values
+ that equal 1 mod m, ..., plus a set of values that equal m-1 mod m.
+
+ However, we expect most or all uses of this code to call contains()
+ much more frequently than anything else, so lock contention is
+ likely to be low. */
+
+#include <algorithm>
+
+#ifndef HASHTABLE_STATS
+#define HASHTABLE_STATS 0
+#endif
+
+#ifndef HASHTABLE_STATS_ATOMIC
+#define HASHTABLE_STATS_ATOMIC 0
+#endif
+
+#if HASHTABLE_STATS
+#if HASHTABLE_STATS_ATOMIC
+/* Stat counters, with atomics. */
+#include <bits/atomic_word.h>
+
+typedef _Atomic_word _AtomicStatCounter;
+
+void
+inc_by (_AtomicStatCounter &stat, int amount)
+{
+ __atomic_add_fetch (&stat, amount, __ATOMIC_ACQ_REL);
+}
+
+#else
+
+/* Stat counters, but without atomics. */
+typedef int _AtomicStatCounter;
+
+void
+inc_by (_AtomicStatCounter& stat, int amount)
+{
+ stat += amount;
+}
+
+#endif
+
+
+/* Number of calls to contains(), insert(), etc. */
+extern _AtomicStatCounter stat_insert;
+extern _AtomicStatCounter stat_contains;
+extern _AtomicStatCounter stat_resize;
+extern _AtomicStatCounter stat_create;
+
+/* Sum of set size over all calls to contains(). */
+extern _AtomicStatCounter stat_contains_sizes;
+
+/* contains() calls in a set whose capacity is more than 1. */
+extern _AtomicStatCounter stat_contains_in_non_trivial_set;
+
+/* Probes in a set whose capacity is more than 1. Ideally, this will
+ be pretty close to stat_contains_in_non_trivial_set. That will
+ happen if our hash function is good and/or important keys were
+ inserted before unimportant keys. */
+extern _AtomicStatCounter stat_probes_in_non_trivial_set;
+
+/* number of calls to contains() with size=0, 1, etc. */
+extern _AtomicStatCounter stat_contains_size0;
+extern _AtomicStatCounter stat_contains_size1;
+extern _AtomicStatCounter stat_contains_size2;
+extern _AtomicStatCounter stat_contains_size3;
+extern _AtomicStatCounter stat_contains_size4;
+extern _AtomicStatCounter stat_contains_size5;
+extern _AtomicStatCounter stat_contains_size6;
+extern _AtomicStatCounter stat_contains_size7;
+extern _AtomicStatCounter stat_contains_size8;
+extern _AtomicStatCounter stat_contains_size9;
+extern _AtomicStatCounter stat_contains_size10;
+extern _AtomicStatCounter stat_contains_size11;
+extern _AtomicStatCounter stat_contains_size12;
+extern _AtomicStatCounter stat_contains_size13_or_more;
+extern _AtomicStatCounter stat_grow_from_size0_to_1;
+extern _AtomicStatCounter stat_grow_from_size1_to_2;
+extern _AtomicStatCounter stat_double_the_number_of_buckets;
+extern _AtomicStatCounter stat_insert_key_that_was_already_present;
+
+/* Hash collisions detected during insert_no_resize(). Only counts
+ hasher(k) == hasher(k'); hasher(k) % tablesize == hasher(k') %
+ tablesize is not sufficient. Will count collisions that are
+ detected during table resizes etc., so the same two keys may add to
+ this stat multiple times. */
+extern _AtomicStatCounter stat_insert_found_hash_collision;
+
+#include <string>
+
+struct insert_only_hash_sets_logger
+{
+ static char *
+ log (char c, char *buf)
+ {
+ *buf++ = c;
+ return buf;
+ }
+
+ static char *
+ log (const char *s, char *buf)
+ { return strcpy (buf, s) + strlen (s); }
+
+ static char *
+ log (_AtomicStatCounter i, char *buf)
+ {
+ if (i < 10)
+ return log ((char) ('0' + i), buf);
+ else
+ return log ((char) ('0' + i % 10), log (i / 10, buf));
+ }
+
+ static char *
+ log (const char *label, _AtomicStatCounter i, char *buf)
+ {
+ buf = log (label, buf);
+ buf = log (": ", buf);
+ buf = log (i, buf);
+ return log ('\n', buf);
+ }
+};
+
+// Write stats to the given buffer, which should be at least 4000 bytes.
+static inline void
+insert_only_hash_tables_stats (char *buf)
+{
+ buf = insert_only_hash_sets_logger::log ("insert", stat_insert, buf);
+ buf = insert_only_hash_sets_logger::log ("contains", stat_contains, buf);
+ buf = insert_only_hash_sets_logger::log ("resize", stat_resize, buf);
+ buf = insert_only_hash_sets_logger::log ("create", stat_create, buf);
+ buf = insert_only_hash_sets_logger::log ("insert_key_that_was_already_"
+ "present",
+ stat_insert_key_that_was_already_present,
+ buf);
+ buf = insert_only_hash_sets_logger::log ("contains_sizes",
+ stat_contains_sizes, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_in_non_trivial_set",
+ stat_contains_in_non_trivial_set,
+ buf);
+ buf = insert_only_hash_sets_logger::log ("probes_in_non_trivial_set",
+ stat_probes_in_non_trivial_set,
+ buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size0",
+ stat_contains_size0, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size1",
+ stat_contains_size1, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size2",
+ stat_contains_size2, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size3",
+ stat_contains_size3, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size4",
+ stat_contains_size4, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size5",
+ stat_contains_size5, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size6",
+ stat_contains_size6, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size7",
+ stat_contains_size7, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size8",
+ stat_contains_size8, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size9",
+ stat_contains_size9, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size10",
+ stat_contains_size10, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size11",
+ stat_contains_size11, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size12",
+ stat_contains_size12, buf);
+ buf = insert_only_hash_sets_logger::log ("contains_size13_or_more",
+ stat_contains_size13_or_more, buf);
+ buf = insert_only_hash_sets_logger::log ("grow_from_size0_to_1",
+ stat_grow_from_size0_to_1, buf);
+ buf = insert_only_hash_sets_logger::log ("grow_from_size1_to_2",
+ stat_grow_from_size1_to_2, buf);
+ buf = insert_only_hash_sets_logger::log ("insert_found_hash_collision",
+ stat_insert_found_hash_collision,
+ buf);
+ buf = insert_only_hash_sets_logger::log ("double_the_number_of_buckets",
+ stat_double_the_number_of_buckets,
+ buf);
+ *buf = '\0';
+}
+
+#else
+
+/* No stats. */
+#define inc_by(statname, amount) do { } while (false && (amount))
+
+#endif
+
+#define inc(statname) inc_by (statname, 1)
+
+template <typename Key, class HashFcn, class Alloc>
+class insert_only_hash_sets
+{
+ public:
+ typedef Key key_type;
+ typedef size_t size_type;
+ typedef Alloc alloc_type;
+ enum { illegal_key = 1 };
+ enum { min_capacity = 4 };
+#if HASHTABLE_STATS
+ enum { stats = true };
+#else
+ enum { stats = false };
+#endif
+
+ /* Do not directly use insert_only_hash_set. Instead, use the
+ static methods below to create and manipulate objects of the
+ following class.
+
+ Implementation details: each set is represented by a pointer
+ plus, perhaps, out-of-line data, which would be an object of type
+ insert_only_hash_set. For a pointer, s, the interpretation is: s
+ == NULL means empty set, lsb(s) == 1 means a set with one
+ element, which is (uintptr_t)s - 1, and otherwise s is a pointer
+ of type insert_only_hash_set*. So, to increase the size of a set
+ we have to change s and/or *s. To check if a set contains some
+ key we have to examine s and possibly *s. */
+ class insert_only_hash_set
+ {
+ public:
+ /* Insert a key. The key must not be a reserved key. */
+ static inline insert_only_hash_set *insert (key_type key,
+ insert_only_hash_set *s);
+
+
+ /* Create an empty set. */
+ static inline insert_only_hash_set *create (size_type capacity);
+
+ /* Return whether the given key is present. If key is illegal_key
+ then either true or false may be returned, but for all other
+ reserved keys false will be returned. */
+ static bool
+ contains (key_type key, const insert_only_hash_set *s)
+ {
+ if (stats)
+ {
+ inc (stat_contains);
+ switch (size (s))
+ {
+ case 0: inc (stat_contains_size0); break;
+ case 1: inc (stat_contains_size1); break;
+ case 2: inc (stat_contains_size2); break;
+ case 3: inc (stat_contains_size3); break;
+ case 4: inc (stat_contains_size4); break;
+ case 5: inc (stat_contains_size5); break;
+ case 6: inc (stat_contains_size6); break;
+ case 7: inc (stat_contains_size7); break;
+ case 8: inc (stat_contains_size8); break;
+ case 9: inc (stat_contains_size9); break;
+ case 10: inc (stat_contains_size10); break;
+ case 11: inc (stat_contains_size11); break;
+ case 12: inc (stat_contains_size12); break;
+ default: inc (stat_contains_size13_or_more); break;
+ }
+ inc_by (stat_contains_sizes, size (s));
+ }
+
+ return (singleton (s) ?
+ singleton_key (key) == s :
+ ((s != NULL) && s->contains (key)));
+ }
+
+ /* Return a set's size. */
+ static size_type
+ size (const insert_only_hash_set *s)
+ { return (s == NULL) ? 0 : (singleton (s) ? 1 : s->num_entries); }
+
+ static inline insert_only_hash_set *resize (size_type target_num_buckets,
+ insert_only_hash_set *s);
+
+
+ private:
+ /* Return whether a set has size 1. */
+ static bool
+ singleton (const insert_only_hash_set *s)
+ { return (uintptr_t) s & 1; }
+
+ /* Return the representation of a singleton set containing the
+ given key. */
+ static insert_only_hash_set *
+ singleton_key (key_type key)
+ { return (insert_only_hash_set *) ((uintptr_t) key + 1); }
+
+ /* Given a singleton set, what key does it contain? */
+ static key_type
+ extract_singleton_key (const insert_only_hash_set *s)
+ {
+ VTV_DEBUG_ASSERT (singleton (s));
+ return (key_type) ((uintptr_t) s - 1);
+ }
+
+ volatile key_type &
+ key_at_index (size_type index)
+ { return buckets[index]; }
+
+ key_type
+ key_at_index (size_type index) const
+ { return buckets[index]; }
+
+ size_type
+ next_index (size_type index, size_type indices_examined) const
+ { return (index + indices_examined) & (num_buckets - 1); }
+
+ inline void insert_no_resize (key_type key);
+
+ inline bool contains (key_type key) const;
+
+ inline insert_only_hash_set *resize_if_necessary (void);
+
+ size_type num_buckets; /* Must be a power of 2 not less than
+ min_capacity. */
+ volatile size_type num_entries;
+ volatile key_type buckets[0]; /* Actual array size is num_buckets. */
+ };
+
+ /* Create an empty set with the given capacity. Requires that n be
+ 0 or a power of 2. If 1 < n < min_capacity then treat n as
+ min_capacity. Sets *handle. Returns true unless the allocator
+ fails. Subsequent operations on this set should use the same
+ handle. */
+
+ static inline bool create (size_type n, insert_only_hash_set **handle);
+
+ /* Force the capacity of a set to be n, unless it was more than n
+ already. Requires that n be 0 or a power of 2. Sets *handle
+ unless the current capacity is n or more. Returns true unless
+ the allocator fails. */
+
+ static inline bool resize (size_type n, insert_only_hash_set **handle);
+
+ /* Insert a key. *handle is unmodified unless (1) a resize occurs,
+ or (2) the set was initially empty. Returns true unless the
+ allocator fails during a resize. If the allocator fails during a
+ resize then the set is reset to be the empty set. The key must
+ not be a reserved key. */
+
+ static inline bool insert (key_type key, insert_only_hash_set **handle);
+
+ /* Check for the presence of a key. If key is illegal_key then
+ either true or false may be returned, but for all other reserved
+ keys false will be returned. */
+
+ static inline bool
+ contains (key_type key, /* const */ insert_only_hash_set **handle)
+ { return insert_only_hash_set::contains (key, *handle); }
+
+ /* Return the size of the given set. */
+ static size_type
+ size (const insert_only_hash_set **handle)
+ { return insert_only_hash_set::size (*handle); }
+
+ static bool
+ is_reserved_key (key_type key)
+ { return ((uintptr_t) key % 2) == 1; }
+};
+
+template <typename Key, class HashFcn, class Alloc>
+typename insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set *
+insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set::resize
+ (size_type n, insert_only_hash_set *s)
+{
+ if (s == NULL)
+ return create (n);
+
+ size_type capacity = singleton (s) ? 1 : s->num_buckets;
+
+ if (n <= capacity)
+ return s;
+
+ insert_only_hash_set *result =
+ create (std::max<size_type> (n, min_capacity));
+ if (result != NULL)
+ {
+ if (singleton (s))
+ {
+ result->insert_no_resize (extract_singleton_key (s));
+ }
+ else
+ {
+ for (size_type i = 0; i < s->num_buckets; i++)
+ if (s->buckets[i] != (key_type) illegal_key)
+ result->insert_no_resize (s->buckets[i]);
+ }
+ VTV_DEBUG_ASSERT (size (result) == size (s));
+ }
+ return result;
+}
+
+template <typename Key, class HashFcn, class Alloc>
+typename insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set *
+insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set::insert
+ (key_type key, insert_only_hash_set *s)
+{
+ VTV_DEBUG_ASSERT (!is_reserved_key (key));
+
+ inc_by (stat_grow_from_size0_to_1, s == NULL);
+
+ if (s == NULL)
+ return singleton_key (key);
+
+ if (singleton (s))
+ {
+ const key_type old_key = extract_singleton_key (s);
+ if (old_key == key)
+ return s;
+
+ /* Grow from size 1 to size 2. */
+ inc (stat_grow_from_size1_to_2);
+ s = create (2);
+ if (s == NULL)
+ return NULL;
+
+ s->insert_no_resize (old_key);
+ s->insert_no_resize (key);
+ VTV_DEBUG_ASSERT (size (s) == 2);
+ return s;
+ }
+ s = s->resize_if_necessary();
+ if (s != NULL)
+ s->insert_no_resize (key);
+ return s;
+}
+
+template <typename Key, class HashFcn, class Alloc>
+typename insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set *
+insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set::create
+ (size_type capacity)
+{
+ if (capacity <= 1)
+ return NULL;
+
+ VTV_DEBUG_ASSERT (capacity > 1 && (capacity & (capacity - 1)) == 0);
+ VTV_DEBUG_ASSERT (sizeof (insert_only_hash_set) == 2 * sizeof (size_type));
+ capacity = std::max <size_type> (capacity, min_capacity);
+ const size_t num_bytes = sizeof (insert_only_hash_set) +
+ sizeof (key_type) * capacity;
+ alloc_type alloc;
+ insert_only_hash_set *result = (insert_only_hash_set *) alloc (num_bytes);
+ result->num_buckets = capacity;
+ result->num_entries = 0;
+ for (size_type i = 0; i < capacity; i++)
+ result->buckets[i] = (key_type) illegal_key;
+ return result;
+}
+
+template <typename Key, class HashFcn, class Alloc>
+void
+insert_only_hash_sets<Key, HashFcn,
+ Alloc>::insert_only_hash_set::insert_no_resize
+ (key_type key)
+{
+ HashFcn hasher;
+ const size_type capacity = num_buckets;
+ VTV_DEBUG_ASSERT (capacity >= min_capacity);
+ VTV_DEBUG_ASSERT (!is_reserved_key (key));
+ size_type index = hasher (key) & (capacity - 1);
+ key_type k = key_at_index (index);
+ size_type indices_examined = 0;
+ while (k != key)
+ {
+ ++indices_examined;
+ if (k == (key_type) illegal_key)
+ {
+ key_at_index (index) = key;
+ ++num_entries;
+ return;
+ }
+ else
+ {
+ inc_by (stat_insert_found_hash_collision,
+ hasher (k) == hasher (key));
+ }
+ VTV_DEBUG_ASSERT (indices_examined < capacity);
+ index = next_index (index, indices_examined);
+ k = key_at_index (index);
+ }
+}
+
+template<typename Key, class HashFcn, class Alloc>
+bool
+insert_only_hash_sets<Key, HashFcn, Alloc>::insert_only_hash_set::contains
+ (key_type key) const
+{
+ inc (stat_contains_in_non_trivial_set);
+ HashFcn hasher;
+ const size_type capacity = num_buckets;
+ size_type index = hasher (key) & (capacity - 1);
+ key_type k = key_at_index (index);
+ size_type indices_examined = 0;
+ inc (stat_probes_in_non_trivial_set);
+ while (k != key)
+ {
+ ++indices_examined;
+ if (/*UNLIKELY*/(k == (key_type) illegal_key
+ || indices_examined == capacity))
+ return false;
+
+ index = next_index (index, indices_examined);
+ k = key_at_index (index);
+ inc (stat_probes_in_non_trivial_set);
+ }
+ return true;
+}
+
+template <typename Key, class HashFcn, class Alloc>
+typename insert_only_hash_sets <Key, HashFcn, Alloc>::insert_only_hash_set *
+ insert_only_hash_sets<Key, HashFcn,
+ Alloc>::insert_only_hash_set::resize_if_necessary (void)
+{
+ VTV_DEBUG_ASSERT (num_buckets >= min_capacity);
+ size_type unused = num_buckets - num_entries;
+ if (unused < (num_buckets >> 2))
+ {
+ inc (stat_double_the_number_of_buckets);
+ size_type new_num_buckets = num_buckets * 2;
+ insert_only_hash_set *s = create (new_num_buckets);
+ for (size_type i = 0; i < num_buckets; i++)
+ if (buckets[i] != (key_type) illegal_key)
+ s->insert_no_resize (buckets[i]);
+ VTV_DEBUG_ASSERT (size (this) == size (s));
+ return s;
+ }
+ else
+ return this;
+}
+
+template<typename Key, class HashFcn, class Alloc>
+bool
+insert_only_hash_sets<Key, HashFcn, Alloc>::create (size_type n,
+ insert_only_hash_set **handle)
+
+{
+ inc (stat_create);
+ *handle = insert_only_hash_set::create (n);
+ return (n <= 1) || (*handle != NULL);
+}
+
+template<typename Key, class HashFcn, class Alloc>
+bool
+insert_only_hash_sets<Key, HashFcn, Alloc>::resize (size_type n,
+ insert_only_hash_set **handle)
+{
+ inc (stat_resize);
+ *handle = insert_only_hash_set::resize (n, *handle);
+ return (n <= 1) || (*handle != NULL);
+}
+
+template<typename Key, class HashFcn, class Alloc>
+bool
+insert_only_hash_sets<Key, HashFcn, Alloc>::insert (key_type key,
+ insert_only_hash_set **handle)
+{
+ inc (stat_insert);
+ const size_type old_size = insert_only_hash_set::size (*handle);
+ *handle = insert_only_hash_set::insert (key, *handle);
+ if (*handle != NULL)
+ {
+ const size_type delta = insert_only_hash_set::size (*handle) - old_size;
+ inc_by (stat_insert_key_that_was_already_present, delta == 0);
+ }
+ return *handle != NULL;
+}
+
+#endif /* VTV_SET_H */
diff --git a/libvtv/vtv_utils.cc b/libvtv/vtv_utils.cc
new file mode 100644
index 00000000000..9cf4b08dc24
--- /dev/null
+++ b/libvtv/vtv_utils.cc
@@ -0,0 +1,161 @@
+/* Copyright (C) 2012-2013
+ Free Software Foundation
+
+ This file is part of GCC.
+
+ GCC is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3, or (at your option)
+ any later version.
+
+ GCC is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ Under Section 7 of GPL version 3, you are granted additional
+ permissions described in the GCC Runtime Library Exception, version
+ 3.1, as published by the Free Software Foundation.
+
+ You should have received a copy of the GNU General Public License and
+ a copy of the GCC Runtime Library Exception along with this program;
+ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* This file is part of the vtable verication runtime library (see
+ comments in vtv_rts.cc for more information about vtable
+ verification). This file contains log file utilities. */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <execinfo.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include "vtv_utils.h"
+
+#ifndef HAVE_SECURE_GETENV
+# ifdef HAVE___SECURE_GETENV
+# define secure_getenv __secure_getenv
+# else
+# define secure_getenv getenv
+# endif
+#endif
+
+static int vtv_failures_log_fd = -1;
+
+/* This function takes the NAME of a log file to open, attempts to
+ open it in the logs_dir directory, and returns the resulting file
+ descriptor.
+
+ This function first checks to see if the user has specifed (via
+ the environment variable VTV_LOGS_DIR) a directory to use for the
+ vtable verification logs. If that fails, the function will open
+ the logs in the current directory.
+*/
+
+int
+__vtv_open_log (const char *name)
+{
+ char log_name[1024];
+ char log_dir[512];
+ uid_t user_id = getuid ();
+ pid_t process_id = getpid ();
+ char *logs_prefix;
+ bool logs_dir_specified = false;
+ int fd = -1;
+
+ logs_prefix = secure_getenv ("VTV_LOGS_DIR");
+ if (logs_prefix && strlen (logs_prefix) > 0)
+ {
+ logs_dir_specified = true;
+ mkdir (logs_prefix, S_IRWXU);
+ snprintf (log_dir, sizeof (log_dir), "%s/vtv_logs", logs_prefix);
+ mkdir (log_dir, S_IRWXU);
+
+ snprintf (log_name, sizeof (log_name), "%s/%d_%d_%s", log_dir,
+ (unsigned) user_id, (unsigned) process_id, name);
+ fd = open (log_name, O_WRONLY | O_APPEND | O_CREAT | O_NOFOLLOW,
+ S_IRWXU);
+ }
+ else
+ fd = dup (2);
+
+ if (fd == -1)
+ __vtv_add_to_log (2, "Cannot open log file %s %s\n", name,
+ strerror (errno));
+ return fd;
+}
+
+/* This function takes a file descriptor (FD) and a string (STR) and
+ tries to write the string to the file. */
+
+static int
+vtv_log_write (int fd, const char *str)
+{
+ if (write (fd, str, strlen (str)) != -1)
+ return 0;
+
+ if (fd != 2) /* Make sure we dont get in a loop. */
+ __vtv_add_to_log (2, "Error writing to log: %s\n", strerror (errno));
+ return -1;
+}
+
+
+/* This function takes a file decriptor (LOG_FILE) and an output
+ format string (FORMAT), followed by zero or more print format
+ arguments (the same as fprintf, for example). It gets the current
+ process ID and PPID, pre-pends them to the formatted message, and
+ writes write it out to the log file referenced by LOG_FILE via calles
+ to vtv_log_write. */
+
+int
+__vtv_add_to_log (int log_file, const char * format, ...)
+{
+ /* We dont want to dynamically allocate this buffer. This should be
+ more than enough in most cases. It if isn't we are careful not to
+ do a buffer overflow. */
+ char output[1024];
+
+ va_list ap;
+ va_start (ap, format);
+
+ snprintf (output, sizeof (output), "VTV: PID=%d PPID=%d ", getpid (),
+ getppid ());
+ vtv_log_write (log_file, output);
+ vsnprintf (output, sizeof (output), format, ap);
+ vtv_log_write (log_file, output);
+ va_end (ap);
+
+ return 0;
+}
+
+/* Open error logging file, if not already open, and write vtable
+ verification failure messages (LOG_MSG) to the log file. Also
+ generate a backtrace in the log file, if GENERATE_BACKTRACE is
+ set. */
+
+void
+__vtv_log_verification_failure (const char *log_msg, bool generate_backtrace)
+{
+ if (vtv_failures_log_fd == -1)
+ vtv_failures_log_fd = __vtv_open_log ("vtable_verification_failures.log");
+
+ if (vtv_failures_log_fd == -1)
+ return;
+
+ __vtv_add_to_log (vtv_failures_log_fd, "%s", log_msg);
+
+ if (generate_backtrace)
+ {
+#define STACK_DEPTH 20
+ void *callers[STACK_DEPTH];
+ int actual_depth = backtrace (callers, STACK_DEPTH);
+ backtrace_symbols_fd (callers, actual_depth, vtv_failures_log_fd);
+ }
+}
diff --git a/libvtv/vtv_utils.h b/libvtv/vtv_utils.h
new file mode 100644
index 00000000000..f20d0b562e9
--- /dev/null
+++ b/libvtv/vtv_utils.h
@@ -0,0 +1,63 @@
+/* Copyright (C) 2012-2013
+ Free Software Foundation
+
+ 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 _VTV_UTILS_H
+#define _VTV_UTILS_H 1
+
+#include <stdlib.h>
+#include "../include/vtv-change-permission.h"
+
+static inline void
+VTV_not_an_error (void)
+{
+}
+
+/* Handler for verification runtime errors. */
+#define VTV_error abort
+
+/* Assertion macros used in vtable verification runtime. */
+#define VTV_ASSERT(EXPR) \
+ if (!(EXPR)) VTV_error();
+
+#ifdef VTV_DEBUG
+#define VTV_DEBUG_ASSERT(EXPR) \
+ ((bool) (!(EXPR)) ? VTV_error() : (void) 0)
+#else
+#define VTV_DEBUG_ASSERT(EXPR) ((void) 0)
+#endif
+
+/* Name of the section where we put general VTV variables for protection */
+#define VTV_PROTECTED_VARS_SECTION ".vtable_map_vars"
+#define VTV_PROTECTED_VAR \
+ __attribute__ ((section (VTV_PROTECTED_VARS_SECTION)))
+
+/* The following logging routines try to use low level file access
+ routines and avoid calling malloc. We need this so that we dont
+ disturb the order of calls to dlopen. Changing the order of dlopen
+ calls may lead to deadlocks */
+int __vtv_open_log (const char * name);
+int __vtv_add_to_log (int log, const char * format, ...);
+void __vtv_log_verification_failure (const char *, bool);
+
+#endif /* VTV_UTILS_H */