From 0542f54a43816b0b2d20361053d753fc448b8427 Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Thu, 26 Feb 2015 11:16:54 +0100 Subject: [PATCH 01/16] bmake.1: Add missing newline. --- contrib/bmake/bmake.1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/bmake/bmake.1 b/contrib/bmake/bmake.1 index bfa86761a4..fdf356bcf9 100644 --- a/contrib/bmake/bmake.1 +++ b/contrib/bmake/bmake.1 @@ -899,7 +899,8 @@ The parent process-id of .Nm . .It Va .MAKE.BUILT.BY The compiler CCVER that built the -.Dx world. +.Dx +world. .It Va MAKE_PRINT_VAR_ON_ERROR When .Nm -- 2.41.0 From cb1ce5292c83c9eb243667f8534ac508645a694e Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Thu, 26 Feb 2015 11:47:05 +0100 Subject: [PATCH 02/16] devd(8): Add -Wno-unused-local-typedefs to CFLAGS for now. The issue is that with -Wunused-local-typedefs, our GCC 5.0 warns about unused local typedefs in its own headers, in this case stl_algo.h which comes in via , which devd(8) includes. Example: c++ [...] -Werror -Wall [...] -c devd.cc In file included from /usr/include/c++/5.0/bits/stl_algo.h:61:0, from /usr/include/c++/5.0/algorithm:62, from devd.cc:93: /usr/include/c++/5.0/bits/stl_heap.h: In function 'void std::pop_heap(_RAIter, _RAIter)': /usr/include/c++/5.0/bits/stl_heap.h:266:2: error: typedef '_ValueType' locally defined but not used [-Werror=unused-local-typedefs] _ValueType; ^ [...] More typedefs are warned about, _InputValueType, _OutputValueType, and _DistanceType. --- sbin/devd/Makefile | 6 ++++++ share/mk/sys.mk | 6 ------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sbin/devd/Makefile b/sbin/devd/Makefile index 9f5348dc43..af0d5d7212 100644 --- a/sbin/devd/Makefile +++ b/sbin/devd/Makefile @@ -13,6 +13,12 @@ LDADD= -ll -lutil YFLAGS+=-v CFLAGS+=-I. -I${.CURDIR} +# XXX gcc50 (at least) warns about its own C++ headers with +# -Wunused-local-typedefs, so disable until fixed +# +.if (${CCVER:Mgcc4[89]} || ${CCVER:Mgcc5*}) +CXXFLAGS+=-Wno-unused-local-typedefs +.endif CLEANFILES= y.output diff --git a/share/mk/sys.mk b/share/mk/sys.mk index 28eeb5da40..39968792e7 100644 --- a/share/mk/sys.mk +++ b/share/mk/sys.mk @@ -60,12 +60,6 @@ CXX_LINK ?= ${CXX} NXCXX ?= ${NXENV} ${CXX} NXCXX_LINK ?= ${NXENV} ${CXX_LINK} CXXFLAGS ?= ${CXXINCLUDES} ${CFLAGS:N-std=*:N-Wnested-externs:N-W*-prototypes:N-Wno-pointer-sign:N-Wold-style-definition} -# XXX gcc50 (at least) warns about its own C++ headers with -# -Wunused-local-typedefs, so disable until fixed -# -.if defined(CCVER) && (${CCVER:Mgcc4[89]} || ${CCVER:Mgcc5*}) -CXXFLAGS += -Wno-unused-local-typedefs -.endif .if !defined(SYSBUILD) && defined(.MAKE.BUILT.BY) && ${.MAKE.BUILT.BY:Mgcc47} CXXFLAGS += -D_GLIBCXX_USE_CXX11_ABI=0 .endif -- 2.41.0 From e94bae9a34bf3de4b8cb4b58166ad1fedfdc25b9 Mon Sep 17 00:00:00 2001 From: Markus Pfeiffer Date: Thu, 26 Feb 2015 12:39:16 +0000 Subject: [PATCH 03/16] netif/if_lagg: Fix panic on MOD_UNLOAD Remove one instance of if_clone_detach being called. Reported-By: bycn82 --- sys/net/lagg/if_lagg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/net/lagg/if_lagg.c b/sys/net/lagg/if_lagg.c index 5fb022c54c..9f2182279f 100644 --- a/sys/net/lagg/if_lagg.c +++ b/sys/net/lagg/if_lagg.c @@ -222,7 +222,6 @@ lagg_modevent(module_t mod, int type, void *data) case MOD_UNLOAD: EVENTHANDLER_DEREGISTER(ifnet_departure_event, lagg_detach_cookie); - if_clone_detach(&lagg_cloner); lagg_input_p = NULL; if_clone_detach(&lagg_cloner); lockuninit(&lagg_list_lock); -- 2.41.0 From 7124a27841442f31d0e649b103eb5d01b192825b Mon Sep 17 00:00:00 2001 From: Sascha Wildner Date: Thu, 26 Feb 2015 13:40:51 +0100 Subject: [PATCH 04/16] Nuke /usr/share/examples/cvsup. Now that i386 is no longer supported we can't even run an old FreeBSD cvsup binary anymore, so all this has become completely pointless. FreeBSD has since switched to SVN, NetBSD's repository can be rsync'ed, about OpenBSD I am not sure though. There are git repos of various BSDs too. --- Makefile_upgrade.inc | 1 + etc/mtree/BSD.usr.dist | 2 - share/examples/cvsup/FreeBSD-supfile | 207 --------------------------- share/examples/cvsup/NetBSD-supfile | 57 -------- share/examples/cvsup/OpenBSD-supfile | 52 ------- share/examples/cvsup/README | 36 ----- 6 files changed, 1 insertion(+), 354 deletions(-) delete mode 100644 share/examples/cvsup/FreeBSD-supfile delete mode 100644 share/examples/cvsup/NetBSD-supfile delete mode 100644 share/examples/cvsup/OpenBSD-supfile delete mode 100644 share/examples/cvsup/README diff --git a/Makefile_upgrade.inc b/Makefile_upgrade.inc index 0d41f8790e..7707455eab 100644 --- a/Makefile_upgrade.inc +++ b/Makefile_upgrade.inc @@ -2824,6 +2824,7 @@ TO_REMOVE+=/usr/share/man/man3/libhammer_get_volinfo.3.gz TO_REMOVE+=/usr/share/man/cat3/libhammer_get_volinfo.3.gz TO_REMOVE+=/usr/share/man/man3/libhammer_free_volinfo.3.gz TO_REMOVE+=/usr/share/man/cat3/libhammer_free_volinfo.3.gz +TO_REMOVE+=/usr/share/examples/cvsup .if ${MACHINE_ARCH} == "x86_64" TO_REMOVE+=/usr/sbin/stlstats diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index 78bf5c3849..e701d25a2f 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -157,8 +157,6 @@ contrib .. .. - cvsup - .. diskless .. drivers diff --git a/share/examples/cvsup/FreeBSD-supfile b/share/examples/cvsup/FreeBSD-supfile deleted file mode 100644 index c1750f066a..0000000000 --- a/share/examples/cvsup/FreeBSD-supfile +++ /dev/null @@ -1,207 +0,0 @@ -# $FreeBSD: src/share/examples/cvsup/cvs-supfile,v 1.48 2008/03/13 22:36:02 edwin Exp $ -# -# This file contains all of the "CVSup collections" that make up the -# CVS development tree of the FreeBSD system. -# -# CVSup (CVS Update Protocol) allows you to download the latest CVS -# tree (or any branch of development therefrom) to your system easily -# and efficiently (far more so than with sup, which CVSup is aimed -# at replacing). If you're running CVSup interactively, and are -# currently using an X display server, you should run CVSup as follows -# to keep your CVS tree up-to-date: -# -# cvsup cvs-supfile -# -# If not running X, or invoking cvsup from a non-interactive script, then -# run it as follows: -# -# cvsup -g -L 2 cvs-supfile -# -# You may wish to change some of the settings in this file to better -# suit your system: -# -# host=CHANGE_THIS.FreeBSD.org -# This specifies the server host which will supply the -# file updates. You must change it to one of the CVSup -# mirror sites listed in the FreeBSD Handbook at -# http://www.freebsd.org/doc/handbook/mirrors.html. -# You can override this setting on the command line -# with cvsup's "-h host" option. -# -# base=/usr -# This specifies the root where CVSup will store information -# about the collections you have transferred to your system. -# A setting of "/usr" will generate this information in -# /usr/sup. You can override the "base" setting on the -# command line with cvsup's "-b base" option. This directory -# must exist in order to run CVSup. -# -# prefix=/home/ncvs -# This specifies where to place the requested files. A -# setting of "/home/ncvs" will place all of the files -# requested in /home/ncvs (e.g., "/home/ncvs/src/bin", -# "/home/ncvs/ports/archivers"). The prefix directory -# must exist in order to run CVSup. - -# Defaults that apply to all the collections -# -# IMPORTANT: Change the next line to use one of the CVSup mirror sites -# listed at http://www.freebsd.org/doc/handbook/mirrors.html. -*default host=CHANGE_THIS.FreeBSD.org -*default base=/usr -*default prefix=/home/ncvs -*default release=cvs -*default delete use-rel-suffix - -# If you seem to be limited by CPU rather than network or disk bandwidth, try -# commenting out the following line. (Normally, today's CPUs are fast enough -# that you want to run compression.) -*default compress - -## Main Source Tree. -# -# The easiest way to get the main source tree is to use the "src-all" -# mega-collection. It includes all of the individual "src-*" collections. -src-all - -# These are the individual collections that make up "src-all". If you -# use these, be sure to comment out "src-all" above. -#src-base -#src-bin -#src-cddl -#src-contrib -#src-etc -#src-games -#src-gnu -#src-include -#src-kerberos5 -#src-kerberosIV -#src-lib -#src-libexec -#src-release -#src-rescue -#src-sbin -#src-share -#src-sys -#src-tools -#src-usrbin -#src-usrsbin -# These are the individual collections that make up FreeBSD's crypto -# collection. They are no longer export-restricted and are a part of -# src-all -#src-crypto -#src-eBones -#src-secure -#src-sys-crypto - -## Ports Collection. -# -# The easiest way to get the ports tree is to use the "ports-all" -# mega-collection. It includes all of the individual "ports-*" -# collections, -ports-all - -# These are the individual collections that make up "ports-all". If you -# use these, be sure to comment out "ports-all" above and always include -# "ports-base" if you use any of the other individual collections below. -# Your ports may not build correctly without an up-to-date "ports-base". -# -#ports-base -# -#ports-accessibility -#ports-arabic -#ports-archivers -#ports-astro -#ports-audio -#ports-benchmarks -#ports-biology -#ports-cad -#ports-chinese -#ports-comms -#ports-converters -#ports-databases -#ports-deskutils -#ports-devel -#ports-dns -#ports-editors -#ports-emulators -#ports-finance -#ports-french -#ports-ftp -#ports-games -#ports-german -#ports-graphics -#ports-hebrew -#ports-hungarian -#ports-irc -#ports-japanese -#ports-java -#ports-korean -#ports-lang -#ports-mail -#ports-math -#ports-mbone -#ports-misc -#ports-multimedia -#ports-net -#ports-net-im -#ports-net-mgmt -#ports-net-p2p -#ports-news -#ports-palm -#ports-picobsd -#ports-polish -#ports-ports-mgmt -#ports-portuguese -#ports-print -#ports-russian -#ports-science -#ports-security -#ports-shells -#ports-sysutils -#ports-textproc -#ports-ukrainian -#ports-vietnamese -#ports-www -#ports-x11 -#ports-x11-clocks -#ports-x11-drivers -#ports-x11-fm -#ports-x11-fonts -#ports-x11-servers -#ports-x11-themes -#ports-x11-toolkits -#ports-x11-wm - -## Documentation -# -# The easiest way to get the doc tree is to use the "doc-all" -# mega-collection. It includes all of the individual "doc-*" -# collections, -doc-all - -## Website -# -# This collection retrieves the www tree of the FreeBSD -# repository -www - -## Projects -# -# This collection retrieves the projects tree of the FreeBSD -# repository -projects-all - -## CVSROOT control files -# -# This is to get the control files that cvs(1) needs and the commit logs. -cvsroot-all - -# These are the individual collections that make up "cvsroot-all" If you -# use these, be sure to comment out "cvsroot-all" above. "cvsroot-common" -# is a synthetic CVSROOT that has all the modules from the other CVSROOT-* -# directories merged into one, and merged commitlogs via symlinks. -#cvsroot-common -#cvsroot-src -#cvsroot-ports -#cvsroot-doc diff --git a/share/examples/cvsup/NetBSD-supfile b/share/examples/cvsup/NetBSD-supfile deleted file mode 100644 index 0e020bfdb7..0000000000 --- a/share/examples/cvsup/NetBSD-supfile +++ /dev/null @@ -1,57 +0,0 @@ -# $NetBSD: netbsd-supfile,v 1.1 2007/06/09 11:32:56 dsieger Exp $ -# $DragonFly: src/share/examples/cvsup/NetBSD-supfile,v 1.3 2008/02/10 22:25:36 swildner Exp $ -# -# NETBSD-CVS-SUPFILE -# -# This file will by default maintain a copy of the NetBSD CVS tree in -# /home/nbcvs -# -# A list of NetBSD CVSup mirrors is available at -# -# http://www.netbsd.org/mirrors/#cvsup -# -# If not running X, or invoking cvsup from a non-interactive script, then -# run it as follows: -# -# cvsup -g -L 2 netbsd-supfile -# -# You may wish to change some of the settings in this file to better -# suit your system: -# -# host= -# This specifies the server host which will supply the -# file updates. -# -# base=/usr -# This specifies the root where CVSup will store information -# about the collections you have transferred to your system. -# A setting of "/usr" will generate this information in -# /usr/sup. You can override the "base" setting on the -# command line with cvsup's "-b base" option. This directory -# must exist in order to run CVSup. -# -# prefix=/home/nbcvs -# This specifies where to place the requested files. A -# setting of "/home/nbcvs" will place all of the files -# requested in /home/nbcvs (e.g., "/home/nbcvs/src/bin"). -# The prefix directory must exist in order to run CVSup. -# -*default host=CHANGE_THIS.NetBSD.org -*default base=/usr -*default prefix=/home/nbcvs -*default release=cvs -*default delete use-rel-suffix -*default compress - -# If you want all tree we have, use this line. -netbsd - -# smaller collections -#netbsd-basesrc -#netbsd-cryptosrc-intl -#netbsd-doc -#netbsd-gnusrc -#netbsd-pkgsrc -#netbsd-sharesrc -#netbsd-syssrc -#netbsd-xsrc diff --git a/share/examples/cvsup/OpenBSD-supfile b/share/examples/cvsup/OpenBSD-supfile deleted file mode 100644 index 525b5974de..0000000000 --- a/share/examples/cvsup/OpenBSD-supfile +++ /dev/null @@ -1,52 +0,0 @@ -# $DragonFly: src/share/examples/cvsup/OpenBSD-supfile,v 1.4 2008/02/10 22:32:19 swildner Exp $ -# -# OPENBSD-CVS-SUPFILE -# -# This file will by default maintain a copy of the OpenBSD CVS tree in -# /home/obcvs -# -# A list of OpenBSD CVSup mirrors is available at: -# -# http://www.openbsd.org/cvsup.html#CVSROOT -# -# If not running X, or invoking cvsup from a non-interactive script, then -# run it as follows: -# -# cvsup -g -L 2 openbsd-supfile -# -# You may wish to change some of the settings in this file to better -# suit your system: -# -# host= -# This specifies the server host which will supply the -# file updates. -# -# base=/usr -# This specifies the root where CVSup will store information -# about the collections you have transferred to your system. -# A setting of "/usr" will generate this information in -# /usr/sup. You can override the "base" setting on the -# command line with cvsup's "-b base" option. This directory -# must exist in order to run CVSup. -# -# prefix=/home/obcvs -# This specifies where to place the requested files. A -# setting of "/home/obcvs" will place all of the files -# requested in /home/obcvs (e.g., "/home/obcvs/src/bin", -# "/home/obcvs/ports/archivers"). The prefix directory -# must exist in order to run CVSup. -# -*default host=CHANGE_THIS.openbsd.org -*default base=/usr -*default prefix=/home/obcvs -*default release=cvs -*default delete use-rel-suffix -*default compress - -OpenBSD-all -#OpenBSD-src -#OpenBSD-www -#OpenBSD-ports -#OpenBSD-x11 -#OpenBSD-xf4 -#OpenBSD-xenocara diff --git a/share/examples/cvsup/README b/share/examples/cvsup/README deleted file mode 100644 index 892133bfce..0000000000 --- a/share/examples/cvsup/README +++ /dev/null @@ -1,36 +0,0 @@ -# $FreeBSD: src/share/examples/cvsup/README,v 1.15.2.5 2002/12/03 05:58:04 kuriyama Exp $ -# $DragonFly: src/share/examples/cvsup/README,v 1.9 2008/07/08 11:59:15 thomas Exp $ - -This directory contains sample "supfiles" for obtaining and updating -the various BSDs via the Internet. These supfiles will work with -CVSup version 14.0 or later. For general information on CVSup -itself, please see http://www.dragonflybsd.org/docs/handbook/handbook-cvsup/ . -You can use net/csup from NetBSD pkgsrc collection to check out -the source tree, or devel/cvsync to retrieve the CVS repository files, -from a CVSup server. - -To maintain the sources for FreeBSD, use: - - FreeBSD-supfile Main source tree for FreeBSD - - A list of mirrors is maintained at: - - http://www.freebsd.org/doc/handbook/cvsup.html#CVSUP-MIRRORS - - -To maintain the sources for NetBSD, use: - - NetBSD-supfile Main source tree for NetBSD - - A list of mirrors is maintained at: - - http://www.netbsd.org/mirrors/#cvsup - - -To maintain the sources for OpenBSD, use: - - OpenBSD-supfile Main source tree for OpenBSD - - A list of mirrors is maintained at: - - http://www.openbsd.org/cvsup.html#CVSROOT -- 2.41.0 From dc241916e10102adde2a9c28e3cd7927ce184206 Mon Sep 17 00:00:00 2001 From: Tomohiro Kusumi Date: Thu, 26 Feb 2015 20:25:59 +0900 Subject: [PATCH 05/16] sys/vfs/hammer: Fix and add comments on root inode - hunk1 - The root inode uses HAMMER_DEF_LOCALIZATION for its onmemory ip(inode) localization, however the purpose of this macro is not documented anywhere. Make it clear by adding this comment. - hunk2 - Show HAMMER_OBJID_ROOT is the root inode # for both real root inode and PFS root inodes. - hunk3-4 - Change "stored in the root inode" to "associated with the root inode". PFS records are not embedded within the ondisk inode structure, but associated with the root inode by id. Commit ea434b6f uses "associated with" in its commit message. --- sys/vfs/hammer/hammer_btree.h | 3 +++ sys/vfs/hammer/hammer_disk.h | 2 +- sys/vfs/hammer/hammer_inode.c | 8 ++++++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/sys/vfs/hammer/hammer_btree.h b/sys/vfs/hammer/hammer_btree.h index 60f1068337..99eb17c259 100644 --- a/sys/vfs/hammer/hammer_btree.h +++ b/sys/vfs/hammer/hammer_btree.h @@ -118,6 +118,9 @@ typedef struct hammer_base_elm *hammer_base_elm_t; * Localization can also be used to create pseudo-filesystems within * a HAMMER filesystem. Pseudo-filesystems would be suitable * replication targets. + * + * The root inode (not the PFS root inode but the real root) uses + * HAMMER_DEF_LOCALIZATION for its ip->obj_localization. */ #define HAMMER_LOCALIZE_RESERVED00 0x00000000 #define HAMMER_LOCALIZE_INODE 0x00000001 diff --git a/sys/vfs/hammer/hammer_disk.h b/sys/vfs/hammer/hammer_disk.h index d507314fb3..8838d4b43b 100644 --- a/sys/vfs/hammer/hammer_disk.h +++ b/sys/vfs/hammer/hammer_disk.h @@ -749,7 +749,7 @@ struct hammer_inode_data { offsetof(struct hammer_inode_data, mtime) #define HAMMER_INODE_DATA_VERSION 1 -#define HAMMER_OBJID_ROOT 1 +#define HAMMER_OBJID_ROOT 1 /* root inodes # */ #define HAMMER_INODE_BASESYMLEN 24 /* see ext.symlink */ /* diff --git a/sys/vfs/hammer/hammer_inode.c b/sys/vfs/hammer/hammer_inode.c index 33a6a88ffb..b3e91fc28a 100644 --- a/sys/vfs/hammer/hammer_inode.c +++ b/sys/vfs/hammer/hammer_inode.c @@ -991,8 +991,8 @@ retry: } /* - * PFS records are stored in the root inode (not the PFS root inode, - * but the real root). Avoid an infinite recursion if loading + * PFS records are associated with the root inode (not the PFS root + * inode, but the real root). Avoid an infinite recursion if loading * the PFS for the real root. */ if (localization) { @@ -1063,6 +1063,10 @@ hammer_save_pseudofs(hammer_transaction_t trans, hammer_pseudofs_inmem_t pfsm) hammer_inode_t ip; int error; + /* + * PFS records are associated with the root inode (not the PFS root + * inode, but the real root). + */ ip = hammer_get_inode(trans, NULL, HAMMER_OBJID_ROOT, HAMMER_MAX_TID, HAMMER_DEF_LOCALIZATION, 0, &error); retry: -- 2.41.0 From 38c04e647523b42b168ebf9b328619ba8992824e Mon Sep 17 00:00:00 2001 From: Tomohiro Kusumi Date: Thu, 26 Feb 2015 20:36:42 +0900 Subject: [PATCH 06/16] sbin/newfs_hammer: Properly set ondisk localization value - Make hammer_newfs properly set ondisk localization for the first two elements (for root inode and PFS) of the root node. - HAMMER does cursor lookup using sum of onmemory ip(inode) localization and localization type, so in this case hammer_newfs needs to write ondisk bits using (HAMMER_DEF_LOCALIZATION + type) instead of just a type (see hammer_get_inode() and hammer_load_pseudofs() for details). - It makes no binary difference since HAMMER_DEF_LOCALIZATION is 0, however it should be fixed for the consistency (e.g. if the macro happens to be defined differently, although it is not likely as it forces ondisk layout change). --- sbin/newfs_hammer/newfs_hammer.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sbin/newfs_hammer/newfs_hammer.c b/sbin/newfs_hammer/newfs_hammer.c index f0a3920f43..6065baf35f 100644 --- a/sbin/newfs_hammer/newfs_hammer.c +++ b/sbin/newfs_hammer/newfs_hammer.c @@ -655,7 +655,8 @@ format_root(const char *label) elm = &bnode->elms[0]; elm->leaf.base.btype = HAMMER_BTREE_TYPE_RECORD; - elm->leaf.base.localization = HAMMER_LOCALIZE_INODE; + elm->leaf.base.localization = HAMMER_DEF_LOCALIZATION + + HAMMER_LOCALIZE_INODE; elm->leaf.base.obj_id = HAMMER_OBJID_ROOT; elm->leaf.base.key = 0; elm->leaf.base.create_tid = create_tid; @@ -670,7 +671,8 @@ format_root(const char *label) elm = &bnode->elms[1]; elm->leaf.base.btype = HAMMER_BTREE_TYPE_RECORD; - elm->leaf.base.localization = HAMMER_LOCALIZE_MISC; + elm->leaf.base.localization = HAMMER_DEF_LOCALIZATION + + HAMMER_LOCALIZE_MISC; elm->leaf.base.obj_id = HAMMER_OBJID_ROOT; elm->leaf.base.key = 0; elm->leaf.base.create_tid = create_tid; -- 2.41.0 From dbe50d5473a314313989fa7ef8073c9d2acc4fbd Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Thu, 26 Feb 2015 20:23:56 +0800 Subject: [PATCH 07/16] acpi/pstate: Allow user to force package level P-state domain Some CPUs only have package P-states, but some BIOSes put each hyperthread to its own P-state domain; allow user to override. It is not enabled by default. --- sys/dev/acpica/acpi_cpu_pstate.c | 54 +++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/sys/dev/acpica/acpi_cpu_pstate.c b/sys/dev/acpica/acpi_cpu_pstate.c index 2becab875d..9f9f082334 100644 --- a/sys/dev/acpica/acpi_cpu_pstate.c +++ b/sys/dev/acpica/acpi_cpu_pstate.c @@ -162,6 +162,9 @@ static const struct acpi_pst_md *acpi_pst_md; static int acpi_pst_ht_reuse_domain = 1; TUNABLE_INT("hw.acpi.cpu.pst.ht_reuse_domain", &acpi_pst_ht_reuse_domain); +static int acpi_pst_force_pkg_domain = 0; +TUNABLE_INT("hw.acpi.cpu.pst.force_pkg_domain", &acpi_pst_force_pkg_domain); + static device_method_t acpi_pst_methods[] = { /* Device interface */ DEVMETHOD(device_probe, acpi_pst_probe), @@ -297,7 +300,7 @@ done: static int acpi_pst_attach(device_t dev) { - struct acpi_pst_softc *sc = device_get_softc(dev), *pst; + struct acpi_pst_softc *sc = device_get_softc(dev); struct acpi_pst_domain *dom = NULL; ACPI_BUFFER buf; ACPI_STATUS status; @@ -383,6 +386,8 @@ acpi_pst_attach(device_t dev) buf.Length = ACPI_ALLOCATE_BUFFER; status = AcpiEvaluateObject(sc->pst_handle, "_PCT", NULL, &buf); if (ACPI_FAILURE(status)) { + struct acpi_pst_softc *pst; + /* * No _PCT. See the comment in acpi_pst_probe() near * _PSD check. @@ -643,6 +648,53 @@ fetch_ppc: sc->pst_state = sc->pst_sstart; + /* + * Some CPUs only have package P-states, but some BIOSes put each + * hyperthread to its own P-state domain; allow user to override. + */ + if (LIST_EMPTY(&dom->pd_pstlist) && acpi_pst_force_pkg_domain) { + cpumask_t mask; + + mask = get_cpumask_from_level(sc->pst_cpuid, CHIP_LEVEL); + if (CPUMASK_TESTNZERO(mask)) { + struct acpi_pst_softc *pst = NULL; + struct acpi_pst_domain *dom1; + + LIST_FOREACH(dom1, &acpi_pst_domains, pd_link) { + LIST_FOREACH(pst, &dom1->pd_pstlist, + pst_link) { + if (CPUMASK_TESTBIT(mask, + pst->pst_cpuid)) + break; + } + if (pst != NULL) + break; + } + if (pst != NULL && + memcmp(&pst->pst_creg, &sc->pst_creg, + sizeof(sc->pst_creg)) == 0 && + memcmp(&pst->pst_sreg, &sc->pst_sreg, + sizeof(sc->pst_sreg)) == 0) { + /* + * Use the same domain for CPUs in the + * same package. + */ + device_printf(dev, "Destroy domain%u, " + "force pkg domain%u\n", + dom->pd_dom, dom1->pd_dom); + LIST_REMOVE(dom, pd_link); + kfree(dom, M_DEVBUF); + dom = dom1; + /* + * Make sure that adding us will not + * overflow the domain containing + * siblings in the same package. + */ + acpi_pst_domain_check_nproc(dev, dom); + } + } + } + /* Link us with the domain */ sc->pst_domain = dom; LIST_INSERT_HEAD(&dom->pd_pstlist, sc, pst_link); -- 2.41.0 From 224ceb2674bab09621dc16ce86b0bc4b5e8298d2 Mon Sep 17 00:00:00 2001 From: John Marino Date: Fri, 27 Feb 2015 09:01:52 +0100 Subject: [PATCH 08/16] Update gcc-50 to SVN version 221044 Last Changed Date: 2015-02-27 09:37:51 +0100 (Fri, 27 Feb 2015) --- contrib/gcc-5.0/LAST_UPDATED | 4 +- contrib/gcc-5.0/gcc/DATESTAMP | 2 +- contrib/gcc-5.0/gcc/builtin-types.def | 10 +- contrib/gcc-5.0/gcc/builtins.c | 11 +- contrib/gcc-5.0/gcc/c-family/c-common.c | 34 +- contrib/gcc-5.0/gcc/cgraph.c | 2 +- contrib/gcc-5.0/gcc/cgraph.h | 49 +- contrib/gcc-5.0/gcc/cgraphclones.c | 2 + contrib/gcc-5.0/gcc/cgraphunit.c | 1 + contrib/gcc-5.0/gcc/common.opt | 4 +- contrib/gcc-5.0/gcc/config/i386/i386.c | 77 ++- contrib/gcc-5.0/gcc/config/i386/i386.h | 5 +- contrib/gcc-5.0/gcc/cp/constexpr.c | 7 +- contrib/gcc-5.0/gcc/cp/decl.c | 4 +- contrib/gcc-5.0/gcc/cp/decl2.c | 8 +- contrib/gcc-5.0/gcc/data-streamer-in.c | 2 +- contrib/gcc-5.0/gcc/doc/extend.texi | 30 +- contrib/gcc-5.0/gcc/doc/rtl.texi | 4 +- contrib/gcc-5.0/gcc/doc/tm.texi | 12 + contrib/gcc-5.0/gcc/dwarf2out.c | 8 + contrib/gcc-5.0/gcc/gimple.h | 2 +- contrib/gcc-5.0/gcc/gimplify.c | 6 +- contrib/gcc-5.0/gcc/ipa-icf-gimple.c | 7 + contrib/gcc-5.0/gcc/ipa-icf.c | 583 ++++++++++++++------ contrib/gcc-5.0/gcc/ipa-icf.h | 71 +++ contrib/gcc-5.0/gcc/ipa-inline-analysis.c | 3 +- contrib/gcc-5.0/gcc/ipa-inline.c | 13 + contrib/gcc-5.0/gcc/ipa-prop.c | 4 +- contrib/gcc-5.0/gcc/ipa-ref.h | 3 + contrib/gcc-5.0/gcc/ipa-visibility.c | 42 +- contrib/gcc-5.0/gcc/ira-color.c | 6 +- contrib/gcc-5.0/gcc/lra-remat.c | 10 + contrib/gcc-5.0/gcc/lto-cgraph.c | 2 +- contrib/gcc-5.0/gcc/lto-section-in.c | 6 +- contrib/gcc-5.0/gcc/lto-streamer-in.c | 126 ++++- contrib/gcc-5.0/gcc/lto-streamer-out.c | 92 +++ contrib/gcc-5.0/gcc/lto-streamer.h | 17 +- contrib/gcc-5.0/gcc/lto/lto-lang.c | 34 +- contrib/gcc-5.0/gcc/lto/lto.c | 16 +- contrib/gcc-5.0/gcc/omp-builtins.def | 8 +- contrib/gcc-5.0/gcc/omp-low.c | 7 + contrib/gcc-5.0/gcc/passes.c | 2 + contrib/gcc-5.0/gcc/real.c | 72 ++- contrib/gcc-5.0/gcc/real.h | 1 + contrib/gcc-5.0/gcc/symtab.c | 50 +- contrib/gcc-5.0/gcc/target.def | 16 + contrib/gcc-5.0/gcc/tree-ssa-math-opts.c | 60 +- contrib/gcc-5.0/gcc/tree-ssa-propagate.c | 28 +- contrib/gcc-5.0/gcc/tree-ssa-reassoc.c | 8 +- contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c | 43 +- contrib/gcc-5.0/gcc/tree-streamer-in.c | 21 +- contrib/gcc-5.0/gcc/tree-streamer-out.c | 6 +- contrib/gcc-5.0/gcc/tree-streamer.c | 8 + contrib/gcc-5.0/gcc/tree-streamer.h | 16 + contrib/gcc-5.0/gcc/tree-vect-loop.c | 9 +- contrib/gcc-5.0/gcc/wide-int.cc | 25 +- contrib/gcc-5.0/libgcc/config/nvptx/t-nvptx | 5 + 57 files changed, 1336 insertions(+), 368 deletions(-) diff --git a/contrib/gcc-5.0/LAST_UPDATED b/contrib/gcc-5.0/LAST_UPDATED index cf7d7415a1..738c0468f7 100644 --- a/contrib/gcc-5.0/LAST_UPDATED +++ b/contrib/gcc-5.0/LAST_UPDATED @@ -1,2 +1,2 @@ -220871 -Last Changed Date: 2015-02-20 15:40:00 +0100 (Fri, 20 Feb 2015) +221044 +Last Changed Date: 2015-02-27 09:37:51 +0100 (Fri, 27 Feb 2015) diff --git a/contrib/gcc-5.0/gcc/DATESTAMP b/contrib/gcc-5.0/gcc/DATESTAMP index 3bdb5ca97c..2826df1756 100644 --- a/contrib/gcc-5.0/gcc/DATESTAMP +++ b/contrib/gcc-5.0/gcc/DATESTAMP @@ -1 +1 @@ -20150220 +20150227 diff --git a/contrib/gcc-5.0/gcc/builtin-types.def b/contrib/gcc-5.0/gcc/builtin-types.def index 3412677ef9..0e345318a3 100644 --- a/contrib/gcc-5.0/gcc/builtin-types.def +++ b/contrib/gcc-5.0/gcc/builtin-types.def @@ -492,6 +492,8 @@ DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I8_INT_INT, BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I8, BT_INT, BT_INT) DEF_FUNCTION_TYPE_5 (BT_FN_BOOL_VPTR_PTR_I16_INT_INT, BT_BOOL, BT_VOLATILE_PTR, BT_PTR, BT_I16, BT_INT, BT_INT) +DEF_FUNCTION_TYPE_5 (BT_FN_VOID_INT_SIZE_PTR_PTR_PTR, + BT_VOID, BT_INT, BT_SIZE, BT_PTR, BT_PTR, BT_PTR) DEF_FUNCTION_TYPE_5 (BT_FN_VOID_OMPFN_PTR_UINT_UINT_UINT, BT_VOID, BT_PTR_FN_VOID_PTR, BT_PTR, BT_UINT, BT_UINT, BT_UINT) @@ -588,12 +590,12 @@ DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, DEF_FUNCTION_TYPE_VAR_5 (BT_FN_INT_INT_INT_INT_INT_INT_VAR, BT_INT, BT_INT, BT_INT, BT_INT, BT_INT, BT_INT) -DEF_FUNCTION_TYPE_VAR_8 (BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR, - BT_VOID, BT_INT, BT_PTR, BT_SIZE, BT_PTR, BT_PTR, +DEF_FUNCTION_TYPE_VAR_7 (BT_FN_VOID_INT_SIZE_PTR_PTR_PTR_INT_INT_VAR, + BT_VOID, BT_INT, BT_SIZE, BT_PTR, BT_PTR, BT_PTR, BT_INT, BT_INT) -DEF_FUNCTION_TYPE_VAR_12 (BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR, - BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_PTR, BT_SIZE, +DEF_FUNCTION_TYPE_VAR_11 (BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR, + BT_VOID, BT_INT, BT_PTR_FN_VOID_PTR, BT_SIZE, BT_PTR, BT_PTR, BT_PTR, BT_INT, BT_INT, BT_INT, BT_INT, BT_INT) diff --git a/contrib/gcc-5.0/gcc/builtins.c b/contrib/gcc-5.0/gcc/builtins.c index 8f3c0bc22b..fb871e696a 100644 --- a/contrib/gcc-5.0/gcc/builtins.c +++ b/contrib/gcc-5.0/gcc/builtins.c @@ -359,13 +359,15 @@ get_object_alignment_2 (tree exp, unsigned int *alignp, tree addr = TREE_OPERAND (exp, 0); unsigned ptr_align; unsigned HOST_WIDE_INT ptr_bitpos; + unsigned HOST_WIDE_INT ptr_bitmask = ~0; + /* If the address is explicitely aligned, handle that. */ if (TREE_CODE (addr) == BIT_AND_EXPR && TREE_CODE (TREE_OPERAND (addr, 1)) == INTEGER_CST) { - align = (TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)) - & -TREE_INT_CST_LOW (TREE_OPERAND (addr, 1))); - align *= BITS_PER_UNIT; + ptr_bitmask = TREE_INT_CST_LOW (TREE_OPERAND (addr, 1)); + ptr_bitmask *= BITS_PER_UNIT; + align = ptr_bitmask & -ptr_bitmask; addr = TREE_OPERAND (addr, 0); } @@ -373,6 +375,9 @@ get_object_alignment_2 (tree exp, unsigned int *alignp, = get_pointer_alignment_1 (addr, &ptr_align, &ptr_bitpos); align = MAX (ptr_align, align); + /* Re-apply explicit alignment to the bitpos. */ + ptr_bitpos &= ptr_bitmask; + /* The alignment of the pointer operand in a TARGET_MEM_REF has to take the variable offset parts into account. */ if (TREE_CODE (exp) == TARGET_MEM_REF) diff --git a/contrib/gcc-5.0/gcc/c-family/c-common.c b/contrib/gcc-5.0/gcc/c-family/c-common.c index 3c18d1cc91..8c23e09196 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-common.c +++ b/contrib/gcc-5.0/gcc/c-family/c-common.c @@ -5236,12 +5236,11 @@ enum c_builtin_type #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME, #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ - NAME, -#define DEF_FUNCTION_TYPE_VAR_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8) NAME, -#define DEF_FUNCTION_TYPE_VAR_12(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, \ - ARG12) NAME, + NAME, +#define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ + ARG6, ARG7) NAME, +#define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ + ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME, #define DEF_POINTER_TYPE(NAME, TYPE) NAME, #include "builtin-types.def" #undef DEF_PRIMITIVE_TYPE @@ -5260,8 +5259,8 @@ enum c_builtin_type #undef DEF_FUNCTION_TYPE_VAR_3 #undef DEF_FUNCTION_TYPE_VAR_4 #undef DEF_FUNCTION_TYPE_VAR_5 -#undef DEF_FUNCTION_TYPE_VAR_8 -#undef DEF_FUNCTION_TYPE_VAR_12 +#undef DEF_FUNCTION_TYPE_VAR_7 +#undef DEF_FUNCTION_TYPE_VAR_11 #undef DEF_POINTER_TYPE BT_LAST }; @@ -5354,14 +5353,13 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node) def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4); #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5); -#define DEF_FUNCTION_TYPE_VAR_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8) \ - def_fn_type (ENUM, RETURN, 1, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ - ARG7, ARG8); -#define DEF_FUNCTION_TYPE_VAR_12(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \ - def_fn_type (ENUM, RETURN, 1, 12, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ - ARG7, ARG8, ARG9, ARG10, ARG11, ARG12); +#define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ + ARG6, ARG7) \ + def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); +#define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ + ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \ + def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ + ARG7, ARG8, ARG9, ARG10, ARG11); #define DEF_POINTER_TYPE(ENUM, TYPE) \ builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]); @@ -5383,8 +5381,8 @@ c_define_builtins (tree va_list_ref_type_node, tree va_list_arg_type_node) #undef DEF_FUNCTION_TYPE_VAR_3 #undef DEF_FUNCTION_TYPE_VAR_4 #undef DEF_FUNCTION_TYPE_VAR_5 -#undef DEF_FUNCTION_TYPE_VAR_8 -#undef DEF_FUNCTION_TYPE_VAR_12 +#undef DEF_FUNCTION_TYPE_VAR_7 +#undef DEF_FUNCTION_TYPE_VAR_11 #undef DEF_POINTER_TYPE builtin_types[(int) BT_LAST] = NULL_TREE; diff --git a/contrib/gcc-5.0/gcc/cgraph.c b/contrib/gcc-5.0/gcc/cgraph.c index 1ad08dc763..5555439215 100644 --- a/contrib/gcc-5.0/gcc/cgraph.c +++ b/contrib/gcc-5.0/gcc/cgraph.c @@ -2630,7 +2630,7 @@ cgraph_edge::verify_corresponds_to_fndecl (tree decl) if (!node || node->body_removed || node->in_other_partition - || node->icf_merged + || callee->icf_merged || callee->in_other_partition) return false; diff --git a/contrib/gcc-5.0/gcc/cgraph.h b/contrib/gcc-5.0/gcc/cgraph.h index ec3cccda86..ff437cf18b 100644 --- a/contrib/gcc-5.0/gcc/cgraph.h +++ b/contrib/gcc-5.0/gcc/cgraph.h @@ -326,9 +326,6 @@ public: /* Return true if ONE and TWO are part of the same COMDAT group. */ inline bool in_same_comdat_group_p (symtab_node *target); - /* Return true when there is a reference to node and it is not vtable. */ - bool address_taken_from_non_vtable_p (void); - /* Return true if symbol is known to be nonzero. */ bool nonzero_address (); @@ -337,6 +334,15 @@ public: return 2 otherwise. */ int equal_address_to (symtab_node *s2); + /* Return true if symbol's address may possibly be compared to other + symbol's address. */ + bool address_matters_p (); + + /* Return true if NODE's address can be compared. This use properties + of NODE only and does not look if the address is actually taken in + interesting way. For that use ADDRESS_MATTERS_P instead. */ + bool address_can_be_compared_p (void); + /* Return symbol table node associated with DECL, if any, and NULL otherwise. */ static inline symtab_node *get (const_tree decl) @@ -3022,6 +3028,43 @@ varpool_node::call_for_symbol_and_aliases (bool (*callback) (varpool_node *, return false; } +/* Return true if NODE's address can be compared. */ + +inline bool +symtab_node::address_can_be_compared_p () +{ + /* Address of virtual tables and functions is never compared. */ + if (DECL_VIRTUAL_P (decl)) + return false; + /* Address of C++ cdtors is never compared. */ + if (is_a (this) + && (DECL_CXX_CONSTRUCTOR_P (decl) + || DECL_CXX_DESTRUCTOR_P (decl))) + return false; + /* Constant pool symbols addresses are never compared. + flag_merge_constants permits us to assume the same on readonly vars. */ + if (is_a (this) + && (DECL_IN_CONSTANT_POOL (decl) + || (flag_merge_constants >= 2 + && TREE_READONLY (decl) && !TREE_THIS_VOLATILE (decl)))) + return false; + return true; +} + +/* Return true if refernece may be used in address compare. */ + +inline bool +ipa_ref::address_matters_p () +{ + if (use != IPA_REF_ADDR) + return false; + /* Addresses taken from virtual tables are never compared. */ + if (is_a (referring) + && DECL_VIRTUAL_P (referring->decl)) + return false; + return referred->address_can_be_compared_p (); +} + /* Build polymorphic call context for indirect call E. */ inline diff --git a/contrib/gcc-5.0/gcc/cgraphclones.c b/contrib/gcc-5.0/gcc/cgraphclones.c index d0a5f70713..c74017615f 100644 --- a/contrib/gcc-5.0/gcc/cgraphclones.c +++ b/contrib/gcc-5.0/gcc/cgraphclones.c @@ -471,6 +471,8 @@ cgraph_node::create_clone (tree decl, gcov_type gcov_count, int freq, new_node->frequency = frequency; new_node->tp_first_run = tp_first_run; new_node->tm_clone = tm_clone; + new_node->icf_merged = icf_merged; + new_node->merged = merged; new_node->clone.tree_map = NULL; new_node->clone.args_to_skip = args_to_skip; diff --git a/contrib/gcc-5.0/gcc/cgraphunit.c b/contrib/gcc-5.0/gcc/cgraphunit.c index 942826d368..9f6878a19e 100644 --- a/contrib/gcc-5.0/gcc/cgraphunit.c +++ b/contrib/gcc-5.0/gcc/cgraphunit.c @@ -2468,6 +2468,7 @@ cgraph_node::create_wrapper (cgraph_node *target) release_body (true); reset (); + DECL_UNINLINABLE (decl) = false; DECL_RESULT (decl) = decl_result; DECL_INITIAL (decl) = NULL; allocate_struct_function (decl, false); diff --git a/contrib/gcc-5.0/gcc/common.opt b/contrib/gcc-5.0/gcc/common.opt index 4fa12f5fa3..b49ac46610 100644 --- a/contrib/gcc-5.0/gcc/common.opt +++ b/contrib/gcc-5.0/gcc/common.opt @@ -1644,11 +1644,11 @@ Report on permanent memory allocation in WPA only ; string constants and constants from constant pool, if 2 also constant ; variables. fmerge-all-constants -Common Report Var(flag_merge_constants,2) Init(1) Optimization +Common Report Var(flag_merge_constants,2) Init(1) Attempt to merge identical constants and constant variables fmerge-constants -Common Report Var(flag_merge_constants,1) Optimization +Common Report Var(flag_merge_constants,1) Attempt to merge identical constants across compilation units fmerge-debug-strings diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.c b/contrib/gcc-5.0/gcc/config/i386/i386.c index 71a5b2202e..bec1324990 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.c +++ b/contrib/gcc-5.0/gcc/config/i386/i386.c @@ -2463,6 +2463,7 @@ static void ix86_function_specific_save (struct cl_target_option *, struct gcc_options *opts); static void ix86_function_specific_restore (struct gcc_options *opts, struct cl_target_option *); +static void ix86_function_specific_post_stream_in (struct cl_target_option *); static void ix86_function_specific_print (FILE *, int, struct cl_target_option *); static bool ix86_valid_target_attribute_p (tree, tree, tree, int); @@ -4571,6 +4572,57 @@ ix86_function_specific_restore (struct gcc_options *opts, set_ix86_tune_features (ix86_tune, false); } +/* Adjust target options after streaming them in. This is mainly about + reconciling them with global options. */ + +static void +ix86_function_specific_post_stream_in (struct cl_target_option *ptr) +{ + /* flag_pic is a global option, but ix86_cmodel is target saved option + partly computed from flag_pic. If flag_pic is on, adjust x_ix86_cmodel + for PIC, or error out. */ + if (flag_pic) + switch (ptr->x_ix86_cmodel) + { + case CM_SMALL: + ptr->x_ix86_cmodel = CM_SMALL_PIC; + break; + + case CM_MEDIUM: + ptr->x_ix86_cmodel = CM_MEDIUM_PIC; + break; + + case CM_LARGE: + ptr->x_ix86_cmodel = CM_LARGE_PIC; + break; + + case CM_KERNEL: + error ("code model %s does not support PIC mode", "kernel"); + break; + + default: + break; + } + else + switch (ptr->x_ix86_cmodel) + { + case CM_SMALL_PIC: + ptr->x_ix86_cmodel = CM_SMALL; + break; + + case CM_MEDIUM_PIC: + ptr->x_ix86_cmodel = CM_MEDIUM; + break; + + case CM_LARGE_PIC: + ptr->x_ix86_cmodel = CM_LARGE; + break; + + default: + break; + } +} + /* Print the current options */ static void @@ -6068,6 +6120,9 @@ ix86_function_arg_regno_p (int regno) int i; const int *parm_regs; + if (TARGET_MPX && BND_REGNO_P (regno)) + return true; + if (!TARGET_64BIT) { if (TARGET_MACHO) @@ -26737,7 +26792,11 @@ ix86_sched_reorder (FILE *dump, int sched_verbose, rtx_insn **ready, ready[n_ready - 1] = insn; return issue_rate; } - if (clock_var != 0 && swap_top_of_ready_list (ready, n_ready)) + + /* Skip selective scheduling since HID is not populated in it. */ + if (clock_var != 0 + && !sel_sched_p () + && swap_top_of_ready_list (ready, n_ready)) { if (sched_verbose > 1) fprintf (dump, ";;\tslm sched_reorder: swap %d and %d insns\n", @@ -26846,6 +26905,16 @@ avoid_func_arg_motion (rtx_insn *first_arg, rtx_insn *insn) rtx set; rtx tmp; + /* Add anti dependencies for bounds stores. */ + if (INSN_P (insn) + && GET_CODE (PATTERN (insn)) == PARALLEL + && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC + && XINT (XVECEXP (PATTERN (insn), 0, 0), 1) == UNSPEC_BNDSTX) + { + add_dependence (first_arg, insn, REG_DEP_ANTI); + return; + } + set = single_set (insn); if (!set) return; @@ -52007,6 +52076,9 @@ ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts) #undef TARGET_OPTION_RESTORE #define TARGET_OPTION_RESTORE ix86_function_specific_restore +#undef TARGET_OPTION_POST_STREAM_IN +#define TARGET_OPTION_POST_STREAM_IN ix86_function_specific_post_stream_in + #undef TARGET_OPTION_PRINT #define TARGET_OPTION_PRINT ix86_function_specific_print @@ -52131,6 +52203,9 @@ ix86_initialize_bounds (tree var, tree lb, tree ub, tree *stmts) #define TARGET_OFFLOAD_OPTIONS \ ix86_offload_options +#undef TARGET_ABSOLUTE_BIGGEST_ALIGNMENT +#define TARGET_ABSOLUTE_BIGGEST_ALIGNMENT 512 + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-i386.h" diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.h b/contrib/gcc-5.0/gcc/config/i386/i386.h index 5d1e5e0cff..1e755d3a35 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.h +++ b/contrib/gcc-5.0/gcc/config/i386/i386.h @@ -795,7 +795,10 @@ extern const char *host_detect_local_cpu (int argc, const char **argv); rounder than this. Pentium+ prefers DFmode values to be aligned to 64 bit boundary - and Pentium Pro XFmode values at 128 bit boundaries. */ + and Pentium Pro XFmode values at 128 bit boundaries. + + When increasing the maximum, also update + TARGET_ABSOLUTE_BIGGEST_ALIGNMENT. */ #define BIGGEST_ALIGNMENT \ (TARGET_AVX512F ? 512 : (TARGET_AVX ? 256 : 128)) diff --git a/contrib/gcc-5.0/gcc/cp/constexpr.c b/contrib/gcc-5.0/gcc/cp/constexpr.c index 32a23ff738..f7e8ce949f 100644 --- a/contrib/gcc-5.0/gcc/cp/constexpr.c +++ b/contrib/gcc-5.0/gcc/cp/constexpr.c @@ -3113,9 +3113,10 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, break; case RETURN_EXPR: - r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), - lval, - non_constant_p, overflow_p); + if (TREE_OPERAND (t, 0) != NULL_TREE) + r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), + lval, + non_constant_p, overflow_p); *jump_target = t; break; diff --git a/contrib/gcc-5.0/gcc/cp/decl.c b/contrib/gcc-5.0/gcc/cp/decl.c index 67c5ae73e3..83e060b4d1 100644 --- a/contrib/gcc-5.0/gcc/cp/decl.c +++ b/contrib/gcc-5.0/gcc/cp/decl.c @@ -13721,9 +13721,7 @@ start_preparsed_function (tree decl1, tree attrs, int flags) || (DECL_CONSTRUCTOR_P (decl1) && targetm.cxx.cdtor_returns_this ())) { - cdtor_label = build_decl (input_location, - LABEL_DECL, NULL_TREE, void_type_node); - DECL_CONTEXT (cdtor_label) = current_function_decl; + cdtor_label = create_artificial_label (input_location); } start_fname_decls (); diff --git a/contrib/gcc-5.0/gcc/cp/decl2.c b/contrib/gcc-5.0/gcc/cp/decl2.c index a7bc08f6e5..a4a5ebf58e 100644 --- a/contrib/gcc-5.0/gcc/cp/decl2.c +++ b/contrib/gcc-5.0/gcc/cp/decl2.c @@ -2175,6 +2175,7 @@ constrain_visibility (tree decl, int visibility, bool tmpl) TREE_PUBLIC (decl) = 0; DECL_WEAK (decl) = 0; DECL_COMMON (decl) = 0; + DECL_COMDAT (decl) = false; if (TREE_CODE (decl) == FUNCTION_DECL || TREE_CODE (decl) == VAR_DECL) { @@ -2215,9 +2216,12 @@ constrain_visibility_for_template (tree decl, tree targs) tree arg = TREE_VEC_ELT (args, i-1); if (TYPE_P (arg)) vis = type_visibility (arg); - else if (TREE_TYPE (arg) && POINTER_TYPE_P (TREE_TYPE (arg))) + else { - STRIP_NOPS (arg); + if (REFERENCE_REF_P (arg)) + arg = TREE_OPERAND (arg, 0); + if (TREE_TYPE (arg)) + STRIP_NOPS (arg); if (TREE_CODE (arg) == ADDR_EXPR) arg = TREE_OPERAND (arg, 0); if (VAR_OR_FUNCTION_DECL_P (arg)) diff --git a/contrib/gcc-5.0/gcc/data-streamer-in.c b/contrib/gcc-5.0/gcc/data-streamer-in.c index 897ceab441..424d52295f 100644 --- a/contrib/gcc-5.0/gcc/data-streamer-in.c +++ b/contrib/gcc-5.0/gcc/data-streamer-in.c @@ -70,7 +70,7 @@ string_for_index (struct data_in *data_in, unsigned int loc, unsigned int *rlen) } /* Get the string stored at location LOC in DATA_IN->STRINGS. */ - lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len); + lto_input_block str_tab (data_in->strings, loc - 1, data_in->strings_len, NULL); len = streamer_read_uhwi (&str_tab); *rlen = len; diff --git a/contrib/gcc-5.0/gcc/doc/extend.texi b/contrib/gcc-5.0/gcc/doc/extend.texi index 54c1941ccf..c066d32274 100644 --- a/contrib/gcc-5.0/gcc/doc/extend.texi +++ b/contrib/gcc-5.0/gcc/doc/extend.texi @@ -2985,7 +2985,7 @@ which this handler should be assigned. If the argument is a name it is treated as a symbolic name for the vector slot. These names should match up with appropriate entries in the linker script. By default the names @code{watchdog} for vector 26, @code{nmi} for vector 30 and -@code{reset} for vector 31 are recognised. +@code{reset} for vector 31 are recognized. You can also use the following function attributes to modify how normal functions interact with interrupt functions: @@ -3388,7 +3388,7 @@ the function label. A second argument can be used to specify the number of halfwords to be added after the function label. For both arguments the maximum allowed value is 1000000. -If both ar guments are zero, hotpatching is disabled. +If both arguments are zero, hotpatching is disabled. @item naked @cindex function without a prologue/epilogue code @@ -4633,7 +4633,7 @@ This example uses the @code{cold} label attribute to indicate the asm goto ("some asm" : : : : NoError); -/* This branch (the fallthru from the asm) is less commonly used */ +/* This branch (the fall-through from the asm) is less commonly used */ ErrorHandling: __attribute__((cold, unused)); /* Semi-colon is required here */ printf("error\n"); @@ -8988,7 +8988,7 @@ returns -1. @node Cilk Plus Builtins @section Cilk Plus C/C++ Language Extension Built-in Functions -GCC provides support for the following built-in reduction funtions if Cilk Plus +GCC provides support for the following built-in reduction functions if Cilk Plus is enabled. Cilk Plus can be enabled using the @option{-fcilkplus} flag. @itemize @bullet @@ -10744,7 +10744,7 @@ __v8hi __builtin_arc_vupsbaw (__v8hi) __v8hi __builtin_arc_vupsbw (__v8hi) @end example -The followign take two @code{int} arguments and return no result: +The following take two @code{int} arguments and return no result: @example void __builtin_arc_vdirun (int, int) void __builtin_arc_vdorun (int, int) @@ -10983,11 +10983,11 @@ intrinsics can be found at The built-in intrinsics for the Advanced SIMD extension are available when NEON is enabled. -Currently, ARM and AArch64 back-ends do not support ACLE 2.0 fully. Both -back-ends support CRC32 intrinsics from @file{arm_acle.h}. The ARM backend's -16-bit floating-point Advanded SIMD Intrinsics currently comply to ACLE v1.1. -AArch64's backend does not have support for 16-bit floating point Advanced SIMD -Intrinsics yet. +Currently, ARM and AArch64 back ends do not support ACLE 2.0 fully. Both +back ends support CRC32 intrinsics from @file{arm_acle.h}. The ARM back end's +16-bit floating-point Advanced SIMD intrinsics currently comply to ACLE v1.1. +AArch64's back end does not have support for 16-bit floating point Advanced SIMD +intrinsics yet. See @ref{ARM Options} and @ref{AArch64 Options} for more information on the availability of extensions. @@ -12451,7 +12451,7 @@ 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 +@code{__builtin_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 @@ -12467,9 +12467,9 @@ _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); +_Decimal128 __builtin_dscliq (_Decimal128, int); _Decimal64 __builtin_dscri (_Decimal64, int); -_Decimal128 __builitn_dscriq (_Decimal128, int); +_Decimal128 __builtin_dscriq (_Decimal128, int); unsigned long long __builtin_unpack_dec128 (_Decimal128, int); _Decimal128 __builtin_pack_dec128 (unsigned long long, unsigned long long); @end smallexample @@ -15079,7 +15079,7 @@ must be a constant integer in the range of 0 to 15. @subsection PowerPC Hardware Transactional Memory Built-in Functions GCC provides two interfaces for accessing the Hardware Transactional Memory (HTM) instructions available on some of the PowerPC family -of prcoessors (eg, POWER8). The two interfaces come in a low level +of processors (eg, POWER8). The two interfaces come in a low level interface, consisting of built-in functions specific to PowerPC and a higher level interface consisting of inline functions that are common between PowerPC and S/390. @@ -19255,4 +19255,4 @@ than no arguments, as C++ demands. @end table @c LocalWords: emph deftypefn builtin ARCv2EM SIMD builtins msimd -@c LocalWords: typedef v4si v8hi DMA dma vdiwr vdowr followign +@c LocalWords: typedef v4si v8hi DMA dma vdiwr vdowr diff --git a/contrib/gcc-5.0/gcc/doc/rtl.texi b/contrib/gcc-5.0/gcc/doc/rtl.texi index 061ab79db1..a5275f4ba0 100644 --- a/contrib/gcc-5.0/gcc/doc/rtl.texi +++ b/contrib/gcc-5.0/gcc/doc/rtl.texi @@ -2306,8 +2306,8 @@ For unsigned widening multiplication, use the same idiom, but with @findex fma @item (fma:@var{m} @var{x} @var{y} @var{z}) Represents the @code{fma}, @code{fmaf}, and @code{fmal} builtin -functions that do a combined multiply of @var{x} and @var{y} and then -adding to@var{z} without doing an intermediate rounding step. +functions, which compute @samp{@var{x} * @var{y} + @var{z}} +without doing an intermediate rounding step. @findex div @findex ss_div diff --git a/contrib/gcc-5.0/gcc/doc/tm.texi b/contrib/gcc-5.0/gcc/doc/tm.texi index 048a28a137..6e5d2c0441 100644 --- a/contrib/gcc-5.0/gcc/doc/tm.texi +++ b/contrib/gcc-5.0/gcc/doc/tm.texi @@ -1003,6 +1003,12 @@ bits. Note that this is not the biggest alignment that is supported, just the biggest alignment that, when violated, may cause a fault. @end defmac +@deftypevr {Target Hook} HOST_WIDE_INT TARGET_ABSOLUTE_BIGGEST_ALIGNMENT +If defined, this target hook specifies the absolute biggest alignment +that a type or variable can have on this machine, otherwise, +@code{BIGGEST_ALIGNMENT} is used. +@end deftypevr + @defmac MALLOC_ABI_ALIGNMENT Alignment, in bits, a C conformant malloc implementation has to provide. If not defined, the default value is @code{BITS_PER_WORD}. @@ -9899,6 +9905,12 @@ information in the @code{struct cl_target_option} structure for function-specific options to the @code{struct gcc_options} structure. @end deftypefn +@deftypefn {Target Hook} void TARGET_OPTION_POST_STREAM_IN (struct cl_target_option *@var{ptr}) +This hook is called to update target-specific information in the +@code{struct cl_target_option} structure after it is streamed in from +LTO bytecode. +@end deftypefn + @deftypefn {Target Hook} void TARGET_OPTION_PRINT (FILE *@var{file}, int @var{indent}, struct cl_target_option *@var{ptr}) This hook is called to print any additional target-specific information in the @code{struct cl_target_option} structure for diff --git a/contrib/gcc-5.0/gcc/dwarf2out.c b/contrib/gcc-5.0/gcc/dwarf2out.c index ebf41c8e5a..6c8e51fcab 100644 --- a/contrib/gcc-5.0/gcc/dwarf2out.c +++ b/contrib/gcc-5.0/gcc/dwarf2out.c @@ -22621,6 +22621,14 @@ output_macinfo (void) static void dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) { + /* This option is currently broken, see (PR53118 and PR46102). */ + if (flag_eliminate_dwarf2_dups + && strstr (lang_hooks.name, "C++")) + { + warning (0, "-feliminate-dwarf2-dups is broken for C++, ignoring"); + flag_eliminate_dwarf2_dups = 0; + } + /* Allocate the file_table. */ file_table = hash_table::create_ggc (50); diff --git a/contrib/gcc-5.0/gcc/gimple.h b/contrib/gcc-5.0/gcc/gimple.h index 5503625c9f..95e4fc8fb3 100644 --- a/contrib/gcc-5.0/gcc/gimple.h +++ b/contrib/gcc-5.0/gcc/gimple.h @@ -1303,7 +1303,7 @@ gcall *gimple_build_call_valist (tree, unsigned, va_list); gcall *gimple_build_call_internal (enum internal_fn, unsigned, ...); gcall *gimple_build_call_internal_vec (enum internal_fn, vec ); gcall *gimple_build_call_from_tree (tree); -gassign *gimple_build_assign (tree, tree CXX_MEM_STAT_DECL); +gassign *gimple_build_assign (tree, tree CXX_MEM_STAT_INFO); gassign *gimple_build_assign (tree, enum tree_code, tree, tree, tree CXX_MEM_STAT_INFO); gassign *gimple_build_assign (tree, enum tree_code, diff --git a/contrib/gcc-5.0/gcc/gimplify.c b/contrib/gcc-5.0/gcc/gimplify.c index 1353ada2f8..d822913acc 100644 --- a/contrib/gcc-5.0/gcc/gimplify.c +++ b/contrib/gcc-5.0/gcc/gimplify.c @@ -8244,10 +8244,10 @@ gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p, TREE_CODE (*expr_p) == TRY_FINALLY_EXPR ? GIMPLE_TRY_FINALLY : GIMPLE_TRY_CATCH); - if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION) - gimple_set_location (try_, saved_location); - else + if (EXPR_HAS_LOCATION (save_expr)) gimple_set_location (try_, EXPR_LOCATION (save_expr)); + else if (LOCATION_LOCUS (saved_location) != UNKNOWN_LOCATION) + gimple_set_location (try_, saved_location); if (TREE_CODE (*expr_p) == TRY_CATCH_EXPR) gimple_try_set_catch_is_cleanup (try_, TRY_CATCH_IS_CLEANUP (*expr_p)); diff --git a/contrib/gcc-5.0/gcc/ipa-icf-gimple.c b/contrib/gcc-5.0/gcc/ipa-icf-gimple.c index 5b176d019d..53d2c38bc9 100644 --- a/contrib/gcc-5.0/gcc/ipa-icf-gimple.c +++ b/contrib/gcc-5.0/gcc/ipa-icf-gimple.c @@ -575,6 +575,13 @@ func_checker::compare_variable_decl (tree t1, tree t2) if (t1 == t2) return true; + if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2)) + return return_false_with_msg ("DECL_HARD_REGISTER are different"); + + if (DECL_HARD_REGISTER (t1) + && DECL_ASSEMBLER_NAME (t1) != DECL_ASSEMBLER_NAME (t2)) + return return_false_with_msg ("HARD REGISTERS are different"); + if (TREE_CODE (t1) == VAR_DECL && (DECL_EXTERNAL (t1) || TREE_STATIC (t1))) { symtab_node *n1 = symtab_node::get (t1); diff --git a/contrib/gcc-5.0/gcc/ipa-icf.c b/contrib/gcc-5.0/gcc/ipa-icf.c index 494fdcf08f..5d50b6f639 100644 --- a/contrib/gcc-5.0/gcc/ipa-icf.c +++ b/contrib/gcc-5.0/gcc/ipa-icf.c @@ -126,6 +126,44 @@ along with GCC; see the file COPYING3. If not see using namespace ipa_icf_gimple; namespace ipa_icf { + +/* Constructor. */ + +symbol_compare_collection::symbol_compare_collection (symtab_node *node) +{ + m_references.create (0); + m_interposables.create (0); + + ipa_ref *ref; + + if (is_a (node) && DECL_VIRTUAL_P (node->decl)) + return; + + for (unsigned i = 0; i < node->num_references (); i++) + { + ref = node->iterate_reference (i, ref); + if (ref->address_matters_p ()) + m_references.safe_push (ref->referred); + + if (ref->referred->get_availability () <= AVAIL_INTERPOSABLE) + { + if (ref->address_matters_p ()) + m_references.safe_push (ref->referred); + else + m_interposables.safe_push (ref->referred); + } + } + + if (is_a (node)) + { + cgraph_node *cnode = dyn_cast (node); + + for (cgraph_edge *e = cnode->callees; e; e = e->next_callee) + if (e->callee->get_availability () <= AVAIL_INTERPOSABLE) + m_interposables.safe_push (e->callee); + } +} + /* Constructor for key value pair, where _ITEM is key and _INDEX is a target. */ sem_usage_pair::sem_usage_pair (sem_item *_item, unsigned int _index): @@ -594,8 +632,56 @@ set_local (cgraph_node *node, void *data) return false; } +/* TREE_ADDRESSABLE of NODE to true if DATA is non-NULL. + Helper for call_for_symbol_thunks_and_aliases. */ + +static bool +set_addressable (varpool_node *node, void *) +{ + TREE_ADDRESSABLE (node->decl) = 1; + return false; +} + +/* Redirect all callers of N and its aliases to TO. Remove aliases if + possible. Return number of redirections made. */ + +static int +redirect_all_callers (cgraph_node *n, cgraph_node *to) +{ + int nredirected = 0; + ipa_ref *ref; + + while (n->callers) + { + cgraph_edge *e = n->callers; + e->redirect_callee (to); + nredirected++; + } + for (unsigned i = 0; n->iterate_direct_aliases (i, ref);) + { + bool removed = false; + cgraph_node *n_alias = dyn_cast (ref->referring); + + if ((DECL_COMDAT_GROUP (n->decl) + && (DECL_COMDAT_GROUP (n->decl) + == DECL_COMDAT_GROUP (n_alias->decl))) + || (n_alias->get_availability () > AVAIL_INTERPOSABLE + && n->get_availability () > AVAIL_INTERPOSABLE)) + { + nredirected += redirect_all_callers (n_alias, to); + if (n_alias->can_remove_if_no_direct_calls_p () + && !n_alias->has_aliases_p ()) + n_alias->remove (); + } + if (!removed) + i++; + } + return nredirected; +} + /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can be applied. */ + bool sem_function::merge (sem_item *alias_item) { @@ -604,16 +690,29 @@ sem_function::merge (sem_item *alias_item) sem_function *alias_func = static_cast (alias_item); cgraph_node *original = get_node (); - cgraph_node *local_original = original; + cgraph_node *local_original = NULL; cgraph_node *alias = alias_func->get_node (); - bool original_address_matters; - bool alias_address_matters; - bool create_thunk = false; + bool create_wrapper = false; bool create_alias = false; bool redirect_callers = false; + bool remove = false; + bool original_discardable = false; + bool original_address_matters = original->address_matters_p (); + bool alias_address_matters = alias->address_matters_p (); + + if (DECL_NO_INLINE_WARNING_P (original->decl) + != DECL_NO_INLINE_WARNING_P (alias->decl)) + { + if (dump_file) + fprintf (dump_file, + "Not unifying; " + "DECL_NO_INLINE_WARNING mismatch.\n\n"); + return false; + } + /* Do not attempt to mix functions from different user sections; we do not know what user intends with those. */ if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section) @@ -622,127 +721,173 @@ sem_function::merge (sem_item *alias_item) { if (dump_file) fprintf (dump_file, - "Not unifying; original and alias are in different sections.\n\n"); + "Not unifying; " + "original and alias are in different sections.\n\n"); return false; } /* See if original is in a section that can be discarded if the main - symbol is not used. */ - if (DECL_EXTERNAL (original->decl)) - original_discardable = true; - if (original->resolution == LDPR_PREEMPTED_REG - || original->resolution == LDPR_PREEMPTED_IR) - original_discardable = true; - if (original->can_be_discarded_p ()) + symbol is not used. + + Also consider case where we have resolution info and we know that + original's definition is not going to be used. In this case we can not + create alias to original. */ + if (original->can_be_discarded_p () + || (node->resolution != LDPR_UNKNOWN + && !decl_binds_to_current_def_p (node->decl))) original_discardable = true; - /* See if original and/or alias address can be compared for equality. */ - original_address_matters - = (!DECL_VIRTUAL_P (original->decl) - && (original->externally_visible - || original->address_taken_from_non_vtable_p ())); - alias_address_matters - = (!DECL_VIRTUAL_P (alias->decl) - && (alias->externally_visible - || alias->address_taken_from_non_vtable_p ())); - - /* If alias and original can be compared for address equality, we need - to create a thunk. Also we can not create extra aliases into discardable - section (or we risk link failures when section is discarded). */ - if ((original_address_matters - && alias_address_matters) - || original_discardable) + /* Creating a symtab alias is the optimal way to merge. + It however can not be used in the following cases: + + 1) if ORIGINAL and ALIAS may be possibly compared for address equality. + 2) if ORIGINAL is in a section that may be discarded by linker or if + it is an external functions where we can not create an alias + (ORIGINAL_DISCARDABLE) + 3) if target do not support symbol aliases. + + If we can not produce alias, we will turn ALIAS into WRAPPER of ORIGINAL + and/or redirect all callers from ALIAS to ORIGINAL. */ + if ((original_address_matters && alias_address_matters) + || original_discardable + || !sem_item::target_supports_symbol_aliases_p ()) { - create_thunk = !stdarg_p (TREE_TYPE (alias->decl)); - create_alias = false; - /* When both alias and original are not overwritable, we can save - the extra thunk wrapper for direct calls. */ + /* First see if we can produce wrapper. */ + + /* Do not turn function in one comdat group into wrapper to another + comdat group. Other compiler producing the body of the + another comdat group may make opossite decision and with unfortunate + linker choices this may close a loop. */ + if (DECL_COMDAT_GROUP (alias->decl) + && (DECL_COMDAT_GROUP (alias->decl) + != DECL_COMDAT_GROUP (original->decl))) + { + if (dump_file) + fprintf (dump_file, + "Wrapper cannot be created because of COMDAT\n"); + } + else if (DECL_STATIC_CHAIN (alias->decl)) + { + if (dump_file) + fprintf (dump_file, + "Can not create wrapper of nested functions.\n"); + } + /* TODO: We can also deal with variadic functions never calling + VA_START. */ + else if (stdarg_p (TREE_TYPE (alias->decl))) + { + if (dump_file) + fprintf (dump_file, + "can not create wrapper of stdarg function.\n"); + } + else if (inline_summaries + && inline_summaries->get (alias)->self_size <= 2) + { + if (dump_file) + fprintf (dump_file, "Wrapper creation is not " + "profitable (function is too small).\n"); + } + /* If user paid attention to mark function noinline, assume it is + somewhat special and do not try to turn it into a wrapper that can + not be undone by inliner. */ + else if (lookup_attribute ("noinline", DECL_ATTRIBUTES (alias->decl))) + { + if (dump_file) + fprintf (dump_file, "Wrappers are not created for noinline.\n"); + } + else + create_wrapper = true; + + /* We can redirect local calls in the case both alias and orignal + are not interposable. */ redirect_callers - = (!original_discardable - && alias->get_availability () > AVAIL_INTERPOSABLE - && original->get_availability () > AVAIL_INTERPOSABLE - && !alias->instrumented_version); - } - else - { - create_alias = true; - create_thunk = false; - redirect_callers = false; - } + = alias->get_availability () > AVAIL_INTERPOSABLE + && original->get_availability () > AVAIL_INTERPOSABLE + && !alias->instrumented_version; - if (create_alias && (DECL_COMDAT_GROUP (alias->decl) - || !sem_item::target_supports_symbol_aliases_p ())) - { - create_alias = false; - create_thunk = true; - } + if (!redirect_callers && !create_wrapper) + { + if (dump_file) + fprintf (dump_file, "Not unifying; can not redirect callers nor " + "produce wrapper\n\n"); + return false; + } - /* We want thunk to always jump to the local function body - unless the body is comdat and may be optimized out. */ - if ((create_thunk || redirect_callers) - && (!original_discardable + /* Work out the symbol the wrapper should call. + If ORIGINAL is interposable, we need to call a local alias. + Also produce local alias (if possible) as an optimization. */ + if (!original_discardable || (DECL_COMDAT_GROUP (original->decl) && (DECL_COMDAT_GROUP (original->decl) - == DECL_COMDAT_GROUP (alias->decl))))) - local_original - = dyn_cast (original->noninterposable_alias ()); - - if (!local_original) - { - if (dump_file) - fprintf (dump_file, "Noninterposable alias cannot be created.\n\n"); - - return false; - } + == DECL_COMDAT_GROUP (alias->decl)))) + { + local_original + = dyn_cast (original->noninterposable_alias ()); + if (!local_original + && original->get_availability () > AVAIL_INTERPOSABLE) + local_original = original; + /* If original is COMDAT local, we can not really redirect external + callers to it. */ + if (original->comdat_local_p ()) + redirect_callers = false; + } + /* If we can not use local alias, fallback to the original + when possible. */ + else if (original->get_availability () > AVAIL_INTERPOSABLE) + local_original = original; + if (!local_original) + { + if (dump_file) + fprintf (dump_file, "Not unifying; " + "can not produce local alias.\n\n"); + return false; + } - if (!decl_binds_to_current_def_p (alias->decl)) - { - if (dump_file) - fprintf (dump_file, "Declaration does not bind to currect definition.\n\n"); - return false; + if (!redirect_callers && !create_wrapper) + { + if (dump_file) + fprintf (dump_file, "Not unifying; " + "can not redirect callers nor produce a wrapper\n\n"); + return false; + } + if (!create_wrapper + && !alias->can_remove_if_no_direct_calls_p ()) + { + if (dump_file) + fprintf (dump_file, "Not unifying; can not make wrapper and " + "function has other uses than direct calls\n\n"); + return false; + } } + else + create_alias = true; if (redirect_callers) { - /* If alias is non-overwritable then - all direct calls are safe to be redirected to the original. */ - bool redirected = false; - while (alias->callers) - { - cgraph_edge *e = alias->callers; - e->redirect_callee (local_original); - push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl)); + int nredirected = redirect_all_callers (alias, local_original); - if (e->call_stmt) - e->redirect_call_stmt_to_callee (); + if (nredirected) + { + alias->icf_merged = true; + local_original->icf_merged = true; - pop_cfun (); - redirected = true; + if (dump_file && nredirected) + fprintf (dump_file, "%i local calls have been " + "redirected.\n", nredirected); } - alias->icf_merged = true; - if (local_original->lto_file_data - && alias->lto_file_data - && local_original->lto_file_data != alias->lto_file_data) - local_original->merged = true; - - /* The alias function is removed if symbol address - does not matter. */ - if (!alias_address_matters) - alias->remove (); - - if (dump_file && redirected) - fprintf (dump_file, "Callgraph local calls have been redirected.\n\n"); + /* If all callers was redirected, do not produce wrapper. */ + if (alias->can_remove_if_no_direct_calls_p () + && !alias->has_aliases_p ()) + { + create_wrapper = false; + remove = true; + } + gcc_assert (!create_alias); } - /* If the condtion above is not met, we are lucky and can turn the - function into real alias. */ else if (create_alias) { alias->icf_merged = true; - if (local_original->lto_file_data - && alias->lto_file_data - && local_original->lto_file_data != alias->lto_file_data) - local_original->merged = true; /* Remove the function's body. */ ipa_merge_profiles (original, alias); @@ -757,39 +902,38 @@ sem_function::merge (sem_item *alias_item) (set_local, (void *)(size_t) original->local_p (), true); if (dump_file) - fprintf (dump_file, "Callgraph alias has been created.\n\n"); + fprintf (dump_file, "Unified; Function alias has been created.\n\n"); } - else if (create_thunk) + if (create_wrapper) { - if (DECL_COMDAT_GROUP (alias->decl)) - { - if (dump_file) - fprintf (dump_file, "Callgraph thunk cannot be created because of COMDAT\n"); + gcc_assert (!create_alias); + alias->icf_merged = true; + local_original->icf_merged = true; - return 0; - } + ipa_merge_profiles (local_original, alias, true); + alias->create_wrapper (local_original); - if (DECL_STATIC_CHAIN (alias->decl)) - { - if (dump_file) - fprintf (dump_file, "Thunk creation is risky for static-chain functions.\n\n"); + if (dump_file) + fprintf (dump_file, "Unified; Wrapper has been created.\n\n"); + } + gcc_assert (alias->icf_merged || remove); + original->icf_merged = true; - return 0; - } + /* Inform the inliner about cross-module merging. */ + if ((original->lto_file_data || alias->lto_file_data) + && original->lto_file_data != alias->lto_file_data) + local_original->merged = original->merged = true; + if (remove) + { + ipa_merge_profiles (original, alias); + alias->release_body (); + alias->reset (); + alias->body_removed = true; alias->icf_merged = true; - if (local_original->lto_file_data - && alias->lto_file_data - && local_original->lto_file_data != alias->lto_file_data) - local_original->merged = true; - ipa_merge_profiles (local_original, alias, true); - alias->create_wrapper (local_original); - if (dump_file) - fprintf (dump_file, "Callgraph thunk has been created.\n\n"); + fprintf (dump_file, "Unified; Function body was removed.\n"); } - else if (dump_file) - fprintf (dump_file, "Callgraph merge operation cannot be performed.\n\n"); return true; } @@ -1285,7 +1429,8 @@ sem_variable::merge (sem_item *alias_item) if (!sem_item::target_supports_symbol_aliases_p ()) { if (dump_file) - fprintf (dump_file, "Symbol aliases are not supported by target\n\n"); + fprintf (dump_file, "Not unifying; " + "Symbol aliases are not supported by target\n\n"); return false; } @@ -1295,73 +1440,93 @@ sem_variable::merge (sem_item *alias_item) varpool_node *alias = alias_var->get_node (); bool original_discardable = false; + bool original_address_matters = original->address_matters_p (); + bool alias_address_matters = alias->address_matters_p (); + /* See if original is in a section that can be discarded if the main - symbol is not used. */ - if (DECL_EXTERNAL (original->decl)) - original_discardable = true; - if (original->resolution == LDPR_PREEMPTED_REG - || original->resolution == LDPR_PREEMPTED_IR) - original_discardable = true; - if (original->can_be_discarded_p ()) + symbol is not used. + Also consider case where we have resolution info and we know that + original's definition is not going to be used. In this case we can not + create alias to original. */ + if (original->can_be_discarded_p () + || (node->resolution != LDPR_UNKNOWN + && !decl_binds_to_current_def_p (node->decl))) original_discardable = true; gcc_assert (!TREE_ASM_WRITTEN (alias->decl)); - if (original_discardable || DECL_EXTERNAL (alias_var->decl) || - !compare_sections (alias_var)) + /* Constant pool machinery is not quite ready for aliases. + TODO: varasm code contains logic for merging DECL_IN_CONSTANT_POOL. + For LTO merging does not happen that is an important missing feature. + We can enable merging with LTO if the DECL_IN_CONSTANT_POOL + flag is dropped and non-local symbol name is assigned. */ + if (DECL_IN_CONSTANT_POOL (alias->decl) + || DECL_IN_CONSTANT_POOL (original->decl)) { if (dump_file) - fprintf (dump_file, "Varpool alias cannot be created\n\n"); + fprintf (dump_file, + "Not unifying; constant pool variables.\n\n"); + return false; + } + /* Do not attempt to mix functions from different user sections; + we do not know what user intends with those. */ + if (((DECL_SECTION_NAME (original->decl) && !original->implicit_section) + || (DECL_SECTION_NAME (alias->decl) && !alias->implicit_section)) + && DECL_SECTION_NAME (original->decl) != DECL_SECTION_NAME (alias->decl)) + { + if (dump_file) + fprintf (dump_file, + "Not unifying; " + "original and alias are in different sections.\n\n"); return false; } - else + + /* We can not merge if address comparsion metters. */ + if (original_address_matters && alias_address_matters + && flag_merge_constants < 2) { - // alias cycle creation check - varpool_node *n = original; + if (dump_file) + fprintf (dump_file, + "Not unifying; " + "adress of original and alias may be compared.\n\n"); + return false; + } - while (n->alias) - { - n = n->get_alias_target (); - if (n == alias) - { - if (dump_file) - fprintf (dump_file, "Varpool alias cannot be created (alias cycle).\n\n"); + if (original_discardable + && (!DECL_COMDAT_GROUP (original->decl) + || (DECL_COMDAT_GROUP (original->decl) + != DECL_COMDAT_GROUP (alias->decl)))) + { + if (dump_file) + fprintf (dump_file, "Not unifying; alias cannot be created; " + "target is discardable\n\n"); - return false; - } - } + return false; + } + else + { + gcc_assert (!original->alias); + gcc_assert (!alias->alias); alias->analyzed = false; DECL_INITIAL (alias->decl) = NULL; alias->need_bounds_init = false; alias->remove_all_references (); + if (TREE_ADDRESSABLE (alias->decl)) + original->call_for_symbol_and_aliases (set_addressable, NULL, true); varpool_node::create_alias (alias_var->decl, decl); alias->resolve_alias (original); if (dump_file) - fprintf (dump_file, "Varpool alias has been created.\n\n"); + fprintf (dump_file, "Unified; Variable alias has been created.\n\n"); return true; } } -bool -sem_variable::compare_sections (sem_variable *alias) -{ - const char *source = node->get_section (); - const char *target = alias->node->get_section(); - - if (source == NULL && target == NULL) - return true; - else if(!source || !target) - return false; - else - return strcmp (source, target) == 0; -} - /* Dump symbol to FILE. */ void @@ -1500,7 +1665,7 @@ sem_item_optimizer::read_section (lto_file_decl_data *file_data, unsigned int count; lto_input_block ib_main ((const char *) data + main_offset, 0, - header->main_size); + header->main_size, file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, @@ -1714,6 +1879,8 @@ void sem_item_optimizer::execute (void) { filter_removed_items (); + unregister_hooks (); + build_hash_based_classes (); if (dump_file) @@ -1969,6 +2136,84 @@ sem_item_optimizer::subdivide_classes_by_equality (bool in_wpa) verify_classes (); } +/* Subdivide classes by address references that members of the class + reference. Example can be a pair of functions that have an address + taken from a function. If these addresses are different the class + is split. */ + +unsigned +sem_item_optimizer::subdivide_classes_by_sensitive_refs () +{ + unsigned newly_created_classes = 0; + + for (hash_table ::iterator it = m_classes.begin (); + it != m_classes.end (); ++it) + { + unsigned int class_count = (*it)->classes.length (); + auto_vec new_classes; + + for (unsigned i = 0; i < class_count; i++) + { + congruence_class *c = (*it)->classes [i]; + + if (c->members.length() > 1) + { + hash_map , + symbol_compare_hashmap_traits> split_map; + + for (unsigned j = 0; j < c->members.length (); j++) + { + sem_item *source_node = c->members[j]; + + symbol_compare_collection *collection = new symbol_compare_collection (source_node->node); + + vec *slot = &split_map.get_or_insert (collection); + gcc_checking_assert (slot); + + slot->safe_push (source_node); + } + + /* If the map contains more than one key, we have to split the map + appropriately. */ + if (split_map.elements () != 1) + { + bool first_class = true; + + hash_map , + symbol_compare_hashmap_traits>::iterator it2 = split_map.begin (); + for (; it2 != split_map.end (); ++it2) + { + congruence_class *new_cls; + new_cls = new congruence_class (class_id++); + + for (unsigned k = 0; k < (*it2).second.length (); k++) + add_item_to_class (new_cls, (*it2).second[k]); + + worklist_push (new_cls); + newly_created_classes++; + + if (first_class) + { + (*it)->classes[i] = new_cls; + first_class = false; + } + else + { + new_classes.safe_push (new_cls); + m_classes_count++; + } + } + } + } + } + + for (unsigned i = 0; i < new_classes.length (); i++) + (*it)->classes.safe_push (new_classes[i]); + } + + return newly_created_classes; +} + /* Verify congruence classes if checking is enabled. */ void @@ -2258,8 +2503,17 @@ sem_item_optimizer::process_cong_reduction (void) fprintf (dump_file, "Congruence class reduction\n"); congruence_class *cls; + + /* Process complete congruence reduction. */ while ((cls = worklist_pop ()) != NULL) do_congruence_step (cls); + + /* Subdivide newly created classes according to references. */ + unsigned new_classes = subdivide_classes_by_sensitive_refs (); + + if (dump_file) + fprintf (dump_file, "Address reference subdivision created: %u " + "new classes.\n", new_classes); } /* Debug function prints all informations about congruence classes. */ @@ -2482,7 +2736,6 @@ ipa_icf_driver (void) gcc_assert (optimizer); optimizer->execute (); - optimizer->unregister_hooks (); delete optimizer; optimizer = NULL; diff --git a/contrib/gcc-5.0/gcc/ipa-icf.h b/contrib/gcc-5.0/gcc/ipa-icf.h index a55699b9d4..9e762398ab 100644 --- a/contrib/gcc-5.0/gcc/ipa-icf.h +++ b/contrib/gcc-5.0/gcc/ipa-icf.h @@ -63,6 +63,70 @@ enum sem_item_type VAR }; +/* Class is container for address references for a symtab_node. */ + +class symbol_compare_collection +{ +public: + /* Constructor. */ + symbol_compare_collection (symtab_node *node); + + /* Destructor. */ + ~symbol_compare_collection () + { + m_references.release (); + m_interposables.release (); + } + + /* Vector of address references. */ + vec m_references; + + /* Vector of interposable references. */ + vec m_interposables; +}; + +/* Hash traits for symbol_compare_collection map. */ + +struct symbol_compare_hashmap_traits: default_hashmap_traits +{ + static hashval_t + hash (const symbol_compare_collection *v) + { + inchash::hash hstate; + hstate.add_int (v->m_references.length ()); + + for (unsigned i = 0; i < v->m_references.length (); i++) + hstate.add_ptr (v->m_references[i]->ultimate_alias_target ()); + + hstate.add_int (v->m_interposables.length ()); + + for (unsigned i = 0; i < v->m_interposables.length (); i++) + hstate.add_ptr (v->m_interposables[i]->ultimate_alias_target ()); + + return hstate.end (); + } + + static bool + equal_keys (const symbol_compare_collection *a, + const symbol_compare_collection *b) + { + if (a->m_references.length () != b->m_references.length ()) + return false; + + for (unsigned i = 0; i < a->m_references.length (); i++) + if (a->m_references[i]->equal_address_to (b->m_references[i]) != 1) + return false; + + for (unsigned i = 0; i < a->m_interposables.length (); i++) + if (!a->m_interposables[i]->semantically_equivalent_p + (b->m_interposables[i])) + return false; + + return true; + } +}; + + /* Semantic item usage pair. */ class sem_usage_pair { @@ -467,6 +531,13 @@ private: classes. If IN_WPA, fast equality function is invoked. */ void subdivide_classes_by_equality (bool in_wpa = false); + /* Subdivide classes by address and interposable references + that members of the class reference. + Example can be a pair of functions that have an address + taken from a function. If these addresses are different the class + is split. */ + unsigned subdivide_classes_by_sensitive_refs(); + /* Debug function prints all informations about congruence classes. */ void dump_cong_classes (void); diff --git a/contrib/gcc-5.0/gcc/ipa-inline-analysis.c b/contrib/gcc-5.0/gcc/ipa-inline-analysis.c index ea03f10181..be178ad445 100644 --- a/contrib/gcc-5.0/gcc/ipa-inline-analysis.c +++ b/contrib/gcc-5.0/gcc/ipa-inline-analysis.c @@ -4190,7 +4190,8 @@ inline_read_section (struct lto_file_decl_data *file_data, const char *data, unsigned int i, count2, j; unsigned int f_count; - lto_input_block ib ((const char *) data + main_offset, header->main_size); + lto_input_block ib ((const char *) data + main_offset, header->main_size, + file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, diff --git a/contrib/gcc-5.0/gcc/ipa-inline.c b/contrib/gcc-5.0/gcc/ipa-inline.c index 025f7fc5f6..c445f0a7a5 100644 --- a/contrib/gcc-5.0/gcc/ipa-inline.c +++ b/contrib/gcc-5.0/gcc/ipa-inline.c @@ -2559,6 +2559,19 @@ early_inliner (function *fun) { timevar_push (TV_INTEGRATION); todo |= optimize_inline_calls (current_function_decl); + /* optimize_inline_calls call above might have introduced new + statements that don't have inline parameters computed. */ + for (edge = node->callees; edge; edge = edge->next_callee) + { + if (inline_edge_summary_vec.length () > (unsigned) edge->uid) + { + struct inline_edge_summary *es = inline_edge_summary (edge); + es->call_stmt_size + = estimate_num_insns (edge->call_stmt, &eni_size_weights); + es->call_stmt_time + = estimate_num_insns (edge->call_stmt, &eni_time_weights); + } + } inline_update_overall_summary (node); inlined = false; timevar_pop (TV_INTEGRATION); diff --git a/contrib/gcc-5.0/gcc/ipa-prop.c b/contrib/gcc-5.0/gcc/ipa-prop.c index 908b5ee602..cfd9c16ed9 100644 --- a/contrib/gcc-5.0/gcc/ipa-prop.c +++ b/contrib/gcc-5.0/gcc/ipa-prop.c @@ -4868,7 +4868,7 @@ ipa_prop_read_section (struct lto_file_decl_data *file_data, const char *data, unsigned int count; lto_input_block ib_main ((const char *) data + main_offset, - header->main_size); + header->main_size, file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, @@ -5089,7 +5089,7 @@ read_replacements_section (struct lto_file_decl_data *file_data, unsigned int count; lto_input_block ib_main ((const char *) data + main_offset, - header->main_size); + header->main_size, file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, header->string_size, vNULL); diff --git a/contrib/gcc-5.0/gcc/ipa-ref.h b/contrib/gcc-5.0/gcc/ipa-ref.h index aea7f4c8b1..38df8c98b5 100644 --- a/contrib/gcc-5.0/gcc/ipa-ref.h +++ b/contrib/gcc-5.0/gcc/ipa-ref.h @@ -47,6 +47,9 @@ public: function. */ bool cannot_lead_to_return (); + /* Return true if refernece may be used in address compare. */ + bool address_matters_p (); + /* Return reference list this reference is in. */ struct ipa_ref_list * referring_ref_list (void); diff --git a/contrib/gcc-5.0/gcc/ipa-visibility.c b/contrib/gcc-5.0/gcc/ipa-visibility.c index 9247e2976e..7614cfbee4 100644 --- a/contrib/gcc-5.0/gcc/ipa-visibility.c +++ b/contrib/gcc-5.0/gcc/ipa-visibility.c @@ -129,27 +129,6 @@ cgraph_node::local_p (void) } -/* Return true when there is a reference to node and it is not vtable. */ - -bool -symtab_node::address_taken_from_non_vtable_p (void) -{ - int i; - struct ipa_ref *ref = NULL; - - for (i = 0; iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ADDR) - { - varpool_node *node; - if (is_a (ref->referring)) - return true; - node = dyn_cast (ref->referring); - if (!DECL_VIRTUAL_P (node->decl)) - return true; - } - return false; -} - /* A helper for comdat_can_be_unshared_p. */ static bool @@ -157,16 +136,14 @@ comdat_can_be_unshared_p_1 (symtab_node *node) { if (!node->externally_visible) return true; - /* When address is taken, we don't know if equality comparison won't - break eventually. Exception are virutal functions, C++ - constructors/destructors and vtables, where this is not possible by - language standard. */ - if (!DECL_VIRTUAL_P (node->decl) - && (TREE_CODE (node->decl) != FUNCTION_DECL - || (!DECL_CXX_CONSTRUCTOR_P (node->decl) - && !DECL_CXX_DESTRUCTOR_P (node->decl))) - && node->address_taken_from_non_vtable_p ()) - return false; + if (node->address_can_be_compared_p ()) + { + struct ipa_ref *ref; + + for (unsigned int i = 0; node->iterate_referring (i, ref); i++) + if (ref->address_matters_p ()) + return false; + } /* If the symbol is used in some weird way, better to not touch it. */ if (node->force_output) @@ -387,7 +364,8 @@ can_replace_by_local_alias_in_vtable (symtab_node *node) /* walk_tree callback that rewrites initializer references. */ static tree -update_vtable_references (tree *tp, int *walk_subtrees, void *data ATTRIBUTE_UNUSED) +update_vtable_references (tree *tp, int *walk_subtrees, + void *data ATTRIBUTE_UNUSED) { if (TREE_CODE (*tp) == VAR_DECL || TREE_CODE (*tp) == FUNCTION_DECL) diff --git a/contrib/gcc-5.0/gcc/ira-color.c b/contrib/gcc-5.0/gcc/ira-color.c index b77ff69e64..ff1fe8a78a 100644 --- a/contrib/gcc-5.0/gcc/ira-color.c +++ b/contrib/gcc-5.0/gcc/ira-color.c @@ -3274,7 +3274,11 @@ color_pass (ira_loop_tree_node_t loop_tree_node) && (loop_tree_node->reg_pressure[pclass] <= ira_class_hard_regs_num[pclass])) || (pic_offset_table_rtx != NULL - && regno == (int) REGNO (pic_offset_table_rtx))) + && regno == (int) REGNO (pic_offset_table_rtx)) + /* Avoid overlapped multi-registers. Moves between them + might result in wrong code generation. */ + || (hard_regno >= 0 + && ira_reg_class_max_nregs[pclass][mode] > 1)) { if (! ALLOCNO_ASSIGNED_P (subloop_allocno)) { diff --git a/contrib/gcc-5.0/gcc/lra-remat.c b/contrib/gcc-5.0/gcc/lra-remat.c index de5081a739..fb0eb3c1f7 100644 --- a/contrib/gcc-5.0/gcc/lra-remat.c +++ b/contrib/gcc-5.0/gcc/lra-remat.c @@ -459,6 +459,16 @@ operand_to_remat (rtx_insn *insn) reg2 = reg2->next) if (reg2->type == OP_OUT && reg->regno == reg2->regno) return -1; + if (reg->regno < FIRST_PSEUDO_REGISTER) + for (struct lra_insn_reg *reg2 = static_id->hard_regs; + reg2 != NULL; + reg2 = reg2->next) + if (reg2->type == OP_OUT + && reg->regno <= reg2->regno + && (reg2->regno + < (reg->regno + + hard_regno_nregs[reg->regno][reg->biggest_mode]))) + return -1; } /* Find the rematerialization operand. */ int nop = static_id->n_operands; diff --git a/contrib/gcc-5.0/gcc/lto-cgraph.c b/contrib/gcc-5.0/gcc/lto-cgraph.c index 6add7fdf3d..c875fed1db 100644 --- a/contrib/gcc-5.0/gcc/lto-cgraph.c +++ b/contrib/gcc-5.0/gcc/lto-cgraph.c @@ -2122,7 +2122,7 @@ input_cgraph_opt_section (struct lto_file_decl_data *file_data, unsigned int count; lto_input_block ib_main ((const char *) data + main_offset, - header->main_size); + header->main_size, file_data->mode_table); data_in = lto_data_in_create (file_data, (const char *) data + string_offset, diff --git a/contrib/gcc-5.0/gcc/lto-section-in.c b/contrib/gcc-5.0/gcc/lto-section-in.c index 20eded67fb..092b0e2892 100644 --- a/contrib/gcc-5.0/gcc/lto-section-in.c +++ b/contrib/gcc-5.0/gcc/lto-section-in.c @@ -89,7 +89,8 @@ const char *lto_section_name[LTO_N_SECTION_TYPES] = "inline", "ipcp_trans", "icf", - "offload_table" + "offload_table", + "mode_table" }; @@ -262,7 +263,8 @@ lto_create_simple_input_block (struct lto_file_decl_data *file_data, return NULL; *datar = data; - return new lto_input_block (data + main_offset, header->main_size); + return new lto_input_block (data + main_offset, header->main_size, + file_data->mode_table); } diff --git a/contrib/gcc-5.0/gcc/lto-streamer-in.c b/contrib/gcc-5.0/gcc/lto-streamer-in.c index e12d00ac81..a045b9746c 100644 --- a/contrib/gcc-5.0/gcc/lto-streamer-in.c +++ b/contrib/gcc-5.0/gcc/lto-streamer-in.c @@ -1116,10 +1116,12 @@ lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symta /* Set up the struct function. */ from = data_in->reader_cache->nodes.length (); - lto_input_block ib_main (data + main_offset, header->main_size); + lto_input_block ib_main (data + main_offset, header->main_size, + file_data->mode_table); if (TREE_CODE (node->decl) == FUNCTION_DECL) { - lto_input_block ib_cfg (data + cfg_offset, header->cfg_size); + lto_input_block ib_cfg (data + cfg_offset, header->cfg_size, + file_data->mode_table); input_function (fn_decl, data_in, &ib_main, &ib_cfg); } else @@ -1384,7 +1386,8 @@ lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base) string_offset = sizeof (*header) + header->main_size; - lto_input_block ib (data + sizeof (*header), header->main_size); + lto_input_block ib (data + sizeof (*header), header->main_size, + file_data->mode_table); data_in = lto_data_in_create (file_data, data + string_offset, header->string_size, vNULL); @@ -1403,6 +1406,123 @@ lto_input_toplevel_asms (struct lto_file_decl_data *file_data, int order_base) } +/* Input mode table. */ + +void +lto_input_mode_table (struct lto_file_decl_data *file_data) +{ + size_t len; + const char *data = lto_get_section_data (file_data, LTO_section_mode_table, + NULL, &len); + if (! data) + { + internal_error ("cannot read LTO mode table from %s", + file_data->file_name); + return; + } + + unsigned char *table = ggc_cleared_vec_alloc (1 << 8); + file_data->mode_table = table; + const struct lto_simple_header_with_strings *header + = (const struct lto_simple_header_with_strings *) data; + int string_offset; + struct data_in *data_in; + string_offset = sizeof (*header) + header->main_size; + + lto_input_block ib (data + sizeof (*header), header->main_size, NULL); + data_in = lto_data_in_create (file_data, data + string_offset, + header->string_size, vNULL); + bitpack_d bp = streamer_read_bitpack (&ib); + + table[VOIDmode] = VOIDmode; + table[BLKmode] = BLKmode; + unsigned int m; + while ((m = bp_unpack_value (&bp, 8)) != VOIDmode) + { + enum mode_class mclass + = bp_unpack_enum (&bp, mode_class, MAX_MODE_CLASS); + unsigned int size = bp_unpack_value (&bp, 8); + unsigned int prec = bp_unpack_value (&bp, 16); + machine_mode inner = (machine_mode) table[bp_unpack_value (&bp, 8)]; + unsigned int nunits = bp_unpack_value (&bp, 8); + unsigned int ibit = 0, fbit = 0; + unsigned int real_fmt_len = 0; + const char *real_fmt_name = NULL; + switch (mclass) + { + case MODE_FRACT: + case MODE_UFRACT: + case MODE_ACCUM: + case MODE_UACCUM: + ibit = bp_unpack_value (&bp, 8); + fbit = bp_unpack_value (&bp, 8); + break; + case MODE_FLOAT: + case MODE_DECIMAL_FLOAT: + real_fmt_name = bp_unpack_indexed_string (data_in, &bp, + &real_fmt_len); + break; + default: + break; + } + /* First search just the GET_CLASS_NARROWEST_MODE to wider modes, + if not found, fallback to all modes. */ + int pass; + for (pass = 0; pass < 2; pass++) + for (machine_mode mr = pass ? VOIDmode + : GET_CLASS_NARROWEST_MODE (mclass); + pass ? mr < MAX_MACHINE_MODE : mr != VOIDmode; + pass ? mr = (machine_mode) (m + 1) + : mr = GET_MODE_WIDER_MODE (mr)) + if (GET_MODE_CLASS (mr) != mclass + || GET_MODE_SIZE (mr) != size + || GET_MODE_PRECISION (mr) != prec + || GET_MODE_INNER (mr) != inner + || GET_MODE_IBIT (mr) != ibit + || GET_MODE_FBIT (mr) != fbit + || GET_MODE_NUNITS (mr) != nunits) + continue; + else if ((mclass == MODE_FLOAT || mclass == MODE_DECIMAL_FLOAT) + && strcmp (REAL_MODE_FORMAT (mr)->name, real_fmt_name) != 0) + continue; + else + { + table[m] = mr; + pass = 2; + break; + } + unsigned int mname_len; + const char *mname = bp_unpack_indexed_string (data_in, &bp, &mname_len); + if (pass == 2) + { + switch (mclass) + { + case MODE_VECTOR_INT: + case MODE_VECTOR_FLOAT: + case MODE_VECTOR_FRACT: + case MODE_VECTOR_UFRACT: + case MODE_VECTOR_ACCUM: + case MODE_VECTOR_UACCUM: + /* For unsupported vector modes just use BLKmode, + if the scalar mode is supported. */ + if (inner != VOIDmode) + { + table[m] = BLKmode; + break; + } + /* FALLTHRU */ + default: + fatal_error (UNKNOWN_LOCATION, "unsupported mode %s\n", mname); + break; + } + } + } + lto_data_in_delete (data_in); + + lto_free_section_data (file_data, LTO_section_mode_table, NULL, data, len); +} + + /* Initialization for the LTO reader. */ void diff --git a/contrib/gcc-5.0/gcc/lto-streamer-out.c b/contrib/gcc-5.0/gcc/lto-streamer-out.c index 0c27c9d73d..671bac3806 100644 --- a/contrib/gcc-5.0/gcc/lto-streamer-out.c +++ b/contrib/gcc-5.0/gcc/lto-streamer-out.c @@ -2642,6 +2642,96 @@ produce_symtab (struct output_block *ob) } +/* Init the streamer_mode_table for output, where we collect info on what + machine_mode values have been streamed. */ +void +lto_output_init_mode_table (void) +{ + memset (streamer_mode_table, '\0', MAX_MACHINE_MODE); +} + + +/* Write the mode table. */ +static void +lto_write_mode_table (void) +{ + struct output_block *ob; + ob = create_output_block (LTO_section_mode_table); + bitpack_d bp = bitpack_create (ob->main_stream); + + /* Ensure that for GET_MODE_INNER (m) != VOIDmode we have + also the inner mode marked. */ + for (int i = 0; i < (int) MAX_MACHINE_MODE; i++) + if (streamer_mode_table[i]) + { + machine_mode m = (machine_mode) i; + if (GET_MODE_INNER (m) != VOIDmode) + streamer_mode_table[(int) GET_MODE_INNER (m)] = 1; + } + /* First stream modes that have GET_MODE_INNER (m) == VOIDmode, + so that we can refer to them afterwards. */ + for (int pass = 0; pass < 2; pass++) + for (int i = 0; i < (int) MAX_MACHINE_MODE; i++) + if (streamer_mode_table[i] && i != (int) VOIDmode && i != (int) BLKmode) + { + machine_mode m = (machine_mode) i; + if ((GET_MODE_INNER (m) == VOIDmode) ^ (pass == 0)) + continue; + bp_pack_value (&bp, m, 8); + bp_pack_enum (&bp, mode_class, MAX_MODE_CLASS, GET_MODE_CLASS (m)); + bp_pack_value (&bp, GET_MODE_SIZE (m), 8); + bp_pack_value (&bp, GET_MODE_PRECISION (m), 16); + bp_pack_value (&bp, GET_MODE_INNER (m), 8); + bp_pack_value (&bp, GET_MODE_NUNITS (m), 8); + switch (GET_MODE_CLASS (m)) + { + case MODE_FRACT: + case MODE_UFRACT: + case MODE_ACCUM: + case MODE_UACCUM: + bp_pack_value (&bp, GET_MODE_IBIT (m), 8); + bp_pack_value (&bp, GET_MODE_FBIT (m), 8); + break; + case MODE_FLOAT: + case MODE_DECIMAL_FLOAT: + bp_pack_string (ob, &bp, REAL_MODE_FORMAT (m)->name, true); + break; + default: + break; + } + bp_pack_string (ob, &bp, GET_MODE_NAME (m), true); + } + bp_pack_value (&bp, VOIDmode, 8); + + streamer_write_bitpack (&bp); + + char *section_name + = lto_get_section_name (LTO_section_mode_table, NULL, NULL); + lto_begin_section (section_name, !flag_wpa); + free (section_name); + + /* The entire header stream is computed here. */ + struct lto_simple_header_with_strings header; + memset (&header, 0, sizeof (header)); + + /* Write the header. */ + header.major_version = LTO_major_version; + header.minor_version = LTO_minor_version; + + header.main_size = ob->main_stream->total_size; + header.string_size = ob->string_stream->total_size; + lto_write_data (&header, sizeof header); + + /* Put all of the gimple and the string table out the asm file as a + block of text. */ + lto_write_stream (ob->main_stream); + lto_write_stream (ob->string_stream); + + lto_end_section (); + destroy_output_block (ob); +} + + /* This pass is run after all of the functions are serialized and all of the IPA passes have written their serialized forms. This pass causes the vector of all of the global decls and types used from @@ -2749,4 +2839,6 @@ produce_asm_for_decls (void) lto_symtab_encoder_delete (ob->decl_state->symtab_node_encoder); lto_function_decl_states.release (); destroy_output_block (ob); + if (lto_stream_offload_p) + lto_write_mode_table (); } diff --git a/contrib/gcc-5.0/gcc/lto-streamer.h b/contrib/gcc-5.0/gcc/lto-streamer.h index 2d9f30c79c..c8862a290e 100644 --- a/contrib/gcc-5.0/gcc/lto-streamer.h +++ b/contrib/gcc-5.0/gcc/lto-streamer.h @@ -248,6 +248,7 @@ enum lto_section_type LTO_section_ipcp_transform, LTO_section_ipa_icf, LTO_section_offload_table, + LTO_section_mode_table, LTO_N_SECTION_TYPES /* Must be last. */ }; @@ -312,12 +313,15 @@ class lto_input_block public: /* Special constructor for the string table, it abuses this to do random access but use the uhwi decoder. */ - lto_input_block (const char *data_, unsigned int p_, unsigned int len_) - : data (data_), p (p_), len (len_) {} - lto_input_block (const char *data_, unsigned int len_) - : data (data_), p (0), len (len_) {} + lto_input_block (const char *data_, unsigned int p_, unsigned int len_, + const unsigned char *mode_table_) + : data (data_), mode_table (mode_table_), p (p_), len (len_) {} + lto_input_block (const char *data_, unsigned int len_, + const unsigned char *mode_table_) + : data (data_), mode_table (mode_table_), p (0), len (len_) {} const char *data; + const unsigned char *mode_table; unsigned int p; unsigned int len; }; @@ -527,6 +531,9 @@ struct GTY(()) lto_file_decl_data /* Map assigning declarations their resolutions. */ hash_map * GTY((skip)) resolution_map; + + /* Mode translation table. */ + const unsigned char *mode_table; }; typedef struct lto_file_decl_data *lto_file_decl_data_ptr; @@ -775,6 +782,7 @@ extern void lto_input_variable_constructor (struct lto_file_decl_data *, extern void lto_input_constructors_and_inits (struct lto_file_decl_data *, const char *); extern void lto_input_toplevel_asms (struct lto_file_decl_data *, int); +extern void lto_input_mode_table (struct lto_file_decl_data *); extern struct data_in *lto_data_in_create (struct lto_file_decl_data *, const char *, unsigned, vec ); @@ -807,6 +815,7 @@ void lto_output_decl_state_refs (struct output_block *, struct lto_output_stream *, struct lto_out_decl_state *); void lto_output_location (struct output_block *, struct bitpack_d *, location_t); +void lto_output_init_mode_table (void); /* In lto-cgraph.c */ diff --git a/contrib/gcc-5.0/gcc/lto/lto-lang.c b/contrib/gcc-5.0/gcc/lto/lto-lang.c index aa474e07d8..073bf17cd1 100644 --- a/contrib/gcc-5.0/gcc/lto/lto-lang.c +++ b/contrib/gcc-5.0/gcc/lto/lto-lang.c @@ -176,12 +176,11 @@ enum lto_builtin_type #define DEF_FUNCTION_TYPE_VAR_3(NAME, RETURN, ARG1, ARG2, ARG3) NAME, #define DEF_FUNCTION_TYPE_VAR_4(NAME, RETURN, ARG1, ARG2, ARG3, ARG4) NAME, #define DEF_FUNCTION_TYPE_VAR_5(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG6) \ - NAME, -#define DEF_FUNCTION_TYPE_VAR_8(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8) NAME, -#define DEF_FUNCTION_TYPE_VAR_12(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, \ - ARG12) NAME, + NAME, +#define DEF_FUNCTION_TYPE_VAR_7(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ + ARG6, ARG7) NAME, +#define DEF_FUNCTION_TYPE_VAR_11(NAME, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ + ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) NAME, #define DEF_POINTER_TYPE(NAME, TYPE) NAME, #include "builtin-types.def" #undef DEF_PRIMITIVE_TYPE @@ -200,8 +199,8 @@ enum lto_builtin_type #undef DEF_FUNCTION_TYPE_VAR_3 #undef DEF_FUNCTION_TYPE_VAR_4 #undef DEF_FUNCTION_TYPE_VAR_5 -#undef DEF_FUNCTION_TYPE_VAR_8 -#undef DEF_FUNCTION_TYPE_VAR_12 +#undef DEF_FUNCTION_TYPE_VAR_7 +#undef DEF_FUNCTION_TYPE_VAR_11 #undef DEF_POINTER_TYPE BT_LAST }; @@ -686,14 +685,13 @@ lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED, def_fn_type (ENUM, RETURN, 1, 4, ARG1, ARG2, ARG3, ARG4); #define DEF_FUNCTION_TYPE_VAR_5(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5) \ def_fn_type (ENUM, RETURN, 1, 5, ARG1, ARG2, ARG3, ARG4, ARG5); -#define DEF_FUNCTION_TYPE_VAR_8(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8) \ - def_fn_type (ENUM, RETURN, 1, 8, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ - ARG7, ARG8); -#define DEF_FUNCTION_TYPE_VAR_12(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ - ARG6, ARG7, ARG8, ARG9, ARG10, ARG11, ARG12) \ - def_fn_type (ENUM, RETURN, 1, 12, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ - ARG7, ARG8, ARG9, ARG10, ARG11, ARG12); +#define DEF_FUNCTION_TYPE_VAR_7(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ + ARG6, ARG7) \ + def_fn_type (ENUM, RETURN, 1, 7, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, ARG7); +#define DEF_FUNCTION_TYPE_VAR_11(ENUM, RETURN, ARG1, ARG2, ARG3, ARG4, ARG5, \ + ARG6, ARG7, ARG8, ARG9, ARG10, ARG11) \ + def_fn_type (ENUM, RETURN, 1, 11, ARG1, ARG2, ARG3, ARG4, ARG5, ARG6, \ + ARG7, ARG8, ARG9, ARG10, ARG11); #define DEF_POINTER_TYPE(ENUM, TYPE) \ builtin_types[(int) ENUM] = build_pointer_type (builtin_types[(int) TYPE]); @@ -715,8 +713,8 @@ lto_define_builtins (tree va_list_ref_type_node ATTRIBUTE_UNUSED, #undef DEF_FUNCTION_TYPE_VAR_3 #undef DEF_FUNCTION_TYPE_VAR_4 #undef DEF_FUNCTION_TYPE_VAR_5 -#undef DEF_FUNCTION_TYPE_VAR_8 -#undef DEF_FUNCTION_TYPE_VAR_12 +#undef DEF_FUNCTION_TYPE_VAR_7 +#undef DEF_FUNCTION_TYPE_VAR_11 #undef DEF_POINTER_TYPE builtin_types[(int) BT_LAST] = NULL_TREE; diff --git a/contrib/gcc-5.0/gcc/lto/lto.c b/contrib/gcc-5.0/gcc/lto/lto.c index c86f8358f3..ce7e6b1974 100644 --- a/contrib/gcc-5.0/gcc/lto/lto.c +++ b/contrib/gcc-5.0/gcc/lto/lto.c @@ -85,6 +85,8 @@ static int lto_parallelism; static GTY(()) tree first_personality_decl; +static GTY(()) const unsigned char *lto_mode_identity_table; + /* Returns a hash code for P. */ static hashval_t @@ -1877,7 +1879,7 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data, uint32_t num_decl_states; lto_input_block ib_main ((const char *) data + main_offset, - header->main_size); + header->main_size, decl_data->mode_table); data_in = lto_data_in_create (decl_data, (const char *) data + string_offset, header->string_size, resolutions); @@ -2219,6 +2221,11 @@ lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file) file_data->renaming_hash_table = lto_create_renaming_table (); file_data->file_name = file->filename; +#ifdef ACCEL_COMPILER + lto_input_mode_table (file_data); +#else + file_data->mode_table = lto_mode_identity_table; +#endif data = lto_get_section_data (file_data, LTO_section_decls, NULL, &len); if (data == NULL) { @@ -3394,6 +3401,13 @@ lto_init (void) memset (<o_stats, 0, sizeof (lto_stats)); bitmap_obstack_initialize (NULL); gimple_register_cfg_hooks (); +#ifndef ACCEL_COMPILER + unsigned char *table + = ggc_vec_alloc (MAX_MACHINE_MODE); + for (int m = 0; m < MAX_MACHINE_MODE; m++) + table[m] = m; + lto_mode_identity_table = table; +#endif } diff --git a/contrib/gcc-5.0/gcc/omp-builtins.def b/contrib/gcc-5.0/gcc/omp-builtins.def index 6aea7b7a97..50f1321f9a 100644 --- a/contrib/gcc-5.0/gcc/omp-builtins.def +++ b/contrib/gcc-5.0/gcc/omp-builtins.def @@ -32,17 +32,17 @@ along with GCC; see the file COPYING3. If not see DEF_GOACC_BUILTIN (BUILT_IN_ACC_GET_DEVICE_TYPE, "acc_get_device_type", BT_FN_INT, ATTR_NOTHROW_LIST) DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DATA_START, "GOACC_data_start", - BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST) + BT_FN_VOID_INT_SIZE_PTR_PTR_PTR, ATTR_NOTHROW_LIST) DEF_GOACC_BUILTIN (BUILT_IN_GOACC_DATA_END, "GOACC_data_end", BT_FN_VOID, ATTR_NOTHROW_LIST) DEF_GOACC_BUILTIN (BUILT_IN_GOACC_ENTER_EXIT_DATA, "GOACC_enter_exit_data", - BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR, + BT_FN_VOID_INT_SIZE_PTR_PTR_PTR_INT_INT_VAR, ATTR_NOTHROW_LIST) DEF_GOACC_BUILTIN (BUILT_IN_GOACC_PARALLEL, "GOACC_parallel", - BT_FN_VOID_INT_OMPFN_PTR_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR, + BT_FN_VOID_INT_OMPFN_SIZE_PTR_PTR_PTR_INT_INT_INT_INT_INT_VAR, ATTR_NOTHROW_LIST) DEF_GOACC_BUILTIN (BUILT_IN_GOACC_UPDATE, "GOACC_update", - BT_FN_VOID_INT_PTR_SIZE_PTR_PTR_PTR_INT_INT_VAR, + BT_FN_VOID_INT_SIZE_PTR_PTR_PTR_INT_INT_VAR, ATTR_NOTHROW_LIST) DEF_GOACC_BUILTIN (BUILT_IN_GOACC_WAIT, "GOACC_wait", BT_FN_VOID_INT_INT_VAR, diff --git a/contrib/gcc-5.0/gcc/omp-low.c b/contrib/gcc-5.0/gcc/omp-low.c index 182836b3a6..75d6707f19 100644 --- a/contrib/gcc-5.0/gcc/omp-low.c +++ b/contrib/gcc-5.0/gcc/omp-low.c @@ -2176,6 +2176,13 @@ create_omp_child_function (omp_context *ctx, bool task_copy) } } + if (cgraph_node::get_create (decl)->offloadable + && !lookup_attribute ("omp declare target", + DECL_ATTRIBUTES (current_function_decl))) + DECL_ATTRIBUTES (decl) + = tree_cons (get_identifier ("omp target entrypoint"), + NULL_TREE, DECL_ATTRIBUTES (decl)); + t = build_decl (DECL_SOURCE_LOCATION (decl), RESULT_DECL, NULL_TREE, void_type_node); DECL_ARTIFICIAL (t) = 1; diff --git a/contrib/gcc-5.0/gcc/passes.c b/contrib/gcc-5.0/gcc/passes.c index dff70e5bbe..23a90d9e2e 100644 --- a/contrib/gcc-5.0/gcc/passes.c +++ b/contrib/gcc-5.0/gcc/passes.c @@ -2460,6 +2460,7 @@ ipa_write_summaries_1 (lto_symtab_encoder_t encoder) struct lto_out_decl_state *state = lto_new_out_decl_state (); state->symtab_node_encoder = encoder; + lto_output_init_mode_table (); lto_push_out_decl_state (state); gcc_assert (!flag_wpa); @@ -2581,6 +2582,7 @@ ipa_write_optimization_summaries (lto_symtab_encoder_t encoder) lto_symtab_encoder_iterator lsei; state->symtab_node_encoder = encoder; + lto_output_init_mode_table (); lto_push_out_decl_state (state); for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei); lsei_next_function_in_partition (&lsei)) diff --git a/contrib/gcc-5.0/gcc/real.c b/contrib/gcc-5.0/gcc/real.c index 01b169ed32..1d1d510333 100644 --- a/contrib/gcc-5.0/gcc/real.c +++ b/contrib/gcc-5.0/gcc/real.c @@ -3031,7 +3031,8 @@ const struct real_format ieee_single_format = true, true, true, - false + false, + "ieee_single" }; const struct real_format mips_single_format = @@ -3052,7 +3053,8 @@ const struct real_format mips_single_format = true, true, false, - true + true, + "mips_single" }; const struct real_format motorola_single_format = @@ -3073,7 +3075,8 @@ const struct real_format motorola_single_format = true, true, true, - true + true, + "motorola_single" }; /* SPU Single Precision (Extended-Range Mode) format is the same as IEEE @@ -3105,7 +3108,8 @@ const struct real_format spu_single_format = true, true, false, - false + false, + "spu_single" }; /* IEEE double-precision format. */ @@ -3314,7 +3318,8 @@ const struct real_format ieee_double_format = true, true, true, - false + false, + "ieee_double" }; const struct real_format mips_double_format = @@ -3335,7 +3340,8 @@ const struct real_format mips_double_format = true, true, false, - true + true, + "mips_double" }; const struct real_format motorola_double_format = @@ -3356,7 +3362,8 @@ const struct real_format motorola_double_format = true, true, true, - true + true, + "motorola_double" }; /* IEEE extended real format. This comes in three flavors: Intel's as @@ -3700,7 +3707,8 @@ const struct real_format ieee_extended_motorola_format = true, true, true, - true + true, + "ieee_extended_motorola" }; const struct real_format ieee_extended_intel_96_format = @@ -3721,7 +3729,8 @@ const struct real_format ieee_extended_intel_96_format = true, true, true, - false + false, + "ieee_extended_intel_96" }; const struct real_format ieee_extended_intel_128_format = @@ -3742,7 +3751,8 @@ const struct real_format ieee_extended_intel_128_format = true, true, true, - false + false, + "ieee_extended_intel_128" }; /* The following caters to i386 systems that set the rounding precision @@ -3765,7 +3775,8 @@ const struct real_format ieee_extended_intel_96_round_53_format = true, true, true, - false + false, + "ieee_extended_intel_96_round_53" }; /* IBM 128-bit extended precision format: a pair of IEEE double precision @@ -3853,7 +3864,8 @@ const struct real_format ibm_extended_format = true, true, true, - false + false, + "ibm_extended" }; const struct real_format mips_extended_format = @@ -3874,7 +3886,8 @@ const struct real_format mips_extended_format = true, true, false, - true + true, + "mips_extended" }; @@ -4137,7 +4150,8 @@ const struct real_format ieee_quad_format = true, true, true, - false + false, + "ieee_quad" }; const struct real_format mips_quad_format = @@ -4158,7 +4172,8 @@ const struct real_format mips_quad_format = true, true, false, - true + true, + "mips_quad" }; /* Descriptions of VAX floating point formats can be found beginning at @@ -4458,7 +4473,8 @@ const struct real_format vax_f_format = false, false, false, - false + false, + "vax_f" }; const struct real_format vax_d_format = @@ -4479,7 +4495,8 @@ const struct real_format vax_d_format = false, false, false, - false + false, + "vax_d" }; const struct real_format vax_g_format = @@ -4500,7 +4517,8 @@ const struct real_format vax_g_format = false, false, false, - false + false, + "vax_g" }; /* Encode real R into a single precision DFP value in BUF. */ @@ -4576,7 +4594,8 @@ const struct real_format decimal_single_format = true, true, true, - false + false, + "decimal_single" }; /* Double precision decimal floating point (IEEE 754). */ @@ -4598,7 +4617,8 @@ const struct real_format decimal_double_format = true, true, true, - false + false, + "decimal_double" }; /* Quad precision decimal floating point (IEEE 754). */ @@ -4620,7 +4640,8 @@ const struct real_format decimal_quad_format = true, true, true, - false + false, + "decimal_quad" }; /* Encode half-precision floats. This routine is used both for the IEEE @@ -4757,7 +4778,8 @@ const struct real_format ieee_half_format = true, true, true, - false + false, + "ieee_half" }; /* ARM's alternative half-precision format, similar to IEEE but with @@ -4781,7 +4803,8 @@ const struct real_format arm_half_format = true, true, false, - false + false, + "arm_half" }; /* A synthetic "format" for internal arithmetic. It's the size of the @@ -4826,7 +4849,8 @@ const struct real_format real_internal_format = false, true, true, - false + false, + "real_internal" }; /* Calculate X raised to the integer exponent N in mode MODE and store diff --git a/contrib/gcc-5.0/gcc/real.h b/contrib/gcc-5.0/gcc/real.h index 424a27a9f2..37a8499baa 100644 --- a/contrib/gcc-5.0/gcc/real.h +++ b/contrib/gcc-5.0/gcc/real.h @@ -155,6 +155,7 @@ struct real_format bool has_signed_zero; bool qnan_msb_set; bool canonical_nan_lsbs_set; + const char *name; }; diff --git a/contrib/gcc-5.0/gcc/symtab.c b/contrib/gcc-5.0/gcc/symtab.c index 7a70b100da..a46ebd49ef 100644 --- a/contrib/gcc-5.0/gcc/symtab.c +++ b/contrib/gcc-5.0/gcc/symtab.c @@ -1156,7 +1156,11 @@ symtab_node::make_decl_local (void) return; if (TREE_CODE (decl) == VAR_DECL) - DECL_COMMON (decl) = 0; + { + DECL_COMMON (decl) = 0; + /* ADDRESSABLE flag is not defined for public symbols. */ + TREE_ADDRESSABLE (decl) = 1; + } else gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); DECL_COMDAT (decl) = 0; @@ -1165,6 +1169,7 @@ symtab_node::make_decl_local (void) DECL_VISIBILITY_SPECIFIED (decl) = 0; DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT; TREE_PUBLIC (decl) = 0; + DECL_DLLIMPORT_P (decl) = 0; if (!DECL_RTL_SET_P (decl)) return; @@ -1512,6 +1517,19 @@ symtab_node::resolve_alias (symtab_node *target) /* If alias has address taken, so does the target. */ if (address_taken) target->ultimate_alias_target ()->address_taken = true; + + /* All non-weakref aliases of THIS are now in fact aliases of TARGET. */ + ipa_ref *ref; + for (unsigned i = 0; iterate_direct_aliases (i, ref);) + { + struct symtab_node *alias_alias = ref->referring; + if (!alias_alias->weakref) + { + alias_alias->remove_all_references (); + alias_alias->create_reference (target, IPA_REF_ALIAS, NULL); + } + else i++; + } return true; } @@ -1534,7 +1552,6 @@ symtab_node::noninterposable_alias (symtab_node *node, void *data) != flags_from_decl_or_type (fn->decl)) || DECL_ATTRIBUTES (node->decl) != DECL_ATTRIBUTES (fn->decl)) return false; - *(symtab_node **)data = node; return true; } @@ -1566,6 +1583,7 @@ symtab_node::noninterposable_alias (void) /* Otherwise create a new one. */ new_decl = copy_node (node->decl); + DECL_DLLIMPORT_P (new_decl) = 0; DECL_NAME (new_decl) = clone_function_name (node->decl, "localalias"); if (TREE_CODE (new_decl) == FUNCTION_DECL) DECL_STRUCT_FUNCTION (new_decl) = NULL; @@ -1862,3 +1880,31 @@ symtab_node::call_for_symbol_and_aliases_1 (bool (*callback) (symtab_node *, } return false; } + +/* Return ture if address of N is possibly compared. */ + +static bool +address_matters_1 (symtab_node *n, void *) +{ + struct ipa_ref *ref; + + if (!n->address_can_be_compared_p ()) + return false; + if (n->externally_visible || n->force_output) + return true; + + for (unsigned int i = 0; n->iterate_referring (i, ref); i++) + if (ref->address_matters_p ()) + return true; + return false; +} + +/* Return true if symbol's address may possibly be compared to other + symbol's address. */ + +bool +symtab_node::address_matters_p () +{ + gcc_assert (!alias); + return call_for_symbol_and_aliases (address_matters_1, NULL, true); +} diff --git a/contrib/gcc-5.0/gcc/target.def b/contrib/gcc-5.0/gcc/target.def index 356f7c1c9a..a00181aa9b 100644 --- a/contrib/gcc-5.0/gcc/target.def +++ b/contrib/gcc-5.0/gcc/target.def @@ -1868,6 +1868,13 @@ recorded in the offload function and variable table.", void, (tree), hook_void_tree) +DEFHOOKPOD +(absolute_biggest_alignment, + "If defined, this target hook specifies the absolute biggest alignment\n\ +that a type or variable can have on this machine, otherwise,\n\ +@code{BIGGEST_ALIGNMENT} is used.", + HOST_WIDE_INT, BIGGEST_ALIGNMENT) + /* Allow target specific overriding of option settings after options have been changed by an attribute or pragma or when it is reset at the end of the code affected by an attribute or pragma. */ @@ -5494,6 +5501,15 @@ information in the @code{struct cl_target_option} structure for\n\ function-specific options to the @code{struct gcc_options} structure.", void, (struct gcc_options *opts, struct cl_target_option *ptr), NULL) +/* Function to update target-specific option information after being + streamed in. */ +DEFHOOK +(post_stream_in, + "This hook is called to update target-specific information in the\n\ +@code{struct cl_target_option} structure after it is streamed in from\n\ +LTO bytecode.", + void, (struct cl_target_option *ptr), NULL) + /* Function to print any extra target state from the target options structure. */ DEFHOOK diff --git a/contrib/gcc-5.0/gcc/tree-ssa-math-opts.c b/contrib/gcc-5.0/gcc/tree-ssa-math-opts.c index e30116dab1..c22a677e80 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-math-opts.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-math-opts.c @@ -1780,6 +1780,10 @@ find_bswap_or_nop_load (gimple stmt, tree ref, struct symbolic_number *n) int unsignedp, volatilep; tree offset, base_addr; + /* Not prepared to handle PDP endian. */ + if (BYTES_BIG_ENDIAN != WORDS_BIG_ENDIAN) + return false; + if (!gimple_assign_load_p (stmt) || gimple_has_volatile_ops (stmt)) return false; @@ -1860,8 +1864,8 @@ perform_symbolic_merge (gimple source_stmt1, struct symbolic_number *n1, || !operand_equal_p (n1->base_addr, n2->base_addr, 0)) return NULL; - if (!n1->offset != !n2->offset || - (n1->offset && !operand_equal_p (n1->offset, n2->offset, 0))) + if (!n1->offset != !n2->offset + || (n1->offset && !operand_equal_p (n1->offset, n2->offset, 0))) return NULL; if (n1->bytepos < n2->bytepos) @@ -1912,8 +1916,8 @@ perform_symbolic_merge (gimple source_stmt1, struct symbolic_number *n1, size = TYPE_PRECISION (n1->type) / BITS_PER_UNIT; for (i = 0; i < size; i++, inc <<= BITS_PER_MARKER) { - unsigned marker = - (toinc_n_ptr->n >> (i * BITS_PER_MARKER)) & MARKER_MASK; + unsigned marker + = (toinc_n_ptr->n >> (i * BITS_PER_MARKER)) & MARKER_MASK; if (marker && marker != MARKER_BYTE_UNKNOWN) toinc_n_ptr->n += inc; } @@ -2032,7 +2036,7 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) case RSHIFT_EXPR: case LROTATE_EXPR: case RROTATE_EXPR: - if (!do_shift_rotate (code, n, (int)TREE_INT_CST_LOW (rhs2))) + if (!do_shift_rotate (code, n, (int) TREE_INT_CST_LOW (rhs2))) return NULL; break; CASE_CONVERT: @@ -2104,12 +2108,12 @@ find_bswap_or_nop_1 (gimple stmt, struct symbolic_number *n, int limit) if (TYPE_PRECISION (n1.type) != TYPE_PRECISION (n2.type)) return NULL; - if (!n1.vuse != !n2.vuse || - (n1.vuse && !operand_equal_p (n1.vuse, n2.vuse, 0))) + if (!n1.vuse != !n2.vuse + || (n1.vuse && !operand_equal_p (n1.vuse, n2.vuse, 0))) return NULL; - source_stmt = - perform_symbolic_merge (source_stmt1, &n1, source_stmt2, &n2, n); + source_stmt + = perform_symbolic_merge (source_stmt1, &n1, source_stmt2, &n2, n); if (!source_stmt) return NULL; @@ -2153,12 +2157,12 @@ find_bswap_or_nop (gimple stmt, struct symbolic_number *n, bool *bswap) in libgcc, and for initial shift/and operation of the src operand. */ limit = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (gimple_expr_type (stmt))); limit += 1 + (int) ceil_log2 ((unsigned HOST_WIDE_INT) limit); - source_stmt = find_bswap_or_nop_1 (stmt, n, limit); + source_stmt = find_bswap_or_nop_1 (stmt, n, limit); if (!source_stmt) return NULL; - /* Find real size of result (highest non zero byte). */ + /* Find real size of result (highest non-zero byte). */ if (n->base_addr) { int rsize; @@ -2261,8 +2265,30 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type, tree load_offset_ptr, aligned_load_type; gimple addr_stmt, load_stmt; unsigned align; + HOST_WIDE_INT load_offset = 0; align = get_object_alignment (src); + /* If the new access is smaller than the original one, we need + to perform big endian adjustment. */ + if (BYTES_BIG_ENDIAN) + { + HOST_WIDE_INT bitsize, bitpos; + machine_mode mode; + int unsignedp, volatilep; + tree offset; + + get_inner_reference (src, &bitsize, &bitpos, &offset, &mode, + &unsignedp, &volatilep, false); + if (n->range < (unsigned HOST_WIDE_INT) bitsize) + { + load_offset = (bitsize - n->range) / BITS_PER_UNIT; + unsigned HOST_WIDE_INT l + = (load_offset * BITS_PER_UNIT) & (align - 1); + if (l) + align = l & -l; + } + } + if (bswap && align < GET_MODE_ALIGNMENT (TYPE_MODE (load_type)) && SLOW_UNALIGNED_ACCESS (TYPE_MODE (load_type), align)) @@ -2274,10 +2300,10 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type, gsi_move_before (&gsi, &gsi_ins); gsi = gsi_for_stmt (cur_stmt); - /* Compute address to load from and cast according to the size - of the load. */ + /* Compute address to load from and cast according to the size + of the load. */ addr_expr = build_fold_addr_expr (unshare_expr (src)); - if (is_gimple_min_invariant (addr_expr)) + if (is_gimple_mem_ref_addr (addr_expr)) addr_tmp = addr_expr; else { @@ -2291,7 +2317,7 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type, aligned_load_type = load_type; if (align < TYPE_ALIGN (load_type)) aligned_load_type = build_aligned_type (load_type, align); - load_offset_ptr = build_int_cst (n->alias_set, 0); + load_offset_ptr = build_int_cst (n->alias_set, load_offset); val_expr = fold_build2 (MEM_REF, aligned_load_type, addr_tmp, load_offset_ptr); @@ -2328,7 +2354,7 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type, { fprintf (dump_file, "%d bit load in target endianness found at: ", - (int)n->range); + (int) n->range); print_gimple_stmt (dump_file, cur_stmt, 0, 0); } return true; @@ -2395,7 +2421,7 @@ bswap_replace (gimple cur_stmt, gimple src_stmt, tree fndecl, tree bswap_type, if (dump_file) { fprintf (dump_file, "%d bit bswap implementation found at: ", - (int)n->range); + (int) n->range); print_gimple_stmt (dump_file, cur_stmt, 0, 0); } diff --git a/contrib/gcc-5.0/gcc/tree-ssa-propagate.c b/contrib/gcc-5.0/gcc/tree-ssa-propagate.c index 6d665ea010..8b82f9e208 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-propagate.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-propagate.c @@ -66,6 +66,7 @@ #include "langhooks.h" #include "value-prof.h" #include "domwalk.h" +#include "cfgloop.h" /* This file implements a generic value propagation engine based on the same propagation used by the SSA-CCP algorithm [1]. @@ -992,6 +993,7 @@ replace_phi_args_in (gphi *phi, ssa_prop_get_value_fn get_value) print_gimple_stmt (dump_file, phi, 0, TDF_SLIM); } + basic_block bb = gimple_bb (phi); for (i = 0; i < gimple_phi_num_args (phi); i++) { tree arg = gimple_phi_arg_def (phi, i); @@ -1002,6 +1004,21 @@ replace_phi_args_in (gphi *phi, ssa_prop_get_value_fn get_value) if (val && val != arg && may_propagate_copy (arg, val)) { + edge e = gimple_phi_arg_edge (phi, i); + + /* Avoid propagating constants into loop latch edge + PHI arguments as this makes coalescing the copy + across this edge impossible. If the argument is + defined by an assert - otherwise the stmt will + get removed without replacing its uses. */ + if (TREE_CODE (val) != SSA_NAME + && bb->loop_father->header == bb + && dominated_by_p (CDI_DOMINATORS, e->src, bb) + && is_gimple_assign (SSA_NAME_DEF_STMT (arg)) + && (gimple_assign_rhs_code (SSA_NAME_DEF_STMT (arg)) + == ASSERT_EXPR)) + continue; + if (TREE_CODE (val) != SSA_NAME) prop_stats.num_const_prop++; else @@ -1014,8 +1031,15 @@ replace_phi_args_in (gphi *phi, ssa_prop_get_value_fn get_value) through an abnormal edge, update the replacement accordingly. */ if (TREE_CODE (val) == SSA_NAME - && gimple_phi_arg_edge (phi, i)->flags & EDGE_ABNORMAL) - SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1; + && e->flags & EDGE_ABNORMAL + && !SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)) + { + /* This can only occur for virtual operands, since + for the real ones SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val)) + would prevent replacement. */ + gcc_checking_assert (virtual_operand_p (val)); + SSA_NAME_OCCURS_IN_ABNORMAL_PHI (val) = 1; + } } } } diff --git a/contrib/gcc-5.0/gcc/tree-ssa-reassoc.c b/contrib/gcc-5.0/gcc/tree-ssa-reassoc.c index ce37053bdb..2e933e769f 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-reassoc.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-reassoc.c @@ -3532,7 +3532,7 @@ rewrite_expr_tree (gimple stmt, unsigned int opindex, /* The final recursion case for this function is that you have exactly two operations left. - If we had one exactly one op in the entire list to start with, we + If we had exactly one op in the entire list to start with, we would have never called this function, and the tail recursion rewrites them one at a time. */ if (opindex + 2 == ops.length ()) @@ -3553,7 +3553,11 @@ rewrite_expr_tree (gimple stmt, unsigned int opindex, print_gimple_stmt (dump_file, stmt, 0, 0); } - if (changed) + /* Even when changed is false, reassociation could have e.g. removed + some redundant operations, so unless we are just swapping the + arguments or unless there is no change at all (then we just + return lhs), force creation of a new SSA_NAME. */ + if (changed || ((rhs1 != oe2->op || rhs2 != oe1->op) && opindex)) { gimple insert_point = find_insert_point (stmt, oe1->op, oe2->op); lhs = make_ssa_name (TREE_TYPE (lhs)); diff --git a/contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c b/contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c index 3326144fe7..7a159bbb67 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-threadupdate.c @@ -197,6 +197,9 @@ dump_jump_thread_path (FILE *dump_file, vec path, if (path[i]->type == EDGE_NO_COPY_SRC_BLOCK) fprintf (dump_file, " (%d, %d) nocopy;", path[i]->e->src->index, path[i]->e->dest->index); + if (path[0]->type == EDGE_FSM_THREAD) + fprintf (dump_file, " (%d, %d) ", + path[i]->e->src->index, path[i]->e->dest->index); } fputc ('\n', dump_file); } @@ -2473,6 +2476,21 @@ duplicate_seme_region (edge entry, edge exit, return true; } +/* Return true when PATH is a valid jump-thread path. */ + +static bool +valid_jump_thread_path (vec *path) +{ + unsigned len = path->length (); + + /* Check that the path is connected. */ + for (unsigned int j = 0; j < len - 1; j++) + if ((*path)[j]->e->dest != (*path)[j+1]->e->src) + return false; + + return true; +} + /* Walk through all blocks and thread incoming edges to the appropriate outgoing edge for each edge pair recorded in THREADED_EDGES. @@ -2505,12 +2523,25 @@ thread_through_all_blocks (bool may_peel_loop_headers) vec *path = paths[i]; edge entry = (*path)[0]->e; - if ((*path)[0]->type != EDGE_FSM_THREAD - /* Do not jump-thread twice from the same block. */ - || bitmap_bit_p (threaded_blocks, entry->src->index)) { - i++; - continue; - } + /* Only code-generate FSM jump-threads in this loop. */ + if ((*path)[0]->type != EDGE_FSM_THREAD) + { + i++; + continue; + } + + /* Do not jump-thread twice from the same block. */ + if (bitmap_bit_p (threaded_blocks, entry->src->index) + /* Verify that the jump thread path is still valid: a + previous jump-thread may have changed the CFG, and + invalidated the current path. */ + || !valid_jump_thread_path (path)) + { + /* Remove invalid FSM jump-thread paths. */ + delete_jump_thread_path (path); + paths.unordered_remove (i); + continue; + } unsigned len = path->length (); edge exit = (*path)[len - 1]->e; diff --git a/contrib/gcc-5.0/gcc/tree-streamer-in.c b/contrib/gcc-5.0/gcc/tree-streamer-in.c index 506e676f56..42e2a73393 100644 --- a/contrib/gcc-5.0/gcc/tree-streamer-in.c +++ b/contrib/gcc-5.0/gcc/tree-streamer-in.c @@ -224,7 +224,7 @@ static void unpack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) { FIXED_VALUE_TYPE *fp = ggc_alloc (); - fp->mode = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); + fp->mode = bp_unpack_machine_mode (bp); fp->data.low = bp_unpack_var_len_int (bp); fp->data.high = bp_unpack_var_len_int (bp); TREE_FIXED_CST_PTR (expr) = fp; @@ -236,7 +236,7 @@ unpack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) static void unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) { - DECL_MODE (expr) = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); + DECL_MODE (expr) = bp_unpack_machine_mode (bp); DECL_NONLOCAL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_VIRTUAL_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_IGNORED_P (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -247,7 +247,10 @@ unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) DECL_EXTERNAL (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_GIMPLE_REG_P (expr) = (unsigned) bp_unpack_value (bp, 1); DECL_ALIGN (expr) = (unsigned) bp_unpack_var_len_unsigned (bp); - +#ifdef ACCEL_COMPILER + if (DECL_ALIGN (expr) > targetm.absolute_biggest_alignment) + DECL_ALIGN (expr) = targetm.absolute_biggest_alignment; +#endif if (TREE_CODE (expr) == LABEL_DECL) { EH_LANDING_PAD_NR (expr) = (int) bp_unpack_var_len_unsigned (bp); @@ -373,7 +376,7 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr) { machine_mode mode; - mode = bp_unpack_enum (bp, machine_mode, MAX_MACHINE_MODE); + mode = bp_unpack_machine_mode (bp); SET_TYPE_MODE (expr, mode); TYPE_STRING_FLAG (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_NO_FORCE_BLK (expr) = (unsigned) bp_unpack_value (bp, 1); @@ -391,6 +394,10 @@ unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr) TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1); TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp); TYPE_ALIGN (expr) = bp_unpack_var_len_unsigned (bp); +#ifdef ACCEL_COMPILER + if (TYPE_ALIGN (expr) > targetm.absolute_biggest_alignment) + TYPE_ALIGN (expr) = targetm.absolute_biggest_alignment; +#endif TYPE_ALIAS_SET (expr) = bp_unpack_var_len_int (bp); } @@ -552,7 +559,11 @@ streamer_read_tree_bitfields (struct lto_input_block *ib, #ifndef ACCEL_COMPILER if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)) - cl_target_option_stream_in (data_in, &bp, TREE_TARGET_OPTION (expr)); + { + cl_target_option_stream_in (data_in, &bp, TREE_TARGET_OPTION (expr)); + if (targetm.target_option.post_stream_in) + targetm.target_option.post_stream_in (TREE_TARGET_OPTION (expr)); + } #endif if (code == OMP_CLAUSE) diff --git a/contrib/gcc-5.0/gcc/tree-streamer-out.c b/contrib/gcc-5.0/gcc/tree-streamer-out.c index 36102ed32a..0e5458b14f 100644 --- a/contrib/gcc-5.0/gcc/tree-streamer-out.c +++ b/contrib/gcc-5.0/gcc/tree-streamer-out.c @@ -190,7 +190,7 @@ static void pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) { struct fixed_value fv = TREE_FIXED_CST (expr); - bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, fv.mode); + bp_pack_machine_mode (bp, fv.mode); bp_pack_var_len_int (bp, fv.data.low); bp_pack_var_len_int (bp, fv.data.high); } @@ -201,7 +201,7 @@ pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr) static void pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr) { - bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, DECL_MODE (expr)); + bp_pack_machine_mode (bp, DECL_MODE (expr)); bp_pack_value (bp, DECL_NONLOCAL (expr), 1); bp_pack_value (bp, DECL_VIRTUAL_P (expr), 1); bp_pack_value (bp, DECL_IGNORED_P (expr), 1); @@ -325,7 +325,7 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr) static void pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr) { - bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, TYPE_MODE (expr)); + bp_pack_machine_mode (bp, TYPE_MODE (expr)); bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1); bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1); bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1); diff --git a/contrib/gcc-5.0/gcc/tree-streamer.c b/contrib/gcc-5.0/gcc/tree-streamer.c index 7b35358c28..2eb0305f3d 100644 --- a/contrib/gcc-5.0/gcc/tree-streamer.c +++ b/contrib/gcc-5.0/gcc/tree-streamer.c @@ -53,6 +53,14 @@ along with GCC; see the file COPYING3. If not see #include "cgraph.h" #include "tree-streamer.h" +/* Table indexed by machine_mode, used for 2 different purposes. + During streaming out we record there non-zero value for all modes + that were streamed out. + During streaming in, we translate the on the disk mode using this + table. For normal LTO it is set to identity, for ACCEL_COMPILER + depending on the mode_table content. */ +unsigned char streamer_mode_table[1 << 8]; + /* Check that all the TS_* structures handled by the streamer_write_* and streamer_read_* routines are exactly ALL the structures defined in treestruct.def. */ diff --git a/contrib/gcc-5.0/gcc/tree-streamer.h b/contrib/gcc-5.0/gcc/tree-streamer.h index 7680620685..20e2621511 100644 --- a/contrib/gcc-5.0/gcc/tree-streamer.h +++ b/contrib/gcc-5.0/gcc/tree-streamer.h @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see #include "streamer-hooks.h" #include "lto-streamer.h" +#include "data-streamer.h" #include "hash-map.h" /* Cache of pickled nodes. Used to avoid writing the same node more @@ -91,6 +92,7 @@ void streamer_write_integer_cst (struct output_block *, tree, bool); void streamer_write_builtin (struct output_block *, tree); /* In tree-streamer.c. */ +extern unsigned char streamer_mode_table[1 << 8]; void streamer_check_handled_ts_structures (void); bool streamer_tree_cache_insert (struct streamer_tree_cache_d *, tree, hashval_t, unsigned *); @@ -119,5 +121,19 @@ streamer_tree_cache_get_hash (struct streamer_tree_cache_d *cache, unsigned ix) return cache->hashes[ix]; } +static inline void +bp_pack_machine_mode (struct bitpack_d *bp, machine_mode mode) +{ + streamer_mode_table[mode] = 1; + bp_pack_enum (bp, machine_mode, 1 << 8, mode); +} + +static inline machine_mode +bp_unpack_machine_mode (struct bitpack_d *bp) +{ + return (machine_mode) + ((struct lto_input_block *) + bp->stream)->mode_table[bp_unpack_enum (bp, machine_mode, 1 << 8)]; +} #endif /* GCC_TREE_STREAMER_H */ diff --git a/contrib/gcc-5.0/gcc/tree-vect-loop.c b/contrib/gcc-5.0/gcc/tree-vect-loop.c index 3e7c701e63..dd4ada2d09 100644 --- a/contrib/gcc-5.0/gcc/tree-vect-loop.c +++ b/contrib/gcc-5.0/gcc/tree-vect-loop.c @@ -4981,6 +4981,12 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, if (!vectype_in) vectype_in = tem; gcc_assert (is_simple_use); + if (!found_nested_cycle_def) + reduc_def_stmt = def_stmt; + + if (reduc_def_stmt && gimple_code (reduc_def_stmt) != GIMPLE_PHI) + return false; + if (!(dt == vect_reduction_def || dt == vect_nested_cycle || ((dt == vect_internal_def || dt == vect_external_def @@ -4993,10 +4999,7 @@ vectorizable_reduction (gimple stmt, gimple_stmt_iterator *gsi, gcc_assert (orig_stmt); return false; } - if (!found_nested_cycle_def) - reduc_def_stmt = def_stmt; - gcc_assert (gimple_code (reduc_def_stmt) == GIMPLE_PHI); if (orig_stmt) gcc_assert (orig_stmt == vect_is_simple_reduction (loop_vinfo, reduc_def_stmt, diff --git a/contrib/gcc-5.0/gcc/wide-int.cc b/contrib/gcc-5.0/gcc/wide-int.cc index fd7cbb4c38..1a7fc1435d 100644 --- a/contrib/gcc-5.0/gcc/wide-int.cc +++ b/contrib/gcc-5.0/gcc/wide-int.cc @@ -237,7 +237,7 @@ wide_int wi::from_mpz (const_tree type, mpz_t x, bool wrap) { size_t count, numb; - int prec = TYPE_PRECISION (type); + unsigned int prec = TYPE_PRECISION (type); wide_int res = wide_int::create (prec); if (!wrap) @@ -261,16 +261,28 @@ wi::from_mpz (const_tree type, mpz_t x, bool wrap) for representing the value. The code to calculate count is extracted from the GMP manual, section "Integer Import and Export": http://gmplib.org/manual/Integer-Import-and-Export.html */ - numb = 8 * sizeof(HOST_WIDE_INT); + numb = CHAR_BIT * sizeof (HOST_WIDE_INT); count = (mpz_sizeinbase (x, 2) + numb - 1) / numb; HOST_WIDE_INT *val = res.write_val (); - mpz_export (val, &count, -1, sizeof (HOST_WIDE_INT), 0, 0, x); + /* Write directly to the wide_int storage if possible, otherwise leave + GMP to allocate the memory for us. It might be slightly more efficient + to use mpz_tdiv_r_2exp for the latter case, but the situation is + pathological and it seems safer to operate on the original mpz value + in all cases. */ + void *valres = mpz_export (count <= WIDE_INT_MAX_ELTS ? val : 0, + &count, -1, sizeof (HOST_WIDE_INT), 0, 0, x); if (count < 1) { val[0] = 0; count = 1; } - res.set_len (count); + count = MIN (count, BLOCKS_NEEDED (prec)); + if (valres != val) + { + memcpy (val, valres, count * sizeof (HOST_WIDE_INT)); + free (valres); + } + res.set_len (canonize (val, count, prec)); if (mpz_sgn (x) < 0) res = -res; @@ -1297,6 +1309,11 @@ wi::mul_internal (HOST_WIDE_INT *val, const HOST_WIDE_INT *op1val, return 1; } umul_ppmm (val[1], val[0], op1.ulow (), op2.ulow ()); + if (val[1] < 0 && prec > HOST_BITS_PER_WIDE_INT * 2) + { + val[2] = 0; + return 3; + } return 1 + (val[1] != 0 || val[0] < 0); } /* Likewise if the output is a full single HWI, except that the diff --git a/contrib/gcc-5.0/libgcc/config/nvptx/t-nvptx b/contrib/gcc-5.0/libgcc/config/nvptx/t-nvptx index 08d3a67189..34d68cca6c 100644 --- a/contrib/gcc-5.0/libgcc/config/nvptx/t-nvptx +++ b/contrib/gcc-5.0/libgcc/config/nvptx/t-nvptx @@ -7,3 +7,8 @@ LIB2FUNCS_EXCLUDE=__main crt0.o: $(srcdir)/config/nvptx/crt0.s cp $< $@ + +# Prevent building "advanced" stuff (for example, gcov support). We don't +# support it, and it may cause the build to fail, because of alloca usage, for +# example. +INHIBIT_LIBC_CFLAGS = -Dinhibit_libc -- 2.41.0 From f74897bf63ea034fdf0ded8c1a25ec4970c551a4 Mon Sep 17 00:00:00 2001 From: John Marino Date: Fri, 27 Feb 2015 09:05:01 +0100 Subject: [PATCH 09/16] gcc50: Update to 27 Feb 2015 snapshot (SVN 221044) --- contrib/gcc-5.0/README.DRAGONFLY | 2 +- gnu/usr.bin/cc50/Makefile.version | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/gcc-5.0/README.DRAGONFLY b/contrib/gcc-5.0/README.DRAGONFLY index 1f4f90ae35..3ed99a528f 100644 --- a/contrib/gcc-5.0/README.DRAGONFLY +++ b/contrib/gcc-5.0/README.DRAGONFLY @@ -8,7 +8,7 @@ XXX file = gcc-5-20150201.tar.bz2 XXX date = 1 Febuary 2015 XXX size = 89749171 XXX sha1 = 0558cb236c982b5e1931ed18fc06967b3da1cd99 -Built from SVN Revision 220667 (13 Feb 2015) +See LAST_UPDATED for SVN revision The file README.DELETED contains a list of deleted files and directories. diff --git a/gnu/usr.bin/cc50/Makefile.version b/gnu/usr.bin/cc50/Makefile.version index 78fad1b438..641b6d672b 100644 --- a/gnu/usr.bin/cc50/Makefile.version +++ b/gnu/usr.bin/cc50/Makefile.version @@ -1,5 +1,5 @@ GCCCOMPLETEVER= 5.0.0 GCCRELEASE= Snapshot # choices are "Snapshot" or "Release" -GCCDATESTAMP= 2015-02-20 +GCCDATESTAMP= 2015-02-27 GCCPOINTVER= ${GCCCOMPLETEVER:R} GCCSHORTVER= ${GCCPOINTVER:S/.//} -- 2.41.0 From 8249c6416368c500932841c93ba35bee47a9d0f4 Mon Sep 17 00:00:00 2001 From: Markus Pfeiffer Date: Thu, 26 Feb 2015 15:24:45 +0000 Subject: [PATCH 10/16] net/if_lagg: Fix double-free issue --- sys/net/lagg/if_lagg.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/net/lagg/if_lagg.c b/sys/net/lagg/if_lagg.c index 9f2182279f..9033c6c02b 100644 --- a/sys/net/lagg/if_lagg.c +++ b/sys/net/lagg/if_lagg.c @@ -356,8 +356,7 @@ lagg_clone_create(struct if_clone *ifc, int unit, caddr_t params __unused) * This uses the callout lock rather than the rmlock; one can't * hold said rmlock during SWI. */ - callout_init(&sc->sc_callout); - /*, &sc->sc_call_lock, 0); */ + callout_init_lk(&sc->sc_callout, &sc->sc_call_lock); /* Initialise pseudo media types */ ifmedia_init(&sc->sc_media, 0, lagg_media_change, @@ -432,7 +431,8 @@ lagg_clone_destroy(struct ifnet *ifp) sysctl_ctx_free(&sc->ctx); ifmedia_removeall(&sc->sc_media); ether_ifdetach(ifp); - if_free(ifp); + /* This ifp is part of lagg_softc, don't free it! */ + /* if_free(ifp); */ /* This grabs sc_callout_mtx, serialising it correctly */ callout_drain(&sc->sc_callout); -- 2.41.0 From a8343f8df3c6fd551d10c36ddafdd3d201acdef9 Mon Sep 17 00:00:00 2001 From: Imre Vadasz Date: Sat, 28 Feb 2015 00:51:27 +0100 Subject: [PATCH 11/16] acpi_video(4): Fix detach panic. * The "if ((adr & DOD_DEVID_MASK_FULL) == DOD_DEVID_LCD)" test from acpi_video_vo_init was missing in acpi_video_vo_destroy. This meant that on some machines we ended up calling STAILQ_REMOVE with an element not contained in the list, which causes a panic since STAILQ_REMOVE doesn't check for the end of the list. --- sys/dev/acpica/acpi_video/acpi_video.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/dev/acpica/acpi_video/acpi_video.c b/sys/dev/acpica/acpi_video/acpi_video.c index e85e1e8a81..d39346aa02 100644 --- a/sys/dev/acpica/acpi_video/acpi_video.c +++ b/sys/dev/acpica/acpi_video/acpi_video.c @@ -633,7 +633,11 @@ acpi_video_vo_destroy(struct acpi_video_output *vo) switch (vo->adr & DOD_DEVID_MASK) { case DOD_DEVID_MONITOR: - voqh = &crt_units; + if ((vo->adr & DOD_DEVID_MASK_FULL) == DOD_DEVID_LCD) { + voqh = &lcd_units; + } else { + voqh = &crt_units; + } break; case DOD_DEVID_TV: voqh = &tv_units; -- 2.41.0 From 024de40533b9f7dc2d6d2aaae58413a348c10686 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 27 Feb 2015 21:00:36 -0800 Subject: [PATCH 12/16] libdmsg - Fix buffer overrun * Large messages (generally large data payloads) could overrun the FIFO buffer. e.g. dd if=/dev/xa of=/dev/null bs=32k * Fix by chunking up large payloads. --- lib/libdmsg/msg.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/libdmsg/msg.c b/lib/libdmsg/msg.c index 419ff816ad..1bcdef6ad1 100644 --- a/lib/libdmsg/msg.c +++ b/lib/libdmsg/msg.c @@ -1313,21 +1313,32 @@ dmsg_iocom_flush2(dmsg_iocom_t *iocom) assert(hoff <= hbytes && aoff <= abytes); if (hoff < hbytes) { + size_t maxlen = hbytes - hoff; + if (maxlen > sizeof(ioq->buf) / 2) + maxlen = sizeof(ioq->buf) / 2; iov[iovcnt].iov_base = (char *)&msg->any.head + hoff; - iov[iovcnt].iov_len = hbytes - hoff; - nact += hbytes - hoff; + iov[iovcnt].iov_len = maxlen; + nact += maxlen; ++iovcnt; - if (iovcnt == DMSG_IOQ_MAXIOVEC) + if (iovcnt == DMSG_IOQ_MAXIOVEC || + maxlen != hbytes - hoff) { break; + } } if (aoff < abytes) { + size_t maxlen = abytes - aoff; + if (maxlen > sizeof(ioq->buf) / 2) + maxlen = sizeof(ioq->buf) / 2; + assert(msg->aux_data != NULL); iov[iovcnt].iov_base = (char *)msg->aux_data + aoff; - iov[iovcnt].iov_len = abytes - aoff; - nact += abytes - aoff; + iov[iovcnt].iov_len = maxlen; + nact += maxlen; ++iovcnt; - if (iovcnt == DMSG_IOQ_MAXIOVEC) + if (iovcnt == DMSG_IOQ_MAXIOVEC || + maxlen != abytes - aoff) { break; + } } hoff = 0; aoff = 0; -- 2.41.0 From 1e271b664a4b7cfa1a7d41bef5b2018b2e842d0a Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 27 Feb 2015 21:03:06 -0800 Subject: [PATCH 13/16] libdmsg - add safeties * Preinitialize return counters to 0 as a safety. Not required for proper operation. --- lib/libdmsg/crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/libdmsg/crypto.c b/lib/libdmsg/crypto.c index 88e48e3f03..55eca1e3c5 100644 --- a/lib/libdmsg/crypto.c +++ b/lib/libdmsg/crypto.c @@ -209,10 +209,12 @@ dmsg_crypto_gcm_encrypt_chunk(dmsg_ioq_t *ioq, char *ct, char *pt, if (!ok) goto fail; + u_len = 0; /* safety */ ok = EVP_EncryptUpdate(&ioq->ctx, ct, &u_len, pt, in_size); if (!ok) goto fail; + f_len = 0; /* safety */ ok = EVP_EncryptFinal(&ioq->ctx, ct + u_len, &f_len); if (!ok) goto fail; -- 2.41.0 From d34b92aff64e5c0f283d9da3a2aa6803b08bd5a2 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Fri, 27 Feb 2015 23:28:42 -0800 Subject: [PATCH 14/16] xdisk - disk_setdiskinfo() must be assynchronous * Allow CMD_BUF_READ operations without the device having to be open. This allows disk probes to occur. * Use disk_setdiskinfo(), which is asynchronous, to avoid an I/O deadlock because the call is made from the rxmsg loop. If it were to issue I/O synchronously we would deadlock and never process the reply. --- sys/dev/disk/xdisk/xdisk.c | 40 +++++++++++++++++++++++++++++--------- sys/kern/subr_diskiocom.c | 9 ++++++++- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/sys/dev/disk/xdisk/xdisk.c b/sys/dev/disk/xdisk/xdisk.c index 800d8101b8..16615b4843 100644 --- a/sys/dev/disk/xdisk/xdisk.c +++ b/sys/dev/disk/xdisk/xdisk.c @@ -465,7 +465,13 @@ xaio_rcvdmsg(kdmsg_msg_t *msg) sc->info.d_ncylinders = 0; if (sc->fs_label[0]) sc->info.d_serialno = sc->fs_label; - disk_setdiskinfo_sync(&sc->disk, &sc->info); + /* + * WARNING! disk_setdiskinfo() must be asynchronous + * because we are in the rxmsg thread. If + * it is synchronous and issues more disk + * I/Os, we will deadlock. + */ + disk_setdiskinfo(&sc->disk, &sc->info); xa_restart_deferred(sc); /* eats serializing */ } else { kprintf("(found spancnt %d sc=%p)\n", sc->spancnt, sc); @@ -700,11 +706,10 @@ xa_strategy(struct dev_strategy_args *ap) struct bio *bio = ap->a_bio; /* - * Allow potentially temporary link failures to fail the I/Os - * only if the device is not open. That is, we allow the disk - * probe code prior to mount to fail. + * Only BUF_CMD_READ is allowed (for probes) if opencnt is zero. + * Otherwise a BLK_OPEN transaction is required. */ - if (sc->opencnt == 0) { + if (sc->opencnt == 0 && bio->bio_buf->b_cmd != BUF_CMD_READ) { bio->bio_buf->b_error = ENXIO; bio->bio_buf->b_flags |= B_ERROR; biodone(bio); @@ -784,10 +789,27 @@ xa_start(xa_tag_t *tag, kdmsg_msg_t *msg, int async) switch(bp->b_cmd) { case BUF_CMD_READ: - msg = kdmsg_msg_alloc(sc->open_tag->state, - DMSG_BLK_READ | - DMSGF_CREATE | DMSGF_DELETE, - xa_bio_completion, tag); + if (sc->opencnt == 0 || sc->open_tag == NULL) { + kdmsg_state_t *span; + + TAILQ_FOREACH(span, &sc->spanq, user_entry) { + if ((span->rxcmd & DMSGF_DELETE) == 0) + break; + } + if (span == NULL) + break; + msg = kdmsg_msg_alloc(span, + DMSG_BLK_READ | + DMSGF_CREATE | + DMSGF_DELETE, + xa_bio_completion, tag); + } else { + msg = kdmsg_msg_alloc(sc->open_tag->state, + DMSG_BLK_READ | + DMSGF_CREATE | + DMSGF_DELETE, + xa_bio_completion, tag); + } msg->any.blk_read.keyid = sc->keyid; msg->any.blk_read.offset = bio->bio_offset; msg->any.blk_read.bytes = bp->b_bcount; diff --git a/sys/kern/subr_diskiocom.c b/sys/kern/subr_diskiocom.c index 78eb3a20d0..448e84a110 100644 --- a/sys/kern/subr_diskiocom.c +++ b/sys/kern/subr_diskiocom.c @@ -196,7 +196,11 @@ disk_rcvdmsg(kdmsg_msg_t *msg) } /* - * All remaining messages must be in a transaction + * All remaining messages must be in a transaction. + * + * NOTE! We currently don't care if the transaction is just + * the span transaction (for disk probes) or if it is the + * BLK_OPEN transaction. * * NOTE! We are switching on the first message's command. The * actual message command within the transaction may be @@ -212,6 +216,9 @@ disk_rcvdmsg(kdmsg_msg_t *msg) disk_blk_open(dp, msg); break; case DMSG_BLK_READ: + /* + * not reached normally but leave in for completeness + */ disk_blk_read(dp, msg); break; case DMSG_BLK_WRITE: -- 2.41.0 From d0f32dcc1a90b3acc46595a8ed98e66dee4f7bfe Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Tigeot?= Date: Sat, 28 Feb 2015 08:50:44 +0100 Subject: [PATCH 15/16] drm: linux/mm.h: Add offset_in_page() Obtained-from: OpenBSD --- sys/dev/drm/include/linux/mm.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/drm/include/linux/mm.h b/sys/dev/drm/include/linux/mm.h index 8e6a01ac7d..a5fd7392cc 100644 --- a/sys/dev/drm/include/linux/mm.h +++ b/sys/dev/drm/include/linux/mm.h @@ -74,4 +74,6 @@ io_remap_pfn_range(struct vm_area_struct *vma, return (0); } +#define offset_in_page(off) ((off) & PAGE_MASK) + #endif /* _LINUX_MM_H_ */ -- 2.41.0 From 40d5c1084ddaba8f5c7725ad5c0f1fe76d34c82a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fran=C3=A7ois=20Tigeot?= Date: Sat, 28 Feb 2015 08:57:43 +0100 Subject: [PATCH 16/16] drm: Add drm_clflush_virt_range() Obtained-from: Linux 3.11 --- sys/dev/drm/drm/Makefile | 1 + sys/dev/drm/drm_cache.c | 54 ++++++++++++++++++++++++++++++++++ sys/dev/drm/include/drm/drmP.h | 3 ++ 3 files changed, 58 insertions(+) create mode 100644 sys/dev/drm/drm_cache.c diff --git a/sys/dev/drm/drm/Makefile b/sys/dev/drm/drm/Makefile index 5342d58d0c..47ae5043cb 100644 --- a/sys/dev/drm/drm/Makefile +++ b/sys/dev/drm/drm/Makefile @@ -6,6 +6,7 @@ SRCS = \ drm_auth.c \ drm_bufs.c \ drm_buffer.c \ + drm_cache.c \ drm_context.c \ drm_crtc.c \ drm_crtc_helper.c \ diff --git a/sys/dev/drm/drm_cache.c b/sys/dev/drm/drm_cache.c new file mode 100644 index 0000000000..2d754d4c0c --- /dev/null +++ b/sys/dev/drm/drm_cache.c @@ -0,0 +1,54 @@ +/************************************************************************** + * + * Copyright (c) 2006-2007 Tungsten Graphics, Inc., Cedar Park, TX., USA + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE + * USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ +/* + * Authors: Thomas Hellström + */ + +#include +#include + +#include +#include + +#define cpu_has_clflush 1 + +void +drm_clflush_virt_range(char *addr, unsigned long length) +{ + if (cpu_has_clflush) { + char *end = addr + length; + cpu_mfence(); + for (; addr < end; addr += cpu_clflush_line_size) + clflush((unsigned long)addr); + clflush((unsigned long)(end - 1)); + cpu_mfence(); + return; + } + + cpu_wbinvd_on_all_cpus(); +} +EXPORT_SYMBOL(drm_clflush_virt_range); diff --git a/sys/dev/drm/include/drm/drmP.h b/sys/dev/drm/include/drm/drmP.h index 4dd9408a05..80fbfbb0d8 100644 --- a/sys/dev/drm/include/drm/drmP.h +++ b/sys/dev/drm/include/drm/drmP.h @@ -1357,6 +1357,9 @@ int drm_getmagic(struct drm_device *dev, void *data, int drm_authmagic(struct drm_device *dev, void *data, struct drm_file *file_priv); +/* Cache management (drm_cache.c) */ +void drm_clflush_virt_range(char *addr, unsigned long length); + /* Buffer management support (drm_bufs.c) */ int drm_addmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -- 2.41.0