From 9f50539d4f719d4e2883742c55a77cd28a518d98 Mon Sep 17 00:00:00 2001 From: John Marino Date: Fri, 13 Feb 2015 09:18:26 +0100 Subject: [PATCH] Update gcc-50 to SVN version 220677 Last Changed Date: 2015-02-13 08:56:14 +0100 (Fri, 13 Feb 2015) --- contrib/gcc-5.0/LAST_UPDATED | 3 +- contrib/gcc-5.0/gcc/DATESTAMP | 2 +- contrib/gcc-5.0/gcc/builtins.c | 6 +- contrib/gcc-5.0/gcc/builtins.def | 54 +- contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c | 10 +- contrib/gcc-5.0/gcc/c-family/c-format.c | 17 +- contrib/gcc-5.0/gcc/c-family/c-omp.c | 5 +- contrib/gcc-5.0/gcc/c-family/c-opts.c | 5 + contrib/gcc-5.0/gcc/c/c-parser.c | 6 +- contrib/gcc-5.0/gcc/c/c-typeck.c | 3 +- contrib/gcc-5.0/gcc/cfgexpand.c | 9 +- contrib/gcc-5.0/gcc/cfghooks.c | 3 + contrib/gcc-5.0/gcc/cgraph.c | 31 +- contrib/gcc-5.0/gcc/cgraph.h | 9 +- contrib/gcc-5.0/gcc/cgraphunit.c | 57 +- contrib/gcc-5.0/gcc/combine.c | 33 +- contrib/gcc-5.0/gcc/common.opt | 15 +- contrib/gcc-5.0/gcc/config/i386/i386.c | 209 ++--- contrib/gcc-5.0/gcc/cp/constexpr.c | 8 +- contrib/gcc-5.0/gcc/cp/cp-tree.h | 4 + contrib/gcc-5.0/gcc/cp/decl.c | 68 +- contrib/gcc-5.0/gcc/cp/except.c | 2 +- contrib/gcc-5.0/gcc/cp/init.c | 13 +- contrib/gcc-5.0/gcc/cp/mangle.c | 3 +- contrib/gcc-5.0/gcc/cp/method.c | 14 - contrib/gcc-5.0/gcc/cp/parser.c | 108 ++- contrib/gcc-5.0/gcc/cp/tree.c | 44 ++ contrib/gcc-5.0/gcc/cp/typeck.c | 9 +- contrib/gcc-5.0/gcc/cse.c | 34 +- contrib/gcc-5.0/gcc/dbxout.c | 2 +- contrib/gcc-5.0/gcc/doc/extend.texi | 714 ++++++++++-------- contrib/gcc-5.0/gcc/doc/invoke.texi | 32 +- contrib/gcc-5.0/gcc/doc/sourcebuild.texi | 3 + contrib/gcc-5.0/gcc/doc/tm.texi | 11 - contrib/gcc-5.0/gcc/dwarf2asm.c | 8 +- contrib/gcc-5.0/gcc/dwarf2out.c | 100 ++- contrib/gcc-5.0/gcc/fold-const.c | 9 +- contrib/gcc-5.0/gcc/gcc-main.c | 46 ++ contrib/gcc-5.0/gcc/gcc.c | 84 +-- contrib/gcc-5.0/gcc/gcc.h | 38 + contrib/gcc-5.0/gcc/gcov-io.c | 2 +- contrib/gcc-5.0/gcc/gcov-tool.c | 15 +- contrib/gcc-5.0/gcc/genmatch.c | 1 + contrib/gcc-5.0/gcc/gimple-fold.c | 1 + contrib/gcc-5.0/gcc/gimple.c | 18 + contrib/gcc-5.0/gcc/gimple.h | 1 + contrib/gcc-5.0/gcc/haifa-sched.c | 10 +- contrib/gcc-5.0/gcc/ipa-cp.c | 13 +- contrib/gcc-5.0/gcc/ipa-devirt.c | 121 ++- contrib/gcc-5.0/gcc/ipa-icf.c | 39 +- contrib/gcc-5.0/gcc/ipa-inline-analysis.c | 9 +- contrib/gcc-5.0/gcc/ipa-inline.c | 26 +- contrib/gcc-5.0/gcc/ipa-polymorphic-call.c | 2 +- contrib/gcc-5.0/gcc/ipa-prop.c | 22 +- contrib/gcc-5.0/gcc/ipa-split.c | 1 + contrib/gcc-5.0/gcc/ipa-visibility.c | 47 +- contrib/gcc-5.0/gcc/ipa.c | 34 +- contrib/gcc-5.0/gcc/ira-color.c | 7 +- contrib/gcc-5.0/gcc/langhooks.c | 8 + contrib/gcc-5.0/gcc/langhooks.h | 1 + contrib/gcc-5.0/gcc/lra-eliminations.c | 2 + contrib/gcc-5.0/gcc/lra.c | 2 +- contrib/gcc-5.0/gcc/lto-cgraph.c | 60 +- contrib/gcc-5.0/gcc/lto-streamer-out.c | 4 +- contrib/gcc-5.0/gcc/lto/lto-symtab.c | 2 + contrib/gcc-5.0/gcc/opts.c | 4 +- contrib/gcc-5.0/gcc/reorg.c | 4 +- contrib/gcc-5.0/gcc/simplify-rtx.c | 62 +- contrib/gcc-5.0/gcc/symtab.c | 9 +- contrib/gcc-5.0/gcc/toplev.c | 11 +- contrib/gcc-5.0/gcc/tree-core.h | 8 +- contrib/gcc-5.0/gcc/tree-eh.c | 11 + contrib/gcc-5.0/gcc/tree-emutls.c | 19 +- contrib/gcc-5.0/gcc/tree-sra.c | 2 +- contrib/gcc-5.0/gcc/tree-ssa-ccp.c | 3 +- contrib/gcc-5.0/gcc/tree-ssa-forwprop.c | 4 + contrib/gcc-5.0/gcc/tree-ssa-loop-ivopts.c | 95 ++- contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c | 18 +- contrib/gcc-5.0/gcc/tree-ssa-loop-niter.h | 2 +- contrib/gcc-5.0/gcc/tree-ssa-pre.c | 1 + contrib/gcc-5.0/gcc/tree-ssa-sccvn.c | 16 +- contrib/gcc-5.0/gcc/tree-ssa-threadedge.c | 19 +- contrib/gcc-5.0/gcc/tree-ssa-uninit.c | 2 +- contrib/gcc-5.0/gcc/tree-ssa.c | 2 + contrib/gcc-5.0/gcc/tree-stdarg.c | 47 +- contrib/gcc-5.0/gcc/tree-streamer-in.c | 98 ++- contrib/gcc-5.0/gcc/tree-streamer-out.c | 57 +- contrib/gcc-5.0/gcc/tree-streamer.h | 7 +- contrib/gcc-5.0/gcc/tree-vect-data-refs.c | 11 +- contrib/gcc-5.0/gcc/tree-vect-loop.c | 11 +- contrib/gcc-5.0/gcc/tree-vrp.c | 3 +- contrib/gcc-5.0/gcc/ubsan.c | 4 +- contrib/gcc-5.0/gcc/varasm.c | 179 +++-- contrib/gcc-5.0/gcc/varpool.c | 3 +- contrib/gcc-5.0/gcc/xcoffout.h | 7 +- contrib/gcc-5.0/include/dwarf2.h | 2 + contrib/gcc-5.0/libcpp/internal.h | 5 + contrib/gcc-5.0/libcpp/macro.c | 31 +- .../gcc-5.0/libgcc/libgcov-driver-system.c | 3 + .../libgomp/config/aix/plugin-suffix.h | 26 - contrib/gcc-5.0/libobjc/thr.c | 5 - contrib/gcc-5.0/libssp/ssp.c | 16 + contrib/gcc-5.0/lto-plugin/lto-plugin.c | 7 - 103 files changed, 1949 insertions(+), 1144 deletions(-) create mode 100644 contrib/gcc-5.0/gcc/gcc-main.c delete mode 100644 contrib/gcc-5.0/libgomp/config/aix/plugin-suffix.h diff --git a/contrib/gcc-5.0/LAST_UPDATED b/contrib/gcc-5.0/LAST_UPDATED index eb8159351e..9851ac7cba 100644 --- a/contrib/gcc-5.0/LAST_UPDATED +++ b/contrib/gcc-5.0/LAST_UPDATED @@ -1 +1,2 @@ -Obtained from SVN: trunk revision 220336 +220677 +Last Changed Date: 2015-02-13 08:56:14 +0100 (Fri, 13 Feb 2015) diff --git a/contrib/gcc-5.0/gcc/DATESTAMP b/contrib/gcc-5.0/gcc/DATESTAMP index d6a8a0e515..932fe4fa59 100644 --- a/contrib/gcc-5.0/gcc/DATESTAMP +++ b/contrib/gcc-5.0/gcc/DATESTAMP @@ -1 +1 @@ -20150201 +20150213 diff --git a/contrib/gcc-5.0/gcc/builtins.c b/contrib/gcc-5.0/gcc/builtins.c index 3ddaddc1ab..8f3c0bc22b 100644 --- a/contrib/gcc-5.0/gcc/builtins.c +++ b/contrib/gcc-5.0/gcc/builtins.c @@ -5960,6 +5960,9 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, machine_mode target_mode = TYPE_MODE (TREE_TYPE (exp)); int flags; + if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) + return targetm.expand_builtin (exp, target, subtarget, mode, ignore); + /* When ASan is enabled, we don't want to expand some memory/string builtins and rely on libsanitizer's hooks. This allows us to avoid redundant checks and be sure, that possible overflow will be detected @@ -5968,9 +5971,6 @@ expand_builtin (tree exp, rtx target, rtx subtarget, machine_mode mode, if ((flag_sanitize & SANITIZE_ADDRESS) && asan_intercepted_p (fcode)) return expand_call (exp, target, ignore); - if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) - return targetm.expand_builtin (exp, target, subtarget, mode, ignore); - /* When not optimizing, generate calls to library functions for a certain set of builtins. */ if (!optimize diff --git a/contrib/gcc-5.0/gcc/builtins.def b/contrib/gcc-5.0/gcc/builtins.def index e3153bf8cf..55ce9f6daa 100644 --- a/contrib/gcc-5.0/gcc/builtins.def +++ b/contrib/gcc-5.0/gcc/builtins.def @@ -63,6 +63,16 @@ along with GCC; see the file COPYING3. If not see The builtins is registered only if COND is true. */ +/* A macro for builtins where the + BUILT_IN_*_CHKP = BUILT_IN_* + BEGIN_CHKP_BUILTINS + 1 + enums should be defined too. */ +#ifndef DEF_BUILTIN_CHKP +#define DEF_BUILTIN_CHKP(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, \ + FALLBACK_P, NONANSI_P, ATTRS, IMPLICIT, COND) \ + DEF_BUILTIN(ENUM, NAME, CLASS, TYPE, LIBTYPE, BOTH_P, FALLBACK_P, \ + NONANSI_P, ATTRS, IMPLICIT, COND) +#endif + /* A GCC builtin (like __builtin_saveregs) is provided by the compiler, but does not correspond to a function in the standard library. */ @@ -87,6 +97,10 @@ along with GCC; see the file COPYING3. If not see #define DEF_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ true, true, false, ATTRS, true, true) +#undef DEF_LIB_BUILTIN_CHKP +#define DEF_LIB_BUILTIN_CHKP(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN_CHKP (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, \ + TYPE, true, true, false, ATTRS, true, true) /* Like DEF_LIB_BUILTIN, except that the function is not one that is specified by ANSI/ISO C. So, when we're being fully conformant we @@ -96,6 +110,10 @@ along with GCC; see the file COPYING3. If not see #define DEF_EXT_LIB_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ true, true, true, ATTRS, false, true) +#undef DEF_EXT_LIB_BUILTIN_CHKP +#define DEF_EXT_LIB_BUILTIN_CHKP(ENUM, NAME, TYPE, ATTRS) \ + DEF_BUILTIN_CHKP (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, \ + TYPE, true, true, true, ATTRS, false, true) /* Like DEF_LIB_BUILTIN, except that the function is only a part of the standard in C94 or above. */ @@ -199,8 +217,8 @@ along with GCC; see the file COPYING3. If not see /* Builtin used by the implementation of Pointer Bounds Checker. */ #undef DEF_CHKP_BUILTIN #define DEF_CHKP_BUILTIN(ENUM, NAME, TYPE, ATTRS) \ - DEF_BUILTIN (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, TYPE, \ - true, true, false, ATTRS, true, true) + DEF_BUILTIN_CHKP (ENUM, "__builtin_" NAME, BUILT_IN_NORMAL, TYPE, \ + TYPE, true, true, false, ATTRS, true, true) /* Define an attribute list for math functions that are normally "impure" because some of them may write into global memory for @@ -595,22 +613,22 @@ DEF_EXT_LIB_BUILTIN (BUILT_IN_BZERO, "bzero", BT_FN_VOID_PTR_SIZE, ATTR_NOTHR DEF_EXT_LIB_BUILTIN (BUILT_IN_INDEX, "index", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_MEMCHR, "memchr", BT_FN_PTR_CONST_PTR_INT_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_MEMCMP, "memcmp", BT_FN_INT_CONST_PTR_CONST_PTR_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN_CHKP (BUILT_IN_MEMCPY, "memcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN_CHKP (BUILT_IN_MEMMOVE, "memmove", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY, "mempcpy", BT_FN_PTR_PTR_CONST_PTR_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN_CHKP (BUILT_IN_MEMSET, "memset", BT_FN_PTR_PTR_INT_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_RINDEX, "rindex", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY, "stpcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY, "stpncpy", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCASECMP, "strcasecmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN_CHKP (BUILT_IN_STRCAT, "strcat", BT_FN_STRING_STRING_CONST_STRING, ATTR_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN_CHKP (BUILT_IN_STRCHR, "strchr", BT_FN_STRING_CONST_STRING_INT, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRCMP, "strcmp", BT_FN_INT_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN_CHKP (BUILT_IN_STRCPY, "strcpy", BT_FN_STRING_STRING_CONST_STRING, ATTR_RET1_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRCSPN, "strcspn", BT_FN_SIZE_CONST_STRING_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRDUP, "strdup", BT_FN_STRING_CONST_STRING, ATTR_MALLOC_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNDUP, "strndup", BT_FN_STRING_CONST_STRING_SIZE, ATTR_MALLOC_NOTHROW_NONNULL_LEAF) -DEF_LIB_BUILTIN (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) +DEF_LIB_BUILTIN_CHKP (BUILT_IN_STRLEN, "strlen", BT_FN_SIZE_CONST_STRING, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCASECMP, "strncasecmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRNCAT, "strncat", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_LIB_BUILTIN (BUILT_IN_STRNCMP, "strncmp", BT_FN_INT_CONST_STRING_CONST_STRING_SIZE, ATTR_PURE_NOTHROW_NONNULL_LEAF) @@ -844,14 +862,14 @@ DEF_BUILTIN_STUB (BUILT_IN_ALLOCA_WITH_ALIGN, "__builtin_alloca_with_align") /* Object size checking builtins. */ DEF_GCC_BUILTIN (BUILT_IN_OBJECT_SIZE, "object_size", BT_FN_SIZE_CONST_PTR_INT, ATTR_PURE_NOTHROW_LEAF_LIST) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMCPY_CHK, "__memcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMMOVE_CHK, "__memmove_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_RET1_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMPCPY_CHK, "__mempcpy_chk", BT_FN_PTR_PTR_CONST_PTR_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_MEMSET_CHK, "__memset_chk", BT_FN_PTR_PTR_INT_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STPCPY_CHK, "__stpcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STPNCPY_CHK, "__stpncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) -DEF_EXT_LIB_BUILTIN (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCAT_CHK, "__strcat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) +DEF_EXT_LIB_BUILTIN_CHKP (BUILT_IN_STRCPY_CHK, "__strcpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCAT_CHK, "__strncat_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_STRNCPY_CHK, "__strncpy_chk", BT_FN_STRING_STRING_CONST_STRING_SIZE_SIZE, ATTR_NOTHROW_NONNULL_LEAF) DEF_EXT_LIB_BUILTIN (BUILT_IN_SNPRINTF_CHK, "__snprintf_chk", BT_FN_INT_STRING_SIZE_INT_SIZE_CONST_STRING_VAR, ATTR_FORMAT_PRINTF_NOTHROW_5_6) diff --git a/contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c b/contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c index 19365920a8..60c2d7f386 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c +++ b/contrib/gcc-5.0/gcc/c-family/c-cppbuiltin.c @@ -891,14 +891,8 @@ c_cpp_builtins (cpp_reader *pfile) /* Represents the C++ ABI version, always defined so it can be used while preprocessing C and assembler. */ if (flag_abi_version == 0) - /* Use a very large value so that: - - #if __GXX_ABI_VERSION >= - - will work whether the user explicitly says "-fabi-version=x" or - "-fabi-version=0". Do not use INT_MAX because that will be - different from system to system. */ - builtin_define_with_int_value ("__GXX_ABI_VERSION", 999999); + /* We should have set this to something real in c_common_post_options. */ + gcc_unreachable (); else if (flag_abi_version == 1) /* Due to a historical accident, this version had the value "102". */ diff --git a/contrib/gcc-5.0/gcc/c-family/c-format.c b/contrib/gcc-5.0/gcc/c-family/c-format.c index faaca09307..2f49b2d2d5 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-format.c +++ b/contrib/gcc-5.0/gcc/c-family/c-format.c @@ -2456,8 +2456,7 @@ check_format_types (location_t loc, format_wanted_type *types) cur_type = TYPE_MAIN_VARIANT (cur_type); /* Check whether the argument type is a character type. This leniency - only applies to certain formats, flagged with 'c'. - */ + only applies to certain formats, flagged with 'c'. */ if (types->char_lenient_flag) char_type_flag = (cur_type == char_type_node || cur_type == signed_char_type_node @@ -2486,6 +2485,20 @@ check_format_types (location_t loc, format_wanted_type *types) ? wanted_type == c_common_unsigned_type (cur_type) : wanted_type == c_common_signed_type (cur_type))) continue; + /* Don't warn about differences merely in signedness if we know + that the current type is integer-promoted and its original type + was unsigned such as that it is in the range of WANTED_TYPE. */ + if (TREE_CODE (wanted_type) == INTEGER_TYPE + && TREE_CODE (cur_type) == INTEGER_TYPE + && warn_format_signedness + && TYPE_UNSIGNED (wanted_type) + && TREE_CODE (cur_param) == NOP_EXPR) + { + tree t = TREE_TYPE (TREE_OPERAND (cur_param, 0)); + if (TYPE_UNSIGNED (t) + && cur_type == lang_hooks.types.type_promotes_to (t)) + continue; + } /* Likewise, "signed char", "unsigned char" and "char" are equivalent but the above test won't consider them equivalent. */ if (wanted_type == char_type_node diff --git a/contrib/gcc-5.0/gcc/c-family/c-omp.c b/contrib/gcc-5.0/gcc/c-family/c-omp.c index 87150459f8..86a9f54b80 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-omp.c +++ b/contrib/gcc-5.0/gcc/c-family/c-omp.c @@ -206,6 +206,9 @@ c_finish_omp_atomic (location_t loc, enum tree_code code, return error_mark_node; } + if (opcode == RDIV_EXPR) + opcode = TRUNC_DIV_EXPR; + /* ??? Validate that rhs does not overlap lhs. */ /* Take and save the address of the lhs. From then on we'll reference it @@ -240,7 +243,7 @@ c_finish_omp_atomic (location_t loc, enum tree_code code, to do this, and then take it apart again. */ if (swapped) { - rhs = build2_loc (loc, opcode, TREE_TYPE (lhs), rhs, lhs); + rhs = build_binary_op (loc, opcode, rhs, lhs, 1); opcode = NOP_EXPR; } bool save = in_late_binary_op; diff --git a/contrib/gcc-5.0/gcc/c-family/c-opts.c b/contrib/gcc-5.0/gcc/c-family/c-opts.c index d10e5bd8da..1a67b5a766 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-opts.c +++ b/contrib/gcc-5.0/gcc/c-family/c-opts.c @@ -886,6 +886,11 @@ c_common_post_options (const char **pfilename) warn_abi = false; } + /* Change flag_abi_version to be the actual current ABI level for the + benefit of c_cpp_builtins. */ + if (flag_abi_version == 0) + flag_abi_version = 8; + if (cxx_dialect >= cxx11) { /* If we're allowing C++0x constructs, don't warn about C++98 diff --git a/contrib/gcc-5.0/gcc/c/c-parser.c b/contrib/gcc-5.0/gcc/c/c-parser.c index 665ee42cf2..ceb9e1a78e 100644 --- a/contrib/gcc-5.0/gcc/c/c-parser.c +++ b/contrib/gcc-5.0/gcc/c/c-parser.c @@ -2391,6 +2391,7 @@ c_parser_declspecs (c_parser *parser, struct c_declspecs *specs, attrs_ok = true; seen_type = true; t = c_parser_enum_specifier (parser); + invoke_plugin_callbacks (PLUGIN_FINISH_TYPE, t.spec); declspecs_add_type (loc, specs, t); break; case RID_STRUCT: @@ -6232,8 +6233,8 @@ c_parser_binary_expression (c_parser *parser, struct c_expr *after, if (__builtin_expect (omp_atomic_lhs != NULL_TREE, 0) && sp == 1 \ && c_parser_peek_token (parser)->type == CPP_SEMICOLON \ && ((1 << stack[sp].prec) \ - & (1 << (PREC_BITOR | PREC_BITXOR | PREC_BITAND | PREC_SHIFT \ - | PREC_ADD | PREC_MULT))) \ + & ((1 << PREC_BITOR) | (1 << PREC_BITXOR) | (1 << PREC_BITAND) \ + | (1 << PREC_SHIFT) | (1 << PREC_ADD) | (1 << PREC_MULT))) \ && stack[sp].op != TRUNC_MOD_EXPR \ && stack[0].expr.value != error_mark_node \ && stack[1].expr.value != error_mark_node \ @@ -12610,6 +12611,7 @@ restart: { case MULT_EXPR: case TRUNC_DIV_EXPR: + case RDIV_EXPR: case PLUS_EXPR: case MINUS_EXPR: case LSHIFT_EXPR: diff --git a/contrib/gcc-5.0/gcc/c/c-typeck.c b/contrib/gcc-5.0/gcc/c/c-typeck.c index 65c6f7f427..a3a9c7760c 100644 --- a/contrib/gcc-5.0/gcc/c/c-typeck.c +++ b/contrib/gcc-5.0/gcc/c/c-typeck.c @@ -8785,8 +8785,7 @@ process_init_element (location_t loc, struct c_expr value, bool implicit, /* If value is a compound literal and we'll be just using its content, don't put it into a SAVE_EXPR. */ if (TREE_CODE (value.value) != COMPOUND_LITERAL_EXPR - || !require_constant_value - || flag_isoc99) + || !require_constant_value) { tree semantic_type = NULL_TREE; if (TREE_CODE (value.value) == EXCESS_PRECISION_EXPR) diff --git a/contrib/gcc-5.0/gcc/cfgexpand.c b/contrib/gcc-5.0/gcc/cfgexpand.c index 12021de0dd..7dfe1f6e7f 100644 --- a/contrib/gcc-5.0/gcc/cfgexpand.c +++ b/contrib/gcc-5.0/gcc/cfgexpand.c @@ -3911,7 +3911,6 @@ expand_debug_expr (tree exp) binary: case tcc_binary: - case tcc_comparison: op1 = expand_debug_expr (TREE_OPERAND (exp, 1)); if (!op1) return NULL_RTX; @@ -3925,6 +3924,10 @@ expand_debug_expr (tree exp) return NULL_RTX; break; + case tcc_comparison: + unsignedp = TYPE_UNSIGNED (TREE_TYPE (TREE_OPERAND (exp, 0))); + goto binary; + case tcc_type: case tcc_statement: gcc_unreachable (); @@ -4006,7 +4009,7 @@ expand_debug_expr (tree exp) op0 = copy_rtx (op0); if (GET_MODE (op0) == BLKmode - /* If op0 is not BLKmode, but BLKmode is, adjust_mode + /* If op0 is not BLKmode, but mode is, adjust_mode below would ICE. While it is likely a FE bug, try to be robust here. See PR43166. */ || mode == BLKmode @@ -5285,7 +5288,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) if (have_debug_uses) { - /* OP is a TERed SSA name, with DEF it's defining + /* OP is a TERed SSA name, with DEF its defining statement, and where OP is used in further debug instructions. Generate a debug temporary, and replace all uses of OP in debug insns with that diff --git a/contrib/gcc-5.0/gcc/cfghooks.c b/contrib/gcc-5.0/gcc/cfghooks.c index 4b57280169..abeab8cf1a 100644 --- a/contrib/gcc-5.0/gcc/cfghooks.c +++ b/contrib/gcc-5.0/gcc/cfghooks.c @@ -863,6 +863,9 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge), if (redirect_edge_p (e)) { dummy->frequency += EDGE_FREQUENCY (e); + if (dummy->frequency > BB_FREQ_MAX) + dummy->frequency = BB_FREQ_MAX; + dummy->count += e->count; fallthru->count += e->count; ei_next (&ei); diff --git a/contrib/gcc-5.0/gcc/cgraph.c b/contrib/gcc-5.0/gcc/cgraph.c index 89d0d2feb9..a71f68ca4e 100644 --- a/contrib/gcc-5.0/gcc/cgraph.c +++ b/contrib/gcc-5.0/gcc/cgraph.c @@ -1324,7 +1324,8 @@ cgraph_edge::redirect_call_stmt_to_callee (void) (int64_t)e->count); gcc_assert (e2->speculative); push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl)); - new_stmt = gimple_ic (e->call_stmt, dyn_cast (ref->referred), + new_stmt = gimple_ic (e->call_stmt, + dyn_cast (ref->referred), e->count || e2->count ? RDIV (e->count * REG_BR_PROB_BASE, e->count + e2->count) @@ -1464,6 +1465,9 @@ cgraph_edge::redirect_call_stmt_to_callee (void) update_stmt_fn (DECL_STRUCT_FUNCTION (e->caller->decl), new_stmt); } + maybe_remove_unused_call_args (DECL_STRUCT_FUNCTION (e->caller->decl), + new_stmt); + e->caller->set_call_stmt_including_clones (e->call_stmt, new_stmt, false); if (symtab->dump_file) @@ -1842,20 +1846,7 @@ cgraph_node::local_info (tree decl) cgraph_node *node = get (decl); if (!node) return NULL; - return &node->local; -} - -/* Return global info for the compiled function. */ - -cgraph_global_info * -cgraph_node::global_info (tree decl) -{ - gcc_assert (TREE_CODE (decl) == FUNCTION_DECL - && symtab->global_info_ready); - cgraph_node *node = get (decl); - if (!node) - return NULL; - return &node->global; + return &node->ultimate_alias_target ()->local; } /* Return local info for the compiled function. */ @@ -1865,11 +1856,13 @@ cgraph_node::rtl_info (tree decl) { gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); cgraph_node *node = get (decl); - if (!node - || (decl != current_function_decl - && !TREE_ASM_WRITTEN (node->decl))) + if (!node) + return NULL; + node = node->ultimate_alias_target (); + if (node->decl != current_function_decl + && !TREE_ASM_WRITTEN (node->decl)) return NULL; - return &node->rtl; + return &node->ultimate_alias_target ()->rtl; } /* Return a string describing the failure REASON. */ diff --git a/contrib/gcc-5.0/gcc/cgraph.h b/contrib/gcc-5.0/gcc/cgraph.h index 40e6c6c767..b9a276c371 100644 --- a/contrib/gcc-5.0/gcc/cgraph.h +++ b/contrib/gcc-5.0/gcc/cgraph.h @@ -1164,9 +1164,6 @@ public: /* Return local info for the compiled function. */ static cgraph_local_info *local_info (tree decl); - /* Return global info for the compiled function. */ - static cgraph_global_info *global_info (tree); - /* Return local info for the compiled function. */ static cgraph_rtl_info *rtl_info (tree); @@ -1187,10 +1184,6 @@ public: return node->used_from_object_file_p (); } - /* Return true when cgraph_node can not be local. - Worker for cgraph_local_node_p. */ - static bool non_local_p (cgraph_node *node, void *); - /* Verify whole cgraph structure. */ static void DEBUG_FUNCTION verify_cgraph_nodes (void); @@ -1296,6 +1289,8 @@ public: other operation that could make previously non-trapping memory accesses trapping. */ unsigned nonfreeing_fn : 1; + /* True if there was multiple COMDAT bodies merged by lto-symtab. */ + unsigned merged : 1; }; /* A cgraph node set is a collection of cgraph nodes. A cgraph node diff --git a/contrib/gcc-5.0/gcc/cgraphunit.c b/contrib/gcc-5.0/gcc/cgraphunit.c index a2650f724c..942826d368 100644 --- a/contrib/gcc-5.0/gcc/cgraphunit.c +++ b/contrib/gcc-5.0/gcc/cgraphunit.c @@ -442,8 +442,10 @@ cgraph_node::finalize_function (tree decl, bool no_collect) node->local.redefined_extern_inline = true; } - notice_global_symbol (decl); + /* Set definition first before calling notice_global_symbol so that + it is available to notice_global_symbol. */ node->definition = true; + notice_global_symbol (decl); node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL; /* With -fkeep-inline-functions we are keeping all inline functions except @@ -580,8 +582,19 @@ cgraph_node::analyze (void) if (thunk.thunk_p) { - create_edge (cgraph_node::get (thunk.alias), - NULL, 0, CGRAPH_FREQ_BASE); + cgraph_node *t = cgraph_node::get (thunk.alias); + + create_edge (t, NULL, 0, CGRAPH_FREQ_BASE); + /* Target code in expand_thunk may need the thunk's target + to be analyzed, so recurse here. */ + if (!t->analyzed) + t->analyze (); + if (t->alias) + { + t = t->get_alias_target (); + if (!t->analyzed) + t->analyze (); + } if (!expand_thunk (false, false)) { thunk.alias = NULL; @@ -792,8 +805,10 @@ varpool_node::finalize_decl (tree decl) if (node->definition) return; - notice_global_symbol (decl); + /* Set definition first before calling notice_global_symbol so that + it is available to notice_global_symbol. */ node->definition = true; + notice_global_symbol (decl); if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl) /* Traditionally we do not eliminate static variables when not optimizing and when not doing toplevel reoder. */ @@ -1515,7 +1530,8 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) current_function_decl = thunk_fndecl; /* Ensure thunks are emitted in their correct sections. */ - resolve_unique_section (thunk_fndecl, 0, flag_function_sections); + resolve_unique_section (thunk_fndecl, 0, + flag_function_sections); DECL_RESULT (thunk_fndecl) = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl), @@ -1547,6 +1563,14 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) thunk.thunk_p = false; analyzed = false; } + else if (stdarg_p (TREE_TYPE (thunk_fndecl))) + { + error ("generic thunk code fails for method %qD which uses %<...%>", + thunk_fndecl); + TREE_ASM_WRITTEN (thunk_fndecl) = 1; + analyzed = true; + return false; + } else { tree restype; @@ -1560,6 +1584,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) gcall *call; greturn *ret; + bool alias_is_noreturn = TREE_THIS_VOLATILE (alias); if (in_lto_p) get_untransformed_body (); @@ -1568,7 +1593,8 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) current_function_decl = thunk_fndecl; /* Ensure thunks are emitted in their correct sections. */ - resolve_unique_section (thunk_fndecl, 0, flag_function_sections); + resolve_unique_section (thunk_fndecl, 0, + flag_function_sections); DECL_IGNORED_P (thunk_fndecl) = 1; bitmap_obstack_initialize (NULL); @@ -1595,7 +1621,7 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) bsi = gsi_start_bb (bb); /* Build call to the function being thunked. */ - if (!VOID_TYPE_P (restype)) + if (!VOID_TYPE_P (restype) && !alias_is_noreturn) { if (DECL_BY_REFERENCE (resdecl)) { @@ -1609,11 +1635,16 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) } else if (!is_gimple_reg_type (restype)) { - restmp = resdecl; + if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl))) + { + restmp = resdecl; - if (TREE_CODE (restmp) == VAR_DECL) - add_local_decl (cfun, restmp); - BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp; + if (TREE_CODE (restmp) == VAR_DECL) + add_local_decl (cfun, restmp); + BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp; + } + else + restmp = create_tmp_var (restype, "retval"); } else restmp = create_tmp_reg (restype, "retval"); @@ -1649,14 +1680,14 @@ cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) callees->call_stmt = call; gimple_call_set_from_thunk (call, true); gimple_call_set_with_bounds (call, instrumentation_clone); - if (restmp) + if (restmp && !alias_is_noreturn) { gimple_call_set_lhs (call, restmp); gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp), TREE_TYPE (TREE_TYPE (alias)))); } gsi_insert_after (&bsi, call, GSI_NEW_STMT); - if (!(gimple_call_flags (call) & ECF_NORETURN)) + if (!alias_is_noreturn) { if (restmp && !this_adjusting && (fixed_offset || virtual_offset)) diff --git a/contrib/gcc-5.0/gcc/combine.c b/contrib/gcc-5.0/gcc/combine.c index ad3bed0f2c..f779117cd7 100644 --- a/contrib/gcc-5.0/gcc/combine.c +++ b/contrib/gcc-5.0/gcc/combine.c @@ -284,6 +284,16 @@ typedef struct reg_stat_struct { static vec reg_stat; +/* One plus the highest pseudo for which we track REG_N_SETS. + regstat_init_n_sets_and_refs allocates the array for REG_N_SETS just once, + but during combine_split_insns new pseudos can be created. As we don't have + updated DF information in that case, it is hard to initialize the array + after growing. The combiner only cares about REG_N_SETS (regno) == 1, + so instead of growing the arrays, just assume all newly created pseudos + during combine might be set multiple times. */ + +static unsigned int reg_n_sets_max; + /* Record the luid of the last insn that invalidated memory (anything that writes memory, and subroutine calls, but not pushes). */ @@ -2420,7 +2430,9 @@ can_change_dest_mode (rtx x, int added_sets, machine_mode mode) >= hard_regno_nregs[regno][mode])); /* Or a pseudo that is only used once. */ - return (REG_N_SETS (regno) == 1 && !added_sets + return (regno < reg_n_sets_max + && REG_N_SETS (regno) == 1 + && !added_sets && !REG_USERVAR_P (x)); } @@ -3630,7 +3642,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, if (REG_P (new_i3_dest) && REG_P (new_i2_dest) - && REGNO (new_i3_dest) == REGNO (new_i2_dest)) + && REGNO (new_i3_dest) == REGNO (new_i2_dest) + && REGNO (new_i2_dest) < reg_n_sets_max) INC_REG_N_SETS (REGNO (new_i2_dest), 1); } } @@ -4480,7 +4493,8 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, zero its use count so it won't make `reload' do any work. */ if (! added_sets_2 && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat)) - && ! i2dest_in_i2src) + && ! i2dest_in_i2src + && REGNO (i2dest) < reg_n_sets_max) INC_REG_N_SETS (REGNO (i2dest), -1); } @@ -4497,7 +4511,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, record_value_for_reg (i1dest, i1_insn, i1_val); - if (! added_sets_1 && ! i1dest_in_i1src) + if (! added_sets_1 + && ! i1dest_in_i1src + && REGNO (i1dest) < reg_n_sets_max) INC_REG_N_SETS (REGNO (i1dest), -1); } @@ -4514,7 +4530,9 @@ try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0, record_value_for_reg (i0dest, i0_insn, i0_val); - if (! added_sets_0 && ! i0dest_in_i0src) + if (! added_sets_0 + && ! i0dest_in_i0src + && REGNO (i0dest) < reg_n_sets_max) INC_REG_N_SETS (REGNO (i0dest), -1); } @@ -9750,6 +9768,7 @@ reg_nonzero_bits_for_combine (const_rtx x, machine_mode mode, || (rsp->last_set_label == label_tick && DF_INSN_LUID (rsp->last_set) < subst_low_luid) || (REGNO (x) >= FIRST_PSEUDO_REGISTER + && REGNO (x) < reg_n_sets_max && REG_N_SETS (REGNO (x)) == 1 && !REGNO_REG_SET_P (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb), @@ -9825,6 +9844,7 @@ reg_num_sign_bit_copies_for_combine (const_rtx x, machine_mode mode, || (rsp->last_set_label == label_tick && DF_INSN_LUID (rsp->last_set) < subst_low_luid) || (REGNO (x) >= FIRST_PSEUDO_REGISTER + && REGNO (x) < reg_n_sets_max && REG_N_SETS (REGNO (x)) == 1 && !REGNO_REG_SET_P (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb), @@ -12863,6 +12883,7 @@ get_last_value_validate (rtx *loc, rtx_insn *insn, int tick, int replace) /* If this is a pseudo-register that was only set once and not live at the beginning of the function, it is always valid. */ || (! (regno >= FIRST_PSEUDO_REGISTER + && regno < reg_n_sets_max && REG_N_SETS (regno) == 1 && (!REGNO_REG_SET_P (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb), @@ -12979,6 +13000,7 @@ get_last_value (const_rtx x) if (value == 0 || (rsp->last_set_label < label_tick_ebb_start && (regno < FIRST_PSEUDO_REGISTER + || regno >= reg_n_sets_max || REG_N_SETS (regno) != 1 || REGNO_REG_SET_P (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb), regno)))) @@ -14166,6 +14188,7 @@ rest_of_handle_combine (void) df_analyze (); regstat_init_n_sets_and_refs (); + reg_n_sets_max = max_reg_num (); rebuild_jump_labels_after_combine = combine_instructions (get_insns (), max_reg_num ()); diff --git a/contrib/gcc-5.0/gcc/common.opt b/contrib/gcc-5.0/gcc/common.opt index 262481ff43..0c60e84797 100644 --- a/contrib/gcc-5.0/gcc/common.opt +++ b/contrib/gcc-5.0/gcc/common.opt @@ -806,7 +806,8 @@ Driver Undocumented ; ; 1: The version of the ABI first used in G++ 3.2. No longer selectable. ; -; 2: The version of the ABI first used in G++ 3.4 (and current default). +; 2: The version of the ABI first used in G++ 3.4, and the default +; until GCC 4.9. ; ; 3: The version of the ABI that fixes the missing underscore ; in template non-type arguments of pointer type. @@ -831,7 +832,8 @@ Driver Undocumented ; ; 8: The version of the ABI that corrects the substitution behavior of ; function types with function-cv-qualifiers. -; First selectable in G++ 4.9. +; First selectable in G++ 4.9 and default in G++ 5 +; (set in c_common_post_options). ; ; Additional positive integers will be assigned as new versions of ; the ABI become the default version of the ABI. @@ -1189,7 +1191,7 @@ Perform interprocedural reduction of aggregates feliminate-unused-debug-symbols Common Report Var(flag_debug_only_used_symbols) -Perform unused type elimination in debug info +Perform unused symbol elimination in debug info feliminate-unused-debug-types Common Report Var(flag_eliminate_unused_debug_types) Init(1) @@ -1372,7 +1374,7 @@ Common Report Var(flag_if_conversion2) Optimization Perform conversion of conditional jumps to conditional execution fstack-reuse= -Common Joined RejectNegative Enum(stack_reuse_level) Var(flag_stack_reuse) Init(SR_ALL) +Common Joined RejectNegative Enum(stack_reuse_level) Var(flag_stack_reuse) Init(SR_ALL) Optimization -fstack-reuse=[all|named_vars|none] Set stack reuse level for local variables. Enum @@ -1856,6 +1858,11 @@ fregmove Common Ignore Does nothing. Preserved for backward compatibility. +flifetime-dse +Common Report Var(flag_lifetime_dse) Init(1) Optimization +Tell DSE that the storage for a C++ object is dead when the constructor +starts and when the destructor finishes. + flive-range-shrinkage Common Report Var(flag_live_range_shrinkage) Init(0) Optimization Relief of register pressure through live range shrinkage diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.c b/contrib/gcc-5.0/gcc/config/i386/i386.c index 7f5796ab52..71a5b2202e 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.c +++ b/contrib/gcc-5.0/gcc/config/i386/i386.c @@ -5070,35 +5070,20 @@ ix86_can_inline_p (tree caller, tree callee) /* Remember the last target of ix86_set_current_function. */ static GTY(()) tree ix86_previous_fndecl; -/* Set target globals to default. */ +/* Set targets globals to the default (or current #pragma GCC target + if active). Invalidate ix86_previous_fndecl cache. */ -static void -ix86_reset_to_default_globals (void) -{ - tree old_tree = (ix86_previous_fndecl - ? DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl) - : NULL_TREE); - - if (old_tree) - { - tree new_tree = target_option_current_node; - cl_target_option_restore (&global_options, - TREE_TARGET_OPTION (new_tree)); - if (TREE_TARGET_GLOBALS (new_tree)) - restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); - else if (new_tree == target_option_default_node) - restore_target_globals (&default_target_globals); - else - TREE_TARGET_GLOBALS (new_tree) - = save_target_globals_default_opts (); - } -} - -/* Invalidate ix86_previous_fndecl cache. */ void ix86_reset_previous_fndecl (void) { - ix86_reset_to_default_globals (); + tree new_tree = target_option_current_node; + cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + if (TREE_TARGET_GLOBALS (new_tree)) + restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); + else if (new_tree == target_option_default_node) + restore_target_globals (&default_target_globals); + else + TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts (); ix86_previous_fndecl = NULL_TREE; } @@ -5111,34 +5096,39 @@ ix86_set_current_function (tree fndecl) /* Only change the context if the function changes. This hook is called several times in the course of compiling a function, and we don't want to slow things down too much or call target_reinit when it isn't safe. */ - if (fndecl && fndecl != ix86_previous_fndecl) - { - tree old_tree = (ix86_previous_fndecl - ? DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl) - : NULL_TREE); + if (fndecl == ix86_previous_fndecl) + return; - tree new_tree = (fndecl - ? DECL_FUNCTION_SPECIFIC_TARGET (fndecl) - : NULL_TREE); + tree old_tree; + if (ix86_previous_fndecl == NULL_TREE) + old_tree = target_option_current_node; + else if (DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl)) + old_tree = DECL_FUNCTION_SPECIFIC_TARGET (ix86_previous_fndecl); + else + old_tree = target_option_default_node; - if (old_tree == new_tree) - ; + if (fndecl == NULL_TREE) + { + if (old_tree != target_option_current_node) + ix86_reset_previous_fndecl (); + return; + } - else if (new_tree && new_tree != target_option_default_node) - { - cl_target_option_restore (&global_options, - TREE_TARGET_OPTION (new_tree)); - if (TREE_TARGET_GLOBALS (new_tree)) - restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); - else - TREE_TARGET_GLOBALS (new_tree) - = save_target_globals_default_opts (); - } + tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl); + if (new_tree == NULL_TREE) + new_tree = target_option_default_node; - else if (old_tree && old_tree != target_option_default_node) - ix86_reset_to_default_globals (); - ix86_previous_fndecl = fndecl; + if (old_tree != new_tree) + { + cl_target_option_restore (&global_options, TREE_TARGET_OPTION (new_tree)); + if (TREE_TARGET_GLOBALS (new_tree)) + restore_target_globals (TREE_TARGET_GLOBALS (new_tree)); + else if (new_tree == target_option_default_node) + restore_target_globals (&default_target_globals); + else + TREE_TARGET_GLOBALS (new_tree) = save_target_globals_default_opts (); } + ix86_previous_fndecl = fndecl; } @@ -5767,49 +5757,55 @@ ix86_function_regparm (const_tree type, const_tree decl) /* Use register calling convention for local functions when possible. */ if (decl - && TREE_CODE (decl) == FUNCTION_DECL + && TREE_CODE (decl) == FUNCTION_DECL) + { + cgraph_node *target = cgraph_node::get (decl); + if (target) + target = target->function_symbol (); + /* Caller and callee must agree on the calling convention, so checking here just optimize means that with __attribute__((optimize (...))) caller could use regparm convention and callee not, or vice versa. Instead look at whether the callee is optimized or not. */ - && opt_for_fn (decl, optimize) - && !(profile_flag && !flag_fentry)) - { - /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */ - cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE (decl)); - if (i && i->local && i->can_change_signature) + if (target && opt_for_fn (target->decl, optimize) + && !(profile_flag && !flag_fentry)) { - int local_regparm, globals = 0, regno; + cgraph_local_info *i = &target->local; + if (i && i->local && i->can_change_signature) + { + int local_regparm, globals = 0, regno; - /* Make sure no regparm register is taken by a - fixed register variable. */ - for (local_regparm = 0; local_regparm < REGPARM_MAX; local_regparm++) - if (fixed_regs[local_regparm]) - break; + /* Make sure no regparm register is taken by a + fixed register variable. */ + for (local_regparm = 0; local_regparm < REGPARM_MAX; + local_regparm++) + if (fixed_regs[local_regparm]) + break; - /* We don't want to use regparm(3) for nested functions as - these use a static chain pointer in the third argument. */ - if (local_regparm == 3 && DECL_STATIC_CHAIN (decl)) - local_regparm = 2; + /* We don't want to use regparm(3) for nested functions as + these use a static chain pointer in the third argument. */ + if (local_regparm == 3 && DECL_STATIC_CHAIN (target->decl)) + local_regparm = 2; - /* In 32-bit mode save a register for the split stack. */ - if (!TARGET_64BIT && local_regparm == 3 && flag_split_stack) - local_regparm = 2; + /* Save a register for the split stack. */ + if (local_regparm == 3 && flag_split_stack) + local_regparm = 2; - /* Each fixed register usage increases register pressure, - so less registers should be used for argument passing. - This functionality can be overriden by an explicit - regparm value. */ - for (regno = AX_REG; regno <= DI_REG; regno++) - if (fixed_regs[regno]) - globals++; + /* Each fixed register usage increases register pressure, + so less registers should be used for argument passing. + This functionality can be overriden by an explicit + regparm value. */ + for (regno = AX_REG; regno <= DI_REG; regno++) + if (fixed_regs[regno]) + globals++; - local_regparm - = globals < local_regparm ? local_regparm - globals : 0; + local_regparm + = globals < local_regparm ? local_regparm - globals : 0; - if (local_regparm > regparm) - regparm = local_regparm; + if (local_regparm > regparm) + regparm = local_regparm; + } } } @@ -5848,15 +5844,37 @@ ix86_function_sseregparm (const_tree type, const_tree decl, bool warn) return 2; } + if (!decl) + return 0; + + cgraph_node *target = cgraph_node::get (decl); + if (target) + target = target->function_symbol (); + /* For local functions, pass up to SSE_REGPARM_MAX SFmode (and DFmode for SSE2) arguments in SSE registers. */ - if (decl && TARGET_SSE_MATH && optimize + if (target + /* TARGET_SSE_MATH */ + && (target_opts_for_fn (target->decl)->x_ix86_fpmath & FPMATH_SSE) + && opt_for_fn (target->decl, optimize) && !(profile_flag && !flag_fentry)) { - /* FIXME: remove this CONST_CAST when cgraph.[ch] is constified. */ - cgraph_local_info *i = cgraph_node::local_info (CONST_CAST_TREE(decl)); + cgraph_local_info *i = &target->local; if (i && i->local && i->can_change_signature) - return TARGET_SSE2 ? 2 : 1; + { + /* Refuse to produce wrong code when local function with SSE enabled + is called from SSE disabled function. + We may work hard to work out these scenarios but hopefully + it doesnot matter in practice. */ + if (!TARGET_SSE && warn) + { + error ("calling %qD with SSE caling convention without " + "SSE/SSE2 enabled", decl); + return 0; + } + return TARGET_SSE2_P (target_opts_for_fn (target->decl) + ->x_ix86_isa_flags) ? 2 : 1; + } } return 0; @@ -6343,20 +6361,25 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ tree fndecl, int caller) { - struct cgraph_local_info *i; + struct cgraph_local_info *i = NULL; + struct cgraph_node *target = NULL; memset (cum, 0, sizeof (*cum)); if (fndecl) { - i = cgraph_node::local_info (fndecl); - cum->call_abi = ix86_function_abi (fndecl); + target = cgraph_node::get (fndecl); + if (target) + { + target = target->function_symbol (); + i = cgraph_node::local_info (target->decl); + cum->call_abi = ix86_function_abi (target->decl); + } + else + cum->call_abi = ix86_function_abi (fndecl); } else - { - i = NULL; - cum->call_abi = ix86_function_type_abi (fntype); - } + cum->call_abi = ix86_function_type_abi (fntype); cum->caller = caller; @@ -6392,7 +6415,7 @@ init_cumulative_args (CUMULATIVE_ARGS *cum, /* Argument info to initialize */ helping K&R code. FIXME: once typesytem is fixed, we won't need this code anymore. */ if (i && i->local && i->can_change_signature) - fntype = TREE_TYPE (fndecl); + fntype = TREE_TYPE (target->decl); cum->stdarg = stdarg_p (fntype); cum->maybe_vaarg = (fntype ? (!prototype_p (fntype) || stdarg_p (fntype)) @@ -30574,6 +30597,8 @@ static void ix86_add_new_builtins (HOST_WIDE_INT isa) { int i; + tree saved_current_target_pragma = current_target_pragma; + current_target_pragma = NULL_TREE; for (i = 0; i < (int)IX86_BUILTIN_MAX; i++) { @@ -30600,6 +30625,8 @@ ix86_add_new_builtins (HOST_WIDE_INT isa) TREE_NOTHROW (decl) = 1; } } + + current_target_pragma = saved_current_target_pragma; } /* Bits for builtin_description.flag. */ diff --git a/contrib/gcc-5.0/gcc/cp/constexpr.c b/contrib/gcc-5.0/gcc/cp/constexpr.c index f143420752..2b56cb2d62 100644 --- a/contrib/gcc-5.0/gcc/cp/constexpr.c +++ b/contrib/gcc-5.0/gcc/cp/constexpr.c @@ -1348,8 +1348,12 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, if (DECL_SAVED_TREE (fun) == NULL_TREE && (DECL_CONSTRUCTOR_P (fun) || DECL_DESTRUCTOR_P (fun))) /* The maybe-in-charge 'tor had its DECL_SAVED_TREE - cleared, try the first clone. */ - fun = DECL_CHAIN (fun); + cleared, try a clone. */ + for (fun = DECL_CHAIN (fun); + fun && DECL_CLONED_FUNCTION_P (fun); + fun = DECL_CHAIN (fun)) + if (DECL_SAVED_TREE (fun)) + break; gcc_assert (DECL_SAVED_TREE (fun)); tree parms, res; diff --git a/contrib/gcc-5.0/gcc/cp/cp-tree.h b/contrib/gcc-5.0/gcc/cp/cp-tree.h index 1176583cef..65219f159e 100644 --- a/contrib/gcc-5.0/gcc/cp/cp-tree.h +++ b/contrib/gcc-5.0/gcc/cp/cp-tree.h @@ -84,6 +84,7 @@ c-common.h, not after. PACK_EXPANSION_LOCAL_P (in *_PACK_EXPANSION) TINFO_HAS_ACCESS_ERRORS (in TEMPLATE_INFO) SIZEOF_EXPR_TYPE_P (in SIZEOF_EXPR) + BLOCK_OUTER_CURLY_BRACE_P (in BLOCK) 1: IDENTIFIER_VIRTUAL_P (in IDENTIFIER_NODE) TI_PENDING_TEMPLATE_FLAG. TEMPLATE_PARMS_FOR_INLINE. @@ -326,6 +327,9 @@ typedef struct ptrmem_cst * ptrmem_cst_t; #define STATEMENT_LIST_TRY_BLOCK(NODE) \ TREE_LANG_FLAG_2 (STATEMENT_LIST_CHECK (NODE)) +/* Mark the outer curly brace BLOCK. */ +#define BLOCK_OUTER_CURLY_BRACE_P(NODE) TREE_LANG_FLAG_0 (BLOCK_CHECK (NODE)) + /* Nonzero if this statement should be considered a full-expression, i.e., if temporaries created during this statement should have their destructors run at the end of this statement. */ diff --git a/contrib/gcc-5.0/gcc/cp/decl.c b/contrib/gcc-5.0/gcc/cp/decl.c index 5119964dea..810acd56e6 100644 --- a/contrib/gcc-5.0/gcc/cp/decl.c +++ b/contrib/gcc-5.0/gcc/cp/decl.c @@ -610,7 +610,10 @@ poplevel (int keep, int reverse, int functionbody) or if this level is a function body, create a BLOCK to record them for the life of this function. */ block = NULL_TREE; - if (keep == 1 || functionbody) + /* Avoid function body block if possible. */ + if (functionbody && subblocks && BLOCK_CHAIN (subblocks) == NULL_TREE) + keep = 0; + else if (keep == 1 || functionbody) block = make_node (BLOCK); if (block != NULL_TREE) { @@ -793,11 +796,16 @@ poplevel (int keep, int reverse, int functionbody) check over all the labels. */ if (functionbody) { - /* Since this is the top level block of a function, the vars are - the function's parameters. Don't leave them in the BLOCK - because they are found in the FUNCTION_DECL instead. */ - BLOCK_VARS (block) = 0; - pop_labels (block); + if (block) + { + /* Since this is the top level block of a function, the vars are + the function's parameters. Don't leave them in the BLOCK + because they are found in the FUNCTION_DECL instead. */ + BLOCK_VARS (block) = 0; + pop_labels (block); + } + else + pop_labels (subblocks); } kind = current_binding_level->kind; @@ -819,7 +827,17 @@ poplevel (int keep, int reverse, int functionbody) /* The current function is being defined, so its DECL_INITIAL should be error_mark_node. */ gcc_assert (DECL_INITIAL (current_function_decl) == error_mark_node); - DECL_INITIAL (current_function_decl) = block; + DECL_INITIAL (current_function_decl) = block ? block : subblocks; + if (subblocks) + { + if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl)) + { + if (BLOCK_SUBBLOCKS (subblocks)) + BLOCK_OUTER_CURLY_BRACE_P (BLOCK_SUBBLOCKS (subblocks)) = 1; + } + else + BLOCK_OUTER_CURLY_BRACE_P (subblocks) = 1; + } } else if (block) current_binding_level->blocks @@ -1813,6 +1831,8 @@ duplicate_decls (tree newdecl, tree olddecl, bool newdecl_is_friend) DECL_PURE_VIRTUAL_P (newdecl) |= DECL_PURE_VIRTUAL_P (olddecl); DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl); DECL_INVALID_OVERRIDER_P (newdecl) |= DECL_INVALID_OVERRIDER_P (olddecl); + DECL_FINAL_P (newdecl) |= DECL_FINAL_P (olddecl); + DECL_OVERRIDE_P (newdecl) |= DECL_OVERRIDE_P (olddecl); DECL_THIS_STATIC (newdecl) |= DECL_THIS_STATIC (olddecl); if (DECL_OVERLOADED_OPERATOR_P (olddecl) != ERROR_MARK) SET_OVERLOADED_OPERATOR_CODE @@ -13916,15 +13936,19 @@ begin_destructor_body (void) initialize_vtbl_ptrs (current_class_ptr); finish_compound_stmt (compound_stmt); - /* Insert a cleanup to let the back end know that the object is dead - when we exit the destructor, either normally or via exception. */ - tree btype = CLASSTYPE_AS_BASE (current_class_type); - tree clobber = build_constructor (btype, NULL); - TREE_THIS_VOLATILE (clobber) = true; - tree bref = build_nop (build_reference_type (btype), current_class_ptr); - bref = convert_from_reference (bref); - tree exprstmt = build2 (MODIFY_EXPR, btype, bref, clobber); - finish_decl_cleanup (NULL_TREE, exprstmt); + if (flag_lifetime_dse) + { + /* Insert a cleanup to let the back end know that the object is dead + when we exit the destructor, either normally or via exception. */ + tree btype = CLASSTYPE_AS_BASE (current_class_type); + tree clobber = build_constructor (btype, NULL); + TREE_THIS_VOLATILE (clobber) = true; + tree bref = build_nop (build_reference_type (btype), + current_class_ptr); + bref = convert_from_reference (bref); + tree exprstmt = build2 (MODIFY_EXPR, btype, bref, clobber); + finish_decl_cleanup (NULL_TREE, exprstmt); + } /* And insert cleanups for our bases and members so that they will be properly destroyed if we throw. */ @@ -14051,10 +14075,14 @@ finish_function_body (tree compstmt) tree outer_curly_brace_block (tree fndecl) { - tree block = BLOCK_SUBBLOCKS (DECL_INITIAL (fndecl)); - if (FUNCTION_NEEDS_BODY_BLOCK (current_function_decl)) - /* Skip the artificial function body block. */ - block = BLOCK_SUBBLOCKS (block); + tree block = DECL_INITIAL (fndecl); + if (BLOCK_OUTER_CURLY_BRACE_P (block)) + return block; + block = BLOCK_SUBBLOCKS (block); + if (BLOCK_OUTER_CURLY_BRACE_P (block)) + return block; + block = BLOCK_SUBBLOCKS (block); + gcc_assert (BLOCK_OUTER_CURLY_BRACE_P (block)); return block; } diff --git a/contrib/gcc-5.0/gcc/cp/except.c b/contrib/gcc-5.0/gcc/cp/except.c index 6aff7b5943..3ff1ce607e 100644 --- a/contrib/gcc-5.0/gcc/cp/except.c +++ b/contrib/gcc-5.0/gcc/cp/except.c @@ -1148,7 +1148,7 @@ check_noexcept_r (tree *tp, int * /*walk_subtrees*/, void * /*data*/) { tree t = *tp; enum tree_code code = TREE_CODE (t); - if (code == CALL_EXPR + if ((code == CALL_EXPR && CALL_EXPR_FN (t)) || code == AGGR_INIT_EXPR) { /* We can only use the exception specification of the called function diff --git a/contrib/gcc-5.0/gcc/cp/init.c b/contrib/gcc-5.0/gcc/cp/init.c index e600472c72..0274663c8f 100644 --- a/contrib/gcc-5.0/gcc/cp/init.c +++ b/contrib/gcc-5.0/gcc/cp/init.c @@ -3539,7 +3539,9 @@ build_vec_init (tree base, tree maxindex, tree init, /* Should we try to create a constant initializer? */ bool try_const = (TREE_CODE (atype) == ARRAY_TYPE && TREE_CONSTANT (maxindex) - && init && TREE_CODE (init) == CONSTRUCTOR + && (init ? TREE_CODE (init) == CONSTRUCTOR + : (type_has_constexpr_default_constructor + (inner_elt_type))) && (literal_type_p (inner_elt_type) || TYPE_HAS_CONSTEXPR_CTOR (inner_elt_type))); vec *const_vec = NULL; @@ -3677,6 +3679,12 @@ build_vec_init (tree base, tree maxindex, tree init, We do need to keep going if we're copying an array. */ + if (try_const && !init) + /* With a constexpr default constructor, which we checked for when + setting try_const above, default-initialization is equivalent to + value-initialization, and build_value_init gives us something more + friendly to maybe_constant_init. */ + explicit_value_init_p = true; if (from_array || ((type_build_ctor_call (type) || init || explicit_value_init_p) && ! (tree_fits_shwi_p (maxindex) @@ -3781,6 +3789,7 @@ build_vec_init (tree base, tree maxindex, tree init, if (try_const) { + /* FIXME refs to earlier elts */ tree e = maybe_constant_init (elt_init); if (reduced_constant_expression_p (e)) { @@ -3795,6 +3804,8 @@ build_vec_init (tree base, tree maxindex, tree init, saw_non_const = true; if (do_static_init) e = build_zero_init (TREE_TYPE (e), NULL_TREE, true); + else + e = NULL_TREE; } if (e) diff --git a/contrib/gcc-5.0/gcc/cp/mangle.c b/contrib/gcc-5.0/gcc/cp/mangle.c index 45377fc02e..fbf4bf27c0 100644 --- a/contrib/gcc-5.0/gcc/cp/mangle.c +++ b/contrib/gcc-5.0/gcc/cp/mangle.c @@ -682,7 +682,8 @@ write_mangled_name (const tree decl, bool top_level) } else if (VAR_P (decl) /* Variable template instantiations are mangled. */ - && !(DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)) + && !(DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) + && variable_template_p (DECL_TI_TEMPLATE (decl))) /* The names of non-static global variables aren't mangled. */ && DECL_EXTERNAL_LINKAGE_P (decl) && (CP_DECL_CONTEXT (decl) == global_namespace diff --git a/contrib/gcc-5.0/gcc/cp/method.c b/contrib/gcc-5.0/gcc/cp/method.c index aeb3791022..33e2f3cb52 100644 --- a/contrib/gcc-5.0/gcc/cp/method.c +++ b/contrib/gcc-5.0/gcc/cp/method.c @@ -418,20 +418,6 @@ use_thunk (tree thunk_fndecl, bool emit_p) if (DECL_ONE_ONLY (function)) thunk_node->add_to_same_comdat_group (funcn); - if (!this_adjusting - || !targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, - virtual_value, alias)) - { - /* If this is a covariant thunk, or we don't have the necessary - code for efficient thunks, generate a thunk function that - just makes a call to the real function. Unfortunately, this - doesn't work for varargs. */ - - if (varargs_function_p (function)) - error ("generic thunk code fails for method %q#D which uses %<...%>", - function); - } - pop_from_top_level (); } diff --git a/contrib/gcc-5.0/gcc/cp/parser.c b/contrib/gcc-5.0/gcc/cp/parser.c index 7168aba358..e81e9d3476 100644 --- a/contrib/gcc-5.0/gcc/cp/parser.c +++ b/contrib/gcc-5.0/gcc/cp/parser.c @@ -3828,7 +3828,7 @@ lookup_literal_operator (tree name, vec *args) work in presence of default arguments on the literal operator parameters. */ && parmtypes == void_list_node) - return fn; + return decl; } } @@ -3862,12 +3862,7 @@ cp_parser_userdef_char_literal (cp_parser *parser) } result = finish_call_expr (decl, &args, false, true, tf_warning_or_error); release_tree_vector (args); - if (result != error_mark_node) - return result; - - error ("unable to find character literal operator %qD with %qT argument", - name, TREE_TYPE (value)); - return error_mark_node; + return result; } /* A subroutine of cp_parser_userdef_numeric_literal to @@ -3955,26 +3950,28 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) decl = lookup_literal_operator (name, args); if (decl && decl != error_mark_node) { - result = finish_call_expr (decl, &args, false, true, tf_none); - if (result != error_mark_node) + result = finish_call_expr (decl, &args, false, true, + tf_warning_or_error); + + if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0) + { + warning_at (token->location, OPT_Woverflow, + "integer literal exceeds range of %qT type", + long_long_unsigned_type_node); + } + else { - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE && overflow > 0) + if (overflow > 0) warning_at (token->location, OPT_Woverflow, - "integer literal exceeds range of %qT type", - long_long_unsigned_type_node); - else - { - if (overflow > 0) - warning_at (token->location, OPT_Woverflow, - "floating literal exceeds range of %qT type", - long_double_type_node); - else if (overflow < 0) - warning_at (token->location, OPT_Woverflow, - "floating literal truncated to zero"); - } - release_tree_vector (args); - return result; + "floating literal exceeds range of %qT type", + long_double_type_node); + else if (overflow < 0) + warning_at (token->location, OPT_Woverflow, + "floating literal truncated to zero"); } + + release_tree_vector (args); + return result; } release_tree_vector (args); @@ -3986,12 +3983,10 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) decl = lookup_literal_operator (name, args); if (decl && decl != error_mark_node) { - result = finish_call_expr (decl, &args, false, true, tf_none); - if (result != error_mark_node) - { - release_tree_vector (args); - return result; - } + result = finish_call_expr (decl, &args, false, true, + tf_warning_or_error); + release_tree_vector (args); + return result; } release_tree_vector (args); @@ -4004,13 +3999,12 @@ cp_parser_userdef_numeric_literal (cp_parser *parser) { tree tmpl_args = make_char_string_pack (num_string); decl = lookup_template_function (decl, tmpl_args); - result = finish_call_expr (decl, &args, false, true, tf_none); - if (result != error_mark_node) - { - release_tree_vector (args); - return result; - } + result = finish_call_expr (decl, &args, false, true, + tf_warning_or_error); + release_tree_vector (args); + return result; } + release_tree_vector (args); error ("unable to find numeric literal operator %qD", name); @@ -4035,40 +4029,37 @@ cp_parser_userdef_string_literal (tree literal) tree decl, result; vec *args; - /* Look for a template function with typename parameter CharT - and parameter pack CharT... Call the function with - template parameter characters representing the string. */ + /* Build up a call to the user-defined operator. */ + /* Lookup the name we got back from the id-expression. */ args = make_tree_vector (); + vec_safe_push (args, value); + vec_safe_push (args, build_int_cst (size_type_node, len)); decl = lookup_literal_operator (name, args); + if (decl && decl != error_mark_node) { - tree tmpl_args = make_string_pack (value); - decl = lookup_template_function (decl, tmpl_args); - result = finish_call_expr (decl, &args, false, true, tf_none); - if (result != error_mark_node) - { - release_tree_vector (args); - return result; - } + result = finish_call_expr (decl, &args, false, true, + tf_warning_or_error); + release_tree_vector (args); + return result; } release_tree_vector (args); - /* Build up a call to the user-defined operator */ - /* Lookup the name we got back from the id-expression. */ + /* Look for a template function with typename parameter CharT + and parameter pack CharT... Call the function with + template parameter characters representing the string. */ args = make_tree_vector (); - vec_safe_push (args, value); - vec_safe_push (args, build_int_cst (size_type_node, len)); - decl = lookup_name (name); - if (!decl || decl == error_mark_node) + decl = lookup_literal_operator (name, args); + if (decl && decl != error_mark_node) { - error ("unable to find string literal operator %qD", name); + tree tmpl_args = make_string_pack (value); + decl = lookup_template_function (decl, tmpl_args); + result = finish_call_expr (decl, &args, false, true, + tf_warning_or_error); release_tree_vector (args); - return error_mark_node; + return result; } - result = finish_call_expr (decl, &args, false, true, tf_none); release_tree_vector (args); - if (result != error_mark_node) - return result; error ("unable to find string literal operator %qD with %qT, %qT arguments", name, TREE_TYPE (value), size_type_node); @@ -29835,6 +29826,7 @@ restart: { case MULT_EXPR: case TRUNC_DIV_EXPR: + case RDIV_EXPR: case PLUS_EXPR: case MINUS_EXPR: case LSHIFT_EXPR: diff --git a/contrib/gcc-5.0/gcc/cp/tree.c b/contrib/gcc-5.0/gcc/cp/tree.c index afb57a3a12..c51e42d2a4 100644 --- a/contrib/gcc-5.0/gcc/cp/tree.c +++ b/contrib/gcc-5.0/gcc/cp/tree.c @@ -3501,6 +3501,50 @@ static tree handle_abi_tag_attribute (tree* node, tree name, tree args, int flags, bool* no_add_attrs) { + for (tree arg = args; arg; arg = TREE_CHAIN (arg)) + { + tree elt = TREE_VALUE (arg); + if (TREE_CODE (elt) != STRING_CST + || (!same_type_ignoring_top_level_qualifiers_p + (strip_array_types (TREE_TYPE (elt)), + char_type_node))) + { + error ("arguments to the %qE attribute must be narrow string " + "literals", name); + goto fail; + } + const char *begin = TREE_STRING_POINTER (elt); + const char *end = begin + TREE_STRING_LENGTH (elt); + for (const char *p = begin; p != end; ++p) + { + char c = *p; + if (p == begin) + { + if (!ISALPHA (c) && c != '_') + { + error ("arguments to the %qE attribute must contain valid " + "identifiers", name); + inform (input_location, "%<%c%> is not a valid first " + "character for an identifier", c); + goto fail; + } + } + else if (p == end - 1) + gcc_assert (c == 0); + else + { + if (!ISALNUM (c) && c != '_') + { + error ("arguments to the %qE attribute must contain valid " + "identifiers", name); + inform (input_location, "%<%c%> is not a valid character " + "in an identifier", c); + goto fail; + } + } + } + } + if (TYPE_P (*node)) { if (!OVERLOAD_TYPE_P (*node)) diff --git a/contrib/gcc-5.0/gcc/cp/typeck.c b/contrib/gcc-5.0/gcc/cp/typeck.c index 32ee78ec30..4c128b7ebe 100644 --- a/contrib/gcc-5.0/gcc/cp/typeck.c +++ b/contrib/gcc-5.0/gcc/cp/typeck.c @@ -4415,7 +4415,8 @@ cp_build_binary_op (location_t location, && decl_with_nonnull_addr_p (TREE_OPERAND (op0, 0))) { if ((complain & tf_warning) - && c_inhibit_evaluation_warnings == 0) + && c_inhibit_evaluation_warnings == 0 + && !TREE_NO_WARNING (op0)) warning (OPT_Waddress, "the address of %qD will never be NULL", TREE_OPERAND (op0, 0)); } @@ -4436,7 +4437,8 @@ cp_build_binary_op (location_t location, && decl_with_nonnull_addr_p (TREE_OPERAND (op1, 0))) { if ((complain & tf_warning) - && c_inhibit_evaluation_warnings == 0) + && c_inhibit_evaluation_warnings == 0 + && !TREE_NO_WARNING (op1)) warning (OPT_Waddress, "the address of %qD will never be NULL", TREE_OPERAND (op1, 0)); } @@ -4537,6 +4539,9 @@ cp_build_binary_op (location_t location, op1 = save_expr (op1); pfn0 = pfn_from_ptrmemfunc (op0); + /* Avoid -Waddress warnings (c++/64877). */ + if (TREE_CODE (pfn0) == ADDR_EXPR) + TREE_NO_WARNING (pfn0) = 1; pfn1 = pfn_from_ptrmemfunc (op1); delta0 = delta_from_ptrmemfunc (op0); delta1 = delta_from_ptrmemfunc (op1); diff --git a/contrib/gcc-5.0/gcc/cse.c b/contrib/gcc-5.0/gcc/cse.c index 7edd901189..2a33827a61 100644 --- a/contrib/gcc-5.0/gcc/cse.c +++ b/contrib/gcc-5.0/gcc/cse.c @@ -1984,6 +1984,22 @@ invalidate (rtx x, machine_mode full_mode) gcc_unreachable (); } } + +/* Invalidate DEST. Used when DEST is not going to be added + into the hash table for some reason, e.g. do_not_record + flagged on it. */ + +static void +invalidate_dest (rtx dest) +{ + if (REG_P (dest) + || GET_CODE (dest) == SUBREG + || MEM_P (dest)) + invalidate (dest, VOIDmode); + else if (GET_CODE (dest) == STRICT_LOW_PART + || GET_CODE (dest) == ZERO_EXTRACT) + invalidate (XEXP (dest, 0), GET_MODE (dest)); +} /* Remove all expressions that refer to register REGNO, since they are already invalid, and we are about to @@ -5510,18 +5526,20 @@ cse_insn (rtx_insn *insn) else if (do_not_record) { - if (REG_P (dest) || GET_CODE (dest) == SUBREG) - invalidate (dest, VOIDmode); - else if (MEM_P (dest)) - invalidate (dest, VOIDmode); - else if (GET_CODE (dest) == STRICT_LOW_PART - || GET_CODE (dest) == ZERO_EXTRACT) - invalidate (XEXP (dest, 0), GET_MODE (dest)); + invalidate_dest (dest); sets[i].rtl = 0; } if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl)) - sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode); + { + do_not_record = 0; + sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode); + if (do_not_record) + { + invalidate_dest (SET_DEST (sets[i].rtl)); + sets[i].rtl = 0; + } + } #ifdef HAVE_cc0 /* If setting CC0, record what it was set to, or a constant, if it diff --git a/contrib/gcc-5.0/gcc/dbxout.c b/contrib/gcc-5.0/gcc/dbxout.c index c756f2e3db..758c1c439f 100644 --- a/contrib/gcc-5.0/gcc/dbxout.c +++ b/contrib/gcc-5.0/gcc/dbxout.c @@ -967,7 +967,7 @@ get_lang_number (void) return N_SO_CC; else if (strcmp (language_string, "GNU F77") == 0) return N_SO_FORTRAN; - else if (strcmp (language_string, "GNU Fortran") == 0) + else if (lang_GNU_Fortran ()) return N_SO_FORTRAN90; /* CHECKME */ else if (strcmp (language_string, "GNU Pascal") == 0) return N_SO_PASCAL; diff --git a/contrib/gcc-5.0/gcc/doc/extend.texi b/contrib/gcc-5.0/gcc/doc/extend.texi index 18068508d0..b06661ef7c 100644 --- a/contrib/gcc-5.0/gcc/doc/extend.texi +++ b/contrib/gcc-5.0/gcc/doc/extend.texi @@ -3396,10 +3396,10 @@ This attribute is available on the ARM, AVR, MCORE, MSP430, NDS32, RL78, RX and SPU ports. It allows the compiler to construct the requisite function declaration, while allowing the body of the function to be assembly code. The specified function will not have -prologue/epilogue sequences generated by the compiler. Only Basic +prologue/epilogue sequences generated by the compiler. Only basic @code{asm} statements can safely be included in naked functions -(@pxref{Basic Asm}). While using Extended @code{asm} or a mixture of -Basic @code{asm} and ``C'' code may appear to work, they cannot be +(@pxref{Basic Asm}). While using extended @code{asm} or a mixture of +basic @code{asm} and C code may appear to work, they cannot be depended upon to work reliably and are not supported. @item near @@ -6382,12 +6382,25 @@ access hardware. @node Using Assembly Language with C @section How to Use Inline Assembly Language in C Code - -GCC provides various extensions that allow you to embed assembler within -C code. +@cindex @code{asm} keyword +@cindex assembly language in C +@cindex inline assembly language +@cindex mixing assembly language and C + +The @code{asm} keyword allows you to embed assembler instructions +within C code. GCC provides two forms of inline @code{asm} +statements. A @dfn{basic @code{asm}} statement is one with no +operands (@pxref{Basic Asm}), while an @dfn{extended @code{asm}} +statement (@pxref{Extended Asm}) includes one or more operands. +The extended form is preferred for mixing C and assembly language +within a function, but to include assembly language at +top level you must use basic @code{asm}. + +You can also use the @code{asm} keyword to override the assembler name +for a C symbol, or to place a C variable in a specific register. @menu -* Basic Asm:: Inline assembler with no operands. +* Basic Asm:: Inline assembler without operands. * Extended Asm:: Inline assembler with operands. * Constraints:: Constraints for @code{asm} operands * Asm Labels:: Specifying the assembler name to use for a C symbol. @@ -6396,92 +6409,105 @@ C code. @end menu @node Basic Asm -@subsection Basic Asm --- Assembler Instructions with No Operands +@subsection Basic Asm --- Assembler Instructions Without Operands @cindex basic @code{asm} +@cindex assembly language in C, basic -The @code{asm} keyword allows you to embed assembler instructions within -C code. +A basic @code{asm} statement has the following syntax: @example -asm [ volatile ] ( AssemblerInstructions ) +asm @r{[} volatile @r{]} ( @var{AssemblerInstructions} ) @end example -To create headers compatible with ISO C, write @code{__asm__} instead of +The @code{asm} keyword is a GNU extension. +When writing code that can be compiled with @option{-ansi} and the +various @option{-std} options, use @code{__asm__} instead of @code{asm} (@pxref{Alternate Keywords}). -By definition, a Basic @code{asm} statement is one with no operands. -@code{asm} statements that contain one or more colons (used to delineate -operands) are considered to be Extended (for example, @code{asm("int $3")} -is Basic, and @code{asm("int $3" : )} is Extended). @xref{Extended Asm}. - @subsubheading Qualifiers -@emph{volatile} -@* -This optional qualifier has no effect. All Basic @code{asm} blocks are -implicitly volatile. +@table @code +@item volatile +The optional @code{volatile} qualifier has no effect. +All basic @code{asm} blocks are implicitly volatile. +@end table @subsubheading Parameters -@emph{AssemblerInstructions} -@* +@table @var + +@item AssemblerInstructions This is a literal string that specifies the assembler code. The string can contain any instructions recognized by the assembler, including directives. GCC does not parse the assembler instructions themselves and does not know what they mean or even whether they are valid assembler input. -The compiler copies it verbatim to the assembly language output file, without -processing dialects or any of the "%" operators that are available with -Extended @code{asm}. This results in minor differences between Basic -@code{asm} strings and Extended @code{asm} templates. For example, to refer to -registers you might use %%eax in Extended @code{asm} and %eax in Basic -@code{asm}. You may place multiple assembler instructions together in a single @code{asm} string, separated by the characters normally used in assembly code for the system. A combination that works in most places is a newline to break the -line, plus a tab character (written as "\n\t"). +line, plus a tab character (written as @samp{\n\t}). Some assemblers allow semicolons as a line separator. However, note that some assembler dialects use semicolons to start a comment. +@end table + +@subsubheading Remarks +Using extended @code{asm} typically produces smaller, safer, and more +efficient code, and in most cases it is a better solution than basic +@code{asm}. However, there are two situations where only basic @code{asm} +can be used: + +@itemize @bullet +@item +Extended @code{asm} statements have to be inside a C +function, so to write inline assembly language at file scope (``top-level''), +outside of C functions, you must use basic @code{asm}. +You can use this technique to emit assembler directives, +define assembly language macros that can be invoked elsewhere in the file, +or write entire functions in assembly language. + +@item +Functions declared +with the @code{naked} attribute also require basic @code{asm} +(@pxref{Function Attributes}). +@end itemize + +Safely accessing C data and calling functions from basic @code{asm} is more +complex than it may appear. To access C data, it is better to use extended +@code{asm}. Do not expect a sequence of @code{asm} statements to remain perfectly consecutive after compilation. If certain instructions need to remain -consecutive in the output, put them in a single multi-instruction asm +consecutive in the output, put them in a single multi-instruction @code{asm} statement. Note that GCC's optimizers can move @code{asm} statements relative to other code, including across jumps. @code{asm} statements may not perform jumps into other @code{asm} statements. GCC does not know about these jumps, and therefore cannot take account of them when deciding how to optimize. Jumps from @code{asm} to C -labels are only supported in Extended @code{asm}. - -@subsubheading Remarks -Using Extended @code{asm} will typically produce smaller, safer, and more -efficient code, and in most cases it is a better solution. When writing -inline assembly language outside of C functions, however, you must use Basic -@code{asm}. Extended @code{asm} statements have to be inside a C function. -Functions declared with the @code{naked} attribute also require Basic -@code{asm} (@pxref{Function Attributes}). +labels are only supported in extended @code{asm}. Under certain circumstances, GCC may duplicate (or remove duplicates of) your assembly code when optimizing. This can lead to unexpected duplicate symbol errors during compilation if your assembly code defines symbols or labels. -Safely accessing C data and calling functions from Basic @code{asm} is more -complex than it may appear. To access C data, it is better to use Extended -@code{asm}. - -Since GCC does not parse the AssemblerInstructions, it has no +Since GCC does not parse the @var{AssemblerInstructions}, it has no visibility of any symbols it references. This may result in GCC discarding those symbols as unreferenced. -Unlike Extended @code{asm}, all Basic @code{asm} blocks are implicitly -volatile. @xref{Volatile}. Similarly, Basic @code{asm} blocks are not treated -as though they used a "memory" clobber (@pxref{Clobbers}). - -All Basic @code{asm} blocks use the assembler dialect specified by the -@option{-masm} command-line option. Basic @code{asm} provides no +The compiler copies the assembler instructions in a basic @code{asm} +verbatim to the assembly language output file, without +processing dialects or any of the @samp{%} operators that are available with +extended @code{asm}. This results in minor differences between basic +@code{asm} strings and extended @code{asm} templates. For example, to refer to +registers you might use @samp{%eax} in basic @code{asm} and +@samp{%%eax} in extended @code{asm}. + +On targets such as x86 that support multiple assembler dialects, +all basic @code{asm} blocks use the assembler dialect specified by the +@option{-masm} command-line option (@pxref{x86 Options}). +Basic @code{asm} provides no mechanism to provide different assembler strings for different dialects. -Here is an example of Basic @code{asm} for i386: +Here is an example of basic @code{asm} for i386: @example /* Note that this code will not compile with -masm=intel */ @@ -6490,95 +6516,90 @@ Here is an example of Basic @code{asm} for i386: @node Extended Asm @subsection Extended Asm - Assembler Instructions with C Expression Operands -@cindex @code{asm} keyword @cindex extended @code{asm} -@cindex assembler instructions +@cindex assembly language in C, extended -The @code{asm} keyword allows you to embed assembler instructions within C -code. With Extended @code{asm} you can read and write C variables from -assembler and perform jumps from assembler code to C labels. +With extended @code{asm} you can read and write C variables from +assembler and perform jumps from assembler code to C labels. +Extended @code{asm} syntax uses colons (@samp{:}) to delimit +the operand parameters after the assembler template: @example -@ifhtml -asm [volatile] ( AssemblerTemplate : [OutputOperands] [ : [InputOperands] [ : [Clobbers] ] ] ) - -asm [volatile] goto ( AssemblerTemplate : : [InputOperands] : [Clobbers] : GotoLabels ) -@end ifhtml -@ifnothtml -asm [volatile] ( AssemblerTemplate - : [OutputOperands] - [ : [InputOperands] - [ : [Clobbers] ] ]) - -asm [volatile] goto ( AssemblerTemplate +asm @r{[}volatile@r{]} ( @var{AssemblerTemplate} + : @var{OutputOperands} + @r{[} : @var{InputOperands} + @r{[} : @var{Clobbers} @r{]} @r{]}) + +asm @r{[}volatile@r{]} goto ( @var{AssemblerTemplate} : - : [InputOperands] - : [Clobbers] - : GotoLabels) -@end ifnothtml + : @var{InputOperands} + : @var{Clobbers} + : @var{GotoLabels}) @end example -To create headers compatible with ISO C, write @code{__asm__} instead of -@code{asm} and @code{__volatile__} instead of @code{volatile} -(@pxref{Alternate Keywords}). There is no alternate for @code{goto}. - -By definition, Extended @code{asm} is an @code{asm} statement that contains -operands. To separate the classes of operands, you use colons. Basic -@code{asm} statements contain no colons. (So, for example, -@code{asm("int $3")} is Basic @code{asm}, and @code{asm("int $3" : )} is -Extended @code{asm}. @pxref{Basic Asm}.) +The @code{asm} keyword is a GNU extension. +When writing code that can be compiled with @option{-ansi} and the +various @option{-std} options, use @code{__asm__} instead of +@code{asm} (@pxref{Alternate Keywords}). @subsubheading Qualifiers -@emph{volatile} -@* -The typical use of Extended @code{asm} statements is to manipulate input +@table @code + +@item volatile +The typical use of extended @code{asm} statements is to manipulate input values to produce output values. However, your @code{asm} statements may also produce side effects. If so, you may need to use the @code{volatile} qualifier to disable certain optimizations. @xref{Volatile}. -@emph{goto} -@* +@item goto This qualifier informs the compiler that the @code{asm} statement may -perform a jump to one of the labels listed in the GotoLabels section. +perform a jump to one of the labels listed in the @var{GotoLabels}. @xref{GotoLabels}. +@end table @subsubheading Parameters -@emph{AssemblerTemplate} -@* -This is a literal string that contains the assembler code. It is a +@table @var +@item AssemblerTemplate +This is a literal string that is the template for the assembler code. It is a combination of fixed text and tokens that refer to the input, output, and goto parameters. @xref{AssemblerTemplate}. -@emph{OutputOperands} -@* +@item OutputOperands A comma-separated list of the C variables modified by the instructions in the -AssemblerTemplate. @xref{OutputOperands}. +@var{AssemblerTemplate}. An empty list is permitted. @xref{OutputOperands}. -@emph{InputOperands} -@* +@item InputOperands A comma-separated list of C expressions read by the instructions in the -AssemblerTemplate. @xref{InputOperands}. +@var{AssemblerTemplate}. An empty list is permitted. @xref{InputOperands}. -@emph{Clobbers} -@* +@item Clobbers A comma-separated list of registers or other values changed by the -AssemblerTemplate, beyond those listed as outputs. @xref{Clobbers}. +@var{AssemblerTemplate}, beyond those listed as outputs. +An empty list is permitted. @xref{Clobbers}. -@emph{GotoLabels} -@* +@item GotoLabels When you are using the @code{goto} form of @code{asm}, this section contains -the list of all C labels to which the AssemblerTemplate may jump. +the list of all C labels to which the code in the +@var{AssemblerTemplate} may jump. @xref{GotoLabels}. +@code{asm} statements may not perform jumps into other @code{asm} statements, +only to the listed @var{GotoLabels}. +GCC's optimizers do not know about other jumps; therefore they cannot take +account of them when deciding how to optimize. +@end table + +The total number of input + output + goto operands is limited to 30. + @subsubheading Remarks The @code{asm} statement allows you to include assembly instructions directly within C code. This may help you to maximize performance in time-sensitive code or to access assembly instructions that are not readily available to C programs. -Note that Extended @code{asm} statements must be inside a function. Only -Basic @code{asm} may be outside functions (@pxref{Basic Asm}). -Functions declared with the @code{naked} attribute also require Basic +Note that extended @code{asm} statements must be inside a function. Only +basic @code{asm} may be outside functions (@pxref{Basic Asm}). +Functions declared with the @code{naked} attribute also require basic @code{asm} (@pxref{Function Attributes}). While the uses of @code{asm} are many and varied, it may help to think of an @@ -6598,7 +6619,7 @@ asm ("mov %1, %0\n\t" printf("%d\n", dst); @end example -This code will copy @var{src} to @var{dst} and add 1 to @var{dst}. +This code copies @code{src} to @code{dst} and add 1 to @code{dst}. @anchor{Volatile} @subsubsection Volatile @@ -6610,13 +6631,12 @@ there is no need for the output variables. Also, the optimizers may move code out of loops if they believe that the code will always return the same result (i.e. none of its input values change between calls). Using the @code{volatile} qualifier disables these optimizations. @code{asm} statements -that have no output operands are implicitly volatile. - -Examples: +that have no output operands, including @code{asm goto} statements, +are implicitly volatile. This i386 code demonstrates a case that does not use (or require) the @code{volatile} qualifier. If it is performing assertion checking, this code -uses @code{asm} to perform the validation. Otherwise, @var{dwRes} is +uses @code{asm} to perform the validation. Otherwise, @code{dwRes} is unreferenced by any code. As a result, the optimizers can discard the @code{asm} statement, which in turn removes the need for the entire @code{DoCheck} routine. By omitting the @code{volatile} qualifier when it @@ -6639,7 +6659,7 @@ void DoCheck(uint32_t dwSomeValue) @end example The next example shows a case where the optimizers can recognize that the input -(@var{dwSomeValue}) never changes during the execution of the function and can +(@code{dwSomeValue}) never changes during the execution of the function and can therefore move the @code{asm} outside the loop to produce more efficient code. Again, using @code{volatile} disables this type of optimization. @@ -6662,7 +6682,8 @@ void do_print(uint32_t dwSomeValue) @end example The following example demonstrates a case where you need to use the -@code{volatile} qualifier. It uses the x86 RDTSC instruction, which reads +@code{volatile} qualifier. +It uses the x86 @code{rdtsc} instruction, which reads the computer's time-stamp counter. Without the @code{volatile} qualifier, the optimizers might assume that the @code{asm} block will always return the same value and therefore optimize away the second call. @@ -6692,7 +6713,7 @@ asm volatile ( "rdtsc\n\t" // Returns the time in EDX:EAX. printf("msr: %llx\n", msr); @end example -GCC's optimizers will not treat this code like the non-volatile code in the +GCC's optimizers do not treat this code like the non-volatile code in the earlier examples. They do not move it out of loops or omit it on the assumption that the result from a previous call is still valid. @@ -6700,7 +6721,7 @@ Note that the compiler can move even volatile @code{asm} instructions relative to other code, including across jump instructions. For example, on many targets there is a system register that controls the rounding mode of floating-point operations. Setting it with a volatile @code{asm}, as in the -following PowerPC example, will not work reliably. +following PowerPC example, does not work reliably. @example asm volatile("mtfsf 255, %0" : : "f" (fpenv)); @@ -6718,16 +6739,18 @@ sum = x + y; Under certain circumstances, GCC may duplicate (or remove duplicates of) your assembly code when optimizing. This can lead to unexpected duplicate symbol -errors during compilation if your asm code defines symbols or labels. Using %= +errors during compilation if your asm code defines symbols or labels. +Using @samp{%=} (@pxref{AssemblerTemplate}) may help resolve this problem. @anchor{AssemblerTemplate} @subsubsection Assembler Template @cindex @code{asm} assembler template -An assembler template is a literal string containing assembler instructions. -The compiler will replace any references to inputs, outputs, and goto labels -in the template, and then output the resulting string to the assembler. The +An assembler template is a literal string containing assembler instructions. +The compiler replaces tokens in the template that refer +to inputs, outputs, and goto labels, +and then outputs the resulting string to the assembler. The string can contain any instructions recognized by the assembler, including directives. GCC does not parse the assembler instructions themselves and does not know what they mean or even whether they are valid @@ -6738,7 +6761,8 @@ You may place multiple assembler instructions together in a single @code{asm} string, separated by the characters normally used in assembly code for the system. A combination that works in most places is a newline to break the line, plus a tab character to move to the instruction field (written as -"\n\t"). Some assemblers allow semicolons as a line separator. However, note +@samp{\n\t}). +Some assemblers allow semicolons as a line separator. However, note that some assembler dialects use semicolons to start a comment. Do not expect a sequence of @code{asm} statements to remain perfectly @@ -6751,20 +6775,44 @@ by using global symbols directly from the assembler template) may not work as expected. Similarly, calling functions directly from an assembler template requires a detailed understanding of the target assembler and ABI. -Since GCC does not parse the AssemblerTemplate, it has no visibility of any +Since GCC does not parse the assembler template, +it has no visibility of any symbols it references. This may result in GCC discarding those symbols as unreferenced unless they are also listed as input, output, or goto operands. -GCC can support multiple assembler dialects (for example, GCC for x86 -supports "att" and "intel" dialects) for inline assembler. In builds that -support this capability, the @option{-masm} option controls which dialect -GCC uses as its default. The hardware-specific documentation for the +@subsubheading Special format strings + +In addition to the tokens described by the input, output, and goto operands, +these tokens have special meanings in the assembler template: + +@table @samp +@item %% +Outputs a single @samp{%} into the assembler code. + +@item %= +Outputs a number that is unique to each instance of the @code{asm} +statement in the entire compilation. This option is useful when creating local +labels and referring to them multiple times in a single template that +generates multiple assembler instructions. + +@item %@{ +@itemx %| +@itemx %@} +Outputs @samp{@{}, @samp{|}, and @samp{@}} characters (respectively) +into the assembler code. When unescaped, these characters have special +meaning to indicate multiple assembler dialects, as described below. +@end table + +@subsubheading Multiple assembler dialects in @code{asm} templates + +On targets such as x86, GCC supports multiple assembler dialects. +The @option{-masm} option controls which dialect GCC uses as its +default for inline assembler. The target-specific documentation for the @option{-masm} option contains the list of supported dialects, as well as the default dialect if the option is not specified. This information may be important to understand, since assembler code that works correctly when compiled using one dialect will likely fail if compiled using another. - -@subsubheading Using braces in @code{asm} templates +@xref{x86 Options}. If your code needs to support multiple assembler dialects (for example, if you are writing public headers that need to support a variety of compilation @@ -6774,23 +6822,26 @@ options), use constructs of this form: @{ dialect0 | dialect1 | dialect2... @} @end example -This construct outputs 'dialect0' when using dialect #0 to compile the code, -'dialect1' for dialect #1, etc. If there are fewer alternatives within the +This construct outputs @code{dialect0} +when using dialect #0 to compile the code, +@code{dialect1} for dialect #1, etc. If there are fewer alternatives within the braces than the number of dialects the compiler supports, the construct outputs nothing. -For example, if an x86 compiler supports two dialects (att, intel), an +For example, if an x86 compiler supports two dialects +(@samp{att}, @samp{intel}), an assembler template such as this: @example "bt@{l %[Offset],%[Base] | %[Base],%[Offset]@}; jc %l2" @end example -would produce the output: +@noindent +is equivalent to one of @example -For att: "btl %[Offset],%[Base] ; jc %l2" -For intel: "bt %[Base],%[Offset]; jc %l2" +"btl %[Offset],%[Base] ; jc %l2" @r{/* att dialect */} +"bt %[Base],%[Offset]; jc %l2" @r{/* intel dialect */} @end example Using that same compiler, this code: @@ -6799,33 +6850,15 @@ Using that same compiler, this code: "xchg@{l@}\t@{%%@}ebx, %1" @end example -would produce +@noindent +corresponds to either @example -For att: "xchgl\t%%ebx, %1" -For intel: "xchg\tebx, %1" +"xchgl\t%%ebx, %1" @r{/* att dialect */} +"xchg\tebx, %1" @r{/* intel dialect */} @end example -There is no support for nesting dialect alternatives. Also, there is no -``escape'' for an open brace (@{), so do not use open braces in an Extended -@code{asm} template other than as a dialect indicator. - -@subsubheading Other format strings - -In addition to the tokens described by the input, output, and goto operands, -there are a few special cases: - -@itemize -@item -"%%" outputs a single "%" into the assembler code. - -@item -"%=" outputs a number that is unique to each instance of the @code{asm} -statement in the entire compilation. This option is useful when creating local -labels and referring to them multiple times in a single template that -generates multiple assembler instructions. - -@end itemize +There is no support for nesting dialect alternatives. @anchor{OutputOperands} @subsubsection Output Operands @@ -6834,8 +6867,8 @@ generates multiple assembler instructions. An @code{asm} statement has zero or more output operands indicating the names of C variables modified by the assembler code. -In this i386 example, @var{old} (referred to in the template string as -@code{%0}) and @var{*Base} (as @code{%1}) are outputs and @var{Offset} +In this i386 example, @code{old} (referred to in the template string as +@code{%0}) and @code{*Base} (as @code{%1}) are outputs and @code{Offset} (@code{%2}) is an input: @example @@ -6850,53 +6883,57 @@ __asm__ ("btsl %2,%1\n\t" // Turn on zero-based bit #Offset in Base. return old; @end example -Operands use this format: +Operands are separated by commas. Each operand has this format: @example -[ [asmSymbolicName] ] "constraint" (cvariablename) +@r{[} [@var{asmSymbolicName}] @r{]} @var{constraint} (@var{cvariablename}) @end example -@emph{asmSymbolicName} -@* - -When not using asmSymbolicNames, use the (zero-based) position of the operand -in the list of operands in the assembler template. For example if there are -three output operands, use @code{%0} in the template to refer to the first, -@code{%1} for the second, and @code{%2} for the third. When using an -asmSymbolicName, reference it by enclosing the name in square brackets -(i.e. @code{%[Value]}). The scope of the name is the @code{asm} statement +@table @var +@item asmSymbolicName +Specifies a symbolic name for the operand. +Reference the name in the assembler template +by enclosing it in square brackets +(i.e. @samp{%[Value]}). The scope of the name is the @code{asm} statement that contains the definition. Any valid C variable name is acceptable, including names already defined in the surrounding code. No two operands within the same @code{asm} statement can use the same symbolic name. -@emph{constraint} -@* -Output constraints must begin with either @code{"="} (a variable overwriting an -existing value) or @code{"+"} (when reading and writing). When using -@code{"="}, do not assume the location will contain the existing value (except -when tying the variable to an input; @pxref{InputOperands,,Input Operands}). +When not using an @var{asmSymbolicName}, use the (zero-based) position +of the operand +in the list of operands in the assembler template. For example if there are +three output operands, use @samp{%0} in the template to refer to the first, +@samp{%1} for the second, and @samp{%2} for the third. + +@item constraint +A string constant specifying constraints on the placement of the operand; +@xref{Constraints}, for details. + +Output constraints must begin with either @samp{=} (a variable overwriting an +existing value) or @samp{+} (when reading and writing). When using +@samp{=}, do not assume the location contains the existing value +on entry to the @code{asm}, except +when the operand is tied to an input; @pxref{InputOperands,,Input Operands}. After the prefix, there must be one or more additional constraints (@pxref{Constraints}) that describe where the value resides. Common -constraints include @code{"r"} for register and @code{"m"} for memory. -When you list more than one possible location (for example @code{"=rm"}), the -compiler chooses the most efficient one based on the current context. If you -list as many alternates as the @code{asm} statement allows, you will permit -the optimizers to produce the best possible code. If you must use a specific -register, but your Machine Constraints do not provide sufficient -control to select the specific register you want, Local Reg Vars may provide -a solution (@pxref{Local Reg Vars}). - -@emph{cvariablename} -@* -Specifies the C variable name of the output (enclosed by parentheses). Accepts -any (non-constant) variable within scope. - -Remarks: - -The total number of input + output + goto operands has a limit of 30. Commas -separate the operands. When the compiler selects the registers to use to -represent the output operands, it will not use any of the clobbered registers +constraints include @samp{r} for register and @samp{m} for memory. +When you list more than one possible location (for example, @code{"=rm"}), +the compiler chooses the most efficient one based on the current context. +If you list as many alternates as the @code{asm} statement allows, you permit +the optimizers to produce the best possible code. +If you must use a specific register, but your Machine Constraints do not +provide sufficient control to select the specific register you want, +local register variables may provide a solution (@pxref{Local Reg Vars}). + +@item cvariablename +Specifies a C lvalue expression to hold the output, typically a variable name. +The enclosing parentheses are a required part of the syntax. + +@end table + +When the compiler selects the registers to use to +represent the output operands, it does not use any of the clobbered registers (@pxref{Clobbers}). Output operand expressions must be lvalues. The compiler cannot check whether @@ -6906,12 +6943,16 @@ example a bit-field), the constraint must allow a register. In that case, GCC uses the register as the output of the @code{asm}, and then stores that register into the output. -Unless an output operand has the '@code{&}' constraint modifier -(@pxref{Modifiers}), GCC may allocate it in the same register as an unrelated -input operand, on the assumption that the assembler code will consume its +Operands using the @samp{+} constraint modifier count as two operands +(that is, both as input and output) towards the total maximum of 30 operands +per @code{asm} statement. + +Use the @samp{&} constraint modifier (@pxref{Modifiers}) on all output +operands that must not overlap an input. Otherwise, +GCC may allocate the output operand in the same register as an unrelated +input operand, on the assumption that the assembler code consumes its inputs before producing outputs. This assumption may be false if the assembler -code actually consists of more than one instruction. In this case, use -'@code{&}' on each output operand that must not overlap an input. +code actually consists of more than one instruction. The same problem can occur if one output parameter (@var{a}) allows a register constraint and another output parameter (@var{b}) allows a memory constraint. @@ -6920,13 +6961,13 @@ registers which @emph{might} be shared by @var{a}, and GCC considers those registers to be inputs to the asm. As above, GCC assumes that such input registers are consumed before any outputs are written. This assumption may result in incorrect behavior if the asm writes to @var{a} before using -@var{b}. Combining the `@code{&}' constraint with the register constraint -ensures that modifying @var{a} will not affect what address is referenced by -@var{b}. Omitting the `@code{&}' constraint means that the location of @var{b} -will be undefined if @var{a} is modified before using @var{b}. +@var{b}. Combining the @samp{&} modifier with the register constraint on @var{a} +ensures that modifying @var{a} does not affect the address referenced by +@var{b}. Otherwise, the location of @var{b} +is undefined if @var{a} is modified before using @var{b}. -@code{asm} supports operand modifiers on operands (for example @code{%k2} -instead of simply @code{%2}). Typically these qualifiers are hardware +@code{asm} supports operand modifiers on operands (for example @samp{%k2} +instead of simply @samp{%2}). Typically these qualifiers are hardware dependent. The list of supported modifiers for x86 is found at @ref{x86Operandmodifiers,x86 Operand modifiers}. @@ -6935,13 +6976,11 @@ operands, use @code{volatile} for the @code{asm} statement to prevent the optimizers from discarding the @code{asm} statement as unneeded (see @ref{Volatile}). -Examples: - -This code makes no use of the optional asmSymbolicName. Therefore it +This code makes no use of the optional @var{asmSymbolicName}. Therefore it references the first output operand as @code{%0} (were there a second, it would be @code{%1}, etc). The number of the first input operand is one greater than that of the last output operand. In this i386 example, that makes -@var{Mask} @code{%1}: +@code{Mask} referenced as @code{%1}: @example uint32_t Mask = 1234; @@ -6953,17 +6992,21 @@ uint32_t Index; : "cc"); @end example -That code overwrites the variable Index ("="), placing the value in a register -("r"). The generic "r" constraint instead of a constraint for a specific +That code overwrites the variable @code{Index} (@samp{=}), +placing the value in a register (@samp{r}). +Using the generic @samp{r} constraint instead of a constraint for a specific register allows the compiler to pick the register to use, which can result in more efficient code. This may not be possible if an assembler instruction requires a specific register. -The following i386 example uses the asmSymbolicName operand. It produces the +The following i386 example uses the @var{asmSymbolicName} syntax. +It produces the same result as the code above, but some may consider it more readable or more maintainable since reordering index numbers is not necessary when adding or -removing operands. The names aIndex and aMask are only used to emphasize which -names get used where. It is acceptable to reuse the names Index and Mask. +removing operands. The names @code{aIndex} and @code{aMask} +are only used in this example to emphasize which +names get used where. +It is acceptable to reuse the names @code{Index} and @code{Mask}. @example uint32_t Mask = 1234; @@ -6987,61 +7030,68 @@ asm ("mov %[e], %[d]" : [e] "rm" (*e)); @end example -Here, @var{d} may either be in a register or in memory. Since the compiler -might already have the current value of the uint32_t pointed to by @var{e} +Here, @code{d} may either be in a register or in memory. Since the compiler +might already have the current value of the @code{uint32_t} location +pointed to by @code{e} in a register, you can enable it to choose the best location -for @var{d} by specifying both constraints. +for @code{d} by specifying both constraints. @anchor{InputOperands} @subsubsection Input Operands @cindex @code{asm} input operands @cindex @code{asm} expressions -Input operands make inputs from C variables and expressions available to the +Input operands make values from C variables and expressions available to the assembly code. -Specify input operands by using the format: +Operands are separated by commas. Each operand has this format: @example -[ [asmSymbolicName] ] "constraint" (cexpression) +@r{[} [@var{asmSymbolicName}] @r{]} @var{constraint} (@var{cexpression}) @end example -@emph{asmSymbolicName} -@* -When not using asmSymbolicNames, use the (zero-based) position of the operand -in the list of operands, including outputs, in the assembler template. For -example, if there are two output parameters and three inputs, @code{%2} refers -to the first input, @code{%3} to the second, and @code{%4} to the third. -When using an asmSymbolicName, reference it by enclosing the name in square -brackets (e.g. @code{%[Value]}). The scope of the name is the @code{asm} -statement that contains the definition. Any valid C variable name is -acceptable, including names already defined in the surrounding code. No two -operands within the same @code{asm} statement can use the same symbolic name. - -@emph{constraint} -@* -Input constraints must be a string containing one or more constraints -(@pxref{Constraints}). When you give more than one possible constraint -(for example, @code{"irm"}), the compiler will choose the most efficient -method based on the current context. Input constraints may not begin with -either "=" or "+". If you must use a specific register, but your Machine -Constraints do not provide sufficient control to select the specific -register you want, Local Reg Vars may provide a solution -(@pxref{Local Reg Vars}). +@table @var +@item asmSymbolicName +Specifies a symbolic name for the operand. +Reference the name in the assembler template +by enclosing it in square brackets +(i.e. @samp{%[Value]}). The scope of the name is the @code{asm} statement +that contains the definition. Any valid C variable name is acceptable, +including names already defined in the surrounding code. No two operands +within the same @code{asm} statement can use the same symbolic name. + +When not using an @var{asmSymbolicName}, use the (zero-based) position +of the operand +in the list of operands in the assembler template. For example if there are +two output operands and three inputs, +use @samp{%2} in the template to refer to the first input operand, +@samp{%3} for the second, and @samp{%4} for the third. + +@item constraint +A string constant specifying constraints on the placement of the operand; +@xref{Constraints}, for details. + +Input constraint strings may not begin with either @samp{=} or @samp{+}. +When you list more than one possible location (for example, @samp{"irm"}), +the compiler chooses the most efficient one based on the current context. +If you must use a specific register, but your Machine Constraints do not +provide sufficient control to select the specific register you want, +local register variables may provide a solution (@pxref{Local Reg Vars}). Input constraints can also be digits (for example, @code{"0"}). This indicates -that the specified input will be in the same place as the output constraint -at the (zero-based) index in the output constraint list. When using -asmSymbolicNames for the output operands, you may use these names (enclosed -in brackets []) instead of digits. +that the specified input must be in the same place as the output constraint +at the (zero-based) index in the output constraint list. +When using @var{asmSymbolicName} syntax for the output operands, +you may use these names (enclosed in brackets @samp{[]}) instead of digits. -@emph{cexpression} -@* +@item cexpression This is the C variable or expression being passed to the @code{asm} statement -as input. +as input. The enclosing parentheses are a required part of the syntax. + +@end table When the compiler selects the registers to use to represent the input -operands, it will not use any of the clobbered registers (@pxref{Clobbers}). +operands, it does not use any of the clobbered registers (@pxref{Clobbers}). If there are no output operands but there are input operands, place two consecutive colons where the output operands would go: @@ -7049,13 +7099,14 @@ consecutive colons where the output operands would go: @example __asm__ ("some instructions" : /* No outputs. */ - : "r" (Offset / 8); + : "r" (Offset / 8)); @end example @strong{Warning:} Do @emph{not} modify the contents of input-only operands (except for inputs tied to outputs). The compiler assumes that on exit from -the @code{asm} statement these operands will contain the same values as they -had before executing the assembler. It is @emph{not} possible to use Clobbers +the @code{asm} statement these operands contain the same values as they +had before executing the statement. +It is @emph{not} possible to use clobbers to inform the compiler that the values in these inputs are changing. One common work-around is to tie the changing input variable to an output variable that never gets used. Note, however, that if the code that follows the @@ -7063,23 +7114,17 @@ that never gets used. Note, however, that if the code that follows the optimizers may discard the @code{asm} statement as unneeded (see @ref{Volatile}). -Remarks: - -The total number of input + output + goto operands has a limit of 30. - -@code{asm} supports operand modifiers on operands (for example @code{%k2} -instead of simply @code{%2}). Typically these qualifiers are hardware +@code{asm} supports operand modifiers on operands (for example @samp{%k2} +instead of simply @samp{%2}). Typically these qualifiers are hardware dependent. The list of supported modifiers for x86 is found at @ref{x86Operandmodifiers,x86 Operand modifiers}. -Examples: - In this example using the fictitious @code{combine} instruction, the constraint @code{"0"} for input operand 1 says that it must occupy the same location as output operand 0. Only input operands may use numbers in constraints, and they must each refer to an output operand. Only a number (or the symbolic assembler name) in the constraint can guarantee that one operand -is in the same place as another. The mere fact that @var{foo} is the value of +is in the same place as another. The mere fact that @code{foo} is the value of both operands is not enough to guarantee that they are in the same place in the generated assembler code. @@ -7102,24 +7147,24 @@ asm ("cmoveq %1, %2, %[result]" @cindex @code{asm} clobbers While the compiler is aware of changes to entries listed in the output -operands, the assembler code may modify more than just the outputs. For +operands, the inline @code{asm} code may modify more than just the outputs. For example, calculations may require additional registers, or the processor may overwrite a register as a side effect of a particular assembler instruction. In order to inform the compiler of these changes, list them in the clobber list. Clobber list items are either register names or the special clobbers -(listed below). Each clobber list item is enclosed in double quotes and -separated by commas. +(listed below). Each clobber list item is a string constant +enclosed in double quotes and separated by commas. Clobber descriptions may not in any way overlap with an input or output operand. For example, you may not have an operand describing a register class with one member when listing that register in the clobber list. Variables -declared to live in specific registers (@pxref{Explicit Reg Vars}), and used -as @code{asm} input or output operands, must have no part mentioned in the +declared to live in specific registers (@pxref{Explicit Reg Vars}) and used +as @code{asm} input or output operands must have no part mentioned in the clobber description. In particular, there is no way to specify that input operands get modified without also specifying them as output operands. When the compiler selects which registers to use to represent input and output -operands, it will not use any of the clobbered registers. As a result, +operands, it does not use any of the clobbered registers. As a result, clobbered registers are available for any use in the assembler code. Here is a realistic example for the VAX showing the use of clobbered @@ -7134,68 +7179,78 @@ asm volatile ("movc3 %0, %1, %2" Also, there are two special clobber arguments: -@enumerate -@item +@table @code +@item "cc" The @code{"cc"} clobber indicates that the assembler code modifies the flags register. On some machines, GCC represents the condition codes as a specific -hardware register; "cc" serves to name this register. On other machines, -condition code handling is different, and specifying "cc" has no effect. But -it is valid no matter what the machine. - -@item -The "memory" clobber tells the compiler that the assembly code performs memory +hardware register; @code{"cc"} serves to name this register. +On other machines, condition code handling is different, +and specifying @code{"cc"} has no effect. But +it is valid no matter what the target. + +@item "memory" +The @code{"memory"} clobber tells the compiler that the assembly code +performs memory reads or writes to items other than those listed in the input and output -operands (for example accessing the memory pointed to by one of the input +operands (for example, accessing the memory pointed to by one of the input parameters). To ensure memory contains correct values, GCC may need to flush specific register values to memory before executing the @code{asm}. Further, -the compiler will not assume that any values read from memory before an -@code{asm} will remain unchanged after that @code{asm}; it will reload them as -needed. This effectively forms a read/write memory barrier for the compiler. +the compiler does not assume that any values read from memory before an +@code{asm} remain unchanged after that @code{asm}; it reloads them as +needed. +Using the @code{"memory"} clobber effectively forms a read/write +memory barrier for the compiler. Note that this clobber does not prevent the @emph{processor} from doing speculative reads past the @code{asm} statement. To prevent that, you need processor-specific fence instructions. Flushing registers to memory has performance implications and may be an issue -for time-sensitive code. One trick to avoid this is available if the size of +for time-sensitive code. You can use a trick to avoid this if the size of the memory being accessed is known at compile time. For example, if accessing ten bytes of a string, use a memory input like: @code{@{"m"( (@{ struct @{ char x[10]; @} *p = (void *)ptr ; *p; @}) )@}}. -@end enumerate +@end table @anchor{GotoLabels} @subsubsection Goto Labels @cindex @code{asm} goto labels -@code{asm goto} allows assembly code to jump to one or more C labels. The -GotoLabels section in an @code{asm goto} statement contains a comma-separated +@code{asm goto} allows assembly code to jump to one or more C labels. The +@var{GotoLabels} section in an @code{asm goto} statement contains +a comma-separated list of all C labels to which the assembler code may jump. GCC assumes that @code{asm} execution falls through to the next statement (if this is not the case, consider using the @code{__builtin_unreachable} intrinsic after the @code{asm} statement). Optimization of @code{asm goto} may be improved by using the @code{hot} and @code{cold} label attributes (@pxref{Label -Attributes}). The total number of input + output + goto operands has -a limit of 30. +Attributes}). -An @code{asm goto} statement can not have outputs (which means that the -statement is implicitly volatile). This is due to an internal restriction of -the compiler: control transfer instructions cannot have outputs. If the -assembler code does modify anything, use the "memory" clobber to force the -optimizers to flush all register values to memory, and reload them if -necessary, after the @code{asm} statement. +An @code{asm goto} statement cannot have outputs. +This is due to an internal restriction of +the compiler: control transfer instructions cannot have outputs. +If the assembler code does modify anything, use the @code{"memory"} clobber +to force the +optimizers to flush all register values to memory and reload them if +necessary after the @code{asm} statement. -To reference a label, prefix it with @code{%l} (that's a lowercase L) followed -by its (zero-based) position in GotoLabels plus the number of input -arguments. For example, if the @code{asm} has three inputs and references two -labels, refer to the first label as @code{%l3} and the second as @code{%l4}). +Also note that an @code{asm goto} statement is always implicitly +considered volatile. -@code{asm} statements may not perform jumps into other @code{asm} statements. -GCC's optimizers do not know about these jumps; therefore they cannot take -account of them when deciding how to optimize. +To reference a label in the assembler template, +prefix it with @samp{%l} (lowercase @samp{L}) followed +by its (zero-based) position in @var{GotoLabels} plus the number of input +operands. For example, if the @code{asm} has three inputs and references two +labels, refer to the first label as @samp{%l3} and the second as @samp{%l4}). + +Alternately, you can reference labels using the actual C label name enclosed +in brackets. For example, to reference a label named @code{carry}, you can +use @samp{%l[carry]}. The label must still be listed in the @var{GotoLabels} +section when using this approach. -Example code for i386 might look like: +Here is an example of @code{asm goto} for i386: @example asm goto ( @@ -7212,7 +7267,7 @@ carry: return 1; @end example -The following example shows an @code{asm goto} that uses the memory clobber. +The following example shows an @code{asm goto} that uses a memory clobber. @example int frob(int x) @@ -7230,17 +7285,20 @@ error: @end example @anchor{x86Operandmodifiers} -@subsubsection x86 Operand modifiers +@subsubsection x86 Operand Modifiers -Input, output, and goto operands for extended @code{asm} statements can use -modifiers to affect the code output to the assembler. For example, the -following code uses the "h" and "b" modifiers for x86: +References to input, output, and goto operands in the assembler template +of extended @code{asm} statements can use +modifiers to affect the way the operands are formatted in +the code output to the assembler. For example, the +following code uses the @samp{h} and @samp{b} modifiers for x86: @example uint16_t num; asm volatile ("xchg %h0, %b0" : "+a" (num) ); @end example +@noindent These modifiers generate this assembler code: @example @@ -7265,7 +7323,7 @@ top: @end example With no modifiers, this is what the output from the operands would be for the -att and intel dialects of assembler: +@samp{att} and @samp{intel} dialects of assembler: @multitable {Operand} {masm=att} {OFFSET FLAT:.L2} @headitem Operand @tab masm=att @tab masm=intel @@ -7327,7 +7385,7 @@ The table below shows the list of supported modifiers and their effects. @end multitable @anchor{x86floatingpointasmoperands} -@subsubsection x86 floating-point asm operands +@subsubsection x86 Floating-Point @code{asm} Operands On x86 targets, there are several rules on the usage of stack-like registers in the operands of an @code{asm}. These rules apply only to the operands @@ -7369,10 +7427,10 @@ reload may think that it can use the same register for both the input and the output. To prevent this from happening, -if any input operand uses the @code{f} constraint, all output register -constraints must use the @code{&} early-clobber modifier. +if any input operand uses the @samp{f} constraint, all output register +constraints must use the @samp{&} early-clobber modifier. -The example above would be correctly written as: +The example above is correctly written as: @smallexample asm ("foo" : "=&t" (a) : "f" (b)); @@ -7385,7 +7443,7 @@ know which registers the outputs appear in unless you indicate this in the constraints. Output operands must specifically indicate which register an output -appears in after an @code{asm}. @code{=f} is not allowed: the operand +appears in after an @code{asm}. @samp{=f} is not allowed: the operand constraints must select a class with a single register. @item @@ -7404,8 +7462,7 @@ unrelated to the inputs and outputs. @end enumerate -Here are a couple of reasonable @code{asm}s to want to write. This -@code{asm} +This @code{asm} takes one input, which is internally popped, and produces two outputs. @smallexample @@ -7529,8 +7586,8 @@ Here @code{a5} is the name of the register that should be used. Choose a register that is normally saved and restored by function calls on your machine, so that library routines will not clobber it. -Naturally the register name is cpu-dependent, so you need to -conditionalize your program according to cpu type. The register +Naturally the register name is CPU-dependent, so you need to +conditionalize your program according to CPU type. The register @code{a5} is a good choice on a 68000 for a variable of pointer type. On machines with register windows, be sure to choose a ``global'' register that is not affected magically by the function call mechanism. @@ -7628,13 +7685,13 @@ Here @code{a5} is the name of the register that should be used. Note that this is the same syntax used for defining global register variables, but for a local variable it appears within a function. -Naturally the register name is cpu-dependent, but this is not a +Naturally the register name is CPU-dependent, but this is not a problem, since specific registers are most often useful with explicit assembler instructions (@pxref{Extended Asm}). Both of these things generally require that you conditionalize your program according to -cpu type. +CPU type. -In addition, operating systems on one type of cpu may differ in how they +In addition, operating systems on one type of CPU may differ in how they name the registers; then you need additional conditionals. For example, some 68000 operating systems call this register @code{%a5}. @@ -7644,11 +7701,12 @@ the variable's value is not live. This option does not guarantee that GCC generates code that has this variable in the register you specify at all times. You may not -code an explicit reference to this register in the @emph{assembler -instruction template} part of an @code{asm} statement and assume it -always refers to this variable. However, using the variable as an -@code{asm} @emph{operand} guarantees that the specified register is used -for the operand. +code an explicit reference to this register in the assembler +instruction template part of an @code{asm} statement and assume it +always refers to this variable. +However, using the variable as an input or output operand to the @code{asm} +guarantees that the specified register is used for that operand. +@xref{Extended Asm}, for more information. Stores into local register variables may be deleted when they appear to be dead according to dataflow analysis. References to local register variables may @@ -17546,8 +17604,10 @@ adding a call to the @code{.init} section. @subsection Symbol-Renaming Pragmas GCC supports a @code{#pragma} directive that changes the name used in -assembly for a given declaration. This effect can also be achieved -using the asm labels extension (@pxref{Asm Labels}). +assembly for a given declaration. While this pragma is supported on all +platforms, it is intended primarily to provide compatibility with the +Solaris system headers. This effect can also be achieved using the asm +labels extension (@pxref{Asm Labels}). @table @code @item redefine_extname @var{oldname} @var{newname} @@ -17852,8 +17912,8 @@ versions earlier than 4.4. @end table With this pragma, the programmer asserts that there are no loop-carried -dependencies which would prevent that consecutive iterations of -the following loop can be executed concurrently with SIMD +dependencies which would prevent consecutive iterations of +the following loop from executing concurrently with SIMD (single instruction multiple data) instructions. For example, the compiler can only unconditionally vectorize the following diff --git a/contrib/gcc-5.0/gcc/doc/invoke.texi b/contrib/gcc-5.0/gcc/doc/invoke.texi index ba81ec7a7d..5cce4f7363 100644 --- a/contrib/gcc-5.0/gcc/doc/invoke.texi +++ b/contrib/gcc-5.0/gcc/doc/invoke.texi @@ -7090,6 +7090,8 @@ optimizing. Use of @option{-gdwarf-4} is recommended along with it. It can be enabled even if var-tracking is disabled, in which case annotations are created and maintained, but discarded at the end. +By default, this flag is enabled together with @option{-fvar-tracking}, +except when selective scheduling is enabled. @item -fvar-tracking-assignments-toggle @opindex fvar-tracking-assignments-toggle @@ -7886,6 +7888,16 @@ registers after writing to their lower 32-bit half. Enabled for Alpha, AArch64 and x86 at levels @option{-O2}, @option{-O3}, @option{-Os}. +@item -fno-lifetime-dse +@opindex fno-lifetime-dse +In C++ the value of an object is only affected by changes within its +lifetime: when the constructor begins, the object has an indeterminate +value, and any changes during the lifetime of the object are dead when +the object is destroyed. Normally dead store elimination will take +advantage of this; if your code relies on the value of the object +storage persisting beyond the lifetime of the object, you can use this +flag to disable this optimization. + @item -flive-range-shrinkage @opindex flive-range-shrinkage Attempt to decrease register pressure through register live range @@ -12098,12 +12110,12 @@ architecture. @opindex mtune Specify the name of the target processor for which GCC should tune the performance of the code. Permissible values for this option are: -@samp{generic}, @samp{cortex-a53}, @samp{cortex-a57}, @samp{thunderx}, -@samp{xgene1}. +@samp{generic}, @samp{cortex-a53}, @samp{cortex-a57}, +@samp{cortex-a72}, @samp{thunderx}, @samp{xgene1}. Additionally, this option can specify that GCC should tune the performance -of the code for a big.LITTLE system. The only permissible value is -@samp{cortex-a57.cortex-a53}. +of the code for a big.LITTLE system. Permissible values for this +option are: @samp{cortex-a57.cortex-a53}, @samp{cortex-a72.cortex-a53}. Where none of @option{-mtune=}, @option{-mcpu=} or @option{-march=} are specified, the code is tuned to perform well across a range @@ -12962,7 +12974,8 @@ Permissible names are: @samp{arm2}, @samp{arm250}, @samp{arm1136j-s}, @samp{arm1136jf-s}, @samp{mpcore}, @samp{mpcorenovfp}, @samp{arm1156t2-s}, @samp{arm1156t2f-s}, @samp{arm1176jz-s}, @samp{arm1176jzf-s}, @samp{cortex-a5}, @samp{cortex-a7}, @samp{cortex-a8}, @samp{cortex-a9}, -@samp{cortex-a12}, @samp{cortex-a15}, @samp{cortex-a53}, @samp{cortex-a57}, +@samp{cortex-a12}, @samp{cortex-a15}, @samp{cortex-a53}, +@samp{cortex-a57}, @samp{cortex-a72}, @samp{cortex-r4}, @samp{cortex-r4f}, @samp{cortex-r5}, @samp{cortex-r7}, @samp{cortex-m7}, @samp{cortex-m4}, @@ -12981,7 +12994,8 @@ Permissible names are: @samp{arm2}, @samp{arm250}, Additionally, this option can specify that GCC should tune the performance of the code for a big.LITTLE system. Permissible names are: -@samp{cortex-a15.cortex-a7}, @samp{cortex-a57.cortex-a53}. +@samp{cortex-a15.cortex-a7}, @samp{cortex-a57.cortex-a53}, +@samp{cortex-a72.cortex-a53}. @option{-mtune=generic-@var{arch}} specifies that GCC should tune the performance for a blend of processors within architecture @var{arch}. @@ -21942,8 +21956,10 @@ functional units well, resulting in unstable performance. @item -masm=@var{dialect} @opindex masm=@var{dialect} -Output assembly instructions using selected @var{dialect}. Supported -choices are @samp{intel} or @samp{att} (the default). Darwin does +Output assembly instructions using selected @var{dialect}. Also affects +which dialect is used for basic @code{asm} (@pxref{Basic Asm}) and +extended @code{asm} (@pxref{Extended Asm}). Supported choices (in dialect +order) are @samp{att} or @samp{intel}. The default is @samp{att}. Darwin does not support @samp{intel}. @item -mieee-fp diff --git a/contrib/gcc-5.0/gcc/doc/sourcebuild.texi b/contrib/gcc-5.0/gcc/doc/sourcebuild.texi index eef5081b99..58759178c2 100644 --- a/contrib/gcc-5.0/gcc/doc/sourcebuild.texi +++ b/contrib/gcc-5.0/gcc/doc/sourcebuild.texi @@ -1884,6 +1884,9 @@ Target uses natural alignment (aligned to type size) for types of @item nonpic Target does not generate PIC by default. +@item pie_enabled +Target generates PIE by default. + @item pcc_bitfield_type_matters Target defines @code{PCC_BITFIELD_TYPE_MATTERS}. diff --git a/contrib/gcc-5.0/gcc/doc/tm.texi b/contrib/gcc-5.0/gcc/doc/tm.texi index 9c81fdb98d..048a28a137 100644 --- a/contrib/gcc-5.0/gcc/doc/tm.texi +++ b/contrib/gcc-5.0/gcc/doc/tm.texi @@ -11107,17 +11107,6 @@ loops containing function calls or branch on table instructions. Take an instruction in @var{insn} and return @code{false} if the instruction is not appropriate as a combination of two or more instructions. The default is to accept all instructions. @end deftypefn -@defmac MD_CAN_REDIRECT_BRANCH (@var{branch1}, @var{branch2}) - -Take a branch insn in @var{branch1} and another in @var{branch2}. -Return true if redirecting @var{branch1} to the destination of -@var{branch2} is possible. - -On some targets, branches may have a limited range. Optimizing the -filling of delay slots can result in branches being redirected, and this -may in turn cause a branch offset to overflow. -@end defmac - @deftypefn {Target Hook} bool TARGET_CAN_FOLLOW_JUMP (const rtx_insn *@var{follower}, const rtx_insn *@var{followee}) FOLLOWER and FOLLOWEE are JUMP_INSN instructions; return true if FOLLOWER may be modified to follow FOLLOWEE; false, if it can't. For example, on some targets, certain kinds of branches can't be made to follow through a hot/cold partitioning. @end deftypefn diff --git a/contrib/gcc-5.0/gcc/dwarf2asm.c b/contrib/gcc-5.0/gcc/dwarf2asm.c index c5942b9027..b817aaf502 100644 --- a/contrib/gcc-5.0/gcc/dwarf2asm.c +++ b/contrib/gcc-5.0/gcc/dwarf2asm.c @@ -159,6 +159,7 @@ dw2_asm_output_delta (int size, const char *lab1, const char *lab2, va_end (ap); } +#ifdef ASM_OUTPUT_DWARF_VMS_DELTA /* Output the difference between two symbols in instruction units in a given size. */ @@ -171,11 +172,6 @@ dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED, va_start (ap, comment); -#ifndef ASM_OUTPUT_DWARF_VMS_DELTA - /* VMS Delta is only special on ia64-vms, but this function also gets - called on alpha-vms so it has to do something sane. */ - dw2_asm_output_delta (size, lab1, lab2, comment); -#else ASM_OUTPUT_DWARF_VMS_DELTA (asm_out_file, size, lab1, lab2); if (flag_debug_asm && comment) { @@ -183,10 +179,10 @@ dw2_asm_output_vms_delta (int size ATTRIBUTE_UNUSED, vfprintf (asm_out_file, comment, ap); } fputc ('\n', asm_out_file); -#endif va_end (ap); } +#endif /* Output a section-relative reference to a LABEL, which was placed in BASE. In general this can only be done for debugging symbols. diff --git a/contrib/gcc-5.0/gcc/dwarf2out.c b/contrib/gcc-5.0/gcc/dwarf2out.c index d9b8c42189..4492f8afc4 100644 --- a/contrib/gcc-5.0/gcc/dwarf2out.c +++ b/contrib/gcc-5.0/gcc/dwarf2out.c @@ -4736,7 +4736,9 @@ is_fortran (void) return (lang == DW_LANG_Fortran77 || lang == DW_LANG_Fortran90 - || lang == DW_LANG_Fortran95); + || lang == DW_LANG_Fortran95 + || lang == DW_LANG_Fortran03 + || lang == DW_LANG_Fortran08); } /* Return TRUE if the language is Ada. */ @@ -8895,14 +8897,14 @@ output_die (dw_die_ref die) for (i = len - 1; i >= 0; --i) { dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i), - name); + "%s", name); name = NULL; } else for (i = 0; i < len; ++i) { dw2_asm_output_data (l, a->dw_attr_val.v.val_wide->elt (i), - name); + "%s", name); name = NULL; } } @@ -9000,9 +9002,15 @@ output_die (dw_die_ref die) break; case dw_val_class_vms_delta: +#ifdef ASM_OUTPUT_DWARF_VMS_DELTA dw2_asm_output_vms_delta (DWARF_OFFSET_SIZE, AT_vms_delta2 (a), AT_vms_delta1 (a), "%s", name); +#else + dw2_asm_output_delta (DWARF_OFFSET_SIZE, + AT_vms_delta2 (a), AT_vms_delta1 (a), + "%s", name); +#endif break; case dw_val_class_lbl_id: @@ -16725,6 +16733,8 @@ lower_bound_default (void) case DW_LANG_Fortran77: case DW_LANG_Fortran90: case DW_LANG_Fortran95: + case DW_LANG_Fortran03: + case DW_LANG_Fortran08: return 1; case DW_LANG_UPC: case DW_LANG_D: @@ -18058,7 +18068,7 @@ gen_type_die_for_member (tree type, tree member, dw_die_ref context_die) /* Forward declare these functions, because they are mutually recursive with their set_block_* pairing functions. */ static void set_decl_origin_self (tree); -static void set_decl_abstract_flags (tree, int); +static void set_decl_abstract_flags (tree, vec &); /* Given a pointer to some BLOCK node, if the BLOCK_ABSTRACT_ORIGIN for the given BLOCK node is NULL, set the BLOCK_ABSTRACT_ORIGIN for the node so @@ -18131,59 +18141,72 @@ set_decl_origin_self (tree decl) } } -/* Given a pointer to some BLOCK node, and a boolean value to set the - "abstract" flags to, set that value into the BLOCK_ABSTRACT flag for - the given block, and for all local decls and all local sub-blocks - (recursively) which are contained therein. */ +/* Given a pointer to some BLOCK node, set the BLOCK_ABSTRACT flag to 1 + and if it wasn't 1 before, push it to abstract_vec vector. + For all local decls and all local sub-blocks (recursively) do it + too. */ static void -set_block_abstract_flags (tree stmt, int setting) +set_block_abstract_flags (tree stmt, vec &abstract_vec) { tree local_decl; tree subblock; unsigned int i; - BLOCK_ABSTRACT (stmt) = setting; + if (!BLOCK_ABSTRACT (stmt)) + { + abstract_vec.safe_push (stmt); + BLOCK_ABSTRACT (stmt) = 1; + } for (local_decl = BLOCK_VARS (stmt); local_decl != NULL_TREE; local_decl = DECL_CHAIN (local_decl)) if (! DECL_EXTERNAL (local_decl)) - set_decl_abstract_flags (local_decl, setting); + set_decl_abstract_flags (local_decl, abstract_vec); for (i = 0; i < BLOCK_NUM_NONLOCALIZED_VARS (stmt); i++) { local_decl = BLOCK_NONLOCALIZED_VAR (stmt, i); if ((TREE_CODE (local_decl) == VAR_DECL && !TREE_STATIC (local_decl)) || TREE_CODE (local_decl) == PARM_DECL) - set_decl_abstract_flags (local_decl, setting); + set_decl_abstract_flags (local_decl, abstract_vec); } for (subblock = BLOCK_SUBBLOCKS (stmt); subblock != NULL_TREE; subblock = BLOCK_CHAIN (subblock)) - set_block_abstract_flags (subblock, setting); + set_block_abstract_flags (subblock, abstract_vec); } -/* Given a pointer to some ..._DECL node, and a boolean value to set the - "abstract" flags to, set that value into the DECL_ABSTRACT_P flag for the - given decl, and (in the case where the decl is a FUNCTION_DECL) also - set the abstract flags for all of the parameters, local vars, local - blocks and sub-blocks (recursively) to the same setting. */ +/* Given a pointer to some ..._DECL node, set DECL_ABSTRACT_P flag on it + to 1 and if it wasn't 1 before, push to abstract_vec vector. + In the case where the decl is a FUNCTION_DECL also set the abstract + flags for all of the parameters, local vars, local + blocks and sub-blocks (recursively). */ static void -set_decl_abstract_flags (tree decl, int setting) +set_decl_abstract_flags (tree decl, vec &abstract_vec) { - DECL_ABSTRACT_P (decl) = setting; + if (!DECL_ABSTRACT_P (decl)) + { + abstract_vec.safe_push (decl); + DECL_ABSTRACT_P (decl) = 1; + } + if (TREE_CODE (decl) == FUNCTION_DECL) { tree arg; for (arg = DECL_ARGUMENTS (decl); arg; arg = DECL_CHAIN (arg)) - DECL_ABSTRACT_P (arg) = setting; + if (!DECL_ABSTRACT_P (arg)) + { + abstract_vec.safe_push (arg); + DECL_ABSTRACT_P (arg) = 1; + } if (DECL_INITIAL (decl) != NULL_TREE && DECL_INITIAL (decl) != error_mark_node) - set_block_abstract_flags (DECL_INITIAL (decl), setting); + set_block_abstract_flags (DECL_INITIAL (decl), abstract_vec); } } @@ -18196,7 +18219,6 @@ dwarf2out_abstract_function (tree decl) dw_die_ref old_die; tree save_fn; tree context; - int was_abstract; hash_table *old_decl_loc_table; hash_table *old_cached_dw_loc_list_table; int old_call_site_count, old_tail_call_site_count; @@ -18238,11 +18260,16 @@ dwarf2out_abstract_function (tree decl) save_fn = current_function_decl; current_function_decl = decl; - was_abstract = DECL_ABSTRACT_P (decl); - set_decl_abstract_flags (decl, 1); + auto_vec abstract_vec; + set_decl_abstract_flags (decl, abstract_vec); dwarf2out_decl (decl); - if (! was_abstract) - set_decl_abstract_flags (decl, 0); + unsigned int i; + tree t; + FOR_EACH_VEC_ELT (abstract_vec, i, t) + if (TREE_CODE (t) == BLOCK) + BLOCK_ABSTRACT (t) = 0; + else + DECL_ABSTRACT_P (t) = 0; current_function_decl = save_fn; decl_loc_table = old_decl_loc_table; @@ -19630,6 +19657,8 @@ gen_producer_string (void) case OPT_nostdinc: case OPT_nostdinc__: case OPT_fpreprocessed: + case OPT_fltrans_output_list_: + case OPT_fresolution_: /* Ignore these. */ continue; default: @@ -19786,8 +19815,17 @@ gen_compile_unit_die (const char *filename) { if (strcmp (language_string, "GNU Ada") == 0) language = DW_LANG_Ada95; - else if (strcmp (language_string, "GNU Fortran") == 0) - language = DW_LANG_Fortran95; + else if (strncmp (language_string, "GNU Fortran", 11) == 0) + { + language = DW_LANG_Fortran95; + if (dwarf_version >= 5 /* || !dwarf_strict */) + { + if (strcmp (language_string, "GNU Fortran2003") == 0) + language = DW_LANG_Fortran03; + else if (strcmp (language_string, "GNU Fortran2008") == 0) + language = DW_LANG_Fortran08; + } + } else if (strcmp (language_string, "GNU Java") == 0) language = DW_LANG_Java; else if (strcmp (language_string, "GNU Objective-C") == 0) @@ -19801,7 +19839,7 @@ gen_compile_unit_die (const char *filename) } } /* Use a degraded Fortran setting in strict DWARF2 so is_fortran works. */ - else if (strcmp (language_string, "GNU Fortran") == 0) + else if (strncmp (language_string, "GNU Fortran", 11) == 0) language = DW_LANG_Fortran90; add_AT_unsigned (die, DW_AT_language, language); @@ -19811,6 +19849,8 @@ gen_compile_unit_die (const char *filename) case DW_LANG_Fortran77: case DW_LANG_Fortran90: case DW_LANG_Fortran95: + case DW_LANG_Fortran03: + case DW_LANG_Fortran08: /* Fortran has case insensitive identifiers and the front-end lowercases everything. */ add_AT_unsigned (die, DW_AT_identifier_case, DW_ID_down_case); diff --git a/contrib/gcc-5.0/gcc/fold-const.c b/contrib/gcc-5.0/gcc/fold-const.c index b4301c78f3..83771207c4 100644 --- a/contrib/gcc-5.0/gcc/fold-const.c +++ b/contrib/gcc-5.0/gcc/fold-const.c @@ -10261,7 +10261,9 @@ fold_binary_loc (location_t loc, tem = build2_loc (loc, LROTATE_EXPR, TREE_TYPE (TREE_OPERAND (arg0, 0)), TREE_OPERAND (arg0, 0), - code0 == LSHIFT_EXPR ? tree01 : tree11); + code0 == LSHIFT_EXPR + ? TREE_OPERAND (arg0, 1) + : TREE_OPERAND (arg1, 1)); return fold_convert_loc (loc, type, tem); } else if (code11 == MINUS_EXPR) @@ -10283,7 +10285,8 @@ fold_binary_loc (location_t loc, ? LROTATE_EXPR : RROTATE_EXPR), TREE_TYPE (TREE_OPERAND (arg0, 0)), - TREE_OPERAND (arg0, 0), tree01)); + TREE_OPERAND (arg0, 0), + TREE_OPERAND (arg0, 1))); } else if (code01 == MINUS_EXPR) { @@ -10304,7 +10307,7 @@ fold_binary_loc (location_t loc, ? LROTATE_EXPR : RROTATE_EXPR), TREE_TYPE (TREE_OPERAND (arg0, 0)), - TREE_OPERAND (arg0, 0), tree11)); + TREE_OPERAND (arg0, 0), TREE_OPERAND (arg1, 1))); } } } diff --git a/contrib/gcc-5.0/gcc/gcc-main.c b/contrib/gcc-5.0/gcc/gcc-main.c new file mode 100644 index 0000000000..230ba4846c --- /dev/null +++ b/contrib/gcc-5.0/gcc/gcc-main.c @@ -0,0 +1,46 @@ +/* "main" for the compiler driver. + Copyright (C) 1987-2015 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* This source file contains "main" for the compiler driver. + All of the real work is done within gcc.c; we implement "main" + in here for the "gcc" binary so that gcc.o can be used in + libgccjit.so. */ + +#include "config.h" +#include "system.h" +#include "coretypes.h" +#include "tm.h" +#include "xregex.h" +#include "obstack.h" +#include "intl.h" +#include "prefix.h" +#include "gcc.h" + +/* Implement the top-level "main" within the driver in terms of + driver::main (implemented in gcc.c). */ + +extern int main (int, char **); + +int +main (int argc, char **argv) +{ + driver d; + + return d.main (argc, argv); +} diff --git a/contrib/gcc-5.0/gcc/gcc.c b/contrib/gcc-5.0/gcc/gcc.c index 186f0aef91..8a163a1c57 100644 --- a/contrib/gcc-5.0/gcc/gcc.c +++ b/contrib/gcc-5.0/gcc/gcc.c @@ -4696,6 +4696,8 @@ do_self_spec (const char *spec) } } + free (decoded_options); + alloc_switch (); switches[n_switches].part1 = 0; } @@ -6880,52 +6882,6 @@ compare_files (char *cmpfile[]) return ret; } -/* The top-level "main" within the driver would be ~1000 lines long. - This class breaks it up into smaller functions and contains some - state shared by them. */ - -class driver -{ - public: - int main (int argc, char **argv); - - private: - void set_progname (const char *argv0) const; - void expand_at_files (int *argc, char ***argv) const; - void decode_argv (int argc, const char **argv); - void global_initializations (); - void build_multilib_strings () const; - void set_up_specs () const; - void putenv_COLLECT_GCC (const char *argv0) const; - void maybe_putenv_COLLECT_LTO_WRAPPER () const; - void maybe_putenv_OFFLOAD_TARGETS () const; - void handle_unrecognized_options () const; - int maybe_print_and_exit () const; - bool prepare_infiles (); - void do_spec_on_infiles () const; - void maybe_run_linker (const char *argv0) const; - void final_actions () const; - int get_exit_code () const; - - private: - char *explicit_link_files; - struct cl_decoded_option *decoded_options; - unsigned int decoded_options_count; -}; - -/* Implement the top-level "main" within the driver in terms of - driver::main. */ - -extern int main (int, char **); - -int -main (int argc, char **argv) -{ - driver d; - - return d.main (argc, argv); -} - /* driver::main is implemented as a series of driver:: method calls. */ int @@ -9463,3 +9419,39 @@ convert_white_space (char *orig) else return orig; } + +/* PR jit/64810. + Targets can provide configure-time default options in + OPTION_DEFAULT_SPECS. The jit needs to access these, but + they are expressed in the spec language. + + Run just enough of the driver to be able to expand these + specs, and then call the callback CB on each + such option. The options strings are *without* a leading + '-' character e.g. ("march=x86-64"). Finally, clean up. */ + +void +driver_get_configure_time_options (void (*cb) (const char *option, + void *user_data), + void *user_data) +{ + size_t i; + + obstack_init (&obstack); + gcc_obstack_init (&opts_obstack); + n_switches = 0; + + for (i = 0; i < ARRAY_SIZE (option_default_specs); i++) + do_option_spec (option_default_specs[i].name, + option_default_specs[i].spec); + + for (i = 0; (int) i < n_switches; i++) + { + gcc_assert (switches[i].part1); + (*cb) (switches[i].part1, user_data); + } + + obstack_free (&opts_obstack, NULL); + obstack_free (&obstack, NULL); + n_switches = 0; +} diff --git a/contrib/gcc-5.0/gcc/gcc.h b/contrib/gcc-5.0/gcc/gcc.h index 473cf6a861..f10a103cd5 100644 --- a/contrib/gcc-5.0/gcc/gcc.h +++ b/contrib/gcc-5.0/gcc/gcc.h @@ -23,6 +23,39 @@ along with GCC; see the file COPYING3. If not see #include "version.h" #include "diagnostic-core.h" +/* The top-level "main" within the driver would be ~1000 lines long. + This class breaks it up into smaller functions and contains some + state shared by them. */ + +class driver +{ + public: + int main (int argc, char **argv); + + private: + void set_progname (const char *argv0) const; + void expand_at_files (int *argc, char ***argv) const; + void decode_argv (int argc, const char **argv); + void global_initializations (); + void build_multilib_strings () const; + void set_up_specs () const; + void putenv_COLLECT_GCC (const char *argv0) const; + void maybe_putenv_COLLECT_LTO_WRAPPER () const; + void maybe_putenv_OFFLOAD_TARGETS () const; + void handle_unrecognized_options () const; + int maybe_print_and_exit () const; + bool prepare_infiles (); + void do_spec_on_infiles () const; + void maybe_run_linker (const char *argv0) const; + void final_actions () const; + int get_exit_code () const; + + private: + char *explicit_link_files; + struct cl_decoded_option *decoded_options; + unsigned int decoded_options_count; +}; + /* The mapping of a spec function name to the C function that implements it. */ struct spec_function @@ -55,4 +88,9 @@ extern int lang_specific_extra_outfiles; extern const char **outfiles; +extern void +driver_get_configure_time_options (void (*cb)(const char *option, + void *user_data), + void *user_data); + #endif /* ! GCC_GCC_H */ diff --git a/contrib/gcc-5.0/gcc/gcov-io.c b/contrib/gcc-5.0/gcc/gcov-io.c index 143a3cebf3..cbd0a9f147 100644 --- a/contrib/gcc-5.0/gcc/gcov-io.c +++ b/contrib/gcc-5.0/gcc/gcov-io.c @@ -39,7 +39,7 @@ static void gcov_allocate (unsigned); /* Optimum number of gcov_unsigned_t's read from or written to disk. */ #define GCOV_BLOCK_SIZE (1 << 10) -GCOV_LINKAGE ATTRIBUTE_HIDDEN struct gcov_var +struct gcov_var { FILE *file; gcov_position_t start; /* Position of first byte of block */ diff --git a/contrib/gcc-5.0/gcc/gcov-tool.c b/contrib/gcc-5.0/gcc/gcov-tool.c index 0f97b532d7..fd27d7c11a 100644 --- a/contrib/gcc-5.0/gcc/gcov-tool.c +++ b/contrib/gcc-5.0/gcc/gcov-tool.c @@ -35,7 +35,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include #include #include +#if HAVE_FTW_H #include +#endif #include extern int gcov_profile_merge (struct gcov_info*, struct gcov_info*, int, int); @@ -49,6 +51,8 @@ extern void gcov_set_verbose (void); /* Set to verbose output mode. */ static bool verbose; +#if HAVE_FTW_H + /* Remove file NAME if it has a gcda suffix. */ static int @@ -69,13 +73,18 @@ unlink_gcda_file (const char *name, return ret; } +#endif /* Remove the gcda files in PATH recursively. */ static int -unlink_profile_dir (const char *path) +unlink_profile_dir (const char *path ATTRIBUTE_UNUSED) { +#if HAVE_FTW_H return nftw(path, unlink_gcda_file, 64, FTW_DEPTH | FTW_PHYS); +#else + return -1; +#endif } /* Output GCOV_INFO lists PROFILE to directory OUT. Note that @@ -90,11 +99,7 @@ gcov_output_files (const char *out, struct gcov_info *profile) /* Try to make directory if it doesn't already exist. */ if (access (out, F_OK) == -1) { -#if !defined(_WIN32) if (mkdir (out, S_IRWXU | S_IRWXG | S_IRWXO) == -1 && errno != EEXIST) -#else - if (mkdir (out) == -1 && errno != EEXIST) -#endif fatal_error (input_location, "Cannot make directory %s", out); } else unlink_profile_dir (out); diff --git a/contrib/gcc-5.0/gcc/genmatch.c b/contrib/gcc-5.0/gcc/genmatch.c index ea557a5bef..6723c29901 100644 --- a/contrib/gcc-5.0/gcc/genmatch.c +++ b/contrib/gcc-5.0/gcc/genmatch.c @@ -982,6 +982,7 @@ replace_id (operand *o, user_id *id, id_base *with) { expr *ne = new expr (e->operation == id ? with : e->operation, e->is_commutative); + ne->expr_type = e->expr_type; for (unsigned i = 0; i < e->ops.length (); ++i) ne->append_op (replace_id (e->ops[i], id, with)); return ne; diff --git a/contrib/gcc-5.0/gcc/gimple-fold.c b/contrib/gcc-5.0/gcc/gimple-fold.c index 3015901d8c..f89220c5a6 100644 --- a/contrib/gcc-5.0/gcc/gimple-fold.c +++ b/contrib/gcc-5.0/gcc/gimple-fold.c @@ -3120,6 +3120,7 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace) } gimple_call_set_lhs (stmt, NULL_TREE); } + maybe_remove_unused_call_args (cfun, stmt); } else { diff --git a/contrib/gcc-5.0/gcc/gimple.c b/contrib/gcc-5.0/gcc/gimple.c index caa1cbd2d0..a5c1192f77 100644 --- a/contrib/gcc-5.0/gcc/gimple.c +++ b/contrib/gcc-5.0/gcc/gimple.c @@ -67,6 +67,7 @@ along with GCC; see the file COPYING3. If not see #include "ipa-ref.h" #include "lto-streamer.h" #include "cgraph.h" +#include "gimple-ssa.h" /* All the tuples have their operand vector (if present) at the very bottom @@ -2950,3 +2951,20 @@ gimple_seq_discard (gimple_seq seq) ggc_free (stmt); } } + +/* See if STMT now calls function that takes no parameters and if so, drop + call arguments. This is used when devirtualization machinery redirects + to __builtiln_unreacahble or __cxa_pure_virutal. */ + +void +maybe_remove_unused_call_args (struct function *fn, gimple stmt) +{ + tree decl = gimple_call_fndecl (stmt); + if (TYPE_ARG_TYPES (TREE_TYPE (decl)) + && TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))) == void_type_node + && gimple_call_num_args (stmt)) + { + gimple_set_num_ops (stmt, 3); + update_stmt_fn (fn, stmt); + } +} diff --git a/contrib/gcc-5.0/gcc/gimple.h b/contrib/gcc-5.0/gcc/gimple.h index 769bad0118..5503625c9f 100644 --- a/contrib/gcc-5.0/gcc/gimple.h +++ b/contrib/gcc-5.0/gcc/gimple.h @@ -1404,6 +1404,7 @@ extern void sort_case_labels (vec); extern void preprocess_case_label_vec_for_gimple (vec, tree, tree *); extern void gimple_seq_set_location (gimple_seq, location_t); extern void gimple_seq_discard (gimple_seq); +extern void maybe_remove_unused_call_args (struct function *, gimple); /* Formal (expression) temporary table handling: multiple occurrences of the same scalar expression are evaluated into the same temporary. */ diff --git a/contrib/gcc-5.0/gcc/haifa-sched.c b/contrib/gcc-5.0/gcc/haifa-sched.c index 75d24217db..64c8c9c1f7 100644 --- a/contrib/gcc-5.0/gcc/haifa-sched.c +++ b/contrib/gcc-5.0/gcc/haifa-sched.c @@ -6291,7 +6291,15 @@ prune_ready_list (state_t temp_state, bool first_cycle_insn_p, if (SCHED_GROUP_P (insn) && cost > min_cost_group) min_cost_group = cost; ready_remove (&ready, i); - queue_insn (insn, cost, reason); + /* Normally we'd want to queue INSN for COST cycles. However, + if SCHED_GROUP_P is set, then we must ensure that nothing + else comes between INSN and its predecessor. If there is + some other insn ready to fire on the next cycle, then that + invariant would be broken. + + So when SCHED_GROUP_P is set, just queue this insn for a + single cycle. */ + queue_insn (insn, SCHED_GROUP_P (insn) ? 1 : cost, reason); if (i + 1 < n) break; } diff --git a/contrib/gcc-5.0/gcc/ipa-cp.c b/contrib/gcc-5.0/gcc/ipa-cp.c index 90fd3c2919..440ced4900 100644 --- a/contrib/gcc-5.0/gcc/ipa-cp.c +++ b/contrib/gcc-5.0/gcc/ipa-cp.c @@ -560,10 +560,7 @@ gather_caller_stats (struct cgraph_node *node, void *data) struct cgraph_edge *cs; for (cs = node->callers; cs; cs = cs->next_caller) - if (cs->caller->thunk.thunk_p) - cs->caller->call_for_symbol_thunks_and_aliases (gather_caller_stats, - stats, false); - else + if (!cs->caller->thunk.thunk_p) { stats->count_sum += cs->count; stats->freq_sum += cs->frequency; @@ -942,7 +939,8 @@ ipa_value_from_jfunc (struct ipa_node_params *info, struct ipa_jump_func *jfunc) { ipcp_lattice *lat; - if (!info->lattices) + if (!info->lattices + || idx >= ipa_get_param_count (info)) return NULL_TREE; lat = ipa_get_scalar_lat (info, idx); if (!lat->is_single_const ()) @@ -1004,7 +1002,8 @@ ipa_context_from_jfunc (ipa_node_params *info, cgraph_edge *cs, int csidx, } else { - if (!info->lattices) + if (!info->lattices + || srcidx >= ipa_get_param_count (info)) return ctx; ipcp_lattice *lat; lat = ipa_get_poly_ctx_lat (info, srcidx); @@ -2641,7 +2640,7 @@ propagate_constants_topo (struct ipa_topo_info *topo) for (cs = v->callees; cs; cs = cs->next_callee) if (ipa_edge_within_scc (cs) && propagate_constants_accross_call (cs)) - push_node_to_stack (topo, cs->callee); + push_node_to_stack (topo, cs->callee->function_symbol ()); v = pop_node_from_stack (topo); } diff --git a/contrib/gcc-5.0/gcc/ipa-devirt.c b/contrib/gcc-5.0/gcc/ipa-devirt.c index aaffa3cbb2..fe4f41bb55 100644 --- a/contrib/gcc-5.0/gcc/ipa-devirt.c +++ b/contrib/gcc-5.0/gcc/ipa-devirt.c @@ -807,7 +807,8 @@ warn_types_mismatch (tree t1, tree t2) gimple_canonical_types_compatible_p. */ static bool -odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, hash_set *visited) +odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned, + hash_set *visited) { /* Check first for the obvious case of pointer identity. */ if (t1 == t2) @@ -1206,8 +1207,8 @@ add_type_duplicate (odr_type val, tree type) val->types_set = new hash_set; /* Always prefer complete type to be the leader. */ - if (!COMPLETE_TYPE_P (val->type) - && COMPLETE_TYPE_P (type)) + if ((!COMPLETE_TYPE_P (val->type) || !TYPE_BINFO (val->type)) + && (COMPLETE_TYPE_P (type) && TYPE_BINFO (val->type))) { tree tmp = type; @@ -1221,7 +1222,7 @@ add_type_duplicate (odr_type val, tree type) { bool merge = true; bool base_mismatch = false; - unsigned int i,j; + unsigned int i; bool warned = false; hash_set visited; @@ -1229,7 +1230,8 @@ add_type_duplicate (odr_type val, tree type) vec_safe_push (val->types, type); /* First we compare memory layout. */ - if (!odr_types_equivalent_p (val->type, type, !flag_ltrans && !val->odr_violated, + if (!odr_types_equivalent_p (val->type, type, + !flag_ltrans && !val->odr_violated, &warned, &visited)) { merge = false; @@ -1253,31 +1255,108 @@ add_type_duplicate (odr_type val, tree type) && TREE_CODE (type) == RECORD_TYPE && TYPE_BINFO (val->type) && TYPE_BINFO (type)) { - for (j = 0, i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) - if (polymorphic_type_binfo_p (BINFO_BASE_BINFO (TYPE_BINFO (type), i))) + if (BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) + != BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))) + { + if (!warned && !val->odr_violated) + { + tree extra_base; + warn_odr (type, val->type, NULL, NULL, !warned, &warned, + "a type with the same name but different " + "number of polymorphic bases is " + "defined in another translation unit"); + if (BINFO_N_BASE_BINFOS (TYPE_BINFO (type)) + > BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))) + extra_base = BINFO_BASE_BINFO + (TYPE_BINFO (type), + BINFO_N_BASE_BINFOS (TYPE_BINFO (val->type))); + else + extra_base = BINFO_BASE_BINFO + (TYPE_BINFO (val->type), + BINFO_N_BASE_BINFOS (TYPE_BINFO (type))); + inform (DECL_SOURCE_LOCATION + (TYPE_NAME (DECL_CONTEXT (extra_base))), + "the extra base is defined here "); + } + base_mismatch = true; + } + else + for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) { - odr_type base = get_odr_type - (BINFO_TYPE - (BINFO_BASE_BINFO (TYPE_BINFO (type), - i)), - true); - if (val->bases.length () <= j || val->bases[j] != base) - base_mismatch = true; - j++; + tree base1 = BINFO_BASE_BINFO (TYPE_BINFO (type), i); + tree base2 = BINFO_BASE_BINFO (TYPE_BINFO (val->type), i); + tree type1 = BINFO_TYPE (base1); + tree type2 = BINFO_TYPE (base2); + + if (types_odr_comparable (type1, type2)) + { + if (!types_same_for_odr (type1, type2)) + base_mismatch = true; + } + else + { + hash_set visited; + if (!odr_types_equivalent_p (type1, type2, false, NULL, + &visited)) + base_mismatch = true; + } + if (base_mismatch) + { + if (!warned && !val->odr_violated) + warn_odr (type, val->type, NULL, NULL, + !warned, &warned, + "a type with the same name but different base " + "type is defined in another translation unit"); + warn_types_mismatch (type1, type2); + break; + } + if (BINFO_OFFSET (base1) != BINFO_OFFSET (base2)) + { + base_mismatch = true; + if (!warned && !val->odr_violated) + warn_odr (type, val->type, NULL, NULL, + !warned, &warned, + "a type with the same name but different base " + "layout is defined in another translation unit"); + break; + } } +#ifdef ENABLE_CHECKING + /* Sanity check that all bases will be build same way again. */ + if (!base_mismatch && val->bases.length ()) + { + unsigned int num_poly_bases = 0; + unsigned int j; + + for (i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); i++) + if (polymorphic_type_binfo_p (BINFO_BASE_BINFO + (TYPE_BINFO (type), i))) + num_poly_bases++; + gcc_assert (num_poly_bases == val->bases.length ()); + for (j = 0, i = 0; i < BINFO_N_BASE_BINFOS (TYPE_BINFO (type)); + i++) + if (polymorphic_type_binfo_p (BINFO_BASE_BINFO + (TYPE_BINFO (type), i))) + { + odr_type base = get_odr_type + (BINFO_TYPE + (BINFO_BASE_BINFO (TYPE_BINFO (type), + i)), + true); + gcc_assert (val->bases[j] == base); + j++; + } + } +#endif if (base_mismatch) { merge = false; odr_violation_reported = true; - - if (!warned && !val->odr_violated) - warn_odr (type, val->type, NULL, NULL, !warned, &warned, - "a type with the same name but different bases is " - "defined in another translation unit"); val->odr_violated = true; + if (symtab->dump_file) { - fprintf (symtab->dump_file, "ODR bse violation or merging bug?\n"); + fprintf (symtab->dump_file, "ODR base violation\n"); print_node (symtab->dump_file, "", val->type, 0); putc ('\n',symtab->dump_file); diff --git a/contrib/gcc-5.0/gcc/ipa-icf.c b/contrib/gcc-5.0/gcc/ipa-icf.c index 9b2d117b97..692946ae7b 100644 --- a/contrib/gcc-5.0/gcc/ipa-icf.c +++ b/contrib/gcc-5.0/gcc/ipa-icf.c @@ -584,6 +584,16 @@ sem_function::equals_private (sem_item *item, return result; } +/* Set LOCAL_P of NODE to true if DATA is non-NULL. + Helper for call_for_symbol_thunks_and_aliases. */ + +static bool +set_local (cgraph_node *node, void *data) +{ + node->local.local = data != NULL; + return false; +} + /* Merges instance with an ALIAS_ITEM, where alias, thunk or redirection can be applied. */ bool @@ -711,6 +721,10 @@ sem_function::merge (sem_item *alias_item) } 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. */ @@ -725,6 +739,10 @@ sem_function::merge (sem_item *alias_item) 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); @@ -735,10 +753,8 @@ sem_function::merge (sem_item *alias_item) cgraph_node::create_alias (alias_func->decl, decl); alias->resolve_alias (original); - /* Workaround for PR63566 that forces equal calling convention - to be used. */ - alias->local.local = false; - original->local.local = false; + original->call_for_symbol_thunks_and_aliases + (set_local, (void *)(size_t) original->local_p (), true); if (dump_file) fprintf (dump_file, "Callgraph alias has been created.\n\n"); @@ -762,6 +778,10 @@ sem_function::merge (sem_item *alias_item) } 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); @@ -1550,11 +1570,13 @@ sem_item_optimizer::read_summary (void) void sem_item_optimizer::register_hooks (void) { - m_cgraph_node_hooks = symtab->add_cgraph_removal_hook - (&sem_item_optimizer::cgraph_removal_hook, this); + if (!m_cgraph_node_hooks) + m_cgraph_node_hooks = symtab->add_cgraph_removal_hook + (&sem_item_optimizer::cgraph_removal_hook, this); - m_varpool_node_hooks = symtab->add_varpool_removal_hook - (&sem_item_optimizer::varpool_removal_hook, this); + if (!m_varpool_node_hooks) + m_varpool_node_hooks = symtab->add_varpool_removal_hook + (&sem_item_optimizer::varpool_removal_hook, this); } /* Unregister callgraph and varpool hooks. */ @@ -2426,6 +2448,7 @@ ipa_icf_generate_summary (void) if (!optimizer) optimizer = new sem_item_optimizer (); + optimizer->register_hooks (); optimizer->parse_funcs_and_vars (); } diff --git a/contrib/gcc-5.0/gcc/ipa-inline-analysis.c b/contrib/gcc-5.0/gcc/ipa-inline-analysis.c index ffa559c0c5..a628a9e987 100644 --- a/contrib/gcc-5.0/gcc/ipa-inline-analysis.c +++ b/contrib/gcc-5.0/gcc/ipa-inline-analysis.c @@ -3702,13 +3702,16 @@ simple_edge_hints (struct cgraph_edge *edge) int hints = 0; struct cgraph_node *to = (edge->caller->global.inlined_to ? edge->caller->global.inlined_to : edge->caller); + struct cgraph_node *callee = edge->callee->ultimate_alias_target (); if (inline_summaries->get (to)->scc_no - && inline_summaries->get (to)->scc_no == inline_summaries->get (edge->callee)->scc_no + && inline_summaries->get (to)->scc_no + == inline_summaries->get (callee)->scc_no && !edge->recursive_p ()) hints |= INLINE_HINT_same_scc; - if (to->lto_file_data && edge->callee->lto_file_data - && to->lto_file_data != edge->callee->lto_file_data) + if (callee->lto_file_data && edge->caller->lto_file_data + && edge->caller->lto_file_data != callee->lto_file_data + && !callee->merged) hints |= INLINE_HINT_cross_module; return hints; diff --git a/contrib/gcc-5.0/gcc/ipa-inline.c b/contrib/gcc-5.0/gcc/ipa-inline.c index be22890740..287a6dd1c4 100644 --- a/contrib/gcc-5.0/gcc/ipa-inline.c +++ b/contrib/gcc-5.0/gcc/ipa-inline.c @@ -1702,6 +1702,7 @@ inline_small_functions (void) { bool update = false; struct cgraph_edge *next; + bool has_speculative = false; if (dump_file) fprintf (dump_file, "Enqueueing calls in %s/%i.\n", @@ -1719,12 +1720,17 @@ inline_small_functions (void) gcc_assert (!edge->aux); update_edge_key (&edge_heap, edge); } - if (edge->speculative && !speculation_useful_p (edge, edge->aux != NULL)) + if (edge->speculative) + has_speculative = true; + } + if (has_speculative) + for (edge = node->callees; edge; edge = next) + if (edge->speculative && !speculation_useful_p (edge, + edge->aux != NULL)) { edge->resolve_speculation (); update = true; } - } if (update) { struct cgraph_node *where = node->global.inlined_to @@ -2528,7 +2534,9 @@ early_inliner (function *fun) cycles of edges to be always inlined in the callgraph. We might want to be smarter and just avoid this type of inlining. */ - || DECL_DISREGARD_INLINE_LIMITS (node->decl)) + || (DECL_DISREGARD_INLINE_LIMITS (node->decl) + && lookup_attribute ("always_inline", + DECL_ATTRIBUTES (node->decl)))) ; else if (lookup_attribute ("flatten", DECL_ATTRIBUTES (node->decl)) != NULL) @@ -2543,6 +2551,18 @@ early_inliner (function *fun) } else { + /* If some always_inline functions was inlined, apply the changes. + This way we will not account always inline into growth limits and + moreover we will inline calls from always inlines that we skipped + previously becuase of conditional above. */ + if (inlined) + { + timevar_push (TV_INTEGRATION); + todo |= optimize_inline_calls (current_function_decl); + inline_update_overall_summary (node); + inlined = false; + timevar_pop (TV_INTEGRATION); + } /* We iterate incremental inlining to get trivial cases of indirect inlining. */ while (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) diff --git a/contrib/gcc-5.0/gcc/ipa-polymorphic-call.c b/contrib/gcc-5.0/gcc/ipa-polymorphic-call.c index 5ad5e517fe..aaa549e03d 100644 --- a/contrib/gcc-5.0/gcc/ipa-polymorphic-call.c +++ b/contrib/gcc-5.0/gcc/ipa-polymorphic-call.c @@ -1078,7 +1078,7 @@ ipa_polymorphic_call_context::ipa_polymorphic_call_context (tree fndecl, base_type = TREE_TYPE (gimple_assign_rhs1 (SSA_NAME_DEF_STMT (base_pointer))); - if (POINTER_TYPE_P (base_type)) + if (base_type && POINTER_TYPE_P (base_type)) combine_speculation_with (TYPE_MAIN_VARIANT (TREE_TYPE (base_type)), offset, true, NULL /* Do not change type here */); diff --git a/contrib/gcc-5.0/gcc/ipa-prop.c b/contrib/gcc-5.0/gcc/ipa-prop.c index 9c8a785cee..878e94f826 100644 --- a/contrib/gcc-5.0/gcc/ipa-prop.c +++ b/contrib/gcc-5.0/gcc/ipa-prop.c @@ -3075,6 +3075,7 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, struct cgraph_indirect_call_info *ici = ie->indirect_info; struct ipa_jump_func *jfunc; int param_index; + cgraph_node *spec_target = NULL; next_ie = ie->next_callee; @@ -3091,6 +3092,14 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, param_index = ici->param_index; jfunc = ipa_get_ith_jump_func (top, param_index); + if (ie->speculative) + { + struct cgraph_edge *de; + struct ipa_ref *ref; + ie->speculative_call_info (de, ie, ref); + spec_target = de->callee; + } + if (!opt_for_fn (node->decl, flag_indirect_inlining)) new_direct_edge = NULL; else if (ici->polymorphic) @@ -3103,11 +3112,14 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, new_direct_edge = try_make_edge_direct_simple_call (ie, jfunc, new_root_info); /* If speculation was removed, then we need to do nothing. */ - if (new_direct_edge && new_direct_edge != ie) + if (new_direct_edge && new_direct_edge != ie + && new_direct_edge->callee == spec_target) { new_direct_edge->indirect_inlining_edge = 1; top = IPA_EDGE_REF (cs); res = true; + if (!new_direct_edge->speculative) + continue; } else if (new_direct_edge) { @@ -3123,9 +3135,13 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, res = true; } top = IPA_EDGE_REF (cs); + /* If speculative edge was introduced we still need to update + call info of the indirect edge. */ + if (!new_direct_edge->speculative) + continue; } - else if (jfunc->type == IPA_JF_PASS_THROUGH - && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) + if (jfunc->type == IPA_JF_PASS_THROUGH + && ipa_get_jf_pass_through_operation (jfunc) == NOP_EXPR) { if ((ici->agg_contents && !ipa_get_jf_pass_through_agg_preserved (jfunc)) diff --git a/contrib/gcc-5.0/gcc/ipa-split.c b/contrib/gcc-5.0/gcc/ipa-split.c index 7e2e300719..7e68a87607 100644 --- a/contrib/gcc-5.0/gcc/ipa-split.c +++ b/contrib/gcc-5.0/gcc/ipa-split.c @@ -1736,6 +1736,7 @@ execute_split_functions (void) /* Local functions called once will be completely inlined most of time. */ || (!node->callers->next_caller && node->local.local)) && !node->address_taken + && !node->has_aliases_p () && (!flag_lto || !node->externally_visible)) { if (dump_file) diff --git a/contrib/gcc-5.0/gcc/ipa-visibility.c b/contrib/gcc-5.0/gcc/ipa-visibility.c index 71894afc90..c33ee469db 100644 --- a/contrib/gcc-5.0/gcc/ipa-visibility.c +++ b/contrib/gcc-5.0/gcc/ipa-visibility.c @@ -101,17 +101,18 @@ along with GCC; see the file COPYING3. If not see /* Return true when NODE can not be local. Worker for cgraph_local_node_p. */ -bool -cgraph_node::non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) +static bool +non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED) { - /* FIXME: Aliases can be local, but i386 gets thunks wrong then. */ - return !(node->only_called_directly_or_aliased_p () - && !node->has_aliases_p () - && node->definition - && !DECL_EXTERNAL (node->decl) - && !node->externally_visible - && !node->used_from_other_partition - && !node->in_other_partition); + return !(node->only_called_directly_or_aliased_p () + /* i386 would need update to output thunk with locak calling + ocnvetions. */ + && !node->thunk.thunk_p + && node->definition + && !DECL_EXTERNAL (node->decl) + && !node->externally_visible + && !node->used_from_other_partition + && !node->in_other_partition); } /* Return true when function can be marked local. */ @@ -121,12 +122,10 @@ cgraph_node::local_p (void) { cgraph_node *n = ultimate_alias_target (); - /* FIXME: thunks can be considered local, but we need prevent i386 - from attempting to change calling convention of them. */ if (n->thunk.thunk_p) - return false; - return !n->call_for_symbol_thunks_and_aliases (cgraph_node::non_local_p, - NULL, true); + return n->callees->callee->local_p (); + return !n->call_for_symbol_thunks_and_aliases (non_local_p, + NULL, true); } @@ -425,11 +424,19 @@ update_visibility_by_resolution_info (symtab_node * node) if (node->same_comdat_group) for (symtab_node *next = node->same_comdat_group; next != node; next = next->same_comdat_group) - gcc_assert (!next->externally_visible - || define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY - || next->resolution == LDPR_PREVAILING_DEF - || next->resolution == LDPR_UNDEF - || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)); + { + if (!next->externally_visible) + continue; + + bool same_def + = define == (next->resolution == LDPR_PREVAILING_DEF_IRONLY + || next->resolution == LDPR_PREVAILING_DEF + || next->resolution == LDPR_UNDEF + || next->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP); + gcc_assert (in_lto_p || same_def); + if (!same_def) + return; + } if (node->same_comdat_group) for (symtab_node *next = node->same_comdat_group; diff --git a/contrib/gcc-5.0/gcc/ipa.c b/contrib/gcc-5.0/gcc/ipa.c index 36264175f5..58ba309737 100644 --- a/contrib/gcc-5.0/gcc/ipa.c +++ b/contrib/gcc-5.0/gcc/ipa.c @@ -383,7 +383,11 @@ symbol_table::remove_unreachable_nodes (FILE *file) /* If we are processing symbol in boundary, mark its AUX pointer for possible later re-processing in enqueue_node. */ if (in_boundary_p) - node->aux = (void *)2; + { + node->aux = (void *)2; + if (node->alias && node->analyzed) + enqueue_node (node->get_alias_target (), &first, &reachable); + } else { if (TREE_CODE (node->decl) == FUNCTION_DECL @@ -486,6 +490,9 @@ symbol_table::remove_unreachable_nodes (FILE *file) } } + else if (cnode->thunk.thunk_p) + enqueue_node (cnode->callees->callee, &first, &reachable); + /* If any reachable function has simd clones, mark them as reachable as well. */ if (cnode->simd_clones) @@ -530,11 +537,17 @@ symbol_table::remove_unreachable_nodes (FILE *file) /* If node is unreachable, remove its body. */ else if (!reachable.contains (node)) { - if (!body_needed_for_clonning.contains (node->decl)) + /* We keep definitions of thunks and aliases in the boundary so + we can walk to the ultimate alias targets and function symbols + reliably. */ + if (node->alias || node->thunk.thunk_p) + ; + else if (!body_needed_for_clonning.contains (node->decl) + && !node->alias && !node->thunk.thunk_p) node->release_body (); else if (!node->clone_of) gcc_assert (in_lto_p || DECL_RESULT (node->decl)); - if (node->definition) + if (node->definition && !node->alias && !node->thunk.thunk_p) { if (file) fprintf (file, " %s/%i", node->name (), node->order); @@ -554,7 +567,6 @@ symbol_table::remove_unreachable_nodes (FILE *file) if (!node->in_other_partition) node->local.local = false; node->remove_callees (); - node->remove_from_same_comdat_group (); node->remove_all_references (); changed = true; if (node->thunk.thunk_p @@ -597,12 +609,24 @@ symbol_table::remove_unreachable_nodes (FILE *file) or not. */ && (!flag_ltrans || !DECL_EXTERNAL (vnode->decl))) { + struct ipa_ref *ref = NULL; + + /* First remove the aliases, so varpool::remove can possibly lookup + the constructor and save it for future use. */ + while (vnode->iterate_direct_aliases (0, ref)) + { + if (file) + fprintf (file, " %s/%i", ref->referred->name (), + ref->referred->order); + ref->referring->remove (); + } if (file) fprintf (file, " %s/%i", vnode->name (), vnode->order); + vnext = next_variable (vnode); vnode->remove (); changed = true; } - else if (!reachable.contains (vnode)) + else if (!reachable.contains (vnode) && !vnode->alias) { tree init; if (vnode->definition) diff --git a/contrib/gcc-5.0/gcc/ira-color.c b/contrib/gcc-5.0/gcc/ira-color.c index d04be29ff4..b77ff69e64 100644 --- a/contrib/gcc-5.0/gcc/ira-color.c +++ b/contrib/gcc-5.0/gcc/ira-color.c @@ -858,7 +858,6 @@ setup_left_conflict_sizes_p (ira_allocno_t a) HARD_REG_SET node_set; nobj = ALLOCNO_NUM_OBJECTS (a); - conflict_size = 0; data = ALLOCNO_COLOR_DATA (a); subnodes = allocno_hard_regs_subnodes + data->hard_regs_subnodes_start; COPY_HARD_REG_SET (profitable_hard_regs, data->profitable_hard_regs); @@ -959,9 +958,9 @@ setup_left_conflict_sizes_p (ira_allocno_t a) } left_conflict_subnodes_size = subnodes[0].left_conflict_subnodes_size; conflict_size - += (left_conflict_subnodes_size - + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size, - subnodes[0].left_conflict_size)); + = (left_conflict_subnodes_size + + MIN (subnodes[0].max_node_impact - left_conflict_subnodes_size, + subnodes[0].left_conflict_size)); conflict_size += ira_reg_class_max_nregs[ALLOCNO_CLASS (a)][ALLOCNO_MODE (a)]; data->colorable_p = conflict_size <= data->available_regs_num; return data->colorable_p; diff --git a/contrib/gcc-5.0/gcc/langhooks.c b/contrib/gcc-5.0/gcc/langhooks.c index f68c81cf8c..74f83519c5 100644 --- a/contrib/gcc-5.0/gcc/langhooks.c +++ b/contrib/gcc-5.0/gcc/langhooks.c @@ -731,3 +731,11 @@ lang_GNU_CXX (void) { return strncmp (lang_hooks.name, "GNU C++", 7) == 0; } + +/* Returns true if the current lang_hooks represents the GNU Fortran frontend. */ + +bool +lang_GNU_Fortran (void) +{ + return strncmp (lang_hooks.name, "GNU Fortran", 11) == 0; +} diff --git a/contrib/gcc-5.0/gcc/langhooks.h b/contrib/gcc-5.0/gcc/langhooks.h index 17c903f88c..4039e8f737 100644 --- a/contrib/gcc-5.0/gcc/langhooks.h +++ b/contrib/gcc-5.0/gcc/langhooks.h @@ -509,5 +509,6 @@ extern tree add_builtin_type (const char *name, tree type); extern bool lang_GNU_C (void); extern bool lang_GNU_CXX (void); +extern bool lang_GNU_Fortran (void); #endif /* GCC_LANG_HOOKS_H */ diff --git a/contrib/gcc-5.0/gcc/lra-eliminations.c b/contrib/gcc-5.0/gcc/lra-eliminations.c index fe05a1f252..64eec4a003 100644 --- a/contrib/gcc-5.0/gcc/lra-eliminations.c +++ b/contrib/gcc-5.0/gcc/lra-eliminations.c @@ -182,6 +182,8 @@ setup_can_eliminate (struct lra_elim_table *ep, bool value) if (! value && ep->from == FRAME_POINTER_REGNUM && ep->to == STACK_POINTER_REGNUM) frame_pointer_needed = 1; + if (!frame_pointer_needed) + REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = 0; } /* Map: eliminable "from" register -> its current elimination, diff --git a/contrib/gcc-5.0/gcc/lra.c b/contrib/gcc-5.0/gcc/lra.c index bc6723db24..abe0c334b3 100644 --- a/contrib/gcc-5.0/gcc/lra.c +++ b/contrib/gcc-5.0/gcc/lra.c @@ -475,7 +475,7 @@ lra_emit_add (rtx x, rtx y, rtx z) rtx insn = emit_add2_insn (x, disp); if (insn != NULL_RTX) { - insn = emit_add2_insn (x, disp); + insn = emit_add2_insn (x, base); if (insn != NULL_RTX) ok_p = true; } diff --git a/contrib/gcc-5.0/gcc/lto-cgraph.c b/contrib/gcc-5.0/gcc/lto-cgraph.c index ab9524b3b7..c0fa47d2c2 100644 --- a/contrib/gcc-5.0/gcc/lto-cgraph.c +++ b/contrib/gcc-5.0/gcc/lto-cgraph.c @@ -432,14 +432,13 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, struct cgraph_node *clone_of, *ultimate_clone_of; ipa_opt_pass_d *pass; int i; - bool alias_p; const char *comdat; const char *section; tree group; boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node); - if (node->analyzed && !boundary_p) + if (node->analyzed && (!boundary_p || node->alias || node->thunk.thunk_p)) tag = LTO_symtab_analyzed_node; else tag = LTO_symtab_unavail_node; @@ -565,14 +564,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, || referenced_from_other_partition_p (node, encoder)), 1); bp_pack_value (&bp, node->lowered, 1); bp_pack_value (&bp, in_other_partition, 1); - /* Real aliases in a boundary become non-aliases. However we still stream - alias info on weakrefs. - TODO: We lose a bit of information here - when we know that variable is - defined in other unit, we may use the info on aliases to resolve - symbol1 != symbol2 type tests that we can do only for locally defined objects - otherwise. */ - alias_p = node->alias && (!boundary_p || node->weakref); - bp_pack_value (&bp, alias_p, 1); + bp_pack_value (&bp, node->alias, 1); bp_pack_value (&bp, node->weakref, 1); bp_pack_value (&bp, node->frequency, 2); bp_pack_value (&bp, node->only_called_at_startup, 1); @@ -581,14 +573,14 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, bp_pack_value (&bp, node->calls_comdat_local, 1); bp_pack_value (&bp, node->icf_merged, 1); bp_pack_value (&bp, node->nonfreeing_fn, 1); - bp_pack_value (&bp, node->thunk.thunk_p && !boundary_p, 1); + bp_pack_value (&bp, node->thunk.thunk_p, 1); bp_pack_enum (&bp, ld_plugin_symbol_resolution, LDPR_NUM_KNOWN, node->resolution); bp_pack_value (&bp, node->instrumentation_clone, 1); streamer_write_bitpack (&bp); streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1); - if (node->thunk.thunk_p && !boundary_p) + if (node->thunk.thunk_p) { streamer_write_uhwi_stream (ob->main_stream, @@ -618,7 +610,6 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node, bool boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node); struct bitpack_d bp; int ref; - bool alias_p; const char *comdat; const char *section; tree group; @@ -638,8 +629,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node, bp_pack_value (&bp, node->implicit_section, 1); bp_pack_value (&bp, node->writeonly, 1); bp_pack_value (&bp, node->definition, 1); - alias_p = node->alias && (!boundary_p || node->weakref); - bp_pack_value (&bp, alias_p, 1); + bp_pack_value (&bp, node->alias, 1); bp_pack_value (&bp, node->weakref, 1); bp_pack_value (&bp, node->analyzed && !boundary_p, 1); gcc_assert (node->definition || !node->analyzed); @@ -794,18 +784,18 @@ output_outgoing_cgraph_edges (struct cgraph_edge *edge, static void output_refs (lto_symtab_encoder_t encoder) { - lto_symtab_encoder_iterator lsei; struct lto_simple_output_block *ob; int count; struct ipa_ref *ref; - int i; ob = lto_create_simple_output_block (LTO_section_refs); - for (lsei = lsei_start_in_partition (encoder); !lsei_end_p (lsei); - lsei_next_in_partition (&lsei)) + for (int i = 0; i < lto_symtab_encoder_size (encoder); i++) { - symtab_node *node = lsei_node (lsei); + symtab_node *node = lto_symtab_encoder_deref (encoder, i); + + if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node)) + continue; count = node->ref_list.nreferences (); if (count) @@ -813,7 +803,7 @@ output_refs (lto_symtab_encoder_t encoder) streamer_write_gcov_count_stream (ob->main_stream, count); streamer_write_uhwi_stream (ob->main_stream, lto_symtab_encoder_lookup (encoder, node)); - for (i = 0; node->iterate_reference (i, ref); i++) + for (int i = 0; node->iterate_reference (i, ref); i++) lto_output_ref (ob, ref, encoder); } } @@ -987,6 +977,19 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) } } } + /* Be sure to also insert alias targert and thunk callees. These needs + to stay to aid local calling conventions. */ + for (i = 0; i < lto_symtab_encoder_size (encoder); i++) + { + symtab_node *node = lto_symtab_encoder_deref (encoder, i); + cgraph_node *cnode = dyn_cast (node); + + if (node->alias && node->analyzed) + create_references (encoder, node); + if (cnode + && cnode->thunk.thunk_p) + add_node_to (encoder, cnode->callees->callee, false); + } lto_symtab_encoder_delete (in_encoder); return encoder; } @@ -998,7 +1001,6 @@ output_symtab (void) { struct cgraph_node *node; struct lto_simple_output_block *ob; - lto_symtab_encoder_iterator lsei; int i, n_nodes; lto_symtab_encoder_t encoder; @@ -1028,12 +1030,16 @@ output_symtab (void) } /* Go over the nodes in SET again to write edges. */ - for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei); - lsei_next_function_in_partition (&lsei)) + for (int i = 0; i < lto_symtab_encoder_size (encoder); i++) { - node = lsei_cgraph_node (lsei); - output_outgoing_cgraph_edges (node->callees, ob, encoder); - output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder); + node = dyn_cast (lto_symtab_encoder_deref (encoder, i)); + if (node + && (node->thunk.thunk_p + || lto_symtab_encoder_in_partition_p (encoder, node))) + { + output_outgoing_cgraph_edges (node->callees, ob, encoder); + output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder); + } } streamer_write_uhwi_stream (ob->main_stream, 0); diff --git a/contrib/gcc-5.0/gcc/lto-streamer-out.c b/contrib/gcc-5.0/gcc/lto-streamer-out.c index cced43b971..0c27c9d73d 100644 --- a/contrib/gcc-5.0/gcc/lto-streamer-out.c +++ b/contrib/gcc-5.0/gcc/lto-streamer-out.c @@ -385,9 +385,7 @@ lto_write_tree_1 (struct output_block *ob, tree expr, bool ref_p) { /* Pack all the non-pointer fields in EXPR into a bitpack and write the resulting bitpack. */ - bitpack_d bp = bitpack_create (ob->main_stream); - streamer_pack_tree_bitfields (ob, &bp, expr); - streamer_write_bitpack (&bp); + streamer_write_tree_bitfields (ob, expr); /* Write all the pointer fields in EXPR. */ streamer_write_tree_body (ob, expr, ref_p); diff --git a/contrib/gcc-5.0/gcc/lto/lto-symtab.c b/contrib/gcc-5.0/gcc/lto/lto-symtab.c index 39c9257edc..c00fd87483 100644 --- a/contrib/gcc-5.0/gcc/lto/lto-symtab.c +++ b/contrib/gcc-5.0/gcc/lto/lto-symtab.c @@ -88,6 +88,8 @@ lto_cgraph_replace_node (struct cgraph_node *node, gcc_assert (!prevailing_node->global.inlined_to); prevailing_node->mark_address_taken (); } + if (node->definition && prevailing_node->definition) + prevailing_node->merged = true; /* Redirect all incoming edges. */ compatible_p diff --git a/contrib/gcc-5.0/gcc/opts.c b/contrib/gcc-5.0/gcc/opts.c index 84627c4e37..4a1ed0e48b 100644 --- a/contrib/gcc-5.0/gcc/opts.c +++ b/contrib/gcc-5.0/gcc/opts.c @@ -1106,7 +1106,7 @@ print_filtered_help (unsigned int include_flags, if (* (const char **) flag_var != NULL) snprintf (new_help + strlen (new_help), sizeof (new_help) - strlen (new_help), - * (const char **) flag_var); + "%s", * (const char **) flag_var); } else if (option->var_type == CLVC_ENUM) { @@ -1120,7 +1120,7 @@ print_filtered_help (unsigned int include_flags, arg = _("[default]"); snprintf (new_help + strlen (new_help), sizeof (new_help) - strlen (new_help), - arg); + "%s", arg); } else sprintf (new_help + strlen (new_help), diff --git a/contrib/gcc-5.0/gcc/reorg.c b/contrib/gcc-5.0/gcc/reorg.c index 2be34572d9..238791044c 100644 --- a/contrib/gcc-5.0/gcc/reorg.c +++ b/contrib/gcc-5.0/gcc/reorg.c @@ -1156,13 +1156,11 @@ steal_delay_list_from_target (rtx_insn *insn, rtx condition, rtx_sequence *seq, || ! single_set (seq->insn (0))) return delay_list; -#ifdef MD_CAN_REDIRECT_BRANCH /* On some targets, branches with delay slots can have a limited displacement. Give the back end a chance to tell us we can't do this. */ - if (! MD_CAN_REDIRECT_BRANCH (insn, seq->insn (0))) + if (! targetm.can_follow_jump (insn, seq->insn (0))) return delay_list; -#endif redundant = XALLOCAVEC (bool, XVECLEN (seq, 0)); for (i = 1; i < seq->len (); i++) diff --git a/contrib/gcc-5.0/gcc/simplify-rtx.c b/contrib/gcc-5.0/gcc/simplify-rtx.c index 5c9e3bf166..a003b4179a 100644 --- a/contrib/gcc-5.0/gcc/simplify-rtx.c +++ b/contrib/gcc-5.0/gcc/simplify-rtx.c @@ -2708,6 +2708,39 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, XEXP (op0, 1), mode), op1); + /* Given (xor (ior (xor A B) C) D), where B, C and D are + constants, simplify to (xor (ior A C) (B&~C)^D), canceling + out bits inverted twice and not set by C. Similarly, given + (xor (and (xor A B) C) D), simplify without inverting C in + the xor operand: (xor (and A C) (B&C)^D). + */ + else if ((GET_CODE (op0) == IOR || GET_CODE (op0) == AND) + && GET_CODE (XEXP (op0, 0)) == XOR + && CONST_INT_P (op1) + && CONST_INT_P (XEXP (op0, 1)) + && CONST_INT_P (XEXP (XEXP (op0, 0), 1))) + { + enum rtx_code op = GET_CODE (op0); + rtx a = XEXP (XEXP (op0, 0), 0); + rtx b = XEXP (XEXP (op0, 0), 1); + rtx c = XEXP (op0, 1); + rtx d = op1; + HOST_WIDE_INT bval = INTVAL (b); + HOST_WIDE_INT cval = INTVAL (c); + HOST_WIDE_INT dval = INTVAL (d); + HOST_WIDE_INT xcval; + + if (op == IOR) + xcval = ~cval; + else + xcval = cval; + + return simplify_gen_binary (XOR, mode, + simplify_gen_binary (op, mode, a, c), + gen_int_mode ((bval & xcval) ^ dval, + mode)); + } + /* Given (xor (and A B) C), using P^Q == (~P&Q) | (~Q&P), we can transform like this: (A&B)^C == ~(A&B)&C | ~C&(A&B) @@ -2724,12 +2757,31 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, HOST_WIDE_INT bval = INTVAL (b); HOST_WIDE_INT cval = INTVAL (c); - rtx na_c - = simplify_binary_operation (AND, mode, - simplify_gen_unary (NOT, mode, a, mode), - c); + /* Instead of computing ~A&C, we compute its negated value, + ~(A|~C). If it yields -1, ~A&C is zero, so we can + optimize for sure. If it does not simplify, we still try + to compute ~A&C below, but since that always allocates + RTL, we don't try that before committing to returning a + simplified expression. */ + rtx n_na_c = simplify_binary_operation (IOR, mode, a, + GEN_INT (~cval)); + if ((~cval & bval) == 0) { + rtx na_c = NULL_RTX; + if (n_na_c) + na_c = simplify_gen_unary (NOT, mode, n_na_c, mode); + else + { + /* If ~A does not simplify, don't bother: we don't + want to simplify 2 operations into 3, and if na_c + were to simplify with na, n_na_c would have + simplified as well. */ + rtx na = simplify_unary_operation (NOT, mode, a, mode); + if (na) + na_c = simplify_gen_binary (AND, mode, na, c); + } + /* Try to simplify ~A&C | ~B&C. */ if (na_c != NULL_RTX) return simplify_gen_binary (IOR, mode, na_c, @@ -2738,7 +2790,7 @@ simplify_binary_operation_1 (enum rtx_code code, machine_mode mode, else { /* If ~A&C is zero, simplify A&(~C&B) | ~B&C. */ - if (na_c == const0_rtx) + if (n_na_c == CONSTM1_RTX (mode)) { rtx a_nc_b = simplify_gen_binary (AND, mode, a, gen_int_mode (~cval & bval, diff --git a/contrib/gcc-5.0/gcc/symtab.c b/contrib/gcc-5.0/gcc/symtab.c index aba1ae4063..3cdf62aeed 100644 --- a/contrib/gcc-5.0/gcc/symtab.c +++ b/contrib/gcc-5.0/gcc/symtab.c @@ -1070,11 +1070,6 @@ symtab_node::verify_base (void) error ("same_comdat_group list across different groups"); error_found = true; } - if (!n->definition) - { - error ("Node has same_comdat_group but it is not a definition"); - error_found = true; - } if (n->type != type) { error ("mixing different types of symbol in same comdat groups is not supported"); @@ -1784,6 +1779,8 @@ symtab_node::get_partitioning_class (void) if (varpool_node *vnode = dyn_cast (this)) { + if (alias && definition && !ultimate_alias_target ()->definition) + return SYMBOL_EXTERNAL; /* Constant pool references use local symbol names that can not be promoted global. We should never put into a constant pool objects that can not be duplicated across partitions. */ @@ -1795,7 +1792,7 @@ symtab_node::get_partitioning_class (void) Handle them as external; compute_ltrans_boundary take care to make proper things to happen (i.e. to make them appear in the boundary but with body streamed, so clone can me materialized). */ - else if (!dyn_cast (this)->definition) + else if (!dyn_cast (this)->function_symbol ()->definition) return SYMBOL_EXTERNAL; /* Linker discardable symbols are duplicated to every use unless they are diff --git a/contrib/gcc-5.0/gcc/toplev.c b/contrib/gcc-5.0/gcc/toplev.c index c4bc74b6e7..99cf180690 100644 --- a/contrib/gcc-5.0/gcc/toplev.c +++ b/contrib/gcc-5.0/gcc/toplev.c @@ -1662,6 +1662,11 @@ process_options (void) flag_sanitize &= ~SANITIZE_ADDRESS; } + /* Do not use IPA optimizations for register allocation if profiler is active + or port does not emit prologue and epilogue as RTL. */ + if (profile_flag || !HAVE_prologue || !HAVE_epilogue) + flag_ipa_ra = 0; + /* Enable -Werror=coverage-mismatch when -Werror and -Wno-error have not been set. */ if (!global_options_set.x_warnings_are_errors @@ -1675,10 +1680,8 @@ process_options (void) optimization_default_node = build_optimization_node (&global_options); optimization_current_node = optimization_default_node; - /* Disable use caller save optimization if profiler is active or port - does not emit prologue and epilogue as RTL. */ - if (profile_flag || !HAVE_prologue || !HAVE_epilogue) - flag_ipa_ra = 0; + /* Please don't change global_options after this point, those changes won't + be reflected in optimization_{default,current}_node. */ } /* This function can be called multiple times to reinitialize the compiler diff --git a/contrib/gcc-5.0/gcc/tree-core.h b/contrib/gcc-5.0/gcc/tree-core.h index c7a21b5c35..3aaf650ff7 100644 --- a/contrib/gcc-5.0/gcc/tree-core.h +++ b/contrib/gcc-5.0/gcc/tree-core.h @@ -158,10 +158,14 @@ enum built_in_function { BEGIN_CHKP_BUILTINS, #undef DEF_BUILTIN -#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) ENUM##_CHKP, +#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) +#undef DEF_BUILTIN_CHKP +#define DEF_BUILTIN_CHKP(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \ + ENUM##_CHKP = ENUM + BEGIN_CHKP_BUILTINS + 1, #include "builtins.def" +#undef DEF_BUILTIN_CHKP - END_CHKP_BUILTINS, + END_CHKP_BUILTINS = BEGIN_CHKP_BUILTINS * 2 + 1, /* Complex division routines in libgcc. These are done via builtins because emit_library_call_value can't handle complex values. */ diff --git a/contrib/gcc-5.0/gcc/tree-eh.c b/contrib/gcc-5.0/gcc/tree-eh.c index 159fa2bee1..3c45f37efb 100644 --- a/contrib/gcc-5.0/gcc/tree-eh.c +++ b/contrib/gcc-5.0/gcc/tree-eh.c @@ -3859,6 +3859,17 @@ mark_reachable_handlers (sbitmap *r_reachablep, sbitmap *lp_reachablep) gimple_eh_dispatch_region ( as_a (stmt))); break; + case GIMPLE_CALL: + if (gimple_call_builtin_p (stmt, BUILT_IN_EH_COPY_VALUES)) + for (int i = 0; i < 2; ++i) + { + tree rt = gimple_call_arg (stmt, i); + HOST_WIDE_INT ri = tree_to_shwi (rt); + + gcc_assert (ri = (int)ri); + bitmap_set_bit (r_reachable, ri); + } + break; default: break; } diff --git a/contrib/gcc-5.0/gcc/tree-emutls.c b/contrib/gcc-5.0/gcc/tree-emutls.c index da03b2a0fc..b4711a59c6 100644 --- a/contrib/gcc-5.0/gcc/tree-emutls.c +++ b/contrib/gcc-5.0/gcc/tree-emutls.c @@ -366,9 +366,14 @@ new_emutls_decl (tree decl, tree alias_of) else if (!alias_of) varpool_node::add (to); else - varpool_node::create_alias (to, - varpool_node::get_for_asmname - (DECL_ASSEMBLER_NAME (DECL_VALUE_EXPR (alias_of)))->decl); + { + varpool_node *n; + varpool_node *t = varpool_node::get_for_asmname + (DECL_ASSEMBLER_NAME (DECL_VALUE_EXPR (alias_of))); + + n = varpool_node::create_alias (to, t->decl); + n->resolve_alias (t); + } return to; } @@ -748,17 +753,19 @@ ipa_lower_emutls (void) cgraph_node *func; bool any_aliases = false; tree ctor_body = NULL; - + hash_set visited; auto_vec tls_vars; /* Examine all global variables for TLS variables. */ FOR_EACH_VARIABLE (var) - if (DECL_THREAD_LOCAL_P (var->decl)) + if (DECL_THREAD_LOCAL_P (var->decl) + && !visited.add (var)) { gcc_checking_assert (TREE_STATIC (var->decl) || DECL_EXTERNAL (var->decl)); tls_vars.safe_push (var); - if (var->alias && var->definition) + if (var->alias && var->definition + && !visited.add (var->ultimate_alias_target ())) tls_vars.safe_push (var->ultimate_alias_target ()); } diff --git a/contrib/gcc-5.0/gcc/tree-sra.c b/contrib/gcc-5.0/gcc/tree-sra.c index ad9584ed3d..c6726a89cb 100644 --- a/contrib/gcc-5.0/gcc/tree-sra.c +++ b/contrib/gcc-5.0/gcc/tree-sra.c @@ -3987,7 +3987,7 @@ dump_dereferences_table (FILE *f, const char *str, HOST_WIDE_INT *table) { basic_block bb; - fprintf (dump_file, str); + fprintf (dump_file, "%s", str); FOR_BB_BETWEEN (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun), EXIT_BLOCK_PTR_FOR_FN (cfun), next_bb) { diff --git a/contrib/gcc-5.0/gcc/tree-ssa-ccp.c b/contrib/gcc-5.0/gcc/tree-ssa-ccp.c index a576bd118b..d45a3ff2a8 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-ccp.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-ccp.c @@ -1145,7 +1145,8 @@ valueize_op_1 (tree op) this SSA edge as the SSA propagator does not necessarily re-visit the use. */ gimple def_stmt = SSA_NAME_DEF_STMT (op); - if (prop_simulate_again_p (def_stmt)) + if (!gimple_nop_p (def_stmt) + && prop_simulate_again_p (def_stmt)) return NULL_TREE; tree tem = get_constant_value (op); if (tem) diff --git a/contrib/gcc-5.0/gcc/tree-ssa-forwprop.c b/contrib/gcc-5.0/gcc/tree-ssa-forwprop.c index 82d832d475..d8db20acd3 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-forwprop.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-forwprop.c @@ -2274,6 +2274,8 @@ pass_forwprop::execute (function *fun) = gimple_build_assign (gimple_assign_lhs (use_stmt), new_rhs); + location_t loc = gimple_location (use_stmt); + gimple_set_location (new_stmt, loc); gimple_stmt_iterator gsi2 = gsi_for_stmt (use_stmt); unlink_stmt_vdef (use_stmt); gsi_remove (&gsi2, true); @@ -2305,6 +2307,8 @@ pass_forwprop::execute (function *fun) TREE_TYPE (TREE_TYPE (use_lhs)), unshare_expr (use_lhs)); gimple new_stmt = gimple_build_assign (new_lhs, rhs); + location_t loc = gimple_location (use_stmt); + gimple_set_location (new_stmt, loc); gimple_set_vuse (new_stmt, gimple_vuse (use_stmt)); gimple_set_vdef (new_stmt, make_ssa_name (gimple_vop (cfun))); SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt; diff --git a/contrib/gcc-5.0/gcc/tree-ssa-loop-ivopts.c b/contrib/gcc-5.0/gcc/tree-ssa-loop-ivopts.c index d50adb0f25..6c96430806 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-loop-ivopts.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-loop-ivopts.c @@ -138,6 +138,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "tree-ssa-address.h" #include "builtins.h" +#include "tree-vectorizer.h" /* FIXME: Expressions are expanded to RTL in this pass to determine the cost of different addressing modes. This should be moved to a TBD @@ -318,6 +319,7 @@ struct ivopts_data { /* The currently optimized loop. */ struct loop *current_loop; + source_location loop_loc; /* Numbers of iterations for all exits of the current loop. */ hash_map *niters; @@ -1079,13 +1081,40 @@ determine_biv_step (gphi *phi) return integer_zerop (iv.step) ? NULL_TREE : iv.step; } +/* Return the first non-invariant ssa var found in EXPR. */ + +static tree +extract_single_var_from_expr (tree expr) +{ + int i, n; + tree tmp; + enum tree_code code; + + if (!expr || is_gimple_min_invariant (expr)) + return NULL; + + code = TREE_CODE (expr); + if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))) + { + n = TREE_OPERAND_LENGTH (expr); + for (i = 0; i < n; i++) + { + tmp = extract_single_var_from_expr (TREE_OPERAND (expr, i)); + + if (tmp) + return tmp; + } + } + return (TREE_CODE (expr) == SSA_NAME) ? expr : NULL; +} + /* Finds basic ivs. */ static bool find_bivs (struct ivopts_data *data) { gphi *phi; - tree step, type, base; + tree step, type, base, stop; bool found = false; struct loop *loop = data->current_loop; gphi_iterator psi; @@ -1102,7 +1131,13 @@ find_bivs (struct ivopts_data *data) continue; base = PHI_ARG_DEF_FROM_EDGE (phi, loop_preheader_edge (loop)); - base = expand_simple_operations (base); + /* Stop expanding iv base at the first ssa var referred by iv step. + Ideally we should stop at any ssa var, because that's expensive + and unusual to happen, we just do it on the first one. + + See PR64705 for the rationale. */ + stop = extract_single_var_from_expr (step); + base = expand_simple_operations (base, stop); if (contains_abnormal_ssa_name_p (base) || contains_abnormal_ssa_name_p (step)) continue; @@ -1174,7 +1209,7 @@ mark_bivs (struct ivopts_data *data) static bool find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv) { - tree lhs; + tree lhs, stop; struct loop *loop = data->current_loop; iv->base = NULL_TREE; @@ -1189,13 +1224,19 @@ find_givs_in_stmt_scev (struct ivopts_data *data, gimple stmt, affine_iv *iv) if (!simple_iv (loop, loop_containing_stmt (stmt), lhs, iv, true)) return false; - iv->base = expand_simple_operations (iv->base); + /* Stop expanding iv base at the first ssa var referred by iv step. + Ideally we should stop at any ssa var, because that's expensive + and unusual to happen, we just do it on the first one. + + See PR64705 for the rationale. */ + stop = extract_single_var_from_expr (iv->step); + iv->base = expand_simple_operations (iv->base, stop); if (contains_abnormal_ssa_name_p (iv->base) || contains_abnormal_ssa_name_p (iv->step)) return false; - /* If STMT could throw, then do not consider STMT as defining a GIV. + /* If STMT could throw, then do not consider STMT as defining a GIV. While this will suppress optimizations, we can not safely delete this GIV and associated statements, even if it appears it is not used. */ if (stmt_could_throw_p (stmt)) @@ -3324,12 +3365,12 @@ get_address_cost (bool symbol_present, bool var_present, XEXP (addr, 1) = gen_int_mode (off, address_mode); if (memory_address_addr_space_p (mem_mode, addr, as)) break; - /* For some TARGET, like ARM THUMB1, the offset should be nature - aligned. Try an aligned offset if address_mode is not QImode. */ - off = (address_mode == QImode) - ? 0 - : ((unsigned HOST_WIDE_INT) 1 << i) - - GET_MODE_SIZE (address_mode); + /* For some strict-alignment targets, the offset must be naturally + aligned. Try an aligned offset if mem_mode is not QImode. */ + off = mem_mode != QImode + ? ((unsigned HOST_WIDE_INT) 1 << i) + - GET_MODE_SIZE (mem_mode) + : 0; if (off > 0) { XEXP (addr, 1) = gen_int_mode (off, address_mode); @@ -3597,22 +3638,26 @@ get_shiftadd_cost (tree expr, machine_mode mode, comp_cost cost0, tree multop = TREE_OPERAND (mult, 0); int m = exact_log2 (int_cst_value (cst)); int maxm = MIN (BITS_PER_WORD, GET_MODE_BITSIZE (mode)); - int sa_cost; - bool equal_p = false; + int as_cost, sa_cost; + bool mult_in_op1; if (!(m >= 0 && m < maxm)) return false; - if (operand_equal_p (op1, mult, 0)) - equal_p = true; + mult_in_op1 = operand_equal_p (op1, mult, 0); + + as_cost = add_cost (speed, mode) + shift_cost (speed, mode, m); + /* If the target has a cheap shift-and-add or shift-and-sub instruction, + use that in preference to a shift insn followed by an add insn. */ sa_cost = (TREE_CODE (expr) != MINUS_EXPR ? shiftadd_cost (speed, mode, m) - : (equal_p + : (mult_in_op1 ? shiftsub1_cost (speed, mode, m) : shiftsub0_cost (speed, mode, m))); - res = new_cost (sa_cost, 0); - res = add_costs (res, equal_p ? cost0 : cost1); + + res = new_cost (MIN (as_cost, sa_cost), 0); + res = add_costs (res, mult_in_op1 ? cost0 : cost1); STRIP_NOPS (multop); if (!is_gimple_val (multop)) @@ -6336,7 +6381,12 @@ create_new_ivs (struct ivopts_data *data, struct iv_ca *set) if (dump_file && (dump_flags & TDF_DETAILS)) { - fprintf (dump_file, "\nSelected IV set: \n"); + fprintf (dump_file, "Selected IV set for loop %d", + data->current_loop->num); + if (data->loop_loc != UNKNOWN_LOCATION) + fprintf (dump_file, " at %s:%d", LOCATION_FILE (data->loop_loc), + LOCATION_LINE (data->loop_loc)); + fprintf (dump_file, ", %lu IVs:\n", bitmap_count_bits (set->cands)); EXECUTE_IF_SET_IN_BITMAP (set->cands, 0, i, bi) { cand = iv_cand (data, i); @@ -6939,11 +6989,16 @@ tree_ssa_iv_optimize_loop (struct ivopts_data *data, struct loop *loop) gcc_assert (!data->niters); data->current_loop = loop; + data->loop_loc = find_loop_location (loop); data->speed = optimize_loop_for_speed_p (loop); if (dump_file && (dump_flags & TDF_DETAILS)) { - fprintf (dump_file, "Processing loop %d\n", loop->num); + fprintf (dump_file, "Processing loop %d", loop->num); + if (data->loop_loc != UNKNOWN_LOCATION) + fprintf (dump_file, " at %s:%d", LOCATION_FILE (data->loop_loc), + LOCATION_LINE (data->loop_loc)); + fprintf (dump_file, "\n"); if (exit) { diff --git a/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c b/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c index a6779585b7..7f6c451c0c 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.c @@ -1563,10 +1563,11 @@ simplify_replace_tree (tree expr, tree old, tree new_tree) } /* Expand definitions of ssa names in EXPR as long as they are simple - enough, and return the new expression. */ + enough, and return the new expression. If STOP is specified, stop + expanding if EXPR equals to it. */ tree -expand_simple_operations (tree expr) +expand_simple_operations (tree expr, tree stop) { unsigned i, n; tree ret = NULL_TREE, e, ee, e1; @@ -1586,7 +1587,7 @@ expand_simple_operations (tree expr) for (i = 0; i < n; i++) { e = TREE_OPERAND (expr, i); - ee = expand_simple_operations (e); + ee = expand_simple_operations (e, stop); if (e == ee) continue; @@ -1605,7 +1606,8 @@ expand_simple_operations (tree expr) return ret; } - if (TREE_CODE (expr) != SSA_NAME) + /* Stop if it's not ssa name or the one we don't want to expand. */ + if (TREE_CODE (expr) != SSA_NAME || expr == stop) return expr; stmt = SSA_NAME_DEF_STMT (expr); @@ -1625,7 +1627,7 @@ expand_simple_operations (tree expr) && src->loop_father != dest->loop_father) return expr; - return expand_simple_operations (e); + return expand_simple_operations (e, stop); } if (gimple_code (stmt) != GIMPLE_ASSIGN) return expr; @@ -1645,7 +1647,7 @@ expand_simple_operations (tree expr) return e; if (code == SSA_NAME) - return expand_simple_operations (e); + return expand_simple_operations (e, stop); return expr; } @@ -1654,7 +1656,7 @@ expand_simple_operations (tree expr) { CASE_CONVERT: /* Casts are simple. */ - ee = expand_simple_operations (e); + ee = expand_simple_operations (e, stop); return fold_build1 (code, TREE_TYPE (expr), ee); case PLUS_EXPR: @@ -1669,7 +1671,7 @@ expand_simple_operations (tree expr) if (!is_gimple_min_invariant (e1)) return expr; - ee = expand_simple_operations (e); + ee = expand_simple_operations (e, stop); return fold_build2 (code, TREE_TYPE (expr), ee, e1); default: diff --git a/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.h b/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.h index 2b0c2d3909..7134906dd8 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.h +++ b/contrib/gcc-5.0/gcc/tree-ssa-loop-niter.h @@ -20,7 +20,7 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_TREE_SSA_LOOP_NITER_H #define GCC_TREE_SSA_LOOP_NITER_H -extern tree expand_simple_operations (tree); +extern tree expand_simple_operations (tree, tree = NULL); extern bool loop_only_exit_p (const struct loop *, const_edge); extern bool number_of_iterations_exit (struct loop *, edge, struct tree_niter_desc *niter, bool, diff --git a/contrib/gcc-5.0/gcc/tree-ssa-pre.c b/contrib/gcc-5.0/gcc/tree-ssa-pre.c index 32cd74dd3b..83b48df8b4 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-pre.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-pre.c @@ -4406,6 +4406,7 @@ eliminate_dom_walker::before_dom_children (basic_block b) cgraph_node::get (fn)->name ()); } gimple_call_set_fndecl (call_stmt, fn); + maybe_remove_unused_call_args (cfun, call_stmt); gimple_set_modified (stmt, true); } } diff --git a/contrib/gcc-5.0/gcc/tree-ssa-sccvn.c b/contrib/gcc-5.0/gcc/tree-ssa-sccvn.c index 25c67d01a7..e417a1536e 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-sccvn.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-sccvn.c @@ -1352,7 +1352,7 @@ fully_constant_vn_reference_p (vn_reference_t ref) || TYPE_PRECISION (ref->type) % BITS_PER_UNIT == 0)) { HOST_WIDE_INT off = 0; - HOST_WIDE_INT size = tree_to_shwi (TYPE_SIZE (ref->type)); + HOST_WIDE_INT size = TYPE_PRECISION (ref->type); if (size % BITS_PER_UNIT != 0 || size > MAX_BITSIZE_MODE_ANY_MODE) return NULL_TREE; @@ -1606,7 +1606,7 @@ vn_reference_lookup_or_insert_for_pieces (tree vuse, va_heap> operands, tree value) { - struct vn_reference_s vr1; + vn_reference_s vr1; vn_reference_t result; unsigned value_id; vr1.vuse = vuse; @@ -2816,7 +2816,8 @@ set_ssa_val_to (tree from, tree to) } gcc_assert (to != NULL_TREE - && (TREE_CODE (to) == SSA_NAME + && ((TREE_CODE (to) == SSA_NAME + && (to == from || SSA_VAL (to) == to)) || is_gimple_min_invariant (to))); if (from != to) @@ -3122,6 +3123,9 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt) tree vuse = gimple_vuse (stmt); tree vdef = gimple_vdef (stmt); + if (TREE_CODE (op) == SSA_NAME) + op = SSA_VAL (op); + /* First we want to lookup using the *vuses* from the store and see if there the last store to this location with the same address had the same value. @@ -3144,8 +3148,6 @@ visit_reference_op_store (tree lhs, tree op, gimple stmt) { if (TREE_CODE (result) == SSA_NAME) result = SSA_VAL (result); - if (TREE_CODE (op) == SSA_NAME) - op = SSA_VAL (op); resultsame = expressions_equal_p (result, op); } @@ -3722,7 +3724,7 @@ visit_use (tree use) changed = set_ssa_val_to (lhs, simplified); if (gimple_vdef (stmt)) changed |= set_ssa_val_to (gimple_vdef (stmt), - gimple_vuse (stmt)); + SSA_VAL (gimple_vuse (stmt))); goto done; } else if (simplified @@ -3731,7 +3733,7 @@ visit_use (tree use) changed = visit_copy (lhs, simplified); if (gimple_vdef (stmt)) changed |= set_ssa_val_to (gimple_vdef (stmt), - gimple_vuse (stmt)); + SSA_VAL (gimple_vuse (stmt))); goto done; } else diff --git a/contrib/gcc-5.0/gcc/tree-ssa-threadedge.c b/contrib/gcc-5.0/gcc/tree-ssa-threadedge.c index 9e10e446bc..4f839910a8 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-threadedge.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-threadedge.c @@ -61,6 +61,7 @@ along with GCC; see the file COPYING3. If not see #include "langhooks.h" #include "params.h" #include "tree-ssa-threadedge.h" +#include "tree-ssa-loop.h" #include "builtins.h" #include "cfg.h" #include "cfganal.h" @@ -1006,7 +1007,8 @@ static int max_threaded_paths; static void fsm_find_control_statement_thread_paths (tree expr, hash_set *visited_phis, - vec *&path) + vec *&path, + bool seen_loop_phi) { tree var = SSA_NAME_VAR (expr); gimple def_stmt = SSA_NAME_DEF_STMT (expr); @@ -1030,6 +1032,14 @@ fsm_find_control_statement_thread_paths (tree expr, int next_path_length = 0; basic_block last_bb_in_path = path->last (); + if (loop_containing_stmt (phi)->header == gimple_bb (phi)) + { + /* Do not walk through more than one loop PHI node. */ + if (seen_loop_phi) + return; + seen_loop_phi = true; + } + /* Following the chain of SSA_NAME definitions, we jumped from a definition in LAST_BB_IN_PATH to a definition in VAR_BB. When these basic blocks are different, append to PATH the blocks from LAST_BB_IN_PATH to VAR_BB. */ @@ -1090,7 +1100,9 @@ fsm_find_control_statement_thread_paths (tree expr, { vec_safe_push (path, bbi); /* Recursively follow SSA_NAMEs looking for a constant definition. */ - fsm_find_control_statement_thread_paths (arg, visited_phis, path); + fsm_find_control_statement_thread_paths (arg, visited_phis, path, + seen_loop_phi); + path->pop (); continue; } @@ -1357,7 +1369,8 @@ thread_through_normal_block (edge e, hash_set *visited_phis = new hash_set; max_threaded_paths = PARAM_VALUE (PARAM_MAX_FSM_THREAD_PATHS); - fsm_find_control_statement_thread_paths (cond, visited_phis, bb_path); + fsm_find_control_statement_thread_paths (cond, visited_phis, bb_path, + false); delete visited_phis; vec_free (bb_path); diff --git a/contrib/gcc-5.0/gcc/tree-ssa-uninit.c b/contrib/gcc-5.0/gcc/tree-ssa-uninit.c index d04c185cc8..19a3e8231f 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-uninit.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-uninit.c @@ -820,7 +820,7 @@ dump_predicates (gimple usestmt, pred_chain_union preds, { size_t i, j; pred_chain one_pred_chain = vNULL; - fprintf (dump_file, msg); + fprintf (dump_file, "%s", msg); print_gimple_stmt (dump_file, usestmt, 0, 0); fprintf (dump_file, "is guarded by :\n\n"); size_t num_preds = preds.length (); diff --git a/contrib/gcc-5.0/gcc/tree-ssa.c b/contrib/gcc-5.0/gcc/tree-ssa.c index 5bf64476be..10d3314558 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa.c +++ b/contrib/gcc-5.0/gcc/tree-ssa.c @@ -1561,6 +1561,8 @@ execute_update_addresses_taken (void) TREE_TYPE (other), TREE_OPERAND (lhs, 0)); gimple load = gimple_build_assign (other, lrhs); + location_t loc = gimple_location (stmt); + gimple_set_location (load, loc); gimple_set_vuse (load, gimple_vuse (stmt)); gsi_insert_before (&gsi, load, GSI_SAME_STMT); gimple_assign_set_lhs (stmt, TREE_OPERAND (lhs, 0)); diff --git a/contrib/gcc-5.0/gcc/tree-stdarg.c b/contrib/gcc-5.0/gcc/tree-stdarg.c index 883c692e8c..2cf0ca3ec8 100644 --- a/contrib/gcc-5.0/gcc/tree-stdarg.c +++ b/contrib/gcc-5.0/gcc/tree-stdarg.c @@ -856,22 +856,23 @@ pass_stdarg::execute (function *fun) /* For va_list_simple_ptr, we have to check PHI nodes too. We treat them as assignments for the purpose of escape analysis. This is not needed for non-simple va_list because virtual phis don't perform - any real data movement. */ - if (va_list_simple_ptr) - { - tree lhs, rhs; - use_operand_p uop; - ssa_op_iter soi; + any real data movement. Also, check PHI nodes for taking address of + the va_list vars. */ + tree lhs, rhs; + use_operand_p uop; + ssa_op_iter soi; - for (gphi_iterator i = gsi_start_phis (bb); !gsi_end_p (i); - gsi_next (&i)) - { - gphi *phi = i.phi (); - lhs = PHI_RESULT (phi); + for (gphi_iterator i = gsi_start_phis (bb); !gsi_end_p (i); + gsi_next (&i)) + { + gphi *phi = i.phi (); + lhs = PHI_RESULT (phi); - if (virtual_operand_p (lhs)) - continue; + if (virtual_operand_p (lhs)) + continue; + if (va_list_simple_ptr) + { FOR_EACH_PHI_ARG (uop, phi, soi, SSA_OP_USE) { rhs = USE_FROM_PTR (uop); @@ -894,6 +895,22 @@ pass_stdarg::execute (function *fun) } } } + + for (unsigned j = 0; !va_list_escapes + && j < gimple_phi_num_args (phi); ++j) + if ((!va_list_simple_ptr + || TREE_CODE (gimple_phi_arg_def (phi, j)) != SSA_NAME) + && walk_tree (gimple_phi_arg_def_ptr (phi, j), + find_va_list_reference, &wi, NULL)) + { + if (dump_file && (dump_flags & TDF_DETAILS)) + { + fputs ("va_list escapes in ", dump_file); + print_gimple_stmt (dump_file, phi, 0, dump_flags); + fputc ('\n', dump_file); + } + va_list_escapes = true; + } } for (gimple_stmt_iterator i = gsi_start_bb (bb); @@ -916,8 +933,8 @@ pass_stdarg::execute (function *fun) if (is_gimple_assign (stmt)) { - tree lhs = gimple_assign_lhs (stmt); - tree rhs = gimple_assign_rhs1 (stmt); + lhs = gimple_assign_lhs (stmt); + rhs = gimple_assign_rhs1 (stmt); if (va_list_simple_ptr) { diff --git a/contrib/gcc-5.0/gcc/tree-streamer-in.c b/contrib/gcc-5.0/gcc/tree-streamer-in.c index 96f4adaced..506e676f56 100644 --- a/contrib/gcc-5.0/gcc/tree-streamer-in.c +++ b/contrib/gcc-5.0/gcc/tree-streamer-in.c @@ -123,7 +123,7 @@ streamer_read_chain (struct lto_input_block *ib, struct data_in *data_in) /* Unpack all the non-pointer fields of the TS_BASE structure of expression EXPR from bitpack BP. */ -static void +static inline void unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr) { /* Note that the code for EXPR has already been unpacked to create EXPR in @@ -158,6 +158,8 @@ unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr) TREE_STATIC (expr) = (unsigned) bp_unpack_value (bp, 1); if (TREE_CODE (expr) != TREE_BINFO) TREE_PRIVATE (expr) = (unsigned) bp_unpack_value (bp, 1); + else + bp_unpack_value (bp, 1); TREE_PROTECTED (expr) = (unsigned) bp_unpack_value (bp, 1); TREE_DEPRECATED (expr) = (unsigned) bp_unpack_value (bp, 1); if (TYPE_P (expr)) @@ -166,9 +168,12 @@ unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr) TYPE_ADDR_SPACE (expr) = (unsigned) bp_unpack_value (bp, 8); } else if (TREE_CODE (expr) == SSA_NAME) - SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1); + { + SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1); + bp_unpack_value (bp, 8); + } else - bp_unpack_value (bp, 1); + bp_unpack_value (bp, 9); } @@ -456,117 +461,102 @@ unpack_ts_omp_clause_value_fields (struct data_in *data_in, } } -/* Unpack all the non-pointer fields in EXPR into a bit pack. */ -static void -unpack_value_fields (struct data_in *data_in, struct bitpack_d *bp, tree expr) +/* Read all the language-independent bitfield values for EXPR from IB. + Return the partially unpacked bitpack so the caller can unpack any other + bitfield values that the writer may have written. */ + +void +streamer_read_tree_bitfields (struct lto_input_block *ib, + struct data_in *data_in, tree expr) { enum tree_code code; + struct bitpack_d bp; - code = TREE_CODE (expr); + /* Read the bitpack of non-pointer values from IB. */ + bp = streamer_read_bitpack (ib); + + /* The first word in BP contains the code of the tree that we + are about to read. */ + code = (enum tree_code) bp_unpack_value (&bp, 16); + lto_tag_check (lto_tree_code_to_tag (code), + lto_tree_code_to_tag (TREE_CODE (expr))); /* Note that all these functions are highly sensitive to changes in the types and sizes of each of the fields being packed. */ - unpack_ts_base_value_fields (bp, expr); + unpack_ts_base_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_INT_CST)) - unpack_ts_int_cst_value_fields (bp, expr); + unpack_ts_int_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST)) - unpack_ts_real_cst_value_fields (bp, expr); + unpack_ts_real_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST)) - unpack_ts_fixed_cst_value_fields (bp, expr); + unpack_ts_fixed_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) - DECL_SOURCE_LOCATION (expr) = stream_input_location (bp, data_in); + DECL_SOURCE_LOCATION (expr) = stream_input_location (&bp, data_in); if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) - unpack_ts_decl_common_value_fields (bp, expr); + unpack_ts_decl_common_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)) - unpack_ts_decl_wrtl_value_fields (bp, expr); + unpack_ts_decl_wrtl_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) - unpack_ts_decl_with_vis_value_fields (bp, expr); + unpack_ts_decl_with_vis_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL)) - unpack_ts_function_decl_value_fields (bp, expr); + unpack_ts_function_decl_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON)) - unpack_ts_type_common_value_fields (bp, expr); + unpack_ts_type_common_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_EXP)) { - SET_EXPR_LOCATION (expr, stream_input_location (bp, data_in)); + SET_EXPR_LOCATION (expr, stream_input_location (&bp, data_in)); if (code == MEM_REF || code == TARGET_MEM_REF) { MR_DEPENDENCE_CLIQUE (expr) - = (unsigned)bp_unpack_value (bp, sizeof (short) * 8); + = (unsigned)bp_unpack_value (&bp, sizeof (short) * 8); if (MR_DEPENDENCE_CLIQUE (expr) != 0) MR_DEPENDENCE_BASE (expr) - = (unsigned)bp_unpack_value (bp, sizeof (short) * 8); + = (unsigned)bp_unpack_value (&bp, sizeof (short) * 8); } } if (CODE_CONTAINS_STRUCT (code, TS_BLOCK)) - unpack_ts_block_value_fields (data_in, bp, expr); + unpack_ts_block_value_fields (data_in, &bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL)) - unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr); + unpack_ts_translation_unit_decl_value_fields (data_in, &bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION)) - cl_optimization_stream_in (bp, TREE_OPTIMIZATION (expr)); + cl_optimization_stream_in (&bp, TREE_OPTIMIZATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_BINFO)) { - unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (bp); + unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (&bp); if (length > 0) vec_safe_grow (BINFO_BASE_ACCESSES (expr), length); } if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) { - unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (bp); + unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (&bp); if (length > 0) vec_safe_grow (CONSTRUCTOR_ELTS (expr), length); } #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)); #endif if (code == OMP_CLAUSE) - unpack_ts_omp_clause_value_fields (data_in, bp, expr); -} - - -/* Read all the language-independent bitfield values for EXPR from IB. - Return the partially unpacked bitpack so the caller can unpack any other - bitfield values that the writer may have written. */ - -struct bitpack_d -streamer_read_tree_bitfields (struct lto_input_block *ib, - struct data_in *data_in, tree expr) -{ - enum tree_code code; - struct bitpack_d bp; - - /* Read the bitpack of non-pointer values from IB. */ - bp = streamer_read_bitpack (ib); - - /* The first word in BP contains the code of the tree that we - are about to read. */ - code = (enum tree_code) bp_unpack_value (&bp, 16); - lto_tag_check (lto_tree_code_to_tag (code), - lto_tree_code_to_tag (TREE_CODE (expr))); - - /* Unpack all the value fields from BP. */ - unpack_value_fields (data_in, &bp, expr); - - return bp; + unpack_ts_omp_clause_value_fields (data_in, &bp, expr); } diff --git a/contrib/gcc-5.0/gcc/tree-streamer-out.c b/contrib/gcc-5.0/gcc/tree-streamer-out.c index 3669680ae9..36102ed32a 100644 --- a/contrib/gcc-5.0/gcc/tree-streamer-out.c +++ b/contrib/gcc-5.0/gcc/tree-streamer-out.c @@ -92,7 +92,7 @@ write_identifier (struct output_block *ob, /* Pack all the non-pointer fields of the TS_BASE structure of expression EXPR into bitpack BP. */ -static void +static inline void pack_ts_base_value_fields (struct bitpack_d *bp, tree expr) { bp_pack_value (bp, TREE_CODE (expr), 16); @@ -129,6 +129,8 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, TREE_STATIC (expr), 1); if (TREE_CODE (expr) != TREE_BINFO) bp_pack_value (bp, TREE_PRIVATE (expr), 1); + else + bp_pack_value (bp, 0, 1); bp_pack_value (bp, TREE_PROTECTED (expr), 1); bp_pack_value (bp, TREE_DEPRECATED (expr), 1); if (TYPE_P (expr)) @@ -137,9 +139,12 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr) bp_pack_value (bp, TYPE_ADDR_SPACE (expr), 8); } else if (TREE_CODE (expr) == SSA_NAME) - bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1); + { + bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1); + bp_pack_value (bp, 0, 8); + } else - bp_pack_value (bp, 0, 1); + bp_pack_value (bp, 0, 9); } @@ -417,78 +422,80 @@ pack_ts_omp_clause_value_fields (struct output_block *ob, /* Pack all the bitfields in EXPR into a bit pack. */ void -streamer_pack_tree_bitfields (struct output_block *ob, - struct bitpack_d *bp, tree expr) +streamer_write_tree_bitfields (struct output_block *ob, tree expr) { + bitpack_d bp = bitpack_create (ob->main_stream); enum tree_code code; code = TREE_CODE (expr); /* Note that all these functions are highly sensitive to changes in the types and sizes of each of the fields being packed. */ - pack_ts_base_value_fields (bp, expr); + pack_ts_base_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_INT_CST)) - pack_ts_int_cst_value_fields (bp, expr); + pack_ts_int_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST)) - pack_ts_real_cst_value_fields (bp, expr); + pack_ts_real_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST)) - pack_ts_fixed_cst_value_fields (bp, expr); + pack_ts_fixed_cst_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL)) - stream_output_location (ob, bp, DECL_SOURCE_LOCATION (expr)); + stream_output_location (ob, &bp, DECL_SOURCE_LOCATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON)) - pack_ts_decl_common_value_fields (bp, expr); + pack_ts_decl_common_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL)) - pack_ts_decl_wrtl_value_fields (bp, expr); + pack_ts_decl_wrtl_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS)) - pack_ts_decl_with_vis_value_fields (bp, expr); + pack_ts_decl_with_vis_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL)) - pack_ts_function_decl_value_fields (bp, expr); + pack_ts_function_decl_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON)) - pack_ts_type_common_value_fields (bp, expr); + pack_ts_type_common_value_fields (&bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_EXP)) { - stream_output_location (ob, bp, EXPR_LOCATION (expr)); + stream_output_location (ob, &bp, EXPR_LOCATION (expr)); if (code == MEM_REF || code == TARGET_MEM_REF) { - bp_pack_value (bp, MR_DEPENDENCE_CLIQUE (expr), sizeof (short) * 8); + bp_pack_value (&bp, MR_DEPENDENCE_CLIQUE (expr), sizeof (short) * 8); if (MR_DEPENDENCE_CLIQUE (expr) != 0) - bp_pack_value (bp, MR_DEPENDENCE_BASE (expr), sizeof (short) * 8); + bp_pack_value (&bp, MR_DEPENDENCE_BASE (expr), sizeof (short) * 8); } } if (CODE_CONTAINS_STRUCT (code, TS_BLOCK)) - pack_ts_block_value_fields (ob, bp, expr); + pack_ts_block_value_fields (ob, &bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL)) - pack_ts_translation_unit_decl_value_fields (ob, bp, expr); + pack_ts_translation_unit_decl_value_fields (ob, &bp, expr); if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION)) - cl_optimization_stream_out (bp, TREE_OPTIMIZATION (expr)); + cl_optimization_stream_out (&bp, TREE_OPTIMIZATION (expr)); if (CODE_CONTAINS_STRUCT (code, TS_BINFO)) - bp_pack_var_len_unsigned (bp, vec_safe_length (BINFO_BASE_ACCESSES (expr))); + bp_pack_var_len_unsigned (&bp, vec_safe_length (BINFO_BASE_ACCESSES (expr))); if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR)) - bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr)); + bp_pack_var_len_unsigned (&bp, CONSTRUCTOR_NELTS (expr)); if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION) /* Don't stream these when passing things to a different target. */ && !lto_stream_offload_p) - cl_target_option_stream_out (ob, bp, TREE_TARGET_OPTION (expr)); + cl_target_option_stream_out (ob, &bp, TREE_TARGET_OPTION (expr)); if (code == OMP_CLAUSE) - pack_ts_omp_clause_value_fields (ob, bp, expr); + pack_ts_omp_clause_value_fields (ob, &bp, expr); + + streamer_write_bitpack (&bp); } diff --git a/contrib/gcc-5.0/gcc/tree-streamer.h b/contrib/gcc-5.0/gcc/tree-streamer.h index 9c150f5216..7680620685 100644 --- a/contrib/gcc-5.0/gcc/tree-streamer.h +++ b/contrib/gcc-5.0/gcc/tree-streamer.h @@ -77,16 +77,15 @@ tree streamer_alloc_tree (struct lto_input_block *, struct data_in *, void streamer_read_tree_body (struct lto_input_block *, struct data_in *, tree); tree streamer_get_pickled_tree (struct lto_input_block *, struct data_in *); tree streamer_get_builtin_tree (struct lto_input_block *, struct data_in *); -struct bitpack_d streamer_read_tree_bitfields (struct lto_input_block *, - struct data_in *, tree); +void streamer_read_tree_bitfields (struct lto_input_block *, + struct data_in *, tree); /* In tree-streamer-out.c. */ void streamer_write_string_cst (struct output_block *, struct lto_output_stream *, tree); void streamer_write_chain (struct output_block *, tree, bool); void streamer_write_tree_header (struct output_block *, tree); -void streamer_pack_tree_bitfields (struct output_block *, struct bitpack_d *, - tree); +void streamer_write_tree_bitfields (struct output_block *, tree); void streamer_write_tree_body (struct output_block *, tree, bool); void streamer_write_integer_cst (struct output_block *, tree, bool); void streamer_write_builtin (struct output_block *, tree); diff --git a/contrib/gcc-5.0/gcc/tree-vect-data-refs.c b/contrib/gcc-5.0/gcc/tree-vect-data-refs.c index 302f2df2af..2c74060d79 100644 --- a/contrib/gcc-5.0/gcc/tree-vect-data-refs.c +++ b/contrib/gcc-5.0/gcc/tree-vect-data-refs.c @@ -1184,10 +1184,13 @@ vect_peeling_hash_get_lowest_cost (_vect_peel_info **slot, } single_iter_cost = vect_get_single_scalar_iteration_cost (loop_vinfo); - outside_cost += vect_get_known_peeling_cost (loop_vinfo, elem->npeel, - &dummy, single_iter_cost, - &prologue_cost_vec, - &epilogue_cost_vec); + outside_cost += vect_get_known_peeling_cost + (loop_vinfo, elem->npeel, &dummy, + /* ??? We use this cost as number of stmts with scalar_stmt cost, + thus divide by that. This introduces rounding errors, thus better + introduce a new cost kind (raw_cost? scalar_iter_cost?). */ + single_iter_cost / vect_get_stmt_cost (scalar_stmt), + &prologue_cost_vec, &epilogue_cost_vec); /* Prologue and epilogue costs are added to the target model later. These costs depend only on the scalar iteration cost, the diff --git a/contrib/gcc-5.0/gcc/tree-vect-loop.c b/contrib/gcc-5.0/gcc/tree-vect-loop.c index c5f1c29cbe..3e7c701e63 100644 --- a/contrib/gcc-5.0/gcc/tree-vect-loop.c +++ b/contrib/gcc-5.0/gcc/tree-vect-loop.c @@ -2834,6 +2834,11 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, statements. */ scalar_single_iter_cost = vect_get_single_scalar_iteration_cost (loop_vinfo); + /* ??? Below we use this cost as number of stmts with scalar_stmt cost, + thus divide by that. This introduces rounding errors, thus better + introduce a new cost kind (raw_cost? scalar_iter_cost?). */ + int scalar_single_iter_stmts + = scalar_single_iter_cost / vect_get_stmt_cost (scalar_stmt); /* Add additional cost for the peeled instructions in prologue and epilogue loop. @@ -2868,10 +2873,10 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, /* FORNOW: Don't attempt to pass individual scalar instructions to the model; just assume linear cost for scalar iterations. */ (void) add_stmt_cost (target_cost_data, - peel_iters_prologue * scalar_single_iter_cost, + peel_iters_prologue * scalar_single_iter_stmts, scalar_stmt, NULL, 0, vect_prologue); (void) add_stmt_cost (target_cost_data, - peel_iters_epilogue * scalar_single_iter_cost, + peel_iters_epilogue * scalar_single_iter_stmts, scalar_stmt, NULL, 0, vect_epilogue); } else @@ -2887,7 +2892,7 @@ vect_estimate_min_profitable_iters (loop_vec_info loop_vinfo, (void) vect_get_known_peeling_cost (loop_vinfo, peel_iters_prologue, &peel_iters_epilogue, - scalar_single_iter_cost, + scalar_single_iter_stmts, &prologue_cost_vec, &epilogue_cost_vec); diff --git a/contrib/gcc-5.0/gcc/tree-vrp.c b/contrib/gcc-5.0/gcc/tree-vrp.c index ef1c21db97..dad1830e9a 100644 --- a/contrib/gcc-5.0/gcc/tree-vrp.c +++ b/contrib/gcc-5.0/gcc/tree-vrp.c @@ -7096,7 +7096,8 @@ vrp_valueize_1 (tree name) this SSA edge as the SSA propagator does not necessarily re-visit the use. */ gimple def_stmt = SSA_NAME_DEF_STMT (name); - if (prop_simulate_again_p (def_stmt)) + if (!gimple_nop_p (def_stmt) + && prop_simulate_again_p (def_stmt)) return NULL_TREE; value_range_t *vr = get_value_range (name); if (range_int_cst_singleton_p (vr)) diff --git a/contrib/gcc-5.0/gcc/ubsan.c b/contrib/gcc-5.0/gcc/ubsan.c index 036e67e787..fc3352f994 100644 --- a/contrib/gcc-5.0/gcc/ubsan.c +++ b/contrib/gcc-5.0/gcc/ubsan.c @@ -987,7 +987,7 @@ ubsan_expand_objsize_ifn (gimple_stmt_iterator *gsi) /* Get rid of the UBSAN_OBJECT_SIZE call from the IR. */ unlink_stmt_vdef (stmt); gsi_remove (&gsi_orig, true); - return gsi_end_p (*gsi); + return true; } /* Cached __ubsan_vptr_type_cache decl. */ @@ -1148,7 +1148,7 @@ ubsan_expand_vptr_ifn (gimple_stmt_iterator *gsip) /* Get rid of the UBSAN_VPTR call from the IR. */ unlink_stmt_vdef (stmt); gsi_remove (&gsi, true); - return gsi_end_p (*gsip); + return true; } /* Instrument a memory reference. BASE is the base of MEM, IS_LHS says diff --git a/contrib/gcc-5.0/gcc/varasm.c b/contrib/gcc-5.0/gcc/varasm.c index 2069432ad9..0211306dba 100644 --- a/contrib/gcc-5.0/gcc/varasm.c +++ b/contrib/gcc-5.0/gcc/varasm.c @@ -5601,6 +5601,7 @@ do_assemble_alias (tree decl, tree target) id = DECL_ASSEMBLER_NAME (decl); ultimate_transparent_alias_target (&id); + ultimate_transparent_alias_target (&target); /* We must force creation of DECL_RTL for debug info generation, even though we don't use it here. */ @@ -5612,8 +5613,6 @@ do_assemble_alias (tree decl, tree target) if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))) { - ultimate_transparent_alias_target (&target); - if (!TREE_SYMBOL_REFERENCED (target)) weakref_targets = tree_cons (decl, target, weakref_targets); @@ -5944,8 +5943,12 @@ default_assemble_visibility (tree decl ATTRIBUTE_UNUSED, }; const char *name, *type; + tree id; + + id = DECL_ASSEMBLER_NAME (decl); + ultimate_transparent_alias_target (&id); + name = IDENTIFIER_POINTER (id); - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); type = visibility_types[vis]; fprintf (asm_out_file, "\t.%s\t", type); @@ -6799,97 +6802,96 @@ resolution_local_p (enum ld_plugin_symbol_resolution resolution) || resolution == LDPR_RESOLVED_EXEC); } -/* Assume ELF-ish defaults, since that's pretty much the most liberal - wrt cross-module name binding. */ - -bool -default_binds_local_p (const_tree exp) -{ - return default_binds_local_p_1 (exp, flag_shlib); -} - -bool -default_binds_local_p_1 (const_tree exp, int shlib) +static bool +default_binds_local_p_2 (const_tree exp, bool shlib, bool weak_dominate) { - bool local_p; - bool resolved_locally = false; - bool resolved_to_local_def = false; - - /* With resolution file in hands, take look into resolutions. - We can't just return true for resolved_locally symbols, - because dynamic linking might overwrite symbols - in shared libraries. */ - if (TREE_CODE (exp) == VAR_DECL && TREE_PUBLIC (exp) - && (TREE_STATIC (exp) || DECL_EXTERNAL (exp))) - { - varpool_node *vnode = varpool_node::get (exp); - if (vnode && (resolution_local_p (vnode->resolution) || vnode->in_other_partition)) - resolved_locally = true; - if (vnode - && resolution_to_local_definition_p (vnode->resolution)) - resolved_to_local_def = true; - } - else if (TREE_CODE (exp) == FUNCTION_DECL && TREE_PUBLIC (exp)) - { - struct cgraph_node *node = cgraph_node::get (exp); - if (node - && (resolution_local_p (node->resolution) || node->in_other_partition)) - resolved_locally = true; - if (node - && resolution_to_local_definition_p (node->resolution)) - resolved_to_local_def = true; - } - /* A non-decl is an entry in the constant pool. */ if (!DECL_P (exp)) - local_p = true; + return true; + /* Weakrefs may not bind locally, even though the weakref itself is always static and therefore local. Similarly, the resolver for ifunc functions might resolve to a non-local function. FIXME: We can resolve the weakref case more curefuly by looking at the weakref alias. */ - else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp)) + if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp)) || (TREE_CODE (exp) == FUNCTION_DECL && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp)))) - local_p = false; + return false; + /* Static variables are always local. */ - else if (! TREE_PUBLIC (exp)) - local_p = true; - /* A variable is local if the user has said explicitly that it will - be. */ - else if ((DECL_VISIBILITY_SPECIFIED (exp) - || resolved_to_local_def) - && DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) - local_p = true; - /* Variables defined outside this object might not be local. */ - else if (DECL_EXTERNAL (exp) && !resolved_locally) - local_p = false; - /* If defined in this object and visibility is not default, must be - local. */ - else if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT) - local_p = true; - /* Default visibility weak data can be overridden by a strong symbol - in another module and so are not local. */ - else if (DECL_WEAK (exp) - && !resolved_locally) - local_p = false; + if (! TREE_PUBLIC (exp)) + return true; + + /* With resolution file in hand, take look into resolutions. + We can't just return true for resolved_locally symbols, + because dynamic linking might overwrite symbols + in shared libraries. */ + bool resolved_locally = false; + bool defined_locally = false; + if (symtab_node *node = symtab_node::get (exp)) + { + if (node->definition || node->in_other_partition) + { + defined_locally = true; + resolved_locally = (weak_dominate && !shlib); + } + if (resolution_to_local_definition_p (node->resolution)) + defined_locally = resolved_locally = true; + else if (resolution_local_p (node->resolution)) + resolved_locally = true; + } + + /* Undefined weak symbols are never defined locally. */ + if (DECL_WEAK (exp) && !defined_locally) + return false; + + /* A symbol is local if the user has said explicitly that it will be, + or if we have a definition for the symbol. We cannot infer visibility + for undefined symbols. */ + if (DECL_VISIBILITY (exp) != VISIBILITY_DEFAULT + && (DECL_VISIBILITY_SPECIFIED (exp) || defined_locally)) + return true; + /* If PIC, then assume that any global name can be overridden by symbols resolved from other modules. */ - else if (shlib) - local_p = false; + if (shlib) + return false; + + /* Variables defined outside this object might not be local. */ + if (DECL_EXTERNAL (exp) && !resolved_locally) + return false; + + /* Non-dominant weak symbols are not defined locally. */ + if (DECL_WEAK (exp) && !resolved_locally) + return false; + /* Uninitialized COMMON variable may be unified with symbols resolved from other modules. */ - else if (DECL_COMMON (exp) - && !resolved_locally - && (DECL_INITIAL (exp) == NULL - || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node))) - local_p = false; + if (DECL_COMMON (exp) + && !resolved_locally + && (DECL_INITIAL (exp) == NULL + || (!in_lto_p && DECL_INITIAL (exp) == error_mark_node))) + return false; + /* Otherwise we're left with initialized (or non-common) global data which is of necessity defined locally. */ - else - local_p = true; + return true; +} + +/* Assume ELF-ish defaults, since that's pretty much the most liberal + wrt cross-module name binding. */ + +bool +default_binds_local_p (const_tree exp) +{ + return default_binds_local_p_2 (exp, flag_shlib != 0, true); +} - return local_p; +bool +default_binds_local_p_1 (const_tree exp, int shlib) +{ + return default_binds_local_p_2 (exp, shlib != 0, false); } /* Return true when references to DECL must bind to current definition in @@ -6911,22 +6913,14 @@ decl_binds_to_current_def_p (const_tree decl) return false; if (!TREE_PUBLIC (decl)) return true; + /* When resolution is available, just use it. */ - if (TREE_CODE (decl) == VAR_DECL - && (TREE_STATIC (decl) || DECL_EXTERNAL (decl))) - { - varpool_node *vnode = varpool_node::get (decl); - if (vnode - && vnode->resolution != LDPR_UNKNOWN) - return resolution_to_local_definition_p (vnode->resolution); - } - else if (TREE_CODE (decl) == FUNCTION_DECL) + if (symtab_node *node = symtab_node::get (decl)) { - struct cgraph_node *node = cgraph_node::get (decl); - if (node - && node->resolution != LDPR_UNKNOWN) + if (node->resolution != LDPR_UNKNOWN) return resolution_to_local_definition_p (node->resolution); } + /* Otherwise we have to assume the worst for DECL_WEAK (hidden weaks binds locally but still can be overwritten), DECL_COMMON (can be merged with a non-common definition somewhere in the same module) or @@ -7177,6 +7171,10 @@ place_block_symbol (rtx symbol) { rtx target = DECL_RTL (snode->ultimate_alias_target ()->decl); + gcc_assert (MEM_P (target) + && GET_CODE (XEXP (target, 0)) == SYMBOL_REF + && SYMBOL_REF_HAS_BLOCK_INFO_P (XEXP (target, 0))); + target = XEXP (target, 0); place_block_symbol (target); SYMBOL_REF_BLOCK_OFFSET (symbol) = SYMBOL_REF_BLOCK_OFFSET (target); return; @@ -7442,9 +7440,10 @@ default_elf_asm_output_external (FILE *file ATTRIBUTE_UNUSED, { /* We output the name if and only if TREE_SYMBOL_REFERENCED is set in order to avoid putting out names that are never really - used. */ + used. Always output visibility specified in the source. */ if (TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) - && targetm.binds_local_p (decl)) + && (DECL_VISIBILITY_SPECIFIED (decl) + || targetm.binds_local_p (decl))) maybe_assemble_visibility (decl); } diff --git a/contrib/gcc-5.0/gcc/varpool.c b/contrib/gcc-5.0/gcc/varpool.c index 3bd6eb41b7..49a921331d 100644 --- a/contrib/gcc-5.0/gcc/varpool.c +++ b/contrib/gcc-5.0/gcc/varpool.c @@ -195,7 +195,6 @@ void varpool_node::remove (void) { symtab->call_varpool_removal_hooks (this); - unregister (); /* When streaming we can have multiple nodes associated with decl. */ if (symtab->state == LTO_STREAMING) @@ -205,6 +204,8 @@ varpool_node::remove (void) else if (DECL_INITIAL (decl) && DECL_INITIAL (decl) != error_mark_node && !ctor_useable_for_folding_p ()) remove_initializer (); + + unregister (); ggc_free (this); } diff --git a/contrib/gcc-5.0/gcc/xcoffout.h b/contrib/gcc-5.0/gcc/xcoffout.h index ad714f2e0b..41b6554abf 100644 --- a/contrib/gcc-5.0/gcc/xcoffout.h +++ b/contrib/gcc-5.0/gcc/xcoffout.h @@ -161,8 +161,11 @@ do { \ /* Do not emit any marker for XCOFF until assembler allows XFT_CV. */ #define NO_DBX_GCC_MARKER -/* Do not break .stabs pseudos into continuations. */ -#define DBX_CONTIN_LENGTH 0 +/* XCOFF32 maximum length is 64K; XLC limits to 16K. */ +#define DBX_CONTIN_LENGTH 16384 + +/* XLC uses '?' as continuation character. */ +#define DBX_CONTIN_CHAR '?' /* Don't try to use the `x' type-cross-reference character in DBX data. Also has the consequence of putting each struct, union or enum diff --git a/contrib/gcc-5.0/include/dwarf2.h b/contrib/gcc-5.0/include/dwarf2.h index ca440dd42b..e05955cad4 100644 --- a/contrib/gcc-5.0/include/dwarf2.h +++ b/contrib/gcc-5.0/include/dwarf2.h @@ -312,6 +312,8 @@ enum dwarf_source_language DW_LANG_C_plus_plus_11 = 0x001a, /* dwarf5.20141029.pdf DRAFT */ DW_LANG_C11 = 0x001d, DW_LANG_C_plus_plus_14 = 0x0021, + DW_LANG_Fortran03 = 0x0022, + DW_LANG_Fortran08 = 0x0023, DW_LANG_lo_user = 0x8000, /* Implementation-defined range start. */ DW_LANG_hi_user = 0xffff, /* Implementation-defined range start. */ diff --git a/contrib/gcc-5.0/libcpp/internal.h b/contrib/gcc-5.0/libcpp/internal.h index 1a7402079c..96ccc19e44 100644 --- a/contrib/gcc-5.0/libcpp/internal.h +++ b/contrib/gcc-5.0/libcpp/internal.h @@ -421,6 +421,11 @@ struct cpp_reader macro invocation. */ source_location invocation_location; + /* This is the node representing the macro being expanded at + top-level. The value of this data member is valid iff + in_macro_expansion_p() returns TRUE. */ + cpp_hashnode *top_most_macro_node; + /* Nonzero if we are about to expand a macro. Note that if we are really expanding a macro, the function macro_of_context returns the macro being expanded and this flag is set to false. Client diff --git a/contrib/gcc-5.0/libcpp/macro.c b/contrib/gcc-5.0/libcpp/macro.c index 95713450c2..1e0a0b560b 100644 --- a/contrib/gcc-5.0/libcpp/macro.c +++ b/contrib/gcc-5.0/libcpp/macro.c @@ -1228,7 +1228,24 @@ enter_macro_context (cpp_reader *pfile, cpp_hashnode *node, pfile->about_to_expand_macro_p = false; /* Handle built-in macros and the _Pragma operator. */ - return builtin_macro (pfile, node, location); + { + source_location loc; + if (/* The top-level macro invocation that triggered the expansion + we are looking at is with a standard macro ...*/ + !(pfile->top_most_macro_node->flags & NODE_BUILTIN) + /* ... and it's a function-like macro invocation. */ + && pfile->top_most_macro_node->value.macro->fun_like) + /* Then the location of the end of the macro invocation is the + location of the closing parenthesis. */ + loc = pfile->cur_token[-1].src_loc; + else + /* Otherwise, the location of the end of the macro invocation is + the location of the expansion point of that top-level macro + invocation. */ + loc = location; + + return builtin_macro (pfile, node, loc); + } } /* De-allocate the memory used by BUFF which is an array of instances @@ -2296,6 +2313,10 @@ _cpp_pop_context (cpp_reader *pfile) macro expansion. */ && macro_of_context (context->prev) != macro) macro->flags &= ~NODE_DISABLED; + + if (macro == pfile->top_most_macro_node && context->prev == NULL) + /* We are popping the context of the top-most macro node. */ + pfile->top_most_macro_node = NULL; } if (context->buff) @@ -2460,9 +2481,13 @@ cpp_get_token_1 (cpp_reader *pfile, source_location *location) { int ret = 0; /* If not in a macro context, and we're going to start an - expansion, record the location. */ + expansion, record the location and the top level macro + about to be expanded. */ if (!in_macro_expansion_p (pfile)) - pfile->invocation_location = result->src_loc; + { + pfile->invocation_location = result->src_loc; + pfile->top_most_macro_node = node; + } if (pfile->state.prevent_expansion) break; diff --git a/contrib/gcc-5.0/libgcc/libgcov-driver-system.c b/contrib/gcc-5.0/libgcc/libgcov-driver-system.c index 56d0800217..94f198dcef 100644 --- a/contrib/gcc-5.0/libgcc/libgcov-driver-system.c +++ b/contrib/gcc-5.0/libgcc/libgcov-driver-system.c @@ -66,6 +66,9 @@ create_file_directory (char *filename) #ifdef TARGET_POSIX_IO && mkdir (filename, 0755) == -1 #else +#ifdef mkdir +#undef mkdir +#endif && mkdir (filename) == -1 #endif /* The directory might have been made by another process. */ diff --git a/contrib/gcc-5.0/libgomp/config/aix/plugin-suffix.h b/contrib/gcc-5.0/libgomp/config/aix/plugin-suffix.h deleted file mode 100644 index 37c192bd38..0000000000 --- a/contrib/gcc-5.0/libgomp/config/aix/plugin-suffix.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright (C) 2015 Free Software Foundation, Inc. - Contributed by Jack Howarth - - This file is part of the GNU Offloading and Multi Processing Library - (libgomp). - - Libgomp is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3, or (at your option) - any later version. - - Libgomp is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS - FOR A PARTICULAR PURPOSE. See the GNU General Public License for - more details. - - Under Section 7 of GPL version 3, you are granted additional - permissions described in the GCC Runtime Library Exception, version - 3.1, as published by the Free Software Foundation. - - You should have received a copy of the GNU General Public License and - a copy of the GCC Runtime Library Exception along with this program; - see the files COPYING3 and COPYING.RUNTIME respectively. If not, see - . */ - -#define SONAME_SUFFIX(n) (".a") diff --git a/contrib/gcc-5.0/libobjc/thr.c b/contrib/gcc-5.0/libobjc/thr.c index f45a752afb..4b16d4b059 100644 --- a/contrib/gcc-5.0/libobjc/thr.c +++ b/contrib/gcc-5.0/libobjc/thr.c @@ -25,11 +25,6 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #include "objc-private/common.h" #include "objc-private/error.h" #define _LIBOBJC -/* The line below is needed for declarations of functions such as - pthread_mutexattr_settype, without which gthr-posix.h may fail to - compile within libobjc. While we only need XPG5 for this, Solaris - requires XPG6 for C99 and later. */ -#define _XOPEN_SOURCE 600 #include "config.h" #include "tconfig.h" #include "coretypes.h" diff --git a/contrib/gcc-5.0/libssp/ssp.c b/contrib/gcc-5.0/libssp/ssp.c index 96adf17ce3..38e3ec83f6 100644 --- a/contrib/gcc-5.0/libssp/ssp.c +++ b/contrib/gcc-5.0/libssp/ssp.c @@ -55,6 +55,7 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see /* Native win32 apps don't know about /dev/tty but can print directly to the console using "CONOUT$" */ #if defined (_WIN32) && !defined (__CYGWIN__) +#include # define _PATH_TTY "CONOUT$" #else # define _PATH_TTY "/dev/tty" @@ -75,6 +76,20 @@ __guard_setup (void) if (__stack_chk_guard != 0) return; +#if defined (_WIN32) && !defined (__CYGWIN__) + HCRYPTPROV hprovider = 0; + if (CryptAcquireContext(&hprovider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) + { + if (CryptGenRandom(hprovider, sizeof (__stack_chk_guard), + (BYTE *)&__stack_chk_guard) && __stack_chk_guard != 0) + { + CryptReleaseContext(hprovider, 0); + return; + } + CryptReleaseContext(hprovider, 0); + } +#else fd = open ("/dev/urandom", O_RDONLY); if (fd != -1) { @@ -85,6 +100,7 @@ __guard_setup (void) return; } +#endif /* If a random generator can't be used, the protector switches the guard to the "terminator canary". */ p = (unsigned char *) &__stack_chk_guard; diff --git a/contrib/gcc-5.0/lto-plugin/lto-plugin.c b/contrib/gcc-5.0/lto-plugin/lto-plugin.c index add83f2c5c..8d957402ba 100644 --- a/contrib/gcc-5.0/lto-plugin/lto-plugin.c +++ b/contrib/gcc-5.0/lto-plugin/lto-plugin.c @@ -145,7 +145,6 @@ static ld_plugin_register_all_symbols_read register_all_symbols_read; static ld_plugin_get_symbols get_symbols, get_symbols_v2; static ld_plugin_register_cleanup register_cleanup; static ld_plugin_add_input_file add_input_file; -static ld_plugin_release_input_file release_input_file; static ld_plugin_add_input_library add_input_library; static ld_plugin_message message; static ld_plugin_add_symbols add_symbols; @@ -1007,9 +1006,6 @@ claim_file_handler (const struct ld_plugin_input_file *file, int *claimed) if (obj.objfile) simple_object_release_read (obj.objfile); - if (release_input_file) - release_input_file (file); - return LDPS_OK; } @@ -1095,9 +1091,6 @@ onload (struct ld_plugin_tv *tv) case LDPT_ADD_INPUT_FILE: add_input_file = p->tv_u.tv_add_input_file; break; - case LDPT_RELEASE_INPUT_FILE: - release_input_file = p->tv_u.tv_release_input_file; - break; case LDPT_ADD_INPUT_LIBRARY: add_input_library = p->tv_u.tv_add_input_library; break; -- 2.41.0