From: John Marino Date: Sat, 18 Jul 2015 01:50:11 +0000 (+0200) Subject: Update gcc-50 to SVN version 225979 (gcc-5-branch) X-Git-Tag: v4.3.1~134^2 X-Git-Url: https://gitweb.dragonflybsd.org/~tuxillo/dragonfly.git/commitdiff_plain/cfea5195dadedcf27c0957cd327d48184c51c8e7 Update gcc-50 to SVN version 225979 (gcc-5-branch) This is equivalent to gcc 5.2 release plus a few additional commits that came through when the gcc-5 branch reopened. Last Changed Date: 2015-07-18 02:16:08 +0200 (Sat, 18 Jul 2015) --- diff --git a/contrib/gcc-5.0/LAST_UPDATED b/contrib/gcc-5.0/LAST_UPDATED index e0c3e33e4c..e47392f0d2 100644 --- a/contrib/gcc-5.0/LAST_UPDATED +++ b/contrib/gcc-5.0/LAST_UPDATED @@ -1,2 +1,2 @@ -223641 -Last Changed Date: 2015-05-25 02:16:10 +0200 (Mon, 25 May 2015) +225979 +Last Changed Date: 2015-07-18 02:16:08 +0200 (Sat, 18 Jul 2015) diff --git a/contrib/gcc-5.0/gcc/BASE-VER b/contrib/gcc-5.0/gcc/BASE-VER index ac14c3dfaa..26d99a283f 100644 --- a/contrib/gcc-5.0/gcc/BASE-VER +++ b/contrib/gcc-5.0/gcc/BASE-VER @@ -1 +1 @@ -5.1.1 +5.2.1 diff --git a/contrib/gcc-5.0/gcc/DATESTAMP b/contrib/gcc-5.0/gcc/DATESTAMP index e6477a174a..66cc981f86 100644 --- a/contrib/gcc-5.0/gcc/DATESTAMP +++ b/contrib/gcc-5.0/gcc/DATESTAMP @@ -1 +1 @@ -20150525 +20150718 diff --git a/contrib/gcc-5.0/gcc/builtins.c b/contrib/gcc-5.0/gcc/builtins.c index 92637771ea..bcbc11d9db 100644 --- a/contrib/gcc-5.0/gcc/builtins.c +++ b/contrib/gcc-5.0/gcc/builtins.c @@ -5915,8 +5915,10 @@ expand_stack_save (void) acceleration device (ACCEL_COMPILER conditional). */ static rtx -expand_builtin_acc_on_device (tree exp, rtx target) +expand_builtin_acc_on_device (tree exp ATTRIBUTE_UNUSED, + rtx target ATTRIBUTE_UNUSED) { +#ifdef ACCEL_COMPILER if (!validate_arglist (exp, INTEGER_TYPE, VOID_TYPE)) return NULL_RTX; @@ -5925,13 +5927,8 @@ expand_builtin_acc_on_device (tree exp, rtx target) /* Return (arg == v1 || arg == v2) ? 1 : 0. */ machine_mode v_mode = TYPE_MODE (TREE_TYPE (arg)); rtx v = expand_normal (arg), v1, v2; -#ifdef ACCEL_COMPILER v1 = GEN_INT (GOMP_DEVICE_NOT_HOST); v2 = GEN_INT (ACCEL_COMPILER_acc_device); -#else - v1 = GEN_INT (GOMP_DEVICE_NONE); - v2 = GEN_INT (GOMP_DEVICE_HOST); -#endif machine_mode target_mode = TYPE_MODE (integer_type_node); if (!target || !register_operand (target, target_mode)) target = gen_reg_rtx (target_mode); @@ -5945,6 +5942,9 @@ expand_builtin_acc_on_device (tree exp, rtx target) emit_label (done_label); return target; +#else + return NULL; +#endif } 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 86a9f54b80..987845ba2c 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-omp.c +++ b/contrib/gcc-5.0/gcc/c-family/c-omp.c @@ -1048,6 +1048,8 @@ c_omp_declare_simd_clauses_to_numbers (tree parms, tree clauses) for (i = 0; i < len; i++) OMP_CLAUSE_CHAIN (clvec[i]) = (i < len - 1) ? clvec[i + 1] : NULL_TREE; } + else + clauses = NULL_TREE; clvec.release (); return clauses; } 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 1a67b5a766..718a05281a 100644 --- a/contrib/gcc-5.0/gcc/c-family/c-opts.c +++ b/contrib/gcc-5.0/gcc/c-family/c-opts.c @@ -889,7 +889,7 @@ c_common_post_options (const char **pfilename) /* 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; + flag_abi_version = 9; if (cxx_dialect >= cxx11) { diff --git a/contrib/gcc-5.0/gcc/c/c-decl.c b/contrib/gcc-5.0/gcc/c/c-decl.c index e28a294dcc..03ce316f06 100644 --- a/contrib/gcc-5.0/gcc/c/c-decl.c +++ b/contrib/gcc-5.0/gcc/c/c-decl.c @@ -1207,6 +1207,7 @@ pop_scope (void) { tree file_decl = build_translation_unit_decl (NULL_TREE); context = file_decl; + debug_hooks->register_main_translation_unit (file_decl); } else context = block; diff --git a/contrib/gcc-5.0/gcc/cgraph.c b/contrib/gcc-5.0/gcc/cgraph.c index 85531c8d0b..852960a817 100644 --- a/contrib/gcc-5.0/gcc/cgraph.c +++ b/contrib/gcc-5.0/gcc/cgraph.c @@ -1281,6 +1281,7 @@ cgraph_edge::redirect_call_stmt_to_callee (void) tree lhs = gimple_call_lhs (e->call_stmt); gcall *new_stmt; gimple_stmt_iterator gsi; + bool skip_bounds = false; #ifdef ENABLE_CHECKING cgraph_node *node; #endif @@ -1389,8 +1390,16 @@ cgraph_edge::redirect_call_stmt_to_callee (void) } } + /* We might propagate instrumented function pointer into + not instrumented function and vice versa. In such a + case we need to either fix function declaration or + remove bounds from call statement. */ + if (flag_check_pointer_bounds && e->callee) + skip_bounds = chkp_redirect_edge (e); + if (e->indirect_unknown_callee - || decl == e->callee->decl) + || (decl == e->callee->decl + && !skip_bounds)) return e->call_stmt; #ifdef ENABLE_CHECKING @@ -1415,13 +1424,19 @@ cgraph_edge::redirect_call_stmt_to_callee (void) } } - if (e->callee->clone.combined_args_to_skip) + if (e->callee->clone.combined_args_to_skip + || skip_bounds) { int lp_nr; - new_stmt - = gimple_call_copy_skip_args (e->call_stmt, - e->callee->clone.combined_args_to_skip); + new_stmt = e->call_stmt; + if (e->callee->clone.combined_args_to_skip) + new_stmt + = gimple_call_copy_skip_args (new_stmt, + e->callee->clone.combined_args_to_skip); + if (skip_bounds) + new_stmt = chkp_copy_call_skip_bounds (new_stmt); + gimple_call_set_fndecl (new_stmt, e->callee->decl); gimple_call_set_fntype (new_stmt, gimple_call_fntype (e->call_stmt)); @@ -3019,6 +3034,20 @@ cgraph_node::verify_node (void) } } + if (instrumentation_clone + && DECL_BUILT_IN_CLASS (decl) == NOT_BUILT_IN) + { + tree name = DECL_ASSEMBLER_NAME (decl); + tree orig_name = DECL_ASSEMBLER_NAME (orig_decl); + + if (!IDENTIFIER_TRANSPARENT_ALIAS (name) + || TREE_CHAIN (name) != orig_name) + { + error ("Alias chain for instrumented node is broken"); + error_found = true; + } + } + if (analyzed && thunk.thunk_p) { if (!callees) diff --git a/contrib/gcc-5.0/gcc/common.opt b/contrib/gcc-5.0/gcc/common.opt index b49ac46610..1218a71fe4 100644 --- a/contrib/gcc-5.0/gcc/common.opt +++ b/contrib/gcc-5.0/gcc/common.opt @@ -833,6 +833,9 @@ 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 and default in G++ 5 +; +; 9: The version of the ABI that corrects the alignment of nullptr_t. +; First selectable and default in G++ 5.2. ; (set in c_common_post_options). ; ; Additional positive integers will be assigned as new versions of @@ -906,7 +909,7 @@ Common Report This switch is deprecated; use -fsanitize-recover= instead fsanitize-undefined-trap-on-error -Common Report Var(flag_sanitize_undefined_trap_on_error) Init(0) +Common Driver Report Var(flag_sanitize_undefined_trap_on_error) Init(0) Use trap instead of a library function for undefined behavior sanitization fasynchronous-unwind-tables diff --git a/contrib/gcc-5.0/gcc/common/config/i386/i386-common.c b/contrib/gcc-5.0/gcc/common/config/i386/i386-common.c index 4e5687ae5a..0f8c3e1df0 100644 --- a/contrib/gcc-5.0/gcc/common/config/i386/i386-common.c +++ b/contrib/gcc-5.0/gcc/common/config/i386/i386-common.c @@ -127,6 +127,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_RDRND_SET OPTION_MASK_ISA_RDRND #define OPTION_MASK_ISA_F16C_SET \ (OPTION_MASK_ISA_F16C | OPTION_MASK_ISA_AVX_SET) +#define OPTION_MASK_ISA_MWAITX_SET OPTION_MASK_ISA_MWAITX /* Define a set of ISAs which aren't available when a given ISA is disabled. MMX and SSE ISAs are handled separately. */ @@ -186,6 +187,7 @@ along with GCC; see the file COPYING3. If not see #define OPTION_MASK_ISA_XSAVES_UNSET OPTION_MASK_ISA_XSAVES #define OPTION_MASK_ISA_PCOMMIT_UNSET OPTION_MASK_ISA_PCOMMIT #define OPTION_MASK_ISA_CLWB_UNSET OPTION_MASK_ISA_CLWB +#define OPTION_MASK_ISA_MWAITX_UNSET OPTION_MASK_ISA_MWAITX /* SSE4 includes both SSE4.1 and SSE4.2. -mno-sse4 should the same as -mno-sse4.1. */ @@ -932,6 +934,19 @@ ix86_handle_option (struct gcc_options *opts, } return true; + case OPT_mmwaitx: + if (value) + { + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MWAITX_SET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MWAITX_SET; + } + else + { + opts->x_ix86_isa_flags &= ~OPTION_MASK_ISA_MWAITX_UNSET; + opts->x_ix86_isa_flags_explicit |= OPTION_MASK_ISA_MWAITX_UNSET; + } + return true; + /* Comes from final.c -- no real reason to change it. */ #define MAX_CODE_ALIGN 16 diff --git a/contrib/gcc-5.0/gcc/config/i386/cpuid.h b/contrib/gcc-5.0/gcc/config/i386/cpuid.h index f931969459..f3ad4dbb8f 100644 --- a/contrib/gcc-5.0/gcc/config/i386/cpuid.h +++ b/contrib/gcc-5.0/gcc/config/i386/cpuid.h @@ -57,6 +57,7 @@ #define bit_LWP (1 << 15) #define bit_FMA4 (1 << 16) #define bit_TBM (1 << 21) +#define bit_MWAITX (1 << 29) /* %edx */ #define bit_MMXEXT (1 << 22) diff --git a/contrib/gcc-5.0/gcc/config/i386/driver-i386.c b/contrib/gcc-5.0/gcc/config/i386/driver-i386.c index c69149d7cb..1c6c22172d 100644 --- a/contrib/gcc-5.0/gcc/config/i386/driver-i386.c +++ b/contrib/gcc-5.0/gcc/config/i386/driver-i386.c @@ -413,7 +413,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) unsigned int has_clflushopt = 0, has_xsavec = 0, has_xsaves = 0; unsigned int has_avx512dq = 0, has_avx512bw = 0, has_avx512vl = 0; unsigned int has_avx512vbmi = 0, has_avx512ifma = 0, has_clwb = 0; - unsigned int has_pcommit = 0; + unsigned int has_pcommit = 0, has_mwaitx = 0; bool arch; @@ -532,6 +532,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) has_longmode = edx & bit_LM; has_3dnowp = edx & bit_3DNOWP; has_3dnow = edx & bit_3DNOW; + has_mwaitx = ecx & bit_MWAITX; } /* Get XCR_XFEATURE_ENABLED_MASK register with xgetbv. */ @@ -953,6 +954,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) const char *avx512vbmi = has_avx512vbmi ? " -mavx512vbmi" : " -mno-avx512vbmi"; const char *clwb = has_clwb ? " -mclwb" : " -mno-clwb"; const char *pcommit = has_pcommit ? " -mpcommit" : " -mno-pcommit"; + const char *mwaitx = has_mwaitx ? " -mmwaitx" : " -mno-mwaitx"; options = concat (options, mmx, mmx3dnow, sse, sse2, sse3, ssse3, sse4a, cx16, sahf, movbe, aes, sha, pclmul, @@ -962,7 +964,7 @@ const char *host_detect_local_cpu (int argc, const char **argv) fxsr, xsave, xsaveopt, avx512f, avx512er, avx512cd, avx512pf, prefetchwt1, clflushopt, xsavec, xsaves, avx512dq, avx512bw, avx512vl, - avx512ifma, avx512vbmi, clwb, pcommit, NULL); + avx512ifma, avx512vbmi, clwb, pcommit, mwaitx, NULL); } done: diff --git a/contrib/gcc-5.0/gcc/config/i386/i386-builtin-types.def b/contrib/gcc-5.0/gcc/config/i386/i386-builtin-types.def index 864d0ea23a..2459c440ba 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386-builtin-types.def +++ b/contrib/gcc-5.0/gcc/config/i386/i386-builtin-types.def @@ -595,6 +595,7 @@ DEF_FUNCTION_TYPE (VOID, PV4DI, V4DI) DEF_FUNCTION_TYPE (VOID, PV4SF, V4SF) DEF_FUNCTION_TYPE (VOID, PV8SF, V8SF) DEF_FUNCTION_TYPE (VOID, UNSIGNED, UNSIGNED) +DEF_FUNCTION_TYPE (VOID, UNSIGNED, UNSIGNED, UNSIGNED) DEF_FUNCTION_TYPE (VOID, PV8DI, V8DI) # Instructions returning mask diff --git a/contrib/gcc-5.0/gcc/config/i386/i386-c.c b/contrib/gcc-5.0/gcc/config/i386/i386-c.c index 03045fb723..f3f90df06e 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386-c.c +++ b/contrib/gcc-5.0/gcc/config/i386/i386-c.c @@ -432,6 +432,8 @@ ix86_target_macros_internal (HOST_WIDE_INT isa_flag, def_or_undef (parse_in, "__PCOMMIT__"); if (isa_flag & OPTION_MASK_ISA_CLWB) def_or_undef (parse_in, "__CLWB__"); + if (isa_flag & OPTION_MASK_ISA_MWAITX) + def_or_undef (parse_in, "__MWAITX__"); } diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.c b/contrib/gcc-5.0/gcc/config/i386/i386.c index 1c842eb9e3..052a9d3bee 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.c +++ b/contrib/gcc-5.0/gcc/config/i386/i386.c @@ -2374,6 +2374,7 @@ static rtx (*ix86_gen_sub3) (rtx, rtx, rtx); static rtx (*ix86_gen_sub3_carry) (rtx, rtx, rtx, rtx, rtx); static rtx (*ix86_gen_one_cmpl2) (rtx, rtx); static rtx (*ix86_gen_monitor) (rtx, rtx, rtx); +static rtx (*ix86_gen_monitorx) (rtx, rtx, rtx); static rtx (*ix86_gen_andsp) (rtx, rtx, rtx); static rtx (*ix86_gen_allocate_stack_worker) (rtx, rtx); static rtx (*ix86_gen_adjust_stack_and_probe) (rtx, rtx, rtx); @@ -2677,6 +2678,7 @@ ix86_target_string (HOST_WIDE_INT isa, int flags, const char *arch, { "-mmpx", OPTION_MASK_ISA_MPX }, { "-mclwb", OPTION_MASK_ISA_CLWB }, { "-mpcommit", OPTION_MASK_ISA_PCOMMIT }, + { "-mmwaitx", OPTION_MASK_ISA_MWAITX }, }; /* Flag options. */ @@ -3190,6 +3192,7 @@ ix86_option_override_internal (bool main_args_p, #define PTA_AVX512VBMI (HOST_WIDE_INT_1 << 54) #define PTA_CLWB (HOST_WIDE_INT_1 << 55) #define PTA_PCOMMIT (HOST_WIDE_INT_1 << 56) +#define PTA_MWAITX (HOST_WIDE_INT_1 << 57) #define PTA_CORE2 \ (PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 \ @@ -3343,7 +3346,7 @@ ix86_option_override_internal (bool main_args_p, | PTA_FMA4 | PTA_XOP | PTA_LWP | PTA_BMI | PTA_BMI2 | PTA_TBM | PTA_F16C | PTA_FMA | PTA_PRFCHW | PTA_FXSR | PTA_XSAVE | PTA_XSAVEOPT | PTA_FSGSBASE | PTA_RDRND - | PTA_MOVBE}, + | PTA_MOVBE | PTA_MWAITX}, {"btver1", PROCESSOR_BTVER1, CPU_GENERIC, PTA_64BIT | PTA_MMX | PTA_SSE | PTA_SSE2 | PTA_SSE3 | PTA_SSSE3 | PTA_SSE4A |PTA_ABM | PTA_CX16 | PTA_PRFCHW @@ -3787,6 +3790,9 @@ ix86_option_override_internal (bool main_args_p, opts->x_ix86_isa_flags |= OPTION_MASK_ISA_AVX512IFMA; if (processor_alias_table[i].flags & (PTA_PREFETCH_SSE | PTA_SSE)) x86_prefetch_sse = true; + if (processor_alias_table[i].flags & PTA_MWAITX + && !(opts->x_ix86_isa_flags_explicit & OPTION_MASK_ISA_MWAITX)) + opts->x_ix86_isa_flags |= OPTION_MASK_ISA_MWAITX; break; } @@ -4217,6 +4223,7 @@ ix86_option_override_internal (bool main_args_p, ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probedi; ix86_gen_probe_stack_range = gen_probe_stack_rangedi; ix86_gen_monitor = gen_sse3_monitor_di; + ix86_gen_monitorx = gen_monitorx_di; } else { @@ -4229,6 +4236,7 @@ ix86_option_override_internal (bool main_args_p, ix86_gen_adjust_stack_and_probe = gen_adjust_stack_and_probesi; ix86_gen_probe_stack_range = gen_probe_stack_rangesi; ix86_gen_monitor = gen_sse3_monitor_si; + ix86_gen_monitorx = gen_monitorx_si; } #ifdef USE_IX86_CLD @@ -4753,6 +4761,7 @@ ix86_valid_target_attribute_inner_p (tree args, char *p_strings[], IX86_ATTR_ISA ("avx512ifma", OPT_mavx512ifma), IX86_ATTR_ISA ("clwb", OPT_mclwb), IX86_ATTR_ISA ("pcommit", OPT_mpcommit), + IX86_ATTR_ISA ("mwaitx", OPT_mmwaitx), /* enum options */ IX86_ATTR_ENUM ("fpmath=", OPT_mfpmath_), @@ -6131,6 +6140,7 @@ bool ix86_function_arg_regno_p (int regno) { int i; + enum calling_abi call_abi; const int *parm_regs; if (TARGET_MPX && BND_REGNO_P (regno)) @@ -6156,16 +6166,18 @@ ix86_function_arg_regno_p (int regno) /* TODO: The function should depend on current function ABI but builtins.c would need updating then. Therefore we use the default ABI. */ + call_abi = ix86_cfun_abi (); /* RAX is used as hidden argument to va_arg functions. */ - if (ix86_abi == SYSV_ABI && regno == AX_REG) + if (call_abi == SYSV_ABI && regno == AX_REG) return true; - if (ix86_abi == MS_ABI) + if (call_abi == MS_ABI) parm_regs = x86_64_ms_abi_int_parameter_registers; else parm_regs = x86_64_int_parameter_registers; - for (i = 0; i < (ix86_abi == MS_ABI + + for (i = 0; i < (call_abi == MS_ABI ? X86_64_MS_REGPARM_MAX : X86_64_REGPARM_MAX); i++) if (regno == parm_regs[i]) return true; @@ -8194,10 +8206,10 @@ ix86_function_value_regno_p (const unsigned int regno) case AX_REG: return true; case DX_REG: - return (!TARGET_64BIT || ix86_abi != MS_ABI); + return (!TARGET_64BIT || ix86_cfun_abi () != MS_ABI); case DI_REG: case SI_REG: - return TARGET_64BIT && ix86_abi != MS_ABI; + return TARGET_64BIT && ix86_cfun_abi () != MS_ABI; case FIRST_BND_REG: return chkp_function_instrumented_p (current_function_decl); @@ -8208,7 +8220,7 @@ ix86_function_value_regno_p (const unsigned int regno) /* TODO: The function should depend on current function ABI but builtins.c would need updating then. Therefore we use the default ABI. */ - if (TARGET_64BIT && ix86_abi == MS_ABI) + if (TARGET_64BIT && ix86_cfun_abi () == MS_ABI) return false; return TARGET_FLOAT_RETURNS_IN_80387; @@ -22990,7 +23002,7 @@ ix86_split_long_move (rtx operands[]) Do an lea to the last part and use only one colliding move. */ else if (collisions > 1) { - rtx base; + rtx base, addr, tls_base = NULL_RTX; collisions = 1; @@ -23001,10 +23013,50 @@ ix86_split_long_move (rtx operands[]) if (GET_MODE (base) != Pmode) base = gen_rtx_REG (Pmode, REGNO (base)); - emit_insn (gen_rtx_SET (VOIDmode, base, XEXP (part[1][0], 0))); + addr = XEXP (part[1][0], 0); + if (TARGET_TLS_DIRECT_SEG_REFS) + { + struct ix86_address parts; + int ok = ix86_decompose_address (addr, &parts); + gcc_assert (ok); + if (parts.seg == DEFAULT_TLS_SEG_REG) + { + /* It is not valid to use %gs: or %fs: in + lea though, so we need to remove it from the + address used for lea and add it to each individual + memory loads instead. */ + addr = copy_rtx (addr); + rtx *x = &addr; + while (GET_CODE (*x) == PLUS) + { + for (i = 0; i < 2; i++) + { + rtx u = XEXP (*x, i); + if (GET_CODE (u) == ZERO_EXTEND) + u = XEXP (u, 0); + if (GET_CODE (u) == UNSPEC + && XINT (u, 1) == UNSPEC_TP) + { + tls_base = XEXP (*x, i); + *x = XEXP (*x, 1 - i); + break; + } + } + if (tls_base) + break; + x = &XEXP (*x, 0); + } + gcc_assert (tls_base); + } + } + emit_insn (gen_rtx_SET (VOIDmode, base, addr)); + if (tls_base) + base = gen_rtx_PLUS (GET_MODE (base), base, tls_base); part[1][0] = replace_equiv_address (part[1][0], base); for (i = 1; i < nparts; i++) { + if (tls_base) + base = copy_rtx (base); tmp = plus_constant (Pmode, base, UNITS_PER_WORD * i); part[1][i] = replace_equiv_address (part[1][i], tmp); } @@ -30628,6 +30680,10 @@ enum ix86_builtins IX86_BUILTIN_CVTPS2PH, IX86_BUILTIN_CVTPS2PH256, + /* MONITORX and MWAITX instrucions. */ + IX86_BUILTIN_MONITORX, + IX86_BUILTIN_MWAITX, + /* CFString built-in for darwin */ IX86_BUILTIN_CFSTRING, @@ -34246,6 +34302,12 @@ ix86_init_mmx_sse_builtins (void) def_builtin (OPTION_MASK_ISA_CLWB, "__builtin_ia32_clwb", VOID_FTYPE_PCVOID, IX86_BUILTIN_CLWB); + /* MONITORX and MWAITX. */ + def_builtin (OPTION_MASK_ISA_MWAITX, "__builtin_ia32_monitorx", + VOID_FTYPE_PCVOID_UNSIGNED_UNSIGNED, IX86_BUILTIN_MONITORX); + def_builtin (OPTION_MASK_ISA_MWAITX, "__builtin_ia32_mwaitx", + VOID_FTYPE_UNSIGNED_UNSIGNED_UNSIGNED, IX86_BUILTIN_MWAITX); + /* Add FMA4 multi-arg argument instructions */ for (i = 0, d = bdesc_multi_arg; i < ARRAY_SIZE (bdesc_multi_arg); i++, d++) { @@ -39018,6 +39080,7 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, return 0; case IX86_BUILTIN_MONITOR: + case IX86_BUILTIN_MONITORX: arg0 = CALL_EXPR_ARG (exp, 0); arg1 = CALL_EXPR_ARG (exp, 1); arg2 = CALL_EXPR_ARG (exp, 2); @@ -39030,7 +39093,10 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, op1 = copy_to_mode_reg (SImode, op1); if (!REG_P (op2)) op2 = copy_to_mode_reg (SImode, op2); - emit_insn (ix86_gen_monitor (op0, op1, op2)); + + emit_insn (fcode == IX86_BUILTIN_MONITOR + ? ix86_gen_monitor (op0, op1, op2) + : ix86_gen_monitorx (op0, op1, op2)); return 0; case IX86_BUILTIN_MWAIT: @@ -39045,6 +39111,22 @@ ix86_expand_builtin (tree exp, rtx target, rtx subtarget, emit_insn (gen_sse3_mwait (op0, op1)); return 0; + case IX86_BUILTIN_MWAITX: + arg0 = CALL_EXPR_ARG (exp, 0); + arg1 = CALL_EXPR_ARG (exp, 1); + arg2 = CALL_EXPR_ARG (exp, 2); + op0 = expand_normal (arg0); + op1 = expand_normal (arg1); + op2 = expand_normal (arg2); + if (!REG_P (op0)) + op0 = copy_to_mode_reg (SImode, op0); + if (!REG_P (op1)) + op1 = copy_to_mode_reg (SImode, op1); + if (!REG_P (op2)) + op2 = copy_to_mode_reg (SImode, op2); + emit_insn (gen_mwaitx (op0, op1, op2)); + return 0; + case IX86_BUILTIN_VEC_INIT_V2SI: case IX86_BUILTIN_VEC_INIT_V4HI: case IX86_BUILTIN_VEC_INIT_V8QI: @@ -44787,6 +44869,8 @@ ix86_expand_vector_set (bool mmx_ok, rtx target, rtx val, int elt) { gen_vec_set_lo_v4df, gen_vec_set_hi_v4df } }; int i, j, n; + machine_mode mmode = VOIDmode; + rtx (*gen_blendm) (rtx, rtx, rtx, rtx); switch (mode) { @@ -45003,81 +45087,65 @@ half: case V8DFmode: if (TARGET_AVX512F) { - tmp = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, tmp, - gen_rtx_VEC_DUPLICATE (mode, val))); - emit_insn (gen_avx512f_blendmv8df (target, tmp, target, - force_reg (QImode, GEN_INT (1 << elt)))); - return; + mmode = QImode; + gen_blendm = gen_avx512f_blendmv8df; } - else - break; + break; + case V8DImode: if (TARGET_AVX512F) { - tmp = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, tmp, - gen_rtx_VEC_DUPLICATE (mode, val))); - emit_insn (gen_avx512f_blendmv8di (target, tmp, target, - force_reg (QImode, GEN_INT (1 << elt)))); - return; + mmode = QImode; + gen_blendm = gen_avx512f_blendmv8di; } - else - break; + break; + case V16SFmode: if (TARGET_AVX512F) { - tmp = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, tmp, - gen_rtx_VEC_DUPLICATE (mode, val))); - emit_insn (gen_avx512f_blendmv16sf (target, tmp, target, - force_reg (HImode, GEN_INT (1 << elt)))); - return; + mmode = HImode; + gen_blendm = gen_avx512f_blendmv16si; } - else - break; + break; + case V16SImode: if (TARGET_AVX512F) { - tmp = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, tmp, - gen_rtx_VEC_DUPLICATE (mode, val))); - emit_insn (gen_avx512f_blendmv16si (target, tmp, target, - force_reg (HImode, GEN_INT (1 << elt)))); - return; + mmode = HImode; + gen_blendm = gen_avx512f_blendmv16si; } - else - break; + break; + case V32HImode: if (TARGET_AVX512F && TARGET_AVX512BW) { - tmp = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, tmp, - gen_rtx_VEC_DUPLICATE (mode, val))); - emit_insn (gen_avx512bw_blendmv32hi (target, tmp, target, - force_reg (SImode, GEN_INT (1 << elt)))); - return; + mmode = SImode; + gen_blendm = gen_avx512bw_blendmv32hi; } - else - break; + break; + case V64QImode: if (TARGET_AVX512F && TARGET_AVX512BW) { - tmp = gen_reg_rtx (mode); - emit_insn (gen_rtx_SET (VOIDmode, tmp, - gen_rtx_VEC_DUPLICATE (mode, val))); - emit_insn (gen_avx512bw_blendmv64qi (target, tmp, target, - force_reg (DImode, GEN_INT (1 << elt)))); - return; + mmode = DImode; + gen_blendm = gen_avx512bw_blendmv64qi; } - else - break; + break; default: break; } - if (use_vec_merge) + if (mmode != VOIDmode) + { + tmp = gen_reg_rtx (mode); + emit_insn (gen_rtx_SET (VOIDmode, tmp, + gen_rtx_VEC_DUPLICATE (mode, val))); + emit_insn (gen_blendm (target, tmp, target, + force_reg (mmode, + gen_int_mode (1 << elt, mmode)))); + } + else if (use_vec_merge) { tmp = gen_rtx_VEC_DUPLICATE (mode, val); tmp = gen_rtx_VEC_MERGE (mode, tmp, target, GEN_INT (1 << elt)); @@ -50267,15 +50335,20 @@ ix86_expand_pinsr (rtx *operands) unsigned int size = INTVAL (operands[1]); unsigned int pos = INTVAL (operands[2]); + if (GET_CODE (src) == SUBREG) + { + /* Reject non-lowpart subregs. */ + if (SUBREG_BYTE (src) != 0) + return false; + src = SUBREG_REG (src); + } + if (GET_CODE (dst) == SUBREG) { pos += SUBREG_BYTE (dst) * BITS_PER_UNIT; dst = SUBREG_REG (dst); } - if (GET_CODE (src) == SUBREG) - src = SUBREG_REG (src); - switch (GET_MODE (dst)) { case V16QImode: diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.h b/contrib/gcc-5.0/gcc/config/i386/i386.h index 6741e9cde2..de43f06bef 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.h +++ b/contrib/gcc-5.0/gcc/config/i386/i386.h @@ -154,6 +154,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #define TARGET_PCOMMIT_P(x) TARGET_ISA_PCOMMIT_P(x) #define TARGET_CLWB TARGET_ISA_CLWB #define TARGET_CLWB_P(x) TARGET_ISA_CLWB_P(x) +#define TARGET_MWAITX TARGET_ISA_MWAITX +#define TARGET_MWAITX_P(x) TARGET_ISA_MWAITX_P(x) #define TARGET_LP64 TARGET_ABI_64 #define TARGET_LP64_P(x) TARGET_ABI_64_P(x) diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.md b/contrib/gcc-5.0/gcc/config/i386/i386.md index e1c82fefc0..2937293333 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.md +++ b/contrib/gcc-5.0/gcc/config/i386/i386.md @@ -261,6 +261,11 @@ ;; For CLFLUSHOPT support UNSPECV_CLFLUSHOPT + + ;; For MONITORX and MWAITX support + UNSPECV_MONITORX + UNSPECV_MWAITX + ]) ;; Constants to represent rounding modes in the ROUND instruction @@ -5046,11 +5051,11 @@ /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). Assemble the 64-bit DImode value in an xmm register. */ emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, operands[1], 0))); + gen_lowpart (SImode, operands[1]))); emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, operands[1], 4))); + gen_highpart (SImode, operands[1]))); emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3], - operands[4])); + operands[4])); operands[3] = gen_rtx_REG (DImode, REGNO (operands[3])); }) @@ -10843,6 +10848,7 @@ [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (zero_extend:DI (match_dup 2)))] { + operands[1] = shallow_copy_rtx (operands[1]); PUT_MODE (operands[1], QImode); operands[2] = gen_lowpart (QImode, operands[0]); }) @@ -10860,6 +10866,7 @@ (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2))) (clobber (reg:CC FLAGS_REG))])] { + operands[1] = shallow_copy_rtx (operands[1]); PUT_MODE (operands[1], QImode); operands[2] = gen_lowpart (QImode, operands[0]); }) @@ -10875,6 +10882,7 @@ [(set (match_dup 2) (match_dup 1)) (set (match_dup 0) (zero_extend:SI (match_dup 2)))] { + operands[1] = shallow_copy_rtx (operands[1]); PUT_MODE (operands[1], QImode); operands[2] = gen_lowpart (QImode, operands[0]); }) @@ -10912,7 +10920,10 @@ (const_int 0)))] "" [(set (match_dup 0) (match_dup 1))] - "PUT_MODE (operands[1], QImode);") +{ + operands[1] = shallow_copy_rtx (operands[1]); + PUT_MODE (operands[1], QImode); +}) (define_split [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand")) @@ -10921,7 +10932,10 @@ (const_int 0)))] "" [(set (match_dup 0) (match_dup 1))] - "PUT_MODE (operands[1], QImode);") +{ + operands[1] = shallow_copy_rtx (operands[1]); + PUT_MODE (operands[1], QImode); +}) (define_split [(set (match_operand:QI 0 "nonimmediate_operand") @@ -10931,15 +10945,15 @@ "" [(set (match_dup 0) (match_dup 1))] { - rtx new_op1 = copy_rtx (operands[1]); - operands[1] = new_op1; - PUT_MODE (new_op1, QImode); - PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), - GET_MODE (XEXP (new_op1, 0)))); + operands[1] = shallow_copy_rtx (operands[1]); + PUT_MODE (operands[1], QImode); + PUT_CODE (operands[1], + ix86_reverse_condition (GET_CODE (operands[1]), + GET_MODE (XEXP (operands[1], 0)))); /* Make sure that (a) the CCmode we have for the flags is strong enough for the reversed compare or (b) we have a valid FP compare. */ - if (! ix86_comparison_operator (new_op1, VOIDmode)) + if (! ix86_comparison_operator (operands[1], VOIDmode)) FAIL; }) @@ -10951,15 +10965,15 @@ "" [(set (match_dup 0) (match_dup 1))] { - rtx new_op1 = copy_rtx (operands[1]); - operands[1] = new_op1; - PUT_MODE (new_op1, QImode); - PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1), - GET_MODE (XEXP (new_op1, 0)))); + operands[1] = shallow_copy_rtx (operands[1]); + PUT_MODE (operands[1], QImode); + PUT_CODE (operands[1], + ix86_reverse_condition (GET_CODE (operands[1]), + GET_MODE (XEXP (operands[1], 0)))); /* Make sure that (a) the CCmode we have for the flags is strong enough for the reversed compare or (b) we have a valid FP compare. */ - if (! ix86_comparison_operator (new_op1, VOIDmode)) + if (! ix86_comparison_operator (operands[1], VOIDmode)) FAIL; }) @@ -11078,7 +11092,10 @@ (if_then_else (match_dup 0) (label_ref (match_dup 1)) (pc)))] - "PUT_MODE (operands[0], VOIDmode);") +{ + operands[0] = shallow_copy_rtx (operands[0]); + PUT_MODE (operands[0], VOIDmode); +}) (define_split [(set (pc) @@ -11093,15 +11110,15 @@ (label_ref (match_dup 1)) (pc)))] { - rtx new_op0 = copy_rtx (operands[0]); - operands[0] = new_op0; - PUT_MODE (new_op0, VOIDmode); - PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0), - GET_MODE (XEXP (new_op0, 0)))); + operands[0] = shallow_copy_rtx (operands[0]); + PUT_MODE (operands[0], VOIDmode); + PUT_CODE (operands[0], + ix86_reverse_condition (GET_CODE (operands[0]), + GET_MODE (XEXP (operands[0], 0)))); /* Make sure that (a) the CCmode we have for the flags is strong enough for the reversed compare or (b) we have a valid FP compare. */ - if (! ix86_comparison_operator (new_op0, VOIDmode)) + if (! ix86_comparison_operator (operands[0], VOIDmode)) FAIL; }) @@ -11138,7 +11155,7 @@ (pc)))] { operands[2] = simplify_gen_subreg (mode, operands[2], QImode, 0); - + operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) @@ -11171,7 +11188,7 @@ (pc)))] { operands[2] = simplify_gen_subreg (mode, operands[2], SImode, 0); - + operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) @@ -11207,7 +11224,7 @@ (pc)))] { operands[2] = simplify_gen_subreg (mode, operands[2], SImode, 0); - + operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) @@ -11239,7 +11256,7 @@ (pc)))] { operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); - + operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) @@ -11275,7 +11292,10 @@ (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)]) (label_ref (match_dup 4)) (pc)))] - "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));") +{ + operands[0] = shallow_copy_rtx (operands[0]); + PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); +}) ;; Define combination compare-and-branch fp compare instructions to help ;; combine. @@ -17241,6 +17261,7 @@ operands[1] = gen_lowpart (SImode, operands[1]); if (GET_CODE (operands[3]) != ASHIFT) operands[2] = gen_lowpart (SImode, operands[2]); + operands[3] = shallow_copy_rtx (operands[3]); PUT_MODE (operands[3], SImode); }) @@ -17410,8 +17431,8 @@ ;; lifetime information then. (define_peephole2 - [(set (match_operand:SWI124 0 "nonimmediate_operand") - (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))] + [(set (match_operand:SWI124 0 "nonimmediate_gr_operand") + (not:SWI124 (match_operand:SWI124 1 "nonimmediate_gr_operand")))] "optimize_insn_for_speed_p () && ((TARGET_NOT_UNPAIRABLE && (!MEM_P (operands[0]) @@ -17555,8 +17576,10 @@ [(match_dup 0) (match_operand 2 "memory_operand")]))] "REGNO (operands[0]) != REGNO (operands[1]) - && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) - || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))" + && ((MMX_REGNO_P (REGNO (operands[0])) + && MMX_REGNO_P (REGNO (operands[1]))) + || (SSE_REGNO_P (REGNO (operands[0])) + && SSE_REGNO_P (REGNO (operands[1]))))" [(set (match_dup 0) (match_dup 2)) (set (match_dup 0) (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]) @@ -17704,7 +17727,7 @@ (match_operand 1 "const0_operand"))] "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ()) - && GENERAL_REG_P (operands[0]) + && GENERAL_REGNO_P (REGNO (operands[0])) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 0) (const_int 0)) (clobber (reg:CC FLAGS_REG))])] @@ -17725,6 +17748,7 @@ [(set (match_operand:SWI248 0 "register_operand") (const_int -1))] "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR) + && GENERAL_REGNO_P (REGNO (operands[0])) && peep2_regno_dead_p (0, FLAGS_REG)" [(parallel [(set (match_dup 0) (const_int -1)) (clobber (reg:CC FLAGS_REG))])] @@ -18092,11 +18116,13 @@ operands[1] = gen_rtx_PLUS (word_mode, base, gen_rtx_MULT (word_mode, index, GEN_INT (scale))); - operands[5] = base; if (mode != word_mode) operands[1] = gen_rtx_SUBREG (mode, operands[1], 0); + + operands[5] = base; if (op1mode != word_mode) - operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0); + operands[5] = gen_lowpart (op1mode, operands[5]); + operands[0] = dest; }) @@ -18847,6 +18873,32 @@ (set_attr "atom_sse_attr" "fence") (set_attr "memory" "unknown")]) +;; MONITORX and MWAITX +(define_insn "mwaitx" + [(unspec_volatile [(match_operand:SI 0 "register_operand" "c") + (match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "register_operand" "b")] + UNSPECV_MWAITX)] + "TARGET_MWAITX" +;; 64bit version is "mwaitx %rax,%rcx,%rbx". But only lower 32bits are used. +;; Since 32bit register operands are implicitly zero extended to 64bit, +;; we only need to set up 32bit registers. + "mwaitx" + [(set_attr "length" "3")]) + +(define_insn "monitorx_" + [(unspec_volatile [(match_operand:P 0 "register_operand" "a") + (match_operand:SI 1 "register_operand" "c") + (match_operand:SI 2 "register_operand" "d")] + UNSPECV_MONITORX)] + "TARGET_MWAITX" +;; 64bit version is "monitorx %rax,%rcx,%rdx". But only lower 32bits in +;; RCX and RDX are used. Since 32bit register operands are implicitly +;; zero extended to 64bit, we only need to set up 32bit registers. + "%^monitorx" + [(set (attr "length") + (symbol_ref ("(Pmode != word_mode) + 3")))]) + ;; MPX instructions (define_expand "_mk" diff --git a/contrib/gcc-5.0/gcc/config/i386/i386.opt b/contrib/gcc-5.0/gcc/config/i386/i386.opt index 301430c238..dd46e26de3 100644 --- a/contrib/gcc-5.0/gcc/config/i386/i386.opt +++ b/contrib/gcc-5.0/gcc/config/i386/i386.opt @@ -859,6 +859,10 @@ mmpx Target Report Mask(ISA_MPX) Var(ix86_isa_flags) Save Support MPX code generation +mmwaitx +Target Report Mask(ISA_MWAITX) Var(ix86_isa_flags) Save +Support MWAITX and MONITORX built-in functions and code generation + mstack-protector-guard= Target RejectNegative Joined Enum(stack_protector_guard) Var(ix86_stack_protector_guard) Init(SSP_TLS) Use given stack-protector guard diff --git a/contrib/gcc-5.0/gcc/config/i386/x86intrin.h b/contrib/gcc-5.0/gcc/config/i386/mwaitxintrin.h similarity index 50% copy from contrib/gcc-5.0/gcc/config/i386/x86intrin.h copy to contrib/gcc-5.0/gcc/config/i386/mwaitxintrin.h index a51188679e..d7112dad20 100644 --- a/contrib/gcc-5.0/gcc/config/i386/x86intrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/mwaitxintrin.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008-2015 Free Software Foundation, Inc. +/* Copyright (C) 2012-2015 Free Software Foundation, Inc. This file is part of GCC. @@ -21,68 +21,30 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see . */ -#ifndef _X86INTRIN_H_INCLUDED -#define _X86INTRIN_H_INCLUDED - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -/* For including AVX instructions */ -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#include - -#endif /* _X86INTRIN_H_INCLUDED */ +#ifndef _MWAITXINTRIN_H_INCLUDED +#define _MWAITXINTRIN_H_INCLUDED + +#ifndef __MWAITX__ +#pragma GCC push_options +#pragma GCC target("mwaitx") +#define __DISABLE_MWAITX__ +#endif /* __MWAITX__ */ + +extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_monitorx (void const * __P, unsigned int __E, unsigned int __H) +{ + __builtin_ia32_monitorx (__P, __E, __H); +} + +extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__)) +_mm_mwaitx (unsigned int __E, unsigned int __H, unsigned int __C) +{ + __builtin_ia32_mwaitx (__E, __H, __C); +} + +#ifdef __DISABLE_MWAITX__ +#undef __DISABLE_MWAITX__ +#pragma GCC pop_options +#endif /* __DISABLE_MWAITX__ */ + +#endif /* _MWAITXINTRIN_H_INCLUDED */ diff --git a/contrib/gcc-5.0/gcc/config/i386/predicates.md b/contrib/gcc-5.0/gcc/config/i386/predicates.md index 0f314ccb0e..f0c999cb18 100644 --- a/contrib/gcc-5.0/gcc/config/i386/predicates.md +++ b/contrib/gcc-5.0/gcc/config/i386/predicates.md @@ -37,6 +37,12 @@ (and (match_code "reg") (match_test "GENERAL_REG_P (op)"))) +;; True if the operand is a nonimmediate operand with GENERAL class register. +(define_predicate "nonimmediate_gr_operand" + (if_then_else (match_code "reg") + (match_test "GENERAL_REGNO_P (REGNO (op))") + (match_operand 0 "nonimmediate_operand"))) + ;; Return true if OP is a register operand other than an i387 fp register. (define_predicate "register_and_not_fp_reg_operand" (and (match_code "reg") diff --git a/contrib/gcc-5.0/gcc/config/i386/sse.md b/contrib/gcc-5.0/gcc/config/i386/sse.md index 8dbf3d119c..2873535369 100644 --- a/contrib/gcc-5.0/gcc/config/i386/sse.md +++ b/contrib/gcc-5.0/gcc/config/i386/sse.md @@ -1078,9 +1078,9 @@ /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax). Assemble the 64-bit DImode value in an xmm register. */ emit_insn (gen_sse2_loadld (operands[0], CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, operands[1], 0))); + gen_lowpart (SImode, operands[1]))); emit_insn (gen_sse2_loadld (operands[2], CONST0_RTX (V4SImode), - gen_rtx_SUBREG (SImode, operands[1], 4))); + gen_highpart (SImode, operands[1]))); emit_insn (gen_vec_interleave_lowv4si (operands[0], operands[0], operands[2])); } @@ -13161,10 +13161,12 @@ (set_attr "atom_sse_attr" "fence") (set_attr "memory" "unknown")]) - +;; As per AMD and Intel ISA manuals, the first operand is extensions +;; and it goes to %ecx. The second operand received is hints and it goes +;; to %eax. (define_insn "sse3_mwait" - [(unspec_volatile [(match_operand:SI 0 "register_operand" "a") - (match_operand:SI 1 "register_operand" "c")] + [(unspec_volatile [(match_operand:SI 0 "register_operand" "c") + (match_operand:SI 1 "register_operand" "a")] UNSPECV_MWAIT)] "TARGET_SSE3" ;; 64bit version is "mwait %rax,%rcx". But only lower 32bits are used. diff --git a/contrib/gcc-5.0/gcc/config/i386/x86intrin.h b/contrib/gcc-5.0/gcc/config/i386/x86intrin.h index a51188679e..6f7b1f66a6 100644 --- a/contrib/gcc-5.0/gcc/config/i386/x86intrin.h +++ b/contrib/gcc-5.0/gcc/config/i386/x86intrin.h @@ -85,4 +85,5 @@ #include +#include #endif /* _X86INTRIN_H_INCLUDED */ diff --git a/contrib/gcc-5.0/gcc/cp/call.c b/contrib/gcc-5.0/gcc/cp/call.c index 31d2b9c2c9..949225b18f 100644 --- a/contrib/gcc-5.0/gcc/cp/call.c +++ b/contrib/gcc-5.0/gcc/cp/call.c @@ -910,9 +910,7 @@ build_aggr_conv (tree type, tree ctor, int flags, tsubst_flags_t complain) tree field = next_initializable_field (TYPE_FIELDS (type)); tree empty_ctor = NULL_TREE; - ctor = reshape_init (type, ctor, tf_none); - if (ctor == error_mark_node) - return NULL; + /* We already called reshape_init in implicit_conversion. */ /* The conversions within the init-list aren't affected by the enclosing context; they're always simple copy-initialization. */ @@ -1801,6 +1799,18 @@ implicit_conversion (tree to, tree from, tree expr, bool c_cast_p, to that conversion. */ complain &= ~tf_error; + /* Call reshape_init early to remove redundant braces. */ + if (expr && BRACE_ENCLOSED_INITIALIZER_P (expr) + && CLASS_TYPE_P (to) + && COMPLETE_TYPE_P (complete_type (to)) + && !CLASSTYPE_NON_AGGREGATE (to)) + { + expr = reshape_init (to, expr, complain); + if (expr == error_mark_node) + return NULL; + from = TREE_TYPE (expr); + } + if (TREE_CODE (to) == REFERENCE_TYPE) conv = reference_binding (to, from, expr, c_cast_p, flags, complain); else @@ -5677,8 +5687,9 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1, case TRUTH_ORIF_EXPR: case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: - warn_logical_operator (loc, code, boolean_type_node, - code_orig_arg1, arg1, code_orig_arg2, arg2); + if (complain & tf_warning) + warn_logical_operator (loc, code, boolean_type_node, + code_orig_arg1, arg1, code_orig_arg2, arg2); /* Fall through. */ case GT_EXPR: case LT_EXPR: @@ -5686,8 +5697,9 @@ build_new_op_1 (location_t loc, enum tree_code code, int flags, tree arg1, case LE_EXPR: case EQ_EXPR: case NE_EXPR: - if ((code_orig_arg1 == BOOLEAN_TYPE) - ^ (code_orig_arg2 == BOOLEAN_TYPE)) + if ((complain & tf_warning) + && ((code_orig_arg1 == BOOLEAN_TYPE) + ^ (code_orig_arg2 == BOOLEAN_TYPE))) maybe_warn_bool_compare (loc, code, arg1, arg2); /* Fall through. */ case PLUS_EXPR: diff --git a/contrib/gcc-5.0/gcc/cp/class.c b/contrib/gcc-5.0/gcc/cp/class.c index 9f189fb5ea..d59d351537 100644 --- a/contrib/gcc-5.0/gcc/cp/class.c +++ b/contrib/gcc-5.0/gcc/cp/class.c @@ -4286,6 +4286,25 @@ layout_nonempty_base_or_field (record_layout_info rli, : TYPE_ALIGN (type))); normalize_rli (rli); } + else if (TREE_CODE (type) == NULLPTR_TYPE + && warn_abi && abi_version_crosses (9)) + { + /* Before ABI v9, we were giving nullptr_t alignment of 1; if + the offset wasn't aligned like a pointer when we started to + layout this field, that affects its position. */ + tree pos = rli_size_unit_so_far (&old_rli); + if (int_cst_value (pos) % TYPE_ALIGN_UNIT (ptr_type_node) != 0) + { + if (abi_version_at_least (9)) + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wabi, + "alignment of %qD increased in -fabi-version=9 " + "(GCC 5.2)", decl); + else + warning_at (DECL_SOURCE_LOCATION (decl), OPT_Wabi, "alignment " + "of %qD will increase in -fabi-version=9", decl); + } + break; + } else /* There was no conflict. We're done laying out this field. */ break; @@ -6825,6 +6844,7 @@ finish_struct (tree t, tree attributes) unreverse_member_declarations (t); cplus_decl_attributes (&t, attributes, (int) ATTR_FLAG_TYPE_IN_PLACE); + fixup_attribute_variants (t); /* Nadger the current location so that diagnostics point to the start of the struct, not the end. */ diff --git a/contrib/gcc-5.0/gcc/cp/constexpr.c b/contrib/gcc-5.0/gcc/cp/constexpr.c index 5e65f29c63..e25072631b 100644 --- a/contrib/gcc-5.0/gcc/cp/constexpr.c +++ b/contrib/gcc-5.0/gcc/cp/constexpr.c @@ -543,8 +543,17 @@ build_constexpr_constructor_member_initializers (tree type, tree body) || TREE_CODE (body) == EH_SPEC_BLOCK) body = TREE_OPERAND (body, 0); if (TREE_CODE (body) == STATEMENT_LIST) - body = STATEMENT_LIST_HEAD (body)->stmt; - body = BIND_EXPR_BODY (body); + { + for (tree_stmt_iterator i = tsi_start (body); + !tsi_end_p (i); tsi_next (&i)) + { + body = tsi_stmt (i); + if (TREE_CODE (body) == BIND_EXPR) + break; + } + } + if (TREE_CODE (body) == BIND_EXPR) + body = BIND_EXPR_BODY (body); if (TREE_CODE (body) == CLEANUP_POINT_EXPR) { body = TREE_OPERAND (body, 0); @@ -1245,6 +1254,15 @@ cxx_eval_call_expression (const constexpr_ctx *ctx, tree t, return build_zero_init (DECL_CONTEXT (fun), NULL_TREE, false); } + /* We can't defer instantiating the function any longer. */ + if (!DECL_INITIAL (fun) + && DECL_TEMPLOID_INSTANTIATION (fun)) + { + ++function_depth; + instantiate_decl (fun, /*defer_ok*/false, /*expl_inst*/false); + --function_depth; + } + /* If in direct recursive call, optimize definition search. */ if (ctx && ctx->call && ctx->call->fundef->decl == fun) new_call.fundef = ctx->call->fundef; @@ -2697,11 +2715,13 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, } release_tree_vector (refs); - if ((AGGREGATE_TYPE_P (TREE_TYPE (t)) || VECTOR_TYPE_P (TREE_TYPE (t)))) + if (AGGREGATE_TYPE_P (type) || VECTOR_TYPE_P (type)) { /* Create a new CONSTRUCTOR in case evaluation of the initializer wants to modify it. */ - *valp = new_ctx.ctor = build_constructor (TREE_TYPE (t), NULL); + new_ctx.ctor = build_constructor (type, NULL); + if (*valp == NULL_TREE) + *valp = new_ctx.ctor; CONSTRUCTOR_NO_IMPLICIT_ZERO (new_ctx.ctor) = true; new_ctx.object = target; } @@ -2709,8 +2729,16 @@ cxx_eval_store_expression (const constexpr_ctx *ctx, tree t, init = cxx_eval_constant_expression (&new_ctx, init, false, non_constant_p, overflow_p); if (target == object) - /* The hash table might have moved since the get earlier. */ - ctx->values->put (object, init); + { + /* The hash table might have moved since the get earlier. */ + valp = ctx->values->get (object); + if (TREE_CODE (init) == CONSTRUCTOR) + /* An outer ctx->ctor might be pointing to *valp, so just replace + its contents. */ + CONSTRUCTOR_ELTS (*valp) = CONSTRUCTOR_ELTS (init); + else + *valp = init; + } else *valp = init; @@ -3212,6 +3240,7 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, case NON_LVALUE_EXPR: case TRY_CATCH_EXPR: + case TRY_BLOCK: case CLEANUP_POINT_EXPR: case MUST_NOT_THROW_EXPR: case EXPR_STMT: @@ -3222,6 +3251,17 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, jump_target); break; + case TRY_FINALLY_EXPR: + r = cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 0), lval, + non_constant_p, overflow_p, + jump_target); + if (!*non_constant_p) + /* Also evaluate the cleanup. */ + cxx_eval_constant_expression (ctx, TREE_OPERAND (t, 1), true, + non_constant_p, overflow_p, + jump_target); + break; + /* These differ from cxx_eval_unary_expression in that this doesn't check for a constant operand or result; an address can be constant without its operand being, and vice versa. */ @@ -3505,7 +3545,9 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, break; case PLACEHOLDER_EXPR: - if (!ctx || !ctx->ctor || (lval && !ctx->object)) + if (!ctx || !ctx->ctor || (lval && !ctx->object) + || !(same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (t), TREE_TYPE (ctx->ctor)))) { /* A placeholder without a referent. We can get here when checking whether NSDMIs are noexcept, or in massage_init_elt; @@ -3520,8 +3562,6 @@ cxx_eval_constant_expression (const constexpr_ctx *ctx, tree t, use ctx->object unconditionally, but using ctx->ctor when we can is a minor optimization. */ tree ctor = lval ? ctx->object : ctx->ctor; - gcc_assert (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (t), TREE_TYPE (ctor))); return cxx_eval_constant_expression (ctx, ctor, lval, non_constant_p, overflow_p); @@ -4314,6 +4354,7 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case CLEANUP_POINT_EXPR: case MUST_NOT_THROW_EXPR: case TRY_CATCH_EXPR: + case TRY_BLOCK: case EH_SPEC_BLOCK: case EXPR_STMT: case PAREN_EXPR: @@ -4323,6 +4364,10 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, case RETURN_EXPR: return RECUR (TREE_OPERAND (t, 0), want_rval); + case TRY_FINALLY_EXPR: + return (RECUR (TREE_OPERAND (t, 0), want_rval) + && RECUR (TREE_OPERAND (t, 1), any)); + case SCOPE_REF: return RECUR (TREE_OPERAND (t, 1), want_rval); @@ -4509,6 +4554,11 @@ potential_constant_expression_1 (tree t, bool want_rval, bool strict, } return false; + case TYPE_DECL: + case TAG_DEFN: + /* We can see these in statement-expressions. */ + return true; + default: if (objc_is_property_ref (t)) return false; diff --git a/contrib/gcc-5.0/gcc/cp/cp-gimplify.c b/contrib/gcc-5.0/gcc/cp/cp-gimplify.c index 70645b59b8..41b3418542 100644 --- a/contrib/gcc-5.0/gcc/cp/cp-gimplify.c +++ b/contrib/gcc-5.0/gcc/cp/cp-gimplify.c @@ -905,6 +905,7 @@ struct cp_genericize_data hash_set *p_set; vec bind_expr_stack; struct cp_genericize_omp_taskreg *omp_ctx; + bool no_sanitize_p; }; /* Perform any pre-gimplification lowering of C++ front end trees to @@ -1104,6 +1105,21 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) : OMP_CLAUSE_DEFAULT_PRIVATE); } } + if (flag_sanitize + & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) + { + /* The point here is to not sanitize static initializers. */ + bool no_sanitize_p = wtd->no_sanitize_p; + wtd->no_sanitize_p = true; + for (tree decl = BIND_EXPR_VARS (stmt); + decl; + decl = DECL_CHAIN (decl)) + if (VAR_P (decl) + && TREE_STATIC (decl) + && DECL_INITIAL (decl)) + cp_walk_tree (&DECL_INITIAL (decl), cp_genericize_r, data, NULL); + wtd->no_sanitize_p = no_sanitize_p; + } wtd->bind_expr_stack.safe_push (stmt); cp_walk_tree (&BIND_EXPR_BODY (stmt), cp_genericize_r, data, NULL); @@ -1226,9 +1242,10 @@ cp_genericize_r (tree *stmt_p, int *walk_subtrees, void *data) if (*stmt_p == error_mark_node) *stmt_p = size_one_node; return NULL; - } - else if (flag_sanitize - & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) + } + else if ((flag_sanitize + & (SANITIZE_NULL | SANITIZE_ALIGNMENT | SANITIZE_VPTR)) + && !wtd->no_sanitize_p) { if ((flag_sanitize & (SANITIZE_NULL | SANITIZE_ALIGNMENT)) && TREE_CODE (stmt) == NOP_EXPR @@ -1269,6 +1286,7 @@ cp_genericize_tree (tree* t_p) wtd.p_set = new hash_set; wtd.bind_expr_stack.create (0); wtd.omp_ctx = NULL; + wtd.no_sanitize_p = false; cp_walk_tree (t_p, cp_genericize_r, &wtd, NULL); delete wtd.p_set; wtd.bind_expr_stack.release (); diff --git a/contrib/gcc-5.0/gcc/cp/cp-tree.h b/contrib/gcc-5.0/gcc/cp/cp-tree.h index 2a904a5f4f..4e525e04d5 100644 --- a/contrib/gcc-5.0/gcc/cp/cp-tree.h +++ b/contrib/gcc-5.0/gcc/cp/cp-tree.h @@ -161,6 +161,7 @@ c-common.h, not after. LABEL_DECL_CONTINUE (in LABEL_DECL) 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). DECL_IMPLICIT_TYPEDEF_P (in a TYPE_DECL) + TEMPLATE_DECL_COMPLEX_ALIAS_P (in TEMPLATE_DECL) 3: DECL_IN_AGGR_P. 4: DECL_C_BIT_FIELD (in a FIELD_DECL) DECL_ANON_UNION_VAR_P (in a VAR_DECL) @@ -2738,6 +2739,10 @@ extern void decl_shadowed_for_var_insert (tree, tree); #define TYPE_DECL_ALIAS_P(NODE) \ DECL_LANG_FLAG_6 (TYPE_DECL_CHECK (NODE)) +/* Nonzero for TEMPLATE_DECL means that it is a 'complex' alias template. */ +#define TEMPLATE_DECL_COMPLEX_ALIAS_P(NODE) \ + DECL_LANG_FLAG_2 (TEMPLATE_DECL_CHECK (NODE)) + /* Nonzero for a type which is an alias for another type; i.e, a type which declaration was written 'using name-of-type = another-type'. */ @@ -4101,7 +4106,8 @@ more_aggr_init_expr_args_p (const aggr_init_expr_arg_iterator *iter) (DECL_LANG_SPECIFIC (NODE)->u.base.not_really_extern) #define DECL_REALLY_EXTERN(NODE) \ - (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE)) + (DECL_EXTERNAL (NODE) \ + && (!DECL_LANG_SPECIFIC (NODE) || !DECL_NOT_REALLY_EXTERN (NODE))) /* A thunk is a stub function. diff --git a/contrib/gcc-5.0/gcc/cp/decl.c b/contrib/gcc-5.0/gcc/cp/decl.c index cde51d6663..72c77eaafa 100644 --- a/contrib/gcc-5.0/gcc/cp/decl.c +++ b/contrib/gcc-5.0/gcc/cp/decl.c @@ -3846,6 +3846,8 @@ cxx_init_decl_processing (void) global_namespace = build_lang_decl (NAMESPACE_DECL, global_scope_name, void_type_node); DECL_CONTEXT (global_namespace) = build_translation_unit_decl (NULL_TREE); + debug_hooks->register_main_translation_unit + (DECL_CONTEXT (global_namespace)); TREE_PUBLIC (global_namespace) = 1; begin_scope (sk_namespace, global_namespace); @@ -4011,6 +4013,8 @@ cxx_init_decl_processing (void) TYPE_SIZE_UNIT (nullptr_type_node) = size_int (GET_MODE_SIZE (ptr_mode)); TYPE_UNSIGNED (nullptr_type_node) = 1; TYPE_PRECISION (nullptr_type_node) = GET_MODE_BITSIZE (ptr_mode); + if (abi_version_at_least (9)) + TYPE_ALIGN (nullptr_type_node) = GET_MODE_ALIGNMENT (ptr_mode); SET_TYPE_MODE (nullptr_type_node, ptr_mode); record_builtin_type (RID_MAX, "decltype(nullptr)", nullptr_type_node); nullptr_node = build_int_cst (nullptr_type_node, 0); @@ -7908,7 +7912,7 @@ grokfndecl (tree ctype, if (TYPE_NOTHROW_P (type) || nothrow_libfn_p (decl)) TREE_NOTHROW (decl) = 1; - if (flag_openmp || flag_cilkplus) + if (flag_openmp || flag_openmp_simd || flag_cilkplus) { /* Adjust "omp declare simd" attributes. */ tree ods = lookup_attribute ("omp declare simd", *attrlist); @@ -8234,13 +8238,6 @@ build_ptrmemfunc_type (tree type) if (type == error_mark_node) return type; - /* If a canonical type already exists for this type, use it. We use - this method instead of type_hash_canon, because it only does a - simple equality check on the list of field members. */ - - if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type))) - return t; - /* Make sure that we always have the unqualified pointer-to-member type first. */ if (cp_cv_quals quals = cp_type_quals (type)) @@ -8249,6 +8246,13 @@ build_ptrmemfunc_type (tree type) return cp_build_qualified_type (unqual, quals); } + /* If a canonical type already exists for this type, use it. We use + this method instead of type_hash_canon, because it only does a + simple equality check on the list of field members. */ + + if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type))) + return t; + t = make_node (RECORD_TYPE); /* Let the front end know this is a pointer to member function. */ diff --git a/contrib/gcc-5.0/gcc/cp/decl2.c b/contrib/gcc-5.0/gcc/cp/decl2.c index 117dbd03c4..f5d1e52be8 100644 --- a/contrib/gcc-5.0/gcc/cp/decl2.c +++ b/contrib/gcc-5.0/gcc/cp/decl2.c @@ -5019,8 +5019,7 @@ mark_used (tree decl, tsubst_flags_t complain) && DECL_TEMPLATE_INFO (decl) && (decl_maybe_constant_var_p (decl) || (TREE_CODE (decl) == FUNCTION_DECL - && (DECL_DECLARED_CONSTEXPR_P (decl) - || DECL_OMP_DECLARE_REDUCTION_P (decl))) + && DECL_OMP_DECLARE_REDUCTION_P (decl)) || undeduced_auto_decl (decl)) && !uses_template_parms (DECL_TI_ARGS (decl))) { diff --git a/contrib/gcc-5.0/gcc/cp/init.c b/contrib/gcc-5.0/gcc/cp/init.c index 957a7a4e6e..04c09d8a0e 100644 --- a/contrib/gcc-5.0/gcc/cp/init.c +++ b/contrib/gcc-5.0/gcc/cp/init.c @@ -3367,6 +3367,18 @@ get_temp_regvar (tree type, tree init) return decl; } +/* Subroutine of build_vec_init. Returns true if assigning to an array of + INNER_ELT_TYPE from INIT is trivial. */ + +static bool +vec_copy_assign_is_trivial (tree inner_elt_type, tree init) +{ + tree fromtype = inner_elt_type; + if (real_lvalue_p (init)) + fromtype = cp_build_reference_type (fromtype, /*rval*/false); + return is_trivially_xible (MODIFY_EXPR, inner_elt_type, fromtype); +} + /* `build_vec_init' returns tree structure that performs initialization of a vector of aggregate types. @@ -3443,8 +3455,7 @@ build_vec_init (tree base, tree maxindex, tree init, && TREE_CODE (atype) == ARRAY_TYPE && TREE_CONSTANT (maxindex) && (from_array == 2 - ? (!CLASS_TYPE_P (inner_elt_type) - || !TYPE_HAS_COMPLEX_COPY_ASSIGN (inner_elt_type)) + ? vec_copy_assign_is_trivial (inner_elt_type, init) : !TYPE_NEEDS_CONSTRUCTING (type)) && ((TREE_CODE (init) == CONSTRUCTOR /* Don't do this if the CONSTRUCTOR might contain something diff --git a/contrib/gcc-5.0/gcc/cp/mangle.c b/contrib/gcc-5.0/gcc/cp/mangle.c index b0f72d1ff1..23c95b6ff6 100644 --- a/contrib/gcc-5.0/gcc/cp/mangle.c +++ b/contrib/gcc-5.0/gcc/cp/mangle.c @@ -2571,7 +2571,7 @@ write_template_args (tree args) if (args) length = TREE_VEC_LENGTH (args); - if (args && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) + if (args && length && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) { /* We have nested template args. We want the innermost template argument list. */ @@ -3470,11 +3470,11 @@ get_mangled_id (tree decl) return targetm.mangle_decl_assembler_name (decl, id); } -/* If DECL is a mangling alias, remove it from the symbol table and return - true; otherwise return false. */ +/* If DECL is an implicit mangling alias, return its symtab node; otherwise + return NULL. */ -bool -maybe_remove_implicit_alias (tree decl) +static symtab_node * +decl_implicit_alias_p (tree decl) { if (DECL_P (decl) && DECL_ARTIFICIAL (decl) && DECL_IGNORED_P (decl) @@ -3484,10 +3484,21 @@ maybe_remove_implicit_alias (tree decl) { symtab_node *n = symtab_node::get (decl); if (n && n->cpp_implicit_alias) - { - n->remove(); - return true; - } + return n; + } + return NULL; +} + +/* If DECL is a mangling alias, remove it from the symbol table and return + true; otherwise return false. */ + +bool +maybe_remove_implicit_alias (tree decl) +{ + if (symtab_node *n = decl_implicit_alias_p (decl)) + { + n->remove(); + return true; } return false; } @@ -3514,21 +3525,38 @@ mangle_decl (const tree decl) id = get_mangled_id (decl); SET_DECL_ASSEMBLER_NAME (decl, id); - if (G.need_abi_warning + if (id != DECL_NAME (decl) + && !DECL_REALLY_EXTERN (decl) /* Don't do this for a fake symbol we aren't going to emit anyway. */ && TREE_CODE (decl) != TYPE_DECL && !DECL_MAYBE_IN_CHARGE_CONSTRUCTOR_P (decl) && !DECL_MAYBE_IN_CHARGE_DESTRUCTOR_P (decl)) { + bool set = false; + + /* Check IDENTIFIER_GLOBAL_VALUE before setting to avoid redundant + errors from multiple definitions. */ + tree d = IDENTIFIER_GLOBAL_VALUE (id); + if (!d || decl_implicit_alias_p (d)) + { + set = true; + SET_IDENTIFIER_GLOBAL_VALUE (id, decl); + } + + if (!G.need_abi_warning) + return; + /* If the mangling will change in the future, emit an alias with the future mangled name for forward-compatibility. */ int save_ver; tree id2; - SET_IDENTIFIER_GLOBAL_VALUE (id, decl); - if (IDENTIFIER_GLOBAL_VALUE (id) != decl) - inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or =0) " - "avoids this error with a change in mangling"); + if (!set) + { + SET_IDENTIFIER_GLOBAL_VALUE (id, decl); + inform (DECL_SOURCE_LOCATION (decl), "a later -fabi-version= (or " + "=0) avoids this error with a change in mangling"); + } save_ver = flag_abi_version; flag_abi_version = flag_abi_compat_version; diff --git a/contrib/gcc-5.0/gcc/cp/parser.c b/contrib/gcc-5.0/gcc/cp/parser.c index 9f5fb6e4be..db9301fcb7 100644 --- a/contrib/gcc-5.0/gcc/cp/parser.c +++ b/contrib/gcc-5.0/gcc/cp/parser.c @@ -14933,6 +14933,30 @@ cp_parser_simple_type_specifier (cp_parser* parser, maybe_warn_cpp0x (CPP0X_AUTO); if (parser->auto_is_implicit_function_template_parm_p) { + /* The 'auto' might be the placeholder return type for a function decl + with trailing return type. */ + bool have_trailing_return_fn_decl = false; + if (cp_lexer_peek_nth_token (parser->lexer, 2)->type + == CPP_OPEN_PAREN) + { + cp_parser_parse_tentatively (parser); + cp_lexer_consume_token (parser->lexer); + cp_lexer_consume_token (parser->lexer); + if (cp_parser_skip_to_closing_parenthesis (parser, + /*recovering*/false, + /*or_comma*/false, + /*consume_paren*/true)) + have_trailing_return_fn_decl + = cp_lexer_next_token_is (parser->lexer, CPP_DEREF); + cp_parser_abort_tentative_parse (parser); + } + + if (have_trailing_return_fn_decl) + { + type = make_auto (); + break; + } + if (cxx_dialect >= cxx14) type = synthesize_implicit_template_parm (parser); else diff --git a/contrib/gcc-5.0/gcc/cp/pt.c b/contrib/gcc-5.0/gcc/cp/pt.c index ac7a139b25..db1060826e 100644 --- a/contrib/gcc-5.0/gcc/cp/pt.c +++ b/contrib/gcc-5.0/gcc/cp/pt.c @@ -217,6 +217,7 @@ static tree template_parm_to_arg (tree t); static tree current_template_args (void); static tree tsubst_template_parm (tree, tree, tsubst_flags_t); static tree instantiate_alias_template (tree, tree, tsubst_flags_t); +static bool complex_alias_template_p (const_tree tmpl); /* Make the current scope suitable for access checking when we are processing T. T can be FUNCTION_DECL for instantiated function @@ -4418,6 +4419,7 @@ get_template_parm_index (tree parm) || TREE_CODE (parm) == TEMPLATE_DECL) parm = TREE_TYPE (parm); if (TREE_CODE (parm) == TEMPLATE_TYPE_PARM + || TREE_CODE (parm) == BOUND_TEMPLATE_TEMPLATE_PARM || TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM) parm = TEMPLATE_TYPE_PARM_INDEX (parm); gcc_assert (TREE_CODE (parm) == TEMPLATE_PARM_INDEX); @@ -5094,6 +5096,11 @@ template arguments to %qD do not match original template %qD", if (TREE_CODE (parm) == TEMPLATE_DECL) DECL_CONTEXT (parm) = tmpl; } + + if (TREE_CODE (decl) == TYPE_DECL + && TYPE_DECL_ALIAS_P (decl) + && complex_alias_template_p (tmpl)) + TEMPLATE_DECL_COMPLEX_ALIAS_P (tmpl) = true; } /* The DECL_TI_ARGS of DECL contains full set of arguments referring @@ -5351,13 +5358,56 @@ alias_template_specialization_p (const_tree t) return false; } -/* Return TRUE iff T is a specialization of an alias template with +/* An alias template is complex from a SFINAE perspective if a template-id + using that alias can be ill-formed when the expansion is not, as with + the void_t template. We determine this by checking whether the + expansion for the alias template uses all its template parameters. */ + +struct uses_all_template_parms_data +{ + int level; + bool *seen; +}; + +static int +uses_all_template_parms_r (tree t, void *data_) +{ + struct uses_all_template_parms_data &data + = *(struct uses_all_template_parms_data*)data_; + tree idx = get_template_parm_index (t); + + if (TEMPLATE_PARM_LEVEL (idx) == data.level) + data.seen[TEMPLATE_PARM_IDX (idx)] = true; + return 0; +} + +static bool +complex_alias_template_p (const_tree tmpl) +{ + struct uses_all_template_parms_data data; + tree pat = DECL_ORIGINAL_TYPE (DECL_TEMPLATE_RESULT (tmpl)); + tree parms = DECL_TEMPLATE_PARMS (tmpl); + data.level = TMPL_PARMS_DEPTH (parms); + int len = TREE_VEC_LENGTH (INNERMOST_TEMPLATE_PARMS (parms)); + data.seen = XALLOCAVEC (bool, len); + for (int i = 0; i < len; ++i) + data.seen[i] = false; + + for_each_template_parm (pat, uses_all_template_parms_r, &data, NULL, true); + for (int i = 0; i < len; ++i) + if (!data.seen[i]) + return true; + return false; +} + +/* Return TRUE iff T is a specialization of a complex alias template with dependent template-arguments. */ bool dependent_alias_template_spec_p (const_tree t) { return (alias_template_specialization_p (t) + && TEMPLATE_DECL_COMPLEX_ALIAS_P (DECL_TI_TEMPLATE (TYPE_NAME (t))) && (any_dependent_template_arguments_p (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (t))))); } @@ -8225,7 +8275,7 @@ for_each_template_parm_r (tree *tp, int *walk_subtrees, void *d) case TYPEOF_TYPE: case UNDERLYING_TYPE: if (pfd->include_nondeduced_p - && for_each_template_parm (TYPE_FIELDS (t), fn, data, + && for_each_template_parm (TYPE_VALUES_RAW (t), fn, data, pfd->visited, pfd->include_nondeduced_p)) return error_mark_node; @@ -9037,7 +9087,7 @@ apply_late_template_attributes (tree *decl_p, tree attributes, int attr_flags, { *p = TREE_CHAIN (t); TREE_CHAIN (t) = NULL_TREE; - if ((flag_openmp || flag_cilkplus) + if ((flag_openmp || flag_openmp_simd || flag_cilkplus) && is_attribute_p ("omp declare simd", get_attribute_name (t)) && TREE_VALUE (t)) @@ -9210,12 +9260,20 @@ instantiate_class_template_1 (tree type) it now. */ push_deferring_access_checks (dk_no_deferred); + int saved_unevaluated_operand = cp_unevaluated_operand; + int saved_inhibit_evaluation_warnings = c_inhibit_evaluation_warnings; + fn_context = decl_function_context (TYPE_MAIN_DECL (type)); /* Also avoid push_to_top_level for a lambda in an NSDMI. */ if (!fn_context && LAMBDA_TYPE_P (type) && TYPE_CLASS_SCOPE_P (type)) fn_context = error_mark_node; if (!fn_context) push_to_top_level (); + else + { + cp_unevaluated_operand = 0; + c_inhibit_evaluation_warnings = 0; + } /* Use #pragma pack from the template context. */ saved_maximum_field_alignment = maximum_field_alignment; maximum_field_alignment = TYPE_PRECISION (pattern); @@ -9631,6 +9689,14 @@ instantiate_class_template_1 (tree type) } } + if (fn_context) + { + /* Restore these before substituting into the lambda capture + initializers. */ + cp_unevaluated_operand = saved_unevaluated_operand; + c_inhibit_evaluation_warnings = saved_inhibit_evaluation_warnings; + } + if (tree expr = CLASSTYPE_LAMBDA_EXPR (type)) { tree decl = lambda_function (type); @@ -9781,16 +9847,22 @@ make_fnparm_pack (tree spec_parm) return extract_fnparm_pack (NULL_TREE, &spec_parm); } -/* Return true iff the Ith element of the argument pack ARG_PACK is a - pack expansion. */ +/* Return 1 if the Ith element of the argument pack ARG_PACK is a + pack expansion with no extra args, 2 if it has extra args, or 0 + if it is not a pack expansion. */ -static bool +static int argument_pack_element_is_expansion_p (tree arg_pack, int i) { tree vec = ARGUMENT_PACK_ARGS (arg_pack); if (i >= TREE_VEC_LENGTH (vec)) - return false; - return PACK_EXPANSION_P (TREE_VEC_ELT (vec, i)); + return 0; + tree elt = TREE_VEC_ELT (vec, i); + if (!PACK_EXPANSION_P (elt)) + return 0; + if (PACK_EXPANSION_EXTRA_ARGS (elt)) + return 2; + return 1; } @@ -9840,7 +9912,12 @@ use_pack_expansion_extra_args_p (tree parm_packs, { tree arg = TREE_VALUE (parm_pack); - if (argument_pack_element_is_expansion_p (arg, i)) + int exp = argument_pack_element_is_expansion_p (arg, i); + if (exp == 2) + /* We can't substitute a pack expansion with extra args into + our pattern. */ + return true; + else if (exp) has_expansion_arg = true; else has_non_expansion_arg = true; @@ -11288,8 +11365,7 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) { /* T is a static data member or namespace-scope entity. We have to substitute into namespace-scope variables - (even though such entities are never templates) because - of cases like: + (not just variable templates) because of cases like: template void f() { extern T t; } @@ -11450,10 +11526,12 @@ tsubst_decl (tree t, tree args, tsubst_flags_t complain) initializer is present. We mimic the non-template processing here. */ DECL_EXTERNAL (r) = 1; + if (DECL_NAMESPACE_SCOPE_P (t)) + DECL_NOT_REALLY_EXTERN (r) = 1; - register_specialization (r, gen_tmpl, argvec, false, hash); DECL_TEMPLATE_INFO (r) = build_template_info (tmpl, argvec); SET_DECL_IMPLICIT_INSTANTIATION (r); + register_specialization (r, gen_tmpl, argvec, false, hash); } else if (!cp_unevaluated_operand) register_local_specialization (r, t); @@ -13049,10 +13127,8 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) if (TREE_STATIC (r)) rest_of_decl_compilation (r, toplevel_bindings_p (), at_eof); - else if (decl_constant_var_p (r)) - /* A use of a local constant decays to its value. - FIXME update for core DR 696. */ - r = scalar_constant_value (r); + else + r = process_outer_var_ref (r, complain); } } /* Remember this for subsequent uses. */ @@ -13467,6 +13543,32 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } } +/* Helper function for tsubst_omp_clauses, used for instantiation of + OMP_CLAUSE_DECL of clauses that handles also OpenMP array sections + represented with TREE_LIST. */ + +static tree +tsubst_omp_clause_decl (tree decl, tree args, tsubst_flags_t complain, + tree in_decl) +{ + if (TREE_CODE (decl) == TREE_LIST) + { + tree low_bound + = tsubst_expr (TREE_PURPOSE (decl), args, complain, in_decl, + /*integral_constant_expression_p=*/false); + tree length = tsubst_expr (TREE_VALUE (decl), args, complain, in_decl, + /*integral_constant_expression_p=*/false); + tree chain = tsubst_omp_clause_decl (TREE_CHAIN (decl), args, complain, + in_decl); + if (TREE_PURPOSE (decl) == low_bound + && TREE_VALUE (decl) == length + && TREE_CHAIN (decl) == chain) + return decl; + return tree_cons (low_bound, length, chain); + } + return tsubst_copy (decl, args, complain, in_decl); +} + /* Like tsubst_copy, but specifically for OpenMP clauses. */ static tree @@ -13498,16 +13600,23 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, case OMP_CLAUSE_FIRSTPRIVATE: case OMP_CLAUSE_COPYIN: case OMP_CLAUSE_COPYPRIVATE: + case OMP_CLAUSE_UNIFORM: + OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args, + complain, in_decl); + break; + case OMP_CLAUSE_DEPEND: + case OMP_CLAUSE_FROM: + case OMP_CLAUSE_TO: + case OMP_CLAUSE_MAP: + OMP_CLAUSE_DECL (nc) + = tsubst_omp_clause_decl (OMP_CLAUSE_DECL (oc), args, complain, + in_decl); + break; case OMP_CLAUSE_IF: case OMP_CLAUSE_NUM_THREADS: case OMP_CLAUSE_SCHEDULE: case OMP_CLAUSE_COLLAPSE: case OMP_CLAUSE_FINAL: - case OMP_CLAUSE_DEPEND: - case OMP_CLAUSE_FROM: - case OMP_CLAUSE_TO: - case OMP_CLAUSE_UNIFORM: - case OMP_CLAUSE_MAP: case OMP_CLAUSE_DEVICE: case OMP_CLAUSE_DIST_SCHEDULE: case OMP_CLAUSE_NUM_TEAMS: @@ -13534,20 +13643,17 @@ tsubst_omp_clauses (tree clauses, bool declare_simd, else gcc_assert (identifier_p (placeholder)); } - OMP_CLAUSE_OPERAND (nc, 0) - = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, - in_decl, /*integral_constant_expression_p=*/false); + OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args, + complain, in_decl); break; case OMP_CLAUSE_LINEAR: case OMP_CLAUSE_ALIGNED: - OMP_CLAUSE_OPERAND (nc, 0) - = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 0), args, complain, - in_decl, /*integral_constant_expression_p=*/false); + OMP_CLAUSE_DECL (nc) = tsubst_copy (OMP_CLAUSE_DECL (oc), args, + complain, in_decl); OMP_CLAUSE_OPERAND (nc, 1) = tsubst_expr (OMP_CLAUSE_OPERAND (oc, 1), args, complain, in_decl, /*integral_constant_expression_p=*/false); break; - case OMP_CLAUSE_NOWAIT: case OMP_CLAUSE_ORDERED: case OMP_CLAUSE_DEFAULT: @@ -15610,7 +15716,11 @@ tsubst_copy_and_build (tree t, r = build_cxx_call (wrap, 0, NULL, tf_warning_or_error); } else if (outer_automatic_var_p (r)) - r = process_outer_var_ref (r, complain); + { + r = process_outer_var_ref (r, complain); + if (is_capture_proxy (r)) + register_local_specialization (r, t); + } if (TREE_CODE (TREE_TYPE (t)) != REFERENCE_TYPE) /* If the original type was a reference, we'll be wrapped in @@ -20865,6 +20975,12 @@ dependent_type_p_r (tree type) names a dependent type. */ if (TREE_CODE (type) == TYPENAME_TYPE) return true; + + /* An alias template specialization can be dependent even if the + resulting type is not. */ + if (dependent_alias_template_spec_p (type)) + return true; + /* -- a cv-qualified type where the cv-unqualified type is dependent. No code is necessary for this bullet; the code below handles @@ -20916,12 +21032,6 @@ dependent_type_p_r (tree type) && (any_dependent_template_arguments_p (INNERMOST_TEMPLATE_ARGS (CLASSTYPE_TI_ARGS (type))))) return true; - /* For an alias template specialization, check the arguments both to the - class template and the alias template. */ - else if (alias_template_specialization_p (type) - && (any_dependent_template_arguments_p - (INNERMOST_TEMPLATE_ARGS (TYPE_TI_ARGS (type))))) - return true; /* All TYPEOF_TYPEs, DECLTYPE_TYPEs, and UNDERLYING_TYPEs are dependent; if the argument of the `typeof' expression is not @@ -21417,6 +21527,10 @@ type_dependent_expression_p (tree expression) && variable_template_p (DECL_TI_TEMPLATE (expression))) return any_dependent_template_arguments_p (DECL_TI_ARGS (expression)); + /* Always dependent, on the number of arguments if nothing else. */ + if (TREE_CODE (expression) == EXPR_PACK_EXPANSION) + return true; + if (TREE_TYPE (expression) == unknown_type_node) { if (TREE_CODE (expression) == ADDR_EXPR) @@ -21434,10 +21548,6 @@ type_dependent_expression_p (tree expression) if (TREE_CODE (expression) == SCOPE_REF) return false; - /* Always dependent, on the number of arguments if nothing else. */ - if (TREE_CODE (expression) == EXPR_PACK_EXPANSION) - return true; - if (BASELINK_P (expression)) { if (BASELINK_OPTYPE (expression) diff --git a/contrib/gcc-5.0/gcc/cp/semantics.c b/contrib/gcc-5.0/gcc/cp/semantics.c index 74af7e842c..82ef6425de 100644 --- a/contrib/gcc-5.0/gcc/cp/semantics.c +++ b/contrib/gcc-5.0/gcc/cp/semantics.c @@ -3109,6 +3109,8 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain) if (cp_unevaluated_operand) /* It's not a use (3.2) if we're in an unevaluated context. */ return decl; + if (decl == error_mark_node) + return decl; tree context = DECL_CONTEXT (decl); tree containing_function = current_function_decl; @@ -3133,7 +3135,11 @@ process_outer_var_ref (tree decl, tsubst_flags_t complain) form, so wait until instantiation time. */ return decl; else if (decl_constant_var_p (decl)) - return scalar_constant_value (decl); + { + tree t = maybe_constant_value (convert_from_reference (decl)); + if (TREE_CONSTANT (t)) + return t; + } } if (parsing_nsdmi ()) diff --git a/contrib/gcc-5.0/gcc/cp/tree.c b/contrib/gcc-5.0/gcc/cp/tree.c index 70fd4cac9d..f0a9589521 100644 --- a/contrib/gcc-5.0/gcc/cp/tree.c +++ b/contrib/gcc-5.0/gcc/cp/tree.c @@ -2237,14 +2237,14 @@ no_linkage_check (tree t, bool relaxed_p) return no_linkage_check (TYPE_PTRMEM_CLASS_TYPE (t), relaxed_p); case METHOD_TYPE: - r = no_linkage_check (TYPE_METHOD_BASETYPE (t), relaxed_p); - if (r) - return r; - /* Fall through. */ case FUNCTION_TYPE: { - tree parm; - for (parm = TYPE_ARG_TYPES (t); + tree parm = TYPE_ARG_TYPES (t); + if (TREE_CODE (t) == METHOD_TYPE) + /* The 'this' pointer isn't interesting; a method has the same + linkage (or lack thereof) as its enclosing class. */ + parm = TREE_CHAIN (parm); + for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm)) { @@ -2358,6 +2358,29 @@ bot_manip (tree* tp, int* walk_subtrees, void* data) *walk_subtrees = 0; return NULL_TREE; } + if (TREE_CODE (*tp) == SAVE_EXPR) + { + t = *tp; + splay_tree_node n = splay_tree_lookup (target_remap, + (splay_tree_key) t); + if (n) + { + *tp = (tree)n->value; + *walk_subtrees = 0; + } + else + { + copy_tree_r (tp, walk_subtrees, NULL); + splay_tree_insert (target_remap, + (splay_tree_key)t, + (splay_tree_value)*tp); + /* Make sure we don't remap an already-remapped SAVE_EXPR. */ + splay_tree_insert (target_remap, + (splay_tree_key)*tp, + (splay_tree_value)*tp); + } + return NULL_TREE; + } /* Make a copy of this node. */ t = copy_tree_r (tp, walk_subtrees, NULL); @@ -2493,15 +2516,15 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_) switch (TREE_CODE (*t)) { case PLACEHOLDER_EXPR: - gcc_assert (same_type_ignoring_top_level_qualifiers_p - (TREE_TYPE (*t), TREE_TYPE (obj))); - *t = obj; - *walk_subtrees = false; - break; - - case TARGET_EXPR: - /* Don't mess with placeholders in an unrelated object. */ - *walk_subtrees = false; + { + tree x = obj; + for (; !(same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (*t), TREE_TYPE (x))); + x = TREE_OPERAND (x, 0)) + gcc_assert (TREE_CODE (x) == COMPONENT_REF); + *t = x; + *walk_subtrees = false; + } break; case CONSTRUCTOR: @@ -2517,7 +2540,12 @@ replace_placeholders_r (tree* t, int* walk_subtrees, void* data_) if (TREE_CODE (*valp) == CONSTRUCTOR && AGGREGATE_TYPE_P (type)) { - subob = build_ctor_subob_ref (ce->index, type, obj); + /* If we're looking at the initializer for OBJ, then build + a sub-object reference. If we're looking at an + initializer for another object, just pass OBJ down. */ + if (same_type_ignoring_top_level_qualifiers_p + (TREE_TYPE (*t), TREE_TYPE (obj))) + subob = build_ctor_subob_ref (ce->index, type, obj); if (TREE_CODE (*valp) == TARGET_EXPR) valp = &TARGET_EXPR_INITIAL (*valp); } @@ -3574,13 +3602,15 @@ handle_abi_tag_attribute (tree* node, tree name, tree args, name, *node); goto fail; } - else if (CLASSTYPE_TEMPLATE_INSTANTIATION (*node)) + else if (CLASS_TYPE_P (*node) + && CLASSTYPE_TEMPLATE_INSTANTIATION (*node)) { warning (OPT_Wattributes, "ignoring %qE attribute applied to " "template instantiation %qT", name, *node); goto fail; } - else if (CLASSTYPE_TEMPLATE_SPECIALIZATION (*node)) + else if (CLASS_TYPE_P (*node) + && CLASSTYPE_TEMPLATE_SPECIALIZATION (*node)) { warning (OPT_Wattributes, "ignoring %qE attribute applied to " "template specialization %qT", name, *node); diff --git a/contrib/gcc-5.0/gcc/cp/typeck.c b/contrib/gcc-5.0/gcc/cp/typeck.c index e9d4cae570..1408e3ca84 100644 --- a/contrib/gcc-5.0/gcc/cp/typeck.c +++ b/contrib/gcc-5.0/gcc/cp/typeck.c @@ -3134,15 +3134,6 @@ cp_build_array_ref (location_t loc, tree array, tree idx, return error_mark_node; } - if (!lvalue_p (array)) - { - if (complain & tf_error) - pedwarn (loc, OPT_Wpedantic, - "ISO C++ forbids subscripting non-lvalue array"); - else - return error_mark_node; - } - /* Note in C++ it is valid to subscript a `register' array, since it is valid to take the address of something with that storage specification. */ diff --git a/contrib/gcc-5.0/gcc/cp/typeck2.c b/contrib/gcc-5.0/gcc/cp/typeck2.c index a4326b75e3..a10a762351 100644 --- a/contrib/gcc-5.0/gcc/cp/typeck2.c +++ b/contrib/gcc-5.0/gcc/cp/typeck2.c @@ -843,7 +843,7 @@ store_init_value (tree decl, tree init, vec** cleanups, int flags) TREE_CONSTANT (decl) = const_init && decl_maybe_constant_var_p (decl); } - if (cxx_dialect >= cxx14) + if (cxx_dialect >= cxx14 && CLASS_TYPE_P (strip_array_types (type))) /* Handle aggregate NSDMI in non-constant initializers, too. */ value = replace_placeholders (value, decl); diff --git a/contrib/gcc-5.0/gcc/dbxout.c b/contrib/gcc-5.0/gcc/dbxout.c index 758c1c439f..e1af563ea3 100644 --- a/contrib/gcc-5.0/gcc/dbxout.c +++ b/contrib/gcc-5.0/gcc/dbxout.c @@ -390,6 +390,7 @@ const struct gcc_debug_hooks dbx_debug_hooks = debug_nothing_tree, /* begin_function */ #endif debug_nothing_int, /* end_function */ + debug_nothing_tree, /* register_main_translation_unit */ dbxout_function_decl, dbxout_global_decl, /* global_decl */ dbxout_type_decl, /* type_decl */ @@ -426,6 +427,7 @@ const struct gcc_debug_hooks xcoff_debug_hooks = xcoffout_end_epilogue, debug_nothing_tree, /* begin_function */ xcoffout_end_function, + debug_nothing_tree, /* register_main_translation_unit */ debug_nothing_tree, /* function_decl */ dbxout_global_decl, /* global_decl */ dbxout_type_decl, /* type_decl */ diff --git a/contrib/gcc-5.0/gcc/debug.c b/contrib/gcc-5.0/gcc/debug.c index 7d18c0aa86..05365759d8 100644 --- a/contrib/gcc-5.0/gcc/debug.c +++ b/contrib/gcc-5.0/gcc/debug.c @@ -51,6 +51,7 @@ const struct gcc_debug_hooks do_nothing_debug_hooks = debug_nothing_int_charstar, /* end_epilogue */ debug_nothing_tree, /* begin_function */ debug_nothing_int, /* end_function */ + debug_nothing_tree, /* register_main_translation_unit */ debug_nothing_tree, /* function_decl */ debug_nothing_tree, /* global_decl */ debug_nothing_tree_int, /* type_decl */ diff --git a/contrib/gcc-5.0/gcc/debug.h b/contrib/gcc-5.0/gcc/debug.h index 276c887f62..82634c653d 100644 --- a/contrib/gcc-5.0/gcc/debug.h +++ b/contrib/gcc-5.0/gcc/debug.h @@ -86,6 +86,10 @@ struct gcc_debug_hooks /* Record end of function. LINE is highest line number in function. */ void (* end_function) (unsigned int line); + /* Register UNIT as the main translation unit. Called from front-ends when + they create their main translation unit. */ + void (* register_main_translation_unit) (tree); + /* Debug information for a function DECL. This might include the function name (a symbol), its parameters, and the block that makes up the function's body, and the local variables of the diff --git a/contrib/gcc-5.0/gcc/dwarf2out.c b/contrib/gcc-5.0/gcc/dwarf2out.c index 60d6e00e9f..749d4cea46 100644 --- a/contrib/gcc-5.0/gcc/dwarf2out.c +++ b/contrib/gcc-5.0/gcc/dwarf2out.c @@ -2466,6 +2466,7 @@ static void dwarf2out_abstract_function (tree); static void dwarf2out_var_location (rtx_insn *); static void dwarf2out_begin_function (tree); static void dwarf2out_end_function (unsigned int); +static void dwarf2out_register_main_translation_unit (tree unit); static void dwarf2out_set_name (tree, tree); /* The debug hooks structure. */ @@ -2494,6 +2495,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks = dwarf2out_end_epilogue, dwarf2out_begin_function, dwarf2out_end_function, /* end_function */ + dwarf2out_register_main_translation_unit, dwarf2out_function_decl, /* function_decl */ dwarf2out_global_decl, dwarf2out_type_decl, /* type_decl */ @@ -20619,6 +20621,28 @@ is_naming_typedef_decl (const_tree decl) != TYPE_NAME (TREE_TYPE (decl)))); } +/* Looks up the DIE for a context. */ + +static inline dw_die_ref +lookup_context_die (tree context) +{ + if (context) + { + /* Find die that represents this context. */ + if (TYPE_P (context)) + { + context = TYPE_MAIN_VARIANT (context); + dw_die_ref ctx = lookup_type_die (context); + if (!ctx) + return NULL; + return strip_naming_typedef (context, ctx); + } + else + return lookup_decl_die (context); + } + return comp_unit_die (); +} + /* Returns the DIE for a context. */ static inline dw_die_ref @@ -22016,6 +22040,26 @@ dwarf2out_end_function (unsigned int) maybe_at_text_label_p = false; } +/* Temporary holder for dwarf2out_register_main_translation_unit. Used to let + front-ends register a translation unit even before dwarf2out_init is + called. */ +static tree main_translation_unit = NULL_TREE; + +/* Hook called by front-ends after they built their main translation unit. + Associate comp_unit_die to UNIT. */ + +static void +dwarf2out_register_main_translation_unit (tree unit) +{ + gcc_assert (TREE_CODE (unit) == TRANSLATION_UNIT_DECL + && main_translation_unit == NULL_TREE); + main_translation_unit = unit; + /* If dwarf2out_init has not been called yet, it will perform the association + itself looking at main_translation_unit. */ + if (decl_die_table != NULL) + equate_decl_number_to_die (unit, comp_unit_die ()); +} + /* Add OPCODE+VAL as an entry at the end of the opcode array in TABLE. */ static void @@ -22753,6 +22797,11 @@ dwarf2out_init (const char *filename ATTRIBUTE_UNUSED) /* Make sure the line number table for .text always exists. */ text_section_line_info = new_line_info_table (); text_section_line_info->end_label = text_end_label; + + /* If front-ends already registered a main translation unit but we were not + ready to perform the association, do this now. */ + if (main_translation_unit != NULL_TREE) + equate_decl_number_to_die (main_translation_unit, comp_unit_die ()); } /* Called before compile () starts outputtting functions, variables @@ -23948,12 +23997,22 @@ resolve_addr (dw_die_ref die) { tree tdecl = SYMBOL_REF_DECL (a->dw_attr_val.v.val_addr); dw_die_ref tdie = lookup_decl_die (tdecl); + dw_die_ref cdie; if (tdie == NULL && DECL_EXTERNAL (tdecl) - && DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE) + && DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE + && (cdie = lookup_context_die (DECL_CONTEXT (tdecl)))) { - force_decl_die (tdecl); - tdie = lookup_decl_die (tdecl); + /* Creating a full DIE for tdecl is overly expensive and + at this point even wrong when in the LTO phase + as it can end up generating new type DIEs we didn't + output and thus optimize_external_refs will crash. */ + tdie = new_die (DW_TAG_subprogram, cdie, NULL_TREE); + add_AT_flag (tdie, DW_AT_external, 1); + add_AT_flag (tdie, DW_AT_declaration, 1); + add_linkage_attr (tdie, tdecl); + add_name_and_src_coords_attributes (tdie, tdecl); + equate_decl_number_to_die (tdecl, tdie); } if (tdie) { diff --git a/contrib/gcc-5.0/gcc/genattrtab.c b/contrib/gcc-5.0/gcc/genattrtab.c index 1fc6b2b6f7..424cb8808e 100644 --- a/contrib/gcc-5.0/gcc/genattrtab.c +++ b/contrib/gcc-5.0/gcc/genattrtab.c @@ -230,7 +230,7 @@ static int *insn_n_alternatives; /* Stores, for each insn code, a bitmap that has bits on for each possible alternative. */ -static int *insn_alternatives; +static uint64_t *insn_alternatives; /* Used to simplify expressions. */ @@ -258,7 +258,7 @@ static char *attr_printf (unsigned int, const char *, ...) ATTRIBUTE_PRINTF_2; static rtx make_numeric_value (int); static struct attr_desc *find_attr (const char **, int); -static rtx mk_attr_alt (int); +static rtx mk_attr_alt (uint64_t); static char *next_comma_elt (const char **); static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int); static rtx copy_boolean (rtx); @@ -769,7 +769,7 @@ check_attr_test (rtx exp, int is_const, int lineno) if (attr == NULL) { if (! strcmp (XSTR (exp, 0), "alternative")) - return mk_attr_alt (1 << atoi (XSTR (exp, 1))); + return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1))); else fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0)); } @@ -815,7 +815,7 @@ check_attr_test (rtx exp, int is_const, int lineno) name_ptr = XSTR (exp, 1); while ((p = next_comma_elt (&name_ptr)) != NULL) - set |= 1 << atoi (p); + set |= ((uint64_t) 1) << atoi (p); return mk_attr_alt (set); } @@ -1292,7 +1292,7 @@ static struct attr_value * get_attr_value (rtx value, struct attr_desc *attr, int insn_code) { struct attr_value *av; - int num_alt = 0; + uint64_t num_alt = 0; value = make_canonical (attr, value); if (compares_alternatives_p (value)) @@ -1934,7 +1934,7 @@ insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int ins This routine is passed an expression and either AND or IOR. It returns a bitmask indicating which alternatives are mentioned within EXP. */ -static int +static uint64_t compute_alternative_mask (rtx exp, enum rtx_code code) { const char *string; @@ -1965,15 +1965,15 @@ compute_alternative_mask (rtx exp, enum rtx_code code) return 0; if (string[1] == 0) - return 1 << (string[0] - '0'); - return 1 << atoi (string); + return ((uint64_t) 1) << (string[0] - '0'); + return ((uint64_t) 1) << atoi (string); } /* Given I, a single-bit mask, return RTX to compare the `alternative' attribute with the value represented by that bit. */ static rtx -make_alternative_compare (int mask) +make_alternative_compare (uint64_t mask) { return mk_attr_alt (mask); } @@ -2472,7 +2472,7 @@ attr_alt_complement (rtx s) in E. */ static rtx -mk_attr_alt (int e) +mk_attr_alt (uint64_t e) { rtx result = rtx_alloc (EQ_ATTR_ALT); @@ -2499,7 +2499,7 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index) struct attr_value *av; struct insn_ent *ie; struct attr_value_list *iv; - int i; + uint64_t i; rtx newexp = exp; bool left_alt, right_alt; @@ -2779,7 +2779,7 @@ simplify_test_exp (rtx exp, int insn_code, int insn_index) case EQ_ATTR: if (XSTR (exp, 0) == alternative_name) { - newexp = mk_attr_alt (1 << atoi (XSTR (exp, 1))); + newexp = mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1))); break; } @@ -5263,10 +5263,11 @@ main (int argc, char **argv) expand_delays (); /* Make `insn_alternatives'. */ - insn_alternatives = oballocvec (int, insn_code_number); + insn_alternatives = oballocvec (uint64_t, insn_code_number); for (id = defs; id; id = id->next) if (id->insn_code >= 0) - insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1; + insn_alternatives[id->insn_code] + = (((uint64_t) 1) << id->num_alternatives) - 1; /* Make `insn_n_alternatives'. */ insn_n_alternatives = oballocvec (int, insn_code_number); diff --git a/contrib/gcc-5.0/gcc/gimple-fold.c b/contrib/gcc-5.0/gcc/gimple-fold.c index 9458f96545..61ebc6c0aa 100644 --- a/contrib/gcc-5.0/gcc/gimple-fold.c +++ b/contrib/gcc-5.0/gcc/gimple-fold.c @@ -2530,7 +2530,7 @@ gimple_fold_builtin_snprintf (gimple_stmt_iterator *gsi) return false; tree orig_len = get_maxval_strlen (orig, 0); - if (!orig_len) + if (!orig_len || TREE_CODE (orig_len) != INTEGER_CST) return false; /* We could expand this as diff --git a/contrib/gcc-5.0/gcc/gimple-ssa-isolate-paths.c b/contrib/gcc-5.0/gcc/gimple-ssa-isolate-paths.c index de318f3483..e6dee0759b 100644 --- a/contrib/gcc-5.0/gcc/gimple-ssa-isolate-paths.c +++ b/contrib/gcc-5.0/gcc/gimple-ssa-isolate-paths.c @@ -510,10 +510,10 @@ gimple_ssa_isolate_erroneous_paths (void) /* We scramble the CFG and loop structures a bit, clean up appropriately. We really should incrementally update the loop structures, in theory it shouldn't be that hard. */ + free_dominance_info (CDI_POST_DOMINATORS); if (cfg_altered) { free_dominance_info (CDI_DOMINATORS); - free_dominance_info (CDI_POST_DOMINATORS); loops_state_set (LOOPS_NEED_FIXUP); return TODO_cleanup_cfg | TODO_update_ssa; } diff --git a/contrib/gcc-5.0/gcc/gimplify.c b/contrib/gcc-5.0/gcc/gimplify.c index 19c47b60c7..e00de258c7 100644 --- a/contrib/gcc-5.0/gcc/gimplify.c +++ b/contrib/gcc-5.0/gcc/gimplify.c @@ -2271,16 +2271,17 @@ gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location) return gimplify_expr (arg_p, pre_p, NULL, test, fb); } -/* Don't fold inside offloading regions: it can break code by adding decl - references that weren't in the source. We'll do it during omplower pass - instead. */ +/* Don't fold inside offloading or taskreg regions: it can break code by + adding decl references that weren't in the source. We'll do it during + omplower pass instead. */ static bool maybe_fold_stmt (gimple_stmt_iterator *gsi) { struct gimplify_omp_ctx *ctx; for (ctx = gimplify_omp_ctxp; ctx; ctx = ctx->outer_context) - if (ctx->region_type == ORT_TARGET) + if (ctx->region_type == ORT_TARGET + || (ctx->region_type & (ORT_PARALLEL | ORT_TASK)) != 0) return false; return fold_stmt (gsi); } diff --git a/contrib/gcc-5.0/gcc/ipa-prop.c b/contrib/gcc-5.0/gcc/ipa-prop.c index dc8f3606b1..d828ccf49d 100644 --- a/contrib/gcc-5.0/gcc/ipa-prop.c +++ b/contrib/gcc-5.0/gcc/ipa-prop.c @@ -2472,11 +2472,15 @@ update_jump_functions_after_inlining (struct cgraph_edge *cs, ctx.offset_by (dst->value.ancestor.offset); if (!ctx.useless_p ()) { - vec_safe_grow_cleared (args->polymorphic_call_contexts, - count); - dst_ctx = ipa_get_ith_polymorhic_call_context (args, i); + if (!dst_ctx) + { + vec_safe_grow_cleared (args->polymorphic_call_contexts, + count); + dst_ctx = ipa_get_ith_polymorhic_call_context (args, i); + } + + dst_ctx->combine_with (ctx); } - dst_ctx->combine_with (ctx); } if (src->agg.items diff --git a/contrib/gcc-5.0/gcc/ipa.c b/contrib/gcc-5.0/gcc/ipa.c index b3752de5e1..ca7cb7ad90 100644 --- a/contrib/gcc-5.0/gcc/ipa.c +++ b/contrib/gcc-5.0/gcc/ipa.c @@ -476,6 +476,20 @@ symbol_table::remove_unreachable_nodes (FILE *file) if (cnode->global.inlined_to) body_needed_for_clonning.add (cnode->decl); + /* For instrumentation clones we always need original + function node for proper LTO privatization. */ + if (cnode->instrumentation_clone + && cnode->definition) + { + gcc_assert (cnode->instrumented_version || in_lto_p); + if (cnode->instrumented_version) + { + enqueue_node (cnode->instrumented_version, &first, + &reachable); + reachable.add (cnode->instrumented_version); + } + } + /* For non-inline clones, force their origins to the boundary and ensure that body is not removed. */ while (cnode->clone_of) @@ -492,7 +506,7 @@ 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) diff --git a/contrib/gcc-5.0/gcc/lra-constraints.c b/contrib/gcc-5.0/gcc/lra-constraints.c index 8b62727911..4f2480e57e 100644 --- a/contrib/gcc-5.0/gcc/lra-constraints.c +++ b/contrib/gcc-5.0/gcc/lra-constraints.c @@ -5172,6 +5172,11 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail) for (reg = curr_static_id->hard_regs; reg != NULL; reg = reg->next) if (reg->type == OP_OUT && ! reg->subreg_p) bitmap_clear_bit (&live_regs, reg->regno); + if (curr_id->arg_hard_regs != NULL) + /* Make clobbered argument hard registers die. */ + for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) + if (regno >= FIRST_PSEUDO_REGISTER) + bitmap_clear_bit (&live_regs, regno - FIRST_PSEUDO_REGISTER); /* Mark each used value as live. */ for (reg = curr_id->regs; reg != NULL; reg = reg->next) if (reg->type != OP_OUT @@ -5182,9 +5187,10 @@ update_ebb_live_info (rtx_insn *head, rtx_insn *tail) && bitmap_bit_p (&check_only_regs, reg->regno)) bitmap_set_bit (&live_regs, reg->regno); if (curr_id->arg_hard_regs != NULL) - /* Make argument hard registers live. */ + /* Make used argument hard registers live. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) - if (bitmap_bit_p (&check_only_regs, regno)) + if (regno < FIRST_PSEUDO_REGISTER + && bitmap_bit_p (&check_only_regs, regno)) bitmap_set_bit (&live_regs, regno); /* It is quite important to remove dead move insns because it means removing dead store. We don't need to process them for @@ -5494,6 +5500,12 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) } } } + /* Process clobbered call regs. */ + if (curr_id->arg_hard_regs != NULL) + for (i = 0; (dst_regno = curr_id->arg_hard_regs[i]) >= 0; i++) + if (dst_regno >= FIRST_PSEUDO_REGISTER) + usage_insns[dst_regno - FIRST_PSEUDO_REGISTER].check + = -(int) INSN_UID (curr_insn); if (! JUMP_P (curr_insn)) for (i = 0; i < to_inherit_num; i++) if (inherit_reload_reg (true, to_inherit[i].regno, @@ -5601,7 +5613,7 @@ inherit_in_ebb (rtx_insn *head, rtx_insn *tail) add_next_usage_insn (src_regno, use_insn, reloads_num); } } - /* Process call args. */ + /* Process used call regs. */ if (curr_id->arg_hard_regs != NULL) for (i = 0; (src_regno = curr_id->arg_hard_regs[i]) >= 0; i++) if (src_regno < FIRST_PSEUDO_REGISTER) diff --git a/contrib/gcc-5.0/gcc/lra-int.h b/contrib/gcc-5.0/gcc/lra-int.h index 12923ee216..259c4c728e 100644 --- a/contrib/gcc-5.0/gcc/lra-int.h +++ b/contrib/gcc-5.0/gcc/lra-int.h @@ -229,9 +229,11 @@ struct lra_insn_recog_data duplication numbers: */ rtx **operand_loc; /* The operand locations, NULL if no operands. */ rtx **dup_loc; /* The dup locations, NULL if no dups. */ - /* Number of hard registers implicitly used in given call insn. The - value can be NULL or points to array of the hard register numbers - ending with a negative value. */ + /* Number of hard registers implicitly used/clobbered in given call + insn. The value can be NULL or points to array of the hard + register numbers ending with a negative value. To differ + clobbered and used hard regs, clobbered hard regs are incremented + by FIRST_PSEUDO_REGISTER. */ int *arg_hard_regs; /* Cached value of get_preferred_alternatives. */ alternative_mask preferred_alternatives; diff --git a/contrib/gcc-5.0/gcc/lra-lives.c b/contrib/gcc-5.0/gcc/lra-lives.c index 9dfffb6f28..eee5f191d8 100644 --- a/contrib/gcc-5.0/gcc/lra-lives.c +++ b/contrib/gcc-5.0/gcc/lra-lives.c @@ -801,7 +801,15 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) dst_regno = REGNO (SET_DEST (set)); if (dst_regno >= lra_constraint_new_regno_start && src_regno >= lra_constraint_new_regno_start) - lra_create_copy (dst_regno, src_regno, freq); + { + /* It might be still an original (non-reload) insn with + one unused output and a constraint requiring to use + the same reg for input/output operands. In this case + dst_regno and src_regno have the same value, we don't + need a misleading copy for this case. */ + if (dst_regno != src_regno) + lra_create_copy (dst_regno, src_regno, freq); + } else if (dst_regno >= lra_constraint_new_regno_start) { if ((hard_regno = src_regno) >= FIRST_PSEUDO_REGISTER) @@ -843,6 +851,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (reg->type != OP_IN) make_hard_regno_born (reg->regno, false); + if (curr_id->arg_hard_regs != NULL) + for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) + if (regno >= FIRST_PSEUDO_REGISTER) + /* It is a clobber. */ + make_hard_regno_born (regno - FIRST_PSEUDO_REGISTER, false); + sparseset_copy (unused_set, start_living); sparseset_clear (start_dying); @@ -858,6 +872,12 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) if (reg->type == OP_OUT && ! reg->early_clobber && ! reg->subreg_p) make_hard_regno_dead (reg->regno); + if (curr_id->arg_hard_regs != NULL) + for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) + if (regno >= FIRST_PSEUDO_REGISTER) + /* It is a clobber. */ + make_hard_regno_dead (regno - FIRST_PSEUDO_REGISTER); + if (call_p) { if (flag_ipa_ra) @@ -906,7 +926,8 @@ process_bb_lives (basic_block bb, int &curr_point, bool dead_insn_p) /* Make argument hard registers live. Don't create conflict of used REAL_PIC_OFFSET_TABLE_REGNUM and the pic pseudo. */ for (i = 0; (regno = curr_id->arg_hard_regs[i]) >= 0; i++) - make_hard_regno_born (regno, true); + if (regno < FIRST_PSEUDO_REGISTER) + make_hard_regno_born (regno, true); sparseset_and_compl (dead_set, start_living, start_dying); diff --git a/contrib/gcc-5.0/gcc/lra.c b/contrib/gcc-5.0/gcc/lra.c index f4d7a3c071..5e5db988f1 100644 --- a/contrib/gcc-5.0/gcc/lra.c +++ b/contrib/gcc-5.0/gcc/lra.c @@ -1088,6 +1088,7 @@ lra_set_insn_recog_data (rtx_insn *insn) data->arg_hard_regs = NULL; if (CALL_P (insn)) { + bool use_p; rtx link; int n_hard_regs, regno, arg_hard_regs[FIRST_PSEUDO_REGISTER]; @@ -1098,7 +1099,8 @@ lra_set_insn_recog_data (rtx_insn *insn) for (link = CALL_INSN_FUNCTION_USAGE (insn); link != NULL_RTX; link = XEXP (link, 1)) - if (GET_CODE (XEXP (link, 0)) == USE + if (((use_p = GET_CODE (XEXP (link, 0)) == USE) + || GET_CODE (XEXP (link, 0)) == CLOBBER) && REG_P (XEXP (XEXP (link, 0), 0))) { regno = REGNO (XEXP (XEXP (link, 0), 0)); @@ -1108,7 +1110,8 @@ lra_set_insn_recog_data (rtx_insn *insn) [regno][GET_MODE (XEXP (XEXP (link, 0), 0))]) - 1; i >= 0; i--) - arg_hard_regs[n_hard_regs++] = regno + i; + arg_hard_regs[n_hard_regs++] + = regno + i + (use_p ? 0 : FIRST_PSEUDO_REGISTER); } if (n_hard_regs != 0) { diff --git a/contrib/gcc-5.0/gcc/lto-cgraph.c b/contrib/gcc-5.0/gcc/lto-cgraph.c index ac50e4bbd2..ea352f1c18 100644 --- a/contrib/gcc-5.0/gcc/lto-cgraph.c +++ b/contrib/gcc-5.0/gcc/lto-cgraph.c @@ -805,8 +805,33 @@ output_refs (lto_symtab_encoder_t encoder) { symtab_node *node = lto_symtab_encoder_deref (encoder, i); + /* IPA_REF_ALIAS and IPA_REF_CHKP references are always preserved + in the boundary. Alias node can't have other references and + can be always handled as if it's not in the boundary. */ if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node)) - continue; + { + cgraph_node *cnode = dyn_cast (node); + /* Output IPA_REF_CHKP reference. */ + if (cnode + && cnode->instrumented_version + && !cnode->instrumentation_clone) + { + for (int i = 0; node->iterate_reference (i, ref); i++) + if (ref->use == IPA_REF_CHKP) + { + if (lto_symtab_encoder_lookup (encoder, ref->referred) + != LCC_NOT_FOUND) + { + int nref = lto_symtab_encoder_lookup (encoder, node); + streamer_write_gcov_count_stream (ob->main_stream, 1); + streamer_write_uhwi_stream (ob->main_stream, nref); + lto_output_ref (ob, ref, encoder); + } + break; + } + } + continue; + } count = node->ref_list.nreferences (); if (count) diff --git a/contrib/gcc-5.0/gcc/lto-wrapper.c b/contrib/gcc-5.0/gcc/lto-wrapper.c index aa51476d2b..bbd4ff8add 100644 --- a/contrib/gcc-5.0/gcc/lto-wrapper.c +++ b/contrib/gcc-5.0/gcc/lto-wrapper.c @@ -273,6 +273,7 @@ merge_and_complain (struct cl_decoded_option **decoded_options, case OPT_fwrapv: case OPT_fopenmp: case OPT_fopenacc: + case OPT_fcheck_pointer_bounds: /* For selected options we can merge conservatively. */ for (j = 0; j < *decoded_options_count; ++j) if ((*decoded_options)[j].opt_index == foption->opt_index) @@ -503,6 +504,7 @@ append_compiler_options (obstack *argv_obstack, struct cl_decoded_option *opts, case OPT_Ofast: case OPT_Og: case OPT_Os: + case OPT_fcheck_pointer_bounds: break; default: diff --git a/contrib/gcc-5.0/gcc/lto/lto-partition.c b/contrib/gcc-5.0/gcc/lto/lto-partition.c index 235b735a8f..7d117e9a49 100644 --- a/contrib/gcc-5.0/gcc/lto/lto-partition.c +++ b/contrib/gcc-5.0/gcc/lto/lto-partition.c @@ -877,27 +877,13 @@ validize_symbol_for_target (symtab_node *node) } } -/* Mangle NODE symbol name into a local name. - This is necessary to do - 1) if two or more static vars of same assembler name - are merged into single ltrans unit. - 2) if previously static var was promoted hidden to avoid possible conflict - with symbols defined out of the LTO world. */ +/* Helper for privatize_symbol_name. Mangle NODE symbol name + represented by DECL. */ static bool -privatize_symbol_name (symtab_node *node) +privatize_symbol_name_1 (symtab_node *node, tree decl) { - tree decl = node->decl; - const char *name; - cgraph_node *cnode = dyn_cast (node); - - /* If we want to privatize instrumentation clone - then we need to change original function name - which is used via transparent alias chain. */ - if (cnode && cnode->instrumentation_clone) - decl = cnode->orig_decl; - - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); + const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); if (must_not_rename (node, name)) return false; @@ -906,31 +892,57 @@ privatize_symbol_name (symtab_node *node) symtab->change_decl_assembler_name (decl, clone_function_name_1 (name, "lto_priv")); + if (node->lto_file_data) lto_record_renamed_decl (node->lto_file_data, name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); + + if (symtab->dump_file) + fprintf (symtab->dump_file, + "Privatizing symbol name: %s -> %s\n", + name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); + + return true; +} + +/* Mangle NODE symbol name into a local name. + This is necessary to do + 1) if two or more static vars of same assembler name + are merged into single ltrans unit. + 2) if previously static var was promoted hidden to avoid possible conflict + with symbols defined out of the LTO world. */ + +static bool +privatize_symbol_name (symtab_node *node) +{ + if (!privatize_symbol_name_1 (node, node->decl)) + return false; + /* We could change name which is a target of transparent alias chain of instrumented function name. Fix alias chain if so .*/ - if (cnode) + if (cgraph_node *cnode = dyn_cast (node)) { tree iname = NULL_TREE; if (cnode->instrumentation_clone) - iname = DECL_ASSEMBLER_NAME (cnode->decl); + { + /* If we want to privatize instrumentation clone + then we also need to privatize original function. */ + if (cnode->instrumented_version) + privatize_symbol_name (cnode->instrumented_version); + else + privatize_symbol_name_1 (cnode, cnode->orig_decl); + iname = DECL_ASSEMBLER_NAME (cnode->decl); + TREE_CHAIN (iname) = DECL_ASSEMBLER_NAME (cnode->orig_decl); + } else if (cnode->instrumented_version - && cnode->instrumented_version->orig_decl == decl) - iname = DECL_ASSEMBLER_NAME (cnode->instrumented_version->decl); - - if (iname) + && cnode->instrumented_version->orig_decl == cnode->decl) { - gcc_assert (IDENTIFIER_TRANSPARENT_ALIAS (iname)); - TREE_CHAIN (iname) = DECL_ASSEMBLER_NAME (decl); + iname = DECL_ASSEMBLER_NAME (cnode->instrumented_version->decl); + TREE_CHAIN (iname) = DECL_ASSEMBLER_NAME (cnode->decl); } } - if (symtab->dump_file) - fprintf (symtab->dump_file, - "Privatizing symbol name: %s -> %s\n", - name, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))); + return true; } diff --git a/contrib/gcc-5.0/gcc/match.pd b/contrib/gcc-5.0/gcc/match.pd index 0e002c7158..e40720e130 100644 --- a/contrib/gcc-5.0/gcc/match.pd +++ b/contrib/gcc-5.0/gcc/match.pd @@ -759,7 +759,8 @@ along with GCC; see the file COPYING3. If not see /* If we are converting an integer to a floating-point that can represent it exactly and back to an integer, we can skip the floating-point conversion. */ - (if (inside_int && inter_float && final_int && + (if (GIMPLE /* PR66211 */ + && inside_int && inter_float && final_int && (unsigned) significand_size (TYPE_MODE (inter_type)) >= inside_prec - !inside_unsignedp) (convert @0)))))) diff --git a/contrib/gcc-5.0/gcc/omp-low.c b/contrib/gcc-5.0/gcc/omp-low.c index 50e3ae5f88..552994b5b5 100644 --- a/contrib/gcc-5.0/gcc/omp-low.c +++ b/contrib/gcc-5.0/gcc/omp-low.c @@ -5599,7 +5599,9 @@ expand_omp_taskreg (struct omp_region *region) vec_safe_truncate (child_cfun->local_decls, dstidx); /* Inform the callgraph about the new function. */ - DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties; + child_cfun->curr_properties = cfun->curr_properties; + child_cfun->has_simduid_loops |= cfun->has_simduid_loops; + child_cfun->has_force_vectorize_loops |= cfun->has_force_vectorize_loops; cgraph_node::add_new_function (child_fn, true); cgraph_node::get (child_fn)->parallelized_function = 1; @@ -7847,6 +7849,8 @@ expand_omp_simd (struct omp_region *region, struct omp_for_data *fd) cfun->has_force_vectorize_loops = true; } } + else if (simduid) + cfun->has_simduid_loops = true; } @@ -8967,7 +8971,9 @@ expand_omp_target (struct omp_region *region) vec_safe_truncate (child_cfun->local_decls, dstidx); /* Inform the callgraph about the new function. */ - DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties; + child_cfun->curr_properties = cfun->curr_properties; + child_cfun->has_simduid_loops |= cfun->has_simduid_loops; + child_cfun->has_force_vectorize_loops |= cfun->has_force_vectorize_loops; cgraph_node::add_new_function (child_fn, true); #ifdef ENABLE_OFFLOADING @@ -11909,8 +11915,8 @@ lower_omp (gimple_seq *body, omp_context *ctx) for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi)) lower_omp_1 (&gsi, ctx); /* During gimplification, we haven't folded statments inside offloading - regions (gimplify.c:maybe_fold_stmt); do that now. */ - if (target_nesting_level) + or taskreg regions (gimplify.c:maybe_fold_stmt); do that now. */ + if (target_nesting_level || taskreg_nesting_level) for (gsi = gsi_start (*body); !gsi_end_p (gsi); gsi_next (&gsi)) fold_stmt (&gsi); input_location = saved_location; @@ -13431,12 +13437,54 @@ simd_clone_adjust (struct cgraph_node *node) uniform args with __builtin_assume_aligned (arg_N(D), alignment) lhs. Handle linear by adding PHIs. */ for (unsigned i = 0; i < node->simdclone->nargs; i++) - if (node->simdclone->args[i].alignment - && node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM - && (node->simdclone->args[i].alignment - & (node->simdclone->args[i].alignment - 1)) == 0 - && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg)) - == POINTER_TYPE) + if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM + && (TREE_ADDRESSABLE (node->simdclone->args[i].orig_arg) + || !is_gimple_reg_type + (TREE_TYPE (node->simdclone->args[i].orig_arg)))) + { + tree orig_arg = node->simdclone->args[i].orig_arg; + if (is_gimple_reg_type (TREE_TYPE (orig_arg))) + iter1 = make_ssa_name (TREE_TYPE (orig_arg)); + else + { + iter1 = create_tmp_var_raw (TREE_TYPE (orig_arg)); + gimple_add_tmp_var (iter1); + } + gsi = gsi_after_labels (entry_bb); + g = gimple_build_assign (iter1, orig_arg); + gsi_insert_before (&gsi, g, GSI_NEW_STMT); + gsi = gsi_after_labels (body_bb); + g = gimple_build_assign (orig_arg, iter1); + gsi_insert_before (&gsi, g, GSI_NEW_STMT); + } + else if (node->simdclone->args[i].arg_type == SIMD_CLONE_ARG_TYPE_UNIFORM + && DECL_BY_REFERENCE (node->simdclone->args[i].orig_arg) + && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg)) + == REFERENCE_TYPE + && TREE_ADDRESSABLE + (TREE_TYPE (TREE_TYPE (node->simdclone->args[i].orig_arg)))) + { + tree orig_arg = node->simdclone->args[i].orig_arg; + tree def = ssa_default_def (cfun, orig_arg); + if (def && !has_zero_uses (def)) + { + iter1 = create_tmp_var_raw (TREE_TYPE (TREE_TYPE (orig_arg))); + gimple_add_tmp_var (iter1); + gsi = gsi_after_labels (entry_bb); + g = gimple_build_assign (iter1, build_simple_mem_ref (def)); + gsi_insert_before (&gsi, g, GSI_NEW_STMT); + gsi = gsi_after_labels (body_bb); + g = gimple_build_assign (build_simple_mem_ref (def), iter1); + gsi_insert_before (&gsi, g, GSI_NEW_STMT); + } + } + else if (node->simdclone->args[i].alignment + && node->simdclone->args[i].arg_type + == SIMD_CLONE_ARG_TYPE_UNIFORM + && (node->simdclone->args[i].alignment + & (node->simdclone->args[i].alignment - 1)) == 0 + && TREE_CODE (TREE_TYPE (node->simdclone->args[i].orig_arg)) + == POINTER_TYPE) { unsigned int alignment = node->simdclone->args[i].alignment; tree orig_arg = node->simdclone->args[i].orig_arg; @@ -13486,13 +13534,31 @@ simd_clone_adjust (struct cgraph_node *node) == SIMD_CLONE_ARG_TYPE_LINEAR_CONSTANT_STEP) { tree orig_arg = node->simdclone->args[i].orig_arg; - tree def = ssa_default_def (cfun, orig_arg); gcc_assert (INTEGRAL_TYPE_P (TREE_TYPE (orig_arg)) || POINTER_TYPE_P (TREE_TYPE (orig_arg))); - if (def && !has_zero_uses (def)) + tree def = NULL_TREE; + if (TREE_ADDRESSABLE (orig_arg)) + { + def = make_ssa_name (TREE_TYPE (orig_arg)); + iter1 = make_ssa_name (TREE_TYPE (orig_arg)); + iter2 = make_ssa_name (TREE_TYPE (orig_arg)); + gsi = gsi_after_labels (entry_bb); + g = gimple_build_assign (def, orig_arg); + gsi_insert_before (&gsi, g, GSI_NEW_STMT); + } + else + { + def = ssa_default_def (cfun, orig_arg); + if (!def || has_zero_uses (def)) + def = NULL_TREE; + else + { + iter1 = make_ssa_name (orig_arg); + iter2 = make_ssa_name (orig_arg); + } + } + if (def) { - iter1 = make_ssa_name (orig_arg); - iter2 = make_ssa_name (orig_arg); phi = create_phi_node (iter1, body_bb); add_phi_arg (phi, def, preheader_edge, UNKNOWN_LOCATION); add_phi_arg (phi, iter2, latch_edge, UNKNOWN_LOCATION); @@ -13509,12 +13575,19 @@ simd_clone_adjust (struct cgraph_node *node) imm_use_iterator iter; use_operand_p use_p; gimple use_stmt; - FOR_EACH_IMM_USE_STMT (use_stmt, iter, def) - if (use_stmt == phi) - continue; - else - FOR_EACH_IMM_USE_ON_STMT (use_p, iter) - SET_USE (use_p, iter1); + if (TREE_ADDRESSABLE (orig_arg)) + { + gsi = gsi_after_labels (body_bb); + g = gimple_build_assign (orig_arg, iter1); + gsi_insert_before (&gsi, g, GSI_NEW_STMT); + } + else + FOR_EACH_IMM_USE_STMT (use_stmt, iter, def) + if (use_stmt == phi) + continue; + else + FOR_EACH_IMM_USE_ON_STMT (use_p, iter) + SET_USE (use_p, iter1); } } diff --git a/contrib/gcc-5.0/gcc/optabs.c b/contrib/gcc-5.0/gcc/optabs.c index e9dc7981c6..6dc994c8da 100644 --- a/contrib/gcc-5.0/gcc/optabs.c +++ b/contrib/gcc-5.0/gcc/optabs.c @@ -6786,11 +6786,11 @@ expand_vec_perm (machine_mode mode, rtx v0, rtx v1, rtx sel, rtx target) machine_mode selmode = GET_MODE (sel); if (u == 2) sel = expand_simple_binop (selmode, PLUS, sel, sel, - sel, 0, OPTAB_DIRECT); + NULL, 0, OPTAB_DIRECT); else sel = expand_simple_binop (selmode, ASHIFT, sel, GEN_INT (exact_log2 (u)), - sel, 0, OPTAB_DIRECT); + NULL, 0, OPTAB_DIRECT); gcc_assert (sel != NULL); /* Broadcast the low byte each element into each of its bytes. */ diff --git a/contrib/gcc-5.0/gcc/passes.def b/contrib/gcc-5.0/gcc/passes.def index 1d598b2999..f77d3d30b0 100644 --- a/contrib/gcc-5.0/gcc/passes.def +++ b/contrib/gcc-5.0/gcc/passes.def @@ -270,6 +270,7 @@ along with GCC; see the file COPYING3. If not see PUSH_INSERT_PASSES_WITHIN (pass_tree_no_loop) NEXT_PASS (pass_slp_vectorize); POP_INSERT_PASSES () + NEXT_PASS (pass_simduid_cleanup); NEXT_PASS (pass_lower_vector_ssa); NEXT_PASS (pass_cse_reciprocals); NEXT_PASS (pass_reassoc); diff --git a/contrib/gcc-5.0/gcc/postreload.c b/contrib/gcc-5.0/gcc/postreload.c index 30fa4498dc..58b586a2e4 100644 --- a/contrib/gcc-5.0/gcc/postreload.c +++ b/contrib/gcc-5.0/gcc/postreload.c @@ -1363,9 +1363,12 @@ reload_combine (void) if (CALL_P (insn)) { rtx link; + HARD_REG_SET used_regs; + + get_call_reg_set_usage (insn, &used_regs, call_used_reg_set); for (r = 0; r < FIRST_PSEUDO_REGISTER; r++) - if (call_used_regs[r]) + if (TEST_HARD_REG_BIT (used_regs, r)) { reg_state[r].use_index = RELOAD_COMBINE_MAX_USES; reg_state[r].store_ruid = reload_combine_ruid; @@ -2161,12 +2164,29 @@ reload_cse_move2add (rtx_insn *first) unknown values. */ if (CALL_P (insn)) { + rtx link; + for (i = FIRST_PSEUDO_REGISTER - 1; i >= 0; i--) { if (call_used_regs[i]) /* Reset the information about this register. */ reg_mode[i] = VOIDmode; } + + for (link = CALL_INSN_FUNCTION_USAGE (insn); link; + link = XEXP (link, 1)) + { + rtx setuse = XEXP (link, 0); + rtx usage_rtx = XEXP (setuse, 0); + if (GET_CODE (setuse) == CLOBBER + && REG_P (usage_rtx)) + { + unsigned int end_regno = END_REGNO (usage_rtx); + for (unsigned int r = REGNO (usage_rtx); r < end_regno; ++r) + /* Reset the information about this register. */ + reg_mode[r] = VOIDmode; + } + } } } return changed; diff --git a/contrib/gcc-5.0/gcc/recog.h b/contrib/gcc-5.0/gcc/recog.h index 45ea671963..3a0d7e27cf 100644 --- a/contrib/gcc-5.0/gcc/recog.h +++ b/contrib/gcc-5.0/gcc/recog.h @@ -23,8 +23,8 @@ along with GCC; see the file COPYING3. If not see /* Random number that should be large enough for all purposes. Also define a type that has at least MAX_RECOG_ALTERNATIVES + 1 bits, with the extra bit giving an invalid value that can be used to mean "uninitialized". */ -#define MAX_RECOG_ALTERNATIVES 30 -typedef unsigned int alternative_mask; +#define MAX_RECOG_ALTERNATIVES 35 +typedef uint64_t alternative_mask; /* A mask of all alternatives. */ #define ALL_ALTERNATIVES ((alternative_mask) -1) diff --git a/contrib/gcc-5.0/gcc/sdbout.c b/contrib/gcc-5.0/gcc/sdbout.c index b4f7325ee3..dd12c67e9c 100644 --- a/contrib/gcc-5.0/gcc/sdbout.c +++ b/contrib/gcc-5.0/gcc/sdbout.c @@ -303,6 +303,7 @@ const struct gcc_debug_hooks sdb_debug_hooks = sdbout_end_epilogue, /* end_epilogue */ sdbout_begin_function, /* begin_function */ sdbout_end_function, /* end_function */ + debug_nothing_tree, /* register_main_translation_unit */ debug_nothing_tree, /* function_decl */ sdbout_global_decl, /* global_decl */ sdbout_symbol, /* type_decl */ diff --git a/contrib/gcc-5.0/gcc/simplify-rtx.c b/contrib/gcc-5.0/gcc/simplify-rtx.c index 5d1749829b..cdad71fa3f 100644 --- a/contrib/gcc-5.0/gcc/simplify-rtx.c +++ b/contrib/gcc-5.0/gcc/simplify-rtx.c @@ -4928,7 +4928,8 @@ simplify_const_relational_operation (enum rtx_code code, /* Optimize comparisons with upper and lower bounds. */ if (HWI_COMPUTABLE_MODE_P (mode) - && CONST_INT_P (trueop1)) + && CONST_INT_P (trueop1) + && !side_effects_p (trueop0)) { int sign; unsigned HOST_WIDE_INT nonzero = nonzero_bits (trueop0, mode); @@ -5041,7 +5042,7 @@ simplify_const_relational_operation (enum rtx_code code, } /* Optimize integer comparisons with zero. */ - if (trueop1 == const0_rtx) + if (trueop1 == const0_rtx && !side_effects_p (trueop0)) { /* Some addresses are known to be nonzero. We don't know their sign, but equality comparisons are known. */ @@ -5092,7 +5093,7 @@ simplify_const_relational_operation (enum rtx_code code, } /* Optimize comparison of ABS with zero. */ - if (trueop1 == CONST0_RTX (mode) + if (trueop1 == CONST0_RTX (mode) && !side_effects_p (trueop0) && (GET_CODE (trueop0) == ABS || (GET_CODE (trueop0) == FLOAT_EXTEND && GET_CODE (XEXP (trueop0, 0)) == ABS))) diff --git a/contrib/gcc-5.0/gcc/toplev.c b/contrib/gcc-5.0/gcc/toplev.c index b06eed3e99..cb6c51739f 100644 --- a/contrib/gcc-5.0/gcc/toplev.c +++ b/contrib/gcc-5.0/gcc/toplev.c @@ -601,6 +601,11 @@ compile_file (void) if (flag_syntax_only || flag_wpa) return; + + /* Reset maximum_field_alignment, it can be adjusted by #pragma pack + and this shouldn't influence any types built by the middle-end + from now on (like gcov_info_type). */ + maximum_field_alignment = initial_max_fld_align * BITS_PER_UNIT; ggc_protect_identifiers = false; @@ -1314,20 +1319,6 @@ process_options (void) so we can correctly initialize debug output. */ no_backend = lang_hooks.post_options (&main_input_filename); - /* Set default values for parameters relation to the Scalar Reduction - of Aggregates passes (SRA and IP-SRA). We must do this here, rather - than in opts.c:default_options_optimization as historically these - tuning heuristics have been based on MOVE_RATIO, which on some - targets requires other symbols from the backend. */ - maybe_set_param_value - (PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED, - get_move_ratio (true) * UNITS_PER_WORD, - global_options.x_param_values, global_options_set.x_param_values); - maybe_set_param_value - (PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE, - get_move_ratio (false) * UNITS_PER_WORD, - global_options.x_param_values, global_options_set.x_param_values); - /* Some machines may reject certain combinations of options. */ targetm.target_option.override (); diff --git a/contrib/gcc-5.0/gcc/tree-chkp.c b/contrib/gcc-5.0/gcc/tree-chkp.c index 8c5a628a9a..c2d9e94596 100644 --- a/contrib/gcc-5.0/gcc/tree-chkp.c +++ b/contrib/gcc-5.0/gcc/tree-chkp.c @@ -529,6 +529,71 @@ chkp_insert_retbnd_call (tree bndval, tree retval, return bndval; } +/* Build a GIMPLE_CALL identical to CALL but skipping bounds + arguments. */ + +gcall * +chkp_copy_call_skip_bounds (gcall *call) +{ + bitmap bounds; + unsigned i; + + bitmap_obstack_initialize (NULL); + bounds = BITMAP_ALLOC (NULL); + + for (i = 0; i < gimple_call_num_args (call); i++) + if (POINTER_BOUNDS_P (gimple_call_arg (call, i))) + bitmap_set_bit (bounds, i); + + if (!bitmap_empty_p (bounds)) + call = gimple_call_copy_skip_args (call, bounds); + gimple_call_set_with_bounds (call, false); + + BITMAP_FREE (bounds); + bitmap_obstack_release (NULL); + + return call; +} + +/* Redirect edge E to the correct node according to call_stmt. + Return 1 if bounds removal from call_stmt should be done + instead of redirection. */ + +bool +chkp_redirect_edge (cgraph_edge *e) +{ + bool instrumented = false; + tree decl = e->callee->decl; + + if (e->callee->instrumentation_clone + || chkp_function_instrumented_p (decl)) + instrumented = true; + + if (instrumented + && !gimple_call_with_bounds_p (e->call_stmt)) + e->redirect_callee (cgraph_node::get_create (e->callee->orig_decl)); + else if (!instrumented + && gimple_call_with_bounds_p (e->call_stmt) + && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCL) + && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDCU) + && !chkp_gimple_call_builtin_p (e->call_stmt, BUILT_IN_CHKP_BNDSTX)) + { + if (e->callee->instrumented_version) + e->redirect_callee (e->callee->instrumented_version); + else + { + tree args = TYPE_ARG_TYPES (TREE_TYPE (decl)); + /* Avoid bounds removal if all args will be removed. */ + if (!args || TREE_VALUE (args) != void_type_node) + return true; + else + gimple_call_set_with_bounds (e->call_stmt, false); + } + } + + return false; +} + /* Mark statement S to not be instrumented. */ static void chkp_mark_stmt (gimple s) diff --git a/contrib/gcc-5.0/gcc/tree-chkp.h b/contrib/gcc-5.0/gcc/tree-chkp.h index 1bafe994da..b5ab56252e 100644 --- a/contrib/gcc-5.0/gcc/tree-chkp.h +++ b/contrib/gcc-5.0/gcc/tree-chkp.h @@ -56,5 +56,7 @@ extern bool chkp_gimple_call_builtin_p (gimple call, extern void chkp_expand_bounds_reset_for_mem (tree mem, tree ptr); extern tree chkp_insert_retbnd_call (tree bndval, tree retval, gimple_stmt_iterator *gsi); +extern gcall *chkp_copy_call_skip_bounds (gcall *call); +extern bool chkp_redirect_edge (cgraph_edge *e); #endif /* GCC_TREE_CHKP_H */ diff --git a/contrib/gcc-5.0/gcc/tree-data-ref.c b/contrib/gcc-5.0/gcc/tree-data-ref.c index 3d1d5f8c0f..57e26d1d95 100644 --- a/contrib/gcc-5.0/gcc/tree-data-ref.c +++ b/contrib/gcc-5.0/gcc/tree-data-ref.c @@ -1036,6 +1036,7 @@ dr_analyze_indices (struct data_reference *dr, loop_p nest, loop_p loop) base, memoff); MR_DEPENDENCE_CLIQUE (ref) = MR_DEPENDENCE_CLIQUE (old); MR_DEPENDENCE_BASE (ref) = MR_DEPENDENCE_BASE (old); + DR_UNCONSTRAINED_BASE (dr) = true; access_fns.safe_push (access_fn); } } @@ -1453,7 +1454,8 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, offset/overlap based analysis but have to rely on points-to information only. */ if (TREE_CODE (addr_a) == MEM_REF - && TREE_CODE (TREE_OPERAND (addr_a, 0)) == SSA_NAME) + && (DR_UNCONSTRAINED_BASE (a) + || TREE_CODE (TREE_OPERAND (addr_a, 0)) == SSA_NAME)) { /* For true dependences we can apply TBAA. */ if (flag_strict_aliasing @@ -1469,7 +1471,8 @@ dr_may_alias_p (const struct data_reference *a, const struct data_reference *b, build_fold_addr_expr (addr_b)); } else if (TREE_CODE (addr_b) == MEM_REF - && TREE_CODE (TREE_OPERAND (addr_b, 0)) == SSA_NAME) + && (DR_UNCONSTRAINED_BASE (b) + || TREE_CODE (TREE_OPERAND (addr_b, 0)) == SSA_NAME)) { /* For true dependences we can apply TBAA. */ if (flag_strict_aliasing diff --git a/contrib/gcc-5.0/gcc/tree-data-ref.h b/contrib/gcc-5.0/gcc/tree-data-ref.h index edb3b562b8..9d8e6992f8 100644 --- a/contrib/gcc-5.0/gcc/tree-data-ref.h +++ b/contrib/gcc-5.0/gcc/tree-data-ref.h @@ -81,6 +81,10 @@ struct indices /* A list of chrecs. Access functions of the indices. */ vec access_fns; + + /* Whether BASE_OBJECT is an access representing the whole object + or whether the access could not be constrained. */ + bool unconstrained_base; }; struct dr_alias @@ -129,6 +133,7 @@ struct data_reference #define DR_STMT(DR) (DR)->stmt #define DR_REF(DR) (DR)->ref #define DR_BASE_OBJECT(DR) (DR)->indices.base_object +#define DR_UNCONSTRAINED_BASE(DR) (DR)->indices.unconstrained_base #define DR_ACCESS_FNS(DR) (DR)->indices.access_fns #define DR_ACCESS_FN(DR, I) DR_ACCESS_FNS (DR)[I] #define DR_NUM_DIMENSIONS(DR) DR_ACCESS_FNS (DR).length () diff --git a/contrib/gcc-5.0/gcc/tree-if-conv.c b/contrib/gcc-5.0/gcc/tree-if-conv.c index 400ee01a51..5a901af5ad 100644 --- a/contrib/gcc-5.0/gcc/tree-if-conv.c +++ b/contrib/gcc-5.0/gcc/tree-if-conv.c @@ -666,7 +666,7 @@ memrefs_read_or_written_unconditionally (gimple stmt, || TREE_CODE (ref_base_b) == REALPART_EXPR) ref_base_b = TREE_OPERAND (ref_base_b, 0); - if (!operand_equal_p (ref_base_a, ref_base_b, 0)) + if (operand_equal_p (ref_base_a, ref_base_b, 0)) { tree cb = bb_predicate (gimple_bb (DR_STMT (b))); diff --git a/contrib/gcc-5.0/gcc/tree-inline.c b/contrib/gcc-5.0/gcc/tree-inline.c index 83e43356f6..70d0102124 100644 --- a/contrib/gcc-5.0/gcc/tree-inline.c +++ b/contrib/gcc-5.0/gcc/tree-inline.c @@ -3033,7 +3033,7 @@ insert_init_debug_bind (copy_body_data *id, base_stmt = gsi_stmt (gsi); } - note = gimple_build_debug_bind (tracked_var, value, base_stmt); + note = gimple_build_debug_bind (tracked_var, unshare_expr (value), base_stmt); if (bb) { diff --git a/contrib/gcc-5.0/gcc/tree-nested.c b/contrib/gcc-5.0/gcc/tree-nested.c index f2e6d3acfd..4991219c19 100644 --- a/contrib/gcc-5.0/gcc/tree-nested.c +++ b/contrib/gcc-5.0/gcc/tree-nested.c @@ -790,10 +790,12 @@ get_static_chain (struct nesting_info *info, tree target_context, if (info->context == target_context) { x = build_addr (info->frame_decl, target_context); + info->static_chain_added |= 1; } else { x = get_chain_decl (info); + info->static_chain_added |= 2; for (i = info->outer; i->context != target_context; i = i->outer) { @@ -825,10 +827,12 @@ get_frame_field (struct nesting_info *info, tree target_context, /* Make sure frame_decl gets created. */ (void) get_frame_type (info); x = info->frame_decl; + info->static_chain_added |= 1; } else { x = get_chain_decl (info); + info->static_chain_added |= 2; for (i = info->outer; i->context != target_context; i = i->outer) { @@ -874,10 +878,12 @@ get_nonlocal_debug_decl (struct nesting_info *info, tree decl) (void) get_frame_type (info); x = info->frame_decl; i = info; + info->static_chain_added |= 1; } else { x = get_chain_decl (info); + info->static_chain_added |= 2; for (i = info->outer; i->context != target_context; i = i->outer) { field = get_chain_field (i); @@ -2311,17 +2317,55 @@ convert_tramp_reference_stmt (gimple_stmt_iterator *gsi, bool *handled_ops_p, case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: { - tree save_local_var_chain; + tree save_local_var_chain = info->new_local_var_chain; walk_gimple_op (stmt, convert_tramp_reference_op, wi); - save_local_var_chain = info->new_local_var_chain; info->new_local_var_chain = NULL; + char save_static_chain_added = info->static_chain_added; + info->static_chain_added = 0; walk_body (convert_tramp_reference_stmt, convert_tramp_reference_op, info, gimple_omp_body_ptr (stmt)); if (info->new_local_var_chain) declare_vars (info->new_local_var_chain, gimple_seq_first_stmt (gimple_omp_body (stmt)), false); + for (int i = 0; i < 2; i++) + { + tree c, decl; + if ((info->static_chain_added & (1 << i)) == 0) + continue; + decl = i ? get_chain_decl (info) : info->frame_decl; + /* Don't add CHAIN.* or FRAME.* twice. */ + for (c = gimple_omp_taskreg_clauses (stmt); + c; + c = OMP_CLAUSE_CHAIN (c)) + if ((OMP_CLAUSE_CODE (c) == OMP_CLAUSE_FIRSTPRIVATE + || OMP_CLAUSE_CODE (c) == OMP_CLAUSE_SHARED) + && OMP_CLAUSE_DECL (c) == decl) + break; + if (c == NULL && gimple_code (stmt) != GIMPLE_OMP_TARGET) + { + c = build_omp_clause (gimple_location (stmt), + i ? OMP_CLAUSE_FIRSTPRIVATE + : OMP_CLAUSE_SHARED); + OMP_CLAUSE_DECL (c) = decl; + OMP_CLAUSE_CHAIN (c) = gimple_omp_taskreg_clauses (stmt); + gimple_omp_taskreg_set_clauses (stmt, c); + } + else if (c == NULL) + { + c = build_omp_clause (gimple_location (stmt), + OMP_CLAUSE_MAP); + OMP_CLAUSE_DECL (c) = decl; + OMP_CLAUSE_SET_MAP_KIND (c, + i ? GOMP_MAP_TO : GOMP_MAP_TOFROM); + OMP_CLAUSE_SIZE (c) = DECL_SIZE_UNIT (decl); + OMP_CLAUSE_CHAIN (c) = gimple_omp_target_clauses (stmt); + gimple_omp_target_set_clauses (as_a (stmt), + c); + } + } info->new_local_var_chain = save_local_var_chain; + info->static_chain_added |= save_static_chain_added; } break; diff --git a/contrib/gcc-5.0/gcc/tree-pass.h b/contrib/gcc-5.0/gcc/tree-pass.h index bc8763db16..51ebcd7f09 100644 --- a/contrib/gcc-5.0/gcc/tree-pass.h +++ b/contrib/gcc-5.0/gcc/tree-pass.h @@ -371,6 +371,7 @@ extern gimple_opt_pass *make_pass_graphite_transforms (gcc::context *ctxt); extern gimple_opt_pass *make_pass_if_conversion (gcc::context *ctxt); extern gimple_opt_pass *make_pass_loop_distribution (gcc::context *ctxt); extern gimple_opt_pass *make_pass_vectorize (gcc::context *ctxt); +extern gimple_opt_pass *make_pass_simduid_cleanup (gcc::context *ctxt); extern gimple_opt_pass *make_pass_slp_vectorize (gcc::context *ctxt); extern gimple_opt_pass *make_pass_complete_unroll (gcc::context *ctxt); extern gimple_opt_pass *make_pass_complete_unrolli (gcc::context *ctxt); diff --git a/contrib/gcc-5.0/gcc/tree-scalar-evolution.c b/contrib/gcc-5.0/gcc/tree-scalar-evolution.c index d89f6314c4..1b457059d0 100644 --- a/contrib/gcc-5.0/gcc/tree-scalar-evolution.c +++ b/contrib/gcc-5.0/gcc/tree-scalar-evolution.c @@ -958,27 +958,25 @@ follow_ssa_edge_binary (struct loop *loop, gimple at_stmt, limit++; evol = *evolution_of_loop; - res = follow_ssa_edge - (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, &evol, limit); - - if (res == t_true) - *evolution_of_loop = add_to_evolution + evol = add_to_evolution (loop->num, chrec_convert (type, evol, at_stmt), code, rhs1, at_stmt); - + res = follow_ssa_edge + (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, &evol, limit); + if (res == t_true) + *evolution_of_loop = evol; else if (res == t_false) { + *evolution_of_loop = add_to_evolution + (loop->num, + chrec_convert (type, *evolution_of_loop, at_stmt), + code, rhs0, at_stmt); res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi, evolution_of_loop, limit); - if (res == t_true) - *evolution_of_loop = add_to_evolution - (loop->num, - chrec_convert (type, *evolution_of_loop, at_stmt), - code, rhs0, at_stmt); - + ; else if (res == t_dont_know) *evolution_of_loop = chrec_dont_know; } @@ -991,15 +989,15 @@ follow_ssa_edge_binary (struct loop *loop, gimple at_stmt, { /* Match an assignment under the form: "a = b + ...". */ + *evolution_of_loop = add_to_evolution + (loop->num, chrec_convert (type, *evolution_of_loop, + at_stmt), + code, rhs1, at_stmt); res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, evolution_of_loop, limit); if (res == t_true) - *evolution_of_loop = add_to_evolution - (loop->num, chrec_convert (type, *evolution_of_loop, - at_stmt), - code, rhs1, at_stmt); - + ; else if (res == t_dont_know) *evolution_of_loop = chrec_dont_know; } @@ -1009,15 +1007,15 @@ follow_ssa_edge_binary (struct loop *loop, gimple at_stmt, { /* Match an assignment under the form: "a = ... + c". */ + *evolution_of_loop = add_to_evolution + (loop->num, chrec_convert (type, *evolution_of_loop, + at_stmt), + code, rhs0, at_stmt); res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs1), halting_phi, evolution_of_loop, limit); if (res == t_true) - *evolution_of_loop = add_to_evolution - (loop->num, chrec_convert (type, *evolution_of_loop, - at_stmt), - code, rhs0, at_stmt); - + ; else if (res == t_dont_know) *evolution_of_loop = chrec_dont_know; } @@ -1042,13 +1040,13 @@ follow_ssa_edge_binary (struct loop *loop, gimple at_stmt, if (TREE_CODE (rhs1) == SSA_NAME) limit++; + *evolution_of_loop = add_to_evolution + (loop->num, chrec_convert (type, *evolution_of_loop, at_stmt), + MINUS_EXPR, rhs1, at_stmt); res = follow_ssa_edge (loop, SSA_NAME_DEF_STMT (rhs0), halting_phi, evolution_of_loop, limit); if (res == t_true) - *evolution_of_loop = add_to_evolution - (loop->num, chrec_convert (type, *evolution_of_loop, at_stmt), - MINUS_EXPR, rhs1, at_stmt); - + ; else if (res == t_dont_know) *evolution_of_loop = chrec_dont_know; } diff --git a/contrib/gcc-5.0/gcc/tree-sra.c b/contrib/gcc-5.0/gcc/tree-sra.c index 6adee70bce..c9fb6bb525 100644 --- a/contrib/gcc-5.0/gcc/tree-sra.c +++ b/contrib/gcc-5.0/gcc/tree-sra.c @@ -2537,11 +2537,20 @@ analyze_all_variable_accesses (void) bitmap tmp = BITMAP_ALLOC (NULL); bitmap_iterator bi; unsigned i; - unsigned max_scalarization_size - = (optimize_function_for_size_p (cfun) - ? PARAM_VALUE (PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE) - : PARAM_VALUE (PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED)) - * BITS_PER_UNIT; + bool optimize_speed_p = !optimize_function_for_size_p (cfun); + + enum compiler_param param = optimize_speed_p + ? PARAM_SRA_MAX_SCALARIZATION_SIZE_SPEED + : PARAM_SRA_MAX_SCALARIZATION_SIZE_SIZE; + + /* If the user didn't set PARAM_SRA_MAX_SCALARIZATION_SIZE_<...>, + fall back to a target default. */ + unsigned HOST_WIDE_INT max_scalarization_size + = global_options_set.x_param_values[param] + ? PARAM_VALUE (param) + : get_move_ratio (optimize_speed_p) * UNITS_PER_WORD; + + max_scalarization_size *= BITS_PER_UNIT; EXECUTE_IF_SET_IN_BITMAP (candidate_bitmap, 0, i, bi) if (bitmap_bit_p (should_scalarize_away_bitmap, i) diff --git a/contrib/gcc-5.0/gcc/tree-ssa-dce.c b/contrib/gcc-5.0/gcc/tree-ssa-dce.c index c9cb0e4895..df30614280 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-dce.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-dce.c @@ -1149,7 +1149,12 @@ remove_dead_stmt (gimple_stmt_iterator *i, basic_block bb) if (e != e2) { cfg_altered = true; - remove_edge (e2); + /* If we made a BB unconditionally exit a loop then this + transform alters the set of BBs in the loop. Schedule + a fixup. */ + if (loop_exit_edge_p (bb->loop_father, e)) + loops_state_set (LOOPS_NEED_FIXUP); + remove_edge (e2); } else ei_next (&ei); diff --git a/contrib/gcc-5.0/gcc/tree-ssa-dom.c b/contrib/gcc-5.0/gcc/tree-ssa-dom.c index ea49eb7c3c..9690004ec1 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-dom.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-dom.c @@ -2963,6 +2963,9 @@ propagate_rhs_into_lhs (gimple stmt, tree lhs, tree rhs, bitmap interesting_name { basic_block bb = gimple_bb (use_stmt); edge te = find_taken_edge (bb, val); + if (!te) + continue; + edge_iterator ei; edge e; gimple_stmt_iterator gsi; diff --git a/contrib/gcc-5.0/gcc/tree-ssa-loop-ivcanon.c b/contrib/gcc-5.0/gcc/tree-ssa-loop-ivcanon.c index 0e1d75d332..251b35fe98 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-loop-ivcanon.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-loop-ivcanon.c @@ -523,9 +523,9 @@ remove_exits_and_undefined_stmts (struct loop *loop, unsigned int npeeled) gimple_stmt_iterator gsi = gsi_for_stmt (elt->stmt); gcall *stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_UNREACHABLE), 0); - gimple_set_location (stmt, gimple_location (elt->stmt)); gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); + split_block (gimple_bb (stmt), stmt); changed = true; if (dump_file && (dump_flags & TDF_DETAILS)) { diff --git a/contrib/gcc-5.0/gcc/tree-ssa-pre.c b/contrib/gcc-5.0/gcc/tree-ssa-pre.c index c985e79869..805cc21e10 100644 --- a/contrib/gcc-5.0/gcc/tree-ssa-pre.c +++ b/contrib/gcc-5.0/gcc/tree-ssa-pre.c @@ -4386,7 +4386,7 @@ eliminate_dom_walker::before_dom_children (basic_block b) (OBJ_TYPE_REF_TOKEN (fn)), context, &final); - if (dump_enabled_p ()) + if (dump_file) dump_possible_polymorphic_call_targets (dump_file, obj_type_ref_class (fn), tree_to_uhwi diff --git a/contrib/gcc-5.0/gcc/tree-vect-slp.c b/contrib/gcc-5.0/gcc/tree-vect-slp.c index 73ab24e8f3..2561472040 100644 --- a/contrib/gcc-5.0/gcc/tree-vect-slp.c +++ b/contrib/gcc-5.0/gcc/tree-vect-slp.c @@ -1875,21 +1875,27 @@ vect_detect_hybrid_slp_stmts (slp_tree node, unsigned i, slp_vect_type stype) { /* Check if a pure SLP stmt has uses in non-SLP stmts. */ gcc_checking_assert (PURE_SLP_STMT (stmt_vinfo)); + /* We always get the pattern stmt here, but for immediate + uses we have to use the LHS of the original stmt. */ + gcc_checking_assert (!STMT_VINFO_IN_PATTERN_P (stmt_vinfo)); + if (STMT_VINFO_RELATED_STMT (stmt_vinfo)) + stmt = STMT_VINFO_RELATED_STMT (stmt_vinfo); if (TREE_CODE (gimple_op (stmt, 0)) == SSA_NAME) FOR_EACH_IMM_USE_STMT (use_stmt, imm_iter, gimple_op (stmt, 0)) - if (gimple_bb (use_stmt) - && flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)) - && (use_vinfo = vinfo_for_stmt (use_stmt)) - && !STMT_SLP_TYPE (use_vinfo) - && (STMT_VINFO_RELEVANT (use_vinfo) - || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (use_vinfo)) - || (STMT_VINFO_IN_PATTERN_P (use_vinfo) - && STMT_VINFO_RELATED_STMT (use_vinfo) - && !STMT_SLP_TYPE (vinfo_for_stmt - (STMT_VINFO_RELATED_STMT (use_vinfo))))) - && !(gimple_code (use_stmt) == GIMPLE_PHI - && STMT_VINFO_DEF_TYPE (use_vinfo) == vect_reduction_def)) - stype = hybrid; + { + if (!flow_bb_inside_loop_p (loop, gimple_bb (use_stmt))) + continue; + use_vinfo = vinfo_for_stmt (use_stmt); + if (STMT_VINFO_IN_PATTERN_P (use_vinfo) + && STMT_VINFO_RELATED_STMT (use_vinfo)) + use_vinfo = vinfo_for_stmt (STMT_VINFO_RELATED_STMT (use_vinfo)); + if (!STMT_SLP_TYPE (use_vinfo) + && (STMT_VINFO_RELEVANT (use_vinfo) + || VECTORIZABLE_CYCLE_DEF (STMT_VINFO_DEF_TYPE (use_vinfo))) + && !(gimple_code (use_stmt) == GIMPLE_PHI + && STMT_VINFO_DEF_TYPE (use_vinfo) == vect_reduction_def)) + stype = hybrid; + } } if (stype == hybrid) diff --git a/contrib/gcc-5.0/gcc/tree-vectorizer.c b/contrib/gcc-5.0/gcc/tree-vectorizer.c index 415bffa14d..25586b08b5 100644 --- a/contrib/gcc-5.0/gcc/tree-vectorizer.c +++ b/contrib/gcc-5.0/gcc/tree-vectorizer.c @@ -176,7 +176,7 @@ simd_array_to_simduid::equal (const value_type *p1, const value_type *p2) into their corresponding constants. */ static void -adjust_simduid_builtins (hash_table **htab) +adjust_simduid_builtins (hash_table *htab) { basic_block bb; @@ -208,10 +208,12 @@ adjust_simduid_builtins (hash_table **htab) gcc_assert (TREE_CODE (arg) == SSA_NAME); simduid_to_vf *p = NULL, data; data.simduid = DECL_UID (SSA_NAME_VAR (arg)); - if (*htab) - p = (*htab)->find (&data); - if (p) - vf = p->vf; + if (htab) + { + p = htab->find (&data); + if (p) + vf = p->vf; + } switch (ifn) { case IFN_GOMP_SIMD_VF: @@ -314,6 +316,38 @@ note_simd_array_uses (hash_table **htab) walk_gimple_op (use_stmt, note_simd_array_uses_cb, &wi); } } + +/* Shrink arrays with "omp simd array" attribute to the corresponding + vectorization factor. */ + +static void +shrink_simd_arrays + (hash_table *simd_array_to_simduid_htab, + hash_table *simduid_to_vf_htab) +{ + for (hash_table::iterator iter + = simd_array_to_simduid_htab->begin (); + iter != simd_array_to_simduid_htab->end (); ++iter) + if ((*iter)->simduid != -1U) + { + tree decl = (*iter)->decl; + int vf = 1; + if (simduid_to_vf_htab) + { + simduid_to_vf *p = NULL, data; + data.simduid = (*iter)->simduid; + p = simduid_to_vf_htab->find (&data); + if (p) + vf = p->vf; + } + tree atype + = build_array_type_nelts (TREE_TYPE (TREE_TYPE (decl)), vf); + TREE_TYPE (decl) = atype; + relayout_decl (decl); + } + + delete simd_array_to_simduid_htab; +} /* A helper function to free data refs. */ @@ -417,11 +451,7 @@ vectorize_loops (void) /* Bail out if there are no loops. */ if (vect_loops_num <= 1) - { - if (cfun->has_simduid_loops) - adjust_simduid_builtins (&simduid_to_vf_htab); - return 0; - } + return 0; if (cfun->has_simduid_loops) note_simd_array_uses (&simd_array_to_simduid_htab); @@ -560,37 +590,14 @@ vectorize_loops (void) /* Fold IFN_GOMP_SIMD_{VF,LANE,LAST_LANE} builtins. */ if (cfun->has_simduid_loops) - adjust_simduid_builtins (&simduid_to_vf_htab); + adjust_simduid_builtins (simduid_to_vf_htab); /* Shrink any "omp array simd" temporary arrays to the actual vectorization factors. */ if (simd_array_to_simduid_htab) - { - for (hash_table::iterator iter - = simd_array_to_simduid_htab->begin (); - iter != simd_array_to_simduid_htab->end (); ++iter) - if ((*iter)->simduid != -1U) - { - tree decl = (*iter)->decl; - int vf = 1; - if (simduid_to_vf_htab) - { - simduid_to_vf *p = NULL, data; - data.simduid = (*iter)->simduid; - p = simduid_to_vf_htab->find (&data); - if (p) - vf = p->vf; - } - tree atype - = build_array_type_nelts (TREE_TYPE (TREE_TYPE (decl)), vf); - TREE_TYPE (decl) = atype; - relayout_decl (decl); - } - - delete simd_array_to_simduid_htab; - } - delete simduid_to_vf_htab; - simduid_to_vf_htab = NULL; + shrink_simd_arrays (simd_array_to_simduid_htab, simduid_to_vf_htab); + delete simduid_to_vf_htab; + cfun->has_simduid_loops = false; if (num_vectorized_loops > 0) { @@ -605,6 +612,64 @@ vectorize_loops (void) } +/* Entry point to the simduid cleanup pass. */ + +namespace { + +const pass_data pass_data_simduid_cleanup = +{ + GIMPLE_PASS, /* type */ + "simduid", /* name */ + OPTGROUP_NONE, /* optinfo_flags */ + TV_NONE, /* tv_id */ + ( PROP_ssa | PROP_cfg ), /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0, /* todo_flags_finish */ +}; + +class pass_simduid_cleanup : public gimple_opt_pass +{ +public: + pass_simduid_cleanup (gcc::context *ctxt) + : gimple_opt_pass (pass_data_simduid_cleanup, ctxt) + {} + + /* opt_pass methods: */ + opt_pass * clone () { return new pass_simduid_cleanup (m_ctxt); } + virtual bool gate (function *fun) { return fun->has_simduid_loops; } + virtual unsigned int execute (function *); + +}; // class pass_simduid_cleanup + +unsigned int +pass_simduid_cleanup::execute (function *fun) +{ + hash_table *simd_array_to_simduid_htab = NULL; + + note_simd_array_uses (&simd_array_to_simduid_htab); + + /* Fold IFN_GOMP_SIMD_{VF,LANE,LAST_LANE} builtins. */ + adjust_simduid_builtins (NULL); + + /* Shrink any "omp array simd" temporary arrays to the + actual vectorization factors. */ + if (simd_array_to_simduid_htab) + shrink_simd_arrays (simd_array_to_simduid_htab, NULL); + fun->has_simduid_loops = false; + return 0; +} + +} // anon namespace + +gimple_opt_pass * +make_pass_simduid_cleanup (gcc::context *ctxt) +{ + return new pass_simduid_cleanup (ctxt); +} + + /* Entry point to basic block SLP phase. */ namespace { diff --git a/contrib/gcc-5.0/gcc/typed-splay-tree.h b/contrib/gcc-5.0/gcc/typed-splay-tree.h new file mode 100644 index 0000000000..784986219e --- /dev/null +++ b/contrib/gcc-5.0/gcc/typed-splay-tree.h @@ -0,0 +1,135 @@ +/* A typesafe wrapper around libiberty's splay-tree.h. + Copyright (C) 2015 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +#ifndef GCC_TYPED_SPLAY_TREE_H +#define GCC_TYPED_SPLAY_TREE_H + +#include "splay-tree.h" + +/* Typesafe wrapper around libiberty's splay-tree.h. */ +template +class typed_splay_tree +{ + public: + typedef KEY_TYPE key_type; + typedef VALUE_TYPE value_type; + + typedef int (*compare_fn) (key_type, key_type); + typedef void (*delete_key_fn) (key_type); + typedef void (*delete_value_fn) (value_type); + + typed_splay_tree (compare_fn, + delete_key_fn, + delete_value_fn); + ~typed_splay_tree (); + + value_type lookup (key_type k); + value_type predecessor (key_type k); + value_type successor (key_type k); + void insert (key_type k, value_type v); + + private: + static value_type node_to_value (splay_tree_node node); + + private: + ::splay_tree m_inner; +}; + +/* Constructor for typed_splay_tree . */ + +template +inline typed_splay_tree:: + typed_splay_tree (compare_fn compare_fn, + delete_key_fn delete_key_fn, + delete_value_fn delete_value_fn) +{ + m_inner = splay_tree_new ((splay_tree_compare_fn)compare_fn, + (splay_tree_delete_key_fn)delete_key_fn, + (splay_tree_delete_value_fn)delete_value_fn); +} + +/* Destructor for typed_splay_tree . */ + +template +inline typed_splay_tree:: + ~typed_splay_tree () +{ + splay_tree_delete (m_inner); +} + +/* Lookup KEY, returning a value if present, and NULL + otherwise. */ + +template +inline VALUE_TYPE +typed_splay_tree::lookup (key_type key) +{ + splay_tree_node node = splay_tree_lookup (m_inner, (splay_tree_key)key); + return node_to_value (node); +} + +/* Return the immediate predecessor of KEY, or NULL if there is no + predecessor. KEY need not be present in the tree. */ + +template +inline VALUE_TYPE +typed_splay_tree::predecessor (key_type key) +{ + splay_tree_node node = splay_tree_predecessor (m_inner, (splay_tree_key)key); + return node_to_value (node); +} + +/* Return the immediate successor of KEY, or NULL if there is no + successor. KEY need not be present in the tree. */ + +template +inline VALUE_TYPE +typed_splay_tree::successor (key_type k) +{ + splay_tree_node node = splay_tree_successor (m_inner, (splay_tree_key)k); + return node_to_value (node); +} + +/* Insert a new node (associating KEY with VALUE). If a + previous node with the indicated KEY exists, its data is replaced + with the new value. */ + +template +inline void +typed_splay_tree::insert (key_type key, + value_type value) +{ + splay_tree_insert (m_inner, + (splay_tree_key)key, + (splay_tree_value)value); +} + +/* Internal function for converting from splay_tree_node to + VALUE_TYPE. */ +template +inline VALUE_TYPE +typed_splay_tree::node_to_value (splay_tree_node node) +{ + if (node) + return (value_type)node->value; + else + return 0; +} + +#endif /* GCC_TYPED_SPLAY_TREE_H */ diff --git a/contrib/gcc-5.0/gcc/varasm.c b/contrib/gcc-5.0/gcc/varasm.c index e8d996cb1e..6c17a0e75f 100644 --- a/contrib/gcc-5.0/gcc/varasm.c +++ b/contrib/gcc-5.0/gcc/varasm.c @@ -1934,12 +1934,12 @@ emit_local (tree decl ATTRIBUTE_UNUSED, unsigned HOST_WIDE_INT rounded ATTRIBUTE_UNUSED) { #if defined ASM_OUTPUT_ALIGNED_DECL_LOCAL - int align = symtab_node::get (decl)->definition_alignment (); + unsigned int align = symtab_node::get (decl)->definition_alignment (); ASM_OUTPUT_ALIGNED_DECL_LOCAL (asm_out_file, decl, name, size, align); return true; #elif defined ASM_OUTPUT_ALIGNED_LOCAL - int align = symtab_node::get (decl)->definition_alignment (); + unsigned int align = symtab_node::get (decl)->definition_alignment (); ASM_OUTPUT_ALIGNED_LOCAL (asm_out_file, name, size, align); return true; #else diff --git a/contrib/gcc-5.0/gcc/vmsdbgout.c b/contrib/gcc-5.0/gcc/vmsdbgout.c index 23d8365cb0..12c783c132 100644 --- a/contrib/gcc-5.0/gcc/vmsdbgout.c +++ b/contrib/gcc-5.0/gcc/vmsdbgout.c @@ -198,6 +198,7 @@ const struct gcc_debug_hooks vmsdbg_debug_hooks vmsdbgout_end_epilogue, vmsdbgout_begin_function, vmsdbgout_end_function, + debug_nothing_tree, /* register_main_translation_unit */ vmsdbgout_decl, vmsdbgout_global_decl, vmsdbgout_type_decl, /* type_decl */ diff --git a/contrib/gcc-5.0/libgcc/config.host b/contrib/gcc-5.0/libgcc/config.host index 4b158958fa..308e4ff463 100644 --- a/contrib/gcc-5.0/libgcc/config.host +++ b/contrib/gcc-5.0/libgcc/config.host @@ -567,9 +567,11 @@ x86_64-*-dragonfly*) ;; i[34567]86-*-freebsd*) tmake_file="${tmake_file} i386/t-freebsd i386/t-crtstuff" + md_unwind_header=i386/freebsd-unwind.h ;; x86_64-*-freebsd*) tmake_file="${tmake_file} i386/t-freebsd i386/t-crtstuff" + md_unwind_header=i386/freebsd-unwind.h ;; i[34567]86-*-netbsdelf*) ;; diff --git a/contrib/gcc-5.0/libgomp/oacc-init.c b/contrib/gcc-5.0/libgomp/oacc-init.c index dc40fb6ffe..a7c2e0d820 100644 --- a/contrib/gcc-5.0/libgomp/oacc-init.c +++ b/contrib/gcc-5.0/libgomp/oacc-init.c @@ -29,6 +29,7 @@ #include "libgomp.h" #include "oacc-int.h" #include "openacc.h" +#include "plugin/plugin-host.h" #include #include #include @@ -548,11 +549,18 @@ ialias (acc_set_device_num) int acc_on_device (acc_device_t dev) { - if (acc_get_device_type () == acc_device_host_nonshm) + struct goacc_thread *thr = goacc_thread (); + + /* We only want to appear to be the "host_nonshm" plugin from "offloaded" + code -- i.e. within a parallel region. Test a flag set by the + openacc_parallel hook of the host_nonshm plugin to determine that. */ + if (acc_get_device_type () == acc_device_host_nonshm + && thr && thr->target_tls + && ((struct nonshm_thread *)thr->target_tls)->nonshm_exec) return dev == acc_device_host_nonshm || dev == acc_device_not_host; - /* Just rely on the compiler builtin. */ - return __builtin_acc_on_device (dev); + /* For OpenACC, libgomp is only built for the host, so this is sufficient. */ + return dev == acc_device_host || dev == acc_device_none; } ialias (acc_on_device) diff --git a/contrib/gcc-5.0/libgomp/plugin/plugin-host.c b/contrib/gcc-5.0/libgomp/plugin/plugin-host.c index 1faf5bc194..3cb4dab377 100644 --- a/contrib/gcc-5.0/libgomp/plugin/plugin-host.c +++ b/contrib/gcc-5.0/libgomp/plugin/plugin-host.c @@ -44,6 +44,7 @@ #include #include #include +#include #ifdef HOST_NONSHM_PLUGIN #define STATIC @@ -55,6 +56,10 @@ #define SELF "host: " #endif +#ifdef HOST_NONSHM_PLUGIN +#include "plugin-host.h" +#endif + STATIC const char * GOMP_OFFLOAD_get_name (void) { @@ -174,7 +179,10 @@ GOMP_OFFLOAD_openacc_parallel (void (*fn) (void *), void *targ_mem_desc __attribute__ ((unused))) { #ifdef HOST_NONSHM_PLUGIN + struct nonshm_thread *thd = GOMP_PLUGIN_acc_thread (); + thd->nonshm_exec = true; fn (devaddrs); + thd->nonshm_exec = false; #else fn (hostaddrs); #endif @@ -232,11 +240,20 @@ STATIC void * GOMP_OFFLOAD_openacc_create_thread_data (int ord __attribute__ ((unused))) { +#ifdef HOST_NONSHM_PLUGIN + struct nonshm_thread *thd + = GOMP_PLUGIN_malloc (sizeof (struct nonshm_thread)); + thd->nonshm_exec = false; + return thd; +#else return NULL; +#endif } STATIC void -GOMP_OFFLOAD_openacc_destroy_thread_data (void *tls_data - __attribute__ ((unused))) +GOMP_OFFLOAD_openacc_destroy_thread_data (void *tls_data) { +#ifdef HOST_NONSHM_PLUGIN + free (tls_data); +#endif } diff --git a/contrib/gcc-5.0/libgomp/plugin/plugin-host.h b/contrib/gcc-5.0/libgomp/plugin/plugin-host.h new file mode 100644 index 0000000000..96955d1941 --- /dev/null +++ b/contrib/gcc-5.0/libgomp/plugin/plugin-host.h @@ -0,0 +1,37 @@ +/* OpenACC Runtime Library: acc_device_host, acc_device_host_nonshm. + + Copyright (C) 2015 Free Software Foundation, Inc. + + Contributed by Mentor Embedded. + + 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 + . */ + +#ifndef PLUGIN_HOST_H +#define PLUGIN_HOST_H + +struct nonshm_thread +{ + bool nonshm_exec; +}; + +#endif diff --git a/contrib/gcc-5.0/libgomp/plugin/plugin-nvptx.c b/contrib/gcc-5.0/libgomp/plugin/plugin-nvptx.c index 583ec87aee..f9754b98f5 100644 --- a/contrib/gcc-5.0/libgomp/plugin/plugin-nvptx.c +++ b/contrib/gcc-5.0/libgomp/plugin/plugin-nvptx.c @@ -777,6 +777,11 @@ nvptx_get_num_devices (void) int n; CUresult r; + /* PR libgomp/65099: Currently, we only support offloading in 64-bit + configurations. */ + if (sizeof (void *) != 8) + return 0; + /* This function will be called before the plugin has been initialized in order to enumerate available devices, but CUDA API routines can't be used until cuInit has been called. Just call it now (but don't yet do any diff --git a/contrib/gcc-5.0/libitm/ChangeLog b/contrib/gcc-5.0/libitm/ChangeLog index d6c7c1c1a5..cf335388e4 100644 --- a/contrib/gcc-5.0/libitm/ChangeLog +++ b/contrib/gcc-5.0/libitm/ChangeLog @@ -1,3 +1,12 @@ +2015-07-16 Release Manager + + * GCC 5.2.0 released. + +2015-07-03 Carlos Sánchez de La Lama + + PR target/52482 + * config/powerpc/sjlj.S: Port to Xcode 2.5. + 2015-04-22 Release Manager * GCC 5.1.0 released. diff --git a/contrib/gcc-5.0/libitm/config/powerpc/sjlj.S b/contrib/gcc-5.0/libitm/config/powerpc/sjlj.S index 878dceb9df..48e021c8a9 100644 --- a/contrib/gcc-5.0/libitm/config/powerpc/sjlj.S +++ b/contrib/gcc-5.0/libitm/config/powerpc/sjlj.S @@ -83,16 +83,16 @@ bl \name .endm #elif defined(_CALL_DARWIN) -.macro FUNC name +.macro FUNC .globl _$0 _$0: .endmacro -.macro END name +.macro END .endmacro -.macro HIDDEN name +.macro HIDDEN .private_extern _$0 .endmacro -.macro CALL name +.macro CALL bl _$0 .endmacro # ifdef __ppc64__ diff --git a/contrib/gcc-5.0/libstdc++-v3/config/abi/pre/gnu.ver b/contrib/gcc-5.0/libstdc++-v3/config/abi/pre/gnu.ver index 7b82ce88ae..120b1336ed 100644 --- a/contrib/gcc-5.0/libstdc++-v3/config/abi/pre/gnu.ver +++ b/contrib/gcc-5.0/libstdc++-v3/config/abi/pre/gnu.ver @@ -543,6 +543,9 @@ GLIBCXX_3.4 { # std::codecvt_byname _ZNSt14codecvt_bynameI[cw]c11__mbstate_tEC[12]EPKc[jmy]; _ZNSt14codecvt_bynameI[cw]c11__mbstate_tED*; +#if defined (_WIN32) && !defined (__CYGWIN__) + _ZNSt14codecvt_bynameI[cw]ciE[CD]*; +#endif # std::collate _ZNSt7collateI[cw]*; @@ -1819,9 +1822,9 @@ GLIBCXX_3.4.21 { _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc; # codecvt, codecvt - _ZNKSt7codecvtID[is]c11__mbstate_t*; - _ZNSt7codecvtID[is]c11__mbstate_t*; - _ZT[ISV]St7codecvtID[is]c11__mbstate_tE; + _ZNKSt7codecvtID[is]c*; + _ZNSt7codecvtID[is]c*; + _ZT[ISV]St7codecvtID[is]c*E; extern "C++" { diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/alloc_traits.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/alloc_traits.h index d6c42ece5d..12c6c12f18 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/alloc_traits.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/alloc_traits.h @@ -72,8 +72,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION typedef _Alloc<_Tp, _Args...> __type; }; - template - using __alloc_rebind = typename __alloctr_rebind<_Ptr, _Tp>::__type; + template + using __alloc_rebind = typename __alloctr_rebind<_Alloc, _Tp>::__type; /** * @brief Uniform interface to all allocator types. diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.h index 3b2603fc65..f0d543a60e 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/basic_string.h @@ -377,7 +377,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11 /** * @brief Default constructor creates an empty string. */ - basic_string() _GLIBCXX_NOEXCEPT + basic_string() +#if __cplusplus >= 201103L + noexcept(is_nothrow_default_constructible<_Alloc>::value) +#endif : _M_dataplus(_M_local_data()) { _M_set_length(0); } diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/locale_conv.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/locale_conv.h index 9b49617b7a..de49dd517f 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/locale_conv.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/locale_conv.h @@ -1,6 +1,6 @@ // wstring_convert implementation -*- C++ -*- -// Copyright (C) 2012 Free Software Foundation, Inc. +// Copyright (C) 2015 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the @@ -51,6 +51,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION * @{ */ +_GLIBCXX_BEGIN_NAMESPACE_CXX11 /// String conversions template, @@ -192,18 +193,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_conv(const _InChar* __first, const _InChar* __last, const _OutStr* __err, _MemFn __memfn) { + auto __outstr = __err ? _OutStr(__err->get_allocator()) : _OutStr(); + + if (__first == __last) + { + _M_count = 0; + return __outstr; + } + if (!_M_with_cvtstate) _M_state = state_type(); - auto __outstr = __err ? _OutStr(__err->get_allocator()) : _OutStr(); size_t __outchars = 0; auto __next = __first; - const auto __maxlen = _M_cvt->max_length(); + const auto __maxlen = _M_cvt->max_length() + 1; codecvt_base::result __result; do { - __outstr.resize(__outstr.size() + (__last - __next) + __maxlen); + __outstr.resize(__outstr.size() + (__last - __next) * __maxlen); auto __outnext = &__outstr.front() + __outchars; auto const __outlast = &__outstr.back() + 1; __result = ((*_M_cvt).*__memfn)(_M_state, __next, __last, __next, @@ -239,6 +247,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION bool _M_with_cvtstate = false; bool _M_with_strings = false; }; +_GLIBCXX_END_NAMESPACE_CXX11 /// Buffer conversions templatealways_noconv(); diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algobase.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algobase.h index 90401350d9..2b69e61895 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algobase.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_algobase.h @@ -715,8 +715,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __fill_a(_Tp* __first, _Tp* __last, const _Tp& __c) { const _Tp __tmp = __c; - __builtin_memset(__first, static_cast(__tmp), - __last - __first); + if (const size_t __len = __last - __first) + __builtin_memset(__first, static_cast(__tmp), __len); } /** @@ -822,8 +822,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION static bool equal(const _Tp* __first1, const _Tp* __last1, const _Tp* __first2) { - return !__builtin_memcmp(__first1, __first2, sizeof(_Tp) - * (__last1 - __first1)); + if (const size_t __len = (__last1 - __first1)) + return !__builtin_memcmp(__first1, __first2, sizeof(_Tp) * __len); + return true; } }; @@ -927,9 +928,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION { const size_t __len1 = __last1 - __first1; const size_t __len2 = __last2 - __first2; - const int __result = __builtin_memcmp(__first1, __first2, - std::min(__len1, __len2)); - return __result != 0 ? __result < 0 : __len1 < __len2; + if (const size_t __len = std::min(__len1, __len2)) + if (int __result = __builtin_memcmp(__first1, __first2, __len)) + return __result < 0; + return __len1 < __len2; } }; diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_bvector.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_bvector.h index 7b93d9508c..71bee213a8 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_bvector.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_bvector.h @@ -573,6 +573,9 @@ template public: vector() +#if __cplusplus >= 201103L + noexcept(is_nothrow_default_constructible::value) +#endif : _Base() { } explicit diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_map.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_map.h index df18973931..179e3f2a0b 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_map.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_map.h @@ -160,6 +160,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @brief Default constructor creates no elements. */ map() +#if __cplusplus >= 201103L + noexcept(is_nothrow_default_constructible::value) +#endif : _M_t() { } /** diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_multimap.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_multimap.h index f3d21ab8be..10ac0fadea 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_multimap.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_multimap.h @@ -158,6 +158,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @brief Default constructor creates no elements. */ multimap() +#if __cplusplus >= 201103L + noexcept(is_nothrow_default_constructible::value) +#endif : _M_t() { } /** diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_multiset.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_multiset.h index 7e92836aae..0a476d1b08 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_multiset.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_multiset.h @@ -138,6 +138,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @brief Default constructor creates no elements. */ multiset() +#if __cplusplus >= 201103L + noexcept(is_nothrow_default_constructible::value) +#endif : _M_t() { } /** diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_set.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_set.h index 5189234357..2e5c89f22c 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_set.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_set.h @@ -140,6 +140,9 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @brief Default constructor creates no elements. */ set() +#if __cplusplus >= 201103L + noexcept(is_nothrow_default_constructible::value) +#endif : _M_t() { } /** diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_tree.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_tree.h index 5ca8e28ef4..d39042f1aa 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_tree.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/stl_tree.h @@ -146,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_valptr() const { return std::__addressof(_M_value_field); } #else - __gnu_cxx::__aligned_buffer<_Val> _M_storage; + __gnu_cxx::__aligned_membuf<_Val> _M_storage; _Val* _M_valptr() @@ -188,7 +188,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_node() { } explicit - _Rb_tree_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT + _Rb_tree_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } reference @@ -260,7 +260,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION : _M_node() { } explicit - _Rb_tree_const_iterator(_Link_type __x) _GLIBCXX_NOEXCEPT + _Rb_tree_const_iterator(_Base_ptr __x) _GLIBCXX_NOEXCEPT : _M_node(__x) { } _Rb_tree_const_iterator(const iterator& __it) _GLIBCXX_NOEXCEPT @@ -268,8 +268,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION iterator _M_const_cast() const _GLIBCXX_NOEXCEPT - { return iterator(static_cast - (const_cast(_M_node))); } + { return iterator(const_cast(_M_node)); } reference operator*() const _GLIBCXX_NOEXCEPT @@ -868,28 +867,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION iterator begin() _GLIBCXX_NOEXCEPT - { - return iterator(static_cast<_Link_type> - (this->_M_impl._M_header._M_left)); - } + { return iterator(this->_M_impl._M_header._M_left); } const_iterator begin() const _GLIBCXX_NOEXCEPT - { - return const_iterator(static_cast<_Const_Link_type> - (this->_M_impl._M_header._M_left)); - } + { return const_iterator(this->_M_impl._M_header._M_left); } iterator end() _GLIBCXX_NOEXCEPT - { return iterator(static_cast<_Link_type>(&this->_M_impl._M_header)); } + { return iterator(&this->_M_impl._M_header); } const_iterator end() const _GLIBCXX_NOEXCEPT - { - return const_iterator(static_cast<_Const_Link_type> - (&this->_M_impl._M_header)); - } + { return const_iterator(&this->_M_impl._M_header); } reverse_iterator rbegin() _GLIBCXX_NOEXCEPT diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/unordered_map.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/unordered_map.h index 92b75d1dfc..3c434abb6a 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/unordered_map.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/unordered_map.h @@ -190,7 +190,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_map(const unordered_map& __umap, const allocator_type& __a) - : _M_h(__umap._M_h, __a) + : _M_h(__umap._M_h, __a) { } /* @@ -200,7 +200,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_map(unordered_map&& __umap, const allocator_type& __a) - : _M_h(std::move(__umap._M_h), __a) + : _M_h(std::move(__umap._M_h), __a) { } /** @@ -219,7 +219,42 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) - : _M_h(__l, __n, __hf, __eql, __a) + : _M_h(__l, __n, __hf, __eql, __a) + { } + + unordered_map(size_type __n, const allocator_type& __a) + : unordered_map(__n, hasher(), key_equal(), __a) + { } + + unordered_map(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_map(__n, __hf, key_equal(), __a) + { } + + template + unordered_map(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_map(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_map(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_map(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_map(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_map(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_map(__l, __n, __hf, key_equal(), __a) { } /// Copy assignment operator. @@ -320,7 +355,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER // modifiers. /** - * @brief Attempts to build and insert a std::pair into the %unordered_map. + * @brief Attempts to build and insert a std::pair into the + * %unordered_map. * * @param __args Arguments used to generate a new pair instance (see * std::piecewise_contruct for passing arguments to each @@ -344,7 +380,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return _M_h.emplace(std::forward<_Args>(__args)...); } /** - * @brief Attempts to build and insert a std::pair into the %unordered_map. + * @brief Attempts to build and insert a std::pair into the + * %unordered_map. * * @param __pos An iterator that serves as a hint as to where the pair * should be inserted. @@ -535,7 +572,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * @param __x An %unordered_map of the same element and allocator * types. * - * This exchanges the elements between two %unordered_map in constant time. + * This exchanges the elements between two %unordered_map in constant + * time. * Note that the global std::swap() function is specialized such that * std::swap(m1,m2) will feed to this function. */ @@ -895,7 +933,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ explicit unordered_multimap(const allocator_type& __a) - : _M_h(__a) + : _M_h(__a) { } /* @@ -905,7 +943,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_multimap(const unordered_multimap& __ummap, const allocator_type& __a) - : _M_h(__ummap._M_h, __a) + : _M_h(__ummap._M_h, __a) { } /* @@ -915,7 +953,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_multimap(unordered_multimap&& __ummap, const allocator_type& __a) - : _M_h(std::move(__ummap._M_h), __a) + : _M_h(std::move(__ummap._M_h), __a) { } /** @@ -934,7 +972,42 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) - : _M_h(__l, __n, __hf, __eql, __a) + : _M_h(__l, __n, __hf, __eql, __a) + { } + + unordered_multimap(size_type __n, const allocator_type& __a) + : unordered_multimap(__n, hasher(), key_equal(), __a) + { } + + unordered_multimap(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__n, __hf, key_equal(), __a) + { } + + template + unordered_multimap(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_multimap(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_multimap(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_multimap(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_multimap(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__l, __n, __hf, key_equal(), __a) { } /// Copy assignment operator. @@ -1055,7 +1128,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER { return _M_h.emplace(std::forward<_Args>(__args)...); } /** - * @brief Attempts to build and insert a std::pair into the %unordered_multimap. + * @brief Attempts to build and insert a std::pair into the + * %unordered_multimap. * * @param __pos An iterator that serves as a hint as to where the pair * should be inserted. diff --git a/contrib/gcc-5.0/libstdc++-v3/include/bits/unordered_set.h b/contrib/gcc-5.0/libstdc++-v3/include/bits/unordered_set.h index 7a2546c825..664d97ef27 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/bits/unordered_set.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/bits/unordered_set.h @@ -174,7 +174,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ explicit unordered_set(const allocator_type& __a) - : _M_h(__a) + : _M_h(__a) { } /* @@ -184,7 +184,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_set(const unordered_set& __uset, const allocator_type& __a) - : _M_h(__uset._M_h, __a) + : _M_h(__uset._M_h, __a) { } /* @@ -194,7 +194,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_set(unordered_set&& __uset, const allocator_type& __a) - : _M_h(std::move(__uset._M_h), __a) + : _M_h(std::move(__uset._M_h), __a) { } /** @@ -213,7 +213,42 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) - : _M_h(__l, __n, __hf, __eql, __a) + : _M_h(__l, __n, __hf, __eql, __a) + { } + + unordered_set(size_type __n, const allocator_type& __a) + : unordered_set(__n, hasher(), key_equal(), __a) + { } + + unordered_set(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__n, __hf, key_equal(), __a) + { } + + template + unordered_set(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_set(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_set(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_set(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_set(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__l, __n, __hf, key_equal(), __a) { } /// Copy assignment operator. @@ -702,8 +737,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER template friend bool - operator==(const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&, - const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&); + operator==(const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&, + const unordered_set<_Value1, _Hash1, _Pred1, _Alloc1>&); }; /** @@ -823,7 +858,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER const hasher& __hf = hasher(), const key_equal& __eql = key_equal(), const allocator_type& __a = allocator_type()) - : _M_h(__l, __n, __hf, __eql, __a) + : _M_h(__l, __n, __hf, __eql, __a) { } /// Copy assignment operator. @@ -840,7 +875,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ explicit unordered_multiset(const allocator_type& __a) - : _M_h(__a) + : _M_h(__a) { } /* @@ -850,7 +885,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_multiset(const unordered_multiset& __umset, const allocator_type& __a) - : _M_h(__umset._M_h, __a) + : _M_h(__umset._M_h, __a) { } /* @@ -860,7 +895,42 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER */ unordered_multiset(unordered_multiset&& __umset, const allocator_type& __a) - : _M_h(std::move(__umset._M_h), __a) + : _M_h(std::move(__umset._M_h), __a) + { } + + unordered_multiset(size_type __n, const allocator_type& __a) + : unordered_multiset(__n, hasher(), key_equal(), __a) + { } + + unordered_multiset(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__n, __hf, key_equal(), __a) + { } + + template + unordered_multiset(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_multiset(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_multiset(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_multiset(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_multiset(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__l, __n, __hf, key_equal(), __a) { } /** @@ -871,8 +941,8 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER * in the initializer list @a __l. * * Note that the assignment completely changes the %unordered_multiset - * and that the resulting %unordered_set's size is the same as the number - * of elements assigned. Old data may be lost. + * and that the resulting %unordered_multiset's size is the same as the + * number of elements assigned. Old data may be lost. */ unordered_multiset& operator=(initializer_list __l) diff --git a/contrib/gcc-5.0/libstdc++-v3/include/debug/array b/contrib/gcc-5.0/libstdc++-v3/include/debug/array index 31d146e935..411e816d31 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/debug/array +++ b/contrib/gcc-5.0/libstdc++-v3/include/debug/array @@ -216,11 +216,11 @@ namespace __debug pointer data() noexcept - { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); } + { return _AT_Type::_S_ptr(_M_elems); } const_pointer data() const noexcept - { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); } + { return _AT_Type::_S_ptr(_M_elems); } }; // Array comparisons. diff --git a/contrib/gcc-5.0/libstdc++-v3/include/debug/unordered_map b/contrib/gcc-5.0/libstdc++-v3/include/debug/unordered_map index a6bf9a68c1..3f46641d67 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/debug/unordered_map +++ b/contrib/gcc-5.0/libstdc++-v3/include/debug/unordered_map @@ -129,6 +129,44 @@ namespace __debug const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } + unordered_map(size_type __n, const allocator_type& __a) + : unordered_map(__n, hasher(), key_equal(), __a) + { } + + unordered_map(size_type __n, + const hasher& __hf, + const allocator_type& __a) + : unordered_map(__n, __hf, key_equal(), __a) + { } + + template + unordered_map(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_map(_InputIterator __first, _InputIterator __last, + size_type __n, + const hasher& __hf, + const allocator_type& __a) + : unordered_map(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_map(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_map(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_map(initializer_list __l, + size_type __n, + const hasher& __hf, + const allocator_type& __a) + : unordered_map(__l, __n, __hf, key_equal(), __a) + { } + ~unordered_map() = default; unordered_map& @@ -544,6 +582,41 @@ namespace __debug const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } + unordered_multimap(size_type __n, const allocator_type& __a) + : unordered_multimap(__n, hasher(), key_equal(), __a) + { } + + unordered_multimap(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__n, __hf, key_equal(), __a) + { } + + template + unordered_multimap(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_multimap(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_multimap(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_multimap(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_multimap(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__l, __n, __hf, key_equal(), __a) + { } + ~unordered_multimap() = default; unordered_multimap& diff --git a/contrib/gcc-5.0/libstdc++-v3/include/debug/unordered_set b/contrib/gcc-5.0/libstdc++-v3/include/debug/unordered_set index afa0a3d465..10a9c270ed 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/debug/unordered_set +++ b/contrib/gcc-5.0/libstdc++-v3/include/debug/unordered_set @@ -129,6 +129,41 @@ namespace __debug const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } + unordered_set(size_type __n, const allocator_type& __a) + : unordered_set(__n, hasher(), key_equal(), __a) + { } + + unordered_set(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__n, __hf, key_equal(), __a) + { } + + template + unordered_set(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_set(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_set(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_set(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_set(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__l, __n, __hf, key_equal(), __a) + { } + ~unordered_set() = default; unordered_set& @@ -540,6 +575,41 @@ namespace __debug const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } + unordered_multiset(size_type __n, const allocator_type& __a) + : unordered_multiset(__n, hasher(), key_equal(), __a) + { } + + unordered_multiset(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__n, __hf, key_equal(), __a) + { } + + template + unordered_multiset(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_multiset(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_multiset(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_multiset(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_multiset(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__l, __n, __hf, key_equal(), __a) + { } + ~unordered_multiset() = default; unordered_multiset& diff --git a/contrib/gcc-5.0/libstdc++-v3/include/ext/aligned_buffer.h b/contrib/gcc-5.0/libstdc++-v3/include/ext/aligned_buffer.h index 01f5729786..d023bc189e 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/ext/aligned_buffer.h +++ b/contrib/gcc-5.0/libstdc++-v3/include/ext/aligned_buffer.h @@ -39,6 +39,47 @@ namespace __gnu_cxx { + // A utility type containing a POD object that can hold an object of type + // _Tp initialized via placement new or allocator_traits::construct. + // Intended for use as a data member subobject, use __aligned_buffer for + // complete objects. + template + struct __aligned_membuf + { + // Target macro ADJUST_FIELD_ALIGN can produce different alignment for + // types when used as class members. __aligned_membuf is intended + // for use as a class member, so align the buffer as for a class member. + struct _Tp2 { _Tp _M_t; }; + + alignas(__alignof__(_Tp2::_M_t)) unsigned char _M_storage[sizeof(_Tp)]; + + __aligned_membuf() = default; + + // Can be used to avoid value-initialization zeroing _M_storage. + __aligned_membuf(std::nullptr_t) { } + + void* + _M_addr() noexcept + { return static_cast(&_M_storage); } + + const void* + _M_addr() const noexcept + { return static_cast(&_M_storage); } + + _Tp* + _M_ptr() noexcept + { return static_cast<_Tp*>(_M_addr()); } + + const _Tp* + _M_ptr() const noexcept + { return static_cast(_M_addr()); } + }; + + // Similar to __aligned_membuf but aligned for complete objects, not members. + // This type is used in , , + // and , but ideally they would use __aligned_membuf + // instead, as it has smaller size for some types on some targets. + // This type is still used to avoid an ABI change. template struct __aligned_buffer : std::aligned_storage::value> diff --git a/contrib/gcc-5.0/libstdc++-v3/include/profile/array b/contrib/gcc-5.0/libstdc++-v3/include/profile/array index a90e396cae..5198bb3af9 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/profile/array +++ b/contrib/gcc-5.0/libstdc++-v3/include/profile/array @@ -178,11 +178,11 @@ namespace __profile pointer data() noexcept - { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); } + { return _AT_Type::_S_ptr(_M_elems); } const_pointer data() const noexcept - { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); } + { return _AT_Type::_S_ptr(_M_elems); } }; // Array comparisons. diff --git a/contrib/gcc-5.0/libstdc++-v3/include/profile/unordered_map b/contrib/gcc-5.0/libstdc++-v3/include/profile/unordered_map index fdb4550cdc..480fabad17 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/profile/unordered_map +++ b/contrib/gcc-5.0/libstdc++-v3/include/profile/unordered_map @@ -119,6 +119,41 @@ namespace __profile const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } + unordered_map(size_type __n, const allocator_type& __a) + : unordered_map(__n, hasher(), key_equal(), __a) + { } + + unordered_map(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_map(__n, __hf, key_equal(), __a) + { } + + template + unordered_map(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_map(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_map(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_map(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_map(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_map(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_map(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_map(__l, __n, __hf, key_equal(), __a) + { } + unordered_map& operator=(const unordered_map&) = default; @@ -361,6 +396,41 @@ namespace __profile const allocator_type& __a = allocator_type()) : _Base(__l, __n, __hf, __eql, __a) { } + unordered_multimap(size_type __n, const allocator_type& __a) + : unordered_multimap(__n, hasher(), key_equal(), __a) + { } + + unordered_multimap(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__n, __hf, key_equal(), __a) + { } + + template + unordered_multimap(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_multimap(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_multimap(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_multimap(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_multimap(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_multimap(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multimap(__l, __n, __hf, key_equal(), __a) + { } + unordered_multimap& operator=(const unordered_multimap&) = default; diff --git a/contrib/gcc-5.0/libstdc++-v3/include/profile/unordered_set b/contrib/gcc-5.0/libstdc++-v3/include/profile/unordered_set index e1eb1a17d3..15950b9f47 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/profile/unordered_set +++ b/contrib/gcc-5.0/libstdc++-v3/include/profile/unordered_set @@ -125,6 +125,41 @@ namespace __profile : _Base(__l, __n, __hf, __eql, __a) { } + unordered_set(size_type __n, const allocator_type& __a) + : unordered_set(__n, hasher(), key_equal(), __a) + { } + + unordered_set(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__n, __hf, key_equal(), __a) + { } + + template + unordered_set(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_set(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_set(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_set(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_set(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_set(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_set(__l, __n, __hf, key_equal(), __a) + { } + unordered_set& operator=(const unordered_set&) = default; @@ -346,6 +381,41 @@ namespace __profile : _Base(__l, __n, __hf, __eql, __a) { } + unordered_multiset(size_type __n, const allocator_type& __a) + : unordered_multiset(__n, hasher(), key_equal(), __a) + { } + + unordered_multiset(size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__n, __hf, key_equal(), __a) + { } + + template + unordered_multiset(_InputIterator __first, _InputIterator __last, + size_type __n, + const allocator_type& __a) + : unordered_multiset(__first, __last, __n, hasher(), key_equal(), __a) + { } + + template + unordered_multiset(_InputIterator __first, _InputIterator __last, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__first, __last, __n, __hf, key_equal(), __a) + { } + + unordered_multiset(initializer_list __l, + size_type __n, + const allocator_type& __a) + : unordered_multiset(__l, __n, hasher(), key_equal(), __a) + { } + + unordered_multiset(initializer_list __l, + size_type __n, const hasher& __hf, + const allocator_type& __a) + : unordered_multiset(__l, __n, __hf, key_equal(), __a) + { } + unordered_multiset& operator=(const unordered_multiset&) = default; diff --git a/contrib/gcc-5.0/libstdc++-v3/include/std/array b/contrib/gcc-5.0/libstdc++-v3/include/std/array index 429506b385..24be44f5b1 100644 --- a/contrib/gcc-5.0/libstdc++-v3/include/std/array +++ b/contrib/gcc-5.0/libstdc++-v3/include/std/array @@ -51,6 +51,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER static constexpr _Tp& _S_ref(const _Type& __t, std::size_t __n) noexcept { return const_cast<_Tp&>(__t[__n]); } + + static constexpr _Tp* + _S_ptr(const _Type& __t) noexcept + { return const_cast<_Tp*>(__t); } }; template @@ -61,6 +65,10 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER static constexpr _Tp& _S_ref(const _Type&, std::size_t) noexcept { return *static_cast<_Tp*>(nullptr); } + + static constexpr _Tp* + _S_ptr(const _Type&) noexcept + { return nullptr; } }; /** @@ -219,11 +227,11 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER pointer data() noexcept - { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); } + { return _AT_Type::_S_ptr(_M_elems); } const_pointer data() const noexcept - { return std::__addressof(_AT_Type::_S_ref(_M_elems, 0)); } + { return _AT_Type::_S_ptr(_M_elems); } }; // Array comparisons. diff --git a/contrib/gcc-5.0/libstdc++-v3/src/c++11/codecvt.cc b/contrib/gcc-5.0/libstdc++-v3/src/c++11/codecvt.cc index 83ee6e0683..6b82aa853e 100644 --- a/contrib/gcc-5.0/libstdc++-v3/src/c++11/codecvt.cc +++ b/contrib/gcc-5.0/libstdc++-v3/src/c++11/codecvt.cc @@ -319,7 +319,7 @@ namespace { if (to.size() > 0) { - *to.next = codepoint; + *to.next = adjust_byte_order(codepoint, mode); ++to.next; return true; } @@ -1124,7 +1124,7 @@ do_length(state_type&, const extern_type* __from, int __codecvt_utf16_base::do_max_length() const throw() -{ return 3; } +{ return 4; } #ifdef _GLIBCXX_USE_WCHAR_T // Define members of codecvt_utf16 base class implementation. diff --git a/contrib/gcc-5.0/libstdc++-v3/src/c++11/thread.cc b/contrib/gcc-5.0/libstdc++-v3/src/c++11/thread.cc index 954f2676aa..906cafa735 100644 --- a/contrib/gcc-5.0/libstdc++-v3/src/c++11/thread.cc +++ b/contrib/gcc-5.0/libstdc++-v3/src/c++11/thread.cc @@ -92,7 +92,7 @@ namespace std _GLIBCXX_VISIBILITY(default) std::terminate(); } - return 0; + return nullptr; } } @@ -137,18 +137,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION __throw_system_error(int(errc::operation_not_permitted)); #endif - _M_start_thread(__b, nullptr); + _M_start_thread(std::move(__b), nullptr); } void thread::_M_start_thread(__shared_base_type __b, void (*)()) { - __b->_M_this_ptr = __b; + auto ptr = __b.get(); + ptr->_M_this_ptr = std::move(__b); int __e = __gthread_create(&_M_id._M_thread, - &execute_native_thread_routine, __b.get()); + &execute_native_thread_routine, ptr); if (__e) { - __b->_M_this_ptr.reset(); + ptr->_M_this_ptr.reset(); __throw_system_error(__e); } }