summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS2
-rw-r--r--boehm-gc/ChangeLog10
-rw-r--r--boehm-gc/Makefile.am2
-rw-r--r--boehm-gc/Makefile.in274
-rw-r--r--boehm-gc/include/Makefile.am2
-rw-r--r--boehm-gc/include/Makefile.in60
-rw-r--r--boehm-gc/testsuite/Makefile.am2
-rw-r--r--boehm-gc/testsuite/Makefile.in41
-rw-r--r--config/ChangeLog5
-rw-r--r--config/mt-gnu2
-rw-r--r--gcc/ChangeLog373
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/ada/gnatvsn.ads4
-rw-r--r--gcc/alloc-pool.c6
-rw-r--r--gcc/c-family/ChangeLog17
-rw-r--r--gcc/c-family/c-common.c36
-rw-r--r--gcc/c-family/c.opt2
-rw-r--r--gcc/c/ChangeLog35
-rw-r--r--gcc/c/c-decl.c40
-rw-r--r--gcc/c/c-parser.c72
-rw-r--r--gcc/c/c-tree.h3
-rw-r--r--gcc/c/c-typeck.c65
-rw-r--r--gcc/cgraph.c4
-rw-r--r--gcc/cgraphunit.c6
-rw-r--r--gcc/config.in12
-rw-r--r--gcc/config/arm/aarch-common.c8
-rw-r--r--gcc/config/arm/arm.c8
-rw-r--r--gcc/config/arm/arm.md12
-rw-r--r--gcc/config/arm/predicates.md3
-rw-r--r--gcc/config/avr/avr.c6
-rw-r--r--gcc/config/i386/i386-c.c7
-rw-r--r--gcc/config/i386/i386.md13
-rw-r--r--gcc/config/m68k/m68k.md4
-rw-r--r--gcc/config/rs6000/altivec.md112
-rw-r--r--gcc/config/rs6000/dfp.md69
-rw-r--r--gcc/config/rs6000/predicates.md5
-rw-r--r--gcc/config/rs6000/rs6000-builtin.def135
-rw-r--r--gcc/config/rs6000/rs6000.c82
-rw-r--r--gcc/config/rs6000/rs6000.h10
-rw-r--r--gcc/config/rs6000/rs6000.md208
-rw-r--r--gcc/config/sol2.h1
-rw-r--r--gcc/config/sparc/sparc.md13
-rw-r--r--gcc/config/sparc/sparc.opt4
-rw-r--r--gcc/config/sparc/sync.md19
-rwxr-xr-xgcc/configure170
-rw-r--r--gcc/configure.ac95
-rw-r--r--gcc/cp/ChangeLog12
-rw-r--r--gcc/cp/parser.c45
-rw-r--r--gcc/cselib.c66
-rw-r--r--gcc/doc/extend.texi67
-rw-r--r--gcc/doc/install.texi3
-rw-r--r--gcc/doc/invoke.texi9
-rw-r--r--gcc/dwarf2out.c56
-rw-r--r--gcc/expr.c12
-rw-r--r--gcc/expr.h8
-rw-r--r--gcc/fortran/ChangeLog20
-rw-r--r--gcc/fortran/arith.c11
-rw-r--r--gcc/fortran/gfortran.h4
-rw-r--r--gcc/fortran/simplify.c32
-rw-r--r--gcc/gimple-ssa-strength-reduction.c17
-rw-r--r--gcc/gimplify.c63
-rw-r--r--gcc/go/ChangeLog13
-rw-r--r--gcc/go/go-gcc.cc168
-rw-r--r--gcc/go/gofrontend/backend.h20
-rw-r--r--gcc/go/gofrontend/expressions.cc141
-rw-r--r--gcc/go/gofrontend/expressions.h148
-rw-r--r--gcc/go/gofrontend/gogo-tree.cc882
-rw-r--r--gcc/go/gofrontend/gogo.cc793
-rw-r--r--gcc/go/gofrontend/gogo.h36
-rw-r--r--gcc/go/gofrontend/statements.cc22
-rw-r--r--gcc/graphite-scop-detection.c6
-rw-r--r--gcc/haifa-sched.c4
-rw-r--r--gcc/omp-low.c14
-rw-r--r--gcc/passes.c133
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/rtlanal.c10
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/testsuite/ChangeLog160
-rw-r--r--gcc/testsuite/c-c++-common/gomp/atomic-16.c40
-rw-r--r--gcc/testsuite/c-c++-common/gomp/pr60823-2.c1
-rw-r--r--gcc/testsuite/c-c++-common/pr60156.c9
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-43.C4
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C55
-rw-r--r--gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C2
-rw-r--r--gcc/testsuite/g++.dg/ipa/devirt-27.C2
-rw-r--r--gcc/testsuite/g++.dg/opt/pr60912.C18
-rw-r--r--gcc/testsuite/g++.dg/vect/pr60896.cc44
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/20140425-1.c23
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr60822.c24
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr60822.x7
-rw-r--r--gcc/testsuite/gcc.c-torture/execute/pr60960.c38
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-overflow-14.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-overflow-15.c2
-rw-r--r--gcc/testsuite/gcc.dg/Wstrict-overflow-18.c2
-rw-r--r--gcc/testsuite/gcc.dg/graphite/pr60979.c37
-rw-r--r--gcc/testsuite/gcc.dg/lto/pr60911_0.c21
-rw-r--r--gcc/testsuite/gcc.dg/pr18079-2.c16
-rw-r--r--gcc/testsuite/gcc.dg/pr18079.c33
-rw-r--r--gcc/testsuite/gcc.dg/pr60114.c31
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr60930.c22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/alias-30.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c1
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp91.c22
-rw-r--r--gcc/testsuite/gcc.dg/vect/pr60505.c2
-rw-r--r--gcc/testsuite/gcc.target/arm/tail-long-call.c12
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bcd-1.c27
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bcd-2.c44
-rw-r--r--gcc/testsuite/gcc.target/powerpc/bcd-3.c103
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c88
-rw-r--r--gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c88
-rw-r--r--gcc/testsuite/gcc.target/powerpc/extend-divide-1.c34
-rw-r--r--gcc/testsuite/gcc.target/powerpc/extend-divide-2.c34
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pack01.c91
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pack02.c95
-rw-r--r--gcc/testsuite/gcc.target/powerpc/pack03.c88
-rw-r--r--gcc/testsuite/gfortran.dg/namelist_utf8.f9030
-rw-r--r--gcc/testsuite/gfortran.dg/no_range_check_3.f9012
-rw-r--r--gcc/tree-nested.c22
-rw-r--r--gcc/tree-pass.h4
-rw-r--r--gcc/tree-ssa-structalias.c41
-rw-r--r--gcc/tree-ssa-threadedge.c2
-rw-r--r--gcc/tree-vect-generic.c3
-rw-r--r--gcc/tree-vect-patterns.c5
-rw-r--r--gcc/tree-vrp.c98
-rw-r--r--gcc/tree.h3
-rw-r--r--libffi/ChangeLog9
-rw-r--r--libffi/Makefile.in250
-rw-r--r--libffi/configure.ac2
-rw-r--r--libffi/include/Makefile.in56
-rw-r--r--libffi/man/Makefile.in68
-rw-r--r--libffi/testsuite/Makefile.in39
-rw-r--r--libgcc/ChangeLog5
-rw-r--r--libgcc/config/i386/crtfastmath.c20
-rw-r--r--libgfortran/ChangeLog13
-rw-r--r--libgfortran/io/list_read.c258
-rw-r--r--libgfortran/io/write.c5
-rw-r--r--libgo/runtime/mheap.c14
-rw-r--r--libgomp/ChangeLog12
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-14.C26
-rw-r--r--libgomp/testsuite/libgomp.c++/atomic-15.C26
-rw-r--r--libgomp/testsuite/libgomp.c/atomic-17.c26
-rw-r--r--libgomp/testsuite/libgomp.c/loop-16.c27
-rw-r--r--libgomp/testsuite/libgomp.c/simd-7.c96
-rw-r--r--libgomp/testsuite/libgomp.c/simd-8.c44
-rw-r--r--libgomp/testsuite/libgomp.c/simd-9.c70
-rw-r--r--libstdc++-v3/ChangeLog63
-rw-r--r--libstdc++-v3/include/bits/regex.tcc35
-rw-r--r--libstdc++-v3/include/bits/regex_automaton.h21
-rw-r--r--libstdc++-v3/include/bits/regex_automaton.tcc23
-rw-r--r--libstdc++-v3/include/bits/regex_compiler.h2
-rw-r--r--libstdc++-v3/include/bits/regex_compiler.tcc20
-rw-r--r--libstdc++-v3/include/bits/regex_executor.h10
-rw-r--r--libstdc++-v3/include/bits/regex_executor.tcc143
-rw-r--r--libstdc++-v3/include/bits/regex_scanner.tcc2
-rw-r--r--libstdc++-v3/include/experimental/optional4
-rw-r--r--libstdc++-v3/include/tr1/regex4
-rw-r--r--libstdc++-v3/testsuite/28_regex/algorithms/regex_match/ecma/char/emptygroup.cc1
-rw-r--r--libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/optional/relops/1.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/optional/relops/2.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/optional/relops/3.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/optional/relops/4.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/optional/relops/5.cc4
-rw-r--r--libstdc++-v3/testsuite/experimental/optional/relops/6.cc4
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_abi.cc3
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_regex.h4
171 files changed, 5182 insertions, 2679 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 80dfb63004b..36979e13785 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -540,7 +540,7 @@ Gabriele Svelto gabriele.svelto@st.com
Sriraman Tallam tmsriram@google.com
Chung-Lin Tang cltang@codesourcery.com
Samuel Tardieu sam@rfc1149.net
-Dinar Temirbulatov dinar@kugelworks.com
+Dinar Temirbulatov dtemirbulatov@gmail.com
Kresten Krab Thorup krab@gcc.gnu.org
Caroline Tice cmtice@google.com
Kyrylo Tkachov kyrylo.tkachov@arm.com
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index 6f124526e3d..1b5c92d878b 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,13 @@
+2014-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/43620
+ * Makefile.am (AUTOMAKE_OPTIONS): Add no-dist.
+ * include/Makefile.am (AUTOMAKE_OPTIONS): Likewise.
+ * testsuite/Makefile.am (AUTOMAKE_OPTIONS): Likewise.
+ * Makefile.in: Regenerated.
+ * include/Makefile.in: Regenerated.
+ * testsuite/Makefile.in: Regenerated.
+
2013-12-21 Andreas Tobler <andreast@gcc.gnu.org>
* include/private/gcconfig.h: Add FreeBSD powerpc64 defines.
diff --git a/boehm-gc/Makefile.am b/boehm-gc/Makefile.am
index 468e6ffc9b4..fa187ef31ee 100644
--- a/boehm-gc/Makefile.am
+++ b/boehm-gc/Makefile.am
@@ -4,7 +4,7 @@
## files that should be in the distribution are not mentioned in this
## Makefile.am.
-AUTOMAKE_OPTIONS = foreign subdir-objects
+AUTOMAKE_OPTIONS = foreign subdir-objects no-dist
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = include testsuite
diff --git a/boehm-gc/Makefile.in b/boehm-gc/Makefile.in
index cd588103659..5fc84910128 100644
--- a/boehm-gc/Makefile.in
+++ b/boehm-gc/Makefile.in
@@ -36,13 +36,10 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = .
-DIST_COMMON = $(am__configure_deps) $(srcdir)/../compile \
- $(srcdir)/../config.guess $(srcdir)/../config.sub \
- $(srcdir)/../depcomp $(srcdir)/../install-sh \
- $(srcdir)/../ltmain.sh $(srcdir)/../missing \
- $(srcdir)/../mkinstalldirs $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(srcdir)/threads.mk.in \
- $(top_srcdir)/configure ChangeLog depcomp
+DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(top_srcdir)/configure $(am__configure_deps) \
+ $(srcdir)/../mkinstalldirs $(srcdir)/threads.mk.in \
+ $(srcdir)/../depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
@@ -63,14 +60,6 @@ CONFIG_CLEAN_FILES = threads.mk
CONFIG_CLEAN_VPATH_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
am__DEPENDENCIES_1 =
-am__libgcjgc_la_SOURCES_DIST = allchblk.c alloc.c blacklst.c \
- checksums.c dbg_mlc.c dyn_load.c finalize.c gc_dlopen.c \
- gcj_mlc.c headers.c malloc.c mallocx.c mark.c mark_rts.c \
- misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c \
- ptr_chck.c real_malloc.c reclaim.c specific.c stubborn.c \
- typd_mlc.c backgraph.c win32_threads.c pthread_support.c \
- pthread_stop_world.c darwin_stop_world.c \
- powerpc_darwin_mach_dep.s
@POWERPC_DARWIN_TRUE@am__objects_1 = powerpc_darwin_mach_dep.lo
am_libgcjgc_la_OBJECTS = allchblk.lo alloc.lo blacklst.lo checksums.lo \
dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \
@@ -80,14 +69,6 @@ am_libgcjgc_la_OBJECTS = allchblk.lo alloc.lo blacklst.lo checksums.lo \
backgraph.lo win32_threads.lo pthread_support.lo \
pthread_stop_world.lo darwin_stop_world.lo $(am__objects_1)
libgcjgc_la_OBJECTS = $(am_libgcjgc_la_OBJECTS)
-am__libgcjgc_convenience_la_SOURCES_DIST = allchblk.c alloc.c \
- blacklst.c checksums.c dbg_mlc.c dyn_load.c finalize.c \
- gc_dlopen.c gcj_mlc.c headers.c malloc.c mallocx.c mark.c \
- mark_rts.c misc.c new_hblk.c obj_map.c os_dep.c \
- pcr_interface.c ptr_chck.c real_malloc.c reclaim.c specific.c \
- stubborn.c typd_mlc.c backgraph.c win32_threads.c \
- pthread_support.c pthread_stop_world.c darwin_stop_world.c \
- powerpc_darwin_mach_dep.s
am__objects_2 = allchblk.lo alloc.lo blacklst.lo checksums.lo \
dbg_mlc.lo dyn_load.lo finalize.lo gc_dlopen.lo gcj_mlc.lo \
headers.lo malloc.lo mallocx.lo mark.lo mark_rts.lo misc.lo \
@@ -115,8 +96,6 @@ CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
LTCCASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=compile $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS)
SOURCES = $(libgcjgc_la_SOURCES) $(libgcjgc_convenience_la_SOURCES)
-DIST_SOURCES = $(am__libgcjgc_la_SOURCES_DIST) \
- $(am__libgcjgc_convenience_la_SOURCES_DIST)
MULTISRCTOP =
MULTIBUILDTOP =
MULTIDIRS =
@@ -133,47 +112,10 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
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 \
- distdir dist dist-all distcheck
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-distdir = $(PACKAGE)-$(VERSION)
-top_distdir = $(distdir)
-am__remove_distdir = \
- { test ! -d "$(distdir)" \
- || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
- && rm -fr "$(distdir)"; }; }
-am__relativize = \
- dir0=`pwd`; \
- sed_first='s,^\([^/]*\)/.*$$,\1,'; \
- sed_rest='s,^[^/]*/*,,'; \
- sed_last='s,^.*/\([^/]*\)$$,\1,'; \
- sed_butlast='s,/*[^/]*$$,,'; \
- while test -n "$$dir1"; do \
- first=`echo "$$dir1" | sed -e "$$sed_first"`; \
- if test "$$first" != "."; then \
- if test "$$first" = ".."; then \
- dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
- dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
- else \
- first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
- if test "$$first2" = "$$first"; then \
- dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
- else \
- dir2="../$$dir2"; \
- fi; \
- dir0="$$dir0"/"$$first"; \
- fi; \
- fi; \
- dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
- done; \
- reldir="$$dir2"
-DIST_ARCHIVES = $(distdir).tar.gz
-GZIP_ENV = --best
-distuninstallcheck_listfiles = find . -type f -print
-distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CPPFLAGS = @AM_CPPFLAGS@
@@ -314,7 +256,7 @@ toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = foreign subdir-objects
+AUTOMAKE_OPTIONS = foreign subdir-objects no-dist
ACLOCAL_AMFLAGS = -I .. -I ../config
SUBDIRS = include testsuite
noinst_LTLIBRARIES = libgcjgc.la libgcjgc_convenience.la
@@ -672,182 +614,6 @@ GTAGS:
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- $(am__remove_distdir)
- test -d "$(distdir)" || mkdir "$(distdir)"
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
- $(am__relativize); \
- new_distdir=$$reldir; \
- dir1=$$subdir; dir2="$(top_distdir)"; \
- $(am__relativize); \
- new_top_distdir=$$reldir; \
- echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
- echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
- ($(am__cd) $$subdir && \
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$$new_top_distdir" \
- distdir="$$new_distdir" \
- am__remove_distdir=: \
- am__skip_length_check=: \
- am__skip_mode_fix=: \
- distdir) \
- || exit 1; \
- fi; \
- done
- -test -n "$(am__skip_mode_fix)" \
- || find "$(distdir)" -type d ! -perm -755 \
- -exec chmod u+rwx,go+rx {} \; -o \
- ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
- || chmod -R a+r "$(distdir)"
-dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-dist-bzip2: distdir
- tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
-
-dist-lzma: distdir
- tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
- $(am__remove_distdir)
-
-dist-xz: distdir
- tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
- $(am__remove_distdir)
-
-dist-tarZ: distdir
- tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
-
-dist-shar: distdir
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
-
-dist-zip: distdir
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
-
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-# This target untars the dist file and tries a VPATH configuration. Then
-# it guarantees that the distribution is self-contained by making another
-# tarfile.
-distcheck: dist
- case '$(DIST_ARCHIVES)' in \
- *.tar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
- *.tar.bz2*) \
- bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lzma*) \
- lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
- *.tar.xz*) \
- xz -dc $(distdir).tar.xz | $(am__untar) ;;\
- *.tar.Z*) \
- uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
- *.shar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
- *.zip*) \
- unzip $(distdir).zip ;;\
- esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
- chmod a-w $(distdir)
- test -d $(distdir)/_build || exit 0; \
- dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
- && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
- && am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
- $(DISTCHECK_CONFIGURE_FLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) dvi \
- && $(MAKE) $(AM_MAKEFLAGS) check \
- && $(MAKE) $(AM_MAKEFLAGS) install \
- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
- && $(MAKE) $(AM_MAKEFLAGS) uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
- distuninstallcheck \
- && chmod -R a-w "$$dc_install_base" \
- && ({ \
- (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
- distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
- } || { rm -rf "$$dc_destdir"; exit 1; }) \
- && rm -rf "$$dc_destdir" \
- && $(MAKE) $(AM_MAKEFLAGS) dist \
- && rm -rf $(DIST_ARCHIVES) \
- && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
- && cd "$$am__cwd" \
- || exit 1
- $(am__remove_distdir)
- @(echo "$(distdir) archives ready for distribution: "; \
- list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
- sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
-distuninstallcheck:
- @$(am__cd) '$(distuninstallcheck_dir)' \
- && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
- || { echo "ERROR: files left after uninstall:" ; \
- if test -n "$(DESTDIR)"; then \
- echo " (check DESTDIR support)"; \
- fi ; \
- $(distuninstallcheck_listfiles) ; \
- exit 1; } >&2
-distcleancheck: distclean
- @if test '$(srcdir)' = . ; then \
- echo "ERROR: distcleancheck can only run from a VPATH build" ; \
- exit 1 ; \
- fi
- @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
- || { echo "ERROR: files left in build directory after distclean:" ; \
- $(distcleancheck_listfiles) ; \
- exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(LTLIBRARIES) all-multi
@@ -960,21 +726,19 @@ uninstall-am:
.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-noinstLTLIBRARIES ctags ctags-recursive dist dist-all \
- dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ dist-xz \
- dist-zip distcheck distclean distclean-compile \
- distclean-generic distclean-libtool distclean-multi \
- distclean-tags distcleancheck distdir distuninstallcheck 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-multi \
- install-pdf install-pdf-am install-ps install-ps-am \
- install-strip 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
+ clean-noinstLTLIBRARIES 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-man install-multi install-pdf install-pdf-am \
+ install-ps install-ps-am install-strip 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
override CFLAGS := $(filter-out $(O0_CFLAGS), $(CFLAGS)) $(O0_CFLAGS)
diff --git a/boehm-gc/include/Makefile.am b/boehm-gc/include/Makefile.am
index 381ae76b8fe..63aec076056 100644
--- a/boehm-gc/include/Makefile.am
+++ b/boehm-gc/include/Makefile.am
@@ -1,4 +1,4 @@
-AUTOMAKE_OPTIONS = foreign
+AUTOMAKE_OPTIONS = foreign no-dist
noinst_HEADERS = gc.h gc_backptr.h gc_local_alloc.h \
gc_pthread_redirects.h gc_cpp.h
diff --git a/boehm-gc/include/Makefile.in b/boehm-gc/include/Makefile.in
index db67a999adf..8287ef6b1d9 100644
--- a/boehm-gc/include/Makefile.in
+++ b/boehm-gc/include/Makefile.in
@@ -36,9 +36,9 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = include
-DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(srcdir)/gc_config.h.in \
- $(srcdir)/gc_ext_config.h.in
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
+ $(srcdir)/gc_config.h.in $(srcdir)/gc_ext_config.h.in \
+ $(noinst_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/depstand.m4 \
@@ -55,11 +55,9 @@ CONFIG_HEADER = gc_config.h gc_ext_config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
-DIST_SOURCES =
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CPPFLAGS = @AM_CPPFLAGS@
@@ -200,7 +198,7 @@ toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = foreign
+AUTOMAKE_OPTIONS = foreign no-dist
noinst_HEADERS = gc.h gc_backptr.h gc_local_alloc.h \
gc_pthread_redirects.h gc_cpp.h
@@ -323,37 +321,6 @@ GTAGS:
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS) gc_config.h gc_ext_config.h
@@ -453,16 +420,15 @@ uninstall-am:
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool ctags distclean distclean-generic distclean-hdr \
- distclean-libtool distclean-tags distdir 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 tags uninstall \
- uninstall-am
+ 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 installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
+ ps ps-am tags uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/boehm-gc/testsuite/Makefile.am b/boehm-gc/testsuite/Makefile.am
index 98010bd1f69..f1eac3b1666 100644
--- a/boehm-gc/testsuite/Makefile.am
+++ b/boehm-gc/testsuite/Makefile.am
@@ -1,6 +1,6 @@
## Process this file with automake to produce Makefile.in.
-AUTOMAKE_OPTIONS = foreign dejagnu
+AUTOMAKE_OPTIONS = foreign dejagnu no-dist
EXPECT = expect
diff --git a/boehm-gc/testsuite/Makefile.in b/boehm-gc/testsuite/Makefile.in
index b12a5c51558..dbb2ff604e0 100644
--- a/boehm-gc/testsuite/Makefile.in
+++ b/boehm-gc/testsuite/Makefile.in
@@ -35,7 +35,7 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = testsuite
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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 \
@@ -53,10 +53,8 @@ CONFIG_HEADER = $(top_builddir)/include/gc_config.h \
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
-DIST_SOURCES =
RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
RUNTEST = runtest
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CPPFLAGS = @AM_CPPFLAGS@
@@ -197,7 +195,7 @@ toolexeclibdir = @toolexeclibdir@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-AUTOMAKE_OPTIONS = foreign dejagnu
+AUTOMAKE_OPTIONS = foreign dejagnu no-dist
EXPECT = expect
# Override default.
@@ -267,37 +265,6 @@ distclean-DEJAGNU:
-l='$(DEJATOOL)'; for tool in $$l; do \
rm -f $$tool.sum $$tool.log; \
done
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
check: check-am
@@ -399,8 +366,8 @@ uninstall-am:
.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \
clean-libtool distclean distclean-DEJAGNU distclean-generic \
- distclean-libtool distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
+ 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 \
diff --git a/config/ChangeLog b/config/ChangeLog
index 7d000625c76..f4152c4ebff 100644
--- a/config/ChangeLog
+++ b/config/ChangeLog
@@ -1,3 +1,8 @@
+2014-04-25 Marc Glisse <marc.glisse@inria.fr>
+
+ PR target/43538
+ * mt-gnu: Don't reset CXXFLAGS_FOR_TARGET.
+
2013-11-29 Marek Polacek <polacek@redhat.com>
* bootstrap-ubsan.mk (POSTSTAGE1_LDFLAGS): Remove -lpthread -ldl.
diff --git a/config/mt-gnu b/config/mt-gnu
index 15bf4171603..5c696f51b0b 100644
--- a/config/mt-gnu
+++ b/config/mt-gnu
@@ -1 +1 @@
-CXXFLAGS_FOR_TARGET = $(CXXFLAGS) -D_GNU_SOURCE
+CXXFLAGS_FOR_TARGET += -D_GNU_SOURCE
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a29383083b3..67a4645a87a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,376 @@
+2014-04-28 Richard Biener <rguenther@suse.de>
+
+ * tree-vrp.c (vrp_var_may_overflow): Remove.
+ (vrp_visit_phi_node): Rather than bumping to +-INF possibly
+ with overflow immediately bump to one before that value and
+ let iteration figure out overflow status.
+
+2014-04-28 Richard Biener <rguenther@suse.de>
+
+ * configure.ac: Do valgrind header checks unconditionally.
+ Add --enable-valgrind-annotations.
+ * system.h: Guard valgrind header inclusion with
+ ENABLE_VALGRIND_ANNOTATIONS instead of ENABLE_VALGRIND_CHECKING.
+ * alloc-pool.c (pool_alloc, pool_free): Use
+ ENABLE_VALGRIND_ANNOTATIONS instead of ENABLE_VALGRIND_CHECKING
+ to guard possibly dead code.
+ * config.in: Regenerated.
+ * configure: Likewise.
+
+2014-04-28 Jeff Law <law@redhat.com>
+
+ PR tree-optimization/60902
+ * tree-ssa-threadedge.c
+ (record_temporary_equivalences_from_stmts_at_dest): Only iterate
+ over real defs when invalidating outputs from statements that do not
+ produce useful outputs for threading.
+
+2014-04-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/60979
+ * graphite-scop-detection.c (scopdet_basic_block_info): Reject
+ SCOPs that end in a block with a successor with abnormal
+ predecessors.
+
+2014-04-28 Richard Biener <rguenther@suse.de>
+
+ * tree-pass.h (execute_pass_list): Adjust prototype.
+ * passes.c (pass_manager::execute_early_local_passes):
+ Adjust.
+ (do_per_function): Change callback signature, push all actual
+ work to the callbals.
+ (do_per_function_toporder): Likewise.
+ (execute_function_dump): Adjust.
+ (execute_function_todo): Likewise.
+ (clear_last_verified): Likewise.
+ (verify_curr_properties): Likewise.
+ (update_properties_after_pass): Likewise.
+ (execute_pass_list_1): Split out from ...
+ (execute_pass_list): ... here. Adjust.
+ (execute_ipa_pass_list): Likewise.
+ * cgraphunit.c (cgraph_add_new_function): Adjust.
+ (analyze_function): Likewise.
+ (expand_function): Likewise.
+ * cgraph.c (release_function_body): Free dominance info
+ here instead of asserting it was magically freed elsewhere.
+
+2014-04-28 Eric Botcazou <ebotcazou@adacore.com>
+
+ * configure.ac: Tweak GAS check for LEON instructions on SPARC.
+ * configure: Regenerate.
+ * config/sparc/sparc.opt (muser-mode): New option.
+ * config/sparc/sync.md (atomic_compare_and_swap<mode>_1): Do not enable
+ for LEON3.
+ (atomic_compare_and_swap_leon3_1): New instruction for LEON3.
+ * doc/invoke.texi (SPARC options): Document -muser-mode.
+
+2014-04-27 Richard Sandiford <rdsandiford@googlemail.com>
+
+ * cselib.c (find_slot_memmode): Delete.
+ (cselib_hasher): Change compare_type to a struct.
+ (cselib_hasher::equal): Update accordingly. Don't expect wrapped
+ constants.
+ (preserve_constants_and_equivs): Adjust for new compare_type.
+ (cselib_find_slot): Likewise. Take the mode of the rtx as argument.
+ (wrap_constant): Delete.
+ (cselib_lookup_mem, cselib_lookup_1): Update calls to cselib_find_slot.
+
+2014-04-26 Markus Trippelsdorf <markus@trippelsdorf.de>
+
+ * doc/install.texi (Building with profile feedback): Remove
+ outdated sentence.
+
+2014-04-26 Tom de Vries <tom@codesourcery.com>
+
+ * config/i386/i386.md (define_expand "ldexpxf3"): Fix out-of-bounds
+ array accesses.
+
+2014-04-25 Cary Coutant <ccoutant@google.com>
+
+ PR debug/60929
+ * dwarf2out.c (should_move_die_to_comdat): A type definition
+ can contain a subprogram definition, but don't move it to a
+ comdat unit.
+ (clone_as_declaration): Copy DW_AT_abstract_origin attribute.
+ (generate_skeleton_bottom_up): Remove DW_AT_object_pointer attribute
+ from original DIE.
+ (clone_tree_hash): Rename to...
+ (clone_tree_partial): ...this; change callers. Copy
+ DW_TAG_subprogram DIEs as declarations.
+ (copy_decls_walk): Don't copy children of a declaration into a
+ type unit.
+
+2014-04-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR target/60969
+ * config/i386/i386.md (*movsf_internal): Set MODE to SI for
+ alternative 12.
+
+2014-04-25 Jiong Wang <jiong.wang@arm.com>
+
+ * config/arm/predicates.md (call_insn_operand): Add long_call check.
+ * config/arm/arm.md (sibcall, sibcall_value): Force the address to
+ reg for long_call.
+ * config/arm/arm.c (arm_function_ok_for_sibcall): Remove long_call
+ restriction.
+
+2014-04-25 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/arm.c (arm_cortex_a8_tune): Initialise
+ T16-related fields.
+
+2014-04-25 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR tree-optimization/60930
+ * gimple-ssa-strength-reduction.c (create_mul_imm_cand): Reject
+ creating a multiply candidate by folding two constant
+ multiplicands when the result overflows.
+
+2014-04-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/60960
+ * tree-vect-generic.c (expand_vector_operation): Only call
+ expand_vector_divmod if type's mode satisfies VECTOR_MODE_P.
+
+2014-04-25 Tom de Vries <tom@codesourcery.com>
+
+ * expr.c (clobber_reg_mode): New function.
+ * expr.h (clobber_reg): New function.
+
+2014-04-25 Tom de Vries <tom@codesourcery.com>
+
+ * rtlanal.c (find_all_hard_reg_sets): Note INSN_CALL_FUNCTION_USAGE
+ clobbers.
+
+2014-04-25 Radovan Obradovic <robradovic@mips.com>
+ Tom de Vries <tom@codesourcery.com>
+
+ * rtlanal.c (find_all_hard_reg_sets): Add bool implicit parameter and
+ handle.
+ * rtl.h (find_all_hard_reg_sets): Add bool parameter.
+ * haifa-sched.c (recompute_todo_spec, check_clobbered_conditions): Add
+ new argument to find_all_hard_reg_sets call.
+
+2014-04-25 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ * config/arm/aarch-common.c (aarch_rev16_shright_mask_imm_p):
+ Use HOST_WIDE_INT_C for mask literal.
+ (aarch_rev16_shleft_mask_imm_p): Likewise.
+
+2014-04-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR target/60941
+ * config/sparc/sparc.md (ashlsi3_extend): Delete.
+
+2014-04-25 Marc Glisse <marc.glisse@inria.fr>
+
+ PR preprocessor/56540
+ * config/i386/i386-c.c (ix86_target_macros): Define
+ __SIZEOF_FLOAT80__ and __SIZEOF_FLOAT128__.
+
+2014-04-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * configure.ac (tga_func): Remove.
+ (LIB_TLS_SPEC): Remove.
+ * configure: Regenerate.
+ * config.in: Regenerate.
+ * config/sol2.h (LIB_SPEC): Don't use LIB_TLS_SPEC.
+
+2014-04-25 Richard Biener <rguenther@suse.de>
+
+ PR ipa/60912
+ * tree-ssa-structalias.c (ipa_pta_execute): Compute direct
+ call stmt use/clobber sets during stmt walk instead of
+ walking the possibly incomplete set of caller edges.
+
+2014-04-25 Richard Biener <rguenther@suse.de>
+
+ PR ipa/60911
+ * passes.c (apply_ipa_transforms): Inline into only caller ...
+ (execute_one_pass): ... here. Properly bring in function
+ bodies for nodes we want to apply IPA transforms to.
+
+2014-04-24 Cong Hou <congh@google.com>
+
+ PR tree-optimization/60896
+ * tree-vect-patterns.c (vect_recog_dot_prod_pattern): Pick up
+ all statements in PATTERN_DEF_SEQ in recognized widen-mult pattern.
+ (vect_mark_pattern_stmts): Set the def type of all statements in
+ PATTERN_DEF_SEQ as vect_internal_def.
+
+2014-04-24 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * doc/extend.texi (PowerPC Built-in Functions): Document new
+ powerpc extended divide, bcd, pack/unpack 128-bit, builtin
+ functions.
+ (PowerPC AltiVec/VSX Built-in Functions): Likewise.
+
+ * config/rs6000/predicates.md (const_0_to_3_operand): New
+ predicate to match 0..3 integer constants.
+
+ * config/rs6000/rs6000-builtin.def (BU_DFP_MISC_1): Add new macros
+ to support adding miscellaneous builtin functions.
+ (BU_DFP_MISC_2): Likewise.
+ (BU_P7_MISC_1): Likewise.
+ (BU_P7_MISC_2): Likewise.
+ (BU_P8V_MISC_3): Likewise.
+ (BU_MISC_1): Likewise.
+ (BU_MISC_2): Likewise.
+ (DIVWE): Add extended divide builtin functions.
+ (DIVWEO): Likewise.
+ (DIVWEU): Likewise.
+ (DIVWEUO): Likewise.
+ (DIVDE): Likewise.
+ (DIVDEO): Likewise.
+ (DIVDEU): Likewise.
+ (DIVDEUO): Likewise.
+ (DXEX): Add decimal floating-point builtin functions.
+ (DXEXQ): Likewise.
+ (DDEDPD): Likewise.
+ (DDEDPDQ): Likewise.
+ (DENBCD): Likewise.
+ (DENBCDQ): Likewise.
+ (DIEX): Likewise.
+ (DIEXQ): Likewise.
+ (DSCLI): Likewise.
+ (DSCLIQ): Likewise.
+ (DSCRI): Likewise.
+ (DSCRIQ): Likewise.
+ (CDTBCD): Add new BCD builtin functions.
+ (CBCDTD): Likewise.
+ (ADDG6S): Likewise.
+ (BCDADD): Likewise.
+ (BCDADD_LT): Likewise.
+ (BCDADD_EQ): Likewise.
+ (BCDADD_GT): Likewise.
+ (BCDADD_OV): Likewise.
+ (BCDSUB): Likewise.
+ (BCDSUB_LT): Likewise.
+ (BCDSUB_EQ): Likewise.
+ (BCDSUB_GT): Likewise.
+ (BCDSUB_OV): Likewise.
+ (PACK_TD): Add new pack/unpack 128-bit type builtin functions.
+ (UNPACK_TD): Likewise.
+ (PACK_TF): Likewise.
+ (UNPACK_TF): Likewise.
+ (UNPACK_TF_0): Likewise.
+ (UNPACK_TF_1): Likewise.
+ (PACK_V1TI): Likewise.
+ (UNPACK_V1TI): Likewise.
+
+ * config/rs6000/rs6000.c (rs6000_builtin_mask_calculate): Add
+ support for decimal floating point builtin functions.
+ (rs6000_expand_ternop_builtin): Add checks for the new builtin
+ functions that take constant arguments.
+ (rs6000_invalid_builtin): Add decimal floating point builtin
+ support.
+ (rs6000_init_builtins): Setup long double, _Decimal64, and
+ _Decimal128 types for new builtin functions.
+ (builtin_function_type): Set the unsigned flags appropriately for
+ the new builtin functions.
+ (rs6000_opt_masks): Add support for decimal floating point builtin
+ functions.
+
+ * config/rs6000/rs6000.h (RS6000_BTM_DFP): Add support for decimal
+ floating point builtin functions.
+ (RS6000_BTM_COMMON): Likewise.
+ (RS6000_BTI_long_double): Likewise.
+ (RS6000_BTI_dfloat64): Likewise.
+ (RS6000_BTI_dfloat128): Likewise.
+ (long_double_type_internal_node): Likewise.
+ (dfloat64_type_internal_node): Likewise.
+ (dfloat128_type_internal_node): Likewise.
+
+ * config/rs6000/altivec.h (UNSPEC_BCDADD): Add support for ISA
+ 2.07 bcd arithmetic instructions.
+ (UNSPEC_BCDSUB): Likewise.
+ (UNSPEC_BCD_OVERFLOW): Likewise.
+ (UNSPEC_BCD_ADD_SUB): Likewise.
+ (bcd_add_sub): Likewise.
+ (BCD_TEST): Likewise.
+ (bcd<bcd_add_sub>): Likewise.
+ (bcd<bcd_add_sub>_test): Likewise.
+ (bcd<bcd_add_sub>_test2): Likewise.
+ (bcd<bcd_add_sub>_<code>): Likewise.
+ (peephole2 for combined bcd ops): Likewise.
+
+ * config/rs6000/dfp.md (UNSPEC_DDEDPD): Add support for new
+ decimal floating point builtin functions.
+ (UNSPEC_DENBCD): Likewise.
+ (UNSPEC_DXEX): Likewise.
+ (UNSPEC_DIEX): Likewise.
+ (UNSPEC_DSCLI): Likewise.
+ (UNSPEC_DSCRI): Likewise.
+ (D64_D128): Likewise.
+ (dfp_suffix): Likewise.
+ (dfp_ddedpd_<mode>): Likewise.
+ (dfp_denbcd_<mode>): Likewise.
+ (dfp_dxex_<mode>): Likewise.
+ (dfp_diex_<mode>): Likewise.
+ (dfp_dscli_<mode>): Likewise.
+ (dfp_dscri_<mode>): Likewise.
+
+ * config/rs6000/rs6000.md (UNSPEC_ADDG6S): Add support for new BCD
+ builtin functions.
+ (UNSPEC_CDTBCD): Likewise.
+ (UNSPEC_CBCDTD): Likewise.
+ (UNSPEC_DIVE): Add support for new extended divide builtin
+ functions.
+ (UNSPEC_DIVEO): Likewise.
+ (UNSPEC_DIVEU): Likewise.
+ (UNSPEC_DIVEUO): Likewise.
+ (UNSPEC_UNPACK_128BIT): Add support for new builtin functions to
+ pack/unpack 128-bit types.
+ (UNSPEC_PACK_128BIT): Likewise.
+ (idiv_ldiv): New mode attribute to set the 32/64-bit divide type.
+ (udiv<mode>3): Use idiv_ldiv mode attribute.
+ (div<mode>3): Likewise.
+ (addg6s): Add new BCD builtin functions.
+ (cdtbcd): Likewise.
+ (cbcdtd): Likewise.
+ (UNSPEC_DIV_EXTEND): Add support for new extended divide
+ instructions.
+ (div_extend): Likewise.
+ (div<div_extend>_<mode>"): Likewise.
+ (FP128_64): Add support for new builtin functions to pack/unpack
+ 128-bit types.
+ (unpack<mode>): Likewise.
+ (unpacktf_0): Likewise.
+ (unpacktf_1): Likewise.
+ (unpack<mode>_dm): Likewise.
+ (unpack<mode>_nodm): Likewise.
+ (pack<mode>): Likewise.
+ (unpackv1ti): Likewise.
+ (packv1ti): Likewise.
+
+2014-04-24 Vishnu K S <Vishnu.k_s@atmel.com>
+
+ * gcc/config/avr/avr.c: Add comment on why -fdelete-null-pointer-checks
+ is disabled.
+
+2014-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ * tree.h (OMP_CLAUSE_LINEAR_GIMPLE_SEQ): Define.
+ * gimplify.c (omp_is_private): Change last argument's type to int.
+ Only diagnose lastprivate if the simd argument is 1, only diagnose
+ linear if the simd argument is 2.
+ (gimplify_omp_for): Adjust omp_is_private callers. When adding
+ lastprivate or private, add the clause to OMP_FOR_CLAUSES. Pass
+ GOVD_EXPLICIT to omp_add_variable. For simd with collapse == 1
+ create OMP_CLAUSE_LINEAR rather than OMP_CLAUSE_PRIVATE for var.
+ If var != decl and decl is in OMP_CLAUSE_LINEAR, gimplify decl
+ increment to OMP_CLAUSE_LINEAR_GIMPLE_SEQ.
+ * omp-low.c (scan_sharing_clauses, lower_lastprivate_clauses): Handle
+ OMP_CLAUSE_LINEAR_GIMPLE_SEQ.
+ * tree-nested.c (convert_nonlocal_omp_clauses,
+ convert_local_omp_clauses): Handle OMP_CLAUSE_LINEAR.
+
+2014-04-24 Segher Boessenkool <segher@kernel.crashing.org>
+
+ PR target/60822
+ * config/m68k/m68k.md (extendplussidi): Don't allow memory for
+ operand 1.
+
2014-04-24 Dimitris Papavasiliou <dpapavas@gmail.com>
* flag-types.h (enum ivar_visibility): Add.
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index dd60d348052..2eee80b2cf1 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20140424
+20140428
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 6dc0c11ed3f..a31cd3c2f11 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,7 @@
+2014-04-26 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gnatvsn.ads (Library_Version): Bump to 4.10.
+
2014-04-23 Eric Botcazou <ebotcazou@adacore.com>
Revert
diff --git a/gcc/ada/gnatvsn.ads b/gcc/ada/gnatvsn.ads
index d1f95621b98..a0155fe7cb9 100644
--- a/gcc/ada/gnatvsn.ads
+++ b/gcc/ada/gnatvsn.ads
@@ -6,7 +6,7 @@
-- --
-- S p e c --
-- --
--- Copyright (C) 1992-2013, Free Software Foundation, Inc. --
+-- Copyright (C) 1992-2014, 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- --
@@ -82,7 +82,7 @@ package Gnatvsn is
-- Prefix generated by binder. If it is changed, be sure to change
-- GNAT.Compiler_Version.Ver_Prefix as well.
- Library_Version : constant String := "4.9";
+ Library_Version : constant String := "4.10";
-- Library version. This value must be updated when the compiler
-- version number Gnat_Static_Version_String is updated.
--
diff --git a/gcc/alloc-pool.c b/gcc/alloc-pool.c
index dfb13ce55fb..87fbd8556fb 100644
--- a/gcc/alloc-pool.c
+++ b/gcc/alloc-pool.c
@@ -250,7 +250,7 @@ void *
pool_alloc (alloc_pool pool)
{
alloc_pool_list header;
-#ifdef ENABLE_VALGRIND_CHECKING
+#ifdef ENABLE_VALGRIND_ANNOTATIONS
int size;
#endif
@@ -265,7 +265,7 @@ pool_alloc (alloc_pool pool)
}
gcc_checking_assert (pool);
-#ifdef ENABLE_VALGRIND_CHECKING
+#ifdef ENABLE_VALGRIND_ANNOTATIONS
size = pool->elt_size - offsetof (allocation_object, u.data);
#endif
@@ -334,7 +334,7 @@ void
pool_free (alloc_pool pool, void *ptr)
{
alloc_pool_list header;
-#if defined(ENABLE_VALGRIND_CHECKING) || defined(ENABLE_CHECKING)
+#if defined(ENABLE_VALGRIND_ANNOTATIONS) || defined(ENABLE_CHECKING)
int size;
size = pool->elt_size - offsetof (allocation_object, u.data);
#endif
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index 1b466ac4b51..fb0d102eac3 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,3 +1,20 @@
+2014-04-25 Marek Polacek <polacek@redhat.com>
+
+ PR c/18079
+ * c-common.c (handle_noinline_attribute): Warn if the attribute
+ conflicts with always_inline attribute.
+ (handle_always_inline_attribute): Warn if the attribute conflicts
+ with noinline attribute.
+
+2014-04-25 Marek Polacek <polacek@redhat.com>
+
+ PR c/60156
+ * c-common.c (check_main_parameter_types): Warn about variadic main.
+
+2014-04-24 Mike Stump <mikestump@comcast.net>
+
+ * c.opt (Wshadow-ivar): Default to on.
+
2014-04-24 Dimitris Papavasiliou <dpapavas@gmail.com>
* c.opt (Wshadow-ivar, flocal-ivars, fivar-visibility): Add.
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index 347be6e8208..0afe2f5ab38 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -2229,6 +2229,10 @@ check_main_parameter_types (tree decl)
if (argct > 0 && (argct < 2 || argct > 3))
pedwarn (input_location, OPT_Wmain,
"%q+D takes only zero or two arguments", decl);
+
+ if (stdarg_p (TREE_TYPE (decl)))
+ pedwarn (input_location, OPT_Wmain,
+ "%q+D declared as variadic function", decl);
}
/* vector_targets_convertible_p is used for vector pointer types. The
@@ -6549,8 +6553,8 @@ handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args),
{
if (lookup_attribute ("cold", DECL_ATTRIBUTES (*node)) != NULL)
{
- warning (OPT_Wattributes, "%qE attribute conflicts with attribute %s",
- name, "cold");
+ warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
+ "with attribute %qs", name, "cold");
*no_add_attrs = true;
}
/* Most of the rest of the hot processing is done later with
@@ -6577,8 +6581,8 @@ handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args),
{
if (lookup_attribute ("hot", DECL_ATTRIBUTES (*node)) != NULL)
{
- warning (OPT_Wattributes, "%qE attribute conflicts with attribute %s",
- name, "hot");
+ warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
+ "with attribute %qs", name, "hot");
*no_add_attrs = true;
}
/* Most of the rest of the cold processing is done later with
@@ -6651,7 +6655,16 @@ handle_noinline_attribute (tree *node, tree name,
int ARG_UNUSED (flags), bool *no_add_attrs)
{
if (TREE_CODE (*node) == FUNCTION_DECL)
- DECL_UNINLINABLE (*node) = 1;
+ {
+ if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (*node)))
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
+ "with attribute %qs", name, "always_inline");
+ *no_add_attrs = true;
+ }
+ else
+ DECL_UNINLINABLE (*node) = 1;
+ }
else
{
warning (OPT_Wattributes, "%qE attribute ignored", name);
@@ -6689,9 +6702,16 @@ handle_always_inline_attribute (tree *node, tree name,
{
if (TREE_CODE (*node) == FUNCTION_DECL)
{
- /* Set the attribute and mark it for disregarding inline
- limits. */
- DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
+ if (lookup_attribute ("noinline", DECL_ATTRIBUTES (*node)))
+ {
+ warning (OPT_Wattributes, "%qE attribute ignored due to conflict "
+ "with %qs attribute", name, "noinline");
+ *no_add_attrs = true;
+ }
+ else
+ /* Set the attribute and mark it for disregarding inline
+ limits. */
+ DECL_DISREGARD_INLINE_LIMITS (*node) = 1;
}
else
{
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 2bc06ba7bba..94447082fb5 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -685,7 +685,7 @@ ObjC ObjC++ Var(warn_selector) Warning
Warn if a selector has multiple methods
Wshadow-ivar
-ObjC ObjC++ Var(warn_shadow_ivar) Init(-1) Warning
+ObjC ObjC++ Var(warn_shadow_ivar) Init(1) Warning
Warn if a local declaration hides an instance variable
Wsequence-point
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 2d182f354d5..80841af40ee 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,38 @@
+2014-04-25 Marek Polacek <polacek@redhat.com>
+
+ PR c/18079
+ * c-decl.c (diagnose_mismatched_decls): Warn for mismatched
+ always_inline/noinline and hot/cold attributes.
+
+2014-04-25 Marek Polacek <polacek@redhat.com>
+
+ PR c/60114
+ * c-parser.c (c_parser_initelt): Pass input_location to
+ process_init_element.
+ (c_parser_initval): Pass loc to process_init_element.
+ * c-tree.h (process_init_element): Adjust declaration.
+ * c-typeck.c (push_init_level): Pass input_location to
+ process_init_element.
+ (pop_init_level): Likewise.
+ (set_designator): Likewise.
+ (output_init_element): Add location_t parameter. Pass loc to
+ digest_init.
+ (output_pending_init_elements): Pass input_location to
+ output_init_element.
+ (process_init_element): Add location_t parameter. Pass loc to
+ output_init_element.
+
+2014-04-24 Prathamesh Kulkarni <bilbotheelffriend@gmail.com>
+
+ * c-parser.c (c_parser_sizeof_expression): Reorganize slightly to
+ avoid goto.
+
+2014-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ * c-parser.c (c_parser_omp_atomic): Allow seq_cst before
+ atomic-clause, allow comma in between atomic-clause and
+ seq_cst.
+
2014-04-22 Jakub Jelinek <jakub@redhat.com>
PR c/59073
diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c
index 82b882e3cd1..90808eda618 100644
--- a/gcc/c/c-decl.c
+++ b/gcc/c/c-decl.c
@@ -2099,18 +2099,38 @@ diagnose_mismatched_decls (tree newdecl, tree olddecl,
/* Diagnose inline __attribute__ ((noinline)) which is silly. */
if (DECL_DECLARED_INLINE_P (newdecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
- {
- warned |= warning (OPT_Wattributes,
- "inline declaration of %qD follows "
- "declaration with attribute noinline", newdecl);
- }
+ warned |= warning (OPT_Wattributes,
+ "inline declaration of %qD follows "
+ "declaration with attribute noinline", newdecl);
else if (DECL_DECLARED_INLINE_P (olddecl)
&& lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl)))
- {
- warned |= warning (OPT_Wattributes,
- "declaration of %q+D with attribute "
- "noinline follows inline declaration ", newdecl);
- }
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute "
+ "noinline follows inline declaration ", newdecl);
+ else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("always_inline", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute "
+ "%qs follows declaration with attribute %qs",
+ newdecl, "noinline", "always_inline");
+ else if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("noinline", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute "
+ "%qs follows declaration with attribute %qs",
+ newdecl, "always_inline", "noinline");
+ else if (lookup_attribute ("cold", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("hot", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute %qs follows "
+ "declaration with attribute %qs", newdecl, "cold",
+ "hot");
+ else if (lookup_attribute ("hot", DECL_ATTRIBUTES (newdecl))
+ && lookup_attribute ("cold", DECL_ATTRIBUTES (olddecl)))
+ warned |= warning (OPT_Wattributes,
+ "declaration of %q+D with attribute %qs follows "
+ "declaration with attribute %qs", newdecl, "hot",
+ "cold");
}
else /* PARM_DECL, VAR_DECL */
{
diff --git a/gcc/c/c-parser.c b/gcc/c/c-parser.c
index b1770860ae7..41ae77b541e 100644
--- a/gcc/c/c-parser.c
+++ b/gcc/c/c-parser.c
@@ -4219,7 +4219,8 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
init.original_type = NULL;
c_parser_error (parser, "expected identifier");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- process_init_element (init, false, braced_init_obstack);
+ process_init_element (input_location, init, false,
+ braced_init_obstack);
return;
}
}
@@ -4351,7 +4352,8 @@ c_parser_initelt (c_parser *parser, struct obstack * braced_init_obstack)
init.original_type = NULL;
c_parser_error (parser, "expected %<=%>");
c_parser_skip_until_found (parser, CPP_COMMA, NULL);
- process_init_element (init, false, braced_init_obstack);
+ process_init_element (input_location, init, false,
+ braced_init_obstack);
return;
}
}
@@ -4372,18 +4374,19 @@ c_parser_initval (c_parser *parser, struct c_expr *after,
{
struct c_expr init;
gcc_assert (!after || c_dialect_objc ());
+ location_t loc = c_parser_peek_token (parser)->location;
+
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE) && !after)
init = c_parser_braced_init (parser, NULL_TREE, true);
else
{
- location_t loc = c_parser_peek_token (parser)->location;
init = c_parser_expr_no_commas (parser, after);
if (init.value != NULL_TREE
&& TREE_CODE (init.value) != STRING_CST
&& TREE_CODE (init.value) != COMPOUND_LITERAL_EXPR)
init = convert_lvalue_to_rvalue (loc, init, true, true);
}
- process_init_element (init, false, braced_init_obstack);
+ process_init_element (loc, init, false, braced_init_obstack);
}
/* Parse a compound statement (possibly a function body) (C90 6.6.2,
@@ -6514,30 +6517,29 @@ c_parser_sizeof_expression (c_parser *parser)
return ret;
}
if (c_parser_next_token_is (parser, CPP_OPEN_BRACE))
+ expr = c_parser_postfix_expression_after_paren_type (parser,
+ type_name,
+ expr_loc);
+ else
{
- expr = c_parser_postfix_expression_after_paren_type (parser,
- type_name,
- expr_loc);
- goto sizeof_expr;
+ /* sizeof ( type-name ). */
+ c_inhibit_evaluation_warnings--;
+ in_sizeof--;
+ return c_expr_sizeof_type (expr_loc, type_name);
}
- /* sizeof ( type-name ). */
- c_inhibit_evaluation_warnings--;
- in_sizeof--;
- return c_expr_sizeof_type (expr_loc, type_name);
}
else
{
expr_loc = c_parser_peek_token (parser)->location;
expr = c_parser_unary_expression (parser);
- sizeof_expr:
- c_inhibit_evaluation_warnings--;
- in_sizeof--;
- mark_exp_read (expr.value);
- if (TREE_CODE (expr.value) == COMPONENT_REF
- && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
- error_at (expr_loc, "%<sizeof%> applied to a bit-field");
- return c_expr_sizeof_expr (expr_loc, expr);
}
+ c_inhibit_evaluation_warnings--;
+ in_sizeof--;
+ mark_exp_read (expr.value);
+ if (TREE_CODE (expr.value) == COMPONENT_REF
+ && DECL_C_BIT_FIELD (TREE_OPERAND (expr.value, 1)))
+ error_at (expr_loc, "%<sizeof%> applied to a bit-field");
+ return c_expr_sizeof_expr (expr_loc, expr);
}
/* Parse an alignof expression. */
@@ -11198,6 +11200,18 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
if (c_parser_next_token_is (parser, CPP_NAME))
{
const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (!strcmp (p, "seq_cst"))
+ {
+ seq_cst = true;
+ c_parser_consume_token (parser);
+ if (c_parser_next_token_is (parser, CPP_COMMA)
+ && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
+ c_parser_consume_token (parser);
+ }
+ }
+ if (c_parser_next_token_is (parser, CPP_NAME))
+ {
+ const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
if (!strcmp (p, "read"))
code = OMP_ATOMIC_READ;
@@ -11212,13 +11226,21 @@ c_parser_omp_atomic (location_t loc, c_parser *parser)
if (p)
c_parser_consume_token (parser);
}
- if (c_parser_next_token_is (parser, CPP_NAME))
+ if (!seq_cst)
{
- const char *p = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
- if (!strcmp (p, "seq_cst"))
+ if (c_parser_next_token_is (parser, CPP_COMMA)
+ && c_parser_peek_2nd_token (parser)->type == CPP_NAME)
+ c_parser_consume_token (parser);
+
+ if (c_parser_next_token_is (parser, CPP_NAME))
{
- seq_cst = true;
- c_parser_consume_token (parser);
+ const char *p
+ = IDENTIFIER_POINTER (c_parser_peek_token (parser)->value);
+ if (!strcmp (p, "seq_cst"))
+ {
+ seq_cst = true;
+ c_parser_consume_token (parser);
+ }
}
}
c_parser_skip_to_pragma_eol (parser);
diff --git a/gcc/c/c-tree.h b/gcc/c/c-tree.h
index 85df8858dea..53768d619b7 100644
--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -612,7 +612,8 @@ extern void push_init_level (int, struct obstack *);
extern struct c_expr pop_init_level (int, struct obstack *);
extern void set_init_index (tree, tree, struct obstack *);
extern void set_init_label (tree, struct obstack *);
-extern void process_init_element (struct c_expr, bool, struct obstack *);
+extern void process_init_element (location_t, struct c_expr, bool,
+ struct obstack *);
extern tree build_compound_literal (location_t, tree, tree, bool);
extern void check_compound_literal_type (location_t, struct c_type_name *);
extern tree c_start_case (location_t, location_t, tree);
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 886ef518be6..e4293104d7b 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -103,8 +103,8 @@ static int spelling_length (void);
static char *print_spelling (char *);
static void warning_init (int, const char *);
static tree digest_init (location_t, tree, tree, tree, bool, bool, int);
-static void output_init_element (tree, tree, bool, tree, tree, int, bool,
- struct obstack *);
+static void output_init_element (location_t, tree, tree, bool, tree, tree, int,
+ bool, struct obstack *);
static void output_pending_init_elements (int, struct obstack *);
static int set_designator (int, struct obstack *);
static void push_range_stack (tree, struct obstack *);
@@ -7182,13 +7182,15 @@ push_init_level (int implicit, struct obstack * braced_init_obstack)
if ((TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
&& constructor_fields == 0)
- process_init_element (pop_init_level (1, braced_init_obstack),
+ process_init_element (input_location,
+ pop_init_level (1, braced_init_obstack),
true, braced_init_obstack);
else if (TREE_CODE (constructor_type) == ARRAY_TYPE
&& constructor_max_index
&& tree_int_cst_lt (constructor_max_index,
constructor_index))
- process_init_element (pop_init_level (1, braced_init_obstack),
+ process_init_element (input_location,
+ pop_init_level (1, braced_init_obstack),
true, braced_init_obstack);
else
break;
@@ -7388,10 +7390,9 @@ pop_init_level (int implicit, struct obstack * braced_init_obstack)
/* When we come to an explicit close brace,
pop any inner levels that didn't have explicit braces. */
while (constructor_stack->implicit)
- {
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
- }
+ process_init_element (input_location,
+ pop_init_level (1, braced_init_obstack),
+ true, braced_init_obstack);
gcc_assert (!constructor_range_stack);
}
@@ -7569,10 +7570,9 @@ set_designator (int array, struct obstack * braced_init_obstack)
/* Designator list starts at the level of closest explicit
braces. */
while (constructor_stack->implicit)
- {
- process_init_element (pop_init_level (1, braced_init_obstack),
- true, braced_init_obstack);
- }
+ process_init_element (input_location,
+ pop_init_level (1, braced_init_obstack),
+ true, braced_init_obstack);
constructor_designated = 1;
return 0;
}
@@ -8194,9 +8194,9 @@ find_init_member (tree field, struct obstack * braced_init_obstack)
existing initializer. */
static void
-output_init_element (tree value, tree origtype, bool strict_string, tree type,
- tree field, int pending, bool implicit,
- struct obstack * braced_init_obstack)
+output_init_element (location_t loc, tree value, tree origtype,
+ bool strict_string, tree type, tree field, int pending,
+ bool implicit, struct obstack * braced_init_obstack)
{
tree semantic_type = NULL_TREE;
bool maybe_const = true;
@@ -8294,8 +8294,8 @@ output_init_element (tree value, tree origtype, bool strict_string, tree type,
if (semantic_type)
value = build1 (EXCESS_PRECISION_EXPR, semantic_type, value);
- value = digest_init (input_location, type, value, origtype, npc,
- strict_string, require_constant_value);
+ value = digest_init (loc, type, value, origtype, npc, strict_string,
+ require_constant_value);
if (value == error_mark_node)
{
constructor_erroneous = 1;
@@ -8422,8 +8422,8 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack)
{
if (tree_int_cst_equal (elt->purpose,
constructor_unfilled_index))
- output_init_element (elt->value, elt->origtype, true,
- TREE_TYPE (constructor_type),
+ output_init_element (input_location, elt->value, elt->origtype,
+ true, TREE_TYPE (constructor_type),
constructor_unfilled_index, 0, false,
braced_init_obstack);
else if (tree_int_cst_lt (constructor_unfilled_index,
@@ -8477,8 +8477,8 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack)
if (tree_int_cst_equal (elt_bitpos, ctor_unfilled_bitpos))
{
constructor_unfilled_fields = elt->purpose;
- output_init_element (elt->value, elt->origtype, true,
- TREE_TYPE (elt->purpose),
+ output_init_element (input_location, elt->value, elt->origtype,
+ true, TREE_TYPE (elt->purpose),
elt->purpose, 0, false,
braced_init_obstack);
}
@@ -8551,7 +8551,7 @@ output_pending_init_elements (int all, struct obstack * braced_init_obstack)
existing initializer. */
void
-process_init_element (struct c_expr value, bool implicit,
+process_init_element (location_t loc, struct c_expr value, bool implicit,
struct obstack * braced_init_obstack)
{
tree orig_value = value.value;
@@ -8595,14 +8595,14 @@ process_init_element (struct c_expr value, bool implicit,
if ((TREE_CODE (constructor_type) == RECORD_TYPE
|| TREE_CODE (constructor_type) == UNION_TYPE)
&& constructor_fields == 0)
- process_init_element (pop_init_level (1, braced_init_obstack),
+ process_init_element (loc, pop_init_level (1, braced_init_obstack),
true, braced_init_obstack);
else if ((TREE_CODE (constructor_type) == ARRAY_TYPE
|| TREE_CODE (constructor_type) == VECTOR_TYPE)
&& constructor_max_index
&& tree_int_cst_lt (constructor_max_index,
constructor_index))
- process_init_element (pop_init_level (1, braced_init_obstack),
+ process_init_element (loc, pop_init_level (1, braced_init_obstack),
true, braced_init_obstack);
else
break;
@@ -8680,7 +8680,7 @@ process_init_element (struct c_expr value, bool implicit,
if (value.value)
{
push_member_name (constructor_fields);
- output_init_element (value.value, value.original_type,
+ output_init_element (loc, value.value, value.original_type,
strict_string, fieldtype,
constructor_fields, 1, implicit,
braced_init_obstack);
@@ -8772,7 +8772,7 @@ process_init_element (struct c_expr value, bool implicit,
if (value.value)
{
push_member_name (constructor_fields);
- output_init_element (value.value, value.original_type,
+ output_init_element (loc, value.value, value.original_type,
strict_string, fieldtype,
constructor_fields, 1, implicit,
braced_init_obstack);
@@ -8824,7 +8824,7 @@ process_init_element (struct c_expr value, bool implicit,
if (value.value)
{
push_array_bounds (tree_to_uhwi (constructor_index));
- output_init_element (value.value, value.original_type,
+ output_init_element (loc, value.value, value.original_type,
strict_string, elttype,
constructor_index, 1, implicit,
braced_init_obstack);
@@ -8859,7 +8859,7 @@ process_init_element (struct c_expr value, bool implicit,
{
if (TREE_CODE (value.value) == VECTOR_CST)
elttype = TYPE_MAIN_VARIANT (constructor_type);
- output_init_element (value.value, value.original_type,
+ output_init_element (loc, value.value, value.original_type,
strict_string, elttype,
constructor_index, 1, implicit,
braced_init_obstack);
@@ -8888,7 +8888,7 @@ process_init_element (struct c_expr value, bool implicit,
else
{
if (value.value)
- output_init_element (value.value, value.original_type,
+ output_init_element (loc, value.value, value.original_type,
strict_string, constructor_type,
NULL_TREE, 1, implicit,
braced_init_obstack);
@@ -8907,8 +8907,8 @@ process_init_element (struct c_expr value, bool implicit,
while (constructor_stack != range_stack->stack)
{
gcc_assert (constructor_stack->implicit);
- process_init_element (pop_init_level (1,
- braced_init_obstack),
+ process_init_element (loc,
+ pop_init_level (1, braced_init_obstack),
true, braced_init_obstack);
}
for (p = range_stack;
@@ -8916,7 +8916,8 @@ process_init_element (struct c_expr value, bool implicit,
p = p->prev)
{
gcc_assert (constructor_stack->implicit);
- process_init_element (pop_init_level (1, braced_init_obstack),
+ process_init_element (loc,
+ pop_init_level (1, braced_init_obstack),
true, braced_init_obstack);
}
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 28524f85ca1..b5df572d039 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1695,8 +1695,8 @@ release_function_body (tree decl)
}
if (cfun->cfg)
{
- gcc_assert (dom_computed[0] == DOM_NONE);
- gcc_assert (dom_computed[1] == DOM_NONE);
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
clear_edges ();
cfun->cfg = NULL;
}
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 7bf9a07cbb2..d06ce3217fd 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -520,7 +520,7 @@ 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 (passes->all_lowering_passes);
+ execute_pass_list (cfun, passes->all_lowering_passes);
passes->execute_early_local_passes ();
bitmap_obstack_release (NULL);
pop_cfun ();
@@ -658,7 +658,7 @@ analyze_function (struct cgraph_node *node)
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
- execute_pass_list (g->get_passes ()->all_lowering_passes);
+ execute_pass_list (cfun, g->get_passes ()->all_lowering_passes);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
compact_blocks ();
@@ -1771,7 +1771,7 @@ expand_function (struct cgraph_node *node)
/* Signal the start of passes. */
invoke_plugin_callbacks (PLUGIN_ALL_PASSES_START, NULL);
- execute_pass_list (g->get_passes ()->all_passes);
+ execute_pass_list (cfun, g->get_passes ()->all_passes);
/* Signal the end of passes. */
invoke_plugin_callbacks (PLUGIN_ALL_PASSES_END, NULL);
diff --git a/gcc/config.in b/gcc/config.in
index af02866dd33..c0ba36ea98b 100644
--- a/gcc/config.in
+++ b/gcc/config.in
@@ -172,6 +172,12 @@
#endif
+/* Define to get calls to the valgrind runtime enabled. */
+#ifndef USED_FOR_TARGET
+#undef ENABLE_VALGRIND_ANNOTATIONS
+#endif
+
+
/* Define if you want to run subprograms and generated programs through
valgrind (a memory checker). This is extremely expensive. */
#ifndef USED_FOR_TARGET
@@ -1697,12 +1703,6 @@
#endif
-/* Define to the library containing __tls_get_addr/___tls_get_addr. */
-#ifndef USED_FOR_TARGET
-#undef LIB_TLS_SPEC
-#endif
-
-
/* The linker hash style */
#ifndef USED_FOR_TARGET
#undef LINKER_HASH_STYLE
diff --git a/gcc/config/arm/aarch-common.c b/gcc/config/arm/aarch-common.c
index 884d4b37fac..d31191ab9e7 100644
--- a/gcc/config/arm/aarch-common.c
+++ b/gcc/config/arm/aarch-common.c
@@ -195,14 +195,18 @@ bool
aarch_rev16_shright_mask_imm_p (rtx val, enum machine_mode mode)
{
return CONST_INT_P (val)
- && INTVAL (val) == trunc_int_for_mode (0xff00ff00ff00ff, mode);
+ && INTVAL (val)
+ == trunc_int_for_mode (HOST_WIDE_INT_C (0xff00ff00ff00ff),
+ mode);
}
bool
aarch_rev16_shleft_mask_imm_p (rtx val, enum machine_mode mode)
{
return CONST_INT_P (val)
- && INTVAL (val) == trunc_int_for_mode (0xff00ff00ff00ff00, mode);
+ && INTVAL (val)
+ == trunc_int_for_mode (HOST_WIDE_INT_C (0xff00ff00ff00ff00),
+ mode);
}
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 8ca945f1a67..1e44080d601 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1710,7 +1710,8 @@ const struct tune_params arm_cortex_a8_tune =
false, /* Prefer LDRD/STRD. */
{true, true}, /* Prefer non short circuit. */
&arm_default_vec_cost, /* Vectorizer costs. */
- false /* Prefer Neon for 64-bits bitops. */
+ false, /* Prefer Neon for 64-bits bitops. */
+ false, false /* Prefer 32-bit encodings. */
};
const struct tune_params arm_cortex_a7_tune =
@@ -6216,11 +6217,6 @@ arm_function_ok_for_sibcall (tree decl, tree exp)
if (TARGET_VXWORKS_RTP && flag_pic && !targetm.binds_local_p (decl))
return false;
- /* Cannot tail-call to long calls, since these are out of range of
- a branch instruction. */
- if (decl && arm_is_long_call_p (decl))
- return false;
-
/* If we are interworking and the function is not declared static
then we can't tail-call it unless we know that it exists in this
compilation unit (since it might be a Thumb routine). */
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 8a949b929fa..97753ce1e98 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -9367,8 +9367,10 @@
"TARGET_32BIT"
"
{
- if (!REG_P (XEXP (operands[0], 0))
- && (GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF))
+ if ((!REG_P (XEXP (operands[0], 0))
+ && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF)
+ || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF
+ && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0)))))
XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0));
if (operands[2] == NULL_RTX)
@@ -9385,8 +9387,10 @@
"TARGET_32BIT"
"
{
- if (!REG_P (XEXP (operands[1], 0)) &&
- (GET_CODE (XEXP (operands[1],0)) != SYMBOL_REF))
+ if ((!REG_P (XEXP (operands[1], 0))
+ && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF)
+ || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
+ && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0)))))
XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0));
if (operands[3] == NULL_RTX)
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 6273e8820c6..d74fcb31bc7 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -681,5 +681,6 @@
(match_code "reg" "0")))
(define_predicate "call_insn_operand"
- (ior (match_code "symbol_ref")
+ (ior (and (match_code "symbol_ref")
+ (match_test "!arm_is_long_call_p (SYMBOL_REF_DECL (op))"))
(match_operand 0 "s_register_operand")))
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 25075b2f4b3..0fa7f6633e2 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -290,6 +290,12 @@ avr_to_int_mode (rtx x)
static void
avr_option_override (void)
{
+ /* Disable -fdelete-null-pointer-checks option for AVR target.
+ This option compiler assumes that dereferencing of a null pointer
+ would halt the program. For AVR this assumption is not true and
+ programs can safely dereference null pointers. Changes made by this
+ option may not work properly for AVR. So disable this option. */
+
flag_delete_null_pointer_checks = 0;
/* caller-save.c looks for call-clobbered hard registers that are assigned
diff --git a/gcc/config/i386/i386-c.c b/gcc/config/i386/i386-c.c
index c9977bf2b0e..2c31dc8062d 100644
--- a/gcc/config/i386/i386-c.c
+++ b/gcc/config/i386/i386-c.c
@@ -518,6 +518,13 @@ ix86_target_macros (void)
if (TARGET_LONG_DOUBLE_128)
cpp_define (parse_in, "__LONG_DOUBLE_128__");
+ if (TARGET_128BIT_LONG_DOUBLE)
+ cpp_define (parse_in, "__SIZEOF_FLOAT80__=16");
+ else
+ cpp_define (parse_in, "__SIZEOF_FLOAT80__=12");
+
+ cpp_define (parse_in, "__SIZEOF_FLOAT128__=16");
+
cpp_define_formatted (parse_in, "__ATOMIC_HLE_ACQUIRE=%d", IX86_HLE_ACQUIRE);
cpp_define_formatted (parse_in, "__ATOMIC_HLE_RELEASE=%d", IX86_HLE_RELEASE);
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 25e2e93e317..fde0a93e68f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -3201,7 +3201,7 @@
(const_string "1")
(const_string "*")))
(set (attr "mode")
- (cond [(eq_attr "alternative" "3,4,9,10,13,14,15")
+ (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
(const_string "SI")
(eq_attr "alternative" "11")
(const_string "DI")
@@ -14427,15 +14427,16 @@
"TARGET_USE_FANCY_MATH_387
&& flag_unsafe_math_optimizations"
{
+ rtx tmp1, tmp2;
if (optimize_insn_for_size_p ())
FAIL;
- operands[3] = gen_reg_rtx (XFmode);
- operands[4] = gen_reg_rtx (XFmode);
+ tmp1 = gen_reg_rtx (XFmode);
+ tmp2 = gen_reg_rtx (XFmode);
- emit_insn (gen_floatsixf2 (operands[3], operands[2]));
- emit_insn (gen_fscalexf4_i387 (operands[0], operands[4],
- operands[1], operands[3]));
+ emit_insn (gen_floatsixf2 (tmp1, operands[2]));
+ emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
+ operands[1], tmp1));
DONE;
})
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index e61048b4d0b..72c11f592db 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -1868,9 +1868,11 @@
;; Maybe there is a way to make that the general case, by forcing the
;; result of the SI tree to be in the lower register of the DI target
+;; Don't allow memory for operand 1 as that would require an earlyclobber
+;; which results in worse code
(define_insn "extendplussidi"
[(set (match_operand:DI 0 "register_operand" "=d")
- (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rmn")
+ (sign_extend:DI (plus:SI (match_operand:SI 1 "general_operand" "%rn")
(match_operand:SI 2 "general_operand" "rmn"))))]
""
{
diff --git a/gcc/config/rs6000/altivec.md b/gcc/config/rs6000/altivec.md
index 674cb40bf7a..a8cfcb739ea 100644
--- a/gcc/config/rs6000/altivec.md
+++ b/gcc/config/rs6000/altivec.md
@@ -143,6 +143,9 @@
UNSPEC_VSUBEUQM
UNSPEC_VSUBECUQ
UNSPEC_VBPERMQ
+ UNSPEC_BCDADD
+ UNSPEC_BCDSUB
+ UNSPEC_BCD_OVERFLOW
])
(define_c_enum "unspecv"
@@ -3334,3 +3337,112 @@
"vbpermq %0,%1,%2"
[(set_attr "length" "4")
(set_attr "type" "vecsimple")])
+
+;; Decimal Integer operations
+(define_int_iterator UNSPEC_BCD_ADD_SUB [UNSPEC_BCDADD UNSPEC_BCDSUB])
+
+(define_int_attr bcd_add_sub [(UNSPEC_BCDADD "add")
+ (UNSPEC_BCDSUB "sub")])
+
+(define_code_iterator BCD_TEST [eq lt gt unordered])
+
+(define_insn "bcd<bcd_add_sub>"
+ [(set (match_operand:V1TI 0 "register_operand" "")
+ (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
+ (match_operand:V1TI 2 "register_operand" "")
+ (match_operand:QI 3 "const_0_to_1_operand" "")]
+ UNSPEC_BCD_ADD_SUB))
+ (clobber (reg:CCFP 74))]
+ "TARGET_P8_VECTOR"
+ "bcd<bcd_add_sub>. %0,%1,%2,%3"
+ [(set_attr "length" "4")
+ (set_attr "type" "vecsimple")])
+
+;; Use a floating point type (V2DFmode) for the compare to set CR6 so that we
+;; can use the unordered test for BCD nans and add/subtracts that overflow. An
+;; UNORDERED test on an integer type (like V1TImode) is not defined. The type
+;; probably should be one that can go in the VMX (Altivec) registers, so we
+;; can't use DDmode or DFmode.
+(define_insn "*bcd<bcd_add_sub>_test"
+ [(set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "v")
+ (match_operand:V1TI 2 "register_operand" "v")
+ (match_operand:QI 3 "const_0_to_1_operand" "i")]
+ UNSPEC_BCD_ADD_SUB)
+ (match_operand:V2DF 4 "zero_constant" "j")))
+ (clobber (match_scratch:V1TI 0 "=v"))]
+ "TARGET_P8_VECTOR"
+ "bcd<bcd_add_sub>. %0,%1,%2,%3"
+ [(set_attr "length" "4")
+ (set_attr "type" "vecsimple")])
+
+(define_insn "*bcd<bcd_add_sub>_test2"
+ [(set (match_operand:V1TI 0 "register_operand" "=v")
+ (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "v")
+ (match_operand:V1TI 2 "register_operand" "v")
+ (match_operand:QI 3 "const_0_to_1_operand" "i")]
+ UNSPEC_BCD_ADD_SUB))
+ (set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)]
+ UNSPEC_BCD_ADD_SUB)
+ (match_operand:V2DF 4 "zero_constant" "j")))]
+ "TARGET_P8_VECTOR"
+ "bcd<bcd_add_sub>. %0,%1,%2,%3"
+ [(set_attr "length" "4")
+ (set_attr "type" "vecsimple")])
+
+(define_expand "bcd<bcd_add_sub>_<code>"
+ [(parallel [(set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_operand:V1TI 1 "register_operand" "")
+ (match_operand:V1TI 2 "register_operand" "")
+ (match_operand:QI 3 "const_0_to_1_operand" "")]
+ UNSPEC_BCD_ADD_SUB)
+ (match_dup 4)))
+ (clobber (match_scratch:V1TI 5 ""))])
+ (set (match_operand:SI 0 "register_operand" "")
+ (BCD_TEST:SI (reg:CCFP 74)
+ (const_int 0)))]
+ "TARGET_P8_VECTOR"
+{
+ operands[4] = CONST0_RTX (V2DFmode);
+})
+
+;; Peephole2 pattern to combine a bcdadd/bcdsub that calculates the value and
+;; the bcdadd/bcdsub that tests the value. The combiner won't work since
+;; CR6 is a hard coded register. Unfortunately, all of the Altivec predicate
+;; support is hard coded to use the fixed register CR6 instead of creating
+;; a register class for CR6.
+
+(define_peephole2
+ [(parallel [(set (match_operand:V1TI 0 "register_operand" "")
+ (unspec:V1TI [(match_operand:V1TI 1 "register_operand" "")
+ (match_operand:V1TI 2 "register_operand" "")
+ (match_operand:QI 3 "const_0_to_1_operand" "")]
+ UNSPEC_BCD_ADD_SUB))
+ (clobber (reg:CCFP 74))])
+ (parallel [(set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)]
+ UNSPEC_BCD_ADD_SUB)
+ (match_operand:V2DF 4 "zero_constant" "")))
+ (clobber (match_operand:V1TI 5 "register_operand" ""))])]
+ "TARGET_P8_VECTOR"
+ [(parallel [(set (match_dup 0)
+ (unspec:V1TI [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)]
+ UNSPEC_BCD_ADD_SUB))
+ (set (reg:CCFP 74)
+ (compare:CCFP
+ (unspec:V2DF [(match_dup 1)
+ (match_dup 2)
+ (match_dup 3)]
+ UNSPEC_BCD_ADD_SUB)
+ (match_dup 4)))])])
diff --git a/gcc/config/rs6000/dfp.md b/gcc/config/rs6000/dfp.md
index 8e99bc0d787..40e27e77d23 100644
--- a/gcc/config/rs6000/dfp.md
+++ b/gcc/config/rs6000/dfp.md
@@ -322,3 +322,72 @@
"TARGET_DFP"
"dctfixq %0,%1"
[(set_attr "type" "fp")])
+
+
+;; Decimal builtin support
+
+(define_c_enum "unspec"
+ [UNSPEC_DDEDPD
+ UNSPEC_DENBCD
+ UNSPEC_DXEX
+ UNSPEC_DIEX
+ UNSPEC_DSCLI
+ UNSPEC_DSCRI])
+
+(define_mode_iterator D64_D128 [DD TD])
+
+(define_mode_attr dfp_suffix [(DD "")
+ (TD "q")])
+
+(define_insn "dfp_ddedpd_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_3_operand" "i")
+ (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+ UNSPEC_DDEDPD))]
+ "TARGET_DFP"
+ "ddedpd<dfp_suffix> %1,%0,%2"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_denbcd_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:QI 1 "const_0_to_1_operand" "i")
+ (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+ UNSPEC_DENBCD))]
+ "TARGET_DFP"
+ "denbcd<dfp_suffix> %1,%0,%2"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_dxex_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")]
+ UNSPEC_DXEX))]
+ "TARGET_DFP"
+ "dxex<dfp_suffix> %0,%1"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_diex_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+ (match_operand:D64_D128 2 "gpc_reg_operand" "d")]
+ UNSPEC_DXEX))]
+ "TARGET_DFP"
+ "diex<dfp_suffix> %0,%1,%2"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_dscli_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+ (match_operand:QI 2 "immediate_operand" "i")]
+ UNSPEC_DSCLI))]
+ "TARGET_DFP"
+ "dscli<dfp_suffix> %0,%1,%2"
+ [(set_attr "type" "fp")])
+
+(define_insn "dfp_dscri_<mode>"
+ [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d")
+ (unspec:D64_D128 [(match_operand:D64_D128 1 "gpc_reg_operand" "d")
+ (match_operand:QI 2 "immediate_operand" "i")]
+ UNSPEC_DSCRI))]
+ "TARGET_DFP"
+ "dscri<dfp_suffix> %0,%1,%2"
+ [(set_attr "type" "fp")])
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 2ed1d4a184d..1616b888c9c 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -171,6 +171,11 @@
(and (match_code "const_int")
(match_test "IN_RANGE (INTVAL (op), 0, 1)")))
+;; Match op = 0..3.
+(define_predicate "const_0_to_3_operand"
+ (and (match_code "const_int")
+ (match_test "IN_RANGE (INTVAL (op), 0, 3)")))
+
;; Match op = 2 or op = 3.
(define_predicate "const_2_to_3_operand"
(and (match_code "const_int")
diff --git a/gcc/config/rs6000/rs6000-builtin.def b/gcc/config/rs6000/rs6000-builtin.def
index 83351691fa5..16793f501e7 100644
--- a/gcc/config/rs6000/rs6000-builtin.def
+++ b/gcc/config/rs6000/rs6000-builtin.def
@@ -570,6 +570,75 @@
MASK, /* MASK */ \
(ATTR | RS6000_BTC_SPECIAL), /* ATTR */ \
CODE_FOR_nothing) /* ICODE */
+
+
+/* Decimal floating point builtins for instructions. */
+#define BU_DFP_MISC_1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_DFP, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_DFP_MISC_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_DFP, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+
+/* Miscellaneous builtins for instructions added in ISA 2.06. These
+ instructions don't require either the DFP or VSX options, just the basic ISA
+ 2.06 (popcntd) enablement since they operate on general purpose
+ registers. */
+#define BU_P7_MISC_1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_1 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_POPCNTD, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_P7_MISC_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_POPCNTD, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+
+/* Miscellaneous builtins for instructions added in ISA 2.07. These
+ instructions do require the ISA 2.07 vector support, but they aren't vector
+ instructions. */
+#define BU_P8V_MISC_3(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_3 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_P8_VECTOR, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_TERNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+/* Miscellaneous builtins. */
+#define BU_MISC_1(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_ALWAYS, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_UNARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
+#define BU_MISC_2(ENUM, NAME, ATTR, ICODE) \
+ RS6000_BUILTIN_2 (MISC_BUILTIN_ ## ENUM, /* ENUM */ \
+ "__builtin_" NAME, /* NAME */ \
+ RS6000_BTM_ALWAYS, /* MASK */ \
+ (RS6000_BTC_ ## ATTR /* ATTR */ \
+ | RS6000_BTC_BINARY), \
+ CODE_FOR_ ## ICODE) /* ICODE */
+
#endif
/* Insure 0 is not a legitimate index. */
@@ -1412,10 +1481,10 @@ BU_P8V_AV_2 (ORC_V4SF, "orc_v4sf", CONST, orcv4sf3)
BU_P8V_AV_2 (ORC_V2DF, "orc_v2df", CONST, orcv2df3)
/* 3 argument altivec instructions added in ISA 2.07. */
-BU_P8V_AV_3 (VADDEUQM, "vaddeuqm", CONST, altivec_vaddeuqm)
-BU_P8V_AV_3 (VADDECUQ, "vaddecuq", CONST, altivec_vaddecuq)
-BU_P8V_AV_3 (VSUBEUQM, "vsubeuqm", CONST, altivec_vsubeuqm)
-BU_P8V_AV_3 (VSUBECUQ, "vsubecuq", CONST, altivec_vsubecuq)
+BU_P8V_AV_3 (VADDEUQM, "vaddeuqm", CONST, altivec_vaddeuqm)
+BU_P8V_AV_3 (VADDECUQ, "vaddecuq", CONST, altivec_vaddecuq)
+BU_P8V_AV_3 (VSUBEUQM, "vsubeuqm", CONST, altivec_vsubeuqm)
+BU_P8V_AV_3 (VSUBECUQ, "vsubecuq", CONST, altivec_vsubecuq)
/* Vector comparison instructions added in ISA 2.07. */
BU_P8V_AV_2 (VCMPEQUD, "vcmpequd", CONST, vector_eqv2di)
@@ -1475,6 +1544,64 @@ BU_P8V_OVERLOAD_3 (VSUBECUQ, "vsubecuq")
BU_P8V_OVERLOAD_3 (VSUBEUQM, "vsubeuqm")
+/* 2 argument extended divide functions added in ISA 2.06. */
+BU_P7_MISC_2 (DIVWE, "divwe", CONST, dive_si)
+BU_P7_MISC_2 (DIVWEO, "divweo", CONST, diveo_si)
+BU_P7_MISC_2 (DIVWEU, "divweu", CONST, diveu_si)
+BU_P7_MISC_2 (DIVWEUO, "divweuo", CONST, diveuo_si)
+BU_P7_MISC_2 (DIVDE, "divde", CONST, dive_di)
+BU_P7_MISC_2 (DIVDEO, "divdeo", CONST, diveo_di)
+BU_P7_MISC_2 (DIVDEU, "divdeu", CONST, diveu_di)
+BU_P7_MISC_2 (DIVDEUO, "divdeuo", CONST, diveuo_di)
+
+/* 1 argument DFP (decimal floating point) functions added in ISA 2.05. */
+BU_DFP_MISC_1 (DXEX, "dxex", CONST, dfp_dxex_dd)
+BU_DFP_MISC_1 (DXEXQ, "dxexq", CONST, dfp_dxex_td)
+
+/* 2 argument DFP (decimal floating point) functions added in ISA 2.05. */
+BU_DFP_MISC_2 (DDEDPD, "ddedpd", CONST, dfp_ddedpd_dd)
+BU_DFP_MISC_2 (DDEDPDQ, "ddedpdq", CONST, dfp_ddedpd_td)
+BU_DFP_MISC_2 (DENBCD, "denbcd", CONST, dfp_denbcd_dd)
+BU_DFP_MISC_2 (DENBCDQ, "denbcdq", CONST, dfp_denbcd_td)
+BU_DFP_MISC_2 (DIEX, "diex", CONST, dfp_diex_dd)
+BU_DFP_MISC_2 (DIEXQ, "diexq", CONST, dfp_diex_td)
+BU_DFP_MISC_2 (DSCLI, "dscli", CONST, dfp_dscli_dd)
+BU_DFP_MISC_2 (DSCLIQ, "dscliq", CONST, dfp_dscli_td)
+BU_DFP_MISC_2 (DSCRI, "dscri", CONST, dfp_dscri_dd)
+BU_DFP_MISC_2 (DSCRIQ, "dscriq", CONST, dfp_dscri_td)
+
+/* 1 argument BCD functions added in ISA 2.06. */
+BU_P7_MISC_1 (CDTBCD, "cdtbcd", CONST, cdtbcd)
+BU_P7_MISC_1 (CBCDTD, "cbcdtd", CONST, cbcdtd)
+
+/* 2 argument BCD functions added in ISA 2.06. */
+BU_P7_MISC_2 (ADDG6S, "addg6s", CONST, addg6s)
+
+/* 3 argument BCD functions added in ISA 2.07. */
+BU_P8V_MISC_3 (BCDADD, "bcdadd", CONST, bcdadd)
+BU_P8V_MISC_3 (BCDADD_LT, "bcdadd_lt", CONST, bcdadd_lt)
+BU_P8V_MISC_3 (BCDADD_EQ, "bcdadd_eq", CONST, bcdadd_eq)
+BU_P8V_MISC_3 (BCDADD_GT, "bcdadd_gt", CONST, bcdadd_gt)
+BU_P8V_MISC_3 (BCDADD_OV, "bcdadd_ov", CONST, bcdadd_unordered)
+BU_P8V_MISC_3 (BCDSUB, "bcdsub", CONST, bcdsub)
+BU_P8V_MISC_3 (BCDSUB_LT, "bcdsub_lt", CONST, bcdsub_lt)
+BU_P8V_MISC_3 (BCDSUB_EQ, "bcdsub_eq", CONST, bcdsub_eq)
+BU_P8V_MISC_3 (BCDSUB_GT, "bcdsub_gt", CONST, bcdsub_gt)
+BU_P8V_MISC_3 (BCDSUB_OV, "bcdsub_ov", CONST, bcdsub_unordered)
+
+/* 2 argument pack/unpack 128-bit floating point types. */
+BU_DFP_MISC_2 (PACK_TD, "pack_dec128", CONST, packtd)
+BU_DFP_MISC_2 (UNPACK_TD, "unpack_dec128", CONST, unpacktd)
+
+BU_MISC_2 (PACK_TF, "pack_longdouble", CONST, packtf)
+BU_MISC_2 (UNPACK_TF, "unpack_longdouble", CONST, unpacktf)
+BU_MISC_1 (UNPACK_TF_0, "longdouble_dw0", CONST, unpacktf_0)
+BU_MISC_1 (UNPACK_TF_1, "longdouble_dw1", CONST, unpacktf_1)
+
+BU_P7_MISC_2 (PACK_V1TI, "pack_vector_int128", CONST, packv1ti)
+BU_P7_MISC_2 (UNPACK_V1TI, "unpack_vector_int128", CONST, unpackv1ti)
+
+
/* 1 argument crypto functions. */
BU_CRYPTO_1 (VSBOX, "vsbox", CONST, crypto_vsbox)
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index bab79df7760..0c983f9a105 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -3038,7 +3038,8 @@ rs6000_builtin_mask_calculate (void)
| ((rs6000_cpu == PROCESSOR_CELL) ? RS6000_BTM_CELL : 0)
| ((TARGET_P8_VECTOR) ? RS6000_BTM_P8_VECTOR : 0)
| ((TARGET_CRYPTO) ? RS6000_BTM_CRYPTO : 0)
- | ((TARGET_HTM) ? RS6000_BTM_HTM : 0));
+ | ((TARGET_HTM) ? RS6000_BTM_HTM : 0)
+ | ((TARGET_DFP) ? RS6000_BTM_DFP : 0));
}
/* Override command line options. Mostly we process the processor type and
@@ -12396,7 +12397,15 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
}
}
else if (icode == CODE_FOR_vsx_set_v2df
- || icode == CODE_FOR_vsx_set_v2di)
+ || icode == CODE_FOR_vsx_set_v2di
+ || icode == CODE_FOR_bcdadd
+ || icode == CODE_FOR_bcdadd_lt
+ || icode == CODE_FOR_bcdadd_eq
+ || icode == CODE_FOR_bcdadd_gt
+ || icode == CODE_FOR_bcdsub
+ || icode == CODE_FOR_bcdsub_lt
+ || icode == CODE_FOR_bcdsub_eq
+ || icode == CODE_FOR_bcdsub_gt)
{
/* Only allow 1-bit unsigned literals. */
STRIP_NOPS (arg2);
@@ -12407,6 +12416,44 @@ rs6000_expand_ternop_builtin (enum insn_code icode, tree exp, rtx target)
return const0_rtx;
}
}
+ else if (icode == CODE_FOR_dfp_ddedpd_dd
+ || icode == CODE_FOR_dfp_ddedpd_td)
+ {
+ /* Only allow 2-bit unsigned literals where the value is 0 or 2. */
+ STRIP_NOPS (arg0);
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg2) & ~0x3)
+ {
+ error ("argument 1 must be 0 or 2");
+ return const0_rtx;
+ }
+ }
+ else if (icode == CODE_FOR_dfp_denbcd_dd
+ || icode == CODE_FOR_dfp_denbcd_td)
+ {
+ /* Only allow 1-bit unsigned literals. */
+ STRIP_NOPS (arg0);
+ if (TREE_CODE (arg0) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg0) & ~0x1)
+ {
+ error ("argument 1 must be a 1-bit unsigned literal");
+ return const0_rtx;
+ }
+ }
+ else if (icode == CODE_FOR_dfp_dscli_dd
+ || icode == CODE_FOR_dfp_dscli_td
+ || icode == CODE_FOR_dfp_dscri_dd
+ || icode == CODE_FOR_dfp_dscri_td)
+ {
+ /* Only allow 6-bit unsigned literals. */
+ STRIP_NOPS (arg1);
+ if (TREE_CODE (arg1) != INTEGER_CST
+ || TREE_INT_CST_LOW (arg1) & ~0x3f)
+ {
+ error ("argument 2 must be a 6-bit unsigned literal");
+ return const0_rtx;
+ }
+ }
else if (icode == CODE_FOR_crypto_vshasigmaw
|| icode == CODE_FOR_crypto_vshasigmad)
{
@@ -13496,6 +13543,14 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode)
error ("Builtin function %s requires the -mpaired option", name);
else if ((fnmask & RS6000_BTM_SPE) != 0)
error ("Builtin function %s requires the -mspe option", name);
+ else if ((fnmask & (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
+ == (RS6000_BTM_DFP | RS6000_BTM_P8_VECTOR))
+ error ("Builtin function %s requires the -mhard-dfp and"
+ "-mpower8-vector options", name);
+ else if ((fnmask & RS6000_BTM_DFP) != 0)
+ error ("Builtin function %s requires the -mhard-dfp option", name);
+ else if ((fnmask & RS6000_BTM_P8_VECTOR) != 0)
+ error ("Builtin function %s requires the -mpower8-vector option", name);
else
error ("Builtin function %s is not supported with the current options",
name);
@@ -13775,6 +13830,9 @@ rs6000_init_builtins (void)
uintTI_type_internal_node = unsigned_intTI_type_node;
float_type_internal_node = float_type_node;
double_type_internal_node = double_type_node;
+ long_double_type_internal_node = long_double_type_node;
+ dfloat64_type_internal_node = dfloat64_type_node;
+ dfloat128_type_internal_node = dfloat128_type_node;
void_type_internal_node = void_type_node;
/* Initialize the modes for builtin_function_type, mapping a machine mode to
@@ -13789,6 +13847,9 @@ rs6000_init_builtins (void)
builtin_mode_to_type[TImode][1] = unsigned_intTI_type_node;
builtin_mode_to_type[SFmode][0] = float_type_node;
builtin_mode_to_type[DFmode][0] = double_type_node;
+ builtin_mode_to_type[TFmode][0] = long_double_type_node;
+ builtin_mode_to_type[DDmode][0] = dfloat64_type_node;
+ builtin_mode_to_type[TDmode][0] = dfloat128_type_node;
builtin_mode_to_type[V1TImode][0] = V1TI_type_node;
builtin_mode_to_type[V1TImode][1] = unsigned_V1TI_type_node;
builtin_mode_to_type[V2SImode][0] = V2SI_type_node;
@@ -14881,6 +14942,8 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
/* unsigned 1 argument functions. */
case CRYPTO_BUILTIN_VSBOX:
case P8V_BUILTIN_VGBBD:
+ case MISC_BUILTIN_CDTBCD:
+ case MISC_BUILTIN_CBCDTD:
h.uns_p[0] = 1;
h.uns_p[1] = 1;
break;
@@ -14899,6 +14962,11 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
case CRYPTO_BUILTIN_VPMSUMW:
case CRYPTO_BUILTIN_VPMSUMD:
case CRYPTO_BUILTIN_VPMSUM:
+ case MISC_BUILTIN_ADDG6S:
+ case MISC_BUILTIN_DIVWEU:
+ case MISC_BUILTIN_DIVWEUO:
+ case MISC_BUILTIN_DIVDEU:
+ case MISC_BUILTIN_DIVDEUO:
h.uns_p[0] = 1;
h.uns_p[1] = 1;
h.uns_p[2] = 1;
@@ -14960,9 +15028,18 @@ builtin_function_type (enum machine_mode mode_ret, enum machine_mode mode_arg0,
/* signed args, unsigned return. */
case VSX_BUILTIN_XVCVDPUXDS_UNS:
case ALTIVEC_BUILTIN_FIXUNS_V4SF_V4SI:
+ case MISC_BUILTIN_UNPACK_TD:
+ case MISC_BUILTIN_UNPACK_V1TI:
h.uns_p[0] = 1;
break;
+ /* unsigned arguments for 128-bit pack instructions. */
+ case MISC_BUILTIN_PACK_TD:
+ case MISC_BUILTIN_PACK_V1TI:
+ h.uns_p[1] = 1;
+ h.uns_p[2] = 1;
+ break;
+
default:
break;
}
@@ -31226,6 +31303,7 @@ static struct rs6000_opt_mask const rs6000_builtin_mask_names[] =
{ "power8-vector", RS6000_BTM_P8_VECTOR, false, false },
{ "crypto", RS6000_BTM_CRYPTO, false, false },
{ "htm", RS6000_BTM_HTM, false, false },
+ { "hard-dfp", RS6000_BTM_DFP, false, false },
};
/* Option variables that we want to support inside attribute((target)) and
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 9d0d61c74ea..2e677d5936e 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -2516,6 +2516,7 @@ extern int frame_pointer_needed;
#define RS6000_BTM_FRSQRTES MASK_POPCNTB /* FRSQRTES instruction. */
#define RS6000_BTM_POPCNTD MASK_POPCNTD /* Target supports ISA 2.06. */
#define RS6000_BTM_CELL MASK_FPRND /* Target is cell powerpc. */
+#define RS6000_BTM_DFP MASK_DFP /* Decimal floating point. */
#define RS6000_BTM_COMMON (RS6000_BTM_ALTIVEC \
| RS6000_BTM_VSX \
@@ -2527,7 +2528,8 @@ extern int frame_pointer_needed;
| RS6000_BTM_FRSQRTES \
| RS6000_BTM_HTM \
| RS6000_BTM_POPCNTD \
- | RS6000_BTM_CELL)
+ | RS6000_BTM_CELL \
+ | RS6000_BTM_DFP)
/* Define builtin enum index. */
@@ -2622,6 +2624,9 @@ enum rs6000_builtin_type_index
RS6000_BTI_UINTTI, /* unsigned_intTI_type_node */
RS6000_BTI_float, /* float_type_node */
RS6000_BTI_double, /* double_type_node */
+ RS6000_BTI_long_double, /* long_double_type_node */
+ RS6000_BTI_dfloat64, /* dfloat64_type_node */
+ RS6000_BTI_dfloat128, /* dfloat128_type_node */
RS6000_BTI_void, /* void_type_node */
RS6000_BTI_MAX
};
@@ -2673,6 +2678,9 @@ enum rs6000_builtin_type_index
#define uintTI_type_internal_node (rs6000_builtin_types[RS6000_BTI_UINTTI])
#define float_type_internal_node (rs6000_builtin_types[RS6000_BTI_float])
#define double_type_internal_node (rs6000_builtin_types[RS6000_BTI_double])
+#define long_double_type_internal_node (rs6000_builtin_types[RS6000_BTI_long_double])
+#define dfloat64_type_internal_node (rs6000_builtin_types[RS6000_BTI_dfloat64])
+#define dfloat128_type_internal_node (rs6000_builtin_types[RS6000_BTI_dfloat128])
#define void_type_internal_node (rs6000_builtin_types[RS6000_BTI_void])
extern GTY(()) tree rs6000_builtin_types[RS6000_BTI_MAX];
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index cdefc8f78c4..937eabf3727 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -125,6 +125,15 @@
UNSPEC_P8V_MTVSRD
UNSPEC_P8V_XXPERMDI
UNSPEC_P8V_RELOAD_FROM_VSX
+ UNSPEC_ADDG6S
+ UNSPEC_CDTBCD
+ UNSPEC_CBCDTD
+ UNSPEC_DIVE
+ UNSPEC_DIVEO
+ UNSPEC_DIVEU
+ UNSPEC_DIVEUO
+ UNSPEC_UNPACK_128BIT
+ UNSPEC_PACK_128BIT
])
;;
@@ -481,6 +490,10 @@
(V2DF "X,X,X,X,X")
(V1TI "X,X,X,X,X")])
+;; Mode attribute to give the correct type for integer divides
+(define_mode_attr idiv_ldiv [(SI "idiv")
+ (DI "ldiv")])
+
;; Start with fixed-point load and store insns. Here we put only the more
;; complex forms. Basic data transfer is done later.
@@ -2755,10 +2768,7 @@
(match_operand:GPR 2 "gpc_reg_operand" "r")))]
""
"div<wd>u %0,%1,%2"
- [(set (attr "type")
- (cond [(match_operand:SI 0 "" "")
- (const_string "idiv")]
- (const_string "ldiv")))])
+ [(set_attr "type" "<idiv_ldiv>")])
;; For powers of two we can do srai/aze for divide and then adjust for
@@ -2782,10 +2792,7 @@
(match_operand:GPR 2 "gpc_reg_operand" "r")))]
""
"div<wd> %0,%1,%2"
- [(set (attr "type")
- (cond [(match_operand:SI 0 "" "")
- (const_string "idiv")]
- (const_string "ldiv")))])
+ [(set_attr "type" "<idiv_ldiv>")])
(define_expand "mod<mode>3"
[(use (match_operand:GPR 0 "gpc_reg_operand" ""))
@@ -15735,6 +15742,191 @@
})
+;; Miscellaneous ISA 2.06 (power7) instructions
+(define_insn "addg6s"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")
+ (match_operand:SI 2 "register_operand" "r")]
+ UNSPEC_ADDG6S))]
+ "TARGET_POPCNTD"
+ "addg6s %0,%1,%2"
+ [(set_attr "type" "integer")
+ (set_attr "length" "4")])
+
+(define_insn "cdtbcd"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
+ UNSPEC_CDTBCD))]
+ "TARGET_POPCNTD"
+ "cdtbcd %0,%1"
+ [(set_attr "type" "integer")
+ (set_attr "length" "4")])
+
+(define_insn "cbcdtd"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
+ UNSPEC_CBCDTD))]
+ "TARGET_POPCNTD"
+ "cbcdtd %0,%1"
+ [(set_attr "type" "integer")
+ (set_attr "length" "4")])
+
+(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
+ UNSPEC_DIVEO
+ UNSPEC_DIVEU
+ UNSPEC_DIVEUO])
+
+(define_int_attr div_extend [(UNSPEC_DIVE "e")
+ (UNSPEC_DIVEO "eo")
+ (UNSPEC_DIVEU "eu")
+ (UNSPEC_DIVEUO "euo")])
+
+(define_insn "div<div_extend>_<mode>"
+ [(set (match_operand:GPR 0 "register_operand" "=r")
+ (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
+ (match_operand:GPR 2 "register_operand" "r")]
+ UNSPEC_DIV_EXTEND))]
+ "TARGET_POPCNTD"
+ "div<wd><div_extend> %0,%1,%2"
+ [(set_attr "type" "<idiv_ldiv>")])
+
+
+;; Pack/unpack 128-bit floating point types that take 2 scalar registers
+
+; Type of the 64-bit part when packing/unpacking 128-bit floating point types
+(define_mode_attr FP128_64 [(TF "DF") (TD "DI")])
+
+(define_expand "unpack<mode>"
+ [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
+ (unspec:<FP128_64>
+ [(match_operand:FMOVE128 1 "register_operand" "")
+ (match_operand:QI 2 "const_0_to_1_operand" "")]
+ UNSPEC_UNPACK_128BIT))]
+ ""
+ "")
+
+;; The Advance Toolchain 7.0-3 added private builtins: __builtin_longdouble_dw0
+;; and __builtin_longdouble_dw1 to optimize glibc. Add support for these
+;; builtins here.
+
+(define_expand "unpacktf_0"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (unspec:DF [(match_operand:TF 1 "register_operand" "")
+ (const_int 0)]
+ UNSPEC_UNPACK_128BIT))]
+ ""
+ "")
+
+(define_expand "unpacktf_1"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (unspec:DF [(match_operand:TF 1 "register_operand" "")
+ (const_int 1)]
+ UNSPEC_UNPACK_128BIT))]
+ ""
+ "")
+
+(define_insn_and_split "unpack<mode>_dm"
+ [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
+ (unspec:<FP128_64>
+ [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
+ (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
+ UNSPEC_UNPACK_128BIT))]
+ "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 3))]
+{
+ unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
+
+ if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
+ {
+ emit_note (NOTE_INSN_DELETED);
+ DONE;
+ }
+
+ operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
+}
+ [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "unpack<mode>_nodm"
+ [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
+ (unspec:<FP128_64>
+ [(match_operand:FMOVE128 1 "register_operand" "d,d")
+ (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
+ UNSPEC_UNPACK_128BIT))]
+ "!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE"
+ "#"
+ "&& reload_completed"
+ [(set (match_dup 0) (match_dup 3))]
+{
+ unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
+
+ if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
+ {
+ emit_note (NOTE_INSN_DELETED);
+ DONE;
+ }
+
+ operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
+}
+ [(set_attr "type" "fp,fpstore")
+ (set_attr "length" "4")])
+
+(define_insn_and_split "pack<mode>"
+ [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
+ (unspec:FMOVE128
+ [(match_operand:<FP128_64> 1 "register_operand" "0,d")
+ (match_operand:<FP128_64> 2 "register_operand" "d,d")]
+ UNSPEC_PACK_128BIT))]
+ ""
+ "@
+ fmr %L0,%2
+ #"
+ "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
+ [(set (match_dup 3) (match_dup 1))
+ (set (match_dup 4) (match_dup 2))]
+{
+ unsigned dest_hi = REGNO (operands[0]);
+ unsigned dest_lo = dest_hi + 1;
+
+ gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
+ gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
+
+ operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
+ operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
+}
+ [(set_attr "type" "fp,fp")
+ (set_attr "length" "4,8")])
+
+(define_insn "unpackv1ti"
+ [(set (match_operand:DI 0 "register_operand" "=d,d")
+ (unspec:DI [(match_operand:V1TI 1 "register_operand" "0,wa")
+ (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
+ UNSPEC_UNPACK_128BIT))]
+ "TARGET_VSX"
+{
+ if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
+ return ASM_COMMENT_START " xxpermdi to same register";
+
+ operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
+ return "xxpermdi %x0,%x1,%x1,%3";
+}
+ [(set_attr "type" "vecperm")
+ (set_attr "length" "4")])
+
+(define_insn "packv1ti"
+ [(set (match_operand:V1TI 0 "register_operand" "=wa")
+ (unspec:V1TI
+ [(match_operand:DI 1 "register_operand" "d")
+ (match_operand:DI 2 "register_operand" "d")]
+ UNSPEC_PACK_128BIT))]
+ "TARGET_VSX"
+ "xxpermdi %x0,%x1,%x2,0"
+ [(set_attr "type" "vecperm")
+ (set_attr "length" "4")])
+
+
(include "sync.md")
(include "vector.md")
diff --git a/gcc/config/sol2.h b/gcc/config/sol2.h
index 2a657db59c1..a21c953b035 100644
--- a/gcc/config/sol2.h
+++ b/gcc/config/sol2.h
@@ -115,7 +115,6 @@ along with GCC; see the file COPYING3. If not see
#define LIB_SPEC \
"%{!symbolic:\
%{pthreads|pthread:-lpthread} \
- %{pthreads|pthread|fprofile-generate*:" LIB_TLS_SPEC "} \
%{p|pg:-ldl} -lc}"
#ifndef CROSS_DIRECTORY_STRUCTURE
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 8b6c647fc00..e2a4669e05d 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -5795,19 +5795,6 @@
}
[(set_attr "type" "shift")])
-(define_insn "*ashlsi3_extend"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (zero_extend:DI
- (ashift:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI"))))]
- "TARGET_ARCH64"
-{
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = GEN_INT (INTVAL (operands[2]) & 0x1f);
- return "sll\t%1, %2, %0";
-}
- [(set_attr "type" "shift")])
-
(define_expand "ashldi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "r")
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index c02aec59f06..64e40955a53 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -113,6 +113,10 @@ mrelax
Target
Optimize tail call instructions in assembler and linker
+muser-mode
+Target Report Mask(USER_MODE)
+Do not generate code that can only run in supervisor mode
+
mcpu=
Target RejectNegative Joined Var(sparc_cpu_and_features) Enum(sparc_processor_type) Init(PROCESSOR_V7)
Use features of and schedule code for given CPU
diff --git a/gcc/config/sparc/sync.md b/gcc/config/sparc/sync.md
index fd5691f73be..e6e237f256f 100644
--- a/gcc/config/sparc/sync.md
+++ b/gcc/config/sparc/sync.md
@@ -200,10 +200,27 @@
[(match_operand:I48MODE 2 "register_operand" "r")
(match_operand:I48MODE 3 "register_operand" "0")]
UNSPECV_CAS))]
- "(TARGET_V9 || TARGET_LEON3) && (<MODE>mode != DImode || TARGET_ARCH64)"
+ "TARGET_V9 && (<MODE>mode != DImode || TARGET_ARCH64)"
"cas<modesuffix>\t%1, %2, %0"
[(set_attr "type" "multi")])
+(define_insn "*atomic_compare_and_swap_leon3_1"
+ [(set (match_operand:SI 0 "register_operand" "=r")
+ (match_operand:SI 1 "mem_noofs_operand" "+w"))
+ (set (match_dup 1)
+ (unspec_volatile:SI
+ [(match_operand:SI 2 "register_operand" "r")
+ (match_operand:SI 3 "register_operand" "0")]
+ UNSPECV_CAS))]
+ "TARGET_LEON3"
+{
+ if (TARGET_USER_MODE)
+ return "casa\t%1 0xa, %2, %0"; /* ASI for user data space. */
+ else
+ return "casa\t%1 0xb, %2, %0"; /* ASI for supervisor data space. */
+}
+ [(set_attr "type" "multi")])
+
(define_insn "*atomic_compare_and_swapdi_v8plus"
[(set (match_operand:DI 0 "register_operand" "=h")
(match_operand:DI 1 "mem_noofs_operand" "+w"))
diff --git a/gcc/configure b/gcc/configure
index 813ccce2257..d912261c1cf 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -882,6 +882,7 @@ enable_werror_always
enable_checking
enable_coverage
enable_gather_detailed_mem_stats
+enable_valgrind_annotations
with_stabs
enable_multilib
enable_multiarch
@@ -1591,6 +1592,8 @@ Optional Features:
Values are opt, noopt, default is noopt
--enable-gather-detailed-mem-stats
enable detailed memory allocation stats gathering
+ --enable-valgrind-annotations
+ enable valgrind runtime interaction
--enable-multilib enable library support for multiple ABIs
--enable-multiarch enable support for multiarch paths
--enable-__cxa_atexit enable __cxa_atexit for C++
@@ -6772,12 +6775,11 @@ fi
-if test x$ac_valgrind_checking != x ; then
- # It is certainly possible that there's valgrind but no valgrind.h.
- # GCC relies on making annotations so we must have both.
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <valgrind/memcheck.h>" >&5
+# It is certainly possible that there's valgrind but no valgrind.h.
+# GCC relies on making annotations so we must have both.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <valgrind/memcheck.h>" >&5
$as_echo_n "checking for VALGRIND_DISCARD in <valgrind/memcheck.h>... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <valgrind/memcheck.h>
#ifndef VALGRIND_DISCARD
@@ -6790,11 +6792,11 @@ else
gcc_cv_header_valgrind_memcheck_h=no
fi
rm -f conftest.err conftest.$ac_ext
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_valgrind_memcheck_h" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_valgrind_memcheck_h" >&5
$as_echo "$gcc_cv_header_valgrind_memcheck_h" >&6; }
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <memcheck.h>" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for VALGRIND_DISCARD in <memcheck.h>" >&5
$as_echo_n "checking for VALGRIND_DISCARD in <memcheck.h>... " >&6; }
- cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <memcheck.h>
#ifndef VALGRIND_DISCARD
@@ -6807,8 +6809,20 @@ else
gcc_cv_header_memcheck_h=no
fi
rm -f conftest.err conftest.$ac_ext
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_memcheck_h" >&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_header_memcheck_h" >&5
$as_echo "$gcc_cv_header_memcheck_h" >&6; }
+if test $gcc_cv_header_valgrind_memcheck_h = yes; then
+
+$as_echo "#define HAVE_VALGRIND_MEMCHECK_H 1" >>confdefs.h
+
+fi
+if test $gcc_cv_header_memcheck_h = yes; then
+
+$as_echo "#define HAVE_MEMCHECK_H 1" >>confdefs.h
+
+fi
+
+if test x$ac_valgrind_checking != x ; then
# Prepare PATH_SEPARATOR.
# The user is always right.
@@ -6887,16 +6901,6 @@ fi
$as_echo "#define ENABLE_VALGRIND_CHECKING 1" >>confdefs.h
- if test $gcc_cv_header_valgrind_memcheck_h = yes; then
-
-$as_echo "#define HAVE_VALGRIND_MEMCHECK_H 1" >>confdefs.h
-
- fi
- if test $gcc_cv_header_memcheck_h = yes; then
-
-$as_echo "#define HAVE_MEMCHECK_H 1" >>confdefs.h
-
- fi
fi
@@ -6939,6 +6943,25 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
+# Check whether --enable-valgrind-annotations was given.
+if test "${enable_valgrind_annotations+set}" = set; then :
+ enableval=$enable_valgrind_annotations;
+else
+ enable_valgrind_annotations=no
+fi
+
+if test x$enable_valgrind_annotations != xno \
+ || test x$ac_valgrind_checking != x; then
+ if (test $have_valgrind_h = no \
+ && test $gcc_cv_header_memcheck_h = no \
+ && test $gcc_cv_header_valgrind_memcheck_h = no); then
+ as_fn_error "*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h" "$LINENO" 5
+ fi
+
+$as_echo "#define ENABLE_VALGRIND_ANNOTATIONS 1" >>confdefs.h
+
+fi
+
# -------------------------------
# Miscenalleous configure options
# -------------------------------
@@ -17971,7 +17994,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 17974 "configure"
+#line 17997 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -18077,7 +18100,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 18080 "configure"
+#line 18103 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -23306,13 +23329,8 @@ foo: .long 25
;;
i[34567]86-*-* | x86_64-*-*)
case "$target" in
- i[34567]86-*-solaris2.*)
- on_solaris=yes
- tga_func=___tls_get_addr
- ;;
- x86_64-*-solaris2.1[0-9]*)
+ i[34567]86-*-solaris2.* | x86_64-*-solaris2.1[0-9]*)
on_solaris=yes
- tga_func=__tls_get_addr
;;
*)
on_solaris=no
@@ -23587,7 +23605,6 @@ foo: .long 25
case "$target" in
sparc*-sun-solaris2.*)
on_solaris=yes
- tga_func=__tls_get_addr
;;
*)
on_solaris=no
@@ -23711,101 +23728,6 @@ if test $gcc_cv_as_tls = yes; then
set_have_as_tls=yes
fi
fi
-case "$target" in
- # TLS was introduced in the Solaris 9 FCS release. Support for GNU-style
- # TLS on x86 was only introduced in Solaris 9 4/04, replacing the earlier
- # Sun style that Sun ld and GCC don't support any longer.
- *-*-solaris2.*)
- ld_tls_support=yes
-
- save_LIBS="$LIBS"
- save_LDFLAGS="$LDFLAGS"
- LIBS=
- LDFLAGS=
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: checking library containing $tga_func" >&5
-$as_echo_n "checking library containing $tga_func... " >&6; }
- # Before Solaris 10, __tls_get_addr (SPARC/x64) resp. ___tls_get_addr
- # (32-bit x86) only lived in libthread, so check for that. Keep
- # set_have_as_tls if found, disable if not.
- as_ac_Search=`$as_echo "ac_cv_search_$tga_func" | $as_tr_sh`
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing $tga_func" >&5
-$as_echo_n "checking for library containing $tga_func... " >&6; }
-if { as_var=$as_ac_Search; eval "test \"\${$as_var+set}\" = set"; }; then :
- $as_echo_n "(cached) " >&6
-else
- ac_func_search_save_LIBS=$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 $tga_func ();
-int
-main ()
-{
-return $tga_func ();
- ;
- return 0;
-}
-_ACEOF
-for ac_lib in '' thread; do
- if test -z "$ac_lib"; then
- ac_res="none required"
- else
- ac_res=-l$ac_lib
- LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- fi
- if ac_fn_c_try_link "$LINENO"; then :
- eval "$as_ac_Search=\$ac_res"
-fi
-rm -f core conftest.err conftest.$ac_objext \
- conftest$ac_exeext
- if { as_var=$as_ac_Search; eval "test \"\${$as_var+set}\" = set"; }; then :
- break
-fi
-done
-if { as_var=$as_ac_Search; eval "test \"\${$as_var+set}\" = set"; }; then :
-
-else
- eval "$as_ac_Search=no"
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
-fi
-eval ac_res=\$$as_ac_Search
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
-$as_echo "$ac_res" >&6; }
-eval ac_res=\$$as_ac_Search
-if test "$ac_res" != no; then :
- test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-
-else
- set_have_as_tls=no
-fi
-
- ld_tls_libs="$LIBS"
- # Clear LIBS if we cannot support TLS.
- if test $set_have_as_tls = no; then
- LIBS=
- fi
- # Always define LIB_TLS_SPEC, even without TLS support.
-
-cat >>confdefs.h <<_ACEOF
-#define LIB_TLS_SPEC "$LIBS"
-_ACEOF
-
- { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIBS" >&5
-$as_echo "$LIBS" >&6; }
-
- LIBS="$save_LIBS"
- LDFLAGS="$save_LDFLAGS"
- ;;
-esac
if test $set_have_as_tls = yes ; then
$as_echo "#define HAVE_AS_TLS 1" >>confdefs.h
@@ -24496,7 +24418,7 @@ else
.align 4
smac %g2, %g3, %g1
umac %g2, %g3, %g1
- cas [%g2], %g3, %g1' > conftest.s
+ casa [%g2] 0xb, %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
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 1235501bd49..5565524c89a 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -514,27 +514,36 @@ dnl # an if statement. This was the source of very frustrating bugs
dnl # in converting to autoconf 2.5x!
AC_CHECK_HEADER(valgrind.h, have_valgrind_h=yes, have_valgrind_h=no)
-if test x$ac_valgrind_checking != x ; then
- # It is certainly possible that there's valgrind but no valgrind.h.
- # GCC relies on making annotations so we must have both.
- AC_MSG_CHECKING(for VALGRIND_DISCARD in <valgrind/memcheck.h>)
- AC_PREPROC_IFELSE([AC_LANG_SOURCE(
- [[#include <valgrind/memcheck.h>
+# It is certainly possible that there's valgrind but no valgrind.h.
+# GCC relies on making annotations so we must have both.
+AC_MSG_CHECKING(for VALGRIND_DISCARD in <valgrind/memcheck.h>)
+AC_PREPROC_IFELSE([AC_LANG_SOURCE(
+ [[#include <valgrind/memcheck.h>
#ifndef VALGRIND_DISCARD
#error VALGRIND_DISCARD not defined
#endif]])],
[gcc_cv_header_valgrind_memcheck_h=yes],
[gcc_cv_header_valgrind_memcheck_h=no])
- AC_MSG_RESULT($gcc_cv_header_valgrind_memcheck_h)
- AC_MSG_CHECKING(for VALGRIND_DISCARD in <memcheck.h>)
- AC_PREPROC_IFELSE([AC_LANG_SOURCE(
- [[#include <memcheck.h>
+AC_MSG_RESULT($gcc_cv_header_valgrind_memcheck_h)
+AC_MSG_CHECKING(for VALGRIND_DISCARD in <memcheck.h>)
+AC_PREPROC_IFELSE([AC_LANG_SOURCE(
+ [[#include <memcheck.h>
#ifndef VALGRIND_DISCARD
#error VALGRIND_DISCARD not defined
#endif]])],
[gcc_cv_header_memcheck_h=yes],
[gcc_cv_header_memcheck_h=no])
- AC_MSG_RESULT($gcc_cv_header_memcheck_h)
+AC_MSG_RESULT($gcc_cv_header_memcheck_h)
+if test $gcc_cv_header_valgrind_memcheck_h = yes; then
+ AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
+ [Define if valgrind's valgrind/memcheck.h header is installed.])
+fi
+if test $gcc_cv_header_memcheck_h = yes; then
+ AC_DEFINE(HAVE_MEMCHECK_H, 1,
+ [Define if valgrind's memcheck.h header is installed.])
+fi
+
+if test x$ac_valgrind_checking != x ; then
AM_PATH_PROG_WITH_TEST(valgrind_path, valgrind,
[$ac_dir/$ac_word --version | grep valgrind- >/dev/null 2>&1])
if test "x$valgrind_path" = "x" \
@@ -548,14 +557,6 @@ if test x$ac_valgrind_checking != x ; then
AC_DEFINE(ENABLE_VALGRIND_CHECKING, 1,
[Define if you want to run subprograms and generated programs
through valgrind (a memory checker). This is extremely expensive.])
- if test $gcc_cv_header_valgrind_memcheck_h = yes; then
- AC_DEFINE(HAVE_VALGRIND_MEMCHECK_H, 1,
- [Define if valgrind's valgrind/memcheck.h header is installed.])
- fi
- if test $gcc_cv_header_memcheck_h = yes; then
- AC_DEFINE(HAVE_MEMCHECK_H, 1,
- [Define if valgrind's memcheck.h header is installed.])
- fi
fi
AC_SUBST(valgrind_path_defines)
AC_SUBST(valgrind_command)
@@ -594,6 +595,21 @@ gather_stats=`if test $enable_gather_detailed_mem_stats != no; then echo 1; else
AC_DEFINE_UNQUOTED(GATHER_STATISTICS, $gather_stats,
[Define to enable detailed memory allocation stats gathering.])
+AC_ARG_ENABLE(valgrind-annotations,
+[AS_HELP_STRING([--enable-valgrind-annotations],
+ [enable valgrind runtime interaction])], [],
+[enable_valgrind_annotations=no])
+if test x$enable_valgrind_annotations != xno \
+ || test x$ac_valgrind_checking != x; then
+ if (test $have_valgrind_h = no \
+ && test $gcc_cv_header_memcheck_h = no \
+ && test $gcc_cv_header_valgrind_memcheck_h = no); then
+ AC_MSG_ERROR([*** Can't find valgrind/memcheck.h, memcheck.h or valgrind.h])
+ fi
+ AC_DEFINE(ENABLE_VALGRIND_ANNOTATIONS, 1,
+[Define to get calls to the valgrind runtime enabled.])
+fi
+
# -------------------------------
# Miscenalleous configure options
# -------------------------------
@@ -2935,13 +2951,8 @@ foo: .long 25
;;
i[34567]86-*-* | x86_64-*-*)
case "$target" in
- i[34567]86-*-solaris2.*)
- on_solaris=yes
- tga_func=___tls_get_addr
- ;;
- x86_64-*-solaris2.1[0-9]*)
+ i[34567]86-*-solaris2.* | x86_64-*-solaris2.1[0-9]*)
on_solaris=yes
- tga_func=__tls_get_addr
;;
*)
on_solaris=no
@@ -3217,7 +3228,6 @@ foo: .long 25
case "$target" in
sparc*-sun-solaris2.*)
on_solaris=yes
- tga_func=__tls_get_addr
;;
*)
on_solaris=no
@@ -3313,37 +3323,6 @@ else
[$tls_first_major,$tls_first_minor,0], [$tls_as_opt], [$conftest_s],,
[set_have_as_tls=yes])
fi
-case "$target" in
- # TLS was introduced in the Solaris 9 FCS release. Support for GNU-style
- # TLS on x86 was only introduced in Solaris 9 4/04, replacing the earlier
- # Sun style that Sun ld and GCC don't support any longer.
- *-*-solaris2.*)
- ld_tls_support=yes
-
- save_LIBS="$LIBS"
- save_LDFLAGS="$LDFLAGS"
- LIBS=
- LDFLAGS=
-
- AC_MSG_CHECKING(library containing $tga_func)
- # Before Solaris 10, __tls_get_addr (SPARC/x64) resp. ___tls_get_addr
- # (32-bit x86) only lived in libthread, so check for that. Keep
- # set_have_as_tls if found, disable if not.
- AC_SEARCH_LIBS([$tga_func], [thread],, [set_have_as_tls=no])
- ld_tls_libs="$LIBS"
- # Clear LIBS if we cannot support TLS.
- if test $set_have_as_tls = no; then
- LIBS=
- fi
- # Always define LIB_TLS_SPEC, even without TLS support.
- AC_DEFINE_UNQUOTED(LIB_TLS_SPEC, "$LIBS",
- [Define to the library containing __tls_get_addr/___tls_get_addr.])
- AC_MSG_RESULT($LIBS)
-
- LIBS="$save_LIBS"
- LDFLAGS="$save_LDFLAGS"
- ;;
-esac
if test $set_have_as_tls = yes ; then
AC_DEFINE(HAVE_AS_TLS, 1,
[Define if your assembler and linker support thread-local storage.])
@@ -3684,7 +3663,7 @@ foo:
.align 4
smac %g2, %g3, %g1
umac %g2, %g3, %g1
- cas [[%g2]], %g3, %g1],,
+ casa [[%g2]] 0xb, %g3, %g1],,
[AC_DEFINE(HAVE_AS_LEON, 1,
[Define if your assembler supports LEON instructions.])])
;;
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ae213426553..a5f3829d705 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,15 @@
+2014-04-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59120
+ * parser.c (cp_parser_alias_declaration): Check return value of
+ cp_parser_require.
+
+2014-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ * parser.c (cp_parser_omp_atomic): Allow seq_cst before
+ atomic-clause, allow comma in between atomic-clause and
+ seq_cst.
+
2014-04-24 Marc Glisse <marc.glisse@inria.fr>
PR libstdc++/43622
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 4e6a2b88f32..962cacedf80 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -16142,15 +16142,8 @@ cp_parser_alias_declaration (cp_parser* parser)
if (parser->num_template_parameter_lists)
parser->type_definition_forbidden_message = saved_message;
- if (type == error_mark_node)
- {
- cp_parser_skip_to_end_of_block_or_statement (parser);
- return error_mark_node;
- }
-
- cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON);
-
- if (cp_parser_error_occurred (parser))
+ if (type == error_mark_node
+ || !cp_parser_require (parser, CPP_SEMICOLON, RT_SEMICOLON))
{
cp_parser_skip_to_end_of_block_or_statement (parser);
return error_mark_node;
@@ -28534,6 +28527,20 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
tree id = cp_lexer_peek_token (parser->lexer)->u.value;
const char *p = IDENTIFIER_POINTER (id);
+ if (!strcmp (p, "seq_cst"))
+ {
+ seq_cst = true;
+ cp_lexer_consume_token (parser->lexer);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME)
+ cp_lexer_consume_token (parser->lexer);
+ }
+ }
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ {
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
if (!strcmp (p, "read"))
code = OMP_ATOMIC_READ;
else if (!strcmp (p, "write"))
@@ -28547,16 +28554,22 @@ cp_parser_omp_atomic (cp_parser *parser, cp_token *pragma_tok)
if (p)
cp_lexer_consume_token (parser->lexer);
}
-
- if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
+ if (!seq_cst)
{
- tree id = cp_lexer_peek_token (parser->lexer)->u.value;
- const char *p = IDENTIFIER_POINTER (id);
+ if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA)
+ && cp_lexer_peek_nth_token (parser->lexer, 2)->type == CPP_NAME)
+ cp_lexer_consume_token (parser->lexer);
- if (!strcmp (p, "seq_cst"))
+ if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
{
- seq_cst = true;
- cp_lexer_consume_token (parser->lexer);
+ tree id = cp_lexer_peek_token (parser->lexer)->u.value;
+ const char *p = IDENTIFIER_POINTER (id);
+
+ if (!strcmp (p, "seq_cst"))
+ {
+ seq_cst = true;
+ cp_lexer_consume_token (parser->lexer);
+ }
}
}
cp_parser_require_pragma_eol (parser, pragma_tok);
diff --git a/gcc/cselib.c b/gcc/cselib.c
index c55b02772ed..00a04baab6e 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -49,9 +49,6 @@ struct elt_list {
cselib_val *elt;
};
-/* See the documentation of cselib_find_slot below. */
-static enum machine_mode find_slot_memmode;
-
static bool cselib_record_memory;
static bool cselib_preserve_constants;
static bool cselib_any_perm_equivs;
@@ -94,7 +91,14 @@ static rtx cselib_expand_value_rtx_1 (rtx, struct expand_value_data *, int);
struct cselib_hasher : typed_noop_remove <cselib_val>
{
typedef cselib_val value_type;
- typedef rtx_def compare_type;
+ struct compare_type {
+ /* The rtx value and its mode (needed separately for constant
+ integers). */
+ enum machine_mode mode;
+ rtx x;
+ /* The mode of the contaning MEM, if any, otherwise VOIDmode. */
+ enum machine_mode memmode;
+ };
static inline hashval_t hash (const value_type *);
static inline bool equal (const value_type *, const compare_type *);
};
@@ -118,27 +122,20 @@ inline bool
cselib_hasher::equal (const value_type *v, const compare_type *x_arg)
{
struct elt_loc_list *l;
- rtx x = CONST_CAST_RTX (x_arg);
- enum machine_mode mode = GET_MODE (x);
-
- gcc_assert (!CONST_SCALAR_INT_P (x) && GET_CODE (x) != CONST_FIXED);
+ rtx x = x_arg->x;
+ enum machine_mode mode = x_arg->mode;
+ enum machine_mode memmode = x_arg->memmode;
if (mode != GET_MODE (v->val_rtx))
return false;
- /* Unwrap X if necessary. */
- if (GET_CODE (x) == CONST
- && (CONST_SCALAR_INT_P (XEXP (x, 0))
- || GET_CODE (XEXP (x, 0)) == CONST_FIXED))
- x = XEXP (x, 0);
-
if (GET_CODE (x) == VALUE)
return x == v->val_rtx;
/* We don't guarantee that distinct rtx's have different hash values,
so we need to do a comparison. */
for (l = v->locs; l; l = l->next)
- if (rtx_equal_for_cselib_1 (l->loc, x, find_slot_memmode))
+ if (rtx_equal_for_cselib_1 (l->loc, x, memmode))
{
promote_debug_loc (l);
return true;
@@ -498,8 +495,11 @@ preserve_constants_and_equivs (cselib_val **x, void *info ATTRIBUTE_UNUSED)
if (invariant_or_equiv_p (v))
{
+ cselib_hasher::compare_type lookup = {
+ GET_MODE (v->val_rtx), v->val_rtx, VOIDmode
+ };
cselib_val **slot
- = cselib_preserved_hash_table.find_slot_with_hash (v->val_rtx,
+ = cselib_preserved_hash_table.find_slot_with_hash (&lookup,
v->hash, INSERT);
gcc_assert (!*slot);
*slot = v;
@@ -572,22 +572,19 @@ cselib_get_next_uid (void)
/* Search for X, whose hashcode is HASH, in CSELIB_HASH_TABLE,
INSERTing if requested. When X is part of the address of a MEM,
- MEMMODE should specify the mode of the MEM. While searching the
- table, MEMMODE is held in FIND_SLOT_MEMMODE, so that autoinc RTXs
- in X can be resolved. */
+ MEMMODE should specify the mode of the MEM. */
static cselib_val **
-cselib_find_slot (rtx x, hashval_t hash, enum insert_option insert,
- enum machine_mode memmode)
+cselib_find_slot (enum machine_mode mode, rtx x, hashval_t hash,
+ enum insert_option insert, enum machine_mode memmode)
{
cselib_val **slot = NULL;
- find_slot_memmode = memmode;
+ cselib_hasher::compare_type lookup = { mode, x, memmode };
if (cselib_preserve_constants)
- slot = cselib_preserved_hash_table.find_slot_with_hash (x, hash,
+ slot = cselib_preserved_hash_table.find_slot_with_hash (&lookup, hash,
NO_INSERT);
if (!slot)
- slot = cselib_hash_table.find_slot_with_hash (x, hash, insert);
- find_slot_memmode = VOIDmode;
+ slot = cselib_hash_table.find_slot_with_hash (&lookup, hash, insert);
return slot;
}
@@ -1041,18 +1038,6 @@ rtx_equal_for_cselib_1 (rtx x, rtx y, enum machine_mode memmode)
return 1;
}
-/* We need to pass down the mode of constants through the hash table
- functions. For that purpose, wrap them in a CONST of the appropriate
- mode. */
-static rtx
-wrap_constant (enum machine_mode mode, rtx x)
-{
- if (!CONST_SCALAR_INT_P (x) && GET_CODE (x) != CONST_FIXED)
- return x;
- gcc_assert (mode != VOIDmode);
- return gen_rtx_CONST (mode, x);
-}
-
/* Hash an rtx. Return 0 if we couldn't hash the rtx.
For registers and memory locations, we look up their cselib_val structure
and return its VALUE element.
@@ -1411,8 +1396,7 @@ cselib_lookup_mem (rtx x, int create)
mem_elt = new_cselib_val (next_uid, mode, x);
add_mem_for_addr (addr, mem_elt, x);
- slot = cselib_find_slot (wrap_constant (mode, x), mem_elt->hash,
- INSERT, mode);
+ slot = cselib_find_slot (mode, x, mem_elt->hash, INSERT, VOIDmode);
*slot = mem_elt;
return mem_elt;
}
@@ -2068,7 +2052,7 @@ cselib_lookup_1 (rtx x, enum machine_mode mode,
}
}
REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e);
- slot = cselib_find_slot (x, e->hash, INSERT, memmode);
+ slot = cselib_find_slot (mode, x, e->hash, INSERT, memmode);
*slot = e;
return e;
}
@@ -2081,7 +2065,7 @@ cselib_lookup_1 (rtx x, enum machine_mode mode,
if (! hashval)
return 0;
- slot = cselib_find_slot (wrap_constant (mode, x), hashval,
+ slot = cselib_find_slot (mode, x, hashval,
create ? INSERT : NO_INSERT, memmode);
if (slot == 0)
return 0;
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index 347a94a3aee..9780d923804 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -12787,9 +12787,12 @@ float __builtin_recipdivf (float, float);
float __builtin_rsqrtf (float);
double __builtin_recipdiv (double, double);
double __builtin_rsqrt (double);
-long __builtin_bpermd (long, long);
uint64_t __builtin_ppc_get_timebase ();
unsigned long __builtin_ppc_mftb ();
+double __builtin_unpack_longdouble (long double, int);
+double __builtin_longdouble_dw0 (long double);
+double __builtin_longdouble_dw1 (long double);
+long double __builtin_pack_longdouble (double, double);
@end smallexample
The @code{vec_rsqrt}, @code{__builtin_rsqrt}, and
@@ -12809,6 +12812,57 @@ The @code{__builtin_ppc_mftb} function always generates one instruction and
returns the Time Base Register value as an unsigned long, throwing away
the most significant word on 32-bit environments.
+The following built-in functions are available for the PowerPC family
+of processors, starting with ISA 2.06 or later (@option{-mcpu=power7}
+or @option{-mpopcntd}):
+@smallexample
+long __builtin_bpermd (long, long);
+int __builtin_divwe (int, int);
+int __builtin_divweo (int, int);
+unsigned int __builtin_divweu (unsigned int, unsigned int);
+unsigned int __builtin_divweuo (unsigned int, unsigned int);
+long __builtin_divde (long, long);
+long __builtin_divdeo (long, long);
+unsigned long __builtin_divdeu (unsigned long, unsigned long);
+unsigned long __builtin_divdeuo (unsigned long, unsigned long);
+unsigned int cdtbcd (unsigned int);
+unsigned int cbcdtd (unsigned int);
+unsigned int addg6s (unsigned int, unsigned int);
+@end smallexample
+
+The @code{__builtin_divde}, @code{__builtin_divdeo},
+@code{__builitin_divdeu}, @code{__builtin_divdeou} functions require a
+64-bit environment support ISA 2.06 or later.
+
+The following built-in functions are available for the PowerPC family
+of processors when hardware decimal floating point
+(@option{-mhard-dfp}) is available:
+@smallexample
+_Decimal64 __builtin_dxex (_Decimal64);
+_Decimal128 __builtin_dxexq (_Decimal128);
+_Decimal64 __builtin_ddedpd (int, _Decimal64);
+_Decimal128 __builtin_ddedpdq (int, _Decimal128);
+_Decimal64 __builtin_denbcd (int, _Decimal64);
+_Decimal128 __builtin_denbcdq (int, _Decimal128);
+_Decimal64 __builtin_diex (_Decimal64, _Decimal64);
+_Decimal128 _builtin_diexq (_Decimal128, _Decimal128);
+_Decimal64 __builtin_dscli (_Decimal64, int);
+_Decimal128 __builitn_dscliq (_Decimal128, int);
+_Decimal64 __builtin_dscri (_Decimal64, int);
+_Decimal128 __builitn_dscriq (_Decimal128, int);
+unsigned long long __builtin_unpack_dec128 (_Decimal128, int);
+_Decimal128 __builtin_pack_dec128 (unsigned long long, unsigned long long);
+@end smallexample
+
+The following built-in functions are available for the PowerPC family
+of processors when the Vector Scalar (vsx) instruction set is
+available:
+@smallexample
+unsigned long long __builtin_unpack_vector_int128 (vector __int128_t, int);
+vector __int128_t __builtin_pack_vector_int128 (unsigned long long,
+ unsigned long long);
+@end smallexample
+
@node PowerPC AltiVec/VSX Built-in Functions
@subsection PowerPC AltiVec Built-in Functions
@@ -15220,6 +15274,17 @@ vector __uint128_t vec_vsubcuq (vector __uint128_t, vector __uint128_t);
__int128_t vec_vsubuqm (__int128_t, __int128_t);
__uint128_t vec_vsubuqm (__uint128_t, __uint128_t);
+
+vector __int128_t __builtin_bcdadd (vector __int128_t, vector__int128_t);
+int __builtin_bcdadd_lt (vector __int128_t, vector__int128_t);
+int __builtin_bcdadd_eq (vector __int128_t, vector__int128_t);
+int __builtin_bcdadd_gt (vector __int128_t, vector__int128_t);
+int __builtin_bcdadd_ov (vector __int128_t, vector__int128_t);
+vector __int128_t bcdsub (vector __int128_t, vector__int128_t);
+int __builtin_bcdsub_lt (vector __int128_t, vector__int128_t);
+int __builtin_bcdsub_eq (vector __int128_t, vector__int128_t);
+int __builtin_bcdsub_gt (vector __int128_t, vector__int128_t);
+int __builtin_bcdsub_ov (vector __int128_t, vector__int128_t);
@end smallexample
If the cryptographic instructions are enabled (@option{-mcrypto} or
diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 0b2b3657577..7851b0061b3 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -2544,8 +2544,7 @@ Finally a @code{stagefeedback} compiler is built using the information collected
Unlike standard bootstrap, several additional restrictions apply. The
compiler used to build @code{stage1} needs to support a 64-bit integral type.
-It is recommended to only use GCC for this. Also parallel make is currently
-not supported since collisions in profile collecting may occur.
+It is recommended to only use GCC for this.
@html
<hr />
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index ff43f262323..da7a00ed00c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -993,6 +993,7 @@ See RS/6000 and PowerPC Options.
-mhard-quad-float -msoft-quad-float @gol
-mstack-bias -mno-stack-bias @gol
-munaligned-doubles -mno-unaligned-doubles @gol
+-muser-mode -mno-user-mode @gol
-mv8plus -mno-v8plus -mvis -mno-vis @gol
-mvis2 -mno-vis2 -mvis3 -mno-vis3 @gol
-mcbcond -mno-cbcond @gol
@@ -20961,6 +20962,14 @@ Specifying this option avoids some rare compatibility problems with code
generated by other compilers. It is not the default because it results
in a performance loss, especially for floating-point code.
+@item -muser-mode
+@itemx -mno-user-mode
+@opindex muser-mode
+@opindex mno-user-mode
+Do not generate code that can only run in supervisor mode. This is relevant
+only for the @code{casa} instruction emitted for the LEON3 processor. The
+default is @option{-mno-user-mode}.
+
@item -mno-faster-structs
@itemx -mfaster-structs
@opindex mno-faster-structs
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 2b2ab5dd831..da0b3f589c9 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -6917,14 +6917,13 @@ should_move_die_to_comdat (dw_die_ref die)
case DW_TAG_structure_type:
case DW_TAG_enumeration_type:
case DW_TAG_union_type:
- /* Don't move declarations, inlined instances, or types nested in a
- subprogram. */
+ /* Don't move declarations, inlined instances, types nested in a
+ subprogram, or types that contain subprogram definitions. */
if (is_declaration_die (die)
|| get_AT (die, DW_AT_abstract_origin)
- || is_nested_in_subprogram (die))
+ || is_nested_in_subprogram (die)
+ || contains_subprogram_definition (die))
return 0;
- /* A type definition should never contain a subprogram definition. */
- gcc_assert (!contains_subprogram_definition (die));
return 1;
case DW_TAG_array_type:
case DW_TAG_interface_type:
@@ -7013,6 +7012,7 @@ clone_as_declaration (dw_die_ref die)
switch (a->dw_attr)
{
+ case DW_AT_abstract_origin:
case DW_AT_artificial:
case DW_AT_containing_type:
case DW_AT_external:
@@ -7245,6 +7245,12 @@ generate_skeleton_bottom_up (skeleton_chain_node *parent)
dw_die_ref clone = clone_die (c);
move_all_children (c, clone);
+ /* If the original has a DW_AT_object_pointer attribute,
+ it would now point to a child DIE just moved to the
+ cloned tree, so we need to remove that attribute from
+ the original. */
+ remove_AT (c, DW_AT_object_pointer);
+
replace_child (c, clone, prev);
generate_skeleton_ancestor_tree (parent);
add_child_die (parent->new_die, c);
@@ -7386,28 +7392,38 @@ break_out_comdat_types (dw_die_ref die)
} while (next != NULL);
}
-/* Like clone_tree, but additionally enter all the children into
- the hash table decl_table. */
+/* Like clone_tree, but copy DW_TAG_subprogram DIEs as declarations.
+ Enter all the cloned children into the hash table decl_table. */
static dw_die_ref
-clone_tree_hash (dw_die_ref die, decl_hash_type decl_table)
+clone_tree_partial (dw_die_ref die, decl_hash_type decl_table)
{
dw_die_ref c;
- dw_die_ref clone = clone_die (die);
+ dw_die_ref clone;
struct decl_table_entry *entry;
- decl_table_entry **slot = decl_table.find_slot_with_hash (die,
- htab_hash_pointer (die), INSERT);
+ decl_table_entry **slot;
+
+ if (die->die_tag == DW_TAG_subprogram)
+ clone = clone_as_declaration (die);
+ else
+ clone = clone_die (die);
+
+ slot = decl_table.find_slot_with_hash (die,
+ htab_hash_pointer (die), INSERT);
+
/* Assert that DIE isn't in the hash table yet. If it would be there
before, the ancestors would be necessarily there as well, therefore
- clone_tree_hash wouldn't be called. */
+ clone_tree_partial wouldn't be called. */
gcc_assert (*slot == HTAB_EMPTY_ENTRY);
+
entry = XCNEW (struct decl_table_entry);
entry->orig = die;
entry->copy = clone;
*slot = entry;
- FOR_EACH_CHILD (die, c,
- add_child_die (clone, clone_tree_hash (c, decl_table)));
+ if (die->die_tag != DW_TAG_subprogram)
+ FOR_EACH_CHILD (die, c,
+ add_child_die (clone, clone_tree_partial (c, decl_table)));
return clone;
}
@@ -7458,9 +7474,15 @@ copy_decls_walk (dw_die_ref unit, dw_die_ref die, decl_hash_type decl_table)
entry->copy = copy;
*slot = entry;
- FOR_EACH_CHILD (targ, c,
- add_child_die (copy,
- clone_tree_hash (c, decl_table)));
+ /* If TARG is not a declaration DIE, we need to copy its
+ children. */
+ if (!is_declaration_die (targ))
+ {
+ FOR_EACH_CHILD (
+ targ, c,
+ add_child_die (copy,
+ clone_tree_partial (c, decl_table)));
+ }
/* Make sure the cloned tree is marked as part of the
type unit. */
diff --git a/gcc/expr.c b/gcc/expr.c
index fe95ebcbfa0..989a8780dc9 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -2365,6 +2365,18 @@ use_reg_mode (rtx *call_fusage, rtx reg, enum machine_mode mode)
= gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
}
+/* Add a CLOBBER expression for REG to the (possibly empty) list pointed
+ to by CALL_FUSAGE. REG must denote a hard register. */
+
+void
+clobber_reg_mode (rtx *call_fusage, rtx reg, enum machine_mode mode)
+{
+ gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
+
+ *call_fusage
+ = gen_rtx_EXPR_LIST (mode, gen_rtx_CLOBBER (VOIDmode, reg), *call_fusage);
+}
+
/* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
starting at REGNO. All of these registers must be hard registers. */
diff --git a/gcc/expr.h b/gcc/expr.h
index 524da6731a9..1823febac26 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -346,6 +346,7 @@ extern void copy_blkmode_from_reg (rtx, rtx, tree);
/* Mark REG as holding a parameter for the next CALL_INSN.
Mode is TYPE_MODE of the non-promoted parameter, or VOIDmode. */
extern void use_reg_mode (rtx *, rtx, enum machine_mode);
+extern void clobber_reg_mode (rtx *, rtx, enum machine_mode);
extern rtx copy_blkmode_to_reg (enum machine_mode, tree);
@@ -356,6 +357,13 @@ use_reg (rtx *fusage, rtx reg)
use_reg_mode (fusage, reg, VOIDmode);
}
+/* Mark REG as clobbered by the call with FUSAGE as CALL_INSN_FUNCTION_USAGE. */
+static inline void
+clobber_reg (rtx *fusage, rtx reg)
+{
+ clobber_reg_mode (fusage, reg, VOIDmode);
+}
+
/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters
for the next CALL_INSN. */
extern void use_regs (rtx *, int, int);
diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog
index 427c9b15ad8..5cf25134e30 100644
--- a/gcc/fortran/ChangeLog
+++ b/gcc/fortran/ChangeLog
@@ -1,3 +1,23 @@
+2014-03-27 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/59604
+ PR fortran/58003
+ * gfortran.h (gfc_convert_mpz_to_signed): Add prototype.
+ * arith.c (gfc_int2int): Convert number to signed if
+ arithmetic overflow is not checked.
+ * simplify.c (convert_mpz_to_unsigned): Only trigger assert for
+ size if range checking is in force.
+ (convert_mpz_to_signed): Make non-static, rename to
+ (gfc_convert_mpz_to_signed).
+ (simplify_dshift): Use gfc_convert_mpz_to_signed.
+ (gfc_simplify_ibclr): Likewise.
+ (gfc_simplify_ibits): Likewise.
+ (gfc_simplify_ibset): Likewise.
+ (simplify_shift): Likewise.
+ (gfc_simplify_ishiftc): Likewise.
+ (gfc_simplify_maskr): Likewise.
+ (gfc_simplify_maskl): Likewise.
+
2014-04-22 Tobias Burnus <burnus@net-b.de>
PR fortran/60881
diff --git a/gcc/fortran/arith.c b/gcc/fortran/arith.c
index 053cf765e59..a05fa4907a4 100644
--- a/gcc/fortran/arith.c
+++ b/gcc/fortran/arith.c
@@ -1976,6 +1976,17 @@ gfc_int2int (gfc_expr *src, int kind)
}
}
+ /* If we do not trap numeric overflow, we need to convert the number to
+ signed, throwing away high-order bits if necessary. */
+ if (gfc_option.flag_range_check == 0)
+ {
+ int k;
+
+ k = gfc_validate_kind (BT_INTEGER, kind, false);
+ gfc_convert_mpz_to_signed (result->value.integer,
+ gfc_integer_kinds[k].bit_size);
+ }
+
return result;
}
diff --git a/gcc/fortran/gfortran.h b/gcc/fortran/gfortran.h
index 14c202dd413..f0eed809ab8 100644
--- a/gcc/fortran/gfortran.h
+++ b/gcc/fortran/gfortran.h
@@ -3022,4 +3022,8 @@ typedef int (*walk_expr_fn_t) (gfc_expr **, int *, void *);
int gfc_expr_walker (gfc_expr **, walk_expr_fn_t, void *);
int gfc_code_walker (gfc_code **, walk_code_fn_t, walk_expr_fn_t, void *);
+/* simplify.c */
+
+void gfc_convert_mpz_to_signed (mpz_t, int);
+
#endif /* GCC_GFORTRAN_H */
diff --git a/gcc/fortran/simplify.c b/gcc/fortran/simplify.c
index 96d0f21f36c..1b6cd5bc4c1 100644
--- a/gcc/fortran/simplify.c
+++ b/gcc/fortran/simplify.c
@@ -151,8 +151,10 @@ convert_mpz_to_unsigned (mpz_t x, int bitsize)
if (mpz_sgn (x) < 0)
{
- /* Confirm that no bits above the signed range are unset. */
- gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX);
+ /* Confirm that no bits above the signed range are unset if we
+ are doing range checking. */
+ if (gfc_option.flag_range_check != 0)
+ gcc_assert (mpz_scan0 (x, bitsize-1) == ULONG_MAX);
mpz_init_set_ui (mask, 1);
mpz_mul_2exp (mask, mask, bitsize);
@@ -175,13 +177,15 @@ convert_mpz_to_unsigned (mpz_t x, int bitsize)
If the bitsize-1 bit is set, this is taken as a sign bit and
the number is converted to the corresponding negative number. */
-static void
-convert_mpz_to_signed (mpz_t x, int bitsize)
+void
+gfc_convert_mpz_to_signed (mpz_t x, int bitsize)
{
mpz_t mask;
- /* Confirm that no bits above the unsigned range are set. */
- gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX);
+ /* Confirm that no bits above the unsigned range are set if we are
+ doing range checking. */
+ if (gfc_option.flag_range_check != 0)
+ gcc_assert (mpz_scan1 (x, bitsize) == ULONG_MAX);
if (mpz_tstbit (x, bitsize - 1) == 1)
{
@@ -1943,7 +1947,7 @@ simplify_dshift (gfc_expr *arg1, gfc_expr *arg2, gfc_expr *shiftarg,
mpz_setbit (result->value.integer, shift + i);
/* Convert to a signed value. */
- convert_mpz_to_signed (result->value.integer, size);
+ gfc_convert_mpz_to_signed (result->value.integer, size);
return result;
}
@@ -2561,7 +2565,7 @@ gfc_simplify_ibclr (gfc_expr *x, gfc_expr *y)
mpz_clrbit (result->value.integer, pos);
- convert_mpz_to_signed (result->value.integer,
+ gfc_convert_mpz_to_signed (result->value.integer,
gfc_integer_kinds[k].bit_size);
return result;
@@ -2619,7 +2623,7 @@ gfc_simplify_ibits (gfc_expr *x, gfc_expr *y, gfc_expr *z)
free (bits);
- convert_mpz_to_signed (result->value.integer,
+ gfc_convert_mpz_to_signed (result->value.integer,
gfc_integer_kinds[k].bit_size);
return result;
@@ -2646,7 +2650,7 @@ gfc_simplify_ibset (gfc_expr *x, gfc_expr *y)
mpz_setbit (result->value.integer, pos);
- convert_mpz_to_signed (result->value.integer,
+ gfc_convert_mpz_to_signed (result->value.integer,
gfc_integer_kinds[k].bit_size);
return result;
@@ -3093,7 +3097,7 @@ simplify_shift (gfc_expr *e, gfc_expr *s, const char *name,
}
}
- convert_mpz_to_signed (result->value.integer, bitsize);
+ gfc_convert_mpz_to_signed (result->value.integer, bitsize);
free (bits);
return result;
@@ -3234,7 +3238,7 @@ gfc_simplify_ishftc (gfc_expr *e, gfc_expr *s, gfc_expr *sz)
}
}
- convert_mpz_to_signed (result->value.integer, isize);
+ gfc_convert_mpz_to_signed (result->value.integer, isize);
free (bits);
return result;
@@ -3954,7 +3958,7 @@ gfc_simplify_maskr (gfc_expr *i, gfc_expr *kind_arg)
mpz_mul_2exp (result->value.integer, result->value.integer, arg);
mpz_sub_ui (result->value.integer, result->value.integer, 1);
- convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
+ gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
return result;
}
@@ -3990,7 +3994,7 @@ gfc_simplify_maskl (gfc_expr *i, gfc_expr *kind_arg)
mpz_sub (result->value.integer, z, result->value.integer);
mpz_clear (z);
- convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
+ gfc_convert_mpz_to_signed (result->value.integer, gfc_integer_kinds[k].bit_size);
return result;
}
diff --git a/gcc/gimple-ssa-strength-reduction.c b/gcc/gimple-ssa-strength-reduction.c
index cf252d4269d..af9f26d2e9c 100644
--- a/gcc/gimple-ssa-strength-reduction.c
+++ b/gcc/gimple-ssa-strength-reduction.c
@@ -1111,14 +1111,17 @@ create_mul_imm_cand (gimple gs, tree base_in, tree stride_in, bool speed)
X = Y * c
============================
X = (B + i') * (S * c) */
- base = base_cand->base_expr;
- index = base_cand->index;
temp = wi::to_widest (base_cand->stride) * wi::to_widest (stride_in);
- stride = wide_int_to_tree (TREE_TYPE (stride_in), temp);
- ctype = base_cand->cand_type;
- if (has_single_use (base_in))
- savings = (base_cand->dead_savings
- + stmt_cost (base_cand->cand_stmt, speed));
+ if (wi::fits_to_tree_p (temp, TREE_TYPE (stride_in)))
+ {
+ base = base_cand->base_expr;
+ index = base_cand->index;
+ stride = wide_int_to_tree (TREE_TYPE (stride_in), temp);
+ ctype = base_cand->cand_type;
+ if (has_single_use (base_in))
+ savings = (base_cand->dead_savings
+ + stmt_cost (base_cand->cand_stmt, speed));
+ }
}
else if (base_cand->kind == CAND_ADD && integer_onep (base_cand->stride))
{
diff --git a/gcc/gimplify.c b/gcc/gimplify.c
index d7470fbb0a6..008a2528644 100644
--- a/gcc/gimplify.c
+++ b/gcc/gimplify.c
@@ -5796,7 +5796,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, bool simd)
+omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, int simd)
{
splay_tree_node n;
@@ -5830,13 +5830,13 @@ omp_is_private (struct gimplify_omp_ctx *ctx, tree decl, bool simd)
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)
+ else if (simd == 1 && (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)
+ else if (simd == 2 && (n->value & GOVD_LINEAR) != 0)
error ("iteration variable %qE is predetermined linear",
DECL_NAME (decl));
}
@@ -6602,8 +6602,8 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
orig_for_stmt = for_stmt = *expr_p;
- simd = TREE_CODE (for_stmt) == OMP_SIMD
- || TREE_CODE (for_stmt) == CILK_SIMD;
+ simd = (TREE_CODE (for_stmt) == OMP_SIMD
+ || TREE_CODE (for_stmt) == CILK_SIMD);
gimplify_scan_omp_clauses (&OMP_FOR_CLAUSES (for_stmt), pre_p,
simd ? ORT_SIMD : ORT_WORKSHARE);
@@ -6659,13 +6659,16 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
/* Make sure the iteration variable is private. */
tree c = NULL_TREE;
+ tree c2 = NULL_TREE;
if (orig_for_stmt != for_stmt)
/* Do this only on innermost construct for combined ones. */;
else 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);
+ omp_is_private (gimplify_omp_ctxp, decl,
+ 1 + (TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt))
+ != 1));
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)
@@ -6691,13 +6694,14 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
: OMP_CLAUSE_PRIVATE);
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,
(lastprivate ? GOVD_LASTPRIVATE : GOVD_PRIVATE)
- | GOVD_SEEN);
+ | GOVD_EXPLICIT | GOVD_SEEN);
c = NULL_TREE;
}
}
- else if (omp_is_private (gimplify_omp_ctxp, decl, simd))
+ else if (omp_is_private (gimplify_omp_ctxp, decl, 0))
omp_notice_variable (gimplify_omp_ctxp, decl, true);
else
omp_add_variable (gimplify_omp_ctxp, decl, GOVD_PRIVATE | GOVD_SEEN);
@@ -6714,7 +6718,25 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gimplify_seq_add_stmt (&for_body, gimple_build_assign (decl, var));
- omp_add_variable (gimplify_omp_ctxp, var, GOVD_PRIVATE | GOVD_SEEN);
+ if (simd && TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) == 1)
+ {
+ c2 = build_omp_clause (input_location, OMP_CLAUSE_LINEAR);
+ OMP_CLAUSE_LINEAR_NO_COPYIN (c2) = 1;
+ OMP_CLAUSE_LINEAR_NO_COPYOUT (c2) = 1;
+ OMP_CLAUSE_DECL (c2) = var;
+ OMP_CLAUSE_CHAIN (c2) = OMP_FOR_CLAUSES (for_stmt);
+ OMP_FOR_CLAUSES (for_stmt) = c2;
+ omp_add_variable (gimplify_omp_ctxp, var,
+ GOVD_LINEAR | GOVD_EXPLICIT | GOVD_SEEN);
+ if (c == NULL_TREE)
+ {
+ c = c2;
+ c2 = NULL_TREE;
+ }
+ }
+ else
+ omp_add_variable (gimplify_omp_ctxp, var,
+ GOVD_PRIVATE | GOVD_SEEN);
}
else
var = decl;
@@ -6817,13 +6839,22 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gcc_unreachable ();
}
+ if (c2)
+ {
+ gcc_assert (c);
+ OMP_CLAUSE_LINEAR_STEP (c2) = OMP_CLAUSE_LINEAR_STEP (c);
+ }
+
if ((var != decl || TREE_VEC_LENGTH (OMP_FOR_INIT (for_stmt)) > 1)
&& orig_for_stmt == for_stmt)
{
for (c = OMP_FOR_CLAUSES (for_stmt); c ; c = OMP_CLAUSE_CHAIN (c))
- if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
- && OMP_CLAUSE_DECL (c) == decl
- && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
+ if (((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
+ && OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) == NULL)
+ || (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && !OMP_CLAUSE_LINEAR_NO_COPYOUT (c)
+ && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) == NULL))
+ && OMP_CLAUSE_DECL (c) == decl)
{
t = TREE_VEC_ELT (OMP_FOR_INCR (for_stmt), i);
gcc_assert (TREE_CODE (t) == MODIFY_EXPR);
@@ -6835,8 +6866,12 @@ gimplify_omp_for (tree *expr_p, gimple_seq *pre_p)
gcc_assert (TREE_OPERAND (t, 0) == var);
t = build2 (TREE_CODE (t), TREE_TYPE (decl), decl,
TREE_OPERAND (t, 1));
- gimplify_assign (decl, t,
- &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
+ gimple_seq *seq;
+ if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE)
+ seq = &OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c);
+ else
+ seq = &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c);
+ gimplify_assign (decl, t, seq);
}
}
}
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 966fd425d78..1a863b04dbc 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,16 @@
+2014-04-25 Chris Manghane <cmang@google.com>
+
+ * go-gcc.cc: Include "cgraph.h" and "gimplify.h".
+ (Gcc_backend::return_statement): Push and pop function.
+ (Gcc_backend::label): Likewise.
+ (Gcc_backend::function_defer_statement): Likewise.
+ (Gcc_backend::switch_statement): Add function parameter.
+ (Gcc_backend::block): Don't permit function to be NULL.
+ (Gcc_backend::temporary_variable): Change go_assert to
+ gcc_assert.
+ (Gcc_backend::gc_root_variable): New function.
+ (Gcc_backend::write_global_definitions): New function.
+
2014-04-22 Chris Manghane <cmang@google.com>
* go-gcc.cc (Gcc_backend::temporary_variable): Push cfun around
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 50403e159ef..a0283fe12e0 100644
--- a/gcc/go/go-gcc.cc
+++ b/gcc/go/go-gcc.cc
@@ -29,9 +29,11 @@
#include "stor-layout.h"
#include "varasm.h"
#include "tree-iterator.h"
+#include "cgraph.h"
#include "convert.h"
#include "basic-block.h"
#include "gimple-expr.h"
+#include "gimplify.h"
#include "toplev.h"
#include "output.h"
#include "real.h"
@@ -317,7 +319,7 @@ class Gcc_backend : public Backend
Location);
Bstatement*
- switch_statement(Bexpression* value,
+ switch_statement(Bfunction* function, Bexpression* value,
const std::vector<std::vector<Bexpression*> >& cases,
const std::vector<Bstatement*>& statements,
Location);
@@ -376,6 +378,9 @@ class Gcc_backend : public Backend
Location, Bstatement**);
Bvariable*
+ gc_root_variable(Btype*, Bexpression*);
+
+ Bvariable*
immutable_struct(const std::string&, bool, bool, Btype*, Location);
void
@@ -420,6 +425,12 @@ class Gcc_backend : public Backend
bool
function_set_body(Bfunction* function, Bstatement* code_stmt);
+ void
+ write_global_definitions(const std::vector<Btype*>&,
+ const std::vector<Bexpression*>&,
+ const std::vector<Bfunction*>&,
+ const std::vector<Bvariable*>&);
+
private:
// Make a Bexpression from a tree.
Bexpression*
@@ -1708,6 +1719,7 @@ Gcc_backend::return_statement(Bfunction* bfunction,
tree result = DECL_RESULT(fntree);
if (result == error_mark_node)
return this->error_statement();
+
tree ret;
if (vals.empty())
ret = fold_build1_loc(location.gcc_location(), RETURN_EXPR, void_type_node,
@@ -1731,7 +1743,14 @@ Gcc_backend::return_statement(Bfunction* bfunction,
// statement.
tree stmt_list = NULL_TREE;
tree rettype = TREE_TYPE(result);
+
+ if (DECL_STRUCT_FUNCTION(fntree) == NULL)
+ push_struct_function(fntree);
+ else
+ push_cfun(DECL_STRUCT_FUNCTION(fntree));
tree rettmp = create_tmp_var(rettype, "RESULT");
+ pop_cfun();
+
tree field = TYPE_FIELDS(rettype);
for (std::vector<Bexpression*>::const_iterator p = vals.begin();
p != vals.end();
@@ -1817,6 +1836,7 @@ Gcc_backend::if_statement(Bexpression* condition, Bblock* then_block,
Bstatement*
Gcc_backend::switch_statement(
+ Bfunction* function,
Bexpression* value,
const std::vector<std::vector<Bexpression*> >& cases,
const std::vector<Bstatement*>& statements,
@@ -1824,6 +1844,12 @@ Gcc_backend::switch_statement(
{
gcc_assert(cases.size() == statements.size());
+ tree decl = function->get_tree();
+ if (DECL_STRUCT_FUNCTION(decl) == NULL)
+ push_struct_function(decl);
+ else
+ push_cfun(DECL_STRUCT_FUNCTION(decl));
+
tree stmt_list = NULL_TREE;
std::vector<std::vector<Bexpression*> >::const_iterator pc = cases.begin();
for (std::vector<Bstatement*>::const_iterator ps = statements.begin();
@@ -1863,6 +1889,7 @@ Gcc_backend::switch_statement(
append_to_statement_list(t, &stmt_list);
}
}
+ pop_cfun();
tree tv = value->get_tree();
if (tv == error_mark_node)
@@ -1921,13 +1948,7 @@ Gcc_backend::block(Bfunction* function, Bblock* enclosing,
tree block_tree = make_node(BLOCK);
if (enclosing == NULL)
{
- // FIXME: Permitting FUNCTION to be NULL is a temporary measure
- // until we have a proper representation of the init function.
- tree fndecl;
- if (function == NULL)
- fndecl = current_function_decl;
- else
- fndecl = function->get_tree();
+ tree fndecl = function->get_tree();
gcc_assert(fndecl != NULL_TREE);
// We may have already created a block for local variables when
@@ -1981,7 +2002,6 @@ Gcc_backend::block(Bfunction* function, Bblock* enclosing,
void_type_node, BLOCK_VARS(block_tree),
NULL_TREE, block_tree);
TREE_SIDE_EFFECTS(bind_tree) = 1;
-
return new Bblock(bind_tree);
}
@@ -2213,7 +2233,7 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
return this->error_variable();
}
- go_assert(function != NULL);
+ gcc_assert(function != NULL);
tree decl = function->get_tree();
tree var;
@@ -2262,6 +2282,28 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock,
return new Bvariable(var);
}
+// Make a GC root variable.
+
+Bvariable*
+Gcc_backend::gc_root_variable(Btype* type, Bexpression* init)
+{
+ tree type_tree = type->get_tree();
+ tree init_tree = init->get_tree();
+ if (type_tree == error_mark_node || init_tree == error_mark_node)
+ return this->error_variable();
+
+ tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
+ create_tmp_var_name("gc"), type_tree);
+ DECL_EXTERNAL(decl) = 0;
+ TREE_PUBLIC(decl) = 0;
+ TREE_STATIC(decl) = 1;
+ DECL_ARTIFICIAL(decl) = 1;
+ DECL_INITIAL(decl) = init_tree;
+ rest_of_decl_compilation(decl, 1, 0);
+
+ return new Bvariable(decl);
+}
+
// Create a named immutable initialized data structure.
Bvariable*
@@ -2276,9 +2318,9 @@ Gcc_backend::immutable_struct(const std::string& name, bool is_hidden,
get_identifier_from_string(name),
build_qualified_type(type_tree, TYPE_QUAL_CONST));
TREE_STATIC(decl) = 1;
+ TREE_USED(decl) = 1;
TREE_READONLY(decl) = 1;
TREE_CONSTANT(decl) = 1;
- TREE_USED(decl) = 1;
DECL_ARTIFICIAL(decl) = 1;
if (!is_hidden)
TREE_PUBLIC(decl) = 1;
@@ -2368,7 +2410,17 @@ Gcc_backend::label(Bfunction* function, const std::string& name,
{
tree decl;
if (name.empty())
- decl = create_artificial_label(location.gcc_location());
+ {
+ tree func_tree = function->get_tree();
+ if (DECL_STRUCT_FUNCTION(func_tree) == NULL)
+ push_struct_function(func_tree);
+ else
+ push_cfun(DECL_STRUCT_FUNCTION(func_tree));
+
+ decl = create_artificial_label(location.gcc_location());
+
+ pop_cfun();
+ }
else
{
tree id = get_identifier_from_string(name);
@@ -2476,11 +2528,18 @@ Gcc_backend::function_defer_statement(Bfunction* function, Bexpression* undefer,
{
tree undefer_tree = undefer->get_tree();
tree defer_tree = defer->get_tree();
+ tree fntree = function->get_tree();
if (undefer_tree == error_mark_node
- || defer_tree == error_mark_node)
+ || defer_tree == error_mark_node
+ || fntree == error_mark_node)
return this->error_statement();
+ if (DECL_STRUCT_FUNCTION(fntree) == NULL)
+ push_struct_function(fntree);
+ else
+ push_cfun(DECL_STRUCT_FUNCTION(fntree));
+
tree stmt_list = NULL;
Blabel* blabel = this->label(function, "", location);
Bstatement* label_def = this->label_definition_statement(blabel);
@@ -2493,6 +2552,7 @@ Gcc_backend::function_defer_statement(Bfunction* function, Bexpression* undefer,
tree try_catch =
build2(TRY_CATCH_EXPR, void_type_node, undefer_tree, catch_body);
append_to_statement_list(try_catch, &stmt_list);
+ pop_cfun();
return this->make_statement(stmt_list);
}
@@ -2537,6 +2597,88 @@ Gcc_backend::function_set_body(Bfunction* function, Bstatement* code_stmt)
return true;
}
+// Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
+// FUNCTION_DECLS, and VARIABLE_DECLS declared globally.
+
+void
+Gcc_backend::write_global_definitions(
+ const std::vector<Btype*>& type_decls,
+ const std::vector<Bexpression*>& constant_decls,
+ const std::vector<Bfunction*>& function_decls,
+ const std::vector<Bvariable*>& variable_decls)
+{
+ size_t count_definitions = type_decls.size() + constant_decls.size()
+ + function_decls.size() + variable_decls.size();
+
+ tree* defs = new tree[count_definitions];
+
+ // Convert all non-erroneous declarations into Gimple form.
+ size_t i = 0;
+ for (std::vector<Bvariable*>::const_iterator p = variable_decls.begin();
+ p != variable_decls.end();
+ ++p)
+ {
+ if ((*p)->get_tree() != error_mark_node)
+ {
+ defs[i] = (*p)->get_tree();
+ go_preserve_from_gc(defs[i]);
+ ++i;
+ }
+ }
+
+ for (std::vector<Btype*>::const_iterator p = type_decls.begin();
+ p != type_decls.end();
+ ++p)
+ {
+ tree type_tree = (*p)->get_tree();
+ if (type_tree != error_mark_node
+ && IS_TYPE_OR_DECL_P(type_tree))
+ {
+ defs[i] = TYPE_NAME(type_tree);
+ gcc_assert(defs[i] != NULL);
+ go_preserve_from_gc(defs[i]);
+ ++i;
+ }
+ }
+ for (std::vector<Bexpression*>::const_iterator p = constant_decls.begin();
+ p != constant_decls.end();
+ ++p)
+ {
+ if ((*p)->get_tree() != error_mark_node)
+ {
+ defs[i] = (*p)->get_tree();
+ go_preserve_from_gc(defs[i]);
+ ++i;
+ }
+ }
+ for (std::vector<Bfunction*>::const_iterator p = function_decls.begin();
+ p != function_decls.end();
+ ++p)
+ {
+ tree decl = (*p)->get_tree();
+ if (decl != error_mark_node)
+ {
+ go_preserve_from_gc(decl);
+ gimplify_function_tree(decl);
+ cgraph_finalize_function(decl, true);
+
+ defs[i] = decl;
+ ++i;
+ }
+ }
+
+ // Pass everything back to the middle-end.
+
+ wrapup_global_declarations(defs, i);
+
+ finalize_compilation_unit();
+
+ check_global_declarations(defs, i);
+ emit_debug_global_declarations(defs, i);
+
+ delete[] defs;
+}
+
// The single backend.
static Gcc_backend gcc_backend;
diff --git a/gcc/go/gofrontend/backend.h b/gcc/go/gofrontend/backend.h
index dd76204e70c..aca3dc6f90e 100644
--- a/gcc/go/gofrontend/backend.h
+++ b/gcc/go/gofrontend/backend.h
@@ -406,9 +406,9 @@ class Backend
// integers, then STATEMENTS[i] is executed. STATEMENTS[i] will
// either end with a goto statement or will fall through into
// STATEMENTS[i + 1]. CASES[i] is empty for the default clause,
- // which need not be last.
+ // which need not be last. FUNCTION is the current function.
virtual Bstatement*
- switch_statement(Bexpression* value,
+ switch_statement(Bfunction* function, Bexpression* value,
const std::vector<std::vector<Bexpression*> >& cases,
const std::vector<Bstatement*>& statements,
Location) = 0;
@@ -534,6 +534,12 @@ class Backend
bool address_is_taken, Location location,
Bstatement** pstatement) = 0;
+ // Create a GC root variable. TYPE is the __go_gc_root_list struct described
+ // in Gogo::register_gc_vars. INIT is the composite literal consisting of a
+ // pointer to the next GC root and the global variables registered.
+ virtual Bvariable*
+ gc_root_variable(Btype* type, Bexpression* init) = 0;
+
// Create a named immutable initialized data structure. This is
// used for type descriptors, map descriptors, and function
// descriptors. This returns a Bvariable because it corresponds to
@@ -653,6 +659,16 @@ class Backend
// true on success, false on failure.
virtual bool
function_set_body(Bfunction* function, Bstatement* code_stmt) = 0;
+
+ // Utility.
+
+ // Write the definitions for all TYPE_DECLS, CONSTANT_DECLS,
+ // FUNCTION_DECLS, and VARIABLE_DECLS declared globally.
+ virtual void
+ write_global_definitions(const std::vector<Btype*>& type_decls,
+ const std::vector<Bexpression*>& constant_decls,
+ const std::vector<Bfunction*>& function_decls,
+ const std::vector<Bvariable*>& variable_decls) = 0;
};
// The backend interface has to define this function.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 74ae9ddcd7d..27562639176 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -3578,127 +3578,7 @@ Expression::make_unsafe_cast(Type* type, Expression* expr,
return new Unsafe_type_conversion_expression(type, expr, location);
}
-// Unary expressions.
-
-class Unary_expression : public Expression
-{
- public:
- Unary_expression(Operator op, Expression* expr, Location location)
- : Expression(EXPRESSION_UNARY, location),
- op_(op), escapes_(true), create_temp_(false), expr_(expr),
- issue_nil_check_(false)
- { }
-
- // Return the operator.
- Operator
- op() const
- { return this->op_; }
-
- // Return the operand.
- Expression*
- operand() const
- { return this->expr_; }
-
- // Record that an address expression does not escape.
- void
- set_does_not_escape()
- {
- go_assert(this->op_ == OPERATOR_AND);
- this->escapes_ = false;
- }
-
- // Record that this is an address expression which should create a
- // temporary variable if necessary. This is used for method calls.
- void
- set_create_temp()
- {
- go_assert(this->op_ == OPERATOR_AND);
- this->create_temp_ = true;
- }
-
- // Apply unary opcode OP to UNC, setting NC. Return true if this
- // could be done, false if not. Issue errors for overflow.
- static bool
- eval_constant(Operator op, const Numeric_constant* unc,
- Location, Numeric_constant* nc);
-
- static Expression*
- do_import(Import*);
-
- protected:
- int
- do_traverse(Traverse* traverse)
- { return Expression::traverse(&this->expr_, traverse); }
-
- Expression*
- do_lower(Gogo*, Named_object*, Statement_inserter*, int);
-
- Expression*
- do_flatten(Gogo*, Named_object*, Statement_inserter*);
-
- bool
- do_is_constant() const;
-
- bool
- do_is_immutable() const
- { return this->expr_->is_immutable()
- || (this->op_ == OPERATOR_AND && this->expr_->is_variable()); }
-
- bool
- do_numeric_constant_value(Numeric_constant*) const;
-
- Type*
- do_type();
-
- void
- do_determine_type(const Type_context*);
-
- void
- do_check_types(Gogo*);
-
- Expression*
- do_copy()
- {
- return Expression::make_unary(this->op_, this->expr_->copy(),
- this->location());
- }
-
- bool
- do_must_eval_subexpressions_in_order(int*) const
- { return this->op_ == OPERATOR_MULT; }
-
- bool
- do_is_addressable() const
- { return this->op_ == OPERATOR_MULT; }
-
- tree
- do_get_tree(Translate_context*);
-
- void
- do_export(Export*) const;
-
- void
- do_dump_expression(Ast_dump_context*) const;
-
- void
- do_issue_nil_check()
- { this->issue_nil_check_ = (this->op_ == OPERATOR_MULT); }
-
- private:
- // The unary operator to apply.
- Operator op_;
- // Normally true. False if this is an address expression which does
- // not escape the current function.
- bool escapes_;
- // True if this is an address expression which should create a
- // temporary variable if necessary.
- bool create_temp_;
- // The operand.
- Expression* expr_;
- // Whether or not to issue a nil check for this expression if its address
- // is being taken.
- bool issue_nil_check_;
-};
+// Class Unary_expression.
// If we are taking the address of a composite literal, and the
// contents are not constant, then we want to make a heap expression
@@ -4214,11 +4094,18 @@ Unary_expression::do_get_tree(Translate_context* context)
}
}
- // Build a decl for a constant constructor.
- if ((this->expr_->is_composite_literal()
+ if (this->is_gc_root_)
+ {
+ // Build a decl for a GC root variable. GC roots are mutable, so they
+ // cannot be represented as an immutable_struct in the backend.
+ Bvariable* gc_root = gogo->backend()->gc_root_variable(btype, bexpr);
+ bexpr = gogo->backend()->var_expression(gc_root, loc);
+ }
+ else if ((this->expr_->is_composite_literal()
|| this->expr_->string_expression() != NULL)
&& this->expr_->is_immutable())
{
+ // Build a decl for a constant constructor.
static unsigned int counter;
char buf[100];
snprintf(buf, sizeof buf, "C%u", counter);
@@ -12508,6 +12395,14 @@ Fixed_array_construction_expression::do_get_tree(Translate_context* context)
return expr_to_tree(this->get_constructor(context, btype));
}
+Expression*
+Expression::make_array_composite_literal(Type* type, Expression_list* vals,
+ Location location)
+{
+ go_assert(type->array_type() != NULL && !type->is_slice_type());
+ return new Fixed_array_construction_expression(type, NULL, vals, location);
+}
+
// Construct a slice.
class Slice_construction_expression : public Array_construction_expression
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index dc9ad71c820..0936e00bae0 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -30,6 +30,7 @@ class Var_expression;
class Temporary_reference_expression;
class Set_and_use_temporary_expression;
class String_expression;
+class Unary_expression;
class Binary_expression;
class Call_expression;
class Func_expression;
@@ -327,6 +328,10 @@ class Expression
static Expression*
make_struct_composite_literal(Type*, Expression_list*, Location);
+ // Make an array composite literal.
+ static Expression*
+ make_array_composite_literal(Type*, Expression_list*, Location);
+
// Make a slice composite literal.
static Expression*
make_slice_composite_literal(Type*, Expression_list*, Location);
@@ -533,6 +538,12 @@ class Expression
Expression*
deref();
+ // If this is a unary expression, return the Unary_expression
+ // structure. Otherwise return NULL.
+ Unary_expression*
+ unary_expression()
+ { return this->convert<Unary_expression, EXPRESSION_UNARY>(); }
+
// If this is a binary expression, return the Binary_expression
// structure. Otherwise return NULL.
Binary_expression*
@@ -1286,6 +1297,143 @@ class String_expression : public Expression
Type* type_;
};
+// A Unary expression.
+
+class Unary_expression : public Expression
+{
+ public:
+ Unary_expression(Operator op, Expression* expr, Location location)
+ : Expression(EXPRESSION_UNARY, location),
+ op_(op), escapes_(true), create_temp_(false), is_gc_root_(false),
+ expr_(expr), issue_nil_check_(false)
+ { }
+
+ // Return the operator.
+ Operator
+ op() const
+ { return this->op_; }
+
+ // Return the operand.
+ Expression*
+ operand() const
+ { return this->expr_; }
+
+ // Record that an address expression does not escape.
+ void
+ set_does_not_escape()
+ {
+ go_assert(this->op_ == OPERATOR_AND);
+ this->escapes_ = false;
+ }
+
+ // Record that this is an address expression which should create a
+ // temporary variable if necessary. This is used for method calls.
+ void
+ set_create_temp()
+ {
+ go_assert(this->op_ == OPERATOR_AND);
+ this->create_temp_ = true;
+ }
+
+ // Record that this is an address expression of a GC root, which is a
+ // mutable composite literal. This used for registering GC variables.
+ void
+ set_is_gc_root()
+ {
+ go_assert(this->op_ == OPERATOR_AND);
+ this->is_gc_root_ = true;
+ }
+
+ // Apply unary opcode OP to UNC, setting NC. Return true if this
+ // could be done, false if not. Issue errors for overflow.
+ static bool
+ eval_constant(Operator op, const Numeric_constant* unc,
+ Location, Numeric_constant* nc);
+
+ static Expression*
+ do_import(Import*);
+
+ protected:
+ int
+ do_traverse(Traverse* traverse)
+ { return Expression::traverse(&this->expr_, traverse); }
+
+ Expression*
+ do_lower(Gogo*, Named_object*, Statement_inserter*, int);
+
+ Expression*
+ do_flatten(Gogo*, Named_object*, Statement_inserter*);
+
+ bool
+ do_is_constant() const;
+
+ bool
+ do_is_immutable() const
+ {
+ return (this->expr_->is_immutable()
+ || (this->op_ == OPERATOR_AND && this->expr_->is_variable()));
+ }
+
+ bool
+ do_numeric_constant_value(Numeric_constant*) const;
+
+ Type*
+ do_type();
+
+ void
+ do_determine_type(const Type_context*);
+
+ void
+ do_check_types(Gogo*);
+
+ Expression*
+ do_copy()
+ {
+ return Expression::make_unary(this->op_, this->expr_->copy(),
+ this->location());
+ }
+
+ bool
+ do_must_eval_subexpressions_in_order(int*) const
+ { return this->op_ == OPERATOR_MULT; }
+
+ bool
+ do_is_addressable() const
+ { return this->op_ == OPERATOR_MULT; }
+
+ tree
+ do_get_tree(Translate_context*);
+
+ void
+ do_export(Export*) const;
+
+ void
+ do_dump_expression(Ast_dump_context*) const;
+
+ void
+ do_issue_nil_check()
+ { this->issue_nil_check_ = (this->op_ == OPERATOR_MULT); }
+
+ private:
+ // The unary operator to apply.
+ Operator op_;
+ // Normally true. False if this is an address expression which does
+ // not escape the current function.
+ bool escapes_;
+ // True if this is an address expression which should create a
+ // temporary variable if necessary.
+ bool create_temp_;
+ // True if this is an address expression for a GC root. A GC root is a
+ // special struct composite literal that is mutable when addressed, meaning
+ // it cannot be represented as an immutable_struct in the backend.
+ bool is_gc_root_;
+ // The operand.
+ Expression* expr_;
+ // Whether or not to issue a nil check for this expression if its address
+ // is being taken.
+ bool issue_nil_check_;
+};
+
// A binary expression.
class Binary_expression : public Expression
diff --git a/gcc/go/gofrontend/gogo-tree.cc b/gcc/go/gofrontend/gogo-tree.cc
index c00e7d16011..6b19a1d82e1 100644
--- a/gcc/go/gofrontend/gogo-tree.cc
+++ b/gcc/go/gofrontend/gogo-tree.cc
@@ -236,830 +236,6 @@ Gogo::define_builtin_function_trees()
false);
}
-// Add statements to INIT_STMT_LIST which run the initialization
-// functions for imported packages. This is only used for the "main"
-// package.
-
-void
-Gogo::init_imports(tree* init_stmt_list)
-{
- go_assert(this->is_main_package());
-
- if (this->imported_init_fns_.empty())
- return;
-
- tree fntype = build_function_type(void_type_node, void_list_node);
-
- // We must call them in increasing priority order.
- std::vector<Import_init> v;
- for (std::set<Import_init>::const_iterator p =
- this->imported_init_fns_.begin();
- p != this->imported_init_fns_.end();
- ++p)
- v.push_back(*p);
- std::sort(v.begin(), v.end());
-
- for (std::vector<Import_init>::const_iterator p = v.begin();
- p != v.end();
- ++p)
- {
- std::string user_name = p->package_name() + ".init";
- tree decl = build_decl(UNKNOWN_LOCATION, FUNCTION_DECL,
- get_identifier_from_string(user_name),
- fntype);
- const std::string& init_name(p->init_name());
- SET_DECL_ASSEMBLER_NAME(decl, get_identifier_from_string(init_name));
- TREE_PUBLIC(decl) = 1;
- DECL_EXTERNAL(decl) = 1;
- append_to_statement_list(build_call_expr(decl, 0), init_stmt_list);
- }
-}
-
-// Register global variables with the garbage collector. We need to
-// register all variables which can hold a pointer value. They become
-// roots during the mark phase. We build a struct that is easy to
-// hook into a list of roots.
-
-// struct __go_gc_root_list
-// {
-// struct __go_gc_root_list* __next;
-// struct __go_gc_root
-// {
-// void* __decl;
-// size_t __size;
-// } __roots[];
-// };
-
-// The last entry in the roots array has a NULL decl field.
-
-void
-Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
- tree* init_stmt_list)
-{
- if (var_gc.empty())
- return;
-
- size_t count = var_gc.size();
-
- tree root_type = Gogo::builtin_struct(NULL, "__go_gc_root", NULL_TREE, 2,
- "__next",
- ptr_type_node,
- "__size",
- sizetype);
-
- tree index_type = build_index_type(size_int(count));
- tree array_type = build_array_type(root_type, index_type);
-
- tree root_list_type = make_node(RECORD_TYPE);
- root_list_type = Gogo::builtin_struct(NULL, "__go_gc_root_list",
- root_list_type, 2,
- "__next",
- build_pointer_type(root_list_type),
- "__roots",
- array_type);
-
- // Build an initialier for the __roots array.
-
- vec<constructor_elt, va_gc> *roots_init;
- vec_alloc(roots_init, count + 1);
-
- size_t i = 0;
- for (std::vector<Named_object*>::const_iterator p = var_gc.begin();
- p != var_gc.end();
- ++p, ++i)
- {
- vec<constructor_elt, va_gc> *init;
- vec_alloc(init, 2);
-
- constructor_elt empty = {NULL, NULL};
- constructor_elt* elt = init->quick_push(empty);
- tree field = TYPE_FIELDS(root_type);
- elt->index = field;
- Bvariable* bvar = (*p)->get_backend_variable(this, NULL);
- tree decl = var_to_tree(bvar);
- go_assert(TREE_CODE(decl) == VAR_DECL);
- elt->value = build_fold_addr_expr(decl);
-
- elt = init->quick_push(empty);
- field = DECL_CHAIN(field);
- elt->index = field;
- elt->value = DECL_SIZE_UNIT(decl);
-
- elt = roots_init->quick_push(empty);
- elt->index = size_int(i);
- elt->value = build_constructor(root_type, init);
- }
-
- // The list ends with a NULL entry.
-
- vec<constructor_elt, va_gc> *init;
- vec_alloc(init, 2);
-
- constructor_elt empty = {NULL, NULL};
- constructor_elt* elt = init->quick_push(empty);
- tree field = TYPE_FIELDS(root_type);
- elt->index = field;
- elt->value = fold_convert(TREE_TYPE(field), null_pointer_node);
-
- elt = init->quick_push(empty);
- field = DECL_CHAIN(field);
- elt->index = field;
- elt->value = size_zero_node;
-
- elt = roots_init->quick_push(empty);
- elt->index = size_int(i);
- elt->value = build_constructor(root_type, init);
-
- // Build a constructor for the struct.
-
- vec<constructor_elt, va_gc> *root_list_init;
- vec_alloc(root_list_init, 2);
-
- elt = root_list_init->quick_push(empty);
- field = TYPE_FIELDS(root_list_type);
- elt->index = field;
- elt->value = fold_convert(TREE_TYPE(field), null_pointer_node);
-
- elt = root_list_init->quick_push(empty);
- field = DECL_CHAIN(field);
- elt->index = field;
- elt->value = build_constructor(array_type, roots_init);
-
- // Build a decl to register.
-
- tree decl = build_decl(BUILTINS_LOCATION, VAR_DECL,
- create_tmp_var_name("gc"), root_list_type);
- DECL_EXTERNAL(decl) = 0;
- TREE_PUBLIC(decl) = 0;
- TREE_STATIC(decl) = 1;
- DECL_ARTIFICIAL(decl) = 1;
- DECL_INITIAL(decl) = build_constructor(root_list_type, root_list_init);
- rest_of_decl_compilation(decl, 1, 0);
-
- static tree register_gc_fndecl;
- tree call = Gogo::call_builtin(&register_gc_fndecl,
- Linemap::predeclared_location(),
- "__go_register_gc_roots",
- 1,
- void_type_node,
- build_pointer_type(root_list_type),
- build_fold_addr_expr(decl));
- if (call != error_mark_node)
- append_to_statement_list(call, init_stmt_list);
-}
-
-// Create the magic initialization function. INIT_STMT_LIST is the
-// code that it needs to run.
-
-void
-Gogo::write_initialization_function(Named_object* initfn, tree init_stmt_list)
-{
- // Make sure that we thought we needed an initialization function,
- // as otherwise we will not have reported it in the export data.
- go_assert(this->is_main_package() || this->need_init_fn_);
-
- if (initfn == NULL)
- initfn = this->initialization_function_decl();
-
- Bfunction* fndecl = initfn->func_value()->get_or_make_decl(this, initfn);
- Location loc = this->package_->location();
- std::vector<Bvariable*> vars;
- this->backend()->block(fndecl, NULL, vars, loc, loc);
-
- if (!this->backend()->function_set_body(fndecl, tree_to_stat(init_stmt_list)))
- {
- go_assert(saw_errors());
- return;
- }
- gimplify_function_tree(function_to_tree(fndecl));
- cgraph_add_new_function(function_to_tree(fndecl), false);
-}
-
-// Search for references to VAR in any statements or called functions.
-
-class Find_var : public Traverse
-{
- public:
- // A hash table we use to avoid looping. The index is the name of a
- // named object. We only look through objects defined in this
- // package.
- typedef Unordered_set(const void*) Seen_objects;
-
- Find_var(Named_object* var, Seen_objects* seen_objects)
- : Traverse(traverse_expressions),
- var_(var), seen_objects_(seen_objects), found_(false)
- { }
-
- // Whether the variable was found.
- bool
- found() const
- { return this->found_; }
-
- int
- expression(Expression**);
-
- private:
- // The variable we are looking for.
- Named_object* var_;
- // Names of objects we have already seen.
- Seen_objects* seen_objects_;
- // True if the variable was found.
- bool found_;
-};
-
-// See if EXPR refers to VAR, looking through function calls and
-// variable initializations.
-
-int
-Find_var::expression(Expression** pexpr)
-{
- Expression* e = *pexpr;
-
- Var_expression* ve = e->var_expression();
- if (ve != NULL)
- {
- Named_object* v = ve->named_object();
- if (v == this->var_)
- {
- this->found_ = true;
- return TRAVERSE_EXIT;
- }
-
- if (v->is_variable() && v->package() == NULL)
- {
- Expression* init = v->var_value()->init();
- if (init != NULL)
- {
- std::pair<Seen_objects::iterator, bool> ins =
- this->seen_objects_->insert(v);
- if (ins.second)
- {
- // This is the first time we have seen this name.
- if (Expression::traverse(&init, this) == TRAVERSE_EXIT)
- return TRAVERSE_EXIT;
- }
- }
- }
- }
-
- // We traverse the code of any function we see. Note that this
- // means that we will traverse the code of a function whose address
- // is taken even if it is not called.
- Func_expression* fe = e->func_expression();
- if (fe != NULL)
- {
- const Named_object* f = fe->named_object();
- if (f->is_function() && f->package() == NULL)
- {
- std::pair<Seen_objects::iterator, bool> ins =
- this->seen_objects_->insert(f);
- if (ins.second)
- {
- // This is the first time we have seen this name.
- if (f->func_value()->block()->traverse(this) == TRAVERSE_EXIT)
- return TRAVERSE_EXIT;
- }
- }
- }
-
- Temporary_reference_expression* tre = e->temporary_reference_expression();
- if (tre != NULL)
- {
- Temporary_statement* ts = tre->statement();
- Expression* init = ts->init();
- if (init != NULL)
- {
- std::pair<Seen_objects::iterator, bool> ins =
- this->seen_objects_->insert(ts);
- if (ins.second)
- {
- // This is the first time we have seen this temporary
- // statement.
- if (Expression::traverse(&init, this) == TRAVERSE_EXIT)
- return TRAVERSE_EXIT;
- }
- }
- }
-
- return TRAVERSE_CONTINUE;
-}
-
-// Return true if EXPR, PREINIT, or DEP refers to VAR.
-
-static bool
-expression_requires(Expression* expr, Block* preinit, Named_object* dep,
- Named_object* var)
-{
- Find_var::Seen_objects seen_objects;
- Find_var find_var(var, &seen_objects);
- if (expr != NULL)
- Expression::traverse(&expr, &find_var);
- if (preinit != NULL)
- preinit->traverse(&find_var);
- if (dep != NULL)
- {
- Expression* init = dep->var_value()->init();
- if (init != NULL)
- Expression::traverse(&init, &find_var);
- if (dep->var_value()->has_pre_init())
- dep->var_value()->preinit()->traverse(&find_var);
- }
-
- return find_var.found();
-}
-
-// Sort variable initializations. If the initialization expression
-// for variable A refers directly or indirectly to the initialization
-// expression for variable B, then we must initialize B before A.
-
-class Var_init
-{
- public:
- Var_init()
- : var_(NULL), init_(NULL)
- { }
-
- Var_init(Named_object* var, Bstatement* init)
- : var_(var), init_(init)
- { }
-
- // Return the variable.
- Named_object*
- var() const
- { return this->var_; }
-
- // Return the initialization expression.
- Bstatement*
- init() const
- { return this->init_; }
-
- private:
- // The variable being initialized.
- Named_object* var_;
- // The initialization statement.
- Bstatement* init_;
-};
-
-typedef std::list<Var_init> Var_inits;
-
-// Sort the variable initializations. The rule we follow is that we
-// emit them in the order they appear in the array, except that if the
-// initialization expression for a variable V1 depends upon another
-// variable V2 then we initialize V1 after V2.
-
-static void
-sort_var_inits(Gogo* gogo, Var_inits* var_inits)
-{
- typedef std::pair<Named_object*, Named_object*> No_no;
- typedef std::map<No_no, bool> Cache;
- Cache cache;
-
- Var_inits ready;
- while (!var_inits->empty())
- {
- Var_inits::iterator p1 = var_inits->begin();
- Named_object* var = p1->var();
- Expression* init = var->var_value()->init();
- Block* preinit = var->var_value()->preinit();
- Named_object* dep = gogo->var_depends_on(var->var_value());
-
- // Start walking through the list to see which variables VAR
- // needs to wait for.
- Var_inits::iterator p2 = p1;
- ++p2;
-
- for (; p2 != var_inits->end(); ++p2)
- {
- Named_object* p2var = p2->var();
- No_no key(var, p2var);
- std::pair<Cache::iterator, bool> ins =
- cache.insert(std::make_pair(key, false));
- if (ins.second)
- ins.first->second = expression_requires(init, preinit, dep, p2var);
- if (ins.first->second)
- {
- // Check for cycles.
- key = std::make_pair(p2var, var);
- ins = cache.insert(std::make_pair(key, false));
- if (ins.second)
- ins.first->second =
- expression_requires(p2var->var_value()->init(),
- p2var->var_value()->preinit(),
- gogo->var_depends_on(p2var->var_value()),
- var);
- if (ins.first->second)
- {
- error_at(var->location(),
- ("initialization expressions for %qs and "
- "%qs depend upon each other"),
- var->message_name().c_str(),
- p2var->message_name().c_str());
- inform(p2->var()->location(), "%qs defined here",
- p2var->message_name().c_str());
- p2 = var_inits->end();
- }
- else
- {
- // We can't emit P1 until P2 is emitted. Move P1.
- Var_inits::iterator p3 = p2;
- ++p3;
- var_inits->splice(p3, *var_inits, p1);
- }
- break;
- }
- }
-
- if (p2 == var_inits->end())
- {
- // VAR does not depends upon any other initialization expressions.
-
- // Check for a loop of VAR on itself. We only do this if
- // INIT is not NULL and there is no dependency; when INIT is
- // NULL, it means that PREINIT sets VAR, which we will
- // interpret as a loop.
- if (init != NULL && dep == NULL
- && expression_requires(init, preinit, NULL, var))
- error_at(var->location(),
- "initialization expression for %qs depends upon itself",
- var->message_name().c_str());
- ready.splice(ready.end(), *var_inits, p1);
- }
- }
-
- // Now READY is the list in the desired initialization order.
- var_inits->swap(ready);
-}
-
-// Write out the global definitions.
-
-void
-Gogo::write_globals()
-{
- this->build_interface_method_tables();
-
- Bindings* bindings = this->current_bindings();
-
- for (Bindings::const_declarations_iterator p = bindings->begin_declarations();
- p != bindings->end_declarations();
- ++p)
- {
- // If any function declarations needed a descriptor, make sure
- // we build it.
- Named_object* no = p->second;
- if (no->is_function_declaration())
- no->func_declaration_value()->build_backend_descriptor(this);
- }
-
- size_t count_definitions = bindings->size_definitions();
- size_t count = count_definitions;
-
- tree* vec = new tree[count];
-
- Named_object* init_fndecl = NULL;
- tree init_stmt_list = NULL_TREE;
-
- if (this->is_main_package())
- this->init_imports(&init_stmt_list);
-
- // A list of variable initializations.
- Var_inits var_inits;
-
- // A list of variables which need to be registered with the garbage
- // collector.
- std::vector<Named_object*> var_gc;
- var_gc.reserve(count);
-
- tree var_init_stmt_list = NULL_TREE;
- size_t i = 0;
- for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
- p != bindings->end_definitions();
- ++p, ++i)
- {
- Named_object* no = *p;
-
- go_assert(i < count);
-
- go_assert(!no->is_type_declaration() && !no->is_function_declaration());
- // There is nothing to do for a package.
- if (no->is_package())
- {
- --i;
- --count;
- continue;
- }
-
- // There is nothing to do for an object which was imported from
- // a different package into the global scope.
- if (no->package() != NULL)
- {
- --i;
- --count;
- continue;
- }
-
- // Skip blank named functions and constants.
- if ((no->is_function() && no->func_value()->is_sink())
- || (no->is_const() && no->const_value()->is_sink()))
- {
- --i;
- --count;
- continue;
- }
-
- // There is nothing useful we can output for constants which
- // have ideal or non-integral type.
- if (no->is_const())
- {
- Type* type = no->const_value()->type();
- if (type == NULL)
- type = no->const_value()->expr()->type();
- if (type->is_abstract() || type->integer_type() == NULL)
- {
- --i;
- --count;
- continue;
- }
- }
-
- if (!no->is_variable())
- {
- vec[i] = no->get_tree(this, NULL);
- if (vec[i] == error_mark_node)
- {
- go_assert(saw_errors());
- --i;
- --count;
- continue;
- }
- }
- else
- {
- Bvariable* var = no->get_backend_variable(this, NULL);
- vec[i] = var_to_tree(var);
- if (vec[i] == error_mark_node)
- {
- go_assert(saw_errors());
- --i;
- --count;
- continue;
- }
-
- // Check for a sink variable, which may be used to run an
- // initializer purely for its side effects.
- bool is_sink = no->name()[0] == '_' && no->name()[1] == '.';
-
- Bstatement* var_init_stmt = NULL;
- if (!no->var_value()->has_pre_init())
- {
- Bexpression* var_binit = no->var_value()->get_init(this, NULL);
- if (var_binit == NULL)
- ;
- else if (TREE_CONSTANT(expr_to_tree(var_binit)))
- {
- if (expression_requires(no->var_value()->init(), NULL,
- this->var_depends_on(no->var_value()),
- no))
- error_at(no->location(),
- "initialization expression for %qs depends "
- "upon itself",
- no->message_name().c_str());
- this->backend()->global_variable_set_init(var, var_binit);
- }
- else if (is_sink)
- var_init_stmt =
- this->backend()->expression_statement(var_binit);
- else
- {
- Location loc = no->var_value()->location();
- Bexpression* var_expr =
- this->backend()->var_expression(var, loc);
- var_init_stmt =
- this->backend()->assignment_statement(var_expr, var_binit,
- loc);
- }
- }
- else
- {
- // We are going to create temporary variables which
- // means that we need an fndecl.
- if (init_fndecl == NULL)
- init_fndecl = this->initialization_function_decl();
-
- Bvariable* var_decl = is_sink ? NULL : var;
- var_init_stmt =
- no->var_value()->get_init_block(this, init_fndecl, var_decl);
- }
-
- if (var_init_stmt != NULL)
- {
- if (no->var_value()->init() == NULL
- && !no->var_value()->has_pre_init())
- append_to_statement_list(stat_to_tree(var_init_stmt),
- &var_init_stmt_list);
- else
- var_inits.push_back(Var_init(no, var_init_stmt));
- }
- else if (this->var_depends_on(no->var_value()) != NULL)
- {
- // This variable is initialized from something that is
- // not in its init or preinit. This variable needs to
- // participate in dependency analysis sorting, in case
- // some other variable depends on this one.
- Btype* int_btype =
- Type::lookup_integer_type("int")->get_backend(this);
- Bexpression* zero = this->backend()->zero_expression(int_btype);
- Bstatement* zero_stmt =
- this->backend()->expression_statement(zero);
- var_inits.push_back(Var_init(no, zero_stmt));
- }
-
- if (!is_sink && no->var_value()->type()->has_pointer())
- var_gc.push_back(no);
- }
- }
-
- // Register global variables with the garbage collector.
- this->register_gc_vars(var_gc, &init_stmt_list);
-
- // Simple variable initializations, after all variables are
- // registered.
- append_to_statement_list(var_init_stmt_list, &init_stmt_list);
-
- // Complex variable initializations, first sorting them into a
- // workable order.
- if (!var_inits.empty())
- {
- sort_var_inits(this, &var_inits);
- for (Var_inits::const_iterator p = var_inits.begin();
- p != var_inits.end();
- ++p)
- append_to_statement_list(stat_to_tree(p->init()), &init_stmt_list);
- }
-
- // After all the variables are initialized, call the "init"
- // functions if there are any.
- for (std::vector<Named_object*>::const_iterator p =
- this->init_functions_.begin();
- p != this->init_functions_.end();
- ++p)
- {
- tree decl = (*p)->get_tree(this, NULL);
- tree call = build_call_expr(decl, 0);
- append_to_statement_list(call, &init_stmt_list);
- }
-
- // Set up a magic function to do all the initialization actions.
- // This will be called if this package is imported.
- if (init_stmt_list != NULL
- || this->need_init_fn_
- || this->is_main_package())
- this->write_initialization_function(init_fndecl, init_stmt_list);
-
- // We should not have seen any new bindings created during the
- // conversion.
- go_assert(count_definitions == this->current_bindings()->size_definitions());
-
- // Pass everything back to the middle-end.
-
- wrapup_global_declarations(vec, count);
-
- finalize_compilation_unit();
-
- check_global_declarations(vec, count);
- emit_debug_global_declarations(vec, count);
-
- delete[] vec;
-}
-
-// Get a tree for a named object.
-
-tree
-Named_object::get_tree(Gogo* gogo, Named_object* function)
-{
- if (this->tree_ != NULL_TREE)
- return this->tree_;
-
- if (Gogo::is_erroneous_name(this->name_))
- {
- this->tree_ = error_mark_node;
- return error_mark_node;
- }
-
- tree decl;
- switch (this->classification_)
- {
- case NAMED_OBJECT_CONST:
- {
- Translate_context subcontext(gogo, function, NULL, NULL);
- Type* type = this->u_.const_value->type();
- Location loc = this->location();
-
- Expression* const_ref = Expression::make_const_reference(this, loc);
- Bexpression* const_decl =
- tree_to_expr(const_ref->get_tree(&subcontext));
- if (type != NULL && type->is_numeric_type())
- {
- Btype* btype = type->get_backend(gogo);
- std::string name = this->get_id(gogo);
- const_decl =
- gogo->backend()->named_constant_expression(btype, name,
- const_decl, loc);
- }
- decl = expr_to_tree(const_decl);
- }
- break;
-
- case NAMED_OBJECT_TYPE:
- {
- Named_type* named_type = this->u_.type_value;
- tree type_tree = type_to_tree(named_type->get_backend(gogo));
- if (type_tree == error_mark_node)
- decl = error_mark_node;
- else
- {
- decl = TYPE_NAME(type_tree);
- go_assert(decl != NULL_TREE);
-
- // We need to produce a type descriptor for every named
- // type, and for a pointer to every named type, since
- // other files or packages might refer to them. We need
- // to do this even for hidden types, because they might
- // still be returned by some function. Simply calling the
- // type_descriptor method is enough to create the type
- // descriptor, even though we don't do anything with it.
- if (this->package_ == NULL)
- {
- named_type->
- type_descriptor_pointer(gogo,
- Linemap::predeclared_location());
- Type* pn = Type::make_pointer_type(named_type);
- pn->type_descriptor_pointer(gogo,
- Linemap::predeclared_location());
- }
- }
- }
- break;
-
- case NAMED_OBJECT_TYPE_DECLARATION:
- error("reference to undefined type %qs",
- this->message_name().c_str());
- return error_mark_node;
-
- case NAMED_OBJECT_VAR:
- case NAMED_OBJECT_RESULT_VAR:
- case NAMED_OBJECT_SINK:
- go_unreachable();
-
- case NAMED_OBJECT_FUNC:
- {
- Function* func = this->u_.func_value;
- decl = function_to_tree(func->get_or_make_decl(gogo, this));
- if (decl != error_mark_node)
- {
- if (func->block() != NULL)
- {
- if (DECL_STRUCT_FUNCTION(decl) == NULL)
- push_struct_function(decl);
- else
- push_cfun(DECL_STRUCT_FUNCTION(decl));
-
- cfun->function_start_locus = func->location().gcc_location();
- cfun->function_end_locus =
- func->block()->end_location().gcc_location();
-
- func->build(gogo, this);
-
- gimplify_function_tree(decl);
-
- cgraph_finalize_function(decl, true);
-
- pop_cfun();
- }
- }
- }
- break;
-
- case NAMED_OBJECT_ERRONEOUS:
- decl = error_mark_node;
- break;
-
- default:
- go_unreachable();
- }
-
- if (TREE_TYPE(decl) == error_mark_node)
- decl = error_mark_node;
-
- tree ret = decl;
-
- this->tree_ = ret;
-
- if (ret != error_mark_node)
- go_preserve_from_gc(ret);
-
- return ret;
-}
-
// Get the backend representation.
Bfunction*
@@ -1106,15 +282,6 @@ Function_declaration::get_or_make_decl(Gogo* gogo, Named_object* no)
return this->fndecl_;
}
-// Return the function's decl after it has been built.
-
-tree
-Function::get_decl() const
-{
- go_assert(this->fndecl_ != NULL);
- return function_to_tree(this->fndecl_);
-}
-
// Build the descriptor for a function declaration. This won't
// necessarily happen if the package has just a declaration for the
// function and no other reference to it, but we may still need the
@@ -1214,55 +381,6 @@ go_type_for_mode(enum machine_mode mode, int unsignedp)
return NULL_TREE;
}
-// Build a builtin struct with a list of fields. The name is
-// STRUCT_NAME. STRUCT_TYPE is NULL_TREE or an empty RECORD_TYPE
-// node; this exists so that the struct can have fields which point to
-// itself. If PTYPE is not NULL, store the result in *PTYPE. There
-// are NFIELDS fields. Each field is a name (a const char*) followed
-// by a type (a tree).
-
-tree
-Gogo::builtin_struct(tree* ptype, const char* struct_name, tree struct_type,
- int nfields, ...)
-{
- if (ptype != NULL && *ptype != NULL_TREE)
- return *ptype;
-
- va_list ap;
- va_start(ap, nfields);
-
- tree fields = NULL_TREE;
- for (int i = 0; i < nfields; ++i)
- {
- const char* field_name = va_arg(ap, const char*);
- tree type = va_arg(ap, tree);
- if (type == error_mark_node)
- {
- if (ptype != NULL)
- *ptype = error_mark_node;
- return error_mark_node;
- }
- tree field = build_decl(BUILTINS_LOCATION, FIELD_DECL,
- get_identifier(field_name), type);
- DECL_CHAIN(field) = fields;
- fields = field;
- }
-
- va_end(ap);
-
- if (struct_type == NULL_TREE)
- struct_type = make_node(RECORD_TYPE);
- finish_builtin_struct(struct_type, struct_name, fields, NULL_TREE);
-
- if (ptype != NULL)
- {
- go_preserve_from_gc(struct_type);
- *ptype = struct_type;
- }
-
- return struct_type;
-}
-
// Build a constructor for a slice. SLICE_TYPE_TREE is the type of
// the slice. VALUES is the value pointer and COUNT is the number of
// entries. If CAPACITY is not NULL, it is the capacity; otherwise
diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc
index ac9510ed9a6..c6ff9886090 100644
--- a/gcc/go/gofrontend/gogo.cc
+++ b/gcc/go/gofrontend/gogo.cc
@@ -575,6 +575,164 @@ Gogo::current_bindings() const
return this->globals_;
}
+// Add statements to INIT_STMTS which run the initialization
+// functions for imported packages. This is only used for the "main"
+// package.
+
+void
+Gogo::init_imports(std::vector<Bstatement*>& init_stmts)
+{
+ go_assert(this->is_main_package());
+
+ if (this->imported_init_fns_.empty())
+ return;
+
+ Location unknown_loc = Linemap::unknown_location();
+ Function_type* func_type =
+ Type::make_function_type(NULL, NULL, NULL, unknown_loc);
+ Btype* fntype = func_type->get_backend_fntype(this);
+
+ // We must call them in increasing priority order.
+ std::vector<Import_init> v;
+ for (std::set<Import_init>::const_iterator p =
+ this->imported_init_fns_.begin();
+ p != this->imported_init_fns_.end();
+ ++p)
+ v.push_back(*p);
+ std::sort(v.begin(), v.end());
+
+ // We build calls to the init functions, which take no arguments.
+ std::vector<Bexpression*> empty_args;
+ for (std::vector<Import_init>::const_iterator p = v.begin();
+ p != v.end();
+ ++p)
+ {
+ std::string user_name = p->package_name() + ".init";
+ const std::string& init_name(p->init_name());
+
+ Bfunction* pfunc = this->backend()->function(fntype, user_name, init_name,
+ true, true, true, false,
+ false, unknown_loc);
+ Bexpression* pfunc_code =
+ this->backend()->function_code_expression(pfunc, unknown_loc);
+ Bexpression* pfunc_call =
+ this->backend()->call_expression(pfunc_code, empty_args, unknown_loc);
+ init_stmts.push_back(this->backend()->expression_statement(pfunc_call));
+ }
+}
+
+// Register global variables with the garbage collector. We need to
+// register all variables which can hold a pointer value. They become
+// roots during the mark phase. We build a struct that is easy to
+// hook into a list of roots.
+
+// struct __go_gc_root_list
+// {
+// struct __go_gc_root_list* __next;
+// struct __go_gc_root
+// {
+// void* __decl;
+// size_t __size;
+// } __roots[];
+// };
+
+// The last entry in the roots array has a NULL decl field.
+
+void
+Gogo::register_gc_vars(const std::vector<Named_object*>& var_gc,
+ std::vector<Bstatement*>& init_stmts)
+{
+ if (var_gc.empty())
+ return;
+
+ Type* pvt = Type::make_pointer_type(Type::make_void_type());
+ Type* uint_type = Type::lookup_integer_type("uint");
+ Struct_type* root_type = Type::make_builtin_struct_type(2,
+ "__decl", pvt,
+ "__size", uint_type);
+
+ Location builtin_loc = Linemap::predeclared_location();
+ size_t count = var_gc.size();
+ mpz_t lenval;
+ mpz_init_set_ui(lenval, count);
+ Expression* length = Expression::make_integer(&lenval, NULL, builtin_loc);
+ mpz_clear(lenval);
+
+ Array_type* root_array_type = Type::make_array_type(root_type, length);
+ Type* ptdt = Type::make_type_descriptor_ptr_type();
+ Struct_type* root_list_type =
+ Type::make_builtin_struct_type(2,
+ "__next", ptdt,
+ "__roots", root_array_type);
+
+ // Build an initializer for the __roots array.
+
+ Expression_list* roots_init = new Expression_list();
+
+ size_t i = 0;
+ for (std::vector<Named_object*>::const_iterator p = var_gc.begin();
+ p != var_gc.end();
+ ++p, ++i)
+ {
+ Expression_list* init = new Expression_list();
+
+ Location no_loc = (*p)->location();
+ Expression* decl = Expression::make_var_reference(*p, no_loc);
+ Expression* decl_addr =
+ Expression::make_unary(OPERATOR_AND, decl, no_loc);
+ init->push_back(decl_addr);
+
+ Expression* decl_size =
+ Expression::make_type_info(decl->type(), Expression::TYPE_INFO_SIZE);
+ init->push_back(decl_size);
+
+ Expression* root_ctor =
+ Expression::make_struct_composite_literal(root_type, init, no_loc);
+ roots_init->push_back(root_ctor);
+ }
+
+ // The list ends with a NULL entry.
+
+ Expression_list* null_init = new Expression_list();
+ Expression* nil = Expression::make_nil(builtin_loc);
+ null_init->push_back(nil);
+
+ mpz_t zval;
+ mpz_init_set_ui(zval, 0UL);
+ Expression* zero = Expression::make_integer(&zval, NULL, builtin_loc);
+ mpz_clear(zval);
+ null_init->push_back(zero);
+
+ Expression* null_root_ctor =
+ Expression::make_struct_composite_literal(root_type, null_init,
+ builtin_loc);
+ roots_init->push_back(null_root_ctor);
+
+ // Build a constructor for the struct.
+
+ Expression_list* root_list_init = new Expression_list();
+ root_list_init->push_back(nil);
+
+ Expression* roots_ctor =
+ Expression::make_array_composite_literal(root_array_type, roots_init,
+ builtin_loc);
+ root_list_init->push_back(roots_ctor);
+
+ Expression* root_list_ctor =
+ Expression::make_struct_composite_literal(root_list_type, root_list_init,
+ builtin_loc);
+
+ Expression* root_addr = Expression::make_unary(OPERATOR_AND, root_list_ctor,
+ builtin_loc);
+ root_addr->unary_expression()->set_is_gc_root();
+ Expression* register_roots = Runtime::make_call(Runtime::REGISTER_GC_ROOTS,
+ builtin_loc, 1, root_addr);
+
+ Translate_context context(this, NULL, NULL, NULL);
+ Bexpression* bcall = tree_to_expr(register_roots->get_tree(&context));
+ init_stmts.push_back(this->backend()->expression_statement(bcall));
+}
+
// Get the name to use for the import control function. If there is a
// global function or variable, then we know that that name must be
// unique in the link, and we use it as the basis for our name.
@@ -614,6 +772,521 @@ Gogo::initialization_function_decl()
return Named_object::make_function(name, NULL, initfn);
}
+// Create the magic initialization function. CODE_STMT is the
+// code that it needs to run.
+
+Named_object*
+Gogo::create_initialization_function(Named_object* initfn,
+ Bstatement* code_stmt)
+{
+ // Make sure that we thought we needed an initialization function,
+ // as otherwise we will not have reported it in the export data.
+ go_assert(this->is_main_package() || this->need_init_fn_);
+
+ if (initfn == NULL)
+ initfn = this->initialization_function_decl();
+
+ // Bind the initialization function code to a block.
+ Bfunction* fndecl = initfn->func_value()->get_or_make_decl(this, initfn);
+ Location pkg_loc = this->package_->location();
+ std::vector<Bvariable*> vars;
+ this->backend()->block(fndecl, NULL, vars, pkg_loc, pkg_loc);
+
+ if (!this->backend()->function_set_body(fndecl, code_stmt))
+ {
+ go_assert(saw_errors());
+ return NULL;
+ }
+ return initfn;
+}
+
+// Search for references to VAR in any statements or called functions.
+
+class Find_var : public Traverse
+{
+ public:
+ // A hash table we use to avoid looping. The index is the name of a
+ // named object. We only look through objects defined in this
+ // package.
+ typedef Unordered_set(const void*) Seen_objects;
+
+ Find_var(Named_object* var, Seen_objects* seen_objects)
+ : Traverse(traverse_expressions),
+ var_(var), seen_objects_(seen_objects), found_(false)
+ { }
+
+ // Whether the variable was found.
+ bool
+ found() const
+ { return this->found_; }
+
+ int
+ expression(Expression**);
+
+ private:
+ // The variable we are looking for.
+ Named_object* var_;
+ // Names of objects we have already seen.
+ Seen_objects* seen_objects_;
+ // True if the variable was found.
+ bool found_;
+};
+
+// See if EXPR refers to VAR, looking through function calls and
+// variable initializations.
+
+int
+Find_var::expression(Expression** pexpr)
+{
+ Expression* e = *pexpr;
+
+ Var_expression* ve = e->var_expression();
+ if (ve != NULL)
+ {
+ Named_object* v = ve->named_object();
+ if (v == this->var_)
+ {
+ this->found_ = true;
+ return TRAVERSE_EXIT;
+ }
+
+ if (v->is_variable() && v->package() == NULL)
+ {
+ Expression* init = v->var_value()->init();
+ if (init != NULL)
+ {
+ std::pair<Seen_objects::iterator, bool> ins =
+ this->seen_objects_->insert(v);
+ if (ins.second)
+ {
+ // This is the first time we have seen this name.
+ if (Expression::traverse(&init, this) == TRAVERSE_EXIT)
+ return TRAVERSE_EXIT;
+ }
+ }
+ }
+ }
+
+ // We traverse the code of any function we see. Note that this
+ // means that we will traverse the code of a function whose address
+ // is taken even if it is not called.
+ Func_expression* fe = e->func_expression();
+ if (fe != NULL)
+ {
+ const Named_object* f = fe->named_object();
+ if (f->is_function() && f->package() == NULL)
+ {
+ std::pair<Seen_objects::iterator, bool> ins =
+ this->seen_objects_->insert(f);
+ if (ins.second)
+ {
+ // This is the first time we have seen this name.
+ if (f->func_value()->block()->traverse(this) == TRAVERSE_EXIT)
+ return TRAVERSE_EXIT;
+ }
+ }
+ }
+
+ Temporary_reference_expression* tre = e->temporary_reference_expression();
+ if (tre != NULL)
+ {
+ Temporary_statement* ts = tre->statement();
+ Expression* init = ts->init();
+ if (init != NULL)
+ {
+ std::pair<Seen_objects::iterator, bool> ins =
+ this->seen_objects_->insert(ts);
+ if (ins.second)
+ {
+ // This is the first time we have seen this temporary
+ // statement.
+ if (Expression::traverse(&init, this) == TRAVERSE_EXIT)
+ return TRAVERSE_EXIT;
+ }
+ }
+ }
+
+ return TRAVERSE_CONTINUE;
+}
+
+// Return true if EXPR, PREINIT, or DEP refers to VAR.
+
+static bool
+expression_requires(Expression* expr, Block* preinit, Named_object* dep,
+ Named_object* var)
+{
+ Find_var::Seen_objects seen_objects;
+ Find_var find_var(var, &seen_objects);
+ if (expr != NULL)
+ Expression::traverse(&expr, &find_var);
+ if (preinit != NULL)
+ preinit->traverse(&find_var);
+ if (dep != NULL)
+ {
+ Expression* init = dep->var_value()->init();
+ if (init != NULL)
+ Expression::traverse(&init, &find_var);
+ if (dep->var_value()->has_pre_init())
+ dep->var_value()->preinit()->traverse(&find_var);
+ }
+
+ return find_var.found();
+}
+
+// Sort variable initializations. If the initialization expression
+// for variable A refers directly or indirectly to the initialization
+// expression for variable B, then we must initialize B before A.
+
+class Var_init
+{
+ public:
+ Var_init()
+ : var_(NULL), init_(NULL)
+ { }
+
+ Var_init(Named_object* var, Bstatement* init)
+ : var_(var), init_(init)
+ { }
+
+ // Return the variable.
+ Named_object*
+ var() const
+ { return this->var_; }
+
+ // Return the initialization expression.
+ Bstatement*
+ init() const
+ { return this->init_; }
+
+ private:
+ // The variable being initialized.
+ Named_object* var_;
+ // The initialization statement.
+ Bstatement* init_;
+};
+
+typedef std::list<Var_init> Var_inits;
+
+// Sort the variable initializations. The rule we follow is that we
+// emit them in the order they appear in the array, except that if the
+// initialization expression for a variable V1 depends upon another
+// variable V2 then we initialize V1 after V2.
+
+static void
+sort_var_inits(Gogo* gogo, Var_inits* var_inits)
+{
+ typedef std::pair<Named_object*, Named_object*> No_no;
+ typedef std::map<No_no, bool> Cache;
+ Cache cache;
+
+ Var_inits ready;
+ while (!var_inits->empty())
+ {
+ Var_inits::iterator p1 = var_inits->begin();
+ Named_object* var = p1->var();
+ Expression* init = var->var_value()->init();
+ Block* preinit = var->var_value()->preinit();
+ Named_object* dep = gogo->var_depends_on(var->var_value());
+
+ // Start walking through the list to see which variables VAR
+ // needs to wait for.
+ Var_inits::iterator p2 = p1;
+ ++p2;
+
+ for (; p2 != var_inits->end(); ++p2)
+ {
+ Named_object* p2var = p2->var();
+ No_no key(var, p2var);
+ std::pair<Cache::iterator, bool> ins =
+ cache.insert(std::make_pair(key, false));
+ if (ins.second)
+ ins.first->second = expression_requires(init, preinit, dep, p2var);
+ if (ins.first->second)
+ {
+ // Check for cycles.
+ key = std::make_pair(p2var, var);
+ ins = cache.insert(std::make_pair(key, false));
+ if (ins.second)
+ ins.first->second =
+ expression_requires(p2var->var_value()->init(),
+ p2var->var_value()->preinit(),
+ gogo->var_depends_on(p2var->var_value()),
+ var);
+ if (ins.first->second)
+ {
+ error_at(var->location(),
+ ("initialization expressions for %qs and "
+ "%qs depend upon each other"),
+ var->message_name().c_str(),
+ p2var->message_name().c_str());
+ inform(p2->var()->location(), "%qs defined here",
+ p2var->message_name().c_str());
+ p2 = var_inits->end();
+ }
+ else
+ {
+ // We can't emit P1 until P2 is emitted. Move P1.
+ Var_inits::iterator p3 = p2;
+ ++p3;
+ var_inits->splice(p3, *var_inits, p1);
+ }
+ break;
+ }
+ }
+
+ if (p2 == var_inits->end())
+ {
+ // VAR does not depends upon any other initialization expressions.
+
+ // Check for a loop of VAR on itself. We only do this if
+ // INIT is not NULL and there is no dependency; when INIT is
+ // NULL, it means that PREINIT sets VAR, which we will
+ // interpret as a loop.
+ if (init != NULL && dep == NULL
+ && expression_requires(init, preinit, NULL, var))
+ error_at(var->location(),
+ "initialization expression for %qs depends upon itself",
+ var->message_name().c_str());
+ ready.splice(ready.end(), *var_inits, p1);
+ }
+ }
+
+ // Now READY is the list in the desired initialization order.
+ var_inits->swap(ready);
+}
+
+// Write out the global definitions.
+
+void
+Gogo::write_globals()
+{
+ this->build_interface_method_tables();
+
+ Bindings* bindings = this->current_bindings();
+
+ for (Bindings::const_declarations_iterator p = bindings->begin_declarations();
+ p != bindings->end_declarations();
+ ++p)
+ {
+ // If any function declarations needed a descriptor, make sure
+ // we build it.
+ Named_object* no = p->second;
+ if (no->is_function_declaration())
+ no->func_declaration_value()->build_backend_descriptor(this);
+ }
+
+ // Lists of globally declared types, variables, constants, and functions
+ // that must be defined.
+ std::vector<Btype*> type_decls;
+ std::vector<Bvariable*> var_decls;
+ std::vector<Bexpression*> const_decls;
+ std::vector<Bfunction*> func_decls;
+
+ // The init function declaration, if necessary.
+ Named_object* init_fndecl = NULL;
+
+ std::vector<Bstatement*> init_stmts;
+ std::vector<Bstatement*> var_init_stmts;
+
+ if (this->is_main_package())
+ this->init_imports(init_stmts);
+
+ // A list of variable initializations.
+ Var_inits var_inits;
+
+ // A list of variables which need to be registered with the garbage
+ // collector.
+ size_t count_definitions = bindings->size_definitions();
+ std::vector<Named_object*> var_gc;
+ var_gc.reserve(count_definitions);
+
+ for (Bindings::const_definitions_iterator p = bindings->begin_definitions();
+ p != bindings->end_definitions();
+ ++p)
+ {
+ Named_object* no = *p;
+ go_assert(!no->is_type_declaration() && !no->is_function_declaration());
+
+ // There is nothing to do for a package.
+ if (no->is_package())
+ continue;
+
+ // There is nothing to do for an object which was imported from
+ // a different package into the global scope.
+ if (no->package() != NULL)
+ continue;
+
+ // Skip blank named functions and constants.
+ if ((no->is_function() && no->func_value()->is_sink())
+ || (no->is_const() && no->const_value()->is_sink()))
+ continue;
+
+ // There is nothing useful we can output for constants which
+ // have ideal or non-integral type.
+ if (no->is_const())
+ {
+ Type* type = no->const_value()->type();
+ if (type == NULL)
+ type = no->const_value()->expr()->type();
+ if (type->is_abstract() || !type->is_numeric_type())
+ continue;
+ }
+
+ if (!no->is_variable())
+ no->get_backend(this, const_decls, type_decls, func_decls);
+ else
+ {
+ Variable* var = no->var_value();
+ Bvariable* bvar = no->get_backend_variable(this, NULL);
+ var_decls.push_back(bvar);
+
+ // Check for a sink variable, which may be used to run an
+ // initializer purely for its side effects.
+ bool is_sink = no->name()[0] == '_' && no->name()[1] == '.';
+
+ Bstatement* var_init_stmt = NULL;
+ if (!var->has_pre_init())
+ {
+ Bexpression* var_binit = var->get_init(this, NULL);
+
+ // If the backend representation of the variable initializer is
+ // constant, we can just set the initial value using
+ // global_var_set_init instead of during the init() function.
+ // The initializer is constant if it is the zero-value of the
+ // variable's type or if the initial value is an immutable value
+ // that is not copied to the heap.
+ bool is_constant_initializer = false;
+ if (var->init() == NULL)
+ is_constant_initializer = true;
+ else
+ {
+ Type* var_type = var->type();
+ Expression* init = var->init();
+ Expression* init_cast =
+ Expression::make_cast(var_type, init, var->location());
+ is_constant_initializer =
+ init_cast->is_immutable() && !var_type->has_pointer();
+ }
+
+ if (var_binit == NULL)
+ ;
+ else if (is_constant_initializer)
+ {
+ if (expression_requires(var->init(), NULL,
+ this->var_depends_on(var), no))
+ error_at(no->location(),
+ "initialization expression for %qs depends "
+ "upon itself",
+ no->message_name().c_str());
+ this->backend()->global_variable_set_init(bvar, var_binit);
+ }
+ else if (is_sink)
+ var_init_stmt =
+ this->backend()->expression_statement(var_binit);
+ else
+ {
+ Location loc = var->location();
+ Bexpression* var_expr =
+ this->backend()->var_expression(bvar, loc);
+ var_init_stmt =
+ this->backend()->assignment_statement(var_expr, var_binit,
+ loc);
+ }
+ }
+ else
+ {
+ // We are going to create temporary variables which
+ // means that we need an fndecl.
+ if (init_fndecl == NULL)
+ init_fndecl = this->initialization_function_decl();
+
+ Bvariable* var_decl = is_sink ? NULL : bvar;
+ var_init_stmt = var->get_init_block(this, init_fndecl, var_decl);
+ }
+
+ if (var_init_stmt != NULL)
+ {
+ if (var->init() == NULL && !var->has_pre_init())
+ var_init_stmts.push_back(var_init_stmt);
+ else
+ var_inits.push_back(Var_init(no, var_init_stmt));
+ }
+ else if (this->var_depends_on(var) != NULL)
+ {
+ // This variable is initialized from something that is
+ // not in its init or preinit. This variable needs to
+ // participate in dependency analysis sorting, in case
+ // some other variable depends on this one.
+ Btype* btype = no->var_value()->type()->get_backend(this);
+ Bexpression* zero = this->backend()->zero_expression(btype);
+ Bstatement* zero_stmt =
+ this->backend()->expression_statement(zero);
+ var_inits.push_back(Var_init(no, zero_stmt));
+ }
+
+ if (!is_sink && var->type()->has_pointer())
+ var_gc.push_back(no);
+ }
+ }
+
+ // Register global variables with the garbage collector.
+ this->register_gc_vars(var_gc, init_stmts);
+
+ // Simple variable initializations, after all variables are
+ // registered.
+ init_stmts.push_back(this->backend()->statement_list(var_init_stmts));
+
+ // Complete variable initializations, first sorting them into a
+ // workable order.
+ if (!var_inits.empty())
+ {
+ sort_var_inits(this, &var_inits);
+ for (Var_inits::const_iterator p = var_inits.begin();
+ p != var_inits.end();
+ ++p)
+ init_stmts.push_back(p->init());
+ }
+
+ // After all the variables are initialized, call the init
+ // functions if there are any. Init functions take no arguments, so
+ // we pass in EMPTY_ARGS to call them.
+ std::vector<Bexpression*> empty_args;
+ for (std::vector<Named_object*>::const_iterator p =
+ this->init_functions_.begin();
+ p != this->init_functions_.end();
+ ++p)
+ {
+ Location func_loc = (*p)->location();
+ Function* func = (*p)->func_value();
+ Bfunction* initfn = func->get_or_make_decl(this, *p);
+ Bexpression* func_code =
+ this->backend()->function_code_expression(initfn, func_loc);
+ Bexpression* call = this->backend()->call_expression(func_code,
+ empty_args,
+ func_loc);
+ init_stmts.push_back(this->backend()->expression_statement(call));
+ }
+
+ // Set up a magic function to do all the initialization actions.
+ // This will be called if this package is imported.
+ Bstatement* init_fncode = this->backend()->statement_list(init_stmts);
+ if (this->need_init_fn_ || this->is_main_package())
+ {
+ init_fndecl =
+ this->create_initialization_function(init_fndecl, init_fncode);
+ if (init_fndecl != NULL)
+ func_decls.push_back(init_fndecl->func_value()->get_decl());
+ }
+
+ // We should not have seen any new bindings created during the conversion.
+ go_assert(count_definitions == this->current_bindings()->size_definitions());
+
+ // Define all globally declared values.
+ if (!saw_errors())
+ this->backend()->write_global_definitions(type_decls, const_decls,
+ func_decls, var_decls);
+}
+
// Return the current block.
Block*
@@ -4182,6 +4855,15 @@ Function::get_or_make_decl(Gogo* gogo, Named_object* no)
return this->fndecl_;
}
+// Return the function's decl after it has been built.
+
+Bfunction*
+Function::get_decl() const
+{
+ go_assert(this->fndecl_ != NULL);
+ return this->fndecl_;
+}
+
// Build the backend representation for the function code.
void
@@ -5266,8 +5948,7 @@ Variable::get_init_block(Gogo* gogo, Named_object* function,
{
Location loc = this->location();
Expression* val_expr =
- Expression::convert_for_assignment(gogo, this->type(),
- this->init_, this->location());
+ Expression::make_cast(this->type(), this->init_, loc);
Bexpression* val = tree_to_expr(val_expr->get_tree(&context));
Bexpression* var_ref = gogo->backend()->var_expression(var_decl, loc);
decl_init = gogo->backend()->assignment_statement(var_ref, val, loc);
@@ -5353,8 +6034,7 @@ Variable::get_backend_variable(Gogo* gogo, Named_object* function,
}
else
{
- tree fndecl = function->func_value()->get_decl();
- Bfunction* bfunction = tree_to_function(fndecl);
+ Bfunction* bfunction = function->func_value()->get_decl();
bool is_address_taken = (this->is_non_escaping_address_taken_
&& !this->is_in_heap());
if (is_parameter)
@@ -5391,8 +6071,7 @@ Result_variable::get_backend_variable(Gogo* gogo, Named_object* function,
if (this->is_in_heap())
type = Type::make_pointer_type(type);
Btype* btype = type->get_backend(gogo);
- tree fndecl = function->func_value()->get_decl();
- Bfunction* bfunction = tree_to_function(fndecl);
+ Bfunction* bfunction = function->func_value()->get_decl();
std::string n = Gogo::unpack_hidden_name(name);
bool is_address_taken = (this->is_non_escaping_address_taken_
&& !this->is_in_heap());
@@ -5482,6 +6161,33 @@ Named_constant::import_const(Import* imp, std::string* pname, Type** ptype,
imp->require_c_string(";\n");
}
+// Get the backend representation.
+
+Bexpression*
+Named_constant::get_backend(Gogo* gogo, Named_object* const_no)
+{
+ if (this->bconst_ == NULL)
+ {
+ Translate_context subcontext(gogo, NULL, NULL, NULL);
+ Type* type = this->type();
+ Location loc = this->location();
+
+ Expression* const_ref = Expression::make_const_reference(const_no, loc);
+ Bexpression* const_decl =
+ tree_to_expr(const_ref->get_tree(&subcontext));
+ if (type != NULL && type->is_numeric_type())
+ {
+ Btype* btype = type->get_backend(gogo);
+ std::string name = const_no->get_id(gogo);
+ const_decl =
+ gogo->backend()->named_constant_expression(btype, name,
+ const_decl, loc);
+ }
+ this->bconst_ = const_decl;
+ }
+ return this->bconst_;
+}
+
// Add a method.
Named_object*
@@ -5552,8 +6258,7 @@ Unknown_name::set_real_named_object(Named_object* no)
Named_object::Named_object(const std::string& name,
const Package* package,
Classification classification)
- : name_(name), package_(package), classification_(classification),
- tree_(NULL)
+ : name_(name), package_(package), classification_(classification)
{
if (Gogo::is_sink_name(name))
go_assert(classification == NAMED_OBJECT_SINK);
@@ -5928,6 +6633,72 @@ Named_object::get_id(Gogo* gogo)
return decl_name;
}
+// Get the backend representation for this named object.
+
+void
+Named_object::get_backend(Gogo* gogo, std::vector<Bexpression*>& const_decls,
+ std::vector<Btype*>& type_decls,
+ std::vector<Bfunction*>& func_decls)
+{
+ switch (this->classification_)
+ {
+ case NAMED_OBJECT_CONST:
+ if (!Gogo::is_erroneous_name(this->name_))
+ const_decls.push_back(this->u_.const_value->get_backend(gogo, this));
+ break;
+
+ case NAMED_OBJECT_TYPE:
+ {
+ Named_type* named_type = this->u_.type_value;
+ if (!Gogo::is_erroneous_name(this->name_))
+ type_decls.push_back(named_type->get_backend(gogo));
+
+ // We need to produce a type descriptor for every named
+ // type, and for a pointer to every named type, since
+ // other files or packages might refer to them. We need
+ // to do this even for hidden types, because they might
+ // still be returned by some function. Simply calling the
+ // type_descriptor method is enough to create the type
+ // descriptor, even though we don't do anything with it.
+ if (this->package_ == NULL)
+ {
+ named_type->
+ type_descriptor_pointer(gogo, Linemap::predeclared_location());
+ Type* pn = Type::make_pointer_type(named_type);
+ pn->type_descriptor_pointer(gogo, Linemap::predeclared_location());
+ }
+ }
+ break;
+
+ case NAMED_OBJECT_TYPE_DECLARATION:
+ error("reference to undefined type %qs",
+ this->message_name().c_str());
+ return;
+
+ case NAMED_OBJECT_VAR:
+ case NAMED_OBJECT_RESULT_VAR:
+ case NAMED_OBJECT_SINK:
+ go_unreachable();
+
+ case NAMED_OBJECT_FUNC:
+ {
+ Function* func = this->u_.func_value;
+ if (!Gogo::is_erroneous_name(this->name_))
+ func_decls.push_back(func->get_or_make_decl(gogo, this));
+
+ if (func->block() != NULL)
+ func->build(gogo, this);
+ }
+ break;
+
+ case NAMED_OBJECT_ERRONEOUS:
+ break;
+
+ default:
+ go_unreachable();
+ }
+}
+
// Class Bindings.
Bindings::Bindings(Bindings* enclosing)
@@ -6400,8 +7171,7 @@ Label::get_backend_label(Translate_context* context)
if (this->blabel_ == NULL)
{
Function* function = context->function()->func_value();
- tree fndecl = function->get_decl();
- Bfunction* bfunction = tree_to_function(fndecl);
+ Bfunction* bfunction = function->get_decl();
this->blabel_ = context->backend()->label(bfunction, this->name_,
this->location_);
}
@@ -6427,8 +7197,7 @@ Unnamed_label::get_blabel(Translate_context* context)
if (this->blabel_ == NULL)
{
Function* function = context->function()->func_value();
- tree fndecl = function->get_decl();
- Bfunction* bfunction = tree_to_function(fndecl);
+ Bfunction* bfunction = function->get_decl();
this->blabel_ = context->backend()->label(bfunction, "",
this->location_);
}
diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h
index dd43d269f40..0be81b2aafe 100644
--- a/gcc/go/gofrontend/gogo.h
+++ b/gcc/go/gofrontend/gogo.h
@@ -44,6 +44,7 @@ class Backend;
class Export;
class Import;
class Bexpression;
+class Btype;
class Bstatement;
class Bblock;
class Bvariable;
@@ -591,11 +592,6 @@ class Gogo
Expression*
runtime_error(int code, Location);
- // Build a builtin struct with a list of fields.
- static tree
- builtin_struct(tree* ptype, const char* struct_name, tree struct_type,
- int nfields, ...);
-
// Mark a function declaration as a builtin library function.
static void
mark_fndecl_as_builtin_library(tree fndecl);
@@ -650,17 +646,18 @@ class Gogo
Named_object*
initialization_function_decl();
- // Write the magic initialization function.
- void
- write_initialization_function(Named_object* fndecl, tree init_stmt_list);
+ // Create the magic initialization function.
+ Named_object*
+ create_initialization_function(Named_object* fndecl, Bstatement* code_stmt);
// Initialize imported packages.
void
- init_imports(tree*);
+ init_imports(std::vector<Bstatement*>&);
// Register variables with the garbage collector.
void
- register_gc_vars(const std::vector<Named_object*>&, tree*);
+ register_gc_vars(const std::vector<Named_object*>&,
+ std::vector<Bstatement*>&);
// Type used to map import names to packages.
typedef std::map<std::string, Package*> Imports;
@@ -1086,7 +1083,7 @@ class Function
get_or_make_decl(Gogo*, Named_object*);
// Return the function's decl after it has been built.
- tree
+ Bfunction*
get_decl() const;
// Set the function decl to hold a backend representation of the function
@@ -1675,7 +1672,7 @@ class Named_constant
Named_constant(Type* type, Expression* expr, int iota_value,
Location location)
: type_(type), expr_(expr), iota_value_(iota_value), location_(location),
- lowering_(false), is_sink_(false)
+ lowering_(false), is_sink_(false), bconst_(NULL)
{ }
Type*
@@ -1737,6 +1734,10 @@ class Named_constant
static void
import_const(Import*, std::string*, Type**, Expression**);
+ // Get the backend representation of the constant value.
+ Bexpression*
+ get_backend(Gogo*, Named_object*);
+
private:
// The type of the constant.
Type* type_;
@@ -1754,6 +1755,8 @@ class Named_constant
bool lowering_;
// Whether this constant is blank named and needs only type checking.
bool is_sink_;
+ // The backend representation of the constant value.
+ Bexpression* bconst_;
};
// A type declaration.
@@ -2176,9 +2179,10 @@ class Named_object
std::string
get_id(Gogo*);
- // Return a tree representing this object.
- tree
- get_tree(Gogo*, Named_object* function);
+ // Get the backend representation of this object.
+ void
+ get_backend(Gogo*, std::vector<Bexpression*>&, std::vector<Btype*>&,
+ std::vector<Bfunction*>&);
// Define a type declaration.
void
@@ -2219,8 +2223,6 @@ class Named_object
Function_declaration* func_declaration_value;
Package* package_value;
} u_;
- // The DECL tree for this object if we have already converted it.
- tree tree_;
};
// A binding contour. This binds names to objects.
diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc
index 49a864faa44..dabf1a83af6 100644
--- a/gcc/go/gofrontend/statements.cc
+++ b/gcc/go/gofrontend/statements.cc
@@ -434,15 +434,9 @@ Temporary_statement::do_get_backend(Translate_context* context)
{
go_assert(this->bvariable_ == NULL);
- // FIXME: Permitting FUNCTION to be NULL here is a temporary measure
- // until we have a better representation of the init function.
Named_object* function = context->function();
- Bfunction* bfunction;
- if (function == NULL)
- bfunction = NULL;
- else
- bfunction = tree_to_function(function->func_value()->get_decl());
-
+ go_assert(function != NULL);
+ Bfunction* bfunction = function->func_value()->get_decl();
Btype* btype = this->type()->get_backend(context->gogo());
Bexpression* binit;
@@ -2781,8 +2775,6 @@ Return_statement::do_get_backend(Translate_context* context)
Location loc = this->location();
Function* function = context->function()->func_value();
- tree fndecl = function->get_decl();
-
Function::Results* results = function->result_variables();
std::vector<Bexpression*> retvals;
if (results != NULL && !results->empty())
@@ -2797,7 +2789,7 @@ Return_statement::do_get_backend(Translate_context* context)
}
}
- return context->backend()->return_statement(tree_to_function(fndecl),
+ return context->backend()->return_statement(function->get_decl(),
retvals, loc);
}
@@ -3803,8 +3795,10 @@ Constant_switch_statement::do_get_backend(Translate_context* context)
this->clauses_->get_backend(context, break_label, &all_cases,
&all_statements);
+ Bfunction* bfunction = context->function()->func_value()->get_decl();
Bstatement* switch_statement;
- switch_statement = context->backend()->switch_statement(switch_val_expr,
+ switch_statement = context->backend()->switch_statement(bfunction,
+ switch_val_expr,
all_cases,
all_statements,
this->location());
@@ -4980,7 +4974,9 @@ Select_clauses::get_backend(Translate_context* context,
std::vector<Bstatement*> statements;
statements.reserve(2);
- Bstatement* switch_stmt = context->backend()->switch_statement(bcall,
+ Bfunction* bfunction = context->function()->func_value()->get_decl();
+ Bstatement* switch_stmt = context->backend()->switch_statement(bfunction,
+ bcall,
cases,
clauses,
location);
diff --git a/gcc/graphite-scop-detection.c b/gcc/graphite-scop-detection.c
index 821f0846ef2..635e21a8519 100644
--- a/gcc/graphite-scop-detection.c
+++ b/gcc/graphite-scop-detection.c
@@ -474,8 +474,10 @@ scopdet_basic_block_info (basic_block bb, loop_p outermost_loop,
result.exits = false;
/* Mark bbs terminating a SESE region difficult, if they start
- a condition. */
- if (!single_succ_p (bb))
+ a condition or if the block it exits to cannot be split
+ with make_forwarder_block. */
+ if (!single_succ_p (bb)
+ || bb_has_abnormal_pred (single_succ (bb)))
result.difficult = true;
else
result.exit = single_succ (bb);
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 2d66e5cab6a..5d16b4d0f94 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -1299,7 +1299,7 @@ recompute_todo_spec (rtx next, bool for_backtrack)
{
HARD_REG_SET t;
- find_all_hard_reg_sets (prev, &t);
+ find_all_hard_reg_sets (prev, &t, true);
if (TEST_HARD_REG_BIT (t, regno))
return HARD_DEP;
if (prev == pro)
@@ -3082,7 +3082,7 @@ check_clobbered_conditions (rtx insn)
if ((current_sched_info->flags & DO_PREDICATION) == 0)
return;
- find_all_hard_reg_sets (insn, &t);
+ find_all_hard_reg_sets (insn, &t, true);
restart:
for (i = 0; i < ready.n_ready; i++)
diff --git a/gcc/omp-low.c b/gcc/omp-low.c
index 5411e00a3c4..a0f024a76ef 100644
--- a/gcc/omp-low.c
+++ b/gcc/omp-low.c
@@ -1730,6 +1730,9 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_REDUCTION
&& OMP_CLAUSE_REDUCTION_PLACEHOLDER (c))
scan_array_reductions = true;
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
+ scan_array_reductions = true;
break;
case OMP_CLAUSE_SHARED:
@@ -1816,6 +1819,9 @@ scan_sharing_clauses (tree clauses, omp_context *ctx)
else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LASTPRIVATE
&& OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c))
scan_omp (&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c), ctx);
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
+ scan_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
}
/* Create a new name for omp child function. Returns an identifier. */
@@ -3801,6 +3807,14 @@ lower_lastprivate_clauses (tree clauses, tree predicate, gimple_seq *stmt_list,
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c));
OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (c) = NULL;
}
+ else if (OMP_CLAUSE_CODE (c) == OMP_CLAUSE_LINEAR
+ && OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c))
+ {
+ lower_omp (&OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c), ctx);
+ gimple_seq_add_seq (stmt_list,
+ OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c));
+ OMP_CLAUSE_LINEAR_GIMPLE_SEQ (c) = NULL;
+ }
x = build_outer_var_ref (var, ctx);
if (is_reference (var))
diff --git a/gcc/passes.c b/gcc/passes.c
index 2be7856f29b..c0a76d62d21 100644
--- a/gcc/passes.c
+++ b/gcc/passes.c
@@ -132,7 +132,7 @@ opt_pass::opt_pass (const pass_data &data, context *ctxt)
void
pass_manager::execute_early_local_passes ()
{
- execute_pass_list (pass_early_local_passes_1->sub);
+ execute_pass_list (cfun, pass_early_local_passes_1->sub);
}
unsigned int
@@ -1498,27 +1498,17 @@ pass_manager::pass_manager (context *ctxt)
call CALLBACK on the current function. */
static void
-do_per_function (void (*callback) (void *data), void *data)
+do_per_function (void (*callback) (function *, void *data), void *data)
{
if (current_function_decl)
- callback (data);
+ callback (cfun, data);
else
{
struct cgraph_node *node;
FOR_EACH_DEFINED_FUNCTION (node)
if (node->analyzed && gimple_has_body_p (node->decl)
&& (!node->clone_of || node->decl != node->clone_of->decl))
- {
- push_cfun (DECL_STRUCT_FUNCTION (node->decl));
- callback (data);
- if (!flag_wpa)
- {
- free_dominance_info (CDI_DOMINATORS);
- free_dominance_info (CDI_POST_DOMINATORS);
- }
- pop_cfun ();
- ggc_collect ();
- }
+ callback (DECL_STRUCT_FUNCTION (node->decl), data);
}
}
@@ -1533,12 +1523,12 @@ static GTY ((length ("nnodes"))) cgraph_node_ptr *order;
call CALLBACK on the current function.
This function is global so that plugins can use it. */
void
-do_per_function_toporder (void (*callback) (void *data), void *data)
+do_per_function_toporder (void (*callback) (function *, void *data), void *data)
{
int i;
if (current_function_decl)
- callback (data);
+ callback (cfun, data);
else
{
gcc_assert (!order);
@@ -1554,15 +1544,7 @@ do_per_function_toporder (void (*callback) (void *data), void *data)
order[i] = NULL;
node->process = 0;
if (cgraph_function_with_gimple_body_p (node))
- {
- cgraph_get_body (node);
- push_cfun (DECL_STRUCT_FUNCTION (node->decl));
- callback (data);
- free_dominance_info (CDI_DOMINATORS);
- free_dominance_info (CDI_POST_DOMINATORS);
- pop_cfun ();
- ggc_collect ();
- }
+ callback (DECL_STRUCT_FUNCTION (node->decl), data);
}
}
ggc_free (order);
@@ -1573,14 +1555,16 @@ do_per_function_toporder (void (*callback) (void *data), void *data)
/* Helper function to perform function body dump. */
static void
-execute_function_dump (void *data)
+execute_function_dump (function *fn, void *data)
{
opt_pass *pass = (opt_pass *)data;
- if (dump_file && current_function_decl)
+ if (dump_file)
{
- if (cfun->curr_properties & PROP_trees)
- dump_function_to_file (current_function_decl, dump_file, dump_flags);
+ push_cfun (fn);
+
+ if (fn->curr_properties & PROP_trees)
+ dump_function_to_file (fn->decl, dump_file, dump_flags);
else
print_rtl_with_bb (dump_file, get_insns (), dump_flags);
@@ -1588,7 +1572,7 @@ execute_function_dump (void *data)
close the file before aborting. */
fflush (dump_file);
- if ((cfun->curr_properties & PROP_cfg)
+ if ((fn->curr_properties & PROP_cfg)
&& (dump_flags & TDF_GRAPH))
{
if (!pass->graph_dump_initialized)
@@ -1596,8 +1580,10 @@ execute_function_dump (void *data)
clean_graph_dump_file (dump_file_name);
pass->graph_dump_initialized = true;
}
- print_graph_cfg (dump_file_name, cfun);
+ print_graph_cfg (dump_file_name, fn);
}
+
+ pop_cfun ();
}
}
@@ -1728,13 +1714,15 @@ pass_manager::dump_profile_report () const
/* Perform all TODO actions that ought to be done on each function. */
static void
-execute_function_todo (void *data)
+execute_function_todo (function *fn, void *data)
{
unsigned int flags = (size_t)data;
- flags &= ~cfun->last_verified;
+ flags &= ~fn->last_verified;
if (!flags)
return;
+ push_cfun (fn);
+
/* Always cleanup the CFG before trying to update SSA. */
if (flags & TODO_cleanup_cfg)
{
@@ -1774,7 +1762,10 @@ execute_function_todo (void *data)
/* If we've seen errors do not bother running any verifiers. */
if (seen_error ())
- return;
+ {
+ pop_cfun ();
+ return;
+ }
#if defined ENABLE_CHECKING
if (flags & TODO_verify_ssa
@@ -1793,7 +1784,9 @@ execute_function_todo (void *data)
verify_rtl_sharing ();
#endif
- cfun->last_verified = flags & TODO_verify_all;
+ fn->last_verified = flags & TODO_verify_all;
+
+ pop_cfun ();
}
/* Perform all TODO actions. */
@@ -1855,9 +1848,9 @@ verify_interpass_invariants (void)
/* Clear the last verified flag. */
static void
-clear_last_verified (void *data ATTRIBUTE_UNUSED)
+clear_last_verified (function *fn, void *data ATTRIBUTE_UNUSED)
{
- cfun->last_verified = 0;
+ fn->last_verified = 0;
}
/* Helper function. Verify that the properties has been turn into the
@@ -1865,10 +1858,10 @@ clear_last_verified (void *data ATTRIBUTE_UNUSED)
#ifdef ENABLE_CHECKING
static void
-verify_curr_properties (void *data)
+verify_curr_properties (function *fn, void *data)
{
unsigned int props = (size_t)data;
- gcc_assert ((cfun->curr_properties & props) == props);
+ gcc_assert ((fn->curr_properties & props) == props);
}
#endif
@@ -1927,11 +1920,11 @@ pass_fini_dump_file (opt_pass *pass)
properties. */
static void
-update_properties_after_pass (void *data)
+update_properties_after_pass (function *fn, void *data)
{
opt_pass *pass = (opt_pass *) data;
- cfun->curr_properties = (cfun->curr_properties | pass->properties_provided)
- & ~pass->properties_destroyed;
+ fn->curr_properties = (fn->curr_properties | pass->properties_provided)
+ & ~pass->properties_destroyed;
}
/* Execute summary generation for all of the passes in IPA_PASS. */
@@ -2039,20 +2032,6 @@ execute_all_ipa_transforms (void)
}
}
-/* Callback for do_per_function to apply all IPA transforms. */
-
-static void
-apply_ipa_transforms (void *data)
-{
- struct cgraph_node *node = cgraph_get_node (current_function_decl);
- if (!node->global.inlined_to && node->ipa_transforms_to_apply.exists ())
- {
- *(bool *)data = true;
- execute_all_ipa_transforms ();
- rebuild_cgraph_edges ();
- }
-}
-
/* Check if PASS is explicitly disabled or enabled and return
the gate status. FUNC is the function to be processed, and
GATE_STATUS is the gate status determined by pass manager by
@@ -2124,8 +2103,26 @@ execute_one_pass (opt_pass *pass)
Apply all trnasforms first. */
if (pass->type == SIMPLE_IPA_PASS)
{
+ struct cgraph_node *node;
bool applied = false;
- do_per_function (apply_ipa_transforms, (void *)&applied);
+ FOR_EACH_DEFINED_FUNCTION (node)
+ if (node->analyzed
+ && cgraph_function_with_gimple_body_p (node)
+ && (!node->clone_of || node->decl != node->clone_of->decl))
+ {
+ if (!node->global.inlined_to
+ && node->ipa_transforms_to_apply.exists ())
+ {
+ cgraph_get_body (node);
+ push_cfun (DECL_STRUCT_FUNCTION (node->decl));
+ execute_all_ipa_transforms ();
+ rebuild_cgraph_edges ();
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
+ pop_cfun ();
+ applied = true;
+ }
+ }
if (applied)
symtab_remove_unreachable_nodes (true, dump_file);
/* Restore current_pass. */
@@ -2202,20 +2199,33 @@ execute_one_pass (opt_pass *pass)
return true;
}
-void
-execute_pass_list (opt_pass *pass)
+static void
+execute_pass_list_1 (opt_pass *pass)
{
do
{
gcc_assert (pass->type == GIMPLE_PASS
|| pass->type == RTL_PASS);
if (execute_one_pass (pass) && pass->sub)
- execute_pass_list (pass->sub);
+ execute_pass_list_1 (pass->sub);
pass = pass->next;
}
while (pass);
}
+void
+execute_pass_list (function *fn, opt_pass *pass)
+{
+ push_cfun (fn);
+ execute_pass_list_1 (pass);
+ if (fn->cfg)
+ {
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
+ }
+ pop_cfun ();
+}
+
/* Write out all LTO data. */
static void
write_lto (void)
@@ -2539,7 +2549,8 @@ execute_ipa_pass_list (opt_pass *pass)
if (pass->sub->type == GIMPLE_PASS)
{
invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_START, NULL);
- do_per_function_toporder ((void (*)(void *))execute_pass_list,
+ do_per_function_toporder ((void (*)(function *, void *))
+ execute_pass_list,
pass->sub);
invoke_plugin_callbacks (PLUGIN_EARLY_GIMPLE_PASSES_END, NULL);
}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index cccb884ae88..f62c334351d 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2231,7 +2231,7 @@ extern const_rtx set_of (const_rtx, const_rtx);
extern void record_hard_reg_sets (rtx, const_rtx, void *);
extern void record_hard_reg_uses (rtx *, void *);
#ifdef HARD_CONST
-extern void find_all_hard_reg_sets (const_rtx, HARD_REG_SET *);
+extern void find_all_hard_reg_sets (const_rtx, HARD_REG_SET *, bool);
#endif
extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *);
extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index 98c652894fb..82cfc1bf70b 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -1046,14 +1046,20 @@ record_hard_reg_sets (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data)
/* Examine INSN, and compute the set of hard registers written by it.
Store it in *PSET. Should only be called after reload. */
void
-find_all_hard_reg_sets (const_rtx insn, HARD_REG_SET *pset)
+find_all_hard_reg_sets (const_rtx insn, HARD_REG_SET *pset, bool implicit)
{
rtx link;
CLEAR_HARD_REG_SET (*pset);
note_stores (PATTERN (insn), record_hard_reg_sets, pset);
if (CALL_P (insn))
- IOR_HARD_REG_SET (*pset, call_used_reg_set);
+ {
+ if (implicit)
+ IOR_HARD_REG_SET (*pset, call_used_reg_set);
+
+ for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
+ record_hard_reg_sets (XEXP (link, 0), NULL, pset);
+ }
for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
if (REG_NOTE_KIND (link) == REG_INC)
record_hard_reg_sets (XEXP (link, 0), NULL, pset);
diff --git a/gcc/system.h b/gcc/system.h
index 8b5089a28d7..b20b5cfde1d 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -1035,7 +1035,7 @@ helper_const_non_const_cast (const char *p)
#endif
#endif
-#ifdef ENABLE_VALGRIND_CHECKING
+#ifdef ENABLE_VALGRIND_ANNOTATIONS
# ifdef HAVE_VALGRIND_MEMCHECK_H
# include <valgrind/memcheck.h>
# elif defined HAVE_MEMCHECK_H
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 70a0f89d592..261bb98a3a4 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,10 +1,156 @@
-i2014-04-24 Alan Lawrence <alan.lawrence@arm.com>
+2014-04-28 Richard Biener <rguenther@suse.de>
+
+ * gcc.dg/tree-ssa/vrp91.c: New testcase.
+ * gcc.dg/Wstrict-overflow-14.c: XFAIL.
+ * gcc.dg/Wstrict-overflow-15.c: Likewise.
+ * gcc.dg/Wstrict-overflow-18.c: Remove XFAIL.
+
+2014-04-28 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/60979
+ * gcc.dg/graphite/pr60979.c: New testcase.
+
+2014-04-28 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
+
+ PR c/60983
+ * gcc.dg/pr60114.c: Use signed chars.
+
+2014-04-28 Paolo Carlini <paolo.carlini@oracle.com>
+
+ PR c++/59120
+ * g++.dg/cpp0x/alias-decl-43.C: New.
+
+2014-03-27 Thomas Koenig <tkoenig@gcc.gnu.org>
+
+ PR fortran/59604
+ PR fortran/58003
+ * gfortran.dg/no_range_check_3.f90: New test.
+
+2014-04-26 Jerry DeLisle <jvdelisle@gcc.gnu>
+
+ PR libfortran/52539
+ * gfortran.dg/namelist_utf8.f90: New test.
+
+2014-04-26 Uros Bizjak <ubizjak@gmail.com>
+
+ * gcc.dg/tree-ssa/alias-30.c (dg-options): Dump only fre1 details.
+ * gcc.dg/vect/pr60505.c: Cleanup vect tree dump.
+ * g++.dg/ipa/devirt-27.C (dg-options): Remove -fdump-ipa-devirt.
+
+2014-04-25 Cary Coutant <ccoutant@google.com>
+
+ PR debug/60929
+ * g++.dg/debug/dwarf2/dwarf4-nested.C: New test case.
+ * g++.dg/debug/dwarf2/dwarf4-typedef.C: Add
+ -fdebug-types-section flag.
+
+2014-04-25 Jiong Wang <jiong.wang@arm.com>
+
+ * gcc.target/arm/tail-long-call.c: New test.
+
+2014-04-25 Bill Schmidt <wschmidt@linux.vnet.ibm.com>
+
+ PR tree-optimization/60930
+ * gcc.dg/torture/pr60930.c: New test.
+
+2014-04-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/60960
+ * gcc.c-torture/execute/pr60960.c: New test.
+
+2014-04-25 Marek Polacek <polacek@redhat.com>
+
+ * gcc.dg/pr18079-2.c: Fix quoting in dg-warning.
+
+2014-04-25 Marek Polacek <polacek@redhat.com>
+
+ PR c/18079
+ * gcc.dg/pr18079.c: New test.
+ * gcc.dg/pr18079-2.c: New test.
+
+2014-04-25 Uros Bizjak <ubizjak@gmail.com>
+
+ * c-c++-common/gomp/pr60823-2.c: Require effective target
+ vect_simd_clones.
+
+2014-04-25 Marek Polacek <polacek@redhat.com>
+
+ PR c/60114
+ * gcc.dg/pr60114.c: New test.
+
+2014-04-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc.c-torture/execute/20140425-1.c: New test.
+
+2014-04-25 Marek Polacek <polacek@redhat.com>
+
+ PR c/60156
+ * c-c++-common/pr60156.c: New test.
+
+2014-04-25 Richard Biener <rguenther@suse.de>
+
+ PR ipa/60912
+ * g++.dg/opt/pr60912.C: New testcase.
+
+2014-04-25 Richard Biener <rguenther@suse.de>
+
+ PR ipa/60911
+ * gcc.dg/lto/pr60911_0.c: New testcase.
+
+2014-04-24 Cong Hou <congh@google.com>
+
+ PR tree-optimization/60896
+ * g++.dg/vect/pr60896.cc: New test.
+
+2014-04-24 Michael Meissner <meissner@linux.vnet.ibm.com>
+
+ * gcc.target/powerpc/pack01.c: New test to test the new pack and
+ unpack builtin functionss for 128-bit types.
+ * gcc.target/powerpc/pack02.c: Likewise.
+ * gcc.target/powerpc/pack03.c: Likewise.
+ * gcc.target/powerpc/extend-divide-1.c: New test to test extended
+ divide builtin functionss.
+ * gcc.target/powerpc/extend-divide-2.c: Likewise.
+ * gcc.target/powerpc/bcd-1.c: New test for the new BCD builtin
+ functions.
+ * gcc.target/powerpc/bcd-2.c: Likewise.
+ * gcc.target/powerpc/bcd-3.c: Likewise.
+ * gcc.target/powerpc/dfp-builtin-1.c: New test for the new DFP
+ builtin functionss.
+ * gcc.target/powerpc/dfp-builtin-2.c: Likewise.
+
+2014-04-24 Vishnu K S <Vishnu.k_s@atmel.com>
+
+ * gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c: Skip test if
+ keeps_null_pointer_checks.
+ * gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c: Ditto.
+ * gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c: Ditto.
+ * gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c: Ditto.
+ * gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c: Ditto.
+
+2014-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ * c-c++-common/gomp/atomic-16.c: Remove all dg-error directives.
+ Replace load with read and store with write.
+
+2014-04-24 Jeff Law <law@redhat.com>
+
+ PR target/60822
+ * gcc.c-torture/pr60822.c: New test.
+ * gcc.c-torture/pr60822.x: New test.
+
+2014-04-24 Dinar Temirbulatov <dtemirbulatov@gmail.com>
+
+ PR c++/57958
+ * testsuite/g++.dg/cpp0x/pr57958.C: New test.
+
+2014-04-24 Alan Lawrence <alan.lawrence@arm.com>
* lib/target-supports.exp (check_effective_target_vect_perm): Return
true for aarch64_be.
2014-04-24 Radovan Obradovic <robradovic@mips.com>
- Tom de Vries <tom@codesourcery.com>
+ Tom de Vries <tom@codesourcery.com>
* gcc.dg/fuse-caller-save.c: New test.
@@ -36,7 +182,7 @@ i2014-04-24 Alan Lawrence <alan.lawrence@arm.com>
2014-04-23 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
- * gcc.target/aarch64/rev16_1.c: New test.
+ * gcc.target/aarch64/rev16_1.c: New test.
2014-04-23 Richard Biener <rguenther@suse.de>
@@ -241,7 +387,7 @@ i2014-04-24 Alan Lawrence <alan.lawrence@arm.com>
PR tree-optimization/60836
* g++.dg/vect/pr60836.cc: New testcase.
-2014-04-17 Richard Biener <rguenther@suse.de>
+2014-04-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/60841
* gcc.dg/vect/pr60841.c: New testcase.
@@ -1924,8 +2070,7 @@ i2014-04-24 Alan Lawrence <alan.lawrence@arm.com>
2014-02-19 Paul Pluzhnikov <ppluzhnikov@google.com>
- * gcc.dg/vect/no-vfa-vect-depend-2.c (main1): Fix buffer
- overflow.
+ * gcc.dg/vect/no-vfa-vect-depend-2.c (main1): Fix buffer overflow.
2014-02-19 Jakub Jelinek <jakub@redhat.com>
@@ -2234,8 +2379,7 @@ i2014-04-24 Alan Lawrence <alan.lawrence@arm.com>
2014-02-10 Jakub Jelinek <jakub@redhat.com>
- * gcc.dg/vect/pr59984.c: Require effective target
- vect_simd_clones.
+ * gcc.dg/vect/pr59984.c: Require effective target vect_simd_clones.
2014-02-09 Paul Thomas <pault@gcc.gnu.org>
diff --git a/gcc/testsuite/c-c++-common/gomp/atomic-16.c b/gcc/testsuite/c-c++-common/gomp/atomic-16.c
index 87fbaa23317..9332396eaa5 100644
--- a/gcc/testsuite/c-c++-common/gomp/atomic-16.c
+++ b/gcc/testsuite/c-c++-common/gomp/atomic-16.c
@@ -7,28 +7,28 @@ void
foo ()
{
int v;
- #pragma omp atomic seq_cst load /* { dg-error "expected end of line" } */
- v = x; /* { dg-error "invalid form" } */
- #pragma omp atomic seq_cst, load /* { dg-error "expected end of line" } */
- v = x; /* { dg-error "invalid form" } */
- #pragma omp atomic seq_cst store /* { dg-error "expected end of line" } */
- x = v; /* { dg-error "invalid form" } */
- #pragma omp atomic seq_cst ,store /* { dg-error "expected end of line" } */
- x = v; /* { dg-error "invalid form" } */
- #pragma omp atomic seq_cst update /* { dg-error "expected end of line" } */
+ #pragma omp atomic seq_cst read
+ v = x;
+ #pragma omp atomic seq_cst, read
+ v = x;
+ #pragma omp atomic seq_cst write
+ x = v;
+ #pragma omp atomic seq_cst ,write
+ x = v;
+ #pragma omp atomic seq_cst update
x += v;
- #pragma omp atomic seq_cst , update /* { dg-error "expected end of line" } */
+ #pragma omp atomic seq_cst , update
x += v;
- #pragma omp atomic seq_cst capture /* { dg-error "expected end of line" } */
- v = x += 2; /* { dg-error "invalid form" } */
- #pragma omp atomic seq_cst, capture /* { dg-error "expected end of line" } */
- v = x += 2; /* { dg-error "invalid form" } */
- #pragma omp atomic load , seq_cst /* { dg-error "expected end of line" } */
- v = x; /* { dg-error "invalid form" } */
- #pragma omp atomic store ,seq_cst /* { dg-error "expected end of line" } */
- x = v; /* { dg-error "invalid form" } */
- #pragma omp atomic update, seq_cst /* { dg-error "expected end of line" } */
+ #pragma omp atomic seq_cst capture
+ v = x += 2;
+ #pragma omp atomic seq_cst, capture
+ v = x += 2;
+ #pragma omp atomic read , seq_cst
+ v = x;
+ #pragma omp atomic write ,seq_cst
+ x = v;
+ #pragma omp atomic update, seq_cst
x += v;
- #pragma omp atomic capture, seq_cst /* { dg-error "expected end of line" } */
+ #pragma omp atomic capture, seq_cst
v = x += 2;
}
diff --git a/gcc/testsuite/c-c++-common/gomp/pr60823-2.c b/gcc/testsuite/c-c++-common/gomp/pr60823-2.c
index e0bf570ddca..4c87620076a 100644
--- a/gcc/testsuite/c-c++-common/gomp/pr60823-2.c
+++ b/gcc/testsuite/c-c++-common/gomp/pr60823-2.c
@@ -1,5 +1,6 @@
/* PR tree-optimization/60823 */
/* { dg-do run } */
+/* { dg-require-effective-target vect_simd_clones } */
/* { dg-options "-O2 -fopenmp-simd" } */
#pragma omp declare simd simdlen(4) notinbranch
diff --git a/gcc/testsuite/c-c++-common/pr60156.c b/gcc/testsuite/c-c++-common/pr60156.c
new file mode 100644
index 00000000000..1e8204c99c7
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/pr60156.c
@@ -0,0 +1,9 @@
+/* PR c/60156 */
+/* { dg-do compile } */
+/* { dg-options "-Wpedantic" } */
+
+int
+main (int argc, char *argv[], ...) /* { dg-warning "declared as variadic function" } */
+{
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-43.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-43.C
new file mode 100644
index 00000000000..02eb33643ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-43.C
@@ -0,0 +1,4 @@
+// PR c++/59120
+// { dg-do compile { target c++11 } }
+
+template<typename T> using X = int T::T*; // { dg-error "expected" }
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C b/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C
new file mode 100644
index 00000000000..160694c3c9f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-nested.C
@@ -0,0 +1,55 @@
+// { dg-do compile }
+// { dg-options "--std=c++11 -dA -gdwarf-4 -fdebug-types-section -fno-merge-debug-strings" }
+
+// Check that -fdebug-types-sections does not copy a full referenced type
+// into a type unit.
+
+// Checks that at least one type unit is generated.
+//
+// { dg-final { scan-assembler "DIE \\(\[^\n\]*\\) DW_TAG_type_unit" } }
+//
+// Check that func is declared exactly once in the debug info (in the
+// compile unit).
+//
+// { dg-final { scan-assembler-times "\\.ascii \"func\\\\0\"\[^\n\]*DW_AT_name" 1 } }
+//
+// Check to make sure that no type unit contains a DIE with DW_AT_low_pc
+// or DW_AT_ranges. These patterns assume that the compile unit is always
+// emitted after all type units.
+//
+// { dg-final { scan-assembler-not "\\.quad\[^\n\]*DW_AT_low_pc.*DIE \\(\[^\n\]*\\) DW_TAG_compile_unit" } }
+// { dg-final { scan-assembler-not "\\.quad\[^\n\]*DW_AT_ranges.*DIE \\(\[^\n\]*\\) DW_TAG_compile_unit" } }
+
+struct A {
+ A();
+ virtual ~A();
+ virtual void foo();
+ private:
+ int data;
+};
+
+struct B {
+ B();
+ virtual ~B();
+};
+
+extern B* table[];
+
+struct D {
+ template <typename T>
+ T* get(int i)
+ {
+ B*& cell = table[i];
+ if (cell == 0)
+ cell = new T();
+ return static_cast<T*>(cell);
+ }
+};
+
+void func(D* d)
+{
+ struct C : B {
+ A a;
+ };
+ d->get<C>(0)->a.foo();
+}
diff --git a/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C b/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C
index c5520fa72b0..89a6bb44e10 100644
--- a/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C
+++ b/gcc/testsuite/g++.dg/debug/dwarf2/dwarf4-typedef.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-gdwarf-4" } */
+/* { dg-options "-gdwarf-4 -fdebug-types-section" } */
/* Regression test for an ICE in output_die when using -gdwarf-4. */
diff --git a/gcc/testsuite/g++.dg/ipa/devirt-27.C b/gcc/testsuite/g++.dg/ipa/devirt-27.C
index 1dcf76cc3c1..749f40af151 100644
--- a/gcc/testsuite/g++.dg/ipa/devirt-27.C
+++ b/gcc/testsuite/g++.dg/ipa/devirt-27.C
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O3 -fdump-ipa-devirt -fdump-tree-optimized" } */
+/* { dg-options "-O3 -fdump-tree-optimized" } */
struct A
{
int a;
diff --git a/gcc/testsuite/g++.dg/opt/pr60912.C b/gcc/testsuite/g++.dg/opt/pr60912.C
new file mode 100644
index 00000000000..ad51ba72570
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr60912.C
@@ -0,0 +1,18 @@
+// { dg-do run }
+// { dg-options "-O -fno-inline -fipa-pta" }
+
+struct IFoo
+{
+ virtual void Foo () = 0;
+};
+
+struct Bar:IFoo
+{
+ void Foo () {}
+};
+
+int main ()
+{
+ (new Bar ())->Foo ();
+ return 0;
+}
diff --git a/gcc/testsuite/g++.dg/vect/pr60896.cc b/gcc/testsuite/g++.dg/vect/pr60896.cc
new file mode 100644
index 00000000000..c6ce68b82a2
--- /dev/null
+++ b/gcc/testsuite/g++.dg/vect/pr60896.cc
@@ -0,0 +1,44 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+struct A
+{
+ int m_fn1 ();
+ short *m_fn2 ();
+};
+
+struct B
+{
+ void *fC;
+};
+
+int a, b;
+unsigned char i;
+void fn1 (unsigned char *p1, A &p2)
+{
+ int c = p2.m_fn1 ();
+ for (int d = 0; c; d++)
+ {
+ short *e = p2.m_fn2 ();
+ unsigned char *f = &p1[0];
+ for (int g = 0; g < a; g++)
+ {
+ int h = e[0];
+ b += h * f[g];
+ }
+ }
+}
+
+void fn2 (A &p1, A &p2, B &p3)
+{
+ int j = p2.m_fn1 ();
+ for (int k = 0; j; k++)
+ if (0)
+ ;
+ else
+ fn1 (&i, p1);
+ if (p3.fC)
+ ;
+ else
+ ;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/20140425-1.c b/gcc/testsuite/gcc.c-torture/execute/20140425-1.c
new file mode 100644
index 00000000000..c447ef95b6c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/20140425-1.c
@@ -0,0 +1,23 @@
+/* PR target/60941 */
+/* Reported by Martin Husemann <martin@netbsd.org> */
+
+extern void abort (void);
+
+static void __attribute__((noinline))
+set (unsigned long *l)
+{
+ *l = 31;
+}
+
+int main (void)
+{
+ unsigned long l;
+ int i;
+
+ set (&l);
+ i = (int) l;
+ l = (unsigned long)(2U << i);
+ if (l != 0)
+ abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr60822.c b/gcc/testsuite/gcc.c-torture/execute/pr60822.c
new file mode 100644
index 00000000000..d2253310e69
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr60822.c
@@ -0,0 +1,24 @@
+struct X {
+ char fill0[800000];
+ int a;
+ char fill1[900000];
+ int b;
+};
+
+int __attribute__((noinline,noclone))
+Avg(struct X *p, int s)
+{
+ return (s * (long long)(p->a + p->b)) >> 17;
+}
+
+struct X x;
+
+int main()
+{
+ x.a = 1 << 17;
+ x.b = 2 << 17;
+ if (Avg(&x, 1) != 3)
+ __builtin_abort();
+ return 0;
+}
+
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr60822.x b/gcc/testsuite/gcc.c-torture/execute/pr60822.x
new file mode 100644
index 00000000000..4efed4c325f
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr60822.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/pr60960.c b/gcc/testsuite/gcc.c-torture/execute/pr60960.c
new file mode 100644
index 00000000000..b4f08d4c543
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr60960.c
@@ -0,0 +1,38 @@
+/* PR tree-optimization/60960 */
+
+typedef unsigned char v4qi __attribute__ ((vector_size (4)));
+
+__attribute__((noinline, noclone)) v4qi
+f1 (v4qi v)
+{
+ return v / 2;
+}
+
+__attribute__((noinline, noclone)) v4qi
+f2 (v4qi v)
+{
+ return v / (v4qi) { 2, 2, 2, 2 };
+}
+
+__attribute__((noinline, noclone)) v4qi
+f3 (v4qi x, v4qi y)
+{
+ return x / y;
+}
+
+int
+main ()
+{
+ v4qi x = { 5, 5, 5, 5 };
+ v4qi y = { 2, 2, 2, 2 };
+ v4qi z = f1 (x);
+ if (__builtin_memcmp (&y, &z, sizeof (y)) != 0)
+ __builtin_abort ();
+ z = f2 (x);
+ if (__builtin_memcmp (&y, &z, sizeof (y)) != 0)
+ __builtin_abort ();
+ z = f3 (x, y);
+ if (__builtin_memcmp (&y, &z, sizeof (y)) != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-14.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-14.c
index 6f3c5a24fd1..dda07ea733b 100644
--- a/gcc/testsuite/gcc.dg/Wstrict-overflow-14.c
+++ b/gcc/testsuite/gcc.dg/Wstrict-overflow-14.c
@@ -10,6 +10,6 @@ foo (int j)
int sum = 0;
for (i = 1; i < j; i += i)
- sum += i / 16; /* { dg-warning "assuming signed overflow does not occur" "" } */
+ sum += i / 16; /* { dg-warning "assuming signed overflow does not occur" "" { xfail *-*-* } } */
return sum;
}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-15.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-15.c
index d1627d2f47b..c9e275c0bd6 100644
--- a/gcc/testsuite/gcc.dg/Wstrict-overflow-15.c
+++ b/gcc/testsuite/gcc.dg/Wstrict-overflow-15.c
@@ -10,6 +10,6 @@ foo (int j)
int sum = 0;
for (i = 1; i < j; i += i)
- sum += __builtin_abs (i); /* { dg-warning "assuming signed overflow does not occur" "" } */
+ sum += __builtin_abs (i); /* { dg-warning "assuming signed overflow does not occur" "" { xfail *-*-* } } */
return sum;
}
diff --git a/gcc/testsuite/gcc.dg/Wstrict-overflow-18.c b/gcc/testsuite/gcc.dg/Wstrict-overflow-18.c
index 2767c44fbf2..7bf111a50ea 100644
--- a/gcc/testsuite/gcc.dg/Wstrict-overflow-18.c
+++ b/gcc/testsuite/gcc.dg/Wstrict-overflow-18.c
@@ -17,7 +17,7 @@ foo (struct c *p)
for (i = 0; i < p->a - p->b; ++i)
{
- if (i > 0) /* { dg-bogus "warning" "" { xfail *-*-* } } */
+ if (i > 0) /* { dg-bogus "warning" "" } */
sum += 2;
bar (p);
}
diff --git a/gcc/testsuite/gcc.dg/graphite/pr60979.c b/gcc/testsuite/gcc.dg/graphite/pr60979.c
new file mode 100644
index 00000000000..0004a51248d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/graphite/pr60979.c
@@ -0,0 +1,37 @@
+/* { dg-options "-O -fgraphite-identity" } */
+
+#include <setjmp.h>
+
+struct x;
+
+typedef struct x **(*a)(struct x *);
+
+struct x {
+ union {
+ struct {
+ union {
+ a *i;
+ } l;
+ int s;
+ } y;
+ } e;
+};
+
+jmp_buf c;
+
+void
+b(struct x *r)
+{
+ int f;
+ static int w = 0;
+ volatile jmp_buf m;
+ f = (*(((struct x *)r)->e.y.l.i[2]((struct x *)r)))->e.y.s;
+ if (w++ != 0)
+ __builtin_memcpy((char *)m, (const char *)c, sizeof(jmp_buf));
+ if (setjmp (c) == 0) {
+ int z;
+ for (z = 0; z < 0; ++z)
+ ;
+ }
+ d((const char *)m);
+}
diff --git a/gcc/testsuite/gcc.dg/lto/pr60911_0.c b/gcc/testsuite/gcc.dg/lto/pr60911_0.c
new file mode 100644
index 00000000000..e4820a20497
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/lto/pr60911_0.c
@@ -0,0 +1,21 @@
+// { dg-lto-do run }
+// { dg-lto-options { { -O2 -flto -fipa-pta } } }
+
+int __attribute__ ((__noinline__)) f (unsigned *p, int *x)
+{
+ int y = *p++ & 0xfff;
+ *x++ = y;
+ *x = *p;
+ return y;
+}
+
+int
+main ()
+{
+ unsigned u[2] = { 0x3aad, 0x5ad1 };
+ int x[2] = { 17689, 23456 };
+
+ if (f (u, x) != 0xaad || x[0] != 0xaad || x[1] != 0x5ad1)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/pr18079-2.c b/gcc/testsuite/gcc.dg/pr18079-2.c
new file mode 100644
index 00000000000..2c83b701e10
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr18079-2.c
@@ -0,0 +1,16 @@
+/* PR c/18079 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+__attribute__ ((always_inline)) void fndecl1 (void);
+__attribute__ ((noinline)) void fndecl1 (void); /* { dg-warning "attribute 'noinline' follows declaration with attribute 'always_inline'" } */
+
+__attribute__ ((noinline)) void fndecl2 (void);
+__attribute__ ((always_inline)) void fndecl2 (void); /* { dg-warning "attribute 'always_inline' follows declaration with attribute 'noinline'" } */
+
+
+__attribute__ ((hot)) void fndecl3 (void);
+__attribute__ ((cold)) void fndecl3 (void); /* { dg-warning "attribute 'cold' follows declaration with attribute 'hot'" } */
+
+__attribute__ ((cold)) void fndecl4 (void);
+__attribute__ ((hot)) void fndecl4 (void); /* { dg-warning "attribute 'hot' follows declaration with attribute 'cold'" } */
diff --git a/gcc/testsuite/gcc.dg/pr18079.c b/gcc/testsuite/gcc.dg/pr18079.c
new file mode 100644
index 00000000000..b84cdebde3f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr18079.c
@@ -0,0 +1,33 @@
+/* PR c/18079 */
+/* { dg-do compile } */
+/* { dg-options "-Wall" } */
+
+__attribute__ ((noinline))
+__attribute__ ((always_inline))
+int
+fn1 (int r)
+{ /* { dg-warning "attribute ignored due to conflict" } */
+ return r & 4;
+}
+
+__attribute__ ((noinline, always_inline))
+int
+fn2 (int r)
+{ /* { dg-warning "attribute ignored due to conflict" } */
+ return r & 4;
+}
+
+__attribute__ ((always_inline))
+__attribute__ ((noinline))
+inline int
+fn3 (int r)
+{ /* { dg-warning "attribute ignored due to conflict" } */
+ return r & 8;
+}
+
+__attribute__ ((always_inline, noinline))
+inline int
+fn4 (int r)
+{ /* { dg-warning "attribute ignored due to conflict" } */
+ return r & 8;
+}
diff --git a/gcc/testsuite/gcc.dg/pr60114.c b/gcc/testsuite/gcc.dg/pr60114.c
new file mode 100644
index 00000000000..c656a9586aa
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr60114.c
@@ -0,0 +1,31 @@
+/* PR c/60114 */
+/* { dg-do compile } */
+/* { dg-options "-Wconversion" } */
+
+struct S { int n, u[2]; };
+const signed char z[] = {
+ [0] = 0x100, /* { dg-warning "9:overflow in implicit constant conversion" } */
+ [2] = 0x101, /* { dg-warning "9:overflow in implicit constant conversion" } */
+};
+int A[] = {
+ 0, 0x80000000, /* { dg-warning "16:conversion of unsigned constant value to negative integer" } */
+ 0xA, 0x80000000, /* { dg-warning "18:conversion of unsigned constant value to negative integer" } */
+ 0xA, 0xA, 0x80000000 /* { dg-warning "23:conversion of unsigned constant value to negative integer" } */
+ };
+int *p = (int []) { 0x80000000 }; /* { dg-warning "21:conversion of unsigned constant value to negative integer" } */
+union { int k; } u = { .k = 0x80000000 }; /* { dg-warning "29:conversion of unsigned constant value to negative integer" } */
+typedef int H[];
+void
+foo (void)
+{
+ signed char a[][3] = { { 0x100, /* { dg-warning "28:overflow in implicit constant conversion" } */
+ 1, 0x100 }, /* { dg-warning "24:overflow in implicit constant conversion" } */
+ { '\0', 0x100, '\0' } /* { dg-warning "27:overflow in implicit constant conversion" } */
+ };
+ (const signed char []) { 0x100 }; /* { dg-warning "28:overflow in implicit constant conversion" } */
+ (const float []) { 1e0, 1e1, 1e100 }; /* { dg-warning "32:conversion" } */
+ struct S s1 = { 0x80000000 }; /* { dg-warning "19:conversion of unsigned constant value to negative integer" } */
+ struct S s2 = { .n = 0x80000000 }; /* { dg-warning "24:conversion of unsigned constant value to negative integer" } */
+ struct S s3 = { .u[1] = 0x80000000 }; /* { dg-warning "27:conversion of unsigned constant value to negative integer" } */
+ H h = { 1, 2, 0x80000000 }; /* { dg-warning "17:conversion of unsigned constant value to negative integer" } */
+}
diff --git a/gcc/testsuite/gcc.dg/torture/pr60930.c b/gcc/testsuite/gcc.dg/torture/pr60930.c
new file mode 100644
index 00000000000..5e35f19882d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr60930.c
@@ -0,0 +1,22 @@
+/* { dg-do run } */
+
+int x = 1;
+
+__attribute__((noinline, noclone)) void
+foo (unsigned long long t)
+{
+ asm volatile ("" : : "r" (&t));
+ if (t == 1)
+ __builtin_abort ();
+}
+
+int
+main ()
+{
+#if __SIZEOF_LONG_LONG__ >= 8
+ unsigned long long t = 0xffffffffffffffffULL * (0xffffffffUL * x);
+ if (t != 0xffffffff00000001ULL)
+ foo (t);;
+#endif
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/alias-30.c b/gcc/testsuite/gcc.dg/tree-ssa/alias-30.c
index addf1284057..7ef830d1937 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/alias-30.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/alias-30.c
@@ -1,5 +1,5 @@
/* { dg-do compile } */
-/* { dg-options "-O -fdump-tree-fre-details" } */
+/* { dg-options "-O -fdump-tree-fre1-details" } */
extern int posix_memalign(void **memptr,
__SIZE_TYPE__ alignment, __SIZE_TYPE__ size);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c
index f1f3101d3d2..3ed98aeb857 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-1.c
@@ -1,6 +1,7 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-isolate-paths" } */
+/* { dg-skip-if "" keeps_null_pointer_checks } */
struct demangle_component
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c
index bfcaa2b01da..912d98e2246 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-2.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fisolate-erroneous-paths-attribute -fdump-tree-isolate-paths -fdump-tree-phicprop1" } */
+/* { dg-skip-if "" keeps_null_pointer_checks } */
int z;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c
index 7dddd8062c0..9c2c5d55c27 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-3.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-isolate-paths" } */
+/* { dg-skip-if "" keeps_null_pointer_checks } */
typedef long unsigned int size_t;
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c
index c9c074df62b..d50a2b27f47 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-4.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fisolate-erroneous-paths-attribute -fdump-tree-isolate-paths -fdump-tree-phicprop1" } */
+/* { dg-skip-if "" keeps_null_pointer_checks } */
extern void foo(void *) __attribute__ ((__nonnull__ (1)));
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c b/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c
index 4d01d5c6399..e6ae37a7f74 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/isolate-5.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O2 -fdump-tree-isolate-paths -fdump-tree-optimized" } */
+/* { dg-skip-if "" keeps_null_pointer_checks } */
struct demangle_component
{
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp91.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp91.c
new file mode 100644
index 00000000000..68d8fd33a0b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp91.c
@@ -0,0 +1,22 @@
+/* { dg-do compile } */
+/* { dg-options "-S -O2 -fdump-tree-vrp2" } */
+
+unsigned short data;
+void foo ()
+{
+ unsigned char x16;
+ unsigned int i;
+ for (i = 0; i < 8; i++)
+ {
+ x16 = data & 1;
+ data >>= 1;
+ if (x16 == 1)
+ {
+ data ^= 0x4;
+ }
+ data >>= 1;
+ }
+}
+
+/* { dg-final { scan-tree-dump "\\\[0, 7\\\]" "vrp2" } } */
+/* { dg-final { cleanup-tree-dump "vrp2" } } */
diff --git a/gcc/testsuite/gcc.dg/vect/pr60505.c b/gcc/testsuite/gcc.dg/vect/pr60505.c
index 694051320ce..70e2ec06fe5 100644
--- a/gcc/testsuite/gcc.dg/vect/pr60505.c
+++ b/gcc/testsuite/gcc.dg/vect/pr60505.c
@@ -10,3 +10,5 @@ void foo(char *in, char *out, int num)
out[i] = (ovec[i] = in[i]);
out[num] = ovec[num/2];
}
+
+/* { dg-final { cleanup-tree-dump "vect" } } */
diff --git a/gcc/testsuite/gcc.target/arm/tail-long-call.c b/gcc/testsuite/gcc.target/arm/tail-long-call.c
new file mode 100644
index 00000000000..9b274686849
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/tail-long-call.c
@@ -0,0 +1,12 @@
+/* { dg-skip-if "need at least armv5te" { *-*-* } { "-march=armv[234]*" "-mthumb" } { "" } } */
+/* { dg-options "-O2 -march=armv5te -marm" } */
+/* { dg-final { scan-assembler "bx" } } */
+/* { dg-final { scan-assembler-not "blx" } } */
+
+int lcal (int) __attribute__ ((long_call));
+
+int
+dec (int a)
+{
+ return lcal (a);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/bcd-1.c b/gcc/testsuite/gcc.target/powerpc/bcd-1.c
new file mode 100644
index 00000000000..c7496c23579
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bcd-1.c
@@ -0,0 +1,27 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "cdtbcd " 1 } } */
+/* { dg-final { scan-assembler-times "cbcdtd " 1 } } */
+/* { dg-final { scan-assembler-times "addg6s " 1 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+
+unsigned int
+to_bcd (unsigned int a)
+{
+ return __builtin_cdtbcd (a);
+}
+
+unsigned int
+from_bcd (unsigned int a)
+{
+ return __builtin_cbcdtd (a);
+}
+
+unsigned int
+bcd_arith (unsigned int a, unsigned int b)
+{
+ return __builtin_addg6s (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/bcd-2.c b/gcc/testsuite/gcc.target/powerpc/bcd-2.c
new file mode 100644
index 00000000000..d330b742376
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bcd-2.c
@@ -0,0 +1,44 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2" } */
+/* { dg-final { scan-assembler-times "bcdadd\[.\] " 2 } } */
+/* { dg-final { scan-assembler-times "bcdsub\[.\] " 2 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+/* { dg-final { scan-assembler-not "mtvsr" } } */
+/* { dg-final { scan-assembler-not "mfvsr" } } */
+/* { dg-final { scan-assembler-not "lvx" } } */
+/* { dg-final { scan-assembler-not "lxvw4x" } } */
+/* { dg-final { scan-assembler-not "lxvd2x" } } */
+/* { dg-final { scan-assembler-not "stvx" } } */
+/* { dg-final { scan-assembler-not "stxvw4x" } } */
+/* { dg-final { scan-assembler-not "stxvd2x" } } */
+
+typedef __int128_t __attribute__((__vector_size__(16))) vector_128_t;
+typedef __int128_t scalar_128_t;
+typedef unsigned long long scalar_64_t;
+
+vector_128_t
+do_add_0 (vector_128_t a, vector_128_t b)
+{
+ return __builtin_bcdadd (a, b, 0);
+}
+
+vector_128_t
+do_add_1 (vector_128_t a, vector_128_t b)
+{
+ return __builtin_bcdadd (a, b, 1);
+}
+
+vector_128_t
+do_sub_0 (vector_128_t a, vector_128_t b)
+{
+ return __builtin_bcdsub (a, b, 0);
+}
+
+vector_128_t
+do_sub_1 (vector_128_t a, vector_128_t b)
+{
+ return __builtin_bcdsub (a, b, 1);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/bcd-3.c b/gcc/testsuite/gcc.target/powerpc/bcd-3.c
new file mode 100644
index 00000000000..436cecf6fff
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/bcd-3.c
@@ -0,0 +1,103 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2" } */
+/* { dg-final { scan-assembler-times "bcdadd\[.\] " 4 } } */
+/* { dg-final { scan-assembler-times "bcdsub\[.\] " 4 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+/* { dg-final { scan-assembler-not "mtvsr" } } */
+/* { dg-final { scan-assembler-not "mfvsr" } } */
+/* { dg-final { scan-assembler-not "lvx" } } */
+/* { dg-final { scan-assembler-not "lxvw4x" } } */
+/* { dg-final { scan-assembler-not "lxvd2x" } } */
+/* { dg-final { scan-assembler-not "stvx" } } */
+/* { dg-final { scan-assembler-not "stxvw4x" } } */
+/* { dg-final { scan-assembler-not "stxvd2x" } } */
+
+typedef __int128_t __attribute__((__vector_size__(16))) vector_128_t;
+typedef __int128_t scalar_128_t;
+typedef unsigned long long scalar_64_t;
+
+/* Test whether the peephole works to allow folding a bcdadd, with a
+ bcdadd_<test> into a single instruction. */
+
+vector_128_t
+do_add_lt (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdadd (a, b, 0);
+ if (__builtin_bcdadd_lt (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
+do_add_eq (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdadd (a, b, 0);
+ if (__builtin_bcdadd_eq (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
+do_add_gt (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdadd (a, b, 0);
+ if (__builtin_bcdadd_gt (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
+do_add_ov (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdadd (a, b, 0);
+ if (__builtin_bcdadd_ov (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
+do_sub_lt (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdsub (a, b, 0);
+ if (__builtin_bcdsub_lt (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
+do_sub_eq (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdsub (a, b, 0);
+ if (__builtin_bcdsub_eq (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
+do_sub_gt (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdsub (a, b, 0);
+ if (__builtin_bcdsub_gt (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
+
+vector_128_t
+do_sub_ov (vector_128_t a, vector_128_t b, int *p)
+{
+ vector_128_t ret = __builtin_bcdsub (a, b, 0);
+ if (__builtin_bcdsub_ov (a, b, 0))
+ *p = 1;
+
+ return ret;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c
new file mode 100644
index 00000000000..614f272642c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-1.c
@@ -0,0 +1,88 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "ddedpd " 4 } } */
+/* { dg-final { scan-assembler-times "denbcd " 2 } } */
+/* { dg-final { scan-assembler-times "dxex " 1 } } */
+/* { dg-final { scan-assembler-times "diex " 1 } } */
+/* { dg-final { scan-assembler-times "dscli " 2 } } */
+/* { dg-final { scan-assembler-times "dscri " 2 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+/* { dg-final { scan-assembler-not "dctqpq" } } */
+/* { dg-final { scan-assembler-not "drdpq" } } */
+/* { dg-final { scan-assembler-not "stfd" } } */
+/* { dg-final { scan-assembler-not "lfd" } } */
+
+_Decimal64
+do_dedpd_0 (_Decimal64 a)
+{
+ return __builtin_ddedpd (0, a);
+}
+
+_Decimal64
+do_dedpd_1 (_Decimal64 a)
+{
+ return __builtin_ddedpd (1, a);
+}
+
+_Decimal64
+do_dedpd_2 (_Decimal64 a)
+{
+ return __builtin_ddedpd (2, a);
+}
+
+_Decimal64
+do_dedpd_3 (_Decimal64 a)
+{
+ return __builtin_ddedpd (3, a);
+}
+
+_Decimal64
+do_enbcd_0 (_Decimal64 a)
+{
+ return __builtin_denbcd (0, a);
+}
+
+_Decimal64
+do_enbcd_1 (_Decimal64 a)
+{
+ return __builtin_denbcd (1, a);
+}
+
+_Decimal64
+do_xex (_Decimal64 a)
+{
+ return __builtin_dxex (a);
+}
+
+_Decimal64
+do_iex (_Decimal64 a, _Decimal64 b)
+{
+ return __builtin_diex (a, b);
+}
+
+_Decimal64
+do_scli_1 (_Decimal64 a)
+{
+ return __builtin_dscli (a, 1);
+}
+
+_Decimal64
+do_scli_10 (_Decimal64 a)
+{
+ return __builtin_dscli (a, 10);
+}
+
+_Decimal64
+do_scri_1 (_Decimal64 a)
+{
+ return __builtin_dscri (a, 1);
+}
+
+_Decimal64
+do_scri_10 (_Decimal64 a)
+{
+ return __builtin_dscri (a, 10);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c
new file mode 100644
index 00000000000..189bc9ad6ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/dfp-builtin-2.c
@@ -0,0 +1,88 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "ddedpdq " 4 } } */
+/* { dg-final { scan-assembler-times "denbcdq " 2 } } */
+/* { dg-final { scan-assembler-times "dxexq " 1 } } */
+/* { dg-final { scan-assembler-times "diexq " 1 } } */
+/* { dg-final { scan-assembler-times "dscliq " 2 } } */
+/* { dg-final { scan-assembler-times "dscriq " 2 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+/* { dg-final { scan-assembler-not "dctqpq" } } */
+/* { dg-final { scan-assembler-not "drdpq" } } */
+/* { dg-final { scan-assembler-not "stfd" } } */
+/* { dg-final { scan-assembler-not "lfd" } } */
+
+_Decimal128
+do_dedpdq_0 (_Decimal128 a)
+{
+ return __builtin_ddedpdq (0, a);
+}
+
+_Decimal128
+do_dedpdq_1 (_Decimal128 a)
+{
+ return __builtin_ddedpdq (1, a);
+}
+
+_Decimal128
+do_dedpdq_2 (_Decimal128 a)
+{
+ return __builtin_ddedpdq (2, a);
+}
+
+_Decimal128
+do_dedpdq_3 (_Decimal128 a)
+{
+ return __builtin_ddedpdq (3, a);
+}
+
+_Decimal128
+do_enbcdq_0 (_Decimal128 a)
+{
+ return __builtin_denbcdq (0, a);
+}
+
+_Decimal128
+do_enbcdq_1 (_Decimal128 a)
+{
+ return __builtin_denbcdq (1, a);
+}
+
+_Decimal128
+do_xexq (_Decimal128 a)
+{
+ return __builtin_dxexq (a);
+}
+
+_Decimal128
+do_iexq (_Decimal128 a, _Decimal128 b)
+{
+ return __builtin_diexq (a, b);
+}
+
+_Decimal128
+do_scliq_1 (_Decimal128 a)
+{
+ return __builtin_dscliq (a, 1);
+}
+
+_Decimal128
+do_scliq_10 (_Decimal128 a)
+{
+ return __builtin_dscliq (a, 10);
+}
+
+_Decimal128
+do_scriq_1 (_Decimal128 a)
+{
+ return __builtin_dscriq (a, 1);
+}
+
+_Decimal128
+do_scriq_10 (_Decimal128 a)
+{
+ return __builtin_dscriq (a, 10);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c b/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c
new file mode 100644
index 00000000000..5f948b7212f
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/extend-divide-1.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "divwe " 1 } } */
+/* { dg-final { scan-assembler-times "divweo " 1 } } */
+/* { dg-final { scan-assembler-times "divweu " 1 } } */
+/* { dg-final { scan-assembler-times "divweuo " 1 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+
+int
+div_we (int a, int b)
+{
+ return __builtin_divwe (a, b);
+}
+
+int
+div_weo (int a, int b)
+{
+ return __builtin_divweo (a, b);
+}
+
+unsigned int
+div_weu (unsigned int a, unsigned int b)
+{
+ return __builtin_divweu (a, b);
+}
+
+unsigned int
+div_weuo (unsigned int a, unsigned int b)
+{
+ return __builtin_divweuo (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c b/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c
new file mode 100644
index 00000000000..8ee6c8cf768
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/extend-divide-2.c
@@ -0,0 +1,34 @@
+/* { dg-do compile { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_vsx_ok } */
+/* { dg-options "-mcpu=power7 -O2" } */
+/* { dg-final { scan-assembler-times "divde " 1 } } */
+/* { dg-final { scan-assembler-times "divdeo " 1 } } */
+/* { dg-final { scan-assembler-times "divdeu " 1 } } */
+/* { dg-final { scan-assembler-times "divdeuo " 1 } } */
+/* { dg-final { scan-assembler-not "bl __builtin" } } */
+
+long
+div_de (long a, long b)
+{
+ return __builtin_divde (a, b);
+}
+
+long
+div_deo (long a, long b)
+{
+ return __builtin_divdeo (a, b);
+}
+
+unsigned long
+div_deu (unsigned long a, unsigned long b)
+{
+ return __builtin_divdeu (a, b);
+}
+
+unsigned long
+div_deuo (unsigned long a, unsigned long b)
+{
+ return __builtin_divdeuo (a, b);
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pack01.c b/gcc/testsuite/gcc.target/powerpc/pack01.c
new file mode 100644
index 00000000000..efac4087c78
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pack01.c
@@ -0,0 +1,91 @@
+/* { dg-do run { target { powerpc*-*-linux* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target p8vector_hw } */
+/* { dg-options "-mcpu=power8 -O2" } */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <altivec.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+typedef __int128_t __attribute__((__vector_size__(16))) vector_128_t;
+typedef __int128_t scalar_128_t;
+typedef unsigned long long scalar_64_t;
+
+volatile scalar_64_t one = 1;
+volatile scalar_64_t two = 2;
+
+int
+main (void)
+{
+ scalar_128_t a = (((scalar_128_t)one) << 64) | ((scalar_128_t)two);
+ vector_128_t v1 = (vector_128_t) { a };
+ vector_128_t v2 = __builtin_pack_vector_int128 (one, two);
+ scalar_64_t x0 = __builtin_unpack_vector_int128 (v1, 0);
+ scalar_64_t x1 = __builtin_unpack_vector_int128 (v1, 1);
+ vector_128_t v3 = __builtin_pack_vector_int128 (x0, x1);
+
+ size_t i;
+ union {
+ scalar_128_t i128;
+ vector_128_t v128;
+ scalar_64_t u64;
+ unsigned char uc[sizeof (scalar_128_t)];
+ char c[sizeof (scalar_128_t)];
+ } u, u2;
+
+#ifdef DEBUG
+ {
+ printf ("a = 0x");
+ u.i128 = a;
+ for (i = 0; i < sizeof (scalar_128_t); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf ("\nv1 = 0x");
+ u.v128 = v1;
+ for (i = 0; i < sizeof (scalar_128_t); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf ("\nv2 = 0x");
+ u.v128 = v2;
+ for (i = 0; i < sizeof (scalar_128_t); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf ("\nv3 = 0x");
+ u.v128 = v3;
+ for (i = 0; i < sizeof (scalar_128_t); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf ("\nx0 = 0x");
+ u.u64 = x0;
+ for (i = 0; i < sizeof (scalar_64_t); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf ("\nx1 = 0x");
+ u.u64 = x1;
+ for (i = 0; i < sizeof (scalar_64_t); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf ("\n");
+ }
+#endif
+
+ u2.i128 = a;
+ u.v128 = v1;
+ if (memcmp (u.c, u2.c, sizeof (scalar_128_t)) != 0)
+ abort ();
+
+ u.v128 = v2;
+ if (memcmp (u.c, u2.c, sizeof (scalar_128_t)) != 0)
+ abort ();
+
+ u.v128 = v3;
+ if (memcmp (u.c, u2.c, sizeof (scalar_128_t)) != 0)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pack02.c b/gcc/testsuite/gcc.target/powerpc/pack02.c
new file mode 100644
index 00000000000..74b6cd04dcc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pack02.c
@@ -0,0 +1,95 @@
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2" } */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <math.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+int
+main (void)
+{
+ double high = pow (2.0, 60);
+ double low = 2.0;
+ long double a = ((long double)high) + ((long double)low);
+ double x0 = __builtin_unpack_longdouble (a, 0);
+ double x1 = __builtin_unpack_longdouble (a, 1);
+ long double b = __builtin_pack_longdouble (x0, x1);
+
+#ifdef DEBUG
+ {
+ size_t i;
+ union {
+ long double ld;
+ double d;
+ unsigned char uc[sizeof (long double)];
+ char c[sizeof (long double)];
+ } u;
+
+ printf ("a = 0x");
+ u.ld = a;
+ for (i = 0; i < sizeof (long double); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (", %Lg\n", a);
+
+ printf ("b = 0x");
+ u.ld = b;
+ for (i = 0; i < sizeof (long double); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (", %Lg\n", b);
+
+ printf ("hi = 0x");
+ u.d = high;
+ for (i = 0; i < sizeof (double); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (",%*s %g\n", (int)(2 * (sizeof (long double) - sizeof (double))), "", high);
+
+ printf ("lo = 0x");
+ u.d = low;
+ for (i = 0; i < sizeof (double); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (",%*s %g\n", (int)(2 * (sizeof (long double) - sizeof (double))), "", low);
+
+ printf ("x0 = 0x");
+ u.d = x0;
+ for (i = 0; i < sizeof (double); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (",%*s %g\n", (int)(2 * (sizeof (long double) - sizeof (double))), "", x0);
+
+ printf ("x1 = 0x");
+ u.d = x1;
+ for (i = 0; i < sizeof (double); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (",%*s %g\n", (int)(2 * (sizeof (long double) - sizeof (double))), "", x1);
+ }
+#endif
+
+ if (high != x0)
+ abort ();
+
+ if (low != x1)
+ abort ();
+
+ if (a != b)
+ abort ();
+
+ if (x0 != high)
+ abort ();
+
+ if (x1 != low)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.target/powerpc/pack03.c b/gcc/testsuite/gcc.target/powerpc/pack03.c
new file mode 100644
index 00000000000..59f0e74ba9c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/powerpc/pack03.c
@@ -0,0 +1,88 @@
+/* { dg-do run { target { powerpc*-*-linux* } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-skip-if "" { powerpc*-*-*spe* } { "*" } { "" } } */
+/* { dg-require-effective-target vsx_hw } */
+/* { dg-options "-O2" } */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <math.h>
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+int
+main (void)
+{
+ _Decimal128 one = (_Decimal128)1.0;
+ _Decimal128 two = (_Decimal128)2.0;
+ _Decimal128 ten = (_Decimal128)10.0;
+ _Decimal128 a = one;
+ _Decimal128 b;
+ _Decimal128 c;
+ unsigned long long x0;
+ unsigned long long x1;
+ size_t i;
+
+ for (i = 0; i < 25; i++)
+ a *= ten;
+
+ a += two;
+
+ x0 = __builtin_unpack_dec128 (a, 0);
+ x1 = __builtin_unpack_dec128 (a, 1);
+ b = __builtin_pack_dec128 (x0, x1);
+ c = __builtin_dscliq (one, 25) + two;
+
+#ifdef DEBUG
+ {
+ union {
+ _Decimal128 d;
+ unsigned long long ull;
+ unsigned char uc[sizeof (_Decimal128)];
+ } u;
+
+ printf ("a = 0x");
+ u.d = a;
+ for (i = 0; i < sizeof (_Decimal128); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (", %Lg\n", (long double)a);
+
+ printf ("b = 0x");
+ u.d = b;
+ for (i = 0; i < sizeof (_Decimal128); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (", %Lg\n", (long double)b);
+
+ printf ("c = 0x");
+ u.d = c;
+ for (i = 0; i < sizeof (_Decimal128); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf (", %Lg\n", (long double)c);
+
+ printf ("x0 = 0x");
+ u.ull = x0;
+ for (i = 0; i < sizeof (unsigned long long); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf ("\nx1 = 0x");
+ u.ull = x1;
+ for (i = 0; i < sizeof (unsigned long long); i++)
+ printf ("%.2x", u.uc[i]);
+
+ printf ("\n");
+ }
+#endif
+
+ if (a != b)
+ abort ();
+
+ if (a != c)
+ abort ();
+
+ return 0;
+}
diff --git a/gcc/testsuite/gfortran.dg/namelist_utf8.f90 b/gcc/testsuite/gfortran.dg/namelist_utf8.f90
new file mode 100644
index 00000000000..c494b8c3b77
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/namelist_utf8.f90
@@ -0,0 +1,30 @@
+! { dg-do run }
+! PR52539 UTF-8 support for namelist read and write
+
+character(len=10, kind=4) :: str, str2
+character(len=25, kind=4) :: str3
+
+namelist /nml/ str
+
+str = 4_'a'//char (int (z'4F60'),4) &
+ //char (int (z'597D'), 4)//4_'b'
+
+open(99, encoding='utf-8',form='formatted')
+write(99, '(3a)') '&nml str = "', str, '" /'
+write(99, '(a)') str
+rewind(99)
+
+str = 4_'XXXX'
+str2 = 4_'YYYY'
+read(99,nml=nml)
+read(99, *) str2
+if (str2 /= str) call abort
+rewind(99)
+
+read(99,'(A)') str3
+if (str3 /= 4_'&nml str = "' // str // 4_'" /') call abort
+read(99,'(A)') str3
+if (str3 /= str) call abort
+
+close(99, status='delete')
+end
diff --git a/gcc/testsuite/gfortran.dg/no_range_check_3.f90 b/gcc/testsuite/gfortran.dg/no_range_check_3.f90
new file mode 100644
index 00000000000..24223af5b38
--- /dev/null
+++ b/gcc/testsuite/gfortran.dg/no_range_check_3.f90
@@ -0,0 +1,12 @@
+! { dg-do run }
+! { dg-options "-fno-range-check" }
+program test
+ integer :: i
+ i = int(z'FFFFFFFF',kind(i))
+ if (i /= -1) call abort
+ if (int(z'FFFFFFFF',kind(i)) /= -1) call abort
+
+ if (popcnt(int(z'0F00F00080000001',8)) /= 10) call abort
+ if (popcnt(int(z'800F0001',4)) /= 6) call abort
+
+end program test
diff --git a/gcc/tree-nested.c b/gcc/tree-nested.c
index df6923f76ef..9c175de4e9d 100644
--- a/gcc/tree-nested.c
+++ b/gcc/tree-nested.c
@@ -1082,6 +1082,11 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
need_stmts = true;
goto do_decl_clause;
+ case OMP_CLAUSE_LINEAR:
+ if (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause))
+ need_stmts = true;
+ goto do_decl_clause;
+
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_COPYPRIVATE:
@@ -1157,6 +1162,12 @@ convert_nonlocal_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
break;
+ case OMP_CLAUSE_LINEAR:
+ walk_body (convert_nonlocal_reference_stmt,
+ convert_nonlocal_reference_op, info,
+ &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause));
+ break;
+
default:
break;
}
@@ -1605,6 +1616,11 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
need_stmts = true;
goto do_decl_clause;
+ case OMP_CLAUSE_LINEAR:
+ if (OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause))
+ need_stmts = true;
+ goto do_decl_clause;
+
case OMP_CLAUSE_PRIVATE:
case OMP_CLAUSE_FIRSTPRIVATE:
case OMP_CLAUSE_COPYPRIVATE:
@@ -1685,6 +1701,12 @@ convert_local_omp_clauses (tree *pclauses, struct walk_stmt_info *wi)
&OMP_CLAUSE_LASTPRIVATE_GIMPLE_SEQ (clause));
break;
+ case OMP_CLAUSE_LINEAR:
+ walk_body (convert_local_reference_stmt,
+ convert_local_reference_op, info,
+ &OMP_CLAUSE_LINEAR_GIMPLE_SEQ (clause));
+ break;
+
default:
break;
}
diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h
index 46dc00c38a3..0d941019f0e 100644
--- a/gcc/tree-pass.h
+++ b/gcc/tree-pass.h
@@ -586,7 +586,7 @@ extern gimple_opt_pass *make_pass_convert_switch (gcc::context *ctxt);
extern opt_pass *current_pass;
extern bool execute_one_pass (opt_pass *);
-extern void execute_pass_list (opt_pass *);
+extern void execute_pass_list (function *, opt_pass *);
extern void execute_ipa_pass_list (opt_pass *);
extern void execute_ipa_summary_passes (ipa_opt_pass_d *);
extern void execute_all_ipa_transforms (void);
@@ -614,7 +614,7 @@ extern bool function_called_by_processed_nodes_p (void);
extern bool first_pass_instance;
/* Declare for plugins. */
-extern void do_per_function_toporder (void (*) (void *), void *);
+extern void do_per_function_toporder (void (*) (function *, void *), void *);
extern void disable_pass (const char *);
extern void enable_pass (const char *);
diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c
index e040c4fc58d..5074142f6f2 100644
--- a/gcc/tree-ssa-structalias.c
+++ b/gcc/tree-ssa-structalias.c
@@ -7243,10 +7243,7 @@ ipa_pta_execute (void)
tree ptr;
struct function *fn;
unsigned i;
- varinfo_t fi;
basic_block bb;
- struct pt_solution uses, clobbers;
- struct cgraph_edge *e;
/* Nodes without a body are not interesting. */
if (!cgraph_function_with_gimple_body_p (node) || node->clone_of)
@@ -7262,21 +7259,6 @@ ipa_pta_execute (void)
find_what_p_points_to (ptr);
}
- /* Compute the call-use and call-clobber sets for all direct calls. */
- fi = lookup_vi_for_tree (node->decl);
- gcc_assert (fi->is_fn_info);
- clobbers
- = find_what_var_points_to (first_vi_for_offset (fi, fi_clobbers));
- uses = find_what_var_points_to (first_vi_for_offset (fi, fi_uses));
- for (e = node->callers; e; e = e->next_caller)
- {
- if (!e->call_stmt)
- continue;
-
- *gimple_call_clobber_set (e->call_stmt) = clobbers;
- *gimple_call_use_set (e->call_stmt) = uses;
- }
-
/* Compute the call-use and call-clobber sets for indirect calls
and calls to external functions. */
FOR_EACH_BB_FN (bb, fn)
@@ -7287,17 +7269,27 @@ ipa_pta_execute (void)
{
gimple stmt = gsi_stmt (gsi);
struct pt_solution *pt;
- varinfo_t vi;
+ varinfo_t vi, fi;
tree decl;
if (!is_gimple_call (stmt))
continue;
- /* Handle direct calls to external functions. */
+ /* Handle direct calls to functions with body. */
decl = gimple_call_fndecl (stmt);
if (decl
- && (!(fi = lookup_vi_for_tree (decl))
- || !fi->is_fn_info))
+ && (fi = lookup_vi_for_tree (decl))
+ && fi->is_fn_info)
+ {
+ *gimple_call_clobber_set (stmt)
+ = find_what_var_points_to
+ (first_vi_for_offset (fi, fi_clobbers));
+ *gimple_call_use_set (stmt)
+ = find_what_var_points_to
+ (first_vi_for_offset (fi, fi_uses));
+ }
+ /* Handle direct calls to external functions. */
+ else if (decl)
{
pt = gimple_call_use_set (stmt);
if (gimple_call_flags (stmt) & ECF_CONST)
@@ -7341,10 +7333,9 @@ ipa_pta_execute (void)
pt->nonlocal = 1;
}
}
-
/* Handle indirect calls. */
- if (!decl
- && (fi = get_fi_for_callee (stmt)))
+ else if (!decl
+ && (fi = get_fi_for_callee (stmt)))
{
/* We need to accumulate all clobbers/uses of all possible
callees. */
diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c
index 8a0103b1637..7621348944f 100644
--- a/gcc/tree-ssa-threadedge.c
+++ b/gcc/tree-ssa-threadedge.c
@@ -398,7 +398,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
ssa_op_iter iter;
if (backedge_seen)
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_ALL_DEFS)
+ FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
{
/* This call only invalidates equivalences created by
PHI nodes. This is by design to keep the cost of
diff --git a/gcc/tree-vect-generic.c b/gcc/tree-vect-generic.c
index 9ac111772f4..e22ce2cc71d 100644
--- a/gcc/tree-vect-generic.c
+++ b/gcc/tree-vect-generic.c
@@ -969,7 +969,8 @@ expand_vector_operation (gimple_stmt_iterator *gsi, tree type, tree compute_type
if (!optimize
|| !VECTOR_INTEGER_TYPE_P (type)
- || TREE_CODE (rhs2) != VECTOR_CST)
+ || TREE_CODE (rhs2) != VECTOR_CST
+ || !VECTOR_MODE_P (TYPE_MODE (type)))
break;
ret = expand_vector_divmod (gsi, type, rhs1, rhs2, code);
diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c
index 75116177fed..094cf047e05 100644
--- a/gcc/tree-vect-patterns.c
+++ b/gcc/tree-vect-patterns.c
@@ -392,6 +392,8 @@ vect_recog_dot_prod_pattern (vec<gimple> *stmts, tree *type_in,
gcc_assert (STMT_VINFO_DEF_TYPE (stmt_vinfo) == vect_internal_def);
oprnd00 = gimple_assign_rhs1 (stmt);
oprnd01 = gimple_assign_rhs2 (stmt);
+ STMT_VINFO_PATTERN_DEF_SEQ (vinfo_for_stmt (last_stmt))
+ = STMT_VINFO_PATTERN_DEF_SEQ (stmt_vinfo);
}
else
{
@@ -3065,8 +3067,7 @@ vect_mark_pattern_stmts (gimple orig_stmt, gimple pattern_stmt,
}
gimple_set_bb (def_stmt, gimple_bb (orig_stmt));
STMT_VINFO_RELATED_STMT (def_stmt_info) = orig_stmt;
- STMT_VINFO_DEF_TYPE (def_stmt_info)
- = STMT_VINFO_DEF_TYPE (orig_stmt_info);
+ STMT_VINFO_DEF_TYPE (def_stmt_info) = vect_internal_def;
if (STMT_VINFO_VECTYPE (def_stmt_info) == NULL_TREE)
STMT_VINFO_VECTYPE (def_stmt_info) = pattern_vectype;
}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 2e2a27f874f..7951805e473 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -3949,52 +3949,6 @@ adjust_range_with_scev (value_range_t *vr, struct loop *loop,
}
}
-/* Return true if VAR may overflow at STMT. This checks any available
- loop information to see if we can determine that VAR does not
- overflow. */
-
-static bool
-vrp_var_may_overflow (tree var, gimple stmt)
-{
- struct loop *l;
- tree chrec, init, step;
-
- if (current_loops == NULL)
- return true;
-
- l = loop_containing_stmt (stmt);
- if (l == NULL
- || !loop_outer (l))
- return true;
-
- chrec = instantiate_parameters (l, analyze_scalar_evolution (l, var));
- if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
- return true;
-
- init = initial_condition_in_loop_num (chrec, l->num);
- step = evolution_part_in_loop_num (chrec, l->num);
-
- if (step == NULL_TREE
- || !is_gimple_min_invariant (step)
- || !valid_value_p (init))
- return true;
-
- /* If we get here, we know something useful about VAR based on the
- loop information. If it wraps, it may overflow. */
-
- if (scev_probably_wraps_p (init, step, stmt, get_chrec_loop (chrec),
- true))
- return true;
-
- if (dump_file && (dump_flags & TDF_DETAILS) != 0)
- {
- print_generic_expr (dump_file, var, 0);
- fprintf (dump_file, ": loop information indicates does not overflow\n");
- }
-
- return false;
-}
-
/* Given two numeric value ranges VR0, VR1 and a comparison code COMP:
@@ -8382,32 +8336,32 @@ vrp_visit_phi_node (gimple phi)
&& (cmp_min != 0 || cmp_max != 0))
goto varying;
- /* If the new minimum is smaller or larger than the previous
- one, go all the way to -INF. In the first case, to avoid
- iterating millions of times to reach -INF, and in the
- other case to avoid infinite bouncing between different
- minimums. */
- if (cmp_min > 0 || cmp_min < 0)
- {
- if (!needs_overflow_infinity (TREE_TYPE (vr_result.min))
- || !vrp_var_may_overflow (lhs, phi))
- vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
- else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
- vr_result.min =
- negative_overflow_infinity (TREE_TYPE (vr_result.min));
- }
-
- /* Similarly, if the new maximum is smaller or larger than
- the previous one, go all the way to +INF. */
- if (cmp_max < 0 || cmp_max > 0)
- {
- if (!needs_overflow_infinity (TREE_TYPE (vr_result.max))
- || !vrp_var_may_overflow (lhs, phi))
- vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
- else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
- vr_result.max =
- positive_overflow_infinity (TREE_TYPE (vr_result.max));
- }
+ /* If the new minimum is larger than than the previous one
+ retain the old value. If the new minimum value is smaller
+ than the previous one and not -INF go all the way to -INF + 1.
+ In the first case, to avoid infinite bouncing between different
+ minimums, and in the other case to avoid iterating millions of
+ times to reach -INF. Going to -INF + 1 also lets the following
+ iteration compute whether there will be any overflow, at the
+ expense of one additional iteration. */
+ if (cmp_min < 0)
+ vr_result.min = lhs_vr->min;
+ else if (cmp_min > 0
+ && !vrp_val_is_min (vr_result.min))
+ vr_result.min
+ = int_const_binop (PLUS_EXPR,
+ vrp_val_min (TREE_TYPE (vr_result.min)),
+ build_int_cst (TREE_TYPE (vr_result.min), 1));
+
+ /* Similarly for the maximum value. */
+ if (cmp_max > 0)
+ vr_result.max = lhs_vr->max;
+ else if (cmp_max < 0
+ && !vrp_val_is_max (vr_result.max))
+ vr_result.max
+ = int_const_binop (MINUS_EXPR,
+ vrp_val_max (TREE_TYPE (vr_result.min)),
+ build_int_cst (TREE_TYPE (vr_result.min), 1));
/* If we dropped either bound to +-INF then if this is a loop
PHI node SCEV may known more about its value-range. */
diff --git a/gcc/tree.h b/gcc/tree.h
index 57c952802a8..3e8e625ab9f 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -1333,6 +1333,9 @@ extern void protected_set_expr_location (tree, location_t);
#define OMP_CLAUSE_LINEAR_STEP(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_LINEAR), 1)
+#define OMP_CLAUSE_LINEAR_GIMPLE_SEQ(NODE) \
+ (OMP_CLAUSE_CHECK (NODE))->omp_clause.gimple_reduction_init
+
#define OMP_CLAUSE_ALIGNED_ALIGNMENT(NODE) \
OMP_CLAUSE_OPERAND (OMP_CLAUSE_SUBCODE_CHECK (NODE, OMP_CLAUSE_ALIGNED), 1)
diff --git a/libffi/ChangeLog b/libffi/ChangeLog
index aebe8553b90..75bfd8036a0 100644
--- a/libffi/ChangeLog
+++ b/libffi/ChangeLog
@@ -1,3 +1,12 @@
+2014-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ PR other/43620
+ * configure.ac (AM_INIT_AUTOMAKE): Add no-dist.
+ * Makefile.in: Regenerated.
+ * include/Makefile.in: Regenerated.
+ * man/Makefile.in: Regenerated.
+ * testsuite/Makefile.in: Regenerated.
+
2014-03-12 Yufeng Zhang <yufeng.zhang@arm.com>
* src/aarch64/sysv.S (ffi_closure_SYSV): Use x29 as the
diff --git a/libffi/Makefile.in b/libffi/Makefile.in
index 9ac95d49bdf..2a04e0b3bec 100644
--- a/libffi/Makefile.in
+++ b/libffi/Makefile.in
@@ -66,14 +66,11 @@ target_triplet = @target@
@PA_HPUX_TRUE@am__append_29 = src/pa/hpux32.S src/pa/ffi.c
@TILE_TRUE@am__append_30 = src/tile/tile.S src/tile/ffi.c
subdir = .
-DIST_COMMON = README $(am__configure_deps) $(srcdir)/../compile \
- $(srcdir)/../config.guess $(srcdir)/../config.sub \
- $(srcdir)/../depcomp $(srcdir)/../install-sh \
- $(srcdir)/../ltmain.sh $(srcdir)/../missing \
- $(srcdir)/../mkinstalldirs $(srcdir)/Makefile.am \
- $(srcdir)/Makefile.in $(srcdir)/doc/stamp-vti \
- $(srcdir)/doc/version.texi $(srcdir)/fficonfig.h.in \
- $(top_srcdir)/configure ChangeLog mdate-sh
+DIST_COMMON = README ChangeLog $(srcdir)/Makefile.in \
+ $(srcdir)/Makefile.am $(top_srcdir)/configure \
+ $(am__configure_deps) $(srcdir)/fficonfig.h.in \
+ $(srcdir)/../mkinstalldirs $(srcdir)/../depcomp mdate-sh \
+ $(srcdir)/doc/version.texi $(srcdir)/doc/stamp-vti
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
$(top_srcdir)/../config/asmcfi.m4 \
@@ -220,7 +217,6 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
SOURCES = $(libffi_la_SOURCES) $(nodist_libffi_la_SOURCES) \
$(libffi_convenience_la_SOURCES) \
$(nodist_libffi_convenience_la_SOURCES)
-DIST_SOURCES = $(libffi_la_SOURCES) $(libffi_convenience_la_SOURCES)
MULTISRCTOP =
MULTIBUILDTOP =
MULTIDIRS =
@@ -249,47 +245,10 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
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 \
- distdir dist dist-all distcheck
+ $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-distdir = $(PACKAGE)-$(VERSION)
-top_distdir = $(distdir)
-am__remove_distdir = \
- { test ! -d "$(distdir)" \
- || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
- && rm -fr "$(distdir)"; }; }
-am__relativize = \
- dir0=`pwd`; \
- sed_first='s,^\([^/]*\)/.*$$,\1,'; \
- sed_rest='s,^[^/]*/*,,'; \
- sed_last='s,^.*/\([^/]*\)$$,\1,'; \
- sed_butlast='s,/*[^/]*$$,,'; \
- while test -n "$$dir1"; do \
- first=`echo "$$dir1" | sed -e "$$sed_first"`; \
- if test "$$first" != "."; then \
- if test "$$first" = ".."; then \
- dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
- dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
- else \
- first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
- if test "$$first2" = "$$first"; then \
- dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
- else \
- dir2="../$$dir2"; \
- fi; \
- dir0="$$dir0"/"$$first"; \
- fi; \
- fi; \
- dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
- done; \
- reldir="$$dir2"
-DIST_ARCHIVES = $(distdir).tar.gz
-GZIP_ENV = --best
-distuninstallcheck_listfiles = find . -type f -print
-distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
@@ -1462,185 +1421,6 @@ GTAGS:
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- $(am__remove_distdir)
- test -d "$(distdir)" || mkdir "$(distdir)"
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
- $(am__relativize); \
- new_distdir=$$reldir; \
- dir1=$$subdir; dir2="$(top_distdir)"; \
- $(am__relativize); \
- new_top_distdir=$$reldir; \
- echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
- echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
- ($(am__cd) $$subdir && \
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$$new_top_distdir" \
- distdir="$$new_distdir" \
- am__remove_distdir=: \
- am__skip_length_check=: \
- am__skip_mode_fix=: \
- distdir) \
- || exit 1; \
- fi; \
- done
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$(top_distdir)" distdir="$(distdir)" \
- dist-info
- -test -n "$(am__skip_mode_fix)" \
- || find "$(distdir)" -type d ! -perm -755 \
- -exec chmod u+rwx,go+rx {} \; -o \
- ! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -400 -exec chmod a+r {} \; -o \
- ! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
- || chmod -R a+r "$(distdir)"
-dist-gzip: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-dist-bzip2: distdir
- tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
- $(am__remove_distdir)
-
-dist-lzma: distdir
- tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
- $(am__remove_distdir)
-
-dist-xz: distdir
- tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
- $(am__remove_distdir)
-
-dist-tarZ: distdir
- tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
- $(am__remove_distdir)
-
-dist-shar: distdir
- shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
- $(am__remove_distdir)
-
-dist-zip: distdir
- -rm -f $(distdir).zip
- zip -rq $(distdir).zip $(distdir)
- $(am__remove_distdir)
-
-dist dist-all: distdir
- tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
- $(am__remove_distdir)
-
-# This target untars the dist file and tries a VPATH configuration. Then
-# it guarantees that the distribution is self-contained by making another
-# tarfile.
-distcheck: dist
- case '$(DIST_ARCHIVES)' in \
- *.tar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
- *.tar.bz2*) \
- bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
- *.tar.lzma*) \
- lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
- *.tar.xz*) \
- xz -dc $(distdir).tar.xz | $(am__untar) ;;\
- *.tar.Z*) \
- uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
- *.shar.gz*) \
- GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
- *.zip*) \
- unzip $(distdir).zip ;;\
- esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
- mkdir $(distdir)/_build
- mkdir $(distdir)/_inst
- chmod a-w $(distdir)
- test -d $(distdir)/_build || exit 0; \
- dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
- && dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
- && am__cwd=`pwd` \
- && $(am__cd) $(distdir)/_build \
- && ../configure --srcdir=.. --prefix="$$dc_install_base" \
- $(DISTCHECK_CONFIGURE_FLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) \
- && $(MAKE) $(AM_MAKEFLAGS) dvi \
- && $(MAKE) $(AM_MAKEFLAGS) check \
- && $(MAKE) $(AM_MAKEFLAGS) install \
- && $(MAKE) $(AM_MAKEFLAGS) installcheck \
- && $(MAKE) $(AM_MAKEFLAGS) uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
- distuninstallcheck \
- && chmod -R a-w "$$dc_install_base" \
- && ({ \
- (cd ../.. && umask 077 && mkdir "$$dc_destdir") \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
- && $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
- distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
- } || { rm -rf "$$dc_destdir"; exit 1; }) \
- && rm -rf "$$dc_destdir" \
- && $(MAKE) $(AM_MAKEFLAGS) dist \
- && rm -rf $(DIST_ARCHIVES) \
- && $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
- && cd "$$am__cwd" \
- || exit 1
- $(am__remove_distdir)
- @(echo "$(distdir) archives ready for distribution: "; \
- list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
- sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
-distuninstallcheck:
- @$(am__cd) '$(distuninstallcheck_dir)' \
- && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
- || { echo "ERROR: files left after uninstall:" ; \
- if test -n "$(DESTDIR)"; then \
- echo " (check DESTDIR support)"; \
- fi ; \
- $(distuninstallcheck_listfiles) ; \
- exit 1; } >&2
-distcleancheck: distclean
- @if test '$(srcdir)' = . ; then \
- echo "ERROR: distcleancheck can only run from a VPATH build" ; \
- exit 1 ; \
- fi
- @test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
- || { echo "ERROR: files left in build directory after distclean:" ; \
- $(distcleancheck_listfiles) ; \
- exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile $(INFO_DEPS) $(LTLIBRARIES) all-multi fficonfig.h \
@@ -1881,16 +1661,14 @@ uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
all all-am all-local all-multi am--refresh check check-am \
clean clean-aminfo clean-generic clean-libtool clean-multi \
clean-noinstLTLIBRARIES clean-toolexeclibLTLIBRARIES ctags \
- ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-info \
- dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
- distclean distclean-compile distclean-generic distclean-hdr \
- distclean-libtool distclean-multi distclean-tags \
- distcleancheck distdir distuninstallcheck 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-multi install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
+ ctags-recursive dist-info distclean distclean-compile \
+ distclean-generic distclean-hdr 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-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-aminfo maintainer-clean-generic \
diff --git a/libffi/configure.ac b/libffi/configure.ac
index 438222775bc..a08feaa0381 100644
--- a/libffi/configure.ac
+++ b/libffi/configure.ac
@@ -12,7 +12,7 @@ target_alias=${target_alias-$host_alias}
. ${srcdir}/configure.host
-AM_INIT_AUTOMAKE
+AM_INIT_AUTOMAKE([no-dist])
# See if makeinfo has been installed and is modern enough
# that we can use it.
diff --git a/libffi/include/Makefile.in b/libffi/include/Makefile.in
index 2a42902d398..c923bf212e4 100644
--- a/libffi/include/Makefile.in
+++ b/libffi/include/Makefile.in
@@ -36,7 +36,7 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = include
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(srcdir)/ffi.h.in $(toollibffi_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
@@ -56,7 +56,6 @@ CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES = ffi.h ffitarget.h
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
-DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -82,7 +81,6 @@ am__installdirs = "$(DESTDIR)$(toollibffidir)"
HEADERS = $(toollibffi_HEADERS)
ETAGS = etags
CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
@@ -333,37 +331,6 @@ GTAGS:
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
check-am: all-am
check: check-am
all-am: Makefile $(HEADERS)
@@ -467,17 +434,16 @@ uninstall-am: uninstall-toollibffiHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool ctags distclean distclean-generic \
- distclean-libtool distclean-tags distdir 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-toollibffiHEADERS installcheck installcheck-am \
- installdirs maintainer-clean maintainer-clean-generic \
- mostlyclean mostlyclean-generic mostlyclean-libtool pdf pdf-am \
- ps ps-am tags uninstall uninstall-am \
- uninstall-toollibffiHEADERS
+ 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-toollibffiHEADERS \
+ installcheck installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-toollibffiHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/libffi/man/Makefile.in b/libffi/man/Makefile.in
index b5ed121df3d..743e67b7d1b 100644
--- a/libffi/man/Makefile.in
+++ b/libffi/man/Makefile.in
@@ -35,7 +35,7 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = man
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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/asmcfi.m4 \
@@ -54,7 +54,6 @@ CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
-DIST_SOURCES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -80,7 +79,6 @@ man3dir = $(mandir)/man3
am__installdirs = "$(DESTDIR)$(man3dir)"
NROFF = nroff
MANS = $(man_MANS)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
@@ -296,50 +294,6 @@ TAGS:
ctags: CTAGS
CTAGS:
-
-distdir: $(DISTFILES)
- @list='$(MANS)'; if test -n "$$list"; then \
- list=`for p in $$list; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
- if test -n "$$list" && \
- grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
- echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
- grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
- echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
- echo " typically \`make maintainer-clean' will remove them" >&2; \
- exit 1; \
- else :; fi; \
- else :; fi
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
check-am: all-am
check: check-am
all-am: Makefile $(MANS)
@@ -443,16 +397,16 @@ uninstall-man: uninstall-man3
.MAKE: install-am install-strip
.PHONY: all all-am check check-am clean clean-generic clean-libtool \
- distclean distclean-generic distclean-libtool distdir 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-man3 \
- 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 uninstall-man uninstall-man3
+ 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-man3 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 \
+ uninstall-man uninstall-man3
# Tell versions [3.59,3.63) of GNU make to not export all variables.
diff --git a/libffi/testsuite/Makefile.in b/libffi/testsuite/Makefile.in
index 540ab66d48c..808d4cb2e5b 100644
--- a/libffi/testsuite/Makefile.in
+++ b/libffi/testsuite/Makefile.in
@@ -35,7 +35,7 @@ build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
subdir = testsuite
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
+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/asmcfi.m4 \
@@ -54,10 +54,8 @@ CONFIG_HEADER = $(top_builddir)/fficonfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
SOURCES =
-DIST_SOURCES =
DEJATOOL = $(PACKAGE)
RUNTESTDEFAULTFLAGS = --tool $$tool --srcdir $$srcdir
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
ALLOCA = @ALLOCA@
AMTAR = @AMTAR@
@@ -351,37 +349,6 @@ distclean-DEJAGNU:
-l='$(DEJATOOL)'; for tool in $$l; do \
rm -f $$tool.sum $$tool.log; \
done
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) check-DEJAGNU
check: check-am
@@ -483,8 +450,8 @@ uninstall-am:
.PHONY: all all-am check check-DEJAGNU check-am clean clean-generic \
clean-libtool distclean distclean-DEJAGNU distclean-generic \
- distclean-libtool distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
+ 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 \
diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog
index d128b08a8ad..e2b28ee2c4d 100644
--- a/libgcc/ChangeLog
+++ b/libgcc/ChangeLog
@@ -1,3 +1,8 @@
+2014-04-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
+
+ * config/i386/crtfastmath.c [!__x86_64__ && __sun__ && __svr4__]
+ (sigill_caught, sigill_hdlr): Remove.
+
2014-04-22 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
* config/i386/crtfastmath.c (set_fast_math): Remove SSE execution
diff --git a/libgcc/config/i386/crtfastmath.c b/libgcc/config/i386/crtfastmath.c
index 24a08843286..67b37eea56f 100644
--- a/libgcc/config/i386/crtfastmath.c
+++ b/libgcc/config/i386/crtfastmath.c
@@ -31,26 +31,6 @@
#include "cpuid.h"
#endif
-#if !defined __x86_64__ && defined __sun__ && defined __svr4__
-#include <signal.h>
-#include <ucontext.h>
-
-static volatile sig_atomic_t sigill_caught;
-
-static void
-sigill_hdlr (int sig __attribute((unused)),
- siginfo_t *sip __attribute__((unused)),
- ucontext_t *ucp)
-{
- sigill_caught = 1;
- /* Set PC to the instruction after the faulting one to skip over it,
- otherwise we enter an infinite loop. 3 is the size of the movaps
- instruction. */
- ucp->uc_mcontext.gregs[EIP] += 3;
- setcontext (ucp);
-}
-#endif
-
static void __attribute__((constructor))
#ifndef __x86_64__
/* The i386 ABI only requires 4-byte stack alignment, so this is necessary
diff --git a/libgfortran/ChangeLog b/libgfortran/ChangeLog
index 0fb3ccddf7d..dc37a861f02 100644
--- a/libgfortran/ChangeLog
+++ b/libgfortran/ChangeLog
@@ -1,3 +1,16 @@
+2014-04-26 Jerry DeLisle <jvdelisle@gcc.gnu>
+
+ PR libfortran/52539
+ * io/list_read.c: Add uchar typedef. (push_char4): New function
+ to save kind=4 character. (next_char_utf8): New function to read
+ a single UTF-8 encoded character value. (read_chracter): Update
+ to use the new functions for reading UTF-8 strings.
+ (list_formatted_read_scalar): Update to handle list directed
+ reads of UTF-8 strings. (nml_read_obj): Likewise update for
+ UTF-8 strings in namelists.
+ * io/write.c (nml_write_obj): Add kind=4 character support for
+ namelist writes.
+
2014-04-24 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* configure.ac: Quote usage of ac_cv_func_clock_gettime in if test.
diff --git a/libgfortran/io/list_read.c b/libgfortran/io/list_read.c
index 625ba0c8594..b052c06b557 100644
--- a/libgfortran/io/list_read.c
+++ b/libgfortran/io/list_read.c
@@ -32,6 +32,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <stdlib.h>
#include <ctype.h>
+typedef unsigned char uchar;
+
/* List directed input. Several parsing subroutines are practically
reimplemented from formatted input, the reason being that there are
@@ -97,6 +99,37 @@ push_char (st_parameter_dt *dtp, char c)
dtp->u.p.saved_string[dtp->u.p.saved_used++] = c;
}
+/* Save a KIND=4 character to a string buffer, enlarging the buffer
+ as necessary. */
+
+static void
+push_char4 (st_parameter_dt *dtp, gfc_char4_t c)
+{
+ gfc_char4_t *new, *p = (gfc_char4_t *) dtp->u.p.saved_string;
+
+ if (p == NULL)
+ {
+ dtp->u.p.saved_string = xcalloc (SCRATCH_SIZE, sizeof (gfc_char4_t));
+ dtp->u.p.saved_length = SCRATCH_SIZE;
+ dtp->u.p.saved_used = 0;
+ p = (gfc_char4_t *) dtp->u.p.saved_string;
+ }
+
+ if (dtp->u.p.saved_used >= dtp->u.p.saved_length)
+ {
+ dtp->u.p.saved_length = 2 * dtp->u.p.saved_length;
+ new = realloc (p, dtp->u.p.saved_length);
+ if (new == NULL)
+ generate_error (&dtp->common, LIBERROR_OS, NULL);
+ p = new;
+
+ memset (new + dtp->u.p.saved_used, 0,
+ dtp->u.p.saved_length - dtp->u.p.saved_used);
+ }
+
+ p[dtp->u.p.saved_used++] = c;
+}
+
/* Free the input buffer if necessary. */
@@ -247,6 +280,57 @@ done:
}
+static gfc_char4_t
+next_char_utf8 (st_parameter_dt *dtp)
+{
+ static const uchar masks[6] = { 0x7F, 0x1F, 0x0F, 0x07, 0x02, 0x01 };
+ static const uchar patns[6] = { 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+ int i, nb;
+ gfc_char4_t c;
+
+ c = next_char (dtp);
+ if (c < 0x80)
+ return c;
+
+ /* The number of leading 1-bits in the first byte indicates how many
+ bytes follow. */
+ for (nb = 2; nb < 7; nb++)
+ if ((c & ~masks[nb-1]) == patns[nb-1])
+ goto found;
+ goto invalid;
+
+ found:
+ c = (c & masks[nb-1]);
+
+ /* Decode the bytes read. */
+ for (i = 1; i < nb; i++)
+ {
+ gfc_char4_t n = next_char (dtp);
+
+ if ((n & 0xC0) != 0x80)
+ goto invalid;
+
+ c = ((c << 6) + (n & 0x3F));
+ }
+
+ /* Make sure the shortest possible encoding was used. */
+ if (c <= 0x7F && nb > 1) goto invalid;
+ if (c <= 0x7FF && nb > 2) goto invalid;
+ if (c <= 0xFFFF && nb > 3) goto invalid;
+ if (c <= 0x1FFFFF && nb > 4) goto invalid;
+ if (c <= 0x3FFFFFF && nb > 5) goto invalid;
+
+ /* Make sure the character is valid. */
+ if (c > 0x7FFFFFFF || (c >= 0xD800 && c <= 0xDFFF))
+ goto invalid;
+
+ return c;
+
+ invalid:
+ generate_error (&dtp->common, LIBERROR_READ_VALUE, "Invalid UTF-8 encoding");
+ return (gfc_char4_t) '?';
+}
+
/* Push a character back onto the input. */
static void
@@ -1087,50 +1171,97 @@ read_character (st_parameter_dt *dtp, int length __attribute__ ((unused)))
}
get_string:
- for (;;)
- {
- if ((c = next_char (dtp)) == EOF)
- goto done_eof;
- switch (c)
- {
- case '"':
- case '\'':
- if (c != quote)
- {
- push_char (dtp, c);
- break;
- }
-
- /* See if we have a doubled quote character or the end of
- the string. */
-
- if ((c = next_char (dtp)) == EOF)
- goto done_eof;
- if (c == quote)
- {
- push_char (dtp, quote);
- break;
- }
-
- unget_char (dtp, c);
- goto done;
-
- CASE_SEPARATORS:
- if (quote == ' ')
- {
- unget_char (dtp, c);
- goto done;
- }
- if (c != '\n' && c != '\r')
+ if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
+ for (;;)
+ {
+ if ((c = next_char_utf8 (dtp)) == EOF)
+ goto done_eof;
+ switch (c)
+ {
+ case '"':
+ case '\'':
+ if (c != quote)
+ {
+ push_char4 (dtp, c);
+ break;
+ }
+
+ /* See if we have a doubled quote character or the end of
+ the string. */
+
+ if ((c = next_char_utf8 (dtp)) == EOF)
+ goto done_eof;
+ if (c == quote)
+ {
+ push_char4 (dtp, quote);
+ break;
+ }
+
+ unget_char (dtp, c);
+ goto done;
+
+ CASE_SEPARATORS:
+ if (quote == ' ')
+ {
+ unget_char (dtp, c);
+ goto done;
+ }
+
+ if (c != '\n' && c != '\r')
+ push_char4 (dtp, c);
+ break;
+
+ default:
+ push_char4 (dtp, c);
+ break;
+ }
+ }
+ else
+ for (;;)
+ {
+ if ((c = next_char (dtp)) == EOF)
+ goto done_eof;
+ switch (c)
+ {
+ case '"':
+ case '\'':
+ if (c != quote)
+ {
+ push_char (dtp, c);
+ break;
+ }
+
+ /* See if we have a doubled quote character or the end of
+ the string. */
+
+ if ((c = next_char (dtp)) == EOF)
+ goto done_eof;
+ if (c == quote)
+ {
+ push_char (dtp, quote);
+ break;
+ }
+
+ unget_char (dtp, c);
+ goto done;
+
+ CASE_SEPARATORS:
+ if (quote == ' ')
+ {
+ unget_char (dtp, c);
+ goto done;
+ }
+
+ if (c != '\n' && c != '\r')
+ push_char (dtp, c);
+ break;
+
+ default:
push_char (dtp, c);
- break;
-
- default:
- push_char (dtp, c);
- break;
- }
- }
+ break;
+ }
+ }
/* At this point, we have to have a separator, or else the string is
invalid. */
@@ -1903,7 +2034,7 @@ static int
list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p,
int kind, size_t size)
{
- gfc_char4_t *q;
+ gfc_char4_t *q, *r;
int c, i, m;
int err = 0;
@@ -2031,13 +2162,19 @@ list_formatted_read_scalar (st_parameter_dt *dtp, bt type, void *p,
{
m = ((int) size < dtp->u.p.saved_used)
? (int) size : dtp->u.p.saved_used;
- if (kind == 1)
- memcpy (p, dtp->u.p.saved_string, m);
+
+ q = (gfc_char4_t *) p;
+ r = (gfc_char4_t *) dtp->u.p.saved_string;
+ if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
+ for (i = 0; i < m; i++)
+ *q++ = *r++;
else
{
- q = (gfc_char4_t *) p;
- for (i = 0; i < m; i++)
- q[i] = (unsigned char) dtp->u.p.saved_string[i];
+ if (kind == 1)
+ memcpy (p, dtp->u.p.saved_string, m);
+ else
+ for (i = 0; i < m; i++)
+ *q++ = (unsigned char) dtp->u.p.saved_string[i];
}
}
else
@@ -2771,10 +2908,27 @@ nml_read_obj (st_parameter_dt *dtp, namelist_info * nl, index_type offset,
}
else
m = dtp->u.p.saved_used;
- pdata = (void*)( pdata + clow - 1 );
- memcpy (pdata, dtp->u.p.saved_string, m);
- if (m < dlen)
- memset ((void*)( pdata + m ), ' ', dlen - m);
+
+ if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
+ {
+ gfc_char4_t *q4, *p4 = pdata;
+ int i;
+
+ q4 = (gfc_char4_t *) dtp->u.p.saved_string;
+ p4 += clow -1;
+ for (i = 0; i < m; i++)
+ *p4++ = *q4++;
+ if (m < dlen)
+ for (i = 0; i < dlen - m; i++)
+ *p4++ = (gfc_char4_t) ' ';
+ }
+ else
+ {
+ pdata = (void*)( pdata + clow - 1 );
+ memcpy (pdata, dtp->u.p.saved_string, m);
+ if (m < dlen)
+ memset ((void*)( pdata + m ), ' ', dlen - m);
+ }
break;
default:
diff --git a/libgfortran/io/write.c b/libgfortran/io/write.c
index eccbe7e2a20..e17a3d86203 100644
--- a/libgfortran/io/write.c
+++ b/libgfortran/io/write.c
@@ -1835,7 +1835,10 @@ nml_write_obj (st_parameter_dt *dtp, namelist_info * obj, index_type offset,
break;
case BT_CHARACTER:
- write_character (dtp, p, 1, obj->string_length, DELIM);
+ if (dtp->u.p.current_unit->flags.encoding == ENCODING_UTF8)
+ write_character (dtp, p, 4, obj->string_length, DELIM);
+ else
+ write_character (dtp, p, 1, obj->string_length, DELIM);
break;
case BT_REAL:
diff --git a/libgo/runtime/mheap.c b/libgo/runtime/mheap.c
index fee493c1367..1b8ab791606 100644
--- a/libgo/runtime/mheap.c
+++ b/libgo/runtime/mheap.c
@@ -387,7 +387,7 @@ forcegchelper(void *vnote)
static uintptr
scavengelist(MSpan *list, uint64 now, uint64 limit)
{
- uintptr released, sumreleased;
+ uintptr released, sumreleased, start, end, pagesize;
MSpan *s;
if(runtime_MSpanList_IsEmpty(list))
@@ -400,7 +400,17 @@ scavengelist(MSpan *list, uint64 now, uint64 limit)
mstats.heap_released += released;
sumreleased += released;
s->npreleased = s->npages;
- runtime_SysUnused((void*)(s->start << PageShift), s->npages << PageShift);
+
+ start = s->start << PageShift;
+ end = start + (s->npages << PageShift);
+
+ // Round start up and end down to ensure we
+ // are acting on entire pages.
+ pagesize = getpagesize();
+ start = ROUND(start, pagesize);
+ end &= ~(pagesize - 1);
+ if(end > start)
+ runtime_SysUnused((void*)start, end - start);
}
}
return sumreleased;
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index c0f093ff458..0b26b9fdb4a 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,15 @@
+2014-04-24 Jakub Jelinek <jakub@redhat.com>
+
+ * testsuite/libgomp.c++/atomic-14.C: Allow seq_cst and
+ atomic type clauses in any order and optional comma in between.
+ * testsuite/libgomp.c++/atomic-15.C: Likewise.
+ * testsuite/libgomp.c/atomic-17.c: Likewise.
+
+ * testsuite/libgomp.c/simd-7.c: New test.
+ * testsuite/libgomp.c/simd-8.c: New test.
+ * testsuite/libgomp.c/simd-9.c: New test.
+ * testsuite/libgomp.c/loop-16.c: New test.
+
2014-04-02 Richard Henderson <rth@redhat.com>
* config/linux/futex.h (futex_wait): Get error value from errno.
diff --git a/libgomp/testsuite/libgomp.c++/atomic-14.C b/libgomp/testsuite/libgomp.c++/atomic-14.C
index 4cd9df812d3..dccea3acd80 100644
--- a/libgomp/testsuite/libgomp.c++/atomic-14.C
+++ b/libgomp/testsuite/libgomp.c++/atomic-14.C
@@ -13,13 +13,13 @@ main ()
v = x;
if (v != 3)
abort ();
- #pragma omp atomic update seq_cst
+ #pragma omp atomic seq_cst update
x = 3 * 2 * 1 + x;
- #pragma omp atomic read seq_cst
+ #pragma omp atomic read, seq_cst
v = x;
if (v != 9)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst, capture
v = x = x | 16;
if (v != 25)
abort ();
@@ -27,15 +27,15 @@ main ()
v = x = x + 14 * 2 / 4;
if (v != 32)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
v = x = 5 | x;
if (v != 37)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture, seq_cst
v = x = 40 + 12 - 2 - 7 - x;
if (v != 6)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic seq_cst read
v = x;
if (v != 6)
abort ();
@@ -43,7 +43,7 @@ main ()
{ v = x; x = 3 + x; }
if (v != 6)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ v = x; x = -1 * -1 * -1 * -1 - x; }
if (v != 9)
abort ();
@@ -51,11 +51,11 @@ main ()
v = x;
if (v != -8)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture, seq_cst
{ x = 2 * 2 - x; v = x; }
if (v != 12)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ x = 7 & x; v = x; }
if (v != 4)
abort ();
@@ -63,7 +63,7 @@ main ()
{ v = x; x = 6; }
if (v != 4)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic read, seq_cst
v = x;
if (v != 6)
abort ();
@@ -71,11 +71,11 @@ main ()
{ v = x; x = 7 * 8 + 23; }
if (v != 6)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic seq_cst, read
v = x;
if (v != 79)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture , seq_cst
{ v = x; x = 23 + 6 * 4; }
if (v != 79)
abort ();
@@ -83,7 +83,7 @@ main ()
v = x;
if (v != 47)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ v = x; x = l ? 17 : 12; }
if (v != 47)
abort ();
diff --git a/libgomp/testsuite/libgomp.c++/atomic-15.C b/libgomp/testsuite/libgomp.c++/atomic-15.C
index 1eabce7dbd3..9abefb64688 100644
--- a/libgomp/testsuite/libgomp.c++/atomic-15.C
+++ b/libgomp/testsuite/libgomp.c++/atomic-15.C
@@ -14,13 +14,13 @@ foo ()
v = x;
if (v != 3)
abort ();
- #pragma omp atomic update seq_cst
+ #pragma omp atomic seq_cst update
x = 3 * 2 * 1 + x;
- #pragma omp atomic read seq_cst
+ #pragma omp atomic read, seq_cst
v = x;
if (v != 9)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst, capture
v = x = x | 16;
if (v != 25)
abort ();
@@ -28,15 +28,15 @@ foo ()
v = x = x + 14 * 2 / 4;
if (v != 32)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
v = x = 5 | x;
if (v != 37)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture, seq_cst
v = x = 40 + 12 - 2 - 7 - x;
if (v != 6)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic seq_cst read
v = x;
if (v != 6)
abort ();
@@ -44,7 +44,7 @@ foo ()
{ v = x; x = 3 + x; }
if (v != 6)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ v = x; x = -1 * -1 * -1 * -1 - x; }
if (v != 9)
abort ();
@@ -52,11 +52,11 @@ foo ()
v = x;
if (v != -8)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture, seq_cst
{ x = 2 * 2 - x; v = x; }
if (v != 12)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ x = 7 & x; v = x; }
if (v != 4)
abort ();
@@ -64,7 +64,7 @@ foo ()
{ v = x; x = 6; }
if (v != 4)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic read, seq_cst
v = x;
if (v != 6)
abort ();
@@ -72,11 +72,11 @@ foo ()
{ v = x; x = 7 * 8 + 23; }
if (v != 6)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic seq_cst, read
v = x;
if (v != 79)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture , seq_cst
{ v = x; x = 23 + 6 * 4; }
if (v != 79)
abort ();
@@ -84,7 +84,7 @@ foo ()
v = x;
if (v != 47)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ v = x; x = l ? 17 : 12; }
if (v != 47)
abort ();
diff --git a/libgomp/testsuite/libgomp.c/atomic-17.c b/libgomp/testsuite/libgomp.c/atomic-17.c
index 2bd0e9b44dc..147ab26a953 100644
--- a/libgomp/testsuite/libgomp.c/atomic-17.c
+++ b/libgomp/testsuite/libgomp.c/atomic-17.c
@@ -13,13 +13,13 @@ main ()
v = x;
if (v != 3)
abort ();
- #pragma omp atomic update seq_cst
+ #pragma omp atomic seq_cst update
x = 3 * 2 * 1 + x;
- #pragma omp atomic read seq_cst
+ #pragma omp atomic read, seq_cst
v = x;
if (v != 9)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst, capture
v = x = x | 16;
if (v != 25)
abort ();
@@ -27,15 +27,15 @@ main ()
v = x = x + 14 * 2 / 4;
if (v != 32)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
v = x = 5 | x;
if (v != 37)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture, seq_cst
v = x = 40 + 12 - 2 - 7 - x;
if (v != 6)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic seq_cst read
v = x;
if (v != 6)
abort ();
@@ -43,7 +43,7 @@ main ()
{ v = x; x = 3 + x; }
if (v != 6)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ v = x; x = -1 * -1 * -1 * -1 - x; }
if (v != 9)
abort ();
@@ -51,11 +51,11 @@ main ()
v = x;
if (v != -8)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture, seq_cst
{ x = 2 * 2 - x; v = x; }
if (v != 12)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ x = 7 & x; v = x; }
if (v != 4)
abort ();
@@ -63,7 +63,7 @@ main ()
{ v = x; x = 6; }
if (v != 4)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic read, seq_cst
v = x;
if (v != 6)
abort ();
@@ -71,11 +71,11 @@ main ()
{ v = x; x = 7 * 8 + 23; }
if (v != 6)
abort ();
- #pragma omp atomic read seq_cst
+ #pragma omp atomic seq_cst, read
v = x;
if (v != 79)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic capture , seq_cst
{ v = x; x = 23 + 6 * 4; }
if (v != 79)
abort ();
@@ -83,7 +83,7 @@ main ()
v = x;
if (v != 47)
abort ();
- #pragma omp atomic capture seq_cst
+ #pragma omp atomic seq_cst capture
{ v = x; x = l ? 17 : 12; }
if (v != 47)
abort ();
diff --git a/libgomp/testsuite/libgomp.c/loop-16.c b/libgomp/testsuite/libgomp.c/loop-16.c
new file mode 100644
index 00000000000..3ef2f6489bd
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/loop-16.c
@@ -0,0 +1,27 @@
+/* { dg-do run } */
+
+extern void abort (void);
+
+volatile int count;
+static int test (void)
+{
+ return ++count > 0;
+}
+
+int i;
+
+int
+main ()
+{
+ #pragma omp for lastprivate (i)
+ for (i = 0; i < 10; ++i)
+ {
+ int *p = &i;
+ if (test ())
+ continue;
+ abort ();
+ }
+ if (i != count)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/simd-7.c b/libgomp/testsuite/libgomp.c/simd-7.c
new file mode 100644
index 00000000000..ab04fee82d7
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/simd-7.c
@@ -0,0 +1,96 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+extern void abort ();
+int a[1024] __attribute__((aligned (32))) = { 1 };
+int b[1024] __attribute__((aligned (32))) = { 1 };
+int k, m;
+struct U { int u; };
+struct V { int v; };
+
+__attribute__((noinline, noclone)) int
+foo (int *p)
+{
+ int i, s = 0;
+ struct U u;
+ struct V v;
+ #pragma omp simd aligned(a, p : 32) linear(k: m + 1) \
+ linear(i) reduction(+:s) lastprivate(u, v)
+ for (i = 0; i < 1024; i++)
+ {
+ int *q = &i;
+ a[i] *= p[i];
+ u.u = p[i] + k;
+ k += m + 1;
+ v.v = p[i] + k;
+ s += p[i] + k;
+ }
+ if (u.u != 36 + 4 + 3 * 1023 || v.v != 36 + 4 + 3 * 1024 || i != 1024)
+ abort ();
+ return s;
+}
+
+__attribute__((noinline, noclone)) int
+bar (int *p)
+{
+ int i, s = 0;
+ struct U u;
+ struct V v;
+ #pragma omp simd aligned(a, p : 32) linear(k: m + 1) \
+ reduction(+:s) lastprivate(u, v)
+ for (i = 0; i < 1024; i++)
+ {
+ int *q = &i;
+ a[i] *= p[i];
+ u.u = p[i] + k;
+ k += m + 1;
+ v.v = p[i] + k;
+ s += p[i] + k;
+ }
+ if (u.u != 36 + 4 + 3 * 1023 || v.v != 36 + 4 + 3 * 1024 || i != 1024)
+ abort ();
+ return s;
+}
+
+int
+main ()
+{
+#if __SIZEOF_INT__ >= 4
+ int i;
+ k = 4;
+ m = 2;
+ for (i = 0; i < 1024; i++)
+ {
+ a[i] = i - 512;
+ b[i] = (i - 51) % 39;
+ }
+ int s = foo (b);
+ for (i = 0; i < 1024; i++)
+ {
+ if (b[i] != (i - 51) % 39
+ || a[i] != (i - 512) * b[i])
+ abort ();
+ }
+ if (k != 4 + 3 * 1024 || s != 1596127)
+ abort ();
+ k = 4;
+ m = 2;
+ for (i = 0; i < 1024; i++)
+ {
+ a[i] = i - 512;
+ b[i] = (i - 51) % 39;
+ }
+ s = bar (b);
+ for (i = 0; i < 1024; i++)
+ {
+ if (b[i] != (i - 51) % 39
+ || a[i] != (i - 512) * b[i])
+ abort ();
+ }
+ if (k != 4 + 3 * 1024 || s != 1596127)
+ abort ();
+#endif
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/simd-8.c b/libgomp/testsuite/libgomp.c/simd-8.c
new file mode 100644
index 00000000000..13f40d58362
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/simd-8.c
@@ -0,0 +1,44 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+extern void abort ();
+int a[32][32] __attribute__((aligned (32))) = { { 1 } };
+struct S { int s; };
+#pragma omp declare reduction (+:struct S:omp_out.s += omp_in.s)
+#pragma omp declare reduction (foo:struct S:omp_out.s += omp_in.s)
+#pragma omp declare reduction (foo:int:omp_out += omp_in)
+
+__attribute__((noinline, noclone)) int
+foo (void)
+{
+ int i, j, u = 0;
+ struct S s, t;
+ s.s = 0; t.s = 0;
+ #pragma omp simd aligned(a : 32) reduction(+:s) reduction(foo:t, u) collapse(2)
+ for (i = 0; i < 32; i++)
+ for (j = 0; j < 32; j++)
+ {
+ int x = a[i][j];
+ s.s += x;
+ t.s += x;
+ u += x;
+ }
+ if (t.s != s.s || u != s.s)
+ abort ();
+ return s.s;
+}
+
+int
+main ()
+{
+ int i, j;
+ for (i = 0; i < 32; i++)
+ for (j = 0; j < 32; j++)
+ a[i][j] = j + (i / 4);
+ int s = foo ();
+ if (s != 19456)
+ abort ();
+ return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/simd-9.c b/libgomp/testsuite/libgomp.c/simd-9.c
new file mode 100644
index 00000000000..b64dd252229
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/simd-9.c
@@ -0,0 +1,70 @@
+/* { dg-do run } */
+/* { dg-options "-O2" } */
+/* { dg-additional-options "-msse2" { target sse2_runtime } } */
+/* { dg-additional-options "-mavx" { target avx_runtime } } */
+
+extern void abort ();
+int a[32][32] __attribute__((aligned (32))) = { { 1 } };
+struct S { int s; };
+#pragma omp declare reduction (+:struct S:omp_out.s += omp_in.s)
+#pragma omp declare reduction (foo:struct S:omp_out.s += omp_in.s)
+#pragma omp declare reduction (foo:int:omp_out += omp_in)
+
+__attribute__((noinline, noclone)) int
+foo (void)
+{
+ int i, j, u = 0;
+ struct S s, t;
+ s.s = 0; t.s = 0;
+ #pragma omp simd aligned(a : 32) lastprivate (i, j) reduction(+:s) reduction(foo:t, u) collapse(2)
+ for (i = 0; i < 32; i++)
+ for (j = 0; j < 32; j++)
+ {
+ int *q = &i;
+ int *r = &j;
+ int x = a[i][j];
+ s.s += x;
+ t.s += x;
+ u += x;
+ }
+ if (t.s != s.s || u != s.s || i != 32 || j != 32)
+ abort ();
+ return s.s;
+}
+
+__attribute__((noinline, noclone)) int
+bar (void)
+{
+ int i, j, u = 0;
+ struct S s, t;
+ s.s = 0; t.s = 0;
+ #pragma omp simd aligned(a:32)reduction(+:s)reduction(foo:t,u)collapse(2)
+ for (i = 0; i < 32; i++)
+ for (j = 0; j < 32; j++)
+ {
+ int *q = &i;
+ int *r = &j;
+ int x = a[i][j];
+ s.s += x;
+ t.s += x;
+ u += x;
+ }
+ if (t.s != s.s || u != s.s || i != 32 || j != 32)
+ abort ();
+ return s.s;
+}
+
+int
+main ()
+{
+ int i, j;
+ for (i = 0; i < 32; i++)
+ for (j = 0; j < 32; j++)
+ a[i][j] = j + (i / 4);
+ int s = foo ();
+ if (s != 19456)
+ abort ();
+ if (bar () != 19456)
+ abort ();
+ return 0;
+}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 83c10944a3b..6cc371c5d9d 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,66 @@
+2014-04-27 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex_automaton.h (_NFA<>::_M_insert_repeat):
+ Add _S_opcode_repeat support to distingush a loop from
+ _S_opcode_alternative.
+ * include/bits/regex_automaton.tcc (_State_base::_M_print,
+ _State_base::_M_dot, _NFA<>::_M_eliminate_dummy,
+ _StateSeq<>::_M_clone): Likewise.
+ * include/bits/regex_compiler.tcc (_Compiler<>::_M_quantifier):
+ Likewise.
+ * include/bits/regex_executor.tcc (_Executor<>::_M_dfs): Likewise.
+ * include/bits/regex_scanner.tcc (_Scanner<>::_M_eat_escape_ecma):
+ Uglify local variable __i.
+ * include/bits/regex_compiler.h (_BracketMatcher<>::_M_make_cache):
+ Use size_t instead of int to compare with vector::size().
+
+2014-04-27 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex_executor.h: Add _M_rep_count to track how
+ many times this repeat node are visited.
+ * include/bits/regex_executor.tcc (_Executor<>::_M_rep_once_more,
+ _Executor<>::_M_dfs): Use _M_rep_count to prevent entering
+ infinite loop.
+
+2014-04-27 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex.tcc (__regex_algo_impl<>): Remove
+ _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT and use
+ _GLIBCXX_REGEX_USE_THOMPSON_NFA instead.
+ * include/bits/regex_automaton.h: Remove quantifier counting variable.
+ * include/bits/regex_automaton.tcc (_State_base::_M_dot):
+ Adjust debug NFA dump.
+
+2014-04-25 Lars Gullik Bjønnes <larsbj@gullik.org>
+
+ PR libstdc++/60710
+ * include/experimental/optional (operator!=): Implement in terms of
+ operator==.
+ * testsuite/experimental/optional/relops/1.cc: Remove operator!=.
+ * testsuite/experimental/optional/relops/2.cc: Likewise.
+ * testsuite/experimental/optional/relops/3.cc: Likewise.
+ * testsuite/experimental/optional/relops/4.cc: Likewise.
+ * testsuite/experimental/optional/relops/5.cc: Likewise.
+ * testsuite/experimental/optional/relops/6.cc: Likewise.
+
+2014-04-25 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/60958
+ * include/tr1/regex (regex_traits::isctype): Comment out broken code.
+ * testsuite/util/testsuite_regex.h (regex_match_debug): Improve
+ comment.
+
+2014-04-25 Marc Glisse <marc.glisse@inria.fr>
+
+ * testsuite/util/testsuite_abi.cc (check_version): Update for
+ CXXABI_1.3.9.
+
+2014-04-24 Tim Shen <timshen91@gmail.com>
+
+ * include/bits/regex_automaton.tcc (_StateSeq<>::_M_clone()):
+ Do _M_alt before _M_next.
+ * testsuite/28_regex/basic_regex/multiple_quantifiers.cc: Add testcases.
+
2014-04-24 Marc Glisse <marc.glisse@inria.fr>
PR libstdc++/43622
diff --git a/libstdc++-v3/include/bits/regex.tcc b/libstdc++-v3/include/bits/regex.tcc
index 5fa1f018b3d..0d737a0b74b 100644
--- a/libstdc++-v3/include/bits/regex.tcc
+++ b/libstdc++-v3/include/bits/regex.tcc
@@ -28,12 +28,12 @@
* Do not attempt to use it directly. @headername{regex}
*/
-// See below __regex_algo_impl to get what this is talking about. The default
-// value 1 indicated a conservative optimization without giving up worst case
-// performance.
-#ifndef _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
-#define _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT 1
-#endif
+// A non-standard switch to let the user pick the matching algorithm.
+// If _GLIBCXX_REGEX_USE_THOMPSON_NFA is defined, the thompson NFA
+// algorithm will be used. This algorithm is not enabled by default,
+// and cannot be used if the regex contains back-references, but has better
+// (polynomial instead of exponential) worst case performace.
+// See __regex_algo_impl below.
namespace std _GLIBCXX_VISIBILITY(default)
{
@@ -66,24 +66,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
for (auto& __it : __res)
__it.matched = false;
- // This function decide which executor to use under given circumstances.
- // The _S_auto policy now is the following: if a NFA has no
- // back-references and has more than _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT
- // quantifiers (*, +, ?), the BFS executor will be used, other wise
- // DFS executor. This is because DFS executor has a exponential upper
- // bound, but better best-case performace. Meanwhile, BFS executor can
- // effectively prevent from exponential-long time matching (which must
- // contains many quantifiers), but it's slower in average.
- //
- // For simple regex, BFS executor could be 2 or more times slower than
- // DFS executor.
- //
- // Of course, BFS executor cannot handle back-references.
+ // __policy is used by testsuites so that they can use Thompson NFA
+ // without defining a macro. Users should define
+ // _GLIBCXX_REGEX_USE_THOMPSON_NFA if they need to use this approach.
bool __ret;
if (!__re._M_automaton->_M_has_backref
- && (__policy == _RegexExecutorPolicy::_S_alternate
- || __re._M_automaton->_M_quant_count
- > _GLIBCXX_REGEX_DFS_QUANTIFIERS_LIMIT))
+#ifndef _GLIBCXX_REGEX_USE_THOMPSON_NFA
+ && __policy == _RegexExecutorPolicy::_S_alternate
+#endif
+ )
{
_Executor<_BiIter, _Alloc, _TraitsT, false>
__executor(__s, __e, __m, __re, __flags);
diff --git a/libstdc++-v3/include/bits/regex_automaton.h b/libstdc++-v3/include/bits/regex_automaton.h
index a442cfe21b7..1b0da1453e9 100644
--- a/libstdc++-v3/include/bits/regex_automaton.h
+++ b/libstdc++-v3/include/bits/regex_automaton.h
@@ -52,6 +52,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
_S_opcode_unknown,
_S_opcode_alternative,
+ _S_opcode_repeat,
_S_opcode_backref,
_S_opcode_line_begin_assertion,
_S_opcode_line_end_assertion,
@@ -74,9 +75,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
size_t _M_backref_index; // for _S_opcode_backref
struct
{
- // for _S_opcode_alternative.
- _StateIdT _M_quant_index;
- // for _S_opcode_alternative or _S_opcode_subexpr_lookahead
+ // for _S_opcode_alternative, _S_opcode_repeat and
+ // _S_opcode_subexpr_lookahead
_StateIdT _M_alt;
// for _S_opcode_word_boundary or _S_opcode_subexpr_lookahead or
// quantifiers (ungreedy if set true)
@@ -120,7 +120,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
explicit
_NFA_base(_FlagT __f)
: _M_flags(__f), _M_start_state(0), _M_subexpr_count(0),
- _M_quant_count(0), _M_has_backref(false)
+ _M_has_backref(false)
{ }
_NFA_base(_NFA_base&&) = default;
@@ -145,7 +145,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_FlagT _M_flags;
_StateIdT _M_start_state;
_SizeT _M_subexpr_count;
- _SizeT _M_quant_count;
bool _M_has_backref;
};
@@ -175,7 +174,17 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_StateT __tmp(_S_opcode_alternative);
// It labels every quantifier to make greedy comparison easier in BFS
// approach.
- __tmp._M_quant_index = this->_M_quant_count++;
+ __tmp._M_next = __next;
+ __tmp._M_alt = __alt;
+ return _M_insert_state(std::move(__tmp));
+ }
+
+ _StateIdT
+ _M_insert_repeat(_StateIdT __next, _StateIdT __alt, bool __neg)
+ {
+ _StateT __tmp(_S_opcode_repeat);
+ // It labels every quantifier to make greedy comparison easier in BFS
+ // approach.
__tmp._M_next = __next;
__tmp._M_alt = __alt;
__tmp._M_neg = __neg;
diff --git a/libstdc++-v3/include/bits/regex_automaton.tcc b/libstdc++-v3/include/bits/regex_automaton.tcc
index 759b053c5ef..e0ac3f94ceb 100644
--- a/libstdc++-v3/include/bits/regex_automaton.tcc
+++ b/libstdc++-v3/include/bits/regex_automaton.tcc
@@ -41,6 +41,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
switch (_M_opcode)
{
case _S_opcode_alternative:
+ case _S_opcode_repeat:
ostr << "alt next=" << _M_next << " alt=" << _M_alt;
break;
case _S_opcode_subexpr_begin:
@@ -72,11 +73,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
switch (_M_opcode)
{
case _S_opcode_alternative:
+ case _S_opcode_repeat:
__ostr << __id << " [label=\"" << __id << "\\nALT\"];\n"
<< __id << " -> " << _M_next
- << " [label=\"epsilon\", tailport=\"s\"];\n"
+ << " [label=\"next\", tailport=\"s\"];\n"
<< __id << " -> " << _M_alt
- << " [label=\"epsilon\", tailport=\"n\"];\n";
+ << " [label=\"alt\", tailport=\"n\"];\n";
break;
case _S_opcode_backref:
__ostr << __id << " [label=\"" << __id << "\\nBACKREF "
@@ -174,6 +176,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
== _S_opcode_dummy)
__it._M_next = (*this)[__it._M_next]._M_next;
if (__it._M_opcode == _S_opcode_alternative
+ || __it._M_opcode == _S_opcode_repeat
|| __it._M_opcode == _S_opcode_subexpr_lookahead)
while (__it._M_alt >= 0 && (*this)[__it._M_alt]._M_opcode
== _S_opcode_dummy)
@@ -197,20 +200,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// _M_insert_state() never return -1
auto __id = _M_nfa._M_insert_state(__dup);
__m[__u] = __id;
- if (__u == _M_end)
- continue;
- if (__dup._M_next != _S_invalid_state_id && __m[__dup._M_next] == -1)
- __stack.push(__dup._M_next);
if (__dup._M_opcode == _S_opcode_alternative
+ || __dup._M_opcode == _S_opcode_repeat
|| __dup._M_opcode == _S_opcode_subexpr_lookahead)
if (__dup._M_alt != _S_invalid_state_id && __m[__dup._M_alt] == -1)
__stack.push(__dup._M_alt);
+ if (__u == _M_end)
+ continue;
+ if (__dup._M_next != _S_invalid_state_id && __m[__dup._M_next] == -1)
+ __stack.push(__dup._M_next);
}
- long __size = static_cast<long>(__m.size());
- for (long __k = 0; __k < __size; __k++)
+ for (auto __v : __m)
{
- long __v;
- if ((__v = __m[__k]) == -1)
+ if (__v == -1)
continue;
auto& __ref = _M_nfa[__v];
if (__ref._M_next != _S_invalid_state_id)
@@ -219,6 +221,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__ref._M_next = __m[__ref._M_next];
}
if (__ref._M_opcode == _S_opcode_alternative
+ || __ref._M_opcode == _S_opcode_repeat
|| __ref._M_opcode == _S_opcode_subexpr_lookahead)
if (__ref._M_alt != _S_invalid_state_id)
{
diff --git a/libstdc++-v3/include/bits/regex_compiler.h b/libstdc++-v3/include/bits/regex_compiler.h
index f5a198f65e9..d7e21624e37 100644
--- a/libstdc++-v3/include/bits/regex_compiler.h
+++ b/libstdc++-v3/include/bits/regex_compiler.h
@@ -421,7 +421,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
void
_M_make_cache(true_type)
{
- for (int __i = 0; __i < _M_cache.size(); __i++)
+ for (size_t __i = 0; __i < _M_cache.size(); __i++)
_M_cache[static_cast<_UnsignedCharT>(__i)] =
_M_apply(__i, false_type());
}
diff --git a/libstdc++-v3/include/bits/regex_compiler.tcc b/libstdc++-v3/include/bits/regex_compiler.tcc
index 128dac12bd7..3cf9e457ccd 100644
--- a/libstdc++-v3/include/bits/regex_compiler.tcc
+++ b/libstdc++-v3/include/bits/regex_compiler.tcc
@@ -188,8 +188,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
__init();
auto __e = _M_pop();
- _StateSeqT __r(_M_nfa, _M_nfa._M_insert_alt(_S_invalid_state_id,
- __e._M_start, __neg));
+ _StateSeqT __r(_M_nfa, _M_nfa._M_insert_repeat(_S_invalid_state_id,
+ __e._M_start, __neg));
__e._M_append(__r);
_M_stack.push(__r);
}
@@ -197,8 +197,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
__init();
auto __e = _M_pop();
- __e._M_append(_M_nfa._M_insert_alt(_S_invalid_state_id, __e._M_start,
- __neg));
+ __e._M_append(_M_nfa._M_insert_repeat(_S_invalid_state_id,
+ __e._M_start, __neg));
_M_stack.push(__e);
}
else if (_M_match_token(_ScannerT::_S_token_opt))
@@ -206,8 +206,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
__init();
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, __neg));
+ _StateSeqT __r(_M_nfa, _M_nfa._M_insert_repeat(_S_invalid_state_id,
+ __e._M_start, __neg));
__e._M_append(__end);
__r._M_append(__end);
_M_stack.push(__r);
@@ -244,8 +244,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
auto __tmp = __r._M_clone();
_StateSeqT __s(_M_nfa,
- _M_nfa._M_insert_alt(_S_invalid_state_id,
- __tmp._M_start, __neg));
+ _M_nfa._M_insert_repeat(_S_invalid_state_id,
+ __tmp._M_start, __neg));
__tmp._M_append(__s);
__e._M_append(__s);
}
@@ -261,8 +261,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
for (long __i = 0; __i < __n; ++__i)
{
auto __tmp = __r._M_clone();
- auto __alt = _M_nfa._M_insert_alt(__tmp._M_start,
- __end, __neg);
+ auto __alt = _M_nfa._M_insert_repeat(__tmp._M_start,
+ __end, __neg);
__stack.push(__alt);
__e._M_append(_StateSeqT(_M_nfa, __alt, __tmp._M_end));
}
diff --git a/libstdc++-v3/include/bits/regex_executor.h b/libstdc++-v3/include/bits/regex_executor.h
index 708c78e2081..c110b88a3f4 100644
--- a/libstdc++-v3/include/bits/regex_executor.h
+++ b/libstdc++-v3/include/bits/regex_executor.h
@@ -73,6 +73,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_M_results(__results),
_M_match_queue(__dfs_mode ? nullptr
: new vector<pair<_StateIdT, _ResultsVec>>()),
+ _M_rep_count(_M_nfa.size()),
_M_visited(__dfs_mode ? nullptr : new vector<bool>(_M_nfa.size())),
_M_flags((__flags & regex_constants::match_prev_avail)
? (__flags
@@ -104,6 +105,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
private:
template<bool __match_mode>
void
+ _M_rep_once_more(_StateIdT);
+
+ template<bool __match_mode>
+ void
_M_dfs(_StateIdT __start);
template<bool __match_mode>
@@ -149,9 +154,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_ResultsVec& _M_results;
// Used in BFS, saving states that need to be considered for the next
// character.
- std::unique_ptr<vector<pair<_StateIdT, _ResultsVec>>> _M_match_queue;
+ unique_ptr<vector<pair<_StateIdT, _ResultsVec>>> _M_match_queue;
// Used in BFS, indicating that which state is already visited.
- std::unique_ptr<vector<bool>> _M_visited;
+ vector<pair<_BiIter, int>> _M_rep_count;
+ unique_ptr<vector<bool>> _M_visited;
_FlagT _M_flags;
// To record current solution.
_StateIdT _M_start_state;
diff --git a/libstdc++-v3/include/bits/regex_executor.tcc b/libstdc++-v3/include/bits/regex_executor.tcc
index 68a5e0490f9..7f8993382c8 100644
--- a/libstdc++-v3/include/bits/regex_executor.tcc
+++ b/libstdc++-v3/include/bits/regex_executor.tcc
@@ -161,7 +161,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
return false;
}
- // TODO: Use a function vector to dispatch, instead of using switch-case.
+ // __rep_count records how many times (__rep_count.second)
+ // this node is visited under certain input iterator
+ // (__rep_count.first). This prevent the executor from entering
+ // infinite loop by refusing to continue when it's already been
+ // visited more than twice. It's `twice` instead of `once` because
+ // we need to spare one more time for potential group capture.
+ template<typename _BiIter, typename _Alloc, typename _TraitsT,
+ bool __dfs_mode>
+ template<bool __match_mode>
+ void _Executor<_BiIter, _Alloc, _TraitsT, __dfs_mode>::
+ _M_rep_once_more(_StateIdT __i)
+ {
+ const auto& __state = _M_nfa[__i];
+ auto& __rep_count = _M_rep_count[__i];
+ if (__rep_count.second == 0 || __rep_count.first != _M_current)
+ {
+ auto __back = __rep_count;
+ __rep_count.first = _M_current;
+ __rep_count.second = 1;
+ _M_dfs<__match_mode>(__state._M_alt);
+ __rep_count = __back;
+ }
+ else
+ {
+ if (__rep_count.second < 2)
+ {
+ __rep_count.second++;
+ _M_dfs<__match_mode>(__state._M_alt);
+ __rep_count.second--;
+ }
+ }
+ };
+
template<typename _BiIter, typename _Alloc, typename _TraitsT,
bool __dfs_mode>
template<bool __match_mode>
@@ -184,69 +216,61 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// of this quantifier". Executing _M_next first or _M_alt first don't
// mean the same thing, and we need to choose the correct order under
// given greedy mode.
- case _S_opcode_alternative:
- // Greedy.
- if (!__state._M_neg)
- {
- // "Once more" is preferred in greedy mode.
- _M_dfs<__match_mode>(__state._M_alt);
- // If it's DFS executor and already accepted, we're done.
- if (!__dfs_mode || !_M_has_sol)
- _M_dfs<__match_mode>(__state._M_next);
- }
- else // Non-greedy mode
- {
- if (__dfs_mode)
- {
- // vice-versa.
+ case _S_opcode_repeat:
+ {
+ // Greedy.
+ if (!__state._M_neg)
+ {
+ _M_rep_once_more<__match_mode>(__i);
+ // If it's DFS executor and already accepted, we're done.
+ if (!__dfs_mode || !_M_has_sol)
_M_dfs<__match_mode>(__state._M_next);
- if (!_M_has_sol)
- _M_dfs<__match_mode>(__state._M_alt);
- }
- else
- {
- // DON'T attempt anything, because there's already another
- // state with higher priority accepted. This state cannot be
- // better by attempting its next node.
- if (!_M_has_sol)
- {
- _M_dfs<__match_mode>(__state._M_next);
- // DON'T attempt anything if it's already accepted. An
- // accepted state *must* be better than a solution that
- // matches a non-greedy quantifier one more time.
- if (!_M_has_sol)
- _M_dfs<__match_mode>(__state._M_alt);
- }
- }
+ }
+ else // Non-greedy mode
+ {
+ if (__dfs_mode)
+ {
+ // vice-versa.
+ _M_dfs<__match_mode>(__state._M_next);
+ if (!_M_has_sol)
+ _M_rep_once_more<__match_mode>(__i);
+ }
+ else
+ {
+ // DON'T attempt anything, because there's already another
+ // state with higher priority accepted. This state cannot be
+ // better by attempting its next node.
+ if (!_M_has_sol)
+ {
+ _M_dfs<__match_mode>(__state._M_next);
+ // DON'T attempt anything if it's already accepted. An
+ // accepted state *must* be better than a solution that
+ // matches a non-greedy quantifier one more time.
+ if (!_M_has_sol)
+ _M_rep_once_more<__match_mode>(__i);
+ }
+ }
+ }
}
break;
case _S_opcode_subexpr_begin:
- // If there's nothing changed since last visit, do NOT continue.
- // This prevents the executor from get into infinite loop when using
- // "()*" to match "".
- if (!_M_cur_results[__state._M_subexpr].matched
- || _M_cur_results[__state._M_subexpr].first != _M_current)
- {
- auto& __res = _M_cur_results[__state._M_subexpr];
- auto __back = __res.first;
- __res.first = _M_current;
- _M_dfs<__match_mode>(__state._M_next);
- __res.first = __back;
- }
+ {
+ auto& __res = _M_cur_results[__state._M_subexpr];
+ auto __back = __res.first;
+ __res.first = _M_current;
+ _M_dfs<__match_mode>(__state._M_next);
+ __res.first = __back;
+ }
break;
case _S_opcode_subexpr_end:
- if (_M_cur_results[__state._M_subexpr].second != _M_current
- || _M_cur_results[__state._M_subexpr].matched != true)
- {
- auto& __res = _M_cur_results[__state._M_subexpr];
- auto __back = __res;
- __res.second = _M_current;
- __res.matched = true;
- _M_dfs<__match_mode>(__state._M_next);
- __res = __back;
- }
- else
+ {
+ auto& __res = _M_cur_results[__state._M_subexpr];
+ auto __back = __res;
+ __res.second = _M_current;
+ __res.matched = true;
_M_dfs<__match_mode>(__state._M_next);
+ __res = __back;
+ }
break;
case _S_opcode_line_begin_assertion:
if (_M_at_begin())
@@ -339,6 +363,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
break;
+ case _S_opcode_alternative:
+ _M_dfs<__match_mode>(__state._M_alt);
+ if (!__dfs_mode || !_M_has_sol)
+ _M_dfs<__match_mode>(__state._M_next);
+ break;
default:
_GLIBCXX_DEBUG_ASSERT(false);
}
diff --git a/libstdc++-v3/include/bits/regex_scanner.tcc b/libstdc++-v3/include/bits/regex_scanner.tcc
index 5332d2eff84..f501ff6c2cb 100644
--- a/libstdc++-v3/include/bits/regex_scanner.tcc
+++ b/libstdc++-v3/include/bits/regex_scanner.tcc
@@ -335,7 +335,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
else if (__c == 'x' || __c == 'u')
{
_M_value.erase();
- for (int i = 0; i < (__c == 'x' ? 2 : 4); i++)
+ for (int __i = 0; __i < (__c == 'x' ? 2 : 4); __i++)
{
if (_M_current == _M_end
|| !_M_ctype.is(_CtypeT::xdigit, *_M_current))
diff --git a/libstdc++-v3/include/experimental/optional b/libstdc++-v3/include/experimental/optional
index 5f2d93fb7f6..2a3f29dcd70 100644
--- a/libstdc++-v3/include/experimental/optional
+++ b/libstdc++-v3/include/experimental/optional
@@ -736,12 +736,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
template<typename _Tp>
constexpr bool
operator!=(const optional<_Tp>& __lhs, _Tp const& __rhs)
- { return !__lhs || *__lhs != __rhs; }
+ { return !__lhs || !(*__lhs == __rhs); }
template<typename _Tp>
constexpr bool
operator!=(const _Tp& __lhs, const optional<_Tp>& __rhs)
- { return !__rhs || __lhs != *__rhs; }
+ { return !__rhs || !(__lhs == *__rhs); }
template<typename _Tp>
constexpr bool
diff --git a/libstdc++-v3/include/tr1/regex b/libstdc++-v3/include/tr1/regex
index 3cff23a2656..0387472ddcc 100644
--- a/libstdc++-v3/include/tr1/regex
+++ b/libstdc++-v3/include/tr1/regex
@@ -678,7 +678,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__ctype.is(__c, __f))
return true;
-
+#if 0
// special case of underscore in [[:w:]]
if (__c == __ctype.widen('_'))
{
@@ -698,7 +698,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
if (__f | __bt)
return true;
}
-
+#endif
return false;
}
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
index 3fdbdadedbe..c33d1b61894 100644
--- 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
@@ -50,6 +50,7 @@ test01()
const char s[] = "";
VERIFY( regex_match_debug(s, m, re) );
}
+ VERIFY(regex_match_debug("", regex("(?:)*")));
}
int
diff --git a/libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc b/libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc
index 5670cbb8e3b..8243eea930a 100644
--- a/libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc
+++ b/libstdc++-v3/testsuite/28_regex/basic_regex/multiple_quantifiers.cc
@@ -21,7 +21,10 @@
// Tests multiple consecutive quantifiers
#include <regex>
+#include <testsuite_hooks.h>
+#include <testsuite_regex.h>
+using namespace __gnu_test;
using namespace std;
int
@@ -29,5 +32,6 @@ main()
{
regex re1("a++");
regex re2("(a+)+");
+ VERIFY(regex_match_debug("aa", regex("(a)*{3}")));
return 0;
}
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/1.cc b/libstdc++-v3/testsuite/experimental/optional/relops/1.cc
index f1408805ac2..3f1ee9c4900 100644
--- a/libstdc++-v3/testsuite/experimental/optional/relops/1.cc
+++ b/libstdc++-v3/testsuite/experimental/optional/relops/1.cc
@@ -37,10 +37,6 @@ namespace ns
{ return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
bool
- operator!=(value_type const& lhs, value_type const& rhs)
- { return !(lhs == rhs); }
-
- bool
operator<(value_type const& lhs, value_type const& rhs)
{ return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/2.cc b/libstdc++-v3/testsuite/experimental/optional/relops/2.cc
index c7fc848deb0..6ee9cba768a 100644
--- a/libstdc++-v3/testsuite/experimental/optional/relops/2.cc
+++ b/libstdc++-v3/testsuite/experimental/optional/relops/2.cc
@@ -37,10 +37,6 @@ namespace ns
{ return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
bool
- operator!=(value_type const& lhs, value_type const& rhs)
- { return !(lhs == rhs); }
-
- bool
operator<(value_type const& lhs, value_type const& rhs)
{ return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/3.cc b/libstdc++-v3/testsuite/experimental/optional/relops/3.cc
index 9729000d5ca..581d0168fbc 100644
--- a/libstdc++-v3/testsuite/experimental/optional/relops/3.cc
+++ b/libstdc++-v3/testsuite/experimental/optional/relops/3.cc
@@ -37,10 +37,6 @@ namespace ns
{ return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
bool
- operator!=(value_type const& lhs, value_type const& rhs)
- { return !(lhs == rhs); }
-
- bool
operator<(value_type const& lhs, value_type const& rhs)
{ return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/4.cc b/libstdc++-v3/testsuite/experimental/optional/relops/4.cc
index 45378f688e4..ce16fcb92f5 100644
--- a/libstdc++-v3/testsuite/experimental/optional/relops/4.cc
+++ b/libstdc++-v3/testsuite/experimental/optional/relops/4.cc
@@ -37,10 +37,6 @@ namespace ns
{ return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
bool
- operator!=(value_type const& lhs, value_type const& rhs)
- { return !(lhs == rhs); }
-
- bool
operator<(value_type const& lhs, value_type const& rhs)
{ return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/5.cc b/libstdc++-v3/testsuite/experimental/optional/relops/5.cc
index 008409ef402..c01bba57a5e 100644
--- a/libstdc++-v3/testsuite/experimental/optional/relops/5.cc
+++ b/libstdc++-v3/testsuite/experimental/optional/relops/5.cc
@@ -37,10 +37,6 @@ namespace ns
{ return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
bool
- operator!=(value_type const& lhs, value_type const& rhs)
- { return !(lhs == rhs); }
-
- bool
operator<(value_type const& lhs, value_type const& rhs)
{ return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
diff --git a/libstdc++-v3/testsuite/experimental/optional/relops/6.cc b/libstdc++-v3/testsuite/experimental/optional/relops/6.cc
index b17914062ee..a24622b5f40 100644
--- a/libstdc++-v3/testsuite/experimental/optional/relops/6.cc
+++ b/libstdc++-v3/testsuite/experimental/optional/relops/6.cc
@@ -37,10 +37,6 @@ namespace ns
{ return std::tie(lhs.i, lhs.s) == std::tie(rhs.i, rhs.s); }
bool
- operator!=(value_type const& lhs, value_type const& rhs)
- { return !(lhs == rhs); }
-
- bool
operator<(value_type const& lhs, value_type const& rhs)
{ return std::tie(lhs.i, lhs.s) < std::tie(rhs.i, rhs.s); }
diff --git a/libstdc++-v3/testsuite/util/testsuite_abi.cc b/libstdc++-v3/testsuite/util/testsuite_abi.cc
index 6b5299b8e7e..39635cb2fca 100644
--- a/libstdc++-v3/testsuite/util/testsuite_abi.cc
+++ b/libstdc++-v3/testsuite/util/testsuite_abi.cc
@@ -210,6 +210,7 @@ check_version(symbol& test, bool added)
known_versions.push_back("CXXABI_1.3.6");
known_versions.push_back("CXXABI_1.3.7");
known_versions.push_back("CXXABI_1.3.8");
+ known_versions.push_back("CXXABI_1.3.9");
known_versions.push_back("CXXABI_TM_1");
}
compat_list::iterator begin = known_versions.begin();
@@ -227,7 +228,7 @@ check_version(symbol& test, bool added)
// Check that added symbols are added in the latest pre-release version.
bool latestp = (test.version_name == "GLIBCXX_3.4.20"
- || test.version_name == "CXXABI_1.3.8"
+ || test.version_name == "CXXABI_1.3.9"
|| test.version_name == "CXXABI_TM_1");
if (added && !latestp)
test.version_status = symbol::incompatible;
diff --git a/libstdc++-v3/testsuite/util/testsuite_regex.h b/libstdc++-v3/testsuite/util/testsuite_regex.h
index 9460ed6ae31..c2031e90a23 100644
--- a/libstdc++-v3/testsuite/util/testsuite_regex.h
+++ b/libstdc++-v3/testsuite/util/testsuite_regex.h
@@ -131,7 +131,7 @@ namespace __gnu_test
// regex_match_debug behaves like regex_match, but will run *two* executors
// (if there's no back-reference) and check if their results agree. If not,
- // an exception throws. One can use them just in the way of using regex_match.
+ // an exception is thrown. The arguments are the same as for regex_match.
template<typename _Bi_iter, typename _Alloc,
typename _Ch_type, typename _Rx_traits>
bool
@@ -153,7 +153,7 @@ namespace __gnu_test
// __m is unspecified if return value is false.
if (__res1 == __res2 && (!__res1 || __m == __mm))
return __res1;
- throw(std::exception());
+ throw std::exception();
}
// No match_results version